[Pkg-ceph-commits] [ceph] 02/17: Imported Upstream version 10.1.0

James Downing Page jamespage at moszumanska.debian.org
Thu Mar 31 10:53:20 UTC 2016


This is an automated email from the git hooks/post-receive script.

jamespage pushed a commit to branch ubuntu-xenial
in repository ceph.

commit 98b5d318c615796203af42c7d41ac7ae2c68eeaf
Author: James Page <james.page at ubuntu.com>
Date:   Sun Mar 27 09:33:55 2016 +0100

    Imported Upstream version 10.1.0
---
 AUTHORS                                            |   75 +-
 ChangeLog                                          | 2441 +++++++-
 Makefile.am                                        |    7 +-
 Makefile.in                                        |   57 +-
 aclocal.m4                                         |   73 +-
 ar-lib                                             |    2 +-
 ceph.spec                                          |  121 +-
 ceph.spec.in                                       |  119 +-
 compile                                            |    2 +-
 config.guess                                       |  233 +-
 config.sub                                         |   60 +-
 configure                                          | 3310 +++++------
 configure.ac                                       |   33 +-
 depcomp                                            |    2 +-
 doc/Makefile.am                                    |    1 +
 doc/Makefile.in                                    |   28 +-
 doc/man/8/ceph-detect-init.rst                     |   54 +
 doc/man/8/ceph-disk.rst                            |  329 +-
 doc/man/8/ceph.rst                                 |   10 +-
 doc/man/8/rbd.rst                                  |    6 +-
 etc/sysconfig/ceph                                 |    3 +
 install-sh                                         |  373 +-
 ltmain.sh                                          | 5535 +++++++----------
 m4/libtool.m4                                      | 2521 ++++----
 m4/ltoptions.m4                                    |  127 +-
 m4/ltsugar.m4                                      |    7 +-
 m4/ltversion.m4                                    |   12 +-
 m4/lt~obsolete.m4                                  |    7 +-
 m4/pkg.m4                                          |  230 +-
 man/Makefile.in                                    |   32 +-
 man/ceph-authtool.8                                |    2 +-
 man/ceph-clsinfo.8                                 |    2 +-
 man/ceph-conf.8                                    |    2 +-
 man/ceph-create-keys.8                             |    2 +-
 man/ceph-debugpack.8                               |    2 +-
 man/ceph-dencoder.8                                |    2 +-
 man/ceph-deploy.8                                  |    4 +-
 man/ceph-detect-init.8                             |    2 +-
 man/ceph-disk.8                                    |  472 +-
 man/ceph-fuse.8                                    |    2 +-
 man/ceph-mds.8                                     |    2 +-
 man/ceph-mon.8                                     |    2 +-
 man/ceph-osd.8                                     |    2 +-
 man/ceph-post-file.8                               |    2 +-
 man/ceph-rbdnamer.8                                |    2 +-
 man/ceph-rest-api.8                                |    2 +-
 man/ceph-run.8                                     |    2 +-
 man/ceph-syn.8                                     |    2 +-
 man/ceph.8                                         |   20 +-
 man/ceph_selinux.8                                 |   54 +-
 man/cephfs.8                                       |    2 +-
 man/crushtool.8                                    |    2 +-
 man/librados-config.8                              |    2 +-
 man/monmaptool.8                                   |    2 +-
 man/mount.ceph.8                                   |    2 +-
 man/osdmaptool.8                                   |    2 +-
 man/rados.8                                        |    2 +-
 man/radosgw-admin.8                                |    2 +-
 man/radosgw.8                                      |    2 +-
 man/rbd-fuse.8                                     |    2 +-
 man/rbd-mirror.8                                   |    2 +-
 man/rbd-nbd.8                                      |    2 +-
 man/rbd-replay-many.8                              |    2 +-
 man/rbd-replay-prep.8                              |    2 +-
 man/rbd-replay.8                                   |    2 +-
 man/rbd.8                                          |    8 +-
 missing                                            |    2 +-
 py-compile                                         |    2 +-
 selinux/Makefile.in                                |   27 +-
 selinux/ceph.fc                                    |    1 +
 selinux/ceph.te                                    |    5 +-
 src/.git_version                                   |    4 +-
 src/Makefile-client.am                             |    3 -
 src/Makefile-env.am                                |    5 +-
 src/Makefile.am                                    |    3 +
 src/Makefile.in                                    | 6264 +++++++++++++-------
 src/acconfig.h.in                                  |   12 +-
 src/ceph-crush-location                            |    8 +-
 src/ceph-detect-init/Makefile.am                   |   10 +-
 src/ceph-detect-init/ceph_detect_init/__init__.py  |    2 -
 .../ceph_detect_init/suse/__init__.py              |   10 +-
 src/ceph-detect-init/run-tox.sh                    |    7 +-
 src/ceph-detect-init/tests/test_all.py             |   12 +
 src/ceph-disk/Makefile.am                          |   10 +-
 src/ceph-disk/ceph_disk/main.py                    |  918 ++-
 src/ceph-disk/run-tox.sh                           |    7 +-
 src/ceph-disk/tests/test_main.py                   |   19 +-
 src/ceph.in                                        |  193 +-
 src/ceph_fuse.cc                                   |    2 +
 src/ceph_mds.cc                                    |    2 +
 src/ceph_mon.cc                                    |    4 +-
 src/ceph_osd.cc                                    |   15 +-
 src/civetweb/src/civetweb.c                        |    2 -
 src/client/Client.cc                               |  370 +-
 src/client/Client.h                                |   28 +-
 src/client/Inode.cc                                |    4 +-
 src/client/Inode.h                                 |   12 +-
 src/client/MetaRequest.h                           |    2 -
 src/client/SyntheticClient.cc                      |  249 +-
 src/client/fuse_ll.cc                              |   48 +-
 src/cls/Makefile-client.am                         |   28 +-
 src/cls/cephfs/cls_cephfs_client.cc                |    2 +-
 src/cls/cephfs/cls_cephfs_client.h                 |    2 +-
 src/cls/hello/cls_hello.cc                         |    2 +-
 src/cls/journal/cls_journal.cc                     |   79 +-
 src/cls/journal/cls_journal_client.cc              |   37 +-
 src/cls/journal/cls_journal_client.h               |   12 +-
 src/cls/journal/cls_journal_types.cc               |   79 +-
 src/cls/journal/cls_journal_types.h                |   61 +-
 src/cls/log/cls_log.cc                             |   10 +-
 src/cls/log/cls_log_client.cc                      |    2 +-
 src/cls/log/cls_log_client.h                       |    2 +-
 src/cls/log/cls_log_ops.h                          |   11 +-
 src/cls/rbd/cls_rbd.cc                             |  513 +-
 src/cls/rbd/cls_rbd_client.cc                      |  180 +-
 src/cls/rbd/cls_rbd_client.h                       |   32 +-
 src/cls/rbd/cls_rbd_types.cc                       |   95 +-
 src/cls/rbd/cls_rbd_types.h                        |   49 +-
 src/cls/rgw/cls_rgw.cc                             |  187 +-
 src/cls/rgw/cls_rgw_client.cc                      |   24 +-
 src/cls/rgw/cls_rgw_client.h                       |    5 +-
 src/cls/rgw/cls_rgw_ops.cc                         |    4 +
 src/cls/rgw/cls_rgw_ops.h                          |   81 +-
 src/cls/rgw/cls_rgw_types.cc                       |   67 +-
 src/cls/rgw/cls_rgw_types.h                        |   65 +-
 src/cls/user/cls_user_client.cc                    |    4 +-
 src/cls/user/cls_user_ops.cc                       |    8 +-
 src/cls/user/cls_user_ops.h                        |    5 +-
 src/cls/user/cls_user_types.cc                     |   12 +-
 src/cls/user/cls_user_types.h                      |   20 +-
 src/common/Continuation.h                          |    2 +-
 src/common/Formatter.h                             |    3 +
 src/common/Graylog.cc                              |    9 +-
 src/common/Graylog.h                               |   18 +-
 src/common/HTMLFormatter.cc                        |    2 +-
 src/common/HTMLFormatter.h                         |    4 +-
 src/common/LogClient.cc                            |    4 +
 src/common/LogClient.h                             |   11 +-
 src/common/Makefile.am                             |   20 +-
 src/common/MemoryModel.cc                          |    2 +
 src/common/PluginRegistry.h                        |    2 +-
 src/common/RWLock.h                                |   25 +-
 src/common/SubProcess.h                            |    6 +-
 src/common/Thread.cc                               |   11 +-
 src/common/Thread.h                                |    1 +
 src/common/Throttle.cc                             |  180 +
 src/common/Throttle.h                              |  102 +
 src/common/TrackedOp.cc                            |   13 +-
 src/common/WeightedPriorityQueue.h                 |  550 +-
 src/common/admin_socket.cc                         |   37 +-
 src/common/admin_socket.h                          |   13 +-
 src/common/bit_vector.hpp                          |   30 +-
 src/common/blkdev.cc                               |   21 +-
 src/common/buffer.cc                               |  195 +-
 src/common/ceph_context.cc                         |    5 +
 src/common/ceph_context.h                          |   27 +
 src/common/ceph_crypto.cc                          |    6 +-
 src/common/ceph_crypto.h                           |   41 +-
 src/common/ceph_json.h                             |   96 +-
 src/common/ceph_strings.cc                         |    4 +-
 src/common/ceph_time.h                             |    4 +
 src/common/cohort_lru.h                            |  468 ++
 src/common/common_init.h                           |    3 +
 src/common/config.cc                               |   68 +-
 src/common/config.h                                |   10 +-
 src/common/config_opts.h                           |  141 +-
 src/common/dout.h                                  |   10 +
 src/common/fs_types.cc                             |  124 +
 src/common/hobject.cc                              |   52 +-
 src/common/hobject.h                               |    1 +
 src/common/mutex_debug.h                           |   15 +-
 src/common/obj_bencher.cc                          |   49 +-
 src/common/page.cc                                 |    2 +-
 src/common/scrub_types.cc                          |  248 +
 src/common/scrub_types.h                           |  141 +
 src/common/snap_types.h                            |    1 +
 src/common/sstring.hh                              |  669 +++
 src/common/strtol.cc                               |   13 +-
 src/common/strtol.h                                |   22 +
 src/common/utf8.c                                  |    3 -
 src/common/utf8.h                                  |    3 +
 src/compressor/zlib/CompressionPluginZlib.cc       |    2 +-
 src/compressor/zlib/CompressionZlib.cc             |    4 +-
 src/crush/CrushTester.cc                           |    7 +
 src/crush/CrushWrapper.cc                          |    3 +
 src/crush/CrushWrapper.h                           |   20 +-
 src/erasure-code/jerasure/ErasureCodeJerasure.h    |    6 +-
 .../jerasure/gf-complete/include/gf_complete.h     |  204 -
 .../jerasure/gf-complete/include/gf_general.h      |   61 -
 .../jerasure/gf-complete/include/gf_int.h          |  200 -
 .../jerasure/gf-complete/include/gf_method.h       |   20 -
 .../jerasure/gf-complete/include/gf_rand.h         |   22 -
 .../jerasure/gf-complete/include/gf_w16.h          |   66 -
 .../jerasure/gf-complete/include/gf_w32.h          |   71 -
 .../jerasure/gf-complete/include/gf_w4.h           |   63 -
 .../jerasure/gf-complete/include/gf_w64.h          |   50 -
 .../jerasure/gf-complete/include/gf_w8.h           |   99 -
 src/erasure-code/jerasure/gf-complete/src/gf.c     | 1076 ----
 .../jerasure/gf-complete/src/gf_general.c          |  539 --
 .../jerasure/gf-complete/src/gf_method.c           |  193 -
 .../jerasure/gf-complete/src/gf_rand.c             |   80 -
 .../jerasure/gf-complete/src/gf_w128.c             | 1783 ------
 src/erasure-code/jerasure/gf-complete/src/gf_w16.c | 2452 --------
 src/erasure-code/jerasure/gf-complete/src/gf_w32.c | 2823 ---------
 src/erasure-code/jerasure/gf-complete/src/gf_w4.c  | 2051 -------
 src/erasure-code/jerasure/gf-complete/src/gf_w64.c | 2218 -------
 src/erasure-code/jerasure/gf-complete/src/gf_w8.c  | 2392 --------
 .../jerasure/gf-complete/src/gf_wgen.c             | 1019 ----
 .../jerasure/gf-complete/src/neon/gf_w16_neon.c    |  356 --
 .../jerasure/gf-complete/src/neon/gf_w32_neon.c    |  269 -
 .../jerasure/gf-complete/src/neon/gf_w4_neon.c     |  247 -
 .../jerasure/gf-complete/src/neon/gf_w64_neon.c    |  333 --
 .../jerasure/gf-complete/src/neon/gf_w8_neon.c     |  302 -
 .../jerasure/jerasure/include/cauchy.h             |   45 -
 .../jerasure/jerasure/include/galois.h             |  100 -
 .../jerasure/jerasure/include/jerasure.h           |  294 -
 .../jerasure/jerasure/include/liberation.h         |   47 -
 .../jerasure/jerasure/include/reed_sol.h           |   50 -
 src/erasure-code/jerasure/jerasure/src/cauchy.c    |  405 --
 src/erasure-code/jerasure/jerasure/src/galois.c    |  365 --
 src/erasure-code/jerasure/jerasure/src/jerasure.c  | 1388 -----
 .../jerasure/jerasure/src/liberation.c             |  262 -
 src/erasure-code/jerasure/jerasure/src/reed_sol.c  |  302 -
 src/global/Makefile.am                             |    1 +
 src/global/global_init.cc                          |   93 +-
 src/global/global_init.h                           |    3 +-
 src/global/pidfile.cc                              |    5 +-
 src/gmock/Makefile.in                              |   70 +-
 src/gmock/aclocal.m4                               | 2741 ++++-----
 src/gmock/build-aux/compile                        |    2 +-
 src/gmock/build-aux/config.guess                   |  233 +-
 src/gmock/build-aux/config.h.in                    |    3 +-
 src/gmock/build-aux/config.sub                     |   60 +-
 src/gmock/build-aux/depcomp                        |    2 +-
 src/gmock/build-aux/install-sh                     |  373 +-
 src/gmock/build-aux/ltmain.sh                      | 5535 +++++++----------
 src/gmock/build-aux/missing                        |    2 +-
 src/gmock/build-aux/test-driver                    |   15 +-
 src/gmock/configure                                | 3124 ++++------
 src/gmock/gtest/Makefile.in                        |   70 +-
 src/gmock/gtest/aclocal.m4                         |   67 +-
 src/gmock/gtest/build-aux/compile                  |    2 +-
 src/gmock/gtest/build-aux/config.guess             |  233 +-
 src/gmock/gtest/build-aux/config.h.in              |    3 +-
 src/gmock/gtest/build-aux/config.sub               |   60 +-
 src/gmock/gtest/build-aux/depcomp                  |    2 +-
 src/gmock/gtest/build-aux/install-sh               |  373 +-
 src/gmock/gtest/build-aux/ltmain.sh                | 5535 +++++++----------
 src/gmock/gtest/build-aux/missing                  |    2 +-
 src/gmock/gtest/build-aux/test-driver              |   15 +-
 src/gmock/gtest/configure                          | 3124 ++++------
 src/gmock/gtest/m4/libtool.m4                      | 2521 ++++----
 src/gmock/gtest/m4/ltoptions.m4                    |  127 +-
 src/gmock/gtest/m4/ltsugar.m4                      |    7 +-
 src/gmock/gtest/m4/ltversion.m4                    |   12 +-
 src/gmock/gtest/m4/lt~obsolete.m4                  |    7 +-
 src/include/CompatSet.h                            |    2 +-
 src/include/Makefile.am                            |    7 +
 src/include/buffer.h                               |   57 +-
 src/include/ceph_features.h                        |   83 +-
 src/include/ceph_fs.h                              |   35 +-
 src/include/compact_map.h                          |   11 +
 src/include/encoding.h                             |   60 +-
 src/include/filepath.h                             |    1 +
 src/include/fs_types.h                             |  106 +
 src/include/object.h                               |    4 +-
 src/include/rados.h                                |    4 +-
 src/include/rados/buffer.h                         |   57 +-
 src/include/rados/librados.h                       |   93 +
 src/include/rados/librados.hpp                     |   73 +-
 src/include/rados/librgw.h                         |   12 +-
 src/include/rados/rados_types.hpp                  |  129 +
 src/include/rados/rgw_file.h                       |  305 +
 src/include/rbd/features.h                         |    3 +
 src/include/rbd/librbd.h                           |   43 +-
 src/include/rbd/librbd.hpp                         |   39 +-
 src/include/rbd_types.h                            |    7 +-
 src/include/types.h                                |   64 +-
 src/include/utime.h                                |   40 +
 src/init-ceph.in                                   |    8 +-
 src/java/Makefile.in                               |   27 +-
 src/java/java/com/ceph/fs/CephMount.java           |   15 +-
 src/java/native/libcephfs_jni.cc                   |   16 +-
 src/java/test/com/ceph/fs/CephMountTest.java       |   32 +-
 src/journal/FutureImpl.cc                          |   14 +-
 src/journal/FutureImpl.h                           |    9 +-
 src/journal/JournalMetadata.cc                     |  336 +-
 src/journal/JournalMetadata.h                      |   44 +-
 src/journal/JournalPlayer.cc                       |  344 +-
 src/journal/JournalPlayer.h                        |   66 +-
 src/journal/JournalRecorder.cc                     |    7 +-
 src/journal/JournalTrimmer.cc                      |   99 +-
 src/journal/JournalTrimmer.h                       |   36 +-
 src/journal/Journaler.cc                           |  125 +-
 src/journal/Journaler.h                            |   52 +-
 src/journal/ObjectPlayer.cc                        |    9 +-
 src/journal/ObjectPlayer.h                         |    6 -
 src/journal/ObjectRecorder.cc                      |    6 +
 src/kv/KeyValueDB.h                                |    8 +-
 src/kv/KineticStore.h                              |    6 +-
 src/kv/LevelDBStore.h                              |   17 +-
 src/kv/Makefile.am                                 |    6 +-
 src/kv/RocksDBStore.cc                             |   13 +-
 src/kv/RocksDBStore.h                              |    3 +-
 src/libcephfs.cc                                   |   98 +-
 src/librados/IoCtxImpl.cc                          |  226 +-
 src/librados/IoCtxImpl.h                           |   29 +-
 src/librados/RadosClient.cc                        |   66 +-
 src/librados/RadosClient.h                         |    2 +
 src/librados/librados.cc                           |  458 +-
 src/librados/snap_set_diff.cc                      |   10 +-
 src/librados/snap_set_diff.h                       |    2 +-
 src/libradosstriper/RadosStriperImpl.cc            |   44 +-
 src/libradosstriper/libradosstriper.cc             |    2 +-
 src/librbd/AioCompletion.cc                        |   44 +-
 src/librbd/AioImageRequest.cc                      |    6 +-
 src/librbd/AioImageRequestWQ.cc                    |   80 +-
 src/librbd/AioImageRequestWQ.h                     |   20 +-
 src/librbd/AioObjectRequest.cc                     |   13 +-
 src/librbd/AioObjectRequest.h                      |    6 +-
 src/librbd/DiffIterate.cc                          |    8 +-
 src/librbd/ExclusiveLock.cc                        |   22 +-
 src/librbd/ExclusiveLock.h                         |    2 +-
 src/librbd/ImageCtx.cc                             |   73 +-
 src/librbd/ImageCtx.h                              |   12 +-
 src/librbd/ImageState.cc                           |  107 +-
 src/librbd/ImageState.h                            |   15 +-
 src/librbd/ImageWatcher.cc                         |  378 +-
 src/librbd/ImageWatcher.h                          |   71 +-
 src/librbd/Journal.cc                              |  538 +-
 src/librbd/Journal.h                               |   52 +-
 src/librbd/LibrbdWriteback.cc                      |    2 +-
 src/librbd/Makefile.am                             |    4 +
 src/librbd/Operations.cc                           |  516 +-
 src/librbd/Operations.h                            |   38 +-
 src/librbd/TaskFinisher.h                          |    8 +-
 src/librbd/Utils.cc                                |    4 +
 src/librbd/Utils.h                                 |   21 +
 src/librbd/WatchNotifyTypes.cc                     |   12 +
 src/librbd/WatchNotifyTypes.h                      |   15 +
 src/librbd/exclusive_lock/AcquireRequest.cc        |   91 +-
 src/librbd/exclusive_lock/AcquireRequest.h         |   63 +-
 src/librbd/exclusive_lock/ReleaseRequest.cc        |   25 +
 src/librbd/exclusive_lock/ReleaseRequest.h         |    8 +-
 src/librbd/image/CloseRequest.cc                   |   43 +-
 src/librbd/image/CloseRequest.h                    |   20 +-
 src/librbd/image/OpenRequest.cc                    |   71 +-
 src/librbd/image/OpenRequest.h                     |    5 +-
 src/librbd/image/RefreshRequest.cc                 |   29 +-
 src/librbd/image/SetSnapRequest.cc                 |   29 +-
 src/librbd/image/SetSnapRequest.h                  |    1 +
 src/librbd/image_watcher/Notifier.cc               |   78 +
 src/librbd/image_watcher/Notifier.h                |   57 +
 src/librbd/image_watcher/NotifyLockOwner.cc        |  105 +
 src/librbd/image_watcher/NotifyLockOwner.h         |   49 +
 src/librbd/internal.cc                             |  603 +-
 src/librbd/internal.h                              |   21 +-
 src/librbd/journal/Replay.cc                       |  403 +-
 src/librbd/journal/Replay.h                        |   23 +-
 src/librbd/journal/Types.cc                        |  151 +-
 src/librbd/journal/Types.h                         |   89 +-
 src/librbd/librbd.cc                               |  161 +-
 src/librbd/operation/RebuildObjectMapRequest.cc    |    3 +-
 src/librbd/operation/RenameRequest.cc              |   17 +-
 src/librbd/operation/RenameRequest.h               |    1 +
 src/librbd/operation/Request.cc                    |   13 +
 src/librbd/operation/Request.h                     |    5 +-
 src/librbd/operation/SnapshotCreateRequest.cc      |    3 +-
 src/librbd/operation/SnapshotRollbackRequest.cc    |    1 +
 src/log/Log.cc                                     |   65 +-
 src/log/Log.h                                      |   14 +-
 src/log/test.cc                                    |   18 +
 src/mds/Beacon.cc                                  |   10 +-
 src/mds/CDentry.cc                                 |   54 -
 src/mds/CDentry.h                                  |   51 +-
 src/mds/CDir.cc                                    |  180 +-
 src/mds/CDir.h                                     |   26 +-
 src/mds/CInode.cc                                  |  548 +-
 src/mds/CInode.h                                   |   72 +-
 src/mds/DamageTable.cc                             |  166 +
 src/mds/DamageTable.h                              |  296 +
 src/mds/FSMap.cc                                   |  816 +++
 src/mds/FSMap.h                                    |  459 ++
 src/mds/Locker.cc                                  |    6 +-
 src/mds/Locker.h                                   |    2 +-
 src/mds/LogEvent.h                                 |    6 +-
 src/mds/MDCache.cc                                 |  453 +-
 src/mds/MDCache.h                                  |   41 +-
 src/mds/MDLog.cc                                   |   20 +-
 src/mds/MDSDaemon.cc                               |   13 +-
 src/mds/MDSMap.cc                                  |   95 +-
 src/mds/MDSMap.h                                   |  172 +-
 src/mds/MDSRank.cc                                 |   38 +-
 src/mds/MDSRank.h                                  |    4 +-
 src/mds/Makefile-server.am                         |    2 +
 src/mds/Makefile.am                                |    1 +
 src/mds/Migrator.cc                                |    3 +-
 src/mds/ScrubHeader.h                              |    9 +-
 src/mds/ScrubStack.cc                              |  331 +-
 src/mds/ScrubStack.h                               |   81 +-
 src/mds/Server.cc                                  |  161 +-
 src/mds/Server.h                                   |   10 +-
 src/mds/SessionMap.cc                              |   24 +-
 src/mds/SessionMap.h                               |    4 +-
 src/mds/SnapRealm.cc                               |   60 +-
 src/mds/SnapRealm.h                                |    8 +-
 src/mds/StrayManager.cc                            |   52 +-
 src/mds/events/ECommitted.h                        |    3 +-
 src/mds/events/EExport.h                           |    3 +-
 src/mds/events/EFragment.h                         |    3 +-
 src/mds/events/EImportFinish.h                     |    3 +-
 src/mds/events/EImportStart.h                      |    3 +-
 src/mds/events/EMetaBlob.h                         |   20 +-
 src/mds/events/ENoOp.h                             |    3 +-
 src/mds/events/EOpen.h                             |    3 +-
 src/mds/events/EResetJournal.h                     |    3 +-
 src/mds/events/ESession.h                          |    3 +-
 src/mds/events/ESessions.h                         |    3 +-
 src/mds/events/ESlaveUpdate.h                      |    3 +-
 src/mds/events/ESubtreeMap.h                       |    3 +-
 src/mds/events/ETableClient.h                      |    3 +-
 src/mds/events/ETableServer.h                      |    3 +-
 src/mds/events/EUpdate.h                           |    3 +-
 src/mds/flock.cc                                   |  181 +-
 src/mds/flock.h                                    |   97 +-
 src/mds/journal.cc                                 |   68 +-
 src/mds/mdstypes.cc                                |   38 +-
 src/mds/mdstypes.h                                 |   90 +-
 src/messages/MClientCaps.h                         |  111 +-
 src/messages/MClientReply.h                        |   95 +-
 src/messages/MFSMap.h                              |   59 +
 src/messages/MMDSBeacon.h                          |   15 +-
 src/messages/MMDSCacheRejoin.h                     |    4 +-
 src/messages/MMonGetVersionReply.h                 |    4 +-
 src/messages/MMonPaxos.h                           |    8 +-
 src/messages/MOSDPGUpdateLogMissing.h              |   82 +
 src/messages/MOSDPGUpdateLogMissingReply.h         |   87 +
 src/messages/MRoute.h                              |    7 -
 src/messages/Makefile.am                           |    3 +
 src/mon/AuthMonitor.cc                             |    4 +-
 src/mon/ConfigKeyService.cc                        |    3 +-
 src/mon/LogMonitor.cc                              |   27 +
 src/mon/LogMonitor.h                               |   33 +-
 src/mon/MDSMonitor.cc                              | 2334 +++++---
 src/mon/MDSMonitor.h                               |   48 +-
 src/mon/MonCommands.h                              |   98 +-
 src/mon/Monitor.cc                                 |  148 +-
 src/mon/Monitor.h                                  |   23 +-
 src/mon/MonmapMonitor.cc                           |    3 +-
 src/mon/OSDMonitor.cc                              |  296 +-
 src/mon/OSDMonitor.h                               |   14 +-
 src/mon/PGMap.cc                                   |   38 +-
 src/mon/PGMap.h                                    |    4 +-
 src/mon/PGMonitor.cc                               |   57 +-
 src/mon/PGMonitor.h                                |    2 +-
 src/mount.fuse.ceph                                |   16 +-
 src/msg/Message.cc                                 |   13 +
 src/msg/Message.h                                  |    2 +
 src/msg/Messenger.cc                               |   11 +-
 src/msg/async/AsyncConnection.cc                   |  119 +-
 src/msg/async/AsyncConnection.h                    |   15 +-
 src/msg/async/AsyncMessenger.cc                    |    5 +-
 src/msg/async/AsyncMessenger.h                     |    5 +-
 src/msg/async/Event.cc                             |   52 +-
 src/msg/async/Event.h                              |   17 +-
 src/msg/async/EventEpoll.cc                        |    9 +-
 src/msg/async/EventKqueue.cc                       |    3 +-
 src/msg/simple/DispatchQueue.cc                    |   11 +-
 src/msg/simple/Pipe.cc                             |    2 +-
 src/msg/simple/Pipe.h                              |    4 +-
 src/msg/xio/XioConnection.cc                       |   14 +-
 src/msg/xio/XioConnection.h                        |   13 +-
 src/msg/xio/XioMessenger.cc                        |   45 +-
 src/msg/xio/XioMessenger.h                         |    2 -
 src/msg/xio/XioPortal.cc                           |    4 +-
 src/msg/xio/XioPortal.h                            |    6 +-
 src/objclass/class_api.cc                          |   25 +
 src/objclass/objclass.h                            |    2 +
 src/ocf/Makefile.in                                |   29 +-
 src/os/Makefile.am                                 |    2 +
 src/os/ObjectStore.cc                              |    2 +-
 src/os/ObjectStore.h                               |   81 +-
 src/os/Transaction.cc                              |   14 +
 src/os/bluestore/BlockDevice.cc                    |   35 +-
 src/os/bluestore/BlockDevice.h                     |   39 +-
 src/os/bluestore/BlueFS.cc                         |    3 +-
 src/os/bluestore/BlueStore.cc                      |  412 +-
 src/os/bluestore/BlueStore.h                       |   60 +-
 src/os/bluestore/KernelDevice.cc                   |   50 +-
 src/os/bluestore/NVMEDevice.cc                     |  591 +-
 src/os/bluestore/NVMEDevice.h                      |    1 +
 src/os/bluestore/StupidAllocator.cc                |   22 +-
 src/os/bluestore/StupidAllocator.h                 |    2 +-
 src/os/filestore/CollectionIndex.h                 |    4 +-
 src/os/filestore/DBObjectMap.cc                    |    2 +-
 src/os/filestore/DBObjectMap.h                     |    2 +-
 src/os/filestore/FileJournal.cc                    |  191 +-
 src/os/filestore/FileJournal.h                     |   38 +-
 src/os/filestore/FileStore.cc                      |  346 +-
 src/os/filestore/FileStore.h                       |   13 +-
 src/os/filestore/Journal.h                         |    9 +-
 src/os/filestore/JournalThrottle.cc                |   67 +
 src/os/filestore/JournalThrottle.h                 |  101 +
 src/os/filestore/JournalingObjectStore.cc          |    4 +
 src/os/filestore/LFNIndex.cc                       |   57 +-
 src/os/filestore/LFNIndex.h                        |    6 +
 src/os/kstore/KStore.cc                            |  740 +--
 src/os/kstore/KStore.h                             |  126 +-
 src/os/memstore/MemStore.cc                        |   26 +-
 src/os/memstore/PageSet.h                          |    3 +
 src/osd/ECBackend.cc                               |   14 +-
 src/osd/ECBackend.h                                |    5 +-
 src/osd/ECUtil.h                                   |    3 +-
 src/osd/Makefile.am                                |    2 +
 src/osd/OSD.cc                                     |  510 +-
 src/osd/OSD.h                                      |   44 +-
 src/osd/OSDMap.cc                                  |  168 +-
 src/osd/OSDMap.h                                   |   35 +-
 src/osd/PG.cc                                      |  242 +-
 src/osd/PG.h                                       |  127 +-
 src/osd/PGBackend.cc                               |   99 +-
 src/osd/PGBackend.h                                |   28 +-
 src/osd/PGLog.cc                                   |  226 +-
 src/osd/PGLog.h                                    |   70 +-
 src/osd/ReplicatedBackend.cc                       |  118 +-
 src/osd/ReplicatedBackend.h                        |   10 +-
 src/osd/ReplicatedPG.cc                            | 1321 +++--
 src/osd/ReplicatedPG.h                             |  357 +-
 src/osd/ScrubStore.cc                              |  195 +
 src/osd/ScrubStore.h                               |   55 +
 src/osd/osd_types.cc                               |  123 +-
 src/osd/osd_types.h                                |  177 +-
 src/osdc/Filer.cc                                  |   18 +-
 src/osdc/Filer.h                                   |   34 +-
 src/osdc/Journaler.cc                              |   18 +-
 src/osdc/Journaler.h                               |   30 +-
 src/osdc/ObjectCacher.h                            |    9 +-
 src/osdc/Objecter.cc                               |  126 +-
 src/osdc/Objecter.h                                |   62 +-
 src/osdc/Striper.cc                                |   78 +-
 src/osdc/Striper.h                                 |   19 +-
 src/pybind/Makefile.am                             |   54 +-
 src/pybind/ceph_argparse.py                        |   73 +-
 src/pybind/ceph_volume_client.py                   |    7 -
 src/pybind/cephfs.py                               |  590 --
 src/pybind/cephfs/Makefile.am                      |   34 +
 src/pybind/cephfs/cephfs.pyx                       |  848 +++
 src/pybind/{ => cephfs}/setup.py                   |   16 +-
 src/pybind/rados.py                                | 2467 --------
 src/pybind/rados/Makefile.am                       |   35 +
 src/pybind/rados/rados.pxd                         |   38 +
 src/pybind/rados/rados.pyx                         | 3223 ++++++++++
 src/pybind/{ => rados}/setup.py                    |   12 +-
 src/pybind/rbd/Makefile.am                         |   34 +
 src/pybind/{ => rbd}/rbd.pyx                       |   14 +-
 src/pybind/{ => rbd}/setup.py                      |    4 +-
 src/rbd_replay/BufferReader.cc                     |    4 +-
 src/rgw/Makefile.am                                |  186 +-
 src/rgw/librgw.cc                                  |  648 +-
 src/rgw/rgw_acl.cc                                 |    2 -
 src/rgw/rgw_admin.cc                               | 2959 ++++++++-
 src/rgw/rgw_auth_s3.cc                             |  200 +
 src/rgw/rgw_auth_s3.h                              |   29 +-
 src/rgw/rgw_b64.h                                  |   87 +
 src/rgw/rgw_basic_types.h                          |    2 +-
 src/rgw/rgw_boost_asio_coroutine.h                 |   67 +
 src/rgw/rgw_boost_asio_yield.h                     |   78 +
 src/rgw/rgw_bucket.cc                              |  330 +-
 src/rgw/rgw_bucket.h                               |  122 +-
 src/rgw/rgw_cache.cc                               |    4 +-
 src/rgw/rgw_cache.h                                |  190 +-
 src/rgw/rgw_civetweb.cc                            |   24 +-
 src/rgw/rgw_civetweb.h                             |    4 +-
 src/rgw/rgw_civetweb_frontend.cc                   |   78 +
 src/rgw/rgw_client_io.cc                           |   21 +-
 src/rgw/rgw_client_io.h                            |   65 +-
 src/rgw/rgw_common.cc                              |  297 +-
 src/rgw/rgw_common.h                               |  369 +-
 src/rgw/rgw_coroutine.cc                           |  856 +++
 src/rgw/rgw_coroutine.h                            |  582 ++
 src/rgw/rgw_cr_rados.cc                            |  655 ++
 src/rgw/rgw_cr_rados.h                             |  940 +++
 src/rgw/rgw_cr_rest.h                              |  118 +
 src/rgw/rgw_data_sync.cc                           | 2557 ++++++++
 src/rgw/rgw_data_sync.h                            |  478 ++
 src/rgw/rgw_dencoder.cc                            |    6 +-
 src/rgw/rgw_fcgi.h                                 |   12 +-
 src/rgw/rgw_fcgi_process.cc                        |  128 +
 src/rgw/rgw_file.cc                                | 1221 ++++
 src/rgw/rgw_file.h                                 | 1924 ++++++
 src/rgw/rgw_frontend.cc                            |   86 +
 src/rgw/rgw_frontend.h                             |  224 +
 src/rgw/rgw_http_client.cc                         |  429 +-
 src/rgw/rgw_http_client.h                          |  114 +-
 src/rgw/rgw_http_errors.h                          |    3 +
 src/rgw/rgw_json_enc.cc                            |  477 +-
 src/rgw/rgw_keystone.cc                            |  183 +-
 src/rgw/rgw_keystone.h                             |  139 +-
 src/rgw/rgw_ldap.cc                                |    4 +
 src/rgw/rgw_ldap.h                                 |  121 +
 src/rgw/rgw_lib.h                                  |  203 +
 src/rgw/rgw_lib_frontend.h                         |  103 +
 src/rgw/rgw_loadgen.h                              |    5 +-
 src/rgw/rgw_loadgen_process.cc                     |  144 +
 src/rgw/rgw_log.cc                                 |   57 +-
 src/rgw/rgw_main.cc                                | 1029 +---
 src/rgw/rgw_meta_sync_status.h                     |  113 +
 src/rgw/rgw_metadata.cc                            |  500 +-
 src/rgw/rgw_metadata.h                             |  117 +-
 src/rgw/rgw_object_expirer.cc                      |    2 +-
 src/rgw/rgw_object_expirer_core.cc                 |   10 +-
 src/rgw/rgw_op.cc                                  |  952 +--
 src/rgw/rgw_op.h                                   |  322 +-
 src/rgw/rgw_orphan.cc                              |    8 +-
 src/rgw/rgw_os_lib.cc                              |   62 +
 src/rgw/rgw_os_lib.h                               |   12 +
 src/rgw/rgw_period_history.cc                      |  340 ++
 src/rgw/rgw_period_history.h                       |  111 +
 src/rgw/rgw_period_puller.cc                       |   97 +
 src/rgw/rgw_period_puller.h                        |   20 +
 src/rgw/rgw_period_pusher.cc                       |  301 +
 src/rgw/rgw_period_pusher.h                        |   56 +
 src/rgw/rgw_process.cc                             |  206 +
 src/rgw/rgw_process.h                              |  181 +
 src/rgw/rgw_quota.cc                               |   13 +-
 src/rgw/rgw_rados.cc                               | 4250 ++++++++++---
 src/rgw/rgw_rados.h                                | 1044 +++-
 src/rgw/rgw_realm_reloader.cc                      |  157 +
 src/rgw/rgw_realm_reloader.h                       |   62 +
 src/rgw/rgw_realm_watcher.cc                       |  141 +
 src/rgw/rgw_realm_watcher.h                        |   69 +
 src/rgw/rgw_request.cc                             |   37 +
 src/rgw/rgw_request.h                              |   64 +
 src/rgw/rgw_rest.cc                                |  366 +-
 src/rgw/rgw_rest.h                                 |  162 +-
 src/rgw/rgw_rest_bucket.h                          |    2 +-
 src/rgw/rgw_rest_client.cc                         |  162 +-
 src/rgw/rgw_rest_client.h                          |   47 +-
 src/rgw/rgw_rest_config.cc                         |   33 +-
 src/rgw/rgw_rest_config.h                          |   25 +-
 src/rgw/rgw_rest_conn.cc                           |  262 +-
 src/rgw/rgw_rest_conn.h                            |  333 +-
 src/rgw/rgw_rest_log.cc                            |  220 +-
 src/rgw/rgw_rest_log.h                             |   60 +-
 src/rgw/rgw_rest_metadata.cc                       |   45 +-
 src/rgw/rgw_rest_metadata.h                        |   11 +-
 src/rgw/rgw_rest_opstate.cc                        |    1 +
 src/rgw/rgw_rest_opstate.h                         |   12 +-
 src/rgw/rgw_rest_realm.cc                          |  280 +
 src/rgw/rgw_rest_realm.h                           |   16 +
 src/rgw/rgw_rest_replica_log.cc                    |    4 +-
 src/rgw/rgw_rest_replica_log.h                     |   13 +-
 src/rgw/rgw_rest_s3.cc                             | 1827 ++++--
 src/rgw/rgw_rest_s3.h                              |  167 +-
 src/rgw/rgw_rest_s3website.h                       |   26 +-
 src/rgw/rgw_rest_swift.cc                          |  492 +-
 src/rgw/rgw_rest_swift.h                           |   34 +-
 src/rgw/rgw_rest_usage.h                           |    3 +-
 src/rgw/rgw_rest_user.cc                           |    5 +-
 src/rgw/rgw_rest_user.h                            |    2 +-
 src/rgw/rgw_swift.cc                               |  575 +-
 src/rgw/rgw_swift.h                                |   11 +-
 src/rgw/rgw_swift_auth.cc                          |   34 +-
 src/rgw/rgw_swift_auth.h                           |    4 +-
 src/rgw/rgw_sync.cc                                | 2157 +++++++
 src/rgw/rgw_sync.h                                 |  443 ++
 src/rgw/rgw_token.cc                               |  135 +
 src/rgw/rgw_token.h                                |  169 +
 src/rgw/rgw_tools.cc                               |    4 +-
 src/rgw/rgw_tools.h                                |    5 +-
 src/rgw/rgw_usage.cc                               |    8 +-
 src/rgw/rgw_user.cc                                |   98 +-
 src/rgw/rgw_user.h                                 |   30 +-
 src/spdk/CONFIG                                    |    5 +
 src/spdk/include/spdk/assert.h                     |    8 +
 src/spdk/include/spdk/barrier.h                    |   12 +-
 src/spdk/include/spdk/file.h                       |   12 +-
 src/spdk/include/spdk/ioat.h                       |   97 +-
 src/spdk/include/spdk/ioat_spec.h                  |  123 +-
 src/spdk/include/spdk/mmio.h                       |    8 +
 src/spdk/include/spdk/nvme.h                       |  388 +-
 src/spdk/include/spdk/nvme_intel.h                 |  116 +-
 src/spdk/include/spdk/nvme_spec.h                  |  583 +-
 src/spdk/include/spdk/pci.h                        |   57 +-
 src/spdk/include/spdk/pci_ids.h                    |   27 +-
 src/spdk/include/spdk/queue.h                      |    8 +
 src/spdk/include/spdk/string.h                     |   10 +-
 src/spdk/include/spdk/vtophys.h                    |    8 +-
 src/spdk/lib/ioat/ioat.c                           |  339 +-
 src/spdk/lib/ioat/ioat_impl.h                      |  214 +-
 src/spdk/lib/ioat/ioat_internal.h                  |   22 +-
 src/spdk/lib/memory/vtophys.c                      |   14 +-
 src/spdk/lib/nvme/Makefile                         |    2 +-
 src/spdk/lib/nvme/nvme.c                           |  141 +-
 src/spdk/lib/nvme/nvme_ctrlr.c                     |  241 +-
 src/spdk/lib/nvme/nvme_ctrlr_cmd.c                 |  107 +-
 src/spdk/lib/nvme/nvme_impl.h                      |  124 +-
 src/spdk/lib/nvme/nvme_internal.h                  |  123 +-
 src/spdk/lib/nvme/nvme_ns.c                        |   44 +-
 src/spdk/lib/nvme/nvme_ns_cmd.c                    |  176 +-
 src/spdk/lib/nvme/nvme_qpair.c                     |  262 +-
 src/spdk/lib/util/file.c                           |    4 +-
 src/spdk/lib/util/pci.c                            |  352 +-
 src/spdk/lib/util/string.c                         |    2 +-
 src/spdk/mk/spdk.common.mk                         |    6 +
 src/stop.sh                                        |   33 +-
 src/test/Makefile-client.am                        |  143 +-
 src/test/Makefile.am                               |    1 +
 src/test/bufferlist.cc                             |  315 +-
 src/test/centos-6/ceph.spec.in                     |  119 +-
 src/test/centos-7/ceph.spec.in                     |  119 +-
 src/test/ceph_crypto.cc                            |    2 -
 src/test/ceph_objectstore_tool.py                  |   16 +
 src/test/cli/crushtool/arg-order-checks.t          |    2 +-
 src/test/cli/crushtool/build.t                     |    1 +
 src/test/cli/osdmaptool/create-print.t             |    1 +
 src/test/cli/osdmaptool/create-racks.t             |    1 +
 src/test/cli/radosgw-admin/help.t                  |   63 +-
 src/test/cli/rbd/help.t                            |  126 +-
 src/test/cli/rbd/not-enough-args.t                 |   24 +
 src/test/cls_journal/test_cls_journal.cc           |   57 +-
 src/test/cls_rbd/test_cls_rbd.cc                   |  124 +-
 src/test/common/Throttle.cc                        |  160 +
 src/test/common/test_bit_vector.cc                 |   29 +-
 src/test/common/test_context.cc                    |    4 +
 src/test/common/test_time.cc                       |    4 +-
 src/test/common/test_weighted_priority_queue.cc    |   15 -
 src/test/compressor/test_compression_plugin.cc     |    6 +-
 .../compressor/test_compression_plugin_snappy.cc   |    6 +-
 .../compressor/test_compression_plugin_zlib.cc     |    6 +-
 src/test/compressor/test_compression_zlib.cc       |   12 +-
 src/test/confutils.cc                              |   18 +-
 src/test/crypto.cc                                 |    2 -
 src/test/debian-jessie/Dockerfile.in               |    2 +-
 src/test/encoding/ceph_dencoder.cc                 |   28 +-
 src/test/encoding/types.h                          |   49 +-
 src/test/erasure-code/ErasureCodeExample.h         |    6 +-
 src/test/erasure-code/TestErasureCode.cc           |    8 +-
 src/test/fedora-21/ceph.spec.in                    |  119 +-
 src/test/journal/RadosTestFixture.cc               |   30 +-
 src/test/journal/RadosTestFixture.h                |   15 +-
 src/test/journal/test_FutureImpl.cc                |  151 +-
 src/test/journal/test_JournalMetadata.cc           |   48 +-
 src/test/journal/test_JournalPlayer.cc             |   94 +-
 src/test/journal/test_JournalRecorder.cc           |   10 -
 src/test/journal/test_JournalTrimmer.cc            |   15 +-
 src/test/journal/test_Journaler.cc                 |   54 +-
 src/test/journal/test_ObjectPlayer.cc              |    4 +-
 src/test/journal/test_ObjectRecorder.cc            |  128 +-
 src/test/libcephfs/test.cc                         |   37 +-
 src/test/librados/list.cc                          |   56 +-
 src/test/librados/misc.cc                          |   15 +-
 src/test/librados/stat.cc                          |   32 +
 src/test/librados/test.cc                          |    6 +-
 src/test/librados/test.h                           |    2 +-
 src/test/librados/tier.cc                          |  253 +
 src/test/librados/tmap_migrate.cc                  |   70 +
 src/test/librados/watch_notify.cc                  |  148 +-
 src/test/librados_test_stub/LibradosTestStub.cc    |   43 +-
 src/test/librados_test_stub/LibradosTestStub.h     |    4 +
 src/test/librados_test_stub/MockTestMemIoCtxImpl.h |   14 +-
 src/test/librados_test_stub/TestIoCtxImpl.cc       |   18 +
 src/test/librados_test_stub/TestIoCtxImpl.h        |    6 +-
 src/test/librados_test_stub/TestMemIoCtxImpl.cc    |   10 +-
 src/test/librados_test_stub/TestMemIoCtxImpl.h     |    2 +-
 src/test/librados_test_stub/TestRadosClient.cc     |   17 +-
 src/test/librados_test_stub/TestRadosClient.h      |    1 +
 src/test/librados_test_stub/TestWatchNotify.cc     |   63 +-
 src/test/librados_test_stub/TestWatchNotify.h      |    8 +-
 .../exclusive_lock/test_mock_AcquireRequest.cc     |  123 +-
 .../exclusive_lock/test_mock_ReleaseRequest.cc     |   27 +-
 src/test/librbd/fsx.cc                             |  433 +-
 src/test/librbd/image/test_mock_RefreshRequest.cc  |  128 +-
 src/test/librbd/journal/test_Replay.cc             |  580 +-
 src/test/librbd/journal/test_mock_Replay.cc        |  659 +-
 src/test/librbd/mock/MockAioImageRequestWQ.h       |    7 +-
 src/test/librbd/mock/MockExclusiveLock.h           |    2 +-
 src/test/librbd/mock/MockImageCtx.h                |   10 +-
 src/test/librbd/mock/MockImageState.h              |   20 +
 src/test/librbd/mock/MockImageWatcher.h            |    3 +
 src/test/librbd/mock/MockJournal.h                 |    3 +
 src/test/librbd/mock/MockObjectMap.h               |    6 +-
 src/test/librbd/mock/MockOperations.h              |   39 +-
 .../librbd/object_map/mock/MockInvalidateRequest.h |   21 +-
 .../object_map/test_mock_InvalidateRequest.cc      |   17 +-
 .../librbd/object_map/test_mock_LockRequest.cc     |    7 +-
 .../librbd/object_map/test_mock_RefreshRequest.cc  |   59 +-
 .../librbd/object_map/test_mock_ResizeRequest.cc   |   11 +-
 .../object_map/test_mock_SnapshotCreateRequest.cc  |    9 +-
 .../object_map/test_mock_SnapshotRemoveRequest.cc  |   19 +-
 .../test_mock_SnapshotRollbackRequest.cc           |    7 +-
 .../librbd/object_map/test_mock_UnlockRequest.cc   |    3 +-
 .../librbd/object_map/test_mock_UpdateRequest.cc   |   11 +-
 .../librbd/operation/test_mock_ResizeRequest.cc    |    3 +-
 .../operation/test_mock_SnapshotCreateRequest.cc   |    7 +-
 .../operation/test_mock_SnapshotProtectRequest.cc  |    5 +-
 .../operation/test_mock_SnapshotRemoveRequest.cc   |    9 +-
 .../operation/test_mock_SnapshotRollbackRequest.cc |   77 +-
 .../test_mock_SnapshotUnprotectRequest.cc          |    7 +-
 src/test/librbd/test_ImageWatcher.cc               |   52 +-
 src/test/librbd/test_fixture.cc                    |    2 +-
 src/test/librbd/test_internal.cc                   |   19 +-
 src/test/librbd/test_librbd.cc                     |  222 +-
 src/test/librbd/test_main.cc                       |    2 +
 src/test/librbd/test_mirroring.cc                  |  219 +
 src/test/librbd/test_mock_ExclusiveLock.cc         |  131 +-
 src/test/librbd/test_mock_Journal.cc               |  242 +-
 src/test/librbd/test_mock_fixture.cc               |   15 +-
 src/test/librbd/test_mock_fixture.h                |    2 +-
 src/test/librgw_file.cc                            |  292 +
 src/test/librgw_file_aw.cc                         |  352 ++
 src/test/librgw_file_cd.cc                         |  182 +
 src/test/librgw_file_gp.cc                         |  484 ++
 src/test/librgw_file_nfsns.cc                      | 1019 ++++
 src/test/msgr/test_msgr.cc                         |    2 +-
 src/test/objectstore/store_test.cc                 |  186 +-
 src/test/objectstore/test_transaction.cc           |  114 +
 src/test/objectstore_bench.cc                      |    4 +-
 src/test/opensuse-13.2/ceph.spec.in                |  119 +-
 src/test/osd/TestOSDMap.cc                         |    8 +-
 src/test/osd/TestPGLog.cc                          |    7 +
 src/test/osd/TestRados.cc                          |    7 +
 src/test/osd/osd-markdown.sh                       |   32 +-
 src/test/osd/types.cc                              |   18 +-
 src/test/pybind/test_ceph_argparse.py              |   20 +-
 src/test/pybind/test_ceph_daemon.py                |    7 +-
 src/test/rbd_mirror/image_replay.cc                |  224 +
 .../image_sync/test_mock_ImageCopyRequest.cc       |  451 ++
 .../image_sync/test_mock_ObjectCopyRequest.cc      |  550 ++
 .../image_sync/test_mock_SnapshotCopyRequest.cc    |  239 +
 .../image_sync/test_mock_SyncPointCreateRequest.cc |  142 +
 .../image_sync/test_mock_SyncPointPruneRequest.cc  |  219 +
 src/test/rbd_mirror/mock/MockJournaler.cc          |   10 +
 src/test/rbd_mirror/mock/MockJournaler.h           |   42 +
 src/test/rbd_mirror/test_ClusterWatcher.cc         |   34 +-
 src/test/rbd_mirror/test_ImageReplayer.cc          |  648 ++
 src/test/rbd_mirror/test_ImageSync.cc              |  130 +
 src/test/rbd_mirror/test_PoolWatcher.cc            |   29 +-
 src/test/rbd_mirror/test_fixture.cc                |  101 +
 src/test/rbd_mirror/test_fixture.h                 |   61 +
 src/test/rbd_mirror/test_main.cc                   |    4 +
 src/test/rbd_mirror/test_mock_ImageSync.cc         |  337 ++
 src/test/rbd_mirror/test_mock_fixture.cc           |   59 +
 src/test/rbd_mirror/test_mock_fixture.h            |   53 +
 src/test/rgw/test_rgw_period_history.cc            |  330 ++
 src/test/run-rbd-unit-tests.sh                     |    2 +-
 src/test/strtol.cc                                 |   21 +
 src/test/system/rados_watch_notify.cc              |    4 +-
 src/test/test_filejournal.cc                       |   20 +
 src/test/test_pageset.cc                           |   12 +
 src/test/test_pidfile.sh                           |   53 +-
 src/test/test_pool_create.sh                       |   58 +
 src/test/test_rgw_admin_log.cc                     |   30 +-
 src/test/test_rgw_admin_opstate.cc                 |    2 +-
 src/test/test_striper.cc                           |   27 +-
 src/test/test_subprocess.cc                        |   32 +-
 src/tools/Makefile-client.am                       |   37 +-
 src/tools/Makefile-server.am                       |    3 +
 src/tools/Makefile.am                              |    3 +-
 src/tools/ceph_conf.cc                             |    2 +
 src/tools/ceph_objectstore_tool.cc                 |    2 +-
 src/tools/cephfs/DataScan.cc                       |  570 +-
 src/tools/cephfs/DataScan.h                        |   44 +-
 src/tools/cephfs/Dumper.cc                         |   33 +-
 src/tools/cephfs/Dumper.h                          |    8 +-
 src/tools/cephfs/EventOutput.cc                    |    2 +-
 src/tools/cephfs/JournalScanner.cc                 |    2 +-
 src/tools/cephfs/JournalTool.cc                    |   82 +-
 src/tools/cephfs/JournalTool.h                     |    6 +-
 src/tools/cephfs/MDSUtility.cc                     |   18 +-
 src/tools/cephfs/MDSUtility.h                      |    8 +-
 src/tools/cephfs/Resetter.cc                       |   29 +-
 src/tools/cephfs/Resetter.h                        |    4 +-
 src/tools/cephfs/RoleSelector.cc                   |   58 +
 src/tools/cephfs/RoleSelector.h                    |   35 +
 src/tools/cephfs/TableTool.cc                      |  122 +-
 src/tools/cephfs/TableTool.h                       |    9 +-
 src/tools/psim.cc                                  |    1 -
 src/tools/rados/rados.cc                           |  242 +-
 src/tools/rbd/ArgumentTypes.cc                     |   12 +-
 src/tools/rbd/Utils.cc                             |   16 +
 src/tools/rbd/Utils.h                              |    2 +
 src/tools/rbd/action/Clone.cc                      |    1 +
 src/tools/rbd/action/Export.cc                     |    1 +
 src/tools/rbd/action/ImportDiff.cc                 |    1 +
 src/tools/rbd/action/Info.cc                       |   30 +
 src/tools/rbd/action/Journal.cc                    |    8 +-
 src/tools/rbd/action/MergeDiff.cc                  |    1 +
 src/tools/rbd/action/MirrorImage.cc                |  213 +
 src/tools/rbd/action/MirrorPool.cc                 |  178 +-
 src/tools/rbd/action/Snap.cc                       |    2 +-
 src/tools/rbd_mirror/ClusterWatcher.cc             |   10 +-
 src/tools/rbd_mirror/ImageReplayer.cc              |  850 ++-
 src/tools/rbd_mirror/ImageReplayer.h               |  175 +-
 src/tools/rbd_mirror/ImageSync.cc                  |  310 +
 src/tools/rbd_mirror/ImageSync.h                   |  122 +
 src/tools/rbd_mirror/Mirror.cc                     |   23 +-
 src/tools/rbd_mirror/Mirror.h                      |    6 +-
 src/tools/rbd_mirror/PoolWatcher.cc                |   51 +-
 src/tools/rbd_mirror/Replayer.cc                   |  137 +-
 src/tools/rbd_mirror/Replayer.h                    |   11 +-
 src/tools/rbd_mirror/Threads.cc                    |   38 +
 src/tools/rbd_mirror/Threads.h                     |   34 +
 .../rbd_mirror/image_replayer/BootstrapRequest.cc  |  302 +
 .../rbd_mirror/image_replayer/BootstrapRequest.h   |  137 +
 .../rbd_mirror/image_replayer/CloseImageRequest.cc |   84 +
 .../rbd_mirror/image_replayer/CloseImageRequest.h  |   66 +
 .../image_replayer/OpenLocalImageRequest.cc        |  140 +
 .../image_replayer/OpenLocalImageRequest.h         |   87 +
 .../rbd_mirror/image_sync/ImageCopyRequest.cc      |  287 +
 src/tools/rbd_mirror/image_sync/ImageCopyRequest.h |  119 +
 .../rbd_mirror/image_sync/ObjectCopyRequest.cc     |  364 ++
 .../rbd_mirror/image_sync/ObjectCopyRequest.h      |  129 +
 .../rbd_mirror/image_sync/SnapshotCopyRequest.cc   |  255 +
 .../rbd_mirror/image_sync/SnapshotCopyRequest.h    |  112 +
 .../image_sync/SyncPointCreateRequest.cc           |  162 +
 .../rbd_mirror/image_sync/SyncPointCreateRequest.h |   90 +
 .../rbd_mirror/image_sync/SyncPointPruneRequest.cc |  202 +
 .../rbd_mirror/image_sync/SyncPointPruneRequest.h  |   94 +
 src/tools/rbd_mirror/main.cc                       |    7 +-
 src/tools/rbd_mirror/types.cc                      |    4 +-
 src/tools/rbd_mirror/types.h                       |   12 +-
 src/tools/setup-virtualenv.sh                      |   16 +-
 src/tracing/librados.tp                            |  110 +
 src/tracing/objectstore.tp                         |   13 +
 src/tracing/tracing-common.h                       |    6 +
 src/upstart/ceph-rbd-mirror-all-starter.conf       |   18 +
 src/upstart/ceph-rbd-mirror-all.conf               |    4 +
 src/upstart/ceph-rbd-mirror.conf                   |   26 +
 src/vstart.sh                                      |   60 +-
 src/xxHash/xxhash.c                                | 1012 ++++
 src/xxHash/xxhash.h                                |  255 +
 systemd/Makefile.am                                |    2 +
 systemd/Makefile.in                                |   29 +-
 systemd/ceph-rbd-mirror.target                     |    5 +
 systemd/ceph-rbd-mirror at .service                   |   22 +
 test-driver                                        |   15 +-
 udev/95-ceph-osd.rules                             |   19 +
 938 files changed, 101134 insertions(+), 67423 deletions(-)

diff --git a/AUTHORS b/AUTHORS
index 4c014a1..192b334 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -1,6 +1,8 @@
+Aaron Bassett <abassett at gmail.com>
 Abhishek Dixit <dixitabhi at gmail.com>
 Abhishek Lekshmanan <abhishek.lekshmanan at ril.com>
 Abhishek Lekshmanan <abhishek at suse.com>
+Abhishek Varshney <abhishek.varshney at flipkart.com>
 Accela Zhao <accelazh at gmail.com>
 Adam C. Emerson <aemerson at linuxbox.com>
 Adam C. Emerson <aemerson at redhat.com>
@@ -48,12 +50,13 @@ apovzner <apovzner at 29311d96-e01e-0410-9327-a35deaab8ce9>
 Ariela <Dell at ARIELA.(none)>
 Aristoteles Neto <aristoteles.neto at webdrive.co.nz>
 Armando Segnini <armaseg at gmail.com>
+Aron Gunn <ritz_303 at yahoo.com>
 Arthur Gorjux <arthurgorjux at gmail.com>
 Ashish Chandra <ashish.a.chandra at ril.com>
-atwardowski <adam.twardowski at gmail.com>
+Avner BenHanoch <avnerb at mellanox.com>
 Babu Shanmugam <anbu at enovance.com>
 Baptiste Veuillez <baptiste.veuillez--mainard at telecom-bretagne.eu>
-Barbora Ančincová <bancinco at redhat.com>
+Barbora Ančincová <bara at redhat.com>
 Bastian Blank <waldi at debian.org>
 Benjamin Kerensa <bkerensa at gmail.com>
 Benoît Knecht <benoit.knecht at fsfe.org>
@@ -84,7 +87,6 @@ Casey Marshall <csm at soe.ucsc.edu>
 CC Lien <cc_lien at tcloudcomputing.com>
 Ce Gu <guce at h3c.com>
 Cesar Mello <cesar at d1.(none)>
-changtao <changtao at hihuron.com>
 Chen Baozi <baozich at gmail.com>
 Chen Dihao <tobeg3oogle at gmail.com>
 Chendi Xue <chendi.xue at intel.com>
@@ -100,7 +102,6 @@ Christophe Courtaut <christophe.courtaut at gmail.com>
 Christopher O'Connell <jwriteclub at gmail.com>
 Christoph Hellwig <hch at infradead.org>
 Christos Stavrakakis <stavr.chris at gmail.com>
-chuanhong-wang <chuanhong.wang at 163.com>
 Chuanhong Wang <wang.chuanhong at zte.com.cn>
 Cilang Zhao <zhao.cilang at h3c.com>
 Claire Massot <claire.massot93 at gmail.com>
@@ -132,15 +133,18 @@ Dmytro Iurchenko <diurchenko at mirantis.com>
 Dominik Hannen <cantares1+github at gmail.com>
 Donghai Xu <xu.donghai at h3c.com>
 Dongmao Zhang <deanraccoon at gmail.com>
+Dongsheng Yang <dongsheng.yang at easystack.cn>
 Dongsu Park <dpark1978 at gmail.com>
 Dong Yuan <yuandong1222 at gmail.com>
 Douglas Fuller <dfuller at redhat.com>
 Drunkard Zhang <gongfan193 at gmail.com>
 Dunrong Huang <dunrong.huang at eayun.com>
 Dunrong Huang <riegamaths at gmail.com>
+Edward Yang <eyang at us.fujitsu.com>
 Eleanor Cawthon <eleanor.cawthon at inktank.com>
 Emile Snyder <emsnyder at ebay.com>
 Emily Popper <emily.popper at dreamhost.com>
+Eric Cook <llua at gmx.com>
 Eric Mourgaya <eric.mourgaya at arkea.com>
 Erik Logtenberg <erik at logtenberg.eu>
 Erwan Velu <erwan at redhat.com>
@@ -173,7 +177,6 @@ George Ryall <george.ryall at stfc.ac.uk>
 Gerben Meijer <gerben at daybyday.nl>
 Gerhard Muntingh <gerhard at warpnet.nl>
 Germain Chipaux <germain.chipaux at gmail.com>
-git-harry <git-harry at live.co.uk>
 Greg Farnum <gfarnum at redhat.com>
 Greg Farnum <greg at inktank.com>
 Gregory Meno <gmeno at redhat.com>
@@ -186,6 +189,7 @@ Hannes Reinecke <hare at suse.de>
 Hannu Valtonen <hannu.valtonen at ormod.com>
 Haomai Wang <haomai at xsky.com>
 Harpreet Dhillon <harpreet at ironsystems.com>
+Harry Harrington <git-harry at live.co.uk>
 Hazem Amara <hazem.amara at telecom-bretagne.eu>
 Hector Martin <marcan at marcan.st>
 Henry C Chang <henry_c_chang at tcloudcomputing.com>
@@ -195,7 +199,6 @@ Hervé Rousseau <hroussea at cern.ch>
 Holger Macht <hmacht at suse.de>
 Huamin Chen <hchen at redhat.com>
 Huang Jun <hjwsm1989 at gmail.com>
-huanwen ren <ren.huanwen at zte.com.cn>
 Ian Holsman <lists at holsman.net>
 Ian Kelling <ian at iankelling.org>
 Igor Fedotov <ifedotov at mirantis.com>
@@ -209,18 +212,21 @@ Ismael Serrano <ismael.serrano at gmail.com>
 Ivan Grcic <igrcic at gmail.com>
 Jacek J. Lakis <jacek.lakis at intel.com>
 Jacek J. Łakis <jacek.lakis at intel.com>
+James Liu <james.liu at ssi.samsung.com>
 James Page <james.page at ubuntu.com>
 James Ryan Cresawn <jrcresawn at gmail.com>
 Jan Harkes <jaharkes at cs.cmu.edu>
 Janne Grunau <j at jannau.net>
 Jashan Kamboj <jashank42 at gmail.com>
 Jason Dillaman <dillaman at redhat.com>
+Javen Wu <javen.wu at xtaotech.com>
 Javier Guerra <javier at guerrag.com>
 Javier M. Mellid <jmunhoz at igalia.com>
 Jean-Rémi Deveaux <jeanremi.deveaux at gmail.com>
 Jeff Epstein <jepst79 at gmail.com>
-Jeffrey Lu <lzhng2000 at hotmail.com>
+Jeffrey Lu <lzhng2000 at aliyun.com>
 Jeff Weber <jweber at cofront.net>
+Jenkins Build Slave User <jenkins-build at trusty-small-unique--e64d6d03-305d-46bd-9a2c-9b546e06937e.localdomain>
 Jenkins <jenkins at ceph.com>
 Jens-Christian Fischer <jens-christian.fischer at switch.ch>
 Jeremy Qian <vanpire110 at 163.com>
@@ -234,12 +240,11 @@ Jiaying Ren <mikulely at gmail.com>
 Ji Chen <insomnia at 139.com>
 Jie Wang <jie.wang at kylin-cloud.com>
 Jim Schutt <jaschut at sandia.gov>
-jingkai <jingkai.yuan at intel.com>
+Jingkai Yuan <jingkai.yuan at intel.com>
 João Eduardo Luís <joao.luis at inktank.com>
 João Eduardo Luís <joao at redhat.com>
-Joao Eduardo Luis <joao at suse.de>
+João Eduardo Luís <joao at suse.de>
 Joaquim Rocha <joaquim.rocha at cern.ch>
-joconcepts <jonas at jonas-keidel.de>
 Joe Buck <jbbuck at gmail.com>
 Joe Handzik <joseph.t.handzik at hp.com>
 Joe Julian <jjulian at io.com>
@@ -251,6 +256,7 @@ Johnu George <johnugeo at cisco.com>
 John Wilkins <john.wilkins at inktank.com>
 John Wilkins <jwilkins at redhat.com>
 Jojy George Varghese <jvarghese at scalecomputing.com>
+Jonas Keidel <jonas at jonas-keidel.de>
 Jonathan Davies <jonathan.davies at canonical.com>
 Jonathan Dieter <jdieter at lesbg.com>
 Jon Bernard <jbernard at tuxion.com>
@@ -269,6 +275,7 @@ Kadu Ribeiro <mail+github at carlosribeiro.me>
 Kai Zhang <zakir.exe at gmail.com>
 Karel Striegel <karel.striegel at ipc.be>
 Karl Eichwalder <ke at suse.de>
+Karol Mroz <kmroz at suse.com>
 Kefu Chai <kchai at redhat.com>
 Ken Dreyer <kdreyer at redhat.com>
 Ken Dreyer <ken.dreyer at inktank.com>
@@ -279,14 +286,12 @@ Kevin Dalley <kevin at kelphead.org>
 Kevin Jones <k.j.jonez at gmail.com>
 Kim Vandry <vandry at TZoNE.ORG>
 Kiseleva Alyona <akiselyova at mirantis.com>
-Kongming <wu.kongming at h3c.com>
 Kongming Wu <wu.kongming at h3c.com>
 Krzysztof Kosiński <krzysztof.kosinski at intel.com>
 Kuan Kai Chiu <big.chiu at bigtera.com>
 Kun Huang <academicgareth at gmail.com>
 Kyle Bader <kyle.bader at dreamhost.com>
 Kyle Marsh <kyle.marsh at dreamhost.com>
-lafont <francois.lafont at ac-versailles.fr>
 Laszlo Boszormenyi <gcs at debian.hu>
 Laurent Barbe <laurent at ksperis.com>
 Lee Revell <rlrevell at gmail.com>
@@ -294,22 +299,26 @@ Lei Dong <leidong at yahoo-inc.com>
 Lenz Grimmer <lenz at grimmer.com>
 Liam Monahan <liam at umiacs.umd.edu>
 Li Peng <lip at dtdream.com>
-litianqing <tianqing at unitedstack.com>
+Li Tianqing <tianqing at unitedstack.com>
+Liu Peiyan <liu.peiyang at h3c.com>
 Li Wang <li.wang at kylin-cloud.com>
+liyankun <liyankun at unitedstack.com>
 Lluis Pamies-Juarez <lluis.pamies-juarez at hgst.com>
 Loic Dachary <ldachary at redhat.com>
 Loic Dachary <loic-201408 at dachary.org>
 Loic Dachary <loic at dachary.org>
 Lucas Fantinel <lucas.fantinel at gmail.com>
 Luis Pabón <lpabon at redhat.com>
+Luis Periquito <luis.periquito at ocado.com>
 Lukasz Jagiello <lukasz at wikia-inc.com>
+Luo Kexue <luo.kexue at zte.com.cn>
 Lu Shi <shi.lu at h3c.com>
 Ma Jianpeng <jianpeng.ma at intel.com>
 Marcel Lauhoff <lauhoff at uni-mainz.de>
-Marcel Lauhoff <ml at irq0.org>
 Marc Koderer <marc at koderer.com>
 Marco Garcês <marco.garces at bci.co.mz>
 Marcus Sorensen <shadowsor at gmail.com>
+Marcus Watts <mwatts at redhat.com>
 Mark Kampe <mark.kampe at dreamhost.com>
 Mark Nelson <mark.nelson at inktank.com>
 Mark Nelson <mnelson at redhat.com>
@@ -323,7 +332,7 @@ Matthew Wodrich <matthew.wodrich at dreamhost.com>
 Matt Richards <mattjrichards at gmail.com>
 Mauricio Garavaglia <mauriciogaravaglia at gmail.com>
 Maxime Robert <maxime.robert1992 at gmail.com>
-Mehdi Abaakouk <sileht at sileht.net>
+Mehdi Abaakouk <sileht at redhat.com>
 Michael McThrow <mmcthrow at gmail.com>
 Michael Nelson <mikenel at tnld.net>
 Michael Riederer <michael at riederer.org>
@@ -332,6 +341,7 @@ Michal Jarzabek <stiopa at gmail.com>
 Mike Kelly <pioto at pioto.org>
 Mike Lundy <mike at fluffypenguin.org>
 Mike Ryan <mike.ryan at inktank.com>
+Mike Shuey <shuey at purdue.edu>
 Milan Broz <mbroz at redhat.com>
 Min Chen <minchen at ubuntukylin.com>
 MingXin Liu <mingxin.liu at kylin-cloud.com>
@@ -380,13 +390,15 @@ Rajesh Nambiar <rajesh.n at msystechnologies.com>
 Raju Kurunkad <raju.kurunkad at sandisk.com>
 Ray Lv <xiangyulv at gmail.com>
 rca <bertosmailbox at gmail.com>
+Rémi Buisson <remi.buisson at cdiscount.com>
 Ren Huanwen <ren.huanwen at zte.com.cn>
+Ricardo Dias <rdias at suse.com>
 riccardo80 <riccardo80 at 29311d96-e01e-0410-9327-a35deaab8ce9>
 Riccardo Ferretti <rferrett at soe.ucsc.edu>
-ritz303 <ritz_303 at yahoo.com>
 Roald J. van Loon <roald at roaldvanloon.nl>
 Robert Jansen <r.jansen at fairbanks.nl>
 Robert LeBlanc <robert.leblanc at endurance.com>
+Robert LeBlanc <robert at leblancnet.us>
 Robin Dehu <robindehu at gmail.com>
 Robin H. Johnson <robbat2 at gentoo.org>
 Robin H. Johnson <robin.johnson at dreamhost.com>
@@ -396,14 +408,13 @@ Roi Dayan <roid at mellanox.com>
 Roman Haritonov <reclosedev at gmail.com>
 Ron Allred <rallred at itrefined.com>
 Rongze Zhu <zrzhit at gmail.com>
-root <liu.peiyang at h3c.com>
-root <root at clove83.zte.com.cn>
 root <root at phenom.dyweni.com>
 Ross Turk <ross.turk at inktank.com>
 Ross Turk <rturk at redhat.com>
 Ruben Kerkhof <ruben at rubenkerkhof.com>
 Ruifeng Yang <yangruifeng.09209 at h3c.com>
 runsisi <runsisi at hust.edu.cn>
+RustShen <rustinpeace at 163.com>
 Rutger ter Borg <rutger at terborg.net>
 Sage Weil <sage at inktank.com>
 Sage Weil <sweil at redhat.com>
@@ -415,7 +426,7 @@ Samuel Just <sjust at redhat.com>
 Sandon Van Ness <sandon at inktank.com>
 Sandon Van Ness <svanness at redhat.com>
 Sangdi Xu <xu.sangdi at h3c.com>
-scienceluo <scienceluo at qq.com>
+Sarthak Munshi <sarthakmunshi at gmail.com>
 Scott A. Brandt <scott at cs.ucsc.edu>
 Scott Devoid <devoid at anl.gov>
 Sean Channel <pentabular at gmail.com>
@@ -426,17 +437,18 @@ Shang Ding <dingshang2013 at 163.com>
 Shanggao Qiu <qiushanggao at qq.com>
 Sharif Olorin <sio at tesser.org>
 Shawn Edwards <lesser.evil at gmail.com>
-shishir gowda <shishir.gowda at sandisk.com>
+Shishir Gowda <shishir.gowda at sandisk.com>
 Shotaro Kawaguchi <kawaguchi.s at jp.fujitsu.com>
-shun-s <songshun134 at 126.com>
+Shun Song <song.shun3 at zte.com.cn>
 Shu, Xinxin <xinxin.shu at intel.com>
 Shylesh Kumar <shmohan at redhat.com>
 Siddharth Sharma <siddharth at redhat.com>
+Signed-off-by: Eric Lee <eric.lee at hgst.com>
 Simone Gotti <simone.gotti at gmail.com>
 Simon Leinen <simon.leinen at switch.ch>
 Somnath Roy <somnath.roy at sandisk.com>
 Sondra.Menthers <sondra.menthers at dreamhost.com>
-songbaisen <song.baisen at zte.com.cn>
+Song Baisen <song.baisen at zte.com.cn>
 Stanislav Sedov <stas at FreeBSD.org>
 Stefan Eilemann <Stefan.Eilemann at epfl.ch>
 Stephan Renatus <s.renatus at x-ion.de>
@@ -447,6 +459,7 @@ Steve MacGregor <grape at lapgoat-0.(none)>
 Steve Stock <steve at technolope.org>
 Stratos Psomadakis <psomas at grnet.gr>
 Stuart Longland <stuartl at vrt.com.au>
+Subramanyam Varanasi <s.varanasi at ssi.samsung.com>
 Sushma Gurram <sushma.gurram at sandisk.com>
 Swami Reddy <swami.reddy at ril.com>
 Sylvain Baubeau <sbaubeau at redhat.com>
@@ -455,6 +468,7 @@ Takanori Nakao <nakao.takanori at jp.fujitsu.com>
 Takeshi Miyamae <miyamae.takeshi at jp.fujitsu.com>
 Takuya ASADA <syuu at dokukino.com>
 Tamil Muthamizhan <tamil.muthamizhan at inktank.com>
+Tao Chang <changtao at hihuron.com>
 Thomas Bechtold <t.bechtold at telekom.de>
 Thomas Cantin <thomas.cantin at telecom-bretagne.eu>
 Thomas Johnson <NTmatter at gmail.com>
@@ -465,7 +479,6 @@ Thorsten Glaser <tg at mirbsd.de>
 Tianshan Qu <tianshan at xsky.com>
 Tim Freund <tim at freunds.net>
 Tim Serong <tserong at suse.com>
-tmuthamizhan <tamil.muthamizhan at inktank.com>
 Tobias Florek <tobias.florek at bytesandbutter.de>
 Tobias Suckow <tobias at suckow.biz>
 Tomasz Paskowski <ss7pro at gmail.com>
@@ -500,49 +513,51 @@ Wei Qian <weiq at dtdream.com>
 Wenjun Huang <wenjunhuang at tencent.com>
 Wesley Spikes <wesley.spikes at dreamhost.com>
 Wido den Hollander <wido at 42on.com>
+Willem Jan Withagen <wjw at digiware.nl>
 William A. Kennington III <william at wkennington.com>
-wuxiangwei <wuxiangwei at h3c.com>
 Wu Xingyi <wuxingyi at letv.com>
 Wyllys Ingersoll <wyllys.ingersoll at keepertech.com>
 Xan Peng <xanpeng at gmail.com>
 Xavier Roche <roche+git at exalead.com>
+Xiangwei Wu <wuxiangwei at h3c.com>
 Xiaowei Chen <chen.xiaowei at h3c.com>
 Xiaoxi Chen <xiaoxi.chen at intel.com>
 Xie Rui <875016668 at qq.com>
-xie xingguo <xie.xingguo at zte.com.cn>
-xie.xingguo <xie.xingguo at zte.com.cn>
-xiexingguo <xie.xingguo at zte.com.cn>
 Xie Xingguo <xie.xingguo at zte.com.cn>
 Xihui He <xihuihe at gmail.com>
 Xing Lin <xinglin at cs.utah.edu>
 Xingyi Wu <wuxingyi2015 at outlook.com>
+Xinze Chi <xinze at xksy.com>
 Xinze Chi <xinze at xsky.com>
 Xiong Yiliang <xiongyiliang at xunlei.com>
 Xuan Liu <liu.xuan at h3c.com>
-YankunLi <YankunLi at users.noreply.github.com>
+Yan Jun <yan.jun8 at zte.com.cn>
+Yankun Li <liyankun at unitedstack.com>
 Yann Dupont <yann at objoo.org>
 Yannick Atchy Dalama <yannick.atchy.dalama at gmail.com>
 Yan, Zheng <zheng.z.yan at intel.com>
 Yan, Zheng <zyan at redhat.com>
 Yazen Ghannam <yazen.ghannam at linaro.org>
 Yehua Chen <chen.yehua at h3c.com>
-Yehua <chen.yehua at h3c.com>
 Yehuda Sadeh <yehuda at inktank.com>
 Yehuda Sadeh <ysadehwe at redhat.com>
 YiQiang Chen <cyqsign at 163.com>
 Yongqiang He <he.yongqiang at h3c.com>
 Yongyue Sun <abioy.sun at gmail.com>
+You Ji <jiyou09 at gmail.com>
 You Ji <youji at ebay.com>
 Yuan Zhou <yuan.zhou at intel.com>
 Yunchuan Wen <yunchuan.wen at kylin-cloud.com>
 Yuri Weinstein <yuri.weinstein at inktank.com>
+Zack Cerza <zack at cerza.org>
+Zack Cerza <zack at redhat.com>
 Zengran Zhang <zhangzengran at h3c.com>
 Zeqiang Zhuang <zhuang.zeqiang at h3c.com>
 Zhang Huan <zhanghuan at ict.ac.cn>
+Zhao Junwang <zhjwpku at gmail.com>
 Zhe Zhang <zzxuanyuan at gmail.com>
 Zhicheng Wei <zhicheng at opensourceforge.net>
 Zhi (David) Zhang <zhangz at yahoo-inc.com>
 Zhiqiang Wang <zhiqiang.wang at intel.com>
 Zhiqiang Wang <zhiqiang at xsky.com>
 Zhi Zhang <willzzhang at tencent.com>
-Zhi Zhang <zhangz.david at outlook.com>
diff --git a/ChangeLog b/ChangeLog
index ee94175..1ed7bd1 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,41 +1,2284 @@
-5acb265 (HEAD, tag: v10.0.5) v10.0.5
+96ae8bd (HEAD, tag: v10.1.0, origin/jewel) 10.1.0
+5b3da26 Makefile-env.am: set a default for CEPH_BUILD_VIRTUALENV
+fa05d80 debian/control: try installing virtualenv first, if it exists
+eb583cb build/ops: in jessie virtualenv is in package virtualenv
+c540835 python: avoid long paths (part 2)
+93c790d python: avoid long paths
+c9245e7 rgw: fix error message for zone delete
+88d35e9 rgw_ldap:  move update of s->perm_mask
+6ffa9c7 rgw_ldap:  two bug fixes
+acea6ef rgw: fix zone delete message
+127c26f cls_rbd: throw error if set_features mask included non-mutable feature
+ba1dd35 mon: fix mixed-version MDSMonitor
+c4364b1 packaging: align radosgw package description
+bbac766 rbd-mirror: fix long termination due to 30sec wait in Mirror::run loop
+9f6ec70 qa: add workunit to run ceph_test_rbd_mirror
+9722dee journal: prevent race injecting new records into overflowed object
+f5375dc packaging: added rbd-mirror startup scripts
+58d4734 upstart: new rbd-mirror daemon scripts
+8a0e472 systemd: new ceph-rbd-mirror scripts
+ebbfdc7 test_pool_create.sh: put test files in the test dir so they are cleaned up
+d9017fb qa/workunits/rbd: new online maintenance op tests
+fab2144 cls/rgw: fix use of timespan
+959ae39 ceph_test_rados_misc: shorten mount timeout
+8b9ed00 os/filestore: fix warning
+811b8f5 qa/workunits/rest/test.py: don't use newfs
+a619468 rbd: rbd-mirroring: Added unit tests to test image mirroring behaviour
+6ebb4f3 rbd: rbd-mirroring: Fixed if clause in mirror_image_get_info
+c472493 rbd: rbd-mirroring: Disable image mirroring when journaling feature is disabled
+ba6c0c9 rbd: rbd-mirroring: Enable image mirroring when journaling feature is enabled
+7385d4a rbd: rbd-mirroring: Enable image mirroring upon create with journaling feature
+425546a rgw: use current period id when it is empty for mdlog list and shard lock/unlock
+4e3cf59 osd: assert that we don't try to use an OSDMap > superblock.newest_map
+b839a06 osd: commit osdmaps before exposing them to PGs
+30e0f92 os/bluestore/BlueFS: Before reap ioct, it should wait io complete.
+f8cca62 mon: ignore msg without session attached
+b0d9b0d mon: remove 'mds setmap' command
+13c7ba4 test: rbd-mirror: different log and asok location for local/remote contexts
+21e127b rbd-mirror: make remote context respect env and argv config params
+c399d31 doc/architecture.rst: remove redundant word "across"
+3800e2b rbd-mirror: command line options should override environment
+06d22ef os/bluestore: rename need_size to want_size in StupidAllocator.
+d571be2 os/bluestore: avoid duplicated searches during allocating free extents
+4d45a3f features: deprecate CEPH_FEATURE_OSD_PROXY_FEATURES
+9aeaf5c features: deprecate CEPH_FEATURE_OSD_MIN_SIZE_RECOVERY
+d2eb101 features: deprecate CEPH_FEATURE_OSD_TRANSACTION_MAY_LAYOUT
+35e2585 features: deprecate CEPH_FEATURE_OSD_OBJECT_DIGEST
+333e988 features,osd/: deprecate CEPH_FEATURE_OSD_REPOP feature bit
+b0ba592 features: deprecate CEPH_FEATURE_OSD_SET_ALLOC_HINT
+9b27e73 features: deprecate CEPH_FEATURE_PACKED_RECOVERY
+fd3b67e features: deprecate CEPH_FEATURE_MON_SCRUB
+9326c2b features: deprecate CEPH_OSD_FEATURE_SNAPMAPPER
+f7af866 features: free CEPH_FEATURE_OSD_HBMSGS, not used since before hammer
+ccbceef features: deprecate CEPH_FEATURE_RECOVERY_RESERVATION
+4591dc0 features: deprecate CEPH_FEATURE_BACKFILL_RESERVATON
+bdcff31 features: free CEPH_FEATURE_MON_GV bit, hasn't been used since before hammer
+2a62b03 features: deprecate CEPH_FEATURE_MON_NULLROUTE
+37518a3 features: deprecate CEPH_FEATURE_CHUNKY_SCRUB
+ac443a8 features: deprecate CEPH_FEATURE_INDEP_PG_MAP
+c21b796 features: deprecate CEPH_FEATURE_QUERY_T
+cb325b2 features: free CEPH_FEATURE_OMAP bit, hasn't been used since before hammer
+f381390 features: deprecate CEPH_FEATURE_MONCLOCKCHECK
+60429c3 rgw: take a reference to the cr in async cr workers
+1f74171 rgw: finalize reqs through a temporary set
+4083271 rgw: update data_log only when completing the op
+9d2d090 doc: initial draft of RBD mirroring admin documentation
+b15ff2f test: rbd-mirror: compare positions using all fields
+e348a7e rbd-mirror: use pool/image names in asok commands
+1539d90 rgw-ldap: conditional build
+9789c29 osd: populate the trim_thru epoch using MOSDMap.oldest_map
+81b07be mstart: start rgw on different ports as well
+e81c81b rbd: rbd-mirror: PoolWatcher watches for mirroring enabled images
+2842c07 rgw/rgw_common.h: fix the RGWBucketInfo decoding
+0abff12 osd/ReplicatedPG: clear watches on change after applying repops
+35afd5a bluestore/NVMEDevice: make IO thread using dpdk launch
+50b53ea qa/workunits/rbd: rbd_mirror was extracting the incorrect image id
+f2e3988 qa/workunits/rbd: use unique logs for each rbd-mirror daemon
+3cf8952 journal: refetch active object before defaulting to new tag
+3895878 rgw/rgw_common.h: fix the RGWBucketInfo decoding
+ff3f0f8 ceph.spec.in: Make ceph-common require libcephfs1
+cd4751a test: rbd-mirror: add "switch to the next tag" test
+f03f99d cls/rgw: fix FTBFS
+4411179 librbd: implement mirror image resync request API
+d1a6c7c librbd: track if a mirror image resync has been requested
+353f895 journal: add placeholder for marking clients are disconnected
+e5f2bb0 librbd: initial implementation of mirror image promote/demote
+f3cd04c librbd: helper methods for manipulating journal tags from API
+74097f3 rbd: dump mirroring primary status on info command
+c8aa842 librbd: expose image mirroring primary/secondary status
+7be4022 test: update rbd cli tests to incorporate new mirror image commands
+04073d8 rbd: add mirror image promote/demote/resync commands
+4d70ff4 librbd: stub API methods for mirror image promotion/demotion/resync
+e925948 rgw: Allow an implicit tenant in case of Keystone
+70ca604 rgw: data shard sync doesn't exit on error
+a028989 rgw ldap: s/memberattr/dnattr/;
+1c5e225 rgw: propagate low time precision for user operations
+809cabf rgw: use higher precision time when encoding / decoding external apis
+6bfaa7e utime: add gmtime_nsec()
+e82a801 rgw: extend date/time parsing
+fe6dc35 packaging: remove sub-package dependencies on "ceph"
+a7fcab1 osd: handle_osd_map whitespace
+5f3f37f packaging: move cephfs repair tools to ceph-common
+921409f journal: reschedule watch if no entries available during live replay
+4c42b95 librbd: correct valgrind memcheck errors
+36af39c qa/workunits/rbd: disable deep-flatten during permissions testing
+c287d79 tools/cephfs: fix tmap_upgrade
+8a72491 rbd: snap list should open image as read-only
+6e124b9 test_msgr: reduce test size to fix memory size
+31f9454 test: add missing shut_down mock method
+2ae1be4 qa/workunits/rbd: handle exception thrown from close during lock test
+80dc454 os/filestore: fix result code overwritten
+736a944 os/filestore: make sloppy_crc can catch fatal error for read()
+ccb395d os/filestore: fix result code overwritten for snapshot()
+ca2f2b1 os/filestore: fast exit if we fail to load exomap
+de3e3a9 os/filestore: remove duplicated lfn_close to same fd
+bbde2f0 os/filestore: exit if we fail to remove any xattr
+3214ae9 RPM: fix openldap and openssl build dependencies for SUSE
+0b6a4c8 rbd: clone operation should default to image format 2
+6a80e2d qa/workunits: remove 'mds setmap' from workunits
+980e017 MDSMonitor: check for duplicated fs creation *before* multiple-fs creation
+82419db osd: pg: drop get_nrep() method, which is never used by anyone
+ed02ce5 osd: fix misnamed macro OSD_SUPERBLOCK_POBJECT
+917e06b doc/dev: add section on interrupting a running suite
+22fe493 qa/workunits/rados/test.sh: test tmap_migrate
+9ea6569 osd: pg: skip over update_heartbeat_peers() on non-primary pg
+3ce61eb osd: pg: drop stray_purged field, which is never used.
+b20cd76 osd: make needs_backfill() fast
+cc0c5e5 osd: make new state "activating" and "peered" visible for pg-relevant cmds
+33f4822 osd: fix pool-dump type mismatch
+a835b0e osd: make os_flags an option
+4734ff9 osd: pg: drop assert_locked() method
+0755915 object: generate file_object string in a safer way
+014fe9b osd: avoid implicit return type cast
+0e1cc01 os/bluestore: only bluestore_sync_transaction = false & bluestore_sync_submit_transaction = false, it submit transaction.
+b45a7b7 os/bluestore: make fm alloca/release w/ other kv ops in the same transaction
+22bcac9 os/bluestore: fix deadlock for bluestore_sync_transaction = true.
+1785f91 test/objectstore: add test cache "offset=length=0".
+8e41220 test: fixup and improvements for rbd-mirror test
+01db964 doc: fix typo
+0613b4f rgw: metadata notifications go to all zones
+0fd7c32 rgw: fetch remote obj uses high def clock for if-[un]modified-since
+f5f5252 rgw: timespan fix
+99ee598 time: For tests, subtract in the right order
+1d4c607 rgw: adapt to narrow stat2() and mtime2()
+416234b rgw: high resolution time
+0695698 utime: add conversion methods to/from real_time
+f3bc365 common/ceph_time: add real_clock::is_zero()
+a60f38d test: remove broken negative test cases
+24e50a1 rbd-mirror: integrate new bootstrap state machine
+e1fa689 rbd-mirror: simple image bootstrap state machine
+3b1db9b rbd-mirror: helper state machine for opening local image
+d61293d rbd-mirror: helper state machine for closing librbd images
+71dc051 test/cli/crushtool: default tunables are now firefly
+f945170 test/cli/osdmaptool: default tunables are now firefly
+7b1f1e8 ceph-detect-init: add test for squeeze
+aef7f9e qa/workunits/rbd: do not use object map during read flag testing
+7a33ab7 librados: cancel aio notification linger op upon completion
+ce9e8f5 test: cmake: Fix make check compilation error
+5b1dc2c rbd-mirroring: test: Added mirror image enable/disable to RBD CLI syntax tests
+bcddb56 cmake: avoid false-positive LDAP header detect
+4aff4ea cls_rbd: protect against excessively large object maps
+c048d2b rbd: rbd-mirroring: Added mirroing info to image info command in RBD CLI
+a3a90bd rbd: rbd-mirroring: Support image mirroring state retrieval in librbd
+66c9b01 rbd: rbd-mirroring: Added mirror image enable/disable commands to RBD CLI
+ec15120 rbd: rbd-mirroring: Support mirroring image disable in librbd
+601867e rbd: rbd-mirroring: Support mirroring image enable in librbd
+f3a78e0 store_test: improve synthetic coverage of the ec stash case
+4b44720 store_test: improve synthetic test coverage of long object names
+8b64432 TestRados: make half the objects have long names
+850ce11 LFNIndex::lfn_translate: consider alt attr as well
+aec5560 LFNIndex::created: fix return value with failure injection
+0fb67c7 store_test: add reproducer for #14766
+7792def ceph_test_rados_api_tmap_migrate: fix warning
+3a928f8 ceph_test_rados_api_list: fix warning
+39ae70b unittest_osdmap: default crush tunables now firefly
+9ed77c8 log: do not pass negative fd to fchown
+44ec595 rgw: don't return EEXIST on put_bucket_instance_info()
+740b950 librbd: handle unregistering the image watcher when disconnected
+80f3bc7 os/filestore/FileStore: only offset=len=0 mean read all data of object.
+b812831 mon/PGMonitor: make pg refresh debug output more informative
+d64c167 mon/PGMap: drop unused nocreating flag for stat_pg_{add,sub}
+f41cb16 osd: drop create events based on same_primary_since, not interval
+4ed894d osd: drop unused primary arg to handle_pg_peering_evt
+439bdbe osd: use handle_pg_peering_evt for pg creations
+26d4f2e mon/PGMonitor: reliably mark PGs state
+cc7e232 osd/OSDMap: fix typo in summarize_mapping_stats
+aec9cd2 SubProcess: Avoid buffer corruption when calling err()
+28982ca mds: change the 'fs remove_data_pool' to 'fs rm_data_pool'
+0dbcb41 osd: min_write_recency_for_promote & min_read_recency_for_promote are only used in cache pool
+e0983cd osd: fix typo
+e68d610 osd: skip over last queue_transaction() if the transaction is empty
+b4157fa doc: add doc for osd_crush_initial_weight
+40f7e6e msg: async: trim already sent for outcoming_bl more efficiently
+6c7dd80 rgw: increase sync lock lease period
+89bf43c rgw: data sync shard controller re-read sync status
+5f5adfe rgw: fix metadata sync backoff
+7c62ddf ceph-detect-init: return None at seeing unknown debian distro
+52ccf75 Revert "rgw ldap"
+e2bbd17 test: verify proper update of object map during rbd-mirror image sync
+0ef801f rbd-mirror: update object map while performing image sync
+9465d3b rbd-mirror: temporarily disable support for cloned images
+18bfef9 test: unit test cases for rbd mirror image sync
+cacb48b rbd-mirror: image sync state machine
+4411212 test: unit tests for rbd::mirror::image_sync::ImageCopyRequest
+e530fbf rbd-mirror: state machine to iterate and copy all image objects
+c7f5f9d librbd: track maximum object count during mirror sync
+cee931f test: test cases for rbd-mirror image sync point state machines
+4718112 rbd-mirror: new image sync point create/prune state machines
+acd40ab librbd: added equality operator to MirrorPeer journal types
+1c8b621 librbd: async version of snap create and snap remove
+14a264d librbd: prefix local maintenance ops methods
+f67bcc0 librbd: maintenance ops now send asynchronous requests
+a4b9243 librbd: track starting point snapshot for mirror sync point
+1d4d4c8 test: move get_mock_io_ctx helper method to common location
+502069a test: unit test cases for rbd::mirror::image_sync::SnapshotCopyRequest
+9a943db rbd-mirror: sync snapshots between remote-local images during bootstrap
+ffa8cc3 librbd: track local to peer snapshot id mapping within journal
+dd4f6a9 test: unit test cases for rbd::mirror::image_sync::ObjectCopyRequest
+67e1a62 test: updated mock expectation for librados remove op
+2b52bfa test: added missing forward declarations for librbd mocks
+7ed0ced rbd_mirror: deep-copy of object and its associated snapshots
+efb2ff5 librbd: helper method for wrappign rados safe callbacks
+a439920 librbd: updated API for calc_snap_set_diff
+69b5ce1 librados: calc_snap_set_diff now provides last known object size
+4c159d3 librados_test_stub: support for truncating/removing with old snap contexts
+f99ed9f rgw: clean up related to idempotent bucket attr modification.
+f0abefd rgw: ONLY little refactoring of helper code for attrs management.
+22a9b51 rgw: add support for metadata upload during PUT on Swift container.
+52e129e rgw: ONLY move helper code for custom attrs management.
+40e92c0 test: disable test_rgw_ldap
+e93778c rgw/Makefile.am: add a missing .h file
+46a3479 rgw_ldap:  merge cleanups
+de8367b rgw: require openldap library client headers
+a0a8dcc rgw: free components on shutdown
+bdcff15 mds: fix FSMap upgrade on mixed mon versions
+38fd3f1 rgw: LDAP pass-through authentication
+e52f7b4 mds: fix FSMap upgrade with daemons in the map
+1ea1735 osd: fix wrong counter for batch objects removal during remove_dir()
+12d151f osd: initialize last_recalibrate field at construction
+996be8e qa/workunits/rbd: use POSIX function definition
+d9af48a ReplicatedPG: be more careful about calling publish_stats_to_osd() correctly
+8616763 rgw: disable swift versioning by default
+06c7716 rgw: improve naming of Swift versioned object's copies.
+da9120a rgw: dump X-Versions-Location HTTP header of Swift API.
+54ea09c rgw: copy swift versioned object to destination if overwritten
+2ae6d54 rgw: swift object versioning data structure changes
+a230a38 debian: make infernalis -> jewel upgrade work
+ba4badf FileStore: fix initialization order for m_disable_wbthrottle
+81b9928 ceph-detect-init: return systemd on Debian Jessie
+4c97aac Revert "test/time: no need to abs(uint64_t) for comparing"
+2b07695 unittest_compression_zlib: do not assume buffer will be null terminated
+2cc736c FSMap: actually include the legacy MDSMap in Filesystems when upgrading
+a83989d FSMap: decode old MDSMaps properly
+9e83f5b mon: make the minimum crush tunables configurable
+88f1380 rados: add ceph:: namespace to bufferlist type
+565d1c7 crush: report minimum_required_version when dumping tunables
+78dc1b3 rgw_ldap:  merge cleanups
+1d18a63 rgw: silence compilation warnings
+a0c816b rgw: cleanup of debug messages
+1b897a9 os/bluestore/KernelDevice: fix signed/unsigned warning
+d963eb7 os/ObjectStore: drop collection attr deprecated warnings
+f9dbf54 osd/PGLog: fix warning
+4bd31fa ghobject_t: use # instead of ! as a separator
+5acb265 v10.0.5
 10ca7f3 debian/changelog: Remove stray 'v' in version
-ea45099 (tag: v10.0.4) v10.0.4
+48d929c msg: async: improve _send_keepalive_or_ack() a little
+cbc7cdb msg: async: fix connection perf counter description
+55a6697 os/filestore: add filestore_punch_hole = false option
+400975b os/filestore: fix punch hole usage in _zero
+bd2285f osd: use correct shard for temp scrub object
+19e6b64 os/bluestore: ref ovec for CLONE, CLONERANGE
+35f6c5c os/bluestore: fix OP_TRY_RENAME
+f2f0e7d os/bluestore: fix _rename
+fcb0786 ceph_test_objectstore: rename assumes target does not exist
+6dcc499 os/memstore: assert src and dst collection match on rename
+e8b94ae os/filestore: make read replace (not append) to result bl
+33b7058 ceph_test_objectstore: add a few checks to the rename test
+a2ecb1a os/bluestore/BlueStore: do not cow_rmw_tail at or past eof
+3dcadb4 os/bluestore: print debug on ENOTEMPTY
+b71f9f1 os/bluestore: make _do_omap_clear debug line pretty
+eee3d70 include/buffer: make is_partial work on empty ptr
+6a60c12 osd/ScrubStore: do not use temp collection
+166a7a9 osd: simplify split vs backfill behavior
+3295253 test: add rbd-mirror test script
+866a704 test: rbd_mirror_image_replay improve commit position parsing
+b0e1eb5 test: ImageReplayer on_stop/on_start error tests
+b61692b rbd-mirror: ImageReplayer async start/stop
+39b27ef librbd: protect against duplicate journal events
+a795d34 librbd: protect against journal replay shutdown race condition
+aa6a8d3 librbd: replaying a journal op post-refresh requires locking
+fdeb125 test: periodic failure in TestJournalReplay.SnapRename
+ccc5e71 config-key: introduce command of 'config-key rm'
+9537762 osd: introduce command of 'osd tier rm-overlay'
+e2b297a osd: introduce command of 'osd tier rm'
+4fa3f80 osd: introduce a command of 'osd pool rm'
+19c61b1 mon: introduce a comamnd of 'mon rm'
+397dae8 mds: introduce command of 'mds rm_data_pool'
+b0b1dfb mon: Introduce command of 'auth rm'
+439991a osd/ScrubStore: remove unused function
+223191f common/config_opts.h: add osd_crush_initial_weight
+99ec183 mds: fix stray purging in 'stripe_count > 1' case
+2408f8d rgw: store system object meta in cache when creating it
+4d59b1d rgw:bucket link now set the bucket.instance acl
+b988f79 rgw_admin: policy dump --xml backward compatibility
+6393565 osd: make promote_probability_millis atomic_t
+acb4a27 remove ceph_real_time_t typedef and overrides using it
+fd4d8ce include/encoding: do not try to be clever with list encoding
+6524f8b osd/PG: only set split child last_backfill if within PG range
+3a8b0e3 rgw: remove unused header file
+dd24f51 rgw: support json format output for rados-admin policy command
+a1333f5 rgw: support json format for admin policy API
+c85573a rgw: also dump realm in radosgw-admin sync status command
+d8f4d9e FileStore: Added O_DSYNC write scheme
+d0f8713 test/pybind/test_ceph_argparse: fix reweight-by-utilization tests
+797f1d4 man/8/ceph.rst: remove invalid option for reweight-by-*
+d9ac047 log: do not repeat errors to stderr
+d1627f5 xio: remove duplicate assignment of peer addr
+9cf46b8 test: correct journal test failure caused by two merged commits
+8affb39 xio: remove unused variable
+e68e37f rgw: require openldap library client headers
+9b36285 mds: set FSMap encoding version to 6
+eb88101 mds: make FSMap.get_filesystem return const
+3c2f28a test: update argparse test for rmfailed
+226639d client: update for multi-filesystems
+0ed5eb7 tools/cephfs: update for FSMap
+4e9b953 mon: update for multiple filesystems
+7a461a4 common/obj_bencher.cc: bump the precision of bandwidth field
+ccbd266 messages: add MFSMap
+00022bf mds: add FSMap
+ce37bbf mds: introduce fs_cluster_id_t type
+5a32017 mds: handle get_mds_info as const
+22ff122 qa: update cephtool test for CephFS multi filesystems
+99c1750 doc: cephfs admin command list
+1cd71d3 messages: fix strings for MMonGetVersionReply
+c3a8a09 java: update libcephfs tests to learn pool name
+8ae92c1 java: add O_DIRECTORY to libcephfs interface
+7778d16 include/CompatSet: trivial const-ness fix
+9ff5cb1 vstart: don't set max_mds to use all daemons
+a30d9ca vstart: don't call "fs new" repeatedly
+93fdd95 mon: initialize last_* timestamps on new pgs to creation time
+23e72e4 librbd: make journal start_external_replay not block
+3fb5152 journal: provide method to check if journaler initialized
+e3d8d65 rgw: instruct civetweb to drop permissions
+422c749 rgw_main: break up frontend config parsing
+f50c332 global_init: add run_pre_init argument to function signature
+c218c53 global: record target user and group strings
+2294c73 Packaging: Removing conditional BuildRequires for btrfs-progs
+5fe3ff3 Modifications to rbd-openstack.rst
+9b79d05 mds: fix inode_t::compare()
+0d9fb7a test: reproducer for writeback CoW deadlock
+93be4c6 rgw_admin: minor output cleanups
+3d58c14 rgw: silence some noisy log messages
+453bc55 rgw_admin: report oldest data not synced
+eea64de rgw_admin: show more data sync info
+03f8e62 rgw_admin: show oldest metadata change not applied
+b15f1ec rgw_admin: a command to show sync status
+977bed0 man/8/ceph-disk: fix formatting issue
+ce33a41 osd: drop unused from arg from handle_pg_peering_evt
+e929b0b osd: only pass history to handle_pg_peering_evt
+363e431 doc: Add French mirror
+868b794 mirrors: Change contact e-mail address for se.ceph.com
+ca16037 pybind: flag an RBD Image as closed regardless of result code
+a8e82a3 librbd: permit watch flush to return error code
+bc62792 rgw: free components on shutdown
+bd6c64d qa/workunits/rados/test.sh: capture stderr too
+0ea13ca rgw: LDAP pass-through authentication
+661891a mon: remove range=100 from reweight-by-* commands
+8dcaacb man/8/ceph-disk: fix formatting issue
+cf0665e osd: pg: remove get_log_write_pos() method
+ed7906e test: update rbd integration cram tests for new default features
+2bb6ef9 rgw: ldap token glue
+87ca3ef rgw: add a pure c++, header-only base64 encode/decode
+2025d63 Add script to test connectivity and availability of Ceph mirrors
+0a7407b mirror: Add examle rsync daemon configuration
+63be401 doc: Updated docs with additional mirror information
+39954da os/bluestore/BlueStore: Allow _dump_onode dynamic accept log level.
+5a5969e os/bluestore/BlueStore: For overwrite a extent, allocate new extent rather than WAL.
+b413a8f cls_rgw: use sized uint64_t for encoded time_t
+f42b86b test/librgw_file_*: use size_t* for rgw_read arg
+e515f14 client: pass proper old snap context to queue_cap_snap()
+bd611ab client: flush kernel pagecache before creating snapshot
+1ea8769 osd: remove up_thru_pending field, which is never used
+585ffed Mon: When create pool use the crush rule consider the pool size
+323c267 doc/dev: Continue writing Testing in the cloud chapter
+27f2d80 stop.sh: make more portable
+88c666d compat: don't call gcc explicitly
+2be4029 rbd: build rbd binary on all platforms
+aa33837 common: build with blkdev on all platforms
+6ce4744 compat: fix build on non-linux
+a572226 common: include malloc.h only on linux
+48a1ba5 rocksdb: more portable make invocation
+1ae5600 freebsd: use sysctl instead of nproc
+18e33f2 buffer: add symmetry operator==() and operator!=()
+9e34417 ceph_test_libcephfs: shutdown without closing file/dir
+8fc1b1b client: close opened dirs when umounting
+f4b210e rgw: remove unused vector
+79e2f18 client: fix root inode number for fuse
+d7e4221 rgw: handle error when fetching data log changes
+aab9166 xxHash: add .gitignore for build artifacts
+517a9d6 .gitmodules: use github.com/ceph/xxHash clone
+bdcc840 qa/workunits/rest/test.py: add confirmation to 'mds setmap'
+433afce mon: initialize last_* timestamps on new pgs to creation time
+b705a71 librbd: refresh image if required before replaying journal ops
+1a800f6 rgw: rework completion notifier and manager lifecycle
+9106e8a rgw: reorder RGWRados::finalize()
+ea29b71 rgw: don't equeue async cr rados operations if going down
+5914ae9 rgw: abort early in realm reload if already reloading
+03d60e3 rgw: silence some debug messasges
+5ecacfe rgw: stop async_rados thread first
+1c99dc2 doc/release-notes: v10.0.4
+7139a23 osd: handle boot racing with NOUP set + clear
+7eba5ba osd: inline advance_map()
+4ded44a journal: possible race condition during fetch playback
+3982895 test: fix errors introduced by rebase to master
+b37f135 journal: clean up playback notification handling
+b710374 tests: updated test cases for librbd journal tag allocation
+21d9595 journal: properly handle tag transition
+3325b87 journal: additional debug messages surrounding commit updates
+8444da8 librbd: improved debugging for journal client / tag processing
+16d5e69 librbd: allocate new journal tag when acquiring exclusive lock
+cbcfedf librbd: add tag handling to journal state machine
+a4dd788 journal: helper method to retrieve in-memory client data
+708c72c rbd-mirror: local pool id no longer stored in client registration
+dbcbaa6 librbd: update journal client and tag data structures
+9892fd7 librbd: allocate new uuid when enabling mirroring
+174359b cls_rbd: support for uuid to represent a mirrored pool
+92628f5 common/strtol.cc: fix the coverity warnings
+7fd230f rbd-mirror: integrate single thread pool for all processing
+3496e77 librbd: own the lifecycle of the journaler's threads
+f983b80 journal: use provided work queue and timer
+a00eae0 journal: pass metadata instead of finisher to FutureImpl
+5cd4ce5 selinux: Allow to manage locks
+519b03f selinux: allow dac_override capability
+052075e librbd: skip truncate request if object does not exist
+d8cdb5f scripts: ceph-release-note rewrite PR title case
+bf61156 release-notes: draft v10.0.4 release notes
+0cdb3af crush: remove straw_calc_version check from has_*_tunables()
+fa7beb0 mon: warn on straw_calc_version=0
+e48c708 doc/rados/operations/crush: rewrite crush tunables section
+000344e crush: make default tunables 'firefly'
+2f3a9c6 rgw: don't clobber first_chunk on retry
+754d210 packaging: Moving Cython into distro specific area
+019d9e1 packaging: Adding redhat-rpm-config
+7d48d21 packaging: Adding btrfs build require
+60b71ec stop: Add missing stop_rgw variable
+4a5875a doc/dev: start Testing in the cloud chapter
+f7eb860 rbd-mirror: avoid recursive lock in timer
+303e2c9 rbd-mirror: properly update replayers
+803eb51 rbd-mirror: spawn replayer thread
+ed035a3 rbd-mirror: don't log error on empty pool
+098be66 rbd-mirror: improve logging
+75b2f43 ceph.in: Minor python3 specific changes
+a565d33 test/bufferlist: Avoid false-positive tests
+37afe5c doc/dev: various refinements
+2da9449 mds: set ScrubHeader for dirfrag when doing non-recursive scrub
+aa1477f mds: improve debug message for CInode::validate_disk_state
+a656f94 mds: improve debug message for CDir::check_rstat()
+1c52d44 mds: remove unused 'Context *' parameter from MDCache::repair_foo_stats()
+7f83e3d mds: report dirfrag stats error found by scrub
+d98c516 mds: use MDSInternalContextBase instead of Context in scrub stack code
+82bd471 mds: queue non-recursive scrub to top of scrub stack
+c8609d1 Continuation: delete self after calling _done()
+f874999 mds: improve passed_validation check.
+700e513 mds: fix typo
+72b9339 mds: and 'force' options to scrub_path asok command
+f2d01c1 mds: remove obsoleted FIXME from scrubstack code
+84ed3cd mds: make scrubstack queue CInode instead of CDentry
+f13fb47 mds: don't ignore scrubbing non-regular non-directory inodes
+2a67152 mds: and 'recursive/repair' options to scrub_path asok command
+6cda4de mds: remove old scrub_dentry code
+a51fd65 mds: use scrubstack code to scrub single dentry
+db12397 mds: handle non-recursive scrubbing
+dad48ec mds: store ScrubHeader refernce in CInode's scrub_info_t
+f2de29e mds: scrub fragstat.mtime and rstat.rctime
+e3fdaae mds: set bad dirfrag's version to 1
+a2def5e mds: don't getxattr and setxattr at the same time
+1cc9d52 mds: check all items even when CInode::validate_disk_state() finds errors
+e900ea4 mds: repair fragstat/rstat errors in inode
+7760fc2 mds: repair fragstat/rstat errors in dirfrag
+5a9944d mds: properly free CInode::ValidationContinuation
+94bc0fb mds: don't crash when scrub finds bad fragstat/rstat
+a9ca637 mds: check both frag_stat and nest_stat when validating inode
+f29091b mds: check dirfrag rstat when dirfrag is fetched
+0ea991e mds: skip scrubbing dentries not modified since last scrub
+5810eb0 tools/rados: reduce rados put memory usage by op_size
+11222c5 cmake: Remove duplicate find_package libcurl line.
+d6a48d9 cls_hello: Fix grammatical error in description comment
+5b57065 doc/dev: integrate testing into the narrative
+c823018 msg: remove duplicated code - local_delivery will now call 'enqueue'
+e904670 Event: fix clock skew problem
+a0572bc doc: detailed description of bugfixing workflow
+602c61b rgw: fix usage log aggregation
+cf8c30a init-ceph.in: allow case-insensitive true in `osd crush update on start'
+59d098c rgw: avoid showing payer when payer == owner
+c007493 rgw: add virtual error bucket per user in usage logs
+44600cb objclass: add cls_cxx_stat2()
+8cfdaa6 test: add a test for stat2(), mtime2()
+e2fcfdf librados: add mtime2() that uses timespec and ceph::real_time
+d0c57ae debian/changelog: Remove stray 'v' in version
+9e47cef ceph_daemon.py: Resolved ImportError to work with python3
+9a6771a rgw: fix for RGWCoroutinesManager::run() return value
+5434db9 rgw: use current period for InitSyncStatus
+762c075 rgw: meta log rest handlers avoid get_log()
+faa60bc rgw: pull first log period from master if not found locally
+1353fe5 rgw: implement find_oldest_log_period for RGWMetadataManager
+1b4d1e3 rgw: period history behaves with no current_period
+8044dcb rgw: initialize async_rados before meta_mgr
+f8804b3 rgw: make RGWMetadataLog::get_shard_oid public and const
+b8a4a9d rgw: add RGWStatObjCR for async raw_obj_stat
+dbb9340 rgw: only write meta sync shard markers if can_adjust_marker
+873cf39 rgw: make RGWMetaSyncCR wakeups thread-safe
+da5f3e7 rgw-admin: add read_current_period_id() helper function
+f25adc2 rgw: ONLY const-correctness and formatting improvements in TempURL.
+a1ea718 rgw: TempURL in radosgw behaves now like its Swift's counterpart.
+5694397 rgw: use TempURL when requested regardless of auth token presence.
+154d865 rgw: don't use req_state::bucket_name in TempURL of Swift API.
+c6f48ff rgw: use Swift account name in TempURL.
+a99f582 rgw: improve support for Swift's URL schema with account name inside.
+4ad230a librados: new stat2() that returns ceph::real_time
+0f7730c debian/changelog: Remove stray 'v' in version
+e386562 librados: add stat2() calls that return high resultion mtime
+01c0a5f etc/sysconfig/ceph: set 128MB tcmalloc cache size
+c8ec17a doc: add ceph-detect-init(8) source to dist tarball
+0e536f5 mailmap: Edward Yang affiliation
+8b0b4ef mailmap: You Ji affiliation
+46310e3 mailmap: Javen Wu affiliation
+1ee635a mailmap: Zack Cerza affiliation
+d47cbcc mailmap: Marcus Watts affiliation
+50a05b1 mailmap: Mike Shuey affiliation
+013db9c mailmap: Luis Periquito affiliation
+fc1578a mailmap: Avner BenHanoch affiliation
+7883d7c mailmap: Abhishek Varshney affiliation
+510ae02 mailmap: Dongsheng Yang affiliation
+7ef9c90 mailmap: Willem Jan Withagen affiliation
+337ea90 mailmap: Yankun Li affiliation
+c988ab2 mailmap: Subramanyam Varanasi affiliation
+91bc114 mailmap: Rémi Buisson affiliation
+35c372b mailmap: Mehdi Abaakouk affiliation
+06a88b0 mailmap: Kefu Chai name normalization
+d5844d2 mailmap: Jason Dillaman name normalization
+178d5b2 mailmap: Aaron Bassett affiliation
+5a1b15d debian: package librgw_file* tests
+11b1cdc debian: tighten sub-package version dependencies
+2f7d1c9 submodules: revert an accidental change
+8c1f7eb rgw: RGWZoneParams::create should not handle -EEXIST error
+e51ac3e ceph-disk: protect destroy with the activate lock
+003dc15 ceph-disk: map after luks formatting
+94c5df4 tests: verify ceph-disk lockbox activation scenarii
+0b4ab0d ceph-disk: improve trigger verbosity
+ed56cef tests: make ceph-disk workunit resilient to non ascii
+48c21ce ceph-disk: implement deactivate --once
+869eb3a tests: verify ceph-disk activate-lockbox
+b36859c ceph-disk: protect list with activate lock
+4d42a56 ceph-disk: implement list for lockbox
+d355a38 doc: update ceph-disk to refer to ceph-disk --help
+67ef329 ceph-disk: add a description for each subcommand
+1ec58fc ceph-disk: implement lockbox key management
+bd4bd5c ceph-disk: simplify trigger
+67f9e8d ceph-disk: re-using an OSD partition bugous test
+15db7fe ceph-disk: make dmcrypt_unmap idempotent
+977bf03 ceph-disk: destroy does not unmap block/journal
+0186062 ceph-disk: display the function name with the log messages
+4727d42 rgw: avoid showing payer when payer == owner
+b7d022f rgw: indexless buckets
+f1ac0de rgw: configurable index type
+905b1d9 rgw: don't override error when initializing zonegroup
+0b48c86 rgw: adjust error code when bucket does not exist in copy operation
+18a75f1 test: use StrEq for C-style string matching
+d0e3da2 common/buffer: correct list_iterator::operator!= behavior
+0357d87 test: librbd template specializations leaking between translation units
+1335871 buffer: increment history alloc as well in raw_combined
+651f05b mon: make max_osds an optional arg
+8a9429d mon: make reweight max_change default configurable
+47b650c mon/OSDMonitor: fix indentation
+28b33a5 qa/workunits/cephtool/test.sh: test reweight-by-x commands
+1de7e47 osd/MonCommand: add/fix up 'osd [test-]reweight-by-{pg,utilization}'
+5b757ef mon: add 'osd utilization' command
+ea9abe5 osd/OSDMap: add summarize_mapping_stats
+a70eaab mon: make reweight-by-* max_change an argument
+38cb31a mds: add "ceph tell mds damage rm"
+434ba9a tools: create mdsdir frag in cephfs-data-scan init
+507a78b mds: enable dirs to go complete with corrupt dentries
+04fd569 mds: add "damage ls" `tell` command.
+9a9bfda mds: fix handling failures opening root
+4773d13 mds: don't suicide() from MDLog I/O functions
+e065e3b mds: add health report for whether there is damage
+652191d mds: generate -EIO on damaged path traverse
+21f91fd mds/MDCache: no need to handle badfrag stray any more
+3f8a6c4 mds: call into DamageTable from CDir
+f816e34 mds: add MDS::damage_table
+309f20a mds: add DamageTable class
+65e5b85 common: add config mds_damage_table_max_entries
+ea45099 v10.0.4
+56cd390 mds: set ScrubHeader for dirfrag when doing non-recursive scrub
+9da1732 mds: improve debug message for CInode::validate_disk_state
+3609bd6 mds: improve debug message for CDir::check_rstat()
+abe4de3 mds: remove unused 'Context *' parameter from MDCache::repair_foo_stats()
+ac8dca8 mds: report dirfrag stats error found by scrub
+61b3549 mds: use MDSInternalContextBase instead of Context in scrub stack code
+6c59383 mds: queue non-recursive scrub to top of scrub stack
+d773755 Continuation: delete self after calling _done()
+2681bd1 mds: improve passed_validation check.
+d1fec4f mds: fix typo
+712a98d mds: and 'force' options to scrub_path asok command
+7288510 mds: remove obsoleted FIXME from scrubstack code
+78e80de mds: make scrubstack queue CInode instead of CDentry
+cc1f902 mds: don't ignore scrubbing non-regular non-directory inodes
+4000f01 mds: and 'recursive/repair' options to scrub_path asok command
+506b536 mds: remove old scrub_dentry code
+5327521 mds: use scrubstack code to scrub single dentry
+e3ef072 mds: handle non-recursive scrubbing
+5651a0d mds: store ScrubHeader refernce in CInode's scrub_info_t
+3f74958 mds: scrub fragstat.mtime and rstat.rctime
+c1f3ef0 mds: set bad dirfrag's version to 1
+950d411 mds: don't getxattr and setxattr at the same time
+1e9f2a2 mds: check all items even when CInode::validate_disk_state() finds errors
+db55452 mds: repair fragstat/rstat errors in inode
+1c7833a mds: repair fragstat/rstat errors in dirfrag
+cfe7296 mds: properly free CInode::ValidationContinuation
+45e942c mds: don't crash when scrub finds bad fragstat/rstat
+7fd1d69 mds: check both frag_stat and nest_stat when validating inode
+bb0b294 mds: check dirfrag rstat when dirfrag is fetched
+4c6842c mds: skip scrubbing dentries not modified since last scrub
+62731d0 ceph-detect-init: return correct value on recent SUSE distros
+50653cf global: complain about parse errors after we open the log
+6c4aafe config: more parse_errors into md_config_t
+658bba8 common/obj_bencher.cc: make verify error fatal
+58250f5 log: fix some whitespace
+23f459c log: use correct delete[]
+f792a3f PGMonitor: unconfuse object count skew message
+fcc459c os/bluestore/BlueStore: Don't leak trim overlay data before write.
+ed4295b Fix alignment in bluefs
+98b6d91 test/osd: Relax the timing intervals in osd-markdown.sh
+a7a65e7 cmake: add common/fs_types.cc to libcommon
+17d8ff4 mon: Monitor: get rid of weighted clock skew reports
+45e16d0 mon: Monitor: adaptative clock skew detection interval
+b0b4b6d os/bluestore/BlueStore: Fix bug when calc offset & end whether locate in the a extent.
+cd49615 common/obj_bencher.cc: use more readable constant instead of magic number
+9acb00e ceph.spec.in: do not install Ceph RA on systemd platforms
+acfc06d ceph.spec.in: use %{_prefix} for ocf instead of hardcoding /usr
+a2d58fc rgw: TempURL of Swift URL does support Content-Disposition override.
+c857fcf rgw: ONLY refactor dump_object_metadata() of rgw_rest_swift.cc.
+26f9d69 rgw: add support for overriding Content-Disposition in GET of Swift API.
+83e77cf Bluestore.h:Added 'override' to virtual functions
+d793c6a test/rgw: add multisite test for meta sync across periods
+d8cfef9 cmake: simplified heap_profiler_objs dependencies
+3e41cfd client/Inode: fix has_dir_layout
+71c4e52 [MON] Fixed calculation of %USED. Now it is shows (space used by all replicas)/(raw space available on OSDs). Before it was (size of pool)/(raw space available on OSDs).
+c2f91a8 keyring permissions for mon daemon
+cdf4486 msg: async: fix result code
+eb5f00a msg: async: reset result code to errno for better tracing
+2242988 msg: async: fix wrong return code if out of memory
+effcd77 BlueStore.h:Remove unneeded includes
+61026c8 cmake: Turned LTTng OFF
+597aaba configure.ac: cython is used for more than librbd now
 13a5aac RPM: move scriptlets from ceph to ceph-base
+c6f317b AUTHORS: update email
+55eeee9 rgw: calculate payload hash in RGWPutObj_ObjStore only when necessary.
+da84cba os/kstore: Latency breakdown in each stage of transaction for Kstore
+677d290 librados: race condition on aio_notify completion handling
+3aa0cce osd: add mon_reweight_max_osds to limit reweight-by-* commands
+6f0a1fb osd: add mon_reweight_max_change option which limits reweight-by-*
+1a6ad50 test: add simple test for new reweight-by-* options
+ddf5c2b osd: add sure and no-increasing options to reweight-by-*
+72ff342 mds: deny access to file with pool_ns layout if feature is missing
+00a1394 mds: fix inodestat size calculation
+a524df2 mds: properly purge backtrace object
+8e728fc messages/MClientCaps: fix decoding
+1de6e94 mds/Server: fix whitespace
+e7ead6a mds/Locker: fix Session leak on access denial
+fafb142 fix init of new fields in MCLientCaps
+7f47cd7 mds/MDSMap: add file layout v2 incompat feature
+00850a6 mds: deny access to directories with pool_ns layouts if feature is missing
+9c7669b mon/MDSMonitor: prevent pool 0 from being used as a data pool
+a2d42d5 mds: don't break compatibility of MClientCaps/MClientReply
+efb4a83 fs_types: file_layout_t: convert pool -1 (undefined) to 0 in legacy encoding
+c31e94d qa/workunits/fs/misc/layout_vxattrs: test layout.pool_namespace
+e0ad651 client: expose layout.pool_namespace vxattr
+386d7c6 mds: allow adjustment of layout.pool_namespace vxattr
+99f1f64 struct ceph_file_layout -> file_layout_t
+2752eee mds: make inode_t, old_inode_t featureful
+e750f48 messages/MClientCaps: avoid fixed struct for encoding
+ff606bf mds: encode inode reply information directly
+0b1f7f5 messages/MClientReply: stop using ceph_mds_reply_inode struct to unpack
+7dcf39f mds: pass features to various CInode encoders and helpers
+826e8d0 mds/MDSMap: cache up_features; fix logic
+162ca5b libradosstriper: move default stripe parameters inline
+7b961ff include/encoding: featureful encoder for list of shared_ptrs
+bdae5bf include/compact_map: featureful encoders, too
+4cf4f8d ceph-dencoder: TYPE_FEATUREFUL_NOCOPY
+358cce1 mds: pass features to LogEvents, EMetaBlob
+e08dd70 mds,mon: include features in beacon messages, MDSMap
+4ad8f72 mds/MDSMap: add features to MDSMap's mds_info_t
+9822081 add fs_types.h, with file_layout_t
+0cd1b94 declare Formatter for everyone
+58a00e0 qa/workunits/fs/misc/layout_vxattr.sh: detect data pool name
+86b7a83 os/bluestore: for _clone, first check source-object whether has extents.
+b0f692d os/bluestore: print Enode::hash w/ hex format.
+7c4f37d os/bluestore: make _clone work when object has overlay data.
+533b617 rgw: send proper ETag value during GET on DLO/SLO through S3 API.
 b87f4ef packaging: lsb_release build and runtime dependency
-4de86bf (origin/wip-move-requires) RPM: drop duplicate /var/lib/ceph/* directories
+aa2b891 buffer: use alignof for raw_combined allocation arithmetic
+ef80690 buffer: clean up raw_combined construction
+b6ed4d3 buffer: size append_buffer so that it fits into page-multiple allocations
+f2c0d5c rbd-replay: s/CEPH_BUFFER_APPEND_SIZE/CEPH_PAGE_SIZE/
+ce3e5a3 buffer: alloc right-sized buffer from read_fd
+73dcd26 buffer: use raw_combined for certain allocations
+6be3b99 buffer: align unspecified allocations to a word
+724a493 buffer: combine data and buffer::raw into single allocation
+04482ae buffer: add front(), back(), get_num_buffers() methods
+69bcbe1 unittest_bufferlist: benchmark some allocations
+08c0d98 unittest_bufferlist: fix append_bench
+7723d29 unittest_bufferlist: fix ptr move test
+0a03b79 osd: set conservative (low) promotion throttling values
+0750769 osd: set per-interval cap on promotions
+46641a9 osd: probabilistic promotion throttling
+a764282 osd/ReplicatedPG: fix promote obc setup when recency > 1
+34dd39c librbd: use aio watch/unwatch during open/close state machines
+eac7e7a librados_test_stub: added aio_watch/aio_unwatch/aio_watch_flush
+feb2fc0 test: adjust rbd test case guards to handle new defaults
+0b2847e test: use default RBD features in test cases
+ed83975 librbd: permit deep-flatten to be dynamically disabled
+d24883e rbd: update default image features
+6eff39a qa/workunits/cephtool/test.sh: wait longer in ceph_watch_start()
+42d81bf common/obj_bencher.cc: faster object name generation
+e4f73b3 librbd: apply orphaned maintenance ops after journal replay
+c438730 librbd: only cancel replay of journal op events upon error
+9c99637 librbd: delay commit of op start event
+b0dc047 journal: permit fire-and-forget aio commit position flush
+ed9de5f librbd: support replay of maintenance ops
+ea9cb4f doc: rgw explain keystone's verify ssl switch
+e564111 doc: add notes about upgrading cephfs
+8ffc4e8 msg: async: start over after failing to bind a port in specified range
+acc6405 test/cli-integration/rbd: disable progress output
+2039873 test/TestPGLog: fix the FTBFS
+0bd82d3 [rgw] RGWLib::env is not used so remove it
+6cd5e20 fixed a bug for write bench with rados
+cf812ea rgw: aggregate usage by payer
+ff8305a rgw: fix permission check for request payer
+554b643 test_filejournal: reserve throttle as needed
+2856cf5 osd: replicatedpg: remove redundant semicolon
+201e174 osd: replicatedpg: break out if we encounter error during do_pg_op()
+30f548e config_opts: make filestore_queue_max_(ops|bytes) U64
+622748a rbd: deprecate image format 1
+ece5b9e Add new mirrors to overview file
+49c76d6 Updated mirroring script to mirror Ceph
+0c0e8a0 AsyncConnection: log cleanup, remove redundant state display
+324145b Event: complete all pending events
+4de86bf RPM: drop duplicate /var/lib/ceph/* directories
 275b5f2 RPM: drop duplicate udev rules from ceph-base
 5083980 packaging: rados-classes libraries in ceph-base
+bd592c0 AsyncConnection: dispatch write handler when accept done
+bcff5be osd: fix typo
+90d4aff osd: fix overload of '==' operator for pg_stat_t
+bcc2866 doc: fix typo, indention etc.
+0952f35 tools/cephfs: add tmap_upgrade
+f22a097 Bugfix: set thread name will fail, when running as differnt user.
+6fb1ceb rgw: do not enforce Content-Length in response for DELETE on Swift's SLO.
+d428296 rgw: return proper etag in response for PUT on Swift's SLO.
+dcd6c4a rgw: ONLY code refactoring in RGWGetObj::handle_slo_manifest.
+44b87bd rgw: calculate etag for SLOs of Swift API.
+c27d279 rgw: culculate etag for DLOs of Swift API.
+4b172fd pybind: update ceph_volume_client for cython
+7f03c0e pybind: fix error handling on getxattr
+10f125f pybind: move cephfs to Cython
+70f32f9 rgw: adjust the request_uri to support absoluteURI of http request
+1ab5fcd doc: mon-config Add information about pg_prime
+2784c65 mon: Enable pg_prime by Default
+8aa159b doc: osd-config Add Configuration Options for op queue.
+b4f1935 Python-argparse is a virtual package which stretch wants you to pick a real package to satisfy the dependency.
 cba211d packaging: pkg_resources.py runtime dependency
 45ede09 ceph.spec.in: move ceph-disk runtime dependency to ceph-osd
 8b04c2b ceph.spec.in: drop support for ancient SUSE versions
 1a0bb0f packaging: move python-flask runtime dependency to ceph-mon, radosgw
 608dd28 RPM: align runtime dependencies with Debian packaging
+083a006 osd: update sprintf() to snprintf()
+8101df0 osd: fix typo
+0d4be18 osd: improve get_net_marked_out() a little bit
+73784f0 osd: fix wrong return type of find_osd_on_ip()
+9453967 test: add tests to (un)register and update journal client
+3e18f56 Revert "AsyncConnection: Close connection when unregistered connection met WAIT"
+a4527c3 journal: async methods to (un)register and update client
+378f4c7 cls::journal: async client_unregister
+8671859 cmake fix: build civetweb with the right include path.
+ea2e24f rgw: fixes and adjustments following rebase
+23785d3 rgw: remove usage from signed resources
+155f079 rgw: change naming of utility functions in rgw_keystone.cc.
+aaa0f6f Use fixed version of civetweb to avoid warning.
+f3925ec Fix ssl link error.
+b451cbb Use ld.so to link in ssl crypto (cmake changes).
+ec186f4 rgw: fix wrong handling of limit=0 during listing of Swift account.
+3254e49 test: remove doubled unwatch API call
+82f547f librados: aio watch/unwatch/notify now uses completion objver
 d4dd0f4 debian: remove ceph-dbg package and any traces of it
+837dcc5 XIO: Changes to fix incorrect ip being assigned in case of multiple RDMA ports.remove rdma local and return error instead to avoid issues with using rdma_local incase of multiple ports.
 3fc7fdb debian: remove ceph-base's dependency on -mon and -osd
+41e5422 tests: update rbd-mirror tests for updated commit handling
+107e114 journal: fix delimiter in ObjectSetPosition formater
+7906737 journal: update JournalTrimmer to support new commit tracking
+df25867 journal: active and minimum set should always grow
+91ea6da journal: update JournalPlayer to support new commit tracking
+5697387 journal: update JournalMetadata to support new commit handling
+44d25fd journal: track commit position for each object splay offset
+92f2409 journal: differentiate corruption vs missing entry errors
+80f34dc rgw: try to parse Keystone token in order appropriate to configuration.
+5d41735 rgw: add insecure option to the http client
+dff62e4 rgw: use pimpl pattern for RGWPeriodHistory
+39671f1 doc: final v9.2.1 release notes
+2a80042 rbd/run_cli_tests.sh: Reflect test failures
+ca50f42 doc: batch small fixes, including typo, syntax etc.
+dc7e027 doc: fix typo
+0cee333 mds: remove stray dentry from delayed eval list after calling eval_stray()
+b33984b os/bluestore/NVMEDevice: remove unused variables ref
+8abffb9 os/bluestore/NVMEDevice: fix error handling for try_get()
+e2bbce7 os/bluestore/NVMEDevice: fix error handling for open()
+2cf7c4a configure.ac: boost_iostreams is required, not optional
+c9a40ad msg/async: don't calculate msg header crc when not needed
+8ce9630 S3 rest api extend for usage show
+c05300b log: segv in a portable way
+753221e cmake: add ErasureCode.cc to jerasure plugins
+aa92f9d rgw: link against system openssl (instead of dlopen at runtime)
+e7edf20 osd/: Use MOSDPGUpdateLogMissing to implement mark_unfound_lost_delete safely
+88ee4e7 osd/,messages/: add MOSDPGUpdateLogMissing[Reply]
+b8e5843 os/: add try_rename
+9f4cba3 Throttle: add BackoffThrottle unit tests
+c9861a0 doc/.../throttles*: update the docs to reflect the throttle changes
+f54e563 Journal: replace the journal throttle with fullness backoff throttle
+83baa1f FileJournal: use queue size explicitely in aio backoff
+a00bed3 FileStore: use BackoffThrottle for the op queue
+b0a8b1c throttle: add a BackoffThrottle implementation
+83b4aab cmake: installing _tp libraries into lib
+430027f PGLog: factor out claim_log_entries_update_missing
+7eadf88 PGLog::merge_log: update missing, after removing divergent
+50e4e2c PG,PGLog: convert to DoutPrefixProviders
+b33dd14 dout.h: add a DoutPrefixProvider and macro to allow passing of prefixes
+d3eac8f ECBackend: use CEPH_MSG_PRIO_HIGH for write replies
+b1151c4 ECBackend: send subop writes and reads at normal priority
+257225d ReplicatedPG: remove OpContext from Repop
+43f3d82 ReplicatedPG: s/release_op_ctx_locks/release_object_locks, don't use opcontext
+e68b550 ReplicatedPG: refactor OpContext to use ObcLockManager
+82896f2 ReplicatedPG::close_op_ctx: the err argument is unused
+7ae52fc osd_types: add ObcLockManager
+0a5b4c1 src/osd: use unique_ptr for backend trasaction, move into submit_transaction
+612fd33 ReplicatedPG::RepGather: remove on_finish, no more users
+1ef04dd ReplicatedPG: use register_on_finish rather than on_finish for flush/evict
+8e82dea ReplicatedPG::scrub: use register_on_commit rather than on_finish
+90a5359 ReplicatedPG: move do_osd_op_effects out of eval_repop
+e4c5356 ReplicatedPG: break out complete_disconnect_watches helper
+cc1b2c6 ReplicatedPG: move client reply handling out of eval_repop
+5110214 osd/: replace simple_repop_.* with simple_opc_.*
+6db7fe7 introduce CEPH_FEATURE_SERVER_JEWEL feature bit
+2e4ad9e cmake: Removed _tp libraries from linking
 dc54a85 debian: fix logrotate conf handling
 9a66bf0 debian: put libexec files in /usr/lib
+18da92f rgw: add support for caching of Keystone admin token.
+c2e6102 test/ceph_objectstore_tool: Deleting btrfs subvolumes before exiting
+9ae8926 ceph-helpers: Delete remaining subvolumes on destroy_osd()
+9dbac6c os/kstore: fix a race condition in _txc_finish()
+e23fdcb rgw: reset return code in when iterating over the bucket the objects
+a704270 cls_rbd: fix the test for ceph-dencoder
+cd0389d ceph-helpers.sh: Deleting forgoten btrfs subvolumes
+ba70bdb config: increase default async op threads
+557c3bf osd: always cleanup the scrub results
+b0b4021 pybind: fix the FTBFS introduced by d0af316
+a7f3a65 mds: avoid creating unnecessary snap dentry/inode
+798ad64 mds: set multiversion inode's first
+f7fb2cb mds: fix open snap parents tracking
+ac7d11a librados: add missing tracpoint for scrub APIs
+c1e1c8d tests: test_pidfile.sh lingering processes
+e2374c4 rados: add "list-inconsistent-snapset" cmd
+8018eab rados: add "list-inconsistent-obj" cmd
+c9b593d librados: add get_inconsistent_snapsets() API
+dfc2f48 librados: add get_inconsistent_objects() API
+3dea4f1 osd: add CEPH_OSD_OP_SCRUBLS pg op
+2009ed2 osd: persist inconsistent snapsets using omap
+c828c39 librados: add `inconsistent_snapset_t` type
+8ed6277 osd/: clear scrub store safetly
+fb956b7 osd: persist inconsistent objs using omap
+f236b7d osd: more constness to spg_t
+b43d480 librados: add `inconsistent_obj_t` types
+4c32706 rados: add "list-inconsistent-pg" command
+d0af316 pybind: add Rados.get_inconsistent_pgs method
+cb4efbd librados: add get_inconsistent_pgs() to librados
+50bbf7f tools/rados: support more --format options
+0c27417 librbd: Truncate of non-existent object results in object map flagged as exists Fixes: #14789
 0cbe3de debian/rpm: split mon/osd/mds server packages
+28e2d1b cls_rbd: add methods for keeping track of mirrored images
+da9b36a librbd: rename rbd_pool_settings object to rbd_mirroring
+2104df8 test/objectstore: add test for GetNumBytes
+6e901ba pybind/rados: track completions before calling aio functions
+3c767ab pybind/rados: Fix error handling and leaks in aio
+5360d86 librbd: init asok_hook on open so name is always known
+80656b1 librbd: get image name on open if it is opened by id
+325963b os/ObjectStore: implement more efficient get_encoded_bytes()
+af12582 xio: remove redundant magic methods
+3cfb83d librados: remove unused local variables
+8caa2e4 librados: do not clear handle for aio_watch()
+48af4be tests/ceph-disk: Let teardown clearing data
+57f31e9 tests/ceph-disk: Using dummy device mappers
+ba05b7e tests/ceph-disk: Creating missing working dir
+7bd95b5 os/filestore: FALLOC_FL_PUNCH_HOLE must be used with FALLOC_FL_KEEP_SIZE
+f59c872 test: enable test for bug #2339 which has been resolved.
+7109de7 RadosClient: call watch_flush before finisher stop
+3a6d627 test/common/test_weighted_priority_queue Fix the unit tests since the changes to WeightedPriorityQueue there is no strict round robin dequeueing of classes. Removed that test from the unittest.
+f03de8e common/WeightedPriorityQueue Rewrote the queue to use intrusive contianers. Microbenchmarks show 60-70% of execution time compared to before.
+e688a44 cls_rbd: async version of dir_get_name
+d48536c common: Do not use non-portable constants in mutex_debug
+cc99072 cmake: fix paths & make object libs of various EC files
+442be02 osd: Replace snprintf with faster implementation in eversion_t::get_key_name
+dafe0d9 doc: fix 0.94.4 and 0.94.5 ordering
+e67099d librbd: deterministically unblock writes on snap set
+514519a librbd: avoid close race-condition within ImageState
+f3fc6b1 rgw: fcgi should include acconfig
+c7c1d28 doc/release-notes: v0.94.6 final notes
+c5a6b6a msg/async: cut the middle-man
+4a61793 ceph-disk: fix prepare --help
+ac241ab ceph-disk: deactivate / destroy PATH arg are optional
 dff71a5 mon/MDSMonitor.cc: properly note beacon when health metrics changes
+103eee4 test: image_replay: use flush to speedup commit position update
+9572d27 rbd-mirror: add asok commands to get image replyer status and flush
+1a6dfa4 rbd-mirror: store sync snapshot name in registered client
+79dcef2 librbd: add field to MirrorPeerClientMeta to store snap name
+e92b452 rbd-mirror: ImageReplayer: pass registered client ID as external param
+9be35bc BlueStore: add sanity check for type during mount
+dc9aba1 BlueStore: fix type mismatch for openat syscall
+204a96c BlueStore: add sanity check for attr removal
+468b64a BlueStore: remove unused local variables
+1e53e5b BlueStore: remove redundant continue
+a843569 BlueStore: fix typo
+f99bf34 BlueStore: fix obsolete comment
+bc320eb BlueStore: remove unused member fs
+0f8bf7d BlueStore: add result check for _do_remove
+98b2d83 BlueStore: add result check logic for _do_truncate
+a906019 BlueStore: set existence for new onode in a proper way during write
+73d86b3 BlueStore: simplify cow allocation for head and tail a little
+d01a39e BlueStore: optimize head check logic
+26db058 BlueStore: simplify put logic a little
+4b673ee KStore: fix return type of _txc_add_transaction
+73f35f1 BlueStore: fix return type of _txc_add_transaction
+00d40e2 BlueStore: avoid create the dest onode in advance
+5e55c13 BlueStore: remove unused member dirty of onode
+46da33b OSD: update heartbeat peers if unable to statfs
+144fa29 os/filestore: fast abort when basedir no more exists
 30bddc4 Makefile: workaround an automake bug for "make check"
+ef6aafa ceph-disk: s/dmcrpyt/dmcrypt/
+a7a5cf2 rgw: return proper error codes in S3/Keystone auth.
+19843ce rgw: enable users of RGWHTTPClient to get HTTP status code.
+7186d1c rgw: improve debugs around S3/Keystone auth mechanism.
+edf8152 rgw: ONLY move PKI-related things from rgw_swift to rgw_keystone.
+0914246 OSD: fix race condition for heartbeat_need_update
+804c615 osd/ReplicatedPG: remove unused bufferlist
+83da093 test: create pools for rbd tests with different prefix
+4d26000 OSD: put a guard for updating heartbeat peers
+67b2744 OSD: fix typo
+7987e54 qa/workunits/fs/misc: Add workunit for file lock deadlock detection
+ad44b5e test_rados_watch_notify: add async_watch_flush tests
+e17a0c0 OSD: shutdown OSDService in a more graceful way
+a1f20db ceph_detect_init/__init__.py: remove shebang
+d20936f Revert "NVMEDevice: add default constructor for Task and clean up"
+8513e00 NVMEDevice: use wakeup instead of direct call
+b09b80e NVMEDevice: accept spdk structure name changes
+8d27e99 test: more debug for TestWatchNotify
+4c0f6a3 NVMEDevice: accept spdk api name changes
+4602f1b spdk: update spdk submodule to accept new interface changes
+feaa457 NVMEDevice: add default constructor for Task and clean up
+7ef2f4a NVMEDevice: only activate zero command when backend supported
+b5cdc33 BlockDevice: detect symbol file basename
+d208668 BlueStore: fix spdk link file create failed
+84a36a0 NVMEDevice: fix atomic and lock changes
+4f868ee NVMEDevice: use nvme_probe to simply init
+61ef7d4 spdk: update spdk submodule
+5259270 NVMEDevice: use nvme zero command instead of writing zero
+398e331 NVMEDevice: cleanup task iterator process
+809189b vstart.sh: avoid race condition starting rgw via vstart.sh
+cf8483f test/radosgw-admin: update the expected usage outputs
 b2ae384 RPM: refrain from packaging EC testing plugins
 1b6faf6 Refrain from versioning EC testing plugins
+cc4b73b test: rbd-mirror: add tool to test ImageReplayer
+f829186 test: rbd-mirror: add ImageReplayer tests
+b3990a1 rbd-mirror: implement ImageReplayer
+9644df6 os/filestore: fix result code if sanity check failed during copy_range
+da0f660 test/time: no need to abs(uint64_t) for comparing
+afdc3cc librados: add async_watch_flush api
+b651dd7 RadosClient: add async watch_flush version
+f5d8da6 Objecter: make linger_callback_flush accept context instead of blocking
+f977f0a librados: add C api impl and tracing codes
+f04c96c librados: remove unused variables
+2be574a test: add aio_unwatch unittest
+28ac263 librados: support aio_unwatch api
+569b121 librados: add unittest for rados aio watch
+87e715c librados: add async watch api
+886e28a journal: wrappers to get journal metadata
+0aaaf36 librbd: allow to use journal replay externally
+9e1cf70 cls::journal: don't print client data
+c68d00c test/bufferlist:Add test case for  bufferlist::is_provided_buffer.
+9867804 Striper: Add function 'assemble_result(CephContext *cct, char *buffer, size_t len)' in StripedReadResult.
+a879301 Striper: Add total_intended_len in StripedReadResult
+f250f4e osdc/objectCacher: Remove the unsed field.
+ed54420 bufferlist: Add new func is_provided_buffer(const char *dst)
+52c04b8 common/TrackedOp: avoid implicitly cast for return value
+b2bfd6c common/TrackedOp: fix inaccurate counting for total slow requests
+700c3dc librbd: update mirror peer data structure
+0ec038a librbd: support image and pool-level mirroring modes
+55cbc60 rgw: Keystone token parsing doesn't need to know API version.
+abbd912 rgw: S3 always must use token format of Keystone v2.
+2f190fd rgw: Keystone token parsing should fail on misformed JSONs.
+90e1f39 rgw: improve debugs in RGWPostHTTPData.
+bc6d7c3 rgw: ONLY formatting improvements for Keystone-related code.
+92764d4 rgw: handle Keystone API version with dedicated enum.
+8e90686 rgw: fix wrong format of admin token request in Keystone v3.
+a622e3f rgw: rework serialization in token retrieval for Keystone's admin.
+84bcb50 rgw: fix Keystone v2 regression in role's JSON parsing
+d3299b0 rgw: accommodate Keystone v3 in S3-related auth mechanisms.
+c5b114b rgw: accommodate Keystone v3 in RGWSwift class.
+38ee661 rgw: basic data structures for Keystone v3.
+46a4881 rgw: unify RGWValidateKeystoneToken with RGWPostHTTPData.
+a868e59 rgw: make RGWPostHTTPData able to extract X-Subject-Token.
 3c5bc07 Makefile: workaround an automake bug for "make check"
+694f92f PendingReleaseNotes: document the dropped buffer symbols
+6c645780 buffer: hide iterator_impl symbols
+7249a5c librbd: read ops require journal replay
+b61f467 cmake: add missing librbd image_watcher sources
 9d25202 Makefile: workaround an automake bug for "make check"
 c7eba2a src/yasm-wrapper: ignore parameters starting with ggc-min
+882066d doc: standardize @param (not @parma, @parmam, @params)
+4213b86 msg/xio/XioConnection.h: init some member variables in ctor
+a55f8c2 librbd/operation/RebuildObjectMapRequest.cc: init m_snap_list_ret in ctor
+c645bd9 librbd/DiffIterate.cc: reduce scope of variable
+1f0c1b1 librbd/ImageCtx.cc: reduce scope of variable
+e6d3a0f msg/async/EventKqueue.cc: reduce scope of variable
+e5c9694 msg/async/Event.cc: reduce scope of variable
+a37ae6a log/Graylog.h: make ctor explicit
+60b61b4 librbd/AioImageRequest.cc: reduce scope of var
+c51ada3 ErasureCodeJerasure.h: init packetsize member var in ctor
+00af2a2 compressor/zlib/CompressionPluginZlib.cc: use explicit for ctor
+6169854 compressor/zlib/CompressionZlib.cc: reduce scope of variable
+91a8b1b journal/JournalMetadata.cc: compare size of lhs instead of rhs to rhs
+d71df26 test_Replay.cc: prefer ++operator for non-primitive iterators
+11bfc6d common/PluginRegistry.h: init Plugin::library in ctor
+b906041 common/Graylog.h: make constructor explicit
+44e028f HTMLFormatter: reuse m_header_done from parent class
+fc44347 cls/rbd/cls_rbd.cc: reuse existing variable with same name
+8793921 mds/Server.cc: replace inefficient string::find() w/ compare()
+729117f client/SyntheticClient.cc: reduce scope of some variables
+cfd0765 client/SyntheticClient.cc: remove unused code
+2b60306 client/Client.cc: init owner_uid and owner_gid vars in ctor
+d407faa rgw/rgw_rados.cc: remove unused variable locator
+822eecf rgw/rgw_op.cc: remove unused variables
+a5d78c2 rgw/rgw_admin.cc: remove unused variables
+aef72ab mds/mdstypes.h: init fnode_t::damage_flags in ctor
+c08435c client/Client.cc: reduce scope of some variables
+56dd09f mds: Add posix file lock deadlock detection
+877eae8 os/filestore: fix result code overwritten for clone
+a917ccf mon: cleanup set-quota error msg
+9695a0b rgw: avoid empty object names
+3d39154 .gitignore: include recently added rgw programs
+3f525f4 rgw: fix s3 list bucket (affects format=json)
+0a988f9 pybind: replace __del__ with __dealloc__ for rbd
+7be19c2 os/filestore: fix wrong scope of result code for error cases during mount
+1e47268 rgw: only validate bucket name if not empty
+804e6c8 rgw: resurrect lost code
+f98b485 pybind: remove next() on iterator
+024caa7 mon/pgmonitor: use appropriate forced conversions in get_rule_avail
+36af480 common: default cluster name to config file prefix
+68f300d os/filestore: fix wrong scope of result code for error cases during mkfs
+8243d18 Event: replace fileevent array to vector
+d5463d7 Event: delete leak event callback
+72b0333 test/Makefile-client.am: adjustment following merge
+eee7d9e librbd: helper method for flushing journal commit positions
+999a319 journal: added interface to flush pending commit position updates
+1cfd965 librbd: differentiate journal replay flush vs shut down
+ac168e3 rgw: add drain_all() before exiting a cr
+d95fcfa rgw: silence compilation #warnings
+996e6e9 rgw: more error reporting
+ac726c6 rgw: data sync error handling (for sync init)
+d2d0f84 rgw: a bit better hashing
+4f15332 librbd: don't hold owner lock while refreshing image synchronously
+4ecdf06 librbd: need owner write lock when disabling exclusive lock
+922072a librbd: correct memory leaks discovered via valgrind
+7e09cb1 librbd: notifications should be flushed between exclusive lock states
+eebe61a rgw: RGWMetaSyncCR loops through period history
+6b6625e rgw: get period history cursor when starting sync
+12cae9e rgw: remove RGWMetadataManager::store_md_log_entries
+be5c263 rgw: rados coroutines take bucket by const ref
+f10a6d4 rgw: add first log period to mdlog info response
+9881330 rgw: factor get_log_shard_id() out of RGWMetadataLog
+adab1e1 rgw: add period id to rgw_rest_log operations
+02edcdd rgw-admin: update callers of get_log
+34ea6bc rgw: add map of period_id -> RGWMetadataLog
+5b12ec0 rgw: add period id to metadata log oids
+699809e rgw: RGWRemoteMetaLog passes period id with requests to master
+25771ef rgw: move sync_status into RGWRemoteMetaLog
+3c990d2 rgw: include period id in rgw_meta_sync_info
+ea9f0fc rgw: use std::move for strings in RGWFetchAllMetaCR
+fe68150 cmake: remove duplicate rgw source files
+1ebb55b rgw: remove RemoteMetaLog::fetch() and admin command
+be06128 rgw: remove unused RGWRemoteMetaLog::list_shards
+c13e7ee rgw: remove unused class RGWReadMDLogShardInfo
+10cdb88 rgw: remove unused clone_shards() in metadata sync
+1999c57 rgw: remove unneeded RGWRados arg for RGWMetadataLog
+3cb199a rgw: we need to clear the id in create_default in case of a race
+10cda14 rgw-admin: command to list sync error logs
+2885014 rgw: set quota when converting regionmap
+3d8d9da librbd: update image name upon rename operations
+ad78558 librbd: missing owner lock on snap rollback cache invalidation
+e01b406 librbd: journal replay should execute ops in clean context
+bc2ae0e librbd: use AIO notifications to prevent blocking ops
+9d0b5b9 librbd: cleanup header update notifications
+2c65617 Revert "librbd: lock notifications should be executed outside librados thread"
+dd5c9e5 librbd: support for AIO notifications
+12a55d6 rstats: enable by default on client; move test workunit to its own dir
+284075c Fix unicode encoding for non-ASCII characters in title and author names
+cded77d release-notes: draft v9.2.1 release notes
 69291f8 packaging: move ceph_common.sh and ceph-osd-prestart.sh to /usr/lib/ceph
+f0dcd32 [ceph-fuse] Fh ref might leak at umounting
+0fb387f pybind: rados cleanup
+b3f8dd8 scripts: ceph-release-notes fixes --strict
+b7524c0 release-notes: draft v0.94.6 release notes
+7ee9968 ceph-disk: make some arguments as required if necessary
+06806f7 [ceph-fuse] Fh ref might leak at umounting
+ee07770 [cephfs] fix free fds being exhausted eventually because freed fds are never put back
+331e90f Use make_shared while creating shared_ptr
+c8b9a79 pybind: use correct subdir for rados install-exec rule
+aa87bec rgw: remove unnecessary overloads in RGWHTTPArgs.
+cb928f5 mds: don't crash because of bad ms-type in ceph.conf (or missing enablement for experimental ms-type)
+b9a4ad8 mon: don't crash because of bad ms-type in ceph.conf (or missing enablement for experimental ms-type)
+027edc3 osd: don't crash because of bad ms-type in ceph.conf (or missing enablement for experimental ms-type)
+c58fc20 os/kstore: default Onode::true to false
+180a12a os/kstore: fix onode_t attr leak in _setattrs()
+27b991a sstring.hh: return type from str_len(...) need not be const
+eeaf8b8 os/kstore: remove unused OnodeMap::remove
+206c3e8 os/kstore: use std::mutex et al
+ebfc6bf rgw: move signal.h dependency from rgw_front.h
+58fe65f os/kstore: add transaction dump msg in _txc_add_transaction
+bce0bc0 os/kstore: wr lock collection in _txc_add_transaction
+67f95c8 Update the documentation
+c4162b5 librbdpy: Use new rados lib
+7216b06 ceph.in: Use new python rados module
+82869f0 Fix rpm/deb packaging
+3c40524 Remove old rados pybinding
+9997b32 Cython Rados module
+4c8f320 OSD: fix fusestore hanging during stop/quit
+c03ab96 os/kstore: use std::atomic
+d457ff0 os/kstore: load OnodeRef in _txc_add_transaction
+a2c90b5 Revert "librbd: use task finisher per CephContext"
+52b7f1d rgw: support system requests over Swift API.
+cd357b6 rgw: enable access to system arguments of RGWHTTPArgs.
+4b9413f os/kstore: drop unused TransContext mutex and cond
+926eb77 os/kstore: fix valgrind warning on fsid read
+1c0406a pybind: Ensure correct python flags are passed
+d3ac713 Move pybind rbd module into it own directory
+1badcdd os/bluestore: change bluestore_backend to bluestore_kvbackend.
+7b57f29 os/bluestore: If bluestore_bluefs == false, only rocksdb_separate_wal_dir == true, it create db.wal direcotry
+dbfee62 os/bluestore: Only enable bluestore_bluefs, symlink or create db or db.wal.
+e6f3968 msg: add thread safety for "random" Messenger + fix wrong usage of random functions
+1b6ec18 rgw: cleanup
+3c28f19 rgw: don't try to parse some forwarded requests
+842140b rgw: adjust data sync async notification locking
 fe14a26 ceph.spec.in: declare /usr/share/ceph properly
+edefcaf vstart.sh: clarify usage on single osd/mds/mon.
+912fe8e vstart.sh: silence a msg where btrfs is not found.
 a6cc8ea rpm: drop systemd_libexec_dir template variable
 5c09a3e rpm: drop user_rgw and group_rgw template variables
-efc8134 (tag: v10.0.3) v10.0.3
+84e9f3f librados_test_stub: watch_flush should block until notifies complete
+d898995 librbd: lock notifications should be executed outside librados thread
+7ae774b librbd: potential race on image close
+f5dfebc librbd: potential deadlock during AIO image re-open
+8756e80 librados_test_stub: ensure AIO callback is also flushed
+a418182 tests: librbd: commit position updated after journal replay
+ba2e6ce common/bit_vector: use hard-coded value for block size
+37a3728 Make variable count usefull
+a1e6dcd osd: rewrite digest only when the digest exists on auth obj
+d476ff6 ceph-disk: flake8 fixes
+678e2bb rgw: cleanups to comments and messages
+ce42172 rgw: catch up aws4 with the new features
+e9917a6 rgw: fix host field in canonical headers under qs
+cc8f31b rgw: fix bug encoding percentage char in X-Amz-Credential
+16646c3 rgw: add aws4 auth grace period
+84bd2af rgw: add x-amz-expires support
+8a4f8e8 rgw: escape aws4 query string
+b052b0d rgw: implement missing handlers for aws4 signatures
+f851cbc rgw: implement RGWOp_Metadata_Put::get_type()
+e183009 rgw: raise error on not implemented AWS4 completions
+8e1048d rgw: add AWS4 completion support for RGW_OP_PUT_ACLS
+e28072e rgw: add AWS4 completion support for RGW_OP_PUT_OBJ
+5547754 rgw: return -EINVAL on unknow authorization
+e533917 rgw: verify X-Amz-Date
+f7f2198 rgw: do not encode key/val when computing canonical qs
+537e549 Revert "rgw: avoid re-encoding already encoded query strings in AWS4 auth"
+52e601b rgw: multiple fixes and adjustments following aws4 code review
+4da8539 rgw: achieve same error behaviour in S3 and RGW when processing signedheaders
+2de292a rgw: validate x-amz-sha256
+79b6b4f rgw: check if x-amz-date has a value
+c32e5ea rgw: verify Content-MD5 is a valid base64 value
+b7772ca rgw: initialize aws4_auth_complete
+3210cd8 rgw: AWS4 auth support for positive content-length
+466cb81 rgw: UNSIGNED-PAYLOAD support in AWS4 auth
+483ad81 rgw: avoid re-encoding already encoded query strings in AWS4 auth
+49856eb rgw: AWS4 auth support when using request params
+a15abe4 rgw: add proper AWSv4 and AWSv2 auth detection
+cbfc4af rgw: handle AWS4 auth case when query string exists
+9a0de48 rgw: AWS4 authentication minimal support
+1ce0c77 client: removed unused Mutex from MetaRequest
+892c144 Objecter: detect laggy ops with objecter_timeout, not osd_timeout
+a7d4e42 rgw: Drop unused usage_exit from rgw_admin.cc
+00d396e rgw: don't use s->bucket for metadata api path entry
+865c76c rgw: add drain_all() after collect() in sync crs
+447c806 rgw: adjust interfaces following rebase
+9abb8e6 rgw: more error handling
+0a0d437 rgw: fail when trying to commit period if no master zone configured
+7bbbec0 rgw: add error_logger to sync env
+2d52ab3 rgw: data sync env cleanup
+caa73ba os/filestore/FileJournal: simplify alignment asserts
+613457f osd: consider high/low mode when putting agent to sleep
+c8048ce os/filestore/FileJournal: set block size via config option
+cb9cfb7 librgw: fix rpm packaging
+85e4feb librgw: fix new Debian control entries
+e18c689 librgw: remove junk files
+5f0fcdb librgw: don't compare a string_ref with "" (use empty())
+244ad79 librgw: fix boost::basic_string_ref template instantiation
+de0f866 librgw: add debian and rpm packaging
+2f706ef librgw: consolidate S3 bucket name validation
+cfb8c81 librgw: fix copyright in src/include/rados/rgw_file.h
+195185d librgw: initialize RGWLib pointer members
+a293c52 librgw: remove slo, dlo, and supplied-md5 logic in RGWWriteRequest
+3d7fa4f librgw: remove RGWLibRequest "magic" numbers added for debugging
+303f542 librgw: comment rgw_nfs config_ops.h tunables
+48c0f5b cohort_lru: remove #if 0 section
+165079d {rgw,common}/Makefile.am: add a few more missing .h files
+acadd09 common: add xxhash.h to Makefile.am
+47a5c0c rgw: fix null dereference
+1f6799d librgw/rgw: fix librgw.la linkage
+c38e3cb librgw/rgw: reorganize autotools linkage
+269d90a librgw: call obj_rec::sync() on dirs1_b
+77a4039 librgw_file_nfsns: create readf_out_name, if needed
+fa9cd66 librgw: remove deprecated/unused librgw personality
+4b42c57 librgw: properly detect RGWRados init failure
+aa96958 librgw: remove deprecated librgw methods
+e43eb4d librgw: temporary fix RGWWrite
+8aa4378 librgw: cleanup rgw_write
+6b9b3d8 librgw: add new rgw_write unit test
+0eda995 librgw: fix RGWReadRequest send_response_data
+06aff87 librgw: add cross-bucket rgw_rename test
+b35de47 librgw: fix intra-bucket rename
+ca6e93b librgw: add support for rgw_rename tests
+2e109ec librgw: fix rgw_unlink and delete atomicity
+ad3a22d librgw: implement object rename
+2a860f4 librgw: fix timestamp on create (another case)
+e68600b librgw: cleanup, move 3 prints to log channel
+7ef6485 librgw: add missing RGWFileHandle::stat in rgw_mkdir
+35445cf librgw: fix leading-slash special case, again
+4f8e765 librgw: disable name-cache lookups w/CREATE
+b57f51b librgw: fix a prefix bug and bucket timestamp bug
+998ed65 librgw: ignore "/" as a common_prefix
+441bff7 librgw: rgw_getattr refactor, RGWLibFS::stat_leaf (object)
+ce62d80 librgw: fix rgw_read, add unit test
+1b797a7 librgw: add rgw_getattr tests
+117208c librgw: re-implement rgw_create
+ec924b6 librgw: update rgw_* api calls so that all take a flags arg
+4f2dd46 librgw: normalize obj_rec::sync calls, fix signedness of refcnt asserts
+a50416b librgw: partial getattrs/gc checks
+402a76f librgw: fix handle type in rgw_mkdir, finish dirs1 create tests
+d18fe86 librgw: set directory ctime and mtime
+d817591 librgw: refactor nfsns dirs1 and fix a "bad unlink" case
+558c211 librgw: incremental bucket-object 2-level tests
+12fd3fa librgw: enforce S3 object name restrictions
+66b6b1f librgw: enforce S3 bucket name restrictions
+54149b0 librgw: FLAG_CREATE cleanup
+c1d1e15 librgw: nfsns dirs1 delete, make hier1 conditional
+41b2357 librgw: incr. fix various nfs ops (REBASEME)
+b008fe5 librgw: reorg SETUP_ENUMERATE test
+b7730c0 librgw: conditionally send '.' and '..' (rgw_readdir)
+5e75c18 librgw: stop abusing parents
+7cc6a6d librgw: likely correct marker handling
+446d92c librgw: is_truncated experiments
+bd07c2a librgw nfsns:  create/delete updates
+adfb96a librgw: don't early terminate readdirs (in progress)
+9a6944c librgw: remove unused st
+603f245 librgw: split nfsns bucket and object create blocks
+82aabab librgw_file_nfsns: bugfix MARKER1_SETUP
+e6b3be3 librgw: consolidate dup'd librgw, rgwlib
+103b9dd librgw: remove search_prefix()
+5b6af8a incremental marker
+80d5201 librgw: omit always-false depth test.
+bd4b984 librgw: rework full_object_name() and friends
+4158721 librgw: add continued readdir test
+1097ed4 marker
+a557c89 Fix copyright statements on new test driver files (Red Hat, Inc.)
+597f69d librgw: dir traversal state GC added
+b970fd0 librgw: restore readdir prints (move to dout)
+7acb20d librgw: move readdir operations into RGWFileHandle::readdir
+453219c librgw: implement small-directory name cache
+e8fc2b7 librgw: remote redundnat prints in RGWReaddirRequest
+49a034a librgw: don't increment offset at rcb (it is no longer a counter)
+bd06808 librgw: fill in dirent cache
+33856c1 librgw: implement framework for fs periodic work
+3237f0b librgw: add intrusive refcnt to RGWLibFS
+baffb14 librgw: header and namespace reorganization
+e448c4e librgw: use string_ref remove_prefix
+8db2c6a librgw: fix initialization of string_ref from temporary
+b19912c cohort_lru: use correct new/delete operator pair
+eaf1563 librgw: move ObjUnref trace print ahead of...unref
+1f2ec09 librgw: cleanup add_marker and handlers
+e6eee9f librgw: rename RGWGetObjRequest, RGWListBucketRequest
+ef6367f common: add (tweaked) sstring.h
+6147c3e librgw: fix RGWLibFS::stat_leaf ex-ref
+9cf6670 lirgw: call RGWLibFS::close in rgw_umount
+562ebcb librgw: implement LRU lifecycle for handles
+066c2e8 librgw: remove dead code (rgw_readdir)
+00571a5 librgw: use correct finish path for RGWWriteRequest (logging and stats)
+e4b0c2b librgw: update posix-style read path
+49a47d1 librgw: set iov->iov_len to nread (get)
+ea51474 librgw: sequential rgw_write works
+5d9e395 librgw: update mtime on write finish
+e08b8d6 librgw: -EISDIR
+0090da6 librgw: check variant type, fix reversed check for write trans
+3b795c1 librgw: finish write transactions in rgw_close path
+a8f8c1a librgw: block in RGWWriteRequest::exec_continue
+6e630d6 librgw: block in RGWWriteRequest::exec_start
+1c722bb librgw: wire up more of continuation
+80bac65 librgw: dont forget to call exec_start
+6b798de librgw: partial implementation of continued request framework
+e3be074 librgw_file_aw: re-enable write sequence
+a27a407 librgw: fix some incorrect uses of string temporary
+5fe0170 librgw: add initial atomic write unit test
+4e5aef6 librgw: don't allow open on directories (externally)
+eb99b44 librgw: restrict objects to single-open
+57938d8 librgw: fix last enumeration bug, move tracing to debug
+a420784 librgw: fix and unify full-name assembly and hashing
+46f82d7 librgw: incremental listing fixes
+b83ac0d librgw: incremental enumeration progress
+6dba692 librgw: remove unused string uri
+589af39 librgw: namespace bugfixes
+821c562 librgw_file_nfsns: stage namespace traversal (fails)
+27c9a36 librgw: initial librgw_file_nfsns.cc test
+ba82ff8 librgw: add missing include deps (rgw_file.h)
+54dcf30 librgw: fix parent chasing in make_fhk
+f9173e8 librgw: fix last-of marker detection
+4e9116a librgw: unify result cases in rgw_mkdir
+33539db librgw: RGWListBucketRequest and related bugfixes
+e53eb38 librgw: implement stat_bucket, call from rgw_lookup
+21bf277 librgw: annotate unlink's rgw_lookup
+b9f3065 librgw: add lookup step in rgw_unlink
+1d17dcd librgw: hide uri in RGWListBucketRequest, use full_objectname()
+06e2dad librgw: add marker processing to RGWListBucket(s)Request
+6e70b6d librgw: reimplement RGWLibFS::stat_leaf
+3ac44f9 librgw: variant handle subtype and marker cache
+fcd4320 librgw: create dir file handles w/correct type
+103eda1 librgw: implement RGWLibFS::stat_leaf
+5725721 librgw: incr rework stat
+3781027 librgw: fix uninitialized rgw_fh
+196ef76 cohort_lru: fix a maybe uninitialized warning (that seems invalid)
+4a23f4c librgw: create explicit directory leaf objects in rgw_mkdir
+b94b51f librgw: consolidate RGWLib RGWOps into RGWRequest
+42fc51a librgw: don't discard lookup result, fix signedness of min_size
+13bc25a librgw: make_fhk put base name, object_name in wrong order
+3e6e4ed librgw: add pseudo() accessor
+fc505f4 librgw: add pseudofs awareness to lookup_fh
+33ee6d2 librgw: make_fhk, compute object hashes path-wise
+6691da0 librgw: add depth and make_path to RGWFileHandle
+443e9c9 librgw: compress RGWFileHandle stat data
+cfc7a4f librgw: fix abuse of std::string& in RGWDeleteObjRequest
+80c8573 librgw: fix rgw_unlink
+fbfafb3 librgw: ok, make RGW vnodes cache Unix attrs
+5f4ef7e librgw: forge Unix attrs in rgw_create
+c480472 librgw: fix Unix file modes
+4fd6511 librgw: implement rgw_create + bugfixes
+6db1f9d librgw: fix size computation in RGWStatObjRequest
+bf6bee6 librgw: fix many rgw_file return codes
+66823a0 librgw: don't abuse fs_private
+857aa1e librgw: introduce RGW_LOOKUP_FLAG_CREATE
+7f482c0 librgw: add getattr unit tests, restructure
+3c94a95 librgw: handle a 3 cases in rgw_getattr
+885a603 librgw: handle rgw_lookup in the root (minimally)
+fd8f20e librgw: change validity check for rgw_lookup
+71590b8 librgw: add RGWStatObjRequest and use it
+0e5f5e2 librgw: add diagnostic dump_buckets() call.
+a5e6d55 librgw: fail RGWLibFS::authorize() on user-by-id lookup failure
+0175a3d librgw: implement rgw_vfsstat
+74e4c5a librgw: rgw_mkdir and rgw_create return addresses
+507ecab librgw: pass struct rgw_fh_hk by reference
+056c0cb librgw: always add struct before rgw_file_handle in rgw_file.h
+8417a78 librgw: bring back lookup_handle()
+455d9d5 librgw_file_gp: check test state before closing null fh handle
+9821d6f librgw: implement intrusive filehandle cache
+d6e171a librgw: add common/cohort_lru.h
+e1b4fc7 librgw_file: release file handles
+73b19a9 librgw_file_gp: don't leak a buffer::list
+ab377b1 librgw: checksum verify writev/readv read-after-write
+b9137e4 librgw: really make hexdump optional, set resid in readv unit test
+5e0b6e4 librgw: fix 2 dout problems
+5139c31 librgw: try-implement rgw_readv/rgw_writev
+540ce76 librgw: improve rgw_write and add WRITE_READ_VERIFY
+421f5ec librgw: remove junk prints
+50abb8c librgw: set RGWGetObj::get_data = true, for great justice
+290b06a librgw: rework library CephContext* and init
+72fb1ad librgw: dispatch RGWDeleteRequest in object branch in rgw_unlink().
+88c2d02 librgw: implement RGWGetObjRequest
+b652126 librgw: declare RGWDeleteObjRequest
+0ec522b librgw: declare RGWGetObjRequest
+21e6ff3 librgw: fix RGWPutObj s->content_length
+24da131 RGWPutObjRequest: fix get_data()
+b3150b0 rgw log: disambiguate 'Read AccessControlPolicy' (logs)
+c352d4b librgw: add --prelist to gp to prime cache
+7f981b1 librgw: fix rgw_open param names and invocation
+9429cb1 librgw: avoid illegal rele()
+ec89aaf librgw: don't create/delete in librgw_file.cc (unit test)
+adcba20 librgw: fs->root_fh is a pointer (and assign it)
+522c958 librgw: bucket names can be const
+e562357 librgw: reify root handles
+1e7539b librgw: incremental RGWPutObj work and almost-complete RGWFH refactor.
+a50bc13 xxHash: build internally
+1254f34 librgw: add ZPage/ZPageSet abstraction (gp unit tests)
+020aee9 xxHash: add as submodule
+fc0a895 librgw: rgw_file_handle refactor, plus get/put
+03b6615 librgw: add options for bucket name, multi create, delete
+abcec54 librgw: fix acl assignment in RGWCreateBucket_OS_Lib
+2994222 librgw: don't fake hostname (real hostname isn't used yet)
+cca325e librgw: don't allow running rgwfile tests as anon
+3fcdd94 librgw: partial delete/unlink support
+9fb454a librgw: return result code from execute_request
+c43384c librgw: fix uri, read_permissions virtual for create-bucket
+460794e librgw: block in create bucket, rgw_mkdir
+ceb2b0e librgw: re-derive rgw_os_lib family
+83bed47 librgw: s/rgw_rest_lib.{h,cc}/rgw_os_lib.{h,cc}
+cbcb641 lirgw: call RGWHanlder_Lib::init_from_header
+6dae209 librgw: cleanups, incremental ListBuckets fixes
+e295629 librgw: forward cmdline args to librgw_create
+55bb8d3 librgw: remove disabled RGWLib RGWREST::get_handler()
+ed7dc88 librgw: cleanups in process_request
+ec96809 librgw: pull RGWUserinfo user into RGWLibRequest
+7e21e23 librgw: cache RGWUserInfo in rgw_fs private handle
+6688bc1 librgw: split RGWUserInfo from struct req_state
+290e788 librgw: RGWFileHandle and RGWLibFS
+f938281 librgw: fixes for RGWListBucketRequest callback
+9c4de57 librgw: untested RGWLibListBucketsRequest and caller.
+80a56f2 librgw: fix 2 bugs in RGWListBuckets, remove scaffolding
+c44f19c librgw: process_request prologue fixups
+0b614a1 librgw: reprocess process_request
+143bd14 librgw: wire up RGWLibFrontend enqueue and exec operations
+84fd9aa librgw: remove RGWLibRequestEnv
+4867148 librgw: wire up request initializers
+259be80 librgw: re-derive RGWLibRequest
+d1d4535 librgw: rename RGWHandler_REST_Lib (sic), inherit from RGWHandler
+ac37941 librgw: remove dead code, add comments in RGWLib
+4af5aea librgw: refactor RGWHandler HTTP/REST methods into _REST
+bf10462 librgw: call rcb in RGWListBucketsRequest operator()
+748a6e5 librgw: add user_id to RGWListBucketsRequest
+adade47 librgw: header inclusion fix, actually call callbacks
+8508730 librgw: incremental
+987821c7 librgw: s/gen_request/enqueue_req/;
+9d6c78f librgw: replace RGWHandler::put_op() in RGWLib path
+ab2349c librgw: move authorize() and read_permissions()
+7e8ecc5 librgw: pre-assign req->op (as self), avoid dynamic_cast
+f4994c8 librgw: breakthrough cleanups (I think)
+f1720d8 librgw: incremental rgw_rest_lib internals
+35a5e50 librgw: include rgw_lib.h from rgw_rest.cc
+5cc096d librgw: tweaks to RGWREST::preprocess and fix a typo in RGWHandler_ObjStore_Lib defn.
+df8f392 refactor RGWClientIO
+79d3879 librgw: comments
+2903d75 librgw: widen rgw_mount, open-code list buckets
+a719a0b librgw: add LOOKUP_BUCKETS and LIST_OBJECTS
+f6a95fc librgw: add list bucket test
+5521c7a librgw: test rgw_(u)mount(...)
+84e2166 librgw: take keys in test
+9eeba4f librgw: fe::init must create RGWLibProcess
+d1bbfe9 librgw: introduce struct rgw_fs
+fae842d librgw: remove classes from extern, argv
+eb2ac51 librgw: fix type of rgw_readdir eof argument (C-11 bool)
+2035fcc librgw: revise rgw_* method signatures
+e7d0300 librgw: update rgw_rename signature
+8fb8f00 librgw: define an rgw_setattr
+763f434 librgw: make rgw_readdir take a bool* for eof
+5dd73b9 librgw: update rgw_readdir interface (stub impl)
+c4262b2 librgw: add hypothetical rgw_statfs call
+c81b85d librgw: stub implement rgw_getattr
+27e066d librgw: add a library version (1.0.0)
+c52a9fa librgw: rgw shared library
+ce5ba5d librgw: compile and implement more of rgw_file
+e769655 librgw: the external type of librgw_t must be void*
+f23cd03 librgw: install librgw.h
+3f60300 librgw: s/nfs_file_handle/rgw_file_handle/;
+9830941 rgw_file.h: preserve cosnt correctness
+2aa79de librgw: fix some return warnings (and cosmetic)
+08b89a5 rgw: introduce libradosgw
+76f1dca rgw: refactor rgw_main
+19391b7 Makefile: workaround an automake bug for "make check"
+153f719 msg/async: set MSG_MORE intelligently
+a07aea6 msg/async: delay bufferlist construction
+7dbce5b osd/ReplicatedPG: respect must_promote in WRITEBACK cache mode
+a0858a5 osd/ReplicatedPG: respect must_promote in READFORWARD and READPROXY
+bab48c2 ceph_test_rados_api_tier: verify class op forces promotion
+7d804cf osd/ReplicatedPG: fix whitespace
+cd87bd4 ceph-disk,ceph-detect-init: clean the build directory
+c1d8faa python: use pip instead of python setup.py
+f88c852 rgw: Fix subuser harder with tenants
+744f384 rgw: add a timelog add operation cr
+7a78b0e rgw: replace #warning with a comment
+5c2b519 rgw: fix do_curl_wait() if curl_multi_wait() not defined
+b2f7438 rgw: fix create_default to handle EEXIST
+79d6952 rgw: metadata and data sync share RGWAsyncRadosProcessor
+2360e16 rgw: fix RGWSystemMetaObj::init to handle perdefined name correctly
+4342bd6 rgw: add error messages to realm::create
+67fccab radosgw-admin: realm pull should not fail if the realm exists
+3348947 rgw: use exclusive flag for store_name in RGWSystemMetaObj::create
+fd46b2d rgw: hold reference to req_completion while calling aio_operate()
+22faa00 rgw: link_pending_requests() fixes
+ee9f206 rgw: more of dropping async ops reference
+0ce5bc5 rgw: fix a typo
+51eb2fa rgw: in create_default read zone_params in case we raced with another
+847ec96 radosgw-admin: add missing break in key rm command
+b243075 rgw: fix a few more leaks
+45c5327 rgw: safe disposal of async processors
+defb4d3 rgw: shorten name of RGWAsyncRadosProcessor thread pool
+8bcdb77 rgw: stop meta sync handler when going down
+efc2dfc rgw: more leak fixes
+47db646 rgw: minor cleanup
+5363017 rgw: reorder RGWRados shutdown
+9e2569e rgw: clear stack ops when unwinding last op
+46f1ee5 rgw: more leak fixes
+9ffa3e2 rgw: fix a few leaks
+d52bf63 rgw: forward meta changes to master
+813c021 rgw: update datalog also when unlinking object instance
+b0630d5 rocksdb: set to master
+71dd408 rgw: 'period push' handler uses RGWPeriodHistory
+f420bd2 rgw: add period history and puller to RGWRados
+d89d224 rgw: add RGWPeriodPuller for RGWPeriodHistory
+60c9798 rgw: add exclusive param to RGWPeriod::set_latest_epoch
+e53fbe3 rgw: split RGWPeriod::reflect out of set_latest_epoch
+470595b rgw: RGWPeriodHistory to track period history
+7469fc2 rgw: fix documentation of RGWRealmWatcher
+1ee26ed rgw: use realm epoch to choose most recent period to push
+b37739a rgw: add realm epoch to RGWRealm and RGWPeriod
+423719b rgw: RGWRealm::set_current_period takes RGWPeriod
+b72530b rgw: start pushing current period on startup
+426e3fc rgw: period commit updates sync status before writing the object
+2d90f85 rgw: 'realm pull' uses realm's current_period for do_period_pull
+e911e14 rgw: use refrence in read_clear_modified
+0ef1fae radosgw-admin: zonegroup set and zone set should set the realm id
+5e708a9 rgw: fix RGWZoneGroup ctor and check period update return code
+8821d06 rgw: init_zg_from_period() fixes
+69c1d9f rgw: data sync, handle delete marker removal
+c599087 rgw: some debug info
+5e93a68 rgw: guard versioned object removal from circular sync
+850dd42 rgw: handle delete marker when doing incremental data sync
+a104062 cls/rgw: log owner, display name when creating delete marker
+c78cb25 mrgw.sh: modify log file name
+d26ebb0 rgw: update datalog when creating delete marker
+18f6853 rgw: set_date_header should use header_name
+71797cd radosgw-admin: add mdlog and datalog status to help.t
+b9da8db rgw: fetch remote obj depends on zone id and pg ver
+b37503a rgw: keep source zone attr on head object
+de129aa rgw: create a short (32bit) zone id, keep it on the period map
+b50b3bb rgw: keep pg ver on obj state, and send it in HEAD request
+d2e41e8 rgw: store obj pg version in the object's head
+6052d4b test-rgw-call.sh: add missing file
+6476c4e rgw: data sync, update high marker when skipping duplicate sync entries
+0cc621c rgw/test_multi.py: add log level for saner output
+21e108b rgw/test_multi.py: meta checkpoint uses zones, not clusters
+f9b9407 rgw/test_multy.py: improve test_object_sync
+fb3dd94 rgw: clear 'null' object instance when fetching remote obj
+7a25c63 test_multi: buckets and objects comparison
+673abbe test_multi: test object sync
+a38a3ae rgw-admin: add datalog status command
+0e9f2e4 rgw: meta sync can remove entries
+61de036 rgw: clone mdlog updates marker in any case
+671f319 test_multi: add more bucket related tests
+a2583c5 rgw: meta sync, handle ENOENT, ECANCELED
+aa5de3b rgw: test_multi: start radosgw with debug logs, asok
+8b8f91a tests_multi.py: test bucket creation, fix meta checkpoint
+38cefb4 test_multi.py: can run through python nose
+7680706 test_multi.py: generate boto connection per zone
+aee4e85 test_multi.py: create a test user
+b170343 test_python.py: call radosgw-admin with cache disabled where applicable
+82b5f3a test_multi.py: move meta checkpoint inside, add configurables
+6f54407 test_multi.py: generate random key
+7fd1528 test_multi.py: wait for meta sync
+99da339 test_multi.py: finer control for bringing up system
+44d0d3f test/rgw: more test work
+22129ec radosgw-admin: fix help.t
+69a395f rgw: remove error message from read_default
+afc900b radosgw-admin: zone list should print default zone
+2ec85ef rgw: default zone per realm
+1827781 rgw: default zonegroup per realm
+845bf22 rgw: create_default cannot set as default
+e206c02 rgw: cleanup remove realm unused master_zonegroup and zonegroups
+b419321 radosgw-admin: use realm current period master_zonegroup as remote for period pull
+8d4fbc0 test/rgw: wait for metadata sync
+1105cff rgw-admin: add mdlog status command
+673b28c test/rgw: basic meta sync status test util
+4571f72 test/rgw: initial work on multi site test framework
+8f34600 rgw: option to set realm, zonegroup, zone as default
+94bd292 rgw: fix period pull of first epoch
+346343e rgw: http client lock related fix
+b991ff7 rgw: more log info on realm reloading
+74fdef4 rgw: bucket sync, don't drain_all() before shutting down lease cr
+f81eb8e rgw: switch to local zonegroup config if zone is not found
+1975310 rgw: make realm pull a raw storage operation
+e8f148e rgw: adding more reflection where needed
+d1d9386 rgw: rearrange zonegroup and zone initialization
+684d813 rgw: report error
+b91e451 rgw: reflect period when setting as current period
+6494347 rgw: realm pull also pulls period
+5c96534 rgw: data shard sync locking
+0b5cdc3 rgw: take a lease before syncing bucket shard
+dd490b6 rgw: merge related fixes
+4720662 rgw: update bucket index marker before skipping entries
+3686135 rgw: fix data sync notification
+2108b2d rgw: remove incorrect conn assignment
+f00585f rgw: incremental sync, skip non-complete entries early
+8b9cd66 rgw: forward bucket creation removal if it's not meta master
+52486a9 rgw: data sync, don't yield when spawning
+b9fbe05 rgw: keep track of how busy a cr stack is
+b8dcb66 rgw: avoid unneeded yield
+6a31379 rgw: fix setting of rgw_zonegroup from rgw_region
+9dccf6e radosgw-admin: clean backward support for region in the cli
+eca0bb8 rgw: use zonegroup id for location constrain
+efe8d9d radosgw-admin: zone set add a check for zone name in json
+3b41d87 rgw: create a unique zone pool names
+e08eb9c rgw: don't spawn multiple concurrent object sync for same object
+36e5ded rgw: fix call to index_key_to_marker()
+d6597be rgw: cancel index operation if delete got ENOENT
+94ad24a rgw: rework set_description(), set_status()
+67fa54f rgw: data sync, only use complete log entries
+0efd1ff rgw: more coroutines annotation
+fa5b36c rgw: start annotating coroutines status and description
+637bd56 rgw: remove sync reporting
+44194c0 rgw: keep status and history in coroutine
+706a194 rgw: remove run context when finished running
+085ee73 rgw: track all stacks, not just scheduled
+b8eb5bd rgw: more on fix for g_ceph_context shutdown
+24e1a4e rgw: handle the case of non exisiting zonegroup
+2830845 radosgw-admin: allow region use for backward compatability
+21eaefa rgw: admin socket related fixes
+1e0ac52 rgw: hook cr managers to admin socket
+d920dab rgw: add locking to coroutines reporting
+968cc6b rgw: start moving report into coroutines
+f5f05ba rgw: more metadata sync reporting
+961e602 rgw: start hooking sync report
+1c6ac7b rgw: framework for per-rgw sync status reporting
+5aa81b9 ceph_json: add deque encode/decode
+7f439b1 radosgw-admin: replace region with zonegroup in the help file
+edc24bf rgw: fix assert on shutdown by keeping g_ceph_context around longer
+124cf06 rgw: remove epoch and duplicates from list_periods
+f20c0ac rgw: fix compilation error in RGWPeriodPusher::handle_notify
+c54a99f rgw: fix compilation error on i386
+aa8a1eb rgw: call drain_all() before returning from some crs
+cd1b46d rgw: allocate a larger buffer for full sync omap oid
+87ef103 rgw: register RGWPeriodPusher with RGWRealmWatcher
+22fca7e rgw: RGWPeriodPusher shares periods between zones/groups
+9ecd08f rgw: RGWRealmWatcher supports multiple watch types
+e836b36 rgw: rename RGWRealmReloader::FrontendPauser to Pauser
+cf8b1b2 rgw: period push succeeds even if it isn't a new period
+76f811b rgw: refactor reconfigure out of RGWRealmWatcher
+ac18d0c rgw: keep Context for reconfig timer cancellation
+5adae5b rgw: add RGWRealm::notify_new_period()
+abec368 rgw: fix typo in RGWPeriod::update
+9122fab rgw: fix for decode of ZoneGroup id
+155ab74 rgw: cr call() doesn't return a value
+521fb06 rgw: data sync marker tracker, don't assert
+396bbb4 rgw: we need to rename the zone inside the zonegroup too
+d065ef4 rgw: fix RGWSystemMetaObj::rename
+1297b37 radosgw-admin: add --zone-new-name to usage
+1aabaaf rgw: init num shards if sync status did not exist
+9fc032f rgw: use correct connection for certain data sync operations
+4f17bbb rgw: translate source_zone param into source zone id
+8c11019 rgw: start marker tracker sync entry can fail
+29496f0 rgw: clarify log message
+10171dc rgw: fetch bucket instance info if doesn't exist
+f75388a rgw: data sync fixes
+8166ac4 rgw: don't force pool names to start with periods
+35ffcff rgw: more backoff related changes and fixes
+7707234 rgw: move code around
+f5a0753 rgw: backoff mechanism for data sync
+dac0ed9 rgw: data sync CR retry after specific errors
+dcac9ba rgw: initialize data sync if needed
+fdbb968 rgw: full data sync, pass correct op
+0cf3c91 rgw: special handling of 'null' object version
+fcc6b8e rgw: initialize data member
+21347a5 rgw: keep timestamp stats in incremental sync position data
+d79fe69 rgw: init REST connection by zone name
+a958be0 rgw: coroutine manager returns ECANCELED when going down
+7942c93 rgw: fix compilation with older boost versions that don't have asio coroutines
+209608a rgw: remove include to <boost/asio/coroutine.h>
+2bfd66e rgw: remove include to <boost/asio/coroutine.h>
+49bf8ba rgw: show data full sync stats
+7c43554 rgw: keep sync progress info for full sync
+28ba9af rgw: update the correct shards when doing full sync
+86148c4 rgw: shutdown lease CR on mdlog inc sync failure
+1a0e74b rgw: use boost::intrusive_ptr for http_op ref counting
+0328253 rgw: apply RGWRESTReadResource::wait_bl() fix to PostResource as well
+e81c1ac rgw: RGWRESTPostResource takes param_list_t for RGWPostRESTResourceCR
+6268158 rgw: add make_param_list() helper
+6c1f376 rgw: add typedef for rest parameter lists
+a1816d9 rgw: use insert to copy containers in rgw_rest_conn
+d585436 rgw: move RGWPostRESTResourceCR to rgw_cr_rest.h
+384df8d rgw: RGWRestConn uses vector instead of map
+91de9b5 rgw: workaround to clear location constrain when using default zonegroup
+1f485dd rgw: bucket ops, obj create and obj delete should check to see if bucket exists
+2a22b2b rgw: realm watcher locks mutex for SafeTimer::shutdown()
+0c0c996 rgw: fix bucket creation and deletion when there is no realm or period configured
+d12da62 rgw: use default zonegroup and zone in init_complete
+9acb629 rgw: allow creating a bucket without current period
+111cb41 rgw: fix data sync initialization
+3fa1cc7 rgw: move data sync init into the processing thread
+105f8a0 rgw: rework incremental md sync error handling
+d047763 rgw: move children collection to other method
+953086a rgw: handle transient error in md full sync
+a4cec38 rgw: coroutine drain fixes
+1a92c4b rgw: RGWCoroutine::spawn() returns stack
+91761d1 rgw: a coroutine util function to collect a single stack
+4bbfe63 rgw: rework error handling when syncing a single md entry
+fbdd3ad rgw: get some errors from req_data
+c8cd83c rgw: multiple sync initialization and error handling fixes
+50fd0bd rgw: return -EAGAIN on a connection related http failure
+41bbe95 rgw: cleanup
+9702966 rgw: error out if failed to build md sync index
+7be9268 rgw: init sync env
+96e3850 rgw: mdlog full sync, yield for each entry
+d8dcf9b rgw: move sync_oid() and shard_object_name() to sync env
+ca5e00b rgw: create RGWMetaSyncEnv, use it as container to sync env
+3191390 rgw: RGWPeriod stores sync_status as vector of strings
+99ef6fc rgw: store metadata sync status on period commit
+de748e5 make: fix link of ceph_test_cls_rgw_meta
+790eeb5 rgw: add rgw_rest_realm.h to the Makefile
+55a5add rgw: add missing rgw_meta_sync_status.h to the Makefile
+580e017 rgw: account total number of metadata entries for sync
+e99da77 rgw: add backoff and restart to meta sync
+09112f2 rgw: fix the mdlog sync lock control flow
+2991ffb rgw: use set_cr_error() and set_cr_done() instead of set_state()
+261e643 rgw: md full sync backoff
+e92c915 rgw: create a realm in case of pervious regions configuration
+6d65dac rgw: add support for region format in RGWOp_ZoneGroupMap_Get
+2650b3b rgw: update current_period after adding converted zonegroup
+ac6dcc7 rgw: add RGWRegionMap for backward compatability
+f2424a1 rgw: update realm_id when converting a region to zonegroup
+ae729aa rgw: add converted regions into the current period
+ab6c921 rgw: RGWRealmWatcher to reload RGWRados on changes
+40608a5 rgw: period commit calls notify_zone
+4d72adc rgw: add realm control object for watch/notify
+30f7485 rgw: add pause/unpause to RGWFrontend interface
+c010a3c rwlock: add prioritize_write flag to prevent write starvation
+f81e72f rgw: RGWHTTPManager dtor stops background thread
+afc3194 radosgw-admin: remove period activate in favor of commit
+6b1cb5d radosgw-admin: add --commit flag for period update
+132c2a1 radosgw-admin: add 'period commit' command
+c38a781 rgw: period push handler supports commit
+d9a19c7 rgw: add RGWPeriod::commit()
+25c14c8 rgw: period push handler updates current period/epoch
+51133f1 rgw: RGWPeriod accessors are const
+2977996 radosgw-admin: add realm pull command
+ee6d76f radosgw-admin: add send_to_remote_or_url() helper
+5704bcd rgw: add op for GET /admin/realm
+7623e43 rgw: add realm params to period pull
+a69e69a rgw: move period Ops to rgw_rest_realm.cc
+fc483c8 rgw: period allows setting id, epoch, latest_epoch
+55dfc85 rgw: omit epoch in oid for staging period
+3b019fa radosgw-admin: add 'period update' to usage
+0174086 rgw: RGWRemoteMetaLog ctor sets async_rados=nullptr
+d3b3dda rgw: fix comparison typo in RGWRados::init_complete
+c7f77c6 rgw: RGWHandler_Config should assume empty type is zonegroupmap
+899ff3d rgw: guard metadata full/incremental sync
+f055fae rgw: guard metadata sync initialization step
+092303a rgw: a bit better coroutine related logging
+76bfd7b rgw: initialize rest connection if no period
+70a2b93 rgw: multiple init metadata sync locking fixes
+697753a rgw: backward compatability update_name for existing zones
+c16caa0 rgw: update new name after converting region to zonegroup
+db6647d radosgw-admin: fix zone get command
+ae80742 rgw: use default zone in case there is no period or zone name
+e9044fc rgw: RGWRados zonegroup and zone_public_config should not be accessed directly
+ea60f7e rgw: RGWRados internal zone should be protected and not accessed directly
+3468dd6 rgw: fix RGWSystemMetaObj::init by passing old_format flag
+c11a5a5 rgw: convert regionmap
+2441b7c rgw: add support to zonegroupmap set
+4c6a01a radosgw-admin: zonegroupmap get should no error if no realm or period
+f5857c7 rgw: no need to store or update zonegroupmap
+8e77fa6 rgw: remove zonegroup_map from RGWRados
+3263c2e cmake: move link dependencies to rgw_a
+d97718d CMake - add check for libcurl
+6a40350 rgw: don't read/init sync status if meta master
+680e58e rgw: fix log message
+8d32392 rgw: can set zone read-only, can set zonegroup id
+fb2b8f2 rgw: update rest connections from the current period
+4195f8b rgw: read local zonegroup and zone only when needed
+bba6853 rgw: use current_period zonegroup and zone when exists
+fa2dc6a rgw: read current period during init
+4733ccb rgw: zonegroup and zone should not be accessed directly
+4a5d77a rgw: get_predefined_name should get the ceph context
+d1e32a8 rgw: can override master zone config
+d2109c7 rgw_admin: update zone set
+78294dd radosgw-admin: zone add command should be zonegroup add
+526421a rgw: run sync thread only when number of zones > 2 and master is configured
+a2e7cd5 rgw: update master zone
+78f53f3 rgw: stuff more info into the period
+4d48401 rgw_admin: period update command
+46b268c rgw: auto create placement target params
+93bddf9 rgw: create default zonegroup for first time run of the gateway
+66041ae rgw: --rgw-zone and --rgw-zonegroup use names not id
+2ae0f41 rgw_admin: can config access/secret key for zone
+56bbadf rgw_admin: can set zonegroup api name
+12239dd rgw_admin: can update zonegroup endpoints, is_master
+c497fac rgw: set first created zone as default
+448674b rgw: prefix default pools with zone name
+8e8f13d rgw: set first created realm as default
+369e484 rgw: period oid doesn't include realm id
+702d5b0 rgw: period get does not require specifying period id
+a325dd5 rgw: use --rgw-realm instead of --realm
+5f774a1 rgw_admin: realm set-default -> realm default
+ee29f62 rgw_admin: zone delete doesn't require zonegroup
+212d8f4 rgw_admin: zone name need to be provided on zone create
+eeaf75d rgw_admin: don't require zonegroup id on some commands
+962eb3c rgw: don't use --zonegroup, use --rgw-zonegroup
+a12ec59 rgw_admin: a zone default command, and other changes
+6577564 rgw_admin: don't use --zone, use --rgw-zone
+fd315d9 rgw: update zonegroup endpoints when creating it
+fc3df34 rgw: update zone endpoints when creating a new zone
+ba629cd rgw: update rest_conn_master when adding a new master zonegroup
+fa12a07 radosgw-admin: zone get and rename commands should work without zonegroup id or name
+9638a4e radosgw-admin: check for valid input in zone delete command
+2a947bf radosgw-admin: check for valid input in zone add command
+01e342f radosgw-admin: check for valid input for zonegroup modify command
+e79171c radosgw-admin: check for legal input for zonegroup default command
+f267df2 radosgw-admin: check legal input for zone modify command
+824a05b radosgw-admin: use realm_id from zonegroup if not provided
+4517bf7 rgw: fix RGWZone::dump
+9954bb5 rgw: add zone modify command to change master zone
+e65afc5 rgw: add zonegroup modify command to allow setting/clearing zonegroup master status
+452c8ee radosgw-admin: fix zonegroup and master usage text
+ef64157 rgw: remove is_master flag from zoneparams
+c926903 rgw: print zone name and id in the begining of the dump
+c05e632 radosgw-admin: fix zone create to check for zonegroup name
+5806562 rgw: store latest sync status when activating a period
+9817809 rgw: add decode_json method to rgw_meta_sync_status structures
+189c1b1 rgw: move rgw_meta_sync_status, rgw_meta_sync_marker and rgw_meta_sync_info into a sperate h file
+bc70d67 rgw: move dump functions into rgw_json_enc.cc
+3bd29b4 rgw: zone config related changes
+9dfbae6 rgw: fix compilation
+208a387 rgw: don't try to unregister request on destructor
+e18b72f rgw: add bucket_quota to RGWRegionMap::encode_json
+9272d7e rgw: add period_map to period dump and encode_json
+852ead5 rgw: fix whitespace and remove debug messages
+220e8e8 rgw: add backward support for old regionmap format
+bded7eb rgw: add RGWRegionMap for backward support
+c1e1f12 rgw: remove debug message from decode_zones
+1882243 radosgw-admin: remove extra print from zonegroup set command
+6705fe7 rgw: rgwzone decode_json should handle empty id for backward compatabiltiy
+6c45a2a rgw: systemmetaobj::create don't generate random id if id is provided
+e020790 radosgw-admin: zone set should handle old format json (without name or id)
+57cb518 rgw: add id to RGWZone dump and decode_json functions
+dbd70b0 radosgw-admin: zone create should update zonegroupmap for non standalone zones
+d12836d radosgw-admin: fix zonegroup default
+922721c radosgw-admin: add --rgw-zonegroup for backward compatability
+9082ed6 radosgw-admin: zone set command should update zonegroupmap
+a320a44 radosgw-admin: realm set should update zonegroup map
+674087e radosgw-admin: zonegroup set needs to update zonegroupmap
+c3907af radosgw-admin: fix zonegroupmap update
+117bb62 rgw: backward compatabilty for zone set command
+3d9eb7f radosgw-admin: add --rgw-zone for backward compatability
+265e093 radosgw-admin: update zonegroupmap when activating a period
+695b48b rgw: fix zonegroupmap initialization in init_complete
+d6d57ae rgw: use realm provided in the command line
+eb6fe35 radosgw-admin: use the correct realm id when creating a new zonegroup
+cd120d8 radosgw-admin: use zonegroup realm id in zone add command
+76df911 rgw: add realm_id to zonegroup
+0e4cdb6 radosgw-admin: update zonegroupmap when adding a zone
+23cafb0 rgw: use encode_map for zonegroups
+d178f99 rgw: fix zonegroup create
+6f80c92 rgw: fix realm create
+3c45e43 rgw: fix init_complete when there is no realm
+60f948d radosgw-admin: fix error messages for zonegroup create
+fe8c344 rgw: fix zonegroup update
+84f9a26 rgw: update zonegroupmap when creating new realm
+8851568 rgw: add period_map to encode/decode
+ae7f804 rgw: add zonegroup_map period update
+1150047 rgw: add zonegroupmap realm update
+9af5152 rgw: fix encoding and decoding of realms and periods
+b8b237a rgw: add realms to zonegroupmap
+10adb67 rgw: zonegroup map contains a map of periods
+c04e688 rgw: move zonegroup data into rgwperiodmap
+993481a rgw: cleanup period init
+660fc7c rgw: use RGWZoneGroupMap in RGWPeriod
+0d83cfe rgw: add use_next_epoch method
+ea0a420 radosgw-admin: add zone create, delete and rename commands
+9a0d417 rgw: RGWZoneParams should inherit from RGWSystemMetaObj
+d4b58ba rgw: RGWZoneGroup should inheirt from RGWSystemMetaObj
+9451af6 cmake: fix erasure-code
+66eb020 rgw: Rename Region to ZoneGroup only internal structures and class
+a8d765d rgw: Add period admin commands and rest api to handle period
+1680bb7 rgw: Add RGWSystemMetaObj class
+daaf7b4 rgw: Add RGWNameToId and RGWDefaultSystemMetaObjInfo
+94db324 rgw: async rados requests through a work queue
+9744de7 rgw: add new class to create resource request
+beac57f rgw: don't require system pools to start with a period
+3c6e5e7 cls/rgw: rgw_bi_log_entry::decode_json(), decode ver
+966dd3e rgw: propagate olh_epoch for obj sync correctly
+6e243c3 cls_rgw: reset dirent flag appropriately
+5e36885 rgw: fetch_remote_obj() uses correct version_id
+9c6a962 rgw: handle object removal in incremental data sync
+ddfb019 rgw: tie incremental data sync
+beba94b rgw: data sync locking fixes
+01608a8 rgw: minor cleanup
+0bdf150 rgw: don't create connection object for zone without endpoints
+5a7e4e3 rgw: async data changes notifications
+b334c03 rgw: work towards datalog sync notification
+35d48c0 rgw: eliminate window for data sync marker
+c43f736 rgw: only account actual io for coroutine io window
+579bd3a rgw: incremental data sync adjustments
+8ff3979 rgw: incremental data sync
+a8dc84e rgw: fix data sync init
+aefa088 rgw: add rwlock to RGWObjectCtx
+cf3bbdd rgw: reduce the use of obj_ctx
+3dff625 rgw: revive io window
+04cd592 rgw: data sync, spawn sync on all shards
+1403b23 rgw: move top level data sync function into coroutine
+390f64a rgw: data sync work
+f6788b7 rgw: multiple fixes related to coroutines draining
+27450d7 Revert "rgw: simplify unblocked by stack state change"
+aa829e3 rgw: clean up child draining a bit
+649b672 rgw: simplify unblocked by stack state change
+c4cdb39 rgw: finish execution when done with bucket sync
+b8d57a2 rgw: add RGWCoroutine::wait_for_child()
+9422936 rgw: no need to yield while collecting
+65308b5 rgw: fix pending operations accounting
+0f42103 rgw: collect spawned requests before completing coroutine
+092cf68 rgw: url_encode http params in requests that we send
+7cc81c4 rgw: skeleton for bucket index incremental sync
+800f391 rgw: add rgw_bi_log_entry::decode_json
+6b2df0e rgw: init shard_id param for bucket listing
+23e083a rgw: fix shard_id use
+cd1ad88 rgw: move bucket shard full sync to its own coroutine
+6d6cdc7 rgw: switch sync state when done with full bucket sync
+e833021 rgw: fix iteration over bucket entries in full sync
+82db477 rgw: silence some verbose logs
+24373fd radosgw-admin: bucket sync commands don't require bucket id
+0ffbd84 rgw: keep bucket sync markers in object attrs
+df001d8 rgw: can read attrs when reading system obj
+727db68 rgw: window of full sync operations per bucket
+868dccf rgw: api adjustment following rebase
+9f63b15 rgw: fix identification of canceled operation
+8659ff1 rgw: bucket sync fetches remote objects
+cd20ec8 rgw: bucket sync, send marker when listing bucket shard
+4d69b8f rgw: extend list bucket versions api
+07f3754 rgw: fix signing for generated requests
+442edc8 rgw: list bucket instance shard entries for data sync
+f5a27f9 rgw: read bucket sync status
+f0e351d rgw: per-bucket instance shard state
+2b4de2d rgw: initial work on data sync run
+5fb6615 rgw-admin: implement data sync init
+3d49dce rgw-admin: data sync status command
+29db3ce rgw: initial data sync work
+fa96d4e rgw-admin: skeleton for data sync commands
+2aa6fd9 radosgw-admin: switch mdlog sync commands to metadata sync
+15c530b build: add cls_timeindex_client to DENCODER_DEPS
+14cb57a rgw: propagate rgwx-bucket-instance for copying objects
+a3b0d20 rgw: fix time parsing for delete precondition
+9751d61 rgw: add no-precondition-error http param for object delete
+0f7e3e0 rgw: add mtime check to object removal if needed
+c90d7cb cls/rgw: add an objclass method to check obj mtime
+fc01f16 rgw: add DELETE_IF_UNMODIFIED_SINCE header to obj delete
+e36db98 rgw: more api adjustments
+babbf67 rgw: adjust calls
+fe9c64b rgw: identify racing writes when using copy-if-newer
+20d24e9 rgw: translate http error 304 to appropriate status
+27946e8 rgw: fix if-modified-since boundary
+8813a44 rgw: add rgwx-copy-if-newer http header
+5d92490 rgw: make rgw_user::empty() const
+142c5a8 rgw: access zone.name, zonegroup_name through accessor
+22f766e rgw: dump internal object tag when system user lists bucket
+359325b rgw: system user can list bucket shard
+9cb1d6f rgw: get_bucket_stats() returns a plain marker if shard specified
+654f203 rgw: bilog info can get shard id
+413ac34 rgw: fix uninitialized variable
+73a2147 rgw: move more code
+9ab02a8 rgw: trivial fix
+be3e272 rgw: use internal wait instead of special coroutine
+07feb13 rgw: coroutine stack wait util
+9ca266a rgw: move more code around
+f2eb0d7 rgw: move code around
+e6548ec rgw: rearrange full metadata sync order
+6adf75c rgw: trivial fixes
+5cc80b0 rgw: fix shutdown
+4b80edb rgw: http client req handling fixes
+3e7b86e rgw: wake up appropriate shard sync handler
+18a9a43 rgw: a few sync thread init/finalization fixes
+f7ac122 rgw: run and stop sync thread
+a848353 rgw: simple thread base class
+11dd2b8 rgw: decode mdlog notification shards
+a7a9ca7 rgw: send mdlog changes notifications to zones
+c26ff96 rgw: add simple POST requests interfaces
+0f65f56 ceph_json: add json encoder / decoder for std::set
+4ce5109 rgw: periodical thread that tracks mdlog changes
+30bf776 rgw: handle mdlog post request
+766d52a rgw: keep track of modified mdlog shards
+390e1e1 rgw: create the first period when creating a new realm
+1f0c2c5 rgw: Add zone add command
+c479504 radosgw-admin: allow creating a zone without a zone group
+c6be10d rgw: add master flag to zonegroup create command
+9da0707 radosgw-admin: period pull supports --url
+7a760fe radosgw-admin: fixes for period push/pull
+669b9fc rgw: RGWRESTSimpleRequest::forward_request params
+4a2f168 common: expose Formatter::flush to derived classes
+6693737 rgw: POST /admin/realm/period reads in json data
+be17da5 rgw: delay allocation of RGWPeriod
+dfadc9f rgw: add handler for /admin/realm/period
+a0d76ec rgw: fixes for RGWZoneGroupMap::decode_json
+6823248 radosgw-admin: add realm set command
+7b81c27 radosgw-admin: add json output to create commands
+b9e51fc rgw: fix period init and activate
+7f683ed rgw: update period predecessor when it is activated
+d259066 rgw: fix realm list-periods
+27fda3a rgw: realm id and epoch should be part of period oid
+92504dd rgw: Add realm list-periods command
+589fe2e radosgw-admin: Add master_zonegroup and master_zone to period prepare
+750074b radosgw-admin: Add period list command
+8190047 radosgw-admin: print new perion in period perpare command
+3fc65d1 rgw: fix zone set command
+27af893 rgw: remove debug messages
+ef5544f rgw: default zone should not be master
+12ce512 radosgw-admin: add zone create, delete and rename commands
+550d84f rgw: RGWZoneParams should inherit from RGWSystemMetaObj
+297de47 rgw: use id for master zone
+a6acb1a rgw: add id to RGWZoneParams
+5fa0764 rgw: Add RGWSystemMetaObj class
+199ee22 rgw-admin: adjustments to period get-current output
+f5a0567 rgw-admin: use default realm on realm get
+1adf6a5 rgw: pass const string reference
+10b3fe7 rgw-admin: fix realms list
+7a1cb78 rgw: fix typo
+764dc5b rgw: do the actual incremental metadata sync
+fe38269 rgw: track mdlog marker
+311c105 rgw: don't force wait on blocked coroutines
+e332d17 rgw: fix busy wait in RGWHTTPManager
+fe11373 rgw: sync local mdlog if needed
+814fe66 rgw: wake up wait coroutine thread on destruction
+dc3feb6 Add zone create admin command - wip
+c169b75 rgw: add id to RGWZone
+8f7b671 rgw: poll mdlog for incremental sync
+6bf77a7 rgw: read mdlog entries for incremental sync
+1292623 rgw: get remote mdlog status when initializing
+3db4e98 rgw: hash full sync keys to shards
+528aff1 rgw: switch to incremental sync when done full meta sync
+46445a6 rgw: update global sync state after building meta indexes
+bd5a6b3 rgw: update meta sync markers during full sync operation
+f176c58 rgw: add zonegroup name or id to zonegroup get and set commands
+f4be269 rgw: Add zonegroup create, delete and rename admin commands
+d07306c rgw: add period activate admin command and fix get current command
+242f2c8 rgw: add current_period to RGWRealm
+95f7126 rgw: RGWZoneGroup should inheirt from RGWSystemMetaObj
+0380054 mds: don't double-shutdown the timer when suiciding
+34f896b src/ceph_osd.cc Add missing newline to usage message
+d7f0304 common: fix build error with Graylog
+d8675cf Log: Adding UT to catch an issue with huge line logging
+dd533a9 Log: Fixing stack overflow when flushing large log lines. See http://tracker.ceph.com/issues/14707
+5b3a4d2 test: new librbd flatten test case
+0da0eda unittest_[ceph_]crypto: fix warnings
+fd85a9b unittest_bufferlist: fix warning
+c633258 unittest_compression_[*_][plugin]: fix warnings
+8fe7584 Better parsing of arguments passed to mount.fuse.ceph by mount command.
+856e6da ceph_test_libcephfs: fix warnings
+8f42f89 tests: ceph-disk.sh: use "readlink -f" instead for fullpath
+bcf1204 selinux: Allow log files to be located in /var/log/radosgw
+bfafc3b xio: avoid trying bind to port we know will fail
+1304e94 xio: check for xio connection error before set as connected
+36a82b3 xio: fix error from explicit ctor of entity_name_t
+b448f3c xio: thread name must be less than 16 chars
+40936fb os/bluestore: fix a typo in SPDK path parsing
+b92eb66 librbd: protect journal replay against overlapping writes
+bb66231 librbd: track in-flight AIO flush requests during journal replay
+1cc409b test: possible librbd journal replay flush race
+3969b83 os/bluestore/KernelDevice: force block size
+fce9b27 rgw: make function parameter 'errordoc_key' passed by reference
+7d10a44 doc/release-notes: v10.0.3
+676c489 global/global_init: chown log, asok if drop privs is deferred
+ccd5531 common/admin_socket: add chown
+32da962 log: add option fchown on log file
+8ca144e OSD/ReplicatedPG: Adding test case to catch issue #14511
+4e3ce25 Add better documentation of --setuser and --setgroup options for ceph-disk.
+17fe9d2 Add --setuser and --setgroup options to ceph-disk(8).
+3adbe10 Add support to override ceph-disk's user and group choices
+efab230 tests: sync ceph-erasure-code-corpus for mktemp -d
+30b257c ghobject_t: use ! instead of @ as a separator
+7ba6889 tests: ceph-disk.sh: should use "readlink -f" instead
+ca5ec8a release-notes: draft v10.0.3 release notes
+5591cdf scripts: ceph-release-notes fix merge messages handling
+075e595 cmake: remove Boost libraries from EXTRALIBS
+f5cad7a log: remove "boost/asio.hpp" from Log.h
+ef1573b cmake: disable warnings introduced by 457f023
+aef2006 Revert "cmake: add libboost_system to EXTRALIBS"
+27212c5 common/page.cc: _page_mask has too many bits
+e85ce44 test_rados_api_misc: disconnected rados_monitor_log test
+25a4fbd rgw: Add old_format support to RGWSystemMetaObj
+8c43c2d rgw: add id to zonegroup
+b6574f2 memstore: fix alignment of Page for test_pageset
+95770b0 rgw: remove region
+6b46abc rgw: change RGWZoneGroup::get_pool_name to return string
+d67cf63 rgw: convert old region configuration to zonegroups during init
+29f34b8 fix ceph-dencoder link
+cdc47a3 cmake: add rgw_sync.cc and rgw_coroutine.cc
+da7940a rgw: fix async sleep and wakeup logic
+26e1b7c rgw: full meta sync
+390c421 rgw: naively fetch all meta objects
+89f9d0a rgw: read remote meta coroutine
+085a992 rgw: read full sync indexes
+9034bd7 rgw: modify sync state, sync run uses state
+f94164e rgw: coroutie for omap_get_vals()
+68fd306 rgw: keep track of spawned coroutines under the current op
+48587f0 rgw: replace omap_set coroutine code
+0f18d6e rgw: fix the simple coroutine
+78192d3 rgw: fix async sleep and wakeup logic
+647888b rgw: coroutines producer consumers
+9171db7 rgw: build index of all master zone meta keys
+2bcad24 rgw: create a coroutine for fetching REST api objects
+8451eff rgw: fetch all metadata entries
+d2fdee3 rgw: meta sync cleanups
+e552145 rgw: remove calls for synchronous rados ops
+42a0222 radosgw-admin: dump shard status on mdlog sync status
+640b49e rgw: initialize all shard markers
+660e21e rgw: return error if any spawned op errored
+c06e310 rgw: iterate through all mdlog sync status shards
+bfeb693 rgw: remove unused code, cleanups
+d2a1743 rgw: adjust mdlog fetch to use new interfaces
+3409051 rgw: fix init mdlog sync
+b14f85a rgw: mdlog sync init
+4be55f1 rgw: use boost for stackless coroutine flow
+c31276f rgw: add cookie to lock coroutines
+c510acd rgw: more lock/unlock coroutines work
+737f8ba rgw: prepare rados lock operation to be used with coroutines
+36f0f81 rgw: simple rgw metadata write coroutine
+3b07e1a rgw: move coroutines code
+a1abe96 rgw: return retcode of failing coroutine
+9457f8b rgw: rename async ops to coroutines
+874ff63 rgw: fail if master zone tries to use meta sync
+9e334eb rgw: Fix init_complete
+aefa7d1 rgw: support old region configurations
+27374b0 rgw: Remove region admin commands
+db0e2b0 rgw: Add zone group admin commands
+c46e5cc rgw: zonegroup json encoding/decoding with backward compatability
+796e470 rgw: Rename Region to ZoneGroup only internal structures and class
+63d7c34 global: add DEFER_DROP_PRIVILEGES flag
+7099e9a rgw: Add period admin commands and rest api to handle period
+5342660 rgw: Add RGWPeriod
+95a5130 rgw: Add RGWRealm class and admin commands to handle it
+c77a5e5 rgw: Use switch for raw storage opcodes
+417ac39 rgw: use string for default realm
+2196eeb rgw: Add RGWSystemMetaObj class
+065fa7c rgw: Add RGWNameToId and RGWDefaultSystemMetaObjInfo
+ced45f4 rgw: fix test_rgw_admin_log.cc
+787ee9a cmake: add rgw_sync.cc
+4396fd4 rgw: async ops can generate new stacks for parallel execution
+2534452 rgw: a few bug fixes related to async operations
+dee7505 rgw: add a generic op to pull data off metadata obj
+9a7a229 rgw: add another state for simple async ops
+901ebb5 rgw: more simplification
+7daa80a rgw: more simplification, no need to take reference to op
+b8399ff rgw: some cleanup, keep async env structure
+72b0986 rgw: create simple async op handler
+3e03724 rgw: async rados requests through a work queue
+a736c25 rgw: retrieve a specific sync shard info
+5e2c2e4 rgw-admin: command to show mdlog sync status
+dd472a1 rgw: stackable ops infrastructure
+624a3fa rgw: initial work on sync status marker
+1c9079a rgw: read mdlog marker
+8f36e60 rgw: clean up mdlog clone states, other fixes
+d4a9051 rgw: don't reference msg after finish_request()
+ff05ddb rgw: hide the completion manager
+0c0d8b0 rgw: create some abstraction around async ops infrastructure
+38424cd rgw: mdlog sync error reporting on failed request
+601018a some error handling work, not ready yet
+9e23388 rgw: md log cloning completely async
+c3206b9 rgw: rework metadata log sync to use async capabilities
+66c1e52 rgw: can now wait on async rest requests
+fe0c785 rgw: add new class to create resource request
+2fbf80f rgw: more http aio stuff
+18bee31 rgw: threaded http manager groundwork
+866fd74 rgw: more work on cleaning up http client interfaces
+ad161bc rgw: rework http client to handle multiple async requests
+55255b2 rgw: paginated mdlog clone
+eac4e79 rgw: initial mdlog clone implementation
+fbc5ef1 rgw: can list mdlog entries
+2124ee5 rgw: move json helper into RGWRESTConn
+deb72c5 ceph_json: make sure header doesn't clobber _ASSERT_H
+2c48ade rgw: decode number of mdlog shards
+a3d500e rgw: fix use of zone name
+cdc953f rgw-admin: initial mdlog sync work
+d5484ff rgw: initial work on mdlog sync
+12a3237 rgw: don't do set_attr on meta objects
+0650799 rgw: user quota may not adjust on bucket removal
+5dfcdf6 librados: check connection state in rados_monitor_log
+89784aa rgw: store immutable metadata entries in heap pool
+676699d rgw: rename default pool names
+1fe7372 rgw: don't require system pools to start with a period
+4cc9843 OSD/ReplicatedPG: Fixing lack of object unblock when flush fails. See: http://tracker.ceph.com/issues/14511
+ee7ac8f cmake: add cls_timeindex to rgw targets
+f3ac051 test: fsx now exercises librbd journal replay
+f08ccc5 librbd: missing lock on maint operation replay callback
+851395a librbd: do not fire flush completions before associated write
+ee1fafa OSD/ReplicatePG: Fixes return value from maybe_handle_cache_detail() depending on maybe_promote() result
+6666300 debian: fix build-depends
+f06c4dc osdc/Objecter: drop lock to unregister asok hooks
+be5748a common: asok should drop lock to call hook
+c28c0b1 Correctly escape block device paths for systemd
+8c03533 mailmap: Matt Benjamin affiliation
+23f2738 mailmap: Emile Snyder affiliation
+0312174 mailmap: Jonas Keidel affiliation
+18d3a16 mailmap:  Alan Grosskurth affiliation
+8b750bf mailmap: Alexey Sheplyakov affiliation
+63d3868 mailmap: Benoît Knecht affiliation
+a03c3f0 mailmap: Chuanhong Wang affiliation
+4ba58fe mailmap: Gu Zhongyan affiliation
+3bb9f86 mailmap: Ivan Grcic affiliation
+70848c4 mailmap: Jeffrey Lu affiliation
+ee4ca53 mailmap: JP François affiliation
+1bdd3b0 mailmap: Kevin Jones affiliation
+6a0c84b mailmap: Lukasz Jagiello affiliation
+26035b5 mailmap: Mauricio Garavaglia affiliation
+8c317ea mailmap: Patrick Donnelly affiliation
+a71ae4a mailmap: Rachana Patel affiliation
+951c331 mailmap: Roi Dayan affiliation
+5736f9c mailmap: Wei Jin affiliation
+712c52b mailmap: Jianjian Huo affiliation
+bbbd2ec mailmap: Sahithi R V affiliation
+230bb72 mailmap: Marcel Lauhoff affiliation
+b27bc0d mailmap: Robert LeBlanc affiliation
+afcc666 mailmap: Erwan Velu affiliation
+28c2108 mailmap: Barbora Ančincová affiliation
+12ea474 Stripper: Fix incorrect push_front -> append_zero change
+3fe17c6 mailmap: fangdong affiliation
+833c8e2 mailmap: Jingkai Yuan affiliation
+3039248 mailmap: Harry Harrington affiliation
+2a35e18 mailmap: Tao Chang affiliation
+ab6baa9 mailmap: Shishir Gowda affiliation
+78d91d6 mailmap: Adam Twardowski affiliation
+e8e0521 mailmap: Shun Song affiliation
+5bda3a2 mailmap: some duplicates found on .organizationmap
+f59db3c mailmap: Luo Kexue affiliation
+588eeea mailmap: Aron Gunn affiliation
+efc8134 v10.0.3
+8556b9d mailmap: further cleanup.
+17d2622 mailmap: Abhishek Lekshmanan affiliation
+467990a mailmap: Darrell Enns affiliation
+2a3ce4e mailmap: Ilya Shipitsin affiliation
+b57a3ac mailmap: Li Tianqing affiliation
+eaf5bc7 mailmap: Yehua Chen affiliation
+ac61c11 mailmap: Ren Huanwen affiliation
+20783f8 mailmap: YiQiang Chen affiliation
+c423d5f mailmap: Zhi Zhang affiliation
+f5bcdae mailmap: François Lafont affiliation
+10bb9a4 mailmap: Liu Peiyan affiliation
+638c636 mailmap: Dunrong Huang affiliation
+0fe9373 mailmap: Xie Xingguo affiliation
+f960bcc mailmap: Song Baisen affiliation
+c2e0b8f mailmap: Zhiqiang Wang affiliation
+84f58b5 mailmap: Xiangwei Wu affiliation
+fcd3bba mailmap: Adam C. Emerson affiliation
+b5d7688 mailmap: Cleanup.
+c8c1603 global: record target uid/gid in cct
 db9408b ceph.spec.in: add license declaration
-51a1572 (origin/wip-cmake-2-8-16) cmake: Added new unittests to make check
+51a1572 cmake: Added new unittests to make check
+0ca8f07 global/global_init: ensure setuser etc messages get logged
+8290536 global/global_init: do not apply_changes until after dropping privs
 a0b0ae0 Revert "osd: do not keep ref of old osdmap in pg"
 23ec516 ceph.spec.in: add copyright notice
+37b517e os/bluestore/BlockDevice: std::atomic_int
+434620b os/bluestore/BlockDevice: use std::mutex and std::condition_variable
+7181a6f msg/simple: significantly reduce minimal memory usage of Pipes
+69d98b6 msg/async: significantly reduce minimal memory usage of AsyncConnections
+12c083e OSD/ReplicatedPG: Fixes unneccessary object promotion when deleting from the cache that lacks hit_set configured.
+3395fb9 crush/CrushTester: workaround a bug in boost::icl
+990b437 OSDMap: reset osd_primary_affinity shared_ptr when deepish_copy_from
 d267aaf tests: ceph-disk.sh should compare with the resolved path
 4d38302 libcephfs: Update LIBCEPHFS_VERSION to indicate the interface was changed
+c21de4d AsyncMessenger: remove unused variables
+c45854a crypto: remove unused Digest::sec_type
+93ac31c journal: remove unused ObjectPlayer::m_fetch_interval
+2a53737 librbd: remove unused C_DiffObject::m_request_num
+9c3f821 librbd: replace atomic_t with std::atomic<int>
+64361c3 ECUtil: remove unused stripe_info_t::stripe_size
+7d08bbf osd: init HeartbeatDispatcher using OSD->cct
 08364c2 ceph-disk/test: fix test_prepare.py::TestPrepare tests
 8569d38 AsyncConnection: avoid debug log in cleanup_handler
+a48c081 rgw/rgw_orphan: check the return value of save_state
 f4b083a osdc: Update to use C++11 concurrency
 21438a6 cmake: add libboost_system to EXTRALIBS
 2669e0c cmake: don't try to install src/ceph-disk directory
@@ -56,13 +2299,19 @@ fa6d0ba cls_journal: new tag management methods and handling
 0851757 os/bluestore/KernelDevice: use _exit(1) for failure injection
 a297261 os/bluestore: fix block device file creation
 4c13f9d os/bluestore/BlueFS: initialize super block_size earlier in mkfs
+bacfce5 tools/cephfs: sharded pgls in cephfs-data-scan
+168e142 librados: enable filtering in object_list API
+e4abb95 cmake: add cls_cephfs to cephfs_testing target
 23d39cb os/kstore: kill dead code
 5d5e420 os/kstore: fix race condition
 1e8719f os/bluestore: fix race condition
+0cef323 mon: get_leader_supported_commands is unused
+17d37be mon/handle_probe_probe: redundant definition
 d5cdc7a os/bluestore: remove unused intrusive member hook in enode
 9828d49 global: do not start two daemons with a single pid-file (part 2)
 dca8111 os/kstore: assign nid for newly created onode
 d5dfb00 os/bluestore: assign nid for newly created onode
+b7bbcee mon: unregister command on shutdown
 9da41fe systemd/ceph-radosgw-prestart.sh: remove
 b9ce1df unittest_config: cope with $data_dir not being expanded on non-daemons
 78592fd common: add $data_dir/config to config search path
@@ -131,8 +2380,13 @@ f1bf983 os/bluestore/BlueStore: fix wal tail block padding
 06af9f0 os/kstore: insert new onode to the front position of onode LRU
 e85ffac scripts/run-coverity: fix upload process
 41c3dc2 test_bufferlist: add move tests for bufferlist
+573a2d9 bluestore/NVMEDevice: remove unused local variables
+83ca830 bluestore/NVMEDevice: fix fd leak
+a5714fb bluestore/NVMEDevice: fix wrong remove_device logic
+06f3837 bluestore/NVMEDevice: fix compiling error
 caed882 os/bluestore: insert new onode to the front position of onode LRU
 7c86775 bluestore/bluefs_types: fix imcomplete output message
+8167a22 mds: function parameter 'df' should be passed by reference
 1c9c49e Crush when get immediate parent quickly reply.
 627535a KernelDevice: add aio_log_finish for write
 cdbea72 KernelDevice: remove unused local variables
@@ -150,6 +2404,7 @@ b593e1c BlueFS: remove redundant intermediate buffer pad
 a3789e8 BlueFS: fix unprecise calculation of sync interval
 09d2644 BlueFS: add log after updating prefer_bdev field.
 93413b5 qa/workunits/rados/test.sh: bash
+ec36dcd rgw: approximate AmazonS3 HostId error field.
 669f143 buffer: add operator= for ptr/bufferlist rvalue
 0305cee misc: using move construct to avoid extra atomic inc/dec
 dd4e6e1 buffer: add ptr move construct
@@ -253,6 +2508,7 @@ e76f716 bluestore: add NVMEDevice backend
 6055d96 AsyncConnection: add a debug option to test noninline way
 86883b2 AsyncMessenger: add perf counter for inline message sent
 f6b87d3 AsyncConnection: use move instead of bufferlist copy construct
+8c7261b Rgw: check the return value when call fe->run()
 e9872ad civetweb: update submodule to silence a compile warning
 493619a common,osd: remove _process(T *t) to silence warnings
 127e7c0 mon: monmap created is 0.000000 use ceph-deploy installed
@@ -264,6 +2520,9 @@ a17ea39 OSD:memory leak in ReplicatedPG.cc
 f8adf40 cmake: disable unused-variable warning for rocksdb
 2699c47 rgw: fix the signed/unsigned comparison warning
 d50bda5 rados: bench: fix the signed/unsigned comparison warning
+b1e27a5 configure.ac: add pwritev check
+aa7b505 cmake: add default pwritev support now
+75a9ee2 buffer: refactor write_fd to make readable
 dc289fe AsyncConnection: avoid dispatch event to a closed connection
 4633e8d cmake: remove duplicated HAVE_EXECINFO_H macro
 88a95b7 os/*stores: fix hidden warnings
@@ -272,6 +2531,7 @@ dc289fe AsyncConnection: avoid dispatch event to a closed connection
 9da2fff AsyncConnection: add log for reap_dead and clean_handler
 cdf3c90 os/memstore: return empty list if offset overflows
 7d232d1 os/memstore: fix wrong blocksize for statfs
+79401d5 rgw: remove duplicated code in RGWRados::get_bucket_info()
 579fbc8 add some cppcheck-suppress noExplicitConstructor comments
 bbf0582 make ctors with one argument explicit
 65ed192 rgw/rgw_rest.cc: fix -Wsign-compare
@@ -350,6 +2610,7 @@ c8c5d0a mon:some cleanup in MonmapMonitor.h
 87b7e53 FuseStore: fix unhandled error cases for open
 97639f6 FuseStore: fix memory leak
 5e564ea tests: simulate writeback flush during snap create
+d5ae7f8 rgw: don't use s->bucket for metadata api path entry
 3ba54cc test/commom/test_weighted_priority_queue.cc: Add unit tests for the new Weighted Priority Queue.
 2061496 test/common/test_prioritized_queue.cc: Fix random shuffle and remove unneeded include.
 795fd8f osd: Add runtime config option to select which queue to use and the priority of the cutoff between the strict queue and the normal queue.
@@ -419,6 +2680,7 @@ b62318e os/bluestore/BlueFS: use std::mutex et al
 e9721b8 os/bluestore: fix FS creation by fs
 20c80b9 tools/rbd: fix error message typo
 130e8c6 Add UT for interval_set implementations
+8a6f1f7 qa/workunits/fs/misc: Add a workunit for tar kernel Documents
 5e2fc70 msg/async: bunch of fixes
 84175ba rgw: fix dangeours usage of strtok in RGWAccessControlPolicy_SWIFT.
 f176664 os/FileStore:clean up error message
@@ -441,6 +2703,7 @@ f2c0ef4 global/pidfile: do not start two daemons with a single pid-file
 07af5f6 bluefs_types: fix device index overflow
 8395059 time: Make ceph_time clocks work under BSD
 e71057d os/fs: fix io_getevents argument
+f111351 FileStore:Use pwritev instead of writev
 68a571b doc: small edits according to review
 2f3774b doc: remove old install-ceph-gateway_old.rst file
 1037d2e doc: Add Ubuntu-specific steps to install RGW
@@ -453,6 +2716,7 @@ c2b5a68 BlueFS: fix space leak during write
 aba6746 PG::activate(): handle unexpected cached_removed_snaps more gracefully
 68c7877 objecter: avoid recursive lock of Objecter::rwlock
 4d30e7c os/bluestore: fix bluestore_wal_transaction_t encoding test
+bde03c7 client: add option to control how directory size is calculated
 3d87312 mon/PGMonitor.cc:warning if pg not scrubbed
 ab01c0e Removing duplicate definitions for rados pool_stat_t and cluster_stat_t
 da6d696 osd: delete useless bytes_written defined in RepModify
@@ -535,10 +2799,12 @@ a9cd257 doc: rename SubmittingPatches to SubmittingPatches.rst
 2c1576b ReplicatedPG::process_copy_chunk: fix invalid list traversal for proxy_read
 97ed425 ReplicatedPG::process_copy_chunk: fix invalid list traversal for proxy_write
 1178271 rgw: remove split formatter code
+7dd9af0 init-ceph.in: skip ceph-disk if it is not present
 a51fbf2 rgw: Parse --subuser better
 e153623 rgw: Drop a debugging message
 f5da159 makefile: remove dependency on libedit
 a9addc6 mon: Go into ERR state if multiple PGs are stuck inactive
+4f4017e Increase verbosity level on RGWObjManifest line
 eb17b8f BlueStore: fix typo
 696584c BlueStore: fix dest onode process logic of clone_range
 1c70f86 BlueStore: fix dest onode process logic of clone
@@ -643,6 +2909,7 @@ cbaee84 osd:osdmap some clean up
 19dc272 mds: add config option to suspend logging
 5d8d666 mds: fix completed cap flush handling
 dafb46b mds: delay handling client caps until corresponding inode is created
+73c36f3 ceph-detect-init: fix py3 test
 0187a59 cls/cls_rbd: pass string by reference
 300c2f7 Compressor: compressor plugins unit tests
 2cadc41 Compressor: compressor code extention: plugin system added
@@ -1191,6 +3458,7 @@ dd8221d osd/OSD.cc Check health state before pre_booting
 9ea99fa mon: remove conflicting subscribes when handle_subscribe
 4efa214 kv: implement value_as_ptr() and use it in .get()
 41fcd87 doc: s/InvalidCap/InvalidCapability
+f302e05 osd: avoid FORCE updating digest been overwritten by MAYBE
 8ea80a0 rgw: add a new error code for invalid admin capability
 4275ee6 rbd-fuse:image name can not include snap name
 9eefc43 tests:delete the default order of RBD in test_rbd
@@ -1288,7 +3556,9 @@ b21152a rbd: fix "static initialization order fiasco"
 4e5921d rgw: Do not send a Content-Length header on status 204
 200d310 librbd: extra request required if journal enabled w/ caching
 bab16bb librbd: stop the copyup thread during shutdown
+7794bc4 osd/ReplicatedPG: check obs.exists for  CEPH_OSD_OP_CMPXATTR/SRC_CMPXATTR.
 395bf8a librbd: exit if parent snap is gone during clone
+0f0c76b osd/ReplicatedPG: for getattr_maybe_cache, it never return -EEXIST.
 0de959f Drop deprecated removal pg type.
 d4cf79b mon: modify the level of a log about OSD's condition in OSDMonitor.cc
 69bcac5 qa/workunits/rbd: use --object-size instead of --order
@@ -1383,6 +3653,7 @@ a977e39 common: utime_t encoding optimization
 d5cee59 doc/cephfs/posix: update
 beacff5 doc/rados/operations/crush-map: update docs on crush tunables
 425c644 crushtool: add mapping test for jewel tunables
+c287fea ajdust mstart and mstop script to run with cmake build
 2245a0c erasure-code/TestErasureCodeIsa.cc: add const
 df0c1f5 journal: add iohint flags for journal replayer.
 84310c5 journal: Add iohint flags for journal write ops.
@@ -1440,7 +3711,7 @@ ae114ae cmake: support ccache via a WITH_CCACHE build option
 50022d3 os: skip checking pg_meta object existance in FileStore pg_meta object in FileStore is actually a logical object without any significant information. All it data writes to omap (leveldb), and actually no competition condition for the real object in FileStore Based on the optimazation, we further reduce _omap_setkeys() execution time (123.784us to 108.444us, about 15%), and save cpu usage 0.5% globally
 1df9705 test/librbd/fsx: musl libc doesn't implement random_r. Use c++11 std::mt19937 generator instead.
 6f1fb16 doc: osd: s/schedued/scheduled/
-7d93cf4 (origin/wip-buffer-header) buffer: make usable outside of ceph source again
+7d93cf4 buffer: make usable outside of ceph source again
 93d3dfe Fixing NULL pointer dereference
 72785ee rgw: enforce SLO part's ETag match during GET on SLO of Swift.
 1cf149d rgw: append X-Static-Large-Object attribute during PUT on SLO.
@@ -1502,7 +3773,7 @@ c83d6db cmake: update for recent rbd changes
 25c70cf Update Jiaying Ren affinity
 c11ca42 Update Rongze Zhu affinity
 593c124 doc: rst style fix for pools document
-e62954e (origin/wip-fix-buffer) deb,rpm: package buffer_fwd.h
+e62954e deb,rpm: package buffer_fwd.h
 b23b92d AsyncConnection: Fix potential return code overflow
 3443b6d Pipe: Fix potential return code overflow
 1adf306 SubmittingPatches: there is no next; only jewel
@@ -1564,7 +3835,7 @@ fb120d7 osd: call on_new_interval on newly split child PG
 60519e2 librbd: correct lock ordering issues discovered by lockdep
 1997144 doc: remove unnecessary period in headline
 2a0263f journal: correct lock ordering issues discovered by lockdep
-4230504 (origin/wip-5073) rgw: remove comments
+4230504 rgw: remove comments
 eda44cd rgw: a minor cleanup
 bf0a7b4 rgw: don't re-set bucket tenant and name when selecting location
 ddb4caa rgw: fix a typo
@@ -1573,7 +3844,7 @@ e5bfd94 rgw: avoid calling rgw_make_bucket_entry_name() when not needed
 9425b04 rgw: objexp hint name backward compatibility
 e8de349 rgw: inherit bucket tenant from user if not specified
 acda806 rgw: add a missing cap type
-bc091ed (origin/wip-cython-rbd) pybind/rbd.pyx: only set self.closed after a successful close
+bc091ed pybind/rbd.pyx: only set self.closed after a successful close
 d10c61a pybind/rbd.pyx: remove redundant RBD.__init__ method
 8931875 ceph.spec: Cython is spelled python-Cython in OpenSuSE
 07ae545 pybind: Improvements to Cython build
@@ -1739,7 +4010,7 @@ a4924d4 ceph.spec.in: add BuildRequires: systemd
 917d85f osbench: Adds handling for the lack of required folders ( data & journal ) and adds checking for previous data presence to avoid assertion
 2902030 osbench: Fix race condition that may cause Sequencer::dtor assertion on benchmark completion
 daae180 Doubled marking from line 1151
-ada6e32 (origin/bp-smaller-pglog-2) osd: slightly reduce actual size of pg_log_entry_t
+ada6e32 osd: slightly reduce actual size of pg_log_entry_t
 d1c9bf6 journal: support replay passed skipped splay objects
 56100ef tests: verify that journal player can handle skipped journal objects
 1509ada mailmap: Jenkins affiliation
@@ -1980,7 +4251,7 @@ ef011da Update .organizationmap
 0fd8de3 msg/async: support of non-block connect in async messenger
 f7f55e3 scrub: compare omap_digest with each other
 785e58e scrub: clarify the result report
-a3aa565 (origin/wip-11287-rebased) journal: avoid holding lock while marking ops are complete
+a3aa565 journal: avoid holding lock while marking ops are complete
 4719696 cmake: updates for refactored librbd IO path
 10deea8 librbd: flush journal entries prior to releasing lock
 b515314 librbd: only erase IO events after they are marked safe
@@ -2103,7 +4374,7 @@ ae79f1d osd: update recovery stats when the recovery completes
 f7f5a08 internal: remove unused local variables
 c8fe5ae librados: cast oid to object explicitly before call ioctx methods Cast oid to object explicitly before call ioctx methods. Signed-off-by: xie xingguo <xie.xingguo at zte.com.cn>
 e986ade IoCtxImpl: remove unused variable sName
-a5651b8 (origin/revert-6419-wip-openssl) Revert 0374bb4a2f5054d606e4aba2d97b5e6765e781b0
+a5651b8 Revert 0374bb4a2f5054d606e4aba2d97b5e6765e781b0
 7496741 rgw: fix modification to index attrs when setting acls
 9689fe0 kv: fix string ctor usage
 bfeb90e librbd: fixed deadlock while attempting to flush AIO requests
@@ -2211,7 +4482,7 @@ da6825d test/test_rados_tool.sh: Add tests for the new bench's write options
 9259e6e tools/rados/rados.cc: Add options to choose the benchmark's write destination
 7524e16 tools/rados/rados.cc: Write to different destinations
 00c6fa9 Objecter: pool_op callback may hang forever.
-400b0f4 (origin/javacruft-wip-ec-modules) Build internal plugins and classes as modules
+400b0f4 Build internal plugins and classes as modules
 d457fc2 mds: apply validate_disk_state to dirs too
 6ba5bef mds: tidy up cdir scrub_initialize in scrubstack
 1930083 mds: write scrub tag during validation
@@ -2374,7 +4645,7 @@ ffd4f2a mailmap: Daniel Gryniewicz affiliation
 7b2e9fc ceph.in: Remove unused variable
 113d727 ceph.in: Don't drop out of command mode on certain kinds of errors
 bb5bcab makefile: For ceph command generation don't append another copy of ceph.in
-d4869a6 (origin/wip-13441) test: add test for pg list_missing on EC pool
+d4869a6 test: add test for pg list_missing on EC pool
 531dd77 osd: list_missing should query missing_loc.needs_recovery_map
 597c43e tracing: add tracepoints for cache pin/unpin
 4783899 osd: return ENOENT when object doesn't exist for cache pin/unpin
@@ -2477,7 +4748,7 @@ e26469e mailmap: Alexander Chuzhoy affiliation
 fee7144 rgw: fix response of delete expired objects
 2cf8d20 update radosgw-admin command
 4a3f375 vstart: set cephfs root uid/gid to caller
-7060a3b (origin/loic-infernalis) doc/infernalis: hate hate
+7060a3b doc/infernalis: hate hate
 e6a9e62 doc/release-notes: i hate rst
 e98408d doc/release-notes: final infernalis notes
 f6adeda rgw: more style fixes
@@ -2498,7 +4769,7 @@ b4c5620 doc: remove toctree items under Create CephFS
 65064ca OSD:shall reset primary and up_primary fields when beginning a new past_interval.
 8855e60 ReplicatedPG::maybe_handle_cache_detail: always populate missing_oid
 da4803e ReplicatedPG::_rollback_to: handle block on full correctly
-45870f0 (origin/wip-static-website) rgw: more style fixes
+45870f0 rgw: more style fixes
 43a568d rgw: style fixes
 34b90b0 minor fixes following rebase
 47d4266 Fixup.
@@ -2608,7 +4879,7 @@ d258bf5 ceph.spec.in: drop MY_CONF_OPTS
 e675400 librbd: invalidate object map on error even w/o holding lock
 bc48ef0 selinux: Fix man page location
 378d56d man/Makefile-server.am: conditionalize make ceph_selinux manpage
-fb50ff6 (origin/wip-13379) mon: do not remove proxied sessions
+fb50ff6 mon: do not remove proxied sessions
 0d1cab4 test: add TestSessionFilter
 be3c4a8 mds: implement filtered "session ls" tell command
 47a1816 mds: call through to MDSRank in handle_command
@@ -2775,7 +5046,7 @@ a965378 ReplicatedPG: clearing a whiteout should create the object
 47f4a03 ceph-objectstore-tool: delete ObjectStore::Sequencer after umount
 f20f67e pybind/cephfs: fix DirEntry helpers
 7b1882f ceph.spec.in: correctly declare systemd dependency for SLE/openSUSE
-3f00042 (origin/wip-13239-infernalis) rgw: set default value for env->get() call
+3f00042 rgw: set default value for env->get() call
 469d35f osd: init started to 0
 bba3ab3 mon: combine _ms_dispatch and dispatch
 612480b test/test_rados_tool.sh: implement regression test for bench verify crash
@@ -2811,7 +5082,7 @@ bf7e937 osdc/Objecter: set FULL_FORCE flag when honor_full is false
 95055e7 osd: add FULL_TRY and FULL_FORCE rados op flags
 7757342 qa: https://ceph.com/git -> https://git.ceph.com
 d4d65fb qa: http://ceph.com/qa -> http://download.ceph.com/qa
-cdccf11 (origin/wip-scrub-fix) osd/PG: compensate for sloppy hobject scrub bounds from hammer
+cdccf11 osd/PG: compensate for sloppy hobject scrub bounds from hammer
 acda626 osd: avoid duplicate MMonGetOSDMap requests
 f4bf14d Update Xinze affinity
 eb28eef Update Chen Min affinity
@@ -3006,7 +5277,7 @@ af39f98 .gitignore: ignore src/ceph.tmpe
 c57e868 rocksdb: ignore m4
 51abff1 ceph.spec: respect CEPH_EXTRA_CONFIGURE_ARGS
 4a5a5b3 qa/workunits/cephtool/test.sh: make mds epoch check more tolerant
-d33fea5 (origin/wip-10617-again) sd/PG: tolerate missing pgmeta object
+d33fea5 sd/PG: tolerate missing pgmeta object
 f15d958 osd: allow peek_map_epoch to return an error
 ff9600a osd/ReplicatedPG: remove stray debug line
 6e85433 AsyncMessenger: Kepp file_lock hold when accessing its event field
@@ -3096,8 +5367,8 @@ d5650c9 tests: new test case for librbd diff_iterate over discard extents
 d32a3be qa/workunits/rados/test_alloc_hint.sh: sudo to ls files
 ab4232b rgw: init_rados failed leads to repeated delete
 e48cec3 mon: disable gmt_hitset if not supported
-02f4461 (origin/wip-leveldb-hang) test: mon: mon-scrub.sh: test 'mon scrub'
-8c2dfad (origin/wonzhq-tmap-update) osd: force promote for ops which ec base pool can't handle
+02f4461 test: mon: mon-scrub.sh: test 'mon scrub'
+8c2dfad osd: force promote for ops which ec base pool can't handle
 8c4323c PerfCounter: Make l_os_queue_lat contains the complete queue latency
 834842c OSD: Add perf counter to count osd thread prepare latency
 70d3108 mon: MonitorDBStore: make get_next_key() work properly
@@ -3114,7 +5385,7 @@ e6fbe53 improve error handle of rbd metadata operation & format output
 bfe359a osd: dump full map bl at 20 when crc doesn't match
 351d957 doc: fix the typo in command example
 7080e0f Thread.h: disable copy constr and assignment op
-7d781f7 (origin/wip-12966) doc: 'ceph --admin-daemon ...' -> 'ceph daemon ...'
+7d781f7 doc: 'ceph --admin-daemon ...' -> 'ceph daemon ...'
 404dd16 tests: base gmock class support for librbd
 e8749b2 librbd: support templating of ImageCtx for async state machines
 1c522be ceph.spec.in: put distro conditional around Group:
@@ -3169,7 +5440,7 @@ af8b3da Messenger: Make fast dispatch message set dispatch timestamp
 929ca5b ceph.spec.in: drop lsb-release dependency from ceph-common
 557e581   mon/MonClient: fix error in 'ceph ping mon.id'   Fixes: #12442
 f65267c rgw : setting max number of buckets for users via ceph.conf option
-64962aa (origin/wip-5785) qa/workunits/rados/test_alloc_hint.sh: sudo to list files
+64962aa qa/workunits/rados/test_alloc_hint.sh: sudo to list files
 75d9f58 osd/ReplicatedPG: use apply_ctx_stats() everywhere
 eb2993a osd/ReplicatedPG: create apply_ctx_stats() helper
 9bf103c osd/ReplicatedPG: snaptimmer: adjust stats through ctx->delta_stats
@@ -3193,7 +5464,7 @@ c938d1f rocksdb: fix 32-bit build
 89aacaf doc: add the doc for min_write_recency_for_promote
 b02cc06 AsyncConnection: Don't use unsafe feature as message encode feature
 2a5d384 mds: add dump_blocked_ops asok command.
-7bfb7f9 (origin/wonzhq-rbd-write-full) librbd: do write_full for whole object write
+7bfb7f9 librbd: do write_full for whole object write
 cf4e8c6 osd: add dump_blocked_ops asok command.
 b199c49 ceph-osd-prestart.sh: fix osd data dir ownership check
 023c517 vstart.sh: enable all experimental features for vstart
@@ -3483,7 +5754,7 @@ f2f23c2 rgw: implement object_is_expired function.
 aa5f1b8 rgw: a few fixes, guard bufferlist decodes
 4f9a843 rgw: add basic support for X-Delete-At header of Swift API.
 2bc5a48 osd: Decode use_gmt_hitset with a unique version
-38465f0 (origin/liewegas-wip-hammer-feature) osd: refuse to boot if any pre-hammer or old hammer (<v0.94.4) are running
+38465f0 osd: refuse to boot if any pre-hammer or old hammer (<v0.94.4) are running
 f668c6c mon: use HAMMER_0_94_4 feature to require sufficiently new hammer
 470f970 include/ceph_features: define HAMMER_0_94_4 feature
 14e02bc PG::handle_advance_map: on_pool_change after handling the map change
@@ -3558,7 +5829,7 @@ b0882fb memstore: replace apply_lock with sequencer
 5d8307a memstore: add Object interface to hide bufferlist
 26f716e memstore: use intrusive_ptr instead of shared_ptr
 01a9a79 osbench: add multithreaded objectstore benchmark
-d7bf8cb (origin/wip-11455) rgw: init some manifest fields when handling explicit objs
+d7bf8cb rgw: init some manifest fields when handling explicit objs
 b610588 ceph.spec.in: remove obsolete SUSE-specific code
 df21a6e osd: expose PGLSFilter in objclass interface
 c318129 ceph.spec.in: Restart services only if they are running
@@ -3570,7 +5841,7 @@ fb1b6dd common: fix insert empty ptr when bufferlist rebuild
 347ac0f ceph_test_rados_api_tier: make PromoteOn2ndRead tolerate thrashing
 8a08acc common/hobject_t: fix is_temp() off-by-one
 7cc8d86 ceph_test_msgr: parse CEPH_ARGS
-dfd142f (origin/wip-memcpy) include/inline_memcpy: use __builtin_memcpy instead of explicit ptr copies
+dfd142f include/inline_memcpy: use __builtin_memcpy instead of explicit ptr copies
 98c0606 include/inline_memcpy: make prototype resemble memcpy's
 fc02a8a added boost timegm impl for cross platform support
 da6d5cf osd: bug fix hit_set_map size for tier pool
@@ -3662,7 +5933,7 @@ ea8609b mon/OSDMonitor: debug why pool creation fails
 88bfd79 test/erasure-code: drop directory from profile
 5df1271 do not include directory in ec profiles
 660ae5b osd: always load erasure plugins from the configured directory
-7295612 (tag: v9.0.3, origin/loic-v9.0.3, origin/last) 9.0.3
+7295612 (tag: v9.0.3) 9.0.3
 271513f erasure-code: shec plugin feature
 5e99a57 mon: add a cache layer over MonitorDBStore
 2d13a47 rbd: fix the FTBFS on old boost introduced by 2050d08
@@ -3807,7 +6078,7 @@ c8a83cd client: track flush TIDs for all pending flushing caps
 d742e79 tests: Add unit tests for CLS numops class
 d17f158 cls_numops: Add cls_numops client
 87f6b73 Add new cls_numops class for numeric operations
-0ba2e14 (origin/revert-4927-snapset-obc) Revert "osd/ReplicatedPG: snapset is not persisted"
+0ba2e14 Revert "osd/ReplicatedPG: snapset is not persisted"
 b18558b osd/OSDMap: test_flag returns bool
 3540fb9 osdc/Objecter: restart listing this PG if sort order changes
 35c1970 osd/ReplicatedPG: fix missing set sort order on [N]PGLS
@@ -3850,7 +6121,7 @@ d33ad15 Adding statfs api to KeyValueDB
 d57d36d osd: add flush/evict mode in pg stats
 af2a38b mon: fix the output of cache_io_rate_summary
 b78883b tests: be more generous with mon tests timeouts
-7e6f819 (origin/wip-5072) doc: update rgw configuration on multiple rgw rados handlers feature
+7e6f819 doc: update rgw configuration on multiple rgw rados handlers feature
 efc8969 Doc: Correcting the default number of copies.
 6f768a7 doc: Removed reference to RAID-4
 c6cf558 CMake: cut down unnecessary linkage on rados tests
@@ -4044,7 +6315,7 @@ f68553e osd/osd_types.cc: get rid of str concat when making hash key
 111ecf8 radosgw-admin: use cout not cerr to print help message.
 145364b logrotate: fix log rotation with systemd
 85cb86d doc: change "--keyfile" description in man page of rbd help
-1ca6bf6 (origin/wip-12536) common/hobject_t: correctly decode pre-infernalis hobject_t min
+1ca6bf6 common/hobject_t: correctly decode pre-infernalis hobject_t min
 bc0d942 CMake: add crushtool
 fe970bc CMake: fix librados build
 2355c45 CMake: fix rbd build
@@ -4128,7 +6399,7 @@ cb51b17 mon: reject over-large values of max_mds
 258cb34 rbd: add "--keyring" option to help message
 5c395ff doc: add bucket object version description. bucket object version has been supported, but do not have description in the docs, so add this part.
 6ab9efe osd: copy the RecoveryCtx::handle when creating a new RecoveryCtx instance from another one
-1320e29 (origin/wip-12410) OSDMonitor::preprocess_get_osdmap: send the last map as well
+1320e29 OSDMonitor::preprocess_get_osdmap: send the last map as well
 f217865 test_librbd_fsx: invalidate before discard in krbd mode
 c4872dd Log::reopen_log_file: take m_flush_mutex
 0559fd3 tools/rados: change the first op id to 0
@@ -4179,7 +6450,7 @@ bbc5c71 rbd: import doesn't require image-spec arg, ditto for export and path
 0d2467a Compressor: Remove thread affinity options
 3482e68 AsyncConnection: Exit process loop if entering fault
 554c982 test/perf_local: disable tests on unsupported archs
-8778ab3 (origin/wip-12465) Log::reopen_log_file: take m_flush_mutex
+8778ab3 Log::reopen_log_file: take m_flush_mutex
 6f54c61 debian: Update maintainers and uploaders
 824c541   common: add nested-name-specifier ThreadPool before WorkQueueVal   Fixes: #12459
 992d959 mds: fix val used in inode->last_journaled
@@ -4750,7 +7021,7 @@ adfa2e0 librbd: flush operations need to acquire owner lock
 d3bd27f rgw: fix reset_loc()
 9298f93 mon/OSDMonitor: fix get_bucket_utilization return value
 e41d97c rgw: fix assignment of copy obj attributes
-4030774 (origin/wip-12064) mon: only send MMonMetadata to peer mons that support it
+4030774 mon: only send MMonMetadata to peer mons that support it
 54a516f configure.ac: Fix JUnit 4 detection on Fedora 22.
 7fbac49 doc: Change the type of list in doc Fixes: #12061. Signed-off-by: Maxime ROBERT <maxime.robert1992 at gmail.com>
 05c56b7 doc: ceph-deploy man page: typo #12063 Replace is initial monitor hostname with is the initial monitor hostname Fixes : #12063 Signed-off-by: CARADANT Kevin <kevin.caradant at gmail.com>
@@ -5090,7 +7361,7 @@ aa62dcb osdmaptool: dump 'osd tree' in specified format
 acdfd98 doc: fix typo in placement-groups.rst
 9c8f8d2 doc: fix a wrong quote in release.rst
 2cc7aee mon: MonitorDBStore: get_next_key() only if prefix matches
-2934909 (origin/wip-mon-scrub) mon: Monitor: allow updating scrub interval on demand
+2934909 mon: Monitor: allow updating scrub interval on demand
 e77b3f4 mon: Monitor: allow scrub to timeout after a while
 80ce9b0 mon: Monitor: inject missing key failures during scrub
 ba4a2c1 mon: Monitor: inject scrub failures
@@ -5226,7 +7497,7 @@ f11de85 mds: fix handle_mds_map in standby_replay
 c199b7b KeyValueStore: Initialize the iterator
 ab30ff2 KeyValueStore: optimize the object header writes
 a46b333 do not return non-exist extents when doing sparse read
-389ae67 (origin/wip-11622) rgw: merge manifests correctly when there's prefix override
+389ae67 rgw: merge manifests correctly when there's prefix override
 9d8c115 init-radosgw.sysv: remove
 1c45f51 init-radosgw: unify init-radosgw[.sysv]
 a4bb992 init-radosgw: look in /var/lib/ceph/radosgw
@@ -5361,7 +7632,7 @@ e9300cb mailmap: Sergey Arkhipov affiliation
 f76bf6c mailmap: Xingyi Wu affiliation
 0f44127 mailmap: Ning Yao affiliation
 95a881f mailmap: Joao Eduardo Luis affiliation
-2738d02 (origin/wip-txn-noappend-sam-rebased) ECBackend: eliminate transaction append, ECSubWrite copy
+2738d02 ECBackend: eliminate transaction append, ECSubWrite copy
 3699a73 mon: fix the FTBFS
 07cf4f7 doc: release notes for hammer v0.94.2
 e1f1c56 mon/PGMap: add more constness
@@ -5513,7 +7784,7 @@ a0f96de mds: in damaged() call flush_log before ending
 8803776 mon: add MonClient::flush_log
 a5e88fc librbd: invoking RBD::open twice will leak memory
 585bc2b mds: send FLUSHSNAP_ACK even if FLUSHSNAP message is unexpected
-fbfd50d (origin/wip-11429) OSD: handle the case where we resurrected an old, deleted pg
+fbfd50d OSD: handle the case where we resurrected an old, deleted pg
 32b8bf5 test: update CMakefile to sync with c44f8e7
 b7f4328 systest_runnable: adjust argument to suite Preforker
 9699246 mds: handle missing mydir dirfrag
@@ -5564,7 +7835,7 @@ d62f80d common/config: detect overflow of int values
 ab51130 Event: Delete driver after cleanup
 caa9f0e rgw: fix ListParts response
 04b0002 qa/workunits/post-file: pick a dir that's readable by world
-999dcc8 (origin/wip-11464) Revert "osd: For object op, first check object whether unfound."
+999dcc8 Revert "osd: For object op, first check object whether unfound."
 8e20240 librbd: TaskFinisher should finish all queued tasks
 ea5107c librbd: librados completions are not properly released
 ed5472a tests: fix valgrind errors with librbd unit test
@@ -5586,7 +7857,7 @@ fd7723a librbd: update ref count when queueing AioCompletion
 f141e02 librbd: flatten should return -EROFS if image is read-only
 594a661 librbd: allow snapshots to be created when snapshot is active
 32c41f8 cls_rbd: get_features needs to support legacy negative tests
-e97fd50 (origin/wip-rgw-content-length) rgw: simplify content length handling
+e97fd50 rgw: simplify content length handling
 79d17af rgw: make compatability deconfliction optional.
 06d67d9 rgw_admin: add --remove-bad flag to bucket check
 8a7e58e AsyncMessenger: Don't need to join thread if not started
@@ -5838,7 +8109,7 @@ e3d62a9 common: make rados bench return correctly errno.
 0498b6a mds: add perf counters descriptions
 8ff8c57 doc/release-notes: note about SHEC
 1cc0181 doc: Corrects rgw.conf file path for Debian-based and RPM-based distros in radosgw man page.
-fb51175 (origin/wip-2862) TestCase: Change in testcase output
+fb51175 TestCase: Change in testcase output
 b15f6d0  Fix to some of the command line parsing (including rbd)
 b0172d8 rbd: create command throws inappropriate error messages
 d1cb94f RBD: update expunge set for latest test, parameterize test script
@@ -6018,7 +8289,7 @@ c4d8e65 Librbd: Add existing rbd configs to aware table
 cf715bd Librbd: Add tests for aware metadata config
 ccdeaf8 mds: fix out-of-order messages
 364e15b Librbd: Add basic metadata aware method
-59aa670 (origin/zhouyuan/isal_2.13) erasure-code: Update ISA-L to 2.13
+59aa670 erasure-code: Update ISA-L to 2.13
 ad15f7d osdc/Striper.cc fix stripe_count == 1 && stripe_unit != object_size
 eaf6e0c Always provide summary for non-healthy cluster.
 c6f1c07 Conditional-compile against minimal tcmalloc.
@@ -6044,7 +8315,7 @@ f9b98c9 ceph-objectstore-tool: Fix message and make it debug only to stderr
 d6acc6a Doc: Incomplete example in erasure-coded-pool.rst
 90c38b5 rocksdb: fix 32-bit build
 ddad2d4 Makefile-rocksdb.am: update for latest rocks
-c176ebf (origin/wip-move-code) osd/: Move ReplicatedBackend methods into ReplicatedBackend.cc
+c176ebf osd/: Move ReplicatedBackend methods into ReplicatedBackend.cc
 e9d6096 ReplicatedPG: remove unused C_OnPushCommit
 6413209 mds: include damaged in MDSMap::dump
 3b2a091 mds: update peer failure response to account for damaged
@@ -6306,7 +8577,7 @@ d9ea168 Some sanitization work on .mailmap, .organizationmap, .peoplemap : Sorti
 90a0393 PendingReleaseNotes: warn about lttng LD_PRELOAD for daemons
 53cc492 ceph_test_rados_tier: add test case for delete+create compound ops
 c0e6227 mds: give up replicas of a stopping mds's stuff
-d47e622 (origin/wip-mon-doc) doc/rados/operations/add-or-rm-mons: revise doc a bit to be less confusing
+d47e622 doc/rados/operations/add-or-rm-mons: revise doc a bit to be less confusing
 8a05092 debian: move /var/lib/ceph/mds to ceph-mds package
 353a325 ceph.spec.in: rm EOL Fedoras; add OBS RHEL5 instead
 703ba37 librbd: acquire cache_lock before refreshing parent
@@ -6989,7 +9260,7 @@ adebf22 rbd_recover_tool: move rbd_recover_tool directory to src/tools subdirect
 2f49de5 ReplicatedPG: block writes on degraded objects unless all peers support it
 2a83ef3 include/encoding: fix an compile warning
 71c6d98 msg: fixup for 2ffacbe (crc configuration in messenger)
-2598fc5 (origin/wip-10734) ObjectStore: fix Transaction encoding version number
+2598fc5 ObjectStore: fix Transaction encoding version number
 46f9ca4 pybind: fixed runtime errors with librbdpy
 9124a76 test/vstart_wrapper.sh: set PATH before calling vstart.sh
 189ef38 init-ceph.in: add $PWD to PATH if running as ./init-ceph
@@ -7068,13 +9339,13 @@ e0f12d9 Fix do_autogen.sh so that -L is allowed
 cfab01e rgw: move perf cleanup before context cleanup
 4074a91 pybind: fix error hiding and inconsistency on librados load.
 cfcfafc Objecter::_op_submit_with_budget: add timeout before call
-00a3ac3 (tag: v0.92, origin/wip-sam-v0.92) 0.92
+00a3ac3 (tag: v0.92) 0.92
 c656bce PGLog: improve PGLog::check() debugging
 05ce2aa qa: use correct binary path on rpm-based systems
 eb526af rbd: watch command should unwatch before exiting
 2a0e9b7 encoding: ignore uninitialized instantiation in boost::optional decode
 f40ee8c do_autogen.sh: default to --with-lttng, -L to build without
-7590387 (origin/wip-assert-version) librados: add missing tracepoints
+7590387 librados: add missing tracepoints
 57bac8e osd:  change pg_stat plain to display CRUSH_ITEM_NONE in pgmap output section.
 4aa9f3f man: add rbd status to doc/man/8/rbd.rst
 a007c52 doc: add cephfs disaster recovery guidance
@@ -7138,7 +9409,7 @@ fc76c89 osdc: add new filed dontneed in BufferHead.
 c83a288 Rework ceph-disk to allow LUKS for encrypted partitions
 707c78b Only create a key of 256 bits length, not 256 bytes
 6a45b8e add all possible ceph-disk run-time requirements to build time deps
-4c50f6a (origin/wip-rgw-versioning-4) rgw: more merge related fixes
+4c50f6a rgw: more merge related fixes
 01cc9d5 rgw: fix merge artifact
 e26023e PG: set scrubber.start = scrubber.end after scrub_compare_maps
 4f9e6ed PG: remove block_writes from scrubber
@@ -7195,7 +9466,7 @@ c4a6eab rgw: fixing rebase casualties
 b6d6f90 mon/MDSMonitor: fix gid/rank/state parsing
 9b9a682 msg/Pipe: set dscp as CS6 for heartbeat socket
 1e236a3 mds: don't join on thread which has not been runned.
-6939e8c (origin/zhouyuan-submodule_https_git) Update git submodule to use the same https protocol
+6939e8c Update git submodule to use the same https protocol
 e393810 librbd: make librbd cache send read op with fadvise_flags.
 a23676b librbd: Don't do readahead for random read.
 8d0295c rgw: extend replica log api (purge-all)
@@ -7233,7 +9504,7 @@ e6f1280 librados: Expose RadosClient instance id through librados
 87ef462 rgw: format mtime of radosgw-admin bucket stats
 dc1630e librbd: trim would not complete if exclusive lock is lost
 3347e0d bug: error when installing ceph dependencies with install-deps.sh
-4e90a31 (origin/wip-10617) osd: add failure injection on pg removals
+4e90a31 osd: add failure injection on pg removals
 9b220bd ceph.spec.in: use wildcards to capture man pages
 51e3ffa rgw: reorder bucket cleanup on bucket overwrite
 313d6a5 rgw: access appropriate shard on bi_get(), bi_put()
@@ -7297,7 +9568,7 @@ b04f698 Doc: Fix the extra blank space in doc/start/quick-rbd.rst
 9ad9ba8 doc: Fix a typo in radosgw-admin doc
 008698b doc: Change Availability text in all of the man pages
 6f44f7a Revert "Revert "Merge remote-tracking branch 'origin/wip-bi-sharding-3' into next""
-90a90bb (origin/wip-rgw-versioning-3) rgw: set default value for swift versioning extension
+90a90bb rgw: set default value for swift versioning extension
 dc11ef1 PGBackend: fix and clarify be_select_auth_object
 26656e3 rgw: fix bucket removal with data purge
 b18b14b ObjectStore::_update_op: treat CLONERANGE2 like CLONE
@@ -7548,7 +9819,7 @@ b383b52 rgw: enable s3 get/set versioning ops
 0d97b40 rgw: get bucket versioning status op
 8ed79d6 rgw: add versioning_enabled field to bucket info
 50547dc mon: PGMonitor: fix division by zero on stats dump
-dbaa142 (origin/wip-bi-sharding-3) rgw: bilog marker related fixes
+dbaa142 rgw: bilog marker related fixes
 c4548f6 pybind: ceph_argparse: validate incorrectly formed targets
 80a9d99 mon: Monitor: return 'required_features' on get_required_features()
 ab996c1 mon: Elector: output features in handle_propose()
@@ -7652,7 +9923,7 @@ d80ded9 mailmap: David Zhang affiliation
 33ba23f common/shared_cache.hpp: empty() iff weak_refs is empty
 d532f3e remove unused hold_map_lock in _open_lock_pg
 9748655 man: add help for rbd merge-diff command
-6986ec1 (origin/wip-10477) osd/PG: populate blocked_by with peers we are trying to activate
+6986ec1 osd/PG: populate blocked_by with peers we are trying to activate
 5b0e8ae mailmap: Yehuda Sadeh name normalization
 3f03a7b doc/release-notes: v0.91
 4ca6931 doc/release-notes: typo
@@ -7741,7 +10012,7 @@ f9b280e Adjust bi log listing to work with multiple bucket shards. Signed-off-by
 67a90dd mon: accumulate a single pending transaction and propose it all at once
 d159586 PendingReleaseNotes: make a note about librados flag changes
 725d660 (tag: v0.91) 0.91
-9264d25 (origin/wip-formatter) common/Formatter: new_formatter -> Formatter::create
+9264d25 common/Formatter: new_formatter -> Formatter::create
 617ad5d common/Formatter: improve json-pretty whitespace
 83c3b13 common/Formatter: add newline to flushed output if m_pretty
 e2a7b17 osd/PG: remove unnecessary publish_stats_to_osd() in all_activated_and_committted()
@@ -8047,7 +10318,7 @@ a302c44 ceph-disk: Fix wrong string formatting
 9783a5c test/msgr/test_msgr: Fix potential unsafe cond wakeup and wrap check
 bba4d35 librados: init last_objver
 2cd9dc0 messages/MClientCaps: init peer.flags
-679652a (origin/wip-osdmap-leak) osd: fix leaked OSDMap
+679652a osd: fix leaked OSDMap
 18f545b librados: Avoid copy data from librados to caller buff when using rados_read_op_read.
 001ea29 Messenger: Create an Messenger implementation by name.
 3a2cb71 mds: fix asok on rank 0
@@ -8257,7 +10528,7 @@ b34e545 os/FileStore.cc: insert not empty list<Context*> to op_finisher/ondisk_f
 7ab4a39 ceph.conf: update sample
 efd9d8d tests: Minor cleanup to librbd test
 78a15ee Fix libstriprados::remove, use strtoll insdead of strtol
-2d4dca7 (origin/wip-10029) SimpleMessenger: Retry binding on addresses if binding fails
+2d4dca7 SimpleMessenger: Retry binding on addresses if binding fails
 e8063a1 test: modify cephfs quota test case
 31a0cdc mds: fix parse_quota_vxattr for invalid data
 bab7122 OSD: FileJournal: call writeq_cond.Signal if necessary in submit_entry
@@ -8266,7 +10537,7 @@ bab7122 OSD: FileJournal: call writeq_cond.Signal if necessary in submit_entry
 6b51a9f mds: set dirfrag version when fetching dirfrag is skipped
 17c72f5 ceph-osd: remove extra close of stderr
 5836899 Revert "client: support listxattr for quota attributes"
-89b2fee (origin/wip-crush-straw) mon: 'osd crush reweight-all'
+89b2fee mon: 'osd crush reweight-all'
 dd7b58f crush: set straw_calc_version=1 for default+optimal; do not touch for presets
 adf5c6d crush/builder: a note about the original crush_calc_straw()
 9000068 mon: add 'osd crush {get,set}-tunable <name> [value]' commands
@@ -8275,7 +10546,7 @@ bf0d8d3 osd: Remove dead code related to old pg removal mechanism
 0827bb7 client: use remount to trim kernel dcache
 dfcb1c9 client: cleanup client callback registration
 2f52202 Revert "client: invalidate kernel dentries one by one"
-9902383 (origin/wip-9998) crush/CrushWrapper: fix create_or_move_item when name exists but item does not
+9902383 crush/CrushWrapper: fix create_or_move_item when name exists but item does not
 8c87e95 crush/builder: prevent bucket weight underflow on item removal
 eeadd60 crush/CrushWrapper: fix _search_item_exists
 a198dee Modifying the docs to add the Get pool commands to match the CLI. Signed-off-by: Chris Holcombe <chris.holcombe at nebula.com>
@@ -8466,7 +10737,7 @@ b8f6b5f doc: Added rbd-replay-many and restructured index.
 6862891 doc: Adds man page for ceph disk in TOC.
 491da51 client: invalidate kernel dentries one by one
 2fa4884 mds: fix race of trimming log segments
-70e1a5d (origin/wip-doc-rbd-replay) doc: Document RBD Replay
+70e1a5d doc: Document RBD Replay
 131f092 mds: don't blindly create empty object when dirfrag is missing
 9b9e3ed mds: allow choosing action for wirte error
 dafef3c mds: add asok command to force MDS readonly
@@ -8479,7 +10750,7 @@ cfef515 mds: disallow slave requests when MDS is readonly
 4aed047 mds: keep locks in sync state when MDS is readonly
 2d4a746 mds: don't trim log when MDS is readonly
 4f6474f mds: disallow write operations when MDS is readonly
-01df222 (origin/wip-10209) osd: tolerate sessionless con in fast dispatch path
+01df222 osd: tolerate sessionless con in fast dispatch path
 0f1c9fd msg: do not const methods that return a mutable pointer
 0d6c803 osd/osd_types: drop category from object_info_t
 5ecdce3 osdc/Objecter: drop category from copy-get
@@ -8840,7 +11111,7 @@ fe7bf06 rgw: RGWRados::get_obj() returns wrong len if len == 0
 f4ee949 osd: cache pool: flush object ignoring cache min flush age when cache pool is full Signed-off-by: Xinze Chi <xmdxcxz at gmail.com>
 6da9405 doc: Edited Key/Value store config reference.
 03be944 doc: Added Key/Value store config reference to index.
-72fc262 (origin/wip-doc-openstack-juno) doc: Update for OpenStack Juno.
+72fc262 doc: Update for OpenStack Juno.
 65c3350 tools: skip up to expire_pos in journal-tool
 e0166a2 osdc/Objecter: Fix a bug of dead looping in Objecter::handle_osd_map
 31c584c osdc/Objecter: e shouldn't be zero in Objecter::handle_osd_map
@@ -9104,7 +11375,7 @@ c9f9e72 Revert "Objecter: disable fast dispatch of CEPH_MSG_OSD_OPREPLY messages
 c4bac3e mds: fix inotable initialization/reset
 c95bb59 mds: fix inotable initialization/reset
 f1fccb1 rpm: 95-ceph-osd-alt.rules is not needed for centos7 / rhel7
-b73fe1a (origin/wip-9730) doc: remove node requirement from 'mon create-initial'
+b73fe1a doc: remove node requirement from 'mon create-initial'
 264f0fc doc: remove whitespace
 20b2766 Update vstart to setup users for s3-tests
 0969945 client: use finisher to abort MDS request
@@ -9121,7 +11392,7 @@ d947050 osd/osd_types: consider CRUSH_ITEM_NONE in check_new_interval() min_size
 50987ec libcephfs.h libcephfs.cc : Defined error codes for the mount function Used new error codes from libcephfs.h to replace the magic numbers in the mount functon found in libcephfs.cc.
 7bab093 return value of handle_message for MSG_OSD_SUBOP/MSG_OSD_SUBOPREPLY should be true
 d955676 rados: Use strict_strtoll instead of strtoll
-809ddd2 (origin/wip-9706) osdc/Objecter: fix use-after-frees in close_session, shutdown
+809ddd2 osdc/Objecter: fix use-after-frees in close_session, shutdown
 72a2ab1 osdc/Objecter: fix tick() session locking
 d98b755 librados: Fix function prototypes in librados.h
 d458b4f PGLog::IndexedLog::trim(): rollback_info_trimmed_to_riter may be log.rend()
@@ -9257,7 +11528,7 @@ b2e4bd5 msg: move SimpleMessenger to msg/simple/
 5eff0ee msg: use localized cct for derr
 06aef6f doc/release-notes: v0.86
 10fe7cf ceph_objectstore_tool: Accept CEPH_ARGS environment arguments
-6aba0ab (origin/wip-9128) Add reset_tp_timeout in long loop in add_source_info for suicide timeout
+6aba0ab Add reset_tp_timeout in long loop in add_source_info for suicide timeout
 52ac520 tools: remove old ceph.cc
 63c7e16 test/osd/Object: don't generate length of 0
 abe4c35 doc: update kernel recommendations, add tunables link
@@ -9402,7 +11673,7 @@ ed77178 erasure-code: run isa tests via libtool and valgrind
 6886224 mailmap: Yan Zheng affiliation
 fc1380b mailmap: Thorsten Glaser affiliation
 7973280 osd: Remove unused PG functions queue_notify(), queue_info(), queue_log()
-0f884fd (origin/wip-9008) For pgls OP, get/put budget on per list session basis, instead of per OP basis, which could lead to deadlock.
+0f884fd For pgls OP, get/put budget on per list session basis, instead of per OP basis, which could lead to deadlock.
 7f87cf1 ReplicatedPG: clean out completed trimmed objects as we go
 2cd9b5f tests: use memcmp to compare binary buffers
 c17ac03 ReplicatedPG: don't move on to the next snap immediately
@@ -9529,7 +11800,7 @@ bb49547 KeyValueStore: Reduce redundancy set_header call
 baf7be9 osdc/Objecter: cancel timeout before clearing op->session
 1149639 ceph-disk: mount xfs with inode64 by default
 ded1b30 erasure-code: preload fails if < 0
-27208db (origin/wip-doc-preflight) doc: Added feedback.
+27208db doc: Added feedback.
 a140439 mds: limit number of caps inspected in caps_tick
 bf590f8 mds: keep per-client revoking caps list
 a6a0fd8 xlist: implement copy constructor
@@ -9703,7 +11974,7 @@ a754ce5 ErasureCodeLrc.cc: fix -Wmaybe-uninitialized compiler warning
 16cbaba osd/PGLog.h: prefer ++operator for non-primitive iterators
 8f368c5 mailmap: Ashish Chandra affiliation
 5fd50c9 mailmap: Boris Ranto affiliation
-a5b4c58 (origin/wip-9309) lockdep: increase max locks (1000 -> 2000)
+a5b4c58 lockdep: increase max locks (1000 -> 2000)
 9fac072 documentation: add the mark_unfound_lost delete option
 bec3032 osd: MissingLoc::get_all_missing is const
 e13ddc7 tests: qa/workunits/cephtool/test.sh early fail
@@ -10016,7 +12287,7 @@ f7c0001 common: remove spurious uint32_t in buffer.c
 b0cc869 mds: rename a bunch of metrics
 31ef1a9 mds: set l_mds_req on client request
 06682c4 vstart.sh: debug rgw = 20 on -d
-00c677b (origin/wip-civetweb-log) rgw: use a separate callback for civetweb access log
+00c677b rgw: use a separate callback for civetweb access log
 850242c rgw: separate civetweb log from rgw log
 f246b56 common/shared_cache: dump weak refs on shutdown
 6cf583c common/shared_cache: take a cct
@@ -10188,7 +12459,7 @@ dd11042 os/FileStore: fix mount/remount force_sync race
 c83c90c rgw: update civetweb submodule
 0d6d1aa init-ceph: don't use bashism
 7df67a5 Fix -Wno-format and -Werror=format-security options clash
-ae0b9f1 (origin/wip-osd-mon-feature) osd: fix feature requirement for mons
+ae0b9f1 osd: fix feature requirement for mons
 0db3e51 ReplicatedPG::maybe_handle_cache: do not forward RWORDERED reads
 5040413 ReplicatedPG::cancel_copy: clear cop->obc
 2f0e295 unittest_osdmap: test EC rule and pool features
@@ -10218,7 +12489,7 @@ a1e79db rgw_admin: add --min-rewrite-stripe-size for object rewrite
 46d8c97 doc: Add documentation about Wireshark dissector.
 6a55543 rgw: fix compilation
 f6771f2 shared_cache: use a single lookup for lookup() too
-cec40da (origin/historic/old-wireshark-dissectors) qa/workunits/cephtool: verify setmaxosd doesn't let you clobber osds
+cec40da qa/workunits/cephtool: verify setmaxosd doesn't let you clobber osds
 a1c3afb OSDMonitor: Do not allow OSD removal using setmaxosd
 16a4360 rgw: pass set_mtime to copy_obj_data()
 800eff2 rgw: copy_obj_data() uses atomic processor
@@ -10550,7 +12821,7 @@ eb697dd librbd: make rbd_get_parent_info() accept NULL out params
 04d0526 PGMonitor: fix bug in caculating pool avail space
 b08470f configure.ac: link libboost_thread only with json-spirit
 9d23cc6 configure: don't link blkid, udev to everything
-de9cfca (origin/wip-flush-set) Only write bufferhead when it's dirty
+de9cfca Only write bufferhead when it's dirty
 1c26266 ObjectCacher: fix bh_{add,remove} dirty_or_tx_bh accounting
 727ac1d ObjectCacher: fix dirty_or_tx_bh logic in bh_set_state()
 5283cfe Wait tx state buffer in flush_set
@@ -10822,7 +13093,7 @@ c0ffa01 mon: Set crash_replay_interval automatically
 917ef15 test: use 0U with gtest to avoid spurious warnings
 522174b qa: support running under non privileged user
 8697d6a OSD: await_reserved_maps() prior to calling mark_down
-6f97206 (origin/wip-osd-map-cache-size) osd: allow osd map cache size to be adjusted at runtime
+6f97206 osd: allow osd map cache size to be adjusted at runtime
 bcc09f9 qa/workunits/cephtool/test.sh: sudo ceph daemon
 959f2b2 PGLog: fix clear() to avoid the IndexLog::zero() asserts
 e0d3b78 rgw: fix uninit ofs in RGWObjManifect::obj_iterator
@@ -11599,7 +13870,7 @@ e97b56e doc: New Admin Guide for Ceph Object Storage.
 24c5ea8 osd: check blacklisted clients in ReplicatedPG::do_op()
 f92677c osd: check blacklisted clients in ReplicatedPG::do_op()
 c64b67b ceph-object-corpus: rebase onto firefly corpus
-077e6f86 ceph-object-corpus: v0.80-rc1-35-g4812150
+077e6f8 ceph-object-corpus: v0.80-rc1-35-g4812150
 8bd4e58 Fix out of source builds
 3aee1e0 Fix clone problem
 fd970bb mon: OSDMonitor: disallow nonsensical cache-mode transitions
@@ -13823,7 +16094,7 @@ c7d8ba7 osd: better performances for the erasure code example
 ff9455b osd: conditionally disable dlclose of erasure code plugins
 8879e43 osd: Fix assert which doesn't apply when compat_mode on
 0bd5cb6 Add backward comptible acting set until all OSDs updated
-8d31f71b osd/ReplicatedPG: fix promote cancellation
+8d31f71 osd/ReplicatedPG: fix promote cancellation
 923bff1 osd/ReplicatedPG: drop RepGather::ondone callback
 2a9c6fc vstart.sh: go faster
 bc893f5 osd/ReplicatedPG: fix undirty on clean object
@@ -13920,7 +16191,7 @@ ebb3ad9 osd/PG: move some pg stat update into a helper
 05274f3 osd: include peer_info in pg query
 5fdcc56 mds: fix bug in MDCache::open_ino_finish
 71d1eb3 mds: add CEPH_FEATURE_EXPORT_PEER and bump the protocal version
-d0b744a1 client: handle session flush message
+d0b744a client: handle session flush message
 05b192f mds: simplify how to export non-auth caps
 9dc52ff mds: send cap import messages to clients after importing subtree succeeds
 6a56588 mds: re-send cap exports in resolve message.
@@ -14064,7 +16335,7 @@ a888a57 crush: implement --show-bad-mappings for indep
 fbc4f99 crush: remove scary message string
 472f495 crush: document the --test mode of operations
 ea86444 Monitor: Elector: share the classic command set if we have a classic mon
-f1ccdb41 Elector: share local command set when deferring
+f1ccdb4 Elector: share local command set when deferring
 ba673be Monitor: import MonCommands.h from original Dumpling and expose it
 3cb58f7 Monitor: validate incoming commands against the leader's set too
 cb51b1e Monitor: disseminate leader's command set instead of our own
@@ -16755,7 +19026,7 @@ c112fc8 mon: add is_shutdown() state helper/accessor
 652c599 mon: shut down Paxos on shutdown
 6630462 osd: break con <-> session cycle on reset
 99172c3 osd: do not leak HeartbeatSession on shutdown
-449bcd6f osd: close classes on shutdown
+449bcd6 osd: close classes on shutdown
 b56c965 osd: do not leak MOSDPings on shutdown
 d172c33 osd/ReplicatedPG: don't leak Session refs in do_osd_op_effects()
 cd1c289 messages/MMonSync: initialize crc in ctor
@@ -24497,7 +26768,7 @@ a53a017 ReplicatedPG: pull() should return PULL_NONE, not false
 f9b7529 osd_types.h: Add constructors for ObjectRecovery*
 7b1c144 test_filestore_idempotent: fix test to create initial object
 6b30cd3 libcephfs: define CEPH_SETATTR_*
-b54bac30 test/encoding/readable.sh: drop bashisms
+b54bac3 test/encoding/readable.sh: drop bashisms
 ffa1de3 filejournal: drop unused variable
 ccf8867 filejournal: aio off by default
 9fded38 test/encoding/readable.sh: skip old version with known incompatibilities
@@ -27465,7 +29736,7 @@ f1f75df ceph_argparse_witharg: fix dashes in args
 4549501 common/Throttle: Remove unused return type on Throttle::get()
 c23d4c2 libceph: delogbalize, again
 92a3a47 Makefile: add missing common/dout.h header to dist tarball
-5da06628 librados: fix end_block calculation for aio_read
+5da0662 librados: fix end_block calculation for aio_read
 823a05c proflogger: only register one event for all loggers
 629ac0d librados: deglobalize, again
 9a3a685 OSDMap: kill some deadcode, deglobalize
@@ -31464,7 +33735,7 @@ b01cc38 rgw: set default log level to 20
 6bd40ac qa: consistent snaptest-%d.sh naming
 9127cd9 mds: fix uninitialized LeaseStat for null lease
 5c714bf osd: log when we get marked down but aren't
-7fbe1655 debug: no name symlink when explicit --log-file
+7fbe165 debug: no name symlink when explicit --log-file
 3de9c8d client: some whitespace cleanup
 8195899 qa: add localized version of Thomas Mueller's snaptest-2.sh
 2d35d24 rgw: exit after 5 seconds from SIGUSR1 anyway
@@ -33058,7 +35329,7 @@ ba515fe mkcephfs: generate cephx keys during mkfs
 329178d mount: set flags when getting -o sync
 6ea3030 mds: fix dumpcache
 6285b61 authtool: only create keyring if --create-keyring (or -c)
-f40957eb config: rename 'keys file' to 'keyring'
+f40957e config: rename 'keys file' to 'keyring'
 3ebf9a4 filestore: optionally checkpoint with snaps
 5bdb348 journal: make sure max_size is multiple of block_size
 54898b3 mds: print setattr'd values with MClientRequest
@@ -33303,7 +35574,7 @@ e439bd3 config: add kill arguments for mds import/export
 b709a72 mds: bracket mds journal events with {start,submit}_entry
 95ee211 todo
 adbd7d8 dropped old aleung mds branch code
-714a9af (origin/historic/aleung_mds_security) mon: fix allocation of low global_ids after mon restart
+714a9af mon: fix allocation of low global_ids after mon restart
 89603b6 test_ioctls: print preferred_osd value from GET_LAYOUT ioctl
 54b8537 hash: fix whitespace
 fd0195a mds: set mdr->in[n] in rdlock_path_xlock_dentry
@@ -33568,7 +35839,7 @@ e97c152 auth: fix verify_authorize_reply stupid
 08fbca8 auth: simplify challenge key encoding
 05e198b buffer: make [], hexdump const
 6133f02 auth: break client/server challenge calc into helper
-9ea4e4a5 auth: CEPH_AUTH_NONE auth and caps working
+9ea4e4a auth: CEPH_AUTH_NONE auth and caps working
 e98eb90 auth: return correct auth type
 8de5de0 auth: auth-none protocol stubs
 0717270 auth: redefine CEPH_AUTH_NONE
@@ -41985,7 +44256,7 @@ eba9e7e *** empty log message ***
 ee63c70 *** empty log message ***
 90a1c02 *** empty log message ***
 bac0031 *** empty log message ***
-25764921 import is currently broken
+2576492 import is currently broken
 b247412 *** empty log message ***
 61a5130 *** empty log message ***
 9475610 *** empty log message ***
diff --git a/Makefile.am b/Makefile.am
index d572e14..7734be2 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -22,6 +22,11 @@ EXTRA_DIST += \
 	share/id_dsa_drop.ceph.com \
 	share/id_dsa_drop.ceph.com.pub
 
+NPROC = nproc
+if FREEBSD
+	NPROC = sysctl -n hw.ncpu
+endif
+
 # why is it so hard to make autotools to this?
 install-data-local::
 	-mkdir -p $(DESTDIR)$(datadir)/ceph
@@ -46,7 +51,7 @@ check-local:: all
 	@cd src/gmock && $(MAKE) $(AM_MAKEFLAGS) lib/libgmock.la lib/libgmock_main.la
 #	exercise cli tools
 	u=`ulimit -u` ; \
-	p=`expr $(shell nproc) / 2` ; \
+	p=`expr $(shell ${NPROC}) / 2` ; \
 	n=`expr $$p \* 1024` ; \
 	if ${CHECK_ULIMIT} && echo ${MAKEFLAGS} | grep --quiet -e -j && test $$u -lt $$n ; then \
 		echo "ulimit -u is $$u which is lower than $$n = $$p / 2 * 1024" ; \
diff --git a/Makefile.in b/Makefile.in
index 1946b65..64c99c7 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -1,7 +1,7 @@
-# Makefile.in generated by automake 1.15 from Makefile.am.
+# Makefile.in generated by automake 1.14.1 from Makefile.am.
 # @configure_input@
 
-# Copyright (C) 1994-2014 Free Software Foundation, Inc.
+# Copyright (C) 1994-2013 Free Software Foundation, Inc.
 
 # This Makefile.in is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -14,17 +14,7 @@
 
 @SET_MAKE@
 VPATH = @srcdir@
-am__is_gnu_make = { \
-  if test -z '$(MAKELEVEL)'; then \
-    false; \
-  elif test -n '$(MAKE_HOST)'; then \
-    true; \
-  elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
-    true; \
-  else \
-    false; \
-  fi; \
-}
+am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
 am__make_running_with_option = \
   case $${target_option-} in \
       ?) ;; \
@@ -89,6 +79,11 @@ build_triplet = @build@
 host_triplet = @host@
 target_triplet = @target@
 subdir = .
+DIST_COMMON = INSTALL NEWS README AUTHORS ChangeLog \
+	$(srcdir)/Makefile.in $(srcdir)/Makefile.am \
+	$(top_srcdir)/configure $(am__configure_deps) \
+	$(srcdir)/ceph.spec.in test-driver COPYING ar-lib compile \
+	config.guess config.sub install-sh missing ltmain.sh
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
 am__aclocal_m4_deps = $(top_srcdir)/m4/ac_check_classpath.m4 \
 	$(top_srcdir)/m4/ac_prog_jar.m4 \
@@ -107,8 +102,6 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/ac_check_classpath.m4 \
 	$(top_srcdir)/m4/pkg.m4 $(top_srcdir)/configure.ac
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
 	$(ACLOCAL_M4)
-DIST_COMMON = $(srcdir)/Makefile.am $(top_srcdir)/configure \
-	$(am__configure_deps) $(am__DIST_COMMON)
 am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \
  configure.lineno config.status.lineno
 mkinstalldirs = $(install_sh) -d
@@ -374,10 +367,6 @@ TEST_LOG_DRIVER = $(SHELL) $(top_srcdir)/test-driver
 TEST_LOG_COMPILE = $(TEST_LOG_COMPILER) $(AM_TEST_LOG_FLAGS) \
 	$(TEST_LOG_FLAGS)
 DIST_SUBDIRS = $(SUBDIRS)
-am__DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/ceph.spec.in AUTHORS \
-	COPYING ChangeLog INSTALL NEWS README ar-lib compile \
-	config.guess config.sub install-sh ltmain.sh missing \
-	test-driver
 DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
 distdir = $(PACKAGE)-$(VERSION)
 top_distdir = $(distdir)
@@ -511,7 +500,6 @@ LN_S = @LN_S@
 LTLIBOBJS = @LTLIBOBJS@
 LTTNG_GEN_TP_CHECK = @LTTNG_GEN_TP_CHECK@
 LTTNG_GEN_TP_PROG = @LTTNG_GEN_TP_PROG@
-LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
 MAKEINFO = @MAKEINFO@
 MANIFEST_TOOL = @MANIFEST_TOOL@
 MKDIR_P = @MKDIR_P@
@@ -538,7 +526,10 @@ PTHREAD_CC = @PTHREAD_CC@
 PTHREAD_CFLAGS = @PTHREAD_CFLAGS@
 PTHREAD_LIBS = @PTHREAD_LIBS@
 PYTHON = @PYTHON@
+PYTHON_CFLAGS = @PYTHON_CFLAGS@
+PYTHON_CONFIG_CHECK = @PYTHON_CONFIG_CHECK@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
+PYTHON_LDFLAGS = @PYTHON_LDFLAGS@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
 PYTHON_PREFIX = @PYTHON_PREFIX@
 PYTHON_VERSION = @PYTHON_VERSION@
@@ -607,7 +598,6 @@ program_transform_name = @program_transform_name@
 psdir = @psdir@
 pyexecdir = @pyexecdir@
 pythondir = @pythondir@
-runstatedir = @runstatedir@
 sbindir = @sbindir@
 sharedstatedir = @sharedstatedir@
 srcdir = @srcdir@
@@ -637,6 +627,7 @@ EXTRA_DIST = autogen.sh ceph.spec.in ceph.spec install-deps.sh \
 	share/id_dsa_drop.ceph.com.pub
 # the "." here makes sure check-local builds gtest and gmock before they are used
 SUBDIRS = . src man doc systemd selinux
+NPROC = nproc
 CHECK_ULIMIT := true
 TESTS = $(check_SCRIPTS)
 check_SCRIPTS = \
@@ -661,6 +652,7 @@ $(srcdir)/Makefile.in:  $(srcdir)/Makefile.am  $(am__configure_deps)
 	echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu Makefile'; \
 	$(am__cd) $(top_srcdir) && \
 	  $(AUTOMAKE) --gnu Makefile
+.PRECIOUS: Makefile
 Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
 	@case '$?' in \
 	  *config.status*) \
@@ -827,7 +819,7 @@ $(TEST_SUITE_LOG): $(TEST_LOGS)
 	if test -n "$$am__remaking_logs"; then \
 	  echo "fatal: making $(TEST_SUITE_LOG): possible infinite" \
 	       "recursion detected" >&2; \
-	elif test -n "$$redo_logs"; then \
+	else \
 	  am__remaking_logs=yes $(MAKE) $(AM_MAKEFLAGS) $$redo_logs; \
 	fi; \
 	if $(am__make_dryrun); then :; else \
@@ -1044,15 +1036,15 @@ dist-xz: distdir
 	$(am__post_remove_distdir)
 
 dist-tarZ: distdir
-	@echo WARNING: "Support for distribution archives compressed with" \
-		       "legacy program 'compress' is deprecated." >&2
+	@echo WARNING: "Support for shar distribution archives is" \
+	               "deprecated." >&2
 	@echo WARNING: "It will be removed altogether in Automake 2.0" >&2
 	tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z
 	$(am__post_remove_distdir)
 
 dist-shar: distdir
-	@echo WARNING: "Support for shar distribution archives is" \
-	               "deprecated." >&2
+	@echo WARNING: "Support for distribution archives compressed with" \
+		       "legacy program 'compress' is deprecated." >&2
 	@echo WARNING: "It will be removed altogether in Automake 2.0" >&2
 	shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz
 	$(am__post_remove_distdir)
@@ -1088,17 +1080,17 @@ distcheck: dist
 	esac
 	chmod -R a-w $(distdir)
 	chmod u+w $(distdir)
-	mkdir $(distdir)/_build $(distdir)/_build/sub $(distdir)/_inst
+	mkdir $(distdir)/_build $(distdir)/_inst
 	chmod a-w $(distdir)
 	test -d $(distdir)/_build || exit 0; \
 	dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \
 	  && dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \
 	  && am__cwd=`pwd` \
-	  && $(am__cd) $(distdir)/_build/sub \
-	  && ../../configure \
+	  && $(am__cd) $(distdir)/_build \
+	  && ../configure \
 	    $(AM_DISTCHECK_CONFIGURE_FLAGS) \
 	    $(DISTCHECK_CONFIGURE_FLAGS) \
-	    --srcdir=../.. --prefix="$$dc_install_base" \
+	    --srcdir=.. --prefix="$$dc_install_base" \
 	  && $(MAKE) $(AM_MAKEFLAGS) \
 	  && $(MAKE) $(AM_MAKEFLAGS) dvi \
 	  && $(MAKE) $(AM_MAKEFLAGS) check \
@@ -1281,8 +1273,7 @@ uninstall-am:
 	mostlyclean-libtool pdf pdf-am ps ps-am recheck tags tags-am \
 	uninstall uninstall-am
 
-.PRECIOUS: Makefile
-
+ at FREEBSD_TRUE@	NPROC = sysctl -n hw.ncpu
 
 # why is it so hard to make autotools to this?
 install-data-local::
@@ -1304,7 +1295,7 @@ check-local:: all
 	@cd src/gmock && $(MAKE) $(AM_MAKEFLAGS) lib/libgmock.la lib/libgmock_main.la
 #	exercise cli tools
 	u=`ulimit -u` ; \
-	p=`expr $(shell nproc) / 2` ; \
+	p=`expr $(shell ${NPROC}) / 2` ; \
 	n=`expr $$p \* 1024` ; \
 	if ${CHECK_ULIMIT} && echo ${MAKEFLAGS} | grep --quiet -e -j && test $$u -lt $$n ; then \
 		echo "ulimit -u is $$u which is lower than $$n = $$p / 2 * 1024" ; \
diff --git a/aclocal.m4 b/aclocal.m4
index aa640de..da19afc 100644
--- a/aclocal.m4
+++ b/aclocal.m4
@@ -1,6 +1,6 @@
-# generated automatically by aclocal 1.15 -*- Autoconf -*-
+# generated automatically by aclocal 1.14.1 -*- Autoconf -*-
 
-# Copyright (C) 1996-2014 Free Software Foundation, Inc.
+# Copyright (C) 1996-2013 Free Software Foundation, Inc.
 
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -20,7 +20,7 @@ You have another version of autoconf.  It may work, but is not guaranteed to.
 If you have problems, you may need to regenerate the build system entirely.
 To do so, use the procedure documented by the package, typically 'autoreconf'.])])
 
-# Copyright (C) 2002-2014 Free Software Foundation, Inc.
+# Copyright (C) 2002-2013 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -32,10 +32,10 @@ To do so, use the procedure documented by the package, typically 'autoreconf'.])
 # generated from the m4 files accompanying Automake X.Y.
 # (This private macro should not be called outside this file.)
 AC_DEFUN([AM_AUTOMAKE_VERSION],
-[am__api_version='1.15'
+[am__api_version='1.14'
 dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to
 dnl require some minimum version.  Point them to the right macro.
-m4_if([$1], [1.15], [],
+m4_if([$1], [1.14.1], [],
       [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl
 ])
 
@@ -51,12 +51,12 @@ m4_define([_AM_AUTOCONF_VERSION], [])
 # Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced.
 # This function is AC_REQUIREd by AM_INIT_AUTOMAKE.
 AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION],
-[AM_AUTOMAKE_VERSION([1.15])dnl
+[AM_AUTOMAKE_VERSION([1.14.1])dnl
 m4_ifndef([AC_AUTOCONF_VERSION],
   [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl
 _AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))])
 
-# Copyright (C) 2011-2014 Free Software Foundation, Inc.
+# Copyright (C) 2011-2013 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -118,7 +118,7 @@ AC_SUBST([AR])dnl
 
 # Figure out how to run the assembler.                      -*- Autoconf -*-
 
-# Copyright (C) 2001-2014 Free Software Foundation, Inc.
+# Copyright (C) 2001-2013 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -138,7 +138,7 @@ _AM_IF_OPTION([no-dependencies],, [_AM_DEPENDENCIES([CCAS])])dnl
 
 # AM_AUX_DIR_EXPAND                                         -*- Autoconf -*-
 
-# Copyright (C) 2001-2014 Free Software Foundation, Inc.
+# Copyright (C) 2001-2013 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -183,14 +183,15 @@ _AM_IF_OPTION([no-dependencies],, [_AM_DEPENDENCIES([CCAS])])dnl
 # configured tree to be moved without reconfiguration.
 
 AC_DEFUN([AM_AUX_DIR_EXPAND],
-[AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT])dnl
-# Expand $ac_aux_dir to an absolute path.
-am_aux_dir=`cd "$ac_aux_dir" && pwd`
+[dnl Rely on autoconf to set up CDPATH properly.
+AC_PREREQ([2.50])dnl
+# expand $ac_aux_dir to an absolute path
+am_aux_dir=`cd $ac_aux_dir && pwd`
 ])
 
 # AM_COND_IF                                            -*- Autoconf -*-
 
-# Copyright (C) 2008-2014 Free Software Foundation, Inc.
+# Copyright (C) 2008-2013 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -227,7 +228,7 @@ fi[]dnl
 
 # AM_CONDITIONAL                                            -*- Autoconf -*-
 
-# Copyright (C) 1997-2014 Free Software Foundation, Inc.
+# Copyright (C) 1997-2013 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -258,7 +259,7 @@ AC_CONFIG_COMMANDS_PRE(
 Usually this means the macro was only invoked conditionally.]])
 fi])])
 
-# Copyright (C) 1999-2014 Free Software Foundation, Inc.
+# Copyright (C) 1999-2013 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -449,7 +450,7 @@ _AM_SUBST_NOTMAKE([am__nodep])dnl
 
 # Generate code to set up dependency tracking.              -*- Autoconf -*-
 
-# Copyright (C) 1999-2014 Free Software Foundation, Inc.
+# Copyright (C) 1999-2013 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -525,7 +526,7 @@ AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS],
 
 # Do all the work for Automake.                             -*- Autoconf -*-
 
-# Copyright (C) 1996-2014 Free Software Foundation, Inc.
+# Copyright (C) 1996-2013 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -615,8 +616,8 @@ AC_REQUIRE([AC_PROG_MKDIR_P])dnl
 # <http://lists.gnu.org/archive/html/automake/2012-07/msg00001.html>
 # <http://lists.gnu.org/archive/html/automake/2012-07/msg00014.html>
 AC_SUBST([mkdir_p], ['$(MKDIR_P)'])
-# We need awk for the "check" target (and possibly the TAP driver).  The
-# system "awk" is bad on some platforms.
+# We need awk for the "check" target.  The system "awk" is bad on
+# some platforms.
 AC_REQUIRE([AC_PROG_AWK])dnl
 AC_REQUIRE([AC_PROG_MAKE_SET])dnl
 AC_REQUIRE([AM_SET_LEADING_DOT])dnl
@@ -689,11 +690,7 @@ to "yes", and re-run configure.
 END
     AC_MSG_ERROR([Your 'rm' program is bad, sorry.])
   fi
-fi
-dnl The trailing newline in this macro's definition is deliberate, for
-dnl backward compatibility and to allow trailing 'dnl'-style comments
-dnl after the AM_INIT_AUTOMAKE invocation. See automake bug#16841.
-])
+fi])
 
 dnl Hook into '_AC_COMPILER_EXEEXT' early to learn its expansion.  Do not
 dnl add the conditional right here, as _AC_COMPILER_EXEEXT may be further
@@ -722,7 +719,7 @@ for _am_header in $config_headers :; do
 done
 echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count])
 
-# Copyright (C) 2001-2014 Free Software Foundation, Inc.
+# Copyright (C) 2001-2013 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -733,7 +730,7 @@ echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_co
 # Define $install_sh.
 AC_DEFUN([AM_PROG_INSTALL_SH],
 [AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
-if test x"${install_sh+set}" != xset; then
+if test x"${install_sh}" != xset; then
   case $am_aux_dir in
   *\ * | *\	*)
     install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;;
@@ -743,7 +740,7 @@ if test x"${install_sh+set}" != xset; then
 fi
 AC_SUBST([install_sh])])
 
-# Copyright (C) 2003-2014 Free Software Foundation, Inc.
+# Copyright (C) 2003-2013 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -764,7 +761,7 @@ AC_SUBST([am__leading_dot])])
 
 # Check to see how 'make' treats includes.	            -*- Autoconf -*-
 
-# Copyright (C) 2001-2014 Free Software Foundation, Inc.
+# Copyright (C) 2001-2013 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -814,7 +811,7 @@ rm -f confinc confmf
 
 # Fake the existence of programs that GNU maintainers use.  -*- Autoconf -*-
 
-# Copyright (C) 1997-2014 Free Software Foundation, Inc.
+# Copyright (C) 1997-2013 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -853,7 +850,7 @@ fi
 
 # Helper functions for option handling.                     -*- Autoconf -*-
 
-# Copyright (C) 2001-2014 Free Software Foundation, Inc.
+# Copyright (C) 2001-2013 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -882,7 +879,7 @@ AC_DEFUN([_AM_SET_OPTIONS],
 AC_DEFUN([_AM_IF_OPTION],
 [m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])])
 
-# Copyright (C) 1999-2014 Free Software Foundation, Inc.
+# Copyright (C) 1999-2013 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -929,7 +926,7 @@ AC_LANG_POP([C])])
 # For backward compatibility.
 AC_DEFUN_ONCE([AM_PROG_CC_C_O], [AC_REQUIRE([AC_PROG_CC])])
 
-# Copyright (C) 1999-2014 Free Software Foundation, Inc.
+# Copyright (C) 1999-2013 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -1164,7 +1161,7 @@ for i in list(range(0, 4)): minverhex = (minverhex << 8) + minver[[i]]
 sys.exit(sys.hexversion < minverhex)"
   AS_IF([AM_RUN_LOG([$1 -c "$prog"])], [$3], [$4])])
 
-# Copyright (C) 2001-2014 Free Software Foundation, Inc.
+# Copyright (C) 2001-2013 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -1183,7 +1180,7 @@ AC_DEFUN([AM_RUN_LOG],
 
 # Check to make sure that the build environment is sane.    -*- Autoconf -*-
 
-# Copyright (C) 1996-2014 Free Software Foundation, Inc.
+# Copyright (C) 1996-2013 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -1264,7 +1261,7 @@ AC_CONFIG_COMMANDS_PRE(
 rm -f conftest.file
 ])
 
-# Copyright (C) 2009-2014 Free Software Foundation, Inc.
+# Copyright (C) 2009-2013 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -1324,7 +1321,7 @@ AC_SUBST([AM_BACKSLASH])dnl
 _AM_SUBST_NOTMAKE([AM_BACKSLASH])dnl
 ])
 
-# Copyright (C) 2001-2014 Free Software Foundation, Inc.
+# Copyright (C) 2001-2013 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -1352,7 +1349,7 @@ fi
 INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s"
 AC_SUBST([INSTALL_STRIP_PROGRAM])])
 
-# Copyright (C) 2006-2014 Free Software Foundation, Inc.
+# Copyright (C) 2006-2013 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -1371,7 +1368,7 @@ AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)])
 
 # Check how to create a tarball.                            -*- Autoconf -*-
 
-# Copyright (C) 2004-2014 Free Software Foundation, Inc.
+# Copyright (C) 2004-2013 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
diff --git a/ar-lib b/ar-lib
index 463b9ec..fe2301e 100755
--- a/ar-lib
+++ b/ar-lib
@@ -4,7 +4,7 @@
 me=ar-lib
 scriptversion=2012-03-01.08; # UTC
 
-# Copyright (C) 2010-2014 Free Software Foundation, Inc.
+# Copyright (C) 2010-2013 Free Software Foundation, Inc.
 # Written by Peter Rosin <peda at lysator.liu.se>.
 #
 # This program is free software; you can redistribute it and/or modify
diff --git a/ceph.spec b/ceph.spec
index 65c51c4..84c1a29 100644
--- a/ceph.spec
+++ b/ceph.spec
@@ -46,7 +46,8 @@ restorecon -R /etc/rc\.d/init\.d/ceph > /dev/null 2>&1; \
 restorecon -R /etc/rc\.d/init\.d/radosgw > /dev/null 2>&1; \
 restorecon -R /var/run/ceph > /dev/null 2>&1; \
 restorecon -R /var/lib/ceph > /dev/null 2>&1; \
-restorecon -R /var/log/ceph > /dev/null 2>&1;
+restorecon -R /var/log/ceph > /dev/null 2>&1; \
+restorecon -R /var/log/radosgw > /dev/null 2>&1;
 %endif
 
 %{!?_udevrulesdir: %global _udevrulesdir /lib/udev/rules.d}
@@ -74,7 +75,7 @@ restorecon -R /var/log/ceph > /dev/null 2>&1;
 # common
 #################################################################################
 Name:		ceph
-Version:	10.0.5
+Version:	10.1.0
 Release:	0%{?dist}
 Epoch:		1
 Summary:	User space components of the Ceph file system
@@ -108,11 +109,6 @@ BuildRequires:	boost-devel
 BuildRequires:  cmake
 BuildRequires:	cryptsetup
 BuildRequires:	fuse-devel
-%if 0%{?suse_version}
-BuildRequires:	python-Cython
-%else
-BuildRequires:	Cython
-%endif
 BuildRequires:	gdbm
 BuildRequires:	hdparm
 BuildRequires:	leveldb-devel > 1.2
@@ -155,15 +151,20 @@ BuildRequires:	libbz2-devel
 %if 0%{with tcmalloc}
 BuildRequires:	gperftools-devel
 %endif
+BuildRequires:  btrfsprogs
 BuildRequires:	mozilla-nss-devel
 BuildRequires:	keyutils-devel
 BuildRequires:	libatomic-ops-devel
+BuildRequires:  libopenssl-devel
 BuildRequires:  lsb-release
+BuildRequires:  openldap2-devel
+BuildRequires:	python-Cython
 %endif
 %if 0%{?fedora} || 0%{?rhel} 
 %if 0%{?_with_systemd}
 Requires:	systemd
 %endif
+BuildRequires:	btrfs-progs
 BuildRequires:	nss-devel
 BuildRequires:	keyutils-libs-devel
 BuildRequires:	libatomic_ops-devel
@@ -171,7 +172,10 @@ Requires(post):	chkconfig
 Requires(preun):	chkconfig
 Requires(preun):	initscripts
 BuildRequires:	gperftools-devel
+BuildRequires:  openldap-devel
+BuildRequires:  openssl-devel
 BuildRequires:  redhat-lsb-core
+BuildRequires:	Cython
 %endif
 # boost
 %if 0%{?fedora} || 0%{?rhel} 
@@ -208,6 +212,10 @@ BuildRequires:	python-sphinx10
 %if 0%{?fedora} || 0%{?suse_version} || 0%{?rhel} >= 7
 BuildRequires:	python-sphinx
 %endif
+#hardened-cc1
+%if 0%{?fedora} || 0%{?rhel}
+BuildRequires:  redhat-rpm-config
+%endif
 
 %description
 Ceph is a massively scalable, open-source, distributed storage system that runs
@@ -224,6 +232,7 @@ Requires:      ceph-common = %{epoch}:%{version}-%{release}
 Requires:      librbd1 = %{epoch}:%{version}-%{release}
 Requires:      librados2 = %{epoch}:%{version}-%{release}
 Requires:      libcephfs1 = %{epoch}:%{version}-%{release}
+Requires:      librgw2 = %{epoch}:%{version}-%{release}
 %if 0%{with selinux}
 Requires:      ceph-selinux = %{epoch}:%{version}-%{release}
 %endif
@@ -253,6 +262,7 @@ Summary:	Ceph Common
 Group:		System Environment/Base
 Requires:	librbd1 = %{epoch}:%{version}-%{release}
 Requires:	librados2 = %{epoch}:%{version}-%{release}
+Requires:	libcephfs1 = %{epoch}:%{version}-%{release}
 Requires:	python-rados = %{epoch}:%{version}-%{release}
 Requires:	python-rbd = %{epoch}:%{version}-%{release}
 Requires:	python-cephfs = %{epoch}:%{version}-%{release}
@@ -300,14 +310,12 @@ of cluster membership, configuration, and state.
 %package fuse
 Summary:	Ceph fuse-based client
 Group:		System Environment/Base
-Requires:	%{name}
 %description fuse
 FUSE based client for Ceph distributed network file system
 
 %package -n rbd-fuse
 Summary:	Ceph fuse-based client
 Group:		System Environment/Base
-Requires:	%{name}
 Requires:	librados2 = %{epoch}:%{version}-%{release}
 Requires:	librbd1 = %{epoch}:%{version}-%{release}
 %description -n rbd-fuse
@@ -316,7 +324,6 @@ FUSE based client to map Ceph rbd images to files
 %package -n rbd-mirror
 Summary:	Ceph daemon for mirroring RBD images
 Group:		System Environment/Base
-Requires:	%{name}
 Requires:	ceph-common = %{epoch}:%{version}-%{release}
 Requires:	librados2 = %{epoch}:%{version}-%{release}
 %description -n rbd-mirror
@@ -326,7 +333,6 @@ changes asynchronously.
 %package -n rbd-nbd
 Summary:	Ceph RBD client base on NBD
 Group:		System Environment/Base
-Requires:	%{name}
 Requires:	librados2 = %{epoch}:%{version}-%{release}
 Requires:	librbd1 = %{epoch}:%{version}-%{release}
 %description -n rbd-nbd
@@ -340,6 +346,7 @@ Requires:	ceph-common = %{epoch}:%{version}-%{release}
 Requires:	ceph-selinux = %{epoch}:%{version}-%{release}
 %endif
 Requires:	librados2 = %{epoch}:%{version}-%{release}
+Requires:	librgw2 = %{epoch}:%{version}-%{release}
 %if 0%{?rhel} || 0%{?fedora}
 Requires:	mailcap
 # python-flask for powerdns
@@ -350,16 +357,17 @@ Requires:	python-flask
 Requires:      python-Flask
 %endif
 %description radosgw
-This package is an S3 HTTP REST gateway for the RADOS object store. It
-is implemented as a FastCGI module using libfcgi, and can be used in
-conjunction with any FastCGI capable web server.
+RADOS is a distributed object store used by the Ceph distributed
+storage system.  This package provides a REST gateway to the
+object store that aims to implement a superset of Amazon's S3
+service as well as the OpenStack Object Storage ("Swift") API.
 
 %if %{with ocf}
 %package resource-agents
 Summary:	OCF-compliant resource agents for Ceph daemons
 Group:		System Environment/Base
 License:	LGPL-2.0
-Requires:	%{name} = %{epoch}:%{version}
+Requires:	ceph-base = %{epoch}:%{version}
 Requires:	resource-agents
 %description resource-agents
 Resource agents for monitoring and managing Ceph daemons
@@ -406,6 +414,24 @@ Obsoletes:	ceph-devel < %{epoch}:%{version}-%{release}
 This package contains libraries and headers needed to develop programs
 that use RADOS object store.
 
+%package -n librgw2
+Summary:	RADOS gateway client library
+Group:		System Environment/Libraries
+License:	LGPL-2.0
+Requires:	librados2 = %{epoch}:%{version}-%{release}
+%description -n librgw2
+This package provides a library implementation of the RADOS gateway
+(distributed object store with S3 and Swift personalities).
+
+%package -n librgw2-devel
+Summary:	RADOS gateway client library
+Group:		Development/Libraries
+License:	LGPL-2.0
+Requires:	librados2 = %{epoch}:%{version}-%{release}
+%description -n librgw2-devel
+This package contains libraries and headers needed to develop programs
+that use RADOS gateway client library.
+
 %package -n python-rados
 Summary:	Python libraries for the RADOS object store
 Group:		System Environment/Libraries
@@ -564,7 +590,7 @@ This package contains the Java libraries for the Ceph File System.
 %package selinux
 Summary:	SELinux support for Ceph MON, OSD and MDS
 Group:		System Environment/Base
-Requires:	%{name}
+Requires:	ceph-base = %{epoch}:%{version}-%{release}
 Requires:	policycoreutils, libselinux-utils
 Requires(post): selinux-policy-base >= %{_selinux_policy_version}, policycoreutils, gawk
 Requires(postun): policycoreutils
@@ -601,7 +627,6 @@ Summary:	Compatibility package for Ceph headers
 Group:		Development/Libraries
 License:	LGPL-2.0
 Obsoletes:	ceph-devel
-Requires:	%{name} = %{epoch}:%{version}-%{release}
 Requires:	librados2-devel = %{epoch}:%{version}-%{release}
 Requires:	libradosstriper1-devel = %{epoch}:%{version}-%{release}
 Requires:	librbd1-devel = %{epoch}:%{version}-%{release}
@@ -733,11 +758,13 @@ install -m 0644 -D etc/sysconfig/ceph $RPM_BUILD_ROOT%{_localstatedir}/adm/fillu
   install -m 0644 -D systemd/ceph-create-keys at .service $RPM_BUILD_ROOT%{_unitdir}/ceph-create-keys at .service
   install -m 0644 -D systemd/ceph-mds at .service $RPM_BUILD_ROOT%{_unitdir}/ceph-mds at .service
   install -m 0644 -D systemd/ceph-radosgw at .service $RPM_BUILD_ROOT%{_unitdir}/ceph-radosgw at .service
+  install -m 0644 -D systemd/ceph-rbd-mirror at .service $RPM_BUILD_ROOT%{_unitdir}/ceph-rbd-mirror at .service
   install -m 0644 -D systemd/ceph.target $RPM_BUILD_ROOT%{_unitdir}/ceph.target
   install -m 0644 -D systemd/ceph-osd.target $RPM_BUILD_ROOT%{_unitdir}/ceph-osd.target
   install -m 0644 -D systemd/ceph-mon.target $RPM_BUILD_ROOT%{_unitdir}/ceph-mon.target
   install -m 0644 -D systemd/ceph-mds.target $RPM_BUILD_ROOT%{_unitdir}/ceph-mds.target
   install -m 0644 -D systemd/ceph-radosgw.target $RPM_BUILD_ROOT%{_unitdir}/ceph-radosgw.target
+  install -m 0644 -D systemd/ceph-rbd-mirror.target $RPM_BUILD_ROOT%{_unitdir}/ceph-rbd-mirror.target
   install -m 0644 -D systemd/ceph-disk at .service $RPM_BUILD_ROOT%{_unitdir}/ceph-disk at .service
   install -m 0755 -D systemd/ceph $RPM_BUILD_ROOT%{_sbindir}/rcceph
 %else
@@ -942,6 +969,9 @@ rm -rf $RPM_BUILD_ROOT
 %{_bindir}/ceph-rbdnamer
 %{_bindir}/ceph-syn
 %{_bindir}/ceph-crush-location
+%{_bindir}/cephfs-data-scan
+%{_bindir}/cephfs-journal-tool
+%{_bindir}/cephfs-table-tool
 %{_bindir}/rados
 %{_bindir}/rbd
 %{_bindir}/rbd-replay
@@ -1018,9 +1048,6 @@ fi
 #################################################################################
 %files mds
 %{_bindir}/ceph-mds
-%{_bindir}/cephfs-journal-tool
-%{_bindir}/cephfs-table-tool
-%{_bindir}/cephfs-data-scan
 %{_mandir}/man8/ceph-mds.8*
 %if 0%{?_with_systemd}
 %{_unitdir}/ceph-mds at .service
@@ -1067,6 +1094,10 @@ fi
 %defattr(-,root,root,-)
 %{_bindir}/rbd-mirror
 %{_mandir}/man8/rbd-mirror.8*
+%if 0%{?_with_systemd}
+%{_unitdir}/ceph-rbd-mirror at .service
+%{_unitdir}/ceph-rbd-mirror.target
+%endif
 
 #################################################################################
 %files -n rbd-nbd
@@ -1079,6 +1110,7 @@ fi
 %defattr(-,root,root,-)
 %{_bindir}/radosgw
 %{_bindir}/radosgw-admin
+%{_bindir}/radosgw-token
 %{_bindir}/radosgw-object-expirer
 %{_mandir}/man8/radosgw.8*
 %{_mandir}/man8/radosgw-admin.8*
@@ -1161,12 +1193,27 @@ fi
 
 #################################################################################
 %if %{with ocf}
+
 %files resource-agents
 %defattr(0755,root,root,-)
-%dir /usr/lib/ocf
-%dir /usr/lib/ocf/resource.d
-%dir /usr/lib/ocf/resource.d/ceph
-/usr/lib/ocf/resource.d/%{name}/*
+# N.B. src/ocf/Makefile.am uses $(prefix)/lib
+%dir %{_prefix}/lib/ocf
+%dir %{_prefix}/lib/ocf/resource.d
+%dir %{_prefix}/lib/ocf/resource.d/ceph
+%if 0%{_with_systemd}
+%exclude %{_prefix}/lib/ocf/resource.d/ceph/ceph
+%exclude %{_prefix}/lib/ocf/resource.d/ceph/mds
+%exclude %{_prefix}/lib/ocf/resource.d/ceph/mon
+%exclude %{_prefix}/lib/ocf/resource.d/ceph/osd
+%endif
+%if ! 0%{_with_systemd}
+%{_prefix}/lib/ocf/resource.d/ceph/ceph
+%{_prefix}/lib/ocf/resource.d/ceph/mds
+%{_prefix}/lib/ocf/resource.d/ceph/mon
+%{_prefix}/lib/ocf/resource.d/ceph/osd
+%endif
+%{_prefix}/lib/ocf/resource.d/ceph/rbd
+
 %endif
 
 #################################################################################
@@ -1206,7 +1253,8 @@ fi
 #################################################################################
 %files -n python-rados
 %defattr(-,root,root,-)
-%{python_sitelib}/rados.py*
+%{python_sitearch}/rados.so
+%{python_sitearch}/rados-*.egg-info
 
 #################################################################################
 %files -n libradosstriper1
@@ -1256,6 +1304,25 @@ ln -sf %{_libdir}/librbd.so.1 /usr/lib64/qemu/librbd.so.1
 %endif
 
 #################################################################################
+%files -n librgw2
+%defattr(-,root,root,-)
+%{_libdir}/librgw.so.*
+
+%post -n librgw2
+/sbin/ldconfig
+
+%postun -n librgw2
+/sbin/ldconfig
+
+#################################################################################
+%files -n librgw2-devel
+%defattr(-,root,root,-)
+%dir %{_includedir}/rados
+%{_includedir}/rados/librgw.h
+%{_includedir}/rados/rgw_file.h
+%{_libdir}/librgw.so
+
+#################################################################################
 %files -n python-rbd
 %defattr(-,root,root,-)
 %{python_sitearch}/rbd.so
@@ -1282,7 +1349,8 @@ ln -sf %{_libdir}/librbd.so.1 /usr/lib64/qemu/librbd.so.1
 #################################################################################
 %files -n python-cephfs
 %defattr(-,root,root,-)
-%{python_sitelib}/cephfs.py*
+%{python_sitearch}/cephfs.so
+%{python_sitearch}/cephfs-*.egg-info
 %{python_sitelib}/ceph_volume_client.py*
 
 #################################################################################
@@ -1310,6 +1378,7 @@ ln -sf %{_libdir}/librbd.so.1 /usr/lib64/qemu/librbd.so.1
 %{_bindir}/ceph_smalliobenchfs
 %{_bindir}/ceph_smalliobenchrbd
 %{_bindir}/ceph_test_*
+%{_bindir}/librgw_file*
 %{_bindir}/ceph_tpbench
 %{_bindir}/ceph_xattr_bench
 %{_bindir}/ceph-coverage
diff --git a/ceph.spec.in b/ceph.spec.in
index 498eac4..b52d7e2 100644
--- a/ceph.spec.in
+++ b/ceph.spec.in
@@ -46,7 +46,8 @@ restorecon -R /etc/rc\.d/init\.d/ceph > /dev/null 2>&1; \
 restorecon -R /etc/rc\.d/init\.d/radosgw > /dev/null 2>&1; \
 restorecon -R /var/run/ceph > /dev/null 2>&1; \
 restorecon -R /var/lib/ceph > /dev/null 2>&1; \
-restorecon -R /var/log/ceph > /dev/null 2>&1;
+restorecon -R /var/log/ceph > /dev/null 2>&1; \
+restorecon -R /var/log/radosgw > /dev/null 2>&1;
 %endif
 
 %{!?_udevrulesdir: %global _udevrulesdir /lib/udev/rules.d}
@@ -108,11 +109,6 @@ BuildRequires:	boost-devel
 BuildRequires:  cmake
 BuildRequires:	cryptsetup
 BuildRequires:	fuse-devel
-%if 0%{?suse_version}
-BuildRequires:	python-Cython
-%else
-BuildRequires:	Cython
-%endif
 BuildRequires:	gdbm
 BuildRequires:	hdparm
 BuildRequires:	leveldb-devel > 1.2
@@ -155,15 +151,20 @@ BuildRequires:	libbz2-devel
 %if 0%{with tcmalloc}
 BuildRequires:	gperftools-devel
 %endif
+BuildRequires:  btrfsprogs
 BuildRequires:	mozilla-nss-devel
 BuildRequires:	keyutils-devel
 BuildRequires:	libatomic-ops-devel
+BuildRequires:  libopenssl-devel
 BuildRequires:  lsb-release
+BuildRequires:  openldap2-devel
+BuildRequires:	python-Cython
 %endif
 %if 0%{?fedora} || 0%{?rhel} 
 %if 0%{?_with_systemd}
 Requires:	systemd
 %endif
+BuildRequires:	btrfs-progs
 BuildRequires:	nss-devel
 BuildRequires:	keyutils-libs-devel
 BuildRequires:	libatomic_ops-devel
@@ -171,7 +172,10 @@ Requires(post):	chkconfig
 Requires(preun):	chkconfig
 Requires(preun):	initscripts
 BuildRequires:	gperftools-devel
+BuildRequires:  openldap-devel
+BuildRequires:  openssl-devel
 BuildRequires:  redhat-lsb-core
+BuildRequires:	Cython
 %endif
 # boost
 %if 0%{?fedora} || 0%{?rhel} 
@@ -208,6 +212,10 @@ BuildRequires:	python-sphinx10
 %if 0%{?fedora} || 0%{?suse_version} || 0%{?rhel} >= 7
 BuildRequires:	python-sphinx
 %endif
+#hardened-cc1
+%if 0%{?fedora} || 0%{?rhel}
+BuildRequires:  redhat-rpm-config
+%endif
 
 %description
 Ceph is a massively scalable, open-source, distributed storage system that runs
@@ -224,6 +232,7 @@ Requires:      ceph-common = %{epoch}:%{version}-%{release}
 Requires:      librbd1 = %{epoch}:%{version}-%{release}
 Requires:      librados2 = %{epoch}:%{version}-%{release}
 Requires:      libcephfs1 = %{epoch}:%{version}-%{release}
+Requires:      librgw2 = %{epoch}:%{version}-%{release}
 %if 0%{with selinux}
 Requires:      ceph-selinux = %{epoch}:%{version}-%{release}
 %endif
@@ -253,6 +262,7 @@ Summary:	Ceph Common
 Group:		System Environment/Base
 Requires:	librbd1 = %{epoch}:%{version}-%{release}
 Requires:	librados2 = %{epoch}:%{version}-%{release}
+Requires:	libcephfs1 = %{epoch}:%{version}-%{release}
 Requires:	python-rados = %{epoch}:%{version}-%{release}
 Requires:	python-rbd = %{epoch}:%{version}-%{release}
 Requires:	python-cephfs = %{epoch}:%{version}-%{release}
@@ -300,14 +310,12 @@ of cluster membership, configuration, and state.
 %package fuse
 Summary:	Ceph fuse-based client
 Group:		System Environment/Base
-Requires:	%{name}
 %description fuse
 FUSE based client for Ceph distributed network file system
 
 %package -n rbd-fuse
 Summary:	Ceph fuse-based client
 Group:		System Environment/Base
-Requires:	%{name}
 Requires:	librados2 = %{epoch}:%{version}-%{release}
 Requires:	librbd1 = %{epoch}:%{version}-%{release}
 %description -n rbd-fuse
@@ -316,7 +324,6 @@ FUSE based client to map Ceph rbd images to files
 %package -n rbd-mirror
 Summary:	Ceph daemon for mirroring RBD images
 Group:		System Environment/Base
-Requires:	%{name}
 Requires:	ceph-common = %{epoch}:%{version}-%{release}
 Requires:	librados2 = %{epoch}:%{version}-%{release}
 %description -n rbd-mirror
@@ -326,7 +333,6 @@ changes asynchronously.
 %package -n rbd-nbd
 Summary:	Ceph RBD client base on NBD
 Group:		System Environment/Base
-Requires:	%{name}
 Requires:	librados2 = %{epoch}:%{version}-%{release}
 Requires:	librbd1 = %{epoch}:%{version}-%{release}
 %description -n rbd-nbd
@@ -340,6 +346,7 @@ Requires:	ceph-common = %{epoch}:%{version}-%{release}
 Requires:	ceph-selinux = %{epoch}:%{version}-%{release}
 %endif
 Requires:	librados2 = %{epoch}:%{version}-%{release}
+Requires:	librgw2 = %{epoch}:%{version}-%{release}
 %if 0%{?rhel} || 0%{?fedora}
 Requires:	mailcap
 # python-flask for powerdns
@@ -350,16 +357,17 @@ Requires:	python-flask
 Requires:      python-Flask
 %endif
 %description radosgw
-This package is an S3 HTTP REST gateway for the RADOS object store. It
-is implemented as a FastCGI module using libfcgi, and can be used in
-conjunction with any FastCGI capable web server.
+RADOS is a distributed object store used by the Ceph distributed
+storage system.  This package provides a REST gateway to the
+object store that aims to implement a superset of Amazon's S3
+service as well as the OpenStack Object Storage ("Swift") API.
 
 %if %{with ocf}
 %package resource-agents
 Summary:	OCF-compliant resource agents for Ceph daemons
 Group:		System Environment/Base
 License:	LGPL-2.0
-Requires:	%{name} = %{epoch}:%{version}
+Requires:	ceph-base = %{epoch}:%{version}
 Requires:	resource-agents
 %description resource-agents
 Resource agents for monitoring and managing Ceph daemons
@@ -406,6 +414,24 @@ Obsoletes:	ceph-devel < %{epoch}:%{version}-%{release}
 This package contains libraries and headers needed to develop programs
 that use RADOS object store.
 
+%package -n librgw2
+Summary:	RADOS gateway client library
+Group:		System Environment/Libraries
+License:	LGPL-2.0
+Requires:	librados2 = %{epoch}:%{version}-%{release}
+%description -n librgw2
+This package provides a library implementation of the RADOS gateway
+(distributed object store with S3 and Swift personalities).
+
+%package -n librgw2-devel
+Summary:	RADOS gateway client library
+Group:		Development/Libraries
+License:	LGPL-2.0
+Requires:	librados2 = %{epoch}:%{version}-%{release}
+%description -n librgw2-devel
+This package contains libraries and headers needed to develop programs
+that use RADOS gateway client library.
+
 %package -n python-rados
 Summary:	Python libraries for the RADOS object store
 Group:		System Environment/Libraries
@@ -564,7 +590,7 @@ This package contains the Java libraries for the Ceph File System.
 %package selinux
 Summary:	SELinux support for Ceph MON, OSD and MDS
 Group:		System Environment/Base
-Requires:	%{name}
+Requires:	ceph-base = %{epoch}:%{version}-%{release}
 Requires:	policycoreutils, libselinux-utils
 Requires(post): selinux-policy-base >= %{_selinux_policy_version}, policycoreutils, gawk
 Requires(postun): policycoreutils
@@ -601,7 +627,6 @@ Summary:	Compatibility package for Ceph headers
 Group:		Development/Libraries
 License:	LGPL-2.0
 Obsoletes:	ceph-devel
-Requires:	%{name} = %{epoch}:%{version}-%{release}
 Requires:	librados2-devel = %{epoch}:%{version}-%{release}
 Requires:	libradosstriper1-devel = %{epoch}:%{version}-%{release}
 Requires:	librbd1-devel = %{epoch}:%{version}-%{release}
@@ -733,11 +758,13 @@ install -m 0644 -D etc/sysconfig/ceph $RPM_BUILD_ROOT%{_localstatedir}/adm/fillu
   install -m 0644 -D systemd/ceph-create-keys at .service $RPM_BUILD_ROOT%{_unitdir}/ceph-create-keys at .service
   install -m 0644 -D systemd/ceph-mds at .service $RPM_BUILD_ROOT%{_unitdir}/ceph-mds at .service
   install -m 0644 -D systemd/ceph-radosgw at .service $RPM_BUILD_ROOT%{_unitdir}/ceph-radosgw at .service
+  install -m 0644 -D systemd/ceph-rbd-mirror at .service $RPM_BUILD_ROOT%{_unitdir}/ceph-rbd-mirror at .service
   install -m 0644 -D systemd/ceph.target $RPM_BUILD_ROOT%{_unitdir}/ceph.target
   install -m 0644 -D systemd/ceph-osd.target $RPM_BUILD_ROOT%{_unitdir}/ceph-osd.target
   install -m 0644 -D systemd/ceph-mon.target $RPM_BUILD_ROOT%{_unitdir}/ceph-mon.target
   install -m 0644 -D systemd/ceph-mds.target $RPM_BUILD_ROOT%{_unitdir}/ceph-mds.target
   install -m 0644 -D systemd/ceph-radosgw.target $RPM_BUILD_ROOT%{_unitdir}/ceph-radosgw.target
+  install -m 0644 -D systemd/ceph-rbd-mirror.target $RPM_BUILD_ROOT%{_unitdir}/ceph-rbd-mirror.target
   install -m 0644 -D systemd/ceph-disk at .service $RPM_BUILD_ROOT%{_unitdir}/ceph-disk at .service
   install -m 0755 -D systemd/ceph $RPM_BUILD_ROOT%{_sbindir}/rcceph
 %else
@@ -942,6 +969,9 @@ rm -rf $RPM_BUILD_ROOT
 %{_bindir}/ceph-rbdnamer
 %{_bindir}/ceph-syn
 %{_bindir}/ceph-crush-location
+%{_bindir}/cephfs-data-scan
+%{_bindir}/cephfs-journal-tool
+%{_bindir}/cephfs-table-tool
 %{_bindir}/rados
 %{_bindir}/rbd
 %{_bindir}/rbd-replay
@@ -1018,9 +1048,6 @@ fi
 #################################################################################
 %files mds
 %{_bindir}/ceph-mds
-%{_bindir}/cephfs-journal-tool
-%{_bindir}/cephfs-table-tool
-%{_bindir}/cephfs-data-scan
 %{_mandir}/man8/ceph-mds.8*
 %if 0%{?_with_systemd}
 %{_unitdir}/ceph-mds at .service
@@ -1067,6 +1094,10 @@ fi
 %defattr(-,root,root,-)
 %{_bindir}/rbd-mirror
 %{_mandir}/man8/rbd-mirror.8*
+%if 0%{?_with_systemd}
+%{_unitdir}/ceph-rbd-mirror at .service
+%{_unitdir}/ceph-rbd-mirror.target
+%endif
 
 #################################################################################
 %files -n rbd-nbd
@@ -1079,6 +1110,7 @@ fi
 %defattr(-,root,root,-)
 %{_bindir}/radosgw
 %{_bindir}/radosgw-admin
+%{_bindir}/radosgw-token
 %{_bindir}/radosgw-object-expirer
 %{_mandir}/man8/radosgw.8*
 %{_mandir}/man8/radosgw-admin.8*
@@ -1161,12 +1193,27 @@ fi
 
 #################################################################################
 %if %{with ocf}
+
 %files resource-agents
 %defattr(0755,root,root,-)
-%dir /usr/lib/ocf
-%dir /usr/lib/ocf/resource.d
-%dir /usr/lib/ocf/resource.d/ceph
-/usr/lib/ocf/resource.d/%{name}/*
+# N.B. src/ocf/Makefile.am uses $(prefix)/lib
+%dir %{_prefix}/lib/ocf
+%dir %{_prefix}/lib/ocf/resource.d
+%dir %{_prefix}/lib/ocf/resource.d/ceph
+%if 0%{_with_systemd}
+%exclude %{_prefix}/lib/ocf/resource.d/ceph/ceph
+%exclude %{_prefix}/lib/ocf/resource.d/ceph/mds
+%exclude %{_prefix}/lib/ocf/resource.d/ceph/mon
+%exclude %{_prefix}/lib/ocf/resource.d/ceph/osd
+%endif
+%if ! 0%{_with_systemd}
+%{_prefix}/lib/ocf/resource.d/ceph/ceph
+%{_prefix}/lib/ocf/resource.d/ceph/mds
+%{_prefix}/lib/ocf/resource.d/ceph/mon
+%{_prefix}/lib/ocf/resource.d/ceph/osd
+%endif
+%{_prefix}/lib/ocf/resource.d/ceph/rbd
+
 %endif
 
 #################################################################################
@@ -1206,7 +1253,8 @@ fi
 #################################################################################
 %files -n python-rados
 %defattr(-,root,root,-)
-%{python_sitelib}/rados.py*
+%{python_sitearch}/rados.so
+%{python_sitearch}/rados-*.egg-info
 
 #################################################################################
 %files -n libradosstriper1
@@ -1256,6 +1304,25 @@ ln -sf %{_libdir}/librbd.so.1 /usr/lib64/qemu/librbd.so.1
 %endif
 
 #################################################################################
+%files -n librgw2
+%defattr(-,root,root,-)
+%{_libdir}/librgw.so.*
+
+%post -n librgw2
+/sbin/ldconfig
+
+%postun -n librgw2
+/sbin/ldconfig
+
+#################################################################################
+%files -n librgw2-devel
+%defattr(-,root,root,-)
+%dir %{_includedir}/rados
+%{_includedir}/rados/librgw.h
+%{_includedir}/rados/rgw_file.h
+%{_libdir}/librgw.so
+
+#################################################################################
 %files -n python-rbd
 %defattr(-,root,root,-)
 %{python_sitearch}/rbd.so
@@ -1282,7 +1349,8 @@ ln -sf %{_libdir}/librbd.so.1 /usr/lib64/qemu/librbd.so.1
 #################################################################################
 %files -n python-cephfs
 %defattr(-,root,root,-)
-%{python_sitelib}/cephfs.py*
+%{python_sitearch}/cephfs.so
+%{python_sitearch}/cephfs-*.egg-info
 %{python_sitelib}/ceph_volume_client.py*
 
 #################################################################################
@@ -1310,6 +1378,7 @@ ln -sf %{_libdir}/librbd.so.1 /usr/lib64/qemu/librbd.so.1
 %{_bindir}/ceph_smalliobenchfs
 %{_bindir}/ceph_smalliobenchrbd
 %{_bindir}/ceph_test_*
+%{_bindir}/librgw_file*
 %{_bindir}/ceph_tpbench
 %{_bindir}/ceph_xattr_bench
 %{_bindir}/ceph-coverage
diff --git a/compile b/compile
index a85b723..531136b 100755
--- a/compile
+++ b/compile
@@ -3,7 +3,7 @@
 
 scriptversion=2012-10-14.11; # UTC
 
-# Copyright (C) 1999-2014 Free Software Foundation, Inc.
+# Copyright (C) 1999-2013 Free Software Foundation, Inc.
 # Written by Tom Tromey <tromey at cygnus.com>.
 #
 # This program is free software; you can redistribute it and/or modify
diff --git a/config.guess b/config.guess
index 1659250..b79252d 100755
--- a/config.guess
+++ b/config.guess
@@ -1,8 +1,8 @@
 #! /bin/sh
 # Attempt to guess a canonical system name.
-#   Copyright 1992-2015 Free Software Foundation, Inc.
+#   Copyright 1992-2013 Free Software Foundation, Inc.
 
-timestamp='2015-08-20'
+timestamp='2013-06-10'
 
 # This file is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License as published by
@@ -24,12 +24,12 @@ timestamp='2015-08-20'
 # program.  This Exception is an additional permission under section 7
 # of the GNU General Public License, version 3 ("GPLv3").
 #
-# Originally written by Per Bothner; maintained since 2000 by Ben Elliston.
+# Originally written by Per Bothner.
 #
 # You can get the latest version of this script from:
 # http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD
 #
-# Please send patches to <config-patches at gnu.org>.
+# Please send patches with a ChangeLog entry to config-patches at gnu.org.
 
 
 me=`echo "$0" | sed -e 's,.*/,,'`
@@ -50,7 +50,7 @@ version="\
 GNU config.guess ($timestamp)
 
 Originally written by Per Bothner.
-Copyright 1992-2015 Free Software Foundation, Inc.
+Copyright 1992-2013 Free Software Foundation, Inc.
 
 This is free software; see the source for copying conditions.  There is NO
 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
@@ -149,7 +149,7 @@ Linux|GNU|GNU/*)
 	LIBC=gnu
 	#endif
 	EOF
-	eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC' | sed 's, ,,g'`
+	eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC'`
 	;;
 esac
 
@@ -168,27 +168,20 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
 	# Note: NetBSD doesn't particularly care about the vendor
 	# portion of the name.  We always set it to "unknown".
 	sysctl="sysctl -n hw.machine_arch"
-	UNAME_MACHINE_ARCH=`(uname -p 2>/dev/null || \
-	    /sbin/$sysctl 2>/dev/null || \
-	    /usr/sbin/$sysctl 2>/dev/null || \
-	    echo unknown)`
+	UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \
+	    /usr/sbin/$sysctl 2>/dev/null || echo unknown)`
 	case "${UNAME_MACHINE_ARCH}" in
 	    armeb) machine=armeb-unknown ;;
 	    arm*) machine=arm-unknown ;;
 	    sh3el) machine=shl-unknown ;;
 	    sh3eb) machine=sh-unknown ;;
 	    sh5el) machine=sh5le-unknown ;;
-	    earmv*)
-		arch=`echo ${UNAME_MACHINE_ARCH} | sed -e 's,^e\(armv[0-9]\).*$,\1,'`
-		endian=`echo ${UNAME_MACHINE_ARCH} | sed -ne 's,^.*\(eb\)$,\1,p'`
-		machine=${arch}${endian}-unknown
-		;;
 	    *) machine=${UNAME_MACHINE_ARCH}-unknown ;;
 	esac
 	# The Operating System including object format, if it has switched
 	# to ELF recently, or will in the future.
 	case "${UNAME_MACHINE_ARCH}" in
-	    arm*|earm*|i386|m68k|ns32k|sh3*|sparc|vax)
+	    arm*|i386|m68k|ns32k|sh3*|sparc|vax)
 		eval $set_cc_for_build
 		if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \
 			| grep -q __ELF__
@@ -204,13 +197,6 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
 		os=netbsd
 		;;
 	esac
-	# Determine ABI tags.
-	case "${UNAME_MACHINE_ARCH}" in
-	    earm*)
-		expr='s/^earmv[0-9]/-eabi/;s/eb$//'
-		abi=`echo ${UNAME_MACHINE_ARCH} | sed -e "$expr"`
-		;;
-	esac
 	# The OS release
 	# Debian GNU/NetBSD machines have a different userland, and
 	# thus, need a distinct triplet. However, they do not need
@@ -221,13 +207,13 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
 		release='-gnu'
 		;;
 	    *)
-		release=`echo ${UNAME_RELEASE} | sed -e 's/[-_].*//' | cut -d. -f1,2`
+		release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
 		;;
 	esac
 	# Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM:
 	# contains redundant information, the shorter form:
 	# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used.
-	echo "${machine}-${os}${release}${abi}"
+	echo "${machine}-${os}${release}"
 	exit ;;
     *:Bitrig:*:*)
 	UNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'`
@@ -249,9 +235,6 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
     *:MirBSD:*:*)
 	echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE}
 	exit ;;
-    *:Sortix:*:*)
-	echo ${UNAME_MACHINE}-unknown-sortix
-	exit ;;
     alpha:OSF1:*:*)
 	case $UNAME_RELEASE in
 	*4.0)
@@ -596,9 +579,8 @@ EOF
 	else
 		IBM_ARCH=powerpc
 	fi
-	if [ -x /usr/bin/lslpp ] ; then
-		IBM_REV=`/usr/bin/lslpp -Lqc bos.rte.libc |
-			   awk -F: '{ print $3 }' | sed s/[0-9]*$/0/`
+	if [ -x /usr/bin/oslevel ] ; then
+		IBM_REV=`/usr/bin/oslevel`
 	else
 		IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
 	fi
@@ -844,7 +826,7 @@ EOF
     *:MINGW*:*)
 	echo ${UNAME_MACHINE}-pc-mingw32
 	exit ;;
-    *:MSYS*:*)
+    i*:MSYS*:*)
 	echo ${UNAME_MACHINE}-pc-msys
 	exit ;;
     i*:windows32*:*)
@@ -950,9 +932,6 @@ EOF
     crisv32:Linux:*:*)
 	echo ${UNAME_MACHINE}-axis-linux-${LIBC}
 	exit ;;
-    e2k:Linux:*:*)
-	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
-	exit ;;
     frv:Linux:*:*)
 	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
 	exit ;;
@@ -990,10 +969,10 @@ EOF
 	eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'`
 	test x"${CPU}" != x && { echo "${CPU}-unknown-linux-${LIBC}"; exit; }
 	;;
-    openrisc*:Linux:*:*)
-	echo or1k-unknown-linux-${LIBC}
+    or1k:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
 	exit ;;
-    or32:Linux:*:* | or1k*:Linux:*:*)
+    or32:Linux:*:*)
 	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
 	exit ;;
     padre:Linux:*:*)
@@ -1041,7 +1020,7 @@ EOF
 	echo ${UNAME_MACHINE}-dec-linux-${LIBC}
 	exit ;;
     x86_64:Linux:*:*)
-	echo ${UNAME_MACHINE}-pc-linux-${LIBC}
+	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
 	exit ;;
     xtensa*:Linux:*:*)
 	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
@@ -1281,26 +1260,16 @@ EOF
 	if test "$UNAME_PROCESSOR" = unknown ; then
 	    UNAME_PROCESSOR=powerpc
 	fi
-	if test `echo "$UNAME_RELEASE" | sed -e 's/\..*//'` -le 10 ; then
-	    if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then
-		if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \
-		    (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \
-		    grep IS_64BIT_ARCH >/dev/null
-		then
-		    case $UNAME_PROCESSOR in
-			i386) UNAME_PROCESSOR=x86_64 ;;
-			powerpc) UNAME_PROCESSOR=powerpc64 ;;
-		    esac
-		fi
+	if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then
+	    if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \
+		(CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \
+		grep IS_64BIT_ARCH >/dev/null
+	    then
+		case $UNAME_PROCESSOR in
+		    i386) UNAME_PROCESSOR=x86_64 ;;
+		    powerpc) UNAME_PROCESSOR=powerpc64 ;;
+		esac
 	    fi
-	elif test "$UNAME_PROCESSOR" = i386 ; then
-	    # Avoid executing cc on OS X 10.9, as it ships with a stub
-	    # that puts up a graphical alert prompting to install
-	    # developer tools.  Any system running Mac OS X 10.7 or
-	    # later (Darwin 11 and later) is required to have a 64-bit
-	    # processor. This is not true of the ARM version of Darwin
-	    # that Apple uses in portable devices.
-	    UNAME_PROCESSOR=x86_64
 	fi
 	echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE}
 	exit ;;
@@ -1392,6 +1361,154 @@ EOF
 	exit ;;
 esac
 
+eval $set_cc_for_build
+cat >$dummy.c <<EOF
+#ifdef _SEQUENT_
+# include <sys/types.h>
+# include <sys/utsname.h>
+#endif
+main ()
+{
+#if defined (sony)
+#if defined (MIPSEB)
+  /* BFD wants "bsd" instead of "newsos".  Perhaps BFD should be changed,
+     I don't know....  */
+  printf ("mips-sony-bsd\n"); exit (0);
+#else
+#include <sys/param.h>
+  printf ("m68k-sony-newsos%s\n",
+#ifdef NEWSOS4
+	"4"
+#else
+	""
+#endif
+	); exit (0);
+#endif
+#endif
+
+#if defined (__arm) && defined (__acorn) && defined (__unix)
+  printf ("arm-acorn-riscix\n"); exit (0);
+#endif
+
+#if defined (hp300) && !defined (hpux)
+  printf ("m68k-hp-bsd\n"); exit (0);
+#endif
+
+#if defined (NeXT)
+#if !defined (__ARCHITECTURE__)
+#define __ARCHITECTURE__ "m68k"
+#endif
+  int version;
+  version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`;
+  if (version < 4)
+    printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version);
+  else
+    printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version);
+  exit (0);
+#endif
+
+#if defined (MULTIMAX) || defined (n16)
+#if defined (UMAXV)
+  printf ("ns32k-encore-sysv\n"); exit (0);
+#else
+#if defined (CMU)
+  printf ("ns32k-encore-mach\n"); exit (0);
+#else
+  printf ("ns32k-encore-bsd\n"); exit (0);
+#endif
+#endif
+#endif
+
+#if defined (__386BSD__)
+  printf ("i386-pc-bsd\n"); exit (0);
+#endif
+
+#if defined (sequent)
+#if defined (i386)
+  printf ("i386-sequent-dynix\n"); exit (0);
+#endif
+#if defined (ns32000)
+  printf ("ns32k-sequent-dynix\n"); exit (0);
+#endif
+#endif
+
+#if defined (_SEQUENT_)
+    struct utsname un;
+
+    uname(&un);
+
+    if (strncmp(un.version, "V2", 2) == 0) {
+	printf ("i386-sequent-ptx2\n"); exit (0);
+    }
+    if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */
+	printf ("i386-sequent-ptx1\n"); exit (0);
+    }
+    printf ("i386-sequent-ptx\n"); exit (0);
+
+#endif
+
+#if defined (vax)
+# if !defined (ultrix)
+#  include <sys/param.h>
+#  if defined (BSD)
+#   if BSD == 43
+      printf ("vax-dec-bsd4.3\n"); exit (0);
+#   else
+#    if BSD == 199006
+      printf ("vax-dec-bsd4.3reno\n"); exit (0);
+#    else
+      printf ("vax-dec-bsd\n"); exit (0);
+#    endif
+#   endif
+#  else
+    printf ("vax-dec-bsd\n"); exit (0);
+#  endif
+# else
+    printf ("vax-dec-ultrix\n"); exit (0);
+# endif
+#endif
+
+#if defined (alliant) && defined (i860)
+  printf ("i860-alliant-bsd\n"); exit (0);
+#endif
+
+  exit (1);
+}
+EOF
+
+$CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && SYSTEM_NAME=`$dummy` &&
+	{ echo "$SYSTEM_NAME"; exit; }
+
+# Apollos put the system type in the environment.
+
+test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit; }
+
+# Convex versions that predate uname can use getsysinfo(1)
+
+if [ -x /usr/convex/getsysinfo ]
+then
+    case `getsysinfo -f cpu_type` in
+    c1*)
+	echo c1-convex-bsd
+	exit ;;
+    c2*)
+	if getsysinfo -f scalar_acc
+	then echo c32-convex-bsd
+	else echo c2-convex-bsd
+	fi
+	exit ;;
+    c34*)
+	echo c34-convex-bsd
+	exit ;;
+    c38*)
+	echo c38-convex-bsd
+	exit ;;
+    c4*)
+	echo c4-convex-bsd
+	exit ;;
+    esac
+fi
+
 cat >&2 <<EOF
 $0: unable to guess system type
 
diff --git a/config.sub b/config.sub
index 1acc966..9633db7 100755
--- a/config.sub
+++ b/config.sub
@@ -1,8 +1,8 @@
 #! /bin/sh
 # Configuration validation subroutine script.
-#   Copyright 1992-2015 Free Software Foundation, Inc.
+#   Copyright 1992-2013 Free Software Foundation, Inc.
 
-timestamp='2015-08-20'
+timestamp='2013-08-10'
 
 # This file is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License as published by
@@ -25,7 +25,7 @@ timestamp='2015-08-20'
 # of the GNU General Public License, version 3 ("GPLv3").
 
 
-# Please send patches to <config-patches at gnu.org>.
+# Please send patches with a ChangeLog entry to config-patches at gnu.org.
 #
 # Configuration subroutine to validate and canonicalize a configuration type.
 # Supply the specified configuration type as an argument.
@@ -68,7 +68,7 @@ Report bugs and patches to <config-patches at gnu.org>."
 version="\
 GNU config.sub ($timestamp)
 
-Copyright 1992-2015 Free Software Foundation, Inc.
+Copyright 1992-2013 Free Software Foundation, Inc.
 
 This is free software; see the source for copying conditions.  There is NO
 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
@@ -117,7 +117,7 @@ maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
 case $maybe_os in
   nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \
   linux-musl* | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \
-  knetbsd*-gnu* | netbsd*-gnu* | netbsd*-eabi* | \
+  knetbsd*-gnu* | netbsd*-gnu* | \
   kopensolaris*-gnu* | \
   storm-chaos* | os2-emx* | rtmk-nova*)
     os=-$maybe_os
@@ -255,18 +255,16 @@ case $basic_machine in
 	| arc | arceb \
 	| arm | arm[bl]e | arme[lb] | armv[2-8] | armv[3-8][lb] | armv7[arm] \
 	| avr | avr32 \
-	| ba \
 	| be32 | be64 \
 	| bfin \
 	| c4x | c8051 | clipper \
 	| d10v | d30v | dlx | dsp16xx \
-	| e2k | epiphany \
-	| fido | fr30 | frv | ft32 \
+	| epiphany \
+	| fido | fr30 | frv \
 	| h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
 	| hexagon \
 	| i370 | i860 | i960 | ia64 \
 	| ip2k | iq2000 \
-	| k1om \
 	| le32 | le64 \
 	| lm32 \
 	| m32c | m32r | m32rle | m68000 | m68k | m88k \
@@ -284,10 +282,8 @@ case $basic_machine in
 	| mips64vr5900 | mips64vr5900el \
 	| mipsisa32 | mipsisa32el \
 	| mipsisa32r2 | mipsisa32r2el \
-	| mipsisa32r6 | mipsisa32r6el \
 	| mipsisa64 | mipsisa64el \
 	| mipsisa64r2 | mipsisa64r2el \
-	| mipsisa64r6 | mipsisa64r6el \
 	| mipsisa64sb1 | mipsisa64sb1el \
 	| mipsisa64sr71k | mipsisa64sr71kel \
 	| mipsr5900 | mipsr5900el \
@@ -299,14 +295,14 @@ case $basic_machine in
 	| nds32 | nds32le | nds32be \
 	| nios | nios2 | nios2eb | nios2el \
 	| ns16k | ns32k \
-	| open8 | or1k | or1knd | or32 \
+	| open8 \
+	| or1k | or32 \
 	| pdp10 | pdp11 | pj | pjl \
 	| powerpc | powerpc64 | powerpc64le | powerpcle \
 	| pyramid \
-	| riscv32 | riscv64 \
 	| rl78 | rx \
 	| score \
-	| sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[234]eb | sheb | shbe | shle | sh[1234]le | sh3ele \
+	| sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \
 	| sh64 | sh64le \
 	| sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \
 	| sparcv8 | sparcv9 | sparcv9b | sparcv9v \
@@ -314,7 +310,6 @@ case $basic_machine in
 	| tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \
 	| ubicom32 \
 	| v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \
-	| visium \
 	| we32k \
 	| x86 | xc16x | xstormy16 | xtensa \
 	| z8k | z80)
@@ -329,10 +324,7 @@ case $basic_machine in
 	c6x)
 		basic_machine=tic6x-unknown
 		;;
-	leon|leon[3-9])
-		basic_machine=sparc-$basic_machine
-		;;
-	m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | nvptx | picochip)
+	m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | picochip)
 		basic_machine=$basic_machine-unknown
 		os=-none
 		;;
@@ -377,20 +369,18 @@ case $basic_machine in
 	| alphapca5[67]-* | alpha64pca5[67]-* | arc-* | arceb-* \
 	| arm-*  | armbe-* | armle-* | armeb-* | armv*-* \
 	| avr-* | avr32-* \
-	| ba-* \
 	| be32-* | be64-* \
 	| bfin-* | bs2000-* \
 	| c[123]* | c30-* | [cjt]90-* | c4x-* \
 	| c8051-* | clipper-* | craynv-* | cydra-* \
 	| d10v-* | d30v-* | dlx-* \
-	| e2k-* | elxsi-* \
+	| elxsi-* \
 	| f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \
 	| h8300-* | h8500-* \
 	| hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \
 	| hexagon-* \
 	| i*86-* | i860-* | i960-* | ia64-* \
 	| ip2k-* | iq2000-* \
-	| k1om-* \
 	| le32-* | le64-* \
 	| lm32-* \
 	| m32c-* | m32r-* | m32rle-* \
@@ -410,10 +400,8 @@ case $basic_machine in
 	| mips64vr5900-* | mips64vr5900el-* \
 	| mipsisa32-* | mipsisa32el-* \
 	| mipsisa32r2-* | mipsisa32r2el-* \
-	| mipsisa32r6-* | mipsisa32r6el-* \
 	| mipsisa64-* | mipsisa64el-* \
 	| mipsisa64r2-* | mipsisa64r2el-* \
-	| mipsisa64r6-* | mipsisa64r6el-* \
 	| mipsisa64sb1-* | mipsisa64sb1el-* \
 	| mipsisa64sr71k-* | mipsisa64sr71kel-* \
 	| mipsr5900-* | mipsr5900el-* \
@@ -425,18 +413,16 @@ case $basic_machine in
 	| nios-* | nios2-* | nios2eb-* | nios2el-* \
 	| none-* | np1-* | ns16k-* | ns32k-* \
 	| open8-* \
-	| or1k*-* \
 	| orion-* \
 	| pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \
 	| powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \
 	| pyramid-* \
-	| riscv32-* | riscv64-* \
 	| rl78-* | romp-* | rs6000-* | rx-* \
 	| sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \
 	| shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \
 	| sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \
 	| sparclite-* \
-	| sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx*-* \
+	| sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx?-* \
 	| tahoe-* \
 	| tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \
 	| tile*-* \
@@ -444,7 +430,6 @@ case $basic_machine in
 	| ubicom32-* \
 	| v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \
 	| vax-* \
-	| visium-* \
 	| we32k-* \
 	| x86-* | x86_64-* | xc16x-* | xps100-* \
 	| xstormy16-* | xtensa*-* \
@@ -521,9 +506,6 @@ case $basic_machine in
 		basic_machine=i386-pc
 		os=-aros
 		;;
-        asmjs)
-		basic_machine=asmjs-unknown
-		;;
 	aux)
 		basic_machine=m68k-apple
 		os=-aux
@@ -785,9 +767,6 @@ case $basic_machine in
 		basic_machine=m68k-isi
 		os=-sysv
 		;;
-	leon-*|leon[3-9]-*)
-		basic_machine=sparc-`echo $basic_machine | sed 's/-.*//'`
-		;;
 	m68knommu)
 		basic_machine=m68k-unknown
 		os=-linux
@@ -843,10 +822,6 @@ case $basic_machine in
 		basic_machine=powerpc-unknown
 		os=-morphos
 		;;
-	moxiebox)
-		basic_machine=moxie-unknown
-		os=-moxiebox
-		;;
 	msdos)
 		basic_machine=i386-pc
 		os=-msdos
@@ -1379,7 +1354,7 @@ case $os in
 	      | -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \
 	      | -sym* | -kopensolaris* | -plan9* \
 	      | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \
-	      | -aos* | -aros* | -cloudabi* | -sortix* \
+	      | -aos* | -aros* \
 	      | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
 	      | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
 	      | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \
@@ -1392,14 +1367,14 @@ case $os in
 	      | -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
 	      | -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \
 	      | -linux-newlib* | -linux-musl* | -linux-uclibc* \
-	      | -uxpv* | -beos* | -mpeix* | -udk* | -moxiebox* \
+	      | -uxpv* | -beos* | -mpeix* | -udk* \
 	      | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \
 	      | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
 	      | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \
 	      | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \
 	      | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \
 	      | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \
-	      | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es* | -tirtos*)
+	      | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es*)
 	# Remember, each alternative MUST END IN *, to match a version number.
 		;;
 	-qnx*)
@@ -1617,6 +1592,9 @@ case $basic_machine in
 	mips*-*)
 		os=-elf
 		;;
+	or1k-*)
+		os=-elf
+		;;
 	or32-*)
 		os=-coff
 		;;
diff --git a/configure b/configure
index 5b3143e..158bcb7 100755
--- a/configure
+++ b/configure
@@ -1,6 +1,6 @@
 #! /bin/sh
 # Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.69 for ceph 10.0.5.
+# Generated by GNU Autoconf 2.69 for ceph 10.1.0.
 #
 # Report bugs to <ceph-devel at vger.kernel.org>.
 #
@@ -590,8 +590,8 @@ MAKEFLAGS=
 # Identity of this package.
 PACKAGE_NAME='ceph'
 PACKAGE_TARNAME='ceph'
-PACKAGE_VERSION='10.0.5'
-PACKAGE_STRING='ceph 10.0.5'
+PACKAGE_VERSION='10.1.0'
+PACKAGE_STRING='ceph 10.1.0'
 PACKAGE_BUGREPORT='ceph-devel at vger.kernel.org'
 PACKAGE_URL=''
 
@@ -647,6 +647,8 @@ PYTHON_VERSION
 PYTHON
 WITH_BUILD_TESTS_FALSE
 WITH_BUILD_TESTS_TRUE
+WITH_OPENLDAP_FALSE
+WITH_OPENLDAP_TRUE
 WITH_EVENTFD_FALSE
 WITH_EVENTFD_TRUE
 systemd_unit_dir
@@ -777,6 +779,9 @@ WITH_BETTER_YASM_ELF64_TRUE
 WITH_GOOD_YASM_ELF64_FALSE
 WITH_GOOD_YASM_ELF64_TRUE
 YASM_CHECK
+PYTHON_LDFLAGS
+PYTHON_CFLAGS
+PYTHON_CONFIG_CHECK
 CYTHON_CHECK
 ENABLE_SERVER_FALSE
 ENABLE_SERVER_TRUE
@@ -858,7 +863,6 @@ CCASFLAGS
 CCAS
 CXXCPP
 CPP
-LT_SYS_LIBRARY_PATH
 OTOOL64
 OTOOL
 LIPO
@@ -930,7 +934,6 @@ infodir
 docdir
 oldincludedir
 includedir
-runstatedir
 localstatedir
 sharedstatedir
 sysconfdir
@@ -958,7 +961,6 @@ enable_shared
 enable_static
 with_pic
 enable_fast_install
-with_aix_soname
 with_gnu_ld
 with_sysroot
 enable_libtool_lock
@@ -1004,6 +1006,7 @@ with_babeltrace
 enable_valgrind
 with_systemd_unit_dir
 with_eventfd
+with_openldap
 '
       ac_precious_vars='build_alias
 host_alias
@@ -1016,7 +1019,6 @@ CPPFLAGS
 CCC
 CC
 CFLAGS
-LT_SYS_LIBRARY_PATH
 CPP
 CXXCPP
 CCAS
@@ -1075,7 +1077,6 @@ datadir='${datarootdir}'
 sysconfdir='${prefix}/etc'
 sharedstatedir='${prefix}/com'
 localstatedir='${prefix}/var'
-runstatedir='${localstatedir}/run'
 includedir='${prefix}/include'
 oldincludedir='/usr/include'
 docdir='${datarootdir}/doc/${PACKAGE_TARNAME}'
@@ -1328,15 +1329,6 @@ do
   | -silent | --silent | --silen | --sile | --sil)
     silent=yes ;;
 
-  -runstatedir | --runstatedir | --runstatedi | --runstated \
-  | --runstate | --runstat | --runsta | --runst | --runs \
-  | --run | --ru | --r)
-    ac_prev=runstatedir ;;
-  -runstatedir=* | --runstatedir=* | --runstatedi=* | --runstated=* \
-  | --runstate=* | --runstat=* | --runsta=* | --runst=* | --runs=* \
-  | --run=* | --ru=* | --r=*)
-    runstatedir=$ac_optarg ;;
-
   -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
     ac_prev=sbindir ;;
   -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
@@ -1474,7 +1466,7 @@ fi
 for ac_var in	exec_prefix prefix bindir sbindir libexecdir datarootdir \
 		datadir sysconfdir sharedstatedir localstatedir includedir \
 		oldincludedir docdir infodir htmldir dvidir pdfdir psdir \
-		libdir localedir mandir runstatedir
+		libdir localedir mandir
 do
   eval ac_val=\$$ac_var
   # Remove trailing slashes.
@@ -1587,7 +1579,7 @@ if test "$ac_init_help" = "long"; then
   # Omit some internal or obsolete options to make the list less imposing.
   # This message is too long to be a string in the A/UX 3.1 sh.
   cat <<_ACEOF
-\`configure' configures ceph 10.0.5 to adapt to many kinds of systems.
+\`configure' configures ceph 10.1.0 to adapt to many kinds of systems.
 
 Usage: $0 [OPTION]... [VAR=VALUE]...
 
@@ -1627,7 +1619,6 @@ Fine tuning of the installation directories:
   --sysconfdir=DIR        read-only single-machine data [PREFIX/etc]
   --sharedstatedir=DIR    modifiable architecture-independent data [PREFIX/com]
   --localstatedir=DIR     modifiable single-machine data [PREFIX/var]
-  --runstatedir=DIR       modifiable per-process data [LOCALSTATEDIR/run]
   --libdir=DIR            object code libraries [EPREFIX/lib]
   --includedir=DIR        C header files [PREFIX/include]
   --oldincludedir=DIR     C header files for non-gcc [/usr/include]
@@ -1659,7 +1650,7 @@ fi
 
 if test -n "$ac_init_help"; then
   case $ac_init_help in
-     short | recursive ) echo "Configuration of ceph 10.0.5:";;
+     short | recursive ) echo "Configuration of ceph 10.1.0:";;
    esac
   cat <<\_ACEOF
 
@@ -1693,15 +1684,12 @@ Optional Packages:
   --with-man-pages        build man pages
   --with-pic[=PKGS]       try to use only PIC/non-PIC objects [default=use
                           both]
-  --with-aix-soname=aix|svr4|both
-                          shared library versioning (aka "SONAME") variant to
-                          provide on AIX, [default=aix].
   --with-gnu-ld           assume the C compiler uses GNU ld [default=no]
-  --with-sysroot[=DIR]    Search for dependent libraries within DIR (or the
-                          compiler's sysroot if not specified).
+  --with-sysroot=DIR Search for dependent libraries within DIR
+                        (or the compiler's sysroot if not specified).
   --with-rados            build with librados support
   --with-rbd              build rbd files
-  --with-cython           build python bindings for librbd
+  --with-cython           build python bindings for libraries
   --with-cephfs           build cephfs files
   --with-radosgw          build RADOS gateway
   --with-selinux          build SELinux policy
@@ -1735,6 +1723,7 @@ Optional Packages:
                           systemd unit directory [SYSTEMD_UNIT_DIR] Defaults
                           to the correct value for debian /etc/systemd/system/
   --without-eventfd       disable eventfd [default=no]
+  --without-openldap      Disable OpenLDAP support (RGW)
 
 Some influential environment variables:
   CXX         C++ compiler command
@@ -1746,8 +1735,6 @@ Some influential environment variables:
               you have headers in a nonstandard directory <include dir>
   CC          C compiler command
   CFLAGS      C compiler flags
-  LT_SYS_LIBRARY_PATH
-              User-defined run-time library search path.
   CPP         C preprocessor
   CXXCPP      C++ preprocessor
   CCAS        assembler compiler command (defaults to CC)
@@ -1846,7 +1833,7 @@ fi
 test -n "$ac_init_help" && exit $ac_status
 if $ac_init_version; then
   cat <<\_ACEOF
-ceph configure 10.0.5
+ceph configure 10.1.0
 generated by GNU Autoconf 2.69
 
 Copyright (C) 2012 Free Software Foundation, Inc.
@@ -2922,7 +2909,7 @@ cat >config.log <<_ACEOF
 This file contains any messages produced by compilers while
 running configure, to aid debugging if configure makes a mistake.
 
-It was created by ceph $as_me 10.0.5, which was
+It was created by ceph $as_me 10.1.0, which was
 generated by GNU Autoconf 2.69.  Invocation command line was
 
   $ $0 $@
@@ -4236,8 +4223,8 @@ test -n "$target_alias" &&
   program_prefix=${target_alias}-
 
 # Fix automake problems in 1.12
-# Expand $ac_aux_dir to an absolute path.
-am_aux_dir=`cd "$ac_aux_dir" && pwd`
+# expand $ac_aux_dir to an absolute path
+am_aux_dir=`cd $ac_aux_dir && pwd`
 
 ac_ext=c
 ac_cpp='$CPP $CPPFLAGS'
@@ -5020,8 +5007,8 @@ esac
 
 
 
-macro_version='2.4.6'
-macro_revision='2.4.6'
+macro_version='2.4.2'
+macro_revision='1.3337'
 
 
 
@@ -5035,7 +5022,7 @@ macro_revision='2.4.6'
 
 
 
-ltmain=$ac_aux_dir/ltmain.sh
+ltmain="$ac_aux_dir/ltmain.sh"
 
 # Backslashify metacharacters that are still active within
 # double-quoted strings.
@@ -5084,7 +5071,7 @@ func_echo_all ()
     $ECHO ""
 }
 
-case $ECHO in
+case "$ECHO" in
   printf*) { $as_echo "$as_me:${as_lineno-$LINENO}: result: printf" >&5
 $as_echo "printf" >&6; } ;;
   print*) { $as_echo "$as_me:${as_lineno-$LINENO}: result: print -r" >&5
@@ -5407,19 +5394,19 @@ test -z "$GREP" && GREP=grep
 
 # Check whether --with-gnu-ld was given.
 if test "${with_gnu_ld+set}" = set; then :
-  withval=$with_gnu_ld; test no = "$withval" || with_gnu_ld=yes
+  withval=$with_gnu_ld; test "$withval" = no || with_gnu_ld=yes
 else
   with_gnu_ld=no
 fi
 
 ac_prog=ld
-if test yes = "$GCC"; then
+if test "$GCC" = yes; then
   # Check if gcc -print-prog-name=ld gives a path.
   { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ld used by $CC" >&5
 $as_echo_n "checking for ld used by $CC... " >&6; }
   case $host in
   *-*-mingw*)
-    # gcc leaves a trailing carriage return, which upsets mingw
+    # gcc leaves a trailing carriage return which upsets mingw
     ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;;
   *)
     ac_prog=`($CC -print-prog-name=ld) 2>&5` ;;
@@ -5433,7 +5420,7 @@ $as_echo_n "checking for ld used by $CC... " >&6; }
       while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do
 	ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"`
       done
-      test -z "$LD" && LD=$ac_prog
+      test -z "$LD" && LD="$ac_prog"
       ;;
   "")
     # If it fails, then pretend we aren't using GCC.
@@ -5444,7 +5431,7 @@ $as_echo_n "checking for ld used by $CC... " >&6; }
     with_gnu_ld=unknown
     ;;
   esac
-elif test yes = "$with_gnu_ld"; then
+elif test "$with_gnu_ld" = yes; then
   { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU ld" >&5
 $as_echo_n "checking for GNU ld... " >&6; }
 else
@@ -5455,32 +5442,32 @@ if ${lt_cv_path_LD+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   if test -z "$LD"; then
-  lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR
+  lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
   for ac_dir in $PATH; do
-    IFS=$lt_save_ifs
+    IFS="$lt_save_ifs"
     test -z "$ac_dir" && ac_dir=.
     if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then
-      lt_cv_path_LD=$ac_dir/$ac_prog
+      lt_cv_path_LD="$ac_dir/$ac_prog"
       # Check to see if the program is GNU ld.  I'd rather use --version,
       # but apparently some variants of GNU ld only accept -v.
       # Break only if it was the GNU/non-GNU ld that we prefer.
       case `"$lt_cv_path_LD" -v 2>&1 </dev/null` in
       *GNU* | *'with BFD'*)
-	test no != "$with_gnu_ld" && break
+	test "$with_gnu_ld" != no && break
 	;;
       *)
-	test yes != "$with_gnu_ld" && break
+	test "$with_gnu_ld" != yes && break
 	;;
       esac
     fi
   done
-  IFS=$lt_save_ifs
+  IFS="$lt_save_ifs"
 else
-  lt_cv_path_LD=$LD # Let the user override the test with a path.
+  lt_cv_path_LD="$LD" # Let the user override the test with a path.
 fi
 fi
 
-LD=$lt_cv_path_LD
+LD="$lt_cv_path_LD"
 if test -n "$LD"; then
   { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LD" >&5
 $as_echo "$LD" >&6; }
@@ -5523,38 +5510,33 @@ if ${lt_cv_path_NM+:} false; then :
 else
   if test -n "$NM"; then
   # Let the user override the test.
-  lt_cv_path_NM=$NM
+  lt_cv_path_NM="$NM"
 else
-  lt_nm_to_check=${ac_tool_prefix}nm
+  lt_nm_to_check="${ac_tool_prefix}nm"
   if test -n "$ac_tool_prefix" && test "$build" = "$host"; then
     lt_nm_to_check="$lt_nm_to_check nm"
   fi
   for lt_tmp_nm in $lt_nm_to_check; do
-    lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR
+    lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
     for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do
-      IFS=$lt_save_ifs
+      IFS="$lt_save_ifs"
       test -z "$ac_dir" && ac_dir=.
-      tmp_nm=$ac_dir/$lt_tmp_nm
-      if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext"; then
+      tmp_nm="$ac_dir/$lt_tmp_nm"
+      if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext" ; then
 	# Check to see if the nm accepts a BSD-compat flag.
-	# Adding the 'sed 1q' prevents false positives on HP-UX, which says:
+	# Adding the `sed 1q' prevents false positives on HP-UX, which says:
 	#   nm: unknown option "B" ignored
 	# Tru64's nm complains that /dev/null is an invalid object file
-	# MSYS converts /dev/null to NUL, MinGW nm treats NUL as empty
-	case $build_os in
-	mingw*) lt_bad_file=conftest.nm/nofile ;;
-	*) lt_bad_file=/dev/null ;;
-	esac
-	case `"$tmp_nm" -B $lt_bad_file 2>&1 | sed '1q'` in
-	*$lt_bad_file* | *'Invalid file or object type'*)
+	case `"$tmp_nm" -B /dev/null 2>&1 | sed '1q'` in
+	*/dev/null* | *'Invalid file or object type'*)
 	  lt_cv_path_NM="$tmp_nm -B"
-	  break 2
+	  break
 	  ;;
 	*)
 	  case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in
 	  */dev/null*)
 	    lt_cv_path_NM="$tmp_nm -p"
-	    break 2
+	    break
 	    ;;
 	  *)
 	    lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but
@@ -5565,15 +5547,15 @@ else
 	esac
       fi
     done
-    IFS=$lt_save_ifs
+    IFS="$lt_save_ifs"
   done
   : ${lt_cv_path_NM=no}
 fi
 fi
 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_NM" >&5
 $as_echo "$lt_cv_path_NM" >&6; }
-if test no != "$lt_cv_path_NM"; then
-  NM=$lt_cv_path_NM
+if test "$lt_cv_path_NM" != "no"; then
+  NM="$lt_cv_path_NM"
 else
   # Didn't find any BSD compatible name lister, look for dumpbin.
   if test -n "$DUMPBIN"; then :
@@ -5679,9 +5661,9 @@ esac
   fi
 fi
 
-    case `$DUMPBIN -symbols -headers /dev/null 2>&1 | sed '1q'` in
+    case `$DUMPBIN -symbols /dev/null 2>&1 | sed '1q'` in
     *COFF*)
-      DUMPBIN="$DUMPBIN -symbols -headers"
+      DUMPBIN="$DUMPBIN -symbols"
       ;;
     *)
       DUMPBIN=:
@@ -5689,8 +5671,8 @@ fi
     esac
   fi
 
-  if test : != "$DUMPBIN"; then
-    NM=$DUMPBIN
+  if test "$DUMPBIN" != ":"; then
+    NM="$DUMPBIN"
   fi
 fi
 test -z "$NM" && NM=nm
@@ -5741,7 +5723,7 @@ if ${lt_cv_sys_max_cmd_len+:} false; then :
   $as_echo_n "(cached) " >&6
 else
     i=0
-  teststring=ABCD
+  teststring="ABCD"
 
   case $build_os in
   msdosdjgpp*)
@@ -5781,7 +5763,7 @@ else
     lt_cv_sys_max_cmd_len=8192;
     ;;
 
-  bitrig* | darwin* | dragonfly* | freebsd* | netbsd* | openbsd*)
+  netbsd* | freebsd* | openbsd* | darwin* | dragonfly*)
     # This has been around since 386BSD, at least.  Likely further.
     if test -x /sbin/sysctl; then
       lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax`
@@ -5832,22 +5814,22 @@ else
   *)
     lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null`
     if test -n "$lt_cv_sys_max_cmd_len" && \
-       test undefined != "$lt_cv_sys_max_cmd_len"; then
+	test undefined != "$lt_cv_sys_max_cmd_len"; then
       lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4`
       lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3`
     else
       # Make teststring a little bigger before we do anything with it.
       # a 1K string should be a reasonable start.
-      for i in 1 2 3 4 5 6 7 8; do
+      for i in 1 2 3 4 5 6 7 8 ; do
         teststring=$teststring$teststring
       done
       SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}}
       # If test is not a shell built-in, we'll probably end up computing a
       # maximum length that is only half of the actual maximum length, but
       # we can't tell.
-      while { test X`env echo "$teststring$teststring" 2>/dev/null` \
+      while { test "X"`env echo "$teststring$teststring" 2>/dev/null` \
 	         = "X$teststring$teststring"; } >/dev/null 2>&1 &&
-	      test 17 != "$i" # 1/2 MB should be enough
+	      test $i != 17 # 1/2 MB should be enough
       do
         i=`expr $i + 1`
         teststring=$teststring$teststring
@@ -5865,7 +5847,7 @@ else
 
 fi
 
-if test -n "$lt_cv_sys_max_cmd_len"; then
+if test -n $lt_cv_sys_max_cmd_len ; then
   { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_sys_max_cmd_len" >&5
 $as_echo "$lt_cv_sys_max_cmd_len" >&6; }
 else
@@ -5883,6 +5865,30 @@ max_cmd_len=$lt_cv_sys_max_cmd_len
 : ${MV="mv -f"}
 : ${RM="rm -f"}
 
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the shell understands some XSI constructs" >&5
+$as_echo_n "checking whether the shell understands some XSI constructs... " >&6; }
+# Try some XSI features
+xsi_shell=no
+( _lt_dummy="a/b/c"
+  test "${_lt_dummy##*/},${_lt_dummy%/*},${_lt_dummy#??}"${_lt_dummy%"$_lt_dummy"}, \
+      = c,a/b,b/c, \
+    && eval 'test $(( 1 + 1 )) -eq 2 \
+    && test "${#_lt_dummy}" -eq 5' ) >/dev/null 2>&1 \
+  && xsi_shell=yes
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $xsi_shell" >&5
+$as_echo "$xsi_shell" >&6; }
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the shell understands \"+=\"" >&5
+$as_echo_n "checking whether the shell understands \"+=\"... " >&6; }
+lt_shell_append=no
+( foo=bar; set foo baz; eval "$1+=\$2" && test "$foo" = barbaz ) \
+    >/dev/null 2>&1 \
+  && lt_shell_append=yes
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_shell_append" >&5
+$as_echo "$lt_shell_append" >&6; }
+
+
 if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then
   lt_unset=unset
 else
@@ -6005,13 +6011,13 @@ esac
 reload_cmds='$LD$reload_flag -o $output$reload_objs'
 case $host_os in
   cygwin* | mingw* | pw32* | cegcc*)
-    if test yes != "$GCC"; then
+    if test "$GCC" != yes; then
       reload_cmds=false
     fi
     ;;
   darwin*)
-    if test yes = "$GCC"; then
-      reload_cmds='$LTCC $LTCFLAGS -nostdlib $wl-r -o $output$reload_objs'
+    if test "$GCC" = yes; then
+      reload_cmds='$LTCC $LTCFLAGS -nostdlib ${wl}-r -o $output$reload_objs'
     else
       reload_cmds='$LD$reload_flag -o $output$reload_objs'
     fi
@@ -6139,13 +6145,13 @@ lt_cv_deplibs_check_method='unknown'
 # Need to set the preceding variable on all platforms that support
 # interlibrary dependencies.
 # 'none' -- dependencies not supported.
-# 'unknown' -- same as none, but documents that we really don't know.
+# `unknown' -- same as none, but documents that we really don't know.
 # 'pass_all' -- all dependencies passed with no checks.
 # 'test_compile' -- check by making test program.
 # 'file_magic [[regex]]' -- check by looking for files in library path
-# that responds to the $file_magic_cmd with a given extended regex.
-# If you have 'file' or equivalent on your system and you're not sure
-# whether 'pass_all' will *always* work, you probably want this one.
+# which responds to the $file_magic_cmd with a given extended regex.
+# If you have `file' or equivalent on your system and you're not sure
+# whether `pass_all' will *always* work, you probably want this one.
 
 case $host_os in
 aix[4-9]*)
@@ -6172,7 +6178,8 @@ mingw* | pw32*)
   # Base MSYS/MinGW do not provide the 'file' command needed by
   # func_win32_libid shell function, so use a weaker test based on 'objdump',
   # unless we find 'file', for example because we are cross-compiling.
-  if ( file / ) >/dev/null 2>&1; then
+  # func_win32_libid assumes BSD nm, so disallow it if using MS dumpbin.
+  if ( test "$lt_cv_nm_interface" = "BSD nm" && file / ) >/dev/null 2>&1; then
     lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL'
     lt_cv_file_magic_cmd='func_win32_libid'
   else
@@ -6268,8 +6275,8 @@ newos6*)
   lt_cv_deplibs_check_method=pass_all
   ;;
 
-openbsd* | bitrig*)
-  if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then
+openbsd*)
+  if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
     lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|\.so|_pic\.a)$'
   else
     lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$'
@@ -6322,9 +6329,6 @@ sysv4 | sysv4.3*)
 tpf*)
   lt_cv_deplibs_check_method=pass_all
   ;;
-os2*)
-  lt_cv_deplibs_check_method=pass_all
-  ;;
 esac
 
 fi
@@ -6482,8 +6486,8 @@ else
 
 case $host_os in
 cygwin* | mingw* | pw32* | cegcc*)
-  # two different shell functions defined in ltmain.sh;
-  # decide which one to use based on capabilities of $DLLTOOL
+  # two different shell functions defined in ltmain.sh
+  # decide which to use based on capabilities of $DLLTOOL
   case `$DLLTOOL --help 2>&1` in
   *--identify-strict*)
     lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib
@@ -6495,7 +6499,7 @@ cygwin* | mingw* | pw32* | cegcc*)
   ;;
 *)
   # fallback: assume linklib IS sharedlib
-  lt_cv_sharedlib_from_linklib_cmd=$ECHO
+  lt_cv_sharedlib_from_linklib_cmd="$ECHO"
   ;;
 esac
 
@@ -6649,7 +6653,7 @@ if ac_fn_c_try_compile "$LINENO"; then :
   ac_status=$?
   $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
   test $ac_status = 0; }
-      if test 0 -eq "$ac_status"; then
+      if test "$ac_status" -eq 0; then
 	# Ensure the archiver fails upon bogus file names.
 	rm -f conftest.$ac_objext libconftest.a
 	{ { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$lt_ar_try\""; } >&5
@@ -6657,7 +6661,7 @@ if ac_fn_c_try_compile "$LINENO"; then :
   ac_status=$?
   $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
   test $ac_status = 0; }
-	if test 0 -ne "$ac_status"; then
+	if test "$ac_status" -ne 0; then
           lt_cv_ar_at_file=@
         fi
       fi
@@ -6670,7 +6674,7 @@ fi
 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ar_at_file" >&5
 $as_echo "$lt_cv_ar_at_file" >&6; }
 
-if test no = "$lt_cv_ar_at_file"; then
+if test "x$lt_cv_ar_at_file" = xno; then
   archiver_list_spec=
 else
   archiver_list_spec=$lt_cv_ar_at_file
@@ -6887,7 +6891,7 @@ old_postuninstall_cmds=
 
 if test -n "$RANLIB"; then
   case $host_os in
-  bitrig* | openbsd*)
+  openbsd*)
     old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$tool_oldlib"
     ;;
   *)
@@ -7019,7 +7023,7 @@ cygwin* | mingw* | pw32* | cegcc*)
   symcode='[ABCDGISTW]'
   ;;
 hpux*)
-  if test ia64 = "$host_cpu"; then
+  if test "$host_cpu" = ia64; then
     symcode='[ABCDEGRST]'
   fi
   ;;
@@ -7052,44 +7056,14 @@ case `$NM -V 2>&1` in
   symcode='[ABCDGIRSTW]' ;;
 esac
 
-if test "$lt_cv_nm_interface" = "MS dumpbin"; then
-  # Gets list of data symbols to import.
-  lt_cv_sys_global_symbol_to_import="sed -n -e 's/^I .* \(.*\)$/\1/p'"
-  # Adjust the below global symbol transforms to fixup imported variables.
-  lt_cdecl_hook=" -e 's/^I .* \(.*\)$/extern __declspec(dllimport) char \1;/p'"
-  lt_c_name_hook=" -e 's/^I .* \(.*\)$/  {\"\1\", (void *) 0},/p'"
-  lt_c_name_lib_hook="\
-  -e 's/^I .* \(lib.*\)$/  {\"\1\", (void *) 0},/p'\
-  -e 's/^I .* \(.*\)$/  {\"lib\1\", (void *) 0},/p'"
-else
-  # Disable hooks by default.
-  lt_cv_sys_global_symbol_to_import=
-  lt_cdecl_hook=
-  lt_c_name_hook=
-  lt_c_name_lib_hook=
-fi
-
 # Transform an extracted symbol line into a proper C declaration.
 # Some systems (esp. on ia64) link data and code symbols differently,
 # so use this general approach.
-lt_cv_sys_global_symbol_to_cdecl="sed -n"\
-$lt_cdecl_hook\
-" -e 's/^T .* \(.*\)$/extern int \1();/p'"\
-" -e 's/^$symcode$symcode* .* \(.*\)$/extern char \1;/p'"
+lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'"
 
 # Transform an extracted symbol line into symbol name and symbol address
-lt_cv_sys_global_symbol_to_c_name_address="sed -n"\
-$lt_c_name_hook\
-" -e 's/^: \(.*\) .*$/  {\"\1\", (void *) 0},/p'"\
-" -e 's/^$symcode$symcode* .* \(.*\)$/  {\"\1\", (void *) \&\1},/p'"
-
-# Transform an extracted symbol line into symbol name with lib prefix and
-# symbol address.
-lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n"\
-$lt_c_name_lib_hook\
-" -e 's/^: \(.*\) .*$/  {\"\1\", (void *) 0},/p'"\
-" -e 's/^$symcode$symcode* .* \(lib.*\)$/  {\"\1\", (void *) \&\1},/p'"\
-" -e 's/^$symcode$symcode* .* \(.*\)$/  {\"lib\1\", (void *) \&\1},/p'"
+lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([^ ]*\)[ ]*$/  {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/  {\"\2\", (void *) \&\2},/p'"
+lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n -e 's/^: \([^ ]*\)[ ]*$/  {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([^ ]*\) \(lib[^ ]*\)$/  {\"\2\", (void *) \&\2},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/  {\"lib\2\", (void *) \&\2},/p'"
 
 # Handle CRLF in mingw tool chain
 opt_cr=
@@ -7107,24 +7081,21 @@ for ac_symprfx in "" "_"; do
 
   # Write the raw and C identifiers.
   if test "$lt_cv_nm_interface" = "MS dumpbin"; then
-    # Fake it for dumpbin and say T for any non-static function,
-    # D for any global variable and I for any imported variable.
+    # Fake it for dumpbin and say T for any non-static function
+    # and D for any global variable.
     # Also find C++ and __fastcall symbols from MSVC++,
     # which start with @ or ?.
     lt_cv_sys_global_symbol_pipe="$AWK '"\
 "     {last_section=section; section=\$ 3};"\
 "     /^COFF SYMBOL TABLE/{for(i in hide) delete hide[i]};"\
 "     /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\
-"     /^ *Symbol name *: /{split(\$ 0,sn,\":\"); si=substr(sn[2],2)};"\
-"     /^ *Type *: code/{print \"T\",si,substr(si,length(prfx))};"\
-"     /^ *Type *: data/{print \"I\",si,substr(si,length(prfx))};"\
 "     \$ 0!~/External *\|/{next};"\
 "     / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\
 "     {if(hide[section]) next};"\
-"     {f=\"D\"}; \$ 0~/\(\).*\|/{f=\"T\"};"\
-"     {split(\$ 0,a,/\||\r/); split(a[2],s)};"\
-"     s[1]~/^[@?]/{print f,s[1],s[1]; next};"\
-"     s[1]~prfx {split(s[1],t,\"@\"); print f,t[1],substr(t[1],length(prfx))}"\
+"     {f=0}; \$ 0~/\(\).*\|/{f=1}; {printf f ? \"T \" : \"D \"};"\
+"     {split(\$ 0, a, /\||\r/); split(a[2], s)};"\
+"     s[1]~/^[@?]/{print s[1], s[1]; next};"\
+"     s[1]~prfx {split(s[1],t,\"@\"); print t[1], substr(t[1],length(prfx))}"\
 "     ' prfx=^$ac_symprfx"
   else
     lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[	 ]\($symcode$symcode*\)[	 ][	 ]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'"
@@ -7172,11 +7143,11 @@ _LT_EOF
 	if $GREP ' nm_test_func$' "$nlist" >/dev/null; then
 	  cat <<_LT_EOF > conftest.$ac_ext
 /* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests.  */
-#if defined _WIN32 || defined __CYGWIN__ || defined _WIN32_WCE
-/* DATA imports from DLLs on WIN32 can't be const, because runtime
+#if defined(_WIN32) || defined(__CYGWIN__) || defined(_WIN32_WCE)
+/* DATA imports from DLLs on WIN32 con't be const, because runtime
    relocations are performed -- see ld's documentation on pseudo-relocs.  */
 # define LT_DLSYM_CONST
-#elif defined __osf__
+#elif defined(__osf__)
 /* This system does not cope well with relocations in const data.  */
 # define LT_DLSYM_CONST
 #else
@@ -7202,7 +7173,7 @@ lt__PROGRAM__LTX_preloaded_symbols[] =
 {
   { "@PROGRAM@", (void *) 0 },
 _LT_EOF
-	  $SED "s/^$symcode$symcode* .* \(.*\)$/  {\"\1\", (void *) \&\1},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext
+	  $SED "s/^$symcode$symcode* \(.*\) \(.*\)$/  {\"\2\", (void *) \&\2},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext
 	  cat <<\_LT_EOF >> conftest.$ac_ext
   {0, (void *) 0}
 };
@@ -7222,13 +7193,13 @@ _LT_EOF
 	  mv conftest.$ac_objext conftstm.$ac_objext
 	  lt_globsym_save_LIBS=$LIBS
 	  lt_globsym_save_CFLAGS=$CFLAGS
-	  LIBS=conftstm.$ac_objext
+	  LIBS="conftstm.$ac_objext"
 	  CFLAGS="$CFLAGS$lt_prog_compiler_no_builtin_flag"
 	  if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5
   (eval $ac_link) 2>&5
   ac_status=$?
   $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
-  test $ac_status = 0; } && test -s conftest$ac_exeext; then
+  test $ac_status = 0; } && test -s conftest${ac_exeext}; then
 	    pipe_works=yes
 	  fi
 	  LIBS=$lt_globsym_save_LIBS
@@ -7249,7 +7220,7 @@ _LT_EOF
   rm -rf conftest* conftst*
 
   # Do not use the global_symbol_pipe unless it works.
-  if test yes = "$pipe_works"; then
+  if test "$pipe_works" = yes; then
     break
   else
     lt_cv_sys_global_symbol_pipe=
@@ -7302,16 +7273,6 @@ fi
 
 
 
-
-
-
-
-
-
-
-
-
-
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for sysroot" >&5
 $as_echo_n "checking for sysroot... " >&6; }
 
@@ -7324,9 +7285,9 @@ fi
 
 
 lt_sysroot=
-case $with_sysroot in #(
+case ${with_sysroot} in #(
  yes)
-   if test yes = "$GCC"; then
+   if test "$GCC" = yes; then
      lt_sysroot=`$CC --print-sysroot 2>/dev/null`
    fi
    ;; #(
@@ -7336,8 +7297,8 @@ case $with_sysroot in #(
  no|'')
    ;; #(
  *)
-   { $as_echo "$as_me:${as_lineno-$LINENO}: result: $with_sysroot" >&5
-$as_echo "$with_sysroot" >&6; }
+   { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${with_sysroot}" >&5
+$as_echo "${with_sysroot}" >&6; }
    as_fn_error $? "The sysroot must be an absolute path." "$LINENO" 5
    ;;
 esac
@@ -7349,99 +7310,18 @@ $as_echo "${lt_sysroot:-no}" >&6; }
 
 
 
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a working dd" >&5
-$as_echo_n "checking for a working dd... " >&6; }
-if ${ac_cv_path_lt_DD+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  printf 0123456789abcdef0123456789abcdef >conftest.i
-cat conftest.i conftest.i >conftest2.i
-: ${lt_DD:=$DD}
-if test -z "$lt_DD"; then
-  ac_path_lt_DD_found=false
-  # Loop through the user's path and test for each of PROGNAME-LIST
-  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-    for ac_prog in dd; do
-    for ac_exec_ext in '' $ac_executable_extensions; do
-      ac_path_lt_DD="$as_dir/$ac_prog$ac_exec_ext"
-      as_fn_executable_p "$ac_path_lt_DD" || continue
-if "$ac_path_lt_DD" bs=32 count=1 <conftest2.i >conftest.out 2>/dev/null; then
-  cmp -s conftest.i conftest.out \
-  && ac_cv_path_lt_DD="$ac_path_lt_DD" ac_path_lt_DD_found=:
-fi
-      $ac_path_lt_DD_found && break 3
-    done
-  done
-  done
-IFS=$as_save_IFS
-  if test -z "$ac_cv_path_lt_DD"; then
-    :
-  fi
-else
-  ac_cv_path_lt_DD=$lt_DD
-fi
-
-rm -f conftest.i conftest2.i conftest.out
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_lt_DD" >&5
-$as_echo "$ac_cv_path_lt_DD" >&6; }
-
-
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to truncate binary pipes" >&5
-$as_echo_n "checking how to truncate binary pipes... " >&6; }
-if ${lt_cv_truncate_bin+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  printf 0123456789abcdef0123456789abcdef >conftest.i
-cat conftest.i conftest.i >conftest2.i
-lt_cv_truncate_bin=
-if "$ac_cv_path_lt_DD" bs=32 count=1 <conftest2.i >conftest.out 2>/dev/null; then
-  cmp -s conftest.i conftest.out \
-  && lt_cv_truncate_bin="$ac_cv_path_lt_DD bs=4096 count=1"
-fi
-rm -f conftest.i conftest2.i conftest.out
-test -z "$lt_cv_truncate_bin" && lt_cv_truncate_bin="$SED -e 4q"
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_truncate_bin" >&5
-$as_echo "$lt_cv_truncate_bin" >&6; }
-
-
-
-
-
-
-
-# Calculate cc_basename.  Skip known compiler wrappers and cross-prefix.
-func_cc_basename ()
-{
-    for cc_temp in $*""; do
-      case $cc_temp in
-        compile | *[\\/]compile | ccache | *[\\/]ccache ) ;;
-        distcc | *[\\/]distcc | purify | *[\\/]purify ) ;;
-        \-*) ;;
-        *) break;;
-      esac
-    done
-    func_cc_basename_result=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"`
-}
-
 # Check whether --enable-libtool-lock was given.
 if test "${enable_libtool_lock+set}" = set; then :
   enableval=$enable_libtool_lock;
 fi
 
-test no = "$enable_libtool_lock" || enable_libtool_lock=yes
+test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes
 
 # Some flags need to be propagated to the compiler or linker for good
 # libtool support.
 case $host in
 ia64-*-hpux*)
-  # Find out what ABI is being produced by ac_compile, and set mode
-  # options accordingly.
+  # Find out which ABI we are using.
   echo 'int i;' > conftest.$ac_ext
   if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
   (eval $ac_compile) 2>&5
@@ -7450,25 +7330,24 @@ ia64-*-hpux*)
   test $ac_status = 0; }; then
     case `/usr/bin/file conftest.$ac_objext` in
       *ELF-32*)
-	HPUX_IA64_MODE=32
+	HPUX_IA64_MODE="32"
 	;;
       *ELF-64*)
-	HPUX_IA64_MODE=64
+	HPUX_IA64_MODE="64"
 	;;
     esac
   fi
   rm -rf conftest*
   ;;
 *-*-irix6*)
-  # Find out what ABI is being produced by ac_compile, and set linker
-  # options accordingly.
+  # Find out which ABI we are using.
   echo '#line '$LINENO' "configure"' > conftest.$ac_ext
   if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
   (eval $ac_compile) 2>&5
   ac_status=$?
   $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
   test $ac_status = 0; }; then
-    if test yes = "$lt_cv_prog_gnu_ld"; then
+    if test "$lt_cv_prog_gnu_ld" = yes; then
       case `/usr/bin/file conftest.$ac_objext` in
 	*32-bit*)
 	  LD="${LD-ld} -melf32bsmip"
@@ -7497,50 +7376,9 @@ ia64-*-hpux*)
   rm -rf conftest*
   ;;
 
-mips64*-*linux*)
-  # Find out what ABI is being produced by ac_compile, and set linker
-  # options accordingly.
-  echo '#line '$LINENO' "configure"' > conftest.$ac_ext
-  if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
-  (eval $ac_compile) 2>&5
-  ac_status=$?
-  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
-  test $ac_status = 0; }; then
-    emul=elf
-    case `/usr/bin/file conftest.$ac_objext` in
-      *32-bit*)
-	emul="${emul}32"
-	;;
-      *64-bit*)
-	emul="${emul}64"
-	;;
-    esac
-    case `/usr/bin/file conftest.$ac_objext` in
-      *MSB*)
-	emul="${emul}btsmip"
-	;;
-      *LSB*)
-	emul="${emul}ltsmip"
-	;;
-    esac
-    case `/usr/bin/file conftest.$ac_objext` in
-      *N32*)
-	emul="${emul}n32"
-	;;
-    esac
-    LD="${LD-ld} -m $emul"
-  fi
-  rm -rf conftest*
-  ;;
-
 x86_64-*kfreebsd*-gnu|x86_64-*linux*|powerpc*-*linux*| \
 s390*-*linux*|s390*-*tpf*|sparc*-*linux*)
-  # Find out what ABI is being produced by ac_compile, and set linker
-  # options accordingly.  Note that the listed cases only cover the
-  # situations where additional linker options are needed (such as when
-  # doing 32-bit compilation for a host where ld defaults to 64-bit, or
-  # vice versa); the common cases where no linker options are needed do
-  # not appear in the list.
+  # Find out which ABI we are using.
   echo 'int i;' > conftest.$ac_ext
   if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
   (eval $ac_compile) 2>&5
@@ -7563,10 +7401,10 @@ s390*-*linux*|s390*-*tpf*|sparc*-*linux*)
 		;;
 	    esac
 	    ;;
-	  powerpc64le-*linux*)
+	  powerpc64le-*)
 	    LD="${LD-ld} -m elf32lppclinux"
 	    ;;
-	  powerpc64-*linux*)
+	  powerpc64-*)
 	    LD="${LD-ld} -m elf32ppclinux"
 	    ;;
 	  s390x-*linux*)
@@ -7585,10 +7423,10 @@ s390*-*linux*|s390*-*tpf*|sparc*-*linux*)
 	  x86_64-*linux*)
 	    LD="${LD-ld} -m elf_x86_64"
 	    ;;
-	  powerpcle-*linux*)
+	  powerpcle-*)
 	    LD="${LD-ld} -m elf64lppc"
 	    ;;
-	  powerpc-*linux*)
+	  powerpc-*)
 	    LD="${LD-ld} -m elf64ppc"
 	    ;;
 	  s390*-*linux*|s390*-*tpf*)
@@ -7606,7 +7444,7 @@ s390*-*linux*|s390*-*tpf*|sparc*-*linux*)
 
 *-*-sco3.2v5*)
   # On SCO OpenServer 5, we need -belf to get full-featured binaries.
-  SAVE_CFLAGS=$CFLAGS
+  SAVE_CFLAGS="$CFLAGS"
   CFLAGS="$CFLAGS -belf"
   { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler needs -belf" >&5
 $as_echo_n "checking whether the C compiler needs -belf... " >&6; }
@@ -7646,14 +7484,13 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu
 fi
 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_cc_needs_belf" >&5
 $as_echo "$lt_cv_cc_needs_belf" >&6; }
-  if test yes != "$lt_cv_cc_needs_belf"; then
+  if test x"$lt_cv_cc_needs_belf" != x"yes"; then
     # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf
-    CFLAGS=$SAVE_CFLAGS
+    CFLAGS="$SAVE_CFLAGS"
   fi
   ;;
 *-*solaris*)
-  # Find out what ABI is being produced by ac_compile, and set linker
-  # options accordingly.
+  # Find out which ABI we are using.
   echo 'int i;' > conftest.$ac_ext
   if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
   (eval $ac_compile) 2>&5
@@ -7665,7 +7502,7 @@ $as_echo "$lt_cv_cc_needs_belf" >&6; }
       case $lt_cv_prog_gnu_ld in
       yes*)
         case $host in
-        i?86-*-solaris*|x86_64-*-solaris*)
+        i?86-*-solaris*)
           LD="${LD-ld} -m elf_x86_64"
           ;;
         sparc*-*-solaris*)
@@ -7674,7 +7511,7 @@ $as_echo "$lt_cv_cc_needs_belf" >&6; }
         esac
         # GNU ld 2.21 introduced _sol2 emulations.  Use them if available.
         if ${LD-ld} -V | grep _sol2 >/dev/null 2>&1; then
-          LD=${LD-ld}_sol2
+          LD="${LD-ld}_sol2"
         fi
         ;;
       *)
@@ -7690,7 +7527,7 @@ $as_echo "$lt_cv_cc_needs_belf" >&6; }
   ;;
 esac
 
-need_locks=$enable_libtool_lock
+need_locks="$enable_libtool_lock"
 
 if test -n "$ac_tool_prefix"; then
   # Extract the first word of "${ac_tool_prefix}mt", so it can be a program name with args.
@@ -7801,7 +7638,7 @@ else
 fi
 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_mainfest_tool" >&5
 $as_echo "$lt_cv_path_mainfest_tool" >&6; }
-if test yes != "$lt_cv_path_mainfest_tool"; then
+if test "x$lt_cv_path_mainfest_tool" != xyes; then
   MANIFEST_TOOL=:
 fi
 
@@ -8304,7 +8141,7 @@ if ${lt_cv_apple_cc_single_mod+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   lt_cv_apple_cc_single_mod=no
-      if test -z "$LT_MULTI_MODULE"; then
+      if test -z "${LT_MULTI_MODULE}"; then
 	# By default we will add the -single_module flag. You can override
 	# by either setting the environment variable LT_MULTI_MODULE
 	# non-empty at configure time, or by adding -multi_module to the
@@ -8322,7 +8159,7 @@ else
 	  cat conftest.err >&5
 	# Otherwise, if the output was created with a 0 exit code from
 	# the compiler, it worked.
-	elif test -f libconftest.dylib && test 0 = "$_lt_result"; then
+	elif test -f libconftest.dylib && test $_lt_result -eq 0; then
 	  lt_cv_apple_cc_single_mod=yes
 	else
 	  cat conftest.err >&5
@@ -8361,7 +8198,7 @@ else
 fi
 rm -f core conftest.err conftest.$ac_objext \
     conftest$ac_exeext conftest.$ac_ext
-	LDFLAGS=$save_LDFLAGS
+	LDFLAGS="$save_LDFLAGS"
 
 fi
 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_exported_symbols_list" >&5
@@ -8390,7 +8227,7 @@ _LT_EOF
       _lt_result=$?
       if test -s conftest.err && $GREP force_load conftest.err; then
 	cat conftest.err >&5
-      elif test -f conftest && test 0 = "$_lt_result" && $GREP forced_load conftest >/dev/null 2>&1; then
+      elif test -f conftest && test $_lt_result -eq 0 && $GREP forced_load conftest >/dev/null 2>&1 ; then
 	lt_cv_ld_force_load=yes
       else
 	cat conftest.err >&5
@@ -8403,32 +8240,32 @@ fi
 $as_echo "$lt_cv_ld_force_load" >&6; }
     case $host_os in
     rhapsody* | darwin1.[012])
-      _lt_dar_allow_undefined='$wl-undefined ${wl}suppress' ;;
+      _lt_dar_allow_undefined='${wl}-undefined ${wl}suppress' ;;
     darwin1.*)
-      _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;;
+      _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;;
     darwin*) # darwin 5.x on
       # if running on 10.5 or later, the deployment target defaults
       # to the OS version, if on x86, and 10.4, the deployment
       # target defaults to 10.4. Don't you love it?
       case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in
 	10.0,*86*-darwin8*|10.0,*-darwin[91]*)
-	  _lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' ;;
-	10.[012][,.]*)
-	  _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;;
+	  _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;;
+	10.[012]*)
+	  _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;;
 	10.*)
-	  _lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' ;;
+	  _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;;
       esac
     ;;
   esac
-    if test yes = "$lt_cv_apple_cc_single_mod"; then
+    if test "$lt_cv_apple_cc_single_mod" = "yes"; then
       _lt_dar_single_mod='$single_module'
     fi
-    if test yes = "$lt_cv_ld_exported_symbols_list"; then
-      _lt_dar_export_syms=' $wl-exported_symbols_list,$output_objdir/$libname-symbols.expsym'
+    if test "$lt_cv_ld_exported_symbols_list" = "yes"; then
+      _lt_dar_export_syms=' ${wl}-exported_symbols_list,$output_objdir/${libname}-symbols.expsym'
     else
-      _lt_dar_export_syms='~$NMEDIT -s $output_objdir/$libname-symbols.expsym $lib'
+      _lt_dar_export_syms='~$NMEDIT -s $output_objdir/${libname}-symbols.expsym ${lib}'
     fi
-    if test : != "$DSYMUTIL" && test no = "$lt_cv_ld_force_load"; then
+    if test "$DSYMUTIL" != ":" && test "$lt_cv_ld_force_load" = "no"; then
       _lt_dsymutil='~$DSYMUTIL $lib || :'
     else
       _lt_dsymutil=
@@ -8436,41 +8273,6 @@ $as_echo "$lt_cv_ld_force_load" >&6; }
     ;;
   esac
 
-# func_munge_path_list VARIABLE PATH
-# -----------------------------------
-# VARIABLE is name of variable containing _space_ separated list of
-# directories to be munged by the contents of PATH, which is string
-# having a format:
-# "DIR[:DIR]:"
-#       string "DIR[ DIR]" will be prepended to VARIABLE
-# ":DIR[:DIR]"
-#       string "DIR[ DIR]" will be appended to VARIABLE
-# "DIRP[:DIRP]::[DIRA:]DIRA"
-#       string "DIRP[ DIRP]" will be prepended to VARIABLE and string
-#       "DIRA[ DIRA]" will be appended to VARIABLE
-# "DIR[:DIR]"
-#       VARIABLE will be replaced by "DIR[ DIR]"
-func_munge_path_list ()
-{
-    case x$2 in
-    x)
-        ;;
-    *:)
-        eval $1=\"`$ECHO $2 | $SED 's/:/ /g'` \$$1\"
-        ;;
-    x:*)
-        eval $1=\"\$$1 `$ECHO $2 | $SED 's/:/ /g'`\"
-        ;;
-    *::*)
-        eval $1=\"\$$1\ `$ECHO $2 | $SED -e 's/.*:://' -e 's/:/ /g'`\"
-        eval $1=\"`$ECHO $2 | $SED -e 's/::.*//' -e 's/:/ /g'`\ \$$1\"
-        ;;
-    *)
-        eval $1=\"`$ECHO $2 | $SED 's/:/ /g'`\"
-        ;;
-    esac
-}
-
 ac_ext=c
 ac_cpp='$CPP $CPPFLAGS'
 ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
@@ -8755,9 +8557,9 @@ done
 
 func_stripname_cnf ()
 {
-  case $2 in
-  .*) func_stripname_result=`$ECHO "$3" | $SED "s%^$1%%; s%\\\\$2\$%%"`;;
-  *)  func_stripname_result=`$ECHO "$3" | $SED "s%^$1%%; s%$2\$%%"`;;
+  case ${2} in
+  .*) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%\\\\${2}\$%%"`;;
+  *)  func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%${2}\$%%"`;;
   esac
 } # func_stripname_cnf
 
@@ -8784,14 +8586,14 @@ if test "${enable_shared+set}" = set; then :
     *)
       enable_shared=no
       # Look at the argument we got.  We use all the common list separators.
-      lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR,
+      lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
       for pkg in $enableval; do
-	IFS=$lt_save_ifs
+	IFS="$lt_save_ifs"
 	if test "X$pkg" = "X$p"; then
 	  enable_shared=yes
 	fi
       done
-      IFS=$lt_save_ifs
+      IFS="$lt_save_ifs"
       ;;
     esac
 else
@@ -8815,14 +8617,14 @@ if test "${enable_static+set}" = set; then :
     *)
      enable_static=no
       # Look at the argument we got.  We use all the common list separators.
-      lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR,
+      lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
       for pkg in $enableval; do
-	IFS=$lt_save_ifs
+	IFS="$lt_save_ifs"
 	if test "X$pkg" = "X$p"; then
 	  enable_static=yes
 	fi
       done
-      IFS=$lt_save_ifs
+      IFS="$lt_save_ifs"
       ;;
     esac
 else
@@ -8846,14 +8648,14 @@ if test "${with_pic+set}" = set; then :
     *)
       pic_mode=default
       # Look at the argument we got.  We use all the common list separators.
-      lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR,
+      lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
       for lt_pkg in $withval; do
-	IFS=$lt_save_ifs
+	IFS="$lt_save_ifs"
 	if test "X$lt_pkg" = "X$lt_p"; then
 	  pic_mode=yes
 	fi
       done
-      IFS=$lt_save_ifs
+      IFS="$lt_save_ifs"
       ;;
     esac
 else
@@ -8861,6 +8663,8 @@ else
 fi
 
 
+test -z "$pic_mode" && pic_mode=default
+
 
 
 
@@ -8876,14 +8680,14 @@ if test "${enable_fast_install+set}" = set; then :
     *)
       enable_fast_install=no
       # Look at the argument we got.  We use all the common list separators.
-      lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR,
+      lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
       for pkg in $enableval; do
-	IFS=$lt_save_ifs
+	IFS="$lt_save_ifs"
 	if test "X$pkg" = "X$p"; then
 	  enable_fast_install=yes
 	fi
       done
-      IFS=$lt_save_ifs
+      IFS="$lt_save_ifs"
       ;;
     esac
 else
@@ -8897,63 +8701,11 @@ fi
 
 
 
-  shared_archive_member_spec=
-case $host,$enable_shared in
-power*-*-aix[5-9]*,yes)
-  { $as_echo "$as_me:${as_lineno-$LINENO}: checking which variant of shared library versioning to provide" >&5
-$as_echo_n "checking which variant of shared library versioning to provide... " >&6; }
-
-# Check whether --with-aix-soname was given.
-if test "${with_aix_soname+set}" = set; then :
-  withval=$with_aix_soname; case $withval in
-    aix|svr4|both)
-      ;;
-    *)
-      as_fn_error $? "Unknown argument to --with-aix-soname" "$LINENO" 5
-      ;;
-    esac
-    lt_cv_with_aix_soname=$with_aix_soname
-else
-  if ${lt_cv_with_aix_soname+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  lt_cv_with_aix_soname=aix
-fi
-
-    with_aix_soname=$lt_cv_with_aix_soname
-fi
-
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $with_aix_soname" >&5
-$as_echo "$with_aix_soname" >&6; }
-  if test aix != "$with_aix_soname"; then
-    # For the AIX way of multilib, we name the shared archive member
-    # based on the bitwidth used, traditionally 'shr.o' or 'shr_64.o',
-    # and 'shr.imp' or 'shr_64.imp', respectively, for the Import File.
-    # Even when GNU compilers ignore OBJECT_MODE but need '-maix64' flag,
-    # the AIX toolchain works better with OBJECT_MODE set (default 32).
-    if test 64 = "${OBJECT_MODE-32}"; then
-      shared_archive_member_spec=shr_64
-    else
-      shared_archive_member_spec=shr
-    fi
-  fi
-  ;;
-*)
-  with_aix_soname=aix
-  ;;
-esac
-
-
-
-
-
-
-
 
 
 
 # This can be used to rebuild libtool when needed
-LIBTOOL_DEPS=$ltmain
+LIBTOOL_DEPS="$ltmain"
 
 # Always use our own libtool.
 LIBTOOL='$(SHELL) $(top_builddir)/libtool'
@@ -9002,7 +8754,7 @@ test -z "$LN_S" && LN_S="ln -s"
 
 
 
-if test -n "${ZSH_VERSION+set}"; then
+if test -n "${ZSH_VERSION+set}" ; then
    setopt NO_GLOB_SUBST
 fi
 
@@ -9041,7 +8793,7 @@ aix3*)
   # AIX sometimes has problems with the GCC collect2 program.  For some
   # reason, if we set the COLLECT_NAMES environment variable, the problems
   # vanish in a puff of smoke.
-  if test set != "${COLLECT_NAMES+set}"; then
+  if test "X${COLLECT_NAMES+set}" != Xset; then
     COLLECT_NAMES=
     export COLLECT_NAMES
   fi
@@ -9052,14 +8804,14 @@ esac
 ofile=libtool
 can_build_shared=yes
 
-# All known linkers require a '.a' archive for static linking (except MSVC,
+# All known linkers require a `.a' archive for static linking (except MSVC,
 # which needs '.lib').
 libext=a
 
-with_gnu_ld=$lt_cv_prog_gnu_ld
+with_gnu_ld="$lt_cv_prog_gnu_ld"
 
-old_CC=$CC
-old_CFLAGS=$CFLAGS
+old_CC="$CC"
+old_CFLAGS="$CFLAGS"
 
 # Set sane defaults for various variables
 test -z "$CC" && CC=cc
@@ -9068,8 +8820,15 @@ test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS
 test -z "$LD" && LD=ld
 test -z "$ac_objext" && ac_objext=o
 
-func_cc_basename $compiler
-cc_basename=$func_cc_basename_result
+for cc_temp in $compiler""; do
+  case $cc_temp in
+    compile | *[\\/]compile | ccache | *[\\/]ccache ) ;;
+    distcc | *[\\/]distcc | purify | *[\\/]purify ) ;;
+    \-*) ;;
+    *) break;;
+  esac
+done
+cc_basename=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"`
 
 
 # Only perform the check for file, if the check method requires it
@@ -9084,22 +8843,22 @@ if ${lt_cv_path_MAGIC_CMD+:} false; then :
 else
   case $MAGIC_CMD in
 [\\/*] |  ?:[\\/]*)
-  lt_cv_path_MAGIC_CMD=$MAGIC_CMD # Let the user override the test with a path.
+  lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path.
   ;;
 *)
-  lt_save_MAGIC_CMD=$MAGIC_CMD
-  lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR
+  lt_save_MAGIC_CMD="$MAGIC_CMD"
+  lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
   ac_dummy="/usr/bin$PATH_SEPARATOR$PATH"
   for ac_dir in $ac_dummy; do
-    IFS=$lt_save_ifs
+    IFS="$lt_save_ifs"
     test -z "$ac_dir" && ac_dir=.
-    if test -f "$ac_dir/${ac_tool_prefix}file"; then
-      lt_cv_path_MAGIC_CMD=$ac_dir/"${ac_tool_prefix}file"
+    if test -f $ac_dir/${ac_tool_prefix}file; then
+      lt_cv_path_MAGIC_CMD="$ac_dir/${ac_tool_prefix}file"
       if test -n "$file_magic_test_file"; then
 	case $deplibs_check_method in
 	"file_magic "*)
 	  file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"`
-	  MAGIC_CMD=$lt_cv_path_MAGIC_CMD
+	  MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
 	  if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null |
 	    $EGREP "$file_magic_regex" > /dev/null; then
 	    :
@@ -9122,13 +8881,13 @@ _LT_EOF
       break
     fi
   done
-  IFS=$lt_save_ifs
-  MAGIC_CMD=$lt_save_MAGIC_CMD
+  IFS="$lt_save_ifs"
+  MAGIC_CMD="$lt_save_MAGIC_CMD"
   ;;
 esac
 fi
 
-MAGIC_CMD=$lt_cv_path_MAGIC_CMD
+MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
 if test -n "$MAGIC_CMD"; then
   { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5
 $as_echo "$MAGIC_CMD" >&6; }
@@ -9150,22 +8909,22 @@ if ${lt_cv_path_MAGIC_CMD+:} false; then :
 else
   case $MAGIC_CMD in
 [\\/*] |  ?:[\\/]*)
-  lt_cv_path_MAGIC_CMD=$MAGIC_CMD # Let the user override the test with a path.
+  lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path.
   ;;
 *)
-  lt_save_MAGIC_CMD=$MAGIC_CMD
-  lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR
+  lt_save_MAGIC_CMD="$MAGIC_CMD"
+  lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
   ac_dummy="/usr/bin$PATH_SEPARATOR$PATH"
   for ac_dir in $ac_dummy; do
-    IFS=$lt_save_ifs
+    IFS="$lt_save_ifs"
     test -z "$ac_dir" && ac_dir=.
-    if test -f "$ac_dir/file"; then
-      lt_cv_path_MAGIC_CMD=$ac_dir/"file"
+    if test -f $ac_dir/file; then
+      lt_cv_path_MAGIC_CMD="$ac_dir/file"
       if test -n "$file_magic_test_file"; then
 	case $deplibs_check_method in
 	"file_magic "*)
 	  file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"`
-	  MAGIC_CMD=$lt_cv_path_MAGIC_CMD
+	  MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
 	  if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null |
 	    $EGREP "$file_magic_regex" > /dev/null; then
 	    :
@@ -9188,13 +8947,13 @@ _LT_EOF
       break
     fi
   done
-  IFS=$lt_save_ifs
-  MAGIC_CMD=$lt_save_MAGIC_CMD
+  IFS="$lt_save_ifs"
+  MAGIC_CMD="$lt_save_MAGIC_CMD"
   ;;
 esac
 fi
 
-MAGIC_CMD=$lt_cv_path_MAGIC_CMD
+MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
 if test -n "$MAGIC_CMD"; then
   { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5
 $as_echo "$MAGIC_CMD" >&6; }
@@ -9215,7 +8974,7 @@ esac
 
 # Use C for the default configuration in the libtool script
 
-lt_save_CC=$CC
+lt_save_CC="$CC"
 ac_ext=c
 ac_cpp='$CPP $CPPFLAGS'
 ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
@@ -9277,7 +9036,7 @@ if test -n "$compiler"; then
 
 lt_prog_compiler_no_builtin_flag=
 
-if test yes = "$GCC"; then
+if test "$GCC" = yes; then
   case $cc_basename in
   nvcc*)
     lt_prog_compiler_no_builtin_flag=' -Xcompiler -fno-builtin' ;;
@@ -9293,7 +9052,7 @@ else
   lt_cv_prog_compiler_rtti_exceptions=no
    ac_outfile=conftest.$ac_objext
    echo "$lt_simple_compile_test_code" > conftest.$ac_ext
-   lt_compiler_flag="-fno-rtti -fno-exceptions"  ## exclude from sc_useless_quotes_in_assignment
+   lt_compiler_flag="-fno-rtti -fno-exceptions"
    # Insert the option either (1) after the last *FLAGS variable, or
    # (2) before a word containing "conftest.", or (3) at the end.
    # Note that $ac_compile itself does not contain backslashes and begins
@@ -9323,7 +9082,7 @@ fi
 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_rtti_exceptions" >&5
 $as_echo "$lt_cv_prog_compiler_rtti_exceptions" >&6; }
 
-if test yes = "$lt_cv_prog_compiler_rtti_exceptions"; then
+if test x"$lt_cv_prog_compiler_rtti_exceptions" = xyes; then
     lt_prog_compiler_no_builtin_flag="$lt_prog_compiler_no_builtin_flag -fno-rtti -fno-exceptions"
 else
     :
@@ -9341,18 +9100,17 @@ lt_prog_compiler_pic=
 lt_prog_compiler_static=
 
 
-  if test yes = "$GCC"; then
+  if test "$GCC" = yes; then
     lt_prog_compiler_wl='-Wl,'
     lt_prog_compiler_static='-static'
 
     case $host_os in
       aix*)
       # All AIX code is PIC.
-      if test ia64 = "$host_cpu"; then
+      if test "$host_cpu" = ia64; then
 	# AIX 5 now supports IA64 processor
 	lt_prog_compiler_static='-Bstatic'
       fi
-      lt_prog_compiler_pic='-fPIC'
       ;;
 
     amigaos*)
@@ -9363,8 +9121,8 @@ lt_prog_compiler_static=
         ;;
       m68k)
             # FIXME: we need at least 68020 code to build shared libraries, but
-            # adding the '-m68020' flag to GCC prevents building anything better,
-            # like '-m68040'.
+            # adding the `-m68020' flag to GCC prevents building anything better,
+            # like `-m68040'.
             lt_prog_compiler_pic='-m68020 -resident32 -malways-restore-a4'
         ;;
       esac
@@ -9380,11 +9138,6 @@ lt_prog_compiler_static=
       # Although the cygwin gcc ignores -fPIC, still need this for old-style
       # (--disable-auto-import) libraries
       lt_prog_compiler_pic='-DDLL_EXPORT'
-      case $host_os in
-      os2*)
-	lt_prog_compiler_static='$wl-static'
-	;;
-      esac
       ;;
 
     darwin* | rhapsody*)
@@ -9455,7 +9208,7 @@ lt_prog_compiler_static=
     case $host_os in
     aix*)
       lt_prog_compiler_wl='-Wl,'
-      if test ia64 = "$host_cpu"; then
+      if test "$host_cpu" = ia64; then
 	# AIX 5 now supports IA64 processor
 	lt_prog_compiler_static='-Bstatic'
       else
@@ -9463,29 +9216,10 @@ lt_prog_compiler_static=
       fi
       ;;
 
-    darwin* | rhapsody*)
-      # PIC is the default on this platform
-      # Common symbols not allowed in MH_DYLIB files
-      lt_prog_compiler_pic='-fno-common'
-      case $cc_basename in
-      nagfor*)
-        # NAG Fortran compiler
-        lt_prog_compiler_wl='-Wl,-Wl,,'
-        lt_prog_compiler_pic='-PIC'
-        lt_prog_compiler_static='-Bstatic'
-        ;;
-      esac
-      ;;
-
     mingw* | cygwin* | pw32* | os2* | cegcc*)
       # This hack is so that the source file can tell whether it is being
       # built for inclusion in a dll (and should export symbols for example).
       lt_prog_compiler_pic='-DDLL_EXPORT'
-      case $host_os in
-      os2*)
-	lt_prog_compiler_static='$wl-static'
-	;;
-      esac
       ;;
 
     hpux9* | hpux10* | hpux11*)
@@ -9501,7 +9235,7 @@ lt_prog_compiler_static=
 	;;
       esac
       # Is there a better lt_prog_compiler_static that works with the bundled CC?
-      lt_prog_compiler_static='$wl-a ${wl}archive'
+      lt_prog_compiler_static='${wl}-a ${wl}archive'
       ;;
 
     irix5* | irix6* | nonstopux*)
@@ -9512,7 +9246,7 @@ lt_prog_compiler_static=
 
     linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*)
       case $cc_basename in
-      # old Intel for x86_64, which still supported -KPIC.
+      # old Intel for x86_64 which still supported -KPIC.
       ecc*)
 	lt_prog_compiler_wl='-Wl,'
 	lt_prog_compiler_pic='-KPIC'
@@ -9537,12 +9271,6 @@ lt_prog_compiler_static=
 	lt_prog_compiler_pic='-PIC'
 	lt_prog_compiler_static='-Bstatic'
 	;;
-      tcc*)
-	# Fabrice Bellard et al's Tiny C Compiler
-	lt_prog_compiler_wl='-Wl,'
-	lt_prog_compiler_pic='-fPIC'
-	lt_prog_compiler_static='-static'
-	;;
       pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*)
         # Portland Group compilers (*not* the Pentium gcc compiler,
 	# which looks to be a dead project)
@@ -9640,7 +9368,7 @@ lt_prog_compiler_static=
       ;;
 
     sysv4*MP*)
-      if test -d /usr/nec; then
+      if test -d /usr/nec ;then
 	lt_prog_compiler_pic='-Kconform_pic'
 	lt_prog_compiler_static='-Bstatic'
       fi
@@ -9669,7 +9397,7 @@ lt_prog_compiler_static=
   fi
 
 case $host_os in
-  # For platforms that do not support PIC, -DPIC is meaningless:
+  # For platforms which do not support PIC, -DPIC is meaningless:
   *djgpp*)
     lt_prog_compiler_pic=
     ;;
@@ -9701,7 +9429,7 @@ else
   lt_cv_prog_compiler_pic_works=no
    ac_outfile=conftest.$ac_objext
    echo "$lt_simple_compile_test_code" > conftest.$ac_ext
-   lt_compiler_flag="$lt_prog_compiler_pic -DPIC"  ## exclude from sc_useless_quotes_in_assignment
+   lt_compiler_flag="$lt_prog_compiler_pic -DPIC"
    # Insert the option either (1) after the last *FLAGS variable, or
    # (2) before a word containing "conftest.", or (3) at the end.
    # Note that $ac_compile itself does not contain backslashes and begins
@@ -9731,7 +9459,7 @@ fi
 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_works" >&5
 $as_echo "$lt_cv_prog_compiler_pic_works" >&6; }
 
-if test yes = "$lt_cv_prog_compiler_pic_works"; then
+if test x"$lt_cv_prog_compiler_pic_works" = xyes; then
     case $lt_prog_compiler_pic in
      "" | " "*) ;;
      *) lt_prog_compiler_pic=" $lt_prog_compiler_pic" ;;
@@ -9763,7 +9491,7 @@ if ${lt_cv_prog_compiler_static_works+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   lt_cv_prog_compiler_static_works=no
-   save_LDFLAGS=$LDFLAGS
+   save_LDFLAGS="$LDFLAGS"
    LDFLAGS="$LDFLAGS $lt_tmp_static_flag"
    echo "$lt_simple_link_test_code" > conftest.$ac_ext
    if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then
@@ -9782,13 +9510,13 @@ else
      fi
    fi
    $RM -r conftest*
-   LDFLAGS=$save_LDFLAGS
+   LDFLAGS="$save_LDFLAGS"
 
 fi
 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_static_works" >&5
 $as_echo "$lt_cv_prog_compiler_static_works" >&6; }
 
-if test yes = "$lt_cv_prog_compiler_static_works"; then
+if test x"$lt_cv_prog_compiler_static_works" = xyes; then
     :
 else
     lt_prog_compiler_static=
@@ -9908,8 +9636,8 @@ $as_echo "$lt_cv_prog_compiler_c_o" >&6; }
 
 
 
-hard_links=nottested
-if test no = "$lt_cv_prog_compiler_c_o" && test no != "$need_locks"; then
+hard_links="nottested"
+if test "$lt_cv_prog_compiler_c_o" = no && test "$need_locks" != no; then
   # do not overwrite the value of need_locks provided by the user
   { $as_echo "$as_me:${as_lineno-$LINENO}: checking if we can lock with hard links" >&5
 $as_echo_n "checking if we can lock with hard links... " >&6; }
@@ -9921,9 +9649,9 @@ $as_echo_n "checking if we can lock with hard links... " >&6; }
   ln conftest.a conftest.b 2>/dev/null && hard_links=no
   { $as_echo "$as_me:${as_lineno-$LINENO}: result: $hard_links" >&5
 $as_echo "$hard_links" >&6; }
-  if test no = "$hard_links"; then
-    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: '$CC' does not support '-c -o', so 'make -j' may be unsafe" >&5
-$as_echo "$as_me: WARNING: '$CC' does not support '-c -o', so 'make -j' may be unsafe" >&2;}
+  if test "$hard_links" = no; then
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&5
+$as_echo "$as_me: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&2;}
     need_locks=warn
   fi
 else
@@ -9966,9 +9694,9 @@ $as_echo_n "checking whether the $compiler linker ($LD) supports shared librarie
   # included in the symbol list
   include_expsyms=
   # exclude_expsyms can be an extended regexp of symbols to exclude
-  # it will be wrapped by ' (' and ')$', so one must not match beginning or
-  # end of line.  Example: 'a|bc|.*d.*' will exclude the symbols 'a' and 'bc',
-  # as well as any symbol that contains 'd'.
+  # it will be wrapped by ` (' and `)$', so one must not match beginning or
+  # end of line.  Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc',
+  # as well as any symbol that contains `d'.
   exclude_expsyms='_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'
   # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out
   # platforms (ab)use it in PIC code, but their linkers get confused if
@@ -9983,7 +9711,7 @@ $as_echo_n "checking whether the $compiler linker ($LD) supports shared librarie
     # FIXME: the MSVC++ port hasn't been tested in a loooong time
     # When not using gcc, we currently assume that we are using
     # Microsoft Visual C++.
-    if test yes != "$GCC"; then
+    if test "$GCC" != yes; then
       with_gnu_ld=no
     fi
     ;;
@@ -9991,7 +9719,7 @@ $as_echo_n "checking whether the $compiler linker ($LD) supports shared librarie
     # we just hope/assume this is gcc and not c89 (= MSVC++)
     with_gnu_ld=yes
     ;;
-  openbsd* | bitrig*)
+  openbsd*)
     with_gnu_ld=no
     ;;
   linux* | k*bsd*-gnu | gnu*)
@@ -10004,7 +9732,7 @@ $as_echo_n "checking whether the $compiler linker ($LD) supports shared librarie
   # On some targets, GNU ld is compatible enough with the native linker
   # that we're better off using the native interface for both.
   lt_use_gnu_ld_interface=no
-  if test yes = "$with_gnu_ld"; then
+  if test "$with_gnu_ld" = yes; then
     case $host_os in
       aix*)
 	# The AIX port of GNU ld has always aspired to compatibility
@@ -10026,24 +9754,24 @@ $as_echo_n "checking whether the $compiler linker ($LD) supports shared librarie
     esac
   fi
 
-  if test yes = "$lt_use_gnu_ld_interface"; then
+  if test "$lt_use_gnu_ld_interface" = yes; then
     # If archive_cmds runs LD, not CC, wlarc should be empty
-    wlarc='$wl'
+    wlarc='${wl}'
 
     # Set some defaults for GNU ld with shared library support. These
     # are reset later if shared libraries are not supported. Putting them
     # here allows them to be overridden if necessary.
     runpath_var=LD_RUN_PATH
-    hardcode_libdir_flag_spec='$wl-rpath $wl$libdir'
-    export_dynamic_flag_spec='$wl--export-dynamic'
+    hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+    export_dynamic_flag_spec='${wl}--export-dynamic'
     # ancient GNU ld didn't support --whole-archive et. al.
     if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then
-      whole_archive_flag_spec=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive'
+      whole_archive_flag_spec="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive'
     else
       whole_archive_flag_spec=
     fi
     supports_anon_versioning=no
-    case `$LD -v | $SED -e 's/(^)\+)\s\+//' 2>&1` in
+    case `$LD -v 2>&1` in
       *GNU\ gold*) supports_anon_versioning=yes ;;
       *\ [01].* | *\ 2.[0-9].* | *\ 2.10.*) ;; # catch versions < 2.11
       *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ...
@@ -10056,7 +9784,7 @@ $as_echo_n "checking whether the $compiler linker ($LD) supports shared librarie
     case $host_os in
     aix[3-9]*)
       # On AIX/PPC, the GNU linker is very broken
-      if test ia64 != "$host_cpu"; then
+      if test "$host_cpu" != ia64; then
 	ld_shlibs=no
 	cat <<_LT_EOF 1>&2
 
@@ -10075,7 +9803,7 @@ _LT_EOF
       case $host_cpu in
       powerpc)
             # see comment about AmigaOS4 .so support
-            archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+            archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
             archive_expsym_cmds=''
         ;;
       m68k)
@@ -10091,7 +9819,7 @@ _LT_EOF
 	allow_undefined_flag=unsupported
 	# Joseph Beckenbach <jrb3 at best.com> says some releases of gcc
 	# support --undefined.  This deserves some investigation.  FIXME
-	archive_cmds='$CC -nostart $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+	archive_cmds='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
       else
 	ld_shlibs=no
       fi
@@ -10101,7 +9829,7 @@ _LT_EOF
       # _LT_TAGVAR(hardcode_libdir_flag_spec, ) is actually meaningless,
       # as there is no search path for DLLs.
       hardcode_libdir_flag_spec='-L$libdir'
-      export_dynamic_flag_spec='$wl--export-all-symbols'
+      export_dynamic_flag_spec='${wl}--export-all-symbols'
       allow_undefined_flag=unsupported
       always_export_symbols=no
       enable_shared_with_static_runtimes=yes
@@ -10109,89 +9837,61 @@ _LT_EOF
       exclude_expsyms='[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname'
 
       if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then
-        archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
-	# If the export-symbols file already is a .def file, use it as
-	# is; otherwise, prepend EXPORTS...
-	archive_expsym_cmds='if   test DEF = "`$SED -n     -e '\''s/^[	 ]*//'\''     -e '\''/^\(;.*\)*$/d'\''     -e '\''s/^\(EXPORTS\|LIBRARY\)\([	 ].*\)*$/DEF/p'\''     -e q     $export_symbols`" ; then
-          cp $export_symbols $output_objdir/$soname.def;
-        else
-          echo EXPORTS > $output_objdir/$soname.def;
-          cat $export_symbols >> $output_objdir/$soname.def;
-        fi~
-        $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+        archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+	# If the export-symbols file already is a .def file (1st line
+	# is EXPORTS), use it as is; otherwise, prepend...
+	archive_expsym_cmds='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then
+	  cp $export_symbols $output_objdir/$soname.def;
+	else
+	  echo EXPORTS > $output_objdir/$soname.def;
+	  cat $export_symbols >> $output_objdir/$soname.def;
+	fi~
+	$CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
       else
 	ld_shlibs=no
       fi
       ;;
 
     haiku*)
-      archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+      archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
       link_all_deplibs=yes
       ;;
 
-    os2*)
-      hardcode_libdir_flag_spec='-L$libdir'
-      hardcode_minus_L=yes
-      allow_undefined_flag=unsupported
-      shrext_cmds=.dll
-      archive_cmds='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~
-	$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~
-	$ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~
-	$ECHO EXPORTS >> $output_objdir/$libname.def~
-	emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~
-	$CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~
-	emximp -o $lib $output_objdir/$libname.def'
-      archive_expsym_cmds='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~
-	$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~
-	$ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~
-	$ECHO EXPORTS >> $output_objdir/$libname.def~
-	prefix_cmds="$SED"~
-	if test EXPORTS = "`$SED 1q $export_symbols`"; then
-	  prefix_cmds="$prefix_cmds -e 1d";
-	fi~
-	prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~
-	cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~
-	$CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~
-	emximp -o $lib $output_objdir/$libname.def'
-      old_archive_From_new_cmds='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def'
-      enable_shared_with_static_runtimes=yes
-      ;;
-
     interix[3-9]*)
       hardcode_direct=no
       hardcode_shlibpath_var=no
-      hardcode_libdir_flag_spec='$wl-rpath,$libdir'
-      export_dynamic_flag_spec='$wl-E'
+      hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
+      export_dynamic_flag_spec='${wl}-E'
       # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc.
       # Instead, shared libraries are loaded at an image base (0x10000000 by
       # default) and relocated if they conflict, which is a slow very memory
       # consuming and fragmenting process.  To avoid this, we pick a random,
       # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link
       # time.  Moving up from 0x10000000 also allows more sbrk(2) space.
-      archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
-      archive_expsym_cmds='sed "s|^|_|" $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--retain-symbols-file,$output_objdir/$soname.expsym $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+      archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+      archive_expsym_cmds='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
       ;;
 
     gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu)
       tmp_diet=no
-      if test linux-dietlibc = "$host_os"; then
+      if test "$host_os" = linux-dietlibc; then
 	case $cc_basename in
 	  diet\ *) tmp_diet=yes;;	# linux-dietlibc with static linking (!diet-dyn)
 	esac
       fi
       if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \
-	 && test no = "$tmp_diet"
+	 && test "$tmp_diet" = no
       then
 	tmp_addflag=' $pic_flag'
 	tmp_sharedflag='-shared'
 	case $cc_basename,$host_cpu in
         pgcc*)				# Portland Group C compiler
-	  whole_archive_flag_spec='$wl--whole-archive`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive'
+	  whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
 	  tmp_addflag=' $pic_flag'
 	  ;;
 	pgf77* | pgf90* | pgf95* | pgfortran*)
 					# Portland Group f77 and f90 compilers
-	  whole_archive_flag_spec='$wl--whole-archive`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive'
+	  whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
 	  tmp_addflag=' $pic_flag -Mnomain' ;;
 	ecc*,ia64* | icc*,ia64*)	# Intel C compiler on ia64
 	  tmp_addflag=' -i_dynamic' ;;
@@ -10202,47 +9902,42 @@ _LT_EOF
 	lf95*)				# Lahey Fortran 8.1
 	  whole_archive_flag_spec=
 	  tmp_sharedflag='--shared' ;;
-        nagfor*)                        # NAGFOR 5.3
-          tmp_sharedflag='-Wl,-shared' ;;
 	xl[cC]* | bgxl[cC]* | mpixl[cC]*) # IBM XL C 8.0 on PPC (deal with xlf below)
 	  tmp_sharedflag='-qmkshrobj'
 	  tmp_addflag= ;;
 	nvcc*)	# Cuda Compiler Driver 2.2
-	  whole_archive_flag_spec='$wl--whole-archive`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive'
+	  whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
 	  compiler_needs_object=yes
 	  ;;
 	esac
 	case `$CC -V 2>&1 | sed 5q` in
 	*Sun\ C*)			# Sun C 5.9
-	  whole_archive_flag_spec='$wl--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive'
+	  whole_archive_flag_spec='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
 	  compiler_needs_object=yes
 	  tmp_sharedflag='-G' ;;
 	*Sun\ F*)			# Sun Fortran 8.3
 	  tmp_sharedflag='-G' ;;
 	esac
-	archive_cmds='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+	archive_cmds='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
 
-        if test yes = "$supports_anon_versioning"; then
+        if test "x$supports_anon_versioning" = xyes; then
           archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~
-            cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
-            echo "local: *; };" >> $output_objdir/$libname.ver~
-            $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-version-script $wl$output_objdir/$libname.ver -o $lib'
+	    cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
+	    echo "local: *; };" >> $output_objdir/$libname.ver~
+	    $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib'
         fi
 
 	case $cc_basename in
-	tcc*)
-	  export_dynamic_flag_spec='-rdynamic'
-	  ;;
 	xlf* | bgf* | bgxlf* | mpixlf*)
 	  # IBM XL Fortran 10.1 on PPC cannot create shared libs itself
 	  whole_archive_flag_spec='--whole-archive$convenience --no-whole-archive'
-	  hardcode_libdir_flag_spec='$wl-rpath $wl$libdir'
+	  hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
 	  archive_cmds='$LD -shared $libobjs $deplibs $linker_flags -soname $soname -o $lib'
-	  if test yes = "$supports_anon_versioning"; then
+	  if test "x$supports_anon_versioning" = xyes; then
 	    archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~
-              cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
-              echo "local: *; };" >> $output_objdir/$libname.ver~
-              $LD -shared $libobjs $deplibs $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib'
+	      cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
+	      echo "local: *; };" >> $output_objdir/$libname.ver~
+	      $LD -shared $libobjs $deplibs $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib'
 	  fi
 	  ;;
 	esac
@@ -10256,8 +9951,8 @@ _LT_EOF
 	archive_cmds='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib'
 	wlarc=
       else
-	archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
-	archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'
+	archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+	archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
       fi
       ;;
 
@@ -10275,8 +9970,8 @@ _LT_EOF
 
 _LT_EOF
       elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
-	archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
-	archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'
+	archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+	archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
       else
 	ld_shlibs=no
       fi
@@ -10288,7 +9983,7 @@ _LT_EOF
 	ld_shlibs=no
 	cat <<_LT_EOF 1>&2
 
-*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 cannot
+*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 can not
 *** reliably create shared libraries on SCO systems.  Therefore, libtool
 *** is disabling shared libraries support.  We urge you to upgrade GNU
 *** binutils to release 2.16.91.0.3 or newer.  Another option is to modify
@@ -10303,9 +9998,9 @@ _LT_EOF
 	  # DT_RUNPATH tag from executables and libraries.  But doing so
 	  # requires that you compile everything twice, which is a pain.
 	  if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
-	    hardcode_libdir_flag_spec='$wl-rpath $wl$libdir'
-	    archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
-	    archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'
+	    hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+	    archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+	    archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
 	  else
 	    ld_shlibs=no
 	  fi
@@ -10322,15 +10017,15 @@ _LT_EOF
 
     *)
       if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
-	archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
-	archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'
+	archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+	archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
       else
 	ld_shlibs=no
       fi
       ;;
     esac
 
-    if test no = "$ld_shlibs"; then
+    if test "$ld_shlibs" = no; then
       runpath_var=
       hardcode_libdir_flag_spec=
       export_dynamic_flag_spec=
@@ -10346,7 +10041,7 @@ _LT_EOF
       # Note: this linker hardcodes the directories in LIBPATH if there
       # are no directories specified by -L.
       hardcode_minus_L=yes
-      if test yes = "$GCC" && test -z "$lt_prog_compiler_static"; then
+      if test "$GCC" = yes && test -z "$lt_prog_compiler_static"; then
 	# Neither direct hardcoding nor static linking is supported with a
 	# broken collect2.
 	hardcode_direct=unsupported
@@ -10354,57 +10049,34 @@ _LT_EOF
       ;;
 
     aix[4-9]*)
-      if test ia64 = "$host_cpu"; then
+      if test "$host_cpu" = ia64; then
 	# On IA64, the linker does run time linking by default, so we don't
 	# have to do anything special.
 	aix_use_runtimelinking=no
 	exp_sym_flag='-Bexport'
-	no_entry_flag=
+	no_entry_flag=""
       else
 	# If we're using GNU nm, then we don't want the "-C" option.
-	# -C means demangle to GNU nm, but means don't demangle to AIX nm.
-	# Without the "-l" option, or with the "-B" option, AIX nm treats
-	# weak defined symbols like other global defined symbols, whereas
-	# GNU nm marks them as "W".
-	# While the 'weak' keyword is ignored in the Export File, we need
-	# it in the Import File for the 'aix-soname' feature, so we have
-	# to replace the "-B" option with "-P" for AIX nm.
+	# -C means demangle to AIX nm, but means don't demangle with GNU nm
+	# Also, AIX nm treats weak defined symbols like other global
+	# defined symbols, whereas GNU nm marks them as "W".
 	if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then
-	  export_symbols_cmds='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && (substr(\$ 3,1,1) != ".")) { if (\$ 2 == "W") { print \$ 3 " weak" } else { print \$ 3 } } }'\'' | sort -u > $export_symbols'
+	  export_symbols_cmds='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols'
 	else
-	  export_symbols_cmds='`func_echo_all $NM | $SED -e '\''s/B\([^B]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && (substr(\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols'
+	  export_symbols_cmds='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols'
 	fi
 	aix_use_runtimelinking=no
 
 	# Test if we are trying to use run time linking or normal
 	# AIX style linking. If -brtl is somewhere in LDFLAGS, we
-	# have runtime linking enabled, and use it for executables.
-	# For shared libraries, we enable/disable runtime linking
-	# depending on the kind of the shared library created -
-	# when "with_aix_soname,aix_use_runtimelinking" is:
-	# "aix,no"   lib.a(lib.so.V) shared, rtl:no,  for executables
-	# "aix,yes"  lib.so          shared, rtl:yes, for executables
-	#            lib.a           static archive
-	# "both,no"  lib.so.V(shr.o) shared, rtl:yes
-	#            lib.a(lib.so.V) shared, rtl:no,  for executables
-	# "both,yes" lib.so.V(shr.o) shared, rtl:yes, for executables
-	#            lib.a(lib.so.V) shared, rtl:no
-	# "svr4,*"   lib.so.V(shr.o) shared, rtl:yes, for executables
-	#            lib.a           static archive
+	# need to do runtime linking.
 	case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*)
 	  for ld_flag in $LDFLAGS; do
-	  if (test x-brtl = "x$ld_flag" || test x-Wl,-brtl = "x$ld_flag"); then
+	  if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then
 	    aix_use_runtimelinking=yes
 	    break
 	  fi
 	  done
-	  if test svr4,no = "$with_aix_soname,$aix_use_runtimelinking"; then
-	    # With aix-soname=svr4, we create the lib.so.V shared archives only,
-	    # so we don't have lib.a shared libs to link our executables.
-	    # We have to force runtime linking in this case.
-	    aix_use_runtimelinking=yes
-	    LDFLAGS="$LDFLAGS -Wl,-brtl"
-	  fi
 	  ;;
 	esac
 
@@ -10423,21 +10095,13 @@ _LT_EOF
       hardcode_direct_absolute=yes
       hardcode_libdir_separator=':'
       link_all_deplibs=yes
-      file_list_spec='$wl-f,'
-      case $with_aix_soname,$aix_use_runtimelinking in
-      aix,*) ;; # traditional, no import file
-      svr4,* | *,yes) # use import file
-	# The Import File defines what to hardcode.
-	hardcode_direct=no
-	hardcode_direct_absolute=no
-	;;
-      esac
+      file_list_spec='${wl}-f,'
 
-      if test yes = "$GCC"; then
+      if test "$GCC" = yes; then
 	case $host_os in aix4.[012]|aix4.[012].*)
 	# We only want to do this on AIX 4.2 and lower, the check
 	# below for broken collect2 doesn't work under 4.3+
-	  collect2name=`$CC -print-prog-name=collect2`
+	  collect2name=`${CC} -print-prog-name=collect2`
 	  if test -f "$collect2name" &&
 	   strings "$collect2name" | $GREP resolve_lib_name >/dev/null
 	  then
@@ -10456,42 +10120,36 @@ _LT_EOF
 	  ;;
 	esac
 	shared_flag='-shared'
-	if test yes = "$aix_use_runtimelinking"; then
-	  shared_flag="$shared_flag "'$wl-G'
+	if test "$aix_use_runtimelinking" = yes; then
+	  shared_flag="$shared_flag "'${wl}-G'
 	fi
-	# Need to ensure runtime linking is disabled for the traditional
-	# shared library, or the linker may eventually find shared libraries
-	# /with/ Import File - we do not want to mix them.
-	shared_flag_aix='-shared'
-	shared_flag_svr4='-shared $wl-G'
+	link_all_deplibs=no
       else
 	# not using gcc
-	if test ia64 = "$host_cpu"; then
+	if test "$host_cpu" = ia64; then
 	# VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release
 	# chokes on -Wl,-G. The following line is correct:
 	  shared_flag='-G'
 	else
-	  if test yes = "$aix_use_runtimelinking"; then
-	    shared_flag='$wl-G'
+	  if test "$aix_use_runtimelinking" = yes; then
+	    shared_flag='${wl}-G'
 	  else
-	    shared_flag='$wl-bM:SRE'
+	    shared_flag='${wl}-bM:SRE'
 	  fi
-	  shared_flag_aix='$wl-bM:SRE'
-	  shared_flag_svr4='$wl-G'
 	fi
       fi
 
-      export_dynamic_flag_spec='$wl-bexpall'
+      export_dynamic_flag_spec='${wl}-bexpall'
       # It seems that -bexpall does not export symbols beginning with
       # underscore (_), so it is better to generate a list of symbols to export.
       always_export_symbols=yes
-      if test aix,yes = "$with_aix_soname,$aix_use_runtimelinking"; then
+      if test "$aix_use_runtimelinking" = yes; then
 	# Warning - without using the other runtime loading flags (-brtl),
 	# -berok will link without error, but may produce a broken library.
 	allow_undefined_flag='-berok'
         # Determine the default libpath from the value encoded in an
         # empty executable.
-        if test set = "${lt_cv_aix_libpath+set}"; then
+        if test "${lt_cv_aix_libpath+set}" = set; then
   aix_libpath=$lt_cv_aix_libpath
 else
   if ${lt_cv_aix_libpath_+:} false; then :
@@ -10526,7 +10184,7 @@ fi
 rm -f core conftest.err conftest.$ac_objext \
     conftest$ac_exeext conftest.$ac_ext
   if test -z "$lt_cv_aix_libpath_"; then
-    lt_cv_aix_libpath_=/usr/lib:/lib
+    lt_cv_aix_libpath_="/usr/lib:/lib"
   fi
 
 fi
@@ -10534,17 +10192,17 @@ fi
   aix_libpath=$lt_cv_aix_libpath_
 fi
 
-        hardcode_libdir_flag_spec='$wl-blibpath:$libdir:'"$aix_libpath"
-        archive_expsym_cmds='$CC -o $output_objdir/$soname $libobjs $deplibs $wl'$no_entry_flag' $compiler_flags `if test -n "$allow_undefined_flag"; then func_echo_all "$wl$allow_undefined_flag"; else :; fi` $wl'$exp_sym_flag:\$export_symbols' '$shared_flag
+        hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath"
+        archive_expsym_cmds='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then func_echo_all "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag"
       else
-	if test ia64 = "$host_cpu"; then
-	  hardcode_libdir_flag_spec='$wl-R $libdir:/usr/lib:/lib'
+	if test "$host_cpu" = ia64; then
+	  hardcode_libdir_flag_spec='${wl}-R $libdir:/usr/lib:/lib'
 	  allow_undefined_flag="-z nodefs"
-	  archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\$wl$no_entry_flag"' $compiler_flags $wl$allow_undefined_flag '"\$wl$exp_sym_flag:\$export_symbols"
+	  archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols"
 	else
 	 # Determine the default libpath from the value encoded in an
 	 # empty executable.
-	 if test set = "${lt_cv_aix_libpath+set}"; then
+	 if test "${lt_cv_aix_libpath+set}" = set; then
   aix_libpath=$lt_cv_aix_libpath
 else
   if ${lt_cv_aix_libpath_+:} false; then :
@@ -10579,7 +10237,7 @@ fi
 rm -f core conftest.err conftest.$ac_objext \
     conftest$ac_exeext conftest.$ac_ext
   if test -z "$lt_cv_aix_libpath_"; then
-    lt_cv_aix_libpath_=/usr/lib:/lib
+    lt_cv_aix_libpath_="/usr/lib:/lib"
   fi
 
 fi
@@ -10587,33 +10245,21 @@ fi
   aix_libpath=$lt_cv_aix_libpath_
 fi
 
-	 hardcode_libdir_flag_spec='$wl-blibpath:$libdir:'"$aix_libpath"
+	 hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath"
 	  # Warning - without using the other run time loading flags,
 	  # -berok will link without error, but may produce a broken library.
-	  no_undefined_flag=' $wl-bernotok'
-	  allow_undefined_flag=' $wl-berok'
-	  if test yes = "$with_gnu_ld"; then
+	  no_undefined_flag=' ${wl}-bernotok'
+	  allow_undefined_flag=' ${wl}-berok'
+	  if test "$with_gnu_ld" = yes; then
 	    # We only use this code for GNU lds that support --whole-archive.
-	    whole_archive_flag_spec='$wl--whole-archive$convenience $wl--no-whole-archive'
+	    whole_archive_flag_spec='${wl}--whole-archive$convenience ${wl}--no-whole-archive'
 	  else
 	    # Exported symbols can be pulled into shared objects from archives
 	    whole_archive_flag_spec='$convenience'
 	  fi
 	  archive_cmds_need_lc=yes
-	  archive_expsym_cmds='$RM -r $output_objdir/$realname.d~$MKDIR $output_objdir/$realname.d'
-	  # -brtl affects multiple linker settings, -berok does not and is overridden later
-	  compiler_flags_filtered='`func_echo_all "$compiler_flags " | $SED -e "s%-brtl\\([, ]\\)%-berok\\1%g"`'
-	  if test svr4 != "$with_aix_soname"; then
-	    # This is similar to how AIX traditionally builds its shared libraries.
-	    archive_expsym_cmds="$archive_expsym_cmds"'~$CC '$shared_flag_aix' -o $output_objdir/$realname.d/$soname $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$realname.d/$soname'
-	  fi
-	  if test aix != "$with_aix_soname"; then
-	    archive_expsym_cmds="$archive_expsym_cmds"'~$CC '$shared_flag_svr4' -o $output_objdir/$realname.d/$shared_archive_member_spec.o $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$STRIP -e $output_objdir/$realname.d/$shared_archive_member_spec.o~( func_echo_all "#! $soname($shared_archive_member_spec.o)"; if test shr_64 = "$shared_archive_member_spec"; then func_echo_all "# 64"; else func_echo_all "# 32"; fi; cat $export_symbols ) >  [...]
-	  else
-	    # used by -dlpreopen to get the symbols
-	    archive_expsym_cmds="$archive_expsym_cmds"'~$MV  $output_objdir/$realname.d/$soname $output_objdir'
-	  fi
-	  archive_expsym_cmds="$archive_expsym_cmds"'~$RM -r $output_objdir/$realname.d'
+	  # This is similar to how AIX traditionally builds its shared libraries.
+	  archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname'
 	fi
       fi
       ;;
@@ -10622,7 +10268,7 @@ fi
       case $host_cpu in
       powerpc)
             # see comment about AmigaOS4 .so support
-            archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+            archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
             archive_expsym_cmds=''
         ;;
       m68k)
@@ -10652,17 +10298,16 @@ fi
 	# Tell ltmain to make .lib files, not .a files.
 	libext=lib
 	# Tell ltmain to make .dll files, not .so files.
-	shrext_cmds=.dll
+	shrext_cmds=".dll"
 	# FIXME: Setting linknames here is a bad hack.
-	archive_cmds='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~linknames='
-	archive_expsym_cmds='if   test DEF = "`$SED -n     -e '\''s/^[	 ]*//'\''     -e '\''/^\(;.*\)*$/d'\''     -e '\''s/^\(EXPORTS\|LIBRARY\)\([	 ].*\)*$/DEF/p'\''     -e q     $export_symbols`" ; then
-            cp "$export_symbols" "$output_objdir/$soname.def";
-            echo "$tool_output_objdir$soname.def" > "$output_objdir/$soname.exp";
-          else
-            $SED -e '\''s/^/-link -EXPORT:/'\'' < $export_symbols > $output_objdir/$soname.exp;
-          fi~
-          $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~
-          linknames='
+	archive_cmds='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-dll~linknames='
+	archive_expsym_cmds='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then
+	    sed -n -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' -e '1\\\!p' < $export_symbols > $output_objdir/$soname.exp;
+	  else
+	    sed -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' < $export_symbols > $output_objdir/$soname.exp;
+	  fi~
+	  $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~
+	  linknames='
 	# The linker will not automatically build a static lib if we build a DLL.
 	# _LT_TAGVAR(old_archive_from_new_cmds, )='true'
 	enable_shared_with_static_runtimes=yes
@@ -10671,18 +10316,18 @@ fi
 	# Don't use ranlib
 	old_postinstall_cmds='chmod 644 $oldlib'
 	postlink_cmds='lt_outputfile="@OUTPUT@"~
-          lt_tool_outputfile="@TOOL_OUTPUT@"~
-          case $lt_outputfile in
-            *.exe|*.EXE) ;;
-            *)
-              lt_outputfile=$lt_outputfile.exe
-              lt_tool_outputfile=$lt_tool_outputfile.exe
-              ;;
-          esac~
-          if test : != "$MANIFEST_TOOL" && test -f "$lt_outputfile.manifest"; then
-            $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1;
-            $RM "$lt_outputfile.manifest";
-          fi'
+	  lt_tool_outputfile="@TOOL_OUTPUT@"~
+	  case $lt_outputfile in
+	    *.exe|*.EXE) ;;
+	    *)
+	      lt_outputfile="$lt_outputfile.exe"
+	      lt_tool_outputfile="$lt_tool_outputfile.exe"
+	      ;;
+	  esac~
+	  if test "$MANIFEST_TOOL" != ":" && test -f "$lt_outputfile.manifest"; then
+	    $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1;
+	    $RM "$lt_outputfile.manifest";
+	  fi'
 	;;
       *)
 	# Assume MSVC wrapper
@@ -10691,7 +10336,7 @@ fi
 	# Tell ltmain to make .lib files, not .a files.
 	libext=lib
 	# Tell ltmain to make .dll files, not .so files.
-	shrext_cmds=.dll
+	shrext_cmds=".dll"
 	# FIXME: Setting linknames here is a bad hack.
 	archive_cmds='$CC -o $lib $libobjs $compiler_flags `func_echo_all "$deplibs" | $SED '\''s/ -lc$//'\''` -link -dll~linknames='
 	# The linker will automatically build a .lib file if we build a DLL.
@@ -10710,24 +10355,24 @@ fi
   hardcode_direct=no
   hardcode_automatic=yes
   hardcode_shlibpath_var=unsupported
-  if test yes = "$lt_cv_ld_force_load"; then
-    whole_archive_flag_spec='`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience $wl-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`'
+  if test "$lt_cv_ld_force_load" = "yes"; then
+    whole_archive_flag_spec='`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience ${wl}-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`'
 
   else
     whole_archive_flag_spec=''
   fi
   link_all_deplibs=yes
-  allow_undefined_flag=$_lt_dar_allow_undefined
+  allow_undefined_flag="$_lt_dar_allow_undefined"
   case $cc_basename in
-     ifort*|nagfor*) _lt_dar_can_shared=yes ;;
+     ifort*) _lt_dar_can_shared=yes ;;
      *) _lt_dar_can_shared=$GCC ;;
   esac
-  if test yes = "$_lt_dar_can_shared"; then
+  if test "$_lt_dar_can_shared" = "yes"; then
     output_verbose_link_cmd=func_echo_all
-    archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dsymutil"
-    module_cmds="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dsymutil"
-    archive_expsym_cmds="sed 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dar_export_syms$_lt_dsymutil"
-    module_expsym_cmds="sed -e 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dar_export_syms$_lt_dsymutil"
+    archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}"
+    module_cmds="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}"
+    archive_expsym_cmds="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}"
+    module_expsym_cmds="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}"
 
   else
   ld_shlibs=no
@@ -10769,33 +10414,33 @@ fi
       ;;
 
     hpux9*)
-      if test yes = "$GCC"; then
-	archive_cmds='$RM $output_objdir/$soname~$CC -shared $pic_flag $wl+b $wl$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib'
+      if test "$GCC" = yes; then
+	archive_cmds='$RM $output_objdir/$soname~$CC -shared $pic_flag ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
       else
-	archive_cmds='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib'
+	archive_cmds='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
       fi
-      hardcode_libdir_flag_spec='$wl+b $wl$libdir'
+      hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
       hardcode_libdir_separator=:
       hardcode_direct=yes
 
       # hardcode_minus_L: Not really in the search PATH,
       # but as the default location of the library.
       hardcode_minus_L=yes
-      export_dynamic_flag_spec='$wl-E'
+      export_dynamic_flag_spec='${wl}-E'
       ;;
 
     hpux10*)
-      if test yes,no = "$GCC,$with_gnu_ld"; then
-	archive_cmds='$CC -shared $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+      if test "$GCC" = yes && test "$with_gnu_ld" = no; then
+	archive_cmds='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
       else
 	archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'
       fi
-      if test no = "$with_gnu_ld"; then
-	hardcode_libdir_flag_spec='$wl+b $wl$libdir'
+      if test "$with_gnu_ld" = no; then
+	hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
 	hardcode_libdir_separator=:
 	hardcode_direct=yes
 	hardcode_direct_absolute=yes
-	export_dynamic_flag_spec='$wl-E'
+	export_dynamic_flag_spec='${wl}-E'
 	# hardcode_minus_L: Not really in the search PATH,
 	# but as the default location of the library.
 	hardcode_minus_L=yes
@@ -10803,25 +10448,25 @@ fi
       ;;
 
     hpux11*)
-      if test yes,no = "$GCC,$with_gnu_ld"; then
+      if test "$GCC" = yes && test "$with_gnu_ld" = no; then
 	case $host_cpu in
 	hppa*64*)
-	  archive_cmds='$CC -shared $wl+h $wl$soname -o $lib $libobjs $deplibs $compiler_flags'
+	  archive_cmds='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
 	  ;;
 	ia64*)
-	  archive_cmds='$CC -shared $pic_flag $wl+h $wl$soname $wl+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
+	  archive_cmds='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
 	  ;;
 	*)
-	  archive_cmds='$CC -shared $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+	  archive_cmds='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
 	  ;;
 	esac
       else
 	case $host_cpu in
 	hppa*64*)
-	  archive_cmds='$CC -b $wl+h $wl$soname -o $lib $libobjs $deplibs $compiler_flags'
+	  archive_cmds='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
 	  ;;
 	ia64*)
-	  archive_cmds='$CC -b $wl+h $wl$soname $wl+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
+	  archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
 	  ;;
 	*)
 
@@ -10833,7 +10478,7 @@ if ${lt_cv_prog_compiler__b+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   lt_cv_prog_compiler__b=no
-   save_LDFLAGS=$LDFLAGS
+   save_LDFLAGS="$LDFLAGS"
    LDFLAGS="$LDFLAGS -b"
    echo "$lt_simple_link_test_code" > conftest.$ac_ext
    if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then
@@ -10852,14 +10497,14 @@ else
      fi
    fi
    $RM -r conftest*
-   LDFLAGS=$save_LDFLAGS
+   LDFLAGS="$save_LDFLAGS"
 
 fi
 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler__b" >&5
 $as_echo "$lt_cv_prog_compiler__b" >&6; }
 
-if test yes = "$lt_cv_prog_compiler__b"; then
-    archive_cmds='$CC -b $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+if test x"$lt_cv_prog_compiler__b" = xyes; then
+    archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
 else
     archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'
 fi
@@ -10867,8 +10512,8 @@ fi
 	  ;;
 	esac
       fi
-      if test no = "$with_gnu_ld"; then
-	hardcode_libdir_flag_spec='$wl+b $wl$libdir'
+      if test "$with_gnu_ld" = no; then
+	hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
 	hardcode_libdir_separator=:
 
 	case $host_cpu in
@@ -10879,7 +10524,7 @@ fi
 	*)
 	  hardcode_direct=yes
 	  hardcode_direct_absolute=yes
-	  export_dynamic_flag_spec='$wl-E'
+	  export_dynamic_flag_spec='${wl}-E'
 
 	  # hardcode_minus_L: Not really in the search PATH,
 	  # but as the default location of the library.
@@ -10890,8 +10535,8 @@ fi
       ;;
 
     irix5* | irix6* | nonstopux*)
-      if test yes = "$GCC"; then
-	archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib'
+      if test "$GCC" = yes; then
+	archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
 	# Try to use the -exported_symbol ld option, if it does not
 	# work, assume that -exports_file does not work either and
 	# implicitly export all symbols.
@@ -10901,8 +10546,8 @@ $as_echo_n "checking whether the $host_os linker accepts -exported_symbol... " >
 if ${lt_cv_irix_exported_symbol+:} false; then :
   $as_echo_n "(cached) " >&6
 else
-  save_LDFLAGS=$LDFLAGS
-	   LDFLAGS="$LDFLAGS -shared $wl-exported_symbol ${wl}foo $wl-update_registry $wl/dev/null"
+  save_LDFLAGS="$LDFLAGS"
+	   LDFLAGS="$LDFLAGS -shared ${wl}-exported_symbol ${wl}foo ${wl}-update_registry ${wl}/dev/null"
 	   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
 int foo (void) { return 0; }
@@ -10914,35 +10559,24 @@ else
 fi
 rm -f core conftest.err conftest.$ac_objext \
     conftest$ac_exeext conftest.$ac_ext
-           LDFLAGS=$save_LDFLAGS
+           LDFLAGS="$save_LDFLAGS"
 fi
 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_irix_exported_symbol" >&5
 $as_echo "$lt_cv_irix_exported_symbol" >&6; }
-	if test yes = "$lt_cv_irix_exported_symbol"; then
-          archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations $wl-exports_file $wl$export_symbols -o $lib'
+	if test "$lt_cv_irix_exported_symbol" = yes; then
+          archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations ${wl}-exports_file ${wl}$export_symbols -o $lib'
 	fi
-	link_all_deplibs=no
       else
-	archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib'
-	archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -exports_file $export_symbols -o $lib'
+	archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib'
+	archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -exports_file $export_symbols -o $lib'
       fi
       archive_cmds_need_lc='no'
-      hardcode_libdir_flag_spec='$wl-rpath $wl$libdir'
+      hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
       hardcode_libdir_separator=:
       inherit_rpath=yes
       link_all_deplibs=yes
       ;;
 
-    linux*)
-      case $cc_basename in
-      tcc*)
-	# Fabrice Bellard et al's Tiny C Compiler
-	ld_shlibs=yes
-	archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
-	;;
-      esac
-      ;;
-
     netbsd* | netbsdelf*-gnu)
       if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
 	archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'  # a.out
@@ -10957,7 +10591,7 @@ $as_echo "$lt_cv_irix_exported_symbol" >&6; }
     newsos6)
       archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
       hardcode_direct=yes
-      hardcode_libdir_flag_spec='$wl-rpath $wl$libdir'
+      hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
       hardcode_libdir_separator=:
       hardcode_shlibpath_var=no
       ;;
@@ -10965,19 +10599,27 @@ $as_echo "$lt_cv_irix_exported_symbol" >&6; }
     *nto* | *qnx*)
       ;;
 
-    openbsd* | bitrig*)
+    openbsd*)
       if test -f /usr/libexec/ld.so; then
 	hardcode_direct=yes
 	hardcode_shlibpath_var=no
 	hardcode_direct_absolute=yes
-	if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then
+	if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
 	  archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
-	  archive_expsym_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags $wl-retain-symbols-file,$export_symbols'
-	  hardcode_libdir_flag_spec='$wl-rpath,$libdir'
-	  export_dynamic_flag_spec='$wl-E'
+	  archive_expsym_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols'
+	  hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
+	  export_dynamic_flag_spec='${wl}-E'
 	else
-	  archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
-	  hardcode_libdir_flag_spec='$wl-rpath,$libdir'
+	  case $host_os in
+	   openbsd[01].* | openbsd2.[0-7] | openbsd2.[0-7].*)
+	     archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+	     hardcode_libdir_flag_spec='-R$libdir'
+	     ;;
+	   *)
+	     archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+	     hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
+	     ;;
+	  esac
 	fi
       else
 	ld_shlibs=no
@@ -10988,53 +10630,33 @@ $as_echo "$lt_cv_irix_exported_symbol" >&6; }
       hardcode_libdir_flag_spec='-L$libdir'
       hardcode_minus_L=yes
       allow_undefined_flag=unsupported
-      shrext_cmds=.dll
-      archive_cmds='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~
-	$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~
-	$ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~
-	$ECHO EXPORTS >> $output_objdir/$libname.def~
-	emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~
-	$CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~
-	emximp -o $lib $output_objdir/$libname.def'
-      archive_expsym_cmds='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~
-	$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~
-	$ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~
-	$ECHO EXPORTS >> $output_objdir/$libname.def~
-	prefix_cmds="$SED"~
-	if test EXPORTS = "`$SED 1q $export_symbols`"; then
-	  prefix_cmds="$prefix_cmds -e 1d";
-	fi~
-	prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~
-	cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~
-	$CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~
-	emximp -o $lib $output_objdir/$libname.def'
-      old_archive_From_new_cmds='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def'
-      enable_shared_with_static_runtimes=yes
+      archive_cmds='$ECHO "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~echo DATA >> $output_objdir/$libname.def~echo " SINGLE NONSHARED" >> $output_objdir/$libname.def~echo EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def'
+      old_archive_from_new_cmds='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def'
       ;;
 
     osf3*)
-      if test yes = "$GCC"; then
-	allow_undefined_flag=' $wl-expect_unresolved $wl\*'
-	archive_cmds='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib'
+      if test "$GCC" = yes; then
+	allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*'
+	archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
       else
 	allow_undefined_flag=' -expect_unresolved \*'
-	archive_cmds='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib'
+	archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib'
       fi
       archive_cmds_need_lc='no'
-      hardcode_libdir_flag_spec='$wl-rpath $wl$libdir'
+      hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
       hardcode_libdir_separator=:
       ;;
 
     osf4* | osf5*)	# as osf3* with the addition of -msym flag
-      if test yes = "$GCC"; then
-	allow_undefined_flag=' $wl-expect_unresolved $wl\*'
-	archive_cmds='$CC -shared$allow_undefined_flag $pic_flag $libobjs $deplibs $compiler_flags $wl-msym $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib'
-	hardcode_libdir_flag_spec='$wl-rpath $wl$libdir'
+      if test "$GCC" = yes; then
+	allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*'
+	archive_cmds='$CC -shared${allow_undefined_flag} $pic_flag $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+	hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
       else
 	allow_undefined_flag=' -expect_unresolved \*'
-	archive_cmds='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib'
+	archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib'
 	archive_expsym_cmds='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~
-          $CC -shared$allow_undefined_flag $wl-input $wl$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib~$RM $lib.exp'
+	$CC -shared${allow_undefined_flag} ${wl}-input ${wl}$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib~$RM $lib.exp'
 
 	# Both c and cxx compiler support -rpath directly
 	hardcode_libdir_flag_spec='-rpath $libdir'
@@ -11045,24 +10667,24 @@ $as_echo "$lt_cv_irix_exported_symbol" >&6; }
 
     solaris*)
       no_undefined_flag=' -z defs'
-      if test yes = "$GCC"; then
-	wlarc='$wl'
-	archive_cmds='$CC -shared $pic_flag $wl-z ${wl}text $wl-h $wl$soname -o $lib $libobjs $deplibs $compiler_flags'
+      if test "$GCC" = yes; then
+	wlarc='${wl}'
+	archive_cmds='$CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
 	archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
-          $CC -shared $pic_flag $wl-z ${wl}text $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp'
+	  $CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp'
       else
 	case `$CC -V 2>&1` in
 	*"Compilers 5.0"*)
 	  wlarc=''
-	  archive_cmds='$LD -G$allow_undefined_flag -h $soname -o $lib $libobjs $deplibs $linker_flags'
+	  archive_cmds='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags'
 	  archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
-            $LD -G$allow_undefined_flag -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp'
+	  $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp'
 	  ;;
 	*)
-	  wlarc='$wl'
-	  archive_cmds='$CC -G$allow_undefined_flag -h $soname -o $lib $libobjs $deplibs $compiler_flags'
+	  wlarc='${wl}'
+	  archive_cmds='$CC -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $compiler_flags'
 	  archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
-            $CC -G$allow_undefined_flag -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp'
+	  $CC -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp'
 	  ;;
 	esac
       fi
@@ -11072,11 +10694,11 @@ $as_echo "$lt_cv_irix_exported_symbol" >&6; }
       solaris2.[0-5] | solaris2.[0-5].*) ;;
       *)
 	# The compiler driver will combine and reorder linker options,
-	# but understands '-z linker_flag'.  GCC discards it without '$wl',
+	# but understands `-z linker_flag'.  GCC discards it without `$wl',
 	# but is careful enough not to reorder.
 	# Supported since Solaris 2.6 (maybe 2.5.1?)
-	if test yes = "$GCC"; then
-	  whole_archive_flag_spec='$wl-z ${wl}allextract$convenience $wl-z ${wl}defaultextract'
+	if test "$GCC" = yes; then
+	  whole_archive_flag_spec='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract'
 	else
 	  whole_archive_flag_spec='-z allextract$convenience -z defaultextract'
 	fi
@@ -11086,10 +10708,10 @@ $as_echo "$lt_cv_irix_exported_symbol" >&6; }
       ;;
 
     sunos4*)
-      if test sequent = "$host_vendor"; then
+      if test "x$host_vendor" = xsequent; then
 	# Use $CC to link under sequent, because it throws in some extra .o
 	# files that make .init and .fini sections work.
-	archive_cmds='$CC -G $wl-h $soname -o $lib $libobjs $deplibs $compiler_flags'
+	archive_cmds='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags'
       else
 	archive_cmds='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags'
       fi
@@ -11138,43 +10760,43 @@ $as_echo "$lt_cv_irix_exported_symbol" >&6; }
       ;;
 
     sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*)
-      no_undefined_flag='$wl-z,text'
+      no_undefined_flag='${wl}-z,text'
       archive_cmds_need_lc=no
       hardcode_shlibpath_var=no
       runpath_var='LD_RUN_PATH'
 
-      if test yes = "$GCC"; then
-	archive_cmds='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
-	archive_expsym_cmds='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+      if test "$GCC" = yes; then
+	archive_cmds='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	archive_expsym_cmds='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
       else
-	archive_cmds='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
-	archive_expsym_cmds='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	archive_cmds='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	archive_expsym_cmds='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
       fi
       ;;
 
     sysv5* | sco3.2v5* | sco5v6*)
-      # Note: We CANNOT use -z defs as we might desire, because we do not
+      # Note: We can NOT use -z defs as we might desire, because we do not
       # link with -lc, and that would cause any symbols used from libc to
       # always be unresolved, which means just about no library would
       # ever link correctly.  If we're not using GNU ld we use -z text
       # though, which does catch some bad symbols but isn't as heavy-handed
       # as -z defs.
-      no_undefined_flag='$wl-z,text'
-      allow_undefined_flag='$wl-z,nodefs'
+      no_undefined_flag='${wl}-z,text'
+      allow_undefined_flag='${wl}-z,nodefs'
       archive_cmds_need_lc=no
       hardcode_shlibpath_var=no
-      hardcode_libdir_flag_spec='$wl-R,$libdir'
+      hardcode_libdir_flag_spec='${wl}-R,$libdir'
       hardcode_libdir_separator=':'
       link_all_deplibs=yes
-      export_dynamic_flag_spec='$wl-Bexport'
+      export_dynamic_flag_spec='${wl}-Bexport'
       runpath_var='LD_RUN_PATH'
 
-      if test yes = "$GCC"; then
-	archive_cmds='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
-	archive_expsym_cmds='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+      if test "$GCC" = yes; then
+	archive_cmds='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	archive_expsym_cmds='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
       else
-	archive_cmds='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
-	archive_expsym_cmds='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	archive_cmds='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	archive_expsym_cmds='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
       fi
       ;;
 
@@ -11189,10 +10811,10 @@ $as_echo "$lt_cv_irix_exported_symbol" >&6; }
       ;;
     esac
 
-    if test sni = "$host_vendor"; then
+    if test x$host_vendor = xsni; then
       case $host in
       sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*)
-	export_dynamic_flag_spec='$wl-Blargedynsym'
+	export_dynamic_flag_spec='${wl}-Blargedynsym'
 	;;
       esac
     fi
@@ -11200,7 +10822,7 @@ $as_echo "$lt_cv_irix_exported_symbol" >&6; }
 
 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs" >&5
 $as_echo "$ld_shlibs" >&6; }
-test no = "$ld_shlibs" && can_build_shared=no
+test "$ld_shlibs" = no && can_build_shared=no
 
 with_gnu_ld=$with_gnu_ld
 
@@ -11226,7 +10848,7 @@ x|xyes)
   # Assume -lc should be added
   archive_cmds_need_lc=yes
 
-  if test yes,yes = "$GCC,$enable_shared"; then
+  if test "$enable_shared" = yes && test "$GCC" = yes; then
     case $archive_cmds in
     *'~'*)
       # FIXME: we may have to deal with multi-command sequences.
@@ -11441,14 +11063,14 @@ esac
   { $as_echo "$as_me:${as_lineno-$LINENO}: checking dynamic linker characteristics" >&5
 $as_echo_n "checking dynamic linker characteristics... " >&6; }
 
-if test yes = "$GCC"; then
+if test "$GCC" = yes; then
   case $host_os in
-    darwin*) lt_awk_arg='/^libraries:/,/LR/' ;;
-    *) lt_awk_arg='/^libraries:/' ;;
+    darwin*) lt_awk_arg="/^libraries:/,/LR/" ;;
+    *) lt_awk_arg="/^libraries:/" ;;
   esac
   case $host_os in
-    mingw* | cegcc*) lt_sed_strip_eq='s|=\([A-Za-z]:\)|\1|g' ;;
-    *) lt_sed_strip_eq='s|=/|/|g' ;;
+    mingw* | cegcc*) lt_sed_strip_eq="s,=\([A-Za-z]:\),\1,g" ;;
+    *) lt_sed_strip_eq="s,=/,/,g" ;;
   esac
   lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e $lt_sed_strip_eq`
   case $lt_search_path_spec in
@@ -11464,35 +11086,28 @@ if test yes = "$GCC"; then
     ;;
   esac
   # Ok, now we have the path, separated by spaces, we can step through it
-  # and add multilib dir if necessary...
+  # and add multilib dir if necessary.
   lt_tmp_lt_search_path_spec=
-  lt_multi_os_dir=/`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null`
-  # ...but if some path component already ends with the multilib dir we assume
-  # that all is fine and trust -print-search-dirs as is (GCC 4.2? or newer).
-  case "$lt_multi_os_dir; $lt_search_path_spec " in
-  "/; "* | "/.; "* | "/./; "* | *"$lt_multi_os_dir "* | *"$lt_multi_os_dir/ "*)
-    lt_multi_os_dir=
-    ;;
-  esac
+  lt_multi_os_dir=`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null`
   for lt_sys_path in $lt_search_path_spec; do
-    if test -d "$lt_sys_path$lt_multi_os_dir"; then
-      lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path$lt_multi_os_dir"
-    elif test -n "$lt_multi_os_dir"; then
+    if test -d "$lt_sys_path/$lt_multi_os_dir"; then
+      lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path/$lt_multi_os_dir"
+    else
       test -d "$lt_sys_path" && \
 	lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path"
     fi
   done
   lt_search_path_spec=`$ECHO "$lt_tmp_lt_search_path_spec" | awk '
-BEGIN {RS = " "; FS = "/|\n";} {
-  lt_foo = "";
-  lt_count = 0;
+BEGIN {RS=" "; FS="/|\n";} {
+  lt_foo="";
+  lt_count=0;
   for (lt_i = NF; lt_i > 0; lt_i--) {
     if ($lt_i != "" && $lt_i != ".") {
       if ($lt_i == "..") {
         lt_count++;
       } else {
         if (lt_count == 0) {
-          lt_foo = "/" $lt_i lt_foo;
+          lt_foo="/" $lt_i lt_foo;
         } else {
           lt_count--;
         }
@@ -11506,7 +11121,7 @@ BEGIN {RS = " "; FS = "/|\n";} {
   # for these hosts.
   case $host_os in
     mingw* | cegcc*) lt_search_path_spec=`$ECHO "$lt_search_path_spec" |\
-      $SED 's|/\([A-Za-z]:\)|\1|g'` ;;
+      $SED 's,/\([A-Za-z]:\),\1,g'` ;;
   esac
   sys_lib_search_path_spec=`$ECHO "$lt_search_path_spec" | $lt_NL2SP`
 else
@@ -11515,7 +11130,7 @@ fi
 library_names_spec=
 libname_spec='lib$name'
 soname_spec=
-shrext_cmds=.so
+shrext_cmds=".so"
 postinstall_cmds=
 postuninstall_cmds=
 finish_cmds=
@@ -11532,16 +11147,14 @@ hardcode_into_libs=no
 # flags to be left without arguments
 need_version=unknown
 
-
-
 case $host_os in
 aix3*)
   version_type=linux # correct to gnu/linux during the next big refactor
-  library_names_spec='$libname$release$shared_ext$versuffix $libname.a'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a'
   shlibpath_var=LIBPATH
 
   # AIX 3 has no versioning support, so we append a major version to the name.
-  soname_spec='$libname$release$shared_ext$major'
+  soname_spec='${libname}${release}${shared_ext}$major'
   ;;
 
 aix[4-9]*)
@@ -11549,91 +11162,41 @@ aix[4-9]*)
   need_lib_prefix=no
   need_version=no
   hardcode_into_libs=yes
-  if test ia64 = "$host_cpu"; then
+  if test "$host_cpu" = ia64; then
     # AIX 5 supports IA64
-    library_names_spec='$libname$release$shared_ext$major $libname$release$shared_ext$versuffix $libname$shared_ext'
+    library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}'
     shlibpath_var=LD_LIBRARY_PATH
   else
     # With GCC up to 2.95.x, collect2 would create an import file
     # for dependence libraries.  The import file would start with
-    # the line '#! .'.  This would cause the generated library to
-    # depend on '.', always an invalid library.  This was fixed in
+    # the line `#! .'.  This would cause the generated library to
+    # depend on `.', always an invalid library.  This was fixed in
     # development snapshots of GCC prior to 3.0.
     case $host_os in
       aix4 | aix4.[01] | aix4.[01].*)
       if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)'
 	   echo ' yes '
-	   echo '#endif'; } | $CC -E - | $GREP yes > /dev/null; then
+	   echo '#endif'; } | ${CC} -E - | $GREP yes > /dev/null; then
 	:
       else
 	can_build_shared=no
       fi
       ;;
     esac
-    # Using Import Files as archive members, it is possible to support
-    # filename-based versioning of shared library archives on AIX. While
-    # this would work for both with and without runtime linking, it will
-    # prevent static linking of such archives. So we do filename-based
-    # shared library versioning with .so extension only, which is used
-    # when both runtime linking and shared linking is enabled.
-    # Unfortunately, runtime linking may impact performance, so we do
-    # not want this to be the default eventually. Also, we use the
-    # versioned .so libs for executables only if there is the -brtl
-    # linker flag in LDFLAGS as well, or --with-aix-soname=svr4 only.
-    # To allow for filename-based versioning support, we need to create
-    # libNAME.so.V as an archive file, containing:
-    # *) an Import File, referring to the versioned filename of the
-    #    archive as well as the shared archive member, telling the
-    #    bitwidth (32 or 64) of that shared object, and providing the
-    #    list of exported symbols of that shared object, eventually
-    #    decorated with the 'weak' keyword
-    # *) the shared object with the F_LOADONLY flag set, to really avoid
-    #    it being seen by the linker.
-    # At run time we better use the real file rather than another symlink,
-    # but for link time we create the symlink libNAME.so -> libNAME.so.V
-
-    case $with_aix_soname,$aix_use_runtimelinking in
-    # AIX (on Power*) has no versioning support, so currently we cannot hardcode correct
+    # AIX (on Power*) has no versioning support, so currently we can not hardcode correct
     # soname into executable. Probably we can add versioning support to
     # collect2, so additional links can be useful in future.
-    aix,yes) # traditional libtool
-      dynamic_linker='AIX unversionable lib.so'
+    if test "$aix_use_runtimelinking" = yes; then
       # If using run time linking (on AIX 4.2 or later) use lib<name>.so
       # instead of lib<name>.a to let people know that these are not
       # typical AIX shared libraries.
-      library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
-      ;;
-    aix,no) # traditional AIX only
-      dynamic_linker='AIX lib.a(lib.so.V)'
+      library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+    else
       # We preserve .a as extension for shared libraries through AIX4.2
       # and later when we are not doing run time linking.
-      library_names_spec='$libname$release.a $libname.a'
-      soname_spec='$libname$release$shared_ext$major'
-      ;;
-    svr4,*) # full svr4 only
-      dynamic_linker="AIX lib.so.V($shared_archive_member_spec.o)"
-      library_names_spec='$libname$release$shared_ext$major $libname$shared_ext'
-      # We do not specify a path in Import Files, so LIBPATH fires.
-      shlibpath_overrides_runpath=yes
-      ;;
-    *,yes) # both, prefer svr4
-      dynamic_linker="AIX lib.so.V($shared_archive_member_spec.o), lib.a(lib.so.V)"
-      library_names_spec='$libname$release$shared_ext$major $libname$shared_ext'
-      # unpreferred sharedlib libNAME.a needs extra handling
-      postinstall_cmds='test -n "$linkname" || linkname="$realname"~func_stripname "" ".so" "$linkname"~$install_shared_prog "$dir/$func_stripname_result.$libext" "$destdir/$func_stripname_result.$libext"~test -z "$tstripme" || test -z "$striplib" || $striplib "$destdir/$func_stripname_result.$libext"'
-      postuninstall_cmds='for n in $library_names $old_library; do :; done~func_stripname "" ".so" "$n"~test "$func_stripname_result" = "$n" || func_append rmfiles " $odir/$func_stripname_result.$libext"'
-      # We do not specify a path in Import Files, so LIBPATH fires.
-      shlibpath_overrides_runpath=yes
-      ;;
-    *,no) # both, prefer aix
-      dynamic_linker="AIX lib.a(lib.so.V), lib.so.V($shared_archive_member_spec.o)"
-      library_names_spec='$libname$release.a $libname.a'
-      soname_spec='$libname$release$shared_ext$major'
-      # unpreferred sharedlib libNAME.so.V and symlink libNAME.so need extra handling
-      postinstall_cmds='test -z "$dlname" || $install_shared_prog $dir/$dlname $destdir/$dlname~test -z "$tstripme" || test -z "$striplib" || $striplib $destdir/$dlname~test -n "$linkname" || linkname=$realname~func_stripname "" ".a" "$linkname"~(cd "$destdir" && $LN_S -f $dlname $func_stripname_result.so)'
-      postuninstall_cmds='test -z "$dlname" || func_append rmfiles " $odir/$dlname"~for n in $old_library $library_names; do :; done~func_stripname "" ".a" "$n"~func_append rmfiles " $odir/$func_stripname_result.so"'
-      ;;
-    esac
+      library_names_spec='${libname}${release}.a $libname.a'
+      soname_spec='${libname}${release}${shared_ext}$major'
+    fi
     shlibpath_var=LIBPATH
   fi
   ;;
@@ -11643,18 +11206,18 @@ amigaos*)
   powerpc)
     # Since July 2007 AmigaOS4 officially supports .so libraries.
     # When compiling the executable, add -use-dynld -Lsobjs: to the compileline.
-    library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
     ;;
   m68k)
     library_names_spec='$libname.ixlibrary $libname.a'
     # Create ${libname}_ixlibrary.a entries in /sys/libs.
-    finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done'
+    finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done'
     ;;
   esac
   ;;
 
 beos*)
-  library_names_spec='$libname$shared_ext'
+  library_names_spec='${libname}${shared_ext}'
   dynamic_linker="$host_os ld.so"
   shlibpath_var=LIBRARY_PATH
   ;;
@@ -11662,8 +11225,8 @@ beos*)
 bsdi[45]*)
   version_type=linux # correct to gnu/linux during the next big refactor
   need_version=no
-  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
-  soname_spec='$libname$release$shared_ext$major'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
   finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir'
   shlibpath_var=LD_LIBRARY_PATH
   sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib"
@@ -11675,7 +11238,7 @@ bsdi[45]*)
 
 cygwin* | mingw* | pw32* | cegcc*)
   version_type=windows
-  shrext_cmds=.dll
+  shrext_cmds=".dll"
   need_version=no
   need_lib_prefix=no
 
@@ -11684,8 +11247,8 @@ cygwin* | mingw* | pw32* | cegcc*)
     # gcc
     library_names_spec='$libname.dll.a'
     # DLL is installed to $(libdir)/../bin by postinstall_cmds
-    postinstall_cmds='base_file=`basename \$file`~
-      dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~
+    postinstall_cmds='base_file=`basename \${file}`~
+      dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~
       dldir=$destdir/`dirname \$dlpath`~
       test -d \$dldir || mkdir -p \$dldir~
       $install_prog $dir/$dlname \$dldir/$dlname~
@@ -11701,17 +11264,17 @@ cygwin* | mingw* | pw32* | cegcc*)
     case $host_os in
     cygwin*)
       # Cygwin DLLs use 'cyg' prefix rather than 'lib'
-      soname_spec='`echo $libname | sed -e 's/^lib/cyg/'``echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext'
+      soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
 
       sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/lib/w32api"
       ;;
     mingw* | cegcc*)
       # MinGW DLLs use traditional 'lib' prefix
-      soname_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext'
+      soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
       ;;
     pw32*)
       # pw32 DLLs use 'pw' prefix rather than 'lib'
-      library_names_spec='`echo $libname | sed -e 's/^lib/pw/'``echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext'
+      library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
       ;;
     esac
     dynamic_linker='Win32 ld.exe'
@@ -11720,8 +11283,8 @@ cygwin* | mingw* | pw32* | cegcc*)
   *,cl*)
     # Native MSVC
     libname_spec='$name'
-    soname_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext'
-    library_names_spec='$libname.dll.lib'
+    soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
+    library_names_spec='${libname}.dll.lib'
 
     case $build_os in
     mingw*)
@@ -11748,7 +11311,7 @@ cygwin* | mingw* | pw32* | cegcc*)
       sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"`
       ;;
     *)
-      sys_lib_search_path_spec=$LIB
+      sys_lib_search_path_spec="$LIB"
       if $ECHO "$sys_lib_search_path_spec" | $GREP ';[c-zC-Z]:/' >/dev/null; then
         # It is most probably a Windows format PATH.
         sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'`
@@ -11761,8 +11324,8 @@ cygwin* | mingw* | pw32* | cegcc*)
     esac
 
     # DLL is installed to $(libdir)/../bin by postinstall_cmds
-    postinstall_cmds='base_file=`basename \$file`~
-      dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~
+    postinstall_cmds='base_file=`basename \${file}`~
+      dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~
       dldir=$destdir/`dirname \$dlpath`~
       test -d \$dldir || mkdir -p \$dldir~
       $install_prog $dir/$dlname \$dldir/$dlname'
@@ -11775,7 +11338,7 @@ cygwin* | mingw* | pw32* | cegcc*)
 
   *)
     # Assume MSVC wrapper
-    library_names_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext $libname.lib'
+    library_names_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext} $libname.lib'
     dynamic_linker='Win32 ld.exe'
     ;;
   esac
@@ -11788,8 +11351,8 @@ darwin* | rhapsody*)
   version_type=darwin
   need_lib_prefix=no
   need_version=no
-  library_names_spec='$libname$release$major$shared_ext $libname$shared_ext'
-  soname_spec='$libname$release$major$shared_ext'
+  library_names_spec='${libname}${release}${major}$shared_ext ${libname}$shared_ext'
+  soname_spec='${libname}${release}${major}$shared_ext'
   shlibpath_overrides_runpath=yes
   shlibpath_var=DYLD_LIBRARY_PATH
   shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`'
@@ -11802,8 +11365,8 @@ dgux*)
   version_type=linux # correct to gnu/linux during the next big refactor
   need_lib_prefix=no
   need_version=no
-  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
-  soname_spec='$libname$release$shared_ext$major'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext'
+  soname_spec='${libname}${release}${shared_ext}$major'
   shlibpath_var=LD_LIBRARY_PATH
   ;;
 
@@ -11821,13 +11384,12 @@ freebsd* | dragonfly*)
   version_type=freebsd-$objformat
   case $version_type in
     freebsd-elf*)
-      library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
-      soname_spec='$libname$release$shared_ext$major'
+      library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}'
       need_version=no
       need_lib_prefix=no
       ;;
     freebsd-*)
-      library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix'
+      library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix'
       need_version=yes
       ;;
   esac
@@ -11857,10 +11419,10 @@ haiku*)
   need_lib_prefix=no
   need_version=no
   dynamic_linker="$host_os runtime_loader"
-  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
-  soname_spec='$libname$release$shared_ext$major'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
   shlibpath_var=LIBRARY_PATH
-  shlibpath_overrides_runpath=no
+  shlibpath_overrides_runpath=yes
   sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib'
   hardcode_into_libs=yes
   ;;
@@ -11878,15 +11440,14 @@ hpux9* | hpux10* | hpux11*)
     dynamic_linker="$host_os dld.so"
     shlibpath_var=LD_LIBRARY_PATH
     shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
-    library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
-    soname_spec='$libname$release$shared_ext$major'
-    if test 32 = "$HPUX_IA64_MODE"; then
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+    soname_spec='${libname}${release}${shared_ext}$major'
+    if test "X$HPUX_IA64_MODE" = X32; then
       sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib"
-      sys_lib_dlsearch_path_spec=/usr/lib/hpux32
     else
       sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64"
-      sys_lib_dlsearch_path_spec=/usr/lib/hpux64
     fi
+    sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
     ;;
   hppa*64*)
     shrext_cmds='.sl'
@@ -11894,8 +11455,8 @@ hpux9* | hpux10* | hpux11*)
     dynamic_linker="$host_os dld.sl"
     shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH
     shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
-    library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
-    soname_spec='$libname$release$shared_ext$major'
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+    soname_spec='${libname}${release}${shared_ext}$major'
     sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64"
     sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
     ;;
@@ -11904,8 +11465,8 @@ hpux9* | hpux10* | hpux11*)
     dynamic_linker="$host_os dld.sl"
     shlibpath_var=SHLIB_PATH
     shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH
-    library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
-    soname_spec='$libname$release$shared_ext$major'
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+    soname_spec='${libname}${release}${shared_ext}$major'
     ;;
   esac
   # HP-UX runs *really* slowly unless shared libraries are mode 555, ...
@@ -11918,8 +11479,8 @@ interix[3-9]*)
   version_type=linux # correct to gnu/linux during the next big refactor
   need_lib_prefix=no
   need_version=no
-  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
-  soname_spec='$libname$release$shared_ext$major'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
   dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)'
   shlibpath_var=LD_LIBRARY_PATH
   shlibpath_overrides_runpath=no
@@ -11930,7 +11491,7 @@ irix5* | irix6* | nonstopux*)
   case $host_os in
     nonstopux*) version_type=nonstopux ;;
     *)
-	if test yes = "$lt_cv_prog_gnu_ld"; then
+	if test "$lt_cv_prog_gnu_ld" = yes; then
 		version_type=linux # correct to gnu/linux during the next big refactor
 	else
 		version_type=irix
@@ -11938,8 +11499,8 @@ irix5* | irix6* | nonstopux*)
   esac
   need_lib_prefix=no
   need_version=no
-  soname_spec='$libname$release$shared_ext$major'
-  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$release$shared_ext $libname$shared_ext'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}'
   case $host_os in
   irix5* | nonstopux*)
     libsuff= shlibsuff=
@@ -11958,8 +11519,8 @@ irix5* | irix6* | nonstopux*)
   esac
   shlibpath_var=LD_LIBRARY${shlibsuff}_PATH
   shlibpath_overrides_runpath=no
-  sys_lib_search_path_spec="/usr/lib$libsuff /lib$libsuff /usr/local/lib$libsuff"
-  sys_lib_dlsearch_path_spec="/usr/lib$libsuff /lib$libsuff"
+  sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}"
+  sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}"
   hardcode_into_libs=yes
   ;;
 
@@ -11968,33 +11529,13 @@ linux*oldld* | linux*aout* | linux*coff*)
   dynamic_linker=no
   ;;
 
-linux*android*)
-  version_type=none # Android doesn't support versioned libraries.
-  need_lib_prefix=no
-  need_version=no
-  library_names_spec='$libname$release$shared_ext'
-  soname_spec='$libname$release$shared_ext'
-  finish_cmds=
-  shlibpath_var=LD_LIBRARY_PATH
-  shlibpath_overrides_runpath=yes
-
-  # This implies no fast_install, which is unacceptable.
-  # Some rework will be needed to allow for fast_install
-  # before this can be enabled.
-  hardcode_into_libs=yes
-
-  dynamic_linker='Android linker'
-  # Don't embed -rpath directories since the linker doesn't support them.
-  hardcode_libdir_flag_spec='-L$libdir'
-  ;;
-
 # This must be glibc/ELF.
 linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*)
   version_type=linux # correct to gnu/linux during the next big refactor
   need_lib_prefix=no
   need_version=no
-  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
-  soname_spec='$libname$release$shared_ext$major'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
   finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir'
   shlibpath_var=LD_LIBRARY_PATH
   shlibpath_overrides_runpath=no
@@ -12038,12 +11579,7 @@ fi
   # before this can be enabled.
   hardcode_into_libs=yes
 
-  # Ideally, we could use ldconfig to report *all* directores which are
-  # searched for libraries, however this is still not possible.  Aside from not
-  # being certain /sbin/ldconfig is available, command
-  # 'ldconfig -N -X -v | grep ^/' on 64bit Fedora does not report /usr/lib64,
-  # even though it is searched at run-time.  Try to do the best guess by
-  # appending ld.so.conf contents (and includes) to the search path.
+  # Append ld.so.conf contents to the search path
   if test -f /etc/ld.so.conf; then
     lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[	 ]*hwcap[	 ]/d;s/[:,	]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '`
     sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra"
@@ -12075,12 +11611,12 @@ netbsd*)
   need_lib_prefix=no
   need_version=no
   if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
-    library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix'
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
     finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
     dynamic_linker='NetBSD (a.out) ld.so'
   else
-    library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
-    soname_spec='$libname$release$shared_ext$major'
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+    soname_spec='${libname}${release}${shared_ext}$major'
     dynamic_linker='NetBSD ld.elf_so'
   fi
   shlibpath_var=LD_LIBRARY_PATH
@@ -12090,7 +11626,7 @@ netbsd*)
 
 newsos6)
   version_type=linux # correct to gnu/linux during the next big refactor
-  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
   shlibpath_var=LD_LIBRARY_PATH
   shlibpath_overrides_runpath=yes
   ;;
@@ -12099,68 +11635,58 @@ newsos6)
   version_type=qnx
   need_lib_prefix=no
   need_version=no
-  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
-  soname_spec='$libname$release$shared_ext$major'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
   shlibpath_var=LD_LIBRARY_PATH
   shlibpath_overrides_runpath=no
   hardcode_into_libs=yes
   dynamic_linker='ldqnx.so'
   ;;
 
-openbsd* | bitrig*)
+openbsd*)
   version_type=sunos
-  sys_lib_dlsearch_path_spec=/usr/lib
+  sys_lib_dlsearch_path_spec="/usr/lib"
   need_lib_prefix=no
-  if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then
-    need_version=no
-  else
-    need_version=yes
-  fi
-  library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix'
+  # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs.
+  case $host_os in
+    openbsd3.3 | openbsd3.3.*)	need_version=yes ;;
+    *)				need_version=no  ;;
+  esac
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
   finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
   shlibpath_var=LD_LIBRARY_PATH
-  shlibpath_overrides_runpath=yes
+  if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+    case $host_os in
+      openbsd2.[89] | openbsd2.[89].*)
+	shlibpath_overrides_runpath=no
+	;;
+      *)
+	shlibpath_overrides_runpath=yes
+	;;
+      esac
+  else
+    shlibpath_overrides_runpath=yes
+  fi
   ;;
 
 os2*)
   libname_spec='$name'
-  version_type=windows
-  shrext_cmds=.dll
-  need_version=no
+  shrext_cmds=".dll"
   need_lib_prefix=no
-  # OS/2 can only load a DLL with a base name of 8 characters or less.
-  soname_spec='`test -n "$os2dllname" && libname="$os2dllname";
-    v=$($ECHO $release$versuffix | tr -d .-);
-    n=$($ECHO $libname | cut -b -$((8 - ${#v})) | tr . _);
-    $ECHO $n$v`$shared_ext'
-  library_names_spec='${libname}_dll.$libext'
+  library_names_spec='$libname${shared_ext} $libname.a'
   dynamic_linker='OS/2 ld.exe'
-  shlibpath_var=BEGINLIBPATH
-  sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib"
-  sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
-  postinstall_cmds='base_file=`basename \$file`~
-    dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; $ECHO \$dlname'\''`~
-    dldir=$destdir/`dirname \$dlpath`~
-    test -d \$dldir || mkdir -p \$dldir~
-    $install_prog $dir/$dlname \$dldir/$dlname~
-    chmod a+x \$dldir/$dlname~
-    if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then
-      eval '\''$striplib \$dldir/$dlname'\'' || exit \$?;
-    fi'
-  postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; $ECHO \$dlname'\''`~
-    dlpath=$dir/\$dldll~
-    $RM \$dlpath'
+  shlibpath_var=LIBPATH
   ;;
 
 osf3* | osf4* | osf5*)
   version_type=osf
   need_lib_prefix=no
   need_version=no
-  soname_spec='$libname$release$shared_ext$major'
-  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
   shlibpath_var=LD_LIBRARY_PATH
   sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib"
-  sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
+  sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec"
   ;;
 
 rdos*)
@@ -12171,8 +11697,8 @@ solaris*)
   version_type=linux # correct to gnu/linux during the next big refactor
   need_lib_prefix=no
   need_version=no
-  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
-  soname_spec='$libname$release$shared_ext$major'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
   shlibpath_var=LD_LIBRARY_PATH
   shlibpath_overrides_runpath=yes
   hardcode_into_libs=yes
@@ -12182,11 +11708,11 @@ solaris*)
 
 sunos4*)
   version_type=sunos
-  library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
   finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir'
   shlibpath_var=LD_LIBRARY_PATH
   shlibpath_overrides_runpath=yes
-  if test yes = "$with_gnu_ld"; then
+  if test "$with_gnu_ld" = yes; then
     need_lib_prefix=no
   fi
   need_version=yes
@@ -12194,8 +11720,8 @@ sunos4*)
 
 sysv4 | sysv4.3*)
   version_type=linux # correct to gnu/linux during the next big refactor
-  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
-  soname_spec='$libname$release$shared_ext$major'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
   shlibpath_var=LD_LIBRARY_PATH
   case $host_vendor in
     sni)
@@ -12216,24 +11742,24 @@ sysv4 | sysv4.3*)
   ;;
 
 sysv4*MP*)
-  if test -d /usr/nec; then
+  if test -d /usr/nec ;then
     version_type=linux # correct to gnu/linux during the next big refactor
-    library_names_spec='$libname$shared_ext.$versuffix $libname$shared_ext.$major $libname$shared_ext'
-    soname_spec='$libname$shared_ext.$major'
+    library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}'
+    soname_spec='$libname${shared_ext}.$major'
     shlibpath_var=LD_LIBRARY_PATH
   fi
   ;;
 
 sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
-  version_type=sco
+  version_type=freebsd-elf
   need_lib_prefix=no
   need_version=no
-  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext $libname$shared_ext'
-  soname_spec='$libname$release$shared_ext$major'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
   shlibpath_var=LD_LIBRARY_PATH
   shlibpath_overrides_runpath=yes
   hardcode_into_libs=yes
-  if test yes = "$with_gnu_ld"; then
+  if test "$with_gnu_ld" = yes; then
     sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib'
   else
     sys_lib_search_path_spec='/usr/ccs/lib /usr/lib'
@@ -12251,7 +11777,7 @@ tpf*)
   version_type=linux # correct to gnu/linux during the next big refactor
   need_lib_prefix=no
   need_version=no
-  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
   shlibpath_var=LD_LIBRARY_PATH
   shlibpath_overrides_runpath=no
   hardcode_into_libs=yes
@@ -12259,8 +11785,8 @@ tpf*)
 
 uts4*)
   version_type=linux # correct to gnu/linux during the next big refactor
-  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
-  soname_spec='$libname$release$shared_ext$major'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
   shlibpath_var=LD_LIBRARY_PATH
   ;;
 
@@ -12270,35 +11796,20 @@ uts4*)
 esac
 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $dynamic_linker" >&5
 $as_echo "$dynamic_linker" >&6; }
-test no = "$dynamic_linker" && can_build_shared=no
+test "$dynamic_linker" = no && can_build_shared=no
 
 variables_saved_for_relink="PATH $shlibpath_var $runpath_var"
-if test yes = "$GCC"; then
+if test "$GCC" = yes; then
   variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH"
 fi
 
-if test set = "${lt_cv_sys_lib_search_path_spec+set}"; then
-  sys_lib_search_path_spec=$lt_cv_sys_lib_search_path_spec
+if test "${lt_cv_sys_lib_search_path_spec+set}" = set; then
+  sys_lib_search_path_spec="$lt_cv_sys_lib_search_path_spec"
 fi
-
-if test set = "${lt_cv_sys_lib_dlsearch_path_spec+set}"; then
-  sys_lib_dlsearch_path_spec=$lt_cv_sys_lib_dlsearch_path_spec
+if test "${lt_cv_sys_lib_dlsearch_path_spec+set}" = set; then
+  sys_lib_dlsearch_path_spec="$lt_cv_sys_lib_dlsearch_path_spec"
 fi
 
-# remember unaugmented sys_lib_dlsearch_path content for libtool script decls...
-configure_time_dlsearch_path=$sys_lib_dlsearch_path_spec
-
-# ... but it needs LT_SYS_LIBRARY_PATH munging for other configure-time code
-func_munge_path_list sys_lib_dlsearch_path_spec "$LT_SYS_LIBRARY_PATH"
-
-# to be used as default LT_SYS_LIBRARY_PATH value in generated libtool
-configure_time_lt_sys_library_path=$LT_SYS_LIBRARY_PATH
-
-
-
-
-
-
 
 
 
@@ -12395,15 +11906,15 @@ $as_echo_n "checking how to hardcode library paths into programs... " >&6; }
 hardcode_action=
 if test -n "$hardcode_libdir_flag_spec" ||
    test -n "$runpath_var" ||
-   test yes = "$hardcode_automatic"; then
+   test "X$hardcode_automatic" = "Xyes" ; then
 
   # We can hardcode non-existent directories.
-  if test no != "$hardcode_direct" &&
+  if test "$hardcode_direct" != no &&
      # If the only mechanism to avoid hardcoding is shlibpath_var, we
      # have to relink, otherwise we might link with an installed library
      # when we should be linking with a yet-to-be-installed one
-     ## test no != "$_LT_TAGVAR(hardcode_shlibpath_var, )" &&
-     test no != "$hardcode_minus_L"; then
+     ## test "$_LT_TAGVAR(hardcode_shlibpath_var, )" != no &&
+     test "$hardcode_minus_L" != no; then
     # Linking always hardcodes the temporary library directory.
     hardcode_action=relink
   else
@@ -12418,12 +11929,12 @@ fi
 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $hardcode_action" >&5
 $as_echo "$hardcode_action" >&6; }
 
-if test relink = "$hardcode_action" ||
-   test yes = "$inherit_rpath"; then
+if test "$hardcode_action" = relink ||
+   test "$inherit_rpath" = yes; then
   # Fast installation is not supported
   enable_fast_install=no
-elif test yes = "$shlibpath_overrides_runpath" ||
-     test no = "$enable_shared"; then
+elif test "$shlibpath_overrides_runpath" = yes ||
+     test "$enable_shared" = no; then
   # Fast installation is not necessary
   enable_fast_install=needless
 fi
@@ -12433,7 +11944,7 @@ fi
 
 
 
-  if test yes != "$enable_dlopen"; then
+  if test "x$enable_dlopen" != xyes; then
   enable_dlopen=unknown
   enable_dlopen_self=unknown
   enable_dlopen_self_static=unknown
@@ -12443,23 +11954,23 @@ else
 
   case $host_os in
   beos*)
-    lt_cv_dlopen=load_add_on
+    lt_cv_dlopen="load_add_on"
     lt_cv_dlopen_libs=
     lt_cv_dlopen_self=yes
     ;;
 
   mingw* | pw32* | cegcc*)
-    lt_cv_dlopen=LoadLibrary
+    lt_cv_dlopen="LoadLibrary"
     lt_cv_dlopen_libs=
     ;;
 
   cygwin*)
-    lt_cv_dlopen=dlopen
+    lt_cv_dlopen="dlopen"
     lt_cv_dlopen_libs=
     ;;
 
   darwin*)
-    # if libdl is installed we need to link against it
+  # if libdl is installed we need to link against it
     { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5
 $as_echo_n "checking for dlopen in -ldl... " >&6; }
 if ${ac_cv_lib_dl_dlopen+:} false; then :
@@ -12497,10 +12008,10 @@ fi
 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5
 $as_echo "$ac_cv_lib_dl_dlopen" >&6; }
 if test "x$ac_cv_lib_dl_dlopen" = xyes; then :
-  lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-ldl
+  lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"
 else
 
-    lt_cv_dlopen=dyld
+    lt_cv_dlopen="dyld"
     lt_cv_dlopen_libs=
     lt_cv_dlopen_self=yes
 
@@ -12508,18 +12019,10 @@ fi
 
     ;;
 
-  tpf*)
-    # Don't try to run any link tests for TPF.  We know it's impossible
-    # because TPF is a cross-compiler, and we know how we open DSOs.
-    lt_cv_dlopen=dlopen
-    lt_cv_dlopen_libs=
-    lt_cv_dlopen_self=no
-    ;;
-
   *)
     ac_fn_c_check_func "$LINENO" "shl_load" "ac_cv_func_shl_load"
 if test "x$ac_cv_func_shl_load" = xyes; then :
-  lt_cv_dlopen=shl_load
+  lt_cv_dlopen="shl_load"
 else
   { $as_echo "$as_me:${as_lineno-$LINENO}: checking for shl_load in -ldld" >&5
 $as_echo_n "checking for shl_load in -ldld... " >&6; }
@@ -12558,11 +12061,11 @@ fi
 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_shl_load" >&5
 $as_echo "$ac_cv_lib_dld_shl_load" >&6; }
 if test "x$ac_cv_lib_dld_shl_load" = xyes; then :
-  lt_cv_dlopen=shl_load lt_cv_dlopen_libs=-ldld
+  lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-ldld"
 else
   ac_fn_c_check_func "$LINENO" "dlopen" "ac_cv_func_dlopen"
 if test "x$ac_cv_func_dlopen" = xyes; then :
-  lt_cv_dlopen=dlopen
+  lt_cv_dlopen="dlopen"
 else
   { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5
 $as_echo_n "checking for dlopen in -ldl... " >&6; }
@@ -12601,7 +12104,7 @@ fi
 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5
 $as_echo "$ac_cv_lib_dl_dlopen" >&6; }
 if test "x$ac_cv_lib_dl_dlopen" = xyes; then :
-  lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-ldl
+  lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"
 else
   { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -lsvld" >&5
 $as_echo_n "checking for dlopen in -lsvld... " >&6; }
@@ -12640,7 +12143,7 @@ fi
 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_svld_dlopen" >&5
 $as_echo "$ac_cv_lib_svld_dlopen" >&6; }
 if test "x$ac_cv_lib_svld_dlopen" = xyes; then :
-  lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-lsvld
+  lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld"
 else
   { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dld_link in -ldld" >&5
 $as_echo_n "checking for dld_link in -ldld... " >&6; }
@@ -12679,7 +12182,7 @@ fi
 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_dld_link" >&5
 $as_echo "$ac_cv_lib_dld_dld_link" >&6; }
 if test "x$ac_cv_lib_dld_dld_link" = xyes; then :
-  lt_cv_dlopen=dld_link lt_cv_dlopen_libs=-ldld
+  lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-ldld"
 fi
 
 
@@ -12700,21 +12203,21 @@ fi
     ;;
   esac
 
-  if test no = "$lt_cv_dlopen"; then
-    enable_dlopen=no
-  else
+  if test "x$lt_cv_dlopen" != xno; then
     enable_dlopen=yes
+  else
+    enable_dlopen=no
   fi
 
   case $lt_cv_dlopen in
   dlopen)
-    save_CPPFLAGS=$CPPFLAGS
-    test yes = "$ac_cv_header_dlfcn_h" && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H"
+    save_CPPFLAGS="$CPPFLAGS"
+    test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H"
 
-    save_LDFLAGS=$LDFLAGS
+    save_LDFLAGS="$LDFLAGS"
     wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\"
 
-    save_LIBS=$LIBS
+    save_LIBS="$LIBS"
     LIBS="$lt_cv_dlopen_libs $LIBS"
 
     { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether a program can dlopen itself" >&5
@@ -12722,7 +12225,7 @@ $as_echo_n "checking whether a program can dlopen itself... " >&6; }
 if ${lt_cv_dlopen_self+:} false; then :
   $as_echo_n "(cached) " >&6
 else
-  	  if test yes = "$cross_compiling"; then :
+  	  if test "$cross_compiling" = yes; then :
   lt_cv_dlopen_self=cross
 else
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
@@ -12769,9 +12272,9 @@ else
 #  endif
 #endif
 
-/* When -fvisibility=hidden is used, assume the code has been annotated
+/* When -fvisbility=hidden is used, assume the code has been annotated
    correspondingly for the symbols needed.  */
-#if defined __GNUC__ && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3))
+#if defined(__GNUC__) && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3))
 int fnord () __attribute__((visibility("default")));
 #endif
 
@@ -12801,7 +12304,7 @@ _LT_EOF
   (eval $ac_link) 2>&5
   ac_status=$?
   $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
-  test $ac_status = 0; } && test -s "conftest$ac_exeext" 2>/dev/null; then
+  test $ac_status = 0; } && test -s conftest${ac_exeext} 2>/dev/null; then
     (./conftest; exit; ) >&5 2>/dev/null
     lt_status=$?
     case x$lt_status in
@@ -12821,14 +12324,14 @@ fi
 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self" >&5
 $as_echo "$lt_cv_dlopen_self" >&6; }
 
-    if test yes = "$lt_cv_dlopen_self"; then
+    if test "x$lt_cv_dlopen_self" = xyes; then
       wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\"
       { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether a statically linked program can dlopen itself" >&5
 $as_echo_n "checking whether a statically linked program can dlopen itself... " >&6; }
 if ${lt_cv_dlopen_self_static+:} false; then :
   $as_echo_n "(cached) " >&6
 else
-  	  if test yes = "$cross_compiling"; then :
+  	  if test "$cross_compiling" = yes; then :
   lt_cv_dlopen_self_static=cross
 else
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
@@ -12875,9 +12378,9 @@ else
 #  endif
 #endif
 
-/* When -fvisibility=hidden is used, assume the code has been annotated
+/* When -fvisbility=hidden is used, assume the code has been annotated
    correspondingly for the symbols needed.  */
-#if defined __GNUC__ && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3))
+#if defined(__GNUC__) && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3))
 int fnord () __attribute__((visibility("default")));
 #endif
 
@@ -12907,7 +12410,7 @@ _LT_EOF
   (eval $ac_link) 2>&5
   ac_status=$?
   $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
-  test $ac_status = 0; } && test -s "conftest$ac_exeext" 2>/dev/null; then
+  test $ac_status = 0; } && test -s conftest${ac_exeext} 2>/dev/null; then
     (./conftest; exit; ) >&5 2>/dev/null
     lt_status=$?
     case x$lt_status in
@@ -12928,9 +12431,9 @@ fi
 $as_echo "$lt_cv_dlopen_self_static" >&6; }
     fi
 
-    CPPFLAGS=$save_CPPFLAGS
-    LDFLAGS=$save_LDFLAGS
-    LIBS=$save_LIBS
+    CPPFLAGS="$save_CPPFLAGS"
+    LDFLAGS="$save_LDFLAGS"
+    LIBS="$save_LIBS"
     ;;
   esac
 
@@ -12974,7 +12477,7 @@ else
 # FIXME - insert some real tests, host_os isn't really good enough
   case $host_os in
   darwin*)
-    if test -n "$STRIP"; then
+    if test -n "$STRIP" ; then
       striplib="$STRIP -x"
       old_striplib="$STRIP -S"
       { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
@@ -13002,7 +12505,7 @@ fi
 
 
 
-  # Report what library types will actually be built
+  # Report which library types will actually be built
   { $as_echo "$as_me:${as_lineno-$LINENO}: checking if libtool supports shared libraries" >&5
 $as_echo_n "checking if libtool supports shared libraries... " >&6; }
   { $as_echo "$as_me:${as_lineno-$LINENO}: result: $can_build_shared" >&5
@@ -13010,13 +12513,13 @@ $as_echo "$can_build_shared" >&6; }
 
   { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build shared libraries" >&5
 $as_echo_n "checking whether to build shared libraries... " >&6; }
-  test no = "$can_build_shared" && enable_shared=no
+  test "$can_build_shared" = "no" && enable_shared=no
 
   # On AIX, shared libraries and static libraries use the same namespace, and
   # are all built from PIC.
   case $host_os in
   aix3*)
-    test yes = "$enable_shared" && enable_static=no
+    test "$enable_shared" = yes && enable_static=no
     if test -n "$RANLIB"; then
       archive_cmds="$archive_cmds~\$RANLIB \$lib"
       postinstall_cmds='$RANLIB $lib'
@@ -13024,12 +12527,8 @@ $as_echo_n "checking whether to build shared libraries... " >&6; }
     ;;
 
   aix[4-9]*)
-    if test ia64 != "$host_cpu"; then
-      case $enable_shared,$with_aix_soname,$aix_use_runtimelinking in
-      yes,aix,yes) ;;			# shared object as lib.so file only
-      yes,svr4,*) ;;			# shared object as lib.so archive member only
-      yes,*) enable_static=no ;;	# shared object in lib.a archive as well
-      esac
+    if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then
+      test "$enable_shared" = yes && enable_static=no
     fi
     ;;
   esac
@@ -13039,7 +12538,7 @@ $as_echo "$enable_shared" >&6; }
   { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build static libraries" >&5
 $as_echo_n "checking whether to build static libraries... " >&6; }
   # Make sure either enable_shared or enable_static is yes.
-  test yes = "$enable_shared" || enable_static=yes
+  test "$enable_shared" = yes || enable_static=yes
   { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_static" >&5
 $as_echo "$enable_static" >&6; }
 
@@ -13053,11 +12552,11 @@ ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
 ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
 ac_compiler_gnu=$ac_cv_c_compiler_gnu
 
-CC=$lt_save_CC
+CC="$lt_save_CC"
 
-      if test -n "$CXX" && ( test no != "$CXX" &&
-    ( (test g++ = "$CXX" && `g++ -v >/dev/null 2>&1` ) ||
-    (test g++ != "$CXX"))); then
+      if test -n "$CXX" && ( test "X$CXX" != "Xno" &&
+    ( (test "X$CXX" = "Xg++" && `g++ -v >/dev/null 2>&1` ) ||
+    (test "X$CXX" != "Xg++"))) ; then
   ac_ext=cpp
 ac_cpp='$CXXCPP $CPPFLAGS'
 ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
@@ -13236,7 +12735,7 @@ objext_CXX=$objext
 # the CXX compiler isn't working.  Some variables (like enable_shared)
 # are currently assumed to apply to all compilers on this platform,
 # and will be corrupted by setting them based on a non-working compiler.
-if test yes != "$_lt_caught_CXX_error"; then
+if test "$_lt_caught_CXX_error" != yes; then
   # Code to be used in simple compile tests
   lt_simple_compile_test_code="int some_variable = 0;"
 
@@ -13297,39 +12796,46 @@ $RM -r conftest*
   CFLAGS=$CXXFLAGS
   compiler=$CC
   compiler_CXX=$CC
-  func_cc_basename $compiler
-cc_basename=$func_cc_basename_result
+  for cc_temp in $compiler""; do
+  case $cc_temp in
+    compile | *[\\/]compile | ccache | *[\\/]ccache ) ;;
+    distcc | *[\\/]distcc | purify | *[\\/]purify ) ;;
+    \-*) ;;
+    *) break;;
+  esac
+done
+cc_basename=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"`
 
 
   if test -n "$compiler"; then
     # We don't want -fno-exception when compiling C++ code, so set the
     # no_builtin_flag separately
-    if test yes = "$GXX"; then
+    if test "$GXX" = yes; then
       lt_prog_compiler_no_builtin_flag_CXX=' -fno-builtin'
     else
       lt_prog_compiler_no_builtin_flag_CXX=
     fi
 
-    if test yes = "$GXX"; then
+    if test "$GXX" = yes; then
       # Set up default GNU C++ configuration
 
 
 
 # Check whether --with-gnu-ld was given.
 if test "${with_gnu_ld+set}" = set; then :
-  withval=$with_gnu_ld; test no = "$withval" || with_gnu_ld=yes
+  withval=$with_gnu_ld; test "$withval" = no || with_gnu_ld=yes
 else
   with_gnu_ld=no
 fi
 
 ac_prog=ld
-if test yes = "$GCC"; then
+if test "$GCC" = yes; then
   # Check if gcc -print-prog-name=ld gives a path.
   { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ld used by $CC" >&5
 $as_echo_n "checking for ld used by $CC... " >&6; }
   case $host in
   *-*-mingw*)
-    # gcc leaves a trailing carriage return, which upsets mingw
+    # gcc leaves a trailing carriage return which upsets mingw
     ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;;
   *)
     ac_prog=`($CC -print-prog-name=ld) 2>&5` ;;
@@ -13343,7 +12849,7 @@ $as_echo_n "checking for ld used by $CC... " >&6; }
       while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do
 	ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"`
       done
-      test -z "$LD" && LD=$ac_prog
+      test -z "$LD" && LD="$ac_prog"
       ;;
   "")
     # If it fails, then pretend we aren't using GCC.
@@ -13354,7 +12860,7 @@ $as_echo_n "checking for ld used by $CC... " >&6; }
     with_gnu_ld=unknown
     ;;
   esac
-elif test yes = "$with_gnu_ld"; then
+elif test "$with_gnu_ld" = yes; then
   { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU ld" >&5
 $as_echo_n "checking for GNU ld... " >&6; }
 else
@@ -13365,32 +12871,32 @@ if ${lt_cv_path_LD+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   if test -z "$LD"; then
-  lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR
+  lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
   for ac_dir in $PATH; do
-    IFS=$lt_save_ifs
+    IFS="$lt_save_ifs"
     test -z "$ac_dir" && ac_dir=.
     if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then
-      lt_cv_path_LD=$ac_dir/$ac_prog
+      lt_cv_path_LD="$ac_dir/$ac_prog"
       # Check to see if the program is GNU ld.  I'd rather use --version,
       # but apparently some variants of GNU ld only accept -v.
       # Break only if it was the GNU/non-GNU ld that we prefer.
       case `"$lt_cv_path_LD" -v 2>&1 </dev/null` in
       *GNU* | *'with BFD'*)
-	test no != "$with_gnu_ld" && break
+	test "$with_gnu_ld" != no && break
 	;;
       *)
-	test yes != "$with_gnu_ld" && break
+	test "$with_gnu_ld" != yes && break
 	;;
       esac
     fi
   done
-  IFS=$lt_save_ifs
+  IFS="$lt_save_ifs"
 else
-  lt_cv_path_LD=$LD # Let the user override the test with a path.
+  lt_cv_path_LD="$LD" # Let the user override the test with a path.
 fi
 fi
 
-LD=$lt_cv_path_LD
+LD="$lt_cv_path_LD"
 if test -n "$LD"; then
   { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LD" >&5
 $as_echo "$LD" >&6; }
@@ -13426,22 +12932,22 @@ with_gnu_ld=$lt_cv_prog_gnu_ld
 
       # Check if GNU C++ uses GNU ld as the underlying linker, since the
       # archiving commands below assume that GNU ld is being used.
-      if test yes = "$with_gnu_ld"; then
-        archive_cmds_CXX='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib'
-        archive_expsym_cmds_CXX='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'
+      if test "$with_gnu_ld" = yes; then
+        archive_cmds_CXX='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib'
+        archive_expsym_cmds_CXX='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
 
-        hardcode_libdir_flag_spec_CXX='$wl-rpath $wl$libdir'
-        export_dynamic_flag_spec_CXX='$wl--export-dynamic'
+        hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir'
+        export_dynamic_flag_spec_CXX='${wl}--export-dynamic'
 
         # If archive_cmds runs LD, not CC, wlarc should be empty
         # XXX I think wlarc can be eliminated in ltcf-cxx, but I need to
         #     investigate it a little bit more. (MM)
-        wlarc='$wl'
+        wlarc='${wl}'
 
         # ancient GNU ld didn't support --whole-archive et. al.
         if eval "`$CC -print-prog-name=ld` --help 2>&1" |
 	  $GREP 'no-whole-archive' > /dev/null; then
-          whole_archive_flag_spec_CXX=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive'
+          whole_archive_flag_spec_CXX="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive'
         else
           whole_archive_flag_spec_CXX=
         fi
@@ -13478,30 +12984,18 @@ $as_echo_n "checking whether the $compiler linker ($LD) supports shared librarie
         ld_shlibs_CXX=no
         ;;
       aix[4-9]*)
-        if test ia64 = "$host_cpu"; then
+        if test "$host_cpu" = ia64; then
           # On IA64, the linker does run time linking by default, so we don't
           # have to do anything special.
           aix_use_runtimelinking=no
           exp_sym_flag='-Bexport'
-          no_entry_flag=
+          no_entry_flag=""
         else
           aix_use_runtimelinking=no
 
           # Test if we are trying to use run time linking or normal
           # AIX style linking. If -brtl is somewhere in LDFLAGS, we
-          # have runtime linking enabled, and use it for executables.
-          # For shared libraries, we enable/disable runtime linking
-          # depending on the kind of the shared library created -
-          # when "with_aix_soname,aix_use_runtimelinking" is:
-          # "aix,no"   lib.a(lib.so.V) shared, rtl:no,  for executables
-          # "aix,yes"  lib.so          shared, rtl:yes, for executables
-          #            lib.a           static archive
-          # "both,no"  lib.so.V(shr.o) shared, rtl:yes
-          #            lib.a(lib.so.V) shared, rtl:no,  for executables
-          # "both,yes" lib.so.V(shr.o) shared, rtl:yes, for executables
-          #            lib.a(lib.so.V) shared, rtl:no
-          # "svr4,*"   lib.so.V(shr.o) shared, rtl:yes, for executables
-          #            lib.a           static archive
+          # need to do runtime linking.
           case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*)
 	    for ld_flag in $LDFLAGS; do
 	      case $ld_flag in
@@ -13511,13 +13005,6 @@ $as_echo_n "checking whether the $compiler linker ($LD) supports shared librarie
 	        ;;
 	      esac
 	    done
-	    if test svr4,no = "$with_aix_soname,$aix_use_runtimelinking"; then
-	      # With aix-soname=svr4, we create the lib.so.V shared archives only,
-	      # so we don't have lib.a shared libs to link our executables.
-	      # We have to force runtime linking in this case.
-	      aix_use_runtimelinking=yes
-	      LDFLAGS="$LDFLAGS -Wl,-brtl"
-	    fi
 	    ;;
           esac
 
@@ -13536,21 +13023,13 @@ $as_echo_n "checking whether the $compiler linker ($LD) supports shared librarie
         hardcode_direct_absolute_CXX=yes
         hardcode_libdir_separator_CXX=':'
         link_all_deplibs_CXX=yes
-        file_list_spec_CXX='$wl-f,'
-        case $with_aix_soname,$aix_use_runtimelinking in
-        aix,*) ;;	# no import file
-        svr4,* | *,yes) # use import file
-          # The Import File defines what to hardcode.
-          hardcode_direct_CXX=no
-          hardcode_direct_absolute_CXX=no
-          ;;
-        esac
+        file_list_spec_CXX='${wl}-f,'
 
-        if test yes = "$GXX"; then
+        if test "$GXX" = yes; then
           case $host_os in aix4.[012]|aix4.[012].*)
           # We only want to do this on AIX 4.2 and lower, the check
           # below for broken collect2 doesn't work under 4.3+
-	  collect2name=`$CC -print-prog-name=collect2`
+	  collect2name=`${CC} -print-prog-name=collect2`
 	  if test -f "$collect2name" &&
 	     strings "$collect2name" | $GREP resolve_lib_name >/dev/null
 	  then
@@ -13568,44 +13047,36 @@ $as_echo_n "checking whether the $compiler linker ($LD) supports shared librarie
 	  fi
           esac
           shared_flag='-shared'
-	  if test yes = "$aix_use_runtimelinking"; then
-	    shared_flag=$shared_flag' $wl-G'
+	  if test "$aix_use_runtimelinking" = yes; then
+	    shared_flag="$shared_flag "'${wl}-G'
 	  fi
-	  # Need to ensure runtime linking is disabled for the traditional
-	  # shared library, or the linker may eventually find shared libraries
-	  # /with/ Import File - we do not want to mix them.
-	  shared_flag_aix='-shared'
-	  shared_flag_svr4='-shared $wl-G'
         else
           # not using gcc
-          if test ia64 = "$host_cpu"; then
+          if test "$host_cpu" = ia64; then
 	  # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release
 	  # chokes on -Wl,-G. The following line is correct:
 	  shared_flag='-G'
           else
-	    if test yes = "$aix_use_runtimelinking"; then
-	      shared_flag='$wl-G'
+	    if test "$aix_use_runtimelinking" = yes; then
+	      shared_flag='${wl}-G'
 	    else
-	      shared_flag='$wl-bM:SRE'
+	      shared_flag='${wl}-bM:SRE'
 	    fi
-	    shared_flag_aix='$wl-bM:SRE'
-	    shared_flag_svr4='$wl-G'
           fi
         fi
 
-        export_dynamic_flag_spec_CXX='$wl-bexpall'
+        export_dynamic_flag_spec_CXX='${wl}-bexpall'
         # It seems that -bexpall does not export symbols beginning with
         # underscore (_), so it is better to generate a list of symbols to
 	# export.
         always_export_symbols_CXX=yes
-	if test aix,yes = "$with_aix_soname,$aix_use_runtimelinking"; then
+        if test "$aix_use_runtimelinking" = yes; then
           # Warning - without using the other runtime loading flags (-brtl),
           # -berok will link without error, but may produce a broken library.
-          # The "-G" linker flag allows undefined symbols.
-          no_undefined_flag_CXX='-bernotok'
+          allow_undefined_flag_CXX='-berok'
           # Determine the default libpath from the value encoded in an empty
           # executable.
-          if test set = "${lt_cv_aix_libpath+set}"; then
+          if test "${lt_cv_aix_libpath+set}" = set; then
   aix_libpath=$lt_cv_aix_libpath
 else
   if ${lt_cv_aix_libpath__CXX+:} false; then :
@@ -13640,7 +13111,7 @@ fi
 rm -f core conftest.err conftest.$ac_objext \
     conftest$ac_exeext conftest.$ac_ext
   if test -z "$lt_cv_aix_libpath__CXX"; then
-    lt_cv_aix_libpath__CXX=/usr/lib:/lib
+    lt_cv_aix_libpath__CXX="/usr/lib:/lib"
   fi
 
 fi
@@ -13648,18 +13119,18 @@ fi
   aix_libpath=$lt_cv_aix_libpath__CXX
 fi
 
-          hardcode_libdir_flag_spec_CXX='$wl-blibpath:$libdir:'"$aix_libpath"
+          hardcode_libdir_flag_spec_CXX='${wl}-blibpath:$libdir:'"$aix_libpath"
 
-          archive_expsym_cmds_CXX='$CC -o $output_objdir/$soname $libobjs $deplibs $wl'$no_entry_flag' $compiler_flags `if test -n "$allow_undefined_flag"; then func_echo_all "$wl$allow_undefined_flag"; else :; fi` $wl'$exp_sym_flag:\$export_symbols' '$shared_flag
+          archive_expsym_cmds_CXX='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then func_echo_all "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag"
         else
-          if test ia64 = "$host_cpu"; then
-	    hardcode_libdir_flag_spec_CXX='$wl-R $libdir:/usr/lib:/lib'
+          if test "$host_cpu" = ia64; then
+	    hardcode_libdir_flag_spec_CXX='${wl}-R $libdir:/usr/lib:/lib'
 	    allow_undefined_flag_CXX="-z nodefs"
-	    archive_expsym_cmds_CXX="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\$wl$no_entry_flag"' $compiler_flags $wl$allow_undefined_flag '"\$wl$exp_sym_flag:\$export_symbols"
+	    archive_expsym_cmds_CXX="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols"
           else
 	    # Determine the default libpath from the value encoded in an
 	    # empty executable.
-	    if test set = "${lt_cv_aix_libpath+set}"; then
+	    if test "${lt_cv_aix_libpath+set}" = set; then
   aix_libpath=$lt_cv_aix_libpath
 else
   if ${lt_cv_aix_libpath__CXX+:} false; then :
@@ -13694,7 +13165,7 @@ fi
 rm -f core conftest.err conftest.$ac_objext \
     conftest$ac_exeext conftest.$ac_ext
   if test -z "$lt_cv_aix_libpath__CXX"; then
-    lt_cv_aix_libpath__CXX=/usr/lib:/lib
+    lt_cv_aix_libpath__CXX="/usr/lib:/lib"
   fi
 
 fi
@@ -13702,34 +13173,22 @@ fi
   aix_libpath=$lt_cv_aix_libpath__CXX
 fi
 
-	    hardcode_libdir_flag_spec_CXX='$wl-blibpath:$libdir:'"$aix_libpath"
+	    hardcode_libdir_flag_spec_CXX='${wl}-blibpath:$libdir:'"$aix_libpath"
 	    # Warning - without using the other run time loading flags,
 	    # -berok will link without error, but may produce a broken library.
-	    no_undefined_flag_CXX=' $wl-bernotok'
-	    allow_undefined_flag_CXX=' $wl-berok'
-	    if test yes = "$with_gnu_ld"; then
+	    no_undefined_flag_CXX=' ${wl}-bernotok'
+	    allow_undefined_flag_CXX=' ${wl}-berok'
+	    if test "$with_gnu_ld" = yes; then
 	      # We only use this code for GNU lds that support --whole-archive.
-	      whole_archive_flag_spec_CXX='$wl--whole-archive$convenience $wl--no-whole-archive'
+	      whole_archive_flag_spec_CXX='${wl}--whole-archive$convenience ${wl}--no-whole-archive'
 	    else
 	      # Exported symbols can be pulled into shared objects from archives
 	      whole_archive_flag_spec_CXX='$convenience'
 	    fi
 	    archive_cmds_need_lc_CXX=yes
-	    archive_expsym_cmds_CXX='$RM -r $output_objdir/$realname.d~$MKDIR $output_objdir/$realname.d'
-	    # -brtl affects multiple linker settings, -berok does not and is overridden later
-	    compiler_flags_filtered='`func_echo_all "$compiler_flags " | $SED -e "s%-brtl\\([, ]\\)%-berok\\1%g"`'
-	    if test svr4 != "$with_aix_soname"; then
-	      # This is similar to how AIX traditionally builds its shared
-	      # libraries. Need -bnortl late, we may have -brtl in LDFLAGS.
-	      archive_expsym_cmds_CXX="$archive_expsym_cmds_CXX"'~$CC '$shared_flag_aix' -o $output_objdir/$realname.d/$soname $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$realname.d/$soname'
-	    fi
-	    if test aix != "$with_aix_soname"; then
-	      archive_expsym_cmds_CXX="$archive_expsym_cmds_CXX"'~$CC '$shared_flag_svr4' -o $output_objdir/$realname.d/$shared_archive_member_spec.o $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$STRIP -e $output_objdir/$realname.d/$shared_archive_member_spec.o~( func_echo_all "#! $soname($shared_archive_member_spec.o)"; if test shr_64 = "$shared_archive_member_spec"; then func_echo_all "# 64"; else func_echo_all "# 32"; fi; cat $export_sy [...]
-	    else
-	      # used by -dlpreopen to get the symbols
-	      archive_expsym_cmds_CXX="$archive_expsym_cmds_CXX"'~$MV  $output_objdir/$realname.d/$soname $output_objdir'
-	    fi
-	    archive_expsym_cmds_CXX="$archive_expsym_cmds_CXX"'~$RM -r $output_objdir/$realname.d'
+	    # This is similar to how AIX traditionally builds its shared
+	    # libraries.
+	    archive_expsym_cmds_CXX="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname'
           fi
         fi
         ;;
@@ -13739,7 +13198,7 @@ fi
 	  allow_undefined_flag_CXX=unsupported
 	  # Joseph Beckenbach <jrb3 at best.com> says some releases of gcc
 	  # support --undefined.  This deserves some investigation.  FIXME
-	  archive_cmds_CXX='$CC -nostart $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+	  archive_cmds_CXX='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
 	else
 	  ld_shlibs_CXX=no
 	fi
@@ -13767,58 +13226,57 @@ fi
 	  # Tell ltmain to make .lib files, not .a files.
 	  libext=lib
 	  # Tell ltmain to make .dll files, not .so files.
-	  shrext_cmds=.dll
+	  shrext_cmds=".dll"
 	  # FIXME: Setting linknames here is a bad hack.
-	  archive_cmds_CXX='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~linknames='
-	  archive_expsym_cmds_CXX='if   test DEF = "`$SED -n     -e '\''s/^[	 ]*//'\''     -e '\''/^\(;.*\)*$/d'\''     -e '\''s/^\(EXPORTS\|LIBRARY\)\([	 ].*\)*$/DEF/p'\''     -e q     $export_symbols`" ; then
-              cp "$export_symbols" "$output_objdir/$soname.def";
-              echo "$tool_output_objdir$soname.def" > "$output_objdir/$soname.exp";
-            else
-              $SED -e '\''s/^/-link -EXPORT:/'\'' < $export_symbols > $output_objdir/$soname.exp;
-            fi~
-            $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~
-            linknames='
+	  archive_cmds_CXX='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-dll~linknames='
+	  archive_expsym_cmds_CXX='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then
+	      $SED -n -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' -e '1\\\!p' < $export_symbols > $output_objdir/$soname.exp;
+	    else
+	      $SED -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' < $export_symbols > $output_objdir/$soname.exp;
+	    fi~
+	    $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~
+	    linknames='
 	  # The linker will not automatically build a static lib if we build a DLL.
 	  # _LT_TAGVAR(old_archive_from_new_cmds, CXX)='true'
 	  enable_shared_with_static_runtimes_CXX=yes
 	  # Don't use ranlib
 	  old_postinstall_cmds_CXX='chmod 644 $oldlib'
 	  postlink_cmds_CXX='lt_outputfile="@OUTPUT@"~
-            lt_tool_outputfile="@TOOL_OUTPUT@"~
-            case $lt_outputfile in
-              *.exe|*.EXE) ;;
-              *)
-                lt_outputfile=$lt_outputfile.exe
-                lt_tool_outputfile=$lt_tool_outputfile.exe
-                ;;
-            esac~
-            func_to_tool_file "$lt_outputfile"~
-            if test : != "$MANIFEST_TOOL" && test -f "$lt_outputfile.manifest"; then
-              $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1;
-              $RM "$lt_outputfile.manifest";
-            fi'
+	    lt_tool_outputfile="@TOOL_OUTPUT@"~
+	    case $lt_outputfile in
+	      *.exe|*.EXE) ;;
+	      *)
+		lt_outputfile="$lt_outputfile.exe"
+		lt_tool_outputfile="$lt_tool_outputfile.exe"
+		;;
+	    esac~
+	    func_to_tool_file "$lt_outputfile"~
+	    if test "$MANIFEST_TOOL" != ":" && test -f "$lt_outputfile.manifest"; then
+	      $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1;
+	      $RM "$lt_outputfile.manifest";
+	    fi'
 	  ;;
 	*)
 	  # g++
 	  # _LT_TAGVAR(hardcode_libdir_flag_spec, CXX) is actually meaningless,
 	  # as there is no search path for DLLs.
 	  hardcode_libdir_flag_spec_CXX='-L$libdir'
-	  export_dynamic_flag_spec_CXX='$wl--export-all-symbols'
+	  export_dynamic_flag_spec_CXX='${wl}--export-all-symbols'
 	  allow_undefined_flag_CXX=unsupported
 	  always_export_symbols_CXX=no
 	  enable_shared_with_static_runtimes_CXX=yes
 
 	  if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then
-	    archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
-	    # If the export-symbols file already is a .def file, use it as
-	    # is; otherwise, prepend EXPORTS...
-	    archive_expsym_cmds_CXX='if   test DEF = "`$SED -n     -e '\''s/^[	 ]*//'\''     -e '\''/^\(;.*\)*$/d'\''     -e '\''s/^\(EXPORTS\|LIBRARY\)\([	 ].*\)*$/DEF/p'\''     -e q     $export_symbols`" ; then
-              cp $export_symbols $output_objdir/$soname.def;
-            else
-              echo EXPORTS > $output_objdir/$soname.def;
-              cat $export_symbols >> $output_objdir/$soname.def;
-            fi~
-            $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+	    archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+	    # If the export-symbols file already is a .def file (1st line
+	    # is EXPORTS), use it as is; otherwise, prepend...
+	    archive_expsym_cmds_CXX='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then
+	      cp $export_symbols $output_objdir/$soname.def;
+	    else
+	      echo EXPORTS > $output_objdir/$soname.def;
+	      cat $export_symbols >> $output_objdir/$soname.def;
+	    fi~
+	    $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
 	  else
 	    ld_shlibs_CXX=no
 	  fi
@@ -13832,27 +13290,27 @@ fi
   hardcode_direct_CXX=no
   hardcode_automatic_CXX=yes
   hardcode_shlibpath_var_CXX=unsupported
-  if test yes = "$lt_cv_ld_force_load"; then
-    whole_archive_flag_spec_CXX='`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience $wl-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`'
+  if test "$lt_cv_ld_force_load" = "yes"; then
+    whole_archive_flag_spec_CXX='`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience ${wl}-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`'
 
   else
     whole_archive_flag_spec_CXX=''
   fi
   link_all_deplibs_CXX=yes
-  allow_undefined_flag_CXX=$_lt_dar_allow_undefined
+  allow_undefined_flag_CXX="$_lt_dar_allow_undefined"
   case $cc_basename in
-     ifort*|nagfor*) _lt_dar_can_shared=yes ;;
+     ifort*) _lt_dar_can_shared=yes ;;
      *) _lt_dar_can_shared=$GCC ;;
   esac
-  if test yes = "$_lt_dar_can_shared"; then
+  if test "$_lt_dar_can_shared" = "yes"; then
     output_verbose_link_cmd=func_echo_all
-    archive_cmds_CXX="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dsymutil"
-    module_cmds_CXX="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dsymutil"
-    archive_expsym_cmds_CXX="sed 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dar_export_syms$_lt_dsymutil"
-    module_expsym_cmds_CXX="sed -e 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dar_export_syms$_lt_dsymutil"
-       if test yes != "$lt_cv_apple_cc_single_mod"; then
-      archive_cmds_CXX="\$CC -r -keep_private_externs -nostdlib -o \$lib-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$lib-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring$_lt_dsymutil"
-      archive_expsym_cmds_CXX="sed 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \$lib-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$lib-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring$_lt_dar_export_syms$_lt_dsymutil"
+    archive_cmds_CXX="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}"
+    module_cmds_CXX="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}"
+    archive_expsym_cmds_CXX="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}"
+    module_expsym_cmds_CXX="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}"
+       if test "$lt_cv_apple_cc_single_mod" != "yes"; then
+      archive_cmds_CXX="\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dsymutil}"
+      archive_expsym_cmds_CXX="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dar_export_syms}${_lt_dsymutil}"
     fi
 
   else
@@ -13861,34 +13319,6 @@ fi
 
 	;;
 
-      os2*)
-	hardcode_libdir_flag_spec_CXX='-L$libdir'
-	hardcode_minus_L_CXX=yes
-	allow_undefined_flag_CXX=unsupported
-	shrext_cmds=.dll
-	archive_cmds_CXX='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~
-	  $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~
-	  $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~
-	  $ECHO EXPORTS >> $output_objdir/$libname.def~
-	  emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~
-	  $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~
-	  emximp -o $lib $output_objdir/$libname.def'
-	archive_expsym_cmds_CXX='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~
-	  $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~
-	  $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~
-	  $ECHO EXPORTS >> $output_objdir/$libname.def~
-	  prefix_cmds="$SED"~
-	  if test EXPORTS = "`$SED 1q $export_symbols`"; then
-	    prefix_cmds="$prefix_cmds -e 1d";
-	  fi~
-	  prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~
-	  cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~
-	  $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~
-	  emximp -o $lib $output_objdir/$libname.def'
-	old_archive_From_new_cmds_CXX='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def'
-	enable_shared_with_static_runtimes_CXX=yes
-	;;
-
       dgux*)
         case $cc_basename in
           ec++*)
@@ -13924,14 +13354,14 @@ fi
         ;;
 
       haiku*)
-        archive_cmds_CXX='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+        archive_cmds_CXX='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
         link_all_deplibs_CXX=yes
         ;;
 
       hpux9*)
-        hardcode_libdir_flag_spec_CXX='$wl+b $wl$libdir'
+        hardcode_libdir_flag_spec_CXX='${wl}+b ${wl}$libdir'
         hardcode_libdir_separator_CXX=:
-        export_dynamic_flag_spec_CXX='$wl-E'
+        export_dynamic_flag_spec_CXX='${wl}-E'
         hardcode_direct_CXX=yes
         hardcode_minus_L_CXX=yes # Not in the search PATH,
 				             # but as the default
@@ -13943,7 +13373,7 @@ fi
             ld_shlibs_CXX=no
             ;;
           aCC*)
-            archive_cmds_CXX='$RM $output_objdir/$soname~$CC -b $wl+b $wl$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib'
+            archive_cmds_CXX='$RM $output_objdir/$soname~$CC -b ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
             # Commands to make compiler produce verbose output that lists
             # what "hidden" libraries, object files and flags are used when
             # linking a shared library.
@@ -13952,11 +13382,11 @@ fi
             # explicitly linking system object files so we need to strip them
             # from the output so that they don't get included in the library
             # dependencies.
-            output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP "\-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
+            output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
             ;;
           *)
-            if test yes = "$GXX"; then
-              archive_cmds_CXX='$RM $output_objdir/$soname~$CC -shared -nostdlib $pic_flag $wl+b $wl$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib'
+            if test "$GXX" = yes; then
+              archive_cmds_CXX='$RM $output_objdir/$soname~$CC -shared -nostdlib $pic_flag ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
             else
               # FIXME: insert proper C++ library support
               ld_shlibs_CXX=no
@@ -13966,15 +13396,15 @@ fi
         ;;
 
       hpux10*|hpux11*)
-        if test no = "$with_gnu_ld"; then
-	  hardcode_libdir_flag_spec_CXX='$wl+b $wl$libdir'
+        if test $with_gnu_ld = no; then
+	  hardcode_libdir_flag_spec_CXX='${wl}+b ${wl}$libdir'
 	  hardcode_libdir_separator_CXX=:
 
           case $host_cpu in
             hppa*64*|ia64*)
               ;;
             *)
-	      export_dynamic_flag_spec_CXX='$wl-E'
+	      export_dynamic_flag_spec_CXX='${wl}-E'
               ;;
           esac
         fi
@@ -14000,13 +13430,13 @@ fi
           aCC*)
 	    case $host_cpu in
 	      hppa*64*)
-	        archive_cmds_CXX='$CC -b $wl+h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+	        archive_cmds_CXX='$CC -b ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
 	        ;;
 	      ia64*)
-	        archive_cmds_CXX='$CC -b $wl+h $wl$soname $wl+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+	        archive_cmds_CXX='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
 	        ;;
 	      *)
-	        archive_cmds_CXX='$CC -b $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+	        archive_cmds_CXX='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
 	        ;;
 	    esac
 	    # Commands to make compiler produce verbose output that lists
@@ -14017,20 +13447,20 @@ fi
 	    # explicitly linking system object files so we need to strip them
 	    # from the output so that they don't get included in the library
 	    # dependencies.
-	    output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP "\-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
+	    output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
 	    ;;
           *)
-	    if test yes = "$GXX"; then
-	      if test no = "$with_gnu_ld"; then
+	    if test "$GXX" = yes; then
+	      if test $with_gnu_ld = no; then
 	        case $host_cpu in
 	          hppa*64*)
-	            archive_cmds_CXX='$CC -shared -nostdlib -fPIC $wl+h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+	            archive_cmds_CXX='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
 	            ;;
 	          ia64*)
-	            archive_cmds_CXX='$CC -shared -nostdlib $pic_flag $wl+h $wl$soname $wl+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+	            archive_cmds_CXX='$CC -shared -nostdlib $pic_flag ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
 	            ;;
 	          *)
-	            archive_cmds_CXX='$CC -shared -nostdlib $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+	            archive_cmds_CXX='$CC -shared -nostdlib $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
 	            ;;
 	        esac
 	      fi
@@ -14045,22 +13475,22 @@ fi
       interix[3-9]*)
 	hardcode_direct_CXX=no
 	hardcode_shlibpath_var_CXX=no
-	hardcode_libdir_flag_spec_CXX='$wl-rpath,$libdir'
-	export_dynamic_flag_spec_CXX='$wl-E'
+	hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir'
+	export_dynamic_flag_spec_CXX='${wl}-E'
 	# Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc.
 	# Instead, shared libraries are loaded at an image base (0x10000000 by
 	# default) and relocated if they conflict, which is a slow very memory
 	# consuming and fragmenting process.  To avoid this, we pick a random,
 	# 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link
 	# time.  Moving up from 0x10000000 also allows more sbrk(2) space.
-	archive_cmds_CXX='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
-	archive_expsym_cmds_CXX='sed "s|^|_|" $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--retain-symbols-file,$output_objdir/$soname.expsym $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+	archive_cmds_CXX='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+	archive_expsym_cmds_CXX='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
 	;;
       irix5* | irix6*)
         case $cc_basename in
           CC*)
 	    # SGI C++
-	    archive_cmds_CXX='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib'
+	    archive_cmds_CXX='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib'
 
 	    # Archives containing C++ object files must be created using
 	    # "CC -ar", where "CC" is the IRIX C++ compiler.  This is
@@ -14069,17 +13499,17 @@ fi
 	    old_archive_cmds_CXX='$CC -ar -WR,-u -o $oldlib $oldobjs'
 	    ;;
           *)
-	    if test yes = "$GXX"; then
-	      if test no = "$with_gnu_ld"; then
-	        archive_cmds_CXX='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib'
+	    if test "$GXX" = yes; then
+	      if test "$with_gnu_ld" = no; then
+	        archive_cmds_CXX='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
 	      else
-	        archive_cmds_CXX='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` -o $lib'
+	        archive_cmds_CXX='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` -o $lib'
 	      fi
 	    fi
 	    link_all_deplibs_CXX=yes
 	    ;;
         esac
-        hardcode_libdir_flag_spec_CXX='$wl-rpath $wl$libdir'
+        hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir'
         hardcode_libdir_separator_CXX=:
         inherit_rpath_CXX=yes
         ;;
@@ -14092,8 +13522,8 @@ fi
 	    # KCC will only create a shared library if the output file
 	    # ends with ".so" (or ".sl" for HP-UX), so rename the library
 	    # to its proper name (with version) after linking.
-	    archive_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib'
-	    archive_expsym_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib $wl-retain-symbols-file,$export_symbols; mv \$templib $lib'
+	    archive_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib'
+	    archive_expsym_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib ${wl}-retain-symbols-file,$export_symbols; mv \$templib $lib'
 	    # Commands to make compiler produce verbose output that lists
 	    # what "hidden" libraries, object files and flags are used when
 	    # linking a shared library.
@@ -14102,10 +13532,10 @@ fi
 	    # explicitly linking system object files so we need to strip them
 	    # from the output so that they don't get included in the library
 	    # dependencies.
-	    output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | $GREP "ld"`; rm -f libconftest$shared_ext; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
+	    output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | $GREP "ld"`; rm -f libconftest$shared_ext; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
 
-	    hardcode_libdir_flag_spec_CXX='$wl-rpath,$libdir'
-	    export_dynamic_flag_spec_CXX='$wl--export-dynamic'
+	    hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir'
+	    export_dynamic_flag_spec_CXX='${wl}--export-dynamic'
 
 	    # Archives containing C++ object files must be created using
 	    # "CC -Bstatic", where "CC" is the KAI C++ compiler.
@@ -14119,59 +13549,59 @@ fi
 	    # earlier do not add the objects themselves.
 	    case `$CC -V 2>&1` in
 	      *"Version 7."*)
-	        archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib'
-		archive_expsym_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'
+	        archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib'
+		archive_expsym_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
 		;;
 	      *)  # Version 8.0 or newer
 	        tmp_idyn=
 	        case $host_cpu in
 		  ia64*) tmp_idyn=' -i_dynamic';;
 		esac
-	        archive_cmds_CXX='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
-		archive_expsym_cmds_CXX='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'
+	        archive_cmds_CXX='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+		archive_expsym_cmds_CXX='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
 		;;
 	    esac
 	    archive_cmds_need_lc_CXX=no
-	    hardcode_libdir_flag_spec_CXX='$wl-rpath,$libdir'
-	    export_dynamic_flag_spec_CXX='$wl--export-dynamic'
-	    whole_archive_flag_spec_CXX='$wl--whole-archive$convenience $wl--no-whole-archive'
+	    hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir'
+	    export_dynamic_flag_spec_CXX='${wl}--export-dynamic'
+	    whole_archive_flag_spec_CXX='${wl}--whole-archive$convenience ${wl}--no-whole-archive'
 	    ;;
           pgCC* | pgcpp*)
             # Portland Group C++ compiler
 	    case `$CC -V` in
 	    *pgCC\ [1-5].* | *pgcpp\ [1-5].*)
 	      prelink_cmds_CXX='tpldir=Template.dir~
-               rm -rf $tpldir~
-               $CC --prelink_objects --instantiation_dir $tpldir $objs $libobjs $compile_deplibs~
-               compile_command="$compile_command `find $tpldir -name \*.o | sort | $NL2SP`"'
+		rm -rf $tpldir~
+		$CC --prelink_objects --instantiation_dir $tpldir $objs $libobjs $compile_deplibs~
+		compile_command="$compile_command `find $tpldir -name \*.o | sort | $NL2SP`"'
 	      old_archive_cmds_CXX='tpldir=Template.dir~
-                rm -rf $tpldir~
-                $CC --prelink_objects --instantiation_dir $tpldir $oldobjs$old_deplibs~
-                $AR $AR_FLAGS $oldlib$oldobjs$old_deplibs `find $tpldir -name \*.o | sort | $NL2SP`~
-                $RANLIB $oldlib'
+		rm -rf $tpldir~
+		$CC --prelink_objects --instantiation_dir $tpldir $oldobjs$old_deplibs~
+		$AR $AR_FLAGS $oldlib$oldobjs$old_deplibs `find $tpldir -name \*.o | sort | $NL2SP`~
+		$RANLIB $oldlib'
 	      archive_cmds_CXX='tpldir=Template.dir~
-                rm -rf $tpldir~
-                $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~
-                $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib'
+		rm -rf $tpldir~
+		$CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~
+		$CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib'
 	      archive_expsym_cmds_CXX='tpldir=Template.dir~
-                rm -rf $tpldir~
-                $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~
-                $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'
+		rm -rf $tpldir~
+		$CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~
+		$CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib'
 	      ;;
 	    *) # Version 6 and above use weak symbols
-	      archive_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib'
-	      archive_expsym_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'
+	      archive_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib'
+	      archive_expsym_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib'
 	      ;;
 	    esac
 
-	    hardcode_libdir_flag_spec_CXX='$wl--rpath $wl$libdir'
-	    export_dynamic_flag_spec_CXX='$wl--export-dynamic'
-	    whole_archive_flag_spec_CXX='$wl--whole-archive`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive'
+	    hardcode_libdir_flag_spec_CXX='${wl}--rpath ${wl}$libdir'
+	    export_dynamic_flag_spec_CXX='${wl}--export-dynamic'
+	    whole_archive_flag_spec_CXX='${wl}--whole-archive`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
             ;;
 	  cxx*)
 	    # Compaq C++
-	    archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib'
-	    archive_expsym_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname  -o $lib $wl-retain-symbols-file $wl$export_symbols'
+	    archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib'
+	    archive_expsym_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname  -o $lib ${wl}-retain-symbols-file $wl$export_symbols'
 
 	    runpath_var=LD_RUN_PATH
 	    hardcode_libdir_flag_spec_CXX='-rpath $libdir'
@@ -14185,18 +13615,18 @@ fi
 	    # explicitly linking system object files so we need to strip them
 	    # from the output so that they don't get included in the library
 	    # dependencies.
-	    output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "X$list" | $Xsed'
+	    output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "X$list" | $Xsed'
 	    ;;
 	  xl* | mpixl* | bgxl*)
 	    # IBM XL 8.0 on PPC, with GNU ld
-	    hardcode_libdir_flag_spec_CXX='$wl-rpath $wl$libdir'
-	    export_dynamic_flag_spec_CXX='$wl--export-dynamic'
-	    archive_cmds_CXX='$CC -qmkshrobj $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
-	    if test yes = "$supports_anon_versioning"; then
+	    hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir'
+	    export_dynamic_flag_spec_CXX='${wl}--export-dynamic'
+	    archive_cmds_CXX='$CC -qmkshrobj $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+	    if test "x$supports_anon_versioning" = xyes; then
 	      archive_expsym_cmds_CXX='echo "{ global:" > $output_objdir/$libname.ver~
-                cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
-                echo "local: *; };" >> $output_objdir/$libname.ver~
-                $CC -qmkshrobj $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-version-script $wl$output_objdir/$libname.ver -o $lib'
+		cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
+		echo "local: *; };" >> $output_objdir/$libname.ver~
+		$CC -qmkshrobj $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib'
 	    fi
 	    ;;
 	  *)
@@ -14204,10 +13634,10 @@ fi
 	    *Sun\ C*)
 	      # Sun C++ 5.9
 	      no_undefined_flag_CXX=' -zdefs'
-	      archive_cmds_CXX='$CC -G$allow_undefined_flag -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
-	      archive_expsym_cmds_CXX='$CC -G$allow_undefined_flag -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-retain-symbols-file $wl$export_symbols'
+	      archive_cmds_CXX='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+	      archive_expsym_cmds_CXX='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file ${wl}$export_symbols'
 	      hardcode_libdir_flag_spec_CXX='-R$libdir'
-	      whole_archive_flag_spec_CXX='$wl--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive'
+	      whole_archive_flag_spec_CXX='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
 	      compiler_needs_object_CXX=yes
 
 	      # Not sure whether something based on
@@ -14265,17 +13695,22 @@ fi
         ld_shlibs_CXX=yes
 	;;
 
-      openbsd* | bitrig*)
+      openbsd2*)
+        # C++ shared libraries are fairly broken
+	ld_shlibs_CXX=no
+	;;
+
+      openbsd*)
 	if test -f /usr/libexec/ld.so; then
 	  hardcode_direct_CXX=yes
 	  hardcode_shlibpath_var_CXX=no
 	  hardcode_direct_absolute_CXX=yes
 	  archive_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib'
-	  hardcode_libdir_flag_spec_CXX='$wl-rpath,$libdir'
-	  if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`"; then
-	    archive_expsym_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-retain-symbols-file,$export_symbols -o $lib'
-	    export_dynamic_flag_spec_CXX='$wl-E'
-	    whole_archive_flag_spec_CXX=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive'
+	  hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir'
+	  if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+	    archive_expsym_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file,$export_symbols -o $lib'
+	    export_dynamic_flag_spec_CXX='${wl}-E'
+	    whole_archive_flag_spec_CXX="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive'
 	  fi
 	  output_verbose_link_cmd=func_echo_all
 	else
@@ -14291,9 +13726,9 @@ fi
 	    # KCC will only create a shared library if the output file
 	    # ends with ".so" (or ".sl" for HP-UX), so rename the library
 	    # to its proper name (with version) after linking.
-	    archive_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo "$lib" | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib'
+	    archive_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo "$lib" | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib'
 
-	    hardcode_libdir_flag_spec_CXX='$wl-rpath,$libdir'
+	    hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir'
 	    hardcode_libdir_separator_CXX=:
 
 	    # Archives containing C++ object files must be created using
@@ -14311,17 +13746,17 @@ fi
           cxx*)
 	    case $host in
 	      osf3*)
-	        allow_undefined_flag_CXX=' $wl-expect_unresolved $wl\*'
-	        archive_cmds_CXX='$CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $soname `test -n "$verstring" && func_echo_all "$wl-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib'
-	        hardcode_libdir_flag_spec_CXX='$wl-rpath $wl$libdir'
+	        allow_undefined_flag_CXX=' ${wl}-expect_unresolved ${wl}\*'
+	        archive_cmds_CXX='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $soname `test -n "$verstring" && func_echo_all "${wl}-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib'
+	        hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir'
 		;;
 	      *)
 	        allow_undefined_flag_CXX=' -expect_unresolved \*'
-	        archive_cmds_CXX='$CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib'
+	        archive_cmds_CXX='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib'
 	        archive_expsym_cmds_CXX='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done~
-                  echo "-hidden">> $lib.exp~
-                  $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname $wl-input $wl$lib.exp  `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib~
-                  $RM $lib.exp'
+	          echo "-hidden">> $lib.exp~
+	          $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname ${wl}-input ${wl}$lib.exp  `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib~
+	          $RM $lib.exp'
 	        hardcode_libdir_flag_spec_CXX='-rpath $libdir'
 		;;
 	    esac
@@ -14336,21 +13771,21 @@ fi
 	    # explicitly linking system object files so we need to strip them
 	    # from the output so that they don't get included in the library
 	    # dependencies.
-	    output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld" | $GREP -v "ld:"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
+	    output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld" | $GREP -v "ld:"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
 	    ;;
 	  *)
-	    if test yes,no = "$GXX,$with_gnu_ld"; then
-	      allow_undefined_flag_CXX=' $wl-expect_unresolved $wl\*'
+	    if test "$GXX" = yes && test "$with_gnu_ld" = no; then
+	      allow_undefined_flag_CXX=' ${wl}-expect_unresolved ${wl}\*'
 	      case $host in
 	        osf3*)
-	          archive_cmds_CXX='$CC -shared -nostdlib $allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib'
+	          archive_cmds_CXX='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
 		  ;;
 	        *)
-	          archive_cmds_CXX='$CC -shared $pic_flag -nostdlib $allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-msym $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib'
+	          archive_cmds_CXX='$CC -shared $pic_flag -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
 		  ;;
 	      esac
 
-	      hardcode_libdir_flag_spec_CXX='$wl-rpath $wl$libdir'
+	      hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir'
 	      hardcode_libdir_separator_CXX=:
 
 	      # Commands to make compiler produce verbose output that lists
@@ -14396,9 +13831,9 @@ fi
 	    # Sun C++ 4.2, 5.x and Centerline C++
             archive_cmds_need_lc_CXX=yes
 	    no_undefined_flag_CXX=' -zdefs'
-	    archive_cmds_CXX='$CC -G$allow_undefined_flag -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+	    archive_cmds_CXX='$CC -G${allow_undefined_flag}  -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
 	    archive_expsym_cmds_CXX='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
-              $CC -G$allow_undefined_flag $wl-M $wl$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp'
+	      $CC -G${allow_undefined_flag} ${wl}-M ${wl}$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp'
 
 	    hardcode_libdir_flag_spec_CXX='-R$libdir'
 	    hardcode_shlibpath_var_CXX=no
@@ -14406,7 +13841,7 @@ fi
 	      solaris2.[0-5] | solaris2.[0-5].*) ;;
 	      *)
 		# The compiler driver will combine and reorder linker options,
-		# but understands '-z linker_flag'.
+		# but understands `-z linker_flag'.
 	        # Supported since Solaris 2.6 (maybe 2.5.1?)
 		whole_archive_flag_spec_CXX='-z allextract$convenience -z defaultextract'
 	        ;;
@@ -14423,30 +13858,30 @@ fi
 	    ;;
           gcx*)
 	    # Green Hills C++ Compiler
-	    archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-h $wl$soname -o $lib'
+	    archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib'
 
 	    # The C++ compiler must be used to create the archive.
 	    old_archive_cmds_CXX='$CC $LDFLAGS -archive -o $oldlib $oldobjs'
 	    ;;
           *)
 	    # GNU C++ compiler with Solaris linker
-	    if test yes,no = "$GXX,$with_gnu_ld"; then
-	      no_undefined_flag_CXX=' $wl-z ${wl}defs'
+	    if test "$GXX" = yes && test "$with_gnu_ld" = no; then
+	      no_undefined_flag_CXX=' ${wl}-z ${wl}defs'
 	      if $CC --version | $GREP -v '^2\.7' > /dev/null; then
-	        archive_cmds_CXX='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-h $wl$soname -o $lib'
+	        archive_cmds_CXX='$CC -shared $pic_flag -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib'
 	        archive_expsym_cmds_CXX='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
-                  $CC -shared $pic_flag -nostdlib $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp'
+		  $CC -shared $pic_flag -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp'
 
 	        # Commands to make compiler produce verbose output that lists
 	        # what "hidden" libraries, object files and flags are used when
 	        # linking a shared library.
 	        output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"'
 	      else
-	        # g++ 2.7 appears to require '-G' NOT '-shared' on this
+	        # g++ 2.7 appears to require `-G' NOT `-shared' on this
 	        # platform.
-	        archive_cmds_CXX='$CC -G -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-h $wl$soname -o $lib'
+	        archive_cmds_CXX='$CC -G -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib'
 	        archive_expsym_cmds_CXX='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
-                  $CC -G -nostdlib $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp'
+		  $CC -G -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp'
 
 	        # Commands to make compiler produce verbose output that lists
 	        # what "hidden" libraries, object files and flags are used when
@@ -14454,11 +13889,11 @@ fi
 	        output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"'
 	      fi
 
-	      hardcode_libdir_flag_spec_CXX='$wl-R $wl$libdir'
+	      hardcode_libdir_flag_spec_CXX='${wl}-R $wl$libdir'
 	      case $host_os in
 		solaris2.[0-5] | solaris2.[0-5].*) ;;
 		*)
-		  whole_archive_flag_spec_CXX='$wl-z ${wl}allextract$convenience $wl-z ${wl}defaultextract'
+		  whole_archive_flag_spec_CXX='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract'
 		  ;;
 	      esac
 	    fi
@@ -14467,52 +13902,52 @@ fi
         ;;
 
     sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*)
-      no_undefined_flag_CXX='$wl-z,text'
+      no_undefined_flag_CXX='${wl}-z,text'
       archive_cmds_need_lc_CXX=no
       hardcode_shlibpath_var_CXX=no
       runpath_var='LD_RUN_PATH'
 
       case $cc_basename in
         CC*)
-	  archive_cmds_CXX='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
-	  archive_expsym_cmds_CXX='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	  archive_cmds_CXX='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	  archive_expsym_cmds_CXX='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
 	  ;;
 	*)
-	  archive_cmds_CXX='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
-	  archive_expsym_cmds_CXX='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	  archive_cmds_CXX='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	  archive_expsym_cmds_CXX='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
 	  ;;
       esac
       ;;
 
       sysv5* | sco3.2v5* | sco5v6*)
-	# Note: We CANNOT use -z defs as we might desire, because we do not
+	# Note: We can NOT use -z defs as we might desire, because we do not
 	# link with -lc, and that would cause any symbols used from libc to
 	# always be unresolved, which means just about no library would
 	# ever link correctly.  If we're not using GNU ld we use -z text
 	# though, which does catch some bad symbols but isn't as heavy-handed
 	# as -z defs.
-	no_undefined_flag_CXX='$wl-z,text'
-	allow_undefined_flag_CXX='$wl-z,nodefs'
+	no_undefined_flag_CXX='${wl}-z,text'
+	allow_undefined_flag_CXX='${wl}-z,nodefs'
 	archive_cmds_need_lc_CXX=no
 	hardcode_shlibpath_var_CXX=no
-	hardcode_libdir_flag_spec_CXX='$wl-R,$libdir'
+	hardcode_libdir_flag_spec_CXX='${wl}-R,$libdir'
 	hardcode_libdir_separator_CXX=':'
 	link_all_deplibs_CXX=yes
-	export_dynamic_flag_spec_CXX='$wl-Bexport'
+	export_dynamic_flag_spec_CXX='${wl}-Bexport'
 	runpath_var='LD_RUN_PATH'
 
 	case $cc_basename in
           CC*)
-	    archive_cmds_CXX='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
-	    archive_expsym_cmds_CXX='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	    archive_cmds_CXX='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	    archive_expsym_cmds_CXX='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
 	    old_archive_cmds_CXX='$CC -Tprelink_objects $oldobjs~
-              '"$old_archive_cmds_CXX"
+	      '"$old_archive_cmds_CXX"
 	    reload_cmds_CXX='$CC -Tprelink_objects $reload_objs~
-              '"$reload_cmds_CXX"
+	      '"$reload_cmds_CXX"
 	    ;;
 	  *)
-	    archive_cmds_CXX='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
-	    archive_expsym_cmds_CXX='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	    archive_cmds_CXX='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	    archive_expsym_cmds_CXX='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
 	    ;;
 	esac
       ;;
@@ -14544,10 +13979,10 @@ fi
 
     { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs_CXX" >&5
 $as_echo "$ld_shlibs_CXX" >&6; }
-    test no = "$ld_shlibs_CXX" && can_build_shared=no
+    test "$ld_shlibs_CXX" = no && can_build_shared=no
 
-    GCC_CXX=$GXX
-    LD_CXX=$LD
+    GCC_CXX="$GXX"
+    LD_CXX="$LD"
 
     ## CAVEAT EMPTOR:
     ## There is no encapsulation within the following macros, do not change
@@ -14591,13 +14026,13 @@ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
   pre_test_object_deps_done=no
 
   for p in `eval "$output_verbose_link_cmd"`; do
-    case $prev$p in
+    case ${prev}${p} in
 
     -L* | -R* | -l*)
        # Some compilers place space between "-{L,R}" and the path.
        # Remove the space.
-       if test x-L = "$p" ||
-          test x-R = "$p"; then
+       if test $p = "-L" ||
+          test $p = "-R"; then
 	 prev=$p
 	 continue
        fi
@@ -14613,16 +14048,16 @@ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
        case $p in
        =*) func_stripname_cnf '=' '' "$p"; p=$lt_sysroot$func_stripname_result ;;
        esac
-       if test no = "$pre_test_object_deps_done"; then
-	 case $prev in
+       if test "$pre_test_object_deps_done" = no; then
+	 case ${prev} in
 	 -L | -R)
 	   # Internal compiler library paths should come after those
 	   # provided the user.  The postdeps already come after the
 	   # user supplied libs so there is no need to process them.
 	   if test -z "$compiler_lib_search_path_CXX"; then
-	     compiler_lib_search_path_CXX=$prev$p
+	     compiler_lib_search_path_CXX="${prev}${p}"
 	   else
-	     compiler_lib_search_path_CXX="${compiler_lib_search_path_CXX} $prev$p"
+	     compiler_lib_search_path_CXX="${compiler_lib_search_path_CXX} ${prev}${p}"
 	   fi
 	   ;;
 	 # The "-l" case would never come before the object being
@@ -14630,9 +14065,9 @@ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
 	 esac
        else
 	 if test -z "$postdeps_CXX"; then
-	   postdeps_CXX=$prev$p
+	   postdeps_CXX="${prev}${p}"
 	 else
-	   postdeps_CXX="${postdeps_CXX} $prev$p"
+	   postdeps_CXX="${postdeps_CXX} ${prev}${p}"
 	 fi
        fi
        prev=
@@ -14647,15 +14082,15 @@ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
 	 continue
        fi
 
-       if test no = "$pre_test_object_deps_done"; then
+       if test "$pre_test_object_deps_done" = no; then
 	 if test -z "$predep_objects_CXX"; then
-	   predep_objects_CXX=$p
+	   predep_objects_CXX="$p"
 	 else
 	   predep_objects_CXX="$predep_objects_CXX $p"
 	 fi
        else
 	 if test -z "$postdep_objects_CXX"; then
-	   postdep_objects_CXX=$p
+	   postdep_objects_CXX="$p"
 	 else
 	   postdep_objects_CXX="$postdep_objects_CXX $p"
 	 fi
@@ -14685,6 +14120,51 @@ interix[3-9]*)
   postdep_objects_CXX=
   postdeps_CXX=
   ;;
+
+linux*)
+  case `$CC -V 2>&1 | sed 5q` in
+  *Sun\ C*)
+    # Sun C++ 5.9
+
+    # The more standards-conforming stlport4 library is
+    # incompatible with the Cstd library. Avoid specifying
+    # it if it's in CXXFLAGS. Ignore libCrun as
+    # -library=stlport4 depends on it.
+    case " $CXX $CXXFLAGS " in
+    *" -library=stlport4 "*)
+      solaris_use_stlport4=yes
+      ;;
+    esac
+
+    if test "$solaris_use_stlport4" != yes; then
+      postdeps_CXX='-library=Cstd -library=Crun'
+    fi
+    ;;
+  esac
+  ;;
+
+solaris*)
+  case $cc_basename in
+  CC* | sunCC*)
+    # The more standards-conforming stlport4 library is
+    # incompatible with the Cstd library. Avoid specifying
+    # it if it's in CXXFLAGS. Ignore libCrun as
+    # -library=stlport4 depends on it.
+    case " $CXX $CXXFLAGS " in
+    *" -library=stlport4 "*)
+      solaris_use_stlport4=yes
+      ;;
+    esac
+
+    # Adding this requires a known-good setup of shared libraries for
+    # Sun compiler versions before 5.6, else PIC objects from an old
+    # archive will be linked into the output, leading to subtle bugs.
+    if test "$solaris_use_stlport4" != yes; then
+      postdeps_CXX='-library=Cstd -library=Crun'
+    fi
+    ;;
+  esac
+  ;;
 esac
 
 
@@ -14693,7 +14173,7 @@ case " $postdeps_CXX " in
 esac
  compiler_lib_search_dirs_CXX=
 if test -n "${compiler_lib_search_path_CXX}"; then
- compiler_lib_search_dirs_CXX=`echo " ${compiler_lib_search_path_CXX}" | $SED -e 's! -L! !g' -e 's!^ !!'`
+ compiler_lib_search_dirs_CXX=`echo " ${compiler_lib_search_path_CXX}" | ${SED} -e 's! -L! !g' -e 's!^ !!'`
 fi
 
 
@@ -14732,18 +14212,17 @@ lt_prog_compiler_static_CXX=
 
 
   # C++ specific cases for pic, static, wl, etc.
-  if test yes = "$GXX"; then
+  if test "$GXX" = yes; then
     lt_prog_compiler_wl_CXX='-Wl,'
     lt_prog_compiler_static_CXX='-static'
 
     case $host_os in
     aix*)
       # All AIX code is PIC.
-      if test ia64 = "$host_cpu"; then
+      if test "$host_cpu" = ia64; then
 	# AIX 5 now supports IA64 processor
 	lt_prog_compiler_static_CXX='-Bstatic'
       fi
-      lt_prog_compiler_pic_CXX='-fPIC'
       ;;
 
     amigaos*)
@@ -14754,8 +14233,8 @@ lt_prog_compiler_static_CXX=
         ;;
       m68k)
             # FIXME: we need at least 68020 code to build shared libraries, but
-            # adding the '-m68020' flag to GCC prevents building anything better,
-            # like '-m68040'.
+            # adding the `-m68020' flag to GCC prevents building anything better,
+            # like `-m68040'.
             lt_prog_compiler_pic_CXX='-m68020 -resident32 -malways-restore-a4'
         ;;
       esac
@@ -14770,11 +14249,6 @@ lt_prog_compiler_static_CXX=
       # Although the cygwin gcc ignores -fPIC, still need this for old-style
       # (--disable-auto-import) libraries
       lt_prog_compiler_pic_CXX='-DDLL_EXPORT'
-      case $host_os in
-      os2*)
-	lt_prog_compiler_static_CXX='$wl-static'
-	;;
-      esac
       ;;
     darwin* | rhapsody*)
       # PIC is the default on this platform
@@ -14824,7 +14298,7 @@ lt_prog_compiler_static_CXX=
     case $host_os in
       aix[4-9]*)
 	# All AIX code is PIC.
-	if test ia64 = "$host_cpu"; then
+	if test "$host_cpu" = ia64; then
 	  # AIX 5 now supports IA64 processor
 	  lt_prog_compiler_static_CXX='-Bstatic'
 	else
@@ -14864,14 +14338,14 @@ lt_prog_compiler_static_CXX=
 	case $cc_basename in
 	  CC*)
 	    lt_prog_compiler_wl_CXX='-Wl,'
-	    lt_prog_compiler_static_CXX='$wl-a ${wl}archive'
-	    if test ia64 != "$host_cpu"; then
+	    lt_prog_compiler_static_CXX='${wl}-a ${wl}archive'
+	    if test "$host_cpu" != ia64; then
 	      lt_prog_compiler_pic_CXX='+Z'
 	    fi
 	    ;;
 	  aCC*)
 	    lt_prog_compiler_wl_CXX='-Wl,'
-	    lt_prog_compiler_static_CXX='$wl-a ${wl}archive'
+	    lt_prog_compiler_static_CXX='${wl}-a ${wl}archive'
 	    case $host_cpu in
 	    hppa*64*|ia64*)
 	      # +Z the default
@@ -14908,7 +14382,7 @@ lt_prog_compiler_static_CXX=
 	    lt_prog_compiler_pic_CXX='-fPIC'
 	    ;;
 	  ecpc* )
-	    # old Intel C++ for x86_64, which still supported -KPIC.
+	    # old Intel C++ for x86_64 which still supported -KPIC.
 	    lt_prog_compiler_wl_CXX='-Wl,'
 	    lt_prog_compiler_pic_CXX='-KPIC'
 	    lt_prog_compiler_static_CXX='-static'
@@ -15053,7 +14527,7 @@ lt_prog_compiler_static_CXX=
   fi
 
 case $host_os in
-  # For platforms that do not support PIC, -DPIC is meaningless:
+  # For platforms which do not support PIC, -DPIC is meaningless:
   *djgpp*)
     lt_prog_compiler_pic_CXX=
     ;;
@@ -15085,7 +14559,7 @@ else
   lt_cv_prog_compiler_pic_works_CXX=no
    ac_outfile=conftest.$ac_objext
    echo "$lt_simple_compile_test_code" > conftest.$ac_ext
-   lt_compiler_flag="$lt_prog_compiler_pic_CXX -DPIC"  ## exclude from sc_useless_quotes_in_assignment
+   lt_compiler_flag="$lt_prog_compiler_pic_CXX -DPIC"
    # Insert the option either (1) after the last *FLAGS variable, or
    # (2) before a word containing "conftest.", or (3) at the end.
    # Note that $ac_compile itself does not contain backslashes and begins
@@ -15115,7 +14589,7 @@ fi
 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_works_CXX" >&5
 $as_echo "$lt_cv_prog_compiler_pic_works_CXX" >&6; }
 
-if test yes = "$lt_cv_prog_compiler_pic_works_CXX"; then
+if test x"$lt_cv_prog_compiler_pic_works_CXX" = xyes; then
     case $lt_prog_compiler_pic_CXX in
      "" | " "*) ;;
      *) lt_prog_compiler_pic_CXX=" $lt_prog_compiler_pic_CXX" ;;
@@ -15141,7 +14615,7 @@ if ${lt_cv_prog_compiler_static_works_CXX+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   lt_cv_prog_compiler_static_works_CXX=no
-   save_LDFLAGS=$LDFLAGS
+   save_LDFLAGS="$LDFLAGS"
    LDFLAGS="$LDFLAGS $lt_tmp_static_flag"
    echo "$lt_simple_link_test_code" > conftest.$ac_ext
    if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then
@@ -15160,13 +14634,13 @@ else
      fi
    fi
    $RM -r conftest*
-   LDFLAGS=$save_LDFLAGS
+   LDFLAGS="$save_LDFLAGS"
 
 fi
 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_static_works_CXX" >&5
 $as_echo "$lt_cv_prog_compiler_static_works_CXX" >&6; }
 
-if test yes = "$lt_cv_prog_compiler_static_works_CXX"; then
+if test x"$lt_cv_prog_compiler_static_works_CXX" = xyes; then
     :
 else
     lt_prog_compiler_static_CXX=
@@ -15280,8 +14754,8 @@ $as_echo "$lt_cv_prog_compiler_c_o_CXX" >&6; }
 
 
 
-hard_links=nottested
-if test no = "$lt_cv_prog_compiler_c_o_CXX" && test no != "$need_locks"; then
+hard_links="nottested"
+if test "$lt_cv_prog_compiler_c_o_CXX" = no && test "$need_locks" != no; then
   # do not overwrite the value of need_locks provided by the user
   { $as_echo "$as_me:${as_lineno-$LINENO}: checking if we can lock with hard links" >&5
 $as_echo_n "checking if we can lock with hard links... " >&6; }
@@ -15293,9 +14767,9 @@ $as_echo_n "checking if we can lock with hard links... " >&6; }
   ln conftest.a conftest.b 2>/dev/null && hard_links=no
   { $as_echo "$as_me:${as_lineno-$LINENO}: result: $hard_links" >&5
 $as_echo "$hard_links" >&6; }
-  if test no = "$hard_links"; then
-    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: '$CC' does not support '-c -o', so 'make -j' may be unsafe" >&5
-$as_echo "$as_me: WARNING: '$CC' does not support '-c -o', so 'make -j' may be unsafe" >&2;}
+  if test "$hard_links" = no; then
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&5
+$as_echo "$as_me: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&2;}
     need_locks=warn
   fi
 else
@@ -15312,21 +14786,17 @@ $as_echo_n "checking whether the $compiler linker ($LD) supports shared librarie
   case $host_os in
   aix[4-9]*)
     # If we're using GNU nm, then we don't want the "-C" option.
-    # -C means demangle to GNU nm, but means don't demangle to AIX nm.
-    # Without the "-l" option, or with the "-B" option, AIX nm treats
-    # weak defined symbols like other global defined symbols, whereas
-    # GNU nm marks them as "W".
-    # While the 'weak' keyword is ignored in the Export File, we need
-    # it in the Import File for the 'aix-soname' feature, so we have
-    # to replace the "-B" option with "-P" for AIX nm.
+    # -C means demangle to AIX nm, but means don't demangle with GNU nm
+    # Also, AIX nm treats weak defined symbols like other global defined
+    # symbols, whereas GNU nm marks them as "W".
     if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then
-      export_symbols_cmds_CXX='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && (substr(\$ 3,1,1) != ".")) { if (\$ 2 == "W") { print \$ 3 " weak" } else { print \$ 3 } } }'\'' | sort -u > $export_symbols'
+      export_symbols_cmds_CXX='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols'
     else
-      export_symbols_cmds_CXX='`func_echo_all $NM | $SED -e '\''s/B\([^B]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && (substr(\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols'
+      export_symbols_cmds_CXX='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols'
     fi
     ;;
   pw32*)
-    export_symbols_cmds_CXX=$ltdll_cmds
+    export_symbols_cmds_CXX="$ltdll_cmds"
     ;;
   cygwin* | mingw* | cegcc*)
     case $cc_basename in
@@ -15349,7 +14819,7 @@ $as_echo_n "checking whether the $compiler linker ($LD) supports shared librarie
 
 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs_CXX" >&5
 $as_echo "$ld_shlibs_CXX" >&6; }
-test no = "$ld_shlibs_CXX" && can_build_shared=no
+test "$ld_shlibs_CXX" = no && can_build_shared=no
 
 with_gnu_ld_CXX=$with_gnu_ld
 
@@ -15366,7 +14836,7 @@ x|xyes)
   # Assume -lc should be added
   archive_cmds_need_lc_CXX=yes
 
-  if test yes,yes = "$GCC,$enable_shared"; then
+  if test "$enable_shared" = yes && test "$GCC" = yes; then
     case $archive_cmds_CXX in
     *'~'*)
       # FIXME: we may have to deal with multi-command sequences.
@@ -15494,7 +14964,7 @@ $as_echo_n "checking dynamic linker characteristics... " >&6; }
 library_names_spec=
 libname_spec='lib$name'
 soname_spec=
-shrext_cmds=.so
+shrext_cmds=".so"
 postinstall_cmds=
 postuninstall_cmds=
 finish_cmds=
@@ -15511,16 +14981,14 @@ hardcode_into_libs=no
 # flags to be left without arguments
 need_version=unknown
 
-
-
 case $host_os in
 aix3*)
   version_type=linux # correct to gnu/linux during the next big refactor
-  library_names_spec='$libname$release$shared_ext$versuffix $libname.a'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a'
   shlibpath_var=LIBPATH
 
   # AIX 3 has no versioning support, so we append a major version to the name.
-  soname_spec='$libname$release$shared_ext$major'
+  soname_spec='${libname}${release}${shared_ext}$major'
   ;;
 
 aix[4-9]*)
@@ -15528,91 +14996,41 @@ aix[4-9]*)
   need_lib_prefix=no
   need_version=no
   hardcode_into_libs=yes
-  if test ia64 = "$host_cpu"; then
+  if test "$host_cpu" = ia64; then
     # AIX 5 supports IA64
-    library_names_spec='$libname$release$shared_ext$major $libname$release$shared_ext$versuffix $libname$shared_ext'
+    library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}'
     shlibpath_var=LD_LIBRARY_PATH
   else
     # With GCC up to 2.95.x, collect2 would create an import file
     # for dependence libraries.  The import file would start with
-    # the line '#! .'.  This would cause the generated library to
-    # depend on '.', always an invalid library.  This was fixed in
+    # the line `#! .'.  This would cause the generated library to
+    # depend on `.', always an invalid library.  This was fixed in
     # development snapshots of GCC prior to 3.0.
     case $host_os in
       aix4 | aix4.[01] | aix4.[01].*)
       if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)'
 	   echo ' yes '
-	   echo '#endif'; } | $CC -E - | $GREP yes > /dev/null; then
+	   echo '#endif'; } | ${CC} -E - | $GREP yes > /dev/null; then
 	:
       else
 	can_build_shared=no
       fi
       ;;
     esac
-    # Using Import Files as archive members, it is possible to support
-    # filename-based versioning of shared library archives on AIX. While
-    # this would work for both with and without runtime linking, it will
-    # prevent static linking of such archives. So we do filename-based
-    # shared library versioning with .so extension only, which is used
-    # when both runtime linking and shared linking is enabled.
-    # Unfortunately, runtime linking may impact performance, so we do
-    # not want this to be the default eventually. Also, we use the
-    # versioned .so libs for executables only if there is the -brtl
-    # linker flag in LDFLAGS as well, or --with-aix-soname=svr4 only.
-    # To allow for filename-based versioning support, we need to create
-    # libNAME.so.V as an archive file, containing:
-    # *) an Import File, referring to the versioned filename of the
-    #    archive as well as the shared archive member, telling the
-    #    bitwidth (32 or 64) of that shared object, and providing the
-    #    list of exported symbols of that shared object, eventually
-    #    decorated with the 'weak' keyword
-    # *) the shared object with the F_LOADONLY flag set, to really avoid
-    #    it being seen by the linker.
-    # At run time we better use the real file rather than another symlink,
-    # but for link time we create the symlink libNAME.so -> libNAME.so.V
-
-    case $with_aix_soname,$aix_use_runtimelinking in
-    # AIX (on Power*) has no versioning support, so currently we cannot hardcode correct
+    # AIX (on Power*) has no versioning support, so currently we can not hardcode correct
     # soname into executable. Probably we can add versioning support to
     # collect2, so additional links can be useful in future.
-    aix,yes) # traditional libtool
-      dynamic_linker='AIX unversionable lib.so'
+    if test "$aix_use_runtimelinking" = yes; then
       # If using run time linking (on AIX 4.2 or later) use lib<name>.so
       # instead of lib<name>.a to let people know that these are not
       # typical AIX shared libraries.
-      library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
-      ;;
-    aix,no) # traditional AIX only
-      dynamic_linker='AIX lib.a(lib.so.V)'
+      library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+    else
       # We preserve .a as extension for shared libraries through AIX4.2
       # and later when we are not doing run time linking.
-      library_names_spec='$libname$release.a $libname.a'
-      soname_spec='$libname$release$shared_ext$major'
-      ;;
-    svr4,*) # full svr4 only
-      dynamic_linker="AIX lib.so.V($shared_archive_member_spec.o)"
-      library_names_spec='$libname$release$shared_ext$major $libname$shared_ext'
-      # We do not specify a path in Import Files, so LIBPATH fires.
-      shlibpath_overrides_runpath=yes
-      ;;
-    *,yes) # both, prefer svr4
-      dynamic_linker="AIX lib.so.V($shared_archive_member_spec.o), lib.a(lib.so.V)"
-      library_names_spec='$libname$release$shared_ext$major $libname$shared_ext'
-      # unpreferred sharedlib libNAME.a needs extra handling
-      postinstall_cmds='test -n "$linkname" || linkname="$realname"~func_stripname "" ".so" "$linkname"~$install_shared_prog "$dir/$func_stripname_result.$libext" "$destdir/$func_stripname_result.$libext"~test -z "$tstripme" || test -z "$striplib" || $striplib "$destdir/$func_stripname_result.$libext"'
-      postuninstall_cmds='for n in $library_names $old_library; do :; done~func_stripname "" ".so" "$n"~test "$func_stripname_result" = "$n" || func_append rmfiles " $odir/$func_stripname_result.$libext"'
-      # We do not specify a path in Import Files, so LIBPATH fires.
-      shlibpath_overrides_runpath=yes
-      ;;
-    *,no) # both, prefer aix
-      dynamic_linker="AIX lib.a(lib.so.V), lib.so.V($shared_archive_member_spec.o)"
-      library_names_spec='$libname$release.a $libname.a'
-      soname_spec='$libname$release$shared_ext$major'
-      # unpreferred sharedlib libNAME.so.V and symlink libNAME.so need extra handling
-      postinstall_cmds='test -z "$dlname" || $install_shared_prog $dir/$dlname $destdir/$dlname~test -z "$tstripme" || test -z "$striplib" || $striplib $destdir/$dlname~test -n "$linkname" || linkname=$realname~func_stripname "" ".a" "$linkname"~(cd "$destdir" && $LN_S -f $dlname $func_stripname_result.so)'
-      postuninstall_cmds='test -z "$dlname" || func_append rmfiles " $odir/$dlname"~for n in $old_library $library_names; do :; done~func_stripname "" ".a" "$n"~func_append rmfiles " $odir/$func_stripname_result.so"'
-      ;;
-    esac
+      library_names_spec='${libname}${release}.a $libname.a'
+      soname_spec='${libname}${release}${shared_ext}$major'
+    fi
     shlibpath_var=LIBPATH
   fi
   ;;
@@ -15622,18 +15040,18 @@ amigaos*)
   powerpc)
     # Since July 2007 AmigaOS4 officially supports .so libraries.
     # When compiling the executable, add -use-dynld -Lsobjs: to the compileline.
-    library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
     ;;
   m68k)
     library_names_spec='$libname.ixlibrary $libname.a'
     # Create ${libname}_ixlibrary.a entries in /sys/libs.
-    finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done'
+    finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done'
     ;;
   esac
   ;;
 
 beos*)
-  library_names_spec='$libname$shared_ext'
+  library_names_spec='${libname}${shared_ext}'
   dynamic_linker="$host_os ld.so"
   shlibpath_var=LIBRARY_PATH
   ;;
@@ -15641,8 +15059,8 @@ beos*)
 bsdi[45]*)
   version_type=linux # correct to gnu/linux during the next big refactor
   need_version=no
-  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
-  soname_spec='$libname$release$shared_ext$major'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
   finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir'
   shlibpath_var=LD_LIBRARY_PATH
   sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib"
@@ -15654,7 +15072,7 @@ bsdi[45]*)
 
 cygwin* | mingw* | pw32* | cegcc*)
   version_type=windows
-  shrext_cmds=.dll
+  shrext_cmds=".dll"
   need_version=no
   need_lib_prefix=no
 
@@ -15663,8 +15081,8 @@ cygwin* | mingw* | pw32* | cegcc*)
     # gcc
     library_names_spec='$libname.dll.a'
     # DLL is installed to $(libdir)/../bin by postinstall_cmds
-    postinstall_cmds='base_file=`basename \$file`~
-      dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~
+    postinstall_cmds='base_file=`basename \${file}`~
+      dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~
       dldir=$destdir/`dirname \$dlpath`~
       test -d \$dldir || mkdir -p \$dldir~
       $install_prog $dir/$dlname \$dldir/$dlname~
@@ -15680,16 +15098,16 @@ cygwin* | mingw* | pw32* | cegcc*)
     case $host_os in
     cygwin*)
       # Cygwin DLLs use 'cyg' prefix rather than 'lib'
-      soname_spec='`echo $libname | sed -e 's/^lib/cyg/'``echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext'
+      soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
 
       ;;
     mingw* | cegcc*)
       # MinGW DLLs use traditional 'lib' prefix
-      soname_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext'
+      soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
       ;;
     pw32*)
       # pw32 DLLs use 'pw' prefix rather than 'lib'
-      library_names_spec='`echo $libname | sed -e 's/^lib/pw/'``echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext'
+      library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
       ;;
     esac
     dynamic_linker='Win32 ld.exe'
@@ -15698,8 +15116,8 @@ cygwin* | mingw* | pw32* | cegcc*)
   *,cl*)
     # Native MSVC
     libname_spec='$name'
-    soname_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext'
-    library_names_spec='$libname.dll.lib'
+    soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
+    library_names_spec='${libname}.dll.lib'
 
     case $build_os in
     mingw*)
@@ -15726,7 +15144,7 @@ cygwin* | mingw* | pw32* | cegcc*)
       sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"`
       ;;
     *)
-      sys_lib_search_path_spec=$LIB
+      sys_lib_search_path_spec="$LIB"
       if $ECHO "$sys_lib_search_path_spec" | $GREP ';[c-zC-Z]:/' >/dev/null; then
         # It is most probably a Windows format PATH.
         sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'`
@@ -15739,8 +15157,8 @@ cygwin* | mingw* | pw32* | cegcc*)
     esac
 
     # DLL is installed to $(libdir)/../bin by postinstall_cmds
-    postinstall_cmds='base_file=`basename \$file`~
-      dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~
+    postinstall_cmds='base_file=`basename \${file}`~
+      dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~
       dldir=$destdir/`dirname \$dlpath`~
       test -d \$dldir || mkdir -p \$dldir~
       $install_prog $dir/$dlname \$dldir/$dlname'
@@ -15753,7 +15171,7 @@ cygwin* | mingw* | pw32* | cegcc*)
 
   *)
     # Assume MSVC wrapper
-    library_names_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext $libname.lib'
+    library_names_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext} $libname.lib'
     dynamic_linker='Win32 ld.exe'
     ;;
   esac
@@ -15766,8 +15184,8 @@ darwin* | rhapsody*)
   version_type=darwin
   need_lib_prefix=no
   need_version=no
-  library_names_spec='$libname$release$major$shared_ext $libname$shared_ext'
-  soname_spec='$libname$release$major$shared_ext'
+  library_names_spec='${libname}${release}${major}$shared_ext ${libname}$shared_ext'
+  soname_spec='${libname}${release}${major}$shared_ext'
   shlibpath_overrides_runpath=yes
   shlibpath_var=DYLD_LIBRARY_PATH
   shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`'
@@ -15779,8 +15197,8 @@ dgux*)
   version_type=linux # correct to gnu/linux during the next big refactor
   need_lib_prefix=no
   need_version=no
-  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
-  soname_spec='$libname$release$shared_ext$major'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext'
+  soname_spec='${libname}${release}${shared_ext}$major'
   shlibpath_var=LD_LIBRARY_PATH
   ;;
 
@@ -15798,13 +15216,12 @@ freebsd* | dragonfly*)
   version_type=freebsd-$objformat
   case $version_type in
     freebsd-elf*)
-      library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
-      soname_spec='$libname$release$shared_ext$major'
+      library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}'
       need_version=no
       need_lib_prefix=no
       ;;
     freebsd-*)
-      library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix'
+      library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix'
       need_version=yes
       ;;
   esac
@@ -15834,10 +15251,10 @@ haiku*)
   need_lib_prefix=no
   need_version=no
   dynamic_linker="$host_os runtime_loader"
-  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
-  soname_spec='$libname$release$shared_ext$major'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
   shlibpath_var=LIBRARY_PATH
-  shlibpath_overrides_runpath=no
+  shlibpath_overrides_runpath=yes
   sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib'
   hardcode_into_libs=yes
   ;;
@@ -15855,15 +15272,14 @@ hpux9* | hpux10* | hpux11*)
     dynamic_linker="$host_os dld.so"
     shlibpath_var=LD_LIBRARY_PATH
     shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
-    library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
-    soname_spec='$libname$release$shared_ext$major'
-    if test 32 = "$HPUX_IA64_MODE"; then
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+    soname_spec='${libname}${release}${shared_ext}$major'
+    if test "X$HPUX_IA64_MODE" = X32; then
       sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib"
-      sys_lib_dlsearch_path_spec=/usr/lib/hpux32
     else
       sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64"
-      sys_lib_dlsearch_path_spec=/usr/lib/hpux64
     fi
+    sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
     ;;
   hppa*64*)
     shrext_cmds='.sl'
@@ -15871,8 +15287,8 @@ hpux9* | hpux10* | hpux11*)
     dynamic_linker="$host_os dld.sl"
     shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH
     shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
-    library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
-    soname_spec='$libname$release$shared_ext$major'
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+    soname_spec='${libname}${release}${shared_ext}$major'
     sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64"
     sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
     ;;
@@ -15881,8 +15297,8 @@ hpux9* | hpux10* | hpux11*)
     dynamic_linker="$host_os dld.sl"
     shlibpath_var=SHLIB_PATH
     shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH
-    library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
-    soname_spec='$libname$release$shared_ext$major'
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+    soname_spec='${libname}${release}${shared_ext}$major'
     ;;
   esac
   # HP-UX runs *really* slowly unless shared libraries are mode 555, ...
@@ -15895,8 +15311,8 @@ interix[3-9]*)
   version_type=linux # correct to gnu/linux during the next big refactor
   need_lib_prefix=no
   need_version=no
-  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
-  soname_spec='$libname$release$shared_ext$major'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
   dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)'
   shlibpath_var=LD_LIBRARY_PATH
   shlibpath_overrides_runpath=no
@@ -15907,7 +15323,7 @@ irix5* | irix6* | nonstopux*)
   case $host_os in
     nonstopux*) version_type=nonstopux ;;
     *)
-	if test yes = "$lt_cv_prog_gnu_ld"; then
+	if test "$lt_cv_prog_gnu_ld" = yes; then
 		version_type=linux # correct to gnu/linux during the next big refactor
 	else
 		version_type=irix
@@ -15915,8 +15331,8 @@ irix5* | irix6* | nonstopux*)
   esac
   need_lib_prefix=no
   need_version=no
-  soname_spec='$libname$release$shared_ext$major'
-  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$release$shared_ext $libname$shared_ext'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}'
   case $host_os in
   irix5* | nonstopux*)
     libsuff= shlibsuff=
@@ -15935,8 +15351,8 @@ irix5* | irix6* | nonstopux*)
   esac
   shlibpath_var=LD_LIBRARY${shlibsuff}_PATH
   shlibpath_overrides_runpath=no
-  sys_lib_search_path_spec="/usr/lib$libsuff /lib$libsuff /usr/local/lib$libsuff"
-  sys_lib_dlsearch_path_spec="/usr/lib$libsuff /lib$libsuff"
+  sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}"
+  sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}"
   hardcode_into_libs=yes
   ;;
 
@@ -15945,33 +15361,13 @@ linux*oldld* | linux*aout* | linux*coff*)
   dynamic_linker=no
   ;;
 
-linux*android*)
-  version_type=none # Android doesn't support versioned libraries.
-  need_lib_prefix=no
-  need_version=no
-  library_names_spec='$libname$release$shared_ext'
-  soname_spec='$libname$release$shared_ext'
-  finish_cmds=
-  shlibpath_var=LD_LIBRARY_PATH
-  shlibpath_overrides_runpath=yes
-
-  # This implies no fast_install, which is unacceptable.
-  # Some rework will be needed to allow for fast_install
-  # before this can be enabled.
-  hardcode_into_libs=yes
-
-  dynamic_linker='Android linker'
-  # Don't embed -rpath directories since the linker doesn't support them.
-  hardcode_libdir_flag_spec_CXX='-L$libdir'
-  ;;
-
 # This must be glibc/ELF.
 linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*)
   version_type=linux # correct to gnu/linux during the next big refactor
   need_lib_prefix=no
   need_version=no
-  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
-  soname_spec='$libname$release$shared_ext$major'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
   finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir'
   shlibpath_var=LD_LIBRARY_PATH
   shlibpath_overrides_runpath=no
@@ -16015,12 +15411,7 @@ fi
   # before this can be enabled.
   hardcode_into_libs=yes
 
-  # Ideally, we could use ldconfig to report *all* directores which are
-  # searched for libraries, however this is still not possible.  Aside from not
-  # being certain /sbin/ldconfig is available, command
-  # 'ldconfig -N -X -v | grep ^/' on 64bit Fedora does not report /usr/lib64,
-  # even though it is searched at run-time.  Try to do the best guess by
-  # appending ld.so.conf contents (and includes) to the search path.
+  # Append ld.so.conf contents to the search path
   if test -f /etc/ld.so.conf; then
     lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[	 ]*hwcap[	 ]/d;s/[:,	]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '`
     sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra"
@@ -16052,12 +15443,12 @@ netbsd*)
   need_lib_prefix=no
   need_version=no
   if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
-    library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix'
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
     finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
     dynamic_linker='NetBSD (a.out) ld.so'
   else
-    library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
-    soname_spec='$libname$release$shared_ext$major'
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+    soname_spec='${libname}${release}${shared_ext}$major'
     dynamic_linker='NetBSD ld.elf_so'
   fi
   shlibpath_var=LD_LIBRARY_PATH
@@ -16067,7 +15458,7 @@ netbsd*)
 
 newsos6)
   version_type=linux # correct to gnu/linux during the next big refactor
-  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
   shlibpath_var=LD_LIBRARY_PATH
   shlibpath_overrides_runpath=yes
   ;;
@@ -16076,68 +15467,58 @@ newsos6)
   version_type=qnx
   need_lib_prefix=no
   need_version=no
-  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
-  soname_spec='$libname$release$shared_ext$major'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
   shlibpath_var=LD_LIBRARY_PATH
   shlibpath_overrides_runpath=no
   hardcode_into_libs=yes
   dynamic_linker='ldqnx.so'
   ;;
 
-openbsd* | bitrig*)
+openbsd*)
   version_type=sunos
-  sys_lib_dlsearch_path_spec=/usr/lib
+  sys_lib_dlsearch_path_spec="/usr/lib"
   need_lib_prefix=no
-  if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then
-    need_version=no
-  else
-    need_version=yes
-  fi
-  library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix'
+  # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs.
+  case $host_os in
+    openbsd3.3 | openbsd3.3.*)	need_version=yes ;;
+    *)				need_version=no  ;;
+  esac
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
   finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
   shlibpath_var=LD_LIBRARY_PATH
-  shlibpath_overrides_runpath=yes
+  if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+    case $host_os in
+      openbsd2.[89] | openbsd2.[89].*)
+	shlibpath_overrides_runpath=no
+	;;
+      *)
+	shlibpath_overrides_runpath=yes
+	;;
+      esac
+  else
+    shlibpath_overrides_runpath=yes
+  fi
   ;;
 
 os2*)
   libname_spec='$name'
-  version_type=windows
-  shrext_cmds=.dll
-  need_version=no
+  shrext_cmds=".dll"
   need_lib_prefix=no
-  # OS/2 can only load a DLL with a base name of 8 characters or less.
-  soname_spec='`test -n "$os2dllname" && libname="$os2dllname";
-    v=$($ECHO $release$versuffix | tr -d .-);
-    n=$($ECHO $libname | cut -b -$((8 - ${#v})) | tr . _);
-    $ECHO $n$v`$shared_ext'
-  library_names_spec='${libname}_dll.$libext'
+  library_names_spec='$libname${shared_ext} $libname.a'
   dynamic_linker='OS/2 ld.exe'
-  shlibpath_var=BEGINLIBPATH
-  sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib"
-  sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
-  postinstall_cmds='base_file=`basename \$file`~
-    dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; $ECHO \$dlname'\''`~
-    dldir=$destdir/`dirname \$dlpath`~
-    test -d \$dldir || mkdir -p \$dldir~
-    $install_prog $dir/$dlname \$dldir/$dlname~
-    chmod a+x \$dldir/$dlname~
-    if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then
-      eval '\''$striplib \$dldir/$dlname'\'' || exit \$?;
-    fi'
-  postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; $ECHO \$dlname'\''`~
-    dlpath=$dir/\$dldll~
-    $RM \$dlpath'
+  shlibpath_var=LIBPATH
   ;;
 
 osf3* | osf4* | osf5*)
   version_type=osf
   need_lib_prefix=no
   need_version=no
-  soname_spec='$libname$release$shared_ext$major'
-  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
   shlibpath_var=LD_LIBRARY_PATH
   sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib"
-  sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
+  sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec"
   ;;
 
 rdos*)
@@ -16148,8 +15529,8 @@ solaris*)
   version_type=linux # correct to gnu/linux during the next big refactor
   need_lib_prefix=no
   need_version=no
-  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
-  soname_spec='$libname$release$shared_ext$major'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
   shlibpath_var=LD_LIBRARY_PATH
   shlibpath_overrides_runpath=yes
   hardcode_into_libs=yes
@@ -16159,11 +15540,11 @@ solaris*)
 
 sunos4*)
   version_type=sunos
-  library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
   finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir'
   shlibpath_var=LD_LIBRARY_PATH
   shlibpath_overrides_runpath=yes
-  if test yes = "$with_gnu_ld"; then
+  if test "$with_gnu_ld" = yes; then
     need_lib_prefix=no
   fi
   need_version=yes
@@ -16171,8 +15552,8 @@ sunos4*)
 
 sysv4 | sysv4.3*)
   version_type=linux # correct to gnu/linux during the next big refactor
-  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
-  soname_spec='$libname$release$shared_ext$major'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
   shlibpath_var=LD_LIBRARY_PATH
   case $host_vendor in
     sni)
@@ -16193,24 +15574,24 @@ sysv4 | sysv4.3*)
   ;;
 
 sysv4*MP*)
-  if test -d /usr/nec; then
+  if test -d /usr/nec ;then
     version_type=linux # correct to gnu/linux during the next big refactor
-    library_names_spec='$libname$shared_ext.$versuffix $libname$shared_ext.$major $libname$shared_ext'
-    soname_spec='$libname$shared_ext.$major'
+    library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}'
+    soname_spec='$libname${shared_ext}.$major'
     shlibpath_var=LD_LIBRARY_PATH
   fi
   ;;
 
 sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
-  version_type=sco
+  version_type=freebsd-elf
   need_lib_prefix=no
   need_version=no
-  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext $libname$shared_ext'
-  soname_spec='$libname$release$shared_ext$major'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
   shlibpath_var=LD_LIBRARY_PATH
   shlibpath_overrides_runpath=yes
   hardcode_into_libs=yes
-  if test yes = "$with_gnu_ld"; then
+  if test "$with_gnu_ld" = yes; then
     sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib'
   else
     sys_lib_search_path_spec='/usr/ccs/lib /usr/lib'
@@ -16228,7 +15609,7 @@ tpf*)
   version_type=linux # correct to gnu/linux during the next big refactor
   need_lib_prefix=no
   need_version=no
-  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
   shlibpath_var=LD_LIBRARY_PATH
   shlibpath_overrides_runpath=no
   hardcode_into_libs=yes
@@ -16236,8 +15617,8 @@ tpf*)
 
 uts4*)
   version_type=linux # correct to gnu/linux during the next big refactor
-  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
-  soname_spec='$libname$release$shared_ext$major'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
   shlibpath_var=LD_LIBRARY_PATH
   ;;
 
@@ -16247,32 +15628,20 @@ uts4*)
 esac
 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $dynamic_linker" >&5
 $as_echo "$dynamic_linker" >&6; }
-test no = "$dynamic_linker" && can_build_shared=no
+test "$dynamic_linker" = no && can_build_shared=no
 
 variables_saved_for_relink="PATH $shlibpath_var $runpath_var"
-if test yes = "$GCC"; then
+if test "$GCC" = yes; then
   variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH"
 fi
 
-if test set = "${lt_cv_sys_lib_search_path_spec+set}"; then
-  sys_lib_search_path_spec=$lt_cv_sys_lib_search_path_spec
+if test "${lt_cv_sys_lib_search_path_spec+set}" = set; then
+  sys_lib_search_path_spec="$lt_cv_sys_lib_search_path_spec"
 fi
-
-if test set = "${lt_cv_sys_lib_dlsearch_path_spec+set}"; then
-  sys_lib_dlsearch_path_spec=$lt_cv_sys_lib_dlsearch_path_spec
+if test "${lt_cv_sys_lib_dlsearch_path_spec+set}" = set; then
+  sys_lib_dlsearch_path_spec="$lt_cv_sys_lib_dlsearch_path_spec"
 fi
 
-# remember unaugmented sys_lib_dlsearch_path content for libtool script decls...
-configure_time_dlsearch_path=$sys_lib_dlsearch_path_spec
-
-# ... but it needs LT_SYS_LIBRARY_PATH munging for other configure-time code
-func_munge_path_list sys_lib_dlsearch_path_spec "$LT_SYS_LIBRARY_PATH"
-
-# to be used as default LT_SYS_LIBRARY_PATH value in generated libtool
-configure_time_lt_sys_library_path=$LT_SYS_LIBRARY_PATH
-
-
-
 
 
 
@@ -16315,15 +15684,15 @@ $as_echo_n "checking how to hardcode library paths into programs... " >&6; }
 hardcode_action_CXX=
 if test -n "$hardcode_libdir_flag_spec_CXX" ||
    test -n "$runpath_var_CXX" ||
-   test yes = "$hardcode_automatic_CXX"; then
+   test "X$hardcode_automatic_CXX" = "Xyes" ; then
 
   # We can hardcode non-existent directories.
-  if test no != "$hardcode_direct_CXX" &&
+  if test "$hardcode_direct_CXX" != no &&
      # If the only mechanism to avoid hardcoding is shlibpath_var, we
      # have to relink, otherwise we might link with an installed library
      # when we should be linking with a yet-to-be-installed one
-     ## test no != "$_LT_TAGVAR(hardcode_shlibpath_var, CXX)" &&
-     test no != "$hardcode_minus_L_CXX"; then
+     ## test "$_LT_TAGVAR(hardcode_shlibpath_var, CXX)" != no &&
+     test "$hardcode_minus_L_CXX" != no; then
     # Linking always hardcodes the temporary library directory.
     hardcode_action_CXX=relink
   else
@@ -16338,12 +15707,12 @@ fi
 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $hardcode_action_CXX" >&5
 $as_echo "$hardcode_action_CXX" >&6; }
 
-if test relink = "$hardcode_action_CXX" ||
-   test yes = "$inherit_rpath_CXX"; then
+if test "$hardcode_action_CXX" = relink ||
+   test "$inherit_rpath_CXX" = yes; then
   # Fast installation is not supported
   enable_fast_install=no
-elif test yes = "$shlibpath_overrides_runpath" ||
-     test no = "$enable_shared"; then
+elif test "$shlibpath_overrides_runpath" = yes ||
+     test "$enable_shared" = no; then
   # Fast installation is not necessary
   enable_fast_install=needless
 fi
@@ -16366,7 +15735,7 @@ fi
   lt_cv_path_LD=$lt_save_path_LD
   lt_cv_prog_gnu_ldcxx=$lt_cv_prog_gnu_ld
   lt_cv_prog_gnu_ld=$lt_save_with_gnu_ld
-fi # test yes != "$_lt_caught_CXX_error"
+fi # test "$_lt_caught_CXX_error" != yes
 
 ac_ext=c
 ac_cpp='$CPP $CPPFLAGS'
@@ -16603,7 +15972,7 @@ fi
 
 
 
-am__api_version='1.15'
+am__api_version='1.14'
 
 # Find a good install program.  We prefer a C program (faster),
 # so one script is as good as another.  But avoid the broken or
@@ -16792,7 +16161,7 @@ else
 $as_echo "$as_me: WARNING: 'missing' script is too old or missing" >&2;}
 fi
 
-if test x"${install_sh+set}" != xset; then
+if test x"${install_sh}" != xset; then
   case $am_aux_dir in
   *\ * | *\	*)
     install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;;
@@ -17035,7 +16404,7 @@ fi
 
 # Define the identity of the package.
  PACKAGE='ceph'
- VERSION='10.0.5'
+ VERSION='10.1.0'
 
 
 cat >>confdefs.h <<_ACEOF
@@ -17069,8 +16438,8 @@ MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"}
 # <http://lists.gnu.org/archive/html/automake/2012-07/msg00014.html>
 mkdir_p='$(MKDIR_P)'
 
-# We need awk for the "check" target (and possibly the TAP driver).  The
-# system "awk" is bad on some platforms.
+# We need awk for the "check" target.  The system "awk" is bad on
+# some platforms.
 # Always define AMTAR for backward compatibility.  Yes, it's still used
 # in the wild :-(  We should find a proper way to deprecate it ...
 AMTAR='$${TAR-tar}'
@@ -17499,7 +16868,6 @@ END
     as_fn_error $? "Your 'rm' program is bad, sorry." "$LINENO" 5
   fi
 fi
-
 # enable make V=0 (if automake >1.11)
 # Check whether --enable-silent-rules was given.
 if test "${enable_silent_rules+set}" = set; then :
@@ -18209,7 +17577,7 @@ fi
 
 #AS_IF([test "$enable_server" = "yes"], [AC_DEFINE([WITH_MON, WITH_OSD, WITH_MDS, ENABLE_SERVER])])
 
-# cython is required to build librbd python bindings
+# cython is required to build python bindings for libraries
 if test x"$with_cython" = xyes; then
     # Extract the first word of "cython", so it can be a program name with args.
 set dummy cython; ac_word=$2
@@ -18254,6 +17622,53 @@ $as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
 as_fn_error $? "cython not found
 See \`config.log' for more details" "$LINENO" 5; }
     fi
+    # Extract the first word of "python-config", so it can be a program name with args.
+set dummy python-config; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_PYTHON_CONFIG_CHECK+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$PYTHON_CONFIG_CHECK"; then
+  ac_cv_prog_PYTHON_CONFIG_CHECK="$PYTHON_CONFIG_CHECK" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_PYTHON_CONFIG_CHECK="yes"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+PYTHON_CONFIG_CHECK=$ac_cv_prog_PYTHON_CONFIG_CHECK
+if test -n "$PYTHON_CONFIG_CHECK"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PYTHON_CONFIG_CHECK" >&5
+$as_echo "$PYTHON_CONFIG_CHECK" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+    if test x"$PYTHON_CONFIG_CHECK" != xyes; then
+        { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "python-config not found
+See \`config.log' for more details" "$LINENO" 5; }
+    fi
+    PYTHON_CFLAGS=`python-config --cflags`
+
+    PYTHON_LDFLAGS=`python-config --ldflags`
+
 fi
 
 # cond-check if snappy-devel is installed, needed by leveldb that is need by server parts of the project
@@ -21340,7 +20755,7 @@ else
 JAVA_TEST=Test.java
 CLASS_TEST=Test.class
 cat << \EOF > $JAVA_TEST
-/* #line 21343 "configure" */
+/* #line 20758 "configure" */
 public class Test {
 }
 EOF
@@ -23850,6 +23265,14 @@ fi
 
 
 
+ac_fn_cxx_check_header_mongrel "$LINENO" "boost/asio/coroutine.hpp" "ac_cv_header_boost_asio_coroutine_hpp" "$ac_includes_default"
+if test "x$ac_cv_header_boost_asio_coroutine_hpp" = xyes; then :
+
+$as_echo "#define HAVE_BOOST_ASIO_COROUTINE /**/" >>confdefs.h
+
+fi
+
+
 ac_fn_cxx_check_header_mongrel "$LINENO" "boost/statechart/state.hpp" "ac_cv_header_boost_statechart_state_hpp" "$ac_includes_default"
 if test "x$ac_cv_header_boost_statechart_state_hpp" = xyes; then :
 
@@ -24045,8 +23468,10 @@ _ACEOF
   LIBS="-lboost_iostreams $LIBS"
 
 else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: \"Boost iostreams library not found.\"" >&5
-$as_echo "$as_me: \"Boost iostreams library not found.\"" >&6;}
+  { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "\"Boost iostreams library not found.\"
+See \`config.log' for more details" "$LINENO" 5; }
 fi
 
 fi
@@ -24648,6 +24073,19 @@ _ACEOF
 fi
 done
 
+for ac_func in pwritev
+do :
+  ac_fn_c_check_func "$LINENO" "pwritev" "ac_cv_func_pwritev"
+if test "x$ac_cv_func_pwritev" = xyes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_PWRITEV 1
+_ACEOF
+
+$as_echo "#define HAVE_PWRITEV 1" >>confdefs.h
+
+fi
+done
+
 
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for fdatasync" >&5
 $as_echo_n "checking for fdatasync... " >&6; }
@@ -25373,6 +24811,81 @@ else
 fi
 
 
+# disable OpenLDAP support
+
+# Check whether --with-openldap was given.
+if test "${with_openldap+set}" = set; then :
+  withval=$with_openldap;
+fi
+
+if test "x$with_openldap" != "xno"; then
+   ac_fn_c_check_header_mongrel "$LINENO" "ldap.h" "ac_cv_header_ldap_h" "$ac_includes_default"
+if test "x$ac_cv_header_ldap_h" = xyes; then :
+
+else
+  as_fn_error $? "ldap.h not found (openldap-dev, openldap-devel)" "$LINENO" 5
+fi
+
+
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ldap_initialize in -lldap" >&5
+$as_echo_n "checking for ldap_initialize in -lldap... " >&6; }
+if ${ac_cv_lib_ldap_ldap_initialize+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lldap  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char ldap_initialize ();
+int
+main ()
+{
+return ldap_initialize ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_ldap_ldap_initialize=yes
+else
+  ac_cv_lib_ldap_ldap_initialize=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_ldap_ldap_initialize" >&5
+$as_echo "$ac_cv_lib_ldap_ldap_initialize" >&6; }
+if test "x$ac_cv_lib_ldap_ldap_initialize" = xyes; then :
+  true
+else
+  { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "libldap not found
+See \`config.log' for more details" "$LINENO" 5; }
+fi
+
+
+$as_echo "#define HAVE_OPENLDAP 1" >>confdefs.h
+
+   have_openldap="yes"
+fi
+ if  test "$have_openldap" = "yes" ; then
+  WITH_OPENLDAP_TRUE=
+  WITH_OPENLDAP_FALSE='#'
+else
+  WITH_OPENLDAP_TRUE='#'
+  WITH_OPENLDAP_FALSE=
+fi
+
+
 # Checks for typedefs, structures, and compiler characteristics.
 #AC_HEADER_STDBOOL
 #AC_C_CONST
@@ -26156,6 +25669,10 @@ if test -z "${WITH_EVENTFD_TRUE}" && test -z "${WITH_EVENTFD_FALSE}"; then
   as_fn_error $? "conditional \"WITH_EVENTFD\" was never defined.
 Usually this means the macro was only invoked conditionally." "$LINENO" 5
 fi
+if test -z "${WITH_OPENLDAP_TRUE}" && test -z "${WITH_OPENLDAP_FALSE}"; then
+  as_fn_error $? "conditional \"WITH_OPENLDAP\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
 if test -z "${WITH_BUILD_TESTS_TRUE}" && test -z "${WITH_BUILD_TESTS_FALSE}"; then
   as_fn_error $? "conditional \"WITH_BUILD_TESTS\" was never defined.
 Usually this means the macro was only invoked conditionally." "$LINENO" 5
@@ -26557,7 +26074,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
 # report actual input values of CONFIG_FILES etc. instead of their
 # values after options handling.
 ac_log="
-This file was extended by ceph $as_me 10.0.5, which was
+This file was extended by ceph $as_me 10.1.0, which was
 generated by GNU Autoconf 2.69.  Invocation command line was
 
   CONFIG_FILES    = $CONFIG_FILES
@@ -26623,7 +26140,7 @@ _ACEOF
 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
 ac_cs_version="\\
-ceph config.status 10.0.5
+ceph config.status 10.1.0
 configured by $0, generated by GNU Autoconf 2.69,
   with options \\"\$ac_cs_config\\"
 
@@ -26757,7 +26274,6 @@ enable_shared='`$ECHO "$enable_shared" | $SED "$delay_single_quote_subst"`'
 enable_static='`$ECHO "$enable_static" | $SED "$delay_single_quote_subst"`'
 pic_mode='`$ECHO "$pic_mode" | $SED "$delay_single_quote_subst"`'
 enable_fast_install='`$ECHO "$enable_fast_install" | $SED "$delay_single_quote_subst"`'
-shared_archive_member_spec='`$ECHO "$shared_archive_member_spec" | $SED "$delay_single_quote_subst"`'
 SHELL='`$ECHO "$SHELL" | $SED "$delay_single_quote_subst"`'
 ECHO='`$ECHO "$ECHO" | $SED "$delay_single_quote_subst"`'
 PATH_SEPARATOR='`$ECHO "$PATH_SEPARATOR" | $SED "$delay_single_quote_subst"`'
@@ -26807,13 +26323,10 @@ compiler='`$ECHO "$compiler" | $SED "$delay_single_quote_subst"`'
 GCC='`$ECHO "$GCC" | $SED "$delay_single_quote_subst"`'
 lt_cv_sys_global_symbol_pipe='`$ECHO "$lt_cv_sys_global_symbol_pipe" | $SED "$delay_single_quote_subst"`'
 lt_cv_sys_global_symbol_to_cdecl='`$ECHO "$lt_cv_sys_global_symbol_to_cdecl" | $SED "$delay_single_quote_subst"`'
-lt_cv_sys_global_symbol_to_import='`$ECHO "$lt_cv_sys_global_symbol_to_import" | $SED "$delay_single_quote_subst"`'
 lt_cv_sys_global_symbol_to_c_name_address='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address" | $SED "$delay_single_quote_subst"`'
 lt_cv_sys_global_symbol_to_c_name_address_lib_prefix='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address_lib_prefix" | $SED "$delay_single_quote_subst"`'
-lt_cv_nm_interface='`$ECHO "$lt_cv_nm_interface" | $SED "$delay_single_quote_subst"`'
 nm_file_list_spec='`$ECHO "$nm_file_list_spec" | $SED "$delay_single_quote_subst"`'
 lt_sysroot='`$ECHO "$lt_sysroot" | $SED "$delay_single_quote_subst"`'
-lt_cv_truncate_bin='`$ECHO "$lt_cv_truncate_bin" | $SED "$delay_single_quote_subst"`'
 objdir='`$ECHO "$objdir" | $SED "$delay_single_quote_subst"`'
 MAGIC_CMD='`$ECHO "$MAGIC_CMD" | $SED "$delay_single_quote_subst"`'
 lt_prog_compiler_no_builtin_flag='`$ECHO "$lt_prog_compiler_no_builtin_flag" | $SED "$delay_single_quote_subst"`'
@@ -26878,8 +26391,7 @@ finish_cmds='`$ECHO "$finish_cmds" | $SED "$delay_single_quote_subst"`'
 finish_eval='`$ECHO "$finish_eval" | $SED "$delay_single_quote_subst"`'
 hardcode_into_libs='`$ECHO "$hardcode_into_libs" | $SED "$delay_single_quote_subst"`'
 sys_lib_search_path_spec='`$ECHO "$sys_lib_search_path_spec" | $SED "$delay_single_quote_subst"`'
-configure_time_dlsearch_path='`$ECHO "$configure_time_dlsearch_path" | $SED "$delay_single_quote_subst"`'
-configure_time_lt_sys_library_path='`$ECHO "$configure_time_lt_sys_library_path" | $SED "$delay_single_quote_subst"`'
+sys_lib_dlsearch_path_spec='`$ECHO "$sys_lib_dlsearch_path_spec" | $SED "$delay_single_quote_subst"`'
 hardcode_action='`$ECHO "$hardcode_action" | $SED "$delay_single_quote_subst"`'
 enable_dlopen='`$ECHO "$enable_dlopen" | $SED "$delay_single_quote_subst"`'
 enable_dlopen_self='`$ECHO "$enable_dlopen_self" | $SED "$delay_single_quote_subst"`'
@@ -26984,12 +26496,9 @@ CFLAGS \
 compiler \
 lt_cv_sys_global_symbol_pipe \
 lt_cv_sys_global_symbol_to_cdecl \
-lt_cv_sys_global_symbol_to_import \
 lt_cv_sys_global_symbol_to_c_name_address \
 lt_cv_sys_global_symbol_to_c_name_address_lib_prefix \
-lt_cv_nm_interface \
 nm_file_list_spec \
-lt_cv_truncate_bin \
 lt_prog_compiler_no_builtin_flag \
 lt_prog_compiler_pic \
 lt_prog_compiler_wl \
@@ -27055,7 +26564,7 @@ postdeps_CXX \
 compiler_lib_search_path_CXX; do
     case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in
     *[\\\\\\\`\\"\\\$]*)
-      eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$sed_quote_subst\\"\\\`\\\\\\"" ## exclude from sc_prohibit_nested_quotes
+      eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$sed_quote_subst\\"\\\`\\\\\\""
       ;;
     *)
       eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\""
@@ -27082,8 +26591,7 @@ postinstall_cmds \
 postuninstall_cmds \
 finish_cmds \
 sys_lib_search_path_spec \
-configure_time_dlsearch_path \
-configure_time_lt_sys_library_path \
+sys_lib_dlsearch_path_spec \
 reload_cmds_CXX \
 old_archive_cmds_CXX \
 old_archive_from_new_cmds_CXX \
@@ -27097,7 +26605,7 @@ prelink_cmds_CXX \
 postlink_cmds_CXX; do
     case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in
     *[\\\\\\\`\\"\\\$]*)
-      eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\"" ## exclude from sc_prohibit_nested_quotes
+      eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\""
       ;;
     *)
       eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\""
@@ -27106,16 +26614,19 @@ postlink_cmds_CXX; do
 done
 
 ac_aux_dir='$ac_aux_dir'
+xsi_shell='$xsi_shell'
+lt_shell_append='$lt_shell_append'
 
-# See if we are running on zsh, and set the options that allow our
+# See if we are running on zsh, and set the options which allow our
 # commands through without removal of \ escapes INIT.
-if test -n "\${ZSH_VERSION+set}"; then
+if test -n "\${ZSH_VERSION+set}" ; then
    setopt NO_GLOB_SUBST
 fi
 
 
     PACKAGE='$PACKAGE'
     VERSION='$VERSION'
+    TIMESTAMP='$TIMESTAMP'
     RM='$RM'
     ofile='$ofile'
 
@@ -27744,53 +27255,55 @@ $as_echo "$as_me: executing $ac_file commands" >&6;}
   case $ac_file$ac_mode in
     "libtool":C)
 
-    # See if we are running on zsh, and set the options that allow our
+    # See if we are running on zsh, and set the options which allow our
     # commands through without removal of \ escapes.
-    if test -n "${ZSH_VERSION+set}"; then
+    if test -n "${ZSH_VERSION+set}" ; then
       setopt NO_GLOB_SUBST
     fi
 
-    cfgfile=${ofile}T
+    cfgfile="${ofile}T"
     trap "$RM \"$cfgfile\"; exit 1" 1 2 15
     $RM "$cfgfile"
 
     cat <<_LT_EOF >> "$cfgfile"
 #! $SHELL
-# Generated automatically by $as_me ($PACKAGE) $VERSION
+
+# `$ECHO "$ofile" | sed 's%^.*/%%'` - Provide generalized library-building support services.
+# Generated automatically by $as_me ($PACKAGE$TIMESTAMP) $VERSION
 # Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
 # NOTE: Changes made to this file will be lost: look at ltmain.sh.
-
-# Provide generalized library-building support services.
-# Written by Gordon Matzigkeit, 1996
-
-# Copyright (C) 2014 Free Software Foundation, Inc.
-# This is free software; see the source for copying conditions.  There is NO
-# warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-
-# GNU Libtool is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of of the License, or
-# (at your option) any later version.
 #
-# As a special exception to the GNU General Public License, if you
-# distribute this file as part of a program or library that is built
-# using GNU Libtool, you may include this file under the  same
-# distribution terms that you use for the rest of that program.
+#   Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005,
+#                 2006, 2007, 2008, 2009, 2010, 2011 Free Software
+#                 Foundation, Inc.
+#   Written by Gordon Matzigkeit, 1996
+#
+#   This file is part of GNU Libtool.
 #
-# GNU Libtool is distributed in the hope that it will be useful, but
-# WITHOUT ANY WARRANTY; without even the implied warranty of
+# GNU Libtool is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2 of
+# the License, or (at your option) any later version.
+#
+# As a special exception to the GNU General Public License,
+# if you distribute this file as part of a program or library that
+# is built using GNU Libtool, you may include this file under the
+# same distribution terms that you use for the rest of that program.
+#
+# GNU Libtool is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 # GNU General Public License for more details.
 #
 # You should have received a copy of the GNU General Public License
-# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+# along with GNU Libtool; see the file COPYING.  If not, a copy
+# can be downloaded from http://www.gnu.org/licenses/gpl.html, or
+# obtained by writing to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 
 
 # The names of the tagged configurations supported by this script.
-available_tags='CXX '
-
-# Configured defaults for sys_lib_dlsearch_path munging.
-: \${LT_SYS_LIBRARY_PATH="$configure_time_lt_sys_library_path"}
+available_tags="CXX "
 
 # ### BEGIN LIBTOOL CONFIG
 
@@ -27810,9 +27323,6 @@ pic_mode=$pic_mode
 # Whether or not to optimize for fast installation.
 fast_install=$enable_fast_install
 
-# Shared archive member basename,for filename based shared library versioning on AIX.
-shared_archive_member_spec=$shared_archive_member_spec
-
 # Shell to use when invoking shell scripts.
 SHELL=$lt_SHELL
 
@@ -27930,27 +27440,18 @@ global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe
 # Transform the output of nm in a proper C declaration.
 global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl
 
-# Transform the output of nm into a list of symbols to manually relocate.
-global_symbol_to_import=$lt_lt_cv_sys_global_symbol_to_import
-
 # Transform the output of nm in a C name address pair.
 global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address
 
 # Transform the output of nm in a C name address pair when lib prefix is needed.
 global_symbol_to_c_name_address_lib_prefix=$lt_lt_cv_sys_global_symbol_to_c_name_address_lib_prefix
 
-# The name lister interface.
-nm_interface=$lt_lt_cv_nm_interface
-
 # Specify filename containing input files for \$NM.
 nm_file_list_spec=$lt_nm_file_list_spec
 
-# The root where to search for dependent libraries,and where our libraries should be installed.
+# The root where to search for dependent libraries,and in which our libraries should be installed.
 lt_sysroot=$lt_sysroot
 
-# Command to truncate a binary pipe.
-lt_truncate_bin=$lt_lt_cv_truncate_bin
-
 # The name of the directory that contains temporary libtool files.
 objdir=$objdir
 
@@ -28041,11 +27542,8 @@ hardcode_into_libs=$hardcode_into_libs
 # Compile-time system search path for libraries.
 sys_lib_search_path_spec=$lt_sys_lib_search_path_spec
 
-# Detected run-time system search path for libraries.
-sys_lib_dlsearch_path_spec=$lt_configure_time_dlsearch_path
-
-# Explicit LT_SYS_LIBRARY_PATH set during ./configure time.
-configure_time_lt_sys_library_path=$lt_configure_time_lt_sys_library_path
+# Run-time system search path for libraries.
+sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec
 
 # Whether dlopen is supported.
 dlopen_support=$enable_dlopen
@@ -28138,13 +27636,13 @@ hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec
 # Whether we need a single "-rpath" flag with a separated argument.
 hardcode_libdir_separator=$lt_hardcode_libdir_separator
 
-# Set to "yes" if using DIR/libNAME\$shared_ext during linking hardcodes
+# Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes
 # DIR into the resulting binary.
 hardcode_direct=$hardcode_direct
 
-# Set to "yes" if using DIR/libNAME\$shared_ext during linking hardcodes
+# Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes
 # DIR into the resulting binary and the resulting library dependency is
-# "absolute",i.e impossible to change by setting \$shlibpath_var if the
+# "absolute",i.e impossible to change by setting \${shlibpath_var} if the
 # library is relocated.
 hardcode_direct_absolute=$hardcode_direct_absolute
 
@@ -28210,72 +27708,13 @@ compiler_lib_search_path=$lt_compiler_lib_search_path
 
 _LT_EOF
 
-    cat <<'_LT_EOF' >> "$cfgfile"
-
-# ### BEGIN FUNCTIONS SHARED WITH CONFIGURE
-
-# func_munge_path_list VARIABLE PATH
-# -----------------------------------
-# VARIABLE is name of variable containing _space_ separated list of
-# directories to be munged by the contents of PATH, which is string
-# having a format:
-# "DIR[:DIR]:"
-#       string "DIR[ DIR]" will be prepended to VARIABLE
-# ":DIR[:DIR]"
-#       string "DIR[ DIR]" will be appended to VARIABLE
-# "DIRP[:DIRP]::[DIRA:]DIRA"
-#       string "DIRP[ DIRP]" will be prepended to VARIABLE and string
-#       "DIRA[ DIRA]" will be appended to VARIABLE
-# "DIR[:DIR]"
-#       VARIABLE will be replaced by "DIR[ DIR]"
-func_munge_path_list ()
-{
-    case x$2 in
-    x)
-        ;;
-    *:)
-        eval $1=\"`$ECHO $2 | $SED 's/:/ /g'` \$$1\"
-        ;;
-    x:*)
-        eval $1=\"\$$1 `$ECHO $2 | $SED 's/:/ /g'`\"
-        ;;
-    *::*)
-        eval $1=\"\$$1\ `$ECHO $2 | $SED -e 's/.*:://' -e 's/:/ /g'`\"
-        eval $1=\"`$ECHO $2 | $SED -e 's/::.*//' -e 's/:/ /g'`\ \$$1\"
-        ;;
-    *)
-        eval $1=\"`$ECHO $2 | $SED 's/:/ /g'`\"
-        ;;
-    esac
-}
-
-
-# Calculate cc_basename.  Skip known compiler wrappers and cross-prefix.
-func_cc_basename ()
-{
-    for cc_temp in $*""; do
-      case $cc_temp in
-        compile | *[\\/]compile | ccache | *[\\/]ccache ) ;;
-        distcc | *[\\/]distcc | purify | *[\\/]purify ) ;;
-        \-*) ;;
-        *) break;;
-      esac
-    done
-    func_cc_basename_result=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"`
-}
-
-
-# ### END FUNCTIONS SHARED WITH CONFIGURE
-
-_LT_EOF
-
   case $host_os in
   aix3*)
     cat <<\_LT_EOF >> "$cfgfile"
 # AIX sometimes has problems with the GCC collect2 program.  For some
 # reason, if we set the COLLECT_NAMES environment variable, the problems
 # vanish in a puff of smoke.
-if test set != "${COLLECT_NAMES+set}"; then
+if test "X${COLLECT_NAMES+set}" != Xset; then
   COLLECT_NAMES=
   export COLLECT_NAMES
 fi
@@ -28284,7 +27723,7 @@ _LT_EOF
   esac
 
 
-ltmain=$ac_aux_dir/ltmain.sh
+ltmain="$ac_aux_dir/ltmain.sh"
 
 
   # We use sed instead of cat because bash on DJGPP gets confused if
@@ -28294,6 +27733,165 @@ ltmain=$ac_aux_dir/ltmain.sh
   sed '$q' "$ltmain" >> "$cfgfile" \
      || (rm -f "$cfgfile"; exit 1)
 
+  if test x"$xsi_shell" = xyes; then
+  sed -e '/^func_dirname ()$/,/^} # func_dirname /c\
+func_dirname ()\
+{\
+\    case ${1} in\
+\      */*) func_dirname_result="${1%/*}${2}" ;;\
+\      *  ) func_dirname_result="${3}" ;;\
+\    esac\
+} # Extended-shell func_dirname implementation' "$cfgfile" > $cfgfile.tmp \
+  && mv -f "$cfgfile.tmp" "$cfgfile" \
+    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+  sed -e '/^func_basename ()$/,/^} # func_basename /c\
+func_basename ()\
+{\
+\    func_basename_result="${1##*/}"\
+} # Extended-shell func_basename implementation' "$cfgfile" > $cfgfile.tmp \
+  && mv -f "$cfgfile.tmp" "$cfgfile" \
+    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+  sed -e '/^func_dirname_and_basename ()$/,/^} # func_dirname_and_basename /c\
+func_dirname_and_basename ()\
+{\
+\    case ${1} in\
+\      */*) func_dirname_result="${1%/*}${2}" ;;\
+\      *  ) func_dirname_result="${3}" ;;\
+\    esac\
+\    func_basename_result="${1##*/}"\
+} # Extended-shell func_dirname_and_basename implementation' "$cfgfile" > $cfgfile.tmp \
+  && mv -f "$cfgfile.tmp" "$cfgfile" \
+    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+  sed -e '/^func_stripname ()$/,/^} # func_stripname /c\
+func_stripname ()\
+{\
+\    # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are\
+\    # positional parameters, so assign one to ordinary parameter first.\
+\    func_stripname_result=${3}\
+\    func_stripname_result=${func_stripname_result#"${1}"}\
+\    func_stripname_result=${func_stripname_result%"${2}"}\
+} # Extended-shell func_stripname implementation' "$cfgfile" > $cfgfile.tmp \
+  && mv -f "$cfgfile.tmp" "$cfgfile" \
+    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+  sed -e '/^func_split_long_opt ()$/,/^} # func_split_long_opt /c\
+func_split_long_opt ()\
+{\
+\    func_split_long_opt_name=${1%%=*}\
+\    func_split_long_opt_arg=${1#*=}\
+} # Extended-shell func_split_long_opt implementation' "$cfgfile" > $cfgfile.tmp \
+  && mv -f "$cfgfile.tmp" "$cfgfile" \
+    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+  sed -e '/^func_split_short_opt ()$/,/^} # func_split_short_opt /c\
+func_split_short_opt ()\
+{\
+\    func_split_short_opt_arg=${1#??}\
+\    func_split_short_opt_name=${1%"$func_split_short_opt_arg"}\
+} # Extended-shell func_split_short_opt implementation' "$cfgfile" > $cfgfile.tmp \
+  && mv -f "$cfgfile.tmp" "$cfgfile" \
+    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+  sed -e '/^func_lo2o ()$/,/^} # func_lo2o /c\
+func_lo2o ()\
+{\
+\    case ${1} in\
+\      *.lo) func_lo2o_result=${1%.lo}.${objext} ;;\
+\      *)    func_lo2o_result=${1} ;;\
+\    esac\
+} # Extended-shell func_lo2o implementation' "$cfgfile" > $cfgfile.tmp \
+  && mv -f "$cfgfile.tmp" "$cfgfile" \
+    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+  sed -e '/^func_xform ()$/,/^} # func_xform /c\
+func_xform ()\
+{\
+    func_xform_result=${1%.*}.lo\
+} # Extended-shell func_xform implementation' "$cfgfile" > $cfgfile.tmp \
+  && mv -f "$cfgfile.tmp" "$cfgfile" \
+    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+  sed -e '/^func_arith ()$/,/^} # func_arith /c\
+func_arith ()\
+{\
+    func_arith_result=$(( $* ))\
+} # Extended-shell func_arith implementation' "$cfgfile" > $cfgfile.tmp \
+  && mv -f "$cfgfile.tmp" "$cfgfile" \
+    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+  sed -e '/^func_len ()$/,/^} # func_len /c\
+func_len ()\
+{\
+    func_len_result=${#1}\
+} # Extended-shell func_len implementation' "$cfgfile" > $cfgfile.tmp \
+  && mv -f "$cfgfile.tmp" "$cfgfile" \
+    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+fi
+
+if test x"$lt_shell_append" = xyes; then
+  sed -e '/^func_append ()$/,/^} # func_append /c\
+func_append ()\
+{\
+    eval "${1}+=\\${2}"\
+} # Extended-shell func_append implementation' "$cfgfile" > $cfgfile.tmp \
+  && mv -f "$cfgfile.tmp" "$cfgfile" \
+    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+  sed -e '/^func_append_quoted ()$/,/^} # func_append_quoted /c\
+func_append_quoted ()\
+{\
+\    func_quote_for_eval "${2}"\
+\    eval "${1}+=\\\\ \\$func_quote_for_eval_result"\
+} # Extended-shell func_append_quoted implementation' "$cfgfile" > $cfgfile.tmp \
+  && mv -f "$cfgfile.tmp" "$cfgfile" \
+    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+  # Save a `func_append' function call where possible by direct use of '+='
+  sed -e 's%func_append \([a-zA-Z_]\{1,\}\) "%\1+="%g' $cfgfile > $cfgfile.tmp \
+    && mv -f "$cfgfile.tmp" "$cfgfile" \
+      || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+  test 0 -eq $? || _lt_function_replace_fail=:
+else
+  # Save a `func_append' function call even when '+=' is not available
+  sed -e 's%func_append \([a-zA-Z_]\{1,\}\) "%\1="$\1%g' $cfgfile > $cfgfile.tmp \
+    && mv -f "$cfgfile.tmp" "$cfgfile" \
+      || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+  test 0 -eq $? || _lt_function_replace_fail=:
+fi
+
+if test x"$_lt_function_replace_fail" = x":"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Unable to substitute extended shell functions in $ofile" >&5
+$as_echo "$as_me: WARNING: Unable to substitute extended shell functions in $ofile" >&2;}
+fi
+
+
    mv -f "$cfgfile" "$ofile" ||
     (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile")
   chmod +x "$ofile"
@@ -28380,13 +27978,13 @@ hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec_CXX
 # Whether we need a single "-rpath" flag with a separated argument.
 hardcode_libdir_separator=$lt_hardcode_libdir_separator_CXX
 
-# Set to "yes" if using DIR/libNAME\$shared_ext during linking hardcodes
+# Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes
 # DIR into the resulting binary.
 hardcode_direct=$hardcode_direct_CXX
 
-# Set to "yes" if using DIR/libNAME\$shared_ext during linking hardcodes
+# Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes
 # DIR into the resulting binary and the resulting library dependency is
-# "absolute",i.e impossible to change by setting \$shlibpath_var if the
+# "absolute",i.e impossible to change by setting \${shlibpath_var} if the
 # library is relocated.
 hardcode_direct_absolute=$hardcode_direct_absolute_CXX
 
diff --git a/configure.ac b/configure.ac
index be669b5..4db6d55 100644
--- a/configure.ac
+++ b/configure.ac
@@ -8,7 +8,7 @@ AC_PREREQ(2.59)
 # VERSION define is not used by the code.  It gets a version string
 # from 'git describe'; see src/ceph_ver.[ch]
 
-AC_INIT([ceph], [10.0.5], [ceph-devel at vger.kernel.org])
+AC_INIT([ceph], [10.1.0], [ceph-devel at vger.kernel.org])
 
 AX_CXX_COMPILE_STDCXX_11(, mandatory)
 
@@ -126,7 +126,7 @@ AM_CONDITIONAL(WITH_RBD, test "$with_rbd" = "yes")
 #AS_IF([test "$with_rbd" = "yes"], [AC_DEFINE([WITH_RADOS, WITH_RBD])])
 
 AC_ARG_WITH([cython],
-	[AS_HELP_STRING([--with-cython], [build python bindings for librbd])],
+	[AS_HELP_STRING([--with-cython], [build python bindings for libraries])],
 	[],
 	[with_cython=yes])
 AM_CONDITIONAL(WITH_CYTHON, test "$with_cython" = "yes")
@@ -207,12 +207,20 @@ AC_ARG_ENABLE([server],
 AM_CONDITIONAL(ENABLE_SERVER, test "$enable_server" = "yes")
 #AS_IF([test "$enable_server" = "yes"], [AC_DEFINE([WITH_MON, WITH_OSD, WITH_MDS, ENABLE_SERVER])])
 
-# cython is required to build librbd python bindings
+# cython is required to build python bindings for libraries
 if test x"$with_cython" = xyes; then
     AC_CHECK_PROG(CYTHON_CHECK, cython, yes)
     if test x"$CYTHON_CHECK" != xyes; then
         AC_MSG_FAILURE([cython not found])
     fi
+    AC_CHECK_PROG(PYTHON_CONFIG_CHECK, python-config, yes)
+    if test x"$PYTHON_CONFIG_CHECK" != xyes; then
+        AC_MSG_FAILURE([python-config not found])
+    fi
+    PYTHON_CFLAGS=`python-config --cflags`
+    AC_SUBST(PYTHON_CFLAGS)
+    PYTHON_LDFLAGS=`python-config --ldflags`
+    AC_SUBST(PYTHON_LDFLAGS)
 fi
 
 # cond-check if snappy-devel is installed, needed by leveldb that is need by server parts of the project
@@ -915,6 +923,9 @@ AC_CHECK_HEADER([boost/random/discrete_distribution.hpp],
 	[AC_DEFINE([HAVE_BOOST_RANDOM_DISCRETE_DISTRIBUTION], [], [have boost::random::discrete_distribution])],
 	[])
 
+AC_CHECK_HEADER([boost/asio/coroutine.hpp],
+	[AC_DEFINE([HAVE_BOOST_ASIO_COROUTINE], [], [have boost::asio::coroutine])],
+	[])
 AC_CHECK_HEADER([boost/statechart/state.hpp], [],
     AC_MSG_FAILURE(["Can't find boost statechart headers; need 1.34 or later"]))
 AC_CHECK_HEADER([boost/regex.hpp], [],
@@ -930,7 +941,7 @@ AC_CHECK_LIB(boost_system-mt, main, [],
 
 AC_CHECK_LIB(boost_iostreams-mt, main, [],
     [AC_CHECK_LIB(boost_iostreams, main, [],
-        AC_MSG_NOTICE(["Boost iostreams library not found."]))])
+        AC_MSG_FAILURE(["Boost iostreams library not found."]))])
 
 # Find the right boost_thread library.
 BOOST_THREAD_LIBS=""
@@ -1073,6 +1084,7 @@ AC_CHECK_HEADERS([sys/prctl.h])
 AC_CHECK_FUNCS([prctl])
 AC_CHECK_FUNCS([pipe2])
 AC_CHECK_FUNCS([posix_fadvise])
+AC_CHECK_FUNCS([pwritev], AC_DEFINE([HAVE_PWRITEV], [1], [we have pwritev]))
 
 AC_MSG_CHECKING([for fdatasync])
 AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
@@ -1267,6 +1279,19 @@ AS_IF([test "x$with_eventfd" != xno],
                      [AC_DEFINE(HAVE_EVENTFD, 1, [Have eventfd extension.])])])
 AM_CONDITIONAL(WITH_EVENTFD, [ test "$with_eventfd" = "yes" ])
 
+# disable OpenLDAP support
+AC_ARG_WITH([openldap],
+            [AS_HELP_STRING([--without-openldap], [Disable OpenLDAP support (RGW)])])
+if test "x$with_openldap" != "xno"; then
+   AC_CHECK_HEADER([ldap.h], [],
+      AC_MSG_ERROR([ldap.h not found (openldap-dev, openldap-devel)]))
+    AC_CHECK_LIB([ldap], [ldap_initialize], [true],
+      AC_MSG_FAILURE([libldap not found]))
+   AC_DEFINE([HAVE_OPENLDAP], [1], [Defined if OpenLDAP enabled])
+   have_openldap="yes"
+fi
+AM_CONDITIONAL(WITH_OPENLDAP, [ test "$have_openldap" = "yes" ])
+
 # Checks for typedefs, structures, and compiler characteristics.
 #AC_HEADER_STDBOOL
 #AC_C_CONST
diff --git a/depcomp b/depcomp
index fc98710..4ebd5b3 100755
--- a/depcomp
+++ b/depcomp
@@ -3,7 +3,7 @@
 
 scriptversion=2013-05-30.07; # UTC
 
-# Copyright (C) 1999-2014 Free Software Foundation, Inc.
+# Copyright (C) 1999-2013 Free Software Foundation, Inc.
 
 # This program is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
diff --git a/doc/Makefile.am b/doc/Makefile.am
index 332b323..75c0ce7 100644
--- a/doc/Makefile.am
+++ b/doc/Makefile.am
@@ -6,6 +6,7 @@ EXTRA_DIST = \
 	man/8/ceph-debugpack.rst	\
 	man/8/ceph-dencoder.rst	\
 	man/8/ceph-deploy.rst	\
+	man/8/ceph-detect-init.rst	\
 	man/8/ceph-disk.rst	\
 	man/8/cephfs.rst	\
 	man/8/ceph-fuse.rst	\
diff --git a/doc/Makefile.in b/doc/Makefile.in
index e55b78b..25b773c 100644
--- a/doc/Makefile.in
+++ b/doc/Makefile.in
@@ -1,7 +1,7 @@
-# Makefile.in generated by automake 1.15 from Makefile.am.
+# Makefile.in generated by automake 1.14.1 from Makefile.am.
 # @configure_input@
 
-# Copyright (C) 1994-2014 Free Software Foundation, Inc.
+# Copyright (C) 1994-2013 Free Software Foundation, Inc.
 
 # This Makefile.in is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -14,17 +14,7 @@
 
 @SET_MAKE@
 VPATH = @srcdir@
-am__is_gnu_make = { \
-  if test -z '$(MAKELEVEL)'; then \
-    false; \
-  elif test -n '$(MAKE_HOST)'; then \
-    true; \
-  elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
-    true; \
-  else \
-    false; \
-  fi; \
-}
+am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
 am__make_running_with_option = \
   case $${target_option-} in \
       ?) ;; \
@@ -89,6 +79,7 @@ build_triplet = @build@
 host_triplet = @host@
 target_triplet = @target@
 subdir = doc
+DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
 am__aclocal_m4_deps = $(top_srcdir)/m4/ac_check_classpath.m4 \
 	$(top_srcdir)/m4/ac_prog_jar.m4 \
@@ -107,7 +98,6 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/ac_check_classpath.m4 \
 	$(top_srcdir)/m4/pkg.m4 $(top_srcdir)/configure.ac
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
 	$(ACLOCAL_M4)
-DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON)
 mkinstalldirs = $(install_sh) -d
 CONFIG_HEADER = $(top_builddir)/src/acconfig.h
 CONFIG_CLEAN_FILES =
@@ -132,7 +122,6 @@ am__can_run_installinfo = \
     *) (install-info --version) >/dev/null 2>&1;; \
   esac
 am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
-am__DIST_COMMON = $(srcdir)/Makefile.in
 DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
 ACLOCAL = @ACLOCAL@
 AMTAR = @AMTAR@
@@ -225,7 +214,6 @@ LN_S = @LN_S@
 LTLIBOBJS = @LTLIBOBJS@
 LTTNG_GEN_TP_CHECK = @LTTNG_GEN_TP_CHECK@
 LTTNG_GEN_TP_PROG = @LTTNG_GEN_TP_PROG@
-LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
 MAKEINFO = @MAKEINFO@
 MANIFEST_TOOL = @MANIFEST_TOOL@
 MKDIR_P = @MKDIR_P@
@@ -252,7 +240,10 @@ PTHREAD_CC = @PTHREAD_CC@
 PTHREAD_CFLAGS = @PTHREAD_CFLAGS@
 PTHREAD_LIBS = @PTHREAD_LIBS@
 PYTHON = @PYTHON@
+PYTHON_CFLAGS = @PYTHON_CFLAGS@
+PYTHON_CONFIG_CHECK = @PYTHON_CONFIG_CHECK@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
+PYTHON_LDFLAGS = @PYTHON_LDFLAGS@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
 PYTHON_PREFIX = @PYTHON_PREFIX@
 PYTHON_VERSION = @PYTHON_VERSION@
@@ -321,7 +312,6 @@ program_transform_name = @program_transform_name@
 psdir = @psdir@
 pyexecdir = @pyexecdir@
 pythondir = @pythondir@
-runstatedir = @runstatedir@
 sbindir = @sbindir@
 sharedstatedir = @sharedstatedir@
 srcdir = @srcdir@
@@ -344,6 +334,7 @@ EXTRA_DIST = \
 	man/8/ceph-debugpack.rst	\
 	man/8/ceph-dencoder.rst	\
 	man/8/ceph-deploy.rst	\
+	man/8/ceph-detect-init.rst	\
 	man/8/ceph-disk.rst	\
 	man/8/cephfs.rst	\
 	man/8/ceph-fuse.rst	\
@@ -387,6 +378,7 @@ $(srcdir)/Makefile.in:  $(srcdir)/Makefile.am  $(am__configure_deps)
 	echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign doc/Makefile'; \
 	$(am__cd) $(top_srcdir) && \
 	  $(AUTOMAKE) --foreign doc/Makefile
+.PRECIOUS: Makefile
 Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
 	@case '$?' in \
 	  *config.status*) \
@@ -561,8 +553,6 @@ uninstall-am:
 	mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
 	tags-am uninstall uninstall-am
 
-.PRECIOUS: Makefile
-
 
 # Tell versions [3.59,3.63) of GNU make to not export all variables.
 # Otherwise a system limit (for SysV at least) may be exceeded.
diff --git a/doc/man/8/ceph-detect-init.rst b/doc/man/8/ceph-detect-init.rst
new file mode 100644
index 0000000..aeb3316
--- /dev/null
+++ b/doc/man/8/ceph-detect-init.rst
@@ -0,0 +1,54 @@
+:orphan:
+
+============================================================
+ ceph-detect-init -- display the init system Ceph should use
+============================================================
+
+.. program:: ceph-detect-init
+
+Synopsis
+========
+
+| **ceph-detect-init** [--verbose] [--use-rhceph] [--default *init*]
+
+Description
+===========
+
+:program:`ceph-detect-init` is a utility that prints the init system
+Ceph uses. It can be one of ``sysvinit``, ``upstart`` or ``systemd``.
+The init system Ceph uses may not be the default init system of the
+host operating system. For instance on Debian Jessie, Ceph may use
+``sysvinit`` although ``systemd`` is the default.
+
+If the init system of the host operating system is unknown, return on
+error, unless :option:`--default` is specified.
+
+Options
+=======
+
+.. option:: --use-rhceph
+
+   When an operating system identifies itself as Red Hat, it is
+   treated as if it was CentOS. With :option:`--use-rhceph` it is
+   treated as RHEL instead.
+
+.. option:: --default INIT
+
+   If the init system of the host operating system is unkown, return
+   the value of *INIT* instead of failing with an error.
+
+.. option:: --verbose
+
+   Display additional information for debugging.
+
+Availability
+============
+
+:program:`ceph-detect-init` is part of Ceph, a massively scalable, open-source, distributed storage system. Please refer to
+the Ceph documentation at http://ceph.com/docs for more information.
+
+See also
+========
+
+:doc:`ceph-disk <ceph-disk>`\(8),
+:doc:`ceph-deploy <ceph-deploy>`\(8)
diff --git a/doc/man/8/ceph-disk.rst b/doc/man/8/ceph-disk.rst
index 8313f5c..2ec3d2b 100644
--- a/doc/man/8/ceph-disk.rst
+++ b/doc/man/8/ceph-disk.rst
@@ -9,22 +9,37 @@
 Synopsis
 ========
 
-| **ceph-disk** **prepare** [--cluster *clustername*] [--cluster-uuid *uuid*]
-	[--fs-type *xfs|ext4|btrfs*] [*data-path*] [*journal-path*]
-
-| **ceph-disk** **activate** [*data-path*] [--activate-key *path*]
-        [--mark-init *sysvinit|upstart|systemd|auto|none*]
-        [--no-start-daemon] [--reactivate]
-
-| **ceph-disk** **activate-all**
-
-| **ceph-disk** **list**
-
-| **ceph-disk** **deactivate** [--cluster *clustername*] [*device-path*]
-        [--deactivate-by-id *id*] [--mark-out]
-
-| **ceph-disk** **destroy** [--cluster *clustername*] [*device-path*]
-        [--destroy-by-id *id*] [--dmcrypt-key-dir *KEYDIR*] [--zap]
+| **ceph-disk** [-h] [-v] [--log-stdout] [--prepend-to-path PATH]
+                [--statedir PATH] [--sysconfdir PATH]
+                [--setuser USER] [--setgroup GROUP]
+                ...
+
+| optional arguments:
+  -h, --help            show this help message and exit
+  -v, --verbose         be more verbose
+  --log-stdout          log to stdout
+  --prepend-to-path PATH
+                        prepend PATH to $PATH for backward compatibility (default /usr/bin)
+  --statedir PATH       directory in which ceph state is preserved (default /var/lib/ceph)
+  --sysconfdir PATH     directory in which ceph configuration files are found (default /etc/ceph)
+  --setuser USER        use the given user for subprocesses, rather than ceph or root
+  --setgroup GROUP      use the given group for subprocesses, rather than ceph or root
+
+| subcommands:
+
+    prepare              Prepare a directory or disk for a Ceph OSD
+    activate             Activate a Ceph OSD
+    activate-lockbox     Activate a Ceph lockbox
+    activate-block       Activate an OSD via its block device
+    activate-journal     Activate an OSD via its journal device
+    activate-all         Activate all tagged OSD partitions
+    list                 List disks, partitions, and Ceph OSDs
+    suppress-activate    Suppress activate on a device (prefix)
+    unsuppress-activate  Stop suppressing activate on a device (prefix)
+    deactivate           Deactivate a Ceph OSD
+    destroy              Destroy a Ceph OSD
+    zap                  Zap/erase/destroy a device's partition table (and contents)
+    trigger              Trigger an event (caled by udev)
 
 Description
 ===========
@@ -42,286 +57,8 @@ subcommands ``prepare`` and ``activate``.
 and destroy an OSD into two steps of deactivating and destroying the OSD by using
 the subcommands ``deactivate`` and ``destroy``.
 
-Subcommands
-============
-
-prepare
---------
-
-Prepare a directory, disk for a Ceph OSD. It creates a GPT partition,
-marks the partition with Ceph type ``uuid``, creates a file system, marks the
-file system as ready for Ceph consumption, uses entire partition and adds a new
-partition to the journal disk. It is run directly or triggered by
-:program:`ceph-deploy`.
-
-Usage::
-
-	ceph-disk prepare --cluster [cluster-name] --cluster-uuid [uuid] --fs-type
-	[ext4|xfs|btrfs] [data-path] [journal-path]
-
-Other options like :option:`--osd-uuid`, :option:`--journal-uuid`,
-:option:`--zap-disk`, :option:`--data-dir`, :option:`--data-dev`,
-:option:`--journal-file`, :option:`--journal-dev`, :option:`--dmcrypt`
-and :option:`--dmcrypt-key-dir` can also be used with the subcommand.
-
-activate
---------
-
-Activate the Ceph OSD. It mounts the volume in a temporary location, allocates
-an OSD id (if needed), remounts in the correct location
-``/var/lib/ceph/osd/$cluster-$id`` and starts ceph-osd. It is triggered by
-``udev`` when it sees the OSD GPT partition type or on ceph service start with
-``ceph disk activate-all``. It is also run directly or triggered by
-:program:`ceph-deploy`.
-
-Usage::
-
-	ceph-disk activate [PATH]
-
-Here, [PATH] is path to a block device or a directory.
-
-An additional option :option:`--activate-key` has to be used with this
-subcommand when a copy of ``/var/lib/ceph/bootstrap-osd/{cluster}.keyring``
-isn't present in the OSD node.
-
-Usage::
-
-	ceph-disk activate [PATH] [--activate-key PATH]
-
-Another option :option:`--mark-init` can also be used with this
-subcommand.  ``--mark-init`` provides init system to manage the OSD
-directory. It defaults to ``auto`` which detects the init system
-suitable for ceph (either ``sysvinit``, ``systemd`` or
-``upstart``). The argument can be used to override the init system. It
-may be convenient when an operating system supports multiple init
-systems, such as Debian GNU/Linux jessie with ``systemd`` and
-``sysvinit``. If the argument is ``none``, the OSD is not marked with
-any init system and ``ceph-disk activate`` needs to be called
-explicitely after each reboot.
-
-
-Usage::
-
-	ceph-disk activate [PATH] [--mark-init *sysvinit|upstart|systemd|auto|none*]
-
-If the option :option:`--no-start-daemon` is given, the activation
-steps are performed but the OSD daemon is not started.
-
-The latest option :option:`--reactivate` can re-activate the OSD which has been
-deactivated with the ``deactivate`` subcommand.
-
-Usage::
-
-	ceph-disk activate [PATH] [--reactivate]
-
-activate-journal
-----------------
-
-Activate an OSD via it's journal device. ``udev`` triggers
-``ceph-disk activate-journal <dev>`` based on the partition type.
-
-Usage::
-
-	ceph-disk activate-journal [DEV]
-
-Here, [DEV] is the path to a journal block device.
-
-Others options like :option:`--activate-key` and :option:`--mark-init` can also
-be used with this subcommand.
-
-``--mark-init`` provides init system to manage the OSD directory.
-
-Usage::
-
-	ceph-disk activate-journal [--activate-key PATH] [--mark-init INITSYSTEM] [DEV]
-
-activate-all
-------------
-
-Activate all tagged OSD partitions. ``activate-all`` relies on
-``/dev/disk/by-parttype-uuid/$typeuuid.$uuid`` to find all partitions. Special
-``udev`` rules are installed to create these links. It is triggered on ceph
-service start or run directly.
-
-Usage::
-
-	ceph-disk activate-all
-
-Others options like :option:`--activate-key` and :option:`--mark-init` can
-also be used with this subcommand.
-
-``--mark-init`` provides init system to manage the OSD directory.
-
-Usage::
-
-	ceph-disk activate-all [--activate-key PATH] [--mark-init INITSYSTEM]
-
-list
-----
-
-List disk partitions and Ceph OSDs. It is run directly or triggered by
-:program:`ceph-deploy`.
-
-Usage::
-
-	ceph-disk list
-
-suppress-activate
------------------
-
-Suppress activate on a device (prefix). Mark devices that you don't want to
-activate with a file like ``/var/lib/ceph/tmp/suppress-activate.sdb`` where the
-last bit is the sanitized device name (/dev/X without the /dev/ prefix). A
-function ``is_suppressed()`` checks for and  matches a prefix (/dev/). It means
-suppressing sdb will stop activate on sdb1, sdb2, etc.
-
-Usage::
-
-	ceph-disk suppress-activate [PATH]
-
-Here, [PATH] is path to a block device or a directory.
-
-unsuppress-activate
--------------------
-
-Stop suppressing activate on a device (prefix). It is used to activate a device
-that was earlier kept deactivated using ``suppress-activate``.
-
-Usage::
-
-	ceph-disk unsuppress-activate [PATH]
-
-Here, [PATH] is path to a block device or a directory.
-
-deactivate
-----------
-Deactivate the Ceph OSD. It stops OSD daemon and optionally marks it out. The
-content of the OSD is left untouched but the *ready*, *active*, *INIT-specific*
-files are removed (so that it is not automatically re-activated by the ``udev``
-rules) and the file deactive is created to remember the OSD is deactivated.
-If the OSD is dmcrypt, remove the data dmcrypt map. When deactivate finishes,
-the OSD is ``down``. A deactivated OSD can later be re-activated using the
-:option:`--reactivate` option of the ``activate`` subcommand.
-
-Usage::
-
-	ceph-disk deactivate [PATH]
-
-Here, [PATH] is a path to a block device or a directory.
-
-Another option :option:`--mark-out` can also be used with this subcommand.
-``--mark-out`` marks the OSD out. The objects it contains will be remapped.
-If you are not sure you will destroy OSD, do not use this option.
-
-You can also use ``osd-id`` to deactivate an OSD with the option :option:`--deactivate-by-id`.
-
-Usage::
-
-	ceph-disk deactivate --deactivate-by-id [OSD-ID]
-
-destroy
--------
-Destroy the Ceph OSD. It removes the OSD from the cluster, the crushmap and
-deallocates OSD ID. It can only destroy an OSD which is *down*.
-
-Usage::
-
-	ceph-disk destroy [PATH]
-
-Here, [PATH] is a path to a block device or a directory.
-
-Another option :option:`--zap` can also be used with this subcommand.
-``--zap`` will destroy the partition table and content of the disk.
-
-Usage::
-
-	ceph-disk destroy [PATH] [--zap]
-
-You can also use the id of an OSD instead of the path with the option
-:option:`--destroy-by-id`.
-
-Usage::
-
-	ceph-disk destroy --destroy-by-id [OSD-ID]
-
-zap
----
-
-Zap/erase/destroy a device's partition table and contents. It actually uses
-``sgdisk`` and it's option ``--zap-all`` to destroy both GPT and MBR data
-structures so that the disk becomes suitable for repartitioning. ``sgdisk``
-then uses ``--mbrtogpt`` to convert the MBR or BSD disklabel disk to a GPT
-disk. The ``prepare`` subcommand can now be executed which will create a new
-GPT partition. It is also run directly or triggered by :program:`ceph-deploy`.
-
-Usage::
-
-	ceph-disk zap [DEV]
-
-Here, [DEV] is path to a block device.
-
-Options
-=======
-
-.. option:: --prepend-to-path PATH
-
-   Prepend PATH to $PATH for backward compatibility (default ``/usr/bin``).
-
-.. option:: --statedir PATH
-
-   Directory in which ceph configuration is preserved (default ``/usr/lib/ceph``).
-
-.. option:: --sysconfdir PATH
-
-   Directory in which ceph configuration files are found (default ``/etc/ceph``).
-
-.. option:: --cluster
-
-   Provide name of the ceph cluster in which the OSD is being prepared.
-
-.. option:: --cluster-uuid
-
-   Provide uuid of the ceph cluster in which the OSD is being prepared.
-
-.. option:: --fs-type
-
-   Provide the filesytem type for the OSD. e.g. ``xfs/ext4/btrfs``.
-
-.. option:: --osd-uuid
-
-	Unique OSD uuid to assign to the disk.
-
-.. option:: --journal-uuid
-
-	Unique uuid to assign to the journal.
-
-.. option:: --zap-disk
-
-	Destroy the partition table and content of a disk.
-
-.. option:: --data-dir
-
-	Verify that ``[data-path]`` is of a directory.
-
-.. option:: --data-dev
-
-	Verify that ``[data-path]`` is of a block device.
-
-.. option:: --journal-file
-
-	Verify that journal is a file.
-
-.. option:: --journal-dev
-
-	Verify that journal is a block device.
-
-.. option:: --dmcrypt
-
-	Encrypt ``[data-path]`` and/or journal devices with ``dm-crypt``.
-
-.. option:: --dmcrypt-key-dir
-
-	Directory where ``dm-crypt`` keys are stored.
+The documentation for each subcommand (prepare, activate, etc.) can be displayed
+with its ``--help`` option. For instance ``ceph-disk prepare --help``.
 
 Availability
 ============
diff --git a/doc/man/8/ceph.rst b/doc/man/8/ceph.rst
index 7a43198..a224d69 100644
--- a/doc/man/8/ceph.rst
+++ b/doc/man/8/ceph.rst
@@ -33,7 +33,7 @@ Synopsis
 
 | **ceph** **log** *<logtext>* [ *<logtext>*... ]
 
-| **ceph** **mds** [ *add_data_pool* \| *cluster_down* \| *cluster_up* \| *compat* \| *deactivate* \| *dump* \| *fail* \| *getmap* \| *newfs* \| *remove_data_pool* \| *rm* \| *rmfailed* \| *set* \| *set_max_mds* \| *set_state* \| *setmap* \| *stat* \| *stop* \| *tell* ] ...
+| **ceph** **mds** [ *add_data_pool* \| *cluster_down* \| *cluster_up* \| *compat* \| *deactivate* \| *dump* \| *fail* \| *getmap* \| *newfs* \| *remove_data_pool* \| *rm* \| *rmfailed* \| *set* \| *set_max_mds* \| *set_state* \| *stat* \| *stop* \| *tell* ] ...
 
 | **ceph** **mon** [ *add* \| *dump* \| *getmap* \| *remove* \| *stat* ] ...
 
@@ -433,12 +433,6 @@ Usage::
 
 	ceph mds set_state <int[0-]> <int[0-20]>
 
-Subcommand ``setmap`` sets mds map; must supply correct epoch number.
-
-Usage::
-
-	ceph mds setmap <int[0-]>
-
 Subcommand ``stat`` shows MDS status.
 
 Usage::
@@ -982,6 +976,7 @@ Subcommand ``reweight-by-pg`` reweight OSDs by PG distribution
 Usage::
 
 	ceph osd reweight-by-pg {<int[100-]>} {<poolname> [<poolname...]}
+	{--no-increasing}
 
 Subcommand ``reweight-by-utilization`` reweight OSDs by utilization
 [overload-percentage-for-consideration, default 120].
@@ -989,6 +984,7 @@ Subcommand ``reweight-by-utilization`` reweight OSDs by utilization
 Usage::
 
 	ceph osd reweight-by-utilization {<int[100-]>}
+	{--no-increasing}
 
 Subcommand ``rm`` removes osd(s) <id> [<id>...] in the cluster.
 
diff --git a/doc/man/8/rbd.rst b/doc/man/8/rbd.rst
index 633d89a..a3594c0 100644
--- a/doc/man/8/rbd.rst
+++ b/doc/man/8/rbd.rst
@@ -56,9 +56,9 @@ Parameters
 
    Specifies which object layout to use. The default is 1.
 
-   * format 1 - Use the original format for a new rbd image. This format is
-     understood by all versions of librbd and the kernel rbd module, but
-     does not support newer features like cloning.
+   * format 1 - (deprecated) Use the original format for a new rbd image. This
+     format is understood by all versions of librbd and the kernel rbd module,
+     but does not support newer features like cloning.
 
    * format 2 - Use the second rbd format, which is supported by
      librbd and kernel since version 3.11 (except for striping). This adds
diff --git a/etc/sysconfig/ceph b/etc/sysconfig/ceph
index 5f41a00..4068f29 100644
--- a/etc/sysconfig/ceph
+++ b/etc/sysconfig/ceph
@@ -3,6 +3,9 @@
 # Environment file for ceph daemon systemd unit files.
 #
 
+# Increase tcmalloc cache size
+TCMALLOC_MAX_TOTAL_THREAD_CACHE_BYTES=128MB
+
 ## use jemalloc instead of tcmalloc
 #
 # jemalloc is generally faster for small IO workloads and when
diff --git a/install-sh b/install-sh
index 59990a1..377bb86 100755
--- a/install-sh
+++ b/install-sh
@@ -1,7 +1,7 @@
 #!/bin/sh
 # install - install a program, script, or datafile
 
-scriptversion=2014-09-12.12; # UTC
+scriptversion=2011-11-20.07; # UTC
 
 # This originates from X11R5 (mit/util/scripts/install.sh), which was
 # later released in X11R6 (xc/config/util/install.sh) with the
@@ -41,15 +41,19 @@ scriptversion=2014-09-12.12; # UTC
 # This script is compatible with the BSD install script, but was written
 # from scratch.
 
-tab='	'
 nl='
 '
-IFS=" $tab$nl"
+IFS=" ""	$nl"
 
-# Set DOITPROG to "echo" to test this script.
+# set DOITPROG to echo to test this script
 
+# Don't use :- since 4.3BSD and earlier shells don't like it.
 doit=${DOITPROG-}
-doit_exec=${doit:-exec}
+if test -z "$doit"; then
+  doit_exec=exec
+else
+  doit_exec=$doit
+fi
 
 # Put in absolute file names if you don't have them in your path;
 # or use environment vars.
@@ -64,6 +68,17 @@ mvprog=${MVPROG-mv}
 rmprog=${RMPROG-rm}
 stripprog=${STRIPPROG-strip}
 
+posix_glob='?'
+initialize_posix_glob='
+  test "$posix_glob" != "?" || {
+    if (set -f) 2>/dev/null; then
+      posix_glob=
+    else
+      posix_glob=:
+    fi
+  }
+'
+
 posix_mkdir=
 
 # Desired mode of installed file.
@@ -82,7 +97,7 @@ dir_arg=
 dst_arg=
 
 copy_on_change=false
-is_target_a_directory=possibly
+no_target_directory=
 
 usage="\
 Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE
@@ -122,57 +137,46 @@ while test $# -ne 0; do
     -d) dir_arg=true;;
 
     -g) chgrpcmd="$chgrpprog $2"
-        shift;;
+	shift;;
 
     --help) echo "$usage"; exit $?;;
 
     -m) mode=$2
-        case $mode in
-          *' '* | *"$tab"* | *"$nl"* | *'*'* | *'?'* | *'['*)
-            echo "$0: invalid mode: $mode" >&2
-            exit 1;;
-        esac
-        shift;;
+	case $mode in
+	  *' '* | *'	'* | *'
+'*	  | *'*'* | *'?'* | *'['*)
+	    echo "$0: invalid mode: $mode" >&2
+	    exit 1;;
+	esac
+	shift;;
 
     -o) chowncmd="$chownprog $2"
-        shift;;
+	shift;;
 
     -s) stripcmd=$stripprog;;
 
-    -t)
-        is_target_a_directory=always
-        dst_arg=$2
-        # Protect names problematic for 'test' and other utilities.
-        case $dst_arg in
-          -* | [=\(\)!]) dst_arg=./$dst_arg;;
-        esac
-        shift;;
+    -t) dst_arg=$2
+	# Protect names problematic for 'test' and other utilities.
+	case $dst_arg in
+	  -* | [=\(\)!]) dst_arg=./$dst_arg;;
+	esac
+	shift;;
 
-    -T) is_target_a_directory=never;;
+    -T) no_target_directory=true;;
 
     --version) echo "$0 $scriptversion"; exit $?;;
 
-    --) shift
-        break;;
+    --)	shift
+	break;;
 
-    -*) echo "$0: invalid option: $1" >&2
-        exit 1;;
+    -*)	echo "$0: invalid option: $1" >&2
+	exit 1;;
 
     *)  break;;
   esac
   shift
 done
 
-# We allow the use of options -d and -T together, by making -d
-# take the precedence; this is for compatibility with GNU install.
-
-if test -n "$dir_arg"; then
-  if test -n "$dst_arg"; then
-    echo "$0: target directory not allowed when installing a directory." >&2
-    exit 1
-  fi
-fi
-
 if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then
   # When -d is used, all remaining arguments are directories to create.
   # When -t is used, the destination is already specified.
@@ -204,15 +208,6 @@ if test $# -eq 0; then
 fi
 
 if test -z "$dir_arg"; then
-  if test $# -gt 1 || test "$is_target_a_directory" = always; then
-    if test ! -d "$dst_arg"; then
-      echo "$0: $dst_arg: Is not a directory." >&2
-      exit 1
-    fi
-  fi
-fi
-
-if test -z "$dir_arg"; then
   do_exit='(exit $ret); exit $ret'
   trap "ret=129; $do_exit" 1
   trap "ret=130; $do_exit" 2
@@ -228,16 +223,16 @@ if test -z "$dir_arg"; then
 
     *[0-7])
       if test -z "$stripcmd"; then
-        u_plus_rw=
+	u_plus_rw=
       else
-        u_plus_rw='% 200'
+	u_plus_rw='% 200'
       fi
       cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;;
     *)
       if test -z "$stripcmd"; then
-        u_plus_rw=
+	u_plus_rw=
       else
-        u_plus_rw=,u+rw
+	u_plus_rw=,u+rw
       fi
       cp_umask=$mode$u_plus_rw;;
   esac
@@ -274,15 +269,41 @@ do
     # If destination is a directory, append the input filename; won't work
     # if double slashes aren't ignored.
     if test -d "$dst"; then
-      if test "$is_target_a_directory" = never; then
-        echo "$0: $dst_arg: Is a directory" >&2
-        exit 1
+      if test -n "$no_target_directory"; then
+	echo "$0: $dst_arg: Is a directory" >&2
+	exit 1
       fi
       dstdir=$dst
       dst=$dstdir/`basename "$src"`
       dstdir_status=0
     else
-      dstdir=`dirname "$dst"`
+      # Prefer dirname, but fall back on a substitute if dirname fails.
+      dstdir=`
+	(dirname "$dst") 2>/dev/null ||
+	expr X"$dst" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	     X"$dst" : 'X\(//\)[^/]' \| \
+	     X"$dst" : 'X\(//\)$' \| \
+	     X"$dst" : 'X\(/\)' \| . 2>/dev/null ||
+	echo X"$dst" |
+	    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+		   s//\1/
+		   q
+		 }
+		 /^X\(\/\/\)[^/].*/{
+		   s//\1/
+		   q
+		 }
+		 /^X\(\/\/\)$/{
+		   s//\1/
+		   q
+		 }
+		 /^X\(\/\).*/{
+		   s//\1/
+		   q
+		 }
+		 s/.*/./; q'
+      `
+
       test -d "$dstdir"
       dstdir_status=$?
     fi
@@ -293,81 +314,74 @@ do
   if test $dstdir_status != 0; then
     case $posix_mkdir in
       '')
-        # Create intermediate dirs using mode 755 as modified by the umask.
-        # This is like FreeBSD 'install' as of 1997-10-28.
-        umask=`umask`
-        case $stripcmd.$umask in
-          # Optimize common cases.
-          *[2367][2367]) mkdir_umask=$umask;;
-          .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;;
-
-          *[0-7])
-            mkdir_umask=`expr $umask + 22 \
-              - $umask % 100 % 40 + $umask % 20 \
-              - $umask % 10 % 4 + $umask % 2
-            `;;
-          *) mkdir_umask=$umask,go-w;;
-        esac
-
-        # With -d, create the new directory with the user-specified mode.
-        # Otherwise, rely on $mkdir_umask.
-        if test -n "$dir_arg"; then
-          mkdir_mode=-m$mode
-        else
-          mkdir_mode=
-        fi
-
-        posix_mkdir=false
-        case $umask in
-          *[123567][0-7][0-7])
-            # POSIX mkdir -p sets u+wx bits regardless of umask, which
-            # is incompatible with FreeBSD 'install' when (umask & 300) != 0.
-            ;;
-          *)
-            # $RANDOM is not portable (e.g. dash);  use it when possible to
-            # lower collision chance
-            tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$
-            trap 'ret=$?; rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" 2>/dev/null; exit $ret' 0
-
-            # As "mkdir -p" follows symlinks and we work in /tmp possibly;  so
-            # create the $tmpdir first (and fail if unsuccessful) to make sure
-            # that nobody tries to guess the $tmpdir name.
-            if (umask $mkdir_umask &&
-                $mkdirprog $mkdir_mode "$tmpdir" &&
-                exec $mkdirprog $mkdir_mode -p -- "$tmpdir/a/b") >/dev/null 2>&1
-            then
-              if test -z "$dir_arg" || {
-                   # Check for POSIX incompatibilities with -m.
-                   # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or
-                   # other-writable bit of parent directory when it shouldn't.
-                   # FreeBSD 6.1 mkdir -m -p sets mode of existing directory.
-                   test_tmpdir="$tmpdir/a"
-                   ls_ld_tmpdir=`ls -ld "$test_tmpdir"`
-                   case $ls_ld_tmpdir in
-                     d????-?r-*) different_mode=700;;
-                     d????-?--*) different_mode=755;;
-                     *) false;;
-                   esac &&
-                   $mkdirprog -m$different_mode -p -- "$test_tmpdir" && {
-                     ls_ld_tmpdir_1=`ls -ld "$test_tmpdir"`
-                     test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1"
-                   }
-                 }
-              then posix_mkdir=:
-              fi
-              rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir"
-            else
-              # Remove any dirs left behind by ancient mkdir implementations.
-              rmdir ./$mkdir_mode ./-p ./-- "$tmpdir" 2>/dev/null
-            fi
-            trap '' 0;;
-        esac;;
+	# Create intermediate dirs using mode 755 as modified by the umask.
+	# This is like FreeBSD 'install' as of 1997-10-28.
+	umask=`umask`
+	case $stripcmd.$umask in
+	  # Optimize common cases.
+	  *[2367][2367]) mkdir_umask=$umask;;
+	  .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;;
+
+	  *[0-7])
+	    mkdir_umask=`expr $umask + 22 \
+	      - $umask % 100 % 40 + $umask % 20 \
+	      - $umask % 10 % 4 + $umask % 2
+	    `;;
+	  *) mkdir_umask=$umask,go-w;;
+	esac
+
+	# With -d, create the new directory with the user-specified mode.
+	# Otherwise, rely on $mkdir_umask.
+	if test -n "$dir_arg"; then
+	  mkdir_mode=-m$mode
+	else
+	  mkdir_mode=
+	fi
+
+	posix_mkdir=false
+	case $umask in
+	  *[123567][0-7][0-7])
+	    # POSIX mkdir -p sets u+wx bits regardless of umask, which
+	    # is incompatible with FreeBSD 'install' when (umask & 300) != 0.
+	    ;;
+	  *)
+	    tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$
+	    trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0
+
+	    if (umask $mkdir_umask &&
+		exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1
+	    then
+	      if test -z "$dir_arg" || {
+		   # Check for POSIX incompatibilities with -m.
+		   # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or
+		   # other-writable bit of parent directory when it shouldn't.
+		   # FreeBSD 6.1 mkdir -m -p sets mode of existing directory.
+		   ls_ld_tmpdir=`ls -ld "$tmpdir"`
+		   case $ls_ld_tmpdir in
+		     d????-?r-*) different_mode=700;;
+		     d????-?--*) different_mode=755;;
+		     *) false;;
+		   esac &&
+		   $mkdirprog -m$different_mode -p -- "$tmpdir" && {
+		     ls_ld_tmpdir_1=`ls -ld "$tmpdir"`
+		     test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1"
+		   }
+		 }
+	      then posix_mkdir=:
+	      fi
+	      rmdir "$tmpdir/d" "$tmpdir"
+	    else
+	      # Remove any dirs left behind by ancient mkdir implementations.
+	      rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null
+	    fi
+	    trap '' 0;;
+	esac;;
     esac
 
     if
       $posix_mkdir && (
-        umask $mkdir_umask &&
-        $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir"
+	umask $mkdir_umask &&
+	$doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir"
       )
     then :
     else
@@ -377,51 +391,53 @@ do
       # directory the slow way, step by step, checking for races as we go.
 
       case $dstdir in
-        /*) prefix='/';;
-        [-=\(\)!]*) prefix='./';;
-        *)  prefix='';;
+	/*) prefix='/';;
+	[-=\(\)!]*) prefix='./';;
+	*)  prefix='';;
       esac
 
+      eval "$initialize_posix_glob"
+
       oIFS=$IFS
       IFS=/
-      set -f
+      $posix_glob set -f
       set fnord $dstdir
       shift
-      set +f
+      $posix_glob set +f
       IFS=$oIFS
 
       prefixes=
 
       for d
       do
-        test X"$d" = X && continue
-
-        prefix=$prefix$d
-        if test -d "$prefix"; then
-          prefixes=
-        else
-          if $posix_mkdir; then
-            (umask=$mkdir_umask &&
-             $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break
-            # Don't fail if two instances are running concurrently.
-            test -d "$prefix" || exit 1
-          else
-            case $prefix in
-              *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;;
-              *) qprefix=$prefix;;
-            esac
-            prefixes="$prefixes '$qprefix'"
-          fi
-        fi
-        prefix=$prefix/
+	test X"$d" = X && continue
+
+	prefix=$prefix$d
+	if test -d "$prefix"; then
+	  prefixes=
+	else
+	  if $posix_mkdir; then
+	    (umask=$mkdir_umask &&
+	     $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break
+	    # Don't fail if two instances are running concurrently.
+	    test -d "$prefix" || exit 1
+	  else
+	    case $prefix in
+	      *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;;
+	      *) qprefix=$prefix;;
+	    esac
+	    prefixes="$prefixes '$qprefix'"
+	  fi
+	fi
+	prefix=$prefix/
       done
 
       if test -n "$prefixes"; then
-        # Don't fail if two instances are running concurrently.
-        (umask $mkdir_umask &&
-         eval "\$doit_exec \$mkdirprog $prefixes") ||
-          test -d "$dstdir" || exit 1
-        obsolete_mkdir_used=true
+	# Don't fail if two instances are running concurrently.
+	(umask $mkdir_umask &&
+	 eval "\$doit_exec \$mkdirprog $prefixes") ||
+	  test -d "$dstdir" || exit 1
+	obsolete_mkdir_used=true
       fi
     fi
   fi
@@ -456,12 +472,15 @@ do
 
     # If -C, don't bother to copy if it wouldn't change the file.
     if $copy_on_change &&
-       old=`LC_ALL=C ls -dlL "$dst"     2>/dev/null` &&
-       new=`LC_ALL=C ls -dlL "$dsttmp"  2>/dev/null` &&
-       set -f &&
+       old=`LC_ALL=C ls -dlL "$dst"	2>/dev/null` &&
+       new=`LC_ALL=C ls -dlL "$dsttmp"	2>/dev/null` &&
+
+       eval "$initialize_posix_glob" &&
+       $posix_glob set -f &&
        set X $old && old=:$2:$4:$5:$6 &&
        set X $new && new=:$2:$4:$5:$6 &&
-       set +f &&
+       $posix_glob set +f &&
+
        test "$old" = "$new" &&
        $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1
     then
@@ -474,24 +493,24 @@ do
       # to itself, or perhaps because mv is so ancient that it does not
       # support -f.
       {
-        # Now remove or move aside any old file at destination location.
-        # We try this two ways since rm can't unlink itself on some
-        # systems and the destination file might be busy for other
-        # reasons.  In this case, the final cleanup might fail but the new
-        # file should still install successfully.
-        {
-          test ! -f "$dst" ||
-          $doit $rmcmd -f "$dst" 2>/dev/null ||
-          { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null &&
-            { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; }
-          } ||
-          { echo "$0: cannot unlink or rename $dst" >&2
-            (exit 1); exit 1
-          }
-        } &&
-
-        # Now rename the file to the real destination.
-        $doit $mvcmd "$dsttmp" "$dst"
+	# Now remove or move aside any old file at destination location.
+	# We try this two ways since rm can't unlink itself on some
+	# systems and the destination file might be busy for other
+	# reasons.  In this case, the final cleanup might fail but the new
+	# file should still install successfully.
+	{
+	  test ! -f "$dst" ||
+	  $doit $rmcmd -f "$dst" 2>/dev/null ||
+	  { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null &&
+	    { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; }
+	  } ||
+	  { echo "$0: cannot unlink or rename $dst" >&2
+	    (exit 1); exit 1
+	  }
+	} &&
+
+	# Now rename the file to the real destination.
+	$doit $mvcmd "$dsttmp" "$dst"
       }
     fi || exit 1
 
diff --git a/ltmain.sh b/ltmain.sh
index 147d758..a356aca 100644
--- a/ltmain.sh
+++ b/ltmain.sh
@@ -1,12 +1,9 @@
-#! /bin/sh
-## DO NOT EDIT - This file generated from ./build-aux/ltmain.in
-##               by inline-source v2014-01-03.01
 
-# libtool (GNU libtool) 2.4.6
-# Provide generalized library-building support services.
+# libtool (GNU libtool) 2.4.2
 # Written by Gordon Matzigkeit <gord at gnu.ai.mit.edu>, 1996
 
-# Copyright (C) 1996-2015 Free Software Foundation, Inc.
+# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, 2006,
+# 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
 # This is free software; see the source for copying conditions.  There is NO
 # warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 
@@ -26,2112 +23,881 @@
 # General Public License for more details.
 #
 # You should have received a copy of the GNU General Public License
-# along with this program.  If not, see <http://www.gnu.org/licenses/>.
-
-
-PROGRAM=libtool
-PACKAGE=libtool
-VERSION="2.4.6 Debian-2.4.6-0.1"
-package_revision=2.4.6
-
-
-## ------ ##
-## Usage. ##
-## ------ ##
-
-# Run './libtool --help' for help with using this script from the
-# command line.
-
-
-## ------------------------------- ##
-## User overridable command paths. ##
-## ------------------------------- ##
-
-# After configure completes, it has a better idea of some of the
-# shell tools we need than the defaults used by the functions shared
-# with bootstrap, so set those here where they can still be over-
-# ridden by the user, but otherwise take precedence.
-
-: ${AUTOCONF="autoconf"}
-: ${AUTOMAKE="automake"}
-
-
-## -------------------------- ##
-## Source external libraries. ##
-## -------------------------- ##
-
-# Much of our low-level functionality needs to be sourced from external
-# libraries, which are installed to $pkgauxdir.
-
-# Set a version string for this script.
-scriptversion=2015-01-20.17; # UTC
-
-# General shell script boiler plate, and helper functions.
-# Written by Gary V. Vaughan, 2004
-
-# Copyright (C) 2004-2015 Free Software Foundation, Inc.
-# This is free software; see the source for copying conditions.  There is NO
-# warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 3 of the License, or
-# (at your option) any later version.
-
-# As a special exception to the GNU General Public License, if you distribute
-# this file as part of a program or library that is built using GNU Libtool,
-# you may include this file under the same distribution terms that you use
-# for the rest of that program.
-
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNES FOR A PARTICULAR PURPOSE. See the GNU
-# General Public License for more details.
-
-# You should have received a copy of the GNU General Public License
-# along with this program. If not, see <http://www.gnu.org/licenses/>.
+# along with GNU Libtool; see the file COPYING.  If not, a copy
+# can be downloaded from http://www.gnu.org/licenses/gpl.html,
+# or obtained by writing to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 
-# Please report bugs or propose patches to gary at gnu.org.
-
-
-## ------ ##
-## Usage. ##
-## ------ ##
-
-# Evaluate this file near the top of your script to gain access to
-# the functions and variables defined here:
+# Usage: $progname [OPTION]... [MODE-ARG]...
+#
+# Provide generalized library-building support services.
 #
-#   . `echo "$0" | ${SED-sed} 's|[^/]*$||'`/build-aux/funclib.sh
+#       --config             show all configuration variables
+#       --debug              enable verbose shell tracing
+#   -n, --dry-run            display commands without modifying any files
+#       --features           display basic configuration information and exit
+#       --mode=MODE          use operation mode MODE
+#       --preserve-dup-deps  don't remove duplicate dependency libraries
+#       --quiet, --silent    don't print informational messages
+#       --no-quiet, --no-silent
+#                            print informational messages (default)
+#       --no-warn            don't display warning messages
+#       --tag=TAG            use configuration variables from tag TAG
+#   -v, --verbose            print more informational messages than default
+#       --no-verbose         don't print the extra informational messages
+#       --version            print version information
+#   -h, --help, --help-all   print short, long, or detailed help message
 #
-# If you need to override any of the default environment variable
-# settings, do that before evaluating this file.
-
-
-## -------------------- ##
-## Shell normalisation. ##
-## -------------------- ##
+# MODE must be one of the following:
+#
+#         clean              remove files from the build directory
+#         compile            compile a source file into a libtool object
+#         execute            automatically set library path, then run a program
+#         finish             complete the installation of libtool libraries
+#         install            install libraries or executables
+#         link               create a library or an executable
+#         uninstall          remove libraries from an installed directory
+#
+# MODE-ARGS vary depending on the MODE.  When passed as first option,
+# `--mode=MODE' may be abbreviated as `MODE' or a unique abbreviation of that.
+# Try `$progname --help --mode=MODE' for a more detailed description of MODE.
+#
+# When reporting a bug, please describe a test case to reproduce it and
+# include the following information:
+#
+#         host-triplet:	$host
+#         shell:		$SHELL
+#         compiler:		$LTCC
+#         compiler flags:		$LTCFLAGS
+#         linker:		$LD (gnu? $with_gnu_ld)
+#         $progname:	(GNU libtool) 2.4.2 Debian-2.4.2-1.7ubuntu1
+#         automake:	$automake_version
+#         autoconf:	$autoconf_version
+#
+# Report bugs to <bug-libtool at gnu.org>.
+# GNU libtool home page: <http://www.gnu.org/software/libtool/>.
+# General help using GNU software: <http://www.gnu.org/gethelp/>.
 
-# Some shells need a little help to be as Bourne compatible as possible.
-# Before doing anything else, make sure all that help has been provided!
+PROGRAM=libtool
+PACKAGE=libtool
+VERSION="2.4.2 Debian-2.4.2-1.7ubuntu1"
+TIMESTAMP=""
+package_revision=1.3337
 
-DUALCASE=1; export DUALCASE # for MKS sh
-if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then :
+# Be Bourne compatible
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
   emulate sh
   NULLCMD=:
-  # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which
+  # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which
   # is contrary to our usage.  Disable this feature.
   alias -g '${1+"$@"}'='"$@"'
   setopt NO_GLOB_SUBST
 else
-  case `(set -o) 2>/dev/null` in *posix*) set -o posix ;; esac
-fi
-
-# NLS nuisances: We save the old values in case they are required later.
-_G_user_locale=
-_G_safe_locale=
-for _G_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES
-do
-  eval "if test set = \"\${$_G_var+set}\"; then
-          save_$_G_var=\$$_G_var
-          $_G_var=C
-	  export $_G_var
-	  _G_user_locale=\"$_G_var=\\\$save_\$_G_var; \$_G_user_locale\"
-	  _G_safe_locale=\"$_G_var=C; \$_G_safe_locale\"
-	fi"
-done
-
-# CDPATH.
-(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
-
-# Make sure IFS has a sensible default
-sp=' '
-nl='
-'
-IFS="$sp	$nl"
-
-# There are apparently some retarded systems that use ';' as a PATH separator!
-if test "${PATH_SEPARATOR+set}" != set; then
-  PATH_SEPARATOR=:
-  (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && {
-    (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 ||
-      PATH_SEPARATOR=';'
-  }
+  case `(set -o) 2>/dev/null` in *posix*) set -o posix;; esac
 fi
+BIN_SH=xpg4; export BIN_SH # for Tru64
+DUALCASE=1; export DUALCASE # for MKS sh
 
-
-
-## ------------------------- ##
-## Locate command utilities. ##
-## ------------------------- ##
-
-
-# func_executable_p FILE
-# ----------------------
-# Check that FILE is an executable regular file.
-func_executable_p ()
-{
-    test -f "$1" && test -x "$1"
-}
-
-
-# func_path_progs PROGS_LIST CHECK_FUNC [PATH]
-# --------------------------------------------
-# Search for either a program that responds to --version with output
-# containing "GNU", or else returned by CHECK_FUNC otherwise, by
-# trying all the directories in PATH with each of the elements of
-# PROGS_LIST.
-#
-# CHECK_FUNC should accept the path to a candidate program, and
-# set $func_check_prog_result if it truncates its output less than
-# $_G_path_prog_max characters.
-func_path_progs ()
+# A function that is used when there is no print builtin or printf.
+func_fallback_echo ()
 {
-    _G_progs_list=$1
-    _G_check_func=$2
-    _G_PATH=${3-"$PATH"}
-
-    _G_path_prog_max=0
-    _G_path_prog_found=false
-    _G_save_IFS=$IFS; IFS=${PATH_SEPARATOR-:}
-    for _G_dir in $_G_PATH; do
-      IFS=$_G_save_IFS
-      test -z "$_G_dir" && _G_dir=.
-      for _G_prog_name in $_G_progs_list; do
-        for _exeext in '' .EXE; do
-          _G_path_prog=$_G_dir/$_G_prog_name$_exeext
-          func_executable_p "$_G_path_prog" || continue
-          case `"$_G_path_prog" --version 2>&1` in
-            *GNU*) func_path_progs_result=$_G_path_prog _G_path_prog_found=: ;;
-            *)     $_G_check_func $_G_path_prog
-		   func_path_progs_result=$func_check_prog_result
-		   ;;
-          esac
-          $_G_path_prog_found && break 3
-        done
-      done
-    done
-    IFS=$_G_save_IFS
-    test -z "$func_path_progs_result" && {
-      echo "no acceptable sed could be found in \$PATH" >&2
-      exit 1
-    }
-}
-
-
-# We want to be able to use the functions in this file before configure
-# has figured out where the best binaries are kept, which means we have
-# to search for them ourselves - except when the results are already set
-# where we skip the searches.
-
-# Unless the user overrides by setting SED, search the path for either GNU
-# sed, or the sed that truncates its output the least.
-test -z "$SED" && {
-  _G_sed_script=s/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/
-  for _G_i in 1 2 3 4 5 6 7; do
-    _G_sed_script=$_G_sed_script$nl$_G_sed_script
-  done
-  echo "$_G_sed_script" 2>/dev/null | sed 99q >conftest.sed
-  _G_sed_script=
-
-  func_check_prog_sed ()
-  {
-    _G_path_prog=$1
-
-    _G_count=0
-    printf 0123456789 >conftest.in
-    while :
-    do
-      cat conftest.in conftest.in >conftest.tmp
-      mv conftest.tmp conftest.in
-      cp conftest.in conftest.nl
-      echo '' >> conftest.nl
-      "$_G_path_prog" -f conftest.sed <conftest.nl >conftest.out 2>/dev/null || break
-      diff conftest.out conftest.nl >/dev/null 2>&1 || break
-      _G_count=`expr $_G_count + 1`
-      if test "$_G_count" -gt "$_G_path_prog_max"; then
-        # Best one so far, save it but keep looking for a better one
-        func_check_prog_result=$_G_path_prog
-        _G_path_prog_max=$_G_count
-      fi
-      # 10*(2^10) chars as input seems more than enough
-      test 10 -lt "$_G_count" && break
-    done
-    rm -f conftest.in conftest.tmp conftest.nl conftest.out
-  }
-
-  func_path_progs "sed gsed" func_check_prog_sed $PATH:/usr/xpg4/bin
-  rm -f conftest.sed
-  SED=$func_path_progs_result
+  eval 'cat <<_LTECHO_EOF
+$1
+_LTECHO_EOF'
 }
 
+# NLS nuisances: We save the old values to restore during execute mode.
+lt_user_locale=
+lt_safe_locale=
+for lt_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES
+do
+  eval "if test \"\${$lt_var+set}\" = set; then
+          save_$lt_var=\$$lt_var
+          $lt_var=C
+	  export $lt_var
+	  lt_user_locale=\"$lt_var=\\\$save_\$lt_var; \$lt_user_locale\"
+	  lt_safe_locale=\"$lt_var=C; \$lt_safe_locale\"
+	fi"
+done
+LC_ALL=C
+LANGUAGE=C
+export LANGUAGE LC_ALL
 
-# Unless the user overrides by setting GREP, search the path for either GNU
-# grep, or the grep that truncates its output the least.
-test -z "$GREP" && {
-  func_check_prog_grep ()
-  {
-    _G_path_prog=$1
-
-    _G_count=0
-    _G_path_prog_max=0
-    printf 0123456789 >conftest.in
-    while :
-    do
-      cat conftest.in conftest.in >conftest.tmp
-      mv conftest.tmp conftest.in
-      cp conftest.in conftest.nl
-      echo 'GREP' >> conftest.nl
-      "$_G_path_prog" -e 'GREP$' -e '-(cannot match)-' <conftest.nl >conftest.out 2>/dev/null || break
-      diff conftest.out conftest.nl >/dev/null 2>&1 || break
-      _G_count=`expr $_G_count + 1`
-      if test "$_G_count" -gt "$_G_path_prog_max"; then
-        # Best one so far, save it but keep looking for a better one
-        func_check_prog_result=$_G_path_prog
-        _G_path_prog_max=$_G_count
-      fi
-      # 10*(2^10) chars as input seems more than enough
-      test 10 -lt "$_G_count" && break
-    done
-    rm -f conftest.in conftest.tmp conftest.nl conftest.out
-  }
+$lt_unset CDPATH
 
-  func_path_progs "grep ggrep" func_check_prog_grep $PATH:/usr/xpg4/bin
-  GREP=$func_path_progs_result
-}
 
+# Work around backward compatibility issue on IRIX 6.5. On IRIX 6.4+, sh
+# is ksh but when the shell is invoked as "sh" and the current value of
+# the _XPG environment variable is not equal to 1 (one), the special
+# positional parameter $0, within a function call, is the name of the
+# function.
+progpath="$0"
 
-## ------------------------------- ##
-## User overridable command paths. ##
-## ------------------------------- ##
 
-# All uppercase variable names are used for environment variables.  These
-# variables can be overridden by the user before calling a script that
-# uses them if a suitable command of that name is not already available
-# in the command search PATH.
 
 : ${CP="cp -f"}
-: ${ECHO="printf %s\n"}
-: ${EGREP="$GREP -E"}
-: ${FGREP="$GREP -F"}
-: ${LN_S="ln -s"}
+test "${ECHO+set}" = set || ECHO=${as_echo-'printf %s\n'}
 : ${MAKE="make"}
 : ${MKDIR="mkdir"}
 : ${MV="mv -f"}
 : ${RM="rm -f"}
 : ${SHELL="${CONFIG_SHELL-/bin/sh}"}
+: ${Xsed="$SED -e 1s/^X//"}
 
+# Global variables:
+EXIT_SUCCESS=0
+EXIT_FAILURE=1
+EXIT_MISMATCH=63  # $? = 63 is used to indicate version mismatch to missing.
+EXIT_SKIP=77	  # $? = 77 is used to indicate a skipped test to automake.
 
-## -------------------- ##
-## Useful sed snippets. ##
-## -------------------- ##
+exit_status=$EXIT_SUCCESS
 
-sed_dirname='s|/[^/]*$||'
-sed_basename='s|^.*/||'
+# Make sure IFS has a sensible default
+lt_nl='
+'
+IFS=" 	$lt_nl"
 
-# Sed substitution that helps us do robust quoting.  It backslashifies
-# metacharacters that are still active within double-quoted strings.
-sed_quote_subst='s|\([`"$\\]\)|\\\1|g'
+dirname="s,/[^/]*$,,"
+basename="s,^.*/,,"
 
-# Same as above, but do not quote variable references.
-sed_double_quote_subst='s/\(["`\\]\)/\\\1/g'
+# func_dirname file append nondir_replacement
+# Compute the dirname of FILE.  If nonempty, add APPEND to the result,
+# otherwise set result to NONDIR_REPLACEMENT.
+func_dirname ()
+{
+    func_dirname_result=`$ECHO "${1}" | $SED "$dirname"`
+    if test "X$func_dirname_result" = "X${1}"; then
+      func_dirname_result="${3}"
+    else
+      func_dirname_result="$func_dirname_result${2}"
+    fi
+} # func_dirname may be replaced by extended shell implementation
 
-# Sed substitution that turns a string into a regex matching for the
-# string literally.
-sed_make_literal_regex='s|[].[^$\\*\/]|\\&|g'
 
-# Sed substitution that converts a w32 file name or path
-# that contains forward slashes, into one that contains
-# (escaped) backslashes.  A very naive implementation.
-sed_naive_backslashify='s|\\\\*|\\|g;s|/|\\|g;s|\\|\\\\|g'
-
-# Re-'\' parameter expansions in output of sed_double_quote_subst that
-# were '\'-ed in input to the same.  If an odd number of '\' preceded a
-# '$' in input to sed_double_quote_subst, that '$' was protected from
-# expansion.  Since each input '\' is now two '\'s, look for any number
-# of runs of four '\'s followed by two '\'s and then a '$'.  '\' that '$'.
-_G_bs='\\'
-_G_bs2='\\\\'
-_G_bs4='\\\\\\\\'
-_G_dollar='\$'
-sed_double_backslash="\
-  s/$_G_bs4/&\\
-/g
-  s/^$_G_bs2$_G_dollar/$_G_bs&/
-  s/\\([^$_G_bs]\\)$_G_bs2$_G_dollar/\\1$_G_bs2$_G_bs$_G_dollar/g
-  s/\n//g"
+# func_basename file
+func_basename ()
+{
+    func_basename_result=`$ECHO "${1}" | $SED "$basename"`
+} # func_basename may be replaced by extended shell implementation
 
 
-## ----------------- ##
-## Global variables. ##
-## ----------------- ##
+# func_dirname_and_basename file append nondir_replacement
+# perform func_basename and func_dirname in a single function
+# call:
+#   dirname:  Compute the dirname of FILE.  If nonempty,
+#             add APPEND to the result, otherwise set result
+#             to NONDIR_REPLACEMENT.
+#             value returned in "$func_dirname_result"
+#   basename: Compute filename of FILE.
+#             value retuned in "$func_basename_result"
+# Implementation must be kept synchronized with func_dirname
+# and func_basename. For efficiency, we do not delegate to
+# those functions but instead duplicate the functionality here.
+func_dirname_and_basename ()
+{
+    # Extract subdirectory from the argument.
+    func_dirname_result=`$ECHO "${1}" | $SED -e "$dirname"`
+    if test "X$func_dirname_result" = "X${1}"; then
+      func_dirname_result="${3}"
+    else
+      func_dirname_result="$func_dirname_result${2}"
+    fi
+    func_basename_result=`$ECHO "${1}" | $SED -e "$basename"`
+} # func_dirname_and_basename may be replaced by extended shell implementation
 
-# Except for the global variables explicitly listed below, the following
-# functions in the '^func_' namespace, and the '^require_' namespace
-# variables initialised in the 'Resource management' section, sourcing
-# this file will not pollute your global namespace with anything
-# else. There's no portable way to scope variables in Bourne shell
-# though, so actually running these functions will sometimes place
-# results into a variable named after the function, and often use
-# temporary variables in the '^_G_' namespace. If you are careful to
-# avoid using those namespaces casually in your sourcing script, things
-# should continue to work as you expect. And, of course, you can freely
-# overwrite any of the functions or variables defined here before
-# calling anything to customize them.
 
-EXIT_SUCCESS=0
-EXIT_FAILURE=1
-EXIT_MISMATCH=63  # $? = 63 is used to indicate version mismatch to missing.
-EXIT_SKIP=77	  # $? = 77 is used to indicate a skipped test to automake.
+# func_stripname prefix suffix name
+# strip PREFIX and SUFFIX off of NAME.
+# PREFIX and SUFFIX must not contain globbing or regex special
+# characters, hashes, percent signs, but SUFFIX may contain a leading
+# dot (in which case that matches only a dot).
+# func_strip_suffix prefix name
+func_stripname ()
+{
+    case ${2} in
+      .*) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%\\\\${2}\$%%"`;;
+      *)  func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%${2}\$%%"`;;
+    esac
+} # func_stripname may be replaced by extended shell implementation
 
-# Allow overriding, eg assuming that you follow the convention of
-# putting '$debug_cmd' at the start of all your functions, you can get
-# bash to show function call trace with:
-#
-#    debug_cmd='eval echo "${FUNCNAME[0]} $*" >&2' bash your-script-name
-debug_cmd=${debug_cmd-":"}
-exit_cmd=:
 
-# By convention, finish your script with:
-#
-#    exit $exit_status
-#
-# so that you can set exit_status to non-zero if you want to indicate
-# something went wrong during execution without actually bailing out at
-# the point of failure.
-exit_status=$EXIT_SUCCESS
+# These SED scripts presuppose an absolute path with a trailing slash.
+pathcar='s,^/\([^/]*\).*$,\1,'
+pathcdr='s,^/[^/]*,,'
+removedotparts=':dotsl
+		s@/\./@/@g
+		t dotsl
+		s,/\.$,/,'
+collapseslashes='s@/\{1,\}@/@g'
+finalslash='s,/*$,/,'
 
-# Work around backward compatibility issue on IRIX 6.5. On IRIX 6.4+, sh
-# is ksh but when the shell is invoked as "sh" and the current value of
-# the _XPG environment variable is not equal to 1 (one), the special
-# positional parameter $0, within a function call, is the name of the
-# function.
-progpath=$0
+# func_normal_abspath PATH
+# Remove doubled-up and trailing slashes, "." path components,
+# and cancel out any ".." path components in PATH after making
+# it an absolute path.
+#             value returned in "$func_normal_abspath_result"
+func_normal_abspath ()
+{
+  # Start from root dir and reassemble the path.
+  func_normal_abspath_result=
+  func_normal_abspath_tpath=$1
+  func_normal_abspath_altnamespace=
+  case $func_normal_abspath_tpath in
+    "")
+      # Empty path, that just means $cwd.
+      func_stripname '' '/' "`pwd`"
+      func_normal_abspath_result=$func_stripname_result
+      return
+    ;;
+    # The next three entries are used to spot a run of precisely
+    # two leading slashes without using negated character classes;
+    # we take advantage of case's first-match behaviour.
+    ///*)
+      # Unusual form of absolute path, do nothing.
+    ;;
+    //*)
+      # Not necessarily an ordinary path; POSIX reserves leading '//'
+      # and for example Cygwin uses it to access remote file shares
+      # over CIFS/SMB, so we conserve a leading double slash if found.
+      func_normal_abspath_altnamespace=/
+    ;;
+    /*)
+      # Absolute path, do nothing.
+    ;;
+    *)
+      # Relative path, prepend $cwd.
+      func_normal_abspath_tpath=`pwd`/$func_normal_abspath_tpath
+    ;;
+  esac
+  # Cancel out all the simple stuff to save iterations.  We also want
+  # the path to end with a slash for ease of parsing, so make sure
+  # there is one (and only one) here.
+  func_normal_abspath_tpath=`$ECHO "$func_normal_abspath_tpath" | $SED \
+        -e "$removedotparts" -e "$collapseslashes" -e "$finalslash"`
+  while :; do
+    # Processed it all yet?
+    if test "$func_normal_abspath_tpath" = / ; then
+      # If we ascended to the root using ".." the result may be empty now.
+      if test -z "$func_normal_abspath_result" ; then
+        func_normal_abspath_result=/
+      fi
+      break
+    fi
+    func_normal_abspath_tcomponent=`$ECHO "$func_normal_abspath_tpath" | $SED \
+        -e "$pathcar"`
+    func_normal_abspath_tpath=`$ECHO "$func_normal_abspath_tpath" | $SED \
+        -e "$pathcdr"`
+    # Figure out what to do with it
+    case $func_normal_abspath_tcomponent in
+      "")
+        # Trailing empty path component, ignore it.
+      ;;
+      ..)
+        # Parent dir; strip last assembled component from result.
+        func_dirname "$func_normal_abspath_result"
+        func_normal_abspath_result=$func_dirname_result
+      ;;
+      *)
+        # Actual path component, append it.
+        func_normal_abspath_result=$func_normal_abspath_result/$func_normal_abspath_tcomponent
+      ;;
+    esac
+  done
+  # Restore leading double-slash if one was found on entry.
+  func_normal_abspath_result=$func_normal_abspath_altnamespace$func_normal_abspath_result
+}
+
+# func_relative_path SRCDIR DSTDIR
+# generates a relative path from SRCDIR to DSTDIR, with a trailing
+# slash if non-empty, suitable for immediately appending a filename
+# without needing to append a separator.
+#             value returned in "$func_relative_path_result"
+func_relative_path ()
+{
+  func_relative_path_result=
+  func_normal_abspath "$1"
+  func_relative_path_tlibdir=$func_normal_abspath_result
+  func_normal_abspath "$2"
+  func_relative_path_tbindir=$func_normal_abspath_result
+
+  # Ascend the tree starting from libdir
+  while :; do
+    # check if we have found a prefix of bindir
+    case $func_relative_path_tbindir in
+      $func_relative_path_tlibdir)
+        # found an exact match
+        func_relative_path_tcancelled=
+        break
+        ;;
+      $func_relative_path_tlibdir*)
+        # found a matching prefix
+        func_stripname "$func_relative_path_tlibdir" '' "$func_relative_path_tbindir"
+        func_relative_path_tcancelled=$func_stripname_result
+        if test -z "$func_relative_path_result"; then
+          func_relative_path_result=.
+        fi
+        break
+        ;;
+      *)
+        func_dirname $func_relative_path_tlibdir
+        func_relative_path_tlibdir=${func_dirname_result}
+        if test "x$func_relative_path_tlibdir" = x ; then
+          # Have to descend all the way to the root!
+          func_relative_path_result=../$func_relative_path_result
+          func_relative_path_tcancelled=$func_relative_path_tbindir
+          break
+        fi
+        func_relative_path_result=../$func_relative_path_result
+        ;;
+    esac
+  done
+
+  # Now calculate path; take care to avoid doubling-up slashes.
+  func_stripname '' '/' "$func_relative_path_result"
+  func_relative_path_result=$func_stripname_result
+  func_stripname '/' '/' "$func_relative_path_tcancelled"
+  if test "x$func_stripname_result" != x ; then
+    func_relative_path_result=${func_relative_path_result}/${func_stripname_result}
+  fi
+
+  # Normalisation. If bindir is libdir, return empty string,
+  # else relative path ending with a slash; either way, target
+  # file name can be directly appended.
+  if test ! -z "$func_relative_path_result"; then
+    func_stripname './' '' "$func_relative_path_result/"
+    func_relative_path_result=$func_stripname_result
+  fi
+}
 
-# The name of this program.
-progname=`$ECHO "$progpath" |$SED "$sed_basename"`
+# The name of this program:
+func_dirname_and_basename "$progpath"
+progname=$func_basename_result
 
-# Make sure we have an absolute progpath for reexecution:
+# Make sure we have an absolute path for reexecution:
 case $progpath in
   [\\/]*|[A-Za-z]:\\*) ;;
   *[\\/]*)
-     progdir=`$ECHO "$progpath" |$SED "$sed_dirname"`
+     progdir=$func_dirname_result
      progdir=`cd "$progdir" && pwd`
-     progpath=$progdir/$progname
+     progpath="$progdir/$progname"
      ;;
   *)
-     _G_IFS=$IFS
+     save_IFS="$IFS"
      IFS=${PATH_SEPARATOR-:}
      for progdir in $PATH; do
-       IFS=$_G_IFS
+       IFS="$save_IFS"
        test -x "$progdir/$progname" && break
      done
-     IFS=$_G_IFS
+     IFS="$save_IFS"
      test -n "$progdir" || progdir=`pwd`
-     progpath=$progdir/$progname
+     progpath="$progdir/$progname"
      ;;
 esac
 
+# Sed substitution that helps us do robust quoting.  It backslashifies
+# metacharacters that are still active within double-quoted strings.
+Xsed="${SED}"' -e 1s/^X//'
+sed_quote_subst='s/\([`"$\\]\)/\\\1/g'
+
+# Same as above, but do not quote variable references.
+double_quote_subst='s/\(["`\\]\)/\\\1/g'
 
-## ----------------- ##
-## Standard options. ##
-## ----------------- ##
+# Sed substitution that turns a string into a regex matching for the
+# string literally.
+sed_make_literal_regex='s,[].[^$\\*\/],\\&,g'
 
-# The following options affect the operation of the functions defined
-# below, and should be set appropriately depending on run-time para-
-# meters passed on the command line.
+# Sed substitution that converts a w32 file name or path
+# which contains forward slashes, into one that contains
+# (escaped) backslashes.  A very naive implementation.
+lt_sed_naive_backslashify='s|\\\\*|\\|g;s|/|\\|g;s|\\|\\\\|g'
+
+# Re-`\' parameter expansions in output of double_quote_subst that were
+# `\'-ed in input to the same.  If an odd number of `\' preceded a '$'
+# in input to double_quote_subst, that '$' was protected from expansion.
+# Since each input `\' is now two `\'s, look for any number of runs of
+# four `\'s followed by two `\'s and then a '$'.  `\' that '$'.
+bs='\\'
+bs2='\\\\'
+bs4='\\\\\\\\'
+dollar='\$'
+sed_double_backslash="\
+  s/$bs4/&\\
+/g
+  s/^$bs2$dollar/$bs&/
+  s/\\([^$bs]\\)$bs2$dollar/\\1$bs2$bs$dollar/g
+  s/\n//g"
 
+# Standard options:
 opt_dry_run=false
+opt_help=false
 opt_quiet=false
 opt_verbose=false
+opt_warning=:
 
-# Categories 'all' and 'none' are always available.  Append any others
-# you will pass as the first argument to func_warning from your own
-# code.
-warning_categories=
+# func_echo arg...
+# Echo program name prefixed message, along with the current mode
+# name if it has been set yet.
+func_echo ()
+{
+    $ECHO "$progname: ${opt_mode+$opt_mode: }$*"
+}
 
-# By default, display warnings according to 'opt_warning_types'.  Set
-# 'warning_func'  to ':' to elide all warnings, or func_fatal_error to
-# treat the next displayed warning as a fatal error.
-warning_func=func_warn_and_continue
+# func_verbose arg...
+# Echo program name prefixed message in verbose mode only.
+func_verbose ()
+{
+    $opt_verbose && func_echo ${1+"$@"}
 
-# Set to 'all' to display all warnings, 'none' to suppress all
-# warnings, or a space delimited list of some subset of
-# 'warning_categories' to display only the listed warnings.
-opt_warning_types=all
+    # A bug in bash halts the script if the last line of a function
+    # fails when set -e is in force, so we need another command to
+    # work around that:
+    :
+}
 
+# func_echo_all arg...
+# Invoke $ECHO with all args, space-separated.
+func_echo_all ()
+{
+    $ECHO "$*"
+}
 
-## -------------------- ##
-## Resource management. ##
-## -------------------- ##
+# func_error arg...
+# Echo program name prefixed message to standard error.
+func_error ()
+{
+    $ECHO "$progname: ${opt_mode+$opt_mode: }"${1+"$@"} 1>&2
+}
 
-# This section contains definitions for functions that each ensure a
-# particular resource (a file, or a non-empty configuration variable for
-# example) is available, and if appropriate to extract default values
-# from pertinent package files. Call them using their associated
-# 'require_*' variable to ensure that they are executed, at most, once.
-#
-# It's entirely deliberate that calling these functions can set
-# variables that don't obey the namespace limitations obeyed by the rest
-# of this file, in order that that they be as useful as possible to
-# callers.
+# func_warning arg...
+# Echo program name prefixed warning message to standard error.
+func_warning ()
+{
+    $opt_warning && $ECHO "$progname: ${opt_mode+$opt_mode: }warning: "${1+"$@"} 1>&2
 
+    # bash bug again:
+    :
+}
 
-# require_term_colors
-# -------------------
-# Allow display of bold text on terminals that support it.
-require_term_colors=func_require_term_colors
-func_require_term_colors ()
+# func_fatal_error arg...
+# Echo program name prefixed message to standard error, and exit.
+func_fatal_error ()
 {
-    $debug_cmd
-
-    test -t 1 && {
-      # COLORTERM and USE_ANSI_COLORS environment variables take
-      # precedence, because most terminfo databases neglect to describe
-      # whether color sequences are supported.
-      test -n "${COLORTERM+set}" && : ${USE_ANSI_COLORS="1"}
-
-      if test 1 = "$USE_ANSI_COLORS"; then
-        # Standard ANSI escape sequences
-        tc_reset=''
-        tc_bold='';   tc_standout=''
-        tc_red='';   tc_green=''
-        tc_blue='';  tc_cyan=''
-      else
-        # Otherwise trust the terminfo database after all.
-        test -n "`tput sgr0 2>/dev/null`" && {
-          tc_reset=`tput sgr0`
-          test -n "`tput bold 2>/dev/null`" && tc_bold=`tput bold`
-          tc_standout=$tc_bold
-          test -n "`tput smso 2>/dev/null`" && tc_standout=`tput smso`
-          test -n "`tput setaf 1 2>/dev/null`" && tc_red=`tput setaf 1`
-          test -n "`tput setaf 2 2>/dev/null`" && tc_green=`tput setaf 2`
-          test -n "`tput setaf 4 2>/dev/null`" && tc_blue=`tput setaf 4`
-          test -n "`tput setaf 5 2>/dev/null`" && tc_cyan=`tput setaf 5`
-        }
-      fi
-    }
+    func_error ${1+"$@"}
+    exit $EXIT_FAILURE
+}
 
-    require_term_colors=:
+# func_fatal_help arg...
+# Echo program name prefixed message to standard error, followed by
+# a help hint, and exit.
+func_fatal_help ()
+{
+    func_error ${1+"$@"}
+    func_fatal_error "$help"
 }
+help="Try \`$progname --help' for more information."  ## default
 
 
-## ----------------- ##
-## Function library. ##
-## ----------------- ##
-
-# This section contains a variety of useful functions to call in your
-# scripts. Take note of the portable wrappers for features provided by
-# some modern shells, which will fall back to slower equivalents on
-# less featureful shells.
-
-
-# func_append VAR VALUE
-# ---------------------
-# Append VALUE onto the existing contents of VAR.
-
-  # We should try to minimise forks, especially on Windows where they are
-  # unreasonably slow, so skip the feature probes when bash or zsh are
-  # being used:
-  if test set = "${BASH_VERSION+set}${ZSH_VERSION+set}"; then
-    : ${_G_HAVE_ARITH_OP="yes"}
-    : ${_G_HAVE_XSI_OPS="yes"}
-    # The += operator was introduced in bash 3.1
-    case $BASH_VERSION in
-      [12].* | 3.0 | 3.0*) ;;
-      *)
-        : ${_G_HAVE_PLUSEQ_OP="yes"}
-        ;;
-    esac
-  fi
-
-  # _G_HAVE_PLUSEQ_OP
-  # Can be empty, in which case the shell is probed, "yes" if += is
-  # useable or anything else if it does not work.
-  test -z "$_G_HAVE_PLUSEQ_OP" \
-    && (eval 'x=a; x+=" b"; test "a b" = "$x"') 2>/dev/null \
-    && _G_HAVE_PLUSEQ_OP=yes
-
-if test yes = "$_G_HAVE_PLUSEQ_OP"
-then
-  # This is an XSI compatible shell, allowing a faster implementation...
-  eval 'func_append ()
-  {
-    $debug_cmd
-
-    eval "$1+=\$2"
-  }'
-else
-  # ...otherwise fall back to using expr, which is often a shell builtin.
-  func_append ()
-  {
-    $debug_cmd
-
-    eval "$1=\$$1\$2"
-  }
-fi
-
-
-# func_append_quoted VAR VALUE
-# ----------------------------
-# Quote VALUE and append to the end of shell variable VAR, separated
-# by a space.
-if test yes = "$_G_HAVE_PLUSEQ_OP"; then
-  eval 'func_append_quoted ()
-  {
-    $debug_cmd
-
-    func_quote_for_eval "$2"
-    eval "$1+=\\ \$func_quote_for_eval_result"
-  }'
-else
-  func_append_quoted ()
-  {
-    $debug_cmd
-
-    func_quote_for_eval "$2"
-    eval "$1=\$$1\\ \$func_quote_for_eval_result"
-  }
-fi
-
-
-# func_append_uniq VAR VALUE
-# --------------------------
-# Append unique VALUE onto the existing contents of VAR, assuming
-# entries are delimited by the first character of VALUE.  For example:
-#
-#   func_append_uniq options " --another-option option-argument"
-#
-# will only append to $options if " --another-option option-argument "
-# is not already present somewhere in $options already (note spaces at
-# each end implied by leading space in second argument).
-func_append_uniq ()
-{
-    $debug_cmd
-
-    eval _G_current_value='`$ECHO $'$1'`'
-    _G_delim=`expr "$2" : '\(.\)'`
-
-    case $_G_delim$_G_current_value$_G_delim in
-      *"$2$_G_delim"*) ;;
-      *) func_append "$@" ;;
-    esac
-}
-
-
-# func_arith TERM...
-# ------------------
-# Set func_arith_result to the result of evaluating TERMs.
-  test -z "$_G_HAVE_ARITH_OP" \
-    && (eval 'test 2 = $(( 1 + 1 ))') 2>/dev/null \
-    && _G_HAVE_ARITH_OP=yes
-
-if test yes = "$_G_HAVE_ARITH_OP"; then
-  eval 'func_arith ()
-  {
-    $debug_cmd
-
-    func_arith_result=$(( $* ))
-  }'
-else
-  func_arith ()
-  {
-    $debug_cmd
-
-    func_arith_result=`expr "$@"`
-  }
-fi
-
-
-# func_basename FILE
-# ------------------
-# Set func_basename_result to FILE with everything up to and including
-# the last / stripped.
-if test yes = "$_G_HAVE_XSI_OPS"; then
-  # If this shell supports suffix pattern removal, then use it to avoid
-  # forking. Hide the definitions single quotes in case the shell chokes
-  # on unsupported syntax...
-  _b='func_basename_result=${1##*/}'
-  _d='case $1 in
-        */*) func_dirname_result=${1%/*}$2 ;;
-        *  ) func_dirname_result=$3        ;;
-      esac'
-
-else
-  # ...otherwise fall back to using sed.
-  _b='func_basename_result=`$ECHO "$1" |$SED "$sed_basename"`'
-  _d='func_dirname_result=`$ECHO "$1"  |$SED "$sed_dirname"`
-      if test "X$func_dirname_result" = "X$1"; then
-        func_dirname_result=$3
-      else
-        func_append func_dirname_result "$2"
-      fi'
-fi
-
-eval 'func_basename ()
-{
-    $debug_cmd
-
-    '"$_b"'
-}'
-
-
-# func_dirname FILE APPEND NONDIR_REPLACEMENT
-# -------------------------------------------
-# Compute the dirname of FILE.  If nonempty, add APPEND to the result,
-# otherwise set result to NONDIR_REPLACEMENT.
-eval 'func_dirname ()
-{
-    $debug_cmd
-
-    '"$_d"'
-}'
-
-
-# func_dirname_and_basename FILE APPEND NONDIR_REPLACEMENT
-# --------------------------------------------------------
-# Perform func_basename and func_dirname in a single function
-# call:
-#   dirname:  Compute the dirname of FILE.  If nonempty,
-#             add APPEND to the result, otherwise set result
-#             to NONDIR_REPLACEMENT.
-#             value returned in "$func_dirname_result"
-#   basename: Compute filename of FILE.
-#             value retuned in "$func_basename_result"
-# For efficiency, we do not delegate to the functions above but instead
-# duplicate the functionality here.
-eval 'func_dirname_and_basename ()
-{
-    $debug_cmd
-
-    '"$_b"'
-    '"$_d"'
-}'
-
-
-# func_echo ARG...
-# ----------------
-# Echo program name prefixed message.
-func_echo ()
-{
-    $debug_cmd
-
-    _G_message=$*
-
-    func_echo_IFS=$IFS
-    IFS=$nl
-    for _G_line in $_G_message; do
-      IFS=$func_echo_IFS
-      $ECHO "$progname: $_G_line"
-    done
-    IFS=$func_echo_IFS
-}
-
-
-# func_echo_all ARG...
-# --------------------
-# Invoke $ECHO with all args, space-separated.
-func_echo_all ()
-{
-    $ECHO "$*"
-}
-
-
-# func_echo_infix_1 INFIX ARG...
-# ------------------------------
-# Echo program name, followed by INFIX on the first line, with any
-# additional lines not showing INFIX.
-func_echo_infix_1 ()
-{
-    $debug_cmd
-
-    $require_term_colors
-
-    _G_infix=$1; shift
-    _G_indent=$_G_infix
-    _G_prefix="$progname: $_G_infix: "
-    _G_message=$*
-
-    # Strip color escape sequences before counting printable length
-    for _G_tc in "$tc_reset" "$tc_bold" "$tc_standout" "$tc_red" "$tc_green" "$tc_blue" "$tc_cyan"
-    do
-      test -n "$_G_tc" && {
-        _G_esc_tc=`$ECHO "$_G_tc" | $SED "$sed_make_literal_regex"`
-        _G_indent=`$ECHO "$_G_indent" | $SED "s|$_G_esc_tc||g"`
-      }
-    done
-    _G_indent="$progname: "`echo "$_G_indent" | $SED 's|.| |g'`"  " ## exclude from sc_prohibit_nested_quotes
-
-    func_echo_infix_1_IFS=$IFS
-    IFS=$nl
-    for _G_line in $_G_message; do
-      IFS=$func_echo_infix_1_IFS
-      $ECHO "$_G_prefix$tc_bold$_G_line$tc_reset" >&2
-      _G_prefix=$_G_indent
-    done
-    IFS=$func_echo_infix_1_IFS
-}
-
-
-# func_error ARG...
-# -----------------
-# Echo program name prefixed message to standard error.
-func_error ()
-{
-    $debug_cmd
-
-    $require_term_colors
-
-    func_echo_infix_1 "  $tc_standout${tc_red}error$tc_reset" "$*" >&2
-}
-
-
-# func_fatal_error ARG...
-# -----------------------
-# Echo program name prefixed message to standard error, and exit.
-func_fatal_error ()
-{
-    $debug_cmd
-
-    func_error "$*"
-    exit $EXIT_FAILURE
-}
-
-
-# func_grep EXPRESSION FILENAME
-# -----------------------------
+# func_grep expression filename
 # Check whether EXPRESSION matches any line of FILENAME, without output.
 func_grep ()
 {
-    $debug_cmd
-
     $GREP "$1" "$2" >/dev/null 2>&1
 }
 
 
-# func_len STRING
-# ---------------
-# Set func_len_result to the length of STRING. STRING may not
-# start with a hyphen.
-  test -z "$_G_HAVE_XSI_OPS" \
-    && (eval 'x=a/b/c;
-      test 5aa/bb/cc = "${#x}${x%%/*}${x%/*}${x#*/}${x##*/}"') 2>/dev/null \
-    && _G_HAVE_XSI_OPS=yes
-
-if test yes = "$_G_HAVE_XSI_OPS"; then
-  eval 'func_len ()
-  {
-    $debug_cmd
-
-    func_len_result=${#1}
-  }'
-else
-  func_len ()
-  {
-    $debug_cmd
-
-    func_len_result=`expr "$1" : ".*" 2>/dev/null || echo $max_cmd_len`
-  }
-fi
-
-
-# func_mkdir_p DIRECTORY-PATH
-# ---------------------------
+# func_mkdir_p directory-path
 # Make sure the entire path to DIRECTORY-PATH is available.
 func_mkdir_p ()
 {
-    $debug_cmd
-
-    _G_directory_path=$1
-    _G_dir_list=
+    my_directory_path="$1"
+    my_dir_list=
 
-    if test -n "$_G_directory_path" && test : != "$opt_dry_run"; then
+    if test -n "$my_directory_path" && test "$opt_dry_run" != ":"; then
 
-      # Protect directory names starting with '-'
-      case $_G_directory_path in
-        -*) _G_directory_path=./$_G_directory_path ;;
+      # Protect directory names starting with `-'
+      case $my_directory_path in
+        -*) my_directory_path="./$my_directory_path" ;;
       esac
 
       # While some portion of DIR does not yet exist...
-      while test ! -d "$_G_directory_path"; do
+      while test ! -d "$my_directory_path"; do
         # ...make a list in topmost first order.  Use a colon delimited
 	# list incase some portion of path contains whitespace.
-        _G_dir_list=$_G_directory_path:$_G_dir_list
+        my_dir_list="$my_directory_path:$my_dir_list"
 
         # If the last portion added has no slash in it, the list is done
-        case $_G_directory_path in */*) ;; *) break ;; esac
+        case $my_directory_path in */*) ;; *) break ;; esac
 
         # ...otherwise throw away the child directory and loop
-        _G_directory_path=`$ECHO "$_G_directory_path" | $SED -e "$sed_dirname"`
+        my_directory_path=`$ECHO "$my_directory_path" | $SED -e "$dirname"`
       done
-      _G_dir_list=`$ECHO "$_G_dir_list" | $SED 's|:*$||'`
+      my_dir_list=`$ECHO "$my_dir_list" | $SED 's,:*$,,'`
 
-      func_mkdir_p_IFS=$IFS; IFS=:
-      for _G_dir in $_G_dir_list; do
-	IFS=$func_mkdir_p_IFS
-        # mkdir can fail with a 'File exist' error if two processes
+      save_mkdir_p_IFS="$IFS"; IFS=':'
+      for my_dir in $my_dir_list; do
+	IFS="$save_mkdir_p_IFS"
+        # mkdir can fail with a `File exist' error if two processes
         # try to create one of the directories concurrently.  Don't
         # stop in that case!
-        $MKDIR "$_G_dir" 2>/dev/null || :
+        $MKDIR "$my_dir" 2>/dev/null || :
       done
-      IFS=$func_mkdir_p_IFS
+      IFS="$save_mkdir_p_IFS"
 
       # Bail out if we (or some other process) failed to create a directory.
-      test -d "$_G_directory_path" || \
-        func_fatal_error "Failed to create '$1'"
+      test -d "$my_directory_path" || \
+        func_fatal_error "Failed to create \`$1'"
     fi
 }
 
 
-# func_mktempdir [BASENAME]
-# -------------------------
+# func_mktempdir [string]
 # Make a temporary directory that won't clash with other running
 # libtool processes, and avoids race conditions if possible.  If
-# given, BASENAME is the basename for that directory.
+# given, STRING is the basename for that directory.
 func_mktempdir ()
 {
-    $debug_cmd
+    my_template="${TMPDIR-/tmp}/${1-$progname}"
 
-    _G_template=${TMPDIR-/tmp}/${1-$progname}
-
-    if test : = "$opt_dry_run"; then
+    if test "$opt_dry_run" = ":"; then
       # Return a directory name, but don't create it in dry-run mode
-      _G_tmpdir=$_G_template-$$
+      my_tmpdir="${my_template}-$$"
     else
 
       # If mktemp works, use that first and foremost
-      _G_tmpdir=`mktemp -d "$_G_template-XXXXXXXX" 2>/dev/null`
+      my_tmpdir=`mktemp -d "${my_template}-XXXXXXXX" 2>/dev/null`
 
-      if test ! -d "$_G_tmpdir"; then
+      if test ! -d "$my_tmpdir"; then
         # Failing that, at least try and use $RANDOM to avoid a race
-        _G_tmpdir=$_G_template-${RANDOM-0}$$
+        my_tmpdir="${my_template}-${RANDOM-0}$$"
 
-        func_mktempdir_umask=`umask`
+        save_mktempdir_umask=`umask`
         umask 0077
-        $MKDIR "$_G_tmpdir"
-        umask $func_mktempdir_umask
+        $MKDIR "$my_tmpdir"
+        umask $save_mktempdir_umask
       fi
 
       # If we're not in dry-run mode, bomb out on failure
-      test -d "$_G_tmpdir" || \
-        func_fatal_error "cannot create temporary directory '$_G_tmpdir'"
-    fi
-
-    $ECHO "$_G_tmpdir"
-}
-
-
-# func_normal_abspath PATH
-# ------------------------
-# Remove doubled-up and trailing slashes, "." path components,
-# and cancel out any ".." path components in PATH after making
-# it an absolute path.
-func_normal_abspath ()
-{
-    $debug_cmd
-
-    # These SED scripts presuppose an absolute path with a trailing slash.
-    _G_pathcar='s|^/\([^/]*\).*$|\1|'
-    _G_pathcdr='s|^/[^/]*||'
-    _G_removedotparts=':dotsl
-		s|/\./|/|g
-		t dotsl
-		s|/\.$|/|'
-    _G_collapseslashes='s|/\{1,\}|/|g'
-    _G_finalslash='s|/*$|/|'
-
-    # Start from root dir and reassemble the path.
-    func_normal_abspath_result=
-    func_normal_abspath_tpath=$1
-    func_normal_abspath_altnamespace=
-    case $func_normal_abspath_tpath in
-      "")
-        # Empty path, that just means $cwd.
-        func_stripname '' '/' "`pwd`"
-        func_normal_abspath_result=$func_stripname_result
-        return
-        ;;
-      # The next three entries are used to spot a run of precisely
-      # two leading slashes without using negated character classes;
-      # we take advantage of case's first-match behaviour.
-      ///*)
-        # Unusual form of absolute path, do nothing.
-        ;;
-      //*)
-        # Not necessarily an ordinary path; POSIX reserves leading '//'
-        # and for example Cygwin uses it to access remote file shares
-        # over CIFS/SMB, so we conserve a leading double slash if found.
-        func_normal_abspath_altnamespace=/
-        ;;
-      /*)
-        # Absolute path, do nothing.
-        ;;
-      *)
-        # Relative path, prepend $cwd.
-        func_normal_abspath_tpath=`pwd`/$func_normal_abspath_tpath
-        ;;
-    esac
-
-    # Cancel out all the simple stuff to save iterations.  We also want
-    # the path to end with a slash for ease of parsing, so make sure
-    # there is one (and only one) here.
-    func_normal_abspath_tpath=`$ECHO "$func_normal_abspath_tpath" | $SED \
-          -e "$_G_removedotparts" -e "$_G_collapseslashes" -e "$_G_finalslash"`
-    while :; do
-      # Processed it all yet?
-      if test / = "$func_normal_abspath_tpath"; then
-        # If we ascended to the root using ".." the result may be empty now.
-        if test -z "$func_normal_abspath_result"; then
-          func_normal_abspath_result=/
-        fi
-        break
-      fi
-      func_normal_abspath_tcomponent=`$ECHO "$func_normal_abspath_tpath" | $SED \
-          -e "$_G_pathcar"`
-      func_normal_abspath_tpath=`$ECHO "$func_normal_abspath_tpath" | $SED \
-          -e "$_G_pathcdr"`
-      # Figure out what to do with it
-      case $func_normal_abspath_tcomponent in
-        "")
-          # Trailing empty path component, ignore it.
-          ;;
-        ..)
-          # Parent dir; strip last assembled component from result.
-          func_dirname "$func_normal_abspath_result"
-          func_normal_abspath_result=$func_dirname_result
-          ;;
-        *)
-          # Actual path component, append it.
-          func_append func_normal_abspath_result "/$func_normal_abspath_tcomponent"
-          ;;
-      esac
-    done
-    # Restore leading double-slash if one was found on entry.
-    func_normal_abspath_result=$func_normal_abspath_altnamespace$func_normal_abspath_result
-}
-
-
-# func_notquiet ARG...
-# --------------------
-# Echo program name prefixed message only when not in quiet mode.
-func_notquiet ()
-{
-    $debug_cmd
-
-    $opt_quiet || func_echo ${1+"$@"}
-
-    # A bug in bash halts the script if the last line of a function
-    # fails when set -e is in force, so we need another command to
-    # work around that:
-    :
-}
-
-
-# func_relative_path SRCDIR DSTDIR
-# --------------------------------
-# Set func_relative_path_result to the relative path from SRCDIR to DSTDIR.
-func_relative_path ()
-{
-    $debug_cmd
-
-    func_relative_path_result=
-    func_normal_abspath "$1"
-    func_relative_path_tlibdir=$func_normal_abspath_result
-    func_normal_abspath "$2"
-    func_relative_path_tbindir=$func_normal_abspath_result
-
-    # Ascend the tree starting from libdir
-    while :; do
-      # check if we have found a prefix of bindir
-      case $func_relative_path_tbindir in
-        $func_relative_path_tlibdir)
-          # found an exact match
-          func_relative_path_tcancelled=
-          break
-          ;;
-        $func_relative_path_tlibdir*)
-          # found a matching prefix
-          func_stripname "$func_relative_path_tlibdir" '' "$func_relative_path_tbindir"
-          func_relative_path_tcancelled=$func_stripname_result
-          if test -z "$func_relative_path_result"; then
-            func_relative_path_result=.
-          fi
-          break
-          ;;
-        *)
-          func_dirname $func_relative_path_tlibdir
-          func_relative_path_tlibdir=$func_dirname_result
-          if test -z "$func_relative_path_tlibdir"; then
-            # Have to descend all the way to the root!
-            func_relative_path_result=../$func_relative_path_result
-            func_relative_path_tcancelled=$func_relative_path_tbindir
-            break
-          fi
-          func_relative_path_result=../$func_relative_path_result
-          ;;
-      esac
-    done
-
-    # Now calculate path; take care to avoid doubling-up slashes.
-    func_stripname '' '/' "$func_relative_path_result"
-    func_relative_path_result=$func_stripname_result
-    func_stripname '/' '/' "$func_relative_path_tcancelled"
-    if test -n "$func_stripname_result"; then
-      func_append func_relative_path_result "/$func_stripname_result"
-    fi
-
-    # Normalisation. If bindir is libdir, return '.' else relative path.
-    if test -n "$func_relative_path_result"; then
-      func_stripname './' '' "$func_relative_path_result"
-      func_relative_path_result=$func_stripname_result
-    fi
-
-    test -n "$func_relative_path_result" || func_relative_path_result=.
-
-    :
-}
-
-
-# func_quote_for_eval ARG...
-# --------------------------
-# Aesthetically quote ARGs to be evaled later.
-# This function returns two values:
-#   i) func_quote_for_eval_result
-#      double-quoted, suitable for a subsequent eval
-#  ii) func_quote_for_eval_unquoted_result
-#      has all characters that are still active within double
-#      quotes backslashified.
-func_quote_for_eval ()
-{
-    $debug_cmd
-
-    func_quote_for_eval_unquoted_result=
-    func_quote_for_eval_result=
-    while test 0 -lt $#; do
-      case $1 in
-        *[\\\`\"\$]*)
-	  _G_unquoted_arg=`printf '%s\n' "$1" |$SED "$sed_quote_subst"` ;;
-        *)
-          _G_unquoted_arg=$1 ;;
-      esac
-      if test -n "$func_quote_for_eval_unquoted_result"; then
-	func_append func_quote_for_eval_unquoted_result " $_G_unquoted_arg"
-      else
-        func_append func_quote_for_eval_unquoted_result "$_G_unquoted_arg"
-      fi
-
-      case $_G_unquoted_arg in
-        # Double-quote args containing shell metacharacters to delay
-        # word splitting, command substitution and variable expansion
-        # for a subsequent eval.
-        # Many Bourne shells cannot handle close brackets correctly
-        # in scan sets, so we specify it separately.
-        *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \	]*|*]*|"")
-          _G_quoted_arg=\"$_G_unquoted_arg\"
-          ;;
-        *)
-          _G_quoted_arg=$_G_unquoted_arg
-	  ;;
-      esac
-
-      if test -n "$func_quote_for_eval_result"; then
-	func_append func_quote_for_eval_result " $_G_quoted_arg"
-      else
-        func_append func_quote_for_eval_result "$_G_quoted_arg"
-      fi
-      shift
-    done
-}
-
-
-# func_quote_for_expand ARG
-# -------------------------
-# Aesthetically quote ARG to be evaled later; same as above,
-# but do not quote variable references.
-func_quote_for_expand ()
-{
-    $debug_cmd
-
-    case $1 in
-      *[\\\`\"]*)
-	_G_arg=`$ECHO "$1" | $SED \
-	    -e "$sed_double_quote_subst" -e "$sed_double_backslash"` ;;
-      *)
-        _G_arg=$1 ;;
-    esac
-
-    case $_G_arg in
-      # Double-quote args containing shell metacharacters to delay
-      # word splitting and command substitution for a subsequent eval.
-      # Many Bourne shells cannot handle close brackets correctly
-      # in scan sets, so we specify it separately.
-      *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \	]*|*]*|"")
-        _G_arg=\"$_G_arg\"
-        ;;
-    esac
-
-    func_quote_for_expand_result=$_G_arg
-}
-
-
-# func_stripname PREFIX SUFFIX NAME
-# ---------------------------------
-# strip PREFIX and SUFFIX from NAME, and store in func_stripname_result.
-# PREFIX and SUFFIX must not contain globbing or regex special
-# characters, hashes, percent signs, but SUFFIX may contain a leading
-# dot (in which case that matches only a dot).
-if test yes = "$_G_HAVE_XSI_OPS"; then
-  eval 'func_stripname ()
-  {
-    $debug_cmd
-
-    # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are
-    # positional parameters, so assign one to ordinary variable first.
-    func_stripname_result=$3
-    func_stripname_result=${func_stripname_result#"$1"}
-    func_stripname_result=${func_stripname_result%"$2"}
-  }'
-else
-  func_stripname ()
-  {
-    $debug_cmd
-
-    case $2 in
-      .*) func_stripname_result=`$ECHO "$3" | $SED -e "s%^$1%%" -e "s%\\\\$2\$%%"`;;
-      *)  func_stripname_result=`$ECHO "$3" | $SED -e "s%^$1%%" -e "s%$2\$%%"`;;
-    esac
-  }
-fi
-
-
-# func_show_eval CMD [FAIL_EXP]
-# -----------------------------
-# Unless opt_quiet is true, then output CMD.  Then, if opt_dryrun is
-# not true, evaluate CMD.  If the evaluation of CMD fails, and FAIL_EXP
-# is given, then evaluate it.
-func_show_eval ()
-{
-    $debug_cmd
-
-    _G_cmd=$1
-    _G_fail_exp=${2-':'}
-
-    func_quote_for_expand "$_G_cmd"
-    eval "func_notquiet $func_quote_for_expand_result"
-
-    $opt_dry_run || {
-      eval "$_G_cmd"
-      _G_status=$?
-      if test 0 -ne "$_G_status"; then
-	eval "(exit $_G_status); $_G_fail_exp"
-      fi
-    }
-}
-
-
-# func_show_eval_locale CMD [FAIL_EXP]
-# ------------------------------------
-# Unless opt_quiet is true, then output CMD.  Then, if opt_dryrun is
-# not true, evaluate CMD.  If the evaluation of CMD fails, and FAIL_EXP
-# is given, then evaluate it.  Use the saved locale for evaluation.
-func_show_eval_locale ()
-{
-    $debug_cmd
-
-    _G_cmd=$1
-    _G_fail_exp=${2-':'}
-
-    $opt_quiet || {
-      func_quote_for_expand "$_G_cmd"
-      eval "func_echo $func_quote_for_expand_result"
-    }
-
-    $opt_dry_run || {
-      eval "$_G_user_locale
-	    $_G_cmd"
-      _G_status=$?
-      eval "$_G_safe_locale"
-      if test 0 -ne "$_G_status"; then
-	eval "(exit $_G_status); $_G_fail_exp"
-      fi
-    }
-}
-
-
-# func_tr_sh
-# ----------
-# Turn $1 into a string suitable for a shell variable name.
-# Result is stored in $func_tr_sh_result.  All characters
-# not in the set a-zA-Z0-9_ are replaced with '_'. Further,
-# if $1 begins with a digit, a '_' is prepended as well.
-func_tr_sh ()
-{
-    $debug_cmd
-
-    case $1 in
-    [0-9]* | *[!a-zA-Z0-9_]*)
-      func_tr_sh_result=`$ECHO "$1" | $SED -e 's/^\([0-9]\)/_\1/' -e 's/[^a-zA-Z0-9_]/_/g'`
-      ;;
-    * )
-      func_tr_sh_result=$1
-      ;;
-    esac
-}
-
-
-# func_verbose ARG...
-# -------------------
-# Echo program name prefixed message in verbose mode only.
-func_verbose ()
-{
-    $debug_cmd
-
-    $opt_verbose && func_echo "$*"
-
-    :
-}
-
-
-# func_warn_and_continue ARG...
-# -----------------------------
-# Echo program name prefixed warning message to standard error.
-func_warn_and_continue ()
-{
-    $debug_cmd
-
-    $require_term_colors
-
-    func_echo_infix_1 "${tc_red}warning$tc_reset" "$*" >&2
-}
-
-
-# func_warning CATEGORY ARG...
-# ----------------------------
-# Echo program name prefixed warning message to standard error. Warning
-# messages can be filtered according to CATEGORY, where this function
-# elides messages where CATEGORY is not listed in the global variable
-# 'opt_warning_types'.
-func_warning ()
-{
-    $debug_cmd
-
-    # CATEGORY must be in the warning_categories list!
-    case " $warning_categories " in
-      *" $1 "*) ;;
-      *) func_internal_error "invalid warning category '$1'" ;;
-    esac
-
-    _G_category=$1
-    shift
-
-    case " $opt_warning_types " in
-      *" $_G_category "*) $warning_func ${1+"$@"} ;;
-    esac
-}
-
-
-# func_sort_ver VER1 VER2
-# -----------------------
-# 'sort -V' is not generally available.
-# Note this deviates from the version comparison in automake
-# in that it treats 1.5 < 1.5.0, and treats 1.4.4a < 1.4-p3a
-# but this should suffice as we won't be specifying old
-# version formats or redundant trailing .0 in bootstrap.conf.
-# If we did want full compatibility then we should probably
-# use m4_version_compare from autoconf.
-func_sort_ver ()
-{
-    $debug_cmd
-
-    printf '%s\n%s\n' "$1" "$2" \
-      | sort -t. -k 1,1n -k 2,2n -k 3,3n -k 4,4n -k 5,5n -k 6,6n -k 7,7n -k 8,8n -k 9,9n
-}
-
-# func_lt_ver PREV CURR
-# ---------------------
-# Return true if PREV and CURR are in the correct order according to
-# func_sort_ver, otherwise false.  Use it like this:
-#
-#  func_lt_ver "$prev_ver" "$proposed_ver" || func_fatal_error "..."
-func_lt_ver ()
-{
-    $debug_cmd
-
-    test "x$1" = x`func_sort_ver "$1" "$2" | $SED 1q`
-}
-
-
-# Local variables:
-# mode: shell-script
-# sh-indentation: 2
-# eval: (add-hook 'before-save-hook 'time-stamp)
-# time-stamp-pattern: "10/scriptversion=%:y-%02m-%02d.%02H; # UTC"
-# time-stamp-time-zone: "UTC"
-# End:
-#! /bin/sh
-
-# Set a version string for this script.
-scriptversion=2014-01-07.03; # UTC
-
-# A portable, pluggable option parser for Bourne shell.
-# Written by Gary V. Vaughan, 2010
-
-# Copyright (C) 2010-2015 Free Software Foundation, Inc.
-# This is free software; see the source for copying conditions.  There is NO
-# warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-
-# You should have received a copy of the GNU General Public License
-# along with this program.  If not, see <http://www.gnu.org/licenses/>.
-
-# Please report bugs or propose patches to gary at gnu.org.
-
-
-## ------ ##
-## Usage. ##
-## ------ ##
-
-# This file is a library for parsing options in your shell scripts along
-# with assorted other useful supporting features that you can make use
-# of too.
-#
-# For the simplest scripts you might need only:
-#
-#   #!/bin/sh
-#   . relative/path/to/funclib.sh
-#   . relative/path/to/options-parser
-#   scriptversion=1.0
-#   func_options ${1+"$@"}
-#   eval set dummy "$func_options_result"; shift
-#   ...rest of your script...
-#
-# In order for the '--version' option to work, you will need to have a
-# suitably formatted comment like the one at the top of this file
-# starting with '# Written by ' and ending with '# warranty; '.
-#
-# For '-h' and '--help' to work, you will also need a one line
-# description of your script's purpose in a comment directly above the
-# '# Written by ' line, like the one at the top of this file.
-#
-# The default options also support '--debug', which will turn on shell
-# execution tracing (see the comment above debug_cmd below for another
-# use), and '--verbose' and the func_verbose function to allow your script
-# to display verbose messages only when your user has specified
-# '--verbose'.
-#
-# After sourcing this file, you can plug processing for additional
-# options by amending the variables from the 'Configuration' section
-# below, and following the instructions in the 'Option parsing'
-# section further down.
-
-## -------------- ##
-## Configuration. ##
-## -------------- ##
-
-# You should override these variables in your script after sourcing this
-# file so that they reflect the customisations you have added to the
-# option parser.
-
-# The usage line for option parsing errors and the start of '-h' and
-# '--help' output messages. You can embed shell variables for delayed
-# expansion at the time the message is displayed, but you will need to
-# quote other shell meta-characters carefully to prevent them being
-# expanded when the contents are evaled.
-usage='$progpath [OPTION]...'
-
-# Short help message in response to '-h' and '--help'.  Add to this or
-# override it after sourcing this library to reflect the full set of
-# options your script accepts.
-usage_message="\
-       --debug        enable verbose shell tracing
-   -W, --warnings=CATEGORY
-                      report the warnings falling in CATEGORY [all]
-   -v, --verbose      verbosely report processing
-       --version      print version information and exit
-   -h, --help         print short or long help message and exit
-"
-
-# Additional text appended to 'usage_message' in response to '--help'.
-long_help_message="
-Warning categories include:
-       'all'          show all warnings
-       'none'         turn off all the warnings
-       'error'        warnings are treated as fatal errors"
-
-# Help message printed before fatal option parsing errors.
-fatal_help="Try '\$progname --help' for more information."
-
-
-
-## ------------------------- ##
-## Hook function management. ##
-## ------------------------- ##
-
-# This section contains functions for adding, removing, and running hooks
-# to the main code.  A hook is just a named list of of function, that can
-# be run in order later on.
-
-# func_hookable FUNC_NAME
-# -----------------------
-# Declare that FUNC_NAME will run hooks added with
-# 'func_add_hook FUNC_NAME ...'.
-func_hookable ()
-{
-    $debug_cmd
-
-    func_append hookable_fns " $1"
-}
-
-
-# func_add_hook FUNC_NAME HOOK_FUNC
-# ---------------------------------
-# Request that FUNC_NAME call HOOK_FUNC before it returns.  FUNC_NAME must
-# first have been declared "hookable" by a call to 'func_hookable'.
-func_add_hook ()
-{
-    $debug_cmd
-
-    case " $hookable_fns " in
-      *" $1 "*) ;;
-      *) func_fatal_error "'$1' does not accept hook functions." ;;
-    esac
-
-    eval func_append ${1}_hooks '" $2"'
-}
-
-
-# func_remove_hook FUNC_NAME HOOK_FUNC
-# ------------------------------------
-# Remove HOOK_FUNC from the list of functions called by FUNC_NAME.
-func_remove_hook ()
-{
-    $debug_cmd
-
-    eval ${1}_hooks='`$ECHO "\$'$1'_hooks" |$SED "s| '$2'||"`'
-}
-
-
-# func_run_hooks FUNC_NAME [ARG]...
-# ---------------------------------
-# Run all hook functions registered to FUNC_NAME.
-# It is assumed that the list of hook functions contains nothing more
-# than a whitespace-delimited list of legal shell function names, and
-# no effort is wasted trying to catch shell meta-characters or preserve
-# whitespace.
-func_run_hooks ()
-{
-    $debug_cmd
-
-    case " $hookable_fns " in
-      *" $1 "*) ;;
-      *) func_fatal_error "'$1' does not support hook funcions.n" ;;
-    esac
-
-    eval _G_hook_fns=\$$1_hooks; shift
-
-    for _G_hook in $_G_hook_fns; do
-      eval $_G_hook '"$@"'
-
-      # store returned options list back into positional
-      # parameters for next 'cmd' execution.
-      eval _G_hook_result=\$${_G_hook}_result
-      eval set dummy "$_G_hook_result"; shift
-    done
-
-    func_quote_for_eval ${1+"$@"}
-    func_run_hooks_result=$func_quote_for_eval_result
-}
-
-
-
-## --------------- ##
-## Option parsing. ##
-## --------------- ##
-
-# In order to add your own option parsing hooks, you must accept the
-# full positional parameter list in your hook function, remove any
-# options that you action, and then pass back the remaining unprocessed
-# options in '<hooked_function_name>_result', escaped suitably for
-# 'eval'.  Like this:
-#
-#    my_options_prep ()
-#    {
-#        $debug_cmd
-#
-#        # Extend the existing usage message.
-#        usage_message=$usage_message'
-#      -s, --silent       don'\''t print informational messages
-#    '
-#
-#        func_quote_for_eval ${1+"$@"}
-#        my_options_prep_result=$func_quote_for_eval_result
-#    }
-#    func_add_hook func_options_prep my_options_prep
-#
-#
-#    my_silent_option ()
-#    {
-#        $debug_cmd
-#
-#        # Note that for efficiency, we parse as many options as we can
-#        # recognise in a loop before passing the remainder back to the
-#        # caller on the first unrecognised argument we encounter.
-#        while test $# -gt 0; do
-#          opt=$1; shift
-#          case $opt in
-#            --silent|-s) opt_silent=: ;;
-#            # Separate non-argument short options:
-#            -s*)         func_split_short_opt "$_G_opt"
-#                         set dummy "$func_split_short_opt_name" \
-#                             "-$func_split_short_opt_arg" ${1+"$@"}
-#                         shift
-#                         ;;
-#            *)            set dummy "$_G_opt" "$*"; shift; break ;;
-#          esac
-#        done
-#
-#        func_quote_for_eval ${1+"$@"}
-#        my_silent_option_result=$func_quote_for_eval_result
-#    }
-#    func_add_hook func_parse_options my_silent_option
-#
-#
-#    my_option_validation ()
-#    {
-#        $debug_cmd
-#
-#        $opt_silent && $opt_verbose && func_fatal_help "\
-#    '--silent' and '--verbose' options are mutually exclusive."
-#
-#        func_quote_for_eval ${1+"$@"}
-#        my_option_validation_result=$func_quote_for_eval_result
-#    }
-#    func_add_hook func_validate_options my_option_validation
-#
-# You'll alse need to manually amend $usage_message to reflect the extra
-# options you parse.  It's preferable to append if you can, so that
-# multiple option parsing hooks can be added safely.
-
-
-# func_options [ARG]...
-# ---------------------
-# All the functions called inside func_options are hookable. See the
-# individual implementations for details.
-func_hookable func_options
-func_options ()
-{
-    $debug_cmd
-
-    func_options_prep ${1+"$@"}
-    eval func_parse_options \
-        ${func_options_prep_result+"$func_options_prep_result"}
-    eval func_validate_options \
-        ${func_parse_options_result+"$func_parse_options_result"}
-
-    eval func_run_hooks func_options \
-        ${func_validate_options_result+"$func_validate_options_result"}
+      test -d "$my_tmpdir" || \
+        func_fatal_error "cannot create temporary directory \`$my_tmpdir'"
+    fi
 
-    # save modified positional parameters for caller
-    func_options_result=$func_run_hooks_result
+    $ECHO "$my_tmpdir"
 }
 
 
-# func_options_prep [ARG]...
-# --------------------------
-# All initialisations required before starting the option parse loop.
-# Note that when calling hook functions, we pass through the list of
-# positional parameters.  If a hook function modifies that list, and
-# needs to propogate that back to rest of this script, then the complete
-# modified list must be put in 'func_run_hooks_result' before
-# returning.
-func_hookable func_options_prep
-func_options_prep ()
+# func_quote_for_eval arg
+# Aesthetically quote ARG to be evaled later.
+# This function returns two values: FUNC_QUOTE_FOR_EVAL_RESULT
+# is double-quoted, suitable for a subsequent eval, whereas
+# FUNC_QUOTE_FOR_EVAL_UNQUOTED_RESULT has merely all characters
+# which are still active within double quotes backslashified.
+func_quote_for_eval ()
 {
-    $debug_cmd
-
-    # Option defaults:
-    opt_verbose=false
-    opt_warning_types=
-
-    func_run_hooks func_options_prep ${1+"$@"}
+    case $1 in
+      *[\\\`\"\$]*)
+	func_quote_for_eval_unquoted_result=`$ECHO "$1" | $SED "$sed_quote_subst"` ;;
+      *)
+        func_quote_for_eval_unquoted_result="$1" ;;
+    esac
 
-    # save modified positional parameters for caller
-    func_options_prep_result=$func_run_hooks_result
+    case $func_quote_for_eval_unquoted_result in
+      # Double-quote args containing shell metacharacters to delay
+      # word splitting, command substitution and and variable
+      # expansion for a subsequent eval.
+      # Many Bourne shells cannot handle close brackets correctly
+      # in scan sets, so we specify it separately.
+      *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \	]*|*]*|"")
+        func_quote_for_eval_result="\"$func_quote_for_eval_unquoted_result\""
+        ;;
+      *)
+        func_quote_for_eval_result="$func_quote_for_eval_unquoted_result"
+    esac
 }
 
 
-# func_parse_options [ARG]...
-# ---------------------------
-# The main option parsing loop.
-func_hookable func_parse_options
-func_parse_options ()
+# func_quote_for_expand arg
+# Aesthetically quote ARG to be evaled later; same as above,
+# but do not quote variable references.
+func_quote_for_expand ()
 {
-    $debug_cmd
-
-    func_parse_options_result=
+    case $1 in
+      *[\\\`\"]*)
+	my_arg=`$ECHO "$1" | $SED \
+	    -e "$double_quote_subst" -e "$sed_double_backslash"` ;;
+      *)
+        my_arg="$1" ;;
+    esac
 
-    # this just eases exit handling
-    while test $# -gt 0; do
-      # Defer to hook functions for initial option parsing, so they
-      # get priority in the event of reusing an option name.
-      func_run_hooks func_parse_options ${1+"$@"}
+    case $my_arg in
+      # Double-quote args containing shell metacharacters to delay
+      # word splitting and command substitution for a subsequent eval.
+      # Many Bourne shells cannot handle close brackets correctly
+      # in scan sets, so we specify it separately.
+      *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \	]*|*]*|"")
+        my_arg="\"$my_arg\""
+        ;;
+    esac
 
-      # Adjust func_parse_options positional parameters to match
-      eval set dummy "$func_run_hooks_result"; shift
+    func_quote_for_expand_result="$my_arg"
+}
 
-      # Break out of the loop if we already parsed every option.
-      test $# -gt 0 || break
 
-      _G_opt=$1
-      shift
-      case $_G_opt in
-        --debug|-x)   debug_cmd='set -x'
-                      func_echo "enabling shell trace mode"
-                      $debug_cmd
-                      ;;
-
-        --no-warnings|--no-warning|--no-warn)
-                      set dummy --warnings none ${1+"$@"}
-                      shift
-		      ;;
+# func_show_eval cmd [fail_exp]
+# Unless opt_silent is true, then output CMD.  Then, if opt_dryrun is
+# not true, evaluate CMD.  If the evaluation of CMD fails, and FAIL_EXP
+# is given, then evaluate it.
+func_show_eval ()
+{
+    my_cmd="$1"
+    my_fail_exp="${2-:}"
 
-        --warnings|--warning|-W)
-                      test $# = 0 && func_missing_arg $_G_opt && break
-                      case " $warning_categories $1" in
-                        *" $1 "*)
-                          # trailing space prevents matching last $1 above
-                          func_append_uniq opt_warning_types " $1"
-                          ;;
-                        *all)
-                          opt_warning_types=$warning_categories
-                          ;;
-                        *none)
-                          opt_warning_types=none
-                          warning_func=:
-                          ;;
-                        *error)
-                          opt_warning_types=$warning_categories
-                          warning_func=func_fatal_error
-                          ;;
-                        *)
-                          func_fatal_error \
-                             "unsupported warning category: '$1'"
-                          ;;
-                      esac
-                      shift
-                      ;;
-
-        --verbose|-v) opt_verbose=: ;;
-        --version)    func_version ;;
-        -\?|-h)       func_usage ;;
-        --help)       func_help ;;
-
-	# Separate optargs to long options (plugins may need this):
-	--*=*)        func_split_equals "$_G_opt"
-	              set dummy "$func_split_equals_lhs" \
-                          "$func_split_equals_rhs" ${1+"$@"}
-                      shift
-                      ;;
-
-       # Separate optargs to short options:
-        -W*)
-                      func_split_short_opt "$_G_opt"
-                      set dummy "$func_split_short_opt_name" \
-                          "$func_split_short_opt_arg" ${1+"$@"}
-                      shift
-                      ;;
-
-        # Separate non-argument short options:
-        -\?*|-h*|-v*|-x*)
-                      func_split_short_opt "$_G_opt"
-                      set dummy "$func_split_short_opt_name" \
-                          "-$func_split_short_opt_arg" ${1+"$@"}
-                      shift
-                      ;;
-
-        --)           break ;;
-        -*)           func_fatal_help "unrecognised option: '$_G_opt'" ;;
-        *)            set dummy "$_G_opt" ${1+"$@"}; shift; break ;;
-      esac
-    done
+    ${opt_silent-false} || {
+      func_quote_for_expand "$my_cmd"
+      eval "func_echo $func_quote_for_expand_result"
+    }
 
-    # save modified positional parameters for caller
-    func_quote_for_eval ${1+"$@"}
-    func_parse_options_result=$func_quote_for_eval_result
+    if ${opt_dry_run-false}; then :; else
+      eval "$my_cmd"
+      my_status=$?
+      if test "$my_status" -eq 0; then :; else
+	eval "(exit $my_status); $my_fail_exp"
+      fi
+    fi
 }
 
 
-# func_validate_options [ARG]...
-# ------------------------------
-# Perform any sanity checks on option settings and/or unconsumed
-# arguments.
-func_hookable func_validate_options
-func_validate_options ()
+# func_show_eval_locale cmd [fail_exp]
+# Unless opt_silent is true, then output CMD.  Then, if opt_dryrun is
+# not true, evaluate CMD.  If the evaluation of CMD fails, and FAIL_EXP
+# is given, then evaluate it.  Use the saved locale for evaluation.
+func_show_eval_locale ()
 {
-    $debug_cmd
-
-    # Display all warnings if -W was not given.
-    test -n "$opt_warning_types" || opt_warning_types=" $warning_categories"
+    my_cmd="$1"
+    my_fail_exp="${2-:}"
 
-    func_run_hooks func_validate_options ${1+"$@"}
-
-    # Bail if the options were screwed!
-    $exit_cmd $EXIT_FAILURE
+    ${opt_silent-false} || {
+      func_quote_for_expand "$my_cmd"
+      eval "func_echo $func_quote_for_expand_result"
+    }
 
-    # save modified positional parameters for caller
-    func_validate_options_result=$func_run_hooks_result
+    if ${opt_dry_run-false}; then :; else
+      eval "$lt_user_locale
+	    $my_cmd"
+      my_status=$?
+      eval "$lt_safe_locale"
+      if test "$my_status" -eq 0; then :; else
+	eval "(exit $my_status); $my_fail_exp"
+      fi
+    fi
 }
 
+# func_tr_sh
+# Turn $1 into a string suitable for a shell variable name.
+# Result is stored in $func_tr_sh_result.  All characters
+# not in the set a-zA-Z0-9_ are replaced with '_'. Further,
+# if $1 begins with a digit, a '_' is prepended as well.
+func_tr_sh ()
+{
+  case $1 in
+  [0-9]* | *[!a-zA-Z0-9_]*)
+    func_tr_sh_result=`$ECHO "$1" | $SED 's/^\([0-9]\)/_\1/; s/[^a-zA-Z0-9_]/_/g'`
+    ;;
+  * )
+    func_tr_sh_result=$1
+    ;;
+  esac
+}
 
 
-## ----------------- ##
-## Helper functions. ##
-## ----------------- ##
-
-# This section contains the helper functions used by the rest of the
-# hookable option parser framework in ascii-betical order.
+# func_version
+# Echo version message to standard output and exit.
+func_version ()
+{
+    $opt_debug
 
+    $SED -n '/(C)/!b go
+	:more
+	/\./!{
+	  N
+	  s/\n# / /
+	  b more
+	}
+	:go
+	/^# '$PROGRAM' (GNU /,/# warranty; / {
+        s/^# //
+	s/^# *$//
+        s/\((C)\)[ 0-9,-]*\( [1-9][0-9]*\)/\1\2/
+        p
+     }' < "$progpath"
+     exit $?
+}
 
-# func_fatal_help ARG...
-# ----------------------
-# Echo program name prefixed message to standard error, followed by
-# a help hint, and exit.
-func_fatal_help ()
+# func_usage
+# Echo short help message to standard output and exit.
+func_usage ()
 {
-    $debug_cmd
+    $opt_debug
 
-    eval \$ECHO \""Usage: $usage"\"
-    eval \$ECHO \""$fatal_help"\"
-    func_error ${1+"$@"}
-    exit $EXIT_FAILURE
+    $SED -n '/^# Usage:/,/^#  *.*--help/ {
+        s/^# //
+	s/^# *$//
+	s/\$progname/'$progname'/
+	p
+    }' < "$progpath"
+    echo
+    $ECHO "run \`$progname --help | more' for full usage"
+    exit $?
 }
 
-
-# func_help
-# ---------
-# Echo long help message to standard output and exit.
+# func_help [NOEXIT]
+# Echo long help message to standard output and exit,
+# unless 'noexit' is passed as argument.
 func_help ()
 {
-    $debug_cmd
-
-    func_usage_message
-    $ECHO "$long_help_message"
-    exit 0
+    $opt_debug
+
+    $SED -n '/^# Usage:/,/# Report bugs to/ {
+	:print
+        s/^# //
+	s/^# *$//
+	s*\$progname*'$progname'*
+	s*\$host*'"$host"'*
+	s*\$SHELL*'"$SHELL"'*
+	s*\$LTCC*'"$LTCC"'*
+	s*\$LTCFLAGS*'"$LTCFLAGS"'*
+	s*\$LD*'"$LD"'*
+	s/\$with_gnu_ld/'"$with_gnu_ld"'/
+	s/\$automake_version/'"`(${AUTOMAKE-automake} --version) 2>/dev/null |$SED 1q`"'/
+	s/\$autoconf_version/'"`(${AUTOCONF-autoconf} --version) 2>/dev/null |$SED 1q`"'/
+	p
+	d
+     }
+     /^# .* home page:/b print
+     /^# General help using/b print
+     ' < "$progpath"
+    ret=$?
+    if test -z "$1"; then
+      exit $ret
+    fi
 }
 
-
-# func_missing_arg ARGNAME
-# ------------------------
+# func_missing_arg argname
 # Echo program name prefixed message to standard error and set global
 # exit_cmd.
 func_missing_arg ()
 {
-    $debug_cmd
+    $opt_debug
 
-    func_error "Missing argument for '$1'."
+    func_error "missing argument for $1."
     exit_cmd=exit
 }
 
 
-# func_split_equals STRING
-# ------------------------
-# Set func_split_equals_lhs and func_split_equals_rhs shell variables after
-# splitting STRING at the '=' sign.
-test -z "$_G_HAVE_XSI_OPS" \
-    && (eval 'x=a/b/c;
-      test 5aa/bb/cc = "${#x}${x%%/*}${x%/*}${x#*/}${x##*/}"') 2>/dev/null \
-    && _G_HAVE_XSI_OPS=yes
-
-if test yes = "$_G_HAVE_XSI_OPS"
-then
-  # This is an XSI compatible shell, allowing a faster implementation...
-  eval 'func_split_equals ()
-  {
-      $debug_cmd
-
-      func_split_equals_lhs=${1%%=*}
-      func_split_equals_rhs=${1#*=}
-      test "x$func_split_equals_lhs" = "x$1" \
-        && func_split_equals_rhs=
-  }'
-else
-  # ...otherwise fall back to using expr, which is often a shell builtin.
-  func_split_equals ()
-  {
-      $debug_cmd
-
-      func_split_equals_lhs=`expr "x$1" : 'x\([^=]*\)'`
-      func_split_equals_rhs=
-      test "x$func_split_equals_lhs" = "x$1" \
-        || func_split_equals_rhs=`expr "x$1" : 'x[^=]*=\(.*\)$'`
-  }
-fi #func_split_equals
-
-
-# func_split_short_opt SHORTOPT
-# -----------------------------
+# func_split_short_opt shortopt
 # Set func_split_short_opt_name and func_split_short_opt_arg shell
 # variables after splitting SHORTOPT after the 2nd character.
-if test yes = "$_G_HAVE_XSI_OPS"
-then
-  # This is an XSI compatible shell, allowing a faster implementation...
-  eval 'func_split_short_opt ()
-  {
-      $debug_cmd
-
-      func_split_short_opt_arg=${1#??}
-      func_split_short_opt_name=${1%"$func_split_short_opt_arg"}
-  }'
-else
-  # ...otherwise fall back to using expr, which is often a shell builtin.
-  func_split_short_opt ()
-  {
-      $debug_cmd
-
-      func_split_short_opt_name=`expr "x$1" : 'x-\(.\)'`
-      func_split_short_opt_arg=`expr "x$1" : 'x-.\(.*\)$'`
-  }
-fi #func_split_short_opt
-
-
-# func_usage
-# ----------
-# Echo short help message to standard output and exit.
-func_usage ()
+func_split_short_opt ()
 {
-    $debug_cmd
+    my_sed_short_opt='1s/^\(..\).*$/\1/;q'
+    my_sed_short_rest='1s/^..\(.*\)$/\1/;q'
 
-    func_usage_message
-    $ECHO "Run '$progname --help |${PAGER-more}' for full usage"
-    exit 0
-}
+    func_split_short_opt_name=`$ECHO "$1" | $SED "$my_sed_short_opt"`
+    func_split_short_opt_arg=`$ECHO "$1" | $SED "$my_sed_short_rest"`
+} # func_split_short_opt may be replaced by extended shell implementation
 
 
-# func_usage_message
-# ------------------
-# Echo short help message to standard output.
-func_usage_message ()
+# func_split_long_opt longopt
+# Set func_split_long_opt_name and func_split_long_opt_arg shell
+# variables after splitting LONGOPT at the `=' sign.
+func_split_long_opt ()
 {
-    $debug_cmd
+    my_sed_long_opt='1s/^\(--[^=]*\)=.*/\1/;q'
+    my_sed_long_arg='1s/^--[^=]*=//'
 
-    eval \$ECHO \""Usage: $usage"\"
-    echo
-    $SED -n 's|^# ||
-        /^Written by/{
-          x;p;x
-        }
-	h
-	/^Written by/q' < "$progpath"
-    echo
-    eval \$ECHO \""$usage_message"\"
-}
+    func_split_long_opt_name=`$ECHO "$1" | $SED "$my_sed_long_opt"`
+    func_split_long_opt_arg=`$ECHO "$1" | $SED "$my_sed_long_arg"`
+} # func_split_long_opt may be replaced by extended shell implementation
 
+exit_cmd=:
 
-# func_version
-# ------------
-# Echo version message to standard output and exit.
-func_version ()
-{
-    $debug_cmd
 
-    printf '%s\n' "$progname $scriptversion"
-    $SED -n '
-        /(C)/!b go
-        :more
-        /\./!{
-          N
-          s|\n# | |
-          b more
-        }
-        :go
-        /^# Written by /,/# warranty; / {
-          s|^# ||
-          s|^# *$||
-          s|\((C)\)[ 0-9,-]*[ ,-]\([1-9][0-9]* \)|\1 \2|
-          p
-        }
-        /^# Written by / {
-          s|^# ||
-          p
-        }
-        /^warranty; /q' < "$progpath"
 
-    exit $?
-}
 
 
-# Local variables:
-# mode: shell-script
-# sh-indentation: 2
-# eval: (add-hook 'before-save-hook 'time-stamp)
-# time-stamp-pattern: "10/scriptversion=%:y-%02m-%02d.%02H; # UTC"
-# time-stamp-time-zone: "UTC"
-# End:
+magic="%%%MAGIC variable%%%"
+magic_exe="%%%MAGIC EXE variable%%%"
 
-# Set a version string.
-scriptversion='(GNU libtool) 2.4.6'
+# Global variables.
+nonopt=
+preserve_args=
+lo2o="s/\\.lo\$/.${objext}/"
+o2lo="s/\\.${objext}\$/.lo/"
+extracted_archives=
+extracted_serial=0
 
+# If this variable is set in any of the actions, the command in it
+# will be execed at the end.  This prevents here-documents from being
+# left over by shells.
+exec_cmd=
 
-# func_echo ARG...
-# ----------------
-# Libtool also displays the current mode in messages, so override
-# funclib.sh func_echo with this custom definition.
-func_echo ()
+# func_append var value
+# Append VALUE to the end of shell variable VAR.
+func_append ()
 {
-    $debug_cmd
-
-    _G_message=$*
-
-    func_echo_IFS=$IFS
-    IFS=$nl
-    for _G_line in $_G_message; do
-      IFS=$func_echo_IFS
-      $ECHO "$progname${opt_mode+: $opt_mode}: $_G_line"
-    done
-    IFS=$func_echo_IFS
-}
-
+    eval "${1}=\$${1}\${2}"
+} # func_append may be replaced by extended shell implementation
 
-# func_warning ARG...
-# -------------------
-# Libtool warnings are not categorized, so override funclib.sh
-# func_warning with this simpler definition.
-func_warning ()
+# func_append_quoted var value
+# Quote VALUE and append to the end of shell variable VAR, separated
+# by a space.
+func_append_quoted ()
 {
-    $debug_cmd
-
-    $warning_func ${1+"$@"}
-}
-
+    func_quote_for_eval "${2}"
+    eval "${1}=\$${1}\\ \$func_quote_for_eval_result"
+} # func_append_quoted may be replaced by extended shell implementation
 
-## ---------------- ##
-## Options parsing. ##
-## ---------------- ##
-
-# Hook in the functions to make sure our own options are parsed during
-# the option parsing loop.
-
-usage='$progpath [OPTION]... [MODE-ARG]...'
-
-# Short help message in response to '-h'.
-usage_message="Options:
-       --config             show all configuration variables
-       --debug              enable verbose shell tracing
-   -n, --dry-run            display commands without modifying any files
-       --features           display basic configuration information and exit
-       --mode=MODE          use operation mode MODE
-       --no-warnings        equivalent to '-Wnone'
-       --preserve-dup-deps  don't remove duplicate dependency libraries
-       --quiet, --silent    don't print informational messages
-       --tag=TAG            use configuration variables from tag TAG
-   -v, --verbose            print more informational messages than default
-       --version            print version information
-   -W, --warnings=CATEGORY  report the warnings falling in CATEGORY [all]
-   -h, --help, --help-all   print short, long, or detailed help message
-"
 
-# Additional text appended to 'usage_message' in response to '--help'.
-func_help ()
+# func_arith arithmetic-term...
+func_arith ()
 {
-    $debug_cmd
-
-    func_usage_message
-    $ECHO "$long_help_message
-
-MODE must be one of the following:
-
-       clean           remove files from the build directory
-       compile         compile a source file into a libtool object
-       execute         automatically set library path, then run a program
-       finish          complete the installation of libtool libraries
-       install         install libraries or executables
-       link            create a library or an executable
-       uninstall       remove libraries from an installed directory
-
-MODE-ARGS vary depending on the MODE.  When passed as first option,
-'--mode=MODE' may be abbreviated as 'MODE' or a unique abbreviation of that.
-Try '$progname --help --mode=MODE' for a more detailed description of MODE.
-
-When reporting a bug, please describe a test case to reproduce it and
-include the following information:
-
-       host-triplet:   $host
-       shell:          $SHELL
-       compiler:       $LTCC
-       compiler flags: $LTCFLAGS
-       linker:         $LD (gnu? $with_gnu_ld)
-       version:        $progname (GNU libtool) 2.4.6
-       automake:       `($AUTOMAKE --version) 2>/dev/null |$SED 1q`
-       autoconf:       `($AUTOCONF --version) 2>/dev/null |$SED 1q`
-
-Report bugs to <bug-libtool at gnu.org>.
-GNU libtool home page: <http://www.gnu.org/s/libtool/>.
-General help using GNU software: <http://www.gnu.org/gethelp/>."
-    exit 0
-}
+    func_arith_result=`expr "${@}"`
+} # func_arith may be replaced by extended shell implementation
 
 
-# func_lo2o OBJECT-NAME
-# ---------------------
-# Transform OBJECT-NAME from a '.lo' suffix to the platform specific
-# object suffix.
+# func_len string
+# STRING may not start with a hyphen.
+func_len ()
+{
+    func_len_result=`expr "${1}" : ".*" 2>/dev/null || echo $max_cmd_len`
+} # func_len may be replaced by extended shell implementation
 
-lo2o=s/\\.lo\$/.$objext/
-o2lo=s/\\.$objext\$/.lo/
 
-if test yes = "$_G_HAVE_XSI_OPS"; then
-  eval 'func_lo2o ()
-  {
-    case $1 in
-      *.lo) func_lo2o_result=${1%.lo}.$objext ;;
-      *   ) func_lo2o_result=$1               ;;
-    esac
-  }'
+# func_lo2o object
+func_lo2o ()
+{
+    func_lo2o_result=`$ECHO "${1}" | $SED "$lo2o"`
+} # func_lo2o may be replaced by extended shell implementation
 
-  # func_xform LIBOBJ-OR-SOURCE
-  # ---------------------------
-  # Transform LIBOBJ-OR-SOURCE from a '.o' or '.c' (or otherwise)
-  # suffix to a '.lo' libtool-object suffix.
-  eval 'func_xform ()
-  {
-    func_xform_result=${1%.*}.lo
-  }'
-else
-  # ...otherwise fall back to using sed.
-  func_lo2o ()
-  {
-    func_lo2o_result=`$ECHO "$1" | $SED "$lo2o"`
-  }
 
-  func_xform ()
-  {
-    func_xform_result=`$ECHO "$1" | $SED 's|\.[^.]*$|.lo|'`
-  }
-fi
+# func_xform libobj-or-source
+func_xform ()
+{
+    func_xform_result=`$ECHO "${1}" | $SED 's/\.[^.]*$/.lo/'`
+} # func_xform may be replaced by extended shell implementation
 
 
-# func_fatal_configuration ARG...
-# -------------------------------
+# func_fatal_configuration arg...
 # Echo program name prefixed message to standard error, followed by
 # a configuration failure hint, and exit.
 func_fatal_configuration ()
 {
-    func__fatal_error ${1+"$@"} \
-      "See the $PACKAGE documentation for more information." \
-      "Fatal configuration error."
+    func_error ${1+"$@"}
+    func_error "See the $PACKAGE documentation for more information."
+    func_fatal_error "Fatal configuration error."
 }
 
 
 # func_config
-# -----------
 # Display the configuration for all the tags in this script.
 func_config ()
 {
@@ -2149,19 +915,17 @@ func_config ()
     exit $?
 }
 
-
 # func_features
-# -------------
 # Display the features supported by this script.
 func_features ()
 {
     echo "host: $host"
-    if test yes = "$build_libtool_libs"; then
+    if test "$build_libtool_libs" = yes; then
       echo "enable shared libraries"
     else
       echo "disable shared libraries"
     fi
-    if test yes = "$build_old_libs"; then
+    if test "$build_old_libs" = yes; then
       echo "enable static libraries"
     else
       echo "disable static libraries"
@@ -2170,350 +934,314 @@ func_features ()
     exit $?
 }
 
-
-# func_enable_tag TAGNAME
-# -----------------------
+# func_enable_tag tagname
 # Verify that TAGNAME is valid, and either flag an error and exit, or
 # enable the TAGNAME tag.  We also add TAGNAME to the global $taglist
 # variable here.
 func_enable_tag ()
 {
-    # Global variable:
-    tagname=$1
+  # Global variable:
+  tagname="$1"
 
-    re_begincf="^# ### BEGIN LIBTOOL TAG CONFIG: $tagname\$"
-    re_endcf="^# ### END LIBTOOL TAG CONFIG: $tagname\$"
-    sed_extractcf=/$re_begincf/,/$re_endcf/p
+  re_begincf="^# ### BEGIN LIBTOOL TAG CONFIG: $tagname\$"
+  re_endcf="^# ### END LIBTOOL TAG CONFIG: $tagname\$"
+  sed_extractcf="/$re_begincf/,/$re_endcf/p"
 
-    # Validate tagname.
-    case $tagname in
-      *[!-_A-Za-z0-9,/]*)
-        func_fatal_error "invalid tag name: $tagname"
-        ;;
-    esac
+  # Validate tagname.
+  case $tagname in
+    *[!-_A-Za-z0-9,/]*)
+      func_fatal_error "invalid tag name: $tagname"
+      ;;
+  esac
 
-    # Don't test for the "default" C tag, as we know it's
-    # there but not specially marked.
-    case $tagname in
-        CC) ;;
+  # Don't test for the "default" C tag, as we know it's
+  # there but not specially marked.
+  case $tagname in
+    CC) ;;
     *)
-        if $GREP "$re_begincf" "$progpath" >/dev/null 2>&1; then
-	  taglist="$taglist $tagname"
-
-	  # Evaluate the configuration.  Be careful to quote the path
-	  # and the sed script, to avoid splitting on whitespace, but
-	  # also don't use non-portable quotes within backquotes within
-	  # quotes we have to do it in 2 steps:
-	  extractedcf=`$SED -n -e "$sed_extractcf" < "$progpath"`
-	  eval "$extractedcf"
-        else
-	  func_error "ignoring unknown tag $tagname"
-        fi
-        ;;
-    esac
+      if $GREP "$re_begincf" "$progpath" >/dev/null 2>&1; then
+	taglist="$taglist $tagname"
+
+	# Evaluate the configuration.  Be careful to quote the path
+	# and the sed script, to avoid splitting on whitespace, but
+	# also don't use non-portable quotes within backquotes within
+	# quotes we have to do it in 2 steps:
+	extractedcf=`$SED -n -e "$sed_extractcf" < "$progpath"`
+	eval "$extractedcf"
+      else
+	func_error "ignoring unknown tag $tagname"
+      fi
+      ;;
+  esac
 }
 
-
 # func_check_version_match
-# ------------------------
 # Ensure that we are using m4 macros, and libtool script from the same
 # release of libtool.
 func_check_version_match ()
 {
-    if test "$package_revision" != "$macro_revision"; then
-      if test "$VERSION" != "$macro_version"; then
-        if test -z "$macro_version"; then
-          cat >&2 <<_LT_EOF
+  if test "$package_revision" != "$macro_revision"; then
+    if test "$VERSION" != "$macro_version"; then
+      if test -z "$macro_version"; then
+        cat >&2 <<_LT_EOF
 $progname: Version mismatch error.  This is $PACKAGE $VERSION, but the
 $progname: definition of this LT_INIT comes from an older release.
 $progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION
 $progname: and run autoconf again.
 _LT_EOF
-        else
-          cat >&2 <<_LT_EOF
+      else
+        cat >&2 <<_LT_EOF
 $progname: Version mismatch error.  This is $PACKAGE $VERSION, but the
 $progname: definition of this LT_INIT comes from $PACKAGE $macro_version.
 $progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION
 $progname: and run autoconf again.
 _LT_EOF
-        fi
-      else
-        cat >&2 <<_LT_EOF
+      fi
+    else
+      cat >&2 <<_LT_EOF
 $progname: Version mismatch error.  This is $PACKAGE $VERSION, revision $package_revision,
 $progname: but the definition of this LT_INIT comes from revision $macro_revision.
 $progname: You should recreate aclocal.m4 with macros from revision $package_revision
 $progname: of $PACKAGE $VERSION and run autoconf again.
 _LT_EOF
-      fi
-
-      exit $EXIT_MISMATCH
     fi
-}
 
+    exit $EXIT_MISMATCH
+  fi
+}
 
-# libtool_options_prep [ARG]...
-# -----------------------------
-# Preparation for options parsed by libtool.
-libtool_options_prep ()
-{
-    $debug_mode
 
-    # Option defaults:
-    opt_config=false
-    opt_dlopen=
-    opt_dry_run=false
-    opt_help=false
-    opt_mode=
-    opt_preserve_dup_deps=false
-    opt_quiet=false
+# Shorthand for --mode=foo, only valid as the first argument
+case $1 in
+clean|clea|cle|cl)
+  shift; set dummy --mode clean ${1+"$@"}; shift
+  ;;
+compile|compil|compi|comp|com|co|c)
+  shift; set dummy --mode compile ${1+"$@"}; shift
+  ;;
+execute|execut|execu|exec|exe|ex|e)
+  shift; set dummy --mode execute ${1+"$@"}; shift
+  ;;
+finish|finis|fini|fin|fi|f)
+  shift; set dummy --mode finish ${1+"$@"}; shift
+  ;;
+install|instal|insta|inst|ins|in|i)
+  shift; set dummy --mode install ${1+"$@"}; shift
+  ;;
+link|lin|li|l)
+  shift; set dummy --mode link ${1+"$@"}; shift
+  ;;
+uninstall|uninstal|uninsta|uninst|unins|unin|uni|un|u)
+  shift; set dummy --mode uninstall ${1+"$@"}; shift
+  ;;
+esac
 
-    nonopt=
-    preserve_args=
 
-    # Shorthand for --mode=foo, only valid as the first argument
-    case $1 in
-    clean|clea|cle|cl)
-      shift; set dummy --mode clean ${1+"$@"}; shift
-      ;;
-    compile|compil|compi|comp|com|co|c)
-      shift; set dummy --mode compile ${1+"$@"}; shift
-      ;;
-    execute|execut|execu|exec|exe|ex|e)
-      shift; set dummy --mode execute ${1+"$@"}; shift
-      ;;
-    finish|finis|fini|fin|fi|f)
-      shift; set dummy --mode finish ${1+"$@"}; shift
-      ;;
-    install|instal|insta|inst|ins|in|i)
-      shift; set dummy --mode install ${1+"$@"}; shift
-      ;;
-    link|lin|li|l)
-      shift; set dummy --mode link ${1+"$@"}; shift
-      ;;
-    uninstall|uninstal|uninsta|uninst|unins|unin|uni|un|u)
-      shift; set dummy --mode uninstall ${1+"$@"}; shift
-      ;;
-    esac
 
-    # Pass back the list of options.
-    func_quote_for_eval ${1+"$@"}
-    libtool_options_prep_result=$func_quote_for_eval_result
-}
-func_add_hook func_options_prep libtool_options_prep
+# Option defaults:
+opt_debug=:
+opt_dry_run=false
+opt_config=false
+opt_preserve_dup_deps=false
+opt_features=false
+opt_finish=false
+opt_help=false
+opt_help_all=false
+opt_silent=:
+opt_warning=:
+opt_verbose=:
+opt_silent=false
+opt_verbose=false
 
 
-# libtool_parse_options [ARG]...
-# ---------------------------------
-# Provide handling for libtool specific options.
-libtool_parse_options ()
+# Parse options once, thoroughly.  This comes as soon as possible in the
+# script to make things like `--version' happen as quickly as we can.
 {
-    $debug_cmd
+  # this just eases exit handling
+  while test $# -gt 0; do
+    opt="$1"
+    shift
+    case $opt in
+      --debug|-x)	opt_debug='set -x'
+			func_echo "enabling shell trace mode"
+			$opt_debug
+			;;
+      --dry-run|--dryrun|-n)
+			opt_dry_run=:
+			;;
+      --config)
+			opt_config=:
+func_config
+			;;
+      --dlopen|-dlopen)
+			optarg="$1"
+			opt_dlopen="${opt_dlopen+$opt_dlopen
+}$optarg"
+			shift
+			;;
+      --preserve-dup-deps)
+			opt_preserve_dup_deps=:
+			;;
+      --features)
+			opt_features=:
+func_features
+			;;
+      --finish)
+			opt_finish=:
+set dummy --mode finish ${1+"$@"}; shift
+			;;
+      --help)
+			opt_help=:
+			;;
+      --help-all)
+			opt_help_all=:
+opt_help=': help-all'
+			;;
+      --mode)
+			test $# = 0 && func_missing_arg $opt && break
+			optarg="$1"
+			opt_mode="$optarg"
+case $optarg in
+  # Valid mode arguments:
+  clean|compile|execute|finish|install|link|relink|uninstall) ;;
+
+  # Catch anything else as an error
+  *) func_error "invalid argument for $opt"
+     exit_cmd=exit
+     break
+     ;;
+esac
+			shift
+			;;
+      --no-silent|--no-quiet)
+			opt_silent=false
+func_append preserve_args " $opt"
+			;;
+      --no-warning|--no-warn)
+			opt_warning=false
+func_append preserve_args " $opt"
+			;;
+      --no-verbose)
+			opt_verbose=false
+func_append preserve_args " $opt"
+			;;
+      --silent|--quiet)
+			opt_silent=:
+func_append preserve_args " $opt"
+        opt_verbose=false
+			;;
+      --verbose|-v)
+			opt_verbose=:
+func_append preserve_args " $opt"
+opt_silent=false
+			;;
+      --tag)
+			test $# = 0 && func_missing_arg $opt && break
+			optarg="$1"
+			opt_tag="$optarg"
+func_append preserve_args " $opt $optarg"
+func_enable_tag "$optarg"
+			shift
+			;;
+
+      -\?|-h)		func_usage				;;
+      --help)		func_help				;;
+      --version)	func_version				;;
+
+      # Separate optargs to long options:
+      --*=*)
+			func_split_long_opt "$opt"
+			set dummy "$func_split_long_opt_name" "$func_split_long_opt_arg" ${1+"$@"}
+			shift
+			;;
+
+      # Separate non-argument short options:
+      -\?*|-h*|-n*|-v*)
+			func_split_short_opt "$opt"
+			set dummy "$func_split_short_opt_name" "-$func_split_short_opt_arg" ${1+"$@"}
+			shift
+			;;
+
+      --)		break					;;
+      -*)		func_fatal_help "unrecognized option \`$opt'" ;;
+      *)		set dummy "$opt" ${1+"$@"};	shift; break  ;;
+    esac
+  done
 
-    # Perform our own loop to consume as many options as possible in
-    # each iteration.
-    while test $# -gt 0; do
-      _G_opt=$1
-      shift
-      case $_G_opt in
-        --dry-run|--dryrun|-n)
-                        opt_dry_run=:
-                        ;;
-
-        --config)       func_config ;;
-
-        --dlopen|-dlopen)
-                        opt_dlopen="${opt_dlopen+$opt_dlopen
-}$1"
-                        shift
-                        ;;
-
-        --preserve-dup-deps)
-                        opt_preserve_dup_deps=: ;;
-
-        --features)     func_features ;;
-
-        --finish)       set dummy --mode finish ${1+"$@"}; shift ;;
-
-        --help)         opt_help=: ;;
-
-        --help-all)     opt_help=': help-all' ;;
-
-        --mode)         test $# = 0 && func_missing_arg $_G_opt && break
-                        opt_mode=$1
-                        case $1 in
-                          # Valid mode arguments:
-                          clean|compile|execute|finish|install|link|relink|uninstall) ;;
-
-                          # Catch anything else as an error
-                          *) func_error "invalid argument for $_G_opt"
-                             exit_cmd=exit
-                             break
-                             ;;
-                        esac
-                        shift
-                        ;;
-
-        --no-silent|--no-quiet)
-                        opt_quiet=false
-                        func_append preserve_args " $_G_opt"
-                        ;;
-
-        --no-warnings|--no-warning|--no-warn)
-                        opt_warning=false
-                        func_append preserve_args " $_G_opt"
-                        ;;
-
-        --no-verbose)
-                        opt_verbose=false
-                        func_append preserve_args " $_G_opt"
-                        ;;
-
-        --silent|--quiet)
-                        opt_quiet=:
-                        opt_verbose=false
-                        func_append preserve_args " $_G_opt"
-                        ;;
-
-        --tag)          test $# = 0 && func_missing_arg $_G_opt && break
-                        opt_tag=$1
-                        func_append preserve_args " $_G_opt $1"
-                        func_enable_tag "$1"
-                        shift
-                        ;;
-
-        --verbose|-v)   opt_quiet=false
-                        opt_verbose=:
-                        func_append preserve_args " $_G_opt"
-                        ;;
-
-	# An option not handled by this hook function:
-        *)		set dummy "$_G_opt" ${1+"$@"};	shift; break  ;;
-      esac
-    done
+  # Validate options:
 
+  # save first non-option argument
+  if test "$#" -gt 0; then
+    nonopt="$opt"
+    shift
+  fi
 
-    # save modified positional parameters for caller
-    func_quote_for_eval ${1+"$@"}
-    libtool_parse_options_result=$func_quote_for_eval_result
-}
-func_add_hook func_parse_options libtool_parse_options
+  # preserve --debug
+  test "$opt_debug" = : || func_append preserve_args " --debug"
 
+  case $host in
+    *cygwin* | *mingw* | *pw32* | *cegcc*)
+      # don't eliminate duplications in $postdeps and $predeps
+      opt_duplicate_compiler_generated_deps=:
+      ;;
+    *)
+      opt_duplicate_compiler_generated_deps=$opt_preserve_dup_deps
+      ;;
+  esac
 
+  $opt_help || {
+    # Sanity checks first:
+    func_check_version_match
 
-# libtool_validate_options [ARG]...
-# ---------------------------------
-# Perform any sanity checks on option settings and/or unconsumed
-# arguments.
-libtool_validate_options ()
-{
-    # save first non-option argument
-    if test 0 -lt $#; then
-      nonopt=$1
-      shift
+    if test "$build_libtool_libs" != yes && test "$build_old_libs" != yes; then
+      func_fatal_configuration "not configured to build any kind of library"
     fi
 
-    # preserve --debug
-    test : = "$debug_cmd" || func_append preserve_args " --debug"
-
-    case $host in
-      # Solaris2 added to fix http://debbugs.gnu.org/cgi/bugreport.cgi?bug=16452
-      # see also: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=59788
-      *cygwin* | *mingw* | *pw32* | *cegcc* | *solaris2* | *os2*)
-        # don't eliminate duplications in $postdeps and $predeps
-        opt_duplicate_compiler_generated_deps=:
-        ;;
-      *)
-        opt_duplicate_compiler_generated_deps=$opt_preserve_dup_deps
-        ;;
-    esac
-
-    $opt_help || {
-      # Sanity checks first:
-      func_check_version_match
-
-      test yes != "$build_libtool_libs" \
-        && test yes != "$build_old_libs" \
-        && func_fatal_configuration "not configured to build any kind of library"
+    # Darwin sucks
+    eval std_shrext=\"$shrext_cmds\"
 
-      # Darwin sucks
-      eval std_shrext=\"$shrext_cmds\"
+    # Only execute mode is allowed to have -dlopen flags.
+    if test -n "$opt_dlopen" && test "$opt_mode" != execute; then
+      func_error "unrecognized option \`-dlopen'"
+      $ECHO "$help" 1>&2
+      exit $EXIT_FAILURE
+    fi
 
-      # Only execute mode is allowed to have -dlopen flags.
-      if test -n "$opt_dlopen" && test execute != "$opt_mode"; then
-        func_error "unrecognized option '-dlopen'"
-        $ECHO "$help" 1>&2
-        exit $EXIT_FAILURE
-      fi
+    # Change the help message to a mode-specific one.
+    generic_help="$help"
+    help="Try \`$progname --help --mode=$opt_mode' for more information."
+  }
 
-      # Change the help message to a mode-specific one.
-      generic_help=$help
-      help="Try '$progname --help --mode=$opt_mode' for more information."
-    }
 
-    # Pass back the unparsed argument list
-    func_quote_for_eval ${1+"$@"}
-    libtool_validate_options_result=$func_quote_for_eval_result
+  # Bail if the options were screwed
+  $exit_cmd $EXIT_FAILURE
 }
-func_add_hook func_validate_options libtool_validate_options
 
 
-# Process options as early as possible so that --help and --version
-# can return quickly.
-func_options ${1+"$@"}
-eval set dummy "$func_options_result"; shift
-
 
 
 ## ----------- ##
 ##    Main.    ##
 ## ----------- ##
 
-magic='%%%MAGIC variable%%%'
-magic_exe='%%%MAGIC EXE variable%%%'
-
-# Global variables.
-extracted_archives=
-extracted_serial=0
-
-# If this variable is set in any of the actions, the command in it
-# will be execed at the end.  This prevents here-documents from being
-# left over by shells.
-exec_cmd=
-
-
-# A function that is used when there is no print builtin or printf.
-func_fallback_echo ()
-{
-  eval 'cat <<_LTECHO_EOF
-$1
-_LTECHO_EOF'
-}
-
-# func_generated_by_libtool
-# True iff stdin has been generated by Libtool. This function is only
-# a basic sanity check; it will hardly flush out determined imposters.
-func_generated_by_libtool_p ()
-{
-  $GREP "^# Generated by .*$PACKAGE" > /dev/null 2>&1
-}
-
 # func_lalib_p file
-# True iff FILE is a libtool '.la' library or '.lo' object file.
+# True iff FILE is a libtool `.la' library or `.lo' object file.
 # This function is only a basic sanity check; it will hardly flush out
 # determined imposters.
 func_lalib_p ()
 {
     test -f "$1" &&
-      $SED -e 4q "$1" 2>/dev/null | func_generated_by_libtool_p
+      $SED -e 4q "$1" 2>/dev/null \
+        | $GREP "^# Generated by .*$PACKAGE" > /dev/null 2>&1
 }
 
 # func_lalib_unsafe_p file
-# True iff FILE is a libtool '.la' library or '.lo' object file.
+# True iff FILE is a libtool `.la' library or `.lo' object file.
 # This function implements the same check as func_lalib_p without
 # resorting to external programs.  To this end, it redirects stdin and
 # closes it afterwards, without saving the original file descriptor.
 # As a safety measure, use it only where a negative result would be
-# fatal anyway.  Works if 'file' does not exist.
+# fatal anyway.  Works if `file' does not exist.
 func_lalib_unsafe_p ()
 {
     lalib_p=no
@@ -2521,13 +1249,13 @@ func_lalib_unsafe_p ()
 	for lalib_p_l in 1 2 3 4
 	do
 	    read lalib_p_line
-	    case $lalib_p_line in
+	    case "$lalib_p_line" in
 		\#\ Generated\ by\ *$PACKAGE* ) lalib_p=yes; break;;
 	    esac
 	done
 	exec 0<&5 5<&-
     fi
-    test yes = "$lalib_p"
+    test "$lalib_p" = yes
 }
 
 # func_ltwrapper_script_p file
@@ -2536,8 +1264,7 @@ func_lalib_unsafe_p ()
 # determined imposters.
 func_ltwrapper_script_p ()
 {
-    test -f "$1" &&
-      $lt_truncate_bin < "$1" 2>/dev/null | func_generated_by_libtool_p
+    func_lalib_p "$1"
 }
 
 # func_ltwrapper_executable_p file
@@ -2562,7 +1289,7 @@ func_ltwrapper_scriptname ()
 {
     func_dirname_and_basename "$1" "" "."
     func_stripname '' '.exe' "$func_basename_result"
-    func_ltwrapper_scriptname_result=$func_dirname_result/$objdir/${func_stripname_result}_ltshwrapper
+    func_ltwrapper_scriptname_result="$func_dirname_result/$objdir/${func_stripname_result}_ltshwrapper"
 }
 
 # func_ltwrapper_p file
@@ -2581,13 +1308,11 @@ func_ltwrapper_p ()
 # FAIL_CMD may read-access the current command in variable CMD!
 func_execute_cmds ()
 {
-    $debug_cmd
-
+    $opt_debug
     save_ifs=$IFS; IFS='~'
     for cmd in $1; do
-      IFS=$sp$nl
-      eval cmd=\"$cmd\"
       IFS=$save_ifs
+      eval cmd=\"$cmd\"
       func_show_eval "$cmd" "${2-:}"
     done
     IFS=$save_ifs
@@ -2599,11 +1324,10 @@ func_execute_cmds ()
 # Note that it is not necessary on cygwin/mingw to append a dot to
 # FILE even if both FILE and FILE.exe exist: automatic-append-.exe
 # behavior happens only for exec(3), not for open(2)!  Also, sourcing
-# 'FILE.' does not work on cygwin managed mounts.
+# `FILE.' does not work on cygwin managed mounts.
 func_source ()
 {
-    $debug_cmd
-
+    $opt_debug
     case $1 in
     */* | *\\*)	. "$1" ;;
     *)		. "./$1" ;;
@@ -2630,10 +1354,10 @@ func_resolve_sysroot ()
 # store the result into func_replace_sysroot_result.
 func_replace_sysroot ()
 {
-  case $lt_sysroot:$1 in
+  case "$lt_sysroot:$1" in
   ?*:"$lt_sysroot"*)
     func_stripname "$lt_sysroot" '' "$1"
-    func_replace_sysroot_result='='$func_stripname_result
+    func_replace_sysroot_result="=$func_stripname_result"
     ;;
   *)
     # Including no sysroot.
@@ -2650,8 +1374,7 @@ func_replace_sysroot ()
 # arg is usually of the form 'gcc ...'
 func_infer_tag ()
 {
-    $debug_cmd
-
+    $opt_debug
     if test -n "$available_tags" && test -z "$tagname"; then
       CC_quoted=
       for arg in $CC; do
@@ -2670,7 +1393,7 @@ func_infer_tag ()
 	for z in $available_tags; do
 	  if $GREP "^# ### BEGIN LIBTOOL TAG CONFIG: $z$" < "$progpath" > /dev/null; then
 	    # Evaluate the configuration.
-	    eval "`$SED -n -e '/^# ### BEGIN LIBTOOL TAG CONFIG: '$z'$/,/^# ### END LIBTOOL TAG CONFIG: '$z'$/p' < $progpath`"
+	    eval "`${SED} -n -e '/^# ### BEGIN LIBTOOL TAG CONFIG: '$z'$/,/^# ### END LIBTOOL TAG CONFIG: '$z'$/p' < $progpath`"
 	    CC_quoted=
 	    for arg in $CC; do
 	      # Double-quote args containing other shell metacharacters.
@@ -2695,7 +1418,7 @@ func_infer_tag ()
 	# line option must be used.
 	if test -z "$tagname"; then
 	  func_echo "unable to infer tagged configuration"
-	  func_fatal_error "specify a tag with '--tag'"
+	  func_fatal_error "specify a tag with \`--tag'"
 #	else
 #	  func_verbose "using $tagname tagged configuration"
 	fi
@@ -2711,15 +1434,15 @@ func_infer_tag ()
 # but don't create it if we're doing a dry run.
 func_write_libtool_object ()
 {
-    write_libobj=$1
-    if test yes = "$build_libtool_libs"; then
-      write_lobj=\'$2\'
+    write_libobj=${1}
+    if test "$build_libtool_libs" = yes; then
+      write_lobj=\'${2}\'
     else
       write_lobj=none
     fi
 
-    if test yes = "$build_old_libs"; then
-      write_oldobj=\'$3\'
+    if test "$build_old_libs" = yes; then
+      write_oldobj=\'${3}\'
     else
       write_oldobj=none
     fi
@@ -2727,7 +1450,7 @@ func_write_libtool_object ()
     $opt_dry_run || {
       cat >${write_libobj}T <<EOF
 # $write_libobj - a libtool object file
-# Generated by $PROGRAM (GNU $PACKAGE) $VERSION
+# Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION
 #
 # Please DO NOT delete this file!
 # It is necessary for linking the library.
@@ -2739,7 +1462,7 @@ pic_object=$write_lobj
 non_pic_object=$write_oldobj
 
 EOF
-      $MV "${write_libobj}T" "$write_libobj"
+      $MV "${write_libobj}T" "${write_libobj}"
     }
 }
 
@@ -2759,9 +1482,8 @@ EOF
 # be empty on error (or when ARG is empty)
 func_convert_core_file_wine_to_w32 ()
 {
-  $debug_cmd
-
-  func_convert_core_file_wine_to_w32_result=$1
+  $opt_debug
+  func_convert_core_file_wine_to_w32_result="$1"
   if test -n "$1"; then
     # Unfortunately, winepath does not exit with a non-zero error code, so we
     # are forced to check the contents of stdout. On the other hand, if the
@@ -2769,9 +1491,9 @@ func_convert_core_file_wine_to_w32 ()
     # *an error message* to stdout. So we must check for both error code of
     # zero AND non-empty stdout, which explains the odd construction:
     func_convert_core_file_wine_to_w32_tmp=`winepath -w "$1" 2>/dev/null`
-    if test "$?" -eq 0 && test -n "$func_convert_core_file_wine_to_w32_tmp"; then
+    if test "$?" -eq 0 && test -n "${func_convert_core_file_wine_to_w32_tmp}"; then
       func_convert_core_file_wine_to_w32_result=`$ECHO "$func_convert_core_file_wine_to_w32_tmp" |
-        $SED -e "$sed_naive_backslashify"`
+        $SED -e "$lt_sed_naive_backslashify"`
     else
       func_convert_core_file_wine_to_w32_result=
     fi
@@ -2792,19 +1514,18 @@ func_convert_core_file_wine_to_w32 ()
 # are convertible, then the result may be empty.
 func_convert_core_path_wine_to_w32 ()
 {
-  $debug_cmd
-
+  $opt_debug
   # unfortunately, winepath doesn't convert paths, only file names
-  func_convert_core_path_wine_to_w32_result=
+  func_convert_core_path_wine_to_w32_result=""
   if test -n "$1"; then
     oldIFS=$IFS
     IFS=:
     for func_convert_core_path_wine_to_w32_f in $1; do
       IFS=$oldIFS
       func_convert_core_file_wine_to_w32 "$func_convert_core_path_wine_to_w32_f"
-      if test -n "$func_convert_core_file_wine_to_w32_result"; then
+      if test -n "$func_convert_core_file_wine_to_w32_result" ; then
         if test -z "$func_convert_core_path_wine_to_w32_result"; then
-          func_convert_core_path_wine_to_w32_result=$func_convert_core_file_wine_to_w32_result
+          func_convert_core_path_wine_to_w32_result="$func_convert_core_file_wine_to_w32_result"
         else
           func_append func_convert_core_path_wine_to_w32_result ";$func_convert_core_file_wine_to_w32_result"
         fi
@@ -2833,8 +1554,7 @@ func_convert_core_path_wine_to_w32 ()
 # environment variable; do not put it in $PATH.
 func_cygpath ()
 {
-  $debug_cmd
-
+  $opt_debug
   if test -n "$LT_CYGPATH" && test -f "$LT_CYGPATH"; then
     func_cygpath_result=`$LT_CYGPATH "$@" 2>/dev/null`
     if test "$?" -ne 0; then
@@ -2843,7 +1563,7 @@ func_cygpath ()
     fi
   else
     func_cygpath_result=
-    func_error "LT_CYGPATH is empty or specifies non-existent file: '$LT_CYGPATH'"
+    func_error "LT_CYGPATH is empty or specifies non-existent file: \`$LT_CYGPATH'"
   fi
 }
 #end: func_cygpath
@@ -2854,11 +1574,10 @@ func_cygpath ()
 # result in func_convert_core_msys_to_w32_result.
 func_convert_core_msys_to_w32 ()
 {
-  $debug_cmd
-
+  $opt_debug
   # awkward: cmd appends spaces to result
   func_convert_core_msys_to_w32_result=`( cmd //c echo "$1" ) 2>/dev/null |
-    $SED -e 's/[ ]*$//' -e "$sed_naive_backslashify"`
+    $SED -e 's/[ ]*$//' -e "$lt_sed_naive_backslashify"`
 }
 #end: func_convert_core_msys_to_w32
 
@@ -2869,14 +1588,13 @@ func_convert_core_msys_to_w32 ()
 # func_to_host_file_result to ARG1).
 func_convert_file_check ()
 {
-  $debug_cmd
-
-  if test -z "$2" && test -n "$1"; then
+  $opt_debug
+  if test -z "$2" && test -n "$1" ; then
     func_error "Could not determine host file name corresponding to"
-    func_error "  '$1'"
+    func_error "  \`$1'"
     func_error "Continuing, but uninstalled executables may not work."
     # Fallback:
-    func_to_host_file_result=$1
+    func_to_host_file_result="$1"
   fi
 }
 # end func_convert_file_check
@@ -2888,11 +1606,10 @@ func_convert_file_check ()
 # func_to_host_file_result to a simplistic fallback value (see below).
 func_convert_path_check ()
 {
-  $debug_cmd
-
+  $opt_debug
   if test -z "$4" && test -n "$3"; then
     func_error "Could not determine the host path corresponding to"
-    func_error "  '$3'"
+    func_error "  \`$3'"
     func_error "Continuing, but uninstalled executables may not work."
     # Fallback.  This is a deliberately simplistic "conversion" and
     # should not be "improved".  See libtool.info.
@@ -2901,7 +1618,7 @@ func_convert_path_check ()
       func_to_host_path_result=`echo "$3" |
         $SED -e "$lt_replace_pathsep_chars"`
     else
-      func_to_host_path_result=$3
+      func_to_host_path_result="$3"
     fi
   fi
 }
@@ -2913,10 +1630,9 @@ func_convert_path_check ()
 # and appending REPL if ORIG matches BACKPAT.
 func_convert_path_front_back_pathsep ()
 {
-  $debug_cmd
-
+  $opt_debug
   case $4 in
-  $1 ) func_to_host_path_result=$3$func_to_host_path_result
+  $1 ) func_to_host_path_result="$3$func_to_host_path_result"
     ;;
   esac
   case $4 in
@@ -2930,7 +1646,7 @@ func_convert_path_front_back_pathsep ()
 ##################################################
 # $build to $host FILE NAME CONVERSION FUNCTIONS #
 ##################################################
-# invoked via '$to_host_file_cmd ARG'
+# invoked via `$to_host_file_cmd ARG'
 #
 # In each case, ARG is the path to be converted from $build to $host format.
 # Result will be available in $func_to_host_file_result.
@@ -2941,8 +1657,7 @@ func_convert_path_front_back_pathsep ()
 # in func_to_host_file_result.
 func_to_host_file ()
 {
-  $debug_cmd
-
+  $opt_debug
   $to_host_file_cmd "$1"
 }
 # end func_to_host_file
@@ -2954,8 +1669,7 @@ func_to_host_file ()
 # in (the comma separated) LAZY, no conversion takes place.
 func_to_tool_file ()
 {
-  $debug_cmd
-
+  $opt_debug
   case ,$2, in
     *,"$to_tool_file_cmd",*)
       func_to_tool_file_result=$1
@@ -2973,7 +1687,7 @@ func_to_tool_file ()
 # Copy ARG to func_to_host_file_result.
 func_convert_file_noop ()
 {
-  func_to_host_file_result=$1
+  func_to_host_file_result="$1"
 }
 # end func_convert_file_noop
 
@@ -2984,12 +1698,11 @@ func_convert_file_noop ()
 # func_to_host_file_result.
 func_convert_file_msys_to_w32 ()
 {
-  $debug_cmd
-
-  func_to_host_file_result=$1
+  $opt_debug
+  func_to_host_file_result="$1"
   if test -n "$1"; then
     func_convert_core_msys_to_w32 "$1"
-    func_to_host_file_result=$func_convert_core_msys_to_w32_result
+    func_to_host_file_result="$func_convert_core_msys_to_w32_result"
   fi
   func_convert_file_check "$1" "$func_to_host_file_result"
 }
@@ -3001,9 +1714,8 @@ func_convert_file_msys_to_w32 ()
 # func_to_host_file_result.
 func_convert_file_cygwin_to_w32 ()
 {
-  $debug_cmd
-
-  func_to_host_file_result=$1
+  $opt_debug
+  func_to_host_file_result="$1"
   if test -n "$1"; then
     # because $build is cygwin, we call "the" cygpath in $PATH; no need to use
     # LT_CYGPATH in this case.
@@ -3019,12 +1731,11 @@ func_convert_file_cygwin_to_w32 ()
 # and a working winepath. Returns result in func_to_host_file_result.
 func_convert_file_nix_to_w32 ()
 {
-  $debug_cmd
-
-  func_to_host_file_result=$1
+  $opt_debug
+  func_to_host_file_result="$1"
   if test -n "$1"; then
     func_convert_core_file_wine_to_w32 "$1"
-    func_to_host_file_result=$func_convert_core_file_wine_to_w32_result
+    func_to_host_file_result="$func_convert_core_file_wine_to_w32_result"
   fi
   func_convert_file_check "$1" "$func_to_host_file_result"
 }
@@ -3036,13 +1747,12 @@ func_convert_file_nix_to_w32 ()
 # Returns result in func_to_host_file_result.
 func_convert_file_msys_to_cygwin ()
 {
-  $debug_cmd
-
-  func_to_host_file_result=$1
+  $opt_debug
+  func_to_host_file_result="$1"
   if test -n "$1"; then
     func_convert_core_msys_to_w32 "$1"
     func_cygpath -u "$func_convert_core_msys_to_w32_result"
-    func_to_host_file_result=$func_cygpath_result
+    func_to_host_file_result="$func_cygpath_result"
   fi
   func_convert_file_check "$1" "$func_to_host_file_result"
 }
@@ -3055,14 +1765,13 @@ func_convert_file_msys_to_cygwin ()
 # in func_to_host_file_result.
 func_convert_file_nix_to_cygwin ()
 {
-  $debug_cmd
-
-  func_to_host_file_result=$1
+  $opt_debug
+  func_to_host_file_result="$1"
   if test -n "$1"; then
     # convert from *nix to w32, then use cygpath to convert from w32 to cygwin.
     func_convert_core_file_wine_to_w32 "$1"
     func_cygpath -u "$func_convert_core_file_wine_to_w32_result"
-    func_to_host_file_result=$func_cygpath_result
+    func_to_host_file_result="$func_cygpath_result"
   fi
   func_convert_file_check "$1" "$func_to_host_file_result"
 }
@@ -3072,7 +1781,7 @@ func_convert_file_nix_to_cygwin ()
 #############################################
 # $build to $host PATH CONVERSION FUNCTIONS #
 #############################################
-# invoked via '$to_host_path_cmd ARG'
+# invoked via `$to_host_path_cmd ARG'
 #
 # In each case, ARG is the path to be converted from $build to $host format.
 # The result will be available in $func_to_host_path_result.
@@ -3096,11 +1805,10 @@ func_convert_file_nix_to_cygwin ()
 to_host_path_cmd=
 func_init_to_host_path_cmd ()
 {
-  $debug_cmd
-
+  $opt_debug
   if test -z "$to_host_path_cmd"; then
     func_stripname 'func_convert_file_' '' "$to_host_file_cmd"
-    to_host_path_cmd=func_convert_path_$func_stripname_result
+    to_host_path_cmd="func_convert_path_${func_stripname_result}"
   fi
 }
 
@@ -3110,8 +1818,7 @@ func_init_to_host_path_cmd ()
 # in func_to_host_path_result.
 func_to_host_path ()
 {
-  $debug_cmd
-
+  $opt_debug
   func_init_to_host_path_cmd
   $to_host_path_cmd "$1"
 }
@@ -3122,7 +1829,7 @@ func_to_host_path ()
 # Copy ARG to func_to_host_path_result.
 func_convert_path_noop ()
 {
-  func_to_host_path_result=$1
+  func_to_host_path_result="$1"
 }
 # end func_convert_path_noop
 
@@ -3133,9 +1840,8 @@ func_convert_path_noop ()
 # func_to_host_path_result.
 func_convert_path_msys_to_w32 ()
 {
-  $debug_cmd
-
-  func_to_host_path_result=$1
+  $opt_debug
+  func_to_host_path_result="$1"
   if test -n "$1"; then
     # Remove leading and trailing path separator characters from ARG.  MSYS
     # behavior is inconsistent here; cygpath turns them into '.;' and ';.';
@@ -3143,7 +1849,7 @@ func_convert_path_msys_to_w32 ()
     func_stripname : : "$1"
     func_to_host_path_tmp1=$func_stripname_result
     func_convert_core_msys_to_w32 "$func_to_host_path_tmp1"
-    func_to_host_path_result=$func_convert_core_msys_to_w32_result
+    func_to_host_path_result="$func_convert_core_msys_to_w32_result"
     func_convert_path_check : ";" \
       "$func_to_host_path_tmp1" "$func_to_host_path_result"
     func_convert_path_front_back_pathsep ":*" "*:" ";" "$1"
@@ -3157,9 +1863,8 @@ func_convert_path_msys_to_w32 ()
 # func_to_host_file_result.
 func_convert_path_cygwin_to_w32 ()
 {
-  $debug_cmd
-
-  func_to_host_path_result=$1
+  $opt_debug
+  func_to_host_path_result="$1"
   if test -n "$1"; then
     # See func_convert_path_msys_to_w32:
     func_stripname : : "$1"
@@ -3178,15 +1883,14 @@ func_convert_path_cygwin_to_w32 ()
 # a working winepath.  Returns result in func_to_host_file_result.
 func_convert_path_nix_to_w32 ()
 {
-  $debug_cmd
-
-  func_to_host_path_result=$1
+  $opt_debug
+  func_to_host_path_result="$1"
   if test -n "$1"; then
     # See func_convert_path_msys_to_w32:
     func_stripname : : "$1"
     func_to_host_path_tmp1=$func_stripname_result
     func_convert_core_path_wine_to_w32 "$func_to_host_path_tmp1"
-    func_to_host_path_result=$func_convert_core_path_wine_to_w32_result
+    func_to_host_path_result="$func_convert_core_path_wine_to_w32_result"
     func_convert_path_check : ";" \
       "$func_to_host_path_tmp1" "$func_to_host_path_result"
     func_convert_path_front_back_pathsep ":*" "*:" ";" "$1"
@@ -3200,16 +1904,15 @@ func_convert_path_nix_to_w32 ()
 # Returns result in func_to_host_file_result.
 func_convert_path_msys_to_cygwin ()
 {
-  $debug_cmd
-
-  func_to_host_path_result=$1
+  $opt_debug
+  func_to_host_path_result="$1"
   if test -n "$1"; then
     # See func_convert_path_msys_to_w32:
     func_stripname : : "$1"
     func_to_host_path_tmp1=$func_stripname_result
     func_convert_core_msys_to_w32 "$func_to_host_path_tmp1"
     func_cygpath -u -p "$func_convert_core_msys_to_w32_result"
-    func_to_host_path_result=$func_cygpath_result
+    func_to_host_path_result="$func_cygpath_result"
     func_convert_path_check : : \
       "$func_to_host_path_tmp1" "$func_to_host_path_result"
     func_convert_path_front_back_pathsep ":*" "*:" : "$1"
@@ -3224,9 +1927,8 @@ func_convert_path_msys_to_cygwin ()
 # func_to_host_file_result.
 func_convert_path_nix_to_cygwin ()
 {
-  $debug_cmd
-
-  func_to_host_path_result=$1
+  $opt_debug
+  func_to_host_path_result="$1"
   if test -n "$1"; then
     # Remove leading and trailing path separator characters from
     # ARG. msys behavior is inconsistent here, cygpath turns them
@@ -3235,7 +1937,7 @@ func_convert_path_nix_to_cygwin ()
     func_to_host_path_tmp1=$func_stripname_result
     func_convert_core_path_wine_to_w32 "$func_to_host_path_tmp1"
     func_cygpath -u -p "$func_convert_core_path_wine_to_w32_result"
-    func_to_host_path_result=$func_cygpath_result
+    func_to_host_path_result="$func_cygpath_result"
     func_convert_path_check : : \
       "$func_to_host_path_tmp1" "$func_to_host_path_result"
     func_convert_path_front_back_pathsep ":*" "*:" : "$1"
@@ -3244,31 +1946,13 @@ func_convert_path_nix_to_cygwin ()
 # end func_convert_path_nix_to_cygwin
 
 
-# func_dll_def_p FILE
-# True iff FILE is a Windows DLL '.def' file.
-# Keep in sync with _LT_DLL_DEF_P in libtool.m4
-func_dll_def_p ()
-{
-  $debug_cmd
-
-  func_dll_def_p_tmp=`$SED -n \
-    -e 's/^[	 ]*//' \
-    -e '/^\(;.*\)*$/d' \
-    -e 's/^\(EXPORTS\|LIBRARY\)\([	 ].*\)*$/DEF/p' \
-    -e q \
-    "$1"`
-  test DEF = "$func_dll_def_p_tmp"
-}
-
-
 # func_mode_compile arg...
 func_mode_compile ()
 {
-    $debug_cmd
-
+    $opt_debug
     # Get the compilation command and the source file.
     base_compile=
-    srcfile=$nonopt  #  always keep a non-empty value in "srcfile"
+    srcfile="$nonopt"  #  always keep a non-empty value in "srcfile"
     suppress_opt=yes
     suppress_output=
     arg_mode=normal
@@ -3281,12 +1965,12 @@ func_mode_compile ()
       case $arg_mode in
       arg  )
 	# do not "continue".  Instead, add this to base_compile
-	lastarg=$arg
+	lastarg="$arg"
 	arg_mode=normal
 	;;
 
       target )
-	libobj=$arg
+	libobj="$arg"
 	arg_mode=normal
 	continue
 	;;
@@ -3296,7 +1980,7 @@ func_mode_compile ()
 	case $arg in
 	-o)
 	  test -n "$libobj" && \
-	    func_fatal_error "you cannot specify '-o' more than once"
+	    func_fatal_error "you cannot specify \`-o' more than once"
 	  arg_mode=target
 	  continue
 	  ;;
@@ -3325,12 +2009,12 @@ func_mode_compile ()
 	  func_stripname '-Wc,' '' "$arg"
 	  args=$func_stripname_result
 	  lastarg=
-	  save_ifs=$IFS; IFS=,
+	  save_ifs="$IFS"; IFS=','
 	  for arg in $args; do
-	    IFS=$save_ifs
+	    IFS="$save_ifs"
 	    func_append_quoted lastarg "$arg"
 	  done
-	  IFS=$save_ifs
+	  IFS="$save_ifs"
 	  func_stripname ' ' '' "$lastarg"
 	  lastarg=$func_stripname_result
 
@@ -3343,8 +2027,8 @@ func_mode_compile ()
 	  # Accept the current argument as the source file.
 	  # The previous "srcfile" becomes the current argument.
 	  #
-	  lastarg=$srcfile
-	  srcfile=$arg
+	  lastarg="$srcfile"
+	  srcfile="$arg"
 	  ;;
 	esac  #  case $arg
 	;;
@@ -3359,13 +2043,13 @@ func_mode_compile ()
       func_fatal_error "you must specify an argument for -Xcompile"
       ;;
     target)
-      func_fatal_error "you must specify a target with '-o'"
+      func_fatal_error "you must specify a target with \`-o'"
       ;;
     *)
       # Get the name of the library object.
       test -z "$libobj" && {
 	func_basename "$srcfile"
-	libobj=$func_basename_result
+	libobj="$func_basename_result"
       }
       ;;
     esac
@@ -3385,7 +2069,7 @@ func_mode_compile ()
     case $libobj in
     *.lo) func_lo2o "$libobj"; obj=$func_lo2o_result ;;
     *)
-      func_fatal_error "cannot determine name of library object from '$libobj'"
+      func_fatal_error "cannot determine name of library object from \`$libobj'"
       ;;
     esac
 
@@ -3394,8 +2078,8 @@ func_mode_compile ()
     for arg in $later; do
       case $arg in
       -shared)
-	test yes = "$build_libtool_libs" \
-	  || func_fatal_configuration "cannot build a shared library"
+	test "$build_libtool_libs" != yes && \
+	  func_fatal_configuration "can not build a shared library"
 	build_old_libs=no
 	continue
 	;;
@@ -3421,17 +2105,17 @@ func_mode_compile ()
     func_quote_for_eval "$libobj"
     test "X$libobj" != "X$func_quote_for_eval_result" \
       && $ECHO "X$libobj" | $GREP '[]~#^*{};<>?"'"'"'	 &()|`$[]' \
-      && func_warning "libobj name '$libobj' may not contain shell special characters."
+      && func_warning "libobj name \`$libobj' may not contain shell special characters."
     func_dirname_and_basename "$obj" "/" ""
-    objname=$func_basename_result
-    xdir=$func_dirname_result
-    lobj=$xdir$objdir/$objname
+    objname="$func_basename_result"
+    xdir="$func_dirname_result"
+    lobj=${xdir}$objdir/$objname
 
     test -z "$base_compile" && \
       func_fatal_help "you must specify a compilation command"
 
     # Delete any leftover library objects.
-    if test yes = "$build_old_libs"; then
+    if test "$build_old_libs" = yes; then
       removelist="$obj $lobj $libobj ${libobj}T"
     else
       removelist="$lobj $libobj ${libobj}T"
@@ -3443,16 +2127,16 @@ func_mode_compile ()
       pic_mode=default
       ;;
     esac
-    if test no = "$pic_mode" && test pass_all != "$deplibs_check_method"; then
+    if test "$pic_mode" = no && test "$deplibs_check_method" != pass_all; then
       # non-PIC code in shared libraries is not supported
       pic_mode=default
     fi
 
     # Calculate the filename of the output object if compiler does
     # not support -o with -c
-    if test no = "$compiler_c_o"; then
-      output_obj=`$ECHO "$srcfile" | $SED 's%^.*/%%; s%\.[^.]*$%%'`.$objext
-      lockfile=$output_obj.lock
+    if test "$compiler_c_o" = no; then
+      output_obj=`$ECHO "$srcfile" | $SED 's%^.*/%%; s%\.[^.]*$%%'`.${objext}
+      lockfile="$output_obj.lock"
     else
       output_obj=
       need_locks=no
@@ -3461,12 +2145,12 @@ func_mode_compile ()
 
     # Lock this critical section if it is needed
     # We use this script file to make the link, it avoids creating a new file
-    if test yes = "$need_locks"; then
+    if test "$need_locks" = yes; then
       until $opt_dry_run || ln "$progpath" "$lockfile" 2>/dev/null; do
 	func_echo "Waiting for $lockfile to be removed"
 	sleep 2
       done
-    elif test warn = "$need_locks"; then
+    elif test "$need_locks" = warn; then
       if test -f "$lockfile"; then
 	$ECHO "\
 *** ERROR, $lockfile exists and contains:
@@ -3474,7 +2158,7 @@ func_mode_compile ()
 
 This indicates that another process is trying to use the same
 temporary object file, and libtool could not work around it because
-your compiler does not support '-c' and '-o' together.  If you
+your compiler does not support \`-c' and \`-o' together.  If you
 repeat this compilation, it may succeed, by chance, but you had better
 avoid parallel builds (make -j) in this platform, or get a better
 compiler."
@@ -3496,11 +2180,11 @@ compiler."
     qsrcfile=$func_quote_for_eval_result
 
     # Only build a PIC object if we are building libtool libraries.
-    if test yes = "$build_libtool_libs"; then
+    if test "$build_libtool_libs" = yes; then
       # Without this assignment, base_compile gets emptied.
       fbsd_hideous_sh_bug=$base_compile
 
-      if test no != "$pic_mode"; then
+      if test "$pic_mode" != no; then
 	command="$base_compile $qsrcfile $pic_flag"
       else
 	# Don't build PIC code
@@ -3517,7 +2201,7 @@ compiler."
       func_show_eval_locale "$command"	\
           'test -n "$output_obj" && $RM $removelist; exit $EXIT_FAILURE'
 
-      if test warn = "$need_locks" &&
+      if test "$need_locks" = warn &&
 	 test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then
 	$ECHO "\
 *** ERROR, $lockfile contains:
@@ -3528,7 +2212,7 @@ $srcfile
 
 This indicates that another process is trying to use the same
 temporary object file, and libtool could not work around it because
-your compiler does not support '-c' and '-o' together.  If you
+your compiler does not support \`-c' and \`-o' together.  If you
 repeat this compilation, it may succeed, by chance, but you had better
 avoid parallel builds (make -j) in this platform, or get a better
 compiler."
@@ -3544,20 +2228,20 @@ compiler."
       fi
 
       # Allow error messages only from the first compilation.
-      if test yes = "$suppress_opt"; then
+      if test "$suppress_opt" = yes; then
 	suppress_output=' >/dev/null 2>&1'
       fi
     fi
 
     # Only build a position-dependent object if we build old libraries.
-    if test yes = "$build_old_libs"; then
-      if test yes != "$pic_mode"; then
+    if test "$build_old_libs" = yes; then
+      if test "$pic_mode" != yes; then
 	# Don't build PIC code
 	command="$base_compile $qsrcfile$pie_flag"
       else
 	command="$base_compile $qsrcfile $pic_flag"
       fi
-      if test yes = "$compiler_c_o"; then
+      if test "$compiler_c_o" = yes; then
 	func_append command " -o $obj"
       fi
 
@@ -3566,7 +2250,7 @@ compiler."
       func_show_eval_locale "$command" \
         '$opt_dry_run || $RM $removelist; exit $EXIT_FAILURE'
 
-      if test warn = "$need_locks" &&
+      if test "$need_locks" = warn &&
 	 test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then
 	$ECHO "\
 *** ERROR, $lockfile contains:
@@ -3577,7 +2261,7 @@ $srcfile
 
 This indicates that another process is trying to use the same
 temporary object file, and libtool could not work around it because
-your compiler does not support '-c' and '-o' together.  If you
+your compiler does not support \`-c' and \`-o' together.  If you
 repeat this compilation, it may succeed, by chance, but you had better
 avoid parallel builds (make -j) in this platform, or get a better
 compiler."
@@ -3597,7 +2281,7 @@ compiler."
       func_write_libtool_object "$libobj" "$objdir/$objname" "$objname"
 
       # Unlock the critical section if it was locked
-      if test no != "$need_locks"; then
+      if test "$need_locks" != no; then
 	removelist=$lockfile
         $RM "$lockfile"
       fi
@@ -3607,7 +2291,7 @@ compiler."
 }
 
 $opt_help || {
-  test compile = "$opt_mode" && func_mode_compile ${1+"$@"}
+  test "$opt_mode" = compile && func_mode_compile ${1+"$@"}
 }
 
 func_mode_help ()
@@ -3627,7 +2311,7 @@ func_mode_help ()
 Remove files from the build directory.
 
 RM is the name of the program to use to delete files associated with each FILE
-(typically '/bin/rm').  RM-OPTIONS are options (such as '-f') to be passed
+(typically \`/bin/rm').  RM-OPTIONS are options (such as \`-f') to be passed
 to RM.
 
 If FILE is a libtool library, object or program, all the files associated
@@ -3646,16 +2330,16 @@ This mode accepts the following additional options:
   -no-suppress      do not suppress compiler output for multiple passes
   -prefer-pic       try to build PIC objects only
   -prefer-non-pic   try to build non-PIC objects only
-  -shared           do not build a '.o' file suitable for static linking
-  -static           only build a '.o' file suitable for static linking
+  -shared           do not build a \`.o' file suitable for static linking
+  -static           only build a \`.o' file suitable for static linking
   -Wc,FLAG          pass FLAG directly to the compiler
 
-COMPILE-COMMAND is a command to be used in creating a 'standard' object file
+COMPILE-COMMAND is a command to be used in creating a \`standard' object file
 from the given SOURCEFILE.
 
 The output file name is determined by removing the directory component from
-SOURCEFILE, then substituting the C source code suffix '.c' with the
-library object suffix, '.lo'."
+SOURCEFILE, then substituting the C source code suffix \`.c' with the
+library object suffix, \`.lo'."
         ;;
 
       execute)
@@ -3668,7 +2352,7 @@ This mode accepts the following additional options:
 
   -dlopen FILE      add the directory containing FILE to the library path
 
-This mode sets the library path environment variable according to '-dlopen'
+This mode sets the library path environment variable according to \`-dlopen'
 flags.
 
 If any of the ARGS are libtool executable wrappers, then they are translated
@@ -3687,7 +2371,7 @@ Complete the installation of libtool libraries.
 Each LIBDIR is a directory that contains libtool libraries.
 
 The commands that this mode executes may require superuser privileges.  Use
-the '--dry-run' option if you just want to see what would be executed."
+the \`--dry-run' option if you just want to see what would be executed."
         ;;
 
       install)
@@ -3697,7 +2381,7 @@ the '--dry-run' option if you just want to see what would be executed."
 Install executables or libraries.
 
 INSTALL-COMMAND is the installation command.  The first component should be
-either the 'install' or 'cp' program.
+either the \`install' or \`cp' program.
 
 The following components of INSTALL-COMMAND are treated specially:
 
@@ -3723,7 +2407,7 @@ The following components of LINK-COMMAND are treated specially:
   -avoid-version    do not add a version suffix if possible
   -bindir BINDIR    specify path to binaries directory (for systems where
                     libraries must be found in the PATH setting at runtime)
-  -dlopen FILE      '-dlpreopen' FILE if it cannot be dlopened at runtime
+  -dlopen FILE      \`-dlpreopen' FILE if it cannot be dlopened at runtime
   -dlpreopen FILE   link in FILE and add its symbols to lt_preloaded_symbols
   -export-dynamic   allow symbols from OUTPUT-FILE to be resolved with dlsym(3)
   -export-symbols SYMFILE
@@ -3737,8 +2421,7 @@ The following components of LINK-COMMAND are treated specially:
   -no-install       link a not-installable executable
   -no-undefined     declare that a library does not refer to external symbols
   -o OUTPUT-FILE    create OUTPUT-FILE from the specified objects
-  -objectlist FILE  use a list of object files found in FILE to specify objects
-  -os2dllname NAME  force a short DLL name on OS/2 (no effect on other OSes)
+  -objectlist FILE  Use a list of object files found in FILE to specify objects
   -precious-files-regex REGEX
                     don't remove output files matching REGEX
   -release RELEASE  specify package release information
@@ -3758,20 +2441,20 @@ The following components of LINK-COMMAND are treated specially:
   -Xlinker FLAG     pass linker-specific FLAG directly to the linker
   -XCClinker FLAG   pass link-specific FLAG to the compiler driver (CC)
 
-All other options (arguments beginning with '-') are ignored.
+All other options (arguments beginning with \`-') are ignored.
 
-Every other argument is treated as a filename.  Files ending in '.la' are
+Every other argument is treated as a filename.  Files ending in \`.la' are
 treated as uninstalled libtool libraries, other files are standard or library
 object files.
 
-If the OUTPUT-FILE ends in '.la', then a libtool library is created,
-only library objects ('.lo' files) may be specified, and '-rpath' is
+If the OUTPUT-FILE ends in \`.la', then a libtool library is created,
+only library objects (\`.lo' files) may be specified, and \`-rpath' is
 required, except when creating a convenience library.
 
-If OUTPUT-FILE ends in '.a' or '.lib', then a standard library is created
-using 'ar' and 'ranlib', or on Windows using 'lib'.
+If OUTPUT-FILE ends in \`.a' or \`.lib', then a standard library is created
+using \`ar' and \`ranlib', or on Windows using \`lib'.
 
-If OUTPUT-FILE ends in '.lo' or '.$objext', then a reloadable object file
+If OUTPUT-FILE ends in \`.lo' or \`.${objext}', then a reloadable object file
 is created, otherwise an executable program is created."
         ;;
 
@@ -3782,7 +2465,7 @@ is created, otherwise an executable program is created."
 Remove libraries from an installation directory.
 
 RM is the name of the program to use to delete files associated with each FILE
-(typically '/bin/rm').  RM-OPTIONS are options (such as '-f') to be passed
+(typically \`/bin/rm').  RM-OPTIONS are options (such as \`-f') to be passed
 to RM.
 
 If FILE is a libtool library, all the files associated with it are deleted.
@@ -3790,17 +2473,17 @@ Otherwise, only FILE itself is deleted using RM."
         ;;
 
       *)
-        func_fatal_help "invalid operation mode '$opt_mode'"
+        func_fatal_help "invalid operation mode \`$opt_mode'"
         ;;
     esac
 
     echo
-    $ECHO "Try '$progname --help' for more information about other modes."
+    $ECHO "Try \`$progname --help' for more information about other modes."
 }
 
 # Now that we've collected a possible --mode arg, show help if necessary
 if $opt_help; then
-  if test : = "$opt_help"; then
+  if test "$opt_help" = :; then
     func_mode_help
   else
     {
@@ -3808,7 +2491,7 @@ if $opt_help; then
       for opt_mode in compile link execute install finish uninstall clean; do
 	func_mode_help
       done
-    } | $SED -n '1p; 2,$s/^Usage:/  or: /p'
+    } | sed -n '1p; 2,$s/^Usage:/  or: /p'
     {
       func_help noexit
       for opt_mode in compile link execute install finish uninstall clean; do
@@ -3816,7 +2499,7 @@ if $opt_help; then
 	func_mode_help
       done
     } |
-    $SED '1d
+    sed '1d
       /^When reporting/,/^Report/{
 	H
 	d
@@ -3833,17 +2516,16 @@ fi
 # func_mode_execute arg...
 func_mode_execute ()
 {
-    $debug_cmd
-
+    $opt_debug
     # The first argument is the command name.
-    cmd=$nonopt
+    cmd="$nonopt"
     test -z "$cmd" && \
       func_fatal_help "you must specify a COMMAND"
 
     # Handle -dlopen flags immediately.
     for file in $opt_dlopen; do
       test -f "$file" \
-	|| func_fatal_help "'$file' is not a file"
+	|| func_fatal_help "\`$file' is not a file"
 
       dir=
       case $file in
@@ -3853,7 +2535,7 @@ func_mode_execute ()
 
 	# Check to see that this really is a libtool archive.
 	func_lalib_unsafe_p "$file" \
-	  || func_fatal_help "'$lib' is not a valid libtool archive"
+	  || func_fatal_help "\`$lib' is not a valid libtool archive"
 
 	# Read the libtool library.
 	dlname=
@@ -3864,18 +2546,18 @@ func_mode_execute ()
 	if test -z "$dlname"; then
 	  # Warn if it was a shared library.
 	  test -n "$library_names" && \
-	    func_warning "'$file' was not linked with '-export-dynamic'"
+	    func_warning "\`$file' was not linked with \`-export-dynamic'"
 	  continue
 	fi
 
 	func_dirname "$file" "" "."
-	dir=$func_dirname_result
+	dir="$func_dirname_result"
 
 	if test -f "$dir/$objdir/$dlname"; then
 	  func_append dir "/$objdir"
 	else
 	  if test ! -f "$dir/$dlname"; then
-	    func_fatal_error "cannot find '$dlname' in '$dir' or '$dir/$objdir'"
+	    func_fatal_error "cannot find \`$dlname' in \`$dir' or \`$dir/$objdir'"
 	  fi
 	fi
 	;;
@@ -3883,18 +2565,18 @@ func_mode_execute ()
       *.lo)
 	# Just add the directory containing the .lo file.
 	func_dirname "$file" "" "."
-	dir=$func_dirname_result
+	dir="$func_dirname_result"
 	;;
 
       *)
-	func_warning "'-dlopen' is ignored for non-libtool libraries and objects"
+	func_warning "\`-dlopen' is ignored for non-libtool libraries and objects"
 	continue
 	;;
       esac
 
       # Get the absolute pathname.
       absdir=`cd "$dir" && pwd`
-      test -n "$absdir" && dir=$absdir
+      test -n "$absdir" && dir="$absdir"
 
       # Now add the directory to shlibpath_var.
       if eval "test -z \"\$$shlibpath_var\""; then
@@ -3906,7 +2588,7 @@ func_mode_execute ()
 
     # This variable tells wrapper scripts just to set shlibpath_var
     # rather than running their programs.
-    libtool_execute_magic=$magic
+    libtool_execute_magic="$magic"
 
     # Check if any of the arguments is a wrapper script.
     args=
@@ -3919,12 +2601,12 @@ func_mode_execute ()
 	if func_ltwrapper_script_p "$file"; then
 	  func_source "$file"
 	  # Transform arg to wrapped name.
-	  file=$progdir/$program
+	  file="$progdir/$program"
 	elif func_ltwrapper_executable_p "$file"; then
 	  func_ltwrapper_scriptname "$file"
 	  func_source "$func_ltwrapper_scriptname_result"
 	  # Transform arg to wrapped name.
-	  file=$progdir/$program
+	  file="$progdir/$program"
 	fi
 	;;
       esac
@@ -3932,15 +2614,7 @@ func_mode_execute ()
       func_append_quoted args "$file"
     done
 
-    if $opt_dry_run; then
-      # Display what would be done.
-      if test -n "$shlibpath_var"; then
-	eval "\$ECHO \"\$shlibpath_var=\$$shlibpath_var\""
-	echo "export $shlibpath_var"
-      fi
-      $ECHO "$cmd$args"
-      exit $EXIT_SUCCESS
-    else
+    if test "X$opt_dry_run" = Xfalse; then
       if test -n "$shlibpath_var"; then
 	# Export the shlibpath_var.
 	eval "export $shlibpath_var"
@@ -3957,18 +2631,25 @@ func_mode_execute ()
       done
 
       # Now prepare to actually exec the command.
-      exec_cmd=\$cmd$args
+      exec_cmd="\$cmd$args"
+    else
+      # Display what would be done.
+      if test -n "$shlibpath_var"; then
+	eval "\$ECHO \"\$shlibpath_var=\$$shlibpath_var\""
+	echo "export $shlibpath_var"
+      fi
+      $ECHO "$cmd$args"
+      exit $EXIT_SUCCESS
     fi
 }
 
-test execute = "$opt_mode" && func_mode_execute ${1+"$@"}
+test "$opt_mode" = execute && func_mode_execute ${1+"$@"}
 
 
 # func_mode_finish arg...
 func_mode_finish ()
 {
-    $debug_cmd
-
+    $opt_debug
     libs=
     libdirs=
     admincmds=
@@ -3982,11 +2663,11 @@ func_mode_finish ()
 	if func_lalib_unsafe_p "$opt"; then
 	  func_append libs " $opt"
 	else
-	  func_warning "'$opt' is not a valid libtool archive"
+	  func_warning "\`$opt' is not a valid libtool archive"
 	fi
 
       else
-	func_fatal_error "invalid argument '$opt'"
+	func_fatal_error "invalid argument \`$opt'"
       fi
     done
 
@@ -4001,12 +2682,12 @@ func_mode_finish ()
       # Remove sysroot references
       if $opt_dry_run; then
         for lib in $libs; do
-          echo "removing references to $lt_sysroot and '=' prefixes from $lib"
+          echo "removing references to $lt_sysroot and \`=' prefixes from $lib"
         done
       else
         tmpdir=`func_mktempdir`
         for lib in $libs; do
-	  $SED -e "$sysroot_cmd s/\([ ']-[LR]\)=/\1/g; s/\([ ']\)=/\1/g" $lib \
+	  sed -e "${sysroot_cmd} s/\([ ']-[LR]\)=/\1/g; s/\([ ']\)=/\1/g" $lib \
 	    > $tmpdir/tmp-la
 	  mv -f $tmpdir/tmp-la $lib
 	done
@@ -4031,7 +2712,7 @@ func_mode_finish ()
     fi
 
     # Exit here if they wanted silent mode.
-    $opt_quiet && exit $EXIT_SUCCESS
+    $opt_silent && exit $EXIT_SUCCESS
 
     if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then
       echo "----------------------------------------------------------------------"
@@ -4042,27 +2723,27 @@ func_mode_finish ()
       echo
       echo "If you ever happen to want to link against installed libraries"
       echo "in a given directory, LIBDIR, you must either use libtool, and"
-      echo "specify the full pathname of the library, or use the '-LLIBDIR'"
+      echo "specify the full pathname of the library, or use the \`-LLIBDIR'"
       echo "flag during linking and do at least one of the following:"
       if test -n "$shlibpath_var"; then
-	echo "   - add LIBDIR to the '$shlibpath_var' environment variable"
+	echo "   - add LIBDIR to the \`$shlibpath_var' environment variable"
 	echo "     during execution"
       fi
       if test -n "$runpath_var"; then
-	echo "   - add LIBDIR to the '$runpath_var' environment variable"
+	echo "   - add LIBDIR to the \`$runpath_var' environment variable"
 	echo "     during linking"
       fi
       if test -n "$hardcode_libdir_flag_spec"; then
 	libdir=LIBDIR
 	eval flag=\"$hardcode_libdir_flag_spec\"
 
-	$ECHO "   - use the '$flag' linker flag"
+	$ECHO "   - use the \`$flag' linker flag"
       fi
       if test -n "$admincmds"; then
 	$ECHO "   - have your system administrator run these commands:$admincmds"
       fi
       if test -f /etc/ld.so.conf; then
-	echo "   - have your system administrator add LIBDIR to '/etc/ld.so.conf'"
+	echo "   - have your system administrator add LIBDIR to \`/etc/ld.so.conf'"
       fi
       echo
 
@@ -4081,20 +2762,18 @@ func_mode_finish ()
     exit $EXIT_SUCCESS
 }
 
-test finish = "$opt_mode" && func_mode_finish ${1+"$@"}
+test "$opt_mode" = finish && func_mode_finish ${1+"$@"}
 
 
 # func_mode_install arg...
 func_mode_install ()
 {
-    $debug_cmd
-
+    $opt_debug
     # There may be an optional sh(1) argument at the beginning of
     # install_prog (especially on Windows NT).
-    if test "$SHELL" = "$nonopt" || test /bin/sh = "$nonopt" ||
+    if test "$nonopt" = "$SHELL" || test "$nonopt" = /bin/sh ||
        # Allow the use of GNU shtool's install command.
-       case $nonopt in *shtool*) :;; *) false;; esac
-    then
+       case $nonopt in *shtool*) :;; *) false;; esac; then
       # Aesthetically quote it.
       func_quote_for_eval "$nonopt"
       install_prog="$func_quote_for_eval_result "
@@ -4121,7 +2800,7 @@ func_mode_install ()
     opts=
     prev=
     install_type=
-    isdir=false
+    isdir=no
     stripme=
     no_mode=:
     for arg
@@ -4134,7 +2813,7 @@ func_mode_install ()
       fi
 
       case $arg in
-      -d) isdir=: ;;
+      -d) isdir=yes ;;
       -f)
 	if $install_cp; then :; else
 	  prev=$arg
@@ -4152,7 +2831,7 @@ func_mode_install ()
       *)
 	# If the previous option needed an argument, then skip it.
 	if test -n "$prev"; then
-	  if test X-m = "X$prev" && test -n "$install_override_mode"; then
+	  if test "x$prev" = x-m && test -n "$install_override_mode"; then
 	    arg2=$install_override_mode
 	    no_mode=false
 	  fi
@@ -4177,7 +2856,7 @@ func_mode_install ()
       func_fatal_help "you must specify an install program"
 
     test -n "$prev" && \
-      func_fatal_help "the '$prev' option requires an argument"
+      func_fatal_help "the \`$prev' option requires an argument"
 
     if test -n "$install_override_mode" && $no_mode; then
       if $install_cp; then :; else
@@ -4199,19 +2878,19 @@ func_mode_install ()
     dest=$func_stripname_result
 
     # Check to see that the destination is a directory.
-    test -d "$dest" && isdir=:
-    if $isdir; then
-      destdir=$dest
+    test -d "$dest" && isdir=yes
+    if test "$isdir" = yes; then
+      destdir="$dest"
       destname=
     else
       func_dirname_and_basename "$dest" "" "."
-      destdir=$func_dirname_result
-      destname=$func_basename_result
+      destdir="$func_dirname_result"
+      destname="$func_basename_result"
 
       # Not a directory, so check to see that there is only one file specified.
       set dummy $files; shift
       test "$#" -gt 1 && \
-	func_fatal_help "'$dest' is not a directory"
+	func_fatal_help "\`$dest' is not a directory"
     fi
     case $destdir in
     [\\/]* | [A-Za-z]:[\\/]*) ;;
@@ -4220,7 +2899,7 @@ func_mode_install ()
 	case $file in
 	*.lo) ;;
 	*)
-	  func_fatal_help "'$destdir' must be an absolute directory name"
+	  func_fatal_help "\`$destdir' must be an absolute directory name"
 	  ;;
 	esac
       done
@@ -4229,7 +2908,7 @@ func_mode_install ()
 
     # This variable tells wrapper scripts just to set variables rather
     # than running their programs.
-    libtool_install_magic=$magic
+    libtool_install_magic="$magic"
 
     staticlibs=
     future_libdirs=
@@ -4249,7 +2928,7 @@ func_mode_install ()
 
 	# Check to see that this really is a libtool archive.
 	func_lalib_unsafe_p "$file" \
-	  || func_fatal_help "'$file' is not a valid libtool archive"
+	  || func_fatal_help "\`$file' is not a valid libtool archive"
 
 	library_names=
 	old_library=
@@ -4271,7 +2950,7 @@ func_mode_install ()
 	fi
 
 	func_dirname "$file" "/" ""
-	dir=$func_dirname_result
+	dir="$func_dirname_result"
 	func_append dir "$objdir"
 
 	if test -n "$relink_command"; then
@@ -4285,7 +2964,7 @@ func_mode_install ()
 	  # are installed into $libdir/../bin (currently, that works fine)
 	  # but it's something to keep an eye on.
 	  test "$inst_prefix_dir" = "$destdir" && \
-	    func_fatal_error "error: cannot install '$file' to a directory not ending in $libdir"
+	    func_fatal_error "error: cannot install \`$file' to a directory not ending in $libdir"
 
 	  if test -n "$inst_prefix_dir"; then
 	    # Stick the inst_prefix_dir data into the link command.
@@ -4294,36 +2973,29 @@ func_mode_install ()
 	    relink_command=`$ECHO "$relink_command" | $SED "s%@inst_prefix_dir@%%"`
 	  fi
 
-	  func_warning "relinking '$file'"
+	  func_warning "relinking \`$file'"
 	  func_show_eval "$relink_command" \
-	    'func_fatal_error "error: relink '\''$file'\'' with the above command before installing it"'
+	    'func_fatal_error "error: relink \`$file'\'' with the above command before installing it"'
 	fi
 
 	# See the names of the shared library.
 	set dummy $library_names; shift
 	if test -n "$1"; then
-	  realname=$1
+	  realname="$1"
 	  shift
 
-	  srcname=$realname
-	  test -n "$relink_command" && srcname=${realname}T
+	  srcname="$realname"
+	  test -n "$relink_command" && srcname="$realname"T
 
 	  # Install the shared library and build the symlinks.
 	  func_show_eval "$install_shared_prog $dir/$srcname $destdir/$realname" \
 	      'exit $?'
-	  tstripme=$stripme
+	  tstripme="$stripme"
 	  case $host_os in
 	  cygwin* | mingw* | pw32* | cegcc*)
 	    case $realname in
 	    *.dll.a)
-	      tstripme=
-	      ;;
-	    esac
-	    ;;
-	  os2*)
-	    case $realname in
-	    *_dll.a)
-	      tstripme=
+	      tstripme=""
 	      ;;
 	    esac
 	    ;;
@@ -4334,7 +3006,7 @@ func_mode_install ()
 
 	  if test "$#" -gt 0; then
 	    # Delete the old symlinks, and create new ones.
-	    # Try 'ln -sf' first, because the 'ln' binary might depend on
+	    # Try `ln -sf' first, because the `ln' binary might depend on
 	    # the symlink we replace!  Solaris /bin/ln does not understand -f,
 	    # so we also need to try rm && ln -s.
 	    for linkname
@@ -4345,14 +3017,14 @@ func_mode_install ()
 	  fi
 
 	  # Do each command in the postinstall commands.
-	  lib=$destdir/$realname
+	  lib="$destdir/$realname"
 	  func_execute_cmds "$postinstall_cmds" 'exit $?'
 	fi
 
 	# Install the pseudo-library for information purposes.
 	func_basename "$file"
-	name=$func_basename_result
-	instname=$dir/${name}i
+	name="$func_basename_result"
+	instname="$dir/$name"i
 	func_show_eval "$install_prog $instname $destdir/$name" 'exit $?'
 
 	# Maybe install the static library, too.
@@ -4364,11 +3036,11 @@ func_mode_install ()
 
 	# Figure out destination file name, if it wasn't already specified.
 	if test -n "$destname"; then
-	  destfile=$destdir/$destname
+	  destfile="$destdir/$destname"
 	else
 	  func_basename "$file"
-	  destfile=$func_basename_result
-	  destfile=$destdir/$destfile
+	  destfile="$func_basename_result"
+	  destfile="$destdir/$destfile"
 	fi
 
 	# Deduce the name of the destination old-style object file.
@@ -4378,11 +3050,11 @@ func_mode_install ()
 	  staticdest=$func_lo2o_result
 	  ;;
 	*.$objext)
-	  staticdest=$destfile
+	  staticdest="$destfile"
 	  destfile=
 	  ;;
 	*)
-	  func_fatal_help "cannot copy a libtool object to '$destfile'"
+	  func_fatal_help "cannot copy a libtool object to \`$destfile'"
 	  ;;
 	esac
 
@@ -4391,7 +3063,7 @@ func_mode_install ()
 	  func_show_eval "$install_prog $file $destfile" 'exit $?'
 
 	# Install the old object if enabled.
-	if test yes = "$build_old_libs"; then
+	if test "$build_old_libs" = yes; then
 	  # Deduce the name of the old-style object file.
 	  func_lo2o "$file"
 	  staticobj=$func_lo2o_result
@@ -4403,23 +3075,23 @@ func_mode_install ()
       *)
 	# Figure out destination file name, if it wasn't already specified.
 	if test -n "$destname"; then
-	  destfile=$destdir/$destname
+	  destfile="$destdir/$destname"
 	else
 	  func_basename "$file"
-	  destfile=$func_basename_result
-	  destfile=$destdir/$destfile
+	  destfile="$func_basename_result"
+	  destfile="$destdir/$destfile"
 	fi
 
 	# If the file is missing, and there is a .exe on the end, strip it
 	# because it is most likely a libtool script we actually want to
 	# install
-	stripped_ext=
+	stripped_ext=""
 	case $file in
 	  *.exe)
 	    if test ! -f "$file"; then
 	      func_stripname '' '.exe' "$file"
 	      file=$func_stripname_result
-	      stripped_ext=.exe
+	      stripped_ext=".exe"
 	    fi
 	    ;;
 	esac
@@ -4447,19 +3119,19 @@ func_mode_install ()
 
 	  # Check the variables that should have been set.
 	  test -z "$generated_by_libtool_version" && \
-	    func_fatal_error "invalid libtool wrapper script '$wrapper'"
+	    func_fatal_error "invalid libtool wrapper script \`$wrapper'"
 
-	  finalize=:
+	  finalize=yes
 	  for lib in $notinst_deplibs; do
 	    # Check to see that each library is installed.
 	    libdir=
 	    if test -f "$lib"; then
 	      func_source "$lib"
 	    fi
-	    libfile=$libdir/`$ECHO "$lib" | $SED 's%^.*/%%g'`
+	    libfile="$libdir/"`$ECHO "$lib" | $SED 's%^.*/%%g'` ### testsuite: skip nested quoting test
 	    if test -n "$libdir" && test ! -f "$libfile"; then
-	      func_warning "'$lib' has not been installed in '$libdir'"
-	      finalize=false
+	      func_warning "\`$lib' has not been installed in \`$libdir'"
+	      finalize=no
 	    fi
 	  done
 
@@ -4467,29 +3139,29 @@ func_mode_install ()
 	  func_source "$wrapper"
 
 	  outputname=
-	  if test no = "$fast_install" && test -n "$relink_command"; then
+	  if test "$fast_install" = no && test -n "$relink_command"; then
 	    $opt_dry_run || {
-	      if $finalize; then
+	      if test "$finalize" = yes; then
 	        tmpdir=`func_mktempdir`
 		func_basename "$file$stripped_ext"
-		file=$func_basename_result
-	        outputname=$tmpdir/$file
+		file="$func_basename_result"
+	        outputname="$tmpdir/$file"
 	        # Replace the output file specification.
 	        relink_command=`$ECHO "$relink_command" | $SED 's%@OUTPUT@%'"$outputname"'%g'`
 
-	        $opt_quiet || {
+	        $opt_silent || {
 	          func_quote_for_expand "$relink_command"
 		  eval "func_echo $func_quote_for_expand_result"
 	        }
 	        if eval "$relink_command"; then :
 	          else
-		  func_error "error: relink '$file' with the above command before installing it"
+		  func_error "error: relink \`$file' with the above command before installing it"
 		  $opt_dry_run || ${RM}r "$tmpdir"
 		  continue
 	        fi
-	        file=$outputname
+	        file="$outputname"
 	      else
-	        func_warning "cannot relink '$file'"
+	        func_warning "cannot relink \`$file'"
 	      fi
 	    }
 	  else
@@ -4526,10 +3198,10 @@ func_mode_install ()
 
     for file in $staticlibs; do
       func_basename "$file"
-      name=$func_basename_result
+      name="$func_basename_result"
 
       # Set up the ranlib parameters.
-      oldlib=$destdir/$name
+      oldlib="$destdir/$name"
       func_to_tool_file "$oldlib" func_convert_file_msys_to_w32
       tool_oldlib=$func_to_tool_file_result
 
@@ -4544,18 +3216,18 @@ func_mode_install ()
     done
 
     test -n "$future_libdirs" && \
-      func_warning "remember to run '$progname --finish$future_libdirs'"
+      func_warning "remember to run \`$progname --finish$future_libdirs'"
 
     if test -n "$current_libdirs"; then
       # Maybe just do a dry run.
       $opt_dry_run && current_libdirs=" -n$current_libdirs"
-      exec_cmd='$SHELL "$progpath" $preserve_args --finish$current_libdirs'
+      exec_cmd='$SHELL $progpath $preserve_args --finish$current_libdirs'
     else
       exit $EXIT_SUCCESS
     fi
 }
 
-test install = "$opt_mode" && func_mode_install ${1+"$@"}
+test "$opt_mode" = install && func_mode_install ${1+"$@"}
 
 
 # func_generate_dlsyms outputname originator pic_p
@@ -4563,17 +3235,16 @@ test install = "$opt_mode" && func_mode_install ${1+"$@"}
 # a dlpreopen symbol table.
 func_generate_dlsyms ()
 {
-    $debug_cmd
-
-    my_outputname=$1
-    my_originator=$2
-    my_pic_p=${3-false}
-    my_prefix=`$ECHO "$my_originator" | $SED 's%[^a-zA-Z0-9]%_%g'`
+    $opt_debug
+    my_outputname="$1"
+    my_originator="$2"
+    my_pic_p="${3-no}"
+    my_prefix=`$ECHO "$my_originator" | sed 's%[^a-zA-Z0-9]%_%g'`
     my_dlsyms=
 
-    if test -n "$dlfiles$dlprefiles" || test no != "$dlself"; then
+    if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then
       if test -n "$NM" && test -n "$global_symbol_pipe"; then
-	my_dlsyms=${my_outputname}S.c
+	my_dlsyms="${my_outputname}S.c"
       else
 	func_error "not configured to extract global symbols from dlpreopened files"
       fi
@@ -4584,7 +3255,7 @@ func_generate_dlsyms ()
       "") ;;
       *.c)
 	# Discover the nlist of each of the dlfiles.
-	nlist=$output_objdir/$my_outputname.nm
+	nlist="$output_objdir/${my_outputname}.nm"
 
 	func_show_eval "$RM $nlist ${nlist}S ${nlist}T"
 
@@ -4592,36 +3263,34 @@ func_generate_dlsyms ()
 	func_verbose "creating $output_objdir/$my_dlsyms"
 
 	$opt_dry_run || $ECHO > "$output_objdir/$my_dlsyms" "\
-/* $my_dlsyms - symbol resolution table for '$my_outputname' dlsym emulation. */
-/* Generated by $PROGRAM (GNU $PACKAGE) $VERSION */
+/* $my_dlsyms - symbol resolution table for \`$my_outputname' dlsym emulation. */
+/* Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION */
 
 #ifdef __cplusplus
 extern \"C\" {
 #endif
 
-#if defined __GNUC__ && (((__GNUC__ == 4) && (__GNUC_MINOR__ >= 4)) || (__GNUC__ > 4))
+#if defined(__GNUC__) && (((__GNUC__ == 4) && (__GNUC_MINOR__ >= 4)) || (__GNUC__ > 4))
 #pragma GCC diagnostic ignored \"-Wstrict-prototypes\"
 #endif
 
 /* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests.  */
-#if defined _WIN32 || defined __CYGWIN__ || defined _WIN32_WCE
-/* DATA imports from DLLs on WIN32 can't be const, because runtime
+#if defined(_WIN32) || defined(__CYGWIN__) || defined(_WIN32_WCE)
+/* DATA imports from DLLs on WIN32 con't be const, because runtime
    relocations are performed -- see ld's documentation on pseudo-relocs.  */
 # define LT_DLSYM_CONST
-#elif defined __osf__
+#elif defined(__osf__)
 /* This system does not cope well with relocations in const data.  */
 # define LT_DLSYM_CONST
 #else
 # define LT_DLSYM_CONST const
 #endif
 
-#define STREQ(s1, s2) (strcmp ((s1), (s2)) == 0)
-
 /* External symbol declarations for the compiler. */\
 "
 
-	if test yes = "$dlself"; then
-	  func_verbose "generating symbol list for '$output'"
+	if test "$dlself" = yes; then
+	  func_verbose "generating symbol list for \`$output'"
 
 	  $opt_dry_run || echo ': @PROGRAM@ ' > "$nlist"
 
@@ -4629,7 +3298,7 @@ extern \"C\" {
 	  progfiles=`$ECHO "$objs$old_deplibs" | $SP2NL | $SED "$lo2o" | $NL2SP`
 	  for progfile in $progfiles; do
 	    func_to_tool_file "$progfile" func_convert_file_msys_to_w32
-	    func_verbose "extracting global C symbols from '$func_to_tool_file_result'"
+	    func_verbose "extracting global C symbols from \`$func_to_tool_file_result'"
 	    $opt_dry_run || eval "$NM $func_to_tool_file_result | $global_symbol_pipe >> '$nlist'"
 	  done
 
@@ -4649,10 +3318,10 @@ extern \"C\" {
 
 	  # Prepare the list of exported symbols
 	  if test -z "$export_symbols"; then
-	    export_symbols=$output_objdir/$outputname.exp
+	    export_symbols="$output_objdir/$outputname.exp"
 	    $opt_dry_run || {
 	      $RM $export_symbols
-	      eval "$SED -n -e '/^: @PROGRAM@ $/d' -e 's/^.* \(.*\)$/\1/p' "'< "$nlist" > "$export_symbols"'
+	      eval "${SED} -n -e '/^: @PROGRAM@ $/d' -e 's/^.* \(.*\)$/\1/p' "'< "$nlist" > "$export_symbols"'
 	      case $host in
 	      *cygwin* | *mingw* | *cegcc* )
                 eval "echo EXPORTS "'> "$output_objdir/$outputname.def"'
@@ -4662,7 +3331,7 @@ extern \"C\" {
 	    }
 	  else
 	    $opt_dry_run || {
-	      eval "$SED -e 's/\([].[*^$]\)/\\\\\1/g' -e 's/^/ /' -e 's/$/$/'"' < "$export_symbols" > "$output_objdir/$outputname.exp"'
+	      eval "${SED} -e 's/\([].[*^$]\)/\\\\\1/g' -e 's/^/ /' -e 's/$/$/'"' < "$export_symbols" > "$output_objdir/$outputname.exp"'
 	      eval '$GREP -f "$output_objdir/$outputname.exp" < "$nlist" > "$nlist"T'
 	      eval '$MV "$nlist"T "$nlist"'
 	      case $host in
@@ -4676,22 +3345,22 @@ extern \"C\" {
 	fi
 
 	for dlprefile in $dlprefiles; do
-	  func_verbose "extracting global C symbols from '$dlprefile'"
+	  func_verbose "extracting global C symbols from \`$dlprefile'"
 	  func_basename "$dlprefile"
-	  name=$func_basename_result
+	  name="$func_basename_result"
           case $host in
 	    *cygwin* | *mingw* | *cegcc* )
 	      # if an import library, we need to obtain dlname
 	      if func_win32_import_lib_p "$dlprefile"; then
 	        func_tr_sh "$dlprefile"
 	        eval "curr_lafile=\$libfile_$func_tr_sh_result"
-	        dlprefile_dlbasename=
+	        dlprefile_dlbasename=""
 	        if test -n "$curr_lafile" && func_lalib_p "$curr_lafile"; then
 	          # Use subshell, to avoid clobbering current variable values
 	          dlprefile_dlname=`source "$curr_lafile" && echo "$dlname"`
-	          if test -n "$dlprefile_dlname"; then
+	          if test -n "$dlprefile_dlname" ; then
 	            func_basename "$dlprefile_dlname"
-	            dlprefile_dlbasename=$func_basename_result
+	            dlprefile_dlbasename="$func_basename_result"
 	          else
 	            # no lafile. user explicitly requested -dlpreopen <import library>.
 	            $sharedlib_from_linklib_cmd "$dlprefile"
@@ -4699,7 +3368,7 @@ extern \"C\" {
 	          fi
 	        fi
 	        $opt_dry_run || {
-	          if test -n "$dlprefile_dlbasename"; then
+	          if test -n "$dlprefile_dlbasename" ; then
 	            eval '$ECHO ": $dlprefile_dlbasename" >> "$nlist"'
 	          else
 	            func_warning "Could not compute DLL name from $name"
@@ -4755,11 +3424,6 @@ extern \"C\" {
 	    echo '/* NONE */' >> "$output_objdir/$my_dlsyms"
 	  fi
 
-	  func_show_eval '$RM "${nlist}I"'
-	  if test -n "$global_symbol_to_import"; then
-	    eval "$global_symbol_to_import"' < "$nlist"S > "$nlist"I'
-	  fi
-
 	  echo >> "$output_objdir/$my_dlsyms" "\
 
 /* The mapping between symbol names and symbols.  */
@@ -4768,30 +3432,11 @@ typedef struct {
   void *address;
 } lt_dlsymlist;
 extern LT_DLSYM_CONST lt_dlsymlist
-lt_${my_prefix}_LTX_preloaded_symbols[];\
-"
-
-	  if test -s "$nlist"I; then
-	    echo >> "$output_objdir/$my_dlsyms" "\
-static void lt_syminit(void)
-{
-  LT_DLSYM_CONST lt_dlsymlist *symbol = lt_${my_prefix}_LTX_preloaded_symbols;
-  for (; symbol->name; ++symbol)
-    {"
-	    $SED 's/.*/      if (STREQ (symbol->name, \"&\")) symbol->address = (void *) \&&;/' < "$nlist"I >> "$output_objdir/$my_dlsyms"
-	    echo >> "$output_objdir/$my_dlsyms" "\
-    }
-}"
-	  fi
-	  echo >> "$output_objdir/$my_dlsyms" "\
+lt_${my_prefix}_LTX_preloaded_symbols[];
 LT_DLSYM_CONST lt_dlsymlist
 lt_${my_prefix}_LTX_preloaded_symbols[] =
-{ {\"$my_originator\", (void *) 0},"
-
-	  if test -s "$nlist"I; then
-	    echo >> "$output_objdir/$my_dlsyms" "\
-  {\"@INIT@\", (void *) &lt_syminit},"
-	  fi
+{\
+  { \"$my_originator\", (void *) 0 },"
 
 	  case $need_lib_prefix in
 	  no)
@@ -4833,7 +3478,9 @@ static const void *lt_preloaded_setup() {
 	  *-*-hpux*)
 	    pic_flag_for_symtable=" $pic_flag"  ;;
 	  *)
-	    $my_pic_p && pic_flag_for_symtable=" $pic_flag"
+	    if test "X$my_pic_p" != Xno; then
+	      pic_flag_for_symtable=" $pic_flag"
+	    fi
 	    ;;
 	  esac
 	  ;;
@@ -4850,10 +3497,10 @@ static const void *lt_preloaded_setup() {
 	func_show_eval '(cd $output_objdir && $LTCC$symtab_cflags -c$no_builtin_flag$pic_flag_for_symtable "$my_dlsyms")' 'exit $?'
 
 	# Clean up the generated files.
-	func_show_eval '$RM "$output_objdir/$my_dlsyms" "$nlist" "${nlist}S" "${nlist}T" "${nlist}I"'
+	func_show_eval '$RM "$output_objdir/$my_dlsyms" "$nlist" "${nlist}S" "${nlist}T"'
 
 	# Transform the symbol file into the correct name.
-	symfileobj=$output_objdir/${my_outputname}S.$objext
+	symfileobj="$output_objdir/${my_outputname}S.$objext"
 	case $host in
 	*cygwin* | *mingw* | *cegcc* )
 	  if test -f "$output_objdir/$my_outputname.def"; then
@@ -4871,7 +3518,7 @@ static const void *lt_preloaded_setup() {
 	esac
 	;;
       *)
-	func_fatal_error "unknown suffix for '$my_dlsyms'"
+	func_fatal_error "unknown suffix for \`$my_dlsyms'"
 	;;
       esac
     else
@@ -4885,32 +3532,6 @@ static const void *lt_preloaded_setup() {
     fi
 }
 
-# func_cygming_gnu_implib_p ARG
-# This predicate returns with zero status (TRUE) if
-# ARG is a GNU/binutils-style import library. Returns
-# with nonzero status (FALSE) otherwise.
-func_cygming_gnu_implib_p ()
-{
-  $debug_cmd
-
-  func_to_tool_file "$1" func_convert_file_msys_to_w32
-  func_cygming_gnu_implib_tmp=`$NM "$func_to_tool_file_result" | eval "$global_symbol_pipe" | $EGREP ' (_head_[A-Za-z0-9_]+_[ad]l*|[A-Za-z0-9_]+_[ad]l*_iname)$'`
-  test -n "$func_cygming_gnu_implib_tmp"
-}
-
-# func_cygming_ms_implib_p ARG
-# This predicate returns with zero status (TRUE) if
-# ARG is an MS-style import library. Returns
-# with nonzero status (FALSE) otherwise.
-func_cygming_ms_implib_p ()
-{
-  $debug_cmd
-
-  func_to_tool_file "$1" func_convert_file_msys_to_w32
-  func_cygming_ms_implib_tmp=`$NM "$func_to_tool_file_result" | eval "$global_symbol_pipe" | $GREP '_NULL_IMPORT_DESCRIPTOR'`
-  test -n "$func_cygming_ms_implib_tmp"
-}
-
 # func_win32_libid arg
 # return the library type of file 'arg'
 #
@@ -4920,9 +3541,8 @@ func_cygming_ms_implib_p ()
 # Despite the name, also deal with 64 bit binaries.
 func_win32_libid ()
 {
-  $debug_cmd
-
-  win32_libid_type=unknown
+  $opt_debug
+  win32_libid_type="unknown"
   win32_fileres=`file -L $1 2>/dev/null`
   case $win32_fileres in
   *ar\ archive\ import\ library*) # definitely import
@@ -4932,29 +3552,16 @@ func_win32_libid ()
     # Keep the egrep pattern in sync with the one in _LT_CHECK_MAGIC_METHOD.
     if eval $OBJDUMP -f $1 | $SED -e '10q' 2>/dev/null |
        $EGREP 'file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)' >/dev/null; then
-      case $nm_interface in
-      "MS dumpbin")
-	if func_cygming_ms_implib_p "$1" ||
-	   func_cygming_gnu_implib_p "$1"
-	then
-	  win32_nmres=import
-	else
-	  win32_nmres=
-	fi
-	;;
-      *)
-	func_to_tool_file "$1" func_convert_file_msys_to_w32
-	win32_nmres=`eval $NM -f posix -A \"$func_to_tool_file_result\" |
-	  $SED -n -e '
+      func_to_tool_file "$1" func_convert_file_msys_to_w32
+      win32_nmres=`eval $NM -f posix -A \"$func_to_tool_file_result\" |
+	$SED -n -e '
 	    1,100{
 		/ I /{
-		    s|.*|import|
+		    s,.*,import,
 		    p
 		    q
 		}
 	    }'`
-	;;
-      esac
       case $win32_nmres in
       import*)  win32_libid_type="x86 archive import";;
       *)        win32_libid_type="x86 archive static";;
@@ -4986,8 +3593,7 @@ func_win32_libid ()
 #    $sharedlib_from_linklib_result
 func_cygming_dll_for_implib ()
 {
-  $debug_cmd
-
+  $opt_debug
   sharedlib_from_linklib_result=`$DLLTOOL --identify-strict --identify "$1"`
 }
 
@@ -5004,8 +3610,7 @@ func_cygming_dll_for_implib ()
 # specified import library.
 func_cygming_dll_for_implib_fallback_core ()
 {
-  $debug_cmd
-
+  $opt_debug
   match_literal=`$ECHO "$1" | $SED "$sed_make_literal_regex"`
   $OBJDUMP -s --section "$1" "$2" 2>/dev/null |
     $SED '/^Contents of section '"$match_literal"':/{
@@ -5041,8 +3646,8 @@ func_cygming_dll_for_implib_fallback_core ()
       /./p' |
     # we now have a list, one entry per line, of the stringified
     # contents of the appropriate section of all members of the
-    # archive that possess that section. Heuristic: eliminate
-    # all those that have a first or second character that is
+    # archive which possess that section. Heuristic: eliminate
+    # all those which have a first or second character that is
     # a '.' (that is, objdump's representation of an unprintable
     # character.) This should work for all archives with less than
     # 0x302f exports -- but will fail for DLLs whose name actually
@@ -5053,6 +3658,30 @@ func_cygming_dll_for_implib_fallback_core ()
     $SED -e '/^\./d;/^.\./d;q'
 }
 
+# func_cygming_gnu_implib_p ARG
+# This predicate returns with zero status (TRUE) if
+# ARG is a GNU/binutils-style import library. Returns
+# with nonzero status (FALSE) otherwise.
+func_cygming_gnu_implib_p ()
+{
+  $opt_debug
+  func_to_tool_file "$1" func_convert_file_msys_to_w32
+  func_cygming_gnu_implib_tmp=`$NM "$func_to_tool_file_result" | eval "$global_symbol_pipe" | $EGREP ' (_head_[A-Za-z0-9_]+_[ad]l*|[A-Za-z0-9_]+_[ad]l*_iname)$'`
+  test -n "$func_cygming_gnu_implib_tmp"
+}
+
+# func_cygming_ms_implib_p ARG
+# This predicate returns with zero status (TRUE) if
+# ARG is an MS-style import library. Returns
+# with nonzero status (FALSE) otherwise.
+func_cygming_ms_implib_p ()
+{
+  $opt_debug
+  func_to_tool_file "$1" func_convert_file_msys_to_w32
+  func_cygming_ms_implib_tmp=`$NM "$func_to_tool_file_result" | eval "$global_symbol_pipe" | $GREP '_NULL_IMPORT_DESCRIPTOR'`
+  test -n "$func_cygming_ms_implib_tmp"
+}
+
 # func_cygming_dll_for_implib_fallback ARG
 # Platform-specific function to extract the
 # name of the DLL associated with the specified
@@ -5066,17 +3695,16 @@ func_cygming_dll_for_implib_fallback_core ()
 #    $sharedlib_from_linklib_result
 func_cygming_dll_for_implib_fallback ()
 {
-  $debug_cmd
-
-  if func_cygming_gnu_implib_p "$1"; then
+  $opt_debug
+  if func_cygming_gnu_implib_p "$1" ; then
     # binutils import library
     sharedlib_from_linklib_result=`func_cygming_dll_for_implib_fallback_core '.idata$7' "$1"`
-  elif func_cygming_ms_implib_p "$1"; then
+  elif func_cygming_ms_implib_p "$1" ; then
     # ms-generated import library
     sharedlib_from_linklib_result=`func_cygming_dll_for_implib_fallback_core '.idata$6' "$1"`
   else
     # unknown
-    sharedlib_from_linklib_result=
+    sharedlib_from_linklib_result=""
   fi
 }
 
@@ -5084,11 +3712,10 @@ func_cygming_dll_for_implib_fallback ()
 # func_extract_an_archive dir oldlib
 func_extract_an_archive ()
 {
-    $debug_cmd
-
-    f_ex_an_ar_dir=$1; shift
-    f_ex_an_ar_oldlib=$1
-    if test yes = "$lock_old_archive_extraction"; then
+    $opt_debug
+    f_ex_an_ar_dir="$1"; shift
+    f_ex_an_ar_oldlib="$1"
+    if test "$lock_old_archive_extraction" = yes; then
       lockfile=$f_ex_an_ar_oldlib.lock
       until $opt_dry_run || ln "$progpath" "$lockfile" 2>/dev/null; do
 	func_echo "Waiting for $lockfile to be removed"
@@ -5097,7 +3724,7 @@ func_extract_an_archive ()
     fi
     func_show_eval "(cd \$f_ex_an_ar_dir && $AR x \"\$f_ex_an_ar_oldlib\")" \
 		   'stat=$?; rm -f "$lockfile"; exit $stat'
-    if test yes = "$lock_old_archive_extraction"; then
+    if test "$lock_old_archive_extraction" = yes; then
       $opt_dry_run || rm -f "$lockfile"
     fi
     if ($AR t "$f_ex_an_ar_oldlib" | sort | sort -uc >/dev/null 2>&1); then
@@ -5111,23 +3738,22 @@ func_extract_an_archive ()
 # func_extract_archives gentop oldlib ...
 func_extract_archives ()
 {
-    $debug_cmd
-
-    my_gentop=$1; shift
+    $opt_debug
+    my_gentop="$1"; shift
     my_oldlibs=${1+"$@"}
-    my_oldobjs=
-    my_xlib=
-    my_xabs=
-    my_xdir=
+    my_oldobjs=""
+    my_xlib=""
+    my_xabs=""
+    my_xdir=""
 
     for my_xlib in $my_oldlibs; do
       # Extract the objects.
       case $my_xlib in
-	[\\/]* | [A-Za-z]:[\\/]*) my_xabs=$my_xlib ;;
+	[\\/]* | [A-Za-z]:[\\/]*) my_xabs="$my_xlib" ;;
 	*) my_xabs=`pwd`"/$my_xlib" ;;
       esac
       func_basename "$my_xlib"
-      my_xlib=$func_basename_result
+      my_xlib="$func_basename_result"
       my_xlib_u=$my_xlib
       while :; do
         case " $extracted_archives " in
@@ -5139,7 +3765,7 @@ func_extract_archives ()
 	esac
       done
       extracted_archives="$extracted_archives $my_xlib_u"
-      my_xdir=$my_gentop/$my_xlib_u
+      my_xdir="$my_gentop/$my_xlib_u"
 
       func_mkdir_p "$my_xdir"
 
@@ -5152,23 +3778,22 @@ func_extract_archives ()
 	  cd $my_xdir || exit $?
 	  darwin_archive=$my_xabs
 	  darwin_curdir=`pwd`
-	  func_basename "$darwin_archive"
-	  darwin_base_archive=$func_basename_result
+	  darwin_base_archive=`basename "$darwin_archive"`
 	  darwin_arches=`$LIPO -info "$darwin_archive" 2>/dev/null | $GREP Architectures 2>/dev/null || true`
 	  if test -n "$darwin_arches"; then
 	    darwin_arches=`$ECHO "$darwin_arches" | $SED -e 's/.*are://'`
 	    darwin_arch=
 	    func_verbose "$darwin_base_archive has multiple architectures $darwin_arches"
-	    for darwin_arch in  $darwin_arches; do
-	      func_mkdir_p "unfat-$$/$darwin_base_archive-$darwin_arch"
-	      $LIPO -thin $darwin_arch -output "unfat-$$/$darwin_base_archive-$darwin_arch/$darwin_base_archive" "$darwin_archive"
-	      cd "unfat-$$/$darwin_base_archive-$darwin_arch"
-	      func_extract_an_archive "`pwd`" "$darwin_base_archive"
+	    for darwin_arch in  $darwin_arches ; do
+	      func_mkdir_p "unfat-$$/${darwin_base_archive}-${darwin_arch}"
+	      $LIPO -thin $darwin_arch -output "unfat-$$/${darwin_base_archive}-${darwin_arch}/${darwin_base_archive}" "${darwin_archive}"
+	      cd "unfat-$$/${darwin_base_archive}-${darwin_arch}"
+	      func_extract_an_archive "`pwd`" "${darwin_base_archive}"
 	      cd "$darwin_curdir"
-	      $RM "unfat-$$/$darwin_base_archive-$darwin_arch/$darwin_base_archive"
+	      $RM "unfat-$$/${darwin_base_archive}-${darwin_arch}/${darwin_base_archive}"
 	    done # $darwin_arches
             ## Okay now we've a bunch of thin objects, gotta fatten them up :)
-	    darwin_filelist=`find unfat-$$ -type f -name \*.o -print -o -name \*.lo -print | $SED -e "$sed_basename" | sort -u`
+	    darwin_filelist=`find unfat-$$ -type f -name \*.o -print -o -name \*.lo -print | $SED -e "$basename" | sort -u`
 	    darwin_file=
 	    darwin_files=
 	    for darwin_file in $darwin_filelist; do
@@ -5190,7 +3815,7 @@ func_extract_archives ()
       my_oldobjs="$my_oldobjs "`find $my_xdir -name \*.$objext -print -o -name \*.lo -print | sort | $NL2SP`
     done
 
-    func_extract_archives_result=$my_oldobjs
+    func_extract_archives_result="$my_oldobjs"
 }
 
 
@@ -5205,7 +3830,7 @@ func_extract_archives ()
 #
 # ARG is the value that the WRAPPER_SCRIPT_BELONGS_IN_OBJDIR
 # variable will take.  If 'yes', then the emitted script
-# will assume that the directory where it is stored is
+# will assume that the directory in which it is stored is
 # the $objdir directory.  This is a cygwin/mingw-specific
 # behavior.
 func_emit_wrapper ()
@@ -5216,7 +3841,7 @@ func_emit_wrapper ()
 #! $SHELL
 
 # $output - temporary wrapper script for $objdir/$outputname
-# Generated by $PROGRAM (GNU $PACKAGE) $VERSION
+# Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION
 #
 # The $output program cannot be directly executed until all the libtool
 # libraries that it depends on are installed.
@@ -5273,9 +3898,9 @@ _LTECHO_EOF'
 
 # Very basic option parsing. These options are (a) specific to
 # the libtool wrapper, (b) are identical between the wrapper
-# /script/ and the wrapper /executable/ that is used only on
+# /script/ and the wrapper /executable/ which is used only on
 # windows platforms, and (c) all begin with the string "--lt-"
-# (application programs are unlikely to have options that match
+# (application programs are unlikely to have options which match
 # this pattern).
 #
 # There are only two supported options: --lt-debug and
@@ -5308,7 +3933,7 @@ func_parse_lt_options ()
 
   # Print the debug banner immediately:
   if test -n \"\$lt_option_debug\"; then
-    echo \"$outputname:$output:\$LINENO: libtool wrapper (GNU $PACKAGE) $VERSION\" 1>&2
+    echo \"${outputname}:${output}:\${LINENO}: libtool wrapper (GNU $PACKAGE$TIMESTAMP) $VERSION\" 1>&2
   fi
 }
 
@@ -5319,7 +3944,7 @@ func_lt_dump_args ()
   lt_dump_args_N=1;
   for lt_arg
   do
-    \$ECHO \"$outputname:$output:\$LINENO: newargv[\$lt_dump_args_N]: \$lt_arg\"
+    \$ECHO \"${outputname}:${output}:\${LINENO}: newargv[\$lt_dump_args_N]: \$lt_arg\"
     lt_dump_args_N=\`expr \$lt_dump_args_N + 1\`
   done
 }
@@ -5333,7 +3958,7 @@ func_exec_program_core ()
   *-*-mingw | *-*-os2* | *-cegcc*)
     $ECHO "\
       if test -n \"\$lt_option_debug\"; then
-        \$ECHO \"$outputname:$output:\$LINENO: newargv[0]: \$progdir\\\\\$program\" 1>&2
+        \$ECHO \"${outputname}:${output}:\${LINENO}: newargv[0]: \$progdir\\\\\$program\" 1>&2
         func_lt_dump_args \${1+\"\$@\"} 1>&2
       fi
       exec \"\$progdir\\\\\$program\" \${1+\"\$@\"}
@@ -5343,7 +3968,7 @@ func_exec_program_core ()
   *)
     $ECHO "\
       if test -n \"\$lt_option_debug\"; then
-        \$ECHO \"$outputname:$output:\$LINENO: newargv[0]: \$progdir/\$program\" 1>&2
+        \$ECHO \"${outputname}:${output}:\${LINENO}: newargv[0]: \$progdir/\$program\" 1>&2
         func_lt_dump_args \${1+\"\$@\"} 1>&2
       fi
       exec \"\$progdir/\$program\" \${1+\"\$@\"}
@@ -5418,13 +4043,13 @@ func_exec_program ()
   test -n \"\$absdir\" && thisdir=\"\$absdir\"
 "
 
-	if test yes = "$fast_install"; then
+	if test "$fast_install" = yes; then
 	  $ECHO "\
   program=lt-'$outputname'$exeext
   progdir=\"\$thisdir/$objdir\"
 
   if test ! -f \"\$progdir/\$program\" ||
-     { file=\`ls -1dt \"\$progdir/\$program\" \"\$progdir/../\$program\" 2>/dev/null | $SED 1q\`; \\
+     { file=\`ls -1dt \"\$progdir/\$program\" \"\$progdir/../\$program\" 2>/dev/null | ${SED} 1q\`; \\
        test \"X\$file\" != \"X\$progdir/\$program\"; }; then
 
     file=\"\$\$-\$program\"
@@ -5441,7 +4066,7 @@ func_exec_program ()
     if test -n \"\$relink_command\"; then
       if relink_command_output=\`eval \$relink_command 2>&1\`; then :
       else
-	\$ECHO \"\$relink_command_output\" >&2
+	$ECHO \"\$relink_command_output\" >&2
 	$RM \"\$progdir/\$file\"
 	exit 1
       fi
@@ -5476,7 +4101,7 @@ func_exec_program ()
 	fi
 
 	# Export our shlibpath_var if we have one.
-	if test yes = "$shlibpath_overrides_runpath" && test -n "$shlibpath_var" && test -n "$temp_rpath"; then
+	if test "$shlibpath_overrides_runpath" = yes && test -n "$shlibpath_var" && test -n "$temp_rpath"; then
 	  $ECHO "\
     # Add our own library path to $shlibpath_var
     $shlibpath_var=\"$temp_rpath\$$shlibpath_var\"
@@ -5496,7 +4121,7 @@ func_exec_program ()
     fi
   else
     # The program doesn't exist.
-    \$ECHO \"\$0: error: '\$progdir/\$program' does not exist\" 1>&2
+    \$ECHO \"\$0: error: \\\`\$progdir/\$program' does not exist\" 1>&2
     \$ECHO \"This script is just a wrapper for \$program.\" 1>&2
     \$ECHO \"See the $PACKAGE documentation for more information.\" 1>&2
     exit 1
@@ -5515,7 +4140,7 @@ func_emit_cwrapperexe_src ()
 	cat <<EOF
 
 /* $cwrappersource - temporary wrapper executable for $objdir/$outputname
-   Generated by $PROGRAM (GNU $PACKAGE) $VERSION
+   Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION
 
    The $output program cannot be directly executed until all the libtool
    libraries that it depends on are installed.
@@ -5550,45 +4175,47 @@ EOF
 #include <fcntl.h>
 #include <sys/stat.h>
 
-#define STREQ(s1, s2) (strcmp ((s1), (s2)) == 0)
-
 /* declarations of non-ANSI functions */
-#if defined __MINGW32__
+#if defined(__MINGW32__)
 # ifdef __STRICT_ANSI__
 int _putenv (const char *);
 # endif
-#elif defined __CYGWIN__
+#elif defined(__CYGWIN__)
 # ifdef __STRICT_ANSI__
 char *realpath (const char *, char *);
 int putenv (char *);
 int setenv (const char *, const char *, int);
 # endif
-/* #elif defined other_platform || defined ... */
+/* #elif defined (other platforms) ... */
 #endif
 
 /* portability defines, excluding path handling macros */
-#if defined _MSC_VER
+#if defined(_MSC_VER)
 # define setmode _setmode
 # define stat    _stat
 # define chmod   _chmod
 # define getcwd  _getcwd
 # define putenv  _putenv
 # define S_IXUSR _S_IEXEC
-#elif defined __MINGW32__
+# ifndef _INTPTR_T_DEFINED
+#  define _INTPTR_T_DEFINED
+#  define intptr_t int
+# endif
+#elif defined(__MINGW32__)
 # define setmode _setmode
 # define stat    _stat
 # define chmod   _chmod
 # define getcwd  _getcwd
 # define putenv  _putenv
-#elif defined __CYGWIN__
+#elif defined(__CYGWIN__)
 # define HAVE_SETENV
 # define FOPEN_WB "wb"
-/* #elif defined other platforms ... */
+/* #elif defined (other platforms) ... */
 #endif
 
-#if defined PATH_MAX
+#if defined(PATH_MAX)
 # define LT_PATHMAX PATH_MAX
-#elif defined MAXPATHLEN
+#elif defined(MAXPATHLEN)
 # define LT_PATHMAX MAXPATHLEN
 #else
 # define LT_PATHMAX 1024
@@ -5607,8 +4234,8 @@ int setenv (const char *, const char *, int);
 # define PATH_SEPARATOR ':'
 #endif
 
-#if defined _WIN32 || defined __MSDOS__ || defined __DJGPP__ || \
-  defined __OS2__
+#if defined (_WIN32) || defined (__MSDOS__) || defined (__DJGPP__) || \
+  defined (__OS2__)
 # define HAVE_DOS_BASED_FILE_SYSTEM
 # define FOPEN_WB "wb"
 # ifndef DIR_SEPARATOR_2
@@ -5641,10 +4268,10 @@ int setenv (const char *, const char *, int);
 
 #define XMALLOC(type, num)      ((type *) xmalloc ((num) * sizeof(type)))
 #define XFREE(stale) do { \
-  if (stale) { free (stale); stale = 0; } \
+  if (stale) { free ((void *) stale); stale = 0; } \
 } while (0)
 
-#if defined LT_DEBUGWRAPPER
+#if defined(LT_DEBUGWRAPPER)
 static int lt_debug = 1;
 #else
 static int lt_debug = 0;
@@ -5673,16 +4300,11 @@ void lt_dump_script (FILE *f);
 EOF
 
 	    cat <<EOF
-#if __GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 5)
-# define externally_visible volatile
-#else
-# define externally_visible __attribute__((externally_visible)) volatile
-#endif
-externally_visible const char * MAGIC_EXE = "$magic_exe";
+volatile const char * MAGIC_EXE = "$magic_exe";
 const char * LIB_PATH_VARNAME = "$shlibpath_var";
 EOF
 
-	    if test yes = "$shlibpath_overrides_runpath" && test -n "$shlibpath_var" && test -n "$temp_rpath"; then
+	    if test "$shlibpath_overrides_runpath" = yes && test -n "$shlibpath_var" && test -n "$temp_rpath"; then
               func_to_host_path "$temp_rpath"
 	      cat <<EOF
 const char * LIB_PATH_VALUE   = "$func_to_host_path_result";
@@ -5706,7 +4328,7 @@ const char * EXE_PATH_VALUE   = "";
 EOF
 	    fi
 
-	    if test yes = "$fast_install"; then
+	    if test "$fast_install" = yes; then
 	      cat <<EOF
 const char * TARGET_PROGRAM_NAME = "lt-$outputname"; /* hopefully, no .exe */
 EOF
@@ -5735,12 +4357,12 @@ main (int argc, char *argv[])
   char *actual_cwrapper_name;
   char *target_name;
   char *lt_argv_zero;
-  int rval = 127;
+  intptr_t rval = 127;
 
   int i;
 
   program_name = (char *) xstrdup (base_name (argv[0]));
-  newargz = XMALLOC (char *, (size_t) argc + 1);
+  newargz = XMALLOC (char *, argc + 1);
 
   /* very simple arg parsing; don't want to rely on getopt
    * also, copy all non cwrapper options to newargz, except
@@ -5749,10 +4371,10 @@ main (int argc, char *argv[])
   newargc=0;
   for (i = 1; i < argc; i++)
     {
-      if (STREQ (argv[i], dumpscript_opt))
+      if (strcmp (argv[i], dumpscript_opt) == 0)
 	{
 EOF
-	    case $host in
+	    case "$host" in
 	      *mingw* | *cygwin* )
 		# make stdout use "unix" line endings
 		echo "          setmode(1,_O_BINARY);"
@@ -5763,12 +4385,12 @@ EOF
 	  lt_dump_script (stdout);
 	  return 0;
 	}
-      if (STREQ (argv[i], debug_opt))
+      if (strcmp (argv[i], debug_opt) == 0)
 	{
           lt_debug = 1;
           continue;
 	}
-      if (STREQ (argv[i], ltwrapper_option_prefix))
+      if (strcmp (argv[i], ltwrapper_option_prefix) == 0)
         {
           /* however, if there is an option in the LTWRAPPER_OPTION_PREFIX
              namespace, but it is not one of the ones we know about and
@@ -5791,7 +4413,7 @@ EOF
 EOF
 	    cat <<EOF
   /* The GNU banner must be the first non-error debug message */
-  lt_debugprintf (__FILE__, __LINE__, "libtool wrapper (GNU $PACKAGE) $VERSION\n");
+  lt_debugprintf (__FILE__, __LINE__, "libtool wrapper (GNU $PACKAGE$TIMESTAMP) $VERSION\n");
 EOF
 	    cat <<"EOF"
   lt_debugprintf (__FILE__, __LINE__, "(main) argv[0]: %s\n", argv[0]);
@@ -5902,7 +4524,7 @@ EOF
 		cat <<"EOF"
   /* execv doesn't actually work on mingw as expected on unix */
   newargz = prepare_spawn (newargz);
-  rval = (int) _spawnv (_P_WAIT, lt_argv_zero, (const char * const *) newargz);
+  rval = _spawnv (_P_WAIT, lt_argv_zero, (const char * const *) newargz);
   if (rval == -1)
     {
       /* failed to start process */
@@ -5947,7 +4569,7 @@ base_name (const char *name)
 {
   const char *base;
 
-#if defined HAVE_DOS_BASED_FILE_SYSTEM
+#if defined (HAVE_DOS_BASED_FILE_SYSTEM)
   /* Skip over the disk name in MSDOS pathnames. */
   if (isalpha ((unsigned char) name[0]) && name[1] == ':')
     name += 2;
@@ -6006,7 +4628,7 @@ find_executable (const char *wrapper)
   const char *p_next;
   /* static buffer for getcwd */
   char tmp[LT_PATHMAX + 1];
-  size_t tmp_len;
+  int tmp_len;
   char *concat_name;
 
   lt_debugprintf (__FILE__, __LINE__, "(find_executable): %s\n",
@@ -6016,7 +4638,7 @@ find_executable (const char *wrapper)
     return NULL;
 
   /* Absolute path? */
-#if defined HAVE_DOS_BASED_FILE_SYSTEM
+#if defined (HAVE_DOS_BASED_FILE_SYSTEM)
   if (isalpha ((unsigned char) wrapper[0]) && wrapper[1] == ':')
     {
       concat_name = xstrdup (wrapper);
@@ -6034,7 +4656,7 @@ find_executable (const char *wrapper)
 	    return concat_name;
 	  XFREE (concat_name);
 	}
-#if defined HAVE_DOS_BASED_FILE_SYSTEM
+#if defined (HAVE_DOS_BASED_FILE_SYSTEM)
     }
 #endif
 
@@ -6057,7 +4679,7 @@ find_executable (const char *wrapper)
 	      for (q = p; *q; q++)
 		if (IS_PATH_SEPARATOR (*q))
 		  break;
-	      p_len = (size_t) (q - p);
+	      p_len = q - p;
 	      p_next = (*q == '\0' ? q : q + 1);
 	      if (p_len == 0)
 		{
@@ -6176,7 +4798,7 @@ strendzap (char *str, const char *pat)
   if (patlen <= len)
     {
       str += len - patlen;
-      if (STREQ (str, pat))
+      if (strcmp (str, pat) == 0)
 	*str = '\0';
     }
   return str;
@@ -6241,7 +4863,7 @@ lt_setenv (const char *name, const char *value)
     char *str = xstrdup (value);
     setenv (name, str, 1);
 #else
-    size_t len = strlen (name) + 1 + strlen (value) + 1;
+    int len = strlen (name) + 1 + strlen (value) + 1;
     char *str = XMALLOC (char, len);
     sprintf (str, "%s=%s", name, value);
     if (putenv (str) != EXIT_SUCCESS)
@@ -6258,8 +4880,8 @@ lt_extend_str (const char *orig_value, const char *add, int to_end)
   char *new_value;
   if (orig_value && *orig_value)
     {
-      size_t orig_value_len = strlen (orig_value);
-      size_t add_len = strlen (add);
+      int orig_value_len = strlen (orig_value);
+      int add_len = strlen (add);
       new_value = XMALLOC (char, add_len + orig_value_len + 1);
       if (to_end)
         {
@@ -6290,10 +4912,10 @@ lt_update_exe_path (const char *name, const char *value)
     {
       char *new_value = lt_extend_str (getenv (name), value, 0);
       /* some systems can't cope with a ':'-terminated path #' */
-      size_t len = strlen (new_value);
-      while ((len > 0) && IS_PATH_SEPARATOR (new_value[len-1]))
+      int len = strlen (new_value);
+      while (((len = strlen (new_value)) > 0) && IS_PATH_SEPARATOR (new_value[len-1]))
         {
-          new_value[--len] = '\0';
+          new_value[len-1] = '\0';
         }
       lt_setenv (name, new_value);
       XFREE (new_value);
@@ -6460,47 +5082,27 @@ EOF
 # True if ARG is an import lib, as indicated by $file_magic_cmd
 func_win32_import_lib_p ()
 {
-    $debug_cmd
-
+    $opt_debug
     case `eval $file_magic_cmd \"\$1\" 2>/dev/null | $SED -e 10q` in
     *import*) : ;;
     *) false ;;
     esac
 }
 
-# func_suncc_cstd_abi
-# !!ONLY CALL THIS FOR SUN CC AFTER $compile_command IS FULLY EXPANDED!!
-# Several compiler flags select an ABI that is incompatible with the
-# Cstd library. Avoid specifying it if any are in CXXFLAGS.
-func_suncc_cstd_abi ()
-{
-    $debug_cmd
-
-    case " $compile_command " in
-    *" -compat=g "*|*\ -std=c++[0-9][0-9]\ *|*" -library=stdcxx4 "*|*" -library=stlport4 "*)
-      suncc_use_cstd_abi=no
-      ;;
-    *)
-      suncc_use_cstd_abi=yes
-      ;;
-    esac
-}
-
 # func_mode_link arg...
 func_mode_link ()
 {
-    $debug_cmd
-
+    $opt_debug
     case $host in
     *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*)
       # It is impossible to link a dll without this setting, and
       # we shouldn't force the makefile maintainer to figure out
-      # what system we are compiling for in order to pass an extra
+      # which system we are compiling for in order to pass an extra
       # flag for every libtool invocation.
       # allow_undefined=no
 
       # FIXME: Unfortunately, there are problems with the above when trying
-      # to make a dll that has undefined symbols, in which case not
+      # to make a dll which has undefined symbols, in which case not
       # even a static library is built.  For now, we need to specify
       # -no-undefined on the libtool link line when we can be certain
       # that all symbols are satisfied, otherwise we get a static library.
@@ -6544,11 +5146,10 @@ func_mode_link ()
     module=no
     no_install=no
     objs=
-    os2dllname=
     non_pic_objects=
     precious_files_regex=
     prefer_static_libs=no
-    preload=false
+    preload=no
     prev=
     prevarg=
     release=
@@ -6560,7 +5161,7 @@ func_mode_link ()
     vinfo=
     vinfo_number=no
     weak_libs=
-    single_module=$wl-single_module
+    single_module="${wl}-single_module"
     func_infer_tag $base_compile
 
     # We need to know -static, to get the right output filenames.
@@ -6568,15 +5169,15 @@ func_mode_link ()
     do
       case $arg in
       -shared)
-	test yes != "$build_libtool_libs" \
-	  && func_fatal_configuration "cannot build a shared library"
+	test "$build_libtool_libs" != yes && \
+	  func_fatal_configuration "can not build a shared library"
 	build_old_libs=no
 	break
 	;;
       -all-static | -static | -static-libtool-libs)
 	case $arg in
 	-all-static)
-	  if test yes = "$build_libtool_libs" && test -z "$link_static_flag"; then
+	  if test "$build_libtool_libs" = yes && test -z "$link_static_flag"; then
 	    func_warning "complete static linking is impossible in this configuration"
 	  fi
 	  if test -n "$link_static_flag"; then
@@ -6609,7 +5210,7 @@ func_mode_link ()
 
     # Go through the arguments, transforming them on the way.
     while test "$#" -gt 0; do
-      arg=$1
+      arg="$1"
       shift
       func_quote_for_eval "$arg"
       qarg=$func_quote_for_eval_unquoted_result
@@ -6626,21 +5227,21 @@ func_mode_link ()
 
 	case $prev in
 	bindir)
-	  bindir=$arg
+	  bindir="$arg"
 	  prev=
 	  continue
 	  ;;
 	dlfiles|dlprefiles)
-	  $preload || {
+	  if test "$preload" = no; then
 	    # Add the symbol object into the linking commands.
 	    func_append compile_command " @SYMFILE@"
 	    func_append finalize_command " @SYMFILE@"
-	    preload=:
-	  }
+	    preload=yes
+	  fi
 	  case $arg in
 	  *.la | *.lo) ;;  # We handle these cases below.
 	  force)
-	    if test no = "$dlself"; then
+	    if test "$dlself" = no; then
 	      dlself=needless
 	      export_dynamic=yes
 	    fi
@@ -6648,9 +5249,9 @@ func_mode_link ()
 	    continue
 	    ;;
 	  self)
-	    if test dlprefiles = "$prev"; then
+	    if test "$prev" = dlprefiles; then
 	      dlself=yes
-	    elif test dlfiles = "$prev" && test yes != "$dlopen_self"; then
+	    elif test "$prev" = dlfiles && test "$dlopen_self" != yes; then
 	      dlself=yes
 	    else
 	      dlself=needless
@@ -6660,7 +5261,7 @@ func_mode_link ()
 	    continue
 	    ;;
 	  *)
-	    if test dlfiles = "$prev"; then
+	    if test "$prev" = dlfiles; then
 	      func_append dlfiles " $arg"
 	    else
 	      func_append dlprefiles " $arg"
@@ -6671,14 +5272,14 @@ func_mode_link ()
 	  esac
 	  ;;
 	expsyms)
-	  export_symbols=$arg
+	  export_symbols="$arg"
 	  test -f "$arg" \
-	    || func_fatal_error "symbol file '$arg' does not exist"
+	    || func_fatal_error "symbol file \`$arg' does not exist"
 	  prev=
 	  continue
 	  ;;
 	expsyms_regex)
-	  export_symbols_regex=$arg
+	  export_symbols_regex="$arg"
 	  prev=
 	  continue
 	  ;;
@@ -6696,13 +5297,7 @@ func_mode_link ()
 	  continue
 	  ;;
 	inst_prefix)
-	  inst_prefix_dir=$arg
-	  prev=
-	  continue
-	  ;;
-	mllvm)
-	  # Clang does not use LLVM to link, so we can simply discard any
-	  # '-mllvm $arg' options when doing the link step.
+	  inst_prefix_dir="$arg"
 	  prev=
 	  continue
 	  ;;
@@ -6726,21 +5321,21 @@ func_mode_link ()
 
 		if test -z "$pic_object" ||
 		   test -z "$non_pic_object" ||
-		   test none = "$pic_object" &&
-		   test none = "$non_pic_object"; then
-		  func_fatal_error "cannot find name of object for '$arg'"
+		   test "$pic_object" = none &&
+		   test "$non_pic_object" = none; then
+		  func_fatal_error "cannot find name of object for \`$arg'"
 		fi
 
 		# Extract subdirectory from the argument.
 		func_dirname "$arg" "/" ""
-		xdir=$func_dirname_result
+		xdir="$func_dirname_result"
 
-		if test none != "$pic_object"; then
+		if test "$pic_object" != none; then
 		  # Prepend the subdirectory the object is found in.
-		  pic_object=$xdir$pic_object
+		  pic_object="$xdir$pic_object"
 
-		  if test dlfiles = "$prev"; then
-		    if test yes = "$build_libtool_libs" && test yes = "$dlopen_support"; then
+		  if test "$prev" = dlfiles; then
+		    if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then
 		      func_append dlfiles " $pic_object"
 		      prev=
 		      continue
@@ -6751,7 +5346,7 @@ func_mode_link ()
 		  fi
 
 		  # CHECK ME:  I think I busted this.  -Ossama
-		  if test dlprefiles = "$prev"; then
+		  if test "$prev" = dlprefiles; then
 		    # Preload the old-style object.
 		    func_append dlprefiles " $pic_object"
 		    prev=
@@ -6759,23 +5354,23 @@ func_mode_link ()
 
 		  # A PIC object.
 		  func_append libobjs " $pic_object"
-		  arg=$pic_object
+		  arg="$pic_object"
 		fi
 
 		# Non-PIC object.
-		if test none != "$non_pic_object"; then
+		if test "$non_pic_object" != none; then
 		  # Prepend the subdirectory the object is found in.
-		  non_pic_object=$xdir$non_pic_object
+		  non_pic_object="$xdir$non_pic_object"
 
 		  # A standard non-PIC object
 		  func_append non_pic_objects " $non_pic_object"
-		  if test -z "$pic_object" || test none = "$pic_object"; then
-		    arg=$non_pic_object
+		  if test -z "$pic_object" || test "$pic_object" = none ; then
+		    arg="$non_pic_object"
 		  fi
 		else
 		  # If the PIC object exists, use it instead.
 		  # $xdir was prepended to $pic_object above.
-		  non_pic_object=$pic_object
+		  non_pic_object="$pic_object"
 		  func_append non_pic_objects " $non_pic_object"
 		fi
 	      else
@@ -6783,7 +5378,7 @@ func_mode_link ()
 		if $opt_dry_run; then
 		  # Extract subdirectory from the argument.
 		  func_dirname "$arg" "/" ""
-		  xdir=$func_dirname_result
+		  xdir="$func_dirname_result"
 
 		  func_lo2o "$arg"
 		  pic_object=$xdir$objdir/$func_lo2o_result
@@ -6791,29 +5386,24 @@ func_mode_link ()
 		  func_append libobjs " $pic_object"
 		  func_append non_pic_objects " $non_pic_object"
 	        else
-		  func_fatal_error "'$arg' is not a valid libtool object"
+		  func_fatal_error "\`$arg' is not a valid libtool object"
 		fi
 	      fi
 	    done
 	  else
-	    func_fatal_error "link input file '$arg' does not exist"
+	    func_fatal_error "link input file \`$arg' does not exist"
 	  fi
 	  arg=$save_arg
 	  prev=
 	  continue
 	  ;;
-	os2dllname)
-	  os2dllname=$arg
-	  prev=
-	  continue
-	  ;;
 	precious_regex)
-	  precious_files_regex=$arg
+	  precious_files_regex="$arg"
 	  prev=
 	  continue
 	  ;;
 	release)
-	  release=-$arg
+	  release="-$arg"
 	  prev=
 	  continue
 	  ;;
@@ -6825,7 +5415,7 @@ func_mode_link ()
 	    func_fatal_error "only absolute run-paths are allowed"
 	    ;;
 	  esac
-	  if test rpath = "$prev"; then
+	  if test "$prev" = rpath; then
 	    case "$rpath " in
 	    *" $arg "*) ;;
 	    *) func_append rpath " $arg" ;;
@@ -6840,7 +5430,7 @@ func_mode_link ()
 	  continue
 	  ;;
 	shrext)
-	  shrext_cmds=$arg
+	  shrext_cmds="$arg"
 	  prev=
 	  continue
 	  ;;
@@ -6880,7 +5470,7 @@ func_mode_link ()
 	esac
       fi # test -n "$prev"
 
-      prevarg=$arg
+      prevarg="$arg"
 
       case $arg in
       -all-static)
@@ -6894,7 +5484,7 @@ func_mode_link ()
 
       -allow-undefined)
 	# FIXME: remove this flag sometime in the future.
-	func_fatal_error "'-allow-undefined' must not be used because it is the default"
+	func_fatal_error "\`-allow-undefined' must not be used because it is the default"
 	;;
 
       -avoid-version)
@@ -6926,7 +5516,7 @@ func_mode_link ()
 	if test -n "$export_symbols" || test -n "$export_symbols_regex"; then
 	  func_fatal_error "more than one -exported-symbols argument is not allowed"
 	fi
-	if test X-export-symbols = "X$arg"; then
+	if test "X$arg" = "X-export-symbols"; then
 	  prev=expsyms
 	else
 	  prev=expsyms_regex
@@ -6960,9 +5550,9 @@ func_mode_link ()
 	func_stripname "-L" '' "$arg"
 	if test -z "$func_stripname_result"; then
 	  if test "$#" -gt 0; then
-	    func_fatal_error "require no space between '-L' and '$1'"
+	    func_fatal_error "require no space between \`-L' and \`$1'"
 	  else
-	    func_fatal_error "need path for '-L' option"
+	    func_fatal_error "need path for \`-L' option"
 	  fi
 	fi
 	func_resolve_sysroot "$func_stripname_result"
@@ -6973,8 +5563,8 @@ func_mode_link ()
 	*)
 	  absdir=`cd "$dir" && pwd`
 	  test -z "$absdir" && \
-	    func_fatal_error "cannot determine absolute directory name of '$dir'"
-	  dir=$absdir
+	    func_fatal_error "cannot determine absolute directory name of \`$dir'"
+	  dir="$absdir"
 	  ;;
 	esac
 	case "$deplibs " in
@@ -7009,7 +5599,7 @@ func_mode_link ()
 	;;
 
       -l*)
-	if test X-lc = "X$arg" || test X-lm = "X$arg"; then
+	if test "X$arg" = "X-lc" || test "X$arg" = "X-lm"; then
 	  case $host in
 	  *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-beos* | *-cegcc* | *-*-haiku*)
 	    # These systems don't actually have a C or math library (as such)
@@ -7017,11 +5607,11 @@ func_mode_link ()
 	    ;;
 	  *-*-os2*)
 	    # These systems don't actually have a C library (as such)
-	    test X-lc = "X$arg" && continue
+	    test "X$arg" = "X-lc" && continue
 	    ;;
-	  *-*-openbsd* | *-*-freebsd* | *-*-dragonfly* | *-*-bitrig*)
+	  *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*)
 	    # Do not include libc due to us having libc/libc_r.
-	    test X-lc = "X$arg" && continue
+	    test "X$arg" = "X-lc" && continue
 	    ;;
 	  *-*-rhapsody* | *-*-darwin1.[012])
 	    # Rhapsody C and math libraries are in the System framework
@@ -7030,16 +5620,16 @@ func_mode_link ()
 	    ;;
 	  *-*-sco3.2v5* | *-*-sco5v6*)
 	    # Causes problems with __ctype
-	    test X-lc = "X$arg" && continue
+	    test "X$arg" = "X-lc" && continue
 	    ;;
 	  *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*)
 	    # Compiler inserts libc in the correct place for threads to work
-	    test X-lc = "X$arg" && continue
+	    test "X$arg" = "X-lc" && continue
 	    ;;
 	  esac
-	elif test X-lc_r = "X$arg"; then
+	elif test "X$arg" = "X-lc_r"; then
 	 case $host in
-	 *-*-openbsd* | *-*-freebsd* | *-*-dragonfly* | *-*-bitrig*)
+	 *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*)
 	   # Do not include libc_r directly, use -pthread flag.
 	   continue
 	   ;;
@@ -7049,11 +5639,6 @@ func_mode_link ()
 	continue
 	;;
 
-      -mllvm)
-	prev=mllvm
-	continue
-	;;
-
       -module)
 	module=yes
 	continue
@@ -7083,7 +5668,7 @@ func_mode_link ()
 	;;
 
       -multi_module)
-	single_module=$wl-multi_module
+	single_module="${wl}-multi_module"
 	continue
 	;;
 
@@ -7097,8 +5682,8 @@ func_mode_link ()
 	*-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-darwin* | *-cegcc*)
 	  # The PATH hackery in wrapper scripts is required on Windows
 	  # and Darwin in order for the loader to find any dlls it needs.
-	  func_warning "'-no-install' is ignored for $host"
-	  func_warning "assuming '-no-fast-install' instead"
+	  func_warning "\`-no-install' is ignored for $host"
+	  func_warning "assuming \`-no-fast-install' instead"
 	  fast_install=no
 	  ;;
 	*) no_install=yes ;;
@@ -7116,11 +5701,6 @@ func_mode_link ()
 	continue
 	;;
 
-      -os2dllname)
-	prev=os2dllname
-	continue
-	;;
-
       -o) prev=output ;;
 
       -precious-files-regex)
@@ -7208,14 +5788,14 @@ func_mode_link ()
 	func_stripname '-Wc,' '' "$arg"
 	args=$func_stripname_result
 	arg=
-	save_ifs=$IFS; IFS=,
+	save_ifs="$IFS"; IFS=','
 	for flag in $args; do
-	  IFS=$save_ifs
+	  IFS="$save_ifs"
           func_quote_for_eval "$flag"
 	  func_append arg " $func_quote_for_eval_result"
 	  func_append compiler_flags " $func_quote_for_eval_result"
 	done
-	IFS=$save_ifs
+	IFS="$save_ifs"
 	func_stripname ' ' '' "$arg"
 	arg=$func_stripname_result
 	;;
@@ -7224,15 +5804,15 @@ func_mode_link ()
 	func_stripname '-Wl,' '' "$arg"
 	args=$func_stripname_result
 	arg=
-	save_ifs=$IFS; IFS=,
+	save_ifs="$IFS"; IFS=','
 	for flag in $args; do
-	  IFS=$save_ifs
+	  IFS="$save_ifs"
           func_quote_for_eval "$flag"
 	  func_append arg " $wl$func_quote_for_eval_result"
 	  func_append compiler_flags " $wl$func_quote_for_eval_result"
 	  func_append linker_flags " $func_quote_for_eval_result"
 	done
-	IFS=$save_ifs
+	IFS="$save_ifs"
 	func_stripname ' ' '' "$arg"
 	arg=$func_stripname_result
 	;;
@@ -7255,7 +5835,7 @@ func_mode_link ()
       # -msg_* for osf cc
       -msg_*)
 	func_quote_for_eval "$arg"
-	arg=$func_quote_for_eval_result
+	arg="$func_quote_for_eval_result"
 	;;
 
       # Flags to be passed through unchanged, with rationale:
@@ -7267,49 +5847,25 @@ func_mode_link ()
       # -m*, -t[45]*, -txscale* architecture-specific flags for GCC
       # -F/path              path to uninstalled frameworks, gcc on darwin
       # -p, -pg, --coverage, -fprofile-*  profiling flags for GCC
-      # -fstack-protector*   stack protector flags for GCC
       # @file                GCC response files
       # -tp=*                Portland pgcc target processor selection
       # --sysroot=*          for sysroot support
-      # -O*, -g*, -flto*, -fwhopr*, -fuse-linker-plugin GCC link-time optimization
-      # -specs=*             GCC specs files
-      # -stdlib=*            select c++ std lib with clang
-      # -fsanitize=*         Clang/GCC memory and address sanitizer
+      # -O*, -flto*, -fwhopr*, -fuse-linker-plugin GCC link-time optimization
       -64|-mips[0-9]|-r[0-9][0-9]*|-xarch=*|-xtarget=*|+DA*|+DD*|-q*|-m*| \
       -t[45]*|-txscale*|-p|-pg|--coverage|-fprofile-*|-F*|@*|-tp=*|--sysroot=*| \
-      -O*|-g*|-flto*|-fwhopr*|-fuse-linker-plugin|-fstack-protector*|-stdlib=*| \
-      -specs=*|-fsanitize=*)
+      -O*|-flto*|-fwhopr*|-fuse-linker-plugin)
         func_quote_for_eval "$arg"
-	arg=$func_quote_for_eval_result
+	arg="$func_quote_for_eval_result"
         func_append compile_command " $arg"
         func_append finalize_command " $arg"
         func_append compiler_flags " $arg"
         continue
         ;;
 
-      -Z*)
-        if test os2 = "`expr $host : '.*\(os2\)'`"; then
-          # OS/2 uses -Zxxx to specify OS/2-specific options
-	  compiler_flags="$compiler_flags $arg"
-	  func_append compile_command " $arg"
-	  func_append finalize_command " $arg"
-	  case $arg in
-	  -Zlinker | -Zstack)
-	    prev=xcompiler
-	    ;;
-	  esac
-	  continue
-        else
-	  # Otherwise treat like 'Some other compiler flag' below
-	  func_quote_for_eval "$arg"
-	  arg=$func_quote_for_eval_result
-        fi
-	;;
-
       # Some other compiler flag.
       -* | +*)
         func_quote_for_eval "$arg"
-	arg=$func_quote_for_eval_result
+	arg="$func_quote_for_eval_result"
 	;;
 
       *.$objext)
@@ -7330,21 +5886,21 @@ func_mode_link ()
 
 	  if test -z "$pic_object" ||
 	     test -z "$non_pic_object" ||
-	     test none = "$pic_object" &&
-	     test none = "$non_pic_object"; then
-	    func_fatal_error "cannot find name of object for '$arg'"
+	     test "$pic_object" = none &&
+	     test "$non_pic_object" = none; then
+	    func_fatal_error "cannot find name of object for \`$arg'"
 	  fi
 
 	  # Extract subdirectory from the argument.
 	  func_dirname "$arg" "/" ""
-	  xdir=$func_dirname_result
+	  xdir="$func_dirname_result"
 
-	  test none = "$pic_object" || {
+	  if test "$pic_object" != none; then
 	    # Prepend the subdirectory the object is found in.
-	    pic_object=$xdir$pic_object
+	    pic_object="$xdir$pic_object"
 
-	    if test dlfiles = "$prev"; then
-	      if test yes = "$build_libtool_libs" && test yes = "$dlopen_support"; then
+	    if test "$prev" = dlfiles; then
+	      if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then
 		func_append dlfiles " $pic_object"
 		prev=
 		continue
@@ -7355,7 +5911,7 @@ func_mode_link ()
 	    fi
 
 	    # CHECK ME:  I think I busted this.  -Ossama
-	    if test dlprefiles = "$prev"; then
+	    if test "$prev" = dlprefiles; then
 	      # Preload the old-style object.
 	      func_append dlprefiles " $pic_object"
 	      prev=
@@ -7363,23 +5919,23 @@ func_mode_link ()
 
 	    # A PIC object.
 	    func_append libobjs " $pic_object"
-	    arg=$pic_object
-	  }
+	    arg="$pic_object"
+	  fi
 
 	  # Non-PIC object.
-	  if test none != "$non_pic_object"; then
+	  if test "$non_pic_object" != none; then
 	    # Prepend the subdirectory the object is found in.
-	    non_pic_object=$xdir$non_pic_object
+	    non_pic_object="$xdir$non_pic_object"
 
 	    # A standard non-PIC object
 	    func_append non_pic_objects " $non_pic_object"
-	    if test -z "$pic_object" || test none = "$pic_object"; then
-	      arg=$non_pic_object
+	    if test -z "$pic_object" || test "$pic_object" = none ; then
+	      arg="$non_pic_object"
 	    fi
 	  else
 	    # If the PIC object exists, use it instead.
 	    # $xdir was prepended to $pic_object above.
-	    non_pic_object=$pic_object
+	    non_pic_object="$pic_object"
 	    func_append non_pic_objects " $non_pic_object"
 	  fi
 	else
@@ -7387,7 +5943,7 @@ func_mode_link ()
 	  if $opt_dry_run; then
 	    # Extract subdirectory from the argument.
 	    func_dirname "$arg" "/" ""
-	    xdir=$func_dirname_result
+	    xdir="$func_dirname_result"
 
 	    func_lo2o "$arg"
 	    pic_object=$xdir$objdir/$func_lo2o_result
@@ -7395,7 +5951,7 @@ func_mode_link ()
 	    func_append libobjs " $pic_object"
 	    func_append non_pic_objects " $non_pic_object"
 	  else
-	    func_fatal_error "'$arg' is not a valid libtool object"
+	    func_fatal_error "\`$arg' is not a valid libtool object"
 	  fi
 	fi
 	;;
@@ -7411,11 +5967,11 @@ func_mode_link ()
 	# A libtool-controlled library.
 
 	func_resolve_sysroot "$arg"
-	if test dlfiles = "$prev"; then
+	if test "$prev" = dlfiles; then
 	  # This library was specified with -dlopen.
 	  func_append dlfiles " $func_resolve_sysroot_result"
 	  prev=
-	elif test dlprefiles = "$prev"; then
+	elif test "$prev" = dlprefiles; then
 	  # The library was specified with -dlpreopen.
 	  func_append dlprefiles " $func_resolve_sysroot_result"
 	  prev=
@@ -7430,7 +5986,7 @@ func_mode_link ()
 	# Unknown arguments in both finalize_command and compile_command need
 	# to be aesthetically quoted because they are evaled later.
 	func_quote_for_eval "$arg"
-	arg=$func_quote_for_eval_result
+	arg="$func_quote_for_eval_result"
 	;;
       esac # arg
 
@@ -7442,9 +5998,9 @@ func_mode_link ()
     done # argument parsing loop
 
     test -n "$prev" && \
-      func_fatal_help "the '$prevarg' option requires an argument"
+      func_fatal_help "the \`$prevarg' option requires an argument"
 
-    if test yes = "$export_dynamic" && test -n "$export_dynamic_flag_spec"; then
+    if test "$export_dynamic" = yes && test -n "$export_dynamic_flag_spec"; then
       eval arg=\"$export_dynamic_flag_spec\"
       func_append compile_command " $arg"
       func_append finalize_command " $arg"
@@ -7453,23 +6009,20 @@ func_mode_link ()
     oldlibs=
     # calculate the name of the file, without its directory
     func_basename "$output"
-    outputname=$func_basename_result
-    libobjs_save=$libobjs
+    outputname="$func_basename_result"
+    libobjs_save="$libobjs"
 
     if test -n "$shlibpath_var"; then
       # get the directories listed in $shlibpath_var
-      eval shlib_search_path=\`\$ECHO \"\$$shlibpath_var\" \| \$SED \'s/:/ /g\'\`
+      eval shlib_search_path=\`\$ECHO \"\${$shlibpath_var}\" \| \$SED \'s/:/ /g\'\`
     else
       shlib_search_path=
     fi
     eval sys_lib_search_path=\"$sys_lib_search_path_spec\"
     eval sys_lib_dlsearch_path=\"$sys_lib_dlsearch_path_spec\"
 
-    # Definition is injected by LT_CONFIG during libtool generation.
-    func_munge_path_list sys_lib_dlsearch_path "$LT_SYS_LIBRARY_PATH"
-
     func_dirname "$output" "/" ""
-    output_objdir=$func_dirname_result$objdir
+    output_objdir="$func_dirname_result$objdir"
     func_to_tool_file "$output_objdir/"
     tool_output_objdir=$func_to_tool_file_result
     # Create the object directory.
@@ -7492,7 +6045,7 @@ func_mode_link ()
     # Find all interdependent deplibs by searching for libraries
     # that are linked more than once (e.g. -la -lb -la)
     for deplib in $deplibs; do
-      if $opt_preserve_dup_deps; then
+      if $opt_preserve_dup_deps ; then
 	case "$libs " in
 	*" $deplib "*) func_append specialdeplibs " $deplib" ;;
 	esac
@@ -7500,7 +6053,7 @@ func_mode_link ()
       func_append libs " $deplib"
     done
 
-    if test lib = "$linkmode"; then
+    if test "$linkmode" = lib; then
       libs="$predeps $libs $compiler_lib_search_path $postdeps"
 
       # Compute libraries that are listed more than once in $predeps
@@ -7532,7 +6085,7 @@ func_mode_link ()
 	  case $file in
 	  *.la) ;;
 	  *)
-	    func_fatal_help "libraries can '-dlopen' only libtool libraries: $file"
+	    func_fatal_help "libraries can \`-dlopen' only libtool libraries: $file"
 	    ;;
 	  esac
 	done
@@ -7540,7 +6093,7 @@ func_mode_link ()
     prog)
 	compile_deplibs=
 	finalize_deplibs=
-	alldeplibs=false
+	alldeplibs=no
 	newdlfiles=
 	newdlprefiles=
 	passes="conv scan dlopen dlpreopen link"
@@ -7552,32 +6105,32 @@ func_mode_link ()
     for pass in $passes; do
       # The preopen pass in lib mode reverses $deplibs; put it back here
       # so that -L comes before libs that need it for instance...
-      if test lib,link = "$linkmode,$pass"; then
+      if test "$linkmode,$pass" = "lib,link"; then
 	## FIXME: Find the place where the list is rebuilt in the wrong
 	##        order, and fix it there properly
         tmp_deplibs=
 	for deplib in $deplibs; do
 	  tmp_deplibs="$deplib $tmp_deplibs"
 	done
-	deplibs=$tmp_deplibs
+	deplibs="$tmp_deplibs"
       fi
 
-      if test lib,link = "$linkmode,$pass" ||
-	 test prog,scan = "$linkmode,$pass"; then
-	libs=$deplibs
+      if test "$linkmode,$pass" = "lib,link" ||
+	 test "$linkmode,$pass" = "prog,scan"; then
+	libs="$deplibs"
 	deplibs=
       fi
-      if test prog = "$linkmode"; then
+      if test "$linkmode" = prog; then
 	case $pass in
-	dlopen) libs=$dlfiles ;;
-	dlpreopen) libs=$dlprefiles ;;
+	dlopen) libs="$dlfiles" ;;
+	dlpreopen) libs="$dlprefiles" ;;
 	link)
 	  libs="$deplibs %DEPLIBS%"
 	  test "X$link_all_deplibs" != Xno && libs="$libs $dependency_libs"
 	  ;;
 	esac
       fi
-      if test lib,dlpreopen = "$linkmode,$pass"; then
+      if test "$linkmode,$pass" = "lib,dlpreopen"; then
 	# Collect and forward deplibs of preopened libtool libs
 	for lib in $dlprefiles; do
 	  # Ignore non-libtool-libs
@@ -7598,26 +6151,26 @@ func_mode_link ()
 	    esac
 	  done
 	done
-	libs=$dlprefiles
+	libs="$dlprefiles"
       fi
-      if test dlopen = "$pass"; then
+      if test "$pass" = dlopen; then
 	# Collect dlpreopened libraries
-	save_deplibs=$deplibs
+	save_deplibs="$deplibs"
 	deplibs=
       fi
 
       for deplib in $libs; do
 	lib=
-	found=false
+	found=no
 	case $deplib in
 	-mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe \
         |-threads|-fopenmp|-openmp|-mp|-xopenmp|-omp|-qsmp=*)
-	  if test prog,link = "$linkmode,$pass"; then
+	  if test "$linkmode,$pass" = "prog,link"; then
 	    compile_deplibs="$deplib $compile_deplibs"
 	    finalize_deplibs="$deplib $finalize_deplibs"
 	  else
 	    func_append compiler_flags " $deplib"
-	    if test lib = "$linkmode"; then
+	    if test "$linkmode" = lib ; then
 		case "$new_inherited_linker_flags " in
 		    *" $deplib "*) ;;
 		    * ) func_append new_inherited_linker_flags " $deplib" ;;
@@ -7627,13 +6180,13 @@ func_mode_link ()
 	  continue
 	  ;;
 	-l*)
-	  if test lib != "$linkmode" && test prog != "$linkmode"; then
-	    func_warning "'-l' is ignored for archives/objects"
+	  if test "$linkmode" != lib && test "$linkmode" != prog; then
+	    func_warning "\`-l' is ignored for archives/objects"
 	    continue
 	  fi
 	  func_stripname '-l' '' "$deplib"
 	  name=$func_stripname_result
-	  if test lib = "$linkmode"; then
+	  if test "$linkmode" = lib; then
 	    searchdirs="$newlib_search_path $lib_search_path $compiler_lib_search_dirs $sys_lib_search_path $shlib_search_path"
 	  else
 	    searchdirs="$newlib_search_path $lib_search_path $sys_lib_search_path $shlib_search_path"
@@ -7641,22 +6194,31 @@ func_mode_link ()
 	  for searchdir in $searchdirs; do
 	    for search_ext in .la $std_shrext .so .a; do
 	      # Search the libtool library
-	      lib=$searchdir/lib$name$search_ext
+	      lib="$searchdir/lib${name}${search_ext}"
 	      if test -f "$lib"; then
-		if test .la = "$search_ext"; then
-		  found=:
+		if test "$search_ext" = ".la"; then
+		  found=yes
 		else
-		  found=false
+		  found=no
 		fi
 		break 2
 	      fi
 	    done
 	  done
-	  if $found; then
-	    # deplib is a libtool library
+	  if test "$found" != yes; then
+	    # deplib doesn't seem to be a libtool library
+	    if test "$linkmode,$pass" = "prog,link"; then
+	      compile_deplibs="$deplib $compile_deplibs"
+	      finalize_deplibs="$deplib $finalize_deplibs"
+	    else
+	      deplibs="$deplib $deplibs"
+	      test "$linkmode" = lib && newdependency_libs="$deplib $newdependency_libs"
+	    fi
+	    continue
+	  else # deplib is a libtool library
 	    # If $allow_libtool_libs_with_static_runtimes && $deplib is a stdlib,
 	    # We need to do some special things here, and not later.
-	    if test yes = "$allow_libtool_libs_with_static_runtimes"; then
+	    if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
 	      case " $predeps $postdeps " in
 	      *" $deplib "*)
 		if func_lalib_p "$lib"; then
@@ -7664,19 +6226,19 @@ func_mode_link ()
 		  old_library=
 		  func_source "$lib"
 		  for l in $old_library $library_names; do
-		    ll=$l
+		    ll="$l"
 		  done
-		  if test "X$ll" = "X$old_library"; then # only static version available
-		    found=false
+		  if test "X$ll" = "X$old_library" ; then # only static version available
+		    found=no
 		    func_dirname "$lib" "" "."
-		    ladir=$func_dirname_result
+		    ladir="$func_dirname_result"
 		    lib=$ladir/$old_library
-		    if test prog,link = "$linkmode,$pass"; then
+		    if test "$linkmode,$pass" = "prog,link"; then
 		      compile_deplibs="$deplib $compile_deplibs"
 		      finalize_deplibs="$deplib $finalize_deplibs"
 		    else
 		      deplibs="$deplib $deplibs"
-		      test lib = "$linkmode" && newdependency_libs="$deplib $newdependency_libs"
+		      test "$linkmode" = lib && newdependency_libs="$deplib $newdependency_libs"
 		    fi
 		    continue
 		  fi
@@ -7685,25 +6247,15 @@ func_mode_link ()
 	      *) ;;
 	      esac
 	    fi
-	  else
-	    # deplib doesn't seem to be a libtool library
-	    if test prog,link = "$linkmode,$pass"; then
-	      compile_deplibs="$deplib $compile_deplibs"
-	      finalize_deplibs="$deplib $finalize_deplibs"
-	    else
-	      deplibs="$deplib $deplibs"
-	      test lib = "$linkmode" && newdependency_libs="$deplib $newdependency_libs"
-	    fi
-	    continue
 	  fi
 	  ;; # -l
 	*.ltframework)
-	  if test prog,link = "$linkmode,$pass"; then
+	  if test "$linkmode,$pass" = "prog,link"; then
 	    compile_deplibs="$deplib $compile_deplibs"
 	    finalize_deplibs="$deplib $finalize_deplibs"
 	  else
 	    deplibs="$deplib $deplibs"
-	    if test lib = "$linkmode"; then
+	    if test "$linkmode" = lib ; then
 		case "$new_inherited_linker_flags " in
 		    *" $deplib "*) ;;
 		    * ) func_append new_inherited_linker_flags " $deplib" ;;
@@ -7716,18 +6268,18 @@ func_mode_link ()
 	  case $linkmode in
 	  lib)
 	    deplibs="$deplib $deplibs"
-	    test conv = "$pass" && continue
+	    test "$pass" = conv && continue
 	    newdependency_libs="$deplib $newdependency_libs"
 	    func_stripname '-L' '' "$deplib"
 	    func_resolve_sysroot "$func_stripname_result"
 	    func_append newlib_search_path " $func_resolve_sysroot_result"
 	    ;;
 	  prog)
-	    if test conv = "$pass"; then
+	    if test "$pass" = conv; then
 	      deplibs="$deplib $deplibs"
 	      continue
 	    fi
-	    if test scan = "$pass"; then
+	    if test "$pass" = scan; then
 	      deplibs="$deplib $deplibs"
 	    else
 	      compile_deplibs="$deplib $compile_deplibs"
@@ -7738,13 +6290,13 @@ func_mode_link ()
 	    func_append newlib_search_path " $func_resolve_sysroot_result"
 	    ;;
 	  *)
-	    func_warning "'-L' is ignored for archives/objects"
+	    func_warning "\`-L' is ignored for archives/objects"
 	    ;;
 	  esac # linkmode
 	  continue
 	  ;; # -L
 	-R*)
-	  if test link = "$pass"; then
+	  if test "$pass" = link; then
 	    func_stripname '-R' '' "$deplib"
 	    func_resolve_sysroot "$func_stripname_result"
 	    dir=$func_resolve_sysroot_result
@@ -7762,7 +6314,7 @@ func_mode_link ()
 	  lib=$func_resolve_sysroot_result
 	  ;;
 	*.$libext)
-	  if test conv = "$pass"; then
+	  if test "$pass" = conv; then
 	    deplibs="$deplib $deplibs"
 	    continue
 	  fi
@@ -7773,26 +6325,21 @@ func_mode_link ()
 	    case " $dlpreconveniencelibs " in
 	    *" $deplib "*) ;;
 	    *)
-	      valid_a_lib=false
+	      valid_a_lib=no
 	      case $deplibs_check_method in
 		match_pattern*)
 		  set dummy $deplibs_check_method; shift
 		  match_pattern_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"`
 		  if eval "\$ECHO \"$deplib\"" 2>/dev/null | $SED 10q \
 		    | $EGREP "$match_pattern_regex" > /dev/null; then
-		    valid_a_lib=:
+		    valid_a_lib=yes
 		  fi
 		;;
 		pass_all)
-		  valid_a_lib=:
+		  valid_a_lib=yes
 		;;
 	      esac
-	      if $valid_a_lib; then
-		echo
-		$ECHO "*** Warning: Linking the shared library $output against the"
-		$ECHO "*** static library $deplib is not portable!"
-		deplibs="$deplib $deplibs"
-	      else
+	      if test "$valid_a_lib" != yes; then
 		echo
 		$ECHO "*** Warning: Trying to link with static lib archive $deplib."
 		echo "*** I have the capability to make that library automatically link in when"
@@ -7800,13 +6347,18 @@ func_mode_link ()
 		echo "*** shared version of the library, which you do not appear to have"
 		echo "*** because the file extensions .$libext of this argument makes me believe"
 		echo "*** that it is just a static archive that I should not use here."
+	      else
+		echo
+		$ECHO "*** Warning: Linking the shared library $output against the"
+		$ECHO "*** static library $deplib is not portable!"
+		deplibs="$deplib $deplibs"
 	      fi
 	      ;;
 	    esac
 	    continue
 	    ;;
 	  prog)
-	    if test link != "$pass"; then
+	    if test "$pass" != link; then
 	      deplibs="$deplib $deplibs"
 	    else
 	      compile_deplibs="$deplib $compile_deplibs"
@@ -7817,10 +6369,10 @@ func_mode_link ()
 	  esac # linkmode
 	  ;; # *.$libext
 	*.lo | *.$objext)
-	  if test conv = "$pass"; then
+	  if test "$pass" = conv; then
 	    deplibs="$deplib $deplibs"
-	  elif test prog = "$linkmode"; then
-	    if test dlpreopen = "$pass" || test yes != "$dlopen_support" || test no = "$build_libtool_libs"; then
+	  elif test "$linkmode" = prog; then
+	    if test "$pass" = dlpreopen || test "$dlopen_support" != yes || test "$build_libtool_libs" = no; then
 	      # If there is no dlopen support or we're linking statically,
 	      # we need to preload.
 	      func_append newdlprefiles " $deplib"
@@ -7833,20 +6385,22 @@ func_mode_link ()
 	  continue
 	  ;;
 	%DEPLIBS%)
-	  alldeplibs=:
+	  alldeplibs=yes
 	  continue
 	  ;;
 	esac # case $deplib
 
-	$found || test -f "$lib" \
-	  || func_fatal_error "cannot find the library '$lib' or unhandled argument '$deplib'"
+	if test "$found" = yes || test -f "$lib"; then :
+	else
+	  func_fatal_error "cannot find the library \`$lib' or unhandled argument \`$deplib'"
+	fi
 
 	# Check to see that this really is a libtool archive.
 	func_lalib_unsafe_p "$lib" \
-	  || func_fatal_error "'$lib' is not a valid libtool archive"
+	  || func_fatal_error "\`$lib' is not a valid libtool archive"
 
 	func_dirname "$lib" "" "."
-	ladir=$func_dirname_result
+	ladir="$func_dirname_result"
 
 	dlname=
 	dlopen=
@@ -7876,19 +6430,19 @@ func_mode_link ()
 	  done
 	fi
 	dependency_libs=`$ECHO " $dependency_libs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'`
-	if test lib,link = "$linkmode,$pass" ||
-	   test prog,scan = "$linkmode,$pass" ||
-	   { test prog != "$linkmode" && test lib != "$linkmode"; }; then
+	if test "$linkmode,$pass" = "lib,link" ||
+	   test "$linkmode,$pass" = "prog,scan" ||
+	   { test "$linkmode" != prog && test "$linkmode" != lib; }; then
 	  test -n "$dlopen" && func_append dlfiles " $dlopen"
 	  test -n "$dlpreopen" && func_append dlprefiles " $dlpreopen"
 	fi
 
-	if test conv = "$pass"; then
+	if test "$pass" = conv; then
 	  # Only check for convenience libraries
 	  deplibs="$lib $deplibs"
 	  if test -z "$libdir"; then
 	    if test -z "$old_library"; then
-	      func_fatal_error "cannot find name of link library for '$lib'"
+	      func_fatal_error "cannot find name of link library for \`$lib'"
 	    fi
 	    # It is a libtool convenience library, so add in its objects.
 	    func_append convenience " $ladir/$objdir/$old_library"
@@ -7896,15 +6450,15 @@ func_mode_link ()
 	    tmp_libs=
 	    for deplib in $dependency_libs; do
 	      deplibs="$deplib $deplibs"
-	      if $opt_preserve_dup_deps; then
+	      if $opt_preserve_dup_deps ; then
 		case "$tmp_libs " in
 		*" $deplib "*) func_append specialdeplibs " $deplib" ;;
 		esac
 	      fi
 	      func_append tmp_libs " $deplib"
 	    done
-	  elif test prog != "$linkmode" && test lib != "$linkmode"; then
-	    func_fatal_error "'$lib' is not a convenience library"
+	  elif test "$linkmode" != prog && test "$linkmode" != lib; then
+	    func_fatal_error "\`$lib' is not a convenience library"
 	  fi
 	  continue
 	fi # $pass = conv
@@ -7913,26 +6467,26 @@ func_mode_link ()
 	# Get the name of the library we link against.
 	linklib=
 	if test -n "$old_library" &&
-	   { test yes = "$prefer_static_libs" ||
-	     test built,no = "$prefer_static_libs,$installed"; }; then
+	   { test "$prefer_static_libs" = yes ||
+	     test "$prefer_static_libs,$installed" = "built,no"; }; then
 	  linklib=$old_library
 	else
 	  for l in $old_library $library_names; do
-	    linklib=$l
+	    linklib="$l"
 	  done
 	fi
 	if test -z "$linklib"; then
-	  func_fatal_error "cannot find name of link library for '$lib'"
+	  func_fatal_error "cannot find name of link library for \`$lib'"
 	fi
 
 	# This library was specified with -dlopen.
-	if test dlopen = "$pass"; then
-	  test -z "$libdir" \
-	    && func_fatal_error "cannot -dlopen a convenience library: '$lib'"
+	if test "$pass" = dlopen; then
+	  if test -z "$libdir"; then
+	    func_fatal_error "cannot -dlopen a convenience library: \`$lib'"
+	  fi
 	  if test -z "$dlname" ||
-	     test yes != "$dlopen_support" ||
-	     test no = "$build_libtool_libs"
-	  then
+	     test "$dlopen_support" != yes ||
+	     test "$build_libtool_libs" = no; then
 	    # If there is no dlname, no dlopen support or we're linking
 	    # statically, we need to preload.  We also need to preload any
 	    # dependent libraries so libltdl's deplib preloader doesn't
@@ -7946,40 +6500,40 @@ func_mode_link ()
 
 	# We need an absolute path.
 	case $ladir in
-	[\\/]* | [A-Za-z]:[\\/]*) abs_ladir=$ladir ;;
+	[\\/]* | [A-Za-z]:[\\/]*) abs_ladir="$ladir" ;;
 	*)
 	  abs_ladir=`cd "$ladir" && pwd`
 	  if test -z "$abs_ladir"; then
-	    func_warning "cannot determine absolute directory name of '$ladir'"
+	    func_warning "cannot determine absolute directory name of \`$ladir'"
 	    func_warning "passing it literally to the linker, although it might fail"
-	    abs_ladir=$ladir
+	    abs_ladir="$ladir"
 	  fi
 	  ;;
 	esac
 	func_basename "$lib"
-	laname=$func_basename_result
+	laname="$func_basename_result"
 
 	# Find the relevant object directory and library name.
-	if test yes = "$installed"; then
+	if test "X$installed" = Xyes; then
 	  if test ! -f "$lt_sysroot$libdir/$linklib" && test -f "$abs_ladir/$linklib"; then
-	    func_warning "library '$lib' was moved."
-	    dir=$ladir
-	    absdir=$abs_ladir
-	    libdir=$abs_ladir
+	    func_warning "library \`$lib' was moved."
+	    dir="$ladir"
+	    absdir="$abs_ladir"
+	    libdir="$abs_ladir"
 	  else
-	    dir=$lt_sysroot$libdir
-	    absdir=$lt_sysroot$libdir
+	    dir="$lt_sysroot$libdir"
+	    absdir="$lt_sysroot$libdir"
 	  fi
-	  test yes = "$hardcode_automatic" && avoidtemprpath=yes
+	  test "X$hardcode_automatic" = Xyes && avoidtemprpath=yes
 	else
 	  if test ! -f "$ladir/$objdir/$linklib" && test -f "$abs_ladir/$linklib"; then
-	    dir=$ladir
-	    absdir=$abs_ladir
+	    dir="$ladir"
+	    absdir="$abs_ladir"
 	    # Remove this search path later
 	    func_append notinst_path " $abs_ladir"
 	  else
-	    dir=$ladir/$objdir
-	    absdir=$abs_ladir/$objdir
+	    dir="$ladir/$objdir"
+	    absdir="$abs_ladir/$objdir"
 	    # Remove this search path later
 	    func_append notinst_path " $abs_ladir"
 	  fi
@@ -7988,11 +6542,11 @@ func_mode_link ()
 	name=$func_stripname_result
 
 	# This library was specified with -dlpreopen.
-	if test dlpreopen = "$pass"; then
-	  if test -z "$libdir" && test prog = "$linkmode"; then
-	    func_fatal_error "only libraries may -dlpreopen a convenience library: '$lib'"
+	if test "$pass" = dlpreopen; then
+	  if test -z "$libdir" && test "$linkmode" = prog; then
+	    func_fatal_error "only libraries may -dlpreopen a convenience library: \`$lib'"
 	  fi
-	  case $host in
+	  case "$host" in
 	    # special handling for platforms with PE-DLLs.
 	    *cygwin* | *mingw* | *cegcc* )
 	      # Linker will automatically link against shared library if both
@@ -8036,9 +6590,9 @@ func_mode_link ()
 
 	if test -z "$libdir"; then
 	  # Link the convenience library
-	  if test lib = "$linkmode"; then
+	  if test "$linkmode" = lib; then
 	    deplibs="$dir/$old_library $deplibs"
-	  elif test prog,link = "$linkmode,$pass"; then
+	  elif test "$linkmode,$pass" = "prog,link"; then
 	    compile_deplibs="$dir/$old_library $compile_deplibs"
 	    finalize_deplibs="$dir/$old_library $finalize_deplibs"
 	  else
@@ -8048,14 +6602,14 @@ func_mode_link ()
 	fi
 
 
-	if test prog = "$linkmode" && test link != "$pass"; then
+	if test "$linkmode" = prog && test "$pass" != link; then
 	  func_append newlib_search_path " $ladir"
 	  deplibs="$lib $deplibs"
 
-	  linkalldeplibs=false
-	  if test no != "$link_all_deplibs" || test -z "$library_names" ||
-	     test no = "$build_libtool_libs"; then
-	    linkalldeplibs=:
+	  linkalldeplibs=no
+	  if test "$link_all_deplibs" != no || test -z "$library_names" ||
+	     test "$build_libtool_libs" = no; then
+	    linkalldeplibs=yes
 	  fi
 
 	  tmp_libs=
@@ -8067,14 +6621,14 @@ func_mode_link ()
 		 ;;
 	    esac
 	    # Need to link against all dependency_libs?
-	    if $linkalldeplibs; then
+	    if test "$linkalldeplibs" = yes; then
 	      deplibs="$deplib $deplibs"
 	    else
 	      # Need to hardcode shared library paths
 	      # or/and link against static libraries
 	      newdependency_libs="$deplib $newdependency_libs"
 	    fi
-	    if $opt_preserve_dup_deps; then
+	    if $opt_preserve_dup_deps ; then
 	      case "$tmp_libs " in
 	      *" $deplib "*) func_append specialdeplibs " $deplib" ;;
 	      esac
@@ -8084,15 +6638,15 @@ func_mode_link ()
 	  continue
 	fi # $linkmode = prog...
 
-	if test prog,link = "$linkmode,$pass"; then
+	if test "$linkmode,$pass" = "prog,link"; then
 	  if test -n "$library_names" &&
-	     { { test no = "$prefer_static_libs" ||
-	         test built,yes = "$prefer_static_libs,$installed"; } ||
+	     { { test "$prefer_static_libs" = no ||
+	         test "$prefer_static_libs,$installed" = "built,yes"; } ||
 	       test -z "$old_library"; }; then
 	    # We need to hardcode the library path
-	    if test -n "$shlibpath_var" && test -z "$avoidtemprpath"; then
+	    if test -n "$shlibpath_var" && test -z "$avoidtemprpath" ; then
 	      # Make sure the rpath contains only unique directories.
-	      case $temp_rpath: in
+	      case "$temp_rpath:" in
 	      *"$absdir:"*) ;;
 	      *) func_append temp_rpath "$absdir:" ;;
 	      esac
@@ -8121,9 +6675,9 @@ func_mode_link ()
 	    esac
 	  fi # $linkmode,$pass = prog,link...
 
-	  if $alldeplibs &&
-	     { test pass_all = "$deplibs_check_method" ||
-	       { test yes = "$build_libtool_libs" &&
+	  if test "$alldeplibs" = yes &&
+	     { test "$deplibs_check_method" = pass_all ||
+	       { test "$build_libtool_libs" = yes &&
 		 test -n "$library_names"; }; }; then
 	    # We only need to search for static libraries
 	    continue
@@ -8132,19 +6686,19 @@ func_mode_link ()
 
 	link_static=no # Whether the deplib will be linked statically
 	use_static_libs=$prefer_static_libs
-	if test built = "$use_static_libs" && test yes = "$installed"; then
+	if test "$use_static_libs" = built && test "$installed" = yes; then
 	  use_static_libs=no
 	fi
 	if test -n "$library_names" &&
-	   { test no = "$use_static_libs" || test -z "$old_library"; }; then
+	   { test "$use_static_libs" = no || test -z "$old_library"; }; then
 	  case $host in
-	  *cygwin* | *mingw* | *cegcc* | *os2*)
+	  *cygwin* | *mingw* | *cegcc*)
 	      # No point in relinking DLLs because paths are not encoded
 	      func_append notinst_deplibs " $lib"
 	      need_relink=no
 	    ;;
 	  *)
-	    if test no = "$installed"; then
+	    if test "$installed" = no; then
 	      func_append notinst_deplibs " $lib"
 	      need_relink=yes
 	    fi
@@ -8154,24 +6708,24 @@ func_mode_link ()
 
 	  # Warn about portability, can't link against -module's on some
 	  # systems (darwin).  Don't bleat about dlopened modules though!
-	  dlopenmodule=
+	  dlopenmodule=""
 	  for dlpremoduletest in $dlprefiles; do
 	    if test "X$dlpremoduletest" = "X$lib"; then
-	      dlopenmodule=$dlpremoduletest
+	      dlopenmodule="$dlpremoduletest"
 	      break
 	    fi
 	  done
-	  if test -z "$dlopenmodule" && test yes = "$shouldnotlink" && test link = "$pass"; then
+	  if test -z "$dlopenmodule" && test "$shouldnotlink" = yes && test "$pass" = link; then
 	    echo
-	    if test prog = "$linkmode"; then
+	    if test "$linkmode" = prog; then
 	      $ECHO "*** Warning: Linking the executable $output against the loadable module"
 	    else
 	      $ECHO "*** Warning: Linking the shared library $output against the loadable module"
 	    fi
 	    $ECHO "*** $linklib is not portable!"
 	  fi
-	  if test lib = "$linkmode" &&
-	     test yes = "$hardcode_into_libs"; then
+	  if test "$linkmode" = lib &&
+	     test "$hardcode_into_libs" = yes; then
 	    # Hardcode the library path.
 	    # Skip directories that are in the system default run-time
 	    # search path.
@@ -8199,43 +6753,43 @@ func_mode_link ()
 	    # figure out the soname
 	    set dummy $library_names
 	    shift
-	    realname=$1
+	    realname="$1"
 	    shift
 	    libname=`eval "\\$ECHO \"$libname_spec\""`
 	    # use dlname if we got it. it's perfectly good, no?
 	    if test -n "$dlname"; then
-	      soname=$dlname
+	      soname="$dlname"
 	    elif test -n "$soname_spec"; then
 	      # bleh windows
 	      case $host in
-	      *cygwin* | mingw* | *cegcc* | *os2*)
+	      *cygwin* | mingw* | *cegcc*)
 	        func_arith $current - $age
 		major=$func_arith_result
-		versuffix=-$major
+		versuffix="-$major"
 		;;
 	      esac
 	      eval soname=\"$soname_spec\"
 	    else
-	      soname=$realname
+	      soname="$realname"
 	    fi
 
 	    # Make a new name for the extract_expsyms_cmds to use
-	    soroot=$soname
+	    soroot="$soname"
 	    func_basename "$soroot"
-	    soname=$func_basename_result
+	    soname="$func_basename_result"
 	    func_stripname 'lib' '.dll' "$soname"
 	    newlib=libimp-$func_stripname_result.a
 
 	    # If the library has no export list, then create one now
 	    if test -f "$output_objdir/$soname-def"; then :
 	    else
-	      func_verbose "extracting exported symbol list from '$soname'"
+	      func_verbose "extracting exported symbol list from \`$soname'"
 	      func_execute_cmds "$extract_expsyms_cmds" 'exit $?'
 	    fi
 
 	    # Create $newlib
 	    if test -f "$output_objdir/$newlib"; then :; else
-	      func_verbose "generating import library for '$soname'"
+	      func_verbose "generating import library for \`$soname'"
 	      func_execute_cmds "$old_archive_from_expsyms_cmds" 'exit $?'
 	    fi
 	    # make sure the library variables are pointing to the new library
@@ -8243,58 +6797,58 @@ func_mode_link ()
 	    linklib=$newlib
 	  fi # test -n "$old_archive_from_expsyms_cmds"
 
-	  if test prog = "$linkmode" || test relink != "$opt_mode"; then
+	  if test "$linkmode" = prog || test "$opt_mode" != relink; then
 	    add_shlibpath=
 	    add_dir=
 	    add=
 	    lib_linked=yes
 	    case $hardcode_action in
 	    immediate | unsupported)
-	      if test no = "$hardcode_direct"; then
-		add=$dir/$linklib
+	      if test "$hardcode_direct" = no; then
+		add="$dir/$linklib"
 		case $host in
-		  *-*-sco3.2v5.0.[024]*) add_dir=-L$dir ;;
-		  *-*-sysv4*uw2*) add_dir=-L$dir ;;
+		  *-*-sco3.2v5.0.[024]*) add_dir="-L$dir" ;;
+		  *-*-sysv4*uw2*) add_dir="-L$dir" ;;
 		  *-*-sysv5OpenUNIX* | *-*-sysv5UnixWare7.[01].[10]* | \
-		    *-*-unixware7*) add_dir=-L$dir ;;
+		    *-*-unixware7*) add_dir="-L$dir" ;;
 		  *-*-darwin* )
-		    # if the lib is a (non-dlopened) module then we cannot
+		    # if the lib is a (non-dlopened) module then we can not
 		    # link against it, someone is ignoring the earlier warnings
 		    if /usr/bin/file -L $add 2> /dev/null |
-			 $GREP ": [^:]* bundle" >/dev/null; then
+			 $GREP ": [^:]* bundle" >/dev/null ; then
 		      if test "X$dlopenmodule" != "X$lib"; then
 			$ECHO "*** Warning: lib $linklib is a module, not a shared library"
-			if test -z "$old_library"; then
+			if test -z "$old_library" ; then
 			  echo
 			  echo "*** And there doesn't seem to be a static archive available"
 			  echo "*** The link will probably fail, sorry"
 			else
-			  add=$dir/$old_library
+			  add="$dir/$old_library"
 			fi
 		      elif test -n "$old_library"; then
-			add=$dir/$old_library
+			add="$dir/$old_library"
 		      fi
 		    fi
 		esac
-	      elif test no = "$hardcode_minus_L"; then
+	      elif test "$hardcode_minus_L" = no; then
 		case $host in
-		*-*-sunos*) add_shlibpath=$dir ;;
+		*-*-sunos*) add_shlibpath="$dir" ;;
 		esac
-		add_dir=-L$dir
-		add=-l$name
-	      elif test no = "$hardcode_shlibpath_var"; then
-		add_shlibpath=$dir
-		add=-l$name
+		add_dir="-L$dir"
+		add="-l$name"
+	      elif test "$hardcode_shlibpath_var" = no; then
+		add_shlibpath="$dir"
+		add="-l$name"
 	      else
 		lib_linked=no
 	      fi
 	      ;;
 	    relink)
-	      if test yes = "$hardcode_direct" &&
-	         test no = "$hardcode_direct_absolute"; then
-		add=$dir/$linklib
-	      elif test yes = "$hardcode_minus_L"; then
-		add_dir=-L$absdir
+	      if test "$hardcode_direct" = yes &&
+	         test "$hardcode_direct_absolute" = no; then
+		add="$dir/$linklib"
+	      elif test "$hardcode_minus_L" = yes; then
+		add_dir="-L$absdir"
 		# Try looking first in the location we're being installed to.
 		if test -n "$inst_prefix_dir"; then
 		  case $libdir in
@@ -8303,10 +6857,10 @@ func_mode_link ()
 		      ;;
 		  esac
 		fi
-		add=-l$name
-	      elif test yes = "$hardcode_shlibpath_var"; then
-		add_shlibpath=$dir
-		add=-l$name
+		add="-l$name"
+	      elif test "$hardcode_shlibpath_var" = yes; then
+		add_shlibpath="$dir"
+		add="-l$name"
 	      else
 		lib_linked=no
 	      fi
@@ -8314,7 +6868,7 @@ func_mode_link ()
 	    *) lib_linked=no ;;
 	    esac
 
-	    if test yes != "$lib_linked"; then
+	    if test "$lib_linked" != yes; then
 	      func_fatal_configuration "unsupported hardcode properties"
 	    fi
 
@@ -8324,15 +6878,15 @@ func_mode_link ()
 	      *) func_append compile_shlibpath "$add_shlibpath:" ;;
 	      esac
 	    fi
-	    if test prog = "$linkmode"; then
+	    if test "$linkmode" = prog; then
 	      test -n "$add_dir" && compile_deplibs="$add_dir $compile_deplibs"
 	      test -n "$add" && compile_deplibs="$add $compile_deplibs"
 	    else
 	      test -n "$add_dir" && deplibs="$add_dir $deplibs"
 	      test -n "$add" && deplibs="$add $deplibs"
-	      if test yes != "$hardcode_direct" &&
-		 test yes != "$hardcode_minus_L" &&
-		 test yes = "$hardcode_shlibpath_var"; then
+	      if test "$hardcode_direct" != yes &&
+		 test "$hardcode_minus_L" != yes &&
+		 test "$hardcode_shlibpath_var" = yes; then
 		case :$finalize_shlibpath: in
 		*":$libdir:"*) ;;
 		*) func_append finalize_shlibpath "$libdir:" ;;
@@ -8341,33 +6895,33 @@ func_mode_link ()
 	    fi
 	  fi
 
-	  if test prog = "$linkmode" || test relink = "$opt_mode"; then
+	  if test "$linkmode" = prog || test "$opt_mode" = relink; then
 	    add_shlibpath=
 	    add_dir=
 	    add=
 	    # Finalize command for both is simple: just hardcode it.
-	    if test yes = "$hardcode_direct" &&
-	       test no = "$hardcode_direct_absolute"; then
-	      add=$libdir/$linklib
-	    elif test yes = "$hardcode_minus_L"; then
-	      add_dir=-L$libdir
-	      add=-l$name
-	    elif test yes = "$hardcode_shlibpath_var"; then
+	    if test "$hardcode_direct" = yes &&
+	       test "$hardcode_direct_absolute" = no; then
+	      add="$libdir/$linklib"
+	    elif test "$hardcode_minus_L" = yes; then
+	      add_dir="-L$libdir"
+	      add="-l$name"
+	    elif test "$hardcode_shlibpath_var" = yes; then
 	      case :$finalize_shlibpath: in
 	      *":$libdir:"*) ;;
 	      *) func_append finalize_shlibpath "$libdir:" ;;
 	      esac
-	      add=-l$name
-	    elif test yes = "$hardcode_automatic"; then
+	      add="-l$name"
+	    elif test "$hardcode_automatic" = yes; then
 	      if test -n "$inst_prefix_dir" &&
-		 test -f "$inst_prefix_dir$libdir/$linklib"; then
-		add=$inst_prefix_dir$libdir/$linklib
+		 test -f "$inst_prefix_dir$libdir/$linklib" ; then
+		add="$inst_prefix_dir$libdir/$linklib"
 	      else
-		add=$libdir/$linklib
+		add="$libdir/$linklib"
 	      fi
 	    else
 	      # We cannot seem to hardcode it, guess we'll fake it.
-	      add_dir=-L$libdir
+	      add_dir="-L$libdir"
 	      # Try looking first in the location we're being installed to.
 	      if test -n "$inst_prefix_dir"; then
 		case $libdir in
@@ -8376,10 +6930,10 @@ func_mode_link ()
 		    ;;
 		esac
 	      fi
-	      add=-l$name
+	      add="-l$name"
 	    fi
 
-	    if test prog = "$linkmode"; then
+	    if test "$linkmode" = prog; then
 	      test -n "$add_dir" && finalize_deplibs="$add_dir $finalize_deplibs"
 	      test -n "$add" && finalize_deplibs="$add $finalize_deplibs"
 	    else
@@ -8387,43 +6941,43 @@ func_mode_link ()
 	      test -n "$add" && deplibs="$add $deplibs"
 	    fi
 	  fi
-	elif test prog = "$linkmode"; then
+	elif test "$linkmode" = prog; then
 	  # Here we assume that one of hardcode_direct or hardcode_minus_L
 	  # is not unsupported.  This is valid on all known static and
 	  # shared platforms.
-	  if test unsupported != "$hardcode_direct"; then
-	    test -n "$old_library" && linklib=$old_library
+	  if test "$hardcode_direct" != unsupported; then
+	    test -n "$old_library" && linklib="$old_library"
 	    compile_deplibs="$dir/$linklib $compile_deplibs"
 	    finalize_deplibs="$dir/$linklib $finalize_deplibs"
 	  else
 	    compile_deplibs="-l$name -L$dir $compile_deplibs"
 	    finalize_deplibs="-l$name -L$dir $finalize_deplibs"
 	  fi
-	elif test yes = "$build_libtool_libs"; then
+	elif test "$build_libtool_libs" = yes; then
 	  # Not a shared library
-	  if test pass_all != "$deplibs_check_method"; then
+	  if test "$deplibs_check_method" != pass_all; then
 	    # We're trying link a shared library against a static one
 	    # but the system doesn't support it.
 
 	    # Just print a warning and add the library to dependency_libs so
 	    # that the program can be linked against the static library.
 	    echo
-	    $ECHO "*** Warning: This system cannot link to static lib archive $lib."
+	    $ECHO "*** Warning: This system can not link to static lib archive $lib."
 	    echo "*** I have the capability to make that library automatically link in when"
 	    echo "*** you link to this library.  But I can only do this if you have a"
 	    echo "*** shared version of the library, which you do not appear to have."
-	    if test yes = "$module"; then
+	    if test "$module" = yes; then
 	      echo "*** But as you try to build a module library, libtool will still create "
 	      echo "*** a static module, that should work as long as the dlopening application"
 	      echo "*** is linked with the -dlopen flag to resolve symbols at runtime."
 	      if test -z "$global_symbol_pipe"; then
 		echo
 		echo "*** However, this would only work if libtool was able to extract symbol"
-		echo "*** lists from a program, using 'nm' or equivalent, but libtool could"
+		echo "*** lists from a program, using \`nm' or equivalent, but libtool could"
 		echo "*** not find such a program.  So, this module is probably useless."
-		echo "*** 'nm' from GNU binutils and a full rebuild may help."
+		echo "*** \`nm' from GNU binutils and a full rebuild may help."
 	      fi
-	      if test no = "$build_old_libs"; then
+	      if test "$build_old_libs" = no; then
 		build_libtool_libs=module
 		build_old_libs=yes
 	      else
@@ -8436,11 +6990,11 @@ func_mode_link ()
 	  fi
 	fi # link shared/static library?
 
-	if test lib = "$linkmode"; then
+	if test "$linkmode" = lib; then
 	  if test -n "$dependency_libs" &&
-	     { test yes != "$hardcode_into_libs" ||
-	       test yes = "$build_old_libs" ||
-	       test yes = "$link_static"; }; then
+	     { test "$hardcode_into_libs" != yes ||
+	       test "$build_old_libs" = yes ||
+	       test "$link_static" = yes; }; then
 	    # Extract -R from dependency_libs
 	    temp_deplibs=
 	    for libdir in $dependency_libs; do
@@ -8454,12 +7008,12 @@ func_mode_link ()
 	      *) func_append temp_deplibs " $libdir";;
 	      esac
 	    done
-	    dependency_libs=$temp_deplibs
+	    dependency_libs="$temp_deplibs"
 	  fi
 
 	  func_append newlib_search_path " $absdir"
 	  # Link against this library
-	  test no = "$link_static" && newdependency_libs="$abs_ladir/$laname $newdependency_libs"
+	  test "$link_static" = no && newdependency_libs="$abs_ladir/$laname $newdependency_libs"
 	  # ... and its dependency_libs
 	  tmp_libs=
 	  for deplib in $dependency_libs; do
@@ -8469,7 +7023,7 @@ func_mode_link ()
                    func_resolve_sysroot "$func_stripname_result";;
               *) func_resolve_sysroot "$deplib" ;;
             esac
-	    if $opt_preserve_dup_deps; then
+	    if $opt_preserve_dup_deps ; then
 	      case "$tmp_libs " in
 	      *" $func_resolve_sysroot_result "*)
                 func_append specialdeplibs " $func_resolve_sysroot_result" ;;
@@ -8478,12 +7032,12 @@ func_mode_link ()
 	    func_append tmp_libs " $func_resolve_sysroot_result"
 	  done
 
-	  if test no != "$link_all_deplibs"; then
+	  if test "$link_all_deplibs" != no; then
 	    # Add the search paths of all dependency libraries
 	    for deplib in $dependency_libs; do
 	      path=
 	      case $deplib in
-	      -L*) path=$deplib ;;
+	      -L*) path="$deplib" ;;
 	      *.la)
 	        func_resolve_sysroot "$deplib"
 	        deplib=$func_resolve_sysroot_result
@@ -8491,12 +7045,12 @@ func_mode_link ()
 		dir=$func_dirname_result
 		# We need an absolute path.
 		case $dir in
-		[\\/]* | [A-Za-z]:[\\/]*) absdir=$dir ;;
+		[\\/]* | [A-Za-z]:[\\/]*) absdir="$dir" ;;
 		*)
 		  absdir=`cd "$dir" && pwd`
 		  if test -z "$absdir"; then
-		    func_warning "cannot determine absolute directory name of '$dir'"
-		    absdir=$dir
+		    func_warning "cannot determine absolute directory name of \`$dir'"
+		    absdir="$dir"
 		  fi
 		  ;;
 		esac
@@ -8504,35 +7058,35 @@ func_mode_link ()
 		case $host in
 		*-*-darwin*)
 		  depdepl=
-		  eval deplibrary_names=`$SED -n -e 's/^library_names=\(.*\)$/\1/p' $deplib`
-		  if test -n "$deplibrary_names"; then
-		    for tmp in $deplibrary_names; do
+		  eval deplibrary_names=`${SED} -n -e 's/^library_names=\(.*\)$/\1/p' $deplib`
+		  if test -n "$deplibrary_names" ; then
+		    for tmp in $deplibrary_names ; do
 		      depdepl=$tmp
 		    done
-		    if test -f "$absdir/$objdir/$depdepl"; then
-		      depdepl=$absdir/$objdir/$depdepl
-		      darwin_install_name=`$OTOOL -L $depdepl | awk '{if (NR == 2) {print $1;exit}}'`
+		    if test -f "$absdir/$objdir/$depdepl" ; then
+		      depdepl="$absdir/$objdir/$depdepl"
+		      darwin_install_name=`${OTOOL} -L $depdepl | awk '{if (NR == 2) {print $1;exit}}'`
                       if test -z "$darwin_install_name"; then
-                          darwin_install_name=`$OTOOL64 -L $depdepl  | awk '{if (NR == 2) {print $1;exit}}'`
+                          darwin_install_name=`${OTOOL64} -L $depdepl  | awk '{if (NR == 2) {print $1;exit}}'`
                       fi
-		      func_append compiler_flags " $wl-dylib_file $wl$darwin_install_name:$depdepl"
-		      func_append linker_flags " -dylib_file $darwin_install_name:$depdepl"
+		      func_append compiler_flags " ${wl}-dylib_file ${wl}${darwin_install_name}:${depdepl}"
+		      func_append linker_flags " -dylib_file ${darwin_install_name}:${depdepl}"
 		      path=
 		    fi
 		  fi
 		  ;;
 		*)
-		  path=-L$absdir/$objdir
+		  path="-L$absdir/$objdir"
 		  ;;
 		esac
 		else
-		  eval libdir=`$SED -n -e 's/^libdir=\(.*\)$/\1/p' $deplib`
+		  eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $deplib`
 		  test -z "$libdir" && \
-		    func_fatal_error "'$deplib' is not a valid libtool archive"
+		    func_fatal_error "\`$deplib' is not a valid libtool archive"
 		  test "$absdir" != "$libdir" && \
-		    func_warning "'$deplib' seems to be moved"
+		    func_warning "\`$deplib' seems to be moved"
 
-		  path=-L$absdir
+		  path="-L$absdir"
 		fi
 		;;
 	      esac
@@ -8544,23 +7098,23 @@ func_mode_link ()
 	  fi # link_all_deplibs != no
 	fi # linkmode = lib
       done # for deplib in $libs
-      if test link = "$pass"; then
-	if test prog = "$linkmode"; then
+      if test "$pass" = link; then
+	if test "$linkmode" = "prog"; then
 	  compile_deplibs="$new_inherited_linker_flags $compile_deplibs"
 	  finalize_deplibs="$new_inherited_linker_flags $finalize_deplibs"
 	else
 	  compiler_flags="$compiler_flags "`$ECHO " $new_inherited_linker_flags" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'`
 	fi
       fi
-      dependency_libs=$newdependency_libs
-      if test dlpreopen = "$pass"; then
+      dependency_libs="$newdependency_libs"
+      if test "$pass" = dlpreopen; then
 	# Link the dlpreopened libraries before other libraries
 	for deplib in $save_deplibs; do
 	  deplibs="$deplib $deplibs"
 	done
       fi
-      if test dlopen != "$pass"; then
-	test conv = "$pass" || {
+      if test "$pass" != dlopen; then
+	if test "$pass" != conv; then
 	  # Make sure lib_search_path contains only unique directories.
 	  lib_search_path=
 	  for dir in $newlib_search_path; do
@@ -8570,12 +7124,12 @@ func_mode_link ()
 	    esac
 	  done
 	  newlib_search_path=
-	}
+	fi
 
-	if test prog,link = "$linkmode,$pass"; then
-	  vars="compile_deplibs finalize_deplibs"
+	if test "$linkmode,$pass" != "prog,link"; then
+	  vars="deplibs"
 	else
-	  vars=deplibs
+	  vars="compile_deplibs finalize_deplibs"
 	fi
 	for var in $vars dependency_libs; do
 	  # Add libraries to $var in reverse order
@@ -8633,93 +7187,62 @@ func_mode_link ()
 	  eval $var=\"$tmp_libs\"
 	done # for var
       fi
-
-      # Add Sun CC postdeps if required:
-      test CXX = "$tagname" && {
-        case $host_os in
-        linux*)
-          case `$CC -V 2>&1 | sed 5q` in
-          *Sun\ C*) # Sun C++ 5.9
-            func_suncc_cstd_abi
-
-            if test no != "$suncc_use_cstd_abi"; then
-              func_append postdeps ' -library=Cstd -library=Crun'
-            fi
-            ;;
-          esac
-          ;;
-
-        solaris*)
-          func_cc_basename "$CC"
-          case $func_cc_basename_result in
-          CC* | sunCC*)
-            func_suncc_cstd_abi
-
-            if test no != "$suncc_use_cstd_abi"; then
-              func_append postdeps ' -library=Cstd -library=Crun'
-            fi
-            ;;
-          esac
-          ;;
-        esac
-      }
-
       # Last step: remove runtime libs from dependency_libs
       # (they stay in deplibs)
       tmp_libs=
-      for i in $dependency_libs; do
+      for i in $dependency_libs ; do
 	case " $predeps $postdeps $compiler_lib_search_path " in
 	*" $i "*)
-	  i=
+	  i=""
 	  ;;
 	esac
-	if test -n "$i"; then
+	if test -n "$i" ; then
 	  func_append tmp_libs " $i"
 	fi
       done
       dependency_libs=$tmp_libs
     done # for pass
-    if test prog = "$linkmode"; then
-      dlfiles=$newdlfiles
+    if test "$linkmode" = prog; then
+      dlfiles="$newdlfiles"
     fi
-    if test prog = "$linkmode" || test lib = "$linkmode"; then
-      dlprefiles=$newdlprefiles
+    if test "$linkmode" = prog || test "$linkmode" = lib; then
+      dlprefiles="$newdlprefiles"
     fi
 
     case $linkmode in
     oldlib)
-      if test -n "$dlfiles$dlprefiles" || test no != "$dlself"; then
-	func_warning "'-dlopen' is ignored for archives"
+      if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then
+	func_warning "\`-dlopen' is ignored for archives"
       fi
 
       case " $deplibs" in
       *\ -l* | *\ -L*)
-	func_warning "'-l' and '-L' are ignored for archives" ;;
+	func_warning "\`-l' and \`-L' are ignored for archives" ;;
       esac
 
       test -n "$rpath" && \
-	func_warning "'-rpath' is ignored for archives"
+	func_warning "\`-rpath' is ignored for archives"
 
       test -n "$xrpath" && \
-	func_warning "'-R' is ignored for archives"
+	func_warning "\`-R' is ignored for archives"
 
       test -n "$vinfo" && \
-	func_warning "'-version-info/-version-number' is ignored for archives"
+	func_warning "\`-version-info/-version-number' is ignored for archives"
 
       test -n "$release" && \
-	func_warning "'-release' is ignored for archives"
+	func_warning "\`-release' is ignored for archives"
 
       test -n "$export_symbols$export_symbols_regex" && \
-	func_warning "'-export-symbols' is ignored for archives"
+	func_warning "\`-export-symbols' is ignored for archives"
 
       # Now set the variables for building old libraries.
       build_libtool_libs=no
-      oldlibs=$output
+      oldlibs="$output"
       func_append objs "$old_deplibs"
       ;;
 
     lib)
-      # Make sure we only generate libraries of the form 'libNAME.la'.
+      # Make sure we only generate libraries of the form `libNAME.la'.
       case $outputname in
       lib*)
 	func_stripname 'lib' '.la' "$outputname"
@@ -8728,10 +7251,10 @@ func_mode_link ()
 	eval libname=\"$libname_spec\"
 	;;
       *)
-	test no = "$module" \
-	  && func_fatal_help "libtool library '$output' must begin with 'lib'"
+	test "$module" = no && \
+	  func_fatal_help "libtool library \`$output' must begin with \`lib'"
 
-	if test no != "$need_lib_prefix"; then
+	if test "$need_lib_prefix" != no; then
 	  # Add the "lib" prefix for modules if required
 	  func_stripname '' '.la' "$outputname"
 	  name=$func_stripname_result
@@ -8745,8 +7268,8 @@ func_mode_link ()
       esac
 
       if test -n "$objs"; then
-	if test pass_all != "$deplibs_check_method"; then
-	  func_fatal_error "cannot build libtool library '$output' from non-libtool objects on this host:$objs"
+	if test "$deplibs_check_method" != pass_all; then
+	  func_fatal_error "cannot build libtool library \`$output' from non-libtool objects on this host:$objs"
 	else
 	  echo
 	  $ECHO "*** Warning: Linking the shared library $output against the non-libtool"
@@ -8755,21 +7278,21 @@ func_mode_link ()
 	fi
       fi
 
-      test no = "$dlself" \
-	|| func_warning "'-dlopen self' is ignored for libtool libraries"
+      test "$dlself" != no && \
+	func_warning "\`-dlopen self' is ignored for libtool libraries"
 
       set dummy $rpath
       shift
-      test 1 -lt "$#" \
-	&& func_warning "ignoring multiple '-rpath's for a libtool library"
+      test "$#" -gt 1 && \
+	func_warning "ignoring multiple \`-rpath's for a libtool library"
 
-      install_libdir=$1
+      install_libdir="$1"
 
       oldlibs=
       if test -z "$rpath"; then
-	if test yes = "$build_libtool_libs"; then
+	if test "$build_libtool_libs" = yes; then
 	  # Building a libtool convenience library.
-	  # Some compilers have problems with a '.al' extension so
+	  # Some compilers have problems with a `.al' extension so
 	  # convenience libraries should have the same extension an
 	  # archive normally would.
 	  oldlibs="$output_objdir/$libname.$libext $oldlibs"
@@ -8778,20 +7301,20 @@ func_mode_link ()
 	fi
 
 	test -n "$vinfo" && \
-	  func_warning "'-version-info/-version-number' is ignored for convenience libraries"
+	  func_warning "\`-version-info/-version-number' is ignored for convenience libraries"
 
 	test -n "$release" && \
-	  func_warning "'-release' is ignored for convenience libraries"
+	  func_warning "\`-release' is ignored for convenience libraries"
       else
 
 	# Parse the version information argument.
-	save_ifs=$IFS; IFS=:
+	save_ifs="$IFS"; IFS=':'
 	set dummy $vinfo 0 0 0
 	shift
-	IFS=$save_ifs
+	IFS="$save_ifs"
 
 	test -n "$7" && \
-	  func_fatal_help "too many parameters to '-version-info'"
+	  func_fatal_help "too many parameters to \`-version-info'"
 
 	# convert absolute version numbers to libtool ages
 	# this retains compatibility with .la files and attempts
@@ -8799,45 +7322,45 @@ func_mode_link ()
 
 	case $vinfo_number in
 	yes)
-	  number_major=$1
-	  number_minor=$2
-	  number_revision=$3
+	  number_major="$1"
+	  number_minor="$2"
+	  number_revision="$3"
 	  #
 	  # There are really only two kinds -- those that
 	  # use the current revision as the major version
 	  # and those that subtract age and use age as
 	  # a minor version.  But, then there is irix
-	  # that has an extra 1 added just for fun
+	  # which has an extra 1 added just for fun
 	  #
 	  case $version_type in
 	  # correct linux to gnu/linux during the next big refactor
-	  darwin|freebsd-elf|linux|osf|windows|none)
+	  darwin|linux|osf|windows|none)
 	    func_arith $number_major + $number_minor
 	    current=$func_arith_result
-	    age=$number_minor
-	    revision=$number_revision
+	    age="$number_minor"
+	    revision="$number_revision"
 	    ;;
-	  freebsd-aout|qnx|sunos)
-	    current=$number_major
-	    revision=$number_minor
-	    age=0
+	  freebsd-aout|freebsd-elf|qnx|sunos)
+	    current="$number_major"
+	    revision="$number_minor"
+	    age="0"
 	    ;;
 	  irix|nonstopux)
 	    func_arith $number_major + $number_minor
 	    current=$func_arith_result
-	    age=$number_minor
-	    revision=$number_minor
+	    age="$number_minor"
+	    revision="$number_minor"
 	    lt_irix_increment=no
 	    ;;
 	  *)
-	    func_fatal_configuration "$modename: unknown library version type '$version_type'"
+	    func_fatal_configuration "$modename: unknown library version type \`$version_type'"
 	    ;;
 	  esac
 	  ;;
 	no)
-	  current=$1
-	  revision=$2
-	  age=$3
+	  current="$1"
+	  revision="$2"
+	  age="$3"
 	  ;;
 	esac
 
@@ -8845,30 +7368,30 @@ func_mode_link ()
 	case $current in
 	0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;;
 	*)
-	  func_error "CURRENT '$current' must be a nonnegative integer"
-	  func_fatal_error "'$vinfo' is not valid version information"
+	  func_error "CURRENT \`$current' must be a nonnegative integer"
+	  func_fatal_error "\`$vinfo' is not valid version information"
 	  ;;
 	esac
 
 	case $revision in
 	0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;;
 	*)
-	  func_error "REVISION '$revision' must be a nonnegative integer"
-	  func_fatal_error "'$vinfo' is not valid version information"
+	  func_error "REVISION \`$revision' must be a nonnegative integer"
+	  func_fatal_error "\`$vinfo' is not valid version information"
 	  ;;
 	esac
 
 	case $age in
 	0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;;
 	*)
-	  func_error "AGE '$age' must be a nonnegative integer"
-	  func_fatal_error "'$vinfo' is not valid version information"
+	  func_error "AGE \`$age' must be a nonnegative integer"
+	  func_fatal_error "\`$vinfo' is not valid version information"
 	  ;;
 	esac
 
 	if test "$age" -gt "$current"; then
-	  func_error "AGE '$age' is greater than the current interface number '$current'"
-	  func_fatal_error "'$vinfo' is not valid version information"
+	  func_error "AGE \`$age' is greater than the current interface number \`$current'"
+	  func_fatal_error "\`$vinfo' is not valid version information"
 	fi
 
 	# Calculate the version variables.
@@ -8883,36 +7406,26 @@ func_mode_link ()
 	  # verstring for coding it into the library header
 	  func_arith $current - $age
 	  major=.$func_arith_result
-	  versuffix=$major.$age.$revision
+	  versuffix="$major.$age.$revision"
 	  # Darwin ld doesn't like 0 for these options...
 	  func_arith $current + 1
 	  minor_current=$func_arith_result
-	  xlcverstring="$wl-compatibility_version $wl$minor_current $wl-current_version $wl$minor_current.$revision"
+	  xlcverstring="${wl}-compatibility_version ${wl}$minor_current ${wl}-current_version ${wl}$minor_current.$revision"
 	  verstring="-compatibility_version $minor_current -current_version $minor_current.$revision"
-          # On Darwin other compilers
-          case $CC in
-              nagfor*)
-                  verstring="$wl-compatibility_version $wl$minor_current $wl-current_version $wl$minor_current.$revision"
-                  ;;
-              *)
-                  verstring="-compatibility_version $minor_current -current_version $minor_current.$revision"
-                  ;;
-          esac
 	  ;;
 
 	freebsd-aout)
-	  major=.$current
-	  versuffix=.$current.$revision
+	  major=".$current"
+	  versuffix=".$current.$revision";
 	  ;;
 
 	freebsd-elf)
-	  func_arith $current - $age
-	  major=.$func_arith_result
-	  versuffix=$major.$age.$revision
+	  major=".$current"
+	  versuffix=".$current"
 	  ;;
 
 	irix | nonstopux)
-	  if test no = "$lt_irix_increment"; then
+	  if test "X$lt_irix_increment" = "Xno"; then
 	    func_arith $current - $age
 	  else
 	    func_arith $current - $age + 1
@@ -8923,74 +7436,69 @@ func_mode_link ()
 	    nonstopux) verstring_prefix=nonstopux ;;
 	    *)         verstring_prefix=sgi ;;
 	  esac
-	  verstring=$verstring_prefix$major.$revision
+	  verstring="$verstring_prefix$major.$revision"
 
 	  # Add in all the interfaces that we are compatible with.
 	  loop=$revision
-	  while test 0 -ne "$loop"; do
+	  while test "$loop" -ne 0; do
 	    func_arith $revision - $loop
 	    iface=$func_arith_result
 	    func_arith $loop - 1
 	    loop=$func_arith_result
-	    verstring=$verstring_prefix$major.$iface:$verstring
+	    verstring="$verstring_prefix$major.$iface:$verstring"
 	  done
 
-	  # Before this point, $major must not contain '.'.
+	  # Before this point, $major must not contain `.'.
 	  major=.$major
-	  versuffix=$major.$revision
+	  versuffix="$major.$revision"
 	  ;;
 
 	linux) # correct to gnu/linux during the next big refactor
 	  func_arith $current - $age
 	  major=.$func_arith_result
-	  versuffix=$major.$age.$revision
+	  versuffix="$major.$age.$revision"
 	  ;;
 
 	osf)
 	  func_arith $current - $age
 	  major=.$func_arith_result
-	  versuffix=.$current.$age.$revision
-	  verstring=$current.$age.$revision
+	  versuffix=".$current.$age.$revision"
+	  verstring="$current.$age.$revision"
 
 	  # Add in all the interfaces that we are compatible with.
 	  loop=$age
-	  while test 0 -ne "$loop"; do
+	  while test "$loop" -ne 0; do
 	    func_arith $current - $loop
 	    iface=$func_arith_result
 	    func_arith $loop - 1
 	    loop=$func_arith_result
-	    verstring=$verstring:$iface.0
+	    verstring="$verstring:${iface}.0"
 	  done
 
 	  # Make executables depend on our current version.
-	  func_append verstring ":$current.0"
+	  func_append verstring ":${current}.0"
 	  ;;
 
 	qnx)
-	  major=.$current
-	  versuffix=.$current
-	  ;;
-
-	sco)
-	  major=.$current
-	  versuffix=.$current
+	  major=".$current"
+	  versuffix=".$current"
 	  ;;
 
 	sunos)
-	  major=.$current
-	  versuffix=.$current.$revision
+	  major=".$current"
+	  versuffix=".$current.$revision"
 	  ;;
 
 	windows)
 	  # Use '-' rather than '.', since we only want one
-	  # extension on DOS 8.3 file systems.
+	  # extension on DOS 8.3 filesystems.
 	  func_arith $current - $age
 	  major=$func_arith_result
-	  versuffix=-$major
+	  versuffix="-$major"
 	  ;;
 
 	*)
-	  func_fatal_configuration "unknown library version type '$version_type'"
+	  func_fatal_configuration "unknown library version type \`$version_type'"
 	  ;;
 	esac
 
@@ -9004,45 +7512,42 @@ func_mode_link ()
 	    verstring=
 	    ;;
 	  *)
-	    verstring=0.0
+	    verstring="0.0"
 	    ;;
 	  esac
-	  if test no = "$need_version"; then
+	  if test "$need_version" = no; then
 	    versuffix=
 	  else
-	    versuffix=.0.0
+	    versuffix=".0.0"
 	  fi
 	fi
 
 	# Remove version info from name if versioning should be avoided
-	if test yes,no = "$avoid_version,$need_version"; then
+	if test "$avoid_version" = yes && test "$need_version" = no; then
 	  major=
 	  versuffix=
-	  verstring=
+	  verstring=""
 	fi
 
 	# Check to see if the archive will have undefined symbols.
-	if test yes = "$allow_undefined"; then
-	  if test unsupported = "$allow_undefined_flag"; then
-	    if test yes = "$build_old_libs"; then
-	      func_warning "undefined symbols not allowed in $host shared libraries; building static only"
-	      build_libtool_libs=no
-	    else
-	      func_fatal_error "can't build $host shared library unless -no-undefined is specified"
-	    fi
+	if test "$allow_undefined" = yes; then
+	  if test "$allow_undefined_flag" = unsupported; then
+	    func_warning "undefined symbols not allowed in $host shared libraries"
+	    build_libtool_libs=no
+	    build_old_libs=yes
 	  fi
 	else
 	  # Don't allow undefined symbols.
-	  allow_undefined_flag=$no_undefined_flag
+	  allow_undefined_flag="$no_undefined_flag"
 	fi
 
       fi
 
-      func_generate_dlsyms "$libname" "$libname" :
+      func_generate_dlsyms "$libname" "$libname" "yes"
       func_append libobjs " $symfileobj"
-      test " " = "$libobjs" && libobjs=
+      test "X$libobjs" = "X " && libobjs=
 
-      if test relink != "$opt_mode"; then
+      if test "$opt_mode" != relink; then
 	# Remove our outputs, but don't remove object files since they
 	# may have been created when compiling PIC objects.
 	removelist=
@@ -9051,8 +7556,8 @@ func_mode_link ()
 	  case $p in
 	    *.$objext | *.gcno)
 	       ;;
-	    $output_objdir/$outputname | $output_objdir/$libname.* | $output_objdir/$libname$release.*)
-	       if test -n "$precious_files_regex"; then
+	    $output_objdir/$outputname | $output_objdir/$libname.* | $output_objdir/${libname}${release}.*)
+	       if test "X$precious_files_regex" != "X"; then
 		 if $ECHO "$p" | $EGREP -e "$precious_files_regex" >/dev/null 2>&1
 		 then
 		   continue
@@ -9068,11 +7573,11 @@ func_mode_link ()
       fi
 
       # Now set the variables for building old libraries.
-      if test yes = "$build_old_libs" && test convenience != "$build_libtool_libs"; then
+      if test "$build_old_libs" = yes && test "$build_libtool_libs" != convenience ; then
 	func_append oldlibs " $output_objdir/$libname.$libext"
 
 	# Transform .lo files to .o files.
-	oldobjs="$objs "`$ECHO "$libobjs" | $SP2NL | $SED "/\.$libext$/d; $lo2o" | $NL2SP`
+	oldobjs="$objs "`$ECHO "$libobjs" | $SP2NL | $SED "/\.${libext}$/d; $lo2o" | $NL2SP`
       fi
 
       # Eliminate all temporary directories.
@@ -9093,13 +7598,13 @@ func_mode_link ()
 	  *) func_append finalize_rpath " $libdir" ;;
 	  esac
 	done
-	if test yes != "$hardcode_into_libs" || test yes = "$build_old_libs"; then
+	if test "$hardcode_into_libs" != yes || test "$build_old_libs" = yes; then
 	  dependency_libs="$temp_xrpath $dependency_libs"
 	fi
       fi
 
       # Make sure dlfiles contains only unique files that won't be dlpreopened
-      old_dlfiles=$dlfiles
+      old_dlfiles="$dlfiles"
       dlfiles=
       for lib in $old_dlfiles; do
 	case " $dlprefiles $dlfiles " in
@@ -9109,7 +7614,7 @@ func_mode_link ()
       done
 
       # Make sure dlprefiles contains only unique files
-      old_dlprefiles=$dlprefiles
+      old_dlprefiles="$dlprefiles"
       dlprefiles=
       for lib in $old_dlprefiles; do
 	case "$dlprefiles " in
@@ -9118,7 +7623,7 @@ func_mode_link ()
 	esac
       done
 
-      if test yes = "$build_libtool_libs"; then
+      if test "$build_libtool_libs" = yes; then
 	if test -n "$rpath"; then
 	  case $host in
 	  *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-beos* | *-cegcc* | *-*-haiku*)
@@ -9142,7 +7647,7 @@ func_mode_link ()
 	    ;;
 	  *)
 	    # Add libc to deplibs on all other systems if necessary.
-	    if test yes = "$build_libtool_need_lc"; then
+	    if test "$build_libtool_need_lc" = "yes"; then
 	      func_append deplibs " -lc"
 	    fi
 	    ;;
@@ -9158,9 +7663,9 @@ func_mode_link ()
 	# I'm not sure if I'm treating the release correctly.  I think
 	# release should show up in the -l (ie -lgmp5) so we don't want to
 	# add it in twice.  Is that correct?
-	release=
-	versuffix=
-	major=
+	release=""
+	versuffix=""
+	major=""
 	newdeplibs=
 	droppeddeps=no
 	case $deplibs_check_method in
@@ -9189,20 +7694,20 @@ EOF
 	      -l*)
 		func_stripname -l '' "$i"
 		name=$func_stripname_result
-		if test yes = "$allow_libtool_libs_with_static_runtimes"; then
+		if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
 		  case " $predeps $postdeps " in
 		  *" $i "*)
 		    func_append newdeplibs " $i"
-		    i=
+		    i=""
 		    ;;
 		  esac
 		fi
-		if test -n "$i"; then
+		if test -n "$i" ; then
 		  libname=`eval "\\$ECHO \"$libname_spec\""`
 		  deplib_matches=`eval "\\$ECHO \"$library_names_spec\""`
 		  set dummy $deplib_matches; shift
 		  deplib_match=$1
-		  if test `expr "$ldd_output" : ".*$deplib_match"` -ne 0; then
+		  if test `expr "$ldd_output" : ".*$deplib_match"` -ne 0 ; then
 		    func_append newdeplibs " $i"
 		  else
 		    droppeddeps=yes
@@ -9232,20 +7737,20 @@ EOF
 		$opt_dry_run || $RM conftest
 		if $LTCC $LTCFLAGS -o conftest conftest.c $i; then
 		  ldd_output=`ldd conftest`
-		  if test yes = "$allow_libtool_libs_with_static_runtimes"; then
+		  if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
 		    case " $predeps $postdeps " in
 		    *" $i "*)
 		      func_append newdeplibs " $i"
-		      i=
+		      i=""
 		      ;;
 		    esac
 		  fi
-		  if test -n "$i"; then
+		  if test -n "$i" ; then
 		    libname=`eval "\\$ECHO \"$libname_spec\""`
 		    deplib_matches=`eval "\\$ECHO \"$library_names_spec\""`
 		    set dummy $deplib_matches; shift
 		    deplib_match=$1
-		    if test `expr "$ldd_output" : ".*$deplib_match"` -ne 0; then
+		    if test `expr "$ldd_output" : ".*$deplib_match"` -ne 0 ; then
 		      func_append newdeplibs " $i"
 		    else
 		      droppeddeps=yes
@@ -9282,24 +7787,24 @@ EOF
 	    -l*)
 	      func_stripname -l '' "$a_deplib"
 	      name=$func_stripname_result
-	      if test yes = "$allow_libtool_libs_with_static_runtimes"; then
+	      if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
 		case " $predeps $postdeps " in
 		*" $a_deplib "*)
 		  func_append newdeplibs " $a_deplib"
-		  a_deplib=
+		  a_deplib=""
 		  ;;
 		esac
 	      fi
-	      if test -n "$a_deplib"; then
+	      if test -n "$a_deplib" ; then
 		libname=`eval "\\$ECHO \"$libname_spec\""`
 		if test -n "$file_magic_glob"; then
 		  libnameglob=`func_echo_all "$libname" | $SED -e $file_magic_glob`
 		else
 		  libnameglob=$libname
 		fi
-		test yes = "$want_nocaseglob" && nocaseglob=`shopt -p nocaseglob`
+		test "$want_nocaseglob" = yes && nocaseglob=`shopt -p nocaseglob`
 		for i in $lib_search_path $sys_lib_search_path $shlib_search_path; do
-		  if test yes = "$want_nocaseglob"; then
+		  if test "$want_nocaseglob" = yes; then
 		    shopt -s nocaseglob
 		    potential_libs=`ls $i/$libnameglob[.-]* 2>/dev/null`
 		    $nocaseglob
@@ -9317,25 +7822,25 @@ EOF
 		      # We might still enter an endless loop, since a link
 		      # loop can be closed while we follow links,
 		      # but so what?
-		      potlib=$potent_lib
+		      potlib="$potent_lib"
 		      while test -h "$potlib" 2>/dev/null; do
-			potliblink=`ls -ld $potlib | $SED 's/.* -> //'`
+			potliblink=`ls -ld $potlib | ${SED} 's/.* -> //'`
 			case $potliblink in
-			[\\/]* | [A-Za-z]:[\\/]*) potlib=$potliblink;;
-			*) potlib=`$ECHO "$potlib" | $SED 's|[^/]*$||'`"$potliblink";;
+			[\\/]* | [A-Za-z]:[\\/]*) potlib="$potliblink";;
+			*) potlib=`$ECHO "$potlib" | $SED 's,[^/]*$,,'`"$potliblink";;
 			esac
 		      done
 		      if eval $file_magic_cmd \"\$potlib\" 2>/dev/null |
 			 $SED -e 10q |
 			 $EGREP "$file_magic_regex" > /dev/null; then
 			func_append newdeplibs " $a_deplib"
-			a_deplib=
+			a_deplib=""
 			break 2
 		      fi
 		  done
 		done
 	      fi
-	      if test -n "$a_deplib"; then
+	      if test -n "$a_deplib" ; then
 		droppeddeps=yes
 		echo
 		$ECHO "*** Warning: linker path does not have real file for library $a_deplib."
@@ -9343,7 +7848,7 @@ EOF
 		echo "*** you link to this library.  But I can only do this if you have a"
 		echo "*** shared version of the library, which you do not appear to have"
 		echo "*** because I did check the linker path looking for a file starting"
-		if test -z "$potlib"; then
+		if test -z "$potlib" ; then
 		  $ECHO "*** with $libname but no candidates were found. (...for file magic test)"
 		else
 		  $ECHO "*** with $libname and none of the candidates passed a file format test"
@@ -9366,30 +7871,30 @@ EOF
 	    -l*)
 	      func_stripname -l '' "$a_deplib"
 	      name=$func_stripname_result
-	      if test yes = "$allow_libtool_libs_with_static_runtimes"; then
+	      if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
 		case " $predeps $postdeps " in
 		*" $a_deplib "*)
 		  func_append newdeplibs " $a_deplib"
-		  a_deplib=
+		  a_deplib=""
 		  ;;
 		esac
 	      fi
-	      if test -n "$a_deplib"; then
+	      if test -n "$a_deplib" ; then
 		libname=`eval "\\$ECHO \"$libname_spec\""`
 		for i in $lib_search_path $sys_lib_search_path $shlib_search_path; do
 		  potential_libs=`ls $i/$libname[.-]* 2>/dev/null`
 		  for potent_lib in $potential_libs; do
-		    potlib=$potent_lib # see symlink-check above in file_magic test
+		    potlib="$potent_lib" # see symlink-check above in file_magic test
 		    if eval "\$ECHO \"$potent_lib\"" 2>/dev/null | $SED 10q | \
 		       $EGREP "$match_pattern_regex" > /dev/null; then
 		      func_append newdeplibs " $a_deplib"
-		      a_deplib=
+		      a_deplib=""
 		      break 2
 		    fi
 		  done
 		done
 	      fi
-	      if test -n "$a_deplib"; then
+	      if test -n "$a_deplib" ; then
 		droppeddeps=yes
 		echo
 		$ECHO "*** Warning: linker path does not have real file for library $a_deplib."
@@ -9397,7 +7902,7 @@ EOF
 		echo "*** you link to this library.  But I can only do this if you have a"
 		echo "*** shared version of the library, which you do not appear to have"
 		echo "*** because I did check the linker path looking for a file starting"
-		if test -z "$potlib"; then
+		if test -z "$potlib" ; then
 		  $ECHO "*** with $libname but no candidates were found. (...for regex pattern test)"
 		else
 		  $ECHO "*** with $libname and none of the candidates passed a file format test"
@@ -9413,18 +7918,18 @@ EOF
 	  done # Gone through all deplibs.
 	  ;;
 	none | unknown | *)
-	  newdeplibs=
+	  newdeplibs=""
 	  tmp_deplibs=`$ECHO " $deplibs" | $SED 's/ -lc$//; s/ -[LR][^ ]*//g'`
-	  if test yes = "$allow_libtool_libs_with_static_runtimes"; then
-	    for i in $predeps $postdeps; do
+	  if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
+	    for i in $predeps $postdeps ; do
 	      # can't use Xsed below, because $i might contain '/'
-	      tmp_deplibs=`$ECHO " $tmp_deplibs" | $SED "s|$i||"`
+	      tmp_deplibs=`$ECHO " $tmp_deplibs" | $SED "s,$i,,"`
 	    done
 	  fi
 	  case $tmp_deplibs in
 	  *[!\	\ ]*)
 	    echo
-	    if test none = "$deplibs_check_method"; then
+	    if test "X$deplibs_check_method" = "Xnone"; then
 	      echo "*** Warning: inter-library dependencies are not supported in this platform."
 	    else
 	      echo "*** Warning: inter-library dependencies are not known to be supported."
@@ -9448,8 +7953,8 @@ EOF
 	  ;;
 	esac
 
-	if test yes = "$droppeddeps"; then
-	  if test yes = "$module"; then
+	if test "$droppeddeps" = yes; then
+	  if test "$module" = yes; then
 	    echo
 	    echo "*** Warning: libtool could not satisfy all declared inter-library"
 	    $ECHO "*** dependencies of module $libname.  Therefore, libtool will create"
@@ -9458,12 +7963,12 @@ EOF
 	    if test -z "$global_symbol_pipe"; then
 	      echo
 	      echo "*** However, this would only work if libtool was able to extract symbol"
-	      echo "*** lists from a program, using 'nm' or equivalent, but libtool could"
+	      echo "*** lists from a program, using \`nm' or equivalent, but libtool could"
 	      echo "*** not find such a program.  So, this module is probably useless."
-	      echo "*** 'nm' from GNU binutils and a full rebuild may help."
+	      echo "*** \`nm' from GNU binutils and a full rebuild may help."
 	    fi
-	    if test no = "$build_old_libs"; then
-	      oldlibs=$output_objdir/$libname.$libext
+	    if test "$build_old_libs" = no; then
+	      oldlibs="$output_objdir/$libname.$libext"
 	      build_libtool_libs=module
 	      build_old_libs=yes
 	    else
@@ -9474,14 +7979,14 @@ EOF
 	    echo "*** automatically added whenever a program is linked with this library"
 	    echo "*** or is declared to -dlopen it."
 
-	    if test no = "$allow_undefined"; then
+	    if test "$allow_undefined" = no; then
 	      echo
 	      echo "*** Since this library must not contain undefined symbols,"
 	      echo "*** because either the platform does not support them or"
 	      echo "*** it was explicitly requested with -no-undefined,"
 	      echo "*** libtool will only create a static version of it."
-	      if test no = "$build_old_libs"; then
-		oldlibs=$output_objdir/$libname.$libext
+	      if test "$build_old_libs" = no; then
+		oldlibs="$output_objdir/$libname.$libext"
 		build_libtool_libs=module
 		build_old_libs=yes
 	      else
@@ -9527,7 +8032,7 @@ EOF
 	*) func_append new_libs " $deplib" ;;
 	esac
       done
-      deplibs=$new_libs
+      deplibs="$new_libs"
 
       # All the library-specific variables (install_libdir is set above).
       library_names=
@@ -9535,25 +8040,25 @@ EOF
       dlname=
 
       # Test again, we may have decided not to build it any more
-      if test yes = "$build_libtool_libs"; then
-	# Remove $wl instances when linking with ld.
+      if test "$build_libtool_libs" = yes; then
+	# Remove ${wl} instances when linking with ld.
 	# FIXME: should test the right _cmds variable.
 	case $archive_cmds in
 	  *\$LD\ *) wl= ;;
         esac
-	if test yes = "$hardcode_into_libs"; then
+	if test "$hardcode_into_libs" = yes; then
 	  # Hardcode the library paths
 	  hardcode_libdirs=
 	  dep_rpath=
-	  rpath=$finalize_rpath
-	  test relink = "$opt_mode" || rpath=$compile_rpath$rpath
+	  rpath="$finalize_rpath"
+	  test "$opt_mode" != relink && rpath="$compile_rpath$rpath"
 	  for libdir in $rpath; do
 	    if test -n "$hardcode_libdir_flag_spec"; then
 	      if test -n "$hardcode_libdir_separator"; then
 		func_replace_sysroot "$libdir"
 		libdir=$func_replace_sysroot_result
 		if test -z "$hardcode_libdirs"; then
-		  hardcode_libdirs=$libdir
+		  hardcode_libdirs="$libdir"
 		else
 		  # Just accumulate the unique libdirs.
 		  case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in
@@ -9578,7 +8083,7 @@ EOF
 	  # Substitute the hardcoded libdirs into the rpath.
 	  if test -n "$hardcode_libdir_separator" &&
 	     test -n "$hardcode_libdirs"; then
-	    libdir=$hardcode_libdirs
+	    libdir="$hardcode_libdirs"
 	    eval "dep_rpath=\"$hardcode_libdir_flag_spec\""
 	  fi
 	  if test -n "$runpath_var" && test -n "$perm_rpath"; then
@@ -9592,8 +8097,8 @@ EOF
 	  test -n "$dep_rpath" && deplibs="$dep_rpath $deplibs"
 	fi
 
-	shlibpath=$finalize_shlibpath
-	test relink = "$opt_mode" || shlibpath=$compile_shlibpath$shlibpath
+	shlibpath="$finalize_shlibpath"
+	test "$opt_mode" != relink && shlibpath="$compile_shlibpath$shlibpath"
 	if test -n "$shlibpath"; then
 	  eval "$shlibpath_var='$shlibpath\$$shlibpath_var'; export $shlibpath_var"
 	fi
@@ -9603,19 +8108,19 @@ EOF
 	eval library_names=\"$library_names_spec\"
 	set dummy $library_names
 	shift
-	realname=$1
+	realname="$1"
 	shift
 
 	if test -n "$soname_spec"; then
 	  eval soname=\"$soname_spec\"
 	else
-	  soname=$realname
+	  soname="$realname"
 	fi
 	if test -z "$dlname"; then
 	  dlname=$soname
 	fi
 
-	lib=$output_objdir/$realname
+	lib="$output_objdir/$realname"
 	linknames=
 	for link
 	do
@@ -9629,7 +8134,7 @@ EOF
 	delfiles=
 	if test -n "$export_symbols" && test -n "$include_expsyms"; then
 	  $opt_dry_run || cp "$export_symbols" "$output_objdir/$libname.uexp"
-	  export_symbols=$output_objdir/$libname.uexp
+	  export_symbols="$output_objdir/$libname.uexp"
 	  func_append delfiles " $export_symbols"
 	fi
 
@@ -9638,31 +8143,31 @@ EOF
 	cygwin* | mingw* | cegcc*)
 	  if test -n "$export_symbols" && test -z "$export_symbols_regex"; then
 	    # exporting using user supplied symfile
-	    func_dll_def_p "$export_symbols" || {
+	    if test "x`$SED 1q $export_symbols`" != xEXPORTS; then
 	      # and it's NOT already a .def file. Must figure out
 	      # which of the given symbols are data symbols and tag
 	      # them as such. So, trigger use of export_symbols_cmds.
 	      # export_symbols gets reassigned inside the "prepare
 	      # the list of exported symbols" if statement, so the
 	      # include_expsyms logic still works.
-	      orig_export_symbols=$export_symbols
+	      orig_export_symbols="$export_symbols"
 	      export_symbols=
 	      always_export_symbols=yes
-	    }
+	    fi
 	  fi
 	  ;;
 	esac
 
 	# Prepare the list of exported symbols
 	if test -z "$export_symbols"; then
-	  if test yes = "$always_export_symbols" || test -n "$export_symbols_regex"; then
-	    func_verbose "generating symbol list for '$libname.la'"
-	    export_symbols=$output_objdir/$libname.exp
+	  if test "$always_export_symbols" = yes || test -n "$export_symbols_regex"; then
+	    func_verbose "generating symbol list for \`$libname.la'"
+	    export_symbols="$output_objdir/$libname.exp"
 	    $opt_dry_run || $RM $export_symbols
 	    cmds=$export_symbols_cmds
-	    save_ifs=$IFS; IFS='~'
+	    save_ifs="$IFS"; IFS='~'
 	    for cmd1 in $cmds; do
-	      IFS=$save_ifs
+	      IFS="$save_ifs"
 	      # Take the normal branch if the nm_file_list_spec branch
 	      # doesn't work or if tool conversion is not needed.
 	      case $nm_file_list_spec~$to_tool_file_cmd in
@@ -9676,7 +8181,7 @@ EOF
 		  try_normal_branch=no
 		  ;;
 	      esac
-	      if test yes = "$try_normal_branch" \
+	      if test "$try_normal_branch" = yes \
 		 && { test "$len" -lt "$max_cmd_len" \
 		      || test "$max_cmd_len" -le -1; }
 	      then
@@ -9687,7 +8192,7 @@ EOF
 		output_la=$func_basename_result
 		save_libobjs=$libobjs
 		save_output=$output
-		output=$output_objdir/$output_la.nm
+		output=${output_objdir}/${output_la}.nm
 		func_to_tool_file "$output"
 		libobjs=$nm_file_list_spec$func_to_tool_file_result
 		func_append delfiles " $output"
@@ -9710,8 +8215,8 @@ EOF
 		break
 	      fi
 	    done
-	    IFS=$save_ifs
-	    if test -n "$export_symbols_regex" && test : != "$skipped_export"; then
+	    IFS="$save_ifs"
+	    if test -n "$export_symbols_regex" && test "X$skipped_export" != "X:"; then
 	      func_show_eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"'
 	      func_show_eval '$MV "${export_symbols}T" "$export_symbols"'
 	    fi
@@ -9719,16 +8224,16 @@ EOF
 	fi
 
 	if test -n "$export_symbols" && test -n "$include_expsyms"; then
-	  tmp_export_symbols=$export_symbols
-	  test -n "$orig_export_symbols" && tmp_export_symbols=$orig_export_symbols
+	  tmp_export_symbols="$export_symbols"
+	  test -n "$orig_export_symbols" && tmp_export_symbols="$orig_export_symbols"
 	  $opt_dry_run || eval '$ECHO "$include_expsyms" | $SP2NL >> "$tmp_export_symbols"'
 	fi
 
-	if test : != "$skipped_export" && test -n "$orig_export_symbols"; then
+	if test "X$skipped_export" != "X:" && test -n "$orig_export_symbols"; then
 	  # The given exports_symbols file has to be filtered, so filter it.
-	  func_verbose "filter symbol list for '$libname.la' to tag DATA exports"
+	  func_verbose "filter symbol list for \`$libname.la' to tag DATA exports"
 	  # FIXME: $output_objdir/$libname.filter potentially contains lots of
-	  # 's' commands, which not all seds can handle. GNU sed should be fine
+	  # 's' commands which not all seds can handle. GNU sed should be fine
 	  # though. Also, the filter scales superlinearly with the number of
 	  # global variables. join(1) would be nice here, but unfortunately
 	  # isn't a blessed tool.
@@ -9747,11 +8252,11 @@ EOF
 	    ;;
 	  esac
 	done
-	deplibs=$tmp_deplibs
+	deplibs="$tmp_deplibs"
 
 	if test -n "$convenience"; then
 	  if test -n "$whole_archive_flag_spec" &&
-	    test yes = "$compiler_needs_object" &&
+	    test "$compiler_needs_object" = yes &&
 	    test -z "$libobjs"; then
 	    # extract the archives, so we have objects to list.
 	    # TODO: could optimize this to just extract one archive.
@@ -9762,7 +8267,7 @@ EOF
 	    eval libobjs=\"\$libobjs $whole_archive_flag_spec\"
 	    test "X$libobjs" = "X " && libobjs=
 	  else
-	    gentop=$output_objdir/${outputname}x
+	    gentop="$output_objdir/${outputname}x"
 	    func_append generated " $gentop"
 
 	    func_extract_archives $gentop $convenience
@@ -9771,18 +8276,18 @@ EOF
 	  fi
 	fi
 
-	if test yes = "$thread_safe" && test -n "$thread_safe_flag_spec"; then
+	if test "$thread_safe" = yes && test -n "$thread_safe_flag_spec"; then
 	  eval flag=\"$thread_safe_flag_spec\"
 	  func_append linker_flags " $flag"
 	fi
 
 	# Make a backup of the uninstalled library when relinking
-	if test relink = "$opt_mode"; then
+	if test "$opt_mode" = relink; then
 	  $opt_dry_run || eval '(cd $output_objdir && $RM ${realname}U && $MV $realname ${realname}U)' || exit $?
 	fi
 
 	# Do each of the archive commands.
-	if test yes = "$module" && test -n "$module_cmds"; then
+	if test "$module" = yes && test -n "$module_cmds" ; then
 	  if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then
 	    eval test_cmds=\"$module_expsym_cmds\"
 	    cmds=$module_expsym_cmds
@@ -9800,7 +8305,7 @@ EOF
 	  fi
 	fi
 
-	if test : != "$skipped_export" &&
+	if test "X$skipped_export" != "X:" &&
 	   func_len " $test_cmds" &&
 	   len=$func_len_result &&
 	   test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then
@@ -9833,8 +8338,8 @@ EOF
 	  last_robj=
 	  k=1
 
-	  if test -n "$save_libobjs" && test : != "$skipped_export" && test yes = "$with_gnu_ld"; then
-	    output=$output_objdir/$output_la.lnkscript
+	  if test -n "$save_libobjs" && test "X$skipped_export" != "X:" && test "$with_gnu_ld" = yes; then
+	    output=${output_objdir}/${output_la}.lnkscript
 	    func_verbose "creating GNU ld script: $output"
 	    echo 'INPUT (' > $output
 	    for obj in $save_libobjs
@@ -9846,14 +8351,14 @@ EOF
 	    func_append delfiles " $output"
 	    func_to_tool_file "$output"
 	    output=$func_to_tool_file_result
-	  elif test -n "$save_libobjs" && test : != "$skipped_export" && test -n "$file_list_spec"; then
-	    output=$output_objdir/$output_la.lnk
+	  elif test -n "$save_libobjs" && test "X$skipped_export" != "X:" && test "X$file_list_spec" != X; then
+	    output=${output_objdir}/${output_la}.lnk
 	    func_verbose "creating linker input file list: $output"
 	    : > $output
 	    set x $save_libobjs
 	    shift
 	    firstobj=
-	    if test yes = "$compiler_needs_object"; then
+	    if test "$compiler_needs_object" = yes; then
 	      firstobj="$1 "
 	      shift
 	    fi
@@ -9868,7 +8373,7 @@ EOF
 	  else
 	    if test -n "$save_libobjs"; then
 	      func_verbose "creating reloadable object files..."
-	      output=$output_objdir/$output_la-$k.$objext
+	      output=$output_objdir/$output_la-${k}.$objext
 	      eval test_cmds=\"$reload_cmds\"
 	      func_len " $test_cmds"
 	      len0=$func_len_result
@@ -9880,13 +8385,13 @@ EOF
 		func_len " $obj"
 		func_arith $len + $func_len_result
 		len=$func_arith_result
-		if test -z "$objlist" ||
+		if test "X$objlist" = X ||
 		   test "$len" -lt "$max_cmd_len"; then
 		  func_append objlist " $obj"
 		else
 		  # The command $test_cmds is almost too long, add a
 		  # command to the queue.
-		  if test 1 -eq "$k"; then
+		  if test "$k" -eq 1 ; then
 		    # The first file doesn't have a previous command to add.
 		    reload_objs=$objlist
 		    eval concat_cmds=\"$reload_cmds\"
@@ -9896,10 +8401,10 @@ EOF
 		    reload_objs="$objlist $last_robj"
 		    eval concat_cmds=\"\$concat_cmds~$reload_cmds~\$RM $last_robj\"
 		  fi
-		  last_robj=$output_objdir/$output_la-$k.$objext
+		  last_robj=$output_objdir/$output_la-${k}.$objext
 		  func_arith $k + 1
 		  k=$func_arith_result
-		  output=$output_objdir/$output_la-$k.$objext
+		  output=$output_objdir/$output_la-${k}.$objext
 		  objlist=" $obj"
 		  func_len " $last_robj"
 		  func_arith $len0 + $func_len_result
@@ -9911,9 +8416,9 @@ EOF
 	      # files will link in the last one created.
 	      test -z "$concat_cmds" || concat_cmds=$concat_cmds~
 	      reload_objs="$objlist $last_robj"
-	      eval concat_cmds=\"\$concat_cmds$reload_cmds\"
+	      eval concat_cmds=\"\${concat_cmds}$reload_cmds\"
 	      if test -n "$last_robj"; then
-	        eval concat_cmds=\"\$concat_cmds~\$RM $last_robj\"
+	        eval concat_cmds=\"\${concat_cmds}~\$RM $last_robj\"
 	      fi
 	      func_append delfiles " $output"
 
@@ -9921,9 +8426,9 @@ EOF
 	      output=
 	    fi
 
-	    ${skipped_export-false} && {
-	      func_verbose "generating symbol list for '$libname.la'"
-	      export_symbols=$output_objdir/$libname.exp
+	    if ${skipped_export-false}; then
+	      func_verbose "generating symbol list for \`$libname.la'"
+	      export_symbols="$output_objdir/$libname.exp"
 	      $opt_dry_run || $RM $export_symbols
 	      libobjs=$output
 	      # Append the command to create the export file.
@@ -9932,16 +8437,16 @@ EOF
 	      if test -n "$last_robj"; then
 		eval concat_cmds=\"\$concat_cmds~\$RM $last_robj\"
 	      fi
-	    }
+	    fi
 
 	    test -n "$save_libobjs" &&
 	      func_verbose "creating a temporary reloadable object file: $output"
 
 	    # Loop through the commands generated above and execute them.
-	    save_ifs=$IFS; IFS='~'
+	    save_ifs="$IFS"; IFS='~'
 	    for cmd in $concat_cmds; do
-	      IFS=$save_ifs
-	      $opt_quiet || {
+	      IFS="$save_ifs"
+	      $opt_silent || {
 		  func_quote_for_expand "$cmd"
 		  eval "func_echo $func_quote_for_expand_result"
 	      }
@@ -9949,7 +8454,7 @@ EOF
 		lt_exit=$?
 
 		# Restore the uninstalled library and exit
-		if test relink = "$opt_mode"; then
+		if test "$opt_mode" = relink; then
 		  ( cd "$output_objdir" && \
 		    $RM "${realname}T" && \
 		    $MV "${realname}U" "$realname" )
@@ -9958,7 +8463,7 @@ EOF
 		exit $lt_exit
 	      }
 	    done
-	    IFS=$save_ifs
+	    IFS="$save_ifs"
 
 	    if test -n "$export_symbols_regex" && ${skipped_export-false}; then
 	      func_show_eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"'
@@ -9966,18 +8471,18 @@ EOF
 	    fi
 	  fi
 
-          ${skipped_export-false} && {
+          if ${skipped_export-false}; then
 	    if test -n "$export_symbols" && test -n "$include_expsyms"; then
-	      tmp_export_symbols=$export_symbols
-	      test -n "$orig_export_symbols" && tmp_export_symbols=$orig_export_symbols
+	      tmp_export_symbols="$export_symbols"
+	      test -n "$orig_export_symbols" && tmp_export_symbols="$orig_export_symbols"
 	      $opt_dry_run || eval '$ECHO "$include_expsyms" | $SP2NL >> "$tmp_export_symbols"'
 	    fi
 
 	    if test -n "$orig_export_symbols"; then
 	      # The given exports_symbols file has to be filtered, so filter it.
-	      func_verbose "filter symbol list for '$libname.la' to tag DATA exports"
+	      func_verbose "filter symbol list for \`$libname.la' to tag DATA exports"
 	      # FIXME: $output_objdir/$libname.filter potentially contains lots of
-	      # 's' commands, which not all seds can handle. GNU sed should be fine
+	      # 's' commands which not all seds can handle. GNU sed should be fine
 	      # though. Also, the filter scales superlinearly with the number of
 	      # global variables. join(1) would be nice here, but unfortunately
 	      # isn't a blessed tool.
@@ -9986,7 +8491,7 @@ EOF
 	      export_symbols=$output_objdir/$libname.def
 	      $opt_dry_run || $SED -f $output_objdir/$libname.filter < $orig_export_symbols > $export_symbols
 	    fi
-	  }
+	  fi
 
 	  libobjs=$output
 	  # Restore the value of output.
@@ -10000,7 +8505,7 @@ EOF
 	  # value of $libobjs for piecewise linking.
 
 	  # Do each of the archive commands.
-	  if test yes = "$module" && test -n "$module_cmds"; then
+	  if test "$module" = yes && test -n "$module_cmds" ; then
 	    if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then
 	      cmds=$module_expsym_cmds
 	    else
@@ -10022,7 +8527,7 @@ EOF
 
 	# Add any objects from preloaded convenience libraries
 	if test -n "$dlprefiles"; then
-	  gentop=$output_objdir/${outputname}x
+	  gentop="$output_objdir/${outputname}x"
 	  func_append generated " $gentop"
 
 	  func_extract_archives $gentop $dlprefiles
@@ -10030,12 +8535,11 @@ EOF
 	  test "X$libobjs" = "X " && libobjs=
 	fi
 
-	save_ifs=$IFS; IFS='~'
+	save_ifs="$IFS"; IFS='~'
 	for cmd in $cmds; do
-	  IFS=$sp$nl
+	  IFS="$save_ifs"
 	  eval cmd=\"$cmd\"
-	  IFS=$save_ifs
-	  $opt_quiet || {
+	  $opt_silent || {
 	    func_quote_for_expand "$cmd"
 	    eval "func_echo $func_quote_for_expand_result"
 	  }
@@ -10043,7 +8547,7 @@ EOF
 	    lt_exit=$?
 
 	    # Restore the uninstalled library and exit
-	    if test relink = "$opt_mode"; then
+	    if test "$opt_mode" = relink; then
 	      ( cd "$output_objdir" && \
 	        $RM "${realname}T" && \
 		$MV "${realname}U" "$realname" )
@@ -10052,10 +8556,10 @@ EOF
 	    exit $lt_exit
 	  }
 	done
-	IFS=$save_ifs
+	IFS="$save_ifs"
 
 	# Restore the uninstalled library and exit
-	if test relink = "$opt_mode"; then
+	if test "$opt_mode" = relink; then
 	  $opt_dry_run || eval '(cd $output_objdir && $RM ${realname}T && $MV $realname ${realname}T && $MV ${realname}U $realname)' || exit $?
 
 	  if test -n "$convenience"; then
@@ -10075,39 +8579,39 @@ EOF
 	done
 
 	# If -module or -export-dynamic was specified, set the dlname.
-	if test yes = "$module" || test yes = "$export_dynamic"; then
+	if test "$module" = yes || test "$export_dynamic" = yes; then
 	  # On all known operating systems, these are identical.
-	  dlname=$soname
+	  dlname="$soname"
 	fi
       fi
       ;;
 
     obj)
-      if test -n "$dlfiles$dlprefiles" || test no != "$dlself"; then
-	func_warning "'-dlopen' is ignored for objects"
+      if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then
+	func_warning "\`-dlopen' is ignored for objects"
       fi
 
       case " $deplibs" in
       *\ -l* | *\ -L*)
-	func_warning "'-l' and '-L' are ignored for objects" ;;
+	func_warning "\`-l' and \`-L' are ignored for objects" ;;
       esac
 
       test -n "$rpath" && \
-	func_warning "'-rpath' is ignored for objects"
+	func_warning "\`-rpath' is ignored for objects"
 
       test -n "$xrpath" && \
-	func_warning "'-R' is ignored for objects"
+	func_warning "\`-R' is ignored for objects"
 
       test -n "$vinfo" && \
-	func_warning "'-version-info' is ignored for objects"
+	func_warning "\`-version-info' is ignored for objects"
 
       test -n "$release" && \
-	func_warning "'-release' is ignored for objects"
+	func_warning "\`-release' is ignored for objects"
 
       case $output in
       *.lo)
 	test -n "$objs$old_deplibs" && \
-	  func_fatal_error "cannot build library object '$output' from non-libtool objects"
+	  func_fatal_error "cannot build library object \`$output' from non-libtool objects"
 
 	libobj=$output
 	func_lo2o "$libobj"
@@ -10115,7 +8619,7 @@ EOF
 	;;
       *)
 	libobj=
-	obj=$output
+	obj="$output"
 	;;
       esac
 
@@ -10128,19 +8632,17 @@ EOF
       # the extraction.
       reload_conv_objs=
       gentop=
-      # if reload_cmds runs $LD directly, get rid of -Wl from
-      # whole_archive_flag_spec and hope we can get by with turning comma
-      # into space.
-      case $reload_cmds in
-        *\$LD[\ \$]*) wl= ;;
-      esac
+      # reload_cmds runs $LD directly, so let us get rid of
+      # -Wl from whole_archive_flag_spec and hope we can get by with
+      # turning comma into space..
+      wl=
+
       if test -n "$convenience"; then
 	if test -n "$whole_archive_flag_spec"; then
 	  eval tmp_whole_archive_flags=\"$whole_archive_flag_spec\"
-	  test -n "$wl" || tmp_whole_archive_flags=`$ECHO "$tmp_whole_archive_flags" | $SED 's|,| |g'`
-	  reload_conv_objs=$reload_objs\ $tmp_whole_archive_flags
+	  reload_conv_objs=$reload_objs\ `$ECHO "$tmp_whole_archive_flags" | $SED 's|,| |g'`
 	else
-	  gentop=$output_objdir/${obj}x
+	  gentop="$output_objdir/${obj}x"
 	  func_append generated " $gentop"
 
 	  func_extract_archives $gentop $convenience
@@ -10149,12 +8651,12 @@ EOF
       fi
 
       # If we're not building shared, we need to use non_pic_objs
-      test yes = "$build_libtool_libs" || libobjs=$non_pic_objects
+      test "$build_libtool_libs" != yes && libobjs="$non_pic_objects"
 
       # Create the old-style object.
-      reload_objs=$objs$old_deplibs' '`$ECHO "$libobjs" | $SP2NL | $SED "/\.$libext$/d; /\.lib$/d; $lo2o" | $NL2SP`' '$reload_conv_objs
+      reload_objs="$objs$old_deplibs "`$ECHO "$libobjs" | $SP2NL | $SED "/\.${libext}$/d; /\.lib$/d; $lo2o" | $NL2SP`" $reload_conv_objs" ### testsuite: skip nested quoting test
 
-      output=$obj
+      output="$obj"
       func_execute_cmds "$reload_cmds" 'exit $?'
 
       # Exit if we aren't doing a library object file.
@@ -10166,7 +8668,7 @@ EOF
 	exit $EXIT_SUCCESS
       fi
 
-      test yes = "$build_libtool_libs" || {
+      if test "$build_libtool_libs" != yes; then
 	if test -n "$gentop"; then
 	  func_show_eval '${RM}r "$gentop"'
 	fi
@@ -10176,12 +8678,12 @@ EOF
 	# $show "echo timestamp > $libobj"
 	# $opt_dry_run || eval "echo timestamp > $libobj" || exit $?
 	exit $EXIT_SUCCESS
-      }
+      fi
 
-      if test -n "$pic_flag" || test default != "$pic_mode"; then
+      if test -n "$pic_flag" || test "$pic_mode" != default; then
 	# Only do commands if we really have different PIC objects.
 	reload_objs="$libobjs $reload_conv_objs"
-	output=$libobj
+	output="$libobj"
 	func_execute_cmds "$reload_cmds" 'exit $?'
       fi
 
@@ -10198,14 +8700,16 @@ EOF
 	          output=$func_stripname_result.exe;;
       esac
       test -n "$vinfo" && \
-	func_warning "'-version-info' is ignored for programs"
+	func_warning "\`-version-info' is ignored for programs"
 
       test -n "$release" && \
-	func_warning "'-release' is ignored for programs"
+	func_warning "\`-release' is ignored for programs"
 
-      $preload \
-	&& test unknown,unknown,unknown = "$dlopen_support,$dlopen_self,$dlopen_self_static" \
-	&& func_warning "'LT_INIT([dlopen])' not used. Assuming no dlopen support."
+      test "$preload" = yes \
+        && test "$dlopen_support" = unknown \
+	&& test "$dlopen_self" = unknown \
+	&& test "$dlopen_self_static" = unknown && \
+	  func_warning "\`LT_INIT([dlopen])' not used. Assuming no dlopen support."
 
       case $host in
       *-*-rhapsody* | *-*-darwin1.[012])
@@ -10219,11 +8723,11 @@ EOF
       *-*-darwin*)
 	# Don't allow lazy linking, it breaks C++ global constructors
 	# But is supposedly fixed on 10.4 or later (yay!).
-	if test CXX = "$tagname"; then
+	if test "$tagname" = CXX ; then
 	  case ${MACOSX_DEPLOYMENT_TARGET-10.0} in
 	    10.[0123])
-	      func_append compile_command " $wl-bind_at_load"
-	      func_append finalize_command " $wl-bind_at_load"
+	      func_append compile_command " ${wl}-bind_at_load"
+	      func_append finalize_command " ${wl}-bind_at_load"
 	    ;;
 	  esac
 	fi
@@ -10259,7 +8763,7 @@ EOF
 	*) func_append new_libs " $deplib" ;;
 	esac
       done
-      compile_deplibs=$new_libs
+      compile_deplibs="$new_libs"
 
 
       func_append compile_command " $compile_deplibs"
@@ -10283,7 +8787,7 @@ EOF
 	if test -n "$hardcode_libdir_flag_spec"; then
 	  if test -n "$hardcode_libdir_separator"; then
 	    if test -z "$hardcode_libdirs"; then
-	      hardcode_libdirs=$libdir
+	      hardcode_libdirs="$libdir"
 	    else
 	      # Just accumulate the unique libdirs.
 	      case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in
@@ -10306,7 +8810,7 @@ EOF
 	fi
 	case $host in
 	*-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*)
-	  testbindir=`$ECHO "$libdir" | $SED -e 's*/lib$*/bin*'`
+	  testbindir=`${ECHO} "$libdir" | ${SED} -e 's*/lib$*/bin*'`
 	  case :$dllsearchpath: in
 	  *":$libdir:"*) ;;
 	  ::) dllsearchpath=$libdir;;
@@ -10323,10 +8827,10 @@ EOF
       # Substitute the hardcoded libdirs into the rpath.
       if test -n "$hardcode_libdir_separator" &&
 	 test -n "$hardcode_libdirs"; then
-	libdir=$hardcode_libdirs
+	libdir="$hardcode_libdirs"
 	eval rpath=\" $hardcode_libdir_flag_spec\"
       fi
-      compile_rpath=$rpath
+      compile_rpath="$rpath"
 
       rpath=
       hardcode_libdirs=
@@ -10334,7 +8838,7 @@ EOF
 	if test -n "$hardcode_libdir_flag_spec"; then
 	  if test -n "$hardcode_libdir_separator"; then
 	    if test -z "$hardcode_libdirs"; then
-	      hardcode_libdirs=$libdir
+	      hardcode_libdirs="$libdir"
 	    else
 	      # Just accumulate the unique libdirs.
 	      case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in
@@ -10359,43 +8863,45 @@ EOF
       # Substitute the hardcoded libdirs into the rpath.
       if test -n "$hardcode_libdir_separator" &&
 	 test -n "$hardcode_libdirs"; then
-	libdir=$hardcode_libdirs
+	libdir="$hardcode_libdirs"
 	eval rpath=\" $hardcode_libdir_flag_spec\"
       fi
-      finalize_rpath=$rpath
+      finalize_rpath="$rpath"
 
-      if test -n "$libobjs" && test yes = "$build_old_libs"; then
+      if test -n "$libobjs" && test "$build_old_libs" = yes; then
 	# Transform all the library objects into standard objects.
 	compile_command=`$ECHO "$compile_command" | $SP2NL | $SED "$lo2o" | $NL2SP`
 	finalize_command=`$ECHO "$finalize_command" | $SP2NL | $SED "$lo2o" | $NL2SP`
       fi
 
-      func_generate_dlsyms "$outputname" "@PROGRAM@" false
+      func_generate_dlsyms "$outputname" "@PROGRAM@" "no"
 
       # template prelinking step
       if test -n "$prelink_cmds"; then
 	func_execute_cmds "$prelink_cmds" 'exit $?'
       fi
 
-      wrappers_required=:
+      wrappers_required=yes
       case $host in
       *cegcc* | *mingw32ce*)
         # Disable wrappers for cegcc and mingw32ce hosts, we are cross compiling anyway.
-        wrappers_required=false
+        wrappers_required=no
         ;;
       *cygwin* | *mingw* )
-        test yes = "$build_libtool_libs" || wrappers_required=false
+        if test "$build_libtool_libs" != yes; then
+          wrappers_required=no
+        fi
         ;;
       *)
-        if test no = "$need_relink" || test yes != "$build_libtool_libs"; then
-          wrappers_required=false
+        if test "$need_relink" = no || test "$build_libtool_libs" != yes; then
+          wrappers_required=no
         fi
         ;;
       esac
-      $wrappers_required || {
+      if test "$wrappers_required" = no; then
 	# Replace the output file specification.
 	compile_command=`$ECHO "$compile_command" | $SED 's%@OUTPUT@%'"$output"'%g'`
-	link_command=$compile_command$compile_rpath
+	link_command="$compile_command$compile_rpath"
 
 	# We have no uninstalled library dependencies, so finalize right now.
 	exit_status=0
@@ -10408,12 +8914,12 @@ EOF
 	fi
 
 	# Delete the generated files.
-	if test -f "$output_objdir/${outputname}S.$objext"; then
-	  func_show_eval '$RM "$output_objdir/${outputname}S.$objext"'
+	if test -f "$output_objdir/${outputname}S.${objext}"; then
+	  func_show_eval '$RM "$output_objdir/${outputname}S.${objext}"'
 	fi
 
 	exit $exit_status
-      }
+      fi
 
       if test -n "$compile_shlibpath$finalize_shlibpath"; then
 	compile_command="$shlibpath_var=\"$compile_shlibpath$finalize_shlibpath\$$shlibpath_var\" $compile_command"
@@ -10443,9 +8949,9 @@ EOF
 	fi
       fi
 
-      if test yes = "$no_install"; then
+      if test "$no_install" = yes; then
 	# We don't need to create a wrapper script.
-	link_command=$compile_var$compile_command$compile_rpath
+	link_command="$compile_var$compile_command$compile_rpath"
 	# Replace the output file specification.
 	link_command=`$ECHO "$link_command" | $SED 's%@OUTPUT@%'"$output"'%g'`
 	# Delete the old output file.
@@ -10462,28 +8968,27 @@ EOF
 	exit $EXIT_SUCCESS
       fi
 
-      case $hardcode_action,$fast_install in
-        relink,*)
-	  # Fast installation is not supported
-	  link_command=$compile_var$compile_command$compile_rpath
-	  relink_command=$finalize_var$finalize_command$finalize_rpath
+      if test "$hardcode_action" = relink; then
+	# Fast installation is not supported
+	link_command="$compile_var$compile_command$compile_rpath"
+	relink_command="$finalize_var$finalize_command$finalize_rpath"
 
-	  func_warning "this platform does not like uninstalled shared libraries"
-	  func_warning "'$output' will be relinked during installation"
-	  ;;
-        *,yes)
-	  link_command=$finalize_var$compile_command$finalize_rpath
-	  relink_command=`$ECHO "$compile_var$compile_command$compile_rpath" | $SED 's%@OUTPUT@%\$progdir/\$file%g'`
-          ;;
-	*,no)
-	  link_command=$compile_var$compile_command$compile_rpath
-	  relink_command=$finalize_var$finalize_command$finalize_rpath
-          ;;
-	*,needless)
-	  link_command=$finalize_var$compile_command$finalize_rpath
-	  relink_command=
-          ;;
-      esac
+	func_warning "this platform does not like uninstalled shared libraries"
+	func_warning "\`$output' will be relinked during installation"
+      else
+	if test "$fast_install" != no; then
+	  link_command="$finalize_var$compile_command$finalize_rpath"
+	  if test "$fast_install" = yes; then
+	    relink_command=`$ECHO "$compile_var$compile_command$compile_rpath" | $SED 's%@OUTPUT@%\$progdir/\$file%g'`
+	  else
+	    # fast_install is set to needless
+	    relink_command=
+	  fi
+	else
+	  link_command="$compile_var$compile_command$compile_rpath"
+	  relink_command="$finalize_var$finalize_command$finalize_rpath"
+	fi
+      fi
 
       # Replace the output file specification.
       link_command=`$ECHO "$link_command" | $SED 's%@OUTPUT@%'"$output_objdir/$outputname"'%g'`
@@ -10540,8 +9045,8 @@ EOF
 	    func_dirname_and_basename "$output" "" "."
 	    output_name=$func_basename_result
 	    output_path=$func_dirname_result
-	    cwrappersource=$output_path/$objdir/lt-$output_name.c
-	    cwrapper=$output_path/$output_name.exe
+	    cwrappersource="$output_path/$objdir/lt-$output_name.c"
+	    cwrapper="$output_path/$output_name.exe"
 	    $RM $cwrappersource $cwrapper
 	    trap "$RM $cwrappersource $cwrapper; exit $EXIT_FAILURE" 1 2 15
 
@@ -10562,7 +9067,7 @@ EOF
 	    trap "$RM $func_ltwrapper_scriptname_result; exit $EXIT_FAILURE" 1 2 15
 	    $opt_dry_run || {
 	      # note: this script will not be executed, so do not chmod.
-	      if test "x$build" = "x$host"; then
+	      if test "x$build" = "x$host" ; then
 		$cwrapper --lt-dump-script > $func_ltwrapper_scriptname_result
 	      else
 		func_emit_wrapper no > $func_ltwrapper_scriptname_result
@@ -10585,27 +9090,25 @@ EOF
     # See if we need to build an old-fashioned archive.
     for oldlib in $oldlibs; do
 
-      case $build_libtool_libs in
-        convenience)
-	  oldobjs="$libobjs_save $symfileobj"
-	  addlibs=$convenience
-	  build_libtool_libs=no
-	  ;;
-	module)
-	  oldobjs=$libobjs_save
-	  addlibs=$old_convenience
+      if test "$build_libtool_libs" = convenience; then
+	oldobjs="$libobjs_save $symfileobj"
+	addlibs="$convenience"
+	build_libtool_libs=no
+      else
+	if test "$build_libtool_libs" = module; then
+	  oldobjs="$libobjs_save"
 	  build_libtool_libs=no
-          ;;
-	*)
+	else
 	  oldobjs="$old_deplibs $non_pic_objects"
-	  $preload && test -f "$symfileobj" \
-	    && func_append oldobjs " $symfileobj"
-	  addlibs=$old_convenience
-	  ;;
-      esac
+	  if test "$preload" = yes && test -f "$symfileobj"; then
+	    func_append oldobjs " $symfileobj"
+	  fi
+	fi
+	addlibs="$old_convenience"
+      fi
 
       if test -n "$addlibs"; then
-	gentop=$output_objdir/${outputname}x
+	gentop="$output_objdir/${outputname}x"
 	func_append generated " $gentop"
 
 	func_extract_archives $gentop $addlibs
@@ -10613,13 +9116,13 @@ EOF
       fi
 
       # Do each command in the archive commands.
-      if test -n "$old_archive_from_new_cmds" && test yes = "$build_libtool_libs"; then
+      if test -n "$old_archive_from_new_cmds" && test "$build_libtool_libs" = yes; then
 	cmds=$old_archive_from_new_cmds
       else
 
 	# Add any objects from preloaded convenience libraries
 	if test -n "$dlprefiles"; then
-	  gentop=$output_objdir/${outputname}x
+	  gentop="$output_objdir/${outputname}x"
 	  func_append generated " $gentop"
 
 	  func_extract_archives $gentop $dlprefiles
@@ -10640,7 +9143,7 @@ EOF
 	  :
 	else
 	  echo "copying selected object files to avoid basename conflicts..."
-	  gentop=$output_objdir/${outputname}x
+	  gentop="$output_objdir/${outputname}x"
 	  func_append generated " $gentop"
 	  func_mkdir_p "$gentop"
 	  save_oldobjs=$oldobjs
@@ -10649,7 +9152,7 @@ EOF
 	  for obj in $save_oldobjs
 	  do
 	    func_basename "$obj"
-	    objbase=$func_basename_result
+	    objbase="$func_basename_result"
 	    case " $oldobjs " in
 	    " ") oldobjs=$obj ;;
 	    *[\ /]"$objbase "*)
@@ -10718,18 +9221,18 @@ EOF
 	    else
 	      # the above command should be used before it gets too long
 	      oldobjs=$objlist
-	      if test "$obj" = "$last_oldobj"; then
+	      if test "$obj" = "$last_oldobj" ; then
 		RANLIB=$save_RANLIB
 	      fi
 	      test -z "$concat_cmds" || concat_cmds=$concat_cmds~
-	      eval concat_cmds=\"\$concat_cmds$old_archive_cmds\"
+	      eval concat_cmds=\"\${concat_cmds}$old_archive_cmds\"
 	      objlist=
 	      len=$len0
 	    fi
 	  done
 	  RANLIB=$save_RANLIB
 	  oldobjs=$objlist
-	  if test -z "$oldobjs"; then
+	  if test "X$oldobjs" = "X" ; then
 	    eval cmds=\"\$concat_cmds\"
 	  else
 	    eval cmds=\"\$concat_cmds~\$old_archive_cmds\"
@@ -10746,7 +9249,7 @@ EOF
     case $output in
     *.la)
       old_library=
-      test yes = "$build_old_libs" && old_library=$libname.$libext
+      test "$build_old_libs" = yes && old_library="$libname.$libext"
       func_verbose "creating $output"
 
       # Preserve any variables that may affect compiler behavior
@@ -10761,31 +9264,31 @@ EOF
 	fi
       done
       # Quote the link command for shipping.
-      relink_command="(cd `pwd`; $SHELL \"$progpath\" $preserve_args --mode=relink $libtool_args @inst_prefix_dir@)"
+      relink_command="(cd `pwd`; $SHELL $progpath $preserve_args --mode=relink $libtool_args @inst_prefix_dir@)"
       relink_command=`$ECHO "$relink_command" | $SED "$sed_quote_subst"`
-      if test yes = "$hardcode_automatic"; then
+      if test "$hardcode_automatic" = yes ; then
 	relink_command=
       fi
 
       # Only create the output if not a dry run.
       $opt_dry_run || {
 	for installed in no yes; do
-	  if test yes = "$installed"; then
+	  if test "$installed" = yes; then
 	    if test -z "$install_libdir"; then
 	      break
 	    fi
-	    output=$output_objdir/${outputname}i
+	    output="$output_objdir/$outputname"i
 	    # Replace all uninstalled libtool libraries with the installed ones
 	    newdependency_libs=
 	    for deplib in $dependency_libs; do
 	      case $deplib in
 	      *.la)
 		func_basename "$deplib"
-		name=$func_basename_result
+		name="$func_basename_result"
 		func_resolve_sysroot "$deplib"
-		eval libdir=`$SED -n -e 's/^libdir=\(.*\)$/\1/p' $func_resolve_sysroot_result`
+		eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $func_resolve_sysroot_result`
 		test -z "$libdir" && \
-		  func_fatal_error "'$deplib' is not a valid libtool archive"
+		  func_fatal_error "\`$deplib' is not a valid libtool archive"
 		func_append newdependency_libs " ${lt_sysroot:+=}$libdir/$name"
 		;;
 	      -L*)
@@ -10801,23 +9304,23 @@ EOF
 	      *) func_append newdependency_libs " $deplib" ;;
 	      esac
 	    done
-	    dependency_libs=$newdependency_libs
+	    dependency_libs="$newdependency_libs"
 	    newdlfiles=
 
 	    for lib in $dlfiles; do
 	      case $lib in
 	      *.la)
 	        func_basename "$lib"
-		name=$func_basename_result
-		eval libdir=`$SED -n -e 's/^libdir=\(.*\)$/\1/p' $lib`
+		name="$func_basename_result"
+		eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib`
 		test -z "$libdir" && \
-		  func_fatal_error "'$lib' is not a valid libtool archive"
+		  func_fatal_error "\`$lib' is not a valid libtool archive"
 		func_append newdlfiles " ${lt_sysroot:+=}$libdir/$name"
 		;;
 	      *) func_append newdlfiles " $lib" ;;
 	      esac
 	    done
-	    dlfiles=$newdlfiles
+	    dlfiles="$newdlfiles"
 	    newdlprefiles=
 	    for lib in $dlprefiles; do
 	      case $lib in
@@ -10827,34 +9330,34 @@ EOF
 		# didn't already link the preopened objects directly into
 		# the library:
 		func_basename "$lib"
-		name=$func_basename_result
-		eval libdir=`$SED -n -e 's/^libdir=\(.*\)$/\1/p' $lib`
+		name="$func_basename_result"
+		eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib`
 		test -z "$libdir" && \
-		  func_fatal_error "'$lib' is not a valid libtool archive"
+		  func_fatal_error "\`$lib' is not a valid libtool archive"
 		func_append newdlprefiles " ${lt_sysroot:+=}$libdir/$name"
 		;;
 	      esac
 	    done
-	    dlprefiles=$newdlprefiles
+	    dlprefiles="$newdlprefiles"
 	  else
 	    newdlfiles=
 	    for lib in $dlfiles; do
 	      case $lib in
-		[\\/]* | [A-Za-z]:[\\/]*) abs=$lib ;;
+		[\\/]* | [A-Za-z]:[\\/]*) abs="$lib" ;;
 		*) abs=`pwd`"/$lib" ;;
 	      esac
 	      func_append newdlfiles " $abs"
 	    done
-	    dlfiles=$newdlfiles
+	    dlfiles="$newdlfiles"
 	    newdlprefiles=
 	    for lib in $dlprefiles; do
 	      case $lib in
-		[\\/]* | [A-Za-z]:[\\/]*) abs=$lib ;;
+		[\\/]* | [A-Za-z]:[\\/]*) abs="$lib" ;;
 		*) abs=`pwd`"/$lib" ;;
 	      esac
 	      func_append newdlprefiles " $abs"
 	    done
-	    dlprefiles=$newdlprefiles
+	    dlprefiles="$newdlprefiles"
 	  fi
 	  $RM $output
 	  # place dlname in correct position for cygwin
@@ -10870,9 +9373,10 @@ EOF
 	  case $host,$output,$installed,$module,$dlname in
 	    *cygwin*,*lai,yes,no,*.dll | *mingw*,*lai,yes,no,*.dll | *cegcc*,*lai,yes,no,*.dll)
 	      # If a -bindir argument was supplied, place the dll there.
-	      if test -n "$bindir"; then
+	      if test "x$bindir" != x ;
+	      then
 		func_relative_path "$install_libdir" "$bindir"
-		tdlname=$func_relative_path_result/$dlname
+		tdlname=$func_relative_path_result$dlname
 	      else
 		# Otherwise fall back on heuristic.
 		tdlname=../bin/$dlname
@@ -10881,7 +9385,7 @@ EOF
 	  esac
 	  $ECHO > $output "\
 # $outputname - a libtool library file
-# Generated by $PROGRAM (GNU $PACKAGE) $VERSION
+# Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION
 #
 # Please DO NOT delete this file!
 # It is necessary for linking the library.
@@ -10895,7 +9399,7 @@ library_names='$library_names'
 # The name of the static archive.
 old_library='$old_library'
 
-# Linker flags that cannot go in dependency_libs.
+# Linker flags that can not go in dependency_libs.
 inherited_linker_flags='$new_inherited_linker_flags'
 
 # Libraries that this one depends upon.
@@ -10921,7 +9425,7 @@ dlpreopen='$dlprefiles'
 
 # Directory that this library needs to be installed in:
 libdir='$install_libdir'"
-	  if test no,yes = "$installed,$need_relink"; then
+	  if test "$installed" = no && test "$need_relink" = yes; then
 	    $ECHO >> $output "\
 relink_command=\"$relink_command\""
 	  fi
@@ -10936,29 +9440,27 @@ relink_command=\"$relink_command\""
     exit $EXIT_SUCCESS
 }
 
-if test link = "$opt_mode" || test relink = "$opt_mode"; then
-  func_mode_link ${1+"$@"}
-fi
+{ test "$opt_mode" = link || test "$opt_mode" = relink; } &&
+    func_mode_link ${1+"$@"}
 
 
 # func_mode_uninstall arg...
 func_mode_uninstall ()
 {
-    $debug_cmd
-
-    RM=$nonopt
+    $opt_debug
+    RM="$nonopt"
     files=
-    rmforce=false
+    rmforce=
     exit_status=0
 
     # This variable tells wrapper scripts just to set variables rather
     # than running their programs.
-    libtool_install_magic=$magic
+    libtool_install_magic="$magic"
 
     for arg
     do
       case $arg in
-      -f) func_append RM " $arg"; rmforce=: ;;
+      -f) func_append RM " $arg"; rmforce=yes ;;
       -*) func_append RM " $arg" ;;
       *) func_append files " $arg" ;;
       esac
@@ -10971,18 +9473,18 @@ func_mode_uninstall ()
 
     for file in $files; do
       func_dirname "$file" "" "."
-      dir=$func_dirname_result
-      if test . = "$dir"; then
-	odir=$objdir
+      dir="$func_dirname_result"
+      if test "X$dir" = X.; then
+	odir="$objdir"
       else
-	odir=$dir/$objdir
+	odir="$dir/$objdir"
       fi
       func_basename "$file"
-      name=$func_basename_result
-      test uninstall = "$opt_mode" && odir=$dir
+      name="$func_basename_result"
+      test "$opt_mode" = uninstall && odir="$dir"
 
       # Remember odir for removal later, being careful to avoid duplicates
-      if test clean = "$opt_mode"; then
+      if test "$opt_mode" = clean; then
 	case " $rmdirs " in
 	  *" $odir "*) ;;
 	  *) func_append rmdirs " $odir" ;;
@@ -10997,11 +9499,11 @@ func_mode_uninstall ()
       elif test -d "$file"; then
 	exit_status=1
 	continue
-      elif $rmforce; then
+      elif test "$rmforce" = yes; then
 	continue
       fi
 
-      rmfiles=$file
+      rmfiles="$file"
 
       case $name in
       *.la)
@@ -11015,7 +9517,7 @@ func_mode_uninstall ()
 	  done
 	  test -n "$old_library" && func_append rmfiles " $odir/$old_library"
 
-	  case $opt_mode in
+	  case "$opt_mode" in
 	  clean)
 	    case " $library_names " in
 	    *" $dlname "*) ;;
@@ -11026,12 +9528,12 @@ func_mode_uninstall ()
 	  uninstall)
 	    if test -n "$library_names"; then
 	      # Do each command in the postuninstall commands.
-	      func_execute_cmds "$postuninstall_cmds" '$rmforce || exit_status=1'
+	      func_execute_cmds "$postuninstall_cmds" 'test "$rmforce" = yes || exit_status=1'
 	    fi
 
 	    if test -n "$old_library"; then
 	      # Do each command in the old_postuninstall commands.
-	      func_execute_cmds "$old_postuninstall_cmds" '$rmforce || exit_status=1'
+	      func_execute_cmds "$old_postuninstall_cmds" 'test "$rmforce" = yes || exit_status=1'
 	    fi
 	    # FIXME: should reinstall the best remaining shared library.
 	    ;;
@@ -11047,19 +9549,21 @@ func_mode_uninstall ()
 	  func_source $dir/$name
 
 	  # Add PIC object to the list of files to remove.
-	  if test -n "$pic_object" && test none != "$pic_object"; then
+	  if test -n "$pic_object" &&
+	     test "$pic_object" != none; then
 	    func_append rmfiles " $dir/$pic_object"
 	  fi
 
 	  # Add non-PIC object to the list of files to remove.
-	  if test -n "$non_pic_object" && test none != "$non_pic_object"; then
+	  if test -n "$non_pic_object" &&
+	     test "$non_pic_object" != none; then
 	    func_append rmfiles " $dir/$non_pic_object"
 	  fi
 	fi
 	;;
 
       *)
-	if test clean = "$opt_mode"; then
+	if test "$opt_mode" = clean ; then
 	  noexename=$name
 	  case $file in
 	  *.exe)
@@ -11086,12 +9590,12 @@ func_mode_uninstall ()
 
 	    # note $name still contains .exe if it was in $file originally
 	    # as does the version of $file that was added into $rmfiles
-	    func_append rmfiles " $odir/$name $odir/${name}S.$objext"
-	    if test yes = "$fast_install" && test -n "$relink_command"; then
+	    func_append rmfiles " $odir/$name $odir/${name}S.${objext}"
+	    if test "$fast_install" = yes && test -n "$relink_command"; then
 	      func_append rmfiles " $odir/lt-$name"
 	    fi
-	    if test "X$noexename" != "X$name"; then
-	      func_append rmfiles " $odir/lt-$noexename.c"
+	    if test "X$noexename" != "X$name" ; then
+	      func_append rmfiles " $odir/lt-${noexename}.c"
 	    fi
 	  fi
 	fi
@@ -11100,7 +9604,7 @@ func_mode_uninstall ()
       func_show_eval "$RM $rmfiles" 'exit_status=1'
     done
 
-    # Try to remove the $objdir's in the directories where we deleted files
+    # Try to remove the ${objdir}s in the directories where we deleted files
     for dir in $rmdirs; do
       if test -d "$dir"; then
 	func_show_eval "rmdir $dir >/dev/null 2>&1"
@@ -11110,17 +9614,16 @@ func_mode_uninstall ()
     exit $exit_status
 }
 
-if test uninstall = "$opt_mode" || test clean = "$opt_mode"; then
-  func_mode_uninstall ${1+"$@"}
-fi
+{ test "$opt_mode" = uninstall || test "$opt_mode" = clean; } &&
+    func_mode_uninstall ${1+"$@"}
 
 test -z "$opt_mode" && {
-  help=$generic_help
+  help="$generic_help"
   func_fatal_help "you must specify a MODE"
 }
 
 test -z "$exec_cmd" && \
-  func_fatal_help "invalid operation mode '$opt_mode'"
+  func_fatal_help "invalid operation mode \`$opt_mode'"
 
 if test -n "$exec_cmd"; then
   eval exec "$exec_cmd"
@@ -11131,7 +9634,7 @@ exit $exit_status
 
 
 # The TAGs below are defined such that we never get into a situation
-# where we disable both kinds of libraries.  Given conflicting
+# in which we disable both kinds of libraries.  Given conflicting
 # choices, we go for a static library, that is the most portable,
 # since we can't tell whether shared libraries were disabled because
 # the user asked for that or because the platform doesn't support
@@ -11154,3 +9657,5 @@ build_old_libs=`case $build_libtool_libs in yes) echo no;; *) echo yes;; esac`
 # mode:shell-script
 # sh-indentation:2
 # End:
+# vi:sw=2
+
diff --git a/m4/libtool.m4 b/m4/libtool.m4
index 10ab284..d7c043f 100644
--- a/m4/libtool.m4
+++ b/m4/libtool.m4
@@ -1,6 +1,8 @@
 # libtool.m4 - Configure libtool for the host system. -*-Autoconf-*-
 #
-#   Copyright (C) 1996-2001, 2003-2015 Free Software Foundation, Inc.
+#   Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005,
+#                 2006, 2007, 2008, 2009, 2010, 2011 Free Software
+#                 Foundation, Inc.
 #   Written by Gordon Matzigkeit, 1996
 #
 # This file is free software; the Free Software Foundation gives
@@ -8,30 +10,36 @@
 # modifications, as long as this notice is preserved.
 
 m4_define([_LT_COPYING], [dnl
-# Copyright (C) 2014 Free Software Foundation, Inc.
-# This is free software; see the source for copying conditions.  There is NO
-# warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-
-# GNU Libtool is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of of the License, or
-# (at your option) any later version.
+#   Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005,
+#                 2006, 2007, 2008, 2009, 2010, 2011 Free Software
+#                 Foundation, Inc.
+#   Written by Gordon Matzigkeit, 1996
+#
+#   This file is part of GNU Libtool.
+#
+# GNU Libtool is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2 of
+# the License, or (at your option) any later version.
 #
-# As a special exception to the GNU General Public License, if you
-# distribute this file as part of a program or library that is built
-# using GNU Libtool, you may include this file under the  same
-# distribution terms that you use for the rest of that program.
+# As a special exception to the GNU General Public License,
+# if you distribute this file as part of a program or library that
+# is built using GNU Libtool, you may include this file under the
+# same distribution terms that you use for the rest of that program.
 #
-# GNU Libtool is distributed in the hope that it will be useful, but
-# WITHOUT ANY WARRANTY; without even the implied warranty of
+# GNU Libtool is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 # GNU General Public License for more details.
 #
 # You should have received a copy of the GNU General Public License
-# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+# along with GNU Libtool; see the file COPYING.  If not, a copy
+# can be downloaded from http://www.gnu.org/licenses/gpl.html, or
+# obtained by writing to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 ])
 
-# serial 58 LT_INIT
+# serial 57 LT_INIT
 
 
 # LT_PREREQ(VERSION)
@@ -59,7 +67,7 @@ esac
 # LT_INIT([OPTIONS])
 # ------------------
 AC_DEFUN([LT_INIT],
-[AC_PREREQ([2.62])dnl We use AC_PATH_PROGS_FEATURE_CHECK
+[AC_PREREQ([2.58])dnl We use AC_INCLUDES_DEFAULT
 AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT])dnl
 AC_BEFORE([$0], [LT_LANG])dnl
 AC_BEFORE([$0], [LT_OUTPUT])dnl
@@ -83,7 +91,7 @@ dnl Parse OPTIONS
 _LT_SET_OPTIONS([$0], [$1])
 
 # This can be used to rebuild libtool when needed
-LIBTOOL_DEPS=$ltmain
+LIBTOOL_DEPS="$ltmain"
 
 # Always use our own libtool.
 LIBTOOL='$(SHELL) $(top_builddir)/libtool'
@@ -103,43 +111,26 @@ dnl AC_DEFUN([AC_PROG_LIBTOOL], [])
 dnl AC_DEFUN([AM_PROG_LIBTOOL], [])
 
 
-# _LT_PREPARE_CC_BASENAME
-# -----------------------
-m4_defun([_LT_PREPARE_CC_BASENAME], [
-# Calculate cc_basename.  Skip known compiler wrappers and cross-prefix.
-func_cc_basename ()
-{
-    for cc_temp in @S|@*""; do
-      case $cc_temp in
-        compile | *[[\\/]]compile | ccache | *[[\\/]]ccache ) ;;
-        distcc | *[[\\/]]distcc | purify | *[[\\/]]purify ) ;;
-        \-*) ;;
-        *) break;;
-      esac
-    done
-    func_cc_basename_result=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"`
-}
-])# _LT_PREPARE_CC_BASENAME
-
-
 # _LT_CC_BASENAME(CC)
 # -------------------
-# It would be clearer to call AC_REQUIREs from _LT_PREPARE_CC_BASENAME,
-# but that macro is also expanded into generated libtool script, which
-# arranges for $SED and $ECHO to be set by different means.
+# Calculate cc_basename.  Skip known compiler wrappers and cross-prefix.
 m4_defun([_LT_CC_BASENAME],
-[m4_require([_LT_PREPARE_CC_BASENAME])dnl
-AC_REQUIRE([_LT_DECL_SED])dnl
-AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH])dnl
-func_cc_basename $1
-cc_basename=$func_cc_basename_result
+[for cc_temp in $1""; do
+  case $cc_temp in
+    compile | *[[\\/]]compile | ccache | *[[\\/]]ccache ) ;;
+    distcc | *[[\\/]]distcc | purify | *[[\\/]]purify ) ;;
+    \-*) ;;
+    *) break;;
+  esac
+done
+cc_basename=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"`
 ])
 
 
 # _LT_FILEUTILS_DEFAULTS
 # ----------------------
 # It is okay to use these file commands and assume they have been set
-# sensibly after 'm4_require([_LT_FILEUTILS_DEFAULTS])'.
+# sensibly after `m4_require([_LT_FILEUTILS_DEFAULTS])'.
 m4_defun([_LT_FILEUTILS_DEFAULTS],
 [: ${CP="cp -f"}
 : ${MV="mv -f"}
@@ -186,16 +177,15 @@ m4_require([_LT_CHECK_SHAREDLIB_FROM_LINKLIB])dnl
 m4_require([_LT_CMD_OLD_ARCHIVE])dnl
 m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl
 m4_require([_LT_WITH_SYSROOT])dnl
-m4_require([_LT_CMD_TRUNCATE])dnl
 
 _LT_CONFIG_LIBTOOL_INIT([
-# See if we are running on zsh, and set the options that allow our
+# See if we are running on zsh, and set the options which allow our
 # commands through without removal of \ escapes INIT.
-if test -n "\${ZSH_VERSION+set}"; then
+if test -n "\${ZSH_VERSION+set}" ; then
    setopt NO_GLOB_SUBST
 fi
 ])
-if test -n "${ZSH_VERSION+set}"; then
+if test -n "${ZSH_VERSION+set}" ; then
    setopt NO_GLOB_SUBST
 fi
 
@@ -208,7 +198,7 @@ aix3*)
   # AIX sometimes has problems with the GCC collect2 program.  For some
   # reason, if we set the COLLECT_NAMES environment variable, the problems
   # vanish in a puff of smoke.
-  if test set != "${COLLECT_NAMES+set}"; then
+  if test "X${COLLECT_NAMES+set}" != Xset; then
     COLLECT_NAMES=
     export COLLECT_NAMES
   fi
@@ -219,14 +209,14 @@ esac
 ofile=libtool
 can_build_shared=yes
 
-# All known linkers require a '.a' archive for static linking (except MSVC,
+# All known linkers require a `.a' archive for static linking (except MSVC,
 # which needs '.lib').
 libext=a
 
-with_gnu_ld=$lt_cv_prog_gnu_ld
+with_gnu_ld="$lt_cv_prog_gnu_ld"
 
-old_CC=$CC
-old_CFLAGS=$CFLAGS
+old_CC="$CC"
+old_CFLAGS="$CFLAGS"
 
 # Set sane defaults for various variables
 test -z "$CC" && CC=cc
@@ -279,14 +269,14 @@ no_glob_subst='s/\*/\\\*/g'
 
 # _LT_PROG_LTMAIN
 # ---------------
-# Note that this code is called both from 'configure', and 'config.status'
+# Note that this code is called both from `configure', and `config.status'
 # now that we use AC_CONFIG_COMMANDS to generate libtool.  Notably,
-# 'config.status' has no value for ac_aux_dir unless we are using Automake,
+# `config.status' has no value for ac_aux_dir unless we are using Automake,
 # so we pass a copy along to make sure it has a sensible value anyway.
 m4_defun([_LT_PROG_LTMAIN],
 [m4_ifdef([AC_REQUIRE_AUX_FILE], [AC_REQUIRE_AUX_FILE([ltmain.sh])])dnl
 _LT_CONFIG_LIBTOOL_INIT([ac_aux_dir='$ac_aux_dir'])
-ltmain=$ac_aux_dir/ltmain.sh
+ltmain="$ac_aux_dir/ltmain.sh"
 ])# _LT_PROG_LTMAIN
 
 
@@ -296,7 +286,7 @@ ltmain=$ac_aux_dir/ltmain.sh
 
 # So that we can recreate a full libtool script including additional
 # tags, we accumulate the chunks of code to send to AC_CONFIG_COMMANDS
-# in macros and then make a single call at the end using the 'libtool'
+# in macros and then make a single call at the end using the `libtool'
 # label.
 
 
@@ -431,8 +421,8 @@ m4_define([_lt_decl_all_varnames],
 
 # _LT_CONFIG_STATUS_DECLARE([VARNAME])
 # ------------------------------------
-# Quote a variable value, and forward it to 'config.status' so that its
-# declaration there will have the same value as in 'configure'.  VARNAME
+# Quote a variable value, and forward it to `config.status' so that its
+# declaration there will have the same value as in `configure'.  VARNAME
 # must have a single quote delimited value for this to work.
 m4_define([_LT_CONFIG_STATUS_DECLARE],
 [$1='`$ECHO "$][$1" | $SED "$delay_single_quote_subst"`'])
@@ -456,7 +446,7 @@ m4_defun([_LT_CONFIG_STATUS_DECLARATIONS],
 # Output comment and list of tags supported by the script
 m4_defun([_LT_LIBTOOL_TAGS],
 [_LT_FORMAT_COMMENT([The names of the tagged configurations supported by this script])dnl
-available_tags='_LT_TAGS'dnl
+available_tags="_LT_TAGS"dnl
 ])
 
 
@@ -484,7 +474,7 @@ m4_ifval([$2], [_$2])[]m4_popdef([_libtool_name])[]dnl
 # _LT_LIBTOOL_CONFIG_VARS
 # -----------------------
 # Produce commented declarations of non-tagged libtool config variables
-# suitable for insertion in the LIBTOOL CONFIG section of the 'libtool'
+# suitable for insertion in the LIBTOOL CONFIG section of the `libtool'
 # script.  Tagged libtool config variables (even for the LIBTOOL CONFIG
 # section) are produced by _LT_LIBTOOL_TAG_VARS.
 m4_defun([_LT_LIBTOOL_CONFIG_VARS],
@@ -510,8 +500,8 @@ m4_define([_LT_TAGVAR], [m4_ifval([$2], [$1_$2], [$1])])
 # Send accumulated output to $CONFIG_STATUS.  Thanks to the lists of
 # variables for single and double quote escaping we saved from calls
 # to _LT_DECL, we can put quote escaped variables declarations
-# into 'config.status', and then the shell code to quote escape them in
-# for loops in 'config.status'.  Finally, any additional code accumulated
+# into `config.status', and then the shell code to quote escape them in
+# for loops in `config.status'.  Finally, any additional code accumulated
 # from calls to _LT_CONFIG_LIBTOOL_INIT is expanded.
 m4_defun([_LT_CONFIG_COMMANDS],
 [AC_PROVIDE_IFELSE([LT_OUTPUT],
@@ -557,7 +547,7 @@ for var in lt_decl_all_varnames([[ \
 ]], lt_decl_quote_varnames); do
     case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in
     *[[\\\\\\\`\\"\\\$]]*)
-      eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$sed_quote_subst\\"\\\`\\\\\\"" ## exclude from sc_prohibit_nested_quotes
+      eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$sed_quote_subst\\"\\\`\\\\\\""
       ;;
     *)
       eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\""
@@ -570,7 +560,7 @@ for var in lt_decl_all_varnames([[ \
 ]], lt_decl_dquote_varnames); do
     case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in
     *[[\\\\\\\`\\"\\\$]]*)
-      eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\"" ## exclude from sc_prohibit_nested_quotes
+      eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\""
       ;;
     *)
       eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\""
@@ -586,7 +576,7 @@ _LT_OUTPUT_LIBTOOL_INIT
 # Generate a child script FILE with all initialization necessary to
 # reuse the environment learned by the parent script, and make the
 # file executable.  If COMMENT is supplied, it is inserted after the
-# '#!' sequence but before initialization text begins.  After this
+# `#!' sequence but before initialization text begins.  After this
 # macro, additional text can be appended to FILE to form the body of
 # the child script.  The macro ends with non-zero status if the
 # file could not be fully written (such as if the disk is full).
@@ -608,7 +598,7 @@ AS_SHELL_SANITIZE
 _AS_PREPARE
 exec AS_MESSAGE_FD>&1
 _ASEOF
-test 0 = "$lt_write_fail" && chmod +x $1[]dnl
+test $lt_write_fail = 0 && chmod +x $1[]dnl
 m4_popdef([AS_MESSAGE_LOG_FD])])])# _LT_GENERATED_FILE_INIT
 
 # LT_OUTPUT
@@ -631,7 +621,7 @@ exec AS_MESSAGE_LOG_FD>>config.log
 } >&AS_MESSAGE_LOG_FD
 
 lt_cl_help="\
-'$as_me' creates a local libtool stub from the current configuration,
+\`$as_me' creates a local libtool stub from the current configuration,
 for use in further configure time tests before the real libtool is
 generated.
 
@@ -653,7 +643,7 @@ Copyright (C) 2011 Free Software Foundation, Inc.
 This config.lt script is free software; the Free Software Foundation
 gives unlimited permision to copy, distribute and modify it."
 
-while test 0 != $[#]
+while test $[#] != 0
 do
   case $[1] in
     --version | --v* | -V )
@@ -666,10 +656,10 @@ do
       lt_cl_silent=: ;;
 
     -*) AC_MSG_ERROR([unrecognized option: $[1]
-Try '$[0] --help' for more information.]) ;;
+Try \`$[0] --help' for more information.]) ;;
 
     *) AC_MSG_ERROR([unrecognized argument: $[1]
-Try '$[0] --help' for more information.]) ;;
+Try \`$[0] --help' for more information.]) ;;
   esac
   shift
 done
@@ -695,7 +685,7 @@ chmod +x "$CONFIG_LT"
 # open by configure.  Here we exec the FD to /dev/null, effectively closing
 # config.log, so it can be properly (re)opened and appended to by config.lt.
 lt_cl_success=:
-test yes = "$silent" &&
+test "$silent" = yes &&
   lt_config_lt_args="$lt_config_lt_args --quiet"
 exec AS_MESSAGE_LOG_FD>/dev/null
 $SHELL "$CONFIG_LT" $lt_config_lt_args || lt_cl_success=false
@@ -715,31 +705,27 @@ m4_defun([_LT_CONFIG],
 _LT_CONFIG_SAVE_COMMANDS([
   m4_define([_LT_TAG], m4_if([$1], [], [C], [$1]))dnl
   m4_if(_LT_TAG, [C], [
-    # See if we are running on zsh, and set the options that allow our
+    # See if we are running on zsh, and set the options which allow our
     # commands through without removal of \ escapes.
-    if test -n "${ZSH_VERSION+set}"; then
+    if test -n "${ZSH_VERSION+set}" ; then
       setopt NO_GLOB_SUBST
     fi
 
-    cfgfile=${ofile}T
+    cfgfile="${ofile}T"
     trap "$RM \"$cfgfile\"; exit 1" 1 2 15
     $RM "$cfgfile"
 
     cat <<_LT_EOF >> "$cfgfile"
 #! $SHELL
-# Generated automatically by $as_me ($PACKAGE) $VERSION
+
+# `$ECHO "$ofile" | sed 's%^.*/%%'` - Provide generalized library-building support services.
+# Generated automatically by $as_me ($PACKAGE$TIMESTAMP) $VERSION
 # Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
 # NOTE: Changes made to this file will be lost: look at ltmain.sh.
-
-# Provide generalized library-building support services.
-# Written by Gordon Matzigkeit, 1996
-
+#
 _LT_COPYING
 _LT_LIBTOOL_TAGS
 
-# Configured defaults for sys_lib_dlsearch_path munging.
-: \${LT_SYS_LIBRARY_PATH="$configure_time_lt_sys_library_path"}
-
 # ### BEGIN LIBTOOL CONFIG
 _LT_LIBTOOL_CONFIG_VARS
 _LT_LIBTOOL_TAG_VARS
@@ -747,24 +733,13 @@ _LT_LIBTOOL_TAG_VARS
 
 _LT_EOF
 
-    cat <<'_LT_EOF' >> "$cfgfile"
-
-# ### BEGIN FUNCTIONS SHARED WITH CONFIGURE
-
-_LT_PREPARE_MUNGE_PATH_LIST
-_LT_PREPARE_CC_BASENAME
-
-# ### END FUNCTIONS SHARED WITH CONFIGURE
-
-_LT_EOF
-
   case $host_os in
   aix3*)
     cat <<\_LT_EOF >> "$cfgfile"
 # AIX sometimes has problems with the GCC collect2 program.  For some
 # reason, if we set the COLLECT_NAMES environment variable, the problems
 # vanish in a puff of smoke.
-if test set != "${COLLECT_NAMES+set}"; then
+if test "X${COLLECT_NAMES+set}" != Xset; then
   COLLECT_NAMES=
   export COLLECT_NAMES
 fi
@@ -781,6 +756,8 @@ _LT_EOF
   sed '$q' "$ltmain" >> "$cfgfile" \
      || (rm -f "$cfgfile"; exit 1)
 
+  _LT_PROG_REPLACE_SHELLFNS
+
    mv -f "$cfgfile" "$ofile" ||
     (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile")
   chmod +x "$ofile"
@@ -798,6 +775,7 @@ _LT_EOF
 [m4_if([$1], [], [
     PACKAGE='$PACKAGE'
     VERSION='$VERSION'
+    TIMESTAMP='$TIMESTAMP'
     RM='$RM'
     ofile='$ofile'], [])
 ])dnl /_LT_CONFIG_SAVE_COMMANDS
@@ -996,7 +974,7 @@ m4_defun_once([_LT_REQUIRED_DARWIN_CHECKS],[
 
     AC_CACHE_CHECK([for -single_module linker flag],[lt_cv_apple_cc_single_mod],
       [lt_cv_apple_cc_single_mod=no
-      if test -z "$LT_MULTI_MODULE"; then
+      if test -z "${LT_MULTI_MODULE}"; then
 	# By default we will add the -single_module flag. You can override
 	# by either setting the environment variable LT_MULTI_MODULE
 	# non-empty at configure time, or by adding -multi_module to the
@@ -1014,7 +992,7 @@ m4_defun_once([_LT_REQUIRED_DARWIN_CHECKS],[
 	  cat conftest.err >&AS_MESSAGE_LOG_FD
 	# Otherwise, if the output was created with a 0 exit code from
 	# the compiler, it worked.
-	elif test -f libconftest.dylib && test 0 = "$_lt_result"; then
+	elif test -f libconftest.dylib && test $_lt_result -eq 0; then
 	  lt_cv_apple_cc_single_mod=yes
 	else
 	  cat conftest.err >&AS_MESSAGE_LOG_FD
@@ -1032,7 +1010,7 @@ m4_defun_once([_LT_REQUIRED_DARWIN_CHECKS],[
       AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])],
 	[lt_cv_ld_exported_symbols_list=yes],
 	[lt_cv_ld_exported_symbols_list=no])
-	LDFLAGS=$save_LDFLAGS
+	LDFLAGS="$save_LDFLAGS"
     ])
 
     AC_CACHE_CHECK([for -force_load linker flag],[lt_cv_ld_force_load],
@@ -1054,7 +1032,7 @@ _LT_EOF
       _lt_result=$?
       if test -s conftest.err && $GREP force_load conftest.err; then
 	cat conftest.err >&AS_MESSAGE_LOG_FD
-      elif test -f conftest && test 0 = "$_lt_result" && $GREP forced_load conftest >/dev/null 2>&1; then
+      elif test -f conftest && test $_lt_result -eq 0 && $GREP forced_load conftest >/dev/null 2>&1 ; then
 	lt_cv_ld_force_load=yes
       else
 	cat conftest.err >&AS_MESSAGE_LOG_FD
@@ -1064,32 +1042,32 @@ _LT_EOF
     ])
     case $host_os in
     rhapsody* | darwin1.[[012]])
-      _lt_dar_allow_undefined='$wl-undefined ${wl}suppress' ;;
+      _lt_dar_allow_undefined='${wl}-undefined ${wl}suppress' ;;
     darwin1.*)
-      _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;;
+      _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;;
     darwin*) # darwin 5.x on
       # if running on 10.5 or later, the deployment target defaults
       # to the OS version, if on x86, and 10.4, the deployment
       # target defaults to 10.4. Don't you love it?
       case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in
 	10.0,*86*-darwin8*|10.0,*-darwin[[91]]*)
-	  _lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' ;;
-	10.[[012]][[,.]]*)
-	  _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;;
+	  _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;;
+	10.[[012]]*)
+	  _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;;
 	10.*)
-	  _lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' ;;
+	  _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;;
       esac
     ;;
   esac
-    if test yes = "$lt_cv_apple_cc_single_mod"; then
+    if test "$lt_cv_apple_cc_single_mod" = "yes"; then
       _lt_dar_single_mod='$single_module'
     fi
-    if test yes = "$lt_cv_ld_exported_symbols_list"; then
-      _lt_dar_export_syms=' $wl-exported_symbols_list,$output_objdir/$libname-symbols.expsym'
+    if test "$lt_cv_ld_exported_symbols_list" = "yes"; then
+      _lt_dar_export_syms=' ${wl}-exported_symbols_list,$output_objdir/${libname}-symbols.expsym'
     else
-      _lt_dar_export_syms='~$NMEDIT -s $output_objdir/$libname-symbols.expsym $lib'
+      _lt_dar_export_syms='~$NMEDIT -s $output_objdir/${libname}-symbols.expsym ${lib}'
     fi
-    if test : != "$DSYMUTIL" && test no = "$lt_cv_ld_force_load"; then
+    if test "$DSYMUTIL" != ":" && test "$lt_cv_ld_force_load" = "no"; then
       _lt_dsymutil='~$DSYMUTIL $lib || :'
     else
       _lt_dsymutil=
@@ -1109,29 +1087,29 @@ m4_defun([_LT_DARWIN_LINKER_FEATURES],
   _LT_TAGVAR(hardcode_direct, $1)=no
   _LT_TAGVAR(hardcode_automatic, $1)=yes
   _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported
-  if test yes = "$lt_cv_ld_force_load"; then
-    _LT_TAGVAR(whole_archive_flag_spec, $1)='`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience $wl-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`'
+  if test "$lt_cv_ld_force_load" = "yes"; then
+    _LT_TAGVAR(whole_archive_flag_spec, $1)='`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience ${wl}-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`'
     m4_case([$1], [F77], [_LT_TAGVAR(compiler_needs_object, $1)=yes],
                   [FC],  [_LT_TAGVAR(compiler_needs_object, $1)=yes])
   else
     _LT_TAGVAR(whole_archive_flag_spec, $1)=''
   fi
   _LT_TAGVAR(link_all_deplibs, $1)=yes
-  _LT_TAGVAR(allow_undefined_flag, $1)=$_lt_dar_allow_undefined
+  _LT_TAGVAR(allow_undefined_flag, $1)="$_lt_dar_allow_undefined"
   case $cc_basename in
-     ifort*|nagfor*) _lt_dar_can_shared=yes ;;
+     ifort*) _lt_dar_can_shared=yes ;;
      *) _lt_dar_can_shared=$GCC ;;
   esac
-  if test yes = "$_lt_dar_can_shared"; then
+  if test "$_lt_dar_can_shared" = "yes"; then
     output_verbose_link_cmd=func_echo_all
-    _LT_TAGVAR(archive_cmds, $1)="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dsymutil"
-    _LT_TAGVAR(module_cmds, $1)="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dsymutil"
-    _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dar_export_syms$_lt_dsymutil"
-    _LT_TAGVAR(module_expsym_cmds, $1)="sed -e 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dar_export_syms$_lt_dsymutil"
+    _LT_TAGVAR(archive_cmds, $1)="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}"
+    _LT_TAGVAR(module_cmds, $1)="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}"
+    _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}"
+    _LT_TAGVAR(module_expsym_cmds, $1)="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}"
     m4_if([$1], [CXX],
-[   if test yes != "$lt_cv_apple_cc_single_mod"; then
-      _LT_TAGVAR(archive_cmds, $1)="\$CC -r -keep_private_externs -nostdlib -o \$lib-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$lib-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring$_lt_dsymutil"
-      _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \$lib-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$lib-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring$_lt_dar_export_syms$_lt_dsymutil"
+[   if test "$lt_cv_apple_cc_single_mod" != "yes"; then
+      _LT_TAGVAR(archive_cmds, $1)="\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dsymutil}"
+      _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dar_export_syms}${_lt_dsymutil}"
     fi
 ],[])
   else
@@ -1151,7 +1129,7 @@ m4_defun([_LT_DARWIN_LINKER_FEATURES],
 # Allow to override them for all tags through lt_cv_aix_libpath.
 m4_defun([_LT_SYS_MODULE_PATH_AIX],
 [m4_require([_LT_DECL_SED])dnl
-if test set = "${lt_cv_aix_libpath+set}"; then
+if test "${lt_cv_aix_libpath+set}" = set; then
   aix_libpath=$lt_cv_aix_libpath
 else
   AC_CACHE_VAL([_LT_TAGVAR([lt_cv_aix_libpath_], [$1])],
@@ -1169,7 +1147,7 @@ else
     _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
   fi],[])
   if test -z "$_LT_TAGVAR([lt_cv_aix_libpath_], [$1])"; then
-    _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=/usr/lib:/lib
+    _LT_TAGVAR([lt_cv_aix_libpath_], [$1])="/usr/lib:/lib"
   fi
   ])
   aix_libpath=$_LT_TAGVAR([lt_cv_aix_libpath_], [$1])
@@ -1189,8 +1167,8 @@ m4_define([_LT_SHELL_INIT],
 # -----------------------
 # Find how we can fake an echo command that does not interpret backslash.
 # In particular, with Autoconf 2.60 or later we add some code to the start
-# of the generated configure script that will find a shell with a builtin
-# printf (that we can use as an echo command).
+# of the generated configure script which will find a shell with a builtin
+# printf (which we can use as an echo command).
 m4_defun([_LT_PROG_ECHO_BACKSLASH],
 [ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
 ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO
@@ -1218,10 +1196,10 @@ fi
 # Invoke $ECHO with all args, space-separated.
 func_echo_all ()
 {
-    $ECHO "$*"
+    $ECHO "$*" 
 }
 
-case $ECHO in
+case "$ECHO" in
   printf*) AC_MSG_RESULT([printf]) ;;
   print*) AC_MSG_RESULT([print -r]) ;;
   *) AC_MSG_RESULT([cat]) ;;
@@ -1247,17 +1225,16 @@ _LT_DECL([], [ECHO], [1], [An echo program that protects backslashes])
 AC_DEFUN([_LT_WITH_SYSROOT],
 [AC_MSG_CHECKING([for sysroot])
 AC_ARG_WITH([sysroot],
-[AS_HELP_STRING([--with-sysroot@<:@=DIR@:>@],
-  [Search for dependent libraries within DIR (or the compiler's sysroot
-   if not specified).])],
+[  --with-sysroot[=DIR] Search for dependent libraries within DIR
+                        (or the compiler's sysroot if not specified).],
 [], [with_sysroot=no])
 
 dnl lt_sysroot will always be passed unquoted.  We quote it here
 dnl in case the user passed a directory name.
 lt_sysroot=
-case $with_sysroot in #(
+case ${with_sysroot} in #(
  yes)
-   if test yes = "$GCC"; then
+   if test "$GCC" = yes; then
      lt_sysroot=`$CC --print-sysroot 2>/dev/null`
    fi
    ;; #(
@@ -1267,14 +1244,14 @@ case $with_sysroot in #(
  no|'')
    ;; #(
  *)
-   AC_MSG_RESULT([$with_sysroot])
+   AC_MSG_RESULT([${with_sysroot}])
    AC_MSG_ERROR([The sysroot must be an absolute path.])
    ;;
 esac
 
  AC_MSG_RESULT([${lt_sysroot:-no}])
 _LT_DECL([], [lt_sysroot], [0], [The root where to search for ]dnl
-[dependent libraries, and where our libraries should be installed.])])
+[dependent libraries, and in which our libraries should be installed.])])
 
 # _LT_ENABLE_LOCK
 # ---------------
@@ -1282,33 +1259,31 @@ m4_defun([_LT_ENABLE_LOCK],
 [AC_ARG_ENABLE([libtool-lock],
   [AS_HELP_STRING([--disable-libtool-lock],
     [avoid locking (might break parallel builds)])])
-test no = "$enable_libtool_lock" || enable_libtool_lock=yes
+test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes
 
 # Some flags need to be propagated to the compiler or linker for good
 # libtool support.
 case $host in
 ia64-*-hpux*)
-  # Find out what ABI is being produced by ac_compile, and set mode
-  # options accordingly.
+  # Find out which ABI we are using.
   echo 'int i;' > conftest.$ac_ext
   if AC_TRY_EVAL(ac_compile); then
     case `/usr/bin/file conftest.$ac_objext` in
       *ELF-32*)
-	HPUX_IA64_MODE=32
+	HPUX_IA64_MODE="32"
 	;;
       *ELF-64*)
-	HPUX_IA64_MODE=64
+	HPUX_IA64_MODE="64"
 	;;
     esac
   fi
   rm -rf conftest*
   ;;
 *-*-irix6*)
-  # Find out what ABI is being produced by ac_compile, and set linker
-  # options accordingly.
+  # Find out which ABI we are using.
   echo '[#]line '$LINENO' "configure"' > conftest.$ac_ext
   if AC_TRY_EVAL(ac_compile); then
-    if test yes = "$lt_cv_prog_gnu_ld"; then
+    if test "$lt_cv_prog_gnu_ld" = yes; then
       case `/usr/bin/file conftest.$ac_objext` in
 	*32-bit*)
 	  LD="${LD-ld} -melf32bsmip"
@@ -1337,46 +1312,9 @@ ia64-*-hpux*)
   rm -rf conftest*
   ;;
 
-mips64*-*linux*)
-  # Find out what ABI is being produced by ac_compile, and set linker
-  # options accordingly.
-  echo '[#]line '$LINENO' "configure"' > conftest.$ac_ext
-  if AC_TRY_EVAL(ac_compile); then
-    emul=elf
-    case `/usr/bin/file conftest.$ac_objext` in
-      *32-bit*)
-	emul="${emul}32"
-	;;
-      *64-bit*)
-	emul="${emul}64"
-	;;
-    esac
-    case `/usr/bin/file conftest.$ac_objext` in
-      *MSB*)
-	emul="${emul}btsmip"
-	;;
-      *LSB*)
-	emul="${emul}ltsmip"
-	;;
-    esac
-    case `/usr/bin/file conftest.$ac_objext` in
-      *N32*)
-	emul="${emul}n32"
-	;;
-    esac
-    LD="${LD-ld} -m $emul"
-  fi
-  rm -rf conftest*
-  ;;
-
 x86_64-*kfreebsd*-gnu|x86_64-*linux*|powerpc*-*linux*| \
 s390*-*linux*|s390*-*tpf*|sparc*-*linux*)
-  # Find out what ABI is being produced by ac_compile, and set linker
-  # options accordingly.  Note that the listed cases only cover the
-  # situations where additional linker options are needed (such as when
-  # doing 32-bit compilation for a host where ld defaults to 64-bit, or
-  # vice versa); the common cases where no linker options are needed do
-  # not appear in the list.
+  # Find out which ABI we are using.
   echo 'int i;' > conftest.$ac_ext
   if AC_TRY_EVAL(ac_compile); then
     case `/usr/bin/file conftest.o` in
@@ -1395,10 +1333,10 @@ s390*-*linux*|s390*-*tpf*|sparc*-*linux*)
 		;;
 	    esac
 	    ;;
-	  powerpc64le-*linux*)
+	  powerpc64le-*)
 	    LD="${LD-ld} -m elf32lppclinux"
 	    ;;
-	  powerpc64-*linux*)
+	  powerpc64-*)
 	    LD="${LD-ld} -m elf32ppclinux"
 	    ;;
 	  s390x-*linux*)
@@ -1417,10 +1355,10 @@ s390*-*linux*|s390*-*tpf*|sparc*-*linux*)
 	  x86_64-*linux*)
 	    LD="${LD-ld} -m elf_x86_64"
 	    ;;
-	  powerpcle-*linux*)
+	  powerpcle-*)
 	    LD="${LD-ld} -m elf64lppc"
 	    ;;
-	  powerpc-*linux*)
+	  powerpc-*)
 	    LD="${LD-ld} -m elf64ppc"
 	    ;;
 	  s390*-*linux*|s390*-*tpf*)
@@ -1438,20 +1376,19 @@ s390*-*linux*|s390*-*tpf*|sparc*-*linux*)
 
 *-*-sco3.2v5*)
   # On SCO OpenServer 5, we need -belf to get full-featured binaries.
-  SAVE_CFLAGS=$CFLAGS
+  SAVE_CFLAGS="$CFLAGS"
   CFLAGS="$CFLAGS -belf"
   AC_CACHE_CHECK([whether the C compiler needs -belf], lt_cv_cc_needs_belf,
     [AC_LANG_PUSH(C)
      AC_LINK_IFELSE([AC_LANG_PROGRAM([[]],[[]])],[lt_cv_cc_needs_belf=yes],[lt_cv_cc_needs_belf=no])
      AC_LANG_POP])
-  if test yes != "$lt_cv_cc_needs_belf"; then
+  if test x"$lt_cv_cc_needs_belf" != x"yes"; then
     # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf
-    CFLAGS=$SAVE_CFLAGS
+    CFLAGS="$SAVE_CFLAGS"
   fi
   ;;
 *-*solaris*)
-  # Find out what ABI is being produced by ac_compile, and set linker
-  # options accordingly.
+  # Find out which ABI we are using.
   echo 'int i;' > conftest.$ac_ext
   if AC_TRY_EVAL(ac_compile); then
     case `/usr/bin/file conftest.o` in
@@ -1459,7 +1396,7 @@ s390*-*linux*|s390*-*tpf*|sparc*-*linux*)
       case $lt_cv_prog_gnu_ld in
       yes*)
         case $host in
-        i?86-*-solaris*|x86_64-*-solaris*)
+        i?86-*-solaris*)
           LD="${LD-ld} -m elf_x86_64"
           ;;
         sparc*-*-solaris*)
@@ -1468,7 +1405,7 @@ s390*-*linux*|s390*-*tpf*|sparc*-*linux*)
         esac
         # GNU ld 2.21 introduced _sol2 emulations.  Use them if available.
         if ${LD-ld} -V | grep _sol2 >/dev/null 2>&1; then
-          LD=${LD-ld}_sol2
+          LD="${LD-ld}_sol2"
         fi
         ;;
       *)
@@ -1484,7 +1421,7 @@ s390*-*linux*|s390*-*tpf*|sparc*-*linux*)
   ;;
 esac
 
-need_locks=$enable_libtool_lock
+need_locks="$enable_libtool_lock"
 ])# _LT_ENABLE_LOCK
 
 
@@ -1503,11 +1440,11 @@ AC_CACHE_CHECK([for archiver @FILE support], [lt_cv_ar_at_file],
      [echo conftest.$ac_objext > conftest.lst
       lt_ar_try='$AR $AR_FLAGS libconftest.a @conftest.lst >&AS_MESSAGE_LOG_FD'
       AC_TRY_EVAL([lt_ar_try])
-      if test 0 -eq "$ac_status"; then
+      if test "$ac_status" -eq 0; then
 	# Ensure the archiver fails upon bogus file names.
 	rm -f conftest.$ac_objext libconftest.a
 	AC_TRY_EVAL([lt_ar_try])
-	if test 0 -ne "$ac_status"; then
+	if test "$ac_status" -ne 0; then
           lt_cv_ar_at_file=@
         fi
       fi
@@ -1515,7 +1452,7 @@ AC_CACHE_CHECK([for archiver @FILE support], [lt_cv_ar_at_file],
      ])
   ])
 
-if test no = "$lt_cv_ar_at_file"; then
+if test "x$lt_cv_ar_at_file" = xno; then
   archiver_list_spec=
 else
   archiver_list_spec=$lt_cv_ar_at_file
@@ -1546,7 +1483,7 @@ old_postuninstall_cmds=
 
 if test -n "$RANLIB"; then
   case $host_os in
-  bitrig* | openbsd*)
+  openbsd*)
     old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$tool_oldlib"
     ;;
   *)
@@ -1582,7 +1519,7 @@ AC_CACHE_CHECK([$1], [$2],
   [$2=no
    m4_if([$4], , [ac_outfile=conftest.$ac_objext], [ac_outfile=$4])
    echo "$lt_simple_compile_test_code" > conftest.$ac_ext
-   lt_compiler_flag="$3"  ## exclude from sc_useless_quotes_in_assignment
+   lt_compiler_flag="$3"
    # Insert the option either (1) after the last *FLAGS variable, or
    # (2) before a word containing "conftest.", or (3) at the end.
    # Note that $ac_compile itself does not contain backslashes and begins
@@ -1609,7 +1546,7 @@ AC_CACHE_CHECK([$1], [$2],
    $RM conftest*
 ])
 
-if test yes = "[$]$2"; then
+if test x"[$]$2" = xyes; then
     m4_if([$5], , :, [$5])
 else
     m4_if([$6], , :, [$6])
@@ -1631,7 +1568,7 @@ AC_DEFUN([_LT_LINKER_OPTION],
 m4_require([_LT_DECL_SED])dnl
 AC_CACHE_CHECK([$1], [$2],
   [$2=no
-   save_LDFLAGS=$LDFLAGS
+   save_LDFLAGS="$LDFLAGS"
    LDFLAGS="$LDFLAGS $3"
    echo "$lt_simple_link_test_code" > conftest.$ac_ext
    if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then
@@ -1650,10 +1587,10 @@ AC_CACHE_CHECK([$1], [$2],
      fi
    fi
    $RM -r conftest*
-   LDFLAGS=$save_LDFLAGS
+   LDFLAGS="$save_LDFLAGS"
 ])
 
-if test yes = "[$]$2"; then
+if test x"[$]$2" = xyes; then
     m4_if([$4], , :, [$4])
 else
     m4_if([$5], , :, [$5])
@@ -1674,7 +1611,7 @@ AC_DEFUN([LT_CMD_MAX_LEN],
 AC_MSG_CHECKING([the maximum length of command line arguments])
 AC_CACHE_VAL([lt_cv_sys_max_cmd_len], [dnl
   i=0
-  teststring=ABCD
+  teststring="ABCD"
 
   case $build_os in
   msdosdjgpp*)
@@ -1714,7 +1651,7 @@ AC_CACHE_VAL([lt_cv_sys_max_cmd_len], [dnl
     lt_cv_sys_max_cmd_len=8192;
     ;;
 
-  bitrig* | darwin* | dragonfly* | freebsd* | netbsd* | openbsd*)
+  netbsd* | freebsd* | openbsd* | darwin* | dragonfly*)
     # This has been around since 386BSD, at least.  Likely further.
     if test -x /sbin/sysctl; then
       lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax`
@@ -1765,22 +1702,22 @@ AC_CACHE_VAL([lt_cv_sys_max_cmd_len], [dnl
   *)
     lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null`
     if test -n "$lt_cv_sys_max_cmd_len" && \
-       test undefined != "$lt_cv_sys_max_cmd_len"; then
+	test undefined != "$lt_cv_sys_max_cmd_len"; then
       lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4`
       lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3`
     else
       # Make teststring a little bigger before we do anything with it.
       # a 1K string should be a reasonable start.
-      for i in 1 2 3 4 5 6 7 8; do
+      for i in 1 2 3 4 5 6 7 8 ; do
         teststring=$teststring$teststring
       done
       SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}}
       # If test is not a shell built-in, we'll probably end up computing a
       # maximum length that is only half of the actual maximum length, but
       # we can't tell.
-      while { test X`env echo "$teststring$teststring" 2>/dev/null` \
+      while { test "X"`env echo "$teststring$teststring" 2>/dev/null` \
 	         = "X$teststring$teststring"; } >/dev/null 2>&1 &&
-	      test 17 != "$i" # 1/2 MB should be enough
+	      test $i != 17 # 1/2 MB should be enough
       do
         i=`expr $i + 1`
         teststring=$teststring$teststring
@@ -1796,7 +1733,7 @@ AC_CACHE_VAL([lt_cv_sys_max_cmd_len], [dnl
     ;;
   esac
 ])
-if test -n "$lt_cv_sys_max_cmd_len"; then
+if test -n $lt_cv_sys_max_cmd_len ; then
   AC_MSG_RESULT($lt_cv_sys_max_cmd_len)
 else
   AC_MSG_RESULT(none)
@@ -1824,7 +1761,7 @@ m4_defun([_LT_HEADER_DLFCN],
 # ----------------------------------------------------------------
 m4_defun([_LT_TRY_DLOPEN_SELF],
 [m4_require([_LT_HEADER_DLFCN])dnl
-if test yes = "$cross_compiling"; then :
+if test "$cross_compiling" = yes; then :
   [$4]
 else
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
@@ -1871,9 +1808,9 @@ else
 #  endif
 #endif
 
-/* When -fvisibility=hidden is used, assume the code has been annotated
+/* When -fvisbility=hidden is used, assume the code has been annotated
    correspondingly for the symbols needed.  */
-#if defined __GNUC__ && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3))
+#if defined(__GNUC__) && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3))
 int fnord () __attribute__((visibility("default")));
 #endif
 
@@ -1899,7 +1836,7 @@ int main ()
   return status;
 }]
 _LT_EOF
-  if AC_TRY_EVAL(ac_link) && test -s "conftest$ac_exeext" 2>/dev/null; then
+  if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext} 2>/dev/null; then
     (./conftest; exit; ) >&AS_MESSAGE_LOG_FD 2>/dev/null
     lt_status=$?
     case x$lt_status in
@@ -1920,7 +1857,7 @@ rm -fr conftest*
 # ------------------
 AC_DEFUN([LT_SYS_DLOPEN_SELF],
 [m4_require([_LT_HEADER_DLFCN])dnl
-if test yes != "$enable_dlopen"; then
+if test "x$enable_dlopen" != xyes; then
   enable_dlopen=unknown
   enable_dlopen_self=unknown
   enable_dlopen_self_static=unknown
@@ -1930,52 +1867,44 @@ else
 
   case $host_os in
   beos*)
-    lt_cv_dlopen=load_add_on
+    lt_cv_dlopen="load_add_on"
     lt_cv_dlopen_libs=
     lt_cv_dlopen_self=yes
     ;;
 
   mingw* | pw32* | cegcc*)
-    lt_cv_dlopen=LoadLibrary
+    lt_cv_dlopen="LoadLibrary"
     lt_cv_dlopen_libs=
     ;;
 
   cygwin*)
-    lt_cv_dlopen=dlopen
+    lt_cv_dlopen="dlopen"
     lt_cv_dlopen_libs=
     ;;
 
   darwin*)
-    # if libdl is installed we need to link against it
+  # if libdl is installed we need to link against it
     AC_CHECK_LIB([dl], [dlopen],
-		[lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-ldl],[
-    lt_cv_dlopen=dyld
+		[lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"],[
+    lt_cv_dlopen="dyld"
     lt_cv_dlopen_libs=
     lt_cv_dlopen_self=yes
     ])
     ;;
 
-  tpf*)
-    # Don't try to run any link tests for TPF.  We know it's impossible
-    # because TPF is a cross-compiler, and we know how we open DSOs.
-    lt_cv_dlopen=dlopen
-    lt_cv_dlopen_libs=
-    lt_cv_dlopen_self=no
-    ;;
-
   *)
     AC_CHECK_FUNC([shl_load],
-	  [lt_cv_dlopen=shl_load],
+	  [lt_cv_dlopen="shl_load"],
       [AC_CHECK_LIB([dld], [shl_load],
-	    [lt_cv_dlopen=shl_load lt_cv_dlopen_libs=-ldld],
+	    [lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-ldld"],
 	[AC_CHECK_FUNC([dlopen],
-	      [lt_cv_dlopen=dlopen],
+	      [lt_cv_dlopen="dlopen"],
 	  [AC_CHECK_LIB([dl], [dlopen],
-		[lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-ldl],
+		[lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"],
 	    [AC_CHECK_LIB([svld], [dlopen],
-		  [lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-lsvld],
+		  [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld"],
 	      [AC_CHECK_LIB([dld], [dld_link],
-		    [lt_cv_dlopen=dld_link lt_cv_dlopen_libs=-ldld])
+		    [lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-ldld"])
 	      ])
 	    ])
 	  ])
@@ -1984,21 +1913,21 @@ else
     ;;
   esac
 
-  if test no = "$lt_cv_dlopen"; then
-    enable_dlopen=no
-  else
+  if test "x$lt_cv_dlopen" != xno; then
     enable_dlopen=yes
+  else
+    enable_dlopen=no
   fi
 
   case $lt_cv_dlopen in
   dlopen)
-    save_CPPFLAGS=$CPPFLAGS
-    test yes = "$ac_cv_header_dlfcn_h" && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H"
+    save_CPPFLAGS="$CPPFLAGS"
+    test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H"
 
-    save_LDFLAGS=$LDFLAGS
+    save_LDFLAGS="$LDFLAGS"
     wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\"
 
-    save_LIBS=$LIBS
+    save_LIBS="$LIBS"
     LIBS="$lt_cv_dlopen_libs $LIBS"
 
     AC_CACHE_CHECK([whether a program can dlopen itself],
@@ -2008,7 +1937,7 @@ else
 	    lt_cv_dlopen_self=no, lt_cv_dlopen_self=cross)
     ])
 
-    if test yes = "$lt_cv_dlopen_self"; then
+    if test "x$lt_cv_dlopen_self" = xyes; then
       wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\"
       AC_CACHE_CHECK([whether a statically linked program can dlopen itself],
 	  lt_cv_dlopen_self_static, [dnl
@@ -2018,9 +1947,9 @@ else
       ])
     fi
 
-    CPPFLAGS=$save_CPPFLAGS
-    LDFLAGS=$save_LDFLAGS
-    LIBS=$save_LIBS
+    CPPFLAGS="$save_CPPFLAGS"
+    LDFLAGS="$save_LDFLAGS"
+    LIBS="$save_LIBS"
     ;;
   esac
 
@@ -2112,8 +2041,8 @@ m4_defun([_LT_COMPILER_FILE_LOCKS],
 m4_require([_LT_FILEUTILS_DEFAULTS])dnl
 _LT_COMPILER_C_O([$1])
 
-hard_links=nottested
-if test no = "$_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)" && test no != "$need_locks"; then
+hard_links="nottested"
+if test "$_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)" = no && test "$need_locks" != no; then
   # do not overwrite the value of need_locks provided by the user
   AC_MSG_CHECKING([if we can lock with hard links])
   hard_links=yes
@@ -2123,8 +2052,8 @@ if test no = "$_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)" && test no != "$need_loc
   ln conftest.a conftest.b 2>&5 || hard_links=no
   ln conftest.a conftest.b 2>/dev/null && hard_links=no
   AC_MSG_RESULT([$hard_links])
-  if test no = "$hard_links"; then
-    AC_MSG_WARN(['$CC' does not support '-c -o', so 'make -j' may be unsafe])
+  if test "$hard_links" = no; then
+    AC_MSG_WARN([`$CC' does not support `-c -o', so `make -j' may be unsafe])
     need_locks=warn
   fi
 else
@@ -2151,8 +2080,8 @@ objdir=$lt_cv_objdir
 _LT_DECL([], [objdir], [0],
          [The name of the directory that contains temporary libtool files])dnl
 m4_pattern_allow([LT_OBJDIR])dnl
-AC_DEFINE_UNQUOTED([LT_OBJDIR], "$lt_cv_objdir/",
-  [Define to the sub-directory where libtool stores uninstalled libraries.])
+AC_DEFINE_UNQUOTED(LT_OBJDIR, "$lt_cv_objdir/",
+  [Define to the sub-directory in which libtool stores uninstalled libraries.])
 ])# _LT_CHECK_OBJDIR
 
 
@@ -2164,15 +2093,15 @@ m4_defun([_LT_LINKER_HARDCODE_LIBPATH],
 _LT_TAGVAR(hardcode_action, $1)=
 if test -n "$_LT_TAGVAR(hardcode_libdir_flag_spec, $1)" ||
    test -n "$_LT_TAGVAR(runpath_var, $1)" ||
-   test yes = "$_LT_TAGVAR(hardcode_automatic, $1)"; then
+   test "X$_LT_TAGVAR(hardcode_automatic, $1)" = "Xyes" ; then
 
   # We can hardcode non-existent directories.
-  if test no != "$_LT_TAGVAR(hardcode_direct, $1)" &&
+  if test "$_LT_TAGVAR(hardcode_direct, $1)" != no &&
      # If the only mechanism to avoid hardcoding is shlibpath_var, we
      # have to relink, otherwise we might link with an installed library
      # when we should be linking with a yet-to-be-installed one
-     ## test no != "$_LT_TAGVAR(hardcode_shlibpath_var, $1)" &&
-     test no != "$_LT_TAGVAR(hardcode_minus_L, $1)"; then
+     ## test "$_LT_TAGVAR(hardcode_shlibpath_var, $1)" != no &&
+     test "$_LT_TAGVAR(hardcode_minus_L, $1)" != no; then
     # Linking always hardcodes the temporary library directory.
     _LT_TAGVAR(hardcode_action, $1)=relink
   else
@@ -2186,12 +2115,12 @@ else
 fi
 AC_MSG_RESULT([$_LT_TAGVAR(hardcode_action, $1)])
 
-if test relink = "$_LT_TAGVAR(hardcode_action, $1)" ||
-   test yes = "$_LT_TAGVAR(inherit_rpath, $1)"; then
+if test "$_LT_TAGVAR(hardcode_action, $1)" = relink ||
+   test "$_LT_TAGVAR(inherit_rpath, $1)" = yes; then
   # Fast installation is not supported
   enable_fast_install=no
-elif test yes = "$shlibpath_overrides_runpath" ||
-     test no = "$enable_shared"; then
+elif test "$shlibpath_overrides_runpath" = yes ||
+     test "$enable_shared" = no; then
   # Fast installation is not necessary
   enable_fast_install=needless
 fi
@@ -2215,7 +2144,7 @@ else
 # FIXME - insert some real tests, host_os isn't really good enough
   case $host_os in
   darwin*)
-    if test -n "$STRIP"; then
+    if test -n "$STRIP" ; then
       striplib="$STRIP -x"
       old_striplib="$STRIP -S"
       AC_MSG_RESULT([yes])
@@ -2233,47 +2162,6 @@ _LT_DECL([], [striplib], [1])
 ])# _LT_CMD_STRIPLIB
 
 
-# _LT_PREPARE_MUNGE_PATH_LIST
-# ---------------------------
-# Make sure func_munge_path_list() is defined correctly.
-m4_defun([_LT_PREPARE_MUNGE_PATH_LIST],
-[[# func_munge_path_list VARIABLE PATH
-# -----------------------------------
-# VARIABLE is name of variable containing _space_ separated list of
-# directories to be munged by the contents of PATH, which is string
-# having a format:
-# "DIR[:DIR]:"
-#       string "DIR[ DIR]" will be prepended to VARIABLE
-# ":DIR[:DIR]"
-#       string "DIR[ DIR]" will be appended to VARIABLE
-# "DIRP[:DIRP]::[DIRA:]DIRA"
-#       string "DIRP[ DIRP]" will be prepended to VARIABLE and string
-#       "DIRA[ DIRA]" will be appended to VARIABLE
-# "DIR[:DIR]"
-#       VARIABLE will be replaced by "DIR[ DIR]"
-func_munge_path_list ()
-{
-    case x at S|@2 in
-    x)
-        ;;
-    *:)
-        eval @S|@1=\"`$ECHO @S|@2 | $SED 's/:/ /g'` \@S|@@S|@1\"
-        ;;
-    x:*)
-        eval @S|@1=\"\@S|@@S|@1 `$ECHO @S|@2 | $SED 's/:/ /g'`\"
-        ;;
-    *::*)
-        eval @S|@1=\"\@S|@@S|@1\ `$ECHO @S|@2 | $SED -e 's/.*:://' -e 's/:/ /g'`\"
-        eval @S|@1=\"`$ECHO @S|@2 | $SED -e 's/::.*//' -e 's/:/ /g'`\ \@S|@@S|@1\"
-        ;;
-    *)
-        eval @S|@1=\"`$ECHO @S|@2 | $SED 's/:/ /g'`\"
-        ;;
-    esac
-}
-]])# _LT_PREPARE_PATH_LIST
-
-
 # _LT_SYS_DYNAMIC_LINKER([TAG])
 # -----------------------------
 # PORTME Fill in your ld.so characteristics
@@ -2284,18 +2172,17 @@ m4_require([_LT_FILEUTILS_DEFAULTS])dnl
 m4_require([_LT_DECL_OBJDUMP])dnl
 m4_require([_LT_DECL_SED])dnl
 m4_require([_LT_CHECK_SHELL_FEATURES])dnl
-m4_require([_LT_PREPARE_MUNGE_PATH_LIST])dnl
 AC_MSG_CHECKING([dynamic linker characteristics])
 m4_if([$1],
 	[], [
-if test yes = "$GCC"; then
+if test "$GCC" = yes; then
   case $host_os in
-    darwin*) lt_awk_arg='/^libraries:/,/LR/' ;;
-    *) lt_awk_arg='/^libraries:/' ;;
+    darwin*) lt_awk_arg="/^libraries:/,/LR/" ;;
+    *) lt_awk_arg="/^libraries:/" ;;
   esac
   case $host_os in
-    mingw* | cegcc*) lt_sed_strip_eq='s|=\([[A-Za-z]]:\)|\1|g' ;;
-    *) lt_sed_strip_eq='s|=/|/|g' ;;
+    mingw* | cegcc*) lt_sed_strip_eq="s,=\([[A-Za-z]]:\),\1,g" ;;
+    *) lt_sed_strip_eq="s,=/,/,g" ;;
   esac
   lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e $lt_sed_strip_eq`
   case $lt_search_path_spec in
@@ -2311,35 +2198,28 @@ if test yes = "$GCC"; then
     ;;
   esac
   # Ok, now we have the path, separated by spaces, we can step through it
-  # and add multilib dir if necessary...
+  # and add multilib dir if necessary.
   lt_tmp_lt_search_path_spec=
-  lt_multi_os_dir=/`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null`
-  # ...but if some path component already ends with the multilib dir we assume
-  # that all is fine and trust -print-search-dirs as is (GCC 4.2? or newer).
-  case "$lt_multi_os_dir; $lt_search_path_spec " in
-  "/; "* | "/.; "* | "/./; "* | *"$lt_multi_os_dir "* | *"$lt_multi_os_dir/ "*)
-    lt_multi_os_dir=
-    ;;
-  esac
+  lt_multi_os_dir=`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null`
   for lt_sys_path in $lt_search_path_spec; do
-    if test -d "$lt_sys_path$lt_multi_os_dir"; then
-      lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path$lt_multi_os_dir"
-    elif test -n "$lt_multi_os_dir"; then
+    if test -d "$lt_sys_path/$lt_multi_os_dir"; then
+      lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path/$lt_multi_os_dir"
+    else
       test -d "$lt_sys_path" && \
 	lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path"
     fi
   done
   lt_search_path_spec=`$ECHO "$lt_tmp_lt_search_path_spec" | awk '
-BEGIN {RS = " "; FS = "/|\n";} {
-  lt_foo = "";
-  lt_count = 0;
+BEGIN {RS=" "; FS="/|\n";} {
+  lt_foo="";
+  lt_count=0;
   for (lt_i = NF; lt_i > 0; lt_i--) {
     if ($lt_i != "" && $lt_i != ".") {
       if ($lt_i == "..") {
         lt_count++;
       } else {
         if (lt_count == 0) {
-          lt_foo = "/" $lt_i lt_foo;
+          lt_foo="/" $lt_i lt_foo;
         } else {
           lt_count--;
         }
@@ -2353,7 +2233,7 @@ BEGIN {RS = " "; FS = "/|\n";} {
   # for these hosts.
   case $host_os in
     mingw* | cegcc*) lt_search_path_spec=`$ECHO "$lt_search_path_spec" |\
-      $SED 's|/\([[A-Za-z]]:\)|\1|g'` ;;
+      $SED 's,/\([[A-Za-z]]:\),\1,g'` ;;
   esac
   sys_lib_search_path_spec=`$ECHO "$lt_search_path_spec" | $lt_NL2SP`
 else
@@ -2362,7 +2242,7 @@ fi])
 library_names_spec=
 libname_spec='lib$name'
 soname_spec=
-shrext_cmds=.so
+shrext_cmds=".so"
 postinstall_cmds=
 postuninstall_cmds=
 finish_cmds=
@@ -2379,17 +2259,14 @@ hardcode_into_libs=no
 # flags to be left without arguments
 need_version=unknown
 
-AC_ARG_VAR([LT_SYS_LIBRARY_PATH],
-[User-defined run-time library search path.])
-
 case $host_os in
 aix3*)
   version_type=linux # correct to gnu/linux during the next big refactor
-  library_names_spec='$libname$release$shared_ext$versuffix $libname.a'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a'
   shlibpath_var=LIBPATH
 
   # AIX 3 has no versioning support, so we append a major version to the name.
-  soname_spec='$libname$release$shared_ext$major'
+  soname_spec='${libname}${release}${shared_ext}$major'
   ;;
 
 aix[[4-9]]*)
@@ -2397,91 +2274,41 @@ aix[[4-9]]*)
   need_lib_prefix=no
   need_version=no
   hardcode_into_libs=yes
-  if test ia64 = "$host_cpu"; then
+  if test "$host_cpu" = ia64; then
     # AIX 5 supports IA64
-    library_names_spec='$libname$release$shared_ext$major $libname$release$shared_ext$versuffix $libname$shared_ext'
+    library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}'
     shlibpath_var=LD_LIBRARY_PATH
   else
     # With GCC up to 2.95.x, collect2 would create an import file
     # for dependence libraries.  The import file would start with
-    # the line '#! .'.  This would cause the generated library to
-    # depend on '.', always an invalid library.  This was fixed in
+    # the line `#! .'.  This would cause the generated library to
+    # depend on `.', always an invalid library.  This was fixed in
     # development snapshots of GCC prior to 3.0.
     case $host_os in
       aix4 | aix4.[[01]] | aix4.[[01]].*)
       if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)'
 	   echo ' yes '
-	   echo '#endif'; } | $CC -E - | $GREP yes > /dev/null; then
+	   echo '#endif'; } | ${CC} -E - | $GREP yes > /dev/null; then
 	:
       else
 	can_build_shared=no
       fi
       ;;
     esac
-    # Using Import Files as archive members, it is possible to support
-    # filename-based versioning of shared library archives on AIX. While
-    # this would work for both with and without runtime linking, it will
-    # prevent static linking of such archives. So we do filename-based
-    # shared library versioning with .so extension only, which is used
-    # when both runtime linking and shared linking is enabled.
-    # Unfortunately, runtime linking may impact performance, so we do
-    # not want this to be the default eventually. Also, we use the
-    # versioned .so libs for executables only if there is the -brtl
-    # linker flag in LDFLAGS as well, or --with-aix-soname=svr4 only.
-    # To allow for filename-based versioning support, we need to create
-    # libNAME.so.V as an archive file, containing:
-    # *) an Import File, referring to the versioned filename of the
-    #    archive as well as the shared archive member, telling the
-    #    bitwidth (32 or 64) of that shared object, and providing the
-    #    list of exported symbols of that shared object, eventually
-    #    decorated with the 'weak' keyword
-    # *) the shared object with the F_LOADONLY flag set, to really avoid
-    #    it being seen by the linker.
-    # At run time we better use the real file rather than another symlink,
-    # but for link time we create the symlink libNAME.so -> libNAME.so.V
-
-    case $with_aix_soname,$aix_use_runtimelinking in
-    # AIX (on Power*) has no versioning support, so currently we cannot hardcode correct
+    # AIX (on Power*) has no versioning support, so currently we can not hardcode correct
     # soname into executable. Probably we can add versioning support to
     # collect2, so additional links can be useful in future.
-    aix,yes) # traditional libtool
-      dynamic_linker='AIX unversionable lib.so'
+    if test "$aix_use_runtimelinking" = yes; then
       # If using run time linking (on AIX 4.2 or later) use lib<name>.so
       # instead of lib<name>.a to let people know that these are not
       # typical AIX shared libraries.
-      library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
-      ;;
-    aix,no) # traditional AIX only
-      dynamic_linker='AIX lib.a[(]lib.so.V[)]'
+      library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+    else
       # We preserve .a as extension for shared libraries through AIX4.2
       # and later when we are not doing run time linking.
-      library_names_spec='$libname$release.a $libname.a'
-      soname_spec='$libname$release$shared_ext$major'
-      ;;
-    svr4,*) # full svr4 only
-      dynamic_linker="AIX lib.so.V[(]$shared_archive_member_spec.o[)]"
-      library_names_spec='$libname$release$shared_ext$major $libname$shared_ext'
-      # We do not specify a path in Import Files, so LIBPATH fires.
-      shlibpath_overrides_runpath=yes
-      ;;
-    *,yes) # both, prefer svr4
-      dynamic_linker="AIX lib.so.V[(]$shared_archive_member_spec.o[)], lib.a[(]lib.so.V[)]"
-      library_names_spec='$libname$release$shared_ext$major $libname$shared_ext'
-      # unpreferred sharedlib libNAME.a needs extra handling
-      postinstall_cmds='test -n "$linkname" || linkname="$realname"~func_stripname "" ".so" "$linkname"~$install_shared_prog "$dir/$func_stripname_result.$libext" "$destdir/$func_stripname_result.$libext"~test -z "$tstripme" || test -z "$striplib" || $striplib "$destdir/$func_stripname_result.$libext"'
-      postuninstall_cmds='for n in $library_names $old_library; do :; done~func_stripname "" ".so" "$n"~test "$func_stripname_result" = "$n" || func_append rmfiles " $odir/$func_stripname_result.$libext"'
-      # We do not specify a path in Import Files, so LIBPATH fires.
-      shlibpath_overrides_runpath=yes
-      ;;
-    *,no) # both, prefer aix
-      dynamic_linker="AIX lib.a[(]lib.so.V[)], lib.so.V[(]$shared_archive_member_spec.o[)]"
-      library_names_spec='$libname$release.a $libname.a'
-      soname_spec='$libname$release$shared_ext$major'
-      # unpreferred sharedlib libNAME.so.V and symlink libNAME.so need extra handling
-      postinstall_cmds='test -z "$dlname" || $install_shared_prog $dir/$dlname $destdir/$dlname~test -z "$tstripme" || test -z "$striplib" || $striplib $destdir/$dlname~test -n "$linkname" || linkname=$realname~func_stripname "" ".a" "$linkname"~(cd "$destdir" && $LN_S -f $dlname $func_stripname_result.so)'
-      postuninstall_cmds='test -z "$dlname" || func_append rmfiles " $odir/$dlname"~for n in $old_library $library_names; do :; done~func_stripname "" ".a" "$n"~func_append rmfiles " $odir/$func_stripname_result.so"'
-      ;;
-    esac
+      library_names_spec='${libname}${release}.a $libname.a'
+      soname_spec='${libname}${release}${shared_ext}$major'
+    fi
     shlibpath_var=LIBPATH
   fi
   ;;
@@ -2491,18 +2318,18 @@ amigaos*)
   powerpc)
     # Since July 2007 AmigaOS4 officially supports .so libraries.
     # When compiling the executable, add -use-dynld -Lsobjs: to the compileline.
-    library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
     ;;
   m68k)
     library_names_spec='$libname.ixlibrary $libname.a'
     # Create ${libname}_ixlibrary.a entries in /sys/libs.
-    finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([[^/]]*\)\.ixlibrary$%\1%'\''`; $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done'
+    finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([[^/]]*\)\.ixlibrary$%\1%'\''`; test $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done'
     ;;
   esac
   ;;
 
 beos*)
-  library_names_spec='$libname$shared_ext'
+  library_names_spec='${libname}${shared_ext}'
   dynamic_linker="$host_os ld.so"
   shlibpath_var=LIBRARY_PATH
   ;;
@@ -2510,8 +2337,8 @@ beos*)
 bsdi[[45]]*)
   version_type=linux # correct to gnu/linux during the next big refactor
   need_version=no
-  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
-  soname_spec='$libname$release$shared_ext$major'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
   finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir'
   shlibpath_var=LD_LIBRARY_PATH
   sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib"
@@ -2523,7 +2350,7 @@ bsdi[[45]]*)
 
 cygwin* | mingw* | pw32* | cegcc*)
   version_type=windows
-  shrext_cmds=.dll
+  shrext_cmds=".dll"
   need_version=no
   need_lib_prefix=no
 
@@ -2532,8 +2359,8 @@ cygwin* | mingw* | pw32* | cegcc*)
     # gcc
     library_names_spec='$libname.dll.a'
     # DLL is installed to $(libdir)/../bin by postinstall_cmds
-    postinstall_cmds='base_file=`basename \$file`~
-      dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~
+    postinstall_cmds='base_file=`basename \${file}`~
+      dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~
       dldir=$destdir/`dirname \$dlpath`~
       test -d \$dldir || mkdir -p \$dldir~
       $install_prog $dir/$dlname \$dldir/$dlname~
@@ -2549,17 +2376,17 @@ cygwin* | mingw* | pw32* | cegcc*)
     case $host_os in
     cygwin*)
       # Cygwin DLLs use 'cyg' prefix rather than 'lib'
-      soname_spec='`echo $libname | sed -e 's/^lib/cyg/'``echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext'
+      soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}'
 m4_if([$1], [],[
       sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/lib/w32api"])
       ;;
     mingw* | cegcc*)
       # MinGW DLLs use traditional 'lib' prefix
-      soname_spec='$libname`echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext'
+      soname_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}'
       ;;
     pw32*)
       # pw32 DLLs use 'pw' prefix rather than 'lib'
-      library_names_spec='`echo $libname | sed -e 's/^lib/pw/'``echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext'
+      library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}'
       ;;
     esac
     dynamic_linker='Win32 ld.exe'
@@ -2568,8 +2395,8 @@ m4_if([$1], [],[
   *,cl*)
     # Native MSVC
     libname_spec='$name'
-    soname_spec='$libname`echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext'
-    library_names_spec='$libname.dll.lib'
+    soname_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}'
+    library_names_spec='${libname}.dll.lib'
 
     case $build_os in
     mingw*)
@@ -2596,7 +2423,7 @@ m4_if([$1], [],[
       sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"`
       ;;
     *)
-      sys_lib_search_path_spec=$LIB
+      sys_lib_search_path_spec="$LIB"
       if $ECHO "$sys_lib_search_path_spec" | [$GREP ';[c-zC-Z]:/' >/dev/null]; then
         # It is most probably a Windows format PATH.
         sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'`
@@ -2609,8 +2436,8 @@ m4_if([$1], [],[
     esac
 
     # DLL is installed to $(libdir)/../bin by postinstall_cmds
-    postinstall_cmds='base_file=`basename \$file`~
-      dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~
+    postinstall_cmds='base_file=`basename \${file}`~
+      dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~
       dldir=$destdir/`dirname \$dlpath`~
       test -d \$dldir || mkdir -p \$dldir~
       $install_prog $dir/$dlname \$dldir/$dlname'
@@ -2623,7 +2450,7 @@ m4_if([$1], [],[
 
   *)
     # Assume MSVC wrapper
-    library_names_spec='$libname`echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext $libname.lib'
+    library_names_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext} $libname.lib'
     dynamic_linker='Win32 ld.exe'
     ;;
   esac
@@ -2636,8 +2463,8 @@ darwin* | rhapsody*)
   version_type=darwin
   need_lib_prefix=no
   need_version=no
-  library_names_spec='$libname$release$major$shared_ext $libname$shared_ext'
-  soname_spec='$libname$release$major$shared_ext'
+  library_names_spec='${libname}${release}${major}$shared_ext ${libname}$shared_ext'
+  soname_spec='${libname}${release}${major}$shared_ext'
   shlibpath_overrides_runpath=yes
   shlibpath_var=DYLD_LIBRARY_PATH
   shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`'
@@ -2650,8 +2477,8 @@ dgux*)
   version_type=linux # correct to gnu/linux during the next big refactor
   need_lib_prefix=no
   need_version=no
-  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
-  soname_spec='$libname$release$shared_ext$major'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext'
+  soname_spec='${libname}${release}${shared_ext}$major'
   shlibpath_var=LD_LIBRARY_PATH
   ;;
 
@@ -2669,13 +2496,12 @@ freebsd* | dragonfly*)
   version_type=freebsd-$objformat
   case $version_type in
     freebsd-elf*)
-      library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
-      soname_spec='$libname$release$shared_ext$major'
+      library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}'
       need_version=no
       need_lib_prefix=no
       ;;
     freebsd-*)
-      library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix'
+      library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix'
       need_version=yes
       ;;
   esac
@@ -2705,10 +2531,10 @@ haiku*)
   need_lib_prefix=no
   need_version=no
   dynamic_linker="$host_os runtime_loader"
-  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
-  soname_spec='$libname$release$shared_ext$major'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
   shlibpath_var=LIBRARY_PATH
-  shlibpath_overrides_runpath=no
+  shlibpath_overrides_runpath=yes
   sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib'
   hardcode_into_libs=yes
   ;;
@@ -2726,15 +2552,14 @@ hpux9* | hpux10* | hpux11*)
     dynamic_linker="$host_os dld.so"
     shlibpath_var=LD_LIBRARY_PATH
     shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
-    library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
-    soname_spec='$libname$release$shared_ext$major'
-    if test 32 = "$HPUX_IA64_MODE"; then
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+    soname_spec='${libname}${release}${shared_ext}$major'
+    if test "X$HPUX_IA64_MODE" = X32; then
       sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib"
-      sys_lib_dlsearch_path_spec=/usr/lib/hpux32
     else
       sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64"
-      sys_lib_dlsearch_path_spec=/usr/lib/hpux64
     fi
+    sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
     ;;
   hppa*64*)
     shrext_cmds='.sl'
@@ -2742,8 +2567,8 @@ hpux9* | hpux10* | hpux11*)
     dynamic_linker="$host_os dld.sl"
     shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH
     shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
-    library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
-    soname_spec='$libname$release$shared_ext$major'
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+    soname_spec='${libname}${release}${shared_ext}$major'
     sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64"
     sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
     ;;
@@ -2752,8 +2577,8 @@ hpux9* | hpux10* | hpux11*)
     dynamic_linker="$host_os dld.sl"
     shlibpath_var=SHLIB_PATH
     shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH
-    library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
-    soname_spec='$libname$release$shared_ext$major'
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+    soname_spec='${libname}${release}${shared_ext}$major'
     ;;
   esac
   # HP-UX runs *really* slowly unless shared libraries are mode 555, ...
@@ -2766,8 +2591,8 @@ interix[[3-9]]*)
   version_type=linux # correct to gnu/linux during the next big refactor
   need_lib_prefix=no
   need_version=no
-  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
-  soname_spec='$libname$release$shared_ext$major'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
   dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)'
   shlibpath_var=LD_LIBRARY_PATH
   shlibpath_overrides_runpath=no
@@ -2778,7 +2603,7 @@ irix5* | irix6* | nonstopux*)
   case $host_os in
     nonstopux*) version_type=nonstopux ;;
     *)
-	if test yes = "$lt_cv_prog_gnu_ld"; then
+	if test "$lt_cv_prog_gnu_ld" = yes; then
 		version_type=linux # correct to gnu/linux during the next big refactor
 	else
 		version_type=irix
@@ -2786,8 +2611,8 @@ irix5* | irix6* | nonstopux*)
   esac
   need_lib_prefix=no
   need_version=no
-  soname_spec='$libname$release$shared_ext$major'
-  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$release$shared_ext $libname$shared_ext'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}'
   case $host_os in
   irix5* | nonstopux*)
     libsuff= shlibsuff=
@@ -2806,8 +2631,8 @@ irix5* | irix6* | nonstopux*)
   esac
   shlibpath_var=LD_LIBRARY${shlibsuff}_PATH
   shlibpath_overrides_runpath=no
-  sys_lib_search_path_spec="/usr/lib$libsuff /lib$libsuff /usr/local/lib$libsuff"
-  sys_lib_dlsearch_path_spec="/usr/lib$libsuff /lib$libsuff"
+  sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}"
+  sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}"
   hardcode_into_libs=yes
   ;;
 
@@ -2816,33 +2641,13 @@ linux*oldld* | linux*aout* | linux*coff*)
   dynamic_linker=no
   ;;
 
-linux*android*)
-  version_type=none # Android doesn't support versioned libraries.
-  need_lib_prefix=no
-  need_version=no
-  library_names_spec='$libname$release$shared_ext'
-  soname_spec='$libname$release$shared_ext'
-  finish_cmds=
-  shlibpath_var=LD_LIBRARY_PATH
-  shlibpath_overrides_runpath=yes
-
-  # This implies no fast_install, which is unacceptable.
-  # Some rework will be needed to allow for fast_install
-  # before this can be enabled.
-  hardcode_into_libs=yes
-
-  dynamic_linker='Android linker'
-  # Don't embed -rpath directories since the linker doesn't support them.
-  _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
-  ;;
-
 # This must be glibc/ELF.
 linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*)
   version_type=linux # correct to gnu/linux during the next big refactor
   need_lib_prefix=no
   need_version=no
-  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
-  soname_spec='$libname$release$shared_ext$major'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
   finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir'
   shlibpath_var=LD_LIBRARY_PATH
   shlibpath_overrides_runpath=no
@@ -2867,12 +2672,7 @@ linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*)
   # before this can be enabled.
   hardcode_into_libs=yes
 
-  # Ideally, we could use ldconfig to report *all* directores which are
-  # searched for libraries, however this is still not possible.  Aside from not
-  # being certain /sbin/ldconfig is available, command
-  # 'ldconfig -N -X -v | grep ^/' on 64bit Fedora does not report /usr/lib64,
-  # even though it is searched at run-time.  Try to do the best guess by
-  # appending ld.so.conf contents (and includes) to the search path.
+  # Append ld.so.conf contents to the search path
   if test -f /etc/ld.so.conf; then
     lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \[$]2)); skip = 1; } { if (!skip) print \[$]0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[	 ]*hwcap[	 ]/d;s/[:,	]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '`
     sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra"
@@ -2904,12 +2704,12 @@ netbsd*)
   need_lib_prefix=no
   need_version=no
   if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
-    library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix'
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
     finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
     dynamic_linker='NetBSD (a.out) ld.so'
   else
-    library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
-    soname_spec='$libname$release$shared_ext$major'
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+    soname_spec='${libname}${release}${shared_ext}$major'
     dynamic_linker='NetBSD ld.elf_so'
   fi
   shlibpath_var=LD_LIBRARY_PATH
@@ -2919,7 +2719,7 @@ netbsd*)
 
 newsos6)
   version_type=linux # correct to gnu/linux during the next big refactor
-  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
   shlibpath_var=LD_LIBRARY_PATH
   shlibpath_overrides_runpath=yes
   ;;
@@ -2928,68 +2728,58 @@ newsos6)
   version_type=qnx
   need_lib_prefix=no
   need_version=no
-  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
-  soname_spec='$libname$release$shared_ext$major'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
   shlibpath_var=LD_LIBRARY_PATH
   shlibpath_overrides_runpath=no
   hardcode_into_libs=yes
   dynamic_linker='ldqnx.so'
   ;;
 
-openbsd* | bitrig*)
+openbsd*)
   version_type=sunos
-  sys_lib_dlsearch_path_spec=/usr/lib
+  sys_lib_dlsearch_path_spec="/usr/lib"
   need_lib_prefix=no
-  if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then
-    need_version=no
-  else
-    need_version=yes
-  fi
-  library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix'
+  # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs.
+  case $host_os in
+    openbsd3.3 | openbsd3.3.*)	need_version=yes ;;
+    *)				need_version=no  ;;
+  esac
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
   finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
   shlibpath_var=LD_LIBRARY_PATH
-  shlibpath_overrides_runpath=yes
+  if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+    case $host_os in
+      openbsd2.[[89]] | openbsd2.[[89]].*)
+	shlibpath_overrides_runpath=no
+	;;
+      *)
+	shlibpath_overrides_runpath=yes
+	;;
+      esac
+  else
+    shlibpath_overrides_runpath=yes
+  fi
   ;;
 
 os2*)
   libname_spec='$name'
-  version_type=windows
-  shrext_cmds=.dll
-  need_version=no
+  shrext_cmds=".dll"
   need_lib_prefix=no
-  # OS/2 can only load a DLL with a base name of 8 characters or less.
-  soname_spec='`test -n "$os2dllname" && libname="$os2dllname";
-    v=$($ECHO $release$versuffix | tr -d .-);
-    n=$($ECHO $libname | cut -b -$((8 - ${#v})) | tr . _);
-    $ECHO $n$v`$shared_ext'
-  library_names_spec='${libname}_dll.$libext'
+  library_names_spec='$libname${shared_ext} $libname.a'
   dynamic_linker='OS/2 ld.exe'
-  shlibpath_var=BEGINLIBPATH
-  sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib"
-  sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
-  postinstall_cmds='base_file=`basename \$file`~
-    dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; $ECHO \$dlname'\''`~
-    dldir=$destdir/`dirname \$dlpath`~
-    test -d \$dldir || mkdir -p \$dldir~
-    $install_prog $dir/$dlname \$dldir/$dlname~
-    chmod a+x \$dldir/$dlname~
-    if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then
-      eval '\''$striplib \$dldir/$dlname'\'' || exit \$?;
-    fi'
-  postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; $ECHO \$dlname'\''`~
-    dlpath=$dir/\$dldll~
-    $RM \$dlpath'
+  shlibpath_var=LIBPATH
   ;;
 
 osf3* | osf4* | osf5*)
   version_type=osf
   need_lib_prefix=no
   need_version=no
-  soname_spec='$libname$release$shared_ext$major'
-  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
   shlibpath_var=LD_LIBRARY_PATH
   sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib"
-  sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
+  sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec"
   ;;
 
 rdos*)
@@ -3000,8 +2790,8 @@ solaris*)
   version_type=linux # correct to gnu/linux during the next big refactor
   need_lib_prefix=no
   need_version=no
-  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
-  soname_spec='$libname$release$shared_ext$major'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
   shlibpath_var=LD_LIBRARY_PATH
   shlibpath_overrides_runpath=yes
   hardcode_into_libs=yes
@@ -3011,11 +2801,11 @@ solaris*)
 
 sunos4*)
   version_type=sunos
-  library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
   finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir'
   shlibpath_var=LD_LIBRARY_PATH
   shlibpath_overrides_runpath=yes
-  if test yes = "$with_gnu_ld"; then
+  if test "$with_gnu_ld" = yes; then
     need_lib_prefix=no
   fi
   need_version=yes
@@ -3023,8 +2813,8 @@ sunos4*)
 
 sysv4 | sysv4.3*)
   version_type=linux # correct to gnu/linux during the next big refactor
-  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
-  soname_spec='$libname$release$shared_ext$major'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
   shlibpath_var=LD_LIBRARY_PATH
   case $host_vendor in
     sni)
@@ -3045,24 +2835,24 @@ sysv4 | sysv4.3*)
   ;;
 
 sysv4*MP*)
-  if test -d /usr/nec; then
+  if test -d /usr/nec ;then
     version_type=linux # correct to gnu/linux during the next big refactor
-    library_names_spec='$libname$shared_ext.$versuffix $libname$shared_ext.$major $libname$shared_ext'
-    soname_spec='$libname$shared_ext.$major'
+    library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}'
+    soname_spec='$libname${shared_ext}.$major'
     shlibpath_var=LD_LIBRARY_PATH
   fi
   ;;
 
 sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
-  version_type=sco
+  version_type=freebsd-elf
   need_lib_prefix=no
   need_version=no
-  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext $libname$shared_ext'
-  soname_spec='$libname$release$shared_ext$major'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
   shlibpath_var=LD_LIBRARY_PATH
   shlibpath_overrides_runpath=yes
   hardcode_into_libs=yes
-  if test yes = "$with_gnu_ld"; then
+  if test "$with_gnu_ld" = yes; then
     sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib'
   else
     sys_lib_search_path_spec='/usr/ccs/lib /usr/lib'
@@ -3080,7 +2870,7 @@ tpf*)
   version_type=linux # correct to gnu/linux during the next big refactor
   need_lib_prefix=no
   need_version=no
-  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
   shlibpath_var=LD_LIBRARY_PATH
   shlibpath_overrides_runpath=no
   hardcode_into_libs=yes
@@ -3088,8 +2878,8 @@ tpf*)
 
 uts4*)
   version_type=linux # correct to gnu/linux during the next big refactor
-  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
-  soname_spec='$libname$release$shared_ext$major'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
   shlibpath_var=LD_LIBRARY_PATH
   ;;
 
@@ -3098,30 +2888,20 @@ uts4*)
   ;;
 esac
 AC_MSG_RESULT([$dynamic_linker])
-test no = "$dynamic_linker" && can_build_shared=no
+test "$dynamic_linker" = no && can_build_shared=no
 
 variables_saved_for_relink="PATH $shlibpath_var $runpath_var"
-if test yes = "$GCC"; then
+if test "$GCC" = yes; then
   variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH"
 fi
 
-if test set = "${lt_cv_sys_lib_search_path_spec+set}"; then
-  sys_lib_search_path_spec=$lt_cv_sys_lib_search_path_spec
+if test "${lt_cv_sys_lib_search_path_spec+set}" = set; then
+  sys_lib_search_path_spec="$lt_cv_sys_lib_search_path_spec"
 fi
-
-if test set = "${lt_cv_sys_lib_dlsearch_path_spec+set}"; then
-  sys_lib_dlsearch_path_spec=$lt_cv_sys_lib_dlsearch_path_spec
+if test "${lt_cv_sys_lib_dlsearch_path_spec+set}" = set; then
+  sys_lib_dlsearch_path_spec="$lt_cv_sys_lib_dlsearch_path_spec"
 fi
 
-# remember unaugmented sys_lib_dlsearch_path content for libtool script decls...
-configure_time_dlsearch_path=$sys_lib_dlsearch_path_spec
-
-# ... but it needs LT_SYS_LIBRARY_PATH munging for other configure-time code
-func_munge_path_list sys_lib_dlsearch_path_spec "$LT_SYS_LIBRARY_PATH"
-
-# to be used as default LT_SYS_LIBRARY_PATH value in generated libtool
-configure_time_lt_sys_library_path=$LT_SYS_LIBRARY_PATH
-
 _LT_DECL([], [variables_saved_for_relink], [1],
     [Variables whose values should be saved in libtool wrapper scripts and
     restored at link time])
@@ -3154,41 +2934,39 @@ _LT_DECL([], [hardcode_into_libs], [0],
     [Whether we should hardcode library paths into libraries])
 _LT_DECL([], [sys_lib_search_path_spec], [2],
     [Compile-time system search path for libraries])
-_LT_DECL([sys_lib_dlsearch_path_spec], [configure_time_dlsearch_path], [2],
-    [Detected run-time system search path for libraries])
-_LT_DECL([], [configure_time_lt_sys_library_path], [2],
-    [Explicit LT_SYS_LIBRARY_PATH set during ./configure time])
+_LT_DECL([], [sys_lib_dlsearch_path_spec], [2],
+    [Run-time system search path for libraries])
 ])# _LT_SYS_DYNAMIC_LINKER
 
 
 # _LT_PATH_TOOL_PREFIX(TOOL)
 # --------------------------
-# find a file program that can recognize shared library
+# find a file program which can recognize shared library
 AC_DEFUN([_LT_PATH_TOOL_PREFIX],
 [m4_require([_LT_DECL_EGREP])dnl
 AC_MSG_CHECKING([for $1])
 AC_CACHE_VAL(lt_cv_path_MAGIC_CMD,
 [case $MAGIC_CMD in
 [[\\/*] |  ?:[\\/]*])
-  lt_cv_path_MAGIC_CMD=$MAGIC_CMD # Let the user override the test with a path.
+  lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path.
   ;;
 *)
-  lt_save_MAGIC_CMD=$MAGIC_CMD
-  lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR
+  lt_save_MAGIC_CMD="$MAGIC_CMD"
+  lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
 dnl $ac_dummy forces splitting on constant user-supplied paths.
 dnl POSIX.2 word splitting is done only on the output of word expansions,
 dnl not every word.  This closes a longstanding sh security hole.
   ac_dummy="m4_if([$2], , $PATH, [$2])"
   for ac_dir in $ac_dummy; do
-    IFS=$lt_save_ifs
+    IFS="$lt_save_ifs"
     test -z "$ac_dir" && ac_dir=.
-    if test -f "$ac_dir/$1"; then
-      lt_cv_path_MAGIC_CMD=$ac_dir/"$1"
+    if test -f $ac_dir/$1; then
+      lt_cv_path_MAGIC_CMD="$ac_dir/$1"
       if test -n "$file_magic_test_file"; then
 	case $deplibs_check_method in
 	"file_magic "*)
 	  file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"`
-	  MAGIC_CMD=$lt_cv_path_MAGIC_CMD
+	  MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
 	  if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null |
 	    $EGREP "$file_magic_regex" > /dev/null; then
 	    :
@@ -3211,11 +2989,11 @@ _LT_EOF
       break
     fi
   done
-  IFS=$lt_save_ifs
-  MAGIC_CMD=$lt_save_MAGIC_CMD
+  IFS="$lt_save_ifs"
+  MAGIC_CMD="$lt_save_MAGIC_CMD"
   ;;
 esac])
-MAGIC_CMD=$lt_cv_path_MAGIC_CMD
+MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
 if test -n "$MAGIC_CMD"; then
   AC_MSG_RESULT($MAGIC_CMD)
 else
@@ -3233,7 +3011,7 @@ dnl AC_DEFUN([AC_PATH_TOOL_PREFIX], [])
 
 # _LT_PATH_MAGIC
 # --------------
-# find a file program that can recognize a shared library
+# find a file program which can recognize a shared library
 m4_defun([_LT_PATH_MAGIC],
 [_LT_PATH_TOOL_PREFIX(${ac_tool_prefix}file, /usr/bin$PATH_SEPARATOR$PATH)
 if test -z "$lt_cv_path_MAGIC_CMD"; then
@@ -3260,16 +3038,16 @@ m4_require([_LT_PROG_ECHO_BACKSLASH])dnl
 AC_ARG_WITH([gnu-ld],
     [AS_HELP_STRING([--with-gnu-ld],
 	[assume the C compiler uses GNU ld @<:@default=no@:>@])],
-    [test no = "$withval" || with_gnu_ld=yes],
+    [test "$withval" = no || with_gnu_ld=yes],
     [with_gnu_ld=no])dnl
 
 ac_prog=ld
-if test yes = "$GCC"; then
+if test "$GCC" = yes; then
   # Check if gcc -print-prog-name=ld gives a path.
   AC_MSG_CHECKING([for ld used by $CC])
   case $host in
   *-*-mingw*)
-    # gcc leaves a trailing carriage return, which upsets mingw
+    # gcc leaves a trailing carriage return which upsets mingw
     ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;;
   *)
     ac_prog=`($CC -print-prog-name=ld) 2>&5` ;;
@@ -3283,7 +3061,7 @@ if test yes = "$GCC"; then
       while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do
 	ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"`
       done
-      test -z "$LD" && LD=$ac_prog
+      test -z "$LD" && LD="$ac_prog"
       ;;
   "")
     # If it fails, then pretend we aren't using GCC.
@@ -3294,37 +3072,37 @@ if test yes = "$GCC"; then
     with_gnu_ld=unknown
     ;;
   esac
-elif test yes = "$with_gnu_ld"; then
+elif test "$with_gnu_ld" = yes; then
   AC_MSG_CHECKING([for GNU ld])
 else
   AC_MSG_CHECKING([for non-GNU ld])
 fi
 AC_CACHE_VAL(lt_cv_path_LD,
 [if test -z "$LD"; then
-  lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR
+  lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
   for ac_dir in $PATH; do
-    IFS=$lt_save_ifs
+    IFS="$lt_save_ifs"
     test -z "$ac_dir" && ac_dir=.
     if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then
-      lt_cv_path_LD=$ac_dir/$ac_prog
+      lt_cv_path_LD="$ac_dir/$ac_prog"
       # Check to see if the program is GNU ld.  I'd rather use --version,
       # but apparently some variants of GNU ld only accept -v.
       # Break only if it was the GNU/non-GNU ld that we prefer.
       case `"$lt_cv_path_LD" -v 2>&1 </dev/null` in
       *GNU* | *'with BFD'*)
-	test no != "$with_gnu_ld" && break
+	test "$with_gnu_ld" != no && break
 	;;
       *)
-	test yes != "$with_gnu_ld" && break
+	test "$with_gnu_ld" != yes && break
 	;;
       esac
     fi
   done
-  IFS=$lt_save_ifs
+  IFS="$lt_save_ifs"
 else
-  lt_cv_path_LD=$LD # Let the user override the test with a path.
+  lt_cv_path_LD="$LD" # Let the user override the test with a path.
 fi])
-LD=$lt_cv_path_LD
+LD="$lt_cv_path_LD"
 if test -n "$LD"; then
   AC_MSG_RESULT($LD)
 else
@@ -3378,13 +3156,13 @@ esac
 reload_cmds='$LD$reload_flag -o $output$reload_objs'
 case $host_os in
   cygwin* | mingw* | pw32* | cegcc*)
-    if test yes != "$GCC"; then
+    if test "$GCC" != yes; then
       reload_cmds=false
     fi
     ;;
   darwin*)
-    if test yes = "$GCC"; then
-      reload_cmds='$LTCC $LTCFLAGS -nostdlib $wl-r -o $output$reload_objs'
+    if test "$GCC" = yes; then
+      reload_cmds='$LTCC $LTCFLAGS -nostdlib ${wl}-r -o $output$reload_objs'
     else
       reload_cmds='$LD$reload_flag -o $output$reload_objs'
     fi
@@ -3395,43 +3173,6 @@ _LT_TAGDECL([], [reload_cmds], [2])dnl
 ])# _LT_CMD_RELOAD
 
 
-# _LT_PATH_DD
-# -----------
-# find a working dd
-m4_defun([_LT_PATH_DD],
-[AC_CACHE_CHECK([for a working dd], [ac_cv_path_lt_DD],
-[printf 0123456789abcdef0123456789abcdef >conftest.i
-cat conftest.i conftest.i >conftest2.i
-: ${lt_DD:=$DD}
-AC_PATH_PROGS_FEATURE_CHECK([lt_DD], [dd],
-[if "$ac_path_lt_DD" bs=32 count=1 <conftest2.i >conftest.out 2>/dev/null; then
-  cmp -s conftest.i conftest.out \
-  && ac_cv_path_lt_DD="$ac_path_lt_DD" ac_path_lt_DD_found=:
-fi])
-rm -f conftest.i conftest2.i conftest.out])
-])# _LT_PATH_DD
-
-
-# _LT_CMD_TRUNCATE
-# ----------------
-# find command to truncate a binary pipe
-m4_defun([_LT_CMD_TRUNCATE],
-[m4_require([_LT_PATH_DD])
-AC_CACHE_CHECK([how to truncate binary pipes], [lt_cv_truncate_bin],
-[printf 0123456789abcdef0123456789abcdef >conftest.i
-cat conftest.i conftest.i >conftest2.i
-lt_cv_truncate_bin=
-if "$ac_cv_path_lt_DD" bs=32 count=1 <conftest2.i >conftest.out 2>/dev/null; then
-  cmp -s conftest.i conftest.out \
-  && lt_cv_truncate_bin="$ac_cv_path_lt_DD bs=4096 count=1"
-fi
-rm -f conftest.i conftest2.i conftest.out
-test -z "$lt_cv_truncate_bin" && lt_cv_truncate_bin="$SED -e 4q"])
-_LT_DECL([lt_truncate_bin], [lt_cv_truncate_bin], [1],
-  [Command to truncate a binary pipe])
-])# _LT_CMD_TRUNCATE
-
-
 # _LT_CHECK_MAGIC_METHOD
 # ----------------------
 # how to check for library dependencies
@@ -3447,13 +3188,13 @@ lt_cv_deplibs_check_method='unknown'
 # Need to set the preceding variable on all platforms that support
 # interlibrary dependencies.
 # 'none' -- dependencies not supported.
-# 'unknown' -- same as none, but documents that we really don't know.
+# `unknown' -- same as none, but documents that we really don't know.
 # 'pass_all' -- all dependencies passed with no checks.
 # 'test_compile' -- check by making test program.
 # 'file_magic [[regex]]' -- check by looking for files in library path
-# that responds to the $file_magic_cmd with a given extended regex.
-# If you have 'file' or equivalent on your system and you're not sure
-# whether 'pass_all' will *always* work, you probably want this one.
+# which responds to the $file_magic_cmd with a given extended regex.
+# If you have `file' or equivalent on your system and you're not sure
+# whether `pass_all' will *always* work, you probably want this one.
 
 case $host_os in
 aix[[4-9]]*)
@@ -3480,7 +3221,8 @@ mingw* | pw32*)
   # Base MSYS/MinGW do not provide the 'file' command needed by
   # func_win32_libid shell function, so use a weaker test based on 'objdump',
   # unless we find 'file', for example because we are cross-compiling.
-  if ( file / ) >/dev/null 2>&1; then
+  # func_win32_libid assumes BSD nm, so disallow it if using MS dumpbin.
+  if ( test "$lt_cv_nm_interface" = "BSD nm" && file / ) >/dev/null 2>&1; then
     lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL'
     lt_cv_file_magic_cmd='func_win32_libid'
   else
@@ -3576,8 +3318,8 @@ newos6*)
   lt_cv_deplibs_check_method=pass_all
   ;;
 
-openbsd* | bitrig*)
-  if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then
+openbsd*)
+  if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
     lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|\.so|_pic\.a)$'
   else
     lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$'
@@ -3630,9 +3372,6 @@ sysv4 | sysv4.3*)
 tpf*)
   lt_cv_deplibs_check_method=pass_all
   ;;
-os2*)
-  lt_cv_deplibs_check_method=pass_all
-  ;;
 esac
 ])
 
@@ -3673,38 +3412,33 @@ AC_DEFUN([LT_PATH_NM],
 AC_CACHE_CHECK([for BSD- or MS-compatible name lister (nm)], lt_cv_path_NM,
 [if test -n "$NM"; then
   # Let the user override the test.
-  lt_cv_path_NM=$NM
+  lt_cv_path_NM="$NM"
 else
-  lt_nm_to_check=${ac_tool_prefix}nm
+  lt_nm_to_check="${ac_tool_prefix}nm"
   if test -n "$ac_tool_prefix" && test "$build" = "$host"; then
     lt_nm_to_check="$lt_nm_to_check nm"
   fi
   for lt_tmp_nm in $lt_nm_to_check; do
-    lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR
+    lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
     for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do
-      IFS=$lt_save_ifs
+      IFS="$lt_save_ifs"
       test -z "$ac_dir" && ac_dir=.
-      tmp_nm=$ac_dir/$lt_tmp_nm
-      if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext"; then
+      tmp_nm="$ac_dir/$lt_tmp_nm"
+      if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext" ; then
 	# Check to see if the nm accepts a BSD-compat flag.
-	# Adding the 'sed 1q' prevents false positives on HP-UX, which says:
+	# Adding the `sed 1q' prevents false positives on HP-UX, which says:
 	#   nm: unknown option "B" ignored
 	# Tru64's nm complains that /dev/null is an invalid object file
-	# MSYS converts /dev/null to NUL, MinGW nm treats NUL as empty
-	case $build_os in
-	mingw*) lt_bad_file=conftest.nm/nofile ;;
-	*) lt_bad_file=/dev/null ;;
-	esac
-	case `"$tmp_nm" -B $lt_bad_file 2>&1 | sed '1q'` in
-	*$lt_bad_file* | *'Invalid file or object type'*)
+	case `"$tmp_nm" -B /dev/null 2>&1 | sed '1q'` in
+	*/dev/null* | *'Invalid file or object type'*)
 	  lt_cv_path_NM="$tmp_nm -B"
-	  break 2
+	  break
 	  ;;
 	*)
 	  case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in
 	  */dev/null*)
 	    lt_cv_path_NM="$tmp_nm -p"
-	    break 2
+	    break
 	    ;;
 	  *)
 	    lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but
@@ -3715,21 +3449,21 @@ else
 	esac
       fi
     done
-    IFS=$lt_save_ifs
+    IFS="$lt_save_ifs"
   done
   : ${lt_cv_path_NM=no}
 fi])
-if test no != "$lt_cv_path_NM"; then
-  NM=$lt_cv_path_NM
+if test "$lt_cv_path_NM" != "no"; then
+  NM="$lt_cv_path_NM"
 else
   # Didn't find any BSD compatible name lister, look for dumpbin.
   if test -n "$DUMPBIN"; then :
     # Let the user override the test.
   else
     AC_CHECK_TOOLS(DUMPBIN, [dumpbin "link -dump"], :)
-    case `$DUMPBIN -symbols -headers /dev/null 2>&1 | sed '1q'` in
+    case `$DUMPBIN -symbols /dev/null 2>&1 | sed '1q'` in
     *COFF*)
-      DUMPBIN="$DUMPBIN -symbols -headers"
+      DUMPBIN="$DUMPBIN -symbols"
       ;;
     *)
       DUMPBIN=:
@@ -3737,8 +3471,8 @@ else
     esac
   fi
   AC_SUBST([DUMPBIN])
-  if test : != "$DUMPBIN"; then
-    NM=$DUMPBIN
+  if test "$DUMPBIN" != ":"; then
+    NM="$DUMPBIN"
   fi
 fi
 test -z "$NM" && NM=nm
@@ -3784,8 +3518,8 @@ lt_cv_sharedlib_from_linklib_cmd,
 
 case $host_os in
 cygwin* | mingw* | pw32* | cegcc*)
-  # two different shell functions defined in ltmain.sh;
-  # decide which one to use based on capabilities of $DLLTOOL
+  # two different shell functions defined in ltmain.sh
+  # decide which to use based on capabilities of $DLLTOOL
   case `$DLLTOOL --help 2>&1` in
   *--identify-strict*)
     lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib
@@ -3797,7 +3531,7 @@ cygwin* | mingw* | pw32* | cegcc*)
   ;;
 *)
   # fallback: assume linklib IS sharedlib
-  lt_cv_sharedlib_from_linklib_cmd=$ECHO
+  lt_cv_sharedlib_from_linklib_cmd="$ECHO"
   ;;
 esac
 ])
@@ -3824,28 +3558,13 @@ AC_CACHE_CHECK([if $MANIFEST_TOOL is a manifest tool], [lt_cv_path_mainfest_tool
     lt_cv_path_mainfest_tool=yes
   fi
   rm -f conftest*])
-if test yes != "$lt_cv_path_mainfest_tool"; then
+if test "x$lt_cv_path_mainfest_tool" != xyes; then
   MANIFEST_TOOL=:
 fi
 _LT_DECL([], [MANIFEST_TOOL], [1], [Manifest tool])dnl
 ])# _LT_PATH_MANIFEST_TOOL
 
 
-# _LT_DLL_DEF_P([FILE])
-# ---------------------
-# True iff FILE is a Windows DLL '.def' file.
-# Keep in sync with func_dll_def_p in the libtool script
-AC_DEFUN([_LT_DLL_DEF_P],
-[dnl
-  test DEF = "`$SED -n dnl
-    -e '\''s/^[[	 ]]*//'\'' dnl Strip leading whitespace
-    -e '\''/^\(;.*\)*$/d'\'' dnl      Delete empty lines and comments
-    -e '\''s/^\(EXPORTS\|LIBRARY\)\([[	 ]].*\)*$/DEF/p'\'' dnl
-    -e q dnl                          Only consider the first "real" line
-    $1`" dnl
-])# _LT_DLL_DEF_P
-
-
 # LT_LIB_M
 # --------
 # check for math library
@@ -3857,11 +3576,11 @@ case $host in
   # These system don't have libm, or don't need it
   ;;
 *-ncr-sysv4.3*)
-  AC_CHECK_LIB(mw, _mwvalidcheckl, LIBM=-lmw)
+  AC_CHECK_LIB(mw, _mwvalidcheckl, LIBM="-lmw")
   AC_CHECK_LIB(m, cos, LIBM="$LIBM -lm")
   ;;
 *)
-  AC_CHECK_LIB(m, cos, LIBM=-lm)
+  AC_CHECK_LIB(m, cos, LIBM="-lm")
   ;;
 esac
 AC_SUBST([LIBM])
@@ -3880,7 +3599,7 @@ m4_defun([_LT_COMPILER_NO_RTTI],
 
 _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=
 
-if test yes = "$GCC"; then
+if test "$GCC" = yes; then
   case $cc_basename in
   nvcc*)
     _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -Xcompiler -fno-builtin' ;;
@@ -3932,7 +3651,7 @@ cygwin* | mingw* | pw32* | cegcc*)
   symcode='[[ABCDGISTW]]'
   ;;
 hpux*)
-  if test ia64 = "$host_cpu"; then
+  if test "$host_cpu" = ia64; then
     symcode='[[ABCDEGRST]]'
   fi
   ;;
@@ -3965,44 +3684,14 @@ case `$NM -V 2>&1` in
   symcode='[[ABCDGIRSTW]]' ;;
 esac
 
-if test "$lt_cv_nm_interface" = "MS dumpbin"; then
-  # Gets list of data symbols to import.
-  lt_cv_sys_global_symbol_to_import="sed -n -e 's/^I .* \(.*\)$/\1/p'"
-  # Adjust the below global symbol transforms to fixup imported variables.
-  lt_cdecl_hook=" -e 's/^I .* \(.*\)$/extern __declspec(dllimport) char \1;/p'"
-  lt_c_name_hook=" -e 's/^I .* \(.*\)$/  {\"\1\", (void *) 0},/p'"
-  lt_c_name_lib_hook="\
-  -e 's/^I .* \(lib.*\)$/  {\"\1\", (void *) 0},/p'\
-  -e 's/^I .* \(.*\)$/  {\"lib\1\", (void *) 0},/p'"
-else
-  # Disable hooks by default.
-  lt_cv_sys_global_symbol_to_import=
-  lt_cdecl_hook=
-  lt_c_name_hook=
-  lt_c_name_lib_hook=
-fi
-
 # Transform an extracted symbol line into a proper C declaration.
 # Some systems (esp. on ia64) link data and code symbols differently,
 # so use this general approach.
-lt_cv_sys_global_symbol_to_cdecl="sed -n"\
-$lt_cdecl_hook\
-" -e 's/^T .* \(.*\)$/extern int \1();/p'"\
-" -e 's/^$symcode$symcode* .* \(.*\)$/extern char \1;/p'"
+lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'"
 
 # Transform an extracted symbol line into symbol name and symbol address
-lt_cv_sys_global_symbol_to_c_name_address="sed -n"\
-$lt_c_name_hook\
-" -e 's/^: \(.*\) .*$/  {\"\1\", (void *) 0},/p'"\
-" -e 's/^$symcode$symcode* .* \(.*\)$/  {\"\1\", (void *) \&\1},/p'"
-
-# Transform an extracted symbol line into symbol name with lib prefix and
-# symbol address.
-lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n"\
-$lt_c_name_lib_hook\
-" -e 's/^: \(.*\) .*$/  {\"\1\", (void *) 0},/p'"\
-" -e 's/^$symcode$symcode* .* \(lib.*\)$/  {\"\1\", (void *) \&\1},/p'"\
-" -e 's/^$symcode$symcode* .* \(.*\)$/  {\"lib\1\", (void *) \&\1},/p'"
+lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([[^ ]]*\)[[ ]]*$/  {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/  {\"\2\", (void *) \&\2},/p'"
+lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n -e 's/^: \([[^ ]]*\)[[ ]]*$/  {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \(lib[[^ ]]*\)$/  {\"\2\", (void *) \&\2},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/  {\"lib\2\", (void *) \&\2},/p'"
 
 # Handle CRLF in mingw tool chain
 opt_cr=
@@ -4020,24 +3709,21 @@ for ac_symprfx in "" "_"; do
 
   # Write the raw and C identifiers.
   if test "$lt_cv_nm_interface" = "MS dumpbin"; then
-    # Fake it for dumpbin and say T for any non-static function,
-    # D for any global variable and I for any imported variable.
+    # Fake it for dumpbin and say T for any non-static function
+    # and D for any global variable.
     # Also find C++ and __fastcall symbols from MSVC++,
     # which start with @ or ?.
     lt_cv_sys_global_symbol_pipe="$AWK ['"\
 "     {last_section=section; section=\$ 3};"\
 "     /^COFF SYMBOL TABLE/{for(i in hide) delete hide[i]};"\
 "     /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\
-"     /^ *Symbol name *: /{split(\$ 0,sn,\":\"); si=substr(sn[2],2)};"\
-"     /^ *Type *: code/{print \"T\",si,substr(si,length(prfx))};"\
-"     /^ *Type *: data/{print \"I\",si,substr(si,length(prfx))};"\
 "     \$ 0!~/External *\|/{next};"\
 "     / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\
 "     {if(hide[section]) next};"\
-"     {f=\"D\"}; \$ 0~/\(\).*\|/{f=\"T\"};"\
-"     {split(\$ 0,a,/\||\r/); split(a[2],s)};"\
-"     s[1]~/^[@?]/{print f,s[1],s[1]; next};"\
-"     s[1]~prfx {split(s[1],t,\"@\"); print f,t[1],substr(t[1],length(prfx))}"\
+"     {f=0}; \$ 0~/\(\).*\|/{f=1}; {printf f ? \"T \" : \"D \"};"\
+"     {split(\$ 0, a, /\||\r/); split(a[2], s)};"\
+"     s[1]~/^[@?]/{print s[1], s[1]; next};"\
+"     s[1]~prfx {split(s[1],t,\"@\"); print t[1], substr(t[1],length(prfx))}"\
 "     ' prfx=^$ac_symprfx]"
   else
     lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[[	 ]]\($symcode$symcode*\)[[	 ]][[	 ]]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'"
@@ -4077,11 +3763,11 @@ _LT_EOF
 	if $GREP ' nm_test_func$' "$nlist" >/dev/null; then
 	  cat <<_LT_EOF > conftest.$ac_ext
 /* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests.  */
-#if defined _WIN32 || defined __CYGWIN__ || defined _WIN32_WCE
-/* DATA imports from DLLs on WIN32 can't be const, because runtime
+#if defined(_WIN32) || defined(__CYGWIN__) || defined(_WIN32_WCE)
+/* DATA imports from DLLs on WIN32 con't be const, because runtime
    relocations are performed -- see ld's documentation on pseudo-relocs.  */
 # define LT@&t at _DLSYM_CONST
-#elif defined __osf__
+#elif defined(__osf__)
 /* This system does not cope well with relocations in const data.  */
 # define LT@&t at _DLSYM_CONST
 #else
@@ -4107,7 +3793,7 @@ lt__PROGRAM__LTX_preloaded_symbols[[]] =
 {
   { "@PROGRAM@", (void *) 0 },
 _LT_EOF
-	  $SED "s/^$symcode$symcode* .* \(.*\)$/  {\"\1\", (void *) \&\1},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext
+	  $SED "s/^$symcode$symcode* \(.*\) \(.*\)$/  {\"\2\", (void *) \&\2},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext
 	  cat <<\_LT_EOF >> conftest.$ac_ext
   {0, (void *) 0}
 };
@@ -4127,9 +3813,9 @@ _LT_EOF
 	  mv conftest.$ac_objext conftstm.$ac_objext
 	  lt_globsym_save_LIBS=$LIBS
 	  lt_globsym_save_CFLAGS=$CFLAGS
-	  LIBS=conftstm.$ac_objext
+	  LIBS="conftstm.$ac_objext"
 	  CFLAGS="$CFLAGS$_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)"
-	  if AC_TRY_EVAL(ac_link) && test -s conftest$ac_exeext; then
+	  if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext}; then
 	    pipe_works=yes
 	  fi
 	  LIBS=$lt_globsym_save_LIBS
@@ -4150,7 +3836,7 @@ _LT_EOF
   rm -rf conftest* conftst*
 
   # Do not use the global_symbol_pipe unless it works.
-  if test yes = "$pipe_works"; then
+  if test "$pipe_works" = yes; then
     break
   else
     lt_cv_sys_global_symbol_pipe=
@@ -4177,16 +3863,12 @@ _LT_DECL([global_symbol_pipe], [lt_cv_sys_global_symbol_pipe], [1],
     [Take the output of nm and produce a listing of raw symbols and C names])
 _LT_DECL([global_symbol_to_cdecl], [lt_cv_sys_global_symbol_to_cdecl], [1],
     [Transform the output of nm in a proper C declaration])
-_LT_DECL([global_symbol_to_import], [lt_cv_sys_global_symbol_to_import], [1],
-    [Transform the output of nm into a list of symbols to manually relocate])
 _LT_DECL([global_symbol_to_c_name_address],
     [lt_cv_sys_global_symbol_to_c_name_address], [1],
     [Transform the output of nm in a C name address pair])
 _LT_DECL([global_symbol_to_c_name_address_lib_prefix],
     [lt_cv_sys_global_symbol_to_c_name_address_lib_prefix], [1],
     [Transform the output of nm in a C name address pair when lib prefix is needed])
-_LT_DECL([nm_interface], [lt_cv_nm_interface], [1],
-    [The name lister interface])
 _LT_DECL([], [nm_file_list_spec], [1],
     [Specify filename containing input files for $NM])
 ]) # _LT_CMD_GLOBAL_SYMBOLS
@@ -4202,18 +3884,17 @@ _LT_TAGVAR(lt_prog_compiler_static, $1)=
 
 m4_if([$1], [CXX], [
   # C++ specific cases for pic, static, wl, etc.
-  if test yes = "$GXX"; then
+  if test "$GXX" = yes; then
     _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
     _LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
 
     case $host_os in
     aix*)
       # All AIX code is PIC.
-      if test ia64 = "$host_cpu"; then
+      if test "$host_cpu" = ia64; then
 	# AIX 5 now supports IA64 processor
 	_LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
       fi
-      _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
       ;;
 
     amigaos*)
@@ -4224,8 +3905,8 @@ m4_if([$1], [CXX], [
         ;;
       m68k)
             # FIXME: we need at least 68020 code to build shared libraries, but
-            # adding the '-m68020' flag to GCC prevents building anything better,
-            # like '-m68040'.
+            # adding the `-m68020' flag to GCC prevents building anything better,
+            # like `-m68040'.
             _LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4'
         ;;
       esac
@@ -4241,11 +3922,6 @@ m4_if([$1], [CXX], [
       # (--disable-auto-import) libraries
       m4_if([$1], [GCJ], [],
 	[_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT'])
-      case $host_os in
-      os2*)
-	_LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-static'
-	;;
-      esac
       ;;
     darwin* | rhapsody*)
       # PIC is the default on this platform
@@ -4295,7 +3971,7 @@ m4_if([$1], [CXX], [
     case $host_os in
       aix[[4-9]]*)
 	# All AIX code is PIC.
-	if test ia64 = "$host_cpu"; then
+	if test "$host_cpu" = ia64; then
 	  # AIX 5 now supports IA64 processor
 	  _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
 	else
@@ -4336,14 +4012,14 @@ m4_if([$1], [CXX], [
 	case $cc_basename in
 	  CC*)
 	    _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
-	    _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-a ${wl}archive'
-	    if test ia64 != "$host_cpu"; then
+	    _LT_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive'
+	    if test "$host_cpu" != ia64; then
 	      _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z'
 	    fi
 	    ;;
 	  aCC*)
 	    _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
-	    _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-a ${wl}archive'
+	    _LT_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive'
 	    case $host_cpu in
 	    hppa*64*|ia64*)
 	      # +Z the default
@@ -4380,7 +4056,7 @@ m4_if([$1], [CXX], [
 	    _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
 	    ;;
 	  ecpc* )
-	    # old Intel C++ for x86_64, which still supported -KPIC.
+	    # old Intel C++ for x86_64 which still supported -KPIC.
 	    _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
 	    _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
 	    _LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
@@ -4525,18 +4201,17 @@ m4_if([$1], [CXX], [
   fi
 ],
 [
-  if test yes = "$GCC"; then
+  if test "$GCC" = yes; then
     _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
     _LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
 
     case $host_os in
       aix*)
       # All AIX code is PIC.
-      if test ia64 = "$host_cpu"; then
+      if test "$host_cpu" = ia64; then
 	# AIX 5 now supports IA64 processor
 	_LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
       fi
-      _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
       ;;
 
     amigaos*)
@@ -4547,8 +4222,8 @@ m4_if([$1], [CXX], [
         ;;
       m68k)
             # FIXME: we need at least 68020 code to build shared libraries, but
-            # adding the '-m68020' flag to GCC prevents building anything better,
-            # like '-m68040'.
+            # adding the `-m68020' flag to GCC prevents building anything better,
+            # like `-m68040'.
             _LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4'
         ;;
       esac
@@ -4565,11 +4240,6 @@ m4_if([$1], [CXX], [
       # (--disable-auto-import) libraries
       m4_if([$1], [GCJ], [],
 	[_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT'])
-      case $host_os in
-      os2*)
-	_LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-static'
-	;;
-      esac
       ;;
 
     darwin* | rhapsody*)
@@ -4640,7 +4310,7 @@ m4_if([$1], [CXX], [
     case $host_os in
     aix*)
       _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
-      if test ia64 = "$host_cpu"; then
+      if test "$host_cpu" = ia64; then
 	# AIX 5 now supports IA64 processor
 	_LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
       else
@@ -4648,30 +4318,11 @@ m4_if([$1], [CXX], [
       fi
       ;;
 
-    darwin* | rhapsody*)
-      # PIC is the default on this platform
-      # Common symbols not allowed in MH_DYLIB files
-      _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common'
-      case $cc_basename in
-      nagfor*)
-        # NAG Fortran compiler
-        _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,-Wl,,'
-        _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC'
-        _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
-        ;;
-      esac
-      ;;
-
     mingw* | cygwin* | pw32* | os2* | cegcc*)
       # This hack is so that the source file can tell whether it is being
       # built for inclusion in a dll (and should export symbols for example).
       m4_if([$1], [GCJ], [],
 	[_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT'])
-      case $host_os in
-      os2*)
-	_LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-static'
-	;;
-      esac
       ;;
 
     hpux9* | hpux10* | hpux11*)
@@ -4687,7 +4338,7 @@ m4_if([$1], [CXX], [
 	;;
       esac
       # Is there a better lt_prog_compiler_static that works with the bundled CC?
-      _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-a ${wl}archive'
+      _LT_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive'
       ;;
 
     irix5* | irix6* | nonstopux*)
@@ -4698,7 +4349,7 @@ m4_if([$1], [CXX], [
 
     linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*)
       case $cc_basename in
-      # old Intel for x86_64, which still supported -KPIC.
+      # old Intel for x86_64 which still supported -KPIC.
       ecc*)
 	_LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
 	_LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
@@ -4723,12 +4374,6 @@ m4_if([$1], [CXX], [
 	_LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC'
 	_LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
 	;;
-      tcc*)
-	# Fabrice Bellard et al's Tiny C Compiler
-	_LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
-	_LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
-	_LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
-	;;
       pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*)
         # Portland Group compilers (*not* the Pentium gcc compiler,
 	# which looks to be a dead project)
@@ -4826,7 +4471,7 @@ m4_if([$1], [CXX], [
       ;;
 
     sysv4*MP*)
-      if test -d /usr/nec; then
+      if test -d /usr/nec ;then
 	_LT_TAGVAR(lt_prog_compiler_pic, $1)='-Kconform_pic'
 	_LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
       fi
@@ -4855,7 +4500,7 @@ m4_if([$1], [CXX], [
   fi
 ])
 case $host_os in
-  # For platforms that do not support PIC, -DPIC is meaningless:
+  # For platforms which do not support PIC, -DPIC is meaningless:
   *djgpp*)
     _LT_TAGVAR(lt_prog_compiler_pic, $1)=
     ;;
@@ -4921,21 +4566,17 @@ m4_if([$1], [CXX], [
   case $host_os in
   aix[[4-9]]*)
     # If we're using GNU nm, then we don't want the "-C" option.
-    # -C means demangle to GNU nm, but means don't demangle to AIX nm.
-    # Without the "-l" option, or with the "-B" option, AIX nm treats
-    # weak defined symbols like other global defined symbols, whereas
-    # GNU nm marks them as "W".
-    # While the 'weak' keyword is ignored in the Export File, we need
-    # it in the Import File for the 'aix-soname' feature, so we have
-    # to replace the "-B" option with "-P" for AIX nm.
+    # -C means demangle to AIX nm, but means don't demangle with GNU nm
+    # Also, AIX nm treats weak defined symbols like other global defined
+    # symbols, whereas GNU nm marks them as "W".
     if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then
-      _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && ([substr](\$ 3,1,1) != ".")) { if (\$ 2 == "W") { print \$ 3 " weak" } else { print \$ 3 } } }'\'' | sort -u > $export_symbols'
+      _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols'
     else
-      _LT_TAGVAR(export_symbols_cmds, $1)='`func_echo_all $NM | $SED -e '\''s/B\([[^B]]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && ([substr](\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols'
+      _LT_TAGVAR(export_symbols_cmds, $1)='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols'
     fi
     ;;
   pw32*)
-    _LT_TAGVAR(export_symbols_cmds, $1)=$ltdll_cmds
+    _LT_TAGVAR(export_symbols_cmds, $1)="$ltdll_cmds"
     ;;
   cygwin* | mingw* | cegcc*)
     case $cc_basename in
@@ -4984,9 +4625,9 @@ m4_if([$1], [CXX], [
   # included in the symbol list
   _LT_TAGVAR(include_expsyms, $1)=
   # exclude_expsyms can be an extended regexp of symbols to exclude
-  # it will be wrapped by ' (' and ')$', so one must not match beginning or
-  # end of line.  Example: 'a|bc|.*d.*' will exclude the symbols 'a' and 'bc',
-  # as well as any symbol that contains 'd'.
+  # it will be wrapped by ` (' and `)$', so one must not match beginning or
+  # end of line.  Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc',
+  # as well as any symbol that contains `d'.
   _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*']
   # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out
   # platforms (ab)use it in PIC code, but their linkers get confused if
@@ -5002,7 +4643,7 @@ dnl Note also adjust exclude_expsyms for C++ above.
     # FIXME: the MSVC++ port hasn't been tested in a loooong time
     # When not using gcc, we currently assume that we are using
     # Microsoft Visual C++.
-    if test yes != "$GCC"; then
+    if test "$GCC" != yes; then
       with_gnu_ld=no
     fi
     ;;
@@ -5010,7 +4651,7 @@ dnl Note also adjust exclude_expsyms for C++ above.
     # we just hope/assume this is gcc and not c89 (= MSVC++)
     with_gnu_ld=yes
     ;;
-  openbsd* | bitrig*)
+  openbsd*)
     with_gnu_ld=no
     ;;
   linux* | k*bsd*-gnu | gnu*)
@@ -5023,7 +4664,7 @@ dnl Note also adjust exclude_expsyms for C++ above.
   # On some targets, GNU ld is compatible enough with the native linker
   # that we're better off using the native interface for both.
   lt_use_gnu_ld_interface=no
-  if test yes = "$with_gnu_ld"; then
+  if test "$with_gnu_ld" = yes; then
     case $host_os in
       aix*)
 	# The AIX port of GNU ld has always aspired to compatibility
@@ -5045,24 +4686,24 @@ dnl Note also adjust exclude_expsyms for C++ above.
     esac
   fi
 
-  if test yes = "$lt_use_gnu_ld_interface"; then
+  if test "$lt_use_gnu_ld_interface" = yes; then
     # If archive_cmds runs LD, not CC, wlarc should be empty
-    wlarc='$wl'
+    wlarc='${wl}'
 
     # Set some defaults for GNU ld with shared library support. These
     # are reset later if shared libraries are not supported. Putting them
     # here allows them to be overridden if necessary.
     runpath_var=LD_RUN_PATH
-    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir'
-    _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic'
+    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+    _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic'
     # ancient GNU ld didn't support --whole-archive et. al.
     if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then
-      _LT_TAGVAR(whole_archive_flag_spec, $1)=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive'
+      _LT_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive'
     else
       _LT_TAGVAR(whole_archive_flag_spec, $1)=
     fi
     supports_anon_versioning=no
-    case `$LD -v | $SED -e 's/([^)]\+)\s\+//' 2>&1` in
+    case `$LD -v 2>&1` in
       *GNU\ gold*) supports_anon_versioning=yes ;;
       *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.10.*) ;; # catch versions < 2.11
       *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ...
@@ -5075,7 +4716,7 @@ dnl Note also adjust exclude_expsyms for C++ above.
     case $host_os in
     aix[[3-9]]*)
       # On AIX/PPC, the GNU linker is very broken
-      if test ia64 != "$host_cpu"; then
+      if test "$host_cpu" != ia64; then
 	_LT_TAGVAR(ld_shlibs, $1)=no
 	cat <<_LT_EOF 1>&2
 
@@ -5094,7 +4735,7 @@ _LT_EOF
       case $host_cpu in
       powerpc)
             # see comment about AmigaOS4 .so support
-            _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+            _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
             _LT_TAGVAR(archive_expsym_cmds, $1)=''
         ;;
       m68k)
@@ -5110,7 +4751,7 @@ _LT_EOF
 	_LT_TAGVAR(allow_undefined_flag, $1)=unsupported
 	# Joseph Beckenbach <jrb3 at best.com> says some releases of gcc
 	# support --undefined.  This deserves some investigation.  FIXME
-	_LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+	_LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
       else
 	_LT_TAGVAR(ld_shlibs, $1)=no
       fi
@@ -5120,7 +4761,7 @@ _LT_EOF
       # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless,
       # as there is no search path for DLLs.
       _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
-      _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-all-symbols'
+      _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-all-symbols'
       _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
       _LT_TAGVAR(always_export_symbols, $1)=no
       _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
@@ -5128,89 +4769,61 @@ _LT_EOF
       _LT_TAGVAR(exclude_expsyms, $1)=['[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname']
 
       if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then
-        _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
-	# If the export-symbols file already is a .def file, use it as
-	# is; otherwise, prepend EXPORTS...
-	_LT_TAGVAR(archive_expsym_cmds, $1)='if _LT_DLL_DEF_P([$export_symbols]); then
-          cp $export_symbols $output_objdir/$soname.def;
-        else
-          echo EXPORTS > $output_objdir/$soname.def;
-          cat $export_symbols >> $output_objdir/$soname.def;
-        fi~
-        $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+        _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+	# If the export-symbols file already is a .def file (1st line
+	# is EXPORTS), use it as is; otherwise, prepend...
+	_LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then
+	  cp $export_symbols $output_objdir/$soname.def;
+	else
+	  echo EXPORTS > $output_objdir/$soname.def;
+	  cat $export_symbols >> $output_objdir/$soname.def;
+	fi~
+	$CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
       else
 	_LT_TAGVAR(ld_shlibs, $1)=no
       fi
       ;;
 
     haiku*)
-      _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+      _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
       _LT_TAGVAR(link_all_deplibs, $1)=yes
       ;;
 
-    os2*)
-      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
-      _LT_TAGVAR(hardcode_minus_L, $1)=yes
-      _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
-      shrext_cmds=.dll
-      _LT_TAGVAR(archive_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~
-	$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~
-	$ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~
-	$ECHO EXPORTS >> $output_objdir/$libname.def~
-	emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~
-	$CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~
-	emximp -o $lib $output_objdir/$libname.def'
-      _LT_TAGVAR(archive_expsym_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~
-	$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~
-	$ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~
-	$ECHO EXPORTS >> $output_objdir/$libname.def~
-	prefix_cmds="$SED"~
-	if test EXPORTS = "`$SED 1q $export_symbols`"; then
-	  prefix_cmds="$prefix_cmds -e 1d";
-	fi~
-	prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~
-	cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~
-	$CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~
-	emximp -o $lib $output_objdir/$libname.def'
-      _LT_TAGVAR(old_archive_From_new_cmds, $1)='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def'
-      _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
-      ;;
-
     interix[[3-9]]*)
       _LT_TAGVAR(hardcode_direct, $1)=no
       _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
-      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir'
-      _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E'
+      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
+      _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
       # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc.
       # Instead, shared libraries are loaded at an image base (0x10000000 by
       # default) and relocated if they conflict, which is a slow very memory
       # consuming and fragmenting process.  To avoid this, we pick a random,
       # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link
       # time.  Moving up from 0x10000000 also allows more sbrk(2) space.
-      _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
-      _LT_TAGVAR(archive_expsym_cmds, $1)='sed "s|^|_|" $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--retain-symbols-file,$output_objdir/$soname.expsym $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+      _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+      _LT_TAGVAR(archive_expsym_cmds, $1)='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
       ;;
 
     gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu)
       tmp_diet=no
-      if test linux-dietlibc = "$host_os"; then
+      if test "$host_os" = linux-dietlibc; then
 	case $cc_basename in
 	  diet\ *) tmp_diet=yes;;	# linux-dietlibc with static linking (!diet-dyn)
 	esac
       fi
       if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \
-	 && test no = "$tmp_diet"
+	 && test "$tmp_diet" = no
       then
 	tmp_addflag=' $pic_flag'
 	tmp_sharedflag='-shared'
 	case $cc_basename,$host_cpu in
         pgcc*)				# Portland Group C compiler
-	  _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive'
+	  _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
 	  tmp_addflag=' $pic_flag'
 	  ;;
 	pgf77* | pgf90* | pgf95* | pgfortran*)
 					# Portland Group f77 and f90 compilers
-	  _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive'
+	  _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
 	  tmp_addflag=' $pic_flag -Mnomain' ;;
 	ecc*,ia64* | icc*,ia64*)	# Intel C compiler on ia64
 	  tmp_addflag=' -i_dynamic' ;;
@@ -5221,47 +4834,42 @@ _LT_EOF
 	lf95*)				# Lahey Fortran 8.1
 	  _LT_TAGVAR(whole_archive_flag_spec, $1)=
 	  tmp_sharedflag='--shared' ;;
-        nagfor*)                        # NAGFOR 5.3
-          tmp_sharedflag='-Wl,-shared' ;;
 	xl[[cC]]* | bgxl[[cC]]* | mpixl[[cC]]*) # IBM XL C 8.0 on PPC (deal with xlf below)
 	  tmp_sharedflag='-qmkshrobj'
 	  tmp_addflag= ;;
 	nvcc*)	# Cuda Compiler Driver 2.2
-	  _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive'
+	  _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
 	  _LT_TAGVAR(compiler_needs_object, $1)=yes
 	  ;;
 	esac
 	case `$CC -V 2>&1 | sed 5q` in
 	*Sun\ C*)			# Sun C 5.9
-	  _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive'
+	  _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
 	  _LT_TAGVAR(compiler_needs_object, $1)=yes
 	  tmp_sharedflag='-G' ;;
 	*Sun\ F*)			# Sun Fortran 8.3
 	  tmp_sharedflag='-G' ;;
 	esac
-	_LT_TAGVAR(archive_cmds, $1)='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+	_LT_TAGVAR(archive_cmds, $1)='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
 
-        if test yes = "$supports_anon_versioning"; then
+        if test "x$supports_anon_versioning" = xyes; then
           _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~
-            cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
-            echo "local: *; };" >> $output_objdir/$libname.ver~
-            $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-version-script $wl$output_objdir/$libname.ver -o $lib'
+	    cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
+	    echo "local: *; };" >> $output_objdir/$libname.ver~
+	    $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib'
         fi
 
 	case $cc_basename in
-	tcc*)
-	  _LT_TAGVAR(export_dynamic_flag_spec, $1)='-rdynamic'
-	  ;;
 	xlf* | bgf* | bgxlf* | mpixlf*)
 	  # IBM XL Fortran 10.1 on PPC cannot create shared libs itself
 	  _LT_TAGVAR(whole_archive_flag_spec, $1)='--whole-archive$convenience --no-whole-archive'
-	  _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir'
+	  _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
 	  _LT_TAGVAR(archive_cmds, $1)='$LD -shared $libobjs $deplibs $linker_flags -soname $soname -o $lib'
-	  if test yes = "$supports_anon_versioning"; then
+	  if test "x$supports_anon_versioning" = xyes; then
 	    _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~
-              cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
-              echo "local: *; };" >> $output_objdir/$libname.ver~
-              $LD -shared $libobjs $deplibs $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib'
+	      cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
+	      echo "local: *; };" >> $output_objdir/$libname.ver~
+	      $LD -shared $libobjs $deplibs $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib'
 	  fi
 	  ;;
 	esac
@@ -5275,8 +4883,8 @@ _LT_EOF
 	_LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib'
 	wlarc=
       else
-	_LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
-	_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'
+	_LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+	_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
       fi
       ;;
 
@@ -5294,8 +4902,8 @@ _LT_EOF
 
 _LT_EOF
       elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
-	_LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
-	_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'
+	_LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+	_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
       else
 	_LT_TAGVAR(ld_shlibs, $1)=no
       fi
@@ -5307,7 +4915,7 @@ _LT_EOF
 	_LT_TAGVAR(ld_shlibs, $1)=no
 	cat <<_LT_EOF 1>&2
 
-*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 cannot
+*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 can not
 *** reliably create shared libraries on SCO systems.  Therefore, libtool
 *** is disabling shared libraries support.  We urge you to upgrade GNU
 *** binutils to release 2.16.91.0.3 or newer.  Another option is to modify
@@ -5322,9 +4930,9 @@ _LT_EOF
 	  # DT_RUNPATH tag from executables and libraries.  But doing so
 	  # requires that you compile everything twice, which is a pain.
 	  if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
-	    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir'
-	    _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
-	    _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'
+	    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+	    _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+	    _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
 	  else
 	    _LT_TAGVAR(ld_shlibs, $1)=no
 	  fi
@@ -5341,15 +4949,15 @@ _LT_EOF
 
     *)
       if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
-	_LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
-	_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'
+	_LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+	_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
       else
 	_LT_TAGVAR(ld_shlibs, $1)=no
       fi
       ;;
     esac
 
-    if test no = "$_LT_TAGVAR(ld_shlibs, $1)"; then
+    if test "$_LT_TAGVAR(ld_shlibs, $1)" = no; then
       runpath_var=
       _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=
       _LT_TAGVAR(export_dynamic_flag_spec, $1)=
@@ -5365,7 +4973,7 @@ _LT_EOF
       # Note: this linker hardcodes the directories in LIBPATH if there
       # are no directories specified by -L.
       _LT_TAGVAR(hardcode_minus_L, $1)=yes
-      if test yes = "$GCC" && test -z "$lt_prog_compiler_static"; then
+      if test "$GCC" = yes && test -z "$lt_prog_compiler_static"; then
 	# Neither direct hardcoding nor static linking is supported with a
 	# broken collect2.
 	_LT_TAGVAR(hardcode_direct, $1)=unsupported
@@ -5373,57 +4981,34 @@ _LT_EOF
       ;;
 
     aix[[4-9]]*)
-      if test ia64 = "$host_cpu"; then
+      if test "$host_cpu" = ia64; then
 	# On IA64, the linker does run time linking by default, so we don't
 	# have to do anything special.
 	aix_use_runtimelinking=no
 	exp_sym_flag='-Bexport'
-	no_entry_flag=
+	no_entry_flag=""
       else
 	# If we're using GNU nm, then we don't want the "-C" option.
-	# -C means demangle to GNU nm, but means don't demangle to AIX nm.
-	# Without the "-l" option, or with the "-B" option, AIX nm treats
-	# weak defined symbols like other global defined symbols, whereas
-	# GNU nm marks them as "W".
-	# While the 'weak' keyword is ignored in the Export File, we need
-	# it in the Import File for the 'aix-soname' feature, so we have
-	# to replace the "-B" option with "-P" for AIX nm.
+	# -C means demangle to AIX nm, but means don't demangle with GNU nm
+	# Also, AIX nm treats weak defined symbols like other global
+	# defined symbols, whereas GNU nm marks them as "W".
 	if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then
-	  _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && ([substr](\$ 3,1,1) != ".")) { if (\$ 2 == "W") { print \$ 3 " weak" } else { print \$ 3 } } }'\'' | sort -u > $export_symbols'
+	  _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols'
 	else
-	  _LT_TAGVAR(export_symbols_cmds, $1)='`func_echo_all $NM | $SED -e '\''s/B\([[^B]]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && ([substr](\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols'
+	  _LT_TAGVAR(export_symbols_cmds, $1)='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols'
 	fi
 	aix_use_runtimelinking=no
 
 	# Test if we are trying to use run time linking or normal
 	# AIX style linking. If -brtl is somewhere in LDFLAGS, we
-	# have runtime linking enabled, and use it for executables.
-	# For shared libraries, we enable/disable runtime linking
-	# depending on the kind of the shared library created -
-	# when "with_aix_soname,aix_use_runtimelinking" is:
-	# "aix,no"   lib.a(lib.so.V) shared, rtl:no,  for executables
-	# "aix,yes"  lib.so          shared, rtl:yes, for executables
-	#            lib.a           static archive
-	# "both,no"  lib.so.V(shr.o) shared, rtl:yes
-	#            lib.a(lib.so.V) shared, rtl:no,  for executables
-	# "both,yes" lib.so.V(shr.o) shared, rtl:yes, for executables
-	#            lib.a(lib.so.V) shared, rtl:no
-	# "svr4,*"   lib.so.V(shr.o) shared, rtl:yes, for executables
-	#            lib.a           static archive
+	# need to do runtime linking.
 	case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*)
 	  for ld_flag in $LDFLAGS; do
-	  if (test x-brtl = "x$ld_flag" || test x-Wl,-brtl = "x$ld_flag"); then
+	  if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then
 	    aix_use_runtimelinking=yes
 	    break
 	  fi
 	  done
-	  if test svr4,no = "$with_aix_soname,$aix_use_runtimelinking"; then
-	    # With aix-soname=svr4, we create the lib.so.V shared archives only,
-	    # so we don't have lib.a shared libs to link our executables.
-	    # We have to force runtime linking in this case.
-	    aix_use_runtimelinking=yes
-	    LDFLAGS="$LDFLAGS -Wl,-brtl"
-	  fi
 	  ;;
 	esac
 
@@ -5442,21 +5027,13 @@ _LT_EOF
       _LT_TAGVAR(hardcode_direct_absolute, $1)=yes
       _LT_TAGVAR(hardcode_libdir_separator, $1)=':'
       _LT_TAGVAR(link_all_deplibs, $1)=yes
-      _LT_TAGVAR(file_list_spec, $1)='$wl-f,'
-      case $with_aix_soname,$aix_use_runtimelinking in
-      aix,*) ;; # traditional, no import file
-      svr4,* | *,yes) # use import file
-	# The Import File defines what to hardcode.
-	_LT_TAGVAR(hardcode_direct, $1)=no
-	_LT_TAGVAR(hardcode_direct_absolute, $1)=no
-	;;
-      esac
+      _LT_TAGVAR(file_list_spec, $1)='${wl}-f,'
 
-      if test yes = "$GCC"; then
+      if test "$GCC" = yes; then
 	case $host_os in aix4.[[012]]|aix4.[[012]].*)
 	# We only want to do this on AIX 4.2 and lower, the check
 	# below for broken collect2 doesn't work under 4.3+
-	  collect2name=`$CC -print-prog-name=collect2`
+	  collect2name=`${CC} -print-prog-name=collect2`
 	  if test -f "$collect2name" &&
 	   strings "$collect2name" | $GREP resolve_lib_name >/dev/null
 	  then
@@ -5475,80 +5052,62 @@ _LT_EOF
 	  ;;
 	esac
 	shared_flag='-shared'
-	if test yes = "$aix_use_runtimelinking"; then
-	  shared_flag="$shared_flag "'$wl-G'
+	if test "$aix_use_runtimelinking" = yes; then
+	  shared_flag="$shared_flag "'${wl}-G'
 	fi
-	# Need to ensure runtime linking is disabled for the traditional
-	# shared library, or the linker may eventually find shared libraries
-	# /with/ Import File - we do not want to mix them.
-	shared_flag_aix='-shared'
-	shared_flag_svr4='-shared $wl-G'
+	_LT_TAGVAR(link_all_deplibs, $1)=no
       else
 	# not using gcc
-	if test ia64 = "$host_cpu"; then
+	if test "$host_cpu" = ia64; then
 	# VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release
 	# chokes on -Wl,-G. The following line is correct:
 	  shared_flag='-G'
 	else
-	  if test yes = "$aix_use_runtimelinking"; then
-	    shared_flag='$wl-G'
+	  if test "$aix_use_runtimelinking" = yes; then
+	    shared_flag='${wl}-G'
 	  else
-	    shared_flag='$wl-bM:SRE'
+	    shared_flag='${wl}-bM:SRE'
 	  fi
-	  shared_flag_aix='$wl-bM:SRE'
-	  shared_flag_svr4='$wl-G'
 	fi
       fi
 
-      _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-bexpall'
+      _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-bexpall'
       # It seems that -bexpall does not export symbols beginning with
       # underscore (_), so it is better to generate a list of symbols to export.
       _LT_TAGVAR(always_export_symbols, $1)=yes
-      if test aix,yes = "$with_aix_soname,$aix_use_runtimelinking"; then
+      if test "$aix_use_runtimelinking" = yes; then
 	# Warning - without using the other runtime loading flags (-brtl),
 	# -berok will link without error, but may produce a broken library.
 	_LT_TAGVAR(allow_undefined_flag, $1)='-berok'
         # Determine the default libpath from the value encoded in an
         # empty executable.
         _LT_SYS_MODULE_PATH_AIX([$1])
-        _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-blibpath:$libdir:'"$aix_libpath"
-        _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs $wl'$no_entry_flag' $compiler_flags `if test -n "$allow_undefined_flag"; then func_echo_all "$wl$allow_undefined_flag"; else :; fi` $wl'$exp_sym_flag:\$export_symbols' '$shared_flag
+        _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath"
+        _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then func_echo_all "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag"
       else
-	if test ia64 = "$host_cpu"; then
-	  _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R $libdir:/usr/lib:/lib'
+	if test "$host_cpu" = ia64; then
+	  _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $libdir:/usr/lib:/lib'
 	  _LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs"
-	  _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\$wl$no_entry_flag"' $compiler_flags $wl$allow_undefined_flag '"\$wl$exp_sym_flag:\$export_symbols"
+	  _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols"
 	else
 	 # Determine the default libpath from the value encoded in an
 	 # empty executable.
 	 _LT_SYS_MODULE_PATH_AIX([$1])
-	 _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-blibpath:$libdir:'"$aix_libpath"
+	 _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath"
 	  # Warning - without using the other run time loading flags,
 	  # -berok will link without error, but may produce a broken library.
-	  _LT_TAGVAR(no_undefined_flag, $1)=' $wl-bernotok'
-	  _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-berok'
-	  if test yes = "$with_gnu_ld"; then
+	  _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-bernotok'
+	  _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-berok'
+	  if test "$with_gnu_ld" = yes; then
 	    # We only use this code for GNU lds that support --whole-archive.
-	    _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive$convenience $wl--no-whole-archive'
+	    _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive$convenience ${wl}--no-whole-archive'
 	  else
 	    # Exported symbols can be pulled into shared objects from archives
 	    _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience'
 	  fi
 	  _LT_TAGVAR(archive_cmds_need_lc, $1)=yes
-	  _LT_TAGVAR(archive_expsym_cmds, $1)='$RM -r $output_objdir/$realname.d~$MKDIR $output_objdir/$realname.d'
-	  # -brtl affects multiple linker settings, -berok does not and is overridden later
-	  compiler_flags_filtered='`func_echo_all "$compiler_flags " | $SED -e "s%-brtl\\([[, ]]\\)%-berok\\1%g"`'
-	  if test svr4 != "$with_aix_soname"; then
-	    # This is similar to how AIX traditionally builds its shared libraries.
-	    _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$CC '$shared_flag_aix' -o $output_objdir/$realname.d/$soname $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$realname.d/$soname'
-	  fi
-	  if test aix != "$with_aix_soname"; then
-	    _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$CC '$shared_flag_svr4' -o $output_objdir/$realname.d/$shared_archive_member_spec.o $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$STRIP -e $output_objdir/$realname.d/$shared_archive_member_spec.o~( func_echo_all "#! $soname($shared_archive_member_spec.o)"; if test shr_64 = "$shared_archive_member_spec"; then func_echo_all "# 64"; else func_echo_all "# 3 [...]
-	  else
-	    # used by -dlpreopen to get the symbols
-	    _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$MV  $output_objdir/$realname.d/$soname $output_objdir'
-	  fi
-	  _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$RM -r $output_objdir/$realname.d'
+	  # This is similar to how AIX traditionally builds its shared libraries.
+	  _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname'
 	fi
       fi
       ;;
@@ -5557,7 +5116,7 @@ _LT_EOF
       case $host_cpu in
       powerpc)
             # see comment about AmigaOS4 .so support
-            _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+            _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
             _LT_TAGVAR(archive_expsym_cmds, $1)=''
         ;;
       m68k)
@@ -5587,17 +5146,16 @@ _LT_EOF
 	# Tell ltmain to make .lib files, not .a files.
 	libext=lib
 	# Tell ltmain to make .dll files, not .so files.
-	shrext_cmds=.dll
+	shrext_cmds=".dll"
 	# FIXME: Setting linknames here is a bad hack.
-	_LT_TAGVAR(archive_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~linknames='
-	_LT_TAGVAR(archive_expsym_cmds, $1)='if _LT_DLL_DEF_P([$export_symbols]); then
-            cp "$export_symbols" "$output_objdir/$soname.def";
-            echo "$tool_output_objdir$soname.def" > "$output_objdir/$soname.exp";
-          else
-            $SED -e '\''s/^/-link -EXPORT:/'\'' < $export_symbols > $output_objdir/$soname.exp;
-          fi~
-          $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~
-          linknames='
+	_LT_TAGVAR(archive_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-dll~linknames='
+	_LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then
+	    sed -n -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' -e '1\\\!p' < $export_symbols > $output_objdir/$soname.exp;
+	  else
+	    sed -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' < $export_symbols > $output_objdir/$soname.exp;
+	  fi~
+	  $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~
+	  linknames='
 	# The linker will not automatically build a static lib if we build a DLL.
 	# _LT_TAGVAR(old_archive_from_new_cmds, $1)='true'
 	_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
@@ -5606,18 +5164,18 @@ _LT_EOF
 	# Don't use ranlib
 	_LT_TAGVAR(old_postinstall_cmds, $1)='chmod 644 $oldlib'
 	_LT_TAGVAR(postlink_cmds, $1)='lt_outputfile="@OUTPUT@"~
-          lt_tool_outputfile="@TOOL_OUTPUT@"~
-          case $lt_outputfile in
-            *.exe|*.EXE) ;;
-            *)
-              lt_outputfile=$lt_outputfile.exe
-              lt_tool_outputfile=$lt_tool_outputfile.exe
-              ;;
-          esac~
-          if test : != "$MANIFEST_TOOL" && test -f "$lt_outputfile.manifest"; then
-            $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1;
-            $RM "$lt_outputfile.manifest";
-          fi'
+	  lt_tool_outputfile="@TOOL_OUTPUT@"~
+	  case $lt_outputfile in
+	    *.exe|*.EXE) ;;
+	    *)
+	      lt_outputfile="$lt_outputfile.exe"
+	      lt_tool_outputfile="$lt_tool_outputfile.exe"
+	      ;;
+	  esac~
+	  if test "$MANIFEST_TOOL" != ":" && test -f "$lt_outputfile.manifest"; then
+	    $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1;
+	    $RM "$lt_outputfile.manifest";
+	  fi'
 	;;
       *)
 	# Assume MSVC wrapper
@@ -5626,7 +5184,7 @@ _LT_EOF
 	# Tell ltmain to make .lib files, not .a files.
 	libext=lib
 	# Tell ltmain to make .dll files, not .so files.
-	shrext_cmds=.dll
+	shrext_cmds=".dll"
 	# FIXME: Setting linknames here is a bad hack.
 	_LT_TAGVAR(archive_cmds, $1)='$CC -o $lib $libobjs $compiler_flags `func_echo_all "$deplibs" | $SED '\''s/ -lc$//'\''` -link -dll~linknames='
 	# The linker will automatically build a .lib file if we build a DLL.
@@ -5676,33 +5234,33 @@ _LT_EOF
       ;;
 
     hpux9*)
-      if test yes = "$GCC"; then
-	_LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared $pic_flag $wl+b $wl$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib'
+      if test "$GCC" = yes; then
+	_LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared $pic_flag ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
       else
-	_LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib'
+	_LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
       fi
-      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir'
+      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir'
       _LT_TAGVAR(hardcode_libdir_separator, $1)=:
       _LT_TAGVAR(hardcode_direct, $1)=yes
 
       # hardcode_minus_L: Not really in the search PATH,
       # but as the default location of the library.
       _LT_TAGVAR(hardcode_minus_L, $1)=yes
-      _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E'
+      _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
       ;;
 
     hpux10*)
-      if test yes,no = "$GCC,$with_gnu_ld"; then
-	_LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+      if test "$GCC" = yes && test "$with_gnu_ld" = no; then
+	_LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
       else
 	_LT_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'
       fi
-      if test no = "$with_gnu_ld"; then
-	_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir'
+      if test "$with_gnu_ld" = no; then
+	_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir'
 	_LT_TAGVAR(hardcode_libdir_separator, $1)=:
 	_LT_TAGVAR(hardcode_direct, $1)=yes
 	_LT_TAGVAR(hardcode_direct_absolute, $1)=yes
-	_LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E'
+	_LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
 	# hardcode_minus_L: Not really in the search PATH,
 	# but as the default location of the library.
 	_LT_TAGVAR(hardcode_minus_L, $1)=yes
@@ -5710,25 +5268,25 @@ _LT_EOF
       ;;
 
     hpux11*)
-      if test yes,no = "$GCC,$with_gnu_ld"; then
+      if test "$GCC" = yes && test "$with_gnu_ld" = no; then
 	case $host_cpu in
 	hppa*64*)
-	  _LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl+h $wl$soname -o $lib $libobjs $deplibs $compiler_flags'
+	  _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
 	  ;;
 	ia64*)
-	  _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $wl+h $wl$soname $wl+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
+	  _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
 	  ;;
 	*)
-	  _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+	  _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
 	  ;;
 	esac
       else
 	case $host_cpu in
 	hppa*64*)
-	  _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname -o $lib $libobjs $deplibs $compiler_flags'
+	  _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
 	  ;;
 	ia64*)
-	  _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
+	  _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
 	  ;;
 	*)
 	m4_if($1, [], [
@@ -5736,14 +5294,14 @@ _LT_EOF
 	  # (HP92453-01 A.11.01.20 doesn't, HP92453-01 B.11.X.35175-35176.GP does)
 	  _LT_LINKER_OPTION([if $CC understands -b],
 	    _LT_TAGVAR(lt_cv_prog_compiler__b, $1), [-b],
-	    [_LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags'],
+	    [_LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'],
 	    [_LT_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'])],
-	  [_LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags'])
+	  [_LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'])
 	  ;;
 	esac
       fi
-      if test no = "$with_gnu_ld"; then
-	_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir'
+      if test "$with_gnu_ld" = no; then
+	_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir'
 	_LT_TAGVAR(hardcode_libdir_separator, $1)=:
 
 	case $host_cpu in
@@ -5754,7 +5312,7 @@ _LT_EOF
 	*)
 	  _LT_TAGVAR(hardcode_direct, $1)=yes
 	  _LT_TAGVAR(hardcode_direct_absolute, $1)=yes
-	  _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E'
+	  _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
 
 	  # hardcode_minus_L: Not really in the search PATH,
 	  # but as the default location of the library.
@@ -5765,16 +5323,16 @@ _LT_EOF
       ;;
 
     irix5* | irix6* | nonstopux*)
-      if test yes = "$GCC"; then
-	_LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib'
+      if test "$GCC" = yes; then
+	_LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
 	# Try to use the -exported_symbol ld option, if it does not
 	# work, assume that -exports_file does not work either and
 	# implicitly export all symbols.
 	# This should be the same for all languages, so no per-tag cache variable.
 	AC_CACHE_CHECK([whether the $host_os linker accepts -exported_symbol],
 	  [lt_cv_irix_exported_symbol],
-	  [save_LDFLAGS=$LDFLAGS
-	   LDFLAGS="$LDFLAGS -shared $wl-exported_symbol ${wl}foo $wl-update_registry $wl/dev/null"
+	  [save_LDFLAGS="$LDFLAGS"
+	   LDFLAGS="$LDFLAGS -shared ${wl}-exported_symbol ${wl}foo ${wl}-update_registry ${wl}/dev/null"
 	   AC_LINK_IFELSE(
 	     [AC_LANG_SOURCE(
 	        [AC_LANG_CASE([C], [[int foo (void) { return 0; }]],
@@ -5787,32 +5345,21 @@ _LT_EOF
       end]])])],
 	      [lt_cv_irix_exported_symbol=yes],
 	      [lt_cv_irix_exported_symbol=no])
-           LDFLAGS=$save_LDFLAGS])
-	if test yes = "$lt_cv_irix_exported_symbol"; then
-          _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations $wl-exports_file $wl$export_symbols -o $lib'
+           LDFLAGS="$save_LDFLAGS"])
+	if test "$lt_cv_irix_exported_symbol" = yes; then
+          _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations ${wl}-exports_file ${wl}$export_symbols -o $lib'
 	fi
-	_LT_TAGVAR(link_all_deplibs, $1)=no
       else
-	_LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib'
-	_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -exports_file $export_symbols -o $lib'
+	_LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib'
+	_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -exports_file $export_symbols -o $lib'
       fi
       _LT_TAGVAR(archive_cmds_need_lc, $1)='no'
-      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir'
+      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
       _LT_TAGVAR(hardcode_libdir_separator, $1)=:
       _LT_TAGVAR(inherit_rpath, $1)=yes
       _LT_TAGVAR(link_all_deplibs, $1)=yes
       ;;
 
-    linux*)
-      case $cc_basename in
-      tcc*)
-	# Fabrice Bellard et al's Tiny C Compiler
-	_LT_TAGVAR(ld_shlibs, $1)=yes
-	_LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
-	;;
-      esac
-      ;;
-
     netbsd* | netbsdelf*-gnu)
       if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
 	_LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'  # a.out
@@ -5827,7 +5374,7 @@ _LT_EOF
     newsos6)
       _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
       _LT_TAGVAR(hardcode_direct, $1)=yes
-      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir'
+      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
       _LT_TAGVAR(hardcode_libdir_separator, $1)=:
       _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
       ;;
@@ -5835,19 +5382,27 @@ _LT_EOF
     *nto* | *qnx*)
       ;;
 
-    openbsd* | bitrig*)
+    openbsd*)
       if test -f /usr/libexec/ld.so; then
 	_LT_TAGVAR(hardcode_direct, $1)=yes
 	_LT_TAGVAR(hardcode_shlibpath_var, $1)=no
 	_LT_TAGVAR(hardcode_direct_absolute, $1)=yes
-	if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then
+	if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
 	  _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
-	  _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags $wl-retain-symbols-file,$export_symbols'
-	  _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir'
-	  _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E'
+	  _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols'
+	  _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
+	  _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
 	else
-	  _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
-	  _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir'
+	  case $host_os in
+	   openbsd[[01]].* | openbsd2.[[0-7]] | openbsd2.[[0-7]].*)
+	     _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+	     _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+	     ;;
+	   *)
+	     _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+	     _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
+	     ;;
+	  esac
 	fi
       else
 	_LT_TAGVAR(ld_shlibs, $1)=no
@@ -5858,53 +5413,33 @@ _LT_EOF
       _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
       _LT_TAGVAR(hardcode_minus_L, $1)=yes
       _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
-      shrext_cmds=.dll
-      _LT_TAGVAR(archive_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~
-	$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~
-	$ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~
-	$ECHO EXPORTS >> $output_objdir/$libname.def~
-	emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~
-	$CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~
-	emximp -o $lib $output_objdir/$libname.def'
-      _LT_TAGVAR(archive_expsym_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~
-	$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~
-	$ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~
-	$ECHO EXPORTS >> $output_objdir/$libname.def~
-	prefix_cmds="$SED"~
-	if test EXPORTS = "`$SED 1q $export_symbols`"; then
-	  prefix_cmds="$prefix_cmds -e 1d";
-	fi~
-	prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~
-	cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~
-	$CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~
-	emximp -o $lib $output_objdir/$libname.def'
-      _LT_TAGVAR(old_archive_From_new_cmds, $1)='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def'
-      _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
+      _LT_TAGVAR(archive_cmds, $1)='$ECHO "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~echo DATA >> $output_objdir/$libname.def~echo " SINGLE NONSHARED" >> $output_objdir/$libname.def~echo EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def'
+      _LT_TAGVAR(old_archive_from_new_cmds, $1)='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def'
       ;;
 
     osf3*)
-      if test yes = "$GCC"; then
-	_LT_TAGVAR(allow_undefined_flag, $1)=' $wl-expect_unresolved $wl\*'
-	_LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib'
+      if test "$GCC" = yes; then
+	_LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*'
+	_LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
       else
 	_LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*'
-	_LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib'
+	_LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib'
       fi
       _LT_TAGVAR(archive_cmds_need_lc, $1)='no'
-      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir'
+      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
       _LT_TAGVAR(hardcode_libdir_separator, $1)=:
       ;;
 
     osf4* | osf5*)	# as osf3* with the addition of -msym flag
-      if test yes = "$GCC"; then
-	_LT_TAGVAR(allow_undefined_flag, $1)=' $wl-expect_unresolved $wl\*'
-	_LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $pic_flag $libobjs $deplibs $compiler_flags $wl-msym $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib'
-	_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir'
+      if test "$GCC" = yes; then
+	_LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*'
+	_LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $pic_flag $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+	_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
       else
 	_LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*'
-	_LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib'
+	_LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib'
 	_LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~
-          $CC -shared$allow_undefined_flag $wl-input $wl$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib~$RM $lib.exp'
+	$CC -shared${allow_undefined_flag} ${wl}-input ${wl}$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib~$RM $lib.exp'
 
 	# Both c and cxx compiler support -rpath directly
 	_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir'
@@ -5915,24 +5450,24 @@ _LT_EOF
 
     solaris*)
       _LT_TAGVAR(no_undefined_flag, $1)=' -z defs'
-      if test yes = "$GCC"; then
-	wlarc='$wl'
-	_LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $wl-z ${wl}text $wl-h $wl$soname -o $lib $libobjs $deplibs $compiler_flags'
+      if test "$GCC" = yes; then
+	wlarc='${wl}'
+	_LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
 	_LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
-          $CC -shared $pic_flag $wl-z ${wl}text $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp'
+	  $CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp'
       else
 	case `$CC -V 2>&1` in
 	*"Compilers 5.0"*)
 	  wlarc=''
-	  _LT_TAGVAR(archive_cmds, $1)='$LD -G$allow_undefined_flag -h $soname -o $lib $libobjs $deplibs $linker_flags'
+	  _LT_TAGVAR(archive_cmds, $1)='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags'
 	  _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
-            $LD -G$allow_undefined_flag -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp'
+	  $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp'
 	  ;;
 	*)
-	  wlarc='$wl'
-	  _LT_TAGVAR(archive_cmds, $1)='$CC -G$allow_undefined_flag -h $soname -o $lib $libobjs $deplibs $compiler_flags'
+	  wlarc='${wl}'
+	  _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $compiler_flags'
 	  _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
-            $CC -G$allow_undefined_flag -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp'
+	  $CC -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp'
 	  ;;
 	esac
       fi
@@ -5942,11 +5477,11 @@ _LT_EOF
       solaris2.[[0-5]] | solaris2.[[0-5]].*) ;;
       *)
 	# The compiler driver will combine and reorder linker options,
-	# but understands '-z linker_flag'.  GCC discards it without '$wl',
+	# but understands `-z linker_flag'.  GCC discards it without `$wl',
 	# but is careful enough not to reorder.
 	# Supported since Solaris 2.6 (maybe 2.5.1?)
-	if test yes = "$GCC"; then
-	  _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl-z ${wl}allextract$convenience $wl-z ${wl}defaultextract'
+	if test "$GCC" = yes; then
+	  _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract'
 	else
 	  _LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract'
 	fi
@@ -5956,10 +5491,10 @@ _LT_EOF
       ;;
 
     sunos4*)
-      if test sequent = "$host_vendor"; then
+      if test "x$host_vendor" = xsequent; then
 	# Use $CC to link under sequent, because it throws in some extra .o
 	# files that make .init and .fini sections work.
-	_LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h $soname -o $lib $libobjs $deplibs $compiler_flags'
+	_LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags'
       else
 	_LT_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags'
       fi
@@ -6008,43 +5543,43 @@ _LT_EOF
       ;;
 
     sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*)
-      _LT_TAGVAR(no_undefined_flag, $1)='$wl-z,text'
+      _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text'
       _LT_TAGVAR(archive_cmds_need_lc, $1)=no
       _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
       runpath_var='LD_RUN_PATH'
 
-      if test yes = "$GCC"; then
-	_LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
-	_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+      if test "$GCC" = yes; then
+	_LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
       else
-	_LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
-	_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	_LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
       fi
       ;;
 
     sysv5* | sco3.2v5* | sco5v6*)
-      # Note: We CANNOT use -z defs as we might desire, because we do not
+      # Note: We can NOT use -z defs as we might desire, because we do not
       # link with -lc, and that would cause any symbols used from libc to
       # always be unresolved, which means just about no library would
       # ever link correctly.  If we're not using GNU ld we use -z text
       # though, which does catch some bad symbols but isn't as heavy-handed
       # as -z defs.
-      _LT_TAGVAR(no_undefined_flag, $1)='$wl-z,text'
-      _LT_TAGVAR(allow_undefined_flag, $1)='$wl-z,nodefs'
+      _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text'
+      _LT_TAGVAR(allow_undefined_flag, $1)='${wl}-z,nodefs'
       _LT_TAGVAR(archive_cmds_need_lc, $1)=no
       _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
-      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R,$libdir'
+      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R,$libdir'
       _LT_TAGVAR(hardcode_libdir_separator, $1)=':'
       _LT_TAGVAR(link_all_deplibs, $1)=yes
-      _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-Bexport'
+      _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Bexport'
       runpath_var='LD_RUN_PATH'
 
-      if test yes = "$GCC"; then
-	_LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
-	_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+      if test "$GCC" = yes; then
+	_LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
       else
-	_LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
-	_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	_LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
       fi
       ;;
 
@@ -6059,17 +5594,17 @@ _LT_EOF
       ;;
     esac
 
-    if test sni = "$host_vendor"; then
+    if test x$host_vendor = xsni; then
       case $host in
       sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*)
-	_LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-Blargedynsym'
+	_LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Blargedynsym'
 	;;
       esac
     fi
   fi
 ])
 AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)])
-test no = "$_LT_TAGVAR(ld_shlibs, $1)" && can_build_shared=no
+test "$_LT_TAGVAR(ld_shlibs, $1)" = no && can_build_shared=no
 
 _LT_TAGVAR(with_gnu_ld, $1)=$with_gnu_ld
 
@@ -6086,7 +5621,7 @@ x|xyes)
   # Assume -lc should be added
   _LT_TAGVAR(archive_cmds_need_lc, $1)=yes
 
-  if test yes,yes = "$GCC,$enable_shared"; then
+  if test "$enable_shared" = yes && test "$GCC" = yes; then
     case $_LT_TAGVAR(archive_cmds, $1) in
     *'~'*)
       # FIXME: we may have to deal with multi-command sequences.
@@ -6166,12 +5701,12 @@ _LT_TAGDECL([], [hardcode_libdir_flag_spec], [1],
 _LT_TAGDECL([], [hardcode_libdir_separator], [1],
     [Whether we need a single "-rpath" flag with a separated argument])
 _LT_TAGDECL([], [hardcode_direct], [0],
-    [Set to "yes" if using DIR/libNAME$shared_ext during linking hardcodes
+    [Set to "yes" if using DIR/libNAME${shared_ext} during linking hardcodes
     DIR into the resulting binary])
 _LT_TAGDECL([], [hardcode_direct_absolute], [0],
-    [Set to "yes" if using DIR/libNAME$shared_ext during linking hardcodes
+    [Set to "yes" if using DIR/libNAME${shared_ext} during linking hardcodes
     DIR into the resulting binary and the resulting library dependency is
-    "absolute", i.e impossible to change by setting $shlibpath_var if the
+    "absolute", i.e impossible to change by setting ${shlibpath_var} if the
     library is relocated])
 _LT_TAGDECL([], [hardcode_minus_L], [0],
     [Set to "yes" if using the -LDIR flag during linking hardcodes DIR
@@ -6212,10 +5747,10 @@ dnl    [Compiler flag to generate thread safe objects])
 # ------------------------
 # Ensure that the configuration variables for a C compiler are suitably
 # defined.  These variables are subsequently used by _LT_CONFIG to write
-# the compiler configuration to 'libtool'.
+# the compiler configuration to `libtool'.
 m4_defun([_LT_LANG_C_CONFIG],
 [m4_require([_LT_DECL_EGREP])dnl
-lt_save_CC=$CC
+lt_save_CC="$CC"
 AC_LANG_PUSH(C)
 
 # Source file extension for C test sources.
@@ -6255,18 +5790,18 @@ if test -n "$compiler"; then
   LT_SYS_DLOPEN_SELF
   _LT_CMD_STRIPLIB
 
-  # Report what library types will actually be built
+  # Report which library types will actually be built
   AC_MSG_CHECKING([if libtool supports shared libraries])
   AC_MSG_RESULT([$can_build_shared])
 
   AC_MSG_CHECKING([whether to build shared libraries])
-  test no = "$can_build_shared" && enable_shared=no
+  test "$can_build_shared" = "no" && enable_shared=no
 
   # On AIX, shared libraries and static libraries use the same namespace, and
   # are all built from PIC.
   case $host_os in
   aix3*)
-    test yes = "$enable_shared" && enable_static=no
+    test "$enable_shared" = yes && enable_static=no
     if test -n "$RANLIB"; then
       archive_cmds="$archive_cmds~\$RANLIB \$lib"
       postinstall_cmds='$RANLIB $lib'
@@ -6274,12 +5809,8 @@ if test -n "$compiler"; then
     ;;
 
   aix[[4-9]]*)
-    if test ia64 != "$host_cpu"; then
-      case $enable_shared,$with_aix_soname,$aix_use_runtimelinking in
-      yes,aix,yes) ;;			# shared object as lib.so file only
-      yes,svr4,*) ;;			# shared object as lib.so archive member only
-      yes,*) enable_static=no ;;	# shared object in lib.a archive as well
-      esac
+    if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then
+      test "$enable_shared" = yes && enable_static=no
     fi
     ;;
   esac
@@ -6287,13 +5818,13 @@ if test -n "$compiler"; then
 
   AC_MSG_CHECKING([whether to build static libraries])
   # Make sure either enable_shared or enable_static is yes.
-  test yes = "$enable_shared" || enable_static=yes
+  test "$enable_shared" = yes || enable_static=yes
   AC_MSG_RESULT([$enable_static])
 
   _LT_CONFIG($1)
 fi
 AC_LANG_POP
-CC=$lt_save_CC
+CC="$lt_save_CC"
 ])# _LT_LANG_C_CONFIG
 
 
@@ -6301,14 +5832,14 @@ CC=$lt_save_CC
 # --------------------------
 # Ensure that the configuration variables for a C++ compiler are suitably
 # defined.  These variables are subsequently used by _LT_CONFIG to write
-# the compiler configuration to 'libtool'.
+# the compiler configuration to `libtool'.
 m4_defun([_LT_LANG_CXX_CONFIG],
 [m4_require([_LT_FILEUTILS_DEFAULTS])dnl
 m4_require([_LT_DECL_EGREP])dnl
 m4_require([_LT_PATH_MANIFEST_TOOL])dnl
-if test -n "$CXX" && ( test no != "$CXX" &&
-    ( (test g++ = "$CXX" && `g++ -v >/dev/null 2>&1` ) ||
-    (test g++ != "$CXX"))); then
+if test -n "$CXX" && ( test "X$CXX" != "Xno" &&
+    ( (test "X$CXX" = "Xg++" && `g++ -v >/dev/null 2>&1` ) ||
+    (test "X$CXX" != "Xg++"))) ; then
   AC_PROG_CXXCPP
 else
   _lt_caught_CXX_error=yes
@@ -6350,7 +5881,7 @@ _LT_TAGVAR(objext, $1)=$objext
 # the CXX compiler isn't working.  Some variables (like enable_shared)
 # are currently assumed to apply to all compilers on this platform,
 # and will be corrupted by setting them based on a non-working compiler.
-if test yes != "$_lt_caught_CXX_error"; then
+if test "$_lt_caught_CXX_error" != yes; then
   # Code to be used in simple compile tests
   lt_simple_compile_test_code="int some_variable = 0;"
 
@@ -6392,35 +5923,35 @@ if test yes != "$_lt_caught_CXX_error"; then
   if test -n "$compiler"; then
     # We don't want -fno-exception when compiling C++ code, so set the
     # no_builtin_flag separately
-    if test yes = "$GXX"; then
+    if test "$GXX" = yes; then
       _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin'
     else
       _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=
     fi
 
-    if test yes = "$GXX"; then
+    if test "$GXX" = yes; then
       # Set up default GNU C++ configuration
 
       LT_PATH_LD
 
       # Check if GNU C++ uses GNU ld as the underlying linker, since the
       # archiving commands below assume that GNU ld is being used.
-      if test yes = "$with_gnu_ld"; then
-        _LT_TAGVAR(archive_cmds, $1)='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib'
-        _LT_TAGVAR(archive_expsym_cmds, $1)='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'
+      if test "$with_gnu_ld" = yes; then
+        _LT_TAGVAR(archive_cmds, $1)='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib'
+        _LT_TAGVAR(archive_expsym_cmds, $1)='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
 
-        _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir'
-        _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic'
+        _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+        _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic'
 
         # If archive_cmds runs LD, not CC, wlarc should be empty
         # XXX I think wlarc can be eliminated in ltcf-cxx, but I need to
         #     investigate it a little bit more. (MM)
-        wlarc='$wl'
+        wlarc='${wl}'
 
         # ancient GNU ld didn't support --whole-archive et. al.
         if eval "`$CC -print-prog-name=ld` --help 2>&1" |
 	  $GREP 'no-whole-archive' > /dev/null; then
-          _LT_TAGVAR(whole_archive_flag_spec, $1)=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive'
+          _LT_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive'
         else
           _LT_TAGVAR(whole_archive_flag_spec, $1)=
         fi
@@ -6456,30 +5987,18 @@ if test yes != "$_lt_caught_CXX_error"; then
         _LT_TAGVAR(ld_shlibs, $1)=no
         ;;
       aix[[4-9]]*)
-        if test ia64 = "$host_cpu"; then
+        if test "$host_cpu" = ia64; then
           # On IA64, the linker does run time linking by default, so we don't
           # have to do anything special.
           aix_use_runtimelinking=no
           exp_sym_flag='-Bexport'
-          no_entry_flag=
+          no_entry_flag=""
         else
           aix_use_runtimelinking=no
 
           # Test if we are trying to use run time linking or normal
           # AIX style linking. If -brtl is somewhere in LDFLAGS, we
-          # have runtime linking enabled, and use it for executables.
-          # For shared libraries, we enable/disable runtime linking
-          # depending on the kind of the shared library created -
-          # when "with_aix_soname,aix_use_runtimelinking" is:
-          # "aix,no"   lib.a(lib.so.V) shared, rtl:no,  for executables
-          # "aix,yes"  lib.so          shared, rtl:yes, for executables
-          #            lib.a           static archive
-          # "both,no"  lib.so.V(shr.o) shared, rtl:yes
-          #            lib.a(lib.so.V) shared, rtl:no,  for executables
-          # "both,yes" lib.so.V(shr.o) shared, rtl:yes, for executables
-          #            lib.a(lib.so.V) shared, rtl:no
-          # "svr4,*"   lib.so.V(shr.o) shared, rtl:yes, for executables
-          #            lib.a           static archive
+          # need to do runtime linking.
           case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*)
 	    for ld_flag in $LDFLAGS; do
 	      case $ld_flag in
@@ -6489,13 +6008,6 @@ if test yes != "$_lt_caught_CXX_error"; then
 	        ;;
 	      esac
 	    done
-	    if test svr4,no = "$with_aix_soname,$aix_use_runtimelinking"; then
-	      # With aix-soname=svr4, we create the lib.so.V shared archives only,
-	      # so we don't have lib.a shared libs to link our executables.
-	      # We have to force runtime linking in this case.
-	      aix_use_runtimelinking=yes
-	      LDFLAGS="$LDFLAGS -Wl,-brtl"
-	    fi
 	    ;;
           esac
 
@@ -6514,21 +6026,13 @@ if test yes != "$_lt_caught_CXX_error"; then
         _LT_TAGVAR(hardcode_direct_absolute, $1)=yes
         _LT_TAGVAR(hardcode_libdir_separator, $1)=':'
         _LT_TAGVAR(link_all_deplibs, $1)=yes
-        _LT_TAGVAR(file_list_spec, $1)='$wl-f,'
-        case $with_aix_soname,$aix_use_runtimelinking in
-        aix,*) ;;	# no import file
-        svr4,* | *,yes) # use import file
-          # The Import File defines what to hardcode.
-          _LT_TAGVAR(hardcode_direct, $1)=no
-          _LT_TAGVAR(hardcode_direct_absolute, $1)=no
-          ;;
-        esac
+        _LT_TAGVAR(file_list_spec, $1)='${wl}-f,'
 
-        if test yes = "$GXX"; then
+        if test "$GXX" = yes; then
           case $host_os in aix4.[[012]]|aix4.[[012]].*)
           # We only want to do this on AIX 4.2 and lower, the check
           # below for broken collect2 doesn't work under 4.3+
-	  collect2name=`$CC -print-prog-name=collect2`
+	  collect2name=`${CC} -print-prog-name=collect2`
 	  if test -f "$collect2name" &&
 	     strings "$collect2name" | $GREP resolve_lib_name >/dev/null
 	  then
@@ -6546,84 +6050,64 @@ if test yes != "$_lt_caught_CXX_error"; then
 	  fi
           esac
           shared_flag='-shared'
-	  if test yes = "$aix_use_runtimelinking"; then
-	    shared_flag=$shared_flag' $wl-G'
+	  if test "$aix_use_runtimelinking" = yes; then
+	    shared_flag="$shared_flag "'${wl}-G'
 	  fi
-	  # Need to ensure runtime linking is disabled for the traditional
-	  # shared library, or the linker may eventually find shared libraries
-	  # /with/ Import File - we do not want to mix them.
-	  shared_flag_aix='-shared'
-	  shared_flag_svr4='-shared $wl-G'
         else
           # not using gcc
-          if test ia64 = "$host_cpu"; then
+          if test "$host_cpu" = ia64; then
 	  # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release
 	  # chokes on -Wl,-G. The following line is correct:
 	  shared_flag='-G'
           else
-	    if test yes = "$aix_use_runtimelinking"; then
-	      shared_flag='$wl-G'
+	    if test "$aix_use_runtimelinking" = yes; then
+	      shared_flag='${wl}-G'
 	    else
-	      shared_flag='$wl-bM:SRE'
+	      shared_flag='${wl}-bM:SRE'
 	    fi
-	    shared_flag_aix='$wl-bM:SRE'
-	    shared_flag_svr4='$wl-G'
           fi
         fi
 
-        _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-bexpall'
+        _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-bexpall'
         # It seems that -bexpall does not export symbols beginning with
         # underscore (_), so it is better to generate a list of symbols to
 	# export.
         _LT_TAGVAR(always_export_symbols, $1)=yes
-	if test aix,yes = "$with_aix_soname,$aix_use_runtimelinking"; then
+        if test "$aix_use_runtimelinking" = yes; then
           # Warning - without using the other runtime loading flags (-brtl),
           # -berok will link without error, but may produce a broken library.
-          # The "-G" linker flag allows undefined symbols.
-          _LT_TAGVAR(no_undefined_flag, $1)='-bernotok'
+          _LT_TAGVAR(allow_undefined_flag, $1)='-berok'
           # Determine the default libpath from the value encoded in an empty
           # executable.
           _LT_SYS_MODULE_PATH_AIX([$1])
-          _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-blibpath:$libdir:'"$aix_libpath"
+          _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath"
 
-          _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs $wl'$no_entry_flag' $compiler_flags `if test -n "$allow_undefined_flag"; then func_echo_all "$wl$allow_undefined_flag"; else :; fi` $wl'$exp_sym_flag:\$export_symbols' '$shared_flag
+          _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then func_echo_all "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag"
         else
-          if test ia64 = "$host_cpu"; then
-	    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R $libdir:/usr/lib:/lib'
+          if test "$host_cpu" = ia64; then
+	    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $libdir:/usr/lib:/lib'
 	    _LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs"
-	    _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\$wl$no_entry_flag"' $compiler_flags $wl$allow_undefined_flag '"\$wl$exp_sym_flag:\$export_symbols"
+	    _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols"
           else
 	    # Determine the default libpath from the value encoded in an
 	    # empty executable.
 	    _LT_SYS_MODULE_PATH_AIX([$1])
-	    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-blibpath:$libdir:'"$aix_libpath"
+	    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath"
 	    # Warning - without using the other run time loading flags,
 	    # -berok will link without error, but may produce a broken library.
-	    _LT_TAGVAR(no_undefined_flag, $1)=' $wl-bernotok'
-	    _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-berok'
-	    if test yes = "$with_gnu_ld"; then
+	    _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-bernotok'
+	    _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-berok'
+	    if test "$with_gnu_ld" = yes; then
 	      # We only use this code for GNU lds that support --whole-archive.
-	      _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive$convenience $wl--no-whole-archive'
+	      _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive$convenience ${wl}--no-whole-archive'
 	    else
 	      # Exported symbols can be pulled into shared objects from archives
 	      _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience'
 	    fi
 	    _LT_TAGVAR(archive_cmds_need_lc, $1)=yes
-	    _LT_TAGVAR(archive_expsym_cmds, $1)='$RM -r $output_objdir/$realname.d~$MKDIR $output_objdir/$realname.d'
-	    # -brtl affects multiple linker settings, -berok does not and is overridden later
-	    compiler_flags_filtered='`func_echo_all "$compiler_flags " | $SED -e "s%-brtl\\([[, ]]\\)%-berok\\1%g"`'
-	    if test svr4 != "$with_aix_soname"; then
-	      # This is similar to how AIX traditionally builds its shared
-	      # libraries. Need -bnortl late, we may have -brtl in LDFLAGS.
-	      _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$CC '$shared_flag_aix' -o $output_objdir/$realname.d/$soname $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$realname.d/$soname'
-	    fi
-	    if test aix != "$with_aix_soname"; then
-	      _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$CC '$shared_flag_svr4' -o $output_objdir/$realname.d/$shared_archive_member_spec.o $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$STRIP -e $output_objdir/$realname.d/$shared_archive_member_spec.o~( func_echo_all "#! $soname($shared_archive_member_spec.o)"; if test shr_64 = "$shared_archive_member_spec"; then func_echo_all "# 64"; else func_echo_all "# [...]
-	    else
-	      # used by -dlpreopen to get the symbols
-	      _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$MV  $output_objdir/$realname.d/$soname $output_objdir'
-	    fi
-	    _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$RM -r $output_objdir/$realname.d'
+	    # This is similar to how AIX traditionally builds its shared
+	    # libraries.
+	    _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname'
           fi
         fi
         ;;
@@ -6633,7 +6117,7 @@ if test yes != "$_lt_caught_CXX_error"; then
 	  _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
 	  # Joseph Beckenbach <jrb3 at best.com> says some releases of gcc
 	  # support --undefined.  This deserves some investigation.  FIXME
-	  _LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+	  _LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
 	else
 	  _LT_TAGVAR(ld_shlibs, $1)=no
 	fi
@@ -6661,58 +6145,57 @@ if test yes != "$_lt_caught_CXX_error"; then
 	  # Tell ltmain to make .lib files, not .a files.
 	  libext=lib
 	  # Tell ltmain to make .dll files, not .so files.
-	  shrext_cmds=.dll
+	  shrext_cmds=".dll"
 	  # FIXME: Setting linknames here is a bad hack.
-	  _LT_TAGVAR(archive_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~linknames='
-	  _LT_TAGVAR(archive_expsym_cmds, $1)='if _LT_DLL_DEF_P([$export_symbols]); then
-              cp "$export_symbols" "$output_objdir/$soname.def";
-              echo "$tool_output_objdir$soname.def" > "$output_objdir/$soname.exp";
-            else
-              $SED -e '\''s/^/-link -EXPORT:/'\'' < $export_symbols > $output_objdir/$soname.exp;
-            fi~
-            $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~
-            linknames='
+	  _LT_TAGVAR(archive_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-dll~linknames='
+	  _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then
+	      $SED -n -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' -e '1\\\!p' < $export_symbols > $output_objdir/$soname.exp;
+	    else
+	      $SED -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' < $export_symbols > $output_objdir/$soname.exp;
+	    fi~
+	    $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~
+	    linknames='
 	  # The linker will not automatically build a static lib if we build a DLL.
 	  # _LT_TAGVAR(old_archive_from_new_cmds, $1)='true'
 	  _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
 	  # Don't use ranlib
 	  _LT_TAGVAR(old_postinstall_cmds, $1)='chmod 644 $oldlib'
 	  _LT_TAGVAR(postlink_cmds, $1)='lt_outputfile="@OUTPUT@"~
-            lt_tool_outputfile="@TOOL_OUTPUT@"~
-            case $lt_outputfile in
-              *.exe|*.EXE) ;;
-              *)
-                lt_outputfile=$lt_outputfile.exe
-                lt_tool_outputfile=$lt_tool_outputfile.exe
-                ;;
-            esac~
-            func_to_tool_file "$lt_outputfile"~
-            if test : != "$MANIFEST_TOOL" && test -f "$lt_outputfile.manifest"; then
-              $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1;
-              $RM "$lt_outputfile.manifest";
-            fi'
+	    lt_tool_outputfile="@TOOL_OUTPUT@"~
+	    case $lt_outputfile in
+	      *.exe|*.EXE) ;;
+	      *)
+		lt_outputfile="$lt_outputfile.exe"
+		lt_tool_outputfile="$lt_tool_outputfile.exe"
+		;;
+	    esac~
+	    func_to_tool_file "$lt_outputfile"~
+	    if test "$MANIFEST_TOOL" != ":" && test -f "$lt_outputfile.manifest"; then
+	      $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1;
+	      $RM "$lt_outputfile.manifest";
+	    fi'
 	  ;;
 	*)
 	  # g++
 	  # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless,
 	  # as there is no search path for DLLs.
 	  _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
-	  _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-all-symbols'
+	  _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-all-symbols'
 	  _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
 	  _LT_TAGVAR(always_export_symbols, $1)=no
 	  _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
 
 	  if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then
-	    _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
-	    # If the export-symbols file already is a .def file, use it as
-	    # is; otherwise, prepend EXPORTS...
-	    _LT_TAGVAR(archive_expsym_cmds, $1)='if _LT_DLL_DEF_P([$export_symbols]); then
-              cp $export_symbols $output_objdir/$soname.def;
-            else
-              echo EXPORTS > $output_objdir/$soname.def;
-              cat $export_symbols >> $output_objdir/$soname.def;
-            fi~
-            $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+	    _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+	    # If the export-symbols file already is a .def file (1st line
+	    # is EXPORTS), use it as is; otherwise, prepend...
+	    _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then
+	      cp $export_symbols $output_objdir/$soname.def;
+	    else
+	      echo EXPORTS > $output_objdir/$soname.def;
+	      cat $export_symbols >> $output_objdir/$soname.def;
+	    fi~
+	    $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
 	  else
 	    _LT_TAGVAR(ld_shlibs, $1)=no
 	  fi
@@ -6723,34 +6206,6 @@ if test yes != "$_lt_caught_CXX_error"; then
         _LT_DARWIN_LINKER_FEATURES($1)
 	;;
 
-      os2*)
-	_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
-	_LT_TAGVAR(hardcode_minus_L, $1)=yes
-	_LT_TAGVAR(allow_undefined_flag, $1)=unsupported
-	shrext_cmds=.dll
-	_LT_TAGVAR(archive_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~
-	  $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~
-	  $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~
-	  $ECHO EXPORTS >> $output_objdir/$libname.def~
-	  emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~
-	  $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~
-	  emximp -o $lib $output_objdir/$libname.def'
-	_LT_TAGVAR(archive_expsym_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~
-	  $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~
-	  $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~
-	  $ECHO EXPORTS >> $output_objdir/$libname.def~
-	  prefix_cmds="$SED"~
-	  if test EXPORTS = "`$SED 1q $export_symbols`"; then
-	    prefix_cmds="$prefix_cmds -e 1d";
-	  fi~
-	  prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~
-	  cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~
-	  $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~
-	  emximp -o $lib $output_objdir/$libname.def'
-	_LT_TAGVAR(old_archive_From_new_cmds, $1)='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def'
-	_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
-	;;
-
       dgux*)
         case $cc_basename in
           ec++*)
@@ -6786,14 +6241,14 @@ if test yes != "$_lt_caught_CXX_error"; then
         ;;
 
       haiku*)
-        _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+        _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
         _LT_TAGVAR(link_all_deplibs, $1)=yes
         ;;
 
       hpux9*)
-        _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir'
+        _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir'
         _LT_TAGVAR(hardcode_libdir_separator, $1)=:
-        _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E'
+        _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
         _LT_TAGVAR(hardcode_direct, $1)=yes
         _LT_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH,
 				             # but as the default
@@ -6805,7 +6260,7 @@ if test yes != "$_lt_caught_CXX_error"; then
             _LT_TAGVAR(ld_shlibs, $1)=no
             ;;
           aCC*)
-            _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -b $wl+b $wl$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib'
+            _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -b ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
             # Commands to make compiler produce verbose output that lists
             # what "hidden" libraries, object files and flags are used when
             # linking a shared library.
@@ -6814,11 +6269,11 @@ if test yes != "$_lt_caught_CXX_error"; then
             # explicitly linking system object files so we need to strip them
             # from the output so that they don't get included in the library
             # dependencies.
-            output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP "\-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
+            output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
             ;;
           *)
-            if test yes = "$GXX"; then
-              _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared -nostdlib $pic_flag $wl+b $wl$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib'
+            if test "$GXX" = yes; then
+              _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared -nostdlib $pic_flag ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
             else
               # FIXME: insert proper C++ library support
               _LT_TAGVAR(ld_shlibs, $1)=no
@@ -6828,15 +6283,15 @@ if test yes != "$_lt_caught_CXX_error"; then
         ;;
 
       hpux10*|hpux11*)
-        if test no = "$with_gnu_ld"; then
-	  _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir'
+        if test $with_gnu_ld = no; then
+	  _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir'
 	  _LT_TAGVAR(hardcode_libdir_separator, $1)=:
 
           case $host_cpu in
             hppa*64*|ia64*)
               ;;
             *)
-	      _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E'
+	      _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
               ;;
           esac
         fi
@@ -6862,13 +6317,13 @@ if test yes != "$_lt_caught_CXX_error"; then
           aCC*)
 	    case $host_cpu in
 	      hppa*64*)
-	        _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+	        _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
 	        ;;
 	      ia64*)
-	        _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+	        _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
 	        ;;
 	      *)
-	        _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+	        _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
 	        ;;
 	    esac
 	    # Commands to make compiler produce verbose output that lists
@@ -6879,20 +6334,20 @@ if test yes != "$_lt_caught_CXX_error"; then
 	    # explicitly linking system object files so we need to strip them
 	    # from the output so that they don't get included in the library
 	    # dependencies.
-	    output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP "\-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
+	    output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
 	    ;;
           *)
-	    if test yes = "$GXX"; then
-	      if test no = "$with_gnu_ld"; then
+	    if test "$GXX" = yes; then
+	      if test $with_gnu_ld = no; then
 	        case $host_cpu in
 	          hppa*64*)
-	            _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC $wl+h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+	            _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
 	            ;;
 	          ia64*)
-	            _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $pic_flag $wl+h $wl$soname $wl+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+	            _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $pic_flag ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
 	            ;;
 	          *)
-	            _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+	            _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
 	            ;;
 	        esac
 	      fi
@@ -6907,22 +6362,22 @@ if test yes != "$_lt_caught_CXX_error"; then
       interix[[3-9]]*)
 	_LT_TAGVAR(hardcode_direct, $1)=no
 	_LT_TAGVAR(hardcode_shlibpath_var, $1)=no
-	_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir'
-	_LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E'
+	_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
+	_LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
 	# Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc.
 	# Instead, shared libraries are loaded at an image base (0x10000000 by
 	# default) and relocated if they conflict, which is a slow very memory
 	# consuming and fragmenting process.  To avoid this, we pick a random,
 	# 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link
 	# time.  Moving up from 0x10000000 also allows more sbrk(2) space.
-	_LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
-	_LT_TAGVAR(archive_expsym_cmds, $1)='sed "s|^|_|" $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--retain-symbols-file,$output_objdir/$soname.expsym $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+	_LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+	_LT_TAGVAR(archive_expsym_cmds, $1)='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
 	;;
       irix5* | irix6*)
         case $cc_basename in
           CC*)
 	    # SGI C++
-	    _LT_TAGVAR(archive_cmds, $1)='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib'
+	    _LT_TAGVAR(archive_cmds, $1)='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib'
 
 	    # Archives containing C++ object files must be created using
 	    # "CC -ar", where "CC" is the IRIX C++ compiler.  This is
@@ -6931,17 +6386,17 @@ if test yes != "$_lt_caught_CXX_error"; then
 	    _LT_TAGVAR(old_archive_cmds, $1)='$CC -ar -WR,-u -o $oldlib $oldobjs'
 	    ;;
           *)
-	    if test yes = "$GXX"; then
-	      if test no = "$with_gnu_ld"; then
-	        _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib'
+	    if test "$GXX" = yes; then
+	      if test "$with_gnu_ld" = no; then
+	        _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
 	      else
-	        _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` -o $lib'
+	        _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` -o $lib'
 	      fi
 	    fi
 	    _LT_TAGVAR(link_all_deplibs, $1)=yes
 	    ;;
         esac
-        _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir'
+        _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
         _LT_TAGVAR(hardcode_libdir_separator, $1)=:
         _LT_TAGVAR(inherit_rpath, $1)=yes
         ;;
@@ -6954,8 +6409,8 @@ if test yes != "$_lt_caught_CXX_error"; then
 	    # KCC will only create a shared library if the output file
 	    # ends with ".so" (or ".sl" for HP-UX), so rename the library
 	    # to its proper name (with version) after linking.
-	    _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib'
-	    _LT_TAGVAR(archive_expsym_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib $wl-retain-symbols-file,$export_symbols; mv \$templib $lib'
+	    _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib'
+	    _LT_TAGVAR(archive_expsym_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib ${wl}-retain-symbols-file,$export_symbols; mv \$templib $lib'
 	    # Commands to make compiler produce verbose output that lists
 	    # what "hidden" libraries, object files and flags are used when
 	    # linking a shared library.
@@ -6964,10 +6419,10 @@ if test yes != "$_lt_caught_CXX_error"; then
 	    # explicitly linking system object files so we need to strip them
 	    # from the output so that they don't get included in the library
 	    # dependencies.
-	    output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | $GREP "ld"`; rm -f libconftest$shared_ext; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
+	    output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | $GREP "ld"`; rm -f libconftest$shared_ext; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
 
-	    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir'
-	    _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic'
+	    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
+	    _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic'
 
 	    # Archives containing C++ object files must be created using
 	    # "CC -Bstatic", where "CC" is the KAI C++ compiler.
@@ -6981,59 +6436,59 @@ if test yes != "$_lt_caught_CXX_error"; then
 	    # earlier do not add the objects themselves.
 	    case `$CC -V 2>&1` in
 	      *"Version 7."*)
-	        _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib'
-		_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'
+	        _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib'
+		_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
 		;;
 	      *)  # Version 8.0 or newer
 	        tmp_idyn=
 	        case $host_cpu in
 		  ia64*) tmp_idyn=' -i_dynamic';;
 		esac
-	        _LT_TAGVAR(archive_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
-		_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'
+	        _LT_TAGVAR(archive_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+		_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
 		;;
 	    esac
 	    _LT_TAGVAR(archive_cmds_need_lc, $1)=no
-	    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir'
-	    _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic'
-	    _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive$convenience $wl--no-whole-archive'
+	    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
+	    _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic'
+	    _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive$convenience ${wl}--no-whole-archive'
 	    ;;
           pgCC* | pgcpp*)
             # Portland Group C++ compiler
 	    case `$CC -V` in
 	    *pgCC\ [[1-5]].* | *pgcpp\ [[1-5]].*)
 	      _LT_TAGVAR(prelink_cmds, $1)='tpldir=Template.dir~
-               rm -rf $tpldir~
-               $CC --prelink_objects --instantiation_dir $tpldir $objs $libobjs $compile_deplibs~
-               compile_command="$compile_command `find $tpldir -name \*.o | sort | $NL2SP`"'
+		rm -rf $tpldir~
+		$CC --prelink_objects --instantiation_dir $tpldir $objs $libobjs $compile_deplibs~
+		compile_command="$compile_command `find $tpldir -name \*.o | sort | $NL2SP`"'
 	      _LT_TAGVAR(old_archive_cmds, $1)='tpldir=Template.dir~
-                rm -rf $tpldir~
-                $CC --prelink_objects --instantiation_dir $tpldir $oldobjs$old_deplibs~
-                $AR $AR_FLAGS $oldlib$oldobjs$old_deplibs `find $tpldir -name \*.o | sort | $NL2SP`~
-                $RANLIB $oldlib'
+		rm -rf $tpldir~
+		$CC --prelink_objects --instantiation_dir $tpldir $oldobjs$old_deplibs~
+		$AR $AR_FLAGS $oldlib$oldobjs$old_deplibs `find $tpldir -name \*.o | sort | $NL2SP`~
+		$RANLIB $oldlib'
 	      _LT_TAGVAR(archive_cmds, $1)='tpldir=Template.dir~
-                rm -rf $tpldir~
-                $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~
-                $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib'
+		rm -rf $tpldir~
+		$CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~
+		$CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib'
 	      _LT_TAGVAR(archive_expsym_cmds, $1)='tpldir=Template.dir~
-                rm -rf $tpldir~
-                $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~
-                $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'
+		rm -rf $tpldir~
+		$CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~
+		$CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib'
 	      ;;
 	    *) # Version 6 and above use weak symbols
-	      _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib'
-	      _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'
+	      _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib'
+	      _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib'
 	      ;;
 	    esac
 
-	    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl--rpath $wl$libdir'
-	    _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic'
-	    _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive'
+	    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}--rpath ${wl}$libdir'
+	    _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic'
+	    _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
             ;;
 	  cxx*)
 	    # Compaq C++
-	    _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib'
-	    _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname  -o $lib $wl-retain-symbols-file $wl$export_symbols'
+	    _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib'
+	    _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname  -o $lib ${wl}-retain-symbols-file $wl$export_symbols'
 
 	    runpath_var=LD_RUN_PATH
 	    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir'
@@ -7047,18 +6502,18 @@ if test yes != "$_lt_caught_CXX_error"; then
 	    # explicitly linking system object files so we need to strip them
 	    # from the output so that they don't get included in the library
 	    # dependencies.
-	    output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "X$list" | $Xsed'
+	    output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "X$list" | $Xsed'
 	    ;;
 	  xl* | mpixl* | bgxl*)
 	    # IBM XL 8.0 on PPC, with GNU ld
-	    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir'
-	    _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic'
-	    _LT_TAGVAR(archive_cmds, $1)='$CC -qmkshrobj $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
-	    if test yes = "$supports_anon_versioning"; then
+	    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+	    _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic'
+	    _LT_TAGVAR(archive_cmds, $1)='$CC -qmkshrobj $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+	    if test "x$supports_anon_versioning" = xyes; then
 	      _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~
-                cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
-                echo "local: *; };" >> $output_objdir/$libname.ver~
-                $CC -qmkshrobj $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-version-script $wl$output_objdir/$libname.ver -o $lib'
+		cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
+		echo "local: *; };" >> $output_objdir/$libname.ver~
+		$CC -qmkshrobj $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib'
 	    fi
 	    ;;
 	  *)
@@ -7066,10 +6521,10 @@ if test yes != "$_lt_caught_CXX_error"; then
 	    *Sun\ C*)
 	      # Sun C++ 5.9
 	      _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs'
-	      _LT_TAGVAR(archive_cmds, $1)='$CC -G$allow_undefined_flag -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
-	      _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G$allow_undefined_flag -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-retain-symbols-file $wl$export_symbols'
+	      _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+	      _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file ${wl}$export_symbols'
 	      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
-	      _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive'
+	      _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
 	      _LT_TAGVAR(compiler_needs_object, $1)=yes
 
 	      # Not sure whether something based on
@@ -7127,17 +6582,22 @@ if test yes != "$_lt_caught_CXX_error"; then
         _LT_TAGVAR(ld_shlibs, $1)=yes
 	;;
 
-      openbsd* | bitrig*)
+      openbsd2*)
+        # C++ shared libraries are fairly broken
+	_LT_TAGVAR(ld_shlibs, $1)=no
+	;;
+
+      openbsd*)
 	if test -f /usr/libexec/ld.so; then
 	  _LT_TAGVAR(hardcode_direct, $1)=yes
 	  _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
 	  _LT_TAGVAR(hardcode_direct_absolute, $1)=yes
 	  _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib'
-	  _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir'
-	  if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`"; then
-	    _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-retain-symbols-file,$export_symbols -o $lib'
-	    _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E'
-	    _LT_TAGVAR(whole_archive_flag_spec, $1)=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive'
+	  _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
+	  if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+	    _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file,$export_symbols -o $lib'
+	    _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
+	    _LT_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive'
 	  fi
 	  output_verbose_link_cmd=func_echo_all
 	else
@@ -7153,9 +6613,9 @@ if test yes != "$_lt_caught_CXX_error"; then
 	    # KCC will only create a shared library if the output file
 	    # ends with ".so" (or ".sl" for HP-UX), so rename the library
 	    # to its proper name (with version) after linking.
-	    _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo "$lib" | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib'
+	    _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo "$lib" | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib'
 
-	    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir'
+	    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
 	    _LT_TAGVAR(hardcode_libdir_separator, $1)=:
 
 	    # Archives containing C++ object files must be created using
@@ -7173,17 +6633,17 @@ if test yes != "$_lt_caught_CXX_error"; then
           cxx*)
 	    case $host in
 	      osf3*)
-	        _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-expect_unresolved $wl\*'
-	        _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $soname `test -n "$verstring" && func_echo_all "$wl-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib'
-	        _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir'
+	        _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*'
+	        _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $soname `test -n "$verstring" && func_echo_all "${wl}-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib'
+	        _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
 		;;
 	      *)
 	        _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*'
-	        _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib'
+	        _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib'
 	        _LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done~
-                  echo "-hidden">> $lib.exp~
-                  $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname $wl-input $wl$lib.exp  `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib~
-                  $RM $lib.exp'
+	          echo "-hidden">> $lib.exp~
+	          $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname ${wl}-input ${wl}$lib.exp  `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib~
+	          $RM $lib.exp'
 	        _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir'
 		;;
 	    esac
@@ -7198,21 +6658,21 @@ if test yes != "$_lt_caught_CXX_error"; then
 	    # explicitly linking system object files so we need to strip them
 	    # from the output so that they don't get included in the library
 	    # dependencies.
-	    output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld" | $GREP -v "ld:"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
+	    output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld" | $GREP -v "ld:"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
 	    ;;
 	  *)
-	    if test yes,no = "$GXX,$with_gnu_ld"; then
-	      _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-expect_unresolved $wl\*'
+	    if test "$GXX" = yes && test "$with_gnu_ld" = no; then
+	      _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*'
 	      case $host in
 	        osf3*)
-	          _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib'
+	          _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
 		  ;;
 	        *)
-	          _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-msym $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib'
+	          _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
 		  ;;
 	      esac
 
-	      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir'
+	      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
 	      _LT_TAGVAR(hardcode_libdir_separator, $1)=:
 
 	      # Commands to make compiler produce verbose output that lists
@@ -7258,9 +6718,9 @@ if test yes != "$_lt_caught_CXX_error"; then
 	    # Sun C++ 4.2, 5.x and Centerline C++
             _LT_TAGVAR(archive_cmds_need_lc,$1)=yes
 	    _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs'
-	    _LT_TAGVAR(archive_cmds, $1)='$CC -G$allow_undefined_flag -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+	    _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag}  -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
 	    _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
-              $CC -G$allow_undefined_flag $wl-M $wl$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp'
+	      $CC -G${allow_undefined_flag} ${wl}-M ${wl}$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp'
 
 	    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
 	    _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
@@ -7268,7 +6728,7 @@ if test yes != "$_lt_caught_CXX_error"; then
 	      solaris2.[[0-5]] | solaris2.[[0-5]].*) ;;
 	      *)
 		# The compiler driver will combine and reorder linker options,
-		# but understands '-z linker_flag'.
+		# but understands `-z linker_flag'.
 	        # Supported since Solaris 2.6 (maybe 2.5.1?)
 		_LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract'
 	        ;;
@@ -7285,30 +6745,30 @@ if test yes != "$_lt_caught_CXX_error"; then
 	    ;;
           gcx*)
 	    # Green Hills C++ Compiler
-	    _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-h $wl$soname -o $lib'
+	    _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib'
 
 	    # The C++ compiler must be used to create the archive.
 	    _LT_TAGVAR(old_archive_cmds, $1)='$CC $LDFLAGS -archive -o $oldlib $oldobjs'
 	    ;;
           *)
 	    # GNU C++ compiler with Solaris linker
-	    if test yes,no = "$GXX,$with_gnu_ld"; then
-	      _LT_TAGVAR(no_undefined_flag, $1)=' $wl-z ${wl}defs'
+	    if test "$GXX" = yes && test "$with_gnu_ld" = no; then
+	      _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-z ${wl}defs'
 	      if $CC --version | $GREP -v '^2\.7' > /dev/null; then
-	        _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-h $wl$soname -o $lib'
+	        _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib'
 	        _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
-                  $CC -shared $pic_flag -nostdlib $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp'
+		  $CC -shared $pic_flag -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp'
 
 	        # Commands to make compiler produce verbose output that lists
 	        # what "hidden" libraries, object files and flags are used when
 	        # linking a shared library.
 	        output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"'
 	      else
-	        # g++ 2.7 appears to require '-G' NOT '-shared' on this
+	        # g++ 2.7 appears to require `-G' NOT `-shared' on this
 	        # platform.
-	        _LT_TAGVAR(archive_cmds, $1)='$CC -G -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-h $wl$soname -o $lib'
+	        _LT_TAGVAR(archive_cmds, $1)='$CC -G -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib'
 	        _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
-                  $CC -G -nostdlib $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp'
+		  $CC -G -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp'
 
 	        # Commands to make compiler produce verbose output that lists
 	        # what "hidden" libraries, object files and flags are used when
@@ -7316,11 +6776,11 @@ if test yes != "$_lt_caught_CXX_error"; then
 	        output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"'
 	      fi
 
-	      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R $wl$libdir'
+	      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $wl$libdir'
 	      case $host_os in
 		solaris2.[[0-5]] | solaris2.[[0-5]].*) ;;
 		*)
-		  _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl-z ${wl}allextract$convenience $wl-z ${wl}defaultextract'
+		  _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract'
 		  ;;
 	      esac
 	    fi
@@ -7329,52 +6789,52 @@ if test yes != "$_lt_caught_CXX_error"; then
         ;;
 
     sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*)
-      _LT_TAGVAR(no_undefined_flag, $1)='$wl-z,text'
+      _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text'
       _LT_TAGVAR(archive_cmds_need_lc, $1)=no
       _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
       runpath_var='LD_RUN_PATH'
 
       case $cc_basename in
         CC*)
-	  _LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
-	  _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	  _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	  _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
 	  ;;
 	*)
-	  _LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
-	  _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	  _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	  _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
 	  ;;
       esac
       ;;
 
       sysv5* | sco3.2v5* | sco5v6*)
-	# Note: We CANNOT use -z defs as we might desire, because we do not
+	# Note: We can NOT use -z defs as we might desire, because we do not
 	# link with -lc, and that would cause any symbols used from libc to
 	# always be unresolved, which means just about no library would
 	# ever link correctly.  If we're not using GNU ld we use -z text
 	# though, which does catch some bad symbols but isn't as heavy-handed
 	# as -z defs.
-	_LT_TAGVAR(no_undefined_flag, $1)='$wl-z,text'
-	_LT_TAGVAR(allow_undefined_flag, $1)='$wl-z,nodefs'
+	_LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text'
+	_LT_TAGVAR(allow_undefined_flag, $1)='${wl}-z,nodefs'
 	_LT_TAGVAR(archive_cmds_need_lc, $1)=no
 	_LT_TAGVAR(hardcode_shlibpath_var, $1)=no
-	_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R,$libdir'
+	_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R,$libdir'
 	_LT_TAGVAR(hardcode_libdir_separator, $1)=':'
 	_LT_TAGVAR(link_all_deplibs, $1)=yes
-	_LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-Bexport'
+	_LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Bexport'
 	runpath_var='LD_RUN_PATH'
 
 	case $cc_basename in
           CC*)
-	    _LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
-	    _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	    _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	    _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
 	    _LT_TAGVAR(old_archive_cmds, $1)='$CC -Tprelink_objects $oldobjs~
-              '"$_LT_TAGVAR(old_archive_cmds, $1)"
+	      '"$_LT_TAGVAR(old_archive_cmds, $1)"
 	    _LT_TAGVAR(reload_cmds, $1)='$CC -Tprelink_objects $reload_objs~
-              '"$_LT_TAGVAR(reload_cmds, $1)"
+	      '"$_LT_TAGVAR(reload_cmds, $1)"
 	    ;;
 	  *)
-	    _LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
-	    _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	    _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	    _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
 	    ;;
 	esac
       ;;
@@ -7405,10 +6865,10 @@ if test yes != "$_lt_caught_CXX_error"; then
     esac
 
     AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)])
-    test no = "$_LT_TAGVAR(ld_shlibs, $1)" && can_build_shared=no
+    test "$_LT_TAGVAR(ld_shlibs, $1)" = no && can_build_shared=no
 
-    _LT_TAGVAR(GCC, $1)=$GXX
-    _LT_TAGVAR(LD, $1)=$LD
+    _LT_TAGVAR(GCC, $1)="$GXX"
+    _LT_TAGVAR(LD, $1)="$LD"
 
     ## CAVEAT EMPTOR:
     ## There is no encapsulation within the following macros, do not change
@@ -7435,7 +6895,7 @@ if test yes != "$_lt_caught_CXX_error"; then
   lt_cv_path_LD=$lt_save_path_LD
   lt_cv_prog_gnu_ldcxx=$lt_cv_prog_gnu_ld
   lt_cv_prog_gnu_ld=$lt_save_with_gnu_ld
-fi # test yes != "$_lt_caught_CXX_error"
+fi # test "$_lt_caught_CXX_error" != yes
 
 AC_LANG_POP
 ])# _LT_LANG_CXX_CONFIG
@@ -7457,14 +6917,13 @@ AC_REQUIRE([_LT_DECL_SED])
 AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH])
 func_stripname_cnf ()
 {
-  case @S|@2 in
-  .*) func_stripname_result=`$ECHO "@S|@3" | $SED "s%^@S|@1%%; s%\\\\@S|@2\$%%"`;;
-  *)  func_stripname_result=`$ECHO "@S|@3" | $SED "s%^@S|@1%%; s%@S|@2\$%%"`;;
+  case ${2} in
+  .*) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%\\\\${2}\$%%"`;;
+  *)  func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%${2}\$%%"`;;
   esac
 } # func_stripname_cnf
 ])# _LT_FUNC_STRIPNAME_CNF
 
-
 # _LT_SYS_HIDDEN_LIBDEPS([TAGNAME])
 # ---------------------------------
 # Figure out "hidden" library dependencies from verbose
@@ -7548,13 +7007,13 @@ if AC_TRY_EVAL(ac_compile); then
   pre_test_object_deps_done=no
 
   for p in `eval "$output_verbose_link_cmd"`; do
-    case $prev$p in
+    case ${prev}${p} in
 
     -L* | -R* | -l*)
        # Some compilers place space between "-{L,R}" and the path.
        # Remove the space.
-       if test x-L = "$p" ||
-          test x-R = "$p"; then
+       if test $p = "-L" ||
+          test $p = "-R"; then
 	 prev=$p
 	 continue
        fi
@@ -7570,16 +7029,16 @@ if AC_TRY_EVAL(ac_compile); then
        case $p in
        =*) func_stripname_cnf '=' '' "$p"; p=$lt_sysroot$func_stripname_result ;;
        esac
-       if test no = "$pre_test_object_deps_done"; then
-	 case $prev in
+       if test "$pre_test_object_deps_done" = no; then
+	 case ${prev} in
 	 -L | -R)
 	   # Internal compiler library paths should come after those
 	   # provided the user.  The postdeps already come after the
 	   # user supplied libs so there is no need to process them.
 	   if test -z "$_LT_TAGVAR(compiler_lib_search_path, $1)"; then
-	     _LT_TAGVAR(compiler_lib_search_path, $1)=$prev$p
+	     _LT_TAGVAR(compiler_lib_search_path, $1)="${prev}${p}"
 	   else
-	     _LT_TAGVAR(compiler_lib_search_path, $1)="${_LT_TAGVAR(compiler_lib_search_path, $1)} $prev$p"
+	     _LT_TAGVAR(compiler_lib_search_path, $1)="${_LT_TAGVAR(compiler_lib_search_path, $1)} ${prev}${p}"
 	   fi
 	   ;;
 	 # The "-l" case would never come before the object being
@@ -7587,9 +7046,9 @@ if AC_TRY_EVAL(ac_compile); then
 	 esac
        else
 	 if test -z "$_LT_TAGVAR(postdeps, $1)"; then
-	   _LT_TAGVAR(postdeps, $1)=$prev$p
+	   _LT_TAGVAR(postdeps, $1)="${prev}${p}"
 	 else
-	   _LT_TAGVAR(postdeps, $1)="${_LT_TAGVAR(postdeps, $1)} $prev$p"
+	   _LT_TAGVAR(postdeps, $1)="${_LT_TAGVAR(postdeps, $1)} ${prev}${p}"
 	 fi
        fi
        prev=
@@ -7604,15 +7063,15 @@ if AC_TRY_EVAL(ac_compile); then
 	 continue
        fi
 
-       if test no = "$pre_test_object_deps_done"; then
+       if test "$pre_test_object_deps_done" = no; then
 	 if test -z "$_LT_TAGVAR(predep_objects, $1)"; then
-	   _LT_TAGVAR(predep_objects, $1)=$p
+	   _LT_TAGVAR(predep_objects, $1)="$p"
 	 else
 	   _LT_TAGVAR(predep_objects, $1)="$_LT_TAGVAR(predep_objects, $1) $p"
 	 fi
        else
 	 if test -z "$_LT_TAGVAR(postdep_objects, $1)"; then
-	   _LT_TAGVAR(postdep_objects, $1)=$p
+	   _LT_TAGVAR(postdep_objects, $1)="$p"
 	 else
 	   _LT_TAGVAR(postdep_objects, $1)="$_LT_TAGVAR(postdep_objects, $1) $p"
 	 fi
@@ -7643,6 +7102,51 @@ interix[[3-9]]*)
   _LT_TAGVAR(postdep_objects,$1)=
   _LT_TAGVAR(postdeps,$1)=
   ;;
+
+linux*)
+  case `$CC -V 2>&1 | sed 5q` in
+  *Sun\ C*)
+    # Sun C++ 5.9
+
+    # The more standards-conforming stlport4 library is
+    # incompatible with the Cstd library. Avoid specifying
+    # it if it's in CXXFLAGS. Ignore libCrun as
+    # -library=stlport4 depends on it.
+    case " $CXX $CXXFLAGS " in
+    *" -library=stlport4 "*)
+      solaris_use_stlport4=yes
+      ;;
+    esac
+
+    if test "$solaris_use_stlport4" != yes; then
+      _LT_TAGVAR(postdeps,$1)='-library=Cstd -library=Crun'
+    fi
+    ;;
+  esac
+  ;;
+
+solaris*)
+  case $cc_basename in
+  CC* | sunCC*)
+    # The more standards-conforming stlport4 library is
+    # incompatible with the Cstd library. Avoid specifying
+    # it if it's in CXXFLAGS. Ignore libCrun as
+    # -library=stlport4 depends on it.
+    case " $CXX $CXXFLAGS " in
+    *" -library=stlport4 "*)
+      solaris_use_stlport4=yes
+      ;;
+    esac
+
+    # Adding this requires a known-good setup of shared libraries for
+    # Sun compiler versions before 5.6, else PIC objects from an old
+    # archive will be linked into the output, leading to subtle bugs.
+    if test "$solaris_use_stlport4" != yes; then
+      _LT_TAGVAR(postdeps,$1)='-library=Cstd -library=Crun'
+    fi
+    ;;
+  esac
+  ;;
 esac
 ])
 
@@ -7651,7 +7155,7 @@ case " $_LT_TAGVAR(postdeps, $1) " in
 esac
  _LT_TAGVAR(compiler_lib_search_dirs, $1)=
 if test -n "${_LT_TAGVAR(compiler_lib_search_path, $1)}"; then
- _LT_TAGVAR(compiler_lib_search_dirs, $1)=`echo " ${_LT_TAGVAR(compiler_lib_search_path, $1)}" | $SED -e 's! -L! !g' -e 's!^ !!'`
+ _LT_TAGVAR(compiler_lib_search_dirs, $1)=`echo " ${_LT_TAGVAR(compiler_lib_search_path, $1)}" | ${SED} -e 's! -L! !g' -e 's!^ !!'`
 fi
 _LT_TAGDECL([], [compiler_lib_search_dirs], [1],
     [The directories searched by this compiler when creating a shared library])
@@ -7671,10 +7175,10 @@ _LT_TAGDECL([], [compiler_lib_search_path], [1],
 # --------------------------
 # Ensure that the configuration variables for a Fortran 77 compiler are
 # suitably defined.  These variables are subsequently used by _LT_CONFIG
-# to write the compiler configuration to 'libtool'.
+# to write the compiler configuration to `libtool'.
 m4_defun([_LT_LANG_F77_CONFIG],
 [AC_LANG_PUSH(Fortran 77)
-if test -z "$F77" || test no = "$F77"; then
+if test -z "$F77" || test "X$F77" = "Xno"; then
   _lt_disable_F77=yes
 fi
 
@@ -7711,7 +7215,7 @@ _LT_TAGVAR(objext, $1)=$objext
 # the F77 compiler isn't working.  Some variables (like enable_shared)
 # are currently assumed to apply to all compilers on this platform,
 # and will be corrupted by setting them based on a non-working compiler.
-if test yes != "$_lt_disable_F77"; then
+if test "$_lt_disable_F77" != yes; then
   # Code to be used in simple compile tests
   lt_simple_compile_test_code="\
       subroutine t
@@ -7733,7 +7237,7 @@ if test yes != "$_lt_disable_F77"; then
   _LT_LINKER_BOILERPLATE
 
   # Allow CC to be a program name with arguments.
-  lt_save_CC=$CC
+  lt_save_CC="$CC"
   lt_save_GCC=$GCC
   lt_save_CFLAGS=$CFLAGS
   CC=${F77-"f77"}
@@ -7747,25 +7251,21 @@ if test yes != "$_lt_disable_F77"; then
     AC_MSG_RESULT([$can_build_shared])
 
     AC_MSG_CHECKING([whether to build shared libraries])
-    test no = "$can_build_shared" && enable_shared=no
+    test "$can_build_shared" = "no" && enable_shared=no
 
     # On AIX, shared libraries and static libraries use the same namespace, and
     # are all built from PIC.
     case $host_os in
       aix3*)
-        test yes = "$enable_shared" && enable_static=no
+        test "$enable_shared" = yes && enable_static=no
         if test -n "$RANLIB"; then
           archive_cmds="$archive_cmds~\$RANLIB \$lib"
           postinstall_cmds='$RANLIB $lib'
         fi
         ;;
       aix[[4-9]]*)
-	if test ia64 != "$host_cpu"; then
-	  case $enable_shared,$with_aix_soname,$aix_use_runtimelinking in
-	  yes,aix,yes) ;;		# shared object as lib.so file only
-	  yes,svr4,*) ;;		# shared object as lib.so archive member only
-	  yes,*) enable_static=no ;;	# shared object in lib.a archive as well
-	  esac
+	if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then
+	  test "$enable_shared" = yes && enable_static=no
 	fi
         ;;
     esac
@@ -7773,11 +7273,11 @@ if test yes != "$_lt_disable_F77"; then
 
     AC_MSG_CHECKING([whether to build static libraries])
     # Make sure either enable_shared or enable_static is yes.
-    test yes = "$enable_shared" || enable_static=yes
+    test "$enable_shared" = yes || enable_static=yes
     AC_MSG_RESULT([$enable_static])
 
-    _LT_TAGVAR(GCC, $1)=$G77
-    _LT_TAGVAR(LD, $1)=$LD
+    _LT_TAGVAR(GCC, $1)="$G77"
+    _LT_TAGVAR(LD, $1)="$LD"
 
     ## CAVEAT EMPTOR:
     ## There is no encapsulation within the following macros, do not change
@@ -7794,9 +7294,9 @@ if test yes != "$_lt_disable_F77"; then
   fi # test -n "$compiler"
 
   GCC=$lt_save_GCC
-  CC=$lt_save_CC
-  CFLAGS=$lt_save_CFLAGS
-fi # test yes != "$_lt_disable_F77"
+  CC="$lt_save_CC"
+  CFLAGS="$lt_save_CFLAGS"
+fi # test "$_lt_disable_F77" != yes
 
 AC_LANG_POP
 ])# _LT_LANG_F77_CONFIG
@@ -7806,11 +7306,11 @@ AC_LANG_POP
 # -------------------------
 # Ensure that the configuration variables for a Fortran compiler are
 # suitably defined.  These variables are subsequently used by _LT_CONFIG
-# to write the compiler configuration to 'libtool'.
+# to write the compiler configuration to `libtool'.
 m4_defun([_LT_LANG_FC_CONFIG],
 [AC_LANG_PUSH(Fortran)
 
-if test -z "$FC" || test no = "$FC"; then
+if test -z "$FC" || test "X$FC" = "Xno"; then
   _lt_disable_FC=yes
 fi
 
@@ -7847,7 +7347,7 @@ _LT_TAGVAR(objext, $1)=$objext
 # the FC compiler isn't working.  Some variables (like enable_shared)
 # are currently assumed to apply to all compilers on this platform,
 # and will be corrupted by setting them based on a non-working compiler.
-if test yes != "$_lt_disable_FC"; then
+if test "$_lt_disable_FC" != yes; then
   # Code to be used in simple compile tests
   lt_simple_compile_test_code="\
       subroutine t
@@ -7869,7 +7369,7 @@ if test yes != "$_lt_disable_FC"; then
   _LT_LINKER_BOILERPLATE
 
   # Allow CC to be a program name with arguments.
-  lt_save_CC=$CC
+  lt_save_CC="$CC"
   lt_save_GCC=$GCC
   lt_save_CFLAGS=$CFLAGS
   CC=${FC-"f95"}
@@ -7885,25 +7385,21 @@ if test yes != "$_lt_disable_FC"; then
     AC_MSG_RESULT([$can_build_shared])
 
     AC_MSG_CHECKING([whether to build shared libraries])
-    test no = "$can_build_shared" && enable_shared=no
+    test "$can_build_shared" = "no" && enable_shared=no
 
     # On AIX, shared libraries and static libraries use the same namespace, and
     # are all built from PIC.
     case $host_os in
       aix3*)
-        test yes = "$enable_shared" && enable_static=no
+        test "$enable_shared" = yes && enable_static=no
         if test -n "$RANLIB"; then
           archive_cmds="$archive_cmds~\$RANLIB \$lib"
           postinstall_cmds='$RANLIB $lib'
         fi
         ;;
       aix[[4-9]]*)
-	if test ia64 != "$host_cpu"; then
-	  case $enable_shared,$with_aix_soname,$aix_use_runtimelinking in
-	  yes,aix,yes) ;;		# shared object as lib.so file only
-	  yes,svr4,*) ;;		# shared object as lib.so archive member only
-	  yes,*) enable_static=no ;;	# shared object in lib.a archive as well
-	  esac
+	if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then
+	  test "$enable_shared" = yes && enable_static=no
 	fi
         ;;
     esac
@@ -7911,11 +7407,11 @@ if test yes != "$_lt_disable_FC"; then
 
     AC_MSG_CHECKING([whether to build static libraries])
     # Make sure either enable_shared or enable_static is yes.
-    test yes = "$enable_shared" || enable_static=yes
+    test "$enable_shared" = yes || enable_static=yes
     AC_MSG_RESULT([$enable_static])
 
-    _LT_TAGVAR(GCC, $1)=$ac_cv_fc_compiler_gnu
-    _LT_TAGVAR(LD, $1)=$LD
+    _LT_TAGVAR(GCC, $1)="$ac_cv_fc_compiler_gnu"
+    _LT_TAGVAR(LD, $1)="$LD"
 
     ## CAVEAT EMPTOR:
     ## There is no encapsulation within the following macros, do not change
@@ -7935,7 +7431,7 @@ if test yes != "$_lt_disable_FC"; then
   GCC=$lt_save_GCC
   CC=$lt_save_CC
   CFLAGS=$lt_save_CFLAGS
-fi # test yes != "$_lt_disable_FC"
+fi # test "$_lt_disable_FC" != yes
 
 AC_LANG_POP
 ])# _LT_LANG_FC_CONFIG
@@ -7945,7 +7441,7 @@ AC_LANG_POP
 # --------------------------
 # Ensure that the configuration variables for the GNU Java Compiler compiler
 # are suitably defined.  These variables are subsequently used by _LT_CONFIG
-# to write the compiler configuration to 'libtool'.
+# to write the compiler configuration to `libtool'.
 m4_defun([_LT_LANG_GCJ_CONFIG],
 [AC_REQUIRE([LT_PROG_GCJ])dnl
 AC_LANG_SAVE
@@ -7979,7 +7475,7 @@ CC=${GCJ-"gcj"}
 CFLAGS=$GCJFLAGS
 compiler=$CC
 _LT_TAGVAR(compiler, $1)=$CC
-_LT_TAGVAR(LD, $1)=$LD
+_LT_TAGVAR(LD, $1)="$LD"
 _LT_CC_BASENAME([$compiler])
 
 # GCJ did not exist at the time GCC didn't implicitly link libc in.
@@ -8016,7 +7512,7 @@ CFLAGS=$lt_save_CFLAGS
 # --------------------------
 # Ensure that the configuration variables for the GNU Go compiler
 # are suitably defined.  These variables are subsequently used by _LT_CONFIG
-# to write the compiler configuration to 'libtool'.
+# to write the compiler configuration to `libtool'.
 m4_defun([_LT_LANG_GO_CONFIG],
 [AC_REQUIRE([LT_PROG_GO])dnl
 AC_LANG_SAVE
@@ -8050,7 +7546,7 @@ CC=${GOC-"gccgo"}
 CFLAGS=$GOFLAGS
 compiler=$CC
 _LT_TAGVAR(compiler, $1)=$CC
-_LT_TAGVAR(LD, $1)=$LD
+_LT_TAGVAR(LD, $1)="$LD"
 _LT_CC_BASENAME([$compiler])
 
 # Go did not exist at the time GCC didn't implicitly link libc in.
@@ -8087,7 +7583,7 @@ CFLAGS=$lt_save_CFLAGS
 # -------------------------
 # Ensure that the configuration variables for the Windows resource compiler
 # are suitably defined.  These variables are subsequently used by _LT_CONFIG
-# to write the compiler configuration to 'libtool'.
+# to write the compiler configuration to `libtool'.
 m4_defun([_LT_LANG_RC_CONFIG],
 [AC_REQUIRE([LT_PROG_RC])dnl
 AC_LANG_SAVE
@@ -8103,7 +7599,7 @@ _LT_TAGVAR(objext, $1)=$objext
 lt_simple_compile_test_code='sample MENU { MENUITEM "&Soup", 100, CHECKED }'
 
 # Code to be used in simple link tests
-lt_simple_link_test_code=$lt_simple_compile_test_code
+lt_simple_link_test_code="$lt_simple_compile_test_code"
 
 # ltmain only uses $CC for tagged configurations so make sure $CC is set.
 _LT_TAG_COMPILER
@@ -8113,7 +7609,7 @@ _LT_COMPILER_BOILERPLATE
 _LT_LINKER_BOILERPLATE
 
 # Allow CC to be a program name with arguments.
-lt_save_CC=$CC
+lt_save_CC="$CC"
 lt_save_CFLAGS=$CFLAGS
 lt_save_GCC=$GCC
 GCC=
@@ -8142,7 +7638,7 @@ AC_DEFUN([LT_PROG_GCJ],
 [m4_ifdef([AC_PROG_GCJ], [AC_PROG_GCJ],
   [m4_ifdef([A][M_PROG_GCJ], [A][M_PROG_GCJ],
     [AC_CHECK_TOOL(GCJ, gcj,)
-      test set = "${GCJFLAGS+set}" || GCJFLAGS="-g -O2"
+      test "x${GCJFLAGS+set}" = xset || GCJFLAGS="-g -O2"
       AC_SUBST(GCJFLAGS)])])[]dnl
 ])
 
@@ -8253,7 +7749,7 @@ lt_ac_count=0
 # Add /usr/xpg4/bin/sed as it is typically found on Solaris
 # along with /bin/sed that truncates output.
 for lt_ac_sed in $lt_ac_sed_list /usr/xpg4/bin/sed; do
-  test ! -f "$lt_ac_sed" && continue
+  test ! -f $lt_ac_sed && continue
   cat /dev/null > conftest.in
   lt_ac_count=0
   echo $ECHO_N "0123456789$ECHO_C" >conftest.in
@@ -8270,9 +7766,9 @@ for lt_ac_sed in $lt_ac_sed_list /usr/xpg4/bin/sed; do
     $lt_ac_sed -e 's/a$//' < conftest.nl >conftest.out || break
     cmp -s conftest.out conftest.nl || break
     # 10000 chars as input seems more than enough
-    test 10 -lt "$lt_ac_count" && break
+    test $lt_ac_count -gt 10 && break
     lt_ac_count=`expr $lt_ac_count + 1`
-    if test "$lt_ac_count" -gt "$lt_ac_max"; then
+    if test $lt_ac_count -gt $lt_ac_max; then
       lt_ac_max=$lt_ac_count
       lt_cv_path_SED=$lt_ac_sed
     fi
@@ -8296,7 +7792,27 @@ dnl AC_DEFUN([LT_AC_PROG_SED], [])
 # Find out whether the shell is Bourne or XSI compatible,
 # or has some other useful features.
 m4_defun([_LT_CHECK_SHELL_FEATURES],
-[if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then
+[AC_MSG_CHECKING([whether the shell understands some XSI constructs])
+# Try some XSI features
+xsi_shell=no
+( _lt_dummy="a/b/c"
+  test "${_lt_dummy##*/},${_lt_dummy%/*},${_lt_dummy#??}"${_lt_dummy%"$_lt_dummy"}, \
+      = c,a/b,b/c, \
+    && eval 'test $(( 1 + 1 )) -eq 2 \
+    && test "${#_lt_dummy}" -eq 5' ) >/dev/null 2>&1 \
+  && xsi_shell=yes
+AC_MSG_RESULT([$xsi_shell])
+_LT_CONFIG_LIBTOOL_INIT([xsi_shell='$xsi_shell'])
+
+AC_MSG_CHECKING([whether the shell understands "+="])
+lt_shell_append=no
+( foo=bar; set foo baz; eval "$[1]+=\$[2]" && test "$foo" = barbaz ) \
+    >/dev/null 2>&1 \
+  && lt_shell_append=yes
+AC_MSG_RESULT([$lt_shell_append])
+_LT_CONFIG_LIBTOOL_INIT([lt_shell_append='$lt_shell_append'])
+
+if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then
   lt_unset=unset
 else
   lt_unset=false
@@ -8320,9 +7836,102 @@ _LT_DECL([NL2SP], [lt_NL2SP], [1], [turn newlines into spaces])dnl
 ])# _LT_CHECK_SHELL_FEATURES
 
 
+# _LT_PROG_FUNCTION_REPLACE (FUNCNAME, REPLACEMENT-BODY)
+# ------------------------------------------------------
+# In `$cfgfile', look for function FUNCNAME delimited by `^FUNCNAME ()$' and
+# '^} FUNCNAME ', and replace its body with REPLACEMENT-BODY.
+m4_defun([_LT_PROG_FUNCTION_REPLACE],
+[dnl {
+sed -e '/^$1 ()$/,/^} # $1 /c\
+$1 ()\
+{\
+m4_bpatsubsts([$2], [$], [\\], [^\([	 ]\)], [\\\1])
+} # Extended-shell $1 implementation' "$cfgfile" > $cfgfile.tmp \
+  && mv -f "$cfgfile.tmp" "$cfgfile" \
+    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+])
+
+
+# _LT_PROG_REPLACE_SHELLFNS
+# -------------------------
+# Replace existing portable implementations of several shell functions with
+# equivalent extended shell implementations where those features are available..
+m4_defun([_LT_PROG_REPLACE_SHELLFNS],
+[if test x"$xsi_shell" = xyes; then
+  _LT_PROG_FUNCTION_REPLACE([func_dirname], [dnl
+    case ${1} in
+      */*) func_dirname_result="${1%/*}${2}" ;;
+      *  ) func_dirname_result="${3}" ;;
+    esac])
+
+  _LT_PROG_FUNCTION_REPLACE([func_basename], [dnl
+    func_basename_result="${1##*/}"])
+
+  _LT_PROG_FUNCTION_REPLACE([func_dirname_and_basename], [dnl
+    case ${1} in
+      */*) func_dirname_result="${1%/*}${2}" ;;
+      *  ) func_dirname_result="${3}" ;;
+    esac
+    func_basename_result="${1##*/}"])
+
+  _LT_PROG_FUNCTION_REPLACE([func_stripname], [dnl
+    # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are
+    # positional parameters, so assign one to ordinary parameter first.
+    func_stripname_result=${3}
+    func_stripname_result=${func_stripname_result#"${1}"}
+    func_stripname_result=${func_stripname_result%"${2}"}])
+
+  _LT_PROG_FUNCTION_REPLACE([func_split_long_opt], [dnl
+    func_split_long_opt_name=${1%%=*}
+    func_split_long_opt_arg=${1#*=}])
+
+  _LT_PROG_FUNCTION_REPLACE([func_split_short_opt], [dnl
+    func_split_short_opt_arg=${1#??}
+    func_split_short_opt_name=${1%"$func_split_short_opt_arg"}])
+
+  _LT_PROG_FUNCTION_REPLACE([func_lo2o], [dnl
+    case ${1} in
+      *.lo) func_lo2o_result=${1%.lo}.${objext} ;;
+      *)    func_lo2o_result=${1} ;;
+    esac])
+
+  _LT_PROG_FUNCTION_REPLACE([func_xform], [    func_xform_result=${1%.*}.lo])
+
+  _LT_PROG_FUNCTION_REPLACE([func_arith], [    func_arith_result=$(( $[*] ))])
+
+  _LT_PROG_FUNCTION_REPLACE([func_len], [    func_len_result=${#1}])
+fi
+
+if test x"$lt_shell_append" = xyes; then
+  _LT_PROG_FUNCTION_REPLACE([func_append], [    eval "${1}+=\\${2}"])
+
+  _LT_PROG_FUNCTION_REPLACE([func_append_quoted], [dnl
+    func_quote_for_eval "${2}"
+dnl m4 expansion turns \\\\ into \\, and then the shell eval turns that into \
+    eval "${1}+=\\\\ \\$func_quote_for_eval_result"])
+
+  # Save a `func_append' function call where possible by direct use of '+='
+  sed -e 's%func_append \([[a-zA-Z_]]\{1,\}\) "%\1+="%g' $cfgfile > $cfgfile.tmp \
+    && mv -f "$cfgfile.tmp" "$cfgfile" \
+      || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+  test 0 -eq $? || _lt_function_replace_fail=:
+else
+  # Save a `func_append' function call even when '+=' is not available
+  sed -e 's%func_append \([[a-zA-Z_]]\{1,\}\) "%\1="$\1%g' $cfgfile > $cfgfile.tmp \
+    && mv -f "$cfgfile.tmp" "$cfgfile" \
+      || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+  test 0 -eq $? || _lt_function_replace_fail=:
+fi
+
+if test x"$_lt_function_replace_fail" = x":"; then
+  AC_MSG_WARN([Unable to substitute extended shell functions in $ofile])
+fi
+])
+
 # _LT_PATH_CONVERSION_FUNCTIONS
 # -----------------------------
-# Determine what file name conversion functions should be used by
+# Determine which file name conversion functions should be used by
 # func_to_host_file (and, implicitly, by func_to_host_path).  These are needed
 # for certain cross-compile configurations and native mingw.
 m4_defun([_LT_PATH_CONVERSION_FUNCTIONS],
diff --git a/m4/ltoptions.m4 b/m4/ltoptions.m4
index 94b0829..5d9acd8 100644
--- a/m4/ltoptions.m4
+++ b/m4/ltoptions.m4
@@ -1,14 +1,14 @@
 # Helper functions for option handling.                    -*- Autoconf -*-
 #
-#   Copyright (C) 2004-2005, 2007-2009, 2011-2015 Free Software
-#   Foundation, Inc.
+#   Copyright (C) 2004, 2005, 2007, 2008, 2009 Free Software Foundation,
+#   Inc.
 #   Written by Gary V. Vaughan, 2004
 #
 # This file is free software; the Free Software Foundation gives
 # unlimited permission to copy and/or distribute it, with or without
 # modifications, as long as this notice is preserved.
 
-# serial 8 ltoptions.m4
+# serial 7 ltoptions.m4
 
 # This is to help aclocal find these macros, as it can't see m4_define.
 AC_DEFUN([LTOPTIONS_VERSION], [m4_if([1])])
@@ -29,7 +29,7 @@ m4_define([_LT_SET_OPTION],
 [m4_define(_LT_MANGLE_OPTION([$1], [$2]))dnl
 m4_ifdef(_LT_MANGLE_DEFUN([$1], [$2]),
         _LT_MANGLE_DEFUN([$1], [$2]),
-    [m4_warning([Unknown $1 option '$2'])])[]dnl
+    [m4_warning([Unknown $1 option `$2'])])[]dnl
 ])
 
 
@@ -75,15 +75,13 @@ m4_if([$1],[LT_INIT],[
   dnl
   dnl If no reference was made to various pairs of opposing options, then
   dnl we run the default mode handler for the pair.  For example, if neither
-  dnl 'shared' nor 'disable-shared' was passed, we enable building of shared
+  dnl `shared' nor `disable-shared' was passed, we enable building of shared
   dnl archives by default:
   _LT_UNLESS_OPTIONS([LT_INIT], [shared disable-shared], [_LT_ENABLE_SHARED])
   _LT_UNLESS_OPTIONS([LT_INIT], [static disable-static], [_LT_ENABLE_STATIC])
   _LT_UNLESS_OPTIONS([LT_INIT], [pic-only no-pic], [_LT_WITH_PIC])
   _LT_UNLESS_OPTIONS([LT_INIT], [fast-install disable-fast-install],
-		   [_LT_ENABLE_FAST_INSTALL])
-  _LT_UNLESS_OPTIONS([LT_INIT], [aix-soname=aix aix-soname=both aix-soname=svr4],
-		   [_LT_WITH_AIX_SONAME([aix])])
+  		   [_LT_ENABLE_FAST_INSTALL])
   ])
 ])# _LT_SET_OPTIONS
 
@@ -114,7 +112,7 @@ AU_DEFUN([AC_LIBTOOL_DLOPEN],
 [_LT_SET_OPTION([LT_INIT], [dlopen])
 AC_DIAGNOSE([obsolete],
 [$0: Remove this warning and the call to _LT_SET_OPTION when you
-put the 'dlopen' option into LT_INIT's first parameter.])
+put the `dlopen' option into LT_INIT's first parameter.])
 ])
 
 dnl aclocal-1.4 backwards compatibility:
@@ -150,7 +148,7 @@ AU_DEFUN([AC_LIBTOOL_WIN32_DLL],
 _LT_SET_OPTION([LT_INIT], [win32-dll])
 AC_DIAGNOSE([obsolete],
 [$0: Remove this warning and the call to _LT_SET_OPTION when you
-put the 'win32-dll' option into LT_INIT's first parameter.])
+put the `win32-dll' option into LT_INIT's first parameter.])
 ])
 
 dnl aclocal-1.4 backwards compatibility:
@@ -159,9 +157,9 @@ dnl AC_DEFUN([AC_LIBTOOL_WIN32_DLL], [])
 
 # _LT_ENABLE_SHARED([DEFAULT])
 # ----------------------------
-# implement the --enable-shared flag, and supports the 'shared' and
-# 'disable-shared' LT_INIT options.
-# DEFAULT is either 'yes' or 'no'.  If omitted, it defaults to 'yes'.
+# implement the --enable-shared flag, and supports the `shared' and
+# `disable-shared' LT_INIT options.
+# DEFAULT is either `yes' or `no'.  If omitted, it defaults to `yes'.
 m4_define([_LT_ENABLE_SHARED],
 [m4_define([_LT_ENABLE_SHARED_DEFAULT], [m4_if($1, no, no, yes)])dnl
 AC_ARG_ENABLE([shared],
@@ -174,14 +172,14 @@ AC_ARG_ENABLE([shared],
     *)
       enable_shared=no
       # Look at the argument we got.  We use all the common list separators.
-      lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR,
+      lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
       for pkg in $enableval; do
-	IFS=$lt_save_ifs
+	IFS="$lt_save_ifs"
 	if test "X$pkg" = "X$p"; then
 	  enable_shared=yes
 	fi
       done
-      IFS=$lt_save_ifs
+      IFS="$lt_save_ifs"
       ;;
     esac],
     [enable_shared=]_LT_ENABLE_SHARED_DEFAULT)
@@ -213,9 +211,9 @@ dnl AC_DEFUN([AM_DISABLE_SHARED], [])
 
 # _LT_ENABLE_STATIC([DEFAULT])
 # ----------------------------
-# implement the --enable-static flag, and support the 'static' and
-# 'disable-static' LT_INIT options.
-# DEFAULT is either 'yes' or 'no'.  If omitted, it defaults to 'yes'.
+# implement the --enable-static flag, and support the `static' and
+# `disable-static' LT_INIT options.
+# DEFAULT is either `yes' or `no'.  If omitted, it defaults to `yes'.
 m4_define([_LT_ENABLE_STATIC],
 [m4_define([_LT_ENABLE_STATIC_DEFAULT], [m4_if($1, no, no, yes)])dnl
 AC_ARG_ENABLE([static],
@@ -228,14 +226,14 @@ AC_ARG_ENABLE([static],
     *)
      enable_static=no
       # Look at the argument we got.  We use all the common list separators.
-      lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR,
+      lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
       for pkg in $enableval; do
-	IFS=$lt_save_ifs
+	IFS="$lt_save_ifs"
 	if test "X$pkg" = "X$p"; then
 	  enable_static=yes
 	fi
       done
-      IFS=$lt_save_ifs
+      IFS="$lt_save_ifs"
       ;;
     esac],
     [enable_static=]_LT_ENABLE_STATIC_DEFAULT)
@@ -267,9 +265,9 @@ dnl AC_DEFUN([AM_DISABLE_STATIC], [])
 
 # _LT_ENABLE_FAST_INSTALL([DEFAULT])
 # ----------------------------------
-# implement the --enable-fast-install flag, and support the 'fast-install'
-# and 'disable-fast-install' LT_INIT options.
-# DEFAULT is either 'yes' or 'no'.  If omitted, it defaults to 'yes'.
+# implement the --enable-fast-install flag, and support the `fast-install'
+# and `disable-fast-install' LT_INIT options.
+# DEFAULT is either `yes' or `no'.  If omitted, it defaults to `yes'.
 m4_define([_LT_ENABLE_FAST_INSTALL],
 [m4_define([_LT_ENABLE_FAST_INSTALL_DEFAULT], [m4_if($1, no, no, yes)])dnl
 AC_ARG_ENABLE([fast-install],
@@ -282,14 +280,14 @@ AC_ARG_ENABLE([fast-install],
     *)
       enable_fast_install=no
       # Look at the argument we got.  We use all the common list separators.
-      lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR,
+      lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
       for pkg in $enableval; do
-	IFS=$lt_save_ifs
+	IFS="$lt_save_ifs"
 	if test "X$pkg" = "X$p"; then
 	  enable_fast_install=yes
 	fi
       done
-      IFS=$lt_save_ifs
+      IFS="$lt_save_ifs"
       ;;
     esac],
     [enable_fast_install=]_LT_ENABLE_FAST_INSTALL_DEFAULT)
@@ -306,14 +304,14 @@ AU_DEFUN([AC_ENABLE_FAST_INSTALL],
 [_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[fast-install])
 AC_DIAGNOSE([obsolete],
 [$0: Remove this warning and the call to _LT_SET_OPTION when you put
-the 'fast-install' option into LT_INIT's first parameter.])
+the `fast-install' option into LT_INIT's first parameter.])
 ])
 
 AU_DEFUN([AC_DISABLE_FAST_INSTALL],
 [_LT_SET_OPTION([LT_INIT], [disable-fast-install])
 AC_DIAGNOSE([obsolete],
 [$0: Remove this warning and the call to _LT_SET_OPTION when you put
-the 'disable-fast-install' option into LT_INIT's first parameter.])
+the `disable-fast-install' option into LT_INIT's first parameter.])
 ])
 
 dnl aclocal-1.4 backwards compatibility:
@@ -321,64 +319,11 @@ dnl AC_DEFUN([AC_ENABLE_FAST_INSTALL], [])
 dnl AC_DEFUN([AM_DISABLE_FAST_INSTALL], [])
 
 
-# _LT_WITH_AIX_SONAME([DEFAULT])
-# ----------------------------------
-# implement the --with-aix-soname flag, and support the `aix-soname=aix'
-# and `aix-soname=both' and `aix-soname=svr4' LT_INIT options. DEFAULT
-# is either `aix', `both' or `svr4'.  If omitted, it defaults to `aix'.
-m4_define([_LT_WITH_AIX_SONAME],
-[m4_define([_LT_WITH_AIX_SONAME_DEFAULT], [m4_if($1, svr4, svr4, m4_if($1, both, both, aix))])dnl
-shared_archive_member_spec=
-case $host,$enable_shared in
-power*-*-aix[[5-9]]*,yes)
-  AC_MSG_CHECKING([which variant of shared library versioning to provide])
-  AC_ARG_WITH([aix-soname],
-    [AS_HELP_STRING([--with-aix-soname=aix|svr4|both],
-      [shared library versioning (aka "SONAME") variant to provide on AIX, @<:@default=]_LT_WITH_AIX_SONAME_DEFAULT[@:>@.])],
-    [case $withval in
-    aix|svr4|both)
-      ;;
-    *)
-      AC_MSG_ERROR([Unknown argument to --with-aix-soname])
-      ;;
-    esac
-    lt_cv_with_aix_soname=$with_aix_soname],
-    [AC_CACHE_VAL([lt_cv_with_aix_soname],
-      [lt_cv_with_aix_soname=]_LT_WITH_AIX_SONAME_DEFAULT)
-    with_aix_soname=$lt_cv_with_aix_soname])
-  AC_MSG_RESULT([$with_aix_soname])
-  if test aix != "$with_aix_soname"; then
-    # For the AIX way of multilib, we name the shared archive member
-    # based on the bitwidth used, traditionally 'shr.o' or 'shr_64.o',
-    # and 'shr.imp' or 'shr_64.imp', respectively, for the Import File.
-    # Even when GNU compilers ignore OBJECT_MODE but need '-maix64' flag,
-    # the AIX toolchain works better with OBJECT_MODE set (default 32).
-    if test 64 = "${OBJECT_MODE-32}"; then
-      shared_archive_member_spec=shr_64
-    else
-      shared_archive_member_spec=shr
-    fi
-  fi
-  ;;
-*)
-  with_aix_soname=aix
-  ;;
-esac
-
-_LT_DECL([], [shared_archive_member_spec], [0],
-    [Shared archive member basename, for filename based shared library versioning on AIX])dnl
-])# _LT_WITH_AIX_SONAME
-
-LT_OPTION_DEFINE([LT_INIT], [aix-soname=aix], [_LT_WITH_AIX_SONAME([aix])])
-LT_OPTION_DEFINE([LT_INIT], [aix-soname=both], [_LT_WITH_AIX_SONAME([both])])
-LT_OPTION_DEFINE([LT_INIT], [aix-soname=svr4], [_LT_WITH_AIX_SONAME([svr4])])
-
-
 # _LT_WITH_PIC([MODE])
 # --------------------
-# implement the --with-pic flag, and support the 'pic-only' and 'no-pic'
+# implement the --with-pic flag, and support the `pic-only' and `no-pic'
 # LT_INIT options.
-# MODE is either 'yes' or 'no'.  If omitted, it defaults to 'both'.
+# MODE is either `yes' or `no'.  If omitted, it defaults to `both'.
 m4_define([_LT_WITH_PIC],
 [AC_ARG_WITH([pic],
     [AS_HELP_STRING([--with-pic@<:@=PKGS@:>@],
@@ -389,17 +334,19 @@ m4_define([_LT_WITH_PIC],
     *)
       pic_mode=default
       # Look at the argument we got.  We use all the common list separators.
-      lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR,
+      lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
       for lt_pkg in $withval; do
-	IFS=$lt_save_ifs
+	IFS="$lt_save_ifs"
 	if test "X$lt_pkg" = "X$lt_p"; then
 	  pic_mode=yes
 	fi
       done
-      IFS=$lt_save_ifs
+      IFS="$lt_save_ifs"
       ;;
     esac],
-    [pic_mode=m4_default([$1], [default])])
+    [pic_mode=default])
+
+test -z "$pic_mode" && pic_mode=m4_default([$1], [default])
 
 _LT_DECL([], [pic_mode], [0], [What type of objects to build])dnl
 ])# _LT_WITH_PIC
@@ -412,7 +359,7 @@ AU_DEFUN([AC_LIBTOOL_PICMODE],
 [_LT_SET_OPTION([LT_INIT], [pic-only])
 AC_DIAGNOSE([obsolete],
 [$0: Remove this warning and the call to _LT_SET_OPTION when you
-put the 'pic-only' option into LT_INIT's first parameter.])
+put the `pic-only' option into LT_INIT's first parameter.])
 ])
 
 dnl aclocal-1.4 backwards compatibility:
diff --git a/m4/ltsugar.m4 b/m4/ltsugar.m4
index 48bc934..9000a05 100644
--- a/m4/ltsugar.m4
+++ b/m4/ltsugar.m4
@@ -1,7 +1,6 @@
 # ltsugar.m4 -- libtool m4 base layer.                         -*-Autoconf-*-
 #
-# Copyright (C) 2004-2005, 2007-2008, 2011-2015 Free Software
-# Foundation, Inc.
+# Copyright (C) 2004, 2005, 2007, 2008 Free Software Foundation, Inc.
 # Written by Gary V. Vaughan, 2004
 #
 # This file is free software; the Free Software Foundation gives
@@ -34,7 +33,7 @@ m4_define([_lt_join],
 # ------------
 # Manipulate m4 lists.
 # These macros are necessary as long as will still need to support
-# Autoconf-2.59, which quotes differently.
+# Autoconf-2.59 which quotes differently.
 m4_define([lt_car], [[$1]])
 m4_define([lt_cdr],
 [m4_if([$#], 0, [m4_fatal([$0: cannot be called without arguments])],
@@ -45,7 +44,7 @@ m4_define([lt_unquote], $1)
 
 # lt_append(MACRO-NAME, STRING, [SEPARATOR])
 # ------------------------------------------
-# Redefine MACRO-NAME to hold its former content plus 'SEPARATOR''STRING'.
+# Redefine MACRO-NAME to hold its former content plus `SEPARATOR'`STRING'.
 # Note that neither SEPARATOR nor STRING are expanded; they are appended
 # to MACRO-NAME as is (leaving the expansion for when MACRO-NAME is invoked).
 # No SEPARATOR is output if MACRO-NAME was previously undefined (different
diff --git a/m4/ltversion.m4 b/m4/ltversion.m4
index fa04b52..07a8602 100644
--- a/m4/ltversion.m4
+++ b/m4/ltversion.m4
@@ -1,6 +1,6 @@
 # ltversion.m4 -- version numbers			-*- Autoconf -*-
 #
-#   Copyright (C) 2004, 2011-2015 Free Software Foundation, Inc.
+#   Copyright (C) 2004 Free Software Foundation, Inc.
 #   Written by Scott James Remnant, 2004
 #
 # This file is free software; the Free Software Foundation gives
@@ -9,15 +9,15 @@
 
 # @configure_input@
 
-# serial 4179 ltversion.m4
+# serial 3337 ltversion.m4
 # This file is part of GNU Libtool
 
-m4_define([LT_PACKAGE_VERSION], [2.4.6])
-m4_define([LT_PACKAGE_REVISION], [2.4.6])
+m4_define([LT_PACKAGE_VERSION], [2.4.2])
+m4_define([LT_PACKAGE_REVISION], [1.3337])
 
 AC_DEFUN([LTVERSION_VERSION],
-[macro_version='2.4.6'
-macro_revision='2.4.6'
+[macro_version='2.4.2'
+macro_revision='1.3337'
 _LT_DECL(, macro_version, 0, [Which release of libtool.m4 was used?])
 _LT_DECL(, macro_revision, 0)
 ])
diff --git a/m4/lt~obsolete.m4 b/m4/lt~obsolete.m4
index c6b26f8..c573da9 100644
--- a/m4/lt~obsolete.m4
+++ b/m4/lt~obsolete.m4
@@ -1,7 +1,6 @@
 # lt~obsolete.m4 -- aclocal satisfying obsolete definitions.    -*-Autoconf-*-
 #
-#   Copyright (C) 2004-2005, 2007, 2009, 2011-2015 Free Software
-#   Foundation, Inc.
+#   Copyright (C) 2004, 2005, 2007, 2009 Free Software Foundation, Inc.
 #   Written by Scott James Remnant, 2004.
 #
 # This file is free software; the Free Software Foundation gives
@@ -12,7 +11,7 @@
 
 # These exist entirely to fool aclocal when bootstrapping libtool.
 #
-# In the past libtool.m4 has provided macros via AC_DEFUN (or AU_DEFUN),
+# In the past libtool.m4 has provided macros via AC_DEFUN (or AU_DEFUN)
 # which have later been changed to m4_define as they aren't part of the
 # exported API, or moved to Autoconf or Automake where they belong.
 #
@@ -26,7 +25,7 @@
 # included after everything else.  This provides aclocal with the
 # AC_DEFUNs it wants, but when m4 processes it, it doesn't do anything
 # because those macros already exist, or will be overwritten later.
-# We use AC_DEFUN over AU_DEFUN for compatibility with aclocal-1.6.
+# We use AC_DEFUN over AU_DEFUN for compatibility with aclocal-1.6. 
 #
 # Anytime we withdraw an AC_DEFUN or AU_DEFUN, remember to add it here.
 # Yes, that means every name once taken will need to remain here until
diff --git a/m4/pkg.m4 b/m4/pkg.m4
index 4688002..9a71878 100644
--- a/m4/pkg.m4
+++ b/m4/pkg.m4
@@ -1,60 +1,29 @@
-dnl pkg.m4 - Macros to locate and utilise pkg-config.   -*- Autoconf -*-
-dnl serial 11 (pkg-config-0.29)
-dnl
-dnl Copyright © 2004 Scott James Remnant <scott at netsplit.com>.
-dnl Copyright © 2012-2015 Dan Nicholson <dbn.lists at gmail.com>
-dnl
-dnl This program is free software; you can redistribute it and/or modify
-dnl it under the terms of the GNU General Public License as published by
-dnl the Free Software Foundation; either version 2 of the License, or
-dnl (at your option) any later version.
-dnl
-dnl This program is distributed in the hope that it will be useful, but
-dnl WITHOUT ANY WARRANTY; without even the implied warranty of
-dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-dnl General Public License for more details.
-dnl
-dnl You should have received a copy of the GNU General Public License
-dnl along with this program; if not, write to the Free Software
-dnl Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
-dnl 02111-1307, USA.
-dnl
-dnl As a special exception to the GNU General Public License, if you
-dnl distribute this file as part of a program that contains a
-dnl configuration script generated by Autoconf, you may include it under
-dnl the same distribution terms that you use for the rest of that
-dnl program.
-
-dnl PKG_PREREQ(MIN-VERSION)
-dnl -----------------------
-dnl Since: 0.29
-dnl
-dnl Verify that the version of the pkg-config macros are at least
-dnl MIN-VERSION. Unlike PKG_PROG_PKG_CONFIG, which checks the user's
-dnl installed version of pkg-config, this checks the developer's version
-dnl of pkg.m4 when generating configure.
-dnl
-dnl To ensure that this macro is defined, also add:
-dnl m4_ifndef([PKG_PREREQ],
-dnl     [m4_fatal([must install pkg-config 0.29 or later before running autoconf/autogen])])
-dnl
-dnl See the "Since" comment for each macro you use to see what version
-dnl of the macros you require.
-m4_defun([PKG_PREREQ],
-[m4_define([PKG_MACROS_VERSION], [0.29])
-m4_if(m4_version_compare(PKG_MACROS_VERSION, [$1]), -1,
-    [m4_fatal([pkg.m4 version $1 or higher is required but ]PKG_MACROS_VERSION[ found])])
-])dnl PKG_PREREQ
-
-dnl PKG_PROG_PKG_CONFIG([MIN-VERSION])
-dnl ----------------------------------
-dnl Since: 0.16
-dnl
-dnl Search for the pkg-config tool and set the PKG_CONFIG variable to
-dnl first found in the path. Checks that the version of pkg-config found
-dnl is at least MIN-VERSION. If MIN-VERSION is not specified, 0.9.0 is
-dnl used since that's the first version where most current features of
-dnl pkg-config existed.
+# pkg.m4 - Macros to locate and utilise pkg-config.            -*- Autoconf -*-
+# serial 1 (pkg-config-0.24)
+# 
+# Copyright © 2004 Scott James Remnant <scott at netsplit.com>.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# General Public License for more details.
+#
+# 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.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# PKG_PROG_PKG_CONFIG([MIN-VERSION])
+# ----------------------------------
 AC_DEFUN([PKG_PROG_PKG_CONFIG],
 [m4_pattern_forbid([^_?PKG_[A-Z_]+$])
 m4_pattern_allow([^PKG_CONFIG(_(PATH|LIBDIR|SYSROOT_DIR|ALLOW_SYSTEM_(CFLAGS|LIBS)))?$])
@@ -76,19 +45,18 @@ if test -n "$PKG_CONFIG"; then
 		PKG_CONFIG=""
 	fi
 fi[]dnl
-])dnl PKG_PROG_PKG_CONFIG
-
-dnl PKG_CHECK_EXISTS(MODULES, [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND])
-dnl -------------------------------------------------------------------
-dnl Since: 0.18
-dnl
-dnl Check to see whether a particular set of modules exists. Similar to
-dnl PKG_CHECK_MODULES(), but does not set variables or print errors.
-dnl
-dnl Please remember that m4 expands AC_REQUIRE([PKG_PROG_PKG_CONFIG])
-dnl only at the first occurence in configure.ac, so if the first place
-dnl it's called might be skipped (such as if it is within an "if", you
-dnl have to call PKG_CHECK_EXISTS manually
+])# PKG_PROG_PKG_CONFIG
+
+# PKG_CHECK_EXISTS(MODULES, [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND])
+#
+# Check to see whether a particular set of modules exists.  Similar
+# to PKG_CHECK_MODULES(), but does not set variables or print errors.
+#
+# Please remember that m4 expands AC_REQUIRE([PKG_PROG_PKG_CONFIG])
+# only at the first occurence in configure.ac, so if the first place
+# it's called might be skipped (such as if it is within an "if", you
+# have to call PKG_CHECK_EXISTS manually
+# --------------------------------------------------------------
 AC_DEFUN([PKG_CHECK_EXISTS],
 [AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl
 if test -n "$PKG_CONFIG" && \
@@ -98,10 +66,8 @@ m4_ifvaln([$3], [else
   $3])dnl
 fi])
 
-dnl _PKG_CONFIG([VARIABLE], [COMMAND], [MODULES])
-dnl ---------------------------------------------
-dnl Internal wrapper calling pkg-config via PKG_CONFIG and setting
-dnl pkg_failed based on the result.
+# _PKG_CONFIG([VARIABLE], [COMMAND], [MODULES])
+# ---------------------------------------------
 m4_define([_PKG_CONFIG],
 [if test -n "$$1"; then
     pkg_cv_[]$1="$$1"
@@ -113,11 +79,10 @@ m4_define([_PKG_CONFIG],
  else
     pkg_failed=untried
 fi[]dnl
-])dnl _PKG_CONFIG
+])# _PKG_CONFIG
 
-dnl _PKG_SHORT_ERRORS_SUPPORTED
-dnl ---------------------------
-dnl Internal check to see if pkg-config supports short errors.
+# _PKG_SHORT_ERRORS_SUPPORTED
+# -----------------------------
 AC_DEFUN([_PKG_SHORT_ERRORS_SUPPORTED],
 [AC_REQUIRE([PKG_PROG_PKG_CONFIG])
 if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
@@ -125,17 +90,19 @@ if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
 else
         _pkg_short_errors_supported=no
 fi[]dnl
-])dnl _PKG_SHORT_ERRORS_SUPPORTED
-
-
-dnl PKG_CHECK_MODULES(VARIABLE-PREFIX, MODULES, [ACTION-IF-FOUND],
-dnl   [ACTION-IF-NOT-FOUND])
-dnl --------------------------------------------------------------
-dnl Since: 0.4.0
-dnl
-dnl Note that if there is a possibility the first call to
-dnl PKG_CHECK_MODULES might not happen, you should be sure to include an
-dnl explicit call to PKG_PROG_PKG_CONFIG in your configure.ac
+])# _PKG_SHORT_ERRORS_SUPPORTED
+
+
+# PKG_CHECK_MODULES(VARIABLE-PREFIX, MODULES, [ACTION-IF-FOUND],
+# [ACTION-IF-NOT-FOUND])
+#
+#
+# Note that if there is a possibility the first call to
+# PKG_CHECK_MODULES might not happen, you should be sure to include an
+# explicit call to PKG_PROG_PKG_CONFIG in your configure.ac
+#
+#
+# --------------------------------------------------------------
 AC_DEFUN([PKG_CHECK_MODULES],
 [AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl
 AC_ARG_VAR([$1][_CFLAGS], [C compiler flags for $1, overriding pkg-config])dnl
@@ -189,87 +156,4 @@ else
         AC_MSG_RESULT([yes])
 	$3
 fi[]dnl
-])dnl PKG_CHECK_MODULES
-
-
-dnl PKG_CHECK_MODULES_STATIC(VARIABLE-PREFIX, MODULES, [ACTION-IF-FOUND],
-dnl   [ACTION-IF-NOT-FOUND])
-dnl ---------------------------------------------------------------------
-dnl Since: 0.29
-dnl
-dnl Checks for existence of MODULES and gathers its build flags with
-dnl static libraries enabled. Sets VARIABLE-PREFIX_CFLAGS from --cflags
-dnl and VARIABLE-PREFIX_LIBS from --libs.
-dnl
-dnl Note that if there is a possibility the first call to
-dnl PKG_CHECK_MODULES_STATIC might not happen, you should be sure to
-dnl include an explicit call to PKG_PROG_PKG_CONFIG in your
-dnl configure.ac.
-AC_DEFUN([PKG_CHECK_MODULES_STATIC],
-[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl
-_save_PKG_CONFIG=$PKG_CONFIG
-PKG_CONFIG="$PKG_CONFIG --static"
-PKG_CHECK_MODULES($@)
-PKG_CONFIG=$_save_PKG_CONFIG[]dnl
-])dnl PKG_CHECK_MODULES_STATIC
-
-
-dnl PKG_INSTALLDIR([DIRECTORY])
-dnl -------------------------
-dnl Since: 0.27
-dnl
-dnl Substitutes the variable pkgconfigdir as the location where a module
-dnl should install pkg-config .pc files. By default the directory is
-dnl $libdir/pkgconfig, but the default can be changed by passing
-dnl DIRECTORY. The user can override through the --with-pkgconfigdir
-dnl parameter.
-AC_DEFUN([PKG_INSTALLDIR],
-[m4_pushdef([pkg_default], [m4_default([$1], ['${libdir}/pkgconfig'])])
-m4_pushdef([pkg_description],
-    [pkg-config installation directory @<:@]pkg_default[@:>@])
-AC_ARG_WITH([pkgconfigdir],
-    [AS_HELP_STRING([--with-pkgconfigdir], pkg_description)],,
-    [with_pkgconfigdir=]pkg_default)
-AC_SUBST([pkgconfigdir], [$with_pkgconfigdir])
-m4_popdef([pkg_default])
-m4_popdef([pkg_description])
-])dnl PKG_INSTALLDIR
-
-
-dnl PKG_NOARCH_INSTALLDIR([DIRECTORY])
-dnl --------------------------------
-dnl Since: 0.27
-dnl
-dnl Substitutes the variable noarch_pkgconfigdir as the location where a
-dnl module should install arch-independent pkg-config .pc files. By
-dnl default the directory is $datadir/pkgconfig, but the default can be
-dnl changed by passing DIRECTORY. The user can override through the
-dnl --with-noarch-pkgconfigdir parameter.
-AC_DEFUN([PKG_NOARCH_INSTALLDIR],
-[m4_pushdef([pkg_default], [m4_default([$1], ['${datadir}/pkgconfig'])])
-m4_pushdef([pkg_description],
-    [pkg-config arch-independent installation directory @<:@]pkg_default[@:>@])
-AC_ARG_WITH([noarch-pkgconfigdir],
-    [AS_HELP_STRING([--with-noarch-pkgconfigdir], pkg_description)],,
-    [with_noarch_pkgconfigdir=]pkg_default)
-AC_SUBST([noarch_pkgconfigdir], [$with_noarch_pkgconfigdir])
-m4_popdef([pkg_default])
-m4_popdef([pkg_description])
-])dnl PKG_NOARCH_INSTALLDIR
-
-
-dnl PKG_CHECK_VAR(VARIABLE, MODULE, CONFIG-VARIABLE,
-dnl [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND])
-dnl -------------------------------------------
-dnl Since: 0.28
-dnl
-dnl Retrieves the value of the pkg-config variable for the given module.
-AC_DEFUN([PKG_CHECK_VAR],
-[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl
-AC_ARG_VAR([$1], [value of $3 for $2, overriding pkg-config])dnl
-
-_PKG_CONFIG([$1], [variable="][$3]["], [$2])
-AS_VAR_COPY([$1], [pkg_cv_][$1])
-
-AS_VAR_IF([$1], [""], [$5], [$4])dnl
-])dnl PKG_CHECK_VAR
+])# PKG_CHECK_MODULES
diff --git a/man/Makefile.in b/man/Makefile.in
index ec60df3..b02835d 100644
--- a/man/Makefile.in
+++ b/man/Makefile.in
@@ -1,7 +1,7 @@
-# Makefile.in generated by automake 1.15 from Makefile.am.
+# Makefile.in generated by automake 1.14.1 from Makefile.am.
 # @configure_input@
 
-# Copyright (C) 1994-2014 Free Software Foundation, Inc.
+# Copyright (C) 1994-2013 Free Software Foundation, Inc.
 
 # This Makefile.in is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -14,17 +14,7 @@
 
 @SET_MAKE@
 VPATH = @srcdir@
-am__is_gnu_make = { \
-  if test -z '$(MAKELEVEL)'; then \
-    false; \
-  elif test -n '$(MAKE_HOST)'; then \
-    true; \
-  elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
-    true; \
-  else \
-    false; \
-  fi; \
-}
+am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
 am__make_running_with_option = \
   case $${target_option-} in \
       ?) ;; \
@@ -88,6 +78,9 @@ POST_UNINSTALL = :
 build_triplet = @build@
 host_triplet = @host@
 target_triplet = @target@
+DIST_COMMON = $(srcdir)/Makefile-client.am \
+	$(srcdir)/Makefile-server.am $(srcdir)/Makefile.in \
+	$(srcdir)/Makefile.am $(dist_man_MANS)
 @ENABLE_CLIENT_TRUE@@WITH_MAN_PAGES_TRUE at am__append_1 = \
 @ENABLE_CLIENT_TRUE@@WITH_MAN_PAGES_TRUE@	ceph-syn.8 \
 @ENABLE_CLIENT_TRUE@@WITH_MAN_PAGES_TRUE@	ceph-conf.8 \
@@ -165,7 +158,6 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/ac_check_classpath.m4 \
 	$(top_srcdir)/m4/pkg.m4 $(top_srcdir)/configure.ac
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
 	$(ACLOCAL_M4)
-DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON)
 mkinstalldirs = $(install_sh) -d
 CONFIG_HEADER = $(top_builddir)/src/acconfig.h
 CONFIG_CLEAN_FILES =
@@ -221,8 +213,6 @@ am__installdirs = "$(DESTDIR)$(man8dir)"
 NROFF = nroff
 MANS = $(dist_man_MANS)
 am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
-am__DIST_COMMON = $(dist_man_MANS) $(srcdir)/Makefile-client.am \
-	$(srcdir)/Makefile-server.am $(srcdir)/Makefile.in
 DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
 ACLOCAL = @ACLOCAL@
 AMTAR = @AMTAR@
@@ -315,7 +305,6 @@ LN_S = @LN_S@
 LTLIBOBJS = @LTLIBOBJS@
 LTTNG_GEN_TP_CHECK = @LTTNG_GEN_TP_CHECK@
 LTTNG_GEN_TP_PROG = @LTTNG_GEN_TP_PROG@
-LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
 MAKEINFO = @MAKEINFO@
 MANIFEST_TOOL = @MANIFEST_TOOL@
 MKDIR_P = @MKDIR_P@
@@ -342,7 +331,10 @@ PTHREAD_CC = @PTHREAD_CC@
 PTHREAD_CFLAGS = @PTHREAD_CFLAGS@
 PTHREAD_LIBS = @PTHREAD_LIBS@
 PYTHON = @PYTHON@
+PYTHON_CFLAGS = @PYTHON_CFLAGS@
+PYTHON_CONFIG_CHECK = @PYTHON_CONFIG_CHECK@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
+PYTHON_LDFLAGS = @PYTHON_LDFLAGS@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
 PYTHON_PREFIX = @PYTHON_PREFIX@
 PYTHON_VERSION = @PYTHON_VERSION@
@@ -411,7 +403,6 @@ program_transform_name = @program_transform_name@
 psdir = @psdir@
 pyexecdir = @pyexecdir@
 pythondir = @pythondir@
-runstatedir = @runstatedir@
 sbindir = @sbindir@
 sharedstatedir = @sharedstatedir@
 srcdir = @srcdir@
@@ -448,6 +439,7 @@ $(srcdir)/Makefile.in:  $(srcdir)/Makefile.am $(srcdir)/Makefile-client.am $(src
 	echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu man/Makefile'; \
 	$(am__cd) $(top_srcdir) && \
 	  $(AUTOMAKE) --gnu man/Makefile
+.PRECIOUS: Makefile
 Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
 	@case '$?' in \
 	  *config.status*) \
@@ -456,7 +448,7 @@ Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
 	    echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
 	    cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
 	esac;
-$(srcdir)/Makefile-client.am $(srcdir)/Makefile-server.am $(am__empty):
+$(srcdir)/Makefile-client.am $(srcdir)/Makefile-server.am:
 
 $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
 	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
@@ -674,8 +666,6 @@ uninstall-man: uninstall-man8
 	ps ps-am tags-am uninstall uninstall-am uninstall-man \
 	uninstall-man8
 
-.PRECIOUS: Makefile
-
 
 # prevent `make` from running in parallel, sphinx runs better in batch mode.
 @WITH_MAN_PAGES_TRUE at .PHONY: sphinx-build.stamp
diff --git a/man/ceph-authtool.8 b/man/ceph-authtool.8
index f396fe4..e590560 100644
--- a/man/ceph-authtool.8
+++ b/man/ceph-authtool.8
@@ -1,6 +1,6 @@
 .\" Man page generated from reStructuredText.
 .
-.TH "CEPH-AUTHTOOL" "8" "March 22, 2016" "dev" "Ceph"
+.TH "CEPH-AUTHTOOL" "8" "March 24, 2016" "dev" "Ceph"
 .SH NAME
 ceph-authtool \- ceph keyring manipulation tool
 .
diff --git a/man/ceph-clsinfo.8 b/man/ceph-clsinfo.8
index 5c7bce7..1f5133f 100644
--- a/man/ceph-clsinfo.8
+++ b/man/ceph-clsinfo.8
@@ -1,6 +1,6 @@
 .\" Man page generated from reStructuredText.
 .
-.TH "CEPH-CLSINFO" "8" "March 22, 2016" "dev" "Ceph"
+.TH "CEPH-CLSINFO" "8" "March 24, 2016" "dev" "Ceph"
 .SH NAME
 ceph-clsinfo \- show class object information
 .
diff --git a/man/ceph-conf.8 b/man/ceph-conf.8
index eac2c9e..c6fa297 100644
--- a/man/ceph-conf.8
+++ b/man/ceph-conf.8
@@ -1,6 +1,6 @@
 .\" Man page generated from reStructuredText.
 .
-.TH "CEPH-CONF" "8" "March 22, 2016" "dev" "Ceph"
+.TH "CEPH-CONF" "8" "March 24, 2016" "dev" "Ceph"
 .SH NAME
 ceph-conf \- ceph conf file tool
 .
diff --git a/man/ceph-create-keys.8 b/man/ceph-create-keys.8
index dc50e72..56dc669 100644
--- a/man/ceph-create-keys.8
+++ b/man/ceph-create-keys.8
@@ -1,6 +1,6 @@
 .\" Man page generated from reStructuredText.
 .
-.TH "CEPH-CREATE-KEYS" "8" "March 22, 2016" "dev" "Ceph"
+.TH "CEPH-CREATE-KEYS" "8" "March 24, 2016" "dev" "Ceph"
 .SH NAME
 ceph-create-keys \- ceph keyring generate tool
 .
diff --git a/man/ceph-debugpack.8 b/man/ceph-debugpack.8
index cd2afcb..c91b7b5 100644
--- a/man/ceph-debugpack.8
+++ b/man/ceph-debugpack.8
@@ -1,6 +1,6 @@
 .\" Man page generated from reStructuredText.
 .
-.TH "CEPH-DEBUGPACK" "8" "March 22, 2016" "dev" "Ceph"
+.TH "CEPH-DEBUGPACK" "8" "March 24, 2016" "dev" "Ceph"
 .SH NAME
 ceph-debugpack \- ceph debug packer utility
 .
diff --git a/man/ceph-dencoder.8 b/man/ceph-dencoder.8
index 7da1978..2d68f36 100644
--- a/man/ceph-dencoder.8
+++ b/man/ceph-dencoder.8
@@ -1,6 +1,6 @@
 .\" Man page generated from reStructuredText.
 .
-.TH "CEPH-DENCODER" "8" "March 22, 2016" "dev" "Ceph"
+.TH "CEPH-DENCODER" "8" "March 24, 2016" "dev" "Ceph"
 .SH NAME
 ceph-dencoder \- ceph encoder/decoder utility
 .
diff --git a/man/ceph-deploy.8 b/man/ceph-deploy.8
index 355da7e..2fd80e2 100644
--- a/man/ceph-deploy.8
+++ b/man/ceph-deploy.8
@@ -1,6 +1,6 @@
 .\" Man page generated from reStructuredText.
 .
-.TH "CEPH-DEPLOY" "8" "March 22, 2016" "dev" "Ceph"
+.TH "CEPH-DEPLOY" "8" "March 24, 2016" "dev" "Ceph"
 .SH NAME
 ceph-deploy \- Ceph deployment tool
 .
@@ -233,7 +233,7 @@ were created then a concatenated keyring is used for deployment of monitors. In
 this process a keyring parser is used which looks for \fB[entity]\fP sections in
 monitor keyrings and returns a list of those sections. A helper is then used to
 collect all keyrings into a single blob that will be used to inject it to monitors
-with \fB\-\-mkfs\fP on remote nodes. All keyring files are concatenated to be
+with \fI\-\-mkfs\fP on remote nodes. All keyring files are concatenated to be
 in a directory ending with \fB\&.keyring\fP\&. During this process the helper uses list
 of sections returned by keyring parser to check if an entity is already present
 in a keyring and if not, adds it. The concatenated keyring is used for deployment
diff --git a/man/ceph-detect-init.8 b/man/ceph-detect-init.8
index 853064a..a124107 100644
--- a/man/ceph-detect-init.8
+++ b/man/ceph-detect-init.8
@@ -1,6 +1,6 @@
 .\" Man page generated from reStructuredText.
 .
-.TH "CEPH-DETECT-INIT" "8" "March 22, 2016" "dev" "Ceph"
+.TH "CEPH-DETECT-INIT" "8" "March 24, 2016" "dev" "Ceph"
 .SH NAME
 ceph-detect-init \- display the init system Ceph should use
 .
diff --git a/man/ceph-disk.8 b/man/ceph-disk.8
index 5687ca4..1a59976 100644
--- a/man/ceph-disk.8
+++ b/man/ceph-disk.8
@@ -1,6 +1,6 @@
 .\" Man page generated from reStructuredText.
 .
-.TH "CEPH-DISK" "8" "March 22, 2016" "dev" "Ceph"
+.TH "CEPH-DISK" "8" "March 24, 2016" "dev" "Ceph"
 .SH NAME
 ceph-disk \- Ceph disk utility for OSD
 .
@@ -32,34 +32,46 @@ level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
 ..
 .SH SYNOPSIS
 .nf
-\fBceph\-disk\fP \fBprepare\fP [\-\-cluster \fIclustername\fP] [\-\-cluster\-uuid \fIuuid\fP]
-[\-\-fs\-type \fIxfs|ext4|btrfs\fP] [\fIdata\-path\fP] [\fIjournal\-path\fP]
+\fBceph\-disk\fP [\-h] [\-v] [\-\-log\-stdout] [\-\-prepend\-to\-path PATH]
+[\-\-statedir PATH] [\-\-sysconfdir PATH]
+[\-\-setuser USER] [\-\-setgroup GROUP]
+...
 .fi
 .sp
 .nf
-\fBceph\-disk\fP \fBactivate\fP [\fIdata\-path\fP] [\-\-activate\-key \fIpath\fP]
-[\-\-mark\-init \fIsysvinit|upstart|systemd|auto|none\fP]
-[\-\-no\-start\-daemon] [\-\-reactivate]
+optional arguments:
+\-h, \-\-help            show this help message and exit
+\-v, \-\-verbose         be more verbose
+\-\-log\-stdout          log to stdout
+\-\-prepend\-to\-path PATH
+                      prepend PATH to $PATH for backward compatibility (default /usr/bin)
+\-\-statedir PATH       directory in which ceph state is preserved (default /var/lib/ceph)
+\-\-sysconfdir PATH     directory in which ceph configuration files are found (default /etc/ceph)
+\-\-setuser USER        use the given user for subprocesses, rather than ceph or root
+\-\-setgroup GROUP      use the given group for subprocesses, rather than ceph or root
 .fi
 .sp
 .nf
-\fBceph\-disk\fP \fBactivate\-all\fP
-.fi
-.sp
-.nf
-\fBceph\-disk\fP \fBlist\fP
-.fi
-.sp
-.nf
-\fBceph\-disk\fP \fBdeactivate\fP [\-\-cluster \fIclustername\fP] [\fIdevice\-path\fP]
-[\-\-deactivate\-by\-id \fIid\fP] [\-\-mark\-out]
-.fi
-.sp
-.nf
-\fBceph\-disk\fP \fBdestroy\fP [\-\-cluster \fIclustername\fP] [\fIdevice\-path\fP]
-[\-\-destroy\-by\-id \fIid\fP] [\-\-dmcrypt\-key\-dir \fIKEYDIR\fP] [\-\-zap]
+subcommands:
 .fi
 .sp
+.INDENT 0.0
+.INDENT 3.5
+prepare              Prepare a directory or disk for a Ceph OSD
+activate             Activate a Ceph OSD
+activate\-lockbox     Activate a Ceph lockbox
+activate\-block       Activate an OSD via its block device
+activate\-journal     Activate an OSD via its journal device
+activate\-all         Activate all tagged OSD partitions
+list                 List disks, partitions, and Ceph OSDs
+suppress\-activate    Suppress activate on a device (prefix)
+unsuppress\-activate  Stop suppressing activate on a device (prefix)
+deactivate           Deactivate a Ceph OSD
+destroy              Destroy a Ceph OSD
+zap                  Zap/erase/destroy a device\(aqs partition table (and contents)
+trigger              Trigger an event (caled by udev)
+.UNINDENT
+.UNINDENT
 .SH DESCRIPTION
 .sp
 \fBceph\-disk\fP is a utility that can prepare and activate a disk, partition or
@@ -74,423 +86,9 @@ subcommands \fBprepare\fP and \fBactivate\fP\&.
 \fBceph\-disk\fP also automates the multiple steps involved to manually stop
 and destroy an OSD into two steps of deactivating and destroying the OSD by using
 the subcommands \fBdeactivate\fP and \fBdestroy\fP\&.
-.SH SUBCOMMANDS
-.SS prepare
-.sp
-Prepare a directory, disk for a Ceph OSD. It creates a GPT partition,
-marks the partition with Ceph type \fBuuid\fP, creates a file system, marks the
-file system as ready for Ceph consumption, uses entire partition and adds a new
-partition to the journal disk. It is run directly or triggered by
-\fBceph\-deploy\fP\&.
-.sp
-Usage:
-.INDENT 0.0
-.INDENT 3.5
-.sp
-.nf
-.ft C
-ceph\-disk prepare \-\-cluster [cluster\-name] \-\-cluster\-uuid [uuid] \-\-fs\-type
-[ext4|xfs|btrfs] [data\-path] [journal\-path]
-.ft P
-.fi
-.UNINDENT
-.UNINDENT
-.sp
-Other options like \fI\%\-\-osd\-uuid\fP, \fI\%\-\-journal\-uuid\fP,
-\fI\%\-\-zap\-disk\fP, \fI\%\-\-data\-dir\fP, \fI\%\-\-data\-dev\fP,
-\fI\%\-\-journal\-file\fP, \fI\%\-\-journal\-dev\fP, \fI\%\-\-dmcrypt\fP
-and \fI\%\-\-dmcrypt\-key\-dir\fP can also be used with the subcommand.
-.SS activate
-.sp
-Activate the Ceph OSD. It mounts the volume in a temporary location, allocates
-an OSD id (if needed), remounts in the correct location
-\fB/var/lib/ceph/osd/$cluster\-$id\fP and starts ceph\-osd. It is triggered by
-\fBudev\fP when it sees the OSD GPT partition type or on ceph service start with
-\fBceph disk activate\-all\fP\&. It is also run directly or triggered by
-\fBceph\-deploy\fP\&.
-.sp
-Usage:
-.INDENT 0.0
-.INDENT 3.5
-.sp
-.nf
-.ft C
-ceph\-disk activate [PATH]
-.ft P
-.fi
-.UNINDENT
-.UNINDENT
-.sp
-Here, [PATH] is path to a block device or a directory.
-.sp
-An additional option \fB\-\-activate\-key\fP has to be used with this
-subcommand when a copy of \fB/var/lib/ceph/bootstrap\-osd/{cluster}.keyring\fP
-isn\(aqt present in the OSD node.
-.sp
-Usage:
-.INDENT 0.0
-.INDENT 3.5
-.sp
-.nf
-.ft C
-ceph\-disk activate [PATH] [\-\-activate\-key PATH]
-.ft P
-.fi
-.UNINDENT
-.UNINDENT
-.sp
-Another option \fB\-\-mark\-init\fP can also be used with this
-subcommand.  \fB\-\-mark\-init\fP provides init system to manage the OSD
-directory. It defaults to \fBauto\fP which detects the init system
-suitable for ceph (either \fBsysvinit\fP, \fBsystemd\fP or
-\fBupstart\fP). The argument can be used to override the init system. It
-may be convenient when an operating system supports multiple init
-systems, such as Debian GNU/Linux jessie with \fBsystemd\fP and
-\fBsysvinit\fP\&. If the argument is \fBnone\fP, the OSD is not marked with
-any init system and \fBceph\-disk activate\fP needs to be called
-explicitely after each reboot.
-.sp
-Usage:
-.INDENT 0.0
-.INDENT 3.5
-.sp
-.nf
-.ft C
-ceph\-disk activate [PATH] [\-\-mark\-init *sysvinit|upstart|systemd|auto|none*]
-.ft P
-.fi
-.UNINDENT
-.UNINDENT
-.sp
-If the option \fB\-\-no\-start\-daemon\fP is given, the activation
-steps are performed but the OSD daemon is not started.
-.sp
-The latest option \fB\-\-reactivate\fP can re\-activate the OSD which has been
-deactivated with the \fBdeactivate\fP subcommand.
-.sp
-Usage:
-.INDENT 0.0
-.INDENT 3.5
-.sp
-.nf
-.ft C
-ceph\-disk activate [PATH] [\-\-reactivate]
-.ft P
-.fi
-.UNINDENT
-.UNINDENT
-.SS activate\-journal
-.sp
-Activate an OSD via it\(aqs journal device. \fBudev\fP triggers
-\fBceph\-disk activate\-journal <dev>\fP based on the partition type.
-.sp
-Usage:
-.INDENT 0.0
-.INDENT 3.5
-.sp
-.nf
-.ft C
-ceph\-disk activate\-journal [DEV]
-.ft P
-.fi
-.UNINDENT
-.UNINDENT
-.sp
-Here, [DEV] is the path to a journal block device.
-.sp
-Others options like \fB\-\-activate\-key\fP and \fB\-\-mark\-init\fP can also
-be used with this subcommand.
-.sp
-\fB\-\-mark\-init\fP provides init system to manage the OSD directory.
-.sp
-Usage:
-.INDENT 0.0
-.INDENT 3.5
-.sp
-.nf
-.ft C
-ceph\-disk activate\-journal [\-\-activate\-key PATH] [\-\-mark\-init INITSYSTEM] [DEV]
-.ft P
-.fi
-.UNINDENT
-.UNINDENT
-.SS activate\-all
-.sp
-Activate all tagged OSD partitions. \fBactivate\-all\fP relies on
-\fB/dev/disk/by\-parttype\-uuid/$typeuuid.$uuid\fP to find all partitions. Special
-\fBudev\fP rules are installed to create these links. It is triggered on ceph
-service start or run directly.
-.sp
-Usage:
-.INDENT 0.0
-.INDENT 3.5
-.sp
-.nf
-.ft C
-ceph\-disk activate\-all
-.ft P
-.fi
-.UNINDENT
-.UNINDENT
-.sp
-Others options like \fB\-\-activate\-key\fP and \fB\-\-mark\-init\fP can
-also be used with this subcommand.
-.sp
-\fB\-\-mark\-init\fP provides init system to manage the OSD directory.
-.sp
-Usage:
-.INDENT 0.0
-.INDENT 3.5
-.sp
-.nf
-.ft C
-ceph\-disk activate\-all [\-\-activate\-key PATH] [\-\-mark\-init INITSYSTEM]
-.ft P
-.fi
-.UNINDENT
-.UNINDENT
-.SS list
-.sp
-List disk partitions and Ceph OSDs. It is run directly or triggered by
-\fBceph\-deploy\fP\&.
-.sp
-Usage:
-.INDENT 0.0
-.INDENT 3.5
-.sp
-.nf
-.ft C
-ceph\-disk list
-.ft P
-.fi
-.UNINDENT
-.UNINDENT
-.SS suppress\-activate
-.sp
-Suppress activate on a device (prefix). Mark devices that you don\(aqt want to
-activate with a file like \fB/var/lib/ceph/tmp/suppress\-activate.sdb\fP where the
-last bit is the sanitized device name (/dev/X without the /dev/ prefix). A
-function \fBis_suppressed()\fP checks for and  matches a prefix (/dev/). It means
-suppressing sdb will stop activate on sdb1, sdb2, etc.
-.sp
-Usage:
-.INDENT 0.0
-.INDENT 3.5
-.sp
-.nf
-.ft C
-ceph\-disk suppress\-activate [PATH]
-.ft P
-.fi
-.UNINDENT
-.UNINDENT
-.sp
-Here, [PATH] is path to a block device or a directory.
-.SS unsuppress\-activate
-.sp
-Stop suppressing activate on a device (prefix). It is used to activate a device
-that was earlier kept deactivated using \fBsuppress\-activate\fP\&.
-.sp
-Usage:
-.INDENT 0.0
-.INDENT 3.5
-.sp
-.nf
-.ft C
-ceph\-disk unsuppress\-activate [PATH]
-.ft P
-.fi
-.UNINDENT
-.UNINDENT
-.sp
-Here, [PATH] is path to a block device or a directory.
-.SS deactivate
-.sp
-Deactivate the Ceph OSD. It stops OSD daemon and optionally marks it out. The
-content of the OSD is left untouched but the \fIready\fP, \fIactive\fP, \fIINIT\-specific\fP
-files are removed (so that it is not automatically re\-activated by the \fBudev\fP
-rules) and the file deactive is created to remember the OSD is deactivated.
-If the OSD is dmcrypt, remove the data dmcrypt map. When deactivate finishes,
-the OSD is \fBdown\fP\&. A deactivated OSD can later be re\-activated using the
-\fB\-\-reactivate\fP option of the \fBactivate\fP subcommand.
-.sp
-Usage:
-.INDENT 0.0
-.INDENT 3.5
-.sp
-.nf
-.ft C
-ceph\-disk deactivate [PATH]
-.ft P
-.fi
-.UNINDENT
-.UNINDENT
-.sp
-Here, [PATH] is a path to a block device or a directory.
-.sp
-Another option \fB\-\-mark\-out\fP can also be used with this subcommand.
-\fB\-\-mark\-out\fP marks the OSD out. The objects it contains will be remapped.
-If you are not sure you will destroy OSD, do not use this option.
-.sp
-You can also use \fBosd\-id\fP to deactivate an OSD with the option \fB\-\-deactivate\-by\-id\fP\&.
-.sp
-Usage:
-.INDENT 0.0
-.INDENT 3.5
-.sp
-.nf
-.ft C
-ceph\-disk deactivate \-\-deactivate\-by\-id [OSD\-ID]
-.ft P
-.fi
-.UNINDENT
-.UNINDENT
-.SS destroy
-.sp
-Destroy the Ceph OSD. It removes the OSD from the cluster, the crushmap and
-deallocates OSD ID. It can only destroy an OSD which is \fIdown\fP\&.
-.sp
-Usage:
-.INDENT 0.0
-.INDENT 3.5
-.sp
-.nf
-.ft C
-ceph\-disk destroy [PATH]
-.ft P
-.fi
-.UNINDENT
-.UNINDENT
-.sp
-Here, [PATH] is a path to a block device or a directory.
-.sp
-Another option \fB\-\-zap\fP can also be used with this subcommand.
-\fB\-\-zap\fP will destroy the partition table and content of the disk.
-.sp
-Usage:
-.INDENT 0.0
-.INDENT 3.5
-.sp
-.nf
-.ft C
-ceph\-disk destroy [PATH] [\-\-zap]
-.ft P
-.fi
-.UNINDENT
-.UNINDENT
-.sp
-You can also use the id of an OSD instead of the path with the option
-\fB\-\-destroy\-by\-id\fP\&.
 .sp
-Usage:
-.INDENT 0.0
-.INDENT 3.5
-.sp
-.nf
-.ft C
-ceph\-disk destroy \-\-destroy\-by\-id [OSD\-ID]
-.ft P
-.fi
-.UNINDENT
-.UNINDENT
-.SS zap
-.sp
-Zap/erase/destroy a device\(aqs partition table and contents. It actually uses
-\fBsgdisk\fP and it\(aqs option \fB\-\-zap\-all\fP to destroy both GPT and MBR data
-structures so that the disk becomes suitable for repartitioning. \fBsgdisk\fP
-then uses \fB\-\-mbrtogpt\fP to convert the MBR or BSD disklabel disk to a GPT
-disk. The \fBprepare\fP subcommand can now be executed which will create a new
-GPT partition. It is also run directly or triggered by \fBceph\-deploy\fP\&.
-.sp
-Usage:
-.INDENT 0.0
-.INDENT 3.5
-.sp
-.nf
-.ft C
-ceph\-disk zap [DEV]
-.ft P
-.fi
-.UNINDENT
-.UNINDENT
-.sp
-Here, [DEV] is path to a block device.
-.SH OPTIONS
-.INDENT 0.0
-.TP
-.B \-\-prepend\-to\-path PATH
-Prepend PATH to $PATH for backward compatibility (default \fB/usr/bin\fP).
-.UNINDENT
-.INDENT 0.0
-.TP
-.B \-\-statedir PATH
-Directory in which ceph configuration is preserved (default \fB/usr/lib/ceph\fP).
-.UNINDENT
-.INDENT 0.0
-.TP
-.B \-\-sysconfdir PATH
-Directory in which ceph configuration files are found (default \fB/etc/ceph\fP).
-.UNINDENT
-.INDENT 0.0
-.TP
-.B \-\-cluster
-Provide name of the ceph cluster in which the OSD is being prepared.
-.UNINDENT
-.INDENT 0.0
-.TP
-.B \-\-cluster\-uuid
-Provide uuid of the ceph cluster in which the OSD is being prepared.
-.UNINDENT
-.INDENT 0.0
-.TP
-.B \-\-fs\-type
-Provide the filesytem type for the OSD. e.g. \fBxfs/ext4/btrfs\fP\&.
-.UNINDENT
-.INDENT 0.0
-.TP
-.B \-\-osd\-uuid
-Unique OSD uuid to assign to the disk.
-.UNINDENT
-.INDENT 0.0
-.TP
-.B \-\-journal\-uuid
-Unique uuid to assign to the journal.
-.UNINDENT
-.INDENT 0.0
-.TP
-.B \-\-zap\-disk
-Destroy the partition table and content of a disk.
-.UNINDENT
-.INDENT 0.0
-.TP
-.B \-\-data\-dir
-Verify that \fB[data\-path]\fP is of a directory.
-.UNINDENT
-.INDENT 0.0
-.TP
-.B \-\-data\-dev
-Verify that \fB[data\-path]\fP is of a block device.
-.UNINDENT
-.INDENT 0.0
-.TP
-.B \-\-journal\-file
-Verify that journal is a file.
-.UNINDENT
-.INDENT 0.0
-.TP
-.B \-\-journal\-dev
-Verify that journal is a block device.
-.UNINDENT
-.INDENT 0.0
-.TP
-.B \-\-dmcrypt
-Encrypt \fB[data\-path]\fP and/or journal devices with \fBdm\-crypt\fP\&.
-.UNINDENT
-.INDENT 0.0
-.TP
-.B \-\-dmcrypt\-key\-dir
-Directory where \fBdm\-crypt\fP keys are stored.
-.UNINDENT
+The documentation for each subcommand (prepare, activate, etc.) can be displayed
+with its \fB\-\-help\fP option. For instance \fBceph\-disk prepare \-\-help\fP\&.
 .SH AVAILABILITY
 .sp
 \fBceph\-disk\fP is part of Ceph, a massively scalable, open\-source, distributed storage system. Please refer to
diff --git a/man/ceph-fuse.8 b/man/ceph-fuse.8
index cafb304..a89df0a 100644
--- a/man/ceph-fuse.8
+++ b/man/ceph-fuse.8
@@ -1,6 +1,6 @@
 .\" Man page generated from reStructuredText.
 .
-.TH "CEPH-FUSE" "8" "March 22, 2016" "dev" "Ceph"
+.TH "CEPH-FUSE" "8" "March 24, 2016" "dev" "Ceph"
 .SH NAME
 ceph-fuse \- FUSE-based client for ceph
 .
diff --git a/man/ceph-mds.8 b/man/ceph-mds.8
index 3ae6814..13fb217 100644
--- a/man/ceph-mds.8
+++ b/man/ceph-mds.8
@@ -1,6 +1,6 @@
 .\" Man page generated from reStructuredText.
 .
-.TH "CEPH-MDS" "8" "March 22, 2016" "dev" "Ceph"
+.TH "CEPH-MDS" "8" "March 24, 2016" "dev" "Ceph"
 .SH NAME
 ceph-mds \- ceph metadata server daemon
 .
diff --git a/man/ceph-mon.8 b/man/ceph-mon.8
index 1949b98..6ab7488 100644
--- a/man/ceph-mon.8
+++ b/man/ceph-mon.8
@@ -1,6 +1,6 @@
 .\" Man page generated from reStructuredText.
 .
-.TH "CEPH-MON" "8" "March 22, 2016" "dev" "Ceph"
+.TH "CEPH-MON" "8" "March 24, 2016" "dev" "Ceph"
 .SH NAME
 ceph-mon \- ceph monitor daemon
 .
diff --git a/man/ceph-osd.8 b/man/ceph-osd.8
index 8a8693b..fff836f 100644
--- a/man/ceph-osd.8
+++ b/man/ceph-osd.8
@@ -1,6 +1,6 @@
 .\" Man page generated from reStructuredText.
 .
-.TH "CEPH-OSD" "8" "March 22, 2016" "dev" "Ceph"
+.TH "CEPH-OSD" "8" "March 24, 2016" "dev" "Ceph"
 .SH NAME
 ceph-osd \- ceph object storage daemon
 .
diff --git a/man/ceph-post-file.8 b/man/ceph-post-file.8
index e9ea346..d94d568 100644
--- a/man/ceph-post-file.8
+++ b/man/ceph-post-file.8
@@ -1,6 +1,6 @@
 .\" Man page generated from reStructuredText.
 .
-.TH "CEPH-POST-FILE" "8" "March 22, 2016" "dev" "Ceph"
+.TH "CEPH-POST-FILE" "8" "March 24, 2016" "dev" "Ceph"
 .SH NAME
 ceph-post-file \- post files for ceph developers
 .
diff --git a/man/ceph-rbdnamer.8 b/man/ceph-rbdnamer.8
index 7dc6e21..0919425 100644
--- a/man/ceph-rbdnamer.8
+++ b/man/ceph-rbdnamer.8
@@ -1,6 +1,6 @@
 .\" Man page generated from reStructuredText.
 .
-.TH "CEPH-RBDNAMER" "8" "March 22, 2016" "dev" "Ceph"
+.TH "CEPH-RBDNAMER" "8" "March 24, 2016" "dev" "Ceph"
 .SH NAME
 ceph-rbdnamer \- udev helper to name RBD devices
 .
diff --git a/man/ceph-rest-api.8 b/man/ceph-rest-api.8
index 9c409e8..c431a6b 100644
--- a/man/ceph-rest-api.8
+++ b/man/ceph-rest-api.8
@@ -1,6 +1,6 @@
 .\" Man page generated from reStructuredText.
 .
-.TH "CEPH-REST-API" "8" "March 22, 2016" "dev" "Ceph"
+.TH "CEPH-REST-API" "8" "March 24, 2016" "dev" "Ceph"
 .SH NAME
 ceph-rest-api \- ceph RESTlike administration server
 .
diff --git a/man/ceph-run.8 b/man/ceph-run.8
index a04c048..500f401 100644
--- a/man/ceph-run.8
+++ b/man/ceph-run.8
@@ -1,6 +1,6 @@
 .\" Man page generated from reStructuredText.
 .
-.TH "CEPH-RUN" "8" "March 22, 2016" "dev" "Ceph"
+.TH "CEPH-RUN" "8" "March 24, 2016" "dev" "Ceph"
 .SH NAME
 ceph-run \- restart daemon on core dump
 .
diff --git a/man/ceph-syn.8 b/man/ceph-syn.8
index df35cbe..61e790a 100644
--- a/man/ceph-syn.8
+++ b/man/ceph-syn.8
@@ -1,6 +1,6 @@
 .\" Man page generated from reStructuredText.
 .
-.TH "CEPH-SYN" "8" "March 22, 2016" "dev" "Ceph"
+.TH "CEPH-SYN" "8" "March 24, 2016" "dev" "Ceph"
 .SH NAME
 ceph-syn \- ceph synthetic workload generator
 .
diff --git a/man/ceph.8 b/man/ceph.8
index 885b5da..945a40f 100644
--- a/man/ceph.8
+++ b/man/ceph.8
@@ -1,6 +1,6 @@
 .\" Man page generated from reStructuredText.
 .
-.TH "CEPH" "8" "March 22, 2016" "dev" "Ceph"
+.TH "CEPH" "8" "March 24, 2016" "dev" "Ceph"
 .SH NAME
 ceph \- ceph administration tool
 .
@@ -80,7 +80,7 @@ level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
 .fi
 .sp
 .nf
-\fBceph\fP \fBmds\fP [ \fIadd_data_pool\fP | \fIcluster_down\fP | \fIcluster_up\fP | \fIcompat\fP | \fIdeactivate\fP | \fIdump\fP | \fIfail\fP | \fIgetmap\fP | \fInewfs\fP | \fIremove_data_pool\fP | \fIrm\fP | \fIrmfailed\fP | \fIset\fP | \fIset_max_mds\fP | \fIset_state\fP | \fIsetmap\fP | \fIstat\fP | \fIstop\fP | \fItell\fP ] ...
+\fBceph\fP \fBmds\fP [ \fIadd_data_pool\fP | \fIcluster_down\fP | \fIcluster_up\fP | \fIcompat\fP | \fIdeactivate\fP | \fIdump\fP | \fIfail\fP | \fIgetmap\fP | \fInewfs\fP | \fIremove_data_pool\fP | \fIrm\fP | \fIrmfailed\fP | \fIset\fP | \fIset_max_mds\fP | \fIset_state\fP | \fIstat\fP | \fIstop\fP | \fItell\fP ] ...
 .fi
 .sp
 .nf
@@ -854,20 +854,6 @@ ceph mds set_state <int[0\-]> <int[0\-20]>
 .UNINDENT
 .UNINDENT
 .sp
-Subcommand \fBsetmap\fP sets mds map; must supply correct epoch number.
-.sp
-Usage:
-.INDENT 0.0
-.INDENT 3.5
-.sp
-.nf
-.ft C
-ceph mds setmap <int[0\-]>
-.ft P
-.fi
-.UNINDENT
-.UNINDENT
-.sp
 Subcommand \fBstat\fP shows MDS status.
 .sp
 Usage:
@@ -2049,6 +2035,7 @@ Usage:
 .nf
 .ft C
 ceph osd reweight\-by\-pg {<int[100\-]>} {<poolname> [<poolname...]}
+{\-\-no\-increasing}
 .ft P
 .fi
 .UNINDENT
@@ -2064,6 +2051,7 @@ Usage:
 .nf
 .ft C
 ceph osd reweight\-by\-utilization {<int[100\-]>}
+{\-\-no\-increasing}
 .ft P
 .fi
 .UNINDENT
diff --git a/man/ceph_selinux.8 b/man/ceph_selinux.8
index a646374..e2482e8 100644
--- a/man/ceph_selinux.8
+++ b/man/ceph_selinux.8
@@ -1,4 +1,4 @@
-.TH  "ceph_selinux"  "8"  "15-08-10" "ceph" "SELinux Policy ceph"
+.TH  "ceph_selinux"  "8"  "16-02-11" "ceph" "SELinux Policy ceph"
 .SH "NAME"
 ceph_selinux \- Security Enhanced Linux Policy for the ceph processes
 .SH "DESCRIPTION"
@@ -170,6 +170,8 @@ The SELinux process type ceph_t can manage files labeled with the following file
 
 	/var/log/ceph(/.*)?
 .br
+	/var/log/radosgw(/.*)?
+.br
 
 .br
 .B ceph_var_lib_t
@@ -238,6 +240,36 @@ The SELinux process type ceph_t can manage files labeled with the following file
 .br
 
 .br
+.B initrc_tmp_t
+
+
+.br
+.B mnt_t
+
+	/mnt(/[^/]*)?
+.br
+	/mnt(/[^/]*)?
+.br
+	/rhev(/[^/]*)?
+.br
+	/media(/[^/]*)?
+.br
+	/media(/[^/]*)?
+.br
+	/media/\.hal-.*
+.br
+	/var/run/media(/[^/]*)?
+.br
+	/net
+.br
+	/afs
+.br
+	/rhev
+.br
+	/misc
+.br
+
+.br
 .B root_t
 
 	/
@@ -246,6 +278,24 @@ The SELinux process type ceph_t can manage files labeled with the following file
 .br
 
 .br
+.B tmp_t
+
+	/sandbox(/.*)?
+.br
+	/tmp
+.br
+	/usr/tmp
+.br
+	/var/tmp
+.br
+	/tmp-inst
+.br
+	/var/tmp-inst
+.br
+	/var/tmp/vi\.recover
+.br
+
+.br
 .B var_run_t
 
 	/run/.*
@@ -319,7 +369,7 @@ Paths:
 .br
 .TP 5
 Paths:
-/var/log/ceph(/.*)?
+/var/log/ceph(/.*)?, /var/log/radosgw(/.*)?
 
 .EX
 .PP
diff --git a/man/cephfs.8 b/man/cephfs.8
index df29f95..d1f29ed 100644
--- a/man/cephfs.8
+++ b/man/cephfs.8
@@ -1,6 +1,6 @@
 .\" Man page generated from reStructuredText.
 .
-.TH "CEPHFS" "8" "March 22, 2016" "dev" "Ceph"
+.TH "CEPHFS" "8" "March 24, 2016" "dev" "Ceph"
 .SH NAME
 cephfs \- ceph file system options utility
 .
diff --git a/man/crushtool.8 b/man/crushtool.8
index bd04f1b..793e820 100644
--- a/man/crushtool.8
+++ b/man/crushtool.8
@@ -1,6 +1,6 @@
 .\" Man page generated from reStructuredText.
 .
-.TH "CRUSHTOOL" "8" "March 22, 2016" "dev" "Ceph"
+.TH "CRUSHTOOL" "8" "March 24, 2016" "dev" "Ceph"
 .SH NAME
 crushtool \- CRUSH map manipulation tool
 .
diff --git a/man/librados-config.8 b/man/librados-config.8
index 59961c8..21c6884 100644
--- a/man/librados-config.8
+++ b/man/librados-config.8
@@ -1,6 +1,6 @@
 .\" Man page generated from reStructuredText.
 .
-.TH "LIBRADOS-CONFIG" "8" "March 22, 2016" "dev" "Ceph"
+.TH "LIBRADOS-CONFIG" "8" "March 24, 2016" "dev" "Ceph"
 .SH NAME
 librados-config \- display information about librados
 .
diff --git a/man/monmaptool.8 b/man/monmaptool.8
index ad2b12d..8b62123 100644
--- a/man/monmaptool.8
+++ b/man/monmaptool.8
@@ -1,6 +1,6 @@
 .\" Man page generated from reStructuredText.
 .
-.TH "MONMAPTOOL" "8" "March 22, 2016" "dev" "Ceph"
+.TH "MONMAPTOOL" "8" "March 24, 2016" "dev" "Ceph"
 .SH NAME
 monmaptool \- ceph monitor cluster map manipulation tool
 .
diff --git a/man/mount.ceph.8 b/man/mount.ceph.8
index 3c4e624..52de2de 100644
--- a/man/mount.ceph.8
+++ b/man/mount.ceph.8
@@ -1,6 +1,6 @@
 .\" Man page generated from reStructuredText.
 .
-.TH "MOUNT.CEPH" "8" "March 22, 2016" "dev" "Ceph"
+.TH "MOUNT.CEPH" "8" "March 24, 2016" "dev" "Ceph"
 .SH NAME
 mount.ceph \- mount a ceph file system
 .
diff --git a/man/osdmaptool.8 b/man/osdmaptool.8
index 89664a1..23f0138 100644
--- a/man/osdmaptool.8
+++ b/man/osdmaptool.8
@@ -1,6 +1,6 @@
 .\" Man page generated from reStructuredText.
 .
-.TH "OSDMAPTOOL" "8" "March 22, 2016" "dev" "Ceph"
+.TH "OSDMAPTOOL" "8" "March 24, 2016" "dev" "Ceph"
 .SH NAME
 osdmaptool \- ceph osd cluster map manipulation tool
 .
diff --git a/man/rados.8 b/man/rados.8
index f23f2ae..37e2d3d 100644
--- a/man/rados.8
+++ b/man/rados.8
@@ -1,6 +1,6 @@
 .\" Man page generated from reStructuredText.
 .
-.TH "RADOS" "8" "March 22, 2016" "dev" "Ceph"
+.TH "RADOS" "8" "March 24, 2016" "dev" "Ceph"
 .SH NAME
 rados \- rados object storage utility
 .
diff --git a/man/radosgw-admin.8 b/man/radosgw-admin.8
index e9df855..0efefb7 100644
--- a/man/radosgw-admin.8
+++ b/man/radosgw-admin.8
@@ -1,6 +1,6 @@
 .\" Man page generated from reStructuredText.
 .
-.TH "RADOSGW-ADMIN" "8" "March 22, 2016" "dev" "Ceph"
+.TH "RADOSGW-ADMIN" "8" "March 24, 2016" "dev" "Ceph"
 .SH NAME
 radosgw-admin \- rados REST gateway user administration utility
 .
diff --git a/man/radosgw.8 b/man/radosgw.8
index 886c078..afaa588 100644
--- a/man/radosgw.8
+++ b/man/radosgw.8
@@ -1,6 +1,6 @@
 .\" Man page generated from reStructuredText.
 .
-.TH "RADOSGW" "8" "March 22, 2016" "dev" "Ceph"
+.TH "RADOSGW" "8" "March 24, 2016" "dev" "Ceph"
 .SH NAME
 radosgw \- rados REST gateway
 .
diff --git a/man/rbd-fuse.8 b/man/rbd-fuse.8
index bcf7adc..056abb9 100644
--- a/man/rbd-fuse.8
+++ b/man/rbd-fuse.8
@@ -1,6 +1,6 @@
 .\" Man page generated from reStructuredText.
 .
-.TH "RBD-FUSE" "8" "March 22, 2016" "dev" "Ceph"
+.TH "RBD-FUSE" "8" "March 24, 2016" "dev" "Ceph"
 .SH NAME
 rbd-fuse \- expose rbd images as files
 .
diff --git a/man/rbd-mirror.8 b/man/rbd-mirror.8
index 9b3ffdd..289c5fd 100644
--- a/man/rbd-mirror.8
+++ b/man/rbd-mirror.8
@@ -1,6 +1,6 @@
 .\" Man page generated from reStructuredText.
 .
-.TH "RBD-MIRROR" "8" "March 22, 2016" "dev" "Ceph"
+.TH "RBD-MIRROR" "8" "March 24, 2016" "dev" "Ceph"
 .SH NAME
 rbd-mirror \- Ceph daemon for mirroring RBD images
 .
diff --git a/man/rbd-nbd.8 b/man/rbd-nbd.8
index 83c3198..0211dc6 100644
--- a/man/rbd-nbd.8
+++ b/man/rbd-nbd.8
@@ -1,6 +1,6 @@
 .\" Man page generated from reStructuredText.
 .
-.TH "RBD-NBD" "8" "March 22, 2016" "dev" "Ceph"
+.TH "RBD-NBD" "8" "March 24, 2016" "dev" "Ceph"
 .SH NAME
 rbd-nbd \- map rbd images to nbd device
 .
diff --git a/man/rbd-replay-many.8 b/man/rbd-replay-many.8
index b8f6d2f..8ae20a1 100644
--- a/man/rbd-replay-many.8
+++ b/man/rbd-replay-many.8
@@ -1,6 +1,6 @@
 .\" Man page generated from reStructuredText.
 .
-.TH "RBD-REPLAY-MANY" "8" "March 22, 2016" "dev" "Ceph"
+.TH "RBD-REPLAY-MANY" "8" "March 24, 2016" "dev" "Ceph"
 .SH NAME
 rbd-replay-many \- replay a rados block device (RBD) workload on several clients
 .
diff --git a/man/rbd-replay-prep.8 b/man/rbd-replay-prep.8
index 58458c8..ebb7c58 100644
--- a/man/rbd-replay-prep.8
+++ b/man/rbd-replay-prep.8
@@ -1,6 +1,6 @@
 .\" Man page generated from reStructuredText.
 .
-.TH "RBD-REPLAY-PREP" "8" "March 22, 2016" "dev" "Ceph"
+.TH "RBD-REPLAY-PREP" "8" "March 24, 2016" "dev" "Ceph"
 .SH NAME
 rbd-replay-prep \- prepare captured rados block device (RBD) workloads for replay
 .
diff --git a/man/rbd-replay.8 b/man/rbd-replay.8
index 24c4d38..c02ea9f 100644
--- a/man/rbd-replay.8
+++ b/man/rbd-replay.8
@@ -1,6 +1,6 @@
 .\" Man page generated from reStructuredText.
 .
-.TH "RBD-REPLAY" "8" "March 22, 2016" "dev" "Ceph"
+.TH "RBD-REPLAY" "8" "March 24, 2016" "dev" "Ceph"
 .SH NAME
 rbd-replay \- replay rados block device (RBD) workloads
 .
diff --git a/man/rbd.8 b/man/rbd.8
index b689909..c2be8e6 100644
--- a/man/rbd.8
+++ b/man/rbd.8
@@ -1,6 +1,6 @@
 .\" Man page generated from reStructuredText.
 .
-.TH "RBD" "8" "March 22, 2016" "dev" "Ceph"
+.TH "RBD" "8" "March 24, 2016" "dev" "Ceph"
 .SH NAME
 rbd \- manage rados block device (RBD) images
 .
@@ -78,9 +78,9 @@ default for some commands).
 Specifies which object layout to use. The default is 1.
 .INDENT 7.0
 .IP \(bu 2
-format 1 \- Use the original format for a new rbd image. This format is
-understood by all versions of librbd and the kernel rbd module, but
-does not support newer features like cloning.
+format 1 \- (deprecated) Use the original format for a new rbd image. This
+format is understood by all versions of librbd and the kernel rbd module,
+but does not support newer features like cloning.
 .IP \(bu 2
 format 2 \- Use the second rbd format, which is supported by
 librbd and kernel since version 3.11 (except for striping). This adds
diff --git a/missing b/missing
index f62bbae..db98974 100755
--- a/missing
+++ b/missing
@@ -3,7 +3,7 @@
 
 scriptversion=2013-10-28.13; # UTC
 
-# Copyright (C) 1996-2014 Free Software Foundation, Inc.
+# Copyright (C) 1996-2013 Free Software Foundation, Inc.
 # Originally written by Fran,cois Pinard <pinard at iro.umontreal.ca>, 1996.
 
 # This program is free software; you can redistribute it and/or modify
diff --git a/py-compile b/py-compile
index bc20391..46ea866 100755
--- a/py-compile
+++ b/py-compile
@@ -3,7 +3,7 @@
 
 scriptversion=2011-06-08.12; # UTC
 
-# Copyright (C) 2000-2014 Free Software Foundation, Inc.
+# Copyright (C) 2000-2013 Free Software Foundation, Inc.
 
 # This program is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
diff --git a/selinux/Makefile.in b/selinux/Makefile.in
index fab874f..a2307c3 100644
--- a/selinux/Makefile.in
+++ b/selinux/Makefile.in
@@ -1,7 +1,7 @@
-# Makefile.in generated by automake 1.15 from Makefile.am.
+# Makefile.in generated by automake 1.14.1 from Makefile.am.
 # @configure_input@
 
-# Copyright (C) 1994-2014 Free Software Foundation, Inc.
+# Copyright (C) 1994-2013 Free Software Foundation, Inc.
 
 # This Makefile.in is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -14,17 +14,7 @@
 
 @SET_MAKE@
 VPATH = @srcdir@
-am__is_gnu_make = { \
-  if test -z '$(MAKELEVEL)'; then \
-    false; \
-  elif test -n '$(MAKE_HOST)'; then \
-    true; \
-  elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
-    true; \
-  else \
-    false; \
-  fi; \
-}
+am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
 am__make_running_with_option = \
   case $${target_option-} in \
       ?) ;; \
@@ -89,6 +79,7 @@ build_triplet = @build@
 host_triplet = @host@
 target_triplet = @target@
 subdir = selinux
+DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
 am__aclocal_m4_deps = $(top_srcdir)/m4/ac_check_classpath.m4 \
 	$(top_srcdir)/m4/ac_prog_jar.m4 \
@@ -107,7 +98,6 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/ac_check_classpath.m4 \
 	$(top_srcdir)/m4/pkg.m4 $(top_srcdir)/configure.ac
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
 	$(ACLOCAL_M4)
-DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON)
 mkinstalldirs = $(install_sh) -d
 CONFIG_HEADER = $(top_builddir)/src/acconfig.h
 CONFIG_CLEAN_FILES =
@@ -132,7 +122,6 @@ am__can_run_installinfo = \
     *) (install-info --version) >/dev/null 2>&1;; \
   esac
 am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
-am__DIST_COMMON = $(srcdir)/Makefile.in
 DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
 ACLOCAL = @ACLOCAL@
 AMTAR = @AMTAR@
@@ -225,7 +214,6 @@ LN_S = @LN_S@
 LTLIBOBJS = @LTLIBOBJS@
 LTTNG_GEN_TP_CHECK = @LTTNG_GEN_TP_CHECK@
 LTTNG_GEN_TP_PROG = @LTTNG_GEN_TP_PROG@
-LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
 MAKEINFO = @MAKEINFO@
 MANIFEST_TOOL = @MANIFEST_TOOL@
 MKDIR_P = @MKDIR_P@
@@ -252,7 +240,10 @@ PTHREAD_CC = @PTHREAD_CC@
 PTHREAD_CFLAGS = @PTHREAD_CFLAGS@
 PTHREAD_LIBS = @PTHREAD_LIBS@
 PYTHON = @PYTHON@
+PYTHON_CFLAGS = @PYTHON_CFLAGS@
+PYTHON_CONFIG_CHECK = @PYTHON_CONFIG_CHECK@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
+PYTHON_LDFLAGS = @PYTHON_LDFLAGS@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
 PYTHON_PREFIX = @PYTHON_PREFIX@
 PYTHON_VERSION = @PYTHON_VERSION@
@@ -321,7 +312,6 @@ program_transform_name = @program_transform_name@
 psdir = @psdir@
 pyexecdir = @pyexecdir@
 pythondir = @pythondir@
-runstatedir = @runstatedir@
 sbindir = @sbindir@
 sharedstatedir = @sharedstatedir@
 srcdir = @srcdir@
@@ -357,6 +347,7 @@ $(srcdir)/Makefile.in:  $(srcdir)/Makefile.am  $(am__configure_deps)
 	echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign selinux/Makefile'; \
 	$(am__cd) $(top_srcdir) && \
 	  $(AUTOMAKE) --foreign selinux/Makefile
+.PRECIOUS: Makefile
 Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
 	@case '$?' in \
 	  *config.status*) \
@@ -536,8 +527,6 @@ uninstall-am:
 	mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
 	tags-am uninstall uninstall-am
 
-.PRECIOUS: Makefile
-
 
 ceph.pp: ceph.te ceph.fc ceph.if
 	$(MAKE) -j1 -f $(datadir)/selinux/devel/Makefile ceph.pp
diff --git a/selinux/ceph.fc b/selinux/ceph.fc
index 6b8d062..3192689 100644
--- a/selinux/ceph.fc
+++ b/selinux/ceph.fc
@@ -9,5 +9,6 @@
 /var/lib/ceph(/.*)?		gen_context(system_u:object_r:ceph_var_lib_t,s0)
 
 /var/log/ceph(/.*)?		gen_context(system_u:object_r:ceph_log_t,s0)
+/var/log/radosgw(/.*)?		gen_context(system_u:object_r:ceph_log_t,s0)
 
 /var/run/ceph(/.*)?		gen_context(system_u:object_r:ceph_var_run_t,s0)
diff --git a/selinux/ceph.te b/selinux/ceph.te
index a215df8..52bb504 100644
--- a/selinux/ceph.te
+++ b/selinux/ceph.te
@@ -1,4 +1,4 @@
-policy_module(ceph, 1.1.0)
+policy_module(ceph, 1.1.1)
 
 require {
 	type sysfs_t;
@@ -43,7 +43,7 @@ files_pid_file(ceph_var_run_t)
 allow ceph_t self:process { signal_perms };
 allow ceph_t self:fifo_file rw_fifo_file_perms;
 allow ceph_t self:unix_stream_socket create_stream_socket_perms;
-allow ceph_t self:capability { setuid setgid };
+allow ceph_t self:capability { setuid setgid dac_override };
 
 manage_dirs_pattern(ceph_t, ceph_log_t, ceph_log_t)
 manage_files_pattern(ceph_t, ceph_log_t, ceph_log_t)
@@ -94,6 +94,7 @@ files_list_tmp(ceph_t)
 fstools_exec(ceph_t)
 nis_use_ypbind_uncond(ceph_t)
 storage_raw_rw_fixed_disk(ceph_t)
+files_manage_generic_locks(ceph_t)
 
 allow ceph_t sysfs_t:dir read;
 allow ceph_t sysfs_t:file { read getattr open };
diff --git a/src/.git_version b/src/.git_version
index 640de07..a8085ff 100644
--- a/src/.git_version
+++ b/src/.git_version
@@ -1,2 +1,2 @@
-5acb2655ec55c904e4c11137971c78bac5b76e4e
-v10.0.5
+96ae8bd25f31862dbd5302f304ebf8bf1166aba6
+v10.1.0
diff --git a/src/Makefile-client.am b/src/Makefile-client.am
index 6babaf6..98e8ebb 100644
--- a/src/Makefile-client.am
+++ b/src/Makefile-client.am
@@ -34,8 +34,6 @@ bash_completion_DATA += \
 	$(srcdir)/bash_completion/rados \
 	$(srcdir)/bash_completion/radosgw-admin
 
-python_PYTHON += pybind/rados.py
-
 librados_config_SOURCES = librados-config.cc
 librados_config_LDADD = $(LIBRADOS) $(CEPH_GLOBAL)
 bin_PROGRAMS += librados-config
@@ -79,7 +77,6 @@ cephfs_SOURCES = cephfs.cc
 cephfs_LDADD = $(LIBCOMMON)
 bin_PROGRAMS += cephfs
 
-python_PYTHON += pybind/cephfs.py
 python_PYTHON += pybind/ceph_volume_client.py
 
 # libcephfs (this should go somewhere else in the future)
diff --git a/src/Makefile-env.am b/src/Makefile-env.am
index a347537..2044647 100644
--- a/src/Makefile-env.am
+++ b/src/Makefile-env.am
@@ -63,7 +63,7 @@ HARDENING_CFLAGS = \
                    --param=ssp-buffer-size=4 \
                    -fPIE
 
-SET_STACK_PROTECTOR_STRONG = $(shell expr `gcc -dumpversion` \>= 4.9)
+SET_STACK_PROTECTOR_STRONG = $(shell expr `$(CC) -dumpversion` \>= 4.9)
 
 		ifeq ($(SET_STACK_PROTECTOR_STRONG),1)
 				HARDENING_CFLAGS += -fstack-protector-strong
@@ -291,10 +291,13 @@ CEPH_GLOBAL = $(LIBGLOBAL) $(LIBCOMMON) $(PTHREAD_LIBS) -lm $(CRYPTO_LIBS) $(EXT
 LIBCOMMON_DEPS =
 LIBRADOS_DEPS =
 LIBRGW_DEPS =
+LIBCIVETWEB_DEPS =
 
 # This is used by the dencoder test
 DENCODER_SOURCES =
 DENCODER_DEPS =
 
+# put virtualenvs in this directory for build
+CEPH_BUILD_VIRTUALENV="/tmp/"
 
 radoslibdir = $(libdir)/rados-classes
diff --git a/src/Makefile.am b/src/Makefile.am
index d2f99b8..cc973b3 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -119,6 +119,9 @@ EXTRA_DIST += \
 	$(srcdir)/upstart/ceph-mds.conf \
 	$(srcdir)/upstart/ceph-mds-all.conf \
 	$(srcdir)/upstart/ceph-mds-all-starter.conf \
+	$(srcdir)/upstart/ceph-rbd-mirror.conf \
+	$(srcdir)/upstart/ceph-rbd-mirror-all.conf \
+	$(srcdir)/upstart/ceph-rbd-mirror-all-starter.conf \
 	$(srcdir)/upstart/radosgw.conf \
 	$(srcdir)/upstart/radosgw-all.conf \
 	$(srcdir)/upstart/radosgw-all-starter.conf \
diff --git a/src/Makefile.in b/src/Makefile.in
index df3217e..cdf135e 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -1,7 +1,7 @@
-# Makefile.in generated by automake 1.15 from Makefile.am.
+# Makefile.in generated by automake 1.14.1 from Makefile.am.
 # @configure_input@
 
-# Copyright (C) 1994-2014 Free Software Foundation, Inc.
+# Copyright (C) 1994-2013 Free Software Foundation, Inc.
 
 # This Makefile.in is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -83,18 +83,66 @@ POST_UNINSTALL = :
 build_triplet = @build@
 host_triplet = @host@
 target_triplet = @target@
+DIST_COMMON = $(srcdir)/Makefile-env.am $(srcdir)/arch/Makefile.am \
+	$(srcdir)/auth/Makefile.am $(srcdir)/brag/Makefile.am \
+	$(srcdir)/ceph-detect-init/Makefile.am \
+	$(srcdir)/ceph-disk/Makefile.am $(srcdir)/crush/Makefile.am \
+	$(srcdir)/kv/Makefile.am $(srcdir)/mon/Makefile.am \
+	$(srcdir)/mds/Makefile.am $(srcdir)/mds/Makefile-client.am \
+	$(srcdir)/mds/Makefile-server.am $(srcdir)/os/Makefile.am \
+	$(srcdir)/osd/Makefile.am $(srcdir)/erasure-code/Makefile.am \
+	$(srcdir)/erasure-code/jerasure/Makefile.am \
+	$(srcdir)/erasure-code/lrc/Makefile.am \
+	$(srcdir)/erasure-code/shec/Makefile.am \
+	$(srcdir)/erasure-code/isa/Makefile.am \
+	$(srcdir)/compressor/Makefile.am \
+	$(srcdir)/compressor/zlib/Makefile.am \
+	$(srcdir)/compressor/snappy/Makefile.am \
+	$(srcdir)/osdc/Makefile.am $(srcdir)/client/Makefile.am \
+	$(srcdir)/global/Makefile.am $(srcdir)/json_spirit/Makefile.am \
+	$(srcdir)/log/Makefile.am $(srcdir)/perfglue/Makefile.am \
+	$(srcdir)/common/Makefile.am $(srcdir)/msg/Makefile.am \
+	$(srcdir)/messages/Makefile.am $(srcdir)/include/Makefile.am \
+	$(srcdir)/librados/Makefile.am \
+	$(srcdir)/libradosstriper/Makefile.am \
+	$(srcdir)/journal/Makefile.am $(srcdir)/librbd/Makefile.am \
+	$(srcdir)/rgw/Makefile.am $(srcdir)/cls/Makefile.am \
+	$(srcdir)/cls/Makefile-client.am \
+	$(srcdir)/cls/Makefile-server.am \
+	$(srcdir)/key_value_store/Makefile.am \
+	$(srcdir)/rbd_replay/Makefile.am $(srcdir)/test/Makefile.am \
+	$(srcdir)/test/erasure-code/Makefile.am \
+	$(srcdir)/test/messenger/Makefile.am \
+	$(srcdir)/test/compressor/Makefile.am \
+	$(srcdir)/test/Makefile-client.am \
+	$(srcdir)/test/Makefile-server.am $(srcdir)/tools/Makefile.am \
+	$(srcdir)/tools/Makefile-client.am \
+	$(srcdir)/tools/Makefile-server.am \
+	$(srcdir)/Makefile-rocksdb.am $(srcdir)/Makefile-spdk.am \
+	$(srcdir)/tracing/Makefile.am $(srcdir)/pybind/Makefile.am \
+	$(srcdir)/pybind/rados/Makefile.am \
+	$(srcdir)/pybind/rbd/Makefile.am \
+	$(srcdir)/pybind/cephfs/Makefile.am \
+	$(srcdir)/Makefile-client.am $(srcdir)/Makefile-server.am \
+	$(srcdir)/Makefile.in $(srcdir)/Makefile.am \
+	$(srcdir)/acconfig.h.in $(dist_bin_SCRIPTS) \
+	$(top_srcdir)/depcomp $(am__python_PYTHON_DIST) \
+	$(top_srcdir)/py-compile $(dist_noinst_DATA) \
+	$(am__noinst_HEADERS_DIST) $(top_srcdir)/test-driver README \
+	TODO
 bin_PROGRAMS = $(am__EXEEXT_28) $(am__EXEEXT_29) $(am__EXEEXT_30) \
 	$(am__EXEEXT_31) $(am__EXEEXT_32) $(am__EXEEXT_33) \
 	$(am__EXEEXT_34) $(am__EXEEXT_35) $(am__EXEEXT_36) \
-	$(am__EXEEXT_37) $(am__EXEEXT_38) monmaptool$(EXEEXT) \
-	crushtool$(EXEEXT) osdmaptool$(EXEEXT) ceph-conf$(EXEEXT) \
-	ceph-authtool$(EXEEXT) $(am__EXEEXT_39) $(am__EXEEXT_40) \
+	$(am__EXEEXT_37) $(am__EXEEXT_38) $(am__EXEEXT_39) \
+	monmaptool$(EXEEXT) crushtool$(EXEEXT) osdmaptool$(EXEEXT) \
+	ceph-conf$(EXEEXT) ceph-authtool$(EXEEXT) $(am__EXEEXT_40) \
 	$(am__EXEEXT_41) $(am__EXEEXT_42) $(am__EXEEXT_43) \
-	$(am__EXEEXT_44) $(am__EXEEXT_45) $(am__EXEEXT_46)
-noinst_PROGRAMS = $(am__EXEEXT_64) $(am__EXEEXT_65) $(am__EXEEXT_66)
+	$(am__EXEEXT_44) $(am__EXEEXT_45) $(am__EXEEXT_46) \
+	$(am__EXEEXT_47)
+noinst_PROGRAMS = $(am__EXEEXT_65) $(am__EXEEXT_66) $(am__EXEEXT_67)
 sbin_PROGRAMS =
-su_sbin_PROGRAMS = $(am__EXEEXT_67)
-check_PROGRAMS = $(am__EXEEXT_62) $(am__EXEEXT_63) \
+su_sbin_PROGRAMS = $(am__EXEEXT_68)
+check_PROGRAMS = $(am__EXEEXT_63) $(am__EXEEXT_64) \
 	unittest_subprocess$(EXEEXT) \
 	unittest_async_compressor$(EXEEXT)
 
@@ -196,6 +244,7 @@ check_PROGRAMS = $(am__EXEEXT_62) $(am__EXEEXT_63) \
 @ENABLE_SERVER_TRUE@@WITH_MDS_TRUE@	mds/flock.h mds/locks.c \
 @ENABLE_SERVER_TRUE@@WITH_MDS_TRUE@	mds/locks.h mds/CDentry.h \
 @ENABLE_SERVER_TRUE@@WITH_MDS_TRUE@	mds/CDir.h mds/CInode.h \
+ at ENABLE_SERVER_TRUE@@WITH_MDS_TRUE@	mds/DamageTable.h \
 @ENABLE_SERVER_TRUE@@WITH_MDS_TRUE@	mds/Capability.h \
 @ENABLE_SERVER_TRUE@@WITH_MDS_TRUE@	mds/InoTable.h \
 @ENABLE_SERVER_TRUE@@WITH_MDS_TRUE@	mds/JournalPointer.h \
@@ -211,7 +260,8 @@ check_PROGRAMS = $(am__EXEEXT_62) $(am__EXEEXT_63) \
 @ENABLE_SERVER_TRUE@@WITH_MDS_TRUE@	mds/Beacon.h \
 @ENABLE_SERVER_TRUE@@WITH_MDS_TRUE@	mds/MDSContext.h \
 @ENABLE_SERVER_TRUE@@WITH_MDS_TRUE@	mds/MDSAuthCaps.h \
- at ENABLE_SERVER_TRUE@@WITH_MDS_TRUE@	mds/MDSMap.h mds/MDSTable.h \
+ at ENABLE_SERVER_TRUE@@WITH_MDS_TRUE@	mds/MDSMap.h mds/FSMap.h \
+ at ENABLE_SERVER_TRUE@@WITH_MDS_TRUE@	mds/MDSTable.h \
 @ENABLE_SERVER_TRUE@@WITH_MDS_TRUE@	mds/MDSTableServer.h \
 @ENABLE_SERVER_TRUE@@WITH_MDS_TRUE@	mds/MDSTableClient.h \
 @ENABLE_SERVER_TRUE@@WITH_MDS_TRUE@	mds/Mutation.h \
@@ -276,6 +326,7 @@ check_PROGRAMS = $(am__EXEEXT_62) $(am__EXEEXT_63) \
 @ENABLE_SERVER_TRUE@	os/filestore/DBObjectMap.h \
 @ENABLE_SERVER_TRUE@	os/filestore/FileJournal.h \
 @ENABLE_SERVER_TRUE@	os/filestore/FileStore.h \
+ at ENABLE_SERVER_TRUE@	os/filestore/JournalThrottle.h \
 @ENABLE_SERVER_TRUE@	os/filestore/FDCache.h \
 @ENABLE_SERVER_TRUE@	os/filestore/GenericFileStoreBackend.h \
 @ENABLE_SERVER_TRUE@	os/filestore/HashIndex.h \
@@ -343,6 +394,7 @@ check_PROGRAMS = $(am__EXEEXT_62) $(am__EXEEXT_63) \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	osd/ECMsgTypes.h \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	osd/ECTransaction.h \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	osd/Watch.h \
+ at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	osd/ScrubStore.h \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	osd/osd_types.h
 
 @LINUX_TRUE at am__append_69 = -export-symbols-regex '.*__erasure_code_.*'
@@ -427,29 +479,24 @@ check_PROGRAMS = $(am__EXEEXT_62) $(am__EXEEXT_63) \
 @AIX_TRUE at am__append_110 = \
 @AIX_TRUE@        common/aix_errno.cc
 
-
-# used by RBD and FileStore
- at LINUX_TRUE@am__append_111 = \
- at LINUX_TRUE@	common/blkdev.cc
-
- at ENABLE_XIO_TRUE@am__append_112 = \
+ at ENABLE_XIO_TRUE@am__append_111 = \
 @ENABLE_XIO_TRUE@	common/address_helper.cc
 
- at WITH_GOOD_YASM_ELF64_TRUE@am__append_113 = common/crc32c_intel_fast_asm.S common/crc32c_intel_fast_zero_asm.S
+ at WITH_GOOD_YASM_ELF64_TRUE@am__append_112 = common/crc32c_intel_fast_asm.S common/crc32c_intel_fast_zero_asm.S
+ at HAVE_ARMV8_CRC_TRUE@am__append_113 = libcommon_crc_aarch64.la
 @HAVE_ARMV8_CRC_TRUE at am__append_114 = libcommon_crc_aarch64.la
- at HAVE_ARMV8_CRC_TRUE@am__append_115 = libcommon_crc_aarch64.la
- at LINUX_TRUE@am__append_116 = -lrt -lblkid
- at ENABLE_XIO_TRUE@am__append_117 = \
+ at LINUX_TRUE@am__append_115 = -lrt -lblkid
+ at ENABLE_XIO_TRUE@am__append_116 = \
 @ENABLE_XIO_TRUE@	common/address_helper.h
 
- at LINUX_TRUE@am__append_118 = libsecret.la
- at LINUX_TRUE@am__append_119 = msg/async/EventEpoll.cc
- at DARWIN_TRUE@am__append_120 = msg/async/EventKqueue.cc
- at FREEBSD_TRUE@am__append_121 = msg/async/EventKqueue.cc
- at LINUX_TRUE@am__append_122 = msg/async/EventEpoll.h
- at DARWIN_TRUE@am__append_123 = msg/async/EventKqueue.h
- at FREEBSD_TRUE@am__append_124 = msg/async/EventKqueue.h
- at ENABLE_XIO_TRUE@am__append_125 = \
+ at LINUX_TRUE@am__append_117 = libsecret.la
+ at LINUX_TRUE@am__append_118 = msg/async/EventEpoll.cc
+ at DARWIN_TRUE@am__append_119 = msg/async/EventKqueue.cc
+ at FREEBSD_TRUE@am__append_120 = msg/async/EventKqueue.cc
+ at LINUX_TRUE@am__append_121 = msg/async/EventEpoll.h
+ at DARWIN_TRUE@am__append_122 = msg/async/EventKqueue.h
+ at FREEBSD_TRUE@am__append_123 = msg/async/EventKqueue.h
+ at ENABLE_XIO_TRUE@am__append_124 = \
 @ENABLE_XIO_TRUE@	msg/xio/QueueStrategy.cc \
 @ENABLE_XIO_TRUE@	msg/xio/XioConnection.cc \
 @ENABLE_XIO_TRUE@	msg/xio/XioMessenger.cc \
@@ -457,7 +504,7 @@ check_PROGRAMS = $(am__EXEEXT_62) $(am__EXEEXT_63) \
 @ENABLE_XIO_TRUE@	msg/xio/XioPortal.cc \
 @ENABLE_XIO_TRUE@	msg/xio/XioPool.cc
 
- at ENABLE_XIO_TRUE@am__append_126 = \
+ at ENABLE_XIO_TRUE@am__append_125 = \
 @ENABLE_XIO_TRUE@	msg/xio/DispatchStrategy.h \
 @ENABLE_XIO_TRUE@	msg/xio/FastStrategy.h \
 @ENABLE_XIO_TRUE@	msg/xio/QueueStrategy.h \
@@ -469,6 +516,10 @@ check_PROGRAMS = $(am__EXEEXT_62) $(am__EXEEXT_63) \
 @ENABLE_XIO_TRUE@	msg/xio/XioPortal.h \
 @ENABLE_XIO_TRUE@	msg/xio/XioSubmit.h
 
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE at am__append_126 = \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	$(srcdir)/include/rados/librgw.h \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	$(srcdir)/include/rados/rgw_file.h
+
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE at am__append_127 =  \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@	librados_internal.la \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@	librados_api.la \
@@ -548,6 +599,8 @@ check_PROGRAMS = $(am__EXEEXT_62) $(am__EXEEXT_63) \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	librbd/image/RefreshParentRequest.h \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	librbd/image/RefreshRequest.h \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	librbd/image/SetSnapRequest.h \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	librbd/image_watcher/Notifier.h \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	librbd/image_watcher/NotifyLockOwner.h \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	librbd/journal/Replay.h \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	librbd/journal/Types.h \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	librbd/object_map/InvalidateRequest.h \
@@ -581,39 +634,63 @@ check_PROGRAMS = $(am__EXEEXT_62) $(am__EXEEXT_63) \
 @ENABLE_CLIENT_TRUE@	rgw/rgw_basic_types.cc \
 @ENABLE_CLIENT_TRUE@	rgw/rgw_common.cc \
 @ENABLE_CLIENT_TRUE@	rgw/rgw_env.cc \
- at ENABLE_CLIENT_TRUE@	rgw/rgw_json_enc.cc
+ at ENABLE_CLIENT_TRUE@	rgw/rgw_json_enc.cc \
+ at ENABLE_CLIENT_TRUE@	rgw/rgw_keystone.cc
 
- at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE at am__append_143 = librgw.la \
- at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	libcivetweb.la
- at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE at am__append_144 = \
+ at ENABLE_CLIENT_TRUE@am__append_143 = -lcurl -lexpat \
+ at ENABLE_CLIENT_TRUE@	libcls_version_client.la \
+ at ENABLE_CLIENT_TRUE@	libcls_log_client.la \
+ at ENABLE_CLIENT_TRUE@	libcls_refcount_client.la \
+ at ENABLE_CLIENT_TRUE@	libcls_user_client.la \
+ at ENABLE_CLIENT_TRUE@	libcls_timeindex_client.la \
+ at ENABLE_CLIENT_TRUE@	libcls_statelog_client.la \
+ at ENABLE_CLIENT_TRUE@	libcls_lock_client.la \
+ at ENABLE_CLIENT_TRUE@	libcls_refcount_client.la \
+ at ENABLE_CLIENT_TRUE@	libcls_replica_log_client.la \
+ at ENABLE_CLIENT_TRUE@	libcls_rgw_client.la libcls_rbd_client.la \
+ at ENABLE_CLIENT_TRUE@	libcls_user_client.la \
+ at ENABLE_CLIENT_TRUE@	libcls_numops_client.la \
+ at ENABLE_CLIENT_TRUE@	libcls_journal_client.la
+ at ENABLE_CLIENT_TRUE@@WITH_OPENLDAP_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE at am__append_144 = rgw/rgw_ldap.cc
+# noinst_LTLIBRARIES += librgw.la
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE at am__append_145 = \
 @ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	$(LIBRADOS) \
 @ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	libcls_rgw_client.la \
- at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	libcls_log_client.a \
- at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	libcls_statelog_client.a \
- at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	libcls_timeindex_client.a \
- at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	libcls_user_client.a \
- at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	libcls_replica_log_client.a \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	libcls_log_client.la \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	libcls_statelog_client.la \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	libcls_timeindex_client.la \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	libcls_user_client.la \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	libcls_replica_log_client.la \
 @ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	libcls_lock_client.la \
 @ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	libcls_refcount_client.la \
- at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	libcls_version_client.a \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	libcls_version_client.la \
 @ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	-lcurl \
 @ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	-lexpat \
 @ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	-lm \
 @ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	-lfcgi \
 @ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	-ldl
 
- at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE at am__append_145 = radosgw \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE at am__append_146 = librgw.la
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE at am__append_147 = -lssl -lcrypto
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE at am__append_148 = libcivetweb.la
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE at am__append_149 = radosgw \
 @ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	radosgw-admin \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	radosgw-token \
 @ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	radosgw-object-expirer
- at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE at am__append_146 = ceph_rgw_multiparser \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE at am__append_150 = ceph_rgw_multiparser \
 @ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	ceph_rgw_jsonparser
- at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE at am__append_147 = \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE at am__append_151 = \
 @ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/rgw_acl.h \
 @ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/rgw_acl_s3.h \
 @ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/rgw_acl_swift.h \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/rgw_b64.h \
 @ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/rgw_client_io.h \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/rgw_coroutine.h \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/rgw_cr_rados.h \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/rgw_cr_rest.h \
 @ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/rgw_fcgi.h \
 @ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/rgw_xml.h \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/rgw_token.h \
 @ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/rgw_basic_types.h \
 @ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/rgw_cache.h \
 @ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/rgw_common.h \
@@ -621,17 +698,26 @@ check_PROGRAMS = $(am__EXEEXT_62) $(am__EXEEXT_63) \
 @ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/rgw_cors_s3.h \
 @ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/rgw_cors_swift.h \
 @ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/rgw_string.h \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/rgw_file.h \
 @ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/rgw_formats.h \
 @ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/rgw_http_errors.h \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/rgw_ldap.h \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/rgw_lib.h \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/rgw_lib_frontend.h \
 @ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/rgw_log.h \
 @ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/rgw_loadgen.h \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/rgw_process.h \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/rgw_request.h \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/rgw_frontend.h \
 @ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/rgw_multi.h \
 @ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/rgw_policy_s3.h \
 @ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/rgw_gc.h \
 @ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/rgw_metadata.h \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/rgw_meta_sync_status.h \
 @ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/rgw_multi_del.h \
 @ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/rgw_object_expirer_core.h \
 @ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/rgw_op.h \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/rgw_os_lib.h \
 @ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/rgw_orphan.h \
 @ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/rgw_http_client.h \
 @ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/rgw_swift.h \
@@ -656,11 +742,21 @@ check_PROGRAMS = $(am__EXEEXT_62) $(am__EXEEXT_63) \
 @ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/rgw_rest_opstate.h \
 @ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/rgw_rest_replica_log.h \
 @ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/rgw_rest_config.h \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/rgw_rest_realm.h \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/rgw_sync.h \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/rgw_data_sync.h \
 @ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/rgw_usage.h \
 @ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/rgw_user.h \
 @ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/rgw_bucket.h \
 @ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/rgw_keystone.h \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/rgw_period_history.h \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/rgw_period_pusher.h \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/rgw_period_puller.h \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/rgw_realm_reloader.h \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/rgw_realm_watcher.h \
 @ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/rgw_civetweb.h \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/rgw_boost_asio_coroutine.h \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/rgw_boost_asio_yield.h \
 @ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/rgw_civetweb_log.h \
 @ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/rgw_website.h \
 @ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/rgw_rest_s3website.h \
@@ -669,26 +765,19 @@ check_PROGRAMS = $(am__EXEEXT_62) $(am__EXEEXT_63) \
 @ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	civetweb/include/civetweb_conf.h \
 @ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	civetweb/src/md5.h
 
- at ENABLE_CLIENT_TRUE@am__append_148 = libcls_lock_client.la \
+ at ENABLE_CLIENT_TRUE@am__append_152 = libcls_lock_client.la \
 @ENABLE_CLIENT_TRUE@	libcls_refcount_client.la \
+ at ENABLE_CLIENT_TRUE@	libcls_version_client.la \
+ at ENABLE_CLIENT_TRUE@	libcls_log_client.la \
+ at ENABLE_CLIENT_TRUE@	libcls_statelog_client.la \
+ at ENABLE_CLIENT_TRUE@	libcls_timeindex_client.la \
+ at ENABLE_CLIENT_TRUE@	libcls_replica_log_client.la \
 @ENABLE_CLIENT_TRUE@	libcls_rgw_client.la libcls_rbd_client.la \
+ at ENABLE_CLIENT_TRUE@	libcls_user_client.la \
 @ENABLE_CLIENT_TRUE@	libcls_cephfs_client.la \
 @ENABLE_CLIENT_TRUE@	libcls_numops_client.la \
 @ENABLE_CLIENT_TRUE@	libcls_journal_client.la
- at ENABLE_CLIENT_TRUE@am__append_149 = libcls_lock_client.la \
- at ENABLE_CLIENT_TRUE@	libcls_refcount_client.la \
- at ENABLE_CLIENT_TRUE@	libcls_replica_log_client.a \
- at ENABLE_CLIENT_TRUE@	libcls_rgw_client.la libcls_rbd_client.la \
- at ENABLE_CLIENT_TRUE@	libcls_user_client.a \
- at ENABLE_CLIENT_TRUE@	libcls_numops_client.la \
- at ENABLE_CLIENT_TRUE@	libcls_journal_client.la
- at ENABLE_CLIENT_TRUE@am__append_150 = libcls_version_client.a \
- at ENABLE_CLIENT_TRUE@	libcls_log_client.a \
- at ENABLE_CLIENT_TRUE@	libcls_statelog_client.a \
- at ENABLE_CLIENT_TRUE@	libcls_timeindex_client.a \
- at ENABLE_CLIENT_TRUE@	libcls_replica_log_client.a \
- at ENABLE_CLIENT_TRUE@	libcls_user_client.a
- at ENABLE_CLIENT_TRUE@am__append_151 = \
+ at ENABLE_CLIENT_TRUE@am__append_153 = \
 @ENABLE_CLIENT_TRUE@	cls/lock/cls_lock_types.h \
 @ENABLE_CLIENT_TRUE@	cls/lock/cls_lock_ops.h \
 @ENABLE_CLIENT_TRUE@	cls/lock/cls_lock_client.h \
@@ -724,7 +813,7 @@ check_PROGRAMS = $(am__EXEEXT_62) $(am__EXEEXT_63) \
 @ENABLE_CLIENT_TRUE@	cls/journal/cls_journal_client.h \
 @ENABLE_CLIENT_TRUE@	cls/journal/cls_journal_types.h
 
- at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE at am__append_152 = libcls_hello.la \
+ at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE at am__append_154 = libcls_hello.la \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	libcls_numops.la \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	libcls_rbd.la \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	libcls_lock.la \
@@ -738,13 +827,13 @@ check_PROGRAMS = $(am__EXEEXT_62) $(am__EXEEXT_63) \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	libcls_rgw.la \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	libcls_cephfs.la \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	libcls_journal.la
- at ENABLE_SERVER_TRUE@@LINUX_TRUE@@WITH_OSD_TRUE at am__append_153 = libcls_kvs.la
- at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE at am__append_154 = \
+ at ENABLE_SERVER_TRUE@@LINUX_TRUE@@WITH_OSD_TRUE at am__append_155 = libcls_kvs.la
+ at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE at am__append_156 = \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	key_value_store/key_value_structure.h \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	key_value_store/kv_flat_btree_async.h \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	key_value_store/kvs_arg_types.h
 
- at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE at am__append_155 = rbd_replay/ActionTypes.h \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE at am__append_157 = rbd_replay/ActionTypes.h \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	rbd_replay/actions.hpp \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	rbd_replay/BoundedBuffer.hpp \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	rbd_replay/BufferReader.h \
@@ -754,27 +843,27 @@ check_PROGRAMS = $(am__EXEEXT_62) $(am__EXEEXT_63) \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	rbd_replay/rbd_loc.hpp \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	rbd_replay/rbd_replay_debug.hpp \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	rbd_replay/Replayer.hpp
- at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE at am__append_156 = librbd_replay_types.la \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE at am__append_158 = librbd_replay_types.la \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	librbd_replay.la \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	librbd_replay_ios.la
- at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE at am__append_157 = librbd_replay_types.la
- at ENABLE_CLIENT_TRUE@@LINUX_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE at am__append_158 = rbd-replay
- at ENABLE_CLIENT_TRUE@@WITH_BABELTRACE_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE at am__append_159 = rbd-replay-prep
- at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE at am__append_160 = \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE at am__append_159 = librbd_replay_types.la
+ at ENABLE_CLIENT_TRUE@@LINUX_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE at am__append_160 = rbd-replay
+ at ENABLE_CLIENT_TRUE@@WITH_BABELTRACE_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE at am__append_161 = rbd-replay-prep
+ at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE at am__append_162 = \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	test/erasure-code/test-erasure-code.sh \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	test/erasure-code/test-erasure-eio.sh
 
- at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE at am__append_161 = test/erasure-code/ceph_erasure_code_benchmark.h \
+ at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE at am__append_163 = test/erasure-code/ceph_erasure_code_benchmark.h \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	test/erasure-code/ceph_erasure_code_benchmark.h \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	test/erasure-code/ErasureCodeExample.h
- at ENABLE_SERVER_TRUE@@LINUX_TRUE@@WITH_OSD_TRUE at am__append_162 = -ldl
- at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE at am__append_163 = ceph_erasure_code_benchmark \
- at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	ceph_erasure_code
 @ENABLE_SERVER_TRUE@@LINUX_TRUE@@WITH_OSD_TRUE at am__append_164 = -ldl
- at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE at am__append_165 = ceph_erasure_code_non_regression
+ at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE at am__append_165 = ceph_erasure_code_benchmark \
+ at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	ceph_erasure_code
 @ENABLE_SERVER_TRUE@@LINUX_TRUE@@WITH_OSD_TRUE at am__append_166 = -ldl
- at ENABLE_SERVER_TRUE@@LINUX_TRUE@@WITH_OSD_TRUE at am__append_167 = -export-symbols-regex '.*__erasure_code_.*'
- at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE at am__append_168 = libec_example.la \
+ at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE at am__append_167 = ceph_erasure_code_non_regression
+ at ENABLE_SERVER_TRUE@@LINUX_TRUE@@WITH_OSD_TRUE at am__append_168 = -ldl
+ at ENABLE_SERVER_TRUE@@LINUX_TRUE@@WITH_OSD_TRUE at am__append_169 = -export-symbols-regex '.*__erasure_code_.*'
+ at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE at am__append_170 = libec_example.la \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	libec_missing_entry_point.la \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	libec_missing_version.la \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	libec_hangs.la \
@@ -788,8 +877,6 @@ check_PROGRAMS = $(am__EXEEXT_62) $(am__EXEEXT_63) \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	libec_test_shec_sse4.la \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	libec_test_shec_sse3.la \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	libec_test_shec_generic.la
- at ENABLE_SERVER_TRUE@@LINUX_TRUE@@WITH_OSD_TRUE at am__append_169 = -export-symbols-regex '.*__erasure_code_.*'
- at ENABLE_SERVER_TRUE@@LINUX_TRUE@@WITH_OSD_TRUE at am__append_170 = -export-symbols-regex '.*__erasure_code_.*'
 @ENABLE_SERVER_TRUE@@LINUX_TRUE@@WITH_OSD_TRUE at am__append_171 = -export-symbols-regex '.*__erasure_code_.*'
 @ENABLE_SERVER_TRUE@@LINUX_TRUE@@WITH_OSD_TRUE at am__append_172 = -export-symbols-regex '.*__erasure_code_.*'
 @ENABLE_SERVER_TRUE@@LINUX_TRUE@@WITH_OSD_TRUE at am__append_173 = -export-symbols-regex '.*__erasure_code_.*'
@@ -797,19 +884,21 @@ check_PROGRAMS = $(am__EXEEXT_62) $(am__EXEEXT_63) \
 @ENABLE_SERVER_TRUE@@LINUX_TRUE@@WITH_OSD_TRUE at am__append_175 = -export-symbols-regex '.*__erasure_code_.*'
 @ENABLE_SERVER_TRUE@@LINUX_TRUE@@WITH_OSD_TRUE at am__append_176 = -export-symbols-regex '.*__erasure_code_.*'
 @ENABLE_SERVER_TRUE@@LINUX_TRUE@@WITH_OSD_TRUE at am__append_177 = -export-symbols-regex '.*__erasure_code_.*'
- at ENABLE_SERVER_TRUE@@LINUX_TRUE@@WITH_OSD_TRUE at am__append_178 = -ldl
- at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE at am__append_179 = unittest_erasure_code_plugin \
+ at ENABLE_SERVER_TRUE@@LINUX_TRUE@@WITH_OSD_TRUE at am__append_178 = -export-symbols-regex '.*__erasure_code_.*'
+ at ENABLE_SERVER_TRUE@@LINUX_TRUE@@WITH_OSD_TRUE at am__append_179 = -export-symbols-regex '.*__erasure_code_.*'
+ at ENABLE_SERVER_TRUE@@LINUX_TRUE@@WITH_OSD_TRUE at am__append_180 = -ldl
+ at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE at am__append_181 = unittest_erasure_code_plugin \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	unittest_erasure_code \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	unittest_erasure_code_jerasure \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	unittest_erasure_code_plugin_jerasure
- at ENABLE_SERVER_TRUE@@LINUX_TRUE@@WITH_OSD_TRUE at am__append_180 = -ldl
- at ENABLE_SERVER_TRUE@@LINUX_TRUE@@WITH_OSD_TRUE at am__append_181 = -ldl
- at ENABLE_SERVER_TRUE@@LINUX_TRUE@@WITH_BETTER_YASM_ELF64_TRUE@@WITH_OSD_TRUE at am__append_182 = -ldl
- at ENABLE_SERVER_TRUE@@WITH_BETTER_YASM_ELF64_TRUE@@WITH_OSD_TRUE at am__append_183 = unittest_erasure_code_isa \
- at ENABLE_SERVER_TRUE@@WITH_BETTER_YASM_ELF64_TRUE@@WITH_OSD_TRUE@	unittest_erasure_code_plugin_isa
+ at ENABLE_SERVER_TRUE@@LINUX_TRUE@@WITH_OSD_TRUE at am__append_182 = -ldl
+ at ENABLE_SERVER_TRUE@@LINUX_TRUE@@WITH_OSD_TRUE at am__append_183 = -ldl
 @ENABLE_SERVER_TRUE@@LINUX_TRUE@@WITH_BETTER_YASM_ELF64_TRUE@@WITH_OSD_TRUE at am__append_184 = -ldl
- at ENABLE_SERVER_TRUE@@LINUX_TRUE@@WITH_OSD_TRUE at am__append_185 = -ldl
- at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE at am__append_186 =  \
+ at ENABLE_SERVER_TRUE@@WITH_BETTER_YASM_ELF64_TRUE@@WITH_OSD_TRUE at am__append_185 = unittest_erasure_code_isa \
+ at ENABLE_SERVER_TRUE@@WITH_BETTER_YASM_ELF64_TRUE@@WITH_OSD_TRUE@	unittest_erasure_code_plugin_isa
+ at ENABLE_SERVER_TRUE@@LINUX_TRUE@@WITH_BETTER_YASM_ELF64_TRUE@@WITH_OSD_TRUE at am__append_186 = -ldl
+ at ENABLE_SERVER_TRUE@@LINUX_TRUE@@WITH_OSD_TRUE at am__append_187 = -ldl
+ at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE at am__append_188 =  \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	unittest_erasure_code_lrc \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	unittest_erasure_code_plugin_lrc \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	unittest_erasure_code_shec \
@@ -823,60 +912,60 @@ check_PROGRAMS = $(am__EXEEXT_62) $(am__EXEEXT_63) \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	unittest_compression_plugin_snappy \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	unittest_compression_zlib \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	unittest_compression_plugin_zlib
- at ENABLE_SERVER_TRUE@@LINUX_TRUE@@WITH_OSD_TRUE at am__append_187 = -ldl
- at ENABLE_SERVER_TRUE@@LINUX_TRUE@@WITH_OSD_TRUE at am__append_188 = -ldl
 @ENABLE_SERVER_TRUE@@LINUX_TRUE@@WITH_OSD_TRUE at am__append_189 = -ldl
 @ENABLE_SERVER_TRUE@@LINUX_TRUE@@WITH_OSD_TRUE at am__append_190 = -ldl
 @ENABLE_SERVER_TRUE@@LINUX_TRUE@@WITH_OSD_TRUE at am__append_191 = -ldl
 @ENABLE_SERVER_TRUE@@LINUX_TRUE@@WITH_OSD_TRUE at am__append_192 = -ldl
- at ENABLE_SERVER_TRUE@@LINUX_TRUE@@WITH_OSD_TRUE at am__append_193 = -export-symbols-regex '.*__erasure_code_.*'
- at ENABLE_SERVER_TRUE@@LINUX_TRUE@@WITH_OSD_TRUE at am__append_194 = -export-symbols-regex '.*__erasure_code_.*'
+ at ENABLE_SERVER_TRUE@@LINUX_TRUE@@WITH_OSD_TRUE at am__append_193 = -ldl
+ at ENABLE_SERVER_TRUE@@LINUX_TRUE@@WITH_OSD_TRUE at am__append_194 = -ldl
 @ENABLE_SERVER_TRUE@@LINUX_TRUE@@WITH_OSD_TRUE at am__append_195 = -export-symbols-regex '.*__erasure_code_.*'
 @ENABLE_SERVER_TRUE@@LINUX_TRUE@@WITH_OSD_TRUE at am__append_196 = -export-symbols-regex '.*__erasure_code_.*'
- at ENABLE_SERVER_TRUE@@ENABLE_XIO_TRUE at am__append_197 = test/messenger/message_helper.h \
+ at ENABLE_SERVER_TRUE@@LINUX_TRUE@@WITH_OSD_TRUE at am__append_197 = -export-symbols-regex '.*__erasure_code_.*'
+ at ENABLE_SERVER_TRUE@@LINUX_TRUE@@WITH_OSD_TRUE at am__append_198 = -export-symbols-regex '.*__erasure_code_.*'
+ at ENABLE_SERVER_TRUE@@ENABLE_XIO_TRUE at am__append_199 = test/messenger/message_helper.h \
 @ENABLE_SERVER_TRUE@@ENABLE_XIO_TRUE@	test/messenger/simple_dispatcher.h \
 @ENABLE_SERVER_TRUE@@ENABLE_XIO_TRUE@	test/messenger/xio_dispatcher.h
- at ENABLE_SERVER_TRUE@@ENABLE_XIO_TRUE@@LINUX_TRUE at am__append_198 = -ldl
- at ENABLE_SERVER_TRUE@@ENABLE_XIO_TRUE@@LINUX_TRUE at am__append_199 = -ldl
- at ENABLE_SERVER_TRUE@@ENABLE_XIO_TRUE at am__append_200 = simple_server \
+ at ENABLE_SERVER_TRUE@@ENABLE_XIO_TRUE@@LINUX_TRUE at am__append_200 = -ldl
+ at ENABLE_SERVER_TRUE@@ENABLE_XIO_TRUE@@LINUX_TRUE at am__append_201 = -ldl
+ at ENABLE_SERVER_TRUE@@ENABLE_XIO_TRUE at am__append_202 = simple_server \
 @ENABLE_SERVER_TRUE@@ENABLE_XIO_TRUE@	simple_client xio_server \
 @ENABLE_SERVER_TRUE@@ENABLE_XIO_TRUE@	xio_client
- at ENABLE_SERVER_TRUE@@ENABLE_XIO_TRUE@@LINUX_TRUE at am__append_201 = -ldl
- at ENABLE_SERVER_TRUE@@ENABLE_XIO_TRUE@@LINUX_TRUE at am__append_202 = -ldl
- at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE at am__append_203 = test/compressor/compressor_example.h
- at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE at am__append_204 = libceph_example.la
- at ENABLE_SERVER_TRUE@@LINUX_TRUE@@WITH_OSD_TRUE at am__append_205 = -ldl
- at ENABLE_SERVER_TRUE@@LINUX_TRUE@@WITH_OSD_TRUE at am__append_206 = -ldl
+ at ENABLE_SERVER_TRUE@@ENABLE_XIO_TRUE@@LINUX_TRUE at am__append_203 = -ldl
+ at ENABLE_SERVER_TRUE@@ENABLE_XIO_TRUE@@LINUX_TRUE at am__append_204 = -ldl
+ at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE at am__append_205 = test/compressor/compressor_example.h
+ at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE at am__append_206 = libceph_example.la
 @ENABLE_SERVER_TRUE@@LINUX_TRUE@@WITH_OSD_TRUE at am__append_207 = -ldl
 @ENABLE_SERVER_TRUE@@LINUX_TRUE@@WITH_OSD_TRUE at am__append_208 = -ldl
 @ENABLE_SERVER_TRUE@@LINUX_TRUE@@WITH_OSD_TRUE at am__append_209 = -ldl
- at COMPILER_HAS_VTA_TRUE@@ENABLE_CLIENT_TRUE at am__append_210 = -fno-var-tracking-assignments
- at COMPILER_HAS_VTA_TRUE@@ENABLE_CLIENT_TRUE at am__append_211 = -fno-var-tracking-assignments
- at ENABLE_CLIENT_TRUE@@WITH_RBD_TRUE at am__append_212 = -DWITH_RBD
- at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE at am__append_213 = -DWITH_RADOSGW
- at ENABLE_CLIENT_TRUE@am__append_214 = ceph-dencoder
- at ENABLE_CLIENT_TRUE@am__append_215 = \
+ at ENABLE_SERVER_TRUE@@LINUX_TRUE@@WITH_OSD_TRUE at am__append_210 = -ldl
+ at ENABLE_SERVER_TRUE@@LINUX_TRUE@@WITH_OSD_TRUE at am__append_211 = -ldl
+ at COMPILER_HAS_VTA_TRUE@@ENABLE_CLIENT_TRUE at am__append_212 = -fno-var-tracking-assignments
+ at COMPILER_HAS_VTA_TRUE@@ENABLE_CLIENT_TRUE at am__append_213 = -fno-var-tracking-assignments
+ at ENABLE_CLIENT_TRUE@@WITH_RBD_TRUE at am__append_214 = -DWITH_RBD
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE at am__append_215 = -DWITH_RADOSGW
+ at ENABLE_CLIENT_TRUE@am__append_216 = ceph-dencoder
+ at ENABLE_CLIENT_TRUE@am__append_217 = \
 @ENABLE_CLIENT_TRUE@	test/encoding/test_ceph_time.h
 
- at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE at am__append_216 = libradostest.la \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE at am__append_218 = libradostest.la \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@	librados_test_stub.la
- at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE at am__append_217 = ceph_test_rados \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE at am__append_219 = ceph_test_rados \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@	ceph_test_mutate
- at ENABLE_CLIENT_TRUE@@WITH_BUILD_TESTS_TRUE@@WITH_RADOS_TRUE at am__append_218 = test_build_librados
- at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE at am__append_219 =  \
+ at ENABLE_CLIENT_TRUE@@WITH_BUILD_TESTS_TRUE@@WITH_RADOS_TRUE at am__append_220 = test_build_librados
+ at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE at am__append_221 =  \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@	ceph_smalliobench \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@	ceph_omapbench \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@	ceph_objectstore_bench
- at ENABLE_CLIENT_TRUE@@LINUX_TRUE@@WITH_RADOS_TRUE at am__append_220 = ceph_kvstorebench \
+ at ENABLE_CLIENT_TRUE@@LINUX_TRUE@@WITH_RADOS_TRUE at am__append_222 = ceph_kvstorebench \
 @ENABLE_CLIENT_TRUE@@LINUX_TRUE@@WITH_RADOS_TRUE@	ceph_test_rados_list_parallel \
 @ENABLE_CLIENT_TRUE@@LINUX_TRUE@@WITH_RADOS_TRUE@	ceph_test_rados_open_pools_parallel \
 @ENABLE_CLIENT_TRUE@@LINUX_TRUE@@WITH_RADOS_TRUE@	ceph_test_rados_delete_pools_parallel \
 @ENABLE_CLIENT_TRUE@@LINUX_TRUE@@WITH_RADOS_TRUE@	ceph_test_rados_watch_notify
- at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE at am__append_221 =  \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE at am__append_223 =  \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@	unittest_librados \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@	unittest_librados_config \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@	unittest_journal
- at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE at am__append_222 =  \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE at am__append_224 =  \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@	ceph_multi_stress_watch \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@	ceph_test_cls_rbd \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@	ceph_test_cls_refcount \
@@ -903,8 +992,9 @@ check_PROGRAMS = $(am__EXEEXT_62) $(am__EXEEXT_63) \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@	ceph_test_rados_api_misc \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@	ceph_test_rados_api_tier \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@	ceph_test_rados_api_lock \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@	ceph_test_rados_api_tmap_migrate \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@	ceph_test_stress_watch
- at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE at am__append_223 = \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE at am__append_225 = \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@	test/librados_test_stub/LibradosTestStub.h \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@	test/librados_test_stub/MockTestMemIoCtxImpl.h \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@	test/librados_test_stub/MockTestMemRadosClient.h \
@@ -915,68 +1005,77 @@ check_PROGRAMS = $(am__EXEEXT_62) $(am__EXEEXT_63) \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@	test/librados_test_stub/TestMemIoCtxImpl.h \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@	test/librados_test_stub/TestIoCtxImpl.h
 
- at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE at am__append_224 = ceph_smalliobenchrbd \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE at am__append_226 = ceph_smalliobenchrbd \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	ceph_test_librbd \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	ceph_test_librbd_api \
- at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	ceph_test_rbd_mirror
- at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE at am__append_225 = unittest_rbd_replay
- at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE at am__append_226 = librbd_test.la \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	ceph_test_rbd_mirror \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	ceph_test_rbd_mirror_image_replay
+ at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE at am__append_227 = unittest_rbd_replay
+ at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE at am__append_228 = librbd_test.la \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	librbd_mirror_test.la
- at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE at am__append_227 = unittest_librbd \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE at am__append_229 = unittest_librbd \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	unittest_rbd_mirror
- at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE at am__append_228 = test/run-rbd-unit-tests.sh
- at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE at am__append_229 = \
- at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	test/librbd/test_fixture.h \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE at am__append_230 = test/run-rbd-unit-tests.sh
+ at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE at am__append_231 = test/librbd/test_fixture.h \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	test/librbd/test_mock_fixture.h \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	test/librbd/test_support.h \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	test/librbd/mock/MockAioImageRequestWQ.h \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	test/librbd/mock/MockContextWQ.h \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	test/librbd/mock/MockExclusiveLock.h \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	test/librbd/mock/MockImageCtx.h \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	test/librbd/mock/MockImageState.h \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	test/librbd/mock/MockImageWatcher.h \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	test/librbd/mock/MockJournal.h \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	test/librbd/mock/MockObjectMap.h \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	test/librbd/mock/MockOperations.h \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	test/librbd/mock/MockReadahead.h \
- at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	test/librbd/object_map/mock/MockInvalidateRequest.h
-
- at ENABLE_CLIENT_TRUE@@LINUX_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE at am__append_230 = ceph_test_librbd_fsx
- at ENABLE_CLIENT_TRUE@@WITH_RADOSSTRIPER_TRUE@@WITH_RADOS_TRUE at am__append_231 = libradosstripertest.la
- at ENABLE_CLIENT_TRUE@@WITH_RADOSSTRIPER_TRUE@@WITH_RADOS_TRUE at am__append_232 = ceph_test_rados_striper_api_io \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	test/librbd/object_map/mock/MockInvalidateRequest.h \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	test/rbd_mirror/test_fixture.h \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	test/rbd_mirror/test_mock_fixture.h \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	test/rbd_mirror/mock/MockJournaler.h
+ at ENABLE_CLIENT_TRUE@@LINUX_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE at am__append_232 = ceph_test_librbd_fsx
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSSTRIPER_TRUE@@WITH_RADOS_TRUE at am__append_233 = libradosstripertest.la
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSSTRIPER_TRUE@@WITH_RADOS_TRUE at am__append_234 = ceph_test_rados_striper_api_io \
 @ENABLE_CLIENT_TRUE@@WITH_RADOSSTRIPER_TRUE@@WITH_RADOS_TRUE@	ceph_test_rados_striper_api_aio \
 @ENABLE_CLIENT_TRUE@@WITH_RADOSSTRIPER_TRUE@@WITH_RADOS_TRUE@	ceph_test_rados_striper_api_striping
- at ENABLE_CLIENT_TRUE@@WITH_BUILD_TESTS_TRUE@@WITH_CEPHFS_TRUE@@WITH_RADOS_TRUE at am__append_233 = test_build_libcephfs
- at ENABLE_CLIENT_TRUE@@WITH_CEPHFS_TRUE@@WITH_RADOS_TRUE at am__append_234 = unittest_encoding \
+ at ENABLE_CLIENT_TRUE@@WITH_BUILD_TESTS_TRUE@@WITH_CEPHFS_TRUE@@WITH_RADOS_TRUE at am__append_235 = test_build_libcephfs
+ at ENABLE_CLIENT_TRUE@@WITH_CEPHFS_TRUE@@WITH_RADOS_TRUE at am__append_236 = unittest_encoding \
 @ENABLE_CLIENT_TRUE@@WITH_CEPHFS_TRUE@@WITH_RADOS_TRUE@	unittest_base64 \
 @ENABLE_CLIENT_TRUE@@WITH_CEPHFS_TRUE@@WITH_RADOS_TRUE@	unittest_run_cmd \
 @ENABLE_CLIENT_TRUE@@WITH_CEPHFS_TRUE@@WITH_RADOS_TRUE@	unittest_simple_spin \
 @ENABLE_CLIENT_TRUE@@WITH_CEPHFS_TRUE@@WITH_RADOS_TRUE@	unittest_libcephfs_config
- at ENABLE_CLIENT_TRUE@@LINUX_TRUE@@WITH_CEPHFS_TRUE@@WITH_RADOS_TRUE at am__append_235 = test/libcephfs/flock.cc
- at ENABLE_CLIENT_TRUE@@WITH_CEPHFS_TRUE@@WITH_RADOS_TRUE at am__append_236 = ceph_test_libcephfs \
+ at ENABLE_CLIENT_TRUE@@LINUX_TRUE@@WITH_CEPHFS_TRUE@@WITH_RADOS_TRUE at am__append_237 = test/libcephfs/flock.cc
+ at ENABLE_CLIENT_TRUE@@WITH_CEPHFS_TRUE@@WITH_RADOS_TRUE at am__append_238 = ceph_test_libcephfs \
 @ENABLE_CLIENT_TRUE@@WITH_CEPHFS_TRUE@@WITH_RADOS_TRUE@	ceph_test_c_headers
- at CLANG_FALSE@@ENABLE_CLIENT_TRUE@@WITH_CEPHFS_TRUE@@WITH_RADOS_TRUE at am__append_237 = -Werror -Wold-style-declaration
- at ENABLE_CLIENT_TRUE@@WITH_BUILD_TESTS_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE at am__append_238 = test_build_librgw
- at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE at am__append_239 = ceph_test_cors \
+ at CLANG_FALSE@@ENABLE_CLIENT_TRUE@@WITH_CEPHFS_TRUE@@WITH_RADOS_TRUE at am__append_239 = -Werror -Wold-style-declaration
+ at ENABLE_CLIENT_TRUE@@WITH_BUILD_TESTS_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE at am__append_240 = test_build_librgw
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE at am__append_241 = ceph_test_cors \
 @ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	ceph_test_rgw_manifest \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	ceph_test_rgw_period_history \
 @ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	ceph_test_rgw_obj \
 @ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	ceph_test_cls_rgw_meta \
 @ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	ceph_test_cls_rgw_log \
 @ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	ceph_test_cls_rgw_opstate \
- at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	ceph_test_cls_rgw
- at ENABLE_SERVER_TRUE@am__append_240 = ceph_test_async_driver \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	ceph_test_cls_rgw \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	librgw_file \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	librgw_file_cd \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	librgw_file_gp \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	librgw_file_aw \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	librgw_file_nfsns
+ at ENABLE_SERVER_TRUE@am__append_242 = ceph_test_async_driver \
 @ENABLE_SERVER_TRUE@	ceph_test_msgr ceph_test_trans \
 @ENABLE_SERVER_TRUE@	ceph_test_mon_workloadgen \
 @ENABLE_SERVER_TRUE@	ceph_test_mon_msg ceph_perf_objectstore \
 @ENABLE_SERVER_TRUE@	ceph_perf_local ceph_perf_msgr_server \
 @ENABLE_SERVER_TRUE@	ceph_perf_msgr_client
- at ENABLE_SERVER_TRUE@am__append_241 = test/perf_helper.h
- at ENABLE_SERVER_TRUE@@LINUX_TRUE at am__append_242 =  \
+ at ENABLE_SERVER_TRUE@am__append_243 = test/perf_helper.h
+ at ENABLE_SERVER_TRUE@@LINUX_TRUE at am__append_244 =  \
 @ENABLE_SERVER_TRUE@@LINUX_TRUE@	ceph_test_objectstore \
 @ENABLE_SERVER_TRUE@@LINUX_TRUE@	ceph_test_keyvaluedb \
 @ENABLE_SERVER_TRUE@@LINUX_TRUE@	ceph_test_filestore
- at ENABLE_SERVER_TRUE@@LINUX_TRUE at am__append_243 = unittest_bluefs \
+ at ENABLE_SERVER_TRUE@@LINUX_TRUE at am__append_245 = unittest_bluefs \
 @ENABLE_SERVER_TRUE@@LINUX_TRUE@	unittest_bluestore_types
- at ENABLE_SERVER_TRUE@am__append_244 =  \
+ at ENABLE_SERVER_TRUE@am__append_246 =  \
 @ENABLE_SERVER_TRUE@	ceph_test_objectstore_workloadgen \
 @ENABLE_SERVER_TRUE@	ceph_test_filestore_idempotent \
 @ENABLE_SERVER_TRUE@	ceph_test_filestore_idempotent_sequence \
@@ -984,72 +1083,87 @@ check_PROGRAMS = $(am__EXEEXT_62) $(am__EXEEXT_63) \
 @ENABLE_SERVER_TRUE@	ceph_test_object_map \
 @ENABLE_SERVER_TRUE@	ceph_test_keyvaluedb_atomicity \
 @ENABLE_SERVER_TRUE@	ceph_test_keyvaluedb_iterators
- at ENABLE_SERVER_TRUE@am__append_245 = unittest_transaction
- at ENABLE_CLIENT_TRUE@@ENABLE_SERVER_TRUE@@WITH_RADOS_TRUE at am__append_246 = ceph_smalliobenchfs \
+ at ENABLE_SERVER_TRUE@am__append_247 = unittest_transaction
+ at ENABLE_CLIENT_TRUE@@ENABLE_SERVER_TRUE@@WITH_RADOS_TRUE at am__append_248 = ceph_smalliobenchfs \
 @ENABLE_CLIENT_TRUE@@ENABLE_SERVER_TRUE@@WITH_RADOS_TRUE@	ceph_smalliobenchdumb \
 @ENABLE_CLIENT_TRUE@@ENABLE_SERVER_TRUE@@WITH_RADOS_TRUE@	ceph_tpbench
- at ENABLE_SERVER_TRUE@@WITH_MON_TRUE at am__append_247 = ceph_test_keys
- at ENABLE_SERVER_TRUE@@WITH_MON_TRUE at am__append_248 = get_command_descriptions
- at ENABLE_SERVER_TRUE@@WITH_MON_TRUE at am__append_249 =  \
+ at ENABLE_SERVER_TRUE@@WITH_MON_TRUE at am__append_249 = ceph_test_keys
+ at ENABLE_SERVER_TRUE@@WITH_MON_TRUE at am__append_250 = get_command_descriptions
+ at ENABLE_SERVER_TRUE@@WITH_MON_TRUE at am__append_251 =  \
 @ENABLE_SERVER_TRUE@@WITH_MON_TRUE@	unittest_mon_moncap \
 @ENABLE_SERVER_TRUE@@WITH_MON_TRUE@	unittest_mon_pgmap
- at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE at am__append_250 =  \
+ at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE at am__append_252 =  \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	unittest_ecbackend \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	unittest_osdscrub \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	unittest_pglog \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	unittest_hitset \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	unittest_osd_osdcap \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	unittest_pageset
- at ENABLE_SERVER_TRUE@@LINUX_TRUE@@WITH_OSD_TRUE at am__append_251 = -ldl
- at ENABLE_SERVER_TRUE@@LINUX_TRUE@@WITH_OSD_TRUE at am__append_252 = -ldl
- at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE at am__append_253 = ceph_test_snap_mapper
- at ENABLE_SERVER_TRUE@@WITH_SLIBROCKSDB_TRUE at am__append_254 = unittest_rocksdb_option_static
- at ENABLE_SERVER_TRUE@@WITH_DLIBROCKSDB_TRUE at am__append_255 = unittest_rocksdb_option
- at ENABLE_SERVER_TRUE@am__append_256 = unittest_chain_xattr \
+ at ENABLE_SERVER_TRUE@@LINUX_TRUE@@WITH_OSD_TRUE at am__append_253 = -ldl
+ at ENABLE_SERVER_TRUE@@LINUX_TRUE@@WITH_OSD_TRUE at am__append_254 = -ldl
+ at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE at am__append_255 = ceph_test_snap_mapper
+ at ENABLE_SERVER_TRUE@@WITH_SLIBROCKSDB_TRUE at am__append_256 = unittest_rocksdb_option_static
+ at ENABLE_SERVER_TRUE@@WITH_DLIBROCKSDB_TRUE at am__append_257 = unittest_rocksdb_option
+ at ENABLE_SERVER_TRUE@am__append_258 = unittest_chain_xattr \
 @ENABLE_SERVER_TRUE@	unittest_lfnindex
- at ENABLE_SERVER_TRUE@@WITH_MDS_TRUE at am__append_257 = unittest_mds_authcap
- at WITH_BUILD_TESTS_TRUE@am__append_258 = test_build_libcommon
- at LINUX_TRUE@am__append_259 = libsystest.la
- at SOLARIS_TRUE@am__append_260 = \
+ at ENABLE_SERVER_TRUE@@WITH_MDS_TRUE at am__append_259 = unittest_mds_authcap
+ at WITH_BUILD_TESTS_TRUE@am__append_260 = test_build_libcommon
+ at LINUX_TRUE@am__append_261 = libsystest.la
+ at SOLARIS_TRUE@am__append_262 = \
 @SOLARIS_TRUE@	-lsocket -lnsl
 
- at LINUX_TRUE@am__append_261 = unittest_blkdev
- at LINUX_TRUE@am__append_262 = ceph_test_get_blkdev_size
- at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE at am__append_263 =  \
+ at LINUX_TRUE@am__append_263 = unittest_blkdev
+ at LINUX_TRUE@am__append_264 = ceph_test_get_blkdev_size
+ at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE at am__append_265 =  \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@	ceph_scratchtool \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@	ceph_scratchtoolpp \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@	ceph_radosacl
- at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE at am__append_264 = rados
- at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE at am__append_265 = tools/rbd/ArgumentTypes.h \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE at am__append_266 = rados
+ at ENABLE_CLIENT_TRUE@@LINUX_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE at am__append_267 = \
+ at ENABLE_CLIENT_TRUE@@LINUX_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	tools/rbd/action/Kernel.cc \
+ at ENABLE_CLIENT_TRUE@@LINUX_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	tools/rbd/action/Nbd.cc
+
+ at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE at am__append_268 = tools/rbd/ArgumentTypes.h \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	tools/rbd/IndentStream.h \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	tools/rbd/OptionPrinter.h \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	tools/rbd/Shell.h \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	tools/rbd/Utils.h \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	tools/rbd_mirror/ClusterWatcher.h \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	tools/rbd_mirror/ImageReplayer.h \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	tools/rbd_mirror/ImageSync.h \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	tools/rbd_mirror/Mirror.h \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	tools/rbd_mirror/PoolWatcher.h \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	tools/rbd_mirror/Replayer.h \
- at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	tools/rbd_mirror/types.h
- at ENABLE_CLIENT_TRUE@@LINUX_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE at am__append_266 = rbd \
- at ENABLE_CLIENT_TRUE@@LINUX_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	rbd-nbd
- at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE at am__append_267 = librbd_mirror_internal.la
- at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE at am__append_268 = rbd-mirror
- at ENABLE_CLIENT_TRUE@@WITH_CEPHFS_TRUE@@WITH_RADOS_TRUE at am__append_269 = ceph-client-debug
- at ENABLE_SERVER_TRUE@am__append_270 = ceph-osdomap-tool \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	tools/rbd_mirror/Threads.h \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	tools/rbd_mirror/types.h \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	tools/rbd_mirror/image_replayer/BootstrapRequest.h \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	tools/rbd_mirror/image_replayer/CloseImageRequest.h \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	tools/rbd_mirror/image_replayer/OpenLocalImageRequest.h \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	tools/rbd_mirror/image_sync/ImageCopyRequest.h \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	tools/rbd_mirror/image_sync/ObjectCopyRequest.h \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	tools/rbd_mirror/image_sync/SnapshotCopyRequest.h \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	tools/rbd_mirror/image_sync/SyncPointCreateRequest.h \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	tools/rbd_mirror/image_sync/SyncPointPruneRequest.h
+ at ENABLE_CLIENT_TRUE@@LINUX_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE at am__append_269 = $(LIBKRBD)
+ at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE at am__append_270 = rbd
+ at ENABLE_CLIENT_TRUE@@LINUX_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE at am__append_271 = rbd-nbd
+ at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE at am__append_272 = librbd_mirror_internal.la
+ at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE at am__append_273 = rbd-mirror
+ at ENABLE_CLIENT_TRUE@@WITH_CEPHFS_TRUE@@WITH_RADOS_TRUE at am__append_274 = ceph-client-debug
+ at ENABLE_SERVER_TRUE@am__append_275 = ceph-osdomap-tool \
 @ENABLE_SERVER_TRUE@	ceph-monstore-tool ceph-kvstore-tool
- at ENABLE_SERVER_TRUE@@LINUX_TRUE@@WITH_OSD_TRUE at am__append_271 = -ldl
- at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE at am__append_272 = ceph-objectstore-tool
- at ENABLE_CLIENT_TRUE@@ENABLE_SERVER_TRUE@@WITH_MDS_TRUE@@WITH_RADOS_TRUE at am__append_273 = cephfs-journal-tool \
+ at ENABLE_SERVER_TRUE@@LINUX_TRUE@@WITH_OSD_TRUE at am__append_276 = -ldl
+ at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE at am__append_277 = ceph-objectstore-tool
+ at ENABLE_CLIENT_TRUE@@ENABLE_SERVER_TRUE@@WITH_MDS_TRUE@@WITH_RADOS_TRUE at am__append_278 = cephfs-journal-tool \
 @ENABLE_CLIENT_TRUE@@ENABLE_SERVER_TRUE@@WITH_MDS_TRUE@@WITH_RADOS_TRUE@	cephfs-table-tool \
 @ENABLE_CLIENT_TRUE@@ENABLE_SERVER_TRUE@@WITH_MDS_TRUE@@WITH_RADOS_TRUE@	cephfs-data-scan
- at WITH_LTTNG_TRUE@am__append_274 = \
+ at WITH_LTTNG_TRUE@am__append_279 = \
 @WITH_LTTNG_TRUE@	libosd_tp.la \
 @WITH_LTTNG_TRUE@	libos_tp.la \
 @WITH_LTTNG_TRUE@	librados_tp.la \
 @WITH_LTTNG_TRUE@	librbd_tp.la
 
- at WITH_LTTNG_TRUE@am__append_275 = \
+ at WITH_LTTNG_TRUE@am__append_280 = \
 @WITH_LTTNG_TRUE@	tracing/librados.h \
 @WITH_LTTNG_TRUE@	tracing/librbd.h \
 @WITH_LTTNG_TRUE@	tracing/objectstore.h \
@@ -1057,56 +1171,63 @@ check_PROGRAMS = $(am__EXEEXT_62) $(am__EXEEXT_63) \
 @WITH_LTTNG_TRUE@	tracing/osd.h \
 @WITH_LTTNG_TRUE@	tracing/pg.h
 
- at ENABLE_CLIENT_TRUE@@WITH_CYTHON_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE at am__append_276 = pybind-all
- at ENABLE_CLIENT_TRUE@@WITH_CYTHON_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE at am__append_277 = pybind-clean
- at ENABLE_CLIENT_TRUE@@WITH_CYTHON_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE at am__append_278 = pybind-install-exec
-TESTS = $(am__EXEEXT_62) $(check_SCRIPTS)
- at ENABLE_CLIENT_TRUE@am__append_279 = \
+ at ENABLE_CLIENT_TRUE@@WITH_CYTHON_TRUE@@WITH_RADOS_TRUE at am__append_281 = $(srcdir)/pybind/rados/setup.py $(srcdir)/pybind/rados/rados.pyx $(srcdir)/pybind/rados/rados.pxd
+ at ENABLE_CLIENT_TRUE@@WITH_CYTHON_TRUE@@WITH_RADOS_TRUE at am__append_282 = rados-pybind-all
+ at ENABLE_CLIENT_TRUE@@WITH_CYTHON_TRUE@@WITH_RADOS_TRUE at am__append_283 = rados-pybind-clean
+ at ENABLE_CLIENT_TRUE@@WITH_CYTHON_TRUE@@WITH_RADOS_TRUE at am__append_284 = rados-pybind-install-exec
+ at ENABLE_CLIENT_TRUE@@WITH_CYTHON_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE at am__append_285 = $(srcdir)/pybind/rbd/setup.py $(srcdir)/pybind/rbd/rbd.pyx
+ at ENABLE_CLIENT_TRUE@@WITH_CYTHON_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE at am__append_286 = rbd-pybind-all
+ at ENABLE_CLIENT_TRUE@@WITH_CYTHON_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE at am__append_287 = rbd-pybind-clean
+ at ENABLE_CLIENT_TRUE@@WITH_CYTHON_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE at am__append_288 = rbd-pybind-install-exec
+ at ENABLE_CLIENT_TRUE@@WITH_CEPHFS_TRUE@@WITH_CYTHON_TRUE@@WITH_RADOS_TRUE at am__append_289 = $(srcdir)/pybind/cephfs/setup.py $(srcdir)/pybind/cephfs/cephfs.pyx
+ at ENABLE_CLIENT_TRUE@@WITH_CEPHFS_TRUE@@WITH_CYTHON_TRUE@@WITH_RADOS_TRUE at am__append_290 = cephfs-pybind-all
+ at ENABLE_CLIENT_TRUE@@WITH_CEPHFS_TRUE@@WITH_CYTHON_TRUE@@WITH_RADOS_TRUE at am__append_291 = cephfs-pybind-clean
+ at ENABLE_CLIENT_TRUE@@WITH_CEPHFS_TRUE@@WITH_CYTHON_TRUE@@WITH_RADOS_TRUE at am__append_292 = cephfs-pybind-install-exec
+TESTS = $(am__EXEEXT_63) $(check_SCRIPTS)
+ at ENABLE_CLIENT_TRUE@am__append_293 = \
 @ENABLE_CLIENT_TRUE@	pybind/ceph_argparse.py \
 @ENABLE_CLIENT_TRUE@	pybind/ceph_daemon.py
 
- at ENABLE_CLIENT_TRUE@am__append_280 = ceph-syn
- at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE at am__append_281 = \
+ at ENABLE_CLIENT_TRUE@am__append_294 = ceph-syn
+ at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE at am__append_295 = \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@	$(srcdir)/bash_completion/rados \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@	$(srcdir)/bash_completion/radosgw-admin
 
- at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE at am__append_282 = pybind/rados.py
- at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE at am__append_283 = librados-config
- at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE at am__append_284 = \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE at am__append_296 = librados-config
+ at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE at am__append_297 = \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	$(srcdir)/bash_completion/rbd
 
- at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE at am__append_285 = \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE at am__append_298 = \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	ceph-rbdnamer \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	rbd-replay-many \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@        rbdmap
 
- at ENABLE_CLIENT_TRUE@@LINUX_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE at am__append_286 = libkrbd.la
- at ENABLE_CLIENT_TRUE@@WITH_FUSE_TRUE@@WITH_RADOS_TRUE at am__append_287 = ceph-fuse
- at ENABLE_CLIENT_TRUE@@WITH_FUSE_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE at am__append_288 = rbd-fuse
- at ENABLE_CLIENT_TRUE@@WITH_CEPHFS_TRUE@@WITH_RADOS_TRUE at am__append_289 = cephfs
- at ENABLE_CLIENT_TRUE@@WITH_CEPHFS_TRUE@@WITH_RADOS_TRUE at am__append_290 = pybind/cephfs.py \
- at ENABLE_CLIENT_TRUE@@WITH_CEPHFS_TRUE@@WITH_RADOS_TRUE@	pybind/ceph_volume_client.py
- at ENABLE_CLIENT_TRUE@@LINUX_TRUE@@WITH_CEPHFS_TRUE@@WITH_RADOS_TRUE at am__append_291 = -Xcompiler -Xlinker -Xcompiler '--exclude-libs=libcommon.a'
- at ENABLE_CLIENT_TRUE@@WITH_CEPHFS_TRUE@@WITH_RADOS_TRUE at am__append_292 = libcephfs.la
- at ENABLE_CEPHFS_JAVA_TRUE@@ENABLE_CLIENT_TRUE@@WITH_CEPHFS_TRUE@@WITH_RADOS_TRUE at am__append_293 = libcephfs_jni.la
- at ENABLE_SERVER_TRUE@am__append_294 = ceph-run ceph-rest-api \
+ at ENABLE_CLIENT_TRUE@@LINUX_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE at am__append_299 = libkrbd.la
+ at ENABLE_CLIENT_TRUE@@WITH_FUSE_TRUE@@WITH_RADOS_TRUE at am__append_300 = ceph-fuse
+ at ENABLE_CLIENT_TRUE@@WITH_FUSE_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE at am__append_301 = rbd-fuse
+ at ENABLE_CLIENT_TRUE@@WITH_CEPHFS_TRUE@@WITH_RADOS_TRUE at am__append_302 = cephfs
+ at ENABLE_CLIENT_TRUE@@WITH_CEPHFS_TRUE@@WITH_RADOS_TRUE at am__append_303 = pybind/ceph_volume_client.py
+ at ENABLE_CLIENT_TRUE@@LINUX_TRUE@@WITH_CEPHFS_TRUE@@WITH_RADOS_TRUE at am__append_304 = -Xcompiler -Xlinker -Xcompiler '--exclude-libs=libcommon.a'
+ at ENABLE_CLIENT_TRUE@@WITH_CEPHFS_TRUE@@WITH_RADOS_TRUE at am__append_305 = libcephfs.la
+ at ENABLE_CEPHFS_JAVA_TRUE@@ENABLE_CLIENT_TRUE@@WITH_CEPHFS_TRUE@@WITH_RADOS_TRUE at am__append_306 = libcephfs_jni.la
+ at ENABLE_SERVER_TRUE@am__append_307 = ceph-run ceph-rest-api \
 @ENABLE_SERVER_TRUE@	ceph-debugpack ceph-crush-location \
 @ENABLE_SERVER_TRUE@	ceph-coverage
- at ENABLE_SERVER_TRUE@am__append_295 = pybind/ceph_rest_api.py
- at ENABLE_SERVER_TRUE@am__append_296 = ceph-coverage init-ceph
- at ENABLE_SERVER_TRUE@am__append_297 = init-ceph
- at ENABLE_SERVER_TRUE@@LINUX_TRUE at am__append_298 = mount.ceph
- at ENABLE_SERVER_TRUE@am__append_299 = mount.fuse.ceph
- at ENABLE_SERVER_TRUE@@WITH_MON_TRUE at am__append_300 = ceph-mon
- at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE at am__append_301 = \
+ at ENABLE_SERVER_TRUE@am__append_308 = pybind/ceph_rest_api.py
+ at ENABLE_SERVER_TRUE@am__append_309 = ceph-coverage init-ceph
+ at ENABLE_SERVER_TRUE@am__append_310 = init-ceph
+ at ENABLE_SERVER_TRUE@@LINUX_TRUE at am__append_311 = mount.ceph
+ at ENABLE_SERVER_TRUE@am__append_312 = mount.fuse.ceph
+ at ENABLE_SERVER_TRUE@@WITH_MON_TRUE at am__append_313 = ceph-mon
+ at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE at am__append_314 = \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	ceph-disk-udev
 
- at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE at am__append_302 = \
+ at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE at am__append_315 = \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	ceph-clsinfo
 
- at ENABLE_SERVER_TRUE@@WITH_LTTNG_TRUE@@WITH_OSD_TRUE at am__append_303 = $(LIBOSD_TP)
- at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE at am__append_304 = ceph-osd
- at ENABLE_SERVER_TRUE@@WITH_MDS_TRUE at am__append_305 = ceph-mds
+ at ENABLE_SERVER_TRUE@@WITH_LTTNG_TRUE@@WITH_OSD_TRUE at am__append_316 = $(LIBOSD_TP)
+ at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE at am__append_317 = ceph-osd
+ at ENABLE_SERVER_TRUE@@WITH_MDS_TRUE at am__append_318 = ceph-mds
 subdir = src
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
 am__aclocal_m4_deps = $(top_srcdir)/m4/ac_check_classpath.m4 \
@@ -1126,9 +1247,6 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/ac_check_classpath.m4 \
 	$(top_srcdir)/m4/pkg.m4 $(top_srcdir)/configure.ac
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
 	$(ACLOCAL_M4)
-DIST_COMMON = $(srcdir)/Makefile.am $(dist_bin_SCRIPTS) \
-	$(am__python_PYTHON_DIST) $(dist_noinst_DATA) \
-	$(am__noinst_HEADERS_DIST) $(am__DIST_COMMON)
 mkinstalldirs = $(install_sh) -d
 CONFIG_HEADER = acconfig.h
 CONFIG_CLEAN_FILES =
@@ -1139,57 +1257,6 @@ AM_V_AR = $(am__v_AR_ at AM_V@)
 am__v_AR_ = $(am__v_AR_ at AM_DEFAULT_V@)
 am__v_AR_0 = @echo "  AR      " $@;
 am__v_AR_1 = 
-libcls_log_client_a_AR = $(AR) $(ARFLAGS)
-libcls_log_client_a_LIBADD =
-am__libcls_log_client_a_SOURCES_DIST = cls/log/cls_log_client.cc
-am__dirstamp = $(am__leading_dot)dirstamp
- at ENABLE_CLIENT_TRUE@am_libcls_log_client_a_OBJECTS =  \
- at ENABLE_CLIENT_TRUE@	cls/log/cls_log_client.$(OBJEXT)
-libcls_log_client_a_OBJECTS = $(am_libcls_log_client_a_OBJECTS)
-libcls_replica_log_client_a_AR = $(AR) $(ARFLAGS)
-libcls_replica_log_client_a_LIBADD =
-am__libcls_replica_log_client_a_SOURCES_DIST =  \
-	cls/replica_log/cls_replica_log_types.cc \
-	cls/replica_log/cls_replica_log_ops.cc \
-	cls/replica_log/cls_replica_log_client.cc
- at ENABLE_CLIENT_TRUE@am_libcls_replica_log_client_a_OBJECTS = cls/replica_log/cls_replica_log_types.$(OBJEXT) \
- at ENABLE_CLIENT_TRUE@	cls/replica_log/cls_replica_log_ops.$(OBJEXT) \
- at ENABLE_CLIENT_TRUE@	cls/replica_log/cls_replica_log_client.$(OBJEXT)
-libcls_replica_log_client_a_OBJECTS =  \
-	$(am_libcls_replica_log_client_a_OBJECTS)
-libcls_statelog_client_a_AR = $(AR) $(ARFLAGS)
-libcls_statelog_client_a_LIBADD =
-am__libcls_statelog_client_a_SOURCES_DIST =  \
-	cls/statelog/cls_statelog_client.cc
- at ENABLE_CLIENT_TRUE@am_libcls_statelog_client_a_OBJECTS = cls/statelog/cls_statelog_client.$(OBJEXT)
-libcls_statelog_client_a_OBJECTS =  \
-	$(am_libcls_statelog_client_a_OBJECTS)
-libcls_timeindex_client_a_AR = $(AR) $(ARFLAGS)
-libcls_timeindex_client_a_LIBADD =
-am__libcls_timeindex_client_a_SOURCES_DIST =  \
-	cls/timeindex/cls_timeindex_client.cc
- at ENABLE_CLIENT_TRUE@am_libcls_timeindex_client_a_OBJECTS = cls/timeindex/cls_timeindex_client.$(OBJEXT)
-libcls_timeindex_client_a_OBJECTS =  \
-	$(am_libcls_timeindex_client_a_OBJECTS)
-libcls_user_client_a_AR = $(AR) $(ARFLAGS)
-libcls_user_client_a_LIBADD =
-am__libcls_user_client_a_SOURCES_DIST = cls/user/cls_user_client.cc \
-	cls/user/cls_user_types.cc cls/user/cls_user_ops.cc
- at ENABLE_CLIENT_TRUE@am_libcls_user_client_a_OBJECTS =  \
- at ENABLE_CLIENT_TRUE@	cls/user/cls_user_client.$(OBJEXT) \
- at ENABLE_CLIENT_TRUE@	cls/user/cls_user_types.$(OBJEXT) \
- at ENABLE_CLIENT_TRUE@	cls/user/cls_user_ops.$(OBJEXT)
-libcls_user_client_a_OBJECTS = $(am_libcls_user_client_a_OBJECTS)
-libcls_version_client_a_AR = $(AR) $(ARFLAGS)
-libcls_version_client_a_LIBADD =
-am__libcls_version_client_a_SOURCES_DIST =  \
-	cls/version/cls_version_client.cc \
-	cls/version/cls_version_types.cc
- at ENABLE_CLIENT_TRUE@am_libcls_version_client_a_OBJECTS =  \
- at ENABLE_CLIENT_TRUE@	cls/version/cls_version_client.$(OBJEXT) \
- at ENABLE_CLIENT_TRUE@	cls/version/cls_version_types.$(OBJEXT)
-libcls_version_client_a_OBJECTS =  \
-	$(am_libcls_version_client_a_OBJECTS)
 libkv_a_AR = $(AR) $(ARFLAGS)
 am__DEPENDENCIES_1 =
 @ENABLE_SERVER_TRUE@@WITH_KINETIC_TRUE at am__DEPENDENCIES_2 =  \
@@ -1199,6 +1266,7 @@ am__DEPENDENCIES_1 =
 @ENABLE_SERVER_TRUE@	$(am__DEPENDENCIES_2)
 am__libkv_a_SOURCES_DIST = kv/KeyValueDB.cc kv/LevelDBStore.cc \
 	kv/RocksDBStore.cc kv/KineticStore.cc
+am__dirstamp = $(am__leading_dot)dirstamp
 @ENABLE_SERVER_TRUE@@WITH_SLIBROCKSDB_TRUE at am__objects_1 = kv/libkv_a-RocksDBStore.$(OBJEXT)
 @ENABLE_SERVER_TRUE@@WITH_DLIBROCKSDB_TRUE at am__objects_2 = kv/libkv_a-RocksDBStore.$(OBJEXT)
 @ENABLE_SERVER_TRUE@@WITH_KINETIC_TRUE at am__objects_3 = kv/libkv_a-KineticStore.$(OBJEXT)
@@ -1235,7 +1303,7 @@ libos_a_AR = $(AR) $(ARFLAGS)
 @ENABLE_SERVER_TRUE@	$(am__DEPENDENCIES_1)
 am__libos_a_SOURCES_DIST = os/filestore/chain_xattr.cc \
 	os/filestore/DBObjectMap.cc os/filestore/FileJournal.cc \
-	os/filestore/FileStore.cc \
+	os/filestore/FileStore.cc os/filestore/JournalThrottle.cc \
 	os/filestore/GenericFileStoreBackend.cc \
 	os/filestore/HashIndex.cc os/filestore/IndexManager.cc \
 	os/filestore/JournalingObjectStore.cc os/filestore/LFNIndex.cc \
@@ -1268,6 +1336,7 @@ am__libos_a_SOURCES_DIST = os/filestore/chain_xattr.cc \
 @ENABLE_SERVER_TRUE@	os/filestore/libos_a-DBObjectMap.$(OBJEXT) \
 @ENABLE_SERVER_TRUE@	os/filestore/libos_a-FileJournal.$(OBJEXT) \
 @ENABLE_SERVER_TRUE@	os/filestore/libos_a-FileStore.$(OBJEXT) \
+ at ENABLE_SERVER_TRUE@	os/filestore/libos_a-JournalThrottle.$(OBJEXT) \
 @ENABLE_SERVER_TRUE@	os/filestore/libos_a-GenericFileStoreBackend.$(OBJEXT) \
 @ENABLE_SERVER_TRUE@	os/filestore/libos_a-HashIndex.$(OBJEXT) \
 @ENABLE_SERVER_TRUE@	os/filestore/libos_a-IndexManager.$(OBJEXT) \
@@ -1305,7 +1374,8 @@ am__libosd_a_SOURCES_DIST = osd/PG.cc osd/ReplicatedPG.cc \
 	osd/ReplicatedBackend.cc osd/ECBackend.cc osd/ECMsgTypes.cc \
 	osd/ECTransaction.cc osd/PGBackend.cc osd/HitSet.cc osd/OSD.cc \
 	osd/OSDCap.cc osd/Watch.cc osd/ClassHandler.cc \
-	osd/OpRequest.cc osd/SnapMapper.cc objclass/class_api.cc
+	osd/OpRequest.cc osd/SnapMapper.cc osd/ScrubStore.cc \
+	objclass/class_api.cc
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE at am_libosd_a_OBJECTS =  \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	osd/libosd_a-PG.$(OBJEXT) \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	osd/libosd_a-ReplicatedPG.$(OBJEXT) \
@@ -1321,6 +1391,7 @@ am__libosd_a_SOURCES_DIST = osd/PG.cc osd/ReplicatedPG.cc \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	osd/libosd_a-ClassHandler.$(OBJEXT) \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	osd/libosd_a-OpRequest.$(OBJEXT) \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	osd/libosd_a-SnapMapper.$(OBJEXT) \
+ at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	osd/libosd_a-ScrubStore.$(OBJEXT) \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	objclass/libosd_a-class_api.$(OBJEXT)
 libosd_a_OBJECTS = $(am_libosd_a_OBJECTS)
 am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
@@ -1595,6 +1666,12 @@ libcls_log_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
 	-o $@
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE at am_libcls_log_la_rpath = -rpath \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(radoslibdir)
+libcls_log_client_la_LIBADD =
+am__libcls_log_client_la_SOURCES_DIST = cls/log/cls_log_client.cc
+ at ENABLE_CLIENT_TRUE@am_libcls_log_client_la_OBJECTS =  \
+ at ENABLE_CLIENT_TRUE@	cls/log/cls_log_client.lo
+libcls_log_client_la_OBJECTS = $(am_libcls_log_client_la_OBJECTS)
+ at ENABLE_CLIENT_TRUE@am_libcls_log_client_la_rpath =
 libcls_numops_la_LIBADD =
 am__libcls_numops_la_SOURCES_DIST = cls/numops/cls_numops.cc
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE at am_libcls_numops_la_OBJECTS =  \
@@ -1676,6 +1753,18 @@ libcls_replica_log_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
 	$(LDFLAGS) -o $@
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE at am_libcls_replica_log_la_rpath =  \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	-rpath $(radoslibdir)
+libcls_replica_log_client_la_LIBADD =
+am__libcls_replica_log_client_la_SOURCES_DIST =  \
+	cls/replica_log/cls_replica_log_types.cc \
+	cls/replica_log/cls_replica_log_ops.cc \
+	cls/replica_log/cls_replica_log_client.cc
+ at ENABLE_CLIENT_TRUE@am_libcls_replica_log_client_la_OBJECTS =  \
+ at ENABLE_CLIENT_TRUE@	cls/replica_log/cls_replica_log_types.lo \
+ at ENABLE_CLIENT_TRUE@	cls/replica_log/cls_replica_log_ops.lo \
+ at ENABLE_CLIENT_TRUE@	cls/replica_log/cls_replica_log_client.lo
+libcls_replica_log_client_la_OBJECTS =  \
+	$(am_libcls_replica_log_client_la_OBJECTS)
+ at ENABLE_CLIENT_TRUE@am_libcls_replica_log_client_la_rpath =
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE at libcls_rgw_la_DEPENDENCIES =  \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	libjson_spirit.la \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__DEPENDENCIES_1) \
@@ -1716,6 +1805,14 @@ libcls_statelog_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
 	$(LDFLAGS) -o $@
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE at am_libcls_statelog_la_rpath =  \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	-rpath $(radoslibdir)
+libcls_statelog_client_la_LIBADD =
+am__libcls_statelog_client_la_SOURCES_DIST =  \
+	cls/statelog/cls_statelog_client.cc
+ at ENABLE_CLIENT_TRUE@am_libcls_statelog_client_la_OBJECTS =  \
+ at ENABLE_CLIENT_TRUE@	cls/statelog/cls_statelog_client.lo
+libcls_statelog_client_la_OBJECTS =  \
+	$(am_libcls_statelog_client_la_OBJECTS)
+ at ENABLE_CLIENT_TRUE@am_libcls_statelog_client_la_rpath =
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE at libcls_timeindex_la_DEPENDENCIES =  \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__DEPENDENCIES_1) \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__DEPENDENCIES_3)
@@ -1728,6 +1825,14 @@ libcls_timeindex_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
 	$(LDFLAGS) -o $@
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE at am_libcls_timeindex_la_rpath =  \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	-rpath $(radoslibdir)
+libcls_timeindex_client_la_LIBADD =
+am__libcls_timeindex_client_la_SOURCES_DIST =  \
+	cls/timeindex/cls_timeindex_client.cc
+ at ENABLE_CLIENT_TRUE@am_libcls_timeindex_client_la_OBJECTS =  \
+ at ENABLE_CLIENT_TRUE@	cls/timeindex/cls_timeindex_client.lo
+libcls_timeindex_client_la_OBJECTS =  \
+	$(am_libcls_timeindex_client_la_OBJECTS)
+ at ENABLE_CLIENT_TRUE@am_libcls_timeindex_client_la_rpath =
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE at libcls_user_la_DEPENDENCIES =  \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__DEPENDENCIES_1) \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__DEPENDENCIES_3)
@@ -1741,6 +1846,15 @@ libcls_user_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
 	$(LDFLAGS) -o $@
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE at am_libcls_user_la_rpath = -rpath \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(radoslibdir)
+libcls_user_client_la_LIBADD =
+am__libcls_user_client_la_SOURCES_DIST = cls/user/cls_user_client.cc \
+	cls/user/cls_user_types.cc cls/user/cls_user_ops.cc
+ at ENABLE_CLIENT_TRUE@am_libcls_user_client_la_OBJECTS =  \
+ at ENABLE_CLIENT_TRUE@	cls/user/cls_user_client.lo \
+ at ENABLE_CLIENT_TRUE@	cls/user/cls_user_types.lo \
+ at ENABLE_CLIENT_TRUE@	cls/user/cls_user_ops.lo
+libcls_user_client_la_OBJECTS = $(am_libcls_user_client_la_OBJECTS)
+ at ENABLE_CLIENT_TRUE@am_libcls_user_client_la_rpath =
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE at libcls_version_la_DEPENDENCIES =  \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__DEPENDENCIES_1) \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__DEPENDENCIES_3)
@@ -1754,8 +1868,18 @@ libcls_version_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
 	$(LDFLAGS) -o $@
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE at am_libcls_version_la_rpath =  \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	-rpath $(radoslibdir)
+libcls_version_client_la_LIBADD =
+am__libcls_version_client_la_SOURCES_DIST =  \
+	cls/version/cls_version_client.cc \
+	cls/version/cls_version_types.cc
+ at ENABLE_CLIENT_TRUE@am_libcls_version_client_la_OBJECTS =  \
+ at ENABLE_CLIENT_TRUE@	cls/version/cls_version_client.lo \
+ at ENABLE_CLIENT_TRUE@	cls/version/cls_version_types.lo
+libcls_version_client_la_OBJECTS =  \
+	$(am_libcls_version_client_la_OBJECTS)
+ at ENABLE_CLIENT_TRUE@am_libcls_version_client_la_rpath =
 am__DEPENDENCIES_5 = libcommon_internal.la libcommon_crc.la \
-	$(am__append_114) $(LIBERASURE_CODE) $(LIBCOMPRESSOR) \
+	$(am__append_113) $(LIBERASURE_CODE) $(LIBCOMPRESSOR) \
 	$(LIBMSG) $(LIBAUTH) $(LIBCRUSH) $(LIBJSON_SPIRIT) $(LIBLOG) \
 	$(LIBARCH) $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1)
 libcommon_la_DEPENDENCIES = $(am__DEPENDENCIES_5)
@@ -1798,15 +1922,15 @@ am__libcommon_internal_la_SOURCES_DIST = ceph_ver.c \
 	common/escape.c common/io_priority.cc common/ceph_time.cc \
 	common/Clock.cc common/Throttle.cc common/Timer.cc \
 	common/Finisher.cc common/environment.cc common/assert.cc \
-	common/run_cmd.cc common/WorkQueue.cc common/ConfUtils.cc \
-	common/MemoryModel.cc common/armor.c common/fd.cc \
-	common/safe_io.c common/snap_types.cc common/str_list.cc \
-	common/str_map.cc common/errno.cc common/RefCountedObj.cc \
-	common/common_init.cc common/pipe.c common/ceph_argparse.cc \
-	common/ceph_context.cc common/types.cc \
-	common/code_environment.cc common/dout.cc common/histogram.cc \
-	common/signal.cc common/simple_spin.cc common/Thread.cc \
-	common/Formatter.cc common/HTMLFormatter.cc \
+	xxHash/xxhash.c common/run_cmd.cc common/WorkQueue.cc \
+	common/ConfUtils.cc common/MemoryModel.cc common/armor.c \
+	common/fd.cc common/fs_types.cc common/safe_io.c \
+	common/snap_types.cc common/str_list.cc common/str_map.cc \
+	common/errno.cc common/RefCountedObj.cc common/common_init.cc \
+	common/pipe.c common/ceph_argparse.cc common/ceph_context.cc \
+	common/types.cc common/code_environment.cc common/dout.cc \
+	common/histogram.cc common/signal.cc common/simple_spin.cc \
+	common/Thread.cc common/Formatter.cc common/HTMLFormatter.cc \
 	common/HeartbeatMap.cc common/config.cc common/utf8.c \
 	common/mime.c common/strtol.cc common/page.cc \
 	common/lockdep.cc common/version.cc common/hex.cc \
@@ -1817,21 +1941,21 @@ am__libcommon_internal_la_SOURCES_DIST = ceph_ver.c \
 	common/bloom_filter.cc common/module.c common/Readahead.cc \
 	common/Cycles.cc common/ContextCompletion.cc \
 	common/TracepointProvider.cc common/PluginRegistry.cc \
-	common/xattr.c common/ipaddr.cc common/ceph_json.cc \
-	common/util.cc common/pick_address.cc common/linux_version.c \
-	common/solaris_errno.cc common/aix_errno.cc common/blkdev.cc \
+	common/scrub_types.cc common/blkdev.cc common/xattr.c \
+	common/ipaddr.cc common/ceph_json.cc common/util.cc \
+	common/pick_address.cc common/linux_version.c \
+	common/solaris_errno.cc common/aix_errno.cc \
 	common/address_helper.cc mon/MonCap.cc mon/MonClient.cc \
 	mon/MonMap.cc osd/OSDMap.cc osd/osd_types.cc osd/ECMsgTypes.cc \
-	osd/HitSet.cc mds/MDSMap.cc mds/inode_backtrace.cc \
-	mds/mdstypes.cc mds/flock.cc
+	osd/HitSet.cc mds/MDSMap.cc mds/FSMap.cc \
+	mds/inode_backtrace.cc mds/mdstypes.cc mds/flock.cc
 @ENABLE_SERVER_TRUE at am__objects_14 = common/xattr.lo common/ipaddr.lo \
 @ENABLE_SERVER_TRUE@	common/ceph_json.lo common/util.lo \
 @ENABLE_SERVER_TRUE@	common/pick_address.lo
 @LINUX_TRUE at am__objects_15 = common/linux_version.lo
 @SOLARIS_TRUE at am__objects_16 = common/solaris_errno.lo
 @AIX_TRUE at am__objects_17 = common/aix_errno.lo
- at LINUX_TRUE@am__objects_18 = common/blkdev.lo
- at ENABLE_XIO_TRUE@am__objects_19 = common/address_helper.lo
+ at ENABLE_XIO_TRUE@am__objects_18 = common/address_helper.lo
 am_libcommon_internal_la_OBJECTS = ceph_ver.lo common/DecayCounter.lo \
 	common/LogClient.lo common/LogEntry.lo common/Graylog.lo \
 	common/PrebufferedStreambuf.lo common/SloppyCRCMap.lo \
@@ -1842,15 +1966,15 @@ am_libcommon_internal_la_OBJECTS = ceph_ver.lo common/DecayCounter.lo \
 	common/escape.lo common/io_priority.lo common/ceph_time.lo \
 	common/Clock.lo common/Throttle.lo common/Timer.lo \
 	common/Finisher.lo common/environment.lo common/assert.lo \
-	common/run_cmd.lo common/WorkQueue.lo common/ConfUtils.lo \
-	common/MemoryModel.lo common/armor.lo common/fd.lo \
-	common/safe_io.lo common/snap_types.lo common/str_list.lo \
-	common/str_map.lo common/errno.lo common/RefCountedObj.lo \
-	common/common_init.lo common/pipe.lo common/ceph_argparse.lo \
-	common/ceph_context.lo common/types.lo \
-	common/code_environment.lo common/dout.lo common/histogram.lo \
-	common/signal.lo common/simple_spin.lo common/Thread.lo \
-	common/Formatter.lo common/HTMLFormatter.lo \
+	xxHash/xxhash.lo common/run_cmd.lo common/WorkQueue.lo \
+	common/ConfUtils.lo common/MemoryModel.lo common/armor.lo \
+	common/fd.lo common/fs_types.lo common/safe_io.lo \
+	common/snap_types.lo common/str_list.lo common/str_map.lo \
+	common/errno.lo common/RefCountedObj.lo common/common_init.lo \
+	common/pipe.lo common/ceph_argparse.lo common/ceph_context.lo \
+	common/types.lo common/code_environment.lo common/dout.lo \
+	common/histogram.lo common/signal.lo common/simple_spin.lo \
+	common/Thread.lo common/Formatter.lo common/HTMLFormatter.lo \
 	common/HeartbeatMap.lo common/config.lo common/utf8.lo \
 	common/mime.lo common/strtol.lo common/page.lo \
 	common/lockdep.lo common/version.lo common/hex.lo \
@@ -1861,11 +1985,12 @@ am_libcommon_internal_la_OBJECTS = ceph_ver.lo common/DecayCounter.lo \
 	common/bloom_filter.lo common/module.lo common/Readahead.lo \
 	common/Cycles.lo common/ContextCompletion.lo \
 	common/TracepointProvider.lo common/PluginRegistry.lo \
-	$(am__objects_14) $(am__objects_15) $(am__objects_16) \
-	$(am__objects_17) $(am__objects_18) $(am__objects_19) \
-	mon/MonCap.lo mon/MonClient.lo mon/MonMap.lo osd/OSDMap.lo \
-	osd/osd_types.lo osd/ECMsgTypes.lo osd/HitSet.lo mds/MDSMap.lo \
-	mds/inode_backtrace.lo mds/mdstypes.lo mds/flock.lo
+	common/scrub_types.lo common/blkdev.lo $(am__objects_14) \
+	$(am__objects_15) $(am__objects_16) $(am__objects_17) \
+	$(am__objects_18) mon/MonCap.lo mon/MonClient.lo mon/MonMap.lo \
+	osd/OSDMap.lo osd/osd_types.lo osd/ECMsgTypes.lo osd/HitSet.lo \
+	mds/MDSMap.lo mds/FSMap.lo mds/inode_backtrace.lo \
+	mds/mdstypes.lo mds/flock.lo
 libcommon_internal_la_OBJECTS = $(am_libcommon_internal_la_OBJECTS)
 am_libcompressor_la_OBJECTS = compressor/Compressor.lo \
 	compressor/AsyncCompressor.lo
@@ -1953,7 +2078,7 @@ libec_jerasure_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
 	$(libec_jerasure_la_LDFLAGS) $(LDFLAGS) -o $@
 libec_jerasure_generic_la_DEPENDENCIES = $(LIBCRUSH) \
 	$(am__DEPENDENCIES_1) $(am__DEPENDENCIES_3)
-am__objects_20 =  \
+am__objects_19 =  \
 	erasure-code/libec_jerasure_generic_la-ErasureCode.lo \
 	erasure-code/jerasure/jerasure/src/libec_jerasure_generic_la-cauchy.lo \
 	erasure-code/jerasure/jerasure/src/libec_jerasure_generic_la-galois.lo \
@@ -1973,7 +2098,7 @@ am__objects_20 =  \
 	erasure-code/jerasure/gf-complete/src/libec_jerasure_generic_la-gf_w8.lo \
 	erasure-code/jerasure/libec_jerasure_generic_la-ErasureCodePluginJerasure.lo \
 	erasure-code/jerasure/libec_jerasure_generic_la-ErasureCodeJerasure.lo
-am_libec_jerasure_generic_la_OBJECTS = $(am__objects_20)
+am_libec_jerasure_generic_la_OBJECTS = $(am__objects_19)
 libec_jerasure_generic_la_OBJECTS =  \
 	$(am_libec_jerasure_generic_la_OBJECTS)
 libec_jerasure_generic_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
@@ -1982,7 +2107,7 @@ libec_jerasure_generic_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
 	$(libec_jerasure_generic_la_LDFLAGS) $(LDFLAGS) -o $@
 libec_jerasure_neon_la_DEPENDENCIES = $(LIBCRUSH) \
 	$(am__DEPENDENCIES_1) $(am__DEPENDENCIES_3)
-am__objects_21 = erasure-code/libec_jerasure_neon_la-ErasureCode.lo \
+am__objects_20 = erasure-code/libec_jerasure_neon_la-ErasureCode.lo \
 	erasure-code/jerasure/jerasure/src/libec_jerasure_neon_la-cauchy.lo \
 	erasure-code/jerasure/jerasure/src/libec_jerasure_neon_la-galois.lo \
 	erasure-code/jerasure/jerasure/src/libec_jerasure_neon_la-jerasure.lo \
@@ -2001,7 +2126,7 @@ am__objects_21 = erasure-code/libec_jerasure_neon_la-ErasureCode.lo \
 	erasure-code/jerasure/gf-complete/src/libec_jerasure_neon_la-gf_w8.lo \
 	erasure-code/jerasure/libec_jerasure_neon_la-ErasureCodePluginJerasure.lo \
 	erasure-code/jerasure/libec_jerasure_neon_la-ErasureCodeJerasure.lo
-am_libec_jerasure_neon_la_OBJECTS = $(am__objects_21) \
+am_libec_jerasure_neon_la_OBJECTS = $(am__objects_20) \
 	erasure-code/jerasure/gf-complete/src/neon/libec_jerasure_neon_la-gf_w4_neon.lo \
 	erasure-code/jerasure/gf-complete/src/neon/libec_jerasure_neon_la-gf_w8_neon.lo \
 	erasure-code/jerasure/gf-complete/src/neon/libec_jerasure_neon_la-gf_w16_neon.lo \
@@ -2016,7 +2141,7 @@ libec_jerasure_neon_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
 @HAVE_NEON_TRUE@	$(erasure_codelibdir)
 libec_jerasure_sse3_la_DEPENDENCIES = $(LIBCRUSH) \
 	$(am__DEPENDENCIES_1) $(am__DEPENDENCIES_3)
-am__objects_22 = erasure-code/libec_jerasure_sse3_la-ErasureCode.lo \
+am__objects_21 = erasure-code/libec_jerasure_sse3_la-ErasureCode.lo \
 	erasure-code/jerasure/jerasure/src/libec_jerasure_sse3_la-cauchy.lo \
 	erasure-code/jerasure/jerasure/src/libec_jerasure_sse3_la-galois.lo \
 	erasure-code/jerasure/jerasure/src/libec_jerasure_sse3_la-jerasure.lo \
@@ -2035,7 +2160,7 @@ am__objects_22 = erasure-code/libec_jerasure_sse3_la-ErasureCode.lo \
 	erasure-code/jerasure/gf-complete/src/libec_jerasure_sse3_la-gf_w8.lo \
 	erasure-code/jerasure/libec_jerasure_sse3_la-ErasureCodePluginJerasure.lo \
 	erasure-code/jerasure/libec_jerasure_sse3_la-ErasureCodeJerasure.lo
-am_libec_jerasure_sse3_la_OBJECTS = $(am__objects_22)
+am_libec_jerasure_sse3_la_OBJECTS = $(am__objects_21)
 libec_jerasure_sse3_la_OBJECTS = $(am_libec_jerasure_sse3_la_OBJECTS)
 libec_jerasure_sse3_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
 	$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \
@@ -2045,7 +2170,7 @@ libec_jerasure_sse3_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
 @HAVE_SSSE3_TRUE@	$(erasure_codelibdir)
 libec_jerasure_sse4_la_DEPENDENCIES = $(LIBCRUSH) \
 	$(am__DEPENDENCIES_1) $(am__DEPENDENCIES_3)
-am__objects_23 = erasure-code/libec_jerasure_sse4_la-ErasureCode.lo \
+am__objects_22 = erasure-code/libec_jerasure_sse4_la-ErasureCode.lo \
 	erasure-code/jerasure/jerasure/src/libec_jerasure_sse4_la-cauchy.lo \
 	erasure-code/jerasure/jerasure/src/libec_jerasure_sse4_la-galois.lo \
 	erasure-code/jerasure/jerasure/src/libec_jerasure_sse4_la-jerasure.lo \
@@ -2064,7 +2189,7 @@ am__objects_23 = erasure-code/libec_jerasure_sse4_la-ErasureCode.lo \
 	erasure-code/jerasure/gf-complete/src/libec_jerasure_sse4_la-gf_w8.lo \
 	erasure-code/jerasure/libec_jerasure_sse4_la-ErasureCodePluginJerasure.lo \
 	erasure-code/jerasure/libec_jerasure_sse4_la-ErasureCodeJerasure.lo
-am_libec_jerasure_sse4_la_OBJECTS = $(am__objects_23)
+am_libec_jerasure_sse4_la_OBJECTS = $(am__objects_22)
 libec_jerasure_sse4_la_OBJECTS = $(am_libec_jerasure_sse4_la_OBJECTS)
 libec_jerasure_sse4_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
 	$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \
@@ -2074,10 +2199,10 @@ libec_jerasure_sse4_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
 @HAVE_SSE4_PCLMUL_TRUE@	$(erasure_codelibdir)
 libec_lrc_la_DEPENDENCIES = $(LIBCRUSH) $(am__DEPENDENCIES_1) \
 	$(LIBJSON_SPIRIT)
-am__objects_24 = erasure-code/libec_lrc_la-ErasureCode.lo \
+am__objects_23 = erasure-code/libec_lrc_la-ErasureCode.lo \
 	erasure-code/lrc/libec_lrc_la-ErasureCodePluginLrc.lo \
 	erasure-code/lrc/libec_lrc_la-ErasureCodeLrc.lo
-am_libec_lrc_la_OBJECTS = $(am__objects_24) \
+am_libec_lrc_la_OBJECTS = $(am__objects_23) \
 	common/libec_lrc_la-str_map.lo
 libec_lrc_la_OBJECTS = $(am_libec_lrc_la_OBJECTS)
 libec_lrc_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \
@@ -2123,7 +2248,7 @@ libec_shec_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
 	$(LDFLAGS) -o $@
 libec_shec_generic_la_DEPENDENCIES = $(LIBCRUSH) $(am__DEPENDENCIES_1) \
 	$(am__DEPENDENCIES_3)
-am__objects_25 = erasure-code/libec_shec_generic_la-ErasureCode.lo \
+am__objects_24 = erasure-code/libec_shec_generic_la-ErasureCode.lo \
 	erasure-code/shec/libec_shec_generic_la-ErasureCodePluginShec.lo \
 	erasure-code/shec/libec_shec_generic_la-ErasureCodeShec.lo \
 	erasure-code/shec/libec_shec_generic_la-ErasureCodeShecTableCache.lo \
@@ -2144,7 +2269,7 @@ am__objects_25 = erasure-code/libec_shec_generic_la-ErasureCode.lo \
 	erasure-code/jerasure/gf-complete/src/libec_shec_generic_la-gf_w4.lo \
 	erasure-code/jerasure/gf-complete/src/libec_shec_generic_la-gf_rand.lo \
 	erasure-code/jerasure/gf-complete/src/libec_shec_generic_la-gf_w8.lo
-am_libec_shec_generic_la_OBJECTS = $(am__objects_25)
+am_libec_shec_generic_la_OBJECTS = $(am__objects_24)
 libec_shec_generic_la_OBJECTS = $(am_libec_shec_generic_la_OBJECTS)
 libec_shec_generic_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
 	$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \
@@ -2152,7 +2277,7 @@ libec_shec_generic_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
 	$(libec_shec_generic_la_LDFLAGS) $(LDFLAGS) -o $@
 libec_shec_neon_la_DEPENDENCIES = $(LIBCRUSH) $(am__DEPENDENCIES_1) \
 	$(am__DEPENDENCIES_3)
-am__objects_26 = erasure-code/libec_shec_neon_la-ErasureCode.lo \
+am__objects_25 = erasure-code/libec_shec_neon_la-ErasureCode.lo \
 	erasure-code/shec/libec_shec_neon_la-ErasureCodePluginShec.lo \
 	erasure-code/shec/libec_shec_neon_la-ErasureCodeShec.lo \
 	erasure-code/shec/libec_shec_neon_la-ErasureCodeShecTableCache.lo \
@@ -2173,7 +2298,7 @@ am__objects_26 = erasure-code/libec_shec_neon_la-ErasureCode.lo \
 	erasure-code/jerasure/gf-complete/src/libec_shec_neon_la-gf_w4.lo \
 	erasure-code/jerasure/gf-complete/src/libec_shec_neon_la-gf_rand.lo \
 	erasure-code/jerasure/gf-complete/src/libec_shec_neon_la-gf_w8.lo
-am_libec_shec_neon_la_OBJECTS = $(am__objects_26) \
+am_libec_shec_neon_la_OBJECTS = $(am__objects_25) \
 	erasure-code/jerasure/gf-complete/src/neon/libec_shec_neon_la-gf_w4_neon.lo \
 	erasure-code/jerasure/gf-complete/src/neon/libec_shec_neon_la-gf_w8_neon.lo \
 	erasure-code/jerasure/gf-complete/src/neon/libec_shec_neon_la-gf_w16_neon.lo \
@@ -2188,7 +2313,7 @@ libec_shec_neon_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
 @HAVE_NEON_TRUE@	$(erasure_codelibdir)
 libec_shec_sse3_la_DEPENDENCIES = $(LIBCRUSH) $(am__DEPENDENCIES_1) \
 	$(am__DEPENDENCIES_3)
-am__objects_27 = erasure-code/libec_shec_sse3_la-ErasureCode.lo \
+am__objects_26 = erasure-code/libec_shec_sse3_la-ErasureCode.lo \
 	erasure-code/shec/libec_shec_sse3_la-ErasureCodePluginShec.lo \
 	erasure-code/shec/libec_shec_sse3_la-ErasureCodeShec.lo \
 	erasure-code/shec/libec_shec_sse3_la-ErasureCodeShecTableCache.lo \
@@ -2209,7 +2334,7 @@ am__objects_27 = erasure-code/libec_shec_sse3_la-ErasureCode.lo \
 	erasure-code/jerasure/gf-complete/src/libec_shec_sse3_la-gf_w4.lo \
 	erasure-code/jerasure/gf-complete/src/libec_shec_sse3_la-gf_rand.lo \
 	erasure-code/jerasure/gf-complete/src/libec_shec_sse3_la-gf_w8.lo
-am_libec_shec_sse3_la_OBJECTS = $(am__objects_27)
+am_libec_shec_sse3_la_OBJECTS = $(am__objects_26)
 libec_shec_sse3_la_OBJECTS = $(am_libec_shec_sse3_la_OBJECTS)
 libec_shec_sse3_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
 	$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \
@@ -2219,7 +2344,7 @@ libec_shec_sse3_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
 @HAVE_SSSE3_TRUE@	$(erasure_codelibdir)
 libec_shec_sse4_la_DEPENDENCIES = $(LIBCRUSH) $(am__DEPENDENCIES_1) \
 	$(am__DEPENDENCIES_3)
-am__objects_28 = erasure-code/libec_shec_sse4_la-ErasureCode.lo \
+am__objects_27 = erasure-code/libec_shec_sse4_la-ErasureCode.lo \
 	erasure-code/shec/libec_shec_sse4_la-ErasureCodePluginShec.lo \
 	erasure-code/shec/libec_shec_sse4_la-ErasureCodeShec.lo \
 	erasure-code/shec/libec_shec_sse4_la-ErasureCodeShecTableCache.lo \
@@ -2240,7 +2365,7 @@ am__objects_28 = erasure-code/libec_shec_sse4_la-ErasureCode.lo \
 	erasure-code/jerasure/gf-complete/src/libec_shec_sse4_la-gf_w4.lo \
 	erasure-code/jerasure/gf-complete/src/libec_shec_sse4_la-gf_rand.lo \
 	erasure-code/jerasure/gf-complete/src/libec_shec_sse4_la-gf_w8.lo
-am_libec_shec_sse4_la_OBJECTS = $(am__objects_28)
+am_libec_shec_sse4_la_OBJECTS = $(am__objects_27)
 libec_shec_sse4_la_OBJECTS = $(am_libec_shec_sse4_la_OBJECTS)
 libec_shec_sse4_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
 	$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \
@@ -2423,7 +2548,7 @@ am__libisa_la_SOURCES_DIST = erasure-code/ErasureCode.cc \
 	erasure-code/isa/ErasureCodeIsaTableCache.cc \
 	erasure-code/isa/ErasureCodePluginIsa.cc \
 	erasure-code/isa/xor_op.cc
- at WITH_BETTER_YASM_ELF64_TRUE@am__objects_29 = erasure-code/libisa_la-ErasureCode.lo \
+ at WITH_BETTER_YASM_ELF64_TRUE@am__objects_28 = erasure-code/libisa_la-ErasureCode.lo \
 @WITH_BETTER_YASM_ELF64_TRUE@	erasure-code/isa/isa-l/erasure_code/libisa_la-ec_base.lo \
 @WITH_BETTER_YASM_ELF64_TRUE@	erasure-code/isa/isa-l/erasure_code/libisa_la-ec_highlevel_func.lo \
 @WITH_BETTER_YASM_ELF64_TRUE@	erasure-code/isa/isa-l/erasure_code/libisa_la-ec_multibinary.asm.lo \
@@ -2469,7 +2594,7 @@ am__libisa_la_SOURCES_DIST = erasure-code/ErasureCode.cc \
 @WITH_BETTER_YASM_ELF64_TRUE@	erasure-code/isa/libisa_la-ErasureCodeIsaTableCache.lo \
 @WITH_BETTER_YASM_ELF64_TRUE@	erasure-code/isa/libisa_la-ErasureCodePluginIsa.lo \
 @WITH_BETTER_YASM_ELF64_TRUE@	erasure-code/isa/libisa_la-xor_op.lo
- at WITH_BETTER_YASM_ELF64_TRUE@am_libisa_la_OBJECTS = $(am__objects_29)
+ at WITH_BETTER_YASM_ELF64_TRUE@am_libisa_la_OBJECTS = $(am__objects_28)
 libisa_la_OBJECTS = $(am_libisa_la_OBJECTS)
 libisa_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
 	$(libisa_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \
@@ -2518,25 +2643,25 @@ am__libmds_la_SOURCES_DIST = mds/Capability.cc mds/MDSDaemon.cc \
 	mds/Server.cc mds/Mutation.cc mds/MDCache.cc \
 	mds/RecoveryQueue.cc mds/StrayManager.cc mds/Locker.cc \
 	mds/Migrator.cc mds/MDBalancer.cc mds/CDentry.cc mds/CDir.cc \
-	mds/CInode.cc mds/LogEvent.cc mds/MDSTable.cc mds/InoTable.cc \
-	mds/JournalPointer.cc mds/MDSTableClient.cc \
-	mds/MDSTableServer.cc mds/SimpleLock.cc mds/ScrubStack.cc \
-	mds/SnapRealm.cc mds/SnapServer.cc mds/snap.cc \
-	mds/SessionMap.cc mds/MDSContext.cc mds/MDSAuthCaps.cc \
-	mds/MDLog.cc
-am__objects_30 = mds/Capability.lo mds/MDSDaemon.lo mds/MDSRank.lo \
+	mds/CInode.cc mds/DamageTable.cc mds/LogEvent.cc \
+	mds/MDSTable.cc mds/InoTable.cc mds/JournalPointer.cc \
+	mds/MDSTableClient.cc mds/MDSTableServer.cc mds/SimpleLock.cc \
+	mds/ScrubStack.cc mds/SnapRealm.cc mds/SnapServer.cc \
+	mds/snap.cc mds/SessionMap.cc mds/MDSContext.cc \
+	mds/MDSAuthCaps.cc mds/MDLog.cc
+am__objects_29 = mds/Capability.lo mds/MDSDaemon.lo mds/MDSRank.lo \
 	mds/Beacon.lo mds/locks.lo mds/journal.lo mds/Server.lo \
 	mds/Mutation.lo mds/MDCache.lo mds/RecoveryQueue.lo \
 	mds/StrayManager.lo mds/Locker.lo mds/Migrator.lo \
 	mds/MDBalancer.lo mds/CDentry.lo mds/CDir.lo mds/CInode.lo \
-	mds/LogEvent.lo mds/MDSTable.lo mds/InoTable.lo \
-	mds/JournalPointer.lo mds/MDSTableClient.lo \
+	mds/DamageTable.lo mds/LogEvent.lo mds/MDSTable.lo \
+	mds/InoTable.lo mds/JournalPointer.lo mds/MDSTableClient.lo \
 	mds/MDSTableServer.lo mds/SimpleLock.lo mds/ScrubStack.lo \
 	mds/SnapRealm.lo mds/SnapServer.lo mds/snap.lo \
 	mds/SessionMap.lo mds/MDSContext.lo mds/MDSAuthCaps.lo \
 	mds/MDLog.lo
 @ENABLE_SERVER_TRUE@@WITH_MDS_TRUE at am_libmds_la_OBJECTS =  \
- at ENABLE_SERVER_TRUE@@WITH_MDS_TRUE@	$(am__objects_30)
+ at ENABLE_SERVER_TRUE@@WITH_MDS_TRUE@	$(am__objects_29)
 libmds_la_OBJECTS = $(am_libmds_la_OBJECTS)
 @ENABLE_SERVER_TRUE@@WITH_MDS_TRUE at am_libmds_la_rpath =
 libmon_types_la_LIBADD =
@@ -2554,11 +2679,11 @@ am__libmsg_la_SOURCES_DIST = msg/Message.cc msg/Messenger.cc \
 	msg/async/EventKqueue.h msg/xio/QueueStrategy.cc \
 	msg/xio/XioConnection.cc msg/xio/XioMessenger.cc \
 	msg/xio/XioMsg.cc msg/xio/XioPortal.cc msg/xio/XioPool.cc
- at LINUX_TRUE@am__objects_31 = msg/async/EventEpoll.lo
- at DARWIN_TRUE@am__objects_32 = msg/async/EventKqueue.lo
- at FREEBSD_TRUE@am__objects_33 = msg/async/EventKqueue.lo
-am__objects_34 =
- at ENABLE_XIO_TRUE@am__objects_35 = msg/xio/QueueStrategy.lo \
+ at LINUX_TRUE@am__objects_30 = msg/async/EventEpoll.lo
+ at DARWIN_TRUE@am__objects_31 = msg/async/EventKqueue.lo
+ at FREEBSD_TRUE@am__objects_32 = msg/async/EventKqueue.lo
+am__objects_33 =
+ at ENABLE_XIO_TRUE@am__objects_34 = msg/xio/QueueStrategy.lo \
 @ENABLE_XIO_TRUE@	msg/xio/XioConnection.lo \
 @ENABLE_XIO_TRUE@	msg/xio/XioMessenger.lo msg/xio/XioMsg.lo \
 @ENABLE_XIO_TRUE@	msg/xio/XioPortal.lo msg/xio/XioPool.lo
@@ -2568,9 +2693,9 @@ am_libmsg_la_OBJECTS = msg/Message.lo msg/Messenger.lo \
 	msg/simple/PipeConnection.lo msg/simple/SimpleMessenger.lo \
 	msg/async/AsyncConnection.lo msg/async/AsyncMessenger.lo \
 	msg/async/Event.lo msg/async/net_handler.lo \
-	msg/async/EventSelect.lo $(am__objects_31) $(am__objects_32) \
-	$(am__objects_33) $(am__objects_34) $(am__objects_34) \
-	$(am__objects_34) $(am__objects_35)
+	msg/async/EventSelect.lo $(am__objects_30) $(am__objects_31) \
+	$(am__objects_32) $(am__objects_33) $(am__objects_33) \
+	$(am__objects_33) $(am__objects_34)
 libmsg_la_OBJECTS = $(am_libmsg_la_OBJECTS)
 libos_tp_la_DEPENDENCIES =
 am__libos_tp_la_SOURCES_DIST = tracing/objectstore.c
@@ -2613,13 +2738,13 @@ libperfglue_la_DEPENDENCIES =
 am__libperfglue_la_SOURCES_DIST = perfglue/heap_profiler.cc \
 	perfglue/disabled_heap_profiler.cc perfglue/cpu_profiler.cc \
 	perfglue/disabled_stubs.cc
- at WITH_TCMALLOC_TRUE@am__objects_36 = perfglue/heap_profiler.lo
- at WITH_TCMALLOC_FALSE@@WITH_TCMALLOC_MINIMAL_TRUE at am__objects_37 = perfglue/heap_profiler.lo
- at WITH_TCMALLOC_FALSE@@WITH_TCMALLOC_MINIMAL_FALSE at am__objects_38 = perfglue/disabled_heap_profiler.lo
- at WITH_PROFILER_TRUE@am__objects_39 = perfglue/cpu_profiler.lo
- at WITH_PROFILER_FALSE@am__objects_40 = perfglue/disabled_stubs.lo
-am_libperfglue_la_OBJECTS = $(am__objects_36) $(am__objects_37) \
-	$(am__objects_38) $(am__objects_39) $(am__objects_40)
+ at WITH_TCMALLOC_TRUE@am__objects_35 = perfglue/heap_profiler.lo
+ at WITH_TCMALLOC_FALSE@@WITH_TCMALLOC_MINIMAL_TRUE at am__objects_36 = perfglue/heap_profiler.lo
+ at WITH_TCMALLOC_FALSE@@WITH_TCMALLOC_MINIMAL_FALSE at am__objects_37 = perfglue/disabled_heap_profiler.lo
+ at WITH_PROFILER_TRUE@am__objects_38 = perfglue/cpu_profiler.lo
+ at WITH_PROFILER_FALSE@am__objects_39 = perfglue/disabled_stubs.lo
+am_libperfglue_la_OBJECTS = $(am__objects_35) $(am__objects_36) \
+	$(am__objects_37) $(am__objects_38) $(am__objects_39)
 libperfglue_la_OBJECTS = $(am_libperfglue_la_OBJECTS)
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE at am__DEPENDENCIES_6 =  \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@	librados_internal.la \
@@ -2780,6 +2905,8 @@ am__librbd_internal_la_SOURCES_DIST = librbd/AioCompletion.cc \
 	librbd/image/CloseRequest.cc librbd/image/OpenRequest.cc \
 	librbd/image/RefreshParentRequest.cc \
 	librbd/image/RefreshRequest.cc librbd/image/SetSnapRequest.cc \
+	librbd/image_watcher/Notifier.cc \
+	librbd/image_watcher/NotifyLockOwner.cc \
 	librbd/journal/Replay.cc \
 	librbd/object_map/InvalidateRequest.cc \
 	librbd/object_map/LockRequest.cc librbd/object_map/Request.cc \
@@ -2828,6 +2955,8 @@ am__librbd_internal_la_SOURCES_DIST = librbd/AioCompletion.cc \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	librbd/image/RefreshParentRequest.lo \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	librbd/image/RefreshRequest.lo \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	librbd/image/SetSnapRequest.lo \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	librbd/image_watcher/Notifier.lo \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	librbd/image_watcher/NotifyLockOwner.lo \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	librbd/journal/Replay.lo \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	librbd/object_map/InvalidateRequest.lo \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	librbd/object_map/LockRequest.lo \
@@ -2856,24 +2985,49 @@ librbd_internal_la_OBJECTS = $(am_librbd_internal_la_OBJECTS)
 librbd_mirror_internal_la_LIBADD =
 am__librbd_mirror_internal_la_SOURCES_DIST =  \
 	tools/rbd_mirror/ClusterWatcher.cc \
-	tools/rbd_mirror/ImageReplayer.cc tools/rbd_mirror/Mirror.cc \
+	tools/rbd_mirror/ImageReplayer.cc \
+	tools/rbd_mirror/ImageSync.cc tools/rbd_mirror/Mirror.cc \
 	tools/rbd_mirror/PoolWatcher.cc tools/rbd_mirror/Replayer.cc \
-	tools/rbd_mirror/types.cc
+	tools/rbd_mirror/Threads.cc tools/rbd_mirror/types.cc \
+	tools/rbd_mirror/image_replayer/BootstrapRequest.cc \
+	tools/rbd_mirror/image_replayer/CloseImageRequest.cc \
+	tools/rbd_mirror/image_replayer/OpenLocalImageRequest.cc \
+	tools/rbd_mirror/image_sync/ImageCopyRequest.cc \
+	tools/rbd_mirror/image_sync/ObjectCopyRequest.cc \
+	tools/rbd_mirror/image_sync/SnapshotCopyRequest.cc \
+	tools/rbd_mirror/image_sync/SyncPointCreateRequest.cc \
+	tools/rbd_mirror/image_sync/SyncPointPruneRequest.cc
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE at am_librbd_mirror_internal_la_OBJECTS = tools/rbd_mirror/ClusterWatcher.lo \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	tools/rbd_mirror/ImageReplayer.lo \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	tools/rbd_mirror/ImageSync.lo \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	tools/rbd_mirror/Mirror.lo \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	tools/rbd_mirror/PoolWatcher.lo \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	tools/rbd_mirror/Replayer.lo \
- at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	tools/rbd_mirror/types.lo
+ at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	tools/rbd_mirror/Threads.lo \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	tools/rbd_mirror/types.lo \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	tools/rbd_mirror/image_replayer/BootstrapRequest.lo \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	tools/rbd_mirror/image_replayer/CloseImageRequest.lo \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	tools/rbd_mirror/image_replayer/OpenLocalImageRequest.lo \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	tools/rbd_mirror/image_sync/ImageCopyRequest.lo \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	tools/rbd_mirror/image_sync/ObjectCopyRequest.lo \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	tools/rbd_mirror/image_sync/SnapshotCopyRequest.lo \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	tools/rbd_mirror/image_sync/SyncPointCreateRequest.lo \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	tools/rbd_mirror/image_sync/SyncPointPruneRequest.lo
 librbd_mirror_internal_la_OBJECTS =  \
 	$(am_librbd_mirror_internal_la_OBJECTS)
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE at am_librbd_mirror_internal_la_rpath =
 librbd_mirror_test_la_LIBADD =
 am__librbd_mirror_test_la_SOURCES_DIST =  \
 	test/rbd_mirror/test_ClusterWatcher.cc \
-	test/rbd_mirror/test_PoolWatcher.cc
+	test/rbd_mirror/test_PoolWatcher.cc \
+	test/rbd_mirror/test_ImageReplayer.cc \
+	test/rbd_mirror/test_ImageSync.cc \
+	test/rbd_mirror/test_fixture.cc
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE at am_librbd_mirror_test_la_OBJECTS = test/rbd_mirror/librbd_mirror_test_la-test_ClusterWatcher.lo \
- at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	test/rbd_mirror/librbd_mirror_test_la-test_PoolWatcher.lo
+ at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	test/rbd_mirror/librbd_mirror_test_la-test_PoolWatcher.lo \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	test/rbd_mirror/librbd_mirror_test_la-test_ImageReplayer.lo \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	test/rbd_mirror/librbd_mirror_test_la-test_ImageSync.lo \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	test/rbd_mirror/librbd_mirror_test_la-test_fixture.lo
 librbd_mirror_test_la_OBJECTS = $(am_librbd_mirror_test_la_OBJECTS)
 librbd_mirror_test_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
 	$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \
@@ -2917,7 +3071,7 @@ librbd_test_la_LIBADD =
 am__librbd_test_la_SOURCES_DIST = test/librbd/test_fixture.cc \
 	test/librbd/test_support.cc test/librbd/test_librbd.cc \
 	test/librbd/test_ImageWatcher.cc test/librbd/test_internal.cc \
-	test/librbd/test_ObjectMap.cc \
+	test/librbd/test_mirroring.cc test/librbd/test_ObjectMap.cc \
 	test/librbd/journal/test_Entries.cc \
 	test/librbd/journal/test_Replay.cc
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE at am_librbd_test_la_OBJECTS = test/librbd/librbd_test_la-test_fixture.lo \
@@ -2925,6 +3079,7 @@ am__librbd_test_la_SOURCES_DIST = test/librbd/test_fixture.cc \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	test/librbd/librbd_test_la-test_librbd.lo \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	test/librbd/librbd_test_la-test_ImageWatcher.lo \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	test/librbd/librbd_test_la-test_internal.lo \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	test/librbd/librbd_test_la-test_mirroring.lo \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	test/librbd/librbd_test_la-test_ObjectMap.lo \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	test/librbd/journal/librbd_test_la-test_Entries.lo \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	test/librbd/journal/librbd_test_la-test_Replay.lo
@@ -2949,64 +3104,124 @@ librbd_types_la_LIBADD =
 am_librbd_types_la_OBJECTS = librbd/journal/Types.lo \
 	librbd/WatchNotifyTypes.lo
 librbd_types_la_OBJECTS = $(am_librbd_types_la_OBJECTS)
-librgw_la_LIBADD =
-am__librgw_la_SOURCES_DIST = rgw/librgw.cc rgw/rgw_acl.cc \
-	rgw/rgw_acl_s3.cc rgw/rgw_acl_swift.cc rgw/rgw_client_io.cc \
-	rgw/rgw_fcgi.cc rgw/rgw_xml.cc rgw/rgw_usage.cc \
-	rgw/rgw_json_enc.cc rgw/rgw_xml_enc.cc rgw/rgw_user.cc \
-	rgw/rgw_bucket.cc rgw/rgw_tools.cc rgw/rgw_rados.cc \
-	rgw/rgw_http_client.cc rgw/rgw_rest_client.cc \
-	rgw/rgw_rest_conn.cc rgw/rgw_op.cc rgw/rgw_basic_types.cc \
-	rgw/rgw_common.cc rgw/rgw_cache.cc rgw/rgw_formats.cc \
-	rgw/rgw_log.cc rgw/rgw_multi.cc rgw/rgw_policy_s3.cc \
-	rgw/rgw_gc.cc rgw/rgw_multi_del.cc rgw/rgw_env.cc \
-	rgw/rgw_cors.cc rgw/rgw_cors_s3.cc rgw/rgw_auth_s3.cc \
-	rgw/rgw_metadata.cc rgw/rgw_replica_log.cc rgw/rgw_keystone.cc \
-	rgw/rgw_quota.cc rgw/rgw_dencoder.cc \
-	rgw/rgw_object_expirer_core.cc rgw/rgw_website.cc
- at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE at am_librgw_la_OBJECTS = rgw/librgw_la-librgw.lo \
- at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/librgw_la-rgw_acl.lo \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE at am__DEPENDENCIES_11 = $(LIBRADOS) \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	libcls_rgw_client.la \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	libcls_log_client.la \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	libcls_statelog_client.la \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	libcls_timeindex_client.la \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	libcls_user_client.la \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	libcls_replica_log_client.la \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	libcls_lock_client.la \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	libcls_refcount_client.la \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	libcls_version_client.la
+am__DEPENDENCIES_12 = $(am__DEPENDENCIES_11)
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE at librgw_la_DEPENDENCIES = $(am__DEPENDENCIES_12) \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_1) \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_1) \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	libglobal.la \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_3)
+am__librgw_la_SOURCES_DIST = rgw/rgw_acl.cc rgw/rgw_acl_s3.cc \
+	rgw/rgw_acl_swift.cc rgw/rgw_coroutine.cc rgw/rgw_cr_rados.cc \
+	rgw/rgw_tools.cc rgw/rgw_basic_types.cc rgw/rgw_bucket.cc \
+	rgw/rgw_cache.cc rgw/rgw_client_io.cc rgw/rgw_common.cc \
+	rgw/rgw_cors.cc rgw/rgw_cors_s3.cc rgw/rgw_dencoder.cc \
+	rgw/rgw_env.cc rgw/rgw_fcgi.cc rgw/rgw_formats.cc \
+	rgw/rgw_frontend.cc rgw/rgw_gc.cc rgw/rgw_http_client.cc \
+	rgw/rgw_json_enc.cc rgw/rgw_keystone.cc rgw/rgw_loadgen.cc \
+	rgw/rgw_log.cc rgw/rgw_metadata.cc rgw/rgw_multi.cc \
+	rgw/rgw_multi_del.cc rgw/rgw_auth_s3.cc \
+	rgw/rgw_period_history.cc rgw/rgw_period_puller.cc \
+	rgw/rgw_period_pusher.cc rgw/rgw_realm_reloader.cc \
+	rgw/rgw_realm_watcher.cc rgw/rgw_sync.cc rgw/rgw_data_sync.cc \
+	rgw/rgw_object_expirer_core.cc rgw/rgw_op.cc rgw/rgw_os_lib.cc \
+	rgw/rgw_policy_s3.cc rgw/rgw_process.cc rgw/rgw_quota.cc \
+	rgw/rgw_rados.cc rgw/rgw_replica_log.cc rgw/rgw_request.cc \
+	rgw/rgw_resolve.cc rgw/rgw_rest_bucket.cc rgw/rgw_rest.cc \
+	rgw/rgw_rest_client.cc rgw/rgw_rest_config.cc \
+	rgw/rgw_rest_conn.cc rgw/rgw_rest_log.cc \
+	rgw/rgw_rest_metadata.cc rgw/rgw_rest_opstate.cc \
+	rgw/rgw_rest_realm.cc rgw/rgw_rest_replica_log.cc \
+	rgw/rgw_rest_s3.cc rgw/rgw_rest_swift.cc rgw/rgw_rest_usage.cc \
+	rgw/rgw_rest_user.cc rgw/rgw_swift_auth.cc rgw/rgw_swift.cc \
+	rgw/rgw_usage.cc rgw/rgw_user.cc rgw/rgw_file.cc rgw/librgw.cc \
+	rgw/rgw_xml.cc rgw/rgw_xml_enc.cc rgw/rgw_website.cc \
+	rgw/rgw_ldap.cc
+ at ENABLE_CLIENT_TRUE@@WITH_OPENLDAP_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE at am__objects_40 = rgw/librgw_la-rgw_ldap.lo
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE at am_librgw_la_OBJECTS = rgw/librgw_la-rgw_acl.lo \
 @ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/librgw_la-rgw_acl_s3.lo \
 @ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/librgw_la-rgw_acl_swift.lo \
- at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/librgw_la-rgw_client_io.lo \
- at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/librgw_la-rgw_fcgi.lo \
- at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/librgw_la-rgw_xml.lo \
- at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/librgw_la-rgw_usage.lo \
- at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/librgw_la-rgw_json_enc.lo \
- at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/librgw_la-rgw_xml_enc.lo \
- at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/librgw_la-rgw_user.lo \
- at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/librgw_la-rgw_bucket.lo \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/librgw_la-rgw_coroutine.lo \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/librgw_la-rgw_cr_rados.lo \
 @ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/librgw_la-rgw_tools.lo \
- at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/librgw_la-rgw_rados.lo \
- at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/librgw_la-rgw_http_client.lo \
- at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/librgw_la-rgw_rest_client.lo \
- at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/librgw_la-rgw_rest_conn.lo \
- at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/librgw_la-rgw_op.lo \
 @ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/librgw_la-rgw_basic_types.lo \
- at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/librgw_la-rgw_common.lo \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/librgw_la-rgw_bucket.lo \
 @ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/librgw_la-rgw_cache.lo \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/librgw_la-rgw_client_io.lo \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/librgw_la-rgw_common.lo \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/librgw_la-rgw_cors.lo \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/librgw_la-rgw_cors_s3.lo \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/librgw_la-rgw_dencoder.lo \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/librgw_la-rgw_env.lo \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/librgw_la-rgw_fcgi.lo \
 @ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/librgw_la-rgw_formats.lo \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/librgw_la-rgw_frontend.lo \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/librgw_la-rgw_gc.lo \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/librgw_la-rgw_http_client.lo \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/librgw_la-rgw_json_enc.lo \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/librgw_la-rgw_keystone.lo \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/librgw_la-rgw_loadgen.lo \
 @ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/librgw_la-rgw_log.lo \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/librgw_la-rgw_metadata.lo \
 @ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/librgw_la-rgw_multi.lo \
- at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/librgw_la-rgw_policy_s3.lo \
- at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/librgw_la-rgw_gc.lo \
 @ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/librgw_la-rgw_multi_del.lo \
- at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/librgw_la-rgw_env.lo \
- at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/librgw_la-rgw_cors.lo \
- at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/librgw_la-rgw_cors_s3.lo \
 @ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/librgw_la-rgw_auth_s3.lo \
- at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/librgw_la-rgw_metadata.lo \
- at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/librgw_la-rgw_replica_log.lo \
- at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/librgw_la-rgw_keystone.lo \
- at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/librgw_la-rgw_quota.lo \
- at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/librgw_la-rgw_dencoder.lo \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/librgw_la-rgw_period_history.lo \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/librgw_la-rgw_period_puller.lo \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/librgw_la-rgw_period_pusher.lo \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/librgw_la-rgw_realm_reloader.lo \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/librgw_la-rgw_realm_watcher.lo \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/librgw_la-rgw_sync.lo \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/librgw_la-rgw_data_sync.lo \
 @ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/librgw_la-rgw_object_expirer_core.lo \
- at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/librgw_la-rgw_website.lo
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/librgw_la-rgw_op.lo \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/librgw_la-rgw_os_lib.lo \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/librgw_la-rgw_policy_s3.lo \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/librgw_la-rgw_process.lo \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/librgw_la-rgw_quota.lo \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/librgw_la-rgw_rados.lo \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/librgw_la-rgw_replica_log.lo \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/librgw_la-rgw_request.lo \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/librgw_la-rgw_resolve.lo \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/librgw_la-rgw_rest_bucket.lo \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/librgw_la-rgw_rest.lo \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/librgw_la-rgw_rest_client.lo \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/librgw_la-rgw_rest_config.lo \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/librgw_la-rgw_rest_conn.lo \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/librgw_la-rgw_rest_log.lo \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/librgw_la-rgw_rest_metadata.lo \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/librgw_la-rgw_rest_opstate.lo \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/librgw_la-rgw_rest_realm.lo \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/librgw_la-rgw_rest_replica_log.lo \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/librgw_la-rgw_rest_s3.lo \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/librgw_la-rgw_rest_swift.lo \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/librgw_la-rgw_rest_usage.lo \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/librgw_la-rgw_rest_user.lo \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/librgw_la-rgw_swift_auth.lo \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/librgw_la-rgw_swift.lo \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/librgw_la-rgw_usage.lo \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/librgw_la-rgw_user.lo \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/librgw_la-rgw_file.lo \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/librgw_la-librgw.lo \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/librgw_la-rgw_xml.lo \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/librgw_la-rgw_xml_enc.lo \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/librgw_la-rgw_website.lo \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	$(am__objects_40)
 librgw_la_OBJECTS = $(am_librgw_la_OBJECTS)
 librgw_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \
 	$(LIBTOOLFLAGS) --mode=link $(CXXLD) $(librgw_la_CXXFLAGS) \
-	$(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
- at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE at am_librgw_la_rpath =
+	$(CXXFLAGS) $(librgw_la_LDFLAGS) $(LDFLAGS) -o $@
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE at am_librgw_la_rpath = -rpath \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	$(libdir)
 libsecret_la_DEPENDENCIES = $(am__DEPENDENCIES_1)
 am_libsecret_la_OBJECTS = common/secret.lo
 libsecret_la_OBJECTS = $(am_libsecret_la_OBJECTS)
@@ -3064,11 +3279,13 @@ libsystest_la_OBJECTS = $(am_libsystest_la_OBJECTS)
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@	ceph_test_rados_api_misc$(EXEEXT) \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@	ceph_test_rados_api_tier$(EXEEXT) \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@	ceph_test_rados_api_lock$(EXEEXT) \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@	ceph_test_rados_api_tmap_migrate$(EXEEXT) \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@	ceph_test_stress_watch$(EXEEXT)
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE at am__EXEEXT_9 = ceph_smalliobenchrbd$(EXEEXT) \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	ceph_test_librbd$(EXEEXT) \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	ceph_test_librbd_api$(EXEEXT) \
- at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	ceph_test_rbd_mirror$(EXEEXT)
+ at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	ceph_test_rbd_mirror$(EXEEXT) \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	ceph_test_rbd_mirror_image_replay$(EXEEXT)
 @ENABLE_CLIENT_TRUE@@LINUX_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE at am__EXEEXT_10 = ceph_test_librbd_fsx$(EXEEXT)
 @ENABLE_CLIENT_TRUE@@WITH_RADOSSTRIPER_TRUE@@WITH_RADOS_TRUE at am__EXEEXT_11 = ceph_test_rados_striper_api_io$(EXEEXT) \
 @ENABLE_CLIENT_TRUE@@WITH_RADOSSTRIPER_TRUE@@WITH_RADOS_TRUE@	ceph_test_rados_striper_api_aio$(EXEEXT) \
@@ -3079,11 +3296,17 @@ libsystest_la_OBJECTS = $(am_libsystest_la_OBJECTS)
 @ENABLE_CLIENT_TRUE@@WITH_BUILD_TESTS_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE at am__EXEEXT_14 = test_build_librgw$(EXEEXT)
 @ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE at am__EXEEXT_15 = ceph_test_cors$(EXEEXT) \
 @ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	ceph_test_rgw_manifest$(EXEEXT) \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	ceph_test_rgw_period_history$(EXEEXT) \
 @ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	ceph_test_rgw_obj$(EXEEXT) \
 @ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	ceph_test_cls_rgw_meta$(EXEEXT) \
 @ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	ceph_test_cls_rgw_log$(EXEEXT) \
 @ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	ceph_test_cls_rgw_opstate$(EXEEXT) \
- at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	ceph_test_cls_rgw$(EXEEXT)
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	ceph_test_cls_rgw$(EXEEXT) \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	librgw_file$(EXEEXT) \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	librgw_file_cd$(EXEEXT) \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	librgw_file_gp$(EXEEXT) \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	librgw_file_aw$(EXEEXT) \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	librgw_file_nfsns$(EXEEXT)
 @ENABLE_SERVER_TRUE at am__EXEEXT_16 = ceph_test_async_driver$(EXEEXT) \
 @ENABLE_SERVER_TRUE@	ceph_test_msgr$(EXEEXT) \
 @ENABLE_SERVER_TRUE@	ceph_test_trans$(EXEEXT) \
@@ -3137,34 +3360,35 @@ am__EXEEXT_27 = $(am__EXEEXT_1) $(am__EXEEXT_2) $(am__EXEEXT_3) \
 @ENABLE_SERVER_TRUE@@WITH_LIBAIO_TRUE at am__EXEEXT_29 = ceph-bluefs-tool$(EXEEXT)
 @ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE at am__EXEEXT_30 = radosgw$(EXEEXT) \
 @ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	radosgw-admin$(EXEEXT) \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	radosgw-token$(EXEEXT) \
 @ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	radosgw-object-expirer$(EXEEXT)
 @ENABLE_CLIENT_TRUE@@LINUX_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE at am__EXEEXT_31 = rbd-replay$(EXEEXT)
 @ENABLE_CLIENT_TRUE@@WITH_BABELTRACE_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE at am__EXEEXT_32 = rbd-replay-prep$(EXEEXT)
 @ENABLE_CLIENT_TRUE at am__EXEEXT_33 = ceph-dencoder$(EXEEXT)
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE at am__EXEEXT_34 = rados$(EXEEXT)
- at ENABLE_CLIENT_TRUE@@LINUX_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE at am__EXEEXT_35 = rbd$(EXEEXT) \
- at ENABLE_CLIENT_TRUE@@LINUX_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	rbd-nbd$(EXEEXT)
- at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE at am__EXEEXT_36 = rbd-mirror$(EXEEXT)
- at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE at am__EXEEXT_37 = ceph-objectstore-tool$(EXEEXT)
- at ENABLE_CLIENT_TRUE@@ENABLE_SERVER_TRUE@@WITH_MDS_TRUE@@WITH_RADOS_TRUE at am__EXEEXT_38 = cephfs-journal-tool$(EXEEXT) \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE at am__EXEEXT_35 = rbd$(EXEEXT)
+ at ENABLE_CLIENT_TRUE@@LINUX_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE at am__EXEEXT_36 = rbd-nbd$(EXEEXT)
+ at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE at am__EXEEXT_37 = rbd-mirror$(EXEEXT)
+ at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE at am__EXEEXT_38 = ceph-objectstore-tool$(EXEEXT)
+ at ENABLE_CLIENT_TRUE@@ENABLE_SERVER_TRUE@@WITH_MDS_TRUE@@WITH_RADOS_TRUE at am__EXEEXT_39 = cephfs-journal-tool$(EXEEXT) \
 @ENABLE_CLIENT_TRUE@@ENABLE_SERVER_TRUE@@WITH_MDS_TRUE@@WITH_RADOS_TRUE@	cephfs-table-tool$(EXEEXT) \
 @ENABLE_CLIENT_TRUE@@ENABLE_SERVER_TRUE@@WITH_MDS_TRUE@@WITH_RADOS_TRUE@	cephfs-data-scan$(EXEEXT)
- at ENABLE_CLIENT_TRUE@am__EXEEXT_39 = ceph-syn$(EXEEXT)
- at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE at am__EXEEXT_40 =  \
+ at ENABLE_CLIENT_TRUE@am__EXEEXT_40 = ceph-syn$(EXEEXT)
+ at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE at am__EXEEXT_41 =  \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@	librados-config$(EXEEXT)
- at ENABLE_CLIENT_TRUE@@WITH_FUSE_TRUE@@WITH_RADOS_TRUE at am__EXEEXT_41 = ceph-fuse$(EXEEXT)
- at ENABLE_CLIENT_TRUE@@WITH_FUSE_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE at am__EXEEXT_42 = rbd-fuse$(EXEEXT)
- at ENABLE_CLIENT_TRUE@@WITH_CEPHFS_TRUE@@WITH_RADOS_TRUE at am__EXEEXT_43 = cephfs$(EXEEXT)
- at ENABLE_SERVER_TRUE@@WITH_MON_TRUE at am__EXEEXT_44 = ceph-mon$(EXEEXT)
- at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE at am__EXEEXT_45 = ceph-osd$(EXEEXT)
- at ENABLE_SERVER_TRUE@@WITH_MDS_TRUE at am__EXEEXT_46 = ceph-mds$(EXEEXT)
- at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE at am__EXEEXT_47 = unittest_erasure_code_plugin$(EXEEXT) \
+ at ENABLE_CLIENT_TRUE@@WITH_FUSE_TRUE@@WITH_RADOS_TRUE at am__EXEEXT_42 = ceph-fuse$(EXEEXT)
+ at ENABLE_CLIENT_TRUE@@WITH_FUSE_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE at am__EXEEXT_43 = rbd-fuse$(EXEEXT)
+ at ENABLE_CLIENT_TRUE@@WITH_CEPHFS_TRUE@@WITH_RADOS_TRUE at am__EXEEXT_44 = cephfs$(EXEEXT)
+ at ENABLE_SERVER_TRUE@@WITH_MON_TRUE at am__EXEEXT_45 = ceph-mon$(EXEEXT)
+ at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE at am__EXEEXT_46 = ceph-osd$(EXEEXT)
+ at ENABLE_SERVER_TRUE@@WITH_MDS_TRUE at am__EXEEXT_47 = ceph-mds$(EXEEXT)
+ at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE at am__EXEEXT_48 = unittest_erasure_code_plugin$(EXEEXT) \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	unittest_erasure_code$(EXEEXT) \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	unittest_erasure_code_jerasure$(EXEEXT) \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	unittest_erasure_code_plugin_jerasure$(EXEEXT)
- at ENABLE_SERVER_TRUE@@WITH_BETTER_YASM_ELF64_TRUE@@WITH_OSD_TRUE at am__EXEEXT_48 = unittest_erasure_code_isa$(EXEEXT) \
+ at ENABLE_SERVER_TRUE@@WITH_BETTER_YASM_ELF64_TRUE@@WITH_OSD_TRUE at am__EXEEXT_49 = unittest_erasure_code_isa$(EXEEXT) \
 @ENABLE_SERVER_TRUE@@WITH_BETTER_YASM_ELF64_TRUE@@WITH_OSD_TRUE@	unittest_erasure_code_plugin_isa$(EXEEXT)
- at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE at am__EXEEXT_49 = unittest_erasure_code_lrc$(EXEEXT) \
+ at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE at am__EXEEXT_50 = unittest_erasure_code_lrc$(EXEEXT) \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	unittest_erasure_code_plugin_lrc$(EXEEXT) \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	unittest_erasure_code_shec$(EXEEXT) \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	unittest_erasure_code_shec_all$(EXEEXT) \
@@ -3177,39 +3401,39 @@ am__EXEEXT_27 = $(am__EXEEXT_1) $(am__EXEEXT_2) $(am__EXEEXT_3) \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	unittest_compression_plugin_snappy$(EXEEXT) \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	unittest_compression_zlib$(EXEEXT) \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	unittest_compression_plugin_zlib$(EXEEXT)
- at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE at am__EXEEXT_50 = unittest_librados$(EXEEXT) \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE at am__EXEEXT_51 = unittest_librados$(EXEEXT) \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@	unittest_librados_config$(EXEEXT) \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@	unittest_journal$(EXEEXT)
- at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE at am__EXEEXT_51 = unittest_rbd_replay$(EXEEXT)
- at ENABLE_CLIENT_TRUE@@WITH_CEPHFS_TRUE@@WITH_RADOS_TRUE at am__EXEEXT_52 = unittest_encoding$(EXEEXT) \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE at am__EXEEXT_52 = unittest_rbd_replay$(EXEEXT)
+ at ENABLE_CLIENT_TRUE@@WITH_CEPHFS_TRUE@@WITH_RADOS_TRUE at am__EXEEXT_53 = unittest_encoding$(EXEEXT) \
 @ENABLE_CLIENT_TRUE@@WITH_CEPHFS_TRUE@@WITH_RADOS_TRUE@	unittest_base64$(EXEEXT) \
 @ENABLE_CLIENT_TRUE@@WITH_CEPHFS_TRUE@@WITH_RADOS_TRUE@	unittest_run_cmd$(EXEEXT) \
 @ENABLE_CLIENT_TRUE@@WITH_CEPHFS_TRUE@@WITH_RADOS_TRUE@	unittest_simple_spin$(EXEEXT) \
 @ENABLE_CLIENT_TRUE@@WITH_CEPHFS_TRUE@@WITH_RADOS_TRUE@	unittest_libcephfs_config$(EXEEXT)
- at ENABLE_SERVER_TRUE@@LINUX_TRUE at am__EXEEXT_53 =  \
+ at ENABLE_SERVER_TRUE@@LINUX_TRUE at am__EXEEXT_54 =  \
 @ENABLE_SERVER_TRUE@@LINUX_TRUE@	unittest_bluefs$(EXEEXT) \
 @ENABLE_SERVER_TRUE@@LINUX_TRUE@	unittest_bluestore_types$(EXEEXT)
- at ENABLE_SERVER_TRUE@am__EXEEXT_54 = unittest_transaction$(EXEEXT)
- at ENABLE_SERVER_TRUE@@WITH_MON_TRUE at am__EXEEXT_55 = unittest_mon_moncap$(EXEEXT) \
+ at ENABLE_SERVER_TRUE@am__EXEEXT_55 = unittest_transaction$(EXEEXT)
+ at ENABLE_SERVER_TRUE@@WITH_MON_TRUE at am__EXEEXT_56 = unittest_mon_moncap$(EXEEXT) \
 @ENABLE_SERVER_TRUE@@WITH_MON_TRUE@	unittest_mon_pgmap$(EXEEXT)
- at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE at am__EXEEXT_56 = unittest_ecbackend$(EXEEXT) \
+ at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE at am__EXEEXT_57 = unittest_ecbackend$(EXEEXT) \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	unittest_osdscrub$(EXEEXT) \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	unittest_pglog$(EXEEXT) \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	unittest_hitset$(EXEEXT) \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	unittest_osd_osdcap$(EXEEXT) \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	unittest_pageset$(EXEEXT)
- at ENABLE_SERVER_TRUE@@WITH_SLIBROCKSDB_TRUE at am__EXEEXT_57 = unittest_rocksdb_option_static$(EXEEXT)
- at ENABLE_SERVER_TRUE@@WITH_DLIBROCKSDB_TRUE at am__EXEEXT_58 = unittest_rocksdb_option$(EXEEXT)
- at ENABLE_SERVER_TRUE@am__EXEEXT_59 = unittest_chain_xattr$(EXEEXT) \
+ at ENABLE_SERVER_TRUE@@WITH_SLIBROCKSDB_TRUE at am__EXEEXT_58 = unittest_rocksdb_option_static$(EXEEXT)
+ at ENABLE_SERVER_TRUE@@WITH_DLIBROCKSDB_TRUE at am__EXEEXT_59 = unittest_rocksdb_option$(EXEEXT)
+ at ENABLE_SERVER_TRUE@am__EXEEXT_60 = unittest_chain_xattr$(EXEEXT) \
 @ENABLE_SERVER_TRUE@	unittest_lfnindex$(EXEEXT)
- at ENABLE_SERVER_TRUE@@WITH_MDS_TRUE at am__EXEEXT_60 = unittest_mds_authcap$(EXEEXT)
- at LINUX_TRUE@am__EXEEXT_61 = unittest_blkdev$(EXEEXT)
-am__EXEEXT_62 = $(am__EXEEXT_47) $(am__EXEEXT_48) $(am__EXEEXT_49) \
-	$(am__EXEEXT_50) $(am__EXEEXT_51) $(am__EXEEXT_52) \
-	$(am__EXEEXT_53) $(am__EXEEXT_54) $(am__EXEEXT_55) \
-	$(am__EXEEXT_56) $(am__EXEEXT_57) $(am__EXEEXT_58) \
-	$(am__EXEEXT_59) $(am__EXEEXT_60) unittest_addrs$(EXEEXT) \
-	$(am__EXEEXT_61) unittest_bloom_filter$(EXEEXT) \
+ at ENABLE_SERVER_TRUE@@WITH_MDS_TRUE at am__EXEEXT_61 = unittest_mds_authcap$(EXEEXT)
+ at LINUX_TRUE@am__EXEEXT_62 = unittest_blkdev$(EXEEXT)
+am__EXEEXT_63 = $(am__EXEEXT_48) $(am__EXEEXT_49) $(am__EXEEXT_50) \
+	$(am__EXEEXT_51) $(am__EXEEXT_52) $(am__EXEEXT_53) \
+	$(am__EXEEXT_54) $(am__EXEEXT_55) $(am__EXEEXT_56) \
+	$(am__EXEEXT_57) $(am__EXEEXT_58) $(am__EXEEXT_59) \
+	$(am__EXEEXT_60) $(am__EXEEXT_61) unittest_addrs$(EXEEXT) \
+	$(am__EXEEXT_62) unittest_bloom_filter$(EXEEXT) \
 	unittest_histogram$(EXEEXT) \
 	unittest_prioritized_queue$(EXEEXT) \
 	unittest_weighted_priority_queue$(EXEEXT) \
@@ -3241,16 +3465,16 @@ am__EXEEXT_62 = $(am__EXEEXT_47) $(am__EXEEXT_48) $(am__EXEEXT_49) \
 	unittest_texttable$(EXEEXT) unittest_on_exit$(EXEEXT) \
 	unittest_readahead$(EXEEXT) unittest_tableformatter$(EXEEXT) \
 	unittest_bit_vector$(EXEEXT) unittest_interval_set$(EXEEXT)
- at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE at am__EXEEXT_63 = unittest_librbd$(EXEEXT) \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE at am__EXEEXT_64 = unittest_librbd$(EXEEXT) \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	unittest_rbd_mirror$(EXEEXT)
- at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE at am__EXEEXT_64 = ceph_erasure_code_non_regression$(EXEEXT)
- at ENABLE_SERVER_TRUE@@ENABLE_XIO_TRUE at am__EXEEXT_65 =  \
+ at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE at am__EXEEXT_65 = ceph_erasure_code_non_regression$(EXEEXT)
+ at ENABLE_SERVER_TRUE@@ENABLE_XIO_TRUE at am__EXEEXT_66 =  \
 @ENABLE_SERVER_TRUE@@ENABLE_XIO_TRUE@	simple_server$(EXEEXT) \
 @ENABLE_SERVER_TRUE@@ENABLE_XIO_TRUE@	simple_client$(EXEEXT) \
 @ENABLE_SERVER_TRUE@@ENABLE_XIO_TRUE@	xio_server$(EXEEXT) \
 @ENABLE_SERVER_TRUE@@ENABLE_XIO_TRUE@	xio_client$(EXEEXT)
- at ENABLE_SERVER_TRUE@@WITH_MON_TRUE at am__EXEEXT_66 = get_command_descriptions$(EXEEXT)
- at ENABLE_SERVER_TRUE@@LINUX_TRUE at am__EXEEXT_67 = mount.ceph$(EXEEXT)
+ at ENABLE_SERVER_TRUE@@WITH_MON_TRUE at am__EXEEXT_67 = get_command_descriptions$(EXEEXT)
+ at ENABLE_SERVER_TRUE@@LINUX_TRUE at am__EXEEXT_68 = mount.ceph$(EXEEXT)
 PROGRAMS = $(bin_PROGRAMS) $(noinst_PROGRAMS) $(sbin_PROGRAMS) \
 	$(su_sbin_PROGRAMS)
 am_ceph_authtool_OBJECTS = tools/ceph_authtool.$(OBJEXT)
@@ -3259,16 +3483,16 @@ ceph_authtool_DEPENDENCIES = $(am__DEPENDENCIES_10)
 am__ceph_bluefs_tool_SOURCES_DIST = os/bluestore/bluefs_tool.cc
 @ENABLE_SERVER_TRUE@@WITH_LIBAIO_TRUE at am_ceph_bluefs_tool_OBJECTS = os/bluestore/bluefs_tool.$(OBJEXT)
 ceph_bluefs_tool_OBJECTS = $(am_ceph_bluefs_tool_OBJECTS)
- at WITH_LIBZFS_TRUE@am__DEPENDENCIES_11 = libos_zfs.a
- at WITH_SPDK_TRUE@am__DEPENDENCIES_12 = $(LIBSPDK_LIBS) \
+ at WITH_LIBZFS_TRUE@am__DEPENDENCIES_13 = libos_zfs.a
+ at WITH_SPDK_TRUE@am__DEPENDENCIES_14 = $(LIBSPDK_LIBS) \
 @WITH_SPDK_TRUE@	$(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1)
-am__DEPENDENCIES_13 = libkv.a $(am__append_27) $(am__DEPENDENCIES_1) \
+am__DEPENDENCIES_15 = libkv.a $(am__append_27) $(am__DEPENDENCIES_1) \
 	$(am__DEPENDENCIES_1)
-am__DEPENDENCIES_14 = libos.a $(am__DEPENDENCIES_1) \
-	$(am__DEPENDENCIES_11) $(am__DEPENDENCIES_12) $(LIBOS_TYPES) \
-	$(am__DEPENDENCIES_13) $(am__DEPENDENCIES_1)
+am__DEPENDENCIES_16 = libos.a $(am__DEPENDENCIES_1) \
+	$(am__DEPENDENCIES_13) $(am__DEPENDENCIES_14) $(LIBOS_TYPES) \
+	$(am__DEPENDENCIES_15) $(am__DEPENDENCIES_1)
 @ENABLE_SERVER_TRUE@@WITH_LIBAIO_TRUE at ceph_bluefs_tool_DEPENDENCIES =  \
- at ENABLE_SERVER_TRUE@@WITH_LIBAIO_TRUE@	$(am__DEPENDENCIES_14) \
+ at ENABLE_SERVER_TRUE@@WITH_LIBAIO_TRUE@	$(am__DEPENDENCIES_16) \
 @ENABLE_SERVER_TRUE@@WITH_LIBAIO_TRUE@	$(am__DEPENDENCIES_10)
 am__ceph_client_debug_SOURCES_DIST = tools/ceph-client-debug.cc
 @ENABLE_CLIENT_TRUE@@WITH_CEPHFS_TRUE@@WITH_RADOS_TRUE at am_ceph_client_debug_OBJECTS = tools/ceph-client-debug.$(OBJEXT)
@@ -3286,15 +3510,15 @@ am__ceph_dencoder_SOURCES_DIST = test/encoding/ceph_dencoder.cc \
 	mds/Mutation.cc mds/MDCache.cc mds/RecoveryQueue.cc \
 	mds/StrayManager.cc mds/Locker.cc mds/Migrator.cc \
 	mds/MDBalancer.cc mds/CDentry.cc mds/CDir.cc mds/CInode.cc \
-	mds/LogEvent.cc mds/MDSTable.cc mds/InoTable.cc \
-	mds/JournalPointer.cc mds/MDSTableClient.cc \
+	mds/DamageTable.cc mds/LogEvent.cc mds/MDSTable.cc \
+	mds/InoTable.cc mds/JournalPointer.cc mds/MDSTableClient.cc \
 	mds/MDSTableServer.cc mds/SimpleLock.cc mds/ScrubStack.cc \
 	mds/SnapRealm.cc mds/SnapServer.cc mds/snap.cc \
 	mds/SessionMap.cc mds/MDSContext.cc mds/MDSAuthCaps.cc \
 	mds/MDLog.cc perfglue/disabled_heap_profiler.cc \
 	perfglue/disabled_stubs.cc rgw/rgw_dencoder.cc rgw/rgw_acl.cc \
 	rgw/rgw_basic_types.cc rgw/rgw_common.cc rgw/rgw_env.cc \
-	rgw/rgw_json_enc.cc
+	rgw/rgw_json_enc.cc rgw/rgw_keystone.cc
 am__objects_41 = mds/ceph_dencoder-Capability.$(OBJEXT) \
 	mds/ceph_dencoder-MDSDaemon.$(OBJEXT) \
 	mds/ceph_dencoder-MDSRank.$(OBJEXT) \
@@ -3312,6 +3536,7 @@ am__objects_41 = mds/ceph_dencoder-Capability.$(OBJEXT) \
 	mds/ceph_dencoder-CDentry.$(OBJEXT) \
 	mds/ceph_dencoder-CDir.$(OBJEXT) \
 	mds/ceph_dencoder-CInode.$(OBJEXT) \
+	mds/ceph_dencoder-DamageTable.$(OBJEXT) \
 	mds/ceph_dencoder-LogEvent.$(OBJEXT) \
 	mds/ceph_dencoder-MDSTable.$(OBJEXT) \
 	mds/ceph_dencoder-InoTable.$(OBJEXT) \
@@ -3334,7 +3559,8 @@ am__objects_41 = mds/ceph_dencoder-Capability.$(OBJEXT) \
 @ENABLE_CLIENT_TRUE@	rgw/ceph_dencoder-rgw_basic_types.$(OBJEXT) \
 @ENABLE_CLIENT_TRUE@	rgw/ceph_dencoder-rgw_common.$(OBJEXT) \
 @ENABLE_CLIENT_TRUE@	rgw/ceph_dencoder-rgw_env.$(OBJEXT) \
- at ENABLE_CLIENT_TRUE@	rgw/ceph_dencoder-rgw_json_enc.$(OBJEXT)
+ at ENABLE_CLIENT_TRUE@	rgw/ceph_dencoder-rgw_json_enc.$(OBJEXT) \
+ at ENABLE_CLIENT_TRUE@	rgw/ceph_dencoder-rgw_keystone.$(OBJEXT)
 am__objects_44 = $(am__objects_42) \
 	perfglue/ceph_dencoder-disabled_heap_profiler.$(OBJEXT) \
 	perfglue/ceph_dencoder-disabled_stubs.$(OBJEXT) \
@@ -3342,9 +3568,27 @@ am__objects_44 = $(am__objects_42) \
 @ENABLE_CLIENT_TRUE at am_ceph_dencoder_OBJECTS = test/encoding/ceph_dencoder-ceph_dencoder.$(OBJEXT) \
 @ENABLE_CLIENT_TRUE@	$(am__objects_44)
 ceph_dencoder_OBJECTS = $(am_ceph_dencoder_OBJECTS)
- at ENABLE_CLIENT_TRUE@ceph_dencoder_DEPENDENCIES = $(LIBRBD_TYPES) \
- at ENABLE_CLIENT_TRUE@	$(LIBOSD_TYPES) $(LIBOS_TYPES) \
- at ENABLE_CLIENT_TRUE@	$(LIBMON_TYPES) $(DENCODER_DEPS) \
+am__DEPENDENCIES_17 = librgw.la $(am__DEPENDENCIES_1)
+ at ENABLE_CLIENT_TRUE@am__DEPENDENCIES_18 = libcls_version_client.la \
+ at ENABLE_CLIENT_TRUE@	libcls_log_client.la \
+ at ENABLE_CLIENT_TRUE@	libcls_refcount_client.la \
+ at ENABLE_CLIENT_TRUE@	libcls_user_client.la \
+ at ENABLE_CLIENT_TRUE@	libcls_timeindex_client.la \
+ at ENABLE_CLIENT_TRUE@	libcls_statelog_client.la \
+ at ENABLE_CLIENT_TRUE@	libcls_lock_client.la \
+ at ENABLE_CLIENT_TRUE@	libcls_refcount_client.la \
+ at ENABLE_CLIENT_TRUE@	libcls_replica_log_client.la \
+ at ENABLE_CLIENT_TRUE@	libcls_rgw_client.la libcls_rbd_client.la \
+ at ENABLE_CLIENT_TRUE@	libcls_user_client.la \
+ at ENABLE_CLIENT_TRUE@	libcls_numops_client.la \
+ at ENABLE_CLIENT_TRUE@	libcls_journal_client.la
+am__DEPENDENCIES_19 = $(am__append_48) $(am__append_137) \
+	$(am__DEPENDENCIES_18) $(am__append_159)
+ at ENABLE_CLIENT_TRUE@ceph_dencoder_DEPENDENCIES =  \
+ at ENABLE_CLIENT_TRUE@	$(am__DEPENDENCIES_17) $(LIBRADOS) \
+ at ENABLE_CLIENT_TRUE@	$(LIBRBD_TYPES) $(LIBOSD_TYPES) \
+ at ENABLE_CLIENT_TRUE@	$(LIBOS_TYPES) $(LIBMON_TYPES) \
+ at ENABLE_CLIENT_TRUE@	$(am__DEPENDENCIES_19) \
 @ENABLE_CLIENT_TRUE@	$(am__DEPENDENCIES_10)
 ceph_dencoder_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
 	$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \
@@ -3359,7 +3603,7 @@ am__ceph_kvstore_tool_SOURCES_DIST = tools/ceph_kvstore_tool.cc
 @ENABLE_SERVER_TRUE at am_ceph_kvstore_tool_OBJECTS = tools/ceph_kvstore_tool-ceph_kvstore_tool.$(OBJEXT)
 ceph_kvstore_tool_OBJECTS = $(am_ceph_kvstore_tool_OBJECTS)
 @ENABLE_SERVER_TRUE at ceph_kvstore_tool_DEPENDENCIES =  \
- at ENABLE_SERVER_TRUE@	$(am__DEPENDENCIES_14) \
+ at ENABLE_SERVER_TRUE@	$(am__DEPENDENCIES_16) \
 @ENABLE_SERVER_TRUE@	$(am__DEPENDENCIES_10)
 ceph_kvstore_tool_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
 	$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \
@@ -3369,12 +3613,12 @@ am__ceph_mds_SOURCES_DIST = ceph_mds.cc
 @ENABLE_SERVER_TRUE@@WITH_MDS_TRUE at am_ceph_mds_OBJECTS =  \
 @ENABLE_SERVER_TRUE@@WITH_MDS_TRUE@	ceph_mds.$(OBJEXT)
 ceph_mds_OBJECTS = $(am_ceph_mds_OBJECTS)
-am__DEPENDENCIES_15 = libperfglue.la $(am__DEPENDENCIES_1) \
+am__DEPENDENCIES_20 = libperfglue.la $(am__DEPENDENCIES_1) \
 	$(am__DEPENDENCIES_1)
-am__DEPENDENCIES_16 = libmds.la $(am__DEPENDENCIES_1) \
-	$(am__DEPENDENCIES_15)
+am__DEPENDENCIES_21 = libmds.la $(am__DEPENDENCIES_1) \
+	$(am__DEPENDENCIES_20)
 @ENABLE_SERVER_TRUE@@WITH_MDS_TRUE at ceph_mds_DEPENDENCIES =  \
- at ENABLE_SERVER_TRUE@@WITH_MDS_TRUE@	$(am__DEPENDENCIES_16) \
+ at ENABLE_SERVER_TRUE@@WITH_MDS_TRUE@	$(am__DEPENDENCIES_21) \
 @ENABLE_SERVER_TRUE@@WITH_MDS_TRUE@	$(LIBOSDC) \
 @ENABLE_SERVER_TRUE@@WITH_MDS_TRUE@	$(am__DEPENDENCIES_10) \
 @ENABLE_SERVER_TRUE@@WITH_MDS_TRUE@	$(am__DEPENDENCIES_4)
@@ -3382,11 +3626,11 @@ am__ceph_mon_SOURCES_DIST = ceph_mon.cc
 @ENABLE_SERVER_TRUE@@WITH_MON_TRUE at am_ceph_mon_OBJECTS =  \
 @ENABLE_SERVER_TRUE@@WITH_MON_TRUE@	ceph_mon.$(OBJEXT)
 ceph_mon_OBJECTS = $(am_ceph_mon_OBJECTS)
-am__DEPENDENCIES_17 = libmon.a $(am__DEPENDENCIES_1) \
-	$(am__DEPENDENCIES_15) $(LIBMON_TYPES)
+am__DEPENDENCIES_22 = libmon.a $(am__DEPENDENCIES_1) \
+	$(am__DEPENDENCIES_20) $(LIBMON_TYPES)
 @ENABLE_SERVER_TRUE@@WITH_MON_TRUE at ceph_mon_DEPENDENCIES =  \
- at ENABLE_SERVER_TRUE@@WITH_MON_TRUE@	$(am__DEPENDENCIES_17) \
- at ENABLE_SERVER_TRUE@@WITH_MON_TRUE@	$(am__DEPENDENCIES_14) \
+ at ENABLE_SERVER_TRUE@@WITH_MON_TRUE@	$(am__DEPENDENCIES_22) \
+ at ENABLE_SERVER_TRUE@@WITH_MON_TRUE@	$(am__DEPENDENCIES_16) \
 @ENABLE_SERVER_TRUE@@WITH_MON_TRUE@	$(am__DEPENDENCIES_10) \
 @ENABLE_SERVER_TRUE@@WITH_MON_TRUE@	$(am__DEPENDENCIES_4) \
 @ENABLE_SERVER_TRUE@@WITH_MON_TRUE@	$(LIBAUTH) \
@@ -3397,7 +3641,7 @@ am__ceph_monstore_tool_SOURCES_DIST = tools/ceph_monstore_tool.cc
 @ENABLE_SERVER_TRUE@	tools/ceph_monstore_tool.$(OBJEXT)
 ceph_monstore_tool_OBJECTS = $(am_ceph_monstore_tool_OBJECTS)
 @ENABLE_SERVER_TRUE at ceph_monstore_tool_DEPENDENCIES =  \
- at ENABLE_SERVER_TRUE@	$(am__DEPENDENCIES_14) \
+ at ENABLE_SERVER_TRUE@	$(am__DEPENDENCIES_16) \
 @ENABLE_SERVER_TRUE@	$(am__DEPENDENCIES_10) \
 @ENABLE_SERVER_TRUE@	$(am__DEPENDENCIES_1)
 am__ceph_objectstore_tool_SOURCES_DIST =  \
@@ -3405,12 +3649,12 @@ am__ceph_objectstore_tool_SOURCES_DIST =  \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE at am_ceph_objectstore_tool_OBJECTS = tools/ceph_objectstore_tool.$(OBJEXT) \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	tools/RadosDump.$(OBJEXT)
 ceph_objectstore_tool_OBJECTS = $(am_ceph_objectstore_tool_OBJECTS)
-am__DEPENDENCIES_18 = libosd.a $(am__DEPENDENCIES_1) $(LIBOSDC) \
-	$(am__DEPENDENCIES_14) $(am__DEPENDENCIES_15) $(LIBOSD_TYPES) \
+am__DEPENDENCIES_23 = libosd.a $(am__DEPENDENCIES_1) $(LIBOSDC) \
+	$(am__DEPENDENCIES_16) $(am__DEPENDENCIES_20) $(LIBOSD_TYPES) \
 	$(LIBOS_TYPES)
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE at ceph_objectstore_tool_DEPENDENCIES =  \
- at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__DEPENDENCIES_18) \
- at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__DEPENDENCIES_14) \
+ at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__DEPENDENCIES_23) \
+ at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__DEPENDENCIES_16) \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__DEPENDENCIES_10) \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__DEPENDENCIES_1) \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__DEPENDENCIES_1)
@@ -3419,10 +3663,10 @@ am__ceph_osd_SOURCES_DIST = ceph_osd.cc
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	ceph_osd.$(OBJEXT)
 ceph_osd_OBJECTS = $(am_ceph_osd_OBJECTS)
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE at ceph_osd_DEPENDENCIES = $(LIBOSDC) \
- at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__DEPENDENCIES_18) \
+ at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__DEPENDENCIES_23) \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(LIBOSD_TYPES) \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(LIBOS_TYPES) \
- at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__DEPENDENCIES_14) \
+ at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__DEPENDENCIES_16) \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__DEPENDENCIES_10) \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__DEPENDENCIES_4) \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__DEPENDENCIES_1)
@@ -3431,7 +3675,7 @@ am__ceph_osdomap_tool_SOURCES_DIST = tools/ceph_osdomap_tool.cc
 @ENABLE_SERVER_TRUE@	tools/ceph_osdomap_tool.$(OBJEXT)
 ceph_osdomap_tool_OBJECTS = $(am_ceph_osdomap_tool_OBJECTS)
 @ENABLE_SERVER_TRUE at ceph_osdomap_tool_DEPENDENCIES =  \
- at ENABLE_SERVER_TRUE@	$(am__DEPENDENCIES_14) \
+ at ENABLE_SERVER_TRUE@	$(am__DEPENDENCIES_16) \
 @ENABLE_SERVER_TRUE@	$(am__DEPENDENCIES_10) \
 @ENABLE_SERVER_TRUE@	$(am__DEPENDENCIES_1)
 am__ceph_syn_SOURCES_DIST = ceph_syn.cc client/SyntheticClient.cc
@@ -3448,7 +3692,7 @@ am__ceph_erasure_code_SOURCES_DIST =  \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE at am_ceph_erasure_code_OBJECTS = test/erasure-code/ceph_erasure_code.$(OBJEXT)
 ceph_erasure_code_OBJECTS = $(am_ceph_erasure_code_OBJECTS)
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE at ceph_erasure_code_DEPENDENCIES =  \
- at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__DEPENDENCIES_18) \
+ at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__DEPENDENCIES_23) \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__DEPENDENCIES_4) \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__DEPENDENCIES_1) \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__DEPENDENCIES_10) \
@@ -3461,7 +3705,7 @@ am__ceph_erasure_code_benchmark_SOURCES_DIST =  \
 ceph_erasure_code_benchmark_OBJECTS =  \
 	$(am_ceph_erasure_code_benchmark_OBJECTS)
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE at ceph_erasure_code_benchmark_DEPENDENCIES =  \
- at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__DEPENDENCIES_18) \
+ at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__DEPENDENCIES_23) \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__DEPENDENCIES_4) \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__DEPENDENCIES_1) \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__DEPENDENCIES_10) \
@@ -3472,7 +3716,7 @@ am__ceph_erasure_code_non_regression_SOURCES_DIST =  \
 ceph_erasure_code_non_regression_OBJECTS =  \
 	$(am_ceph_erasure_code_non_regression_OBJECTS)
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE at ceph_erasure_code_non_regression_DEPENDENCIES =  \
- at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__DEPENDENCIES_18) \
+ at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__DEPENDENCIES_23) \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__DEPENDENCIES_4) \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__DEPENDENCIES_1) \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__DEPENDENCIES_10) \
@@ -3497,7 +3741,7 @@ am__ceph_objectstore_bench_SOURCES_DIST = test/objectstore_bench.cc
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE at am_ceph_objectstore_bench_OBJECTS = test/objectstore_bench.$(OBJEXT)
 ceph_objectstore_bench_OBJECTS = $(am_ceph_objectstore_bench_OBJECTS)
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE at ceph_objectstore_bench_DEPENDENCIES =  \
- at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_14) \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_16) \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_10)
 am__ceph_omapbench_SOURCES_DIST = test/omap_bench.cc
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE at am_ceph_omapbench_OBJECTS = test/omap_bench.$(OBJEXT)
@@ -3512,7 +3756,7 @@ am__ceph_perf_local_SOURCES_DIST = test/perf_local.cc \
 @ENABLE_SERVER_TRUE@	test/ceph_perf_local-perf_helper.$(OBJEXT)
 ceph_perf_local_OBJECTS = $(am_ceph_perf_local_OBJECTS)
 @ENABLE_SERVER_TRUE at ceph_perf_local_DEPENDENCIES =  \
- at ENABLE_SERVER_TRUE@	$(am__DEPENDENCIES_14) \
+ at ENABLE_SERVER_TRUE@	$(am__DEPENDENCIES_16) \
 @ENABLE_SERVER_TRUE@	$(am__DEPENDENCIES_10)
 ceph_perf_local_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
 	$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \
@@ -3522,13 +3766,13 @@ am__ceph_perf_msgr_client_SOURCES_DIST =  \
 	test/msgr/perf_msgr_client.cc
 @ENABLE_SERVER_TRUE at am_ceph_perf_msgr_client_OBJECTS = test/msgr/ceph_perf_msgr_client-perf_msgr_client.$(OBJEXT)
 ceph_perf_msgr_client_OBJECTS = $(am_ceph_perf_msgr_client_OBJECTS)
-am__DEPENDENCIES_19 = $(top_builddir)/src/gmock/lib/libgmock_main.la \
+am__DEPENDENCIES_24 = $(top_builddir)/src/gmock/lib/libgmock_main.la \
 	$(top_builddir)/src/gmock/lib/libgmock.la \
 	$(top_builddir)/src/gmock/gtest/lib/libgtest.la \
 	$(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1)
 @ENABLE_SERVER_TRUE at ceph_perf_msgr_client_DEPENDENCIES =  \
- at ENABLE_SERVER_TRUE@	$(am__DEPENDENCIES_14) \
- at ENABLE_SERVER_TRUE@	$(am__DEPENDENCIES_19) \
+ at ENABLE_SERVER_TRUE@	$(am__DEPENDENCIES_16) \
+ at ENABLE_SERVER_TRUE@	$(am__DEPENDENCIES_24) \
 @ENABLE_SERVER_TRUE@	$(am__DEPENDENCIES_10)
 ceph_perf_msgr_client_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
 	$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \
@@ -3539,8 +3783,8 @@ am__ceph_perf_msgr_server_SOURCES_DIST =  \
 @ENABLE_SERVER_TRUE at am_ceph_perf_msgr_server_OBJECTS = test/msgr/ceph_perf_msgr_server-perf_msgr_server.$(OBJEXT)
 ceph_perf_msgr_server_OBJECTS = $(am_ceph_perf_msgr_server_OBJECTS)
 @ENABLE_SERVER_TRUE at ceph_perf_msgr_server_DEPENDENCIES =  \
- at ENABLE_SERVER_TRUE@	$(am__DEPENDENCIES_14) \
- at ENABLE_SERVER_TRUE@	$(am__DEPENDENCIES_19) \
+ at ENABLE_SERVER_TRUE@	$(am__DEPENDENCIES_16) \
+ at ENABLE_SERVER_TRUE@	$(am__DEPENDENCIES_24) \
 @ENABLE_SERVER_TRUE@	$(am__DEPENDENCIES_10)
 ceph_perf_msgr_server_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
 	$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \
@@ -3551,8 +3795,8 @@ am__ceph_perf_objectstore_SOURCES_DIST =  \
 @ENABLE_SERVER_TRUE at am_ceph_perf_objectstore_OBJECTS = test/objectstore/ceph_perf_objectstore-ObjectStoreTransactionBenchmark.$(OBJEXT)
 ceph_perf_objectstore_OBJECTS = $(am_ceph_perf_objectstore_OBJECTS)
 @ENABLE_SERVER_TRUE at ceph_perf_objectstore_DEPENDENCIES =  \
- at ENABLE_SERVER_TRUE@	$(am__DEPENDENCIES_14) \
- at ENABLE_SERVER_TRUE@	$(am__DEPENDENCIES_19) \
+ at ENABLE_SERVER_TRUE@	$(am__DEPENDENCIES_16) \
+ at ENABLE_SERVER_TRUE@	$(am__DEPENDENCIES_24) \
 @ENABLE_SERVER_TRUE@	$(am__DEPENDENCIES_10)
 ceph_perf_objectstore_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
 	$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \
@@ -3575,26 +3819,14 @@ am__ceph_rgw_jsonparser_SOURCES_DIST = rgw/rgw_jsonparser.cc \
 @ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/rgw_env.$(OBJEXT) \
 @ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/rgw_json_enc.$(OBJEXT)
 ceph_rgw_jsonparser_OBJECTS = $(am_ceph_rgw_jsonparser_OBJECTS)
-am__DEPENDENCIES_20 = librgw.la $(am__DEPENDENCIES_1)
- at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE at am__DEPENDENCIES_21 = $(LIBRADOS) \
- at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	libcls_rgw_client.la \
- at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	libcls_log_client.a \
- at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	libcls_statelog_client.a \
- at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	libcls_timeindex_client.a \
- at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	libcls_user_client.a \
- at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	libcls_replica_log_client.a \
- at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	libcls_lock_client.la \
- at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	libcls_refcount_client.la \
- at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	libcls_version_client.a
-am__DEPENDENCIES_22 = $(am__DEPENDENCIES_21)
- at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE at ceph_rgw_jsonparser_DEPENDENCIES = $(am__DEPENDENCIES_20) \
- at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_22) \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE at ceph_rgw_jsonparser_DEPENDENCIES = $(am__DEPENDENCIES_17) \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_12) \
 @ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_10)
 am__ceph_rgw_multiparser_SOURCES_DIST = rgw/rgw_multiparser.cc
 @ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE at am_ceph_rgw_multiparser_OBJECTS = rgw/rgw_multiparser.$(OBJEXT)
 ceph_rgw_multiparser_OBJECTS = $(am_ceph_rgw_multiparser_OBJECTS)
- at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE at ceph_rgw_multiparser_DEPENDENCIES = $(am__DEPENDENCIES_20) \
- at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_22) \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE at ceph_rgw_multiparser_DEPENDENCIES = $(am__DEPENDENCIES_17) \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_12) \
 @ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_10)
 am__ceph_scratchtool_SOURCES_DIST = tools/scratchtool.c
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE at am_ceph_scratchtool_OBJECTS = tools/scratchtool.$(OBJEXT)
@@ -3630,7 +3862,7 @@ am__ceph_smalliobenchdumb_SOURCES_DIST =  \
 ceph_smalliobenchdumb_OBJECTS = $(am_ceph_smalliobenchdumb_OBJECTS)
 @ENABLE_CLIENT_TRUE@@ENABLE_SERVER_TRUE@@WITH_RADOS_TRUE at ceph_smalliobenchdumb_DEPENDENCIES = $(LIBRADOS) \
 @ENABLE_CLIENT_TRUE@@ENABLE_SERVER_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_1) \
- at ENABLE_CLIENT_TRUE@@ENABLE_SERVER_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_14) \
+ at ENABLE_CLIENT_TRUE@@ENABLE_SERVER_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_16) \
 @ENABLE_CLIENT_TRUE@@ENABLE_SERVER_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_10)
 am__ceph_smalliobenchfs_SOURCES_DIST =  \
 	test/bench/small_io_bench_fs.cc \
@@ -3643,7 +3875,7 @@ am__ceph_smalliobenchfs_SOURCES_DIST =  \
 ceph_smalliobenchfs_OBJECTS = $(am_ceph_smalliobenchfs_OBJECTS)
 @ENABLE_CLIENT_TRUE@@ENABLE_SERVER_TRUE@@WITH_RADOS_TRUE at ceph_smalliobenchfs_DEPENDENCIES = $(LIBRADOS) \
 @ENABLE_CLIENT_TRUE@@ENABLE_SERVER_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_1) \
- at ENABLE_CLIENT_TRUE@@ENABLE_SERVER_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_14) \
+ at ENABLE_CLIENT_TRUE@@ENABLE_SERVER_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_16) \
 @ENABLE_CLIENT_TRUE@@ENABLE_SERVER_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_10)
 am__ceph_smalliobenchrbd_SOURCES_DIST =  \
 	test/bench/small_io_bench_rbd.cc test/bench/rbd_backend.cc \
@@ -3663,8 +3895,8 @@ am__ceph_test_async_driver_SOURCES_DIST =  \
 @ENABLE_SERVER_TRUE at am_ceph_test_async_driver_OBJECTS = test/msgr/ceph_test_async_driver-test_async_driver.$(OBJEXT)
 ceph_test_async_driver_OBJECTS = $(am_ceph_test_async_driver_OBJECTS)
 @ENABLE_SERVER_TRUE at ceph_test_async_driver_DEPENDENCIES =  \
- at ENABLE_SERVER_TRUE@	$(am__DEPENDENCIES_14) \
- at ENABLE_SERVER_TRUE@	$(am__DEPENDENCIES_19) \
+ at ENABLE_SERVER_TRUE@	$(am__DEPENDENCIES_16) \
+ at ENABLE_SERVER_TRUE@	$(am__DEPENDENCIES_24) \
 @ENABLE_SERVER_TRUE@	$(am__DEPENDENCIES_10)
 ceph_test_async_driver_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
 	$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \
@@ -3691,7 +3923,7 @@ ceph_test_cls_hello_OBJECTS = $(am_ceph_test_cls_hello_OBJECTS)
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE at ceph_test_cls_hello_DEPENDENCIES =  \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@	$(LIBRADOS) \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_1) \
- at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_19) \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_24) \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_10) \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_9)
 ceph_test_cls_hello_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
@@ -3707,7 +3939,7 @@ ceph_test_cls_journal_OBJECTS = $(am_ceph_test_cls_journal_OBJECTS)
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@	$(LIBRADOS) \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_4) \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_1) \
- at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_19) \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_24) \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_9)
 ceph_test_cls_journal_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
 	$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \
@@ -3720,7 +3952,7 @@ ceph_test_cls_lock_OBJECTS = $(am_ceph_test_cls_lock_OBJECTS)
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@	$(LIBRADOS) \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@	libcls_lock_client.la \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_4) \
- at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_19) \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_24) \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_9)
 ceph_test_cls_lock_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
 	$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \
@@ -3731,8 +3963,8 @@ am__ceph_test_cls_log_SOURCES_DIST = test/cls_log/test_cls_log.cc
 ceph_test_cls_log_OBJECTS = $(am_ceph_test_cls_log_OBJECTS)
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE at ceph_test_cls_log_DEPENDENCIES =  \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@	$(LIBRADOS) \
- at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@	libcls_log_client.a \
- at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_19) \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@	libcls_log_client.la \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_24) \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_10) \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_9)
 ceph_test_cls_log_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
@@ -3746,7 +3978,7 @@ ceph_test_cls_numops_OBJECTS = $(am_ceph_test_cls_numops_OBJECTS)
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE at ceph_test_cls_numops_DEPENDENCIES =  \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@	$(LIBRADOS) \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@	libcls_numops_client.la \
- at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_19) \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_24) \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_10) \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_9)
 ceph_test_cls_numops_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
@@ -3761,7 +3993,7 @@ ceph_test_cls_rbd_OBJECTS = $(am_ceph_test_cls_rbd_OBJECTS)
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@	libcls_rbd_client.la \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@	libcls_lock_client.la \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_4) \
- at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_19) \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_24) \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_9) \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_1) \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_3)
@@ -3776,7 +4008,7 @@ ceph_test_cls_refcount_OBJECTS = $(am_ceph_test_cls_refcount_OBJECTS)
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE at ceph_test_cls_refcount_DEPENDENCIES =  \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@	$(LIBRADOS) \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@	libcls_refcount_client.la \
- at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_19) \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_24) \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_9)
 ceph_test_cls_refcount_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
 	$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \
@@ -3789,8 +4021,8 @@ ceph_test_cls_replica_log_OBJECTS =  \
 	$(am_ceph_test_cls_replica_log_OBJECTS)
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE at ceph_test_cls_replica_log_DEPENDENCIES =  \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@	$(LIBRADOS) \
- at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@	libcls_replica_log_client.a \
- at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_19) \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@	libcls_replica_log_client.la \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_24) \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_10) \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_9)
 ceph_test_cls_replica_log_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
@@ -3804,7 +4036,7 @@ ceph_test_cls_rgw_OBJECTS = $(am_ceph_test_cls_rgw_OBJECTS)
 @ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_1) \
 @ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	libcls_rgw_client.la \
 @ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_4) \
- at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_19) \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_24) \
 @ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_10) \
 @ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_9)
 ceph_test_cls_rgw_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
@@ -3815,16 +4047,17 @@ am__ceph_test_cls_rgw_log_SOURCES_DIST = test/test_rgw_admin_log.cc
 @ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE at am_ceph_test_cls_rgw_log_OBJECTS = test/ceph_test_cls_rgw_log-test_rgw_admin_log.$(OBJEXT)
 ceph_test_cls_rgw_log_OBJECTS = $(am_ceph_test_cls_rgw_log_OBJECTS)
 @ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE at ceph_test_cls_rgw_log_DEPENDENCIES = $(LIBRADOS) \
- at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_20) \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_17) \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_12) \
 @ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_10) \
- at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_19) \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_24) \
 @ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_1) \
- at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	libcls_version_client.a \
- at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	libcls_log_client.a \
- at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	libcls_statelog_client.a \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	libcls_version_client.la \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	libcls_log_client.la \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	libcls_statelog_client.la \
 @ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	libcls_refcount_client.la \
 @ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	libcls_rgw_client.la \
- at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	libcls_user_client.a \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	libcls_user_client.la \
 @ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	libcls_lock_client.la
 ceph_test_cls_rgw_log_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
 	$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \
@@ -3833,17 +4066,18 @@ ceph_test_cls_rgw_log_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
 am__ceph_test_cls_rgw_meta_SOURCES_DIST = test/test_rgw_admin_meta.cc
 @ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE at am_ceph_test_cls_rgw_meta_OBJECTS = test/ceph_test_cls_rgw_meta-test_rgw_admin_meta.$(OBJEXT)
 ceph_test_cls_rgw_meta_OBJECTS = $(am_ceph_test_cls_rgw_meta_OBJECTS)
- at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE at ceph_test_cls_rgw_meta_DEPENDENCIES = $(LIBRADOS) \
- at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_20) \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE at ceph_test_cls_rgw_meta_DEPENDENCIES = $(am__DEPENDENCIES_17) \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	$(LIBRADOS) \
 @ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_10) \
- at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_19) \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_24) \
 @ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_1) \
- at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	libcls_version_client.a \
- at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	libcls_log_client.a \
- at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	libcls_statelog_client.a \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	libcls_timeindex_client.la \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	libcls_version_client.la \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	libcls_log_client.la \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	libcls_statelog_client.la \
 @ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	libcls_refcount_client.la \
 @ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	libcls_rgw_client.la \
- at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	libcls_user_client.a \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	libcls_user_client.la \
 @ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	libcls_lock_client.la
 ceph_test_cls_rgw_meta_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
 	$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \
@@ -3855,17 +4089,17 @@ am__ceph_test_cls_rgw_opstate_SOURCES_DIST =  \
 ceph_test_cls_rgw_opstate_OBJECTS =  \
 	$(am_ceph_test_cls_rgw_opstate_OBJECTS)
 @ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE at ceph_test_cls_rgw_opstate_DEPENDENCIES = $(LIBRADOS) \
- at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_20) \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_17) \
 @ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_10) \
- at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_19) \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_24) \
 @ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_1) \
- at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	libcls_version_client.a \
- at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	libcls_log_client.a \
- at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	libcls_timeindex_client.a \
- at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	libcls_statelog_client.a \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	libcls_version_client.la \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	libcls_log_client.la \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	libcls_timeindex_client.la \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	libcls_statelog_client.la \
 @ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	libcls_refcount_client.la \
 @ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	libcls_rgw_client.la \
- at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	libcls_user_client.a \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	libcls_user_client.la \
 @ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	libcls_lock_client.la \
 @ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	$(LIBRADOS)
 ceph_test_cls_rgw_opstate_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
@@ -3878,8 +4112,8 @@ am__ceph_test_cls_statelog_SOURCES_DIST =  \
 ceph_test_cls_statelog_OBJECTS = $(am_ceph_test_cls_statelog_OBJECTS)
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE at ceph_test_cls_statelog_DEPENDENCIES =  \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@	$(LIBRADOS) \
- at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@	libcls_statelog_client.a \
- at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_19) \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@	libcls_statelog_client.la \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_24) \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_10) \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_9)
 ceph_test_cls_statelog_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
@@ -3892,8 +4126,8 @@ am__ceph_test_cls_version_SOURCES_DIST =  \
 ceph_test_cls_version_OBJECTS = $(am_ceph_test_cls_version_OBJECTS)
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE at ceph_test_cls_version_DEPENDENCIES =  \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@	$(LIBRADOS) \
- at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@	libcls_version_client.a \
- at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_19) \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@	libcls_version_client.la \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_24) \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_9)
 ceph_test_cls_version_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
 	$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \
@@ -3903,9 +4137,9 @@ am__ceph_test_cors_SOURCES_DIST = test/test_cors.cc
 @ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE at am_ceph_test_cors_OBJECTS = test/ceph_test_cors-test_cors.$(OBJEXT)
 ceph_test_cors_OBJECTS = $(am_ceph_test_cors_OBJECTS)
 @ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE at ceph_test_cors_DEPENDENCIES = $(LIBRADOS) \
- at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_20) \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_17) \
 @ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_10) \
- at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_19)
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_24)
 ceph_test_cors_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
 	$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \
 	$(ceph_test_cors_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) \
@@ -3917,8 +4151,8 @@ am__ceph_test_filejournal_SOURCES_DIST = test/test_filejournal.cc
 @ENABLE_SERVER_TRUE at am_ceph_test_filejournal_OBJECTS = test/ceph_test_filejournal-test_filejournal.$(OBJEXT)
 ceph_test_filejournal_OBJECTS = $(am_ceph_test_filejournal_OBJECTS)
 @ENABLE_SERVER_TRUE at ceph_test_filejournal_DEPENDENCIES =  \
- at ENABLE_SERVER_TRUE@	$(am__DEPENDENCIES_14) \
- at ENABLE_SERVER_TRUE@	$(am__DEPENDENCIES_19) \
+ at ENABLE_SERVER_TRUE@	$(am__DEPENDENCIES_16) \
+ at ENABLE_SERVER_TRUE@	$(am__DEPENDENCIES_24) \
 @ENABLE_SERVER_TRUE@	$(am__DEPENDENCIES_10)
 ceph_test_filejournal_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
 	$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \
@@ -3929,8 +4163,8 @@ am__ceph_test_filestore_SOURCES_DIST =  \
 @ENABLE_SERVER_TRUE@@LINUX_TRUE at am_ceph_test_filestore_OBJECTS = test/filestore/ceph_test_filestore-TestFileStore.$(OBJEXT)
 ceph_test_filestore_OBJECTS = $(am_ceph_test_filestore_OBJECTS)
 @ENABLE_SERVER_TRUE@@LINUX_TRUE at ceph_test_filestore_DEPENDENCIES =  \
- at ENABLE_SERVER_TRUE@@LINUX_TRUE@	$(am__DEPENDENCIES_14) \
- at ENABLE_SERVER_TRUE@@LINUX_TRUE@	$(am__DEPENDENCIES_19) \
+ at ENABLE_SERVER_TRUE@@LINUX_TRUE@	$(am__DEPENDENCIES_16) \
+ at ENABLE_SERVER_TRUE@@LINUX_TRUE@	$(am__DEPENDENCIES_24) \
 @ENABLE_SERVER_TRUE@@LINUX_TRUE@	$(am__DEPENDENCIES_10)
 ceph_test_filestore_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
 	$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \
@@ -3946,7 +4180,7 @@ am__ceph_test_filestore_idempotent_SOURCES_DIST =  \
 ceph_test_filestore_idempotent_OBJECTS =  \
 	$(am_ceph_test_filestore_idempotent_OBJECTS)
 @ENABLE_SERVER_TRUE at ceph_test_filestore_idempotent_DEPENDENCIES =  \
- at ENABLE_SERVER_TRUE@	$(am__DEPENDENCIES_14) \
+ at ENABLE_SERVER_TRUE@	$(am__DEPENDENCIES_16) \
 @ENABLE_SERVER_TRUE@	$(am__DEPENDENCIES_10)
 am__ceph_test_filestore_idempotent_sequence_SOURCES_DIST =  \
 	test/objectstore/test_idempotent_sequence.cc \
@@ -3960,7 +4194,7 @@ am__ceph_test_filestore_idempotent_sequence_SOURCES_DIST =  \
 ceph_test_filestore_idempotent_sequence_OBJECTS =  \
 	$(am_ceph_test_filestore_idempotent_sequence_OBJECTS)
 @ENABLE_SERVER_TRUE at ceph_test_filestore_idempotent_sequence_DEPENDENCIES =  \
- at ENABLE_SERVER_TRUE@	$(am__DEPENDENCIES_14) \
+ at ENABLE_SERVER_TRUE@	$(am__DEPENDENCIES_16) \
 @ENABLE_SERVER_TRUE@	$(am__DEPENDENCIES_10)
 am__ceph_test_get_blkdev_size_SOURCES_DIST =  \
 	test/test_get_blkdev_size.cc
@@ -3980,14 +4214,14 @@ am__ceph_test_keys_SOURCES_DIST = test/testkeys.cc
 @ENABLE_SERVER_TRUE@@WITH_MON_TRUE@	test/testkeys.$(OBJEXT)
 ceph_test_keys_OBJECTS = $(am_ceph_test_keys_OBJECTS)
 @ENABLE_SERVER_TRUE@@WITH_MON_TRUE at ceph_test_keys_DEPENDENCIES =  \
- at ENABLE_SERVER_TRUE@@WITH_MON_TRUE@	$(am__DEPENDENCIES_17) \
+ at ENABLE_SERVER_TRUE@@WITH_MON_TRUE@	$(am__DEPENDENCIES_22) \
 @ENABLE_SERVER_TRUE@@WITH_MON_TRUE@	$(am__DEPENDENCIES_10)
 am__ceph_test_keyvaluedb_SOURCES_DIST = test/objectstore/test_kv.cc
 @ENABLE_SERVER_TRUE@@LINUX_TRUE at am_ceph_test_keyvaluedb_OBJECTS = test/objectstore/ceph_test_keyvaluedb-test_kv.$(OBJEXT)
 ceph_test_keyvaluedb_OBJECTS = $(am_ceph_test_keyvaluedb_OBJECTS)
 @ENABLE_SERVER_TRUE@@LINUX_TRUE at ceph_test_keyvaluedb_DEPENDENCIES =  \
- at ENABLE_SERVER_TRUE@@LINUX_TRUE@	$(am__DEPENDENCIES_14) \
- at ENABLE_SERVER_TRUE@@LINUX_TRUE@	$(am__DEPENDENCIES_19) \
+ at ENABLE_SERVER_TRUE@@LINUX_TRUE@	$(am__DEPENDENCIES_16) \
+ at ENABLE_SERVER_TRUE@@LINUX_TRUE@	$(am__DEPENDENCIES_24) \
 @ENABLE_SERVER_TRUE@@LINUX_TRUE@	$(am__DEPENDENCIES_10)
 ceph_test_keyvaluedb_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
 	$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \
@@ -3999,8 +4233,8 @@ am__ceph_test_keyvaluedb_atomicity_SOURCES_DIST =  \
 ceph_test_keyvaluedb_atomicity_OBJECTS =  \
 	$(am_ceph_test_keyvaluedb_atomicity_OBJECTS)
 @ENABLE_SERVER_TRUE at ceph_test_keyvaluedb_atomicity_DEPENDENCIES =  \
- at ENABLE_SERVER_TRUE@	$(am__DEPENDENCIES_14) \
- at ENABLE_SERVER_TRUE@	$(am__DEPENDENCIES_19) \
+ at ENABLE_SERVER_TRUE@	$(am__DEPENDENCIES_16) \
+ at ENABLE_SERVER_TRUE@	$(am__DEPENDENCIES_24) \
 @ENABLE_SERVER_TRUE@	$(am__DEPENDENCIES_10)
 ceph_test_keyvaluedb_atomicity_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
 	$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \
@@ -4014,8 +4248,8 @@ am__ceph_test_keyvaluedb_iterators_SOURCES_DIST =  \
 ceph_test_keyvaluedb_iterators_OBJECTS =  \
 	$(am_ceph_test_keyvaluedb_iterators_OBJECTS)
 @ENABLE_SERVER_TRUE at ceph_test_keyvaluedb_iterators_DEPENDENCIES =  \
- at ENABLE_SERVER_TRUE@	$(am__DEPENDENCIES_14) \
- at ENABLE_SERVER_TRUE@	$(am__DEPENDENCIES_19) \
+ at ENABLE_SERVER_TRUE@	$(am__DEPENDENCIES_16) \
+ at ENABLE_SERVER_TRUE@	$(am__DEPENDENCIES_24) \
 @ENABLE_SERVER_TRUE@	$(am__DEPENDENCIES_10)
 ceph_test_keyvaluedb_iterators_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
 	$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \
@@ -4037,7 +4271,7 @@ ceph_test_libcephfs_OBJECTS = $(am_ceph_test_libcephfs_OBJECTS)
 @ENABLE_CLIENT_TRUE@@WITH_CEPHFS_TRUE@@WITH_RADOS_TRUE at ceph_test_libcephfs_DEPENDENCIES = $(LIBRADOS) \
 @ENABLE_CLIENT_TRUE@@WITH_CEPHFS_TRUE@@WITH_RADOS_TRUE@	$(LIBCEPHFS) \
 @ENABLE_CLIENT_TRUE@@WITH_CEPHFS_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_4) \
- at ENABLE_CLIENT_TRUE@@WITH_CEPHFS_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_19)
+ at ENABLE_CLIENT_TRUE@@WITH_CEPHFS_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_24)
 ceph_test_libcephfs_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
 	$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \
 	$(ceph_test_libcephfs_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) \
@@ -4055,7 +4289,7 @@ ceph_test_librbd_OBJECTS = $(am_ceph_test_librbd_OBJECTS)
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	libcls_journal_client.la \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	librados_api.la \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	$(am__DEPENDENCIES_7) \
- at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	$(am__DEPENDENCIES_19) \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	$(am__DEPENDENCIES_24) \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	$(am__DEPENDENCIES_10) \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	$(am__DEPENDENCIES_9)
 ceph_test_librbd_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
@@ -4072,7 +4306,7 @@ ceph_test_librbd_api_OBJECTS = $(am_ceph_test_librbd_api_OBJECTS)
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	$(LIBRBD) \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	$(LIBRADOS) \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	$(am__DEPENDENCIES_4) \
- at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	$(am__DEPENDENCIES_19) \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	$(am__DEPENDENCIES_24) \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	$(am__DEPENDENCIES_9)
 ceph_test_librbd_api_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
 	$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \
@@ -4081,7 +4315,9 @@ ceph_test_librbd_api_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
 am__ceph_test_librbd_fsx_SOURCES_DIST = test/librbd/fsx.cc
 @ENABLE_CLIENT_TRUE@@LINUX_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE at am_ceph_test_librbd_fsx_OBJECTS = test/librbd/ceph_test_librbd_fsx-fsx.$(OBJEXT)
 ceph_test_librbd_fsx_OBJECTS = $(am_ceph_test_librbd_fsx_OBJECTS)
- at ENABLE_CLIENT_TRUE@@LINUX_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE at ceph_test_librbd_fsx_DEPENDENCIES = $(LIBKRBD) \
+ at ENABLE_CLIENT_TRUE@@LINUX_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE at ceph_test_librbd_fsx_DEPENDENCIES = libjournal.la \
+ at ENABLE_CLIENT_TRUE@@LINUX_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	libcls_journal_client.la \
+ at ENABLE_CLIENT_TRUE@@LINUX_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	$(LIBKRBD) \
 @ENABLE_CLIENT_TRUE@@LINUX_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	$(LIBRBD) \
 @ENABLE_CLIENT_TRUE@@LINUX_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	$(LIBRADOS) \
 @ENABLE_CLIENT_TRUE@@LINUX_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	$(am__DEPENDENCIES_1) \
@@ -4094,9 +4330,9 @@ am__ceph_test_mon_msg_SOURCES_DIST = test/mon/test-mon-msg.cc
 @ENABLE_SERVER_TRUE at am_ceph_test_mon_msg_OBJECTS = test/mon/ceph_test_mon_msg-test-mon-msg.$(OBJEXT)
 ceph_test_mon_msg_OBJECTS = $(am_ceph_test_mon_msg_OBJECTS)
 @ENABLE_SERVER_TRUE at ceph_test_mon_msg_DEPENDENCIES =  \
- at ENABLE_SERVER_TRUE@	$(am__DEPENDENCIES_14) $(LIBOSDC) \
+ at ENABLE_SERVER_TRUE@	$(am__DEPENDENCIES_16) $(LIBOSDC) \
 @ENABLE_SERVER_TRUE@	$(am__DEPENDENCIES_10) \
- at ENABLE_SERVER_TRUE@	$(am__DEPENDENCIES_19)
+ at ENABLE_SERVER_TRUE@	$(am__DEPENDENCIES_24)
 ceph_test_mon_msg_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
 	$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \
 	$(ceph_test_mon_msg_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) \
@@ -4108,14 +4344,14 @@ am__ceph_test_mon_workloadgen_SOURCES_DIST =  \
 ceph_test_mon_workloadgen_OBJECTS =  \
 	$(am_ceph_test_mon_workloadgen_OBJECTS)
 @ENABLE_SERVER_TRUE at ceph_test_mon_workloadgen_DEPENDENCIES =  \
- at ENABLE_SERVER_TRUE@	$(am__DEPENDENCIES_14) $(LIBOSDC) \
+ at ENABLE_SERVER_TRUE@	$(am__DEPENDENCIES_16) $(LIBOSDC) \
 @ENABLE_SERVER_TRUE@	$(am__DEPENDENCIES_10)
 am__ceph_test_msgr_SOURCES_DIST = test/msgr/test_msgr.cc
 @ENABLE_SERVER_TRUE at am_ceph_test_msgr_OBJECTS = test/msgr/ceph_test_msgr-test_msgr.$(OBJEXT)
 ceph_test_msgr_OBJECTS = $(am_ceph_test_msgr_OBJECTS)
 @ENABLE_SERVER_TRUE at ceph_test_msgr_DEPENDENCIES =  \
- at ENABLE_SERVER_TRUE@	$(am__DEPENDENCIES_14) \
- at ENABLE_SERVER_TRUE@	$(am__DEPENDENCIES_19) \
+ at ENABLE_SERVER_TRUE@	$(am__DEPENDENCIES_16) \
+ at ENABLE_SERVER_TRUE@	$(am__DEPENDENCIES_24) \
 @ENABLE_SERVER_TRUE@	$(am__DEPENDENCIES_10)
 ceph_test_msgr_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
 	$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \
@@ -4134,8 +4370,8 @@ am__ceph_test_object_map_SOURCES_DIST =  \
 @ENABLE_SERVER_TRUE@	test/ObjectMap/ceph_test_object_map-KeyValueDBMemory.$(OBJEXT)
 ceph_test_object_map_OBJECTS = $(am_ceph_test_object_map_OBJECTS)
 @ENABLE_SERVER_TRUE at ceph_test_object_map_DEPENDENCIES =  \
- at ENABLE_SERVER_TRUE@	$(am__DEPENDENCIES_14) \
- at ENABLE_SERVER_TRUE@	$(am__DEPENDENCIES_19) \
+ at ENABLE_SERVER_TRUE@	$(am__DEPENDENCIES_16) \
+ at ENABLE_SERVER_TRUE@	$(am__DEPENDENCIES_24) \
 @ENABLE_SERVER_TRUE@	$(am__DEPENDENCIES_10)
 ceph_test_object_map_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
 	$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \
@@ -4153,8 +4389,8 @@ am__ceph_test_objectstore_SOURCES_DIST =  \
 @ENABLE_SERVER_TRUE@@LINUX_TRUE at am_ceph_test_objectstore_OBJECTS = test/objectstore/ceph_test_objectstore-store_test.$(OBJEXT)
 ceph_test_objectstore_OBJECTS = $(am_ceph_test_objectstore_OBJECTS)
 @ENABLE_SERVER_TRUE@@LINUX_TRUE at ceph_test_objectstore_DEPENDENCIES =  \
- at ENABLE_SERVER_TRUE@@LINUX_TRUE@	$(am__DEPENDENCIES_14) \
- at ENABLE_SERVER_TRUE@@LINUX_TRUE@	$(am__DEPENDENCIES_19) \
+ at ENABLE_SERVER_TRUE@@LINUX_TRUE@	$(am__DEPENDENCIES_16) \
+ at ENABLE_SERVER_TRUE@@LINUX_TRUE@	$(am__DEPENDENCIES_24) \
 @ENABLE_SERVER_TRUE@@LINUX_TRUE@	$(am__DEPENDENCIES_10)
 ceph_test_objectstore_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
 	$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \
@@ -4168,7 +4404,7 @@ am__ceph_test_objectstore_workloadgen_SOURCES_DIST =  \
 ceph_test_objectstore_workloadgen_OBJECTS =  \
 	$(am_ceph_test_objectstore_workloadgen_OBJECTS)
 @ENABLE_SERVER_TRUE at ceph_test_objectstore_workloadgen_DEPENDENCIES =  \
- at ENABLE_SERVER_TRUE@	$(am__DEPENDENCIES_14) \
+ at ENABLE_SERVER_TRUE@	$(am__DEPENDENCIES_16) \
 @ENABLE_SERVER_TRUE@	$(am__DEPENDENCIES_10)
 am__ceph_test_rados_SOURCES_DIST = test/osd/TestRados.cc \
 	test/osd/TestOpStat.cc test/osd/Object.cc \
@@ -4188,7 +4424,7 @@ ceph_test_rados_api_aio_OBJECTS =  \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE at ceph_test_rados_api_aio_DEPENDENCIES =  \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@	$(LIBRADOS) \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_4) \
- at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_19) \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_24) \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_9)
 ceph_test_rados_api_aio_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
 	$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \
@@ -4201,7 +4437,7 @@ ceph_test_rados_api_c_read_operations_OBJECTS =  \
 	$(am_ceph_test_rados_api_c_read_operations_OBJECTS)
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE at ceph_test_rados_api_c_read_operations_DEPENDENCIES =  \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@	$(LIBRADOS) \
- at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_19) \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_24) \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_9)
 ceph_test_rados_api_c_read_operations_LINK = $(LIBTOOL) $(AM_V_lt) \
 	--tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link \
@@ -4214,7 +4450,7 @@ ceph_test_rados_api_c_write_operations_OBJECTS =  \
 	$(am_ceph_test_rados_api_c_write_operations_OBJECTS)
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE at ceph_test_rados_api_c_write_operations_DEPENDENCIES =  \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@	$(LIBRADOS) \
- at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_19) \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_24) \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_9)
 ceph_test_rados_api_c_write_operations_LINK = $(LIBTOOL) $(AM_V_lt) \
 	--tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link \
@@ -4226,7 +4462,7 @@ ceph_test_rados_api_cls_OBJECTS =  \
 	$(am_ceph_test_rados_api_cls_OBJECTS)
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE at ceph_test_rados_api_cls_DEPENDENCIES =  \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@	$(LIBRADOS) \
- at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_19) \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_24) \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_9)
 ceph_test_rados_api_cls_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
 	$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \
@@ -4240,7 +4476,7 @@ ceph_test_rados_api_cmd_OBJECTS =  \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_4) \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@	$(LIBRADOS) \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_1) \
- at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_19) \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_24) \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_9)
 ceph_test_rados_api_cmd_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
 	$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \
@@ -4251,7 +4487,7 @@ am__ceph_test_rados_api_io_SOURCES_DIST = test/librados/io.cc
 ceph_test_rados_api_io_OBJECTS = $(am_ceph_test_rados_api_io_OBJECTS)
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE at ceph_test_rados_api_io_DEPENDENCIES =  \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@	$(LIBRADOS) \
- at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_19) \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_24) \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_9)
 ceph_test_rados_api_io_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
 	$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \
@@ -4263,7 +4499,7 @@ ceph_test_rados_api_list_OBJECTS =  \
 	$(am_ceph_test_rados_api_list_OBJECTS)
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE at ceph_test_rados_api_list_DEPENDENCIES =  \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@	$(LIBRADOS) \
- at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_19) \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_24) \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_9)
 ceph_test_rados_api_list_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
 	$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \
@@ -4275,7 +4511,7 @@ ceph_test_rados_api_lock_OBJECTS =  \
 	$(am_ceph_test_rados_api_lock_OBJECTS)
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE at ceph_test_rados_api_lock_DEPENDENCIES =  \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@	$(LIBRADOS) \
- at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_19) \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_24) \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_9)
 ceph_test_rados_api_lock_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
 	$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \
@@ -4287,7 +4523,7 @@ ceph_test_rados_api_misc_OBJECTS =  \
 	$(am_ceph_test_rados_api_misc_OBJECTS)
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE at ceph_test_rados_api_misc_DEPENDENCIES =  \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@	$(LIBRADOS) \
- at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_19) \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_24) \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_10) \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_9)
 ceph_test_rados_api_misc_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
@@ -4300,7 +4536,7 @@ ceph_test_rados_api_nlist_OBJECTS =  \
 	$(am_ceph_test_rados_api_nlist_OBJECTS)
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE at ceph_test_rados_api_nlist_DEPENDENCIES =  \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@	$(LIBRADOS) \
- at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_19) \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_24) \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_9)
 ceph_test_rados_api_nlist_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
 	$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \
@@ -4312,7 +4548,7 @@ ceph_test_rados_api_pool_OBJECTS =  \
 	$(am_ceph_test_rados_api_pool_OBJECTS)
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE at ceph_test_rados_api_pool_DEPENDENCIES =  \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@	$(LIBRADOS) \
- at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_19) \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_24) \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_9)
 ceph_test_rados_api_pool_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
 	$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \
@@ -4325,7 +4561,7 @@ ceph_test_rados_api_snapshots_OBJECTS =  \
 	$(am_ceph_test_rados_api_snapshots_OBJECTS)
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE at ceph_test_rados_api_snapshots_DEPENDENCIES =  \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@	$(LIBRADOS) \
- at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_19) \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_24) \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_9)
 ceph_test_rados_api_snapshots_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
 	$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \
@@ -4337,7 +4573,7 @@ ceph_test_rados_api_stat_OBJECTS =  \
 	$(am_ceph_test_rados_api_stat_OBJECTS)
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE at ceph_test_rados_api_stat_DEPENDENCIES =  \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@	$(LIBRADOS) \
- at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_19) \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_24) \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_9)
 ceph_test_rados_api_stat_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
 	$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \
@@ -4351,13 +4587,32 @@ ceph_test_rados_api_tier_OBJECTS =  \
 	$(am_ceph_test_rados_api_tier_OBJECTS)
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE at ceph_test_rados_api_tier_DEPENDENCIES =  \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@	$(LIBRADOS) \
- at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_19) \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_24) \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_10) \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_9)
 ceph_test_rados_api_tier_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
 	$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \
 	$(ceph_test_rados_api_tier_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) \
 	$(LDFLAGS) -o $@
+am__ceph_test_rados_api_tmap_migrate_SOURCES_DIST =  \
+	test/librados/tmap_migrate.cc tools/cephfs/DataScan.cc \
+	tools/cephfs/MDSUtility.cc
+ at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE at am_ceph_test_rados_api_tmap_migrate_OBJECTS = test/librados/ceph_test_rados_api_tmap_migrate-tmap_migrate.$(OBJEXT) \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@	tools/cephfs/ceph_test_rados_api_tmap_migrate-DataScan.$(OBJEXT) \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@	tools/cephfs/ceph_test_rados_api_tmap_migrate-MDSUtility.$(OBJEXT)
+ceph_test_rados_api_tmap_migrate_OBJECTS =  \
+	$(am_ceph_test_rados_api_tmap_migrate_OBJECTS)
+ at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE at ceph_test_rados_api_tmap_migrate_DEPENDENCIES =  \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@	$(LIBRADOS) \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_24) \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_21) \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@	libcls_cephfs_client.la \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_10) \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_9)
+ceph_test_rados_api_tmap_migrate_LINK = $(LIBTOOL) $(AM_V_lt) \
+	--tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link \
+	$(CXXLD) $(ceph_test_rados_api_tmap_migrate_CXXFLAGS) \
+	$(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
 am__ceph_test_rados_api_watch_notify_SOURCES_DIST =  \
 	test/librados/watch_notify.cc
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE at am_ceph_test_rados_api_watch_notify_OBJECTS = test/librados/ceph_test_rados_api_watch_notify-watch_notify.$(OBJEXT)
@@ -4365,7 +4620,7 @@ ceph_test_rados_api_watch_notify_OBJECTS =  \
 	$(am_ceph_test_rados_api_watch_notify_OBJECTS)
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE at ceph_test_rados_api_watch_notify_DEPENDENCIES =  \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@	$(LIBRADOS) \
- at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_19) \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_24) \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_9)
 ceph_test_rados_api_watch_notify_LINK = $(LIBTOOL) $(AM_V_lt) \
 	--tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link \
@@ -4417,7 +4672,7 @@ ceph_test_rados_striper_api_aio_OBJECTS =  \
 	$(am_ceph_test_rados_striper_api_aio_OBJECTS)
 @ENABLE_CLIENT_TRUE@@WITH_RADOSSTRIPER_TRUE@@WITH_RADOS_TRUE at ceph_test_rados_striper_api_aio_DEPENDENCIES = $(LIBRADOS) \
 @ENABLE_CLIENT_TRUE@@WITH_RADOSSTRIPER_TRUE@@WITH_RADOS_TRUE@	$(LIBRADOSSTRIPER) \
- at ENABLE_CLIENT_TRUE@@WITH_RADOSSTRIPER_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_19) \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSSTRIPER_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_24) \
 @ENABLE_CLIENT_TRUE@@WITH_RADOSSTRIPER_TRUE@@WITH_RADOS_TRUE@	$(RADOS_STRIPER_TEST_LDADD)
 ceph_test_rados_striper_api_aio_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
 	$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \
@@ -4431,7 +4686,7 @@ ceph_test_rados_striper_api_io_OBJECTS =  \
 @ENABLE_CLIENT_TRUE@@WITH_RADOSSTRIPER_TRUE@@WITH_RADOS_TRUE at ceph_test_rados_striper_api_io_DEPENDENCIES = $(LIBRADOS) \
 @ENABLE_CLIENT_TRUE@@WITH_RADOSSTRIPER_TRUE@@WITH_RADOS_TRUE@	$(LIBRADOSSTRIPER) \
 @ENABLE_CLIENT_TRUE@@WITH_RADOSSTRIPER_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_4) \
- at ENABLE_CLIENT_TRUE@@WITH_RADOSSTRIPER_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_19) \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSSTRIPER_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_24) \
 @ENABLE_CLIENT_TRUE@@WITH_RADOSSTRIPER_TRUE@@WITH_RADOS_TRUE@	$(RADOS_STRIPER_TEST_LDADD)
 ceph_test_rados_striper_api_io_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
 	$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \
@@ -4444,7 +4699,7 @@ ceph_test_rados_striper_api_striping_OBJECTS =  \
 	$(am_ceph_test_rados_striper_api_striping_OBJECTS)
 @ENABLE_CLIENT_TRUE@@WITH_RADOSSTRIPER_TRUE@@WITH_RADOS_TRUE at ceph_test_rados_striper_api_striping_DEPENDENCIES = $(LIBRADOS) \
 @ENABLE_CLIENT_TRUE@@WITH_RADOSSTRIPER_TRUE@@WITH_RADOS_TRUE@	$(LIBRADOSSTRIPER) \
- at ENABLE_CLIENT_TRUE@@WITH_RADOSSTRIPER_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_19) \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSSTRIPER_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_24) \
 @ENABLE_CLIENT_TRUE@@WITH_RADOSSTRIPER_TRUE@@WITH_RADOS_TRUE@	$(RADOS_STRIPER_TEST_LDADD)
 ceph_test_rados_striper_api_striping_LINK = $(LIBTOOL) $(AM_V_lt) \
 	--tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link \
@@ -4484,13 +4739,30 @@ ceph_test_rbd_mirror_OBJECTS = $(am_ceph_test_rbd_mirror_OBJECTS)
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	librados_api.la \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	$(am__DEPENDENCIES_7) \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	$(LIBOSDC) \
- at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	$(am__DEPENDENCIES_19) \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	$(am__DEPENDENCIES_24) \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	$(am__DEPENDENCIES_10) \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	$(am__DEPENDENCIES_9)
 ceph_test_rbd_mirror_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
 	$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \
 	$(ceph_test_rbd_mirror_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) \
 	$(LDFLAGS) -o $@
+am__ceph_test_rbd_mirror_image_replay_SOURCES_DIST =  \
+	test/rbd_mirror/image_replay.cc
+ at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE at am_ceph_test_rbd_mirror_image_replay_OBJECTS = test/rbd_mirror/image_replay.$(OBJEXT)
+ceph_test_rbd_mirror_image_replay_OBJECTS =  \
+	$(am_ceph_test_rbd_mirror_image_replay_OBJECTS)
+ at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE at ceph_test_rbd_mirror_image_replay_DEPENDENCIES = librbd_mirror_internal.la \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	librbd_internal.la \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	librbd_api.la \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	$(LIBRBD_TYPES) \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	libjournal.la \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	$(LIBRADOS) \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	$(LIBOSDC) \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	librados_internal.la \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	libcls_rbd_client.la \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	libcls_lock_client.la \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	libcls_journal_client.la \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	$(am__DEPENDENCIES_10)
 am_ceph_test_rewrite_latency_OBJECTS =  \
 	test/test_rewrite_latency.$(OBJEXT)
 ceph_test_rewrite_latency_OBJECTS =  \
@@ -4503,10 +4775,10 @@ am__ceph_test_rgw_manifest_SOURCES_DIST =  \
 @ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE at am_ceph_test_rgw_manifest_OBJECTS = test/rgw/ceph_test_rgw_manifest-test_rgw_manifest.$(OBJEXT)
 ceph_test_rgw_manifest_OBJECTS = $(am_ceph_test_rgw_manifest_OBJECTS)
 @ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE at ceph_test_rgw_manifest_DEPENDENCIES = $(LIBRADOS) \
- at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_20) \
- at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_22) \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_17) \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_12) \
 @ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_10) \
- at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_19) \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_24) \
 @ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_1)
 ceph_test_rgw_manifest_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
 	$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \
@@ -4516,15 +4788,30 @@ am__ceph_test_rgw_obj_SOURCES_DIST = test/rgw/test_rgw_obj.cc
 @ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE at am_ceph_test_rgw_obj_OBJECTS = test/rgw/ceph_test_rgw_obj-test_rgw_obj.$(OBJEXT)
 ceph_test_rgw_obj_OBJECTS = $(am_ceph_test_rgw_obj_OBJECTS)
 @ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE at ceph_test_rgw_obj_DEPENDENCIES = $(LIBRADOS) \
- at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_20) \
- at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_22) \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_17) \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_12) \
 @ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_10) \
- at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_19) \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_24) \
 @ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_1)
 ceph_test_rgw_obj_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
 	$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \
 	$(ceph_test_rgw_obj_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) \
 	$(LDFLAGS) -o $@
+am__ceph_test_rgw_period_history_SOURCES_DIST =  \
+	test/rgw/test_rgw_period_history.cc
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE at am_ceph_test_rgw_period_history_OBJECTS = test/rgw/ceph_test_rgw_period_history-test_rgw_period_history.$(OBJEXT)
+ceph_test_rgw_period_history_OBJECTS =  \
+	$(am_ceph_test_rgw_period_history_OBJECTS)
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE at ceph_test_rgw_period_history_DEPENDENCIES = $(LIBRADOS) \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_17) \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_12) \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_10) \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_24) \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_1)
+ceph_test_rgw_period_history_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
+	$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \
+	$(ceph_test_rgw_period_history_CXXFLAGS) $(CXXFLAGS) \
+	$(AM_LDFLAGS) $(LDFLAGS) -o $@
 am_ceph_test_signal_handlers_OBJECTS =  \
 	test/TestSignalHandlers.$(OBJEXT)
 ceph_test_signal_handlers_OBJECTS =  \
@@ -4534,8 +4821,8 @@ am__ceph_test_snap_mapper_SOURCES_DIST = test/test_snap_mapper.cc
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE at am_ceph_test_snap_mapper_OBJECTS = test/ceph_test_snap_mapper-test_snap_mapper.$(OBJEXT)
 ceph_test_snap_mapper_OBJECTS = $(am_ceph_test_snap_mapper_OBJECTS)
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE at ceph_test_snap_mapper_DEPENDENCIES =  \
- at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__DEPENDENCIES_18) \
- at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__DEPENDENCIES_19) \
+ at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__DEPENDENCIES_23) \
+ at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__DEPENDENCIES_24) \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__DEPENDENCIES_10)
 ceph_test_snap_mapper_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
 	$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \
@@ -4547,7 +4834,7 @@ ceph_test_stress_watch_OBJECTS = $(am_ceph_test_stress_watch_OBJECTS)
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE at ceph_test_stress_watch_DEPENDENCIES =  \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@	$(LIBRADOS) \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_4) \
- at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_19) \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_24) \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_9)
 ceph_test_stress_watch_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
 	$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \
@@ -4561,7 +4848,7 @@ am__ceph_test_trans_SOURCES_DIST = test/test_trans.cc
 @ENABLE_SERVER_TRUE@	test/test_trans.$(OBJEXT)
 ceph_test_trans_OBJECTS = $(am_ceph_test_trans_OBJECTS)
 @ENABLE_SERVER_TRUE at ceph_test_trans_DEPENDENCIES =  \
- at ENABLE_SERVER_TRUE@	$(am__DEPENDENCIES_14) \
+ at ENABLE_SERVER_TRUE@	$(am__DEPENDENCIES_16) \
 @ENABLE_SERVER_TRUE@	$(am__DEPENDENCIES_10)
 am__ceph_tpbench_SOURCES_DIST = test/bench/tp_bench.cc \
 	test/bench/detailed_stat_collector.cc
@@ -4570,14 +4857,14 @@ am__ceph_tpbench_SOURCES_DIST = test/bench/tp_bench.cc \
 ceph_tpbench_OBJECTS = $(am_ceph_tpbench_OBJECTS)
 @ENABLE_CLIENT_TRUE@@ENABLE_SERVER_TRUE@@WITH_RADOS_TRUE at ceph_tpbench_DEPENDENCIES = $(LIBRADOS) \
 @ENABLE_CLIENT_TRUE@@ENABLE_SERVER_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_1) \
- at ENABLE_CLIENT_TRUE@@ENABLE_SERVER_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_14) \
+ at ENABLE_CLIENT_TRUE@@ENABLE_SERVER_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_16) \
 @ENABLE_CLIENT_TRUE@@ENABLE_SERVER_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_10)
 am__ceph_xattr_bench_SOURCES_DIST = test/xattr_bench.cc
 @ENABLE_SERVER_TRUE at am_ceph_xattr_bench_OBJECTS = test/ceph_xattr_bench-xattr_bench.$(OBJEXT)
 ceph_xattr_bench_OBJECTS = $(am_ceph_xattr_bench_OBJECTS)
 @ENABLE_SERVER_TRUE at ceph_xattr_bench_DEPENDENCIES =  \
- at ENABLE_SERVER_TRUE@	$(am__DEPENDENCIES_14) \
- at ENABLE_SERVER_TRUE@	$(am__DEPENDENCIES_19) \
+ at ENABLE_SERVER_TRUE@	$(am__DEPENDENCIES_16) \
+ at ENABLE_SERVER_TRUE@	$(am__DEPENDENCIES_24) \
 @ENABLE_SERVER_TRUE@	$(am__DEPENDENCIES_10)
 ceph_xattr_bench_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
 	$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \
@@ -4588,23 +4875,26 @@ am__cephfs_SOURCES_DIST = cephfs.cc
 cephfs_OBJECTS = $(am_cephfs_OBJECTS)
 @ENABLE_CLIENT_TRUE@@WITH_CEPHFS_TRUE@@WITH_RADOS_TRUE at cephfs_DEPENDENCIES = $(am__DEPENDENCIES_4)
 am__cephfs_data_scan_SOURCES_DIST = tools/cephfs/cephfs-data-scan.cc \
-	tools/cephfs/DataScan.cc tools/cephfs/MDSUtility.cc
+	tools/cephfs/DataScan.cc tools/cephfs/RoleSelector.cc \
+	tools/cephfs/MDSUtility.cc
 @ENABLE_CLIENT_TRUE@@ENABLE_SERVER_TRUE@@WITH_MDS_TRUE@@WITH_RADOS_TRUE at am_cephfs_data_scan_OBJECTS = tools/cephfs/cephfs-data-scan.$(OBJEXT) \
 @ENABLE_CLIENT_TRUE@@ENABLE_SERVER_TRUE@@WITH_MDS_TRUE@@WITH_RADOS_TRUE@	tools/cephfs/DataScan.$(OBJEXT) \
+ at ENABLE_CLIENT_TRUE@@ENABLE_SERVER_TRUE@@WITH_MDS_TRUE@@WITH_RADOS_TRUE@	tools/cephfs/RoleSelector.$(OBJEXT) \
 @ENABLE_CLIENT_TRUE@@ENABLE_SERVER_TRUE@@WITH_MDS_TRUE@@WITH_RADOS_TRUE@	tools/cephfs/MDSUtility.$(OBJEXT)
 cephfs_data_scan_OBJECTS = $(am_cephfs_data_scan_OBJECTS)
- at ENABLE_CLIENT_TRUE@@ENABLE_SERVER_TRUE@@WITH_MDS_TRUE@@WITH_RADOS_TRUE at cephfs_data_scan_DEPENDENCIES = $(am__DEPENDENCIES_16) \
+ at ENABLE_CLIENT_TRUE@@ENABLE_SERVER_TRUE@@WITH_MDS_TRUE@@WITH_RADOS_TRUE at cephfs_data_scan_DEPENDENCIES = $(am__DEPENDENCIES_21) \
 @ENABLE_CLIENT_TRUE@@ENABLE_SERVER_TRUE@@WITH_MDS_TRUE@@WITH_RADOS_TRUE@	libcls_cephfs_client.la \
 @ENABLE_CLIENT_TRUE@@ENABLE_SERVER_TRUE@@WITH_MDS_TRUE@@WITH_RADOS_TRUE@	$(LIBRADOS) \
 @ENABLE_CLIENT_TRUE@@ENABLE_SERVER_TRUE@@WITH_MDS_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_10)
 am__cephfs_journal_tool_SOURCES_DIST =  \
 	tools/cephfs/cephfs-journal-tool.cc \
-	tools/cephfs/JournalTool.cc tools/cephfs/JournalFilter.cc \
-	tools/cephfs/JournalScanner.cc tools/cephfs/EventOutput.cc \
-	tools/cephfs/Dumper.cc tools/cephfs/Resetter.cc \
-	tools/cephfs/MDSUtility.cc
+	tools/cephfs/JournalTool.cc tools/cephfs/RoleSelector.cc \
+	tools/cephfs/JournalFilter.cc tools/cephfs/JournalScanner.cc \
+	tools/cephfs/EventOutput.cc tools/cephfs/Dumper.cc \
+	tools/cephfs/Resetter.cc tools/cephfs/MDSUtility.cc
 @ENABLE_CLIENT_TRUE@@ENABLE_SERVER_TRUE@@WITH_MDS_TRUE@@WITH_RADOS_TRUE at am_cephfs_journal_tool_OBJECTS = tools/cephfs/cephfs-journal-tool.$(OBJEXT) \
 @ENABLE_CLIENT_TRUE@@ENABLE_SERVER_TRUE@@WITH_MDS_TRUE@@WITH_RADOS_TRUE@	tools/cephfs/JournalTool.$(OBJEXT) \
+ at ENABLE_CLIENT_TRUE@@ENABLE_SERVER_TRUE@@WITH_MDS_TRUE@@WITH_RADOS_TRUE@	tools/cephfs/RoleSelector.$(OBJEXT) \
 @ENABLE_CLIENT_TRUE@@ENABLE_SERVER_TRUE@@WITH_MDS_TRUE@@WITH_RADOS_TRUE@	tools/cephfs/JournalFilter.$(OBJEXT) \
 @ENABLE_CLIENT_TRUE@@ENABLE_SERVER_TRUE@@WITH_MDS_TRUE@@WITH_RADOS_TRUE@	tools/cephfs/JournalScanner.$(OBJEXT) \
 @ENABLE_CLIENT_TRUE@@ENABLE_SERVER_TRUE@@WITH_MDS_TRUE@@WITH_RADOS_TRUE@	tools/cephfs/EventOutput.$(OBJEXT) \
@@ -4612,17 +4902,18 @@ am__cephfs_journal_tool_SOURCES_DIST =  \
 @ENABLE_CLIENT_TRUE@@ENABLE_SERVER_TRUE@@WITH_MDS_TRUE@@WITH_RADOS_TRUE@	tools/cephfs/Resetter.$(OBJEXT) \
 @ENABLE_CLIENT_TRUE@@ENABLE_SERVER_TRUE@@WITH_MDS_TRUE@@WITH_RADOS_TRUE@	tools/cephfs/MDSUtility.$(OBJEXT)
 cephfs_journal_tool_OBJECTS = $(am_cephfs_journal_tool_OBJECTS)
- at ENABLE_CLIENT_TRUE@@ENABLE_SERVER_TRUE@@WITH_MDS_TRUE@@WITH_RADOS_TRUE at cephfs_journal_tool_DEPENDENCIES = $(am__DEPENDENCIES_16) \
+ at ENABLE_CLIENT_TRUE@@ENABLE_SERVER_TRUE@@WITH_MDS_TRUE@@WITH_RADOS_TRUE at cephfs_journal_tool_DEPENDENCIES = $(am__DEPENDENCIES_21) \
 @ENABLE_CLIENT_TRUE@@ENABLE_SERVER_TRUE@@WITH_MDS_TRUE@@WITH_RADOS_TRUE@	$(LIBRADOS) \
 @ENABLE_CLIENT_TRUE@@ENABLE_SERVER_TRUE@@WITH_MDS_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_10)
 am__cephfs_table_tool_SOURCES_DIST =  \
 	tools/cephfs/cephfs-table-tool.cc tools/cephfs/TableTool.cc \
-	tools/cephfs/MDSUtility.cc
+	tools/cephfs/RoleSelector.cc tools/cephfs/MDSUtility.cc
 @ENABLE_CLIENT_TRUE@@ENABLE_SERVER_TRUE@@WITH_MDS_TRUE@@WITH_RADOS_TRUE at am_cephfs_table_tool_OBJECTS = tools/cephfs/cephfs-table-tool.$(OBJEXT) \
 @ENABLE_CLIENT_TRUE@@ENABLE_SERVER_TRUE@@WITH_MDS_TRUE@@WITH_RADOS_TRUE@	tools/cephfs/TableTool.$(OBJEXT) \
+ at ENABLE_CLIENT_TRUE@@ENABLE_SERVER_TRUE@@WITH_MDS_TRUE@@WITH_RADOS_TRUE@	tools/cephfs/RoleSelector.$(OBJEXT) \
 @ENABLE_CLIENT_TRUE@@ENABLE_SERVER_TRUE@@WITH_MDS_TRUE@@WITH_RADOS_TRUE@	tools/cephfs/MDSUtility.$(OBJEXT)
 cephfs_table_tool_OBJECTS = $(am_cephfs_table_tool_OBJECTS)
- at ENABLE_CLIENT_TRUE@@ENABLE_SERVER_TRUE@@WITH_MDS_TRUE@@WITH_RADOS_TRUE at cephfs_table_tool_DEPENDENCIES = $(am__DEPENDENCIES_16) \
+ at ENABLE_CLIENT_TRUE@@ENABLE_SERVER_TRUE@@WITH_MDS_TRUE@@WITH_RADOS_TRUE at cephfs_table_tool_DEPENDENCIES = $(am__DEPENDENCIES_21) \
 @ENABLE_CLIENT_TRUE@@ENABLE_SERVER_TRUE@@WITH_MDS_TRUE@@WITH_RADOS_TRUE@	$(LIBRADOS) \
 @ENABLE_CLIENT_TRUE@@ENABLE_SERVER_TRUE@@WITH_MDS_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_10)
 am_crushtool_OBJECTS = tools/crushtool.$(OBJEXT)
@@ -4634,9 +4925,9 @@ am__get_command_descriptions_SOURCES_DIST =  \
 get_command_descriptions_OBJECTS =  \
 	$(am_get_command_descriptions_OBJECTS)
 @ENABLE_SERVER_TRUE@@WITH_MON_TRUE at get_command_descriptions_DEPENDENCIES =  \
- at ENABLE_SERVER_TRUE@@WITH_MON_TRUE@	$(am__DEPENDENCIES_17) \
+ at ENABLE_SERVER_TRUE@@WITH_MON_TRUE@	$(am__DEPENDENCIES_22) \
 @ENABLE_SERVER_TRUE@@WITH_MON_TRUE@	$(LIBMON_TYPES) \
- at ENABLE_SERVER_TRUE@@WITH_MON_TRUE@	$(am__DEPENDENCIES_14) \
+ at ENABLE_SERVER_TRUE@@WITH_MON_TRUE@	$(am__DEPENDENCIES_16) \
 @ENABLE_SERVER_TRUE@@WITH_MON_TRUE@	$(am__DEPENDENCIES_4) \
 @ENABLE_SERVER_TRUE@@WITH_MON_TRUE@	$(am__DEPENDENCIES_10)
 am__librados_config_SOURCES_DIST = librados-config.cc
@@ -4645,6 +4936,70 @@ librados_config_OBJECTS = $(am_librados_config_OBJECTS)
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE at librados_config_DEPENDENCIES =  \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@	$(LIBRADOS) \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_10)
+am__librgw_file_SOURCES_DIST = test/librgw_file.cc
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE at am_librgw_file_OBJECTS = test/librgw_file-librgw_file.$(OBJEXT)
+librgw_file_OBJECTS = $(am_librgw_file_OBJECTS)
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE at librgw_file_DEPENDENCIES = $(am__DEPENDENCIES_24) \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	librgw.la \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	librados.la \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_1) \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_10) \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_3)
+librgw_file_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \
+	$(LIBTOOLFLAGS) --mode=link $(CXXLD) $(librgw_file_CXXFLAGS) \
+	$(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
+am__librgw_file_aw_SOURCES_DIST = test/librgw_file_aw.cc
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE at am_librgw_file_aw_OBJECTS = test/librgw_file_aw-librgw_file_aw.$(OBJEXT)
+librgw_file_aw_OBJECTS = $(am_librgw_file_aw_OBJECTS)
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE at librgw_file_aw_DEPENDENCIES = $(am__DEPENDENCIES_24) \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	librgw.la \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	librados.la \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_1) \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_10) \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_3)
+librgw_file_aw_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
+	$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \
+	$(librgw_file_aw_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) \
+	$(LDFLAGS) -o $@
+am__librgw_file_cd_SOURCES_DIST = test/librgw_file_cd.cc
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE at am_librgw_file_cd_OBJECTS = test/librgw_file_cd-librgw_file_cd.$(OBJEXT)
+librgw_file_cd_OBJECTS = $(am_librgw_file_cd_OBJECTS)
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE at librgw_file_cd_DEPENDENCIES = $(am__DEPENDENCIES_24) \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	librgw.la \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	librados.la \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_1) \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_10) \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_3)
+librgw_file_cd_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
+	$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \
+	$(librgw_file_cd_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) \
+	$(LDFLAGS) -o $@
+am__librgw_file_gp_SOURCES_DIST = test/librgw_file_gp.cc
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE at am_librgw_file_gp_OBJECTS = test/librgw_file_gp-librgw_file_gp.$(OBJEXT)
+librgw_file_gp_OBJECTS = $(am_librgw_file_gp_OBJECTS)
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE at librgw_file_gp_DEPENDENCIES = $(am__DEPENDENCIES_24) \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	librgw.la \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	librados.la \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_1) \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_10) \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_3)
+librgw_file_gp_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
+	$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \
+	$(librgw_file_gp_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) \
+	$(LDFLAGS) -o $@
+am__librgw_file_nfsns_SOURCES_DIST = test/librgw_file_nfsns.cc
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE at am_librgw_file_nfsns_OBJECTS = test/librgw_file_nfsns-librgw_file_nfsns.$(OBJEXT)
+librgw_file_nfsns_OBJECTS = $(am_librgw_file_nfsns_OBJECTS)
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE at librgw_file_nfsns_DEPENDENCIES = $(am__DEPENDENCIES_24) \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	librgw.la \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	librados.la \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_1) \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_10) \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_3)
+librgw_file_nfsns_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
+	$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \
+	$(librgw_file_nfsns_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) \
+	$(LDFLAGS) -o $@
 am_monmaptool_OBJECTS = tools/monmaptool.$(OBJEXT)
 monmaptool_OBJECTS = $(am_monmaptool_OBJECTS)
 monmaptool_DEPENDENCIES = $(am__DEPENDENCIES_10)
@@ -4671,50 +5026,43 @@ rados_OBJECTS = $(am_rados_OBJECTS)
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@	$(LIBRADOS) \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@	$(LIBRADOSSTRIPER) \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_10)
-am__radosgw_SOURCES_DIST = rgw/rgw_resolve.cc rgw/rgw_rest.cc \
-	rgw/rgw_rest_swift.cc rgw/rgw_rest_s3.cc rgw/rgw_rest_usage.cc \
-	rgw/rgw_rest_user.cc rgw/rgw_rest_bucket.cc \
-	rgw/rgw_rest_metadata.cc rgw/rgw_replica_log.cc \
-	rgw/rgw_rest_log.cc rgw/rgw_rest_opstate.cc \
-	rgw/rgw_rest_replica_log.cc rgw/rgw_rest_config.cc \
-	rgw/rgw_http_client.cc rgw/rgw_swift.cc rgw/rgw_swift_auth.cc \
-	rgw/rgw_loadgen.cc rgw/rgw_main.cc
- at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE at am_radosgw_OBJECTS = rgw/rgw_resolve.$(OBJEXT) \
- at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/rgw_rest.$(OBJEXT) \
- at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/rgw_rest_swift.$(OBJEXT) \
- at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/rgw_rest_s3.$(OBJEXT) \
- at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/rgw_rest_usage.$(OBJEXT) \
- at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/rgw_rest_user.$(OBJEXT) \
- at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/rgw_rest_bucket.$(OBJEXT) \
- at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/rgw_rest_metadata.$(OBJEXT) \
- at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/rgw_replica_log.$(OBJEXT) \
- at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/rgw_rest_log.$(OBJEXT) \
- at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/rgw_rest_opstate.$(OBJEXT) \
- at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/rgw_rest_replica_log.$(OBJEXT) \
- at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/rgw_rest_config.$(OBJEXT) \
- at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/rgw_http_client.$(OBJEXT) \
- at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/rgw_swift.$(OBJEXT) \
- at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/rgw_swift_auth.$(OBJEXT) \
- at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/rgw_loadgen.$(OBJEXT) \
+am__radosgw_SOURCES_DIST = rgw/rgw_fcgi_process.cc \
+	rgw/rgw_loadgen_process.cc rgw/rgw_civetweb.cc \
+	rgw/rgw_civetweb_frontend.cc rgw/rgw_civetweb_log.cc \
+	civetweb/src/civetweb.c rgw/rgw_main.cc
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE at am_radosgw_OBJECTS = rgw/rgw_fcgi_process.$(OBJEXT) \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/rgw_loadgen_process.$(OBJEXT) \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/rgw_civetweb.$(OBJEXT) \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/rgw_civetweb_frontend.$(OBJEXT) \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/rgw_civetweb_log.$(OBJEXT) \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	civetweb/src/radosgw-civetweb.$(OBJEXT) \
 @ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/rgw_main.$(OBJEXT)
 radosgw_OBJECTS = $(am_radosgw_OBJECTS)
- at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE at radosgw_DEPENDENCIES = $(am__DEPENDENCIES_20) \
+am__DEPENDENCIES_25 = $(am__DEPENDENCIES_1)
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE at radosgw_DEPENDENCIES = $(am__DEPENDENCIES_17) \
 @ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	$(LIBCIVETWEB) \
- at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_22) \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_25) \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_12) \
 @ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_1) \
 @ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_10)
 am__radosgw_admin_SOURCES_DIST = rgw/rgw_admin.cc rgw/rgw_orphan.cc
 @ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE at am_radosgw_admin_OBJECTS = rgw/rgw_admin.$(OBJEXT) \
 @ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/rgw_orphan.$(OBJEXT)
 radosgw_admin_OBJECTS = $(am_radosgw_admin_OBJECTS)
- at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE at radosgw_admin_DEPENDENCIES = $(am__DEPENDENCIES_20) \
- at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_22) \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE at radosgw_admin_DEPENDENCIES = $(am__DEPENDENCIES_17) \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_12) \
 @ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_10)
 am__radosgw_object_expirer_SOURCES_DIST = rgw/rgw_object_expirer.cc
 @ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE at am_radosgw_object_expirer_OBJECTS = rgw/rgw_object_expirer.$(OBJEXT)
 radosgw_object_expirer_OBJECTS = $(am_radosgw_object_expirer_OBJECTS)
- at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE at radosgw_object_expirer_DEPENDENCIES = $(am__DEPENDENCIES_20) \
- at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_22) \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE at radosgw_object_expirer_DEPENDENCIES = $(am__DEPENDENCIES_17) \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_12) \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_10)
+am__radosgw_token_SOURCES_DIST = rgw/rgw_token.cc
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE at am_radosgw_token_OBJECTS = rgw/rgw_token.$(OBJEXT)
+radosgw_token_OBJECTS = $(am_radosgw_token_OBJECTS)
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE at radosgw_token_DEPENDENCIES = $(am__DEPENDENCIES_17) \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_12) \
 @ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_10)
 am__rbd_SOURCES_DIST = tools/rbd/rbd.cc tools/rbd/ArgumentTypes.cc \
 	tools/rbd/IndentStream.cc tools/rbd/OptionPrinter.cc \
@@ -4727,13 +5075,15 @@ am__rbd_SOURCES_DIST = tools/rbd/rbd.cc tools/rbd/ArgumentTypes.cc \
 	tools/rbd/action/Flatten.cc tools/rbd/action/ImageMeta.cc \
 	tools/rbd/action/Import.cc tools/rbd/action/ImportDiff.cc \
 	tools/rbd/action/Info.cc tools/rbd/action/Journal.cc \
-	tools/rbd/action/Kernel.cc tools/rbd/action/Nbd.cc \
 	tools/rbd/action/List.cc tools/rbd/action/Lock.cc \
 	tools/rbd/action/MergeDiff.cc tools/rbd/action/MirrorPool.cc \
-	tools/rbd/action/ObjectMap.cc tools/rbd/action/Remove.cc \
-	tools/rbd/action/Rename.cc tools/rbd/action/Resize.cc \
-	tools/rbd/action/Snap.cc tools/rbd/action/Status.cc \
-	tools/rbd/action/Watch.cc
+	tools/rbd/action/MirrorImage.cc tools/rbd/action/ObjectMap.cc \
+	tools/rbd/action/Remove.cc tools/rbd/action/Rename.cc \
+	tools/rbd/action/Resize.cc tools/rbd/action/Snap.cc \
+	tools/rbd/action/Status.cc tools/rbd/action/Watch.cc \
+	tools/rbd/action/Kernel.cc tools/rbd/action/Nbd.cc
+ at ENABLE_CLIENT_TRUE@@LINUX_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE at am__objects_46 = tools/rbd/action/Kernel.$(OBJEXT) \
+ at ENABLE_CLIENT_TRUE@@LINUX_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	tools/rbd/action/Nbd.$(OBJEXT)
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE at am_rbd_OBJECTS = tools/rbd/rbd.$(OBJEXT) \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	tools/rbd/ArgumentTypes.$(OBJEXT) \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	tools/rbd/IndentStream.$(OBJEXT) \
@@ -4756,29 +5106,29 @@ am__rbd_SOURCES_DIST = tools/rbd/rbd.cc tools/rbd/ArgumentTypes.cc \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	tools/rbd/action/ImportDiff.$(OBJEXT) \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	tools/rbd/action/Info.$(OBJEXT) \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	tools/rbd/action/Journal.$(OBJEXT) \
- at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	tools/rbd/action/Kernel.$(OBJEXT) \
- at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	tools/rbd/action/Nbd.$(OBJEXT) \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	tools/rbd/action/List.$(OBJEXT) \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	tools/rbd/action/Lock.$(OBJEXT) \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	tools/rbd/action/MergeDiff.$(OBJEXT) \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	tools/rbd/action/MirrorPool.$(OBJEXT) \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	tools/rbd/action/MirrorImage.$(OBJEXT) \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	tools/rbd/action/ObjectMap.$(OBJEXT) \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	tools/rbd/action/Remove.$(OBJEXT) \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	tools/rbd/action/Rename.$(OBJEXT) \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	tools/rbd/action/Resize.$(OBJEXT) \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	tools/rbd/action/Snap.$(OBJEXT) \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	tools/rbd/action/Status.$(OBJEXT) \
- at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	tools/rbd/action/Watch.$(OBJEXT)
+ at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	tools/rbd/action/Watch.$(OBJEXT) \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	$(am__objects_46)
 rbd_OBJECTS = $(am_rbd_OBJECTS)
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE at rbd_DEPENDENCIES = libjournal.la \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	libcls_journal_client.la \
- at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	$(LIBKRBD) \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	$(LIBRBD) \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	$(LIBRBD_TYPES) \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	$(LIBRADOS) \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	$(am__DEPENDENCIES_10) \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	$(am__DEPENDENCIES_1) \
- at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	$(am__DEPENDENCIES_1)
+ at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	$(am__DEPENDENCIES_1) \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	$(am__append_269)
 am__rbd_fuse_SOURCES_DIST = rbd_fuse/rbd-fuse.cc
 @ENABLE_CLIENT_TRUE@@WITH_FUSE_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE at am_rbd_fuse_OBJECTS = rbd_fuse/rbd_fuse-rbd-fuse.$(OBJEXT)
 rbd_fuse_OBJECTS = $(am_rbd_fuse_OBJECTS)
@@ -4839,7 +5189,7 @@ am__simple_client_SOURCES_DIST = test/messenger/simple_client.cc \
 @ENABLE_SERVER_TRUE@@ENABLE_XIO_TRUE@	test/messenger/simple_client-simple_dispatcher.$(OBJEXT)
 simple_client_OBJECTS = $(am_simple_client_OBJECTS)
 @ENABLE_SERVER_TRUE@@ENABLE_XIO_TRUE at simple_client_DEPENDENCIES =  \
- at ENABLE_SERVER_TRUE@@ENABLE_XIO_TRUE@	$(am__DEPENDENCIES_14) \
+ at ENABLE_SERVER_TRUE@@ENABLE_XIO_TRUE@	$(am__DEPENDENCIES_16) \
 @ENABLE_SERVER_TRUE@@ENABLE_XIO_TRUE@	$(am__DEPENDENCIES_4) \
 @ENABLE_SERVER_TRUE@@ENABLE_XIO_TRUE@	$(am__DEPENDENCIES_10) \
 @ENABLE_SERVER_TRUE@@ENABLE_XIO_TRUE@	$(am__DEPENDENCIES_1) \
@@ -4855,7 +5205,7 @@ am__simple_server_SOURCES_DIST = test/messenger/simple_server.cc \
 @ENABLE_SERVER_TRUE@@ENABLE_XIO_TRUE@	test/messenger/simple_server-simple_dispatcher.$(OBJEXT)
 simple_server_OBJECTS = $(am_simple_server_OBJECTS)
 @ENABLE_SERVER_TRUE@@ENABLE_XIO_TRUE at simple_server_DEPENDENCIES =  \
- at ENABLE_SERVER_TRUE@@ENABLE_XIO_TRUE@	$(am__DEPENDENCIES_14) \
+ at ENABLE_SERVER_TRUE@@ENABLE_XIO_TRUE@	$(am__DEPENDENCIES_16) \
 @ENABLE_SERVER_TRUE@@ENABLE_XIO_TRUE@	$(am__DEPENDENCIES_4) \
 @ENABLE_SERVER_TRUE@@ENABLE_XIO_TRUE@	$(am__DEPENDENCIES_10) \
 @ENABLE_SERVER_TRUE@@ENABLE_XIO_TRUE@	$(am__DEPENDENCIES_1) \
@@ -4868,13 +5218,13 @@ simple_server_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
 am__test_build_libcephfs_SOURCES_DIST = test/buildtest_skeleton.cc \
 	osdc/Objecter.cc osdc/ObjectCacher.cc osdc/Filer.cc \
 	osdc/Striper.cc osdc/Journaler.cc
-am__objects_46 = osdc/test_build_libcephfs-Objecter.$(OBJEXT) \
+am__objects_47 = osdc/test_build_libcephfs-Objecter.$(OBJEXT) \
 	osdc/test_build_libcephfs-ObjectCacher.$(OBJEXT) \
 	osdc/test_build_libcephfs-Filer.$(OBJEXT) \
 	osdc/test_build_libcephfs-Striper.$(OBJEXT) \
 	osdc/test_build_libcephfs-Journaler.$(OBJEXT)
 @ENABLE_CLIENT_TRUE@@WITH_BUILD_TESTS_TRUE@@WITH_CEPHFS_TRUE@@WITH_RADOS_TRUE at am_test_build_libcephfs_OBJECTS = test/test_build_libcephfs-buildtest_skeleton.$(OBJEXT) \
- at ENABLE_CLIENT_TRUE@@WITH_BUILD_TESTS_TRUE@@WITH_CEPHFS_TRUE@@WITH_RADOS_TRUE@	$(am__objects_46)
+ at ENABLE_CLIENT_TRUE@@WITH_BUILD_TESTS_TRUE@@WITH_CEPHFS_TRUE@@WITH_RADOS_TRUE@	$(am__objects_47)
 test_build_libcephfs_OBJECTS = $(am_test_build_libcephfs_OBJECTS)
 @ENABLE_CLIENT_TRUE@@WITH_BUILD_TESTS_TRUE@@WITH_CEPHFS_TRUE@@WITH_RADOS_TRUE at test_build_libcephfs_DEPENDENCIES = $(LIBCEPHFS) \
 @ENABLE_CLIENT_TRUE@@WITH_BUILD_TESTS_TRUE@@WITH_CEPHFS_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_1) \
@@ -4886,9 +5236,9 @@ test_build_libcephfs_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
 	$(test_build_libcephfs_LDFLAGS) $(LDFLAGS) -o $@
 am__test_build_libcommon_SOURCES_DIST = test/buildtest_skeleton.cc \
 	common/buffer.cc
-am__objects_47 = common/test_build_libcommon-buffer.$(OBJEXT)
+am__objects_48 = common/test_build_libcommon-buffer.$(OBJEXT)
 @WITH_BUILD_TESTS_TRUE at am_test_build_libcommon_OBJECTS = test/test_build_libcommon-buildtest_skeleton.$(OBJEXT) \
- at WITH_BUILD_TESTS_TRUE@	$(am__objects_47)
+ at WITH_BUILD_TESTS_TRUE@	$(am__objects_48)
 test_build_libcommon_OBJECTS = $(am_test_build_libcommon_OBJECTS)
 @WITH_BUILD_TESTS_TRUE at test_build_libcommon_DEPENDENCIES =  \
 @WITH_BUILD_TESTS_TRUE@	$(am__DEPENDENCIES_5) \
@@ -4901,10 +5251,10 @@ test_build_libcommon_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
 	$(test_build_libcommon_LDFLAGS) $(LDFLAGS) -o $@
 am__test_build_librados_SOURCES_DIST = test/buildtest_skeleton.cc \
 	common/buffer.cc librados/librados.cc
- at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE at am__objects_48 = common/test_build_librados-buffer.$(OBJEXT) \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE at am__objects_49 = common/test_build_librados-buffer.$(OBJEXT) \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@	librados/test_build_librados-librados.$(OBJEXT)
 @ENABLE_CLIENT_TRUE@@WITH_BUILD_TESTS_TRUE@@WITH_RADOS_TRUE at am_test_build_librados_OBJECTS = test/test_build_librados-buildtest_skeleton.$(OBJEXT) \
- at ENABLE_CLIENT_TRUE@@WITH_BUILD_TESTS_TRUE@@WITH_RADOS_TRUE@	$(am__objects_48)
+ at ENABLE_CLIENT_TRUE@@WITH_BUILD_TESTS_TRUE@@WITH_RADOS_TRUE@	$(am__objects_49)
 test_build_librados_OBJECTS = $(am_test_build_librados_OBJECTS)
 @ENABLE_CLIENT_TRUE@@WITH_BUILD_TESTS_TRUE@@WITH_RADOS_TRUE at test_build_librados_DEPENDENCIES = $(am__DEPENDENCIES_7) \
 @ENABLE_CLIENT_TRUE@@WITH_BUILD_TESTS_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_1) \
@@ -4915,61 +5265,106 @@ test_build_librados_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
 	$(test_build_librados_CXXFLAGS) $(CXXFLAGS) \
 	$(test_build_librados_LDFLAGS) $(LDFLAGS) -o $@
 am__test_build_librgw_SOURCES_DIST = test/buildtest_skeleton.cc \
-	rgw/librgw.cc rgw/rgw_acl.cc rgw/rgw_acl_s3.cc \
-	rgw/rgw_acl_swift.cc rgw/rgw_client_io.cc rgw/rgw_fcgi.cc \
-	rgw/rgw_xml.cc rgw/rgw_usage.cc rgw/rgw_json_enc.cc \
-	rgw/rgw_xml_enc.cc rgw/rgw_user.cc rgw/rgw_bucket.cc \
-	rgw/rgw_tools.cc rgw/rgw_rados.cc rgw/rgw_http_client.cc \
-	rgw/rgw_rest_client.cc rgw/rgw_rest_conn.cc rgw/rgw_op.cc \
-	rgw/rgw_basic_types.cc rgw/rgw_common.cc rgw/rgw_cache.cc \
-	rgw/rgw_formats.cc rgw/rgw_log.cc rgw/rgw_multi.cc \
-	rgw/rgw_policy_s3.cc rgw/rgw_gc.cc rgw/rgw_multi_del.cc \
-	rgw/rgw_env.cc rgw/rgw_cors.cc rgw/rgw_cors_s3.cc \
-	rgw/rgw_auth_s3.cc rgw/rgw_metadata.cc rgw/rgw_replica_log.cc \
-	rgw/rgw_keystone.cc rgw/rgw_quota.cc rgw/rgw_dencoder.cc \
-	rgw/rgw_object_expirer_core.cc rgw/rgw_website.cc
- at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE at am__objects_49 = rgw/test_build_librgw-librgw.$(OBJEXT) \
- at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/test_build_librgw-rgw_acl.$(OBJEXT) \
+	rgw/rgw_acl.cc rgw/rgw_acl_s3.cc rgw/rgw_acl_swift.cc \
+	rgw/rgw_coroutine.cc rgw/rgw_cr_rados.cc rgw/rgw_tools.cc \
+	rgw/rgw_basic_types.cc rgw/rgw_bucket.cc rgw/rgw_cache.cc \
+	rgw/rgw_client_io.cc rgw/rgw_common.cc rgw/rgw_cors.cc \
+	rgw/rgw_cors_s3.cc rgw/rgw_dencoder.cc rgw/rgw_env.cc \
+	rgw/rgw_fcgi.cc rgw/rgw_formats.cc rgw/rgw_frontend.cc \
+	rgw/rgw_gc.cc rgw/rgw_http_client.cc rgw/rgw_json_enc.cc \
+	rgw/rgw_keystone.cc rgw/rgw_loadgen.cc rgw/rgw_log.cc \
+	rgw/rgw_metadata.cc rgw/rgw_multi.cc rgw/rgw_multi_del.cc \
+	rgw/rgw_auth_s3.cc rgw/rgw_period_history.cc \
+	rgw/rgw_period_puller.cc rgw/rgw_period_pusher.cc \
+	rgw/rgw_realm_reloader.cc rgw/rgw_realm_watcher.cc \
+	rgw/rgw_sync.cc rgw/rgw_data_sync.cc \
+	rgw/rgw_object_expirer_core.cc rgw/rgw_op.cc rgw/rgw_os_lib.cc \
+	rgw/rgw_policy_s3.cc rgw/rgw_process.cc rgw/rgw_quota.cc \
+	rgw/rgw_rados.cc rgw/rgw_replica_log.cc rgw/rgw_request.cc \
+	rgw/rgw_resolve.cc rgw/rgw_rest_bucket.cc rgw/rgw_rest.cc \
+	rgw/rgw_rest_client.cc rgw/rgw_rest_config.cc \
+	rgw/rgw_rest_conn.cc rgw/rgw_rest_log.cc \
+	rgw/rgw_rest_metadata.cc rgw/rgw_rest_opstate.cc \
+	rgw/rgw_rest_realm.cc rgw/rgw_rest_replica_log.cc \
+	rgw/rgw_rest_s3.cc rgw/rgw_rest_swift.cc rgw/rgw_rest_usage.cc \
+	rgw/rgw_rest_user.cc rgw/rgw_swift_auth.cc rgw/rgw_swift.cc \
+	rgw/rgw_usage.cc rgw/rgw_user.cc rgw/rgw_file.cc rgw/librgw.cc \
+	rgw/rgw_xml.cc rgw/rgw_xml_enc.cc rgw/rgw_website.cc \
+	rgw/rgw_ldap.cc
+ at ENABLE_CLIENT_TRUE@@WITH_OPENLDAP_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE at am__objects_50 = rgw/test_build_librgw-rgw_ldap.$(OBJEXT)
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE at am__objects_51 = rgw/test_build_librgw-rgw_acl.$(OBJEXT) \
 @ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/test_build_librgw-rgw_acl_s3.$(OBJEXT) \
 @ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/test_build_librgw-rgw_acl_swift.$(OBJEXT) \
- at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/test_build_librgw-rgw_client_io.$(OBJEXT) \
- at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/test_build_librgw-rgw_fcgi.$(OBJEXT) \
- at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/test_build_librgw-rgw_xml.$(OBJEXT) \
- at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/test_build_librgw-rgw_usage.$(OBJEXT) \
- at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/test_build_librgw-rgw_json_enc.$(OBJEXT) \
- at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/test_build_librgw-rgw_xml_enc.$(OBJEXT) \
- at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/test_build_librgw-rgw_user.$(OBJEXT) \
- at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/test_build_librgw-rgw_bucket.$(OBJEXT) \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/test_build_librgw-rgw_coroutine.$(OBJEXT) \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/test_build_librgw-rgw_cr_rados.$(OBJEXT) \
 @ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/test_build_librgw-rgw_tools.$(OBJEXT) \
- at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/test_build_librgw-rgw_rados.$(OBJEXT) \
- at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/test_build_librgw-rgw_http_client.$(OBJEXT) \
- at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/test_build_librgw-rgw_rest_client.$(OBJEXT) \
- at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/test_build_librgw-rgw_rest_conn.$(OBJEXT) \
- at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/test_build_librgw-rgw_op.$(OBJEXT) \
 @ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/test_build_librgw-rgw_basic_types.$(OBJEXT) \
- at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/test_build_librgw-rgw_common.$(OBJEXT) \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/test_build_librgw-rgw_bucket.$(OBJEXT) \
 @ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/test_build_librgw-rgw_cache.$(OBJEXT) \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/test_build_librgw-rgw_client_io.$(OBJEXT) \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/test_build_librgw-rgw_common.$(OBJEXT) \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/test_build_librgw-rgw_cors.$(OBJEXT) \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/test_build_librgw-rgw_cors_s3.$(OBJEXT) \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/test_build_librgw-rgw_dencoder.$(OBJEXT) \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/test_build_librgw-rgw_env.$(OBJEXT) \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/test_build_librgw-rgw_fcgi.$(OBJEXT) \
 @ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/test_build_librgw-rgw_formats.$(OBJEXT) \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/test_build_librgw-rgw_frontend.$(OBJEXT) \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/test_build_librgw-rgw_gc.$(OBJEXT) \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/test_build_librgw-rgw_http_client.$(OBJEXT) \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/test_build_librgw-rgw_json_enc.$(OBJEXT) \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/test_build_librgw-rgw_keystone.$(OBJEXT) \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/test_build_librgw-rgw_loadgen.$(OBJEXT) \
 @ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/test_build_librgw-rgw_log.$(OBJEXT) \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/test_build_librgw-rgw_metadata.$(OBJEXT) \
 @ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/test_build_librgw-rgw_multi.$(OBJEXT) \
- at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/test_build_librgw-rgw_policy_s3.$(OBJEXT) \
- at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/test_build_librgw-rgw_gc.$(OBJEXT) \
 @ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/test_build_librgw-rgw_multi_del.$(OBJEXT) \
- at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/test_build_librgw-rgw_env.$(OBJEXT) \
- at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/test_build_librgw-rgw_cors.$(OBJEXT) \
- at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/test_build_librgw-rgw_cors_s3.$(OBJEXT) \
 @ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/test_build_librgw-rgw_auth_s3.$(OBJEXT) \
- at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/test_build_librgw-rgw_metadata.$(OBJEXT) \
- at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/test_build_librgw-rgw_replica_log.$(OBJEXT) \
- at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/test_build_librgw-rgw_keystone.$(OBJEXT) \
- at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/test_build_librgw-rgw_quota.$(OBJEXT) \
- at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/test_build_librgw-rgw_dencoder.$(OBJEXT) \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/test_build_librgw-rgw_period_history.$(OBJEXT) \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/test_build_librgw-rgw_period_puller.$(OBJEXT) \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/test_build_librgw-rgw_period_pusher.$(OBJEXT) \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/test_build_librgw-rgw_realm_reloader.$(OBJEXT) \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/test_build_librgw-rgw_realm_watcher.$(OBJEXT) \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/test_build_librgw-rgw_sync.$(OBJEXT) \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/test_build_librgw-rgw_data_sync.$(OBJEXT) \
 @ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/test_build_librgw-rgw_object_expirer_core.$(OBJEXT) \
- at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/test_build_librgw-rgw_website.$(OBJEXT)
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/test_build_librgw-rgw_op.$(OBJEXT) \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/test_build_librgw-rgw_os_lib.$(OBJEXT) \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/test_build_librgw-rgw_policy_s3.$(OBJEXT) \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/test_build_librgw-rgw_process.$(OBJEXT) \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/test_build_librgw-rgw_quota.$(OBJEXT) \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/test_build_librgw-rgw_rados.$(OBJEXT) \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/test_build_librgw-rgw_replica_log.$(OBJEXT) \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/test_build_librgw-rgw_request.$(OBJEXT) \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/test_build_librgw-rgw_resolve.$(OBJEXT) \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/test_build_librgw-rgw_rest_bucket.$(OBJEXT) \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/test_build_librgw-rgw_rest.$(OBJEXT) \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/test_build_librgw-rgw_rest_client.$(OBJEXT) \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/test_build_librgw-rgw_rest_config.$(OBJEXT) \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/test_build_librgw-rgw_rest_conn.$(OBJEXT) \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/test_build_librgw-rgw_rest_log.$(OBJEXT) \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/test_build_librgw-rgw_rest_metadata.$(OBJEXT) \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/test_build_librgw-rgw_rest_opstate.$(OBJEXT) \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/test_build_librgw-rgw_rest_realm.$(OBJEXT) \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/test_build_librgw-rgw_rest_replica_log.$(OBJEXT) \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/test_build_librgw-rgw_rest_s3.$(OBJEXT) \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/test_build_librgw-rgw_rest_swift.$(OBJEXT) \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/test_build_librgw-rgw_rest_usage.$(OBJEXT) \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/test_build_librgw-rgw_rest_user.$(OBJEXT) \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/test_build_librgw-rgw_swift_auth.$(OBJEXT) \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/test_build_librgw-rgw_swift.$(OBJEXT) \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/test_build_librgw-rgw_usage.$(OBJEXT) \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/test_build_librgw-rgw_user.$(OBJEXT) \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/test_build_librgw-rgw_file.$(OBJEXT) \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/test_build_librgw-librgw.$(OBJEXT) \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/test_build_librgw-rgw_xml.$(OBJEXT) \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/test_build_librgw-rgw_xml_enc.$(OBJEXT) \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/test_build_librgw-rgw_website.$(OBJEXT) \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	$(am__objects_50)
 @ENABLE_CLIENT_TRUE@@WITH_BUILD_TESTS_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE at am_test_build_librgw_OBJECTS = test/test_build_librgw-buildtest_skeleton.$(OBJEXT) \
- at ENABLE_CLIENT_TRUE@@WITH_BUILD_TESTS_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	$(am__objects_49)
+ at ENABLE_CLIENT_TRUE@@WITH_BUILD_TESTS_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	$(am__objects_51)
 test_build_librgw_OBJECTS = $(am_test_build_librgw_OBJECTS)
- at ENABLE_CLIENT_TRUE@@WITH_BUILD_TESTS_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE at test_build_librgw_DEPENDENCIES = $(am__DEPENDENCIES_22) \
+ at ENABLE_CLIENT_TRUE@@WITH_BUILD_TESTS_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE at test_build_librgw_DEPENDENCIES = $(am__DEPENDENCIES_12) \
 @ENABLE_CLIENT_TRUE@@WITH_BUILD_TESTS_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_1) \
 @ENABLE_CLIENT_TRUE@@WITH_BUILD_TESTS_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_1) \
 @ENABLE_CLIENT_TRUE@@WITH_BUILD_TESTS_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_3) \
@@ -4980,7 +5375,7 @@ test_build_librgw_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
 	$(test_build_librgw_LDFLAGS) $(LDFLAGS) -o $@
 am_unittest_addrs_OBJECTS = test/unittest_addrs-test_addrs.$(OBJEXT)
 unittest_addrs_OBJECTS = $(am_unittest_addrs_OBJECTS)
-unittest_addrs_DEPENDENCIES = $(am__DEPENDENCIES_19) \
+unittest_addrs_DEPENDENCIES = $(am__DEPENDENCIES_24) \
 	$(am__DEPENDENCIES_10)
 unittest_addrs_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
 	$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \
@@ -4989,7 +5384,7 @@ unittest_addrs_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
 am_unittest_admin_socket_OBJECTS =  \
 	test/unittest_admin_socket-admin_socket.$(OBJEXT)
 unittest_admin_socket_OBJECTS = $(am_unittest_admin_socket_OBJECTS)
-unittest_admin_socket_DEPENDENCIES = $(am__DEPENDENCIES_19) \
+unittest_admin_socket_DEPENDENCIES = $(am__DEPENDENCIES_24) \
 	$(am__DEPENDENCIES_10)
 unittest_admin_socket_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
 	$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \
@@ -4997,7 +5392,7 @@ unittest_admin_socket_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
 	$(LDFLAGS) -o $@
 am_unittest_arch_OBJECTS = test/unittest_arch-test_arch.$(OBJEXT)
 unittest_arch_OBJECTS = $(am_unittest_arch_OBJECTS)
-unittest_arch_DEPENDENCIES = $(am__DEPENDENCIES_19) \
+unittest_arch_DEPENDENCIES = $(am__DEPENDENCIES_24) \
 	$(am__DEPENDENCIES_10)
 unittest_arch_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
 	$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \
@@ -5006,7 +5401,7 @@ unittest_arch_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
 am_unittest_async_compressor_OBJECTS = test/common/unittest_async_compressor-test_async_compressor.$(OBJEXT)
 unittest_async_compressor_OBJECTS =  \
 	$(am_unittest_async_compressor_OBJECTS)
-unittest_async_compressor_DEPENDENCIES = $(am__DEPENDENCIES_19) \
+unittest_async_compressor_DEPENDENCIES = $(am__DEPENDENCIES_24) \
 	$(am__DEPENDENCIES_10) $(LIBCOMPRESSOR) $(am__DEPENDENCIES_4)
 unittest_async_compressor_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
 	$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \
@@ -5017,7 +5412,7 @@ am__unittest_base64_SOURCES_DIST = test/base64.cc
 unittest_base64_OBJECTS = $(am_unittest_base64_OBJECTS)
 @ENABLE_CLIENT_TRUE@@WITH_CEPHFS_TRUE@@WITH_RADOS_TRUE at unittest_base64_DEPENDENCIES = $(LIBCEPHFS) \
 @ENABLE_CLIENT_TRUE@@WITH_CEPHFS_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_10) \
- at ENABLE_CLIENT_TRUE@@WITH_CEPHFS_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_19)
+ at ENABLE_CLIENT_TRUE@@WITH_CEPHFS_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_24)
 unittest_base64_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
 	$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \
 	$(unittest_base64_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) \
@@ -5025,7 +5420,7 @@ unittest_base64_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
 am_unittest_bit_vector_OBJECTS =  \
 	test/common/unittest_bit_vector-test_bit_vector.$(OBJEXT)
 unittest_bit_vector_OBJECTS = $(am_unittest_bit_vector_OBJECTS)
-unittest_bit_vector_DEPENDENCIES = $(am__DEPENDENCIES_19) \
+unittest_bit_vector_DEPENDENCIES = $(am__DEPENDENCIES_24) \
 	$(am__DEPENDENCIES_10)
 unittest_bit_vector_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
 	$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \
@@ -5034,7 +5429,7 @@ unittest_bit_vector_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
 am_unittest_blkdev_OBJECTS =  \
 	test/common/unittest_blkdev-test_blkdev.$(OBJEXT)
 unittest_blkdev_OBJECTS = $(am_unittest_blkdev_OBJECTS)
-unittest_blkdev_DEPENDENCIES = $(am__DEPENDENCIES_19) \
+unittest_blkdev_DEPENDENCIES = $(am__DEPENDENCIES_24) \
 	$(am__DEPENDENCIES_10)
 unittest_blkdev_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
 	$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \
@@ -5043,7 +5438,7 @@ unittest_blkdev_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
 am_unittest_bloom_filter_OBJECTS =  \
 	test/common/unittest_bloom_filter-test_bloom_filter.$(OBJEXT)
 unittest_bloom_filter_OBJECTS = $(am_unittest_bloom_filter_OBJECTS)
-unittest_bloom_filter_DEPENDENCIES = $(am__DEPENDENCIES_19) \
+unittest_bloom_filter_DEPENDENCIES = $(am__DEPENDENCIES_24) \
 	$(am__DEPENDENCIES_10)
 unittest_bloom_filter_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
 	$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \
@@ -5053,8 +5448,8 @@ am__unittest_bluefs_SOURCES_DIST = test/objectstore/test_bluefs.cc
 @ENABLE_SERVER_TRUE@@LINUX_TRUE at am_unittest_bluefs_OBJECTS = test/objectstore/unittest_bluefs-test_bluefs.$(OBJEXT)
 unittest_bluefs_OBJECTS = $(am_unittest_bluefs_OBJECTS)
 @ENABLE_SERVER_TRUE@@LINUX_TRUE at unittest_bluefs_DEPENDENCIES =  \
- at ENABLE_SERVER_TRUE@@LINUX_TRUE@	$(am__DEPENDENCIES_14) \
- at ENABLE_SERVER_TRUE@@LINUX_TRUE@	$(am__DEPENDENCIES_19) \
+ at ENABLE_SERVER_TRUE@@LINUX_TRUE@	$(am__DEPENDENCIES_16) \
+ at ENABLE_SERVER_TRUE@@LINUX_TRUE@	$(am__DEPENDENCIES_24) \
 @ENABLE_SERVER_TRUE@@LINUX_TRUE@	$(am__DEPENDENCIES_10)
 unittest_bluefs_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
 	$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \
@@ -5066,8 +5461,8 @@ am__unittest_bluestore_types_SOURCES_DIST =  \
 unittest_bluestore_types_OBJECTS =  \
 	$(am_unittest_bluestore_types_OBJECTS)
 @ENABLE_SERVER_TRUE@@LINUX_TRUE at unittest_bluestore_types_DEPENDENCIES =  \
- at ENABLE_SERVER_TRUE@@LINUX_TRUE@	$(am__DEPENDENCIES_14) \
- at ENABLE_SERVER_TRUE@@LINUX_TRUE@	$(am__DEPENDENCIES_19) \
+ at ENABLE_SERVER_TRUE@@LINUX_TRUE@	$(am__DEPENDENCIES_16) \
+ at ENABLE_SERVER_TRUE@@LINUX_TRUE@	$(am__DEPENDENCIES_24) \
 @ENABLE_SERVER_TRUE@@LINUX_TRUE@	$(am__DEPENDENCIES_10)
 unittest_bluestore_types_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
 	$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \
@@ -5076,7 +5471,7 @@ unittest_bluestore_types_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
 am_unittest_bufferlist_OBJECTS =  \
 	test/unittest_bufferlist-bufferlist.$(OBJEXT)
 unittest_bufferlist_OBJECTS = $(am_unittest_bufferlist_OBJECTS)
-unittest_bufferlist_DEPENDENCIES = $(am__DEPENDENCIES_19) \
+unittest_bufferlist_DEPENDENCIES = $(am__DEPENDENCIES_24) \
 	$(am__DEPENDENCIES_10)
 unittest_bufferlist_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
 	$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \
@@ -5085,7 +5480,7 @@ unittest_bufferlist_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
 am_unittest_ceph_argparse_OBJECTS =  \
 	test/unittest_ceph_argparse-ceph_argparse.$(OBJEXT)
 unittest_ceph_argparse_OBJECTS = $(am_unittest_ceph_argparse_OBJECTS)
-unittest_ceph_argparse_DEPENDENCIES = $(am__DEPENDENCIES_19) \
+unittest_ceph_argparse_DEPENDENCIES = $(am__DEPENDENCIES_24) \
 	$(am__DEPENDENCIES_10)
 unittest_ceph_argparse_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
 	$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \
@@ -5095,7 +5490,7 @@ am_unittest_ceph_compatset_OBJECTS =  \
 	test/unittest_ceph_compatset-ceph_compatset.$(OBJEXT)
 unittest_ceph_compatset_OBJECTS =  \
 	$(am_unittest_ceph_compatset_OBJECTS)
-unittest_ceph_compatset_DEPENDENCIES = $(am__DEPENDENCIES_19) \
+unittest_ceph_compatset_DEPENDENCIES = $(am__DEPENDENCIES_24) \
 	$(am__DEPENDENCIES_10)
 unittest_ceph_compatset_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
 	$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \
@@ -5104,7 +5499,7 @@ unittest_ceph_compatset_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
 am_unittest_ceph_crypto_OBJECTS =  \
 	test/unittest_ceph_crypto-ceph_crypto.$(OBJEXT)
 unittest_ceph_crypto_OBJECTS = $(am_unittest_ceph_crypto_OBJECTS)
-unittest_ceph_crypto_DEPENDENCIES = $(am__DEPENDENCIES_19) \
+unittest_ceph_crypto_DEPENDENCIES = $(am__DEPENDENCIES_24) \
 	$(am__DEPENDENCIES_10)
 unittest_ceph_crypto_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
 	$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \
@@ -5115,8 +5510,8 @@ am__unittest_chain_xattr_SOURCES_DIST =  \
 @ENABLE_SERVER_TRUE at am_unittest_chain_xattr_OBJECTS = test/objectstore/unittest_chain_xattr-chain_xattr.$(OBJEXT)
 unittest_chain_xattr_OBJECTS = $(am_unittest_chain_xattr_OBJECTS)
 @ENABLE_SERVER_TRUE at unittest_chain_xattr_DEPENDENCIES =  \
- at ENABLE_SERVER_TRUE@	$(am__DEPENDENCIES_14) \
- at ENABLE_SERVER_TRUE@	$(am__DEPENDENCIES_19) \
+ at ENABLE_SERVER_TRUE@	$(am__DEPENDENCIES_16) \
+ at ENABLE_SERVER_TRUE@	$(am__DEPENDENCIES_24) \
 @ENABLE_SERVER_TRUE@	$(am__DEPENDENCIES_10)
 unittest_chain_xattr_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
 	$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \
@@ -5130,9 +5525,9 @@ am__unittest_compression_plugin_SOURCES_DIST =  \
 unittest_compression_plugin_OBJECTS =  \
 	$(am_unittest_compression_plugin_OBJECTS)
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE at unittest_compression_plugin_DEPENDENCIES =  \
- at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__DEPENDENCIES_18) \
+ at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__DEPENDENCIES_23) \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__DEPENDENCIES_4) \
- at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__DEPENDENCIES_19) \
+ at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__DEPENDENCIES_24) \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__DEPENDENCIES_10) \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__DEPENDENCIES_1)
 unittest_compression_plugin_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
@@ -5143,16 +5538,16 @@ am__unittest_compression_plugin_snappy_SOURCES_DIST =  \
 	test/compressor/test_compression_plugin_snappy.cc \
 	compressor/Compressor.cc \
 	compressor/snappy/CompressionPluginSnappy.cc
-am__objects_50 = compressor/unittest_compression_plugin_snappy-Compressor.$(OBJEXT) \
+am__objects_52 = compressor/unittest_compression_plugin_snappy-Compressor.$(OBJEXT) \
 	compressor/snappy/unittest_compression_plugin_snappy-CompressionPluginSnappy.$(OBJEXT)
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE at am_unittest_compression_plugin_snappy_OBJECTS = test/compressor/unittest_compression_plugin_snappy-test_compression_plugin_snappy.$(OBJEXT) \
- at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__objects_50)
+ at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__objects_52)
 unittest_compression_plugin_snappy_OBJECTS =  \
 	$(am_unittest_compression_plugin_snappy_OBJECTS)
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE at unittest_compression_plugin_snappy_DEPENDENCIES =  \
- at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__DEPENDENCIES_18) \
+ at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__DEPENDENCIES_23) \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__DEPENDENCIES_4) \
- at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__DEPENDENCIES_19) \
+ at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__DEPENDENCIES_24) \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__DEPENDENCIES_10) \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(LIBCOMPRESSOR) \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__DEPENDENCIES_1)
@@ -5166,17 +5561,17 @@ am__unittest_compression_plugin_zlib_SOURCES_DIST =  \
 	compressor/Compressor.cc \
 	compressor/zlib/CompressionPluginZlib.cc \
 	compressor/zlib/CompressionZlib.cc
-am__objects_51 = compressor/unittest_compression_plugin_zlib-Compressor.$(OBJEXT) \
+am__objects_53 = compressor/unittest_compression_plugin_zlib-Compressor.$(OBJEXT) \
 	compressor/zlib/unittest_compression_plugin_zlib-CompressionPluginZlib.$(OBJEXT) \
 	compressor/zlib/unittest_compression_plugin_zlib-CompressionZlib.$(OBJEXT)
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE at am_unittest_compression_plugin_zlib_OBJECTS = test/compressor/unittest_compression_plugin_zlib-test_compression_plugin_zlib.$(OBJEXT) \
- at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__objects_51)
+ at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__objects_53)
 unittest_compression_plugin_zlib_OBJECTS =  \
 	$(am_unittest_compression_plugin_zlib_OBJECTS)
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE at unittest_compression_plugin_zlib_DEPENDENCIES =  \
- at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__DEPENDENCIES_18) \
+ at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__DEPENDENCIES_23) \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__DEPENDENCIES_4) \
- at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__DEPENDENCIES_19) \
+ at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__DEPENDENCIES_24) \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__DEPENDENCIES_10) \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(LIBCOMPRESSOR) \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__DEPENDENCIES_1)
@@ -5189,17 +5584,17 @@ am__unittest_compression_snappy_SOURCES_DIST =  \
 	test/compressor/test_compression_snappy.cc \
 	compressor/Compressor.cc \
 	compressor/snappy/CompressionPluginSnappy.cc
-am__objects_52 =  \
+am__objects_54 =  \
 	compressor/unittest_compression_snappy-Compressor.$(OBJEXT) \
 	compressor/snappy/unittest_compression_snappy-CompressionPluginSnappy.$(OBJEXT)
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE at am_unittest_compression_snappy_OBJECTS = test/compressor/unittest_compression_snappy-test_compression_snappy.$(OBJEXT) \
- at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__objects_52)
+ at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__objects_54)
 unittest_compression_snappy_OBJECTS =  \
 	$(am_unittest_compression_snappy_OBJECTS)
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE at unittest_compression_snappy_DEPENDENCIES =  \
- at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__DEPENDENCIES_18) \
+ at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__DEPENDENCIES_23) \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__DEPENDENCIES_4) \
- at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__DEPENDENCIES_19) \
+ at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__DEPENDENCIES_24) \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__DEPENDENCIES_10) \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__DEPENDENCIES_1)
 unittest_compression_snappy_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
@@ -5211,18 +5606,18 @@ am__unittest_compression_zlib_SOURCES_DIST =  \
 	compressor/Compressor.cc \
 	compressor/zlib/CompressionPluginZlib.cc \
 	compressor/zlib/CompressionZlib.cc
-am__objects_53 =  \
+am__objects_55 =  \
 	compressor/unittest_compression_zlib-Compressor.$(OBJEXT) \
 	compressor/zlib/unittest_compression_zlib-CompressionPluginZlib.$(OBJEXT) \
 	compressor/zlib/unittest_compression_zlib-CompressionZlib.$(OBJEXT)
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE at am_unittest_compression_zlib_OBJECTS = test/compressor/unittest_compression_zlib-test_compression_zlib.$(OBJEXT) \
- at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__objects_53)
+ at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__objects_55)
 unittest_compression_zlib_OBJECTS =  \
 	$(am_unittest_compression_zlib_OBJECTS)
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE at unittest_compression_zlib_DEPENDENCIES =  \
- at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__DEPENDENCIES_18) \
+ at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__DEPENDENCIES_23) \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__DEPENDENCIES_4) \
- at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__DEPENDENCIES_19) \
+ at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__DEPENDENCIES_24) \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__DEPENDENCIES_10) \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__DEPENDENCIES_1)
 unittest_compression_zlib_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
@@ -5232,7 +5627,7 @@ unittest_compression_zlib_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
 am_unittest_config_OBJECTS =  \
 	test/common/unittest_config-test_config.$(OBJEXT)
 unittest_config_OBJECTS = $(am_unittest_config_OBJECTS)
-unittest_config_DEPENDENCIES = $(am__DEPENDENCIES_19) \
+unittest_config_DEPENDENCIES = $(am__DEPENDENCIES_24) \
 	$(am__DEPENDENCIES_10)
 unittest_config_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
 	$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \
@@ -5241,7 +5636,7 @@ unittest_config_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
 am_unittest_confutils_OBJECTS =  \
 	test/unittest_confutils-confutils.$(OBJEXT)
 unittest_confutils_OBJECTS = $(am_unittest_confutils_OBJECTS)
-unittest_confutils_DEPENDENCIES = $(am__DEPENDENCIES_19) \
+unittest_confutils_DEPENDENCIES = $(am__DEPENDENCIES_24) \
 	$(am__DEPENDENCIES_10)
 unittest_confutils_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
 	$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \
@@ -5250,7 +5645,7 @@ unittest_confutils_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
 am_unittest_context_OBJECTS =  \
 	test/common/unittest_context-test_context.$(OBJEXT)
 unittest_context_OBJECTS = $(am_unittest_context_OBJECTS)
-unittest_context_DEPENDENCIES = $(am__DEPENDENCIES_19) \
+unittest_context_DEPENDENCIES = $(am__DEPENDENCIES_24) \
 	$(am__DEPENDENCIES_10)
 unittest_context_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
 	$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \
@@ -5259,7 +5654,7 @@ unittest_context_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
 am_unittest_crc32c_OBJECTS =  \
 	test/common/unittest_crc32c-test_crc32c.$(OBJEXT)
 unittest_crc32c_OBJECTS = $(am_unittest_crc32c_OBJECTS)
-unittest_crc32c_DEPENDENCIES = $(am__DEPENDENCIES_19) \
+unittest_crc32c_DEPENDENCIES = $(am__DEPENDENCIES_24) \
 	$(am__DEPENDENCIES_10)
 unittest_crc32c_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
 	$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \
@@ -5268,7 +5663,7 @@ unittest_crc32c_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
 am_unittest_crush_OBJECTS = test/crush/unittest_crush-crush.$(OBJEXT)
 unittest_crush_OBJECTS = $(am_unittest_crush_OBJECTS)
 unittest_crush_DEPENDENCIES = $(am__DEPENDENCIES_4) \
-	$(am__DEPENDENCIES_19) $(am__DEPENDENCIES_3) \
+	$(am__DEPENDENCIES_24) $(am__DEPENDENCIES_3) \
 	$(am__DEPENDENCIES_10)
 unittest_crush_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
 	$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \
@@ -5277,7 +5672,7 @@ unittest_crush_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
 am_unittest_crush_wrapper_OBJECTS =  \
 	test/crush/unittest_crush_wrapper-CrushWrapper.$(OBJEXT)
 unittest_crush_wrapper_OBJECTS = $(am_unittest_crush_wrapper_OBJECTS)
-unittest_crush_wrapper_DEPENDENCIES = $(am__DEPENDENCIES_19) \
+unittest_crush_wrapper_DEPENDENCIES = $(am__DEPENDENCIES_24) \
 	$(am__DEPENDENCIES_10) $(LIBCRUSH)
 unittest_crush_wrapper_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
 	$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \
@@ -5285,7 +5680,7 @@ unittest_crush_wrapper_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
 	$(LDFLAGS) -o $@
 am_unittest_crypto_OBJECTS = test/unittest_crypto-crypto.$(OBJEXT)
 unittest_crypto_OBJECTS = $(am_unittest_crypto_OBJECTS)
-unittest_crypto_DEPENDENCIES = $(am__DEPENDENCIES_19) \
+unittest_crypto_DEPENDENCIES = $(am__DEPENDENCIES_24) \
 	$(am__DEPENDENCIES_10)
 unittest_crypto_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
 	$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \
@@ -5294,7 +5689,7 @@ unittest_crypto_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
 am_unittest_crypto_init_OBJECTS =  \
 	test/unittest_crypto_init-crypto_init.$(OBJEXT)
 unittest_crypto_init_OBJECTS = $(am_unittest_crypto_init_OBJECTS)
-unittest_crypto_init_DEPENDENCIES = $(am__DEPENDENCIES_19) \
+unittest_crypto_init_DEPENDENCIES = $(am__DEPENDENCIES_24) \
 	$(am__DEPENDENCIES_10)
 unittest_crypto_init_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
 	$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \
@@ -5303,7 +5698,7 @@ unittest_crypto_init_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
 am_unittest_daemon_config_OBJECTS =  \
 	test/unittest_daemon_config-daemon_config.$(OBJEXT)
 unittest_daemon_config_OBJECTS = $(am_unittest_daemon_config_OBJECTS)
-unittest_daemon_config_DEPENDENCIES = $(am__DEPENDENCIES_19) \
+unittest_daemon_config_DEPENDENCIES = $(am__DEPENDENCIES_24) \
 	$(am__DEPENDENCIES_10)
 unittest_daemon_config_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
 	$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \
@@ -5313,8 +5708,8 @@ am__unittest_ecbackend_SOURCES_DIST = test/osd/TestECBackend.cc
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE at am_unittest_ecbackend_OBJECTS = test/osd/unittest_ecbackend-TestECBackend.$(OBJEXT)
 unittest_ecbackend_OBJECTS = $(am_unittest_ecbackend_OBJECTS)
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE at unittest_ecbackend_DEPENDENCIES =  \
- at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__DEPENDENCIES_18) \
- at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__DEPENDENCIES_19) \
+ at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__DEPENDENCIES_23) \
+ at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__DEPENDENCIES_24) \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__DEPENDENCIES_10)
 unittest_ecbackend_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
 	$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \
@@ -5326,7 +5721,7 @@ unittest_encoding_OBJECTS = $(am_unittest_encoding_OBJECTS)
 @ENABLE_CLIENT_TRUE@@WITH_CEPHFS_TRUE@@WITH_RADOS_TRUE at unittest_encoding_DEPENDENCIES = $(LIBCEPHFS) \
 @ENABLE_CLIENT_TRUE@@WITH_CEPHFS_TRUE@@WITH_RADOS_TRUE@	$(LIBRADOS) \
 @ENABLE_CLIENT_TRUE@@WITH_CEPHFS_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_10) \
- at ENABLE_CLIENT_TRUE@@WITH_CEPHFS_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_19)
+ at ENABLE_CLIENT_TRUE@@WITH_CEPHFS_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_24)
 unittest_encoding_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
 	$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \
 	$(unittest_encoding_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) \
@@ -5337,9 +5732,9 @@ am__unittest_erasure_code_SOURCES_DIST = erasure-code/ErasureCode.cc \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	test/erasure-code/unittest_erasure_code-TestErasureCode.$(OBJEXT)
 unittest_erasure_code_OBJECTS = $(am_unittest_erasure_code_OBJECTS)
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE at unittest_erasure_code_DEPENDENCIES =  \
- at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__DEPENDENCIES_18) \
+ at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__DEPENDENCIES_23) \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__DEPENDENCIES_4) \
- at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__DEPENDENCIES_19) \
+ at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__DEPENDENCIES_24) \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__DEPENDENCIES_10)
 unittest_erasure_code_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
 	$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \
@@ -5353,9 +5748,9 @@ am__unittest_erasure_code_example_SOURCES_DIST =  \
 unittest_erasure_code_example_OBJECTS =  \
 	$(am_unittest_erasure_code_example_OBJECTS)
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE at unittest_erasure_code_example_DEPENDENCIES =  \
- at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__DEPENDENCIES_18) \
+ at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__DEPENDENCIES_23) \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__DEPENDENCIES_4) \
- at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__DEPENDENCIES_19) \
+ at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__DEPENDENCIES_24) \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__DEPENDENCIES_10)
 unittest_erasure_code_example_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
 	$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \
@@ -5368,9 +5763,9 @@ am__unittest_erasure_code_isa_SOURCES_DIST =  \
 @ENABLE_SERVER_TRUE@@WITH_BETTER_YASM_ELF64_TRUE@@WITH_OSD_TRUE@	test/erasure-code/unittest_erasure_code_isa-TestErasureCodeIsa.$(OBJEXT)
 unittest_erasure_code_isa_OBJECTS =  \
 	$(am_unittest_erasure_code_isa_OBJECTS)
- at ENABLE_SERVER_TRUE@@WITH_BETTER_YASM_ELF64_TRUE@@WITH_OSD_TRUE at unittest_erasure_code_isa_DEPENDENCIES = $(am__DEPENDENCIES_18) \
+ at ENABLE_SERVER_TRUE@@WITH_BETTER_YASM_ELF64_TRUE@@WITH_OSD_TRUE at unittest_erasure_code_isa_DEPENDENCIES = $(am__DEPENDENCIES_23) \
 @ENABLE_SERVER_TRUE@@WITH_BETTER_YASM_ELF64_TRUE@@WITH_OSD_TRUE@	$(am__DEPENDENCIES_4) \
- at ENABLE_SERVER_TRUE@@WITH_BETTER_YASM_ELF64_TRUE@@WITH_OSD_TRUE@	$(am__DEPENDENCIES_19) \
+ at ENABLE_SERVER_TRUE@@WITH_BETTER_YASM_ELF64_TRUE@@WITH_OSD_TRUE@	$(am__DEPENDENCIES_24) \
 @ENABLE_SERVER_TRUE@@WITH_BETTER_YASM_ELF64_TRUE@@WITH_OSD_TRUE@	$(am__DEPENDENCIES_10) \
 @ENABLE_SERVER_TRUE@@WITH_BETTER_YASM_ELF64_TRUE@@WITH_OSD_TRUE@	libisa.la \
 @ENABLE_SERVER_TRUE@@WITH_BETTER_YASM_ELF64_TRUE@@WITH_OSD_TRUE@	$(LIBERASURE_CODE) \
@@ -5400,7 +5795,7 @@ am__unittest_erasure_code_jerasure_SOURCES_DIST =  \
 	erasure-code/jerasure/gf-complete/src/gf_w8.c \
 	erasure-code/jerasure/ErasureCodePluginJerasure.cc \
 	erasure-code/jerasure/ErasureCodeJerasure.cc
-am__objects_54 = erasure-code/unittest_erasure_code_jerasure-ErasureCode.$(OBJEXT) \
+am__objects_56 = erasure-code/unittest_erasure_code_jerasure-ErasureCode.$(OBJEXT) \
 	erasure-code/jerasure/jerasure/src/unittest_erasure_code_jerasure-cauchy.$(OBJEXT) \
 	erasure-code/jerasure/jerasure/src/unittest_erasure_code_jerasure-galois.$(OBJEXT) \
 	erasure-code/jerasure/jerasure/src/unittest_erasure_code_jerasure-jerasure.$(OBJEXT) \
@@ -5420,13 +5815,13 @@ am__objects_54 = erasure-code/unittest_erasure_code_jerasure-ErasureCode.$(OBJEX
 	erasure-code/jerasure/unittest_erasure_code_jerasure-ErasureCodePluginJerasure.$(OBJEXT) \
 	erasure-code/jerasure/unittest_erasure_code_jerasure-ErasureCodeJerasure.$(OBJEXT)
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE at am_unittest_erasure_code_jerasure_OBJECTS = test/erasure-code/unittest_erasure_code_jerasure-TestErasureCodeJerasure.$(OBJEXT) \
- at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__objects_54)
+ at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__objects_56)
 unittest_erasure_code_jerasure_OBJECTS =  \
 	$(am_unittest_erasure_code_jerasure_OBJECTS)
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE at unittest_erasure_code_jerasure_DEPENDENCIES =  \
- at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__DEPENDENCIES_18) \
+ at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__DEPENDENCIES_23) \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__DEPENDENCIES_4) \
- at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__DEPENDENCIES_19) \
+ at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__DEPENDENCIES_24) \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__DEPENDENCIES_10) \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__DEPENDENCIES_1)
 unittest_erasure_code_jerasure_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
@@ -5438,18 +5833,18 @@ am__unittest_erasure_code_lrc_SOURCES_DIST =  \
 	erasure-code/ErasureCode.cc \
 	erasure-code/lrc/ErasureCodePluginLrc.cc \
 	erasure-code/lrc/ErasureCodeLrc.cc
-am__objects_55 =  \
+am__objects_57 =  \
 	erasure-code/unittest_erasure_code_lrc-ErasureCode.$(OBJEXT) \
 	erasure-code/lrc/unittest_erasure_code_lrc-ErasureCodePluginLrc.$(OBJEXT) \
 	erasure-code/lrc/unittest_erasure_code_lrc-ErasureCodeLrc.$(OBJEXT)
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE at am_unittest_erasure_code_lrc_OBJECTS = test/erasure-code/unittest_erasure_code_lrc-TestErasureCodeLrc.$(OBJEXT) \
- at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__objects_55)
+ at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__objects_57)
 unittest_erasure_code_lrc_OBJECTS =  \
 	$(am_unittest_erasure_code_lrc_OBJECTS)
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE at unittest_erasure_code_lrc_DEPENDENCIES =  \
- at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__DEPENDENCIES_18) \
+ at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__DEPENDENCIES_23) \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__DEPENDENCIES_4) \
- at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__DEPENDENCIES_19) \
+ at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__DEPENDENCIES_24) \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__DEPENDENCIES_10) \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__DEPENDENCIES_1)
 unittest_erasure_code_lrc_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
@@ -5464,9 +5859,9 @@ am__unittest_erasure_code_plugin_SOURCES_DIST =  \
 unittest_erasure_code_plugin_OBJECTS =  \
 	$(am_unittest_erasure_code_plugin_OBJECTS)
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE at unittest_erasure_code_plugin_DEPENDENCIES =  \
- at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__DEPENDENCIES_18) \
+ at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__DEPENDENCIES_23) \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__DEPENDENCIES_4) \
- at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__DEPENDENCIES_19) \
+ at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__DEPENDENCIES_24) \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__DEPENDENCIES_10) \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__DEPENDENCIES_1)
 unittest_erasure_code_plugin_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
@@ -5480,9 +5875,9 @@ am__unittest_erasure_code_plugin_isa_SOURCES_DIST =  \
 @ENABLE_SERVER_TRUE@@WITH_BETTER_YASM_ELF64_TRUE@@WITH_OSD_TRUE@	test/erasure-code/unittest_erasure_code_plugin_isa-TestErasureCodePluginIsa.$(OBJEXT)
 unittest_erasure_code_plugin_isa_OBJECTS =  \
 	$(am_unittest_erasure_code_plugin_isa_OBJECTS)
- at ENABLE_SERVER_TRUE@@WITH_BETTER_YASM_ELF64_TRUE@@WITH_OSD_TRUE at unittest_erasure_code_plugin_isa_DEPENDENCIES = $(am__DEPENDENCIES_18) \
+ at ENABLE_SERVER_TRUE@@WITH_BETTER_YASM_ELF64_TRUE@@WITH_OSD_TRUE at unittest_erasure_code_plugin_isa_DEPENDENCIES = $(am__DEPENDENCIES_23) \
 @ENABLE_SERVER_TRUE@@WITH_BETTER_YASM_ELF64_TRUE@@WITH_OSD_TRUE@	$(am__DEPENDENCIES_4) \
- at ENABLE_SERVER_TRUE@@WITH_BETTER_YASM_ELF64_TRUE@@WITH_OSD_TRUE@	$(am__DEPENDENCIES_19) \
+ at ENABLE_SERVER_TRUE@@WITH_BETTER_YASM_ELF64_TRUE@@WITH_OSD_TRUE@	$(am__DEPENDENCIES_24) \
 @ENABLE_SERVER_TRUE@@WITH_BETTER_YASM_ELF64_TRUE@@WITH_OSD_TRUE@	$(am__DEPENDENCIES_10) \
 @ENABLE_SERVER_TRUE@@WITH_BETTER_YASM_ELF64_TRUE@@WITH_OSD_TRUE@	$(LIBERASURE_CODE) \
 @ENABLE_SERVER_TRUE@@WITH_BETTER_YASM_ELF64_TRUE@@WITH_OSD_TRUE@	$(am__DEPENDENCIES_1)
@@ -5496,9 +5891,9 @@ am__unittest_erasure_code_plugin_jerasure_SOURCES_DIST =  \
 unittest_erasure_code_plugin_jerasure_OBJECTS =  \
 	$(am_unittest_erasure_code_plugin_jerasure_OBJECTS)
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE at unittest_erasure_code_plugin_jerasure_DEPENDENCIES =  \
- at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__DEPENDENCIES_18) \
+ at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__DEPENDENCIES_23) \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__DEPENDENCIES_4) \
- at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__DEPENDENCIES_19) \
+ at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__DEPENDENCIES_24) \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__DEPENDENCIES_10) \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__DEPENDENCIES_1)
 unittest_erasure_code_plugin_jerasure_LINK = $(LIBTOOL) $(AM_V_lt) \
@@ -5511,9 +5906,9 @@ am__unittest_erasure_code_plugin_lrc_SOURCES_DIST =  \
 unittest_erasure_code_plugin_lrc_OBJECTS =  \
 	$(am_unittest_erasure_code_plugin_lrc_OBJECTS)
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE at unittest_erasure_code_plugin_lrc_DEPENDENCIES =  \
- at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__DEPENDENCIES_18) \
+ at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__DEPENDENCIES_23) \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__DEPENDENCIES_4) \
- at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__DEPENDENCIES_19) \
+ at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__DEPENDENCIES_24) \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__DEPENDENCIES_10) \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__DEPENDENCIES_1)
 unittest_erasure_code_plugin_lrc_LINK = $(LIBTOOL) $(AM_V_lt) \
@@ -5526,9 +5921,9 @@ am__unittest_erasure_code_plugin_shec_SOURCES_DIST =  \
 unittest_erasure_code_plugin_shec_OBJECTS =  \
 	$(am_unittest_erasure_code_plugin_shec_OBJECTS)
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE at unittest_erasure_code_plugin_shec_DEPENDENCIES =  \
- at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__DEPENDENCIES_18) \
+ at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__DEPENDENCIES_23) \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__DEPENDENCIES_4) \
- at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__DEPENDENCIES_19) \
+ at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__DEPENDENCIES_24) \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__DEPENDENCIES_10) \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__DEPENDENCIES_1)
 unittest_erasure_code_plugin_shec_LINK = $(LIBTOOL) $(AM_V_lt) \
@@ -5558,7 +5953,7 @@ am__unittest_erasure_code_shec_SOURCES_DIST =  \
 	erasure-code/jerasure/gf-complete/src/gf_w4.c \
 	erasure-code/jerasure/gf-complete/src/gf_rand.c \
 	erasure-code/jerasure/gf-complete/src/gf_w8.c
-am__objects_56 =  \
+am__objects_58 =  \
 	erasure-code/unittest_erasure_code_shec-ErasureCode.$(OBJEXT) \
 	erasure-code/shec/unittest_erasure_code_shec-ErasureCodePluginShec.$(OBJEXT) \
 	erasure-code/shec/unittest_erasure_code_shec-ErasureCodeShec.$(OBJEXT) \
@@ -5581,13 +5976,13 @@ am__objects_56 =  \
 	erasure-code/jerasure/gf-complete/src/unittest_erasure_code_shec-gf_rand.$(OBJEXT) \
 	erasure-code/jerasure/gf-complete/src/unittest_erasure_code_shec-gf_w8.$(OBJEXT)
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE at am_unittest_erasure_code_shec_OBJECTS = test/erasure-code/unittest_erasure_code_shec-TestErasureCodeShec.$(OBJEXT) \
- at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__objects_56)
+ at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__objects_58)
 unittest_erasure_code_shec_OBJECTS =  \
 	$(am_unittest_erasure_code_shec_OBJECTS)
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE at unittest_erasure_code_shec_DEPENDENCIES =  \
- at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__DEPENDENCIES_18) \
+ at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__DEPENDENCIES_23) \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__DEPENDENCIES_4) \
- at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__DEPENDENCIES_19) \
+ at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__DEPENDENCIES_24) \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__DEPENDENCIES_10) \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__DEPENDENCIES_1)
 unittest_erasure_code_shec_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
@@ -5617,7 +6012,7 @@ am__unittest_erasure_code_shec_all_SOURCES_DIST =  \
 	erasure-code/jerasure/gf-complete/src/gf_w4.c \
 	erasure-code/jerasure/gf-complete/src/gf_rand.c \
 	erasure-code/jerasure/gf-complete/src/gf_w8.c
-am__objects_57 = erasure-code/unittest_erasure_code_shec_all-ErasureCode.$(OBJEXT) \
+am__objects_59 = erasure-code/unittest_erasure_code_shec_all-ErasureCode.$(OBJEXT) \
 	erasure-code/shec/unittest_erasure_code_shec_all-ErasureCodePluginShec.$(OBJEXT) \
 	erasure-code/shec/unittest_erasure_code_shec_all-ErasureCodeShec.$(OBJEXT) \
 	erasure-code/shec/unittest_erasure_code_shec_all-ErasureCodeShecTableCache.$(OBJEXT) \
@@ -5639,13 +6034,13 @@ am__objects_57 = erasure-code/unittest_erasure_code_shec_all-ErasureCode.$(OBJEX
 	erasure-code/jerasure/gf-complete/src/unittest_erasure_code_shec_all-gf_rand.$(OBJEXT) \
 	erasure-code/jerasure/gf-complete/src/unittest_erasure_code_shec_all-gf_w8.$(OBJEXT)
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE at am_unittest_erasure_code_shec_all_OBJECTS = test/erasure-code/unittest_erasure_code_shec_all-TestErasureCodeShec_all.$(OBJEXT) \
- at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__objects_57)
+ at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__objects_59)
 unittest_erasure_code_shec_all_OBJECTS =  \
 	$(am_unittest_erasure_code_shec_all_OBJECTS)
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE at unittest_erasure_code_shec_all_DEPENDENCIES =  \
- at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__DEPENDENCIES_18) \
+ at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__DEPENDENCIES_23) \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__DEPENDENCIES_4) \
- at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__DEPENDENCIES_19) \
+ at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__DEPENDENCIES_24) \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__DEPENDENCIES_10) \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__DEPENDENCIES_1)
 unittest_erasure_code_shec_all_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
@@ -5675,7 +6070,7 @@ am__unittest_erasure_code_shec_arguments_SOURCES_DIST =  \
 	erasure-code/jerasure/gf-complete/src/gf_w4.c \
 	erasure-code/jerasure/gf-complete/src/gf_rand.c \
 	erasure-code/jerasure/gf-complete/src/gf_w8.c
-am__objects_58 = erasure-code/unittest_erasure_code_shec_arguments-ErasureCode.$(OBJEXT) \
+am__objects_60 = erasure-code/unittest_erasure_code_shec_arguments-ErasureCode.$(OBJEXT) \
 	erasure-code/shec/unittest_erasure_code_shec_arguments-ErasureCodePluginShec.$(OBJEXT) \
 	erasure-code/shec/unittest_erasure_code_shec_arguments-ErasureCodeShec.$(OBJEXT) \
 	erasure-code/shec/unittest_erasure_code_shec_arguments-ErasureCodeShecTableCache.$(OBJEXT) \
@@ -5697,13 +6092,13 @@ am__objects_58 = erasure-code/unittest_erasure_code_shec_arguments-ErasureCode.$
 	erasure-code/jerasure/gf-complete/src/unittest_erasure_code_shec_arguments-gf_rand.$(OBJEXT) \
 	erasure-code/jerasure/gf-complete/src/unittest_erasure_code_shec_arguments-gf_w8.$(OBJEXT)
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE at am_unittest_erasure_code_shec_arguments_OBJECTS = test/erasure-code/unittest_erasure_code_shec_arguments-TestErasureCodeShec_arguments.$(OBJEXT) \
- at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__objects_58)
+ at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__objects_60)
 unittest_erasure_code_shec_arguments_OBJECTS =  \
 	$(am_unittest_erasure_code_shec_arguments_OBJECTS)
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE at unittest_erasure_code_shec_arguments_DEPENDENCIES =  \
- at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__DEPENDENCIES_18) \
+ at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__DEPENDENCIES_23) \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__DEPENDENCIES_4) \
- at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__DEPENDENCIES_19) \
+ at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__DEPENDENCIES_24) \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__DEPENDENCIES_10) \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__DEPENDENCIES_1)
 unittest_erasure_code_shec_arguments_LINK = $(LIBTOOL) $(AM_V_lt) \
@@ -5733,7 +6128,7 @@ am__unittest_erasure_code_shec_thread_SOURCES_DIST =  \
 	erasure-code/jerasure/gf-complete/src/gf_w4.c \
 	erasure-code/jerasure/gf-complete/src/gf_rand.c \
 	erasure-code/jerasure/gf-complete/src/gf_w8.c
-am__objects_59 = erasure-code/unittest_erasure_code_shec_thread-ErasureCode.$(OBJEXT) \
+am__objects_61 = erasure-code/unittest_erasure_code_shec_thread-ErasureCode.$(OBJEXT) \
 	erasure-code/shec/unittest_erasure_code_shec_thread-ErasureCodePluginShec.$(OBJEXT) \
 	erasure-code/shec/unittest_erasure_code_shec_thread-ErasureCodeShec.$(OBJEXT) \
 	erasure-code/shec/unittest_erasure_code_shec_thread-ErasureCodeShecTableCache.$(OBJEXT) \
@@ -5755,13 +6150,13 @@ am__objects_59 = erasure-code/unittest_erasure_code_shec_thread-ErasureCode.$(OB
 	erasure-code/jerasure/gf-complete/src/unittest_erasure_code_shec_thread-gf_rand.$(OBJEXT) \
 	erasure-code/jerasure/gf-complete/src/unittest_erasure_code_shec_thread-gf_w8.$(OBJEXT)
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE at am_unittest_erasure_code_shec_thread_OBJECTS = test/erasure-code/unittest_erasure_code_shec_thread-TestErasureCodeShec_thread.$(OBJEXT) \
- at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__objects_59)
+ at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__objects_61)
 unittest_erasure_code_shec_thread_OBJECTS =  \
 	$(am_unittest_erasure_code_shec_thread_OBJECTS)
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE at unittest_erasure_code_shec_thread_DEPENDENCIES =  \
- at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__DEPENDENCIES_18) \
+ at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__DEPENDENCIES_23) \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__DEPENDENCIES_4) \
- at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__DEPENDENCIES_19) \
+ at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__DEPENDENCIES_24) \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__DEPENDENCIES_10) \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__DEPENDENCIES_1)
 unittest_erasure_code_shec_thread_LINK = $(LIBTOOL) $(AM_V_lt) \
@@ -5770,7 +6165,7 @@ unittest_erasure_code_shec_thread_LINK = $(LIBTOOL) $(AM_V_lt) \
 	$(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
 am_unittest_escape_OBJECTS = test/unittest_escape-escape.$(OBJEXT)
 unittest_escape_OBJECTS = $(am_unittest_escape_OBJECTS)
-unittest_escape_DEPENDENCIES = $(am__DEPENDENCIES_19) \
+unittest_escape_DEPENDENCIES = $(am__DEPENDENCIES_24) \
 	$(am__DEPENDENCIES_10)
 unittest_escape_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
 	$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \
@@ -5780,7 +6175,7 @@ am_unittest_formatter_OBJECTS =  \
 	test/unittest_formatter-formatter.$(OBJEXT) \
 	rgw/unittest_formatter-rgw_formats.$(OBJEXT)
 unittest_formatter_OBJECTS = $(am_unittest_formatter_OBJECTS)
-unittest_formatter_DEPENDENCIES = $(am__DEPENDENCIES_19) \
+unittest_formatter_DEPENDENCIES = $(am__DEPENDENCIES_24) \
 	$(am__DEPENDENCIES_10)
 unittest_formatter_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
 	$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \
@@ -5788,7 +6183,7 @@ unittest_formatter_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
 	$(LDFLAGS) -o $@
 am_unittest_gather_OBJECTS = test/unittest_gather-gather.$(OBJEXT)
 unittest_gather_OBJECTS = $(am_unittest_gather_OBJECTS)
-unittest_gather_DEPENDENCIES = $(am__DEPENDENCIES_19) \
+unittest_gather_DEPENDENCIES = $(am__DEPENDENCIES_24) \
 	$(am__DEPENDENCIES_10)
 unittest_gather_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
 	$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \
@@ -5798,7 +6193,7 @@ am_unittest_heartbeatmap_OBJECTS =  \
 	test/unittest_heartbeatmap-heartbeat_map.$(OBJEXT)
 unittest_heartbeatmap_OBJECTS = $(am_unittest_heartbeatmap_OBJECTS)
 unittest_heartbeatmap_DEPENDENCIES = $(am__DEPENDENCIES_4) \
-	$(am__DEPENDENCIES_19) $(am__DEPENDENCIES_10)
+	$(am__DEPENDENCIES_24) $(am__DEPENDENCIES_10)
 unittest_heartbeatmap_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
 	$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \
 	$(unittest_heartbeatmap_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) \
@@ -5806,7 +6201,7 @@ unittest_heartbeatmap_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
 am_unittest_histogram_OBJECTS =  \
 	test/common/unittest_histogram-histogram.$(OBJEXT)
 unittest_histogram_OBJECTS = $(am_unittest_histogram_OBJECTS)
-unittest_histogram_DEPENDENCIES = $(am__DEPENDENCIES_19) \
+unittest_histogram_DEPENDENCIES = $(am__DEPENDENCIES_24) \
 	$(am__DEPENDENCIES_10)
 unittest_histogram_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
 	$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \
@@ -5816,8 +6211,8 @@ am__unittest_hitset_SOURCES_DIST = test/osd/hitset.cc
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE at am_unittest_hitset_OBJECTS = test/osd/unittest_hitset-hitset.$(OBJEXT)
 unittest_hitset_OBJECTS = $(am_unittest_hitset_OBJECTS)
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE at unittest_hitset_DEPENDENCIES =  \
- at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__DEPENDENCIES_18) \
- at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__DEPENDENCIES_19) \
+ at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__DEPENDENCIES_23) \
+ at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__DEPENDENCIES_24) \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__DEPENDENCIES_10)
 unittest_hitset_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
 	$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \
@@ -5826,7 +6221,7 @@ unittest_hitset_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
 am_unittest_interval_set_OBJECTS =  \
 	test/common/unittest_interval_set-test_interval_set.$(OBJEXT)
 unittest_interval_set_OBJECTS = $(am_unittest_interval_set_OBJECTS)
-unittest_interval_set_DEPENDENCIES = $(am__DEPENDENCIES_19) \
+unittest_interval_set_DEPENDENCIES = $(am__DEPENDENCIES_24) \
 	$(am__DEPENDENCIES_10)
 unittest_interval_set_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
 	$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \
@@ -5835,7 +6230,7 @@ unittest_interval_set_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
 am_unittest_io_priority_OBJECTS =  \
 	test/common/unittest_io_priority-test_io_priority.$(OBJEXT)
 unittest_io_priority_OBJECTS = $(am_unittest_io_priority_OBJECTS)
-unittest_io_priority_DEPENDENCIES = $(am__DEPENDENCIES_19) \
+unittest_io_priority_DEPENDENCIES = $(am__DEPENDENCIES_24) \
 	$(am__DEPENDENCIES_10)
 unittest_io_priority_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
 	$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \
@@ -5844,7 +6239,7 @@ unittest_io_priority_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
 am_unittest_ipaddr_OBJECTS =  \
 	test/unittest_ipaddr-test_ipaddr.$(OBJEXT)
 unittest_ipaddr_OBJECTS = $(am_unittest_ipaddr_OBJECTS)
-unittest_ipaddr_DEPENDENCIES = $(am__DEPENDENCIES_19) \
+unittest_ipaddr_DEPENDENCIES = $(am__DEPENDENCIES_24) \
 	$(am__DEPENDENCIES_10)
 unittest_ipaddr_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
 	$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \
@@ -5877,7 +6272,7 @@ unittest_journal_OBJECTS = $(am_unittest_journal_OBJECTS)
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@	libcls_journal_client.la \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@	librados_test_stub.la \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@	librados_internal.la \
- at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_19) \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_24) \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_10) \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_9) \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@	$(LIBRADOS)
@@ -5889,8 +6284,8 @@ am__unittest_lfnindex_SOURCES_DIST = test/os/TestLFNIndex.cc
 @ENABLE_SERVER_TRUE at am_unittest_lfnindex_OBJECTS = test/os/unittest_lfnindex-TestLFNIndex.$(OBJEXT)
 unittest_lfnindex_OBJECTS = $(am_unittest_lfnindex_OBJECTS)
 @ENABLE_SERVER_TRUE at unittest_lfnindex_DEPENDENCIES =  \
- at ENABLE_SERVER_TRUE@	$(am__DEPENDENCIES_14) \
- at ENABLE_SERVER_TRUE@	$(am__DEPENDENCIES_19) \
+ at ENABLE_SERVER_TRUE@	$(am__DEPENDENCIES_16) \
+ at ENABLE_SERVER_TRUE@	$(am__DEPENDENCIES_24) \
 @ENABLE_SERVER_TRUE@	$(am__DEPENDENCIES_10)
 unittest_lfnindex_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
 	$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \
@@ -5902,7 +6297,7 @@ unittest_libcephfs_config_OBJECTS =  \
 	$(am_unittest_libcephfs_config_OBJECTS)
 @ENABLE_CLIENT_TRUE@@WITH_CEPHFS_TRUE@@WITH_RADOS_TRUE at unittest_libcephfs_config_DEPENDENCIES = $(LIBCEPHFS) \
 @ENABLE_CLIENT_TRUE@@WITH_CEPHFS_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_10) \
- at ENABLE_CLIENT_TRUE@@WITH_CEPHFS_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_19)
+ at ENABLE_CLIENT_TRUE@@WITH_CEPHFS_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_24)
 unittest_libcephfs_config_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
 	$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \
 	$(unittest_libcephfs_config_CXXFLAGS) $(CXXFLAGS) \
@@ -5913,7 +6308,7 @@ unittest_librados_OBJECTS = $(am_unittest_librados_OBJECTS)
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE at unittest_librados_DEPENDENCIES =  \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@	$(LIBRADOS) \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_10) \
- at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_19)
+ at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_24)
 unittest_librados_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
 	$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \
 	$(unittest_librados_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) \
@@ -5926,7 +6321,7 @@ unittest_librados_config_OBJECTS =  \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE at unittest_librados_config_DEPENDENCIES =  \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@	$(LIBRADOS) \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_10) \
- at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_19)
+ at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_24)
 unittest_librados_config_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
 	$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \
 	$(unittest_librados_config_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) \
@@ -5990,7 +6385,7 @@ unittest_librbd_OBJECTS = $(am_unittest_librbd_OBJECTS)
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	librados_internal.la \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	$(LIBRADOS) \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	$(LIBOSDC) \
- at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	$(am__DEPENDENCIES_19) \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	$(am__DEPENDENCIES_24) \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	$(am__DEPENDENCIES_10) \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	$(am__DEPENDENCIES_9)
 unittest_librbd_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
@@ -6000,13 +6395,13 @@ unittest_librbd_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
 am_unittest_log_OBJECTS = log/unittest_log-test.$(OBJEXT)
 unittest_log_OBJECTS = $(am_unittest_log_OBJECTS)
 unittest_log_DEPENDENCIES = $(am__DEPENDENCIES_4) \
-	$(am__DEPENDENCIES_19)
+	$(am__DEPENDENCIES_24)
 unittest_log_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \
 	$(LIBTOOLFLAGS) --mode=link $(CXXLD) $(unittest_log_CXXFLAGS) \
 	$(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
 am_unittest_lru_OBJECTS = test/common/unittest_lru-test_lru.$(OBJEXT)
 unittest_lru_OBJECTS = $(am_unittest_lru_OBJECTS)
-unittest_lru_DEPENDENCIES = $(am__DEPENDENCIES_19) \
+unittest_lru_DEPENDENCIES = $(am__DEPENDENCIES_24) \
 	$(am__DEPENDENCIES_10)
 unittest_lru_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \
 	$(LIBTOOLFLAGS) --mode=link $(CXXLD) $(unittest_lru_CXXFLAGS) \
@@ -6015,8 +6410,8 @@ am__unittest_mds_authcap_SOURCES_DIST = test/mds/TestMDSAuthCaps.cc
 @ENABLE_SERVER_TRUE@@WITH_MDS_TRUE at am_unittest_mds_authcap_OBJECTS = test/mds/unittest_mds_authcap-TestMDSAuthCaps.$(OBJEXT)
 unittest_mds_authcap_OBJECTS = $(am_unittest_mds_authcap_OBJECTS)
 @ENABLE_SERVER_TRUE@@WITH_MDS_TRUE at unittest_mds_authcap_DEPENDENCIES =  \
- at ENABLE_SERVER_TRUE@@WITH_MDS_TRUE@	$(am__DEPENDENCIES_16) \
- at ENABLE_SERVER_TRUE@@WITH_MDS_TRUE@	$(am__DEPENDENCIES_19) \
+ at ENABLE_SERVER_TRUE@@WITH_MDS_TRUE@	$(am__DEPENDENCIES_21) \
+ at ENABLE_SERVER_TRUE@@WITH_MDS_TRUE@	$(am__DEPENDENCIES_24) \
 @ENABLE_SERVER_TRUE@@WITH_MDS_TRUE@	$(am__DEPENDENCIES_10)
 unittest_mds_authcap_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
 	$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \
@@ -6025,7 +6420,7 @@ unittest_mds_authcap_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
 am_unittest_mds_types_OBJECTS =  \
 	test/fs/unittest_mds_types-mds_types.$(OBJEXT)
 unittest_mds_types_OBJECTS = $(am_unittest_mds_types_OBJECTS)
-unittest_mds_types_DEPENDENCIES = $(am__DEPENDENCIES_19) \
+unittest_mds_types_DEPENDENCIES = $(am__DEPENDENCIES_24) \
 	$(am__DEPENDENCIES_10)
 unittest_mds_types_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
 	$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \
@@ -6033,7 +6428,7 @@ unittest_mds_types_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
 	$(LDFLAGS) -o $@
 am_unittest_mime_OBJECTS = test/unittest_mime-mime.$(OBJEXT)
 unittest_mime_OBJECTS = $(am_unittest_mime_OBJECTS)
-unittest_mime_DEPENDENCIES = $(am__DEPENDENCIES_19) \
+unittest_mime_DEPENDENCIES = $(am__DEPENDENCIES_24) \
 	$(am__DEPENDENCIES_10)
 unittest_mime_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
 	$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \
@@ -6043,8 +6438,8 @@ am__unittest_mon_moncap_SOURCES_DIST = test/mon/moncap.cc
 @ENABLE_SERVER_TRUE@@WITH_MON_TRUE at am_unittest_mon_moncap_OBJECTS = test/mon/unittest_mon_moncap-moncap.$(OBJEXT)
 unittest_mon_moncap_OBJECTS = $(am_unittest_mon_moncap_OBJECTS)
 @ENABLE_SERVER_TRUE@@WITH_MON_TRUE at unittest_mon_moncap_DEPENDENCIES =  \
- at ENABLE_SERVER_TRUE@@WITH_MON_TRUE@	$(am__DEPENDENCIES_17) \
- at ENABLE_SERVER_TRUE@@WITH_MON_TRUE@	$(am__DEPENDENCIES_19) \
+ at ENABLE_SERVER_TRUE@@WITH_MON_TRUE@	$(am__DEPENDENCIES_22) \
+ at ENABLE_SERVER_TRUE@@WITH_MON_TRUE@	$(am__DEPENDENCIES_24) \
 @ENABLE_SERVER_TRUE@@WITH_MON_TRUE@	$(am__DEPENDENCIES_10)
 unittest_mon_moncap_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
 	$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \
@@ -6054,8 +6449,8 @@ am__unittest_mon_pgmap_SOURCES_DIST = test/mon/PGMap.cc
 @ENABLE_SERVER_TRUE@@WITH_MON_TRUE at am_unittest_mon_pgmap_OBJECTS = test/mon/unittest_mon_pgmap-PGMap.$(OBJEXT)
 unittest_mon_pgmap_OBJECTS = $(am_unittest_mon_pgmap_OBJECTS)
 @ENABLE_SERVER_TRUE@@WITH_MON_TRUE at unittest_mon_pgmap_DEPENDENCIES =  \
- at ENABLE_SERVER_TRUE@@WITH_MON_TRUE@	$(am__DEPENDENCIES_17) \
- at ENABLE_SERVER_TRUE@@WITH_MON_TRUE@	$(am__DEPENDENCIES_19) \
+ at ENABLE_SERVER_TRUE@@WITH_MON_TRUE@	$(am__DEPENDENCIES_22) \
+ at ENABLE_SERVER_TRUE@@WITH_MON_TRUE@	$(am__DEPENDENCIES_24) \
 @ENABLE_SERVER_TRUE@@WITH_MON_TRUE@	$(am__DEPENDENCIES_10)
 unittest_mon_pgmap_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
 	$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \
@@ -6064,7 +6459,7 @@ unittest_mon_pgmap_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
 am_unittest_mutex_debug_OBJECTS =  \
 	test/common/unittest_mutex_debug-test_mutex_debug.$(OBJEXT)
 unittest_mutex_debug_OBJECTS = $(am_unittest_mutex_debug_OBJECTS)
-unittest_mutex_debug_DEPENDENCIES = $(am__DEPENDENCIES_19) \
+unittest_mutex_debug_DEPENDENCIES = $(am__DEPENDENCIES_24) \
 	$(am__DEPENDENCIES_10) $(am__DEPENDENCIES_3)
 unittest_mutex_debug_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
 	$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \
@@ -6077,8 +6472,8 @@ am__unittest_osd_osdcap_SOURCES_DIST = test/osd/osdcap.cc
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE at am_unittest_osd_osdcap_OBJECTS = test/osd/unittest_osd_osdcap-osdcap.$(OBJEXT)
 unittest_osd_osdcap_OBJECTS = $(am_unittest_osd_osdcap_OBJECTS)
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE at unittest_osd_osdcap_DEPENDENCIES =  \
- at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__DEPENDENCIES_18) \
- at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__DEPENDENCIES_19) \
+ at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__DEPENDENCIES_23) \
+ at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__DEPENDENCIES_24) \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__DEPENDENCIES_10)
 unittest_osd_osdcap_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
 	$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \
@@ -6087,7 +6482,7 @@ unittest_osd_osdcap_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
 am_unittest_osd_types_OBJECTS =  \
 	test/osd/unittest_osd_types-types.$(OBJEXT)
 unittest_osd_types_OBJECTS = $(am_unittest_osd_types_OBJECTS)
-unittest_osd_types_DEPENDENCIES = $(am__DEPENDENCIES_19) \
+unittest_osd_types_DEPENDENCIES = $(am__DEPENDENCIES_24) \
 	$(am__DEPENDENCIES_10)
 unittest_osd_types_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
 	$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \
@@ -6096,7 +6491,7 @@ unittest_osd_types_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
 am_unittest_osdmap_OBJECTS =  \
 	test/osd/unittest_osdmap-TestOSDMap.$(OBJEXT)
 unittest_osdmap_OBJECTS = $(am_unittest_osdmap_OBJECTS)
-unittest_osdmap_DEPENDENCIES = $(am__DEPENDENCIES_19) \
+unittest_osdmap_DEPENDENCIES = $(am__DEPENDENCIES_24) \
 	$(am__DEPENDENCIES_4) $(am__DEPENDENCIES_10)
 unittest_osdmap_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
 	$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \
@@ -6106,8 +6501,8 @@ am__unittest_osdscrub_SOURCES_DIST = test/osd/TestOSDScrub.cc
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE at am_unittest_osdscrub_OBJECTS = test/osd/unittest_osdscrub-TestOSDScrub.$(OBJEXT)
 unittest_osdscrub_OBJECTS = $(am_unittest_osdscrub_OBJECTS)
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE at unittest_osdscrub_DEPENDENCIES =  \
- at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__DEPENDENCIES_18) \
- at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__DEPENDENCIES_19) \
+ at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__DEPENDENCIES_23) \
+ at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__DEPENDENCIES_24) \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__DEPENDENCIES_10) \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__DEPENDENCIES_1)
 unittest_osdscrub_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
@@ -6118,7 +6513,7 @@ am__unittest_pageset_SOURCES_DIST = test/test_pageset.cc
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE at am_unittest_pageset_OBJECTS = test/unittest_pageset-test_pageset.$(OBJEXT)
 unittest_pageset_OBJECTS = $(am_unittest_pageset_OBJECTS)
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE at unittest_pageset_DEPENDENCIES =  \
- at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__DEPENDENCIES_19)
+ at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__DEPENDENCIES_24)
 unittest_pageset_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
 	$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \
 	$(unittest_pageset_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) \
@@ -6126,7 +6521,7 @@ unittest_pageset_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
 am_unittest_perf_counters_OBJECTS =  \
 	test/unittest_perf_counters-perf_counters.$(OBJEXT)
 unittest_perf_counters_OBJECTS = $(am_unittest_perf_counters_OBJECTS)
-unittest_perf_counters_DEPENDENCIES = $(am__DEPENDENCIES_19) \
+unittest_perf_counters_DEPENDENCIES = $(am__DEPENDENCIES_24) \
 	$(am__DEPENDENCIES_10)
 unittest_perf_counters_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
 	$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \
@@ -6136,8 +6531,8 @@ am__unittest_pglog_SOURCES_DIST = test/osd/TestPGLog.cc
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE at am_unittest_pglog_OBJECTS = test/osd/unittest_pglog-TestPGLog.$(OBJEXT)
 unittest_pglog_OBJECTS = $(am_unittest_pglog_OBJECTS)
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE at unittest_pglog_DEPENDENCIES =  \
- at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__DEPENDENCIES_18) \
- at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__DEPENDENCIES_19) \
+ at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__DEPENDENCIES_23) \
+ at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__DEPENDENCIES_24) \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__DEPENDENCIES_10) \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__DEPENDENCIES_1)
 unittest_pglog_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
@@ -6148,7 +6543,7 @@ am_unittest_prebufferedstreambuf_OBJECTS = test/unittest_prebufferedstreambuf-te
 unittest_prebufferedstreambuf_OBJECTS =  \
 	$(am_unittest_prebufferedstreambuf_OBJECTS)
 unittest_prebufferedstreambuf_DEPENDENCIES = $(am__DEPENDENCIES_4) \
-	$(am__DEPENDENCIES_19) $(am__DEPENDENCIES_3)
+	$(am__DEPENDENCIES_24) $(am__DEPENDENCIES_3)
 unittest_prebufferedstreambuf_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
 	$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \
 	$(unittest_prebufferedstreambuf_CXXFLAGS) $(CXXFLAGS) \
@@ -6156,14 +6551,30 @@ unittest_prebufferedstreambuf_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
 am_unittest_prioritized_queue_OBJECTS = test/common/unittest_prioritized_queue-test_prioritized_queue.$(OBJEXT)
 unittest_prioritized_queue_OBJECTS =  \
 	$(am_unittest_prioritized_queue_OBJECTS)
-unittest_prioritized_queue_DEPENDENCIES = $(am__DEPENDENCIES_19) \
+unittest_prioritized_queue_DEPENDENCIES = $(am__DEPENDENCIES_24) \
 	$(am__DEPENDENCIES_10)
 unittest_prioritized_queue_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
 	$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \
 	$(unittest_prioritized_queue_CXXFLAGS) $(CXXFLAGS) \
 	$(AM_LDFLAGS) $(LDFLAGS) -o $@
-am__unittest_rbd_mirror_SOURCES_DIST = test/rbd_mirror/test_main.cc
- at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE at am_unittest_rbd_mirror_OBJECTS = test/rbd_mirror/unittest_rbd_mirror-test_main.$(OBJEXT)
+am__unittest_rbd_mirror_SOURCES_DIST = test/rbd_mirror/test_main.cc \
+	test/rbd_mirror/test_mock_fixture.cc \
+	test/rbd_mirror/test_mock_ImageSync.cc \
+	test/rbd_mirror/image_sync/test_mock_ImageCopyRequest.cc \
+	test/rbd_mirror/image_sync/test_mock_ObjectCopyRequest.cc \
+	test/rbd_mirror/image_sync/test_mock_SnapshotCopyRequest.cc \
+	test/rbd_mirror/image_sync/test_mock_SyncPointCreateRequest.cc \
+	test/rbd_mirror/image_sync/test_mock_SyncPointPruneRequest.cc \
+	test/rbd_mirror/mock/MockJournaler.cc
+ at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE at am_unittest_rbd_mirror_OBJECTS = test/rbd_mirror/unittest_rbd_mirror-test_main.$(OBJEXT) \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	test/rbd_mirror/unittest_rbd_mirror-test_mock_fixture.$(OBJEXT) \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	test/rbd_mirror/unittest_rbd_mirror-test_mock_ImageSync.$(OBJEXT) \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	test/rbd_mirror/image_sync/unittest_rbd_mirror-test_mock_ImageCopyRequest.$(OBJEXT) \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	test/rbd_mirror/image_sync/unittest_rbd_mirror-test_mock_ObjectCopyRequest.$(OBJEXT) \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	test/rbd_mirror/image_sync/unittest_rbd_mirror-test_mock_SnapshotCopyRequest.$(OBJEXT) \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	test/rbd_mirror/image_sync/unittest_rbd_mirror-test_mock_SyncPointCreateRequest.$(OBJEXT) \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	test/rbd_mirror/image_sync/unittest_rbd_mirror-test_mock_SyncPointPruneRequest.$(OBJEXT) \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	test/rbd_mirror/mock/unittest_rbd_mirror-MockJournaler.$(OBJEXT)
 unittest_rbd_mirror_OBJECTS = $(am_unittest_rbd_mirror_OBJECTS)
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE at unittest_rbd_mirror_DEPENDENCIES = librbd_mirror_test.la \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	librados_test_stub.la \
@@ -6178,7 +6589,7 @@ unittest_rbd_mirror_OBJECTS = $(am_unittest_rbd_mirror_OBJECTS)
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	$(LIBRBD_TYPES) \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	$(LIBRADOS) \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	$(LIBOSDC) \
- at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	$(am__DEPENDENCIES_19) \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	$(am__DEPENDENCIES_24) \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	$(am__DEPENDENCIES_10) \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	$(am__DEPENDENCIES_9)
 unittest_rbd_mirror_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
@@ -6194,7 +6605,7 @@ unittest_rbd_replay_OBJECTS = $(am_unittest_rbd_replay_OBJECTS)
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	$(am__DEPENDENCIES_10) \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	librbd_replay.la \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	librbd_replay_ios.la \
- at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	$(am__DEPENDENCIES_19)
+ at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	$(am__DEPENDENCIES_24)
 unittest_rbd_replay_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
 	$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \
 	$(unittest_rbd_replay_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) \
@@ -6202,7 +6613,7 @@ unittest_rbd_replay_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
 am_unittest_readahead_OBJECTS =  \
 	test/common/unittest_readahead-Readahead.$(OBJEXT)
 unittest_readahead_OBJECTS = $(am_unittest_readahead_OBJECTS)
-unittest_readahead_DEPENDENCIES = $(am__DEPENDENCIES_19) \
+unittest_readahead_DEPENDENCIES = $(am__DEPENDENCIES_24) \
 	$(am__DEPENDENCIES_10)
 unittest_readahead_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
 	$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \
@@ -6213,8 +6624,8 @@ am__unittest_rocksdb_option_SOURCES_DIST =  \
 @ENABLE_SERVER_TRUE@@WITH_DLIBROCKSDB_TRUE at am_unittest_rocksdb_option_OBJECTS = test/objectstore/unittest_rocksdb_option-TestRocksdbOptionParse.$(OBJEXT)
 unittest_rocksdb_option_OBJECTS =  \
 	$(am_unittest_rocksdb_option_OBJECTS)
- at ENABLE_SERVER_TRUE@@WITH_DLIBROCKSDB_TRUE at unittest_rocksdb_option_DEPENDENCIES = $(am__DEPENDENCIES_14) \
- at ENABLE_SERVER_TRUE@@WITH_DLIBROCKSDB_TRUE@	$(am__DEPENDENCIES_19) \
+ at ENABLE_SERVER_TRUE@@WITH_DLIBROCKSDB_TRUE at unittest_rocksdb_option_DEPENDENCIES = $(am__DEPENDENCIES_16) \
+ at ENABLE_SERVER_TRUE@@WITH_DLIBROCKSDB_TRUE@	$(am__DEPENDENCIES_24) \
 @ENABLE_SERVER_TRUE@@WITH_DLIBROCKSDB_TRUE@	$(am__DEPENDENCIES_10)
 unittest_rocksdb_option_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
 	$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \
@@ -6225,8 +6636,8 @@ am__unittest_rocksdb_option_static_SOURCES_DIST =  \
 @ENABLE_SERVER_TRUE@@WITH_SLIBROCKSDB_TRUE at am_unittest_rocksdb_option_static_OBJECTS = test/objectstore/unittest_rocksdb_option_static-TestRocksdbOptionParse.$(OBJEXT)
 unittest_rocksdb_option_static_OBJECTS =  \
 	$(am_unittest_rocksdb_option_static_OBJECTS)
- at ENABLE_SERVER_TRUE@@WITH_SLIBROCKSDB_TRUE at unittest_rocksdb_option_static_DEPENDENCIES = $(am__DEPENDENCIES_14) \
- at ENABLE_SERVER_TRUE@@WITH_SLIBROCKSDB_TRUE@	$(am__DEPENDENCIES_19) \
+ at ENABLE_SERVER_TRUE@@WITH_SLIBROCKSDB_TRUE at unittest_rocksdb_option_static_DEPENDENCIES = $(am__DEPENDENCIES_16) \
+ at ENABLE_SERVER_TRUE@@WITH_SLIBROCKSDB_TRUE@	$(am__DEPENDENCIES_24) \
 @ENABLE_SERVER_TRUE@@WITH_SLIBROCKSDB_TRUE@	$(am__DEPENDENCIES_10)
 unittest_rocksdb_option_static_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
 	$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \
@@ -6237,7 +6648,7 @@ am__unittest_run_cmd_SOURCES_DIST = test/run_cmd.cc
 unittest_run_cmd_OBJECTS = $(am_unittest_run_cmd_OBJECTS)
 @ENABLE_CLIENT_TRUE@@WITH_CEPHFS_TRUE@@WITH_RADOS_TRUE at unittest_run_cmd_DEPENDENCIES = $(LIBCEPHFS) \
 @ENABLE_CLIENT_TRUE@@WITH_CEPHFS_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_10) \
- at ENABLE_CLIENT_TRUE@@WITH_CEPHFS_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_19)
+ at ENABLE_CLIENT_TRUE@@WITH_CEPHFS_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_24)
 unittest_run_cmd_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
 	$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \
 	$(unittest_run_cmd_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) \
@@ -6245,7 +6656,7 @@ unittest_run_cmd_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
 am_unittest_safe_io_OBJECTS =  \
 	test/common/unittest_safe_io-test_safe_io.$(OBJEXT)
 unittest_safe_io_OBJECTS = $(am_unittest_safe_io_OBJECTS)
-unittest_safe_io_DEPENDENCIES = $(am__DEPENDENCIES_19) \
+unittest_safe_io_DEPENDENCIES = $(am__DEPENDENCIES_24) \
 	$(am__DEPENDENCIES_10)
 unittest_safe_io_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
 	$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \
@@ -6254,7 +6665,7 @@ unittest_safe_io_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
 am_unittest_shared_cache_OBJECTS =  \
 	test/common/unittest_shared_cache-test_shared_cache.$(OBJEXT)
 unittest_shared_cache_OBJECTS = $(am_unittest_shared_cache_OBJECTS)
-unittest_shared_cache_DEPENDENCIES = $(am__DEPENDENCIES_19) \
+unittest_shared_cache_DEPENDENCIES = $(am__DEPENDENCIES_24) \
 	$(am__DEPENDENCIES_10)
 unittest_shared_cache_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
 	$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \
@@ -6263,7 +6674,7 @@ unittest_shared_cache_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
 am_unittest_sharedptr_registry_OBJECTS = test/common/unittest_sharedptr_registry-test_sharedptr_registry.$(OBJEXT)
 unittest_sharedptr_registry_OBJECTS =  \
 	$(am_unittest_sharedptr_registry_OBJECTS)
-unittest_sharedptr_registry_DEPENDENCIES = $(am__DEPENDENCIES_19) \
+unittest_sharedptr_registry_DEPENDENCIES = $(am__DEPENDENCIES_24) \
 	$(am__DEPENDENCIES_10)
 unittest_sharedptr_registry_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
 	$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \
@@ -6271,7 +6682,7 @@ unittest_sharedptr_registry_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
 	$(AM_LDFLAGS) $(LDFLAGS) -o $@
 am_unittest_shunique_lock_OBJECTS = test/common/unittest_shunique_lock-test_shunique_lock.$(OBJEXT)
 unittest_shunique_lock_OBJECTS = $(am_unittest_shunique_lock_OBJECTS)
-unittest_shunique_lock_DEPENDENCIES = $(am__DEPENDENCIES_19) \
+unittest_shunique_lock_DEPENDENCIES = $(am__DEPENDENCIES_24) \
 	$(am__DEPENDENCIES_10) $(am__DEPENDENCIES_3)
 unittest_shunique_lock_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
 	$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \
@@ -6279,7 +6690,7 @@ unittest_shunique_lock_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
 	$(LDFLAGS) -o $@
 am_unittest_signals_OBJECTS = test/unittest_signals-signals.$(OBJEXT)
 unittest_signals_OBJECTS = $(am_unittest_signals_OBJECTS)
-unittest_signals_DEPENDENCIES = $(am__DEPENDENCIES_19) \
+unittest_signals_DEPENDENCIES = $(am__DEPENDENCIES_24) \
 	$(am__DEPENDENCIES_10)
 unittest_signals_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
 	$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \
@@ -6290,7 +6701,7 @@ am__unittest_simple_spin_SOURCES_DIST = test/simple_spin.cc
 unittest_simple_spin_OBJECTS = $(am_unittest_simple_spin_OBJECTS)
 @ENABLE_CLIENT_TRUE@@WITH_CEPHFS_TRUE@@WITH_RADOS_TRUE at unittest_simple_spin_DEPENDENCIES = $(LIBCEPHFS) \
 @ENABLE_CLIENT_TRUE@@WITH_CEPHFS_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_10) \
- at ENABLE_CLIENT_TRUE@@WITH_CEPHFS_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_19)
+ at ENABLE_CLIENT_TRUE@@WITH_CEPHFS_TRUE@@WITH_RADOS_TRUE@	$(am__DEPENDENCIES_24)
 unittest_simple_spin_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
 	$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \
 	$(unittest_simple_spin_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) \
@@ -6298,7 +6709,7 @@ unittest_simple_spin_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
 am_unittest_sloppy_crc_map_OBJECTS = test/common/unittest_sloppy_crc_map-test_sloppy_crc_map.$(OBJEXT)
 unittest_sloppy_crc_map_OBJECTS =  \
 	$(am_unittest_sloppy_crc_map_OBJECTS)
-unittest_sloppy_crc_map_DEPENDENCIES = $(am__DEPENDENCIES_19) \
+unittest_sloppy_crc_map_DEPENDENCIES = $(am__DEPENDENCIES_24) \
 	$(am__DEPENDENCIES_10)
 unittest_sloppy_crc_map_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
 	$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \
@@ -6307,7 +6718,7 @@ unittest_sloppy_crc_map_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
 am_unittest_str_list_OBJECTS =  \
 	test/unittest_str_list-test_str_list.$(OBJEXT)
 unittest_str_list_OBJECTS = $(am_unittest_str_list_OBJECTS)
-unittest_str_list_DEPENDENCIES = $(am__DEPENDENCIES_19) \
+unittest_str_list_DEPENDENCIES = $(am__DEPENDENCIES_24) \
 	$(am__DEPENDENCIES_10)
 unittest_str_list_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
 	$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \
@@ -6316,7 +6727,7 @@ unittest_str_list_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
 am_unittest_str_map_OBJECTS =  \
 	test/common/unittest_str_map-test_str_map.$(OBJEXT)
 unittest_str_map_OBJECTS = $(am_unittest_str_map_OBJECTS)
-unittest_str_map_DEPENDENCIES = $(am__DEPENDENCIES_19) \
+unittest_str_map_DEPENDENCIES = $(am__DEPENDENCIES_24) \
 	$(am__DEPENDENCIES_10)
 unittest_str_map_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
 	$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \
@@ -6325,7 +6736,7 @@ unittest_str_map_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
 am_unittest_striper_OBJECTS =  \
 	test/unittest_striper-test_striper.$(OBJEXT)
 unittest_striper_OBJECTS = $(am_unittest_striper_OBJECTS)
-unittest_striper_DEPENDENCIES = $(LIBOSDC) $(am__DEPENDENCIES_19) \
+unittest_striper_DEPENDENCIES = $(LIBOSDC) $(am__DEPENDENCIES_24) \
 	$(am__DEPENDENCIES_10)
 unittest_striper_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
 	$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \
@@ -6333,7 +6744,7 @@ unittest_striper_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
 	$(LDFLAGS) -o $@
 am_unittest_strtol_OBJECTS = test/unittest_strtol-strtol.$(OBJEXT)
 unittest_strtol_OBJECTS = $(am_unittest_strtol_OBJECTS)
-unittest_strtol_DEPENDENCIES = $(am__DEPENDENCIES_19) \
+unittest_strtol_DEPENDENCIES = $(am__DEPENDENCIES_24) \
 	$(am__DEPENDENCIES_10)
 unittest_strtol_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
 	$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \
@@ -6343,7 +6754,7 @@ am_unittest_subprocess_OBJECTS =  \
 	test/unittest_subprocess-test_subprocess.$(OBJEXT)
 unittest_subprocess_OBJECTS = $(am_unittest_subprocess_OBJECTS)
 unittest_subprocess_DEPENDENCIES = $(am__DEPENDENCIES_4) \
-	$(am__DEPENDENCIES_19)
+	$(am__DEPENDENCIES_24)
 unittest_subprocess_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
 	$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \
 	$(unittest_subprocess_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) \
@@ -6351,7 +6762,7 @@ unittest_subprocess_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
 am_unittest_tableformatter_OBJECTS = test/common/unittest_tableformatter-test_tableformatter.$(OBJEXT)
 unittest_tableformatter_OBJECTS =  \
 	$(am_unittest_tableformatter_OBJECTS)
-unittest_tableformatter_DEPENDENCIES = $(am__DEPENDENCIES_19) \
+unittest_tableformatter_DEPENDENCIES = $(am__DEPENDENCIES_24) \
 	$(am__DEPENDENCIES_10)
 unittest_tableformatter_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
 	$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \
@@ -6361,7 +6772,7 @@ am_unittest_texttable_OBJECTS =  \
 	test/unittest_texttable-test_texttable.$(OBJEXT)
 unittest_texttable_OBJECTS = $(am_unittest_texttable_OBJECTS)
 unittest_texttable_DEPENDENCIES = $(am__DEPENDENCIES_4) \
-	$(am__DEPENDENCIES_19)
+	$(am__DEPENDENCIES_24)
 unittest_texttable_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
 	$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \
 	$(unittest_texttable_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) \
@@ -6369,7 +6780,7 @@ unittest_texttable_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
 am_unittest_throttle_OBJECTS =  \
 	test/common/unittest_throttle-Throttle.$(OBJEXT)
 unittest_throttle_OBJECTS = $(am_unittest_throttle_OBJECTS)
-unittest_throttle_DEPENDENCIES = $(am__DEPENDENCIES_19) \
+unittest_throttle_DEPENDENCIES = $(am__DEPENDENCIES_24) \
 	$(am__DEPENDENCIES_10)
 unittest_throttle_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
 	$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \
@@ -6379,7 +6790,7 @@ am_unittest_time_OBJECTS =  \
 	test/common/unittest_time-test_time.$(OBJEXT)
 unittest_time_OBJECTS = $(am_unittest_time_OBJECTS)
 unittest_time_DEPENDENCIES = $(am__DEPENDENCIES_4) \
-	$(am__DEPENDENCIES_19) $(am__DEPENDENCIES_1) \
+	$(am__DEPENDENCIES_24) $(am__DEPENDENCIES_1) \
 	$(am__DEPENDENCIES_3)
 unittest_time_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
 	$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \
@@ -6390,8 +6801,8 @@ am__unittest_transaction_SOURCES_DIST =  \
 @ENABLE_SERVER_TRUE at am_unittest_transaction_OBJECTS = test/objectstore/unittest_transaction-test_transaction.$(OBJEXT)
 unittest_transaction_OBJECTS = $(am_unittest_transaction_OBJECTS)
 @ENABLE_SERVER_TRUE at unittest_transaction_DEPENDENCIES =  \
- at ENABLE_SERVER_TRUE@	$(am__DEPENDENCIES_14) \
- at ENABLE_SERVER_TRUE@	$(am__DEPENDENCIES_19) \
+ at ENABLE_SERVER_TRUE@	$(am__DEPENDENCIES_16) \
+ at ENABLE_SERVER_TRUE@	$(am__DEPENDENCIES_24) \
 @ENABLE_SERVER_TRUE@	$(am__DEPENDENCIES_10)
 unittest_transaction_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
 	$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \
@@ -6399,7 +6810,7 @@ unittest_transaction_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
 	$(LDFLAGS) -o $@
 am_unittest_utf8_OBJECTS = test/unittest_utf8-utf8.$(OBJEXT)
 unittest_utf8_OBJECTS = $(am_unittest_utf8_OBJECTS)
-unittest_utf8_DEPENDENCIES = $(am__DEPENDENCIES_19) \
+unittest_utf8_DEPENDENCIES = $(am__DEPENDENCIES_24) \
 	$(am__DEPENDENCIES_10)
 unittest_utf8_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
 	$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \
@@ -6409,7 +6820,7 @@ am_unittest_util_OBJECTS =  \
 	test/common/unittest_util-test_util.$(OBJEXT)
 unittest_util_OBJECTS = $(am_unittest_util_OBJECTS)
 unittest_util_DEPENDENCIES = $(am__DEPENDENCIES_4) \
-	$(am__DEPENDENCIES_19) $(am__DEPENDENCIES_1) \
+	$(am__DEPENDENCIES_24) $(am__DEPENDENCIES_1) \
 	$(am__DEPENDENCIES_3)
 unittest_util_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
 	$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \
@@ -6419,7 +6830,7 @@ am_unittest_weighted_priority_queue_OBJECTS = test/common/unittest_weighted_prio
 unittest_weighted_priority_queue_OBJECTS =  \
 	$(am_unittest_weighted_priority_queue_OBJECTS)
 unittest_weighted_priority_queue_DEPENDENCIES =  \
-	$(am__DEPENDENCIES_19) $(am__DEPENDENCIES_10)
+	$(am__DEPENDENCIES_24) $(am__DEPENDENCIES_10)
 unittest_weighted_priority_queue_LINK = $(LIBTOOL) $(AM_V_lt) \
 	--tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link \
 	$(CXXLD) $(unittest_weighted_priority_queue_CXXFLAGS) \
@@ -6427,7 +6838,7 @@ unittest_weighted_priority_queue_LINK = $(LIBTOOL) $(AM_V_lt) \
 am_unittest_workqueue_OBJECTS =  \
 	test/unittest_workqueue-test_workqueue.$(OBJEXT)
 unittest_workqueue_OBJECTS = $(am_unittest_workqueue_OBJECTS)
-unittest_workqueue_DEPENDENCIES = $(am__DEPENDENCIES_19) \
+unittest_workqueue_DEPENDENCIES = $(am__DEPENDENCIES_24) \
 	$(am__DEPENDENCIES_10)
 unittest_workqueue_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
 	$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \
@@ -6435,7 +6846,7 @@ unittest_workqueue_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
 	$(LDFLAGS) -o $@
 am_unittest_xlist_OBJECTS = test/unittest_xlist-test_xlist.$(OBJEXT)
 unittest_xlist_OBJECTS = $(am_unittest_xlist_OBJECTS)
-unittest_xlist_DEPENDENCIES = $(am__DEPENDENCIES_19) \
+unittest_xlist_DEPENDENCIES = $(am__DEPENDENCIES_24) \
 	$(am__DEPENDENCIES_4)
 unittest_xlist_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
 	$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \
@@ -6447,7 +6858,7 @@ am__xio_client_SOURCES_DIST = test/messenger/xio_client.cc \
 @ENABLE_SERVER_TRUE@@ENABLE_XIO_TRUE@	test/messenger/xio_client-xio_dispatcher.$(OBJEXT)
 xio_client_OBJECTS = $(am_xio_client_OBJECTS)
 @ENABLE_SERVER_TRUE@@ENABLE_XIO_TRUE at xio_client_DEPENDENCIES =  \
- at ENABLE_SERVER_TRUE@@ENABLE_XIO_TRUE@	$(am__DEPENDENCIES_14) \
+ at ENABLE_SERVER_TRUE@@ENABLE_XIO_TRUE@	$(am__DEPENDENCIES_16) \
 @ENABLE_SERVER_TRUE@@ENABLE_XIO_TRUE@	$(am__DEPENDENCIES_10) \
 @ENABLE_SERVER_TRUE@@ENABLE_XIO_TRUE@	$(am__DEPENDENCIES_4) \
 @ENABLE_SERVER_TRUE@@ENABLE_XIO_TRUE@	$(am__DEPENDENCIES_1) \
@@ -6462,7 +6873,7 @@ am__xio_server_SOURCES_DIST = test/messenger/xio_server.cc \
 @ENABLE_SERVER_TRUE@@ENABLE_XIO_TRUE@	test/messenger/xio_server-xio_dispatcher.$(OBJEXT)
 xio_server_OBJECTS = $(am_xio_server_OBJECTS)
 @ENABLE_SERVER_TRUE@@ENABLE_XIO_TRUE at xio_server_DEPENDENCIES =  \
- at ENABLE_SERVER_TRUE@@ENABLE_XIO_TRUE@	$(am__DEPENDENCIES_14) \
+ at ENABLE_SERVER_TRUE@@ENABLE_XIO_TRUE@	$(am__DEPENDENCIES_16) \
 @ENABLE_SERVER_TRUE@@ENABLE_XIO_TRUE@	$(am__DEPENDENCIES_10) \
 @ENABLE_SERVER_TRUE@@ENABLE_XIO_TRUE@	$(am__DEPENDENCIES_4) \
 @ENABLE_SERVER_TRUE@@ENABLE_XIO_TRUE@	$(am__DEPENDENCIES_1) \
@@ -6544,13 +6955,7 @@ AM_V_CCAS = $(am__v_CCAS_ at AM_V@)
 am__v_CCAS_ = $(am__v_CCAS_ at AM_DEFAULT_V@)
 am__v_CCAS_0 = @echo "  CCAS    " $@;
 am__v_CCAS_1 = 
-SOURCES = $(libcls_log_client_a_SOURCES) \
-	$(libcls_replica_log_client_a_SOURCES) \
-	$(libcls_statelog_client_a_SOURCES) \
-	$(libcls_timeindex_client_a_SOURCES) \
-	$(libcls_user_client_a_SOURCES) \
-	$(libcls_version_client_a_SOURCES) $(libkv_a_SOURCES) \
-	$(libmon_a_SOURCES) $(libos_a_SOURCES) \
+SOURCES = $(libkv_a_SOURCES) $(libmon_a_SOURCES) $(libos_a_SOURCES) \
 	$(libos_types_a_SOURCES) $(libos_zfs_a_SOURCES) \
 	$(libosd_a_SOURCES) $(libarch_la_SOURCES) \
 	$(libauth_la_SOURCES) $(libceph_example_la_SOURCES) \
@@ -6562,14 +6967,21 @@ SOURCES = $(libcls_log_client_a_SOURCES) \
 	$(libcls_journal_la_SOURCES) \
 	$(libcls_journal_client_la_SOURCES) $(libcls_kvs_la_SOURCES) \
 	$(libcls_lock_la_SOURCES) $(libcls_lock_client_la_SOURCES) \
-	$(libcls_log_la_SOURCES) $(libcls_numops_la_SOURCES) \
-	$(libcls_numops_client_la_SOURCES) $(libcls_rbd_la_SOURCES) \
-	$(libcls_rbd_client_la_SOURCES) $(libcls_refcount_la_SOURCES) \
+	$(libcls_log_la_SOURCES) $(libcls_log_client_la_SOURCES) \
+	$(libcls_numops_la_SOURCES) $(libcls_numops_client_la_SOURCES) \
+	$(libcls_rbd_la_SOURCES) $(libcls_rbd_client_la_SOURCES) \
+	$(libcls_refcount_la_SOURCES) \
 	$(libcls_refcount_client_la_SOURCES) \
-	$(libcls_replica_log_la_SOURCES) $(libcls_rgw_la_SOURCES) \
-	$(libcls_rgw_client_la_SOURCES) $(libcls_statelog_la_SOURCES) \
-	$(libcls_timeindex_la_SOURCES) $(libcls_user_la_SOURCES) \
-	$(libcls_version_la_SOURCES) $(libcommon_la_SOURCES) \
+	$(libcls_replica_log_la_SOURCES) \
+	$(libcls_replica_log_client_la_SOURCES) \
+	$(libcls_rgw_la_SOURCES) $(libcls_rgw_client_la_SOURCES) \
+	$(libcls_statelog_la_SOURCES) \
+	$(libcls_statelog_client_la_SOURCES) \
+	$(libcls_timeindex_la_SOURCES) \
+	$(libcls_timeindex_client_la_SOURCES) \
+	$(libcls_user_la_SOURCES) $(libcls_user_client_la_SOURCES) \
+	$(libcls_version_la_SOURCES) \
+	$(libcls_version_client_la_SOURCES) $(libcommon_la_SOURCES) \
 	$(libcommon_crc_la_SOURCES) \
 	$(libcommon_crc_aarch64_la_SOURCES) \
 	$(libcommon_internal_la_SOURCES) $(libcompressor_la_SOURCES) \
@@ -6680,6 +7092,7 @@ SOURCES = $(libcls_log_client_a_SOURCES) \
 	$(ceph_test_rados_api_snapshots_SOURCES) \
 	$(ceph_test_rados_api_stat_SOURCES) \
 	$(ceph_test_rados_api_tier_SOURCES) \
+	$(ceph_test_rados_api_tmap_migrate_SOURCES) \
 	$(ceph_test_rados_api_watch_notify_SOURCES) \
 	$(ceph_test_rados_delete_pools_parallel_SOURCES) \
 	$(ceph_test_rados_list_parallel_SOURCES) \
@@ -6689,8 +7102,10 @@ SOURCES = $(libcls_log_client_a_SOURCES) \
 	$(ceph_test_rados_striper_api_striping_SOURCES) \
 	$(ceph_test_rados_watch_notify_SOURCES) \
 	$(ceph_test_rbd_mirror_SOURCES) \
+	$(ceph_test_rbd_mirror_image_replay_SOURCES) \
 	$(ceph_test_rewrite_latency_SOURCES) \
 	$(ceph_test_rgw_manifest_SOURCES) $(ceph_test_rgw_obj_SOURCES) \
+	$(ceph_test_rgw_period_history_SOURCES) \
 	$(ceph_test_signal_handlers_SOURCES) \
 	$(ceph_test_snap_mapper_SOURCES) \
 	$(ceph_test_stress_watch_SOURCES) $(ceph_test_timers_SOURCES) \
@@ -6699,9 +7114,12 @@ SOURCES = $(libcls_log_client_a_SOURCES) \
 	$(cephfs_data_scan_SOURCES) $(cephfs_journal_tool_SOURCES) \
 	$(cephfs_table_tool_SOURCES) $(crushtool_SOURCES) \
 	$(get_command_descriptions_SOURCES) $(librados_config_SOURCES) \
-	$(monmaptool_SOURCES) $(mount_ceph_SOURCES) \
-	$(osdmaptool_SOURCES) $(rados_SOURCES) $(radosgw_SOURCES) \
-	$(radosgw_admin_SOURCES) $(radosgw_object_expirer_SOURCES) \
+	$(librgw_file_SOURCES) $(librgw_file_aw_SOURCES) \
+	$(librgw_file_cd_SOURCES) $(librgw_file_gp_SOURCES) \
+	$(librgw_file_nfsns_SOURCES) $(monmaptool_SOURCES) \
+	$(mount_ceph_SOURCES) $(osdmaptool_SOURCES) $(rados_SOURCES) \
+	$(radosgw_SOURCES) $(radosgw_admin_SOURCES) \
+	$(radosgw_object_expirer_SOURCES) $(radosgw_token_SOURCES) \
 	$(rbd_SOURCES) $(rbd_fuse_SOURCES) $(rbd_mirror_SOURCES) \
 	$(rbd_nbd_SOURCES) $(rbd_replay_SOURCES) \
 	$(rbd_replay_prep_SOURCES) $(simple_client_SOURCES) \
@@ -6782,14 +7200,9 @@ SOURCES = $(libcls_log_client_a_SOURCES) \
 	$(unittest_weighted_priority_queue_SOURCES) \
 	$(unittest_workqueue_SOURCES) $(unittest_xlist_SOURCES) \
 	$(xio_client_SOURCES) $(xio_server_SOURCES)
-DIST_SOURCES = $(am__libcls_log_client_a_SOURCES_DIST) \
-	$(am__libcls_replica_log_client_a_SOURCES_DIST) \
-	$(am__libcls_statelog_client_a_SOURCES_DIST) \
-	$(am__libcls_timeindex_client_a_SOURCES_DIST) \
-	$(am__libcls_user_client_a_SOURCES_DIST) \
-	$(am__libcls_version_client_a_SOURCES_DIST) \
-	$(am__libkv_a_SOURCES_DIST) $(am__libmon_a_SOURCES_DIST) \
-	$(am__libos_a_SOURCES_DIST) $(am__libos_types_a_SOURCES_DIST) \
+DIST_SOURCES = $(am__libkv_a_SOURCES_DIST) \
+	$(am__libmon_a_SOURCES_DIST) $(am__libos_a_SOURCES_DIST) \
+	$(am__libos_types_a_SOURCES_DIST) \
 	$(am__libos_zfs_a_SOURCES_DIST) $(am__libosd_a_SOURCES_DIST) \
 	$(libarch_la_SOURCES) $(libauth_la_SOURCES) \
 	$(am__libceph_example_la_SOURCES_DIST) \
@@ -6808,6 +7221,7 @@ DIST_SOURCES = $(am__libcls_log_client_a_SOURCES_DIST) \
 	$(am__libcls_lock_la_SOURCES_DIST) \
 	$(am__libcls_lock_client_la_SOURCES_DIST) \
 	$(am__libcls_log_la_SOURCES_DIST) \
+	$(am__libcls_log_client_la_SOURCES_DIST) \
 	$(am__libcls_numops_la_SOURCES_DIST) \
 	$(am__libcls_numops_client_la_SOURCES_DIST) \
 	$(am__libcls_rbd_la_SOURCES_DIST) \
@@ -6815,13 +7229,18 @@ DIST_SOURCES = $(am__libcls_log_client_a_SOURCES_DIST) \
 	$(am__libcls_refcount_la_SOURCES_DIST) \
 	$(am__libcls_refcount_client_la_SOURCES_DIST) \
 	$(am__libcls_replica_log_la_SOURCES_DIST) \
+	$(am__libcls_replica_log_client_la_SOURCES_DIST) \
 	$(am__libcls_rgw_la_SOURCES_DIST) \
 	$(am__libcls_rgw_client_la_SOURCES_DIST) \
 	$(am__libcls_statelog_la_SOURCES_DIST) \
+	$(am__libcls_statelog_client_la_SOURCES_DIST) \
 	$(am__libcls_timeindex_la_SOURCES_DIST) \
+	$(am__libcls_timeindex_client_la_SOURCES_DIST) \
 	$(am__libcls_user_la_SOURCES_DIST) \
-	$(am__libcls_version_la_SOURCES_DIST) $(libcommon_la_SOURCES) \
-	$(am__libcommon_crc_la_SOURCES_DIST) \
+	$(am__libcls_user_client_la_SOURCES_DIST) \
+	$(am__libcls_version_la_SOURCES_DIST) \
+	$(am__libcls_version_client_la_SOURCES_DIST) \
+	$(libcommon_la_SOURCES) $(am__libcommon_crc_la_SOURCES_DIST) \
 	$(am__libcommon_crc_aarch64_la_SOURCES_DIST) \
 	$(am__libcommon_internal_la_SOURCES_DIST) \
 	$(libcompressor_la_SOURCES) $(libcrush_la_SOURCES) \
@@ -6961,6 +7380,7 @@ DIST_SOURCES = $(am__libcls_log_client_a_SOURCES_DIST) \
 	$(am__ceph_test_rados_api_snapshots_SOURCES_DIST) \
 	$(am__ceph_test_rados_api_stat_SOURCES_DIST) \
 	$(am__ceph_test_rados_api_tier_SOURCES_DIST) \
+	$(am__ceph_test_rados_api_tmap_migrate_SOURCES_DIST) \
 	$(am__ceph_test_rados_api_watch_notify_SOURCES_DIST) \
 	$(am__ceph_test_rados_delete_pools_parallel_SOURCES_DIST) \
 	$(am__ceph_test_rados_list_parallel_SOURCES_DIST) \
@@ -6970,9 +7390,11 @@ DIST_SOURCES = $(am__libcls_log_client_a_SOURCES_DIST) \
 	$(am__ceph_test_rados_striper_api_striping_SOURCES_DIST) \
 	$(am__ceph_test_rados_watch_notify_SOURCES_DIST) \
 	$(am__ceph_test_rbd_mirror_SOURCES_DIST) \
+	$(am__ceph_test_rbd_mirror_image_replay_SOURCES_DIST) \
 	$(ceph_test_rewrite_latency_SOURCES) \
 	$(am__ceph_test_rgw_manifest_SOURCES_DIST) \
 	$(am__ceph_test_rgw_obj_SOURCES_DIST) \
+	$(am__ceph_test_rgw_period_history_SOURCES_DIST) \
 	$(ceph_test_signal_handlers_SOURCES) \
 	$(am__ceph_test_snap_mapper_SOURCES_DIST) \
 	$(am__ceph_test_stress_watch_SOURCES_DIST) \
@@ -6985,14 +7407,19 @@ DIST_SOURCES = $(am__libcls_log_client_a_SOURCES_DIST) \
 	$(am__cephfs_journal_tool_SOURCES_DIST) \
 	$(am__cephfs_table_tool_SOURCES_DIST) $(crushtool_SOURCES) \
 	$(am__get_command_descriptions_SOURCES_DIST) \
-	$(am__librados_config_SOURCES_DIST) $(monmaptool_SOURCES) \
+	$(am__librados_config_SOURCES_DIST) \
+	$(am__librgw_file_SOURCES_DIST) \
+	$(am__librgw_file_aw_SOURCES_DIST) \
+	$(am__librgw_file_cd_SOURCES_DIST) \
+	$(am__librgw_file_gp_SOURCES_DIST) \
+	$(am__librgw_file_nfsns_SOURCES_DIST) $(monmaptool_SOURCES) \
 	$(am__mount_ceph_SOURCES_DIST) $(osdmaptool_SOURCES) \
 	$(am__rados_SOURCES_DIST) $(am__radosgw_SOURCES_DIST) \
 	$(am__radosgw_admin_SOURCES_DIST) \
 	$(am__radosgw_object_expirer_SOURCES_DIST) \
-	$(am__rbd_SOURCES_DIST) $(am__rbd_fuse_SOURCES_DIST) \
-	$(am__rbd_mirror_SOURCES_DIST) $(am__rbd_nbd_SOURCES_DIST) \
-	$(am__rbd_replay_SOURCES_DIST) \
+	$(am__radosgw_token_SOURCES_DIST) $(am__rbd_SOURCES_DIST) \
+	$(am__rbd_fuse_SOURCES_DIST) $(am__rbd_mirror_SOURCES_DIST) \
+	$(am__rbd_nbd_SOURCES_DIST) $(am__rbd_replay_SOURCES_DIST) \
 	$(am__rbd_replay_prep_SOURCES_DIST) \
 	$(am__simple_client_SOURCES_DIST) \
 	$(am__simple_server_SOURCES_DIST) \
@@ -7100,8 +7527,7 @@ am__can_run_installinfo = \
     *) (install-info --version) >/dev/null 2>&1;; \
   esac
 am__python_PYTHON_DIST = pybind/ceph_argparse.py pybind/ceph_daemon.py \
-	pybind/rados.py pybind/cephfs.py pybind/ceph_volume_client.py \
-	pybind/ceph_rest_api.py
+	pybind/ceph_volume_client.py pybind/ceph_rest_api.py
 am__py_compile = PYTHON=$(PYTHON) $(SHELL) $(py_compile)
 am__pep3147_tweak = \
   sed -e 's|\.py$$||' -e 's|[^/]*$$|__pycache__/&.*.py|'
@@ -7143,18 +7569,19 @@ am__noinst_HEADERS_DIST = arch/intel.h arch/arm.h arch/probe.h \
 	mon/PGMonitor.h mon/Paxos.h mon/PaxosService.h \
 	mon/QuorumService.h mon/Session.h mon/mon_types.h \
 	mds/inode_backtrace.h mds/flock.h mds/locks.c mds/locks.h \
-	mds/CDentry.h mds/CDir.h mds/CInode.h mds/Capability.h \
-	mds/InoTable.h mds/JournalPointer.h mds/LocalLock.h \
-	mds/Locker.h mds/LogEvent.h mds/LogSegment.h mds/MDBalancer.h \
-	mds/MDCache.h mds/RecoveryQueue.h mds/StrayManager.h \
-	mds/MDLog.h mds/MDSRank.h mds/MDSDaemon.h mds/Beacon.h \
-	mds/MDSContext.h mds/MDSAuthCaps.h mds/MDSMap.h mds/MDSTable.h \
-	mds/MDSTableServer.h mds/MDSTableClient.h mds/Mutation.h \
-	mds/Migrator.h mds/ScatterLock.h mds/ScrubStack.h \
-	mds/ScrubHeader.h mds/Server.h mds/SessionMap.h \
-	mds/SimpleLock.h mds/SnapClient.h mds/SnapRealm.h \
-	mds/SnapServer.h mds/mds_table_types.h mds/mdstypes.h \
-	mds/snap.h mds/MDSContinuation.h mds/events/ECommitted.h \
+	mds/CDentry.h mds/CDir.h mds/CInode.h mds/DamageTable.h \
+	mds/Capability.h mds/InoTable.h mds/JournalPointer.h \
+	mds/LocalLock.h mds/Locker.h mds/LogEvent.h mds/LogSegment.h \
+	mds/MDBalancer.h mds/MDCache.h mds/RecoveryQueue.h \
+	mds/StrayManager.h mds/MDLog.h mds/MDSRank.h mds/MDSDaemon.h \
+	mds/Beacon.h mds/MDSContext.h mds/MDSAuthCaps.h mds/MDSMap.h \
+	mds/FSMap.h mds/MDSTable.h mds/MDSTableServer.h \
+	mds/MDSTableClient.h mds/Mutation.h mds/Migrator.h \
+	mds/ScatterLock.h mds/ScrubStack.h mds/ScrubHeader.h \
+	mds/Server.h mds/SessionMap.h mds/SimpleLock.h \
+	mds/SnapClient.h mds/SnapRealm.h mds/SnapServer.h \
+	mds/mds_table_types.h mds/mdstypes.h mds/snap.h \
+	mds/MDSContinuation.h mds/events/ECommitted.h \
 	mds/events/EExport.h mds/events/EFragment.h \
 	mds/events/EImportFinish.h mds/events/EImportStart.h \
 	mds/events/EMetaBlob.h mds/events/ENoOp.h mds/events/EOpen.h \
@@ -7166,7 +7593,8 @@ am__noinst_HEADERS_DIST = arch/intel.h arch/arm.h arch/probe.h \
 	os/filestore/BtrfsFileStoreBackend.h \
 	os/filestore/CollectionIndex.h os/filestore/DBObjectMap.h \
 	os/filestore/FileJournal.h os/filestore/FileStore.h \
-	os/filestore/FDCache.h os/filestore/GenericFileStoreBackend.h \
+	os/filestore/JournalThrottle.h os/filestore/FDCache.h \
+	os/filestore/GenericFileStoreBackend.h \
 	os/filestore/HashIndex.h os/filestore/IndexManager.h \
 	os/filestore/Journal.h os/filestore/JournalingObjectStore.h \
 	os/filestore/LFNIndex.h os/filestore/SequencerPosition.h \
@@ -7187,7 +7615,7 @@ am__noinst_HEADERS_DIST = arch/intel.h arch/arm.h arch/probe.h \
 	osd/PG.h osd/PGLog.h osd/ReplicatedPG.h osd/PGBackend.h \
 	osd/ReplicatedBackend.h osd/TierAgentState.h osd/ECBackend.h \
 	osd/ECUtil.h osd/ECMsgTypes.h osd/ECTransaction.h osd/Watch.h \
-	osd/osd_types.h \
+	osd/ScrubStore.h osd/osd_types.h \
 	erasure-code/jerasure/gf-complete/include/gf_complete.h \
 	erasure-code/jerasure/gf-complete/include/gf_general.h \
 	erasure-code/jerasure/gf-complete/include/gf_int.h \
@@ -7243,11 +7671,11 @@ am__noinst_HEADERS_DIST = arch/intel.h arch/arm.h arch/probe.h \
 	perfglue/cpu_profiler.h perfglue/heap_profiler.h \
 	common/bloom_filter.hpp common/sctp_crc32.h \
 	common/crc32c_intel_baseline.h common/crc32c_intel_fast.h \
-	common/crc32c_aarch64.h common/BackTrace.h \
-	common/RefCountedObj.h common/HeartbeatMap.h \
-	common/LogClient.h common/LogEntry.h common/Graylog.h \
-	common/Preforker.h common/SloppyCRCMap.h common/WorkQueue.h \
-	common/OpQueue.h common/PrioritizedQueue.h \
+	common/crc32c_aarch64.h common/cohort_lru.h common/sstring.hh \
+	xxHash/xxhash.h common/BackTrace.h common/RefCountedObj.h \
+	common/HeartbeatMap.h common/LogClient.h common/LogEntry.h \
+	common/Graylog.h common/Preforker.h common/SloppyCRCMap.h \
+	common/WorkQueue.h common/OpQueue.h common/PrioritizedQueue.h \
 	common/WeightedPriorityQueue.h common/ceph_argparse.h \
 	common/ceph_context.h common/xattr.h common/blkdev.h \
 	common/compiler_extensions.h common/debug.h common/dout.h \
@@ -7280,8 +7708,9 @@ am__noinst_HEADERS_DIST = arch/intel.h arch/arm.h arch/probe.h \
 	common/ContextCompletion.h common/bit_vector.hpp \
 	common/SubProcess.h common/valgrind.h \
 	common/TracepointProvider.h common/event_socket.h \
-	common/PluginRegistry.h common/ceph_time.h common/ceph_timer.h \
-	common/align.h common/mutex_debug.h common/shunique_lock.h \
+	common/PluginRegistry.h common/scrub_types.h \
+	common/ceph_time.h common/ceph_timer.h common/align.h \
+	common/mutex_debug.h common/shunique_lock.h \
 	common/address_helper.h common/secret.h msg/Connection.h \
 	msg/Dispatcher.h msg/Message.h msg/Messenger.h \
 	msg/SimplePolicyMessenger.h msg/msg_types.h \
@@ -7318,16 +7747,16 @@ am__noinst_HEADERS_DIST = arch/intel.h arch/arm.h arch/probe.h \
 	messages/MMDSCacheRejoin.h messages/MMDSLoadTargets.h \
 	messages/MMDSFindIno.h messages/MMDSFindInoReply.h \
 	messages/MMDSFragmentNotify.h messages/MMDSMap.h \
-	messages/MMDSOpenIno.h messages/MMDSOpenInoReply.h \
-	messages/MMDSResolve.h messages/MMDSResolveAck.h \
-	messages/MMDSSlaveRequest.h messages/MMDSTableRequest.h \
-	messages/MMonCommand.h messages/MMonCommandAck.h \
-	messages/MMonElection.h messages/MMonGetMap.h \
-	messages/MMonGetOSDMap.h messages/MMonGetVersion.h \
-	messages/MMonGetVersionReply.h messages/MMonGlobalID.h \
-	messages/MMonHealth.h messages/MMonJoin.h messages/MMonMap.h \
-	messages/MMonMetadata.h messages/MMonPaxos.h \
-	messages/MMonProbe.h messages/MMonScrub.h \
+	messages/MFSMap.h messages/MMDSOpenIno.h \
+	messages/MMDSOpenInoReply.h messages/MMDSResolve.h \
+	messages/MMDSResolveAck.h messages/MMDSSlaveRequest.h \
+	messages/MMDSTableRequest.h messages/MMonCommand.h \
+	messages/MMonCommandAck.h messages/MMonElection.h \
+	messages/MMonGetMap.h messages/MMonGetOSDMap.h \
+	messages/MMonGetVersion.h messages/MMonGetVersionReply.h \
+	messages/MMonGlobalID.h messages/MMonHealth.h \
+	messages/MMonJoin.h messages/MMonMap.h messages/MMonMetadata.h \
+	messages/MMonPaxos.h messages/MMonProbe.h messages/MMonScrub.h \
 	messages/MMonSubscribe.h messages/MMonSubscribeAck.h \
 	messages/MMonSync.h messages/MOSDAlive.h messages/MOSDBoot.h \
 	messages/MOSDFailure.h messages/MOSDMarkMeDown.h \
@@ -7338,6 +7767,8 @@ am__noinst_HEADERS_DIST = arch/intel.h arch/arm.h arch/probe.h \
 	messages/MOSDPGLog.h messages/MOSDPGMissing.h \
 	messages/MOSDPGNotify.h messages/MOSDPGQuery.h \
 	messages/MOSDPGRemove.h messages/MOSDPGScan.h \
+	messages/MOSDPGUpdateLogMissing.h \
+	messages/MOSDPGUpdateLogMissingReply.h \
 	messages/MOSDECSubOpWrite.h messages/MOSDECSubOpWriteReply.h \
 	messages/MOSDECSubOpRead.h messages/MOSDECSubOpReadReply.h \
 	messages/MBackfillReserve.h messages/MRecoveryReserve.h \
@@ -7364,10 +7795,11 @@ am__noinst_HEADERS_DIST = arch/intel.h arch/arm.h arch/probe.h \
 	include/cpp-btree/btree_map.h include/sock_compat.h \
 	include/crc32c.h include/encoding.h include/encoding_btree.h \
 	include/err.h include/error.h include/filepath.h \
-	include/frag.h include/hash.h include/inline_memory.h \
-	include/intarith.h include/interval_set.h include/int_types.h \
-	include/ipaddr.h include/krbd.h include/linux_fiemap.h \
-	include/lru.h include/msgr.h include/object.h include/page.h \
+	include/frag.h include/fs_types.h include/hash.h \
+	include/inline_memory.h include/intarith.h \
+	include/interval_set.h include/int_types.h include/ipaddr.h \
+	include/krbd.h include/linux_fiemap.h include/lru.h \
+	include/msgr.h include/object.h include/page.h \
 	include/rangeset.h include/rados.h include/rbd_types.h \
 	include/statlite.h include/str_list.h include/str_map.h \
 	include/stringify.h include/types.h include/utime.h \
@@ -7377,7 +7809,7 @@ am__noinst_HEADERS_DIST = arch/intel.h arch/arm.h arch/probe.h \
 	include/rados/rados_types.hpp include/rados/librados.hpp \
 	include/rados/librgw.h include/rados/page.h \
 	include/rados/crc32c.h include/rados/buffer.h \
-	include/rados/buffer_fwd.h \
+	include/rados/buffer_fwd.h include/rados/rgw_file.h \
 	include/radosstriper/libradosstriper.h \
 	include/radosstriper/libradosstriper.hpp \
 	include/rbd/features.h include/rbd/librbd.h \
@@ -7412,8 +7844,9 @@ am__noinst_HEADERS_DIST = arch/intel.h arch/arm.h arch/probe.h \
 	librbd/image/CloseRequest.h librbd/image/OpenRequest.h \
 	librbd/image/RefreshParentRequest.h \
 	librbd/image/RefreshRequest.h librbd/image/SetSnapRequest.h \
-	librbd/journal/Replay.h librbd/journal/Types.h \
-	librbd/object_map/InvalidateRequest.h \
+	librbd/image_watcher/Notifier.h \
+	librbd/image_watcher/NotifyLockOwner.h librbd/journal/Replay.h \
+	librbd/journal/Types.h librbd/object_map/InvalidateRequest.h \
 	librbd/object_map/LockRequest.h librbd/object_map/Request.h \
 	librbd/object_map/RefreshRequest.h \
 	librbd/object_map/ResizeRequest.h \
@@ -7433,26 +7866,35 @@ am__noinst_HEADERS_DIST = arch/intel.h arch/arm.h arch/probe.h \
 	librbd/operation/SnapshotRollbackRequest.h \
 	librbd/operation/SnapshotUnprotectRequest.h \
 	librbd/operation/TrimRequest.h rgw/rgw_acl.h rgw/rgw_acl_s3.h \
-	rgw/rgw_acl_swift.h rgw/rgw_client_io.h rgw/rgw_fcgi.h \
-	rgw/rgw_xml.h rgw/rgw_basic_types.h rgw/rgw_cache.h \
-	rgw/rgw_common.h rgw/rgw_cors.h rgw/rgw_cors_s3.h \
-	rgw/rgw_cors_swift.h rgw/rgw_string.h rgw/rgw_formats.h \
-	rgw/rgw_http_errors.h rgw/rgw_log.h rgw/rgw_loadgen.h \
+	rgw/rgw_acl_swift.h rgw/rgw_b64.h rgw/rgw_client_io.h \
+	rgw/rgw_coroutine.h rgw/rgw_cr_rados.h rgw/rgw_cr_rest.h \
+	rgw/rgw_fcgi.h rgw/rgw_xml.h rgw/rgw_token.h \
+	rgw/rgw_basic_types.h rgw/rgw_cache.h rgw/rgw_common.h \
+	rgw/rgw_cors.h rgw/rgw_cors_s3.h rgw/rgw_cors_swift.h \
+	rgw/rgw_string.h rgw/rgw_file.h rgw/rgw_formats.h \
+	rgw/rgw_http_errors.h rgw/rgw_ldap.h rgw/rgw_lib.h \
+	rgw/rgw_lib_frontend.h rgw/rgw_log.h rgw/rgw_loadgen.h \
+	rgw/rgw_process.h rgw/rgw_request.h rgw/rgw_frontend.h \
 	rgw/rgw_multi.h rgw/rgw_policy_s3.h rgw/rgw_gc.h \
-	rgw/rgw_metadata.h rgw/rgw_multi_del.h \
-	rgw/rgw_object_expirer_core.h rgw/rgw_op.h rgw/rgw_orphan.h \
-	rgw/rgw_http_client.h rgw/rgw_swift.h rgw/rgw_swift_auth.h \
-	rgw/rgw_quota.h rgw/rgw_rados.h rgw/rgw_replica_log.h \
-	rgw/rgw_resolve.h rgw/rgw_rest.h rgw/rgw_rest_swift.h \
-	rgw/rgw_rest_s3.h rgw/rgw_auth_s3.h rgw/rgw_rest_admin.h \
-	rgw/rgw_rest_usage.h rgw/rgw_rest_user.h rgw/rgw_rest_bucket.h \
+	rgw/rgw_metadata.h rgw/rgw_meta_sync_status.h \
+	rgw/rgw_multi_del.h rgw/rgw_object_expirer_core.h rgw/rgw_op.h \
+	rgw/rgw_os_lib.h rgw/rgw_orphan.h rgw/rgw_http_client.h \
+	rgw/rgw_swift.h rgw/rgw_swift_auth.h rgw/rgw_quota.h \
+	rgw/rgw_rados.h rgw/rgw_replica_log.h rgw/rgw_resolve.h \
+	rgw/rgw_rest.h rgw/rgw_rest_swift.h rgw/rgw_rest_s3.h \
+	rgw/rgw_auth_s3.h rgw/rgw_rest_admin.h rgw/rgw_rest_usage.h \
+	rgw/rgw_rest_user.h rgw/rgw_rest_bucket.h \
 	rgw/rgw_rest_client.h rgw/rgw_rest_conn.h rgw/rgw_tools.h \
 	rgw/rgw_rest_metadata.h rgw/rgw_rest_log.h \
 	rgw/rgw_rest_opstate.h rgw/rgw_rest_replica_log.h \
-	rgw/rgw_rest_config.h rgw/rgw_usage.h rgw/rgw_user.h \
-	rgw/rgw_bucket.h rgw/rgw_keystone.h rgw/rgw_civetweb.h \
-	rgw/rgw_civetweb_log.h rgw/rgw_website.h \
-	rgw/rgw_rest_s3website.h civetweb/civetweb.h \
+	rgw/rgw_rest_config.h rgw/rgw_rest_realm.h rgw/rgw_sync.h \
+	rgw/rgw_data_sync.h rgw/rgw_usage.h rgw/rgw_user.h \
+	rgw/rgw_bucket.h rgw/rgw_keystone.h rgw/rgw_period_history.h \
+	rgw/rgw_period_pusher.h rgw/rgw_period_puller.h \
+	rgw/rgw_realm_reloader.h rgw/rgw_realm_watcher.h \
+	rgw/rgw_civetweb.h rgw/rgw_boost_asio_coroutine.h \
+	rgw/rgw_boost_asio_yield.h rgw/rgw_civetweb_log.h \
+	rgw/rgw_website.h rgw/rgw_rest_s3website.h civetweb/civetweb.h \
 	civetweb/include/civetweb.h civetweb/include/civetweb_conf.h \
 	civetweb/src/md5.h cls/lock/cls_lock_types.h \
 	cls/lock/cls_lock_ops.h cls/lock/cls_lock_client.h \
@@ -7508,13 +7950,17 @@ am__noinst_HEADERS_DIST = arch/intel.h arch/arm.h arch/probe.h \
 	test/librbd/mock/MockContextWQ.h \
 	test/librbd/mock/MockExclusiveLock.h \
 	test/librbd/mock/MockImageCtx.h \
+	test/librbd/mock/MockImageState.h \
 	test/librbd/mock/MockImageWatcher.h \
 	test/librbd/mock/MockJournal.h \
 	test/librbd/mock/MockObjectMap.h \
 	test/librbd/mock/MockOperations.h \
 	test/librbd/mock/MockReadahead.h \
 	test/librbd/object_map/mock/MockInvalidateRequest.h \
-	test/perf_helper.h test/bench/backend.h test/bench/bencher.h \
+	test/rbd_mirror/test_fixture.h \
+	test/rbd_mirror/test_mock_fixture.h \
+	test/rbd_mirror/mock/MockJournaler.h test/perf_helper.h \
+	test/bench/backend.h test/bench/bencher.h \
 	test/bench/detailed_stat_collector.h test/bench/distribution.h \
 	test/bench/dumb_backend.h test/bench/rados_backend.h \
 	test/bench/rbd_backend.h test/bench/stat_collector.h \
@@ -7541,15 +7987,25 @@ am__noinst_HEADERS_DIST = arch/intel.h arch/arm.h arch/probe.h \
 	tools/rbd/ArgumentTypes.h tools/rbd/IndentStream.h \
 	tools/rbd/OptionPrinter.h tools/rbd/Shell.h tools/rbd/Utils.h \
 	tools/rbd_mirror/ClusterWatcher.h \
-	tools/rbd_mirror/ImageReplayer.h tools/rbd_mirror/Mirror.h \
-	tools/rbd_mirror/PoolWatcher.h tools/rbd_mirror/Replayer.h \
-	tools/rbd_mirror/types.h tools/cephfs/JournalTool.h \
-	tools/cephfs/JournalScanner.h tools/cephfs/JournalFilter.h \
-	tools/cephfs/EventOutput.h tools/cephfs/Resetter.h \
-	tools/cephfs/Dumper.h tools/cephfs/TableTool.h \
-	tools/cephfs/MDSUtility.h tools/RadosDump.h \
-	tools/rados/RadosImport.h tools/ceph_objectstore_tool.h \
-	tools/rados/PoolDump.h tools/cephfs/DataScan.h cls_acl.cc \
+	tools/rbd_mirror/ImageReplayer.h tools/rbd_mirror/ImageSync.h \
+	tools/rbd_mirror/Mirror.h tools/rbd_mirror/PoolWatcher.h \
+	tools/rbd_mirror/Replayer.h tools/rbd_mirror/Threads.h \
+	tools/rbd_mirror/types.h \
+	tools/rbd_mirror/image_replayer/BootstrapRequest.h \
+	tools/rbd_mirror/image_replayer/CloseImageRequest.h \
+	tools/rbd_mirror/image_replayer/OpenLocalImageRequest.h \
+	tools/rbd_mirror/image_sync/ImageCopyRequest.h \
+	tools/rbd_mirror/image_sync/ObjectCopyRequest.h \
+	tools/rbd_mirror/image_sync/SnapshotCopyRequest.h \
+	tools/rbd_mirror/image_sync/SyncPointCreateRequest.h \
+	tools/rbd_mirror/image_sync/SyncPointPruneRequest.h \
+	tools/cephfs/JournalTool.h tools/cephfs/JournalScanner.h \
+	tools/cephfs/JournalFilter.h tools/cephfs/EventOutput.h \
+	tools/cephfs/Resetter.h tools/cephfs/Dumper.h \
+	tools/cephfs/TableTool.h tools/cephfs/MDSUtility.h \
+	tools/RadosDump.h tools/rados/RadosImport.h \
+	tools/ceph_objectstore_tool.h tools/rados/PoolDump.h \
+	tools/cephfs/DataScan.h tools/cephfs/RoleSelector.h cls_acl.cc \
 	cls_crypto.cc fetch_config logrotate.conf sample.ceph.conf \
 	bash_completion/ceph bash_completion/rados bash_completion/rbd \
 	bash_completion/radosgw-admin mount/canonicalize.c \
@@ -7759,47 +8215,6 @@ TEST_LOGS = $(am__test_logs2:.test.log=.log)
 TEST_LOG_DRIVER = $(SHELL) $(top_srcdir)/test-driver
 TEST_LOG_COMPILE = $(TEST_LOG_COMPILER) $(AM_TEST_LOG_FLAGS) \
 	$(TEST_LOG_FLAGS)
-am__DIST_COMMON = $(srcdir)/Makefile-client.am \
-	$(srcdir)/Makefile-env.am $(srcdir)/Makefile-rocksdb.am \
-	$(srcdir)/Makefile-server.am $(srcdir)/Makefile-spdk.am \
-	$(srcdir)/Makefile.in $(srcdir)/acconfig.h.in \
-	$(srcdir)/arch/Makefile.am $(srcdir)/auth/Makefile.am \
-	$(srcdir)/brag/Makefile.am \
-	$(srcdir)/ceph-detect-init/Makefile.am \
-	$(srcdir)/ceph-disk/Makefile.am $(srcdir)/client/Makefile.am \
-	$(srcdir)/cls/Makefile-client.am \
-	$(srcdir)/cls/Makefile-server.am $(srcdir)/cls/Makefile.am \
-	$(srcdir)/common/Makefile.am $(srcdir)/compressor/Makefile.am \
-	$(srcdir)/compressor/snappy/Makefile.am \
-	$(srcdir)/compressor/zlib/Makefile.am \
-	$(srcdir)/crush/Makefile.am $(srcdir)/erasure-code/Makefile.am \
-	$(srcdir)/erasure-code/isa/Makefile.am \
-	$(srcdir)/erasure-code/jerasure/Makefile.am \
-	$(srcdir)/erasure-code/lrc/Makefile.am \
-	$(srcdir)/erasure-code/shec/Makefile.am \
-	$(srcdir)/global/Makefile.am $(srcdir)/include/Makefile.am \
-	$(srcdir)/journal/Makefile.am \
-	$(srcdir)/json_spirit/Makefile.am \
-	$(srcdir)/key_value_store/Makefile.am $(srcdir)/kv/Makefile.am \
-	$(srcdir)/librados/Makefile.am \
-	$(srcdir)/libradosstriper/Makefile.am \
-	$(srcdir)/librbd/Makefile.am $(srcdir)/log/Makefile.am \
-	$(srcdir)/mds/Makefile-client.am \
-	$(srcdir)/mds/Makefile-server.am $(srcdir)/mds/Makefile.am \
-	$(srcdir)/messages/Makefile.am $(srcdir)/mon/Makefile.am \
-	$(srcdir)/msg/Makefile.am $(srcdir)/os/Makefile.am \
-	$(srcdir)/osd/Makefile.am $(srcdir)/osdc/Makefile.am \
-	$(srcdir)/perfglue/Makefile.am $(srcdir)/pybind/Makefile.am \
-	$(srcdir)/rbd_replay/Makefile.am $(srcdir)/rgw/Makefile.am \
-	$(srcdir)/test/Makefile-client.am \
-	$(srcdir)/test/Makefile-server.am $(srcdir)/test/Makefile.am \
-	$(srcdir)/test/compressor/Makefile.am \
-	$(srcdir)/test/erasure-code/Makefile.am \
-	$(srcdir)/test/messenger/Makefile.am \
-	$(srcdir)/tools/Makefile-client.am \
-	$(srcdir)/tools/Makefile-server.am $(srcdir)/tools/Makefile.am \
-	$(srcdir)/tracing/Makefile.am $(top_srcdir)/depcomp \
-	$(top_srcdir)/py-compile $(top_srcdir)/test-driver README TODO
 DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
 am__relativize = \
   dir0=`pwd`; \
@@ -7936,7 +8351,6 @@ LN_S = @LN_S@
 LTLIBOBJS = @LTLIBOBJS@
 LTTNG_GEN_TP_CHECK = @LTTNG_GEN_TP_CHECK@
 LTTNG_GEN_TP_PROG = @LTTNG_GEN_TP_PROG@
-LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
 MAKEINFO = @MAKEINFO@
 MANIFEST_TOOL = @MANIFEST_TOOL@
 MKDIR_P = @MKDIR_P@
@@ -7963,7 +8377,10 @@ PTHREAD_CC = @PTHREAD_CC@
 PTHREAD_CFLAGS = @PTHREAD_CFLAGS@
 PTHREAD_LIBS = @PTHREAD_LIBS@
 PYTHON = @PYTHON@
+PYTHON_CFLAGS = @PYTHON_CFLAGS@
+PYTHON_CONFIG_CHECK = @PYTHON_CONFIG_CHECK@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
+PYTHON_LDFLAGS = @PYTHON_LDFLAGS@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
 PYTHON_PREFIX = @PYTHON_PREFIX@
 PYTHON_VERSION = @PYTHON_VERSION@
@@ -8032,7 +8449,6 @@ program_transform_name = @program_transform_name@
 psdir = @psdir@
 pyexecdir = @pyexecdir@
 pythondir = @pythondir@
-runstatedir = @runstatedir@
 sbindir = @sbindir@
 sharedstatedir = @sharedstatedir@
 srcdir = @srcdir@
@@ -8050,7 +8466,7 @@ top_srcdir = @top_srcdir@
 AUTOMAKE_OPTIONS = gnu subdir-objects
 SUBDIRS = ocf java
 DIST_SUBDIRS = gmock ocf java
-BUILT_SOURCES = $(am__append_275) $(am__append_297)
+BUILT_SOURCES = $(am__append_280) $(am__append_310)
 
 # extra bits
 EXTRA_DIST = $(am__append_31) ceph-detect-init/AUTHORS.rst \
@@ -8742,7 +9158,7 @@ EXTRA_DIST = $(am__append_31) ceph-detect-init/AUTHORS.rst \
 	spdk/include/spdk/queue_extras.h spdk/include/spdk/file.h \
 	spdk/include/spdk/assert.h spdk/include/spdk/barrier.h \
 	spdk/include/spdk/mmio.h tracing/tracing-common.h \
-	$(srcdir)/pybind/setup.py $(srcdir)/pybind/rbd.pyx \
+	$(am__append_281) $(am__append_285) $(am__append_289) \
 	$(srcdir)/$(shell_scripts:%=%.in) $(srcdir)/vstart.sh \
 	$(srcdir)/stop.sh ceph-run $(srcdir)/ceph-osd-prestart.sh \
 	$(srcdir)/ceph_common.sh $(srcdir)/init-radosgw \
@@ -8762,6 +9178,9 @@ EXTRA_DIST = $(am__append_31) ceph-detect-init/AUTHORS.rst \
 	$(srcdir)/upstart/ceph-mds.conf \
 	$(srcdir)/upstart/ceph-mds-all.conf \
 	$(srcdir)/upstart/ceph-mds-all-starter.conf \
+	$(srcdir)/upstart/ceph-rbd-mirror.conf \
+	$(srcdir)/upstart/ceph-rbd-mirror-all.conf \
+	$(srcdir)/upstart/ceph-rbd-mirror-all-starter.conf \
 	$(srcdir)/upstart/radosgw.conf \
 	$(srcdir)/upstart/radosgw-all.conf \
 	$(srcdir)/upstart/radosgw-all-starter.conf \
@@ -8864,11 +9283,11 @@ noinst_HEADERS = arch/intel.h arch/arm.h arch/probe.h \
 	perfglue/cpu_profiler.h perfglue/heap_profiler.h \
 	common/bloom_filter.hpp common/sctp_crc32.h \
 	common/crc32c_intel_baseline.h common/crc32c_intel_fast.h \
-	common/crc32c_aarch64.h common/BackTrace.h \
-	common/RefCountedObj.h common/HeartbeatMap.h \
-	common/LogClient.h common/LogEntry.h common/Graylog.h \
-	common/Preforker.h common/SloppyCRCMap.h common/WorkQueue.h \
-	common/OpQueue.h common/PrioritizedQueue.h \
+	common/crc32c_aarch64.h common/cohort_lru.h common/sstring.hh \
+	xxHash/xxhash.h common/BackTrace.h common/RefCountedObj.h \
+	common/HeartbeatMap.h common/LogClient.h common/LogEntry.h \
+	common/Graylog.h common/Preforker.h common/SloppyCRCMap.h \
+	common/WorkQueue.h common/OpQueue.h common/PrioritizedQueue.h \
 	common/WeightedPriorityQueue.h common/ceph_argparse.h \
 	common/ceph_context.h common/xattr.h common/blkdev.h \
 	common/compiler_extensions.h common/debug.h common/dout.h \
@@ -8901,50 +9320,50 @@ noinst_HEADERS = arch/intel.h arch/arm.h arch/probe.h \
 	common/ContextCompletion.h common/bit_vector.hpp \
 	common/SubProcess.h common/valgrind.h \
 	common/TracepointProvider.h common/event_socket.h \
-	common/PluginRegistry.h common/ceph_time.h common/ceph_timer.h \
-	common/align.h common/mutex_debug.h common/shunique_lock.h \
-	$(am__append_117) common/secret.h msg/Connection.h \
-	msg/Dispatcher.h msg/Message.h msg/Messenger.h \
-	msg/SimplePolicyMessenger.h msg/msg_types.h \
-	msg/simple/Accepter.h msg/simple/DispatchQueue.h \
-	msg/simple/Pipe.h msg/simple/PipeConnection.h \
-	msg/simple/SimpleMessenger.h msg/async/AsyncConnection.h \
-	msg/async/AsyncMessenger.h msg/async/Event.h \
-	msg/async/EventEpoll.h msg/async/EventSelect.h \
-	msg/async/net_handler.h $(am__append_126) messages/MAuth.h \
-	messages/MAuthReply.h messages/MCacheExpire.h \
-	messages/MClientCaps.h messages/MClientCapRelease.h \
-	messages/MClientLease.h messages/MClientReconnect.h \
-	messages/MClientReply.h messages/MClientRequest.h \
-	messages/MClientRequestForward.h messages/MClientSession.h \
-	messages/MClientSnap.h messages/MClientQuota.h \
-	messages/MCommand.h messages/MCommandReply.h \
-	messages/MDentryLink.h messages/MDentryUnlink.h \
-	messages/MDirUpdate.h messages/MDiscover.h \
-	messages/MDiscoverReply.h messages/MExportCaps.h \
-	messages/MExportCapsAck.h messages/MGatherCaps.h \
-	messages/MExportDir.h messages/MExportDirAck.h \
-	messages/MExportDirCancel.h messages/MExportDirDiscover.h \
-	messages/MExportDirDiscoverAck.h messages/MExportDirFinish.h \
-	messages/MExportDirNotify.h messages/MExportDirNotifyAck.h \
-	messages/MExportDirPrep.h messages/MExportDirPrepAck.h \
-	messages/MGenericMessage.h messages/MGetPoolStats.h \
-	messages/MGetPoolStatsReply.h messages/MHeartbeat.h \
-	messages/MInodeFileCaps.h messages/MLock.h messages/MLog.h \
-	messages/MLogAck.h messages/MMDSBeacon.h \
-	messages/MMDSCacheRejoin.h messages/MMDSLoadTargets.h \
-	messages/MMDSFindIno.h messages/MMDSFindInoReply.h \
-	messages/MMDSFragmentNotify.h messages/MMDSMap.h \
-	messages/MMDSOpenIno.h messages/MMDSOpenInoReply.h \
-	messages/MMDSResolve.h messages/MMDSResolveAck.h \
-	messages/MMDSSlaveRequest.h messages/MMDSTableRequest.h \
-	messages/MMonCommand.h messages/MMonCommandAck.h \
-	messages/MMonElection.h messages/MMonGetMap.h \
-	messages/MMonGetOSDMap.h messages/MMonGetVersion.h \
-	messages/MMonGetVersionReply.h messages/MMonGlobalID.h \
-	messages/MMonHealth.h messages/MMonJoin.h messages/MMonMap.h \
-	messages/MMonMetadata.h messages/MMonPaxos.h \
-	messages/MMonProbe.h messages/MMonScrub.h \
+	common/PluginRegistry.h common/scrub_types.h \
+	common/ceph_time.h common/ceph_timer.h common/align.h \
+	common/mutex_debug.h common/shunique_lock.h $(am__append_116) \
+	common/secret.h msg/Connection.h msg/Dispatcher.h \
+	msg/Message.h msg/Messenger.h msg/SimplePolicyMessenger.h \
+	msg/msg_types.h msg/simple/Accepter.h \
+	msg/simple/DispatchQueue.h msg/simple/Pipe.h \
+	msg/simple/PipeConnection.h msg/simple/SimpleMessenger.h \
+	msg/async/AsyncConnection.h msg/async/AsyncMessenger.h \
+	msg/async/Event.h msg/async/EventEpoll.h \
+	msg/async/EventSelect.h msg/async/net_handler.h \
+	$(am__append_125) messages/MAuth.h messages/MAuthReply.h \
+	messages/MCacheExpire.h messages/MClientCaps.h \
+	messages/MClientCapRelease.h messages/MClientLease.h \
+	messages/MClientReconnect.h messages/MClientReply.h \
+	messages/MClientRequest.h messages/MClientRequestForward.h \
+	messages/MClientSession.h messages/MClientSnap.h \
+	messages/MClientQuota.h messages/MCommand.h \
+	messages/MCommandReply.h messages/MDentryLink.h \
+	messages/MDentryUnlink.h messages/MDirUpdate.h \
+	messages/MDiscover.h messages/MDiscoverReply.h \
+	messages/MExportCaps.h messages/MExportCapsAck.h \
+	messages/MGatherCaps.h messages/MExportDir.h \
+	messages/MExportDirAck.h messages/MExportDirCancel.h \
+	messages/MExportDirDiscover.h messages/MExportDirDiscoverAck.h \
+	messages/MExportDirFinish.h messages/MExportDirNotify.h \
+	messages/MExportDirNotifyAck.h messages/MExportDirPrep.h \
+	messages/MExportDirPrepAck.h messages/MGenericMessage.h \
+	messages/MGetPoolStats.h messages/MGetPoolStatsReply.h \
+	messages/MHeartbeat.h messages/MInodeFileCaps.h \
+	messages/MLock.h messages/MLog.h messages/MLogAck.h \
+	messages/MMDSBeacon.h messages/MMDSCacheRejoin.h \
+	messages/MMDSLoadTargets.h messages/MMDSFindIno.h \
+	messages/MMDSFindInoReply.h messages/MMDSFragmentNotify.h \
+	messages/MMDSMap.h messages/MFSMap.h messages/MMDSOpenIno.h \
+	messages/MMDSOpenInoReply.h messages/MMDSResolve.h \
+	messages/MMDSResolveAck.h messages/MMDSSlaveRequest.h \
+	messages/MMDSTableRequest.h messages/MMonCommand.h \
+	messages/MMonCommandAck.h messages/MMonElection.h \
+	messages/MMonGetMap.h messages/MMonGetOSDMap.h \
+	messages/MMonGetVersion.h messages/MMonGetVersionReply.h \
+	messages/MMonGlobalID.h messages/MMonHealth.h \
+	messages/MMonJoin.h messages/MMonMap.h messages/MMonMetadata.h \
+	messages/MMonPaxos.h messages/MMonProbe.h messages/MMonScrub.h \
 	messages/MMonSubscribe.h messages/MMonSubscribeAck.h \
 	messages/MMonSync.h messages/MOSDAlive.h messages/MOSDBoot.h \
 	messages/MOSDFailure.h messages/MOSDMarkMeDown.h \
@@ -8955,6 +9374,8 @@ noinst_HEADERS = arch/intel.h arch/arm.h arch/probe.h \
 	messages/MOSDPGLog.h messages/MOSDPGMissing.h \
 	messages/MOSDPGNotify.h messages/MOSDPGQuery.h \
 	messages/MOSDPGRemove.h messages/MOSDPGScan.h \
+	messages/MOSDPGUpdateLogMissing.h \
+	messages/MOSDPGUpdateLogMissingReply.h \
 	messages/MOSDECSubOpWrite.h messages/MOSDECSubOpWriteReply.h \
 	messages/MOSDECSubOpRead.h messages/MOSDECSubOpReadReply.h \
 	messages/MBackfillReserve.h messages/MRecoveryReserve.h \
@@ -8981,10 +9402,11 @@ noinst_HEADERS = arch/intel.h arch/arm.h arch/probe.h \
 	include/cpp-btree/btree_map.h include/sock_compat.h \
 	include/crc32c.h include/encoding.h include/encoding_btree.h \
 	include/err.h include/error.h include/filepath.h \
-	include/frag.h include/hash.h include/inline_memory.h \
-	include/intarith.h include/interval_set.h include/int_types.h \
-	include/ipaddr.h include/krbd.h include/linux_fiemap.h \
-	include/lru.h include/msgr.h include/object.h include/page.h \
+	include/frag.h include/fs_types.h include/hash.h \
+	include/inline_memory.h include/intarith.h \
+	include/interval_set.h include/int_types.h include/ipaddr.h \
+	include/krbd.h include/linux_fiemap.h include/lru.h \
+	include/msgr.h include/object.h include/page.h \
 	include/rangeset.h include/rados.h include/rbd_types.h \
 	include/statlite.h include/str_list.h include/str_map.h \
 	include/stringify.h include/types.h include/utime.h \
@@ -8994,7 +9416,7 @@ noinst_HEADERS = arch/intel.h arch/arm.h arch/probe.h \
 	include/rados/rados_types.hpp include/rados/librados.hpp \
 	include/rados/librgw.h include/rados/page.h \
 	include/rados/crc32c.h include/rados/buffer.h \
-	include/rados/buffer_fwd.h \
+	include/rados/buffer_fwd.h include/rados/rgw_file.h \
 	include/radosstriper/libradosstriper.h \
 	include/radosstriper/libradosstriper.hpp \
 	include/rbd/features.h include/rbd/librbd.h \
@@ -9004,10 +9426,10 @@ noinst_HEADERS = arch/intel.h arch/arm.h arch/probe.h \
 	include/unordered_set.h include/unordered_map.h \
 	include/timegm.h include/event_type.h $(am__append_132) \
 	$(am__append_135) $(am__append_136) $(am__append_141) \
-	$(am__append_147) $(am__append_151) $(am__append_154) \
-	$(am__append_155) $(am__append_161) $(am__append_197) \
-	$(am__append_203) $(am__append_215) $(am__append_223) \
-	$(am__append_229) $(am__append_241) test/bench/backend.h \
+	$(am__append_151) $(am__append_153) $(am__append_156) \
+	$(am__append_157) $(am__append_163) $(am__append_199) \
+	$(am__append_205) $(am__append_217) $(am__append_225) \
+	$(am__append_231) $(am__append_243) test/bench/backend.h \
 	test/bench/bencher.h test/bench/detailed_stat_collector.h \
 	test/bench/distribution.h test/bench/dumb_backend.h \
 	test/bench/rados_backend.h test/bench/rbd_backend.h \
@@ -9030,55 +9452,54 @@ noinst_HEADERS = arch/intel.h arch/arm.h arch/probe.h \
 	test/system/st_rados_list_objects.h \
 	test/system/st_rados_notify.h test/system/st_rados_watch.h \
 	test/system/systest_runnable.h test/system/systest_settings.h \
-	test/unit.h test/journal/RadosTestFixture.h $(am__append_265) \
+	test/unit.h test/journal/RadosTestFixture.h $(am__append_268) \
 	tools/cephfs/JournalTool.h tools/cephfs/JournalScanner.h \
 	tools/cephfs/JournalFilter.h tools/cephfs/EventOutput.h \
 	tools/cephfs/Resetter.h tools/cephfs/Dumper.h \
 	tools/cephfs/TableTool.h tools/cephfs/MDSUtility.h \
 	tools/RadosDump.h tools/rados/RadosImport.h \
 	tools/ceph_objectstore_tool.h tools/rados/PoolDump.h \
-	tools/cephfs/DataScan.h cls_acl.cc cls_crypto.cc fetch_config \
-	logrotate.conf sample.ceph.conf bash_completion/ceph \
-	bash_completion/rados bash_completion/rbd \
+	tools/cephfs/DataScan.h tools/cephfs/RoleSelector.h cls_acl.cc \
+	cls_crypto.cc fetch_config logrotate.conf sample.ceph.conf \
+	bash_completion/ceph bash_completion/rados bash_completion/rbd \
 	bash_completion/radosgw-admin mount/canonicalize.c \
 	mount/mtab.c objclass/objclass.h
-bin_SCRIPTS = $(am__append_30) $(am__append_285) $(am__append_294) \
-	$(am__append_302)
+bin_SCRIPTS = $(am__append_30) $(am__append_298) $(am__append_307) \
+	$(am__append_315)
 sbin_SCRIPTS = 
-su_sbin_SCRIPTS = $(am__append_299)
+su_sbin_SCRIPTS = $(am__append_312)
 dist_bin_SCRIPTS = 
 lib_LTLIBRARIES = $(am__append_131) $(am__append_134) \
-	$(am__append_140) $(am__append_274) $(am__append_292) \
-	$(am__append_293)
+	$(am__append_140) $(am__append_146) $(am__append_279) \
+	$(am__append_305) $(am__append_306)
 noinst_LTLIBRARIES = libarch.la libauth.la libcrush.la libmon_types.la \
 	$(am__append_49) libosd_types.la $(am__append_87) \
 	liberasure_code.la libcompressor.la libosdc.la \
 	$(am__append_92) $(am__append_94) libglobal.la \
 	libjson_spirit.la liblog.la libperfglue.la \
-	libcommon_internal.la libcommon_crc.la $(am__append_115) \
-	libcommon.la $(am__append_118) libmsg.la $(am__append_127) \
-	librbd_types.la $(am__append_138) $(am__append_143) \
-	$(am__append_148) $(am__append_156) $(am__append_216) \
-	$(am__append_226) $(am__append_231) $(am__append_259) \
-	$(am__append_267) $(am__append_286)
+	libcommon_internal.la libcommon_crc.la $(am__append_114) \
+	libcommon.la $(am__append_117) libmsg.la $(am__append_127) \
+	librbd_types.la $(am__append_138) $(am__append_148) \
+	$(am__append_152) $(am__append_158) $(am__append_218) \
+	$(am__append_228) $(am__append_233) $(am__append_261) \
+	$(am__append_272) $(am__append_299)
 noinst_LIBRARIES = $(am__append_32) $(am__append_45) libos_types.a \
-	$(am__append_57) $(am__append_61) $(am__append_67) \
-	$(am__append_150)
-radoslib_LTLIBRARIES = $(am__append_152) $(am__append_153)
+	$(am__append_57) $(am__append_61) $(am__append_67)
+radoslib_LTLIBRARIES = $(am__append_154) $(am__append_155)
 
 # like bin_PROGRAMS, but these targets are only built for debug builds
-bin_DEBUGPROGRAMS = $(am__append_96) $(am__append_146) \
-	$(am__append_163) $(am__append_217) $(am__append_218) \
-	$(am__append_219) $(am__append_220) $(am__append_222) \
-	$(am__append_224) $(am__append_230) $(am__append_232) \
-	$(am__append_233) $(am__append_236) $(am__append_238) \
-	$(am__append_239) $(am__append_240) $(am__append_242) \
-	$(am__append_244) $(am__append_246) $(am__append_247) \
-	$(am__append_253) ceph_test_timers ceph_test_signal_handlers \
-	ceph_test_rewrite_latency ceph_test_crypto $(am__append_258) \
+bin_DEBUGPROGRAMS = $(am__append_96) $(am__append_150) \
+	$(am__append_165) $(am__append_219) $(am__append_220) \
+	$(am__append_221) $(am__append_222) $(am__append_224) \
+	$(am__append_226) $(am__append_232) $(am__append_234) \
+	$(am__append_235) $(am__append_238) $(am__append_240) \
+	$(am__append_241) $(am__append_242) $(am__append_244) \
+	$(am__append_246) $(am__append_248) $(am__append_249) \
+	$(am__append_255) ceph_test_timers ceph_test_signal_handlers \
+	ceph_test_rewrite_latency ceph_test_crypto $(am__append_260) \
 	ceph_bench_log ceph_test_objectcacher_stress \
-	ceph_test_cfuse_cache_invalidate $(am__append_262) \
-	$(am__append_263) $(am__append_269) $(am__append_270) \
+	ceph_test_cfuse_cache_invalidate $(am__append_264) \
+	$(am__append_265) $(am__append_274) $(am__append_275) \
 	ceph_psim
 
 # like sbin_SCRIPTS but can be used to install to e.g. /usr/sbin
@@ -9088,12 +9509,12 @@ ceph_sbindir = $(sbindir)
 su_sbindir = /sbin
 
 # C/C++ tests to build and executed will be appended to this
-check_TESTPROGRAMS = $(am__append_179) $(am__append_183) \
-	$(am__append_186) $(am__append_221) $(am__append_225) \
-	$(am__append_234) $(am__append_243) $(am__append_245) \
-	$(am__append_249) $(am__append_250) $(am__append_254) \
-	$(am__append_255) $(am__append_256) $(am__append_257) \
-	unittest_addrs $(am__append_261) unittest_bloom_filter \
+check_TESTPROGRAMS = $(am__append_181) $(am__append_185) \
+	$(am__append_188) $(am__append_223) $(am__append_227) \
+	$(am__append_236) $(am__append_245) $(am__append_247) \
+	$(am__append_251) $(am__append_252) $(am__append_256) \
+	$(am__append_257) $(am__append_258) $(am__append_259) \
+	unittest_addrs $(am__append_263) unittest_bloom_filter \
 	unittest_histogram unittest_prioritized_queue \
 	unittest_weighted_priority_queue unittest_str_map \
 	unittest_mutex_debug unittest_shunique_lock \
@@ -9155,13 +9576,13 @@ check_TESTPROGRAMS = $(am__append_179) $(am__append_183) \
 # GNU Library Public License for more details.
 #
 check_SCRIPTS = ceph-detect-init/run-tox.sh ceph-disk/run-tox.sh \
-	$(am__append_160) $(am__append_228) \
+	$(am__append_162) $(am__append_230) \
 	test/ceph_objectstore_tool.py test/test-ceph-helpers.sh \
 	test/cephtool-test-osd.sh test/cephtool-test-mon.sh \
 	test/cephtool-test-mds.sh test/cephtool-test-rados.sh \
-	unittest_bufferlist.sh test/encoding/check-generated.sh \
-	test/mon/osd-pool-create.sh test/mon/misc.sh \
-	test/mon/osd-crush.sh test/mon/mon-ping.sh \
+	test/test_pool_create.sh unittest_bufferlist.sh \
+	test/encoding/check-generated.sh test/mon/osd-pool-create.sh \
+	test/mon/misc.sh test/mon/osd-crush.sh test/mon/mon-ping.sh \
 	test/mon/mon-created-time.sh \
 	test/mon/osd-erasure-code-profile.sh test/mon/mkfs.sh \
 	test/mon/mon-scrub.sh test/osd/osd-scrub-repair.sh \
@@ -9188,7 +9609,7 @@ HARDENING_CFLAGS = \
                    --param=ssp-buffer-size=4 \
                    -fPIE
 
-SET_STACK_PROTECTOR_STRONG = $(shell expr `gcc -dumpversion` \>= 4.9)
+SET_STACK_PROTECTOR_STRONG = $(shell expr `$(CC) -dumpversion` \>= 4.9)
 HARDENING_LDFLAGS = \
                      -pie \
                      -Wl,-z,relro \
@@ -9275,26 +9696,32 @@ CEPH_GLOBAL = $(LIBGLOBAL) $(LIBCOMMON) $(PTHREAD_LIBS) -lm $(CRYPTO_LIBS) $(EXT
 
 # important; libmsg before libauth!
 LIBCOMMON_DEPS = libcommon_internal.la libcommon_crc.la \
-	$(am__append_114) $(LIBERASURE_CODE) $(LIBCOMPRESSOR) \
+	$(am__append_113) $(LIBERASURE_CODE) $(LIBCOMPRESSOR) \
 	$(LIBMSG) $(LIBAUTH) $(LIBCRUSH) $(LIBJSON_SPIRIT) $(LIBLOG) \
-	$(LIBARCH) $(BOOST_RANDOM_LIBS) -luuid $(am__append_116)
+	$(LIBARCH) $(BOOST_RANDOM_LIBS) -luuid $(am__append_115)
 LIBRADOS_DEPS = $(am__append_128)
-LIBRGW_DEPS = $(am__append_144)
+LIBRGW_DEPS = $(am__append_145)
+LIBCIVETWEB_DEPS = $(am__append_147)
 
 # This is used by the dencoder test
 
 # Do not use TCMALLOC with dencoder
 DENCODER_SOURCES = $(am__append_47) perfglue/disabled_heap_profiler.cc \
 	perfglue/disabled_stubs.cc $(am__append_142)
-DENCODER_DEPS = $(am__append_48) $(am__append_137) $(am__append_149) \
-	$(am__append_157)
+DENCODER_DEPS = $(am__append_48) $(am__append_137) $(am__append_143) \
+	$(am__append_159)
+
+# put virtualenvs in this directory for build
+CEPH_BUILD_VIRTUALENV = "/tmp/"
 radoslibdir = $(libdir)/rados-classes
-LOCAL_ALL = ceph-detect-init-all ceph-disk-all $(am__append_276)
-LOCAL_CLEAN = ceph-detect-init-clean ceph-disk-clean $(am__append_277) \
-	base-clean-local
+LOCAL_ALL = ceph-detect-init-all ceph-disk-all $(am__append_282) \
+	$(am__append_286) $(am__append_290)
+LOCAL_CLEAN = ceph-detect-init-clean ceph-disk-clean $(am__append_283) \
+	$(am__append_287) $(am__append_291) base-clean-local
 LOCAL_INSTALLDATA = ceph-detect-init-install-data \
 	ceph-disk-install-data base-install-data-local
-LOCAL_INSTALLEXEC = $(am__append_278)
+LOCAL_INSTALLEXEC = $(am__append_284) $(am__append_288) \
+	$(am__append_292)
 libarch_la_SOURCES = \
 	arch/intel.c \
 	arch/arm.c \
@@ -9334,6 +9761,12 @@ libcrush_la_SOURCES = \
 @ENABLE_SERVER_TRUE@	$(am__append_42)
 @ENABLE_SERVER_TRUE at libkv_a_LIBADD = $(am__append_36) $(am__append_39) \
 @ENABLE_SERVER_TRUE@	$(am__append_43)
+ at ENABLE_SERVER_TRUE@@FREEBSD_TRUE@@WITH_SLIBROCKSDB_TRUE at NPROC = sysctl -n hw.ncpu
+
+# build rocksdb with its own makefile
+# for some stupid reason this needs -fPIC...
+# PORTABLE=1 fixes the aarch64 build (-march=native doesn't work there)
+ at ENABLE_SERVER_TRUE@@WITH_SLIBROCKSDB_TRUE at NPROC = nproc
 libmon_types_la_SOURCES = \
 	mon/PGMap.cc
 
@@ -9371,6 +9804,7 @@ LIBMDS_SOURCES = \
 	mds/CDentry.cc \
 	mds/CDir.cc \
 	mds/CInode.cc \
+	mds/DamageTable.cc \
 	mds/LogEvent.cc \
 	mds/MDSTable.cc \
 	mds/InoTable.cc \
@@ -9397,6 +9831,7 @@ libos_types_a_CXXFLAGS = ${AM_CXXFLAGS}
 @ENABLE_SERVER_TRUE@	os/filestore/DBObjectMap.cc \
 @ENABLE_SERVER_TRUE@	os/filestore/FileJournal.cc \
 @ENABLE_SERVER_TRUE@	os/filestore/FileStore.cc \
+ at ENABLE_SERVER_TRUE@	os/filestore/JournalThrottle.cc \
 @ENABLE_SERVER_TRUE@	os/filestore/GenericFileStoreBackend.cc \
 @ENABLE_SERVER_TRUE@	os/filestore/HashIndex.cc \
 @ENABLE_SERVER_TRUE@	os/filestore/IndexManager.cc \
@@ -9445,6 +9880,7 @@ libosd_types_la_CXXFLAGS = ${AM_CXXFLAGS}
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	osd/ClassHandler.cc \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	osd/OpRequest.cc \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	osd/SnapMapper.cc \
+ at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	osd/ScrubStore.cc \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	objclass/class_api.cc
 
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE at libosd_a_CXXFLAGS = ${AM_CXXFLAGS}
@@ -9454,7 +9890,7 @@ erasure_codelib_LTLIBRARIES = libec_jerasure_generic.la \
 	$(am__append_71) $(am__append_73) $(am__append_75) \
 	libec_jerasure.la libec_lrc.la libec_shec_generic.la \
 	$(am__append_80) $(am__append_82) $(am__append_84) \
-	libec_shec.la $(am__append_89) $(am__append_168)
+	libec_shec.la $(am__append_89) $(am__append_170)
 jerasure_sources = \
   erasure-code/ErasureCode.cc \
   erasure-code/jerasure/jerasure/src/cauchy.c \
@@ -9761,7 +10197,7 @@ liberasure_code_la_DEPENDENCIES = $(erasure_codelib_LTLIBRARIES)
 @LINUX_TRUE at liberasure_code_la_LIBADD = -ldl
 compressorlibdir = $(pkglibdir)/compressor
 compressorlib_LTLIBRARIES = libceph_zlib.la libceph_snappy.la \
-	$(am__append_204)
+	$(am__append_206)
 zlib_sources = \
   compressor/Compressor.cc \
   compressor/zlib/CompressionPluginZlib.cc \
@@ -9848,15 +10284,15 @@ libcommon_internal_la_SOURCES = ceph_ver.c common/DecayCounter.cc \
 	common/escape.c common/io_priority.cc common/ceph_time.cc \
 	common/Clock.cc common/Throttle.cc common/Timer.cc \
 	common/Finisher.cc common/environment.cc common/assert.cc \
-	common/run_cmd.cc common/WorkQueue.cc common/ConfUtils.cc \
-	common/MemoryModel.cc common/armor.c common/fd.cc \
-	common/safe_io.c common/snap_types.cc common/str_list.cc \
-	common/str_map.cc common/errno.cc common/RefCountedObj.cc \
-	common/common_init.cc common/pipe.c common/ceph_argparse.cc \
-	common/ceph_context.cc common/types.cc \
-	common/code_environment.cc common/dout.cc common/histogram.cc \
-	common/signal.cc common/simple_spin.cc common/Thread.cc \
-	common/Formatter.cc common/HTMLFormatter.cc \
+	xxHash/xxhash.c common/run_cmd.cc common/WorkQueue.cc \
+	common/ConfUtils.cc common/MemoryModel.cc common/armor.c \
+	common/fd.cc common/fs_types.cc common/safe_io.c \
+	common/snap_types.cc common/str_list.cc common/str_map.cc \
+	common/errno.cc common/RefCountedObj.cc common/common_init.cc \
+	common/pipe.c common/ceph_argparse.cc common/ceph_context.cc \
+	common/types.cc common/code_environment.cc common/dout.cc \
+	common/histogram.cc common/signal.cc common/simple_spin.cc \
+	common/Thread.cc common/Formatter.cc common/HTMLFormatter.cc \
 	common/HeartbeatMap.cc common/config.cc common/utf8.c \
 	common/mime.c common/strtol.cc common/page.cc \
 	common/lockdep.cc common/version.cc common/hex.cc \
@@ -9867,16 +10303,17 @@ libcommon_internal_la_SOURCES = ceph_ver.c common/DecayCounter.cc \
 	common/bloom_filter.cc common/module.c common/Readahead.cc \
 	common/Cycles.cc common/ContextCompletion.cc \
 	common/TracepointProvider.cc common/PluginRegistry.cc \
-	$(am__append_107) $(am__append_108) $(am__append_109) \
-	$(am__append_110) $(am__append_111) $(am__append_112) \
-	mon/MonCap.cc mon/MonClient.cc mon/MonMap.cc osd/OSDMap.cc \
-	osd/osd_types.cc osd/ECMsgTypes.cc osd/HitSet.cc mds/MDSMap.cc \
-	mds/inode_backtrace.cc mds/mdstypes.cc mds/flock.cc
+	common/scrub_types.cc common/blkdev.cc $(am__append_107) \
+	$(am__append_108) $(am__append_109) $(am__append_110) \
+	$(am__append_111) mon/MonCap.cc mon/MonClient.cc mon/MonMap.cc \
+	osd/OSDMap.cc osd/osd_types.cc osd/ECMsgTypes.cc osd/HitSet.cc \
+	mds/MDSMap.cc mds/FSMap.cc mds/inode_backtrace.cc \
+	mds/mdstypes.cc mds/flock.cc
 
 # inject crc in common
 libcommon_crc_la_SOURCES = common/sctp_crc32.c common/crc32c.cc \
 	common/crc32c_intel_baseline.c common/crc32c_intel_fast.c \
-	$(am__append_113)
+	$(am__append_112)
 @WITH_GOOD_YASM_ELF64_TRUE at libcommon_crc_la_LIBTOOLFLAGS = --tag=CC
 @HAVE_ARMV8_CRC_TRUE at libcommon_crc_aarch64_la_SOURCES = common/crc32c_aarch64.c
 @HAVE_ARMV8_CRC_TRUE at libcommon_crc_aarch64_la_CFLAGS = $(AM_CFLAGS) $(ARM_CRC_FLAGS)
@@ -9890,12 +10327,11 @@ libmsg_la_SOURCES = msg/Message.cc msg/Messenger.cc msg/msg_types.cc \
 	msg/simple/SimpleMessenger.cc msg/async/AsyncConnection.cc \
 	msg/async/AsyncMessenger.cc msg/async/Event.cc \
 	msg/async/net_handler.cc msg/async/EventSelect.cc \
-	$(am__append_119) $(am__append_120) $(am__append_121) \
-	$(am__append_122) $(am__append_123) $(am__append_124) \
-	$(am__append_125)
+	$(am__append_118) $(am__append_119) $(am__append_120) \
+	$(am__append_121) $(am__append_122) $(am__append_123) \
+	$(am__append_124)
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE at rados_includedir = $(includedir)/rados
- at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE at rados_include_DATA = \
- at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@	$(srcdir)/include/rados/librados.h \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE at rados_include_DATA = $(srcdir)/include/rados/librados.h \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@	$(srcdir)/include/rados/rados_types.h \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@	$(srcdir)/include/rados/rados_types.hpp \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@	$(srcdir)/include/rados/librados.hpp \
@@ -9903,8 +10339,8 @@ libmsg_la_SOURCES = msg/Message.cc msg/Messenger.cc msg/msg_types.cc \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@	$(srcdir)/include/buffer_fwd.h \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@	$(srcdir)/include/page.h \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@	$(srcdir)/include/crc32c.h \
- at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@	$(srcdir)/include/memory.h
-
+ at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@	$(srcdir)/include/memory.h \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@	$(am__append_126)
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE at librbd_includedir = $(includedir)/rbd
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE at librbd_include_DATA = \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	$(srcdir)/include/rbd/features.h \
@@ -10002,6 +10438,8 @@ librbd_types_la_SOURCES = \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	librbd/image/RefreshParentRequest.cc \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	librbd/image/RefreshRequest.cc \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	librbd/image/SetSnapRequest.cc \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	librbd/image_watcher/Notifier.cc \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	librbd/image_watcher/NotifyLockOwner.cc \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	librbd/journal/Replay.cc \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	librbd/object_map/InvalidateRequest.cc \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	librbd/object_map/LockRequest.cc \
@@ -10046,79 +10484,110 @@ librbd_types_la_SOURCES = \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	1:0:0 \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	$(am__append_139)
 @ENABLE_CLIENT_TRUE@@LINUX_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE at librbd_la_CXXFLAGS = -fvisibility=hidden -fvisibility-inlines-hidden
- at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE at librgw_la_SOURCES = \
- at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/librgw.cc \
- at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/rgw_acl.cc \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE at librgw_la_SOURCES = rgw/rgw_acl.cc \
 @ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/rgw_acl_s3.cc \
 @ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/rgw_acl_swift.cc \
- at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/rgw_client_io.cc \
- at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/rgw_fcgi.cc \
- at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/rgw_xml.cc \
- at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/rgw_usage.cc \
- at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/rgw_json_enc.cc \
- at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/rgw_xml_enc.cc \
- at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/rgw_user.cc \
- at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/rgw_bucket.cc\
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/rgw_coroutine.cc \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/rgw_cr_rados.cc \
 @ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/rgw_tools.cc \
- at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/rgw_rados.cc \
- at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/rgw_http_client.cc \
- at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/rgw_rest_client.cc \
- at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/rgw_rest_conn.cc \
- at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/rgw_op.cc \
 @ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/rgw_basic_types.cc \
- at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/rgw_common.cc \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/rgw_bucket.cc \
 @ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/rgw_cache.cc \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/rgw_client_io.cc \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/rgw_common.cc \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/rgw_cors.cc \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/rgw_cors_s3.cc \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/rgw_dencoder.cc \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/rgw_env.cc \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/rgw_fcgi.cc \
 @ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/rgw_formats.cc \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/rgw_frontend.cc \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/rgw_gc.cc \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/rgw_http_client.cc \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/rgw_json_enc.cc \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/rgw_keystone.cc \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/rgw_loadgen.cc \
 @ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/rgw_log.cc \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/rgw_metadata.cc \
 @ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/rgw_multi.cc \
- at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/rgw_policy_s3.cc \
- at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/rgw_gc.cc \
 @ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/rgw_multi_del.cc \
- at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/rgw_env.cc \
- at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/rgw_cors.cc \
- at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/rgw_cors_s3.cc \
 @ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/rgw_auth_s3.cc \
- at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/rgw_metadata.cc \
- at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/rgw_replica_log.cc \
- at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/rgw_keystone.cc \
- at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/rgw_quota.cc \
- at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/rgw_dencoder.cc \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/rgw_period_history.cc \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/rgw_period_puller.cc \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/rgw_period_pusher.cc \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/rgw_realm_reloader.cc \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/rgw_realm_watcher.cc \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/rgw_sync.cc \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/rgw_data_sync.cc \
 @ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/rgw_object_expirer_core.cc \
- at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/rgw_website.cc
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/rgw_op.cc \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/rgw_os_lib.cc \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/rgw_policy_s3.cc \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/rgw_process.cc \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/rgw_quota.cc \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/rgw_rados.cc \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/rgw_replica_log.cc \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/rgw_request.cc \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/rgw_resolve.cc \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/rgw_rest_bucket.cc \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/rgw_rest.cc \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/rgw_rest_client.cc \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/rgw_rest_config.cc \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/rgw_rest_conn.cc \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/rgw_rest_log.cc \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/rgw_rest_metadata.cc \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/rgw_rest_opstate.cc \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/rgw_rest_realm.cc \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/rgw_rest_replica_log.cc \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/rgw_rest_s3.cc \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/rgw_rest_swift.cc \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/rgw_rest_usage.cc \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/rgw_rest_user.cc \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/rgw_swift_auth.cc \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/rgw_swift.cc \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/rgw_usage.cc \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/rgw_user.cc \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/rgw_file.cc \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/librgw.cc \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/rgw_xml.cc \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/rgw_xml_enc.cc \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/rgw_website.cc \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	$(am__append_144)
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE at librgw_la_CXXFLAGS = -Woverloaded-virtual -fPIC -I$(srcdir)/xxHash \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	${AM_CXXFLAGS}
+
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE at librgw_la_LIBADD = $(LIBRGW_DEPS) \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	$(PTHREAD_LIBS) $(RESOLV_LIBS) libglobal.la \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	$(EXTRALIBS)
 
- at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE at librgw_la_CXXFLAGS = -Woverloaded-virtual ${AM_CXXFLAGS}
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE at librgw_la_LDFLAGS = ${AM_LDFLAGS} -version-info 2:0:0
 @ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE at CIVETWEB_INCLUDE = --include $(srcdir)/civetweb/include/civetweb_conf.h
 @ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE at libcivetweb_la_SOURCES = \
 @ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/rgw_civetweb.cc \
 @ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/rgw_civetweb_log.cc \
 @ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	civetweb/src/civetweb.c
 
- at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE at libcivetweb_la_CXXFLAGS = ${CIVETWEB_INCLUDE} -Woverloaded-virtual ${AM_CXXFLAGS}
- at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE at libcivetweb_la_CFLAGS = -I$(srcdir)/civetweb/include ${CIVETWEB_INCLUDE}
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE at libcivetweb_la_CXXFLAGS = ${CIVETWEB_INCLUDE} -fPIC -Woverloaded-virtual \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	${AM_CXXFLAGS}
+
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE at libcivetweb_la_CFLAGS = -I$(srcdir)/civetweb/include ${CIVETWEB_INCLUDE} -fPIC -DNO_SSL_DL
 @ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE at radosgw_SOURCES = \
- at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/rgw_resolve.cc \
- at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/rgw_rest.cc \
- at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/rgw_rest_swift.cc \
- at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/rgw_rest_s3.cc \
- at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/rgw_rest_usage.cc \
- at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/rgw_rest_user.cc \
- at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/rgw_rest_bucket.cc \
- at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/rgw_rest_metadata.cc \
- at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/rgw_replica_log.cc \
- at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/rgw_rest_log.cc \
- at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/rgw_rest_opstate.cc \
- at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/rgw_rest_replica_log.cc \
- at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/rgw_rest_config.cc \
- at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/rgw_http_client.cc \
- at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/rgw_swift.cc \
- at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/rgw_swift_auth.cc \
- at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/rgw_loadgen.cc \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/rgw_fcgi_process.cc \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/rgw_loadgen_process.cc \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/rgw_civetweb.cc \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/rgw_civetweb_frontend.cc \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/rgw_civetweb_log.cc \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	civetweb/src/civetweb.c \
 @ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	rgw/rgw_main.cc
 
- at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE at radosgw_CFLAGS = -I$(srcdir)/civetweb/include
- at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE at radosgw_LDADD = $(LIBRGW) $(LIBCIVETWEB) $(LIBRGW_DEPS) $(RESOLV_LIBS) $(CEPH_GLOBAL)
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE at radosgw_CFLAGS = -I$(srcdir)/civetweb/include -fPIC -I$(srcdir)/xxHash
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE at radosgw_LDADD = $(LIBRGW) $(LIBCIVETWEB) $(LIBCIVETWEB_DEPS) $(LIBRGW_DEPS) $(RESOLV_LIBS) \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	$(CEPH_GLOBAL)
+
 @ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE at radosgw_admin_SOURCES = rgw/rgw_admin.cc rgw/rgw_orphan.cc
 @ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE at radosgw_admin_LDADD = $(LIBRGW) $(LIBRGW_DEPS) $(CEPH_GLOBAL)
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE at radosgw_token_SOURCES = rgw/rgw_token.cc
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE at radosgw_token_LDADD = $(LIBRGW) $(LIBRGW_DEPS) $(CEPH_GLOBAL)
 @ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE at radosgw_object_expirer_SOURCES = rgw/rgw_object_expirer.cc
 @ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE at radosgw_object_expirer_LDADD = $(LIBRGW) $(LIBRGW_DEPS) $(CEPH_GLOBAL)
 @ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE at ceph_rgw_multiparser_SOURCES = rgw/rgw_multiparser.cc
@@ -10139,14 +10608,14 @@ librbd_types_la_SOURCES = \
 @ENABLE_CLIENT_TRUE@	cls/refcount/cls_refcount_client.cc \
 @ENABLE_CLIENT_TRUE@	cls/refcount/cls_refcount_ops.cc
 
- at ENABLE_CLIENT_TRUE@libcls_version_client_a_SOURCES = \
+ at ENABLE_CLIENT_TRUE@libcls_version_client_la_SOURCES = \
 @ENABLE_CLIENT_TRUE@	cls/version/cls_version_client.cc \
 @ENABLE_CLIENT_TRUE@	cls/version/cls_version_types.cc
 
- at ENABLE_CLIENT_TRUE@libcls_log_client_a_SOURCES = cls/log/cls_log_client.cc
- at ENABLE_CLIENT_TRUE@libcls_statelog_client_a_SOURCES = cls/statelog/cls_statelog_client.cc
- at ENABLE_CLIENT_TRUE@libcls_timeindex_client_a_SOURCES = cls/timeindex/cls_timeindex_client.cc
- at ENABLE_CLIENT_TRUE@libcls_replica_log_client_a_SOURCES = \
+ at ENABLE_CLIENT_TRUE@libcls_log_client_la_SOURCES = cls/log/cls_log_client.cc
+ at ENABLE_CLIENT_TRUE@libcls_statelog_client_la_SOURCES = cls/statelog/cls_statelog_client.cc
+ at ENABLE_CLIENT_TRUE@libcls_timeindex_client_la_SOURCES = cls/timeindex/cls_timeindex_client.cc
+ at ENABLE_CLIENT_TRUE@libcls_replica_log_client_la_SOURCES = \
 @ENABLE_CLIENT_TRUE@	cls/replica_log/cls_replica_log_types.cc \
 @ENABLE_CLIENT_TRUE@	cls/replica_log/cls_replica_log_ops.cc \
 @ENABLE_CLIENT_TRUE@	cls/replica_log/cls_replica_log_client.cc
@@ -10160,7 +10629,7 @@ librbd_types_la_SOURCES = \
 @ENABLE_CLIENT_TRUE@	cls/rbd/cls_rbd_client.cc \
 @ENABLE_CLIENT_TRUE@	cls/rbd/cls_rbd_types.cc
 
- at ENABLE_CLIENT_TRUE@libcls_user_client_a_SOURCES = cls/user/cls_user_client.cc \
+ at ENABLE_CLIENT_TRUE@libcls_user_client_la_SOURCES = cls/user/cls_user_client.cc \
 @ENABLE_CLIENT_TRUE@	cls/user/cls_user_types.cc \
 @ENABLE_CLIENT_TRUE@	cls/user/cls_user_ops.cc
 
@@ -10287,7 +10756,7 @@ librbd_types_la_SOURCES = \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(LIBOSD) $(LIBCOMMON) \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(BOOST_PROGRAM_OPTIONS_LIBS) \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(CEPH_GLOBAL) \
- at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__append_162)
+ at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__append_164)
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE at ceph_erasure_code_non_regression_SOURCES = \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	test/erasure-code/ceph_erasure_code_non_regression.cc
 
@@ -10295,7 +10764,7 @@ librbd_types_la_SOURCES = \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(LIBOSD) $(LIBCOMMON) \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(BOOST_PROGRAM_OPTIONS_LIBS) \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(CEPH_GLOBAL) \
- at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__append_164)
+ at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__append_166)
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE at ceph_erasure_code_SOURCES = \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	test/erasure-code/ceph_erasure_code.cc
 
@@ -10303,7 +10772,7 @@ librbd_types_la_SOURCES = \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(LIBOSD) $(LIBCOMMON) \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(BOOST_PROGRAM_OPTIONS_LIBS) \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(CEPH_GLOBAL) \
- at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__append_166)
+ at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__append_168)
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE at libec_example_la_SOURCES = \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	erasure-code/ErasureCode.cc \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	test/erasure-code/ErasureCodePluginExample.cc
@@ -10314,7 +10783,7 @@ librbd_types_la_SOURCES = \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE at libec_example_la_LDFLAGS =  \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	${AM_LDFLAGS} -module \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	-avoid-version -shared \
- at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__append_167)
+ at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__append_169)
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE at libec_missing_entry_point_la_SOURCES = test/erasure-code/ErasureCodePluginMissingEntryPoint.cc
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE at libec_missing_entry_point_la_CFLAGS = ${AM_CFLAGS}
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE at libec_missing_entry_point_la_CXXFLAGS = ${AM_CXXFLAGS}
@@ -10322,7 +10791,7 @@ librbd_types_la_SOURCES = \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE at libec_missing_entry_point_la_LDFLAGS =  \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	${AM_LDFLAGS} -module \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	-avoid-version -shared \
- at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__append_169)
+ at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__append_171)
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE at libec_missing_version_la_SOURCES = test/erasure-code/ErasureCodePluginMissingVersion.cc
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE at libec_missing_version_la_CFLAGS = ${AM_CFLAGS}
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE at libec_missing_version_la_CXXFLAGS = ${AM_CXXFLAGS}
@@ -10330,7 +10799,7 @@ librbd_types_la_SOURCES = \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE at libec_missing_version_la_LDFLAGS =  \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	${AM_LDFLAGS} -module \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	-avoid-version -shared \
- at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__append_170)
+ at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__append_172)
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE at libec_hangs_la_SOURCES = test/erasure-code/ErasureCodePluginHangs.cc
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE at libec_hangs_la_CFLAGS = ${AM_CFLAGS}
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE at libec_hangs_la_CXXFLAGS = ${AM_CXXFLAGS}
@@ -10338,7 +10807,7 @@ librbd_types_la_SOURCES = \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE at libec_hangs_la_LDFLAGS =  \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	${AM_LDFLAGS} -module \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	-avoid-version -shared \
- at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__append_171)
+ at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__append_173)
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE at libec_fail_to_initialize_la_SOURCES = test/erasure-code/ErasureCodePluginFailToInitialize.cc
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE at libec_fail_to_initialize_la_CFLAGS = ${AM_CFLAGS}
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE at libec_fail_to_initialize_la_CXXFLAGS = ${AM_CXXFLAGS}
@@ -10346,7 +10815,7 @@ librbd_types_la_SOURCES = \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE at libec_fail_to_initialize_la_LDFLAGS =  \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	${AM_LDFLAGS} -module \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	-avoid-version -shared \
- at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__append_172)
+ at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__append_174)
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE at libec_fail_to_register_la_SOURCES = test/erasure-code/ErasureCodePluginFailToRegister.cc
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE at libec_fail_to_register_la_CFLAGS = ${AM_CFLAGS}
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE at libec_fail_to_register_la_CXXFLAGS = ${AM_CXXFLAGS}
@@ -10354,7 +10823,7 @@ librbd_types_la_SOURCES = \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE at libec_fail_to_register_la_LDFLAGS =  \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	${AM_LDFLAGS} -module \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	-avoid-version -shared \
- at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__append_173)
+ at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__append_175)
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE at libec_test_jerasure_neon_la_SOURCES = test/erasure-code/TestJerasurePluginNEON.cc
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE at libec_test_jerasure_neon_la_CFLAGS = ${AM_CFLAGS}
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE at libec_test_jerasure_neon_la_CXXFLAGS = ${AM_CXXFLAGS}
@@ -10362,7 +10831,7 @@ librbd_types_la_SOURCES = \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE at libec_test_jerasure_neon_la_LDFLAGS =  \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	${AM_LDFLAGS} -module \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	-avoid-version -shared \
- at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__append_174)
+ at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__append_176)
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE at libec_test_jerasure_sse4_la_SOURCES = test/erasure-code/TestJerasurePluginSSE4.cc
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE at libec_test_jerasure_sse4_la_CFLAGS = ${AM_CFLAGS}
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE at libec_test_jerasure_sse4_la_CXXFLAGS = ${AM_CXXFLAGS}
@@ -10370,7 +10839,7 @@ librbd_types_la_SOURCES = \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE at libec_test_jerasure_sse4_la_LDFLAGS =  \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	${AM_LDFLAGS} -module \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	-avoid-version -shared \
- at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__append_175)
+ at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__append_177)
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE at libec_test_jerasure_sse3_la_SOURCES = test/erasure-code/TestJerasurePluginSSE3.cc
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE at libec_test_jerasure_sse3_la_CFLAGS = ${AM_CFLAGS}
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE at libec_test_jerasure_sse3_la_CXXFLAGS = ${AM_CXXFLAGS}
@@ -10378,7 +10847,7 @@ librbd_types_la_SOURCES = \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE at libec_test_jerasure_sse3_la_LDFLAGS =  \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	${AM_LDFLAGS} -module \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	-avoid-version -shared \
- at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__append_176)
+ at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__append_178)
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE at libec_test_jerasure_generic_la_SOURCES = test/erasure-code/TestJerasurePluginGeneric.cc
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE at libec_test_jerasure_generic_la_CFLAGS = ${AM_CFLAGS}
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE at libec_test_jerasure_generic_la_CXXFLAGS = ${AM_CXXFLAGS}
@@ -10386,7 +10855,7 @@ librbd_types_la_SOURCES = \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE at libec_test_jerasure_generic_la_LDFLAGS =  \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	${AM_LDFLAGS} -module \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	-avoid-version -shared \
- at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__append_177)
+ at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__append_179)
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE at unittest_erasure_code_plugin_SOURCES = \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	erasure-code/ErasureCode.cc \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	test/erasure-code/TestErasureCodePlugin.cc 
@@ -10396,7 +10865,7 @@ librbd_types_la_SOURCES = \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(LIBOSD) $(LIBCOMMON) \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(UNITTEST_LDADD) \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(CEPH_GLOBAL) \
- at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__append_178)
+ at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__append_180)
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE at unittest_erasure_code_SOURCES = \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	erasure-code/ErasureCode.cc \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	test/erasure-code/TestErasureCode.cc
@@ -10419,7 +10888,7 @@ librbd_types_la_SOURCES = \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(LIBOSD) $(LIBCOMMON) \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(UNITTEST_LDADD) \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(CEPH_GLOBAL) \
- at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__append_180)
+ at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__append_182)
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE at unittest_erasure_code_plugin_jerasure_SOURCES = \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	test/erasure-code/TestErasureCodePluginJerasure.cc
 
@@ -10428,7 +10897,7 @@ librbd_types_la_SOURCES = \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(LIBOSD) $(LIBCOMMON) \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(UNITTEST_LDADD) \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(CEPH_GLOBAL) \
- at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__append_181)
+ at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__append_183)
 @ENABLE_SERVER_TRUE@@WITH_BETTER_YASM_ELF64_TRUE@@WITH_OSD_TRUE at unittest_erasure_code_isa_SOURCES = \
 @ENABLE_SERVER_TRUE@@WITH_BETTER_YASM_ELF64_TRUE@@WITH_OSD_TRUE@	erasure-code/ErasureCode.cc \
 @ENABLE_SERVER_TRUE@@WITH_BETTER_YASM_ELF64_TRUE@@WITH_OSD_TRUE@	test/erasure-code/TestErasureCodeIsa.cc
@@ -10440,7 +10909,7 @@ librbd_types_la_SOURCES = \
 @ENABLE_SERVER_TRUE@@WITH_BETTER_YASM_ELF64_TRUE@@WITH_OSD_TRUE@	$(CEPH_GLOBAL) \
 @ENABLE_SERVER_TRUE@@WITH_BETTER_YASM_ELF64_TRUE@@WITH_OSD_TRUE@	libisa.la \
 @ENABLE_SERVER_TRUE@@WITH_BETTER_YASM_ELF64_TRUE@@WITH_OSD_TRUE@	$(LIBERASURE_CODE) \
- at ENABLE_SERVER_TRUE@@WITH_BETTER_YASM_ELF64_TRUE@@WITH_OSD_TRUE@	$(am__append_182)
+ at ENABLE_SERVER_TRUE@@WITH_BETTER_YASM_ELF64_TRUE@@WITH_OSD_TRUE@	$(am__append_184)
 @ENABLE_SERVER_TRUE@@WITH_BETTER_YASM_ELF64_TRUE@@WITH_OSD_TRUE at unittest_erasure_code_plugin_isa_SOURCES = \
 @ENABLE_SERVER_TRUE@@WITH_BETTER_YASM_ELF64_TRUE@@WITH_OSD_TRUE@	erasure-code/ErasureCode.cc \
 @ENABLE_SERVER_TRUE@@WITH_BETTER_YASM_ELF64_TRUE@@WITH_OSD_TRUE@	test/erasure-code/TestErasureCodePluginIsa.cc
@@ -10451,7 +10920,7 @@ librbd_types_la_SOURCES = \
 @ENABLE_SERVER_TRUE@@WITH_BETTER_YASM_ELF64_TRUE@@WITH_OSD_TRUE@	$(UNITTEST_LDADD) \
 @ENABLE_SERVER_TRUE@@WITH_BETTER_YASM_ELF64_TRUE@@WITH_OSD_TRUE@	$(CEPH_GLOBAL) \
 @ENABLE_SERVER_TRUE@@WITH_BETTER_YASM_ELF64_TRUE@@WITH_OSD_TRUE@	$(LIBERASURE_CODE) \
- at ENABLE_SERVER_TRUE@@WITH_BETTER_YASM_ELF64_TRUE@@WITH_OSD_TRUE@	$(am__append_184)
+ at ENABLE_SERVER_TRUE@@WITH_BETTER_YASM_ELF64_TRUE@@WITH_OSD_TRUE@	$(am__append_186)
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE at unittest_erasure_code_lrc_SOURCES = \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	test/erasure-code/TestErasureCodeLrc.cc \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	${lrc_sources}
@@ -10461,7 +10930,7 @@ librbd_types_la_SOURCES = \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(LIBOSD) $(LIBCOMMON) \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(UNITTEST_LDADD) \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(CEPH_GLOBAL) \
- at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__append_185)
+ at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__append_187)
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE at unittest_erasure_code_plugin_lrc_SOURCES = \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	test/erasure-code/TestErasureCodePluginLrc.cc
 
@@ -10470,7 +10939,7 @@ librbd_types_la_SOURCES = \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(LIBOSD) $(LIBCOMMON) \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(UNITTEST_LDADD) \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(CEPH_GLOBAL) \
- at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__append_187)
+ at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__append_189)
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE at unittest_erasure_code_shec_SOURCES = \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	test/erasure-code/TestErasureCodeShec.cc \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	${shec_sources}
@@ -10491,7 +10960,7 @@ librbd_types_la_SOURCES = \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(LIBOSD) $(LIBCOMMON) \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(UNITTEST_LDADD) \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(CEPH_GLOBAL) \
- at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__append_188)
+ at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__append_190)
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE at unittest_erasure_code_shec_all_SOURCES = \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	test/erasure-code/TestErasureCodeShec_all.cc \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	${shec_sources}
@@ -10512,7 +10981,7 @@ librbd_types_la_SOURCES = \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(LIBOSD) $(LIBCOMMON) \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(UNITTEST_LDADD) \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(CEPH_GLOBAL) \
- at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__append_189)
+ at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__append_191)
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE at unittest_erasure_code_shec_thread_SOURCES = \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	test/erasure-code/TestErasureCodeShec_thread.cc \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	${shec_sources}
@@ -10533,7 +11002,7 @@ librbd_types_la_SOURCES = \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(LIBOSD) $(LIBCOMMON) \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(UNITTEST_LDADD) \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(CEPH_GLOBAL) \
- at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__append_190)
+ at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__append_192)
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE at unittest_erasure_code_shec_arguments_SOURCES = \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	test/erasure-code/TestErasureCodeShec_arguments.cc \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	${shec_sources}
@@ -10554,7 +11023,7 @@ librbd_types_la_SOURCES = \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(LIBOSD) $(LIBCOMMON) \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(UNITTEST_LDADD) \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(CEPH_GLOBAL) \
- at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__append_191)
+ at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__append_193)
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE at unittest_erasure_code_plugin_shec_SOURCES = \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@        test/erasure-code/TestErasureCodePluginShec.cc
 
@@ -10563,7 +11032,7 @@ librbd_types_la_SOURCES = \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(LIBOSD) $(LIBCOMMON) \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(UNITTEST_LDADD) \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(CEPH_GLOBAL) \
- at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__append_192)
+ at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__append_194)
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE at libec_test_shec_neon_la_SOURCES = test/erasure-code/TestShecPluginNEON.cc
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE at libec_test_shec_neon_la_CFLAGS = ${AM_CFLAGS}
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE at libec_test_shec_neon_la_CXXFLAGS = ${AM_CXXFLAGS}
@@ -10571,7 +11040,7 @@ librbd_types_la_SOURCES = \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE at libec_test_shec_neon_la_LDFLAGS =  \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	${AM_LDFLAGS} -module \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	-avoid-version -shared \
- at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__append_193)
+ at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__append_195)
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE at libec_test_shec_sse4_la_SOURCES = test/erasure-code/TestShecPluginSSE4.cc
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE at libec_test_shec_sse4_la_CFLAGS = ${AM_CFLAGS}
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE at libec_test_shec_sse4_la_CXXFLAGS = ${AM_CXXFLAGS}
@@ -10579,7 +11048,7 @@ librbd_types_la_SOURCES = \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE at libec_test_shec_sse4_la_LDFLAGS =  \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	${AM_LDFLAGS} -module \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	-avoid-version -shared \
- at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__append_194)
+ at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__append_196)
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE at libec_test_shec_sse3_la_SOURCES = test/erasure-code/TestShecPluginSSE3.cc
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE at libec_test_shec_sse3_la_CFLAGS = ${AM_CFLAGS}
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE at libec_test_shec_sse3_la_CXXFLAGS = ${AM_CXXFLAGS}
@@ -10587,7 +11056,7 @@ librbd_types_la_SOURCES = \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE at libec_test_shec_sse3_la_LDFLAGS =  \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	${AM_LDFLAGS} -module \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	-avoid-version -shared \
- at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__append_195)
+ at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__append_197)
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE at libec_test_shec_generic_la_SOURCES = test/erasure-code/TestShecPluginGeneric.cc
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE at libec_test_shec_generic_la_CFLAGS = ${AM_CFLAGS}
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE at libec_test_shec_generic_la_CXXFLAGS = ${AM_CXXFLAGS}
@@ -10595,7 +11064,7 @@ librbd_types_la_SOURCES = \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE at libec_test_shec_generic_la_LDFLAGS =  \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	${AM_LDFLAGS} -module \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	-avoid-version -shared \
- at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__append_196)
+ at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__append_198)
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE at unittest_erasure_code_example_SOURCES = \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	erasure-code/ErasureCode.cc \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	test/erasure-code/TestErasureCodeExample.cc
@@ -10613,7 +11082,7 @@ librbd_types_la_SOURCES = \
 @ENABLE_SERVER_TRUE@@ENABLE_XIO_TRUE@	$(CEPH_GLOBAL) \
 @ENABLE_SERVER_TRUE@@ENABLE_XIO_TRUE@	$(PTHREAD_LIBS) \
 @ENABLE_SERVER_TRUE@@ENABLE_XIO_TRUE@	$(EXTRALIBS) \
- at ENABLE_SERVER_TRUE@@ENABLE_XIO_TRUE@	$(am__append_198)
+ at ENABLE_SERVER_TRUE@@ENABLE_XIO_TRUE@	$(am__append_200)
 @ENABLE_SERVER_TRUE@@ENABLE_XIO_TRUE at simple_client_SOURCES = \
 @ENABLE_SERVER_TRUE@@ENABLE_XIO_TRUE@	test/messenger/simple_client.cc \
 @ENABLE_SERVER_TRUE@@ENABLE_XIO_TRUE@	test/messenger/simple_dispatcher.cc
@@ -10625,7 +11094,7 @@ librbd_types_la_SOURCES = \
 @ENABLE_SERVER_TRUE@@ENABLE_XIO_TRUE@	$(CEPH_GLOBAL) \
 @ENABLE_SERVER_TRUE@@ENABLE_XIO_TRUE@	$(PTHREAD_LIBS) \
 @ENABLE_SERVER_TRUE@@ENABLE_XIO_TRUE@	$(EXTRALIBS) \
- at ENABLE_SERVER_TRUE@@ENABLE_XIO_TRUE@	$(am__append_199)
+ at ENABLE_SERVER_TRUE@@ENABLE_XIO_TRUE@	$(am__append_201)
 @ENABLE_SERVER_TRUE@@ENABLE_XIO_TRUE at xio_server_SOURCES = \
 @ENABLE_SERVER_TRUE@@ENABLE_XIO_TRUE@	test/messenger/xio_server.cc \
 @ENABLE_SERVER_TRUE@@ENABLE_XIO_TRUE@	test/messenger/xio_dispatcher.cc
@@ -10637,7 +11106,7 @@ librbd_types_la_SOURCES = \
 @ENABLE_SERVER_TRUE@@ENABLE_XIO_TRUE@	$(LIBCOMMON) \
 @ENABLE_SERVER_TRUE@@ENABLE_XIO_TRUE@	$(PTHREAD_LIBS) \
 @ENABLE_SERVER_TRUE@@ENABLE_XIO_TRUE@	$(EXTRALIBS) \
- at ENABLE_SERVER_TRUE@@ENABLE_XIO_TRUE@	$(am__append_201)
+ at ENABLE_SERVER_TRUE@@ENABLE_XIO_TRUE@	$(am__append_203)
 @ENABLE_SERVER_TRUE@@ENABLE_XIO_TRUE at xio_client_SOURCES = \
 @ENABLE_SERVER_TRUE@@ENABLE_XIO_TRUE@	test/messenger/xio_client.cc \
 @ENABLE_SERVER_TRUE@@ENABLE_XIO_TRUE@	test/messenger/xio_dispatcher.cc
@@ -10649,7 +11118,7 @@ librbd_types_la_SOURCES = \
 @ENABLE_SERVER_TRUE@@ENABLE_XIO_TRUE@	$(LIBCOMMON) \
 @ENABLE_SERVER_TRUE@@ENABLE_XIO_TRUE@	$(PTHREAD_LIBS) \
 @ENABLE_SERVER_TRUE@@ENABLE_XIO_TRUE@	$(EXTRALIBS) \
- at ENABLE_SERVER_TRUE@@ENABLE_XIO_TRUE@	$(am__append_202)
+ at ENABLE_SERVER_TRUE@@ENABLE_XIO_TRUE@	$(am__append_204)
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE at libceph_example_la_SOURCES = \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	compressor/Compressor.cc \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	test/compressor/compressor_plugin_example.cc
@@ -10667,7 +11136,7 @@ librbd_types_la_SOURCES = \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(LIBOSD) $(LIBCOMMON) \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(UNITTEST_LDADD) \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(CEPH_GLOBAL) \
- at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__append_205)
+ at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__append_207)
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE at unittest_compression_snappy_SOURCES = \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	test/compressor/test_compression_snappy.cc \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	${snappy_sources}
@@ -10677,7 +11146,7 @@ librbd_types_la_SOURCES = \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(LIBOSD) $(LIBCOMMON) \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(UNITTEST_LDADD) \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(CEPH_GLOBAL) \
- at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__append_206)
+ at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__append_208)
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE at unittest_compression_snappy_LDFLAGS = -lsnappy
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE at unittest_compression_plugin_snappy_SOURCES = \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	test/compressor/test_compression_plugin_snappy.cc \
@@ -10689,7 +11158,7 @@ librbd_types_la_SOURCES = \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(UNITTEST_LDADD) \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(CEPH_GLOBAL) \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(LIBCOMPRESSOR) \
- at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__append_207)
+ at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__append_209)
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE at unittest_compression_plugin_snappy_LDFLAGS = -lsnappy
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE at unittest_compression_zlib_SOURCES = \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	test/compressor/test_compression_zlib.cc \
@@ -10700,7 +11169,7 @@ librbd_types_la_SOURCES = \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(LIBOSD) $(LIBCOMMON) \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(UNITTEST_LDADD) \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(CEPH_GLOBAL) \
- at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__append_208)
+ at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__append_210)
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE at unittest_compression_zlib_LDFLAGS = -lz
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE at unittest_compression_plugin_zlib_SOURCES = \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	test/compressor/test_compression_plugin_zlib.cc \
@@ -10712,7 +11181,7 @@ librbd_types_la_SOURCES = \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(UNITTEST_LDADD) \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(CEPH_GLOBAL) \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(LIBCOMPRESSOR) \
- at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__append_209)
+ at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__append_211)
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE at unittest_compression_plugin_zlib_LDFLAGS = -lz
 
 # This should use LIBMDS_TYPES once it exists
@@ -10721,6 +11190,8 @@ librbd_types_la_SOURCES = \
 @ENABLE_CLIENT_TRUE@	$(DENCODER_SOURCES)
 
 @ENABLE_CLIENT_TRUE at ceph_dencoder_LDADD = \
+ at ENABLE_CLIENT_TRUE@	$(LIBRGW) \
+ at ENABLE_CLIENT_TRUE@	$(LIBRADOS) \
 @ENABLE_CLIENT_TRUE@	$(LIBRBD_TYPES) \
 @ENABLE_CLIENT_TRUE@	$(LIBOSD_TYPES) \
 @ENABLE_CLIENT_TRUE@	$(LIBOS_TYPES) \
@@ -10731,10 +11202,10 @@ librbd_types_la_SOURCES = \
 
 # These should always use explicit _CFLAGS/_CXXFLAGS so avoid basename conflicts
 @ENABLE_CLIENT_TRUE at ceph_dencoder_CFLAGS = ${AM_CFLAGS} \
- at ENABLE_CLIENT_TRUE@	$(am__append_210)
+ at ENABLE_CLIENT_TRUE@	$(am__append_212)
 @ENABLE_CLIENT_TRUE at ceph_dencoder_CXXFLAGS = ${AM_CXXFLAGS} \
- at ENABLE_CLIENT_TRUE@	$(am__append_211) $(am__append_212) \
- at ENABLE_CLIENT_TRUE@	$(am__append_213)
+ at ENABLE_CLIENT_TRUE@	$(am__append_213) $(am__append_214) \
+ at ENABLE_CLIENT_TRUE@	$(am__append_215)
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE at libradostest_la_SOURCES = \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@	test/librados/test.cc \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@	test/librados/TestCase.cc
@@ -10823,17 +11294,17 @@ librbd_types_la_SOURCES = \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE at ceph_test_cls_refcount_LDADD = $(LIBRADOS) libcls_refcount_client.la $(UNITTEST_LDADD) $(RADOS_TEST_LDADD)
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE at ceph_test_cls_refcount_CXXFLAGS = $(UNITTEST_CXXFLAGS)
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE at ceph_test_cls_version_SOURCES = test/cls_version/test_cls_version.cc
- at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE at ceph_test_cls_version_LDADD = $(LIBRADOS) libcls_version_client.a $(UNITTEST_LDADD) $(RADOS_TEST_LDADD)
+ at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE at ceph_test_cls_version_LDADD = $(LIBRADOS) libcls_version_client.la $(UNITTEST_LDADD) $(RADOS_TEST_LDADD)
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE at ceph_test_cls_version_CXXFLAGS = $(UNITTEST_CXXFLAGS)
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE at ceph_test_cls_log_SOURCES = test/cls_log/test_cls_log.cc
- at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE at ceph_test_cls_log_LDADD = $(LIBRADOS) libcls_log_client.a $(UNITTEST_LDADD) $(CEPH_GLOBAL) $(RADOS_TEST_LDADD)
+ at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE at ceph_test_cls_log_LDADD = $(LIBRADOS) libcls_log_client.la $(UNITTEST_LDADD) $(CEPH_GLOBAL) $(RADOS_TEST_LDADD)
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE at ceph_test_cls_log_CXXFLAGS = $(UNITTEST_CXXFLAGS)
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE at ceph_test_cls_statelog_SOURCES = test/cls_statelog/test_cls_statelog.cc
- at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE at ceph_test_cls_statelog_LDADD = $(LIBRADOS) libcls_statelog_client.a $(UNITTEST_LDADD) $(CEPH_GLOBAL) $(RADOS_TEST_LDADD)
+ at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE at ceph_test_cls_statelog_LDADD = $(LIBRADOS) libcls_statelog_client.la $(UNITTEST_LDADD) $(CEPH_GLOBAL) $(RADOS_TEST_LDADD)
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE at ceph_test_cls_statelog_CXXFLAGS = $(UNITTEST_CXXFLAGS)
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE at ceph_test_cls_replica_log_SOURCES = test/cls_replica_log/test_cls_replica_log.cc
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE at ceph_test_cls_replica_log_LDADD = \
- at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@	$(LIBRADOS) libcls_replica_log_client.a \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@	$(LIBRADOS) libcls_replica_log_client.la \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@	$(UNITTEST_LDADD) $(CEPH_GLOBAL) $(RADOS_TEST_LDADD)
 
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE at ceph_test_cls_replica_log_CXXFLAGS = $(UNITTEST_CXXFLAGS)
@@ -10918,6 +11389,9 @@ librbd_types_la_SOURCES = \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE at ceph_test_rados_api_lock_SOURCES = test/librados/lock.cc
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE at ceph_test_rados_api_lock_LDADD = $(LIBRADOS) $(UNITTEST_LDADD) $(RADOS_TEST_LDADD)
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE at ceph_test_rados_api_lock_CXXFLAGS = $(UNITTEST_CXXFLAGS)
+ at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE at ceph_test_rados_api_tmap_migrate_SOURCES = test/librados/tmap_migrate.cc tools/cephfs/DataScan.cc tools/cephfs/MDSUtility.cc
+ at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE at ceph_test_rados_api_tmap_migrate_LDADD = $(LIBRADOS) $(UNITTEST_LDADD) $(LIBMDS) libcls_cephfs_client.la  $(CEPH_GLOBAL) $(RADOS_TEST_LDADD)
+ at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE at ceph_test_rados_api_tmap_migrate_CXXFLAGS = $(UNITTEST_CXXFLAGS)
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE at ceph_test_stress_watch_SOURCES = test/test_stress_watch.cc
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE at ceph_test_stress_watch_LDADD = \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@	$(LIBRADOS) $(LIBCOMMON) $(UNITTEST_LDADD) $(RADOS_TEST_LDADD)
@@ -10973,6 +11447,7 @@ librbd_types_la_SOURCES = \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	test/librbd/test_librbd.cc \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	test/librbd/test_ImageWatcher.cc \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	test/librbd/test_internal.cc \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	test/librbd/test_mirroring.cc \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	test/librbd/test_ObjectMap.cc \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	test/librbd/journal/test_Entries.cc \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	test/librbd/journal/test_Replay.cc
@@ -11034,11 +11509,22 @@ librbd_types_la_SOURCES = \
 
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE at librbd_mirror_test_la_SOURCES = \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	test/rbd_mirror/test_ClusterWatcher.cc \
- at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	test/rbd_mirror/test_PoolWatcher.cc
+ at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	test/rbd_mirror/test_PoolWatcher.cc \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	test/rbd_mirror/test_ImageReplayer.cc \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	test/rbd_mirror/test_ImageSync.cc \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	test/rbd_mirror/test_fixture.cc
 
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE at librbd_mirror_test_la_CXXFLAGS = $(UNITTEST_CXXFLAGS)
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE at unittest_rbd_mirror_SOURCES = \
- at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	test/rbd_mirror/test_main.cc
+ at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	test/rbd_mirror/test_main.cc \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	test/rbd_mirror/test_mock_fixture.cc \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	test/rbd_mirror/test_mock_ImageSync.cc \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	test/rbd_mirror/image_sync/test_mock_ImageCopyRequest.cc \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	test/rbd_mirror/image_sync/test_mock_ObjectCopyRequest.cc \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	test/rbd_mirror/image_sync/test_mock_SnapshotCopyRequest.cc \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	test/rbd_mirror/image_sync/test_mock_SyncPointCreateRequest.cc \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	test/rbd_mirror/image_sync/test_mock_SyncPointPruneRequest.cc \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	test/rbd_mirror/mock/MockJournaler.cc
 
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE at unittest_rbd_mirror_CXXFLAGS = $(UNITTEST_CXXFLAGS)
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE at unittest_rbd_mirror_LDADD = \
@@ -11075,8 +11561,25 @@ librbd_types_la_SOURCES = \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	$(LIBOSDC) $(UNITTEST_LDADD) \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	$(CEPH_GLOBAL) $(RADOS_TEST_LDADD)
 
+ at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE at ceph_test_rbd_mirror_image_replay_SOURCES = \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	test/rbd_mirror/image_replay.cc
+
+ at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE at ceph_test_rbd_mirror_image_replay_LDADD = \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	librbd_mirror_internal.la \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	librbd_internal.la \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	librbd_api.la \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	$(LIBRBD_TYPES) \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	libjournal.la \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	$(LIBRADOS) $(LIBOSDC) \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	librados_internal.la \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	libcls_rbd_client.la \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	libcls_lock_client.la \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	libcls_journal_client.la \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	$(CEPH_GLOBAL)
+
 @ENABLE_CLIENT_TRUE@@LINUX_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE at ceph_test_librbd_fsx_SOURCES = test/librbd/fsx.cc
 @ENABLE_CLIENT_TRUE@@LINUX_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE at ceph_test_librbd_fsx_LDADD = \
+ at ENABLE_CLIENT_TRUE@@LINUX_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	libjournal.la libcls_journal_client.la \
 @ENABLE_CLIENT_TRUE@@LINUX_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	$(LIBKRBD) $(LIBRBD) $(LIBRADOS) \
 @ENABLE_CLIENT_TRUE@@LINUX_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	$(CRYPTO_LIBS) $(PTHREAD_LIBS)
 
@@ -11130,7 +11633,7 @@ librbd_types_la_SOURCES = \
 @ENABLE_CLIENT_TRUE@@WITH_CEPHFS_TRUE@@WITH_RADOS_TRUE@	test/libcephfs/multiclient.cc \
 @ENABLE_CLIENT_TRUE@@WITH_CEPHFS_TRUE@@WITH_RADOS_TRUE@	test/libcephfs/access.cc \
 @ENABLE_CLIENT_TRUE@@WITH_CEPHFS_TRUE@@WITH_RADOS_TRUE@	test/libcephfs/acl.cc \
- at ENABLE_CLIENT_TRUE@@WITH_CEPHFS_TRUE@@WITH_RADOS_TRUE@	$(am__append_235)
+ at ENABLE_CLIENT_TRUE@@WITH_CEPHFS_TRUE@@WITH_RADOS_TRUE@	$(am__append_237)
 @ENABLE_CLIENT_TRUE@@WITH_CEPHFS_TRUE@@WITH_RADOS_TRUE at ceph_test_libcephfs_LDADD = $(LIBRADOS) $(LIBCEPHFS) $(LIBCOMMON) $(UNITTEST_LDADD)
 @ENABLE_CLIENT_TRUE@@WITH_CEPHFS_TRUE@@WITH_RADOS_TRUE at ceph_test_libcephfs_CXXFLAGS = $(UNITTEST_CXXFLAGS)
 @ENABLE_CLIENT_TRUE@@WITH_CEPHFS_TRUE@@WITH_RADOS_TRUE at unittest_encoding_SOURCES = test/encoding.cc
@@ -11153,7 +11656,7 @@ librbd_types_la_SOURCES = \
 @ENABLE_CLIENT_TRUE@@WITH_CEPHFS_TRUE@@WITH_RADOS_TRUE@	-Wignored-qualifiers \
 @ENABLE_CLIENT_TRUE@@WITH_CEPHFS_TRUE@@WITH_RADOS_TRUE@	-Wold-style-definition \
 @ENABLE_CLIENT_TRUE@@WITH_CEPHFS_TRUE@@WITH_RADOS_TRUE@	-Wtype-limits \
- at ENABLE_CLIENT_TRUE@@WITH_CEPHFS_TRUE@@WITH_RADOS_TRUE@	$(am__append_237)
+ at ENABLE_CLIENT_TRUE@@WITH_CEPHFS_TRUE@@WITH_RADOS_TRUE@	$(am__append_239)
 @ENABLE_CLIENT_TRUE@@WITH_BUILD_TESTS_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE at test_build_librgw_SOURCES = \
 @ENABLE_CLIENT_TRUE@@WITH_BUILD_TESTS_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	test/buildtest_skeleton.cc \
 @ENABLE_CLIENT_TRUE@@WITH_BUILD_TESTS_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	$(librgw_la_SOURCES)
@@ -11166,18 +11669,6 @@ librbd_types_la_SOURCES = \
 @ENABLE_CLIENT_TRUE@@WITH_BUILD_TESTS_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE at test_build_librgw_LDFLAGS = -static-libtool-libs
 @ENABLE_CLIENT_TRUE@@WITH_BUILD_TESTS_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE at test_build_librgw_CFLAGS = $(AM_CFLAGS)
 @ENABLE_CLIENT_TRUE@@WITH_BUILD_TESTS_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE at test_build_librgw_CXXFLAGS = $(AM_CXXFLAGS)
-
-#unittest_librgw_link_SOURCES = test/librgw_link.cc
-#unittest_librgw_link_LDFLAGS = $(PTHREAD_CFLAGS) ${AM_LDFLAGS}
-#unittest_librgw_link_LDADD = $(LIBRGW) ${UNITTEST_LDADD}
-#unittest_librgw_link_CXXFLAGS = ${CRYPTO_CFLAGS} ${AM_CXXFLAGS} ${UNITTEST_CXXFLAGS}
-#check_TESTPROGRAMS += unittest_librgw_link
-
-#unittest_librgw_SOURCES = test/librgw.cc
-#unittest_librgw_LDFLAGS = -lrt $(PTHREAD_CFLAGS) -lcurl ${AM_LDFLAGS}
-#unittest_librgw_LDADD =  librgw.la $(LIBRADOS) ${UNITTEST_LDADD} -lexpat $(CEPH_GLOBAL)
-#unittest_librgw_CXXFLAGS = ${CRYPTO_CFLAGS} ${AM_CXXFLAGS} ${UNITTEST_CXXFLAGS}
-#check_TESTPROGRAMS += unittest_librgw
 @ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE at ceph_test_cors_SOURCES = test/test_cors.cc
 @ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE at ceph_test_cors_LDADD = \
 @ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	$(LIBRADOS) $(LIBRGW) $(CEPH_GLOBAL) \
@@ -11192,6 +11683,12 @@ librbd_types_la_SOURCES = \
 @ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	-lcurl -lexpat
 
 @ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE at ceph_test_rgw_manifest_CXXFLAGS = $(UNITTEST_CXXFLAGS)
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE at ceph_test_rgw_period_history_SOURCES = test/rgw/test_rgw_period_history.cc
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE at ceph_test_rgw_period_history_LDADD = \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	$(LIBRADOS) $(LIBRGW) $(LIBRGW_DEPS) $(CEPH_GLOBAL) \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	$(UNITTEST_LDADD) $(CRYPTO_LIBS) -lcurl -lexpat
+
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE at ceph_test_rgw_period_history_CXXFLAGS = $(UNITTEST_CXXFLAGS)
 @ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE at ceph_test_rgw_obj_SOURCES = test/rgw/test_rgw_obj.cc
 @ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE at ceph_test_rgw_obj_LDADD = \
 @ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	$(LIBRADOS) $(LIBRGW) $(LIBRGW_DEPS) $(CEPH_GLOBAL) \
@@ -11201,22 +11698,23 @@ librbd_types_la_SOURCES = \
 @ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE at ceph_test_rgw_obj_CXXFLAGS = $(UNITTEST_CXXFLAGS)
 @ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE at ceph_test_cls_rgw_meta_SOURCES = test/test_rgw_admin_meta.cc
 @ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE at ceph_test_cls_rgw_meta_LDADD = \
- at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	$(LIBRADOS) $(LIBRGW) $(CEPH_GLOBAL) \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	$(LIBRGW) $(LIBRADOS) $(CEPH_GLOBAL) \
 @ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	$(UNITTEST_LDADD) $(CRYPTO_LIBS) \
 @ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	-lcurl -lexpat \
- at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	libcls_version_client.a libcls_log_client.a \
- at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	libcls_statelog_client.a libcls_refcount_client.la \
- at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	libcls_rgw_client.la libcls_user_client.a libcls_lock_client.la
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	libcls_timeindex_client.la \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	libcls_version_client.la libcls_log_client.la \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	libcls_statelog_client.la libcls_refcount_client.la \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	libcls_rgw_client.la libcls_user_client.la libcls_lock_client.la
 
 @ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE at ceph_test_cls_rgw_meta_CXXFLAGS = $(UNITTEST_CXXFLAGS)
 @ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE at ceph_test_cls_rgw_log_SOURCES = test/test_rgw_admin_log.cc
 @ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE at ceph_test_cls_rgw_log_LDADD = \
- at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	$(LIBRADOS) $(LIBRGW) $(CEPH_GLOBAL) \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	$(LIBRADOS) $(LIBRGW) $(LIBRGW_DEPS) $(CEPH_GLOBAL) \
 @ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	$(UNITTEST_LDADD) $(CRYPTO_LIBS) \
 @ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	-lcurl -lexpat \
- at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	libcls_version_client.a libcls_log_client.a \
- at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	libcls_statelog_client.a libcls_refcount_client.la \
- at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	libcls_rgw_client.la libcls_user_client.a libcls_lock_client.la
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	libcls_version_client.la libcls_log_client.la \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	libcls_statelog_client.la libcls_refcount_client.la \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	libcls_rgw_client.la libcls_user_client.la libcls_lock_client.la
 
 @ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE at ceph_test_cls_rgw_log_CXXFLAGS = $(UNITTEST_CXXFLAGS)
 @ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE at ceph_test_cls_rgw_opstate_SOURCES = test/test_rgw_admin_opstate.cc
@@ -11224,9 +11722,10 @@ librbd_types_la_SOURCES = \
 @ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	$(LIBRADOS) $(LIBRGW) $(CEPH_GLOBAL) \
 @ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	$(UNITTEST_LDADD) $(CRYPTO_LIBS) \
 @ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	-lcurl -lexpat \
- at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	libcls_version_client.a libcls_log_client.a  libcls_timeindex_client.a \
- at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	libcls_statelog_client.a libcls_refcount_client.la \
- at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	libcls_rgw_client.la libcls_user_client.a libcls_lock_client.la \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	libcls_version_client.la libcls_log_client.la \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	libcls_timeindex_client.la \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	libcls_statelog_client.la libcls_refcount_client.la \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	libcls_rgw_client.la libcls_user_client.la libcls_lock_client.la \
 @ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	$(LIBRADOS)
 
 @ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE at ceph_test_cls_rgw_opstate_CXXFLAGS = $(UNITTEST_CXXFLAGS)
@@ -11236,6 +11735,33 @@ librbd_types_la_SOURCES = \
 @ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	$(LIBCOMMON) $(UNITTEST_LDADD) $(CEPH_GLOBAL) $(RADOS_TEST_LDADD)
 
 @ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE at ceph_test_cls_rgw_CXXFLAGS = $(UNITTEST_CXXFLAGS)
+
+# librgw/RGW-NFS
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE at librgw_file_SOURCES = test/librgw_file.cc
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE at librgw_file_CXXFLAGS = -I$(srcdir)/xxHash $(UNITTEST_CXXFLAGS)
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE at librgw_file_LDADD = $(UNITTEST_LDADD)  \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	librgw.la librados.la $(PTHREAD_LIBS) $(CEPH_GLOBAL) $(EXTRALIBS) 
+
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE at librgw_file_cd_SOURCES = test/librgw_file_cd.cc
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE at librgw_file_cd_CXXFLAGS = -I$(srcdir)/xxHash $(UNITTEST_CXXFLAGS)
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE at librgw_file_cd_LDADD = $(UNITTEST_LDADD) \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	librgw.la librados.la $(PTHREAD_LIBS) $(CEPH_GLOBAL) $(EXTRALIBS)
+
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE at librgw_file_gp_SOURCES = test/librgw_file_gp.cc
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE at librgw_file_gp_CXXFLAGS = -I$(srcdir)/xxHash $(UNITTEST_CXXFLAGS)
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE at librgw_file_gp_LDADD = $(UNITTEST_LDADD) \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	librgw.la librados.la $(PTHREAD_LIBS) $(CEPH_GLOBAL) $(EXTRALIBS)
+
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE at librgw_file_aw_SOURCES = test/librgw_file_aw.cc
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE at librgw_file_aw_CXXFLAGS = -I$(srcdir)/xxHash $(UNITTEST_CXXFLAGS)
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE at librgw_file_aw_LDADD = $(UNITTEST_LDADD) \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	librgw.la librados.la $(PTHREAD_LIBS) $(CEPH_GLOBAL) $(EXTRALIBS)
+
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE at librgw_file_nfsns_SOURCES = test/librgw_file_nfsns.cc
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE at librgw_file_nfsns_CXXFLAGS = -I$(srcdir)/xxHash $(UNITTEST_CXXFLAGS)
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE at librgw_file_nfsns_LDADD = $(UNITTEST_LDADD) \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOSGW_TRUE@@WITH_RADOS_TRUE@	librgw.la librados.la $(PTHREAD_LIBS) $(CEPH_GLOBAL) $(EXTRALIBS)
+
 @ENABLE_SERVER_TRUE at ceph_test_async_driver_SOURCES = test/msgr/test_async_driver.cc
 @ENABLE_SERVER_TRUE at ceph_test_async_driver_LDADD = $(LIBOS) $(UNITTEST_LDADD) $(CEPH_GLOBAL)
 @ENABLE_SERVER_TRUE at ceph_test_async_driver_CXXFLAGS = $(UNITTEST_CXXFLAGS)
@@ -11358,13 +11884,13 @@ librbd_types_la_SOURCES = \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE at unittest_osdscrub_LDADD =  \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(LIBOSD) $(UNITTEST_LDADD) \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(CEPH_GLOBAL) \
- at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__append_251)
+ at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__append_253)
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE at unittest_pglog_SOURCES = test/osd/TestPGLog.cc
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE at unittest_pglog_CXXFLAGS = $(UNITTEST_CXXFLAGS)
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE at unittest_pglog_LDADD = $(LIBOSD) \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(UNITTEST_LDADD) \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(CEPH_GLOBAL) \
- at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__append_252)
+ at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__append_254)
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE at unittest_hitset_SOURCES = test/osd/hitset.cc
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE at unittest_hitset_CXXFLAGS = $(UNITTEST_CXXFLAGS)
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE at unittest_hitset_LDADD = $(LIBOSD) $(UNITTEST_LDADD) $(CEPH_GLOBAL)
@@ -11431,7 +11957,7 @@ UNITTEST_CXXFLAGS = \
 UNITTEST_LDADD = $(top_builddir)/src/gmock/lib/libgmock_main.la \
 	$(top_builddir)/src/gmock/lib/libgmock.la \
 	$(top_builddir)/src/gmock/gtest/lib/libgtest.la \
-	$(PTHREAD_LIBS) $(am__append_260)
+	$(PTHREAD_LIBS) $(am__append_262)
 unittest_addrs_SOURCES = test/test_addrs.cc
 unittest_addrs_CXXFLAGS = $(UNITTEST_CXXFLAGS)
 unittest_addrs_LDADD = $(UNITTEST_LDADD) $(CEPH_GLOBAL)
@@ -11639,8 +12165,7 @@ ceph_test_cfuse_cache_invalidate_SOURCES = test/test_cfuse_cache_invalidate.cc
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@	needs cleanup so it can \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@	go in libcommon.la
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE at rados_LDADD = libcls_lock_client.la $(LIBRADOS) $(LIBRADOSSTRIPER) $(CEPH_GLOBAL)
- at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE at rbd_SOURCES = \
- at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	tools/rbd/rbd.cc \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE at rbd_SOURCES = tools/rbd/rbd.cc \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	tools/rbd/ArgumentTypes.cc \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	tools/rbd/IndentStream.cc \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	tools/rbd/OptionPrinter.cc \
@@ -11662,25 +12187,28 @@ ceph_test_cfuse_cache_invalidate_SOURCES = test/test_cfuse_cache_invalidate.cc
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	tools/rbd/action/ImportDiff.cc \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	tools/rbd/action/Info.cc \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	tools/rbd/action/Journal.cc \
- at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	tools/rbd/action/Kernel.cc \
- at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	tools/rbd/action/Nbd.cc \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	tools/rbd/action/List.cc \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	tools/rbd/action/Lock.cc \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	tools/rbd/action/MergeDiff.cc \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	tools/rbd/action/MirrorPool.cc \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	tools/rbd/action/MirrorImage.cc \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	tools/rbd/action/ObjectMap.cc \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	tools/rbd/action/Remove.cc \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	tools/rbd/action/Rename.cc \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	tools/rbd/action/Resize.cc \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	tools/rbd/action/Snap.cc \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	tools/rbd/action/Status.cc \
- at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	tools/rbd/action/Watch.cc
-
- at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE at rbd_LDADD = \
- at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	libjournal.la libcls_journal_client.la \
- at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	$(LIBKRBD) $(LIBRBD) $(LIBRBD_TYPES) $(LIBRADOS) $(CEPH_GLOBAL) \
- at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	$(BOOST_REGEX_LIBS) $(BOOST_PROGRAM_OPTIONS_LIBS)
-
+ at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	tools/rbd/action/Watch.cc \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	$(am__append_267)
+ at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE at rbd_LDADD = libjournal.la \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	libcls_journal_client.la \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	$(LIBRBD) \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	$(LIBRBD_TYPES) \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	$(LIBRADOS) \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	$(CEPH_GLOBAL) \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	$(BOOST_REGEX_LIBS) \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	$(BOOST_PROGRAM_OPTIONS_LIBS) \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	$(am__append_269)
 @ENABLE_CLIENT_TRUE@@LINUX_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE at rbd_nbd_SOURCES = tools/rbd_nbd/rbd-nbd.cc
 @ENABLE_CLIENT_TRUE@@LINUX_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE at rbd_nbd_CXXFLAGS = $(AM_CXXFLAGS)
 @ENABLE_CLIENT_TRUE@@LINUX_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE at rbd_nbd_LDADD = $(LIBRBD) $(LIBRADOS) $(CEPH_GLOBAL) $(BOOST_REGEX_LIBS)
@@ -11689,10 +12217,20 @@ ceph_test_cfuse_cache_invalidate_SOURCES = test/test_cfuse_cache_invalidate.cc
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE at librbd_mirror_internal_la_SOURCES = \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	tools/rbd_mirror/ClusterWatcher.cc \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	tools/rbd_mirror/ImageReplayer.cc \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	tools/rbd_mirror/ImageSync.cc \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	tools/rbd_mirror/Mirror.cc \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	tools/rbd_mirror/PoolWatcher.cc \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	tools/rbd_mirror/Replayer.cc \
- at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	tools/rbd_mirror/types.cc
+ at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	tools/rbd_mirror/Threads.cc \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	tools/rbd_mirror/types.cc \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	tools/rbd_mirror/image_replayer/BootstrapRequest.cc \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	tools/rbd_mirror/image_replayer/CloseImageRequest.cc \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	tools/rbd_mirror/image_replayer/OpenLocalImageRequest.cc \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	tools/rbd_mirror/image_sync/ImageCopyRequest.cc \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	tools/rbd_mirror/image_sync/ObjectCopyRequest.cc \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	tools/rbd_mirror/image_sync/SnapshotCopyRequest.cc \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	tools/rbd_mirror/image_sync/SyncPointCreateRequest.cc \
+ at ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	tools/rbd_mirror/image_sync/SyncPointPruneRequest.cc
 
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE at rbd_mirror_SOURCES = \
 @ENABLE_CLIENT_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	tools/rbd_mirror/main.cc
@@ -11726,10 +12264,11 @@ ceph_test_cfuse_cache_invalidate_SOURCES = test/test_cfuse_cache_invalidate.cc
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(LIBOSD) $(LIBOS) \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(CEPH_GLOBAL) \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(BOOST_PROGRAM_OPTIONS_LIBS) \
- at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__append_271)
+ at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__append_276)
 @ENABLE_CLIENT_TRUE@@ENABLE_SERVER_TRUE@@WITH_MDS_TRUE@@WITH_RADOS_TRUE at cephfs_journal_tool_SOURCES = \
 @ENABLE_CLIENT_TRUE@@ENABLE_SERVER_TRUE@@WITH_MDS_TRUE@@WITH_RADOS_TRUE@	tools/cephfs/cephfs-journal-tool.cc \
 @ENABLE_CLIENT_TRUE@@ENABLE_SERVER_TRUE@@WITH_MDS_TRUE@@WITH_RADOS_TRUE@	tools/cephfs/JournalTool.cc \
+ at ENABLE_CLIENT_TRUE@@ENABLE_SERVER_TRUE@@WITH_MDS_TRUE@@WITH_RADOS_TRUE@	tools/cephfs/RoleSelector.cc \
 @ENABLE_CLIENT_TRUE@@ENABLE_SERVER_TRUE@@WITH_MDS_TRUE@@WITH_RADOS_TRUE@	tools/cephfs/JournalFilter.cc \
 @ENABLE_CLIENT_TRUE@@ENABLE_SERVER_TRUE@@WITH_MDS_TRUE@@WITH_RADOS_TRUE@	tools/cephfs/JournalScanner.cc \
 @ENABLE_CLIENT_TRUE@@ENABLE_SERVER_TRUE@@WITH_MDS_TRUE@@WITH_RADOS_TRUE@	tools/cephfs/EventOutput.cc \
@@ -11741,12 +12280,14 @@ ceph_test_cfuse_cache_invalidate_SOURCES = test/test_cfuse_cache_invalidate.cc
 @ENABLE_CLIENT_TRUE@@ENABLE_SERVER_TRUE@@WITH_MDS_TRUE@@WITH_RADOS_TRUE at cephfs_table_tool_SOURCES = \
 @ENABLE_CLIENT_TRUE@@ENABLE_SERVER_TRUE@@WITH_MDS_TRUE@@WITH_RADOS_TRUE@	tools/cephfs/cephfs-table-tool.cc \
 @ENABLE_CLIENT_TRUE@@ENABLE_SERVER_TRUE@@WITH_MDS_TRUE@@WITH_RADOS_TRUE@	tools/cephfs/TableTool.cc \
+ at ENABLE_CLIENT_TRUE@@ENABLE_SERVER_TRUE@@WITH_MDS_TRUE@@WITH_RADOS_TRUE@	tools/cephfs/RoleSelector.cc \
 @ENABLE_CLIENT_TRUE@@ENABLE_SERVER_TRUE@@WITH_MDS_TRUE@@WITH_RADOS_TRUE@	tools/cephfs/MDSUtility.cc
 
 @ENABLE_CLIENT_TRUE@@ENABLE_SERVER_TRUE@@WITH_MDS_TRUE@@WITH_RADOS_TRUE at cephfs_table_tool_LDADD = $(LIBMDS) $(LIBRADOS) $(CEPH_GLOBAL)
 @ENABLE_CLIENT_TRUE@@ENABLE_SERVER_TRUE@@WITH_MDS_TRUE@@WITH_RADOS_TRUE at cephfs_data_scan_SOURCES = \
 @ENABLE_CLIENT_TRUE@@ENABLE_SERVER_TRUE@@WITH_MDS_TRUE@@WITH_RADOS_TRUE@	tools/cephfs/cephfs-data-scan.cc \
 @ENABLE_CLIENT_TRUE@@ENABLE_SERVER_TRUE@@WITH_MDS_TRUE@@WITH_RADOS_TRUE@	tools/cephfs/DataScan.cc \
+ at ENABLE_CLIENT_TRUE@@ENABLE_SERVER_TRUE@@WITH_MDS_TRUE@@WITH_RADOS_TRUE@	tools/cephfs/RoleSelector.cc \
 @ENABLE_CLIENT_TRUE@@ENABLE_SERVER_TRUE@@WITH_MDS_TRUE@@WITH_RADOS_TRUE@	tools/cephfs/MDSUtility.cc
 
 @ENABLE_CLIENT_TRUE@@ENABLE_SERVER_TRUE@@WITH_MDS_TRUE@@WITH_RADOS_TRUE at cephfs_data_scan_LDADD = $(LIBMDS) libcls_cephfs_client.la $(LIBRADOS) $(CEPH_GLOBAL)
@@ -11802,12 +12343,12 @@ librbd_tp_la_LDFLAGS = -version-info 1:0:0
 libos_tp_la_LIBADD = -ldl -llttng-ust
 libos_tp_la_CFLAGS = -I$(top_srcdir)/src/tracing -I$(top_srcdir)/src $(AM_CFLAGS) -fpic
 libos_tp_la_LDFLAGS = -version-info 1:0:0
- at ENABLE_CLIENT_TRUE@@WITH_CYTHON_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE at PY_DISTUTILS = \
- at ENABLE_CLIENT_TRUE@@WITH_CYTHON_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	CPPFLAGS="-iquote \${abs_srcdir}/include ${AM_CPPFLAGS} ${CPPFLAGS}" \
- at ENABLE_CLIENT_TRUE@@WITH_CYTHON_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	CFLAGS="-iquote \${abs_srcdir}/include ${AM_CFLAGS} ${CFLAGS}" \
- at ENABLE_CLIENT_TRUE@@WITH_CYTHON_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	LDFLAGS="-L\${abs_builddir}/.libs $(subst -pie,,${AM_LDFLAGS}) ${LDFLAGS}" \
- at ENABLE_CLIENT_TRUE@@WITH_CYTHON_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	CYTHON_BUILD_DIR="$(shell readlink -f $(builddir))/build" \
- at ENABLE_CLIENT_TRUE@@WITH_CYTHON_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	${PYTHON} ./setup.py
+ at ENABLE_CLIENT_TRUE@@WITH_CYTHON_TRUE at PY_DISTUTILS = \
+ at ENABLE_CLIENT_TRUE@@WITH_CYTHON_TRUE@	CPPFLAGS="-iquote \${abs_srcdir}/include ${AM_CPPFLAGS} ${CPPFLAGS}" \
+ at ENABLE_CLIENT_TRUE@@WITH_CYTHON_TRUE@	CFLAGS="-iquote \${abs_srcdir}/include ${AM_CFLAGS} ${PYTHON_CFLAGS}" \
+ at ENABLE_CLIENT_TRUE@@WITH_CYTHON_TRUE@	LDFLAGS="-L\${abs_builddir}/.libs $(subst -pie,,${AM_LDFLAGS}) ${PYTHON_LDFLAGS}" \
+ at ENABLE_CLIENT_TRUE@@WITH_CYTHON_TRUE@	CYTHON_BUILD_DIR="$(shell readlink -f $(builddir))/build" \
+ at ENABLE_CLIENT_TRUE@@WITH_CYTHON_TRUE@	${PYTHON} ./setup.py
 
 
 # subdirs
@@ -11824,7 +12365,7 @@ editpaths = sed \
 	-e 's|@@GCOV_PREFIX_STRIP[@][@]|$(GCOV_PREFIX_STRIP)|g'
 
 shell_scripts = ceph-debugpack ceph-post-file ceph-crush-location \
-	$(am__append_296)
+	$(am__append_309)
 doc_DATA = $(srcdir)/sample.ceph.conf sample.fetch_config
 
 # various scripts in $(libexecdir)
@@ -11837,12 +12378,11 @@ ceph_libexec_SCRIPTS = ceph_common.sh ceph-osd-prestart.sh
 @WITH_LTTNG_TRUE at TESTS_ENVIRONMENT = LD_PRELOAD=liblttng-ust-fork.so; export LD_PRELOAD; echo "LD_PRELOAD=$${LD_PRELOAD}";
 
 # pybind
-python_PYTHON = $(am__append_279) $(am__append_282) $(am__append_290) \
-	$(am__append_295)
+python_PYTHON = $(am__append_293) $(am__append_303) $(am__append_308)
 @ENABLE_CLIENT_TRUE at bash_completiondir = $(sysconfdir)/bash_completion.d
 @ENABLE_CLIENT_TRUE at bash_completion_DATA =  \
 @ENABLE_CLIENT_TRUE@	$(srcdir)/bash_completion/ceph \
- at ENABLE_CLIENT_TRUE@	$(am__append_281) $(am__append_284)
+ at ENABLE_CLIENT_TRUE@	$(am__append_295) $(am__append_297)
 @ENABLE_CLIENT_TRUE at ceph_syn_SOURCES = ceph_syn.cc \
 @ENABLE_CLIENT_TRUE@	client/SyntheticClient.cc # uses g_conf.. \
 @ENABLE_CLIENT_TRUE@	needs cleanup
@@ -11869,7 +12409,7 @@ python_PYTHON = $(am__append_279) $(am__append_282) $(am__append_290) \
 @ENABLE_CLIENT_TRUE@@WITH_CEPHFS_TRUE@@WITH_RADOS_TRUE@	1:0:0 \
 @ENABLE_CLIENT_TRUE@@WITH_CEPHFS_TRUE@@WITH_RADOS_TRUE@	-export-symbols-regex \
 @ENABLE_CLIENT_TRUE@@WITH_CEPHFS_TRUE@@WITH_RADOS_TRUE@	'^ceph_.*' \
- at ENABLE_CLIENT_TRUE@@WITH_CEPHFS_TRUE@@WITH_RADOS_TRUE@	$(am__append_291)
+ at ENABLE_CLIENT_TRUE@@WITH_CEPHFS_TRUE@@WITH_RADOS_TRUE@	$(am__append_304)
 
 # jni library (java source is in src/java)
 @ENABLE_CEPHFS_JAVA_TRUE@@ENABLE_CLIENT_TRUE@@WITH_CEPHFS_TRUE@@WITH_RADOS_TRUE at libcephfs_jni_la_SOURCES = \
@@ -11882,7 +12422,7 @@ python_PYTHON = $(am__append_279) $(am__append_282) $(am__append_290) \
 @ENABLE_CEPHFS_JAVA_TRUE@@ENABLE_CLIENT_TRUE@@WITH_CEPHFS_TRUE@@WITH_RADOS_TRUE at libcephfs_jni_la_CPPFLAGS = $(JDK_CPPFLAGS) $(AM_CPPFLAGS)
 @ENABLE_CEPHFS_JAVA_TRUE@@ENABLE_CLIENT_TRUE@@WITH_CEPHFS_TRUE@@WITH_RADOS_TRUE at libcephfs_jni_la_LDFLAGS = ${AM_LDFLAGS} -version-info 1:0:0
 @ENABLE_SERVER_TRUE at ceph_sbin_SCRIPTS = ceph-create-keys \
- at ENABLE_SERVER_TRUE@	$(am__append_301)
+ at ENABLE_SERVER_TRUE@	$(am__append_314)
 @ENABLE_SERVER_TRUE at mount_ceph_SOURCES = mount/mount.ceph.c
 @ENABLE_SERVER_TRUE at mount_ceph_LDADD = $(LIBSECRET) $(LIBCOMMON)
 @ENABLE_SERVER_TRUE@@WITH_MON_TRUE at ceph_mon_SOURCES = ceph_mon.cc
@@ -11892,7 +12432,7 @@ python_PYTHON = $(am__append_279) $(am__append_282) $(am__append_290) \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(LIBOSD) $(LIBOSD_TYPES) \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(LIBOS_TYPES) $(LIBOS) \
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(CEPH_GLOBAL) $(LIBCOMMON) \
- at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__append_303)
+ at ENABLE_SERVER_TRUE@@WITH_OSD_TRUE@	$(am__append_316)
 @ENABLE_SERVER_TRUE@@WITH_MDS_TRUE at ceph_mds_SOURCES = ceph_mds.cc
 @ENABLE_SERVER_TRUE@@WITH_MDS_TRUE at ceph_mds_LDADD = $(LIBMDS) $(LIBOSDC) $(CEPH_GLOBAL) $(LIBCOMMON)
 @ENABLE_COVERAGE_TRUE@@ENABLE_SERVER_TRUE at COV_DIR = $(DESTDIR)$(libdir)/ceph/coverage
@@ -11903,7 +12443,7 @@ all: $(BUILT_SOURCES) acconfig.h
 
 .SUFFIXES:
 .SUFFIXES: .S .c .cc .cpp .lo .log .o .obj .s .test .test$(EXEEXT) .trs
-$(srcdir)/Makefile.in:  $(srcdir)/Makefile.am $(srcdir)/Makefile-env.am $(srcdir)/arch/Makefile.am $(srcdir)/auth/Makefile.am $(srcdir)/brag/Makefile.am $(srcdir)/ceph-detect-init/Makefile.am $(srcdir)/ceph-disk/Makefile.am $(srcdir)/crush/Makefile.am $(srcdir)/kv/Makefile.am $(srcdir)/mon/Makefile.am $(srcdir)/mds/Makefile.am $(srcdir)/mds/Makefile-client.am $(srcdir)/mds/Makefile-server.am $(srcdir)/os/Makefile.am $(srcdir)/osd/Makefile.am $(srcdir)/erasure-code/Makefile.am $(srcdir)/e [...]
+$(srcdir)/Makefile.in:  $(srcdir)/Makefile.am $(srcdir)/Makefile-env.am $(srcdir)/arch/Makefile.am $(srcdir)/auth/Makefile.am $(srcdir)/brag/Makefile.am $(srcdir)/ceph-detect-init/Makefile.am $(srcdir)/ceph-disk/Makefile.am $(srcdir)/crush/Makefile.am $(srcdir)/kv/Makefile.am $(srcdir)/mon/Makefile.am $(srcdir)/mds/Makefile.am $(srcdir)/mds/Makefile-client.am $(srcdir)/mds/Makefile-server.am $(srcdir)/os/Makefile.am $(srcdir)/osd/Makefile.am $(srcdir)/erasure-code/Makefile.am $(srcdir)/e [...]
 	@for dep in $?; do \
 	  case '$(am__configure_deps)' in \
 	    *$$dep*) \
@@ -11915,6 +12455,7 @@ $(srcdir)/Makefile.in:  $(srcdir)/Makefile.am $(srcdir)/Makefile-env.am $(srcdir
 	echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/Makefile'; \
 	$(am__cd) $(top_srcdir) && \
 	  $(AUTOMAKE) --gnu src/Makefile
+.PRECIOUS: Makefile
 Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
 	@case '$?' in \
 	  *config.status*) \
@@ -11923,7 +12464,7 @@ Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
 	    echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
 	    cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
 	esac;
-$(srcdir)/Makefile-env.am $(srcdir)/arch/Makefile.am $(srcdir)/auth/Makefile.am $(srcdir)/brag/Makefile.am $(srcdir)/ceph-detect-init/Makefile.am $(srcdir)/ceph-disk/Makefile.am $(srcdir)/crush/Makefile.am $(srcdir)/kv/Makefile.am $(srcdir)/mon/Makefile.am $(srcdir)/mds/Makefile.am $(srcdir)/mds/Makefile-client.am $(srcdir)/mds/Makefile-server.am $(srcdir)/os/Makefile.am $(srcdir)/osd/Makefile.am $(srcdir)/erasure-code/Makefile.am $(srcdir)/erasure-code/jerasure/Makefile.am $(srcdir)/era [...]
+$(srcdir)/Makefile-env.am $(srcdir)/arch/Makefile.am $(srcdir)/auth/Makefile.am $(srcdir)/brag/Makefile.am $(srcdir)/ceph-detect-init/Makefile.am $(srcdir)/ceph-disk/Makefile.am $(srcdir)/crush/Makefile.am $(srcdir)/kv/Makefile.am $(srcdir)/mon/Makefile.am $(srcdir)/mds/Makefile.am $(srcdir)/mds/Makefile-client.am $(srcdir)/mds/Makefile-server.am $(srcdir)/os/Makefile.am $(srcdir)/osd/Makefile.am $(srcdir)/erasure-code/Makefile.am $(srcdir)/erasure-code/jerasure/Makefile.am $(srcdir)/era [...]
 
 $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
 	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
@@ -11951,113 +12492,20 @@ distclean-hdr:
 
 clean-noinstLIBRARIES:
 	-test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES)
-cls/log/$(am__dirstamp):
-	@$(MKDIR_P) cls/log
-	@: > cls/log/$(am__dirstamp)
-cls/log/$(DEPDIR)/$(am__dirstamp):
-	@$(MKDIR_P) cls/log/$(DEPDIR)
-	@: > cls/log/$(DEPDIR)/$(am__dirstamp)
-cls/log/cls_log_client.$(OBJEXT): cls/log/$(am__dirstamp) \
-	cls/log/$(DEPDIR)/$(am__dirstamp)
-
-libcls_log_client.a: $(libcls_log_client_a_OBJECTS) $(libcls_log_client_a_DEPENDENCIES) $(EXTRA_libcls_log_client_a_DEPENDENCIES) 
-	$(AM_V_at)-rm -f libcls_log_client.a
-	$(AM_V_AR)$(libcls_log_client_a_AR) libcls_log_client.a $(libcls_log_client_a_OBJECTS) $(libcls_log_client_a_LIBADD)
-	$(AM_V_at)$(RANLIB) libcls_log_client.a
-cls/replica_log/$(am__dirstamp):
-	@$(MKDIR_P) cls/replica_log
-	@: > cls/replica_log/$(am__dirstamp)
-cls/replica_log/$(DEPDIR)/$(am__dirstamp):
-	@$(MKDIR_P) cls/replica_log/$(DEPDIR)
-	@: > cls/replica_log/$(DEPDIR)/$(am__dirstamp)
-cls/replica_log/cls_replica_log_types.$(OBJEXT):  \
-	cls/replica_log/$(am__dirstamp) \
-	cls/replica_log/$(DEPDIR)/$(am__dirstamp)
-cls/replica_log/cls_replica_log_ops.$(OBJEXT):  \
-	cls/replica_log/$(am__dirstamp) \
-	cls/replica_log/$(DEPDIR)/$(am__dirstamp)
-cls/replica_log/cls_replica_log_client.$(OBJEXT):  \
-	cls/replica_log/$(am__dirstamp) \
-	cls/replica_log/$(DEPDIR)/$(am__dirstamp)
-
-libcls_replica_log_client.a: $(libcls_replica_log_client_a_OBJECTS) $(libcls_replica_log_client_a_DEPENDENCIES) $(EXTRA_libcls_replica_log_client_a_DEPENDENCIES) 
-	$(AM_V_at)-rm -f libcls_replica_log_client.a
-	$(AM_V_AR)$(libcls_replica_log_client_a_AR) libcls_replica_log_client.a $(libcls_replica_log_client_a_OBJECTS) $(libcls_replica_log_client_a_LIBADD)
-	$(AM_V_at)$(RANLIB) libcls_replica_log_client.a
-cls/statelog/$(am__dirstamp):
-	@$(MKDIR_P) cls/statelog
-	@: > cls/statelog/$(am__dirstamp)
-cls/statelog/$(DEPDIR)/$(am__dirstamp):
-	@$(MKDIR_P) cls/statelog/$(DEPDIR)
-	@: > cls/statelog/$(DEPDIR)/$(am__dirstamp)
-cls/statelog/cls_statelog_client.$(OBJEXT):  \
-	cls/statelog/$(am__dirstamp) \
-	cls/statelog/$(DEPDIR)/$(am__dirstamp)
-
-libcls_statelog_client.a: $(libcls_statelog_client_a_OBJECTS) $(libcls_statelog_client_a_DEPENDENCIES) $(EXTRA_libcls_statelog_client_a_DEPENDENCIES) 
-	$(AM_V_at)-rm -f libcls_statelog_client.a
-	$(AM_V_AR)$(libcls_statelog_client_a_AR) libcls_statelog_client.a $(libcls_statelog_client_a_OBJECTS) $(libcls_statelog_client_a_LIBADD)
-	$(AM_V_at)$(RANLIB) libcls_statelog_client.a
-cls/timeindex/$(am__dirstamp):
-	@$(MKDIR_P) cls/timeindex
-	@: > cls/timeindex/$(am__dirstamp)
-cls/timeindex/$(DEPDIR)/$(am__dirstamp):
-	@$(MKDIR_P) cls/timeindex/$(DEPDIR)
-	@: > cls/timeindex/$(DEPDIR)/$(am__dirstamp)
-cls/timeindex/cls_timeindex_client.$(OBJEXT):  \
-	cls/timeindex/$(am__dirstamp) \
-	cls/timeindex/$(DEPDIR)/$(am__dirstamp)
-
-libcls_timeindex_client.a: $(libcls_timeindex_client_a_OBJECTS) $(libcls_timeindex_client_a_DEPENDENCIES) $(EXTRA_libcls_timeindex_client_a_DEPENDENCIES) 
-	$(AM_V_at)-rm -f libcls_timeindex_client.a
-	$(AM_V_AR)$(libcls_timeindex_client_a_AR) libcls_timeindex_client.a $(libcls_timeindex_client_a_OBJECTS) $(libcls_timeindex_client_a_LIBADD)
-	$(AM_V_at)$(RANLIB) libcls_timeindex_client.a
-cls/user/$(am__dirstamp):
-	@$(MKDIR_P) cls/user
-	@: > cls/user/$(am__dirstamp)
-cls/user/$(DEPDIR)/$(am__dirstamp):
-	@$(MKDIR_P) cls/user/$(DEPDIR)
-	@: > cls/user/$(DEPDIR)/$(am__dirstamp)
-cls/user/cls_user_client.$(OBJEXT): cls/user/$(am__dirstamp) \
-	cls/user/$(DEPDIR)/$(am__dirstamp)
-cls/user/cls_user_types.$(OBJEXT): cls/user/$(am__dirstamp) \
-	cls/user/$(DEPDIR)/$(am__dirstamp)
-cls/user/cls_user_ops.$(OBJEXT): cls/user/$(am__dirstamp) \
-	cls/user/$(DEPDIR)/$(am__dirstamp)
-
-libcls_user_client.a: $(libcls_user_client_a_OBJECTS) $(libcls_user_client_a_DEPENDENCIES) $(EXTRA_libcls_user_client_a_DEPENDENCIES) 
-	$(AM_V_at)-rm -f libcls_user_client.a
-	$(AM_V_AR)$(libcls_user_client_a_AR) libcls_user_client.a $(libcls_user_client_a_OBJECTS) $(libcls_user_client_a_LIBADD)
-	$(AM_V_at)$(RANLIB) libcls_user_client.a
-cls/version/$(am__dirstamp):
-	@$(MKDIR_P) cls/version
-	@: > cls/version/$(am__dirstamp)
-cls/version/$(DEPDIR)/$(am__dirstamp):
-	@$(MKDIR_P) cls/version/$(DEPDIR)
-	@: > cls/version/$(DEPDIR)/$(am__dirstamp)
-cls/version/cls_version_client.$(OBJEXT): cls/version/$(am__dirstamp) \
-	cls/version/$(DEPDIR)/$(am__dirstamp)
-cls/version/cls_version_types.$(OBJEXT): cls/version/$(am__dirstamp) \
-	cls/version/$(DEPDIR)/$(am__dirstamp)
-
-libcls_version_client.a: $(libcls_version_client_a_OBJECTS) $(libcls_version_client_a_DEPENDENCIES) $(EXTRA_libcls_version_client_a_DEPENDENCIES) 
-	$(AM_V_at)-rm -f libcls_version_client.a
-	$(AM_V_AR)$(libcls_version_client_a_AR) libcls_version_client.a $(libcls_version_client_a_OBJECTS) $(libcls_version_client_a_LIBADD)
-	$(AM_V_at)$(RANLIB) libcls_version_client.a
-kv/$(am__dirstamp):
-	@$(MKDIR_P) kv
-	@: > kv/$(am__dirstamp)
-kv/$(DEPDIR)/$(am__dirstamp):
-	@$(MKDIR_P) kv/$(DEPDIR)
-	@: > kv/$(DEPDIR)/$(am__dirstamp)
-kv/libkv_a-KeyValueDB.$(OBJEXT): kv/$(am__dirstamp) \
-	kv/$(DEPDIR)/$(am__dirstamp)
-kv/libkv_a-LevelDBStore.$(OBJEXT): kv/$(am__dirstamp) \
-	kv/$(DEPDIR)/$(am__dirstamp)
-kv/libkv_a-RocksDBStore.$(OBJEXT): kv/$(am__dirstamp) \
-	kv/$(DEPDIR)/$(am__dirstamp)
-kv/libkv_a-KineticStore.$(OBJEXT): kv/$(am__dirstamp) \
-	kv/$(DEPDIR)/$(am__dirstamp)
+kv/$(am__dirstamp):
+	@$(MKDIR_P) kv
+	@: > kv/$(am__dirstamp)
+kv/$(DEPDIR)/$(am__dirstamp):
+	@$(MKDIR_P) kv/$(DEPDIR)
+	@: > kv/$(DEPDIR)/$(am__dirstamp)
+kv/libkv_a-KeyValueDB.$(OBJEXT): kv/$(am__dirstamp) \
+	kv/$(DEPDIR)/$(am__dirstamp)
+kv/libkv_a-LevelDBStore.$(OBJEXT): kv/$(am__dirstamp) \
+	kv/$(DEPDIR)/$(am__dirstamp)
+kv/libkv_a-RocksDBStore.$(OBJEXT): kv/$(am__dirstamp) \
+	kv/$(DEPDIR)/$(am__dirstamp)
+kv/libkv_a-KineticStore.$(OBJEXT): kv/$(am__dirstamp) \
+	kv/$(DEPDIR)/$(am__dirstamp)
 
 libkv.a: $(libkv_a_OBJECTS) $(libkv_a_DEPENDENCIES) $(EXTRA_libkv_a_DEPENDENCIES) 
 	$(AM_V_at)-rm -f libkv.a
@@ -12117,6 +12565,9 @@ os/filestore/libos_a-FileJournal.$(OBJEXT):  \
 os/filestore/libos_a-FileStore.$(OBJEXT):  \
 	os/filestore/$(am__dirstamp) \
 	os/filestore/$(DEPDIR)/$(am__dirstamp)
+os/filestore/libos_a-JournalThrottle.$(OBJEXT):  \
+	os/filestore/$(am__dirstamp) \
+	os/filestore/$(DEPDIR)/$(am__dirstamp)
 os/filestore/libos_a-GenericFileStoreBackend.$(OBJEXT):  \
 	os/filestore/$(am__dirstamp) \
 	os/filestore/$(DEPDIR)/$(am__dirstamp)
@@ -12276,6 +12727,8 @@ osd/libosd_a-OpRequest.$(OBJEXT): osd/$(am__dirstamp) \
 	osd/$(DEPDIR)/$(am__dirstamp)
 osd/libosd_a-SnapMapper.$(OBJEXT): osd/$(am__dirstamp) \
 	osd/$(DEPDIR)/$(am__dirstamp)
+osd/libosd_a-ScrubStore.$(OBJEXT): osd/$(am__dirstamp) \
+	osd/$(DEPDIR)/$(am__dirstamp)
 objclass/$(am__dirstamp):
 	@$(MKDIR_P) objclass
 	@: > objclass/$(am__dirstamp)
@@ -12708,11 +13161,22 @@ cls/lock/cls_lock_ops.lo: cls/lock/$(am__dirstamp) \
 
 libcls_lock_client.la: $(libcls_lock_client_la_OBJECTS) $(libcls_lock_client_la_DEPENDENCIES) $(EXTRA_libcls_lock_client_la_DEPENDENCIES) 
 	$(AM_V_CXXLD)$(CXXLINK) $(am_libcls_lock_client_la_rpath) $(libcls_lock_client_la_OBJECTS) $(libcls_lock_client_la_LIBADD) $(LIBS)
+cls/log/$(am__dirstamp):
+	@$(MKDIR_P) cls/log
+	@: > cls/log/$(am__dirstamp)
+cls/log/$(DEPDIR)/$(am__dirstamp):
+	@$(MKDIR_P) cls/log/$(DEPDIR)
+	@: > cls/log/$(DEPDIR)/$(am__dirstamp)
 cls/log/cls_log.lo: cls/log/$(am__dirstamp) \
 	cls/log/$(DEPDIR)/$(am__dirstamp)
 
 libcls_log.la: $(libcls_log_la_OBJECTS) $(libcls_log_la_DEPENDENCIES) $(EXTRA_libcls_log_la_DEPENDENCIES) 
 	$(AM_V_CXXLD)$(libcls_log_la_LINK) $(am_libcls_log_la_rpath) $(libcls_log_la_OBJECTS) $(libcls_log_la_LIBADD) $(LIBS)
+cls/log/cls_log_client.lo: cls/log/$(am__dirstamp) \
+	cls/log/$(DEPDIR)/$(am__dirstamp)
+
+libcls_log_client.la: $(libcls_log_client_la_OBJECTS) $(libcls_log_client_la_DEPENDENCIES) $(EXTRA_libcls_log_client_la_DEPENDENCIES) 
+	$(AM_V_CXXLD)$(CXXLINK) $(am_libcls_log_client_la_rpath) $(libcls_log_client_la_OBJECTS) $(libcls_log_client_la_LIBADD) $(LIBS)
 cls/numops/$(am__dirstamp):
 	@$(MKDIR_P) cls/numops
 	@: > cls/numops/$(am__dirstamp)
@@ -12773,11 +13237,29 @@ cls/refcount/cls_refcount_client.lo: cls/refcount/$(am__dirstamp) \
 
 libcls_refcount_client.la: $(libcls_refcount_client_la_OBJECTS) $(libcls_refcount_client_la_DEPENDENCIES) $(EXTRA_libcls_refcount_client_la_DEPENDENCIES) 
 	$(AM_V_CXXLD)$(CXXLINK) $(am_libcls_refcount_client_la_rpath) $(libcls_refcount_client_la_OBJECTS) $(libcls_refcount_client_la_LIBADD) $(LIBS)
+cls/replica_log/$(am__dirstamp):
+	@$(MKDIR_P) cls/replica_log
+	@: > cls/replica_log/$(am__dirstamp)
+cls/replica_log/$(DEPDIR)/$(am__dirstamp):
+	@$(MKDIR_P) cls/replica_log/$(DEPDIR)
+	@: > cls/replica_log/$(DEPDIR)/$(am__dirstamp)
 cls/replica_log/cls_replica_log.lo: cls/replica_log/$(am__dirstamp) \
 	cls/replica_log/$(DEPDIR)/$(am__dirstamp)
 
 libcls_replica_log.la: $(libcls_replica_log_la_OBJECTS) $(libcls_replica_log_la_DEPENDENCIES) $(EXTRA_libcls_replica_log_la_DEPENDENCIES) 
 	$(AM_V_CXXLD)$(libcls_replica_log_la_LINK) $(am_libcls_replica_log_la_rpath) $(libcls_replica_log_la_OBJECTS) $(libcls_replica_log_la_LIBADD) $(LIBS)
+cls/replica_log/cls_replica_log_types.lo:  \
+	cls/replica_log/$(am__dirstamp) \
+	cls/replica_log/$(DEPDIR)/$(am__dirstamp)
+cls/replica_log/cls_replica_log_ops.lo:  \
+	cls/replica_log/$(am__dirstamp) \
+	cls/replica_log/$(DEPDIR)/$(am__dirstamp)
+cls/replica_log/cls_replica_log_client.lo:  \
+	cls/replica_log/$(am__dirstamp) \
+	cls/replica_log/$(DEPDIR)/$(am__dirstamp)
+
+libcls_replica_log_client.la: $(libcls_replica_log_client_la_OBJECTS) $(libcls_replica_log_client_la_DEPENDENCIES) $(EXTRA_libcls_replica_log_client_la_DEPENDENCIES) 
+	$(AM_V_CXXLD)$(CXXLINK) $(am_libcls_replica_log_client_la_rpath) $(libcls_replica_log_client_la_OBJECTS) $(libcls_replica_log_client_la_LIBADD) $(LIBS)
 cls/rgw/$(am__dirstamp):
 	@$(MKDIR_P) cls/rgw
 	@: > cls/rgw/$(am__dirstamp)
@@ -12798,26 +13280,76 @@ cls/rgw/cls_rgw_client.lo: cls/rgw/$(am__dirstamp) \
 
 libcls_rgw_client.la: $(libcls_rgw_client_la_OBJECTS) $(libcls_rgw_client_la_DEPENDENCIES) $(EXTRA_libcls_rgw_client_la_DEPENDENCIES) 
 	$(AM_V_CXXLD)$(CXXLINK) $(am_libcls_rgw_client_la_rpath) $(libcls_rgw_client_la_OBJECTS) $(libcls_rgw_client_la_LIBADD) $(LIBS)
+cls/statelog/$(am__dirstamp):
+	@$(MKDIR_P) cls/statelog
+	@: > cls/statelog/$(am__dirstamp)
+cls/statelog/$(DEPDIR)/$(am__dirstamp):
+	@$(MKDIR_P) cls/statelog/$(DEPDIR)
+	@: > cls/statelog/$(DEPDIR)/$(am__dirstamp)
 cls/statelog/cls_statelog.lo: cls/statelog/$(am__dirstamp) \
 	cls/statelog/$(DEPDIR)/$(am__dirstamp)
 
 libcls_statelog.la: $(libcls_statelog_la_OBJECTS) $(libcls_statelog_la_DEPENDENCIES) $(EXTRA_libcls_statelog_la_DEPENDENCIES) 
 	$(AM_V_CXXLD)$(libcls_statelog_la_LINK) $(am_libcls_statelog_la_rpath) $(libcls_statelog_la_OBJECTS) $(libcls_statelog_la_LIBADD) $(LIBS)
+cls/statelog/cls_statelog_client.lo: cls/statelog/$(am__dirstamp) \
+	cls/statelog/$(DEPDIR)/$(am__dirstamp)
+
+libcls_statelog_client.la: $(libcls_statelog_client_la_OBJECTS) $(libcls_statelog_client_la_DEPENDENCIES) $(EXTRA_libcls_statelog_client_la_DEPENDENCIES) 
+	$(AM_V_CXXLD)$(CXXLINK) $(am_libcls_statelog_client_la_rpath) $(libcls_statelog_client_la_OBJECTS) $(libcls_statelog_client_la_LIBADD) $(LIBS)
+cls/timeindex/$(am__dirstamp):
+	@$(MKDIR_P) cls/timeindex
+	@: > cls/timeindex/$(am__dirstamp)
+cls/timeindex/$(DEPDIR)/$(am__dirstamp):
+	@$(MKDIR_P) cls/timeindex/$(DEPDIR)
+	@: > cls/timeindex/$(DEPDIR)/$(am__dirstamp)
 cls/timeindex/cls_timeindex.lo: cls/timeindex/$(am__dirstamp) \
 	cls/timeindex/$(DEPDIR)/$(am__dirstamp)
 
 libcls_timeindex.la: $(libcls_timeindex_la_OBJECTS) $(libcls_timeindex_la_DEPENDENCIES) $(EXTRA_libcls_timeindex_la_DEPENDENCIES) 
 	$(AM_V_CXXLD)$(libcls_timeindex_la_LINK) $(am_libcls_timeindex_la_rpath) $(libcls_timeindex_la_OBJECTS) $(libcls_timeindex_la_LIBADD) $(LIBS)
+cls/timeindex/cls_timeindex_client.lo: cls/timeindex/$(am__dirstamp) \
+	cls/timeindex/$(DEPDIR)/$(am__dirstamp)
+
+libcls_timeindex_client.la: $(libcls_timeindex_client_la_OBJECTS) $(libcls_timeindex_client_la_DEPENDENCIES) $(EXTRA_libcls_timeindex_client_la_DEPENDENCIES) 
+	$(AM_V_CXXLD)$(CXXLINK) $(am_libcls_timeindex_client_la_rpath) $(libcls_timeindex_client_la_OBJECTS) $(libcls_timeindex_client_la_LIBADD) $(LIBS)
+cls/user/$(am__dirstamp):
+	@$(MKDIR_P) cls/user
+	@: > cls/user/$(am__dirstamp)
+cls/user/$(DEPDIR)/$(am__dirstamp):
+	@$(MKDIR_P) cls/user/$(DEPDIR)
+	@: > cls/user/$(DEPDIR)/$(am__dirstamp)
 cls/user/cls_user.lo: cls/user/$(am__dirstamp) \
 	cls/user/$(DEPDIR)/$(am__dirstamp)
 
 libcls_user.la: $(libcls_user_la_OBJECTS) $(libcls_user_la_DEPENDENCIES) $(EXTRA_libcls_user_la_DEPENDENCIES) 
 	$(AM_V_CXXLD)$(libcls_user_la_LINK) $(am_libcls_user_la_rpath) $(libcls_user_la_OBJECTS) $(libcls_user_la_LIBADD) $(LIBS)
+cls/user/cls_user_client.lo: cls/user/$(am__dirstamp) \
+	cls/user/$(DEPDIR)/$(am__dirstamp)
+cls/user/cls_user_types.lo: cls/user/$(am__dirstamp) \
+	cls/user/$(DEPDIR)/$(am__dirstamp)
+cls/user/cls_user_ops.lo: cls/user/$(am__dirstamp) \
+	cls/user/$(DEPDIR)/$(am__dirstamp)
+
+libcls_user_client.la: $(libcls_user_client_la_OBJECTS) $(libcls_user_client_la_DEPENDENCIES) $(EXTRA_libcls_user_client_la_DEPENDENCIES) 
+	$(AM_V_CXXLD)$(CXXLINK) $(am_libcls_user_client_la_rpath) $(libcls_user_client_la_OBJECTS) $(libcls_user_client_la_LIBADD) $(LIBS)
+cls/version/$(am__dirstamp):
+	@$(MKDIR_P) cls/version
+	@: > cls/version/$(am__dirstamp)
+cls/version/$(DEPDIR)/$(am__dirstamp):
+	@$(MKDIR_P) cls/version/$(DEPDIR)
+	@: > cls/version/$(DEPDIR)/$(am__dirstamp)
 cls/version/cls_version.lo: cls/version/$(am__dirstamp) \
 	cls/version/$(DEPDIR)/$(am__dirstamp)
 
 libcls_version.la: $(libcls_version_la_OBJECTS) $(libcls_version_la_DEPENDENCIES) $(EXTRA_libcls_version_la_DEPENDENCIES) 
 	$(AM_V_CXXLD)$(libcls_version_la_LINK) $(am_libcls_version_la_rpath) $(libcls_version_la_OBJECTS) $(libcls_version_la_LIBADD) $(LIBS)
+cls/version/cls_version_client.lo: cls/version/$(am__dirstamp) \
+	cls/version/$(DEPDIR)/$(am__dirstamp)
+cls/version/cls_version_types.lo: cls/version/$(am__dirstamp) \
+	cls/version/$(DEPDIR)/$(am__dirstamp)
+
+libcls_version_client.la: $(libcls_version_client_la_OBJECTS) $(libcls_version_client_la_DEPENDENCIES) $(EXTRA_libcls_version_client_la_DEPENDENCIES) 
+	$(AM_V_CXXLD)$(CXXLINK) $(am_libcls_version_client_la_rpath) $(libcls_version_client_la_OBJECTS) $(libcls_version_client_la_LIBADD) $(LIBS)
 common/buffer.lo: common/$(am__dirstamp) \
 	common/$(DEPDIR)/$(am__dirstamp)
 
@@ -12889,6 +13421,14 @@ common/environment.lo: common/$(am__dirstamp) \
 	common/$(DEPDIR)/$(am__dirstamp)
 common/assert.lo: common/$(am__dirstamp) \
 	common/$(DEPDIR)/$(am__dirstamp)
+xxHash/$(am__dirstamp):
+	@$(MKDIR_P) xxHash
+	@: > xxHash/$(am__dirstamp)
+xxHash/$(DEPDIR)/$(am__dirstamp):
+	@$(MKDIR_P) xxHash/$(DEPDIR)
+	@: > xxHash/$(DEPDIR)/$(am__dirstamp)
+xxHash/xxhash.lo: xxHash/$(am__dirstamp) \
+	xxHash/$(DEPDIR)/$(am__dirstamp)
 common/run_cmd.lo: common/$(am__dirstamp) \
 	common/$(DEPDIR)/$(am__dirstamp)
 common/WorkQueue.lo: common/$(am__dirstamp) \
@@ -12900,6 +13440,8 @@ common/MemoryModel.lo: common/$(am__dirstamp) \
 common/armor.lo: common/$(am__dirstamp) \
 	common/$(DEPDIR)/$(am__dirstamp)
 common/fd.lo: common/$(am__dirstamp) common/$(DEPDIR)/$(am__dirstamp)
+common/fs_types.lo: common/$(am__dirstamp) \
+	common/$(DEPDIR)/$(am__dirstamp)
 common/safe_io.lo: common/$(am__dirstamp) \
 	common/$(DEPDIR)/$(am__dirstamp)
 common/snap_types.lo: common/$(am__dirstamp) \
@@ -12989,6 +13531,10 @@ common/TracepointProvider.lo: common/$(am__dirstamp) \
 	common/$(DEPDIR)/$(am__dirstamp)
 common/PluginRegistry.lo: common/$(am__dirstamp) \
 	common/$(DEPDIR)/$(am__dirstamp)
+common/scrub_types.lo: common/$(am__dirstamp) \
+	common/$(DEPDIR)/$(am__dirstamp)
+common/blkdev.lo: common/$(am__dirstamp) \
+	common/$(DEPDIR)/$(am__dirstamp)
 common/xattr.lo: common/$(am__dirstamp) \
 	common/$(DEPDIR)/$(am__dirstamp)
 common/ipaddr.lo: common/$(am__dirstamp) \
@@ -13003,8 +13549,6 @@ common/solaris_errno.lo: common/$(am__dirstamp) \
 	common/$(DEPDIR)/$(am__dirstamp)
 common/aix_errno.lo: common/$(am__dirstamp) \
 	common/$(DEPDIR)/$(am__dirstamp)
-common/blkdev.lo: common/$(am__dirstamp) \
-	common/$(DEPDIR)/$(am__dirstamp)
 common/address_helper.lo: common/$(am__dirstamp) \
 	common/$(DEPDIR)/$(am__dirstamp)
 mon/MonCap.lo: mon/$(am__dirstamp) mon/$(DEPDIR)/$(am__dirstamp)
@@ -13021,6 +13565,7 @@ mds/$(DEPDIR)/$(am__dirstamp):
 	@$(MKDIR_P) mds/$(DEPDIR)
 	@: > mds/$(DEPDIR)/$(am__dirstamp)
 mds/MDSMap.lo: mds/$(am__dirstamp) mds/$(DEPDIR)/$(am__dirstamp)
+mds/FSMap.lo: mds/$(am__dirstamp) mds/$(DEPDIR)/$(am__dirstamp)
 mds/inode_backtrace.lo: mds/$(am__dirstamp) \
 	mds/$(DEPDIR)/$(am__dirstamp)
 mds/mdstypes.lo: mds/$(am__dirstamp) mds/$(DEPDIR)/$(am__dirstamp)
@@ -14007,6 +14552,7 @@ mds/MDBalancer.lo: mds/$(am__dirstamp) mds/$(DEPDIR)/$(am__dirstamp)
 mds/CDentry.lo: mds/$(am__dirstamp) mds/$(DEPDIR)/$(am__dirstamp)
 mds/CDir.lo: mds/$(am__dirstamp) mds/$(DEPDIR)/$(am__dirstamp)
 mds/CInode.lo: mds/$(am__dirstamp) mds/$(DEPDIR)/$(am__dirstamp)
+mds/DamageTable.lo: mds/$(am__dirstamp) mds/$(DEPDIR)/$(am__dirstamp)
 mds/LogEvent.lo: mds/$(am__dirstamp) mds/$(DEPDIR)/$(am__dirstamp)
 mds/MDSTable.lo: mds/$(am__dirstamp) mds/$(DEPDIR)/$(am__dirstamp)
 mds/InoTable.lo: mds/$(am__dirstamp) mds/$(DEPDIR)/$(am__dirstamp)
@@ -14351,6 +14897,18 @@ librbd/image/RefreshRequest.lo: librbd/image/$(am__dirstamp) \
 	librbd/image/$(DEPDIR)/$(am__dirstamp)
 librbd/image/SetSnapRequest.lo: librbd/image/$(am__dirstamp) \
 	librbd/image/$(DEPDIR)/$(am__dirstamp)
+librbd/image_watcher/$(am__dirstamp):
+	@$(MKDIR_P) librbd/image_watcher
+	@: > librbd/image_watcher/$(am__dirstamp)
+librbd/image_watcher/$(DEPDIR)/$(am__dirstamp):
+	@$(MKDIR_P) librbd/image_watcher/$(DEPDIR)
+	@: > librbd/image_watcher/$(DEPDIR)/$(am__dirstamp)
+librbd/image_watcher/Notifier.lo:  \
+	librbd/image_watcher/$(am__dirstamp) \
+	librbd/image_watcher/$(DEPDIR)/$(am__dirstamp)
+librbd/image_watcher/NotifyLockOwner.lo:  \
+	librbd/image_watcher/$(am__dirstamp) \
+	librbd/image_watcher/$(DEPDIR)/$(am__dirstamp)
 librbd/journal/$(am__dirstamp):
 	@$(MKDIR_P) librbd/journal
 	@: > librbd/journal/$(am__dirstamp)
@@ -14440,14 +14998,54 @@ tools/rbd_mirror/ClusterWatcher.lo: tools/rbd_mirror/$(am__dirstamp) \
 	tools/rbd_mirror/$(DEPDIR)/$(am__dirstamp)
 tools/rbd_mirror/ImageReplayer.lo: tools/rbd_mirror/$(am__dirstamp) \
 	tools/rbd_mirror/$(DEPDIR)/$(am__dirstamp)
+tools/rbd_mirror/ImageSync.lo: tools/rbd_mirror/$(am__dirstamp) \
+	tools/rbd_mirror/$(DEPDIR)/$(am__dirstamp)
 tools/rbd_mirror/Mirror.lo: tools/rbd_mirror/$(am__dirstamp) \
 	tools/rbd_mirror/$(DEPDIR)/$(am__dirstamp)
 tools/rbd_mirror/PoolWatcher.lo: tools/rbd_mirror/$(am__dirstamp) \
 	tools/rbd_mirror/$(DEPDIR)/$(am__dirstamp)
 tools/rbd_mirror/Replayer.lo: tools/rbd_mirror/$(am__dirstamp) \
 	tools/rbd_mirror/$(DEPDIR)/$(am__dirstamp)
+tools/rbd_mirror/Threads.lo: tools/rbd_mirror/$(am__dirstamp) \
+	tools/rbd_mirror/$(DEPDIR)/$(am__dirstamp)
 tools/rbd_mirror/types.lo: tools/rbd_mirror/$(am__dirstamp) \
 	tools/rbd_mirror/$(DEPDIR)/$(am__dirstamp)
+tools/rbd_mirror/image_replayer/$(am__dirstamp):
+	@$(MKDIR_P) tools/rbd_mirror/image_replayer
+	@: > tools/rbd_mirror/image_replayer/$(am__dirstamp)
+tools/rbd_mirror/image_replayer/$(DEPDIR)/$(am__dirstamp):
+	@$(MKDIR_P) tools/rbd_mirror/image_replayer/$(DEPDIR)
+	@: > tools/rbd_mirror/image_replayer/$(DEPDIR)/$(am__dirstamp)
+tools/rbd_mirror/image_replayer/BootstrapRequest.lo:  \
+	tools/rbd_mirror/image_replayer/$(am__dirstamp) \
+	tools/rbd_mirror/image_replayer/$(DEPDIR)/$(am__dirstamp)
+tools/rbd_mirror/image_replayer/CloseImageRequest.lo:  \
+	tools/rbd_mirror/image_replayer/$(am__dirstamp) \
+	tools/rbd_mirror/image_replayer/$(DEPDIR)/$(am__dirstamp)
+tools/rbd_mirror/image_replayer/OpenLocalImageRequest.lo:  \
+	tools/rbd_mirror/image_replayer/$(am__dirstamp) \
+	tools/rbd_mirror/image_replayer/$(DEPDIR)/$(am__dirstamp)
+tools/rbd_mirror/image_sync/$(am__dirstamp):
+	@$(MKDIR_P) tools/rbd_mirror/image_sync
+	@: > tools/rbd_mirror/image_sync/$(am__dirstamp)
+tools/rbd_mirror/image_sync/$(DEPDIR)/$(am__dirstamp):
+	@$(MKDIR_P) tools/rbd_mirror/image_sync/$(DEPDIR)
+	@: > tools/rbd_mirror/image_sync/$(DEPDIR)/$(am__dirstamp)
+tools/rbd_mirror/image_sync/ImageCopyRequest.lo:  \
+	tools/rbd_mirror/image_sync/$(am__dirstamp) \
+	tools/rbd_mirror/image_sync/$(DEPDIR)/$(am__dirstamp)
+tools/rbd_mirror/image_sync/ObjectCopyRequest.lo:  \
+	tools/rbd_mirror/image_sync/$(am__dirstamp) \
+	tools/rbd_mirror/image_sync/$(DEPDIR)/$(am__dirstamp)
+tools/rbd_mirror/image_sync/SnapshotCopyRequest.lo:  \
+	tools/rbd_mirror/image_sync/$(am__dirstamp) \
+	tools/rbd_mirror/image_sync/$(DEPDIR)/$(am__dirstamp)
+tools/rbd_mirror/image_sync/SyncPointCreateRequest.lo:  \
+	tools/rbd_mirror/image_sync/$(am__dirstamp) \
+	tools/rbd_mirror/image_sync/$(DEPDIR)/$(am__dirstamp)
+tools/rbd_mirror/image_sync/SyncPointPruneRequest.lo:  \
+	tools/rbd_mirror/image_sync/$(am__dirstamp) \
+	tools/rbd_mirror/image_sync/$(DEPDIR)/$(am__dirstamp)
 
 librbd_mirror_internal.la: $(librbd_mirror_internal_la_OBJECTS) $(librbd_mirror_internal_la_DEPENDENCIES) $(EXTRA_librbd_mirror_internal_la_DEPENDENCIES) 
 	$(AM_V_CXXLD)$(CXXLINK) $(am_librbd_mirror_internal_la_rpath) $(librbd_mirror_internal_la_OBJECTS) $(librbd_mirror_internal_la_LIBADD) $(LIBS)
@@ -14463,6 +15061,15 @@ test/rbd_mirror/librbd_mirror_test_la-test_ClusterWatcher.lo:  \
 test/rbd_mirror/librbd_mirror_test_la-test_PoolWatcher.lo:  \
 	test/rbd_mirror/$(am__dirstamp) \
 	test/rbd_mirror/$(DEPDIR)/$(am__dirstamp)
+test/rbd_mirror/librbd_mirror_test_la-test_ImageReplayer.lo:  \
+	test/rbd_mirror/$(am__dirstamp) \
+	test/rbd_mirror/$(DEPDIR)/$(am__dirstamp)
+test/rbd_mirror/librbd_mirror_test_la-test_ImageSync.lo:  \
+	test/rbd_mirror/$(am__dirstamp) \
+	test/rbd_mirror/$(DEPDIR)/$(am__dirstamp)
+test/rbd_mirror/librbd_mirror_test_la-test_fixture.lo:  \
+	test/rbd_mirror/$(am__dirstamp) \
+	test/rbd_mirror/$(DEPDIR)/$(am__dirstamp)
 
 librbd_mirror_test.la: $(librbd_mirror_test_la_OBJECTS) $(librbd_mirror_test_la_DEPENDENCIES) $(EXTRA_librbd_mirror_test_la_DEPENDENCIES) 
 	$(AM_V_CXXLD)$(librbd_mirror_test_la_LINK) $(am_librbd_mirror_test_la_rpath) $(librbd_mirror_test_la_OBJECTS) $(librbd_mirror_test_la_LIBADD) $(LIBS)
@@ -14518,6 +15125,9 @@ test/librbd/librbd_test_la-test_ImageWatcher.lo:  \
 test/librbd/librbd_test_la-test_internal.lo:  \
 	test/librbd/$(am__dirstamp) \
 	test/librbd/$(DEPDIR)/$(am__dirstamp)
+test/librbd/librbd_test_la-test_mirroring.lo:  \
+	test/librbd/$(am__dirstamp) \
+	test/librbd/$(DEPDIR)/$(am__dirstamp)
 test/librbd/librbd_test_la-test_ObjectMap.lo:  \
 	test/librbd/$(am__dirstamp) \
 	test/librbd/$(DEPDIR)/$(am__dirstamp)
@@ -14548,82 +15158,144 @@ librbd/WatchNotifyTypes.lo: librbd/$(am__dirstamp) \
 
 librbd_types.la: $(librbd_types_la_OBJECTS) $(librbd_types_la_DEPENDENCIES) $(EXTRA_librbd_types_la_DEPENDENCIES) 
 	$(AM_V_CXXLD)$(CXXLINK)  $(librbd_types_la_OBJECTS) $(librbd_types_la_LIBADD) $(LIBS)
-rgw/librgw_la-librgw.lo: rgw/$(am__dirstamp) \
-	rgw/$(DEPDIR)/$(am__dirstamp)
 rgw/librgw_la-rgw_acl.lo: rgw/$(am__dirstamp) \
 	rgw/$(DEPDIR)/$(am__dirstamp)
 rgw/librgw_la-rgw_acl_s3.lo: rgw/$(am__dirstamp) \
 	rgw/$(DEPDIR)/$(am__dirstamp)
 rgw/librgw_la-rgw_acl_swift.lo: rgw/$(am__dirstamp) \
 	rgw/$(DEPDIR)/$(am__dirstamp)
+rgw/librgw_la-rgw_coroutine.lo: rgw/$(am__dirstamp) \
+	rgw/$(DEPDIR)/$(am__dirstamp)
+rgw/librgw_la-rgw_cr_rados.lo: rgw/$(am__dirstamp) \
+	rgw/$(DEPDIR)/$(am__dirstamp)
+rgw/librgw_la-rgw_tools.lo: rgw/$(am__dirstamp) \
+	rgw/$(DEPDIR)/$(am__dirstamp)
+rgw/librgw_la-rgw_basic_types.lo: rgw/$(am__dirstamp) \
+	rgw/$(DEPDIR)/$(am__dirstamp)
+rgw/librgw_la-rgw_bucket.lo: rgw/$(am__dirstamp) \
+	rgw/$(DEPDIR)/$(am__dirstamp)
+rgw/librgw_la-rgw_cache.lo: rgw/$(am__dirstamp) \
+	rgw/$(DEPDIR)/$(am__dirstamp)
 rgw/librgw_la-rgw_client_io.lo: rgw/$(am__dirstamp) \
 	rgw/$(DEPDIR)/$(am__dirstamp)
+rgw/librgw_la-rgw_common.lo: rgw/$(am__dirstamp) \
+	rgw/$(DEPDIR)/$(am__dirstamp)
+rgw/librgw_la-rgw_cors.lo: rgw/$(am__dirstamp) \
+	rgw/$(DEPDIR)/$(am__dirstamp)
+rgw/librgw_la-rgw_cors_s3.lo: rgw/$(am__dirstamp) \
+	rgw/$(DEPDIR)/$(am__dirstamp)
+rgw/librgw_la-rgw_dencoder.lo: rgw/$(am__dirstamp) \
+	rgw/$(DEPDIR)/$(am__dirstamp)
+rgw/librgw_la-rgw_env.lo: rgw/$(am__dirstamp) \
+	rgw/$(DEPDIR)/$(am__dirstamp)
 rgw/librgw_la-rgw_fcgi.lo: rgw/$(am__dirstamp) \
 	rgw/$(DEPDIR)/$(am__dirstamp)
-rgw/librgw_la-rgw_xml.lo: rgw/$(am__dirstamp) \
+rgw/librgw_la-rgw_formats.lo: rgw/$(am__dirstamp) \
 	rgw/$(DEPDIR)/$(am__dirstamp)
-rgw/librgw_la-rgw_usage.lo: rgw/$(am__dirstamp) \
+rgw/librgw_la-rgw_frontend.lo: rgw/$(am__dirstamp) \
+	rgw/$(DEPDIR)/$(am__dirstamp)
+rgw/librgw_la-rgw_gc.lo: rgw/$(am__dirstamp) \
+	rgw/$(DEPDIR)/$(am__dirstamp)
+rgw/librgw_la-rgw_http_client.lo: rgw/$(am__dirstamp) \
 	rgw/$(DEPDIR)/$(am__dirstamp)
 rgw/librgw_la-rgw_json_enc.lo: rgw/$(am__dirstamp) \
 	rgw/$(DEPDIR)/$(am__dirstamp)
-rgw/librgw_la-rgw_xml_enc.lo: rgw/$(am__dirstamp) \
+rgw/librgw_la-rgw_keystone.lo: rgw/$(am__dirstamp) \
 	rgw/$(DEPDIR)/$(am__dirstamp)
-rgw/librgw_la-rgw_user.lo: rgw/$(am__dirstamp) \
+rgw/librgw_la-rgw_loadgen.lo: rgw/$(am__dirstamp) \
 	rgw/$(DEPDIR)/$(am__dirstamp)
-rgw/librgw_la-rgw_bucket.lo: rgw/$(am__dirstamp) \
+rgw/librgw_la-rgw_log.lo: rgw/$(am__dirstamp) \
 	rgw/$(DEPDIR)/$(am__dirstamp)
-rgw/librgw_la-rgw_tools.lo: rgw/$(am__dirstamp) \
+rgw/librgw_la-rgw_metadata.lo: rgw/$(am__dirstamp) \
 	rgw/$(DEPDIR)/$(am__dirstamp)
-rgw/librgw_la-rgw_rados.lo: rgw/$(am__dirstamp) \
+rgw/librgw_la-rgw_multi.lo: rgw/$(am__dirstamp) \
 	rgw/$(DEPDIR)/$(am__dirstamp)
-rgw/librgw_la-rgw_http_client.lo: rgw/$(am__dirstamp) \
+rgw/librgw_la-rgw_multi_del.lo: rgw/$(am__dirstamp) \
 	rgw/$(DEPDIR)/$(am__dirstamp)
-rgw/librgw_la-rgw_rest_client.lo: rgw/$(am__dirstamp) \
+rgw/librgw_la-rgw_auth_s3.lo: rgw/$(am__dirstamp) \
 	rgw/$(DEPDIR)/$(am__dirstamp)
-rgw/librgw_la-rgw_rest_conn.lo: rgw/$(am__dirstamp) \
+rgw/librgw_la-rgw_period_history.lo: rgw/$(am__dirstamp) \
 	rgw/$(DEPDIR)/$(am__dirstamp)
-rgw/librgw_la-rgw_op.lo: rgw/$(am__dirstamp) \
+rgw/librgw_la-rgw_period_puller.lo: rgw/$(am__dirstamp) \
 	rgw/$(DEPDIR)/$(am__dirstamp)
-rgw/librgw_la-rgw_basic_types.lo: rgw/$(am__dirstamp) \
+rgw/librgw_la-rgw_period_pusher.lo: rgw/$(am__dirstamp) \
 	rgw/$(DEPDIR)/$(am__dirstamp)
-rgw/librgw_la-rgw_common.lo: rgw/$(am__dirstamp) \
+rgw/librgw_la-rgw_realm_reloader.lo: rgw/$(am__dirstamp) \
 	rgw/$(DEPDIR)/$(am__dirstamp)
-rgw/librgw_la-rgw_cache.lo: rgw/$(am__dirstamp) \
+rgw/librgw_la-rgw_realm_watcher.lo: rgw/$(am__dirstamp) \
 	rgw/$(DEPDIR)/$(am__dirstamp)
-rgw/librgw_la-rgw_formats.lo: rgw/$(am__dirstamp) \
+rgw/librgw_la-rgw_sync.lo: rgw/$(am__dirstamp) \
 	rgw/$(DEPDIR)/$(am__dirstamp)
-rgw/librgw_la-rgw_log.lo: rgw/$(am__dirstamp) \
+rgw/librgw_la-rgw_data_sync.lo: rgw/$(am__dirstamp) \
 	rgw/$(DEPDIR)/$(am__dirstamp)
-rgw/librgw_la-rgw_multi.lo: rgw/$(am__dirstamp) \
+rgw/librgw_la-rgw_object_expirer_core.lo: rgw/$(am__dirstamp) \
+	rgw/$(DEPDIR)/$(am__dirstamp)
+rgw/librgw_la-rgw_op.lo: rgw/$(am__dirstamp) \
+	rgw/$(DEPDIR)/$(am__dirstamp)
+rgw/librgw_la-rgw_os_lib.lo: rgw/$(am__dirstamp) \
 	rgw/$(DEPDIR)/$(am__dirstamp)
 rgw/librgw_la-rgw_policy_s3.lo: rgw/$(am__dirstamp) \
 	rgw/$(DEPDIR)/$(am__dirstamp)
-rgw/librgw_la-rgw_gc.lo: rgw/$(am__dirstamp) \
+rgw/librgw_la-rgw_process.lo: rgw/$(am__dirstamp) \
 	rgw/$(DEPDIR)/$(am__dirstamp)
-rgw/librgw_la-rgw_multi_del.lo: rgw/$(am__dirstamp) \
+rgw/librgw_la-rgw_quota.lo: rgw/$(am__dirstamp) \
 	rgw/$(DEPDIR)/$(am__dirstamp)
-rgw/librgw_la-rgw_env.lo: rgw/$(am__dirstamp) \
+rgw/librgw_la-rgw_rados.lo: rgw/$(am__dirstamp) \
 	rgw/$(DEPDIR)/$(am__dirstamp)
-rgw/librgw_la-rgw_cors.lo: rgw/$(am__dirstamp) \
+rgw/librgw_la-rgw_replica_log.lo: rgw/$(am__dirstamp) \
 	rgw/$(DEPDIR)/$(am__dirstamp)
-rgw/librgw_la-rgw_cors_s3.lo: rgw/$(am__dirstamp) \
+rgw/librgw_la-rgw_request.lo: rgw/$(am__dirstamp) \
 	rgw/$(DEPDIR)/$(am__dirstamp)
-rgw/librgw_la-rgw_auth_s3.lo: rgw/$(am__dirstamp) \
+rgw/librgw_la-rgw_resolve.lo: rgw/$(am__dirstamp) \
 	rgw/$(DEPDIR)/$(am__dirstamp)
-rgw/librgw_la-rgw_metadata.lo: rgw/$(am__dirstamp) \
+rgw/librgw_la-rgw_rest_bucket.lo: rgw/$(am__dirstamp) \
 	rgw/$(DEPDIR)/$(am__dirstamp)
-rgw/librgw_la-rgw_replica_log.lo: rgw/$(am__dirstamp) \
+rgw/librgw_la-rgw_rest.lo: rgw/$(am__dirstamp) \
 	rgw/$(DEPDIR)/$(am__dirstamp)
-rgw/librgw_la-rgw_keystone.lo: rgw/$(am__dirstamp) \
+rgw/librgw_la-rgw_rest_client.lo: rgw/$(am__dirstamp) \
 	rgw/$(DEPDIR)/$(am__dirstamp)
-rgw/librgw_la-rgw_quota.lo: rgw/$(am__dirstamp) \
+rgw/librgw_la-rgw_rest_config.lo: rgw/$(am__dirstamp) \
 	rgw/$(DEPDIR)/$(am__dirstamp)
-rgw/librgw_la-rgw_dencoder.lo: rgw/$(am__dirstamp) \
+rgw/librgw_la-rgw_rest_conn.lo: rgw/$(am__dirstamp) \
 	rgw/$(DEPDIR)/$(am__dirstamp)
-rgw/librgw_la-rgw_object_expirer_core.lo: rgw/$(am__dirstamp) \
+rgw/librgw_la-rgw_rest_log.lo: rgw/$(am__dirstamp) \
+	rgw/$(DEPDIR)/$(am__dirstamp)
+rgw/librgw_la-rgw_rest_metadata.lo: rgw/$(am__dirstamp) \
+	rgw/$(DEPDIR)/$(am__dirstamp)
+rgw/librgw_la-rgw_rest_opstate.lo: rgw/$(am__dirstamp) \
+	rgw/$(DEPDIR)/$(am__dirstamp)
+rgw/librgw_la-rgw_rest_realm.lo: rgw/$(am__dirstamp) \
+	rgw/$(DEPDIR)/$(am__dirstamp)
+rgw/librgw_la-rgw_rest_replica_log.lo: rgw/$(am__dirstamp) \
+	rgw/$(DEPDIR)/$(am__dirstamp)
+rgw/librgw_la-rgw_rest_s3.lo: rgw/$(am__dirstamp) \
+	rgw/$(DEPDIR)/$(am__dirstamp)
+rgw/librgw_la-rgw_rest_swift.lo: rgw/$(am__dirstamp) \
+	rgw/$(DEPDIR)/$(am__dirstamp)
+rgw/librgw_la-rgw_rest_usage.lo: rgw/$(am__dirstamp) \
+	rgw/$(DEPDIR)/$(am__dirstamp)
+rgw/librgw_la-rgw_rest_user.lo: rgw/$(am__dirstamp) \
+	rgw/$(DEPDIR)/$(am__dirstamp)
+rgw/librgw_la-rgw_swift_auth.lo: rgw/$(am__dirstamp) \
+	rgw/$(DEPDIR)/$(am__dirstamp)
+rgw/librgw_la-rgw_swift.lo: rgw/$(am__dirstamp) \
+	rgw/$(DEPDIR)/$(am__dirstamp)
+rgw/librgw_la-rgw_usage.lo: rgw/$(am__dirstamp) \
+	rgw/$(DEPDIR)/$(am__dirstamp)
+rgw/librgw_la-rgw_user.lo: rgw/$(am__dirstamp) \
+	rgw/$(DEPDIR)/$(am__dirstamp)
+rgw/librgw_la-rgw_file.lo: rgw/$(am__dirstamp) \
+	rgw/$(DEPDIR)/$(am__dirstamp)
+rgw/librgw_la-librgw.lo: rgw/$(am__dirstamp) \
+	rgw/$(DEPDIR)/$(am__dirstamp)
+rgw/librgw_la-rgw_xml.lo: rgw/$(am__dirstamp) \
+	rgw/$(DEPDIR)/$(am__dirstamp)
+rgw/librgw_la-rgw_xml_enc.lo: rgw/$(am__dirstamp) \
 	rgw/$(DEPDIR)/$(am__dirstamp)
 rgw/librgw_la-rgw_website.lo: rgw/$(am__dirstamp) \
 	rgw/$(DEPDIR)/$(am__dirstamp)
+rgw/librgw_la-rgw_ldap.lo: rgw/$(am__dirstamp) \
+	rgw/$(DEPDIR)/$(am__dirstamp)
 
 librgw.la: $(librgw_la_OBJECTS) $(librgw_la_DEPENDENCIES) $(EXTRA_librgw_la_DEPENDENCIES) 
 	$(AM_V_CXXLD)$(librgw_la_LINK) $(am_librgw_la_rpath) $(librgw_la_OBJECTS) $(librgw_la_LIBADD) $(LIBS)
@@ -14885,6 +15557,8 @@ mds/ceph_dencoder-CDir.$(OBJEXT): mds/$(am__dirstamp) \
 	mds/$(DEPDIR)/$(am__dirstamp)
 mds/ceph_dencoder-CInode.$(OBJEXT): mds/$(am__dirstamp) \
 	mds/$(DEPDIR)/$(am__dirstamp)
+mds/ceph_dencoder-DamageTable.$(OBJEXT): mds/$(am__dirstamp) \
+	mds/$(DEPDIR)/$(am__dirstamp)
 mds/ceph_dencoder-LogEvent.$(OBJEXT): mds/$(am__dirstamp) \
 	mds/$(DEPDIR)/$(am__dirstamp)
 mds/ceph_dencoder-MDSTable.$(OBJEXT): mds/$(am__dirstamp) \
@@ -14931,6 +15605,8 @@ rgw/ceph_dencoder-rgw_env.$(OBJEXT): rgw/$(am__dirstamp) \
 	rgw/$(DEPDIR)/$(am__dirstamp)
 rgw/ceph_dencoder-rgw_json_enc.$(OBJEXT): rgw/$(am__dirstamp) \
 	rgw/$(DEPDIR)/$(am__dirstamp)
+rgw/ceph_dencoder-rgw_keystone.$(OBJEXT): rgw/$(am__dirstamp) \
+	rgw/$(DEPDIR)/$(am__dirstamp)
 
 ceph-dencoder$(EXEEXT): $(ceph_dencoder_OBJECTS) $(ceph_dencoder_DEPENDENCIES) $(EXTRA_ceph_dencoder_DEPENDENCIES) 
 	@rm -f ceph-dencoder$(EXEEXT)
@@ -15706,6 +16382,25 @@ osd/ceph_test_rados_api_tier-HitSet.$(OBJEXT): osd/$(am__dirstamp) \
 ceph_test_rados_api_tier$(EXEEXT): $(ceph_test_rados_api_tier_OBJECTS) $(ceph_test_rados_api_tier_DEPENDENCIES) $(EXTRA_ceph_test_rados_api_tier_DEPENDENCIES) 
 	@rm -f ceph_test_rados_api_tier$(EXEEXT)
 	$(AM_V_CXXLD)$(ceph_test_rados_api_tier_LINK) $(ceph_test_rados_api_tier_OBJECTS) $(ceph_test_rados_api_tier_LDADD) $(LIBS)
+test/librados/ceph_test_rados_api_tmap_migrate-tmap_migrate.$(OBJEXT):  \
+	test/librados/$(am__dirstamp) \
+	test/librados/$(DEPDIR)/$(am__dirstamp)
+tools/cephfs/$(am__dirstamp):
+	@$(MKDIR_P) tools/cephfs
+	@: > tools/cephfs/$(am__dirstamp)
+tools/cephfs/$(DEPDIR)/$(am__dirstamp):
+	@$(MKDIR_P) tools/cephfs/$(DEPDIR)
+	@: > tools/cephfs/$(DEPDIR)/$(am__dirstamp)
+tools/cephfs/ceph_test_rados_api_tmap_migrate-DataScan.$(OBJEXT):  \
+	tools/cephfs/$(am__dirstamp) \
+	tools/cephfs/$(DEPDIR)/$(am__dirstamp)
+tools/cephfs/ceph_test_rados_api_tmap_migrate-MDSUtility.$(OBJEXT):  \
+	tools/cephfs/$(am__dirstamp) \
+	tools/cephfs/$(DEPDIR)/$(am__dirstamp)
+
+ceph_test_rados_api_tmap_migrate$(EXEEXT): $(ceph_test_rados_api_tmap_migrate_OBJECTS) $(ceph_test_rados_api_tmap_migrate_DEPENDENCIES) $(EXTRA_ceph_test_rados_api_tmap_migrate_DEPENDENCIES) 
+	@rm -f ceph_test_rados_api_tmap_migrate$(EXEEXT)
+	$(AM_V_CXXLD)$(ceph_test_rados_api_tmap_migrate_LINK) $(ceph_test_rados_api_tmap_migrate_OBJECTS) $(ceph_test_rados_api_tmap_migrate_LDADD) $(LIBS)
 test/librados/ceph_test_rados_api_watch_notify-watch_notify.$(OBJEXT):  \
 	test/librados/$(am__dirstamp) \
 	test/librados/$(DEPDIR)/$(am__dirstamp)
@@ -15784,6 +16479,13 @@ test/rbd_mirror/ceph_test_rbd_mirror-test_main.$(OBJEXT):  \
 ceph_test_rbd_mirror$(EXEEXT): $(ceph_test_rbd_mirror_OBJECTS) $(ceph_test_rbd_mirror_DEPENDENCIES) $(EXTRA_ceph_test_rbd_mirror_DEPENDENCIES) 
 	@rm -f ceph_test_rbd_mirror$(EXEEXT)
 	$(AM_V_CXXLD)$(ceph_test_rbd_mirror_LINK) $(ceph_test_rbd_mirror_OBJECTS) $(ceph_test_rbd_mirror_LDADD) $(LIBS)
+test/rbd_mirror/image_replay.$(OBJEXT):  \
+	test/rbd_mirror/$(am__dirstamp) \
+	test/rbd_mirror/$(DEPDIR)/$(am__dirstamp)
+
+ceph_test_rbd_mirror_image_replay$(EXEEXT): $(ceph_test_rbd_mirror_image_replay_OBJECTS) $(ceph_test_rbd_mirror_image_replay_DEPENDENCIES) $(EXTRA_ceph_test_rbd_mirror_image_replay_DEPENDENCIES) 
+	@rm -f ceph_test_rbd_mirror_image_replay$(EXEEXT)
+	$(AM_V_CXXLD)$(CXXLINK) $(ceph_test_rbd_mirror_image_replay_OBJECTS) $(ceph_test_rbd_mirror_image_replay_LDADD) $(LIBS)
 test/test_rewrite_latency.$(OBJEXT): test/$(am__dirstamp) \
 	test/$(DEPDIR)/$(am__dirstamp)
 
@@ -15808,6 +16510,12 @@ test/rgw/ceph_test_rgw_obj-test_rgw_obj.$(OBJEXT):  \
 ceph_test_rgw_obj$(EXEEXT): $(ceph_test_rgw_obj_OBJECTS) $(ceph_test_rgw_obj_DEPENDENCIES) $(EXTRA_ceph_test_rgw_obj_DEPENDENCIES) 
 	@rm -f ceph_test_rgw_obj$(EXEEXT)
 	$(AM_V_CXXLD)$(ceph_test_rgw_obj_LINK) $(ceph_test_rgw_obj_OBJECTS) $(ceph_test_rgw_obj_LDADD) $(LIBS)
+test/rgw/ceph_test_rgw_period_history-test_rgw_period_history.$(OBJEXT):  \
+	test/rgw/$(am__dirstamp) test/rgw/$(DEPDIR)/$(am__dirstamp)
+
+ceph_test_rgw_period_history$(EXEEXT): $(ceph_test_rgw_period_history_OBJECTS) $(ceph_test_rgw_period_history_DEPENDENCIES) $(EXTRA_ceph_test_rgw_period_history_DEPENDENCIES) 
+	@rm -f ceph_test_rgw_period_history$(EXEEXT)
+	$(AM_V_CXXLD)$(ceph_test_rgw_period_history_LINK) $(ceph_test_rgw_period_history_OBJECTS) $(ceph_test_rgw_period_history_LDADD) $(LIBS)
 test/TestSignalHandlers.$(OBJEXT): test/$(am__dirstamp) \
 	test/$(DEPDIR)/$(am__dirstamp)
 
@@ -15854,16 +16562,12 @@ ceph_xattr_bench$(EXEEXT): $(ceph_xattr_bench_OBJECTS) $(ceph_xattr_bench_DEPEND
 cephfs$(EXEEXT): $(cephfs_OBJECTS) $(cephfs_DEPENDENCIES) $(EXTRA_cephfs_DEPENDENCIES) 
 	@rm -f cephfs$(EXEEXT)
 	$(AM_V_CXXLD)$(CXXLINK) $(cephfs_OBJECTS) $(cephfs_LDADD) $(LIBS)
-tools/cephfs/$(am__dirstamp):
-	@$(MKDIR_P) tools/cephfs
-	@: > tools/cephfs/$(am__dirstamp)
-tools/cephfs/$(DEPDIR)/$(am__dirstamp):
-	@$(MKDIR_P) tools/cephfs/$(DEPDIR)
-	@: > tools/cephfs/$(DEPDIR)/$(am__dirstamp)
 tools/cephfs/cephfs-data-scan.$(OBJEXT): tools/cephfs/$(am__dirstamp) \
 	tools/cephfs/$(DEPDIR)/$(am__dirstamp)
 tools/cephfs/DataScan.$(OBJEXT): tools/cephfs/$(am__dirstamp) \
 	tools/cephfs/$(DEPDIR)/$(am__dirstamp)
+tools/cephfs/RoleSelector.$(OBJEXT): tools/cephfs/$(am__dirstamp) \
+	tools/cephfs/$(DEPDIR)/$(am__dirstamp)
 tools/cephfs/MDSUtility.$(OBJEXT): tools/cephfs/$(am__dirstamp) \
 	tools/cephfs/$(DEPDIR)/$(am__dirstamp)
 
@@ -15915,6 +16619,36 @@ get_command_descriptions$(EXEEXT): $(get_command_descriptions_OBJECTS) $(get_com
 librados-config$(EXEEXT): $(librados_config_OBJECTS) $(librados_config_DEPENDENCIES) $(EXTRA_librados_config_DEPENDENCIES) 
 	@rm -f librados-config$(EXEEXT)
 	$(AM_V_CXXLD)$(CXXLINK) $(librados_config_OBJECTS) $(librados_config_LDADD) $(LIBS)
+test/librgw_file-librgw_file.$(OBJEXT): test/$(am__dirstamp) \
+	test/$(DEPDIR)/$(am__dirstamp)
+
+librgw_file$(EXEEXT): $(librgw_file_OBJECTS) $(librgw_file_DEPENDENCIES) $(EXTRA_librgw_file_DEPENDENCIES) 
+	@rm -f librgw_file$(EXEEXT)
+	$(AM_V_CXXLD)$(librgw_file_LINK) $(librgw_file_OBJECTS) $(librgw_file_LDADD) $(LIBS)
+test/librgw_file_aw-librgw_file_aw.$(OBJEXT): test/$(am__dirstamp) \
+	test/$(DEPDIR)/$(am__dirstamp)
+
+librgw_file_aw$(EXEEXT): $(librgw_file_aw_OBJECTS) $(librgw_file_aw_DEPENDENCIES) $(EXTRA_librgw_file_aw_DEPENDENCIES) 
+	@rm -f librgw_file_aw$(EXEEXT)
+	$(AM_V_CXXLD)$(librgw_file_aw_LINK) $(librgw_file_aw_OBJECTS) $(librgw_file_aw_LDADD) $(LIBS)
+test/librgw_file_cd-librgw_file_cd.$(OBJEXT): test/$(am__dirstamp) \
+	test/$(DEPDIR)/$(am__dirstamp)
+
+librgw_file_cd$(EXEEXT): $(librgw_file_cd_OBJECTS) $(librgw_file_cd_DEPENDENCIES) $(EXTRA_librgw_file_cd_DEPENDENCIES) 
+	@rm -f librgw_file_cd$(EXEEXT)
+	$(AM_V_CXXLD)$(librgw_file_cd_LINK) $(librgw_file_cd_OBJECTS) $(librgw_file_cd_LDADD) $(LIBS)
+test/librgw_file_gp-librgw_file_gp.$(OBJEXT): test/$(am__dirstamp) \
+	test/$(DEPDIR)/$(am__dirstamp)
+
+librgw_file_gp$(EXEEXT): $(librgw_file_gp_OBJECTS) $(librgw_file_gp_DEPENDENCIES) $(EXTRA_librgw_file_gp_DEPENDENCIES) 
+	@rm -f librgw_file_gp$(EXEEXT)
+	$(AM_V_CXXLD)$(librgw_file_gp_LINK) $(librgw_file_gp_OBJECTS) $(librgw_file_gp_LDADD) $(LIBS)
+test/librgw_file_nfsns-librgw_file_nfsns.$(OBJEXT):  \
+	test/$(am__dirstamp) test/$(DEPDIR)/$(am__dirstamp)
+
+librgw_file_nfsns$(EXEEXT): $(librgw_file_nfsns_OBJECTS) $(librgw_file_nfsns_DEPENDENCIES) $(EXTRA_librgw_file_nfsns_DEPENDENCIES) 
+	@rm -f librgw_file_nfsns$(EXEEXT)
+	$(AM_V_CXXLD)$(librgw_file_nfsns_LINK) $(librgw_file_nfsns_OBJECTS) $(librgw_file_nfsns_LDADD) $(LIBS)
 tools/monmaptool.$(OBJEXT): tools/$(am__dirstamp) \
 	tools/$(DEPDIR)/$(am__dirstamp)
 
@@ -15957,41 +16691,19 @@ common/obj_bencher.$(OBJEXT): common/$(am__dirstamp) \
 rados$(EXEEXT): $(rados_OBJECTS) $(rados_DEPENDENCIES) $(EXTRA_rados_DEPENDENCIES) 
 	@rm -f rados$(EXEEXT)
 	$(AM_V_CXXLD)$(CXXLINK) $(rados_OBJECTS) $(rados_LDADD) $(LIBS)
-rgw/rgw_resolve.$(OBJEXT): rgw/$(am__dirstamp) \
+rgw/rgw_fcgi_process.$(OBJEXT): rgw/$(am__dirstamp) \
 	rgw/$(DEPDIR)/$(am__dirstamp)
-rgw/rgw_rest.$(OBJEXT): rgw/$(am__dirstamp) \
+rgw/rgw_loadgen_process.$(OBJEXT): rgw/$(am__dirstamp) \
 	rgw/$(DEPDIR)/$(am__dirstamp)
-rgw/rgw_rest_swift.$(OBJEXT): rgw/$(am__dirstamp) \
+rgw/rgw_civetweb.$(OBJEXT): rgw/$(am__dirstamp) \
 	rgw/$(DEPDIR)/$(am__dirstamp)
-rgw/rgw_rest_s3.$(OBJEXT): rgw/$(am__dirstamp) \
+rgw/rgw_civetweb_frontend.$(OBJEXT): rgw/$(am__dirstamp) \
 	rgw/$(DEPDIR)/$(am__dirstamp)
-rgw/rgw_rest_usage.$(OBJEXT): rgw/$(am__dirstamp) \
+rgw/rgw_civetweb_log.$(OBJEXT): rgw/$(am__dirstamp) \
 	rgw/$(DEPDIR)/$(am__dirstamp)
-rgw/rgw_rest_user.$(OBJEXT): rgw/$(am__dirstamp) \
-	rgw/$(DEPDIR)/$(am__dirstamp)
-rgw/rgw_rest_bucket.$(OBJEXT): rgw/$(am__dirstamp) \
-	rgw/$(DEPDIR)/$(am__dirstamp)
-rgw/rgw_rest_metadata.$(OBJEXT): rgw/$(am__dirstamp) \
-	rgw/$(DEPDIR)/$(am__dirstamp)
-rgw/rgw_replica_log.$(OBJEXT): rgw/$(am__dirstamp) \
-	rgw/$(DEPDIR)/$(am__dirstamp)
-rgw/rgw_rest_log.$(OBJEXT): rgw/$(am__dirstamp) \
-	rgw/$(DEPDIR)/$(am__dirstamp)
-rgw/rgw_rest_opstate.$(OBJEXT): rgw/$(am__dirstamp) \
-	rgw/$(DEPDIR)/$(am__dirstamp)
-rgw/rgw_rest_replica_log.$(OBJEXT): rgw/$(am__dirstamp) \
-	rgw/$(DEPDIR)/$(am__dirstamp)
-rgw/rgw_rest_config.$(OBJEXT): rgw/$(am__dirstamp) \
-	rgw/$(DEPDIR)/$(am__dirstamp)
-rgw/rgw_http_client.$(OBJEXT): rgw/$(am__dirstamp) \
-	rgw/$(DEPDIR)/$(am__dirstamp)
-rgw/rgw_swift.$(OBJEXT): rgw/$(am__dirstamp) \
-	rgw/$(DEPDIR)/$(am__dirstamp)
-rgw/rgw_swift_auth.$(OBJEXT): rgw/$(am__dirstamp) \
-	rgw/$(DEPDIR)/$(am__dirstamp)
-rgw/rgw_loadgen.$(OBJEXT): rgw/$(am__dirstamp) \
-	rgw/$(DEPDIR)/$(am__dirstamp)
-rgw/rgw_main.$(OBJEXT): rgw/$(am__dirstamp) \
+civetweb/src/radosgw-civetweb.$(OBJEXT): civetweb/src/$(am__dirstamp) \
+	civetweb/src/$(DEPDIR)/$(am__dirstamp)
+rgw/rgw_main.$(OBJEXT): rgw/$(am__dirstamp) \
 	rgw/$(DEPDIR)/$(am__dirstamp)
 
 radosgw$(EXEEXT): $(radosgw_OBJECTS) $(radosgw_DEPENDENCIES) $(EXTRA_radosgw_DEPENDENCIES) 
@@ -16011,6 +16723,12 @@ rgw/rgw_object_expirer.$(OBJEXT): rgw/$(am__dirstamp) \
 radosgw-object-expirer$(EXEEXT): $(radosgw_object_expirer_OBJECTS) $(radosgw_object_expirer_DEPENDENCIES) $(EXTRA_radosgw_object_expirer_DEPENDENCIES) 
 	@rm -f radosgw-object-expirer$(EXEEXT)
 	$(AM_V_CXXLD)$(CXXLINK) $(radosgw_object_expirer_OBJECTS) $(radosgw_object_expirer_LDADD) $(LIBS)
+rgw/rgw_token.$(OBJEXT): rgw/$(am__dirstamp) \
+	rgw/$(DEPDIR)/$(am__dirstamp)
+
+radosgw-token$(EXEEXT): $(radosgw_token_OBJECTS) $(radosgw_token_DEPENDENCIES) $(EXTRA_radosgw_token_DEPENDENCIES) 
+	@rm -f radosgw-token$(EXEEXT)
+	$(AM_V_CXXLD)$(CXXLINK) $(radosgw_token_OBJECTS) $(radosgw_token_LDADD) $(LIBS)
 tools/rbd/$(am__dirstamp):
 	@$(MKDIR_P) tools/rbd
 	@: > tools/rbd/$(am__dirstamp)
@@ -16072,10 +16790,6 @@ tools/rbd/action/Info.$(OBJEXT): tools/rbd/action/$(am__dirstamp) \
 	tools/rbd/action/$(DEPDIR)/$(am__dirstamp)
 tools/rbd/action/Journal.$(OBJEXT): tools/rbd/action/$(am__dirstamp) \
 	tools/rbd/action/$(DEPDIR)/$(am__dirstamp)
-tools/rbd/action/Kernel.$(OBJEXT): tools/rbd/action/$(am__dirstamp) \
-	tools/rbd/action/$(DEPDIR)/$(am__dirstamp)
-tools/rbd/action/Nbd.$(OBJEXT): tools/rbd/action/$(am__dirstamp) \
-	tools/rbd/action/$(DEPDIR)/$(am__dirstamp)
 tools/rbd/action/List.$(OBJEXT): tools/rbd/action/$(am__dirstamp) \
 	tools/rbd/action/$(DEPDIR)/$(am__dirstamp)
 tools/rbd/action/Lock.$(OBJEXT): tools/rbd/action/$(am__dirstamp) \
@@ -16086,6 +16800,9 @@ tools/rbd/action/MergeDiff.$(OBJEXT):  \
 tools/rbd/action/MirrorPool.$(OBJEXT):  \
 	tools/rbd/action/$(am__dirstamp) \
 	tools/rbd/action/$(DEPDIR)/$(am__dirstamp)
+tools/rbd/action/MirrorImage.$(OBJEXT):  \
+	tools/rbd/action/$(am__dirstamp) \
+	tools/rbd/action/$(DEPDIR)/$(am__dirstamp)
 tools/rbd/action/ObjectMap.$(OBJEXT):  \
 	tools/rbd/action/$(am__dirstamp) \
 	tools/rbd/action/$(DEPDIR)/$(am__dirstamp)
@@ -16101,6 +16818,10 @@ tools/rbd/action/Status.$(OBJEXT): tools/rbd/action/$(am__dirstamp) \
 	tools/rbd/action/$(DEPDIR)/$(am__dirstamp)
 tools/rbd/action/Watch.$(OBJEXT): tools/rbd/action/$(am__dirstamp) \
 	tools/rbd/action/$(DEPDIR)/$(am__dirstamp)
+tools/rbd/action/Kernel.$(OBJEXT): tools/rbd/action/$(am__dirstamp) \
+	tools/rbd/action/$(DEPDIR)/$(am__dirstamp)
+tools/rbd/action/Nbd.$(OBJEXT): tools/rbd/action/$(am__dirstamp) \
+	tools/rbd/action/$(DEPDIR)/$(am__dirstamp)
 
 rbd$(EXEEXT): $(rbd_OBJECTS) $(rbd_DEPENDENCIES) $(EXTRA_rbd_DEPENDENCIES) 
 	@rm -f rbd$(EXEEXT)
@@ -16210,82 +16931,144 @@ test_build_librados$(EXEEXT): $(test_build_librados_OBJECTS) $(test_build_librad
 	$(AM_V_CXXLD)$(test_build_librados_LINK) $(test_build_librados_OBJECTS) $(test_build_librados_LDADD) $(LIBS)
 test/test_build_librgw-buildtest_skeleton.$(OBJEXT):  \
 	test/$(am__dirstamp) test/$(DEPDIR)/$(am__dirstamp)
-rgw/test_build_librgw-librgw.$(OBJEXT): rgw/$(am__dirstamp) \
-	rgw/$(DEPDIR)/$(am__dirstamp)
 rgw/test_build_librgw-rgw_acl.$(OBJEXT): rgw/$(am__dirstamp) \
 	rgw/$(DEPDIR)/$(am__dirstamp)
 rgw/test_build_librgw-rgw_acl_s3.$(OBJEXT): rgw/$(am__dirstamp) \
 	rgw/$(DEPDIR)/$(am__dirstamp)
 rgw/test_build_librgw-rgw_acl_swift.$(OBJEXT): rgw/$(am__dirstamp) \
 	rgw/$(DEPDIR)/$(am__dirstamp)
-rgw/test_build_librgw-rgw_client_io.$(OBJEXT): rgw/$(am__dirstamp) \
+rgw/test_build_librgw-rgw_coroutine.$(OBJEXT): rgw/$(am__dirstamp) \
 	rgw/$(DEPDIR)/$(am__dirstamp)
-rgw/test_build_librgw-rgw_fcgi.$(OBJEXT): rgw/$(am__dirstamp) \
+rgw/test_build_librgw-rgw_cr_rados.$(OBJEXT): rgw/$(am__dirstamp) \
 	rgw/$(DEPDIR)/$(am__dirstamp)
-rgw/test_build_librgw-rgw_xml.$(OBJEXT): rgw/$(am__dirstamp) \
+rgw/test_build_librgw-rgw_tools.$(OBJEXT): rgw/$(am__dirstamp) \
 	rgw/$(DEPDIR)/$(am__dirstamp)
-rgw/test_build_librgw-rgw_usage.$(OBJEXT): rgw/$(am__dirstamp) \
+rgw/test_build_librgw-rgw_basic_types.$(OBJEXT): rgw/$(am__dirstamp) \
 	rgw/$(DEPDIR)/$(am__dirstamp)
-rgw/test_build_librgw-rgw_json_enc.$(OBJEXT): rgw/$(am__dirstamp) \
+rgw/test_build_librgw-rgw_bucket.$(OBJEXT): rgw/$(am__dirstamp) \
 	rgw/$(DEPDIR)/$(am__dirstamp)
-rgw/test_build_librgw-rgw_xml_enc.$(OBJEXT): rgw/$(am__dirstamp) \
+rgw/test_build_librgw-rgw_cache.$(OBJEXT): rgw/$(am__dirstamp) \
 	rgw/$(DEPDIR)/$(am__dirstamp)
-rgw/test_build_librgw-rgw_user.$(OBJEXT): rgw/$(am__dirstamp) \
+rgw/test_build_librgw-rgw_client_io.$(OBJEXT): rgw/$(am__dirstamp) \
 	rgw/$(DEPDIR)/$(am__dirstamp)
-rgw/test_build_librgw-rgw_bucket.$(OBJEXT): rgw/$(am__dirstamp) \
+rgw/test_build_librgw-rgw_common.$(OBJEXT): rgw/$(am__dirstamp) \
 	rgw/$(DEPDIR)/$(am__dirstamp)
-rgw/test_build_librgw-rgw_tools.$(OBJEXT): rgw/$(am__dirstamp) \
+rgw/test_build_librgw-rgw_cors.$(OBJEXT): rgw/$(am__dirstamp) \
 	rgw/$(DEPDIR)/$(am__dirstamp)
-rgw/test_build_librgw-rgw_rados.$(OBJEXT): rgw/$(am__dirstamp) \
+rgw/test_build_librgw-rgw_cors_s3.$(OBJEXT): rgw/$(am__dirstamp) \
 	rgw/$(DEPDIR)/$(am__dirstamp)
-rgw/test_build_librgw-rgw_http_client.$(OBJEXT): rgw/$(am__dirstamp) \
+rgw/test_build_librgw-rgw_dencoder.$(OBJEXT): rgw/$(am__dirstamp) \
 	rgw/$(DEPDIR)/$(am__dirstamp)
-rgw/test_build_librgw-rgw_rest_client.$(OBJEXT): rgw/$(am__dirstamp) \
+rgw/test_build_librgw-rgw_env.$(OBJEXT): rgw/$(am__dirstamp) \
 	rgw/$(DEPDIR)/$(am__dirstamp)
-rgw/test_build_librgw-rgw_rest_conn.$(OBJEXT): rgw/$(am__dirstamp) \
+rgw/test_build_librgw-rgw_fcgi.$(OBJEXT): rgw/$(am__dirstamp) \
 	rgw/$(DEPDIR)/$(am__dirstamp)
-rgw/test_build_librgw-rgw_op.$(OBJEXT): rgw/$(am__dirstamp) \
+rgw/test_build_librgw-rgw_formats.$(OBJEXT): rgw/$(am__dirstamp) \
 	rgw/$(DEPDIR)/$(am__dirstamp)
-rgw/test_build_librgw-rgw_basic_types.$(OBJEXT): rgw/$(am__dirstamp) \
+rgw/test_build_librgw-rgw_frontend.$(OBJEXT): rgw/$(am__dirstamp) \
 	rgw/$(DEPDIR)/$(am__dirstamp)
-rgw/test_build_librgw-rgw_common.$(OBJEXT): rgw/$(am__dirstamp) \
+rgw/test_build_librgw-rgw_gc.$(OBJEXT): rgw/$(am__dirstamp) \
 	rgw/$(DEPDIR)/$(am__dirstamp)
-rgw/test_build_librgw-rgw_cache.$(OBJEXT): rgw/$(am__dirstamp) \
+rgw/test_build_librgw-rgw_http_client.$(OBJEXT): rgw/$(am__dirstamp) \
 	rgw/$(DEPDIR)/$(am__dirstamp)
-rgw/test_build_librgw-rgw_formats.$(OBJEXT): rgw/$(am__dirstamp) \
+rgw/test_build_librgw-rgw_json_enc.$(OBJEXT): rgw/$(am__dirstamp) \
+	rgw/$(DEPDIR)/$(am__dirstamp)
+rgw/test_build_librgw-rgw_keystone.$(OBJEXT): rgw/$(am__dirstamp) \
+	rgw/$(DEPDIR)/$(am__dirstamp)
+rgw/test_build_librgw-rgw_loadgen.$(OBJEXT): rgw/$(am__dirstamp) \
 	rgw/$(DEPDIR)/$(am__dirstamp)
 rgw/test_build_librgw-rgw_log.$(OBJEXT): rgw/$(am__dirstamp) \
 	rgw/$(DEPDIR)/$(am__dirstamp)
+rgw/test_build_librgw-rgw_metadata.$(OBJEXT): rgw/$(am__dirstamp) \
+	rgw/$(DEPDIR)/$(am__dirstamp)
 rgw/test_build_librgw-rgw_multi.$(OBJEXT): rgw/$(am__dirstamp) \
 	rgw/$(DEPDIR)/$(am__dirstamp)
-rgw/test_build_librgw-rgw_policy_s3.$(OBJEXT): rgw/$(am__dirstamp) \
+rgw/test_build_librgw-rgw_multi_del.$(OBJEXT): rgw/$(am__dirstamp) \
 	rgw/$(DEPDIR)/$(am__dirstamp)
-rgw/test_build_librgw-rgw_gc.$(OBJEXT): rgw/$(am__dirstamp) \
+rgw/test_build_librgw-rgw_auth_s3.$(OBJEXT): rgw/$(am__dirstamp) \
 	rgw/$(DEPDIR)/$(am__dirstamp)
-rgw/test_build_librgw-rgw_multi_del.$(OBJEXT): rgw/$(am__dirstamp) \
+rgw/test_build_librgw-rgw_period_history.$(OBJEXT):  \
+	rgw/$(am__dirstamp) rgw/$(DEPDIR)/$(am__dirstamp)
+rgw/test_build_librgw-rgw_period_puller.$(OBJEXT):  \
+	rgw/$(am__dirstamp) rgw/$(DEPDIR)/$(am__dirstamp)
+rgw/test_build_librgw-rgw_period_pusher.$(OBJEXT):  \
+	rgw/$(am__dirstamp) rgw/$(DEPDIR)/$(am__dirstamp)
+rgw/test_build_librgw-rgw_realm_reloader.$(OBJEXT):  \
+	rgw/$(am__dirstamp) rgw/$(DEPDIR)/$(am__dirstamp)
+rgw/test_build_librgw-rgw_realm_watcher.$(OBJEXT):  \
+	rgw/$(am__dirstamp) rgw/$(DEPDIR)/$(am__dirstamp)
+rgw/test_build_librgw-rgw_sync.$(OBJEXT): rgw/$(am__dirstamp) \
 	rgw/$(DEPDIR)/$(am__dirstamp)
-rgw/test_build_librgw-rgw_env.$(OBJEXT): rgw/$(am__dirstamp) \
+rgw/test_build_librgw-rgw_data_sync.$(OBJEXT): rgw/$(am__dirstamp) \
 	rgw/$(DEPDIR)/$(am__dirstamp)
-rgw/test_build_librgw-rgw_cors.$(OBJEXT): rgw/$(am__dirstamp) \
+rgw/test_build_librgw-rgw_object_expirer_core.$(OBJEXT):  \
+	rgw/$(am__dirstamp) rgw/$(DEPDIR)/$(am__dirstamp)
+rgw/test_build_librgw-rgw_op.$(OBJEXT): rgw/$(am__dirstamp) \
 	rgw/$(DEPDIR)/$(am__dirstamp)
-rgw/test_build_librgw-rgw_cors_s3.$(OBJEXT): rgw/$(am__dirstamp) \
+rgw/test_build_librgw-rgw_os_lib.$(OBJEXT): rgw/$(am__dirstamp) \
 	rgw/$(DEPDIR)/$(am__dirstamp)
-rgw/test_build_librgw-rgw_auth_s3.$(OBJEXT): rgw/$(am__dirstamp) \
+rgw/test_build_librgw-rgw_policy_s3.$(OBJEXT): rgw/$(am__dirstamp) \
 	rgw/$(DEPDIR)/$(am__dirstamp)
-rgw/test_build_librgw-rgw_metadata.$(OBJEXT): rgw/$(am__dirstamp) \
+rgw/test_build_librgw-rgw_process.$(OBJEXT): rgw/$(am__dirstamp) \
+	rgw/$(DEPDIR)/$(am__dirstamp)
+rgw/test_build_librgw-rgw_quota.$(OBJEXT): rgw/$(am__dirstamp) \
+	rgw/$(DEPDIR)/$(am__dirstamp)
+rgw/test_build_librgw-rgw_rados.$(OBJEXT): rgw/$(am__dirstamp) \
 	rgw/$(DEPDIR)/$(am__dirstamp)
 rgw/test_build_librgw-rgw_replica_log.$(OBJEXT): rgw/$(am__dirstamp) \
 	rgw/$(DEPDIR)/$(am__dirstamp)
-rgw/test_build_librgw-rgw_keystone.$(OBJEXT): rgw/$(am__dirstamp) \
+rgw/test_build_librgw-rgw_request.$(OBJEXT): rgw/$(am__dirstamp) \
 	rgw/$(DEPDIR)/$(am__dirstamp)
-rgw/test_build_librgw-rgw_quota.$(OBJEXT): rgw/$(am__dirstamp) \
+rgw/test_build_librgw-rgw_resolve.$(OBJEXT): rgw/$(am__dirstamp) \
 	rgw/$(DEPDIR)/$(am__dirstamp)
-rgw/test_build_librgw-rgw_dencoder.$(OBJEXT): rgw/$(am__dirstamp) \
+rgw/test_build_librgw-rgw_rest_bucket.$(OBJEXT): rgw/$(am__dirstamp) \
 	rgw/$(DEPDIR)/$(am__dirstamp)
-rgw/test_build_librgw-rgw_object_expirer_core.$(OBJEXT):  \
+rgw/test_build_librgw-rgw_rest.$(OBJEXT): rgw/$(am__dirstamp) \
+	rgw/$(DEPDIR)/$(am__dirstamp)
+rgw/test_build_librgw-rgw_rest_client.$(OBJEXT): rgw/$(am__dirstamp) \
+	rgw/$(DEPDIR)/$(am__dirstamp)
+rgw/test_build_librgw-rgw_rest_config.$(OBJEXT): rgw/$(am__dirstamp) \
+	rgw/$(DEPDIR)/$(am__dirstamp)
+rgw/test_build_librgw-rgw_rest_conn.$(OBJEXT): rgw/$(am__dirstamp) \
+	rgw/$(DEPDIR)/$(am__dirstamp)
+rgw/test_build_librgw-rgw_rest_log.$(OBJEXT): rgw/$(am__dirstamp) \
+	rgw/$(DEPDIR)/$(am__dirstamp)
+rgw/test_build_librgw-rgw_rest_metadata.$(OBJEXT):  \
+	rgw/$(am__dirstamp) rgw/$(DEPDIR)/$(am__dirstamp)
+rgw/test_build_librgw-rgw_rest_opstate.$(OBJEXT): rgw/$(am__dirstamp) \
+	rgw/$(DEPDIR)/$(am__dirstamp)
+rgw/test_build_librgw-rgw_rest_realm.$(OBJEXT): rgw/$(am__dirstamp) \
+	rgw/$(DEPDIR)/$(am__dirstamp)
+rgw/test_build_librgw-rgw_rest_replica_log.$(OBJEXT):  \
 	rgw/$(am__dirstamp) rgw/$(DEPDIR)/$(am__dirstamp)
+rgw/test_build_librgw-rgw_rest_s3.$(OBJEXT): rgw/$(am__dirstamp) \
+	rgw/$(DEPDIR)/$(am__dirstamp)
+rgw/test_build_librgw-rgw_rest_swift.$(OBJEXT): rgw/$(am__dirstamp) \
+	rgw/$(DEPDIR)/$(am__dirstamp)
+rgw/test_build_librgw-rgw_rest_usage.$(OBJEXT): rgw/$(am__dirstamp) \
+	rgw/$(DEPDIR)/$(am__dirstamp)
+rgw/test_build_librgw-rgw_rest_user.$(OBJEXT): rgw/$(am__dirstamp) \
+	rgw/$(DEPDIR)/$(am__dirstamp)
+rgw/test_build_librgw-rgw_swift_auth.$(OBJEXT): rgw/$(am__dirstamp) \
+	rgw/$(DEPDIR)/$(am__dirstamp)
+rgw/test_build_librgw-rgw_swift.$(OBJEXT): rgw/$(am__dirstamp) \
+	rgw/$(DEPDIR)/$(am__dirstamp)
+rgw/test_build_librgw-rgw_usage.$(OBJEXT): rgw/$(am__dirstamp) \
+	rgw/$(DEPDIR)/$(am__dirstamp)
+rgw/test_build_librgw-rgw_user.$(OBJEXT): rgw/$(am__dirstamp) \
+	rgw/$(DEPDIR)/$(am__dirstamp)
+rgw/test_build_librgw-rgw_file.$(OBJEXT): rgw/$(am__dirstamp) \
+	rgw/$(DEPDIR)/$(am__dirstamp)
+rgw/test_build_librgw-librgw.$(OBJEXT): rgw/$(am__dirstamp) \
+	rgw/$(DEPDIR)/$(am__dirstamp)
+rgw/test_build_librgw-rgw_xml.$(OBJEXT): rgw/$(am__dirstamp) \
+	rgw/$(DEPDIR)/$(am__dirstamp)
+rgw/test_build_librgw-rgw_xml_enc.$(OBJEXT): rgw/$(am__dirstamp) \
+	rgw/$(DEPDIR)/$(am__dirstamp)
 rgw/test_build_librgw-rgw_website.$(OBJEXT): rgw/$(am__dirstamp) \
 	rgw/$(DEPDIR)/$(am__dirstamp)
+rgw/test_build_librgw-rgw_ldap.$(OBJEXT): rgw/$(am__dirstamp) \
+	rgw/$(DEPDIR)/$(am__dirstamp)
 
 test_build_librgw$(EXEEXT): $(test_build_librgw_OBJECTS) $(test_build_librgw_DEPENDENCIES) $(EXTRA_test_build_librgw_DEPENDENCIES) 
 	@rm -f test_build_librgw$(EXEEXT)
@@ -17319,6 +18102,42 @@ unittest_prioritized_queue$(EXEEXT): $(unittest_prioritized_queue_OBJECTS) $(uni
 test/rbd_mirror/unittest_rbd_mirror-test_main.$(OBJEXT):  \
 	test/rbd_mirror/$(am__dirstamp) \
 	test/rbd_mirror/$(DEPDIR)/$(am__dirstamp)
+test/rbd_mirror/unittest_rbd_mirror-test_mock_fixture.$(OBJEXT):  \
+	test/rbd_mirror/$(am__dirstamp) \
+	test/rbd_mirror/$(DEPDIR)/$(am__dirstamp)
+test/rbd_mirror/unittest_rbd_mirror-test_mock_ImageSync.$(OBJEXT):  \
+	test/rbd_mirror/$(am__dirstamp) \
+	test/rbd_mirror/$(DEPDIR)/$(am__dirstamp)
+test/rbd_mirror/image_sync/$(am__dirstamp):
+	@$(MKDIR_P) test/rbd_mirror/image_sync
+	@: > test/rbd_mirror/image_sync/$(am__dirstamp)
+test/rbd_mirror/image_sync/$(DEPDIR)/$(am__dirstamp):
+	@$(MKDIR_P) test/rbd_mirror/image_sync/$(DEPDIR)
+	@: > test/rbd_mirror/image_sync/$(DEPDIR)/$(am__dirstamp)
+test/rbd_mirror/image_sync/unittest_rbd_mirror-test_mock_ImageCopyRequest.$(OBJEXT):  \
+	test/rbd_mirror/image_sync/$(am__dirstamp) \
+	test/rbd_mirror/image_sync/$(DEPDIR)/$(am__dirstamp)
+test/rbd_mirror/image_sync/unittest_rbd_mirror-test_mock_ObjectCopyRequest.$(OBJEXT):  \
+	test/rbd_mirror/image_sync/$(am__dirstamp) \
+	test/rbd_mirror/image_sync/$(DEPDIR)/$(am__dirstamp)
+test/rbd_mirror/image_sync/unittest_rbd_mirror-test_mock_SnapshotCopyRequest.$(OBJEXT):  \
+	test/rbd_mirror/image_sync/$(am__dirstamp) \
+	test/rbd_mirror/image_sync/$(DEPDIR)/$(am__dirstamp)
+test/rbd_mirror/image_sync/unittest_rbd_mirror-test_mock_SyncPointCreateRequest.$(OBJEXT):  \
+	test/rbd_mirror/image_sync/$(am__dirstamp) \
+	test/rbd_mirror/image_sync/$(DEPDIR)/$(am__dirstamp)
+test/rbd_mirror/image_sync/unittest_rbd_mirror-test_mock_SyncPointPruneRequest.$(OBJEXT):  \
+	test/rbd_mirror/image_sync/$(am__dirstamp) \
+	test/rbd_mirror/image_sync/$(DEPDIR)/$(am__dirstamp)
+test/rbd_mirror/mock/$(am__dirstamp):
+	@$(MKDIR_P) test/rbd_mirror/mock
+	@: > test/rbd_mirror/mock/$(am__dirstamp)
+test/rbd_mirror/mock/$(DEPDIR)/$(am__dirstamp):
+	@$(MKDIR_P) test/rbd_mirror/mock/$(DEPDIR)
+	@: > test/rbd_mirror/mock/$(DEPDIR)/$(am__dirstamp)
+test/rbd_mirror/mock/unittest_rbd_mirror-MockJournaler.$(OBJEXT):  \
+	test/rbd_mirror/mock/$(am__dirstamp) \
+	test/rbd_mirror/mock/$(DEPDIR)/$(am__dirstamp)
 
 unittest_rbd_mirror$(EXEEXT): $(unittest_rbd_mirror_OBJECTS) $(unittest_rbd_mirror_DEPENDENCIES) $(EXTRA_unittest_rbd_mirror_DEPENDENCIES) 
 	@rm -f unittest_rbd_mirror$(EXEEXT)
@@ -17859,6 +18678,8 @@ mostlyclean-compile:
 	-rm -f librbd/exclusive_lock/*.lo
 	-rm -f librbd/image/*.$(OBJEXT)
 	-rm -f librbd/image/*.lo
+	-rm -f librbd/image_watcher/*.$(OBJEXT)
+	-rm -f librbd/image_watcher/*.lo
 	-rm -f librbd/journal/*.$(OBJEXT)
 	-rm -f librbd/journal/*.lo
 	-rm -f librbd/object_map/*.$(OBJEXT)
@@ -17947,6 +18768,8 @@ mostlyclean-compile:
 	-rm -f test/osdc/*.$(OBJEXT)
 	-rm -f test/rbd_mirror/*.$(OBJEXT)
 	-rm -f test/rbd_mirror/*.lo
+	-rm -f test/rbd_mirror/image_sync/*.$(OBJEXT)
+	-rm -f test/rbd_mirror/mock/*.$(OBJEXT)
 	-rm -f test/rgw/*.$(OBJEXT)
 	-rm -f test/system/*.$(OBJEXT)
 	-rm -f test/system/*.lo
@@ -17957,9 +18780,15 @@ mostlyclean-compile:
 	-rm -f tools/rbd/action/*.$(OBJEXT)
 	-rm -f tools/rbd_mirror/*.$(OBJEXT)
 	-rm -f tools/rbd_mirror/*.lo
+	-rm -f tools/rbd_mirror/image_replayer/*.$(OBJEXT)
+	-rm -f tools/rbd_mirror/image_replayer/*.lo
+	-rm -f tools/rbd_mirror/image_sync/*.$(OBJEXT)
+	-rm -f tools/rbd_mirror/image_sync/*.lo
 	-rm -f tools/rbd_nbd/*.$(OBJEXT)
 	-rm -f tracing/*.$(OBJEXT)
 	-rm -f tracing/*.lo
+	-rm -f xxHash/*.$(OBJEXT)
+	-rm -f xxHash/*.lo
 
 distclean-compile:
 	-rm -f *.tab.c
@@ -17994,6 +18823,7 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote at auth/none/$(DEPDIR)/AuthNoneAuthorizeHandler.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at auth/unknown/$(DEPDIR)/AuthUnknownAuthorizeHandler.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at civetweb/src/$(DEPDIR)/libcivetweb_la-civetweb.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at civetweb/src/$(DEPDIR)/radosgw-civetweb.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at client/$(DEPDIR)/Client.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at client/$(DEPDIR)/ClientSnapRealm.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at client/$(DEPDIR)/Dentry.Plo at am__quote@
@@ -18016,7 +18846,7 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote at cls/lock/$(DEPDIR)/cls_lock_ops.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at cls/lock/$(DEPDIR)/cls_lock_types.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at cls/log/$(DEPDIR)/cls_log.Plo at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at cls/log/$(DEPDIR)/cls_log_client.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at cls/log/$(DEPDIR)/cls_log_client.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at cls/numops/$(DEPDIR)/cls_numops.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at cls/numops/$(DEPDIR)/cls_numops_client.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at cls/rbd/$(DEPDIR)/cls_rbd.Plo at am__quote@
@@ -18026,24 +18856,24 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote at cls/refcount/$(DEPDIR)/cls_refcount_client.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at cls/refcount/$(DEPDIR)/cls_refcount_ops.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at cls/replica_log/$(DEPDIR)/cls_replica_log.Plo at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at cls/replica_log/$(DEPDIR)/cls_replica_log_client.Po at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at cls/replica_log/$(DEPDIR)/cls_replica_log_ops.Po at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at cls/replica_log/$(DEPDIR)/cls_replica_log_types.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at cls/replica_log/$(DEPDIR)/cls_replica_log_client.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at cls/replica_log/$(DEPDIR)/cls_replica_log_ops.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at cls/replica_log/$(DEPDIR)/cls_replica_log_types.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at cls/rgw/$(DEPDIR)/cls_rgw.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at cls/rgw/$(DEPDIR)/cls_rgw_client.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at cls/rgw/$(DEPDIR)/cls_rgw_ops.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at cls/rgw/$(DEPDIR)/cls_rgw_types.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at cls/statelog/$(DEPDIR)/cls_statelog.Plo at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at cls/statelog/$(DEPDIR)/cls_statelog_client.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at cls/statelog/$(DEPDIR)/cls_statelog_client.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at cls/timeindex/$(DEPDIR)/cls_timeindex.Plo at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at cls/timeindex/$(DEPDIR)/cls_timeindex_client.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at cls/timeindex/$(DEPDIR)/cls_timeindex_client.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at cls/user/$(DEPDIR)/cls_user.Plo at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at cls/user/$(DEPDIR)/cls_user_client.Po at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at cls/user/$(DEPDIR)/cls_user_ops.Po at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at cls/user/$(DEPDIR)/cls_user_types.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at cls/user/$(DEPDIR)/cls_user_client.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at cls/user/$(DEPDIR)/cls_user_ops.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at cls/user/$(DEPDIR)/cls_user_types.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at cls/version/$(DEPDIR)/cls_version.Plo at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at cls/version/$(DEPDIR)/cls_version_client.Po at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at cls/version/$(DEPDIR)/cls_version_types.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at cls/version/$(DEPDIR)/cls_version_client.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at cls/version/$(DEPDIR)/cls_version_types.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at common/$(DEPDIR)/BackTrace.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at common/$(DEPDIR)/Clock.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at common/$(DEPDIR)/ConfUtils.Plo at am__quote@
@@ -18102,6 +18932,7 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote at common/$(DEPDIR)/errno.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at common/$(DEPDIR)/escape.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at common/$(DEPDIR)/fd.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at common/$(DEPDIR)/fs_types.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at common/$(DEPDIR)/hex.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at common/$(DEPDIR)/histogram.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at common/$(DEPDIR)/hobject.Plo at am__quote@
@@ -18128,6 +18959,7 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote at common/$(DEPDIR)/pipe.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at common/$(DEPDIR)/run_cmd.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at common/$(DEPDIR)/safe_io.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at common/$(DEPDIR)/scrub_types.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at common/$(DEPDIR)/secret.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at common/$(DEPDIR)/signal.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at common/$(DEPDIR)/simple_spin.Plo at am__quote@
@@ -18531,6 +19363,8 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote at librbd/image/$(DEPDIR)/RefreshParentRequest.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at librbd/image/$(DEPDIR)/RefreshRequest.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at librbd/image/$(DEPDIR)/SetSnapRequest.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at librbd/image_watcher/$(DEPDIR)/Notifier.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at librbd/image_watcher/$(DEPDIR)/NotifyLockOwner.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at librbd/journal/$(DEPDIR)/Replay.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at librbd/journal/$(DEPDIR)/Types.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at librbd/object_map/$(DEPDIR)/InvalidateRequest.Plo at am__quote@
@@ -18563,6 +19397,8 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote at mds/$(DEPDIR)/CDir.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at mds/$(DEPDIR)/CInode.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at mds/$(DEPDIR)/Capability.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at mds/$(DEPDIR)/DamageTable.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at mds/$(DEPDIR)/FSMap.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at mds/$(DEPDIR)/InoTable.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at mds/$(DEPDIR)/JournalPointer.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at mds/$(DEPDIR)/Locker.Plo at am__quote@
@@ -18593,6 +19429,7 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote at mds/$(DEPDIR)/ceph_dencoder-CDir.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at mds/$(DEPDIR)/ceph_dencoder-CInode.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at mds/$(DEPDIR)/ceph_dencoder-Capability.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at mds/$(DEPDIR)/ceph_dencoder-DamageTable.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at mds/$(DEPDIR)/ceph_dencoder-InoTable.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at mds/$(DEPDIR)/ceph_dencoder-JournalPointer.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at mds/$(DEPDIR)/ceph_dencoder-Locker.Po at am__quote@
@@ -18689,6 +19526,7 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote at os/filestore/$(DEPDIR)/libos_a-GenericFileStoreBackend.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at os/filestore/$(DEPDIR)/libos_a-HashIndex.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at os/filestore/$(DEPDIR)/libos_a-IndexManager.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at os/filestore/$(DEPDIR)/libos_a-JournalThrottle.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at os/filestore/$(DEPDIR)/libos_a-JournalingObjectStore.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at os/filestore/$(DEPDIR)/libos_a-LFNIndex.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at os/filestore/$(DEPDIR)/libos_a-WBThrottle.Po at am__quote@
@@ -18718,6 +19556,7 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote at osd/$(DEPDIR)/libosd_a-PGBackend.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at osd/$(DEPDIR)/libosd_a-ReplicatedBackend.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at osd/$(DEPDIR)/libosd_a-ReplicatedPG.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at osd/$(DEPDIR)/libosd_a-ScrubStore.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at osd/$(DEPDIR)/libosd_a-SnapMapper.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at osd/$(DEPDIR)/libosd_a-Watch.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at osd/$(DEPDIR)/libosd_types_la-ECUtil.Plo at am__quote@
@@ -18757,6 +19596,7 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote at rgw/$(DEPDIR)/ceph_dencoder-rgw_dencoder.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at rgw/$(DEPDIR)/ceph_dencoder-rgw_env.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at rgw/$(DEPDIR)/ceph_dencoder-rgw_json_enc.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at rgw/$(DEPDIR)/ceph_dencoder-rgw_keystone.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at rgw/$(DEPDIR)/libcivetweb_la-rgw_civetweb.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at rgw/$(DEPDIR)/libcivetweb_la-rgw_civetweb_log.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at rgw/$(DEPDIR)/librgw_la-librgw.Plo at am__quote@
@@ -18769,28 +19609,59 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote at rgw/$(DEPDIR)/librgw_la-rgw_cache.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at rgw/$(DEPDIR)/librgw_la-rgw_client_io.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at rgw/$(DEPDIR)/librgw_la-rgw_common.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at rgw/$(DEPDIR)/librgw_la-rgw_coroutine.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at rgw/$(DEPDIR)/librgw_la-rgw_cors.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at rgw/$(DEPDIR)/librgw_la-rgw_cors_s3.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at rgw/$(DEPDIR)/librgw_la-rgw_cr_rados.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at rgw/$(DEPDIR)/librgw_la-rgw_data_sync.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at rgw/$(DEPDIR)/librgw_la-rgw_dencoder.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at rgw/$(DEPDIR)/librgw_la-rgw_env.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at rgw/$(DEPDIR)/librgw_la-rgw_fcgi.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at rgw/$(DEPDIR)/librgw_la-rgw_file.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at rgw/$(DEPDIR)/librgw_la-rgw_formats.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at rgw/$(DEPDIR)/librgw_la-rgw_frontend.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at rgw/$(DEPDIR)/librgw_la-rgw_gc.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at rgw/$(DEPDIR)/librgw_la-rgw_http_client.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at rgw/$(DEPDIR)/librgw_la-rgw_json_enc.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at rgw/$(DEPDIR)/librgw_la-rgw_keystone.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at rgw/$(DEPDIR)/librgw_la-rgw_ldap.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at rgw/$(DEPDIR)/librgw_la-rgw_loadgen.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at rgw/$(DEPDIR)/librgw_la-rgw_log.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at rgw/$(DEPDIR)/librgw_la-rgw_metadata.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at rgw/$(DEPDIR)/librgw_la-rgw_multi.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at rgw/$(DEPDIR)/librgw_la-rgw_multi_del.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at rgw/$(DEPDIR)/librgw_la-rgw_object_expirer_core.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at rgw/$(DEPDIR)/librgw_la-rgw_op.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at rgw/$(DEPDIR)/librgw_la-rgw_os_lib.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at rgw/$(DEPDIR)/librgw_la-rgw_period_history.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at rgw/$(DEPDIR)/librgw_la-rgw_period_puller.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at rgw/$(DEPDIR)/librgw_la-rgw_period_pusher.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at rgw/$(DEPDIR)/librgw_la-rgw_policy_s3.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at rgw/$(DEPDIR)/librgw_la-rgw_process.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at rgw/$(DEPDIR)/librgw_la-rgw_quota.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at rgw/$(DEPDIR)/librgw_la-rgw_rados.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at rgw/$(DEPDIR)/librgw_la-rgw_realm_reloader.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at rgw/$(DEPDIR)/librgw_la-rgw_realm_watcher.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at rgw/$(DEPDIR)/librgw_la-rgw_replica_log.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at rgw/$(DEPDIR)/librgw_la-rgw_request.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at rgw/$(DEPDIR)/librgw_la-rgw_resolve.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at rgw/$(DEPDIR)/librgw_la-rgw_rest.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at rgw/$(DEPDIR)/librgw_la-rgw_rest_bucket.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at rgw/$(DEPDIR)/librgw_la-rgw_rest_client.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at rgw/$(DEPDIR)/librgw_la-rgw_rest_config.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at rgw/$(DEPDIR)/librgw_la-rgw_rest_conn.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at rgw/$(DEPDIR)/librgw_la-rgw_rest_log.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at rgw/$(DEPDIR)/librgw_la-rgw_rest_metadata.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at rgw/$(DEPDIR)/librgw_la-rgw_rest_opstate.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at rgw/$(DEPDIR)/librgw_la-rgw_rest_realm.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at rgw/$(DEPDIR)/librgw_la-rgw_rest_replica_log.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at rgw/$(DEPDIR)/librgw_la-rgw_rest_s3.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at rgw/$(DEPDIR)/librgw_la-rgw_rest_swift.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at rgw/$(DEPDIR)/librgw_la-rgw_rest_usage.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at rgw/$(DEPDIR)/librgw_la-rgw_rest_user.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at rgw/$(DEPDIR)/librgw_la-rgw_swift.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at rgw/$(DEPDIR)/librgw_la-rgw_swift_auth.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at rgw/$(DEPDIR)/librgw_la-rgw_sync.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at rgw/$(DEPDIR)/librgw_la-rgw_tools.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at rgw/$(DEPDIR)/librgw_la-rgw_usage.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at rgw/$(DEPDIR)/librgw_la-rgw_user.Plo at am__quote@
@@ -18798,31 +19669,20 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote at rgw/$(DEPDIR)/librgw_la-rgw_xml.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at rgw/$(DEPDIR)/librgw_la-rgw_xml_enc.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at rgw/$(DEPDIR)/rgw_admin.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at rgw/$(DEPDIR)/rgw_civetweb.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at rgw/$(DEPDIR)/rgw_civetweb_frontend.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at rgw/$(DEPDIR)/rgw_civetweb_log.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at rgw/$(DEPDIR)/rgw_common.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at rgw/$(DEPDIR)/rgw_env.Po at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at rgw/$(DEPDIR)/rgw_http_client.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at rgw/$(DEPDIR)/rgw_fcgi_process.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at rgw/$(DEPDIR)/rgw_json_enc.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at rgw/$(DEPDIR)/rgw_jsonparser.Po at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at rgw/$(DEPDIR)/rgw_loadgen.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at rgw/$(DEPDIR)/rgw_loadgen_process.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at rgw/$(DEPDIR)/rgw_main.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at rgw/$(DEPDIR)/rgw_multiparser.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at rgw/$(DEPDIR)/rgw_object_expirer.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at rgw/$(DEPDIR)/rgw_orphan.Po at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at rgw/$(DEPDIR)/rgw_replica_log.Po at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at rgw/$(DEPDIR)/rgw_resolve.Po at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at rgw/$(DEPDIR)/rgw_rest.Po at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at rgw/$(DEPDIR)/rgw_rest_bucket.Po at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at rgw/$(DEPDIR)/rgw_rest_config.Po at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at rgw/$(DEPDIR)/rgw_rest_log.Po at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at rgw/$(DEPDIR)/rgw_rest_metadata.Po at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at rgw/$(DEPDIR)/rgw_rest_opstate.Po at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at rgw/$(DEPDIR)/rgw_rest_replica_log.Po at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at rgw/$(DEPDIR)/rgw_rest_s3.Po at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at rgw/$(DEPDIR)/rgw_rest_swift.Po at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at rgw/$(DEPDIR)/rgw_rest_usage.Po at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at rgw/$(DEPDIR)/rgw_rest_user.Po at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at rgw/$(DEPDIR)/rgw_swift.Po at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at rgw/$(DEPDIR)/rgw_swift_auth.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at rgw/$(DEPDIR)/rgw_token.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at rgw/$(DEPDIR)/test_build_librgw-librgw.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at rgw/$(DEPDIR)/test_build_librgw-rgw_acl.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at rgw/$(DEPDIR)/test_build_librgw-rgw_acl_s3.Po at am__quote@
@@ -18833,28 +19693,59 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote at rgw/$(DEPDIR)/test_build_librgw-rgw_cache.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at rgw/$(DEPDIR)/test_build_librgw-rgw_client_io.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at rgw/$(DEPDIR)/test_build_librgw-rgw_common.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at rgw/$(DEPDIR)/test_build_librgw-rgw_coroutine.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at rgw/$(DEPDIR)/test_build_librgw-rgw_cors.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at rgw/$(DEPDIR)/test_build_librgw-rgw_cors_s3.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at rgw/$(DEPDIR)/test_build_librgw-rgw_cr_rados.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at rgw/$(DEPDIR)/test_build_librgw-rgw_data_sync.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at rgw/$(DEPDIR)/test_build_librgw-rgw_dencoder.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at rgw/$(DEPDIR)/test_build_librgw-rgw_env.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at rgw/$(DEPDIR)/test_build_librgw-rgw_fcgi.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at rgw/$(DEPDIR)/test_build_librgw-rgw_file.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at rgw/$(DEPDIR)/test_build_librgw-rgw_formats.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at rgw/$(DEPDIR)/test_build_librgw-rgw_frontend.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at rgw/$(DEPDIR)/test_build_librgw-rgw_gc.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at rgw/$(DEPDIR)/test_build_librgw-rgw_http_client.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at rgw/$(DEPDIR)/test_build_librgw-rgw_json_enc.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at rgw/$(DEPDIR)/test_build_librgw-rgw_keystone.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at rgw/$(DEPDIR)/test_build_librgw-rgw_ldap.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at rgw/$(DEPDIR)/test_build_librgw-rgw_loadgen.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at rgw/$(DEPDIR)/test_build_librgw-rgw_log.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at rgw/$(DEPDIR)/test_build_librgw-rgw_metadata.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at rgw/$(DEPDIR)/test_build_librgw-rgw_multi.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at rgw/$(DEPDIR)/test_build_librgw-rgw_multi_del.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at rgw/$(DEPDIR)/test_build_librgw-rgw_object_expirer_core.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at rgw/$(DEPDIR)/test_build_librgw-rgw_op.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at rgw/$(DEPDIR)/test_build_librgw-rgw_os_lib.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at rgw/$(DEPDIR)/test_build_librgw-rgw_period_history.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at rgw/$(DEPDIR)/test_build_librgw-rgw_period_puller.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at rgw/$(DEPDIR)/test_build_librgw-rgw_period_pusher.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at rgw/$(DEPDIR)/test_build_librgw-rgw_policy_s3.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at rgw/$(DEPDIR)/test_build_librgw-rgw_process.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at rgw/$(DEPDIR)/test_build_librgw-rgw_quota.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at rgw/$(DEPDIR)/test_build_librgw-rgw_rados.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at rgw/$(DEPDIR)/test_build_librgw-rgw_realm_reloader.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at rgw/$(DEPDIR)/test_build_librgw-rgw_realm_watcher.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at rgw/$(DEPDIR)/test_build_librgw-rgw_replica_log.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at rgw/$(DEPDIR)/test_build_librgw-rgw_request.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at rgw/$(DEPDIR)/test_build_librgw-rgw_resolve.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at rgw/$(DEPDIR)/test_build_librgw-rgw_rest.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at rgw/$(DEPDIR)/test_build_librgw-rgw_rest_bucket.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at rgw/$(DEPDIR)/test_build_librgw-rgw_rest_client.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at rgw/$(DEPDIR)/test_build_librgw-rgw_rest_config.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at rgw/$(DEPDIR)/test_build_librgw-rgw_rest_conn.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at rgw/$(DEPDIR)/test_build_librgw-rgw_rest_log.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at rgw/$(DEPDIR)/test_build_librgw-rgw_rest_metadata.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at rgw/$(DEPDIR)/test_build_librgw-rgw_rest_opstate.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at rgw/$(DEPDIR)/test_build_librgw-rgw_rest_realm.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at rgw/$(DEPDIR)/test_build_librgw-rgw_rest_replica_log.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at rgw/$(DEPDIR)/test_build_librgw-rgw_rest_s3.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at rgw/$(DEPDIR)/test_build_librgw-rgw_rest_swift.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at rgw/$(DEPDIR)/test_build_librgw-rgw_rest_usage.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at rgw/$(DEPDIR)/test_build_librgw-rgw_rest_user.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at rgw/$(DEPDIR)/test_build_librgw-rgw_swift.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at rgw/$(DEPDIR)/test_build_librgw-rgw_swift_auth.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at rgw/$(DEPDIR)/test_build_librgw-rgw_sync.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at rgw/$(DEPDIR)/test_build_librgw-rgw_tools.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at rgw/$(DEPDIR)/test_build_librgw-rgw_usage.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at rgw/$(DEPDIR)/test_build_librgw-rgw_user.Po at am__quote@
@@ -18877,6 +19768,11 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote at test/$(DEPDIR)/ceph_test_stress_watch-test_stress_watch.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at test/$(DEPDIR)/ceph_xattr_bench-xattr_bench.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at test/$(DEPDIR)/kv_store_bench.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at test/$(DEPDIR)/librgw_file-librgw_file.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at test/$(DEPDIR)/librgw_file_aw-librgw_file_aw.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at test/$(DEPDIR)/librgw_file_cd-librgw_file_cd.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at test/$(DEPDIR)/librgw_file_gp-librgw_file_gp.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at test/$(DEPDIR)/librgw_file_nfsns-librgw_file_nfsns.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at test/$(DEPDIR)/multi_stress_watch.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at test/$(DEPDIR)/objectstore_bench.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at test/$(DEPDIR)/omap_bench.Po at am__quote@
@@ -19055,6 +19951,7 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote at test/librados/$(DEPDIR)/ceph_test_rados_api_snapshots-snapshots.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at test/librados/$(DEPDIR)/ceph_test_rados_api_stat-stat.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at test/librados/$(DEPDIR)/ceph_test_rados_api_tier-tier.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at test/librados/$(DEPDIR)/ceph_test_rados_api_tmap_migrate-tmap_migrate.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at test/librados/$(DEPDIR)/ceph_test_rados_api_watch_notify-watch_notify.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at test/librados/$(DEPDIR)/libradostest_la-TestCase.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at test/librados/$(DEPDIR)/libradostest_la-test.Plo at am__quote@
@@ -19081,6 +19978,7 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote at test/librbd/$(DEPDIR)/librbd_test_la-test_fixture.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at test/librbd/$(DEPDIR)/librbd_test_la-test_internal.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at test/librbd/$(DEPDIR)/librbd_test_la-test_librbd.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at test/librbd/$(DEPDIR)/librbd_test_la-test_mirroring.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at test/librbd/$(DEPDIR)/librbd_test_la-test_support.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at test/librbd/$(DEPDIR)/unittest_librbd-test_main.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at test/librbd/$(DEPDIR)/unittest_librbd-test_mock_ExclusiveLock.Po at am__quote@
@@ -19155,11 +20053,24 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote at test/osdc/$(DEPDIR)/FakeWriteback.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at test/osdc/$(DEPDIR)/object_cacher_stress.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at test/rbd_mirror/$(DEPDIR)/ceph_test_rbd_mirror-test_main.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at test/rbd_mirror/$(DEPDIR)/image_replay.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at test/rbd_mirror/$(DEPDIR)/librbd_mirror_test_la-test_ClusterWatcher.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at test/rbd_mirror/$(DEPDIR)/librbd_mirror_test_la-test_ImageReplayer.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at test/rbd_mirror/$(DEPDIR)/librbd_mirror_test_la-test_ImageSync.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at test/rbd_mirror/$(DEPDIR)/librbd_mirror_test_la-test_PoolWatcher.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at test/rbd_mirror/$(DEPDIR)/librbd_mirror_test_la-test_fixture.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at test/rbd_mirror/$(DEPDIR)/unittest_rbd_mirror-test_main.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at test/rbd_mirror/$(DEPDIR)/unittest_rbd_mirror-test_mock_ImageSync.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at test/rbd_mirror/$(DEPDIR)/unittest_rbd_mirror-test_mock_fixture.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at test/rbd_mirror/image_sync/$(DEPDIR)/unittest_rbd_mirror-test_mock_ImageCopyRequest.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at test/rbd_mirror/image_sync/$(DEPDIR)/unittest_rbd_mirror-test_mock_ObjectCopyRequest.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at test/rbd_mirror/image_sync/$(DEPDIR)/unittest_rbd_mirror-test_mock_SnapshotCopyRequest.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at test/rbd_mirror/image_sync/$(DEPDIR)/unittest_rbd_mirror-test_mock_SyncPointCreateRequest.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at test/rbd_mirror/image_sync/$(DEPDIR)/unittest_rbd_mirror-test_mock_SyncPointPruneRequest.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at test/rbd_mirror/mock/$(DEPDIR)/unittest_rbd_mirror-MockJournaler.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at test/rgw/$(DEPDIR)/ceph_test_rgw_manifest-test_rgw_manifest.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at test/rgw/$(DEPDIR)/ceph_test_rgw_obj-test_rgw_obj.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at test/rgw/$(DEPDIR)/ceph_test_rgw_period_history-test_rgw_period_history.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at test/system/$(DEPDIR)/cross_process_sem.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at test/system/$(DEPDIR)/rados_delete_pools_parallel.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at test/system/$(DEPDIR)/rados_list_parallel.Po at am__quote@
@@ -19196,7 +20107,10 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote at tools/cephfs/$(DEPDIR)/JournalTool.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at tools/cephfs/$(DEPDIR)/MDSUtility.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at tools/cephfs/$(DEPDIR)/Resetter.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at tools/cephfs/$(DEPDIR)/RoleSelector.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at tools/cephfs/$(DEPDIR)/TableTool.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at tools/cephfs/$(DEPDIR)/ceph_test_rados_api_tmap_migrate-DataScan.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at tools/cephfs/$(DEPDIR)/ceph_test_rados_api_tmap_migrate-MDSUtility.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at tools/cephfs/$(DEPDIR)/cephfs-data-scan.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at tools/cephfs/$(DEPDIR)/cephfs-journal-tool.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at tools/cephfs/$(DEPDIR)/cephfs-table-tool.Po at am__quote@
@@ -19229,6 +20143,7 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote at tools/rbd/action/$(DEPDIR)/List.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at tools/rbd/action/$(DEPDIR)/Lock.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at tools/rbd/action/$(DEPDIR)/MergeDiff.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at tools/rbd/action/$(DEPDIR)/MirrorImage.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at tools/rbd/action/$(DEPDIR)/MirrorPool.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at tools/rbd/action/$(DEPDIR)/Nbd.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at tools/rbd/action/$(DEPDIR)/ObjectMap.Po at am__quote@
@@ -19240,11 +20155,21 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote at tools/rbd/action/$(DEPDIR)/Watch.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at tools/rbd_mirror/$(DEPDIR)/ClusterWatcher.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at tools/rbd_mirror/$(DEPDIR)/ImageReplayer.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at tools/rbd_mirror/$(DEPDIR)/ImageSync.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at tools/rbd_mirror/$(DEPDIR)/Mirror.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at tools/rbd_mirror/$(DEPDIR)/PoolWatcher.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at tools/rbd_mirror/$(DEPDIR)/Replayer.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at tools/rbd_mirror/$(DEPDIR)/Threads.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at tools/rbd_mirror/$(DEPDIR)/main.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at tools/rbd_mirror/$(DEPDIR)/types.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at tools/rbd_mirror/image_replayer/$(DEPDIR)/BootstrapRequest.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at tools/rbd_mirror/image_replayer/$(DEPDIR)/CloseImageRequest.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at tools/rbd_mirror/image_replayer/$(DEPDIR)/OpenLocalImageRequest.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at tools/rbd_mirror/image_sync/$(DEPDIR)/ImageCopyRequest.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at tools/rbd_mirror/image_sync/$(DEPDIR)/ObjectCopyRequest.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at tools/rbd_mirror/image_sync/$(DEPDIR)/SnapshotCopyRequest.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at tools/rbd_mirror/image_sync/$(DEPDIR)/SyncPointCreateRequest.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at tools/rbd_mirror/image_sync/$(DEPDIR)/SyncPointPruneRequest.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at tools/rbd_nbd/$(DEPDIR)/rbd_nbd-rbd-nbd.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at tracing/$(DEPDIR)/libos_tp_la-objectstore.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at tracing/$(DEPDIR)/libosd_tp_la-oprequest.Plo at am__quote@
@@ -19252,6 +20177,7 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote at tracing/$(DEPDIR)/libosd_tp_la-pg.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at tracing/$(DEPDIR)/librados_tp_la-librados.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at tracing/$(DEPDIR)/librbd_tp_la-librbd.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at xxHash/$(DEPDIR)/xxhash.Plo at am__quote@
 
 .S.o:
 @am__fastdepCCAS_TRUE@	$(AM_V_CPPAS)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\
@@ -20428,6 +21354,20 @@ test/ceph_test_c_headers-test_c_headers.obj: test/test_c_headers.c
 @AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ceph_test_c_headers_CFLAGS) $(CFLAGS) -c -o test/ceph_test_c_headers-test_c_headers.obj `if test -f 'test/test_c_headers.c'; then $(CYGPATH_W) 'test/test_c_headers.c'; else $(CYGPATH_W) '$(srcdir)/test/test_c_headers.c'; fi`
 
+civetweb/src/radosgw-civetweb.o: civetweb/src/civetweb.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(radosgw_CFLAGS) $(CFLAGS) -MT civetweb/src/radosgw-civetweb.o -MD -MP -MF civetweb/src/$(DEPDIR)/radosgw-civetweb.Tpo -c -o civetweb/src/radosgw-civetweb.o `test -f 'civetweb/src/civetweb.c' || echo '$(srcdir)/'`civetweb/src/civetweb.c
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) civetweb/src/$(DEPDIR)/radosgw-civetweb.Tpo civetweb/src/$(DEPDIR)/radosgw-civetweb.Po
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='civetweb/src/civetweb.c' object='civetweb/src/radosgw-civetweb.o' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(radosgw_CFLAGS) $(CFLAGS) -c -o civetweb/src/radosgw-civetweb.o `test -f 'civetweb/src/civetweb.c' || echo '$(srcdir)/'`civetweb/src/civetweb.c
+
+civetweb/src/radosgw-civetweb.obj: civetweb/src/civetweb.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(radosgw_CFLAGS) $(CFLAGS) -MT civetweb/src/radosgw-civetweb.obj -MD -MP -MF civetweb/src/$(DEPDIR)/radosgw-civetweb.Tpo -c -o civetweb/src/radosgw-civetweb.obj `if test -f 'civetweb/src/civetweb.c'; then $(CYGPATH_W) 'civetweb/src/civetweb.c'; else $(CYGPATH_W) '$(srcdir)/civetweb/src/civetweb.c'; fi`
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) civetweb/src/$(DEPDIR)/radosgw-civetweb.Tpo civetweb/src/$(DEPDIR)/radosgw-civetweb.Po
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='civetweb/src/civetweb.c' object='civetweb/src/radosgw-civetweb.obj' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(radosgw_CFLAGS) $(CFLAGS) -c -o civetweb/src/radosgw-civetweb.obj `if test -f 'civetweb/src/civetweb.c'; then $(CYGPATH_W) 'civetweb/src/civetweb.c'; else $(CYGPATH_W) '$(srcdir)/civetweb/src/civetweb.c'; fi`
+
 erasure-code/jerasure/jerasure/src/unittest_erasure_code_jerasure-cauchy.o: erasure-code/jerasure/jerasure/src/cauchy.c
 @am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(unittest_erasure_code_jerasure_CFLAGS) $(CFLAGS) -MT erasure-code/jerasure/jerasure/src/unittest_erasure_code_jerasure-cauchy.o -MD -MP -MF erasure-code/jerasure/jerasure/src/$(DEPDIR)/unittest_erasure_code_jerasure-cauchy.Tpo -c -o erasure-code/jerasure/jerasure/src/unittest_erasure_code_jerasure-cauchy.o `test -f 'erasure-code/jerasure/jerasure/src/cauchy.c' || echo '$(srcdir)/'`er [...]
 @am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) erasure-code/jerasure/jerasure/src/$(DEPDIR)/unittest_erasure_code_jerasure-cauchy.Tpo erasure-code/jerasure/jerasure/src/$(DEPDIR)/unittest_erasure_code_jerasure-cauchy.Po
@@ -21740,6 +22680,20 @@ os/filestore/libos_a-FileStore.obj: os/filestore/FileStore.cc
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libos_a_CXXFLAGS) $(CXXFLAGS) -c -o os/filestore/libos_a-FileStore.obj `if test -f 'os/filestore/FileStore.cc'; then $(CYGPATH_W) 'os/filestore/FileStore.cc'; else $(CYGPATH_W) '$(srcdir)/os/filestore/FileStore.cc'; fi`
 
+os/filestore/libos_a-JournalThrottle.o: os/filestore/JournalThrottle.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libos_a_CXXFLAGS) $(CXXFLAGS) -MT os/filestore/libos_a-JournalThrottle.o -MD -MP -MF os/filestore/$(DEPDIR)/libos_a-JournalThrottle.Tpo -c -o os/filestore/libos_a-JournalThrottle.o `test -f 'os/filestore/JournalThrottle.cc' || echo '$(srcdir)/'`os/filestore/JournalThrottle.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) os/filestore/$(DEPDIR)/libos_a-JournalThrottle.Tpo os/filestore/$(DEPDIR)/libos_a-JournalThrottle.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='os/filestore/JournalThrottle.cc' object='os/filestore/libos_a-JournalThrottle.o' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libos_a_CXXFLAGS) $(CXXFLAGS) -c -o os/filestore/libos_a-JournalThrottle.o `test -f 'os/filestore/JournalThrottle.cc' || echo '$(srcdir)/'`os/filestore/JournalThrottle.cc
+
+os/filestore/libos_a-JournalThrottle.obj: os/filestore/JournalThrottle.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libos_a_CXXFLAGS) $(CXXFLAGS) -MT os/filestore/libos_a-JournalThrottle.obj -MD -MP -MF os/filestore/$(DEPDIR)/libos_a-JournalThrottle.Tpo -c -o os/filestore/libos_a-JournalThrottle.obj `if test -f 'os/filestore/JournalThrottle.cc'; then $(CYGPATH_W) 'os/filestore/JournalThrottle.cc'; else $(CYGPATH_W) '$(srcdir)/os/filestore/JournalThrottle.cc'; fi`
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) os/filestore/$(DEPDIR)/libos_a-JournalThrottle.Tpo os/filestore/$(DEPDIR)/libos_a-JournalThrottle.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='os/filestore/JournalThrottle.cc' object='os/filestore/libos_a-JournalThrottle.obj' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libos_a_CXXFLAGS) $(CXXFLAGS) -c -o os/filestore/libos_a-JournalThrottle.obj `if test -f 'os/filestore/JournalThrottle.cc'; then $(CYGPATH_W) 'os/filestore/JournalThrottle.cc'; else $(CYGPATH_W) '$(srcdir)/os/filestore/JournalThrottle.cc'; fi`
+
 os/filestore/libos_a-GenericFileStoreBackend.o: os/filestore/GenericFileStoreBackend.cc
 @am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libos_a_CXXFLAGS) $(CXXFLAGS) -MT os/filestore/libos_a-GenericFileStoreBackend.o -MD -MP -MF os/filestore/$(DEPDIR)/libos_a-GenericFileStoreBackend.Tpo -c -o os/filestore/libos_a-GenericFileStoreBackend.o `test -f 'os/filestore/GenericFileStoreBackend.cc' || echo '$(srcdir)/'`os/filestore/GenericFileStoreBackend.cc
 @am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) os/filestore/$(DEPDIR)/libos_a-GenericFileStoreBackend.Tpo os/filestore/$(DEPDIR)/libos_a-GenericFileStoreBackend.Po
@@ -22370,6 +23324,20 @@ osd/libosd_a-SnapMapper.obj: osd/SnapMapper.cc
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libosd_a_CXXFLAGS) $(CXXFLAGS) -c -o osd/libosd_a-SnapMapper.obj `if test -f 'osd/SnapMapper.cc'; then $(CYGPATH_W) 'osd/SnapMapper.cc'; else $(CYGPATH_W) '$(srcdir)/osd/SnapMapper.cc'; fi`
 
+osd/libosd_a-ScrubStore.o: osd/ScrubStore.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libosd_a_CXXFLAGS) $(CXXFLAGS) -MT osd/libosd_a-ScrubStore.o -MD -MP -MF osd/$(DEPDIR)/libosd_a-ScrubStore.Tpo -c -o osd/libosd_a-ScrubStore.o `test -f 'osd/ScrubStore.cc' || echo '$(srcdir)/'`osd/ScrubStore.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) osd/$(DEPDIR)/libosd_a-ScrubStore.Tpo osd/$(DEPDIR)/libosd_a-ScrubStore.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='osd/ScrubStore.cc' object='osd/libosd_a-ScrubStore.o' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libosd_a_CXXFLAGS) $(CXXFLAGS) -c -o osd/libosd_a-ScrubStore.o `test -f 'osd/ScrubStore.cc' || echo '$(srcdir)/'`osd/ScrubStore.cc
+
+osd/libosd_a-ScrubStore.obj: osd/ScrubStore.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libosd_a_CXXFLAGS) $(CXXFLAGS) -MT osd/libosd_a-ScrubStore.obj -MD -MP -MF osd/$(DEPDIR)/libosd_a-ScrubStore.Tpo -c -o osd/libosd_a-ScrubStore.obj `if test -f 'osd/ScrubStore.cc'; then $(CYGPATH_W) 'osd/ScrubStore.cc'; else $(CYGPATH_W) '$(srcdir)/osd/ScrubStore.cc'; fi`
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) osd/$(DEPDIR)/libosd_a-ScrubStore.Tpo osd/$(DEPDIR)/libosd_a-ScrubStore.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='osd/ScrubStore.cc' object='osd/libosd_a-ScrubStore.obj' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libosd_a_CXXFLAGS) $(CXXFLAGS) -c -o osd/libosd_a-ScrubStore.obj `if test -f 'osd/ScrubStore.cc'; then $(CYGPATH_W) 'osd/ScrubStore.cc'; else $(CYGPATH_W) '$(srcdir)/osd/ScrubStore.cc'; fi`
+
 objclass/libosd_a-class_api.o: objclass/class_api.cc
 @am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libosd_a_CXXFLAGS) $(CXXFLAGS) -MT objclass/libosd_a-class_api.o -MD -MP -MF objclass/$(DEPDIR)/libosd_a-class_api.Tpo -c -o objclass/libosd_a-class_api.o `test -f 'objclass/class_api.cc' || echo '$(srcdir)/'`objclass/class_api.cc
 @am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) objclass/$(DEPDIR)/libosd_a-class_api.Tpo objclass/$(DEPDIR)/libosd_a-class_api.Po
@@ -22951,6 +23919,27 @@ test/rbd_mirror/librbd_mirror_test_la-test_PoolWatcher.lo: test/rbd_mirror/test_
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librbd_mirror_test_la_CXXFLAGS) $(CXXFLAGS) -c -o test/rbd_mirror/librbd_mirror_test_la-test_PoolWatcher.lo `test -f 'test/rbd_mirror/test_PoolWatcher.cc' || echo '$(srcdir)/'`test/rbd_mirror/test_PoolWatcher.cc
 
+test/rbd_mirror/librbd_mirror_test_la-test_ImageReplayer.lo: test/rbd_mirror/test_ImageReplayer.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librbd_mirror_test_la_CXXFLAGS) $(CXXFLAGS) -MT test/rbd_mirror/librbd_mirror_test_la-test_ImageReplayer.lo -MD -MP -MF test/rbd_mirror/$(DEPDIR)/librbd_mirror_test_la-test_ImageReplayer.Tpo -c -o test/rbd_mirror/librbd_mirror_test_la-test_ImageReplayer.lo `test -f 'test/rbd_mirror/test_ImageReplayer [...]
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) test/rbd_mirror/$(DEPDIR)/librbd_mirror_test_la-test_ImageReplayer.Tpo test/rbd_mirror/$(DEPDIR)/librbd_mirror_test_la-test_ImageReplayer.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='test/rbd_mirror/test_ImageReplayer.cc' object='test/rbd_mirror/librbd_mirror_test_la-test_ImageReplayer.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librbd_mirror_test_la_CXXFLAGS) $(CXXFLAGS) -c -o test/rbd_mirror/librbd_mirror_test_la-test_ImageReplayer.lo `test -f 'test/rbd_mirror/test_ImageReplayer.cc' || echo '$(srcdir)/'`test/rbd_mirror/test_ImageReplayer.cc
+
+test/rbd_mirror/librbd_mirror_test_la-test_ImageSync.lo: test/rbd_mirror/test_ImageSync.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librbd_mirror_test_la_CXXFLAGS) $(CXXFLAGS) -MT test/rbd_mirror/librbd_mirror_test_la-test_ImageSync.lo -MD -MP -MF test/rbd_mirror/$(DEPDIR)/librbd_mirror_test_la-test_ImageSync.Tpo -c -o test/rbd_mirror/librbd_mirror_test_la-test_ImageSync.lo `test -f 'test/rbd_mirror/test_ImageSync.cc' || echo '$( [...]
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) test/rbd_mirror/$(DEPDIR)/librbd_mirror_test_la-test_ImageSync.Tpo test/rbd_mirror/$(DEPDIR)/librbd_mirror_test_la-test_ImageSync.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='test/rbd_mirror/test_ImageSync.cc' object='test/rbd_mirror/librbd_mirror_test_la-test_ImageSync.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librbd_mirror_test_la_CXXFLAGS) $(CXXFLAGS) -c -o test/rbd_mirror/librbd_mirror_test_la-test_ImageSync.lo `test -f 'test/rbd_mirror/test_ImageSync.cc' || echo '$(srcdir)/'`test/rbd_mirror/test_ImageSync.cc
+
+test/rbd_mirror/librbd_mirror_test_la-test_fixture.lo: test/rbd_mirror/test_fixture.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librbd_mirror_test_la_CXXFLAGS) $(CXXFLAGS) -MT test/rbd_mirror/librbd_mirror_test_la-test_fixture.lo -MD -MP -MF test/rbd_mirror/$(DEPDIR)/librbd_mirror_test_la-test_fixture.Tpo -c -o test/rbd_mirror/librbd_mirror_test_la-test_fixture.lo `test -f 'test/rbd_mirror/test_fixture.cc' || echo '$(srcdir)/ [...]
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) test/rbd_mirror/$(DEPDIR)/librbd_mirror_test_la-test_fixture.Tpo test/rbd_mirror/$(DEPDIR)/librbd_mirror_test_la-test_fixture.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='test/rbd_mirror/test_fixture.cc' object='test/rbd_mirror/librbd_mirror_test_la-test_fixture.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librbd_mirror_test_la_CXXFLAGS) $(CXXFLAGS) -c -o test/rbd_mirror/librbd_mirror_test_la-test_fixture.lo `test -f 'test/rbd_mirror/test_fixture.cc' || echo '$(srcdir)/'`test/rbd_mirror/test_fixture.cc
+
 test/librbd/librbd_test_la-test_fixture.lo: test/librbd/test_fixture.cc
 @am__fastdepCXX_TRUE@	$(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librbd_test_la_CXXFLAGS) $(CXXFLAGS) -MT test/librbd/librbd_test_la-test_fixture.lo -MD -MP -MF test/librbd/$(DEPDIR)/librbd_test_la-test_fixture.Tpo -c -o test/librbd/librbd_test_la-test_fixture.lo `test -f 'test/librbd/test_fixture.cc' || echo '$(srcdir)/'`test/librbd/test_fixture.cc
 @am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) test/librbd/$(DEPDIR)/librbd_test_la-test_fixture.Tpo test/librbd/$(DEPDIR)/librbd_test_la-test_fixture.Plo
@@ -22986,6 +23975,13 @@ test/librbd/librbd_test_la-test_internal.lo: test/librbd/test_internal.cc
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librbd_test_la_CXXFLAGS) $(CXXFLAGS) -c -o test/librbd/librbd_test_la-test_internal.lo `test -f 'test/librbd/test_internal.cc' || echo '$(srcdir)/'`test/librbd/test_internal.cc
 
+test/librbd/librbd_test_la-test_mirroring.lo: test/librbd/test_mirroring.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librbd_test_la_CXXFLAGS) $(CXXFLAGS) -MT test/librbd/librbd_test_la-test_mirroring.lo -MD -MP -MF test/librbd/$(DEPDIR)/librbd_test_la-test_mirroring.Tpo -c -o test/librbd/librbd_test_la-test_mirroring.lo `test -f 'test/librbd/test_mirroring.cc' || echo '$(srcdir)/'`test/librbd/test_mirroring.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) test/librbd/$(DEPDIR)/librbd_test_la-test_mirroring.Tpo test/librbd/$(DEPDIR)/librbd_test_la-test_mirroring.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='test/librbd/test_mirroring.cc' object='test/librbd/librbd_test_la-test_mirroring.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librbd_test_la_CXXFLAGS) $(CXXFLAGS) -c -o test/librbd/librbd_test_la-test_mirroring.lo `test -f 'test/librbd/test_mirroring.cc' || echo '$(srcdir)/'`test/librbd/test_mirroring.cc
+
 test/librbd/librbd_test_la-test_ObjectMap.lo: test/librbd/test_ObjectMap.cc
 @am__fastdepCXX_TRUE@	$(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librbd_test_la_CXXFLAGS) $(CXXFLAGS) -MT test/librbd/librbd_test_la-test_ObjectMap.lo -MD -MP -MF test/librbd/$(DEPDIR)/librbd_test_la-test_ObjectMap.Tpo -c -o test/librbd/librbd_test_la-test_ObjectMap.lo `test -f 'test/librbd/test_ObjectMap.cc' || echo '$(srcdir)/'`test/librbd/test_ObjectMap.cc
 @am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) test/librbd/$(DEPDIR)/librbd_test_la-test_ObjectMap.Tpo test/librbd/$(DEPDIR)/librbd_test_la-test_ObjectMap.Plo
@@ -23007,13 +24003,6 @@ test/librbd/journal/librbd_test_la-test_Replay.lo: test/librbd/journal/test_Repl
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librbd_test_la_CXXFLAGS) $(CXXFLAGS) -c -o test/librbd/journal/librbd_test_la-test_Replay.lo `test -f 'test/librbd/journal/test_Replay.cc' || echo '$(srcdir)/'`test/librbd/journal/test_Replay.cc
 
-rgw/librgw_la-librgw.lo: rgw/librgw.cc
- at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librgw_la_CXXFLAGS) $(CXXFLAGS) -MT rgw/librgw_la-librgw.lo -MD -MP -MF rgw/$(DEPDIR)/librgw_la-librgw.Tpo -c -o rgw/librgw_la-librgw.lo `test -f 'rgw/librgw.cc' || echo '$(srcdir)/'`rgw/librgw.cc
- at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/librgw_la-librgw.Tpo rgw/$(DEPDIR)/librgw_la-librgw.Plo
- at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/librgw.cc' object='rgw/librgw_la-librgw.lo' libtool=yes @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librgw_la_CXXFLAGS) $(CXXFLAGS) -c -o rgw/librgw_la-librgw.lo `test -f 'rgw/librgw.cc' || echo '$(srcdir)/'`rgw/librgw.cc
-
 rgw/librgw_la-rgw_acl.lo: rgw/rgw_acl.cc
 @am__fastdepCXX_TRUE@	$(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librgw_la_CXXFLAGS) $(CXXFLAGS) -MT rgw/librgw_la-rgw_acl.lo -MD -MP -MF rgw/$(DEPDIR)/librgw_la-rgw_acl.Tpo -c -o rgw/librgw_la-rgw_acl.lo `test -f 'rgw/rgw_acl.cc' || echo '$(srcdir)/'`rgw/rgw_acl.cc
 @am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/librgw_la-rgw_acl.Tpo rgw/$(DEPDIR)/librgw_la-rgw_acl.Plo
@@ -23035,61 +24024,19 @@ rgw/librgw_la-rgw_acl_swift.lo: rgw/rgw_acl_swift.cc
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librgw_la_CXXFLAGS) $(CXXFLAGS) -c -o rgw/librgw_la-rgw_acl_swift.lo `test -f 'rgw/rgw_acl_swift.cc' || echo '$(srcdir)/'`rgw/rgw_acl_swift.cc
 
-rgw/librgw_la-rgw_client_io.lo: rgw/rgw_client_io.cc
- at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librgw_la_CXXFLAGS) $(CXXFLAGS) -MT rgw/librgw_la-rgw_client_io.lo -MD -MP -MF rgw/$(DEPDIR)/librgw_la-rgw_client_io.Tpo -c -o rgw/librgw_la-rgw_client_io.lo `test -f 'rgw/rgw_client_io.cc' || echo '$(srcdir)/'`rgw/rgw_client_io.cc
- at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/librgw_la-rgw_client_io.Tpo rgw/$(DEPDIR)/librgw_la-rgw_client_io.Plo
- at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_client_io.cc' object='rgw/librgw_la-rgw_client_io.lo' libtool=yes @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librgw_la_CXXFLAGS) $(CXXFLAGS) -c -o rgw/librgw_la-rgw_client_io.lo `test -f 'rgw/rgw_client_io.cc' || echo '$(srcdir)/'`rgw/rgw_client_io.cc
-
-rgw/librgw_la-rgw_fcgi.lo: rgw/rgw_fcgi.cc
- at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librgw_la_CXXFLAGS) $(CXXFLAGS) -MT rgw/librgw_la-rgw_fcgi.lo -MD -MP -MF rgw/$(DEPDIR)/librgw_la-rgw_fcgi.Tpo -c -o rgw/librgw_la-rgw_fcgi.lo `test -f 'rgw/rgw_fcgi.cc' || echo '$(srcdir)/'`rgw/rgw_fcgi.cc
- at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/librgw_la-rgw_fcgi.Tpo rgw/$(DEPDIR)/librgw_la-rgw_fcgi.Plo
- at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_fcgi.cc' object='rgw/librgw_la-rgw_fcgi.lo' libtool=yes @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librgw_la_CXXFLAGS) $(CXXFLAGS) -c -o rgw/librgw_la-rgw_fcgi.lo `test -f 'rgw/rgw_fcgi.cc' || echo '$(srcdir)/'`rgw/rgw_fcgi.cc
-
-rgw/librgw_la-rgw_xml.lo: rgw/rgw_xml.cc
- at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librgw_la_CXXFLAGS) $(CXXFLAGS) -MT rgw/librgw_la-rgw_xml.lo -MD -MP -MF rgw/$(DEPDIR)/librgw_la-rgw_xml.Tpo -c -o rgw/librgw_la-rgw_xml.lo `test -f 'rgw/rgw_xml.cc' || echo '$(srcdir)/'`rgw/rgw_xml.cc
- at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/librgw_la-rgw_xml.Tpo rgw/$(DEPDIR)/librgw_la-rgw_xml.Plo
- at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_xml.cc' object='rgw/librgw_la-rgw_xml.lo' libtool=yes @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librgw_la_CXXFLAGS) $(CXXFLAGS) -c -o rgw/librgw_la-rgw_xml.lo `test -f 'rgw/rgw_xml.cc' || echo '$(srcdir)/'`rgw/rgw_xml.cc
-
-rgw/librgw_la-rgw_usage.lo: rgw/rgw_usage.cc
- at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librgw_la_CXXFLAGS) $(CXXFLAGS) -MT rgw/librgw_la-rgw_usage.lo -MD -MP -MF rgw/$(DEPDIR)/librgw_la-rgw_usage.Tpo -c -o rgw/librgw_la-rgw_usage.lo `test -f 'rgw/rgw_usage.cc' || echo '$(srcdir)/'`rgw/rgw_usage.cc
- at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/librgw_la-rgw_usage.Tpo rgw/$(DEPDIR)/librgw_la-rgw_usage.Plo
- at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_usage.cc' object='rgw/librgw_la-rgw_usage.lo' libtool=yes @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librgw_la_CXXFLAGS) $(CXXFLAGS) -c -o rgw/librgw_la-rgw_usage.lo `test -f 'rgw/rgw_usage.cc' || echo '$(srcdir)/'`rgw/rgw_usage.cc
-
-rgw/librgw_la-rgw_json_enc.lo: rgw/rgw_json_enc.cc
- at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librgw_la_CXXFLAGS) $(CXXFLAGS) -MT rgw/librgw_la-rgw_json_enc.lo -MD -MP -MF rgw/$(DEPDIR)/librgw_la-rgw_json_enc.Tpo -c -o rgw/librgw_la-rgw_json_enc.lo `test -f 'rgw/rgw_json_enc.cc' || echo '$(srcdir)/'`rgw/rgw_json_enc.cc
- at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/librgw_la-rgw_json_enc.Tpo rgw/$(DEPDIR)/librgw_la-rgw_json_enc.Plo
- at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_json_enc.cc' object='rgw/librgw_la-rgw_json_enc.lo' libtool=yes @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librgw_la_CXXFLAGS) $(CXXFLAGS) -c -o rgw/librgw_la-rgw_json_enc.lo `test -f 'rgw/rgw_json_enc.cc' || echo '$(srcdir)/'`rgw/rgw_json_enc.cc
-
-rgw/librgw_la-rgw_xml_enc.lo: rgw/rgw_xml_enc.cc
- at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librgw_la_CXXFLAGS) $(CXXFLAGS) -MT rgw/librgw_la-rgw_xml_enc.lo -MD -MP -MF rgw/$(DEPDIR)/librgw_la-rgw_xml_enc.Tpo -c -o rgw/librgw_la-rgw_xml_enc.lo `test -f 'rgw/rgw_xml_enc.cc' || echo '$(srcdir)/'`rgw/rgw_xml_enc.cc
- at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/librgw_la-rgw_xml_enc.Tpo rgw/$(DEPDIR)/librgw_la-rgw_xml_enc.Plo
- at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_xml_enc.cc' object='rgw/librgw_la-rgw_xml_enc.lo' libtool=yes @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librgw_la_CXXFLAGS) $(CXXFLAGS) -c -o rgw/librgw_la-rgw_xml_enc.lo `test -f 'rgw/rgw_xml_enc.cc' || echo '$(srcdir)/'`rgw/rgw_xml_enc.cc
-
-rgw/librgw_la-rgw_user.lo: rgw/rgw_user.cc
- at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librgw_la_CXXFLAGS) $(CXXFLAGS) -MT rgw/librgw_la-rgw_user.lo -MD -MP -MF rgw/$(DEPDIR)/librgw_la-rgw_user.Tpo -c -o rgw/librgw_la-rgw_user.lo `test -f 'rgw/rgw_user.cc' || echo '$(srcdir)/'`rgw/rgw_user.cc
- at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/librgw_la-rgw_user.Tpo rgw/$(DEPDIR)/librgw_la-rgw_user.Plo
- at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_user.cc' object='rgw/librgw_la-rgw_user.lo' libtool=yes @AMDEPBACKSLASH@
+rgw/librgw_la-rgw_coroutine.lo: rgw/rgw_coroutine.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librgw_la_CXXFLAGS) $(CXXFLAGS) -MT rgw/librgw_la-rgw_coroutine.lo -MD -MP -MF rgw/$(DEPDIR)/librgw_la-rgw_coroutine.Tpo -c -o rgw/librgw_la-rgw_coroutine.lo `test -f 'rgw/rgw_coroutine.cc' || echo '$(srcdir)/'`rgw/rgw_coroutine.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/librgw_la-rgw_coroutine.Tpo rgw/$(DEPDIR)/librgw_la-rgw_coroutine.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_coroutine.cc' object='rgw/librgw_la-rgw_coroutine.lo' libtool=yes @AMDEPBACKSLASH@
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librgw_la_CXXFLAGS) $(CXXFLAGS) -c -o rgw/librgw_la-rgw_user.lo `test -f 'rgw/rgw_user.cc' || echo '$(srcdir)/'`rgw/rgw_user.cc
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librgw_la_CXXFLAGS) $(CXXFLAGS) -c -o rgw/librgw_la-rgw_coroutine.lo `test -f 'rgw/rgw_coroutine.cc' || echo '$(srcdir)/'`rgw/rgw_coroutine.cc
 
-rgw/librgw_la-rgw_bucket.lo: rgw/rgw_bucket.cc
- at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librgw_la_CXXFLAGS) $(CXXFLAGS) -MT rgw/librgw_la-rgw_bucket.lo -MD -MP -MF rgw/$(DEPDIR)/librgw_la-rgw_bucket.Tpo -c -o rgw/librgw_la-rgw_bucket.lo `test -f 'rgw/rgw_bucket.cc' || echo '$(srcdir)/'`rgw/rgw_bucket.cc
- at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/librgw_la-rgw_bucket.Tpo rgw/$(DEPDIR)/librgw_la-rgw_bucket.Plo
- at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_bucket.cc' object='rgw/librgw_la-rgw_bucket.lo' libtool=yes @AMDEPBACKSLASH@
+rgw/librgw_la-rgw_cr_rados.lo: rgw/rgw_cr_rados.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librgw_la_CXXFLAGS) $(CXXFLAGS) -MT rgw/librgw_la-rgw_cr_rados.lo -MD -MP -MF rgw/$(DEPDIR)/librgw_la-rgw_cr_rados.Tpo -c -o rgw/librgw_la-rgw_cr_rados.lo `test -f 'rgw/rgw_cr_rados.cc' || echo '$(srcdir)/'`rgw/rgw_cr_rados.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/librgw_la-rgw_cr_rados.Tpo rgw/$(DEPDIR)/librgw_la-rgw_cr_rados.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_cr_rados.cc' object='rgw/librgw_la-rgw_cr_rados.lo' libtool=yes @AMDEPBACKSLASH@
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librgw_la_CXXFLAGS) $(CXXFLAGS) -c -o rgw/librgw_la-rgw_bucket.lo `test -f 'rgw/rgw_bucket.cc' || echo '$(srcdir)/'`rgw/rgw_bucket.cc
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librgw_la_CXXFLAGS) $(CXXFLAGS) -c -o rgw/librgw_la-rgw_cr_rados.lo `test -f 'rgw/rgw_cr_rados.cc' || echo '$(srcdir)/'`rgw/rgw_cr_rados.cc
 
 rgw/librgw_la-rgw_tools.lo: rgw/rgw_tools.cc
 @am__fastdepCXX_TRUE@	$(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librgw_la_CXXFLAGS) $(CXXFLAGS) -MT rgw/librgw_la-rgw_tools.lo -MD -MP -MF rgw/$(DEPDIR)/librgw_la-rgw_tools.Tpo -c -o rgw/librgw_la-rgw_tools.lo `test -f 'rgw/rgw_tools.cc' || echo '$(srcdir)/'`rgw/rgw_tools.cc
@@ -23098,41 +24045,6 @@ rgw/librgw_la-rgw_tools.lo: rgw/rgw_tools.cc
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librgw_la_CXXFLAGS) $(CXXFLAGS) -c -o rgw/librgw_la-rgw_tools.lo `test -f 'rgw/rgw_tools.cc' || echo '$(srcdir)/'`rgw/rgw_tools.cc
 
-rgw/librgw_la-rgw_rados.lo: rgw/rgw_rados.cc
- at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librgw_la_CXXFLAGS) $(CXXFLAGS) -MT rgw/librgw_la-rgw_rados.lo -MD -MP -MF rgw/$(DEPDIR)/librgw_la-rgw_rados.Tpo -c -o rgw/librgw_la-rgw_rados.lo `test -f 'rgw/rgw_rados.cc' || echo '$(srcdir)/'`rgw/rgw_rados.cc
- at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/librgw_la-rgw_rados.Tpo rgw/$(DEPDIR)/librgw_la-rgw_rados.Plo
- at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_rados.cc' object='rgw/librgw_la-rgw_rados.lo' libtool=yes @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librgw_la_CXXFLAGS) $(CXXFLAGS) -c -o rgw/librgw_la-rgw_rados.lo `test -f 'rgw/rgw_rados.cc' || echo '$(srcdir)/'`rgw/rgw_rados.cc
-
-rgw/librgw_la-rgw_http_client.lo: rgw/rgw_http_client.cc
- at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librgw_la_CXXFLAGS) $(CXXFLAGS) -MT rgw/librgw_la-rgw_http_client.lo -MD -MP -MF rgw/$(DEPDIR)/librgw_la-rgw_http_client.Tpo -c -o rgw/librgw_la-rgw_http_client.lo `test -f 'rgw/rgw_http_client.cc' || echo '$(srcdir)/'`rgw/rgw_http_client.cc
- at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/librgw_la-rgw_http_client.Tpo rgw/$(DEPDIR)/librgw_la-rgw_http_client.Plo
- at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_http_client.cc' object='rgw/librgw_la-rgw_http_client.lo' libtool=yes @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librgw_la_CXXFLAGS) $(CXXFLAGS) -c -o rgw/librgw_la-rgw_http_client.lo `test -f 'rgw/rgw_http_client.cc' || echo '$(srcdir)/'`rgw/rgw_http_client.cc
-
-rgw/librgw_la-rgw_rest_client.lo: rgw/rgw_rest_client.cc
- at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librgw_la_CXXFLAGS) $(CXXFLAGS) -MT rgw/librgw_la-rgw_rest_client.lo -MD -MP -MF rgw/$(DEPDIR)/librgw_la-rgw_rest_client.Tpo -c -o rgw/librgw_la-rgw_rest_client.lo `test -f 'rgw/rgw_rest_client.cc' || echo '$(srcdir)/'`rgw/rgw_rest_client.cc
- at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/librgw_la-rgw_rest_client.Tpo rgw/$(DEPDIR)/librgw_la-rgw_rest_client.Plo
- at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_rest_client.cc' object='rgw/librgw_la-rgw_rest_client.lo' libtool=yes @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librgw_la_CXXFLAGS) $(CXXFLAGS) -c -o rgw/librgw_la-rgw_rest_client.lo `test -f 'rgw/rgw_rest_client.cc' || echo '$(srcdir)/'`rgw/rgw_rest_client.cc
-
-rgw/librgw_la-rgw_rest_conn.lo: rgw/rgw_rest_conn.cc
- at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librgw_la_CXXFLAGS) $(CXXFLAGS) -MT rgw/librgw_la-rgw_rest_conn.lo -MD -MP -MF rgw/$(DEPDIR)/librgw_la-rgw_rest_conn.Tpo -c -o rgw/librgw_la-rgw_rest_conn.lo `test -f 'rgw/rgw_rest_conn.cc' || echo '$(srcdir)/'`rgw/rgw_rest_conn.cc
- at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/librgw_la-rgw_rest_conn.Tpo rgw/$(DEPDIR)/librgw_la-rgw_rest_conn.Plo
- at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_rest_conn.cc' object='rgw/librgw_la-rgw_rest_conn.lo' libtool=yes @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librgw_la_CXXFLAGS) $(CXXFLAGS) -c -o rgw/librgw_la-rgw_rest_conn.lo `test -f 'rgw/rgw_rest_conn.cc' || echo '$(srcdir)/'`rgw/rgw_rest_conn.cc
-
-rgw/librgw_la-rgw_op.lo: rgw/rgw_op.cc
- at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librgw_la_CXXFLAGS) $(CXXFLAGS) -MT rgw/librgw_la-rgw_op.lo -MD -MP -MF rgw/$(DEPDIR)/librgw_la-rgw_op.Tpo -c -o rgw/librgw_la-rgw_op.lo `test -f 'rgw/rgw_op.cc' || echo '$(srcdir)/'`rgw/rgw_op.cc
- at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/librgw_la-rgw_op.Tpo rgw/$(DEPDIR)/librgw_la-rgw_op.Plo
- at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_op.cc' object='rgw/librgw_la-rgw_op.lo' libtool=yes @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librgw_la_CXXFLAGS) $(CXXFLAGS) -c -o rgw/librgw_la-rgw_op.lo `test -f 'rgw/rgw_op.cc' || echo '$(srcdir)/'`rgw/rgw_op.cc
-
 rgw/librgw_la-rgw_basic_types.lo: rgw/rgw_basic_types.cc
 @am__fastdepCXX_TRUE@	$(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librgw_la_CXXFLAGS) $(CXXFLAGS) -MT rgw/librgw_la-rgw_basic_types.lo -MD -MP -MF rgw/$(DEPDIR)/librgw_la-rgw_basic_types.Tpo -c -o rgw/librgw_la-rgw_basic_types.lo `test -f 'rgw/rgw_basic_types.cc' || echo '$(srcdir)/'`rgw/rgw_basic_types.cc
 @am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/librgw_la-rgw_basic_types.Tpo rgw/$(DEPDIR)/librgw_la-rgw_basic_types.Plo
@@ -23140,12 +24052,12 @@ rgw/librgw_la-rgw_basic_types.lo: rgw/rgw_basic_types.cc
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librgw_la_CXXFLAGS) $(CXXFLAGS) -c -o rgw/librgw_la-rgw_basic_types.lo `test -f 'rgw/rgw_basic_types.cc' || echo '$(srcdir)/'`rgw/rgw_basic_types.cc
 
-rgw/librgw_la-rgw_common.lo: rgw/rgw_common.cc
- at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librgw_la_CXXFLAGS) $(CXXFLAGS) -MT rgw/librgw_la-rgw_common.lo -MD -MP -MF rgw/$(DEPDIR)/librgw_la-rgw_common.Tpo -c -o rgw/librgw_la-rgw_common.lo `test -f 'rgw/rgw_common.cc' || echo '$(srcdir)/'`rgw/rgw_common.cc
- at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/librgw_la-rgw_common.Tpo rgw/$(DEPDIR)/librgw_la-rgw_common.Plo
- at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_common.cc' object='rgw/librgw_la-rgw_common.lo' libtool=yes @AMDEPBACKSLASH@
+rgw/librgw_la-rgw_bucket.lo: rgw/rgw_bucket.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librgw_la_CXXFLAGS) $(CXXFLAGS) -MT rgw/librgw_la-rgw_bucket.lo -MD -MP -MF rgw/$(DEPDIR)/librgw_la-rgw_bucket.Tpo -c -o rgw/librgw_la-rgw_bucket.lo `test -f 'rgw/rgw_bucket.cc' || echo '$(srcdir)/'`rgw/rgw_bucket.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/librgw_la-rgw_bucket.Tpo rgw/$(DEPDIR)/librgw_la-rgw_bucket.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_bucket.cc' object='rgw/librgw_la-rgw_bucket.lo' libtool=yes @AMDEPBACKSLASH@
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librgw_la_CXXFLAGS) $(CXXFLAGS) -c -o rgw/librgw_la-rgw_common.lo `test -f 'rgw/rgw_common.cc' || echo '$(srcdir)/'`rgw/rgw_common.cc
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librgw_la_CXXFLAGS) $(CXXFLAGS) -c -o rgw/librgw_la-rgw_bucket.lo `test -f 'rgw/rgw_bucket.cc' || echo '$(srcdir)/'`rgw/rgw_bucket.cc
 
 rgw/librgw_la-rgw_cache.lo: rgw/rgw_cache.cc
 @am__fastdepCXX_TRUE@	$(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librgw_la_CXXFLAGS) $(CXXFLAGS) -MT rgw/librgw_la-rgw_cache.lo -MD -MP -MF rgw/$(DEPDIR)/librgw_la-rgw_cache.Tpo -c -o rgw/librgw_la-rgw_cache.lo `test -f 'rgw/rgw_cache.cc' || echo '$(srcdir)/'`rgw/rgw_cache.cc
@@ -23154,13 +24066,104 @@ rgw/librgw_la-rgw_cache.lo: rgw/rgw_cache.cc
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librgw_la_CXXFLAGS) $(CXXFLAGS) -c -o rgw/librgw_la-rgw_cache.lo `test -f 'rgw/rgw_cache.cc' || echo '$(srcdir)/'`rgw/rgw_cache.cc
 
-rgw/librgw_la-rgw_formats.lo: rgw/rgw_formats.cc
- at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librgw_la_CXXFLAGS) $(CXXFLAGS) -MT rgw/librgw_la-rgw_formats.lo -MD -MP -MF rgw/$(DEPDIR)/librgw_la-rgw_formats.Tpo -c -o rgw/librgw_la-rgw_formats.lo `test -f 'rgw/rgw_formats.cc' || echo '$(srcdir)/'`rgw/rgw_formats.cc
- at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/librgw_la-rgw_formats.Tpo rgw/$(DEPDIR)/librgw_la-rgw_formats.Plo
- at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_formats.cc' object='rgw/librgw_la-rgw_formats.lo' libtool=yes @AMDEPBACKSLASH@
+rgw/librgw_la-rgw_client_io.lo: rgw/rgw_client_io.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librgw_la_CXXFLAGS) $(CXXFLAGS) -MT rgw/librgw_la-rgw_client_io.lo -MD -MP -MF rgw/$(DEPDIR)/librgw_la-rgw_client_io.Tpo -c -o rgw/librgw_la-rgw_client_io.lo `test -f 'rgw/rgw_client_io.cc' || echo '$(srcdir)/'`rgw/rgw_client_io.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/librgw_la-rgw_client_io.Tpo rgw/$(DEPDIR)/librgw_la-rgw_client_io.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_client_io.cc' object='rgw/librgw_la-rgw_client_io.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librgw_la_CXXFLAGS) $(CXXFLAGS) -c -o rgw/librgw_la-rgw_client_io.lo `test -f 'rgw/rgw_client_io.cc' || echo '$(srcdir)/'`rgw/rgw_client_io.cc
+
+rgw/librgw_la-rgw_common.lo: rgw/rgw_common.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librgw_la_CXXFLAGS) $(CXXFLAGS) -MT rgw/librgw_la-rgw_common.lo -MD -MP -MF rgw/$(DEPDIR)/librgw_la-rgw_common.Tpo -c -o rgw/librgw_la-rgw_common.lo `test -f 'rgw/rgw_common.cc' || echo '$(srcdir)/'`rgw/rgw_common.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/librgw_la-rgw_common.Tpo rgw/$(DEPDIR)/librgw_la-rgw_common.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_common.cc' object='rgw/librgw_la-rgw_common.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librgw_la_CXXFLAGS) $(CXXFLAGS) -c -o rgw/librgw_la-rgw_common.lo `test -f 'rgw/rgw_common.cc' || echo '$(srcdir)/'`rgw/rgw_common.cc
+
+rgw/librgw_la-rgw_cors.lo: rgw/rgw_cors.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librgw_la_CXXFLAGS) $(CXXFLAGS) -MT rgw/librgw_la-rgw_cors.lo -MD -MP -MF rgw/$(DEPDIR)/librgw_la-rgw_cors.Tpo -c -o rgw/librgw_la-rgw_cors.lo `test -f 'rgw/rgw_cors.cc' || echo '$(srcdir)/'`rgw/rgw_cors.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/librgw_la-rgw_cors.Tpo rgw/$(DEPDIR)/librgw_la-rgw_cors.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_cors.cc' object='rgw/librgw_la-rgw_cors.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librgw_la_CXXFLAGS) $(CXXFLAGS) -c -o rgw/librgw_la-rgw_cors.lo `test -f 'rgw/rgw_cors.cc' || echo '$(srcdir)/'`rgw/rgw_cors.cc
+
+rgw/librgw_la-rgw_cors_s3.lo: rgw/rgw_cors_s3.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librgw_la_CXXFLAGS) $(CXXFLAGS) -MT rgw/librgw_la-rgw_cors_s3.lo -MD -MP -MF rgw/$(DEPDIR)/librgw_la-rgw_cors_s3.Tpo -c -o rgw/librgw_la-rgw_cors_s3.lo `test -f 'rgw/rgw_cors_s3.cc' || echo '$(srcdir)/'`rgw/rgw_cors_s3.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/librgw_la-rgw_cors_s3.Tpo rgw/$(DEPDIR)/librgw_la-rgw_cors_s3.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_cors_s3.cc' object='rgw/librgw_la-rgw_cors_s3.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librgw_la_CXXFLAGS) $(CXXFLAGS) -c -o rgw/librgw_la-rgw_cors_s3.lo `test -f 'rgw/rgw_cors_s3.cc' || echo '$(srcdir)/'`rgw/rgw_cors_s3.cc
+
+rgw/librgw_la-rgw_dencoder.lo: rgw/rgw_dencoder.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librgw_la_CXXFLAGS) $(CXXFLAGS) -MT rgw/librgw_la-rgw_dencoder.lo -MD -MP -MF rgw/$(DEPDIR)/librgw_la-rgw_dencoder.Tpo -c -o rgw/librgw_la-rgw_dencoder.lo `test -f 'rgw/rgw_dencoder.cc' || echo '$(srcdir)/'`rgw/rgw_dencoder.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/librgw_la-rgw_dencoder.Tpo rgw/$(DEPDIR)/librgw_la-rgw_dencoder.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_dencoder.cc' object='rgw/librgw_la-rgw_dencoder.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librgw_la_CXXFLAGS) $(CXXFLAGS) -c -o rgw/librgw_la-rgw_dencoder.lo `test -f 'rgw/rgw_dencoder.cc' || echo '$(srcdir)/'`rgw/rgw_dencoder.cc
+
+rgw/librgw_la-rgw_env.lo: rgw/rgw_env.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librgw_la_CXXFLAGS) $(CXXFLAGS) -MT rgw/librgw_la-rgw_env.lo -MD -MP -MF rgw/$(DEPDIR)/librgw_la-rgw_env.Tpo -c -o rgw/librgw_la-rgw_env.lo `test -f 'rgw/rgw_env.cc' || echo '$(srcdir)/'`rgw/rgw_env.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/librgw_la-rgw_env.Tpo rgw/$(DEPDIR)/librgw_la-rgw_env.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_env.cc' object='rgw/librgw_la-rgw_env.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librgw_la_CXXFLAGS) $(CXXFLAGS) -c -o rgw/librgw_la-rgw_env.lo `test -f 'rgw/rgw_env.cc' || echo '$(srcdir)/'`rgw/rgw_env.cc
+
+rgw/librgw_la-rgw_fcgi.lo: rgw/rgw_fcgi.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librgw_la_CXXFLAGS) $(CXXFLAGS) -MT rgw/librgw_la-rgw_fcgi.lo -MD -MP -MF rgw/$(DEPDIR)/librgw_la-rgw_fcgi.Tpo -c -o rgw/librgw_la-rgw_fcgi.lo `test -f 'rgw/rgw_fcgi.cc' || echo '$(srcdir)/'`rgw/rgw_fcgi.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/librgw_la-rgw_fcgi.Tpo rgw/$(DEPDIR)/librgw_la-rgw_fcgi.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_fcgi.cc' object='rgw/librgw_la-rgw_fcgi.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librgw_la_CXXFLAGS) $(CXXFLAGS) -c -o rgw/librgw_la-rgw_fcgi.lo `test -f 'rgw/rgw_fcgi.cc' || echo '$(srcdir)/'`rgw/rgw_fcgi.cc
+
+rgw/librgw_la-rgw_formats.lo: rgw/rgw_formats.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librgw_la_CXXFLAGS) $(CXXFLAGS) -MT rgw/librgw_la-rgw_formats.lo -MD -MP -MF rgw/$(DEPDIR)/librgw_la-rgw_formats.Tpo -c -o rgw/librgw_la-rgw_formats.lo `test -f 'rgw/rgw_formats.cc' || echo '$(srcdir)/'`rgw/rgw_formats.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/librgw_la-rgw_formats.Tpo rgw/$(DEPDIR)/librgw_la-rgw_formats.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_formats.cc' object='rgw/librgw_la-rgw_formats.lo' libtool=yes @AMDEPBACKSLASH@
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librgw_la_CXXFLAGS) $(CXXFLAGS) -c -o rgw/librgw_la-rgw_formats.lo `test -f 'rgw/rgw_formats.cc' || echo '$(srcdir)/'`rgw/rgw_formats.cc
 
+rgw/librgw_la-rgw_frontend.lo: rgw/rgw_frontend.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librgw_la_CXXFLAGS) $(CXXFLAGS) -MT rgw/librgw_la-rgw_frontend.lo -MD -MP -MF rgw/$(DEPDIR)/librgw_la-rgw_frontend.Tpo -c -o rgw/librgw_la-rgw_frontend.lo `test -f 'rgw/rgw_frontend.cc' || echo '$(srcdir)/'`rgw/rgw_frontend.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/librgw_la-rgw_frontend.Tpo rgw/$(DEPDIR)/librgw_la-rgw_frontend.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_frontend.cc' object='rgw/librgw_la-rgw_frontend.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librgw_la_CXXFLAGS) $(CXXFLAGS) -c -o rgw/librgw_la-rgw_frontend.lo `test -f 'rgw/rgw_frontend.cc' || echo '$(srcdir)/'`rgw/rgw_frontend.cc
+
+rgw/librgw_la-rgw_gc.lo: rgw/rgw_gc.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librgw_la_CXXFLAGS) $(CXXFLAGS) -MT rgw/librgw_la-rgw_gc.lo -MD -MP -MF rgw/$(DEPDIR)/librgw_la-rgw_gc.Tpo -c -o rgw/librgw_la-rgw_gc.lo `test -f 'rgw/rgw_gc.cc' || echo '$(srcdir)/'`rgw/rgw_gc.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/librgw_la-rgw_gc.Tpo rgw/$(DEPDIR)/librgw_la-rgw_gc.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_gc.cc' object='rgw/librgw_la-rgw_gc.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librgw_la_CXXFLAGS) $(CXXFLAGS) -c -o rgw/librgw_la-rgw_gc.lo `test -f 'rgw/rgw_gc.cc' || echo '$(srcdir)/'`rgw/rgw_gc.cc
+
+rgw/librgw_la-rgw_http_client.lo: rgw/rgw_http_client.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librgw_la_CXXFLAGS) $(CXXFLAGS) -MT rgw/librgw_la-rgw_http_client.lo -MD -MP -MF rgw/$(DEPDIR)/librgw_la-rgw_http_client.Tpo -c -o rgw/librgw_la-rgw_http_client.lo `test -f 'rgw/rgw_http_client.cc' || echo '$(srcdir)/'`rgw/rgw_http_client.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/librgw_la-rgw_http_client.Tpo rgw/$(DEPDIR)/librgw_la-rgw_http_client.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_http_client.cc' object='rgw/librgw_la-rgw_http_client.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librgw_la_CXXFLAGS) $(CXXFLAGS) -c -o rgw/librgw_la-rgw_http_client.lo `test -f 'rgw/rgw_http_client.cc' || echo '$(srcdir)/'`rgw/rgw_http_client.cc
+
+rgw/librgw_la-rgw_json_enc.lo: rgw/rgw_json_enc.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librgw_la_CXXFLAGS) $(CXXFLAGS) -MT rgw/librgw_la-rgw_json_enc.lo -MD -MP -MF rgw/$(DEPDIR)/librgw_la-rgw_json_enc.Tpo -c -o rgw/librgw_la-rgw_json_enc.lo `test -f 'rgw/rgw_json_enc.cc' || echo '$(srcdir)/'`rgw/rgw_json_enc.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/librgw_la-rgw_json_enc.Tpo rgw/$(DEPDIR)/librgw_la-rgw_json_enc.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_json_enc.cc' object='rgw/librgw_la-rgw_json_enc.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librgw_la_CXXFLAGS) $(CXXFLAGS) -c -o rgw/librgw_la-rgw_json_enc.lo `test -f 'rgw/rgw_json_enc.cc' || echo '$(srcdir)/'`rgw/rgw_json_enc.cc
+
+rgw/librgw_la-rgw_keystone.lo: rgw/rgw_keystone.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librgw_la_CXXFLAGS) $(CXXFLAGS) -MT rgw/librgw_la-rgw_keystone.lo -MD -MP -MF rgw/$(DEPDIR)/librgw_la-rgw_keystone.Tpo -c -o rgw/librgw_la-rgw_keystone.lo `test -f 'rgw/rgw_keystone.cc' || echo '$(srcdir)/'`rgw/rgw_keystone.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/librgw_la-rgw_keystone.Tpo rgw/$(DEPDIR)/librgw_la-rgw_keystone.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_keystone.cc' object='rgw/librgw_la-rgw_keystone.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librgw_la_CXXFLAGS) $(CXXFLAGS) -c -o rgw/librgw_la-rgw_keystone.lo `test -f 'rgw/rgw_keystone.cc' || echo '$(srcdir)/'`rgw/rgw_keystone.cc
+
+rgw/librgw_la-rgw_loadgen.lo: rgw/rgw_loadgen.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librgw_la_CXXFLAGS) $(CXXFLAGS) -MT rgw/librgw_la-rgw_loadgen.lo -MD -MP -MF rgw/$(DEPDIR)/librgw_la-rgw_loadgen.Tpo -c -o rgw/librgw_la-rgw_loadgen.lo `test -f 'rgw/rgw_loadgen.cc' || echo '$(srcdir)/'`rgw/rgw_loadgen.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/librgw_la-rgw_loadgen.Tpo rgw/$(DEPDIR)/librgw_la-rgw_loadgen.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_loadgen.cc' object='rgw/librgw_la-rgw_loadgen.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librgw_la_CXXFLAGS) $(CXXFLAGS) -c -o rgw/librgw_la-rgw_loadgen.lo `test -f 'rgw/rgw_loadgen.cc' || echo '$(srcdir)/'`rgw/rgw_loadgen.cc
+
 rgw/librgw_la-rgw_log.lo: rgw/rgw_log.cc
 @am__fastdepCXX_TRUE@	$(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librgw_la_CXXFLAGS) $(CXXFLAGS) -MT rgw/librgw_la-rgw_log.lo -MD -MP -MF rgw/$(DEPDIR)/librgw_la-rgw_log.Tpo -c -o rgw/librgw_la-rgw_log.lo `test -f 'rgw/rgw_log.cc' || echo '$(srcdir)/'`rgw/rgw_log.cc
 @am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/librgw_la-rgw_log.Tpo rgw/$(DEPDIR)/librgw_la-rgw_log.Plo
@@ -23168,6 +24171,13 @@ rgw/librgw_la-rgw_log.lo: rgw/rgw_log.cc
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librgw_la_CXXFLAGS) $(CXXFLAGS) -c -o rgw/librgw_la-rgw_log.lo `test -f 'rgw/rgw_log.cc' || echo '$(srcdir)/'`rgw/rgw_log.cc
 
+rgw/librgw_la-rgw_metadata.lo: rgw/rgw_metadata.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librgw_la_CXXFLAGS) $(CXXFLAGS) -MT rgw/librgw_la-rgw_metadata.lo -MD -MP -MF rgw/$(DEPDIR)/librgw_la-rgw_metadata.Tpo -c -o rgw/librgw_la-rgw_metadata.lo `test -f 'rgw/rgw_metadata.cc' || echo '$(srcdir)/'`rgw/rgw_metadata.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/librgw_la-rgw_metadata.Tpo rgw/$(DEPDIR)/librgw_la-rgw_metadata.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_metadata.cc' object='rgw/librgw_la-rgw_metadata.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librgw_la_CXXFLAGS) $(CXXFLAGS) -c -o rgw/librgw_la-rgw_metadata.lo `test -f 'rgw/rgw_metadata.cc' || echo '$(srcdir)/'`rgw/rgw_metadata.cc
+
 rgw/librgw_la-rgw_multi.lo: rgw/rgw_multi.cc
 @am__fastdepCXX_TRUE@	$(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librgw_la_CXXFLAGS) $(CXXFLAGS) -MT rgw/librgw_la-rgw_multi.lo -MD -MP -MF rgw/$(DEPDIR)/librgw_la-rgw_multi.Tpo -c -o rgw/librgw_la-rgw_multi.lo `test -f 'rgw/rgw_multi.cc' || echo '$(srcdir)/'`rgw/rgw_multi.cc
 @am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/librgw_la-rgw_multi.Tpo rgw/$(DEPDIR)/librgw_la-rgw_multi.Plo
@@ -23175,20 +24185,6 @@ rgw/librgw_la-rgw_multi.lo: rgw/rgw_multi.cc
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librgw_la_CXXFLAGS) $(CXXFLAGS) -c -o rgw/librgw_la-rgw_multi.lo `test -f 'rgw/rgw_multi.cc' || echo '$(srcdir)/'`rgw/rgw_multi.cc
 
-rgw/librgw_la-rgw_policy_s3.lo: rgw/rgw_policy_s3.cc
- at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librgw_la_CXXFLAGS) $(CXXFLAGS) -MT rgw/librgw_la-rgw_policy_s3.lo -MD -MP -MF rgw/$(DEPDIR)/librgw_la-rgw_policy_s3.Tpo -c -o rgw/librgw_la-rgw_policy_s3.lo `test -f 'rgw/rgw_policy_s3.cc' || echo '$(srcdir)/'`rgw/rgw_policy_s3.cc
- at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/librgw_la-rgw_policy_s3.Tpo rgw/$(DEPDIR)/librgw_la-rgw_policy_s3.Plo
- at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_policy_s3.cc' object='rgw/librgw_la-rgw_policy_s3.lo' libtool=yes @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librgw_la_CXXFLAGS) $(CXXFLAGS) -c -o rgw/librgw_la-rgw_policy_s3.lo `test -f 'rgw/rgw_policy_s3.cc' || echo '$(srcdir)/'`rgw/rgw_policy_s3.cc
-
-rgw/librgw_la-rgw_gc.lo: rgw/rgw_gc.cc
- at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librgw_la_CXXFLAGS) $(CXXFLAGS) -MT rgw/librgw_la-rgw_gc.lo -MD -MP -MF rgw/$(DEPDIR)/librgw_la-rgw_gc.Tpo -c -o rgw/librgw_la-rgw_gc.lo `test -f 'rgw/rgw_gc.cc' || echo '$(srcdir)/'`rgw/rgw_gc.cc
- at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/librgw_la-rgw_gc.Tpo rgw/$(DEPDIR)/librgw_la-rgw_gc.Plo
- at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_gc.cc' object='rgw/librgw_la-rgw_gc.lo' libtool=yes @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librgw_la_CXXFLAGS) $(CXXFLAGS) -c -o rgw/librgw_la-rgw_gc.lo `test -f 'rgw/rgw_gc.cc' || echo '$(srcdir)/'`rgw/rgw_gc.cc
-
 rgw/librgw_la-rgw_multi_del.lo: rgw/rgw_multi_del.cc
 @am__fastdepCXX_TRUE@	$(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librgw_la_CXXFLAGS) $(CXXFLAGS) -MT rgw/librgw_la-rgw_multi_del.lo -MD -MP -MF rgw/$(DEPDIR)/librgw_la-rgw_multi_del.Tpo -c -o rgw/librgw_la-rgw_multi_del.lo `test -f 'rgw/rgw_multi_del.cc' || echo '$(srcdir)/'`rgw/rgw_multi_del.cc
 @am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/librgw_la-rgw_multi_del.Tpo rgw/$(DEPDIR)/librgw_la-rgw_multi_del.Plo
@@ -23196,27 +24192,6 @@ rgw/librgw_la-rgw_multi_del.lo: rgw/rgw_multi_del.cc
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librgw_la_CXXFLAGS) $(CXXFLAGS) -c -o rgw/librgw_la-rgw_multi_del.lo `test -f 'rgw/rgw_multi_del.cc' || echo '$(srcdir)/'`rgw/rgw_multi_del.cc
 
-rgw/librgw_la-rgw_env.lo: rgw/rgw_env.cc
- at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librgw_la_CXXFLAGS) $(CXXFLAGS) -MT rgw/librgw_la-rgw_env.lo -MD -MP -MF rgw/$(DEPDIR)/librgw_la-rgw_env.Tpo -c -o rgw/librgw_la-rgw_env.lo `test -f 'rgw/rgw_env.cc' || echo '$(srcdir)/'`rgw/rgw_env.cc
- at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/librgw_la-rgw_env.Tpo rgw/$(DEPDIR)/librgw_la-rgw_env.Plo
- at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_env.cc' object='rgw/librgw_la-rgw_env.lo' libtool=yes @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librgw_la_CXXFLAGS) $(CXXFLAGS) -c -o rgw/librgw_la-rgw_env.lo `test -f 'rgw/rgw_env.cc' || echo '$(srcdir)/'`rgw/rgw_env.cc
-
-rgw/librgw_la-rgw_cors.lo: rgw/rgw_cors.cc
- at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librgw_la_CXXFLAGS) $(CXXFLAGS) -MT rgw/librgw_la-rgw_cors.lo -MD -MP -MF rgw/$(DEPDIR)/librgw_la-rgw_cors.Tpo -c -o rgw/librgw_la-rgw_cors.lo `test -f 'rgw/rgw_cors.cc' || echo '$(srcdir)/'`rgw/rgw_cors.cc
- at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/librgw_la-rgw_cors.Tpo rgw/$(DEPDIR)/librgw_la-rgw_cors.Plo
- at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_cors.cc' object='rgw/librgw_la-rgw_cors.lo' libtool=yes @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librgw_la_CXXFLAGS) $(CXXFLAGS) -c -o rgw/librgw_la-rgw_cors.lo `test -f 'rgw/rgw_cors.cc' || echo '$(srcdir)/'`rgw/rgw_cors.cc
-
-rgw/librgw_la-rgw_cors_s3.lo: rgw/rgw_cors_s3.cc
- at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librgw_la_CXXFLAGS) $(CXXFLAGS) -MT rgw/librgw_la-rgw_cors_s3.lo -MD -MP -MF rgw/$(DEPDIR)/librgw_la-rgw_cors_s3.Tpo -c -o rgw/librgw_la-rgw_cors_s3.lo `test -f 'rgw/rgw_cors_s3.cc' || echo '$(srcdir)/'`rgw/rgw_cors_s3.cc
- at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/librgw_la-rgw_cors_s3.Tpo rgw/$(DEPDIR)/librgw_la-rgw_cors_s3.Plo
- at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_cors_s3.cc' object='rgw/librgw_la-rgw_cors_s3.lo' libtool=yes @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librgw_la_CXXFLAGS) $(CXXFLAGS) -c -o rgw/librgw_la-rgw_cors_s3.lo `test -f 'rgw/rgw_cors_s3.cc' || echo '$(srcdir)/'`rgw/rgw_cors_s3.cc
-
 rgw/librgw_la-rgw_auth_s3.lo: rgw/rgw_auth_s3.cc
 @am__fastdepCXX_TRUE@	$(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librgw_la_CXXFLAGS) $(CXXFLAGS) -MT rgw/librgw_la-rgw_auth_s3.lo -MD -MP -MF rgw/$(DEPDIR)/librgw_la-rgw_auth_s3.Tpo -c -o rgw/librgw_la-rgw_auth_s3.lo `test -f 'rgw/rgw_auth_s3.cc' || echo '$(srcdir)/'`rgw/rgw_auth_s3.cc
 @am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/librgw_la-rgw_auth_s3.Tpo rgw/$(DEPDIR)/librgw_la-rgw_auth_s3.Plo
@@ -23224,40 +24199,54 @@ rgw/librgw_la-rgw_auth_s3.lo: rgw/rgw_auth_s3.cc
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librgw_la_CXXFLAGS) $(CXXFLAGS) -c -o rgw/librgw_la-rgw_auth_s3.lo `test -f 'rgw/rgw_auth_s3.cc' || echo '$(srcdir)/'`rgw/rgw_auth_s3.cc
 
-rgw/librgw_la-rgw_metadata.lo: rgw/rgw_metadata.cc
- at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librgw_la_CXXFLAGS) $(CXXFLAGS) -MT rgw/librgw_la-rgw_metadata.lo -MD -MP -MF rgw/$(DEPDIR)/librgw_la-rgw_metadata.Tpo -c -o rgw/librgw_la-rgw_metadata.lo `test -f 'rgw/rgw_metadata.cc' || echo '$(srcdir)/'`rgw/rgw_metadata.cc
- at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/librgw_la-rgw_metadata.Tpo rgw/$(DEPDIR)/librgw_la-rgw_metadata.Plo
- at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_metadata.cc' object='rgw/librgw_la-rgw_metadata.lo' libtool=yes @AMDEPBACKSLASH@
+rgw/librgw_la-rgw_period_history.lo: rgw/rgw_period_history.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librgw_la_CXXFLAGS) $(CXXFLAGS) -MT rgw/librgw_la-rgw_period_history.lo -MD -MP -MF rgw/$(DEPDIR)/librgw_la-rgw_period_history.Tpo -c -o rgw/librgw_la-rgw_period_history.lo `test -f 'rgw/rgw_period_history.cc' || echo '$(srcdir)/'`rgw/rgw_period_history.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/librgw_la-rgw_period_history.Tpo rgw/$(DEPDIR)/librgw_la-rgw_period_history.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_period_history.cc' object='rgw/librgw_la-rgw_period_history.lo' libtool=yes @AMDEPBACKSLASH@
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librgw_la_CXXFLAGS) $(CXXFLAGS) -c -o rgw/librgw_la-rgw_metadata.lo `test -f 'rgw/rgw_metadata.cc' || echo '$(srcdir)/'`rgw/rgw_metadata.cc
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librgw_la_CXXFLAGS) $(CXXFLAGS) -c -o rgw/librgw_la-rgw_period_history.lo `test -f 'rgw/rgw_period_history.cc' || echo '$(srcdir)/'`rgw/rgw_period_history.cc
 
-rgw/librgw_la-rgw_replica_log.lo: rgw/rgw_replica_log.cc
- at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librgw_la_CXXFLAGS) $(CXXFLAGS) -MT rgw/librgw_la-rgw_replica_log.lo -MD -MP -MF rgw/$(DEPDIR)/librgw_la-rgw_replica_log.Tpo -c -o rgw/librgw_la-rgw_replica_log.lo `test -f 'rgw/rgw_replica_log.cc' || echo '$(srcdir)/'`rgw/rgw_replica_log.cc
- at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/librgw_la-rgw_replica_log.Tpo rgw/$(DEPDIR)/librgw_la-rgw_replica_log.Plo
- at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_replica_log.cc' object='rgw/librgw_la-rgw_replica_log.lo' libtool=yes @AMDEPBACKSLASH@
+rgw/librgw_la-rgw_period_puller.lo: rgw/rgw_period_puller.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librgw_la_CXXFLAGS) $(CXXFLAGS) -MT rgw/librgw_la-rgw_period_puller.lo -MD -MP -MF rgw/$(DEPDIR)/librgw_la-rgw_period_puller.Tpo -c -o rgw/librgw_la-rgw_period_puller.lo `test -f 'rgw/rgw_period_puller.cc' || echo '$(srcdir)/'`rgw/rgw_period_puller.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/librgw_la-rgw_period_puller.Tpo rgw/$(DEPDIR)/librgw_la-rgw_period_puller.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_period_puller.cc' object='rgw/librgw_la-rgw_period_puller.lo' libtool=yes @AMDEPBACKSLASH@
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librgw_la_CXXFLAGS) $(CXXFLAGS) -c -o rgw/librgw_la-rgw_replica_log.lo `test -f 'rgw/rgw_replica_log.cc' || echo '$(srcdir)/'`rgw/rgw_replica_log.cc
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librgw_la_CXXFLAGS) $(CXXFLAGS) -c -o rgw/librgw_la-rgw_period_puller.lo `test -f 'rgw/rgw_period_puller.cc' || echo '$(srcdir)/'`rgw/rgw_period_puller.cc
 
-rgw/librgw_la-rgw_keystone.lo: rgw/rgw_keystone.cc
- at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librgw_la_CXXFLAGS) $(CXXFLAGS) -MT rgw/librgw_la-rgw_keystone.lo -MD -MP -MF rgw/$(DEPDIR)/librgw_la-rgw_keystone.Tpo -c -o rgw/librgw_la-rgw_keystone.lo `test -f 'rgw/rgw_keystone.cc' || echo '$(srcdir)/'`rgw/rgw_keystone.cc
- at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/librgw_la-rgw_keystone.Tpo rgw/$(DEPDIR)/librgw_la-rgw_keystone.Plo
- at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_keystone.cc' object='rgw/librgw_la-rgw_keystone.lo' libtool=yes @AMDEPBACKSLASH@
+rgw/librgw_la-rgw_period_pusher.lo: rgw/rgw_period_pusher.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librgw_la_CXXFLAGS) $(CXXFLAGS) -MT rgw/librgw_la-rgw_period_pusher.lo -MD -MP -MF rgw/$(DEPDIR)/librgw_la-rgw_period_pusher.Tpo -c -o rgw/librgw_la-rgw_period_pusher.lo `test -f 'rgw/rgw_period_pusher.cc' || echo '$(srcdir)/'`rgw/rgw_period_pusher.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/librgw_la-rgw_period_pusher.Tpo rgw/$(DEPDIR)/librgw_la-rgw_period_pusher.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_period_pusher.cc' object='rgw/librgw_la-rgw_period_pusher.lo' libtool=yes @AMDEPBACKSLASH@
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librgw_la_CXXFLAGS) $(CXXFLAGS) -c -o rgw/librgw_la-rgw_keystone.lo `test -f 'rgw/rgw_keystone.cc' || echo '$(srcdir)/'`rgw/rgw_keystone.cc
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librgw_la_CXXFLAGS) $(CXXFLAGS) -c -o rgw/librgw_la-rgw_period_pusher.lo `test -f 'rgw/rgw_period_pusher.cc' || echo '$(srcdir)/'`rgw/rgw_period_pusher.cc
 
-rgw/librgw_la-rgw_quota.lo: rgw/rgw_quota.cc
- at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librgw_la_CXXFLAGS) $(CXXFLAGS) -MT rgw/librgw_la-rgw_quota.lo -MD -MP -MF rgw/$(DEPDIR)/librgw_la-rgw_quota.Tpo -c -o rgw/librgw_la-rgw_quota.lo `test -f 'rgw/rgw_quota.cc' || echo '$(srcdir)/'`rgw/rgw_quota.cc
- at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/librgw_la-rgw_quota.Tpo rgw/$(DEPDIR)/librgw_la-rgw_quota.Plo
- at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_quota.cc' object='rgw/librgw_la-rgw_quota.lo' libtool=yes @AMDEPBACKSLASH@
+rgw/librgw_la-rgw_realm_reloader.lo: rgw/rgw_realm_reloader.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librgw_la_CXXFLAGS) $(CXXFLAGS) -MT rgw/librgw_la-rgw_realm_reloader.lo -MD -MP -MF rgw/$(DEPDIR)/librgw_la-rgw_realm_reloader.Tpo -c -o rgw/librgw_la-rgw_realm_reloader.lo `test -f 'rgw/rgw_realm_reloader.cc' || echo '$(srcdir)/'`rgw/rgw_realm_reloader.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/librgw_la-rgw_realm_reloader.Tpo rgw/$(DEPDIR)/librgw_la-rgw_realm_reloader.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_realm_reloader.cc' object='rgw/librgw_la-rgw_realm_reloader.lo' libtool=yes @AMDEPBACKSLASH@
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librgw_la_CXXFLAGS) $(CXXFLAGS) -c -o rgw/librgw_la-rgw_quota.lo `test -f 'rgw/rgw_quota.cc' || echo '$(srcdir)/'`rgw/rgw_quota.cc
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librgw_la_CXXFLAGS) $(CXXFLAGS) -c -o rgw/librgw_la-rgw_realm_reloader.lo `test -f 'rgw/rgw_realm_reloader.cc' || echo '$(srcdir)/'`rgw/rgw_realm_reloader.cc
 
-rgw/librgw_la-rgw_dencoder.lo: rgw/rgw_dencoder.cc
- at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librgw_la_CXXFLAGS) $(CXXFLAGS) -MT rgw/librgw_la-rgw_dencoder.lo -MD -MP -MF rgw/$(DEPDIR)/librgw_la-rgw_dencoder.Tpo -c -o rgw/librgw_la-rgw_dencoder.lo `test -f 'rgw/rgw_dencoder.cc' || echo '$(srcdir)/'`rgw/rgw_dencoder.cc
- at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/librgw_la-rgw_dencoder.Tpo rgw/$(DEPDIR)/librgw_la-rgw_dencoder.Plo
- at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_dencoder.cc' object='rgw/librgw_la-rgw_dencoder.lo' libtool=yes @AMDEPBACKSLASH@
+rgw/librgw_la-rgw_realm_watcher.lo: rgw/rgw_realm_watcher.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librgw_la_CXXFLAGS) $(CXXFLAGS) -MT rgw/librgw_la-rgw_realm_watcher.lo -MD -MP -MF rgw/$(DEPDIR)/librgw_la-rgw_realm_watcher.Tpo -c -o rgw/librgw_la-rgw_realm_watcher.lo `test -f 'rgw/rgw_realm_watcher.cc' || echo '$(srcdir)/'`rgw/rgw_realm_watcher.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/librgw_la-rgw_realm_watcher.Tpo rgw/$(DEPDIR)/librgw_la-rgw_realm_watcher.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_realm_watcher.cc' object='rgw/librgw_la-rgw_realm_watcher.lo' libtool=yes @AMDEPBACKSLASH@
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librgw_la_CXXFLAGS) $(CXXFLAGS) -c -o rgw/librgw_la-rgw_dencoder.lo `test -f 'rgw/rgw_dencoder.cc' || echo '$(srcdir)/'`rgw/rgw_dencoder.cc
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librgw_la_CXXFLAGS) $(CXXFLAGS) -c -o rgw/librgw_la-rgw_realm_watcher.lo `test -f 'rgw/rgw_realm_watcher.cc' || echo '$(srcdir)/'`rgw/rgw_realm_watcher.cc
+
+rgw/librgw_la-rgw_sync.lo: rgw/rgw_sync.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librgw_la_CXXFLAGS) $(CXXFLAGS) -MT rgw/librgw_la-rgw_sync.lo -MD -MP -MF rgw/$(DEPDIR)/librgw_la-rgw_sync.Tpo -c -o rgw/librgw_la-rgw_sync.lo `test -f 'rgw/rgw_sync.cc' || echo '$(srcdir)/'`rgw/rgw_sync.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/librgw_la-rgw_sync.Tpo rgw/$(DEPDIR)/librgw_la-rgw_sync.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_sync.cc' object='rgw/librgw_la-rgw_sync.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librgw_la_CXXFLAGS) $(CXXFLAGS) -c -o rgw/librgw_la-rgw_sync.lo `test -f 'rgw/rgw_sync.cc' || echo '$(srcdir)/'`rgw/rgw_sync.cc
+
+rgw/librgw_la-rgw_data_sync.lo: rgw/rgw_data_sync.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librgw_la_CXXFLAGS) $(CXXFLAGS) -MT rgw/librgw_la-rgw_data_sync.lo -MD -MP -MF rgw/$(DEPDIR)/librgw_la-rgw_data_sync.Tpo -c -o rgw/librgw_la-rgw_data_sync.lo `test -f 'rgw/rgw_data_sync.cc' || echo '$(srcdir)/'`rgw/rgw_data_sync.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/librgw_la-rgw_data_sync.Tpo rgw/$(DEPDIR)/librgw_la-rgw_data_sync.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_data_sync.cc' object='rgw/librgw_la-rgw_data_sync.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librgw_la_CXXFLAGS) $(CXXFLAGS) -c -o rgw/librgw_la-rgw_data_sync.lo `test -f 'rgw/rgw_data_sync.cc' || echo '$(srcdir)/'`rgw/rgw_data_sync.cc
 
 rgw/librgw_la-rgw_object_expirer_core.lo: rgw/rgw_object_expirer_core.cc
 @am__fastdepCXX_TRUE@	$(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librgw_la_CXXFLAGS) $(CXXFLAGS) -MT rgw/librgw_la-rgw_object_expirer_core.lo -MD -MP -MF rgw/$(DEPDIR)/librgw_la-rgw_object_expirer_core.Tpo -c -o rgw/librgw_la-rgw_object_expirer_core.lo `test -f 'rgw/rgw_object_expirer_core.cc' || echo '$(srcdir)/'`rgw/rgw_object_expirer_core.cc
@@ -23266,103 +24255,327 @@ rgw/librgw_la-rgw_object_expirer_core.lo: rgw/rgw_object_expirer_core.cc
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librgw_la_CXXFLAGS) $(CXXFLAGS) -c -o rgw/librgw_la-rgw_object_expirer_core.lo `test -f 'rgw/rgw_object_expirer_core.cc' || echo '$(srcdir)/'`rgw/rgw_object_expirer_core.cc
 
-rgw/librgw_la-rgw_website.lo: rgw/rgw_website.cc
- at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librgw_la_CXXFLAGS) $(CXXFLAGS) -MT rgw/librgw_la-rgw_website.lo -MD -MP -MF rgw/$(DEPDIR)/librgw_la-rgw_website.Tpo -c -o rgw/librgw_la-rgw_website.lo `test -f 'rgw/rgw_website.cc' || echo '$(srcdir)/'`rgw/rgw_website.cc
- at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/librgw_la-rgw_website.Tpo rgw/$(DEPDIR)/librgw_la-rgw_website.Plo
- at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_website.cc' object='rgw/librgw_la-rgw_website.lo' libtool=yes @AMDEPBACKSLASH@
+rgw/librgw_la-rgw_op.lo: rgw/rgw_op.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librgw_la_CXXFLAGS) $(CXXFLAGS) -MT rgw/librgw_la-rgw_op.lo -MD -MP -MF rgw/$(DEPDIR)/librgw_la-rgw_op.Tpo -c -o rgw/librgw_la-rgw_op.lo `test -f 'rgw/rgw_op.cc' || echo '$(srcdir)/'`rgw/rgw_op.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/librgw_la-rgw_op.Tpo rgw/$(DEPDIR)/librgw_la-rgw_op.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_op.cc' object='rgw/librgw_la-rgw_op.lo' libtool=yes @AMDEPBACKSLASH@
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librgw_la_CXXFLAGS) $(CXXFLAGS) -c -o rgw/librgw_la-rgw_website.lo `test -f 'rgw/rgw_website.cc' || echo '$(srcdir)/'`rgw/rgw_website.cc
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librgw_la_CXXFLAGS) $(CXXFLAGS) -c -o rgw/librgw_la-rgw_op.lo `test -f 'rgw/rgw_op.cc' || echo '$(srcdir)/'`rgw/rgw_op.cc
 
-test/encoding/ceph_dencoder-ceph_dencoder.o: test/encoding/ceph_dencoder.cc
- at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ceph_dencoder_CXXFLAGS) $(CXXFLAGS) -MT test/encoding/ceph_dencoder-ceph_dencoder.o -MD -MP -MF test/encoding/$(DEPDIR)/ceph_dencoder-ceph_dencoder.Tpo -c -o test/encoding/ceph_dencoder-ceph_dencoder.o `test -f 'test/encoding/ceph_dencoder.cc' || echo '$(srcdir)/'`test/encoding/ceph_dencoder.cc
- at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) test/encoding/$(DEPDIR)/ceph_dencoder-ceph_dencoder.Tpo test/encoding/$(DEPDIR)/ceph_dencoder-ceph_dencoder.Po
- at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='test/encoding/ceph_dencoder.cc' object='test/encoding/ceph_dencoder-ceph_dencoder.o' libtool=no @AMDEPBACKSLASH@
+rgw/librgw_la-rgw_os_lib.lo: rgw/rgw_os_lib.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librgw_la_CXXFLAGS) $(CXXFLAGS) -MT rgw/librgw_la-rgw_os_lib.lo -MD -MP -MF rgw/$(DEPDIR)/librgw_la-rgw_os_lib.Tpo -c -o rgw/librgw_la-rgw_os_lib.lo `test -f 'rgw/rgw_os_lib.cc' || echo '$(srcdir)/'`rgw/rgw_os_lib.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/librgw_la-rgw_os_lib.Tpo rgw/$(DEPDIR)/librgw_la-rgw_os_lib.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_os_lib.cc' object='rgw/librgw_la-rgw_os_lib.lo' libtool=yes @AMDEPBACKSLASH@
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ceph_dencoder_CXXFLAGS) $(CXXFLAGS) -c -o test/encoding/ceph_dencoder-ceph_dencoder.o `test -f 'test/encoding/ceph_dencoder.cc' || echo '$(srcdir)/'`test/encoding/ceph_dencoder.cc
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librgw_la_CXXFLAGS) $(CXXFLAGS) -c -o rgw/librgw_la-rgw_os_lib.lo `test -f 'rgw/rgw_os_lib.cc' || echo '$(srcdir)/'`rgw/rgw_os_lib.cc
 
-test/encoding/ceph_dencoder-ceph_dencoder.obj: test/encoding/ceph_dencoder.cc
- at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ceph_dencoder_CXXFLAGS) $(CXXFLAGS) -MT test/encoding/ceph_dencoder-ceph_dencoder.obj -MD -MP -MF test/encoding/$(DEPDIR)/ceph_dencoder-ceph_dencoder.Tpo -c -o test/encoding/ceph_dencoder-ceph_dencoder.obj `if test -f 'test/encoding/ceph_dencoder.cc'; then $(CYGPATH_W) 'test/encoding/ceph_dencoder.cc'; else $(CYGPATH_W) '$(srcdir)/test/encoding/ceph_dencoder.cc'; fi`
- at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) test/encoding/$(DEPDIR)/ceph_dencoder-ceph_dencoder.Tpo test/encoding/$(DEPDIR)/ceph_dencoder-ceph_dencoder.Po
- at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='test/encoding/ceph_dencoder.cc' object='test/encoding/ceph_dencoder-ceph_dencoder.obj' libtool=no @AMDEPBACKSLASH@
+rgw/librgw_la-rgw_policy_s3.lo: rgw/rgw_policy_s3.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librgw_la_CXXFLAGS) $(CXXFLAGS) -MT rgw/librgw_la-rgw_policy_s3.lo -MD -MP -MF rgw/$(DEPDIR)/librgw_la-rgw_policy_s3.Tpo -c -o rgw/librgw_la-rgw_policy_s3.lo `test -f 'rgw/rgw_policy_s3.cc' || echo '$(srcdir)/'`rgw/rgw_policy_s3.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/librgw_la-rgw_policy_s3.Tpo rgw/$(DEPDIR)/librgw_la-rgw_policy_s3.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_policy_s3.cc' object='rgw/librgw_la-rgw_policy_s3.lo' libtool=yes @AMDEPBACKSLASH@
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ceph_dencoder_CXXFLAGS) $(CXXFLAGS) -c -o test/encoding/ceph_dencoder-ceph_dencoder.obj `if test -f 'test/encoding/ceph_dencoder.cc'; then $(CYGPATH_W) 'test/encoding/ceph_dencoder.cc'; else $(CYGPATH_W) '$(srcdir)/test/encoding/ceph_dencoder.cc'; fi`
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librgw_la_CXXFLAGS) $(CXXFLAGS) -c -o rgw/librgw_la-rgw_policy_s3.lo `test -f 'rgw/rgw_policy_s3.cc' || echo '$(srcdir)/'`rgw/rgw_policy_s3.cc
 
-mds/ceph_dencoder-Capability.o: mds/Capability.cc
- at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ceph_dencoder_CXXFLAGS) $(CXXFLAGS) -MT mds/ceph_dencoder-Capability.o -MD -MP -MF mds/$(DEPDIR)/ceph_dencoder-Capability.Tpo -c -o mds/ceph_dencoder-Capability.o `test -f 'mds/Capability.cc' || echo '$(srcdir)/'`mds/Capability.cc
- at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) mds/$(DEPDIR)/ceph_dencoder-Capability.Tpo mds/$(DEPDIR)/ceph_dencoder-Capability.Po
- at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='mds/Capability.cc' object='mds/ceph_dencoder-Capability.o' libtool=no @AMDEPBACKSLASH@
+rgw/librgw_la-rgw_process.lo: rgw/rgw_process.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librgw_la_CXXFLAGS) $(CXXFLAGS) -MT rgw/librgw_la-rgw_process.lo -MD -MP -MF rgw/$(DEPDIR)/librgw_la-rgw_process.Tpo -c -o rgw/librgw_la-rgw_process.lo `test -f 'rgw/rgw_process.cc' || echo '$(srcdir)/'`rgw/rgw_process.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/librgw_la-rgw_process.Tpo rgw/$(DEPDIR)/librgw_la-rgw_process.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_process.cc' object='rgw/librgw_la-rgw_process.lo' libtool=yes @AMDEPBACKSLASH@
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ceph_dencoder_CXXFLAGS) $(CXXFLAGS) -c -o mds/ceph_dencoder-Capability.o `test -f 'mds/Capability.cc' || echo '$(srcdir)/'`mds/Capability.cc
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librgw_la_CXXFLAGS) $(CXXFLAGS) -c -o rgw/librgw_la-rgw_process.lo `test -f 'rgw/rgw_process.cc' || echo '$(srcdir)/'`rgw/rgw_process.cc
 
-mds/ceph_dencoder-Capability.obj: mds/Capability.cc
- at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ceph_dencoder_CXXFLAGS) $(CXXFLAGS) -MT mds/ceph_dencoder-Capability.obj -MD -MP -MF mds/$(DEPDIR)/ceph_dencoder-Capability.Tpo -c -o mds/ceph_dencoder-Capability.obj `if test -f 'mds/Capability.cc'; then $(CYGPATH_W) 'mds/Capability.cc'; else $(CYGPATH_W) '$(srcdir)/mds/Capability.cc'; fi`
- at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) mds/$(DEPDIR)/ceph_dencoder-Capability.Tpo mds/$(DEPDIR)/ceph_dencoder-Capability.Po
- at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='mds/Capability.cc' object='mds/ceph_dencoder-Capability.obj' libtool=no @AMDEPBACKSLASH@
+rgw/librgw_la-rgw_quota.lo: rgw/rgw_quota.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librgw_la_CXXFLAGS) $(CXXFLAGS) -MT rgw/librgw_la-rgw_quota.lo -MD -MP -MF rgw/$(DEPDIR)/librgw_la-rgw_quota.Tpo -c -o rgw/librgw_la-rgw_quota.lo `test -f 'rgw/rgw_quota.cc' || echo '$(srcdir)/'`rgw/rgw_quota.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/librgw_la-rgw_quota.Tpo rgw/$(DEPDIR)/librgw_la-rgw_quota.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_quota.cc' object='rgw/librgw_la-rgw_quota.lo' libtool=yes @AMDEPBACKSLASH@
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ceph_dencoder_CXXFLAGS) $(CXXFLAGS) -c -o mds/ceph_dencoder-Capability.obj `if test -f 'mds/Capability.cc'; then $(CYGPATH_W) 'mds/Capability.cc'; else $(CYGPATH_W) '$(srcdir)/mds/Capability.cc'; fi`
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librgw_la_CXXFLAGS) $(CXXFLAGS) -c -o rgw/librgw_la-rgw_quota.lo `test -f 'rgw/rgw_quota.cc' || echo '$(srcdir)/'`rgw/rgw_quota.cc
 
-mds/ceph_dencoder-MDSDaemon.o: mds/MDSDaemon.cc
- at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ceph_dencoder_CXXFLAGS) $(CXXFLAGS) -MT mds/ceph_dencoder-MDSDaemon.o -MD -MP -MF mds/$(DEPDIR)/ceph_dencoder-MDSDaemon.Tpo -c -o mds/ceph_dencoder-MDSDaemon.o `test -f 'mds/MDSDaemon.cc' || echo '$(srcdir)/'`mds/MDSDaemon.cc
- at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) mds/$(DEPDIR)/ceph_dencoder-MDSDaemon.Tpo mds/$(DEPDIR)/ceph_dencoder-MDSDaemon.Po
- at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='mds/MDSDaemon.cc' object='mds/ceph_dencoder-MDSDaemon.o' libtool=no @AMDEPBACKSLASH@
+rgw/librgw_la-rgw_rados.lo: rgw/rgw_rados.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librgw_la_CXXFLAGS) $(CXXFLAGS) -MT rgw/librgw_la-rgw_rados.lo -MD -MP -MF rgw/$(DEPDIR)/librgw_la-rgw_rados.Tpo -c -o rgw/librgw_la-rgw_rados.lo `test -f 'rgw/rgw_rados.cc' || echo '$(srcdir)/'`rgw/rgw_rados.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/librgw_la-rgw_rados.Tpo rgw/$(DEPDIR)/librgw_la-rgw_rados.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_rados.cc' object='rgw/librgw_la-rgw_rados.lo' libtool=yes @AMDEPBACKSLASH@
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ceph_dencoder_CXXFLAGS) $(CXXFLAGS) -c -o mds/ceph_dencoder-MDSDaemon.o `test -f 'mds/MDSDaemon.cc' || echo '$(srcdir)/'`mds/MDSDaemon.cc
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librgw_la_CXXFLAGS) $(CXXFLAGS) -c -o rgw/librgw_la-rgw_rados.lo `test -f 'rgw/rgw_rados.cc' || echo '$(srcdir)/'`rgw/rgw_rados.cc
 
-mds/ceph_dencoder-MDSDaemon.obj: mds/MDSDaemon.cc
- at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ceph_dencoder_CXXFLAGS) $(CXXFLAGS) -MT mds/ceph_dencoder-MDSDaemon.obj -MD -MP -MF mds/$(DEPDIR)/ceph_dencoder-MDSDaemon.Tpo -c -o mds/ceph_dencoder-MDSDaemon.obj `if test -f 'mds/MDSDaemon.cc'; then $(CYGPATH_W) 'mds/MDSDaemon.cc'; else $(CYGPATH_W) '$(srcdir)/mds/MDSDaemon.cc'; fi`
- at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) mds/$(DEPDIR)/ceph_dencoder-MDSDaemon.Tpo mds/$(DEPDIR)/ceph_dencoder-MDSDaemon.Po
- at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='mds/MDSDaemon.cc' object='mds/ceph_dencoder-MDSDaemon.obj' libtool=no @AMDEPBACKSLASH@
+rgw/librgw_la-rgw_replica_log.lo: rgw/rgw_replica_log.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librgw_la_CXXFLAGS) $(CXXFLAGS) -MT rgw/librgw_la-rgw_replica_log.lo -MD -MP -MF rgw/$(DEPDIR)/librgw_la-rgw_replica_log.Tpo -c -o rgw/librgw_la-rgw_replica_log.lo `test -f 'rgw/rgw_replica_log.cc' || echo '$(srcdir)/'`rgw/rgw_replica_log.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/librgw_la-rgw_replica_log.Tpo rgw/$(DEPDIR)/librgw_la-rgw_replica_log.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_replica_log.cc' object='rgw/librgw_la-rgw_replica_log.lo' libtool=yes @AMDEPBACKSLASH@
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ceph_dencoder_CXXFLAGS) $(CXXFLAGS) -c -o mds/ceph_dencoder-MDSDaemon.obj `if test -f 'mds/MDSDaemon.cc'; then $(CYGPATH_W) 'mds/MDSDaemon.cc'; else $(CYGPATH_W) '$(srcdir)/mds/MDSDaemon.cc'; fi`
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librgw_la_CXXFLAGS) $(CXXFLAGS) -c -o rgw/librgw_la-rgw_replica_log.lo `test -f 'rgw/rgw_replica_log.cc' || echo '$(srcdir)/'`rgw/rgw_replica_log.cc
 
-mds/ceph_dencoder-MDSRank.o: mds/MDSRank.cc
- at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ceph_dencoder_CXXFLAGS) $(CXXFLAGS) -MT mds/ceph_dencoder-MDSRank.o -MD -MP -MF mds/$(DEPDIR)/ceph_dencoder-MDSRank.Tpo -c -o mds/ceph_dencoder-MDSRank.o `test -f 'mds/MDSRank.cc' || echo '$(srcdir)/'`mds/MDSRank.cc
- at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) mds/$(DEPDIR)/ceph_dencoder-MDSRank.Tpo mds/$(DEPDIR)/ceph_dencoder-MDSRank.Po
- at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='mds/MDSRank.cc' object='mds/ceph_dencoder-MDSRank.o' libtool=no @AMDEPBACKSLASH@
+rgw/librgw_la-rgw_request.lo: rgw/rgw_request.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librgw_la_CXXFLAGS) $(CXXFLAGS) -MT rgw/librgw_la-rgw_request.lo -MD -MP -MF rgw/$(DEPDIR)/librgw_la-rgw_request.Tpo -c -o rgw/librgw_la-rgw_request.lo `test -f 'rgw/rgw_request.cc' || echo '$(srcdir)/'`rgw/rgw_request.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/librgw_la-rgw_request.Tpo rgw/$(DEPDIR)/librgw_la-rgw_request.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_request.cc' object='rgw/librgw_la-rgw_request.lo' libtool=yes @AMDEPBACKSLASH@
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ceph_dencoder_CXXFLAGS) $(CXXFLAGS) -c -o mds/ceph_dencoder-MDSRank.o `test -f 'mds/MDSRank.cc' || echo '$(srcdir)/'`mds/MDSRank.cc
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librgw_la_CXXFLAGS) $(CXXFLAGS) -c -o rgw/librgw_la-rgw_request.lo `test -f 'rgw/rgw_request.cc' || echo '$(srcdir)/'`rgw/rgw_request.cc
 
-mds/ceph_dencoder-MDSRank.obj: mds/MDSRank.cc
- at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ceph_dencoder_CXXFLAGS) $(CXXFLAGS) -MT mds/ceph_dencoder-MDSRank.obj -MD -MP -MF mds/$(DEPDIR)/ceph_dencoder-MDSRank.Tpo -c -o mds/ceph_dencoder-MDSRank.obj `if test -f 'mds/MDSRank.cc'; then $(CYGPATH_W) 'mds/MDSRank.cc'; else $(CYGPATH_W) '$(srcdir)/mds/MDSRank.cc'; fi`
- at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) mds/$(DEPDIR)/ceph_dencoder-MDSRank.Tpo mds/$(DEPDIR)/ceph_dencoder-MDSRank.Po
- at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='mds/MDSRank.cc' object='mds/ceph_dencoder-MDSRank.obj' libtool=no @AMDEPBACKSLASH@
+rgw/librgw_la-rgw_resolve.lo: rgw/rgw_resolve.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librgw_la_CXXFLAGS) $(CXXFLAGS) -MT rgw/librgw_la-rgw_resolve.lo -MD -MP -MF rgw/$(DEPDIR)/librgw_la-rgw_resolve.Tpo -c -o rgw/librgw_la-rgw_resolve.lo `test -f 'rgw/rgw_resolve.cc' || echo '$(srcdir)/'`rgw/rgw_resolve.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/librgw_la-rgw_resolve.Tpo rgw/$(DEPDIR)/librgw_la-rgw_resolve.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_resolve.cc' object='rgw/librgw_la-rgw_resolve.lo' libtool=yes @AMDEPBACKSLASH@
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ceph_dencoder_CXXFLAGS) $(CXXFLAGS) -c -o mds/ceph_dencoder-MDSRank.obj `if test -f 'mds/MDSRank.cc'; then $(CYGPATH_W) 'mds/MDSRank.cc'; else $(CYGPATH_W) '$(srcdir)/mds/MDSRank.cc'; fi`
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librgw_la_CXXFLAGS) $(CXXFLAGS) -c -o rgw/librgw_la-rgw_resolve.lo `test -f 'rgw/rgw_resolve.cc' || echo '$(srcdir)/'`rgw/rgw_resolve.cc
 
-mds/ceph_dencoder-Beacon.o: mds/Beacon.cc
- at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ceph_dencoder_CXXFLAGS) $(CXXFLAGS) -MT mds/ceph_dencoder-Beacon.o -MD -MP -MF mds/$(DEPDIR)/ceph_dencoder-Beacon.Tpo -c -o mds/ceph_dencoder-Beacon.o `test -f 'mds/Beacon.cc' || echo '$(srcdir)/'`mds/Beacon.cc
- at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) mds/$(DEPDIR)/ceph_dencoder-Beacon.Tpo mds/$(DEPDIR)/ceph_dencoder-Beacon.Po
- at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='mds/Beacon.cc' object='mds/ceph_dencoder-Beacon.o' libtool=no @AMDEPBACKSLASH@
+rgw/librgw_la-rgw_rest_bucket.lo: rgw/rgw_rest_bucket.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librgw_la_CXXFLAGS) $(CXXFLAGS) -MT rgw/librgw_la-rgw_rest_bucket.lo -MD -MP -MF rgw/$(DEPDIR)/librgw_la-rgw_rest_bucket.Tpo -c -o rgw/librgw_la-rgw_rest_bucket.lo `test -f 'rgw/rgw_rest_bucket.cc' || echo '$(srcdir)/'`rgw/rgw_rest_bucket.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/librgw_la-rgw_rest_bucket.Tpo rgw/$(DEPDIR)/librgw_la-rgw_rest_bucket.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_rest_bucket.cc' object='rgw/librgw_la-rgw_rest_bucket.lo' libtool=yes @AMDEPBACKSLASH@
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ceph_dencoder_CXXFLAGS) $(CXXFLAGS) -c -o mds/ceph_dencoder-Beacon.o `test -f 'mds/Beacon.cc' || echo '$(srcdir)/'`mds/Beacon.cc
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librgw_la_CXXFLAGS) $(CXXFLAGS) -c -o rgw/librgw_la-rgw_rest_bucket.lo `test -f 'rgw/rgw_rest_bucket.cc' || echo '$(srcdir)/'`rgw/rgw_rest_bucket.cc
 
-mds/ceph_dencoder-Beacon.obj: mds/Beacon.cc
- at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ceph_dencoder_CXXFLAGS) $(CXXFLAGS) -MT mds/ceph_dencoder-Beacon.obj -MD -MP -MF mds/$(DEPDIR)/ceph_dencoder-Beacon.Tpo -c -o mds/ceph_dencoder-Beacon.obj `if test -f 'mds/Beacon.cc'; then $(CYGPATH_W) 'mds/Beacon.cc'; else $(CYGPATH_W) '$(srcdir)/mds/Beacon.cc'; fi`
- at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) mds/$(DEPDIR)/ceph_dencoder-Beacon.Tpo mds/$(DEPDIR)/ceph_dencoder-Beacon.Po
- at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='mds/Beacon.cc' object='mds/ceph_dencoder-Beacon.obj' libtool=no @AMDEPBACKSLASH@
+rgw/librgw_la-rgw_rest.lo: rgw/rgw_rest.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librgw_la_CXXFLAGS) $(CXXFLAGS) -MT rgw/librgw_la-rgw_rest.lo -MD -MP -MF rgw/$(DEPDIR)/librgw_la-rgw_rest.Tpo -c -o rgw/librgw_la-rgw_rest.lo `test -f 'rgw/rgw_rest.cc' || echo '$(srcdir)/'`rgw/rgw_rest.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/librgw_la-rgw_rest.Tpo rgw/$(DEPDIR)/librgw_la-rgw_rest.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_rest.cc' object='rgw/librgw_la-rgw_rest.lo' libtool=yes @AMDEPBACKSLASH@
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ceph_dencoder_CXXFLAGS) $(CXXFLAGS) -c -o mds/ceph_dencoder-Beacon.obj `if test -f 'mds/Beacon.cc'; then $(CYGPATH_W) 'mds/Beacon.cc'; else $(CYGPATH_W) '$(srcdir)/mds/Beacon.cc'; fi`
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librgw_la_CXXFLAGS) $(CXXFLAGS) -c -o rgw/librgw_la-rgw_rest.lo `test -f 'rgw/rgw_rest.cc' || echo '$(srcdir)/'`rgw/rgw_rest.cc
 
-mds/ceph_dencoder-journal.o: mds/journal.cc
- at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ceph_dencoder_CXXFLAGS) $(CXXFLAGS) -MT mds/ceph_dencoder-journal.o -MD -MP -MF mds/$(DEPDIR)/ceph_dencoder-journal.Tpo -c -o mds/ceph_dencoder-journal.o `test -f 'mds/journal.cc' || echo '$(srcdir)/'`mds/journal.cc
- at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) mds/$(DEPDIR)/ceph_dencoder-journal.Tpo mds/$(DEPDIR)/ceph_dencoder-journal.Po
- at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='mds/journal.cc' object='mds/ceph_dencoder-journal.o' libtool=no @AMDEPBACKSLASH@
+rgw/librgw_la-rgw_rest_client.lo: rgw/rgw_rest_client.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librgw_la_CXXFLAGS) $(CXXFLAGS) -MT rgw/librgw_la-rgw_rest_client.lo -MD -MP -MF rgw/$(DEPDIR)/librgw_la-rgw_rest_client.Tpo -c -o rgw/librgw_la-rgw_rest_client.lo `test -f 'rgw/rgw_rest_client.cc' || echo '$(srcdir)/'`rgw/rgw_rest_client.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/librgw_la-rgw_rest_client.Tpo rgw/$(DEPDIR)/librgw_la-rgw_rest_client.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_rest_client.cc' object='rgw/librgw_la-rgw_rest_client.lo' libtool=yes @AMDEPBACKSLASH@
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ceph_dencoder_CXXFLAGS) $(CXXFLAGS) -c -o mds/ceph_dencoder-journal.o `test -f 'mds/journal.cc' || echo '$(srcdir)/'`mds/journal.cc
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librgw_la_CXXFLAGS) $(CXXFLAGS) -c -o rgw/librgw_la-rgw_rest_client.lo `test -f 'rgw/rgw_rest_client.cc' || echo '$(srcdir)/'`rgw/rgw_rest_client.cc
 
-mds/ceph_dencoder-journal.obj: mds/journal.cc
- at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ceph_dencoder_CXXFLAGS) $(CXXFLAGS) -MT mds/ceph_dencoder-journal.obj -MD -MP -MF mds/$(DEPDIR)/ceph_dencoder-journal.Tpo -c -o mds/ceph_dencoder-journal.obj `if test -f 'mds/journal.cc'; then $(CYGPATH_W) 'mds/journal.cc'; else $(CYGPATH_W) '$(srcdir)/mds/journal.cc'; fi`
- at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) mds/$(DEPDIR)/ceph_dencoder-journal.Tpo mds/$(DEPDIR)/ceph_dencoder-journal.Po
- at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='mds/journal.cc' object='mds/ceph_dencoder-journal.obj' libtool=no @AMDEPBACKSLASH@
+rgw/librgw_la-rgw_rest_config.lo: rgw/rgw_rest_config.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librgw_la_CXXFLAGS) $(CXXFLAGS) -MT rgw/librgw_la-rgw_rest_config.lo -MD -MP -MF rgw/$(DEPDIR)/librgw_la-rgw_rest_config.Tpo -c -o rgw/librgw_la-rgw_rest_config.lo `test -f 'rgw/rgw_rest_config.cc' || echo '$(srcdir)/'`rgw/rgw_rest_config.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/librgw_la-rgw_rest_config.Tpo rgw/$(DEPDIR)/librgw_la-rgw_rest_config.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_rest_config.cc' object='rgw/librgw_la-rgw_rest_config.lo' libtool=yes @AMDEPBACKSLASH@
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ceph_dencoder_CXXFLAGS) $(CXXFLAGS) -c -o mds/ceph_dencoder-journal.obj `if test -f 'mds/journal.cc'; then $(CYGPATH_W) 'mds/journal.cc'; else $(CYGPATH_W) '$(srcdir)/mds/journal.cc'; fi`
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librgw_la_CXXFLAGS) $(CXXFLAGS) -c -o rgw/librgw_la-rgw_rest_config.lo `test -f 'rgw/rgw_rest_config.cc' || echo '$(srcdir)/'`rgw/rgw_rest_config.cc
 
-mds/ceph_dencoder-Server.o: mds/Server.cc
- at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ceph_dencoder_CXXFLAGS) $(CXXFLAGS) -MT mds/ceph_dencoder-Server.o -MD -MP -MF mds/$(DEPDIR)/ceph_dencoder-Server.Tpo -c -o mds/ceph_dencoder-Server.o `test -f 'mds/Server.cc' || echo '$(srcdir)/'`mds/Server.cc
- at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) mds/$(DEPDIR)/ceph_dencoder-Server.Tpo mds/$(DEPDIR)/ceph_dencoder-Server.Po
- at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='mds/Server.cc' object='mds/ceph_dencoder-Server.o' libtool=no @AMDEPBACKSLASH@
+rgw/librgw_la-rgw_rest_conn.lo: rgw/rgw_rest_conn.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librgw_la_CXXFLAGS) $(CXXFLAGS) -MT rgw/librgw_la-rgw_rest_conn.lo -MD -MP -MF rgw/$(DEPDIR)/librgw_la-rgw_rest_conn.Tpo -c -o rgw/librgw_la-rgw_rest_conn.lo `test -f 'rgw/rgw_rest_conn.cc' || echo '$(srcdir)/'`rgw/rgw_rest_conn.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/librgw_la-rgw_rest_conn.Tpo rgw/$(DEPDIR)/librgw_la-rgw_rest_conn.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_rest_conn.cc' object='rgw/librgw_la-rgw_rest_conn.lo' libtool=yes @AMDEPBACKSLASH@
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ceph_dencoder_CXXFLAGS) $(CXXFLAGS) -c -o mds/ceph_dencoder-Server.o `test -f 'mds/Server.cc' || echo '$(srcdir)/'`mds/Server.cc
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librgw_la_CXXFLAGS) $(CXXFLAGS) -c -o rgw/librgw_la-rgw_rest_conn.lo `test -f 'rgw/rgw_rest_conn.cc' || echo '$(srcdir)/'`rgw/rgw_rest_conn.cc
+
+rgw/librgw_la-rgw_rest_log.lo: rgw/rgw_rest_log.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librgw_la_CXXFLAGS) $(CXXFLAGS) -MT rgw/librgw_la-rgw_rest_log.lo -MD -MP -MF rgw/$(DEPDIR)/librgw_la-rgw_rest_log.Tpo -c -o rgw/librgw_la-rgw_rest_log.lo `test -f 'rgw/rgw_rest_log.cc' || echo '$(srcdir)/'`rgw/rgw_rest_log.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/librgw_la-rgw_rest_log.Tpo rgw/$(DEPDIR)/librgw_la-rgw_rest_log.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_rest_log.cc' object='rgw/librgw_la-rgw_rest_log.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librgw_la_CXXFLAGS) $(CXXFLAGS) -c -o rgw/librgw_la-rgw_rest_log.lo `test -f 'rgw/rgw_rest_log.cc' || echo '$(srcdir)/'`rgw/rgw_rest_log.cc
+
+rgw/librgw_la-rgw_rest_metadata.lo: rgw/rgw_rest_metadata.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librgw_la_CXXFLAGS) $(CXXFLAGS) -MT rgw/librgw_la-rgw_rest_metadata.lo -MD -MP -MF rgw/$(DEPDIR)/librgw_la-rgw_rest_metadata.Tpo -c -o rgw/librgw_la-rgw_rest_metadata.lo `test -f 'rgw/rgw_rest_metadata.cc' || echo '$(srcdir)/'`rgw/rgw_rest_metadata.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/librgw_la-rgw_rest_metadata.Tpo rgw/$(DEPDIR)/librgw_la-rgw_rest_metadata.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_rest_metadata.cc' object='rgw/librgw_la-rgw_rest_metadata.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librgw_la_CXXFLAGS) $(CXXFLAGS) -c -o rgw/librgw_la-rgw_rest_metadata.lo `test -f 'rgw/rgw_rest_metadata.cc' || echo '$(srcdir)/'`rgw/rgw_rest_metadata.cc
+
+rgw/librgw_la-rgw_rest_opstate.lo: rgw/rgw_rest_opstate.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librgw_la_CXXFLAGS) $(CXXFLAGS) -MT rgw/librgw_la-rgw_rest_opstate.lo -MD -MP -MF rgw/$(DEPDIR)/librgw_la-rgw_rest_opstate.Tpo -c -o rgw/librgw_la-rgw_rest_opstate.lo `test -f 'rgw/rgw_rest_opstate.cc' || echo '$(srcdir)/'`rgw/rgw_rest_opstate.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/librgw_la-rgw_rest_opstate.Tpo rgw/$(DEPDIR)/librgw_la-rgw_rest_opstate.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_rest_opstate.cc' object='rgw/librgw_la-rgw_rest_opstate.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librgw_la_CXXFLAGS) $(CXXFLAGS) -c -o rgw/librgw_la-rgw_rest_opstate.lo `test -f 'rgw/rgw_rest_opstate.cc' || echo '$(srcdir)/'`rgw/rgw_rest_opstate.cc
+
+rgw/librgw_la-rgw_rest_realm.lo: rgw/rgw_rest_realm.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librgw_la_CXXFLAGS) $(CXXFLAGS) -MT rgw/librgw_la-rgw_rest_realm.lo -MD -MP -MF rgw/$(DEPDIR)/librgw_la-rgw_rest_realm.Tpo -c -o rgw/librgw_la-rgw_rest_realm.lo `test -f 'rgw/rgw_rest_realm.cc' || echo '$(srcdir)/'`rgw/rgw_rest_realm.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/librgw_la-rgw_rest_realm.Tpo rgw/$(DEPDIR)/librgw_la-rgw_rest_realm.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_rest_realm.cc' object='rgw/librgw_la-rgw_rest_realm.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librgw_la_CXXFLAGS) $(CXXFLAGS) -c -o rgw/librgw_la-rgw_rest_realm.lo `test -f 'rgw/rgw_rest_realm.cc' || echo '$(srcdir)/'`rgw/rgw_rest_realm.cc
+
+rgw/librgw_la-rgw_rest_replica_log.lo: rgw/rgw_rest_replica_log.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librgw_la_CXXFLAGS) $(CXXFLAGS) -MT rgw/librgw_la-rgw_rest_replica_log.lo -MD -MP -MF rgw/$(DEPDIR)/librgw_la-rgw_rest_replica_log.Tpo -c -o rgw/librgw_la-rgw_rest_replica_log.lo `test -f 'rgw/rgw_rest_replica_log.cc' || echo '$(srcdir)/'`rgw/rgw_rest_replica_log.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/librgw_la-rgw_rest_replica_log.Tpo rgw/$(DEPDIR)/librgw_la-rgw_rest_replica_log.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_rest_replica_log.cc' object='rgw/librgw_la-rgw_rest_replica_log.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librgw_la_CXXFLAGS) $(CXXFLAGS) -c -o rgw/librgw_la-rgw_rest_replica_log.lo `test -f 'rgw/rgw_rest_replica_log.cc' || echo '$(srcdir)/'`rgw/rgw_rest_replica_log.cc
+
+rgw/librgw_la-rgw_rest_s3.lo: rgw/rgw_rest_s3.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librgw_la_CXXFLAGS) $(CXXFLAGS) -MT rgw/librgw_la-rgw_rest_s3.lo -MD -MP -MF rgw/$(DEPDIR)/librgw_la-rgw_rest_s3.Tpo -c -o rgw/librgw_la-rgw_rest_s3.lo `test -f 'rgw/rgw_rest_s3.cc' || echo '$(srcdir)/'`rgw/rgw_rest_s3.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/librgw_la-rgw_rest_s3.Tpo rgw/$(DEPDIR)/librgw_la-rgw_rest_s3.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_rest_s3.cc' object='rgw/librgw_la-rgw_rest_s3.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librgw_la_CXXFLAGS) $(CXXFLAGS) -c -o rgw/librgw_la-rgw_rest_s3.lo `test -f 'rgw/rgw_rest_s3.cc' || echo '$(srcdir)/'`rgw/rgw_rest_s3.cc
+
+rgw/librgw_la-rgw_rest_swift.lo: rgw/rgw_rest_swift.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librgw_la_CXXFLAGS) $(CXXFLAGS) -MT rgw/librgw_la-rgw_rest_swift.lo -MD -MP -MF rgw/$(DEPDIR)/librgw_la-rgw_rest_swift.Tpo -c -o rgw/librgw_la-rgw_rest_swift.lo `test -f 'rgw/rgw_rest_swift.cc' || echo '$(srcdir)/'`rgw/rgw_rest_swift.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/librgw_la-rgw_rest_swift.Tpo rgw/$(DEPDIR)/librgw_la-rgw_rest_swift.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_rest_swift.cc' object='rgw/librgw_la-rgw_rest_swift.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librgw_la_CXXFLAGS) $(CXXFLAGS) -c -o rgw/librgw_la-rgw_rest_swift.lo `test -f 'rgw/rgw_rest_swift.cc' || echo '$(srcdir)/'`rgw/rgw_rest_swift.cc
+
+rgw/librgw_la-rgw_rest_usage.lo: rgw/rgw_rest_usage.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librgw_la_CXXFLAGS) $(CXXFLAGS) -MT rgw/librgw_la-rgw_rest_usage.lo -MD -MP -MF rgw/$(DEPDIR)/librgw_la-rgw_rest_usage.Tpo -c -o rgw/librgw_la-rgw_rest_usage.lo `test -f 'rgw/rgw_rest_usage.cc' || echo '$(srcdir)/'`rgw/rgw_rest_usage.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/librgw_la-rgw_rest_usage.Tpo rgw/$(DEPDIR)/librgw_la-rgw_rest_usage.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_rest_usage.cc' object='rgw/librgw_la-rgw_rest_usage.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librgw_la_CXXFLAGS) $(CXXFLAGS) -c -o rgw/librgw_la-rgw_rest_usage.lo `test -f 'rgw/rgw_rest_usage.cc' || echo '$(srcdir)/'`rgw/rgw_rest_usage.cc
+
+rgw/librgw_la-rgw_rest_user.lo: rgw/rgw_rest_user.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librgw_la_CXXFLAGS) $(CXXFLAGS) -MT rgw/librgw_la-rgw_rest_user.lo -MD -MP -MF rgw/$(DEPDIR)/librgw_la-rgw_rest_user.Tpo -c -o rgw/librgw_la-rgw_rest_user.lo `test -f 'rgw/rgw_rest_user.cc' || echo '$(srcdir)/'`rgw/rgw_rest_user.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/librgw_la-rgw_rest_user.Tpo rgw/$(DEPDIR)/librgw_la-rgw_rest_user.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_rest_user.cc' object='rgw/librgw_la-rgw_rest_user.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librgw_la_CXXFLAGS) $(CXXFLAGS) -c -o rgw/librgw_la-rgw_rest_user.lo `test -f 'rgw/rgw_rest_user.cc' || echo '$(srcdir)/'`rgw/rgw_rest_user.cc
+
+rgw/librgw_la-rgw_swift_auth.lo: rgw/rgw_swift_auth.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librgw_la_CXXFLAGS) $(CXXFLAGS) -MT rgw/librgw_la-rgw_swift_auth.lo -MD -MP -MF rgw/$(DEPDIR)/librgw_la-rgw_swift_auth.Tpo -c -o rgw/librgw_la-rgw_swift_auth.lo `test -f 'rgw/rgw_swift_auth.cc' || echo '$(srcdir)/'`rgw/rgw_swift_auth.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/librgw_la-rgw_swift_auth.Tpo rgw/$(DEPDIR)/librgw_la-rgw_swift_auth.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_swift_auth.cc' object='rgw/librgw_la-rgw_swift_auth.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librgw_la_CXXFLAGS) $(CXXFLAGS) -c -o rgw/librgw_la-rgw_swift_auth.lo `test -f 'rgw/rgw_swift_auth.cc' || echo '$(srcdir)/'`rgw/rgw_swift_auth.cc
+
+rgw/librgw_la-rgw_swift.lo: rgw/rgw_swift.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librgw_la_CXXFLAGS) $(CXXFLAGS) -MT rgw/librgw_la-rgw_swift.lo -MD -MP -MF rgw/$(DEPDIR)/librgw_la-rgw_swift.Tpo -c -o rgw/librgw_la-rgw_swift.lo `test -f 'rgw/rgw_swift.cc' || echo '$(srcdir)/'`rgw/rgw_swift.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/librgw_la-rgw_swift.Tpo rgw/$(DEPDIR)/librgw_la-rgw_swift.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_swift.cc' object='rgw/librgw_la-rgw_swift.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librgw_la_CXXFLAGS) $(CXXFLAGS) -c -o rgw/librgw_la-rgw_swift.lo `test -f 'rgw/rgw_swift.cc' || echo '$(srcdir)/'`rgw/rgw_swift.cc
+
+rgw/librgw_la-rgw_usage.lo: rgw/rgw_usage.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librgw_la_CXXFLAGS) $(CXXFLAGS) -MT rgw/librgw_la-rgw_usage.lo -MD -MP -MF rgw/$(DEPDIR)/librgw_la-rgw_usage.Tpo -c -o rgw/librgw_la-rgw_usage.lo `test -f 'rgw/rgw_usage.cc' || echo '$(srcdir)/'`rgw/rgw_usage.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/librgw_la-rgw_usage.Tpo rgw/$(DEPDIR)/librgw_la-rgw_usage.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_usage.cc' object='rgw/librgw_la-rgw_usage.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librgw_la_CXXFLAGS) $(CXXFLAGS) -c -o rgw/librgw_la-rgw_usage.lo `test -f 'rgw/rgw_usage.cc' || echo '$(srcdir)/'`rgw/rgw_usage.cc
+
+rgw/librgw_la-rgw_user.lo: rgw/rgw_user.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librgw_la_CXXFLAGS) $(CXXFLAGS) -MT rgw/librgw_la-rgw_user.lo -MD -MP -MF rgw/$(DEPDIR)/librgw_la-rgw_user.Tpo -c -o rgw/librgw_la-rgw_user.lo `test -f 'rgw/rgw_user.cc' || echo '$(srcdir)/'`rgw/rgw_user.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/librgw_la-rgw_user.Tpo rgw/$(DEPDIR)/librgw_la-rgw_user.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_user.cc' object='rgw/librgw_la-rgw_user.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librgw_la_CXXFLAGS) $(CXXFLAGS) -c -o rgw/librgw_la-rgw_user.lo `test -f 'rgw/rgw_user.cc' || echo '$(srcdir)/'`rgw/rgw_user.cc
+
+rgw/librgw_la-rgw_file.lo: rgw/rgw_file.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librgw_la_CXXFLAGS) $(CXXFLAGS) -MT rgw/librgw_la-rgw_file.lo -MD -MP -MF rgw/$(DEPDIR)/librgw_la-rgw_file.Tpo -c -o rgw/librgw_la-rgw_file.lo `test -f 'rgw/rgw_file.cc' || echo '$(srcdir)/'`rgw/rgw_file.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/librgw_la-rgw_file.Tpo rgw/$(DEPDIR)/librgw_la-rgw_file.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_file.cc' object='rgw/librgw_la-rgw_file.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librgw_la_CXXFLAGS) $(CXXFLAGS) -c -o rgw/librgw_la-rgw_file.lo `test -f 'rgw/rgw_file.cc' || echo '$(srcdir)/'`rgw/rgw_file.cc
+
+rgw/librgw_la-librgw.lo: rgw/librgw.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librgw_la_CXXFLAGS) $(CXXFLAGS) -MT rgw/librgw_la-librgw.lo -MD -MP -MF rgw/$(DEPDIR)/librgw_la-librgw.Tpo -c -o rgw/librgw_la-librgw.lo `test -f 'rgw/librgw.cc' || echo '$(srcdir)/'`rgw/librgw.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/librgw_la-librgw.Tpo rgw/$(DEPDIR)/librgw_la-librgw.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/librgw.cc' object='rgw/librgw_la-librgw.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librgw_la_CXXFLAGS) $(CXXFLAGS) -c -o rgw/librgw_la-librgw.lo `test -f 'rgw/librgw.cc' || echo '$(srcdir)/'`rgw/librgw.cc
+
+rgw/librgw_la-rgw_xml.lo: rgw/rgw_xml.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librgw_la_CXXFLAGS) $(CXXFLAGS) -MT rgw/librgw_la-rgw_xml.lo -MD -MP -MF rgw/$(DEPDIR)/librgw_la-rgw_xml.Tpo -c -o rgw/librgw_la-rgw_xml.lo `test -f 'rgw/rgw_xml.cc' || echo '$(srcdir)/'`rgw/rgw_xml.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/librgw_la-rgw_xml.Tpo rgw/$(DEPDIR)/librgw_la-rgw_xml.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_xml.cc' object='rgw/librgw_la-rgw_xml.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librgw_la_CXXFLAGS) $(CXXFLAGS) -c -o rgw/librgw_la-rgw_xml.lo `test -f 'rgw/rgw_xml.cc' || echo '$(srcdir)/'`rgw/rgw_xml.cc
+
+rgw/librgw_la-rgw_xml_enc.lo: rgw/rgw_xml_enc.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librgw_la_CXXFLAGS) $(CXXFLAGS) -MT rgw/librgw_la-rgw_xml_enc.lo -MD -MP -MF rgw/$(DEPDIR)/librgw_la-rgw_xml_enc.Tpo -c -o rgw/librgw_la-rgw_xml_enc.lo `test -f 'rgw/rgw_xml_enc.cc' || echo '$(srcdir)/'`rgw/rgw_xml_enc.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/librgw_la-rgw_xml_enc.Tpo rgw/$(DEPDIR)/librgw_la-rgw_xml_enc.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_xml_enc.cc' object='rgw/librgw_la-rgw_xml_enc.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librgw_la_CXXFLAGS) $(CXXFLAGS) -c -o rgw/librgw_la-rgw_xml_enc.lo `test -f 'rgw/rgw_xml_enc.cc' || echo '$(srcdir)/'`rgw/rgw_xml_enc.cc
+
+rgw/librgw_la-rgw_website.lo: rgw/rgw_website.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librgw_la_CXXFLAGS) $(CXXFLAGS) -MT rgw/librgw_la-rgw_website.lo -MD -MP -MF rgw/$(DEPDIR)/librgw_la-rgw_website.Tpo -c -o rgw/librgw_la-rgw_website.lo `test -f 'rgw/rgw_website.cc' || echo '$(srcdir)/'`rgw/rgw_website.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/librgw_la-rgw_website.Tpo rgw/$(DEPDIR)/librgw_la-rgw_website.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_website.cc' object='rgw/librgw_la-rgw_website.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librgw_la_CXXFLAGS) $(CXXFLAGS) -c -o rgw/librgw_la-rgw_website.lo `test -f 'rgw/rgw_website.cc' || echo '$(srcdir)/'`rgw/rgw_website.cc
+
+rgw/librgw_la-rgw_ldap.lo: rgw/rgw_ldap.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librgw_la_CXXFLAGS) $(CXXFLAGS) -MT rgw/librgw_la-rgw_ldap.lo -MD -MP -MF rgw/$(DEPDIR)/librgw_la-rgw_ldap.Tpo -c -o rgw/librgw_la-rgw_ldap.lo `test -f 'rgw/rgw_ldap.cc' || echo '$(srcdir)/'`rgw/rgw_ldap.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/librgw_la-rgw_ldap.Tpo rgw/$(DEPDIR)/librgw_la-rgw_ldap.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_ldap.cc' object='rgw/librgw_la-rgw_ldap.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librgw_la_CXXFLAGS) $(CXXFLAGS) -c -o rgw/librgw_la-rgw_ldap.lo `test -f 'rgw/rgw_ldap.cc' || echo '$(srcdir)/'`rgw/rgw_ldap.cc
+
+test/encoding/ceph_dencoder-ceph_dencoder.o: test/encoding/ceph_dencoder.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ceph_dencoder_CXXFLAGS) $(CXXFLAGS) -MT test/encoding/ceph_dencoder-ceph_dencoder.o -MD -MP -MF test/encoding/$(DEPDIR)/ceph_dencoder-ceph_dencoder.Tpo -c -o test/encoding/ceph_dencoder-ceph_dencoder.o `test -f 'test/encoding/ceph_dencoder.cc' || echo '$(srcdir)/'`test/encoding/ceph_dencoder.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) test/encoding/$(DEPDIR)/ceph_dencoder-ceph_dencoder.Tpo test/encoding/$(DEPDIR)/ceph_dencoder-ceph_dencoder.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='test/encoding/ceph_dencoder.cc' object='test/encoding/ceph_dencoder-ceph_dencoder.o' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ceph_dencoder_CXXFLAGS) $(CXXFLAGS) -c -o test/encoding/ceph_dencoder-ceph_dencoder.o `test -f 'test/encoding/ceph_dencoder.cc' || echo '$(srcdir)/'`test/encoding/ceph_dencoder.cc
+
+test/encoding/ceph_dencoder-ceph_dencoder.obj: test/encoding/ceph_dencoder.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ceph_dencoder_CXXFLAGS) $(CXXFLAGS) -MT test/encoding/ceph_dencoder-ceph_dencoder.obj -MD -MP -MF test/encoding/$(DEPDIR)/ceph_dencoder-ceph_dencoder.Tpo -c -o test/encoding/ceph_dencoder-ceph_dencoder.obj `if test -f 'test/encoding/ceph_dencoder.cc'; then $(CYGPATH_W) 'test/encoding/ceph_dencoder.cc'; else $(CYGPATH_W) '$(srcdir)/test/encoding/ceph_dencoder.cc'; fi`
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) test/encoding/$(DEPDIR)/ceph_dencoder-ceph_dencoder.Tpo test/encoding/$(DEPDIR)/ceph_dencoder-ceph_dencoder.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='test/encoding/ceph_dencoder.cc' object='test/encoding/ceph_dencoder-ceph_dencoder.obj' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ceph_dencoder_CXXFLAGS) $(CXXFLAGS) -c -o test/encoding/ceph_dencoder-ceph_dencoder.obj `if test -f 'test/encoding/ceph_dencoder.cc'; then $(CYGPATH_W) 'test/encoding/ceph_dencoder.cc'; else $(CYGPATH_W) '$(srcdir)/test/encoding/ceph_dencoder.cc'; fi`
+
+mds/ceph_dencoder-Capability.o: mds/Capability.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ceph_dencoder_CXXFLAGS) $(CXXFLAGS) -MT mds/ceph_dencoder-Capability.o -MD -MP -MF mds/$(DEPDIR)/ceph_dencoder-Capability.Tpo -c -o mds/ceph_dencoder-Capability.o `test -f 'mds/Capability.cc' || echo '$(srcdir)/'`mds/Capability.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) mds/$(DEPDIR)/ceph_dencoder-Capability.Tpo mds/$(DEPDIR)/ceph_dencoder-Capability.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='mds/Capability.cc' object='mds/ceph_dencoder-Capability.o' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ceph_dencoder_CXXFLAGS) $(CXXFLAGS) -c -o mds/ceph_dencoder-Capability.o `test -f 'mds/Capability.cc' || echo '$(srcdir)/'`mds/Capability.cc
+
+mds/ceph_dencoder-Capability.obj: mds/Capability.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ceph_dencoder_CXXFLAGS) $(CXXFLAGS) -MT mds/ceph_dencoder-Capability.obj -MD -MP -MF mds/$(DEPDIR)/ceph_dencoder-Capability.Tpo -c -o mds/ceph_dencoder-Capability.obj `if test -f 'mds/Capability.cc'; then $(CYGPATH_W) 'mds/Capability.cc'; else $(CYGPATH_W) '$(srcdir)/mds/Capability.cc'; fi`
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) mds/$(DEPDIR)/ceph_dencoder-Capability.Tpo mds/$(DEPDIR)/ceph_dencoder-Capability.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='mds/Capability.cc' object='mds/ceph_dencoder-Capability.obj' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ceph_dencoder_CXXFLAGS) $(CXXFLAGS) -c -o mds/ceph_dencoder-Capability.obj `if test -f 'mds/Capability.cc'; then $(CYGPATH_W) 'mds/Capability.cc'; else $(CYGPATH_W) '$(srcdir)/mds/Capability.cc'; fi`
+
+mds/ceph_dencoder-MDSDaemon.o: mds/MDSDaemon.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ceph_dencoder_CXXFLAGS) $(CXXFLAGS) -MT mds/ceph_dencoder-MDSDaemon.o -MD -MP -MF mds/$(DEPDIR)/ceph_dencoder-MDSDaemon.Tpo -c -o mds/ceph_dencoder-MDSDaemon.o `test -f 'mds/MDSDaemon.cc' || echo '$(srcdir)/'`mds/MDSDaemon.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) mds/$(DEPDIR)/ceph_dencoder-MDSDaemon.Tpo mds/$(DEPDIR)/ceph_dencoder-MDSDaemon.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='mds/MDSDaemon.cc' object='mds/ceph_dencoder-MDSDaemon.o' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ceph_dencoder_CXXFLAGS) $(CXXFLAGS) -c -o mds/ceph_dencoder-MDSDaemon.o `test -f 'mds/MDSDaemon.cc' || echo '$(srcdir)/'`mds/MDSDaemon.cc
+
+mds/ceph_dencoder-MDSDaemon.obj: mds/MDSDaemon.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ceph_dencoder_CXXFLAGS) $(CXXFLAGS) -MT mds/ceph_dencoder-MDSDaemon.obj -MD -MP -MF mds/$(DEPDIR)/ceph_dencoder-MDSDaemon.Tpo -c -o mds/ceph_dencoder-MDSDaemon.obj `if test -f 'mds/MDSDaemon.cc'; then $(CYGPATH_W) 'mds/MDSDaemon.cc'; else $(CYGPATH_W) '$(srcdir)/mds/MDSDaemon.cc'; fi`
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) mds/$(DEPDIR)/ceph_dencoder-MDSDaemon.Tpo mds/$(DEPDIR)/ceph_dencoder-MDSDaemon.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='mds/MDSDaemon.cc' object='mds/ceph_dencoder-MDSDaemon.obj' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ceph_dencoder_CXXFLAGS) $(CXXFLAGS) -c -o mds/ceph_dencoder-MDSDaemon.obj `if test -f 'mds/MDSDaemon.cc'; then $(CYGPATH_W) 'mds/MDSDaemon.cc'; else $(CYGPATH_W) '$(srcdir)/mds/MDSDaemon.cc'; fi`
+
+mds/ceph_dencoder-MDSRank.o: mds/MDSRank.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ceph_dencoder_CXXFLAGS) $(CXXFLAGS) -MT mds/ceph_dencoder-MDSRank.o -MD -MP -MF mds/$(DEPDIR)/ceph_dencoder-MDSRank.Tpo -c -o mds/ceph_dencoder-MDSRank.o `test -f 'mds/MDSRank.cc' || echo '$(srcdir)/'`mds/MDSRank.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) mds/$(DEPDIR)/ceph_dencoder-MDSRank.Tpo mds/$(DEPDIR)/ceph_dencoder-MDSRank.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='mds/MDSRank.cc' object='mds/ceph_dencoder-MDSRank.o' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ceph_dencoder_CXXFLAGS) $(CXXFLAGS) -c -o mds/ceph_dencoder-MDSRank.o `test -f 'mds/MDSRank.cc' || echo '$(srcdir)/'`mds/MDSRank.cc
+
+mds/ceph_dencoder-MDSRank.obj: mds/MDSRank.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ceph_dencoder_CXXFLAGS) $(CXXFLAGS) -MT mds/ceph_dencoder-MDSRank.obj -MD -MP -MF mds/$(DEPDIR)/ceph_dencoder-MDSRank.Tpo -c -o mds/ceph_dencoder-MDSRank.obj `if test -f 'mds/MDSRank.cc'; then $(CYGPATH_W) 'mds/MDSRank.cc'; else $(CYGPATH_W) '$(srcdir)/mds/MDSRank.cc'; fi`
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) mds/$(DEPDIR)/ceph_dencoder-MDSRank.Tpo mds/$(DEPDIR)/ceph_dencoder-MDSRank.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='mds/MDSRank.cc' object='mds/ceph_dencoder-MDSRank.obj' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ceph_dencoder_CXXFLAGS) $(CXXFLAGS) -c -o mds/ceph_dencoder-MDSRank.obj `if test -f 'mds/MDSRank.cc'; then $(CYGPATH_W) 'mds/MDSRank.cc'; else $(CYGPATH_W) '$(srcdir)/mds/MDSRank.cc'; fi`
+
+mds/ceph_dencoder-Beacon.o: mds/Beacon.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ceph_dencoder_CXXFLAGS) $(CXXFLAGS) -MT mds/ceph_dencoder-Beacon.o -MD -MP -MF mds/$(DEPDIR)/ceph_dencoder-Beacon.Tpo -c -o mds/ceph_dencoder-Beacon.o `test -f 'mds/Beacon.cc' || echo '$(srcdir)/'`mds/Beacon.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) mds/$(DEPDIR)/ceph_dencoder-Beacon.Tpo mds/$(DEPDIR)/ceph_dencoder-Beacon.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='mds/Beacon.cc' object='mds/ceph_dencoder-Beacon.o' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ceph_dencoder_CXXFLAGS) $(CXXFLAGS) -c -o mds/ceph_dencoder-Beacon.o `test -f 'mds/Beacon.cc' || echo '$(srcdir)/'`mds/Beacon.cc
+
+mds/ceph_dencoder-Beacon.obj: mds/Beacon.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ceph_dencoder_CXXFLAGS) $(CXXFLAGS) -MT mds/ceph_dencoder-Beacon.obj -MD -MP -MF mds/$(DEPDIR)/ceph_dencoder-Beacon.Tpo -c -o mds/ceph_dencoder-Beacon.obj `if test -f 'mds/Beacon.cc'; then $(CYGPATH_W) 'mds/Beacon.cc'; else $(CYGPATH_W) '$(srcdir)/mds/Beacon.cc'; fi`
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) mds/$(DEPDIR)/ceph_dencoder-Beacon.Tpo mds/$(DEPDIR)/ceph_dencoder-Beacon.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='mds/Beacon.cc' object='mds/ceph_dencoder-Beacon.obj' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ceph_dencoder_CXXFLAGS) $(CXXFLAGS) -c -o mds/ceph_dencoder-Beacon.obj `if test -f 'mds/Beacon.cc'; then $(CYGPATH_W) 'mds/Beacon.cc'; else $(CYGPATH_W) '$(srcdir)/mds/Beacon.cc'; fi`
+
+mds/ceph_dencoder-journal.o: mds/journal.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ceph_dencoder_CXXFLAGS) $(CXXFLAGS) -MT mds/ceph_dencoder-journal.o -MD -MP -MF mds/$(DEPDIR)/ceph_dencoder-journal.Tpo -c -o mds/ceph_dencoder-journal.o `test -f 'mds/journal.cc' || echo '$(srcdir)/'`mds/journal.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) mds/$(DEPDIR)/ceph_dencoder-journal.Tpo mds/$(DEPDIR)/ceph_dencoder-journal.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='mds/journal.cc' object='mds/ceph_dencoder-journal.o' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ceph_dencoder_CXXFLAGS) $(CXXFLAGS) -c -o mds/ceph_dencoder-journal.o `test -f 'mds/journal.cc' || echo '$(srcdir)/'`mds/journal.cc
+
+mds/ceph_dencoder-journal.obj: mds/journal.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ceph_dencoder_CXXFLAGS) $(CXXFLAGS) -MT mds/ceph_dencoder-journal.obj -MD -MP -MF mds/$(DEPDIR)/ceph_dencoder-journal.Tpo -c -o mds/ceph_dencoder-journal.obj `if test -f 'mds/journal.cc'; then $(CYGPATH_W) 'mds/journal.cc'; else $(CYGPATH_W) '$(srcdir)/mds/journal.cc'; fi`
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) mds/$(DEPDIR)/ceph_dencoder-journal.Tpo mds/$(DEPDIR)/ceph_dencoder-journal.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='mds/journal.cc' object='mds/ceph_dencoder-journal.obj' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ceph_dencoder_CXXFLAGS) $(CXXFLAGS) -c -o mds/ceph_dencoder-journal.obj `if test -f 'mds/journal.cc'; then $(CYGPATH_W) 'mds/journal.cc'; else $(CYGPATH_W) '$(srcdir)/mds/journal.cc'; fi`
+
+mds/ceph_dencoder-Server.o: mds/Server.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ceph_dencoder_CXXFLAGS) $(CXXFLAGS) -MT mds/ceph_dencoder-Server.o -MD -MP -MF mds/$(DEPDIR)/ceph_dencoder-Server.Tpo -c -o mds/ceph_dencoder-Server.o `test -f 'mds/Server.cc' || echo '$(srcdir)/'`mds/Server.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) mds/$(DEPDIR)/ceph_dencoder-Server.Tpo mds/$(DEPDIR)/ceph_dencoder-Server.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='mds/Server.cc' object='mds/ceph_dencoder-Server.o' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ceph_dencoder_CXXFLAGS) $(CXXFLAGS) -c -o mds/ceph_dencoder-Server.o `test -f 'mds/Server.cc' || echo '$(srcdir)/'`mds/Server.cc
 
 mds/ceph_dencoder-Server.obj: mds/Server.cc
 @am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ceph_dencoder_CXXFLAGS) $(CXXFLAGS) -MT mds/ceph_dencoder-Server.obj -MD -MP -MF mds/$(DEPDIR)/ceph_dencoder-Server.Tpo -c -o mds/ceph_dencoder-Server.obj `if test -f 'mds/Server.cc'; then $(CYGPATH_W) 'mds/Server.cc'; else $(CYGPATH_W) '$(srcdir)/mds/Server.cc'; fi`
@@ -23511,6 +24724,20 @@ mds/ceph_dencoder-CInode.obj: mds/CInode.cc
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ceph_dencoder_CXXFLAGS) $(CXXFLAGS) -c -o mds/ceph_dencoder-CInode.obj `if test -f 'mds/CInode.cc'; then $(CYGPATH_W) 'mds/CInode.cc'; else $(CYGPATH_W) '$(srcdir)/mds/CInode.cc'; fi`
 
+mds/ceph_dencoder-DamageTable.o: mds/DamageTable.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ceph_dencoder_CXXFLAGS) $(CXXFLAGS) -MT mds/ceph_dencoder-DamageTable.o -MD -MP -MF mds/$(DEPDIR)/ceph_dencoder-DamageTable.Tpo -c -o mds/ceph_dencoder-DamageTable.o `test -f 'mds/DamageTable.cc' || echo '$(srcdir)/'`mds/DamageTable.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) mds/$(DEPDIR)/ceph_dencoder-DamageTable.Tpo mds/$(DEPDIR)/ceph_dencoder-DamageTable.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='mds/DamageTable.cc' object='mds/ceph_dencoder-DamageTable.o' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ceph_dencoder_CXXFLAGS) $(CXXFLAGS) -c -o mds/ceph_dencoder-DamageTable.o `test -f 'mds/DamageTable.cc' || echo '$(srcdir)/'`mds/DamageTable.cc
+
+mds/ceph_dencoder-DamageTable.obj: mds/DamageTable.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ceph_dencoder_CXXFLAGS) $(CXXFLAGS) -MT mds/ceph_dencoder-DamageTable.obj -MD -MP -MF mds/$(DEPDIR)/ceph_dencoder-DamageTable.Tpo -c -o mds/ceph_dencoder-DamageTable.obj `if test -f 'mds/DamageTable.cc'; then $(CYGPATH_W) 'mds/DamageTable.cc'; else $(CYGPATH_W) '$(srcdir)/mds/DamageTable.cc'; fi`
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) mds/$(DEPDIR)/ceph_dencoder-DamageTable.Tpo mds/$(DEPDIR)/ceph_dencoder-DamageTable.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='mds/DamageTable.cc' object='mds/ceph_dencoder-DamageTable.obj' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ceph_dencoder_CXXFLAGS) $(CXXFLAGS) -c -o mds/ceph_dencoder-DamageTable.obj `if test -f 'mds/DamageTable.cc'; then $(CYGPATH_W) 'mds/DamageTable.cc'; else $(CYGPATH_W) '$(srcdir)/mds/DamageTable.cc'; fi`
+
 mds/ceph_dencoder-LogEvent.o: mds/LogEvent.cc
 @am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ceph_dencoder_CXXFLAGS) $(CXXFLAGS) -MT mds/ceph_dencoder-LogEvent.o -MD -MP -MF mds/$(DEPDIR)/ceph_dencoder-LogEvent.Tpo -c -o mds/ceph_dencoder-LogEvent.o `test -f 'mds/LogEvent.cc' || echo '$(srcdir)/'`mds/LogEvent.cc
 @am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) mds/$(DEPDIR)/ceph_dencoder-LogEvent.Tpo mds/$(DEPDIR)/ceph_dencoder-LogEvent.Po
@@ -23833,6 +25060,20 @@ rgw/ceph_dencoder-rgw_json_enc.obj: rgw/rgw_json_enc.cc
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ceph_dencoder_CXXFLAGS) $(CXXFLAGS) -c -o rgw/ceph_dencoder-rgw_json_enc.obj `if test -f 'rgw/rgw_json_enc.cc'; then $(CYGPATH_W) 'rgw/rgw_json_enc.cc'; else $(CYGPATH_W) '$(srcdir)/rgw/rgw_json_enc.cc'; fi`
 
+rgw/ceph_dencoder-rgw_keystone.o: rgw/rgw_keystone.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ceph_dencoder_CXXFLAGS) $(CXXFLAGS) -MT rgw/ceph_dencoder-rgw_keystone.o -MD -MP -MF rgw/$(DEPDIR)/ceph_dencoder-rgw_keystone.Tpo -c -o rgw/ceph_dencoder-rgw_keystone.o `test -f 'rgw/rgw_keystone.cc' || echo '$(srcdir)/'`rgw/rgw_keystone.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/ceph_dencoder-rgw_keystone.Tpo rgw/$(DEPDIR)/ceph_dencoder-rgw_keystone.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_keystone.cc' object='rgw/ceph_dencoder-rgw_keystone.o' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ceph_dencoder_CXXFLAGS) $(CXXFLAGS) -c -o rgw/ceph_dencoder-rgw_keystone.o `test -f 'rgw/rgw_keystone.cc' || echo '$(srcdir)/'`rgw/rgw_keystone.cc
+
+rgw/ceph_dencoder-rgw_keystone.obj: rgw/rgw_keystone.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ceph_dencoder_CXXFLAGS) $(CXXFLAGS) -MT rgw/ceph_dencoder-rgw_keystone.obj -MD -MP -MF rgw/$(DEPDIR)/ceph_dencoder-rgw_keystone.Tpo -c -o rgw/ceph_dencoder-rgw_keystone.obj `if test -f 'rgw/rgw_keystone.cc'; then $(CYGPATH_W) 'rgw/rgw_keystone.cc'; else $(CYGPATH_W) '$(srcdir)/rgw/rgw_keystone.cc'; fi`
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/ceph_dencoder-rgw_keystone.Tpo rgw/$(DEPDIR)/ceph_dencoder-rgw_keystone.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_keystone.cc' object='rgw/ceph_dencoder-rgw_keystone.obj' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ceph_dencoder_CXXFLAGS) $(CXXFLAGS) -c -o rgw/ceph_dencoder-rgw_keystone.obj `if test -f 'rgw/rgw_keystone.cc'; then $(CYGPATH_W) 'rgw/rgw_keystone.cc'; else $(CYGPATH_W) '$(srcdir)/rgw/rgw_keystone.cc'; fi`
+
 tools/ceph_kvstore_tool-ceph_kvstore_tool.o: tools/ceph_kvstore_tool.cc
 @am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ceph_kvstore_tool_CXXFLAGS) $(CXXFLAGS) -MT tools/ceph_kvstore_tool-ceph_kvstore_tool.o -MD -MP -MF tools/$(DEPDIR)/ceph_kvstore_tool-ceph_kvstore_tool.Tpo -c -o tools/ceph_kvstore_tool-ceph_kvstore_tool.o `test -f 'tools/ceph_kvstore_tool.cc' || echo '$(srcdir)/'`tools/ceph_kvstore_tool.cc
 @am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) tools/$(DEPDIR)/ceph_kvstore_tool-ceph_kvstore_tool.Tpo tools/$(DEPDIR)/ceph_kvstore_tool-ceph_kvstore_tool.Po
@@ -24673,6 +25914,48 @@ osd/ceph_test_rados_api_tier-HitSet.obj: osd/HitSet.cc
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ceph_test_rados_api_tier_CXXFLAGS) $(CXXFLAGS) -c -o osd/ceph_test_rados_api_tier-HitSet.obj `if test -f 'osd/HitSet.cc'; then $(CYGPATH_W) 'osd/HitSet.cc'; else $(CYGPATH_W) '$(srcdir)/osd/HitSet.cc'; fi`
 
+test/librados/ceph_test_rados_api_tmap_migrate-tmap_migrate.o: test/librados/tmap_migrate.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ceph_test_rados_api_tmap_migrate_CXXFLAGS) $(CXXFLAGS) -MT test/librados/ceph_test_rados_api_tmap_migrate-tmap_migrate.o -MD -MP -MF test/librados/$(DEPDIR)/ceph_test_rados_api_tmap_migrate-tmap_migrate.Tpo -c -o test/librados/ceph_test_rados_api_tmap_migrate-tmap_migrate.o `test -f 'test/librados/tmap_migrate.cc' || echo '$(srcdir)/'`test/librados/tmap_migrate.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) test/librados/$(DEPDIR)/ceph_test_rados_api_tmap_migrate-tmap_migrate.Tpo test/librados/$(DEPDIR)/ceph_test_rados_api_tmap_migrate-tmap_migrate.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='test/librados/tmap_migrate.cc' object='test/librados/ceph_test_rados_api_tmap_migrate-tmap_migrate.o' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ceph_test_rados_api_tmap_migrate_CXXFLAGS) $(CXXFLAGS) -c -o test/librados/ceph_test_rados_api_tmap_migrate-tmap_migrate.o `test -f 'test/librados/tmap_migrate.cc' || echo '$(srcdir)/'`test/librados/tmap_migrate.cc
+
+test/librados/ceph_test_rados_api_tmap_migrate-tmap_migrate.obj: test/librados/tmap_migrate.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ceph_test_rados_api_tmap_migrate_CXXFLAGS) $(CXXFLAGS) -MT test/librados/ceph_test_rados_api_tmap_migrate-tmap_migrate.obj -MD -MP -MF test/librados/$(DEPDIR)/ceph_test_rados_api_tmap_migrate-tmap_migrate.Tpo -c -o test/librados/ceph_test_rados_api_tmap_migrate-tmap_migrate.obj `if test -f 'test/librados/tmap_migrate.cc'; then $(CYGPATH_W) 'test/librados/tmap_migrate.cc'; else $(C [...]
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) test/librados/$(DEPDIR)/ceph_test_rados_api_tmap_migrate-tmap_migrate.Tpo test/librados/$(DEPDIR)/ceph_test_rados_api_tmap_migrate-tmap_migrate.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='test/librados/tmap_migrate.cc' object='test/librados/ceph_test_rados_api_tmap_migrate-tmap_migrate.obj' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ceph_test_rados_api_tmap_migrate_CXXFLAGS) $(CXXFLAGS) -c -o test/librados/ceph_test_rados_api_tmap_migrate-tmap_migrate.obj `if test -f 'test/librados/tmap_migrate.cc'; then $(CYGPATH_W) 'test/librados/tmap_migrate.cc'; else $(CYGPATH_W) '$(srcdir)/test/librados/tmap_migrate.cc'; fi`
+
+tools/cephfs/ceph_test_rados_api_tmap_migrate-DataScan.o: tools/cephfs/DataScan.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ceph_test_rados_api_tmap_migrate_CXXFLAGS) $(CXXFLAGS) -MT tools/cephfs/ceph_test_rados_api_tmap_migrate-DataScan.o -MD -MP -MF tools/cephfs/$(DEPDIR)/ceph_test_rados_api_tmap_migrate-DataScan.Tpo -c -o tools/cephfs/ceph_test_rados_api_tmap_migrate-DataScan.o `test -f 'tools/cephfs/DataScan.cc' || echo '$(srcdir)/'`tools/cephfs/DataScan.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) tools/cephfs/$(DEPDIR)/ceph_test_rados_api_tmap_migrate-DataScan.Tpo tools/cephfs/$(DEPDIR)/ceph_test_rados_api_tmap_migrate-DataScan.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='tools/cephfs/DataScan.cc' object='tools/cephfs/ceph_test_rados_api_tmap_migrate-DataScan.o' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ceph_test_rados_api_tmap_migrate_CXXFLAGS) $(CXXFLAGS) -c -o tools/cephfs/ceph_test_rados_api_tmap_migrate-DataScan.o `test -f 'tools/cephfs/DataScan.cc' || echo '$(srcdir)/'`tools/cephfs/DataScan.cc
+
+tools/cephfs/ceph_test_rados_api_tmap_migrate-DataScan.obj: tools/cephfs/DataScan.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ceph_test_rados_api_tmap_migrate_CXXFLAGS) $(CXXFLAGS) -MT tools/cephfs/ceph_test_rados_api_tmap_migrate-DataScan.obj -MD -MP -MF tools/cephfs/$(DEPDIR)/ceph_test_rados_api_tmap_migrate-DataScan.Tpo -c -o tools/cephfs/ceph_test_rados_api_tmap_migrate-DataScan.obj `if test -f 'tools/cephfs/DataScan.cc'; then $(CYGPATH_W) 'tools/cephfs/DataScan.cc'; else $(CYGPATH_W) '$(srcdir)/tool [...]
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) tools/cephfs/$(DEPDIR)/ceph_test_rados_api_tmap_migrate-DataScan.Tpo tools/cephfs/$(DEPDIR)/ceph_test_rados_api_tmap_migrate-DataScan.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='tools/cephfs/DataScan.cc' object='tools/cephfs/ceph_test_rados_api_tmap_migrate-DataScan.obj' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ceph_test_rados_api_tmap_migrate_CXXFLAGS) $(CXXFLAGS) -c -o tools/cephfs/ceph_test_rados_api_tmap_migrate-DataScan.obj `if test -f 'tools/cephfs/DataScan.cc'; then $(CYGPATH_W) 'tools/cephfs/DataScan.cc'; else $(CYGPATH_W) '$(srcdir)/tools/cephfs/DataScan.cc'; fi`
+
+tools/cephfs/ceph_test_rados_api_tmap_migrate-MDSUtility.o: tools/cephfs/MDSUtility.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ceph_test_rados_api_tmap_migrate_CXXFLAGS) $(CXXFLAGS) -MT tools/cephfs/ceph_test_rados_api_tmap_migrate-MDSUtility.o -MD -MP -MF tools/cephfs/$(DEPDIR)/ceph_test_rados_api_tmap_migrate-MDSUtility.Tpo -c -o tools/cephfs/ceph_test_rados_api_tmap_migrate-MDSUtility.o `test -f 'tools/cephfs/MDSUtility.cc' || echo '$(srcdir)/'`tools/cephfs/MDSUtility.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) tools/cephfs/$(DEPDIR)/ceph_test_rados_api_tmap_migrate-MDSUtility.Tpo tools/cephfs/$(DEPDIR)/ceph_test_rados_api_tmap_migrate-MDSUtility.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='tools/cephfs/MDSUtility.cc' object='tools/cephfs/ceph_test_rados_api_tmap_migrate-MDSUtility.o' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ceph_test_rados_api_tmap_migrate_CXXFLAGS) $(CXXFLAGS) -c -o tools/cephfs/ceph_test_rados_api_tmap_migrate-MDSUtility.o `test -f 'tools/cephfs/MDSUtility.cc' || echo '$(srcdir)/'`tools/cephfs/MDSUtility.cc
+
+tools/cephfs/ceph_test_rados_api_tmap_migrate-MDSUtility.obj: tools/cephfs/MDSUtility.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ceph_test_rados_api_tmap_migrate_CXXFLAGS) $(CXXFLAGS) -MT tools/cephfs/ceph_test_rados_api_tmap_migrate-MDSUtility.obj -MD -MP -MF tools/cephfs/$(DEPDIR)/ceph_test_rados_api_tmap_migrate-MDSUtility.Tpo -c -o tools/cephfs/ceph_test_rados_api_tmap_migrate-MDSUtility.obj `if test -f 'tools/cephfs/MDSUtility.cc'; then $(CYGPATH_W) 'tools/cephfs/MDSUtility.cc'; else $(CYGPATH_W) '$(sr [...]
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) tools/cephfs/$(DEPDIR)/ceph_test_rados_api_tmap_migrate-MDSUtility.Tpo tools/cephfs/$(DEPDIR)/ceph_test_rados_api_tmap_migrate-MDSUtility.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='tools/cephfs/MDSUtility.cc' object='tools/cephfs/ceph_test_rados_api_tmap_migrate-MDSUtility.obj' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ceph_test_rados_api_tmap_migrate_CXXFLAGS) $(CXXFLAGS) -c -o tools/cephfs/ceph_test_rados_api_tmap_migrate-MDSUtility.obj `if test -f 'tools/cephfs/MDSUtility.cc'; then $(CYGPATH_W) 'tools/cephfs/MDSUtility.cc'; else $(CYGPATH_W) '$(srcdir)/tools/cephfs/MDSUtility.cc'; fi`
+
 test/librados/ceph_test_rados_api_watch_notify-watch_notify.o: test/librados/watch_notify.cc
 @am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ceph_test_rados_api_watch_notify_CXXFLAGS) $(CXXFLAGS) -MT test/librados/ceph_test_rados_api_watch_notify-watch_notify.o -MD -MP -MF test/librados/$(DEPDIR)/ceph_test_rados_api_watch_notify-watch_notify.Tpo -c -o test/librados/ceph_test_rados_api_watch_notify-watch_notify.o `test -f 'test/librados/watch_notify.cc' || echo '$(srcdir)/'`test/librados/watch_notify.cc
 @am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) test/librados/$(DEPDIR)/ceph_test_rados_api_watch_notify-watch_notify.Tpo test/librados/$(DEPDIR)/ceph_test_rados_api_watch_notify-watch_notify.Po
@@ -24771,6 +26054,20 @@ test/rgw/ceph_test_rgw_obj-test_rgw_obj.obj: test/rgw/test_rgw_obj.cc
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ceph_test_rgw_obj_CXXFLAGS) $(CXXFLAGS) -c -o test/rgw/ceph_test_rgw_obj-test_rgw_obj.obj `if test -f 'test/rgw/test_rgw_obj.cc'; then $(CYGPATH_W) 'test/rgw/test_rgw_obj.cc'; else $(CYGPATH_W) '$(srcdir)/test/rgw/test_rgw_obj.cc'; fi`
 
+test/rgw/ceph_test_rgw_period_history-test_rgw_period_history.o: test/rgw/test_rgw_period_history.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ceph_test_rgw_period_history_CXXFLAGS) $(CXXFLAGS) -MT test/rgw/ceph_test_rgw_period_history-test_rgw_period_history.o -MD -MP -MF test/rgw/$(DEPDIR)/ceph_test_rgw_period_history-test_rgw_period_history.Tpo -c -o test/rgw/ceph_test_rgw_period_history-test_rgw_period_history.o `test -f 'test/rgw/test_rgw_period_history.cc' || echo '$(srcdir)/'`test/rgw/test_rgw_period_history.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) test/rgw/$(DEPDIR)/ceph_test_rgw_period_history-test_rgw_period_history.Tpo test/rgw/$(DEPDIR)/ceph_test_rgw_period_history-test_rgw_period_history.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='test/rgw/test_rgw_period_history.cc' object='test/rgw/ceph_test_rgw_period_history-test_rgw_period_history.o' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ceph_test_rgw_period_history_CXXFLAGS) $(CXXFLAGS) -c -o test/rgw/ceph_test_rgw_period_history-test_rgw_period_history.o `test -f 'test/rgw/test_rgw_period_history.cc' || echo '$(srcdir)/'`test/rgw/test_rgw_period_history.cc
+
+test/rgw/ceph_test_rgw_period_history-test_rgw_period_history.obj: test/rgw/test_rgw_period_history.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ceph_test_rgw_period_history_CXXFLAGS) $(CXXFLAGS) -MT test/rgw/ceph_test_rgw_period_history-test_rgw_period_history.obj -MD -MP -MF test/rgw/$(DEPDIR)/ceph_test_rgw_period_history-test_rgw_period_history.Tpo -c -o test/rgw/ceph_test_rgw_period_history-test_rgw_period_history.obj `if test -f 'test/rgw/test_rgw_period_history.cc'; then $(CYGPATH_W) 'test/rgw/test_rgw_period_history [...]
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) test/rgw/$(DEPDIR)/ceph_test_rgw_period_history-test_rgw_period_history.Tpo test/rgw/$(DEPDIR)/ceph_test_rgw_period_history-test_rgw_period_history.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='test/rgw/test_rgw_period_history.cc' object='test/rgw/ceph_test_rgw_period_history-test_rgw_period_history.obj' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ceph_test_rgw_period_history_CXXFLAGS) $(CXXFLAGS) -c -o test/rgw/ceph_test_rgw_period_history-test_rgw_period_history.obj `if test -f 'test/rgw/test_rgw_period_history.cc'; then $(CYGPATH_W) 'test/rgw/test_rgw_period_history.cc'; else $(CYGPATH_W) '$(srcdir)/test/rgw/test_rgw_period_history.cc'; fi`
+
 test/ceph_test_snap_mapper-test_snap_mapper.o: test/test_snap_mapper.cc
 @am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ceph_test_snap_mapper_CXXFLAGS) $(CXXFLAGS) -MT test/ceph_test_snap_mapper-test_snap_mapper.o -MD -MP -MF test/$(DEPDIR)/ceph_test_snap_mapper-test_snap_mapper.Tpo -c -o test/ceph_test_snap_mapper-test_snap_mapper.o `test -f 'test/test_snap_mapper.cc' || echo '$(srcdir)/'`test/test_snap_mapper.cc
 @am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) test/$(DEPDIR)/ceph_test_snap_mapper-test_snap_mapper.Tpo test/$(DEPDIR)/ceph_test_snap_mapper-test_snap_mapper.Po
@@ -24813,6 +26110,76 @@ test/ceph_xattr_bench-xattr_bench.obj: test/xattr_bench.cc
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ceph_xattr_bench_CXXFLAGS) $(CXXFLAGS) -c -o test/ceph_xattr_bench-xattr_bench.obj `if test -f 'test/xattr_bench.cc'; then $(CYGPATH_W) 'test/xattr_bench.cc'; else $(CYGPATH_W) '$(srcdir)/test/xattr_bench.cc'; fi`
 
+test/librgw_file-librgw_file.o: test/librgw_file.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librgw_file_CXXFLAGS) $(CXXFLAGS) -MT test/librgw_file-librgw_file.o -MD -MP -MF test/$(DEPDIR)/librgw_file-librgw_file.Tpo -c -o test/librgw_file-librgw_file.o `test -f 'test/librgw_file.cc' || echo '$(srcdir)/'`test/librgw_file.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) test/$(DEPDIR)/librgw_file-librgw_file.Tpo test/$(DEPDIR)/librgw_file-librgw_file.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='test/librgw_file.cc' object='test/librgw_file-librgw_file.o' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librgw_file_CXXFLAGS) $(CXXFLAGS) -c -o test/librgw_file-librgw_file.o `test -f 'test/librgw_file.cc' || echo '$(srcdir)/'`test/librgw_file.cc
+
+test/librgw_file-librgw_file.obj: test/librgw_file.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librgw_file_CXXFLAGS) $(CXXFLAGS) -MT test/librgw_file-librgw_file.obj -MD -MP -MF test/$(DEPDIR)/librgw_file-librgw_file.Tpo -c -o test/librgw_file-librgw_file.obj `if test -f 'test/librgw_file.cc'; then $(CYGPATH_W) 'test/librgw_file.cc'; else $(CYGPATH_W) '$(srcdir)/test/librgw_file.cc'; fi`
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) test/$(DEPDIR)/librgw_file-librgw_file.Tpo test/$(DEPDIR)/librgw_file-librgw_file.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='test/librgw_file.cc' object='test/librgw_file-librgw_file.obj' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librgw_file_CXXFLAGS) $(CXXFLAGS) -c -o test/librgw_file-librgw_file.obj `if test -f 'test/librgw_file.cc'; then $(CYGPATH_W) 'test/librgw_file.cc'; else $(CYGPATH_W) '$(srcdir)/test/librgw_file.cc'; fi`
+
+test/librgw_file_aw-librgw_file_aw.o: test/librgw_file_aw.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librgw_file_aw_CXXFLAGS) $(CXXFLAGS) -MT test/librgw_file_aw-librgw_file_aw.o -MD -MP -MF test/$(DEPDIR)/librgw_file_aw-librgw_file_aw.Tpo -c -o test/librgw_file_aw-librgw_file_aw.o `test -f 'test/librgw_file_aw.cc' || echo '$(srcdir)/'`test/librgw_file_aw.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) test/$(DEPDIR)/librgw_file_aw-librgw_file_aw.Tpo test/$(DEPDIR)/librgw_file_aw-librgw_file_aw.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='test/librgw_file_aw.cc' object='test/librgw_file_aw-librgw_file_aw.o' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librgw_file_aw_CXXFLAGS) $(CXXFLAGS) -c -o test/librgw_file_aw-librgw_file_aw.o `test -f 'test/librgw_file_aw.cc' || echo '$(srcdir)/'`test/librgw_file_aw.cc
+
+test/librgw_file_aw-librgw_file_aw.obj: test/librgw_file_aw.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librgw_file_aw_CXXFLAGS) $(CXXFLAGS) -MT test/librgw_file_aw-librgw_file_aw.obj -MD -MP -MF test/$(DEPDIR)/librgw_file_aw-librgw_file_aw.Tpo -c -o test/librgw_file_aw-librgw_file_aw.obj `if test -f 'test/librgw_file_aw.cc'; then $(CYGPATH_W) 'test/librgw_file_aw.cc'; else $(CYGPATH_W) '$(srcdir)/test/librgw_file_aw.cc'; fi`
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) test/$(DEPDIR)/librgw_file_aw-librgw_file_aw.Tpo test/$(DEPDIR)/librgw_file_aw-librgw_file_aw.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='test/librgw_file_aw.cc' object='test/librgw_file_aw-librgw_file_aw.obj' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librgw_file_aw_CXXFLAGS) $(CXXFLAGS) -c -o test/librgw_file_aw-librgw_file_aw.obj `if test -f 'test/librgw_file_aw.cc'; then $(CYGPATH_W) 'test/librgw_file_aw.cc'; else $(CYGPATH_W) '$(srcdir)/test/librgw_file_aw.cc'; fi`
+
+test/librgw_file_cd-librgw_file_cd.o: test/librgw_file_cd.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librgw_file_cd_CXXFLAGS) $(CXXFLAGS) -MT test/librgw_file_cd-librgw_file_cd.o -MD -MP -MF test/$(DEPDIR)/librgw_file_cd-librgw_file_cd.Tpo -c -o test/librgw_file_cd-librgw_file_cd.o `test -f 'test/librgw_file_cd.cc' || echo '$(srcdir)/'`test/librgw_file_cd.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) test/$(DEPDIR)/librgw_file_cd-librgw_file_cd.Tpo test/$(DEPDIR)/librgw_file_cd-librgw_file_cd.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='test/librgw_file_cd.cc' object='test/librgw_file_cd-librgw_file_cd.o' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librgw_file_cd_CXXFLAGS) $(CXXFLAGS) -c -o test/librgw_file_cd-librgw_file_cd.o `test -f 'test/librgw_file_cd.cc' || echo '$(srcdir)/'`test/librgw_file_cd.cc
+
+test/librgw_file_cd-librgw_file_cd.obj: test/librgw_file_cd.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librgw_file_cd_CXXFLAGS) $(CXXFLAGS) -MT test/librgw_file_cd-librgw_file_cd.obj -MD -MP -MF test/$(DEPDIR)/librgw_file_cd-librgw_file_cd.Tpo -c -o test/librgw_file_cd-librgw_file_cd.obj `if test -f 'test/librgw_file_cd.cc'; then $(CYGPATH_W) 'test/librgw_file_cd.cc'; else $(CYGPATH_W) '$(srcdir)/test/librgw_file_cd.cc'; fi`
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) test/$(DEPDIR)/librgw_file_cd-librgw_file_cd.Tpo test/$(DEPDIR)/librgw_file_cd-librgw_file_cd.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='test/librgw_file_cd.cc' object='test/librgw_file_cd-librgw_file_cd.obj' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librgw_file_cd_CXXFLAGS) $(CXXFLAGS) -c -o test/librgw_file_cd-librgw_file_cd.obj `if test -f 'test/librgw_file_cd.cc'; then $(CYGPATH_W) 'test/librgw_file_cd.cc'; else $(CYGPATH_W) '$(srcdir)/test/librgw_file_cd.cc'; fi`
+
+test/librgw_file_gp-librgw_file_gp.o: test/librgw_file_gp.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librgw_file_gp_CXXFLAGS) $(CXXFLAGS) -MT test/librgw_file_gp-librgw_file_gp.o -MD -MP -MF test/$(DEPDIR)/librgw_file_gp-librgw_file_gp.Tpo -c -o test/librgw_file_gp-librgw_file_gp.o `test -f 'test/librgw_file_gp.cc' || echo '$(srcdir)/'`test/librgw_file_gp.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) test/$(DEPDIR)/librgw_file_gp-librgw_file_gp.Tpo test/$(DEPDIR)/librgw_file_gp-librgw_file_gp.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='test/librgw_file_gp.cc' object='test/librgw_file_gp-librgw_file_gp.o' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librgw_file_gp_CXXFLAGS) $(CXXFLAGS) -c -o test/librgw_file_gp-librgw_file_gp.o `test -f 'test/librgw_file_gp.cc' || echo '$(srcdir)/'`test/librgw_file_gp.cc
+
+test/librgw_file_gp-librgw_file_gp.obj: test/librgw_file_gp.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librgw_file_gp_CXXFLAGS) $(CXXFLAGS) -MT test/librgw_file_gp-librgw_file_gp.obj -MD -MP -MF test/$(DEPDIR)/librgw_file_gp-librgw_file_gp.Tpo -c -o test/librgw_file_gp-librgw_file_gp.obj `if test -f 'test/librgw_file_gp.cc'; then $(CYGPATH_W) 'test/librgw_file_gp.cc'; else $(CYGPATH_W) '$(srcdir)/test/librgw_file_gp.cc'; fi`
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) test/$(DEPDIR)/librgw_file_gp-librgw_file_gp.Tpo test/$(DEPDIR)/librgw_file_gp-librgw_file_gp.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='test/librgw_file_gp.cc' object='test/librgw_file_gp-librgw_file_gp.obj' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librgw_file_gp_CXXFLAGS) $(CXXFLAGS) -c -o test/librgw_file_gp-librgw_file_gp.obj `if test -f 'test/librgw_file_gp.cc'; then $(CYGPATH_W) 'test/librgw_file_gp.cc'; else $(CYGPATH_W) '$(srcdir)/test/librgw_file_gp.cc'; fi`
+
+test/librgw_file_nfsns-librgw_file_nfsns.o: test/librgw_file_nfsns.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librgw_file_nfsns_CXXFLAGS) $(CXXFLAGS) -MT test/librgw_file_nfsns-librgw_file_nfsns.o -MD -MP -MF test/$(DEPDIR)/librgw_file_nfsns-librgw_file_nfsns.Tpo -c -o test/librgw_file_nfsns-librgw_file_nfsns.o `test -f 'test/librgw_file_nfsns.cc' || echo '$(srcdir)/'`test/librgw_file_nfsns.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) test/$(DEPDIR)/librgw_file_nfsns-librgw_file_nfsns.Tpo test/$(DEPDIR)/librgw_file_nfsns-librgw_file_nfsns.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='test/librgw_file_nfsns.cc' object='test/librgw_file_nfsns-librgw_file_nfsns.o' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librgw_file_nfsns_CXXFLAGS) $(CXXFLAGS) -c -o test/librgw_file_nfsns-librgw_file_nfsns.o `test -f 'test/librgw_file_nfsns.cc' || echo '$(srcdir)/'`test/librgw_file_nfsns.cc
+
+test/librgw_file_nfsns-librgw_file_nfsns.obj: test/librgw_file_nfsns.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librgw_file_nfsns_CXXFLAGS) $(CXXFLAGS) -MT test/librgw_file_nfsns-librgw_file_nfsns.obj -MD -MP -MF test/$(DEPDIR)/librgw_file_nfsns-librgw_file_nfsns.Tpo -c -o test/librgw_file_nfsns-librgw_file_nfsns.obj `if test -f 'test/librgw_file_nfsns.cc'; then $(CYGPATH_W) 'test/librgw_file_nfsns.cc'; else $(CYGPATH_W) '$(srcdir)/test/librgw_file_nfsns.cc'; fi`
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) test/$(DEPDIR)/librgw_file_nfsns-librgw_file_nfsns.Tpo test/$(DEPDIR)/librgw_file_nfsns-librgw_file_nfsns.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='test/librgw_file_nfsns.cc' object='test/librgw_file_nfsns-librgw_file_nfsns.obj' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librgw_file_nfsns_CXXFLAGS) $(CXXFLAGS) -c -o test/librgw_file_nfsns-librgw_file_nfsns.obj `if test -f 'test/librgw_file_nfsns.cc'; then $(CYGPATH_W) 'test/librgw_file_nfsns.cc'; else $(CYGPATH_W) '$(srcdir)/test/librgw_file_nfsns.cc'; fi`
+
 rbd_fuse/rbd_fuse-rbd-fuse.o: rbd_fuse/rbd-fuse.cc
 @am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rbd_fuse_CXXFLAGS) $(CXXFLAGS) -MT rbd_fuse/rbd_fuse-rbd-fuse.o -MD -MP -MF rbd_fuse/$(DEPDIR)/rbd_fuse-rbd-fuse.Tpo -c -o rbd_fuse/rbd_fuse-rbd-fuse.o `test -f 'rbd_fuse/rbd-fuse.cc' || echo '$(srcdir)/'`rbd_fuse/rbd-fuse.cc
 @am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rbd_fuse/$(DEPDIR)/rbd_fuse-rbd-fuse.Tpo rbd_fuse/$(DEPDIR)/rbd_fuse-rbd-fuse.Po
@@ -25065,20 +26432,6 @@ test/test_build_librgw-buildtest_skeleton.obj: test/buildtest_skeleton.cc
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -c -o test/test_build_librgw-buildtest_skeleton.obj `if test -f 'test/buildtest_skeleton.cc'; then $(CYGPATH_W) 'test/buildtest_skeleton.cc'; else $(CYGPATH_W) '$(srcdir)/test/buildtest_skeleton.cc'; fi`
 
-rgw/test_build_librgw-librgw.o: rgw/librgw.cc
- at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -MT rgw/test_build_librgw-librgw.o -MD -MP -MF rgw/$(DEPDIR)/test_build_librgw-librgw.Tpo -c -o rgw/test_build_librgw-librgw.o `test -f 'rgw/librgw.cc' || echo '$(srcdir)/'`rgw/librgw.cc
- at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/test_build_librgw-librgw.Tpo rgw/$(DEPDIR)/test_build_librgw-librgw.Po
- at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/librgw.cc' object='rgw/test_build_librgw-librgw.o' libtool=no @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -c -o rgw/test_build_librgw-librgw.o `test -f 'rgw/librgw.cc' || echo '$(srcdir)/'`rgw/librgw.cc
-
-rgw/test_build_librgw-librgw.obj: rgw/librgw.cc
- at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -MT rgw/test_build_librgw-librgw.obj -MD -MP -MF rgw/$(DEPDIR)/test_build_librgw-librgw.Tpo -c -o rgw/test_build_librgw-librgw.obj `if test -f 'rgw/librgw.cc'; then $(CYGPATH_W) 'rgw/librgw.cc'; else $(CYGPATH_W) '$(srcdir)/rgw/librgw.cc'; fi`
- at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/test_build_librgw-librgw.Tpo rgw/$(DEPDIR)/test_build_librgw-librgw.Po
- at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/librgw.cc' object='rgw/test_build_librgw-librgw.obj' libtool=no @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -c -o rgw/test_build_librgw-librgw.obj `if test -f 'rgw/librgw.cc'; then $(CYGPATH_W) 'rgw/librgw.cc'; else $(CYGPATH_W) '$(srcdir)/rgw/librgw.cc'; fi`
-
 rgw/test_build_librgw-rgw_acl.o: rgw/rgw_acl.cc
 @am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -MT rgw/test_build_librgw-rgw_acl.o -MD -MP -MF rgw/$(DEPDIR)/test_build_librgw-rgw_acl.Tpo -c -o rgw/test_build_librgw-rgw_acl.o `test -f 'rgw/rgw_acl.cc' || echo '$(srcdir)/'`rgw/rgw_acl.cc
 @am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/test_build_librgw-rgw_acl.Tpo rgw/$(DEPDIR)/test_build_librgw-rgw_acl.Po
@@ -25091,161 +26444,567 @@ rgw/test_build_librgw-rgw_acl.obj: rgw/rgw_acl.cc
 @am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/test_build_librgw-rgw_acl.Tpo rgw/$(DEPDIR)/test_build_librgw-rgw_acl.Po
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_acl.cc' object='rgw/test_build_librgw-rgw_acl.obj' libtool=no @AMDEPBACKSLASH@
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -c -o rgw/test_build_librgw-rgw_acl.obj `if test -f 'rgw/rgw_acl.cc'; then $(CYGPATH_W) 'rgw/rgw_acl.cc'; else $(CYGPATH_W) '$(srcdir)/rgw/rgw_acl.cc'; fi`
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -c -o rgw/test_build_librgw-rgw_acl.obj `if test -f 'rgw/rgw_acl.cc'; then $(CYGPATH_W) 'rgw/rgw_acl.cc'; else $(CYGPATH_W) '$(srcdir)/rgw/rgw_acl.cc'; fi`
+
+rgw/test_build_librgw-rgw_acl_s3.o: rgw/rgw_acl_s3.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -MT rgw/test_build_librgw-rgw_acl_s3.o -MD -MP -MF rgw/$(DEPDIR)/test_build_librgw-rgw_acl_s3.Tpo -c -o rgw/test_build_librgw-rgw_acl_s3.o `test -f 'rgw/rgw_acl_s3.cc' || echo '$(srcdir)/'`rgw/rgw_acl_s3.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/test_build_librgw-rgw_acl_s3.Tpo rgw/$(DEPDIR)/test_build_librgw-rgw_acl_s3.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_acl_s3.cc' object='rgw/test_build_librgw-rgw_acl_s3.o' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -c -o rgw/test_build_librgw-rgw_acl_s3.o `test -f 'rgw/rgw_acl_s3.cc' || echo '$(srcdir)/'`rgw/rgw_acl_s3.cc
+
+rgw/test_build_librgw-rgw_acl_s3.obj: rgw/rgw_acl_s3.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -MT rgw/test_build_librgw-rgw_acl_s3.obj -MD -MP -MF rgw/$(DEPDIR)/test_build_librgw-rgw_acl_s3.Tpo -c -o rgw/test_build_librgw-rgw_acl_s3.obj `if test -f 'rgw/rgw_acl_s3.cc'; then $(CYGPATH_W) 'rgw/rgw_acl_s3.cc'; else $(CYGPATH_W) '$(srcdir)/rgw/rgw_acl_s3.cc'; fi`
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/test_build_librgw-rgw_acl_s3.Tpo rgw/$(DEPDIR)/test_build_librgw-rgw_acl_s3.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_acl_s3.cc' object='rgw/test_build_librgw-rgw_acl_s3.obj' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -c -o rgw/test_build_librgw-rgw_acl_s3.obj `if test -f 'rgw/rgw_acl_s3.cc'; then $(CYGPATH_W) 'rgw/rgw_acl_s3.cc'; else $(CYGPATH_W) '$(srcdir)/rgw/rgw_acl_s3.cc'; fi`
+
+rgw/test_build_librgw-rgw_acl_swift.o: rgw/rgw_acl_swift.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -MT rgw/test_build_librgw-rgw_acl_swift.o -MD -MP -MF rgw/$(DEPDIR)/test_build_librgw-rgw_acl_swift.Tpo -c -o rgw/test_build_librgw-rgw_acl_swift.o `test -f 'rgw/rgw_acl_swift.cc' || echo '$(srcdir)/'`rgw/rgw_acl_swift.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/test_build_librgw-rgw_acl_swift.Tpo rgw/$(DEPDIR)/test_build_librgw-rgw_acl_swift.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_acl_swift.cc' object='rgw/test_build_librgw-rgw_acl_swift.o' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -c -o rgw/test_build_librgw-rgw_acl_swift.o `test -f 'rgw/rgw_acl_swift.cc' || echo '$(srcdir)/'`rgw/rgw_acl_swift.cc
+
+rgw/test_build_librgw-rgw_acl_swift.obj: rgw/rgw_acl_swift.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -MT rgw/test_build_librgw-rgw_acl_swift.obj -MD -MP -MF rgw/$(DEPDIR)/test_build_librgw-rgw_acl_swift.Tpo -c -o rgw/test_build_librgw-rgw_acl_swift.obj `if test -f 'rgw/rgw_acl_swift.cc'; then $(CYGPATH_W) 'rgw/rgw_acl_swift.cc'; else $(CYGPATH_W) '$(srcdir)/rgw/rgw_acl_swift.cc'; fi`
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/test_build_librgw-rgw_acl_swift.Tpo rgw/$(DEPDIR)/test_build_librgw-rgw_acl_swift.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_acl_swift.cc' object='rgw/test_build_librgw-rgw_acl_swift.obj' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -c -o rgw/test_build_librgw-rgw_acl_swift.obj `if test -f 'rgw/rgw_acl_swift.cc'; then $(CYGPATH_W) 'rgw/rgw_acl_swift.cc'; else $(CYGPATH_W) '$(srcdir)/rgw/rgw_acl_swift.cc'; fi`
+
+rgw/test_build_librgw-rgw_coroutine.o: rgw/rgw_coroutine.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -MT rgw/test_build_librgw-rgw_coroutine.o -MD -MP -MF rgw/$(DEPDIR)/test_build_librgw-rgw_coroutine.Tpo -c -o rgw/test_build_librgw-rgw_coroutine.o `test -f 'rgw/rgw_coroutine.cc' || echo '$(srcdir)/'`rgw/rgw_coroutine.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/test_build_librgw-rgw_coroutine.Tpo rgw/$(DEPDIR)/test_build_librgw-rgw_coroutine.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_coroutine.cc' object='rgw/test_build_librgw-rgw_coroutine.o' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -c -o rgw/test_build_librgw-rgw_coroutine.o `test -f 'rgw/rgw_coroutine.cc' || echo '$(srcdir)/'`rgw/rgw_coroutine.cc
+
+rgw/test_build_librgw-rgw_coroutine.obj: rgw/rgw_coroutine.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -MT rgw/test_build_librgw-rgw_coroutine.obj -MD -MP -MF rgw/$(DEPDIR)/test_build_librgw-rgw_coroutine.Tpo -c -o rgw/test_build_librgw-rgw_coroutine.obj `if test -f 'rgw/rgw_coroutine.cc'; then $(CYGPATH_W) 'rgw/rgw_coroutine.cc'; else $(CYGPATH_W) '$(srcdir)/rgw/rgw_coroutine.cc'; fi`
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/test_build_librgw-rgw_coroutine.Tpo rgw/$(DEPDIR)/test_build_librgw-rgw_coroutine.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_coroutine.cc' object='rgw/test_build_librgw-rgw_coroutine.obj' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -c -o rgw/test_build_librgw-rgw_coroutine.obj `if test -f 'rgw/rgw_coroutine.cc'; then $(CYGPATH_W) 'rgw/rgw_coroutine.cc'; else $(CYGPATH_W) '$(srcdir)/rgw/rgw_coroutine.cc'; fi`
+
+rgw/test_build_librgw-rgw_cr_rados.o: rgw/rgw_cr_rados.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -MT rgw/test_build_librgw-rgw_cr_rados.o -MD -MP -MF rgw/$(DEPDIR)/test_build_librgw-rgw_cr_rados.Tpo -c -o rgw/test_build_librgw-rgw_cr_rados.o `test -f 'rgw/rgw_cr_rados.cc' || echo '$(srcdir)/'`rgw/rgw_cr_rados.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/test_build_librgw-rgw_cr_rados.Tpo rgw/$(DEPDIR)/test_build_librgw-rgw_cr_rados.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_cr_rados.cc' object='rgw/test_build_librgw-rgw_cr_rados.o' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -c -o rgw/test_build_librgw-rgw_cr_rados.o `test -f 'rgw/rgw_cr_rados.cc' || echo '$(srcdir)/'`rgw/rgw_cr_rados.cc
+
+rgw/test_build_librgw-rgw_cr_rados.obj: rgw/rgw_cr_rados.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -MT rgw/test_build_librgw-rgw_cr_rados.obj -MD -MP -MF rgw/$(DEPDIR)/test_build_librgw-rgw_cr_rados.Tpo -c -o rgw/test_build_librgw-rgw_cr_rados.obj `if test -f 'rgw/rgw_cr_rados.cc'; then $(CYGPATH_W) 'rgw/rgw_cr_rados.cc'; else $(CYGPATH_W) '$(srcdir)/rgw/rgw_cr_rados.cc'; fi`
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/test_build_librgw-rgw_cr_rados.Tpo rgw/$(DEPDIR)/test_build_librgw-rgw_cr_rados.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_cr_rados.cc' object='rgw/test_build_librgw-rgw_cr_rados.obj' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -c -o rgw/test_build_librgw-rgw_cr_rados.obj `if test -f 'rgw/rgw_cr_rados.cc'; then $(CYGPATH_W) 'rgw/rgw_cr_rados.cc'; else $(CYGPATH_W) '$(srcdir)/rgw/rgw_cr_rados.cc'; fi`
+
+rgw/test_build_librgw-rgw_tools.o: rgw/rgw_tools.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -MT rgw/test_build_librgw-rgw_tools.o -MD -MP -MF rgw/$(DEPDIR)/test_build_librgw-rgw_tools.Tpo -c -o rgw/test_build_librgw-rgw_tools.o `test -f 'rgw/rgw_tools.cc' || echo '$(srcdir)/'`rgw/rgw_tools.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/test_build_librgw-rgw_tools.Tpo rgw/$(DEPDIR)/test_build_librgw-rgw_tools.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_tools.cc' object='rgw/test_build_librgw-rgw_tools.o' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -c -o rgw/test_build_librgw-rgw_tools.o `test -f 'rgw/rgw_tools.cc' || echo '$(srcdir)/'`rgw/rgw_tools.cc
+
+rgw/test_build_librgw-rgw_tools.obj: rgw/rgw_tools.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -MT rgw/test_build_librgw-rgw_tools.obj -MD -MP -MF rgw/$(DEPDIR)/test_build_librgw-rgw_tools.Tpo -c -o rgw/test_build_librgw-rgw_tools.obj `if test -f 'rgw/rgw_tools.cc'; then $(CYGPATH_W) 'rgw/rgw_tools.cc'; else $(CYGPATH_W) '$(srcdir)/rgw/rgw_tools.cc'; fi`
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/test_build_librgw-rgw_tools.Tpo rgw/$(DEPDIR)/test_build_librgw-rgw_tools.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_tools.cc' object='rgw/test_build_librgw-rgw_tools.obj' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -c -o rgw/test_build_librgw-rgw_tools.obj `if test -f 'rgw/rgw_tools.cc'; then $(CYGPATH_W) 'rgw/rgw_tools.cc'; else $(CYGPATH_W) '$(srcdir)/rgw/rgw_tools.cc'; fi`
+
+rgw/test_build_librgw-rgw_basic_types.o: rgw/rgw_basic_types.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -MT rgw/test_build_librgw-rgw_basic_types.o -MD -MP -MF rgw/$(DEPDIR)/test_build_librgw-rgw_basic_types.Tpo -c -o rgw/test_build_librgw-rgw_basic_types.o `test -f 'rgw/rgw_basic_types.cc' || echo '$(srcdir)/'`rgw/rgw_basic_types.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/test_build_librgw-rgw_basic_types.Tpo rgw/$(DEPDIR)/test_build_librgw-rgw_basic_types.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_basic_types.cc' object='rgw/test_build_librgw-rgw_basic_types.o' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -c -o rgw/test_build_librgw-rgw_basic_types.o `test -f 'rgw/rgw_basic_types.cc' || echo '$(srcdir)/'`rgw/rgw_basic_types.cc
+
+rgw/test_build_librgw-rgw_basic_types.obj: rgw/rgw_basic_types.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -MT rgw/test_build_librgw-rgw_basic_types.obj -MD -MP -MF rgw/$(DEPDIR)/test_build_librgw-rgw_basic_types.Tpo -c -o rgw/test_build_librgw-rgw_basic_types.obj `if test -f 'rgw/rgw_basic_types.cc'; then $(CYGPATH_W) 'rgw/rgw_basic_types.cc'; else $(CYGPATH_W) '$(srcdir)/rgw/rgw_basic_types.cc'; fi`
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/test_build_librgw-rgw_basic_types.Tpo rgw/$(DEPDIR)/test_build_librgw-rgw_basic_types.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_basic_types.cc' object='rgw/test_build_librgw-rgw_basic_types.obj' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -c -o rgw/test_build_librgw-rgw_basic_types.obj `if test -f 'rgw/rgw_basic_types.cc'; then $(CYGPATH_W) 'rgw/rgw_basic_types.cc'; else $(CYGPATH_W) '$(srcdir)/rgw/rgw_basic_types.cc'; fi`
+
+rgw/test_build_librgw-rgw_bucket.o: rgw/rgw_bucket.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -MT rgw/test_build_librgw-rgw_bucket.o -MD -MP -MF rgw/$(DEPDIR)/test_build_librgw-rgw_bucket.Tpo -c -o rgw/test_build_librgw-rgw_bucket.o `test -f 'rgw/rgw_bucket.cc' || echo '$(srcdir)/'`rgw/rgw_bucket.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/test_build_librgw-rgw_bucket.Tpo rgw/$(DEPDIR)/test_build_librgw-rgw_bucket.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_bucket.cc' object='rgw/test_build_librgw-rgw_bucket.o' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -c -o rgw/test_build_librgw-rgw_bucket.o `test -f 'rgw/rgw_bucket.cc' || echo '$(srcdir)/'`rgw/rgw_bucket.cc
+
+rgw/test_build_librgw-rgw_bucket.obj: rgw/rgw_bucket.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -MT rgw/test_build_librgw-rgw_bucket.obj -MD -MP -MF rgw/$(DEPDIR)/test_build_librgw-rgw_bucket.Tpo -c -o rgw/test_build_librgw-rgw_bucket.obj `if test -f 'rgw/rgw_bucket.cc'; then $(CYGPATH_W) 'rgw/rgw_bucket.cc'; else $(CYGPATH_W) '$(srcdir)/rgw/rgw_bucket.cc'; fi`
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/test_build_librgw-rgw_bucket.Tpo rgw/$(DEPDIR)/test_build_librgw-rgw_bucket.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_bucket.cc' object='rgw/test_build_librgw-rgw_bucket.obj' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -c -o rgw/test_build_librgw-rgw_bucket.obj `if test -f 'rgw/rgw_bucket.cc'; then $(CYGPATH_W) 'rgw/rgw_bucket.cc'; else $(CYGPATH_W) '$(srcdir)/rgw/rgw_bucket.cc'; fi`
+
+rgw/test_build_librgw-rgw_cache.o: rgw/rgw_cache.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -MT rgw/test_build_librgw-rgw_cache.o -MD -MP -MF rgw/$(DEPDIR)/test_build_librgw-rgw_cache.Tpo -c -o rgw/test_build_librgw-rgw_cache.o `test -f 'rgw/rgw_cache.cc' || echo '$(srcdir)/'`rgw/rgw_cache.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/test_build_librgw-rgw_cache.Tpo rgw/$(DEPDIR)/test_build_librgw-rgw_cache.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_cache.cc' object='rgw/test_build_librgw-rgw_cache.o' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -c -o rgw/test_build_librgw-rgw_cache.o `test -f 'rgw/rgw_cache.cc' || echo '$(srcdir)/'`rgw/rgw_cache.cc
+
+rgw/test_build_librgw-rgw_cache.obj: rgw/rgw_cache.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -MT rgw/test_build_librgw-rgw_cache.obj -MD -MP -MF rgw/$(DEPDIR)/test_build_librgw-rgw_cache.Tpo -c -o rgw/test_build_librgw-rgw_cache.obj `if test -f 'rgw/rgw_cache.cc'; then $(CYGPATH_W) 'rgw/rgw_cache.cc'; else $(CYGPATH_W) '$(srcdir)/rgw/rgw_cache.cc'; fi`
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/test_build_librgw-rgw_cache.Tpo rgw/$(DEPDIR)/test_build_librgw-rgw_cache.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_cache.cc' object='rgw/test_build_librgw-rgw_cache.obj' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -c -o rgw/test_build_librgw-rgw_cache.obj `if test -f 'rgw/rgw_cache.cc'; then $(CYGPATH_W) 'rgw/rgw_cache.cc'; else $(CYGPATH_W) '$(srcdir)/rgw/rgw_cache.cc'; fi`
+
+rgw/test_build_librgw-rgw_client_io.o: rgw/rgw_client_io.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -MT rgw/test_build_librgw-rgw_client_io.o -MD -MP -MF rgw/$(DEPDIR)/test_build_librgw-rgw_client_io.Tpo -c -o rgw/test_build_librgw-rgw_client_io.o `test -f 'rgw/rgw_client_io.cc' || echo '$(srcdir)/'`rgw/rgw_client_io.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/test_build_librgw-rgw_client_io.Tpo rgw/$(DEPDIR)/test_build_librgw-rgw_client_io.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_client_io.cc' object='rgw/test_build_librgw-rgw_client_io.o' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -c -o rgw/test_build_librgw-rgw_client_io.o `test -f 'rgw/rgw_client_io.cc' || echo '$(srcdir)/'`rgw/rgw_client_io.cc
+
+rgw/test_build_librgw-rgw_client_io.obj: rgw/rgw_client_io.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -MT rgw/test_build_librgw-rgw_client_io.obj -MD -MP -MF rgw/$(DEPDIR)/test_build_librgw-rgw_client_io.Tpo -c -o rgw/test_build_librgw-rgw_client_io.obj `if test -f 'rgw/rgw_client_io.cc'; then $(CYGPATH_W) 'rgw/rgw_client_io.cc'; else $(CYGPATH_W) '$(srcdir)/rgw/rgw_client_io.cc'; fi`
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/test_build_librgw-rgw_client_io.Tpo rgw/$(DEPDIR)/test_build_librgw-rgw_client_io.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_client_io.cc' object='rgw/test_build_librgw-rgw_client_io.obj' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -c -o rgw/test_build_librgw-rgw_client_io.obj `if test -f 'rgw/rgw_client_io.cc'; then $(CYGPATH_W) 'rgw/rgw_client_io.cc'; else $(CYGPATH_W) '$(srcdir)/rgw/rgw_client_io.cc'; fi`
+
+rgw/test_build_librgw-rgw_common.o: rgw/rgw_common.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -MT rgw/test_build_librgw-rgw_common.o -MD -MP -MF rgw/$(DEPDIR)/test_build_librgw-rgw_common.Tpo -c -o rgw/test_build_librgw-rgw_common.o `test -f 'rgw/rgw_common.cc' || echo '$(srcdir)/'`rgw/rgw_common.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/test_build_librgw-rgw_common.Tpo rgw/$(DEPDIR)/test_build_librgw-rgw_common.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_common.cc' object='rgw/test_build_librgw-rgw_common.o' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -c -o rgw/test_build_librgw-rgw_common.o `test -f 'rgw/rgw_common.cc' || echo '$(srcdir)/'`rgw/rgw_common.cc
+
+rgw/test_build_librgw-rgw_common.obj: rgw/rgw_common.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -MT rgw/test_build_librgw-rgw_common.obj -MD -MP -MF rgw/$(DEPDIR)/test_build_librgw-rgw_common.Tpo -c -o rgw/test_build_librgw-rgw_common.obj `if test -f 'rgw/rgw_common.cc'; then $(CYGPATH_W) 'rgw/rgw_common.cc'; else $(CYGPATH_W) '$(srcdir)/rgw/rgw_common.cc'; fi`
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/test_build_librgw-rgw_common.Tpo rgw/$(DEPDIR)/test_build_librgw-rgw_common.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_common.cc' object='rgw/test_build_librgw-rgw_common.obj' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -c -o rgw/test_build_librgw-rgw_common.obj `if test -f 'rgw/rgw_common.cc'; then $(CYGPATH_W) 'rgw/rgw_common.cc'; else $(CYGPATH_W) '$(srcdir)/rgw/rgw_common.cc'; fi`
+
+rgw/test_build_librgw-rgw_cors.o: rgw/rgw_cors.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -MT rgw/test_build_librgw-rgw_cors.o -MD -MP -MF rgw/$(DEPDIR)/test_build_librgw-rgw_cors.Tpo -c -o rgw/test_build_librgw-rgw_cors.o `test -f 'rgw/rgw_cors.cc' || echo '$(srcdir)/'`rgw/rgw_cors.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/test_build_librgw-rgw_cors.Tpo rgw/$(DEPDIR)/test_build_librgw-rgw_cors.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_cors.cc' object='rgw/test_build_librgw-rgw_cors.o' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -c -o rgw/test_build_librgw-rgw_cors.o `test -f 'rgw/rgw_cors.cc' || echo '$(srcdir)/'`rgw/rgw_cors.cc
+
+rgw/test_build_librgw-rgw_cors.obj: rgw/rgw_cors.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -MT rgw/test_build_librgw-rgw_cors.obj -MD -MP -MF rgw/$(DEPDIR)/test_build_librgw-rgw_cors.Tpo -c -o rgw/test_build_librgw-rgw_cors.obj `if test -f 'rgw/rgw_cors.cc'; then $(CYGPATH_W) 'rgw/rgw_cors.cc'; else $(CYGPATH_W) '$(srcdir)/rgw/rgw_cors.cc'; fi`
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/test_build_librgw-rgw_cors.Tpo rgw/$(DEPDIR)/test_build_librgw-rgw_cors.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_cors.cc' object='rgw/test_build_librgw-rgw_cors.obj' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -c -o rgw/test_build_librgw-rgw_cors.obj `if test -f 'rgw/rgw_cors.cc'; then $(CYGPATH_W) 'rgw/rgw_cors.cc'; else $(CYGPATH_W) '$(srcdir)/rgw/rgw_cors.cc'; fi`
+
+rgw/test_build_librgw-rgw_cors_s3.o: rgw/rgw_cors_s3.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -MT rgw/test_build_librgw-rgw_cors_s3.o -MD -MP -MF rgw/$(DEPDIR)/test_build_librgw-rgw_cors_s3.Tpo -c -o rgw/test_build_librgw-rgw_cors_s3.o `test -f 'rgw/rgw_cors_s3.cc' || echo '$(srcdir)/'`rgw/rgw_cors_s3.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/test_build_librgw-rgw_cors_s3.Tpo rgw/$(DEPDIR)/test_build_librgw-rgw_cors_s3.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_cors_s3.cc' object='rgw/test_build_librgw-rgw_cors_s3.o' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -c -o rgw/test_build_librgw-rgw_cors_s3.o `test -f 'rgw/rgw_cors_s3.cc' || echo '$(srcdir)/'`rgw/rgw_cors_s3.cc
+
+rgw/test_build_librgw-rgw_cors_s3.obj: rgw/rgw_cors_s3.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -MT rgw/test_build_librgw-rgw_cors_s3.obj -MD -MP -MF rgw/$(DEPDIR)/test_build_librgw-rgw_cors_s3.Tpo -c -o rgw/test_build_librgw-rgw_cors_s3.obj `if test -f 'rgw/rgw_cors_s3.cc'; then $(CYGPATH_W) 'rgw/rgw_cors_s3.cc'; else $(CYGPATH_W) '$(srcdir)/rgw/rgw_cors_s3.cc'; fi`
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/test_build_librgw-rgw_cors_s3.Tpo rgw/$(DEPDIR)/test_build_librgw-rgw_cors_s3.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_cors_s3.cc' object='rgw/test_build_librgw-rgw_cors_s3.obj' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -c -o rgw/test_build_librgw-rgw_cors_s3.obj `if test -f 'rgw/rgw_cors_s3.cc'; then $(CYGPATH_W) 'rgw/rgw_cors_s3.cc'; else $(CYGPATH_W) '$(srcdir)/rgw/rgw_cors_s3.cc'; fi`
+
+rgw/test_build_librgw-rgw_dencoder.o: rgw/rgw_dencoder.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -MT rgw/test_build_librgw-rgw_dencoder.o -MD -MP -MF rgw/$(DEPDIR)/test_build_librgw-rgw_dencoder.Tpo -c -o rgw/test_build_librgw-rgw_dencoder.o `test -f 'rgw/rgw_dencoder.cc' || echo '$(srcdir)/'`rgw/rgw_dencoder.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/test_build_librgw-rgw_dencoder.Tpo rgw/$(DEPDIR)/test_build_librgw-rgw_dencoder.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_dencoder.cc' object='rgw/test_build_librgw-rgw_dencoder.o' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -c -o rgw/test_build_librgw-rgw_dencoder.o `test -f 'rgw/rgw_dencoder.cc' || echo '$(srcdir)/'`rgw/rgw_dencoder.cc
+
+rgw/test_build_librgw-rgw_dencoder.obj: rgw/rgw_dencoder.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -MT rgw/test_build_librgw-rgw_dencoder.obj -MD -MP -MF rgw/$(DEPDIR)/test_build_librgw-rgw_dencoder.Tpo -c -o rgw/test_build_librgw-rgw_dencoder.obj `if test -f 'rgw/rgw_dencoder.cc'; then $(CYGPATH_W) 'rgw/rgw_dencoder.cc'; else $(CYGPATH_W) '$(srcdir)/rgw/rgw_dencoder.cc'; fi`
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/test_build_librgw-rgw_dencoder.Tpo rgw/$(DEPDIR)/test_build_librgw-rgw_dencoder.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_dencoder.cc' object='rgw/test_build_librgw-rgw_dencoder.obj' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -c -o rgw/test_build_librgw-rgw_dencoder.obj `if test -f 'rgw/rgw_dencoder.cc'; then $(CYGPATH_W) 'rgw/rgw_dencoder.cc'; else $(CYGPATH_W) '$(srcdir)/rgw/rgw_dencoder.cc'; fi`
+
+rgw/test_build_librgw-rgw_env.o: rgw/rgw_env.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -MT rgw/test_build_librgw-rgw_env.o -MD -MP -MF rgw/$(DEPDIR)/test_build_librgw-rgw_env.Tpo -c -o rgw/test_build_librgw-rgw_env.o `test -f 'rgw/rgw_env.cc' || echo '$(srcdir)/'`rgw/rgw_env.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/test_build_librgw-rgw_env.Tpo rgw/$(DEPDIR)/test_build_librgw-rgw_env.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_env.cc' object='rgw/test_build_librgw-rgw_env.o' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -c -o rgw/test_build_librgw-rgw_env.o `test -f 'rgw/rgw_env.cc' || echo '$(srcdir)/'`rgw/rgw_env.cc
+
+rgw/test_build_librgw-rgw_env.obj: rgw/rgw_env.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -MT rgw/test_build_librgw-rgw_env.obj -MD -MP -MF rgw/$(DEPDIR)/test_build_librgw-rgw_env.Tpo -c -o rgw/test_build_librgw-rgw_env.obj `if test -f 'rgw/rgw_env.cc'; then $(CYGPATH_W) 'rgw/rgw_env.cc'; else $(CYGPATH_W) '$(srcdir)/rgw/rgw_env.cc'; fi`
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/test_build_librgw-rgw_env.Tpo rgw/$(DEPDIR)/test_build_librgw-rgw_env.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_env.cc' object='rgw/test_build_librgw-rgw_env.obj' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -c -o rgw/test_build_librgw-rgw_env.obj `if test -f 'rgw/rgw_env.cc'; then $(CYGPATH_W) 'rgw/rgw_env.cc'; else $(CYGPATH_W) '$(srcdir)/rgw/rgw_env.cc'; fi`
+
+rgw/test_build_librgw-rgw_fcgi.o: rgw/rgw_fcgi.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -MT rgw/test_build_librgw-rgw_fcgi.o -MD -MP -MF rgw/$(DEPDIR)/test_build_librgw-rgw_fcgi.Tpo -c -o rgw/test_build_librgw-rgw_fcgi.o `test -f 'rgw/rgw_fcgi.cc' || echo '$(srcdir)/'`rgw/rgw_fcgi.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/test_build_librgw-rgw_fcgi.Tpo rgw/$(DEPDIR)/test_build_librgw-rgw_fcgi.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_fcgi.cc' object='rgw/test_build_librgw-rgw_fcgi.o' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -c -o rgw/test_build_librgw-rgw_fcgi.o `test -f 'rgw/rgw_fcgi.cc' || echo '$(srcdir)/'`rgw/rgw_fcgi.cc
+
+rgw/test_build_librgw-rgw_fcgi.obj: rgw/rgw_fcgi.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -MT rgw/test_build_librgw-rgw_fcgi.obj -MD -MP -MF rgw/$(DEPDIR)/test_build_librgw-rgw_fcgi.Tpo -c -o rgw/test_build_librgw-rgw_fcgi.obj `if test -f 'rgw/rgw_fcgi.cc'; then $(CYGPATH_W) 'rgw/rgw_fcgi.cc'; else $(CYGPATH_W) '$(srcdir)/rgw/rgw_fcgi.cc'; fi`
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/test_build_librgw-rgw_fcgi.Tpo rgw/$(DEPDIR)/test_build_librgw-rgw_fcgi.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_fcgi.cc' object='rgw/test_build_librgw-rgw_fcgi.obj' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -c -o rgw/test_build_librgw-rgw_fcgi.obj `if test -f 'rgw/rgw_fcgi.cc'; then $(CYGPATH_W) 'rgw/rgw_fcgi.cc'; else $(CYGPATH_W) '$(srcdir)/rgw/rgw_fcgi.cc'; fi`
+
+rgw/test_build_librgw-rgw_formats.o: rgw/rgw_formats.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -MT rgw/test_build_librgw-rgw_formats.o -MD -MP -MF rgw/$(DEPDIR)/test_build_librgw-rgw_formats.Tpo -c -o rgw/test_build_librgw-rgw_formats.o `test -f 'rgw/rgw_formats.cc' || echo '$(srcdir)/'`rgw/rgw_formats.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/test_build_librgw-rgw_formats.Tpo rgw/$(DEPDIR)/test_build_librgw-rgw_formats.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_formats.cc' object='rgw/test_build_librgw-rgw_formats.o' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -c -o rgw/test_build_librgw-rgw_formats.o `test -f 'rgw/rgw_formats.cc' || echo '$(srcdir)/'`rgw/rgw_formats.cc
+
+rgw/test_build_librgw-rgw_formats.obj: rgw/rgw_formats.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -MT rgw/test_build_librgw-rgw_formats.obj -MD -MP -MF rgw/$(DEPDIR)/test_build_librgw-rgw_formats.Tpo -c -o rgw/test_build_librgw-rgw_formats.obj `if test -f 'rgw/rgw_formats.cc'; then $(CYGPATH_W) 'rgw/rgw_formats.cc'; else $(CYGPATH_W) '$(srcdir)/rgw/rgw_formats.cc'; fi`
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/test_build_librgw-rgw_formats.Tpo rgw/$(DEPDIR)/test_build_librgw-rgw_formats.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_formats.cc' object='rgw/test_build_librgw-rgw_formats.obj' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -c -o rgw/test_build_librgw-rgw_formats.obj `if test -f 'rgw/rgw_formats.cc'; then $(CYGPATH_W) 'rgw/rgw_formats.cc'; else $(CYGPATH_W) '$(srcdir)/rgw/rgw_formats.cc'; fi`
+
+rgw/test_build_librgw-rgw_frontend.o: rgw/rgw_frontend.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -MT rgw/test_build_librgw-rgw_frontend.o -MD -MP -MF rgw/$(DEPDIR)/test_build_librgw-rgw_frontend.Tpo -c -o rgw/test_build_librgw-rgw_frontend.o `test -f 'rgw/rgw_frontend.cc' || echo '$(srcdir)/'`rgw/rgw_frontend.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/test_build_librgw-rgw_frontend.Tpo rgw/$(DEPDIR)/test_build_librgw-rgw_frontend.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_frontend.cc' object='rgw/test_build_librgw-rgw_frontend.o' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -c -o rgw/test_build_librgw-rgw_frontend.o `test -f 'rgw/rgw_frontend.cc' || echo '$(srcdir)/'`rgw/rgw_frontend.cc
+
+rgw/test_build_librgw-rgw_frontend.obj: rgw/rgw_frontend.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -MT rgw/test_build_librgw-rgw_frontend.obj -MD -MP -MF rgw/$(DEPDIR)/test_build_librgw-rgw_frontend.Tpo -c -o rgw/test_build_librgw-rgw_frontend.obj `if test -f 'rgw/rgw_frontend.cc'; then $(CYGPATH_W) 'rgw/rgw_frontend.cc'; else $(CYGPATH_W) '$(srcdir)/rgw/rgw_frontend.cc'; fi`
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/test_build_librgw-rgw_frontend.Tpo rgw/$(DEPDIR)/test_build_librgw-rgw_frontend.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_frontend.cc' object='rgw/test_build_librgw-rgw_frontend.obj' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -c -o rgw/test_build_librgw-rgw_frontend.obj `if test -f 'rgw/rgw_frontend.cc'; then $(CYGPATH_W) 'rgw/rgw_frontend.cc'; else $(CYGPATH_W) '$(srcdir)/rgw/rgw_frontend.cc'; fi`
+
+rgw/test_build_librgw-rgw_gc.o: rgw/rgw_gc.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -MT rgw/test_build_librgw-rgw_gc.o -MD -MP -MF rgw/$(DEPDIR)/test_build_librgw-rgw_gc.Tpo -c -o rgw/test_build_librgw-rgw_gc.o `test -f 'rgw/rgw_gc.cc' || echo '$(srcdir)/'`rgw/rgw_gc.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/test_build_librgw-rgw_gc.Tpo rgw/$(DEPDIR)/test_build_librgw-rgw_gc.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_gc.cc' object='rgw/test_build_librgw-rgw_gc.o' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -c -o rgw/test_build_librgw-rgw_gc.o `test -f 'rgw/rgw_gc.cc' || echo '$(srcdir)/'`rgw/rgw_gc.cc
+
+rgw/test_build_librgw-rgw_gc.obj: rgw/rgw_gc.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -MT rgw/test_build_librgw-rgw_gc.obj -MD -MP -MF rgw/$(DEPDIR)/test_build_librgw-rgw_gc.Tpo -c -o rgw/test_build_librgw-rgw_gc.obj `if test -f 'rgw/rgw_gc.cc'; then $(CYGPATH_W) 'rgw/rgw_gc.cc'; else $(CYGPATH_W) '$(srcdir)/rgw/rgw_gc.cc'; fi`
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/test_build_librgw-rgw_gc.Tpo rgw/$(DEPDIR)/test_build_librgw-rgw_gc.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_gc.cc' object='rgw/test_build_librgw-rgw_gc.obj' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -c -o rgw/test_build_librgw-rgw_gc.obj `if test -f 'rgw/rgw_gc.cc'; then $(CYGPATH_W) 'rgw/rgw_gc.cc'; else $(CYGPATH_W) '$(srcdir)/rgw/rgw_gc.cc'; fi`
+
+rgw/test_build_librgw-rgw_http_client.o: rgw/rgw_http_client.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -MT rgw/test_build_librgw-rgw_http_client.o -MD -MP -MF rgw/$(DEPDIR)/test_build_librgw-rgw_http_client.Tpo -c -o rgw/test_build_librgw-rgw_http_client.o `test -f 'rgw/rgw_http_client.cc' || echo '$(srcdir)/'`rgw/rgw_http_client.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/test_build_librgw-rgw_http_client.Tpo rgw/$(DEPDIR)/test_build_librgw-rgw_http_client.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_http_client.cc' object='rgw/test_build_librgw-rgw_http_client.o' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -c -o rgw/test_build_librgw-rgw_http_client.o `test -f 'rgw/rgw_http_client.cc' || echo '$(srcdir)/'`rgw/rgw_http_client.cc
+
+rgw/test_build_librgw-rgw_http_client.obj: rgw/rgw_http_client.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -MT rgw/test_build_librgw-rgw_http_client.obj -MD -MP -MF rgw/$(DEPDIR)/test_build_librgw-rgw_http_client.Tpo -c -o rgw/test_build_librgw-rgw_http_client.obj `if test -f 'rgw/rgw_http_client.cc'; then $(CYGPATH_W) 'rgw/rgw_http_client.cc'; else $(CYGPATH_W) '$(srcdir)/rgw/rgw_http_client.cc'; fi`
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/test_build_librgw-rgw_http_client.Tpo rgw/$(DEPDIR)/test_build_librgw-rgw_http_client.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_http_client.cc' object='rgw/test_build_librgw-rgw_http_client.obj' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -c -o rgw/test_build_librgw-rgw_http_client.obj `if test -f 'rgw/rgw_http_client.cc'; then $(CYGPATH_W) 'rgw/rgw_http_client.cc'; else $(CYGPATH_W) '$(srcdir)/rgw/rgw_http_client.cc'; fi`
+
+rgw/test_build_librgw-rgw_json_enc.o: rgw/rgw_json_enc.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -MT rgw/test_build_librgw-rgw_json_enc.o -MD -MP -MF rgw/$(DEPDIR)/test_build_librgw-rgw_json_enc.Tpo -c -o rgw/test_build_librgw-rgw_json_enc.o `test -f 'rgw/rgw_json_enc.cc' || echo '$(srcdir)/'`rgw/rgw_json_enc.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/test_build_librgw-rgw_json_enc.Tpo rgw/$(DEPDIR)/test_build_librgw-rgw_json_enc.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_json_enc.cc' object='rgw/test_build_librgw-rgw_json_enc.o' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -c -o rgw/test_build_librgw-rgw_json_enc.o `test -f 'rgw/rgw_json_enc.cc' || echo '$(srcdir)/'`rgw/rgw_json_enc.cc
+
+rgw/test_build_librgw-rgw_json_enc.obj: rgw/rgw_json_enc.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -MT rgw/test_build_librgw-rgw_json_enc.obj -MD -MP -MF rgw/$(DEPDIR)/test_build_librgw-rgw_json_enc.Tpo -c -o rgw/test_build_librgw-rgw_json_enc.obj `if test -f 'rgw/rgw_json_enc.cc'; then $(CYGPATH_W) 'rgw/rgw_json_enc.cc'; else $(CYGPATH_W) '$(srcdir)/rgw/rgw_json_enc.cc'; fi`
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/test_build_librgw-rgw_json_enc.Tpo rgw/$(DEPDIR)/test_build_librgw-rgw_json_enc.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_json_enc.cc' object='rgw/test_build_librgw-rgw_json_enc.obj' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -c -o rgw/test_build_librgw-rgw_json_enc.obj `if test -f 'rgw/rgw_json_enc.cc'; then $(CYGPATH_W) 'rgw/rgw_json_enc.cc'; else $(CYGPATH_W) '$(srcdir)/rgw/rgw_json_enc.cc'; fi`
+
+rgw/test_build_librgw-rgw_keystone.o: rgw/rgw_keystone.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -MT rgw/test_build_librgw-rgw_keystone.o -MD -MP -MF rgw/$(DEPDIR)/test_build_librgw-rgw_keystone.Tpo -c -o rgw/test_build_librgw-rgw_keystone.o `test -f 'rgw/rgw_keystone.cc' || echo '$(srcdir)/'`rgw/rgw_keystone.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/test_build_librgw-rgw_keystone.Tpo rgw/$(DEPDIR)/test_build_librgw-rgw_keystone.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_keystone.cc' object='rgw/test_build_librgw-rgw_keystone.o' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -c -o rgw/test_build_librgw-rgw_keystone.o `test -f 'rgw/rgw_keystone.cc' || echo '$(srcdir)/'`rgw/rgw_keystone.cc
+
+rgw/test_build_librgw-rgw_keystone.obj: rgw/rgw_keystone.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -MT rgw/test_build_librgw-rgw_keystone.obj -MD -MP -MF rgw/$(DEPDIR)/test_build_librgw-rgw_keystone.Tpo -c -o rgw/test_build_librgw-rgw_keystone.obj `if test -f 'rgw/rgw_keystone.cc'; then $(CYGPATH_W) 'rgw/rgw_keystone.cc'; else $(CYGPATH_W) '$(srcdir)/rgw/rgw_keystone.cc'; fi`
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/test_build_librgw-rgw_keystone.Tpo rgw/$(DEPDIR)/test_build_librgw-rgw_keystone.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_keystone.cc' object='rgw/test_build_librgw-rgw_keystone.obj' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -c -o rgw/test_build_librgw-rgw_keystone.obj `if test -f 'rgw/rgw_keystone.cc'; then $(CYGPATH_W) 'rgw/rgw_keystone.cc'; else $(CYGPATH_W) '$(srcdir)/rgw/rgw_keystone.cc'; fi`
+
+rgw/test_build_librgw-rgw_loadgen.o: rgw/rgw_loadgen.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -MT rgw/test_build_librgw-rgw_loadgen.o -MD -MP -MF rgw/$(DEPDIR)/test_build_librgw-rgw_loadgen.Tpo -c -o rgw/test_build_librgw-rgw_loadgen.o `test -f 'rgw/rgw_loadgen.cc' || echo '$(srcdir)/'`rgw/rgw_loadgen.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/test_build_librgw-rgw_loadgen.Tpo rgw/$(DEPDIR)/test_build_librgw-rgw_loadgen.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_loadgen.cc' object='rgw/test_build_librgw-rgw_loadgen.o' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -c -o rgw/test_build_librgw-rgw_loadgen.o `test -f 'rgw/rgw_loadgen.cc' || echo '$(srcdir)/'`rgw/rgw_loadgen.cc
+
+rgw/test_build_librgw-rgw_loadgen.obj: rgw/rgw_loadgen.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -MT rgw/test_build_librgw-rgw_loadgen.obj -MD -MP -MF rgw/$(DEPDIR)/test_build_librgw-rgw_loadgen.Tpo -c -o rgw/test_build_librgw-rgw_loadgen.obj `if test -f 'rgw/rgw_loadgen.cc'; then $(CYGPATH_W) 'rgw/rgw_loadgen.cc'; else $(CYGPATH_W) '$(srcdir)/rgw/rgw_loadgen.cc'; fi`
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/test_build_librgw-rgw_loadgen.Tpo rgw/$(DEPDIR)/test_build_librgw-rgw_loadgen.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_loadgen.cc' object='rgw/test_build_librgw-rgw_loadgen.obj' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -c -o rgw/test_build_librgw-rgw_loadgen.obj `if test -f 'rgw/rgw_loadgen.cc'; then $(CYGPATH_W) 'rgw/rgw_loadgen.cc'; else $(CYGPATH_W) '$(srcdir)/rgw/rgw_loadgen.cc'; fi`
+
+rgw/test_build_librgw-rgw_log.o: rgw/rgw_log.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -MT rgw/test_build_librgw-rgw_log.o -MD -MP -MF rgw/$(DEPDIR)/test_build_librgw-rgw_log.Tpo -c -o rgw/test_build_librgw-rgw_log.o `test -f 'rgw/rgw_log.cc' || echo '$(srcdir)/'`rgw/rgw_log.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/test_build_librgw-rgw_log.Tpo rgw/$(DEPDIR)/test_build_librgw-rgw_log.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_log.cc' object='rgw/test_build_librgw-rgw_log.o' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -c -o rgw/test_build_librgw-rgw_log.o `test -f 'rgw/rgw_log.cc' || echo '$(srcdir)/'`rgw/rgw_log.cc
+
+rgw/test_build_librgw-rgw_log.obj: rgw/rgw_log.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -MT rgw/test_build_librgw-rgw_log.obj -MD -MP -MF rgw/$(DEPDIR)/test_build_librgw-rgw_log.Tpo -c -o rgw/test_build_librgw-rgw_log.obj `if test -f 'rgw/rgw_log.cc'; then $(CYGPATH_W) 'rgw/rgw_log.cc'; else $(CYGPATH_W) '$(srcdir)/rgw/rgw_log.cc'; fi`
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/test_build_librgw-rgw_log.Tpo rgw/$(DEPDIR)/test_build_librgw-rgw_log.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_log.cc' object='rgw/test_build_librgw-rgw_log.obj' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -c -o rgw/test_build_librgw-rgw_log.obj `if test -f 'rgw/rgw_log.cc'; then $(CYGPATH_W) 'rgw/rgw_log.cc'; else $(CYGPATH_W) '$(srcdir)/rgw/rgw_log.cc'; fi`
+
+rgw/test_build_librgw-rgw_metadata.o: rgw/rgw_metadata.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -MT rgw/test_build_librgw-rgw_metadata.o -MD -MP -MF rgw/$(DEPDIR)/test_build_librgw-rgw_metadata.Tpo -c -o rgw/test_build_librgw-rgw_metadata.o `test -f 'rgw/rgw_metadata.cc' || echo '$(srcdir)/'`rgw/rgw_metadata.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/test_build_librgw-rgw_metadata.Tpo rgw/$(DEPDIR)/test_build_librgw-rgw_metadata.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_metadata.cc' object='rgw/test_build_librgw-rgw_metadata.o' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -c -o rgw/test_build_librgw-rgw_metadata.o `test -f 'rgw/rgw_metadata.cc' || echo '$(srcdir)/'`rgw/rgw_metadata.cc
+
+rgw/test_build_librgw-rgw_metadata.obj: rgw/rgw_metadata.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -MT rgw/test_build_librgw-rgw_metadata.obj -MD -MP -MF rgw/$(DEPDIR)/test_build_librgw-rgw_metadata.Tpo -c -o rgw/test_build_librgw-rgw_metadata.obj `if test -f 'rgw/rgw_metadata.cc'; then $(CYGPATH_W) 'rgw/rgw_metadata.cc'; else $(CYGPATH_W) '$(srcdir)/rgw/rgw_metadata.cc'; fi`
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/test_build_librgw-rgw_metadata.Tpo rgw/$(DEPDIR)/test_build_librgw-rgw_metadata.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_metadata.cc' object='rgw/test_build_librgw-rgw_metadata.obj' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -c -o rgw/test_build_librgw-rgw_metadata.obj `if test -f 'rgw/rgw_metadata.cc'; then $(CYGPATH_W) 'rgw/rgw_metadata.cc'; else $(CYGPATH_W) '$(srcdir)/rgw/rgw_metadata.cc'; fi`
+
+rgw/test_build_librgw-rgw_multi.o: rgw/rgw_multi.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -MT rgw/test_build_librgw-rgw_multi.o -MD -MP -MF rgw/$(DEPDIR)/test_build_librgw-rgw_multi.Tpo -c -o rgw/test_build_librgw-rgw_multi.o `test -f 'rgw/rgw_multi.cc' || echo '$(srcdir)/'`rgw/rgw_multi.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/test_build_librgw-rgw_multi.Tpo rgw/$(DEPDIR)/test_build_librgw-rgw_multi.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_multi.cc' object='rgw/test_build_librgw-rgw_multi.o' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -c -o rgw/test_build_librgw-rgw_multi.o `test -f 'rgw/rgw_multi.cc' || echo '$(srcdir)/'`rgw/rgw_multi.cc
+
+rgw/test_build_librgw-rgw_multi.obj: rgw/rgw_multi.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -MT rgw/test_build_librgw-rgw_multi.obj -MD -MP -MF rgw/$(DEPDIR)/test_build_librgw-rgw_multi.Tpo -c -o rgw/test_build_librgw-rgw_multi.obj `if test -f 'rgw/rgw_multi.cc'; then $(CYGPATH_W) 'rgw/rgw_multi.cc'; else $(CYGPATH_W) '$(srcdir)/rgw/rgw_multi.cc'; fi`
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/test_build_librgw-rgw_multi.Tpo rgw/$(DEPDIR)/test_build_librgw-rgw_multi.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_multi.cc' object='rgw/test_build_librgw-rgw_multi.obj' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -c -o rgw/test_build_librgw-rgw_multi.obj `if test -f 'rgw/rgw_multi.cc'; then $(CYGPATH_W) 'rgw/rgw_multi.cc'; else $(CYGPATH_W) '$(srcdir)/rgw/rgw_multi.cc'; fi`
+
+rgw/test_build_librgw-rgw_multi_del.o: rgw/rgw_multi_del.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -MT rgw/test_build_librgw-rgw_multi_del.o -MD -MP -MF rgw/$(DEPDIR)/test_build_librgw-rgw_multi_del.Tpo -c -o rgw/test_build_librgw-rgw_multi_del.o `test -f 'rgw/rgw_multi_del.cc' || echo '$(srcdir)/'`rgw/rgw_multi_del.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/test_build_librgw-rgw_multi_del.Tpo rgw/$(DEPDIR)/test_build_librgw-rgw_multi_del.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_multi_del.cc' object='rgw/test_build_librgw-rgw_multi_del.o' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -c -o rgw/test_build_librgw-rgw_multi_del.o `test -f 'rgw/rgw_multi_del.cc' || echo '$(srcdir)/'`rgw/rgw_multi_del.cc
+
+rgw/test_build_librgw-rgw_multi_del.obj: rgw/rgw_multi_del.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -MT rgw/test_build_librgw-rgw_multi_del.obj -MD -MP -MF rgw/$(DEPDIR)/test_build_librgw-rgw_multi_del.Tpo -c -o rgw/test_build_librgw-rgw_multi_del.obj `if test -f 'rgw/rgw_multi_del.cc'; then $(CYGPATH_W) 'rgw/rgw_multi_del.cc'; else $(CYGPATH_W) '$(srcdir)/rgw/rgw_multi_del.cc'; fi`
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/test_build_librgw-rgw_multi_del.Tpo rgw/$(DEPDIR)/test_build_librgw-rgw_multi_del.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_multi_del.cc' object='rgw/test_build_librgw-rgw_multi_del.obj' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -c -o rgw/test_build_librgw-rgw_multi_del.obj `if test -f 'rgw/rgw_multi_del.cc'; then $(CYGPATH_W) 'rgw/rgw_multi_del.cc'; else $(CYGPATH_W) '$(srcdir)/rgw/rgw_multi_del.cc'; fi`
+
+rgw/test_build_librgw-rgw_auth_s3.o: rgw/rgw_auth_s3.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -MT rgw/test_build_librgw-rgw_auth_s3.o -MD -MP -MF rgw/$(DEPDIR)/test_build_librgw-rgw_auth_s3.Tpo -c -o rgw/test_build_librgw-rgw_auth_s3.o `test -f 'rgw/rgw_auth_s3.cc' || echo '$(srcdir)/'`rgw/rgw_auth_s3.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/test_build_librgw-rgw_auth_s3.Tpo rgw/$(DEPDIR)/test_build_librgw-rgw_auth_s3.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_auth_s3.cc' object='rgw/test_build_librgw-rgw_auth_s3.o' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -c -o rgw/test_build_librgw-rgw_auth_s3.o `test -f 'rgw/rgw_auth_s3.cc' || echo '$(srcdir)/'`rgw/rgw_auth_s3.cc
+
+rgw/test_build_librgw-rgw_auth_s3.obj: rgw/rgw_auth_s3.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -MT rgw/test_build_librgw-rgw_auth_s3.obj -MD -MP -MF rgw/$(DEPDIR)/test_build_librgw-rgw_auth_s3.Tpo -c -o rgw/test_build_librgw-rgw_auth_s3.obj `if test -f 'rgw/rgw_auth_s3.cc'; then $(CYGPATH_W) 'rgw/rgw_auth_s3.cc'; else $(CYGPATH_W) '$(srcdir)/rgw/rgw_auth_s3.cc'; fi`
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/test_build_librgw-rgw_auth_s3.Tpo rgw/$(DEPDIR)/test_build_librgw-rgw_auth_s3.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_auth_s3.cc' object='rgw/test_build_librgw-rgw_auth_s3.obj' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -c -o rgw/test_build_librgw-rgw_auth_s3.obj `if test -f 'rgw/rgw_auth_s3.cc'; then $(CYGPATH_W) 'rgw/rgw_auth_s3.cc'; else $(CYGPATH_W) '$(srcdir)/rgw/rgw_auth_s3.cc'; fi`
+
+rgw/test_build_librgw-rgw_period_history.o: rgw/rgw_period_history.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -MT rgw/test_build_librgw-rgw_period_history.o -MD -MP -MF rgw/$(DEPDIR)/test_build_librgw-rgw_period_history.Tpo -c -o rgw/test_build_librgw-rgw_period_history.o `test -f 'rgw/rgw_period_history.cc' || echo '$(srcdir)/'`rgw/rgw_period_history.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/test_build_librgw-rgw_period_history.Tpo rgw/$(DEPDIR)/test_build_librgw-rgw_period_history.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_period_history.cc' object='rgw/test_build_librgw-rgw_period_history.o' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -c -o rgw/test_build_librgw-rgw_period_history.o `test -f 'rgw/rgw_period_history.cc' || echo '$(srcdir)/'`rgw/rgw_period_history.cc
+
+rgw/test_build_librgw-rgw_period_history.obj: rgw/rgw_period_history.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -MT rgw/test_build_librgw-rgw_period_history.obj -MD -MP -MF rgw/$(DEPDIR)/test_build_librgw-rgw_period_history.Tpo -c -o rgw/test_build_librgw-rgw_period_history.obj `if test -f 'rgw/rgw_period_history.cc'; then $(CYGPATH_W) 'rgw/rgw_period_history.cc'; else $(CYGPATH_W) '$(srcdir)/rgw/rgw_period_history.cc'; fi`
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/test_build_librgw-rgw_period_history.Tpo rgw/$(DEPDIR)/test_build_librgw-rgw_period_history.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_period_history.cc' object='rgw/test_build_librgw-rgw_period_history.obj' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -c -o rgw/test_build_librgw-rgw_period_history.obj `if test -f 'rgw/rgw_period_history.cc'; then $(CYGPATH_W) 'rgw/rgw_period_history.cc'; else $(CYGPATH_W) '$(srcdir)/rgw/rgw_period_history.cc'; fi`
+
+rgw/test_build_librgw-rgw_period_puller.o: rgw/rgw_period_puller.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -MT rgw/test_build_librgw-rgw_period_puller.o -MD -MP -MF rgw/$(DEPDIR)/test_build_librgw-rgw_period_puller.Tpo -c -o rgw/test_build_librgw-rgw_period_puller.o `test -f 'rgw/rgw_period_puller.cc' || echo '$(srcdir)/'`rgw/rgw_period_puller.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/test_build_librgw-rgw_period_puller.Tpo rgw/$(DEPDIR)/test_build_librgw-rgw_period_puller.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_period_puller.cc' object='rgw/test_build_librgw-rgw_period_puller.o' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -c -o rgw/test_build_librgw-rgw_period_puller.o `test -f 'rgw/rgw_period_puller.cc' || echo '$(srcdir)/'`rgw/rgw_period_puller.cc
+
+rgw/test_build_librgw-rgw_period_puller.obj: rgw/rgw_period_puller.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -MT rgw/test_build_librgw-rgw_period_puller.obj -MD -MP -MF rgw/$(DEPDIR)/test_build_librgw-rgw_period_puller.Tpo -c -o rgw/test_build_librgw-rgw_period_puller.obj `if test -f 'rgw/rgw_period_puller.cc'; then $(CYGPATH_W) 'rgw/rgw_period_puller.cc'; else $(CYGPATH_W) '$(srcdir)/rgw/rgw_period_puller.cc'; fi`
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/test_build_librgw-rgw_period_puller.Tpo rgw/$(DEPDIR)/test_build_librgw-rgw_period_puller.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_period_puller.cc' object='rgw/test_build_librgw-rgw_period_puller.obj' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -c -o rgw/test_build_librgw-rgw_period_puller.obj `if test -f 'rgw/rgw_period_puller.cc'; then $(CYGPATH_W) 'rgw/rgw_period_puller.cc'; else $(CYGPATH_W) '$(srcdir)/rgw/rgw_period_puller.cc'; fi`
 
-rgw/test_build_librgw-rgw_acl_s3.o: rgw/rgw_acl_s3.cc
- at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -MT rgw/test_build_librgw-rgw_acl_s3.o -MD -MP -MF rgw/$(DEPDIR)/test_build_librgw-rgw_acl_s3.Tpo -c -o rgw/test_build_librgw-rgw_acl_s3.o `test -f 'rgw/rgw_acl_s3.cc' || echo '$(srcdir)/'`rgw/rgw_acl_s3.cc
- at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/test_build_librgw-rgw_acl_s3.Tpo rgw/$(DEPDIR)/test_build_librgw-rgw_acl_s3.Po
- at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_acl_s3.cc' object='rgw/test_build_librgw-rgw_acl_s3.o' libtool=no @AMDEPBACKSLASH@
+rgw/test_build_librgw-rgw_period_pusher.o: rgw/rgw_period_pusher.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -MT rgw/test_build_librgw-rgw_period_pusher.o -MD -MP -MF rgw/$(DEPDIR)/test_build_librgw-rgw_period_pusher.Tpo -c -o rgw/test_build_librgw-rgw_period_pusher.o `test -f 'rgw/rgw_period_pusher.cc' || echo '$(srcdir)/'`rgw/rgw_period_pusher.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/test_build_librgw-rgw_period_pusher.Tpo rgw/$(DEPDIR)/test_build_librgw-rgw_period_pusher.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_period_pusher.cc' object='rgw/test_build_librgw-rgw_period_pusher.o' libtool=no @AMDEPBACKSLASH@
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -c -o rgw/test_build_librgw-rgw_acl_s3.o `test -f 'rgw/rgw_acl_s3.cc' || echo '$(srcdir)/'`rgw/rgw_acl_s3.cc
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -c -o rgw/test_build_librgw-rgw_period_pusher.o `test -f 'rgw/rgw_period_pusher.cc' || echo '$(srcdir)/'`rgw/rgw_period_pusher.cc
 
-rgw/test_build_librgw-rgw_acl_s3.obj: rgw/rgw_acl_s3.cc
- at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -MT rgw/test_build_librgw-rgw_acl_s3.obj -MD -MP -MF rgw/$(DEPDIR)/test_build_librgw-rgw_acl_s3.Tpo -c -o rgw/test_build_librgw-rgw_acl_s3.obj `if test -f 'rgw/rgw_acl_s3.cc'; then $(CYGPATH_W) 'rgw/rgw_acl_s3.cc'; else $(CYGPATH_W) '$(srcdir)/rgw/rgw_acl_s3.cc'; fi`
- at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/test_build_librgw-rgw_acl_s3.Tpo rgw/$(DEPDIR)/test_build_librgw-rgw_acl_s3.Po
- at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_acl_s3.cc' object='rgw/test_build_librgw-rgw_acl_s3.obj' libtool=no @AMDEPBACKSLASH@
+rgw/test_build_librgw-rgw_period_pusher.obj: rgw/rgw_period_pusher.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -MT rgw/test_build_librgw-rgw_period_pusher.obj -MD -MP -MF rgw/$(DEPDIR)/test_build_librgw-rgw_period_pusher.Tpo -c -o rgw/test_build_librgw-rgw_period_pusher.obj `if test -f 'rgw/rgw_period_pusher.cc'; then $(CYGPATH_W) 'rgw/rgw_period_pusher.cc'; else $(CYGPATH_W) '$(srcdir)/rgw/rgw_period_pusher.cc'; fi`
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/test_build_librgw-rgw_period_pusher.Tpo rgw/$(DEPDIR)/test_build_librgw-rgw_period_pusher.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_period_pusher.cc' object='rgw/test_build_librgw-rgw_period_pusher.obj' libtool=no @AMDEPBACKSLASH@
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -c -o rgw/test_build_librgw-rgw_acl_s3.obj `if test -f 'rgw/rgw_acl_s3.cc'; then $(CYGPATH_W) 'rgw/rgw_acl_s3.cc'; else $(CYGPATH_W) '$(srcdir)/rgw/rgw_acl_s3.cc'; fi`
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -c -o rgw/test_build_librgw-rgw_period_pusher.obj `if test -f 'rgw/rgw_period_pusher.cc'; then $(CYGPATH_W) 'rgw/rgw_period_pusher.cc'; else $(CYGPATH_W) '$(srcdir)/rgw/rgw_period_pusher.cc'; fi`
 
-rgw/test_build_librgw-rgw_acl_swift.o: rgw/rgw_acl_swift.cc
- at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -MT rgw/test_build_librgw-rgw_acl_swift.o -MD -MP -MF rgw/$(DEPDIR)/test_build_librgw-rgw_acl_swift.Tpo -c -o rgw/test_build_librgw-rgw_acl_swift.o `test -f 'rgw/rgw_acl_swift.cc' || echo '$(srcdir)/'`rgw/rgw_acl_swift.cc
- at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/test_build_librgw-rgw_acl_swift.Tpo rgw/$(DEPDIR)/test_build_librgw-rgw_acl_swift.Po
- at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_acl_swift.cc' object='rgw/test_build_librgw-rgw_acl_swift.o' libtool=no @AMDEPBACKSLASH@
+rgw/test_build_librgw-rgw_realm_reloader.o: rgw/rgw_realm_reloader.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -MT rgw/test_build_librgw-rgw_realm_reloader.o -MD -MP -MF rgw/$(DEPDIR)/test_build_librgw-rgw_realm_reloader.Tpo -c -o rgw/test_build_librgw-rgw_realm_reloader.o `test -f 'rgw/rgw_realm_reloader.cc' || echo '$(srcdir)/'`rgw/rgw_realm_reloader.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/test_build_librgw-rgw_realm_reloader.Tpo rgw/$(DEPDIR)/test_build_librgw-rgw_realm_reloader.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_realm_reloader.cc' object='rgw/test_build_librgw-rgw_realm_reloader.o' libtool=no @AMDEPBACKSLASH@
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -c -o rgw/test_build_librgw-rgw_acl_swift.o `test -f 'rgw/rgw_acl_swift.cc' || echo '$(srcdir)/'`rgw/rgw_acl_swift.cc
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -c -o rgw/test_build_librgw-rgw_realm_reloader.o `test -f 'rgw/rgw_realm_reloader.cc' || echo '$(srcdir)/'`rgw/rgw_realm_reloader.cc
 
-rgw/test_build_librgw-rgw_acl_swift.obj: rgw/rgw_acl_swift.cc
- at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -MT rgw/test_build_librgw-rgw_acl_swift.obj -MD -MP -MF rgw/$(DEPDIR)/test_build_librgw-rgw_acl_swift.Tpo -c -o rgw/test_build_librgw-rgw_acl_swift.obj `if test -f 'rgw/rgw_acl_swift.cc'; then $(CYGPATH_W) 'rgw/rgw_acl_swift.cc'; else $(CYGPATH_W) '$(srcdir)/rgw/rgw_acl_swift.cc'; fi`
- at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/test_build_librgw-rgw_acl_swift.Tpo rgw/$(DEPDIR)/test_build_librgw-rgw_acl_swift.Po
- at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_acl_swift.cc' object='rgw/test_build_librgw-rgw_acl_swift.obj' libtool=no @AMDEPBACKSLASH@
+rgw/test_build_librgw-rgw_realm_reloader.obj: rgw/rgw_realm_reloader.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -MT rgw/test_build_librgw-rgw_realm_reloader.obj -MD -MP -MF rgw/$(DEPDIR)/test_build_librgw-rgw_realm_reloader.Tpo -c -o rgw/test_build_librgw-rgw_realm_reloader.obj `if test -f 'rgw/rgw_realm_reloader.cc'; then $(CYGPATH_W) 'rgw/rgw_realm_reloader.cc'; else $(CYGPATH_W) '$(srcdir)/rgw/rgw_realm_reloader.cc'; fi`
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/test_build_librgw-rgw_realm_reloader.Tpo rgw/$(DEPDIR)/test_build_librgw-rgw_realm_reloader.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_realm_reloader.cc' object='rgw/test_build_librgw-rgw_realm_reloader.obj' libtool=no @AMDEPBACKSLASH@
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -c -o rgw/test_build_librgw-rgw_acl_swift.obj `if test -f 'rgw/rgw_acl_swift.cc'; then $(CYGPATH_W) 'rgw/rgw_acl_swift.cc'; else $(CYGPATH_W) '$(srcdir)/rgw/rgw_acl_swift.cc'; fi`
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -c -o rgw/test_build_librgw-rgw_realm_reloader.obj `if test -f 'rgw/rgw_realm_reloader.cc'; then $(CYGPATH_W) 'rgw/rgw_realm_reloader.cc'; else $(CYGPATH_W) '$(srcdir)/rgw/rgw_realm_reloader.cc'; fi`
 
-rgw/test_build_librgw-rgw_client_io.o: rgw/rgw_client_io.cc
- at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -MT rgw/test_build_librgw-rgw_client_io.o -MD -MP -MF rgw/$(DEPDIR)/test_build_librgw-rgw_client_io.Tpo -c -o rgw/test_build_librgw-rgw_client_io.o `test -f 'rgw/rgw_client_io.cc' || echo '$(srcdir)/'`rgw/rgw_client_io.cc
- at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/test_build_librgw-rgw_client_io.Tpo rgw/$(DEPDIR)/test_build_librgw-rgw_client_io.Po
- at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_client_io.cc' object='rgw/test_build_librgw-rgw_client_io.o' libtool=no @AMDEPBACKSLASH@
+rgw/test_build_librgw-rgw_realm_watcher.o: rgw/rgw_realm_watcher.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -MT rgw/test_build_librgw-rgw_realm_watcher.o -MD -MP -MF rgw/$(DEPDIR)/test_build_librgw-rgw_realm_watcher.Tpo -c -o rgw/test_build_librgw-rgw_realm_watcher.o `test -f 'rgw/rgw_realm_watcher.cc' || echo '$(srcdir)/'`rgw/rgw_realm_watcher.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/test_build_librgw-rgw_realm_watcher.Tpo rgw/$(DEPDIR)/test_build_librgw-rgw_realm_watcher.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_realm_watcher.cc' object='rgw/test_build_librgw-rgw_realm_watcher.o' libtool=no @AMDEPBACKSLASH@
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -c -o rgw/test_build_librgw-rgw_client_io.o `test -f 'rgw/rgw_client_io.cc' || echo '$(srcdir)/'`rgw/rgw_client_io.cc
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -c -o rgw/test_build_librgw-rgw_realm_watcher.o `test -f 'rgw/rgw_realm_watcher.cc' || echo '$(srcdir)/'`rgw/rgw_realm_watcher.cc
 
-rgw/test_build_librgw-rgw_client_io.obj: rgw/rgw_client_io.cc
- at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -MT rgw/test_build_librgw-rgw_client_io.obj -MD -MP -MF rgw/$(DEPDIR)/test_build_librgw-rgw_client_io.Tpo -c -o rgw/test_build_librgw-rgw_client_io.obj `if test -f 'rgw/rgw_client_io.cc'; then $(CYGPATH_W) 'rgw/rgw_client_io.cc'; else $(CYGPATH_W) '$(srcdir)/rgw/rgw_client_io.cc'; fi`
- at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/test_build_librgw-rgw_client_io.Tpo rgw/$(DEPDIR)/test_build_librgw-rgw_client_io.Po
- at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_client_io.cc' object='rgw/test_build_librgw-rgw_client_io.obj' libtool=no @AMDEPBACKSLASH@
+rgw/test_build_librgw-rgw_realm_watcher.obj: rgw/rgw_realm_watcher.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -MT rgw/test_build_librgw-rgw_realm_watcher.obj -MD -MP -MF rgw/$(DEPDIR)/test_build_librgw-rgw_realm_watcher.Tpo -c -o rgw/test_build_librgw-rgw_realm_watcher.obj `if test -f 'rgw/rgw_realm_watcher.cc'; then $(CYGPATH_W) 'rgw/rgw_realm_watcher.cc'; else $(CYGPATH_W) '$(srcdir)/rgw/rgw_realm_watcher.cc'; fi`
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/test_build_librgw-rgw_realm_watcher.Tpo rgw/$(DEPDIR)/test_build_librgw-rgw_realm_watcher.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_realm_watcher.cc' object='rgw/test_build_librgw-rgw_realm_watcher.obj' libtool=no @AMDEPBACKSLASH@
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -c -o rgw/test_build_librgw-rgw_client_io.obj `if test -f 'rgw/rgw_client_io.cc'; then $(CYGPATH_W) 'rgw/rgw_client_io.cc'; else $(CYGPATH_W) '$(srcdir)/rgw/rgw_client_io.cc'; fi`
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -c -o rgw/test_build_librgw-rgw_realm_watcher.obj `if test -f 'rgw/rgw_realm_watcher.cc'; then $(CYGPATH_W) 'rgw/rgw_realm_watcher.cc'; else $(CYGPATH_W) '$(srcdir)/rgw/rgw_realm_watcher.cc'; fi`
 
-rgw/test_build_librgw-rgw_fcgi.o: rgw/rgw_fcgi.cc
- at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -MT rgw/test_build_librgw-rgw_fcgi.o -MD -MP -MF rgw/$(DEPDIR)/test_build_librgw-rgw_fcgi.Tpo -c -o rgw/test_build_librgw-rgw_fcgi.o `test -f 'rgw/rgw_fcgi.cc' || echo '$(srcdir)/'`rgw/rgw_fcgi.cc
- at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/test_build_librgw-rgw_fcgi.Tpo rgw/$(DEPDIR)/test_build_librgw-rgw_fcgi.Po
- at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_fcgi.cc' object='rgw/test_build_librgw-rgw_fcgi.o' libtool=no @AMDEPBACKSLASH@
+rgw/test_build_librgw-rgw_sync.o: rgw/rgw_sync.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -MT rgw/test_build_librgw-rgw_sync.o -MD -MP -MF rgw/$(DEPDIR)/test_build_librgw-rgw_sync.Tpo -c -o rgw/test_build_librgw-rgw_sync.o `test -f 'rgw/rgw_sync.cc' || echo '$(srcdir)/'`rgw/rgw_sync.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/test_build_librgw-rgw_sync.Tpo rgw/$(DEPDIR)/test_build_librgw-rgw_sync.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_sync.cc' object='rgw/test_build_librgw-rgw_sync.o' libtool=no @AMDEPBACKSLASH@
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -c -o rgw/test_build_librgw-rgw_fcgi.o `test -f 'rgw/rgw_fcgi.cc' || echo '$(srcdir)/'`rgw/rgw_fcgi.cc
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -c -o rgw/test_build_librgw-rgw_sync.o `test -f 'rgw/rgw_sync.cc' || echo '$(srcdir)/'`rgw/rgw_sync.cc
 
-rgw/test_build_librgw-rgw_fcgi.obj: rgw/rgw_fcgi.cc
- at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -MT rgw/test_build_librgw-rgw_fcgi.obj -MD -MP -MF rgw/$(DEPDIR)/test_build_librgw-rgw_fcgi.Tpo -c -o rgw/test_build_librgw-rgw_fcgi.obj `if test -f 'rgw/rgw_fcgi.cc'; then $(CYGPATH_W) 'rgw/rgw_fcgi.cc'; else $(CYGPATH_W) '$(srcdir)/rgw/rgw_fcgi.cc'; fi`
- at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/test_build_librgw-rgw_fcgi.Tpo rgw/$(DEPDIR)/test_build_librgw-rgw_fcgi.Po
- at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_fcgi.cc' object='rgw/test_build_librgw-rgw_fcgi.obj' libtool=no @AMDEPBACKSLASH@
+rgw/test_build_librgw-rgw_sync.obj: rgw/rgw_sync.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -MT rgw/test_build_librgw-rgw_sync.obj -MD -MP -MF rgw/$(DEPDIR)/test_build_librgw-rgw_sync.Tpo -c -o rgw/test_build_librgw-rgw_sync.obj `if test -f 'rgw/rgw_sync.cc'; then $(CYGPATH_W) 'rgw/rgw_sync.cc'; else $(CYGPATH_W) '$(srcdir)/rgw/rgw_sync.cc'; fi`
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/test_build_librgw-rgw_sync.Tpo rgw/$(DEPDIR)/test_build_librgw-rgw_sync.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_sync.cc' object='rgw/test_build_librgw-rgw_sync.obj' libtool=no @AMDEPBACKSLASH@
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -c -o rgw/test_build_librgw-rgw_fcgi.obj `if test -f 'rgw/rgw_fcgi.cc'; then $(CYGPATH_W) 'rgw/rgw_fcgi.cc'; else $(CYGPATH_W) '$(srcdir)/rgw/rgw_fcgi.cc'; fi`
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -c -o rgw/test_build_librgw-rgw_sync.obj `if test -f 'rgw/rgw_sync.cc'; then $(CYGPATH_W) 'rgw/rgw_sync.cc'; else $(CYGPATH_W) '$(srcdir)/rgw/rgw_sync.cc'; fi`
 
-rgw/test_build_librgw-rgw_xml.o: rgw/rgw_xml.cc
- at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -MT rgw/test_build_librgw-rgw_xml.o -MD -MP -MF rgw/$(DEPDIR)/test_build_librgw-rgw_xml.Tpo -c -o rgw/test_build_librgw-rgw_xml.o `test -f 'rgw/rgw_xml.cc' || echo '$(srcdir)/'`rgw/rgw_xml.cc
- at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/test_build_librgw-rgw_xml.Tpo rgw/$(DEPDIR)/test_build_librgw-rgw_xml.Po
- at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_xml.cc' object='rgw/test_build_librgw-rgw_xml.o' libtool=no @AMDEPBACKSLASH@
+rgw/test_build_librgw-rgw_data_sync.o: rgw/rgw_data_sync.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -MT rgw/test_build_librgw-rgw_data_sync.o -MD -MP -MF rgw/$(DEPDIR)/test_build_librgw-rgw_data_sync.Tpo -c -o rgw/test_build_librgw-rgw_data_sync.o `test -f 'rgw/rgw_data_sync.cc' || echo '$(srcdir)/'`rgw/rgw_data_sync.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/test_build_librgw-rgw_data_sync.Tpo rgw/$(DEPDIR)/test_build_librgw-rgw_data_sync.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_data_sync.cc' object='rgw/test_build_librgw-rgw_data_sync.o' libtool=no @AMDEPBACKSLASH@
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -c -o rgw/test_build_librgw-rgw_xml.o `test -f 'rgw/rgw_xml.cc' || echo '$(srcdir)/'`rgw/rgw_xml.cc
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -c -o rgw/test_build_librgw-rgw_data_sync.o `test -f 'rgw/rgw_data_sync.cc' || echo '$(srcdir)/'`rgw/rgw_data_sync.cc
 
-rgw/test_build_librgw-rgw_xml.obj: rgw/rgw_xml.cc
- at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -MT rgw/test_build_librgw-rgw_xml.obj -MD -MP -MF rgw/$(DEPDIR)/test_build_librgw-rgw_xml.Tpo -c -o rgw/test_build_librgw-rgw_xml.obj `if test -f 'rgw/rgw_xml.cc'; then $(CYGPATH_W) 'rgw/rgw_xml.cc'; else $(CYGPATH_W) '$(srcdir)/rgw/rgw_xml.cc'; fi`
- at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/test_build_librgw-rgw_xml.Tpo rgw/$(DEPDIR)/test_build_librgw-rgw_xml.Po
- at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_xml.cc' object='rgw/test_build_librgw-rgw_xml.obj' libtool=no @AMDEPBACKSLASH@
+rgw/test_build_librgw-rgw_data_sync.obj: rgw/rgw_data_sync.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -MT rgw/test_build_librgw-rgw_data_sync.obj -MD -MP -MF rgw/$(DEPDIR)/test_build_librgw-rgw_data_sync.Tpo -c -o rgw/test_build_librgw-rgw_data_sync.obj `if test -f 'rgw/rgw_data_sync.cc'; then $(CYGPATH_W) 'rgw/rgw_data_sync.cc'; else $(CYGPATH_W) '$(srcdir)/rgw/rgw_data_sync.cc'; fi`
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/test_build_librgw-rgw_data_sync.Tpo rgw/$(DEPDIR)/test_build_librgw-rgw_data_sync.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_data_sync.cc' object='rgw/test_build_librgw-rgw_data_sync.obj' libtool=no @AMDEPBACKSLASH@
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -c -o rgw/test_build_librgw-rgw_xml.obj `if test -f 'rgw/rgw_xml.cc'; then $(CYGPATH_W) 'rgw/rgw_xml.cc'; else $(CYGPATH_W) '$(srcdir)/rgw/rgw_xml.cc'; fi`
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -c -o rgw/test_build_librgw-rgw_data_sync.obj `if test -f 'rgw/rgw_data_sync.cc'; then $(CYGPATH_W) 'rgw/rgw_data_sync.cc'; else $(CYGPATH_W) '$(srcdir)/rgw/rgw_data_sync.cc'; fi`
 
-rgw/test_build_librgw-rgw_usage.o: rgw/rgw_usage.cc
- at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -MT rgw/test_build_librgw-rgw_usage.o -MD -MP -MF rgw/$(DEPDIR)/test_build_librgw-rgw_usage.Tpo -c -o rgw/test_build_librgw-rgw_usage.o `test -f 'rgw/rgw_usage.cc' || echo '$(srcdir)/'`rgw/rgw_usage.cc
- at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/test_build_librgw-rgw_usage.Tpo rgw/$(DEPDIR)/test_build_librgw-rgw_usage.Po
- at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_usage.cc' object='rgw/test_build_librgw-rgw_usage.o' libtool=no @AMDEPBACKSLASH@
+rgw/test_build_librgw-rgw_object_expirer_core.o: rgw/rgw_object_expirer_core.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -MT rgw/test_build_librgw-rgw_object_expirer_core.o -MD -MP -MF rgw/$(DEPDIR)/test_build_librgw-rgw_object_expirer_core.Tpo -c -o rgw/test_build_librgw-rgw_object_expirer_core.o `test -f 'rgw/rgw_object_expirer_core.cc' || echo '$(srcdir)/'`rgw/rgw_object_expirer_core.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/test_build_librgw-rgw_object_expirer_core.Tpo rgw/$(DEPDIR)/test_build_librgw-rgw_object_expirer_core.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_object_expirer_core.cc' object='rgw/test_build_librgw-rgw_object_expirer_core.o' libtool=no @AMDEPBACKSLASH@
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -c -o rgw/test_build_librgw-rgw_usage.o `test -f 'rgw/rgw_usage.cc' || echo '$(srcdir)/'`rgw/rgw_usage.cc
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -c -o rgw/test_build_librgw-rgw_object_expirer_core.o `test -f 'rgw/rgw_object_expirer_core.cc' || echo '$(srcdir)/'`rgw/rgw_object_expirer_core.cc
 
-rgw/test_build_librgw-rgw_usage.obj: rgw/rgw_usage.cc
- at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -MT rgw/test_build_librgw-rgw_usage.obj -MD -MP -MF rgw/$(DEPDIR)/test_build_librgw-rgw_usage.Tpo -c -o rgw/test_build_librgw-rgw_usage.obj `if test -f 'rgw/rgw_usage.cc'; then $(CYGPATH_W) 'rgw/rgw_usage.cc'; else $(CYGPATH_W) '$(srcdir)/rgw/rgw_usage.cc'; fi`
- at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/test_build_librgw-rgw_usage.Tpo rgw/$(DEPDIR)/test_build_librgw-rgw_usage.Po
- at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_usage.cc' object='rgw/test_build_librgw-rgw_usage.obj' libtool=no @AMDEPBACKSLASH@
+rgw/test_build_librgw-rgw_object_expirer_core.obj: rgw/rgw_object_expirer_core.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -MT rgw/test_build_librgw-rgw_object_expirer_core.obj -MD -MP -MF rgw/$(DEPDIR)/test_build_librgw-rgw_object_expirer_core.Tpo -c -o rgw/test_build_librgw-rgw_object_expirer_core.obj `if test -f 'rgw/rgw_object_expirer_core.cc'; then $(CYGPATH_W) 'rgw/rgw_object_expirer_core.cc'; else $(CYGPATH_W) '$(srcdir)/rgw/rgw_object_expirer_core.cc'; fi`
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/test_build_librgw-rgw_object_expirer_core.Tpo rgw/$(DEPDIR)/test_build_librgw-rgw_object_expirer_core.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_object_expirer_core.cc' object='rgw/test_build_librgw-rgw_object_expirer_core.obj' libtool=no @AMDEPBACKSLASH@
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -c -o rgw/test_build_librgw-rgw_usage.obj `if test -f 'rgw/rgw_usage.cc'; then $(CYGPATH_W) 'rgw/rgw_usage.cc'; else $(CYGPATH_W) '$(srcdir)/rgw/rgw_usage.cc'; fi`
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -c -o rgw/test_build_librgw-rgw_object_expirer_core.obj `if test -f 'rgw/rgw_object_expirer_core.cc'; then $(CYGPATH_W) 'rgw/rgw_object_expirer_core.cc'; else $(CYGPATH_W) '$(srcdir)/rgw/rgw_object_expirer_core.cc'; fi`
 
-rgw/test_build_librgw-rgw_json_enc.o: rgw/rgw_json_enc.cc
- at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -MT rgw/test_build_librgw-rgw_json_enc.o -MD -MP -MF rgw/$(DEPDIR)/test_build_librgw-rgw_json_enc.Tpo -c -o rgw/test_build_librgw-rgw_json_enc.o `test -f 'rgw/rgw_json_enc.cc' || echo '$(srcdir)/'`rgw/rgw_json_enc.cc
- at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/test_build_librgw-rgw_json_enc.Tpo rgw/$(DEPDIR)/test_build_librgw-rgw_json_enc.Po
- at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_json_enc.cc' object='rgw/test_build_librgw-rgw_json_enc.o' libtool=no @AMDEPBACKSLASH@
+rgw/test_build_librgw-rgw_op.o: rgw/rgw_op.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -MT rgw/test_build_librgw-rgw_op.o -MD -MP -MF rgw/$(DEPDIR)/test_build_librgw-rgw_op.Tpo -c -o rgw/test_build_librgw-rgw_op.o `test -f 'rgw/rgw_op.cc' || echo '$(srcdir)/'`rgw/rgw_op.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/test_build_librgw-rgw_op.Tpo rgw/$(DEPDIR)/test_build_librgw-rgw_op.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_op.cc' object='rgw/test_build_librgw-rgw_op.o' libtool=no @AMDEPBACKSLASH@
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -c -o rgw/test_build_librgw-rgw_json_enc.o `test -f 'rgw/rgw_json_enc.cc' || echo '$(srcdir)/'`rgw/rgw_json_enc.cc
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -c -o rgw/test_build_librgw-rgw_op.o `test -f 'rgw/rgw_op.cc' || echo '$(srcdir)/'`rgw/rgw_op.cc
 
-rgw/test_build_librgw-rgw_json_enc.obj: rgw/rgw_json_enc.cc
- at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -MT rgw/test_build_librgw-rgw_json_enc.obj -MD -MP -MF rgw/$(DEPDIR)/test_build_librgw-rgw_json_enc.Tpo -c -o rgw/test_build_librgw-rgw_json_enc.obj `if test -f 'rgw/rgw_json_enc.cc'; then $(CYGPATH_W) 'rgw/rgw_json_enc.cc'; else $(CYGPATH_W) '$(srcdir)/rgw/rgw_json_enc.cc'; fi`
- at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/test_build_librgw-rgw_json_enc.Tpo rgw/$(DEPDIR)/test_build_librgw-rgw_json_enc.Po
- at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_json_enc.cc' object='rgw/test_build_librgw-rgw_json_enc.obj' libtool=no @AMDEPBACKSLASH@
+rgw/test_build_librgw-rgw_op.obj: rgw/rgw_op.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -MT rgw/test_build_librgw-rgw_op.obj -MD -MP -MF rgw/$(DEPDIR)/test_build_librgw-rgw_op.Tpo -c -o rgw/test_build_librgw-rgw_op.obj `if test -f 'rgw/rgw_op.cc'; then $(CYGPATH_W) 'rgw/rgw_op.cc'; else $(CYGPATH_W) '$(srcdir)/rgw/rgw_op.cc'; fi`
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/test_build_librgw-rgw_op.Tpo rgw/$(DEPDIR)/test_build_librgw-rgw_op.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_op.cc' object='rgw/test_build_librgw-rgw_op.obj' libtool=no @AMDEPBACKSLASH@
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -c -o rgw/test_build_librgw-rgw_json_enc.obj `if test -f 'rgw/rgw_json_enc.cc'; then $(CYGPATH_W) 'rgw/rgw_json_enc.cc'; else $(CYGPATH_W) '$(srcdir)/rgw/rgw_json_enc.cc'; fi`
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -c -o rgw/test_build_librgw-rgw_op.obj `if test -f 'rgw/rgw_op.cc'; then $(CYGPATH_W) 'rgw/rgw_op.cc'; else $(CYGPATH_W) '$(srcdir)/rgw/rgw_op.cc'; fi`
 
-rgw/test_build_librgw-rgw_xml_enc.o: rgw/rgw_xml_enc.cc
- at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -MT rgw/test_build_librgw-rgw_xml_enc.o -MD -MP -MF rgw/$(DEPDIR)/test_build_librgw-rgw_xml_enc.Tpo -c -o rgw/test_build_librgw-rgw_xml_enc.o `test -f 'rgw/rgw_xml_enc.cc' || echo '$(srcdir)/'`rgw/rgw_xml_enc.cc
- at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/test_build_librgw-rgw_xml_enc.Tpo rgw/$(DEPDIR)/test_build_librgw-rgw_xml_enc.Po
- at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_xml_enc.cc' object='rgw/test_build_librgw-rgw_xml_enc.o' libtool=no @AMDEPBACKSLASH@
+rgw/test_build_librgw-rgw_os_lib.o: rgw/rgw_os_lib.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -MT rgw/test_build_librgw-rgw_os_lib.o -MD -MP -MF rgw/$(DEPDIR)/test_build_librgw-rgw_os_lib.Tpo -c -o rgw/test_build_librgw-rgw_os_lib.o `test -f 'rgw/rgw_os_lib.cc' || echo '$(srcdir)/'`rgw/rgw_os_lib.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/test_build_librgw-rgw_os_lib.Tpo rgw/$(DEPDIR)/test_build_librgw-rgw_os_lib.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_os_lib.cc' object='rgw/test_build_librgw-rgw_os_lib.o' libtool=no @AMDEPBACKSLASH@
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -c -o rgw/test_build_librgw-rgw_xml_enc.o `test -f 'rgw/rgw_xml_enc.cc' || echo '$(srcdir)/'`rgw/rgw_xml_enc.cc
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -c -o rgw/test_build_librgw-rgw_os_lib.o `test -f 'rgw/rgw_os_lib.cc' || echo '$(srcdir)/'`rgw/rgw_os_lib.cc
 
-rgw/test_build_librgw-rgw_xml_enc.obj: rgw/rgw_xml_enc.cc
- at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -MT rgw/test_build_librgw-rgw_xml_enc.obj -MD -MP -MF rgw/$(DEPDIR)/test_build_librgw-rgw_xml_enc.Tpo -c -o rgw/test_build_librgw-rgw_xml_enc.obj `if test -f 'rgw/rgw_xml_enc.cc'; then $(CYGPATH_W) 'rgw/rgw_xml_enc.cc'; else $(CYGPATH_W) '$(srcdir)/rgw/rgw_xml_enc.cc'; fi`
- at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/test_build_librgw-rgw_xml_enc.Tpo rgw/$(DEPDIR)/test_build_librgw-rgw_xml_enc.Po
- at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_xml_enc.cc' object='rgw/test_build_librgw-rgw_xml_enc.obj' libtool=no @AMDEPBACKSLASH@
+rgw/test_build_librgw-rgw_os_lib.obj: rgw/rgw_os_lib.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -MT rgw/test_build_librgw-rgw_os_lib.obj -MD -MP -MF rgw/$(DEPDIR)/test_build_librgw-rgw_os_lib.Tpo -c -o rgw/test_build_librgw-rgw_os_lib.obj `if test -f 'rgw/rgw_os_lib.cc'; then $(CYGPATH_W) 'rgw/rgw_os_lib.cc'; else $(CYGPATH_W) '$(srcdir)/rgw/rgw_os_lib.cc'; fi`
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/test_build_librgw-rgw_os_lib.Tpo rgw/$(DEPDIR)/test_build_librgw-rgw_os_lib.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_os_lib.cc' object='rgw/test_build_librgw-rgw_os_lib.obj' libtool=no @AMDEPBACKSLASH@
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -c -o rgw/test_build_librgw-rgw_xml_enc.obj `if test -f 'rgw/rgw_xml_enc.cc'; then $(CYGPATH_W) 'rgw/rgw_xml_enc.cc'; else $(CYGPATH_W) '$(srcdir)/rgw/rgw_xml_enc.cc'; fi`
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -c -o rgw/test_build_librgw-rgw_os_lib.obj `if test -f 'rgw/rgw_os_lib.cc'; then $(CYGPATH_W) 'rgw/rgw_os_lib.cc'; else $(CYGPATH_W) '$(srcdir)/rgw/rgw_os_lib.cc'; fi`
 
-rgw/test_build_librgw-rgw_user.o: rgw/rgw_user.cc
- at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -MT rgw/test_build_librgw-rgw_user.o -MD -MP -MF rgw/$(DEPDIR)/test_build_librgw-rgw_user.Tpo -c -o rgw/test_build_librgw-rgw_user.o `test -f 'rgw/rgw_user.cc' || echo '$(srcdir)/'`rgw/rgw_user.cc
- at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/test_build_librgw-rgw_user.Tpo rgw/$(DEPDIR)/test_build_librgw-rgw_user.Po
- at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_user.cc' object='rgw/test_build_librgw-rgw_user.o' libtool=no @AMDEPBACKSLASH@
+rgw/test_build_librgw-rgw_policy_s3.o: rgw/rgw_policy_s3.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -MT rgw/test_build_librgw-rgw_policy_s3.o -MD -MP -MF rgw/$(DEPDIR)/test_build_librgw-rgw_policy_s3.Tpo -c -o rgw/test_build_librgw-rgw_policy_s3.o `test -f 'rgw/rgw_policy_s3.cc' || echo '$(srcdir)/'`rgw/rgw_policy_s3.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/test_build_librgw-rgw_policy_s3.Tpo rgw/$(DEPDIR)/test_build_librgw-rgw_policy_s3.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_policy_s3.cc' object='rgw/test_build_librgw-rgw_policy_s3.o' libtool=no @AMDEPBACKSLASH@
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -c -o rgw/test_build_librgw-rgw_user.o `test -f 'rgw/rgw_user.cc' || echo '$(srcdir)/'`rgw/rgw_user.cc
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -c -o rgw/test_build_librgw-rgw_policy_s3.o `test -f 'rgw/rgw_policy_s3.cc' || echo '$(srcdir)/'`rgw/rgw_policy_s3.cc
 
-rgw/test_build_librgw-rgw_user.obj: rgw/rgw_user.cc
- at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -MT rgw/test_build_librgw-rgw_user.obj -MD -MP -MF rgw/$(DEPDIR)/test_build_librgw-rgw_user.Tpo -c -o rgw/test_build_librgw-rgw_user.obj `if test -f 'rgw/rgw_user.cc'; then $(CYGPATH_W) 'rgw/rgw_user.cc'; else $(CYGPATH_W) '$(srcdir)/rgw/rgw_user.cc'; fi`
- at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/test_build_librgw-rgw_user.Tpo rgw/$(DEPDIR)/test_build_librgw-rgw_user.Po
- at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_user.cc' object='rgw/test_build_librgw-rgw_user.obj' libtool=no @AMDEPBACKSLASH@
+rgw/test_build_librgw-rgw_policy_s3.obj: rgw/rgw_policy_s3.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -MT rgw/test_build_librgw-rgw_policy_s3.obj -MD -MP -MF rgw/$(DEPDIR)/test_build_librgw-rgw_policy_s3.Tpo -c -o rgw/test_build_librgw-rgw_policy_s3.obj `if test -f 'rgw/rgw_policy_s3.cc'; then $(CYGPATH_W) 'rgw/rgw_policy_s3.cc'; else $(CYGPATH_W) '$(srcdir)/rgw/rgw_policy_s3.cc'; fi`
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/test_build_librgw-rgw_policy_s3.Tpo rgw/$(DEPDIR)/test_build_librgw-rgw_policy_s3.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_policy_s3.cc' object='rgw/test_build_librgw-rgw_policy_s3.obj' libtool=no @AMDEPBACKSLASH@
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -c -o rgw/test_build_librgw-rgw_user.obj `if test -f 'rgw/rgw_user.cc'; then $(CYGPATH_W) 'rgw/rgw_user.cc'; else $(CYGPATH_W) '$(srcdir)/rgw/rgw_user.cc'; fi`
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -c -o rgw/test_build_librgw-rgw_policy_s3.obj `if test -f 'rgw/rgw_policy_s3.cc'; then $(CYGPATH_W) 'rgw/rgw_policy_s3.cc'; else $(CYGPATH_W) '$(srcdir)/rgw/rgw_policy_s3.cc'; fi`
 
-rgw/test_build_librgw-rgw_bucket.o: rgw/rgw_bucket.cc
- at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -MT rgw/test_build_librgw-rgw_bucket.o -MD -MP -MF rgw/$(DEPDIR)/test_build_librgw-rgw_bucket.Tpo -c -o rgw/test_build_librgw-rgw_bucket.o `test -f 'rgw/rgw_bucket.cc' || echo '$(srcdir)/'`rgw/rgw_bucket.cc
- at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/test_build_librgw-rgw_bucket.Tpo rgw/$(DEPDIR)/test_build_librgw-rgw_bucket.Po
- at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_bucket.cc' object='rgw/test_build_librgw-rgw_bucket.o' libtool=no @AMDEPBACKSLASH@
+rgw/test_build_librgw-rgw_process.o: rgw/rgw_process.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -MT rgw/test_build_librgw-rgw_process.o -MD -MP -MF rgw/$(DEPDIR)/test_build_librgw-rgw_process.Tpo -c -o rgw/test_build_librgw-rgw_process.o `test -f 'rgw/rgw_process.cc' || echo '$(srcdir)/'`rgw/rgw_process.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/test_build_librgw-rgw_process.Tpo rgw/$(DEPDIR)/test_build_librgw-rgw_process.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_process.cc' object='rgw/test_build_librgw-rgw_process.o' libtool=no @AMDEPBACKSLASH@
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -c -o rgw/test_build_librgw-rgw_bucket.o `test -f 'rgw/rgw_bucket.cc' || echo '$(srcdir)/'`rgw/rgw_bucket.cc
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -c -o rgw/test_build_librgw-rgw_process.o `test -f 'rgw/rgw_process.cc' || echo '$(srcdir)/'`rgw/rgw_process.cc
 
-rgw/test_build_librgw-rgw_bucket.obj: rgw/rgw_bucket.cc
- at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -MT rgw/test_build_librgw-rgw_bucket.obj -MD -MP -MF rgw/$(DEPDIR)/test_build_librgw-rgw_bucket.Tpo -c -o rgw/test_build_librgw-rgw_bucket.obj `if test -f 'rgw/rgw_bucket.cc'; then $(CYGPATH_W) 'rgw/rgw_bucket.cc'; else $(CYGPATH_W) '$(srcdir)/rgw/rgw_bucket.cc'; fi`
- at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/test_build_librgw-rgw_bucket.Tpo rgw/$(DEPDIR)/test_build_librgw-rgw_bucket.Po
- at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_bucket.cc' object='rgw/test_build_librgw-rgw_bucket.obj' libtool=no @AMDEPBACKSLASH@
+rgw/test_build_librgw-rgw_process.obj: rgw/rgw_process.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -MT rgw/test_build_librgw-rgw_process.obj -MD -MP -MF rgw/$(DEPDIR)/test_build_librgw-rgw_process.Tpo -c -o rgw/test_build_librgw-rgw_process.obj `if test -f 'rgw/rgw_process.cc'; then $(CYGPATH_W) 'rgw/rgw_process.cc'; else $(CYGPATH_W) '$(srcdir)/rgw/rgw_process.cc'; fi`
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/test_build_librgw-rgw_process.Tpo rgw/$(DEPDIR)/test_build_librgw-rgw_process.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_process.cc' object='rgw/test_build_librgw-rgw_process.obj' libtool=no @AMDEPBACKSLASH@
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -c -o rgw/test_build_librgw-rgw_bucket.obj `if test -f 'rgw/rgw_bucket.cc'; then $(CYGPATH_W) 'rgw/rgw_bucket.cc'; else $(CYGPATH_W) '$(srcdir)/rgw/rgw_bucket.cc'; fi`
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -c -o rgw/test_build_librgw-rgw_process.obj `if test -f 'rgw/rgw_process.cc'; then $(CYGPATH_W) 'rgw/rgw_process.cc'; else $(CYGPATH_W) '$(srcdir)/rgw/rgw_process.cc'; fi`
 
-rgw/test_build_librgw-rgw_tools.o: rgw/rgw_tools.cc
- at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -MT rgw/test_build_librgw-rgw_tools.o -MD -MP -MF rgw/$(DEPDIR)/test_build_librgw-rgw_tools.Tpo -c -o rgw/test_build_librgw-rgw_tools.o `test -f 'rgw/rgw_tools.cc' || echo '$(srcdir)/'`rgw/rgw_tools.cc
- at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/test_build_librgw-rgw_tools.Tpo rgw/$(DEPDIR)/test_build_librgw-rgw_tools.Po
- at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_tools.cc' object='rgw/test_build_librgw-rgw_tools.o' libtool=no @AMDEPBACKSLASH@
+rgw/test_build_librgw-rgw_quota.o: rgw/rgw_quota.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -MT rgw/test_build_librgw-rgw_quota.o -MD -MP -MF rgw/$(DEPDIR)/test_build_librgw-rgw_quota.Tpo -c -o rgw/test_build_librgw-rgw_quota.o `test -f 'rgw/rgw_quota.cc' || echo '$(srcdir)/'`rgw/rgw_quota.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/test_build_librgw-rgw_quota.Tpo rgw/$(DEPDIR)/test_build_librgw-rgw_quota.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_quota.cc' object='rgw/test_build_librgw-rgw_quota.o' libtool=no @AMDEPBACKSLASH@
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -c -o rgw/test_build_librgw-rgw_tools.o `test -f 'rgw/rgw_tools.cc' || echo '$(srcdir)/'`rgw/rgw_tools.cc
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -c -o rgw/test_build_librgw-rgw_quota.o `test -f 'rgw/rgw_quota.cc' || echo '$(srcdir)/'`rgw/rgw_quota.cc
 
-rgw/test_build_librgw-rgw_tools.obj: rgw/rgw_tools.cc
- at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -MT rgw/test_build_librgw-rgw_tools.obj -MD -MP -MF rgw/$(DEPDIR)/test_build_librgw-rgw_tools.Tpo -c -o rgw/test_build_librgw-rgw_tools.obj `if test -f 'rgw/rgw_tools.cc'; then $(CYGPATH_W) 'rgw/rgw_tools.cc'; else $(CYGPATH_W) '$(srcdir)/rgw/rgw_tools.cc'; fi`
- at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/test_build_librgw-rgw_tools.Tpo rgw/$(DEPDIR)/test_build_librgw-rgw_tools.Po
- at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_tools.cc' object='rgw/test_build_librgw-rgw_tools.obj' libtool=no @AMDEPBACKSLASH@
+rgw/test_build_librgw-rgw_quota.obj: rgw/rgw_quota.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -MT rgw/test_build_librgw-rgw_quota.obj -MD -MP -MF rgw/$(DEPDIR)/test_build_librgw-rgw_quota.Tpo -c -o rgw/test_build_librgw-rgw_quota.obj `if test -f 'rgw/rgw_quota.cc'; then $(CYGPATH_W) 'rgw/rgw_quota.cc'; else $(CYGPATH_W) '$(srcdir)/rgw/rgw_quota.cc'; fi`
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/test_build_librgw-rgw_quota.Tpo rgw/$(DEPDIR)/test_build_librgw-rgw_quota.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_quota.cc' object='rgw/test_build_librgw-rgw_quota.obj' libtool=no @AMDEPBACKSLASH@
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -c -o rgw/test_build_librgw-rgw_tools.obj `if test -f 'rgw/rgw_tools.cc'; then $(CYGPATH_W) 'rgw/rgw_tools.cc'; else $(CYGPATH_W) '$(srcdir)/rgw/rgw_tools.cc'; fi`
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -c -o rgw/test_build_librgw-rgw_quota.obj `if test -f 'rgw/rgw_quota.cc'; then $(CYGPATH_W) 'rgw/rgw_quota.cc'; else $(CYGPATH_W) '$(srcdir)/rgw/rgw_quota.cc'; fi`
 
 rgw/test_build_librgw-rgw_rados.o: rgw/rgw_rados.cc
 @am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -MT rgw/test_build_librgw-rgw_rados.o -MD -MP -MF rgw/$(DEPDIR)/test_build_librgw-rgw_rados.Tpo -c -o rgw/test_build_librgw-rgw_rados.o `test -f 'rgw/rgw_rados.cc' || echo '$(srcdir)/'`rgw/rgw_rados.cc
@@ -25261,19 +27020,75 @@ rgw/test_build_librgw-rgw_rados.obj: rgw/rgw_rados.cc
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -c -o rgw/test_build_librgw-rgw_rados.obj `if test -f 'rgw/rgw_rados.cc'; then $(CYGPATH_W) 'rgw/rgw_rados.cc'; else $(CYGPATH_W) '$(srcdir)/rgw/rgw_rados.cc'; fi`
 
-rgw/test_build_librgw-rgw_http_client.o: rgw/rgw_http_client.cc
- at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -MT rgw/test_build_librgw-rgw_http_client.o -MD -MP -MF rgw/$(DEPDIR)/test_build_librgw-rgw_http_client.Tpo -c -o rgw/test_build_librgw-rgw_http_client.o `test -f 'rgw/rgw_http_client.cc' || echo '$(srcdir)/'`rgw/rgw_http_client.cc
- at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/test_build_librgw-rgw_http_client.Tpo rgw/$(DEPDIR)/test_build_librgw-rgw_http_client.Po
- at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_http_client.cc' object='rgw/test_build_librgw-rgw_http_client.o' libtool=no @AMDEPBACKSLASH@
+rgw/test_build_librgw-rgw_replica_log.o: rgw/rgw_replica_log.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -MT rgw/test_build_librgw-rgw_replica_log.o -MD -MP -MF rgw/$(DEPDIR)/test_build_librgw-rgw_replica_log.Tpo -c -o rgw/test_build_librgw-rgw_replica_log.o `test -f 'rgw/rgw_replica_log.cc' || echo '$(srcdir)/'`rgw/rgw_replica_log.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/test_build_librgw-rgw_replica_log.Tpo rgw/$(DEPDIR)/test_build_librgw-rgw_replica_log.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_replica_log.cc' object='rgw/test_build_librgw-rgw_replica_log.o' libtool=no @AMDEPBACKSLASH@
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -c -o rgw/test_build_librgw-rgw_http_client.o `test -f 'rgw/rgw_http_client.cc' || echo '$(srcdir)/'`rgw/rgw_http_client.cc
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -c -o rgw/test_build_librgw-rgw_replica_log.o `test -f 'rgw/rgw_replica_log.cc' || echo '$(srcdir)/'`rgw/rgw_replica_log.cc
 
-rgw/test_build_librgw-rgw_http_client.obj: rgw/rgw_http_client.cc
- at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -MT rgw/test_build_librgw-rgw_http_client.obj -MD -MP -MF rgw/$(DEPDIR)/test_build_librgw-rgw_http_client.Tpo -c -o rgw/test_build_librgw-rgw_http_client.obj `if test -f 'rgw/rgw_http_client.cc'; then $(CYGPATH_W) 'rgw/rgw_http_client.cc'; else $(CYGPATH_W) '$(srcdir)/rgw/rgw_http_client.cc'; fi`
- at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/test_build_librgw-rgw_http_client.Tpo rgw/$(DEPDIR)/test_build_librgw-rgw_http_client.Po
- at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_http_client.cc' object='rgw/test_build_librgw-rgw_http_client.obj' libtool=no @AMDEPBACKSLASH@
+rgw/test_build_librgw-rgw_replica_log.obj: rgw/rgw_replica_log.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -MT rgw/test_build_librgw-rgw_replica_log.obj -MD -MP -MF rgw/$(DEPDIR)/test_build_librgw-rgw_replica_log.Tpo -c -o rgw/test_build_librgw-rgw_replica_log.obj `if test -f 'rgw/rgw_replica_log.cc'; then $(CYGPATH_W) 'rgw/rgw_replica_log.cc'; else $(CYGPATH_W) '$(srcdir)/rgw/rgw_replica_log.cc'; fi`
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/test_build_librgw-rgw_replica_log.Tpo rgw/$(DEPDIR)/test_build_librgw-rgw_replica_log.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_replica_log.cc' object='rgw/test_build_librgw-rgw_replica_log.obj' libtool=no @AMDEPBACKSLASH@
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -c -o rgw/test_build_librgw-rgw_http_client.obj `if test -f 'rgw/rgw_http_client.cc'; then $(CYGPATH_W) 'rgw/rgw_http_client.cc'; else $(CYGPATH_W) '$(srcdir)/rgw/rgw_http_client.cc'; fi`
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -c -o rgw/test_build_librgw-rgw_replica_log.obj `if test -f 'rgw/rgw_replica_log.cc'; then $(CYGPATH_W) 'rgw/rgw_replica_log.cc'; else $(CYGPATH_W) '$(srcdir)/rgw/rgw_replica_log.cc'; fi`
+
+rgw/test_build_librgw-rgw_request.o: rgw/rgw_request.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -MT rgw/test_build_librgw-rgw_request.o -MD -MP -MF rgw/$(DEPDIR)/test_build_librgw-rgw_request.Tpo -c -o rgw/test_build_librgw-rgw_request.o `test -f 'rgw/rgw_request.cc' || echo '$(srcdir)/'`rgw/rgw_request.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/test_build_librgw-rgw_request.Tpo rgw/$(DEPDIR)/test_build_librgw-rgw_request.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_request.cc' object='rgw/test_build_librgw-rgw_request.o' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -c -o rgw/test_build_librgw-rgw_request.o `test -f 'rgw/rgw_request.cc' || echo '$(srcdir)/'`rgw/rgw_request.cc
+
+rgw/test_build_librgw-rgw_request.obj: rgw/rgw_request.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -MT rgw/test_build_librgw-rgw_request.obj -MD -MP -MF rgw/$(DEPDIR)/test_build_librgw-rgw_request.Tpo -c -o rgw/test_build_librgw-rgw_request.obj `if test -f 'rgw/rgw_request.cc'; then $(CYGPATH_W) 'rgw/rgw_request.cc'; else $(CYGPATH_W) '$(srcdir)/rgw/rgw_request.cc'; fi`
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/test_build_librgw-rgw_request.Tpo rgw/$(DEPDIR)/test_build_librgw-rgw_request.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_request.cc' object='rgw/test_build_librgw-rgw_request.obj' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -c -o rgw/test_build_librgw-rgw_request.obj `if test -f 'rgw/rgw_request.cc'; then $(CYGPATH_W) 'rgw/rgw_request.cc'; else $(CYGPATH_W) '$(srcdir)/rgw/rgw_request.cc'; fi`
+
+rgw/test_build_librgw-rgw_resolve.o: rgw/rgw_resolve.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -MT rgw/test_build_librgw-rgw_resolve.o -MD -MP -MF rgw/$(DEPDIR)/test_build_librgw-rgw_resolve.Tpo -c -o rgw/test_build_librgw-rgw_resolve.o `test -f 'rgw/rgw_resolve.cc' || echo '$(srcdir)/'`rgw/rgw_resolve.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/test_build_librgw-rgw_resolve.Tpo rgw/$(DEPDIR)/test_build_librgw-rgw_resolve.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_resolve.cc' object='rgw/test_build_librgw-rgw_resolve.o' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -c -o rgw/test_build_librgw-rgw_resolve.o `test -f 'rgw/rgw_resolve.cc' || echo '$(srcdir)/'`rgw/rgw_resolve.cc
+
+rgw/test_build_librgw-rgw_resolve.obj: rgw/rgw_resolve.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -MT rgw/test_build_librgw-rgw_resolve.obj -MD -MP -MF rgw/$(DEPDIR)/test_build_librgw-rgw_resolve.Tpo -c -o rgw/test_build_librgw-rgw_resolve.obj `if test -f 'rgw/rgw_resolve.cc'; then $(CYGPATH_W) 'rgw/rgw_resolve.cc'; else $(CYGPATH_W) '$(srcdir)/rgw/rgw_resolve.cc'; fi`
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/test_build_librgw-rgw_resolve.Tpo rgw/$(DEPDIR)/test_build_librgw-rgw_resolve.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_resolve.cc' object='rgw/test_build_librgw-rgw_resolve.obj' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -c -o rgw/test_build_librgw-rgw_resolve.obj `if test -f 'rgw/rgw_resolve.cc'; then $(CYGPATH_W) 'rgw/rgw_resolve.cc'; else $(CYGPATH_W) '$(srcdir)/rgw/rgw_resolve.cc'; fi`
+
+rgw/test_build_librgw-rgw_rest_bucket.o: rgw/rgw_rest_bucket.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -MT rgw/test_build_librgw-rgw_rest_bucket.o -MD -MP -MF rgw/$(DEPDIR)/test_build_librgw-rgw_rest_bucket.Tpo -c -o rgw/test_build_librgw-rgw_rest_bucket.o `test -f 'rgw/rgw_rest_bucket.cc' || echo '$(srcdir)/'`rgw/rgw_rest_bucket.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/test_build_librgw-rgw_rest_bucket.Tpo rgw/$(DEPDIR)/test_build_librgw-rgw_rest_bucket.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_rest_bucket.cc' object='rgw/test_build_librgw-rgw_rest_bucket.o' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -c -o rgw/test_build_librgw-rgw_rest_bucket.o `test -f 'rgw/rgw_rest_bucket.cc' || echo '$(srcdir)/'`rgw/rgw_rest_bucket.cc
+
+rgw/test_build_librgw-rgw_rest_bucket.obj: rgw/rgw_rest_bucket.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -MT rgw/test_build_librgw-rgw_rest_bucket.obj -MD -MP -MF rgw/$(DEPDIR)/test_build_librgw-rgw_rest_bucket.Tpo -c -o rgw/test_build_librgw-rgw_rest_bucket.obj `if test -f 'rgw/rgw_rest_bucket.cc'; then $(CYGPATH_W) 'rgw/rgw_rest_bucket.cc'; else $(CYGPATH_W) '$(srcdir)/rgw/rgw_rest_bucket.cc'; fi`
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/test_build_librgw-rgw_rest_bucket.Tpo rgw/$(DEPDIR)/test_build_librgw-rgw_rest_bucket.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_rest_bucket.cc' object='rgw/test_build_librgw-rgw_rest_bucket.obj' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -c -o rgw/test_build_librgw-rgw_rest_bucket.obj `if test -f 'rgw/rgw_rest_bucket.cc'; then $(CYGPATH_W) 'rgw/rgw_rest_bucket.cc'; else $(CYGPATH_W) '$(srcdir)/rgw/rgw_rest_bucket.cc'; fi`
+
+rgw/test_build_librgw-rgw_rest.o: rgw/rgw_rest.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -MT rgw/test_build_librgw-rgw_rest.o -MD -MP -MF rgw/$(DEPDIR)/test_build_librgw-rgw_rest.Tpo -c -o rgw/test_build_librgw-rgw_rest.o `test -f 'rgw/rgw_rest.cc' || echo '$(srcdir)/'`rgw/rgw_rest.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/test_build_librgw-rgw_rest.Tpo rgw/$(DEPDIR)/test_build_librgw-rgw_rest.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_rest.cc' object='rgw/test_build_librgw-rgw_rest.o' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -c -o rgw/test_build_librgw-rgw_rest.o `test -f 'rgw/rgw_rest.cc' || echo '$(srcdir)/'`rgw/rgw_rest.cc
+
+rgw/test_build_librgw-rgw_rest.obj: rgw/rgw_rest.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -MT rgw/test_build_librgw-rgw_rest.obj -MD -MP -MF rgw/$(DEPDIR)/test_build_librgw-rgw_rest.Tpo -c -o rgw/test_build_librgw-rgw_rest.obj `if test -f 'rgw/rgw_rest.cc'; then $(CYGPATH_W) 'rgw/rgw_rest.cc'; else $(CYGPATH_W) '$(srcdir)/rgw/rgw_rest.cc'; fi`
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/test_build_librgw-rgw_rest.Tpo rgw/$(DEPDIR)/test_build_librgw-rgw_rest.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_rest.cc' object='rgw/test_build_librgw-rgw_rest.obj' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -c -o rgw/test_build_librgw-rgw_rest.obj `if test -f 'rgw/rgw_rest.cc'; then $(CYGPATH_W) 'rgw/rgw_rest.cc'; else $(CYGPATH_W) '$(srcdir)/rgw/rgw_rest.cc'; fi`
 
 rgw/test_build_librgw-rgw_rest_client.o: rgw/rgw_rest_client.cc
 @am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -MT rgw/test_build_librgw-rgw_rest_client.o -MD -MP -MF rgw/$(DEPDIR)/test_build_librgw-rgw_rest_client.Tpo -c -o rgw/test_build_librgw-rgw_rest_client.o `test -f 'rgw/rgw_rest_client.cc' || echo '$(srcdir)/'`rgw/rgw_rest_client.cc
@@ -25289,6 +27104,20 @@ rgw/test_build_librgw-rgw_rest_client.obj: rgw/rgw_rest_client.cc
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -c -o rgw/test_build_librgw-rgw_rest_client.obj `if test -f 'rgw/rgw_rest_client.cc'; then $(CYGPATH_W) 'rgw/rgw_rest_client.cc'; else $(CYGPATH_W) '$(srcdir)/rgw/rgw_rest_client.cc'; fi`
 
+rgw/test_build_librgw-rgw_rest_config.o: rgw/rgw_rest_config.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -MT rgw/test_build_librgw-rgw_rest_config.o -MD -MP -MF rgw/$(DEPDIR)/test_build_librgw-rgw_rest_config.Tpo -c -o rgw/test_build_librgw-rgw_rest_config.o `test -f 'rgw/rgw_rest_config.cc' || echo '$(srcdir)/'`rgw/rgw_rest_config.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/test_build_librgw-rgw_rest_config.Tpo rgw/$(DEPDIR)/test_build_librgw-rgw_rest_config.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_rest_config.cc' object='rgw/test_build_librgw-rgw_rest_config.o' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -c -o rgw/test_build_librgw-rgw_rest_config.o `test -f 'rgw/rgw_rest_config.cc' || echo '$(srcdir)/'`rgw/rgw_rest_config.cc
+
+rgw/test_build_librgw-rgw_rest_config.obj: rgw/rgw_rest_config.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -MT rgw/test_build_librgw-rgw_rest_config.obj -MD -MP -MF rgw/$(DEPDIR)/test_build_librgw-rgw_rest_config.Tpo -c -o rgw/test_build_librgw-rgw_rest_config.obj `if test -f 'rgw/rgw_rest_config.cc'; then $(CYGPATH_W) 'rgw/rgw_rest_config.cc'; else $(CYGPATH_W) '$(srcdir)/rgw/rgw_rest_config.cc'; fi`
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/test_build_librgw-rgw_rest_config.Tpo rgw/$(DEPDIR)/test_build_librgw-rgw_rest_config.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_rest_config.cc' object='rgw/test_build_librgw-rgw_rest_config.obj' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -c -o rgw/test_build_librgw-rgw_rest_config.obj `if test -f 'rgw/rgw_rest_config.cc'; then $(CYGPATH_W) 'rgw/rgw_rest_config.cc'; else $(CYGPATH_W) '$(srcdir)/rgw/rgw_rest_config.cc'; fi`
+
 rgw/test_build_librgw-rgw_rest_conn.o: rgw/rgw_rest_conn.cc
 @am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -MT rgw/test_build_librgw-rgw_rest_conn.o -MD -MP -MF rgw/$(DEPDIR)/test_build_librgw-rgw_rest_conn.Tpo -c -o rgw/test_build_librgw-rgw_rest_conn.o `test -f 'rgw/rgw_rest_conn.cc' || echo '$(srcdir)/'`rgw/rgw_rest_conn.cc
 @am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/test_build_librgw-rgw_rest_conn.Tpo rgw/$(DEPDIR)/test_build_librgw-rgw_rest_conn.Po
@@ -25303,285 +27132,243 @@ rgw/test_build_librgw-rgw_rest_conn.obj: rgw/rgw_rest_conn.cc
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -c -o rgw/test_build_librgw-rgw_rest_conn.obj `if test -f 'rgw/rgw_rest_conn.cc'; then $(CYGPATH_W) 'rgw/rgw_rest_conn.cc'; else $(CYGPATH_W) '$(srcdir)/rgw/rgw_rest_conn.cc'; fi`
 
-rgw/test_build_librgw-rgw_op.o: rgw/rgw_op.cc
- at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -MT rgw/test_build_librgw-rgw_op.o -MD -MP -MF rgw/$(DEPDIR)/test_build_librgw-rgw_op.Tpo -c -o rgw/test_build_librgw-rgw_op.o `test -f 'rgw/rgw_op.cc' || echo '$(srcdir)/'`rgw/rgw_op.cc
- at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/test_build_librgw-rgw_op.Tpo rgw/$(DEPDIR)/test_build_librgw-rgw_op.Po
- at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_op.cc' object='rgw/test_build_librgw-rgw_op.o' libtool=no @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -c -o rgw/test_build_librgw-rgw_op.o `test -f 'rgw/rgw_op.cc' || echo '$(srcdir)/'`rgw/rgw_op.cc
-
-rgw/test_build_librgw-rgw_op.obj: rgw/rgw_op.cc
- at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -MT rgw/test_build_librgw-rgw_op.obj -MD -MP -MF rgw/$(DEPDIR)/test_build_librgw-rgw_op.Tpo -c -o rgw/test_build_librgw-rgw_op.obj `if test -f 'rgw/rgw_op.cc'; then $(CYGPATH_W) 'rgw/rgw_op.cc'; else $(CYGPATH_W) '$(srcdir)/rgw/rgw_op.cc'; fi`
- at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/test_build_librgw-rgw_op.Tpo rgw/$(DEPDIR)/test_build_librgw-rgw_op.Po
- at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_op.cc' object='rgw/test_build_librgw-rgw_op.obj' libtool=no @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -c -o rgw/test_build_librgw-rgw_op.obj `if test -f 'rgw/rgw_op.cc'; then $(CYGPATH_W) 'rgw/rgw_op.cc'; else $(CYGPATH_W) '$(srcdir)/rgw/rgw_op.cc'; fi`
-
-rgw/test_build_librgw-rgw_basic_types.o: rgw/rgw_basic_types.cc
- at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -MT rgw/test_build_librgw-rgw_basic_types.o -MD -MP -MF rgw/$(DEPDIR)/test_build_librgw-rgw_basic_types.Tpo -c -o rgw/test_build_librgw-rgw_basic_types.o `test -f 'rgw/rgw_basic_types.cc' || echo '$(srcdir)/'`rgw/rgw_basic_types.cc
- at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/test_build_librgw-rgw_basic_types.Tpo rgw/$(DEPDIR)/test_build_librgw-rgw_basic_types.Po
- at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_basic_types.cc' object='rgw/test_build_librgw-rgw_basic_types.o' libtool=no @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -c -o rgw/test_build_librgw-rgw_basic_types.o `test -f 'rgw/rgw_basic_types.cc' || echo '$(srcdir)/'`rgw/rgw_basic_types.cc
-
-rgw/test_build_librgw-rgw_basic_types.obj: rgw/rgw_basic_types.cc
- at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -MT rgw/test_build_librgw-rgw_basic_types.obj -MD -MP -MF rgw/$(DEPDIR)/test_build_librgw-rgw_basic_types.Tpo -c -o rgw/test_build_librgw-rgw_basic_types.obj `if test -f 'rgw/rgw_basic_types.cc'; then $(CYGPATH_W) 'rgw/rgw_basic_types.cc'; else $(CYGPATH_W) '$(srcdir)/rgw/rgw_basic_types.cc'; fi`
- at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/test_build_librgw-rgw_basic_types.Tpo rgw/$(DEPDIR)/test_build_librgw-rgw_basic_types.Po
- at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_basic_types.cc' object='rgw/test_build_librgw-rgw_basic_types.obj' libtool=no @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -c -o rgw/test_build_librgw-rgw_basic_types.obj `if test -f 'rgw/rgw_basic_types.cc'; then $(CYGPATH_W) 'rgw/rgw_basic_types.cc'; else $(CYGPATH_W) '$(srcdir)/rgw/rgw_basic_types.cc'; fi`
-
-rgw/test_build_librgw-rgw_common.o: rgw/rgw_common.cc
- at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -MT rgw/test_build_librgw-rgw_common.o -MD -MP -MF rgw/$(DEPDIR)/test_build_librgw-rgw_common.Tpo -c -o rgw/test_build_librgw-rgw_common.o `test -f 'rgw/rgw_common.cc' || echo '$(srcdir)/'`rgw/rgw_common.cc
- at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/test_build_librgw-rgw_common.Tpo rgw/$(DEPDIR)/test_build_librgw-rgw_common.Po
- at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_common.cc' object='rgw/test_build_librgw-rgw_common.o' libtool=no @AMDEPBACKSLASH@
+rgw/test_build_librgw-rgw_rest_log.o: rgw/rgw_rest_log.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -MT rgw/test_build_librgw-rgw_rest_log.o -MD -MP -MF rgw/$(DEPDIR)/test_build_librgw-rgw_rest_log.Tpo -c -o rgw/test_build_librgw-rgw_rest_log.o `test -f 'rgw/rgw_rest_log.cc' || echo '$(srcdir)/'`rgw/rgw_rest_log.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/test_build_librgw-rgw_rest_log.Tpo rgw/$(DEPDIR)/test_build_librgw-rgw_rest_log.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_rest_log.cc' object='rgw/test_build_librgw-rgw_rest_log.o' libtool=no @AMDEPBACKSLASH@
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -c -o rgw/test_build_librgw-rgw_common.o `test -f 'rgw/rgw_common.cc' || echo '$(srcdir)/'`rgw/rgw_common.cc
-
-rgw/test_build_librgw-rgw_common.obj: rgw/rgw_common.cc
- at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -MT rgw/test_build_librgw-rgw_common.obj -MD -MP -MF rgw/$(DEPDIR)/test_build_librgw-rgw_common.Tpo -c -o rgw/test_build_librgw-rgw_common.obj `if test -f 'rgw/rgw_common.cc'; then $(CYGPATH_W) 'rgw/rgw_common.cc'; else $(CYGPATH_W) '$(srcdir)/rgw/rgw_common.cc'; fi`
- at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/test_build_librgw-rgw_common.Tpo rgw/$(DEPDIR)/test_build_librgw-rgw_common.Po
- at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_common.cc' object='rgw/test_build_librgw-rgw_common.obj' libtool=no @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -c -o rgw/test_build_librgw-rgw_common.obj `if test -f 'rgw/rgw_common.cc'; then $(CYGPATH_W) 'rgw/rgw_common.cc'; else $(CYGPATH_W) '$(srcdir)/rgw/rgw_common.cc'; fi`
-
-rgw/test_build_librgw-rgw_cache.o: rgw/rgw_cache.cc
- at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -MT rgw/test_build_librgw-rgw_cache.o -MD -MP -MF rgw/$(DEPDIR)/test_build_librgw-rgw_cache.Tpo -c -o rgw/test_build_librgw-rgw_cache.o `test -f 'rgw/rgw_cache.cc' || echo '$(srcdir)/'`rgw/rgw_cache.cc
- at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/test_build_librgw-rgw_cache.Tpo rgw/$(DEPDIR)/test_build_librgw-rgw_cache.Po
- at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_cache.cc' object='rgw/test_build_librgw-rgw_cache.o' libtool=no @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -c -o rgw/test_build_librgw-rgw_cache.o `test -f 'rgw/rgw_cache.cc' || echo '$(srcdir)/'`rgw/rgw_cache.cc
-
-rgw/test_build_librgw-rgw_cache.obj: rgw/rgw_cache.cc
- at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -MT rgw/test_build_librgw-rgw_cache.obj -MD -MP -MF rgw/$(DEPDIR)/test_build_librgw-rgw_cache.Tpo -c -o rgw/test_build_librgw-rgw_cache.obj `if test -f 'rgw/rgw_cache.cc'; then $(CYGPATH_W) 'rgw/rgw_cache.cc'; else $(CYGPATH_W) '$(srcdir)/rgw/rgw_cache.cc'; fi`
- at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/test_build_librgw-rgw_cache.Tpo rgw/$(DEPDIR)/test_build_librgw-rgw_cache.Po
- at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_cache.cc' object='rgw/test_build_librgw-rgw_cache.obj' libtool=no @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -c -o rgw/test_build_librgw-rgw_cache.obj `if test -f 'rgw/rgw_cache.cc'; then $(CYGPATH_W) 'rgw/rgw_cache.cc'; else $(CYGPATH_W) '$(srcdir)/rgw/rgw_cache.cc'; fi`
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -c -o rgw/test_build_librgw-rgw_rest_log.o `test -f 'rgw/rgw_rest_log.cc' || echo '$(srcdir)/'`rgw/rgw_rest_log.cc
 
-rgw/test_build_librgw-rgw_formats.o: rgw/rgw_formats.cc
- at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -MT rgw/test_build_librgw-rgw_formats.o -MD -MP -MF rgw/$(DEPDIR)/test_build_librgw-rgw_formats.Tpo -c -o rgw/test_build_librgw-rgw_formats.o `test -f 'rgw/rgw_formats.cc' || echo '$(srcdir)/'`rgw/rgw_formats.cc
- at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/test_build_librgw-rgw_formats.Tpo rgw/$(DEPDIR)/test_build_librgw-rgw_formats.Po
- at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_formats.cc' object='rgw/test_build_librgw-rgw_formats.o' libtool=no @AMDEPBACKSLASH@
+rgw/test_build_librgw-rgw_rest_log.obj: rgw/rgw_rest_log.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -MT rgw/test_build_librgw-rgw_rest_log.obj -MD -MP -MF rgw/$(DEPDIR)/test_build_librgw-rgw_rest_log.Tpo -c -o rgw/test_build_librgw-rgw_rest_log.obj `if test -f 'rgw/rgw_rest_log.cc'; then $(CYGPATH_W) 'rgw/rgw_rest_log.cc'; else $(CYGPATH_W) '$(srcdir)/rgw/rgw_rest_log.cc'; fi`
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/test_build_librgw-rgw_rest_log.Tpo rgw/$(DEPDIR)/test_build_librgw-rgw_rest_log.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_rest_log.cc' object='rgw/test_build_librgw-rgw_rest_log.obj' libtool=no @AMDEPBACKSLASH@
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -c -o rgw/test_build_librgw-rgw_formats.o `test -f 'rgw/rgw_formats.cc' || echo '$(srcdir)/'`rgw/rgw_formats.cc
-
-rgw/test_build_librgw-rgw_formats.obj: rgw/rgw_formats.cc
- at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -MT rgw/test_build_librgw-rgw_formats.obj -MD -MP -MF rgw/$(DEPDIR)/test_build_librgw-rgw_formats.Tpo -c -o rgw/test_build_librgw-rgw_formats.obj `if test -f 'rgw/rgw_formats.cc'; then $(CYGPATH_W) 'rgw/rgw_formats.cc'; else $(CYGPATH_W) '$(srcdir)/rgw/rgw_formats.cc'; fi`
- at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/test_build_librgw-rgw_formats.Tpo rgw/$(DEPDIR)/test_build_librgw-rgw_formats.Po
- at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_formats.cc' object='rgw/test_build_librgw-rgw_formats.obj' libtool=no @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -c -o rgw/test_build_librgw-rgw_rest_log.obj `if test -f 'rgw/rgw_rest_log.cc'; then $(CYGPATH_W) 'rgw/rgw_rest_log.cc'; else $(CYGPATH_W) '$(srcdir)/rgw/rgw_rest_log.cc'; fi`
+
+rgw/test_build_librgw-rgw_rest_metadata.o: rgw/rgw_rest_metadata.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -MT rgw/test_build_librgw-rgw_rest_metadata.o -MD -MP -MF rgw/$(DEPDIR)/test_build_librgw-rgw_rest_metadata.Tpo -c -o rgw/test_build_librgw-rgw_rest_metadata.o `test -f 'rgw/rgw_rest_metadata.cc' || echo '$(srcdir)/'`rgw/rgw_rest_metadata.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/test_build_librgw-rgw_rest_metadata.Tpo rgw/$(DEPDIR)/test_build_librgw-rgw_rest_metadata.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_rest_metadata.cc' object='rgw/test_build_librgw-rgw_rest_metadata.o' libtool=no @AMDEPBACKSLASH@
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -c -o rgw/test_build_librgw-rgw_formats.obj `if test -f 'rgw/rgw_formats.cc'; then $(CYGPATH_W) 'rgw/rgw_formats.cc'; else $(CYGPATH_W) '$(srcdir)/rgw/rgw_formats.cc'; fi`
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -c -o rgw/test_build_librgw-rgw_rest_metadata.o `test -f 'rgw/rgw_rest_metadata.cc' || echo '$(srcdir)/'`rgw/rgw_rest_metadata.cc
 
-rgw/test_build_librgw-rgw_log.o: rgw/rgw_log.cc
- at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -MT rgw/test_build_librgw-rgw_log.o -MD -MP -MF rgw/$(DEPDIR)/test_build_librgw-rgw_log.Tpo -c -o rgw/test_build_librgw-rgw_log.o `test -f 'rgw/rgw_log.cc' || echo '$(srcdir)/'`rgw/rgw_log.cc
- at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/test_build_librgw-rgw_log.Tpo rgw/$(DEPDIR)/test_build_librgw-rgw_log.Po
- at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_log.cc' object='rgw/test_build_librgw-rgw_log.o' libtool=no @AMDEPBACKSLASH@
+rgw/test_build_librgw-rgw_rest_metadata.obj: rgw/rgw_rest_metadata.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -MT rgw/test_build_librgw-rgw_rest_metadata.obj -MD -MP -MF rgw/$(DEPDIR)/test_build_librgw-rgw_rest_metadata.Tpo -c -o rgw/test_build_librgw-rgw_rest_metadata.obj `if test -f 'rgw/rgw_rest_metadata.cc'; then $(CYGPATH_W) 'rgw/rgw_rest_metadata.cc'; else $(CYGPATH_W) '$(srcdir)/rgw/rgw_rest_metadata.cc'; fi`
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/test_build_librgw-rgw_rest_metadata.Tpo rgw/$(DEPDIR)/test_build_librgw-rgw_rest_metadata.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_rest_metadata.cc' object='rgw/test_build_librgw-rgw_rest_metadata.obj' libtool=no @AMDEPBACKSLASH@
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -c -o rgw/test_build_librgw-rgw_log.o `test -f 'rgw/rgw_log.cc' || echo '$(srcdir)/'`rgw/rgw_log.cc
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -c -o rgw/test_build_librgw-rgw_rest_metadata.obj `if test -f 'rgw/rgw_rest_metadata.cc'; then $(CYGPATH_W) 'rgw/rgw_rest_metadata.cc'; else $(CYGPATH_W) '$(srcdir)/rgw/rgw_rest_metadata.cc'; fi`
 
-rgw/test_build_librgw-rgw_log.obj: rgw/rgw_log.cc
- at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -MT rgw/test_build_librgw-rgw_log.obj -MD -MP -MF rgw/$(DEPDIR)/test_build_librgw-rgw_log.Tpo -c -o rgw/test_build_librgw-rgw_log.obj `if test -f 'rgw/rgw_log.cc'; then $(CYGPATH_W) 'rgw/rgw_log.cc'; else $(CYGPATH_W) '$(srcdir)/rgw/rgw_log.cc'; fi`
- at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/test_build_librgw-rgw_log.Tpo rgw/$(DEPDIR)/test_build_librgw-rgw_log.Po
- at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_log.cc' object='rgw/test_build_librgw-rgw_log.obj' libtool=no @AMDEPBACKSLASH@
+rgw/test_build_librgw-rgw_rest_opstate.o: rgw/rgw_rest_opstate.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -MT rgw/test_build_librgw-rgw_rest_opstate.o -MD -MP -MF rgw/$(DEPDIR)/test_build_librgw-rgw_rest_opstate.Tpo -c -o rgw/test_build_librgw-rgw_rest_opstate.o `test -f 'rgw/rgw_rest_opstate.cc' || echo '$(srcdir)/'`rgw/rgw_rest_opstate.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/test_build_librgw-rgw_rest_opstate.Tpo rgw/$(DEPDIR)/test_build_librgw-rgw_rest_opstate.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_rest_opstate.cc' object='rgw/test_build_librgw-rgw_rest_opstate.o' libtool=no @AMDEPBACKSLASH@
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -c -o rgw/test_build_librgw-rgw_log.obj `if test -f 'rgw/rgw_log.cc'; then $(CYGPATH_W) 'rgw/rgw_log.cc'; else $(CYGPATH_W) '$(srcdir)/rgw/rgw_log.cc'; fi`
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -c -o rgw/test_build_librgw-rgw_rest_opstate.o `test -f 'rgw/rgw_rest_opstate.cc' || echo '$(srcdir)/'`rgw/rgw_rest_opstate.cc
 
-rgw/test_build_librgw-rgw_multi.o: rgw/rgw_multi.cc
- at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -MT rgw/test_build_librgw-rgw_multi.o -MD -MP -MF rgw/$(DEPDIR)/test_build_librgw-rgw_multi.Tpo -c -o rgw/test_build_librgw-rgw_multi.o `test -f 'rgw/rgw_multi.cc' || echo '$(srcdir)/'`rgw/rgw_multi.cc
- at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/test_build_librgw-rgw_multi.Tpo rgw/$(DEPDIR)/test_build_librgw-rgw_multi.Po
- at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_multi.cc' object='rgw/test_build_librgw-rgw_multi.o' libtool=no @AMDEPBACKSLASH@
+rgw/test_build_librgw-rgw_rest_opstate.obj: rgw/rgw_rest_opstate.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -MT rgw/test_build_librgw-rgw_rest_opstate.obj -MD -MP -MF rgw/$(DEPDIR)/test_build_librgw-rgw_rest_opstate.Tpo -c -o rgw/test_build_librgw-rgw_rest_opstate.obj `if test -f 'rgw/rgw_rest_opstate.cc'; then $(CYGPATH_W) 'rgw/rgw_rest_opstate.cc'; else $(CYGPATH_W) '$(srcdir)/rgw/rgw_rest_opstate.cc'; fi`
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/test_build_librgw-rgw_rest_opstate.Tpo rgw/$(DEPDIR)/test_build_librgw-rgw_rest_opstate.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_rest_opstate.cc' object='rgw/test_build_librgw-rgw_rest_opstate.obj' libtool=no @AMDEPBACKSLASH@
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -c -o rgw/test_build_librgw-rgw_multi.o `test -f 'rgw/rgw_multi.cc' || echo '$(srcdir)/'`rgw/rgw_multi.cc
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -c -o rgw/test_build_librgw-rgw_rest_opstate.obj `if test -f 'rgw/rgw_rest_opstate.cc'; then $(CYGPATH_W) 'rgw/rgw_rest_opstate.cc'; else $(CYGPATH_W) '$(srcdir)/rgw/rgw_rest_opstate.cc'; fi`
 
-rgw/test_build_librgw-rgw_multi.obj: rgw/rgw_multi.cc
- at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -MT rgw/test_build_librgw-rgw_multi.obj -MD -MP -MF rgw/$(DEPDIR)/test_build_librgw-rgw_multi.Tpo -c -o rgw/test_build_librgw-rgw_multi.obj `if test -f 'rgw/rgw_multi.cc'; then $(CYGPATH_W) 'rgw/rgw_multi.cc'; else $(CYGPATH_W) '$(srcdir)/rgw/rgw_multi.cc'; fi`
- at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/test_build_librgw-rgw_multi.Tpo rgw/$(DEPDIR)/test_build_librgw-rgw_multi.Po
- at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_multi.cc' object='rgw/test_build_librgw-rgw_multi.obj' libtool=no @AMDEPBACKSLASH@
+rgw/test_build_librgw-rgw_rest_realm.o: rgw/rgw_rest_realm.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -MT rgw/test_build_librgw-rgw_rest_realm.o -MD -MP -MF rgw/$(DEPDIR)/test_build_librgw-rgw_rest_realm.Tpo -c -o rgw/test_build_librgw-rgw_rest_realm.o `test -f 'rgw/rgw_rest_realm.cc' || echo '$(srcdir)/'`rgw/rgw_rest_realm.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/test_build_librgw-rgw_rest_realm.Tpo rgw/$(DEPDIR)/test_build_librgw-rgw_rest_realm.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_rest_realm.cc' object='rgw/test_build_librgw-rgw_rest_realm.o' libtool=no @AMDEPBACKSLASH@
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -c -o rgw/test_build_librgw-rgw_multi.obj `if test -f 'rgw/rgw_multi.cc'; then $(CYGPATH_W) 'rgw/rgw_multi.cc'; else $(CYGPATH_W) '$(srcdir)/rgw/rgw_multi.cc'; fi`
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -c -o rgw/test_build_librgw-rgw_rest_realm.o `test -f 'rgw/rgw_rest_realm.cc' || echo '$(srcdir)/'`rgw/rgw_rest_realm.cc
 
-rgw/test_build_librgw-rgw_policy_s3.o: rgw/rgw_policy_s3.cc
- at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -MT rgw/test_build_librgw-rgw_policy_s3.o -MD -MP -MF rgw/$(DEPDIR)/test_build_librgw-rgw_policy_s3.Tpo -c -o rgw/test_build_librgw-rgw_policy_s3.o `test -f 'rgw/rgw_policy_s3.cc' || echo '$(srcdir)/'`rgw/rgw_policy_s3.cc
- at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/test_build_librgw-rgw_policy_s3.Tpo rgw/$(DEPDIR)/test_build_librgw-rgw_policy_s3.Po
- at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_policy_s3.cc' object='rgw/test_build_librgw-rgw_policy_s3.o' libtool=no @AMDEPBACKSLASH@
+rgw/test_build_librgw-rgw_rest_realm.obj: rgw/rgw_rest_realm.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -MT rgw/test_build_librgw-rgw_rest_realm.obj -MD -MP -MF rgw/$(DEPDIR)/test_build_librgw-rgw_rest_realm.Tpo -c -o rgw/test_build_librgw-rgw_rest_realm.obj `if test -f 'rgw/rgw_rest_realm.cc'; then $(CYGPATH_W) 'rgw/rgw_rest_realm.cc'; else $(CYGPATH_W) '$(srcdir)/rgw/rgw_rest_realm.cc'; fi`
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/test_build_librgw-rgw_rest_realm.Tpo rgw/$(DEPDIR)/test_build_librgw-rgw_rest_realm.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_rest_realm.cc' object='rgw/test_build_librgw-rgw_rest_realm.obj' libtool=no @AMDEPBACKSLASH@
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -c -o rgw/test_build_librgw-rgw_policy_s3.o `test -f 'rgw/rgw_policy_s3.cc' || echo '$(srcdir)/'`rgw/rgw_policy_s3.cc
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -c -o rgw/test_build_librgw-rgw_rest_realm.obj `if test -f 'rgw/rgw_rest_realm.cc'; then $(CYGPATH_W) 'rgw/rgw_rest_realm.cc'; else $(CYGPATH_W) '$(srcdir)/rgw/rgw_rest_realm.cc'; fi`
 
-rgw/test_build_librgw-rgw_policy_s3.obj: rgw/rgw_policy_s3.cc
- at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -MT rgw/test_build_librgw-rgw_policy_s3.obj -MD -MP -MF rgw/$(DEPDIR)/test_build_librgw-rgw_policy_s3.Tpo -c -o rgw/test_build_librgw-rgw_policy_s3.obj `if test -f 'rgw/rgw_policy_s3.cc'; then $(CYGPATH_W) 'rgw/rgw_policy_s3.cc'; else $(CYGPATH_W) '$(srcdir)/rgw/rgw_policy_s3.cc'; fi`
- at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/test_build_librgw-rgw_policy_s3.Tpo rgw/$(DEPDIR)/test_build_librgw-rgw_policy_s3.Po
- at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_policy_s3.cc' object='rgw/test_build_librgw-rgw_policy_s3.obj' libtool=no @AMDEPBACKSLASH@
+rgw/test_build_librgw-rgw_rest_replica_log.o: rgw/rgw_rest_replica_log.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -MT rgw/test_build_librgw-rgw_rest_replica_log.o -MD -MP -MF rgw/$(DEPDIR)/test_build_librgw-rgw_rest_replica_log.Tpo -c -o rgw/test_build_librgw-rgw_rest_replica_log.o `test -f 'rgw/rgw_rest_replica_log.cc' || echo '$(srcdir)/'`rgw/rgw_rest_replica_log.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/test_build_librgw-rgw_rest_replica_log.Tpo rgw/$(DEPDIR)/test_build_librgw-rgw_rest_replica_log.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_rest_replica_log.cc' object='rgw/test_build_librgw-rgw_rest_replica_log.o' libtool=no @AMDEPBACKSLASH@
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -c -o rgw/test_build_librgw-rgw_policy_s3.obj `if test -f 'rgw/rgw_policy_s3.cc'; then $(CYGPATH_W) 'rgw/rgw_policy_s3.cc'; else $(CYGPATH_W) '$(srcdir)/rgw/rgw_policy_s3.cc'; fi`
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -c -o rgw/test_build_librgw-rgw_rest_replica_log.o `test -f 'rgw/rgw_rest_replica_log.cc' || echo '$(srcdir)/'`rgw/rgw_rest_replica_log.cc
 
-rgw/test_build_librgw-rgw_gc.o: rgw/rgw_gc.cc
- at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -MT rgw/test_build_librgw-rgw_gc.o -MD -MP -MF rgw/$(DEPDIR)/test_build_librgw-rgw_gc.Tpo -c -o rgw/test_build_librgw-rgw_gc.o `test -f 'rgw/rgw_gc.cc' || echo '$(srcdir)/'`rgw/rgw_gc.cc
- at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/test_build_librgw-rgw_gc.Tpo rgw/$(DEPDIR)/test_build_librgw-rgw_gc.Po
- at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_gc.cc' object='rgw/test_build_librgw-rgw_gc.o' libtool=no @AMDEPBACKSLASH@
+rgw/test_build_librgw-rgw_rest_replica_log.obj: rgw/rgw_rest_replica_log.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -MT rgw/test_build_librgw-rgw_rest_replica_log.obj -MD -MP -MF rgw/$(DEPDIR)/test_build_librgw-rgw_rest_replica_log.Tpo -c -o rgw/test_build_librgw-rgw_rest_replica_log.obj `if test -f 'rgw/rgw_rest_replica_log.cc'; then $(CYGPATH_W) 'rgw/rgw_rest_replica_log.cc'; else $(CYGPATH_W) '$(srcdir)/rgw/rgw_rest_replica_log.cc'; fi`
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/test_build_librgw-rgw_rest_replica_log.Tpo rgw/$(DEPDIR)/test_build_librgw-rgw_rest_replica_log.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_rest_replica_log.cc' object='rgw/test_build_librgw-rgw_rest_replica_log.obj' libtool=no @AMDEPBACKSLASH@
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -c -o rgw/test_build_librgw-rgw_gc.o `test -f 'rgw/rgw_gc.cc' || echo '$(srcdir)/'`rgw/rgw_gc.cc
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -c -o rgw/test_build_librgw-rgw_rest_replica_log.obj `if test -f 'rgw/rgw_rest_replica_log.cc'; then $(CYGPATH_W) 'rgw/rgw_rest_replica_log.cc'; else $(CYGPATH_W) '$(srcdir)/rgw/rgw_rest_replica_log.cc'; fi`
 
-rgw/test_build_librgw-rgw_gc.obj: rgw/rgw_gc.cc
- at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -MT rgw/test_build_librgw-rgw_gc.obj -MD -MP -MF rgw/$(DEPDIR)/test_build_librgw-rgw_gc.Tpo -c -o rgw/test_build_librgw-rgw_gc.obj `if test -f 'rgw/rgw_gc.cc'; then $(CYGPATH_W) 'rgw/rgw_gc.cc'; else $(CYGPATH_W) '$(srcdir)/rgw/rgw_gc.cc'; fi`
- at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/test_build_librgw-rgw_gc.Tpo rgw/$(DEPDIR)/test_build_librgw-rgw_gc.Po
- at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_gc.cc' object='rgw/test_build_librgw-rgw_gc.obj' libtool=no @AMDEPBACKSLASH@
+rgw/test_build_librgw-rgw_rest_s3.o: rgw/rgw_rest_s3.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -MT rgw/test_build_librgw-rgw_rest_s3.o -MD -MP -MF rgw/$(DEPDIR)/test_build_librgw-rgw_rest_s3.Tpo -c -o rgw/test_build_librgw-rgw_rest_s3.o `test -f 'rgw/rgw_rest_s3.cc' || echo '$(srcdir)/'`rgw/rgw_rest_s3.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/test_build_librgw-rgw_rest_s3.Tpo rgw/$(DEPDIR)/test_build_librgw-rgw_rest_s3.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_rest_s3.cc' object='rgw/test_build_librgw-rgw_rest_s3.o' libtool=no @AMDEPBACKSLASH@
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -c -o rgw/test_build_librgw-rgw_gc.obj `if test -f 'rgw/rgw_gc.cc'; then $(CYGPATH_W) 'rgw/rgw_gc.cc'; else $(CYGPATH_W) '$(srcdir)/rgw/rgw_gc.cc'; fi`
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -c -o rgw/test_build_librgw-rgw_rest_s3.o `test -f 'rgw/rgw_rest_s3.cc' || echo '$(srcdir)/'`rgw/rgw_rest_s3.cc
 
-rgw/test_build_librgw-rgw_multi_del.o: rgw/rgw_multi_del.cc
- at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -MT rgw/test_build_librgw-rgw_multi_del.o -MD -MP -MF rgw/$(DEPDIR)/test_build_librgw-rgw_multi_del.Tpo -c -o rgw/test_build_librgw-rgw_multi_del.o `test -f 'rgw/rgw_multi_del.cc' || echo '$(srcdir)/'`rgw/rgw_multi_del.cc
- at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/test_build_librgw-rgw_multi_del.Tpo rgw/$(DEPDIR)/test_build_librgw-rgw_multi_del.Po
- at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_multi_del.cc' object='rgw/test_build_librgw-rgw_multi_del.o' libtool=no @AMDEPBACKSLASH@
+rgw/test_build_librgw-rgw_rest_s3.obj: rgw/rgw_rest_s3.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -MT rgw/test_build_librgw-rgw_rest_s3.obj -MD -MP -MF rgw/$(DEPDIR)/test_build_librgw-rgw_rest_s3.Tpo -c -o rgw/test_build_librgw-rgw_rest_s3.obj `if test -f 'rgw/rgw_rest_s3.cc'; then $(CYGPATH_W) 'rgw/rgw_rest_s3.cc'; else $(CYGPATH_W) '$(srcdir)/rgw/rgw_rest_s3.cc'; fi`
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/test_build_librgw-rgw_rest_s3.Tpo rgw/$(DEPDIR)/test_build_librgw-rgw_rest_s3.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_rest_s3.cc' object='rgw/test_build_librgw-rgw_rest_s3.obj' libtool=no @AMDEPBACKSLASH@
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -c -o rgw/test_build_librgw-rgw_multi_del.o `test -f 'rgw/rgw_multi_del.cc' || echo '$(srcdir)/'`rgw/rgw_multi_del.cc
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -c -o rgw/test_build_librgw-rgw_rest_s3.obj `if test -f 'rgw/rgw_rest_s3.cc'; then $(CYGPATH_W) 'rgw/rgw_rest_s3.cc'; else $(CYGPATH_W) '$(srcdir)/rgw/rgw_rest_s3.cc'; fi`
 
-rgw/test_build_librgw-rgw_multi_del.obj: rgw/rgw_multi_del.cc
- at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -MT rgw/test_build_librgw-rgw_multi_del.obj -MD -MP -MF rgw/$(DEPDIR)/test_build_librgw-rgw_multi_del.Tpo -c -o rgw/test_build_librgw-rgw_multi_del.obj `if test -f 'rgw/rgw_multi_del.cc'; then $(CYGPATH_W) 'rgw/rgw_multi_del.cc'; else $(CYGPATH_W) '$(srcdir)/rgw/rgw_multi_del.cc'; fi`
- at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/test_build_librgw-rgw_multi_del.Tpo rgw/$(DEPDIR)/test_build_librgw-rgw_multi_del.Po
- at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_multi_del.cc' object='rgw/test_build_librgw-rgw_multi_del.obj' libtool=no @AMDEPBACKSLASH@
+rgw/test_build_librgw-rgw_rest_swift.o: rgw/rgw_rest_swift.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -MT rgw/test_build_librgw-rgw_rest_swift.o -MD -MP -MF rgw/$(DEPDIR)/test_build_librgw-rgw_rest_swift.Tpo -c -o rgw/test_build_librgw-rgw_rest_swift.o `test -f 'rgw/rgw_rest_swift.cc' || echo '$(srcdir)/'`rgw/rgw_rest_swift.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/test_build_librgw-rgw_rest_swift.Tpo rgw/$(DEPDIR)/test_build_librgw-rgw_rest_swift.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_rest_swift.cc' object='rgw/test_build_librgw-rgw_rest_swift.o' libtool=no @AMDEPBACKSLASH@
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -c -o rgw/test_build_librgw-rgw_multi_del.obj `if test -f 'rgw/rgw_multi_del.cc'; then $(CYGPATH_W) 'rgw/rgw_multi_del.cc'; else $(CYGPATH_W) '$(srcdir)/rgw/rgw_multi_del.cc'; fi`
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -c -o rgw/test_build_librgw-rgw_rest_swift.o `test -f 'rgw/rgw_rest_swift.cc' || echo '$(srcdir)/'`rgw/rgw_rest_swift.cc
 
-rgw/test_build_librgw-rgw_env.o: rgw/rgw_env.cc
- at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -MT rgw/test_build_librgw-rgw_env.o -MD -MP -MF rgw/$(DEPDIR)/test_build_librgw-rgw_env.Tpo -c -o rgw/test_build_librgw-rgw_env.o `test -f 'rgw/rgw_env.cc' || echo '$(srcdir)/'`rgw/rgw_env.cc
- at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/test_build_librgw-rgw_env.Tpo rgw/$(DEPDIR)/test_build_librgw-rgw_env.Po
- at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_env.cc' object='rgw/test_build_librgw-rgw_env.o' libtool=no @AMDEPBACKSLASH@
+rgw/test_build_librgw-rgw_rest_swift.obj: rgw/rgw_rest_swift.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -MT rgw/test_build_librgw-rgw_rest_swift.obj -MD -MP -MF rgw/$(DEPDIR)/test_build_librgw-rgw_rest_swift.Tpo -c -o rgw/test_build_librgw-rgw_rest_swift.obj `if test -f 'rgw/rgw_rest_swift.cc'; then $(CYGPATH_W) 'rgw/rgw_rest_swift.cc'; else $(CYGPATH_W) '$(srcdir)/rgw/rgw_rest_swift.cc'; fi`
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/test_build_librgw-rgw_rest_swift.Tpo rgw/$(DEPDIR)/test_build_librgw-rgw_rest_swift.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_rest_swift.cc' object='rgw/test_build_librgw-rgw_rest_swift.obj' libtool=no @AMDEPBACKSLASH@
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -c -o rgw/test_build_librgw-rgw_env.o `test -f 'rgw/rgw_env.cc' || echo '$(srcdir)/'`rgw/rgw_env.cc
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -c -o rgw/test_build_librgw-rgw_rest_swift.obj `if test -f 'rgw/rgw_rest_swift.cc'; then $(CYGPATH_W) 'rgw/rgw_rest_swift.cc'; else $(CYGPATH_W) '$(srcdir)/rgw/rgw_rest_swift.cc'; fi`
 
-rgw/test_build_librgw-rgw_env.obj: rgw/rgw_env.cc
- at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -MT rgw/test_build_librgw-rgw_env.obj -MD -MP -MF rgw/$(DEPDIR)/test_build_librgw-rgw_env.Tpo -c -o rgw/test_build_librgw-rgw_env.obj `if test -f 'rgw/rgw_env.cc'; then $(CYGPATH_W) 'rgw/rgw_env.cc'; else $(CYGPATH_W) '$(srcdir)/rgw/rgw_env.cc'; fi`
- at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/test_build_librgw-rgw_env.Tpo rgw/$(DEPDIR)/test_build_librgw-rgw_env.Po
- at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_env.cc' object='rgw/test_build_librgw-rgw_env.obj' libtool=no @AMDEPBACKSLASH@
+rgw/test_build_librgw-rgw_rest_usage.o: rgw/rgw_rest_usage.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -MT rgw/test_build_librgw-rgw_rest_usage.o -MD -MP -MF rgw/$(DEPDIR)/test_build_librgw-rgw_rest_usage.Tpo -c -o rgw/test_build_librgw-rgw_rest_usage.o `test -f 'rgw/rgw_rest_usage.cc' || echo '$(srcdir)/'`rgw/rgw_rest_usage.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/test_build_librgw-rgw_rest_usage.Tpo rgw/$(DEPDIR)/test_build_librgw-rgw_rest_usage.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_rest_usage.cc' object='rgw/test_build_librgw-rgw_rest_usage.o' libtool=no @AMDEPBACKSLASH@
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -c -o rgw/test_build_librgw-rgw_env.obj `if test -f 'rgw/rgw_env.cc'; then $(CYGPATH_W) 'rgw/rgw_env.cc'; else $(CYGPATH_W) '$(srcdir)/rgw/rgw_env.cc'; fi`
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -c -o rgw/test_build_librgw-rgw_rest_usage.o `test -f 'rgw/rgw_rest_usage.cc' || echo '$(srcdir)/'`rgw/rgw_rest_usage.cc
 
-rgw/test_build_librgw-rgw_cors.o: rgw/rgw_cors.cc
- at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -MT rgw/test_build_librgw-rgw_cors.o -MD -MP -MF rgw/$(DEPDIR)/test_build_librgw-rgw_cors.Tpo -c -o rgw/test_build_librgw-rgw_cors.o `test -f 'rgw/rgw_cors.cc' || echo '$(srcdir)/'`rgw/rgw_cors.cc
- at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/test_build_librgw-rgw_cors.Tpo rgw/$(DEPDIR)/test_build_librgw-rgw_cors.Po
- at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_cors.cc' object='rgw/test_build_librgw-rgw_cors.o' libtool=no @AMDEPBACKSLASH@
+rgw/test_build_librgw-rgw_rest_usage.obj: rgw/rgw_rest_usage.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -MT rgw/test_build_librgw-rgw_rest_usage.obj -MD -MP -MF rgw/$(DEPDIR)/test_build_librgw-rgw_rest_usage.Tpo -c -o rgw/test_build_librgw-rgw_rest_usage.obj `if test -f 'rgw/rgw_rest_usage.cc'; then $(CYGPATH_W) 'rgw/rgw_rest_usage.cc'; else $(CYGPATH_W) '$(srcdir)/rgw/rgw_rest_usage.cc'; fi`
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/test_build_librgw-rgw_rest_usage.Tpo rgw/$(DEPDIR)/test_build_librgw-rgw_rest_usage.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_rest_usage.cc' object='rgw/test_build_librgw-rgw_rest_usage.obj' libtool=no @AMDEPBACKSLASH@
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -c -o rgw/test_build_librgw-rgw_cors.o `test -f 'rgw/rgw_cors.cc' || echo '$(srcdir)/'`rgw/rgw_cors.cc
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -c -o rgw/test_build_librgw-rgw_rest_usage.obj `if test -f 'rgw/rgw_rest_usage.cc'; then $(CYGPATH_W) 'rgw/rgw_rest_usage.cc'; else $(CYGPATH_W) '$(srcdir)/rgw/rgw_rest_usage.cc'; fi`
 
-rgw/test_build_librgw-rgw_cors.obj: rgw/rgw_cors.cc
- at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -MT rgw/test_build_librgw-rgw_cors.obj -MD -MP -MF rgw/$(DEPDIR)/test_build_librgw-rgw_cors.Tpo -c -o rgw/test_build_librgw-rgw_cors.obj `if test -f 'rgw/rgw_cors.cc'; then $(CYGPATH_W) 'rgw/rgw_cors.cc'; else $(CYGPATH_W) '$(srcdir)/rgw/rgw_cors.cc'; fi`
- at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/test_build_librgw-rgw_cors.Tpo rgw/$(DEPDIR)/test_build_librgw-rgw_cors.Po
- at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_cors.cc' object='rgw/test_build_librgw-rgw_cors.obj' libtool=no @AMDEPBACKSLASH@
+rgw/test_build_librgw-rgw_rest_user.o: rgw/rgw_rest_user.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -MT rgw/test_build_librgw-rgw_rest_user.o -MD -MP -MF rgw/$(DEPDIR)/test_build_librgw-rgw_rest_user.Tpo -c -o rgw/test_build_librgw-rgw_rest_user.o `test -f 'rgw/rgw_rest_user.cc' || echo '$(srcdir)/'`rgw/rgw_rest_user.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/test_build_librgw-rgw_rest_user.Tpo rgw/$(DEPDIR)/test_build_librgw-rgw_rest_user.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_rest_user.cc' object='rgw/test_build_librgw-rgw_rest_user.o' libtool=no @AMDEPBACKSLASH@
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -c -o rgw/test_build_librgw-rgw_cors.obj `if test -f 'rgw/rgw_cors.cc'; then $(CYGPATH_W) 'rgw/rgw_cors.cc'; else $(CYGPATH_W) '$(srcdir)/rgw/rgw_cors.cc'; fi`
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -c -o rgw/test_build_librgw-rgw_rest_user.o `test -f 'rgw/rgw_rest_user.cc' || echo '$(srcdir)/'`rgw/rgw_rest_user.cc
 
-rgw/test_build_librgw-rgw_cors_s3.o: rgw/rgw_cors_s3.cc
- at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -MT rgw/test_build_librgw-rgw_cors_s3.o -MD -MP -MF rgw/$(DEPDIR)/test_build_librgw-rgw_cors_s3.Tpo -c -o rgw/test_build_librgw-rgw_cors_s3.o `test -f 'rgw/rgw_cors_s3.cc' || echo '$(srcdir)/'`rgw/rgw_cors_s3.cc
- at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/test_build_librgw-rgw_cors_s3.Tpo rgw/$(DEPDIR)/test_build_librgw-rgw_cors_s3.Po
- at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_cors_s3.cc' object='rgw/test_build_librgw-rgw_cors_s3.o' libtool=no @AMDEPBACKSLASH@
+rgw/test_build_librgw-rgw_rest_user.obj: rgw/rgw_rest_user.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -MT rgw/test_build_librgw-rgw_rest_user.obj -MD -MP -MF rgw/$(DEPDIR)/test_build_librgw-rgw_rest_user.Tpo -c -o rgw/test_build_librgw-rgw_rest_user.obj `if test -f 'rgw/rgw_rest_user.cc'; then $(CYGPATH_W) 'rgw/rgw_rest_user.cc'; else $(CYGPATH_W) '$(srcdir)/rgw/rgw_rest_user.cc'; fi`
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/test_build_librgw-rgw_rest_user.Tpo rgw/$(DEPDIR)/test_build_librgw-rgw_rest_user.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_rest_user.cc' object='rgw/test_build_librgw-rgw_rest_user.obj' libtool=no @AMDEPBACKSLASH@
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -c -o rgw/test_build_librgw-rgw_cors_s3.o `test -f 'rgw/rgw_cors_s3.cc' || echo '$(srcdir)/'`rgw/rgw_cors_s3.cc
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -c -o rgw/test_build_librgw-rgw_rest_user.obj `if test -f 'rgw/rgw_rest_user.cc'; then $(CYGPATH_W) 'rgw/rgw_rest_user.cc'; else $(CYGPATH_W) '$(srcdir)/rgw/rgw_rest_user.cc'; fi`
 
-rgw/test_build_librgw-rgw_cors_s3.obj: rgw/rgw_cors_s3.cc
- at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -MT rgw/test_build_librgw-rgw_cors_s3.obj -MD -MP -MF rgw/$(DEPDIR)/test_build_librgw-rgw_cors_s3.Tpo -c -o rgw/test_build_librgw-rgw_cors_s3.obj `if test -f 'rgw/rgw_cors_s3.cc'; then $(CYGPATH_W) 'rgw/rgw_cors_s3.cc'; else $(CYGPATH_W) '$(srcdir)/rgw/rgw_cors_s3.cc'; fi`
- at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/test_build_librgw-rgw_cors_s3.Tpo rgw/$(DEPDIR)/test_build_librgw-rgw_cors_s3.Po
- at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_cors_s3.cc' object='rgw/test_build_librgw-rgw_cors_s3.obj' libtool=no @AMDEPBACKSLASH@
+rgw/test_build_librgw-rgw_swift_auth.o: rgw/rgw_swift_auth.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -MT rgw/test_build_librgw-rgw_swift_auth.o -MD -MP -MF rgw/$(DEPDIR)/test_build_librgw-rgw_swift_auth.Tpo -c -o rgw/test_build_librgw-rgw_swift_auth.o `test -f 'rgw/rgw_swift_auth.cc' || echo '$(srcdir)/'`rgw/rgw_swift_auth.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/test_build_librgw-rgw_swift_auth.Tpo rgw/$(DEPDIR)/test_build_librgw-rgw_swift_auth.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_swift_auth.cc' object='rgw/test_build_librgw-rgw_swift_auth.o' libtool=no @AMDEPBACKSLASH@
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -c -o rgw/test_build_librgw-rgw_cors_s3.obj `if test -f 'rgw/rgw_cors_s3.cc'; then $(CYGPATH_W) 'rgw/rgw_cors_s3.cc'; else $(CYGPATH_W) '$(srcdir)/rgw/rgw_cors_s3.cc'; fi`
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -c -o rgw/test_build_librgw-rgw_swift_auth.o `test -f 'rgw/rgw_swift_auth.cc' || echo '$(srcdir)/'`rgw/rgw_swift_auth.cc
 
-rgw/test_build_librgw-rgw_auth_s3.o: rgw/rgw_auth_s3.cc
- at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -MT rgw/test_build_librgw-rgw_auth_s3.o -MD -MP -MF rgw/$(DEPDIR)/test_build_librgw-rgw_auth_s3.Tpo -c -o rgw/test_build_librgw-rgw_auth_s3.o `test -f 'rgw/rgw_auth_s3.cc' || echo '$(srcdir)/'`rgw/rgw_auth_s3.cc
- at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/test_build_librgw-rgw_auth_s3.Tpo rgw/$(DEPDIR)/test_build_librgw-rgw_auth_s3.Po
- at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_auth_s3.cc' object='rgw/test_build_librgw-rgw_auth_s3.o' libtool=no @AMDEPBACKSLASH@
+rgw/test_build_librgw-rgw_swift_auth.obj: rgw/rgw_swift_auth.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -MT rgw/test_build_librgw-rgw_swift_auth.obj -MD -MP -MF rgw/$(DEPDIR)/test_build_librgw-rgw_swift_auth.Tpo -c -o rgw/test_build_librgw-rgw_swift_auth.obj `if test -f 'rgw/rgw_swift_auth.cc'; then $(CYGPATH_W) 'rgw/rgw_swift_auth.cc'; else $(CYGPATH_W) '$(srcdir)/rgw/rgw_swift_auth.cc'; fi`
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/test_build_librgw-rgw_swift_auth.Tpo rgw/$(DEPDIR)/test_build_librgw-rgw_swift_auth.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_swift_auth.cc' object='rgw/test_build_librgw-rgw_swift_auth.obj' libtool=no @AMDEPBACKSLASH@
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -c -o rgw/test_build_librgw-rgw_auth_s3.o `test -f 'rgw/rgw_auth_s3.cc' || echo '$(srcdir)/'`rgw/rgw_auth_s3.cc
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -c -o rgw/test_build_librgw-rgw_swift_auth.obj `if test -f 'rgw/rgw_swift_auth.cc'; then $(CYGPATH_W) 'rgw/rgw_swift_auth.cc'; else $(CYGPATH_W) '$(srcdir)/rgw/rgw_swift_auth.cc'; fi`
 
-rgw/test_build_librgw-rgw_auth_s3.obj: rgw/rgw_auth_s3.cc
- at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -MT rgw/test_build_librgw-rgw_auth_s3.obj -MD -MP -MF rgw/$(DEPDIR)/test_build_librgw-rgw_auth_s3.Tpo -c -o rgw/test_build_librgw-rgw_auth_s3.obj `if test -f 'rgw/rgw_auth_s3.cc'; then $(CYGPATH_W) 'rgw/rgw_auth_s3.cc'; else $(CYGPATH_W) '$(srcdir)/rgw/rgw_auth_s3.cc'; fi`
- at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/test_build_librgw-rgw_auth_s3.Tpo rgw/$(DEPDIR)/test_build_librgw-rgw_auth_s3.Po
- at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_auth_s3.cc' object='rgw/test_build_librgw-rgw_auth_s3.obj' libtool=no @AMDEPBACKSLASH@
+rgw/test_build_librgw-rgw_swift.o: rgw/rgw_swift.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -MT rgw/test_build_librgw-rgw_swift.o -MD -MP -MF rgw/$(DEPDIR)/test_build_librgw-rgw_swift.Tpo -c -o rgw/test_build_librgw-rgw_swift.o `test -f 'rgw/rgw_swift.cc' || echo '$(srcdir)/'`rgw/rgw_swift.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/test_build_librgw-rgw_swift.Tpo rgw/$(DEPDIR)/test_build_librgw-rgw_swift.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_swift.cc' object='rgw/test_build_librgw-rgw_swift.o' libtool=no @AMDEPBACKSLASH@
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -c -o rgw/test_build_librgw-rgw_auth_s3.obj `if test -f 'rgw/rgw_auth_s3.cc'; then $(CYGPATH_W) 'rgw/rgw_auth_s3.cc'; else $(CYGPATH_W) '$(srcdir)/rgw/rgw_auth_s3.cc'; fi`
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -c -o rgw/test_build_librgw-rgw_swift.o `test -f 'rgw/rgw_swift.cc' || echo '$(srcdir)/'`rgw/rgw_swift.cc
 
-rgw/test_build_librgw-rgw_metadata.o: rgw/rgw_metadata.cc
- at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -MT rgw/test_build_librgw-rgw_metadata.o -MD -MP -MF rgw/$(DEPDIR)/test_build_librgw-rgw_metadata.Tpo -c -o rgw/test_build_librgw-rgw_metadata.o `test -f 'rgw/rgw_metadata.cc' || echo '$(srcdir)/'`rgw/rgw_metadata.cc
- at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/test_build_librgw-rgw_metadata.Tpo rgw/$(DEPDIR)/test_build_librgw-rgw_metadata.Po
- at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_metadata.cc' object='rgw/test_build_librgw-rgw_metadata.o' libtool=no @AMDEPBACKSLASH@
+rgw/test_build_librgw-rgw_swift.obj: rgw/rgw_swift.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -MT rgw/test_build_librgw-rgw_swift.obj -MD -MP -MF rgw/$(DEPDIR)/test_build_librgw-rgw_swift.Tpo -c -o rgw/test_build_librgw-rgw_swift.obj `if test -f 'rgw/rgw_swift.cc'; then $(CYGPATH_W) 'rgw/rgw_swift.cc'; else $(CYGPATH_W) '$(srcdir)/rgw/rgw_swift.cc'; fi`
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/test_build_librgw-rgw_swift.Tpo rgw/$(DEPDIR)/test_build_librgw-rgw_swift.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_swift.cc' object='rgw/test_build_librgw-rgw_swift.obj' libtool=no @AMDEPBACKSLASH@
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -c -o rgw/test_build_librgw-rgw_metadata.o `test -f 'rgw/rgw_metadata.cc' || echo '$(srcdir)/'`rgw/rgw_metadata.cc
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -c -o rgw/test_build_librgw-rgw_swift.obj `if test -f 'rgw/rgw_swift.cc'; then $(CYGPATH_W) 'rgw/rgw_swift.cc'; else $(CYGPATH_W) '$(srcdir)/rgw/rgw_swift.cc'; fi`
 
-rgw/test_build_librgw-rgw_metadata.obj: rgw/rgw_metadata.cc
- at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -MT rgw/test_build_librgw-rgw_metadata.obj -MD -MP -MF rgw/$(DEPDIR)/test_build_librgw-rgw_metadata.Tpo -c -o rgw/test_build_librgw-rgw_metadata.obj `if test -f 'rgw/rgw_metadata.cc'; then $(CYGPATH_W) 'rgw/rgw_metadata.cc'; else $(CYGPATH_W) '$(srcdir)/rgw/rgw_metadata.cc'; fi`
- at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/test_build_librgw-rgw_metadata.Tpo rgw/$(DEPDIR)/test_build_librgw-rgw_metadata.Po
- at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_metadata.cc' object='rgw/test_build_librgw-rgw_metadata.obj' libtool=no @AMDEPBACKSLASH@
+rgw/test_build_librgw-rgw_usage.o: rgw/rgw_usage.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -MT rgw/test_build_librgw-rgw_usage.o -MD -MP -MF rgw/$(DEPDIR)/test_build_librgw-rgw_usage.Tpo -c -o rgw/test_build_librgw-rgw_usage.o `test -f 'rgw/rgw_usage.cc' || echo '$(srcdir)/'`rgw/rgw_usage.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/test_build_librgw-rgw_usage.Tpo rgw/$(DEPDIR)/test_build_librgw-rgw_usage.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_usage.cc' object='rgw/test_build_librgw-rgw_usage.o' libtool=no @AMDEPBACKSLASH@
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -c -o rgw/test_build_librgw-rgw_metadata.obj `if test -f 'rgw/rgw_metadata.cc'; then $(CYGPATH_W) 'rgw/rgw_metadata.cc'; else $(CYGPATH_W) '$(srcdir)/rgw/rgw_metadata.cc'; fi`
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -c -o rgw/test_build_librgw-rgw_usage.o `test -f 'rgw/rgw_usage.cc' || echo '$(srcdir)/'`rgw/rgw_usage.cc
 
-rgw/test_build_librgw-rgw_replica_log.o: rgw/rgw_replica_log.cc
- at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -MT rgw/test_build_librgw-rgw_replica_log.o -MD -MP -MF rgw/$(DEPDIR)/test_build_librgw-rgw_replica_log.Tpo -c -o rgw/test_build_librgw-rgw_replica_log.o `test -f 'rgw/rgw_replica_log.cc' || echo '$(srcdir)/'`rgw/rgw_replica_log.cc
- at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/test_build_librgw-rgw_replica_log.Tpo rgw/$(DEPDIR)/test_build_librgw-rgw_replica_log.Po
- at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_replica_log.cc' object='rgw/test_build_librgw-rgw_replica_log.o' libtool=no @AMDEPBACKSLASH@
+rgw/test_build_librgw-rgw_usage.obj: rgw/rgw_usage.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -MT rgw/test_build_librgw-rgw_usage.obj -MD -MP -MF rgw/$(DEPDIR)/test_build_librgw-rgw_usage.Tpo -c -o rgw/test_build_librgw-rgw_usage.obj `if test -f 'rgw/rgw_usage.cc'; then $(CYGPATH_W) 'rgw/rgw_usage.cc'; else $(CYGPATH_W) '$(srcdir)/rgw/rgw_usage.cc'; fi`
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/test_build_librgw-rgw_usage.Tpo rgw/$(DEPDIR)/test_build_librgw-rgw_usage.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_usage.cc' object='rgw/test_build_librgw-rgw_usage.obj' libtool=no @AMDEPBACKSLASH@
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -c -o rgw/test_build_librgw-rgw_replica_log.o `test -f 'rgw/rgw_replica_log.cc' || echo '$(srcdir)/'`rgw/rgw_replica_log.cc
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -c -o rgw/test_build_librgw-rgw_usage.obj `if test -f 'rgw/rgw_usage.cc'; then $(CYGPATH_W) 'rgw/rgw_usage.cc'; else $(CYGPATH_W) '$(srcdir)/rgw/rgw_usage.cc'; fi`
 
-rgw/test_build_librgw-rgw_replica_log.obj: rgw/rgw_replica_log.cc
- at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -MT rgw/test_build_librgw-rgw_replica_log.obj -MD -MP -MF rgw/$(DEPDIR)/test_build_librgw-rgw_replica_log.Tpo -c -o rgw/test_build_librgw-rgw_replica_log.obj `if test -f 'rgw/rgw_replica_log.cc'; then $(CYGPATH_W) 'rgw/rgw_replica_log.cc'; else $(CYGPATH_W) '$(srcdir)/rgw/rgw_replica_log.cc'; fi`
- at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/test_build_librgw-rgw_replica_log.Tpo rgw/$(DEPDIR)/test_build_librgw-rgw_replica_log.Po
- at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_replica_log.cc' object='rgw/test_build_librgw-rgw_replica_log.obj' libtool=no @AMDEPBACKSLASH@
+rgw/test_build_librgw-rgw_user.o: rgw/rgw_user.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -MT rgw/test_build_librgw-rgw_user.o -MD -MP -MF rgw/$(DEPDIR)/test_build_librgw-rgw_user.Tpo -c -o rgw/test_build_librgw-rgw_user.o `test -f 'rgw/rgw_user.cc' || echo '$(srcdir)/'`rgw/rgw_user.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/test_build_librgw-rgw_user.Tpo rgw/$(DEPDIR)/test_build_librgw-rgw_user.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_user.cc' object='rgw/test_build_librgw-rgw_user.o' libtool=no @AMDEPBACKSLASH@
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -c -o rgw/test_build_librgw-rgw_replica_log.obj `if test -f 'rgw/rgw_replica_log.cc'; then $(CYGPATH_W) 'rgw/rgw_replica_log.cc'; else $(CYGPATH_W) '$(srcdir)/rgw/rgw_replica_log.cc'; fi`
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -c -o rgw/test_build_librgw-rgw_user.o `test -f 'rgw/rgw_user.cc' || echo '$(srcdir)/'`rgw/rgw_user.cc
 
-rgw/test_build_librgw-rgw_keystone.o: rgw/rgw_keystone.cc
- at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -MT rgw/test_build_librgw-rgw_keystone.o -MD -MP -MF rgw/$(DEPDIR)/test_build_librgw-rgw_keystone.Tpo -c -o rgw/test_build_librgw-rgw_keystone.o `test -f 'rgw/rgw_keystone.cc' || echo '$(srcdir)/'`rgw/rgw_keystone.cc
- at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/test_build_librgw-rgw_keystone.Tpo rgw/$(DEPDIR)/test_build_librgw-rgw_keystone.Po
- at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_keystone.cc' object='rgw/test_build_librgw-rgw_keystone.o' libtool=no @AMDEPBACKSLASH@
+rgw/test_build_librgw-rgw_user.obj: rgw/rgw_user.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -MT rgw/test_build_librgw-rgw_user.obj -MD -MP -MF rgw/$(DEPDIR)/test_build_librgw-rgw_user.Tpo -c -o rgw/test_build_librgw-rgw_user.obj `if test -f 'rgw/rgw_user.cc'; then $(CYGPATH_W) 'rgw/rgw_user.cc'; else $(CYGPATH_W) '$(srcdir)/rgw/rgw_user.cc'; fi`
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/test_build_librgw-rgw_user.Tpo rgw/$(DEPDIR)/test_build_librgw-rgw_user.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_user.cc' object='rgw/test_build_librgw-rgw_user.obj' libtool=no @AMDEPBACKSLASH@
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -c -o rgw/test_build_librgw-rgw_keystone.o `test -f 'rgw/rgw_keystone.cc' || echo '$(srcdir)/'`rgw/rgw_keystone.cc
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -c -o rgw/test_build_librgw-rgw_user.obj `if test -f 'rgw/rgw_user.cc'; then $(CYGPATH_W) 'rgw/rgw_user.cc'; else $(CYGPATH_W) '$(srcdir)/rgw/rgw_user.cc'; fi`
 
-rgw/test_build_librgw-rgw_keystone.obj: rgw/rgw_keystone.cc
- at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -MT rgw/test_build_librgw-rgw_keystone.obj -MD -MP -MF rgw/$(DEPDIR)/test_build_librgw-rgw_keystone.Tpo -c -o rgw/test_build_librgw-rgw_keystone.obj `if test -f 'rgw/rgw_keystone.cc'; then $(CYGPATH_W) 'rgw/rgw_keystone.cc'; else $(CYGPATH_W) '$(srcdir)/rgw/rgw_keystone.cc'; fi`
- at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/test_build_librgw-rgw_keystone.Tpo rgw/$(DEPDIR)/test_build_librgw-rgw_keystone.Po
- at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_keystone.cc' object='rgw/test_build_librgw-rgw_keystone.obj' libtool=no @AMDEPBACKSLASH@
+rgw/test_build_librgw-rgw_file.o: rgw/rgw_file.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -MT rgw/test_build_librgw-rgw_file.o -MD -MP -MF rgw/$(DEPDIR)/test_build_librgw-rgw_file.Tpo -c -o rgw/test_build_librgw-rgw_file.o `test -f 'rgw/rgw_file.cc' || echo '$(srcdir)/'`rgw/rgw_file.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/test_build_librgw-rgw_file.Tpo rgw/$(DEPDIR)/test_build_librgw-rgw_file.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_file.cc' object='rgw/test_build_librgw-rgw_file.o' libtool=no @AMDEPBACKSLASH@
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -c -o rgw/test_build_librgw-rgw_keystone.obj `if test -f 'rgw/rgw_keystone.cc'; then $(CYGPATH_W) 'rgw/rgw_keystone.cc'; else $(CYGPATH_W) '$(srcdir)/rgw/rgw_keystone.cc'; fi`
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -c -o rgw/test_build_librgw-rgw_file.o `test -f 'rgw/rgw_file.cc' || echo '$(srcdir)/'`rgw/rgw_file.cc
 
-rgw/test_build_librgw-rgw_quota.o: rgw/rgw_quota.cc
- at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -MT rgw/test_build_librgw-rgw_quota.o -MD -MP -MF rgw/$(DEPDIR)/test_build_librgw-rgw_quota.Tpo -c -o rgw/test_build_librgw-rgw_quota.o `test -f 'rgw/rgw_quota.cc' || echo '$(srcdir)/'`rgw/rgw_quota.cc
- at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/test_build_librgw-rgw_quota.Tpo rgw/$(DEPDIR)/test_build_librgw-rgw_quota.Po
- at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_quota.cc' object='rgw/test_build_librgw-rgw_quota.o' libtool=no @AMDEPBACKSLASH@
+rgw/test_build_librgw-rgw_file.obj: rgw/rgw_file.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -MT rgw/test_build_librgw-rgw_file.obj -MD -MP -MF rgw/$(DEPDIR)/test_build_librgw-rgw_file.Tpo -c -o rgw/test_build_librgw-rgw_file.obj `if test -f 'rgw/rgw_file.cc'; then $(CYGPATH_W) 'rgw/rgw_file.cc'; else $(CYGPATH_W) '$(srcdir)/rgw/rgw_file.cc'; fi`
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/test_build_librgw-rgw_file.Tpo rgw/$(DEPDIR)/test_build_librgw-rgw_file.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_file.cc' object='rgw/test_build_librgw-rgw_file.obj' libtool=no @AMDEPBACKSLASH@
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -c -o rgw/test_build_librgw-rgw_quota.o `test -f 'rgw/rgw_quota.cc' || echo '$(srcdir)/'`rgw/rgw_quota.cc
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -c -o rgw/test_build_librgw-rgw_file.obj `if test -f 'rgw/rgw_file.cc'; then $(CYGPATH_W) 'rgw/rgw_file.cc'; else $(CYGPATH_W) '$(srcdir)/rgw/rgw_file.cc'; fi`
 
-rgw/test_build_librgw-rgw_quota.obj: rgw/rgw_quota.cc
- at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -MT rgw/test_build_librgw-rgw_quota.obj -MD -MP -MF rgw/$(DEPDIR)/test_build_librgw-rgw_quota.Tpo -c -o rgw/test_build_librgw-rgw_quota.obj `if test -f 'rgw/rgw_quota.cc'; then $(CYGPATH_W) 'rgw/rgw_quota.cc'; else $(CYGPATH_W) '$(srcdir)/rgw/rgw_quota.cc'; fi`
- at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/test_build_librgw-rgw_quota.Tpo rgw/$(DEPDIR)/test_build_librgw-rgw_quota.Po
- at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_quota.cc' object='rgw/test_build_librgw-rgw_quota.obj' libtool=no @AMDEPBACKSLASH@
+rgw/test_build_librgw-librgw.o: rgw/librgw.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -MT rgw/test_build_librgw-librgw.o -MD -MP -MF rgw/$(DEPDIR)/test_build_librgw-librgw.Tpo -c -o rgw/test_build_librgw-librgw.o `test -f 'rgw/librgw.cc' || echo '$(srcdir)/'`rgw/librgw.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/test_build_librgw-librgw.Tpo rgw/$(DEPDIR)/test_build_librgw-librgw.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/librgw.cc' object='rgw/test_build_librgw-librgw.o' libtool=no @AMDEPBACKSLASH@
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -c -o rgw/test_build_librgw-rgw_quota.obj `if test -f 'rgw/rgw_quota.cc'; then $(CYGPATH_W) 'rgw/rgw_quota.cc'; else $(CYGPATH_W) '$(srcdir)/rgw/rgw_quota.cc'; fi`
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -c -o rgw/test_build_librgw-librgw.o `test -f 'rgw/librgw.cc' || echo '$(srcdir)/'`rgw/librgw.cc
 
-rgw/test_build_librgw-rgw_dencoder.o: rgw/rgw_dencoder.cc
- at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -MT rgw/test_build_librgw-rgw_dencoder.o -MD -MP -MF rgw/$(DEPDIR)/test_build_librgw-rgw_dencoder.Tpo -c -o rgw/test_build_librgw-rgw_dencoder.o `test -f 'rgw/rgw_dencoder.cc' || echo '$(srcdir)/'`rgw/rgw_dencoder.cc
- at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/test_build_librgw-rgw_dencoder.Tpo rgw/$(DEPDIR)/test_build_librgw-rgw_dencoder.Po
- at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_dencoder.cc' object='rgw/test_build_librgw-rgw_dencoder.o' libtool=no @AMDEPBACKSLASH@
+rgw/test_build_librgw-librgw.obj: rgw/librgw.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -MT rgw/test_build_librgw-librgw.obj -MD -MP -MF rgw/$(DEPDIR)/test_build_librgw-librgw.Tpo -c -o rgw/test_build_librgw-librgw.obj `if test -f 'rgw/librgw.cc'; then $(CYGPATH_W) 'rgw/librgw.cc'; else $(CYGPATH_W) '$(srcdir)/rgw/librgw.cc'; fi`
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/test_build_librgw-librgw.Tpo rgw/$(DEPDIR)/test_build_librgw-librgw.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/librgw.cc' object='rgw/test_build_librgw-librgw.obj' libtool=no @AMDEPBACKSLASH@
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -c -o rgw/test_build_librgw-rgw_dencoder.o `test -f 'rgw/rgw_dencoder.cc' || echo '$(srcdir)/'`rgw/rgw_dencoder.cc
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -c -o rgw/test_build_librgw-librgw.obj `if test -f 'rgw/librgw.cc'; then $(CYGPATH_W) 'rgw/librgw.cc'; else $(CYGPATH_W) '$(srcdir)/rgw/librgw.cc'; fi`
 
-rgw/test_build_librgw-rgw_dencoder.obj: rgw/rgw_dencoder.cc
- at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -MT rgw/test_build_librgw-rgw_dencoder.obj -MD -MP -MF rgw/$(DEPDIR)/test_build_librgw-rgw_dencoder.Tpo -c -o rgw/test_build_librgw-rgw_dencoder.obj `if test -f 'rgw/rgw_dencoder.cc'; then $(CYGPATH_W) 'rgw/rgw_dencoder.cc'; else $(CYGPATH_W) '$(srcdir)/rgw/rgw_dencoder.cc'; fi`
- at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/test_build_librgw-rgw_dencoder.Tpo rgw/$(DEPDIR)/test_build_librgw-rgw_dencoder.Po
- at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_dencoder.cc' object='rgw/test_build_librgw-rgw_dencoder.obj' libtool=no @AMDEPBACKSLASH@
+rgw/test_build_librgw-rgw_xml.o: rgw/rgw_xml.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -MT rgw/test_build_librgw-rgw_xml.o -MD -MP -MF rgw/$(DEPDIR)/test_build_librgw-rgw_xml.Tpo -c -o rgw/test_build_librgw-rgw_xml.o `test -f 'rgw/rgw_xml.cc' || echo '$(srcdir)/'`rgw/rgw_xml.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/test_build_librgw-rgw_xml.Tpo rgw/$(DEPDIR)/test_build_librgw-rgw_xml.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_xml.cc' object='rgw/test_build_librgw-rgw_xml.o' libtool=no @AMDEPBACKSLASH@
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -c -o rgw/test_build_librgw-rgw_dencoder.obj `if test -f 'rgw/rgw_dencoder.cc'; then $(CYGPATH_W) 'rgw/rgw_dencoder.cc'; else $(CYGPATH_W) '$(srcdir)/rgw/rgw_dencoder.cc'; fi`
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -c -o rgw/test_build_librgw-rgw_xml.o `test -f 'rgw/rgw_xml.cc' || echo '$(srcdir)/'`rgw/rgw_xml.cc
 
-rgw/test_build_librgw-rgw_object_expirer_core.o: rgw/rgw_object_expirer_core.cc
- at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -MT rgw/test_build_librgw-rgw_object_expirer_core.o -MD -MP -MF rgw/$(DEPDIR)/test_build_librgw-rgw_object_expirer_core.Tpo -c -o rgw/test_build_librgw-rgw_object_expirer_core.o `test -f 'rgw/rgw_object_expirer_core.cc' || echo '$(srcdir)/'`rgw/rgw_object_expirer_core.cc
- at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/test_build_librgw-rgw_object_expirer_core.Tpo rgw/$(DEPDIR)/test_build_librgw-rgw_object_expirer_core.Po
- at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_object_expirer_core.cc' object='rgw/test_build_librgw-rgw_object_expirer_core.o' libtool=no @AMDEPBACKSLASH@
+rgw/test_build_librgw-rgw_xml.obj: rgw/rgw_xml.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -MT rgw/test_build_librgw-rgw_xml.obj -MD -MP -MF rgw/$(DEPDIR)/test_build_librgw-rgw_xml.Tpo -c -o rgw/test_build_librgw-rgw_xml.obj `if test -f 'rgw/rgw_xml.cc'; then $(CYGPATH_W) 'rgw/rgw_xml.cc'; else $(CYGPATH_W) '$(srcdir)/rgw/rgw_xml.cc'; fi`
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/test_build_librgw-rgw_xml.Tpo rgw/$(DEPDIR)/test_build_librgw-rgw_xml.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_xml.cc' object='rgw/test_build_librgw-rgw_xml.obj' libtool=no @AMDEPBACKSLASH@
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -c -o rgw/test_build_librgw-rgw_object_expirer_core.o `test -f 'rgw/rgw_object_expirer_core.cc' || echo '$(srcdir)/'`rgw/rgw_object_expirer_core.cc
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -c -o rgw/test_build_librgw-rgw_xml.obj `if test -f 'rgw/rgw_xml.cc'; then $(CYGPATH_W) 'rgw/rgw_xml.cc'; else $(CYGPATH_W) '$(srcdir)/rgw/rgw_xml.cc'; fi`
 
-rgw/test_build_librgw-rgw_object_expirer_core.obj: rgw/rgw_object_expirer_core.cc
- at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -MT rgw/test_build_librgw-rgw_object_expirer_core.obj -MD -MP -MF rgw/$(DEPDIR)/test_build_librgw-rgw_object_expirer_core.Tpo -c -o rgw/test_build_librgw-rgw_object_expirer_core.obj `if test -f 'rgw/rgw_object_expirer_core.cc'; then $(CYGPATH_W) 'rgw/rgw_object_expirer_core.cc'; else $(CYGPATH_W) '$(srcdir)/rgw/rgw_object_expirer_core.cc'; fi`
- at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/test_build_librgw-rgw_object_expirer_core.Tpo rgw/$(DEPDIR)/test_build_librgw-rgw_object_expirer_core.Po
- at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_object_expirer_core.cc' object='rgw/test_build_librgw-rgw_object_expirer_core.obj' libtool=no @AMDEPBACKSLASH@
+rgw/test_build_librgw-rgw_xml_enc.o: rgw/rgw_xml_enc.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -MT rgw/test_build_librgw-rgw_xml_enc.o -MD -MP -MF rgw/$(DEPDIR)/test_build_librgw-rgw_xml_enc.Tpo -c -o rgw/test_build_librgw-rgw_xml_enc.o `test -f 'rgw/rgw_xml_enc.cc' || echo '$(srcdir)/'`rgw/rgw_xml_enc.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/test_build_librgw-rgw_xml_enc.Tpo rgw/$(DEPDIR)/test_build_librgw-rgw_xml_enc.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_xml_enc.cc' object='rgw/test_build_librgw-rgw_xml_enc.o' libtool=no @AMDEPBACKSLASH@
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -c -o rgw/test_build_librgw-rgw_object_expirer_core.obj `if test -f 'rgw/rgw_object_expirer_core.cc'; then $(CYGPATH_W) 'rgw/rgw_object_expirer_core.cc'; else $(CYGPATH_W) '$(srcdir)/rgw/rgw_object_expirer_core.cc'; fi`
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -c -o rgw/test_build_librgw-rgw_xml_enc.o `test -f 'rgw/rgw_xml_enc.cc' || echo '$(srcdir)/'`rgw/rgw_xml_enc.cc
+
+rgw/test_build_librgw-rgw_xml_enc.obj: rgw/rgw_xml_enc.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -MT rgw/test_build_librgw-rgw_xml_enc.obj -MD -MP -MF rgw/$(DEPDIR)/test_build_librgw-rgw_xml_enc.Tpo -c -o rgw/test_build_librgw-rgw_xml_enc.obj `if test -f 'rgw/rgw_xml_enc.cc'; then $(CYGPATH_W) 'rgw/rgw_xml_enc.cc'; else $(CYGPATH_W) '$(srcdir)/rgw/rgw_xml_enc.cc'; fi`
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/test_build_librgw-rgw_xml_enc.Tpo rgw/$(DEPDIR)/test_build_librgw-rgw_xml_enc.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_xml_enc.cc' object='rgw/test_build_librgw-rgw_xml_enc.obj' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -c -o rgw/test_build_librgw-rgw_xml_enc.obj `if test -f 'rgw/rgw_xml_enc.cc'; then $(CYGPATH_W) 'rgw/rgw_xml_enc.cc'; else $(CYGPATH_W) '$(srcdir)/rgw/rgw_xml_enc.cc'; fi`
 
 rgw/test_build_librgw-rgw_website.o: rgw/rgw_website.cc
 @am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -MT rgw/test_build_librgw-rgw_website.o -MD -MP -MF rgw/$(DEPDIR)/test_build_librgw-rgw_website.Tpo -c -o rgw/test_build_librgw-rgw_website.o `test -f 'rgw/rgw_website.cc' || echo '$(srcdir)/'`rgw/rgw_website.cc
@@ -25597,6 +27384,20 @@ rgw/test_build_librgw-rgw_website.obj: rgw/rgw_website.cc
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -c -o rgw/test_build_librgw-rgw_website.obj `if test -f 'rgw/rgw_website.cc'; then $(CYGPATH_W) 'rgw/rgw_website.cc'; else $(CYGPATH_W) '$(srcdir)/rgw/rgw_website.cc'; fi`
 
+rgw/test_build_librgw-rgw_ldap.o: rgw/rgw_ldap.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -MT rgw/test_build_librgw-rgw_ldap.o -MD -MP -MF rgw/$(DEPDIR)/test_build_librgw-rgw_ldap.Tpo -c -o rgw/test_build_librgw-rgw_ldap.o `test -f 'rgw/rgw_ldap.cc' || echo '$(srcdir)/'`rgw/rgw_ldap.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/test_build_librgw-rgw_ldap.Tpo rgw/$(DEPDIR)/test_build_librgw-rgw_ldap.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_ldap.cc' object='rgw/test_build_librgw-rgw_ldap.o' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -c -o rgw/test_build_librgw-rgw_ldap.o `test -f 'rgw/rgw_ldap.cc' || echo '$(srcdir)/'`rgw/rgw_ldap.cc
+
+rgw/test_build_librgw-rgw_ldap.obj: rgw/rgw_ldap.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -MT rgw/test_build_librgw-rgw_ldap.obj -MD -MP -MF rgw/$(DEPDIR)/test_build_librgw-rgw_ldap.Tpo -c -o rgw/test_build_librgw-rgw_ldap.obj `if test -f 'rgw/rgw_ldap.cc'; then $(CYGPATH_W) 'rgw/rgw_ldap.cc'; else $(CYGPATH_W) '$(srcdir)/rgw/rgw_ldap.cc'; fi`
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) rgw/$(DEPDIR)/test_build_librgw-rgw_ldap.Tpo rgw/$(DEPDIR)/test_build_librgw-rgw_ldap.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='rgw/rgw_ldap.cc' object='rgw/test_build_librgw-rgw_ldap.obj' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_build_librgw_CXXFLAGS) $(CXXFLAGS) -c -o rgw/test_build_librgw-rgw_ldap.obj `if test -f 'rgw/rgw_ldap.cc'; then $(CYGPATH_W) 'rgw/rgw_ldap.cc'; else $(CYGPATH_W) '$(srcdir)/rgw/rgw_ldap.cc'; fi`
+
 test/unittest_addrs-test_addrs.o: test/test_addrs.cc
 @am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(unittest_addrs_CXXFLAGS) $(CXXFLAGS) -MT test/unittest_addrs-test_addrs.o -MD -MP -MF test/$(DEPDIR)/unittest_addrs-test_addrs.Tpo -c -o test/unittest_addrs-test_addrs.o `test -f 'test/test_addrs.cc' || echo '$(srcdir)/'`test/test_addrs.cc
 @am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) test/$(DEPDIR)/unittest_addrs-test_addrs.Tpo test/$(DEPDIR)/unittest_addrs-test_addrs.Po
@@ -27683,6 +29484,118 @@ test/rbd_mirror/unittest_rbd_mirror-test_main.obj: test/rbd_mirror/test_main.cc
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(unittest_rbd_mirror_CXXFLAGS) $(CXXFLAGS) -c -o test/rbd_mirror/unittest_rbd_mirror-test_main.obj `if test -f 'test/rbd_mirror/test_main.cc'; then $(CYGPATH_W) 'test/rbd_mirror/test_main.cc'; else $(CYGPATH_W) '$(srcdir)/test/rbd_mirror/test_main.cc'; fi`
 
+test/rbd_mirror/unittest_rbd_mirror-test_mock_fixture.o: test/rbd_mirror/test_mock_fixture.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(unittest_rbd_mirror_CXXFLAGS) $(CXXFLAGS) -MT test/rbd_mirror/unittest_rbd_mirror-test_mock_fixture.o -MD -MP -MF test/rbd_mirror/$(DEPDIR)/unittest_rbd_mirror-test_mock_fixture.Tpo -c -o test/rbd_mirror/unittest_rbd_mirror-test_mock_fixture.o `test -f 'test/rbd_mirror/test_mock_fixture.cc' || echo '$(srcdir)/'`test/rbd_mirror/test_mock_fixture.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) test/rbd_mirror/$(DEPDIR)/unittest_rbd_mirror-test_mock_fixture.Tpo test/rbd_mirror/$(DEPDIR)/unittest_rbd_mirror-test_mock_fixture.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='test/rbd_mirror/test_mock_fixture.cc' object='test/rbd_mirror/unittest_rbd_mirror-test_mock_fixture.o' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(unittest_rbd_mirror_CXXFLAGS) $(CXXFLAGS) -c -o test/rbd_mirror/unittest_rbd_mirror-test_mock_fixture.o `test -f 'test/rbd_mirror/test_mock_fixture.cc' || echo '$(srcdir)/'`test/rbd_mirror/test_mock_fixture.cc
+
+test/rbd_mirror/unittest_rbd_mirror-test_mock_fixture.obj: test/rbd_mirror/test_mock_fixture.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(unittest_rbd_mirror_CXXFLAGS) $(CXXFLAGS) -MT test/rbd_mirror/unittest_rbd_mirror-test_mock_fixture.obj -MD -MP -MF test/rbd_mirror/$(DEPDIR)/unittest_rbd_mirror-test_mock_fixture.Tpo -c -o test/rbd_mirror/unittest_rbd_mirror-test_mock_fixture.obj `if test -f 'test/rbd_mirror/test_mock_fixture.cc'; then $(CYGPATH_W) 'test/rbd_mirror/test_mock_fixture.cc'; else $(CYGPATH_W) '$(srcd [...]
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) test/rbd_mirror/$(DEPDIR)/unittest_rbd_mirror-test_mock_fixture.Tpo test/rbd_mirror/$(DEPDIR)/unittest_rbd_mirror-test_mock_fixture.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='test/rbd_mirror/test_mock_fixture.cc' object='test/rbd_mirror/unittest_rbd_mirror-test_mock_fixture.obj' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(unittest_rbd_mirror_CXXFLAGS) $(CXXFLAGS) -c -o test/rbd_mirror/unittest_rbd_mirror-test_mock_fixture.obj `if test -f 'test/rbd_mirror/test_mock_fixture.cc'; then $(CYGPATH_W) 'test/rbd_mirror/test_mock_fixture.cc'; else $(CYGPATH_W) '$(srcdir)/test/rbd_mirror/test_mock_fixture.cc'; fi`
+
+test/rbd_mirror/unittest_rbd_mirror-test_mock_ImageSync.o: test/rbd_mirror/test_mock_ImageSync.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(unittest_rbd_mirror_CXXFLAGS) $(CXXFLAGS) -MT test/rbd_mirror/unittest_rbd_mirror-test_mock_ImageSync.o -MD -MP -MF test/rbd_mirror/$(DEPDIR)/unittest_rbd_mirror-test_mock_ImageSync.Tpo -c -o test/rbd_mirror/unittest_rbd_mirror-test_mock_ImageSync.o `test -f 'test/rbd_mirror/test_mock_ImageSync.cc' || echo '$(srcdir)/'`test/rbd_mirror/test_mock_ImageSync.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) test/rbd_mirror/$(DEPDIR)/unittest_rbd_mirror-test_mock_ImageSync.Tpo test/rbd_mirror/$(DEPDIR)/unittest_rbd_mirror-test_mock_ImageSync.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='test/rbd_mirror/test_mock_ImageSync.cc' object='test/rbd_mirror/unittest_rbd_mirror-test_mock_ImageSync.o' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(unittest_rbd_mirror_CXXFLAGS) $(CXXFLAGS) -c -o test/rbd_mirror/unittest_rbd_mirror-test_mock_ImageSync.o `test -f 'test/rbd_mirror/test_mock_ImageSync.cc' || echo '$(srcdir)/'`test/rbd_mirror/test_mock_ImageSync.cc
+
+test/rbd_mirror/unittest_rbd_mirror-test_mock_ImageSync.obj: test/rbd_mirror/test_mock_ImageSync.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(unittest_rbd_mirror_CXXFLAGS) $(CXXFLAGS) -MT test/rbd_mirror/unittest_rbd_mirror-test_mock_ImageSync.obj -MD -MP -MF test/rbd_mirror/$(DEPDIR)/unittest_rbd_mirror-test_mock_ImageSync.Tpo -c -o test/rbd_mirror/unittest_rbd_mirror-test_mock_ImageSync.obj `if test -f 'test/rbd_mirror/test_mock_ImageSync.cc'; then $(CYGPATH_W) 'test/rbd_mirror/test_mock_ImageSync.cc'; else $(CYGPATH_ [...]
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) test/rbd_mirror/$(DEPDIR)/unittest_rbd_mirror-test_mock_ImageSync.Tpo test/rbd_mirror/$(DEPDIR)/unittest_rbd_mirror-test_mock_ImageSync.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='test/rbd_mirror/test_mock_ImageSync.cc' object='test/rbd_mirror/unittest_rbd_mirror-test_mock_ImageSync.obj' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(unittest_rbd_mirror_CXXFLAGS) $(CXXFLAGS) -c -o test/rbd_mirror/unittest_rbd_mirror-test_mock_ImageSync.obj `if test -f 'test/rbd_mirror/test_mock_ImageSync.cc'; then $(CYGPATH_W) 'test/rbd_mirror/test_mock_ImageSync.cc'; else $(CYGPATH_W) '$(srcdir)/test/rbd_mirror/test_mock_ImageSync.cc'; fi`
+
+test/rbd_mirror/image_sync/unittest_rbd_mirror-test_mock_ImageCopyRequest.o: test/rbd_mirror/image_sync/test_mock_ImageCopyRequest.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(unittest_rbd_mirror_CXXFLAGS) $(CXXFLAGS) -MT test/rbd_mirror/image_sync/unittest_rbd_mirror-test_mock_ImageCopyRequest.o -MD -MP -MF test/rbd_mirror/image_sync/$(DEPDIR)/unittest_rbd_mirror-test_mock_ImageCopyRequest.Tpo -c -o test/rbd_mirror/image_sync/unittest_rbd_mirror-test_mock_ImageCopyRequest.o `test -f 'test/rbd_mirror/image_sync/test_mock_ImageCopyRequest.cc' || echo '$( [...]
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) test/rbd_mirror/image_sync/$(DEPDIR)/unittest_rbd_mirror-test_mock_ImageCopyRequest.Tpo test/rbd_mirror/image_sync/$(DEPDIR)/unittest_rbd_mirror-test_mock_ImageCopyRequest.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='test/rbd_mirror/image_sync/test_mock_ImageCopyRequest.cc' object='test/rbd_mirror/image_sync/unittest_rbd_mirror-test_mock_ImageCopyRequest.o' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(unittest_rbd_mirror_CXXFLAGS) $(CXXFLAGS) -c -o test/rbd_mirror/image_sync/unittest_rbd_mirror-test_mock_ImageCopyRequest.o `test -f 'test/rbd_mirror/image_sync/test_mock_ImageCopyRequest.cc' || echo '$(srcdir)/'`test/rbd_mirror/image_sync/test_mock_ImageCopyRequest.cc
+
+test/rbd_mirror/image_sync/unittest_rbd_mirror-test_mock_ImageCopyRequest.obj: test/rbd_mirror/image_sync/test_mock_ImageCopyRequest.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(unittest_rbd_mirror_CXXFLAGS) $(CXXFLAGS) -MT test/rbd_mirror/image_sync/unittest_rbd_mirror-test_mock_ImageCopyRequest.obj -MD -MP -MF test/rbd_mirror/image_sync/$(DEPDIR)/unittest_rbd_mirror-test_mock_ImageCopyRequest.Tpo -c -o test/rbd_mirror/image_sync/unittest_rbd_mirror-test_mock_ImageCopyRequest.obj `if test -f 'test/rbd_mirror/image_sync/test_mock_ImageCopyRequest.cc'; the [...]
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) test/rbd_mirror/image_sync/$(DEPDIR)/unittest_rbd_mirror-test_mock_ImageCopyRequest.Tpo test/rbd_mirror/image_sync/$(DEPDIR)/unittest_rbd_mirror-test_mock_ImageCopyRequest.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='test/rbd_mirror/image_sync/test_mock_ImageCopyRequest.cc' object='test/rbd_mirror/image_sync/unittest_rbd_mirror-test_mock_ImageCopyRequest.obj' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(unittest_rbd_mirror_CXXFLAGS) $(CXXFLAGS) -c -o test/rbd_mirror/image_sync/unittest_rbd_mirror-test_mock_ImageCopyRequest.obj `if test -f 'test/rbd_mirror/image_sync/test_mock_ImageCopyRequest.cc'; then $(CYGPATH_W) 'test/rbd_mirror/image_sync/test_mock_ImageCopyRequest.cc'; else $(CYGPATH_W) '$(srcdir)/test/rbd_mirror/image_sync/test_mock_ImageCopyRequest.cc'; fi`
+
+test/rbd_mirror/image_sync/unittest_rbd_mirror-test_mock_ObjectCopyRequest.o: test/rbd_mirror/image_sync/test_mock_ObjectCopyRequest.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(unittest_rbd_mirror_CXXFLAGS) $(CXXFLAGS) -MT test/rbd_mirror/image_sync/unittest_rbd_mirror-test_mock_ObjectCopyRequest.o -MD -MP -MF test/rbd_mirror/image_sync/$(DEPDIR)/unittest_rbd_mirror-test_mock_ObjectCopyRequest.Tpo -c -o test/rbd_mirror/image_sync/unittest_rbd_mirror-test_mock_ObjectCopyRequest.o `test -f 'test/rbd_mirror/image_sync/test_mock_ObjectCopyRequest.cc' || echo [...]
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) test/rbd_mirror/image_sync/$(DEPDIR)/unittest_rbd_mirror-test_mock_ObjectCopyRequest.Tpo test/rbd_mirror/image_sync/$(DEPDIR)/unittest_rbd_mirror-test_mock_ObjectCopyRequest.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='test/rbd_mirror/image_sync/test_mock_ObjectCopyRequest.cc' object='test/rbd_mirror/image_sync/unittest_rbd_mirror-test_mock_ObjectCopyRequest.o' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(unittest_rbd_mirror_CXXFLAGS) $(CXXFLAGS) -c -o test/rbd_mirror/image_sync/unittest_rbd_mirror-test_mock_ObjectCopyRequest.o `test -f 'test/rbd_mirror/image_sync/test_mock_ObjectCopyRequest.cc' || echo '$(srcdir)/'`test/rbd_mirror/image_sync/test_mock_ObjectCopyRequest.cc
+
+test/rbd_mirror/image_sync/unittest_rbd_mirror-test_mock_ObjectCopyRequest.obj: test/rbd_mirror/image_sync/test_mock_ObjectCopyRequest.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(unittest_rbd_mirror_CXXFLAGS) $(CXXFLAGS) -MT test/rbd_mirror/image_sync/unittest_rbd_mirror-test_mock_ObjectCopyRequest.obj -MD -MP -MF test/rbd_mirror/image_sync/$(DEPDIR)/unittest_rbd_mirror-test_mock_ObjectCopyRequest.Tpo -c -o test/rbd_mirror/image_sync/unittest_rbd_mirror-test_mock_ObjectCopyRequest.obj `if test -f 'test/rbd_mirror/image_sync/test_mock_ObjectCopyRequest.cc'; [...]
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) test/rbd_mirror/image_sync/$(DEPDIR)/unittest_rbd_mirror-test_mock_ObjectCopyRequest.Tpo test/rbd_mirror/image_sync/$(DEPDIR)/unittest_rbd_mirror-test_mock_ObjectCopyRequest.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='test/rbd_mirror/image_sync/test_mock_ObjectCopyRequest.cc' object='test/rbd_mirror/image_sync/unittest_rbd_mirror-test_mock_ObjectCopyRequest.obj' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(unittest_rbd_mirror_CXXFLAGS) $(CXXFLAGS) -c -o test/rbd_mirror/image_sync/unittest_rbd_mirror-test_mock_ObjectCopyRequest.obj `if test -f 'test/rbd_mirror/image_sync/test_mock_ObjectCopyRequest.cc'; then $(CYGPATH_W) 'test/rbd_mirror/image_sync/test_mock_ObjectCopyRequest.cc'; else $(CYGPATH_W) '$(srcdir)/test/rbd_mirror/image_sync/test_mock_ObjectCopyRequest.cc'; fi`
+
+test/rbd_mirror/image_sync/unittest_rbd_mirror-test_mock_SnapshotCopyRequest.o: test/rbd_mirror/image_sync/test_mock_SnapshotCopyRequest.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(unittest_rbd_mirror_CXXFLAGS) $(CXXFLAGS) -MT test/rbd_mirror/image_sync/unittest_rbd_mirror-test_mock_SnapshotCopyRequest.o -MD -MP -MF test/rbd_mirror/image_sync/$(DEPDIR)/unittest_rbd_mirror-test_mock_SnapshotCopyRequest.Tpo -c -o test/rbd_mirror/image_sync/unittest_rbd_mirror-test_mock_SnapshotCopyRequest.o `test -f 'test/rbd_mirror/image_sync/test_mock_SnapshotCopyRequest.cc' [...]
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) test/rbd_mirror/image_sync/$(DEPDIR)/unittest_rbd_mirror-test_mock_SnapshotCopyRequest.Tpo test/rbd_mirror/image_sync/$(DEPDIR)/unittest_rbd_mirror-test_mock_SnapshotCopyRequest.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='test/rbd_mirror/image_sync/test_mock_SnapshotCopyRequest.cc' object='test/rbd_mirror/image_sync/unittest_rbd_mirror-test_mock_SnapshotCopyRequest.o' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(unittest_rbd_mirror_CXXFLAGS) $(CXXFLAGS) -c -o test/rbd_mirror/image_sync/unittest_rbd_mirror-test_mock_SnapshotCopyRequest.o `test -f 'test/rbd_mirror/image_sync/test_mock_SnapshotCopyRequest.cc' || echo '$(srcdir)/'`test/rbd_mirror/image_sync/test_mock_SnapshotCopyRequest.cc
+
+test/rbd_mirror/image_sync/unittest_rbd_mirror-test_mock_SnapshotCopyRequest.obj: test/rbd_mirror/image_sync/test_mock_SnapshotCopyRequest.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(unittest_rbd_mirror_CXXFLAGS) $(CXXFLAGS) -MT test/rbd_mirror/image_sync/unittest_rbd_mirror-test_mock_SnapshotCopyRequest.obj -MD -MP -MF test/rbd_mirror/image_sync/$(DEPDIR)/unittest_rbd_mirror-test_mock_SnapshotCopyRequest.Tpo -c -o test/rbd_mirror/image_sync/unittest_rbd_mirror-test_mock_SnapshotCopyRequest.obj `if test -f 'test/rbd_mirror/image_sync/test_mock_SnapshotCopyRequ [...]
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) test/rbd_mirror/image_sync/$(DEPDIR)/unittest_rbd_mirror-test_mock_SnapshotCopyRequest.Tpo test/rbd_mirror/image_sync/$(DEPDIR)/unittest_rbd_mirror-test_mock_SnapshotCopyRequest.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='test/rbd_mirror/image_sync/test_mock_SnapshotCopyRequest.cc' object='test/rbd_mirror/image_sync/unittest_rbd_mirror-test_mock_SnapshotCopyRequest.obj' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(unittest_rbd_mirror_CXXFLAGS) $(CXXFLAGS) -c -o test/rbd_mirror/image_sync/unittest_rbd_mirror-test_mock_SnapshotCopyRequest.obj `if test -f 'test/rbd_mirror/image_sync/test_mock_SnapshotCopyRequest.cc'; then $(CYGPATH_W) 'test/rbd_mirror/image_sync/test_mock_SnapshotCopyRequest.cc'; else $(CYGPATH_W) '$(srcdir)/test/rbd_mirror/image_sync/test_mock_SnapshotCopyRequest. [...]
+
+test/rbd_mirror/image_sync/unittest_rbd_mirror-test_mock_SyncPointCreateRequest.o: test/rbd_mirror/image_sync/test_mock_SyncPointCreateRequest.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(unittest_rbd_mirror_CXXFLAGS) $(CXXFLAGS) -MT test/rbd_mirror/image_sync/unittest_rbd_mirror-test_mock_SyncPointCreateRequest.o -MD -MP -MF test/rbd_mirror/image_sync/$(DEPDIR)/unittest_rbd_mirror-test_mock_SyncPointCreateRequest.Tpo -c -o test/rbd_mirror/image_sync/unittest_rbd_mirror-test_mock_SyncPointCreateRequest.o `test -f 'test/rbd_mirror/image_sync/test_mock_SyncPointCreat [...]
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) test/rbd_mirror/image_sync/$(DEPDIR)/unittest_rbd_mirror-test_mock_SyncPointCreateRequest.Tpo test/rbd_mirror/image_sync/$(DEPDIR)/unittest_rbd_mirror-test_mock_SyncPointCreateRequest.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='test/rbd_mirror/image_sync/test_mock_SyncPointCreateRequest.cc' object='test/rbd_mirror/image_sync/unittest_rbd_mirror-test_mock_SyncPointCreateRequest.o' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(unittest_rbd_mirror_CXXFLAGS) $(CXXFLAGS) -c -o test/rbd_mirror/image_sync/unittest_rbd_mirror-test_mock_SyncPointCreateRequest.o `test -f 'test/rbd_mirror/image_sync/test_mock_SyncPointCreateRequest.cc' || echo '$(srcdir)/'`test/rbd_mirror/image_sync/test_mock_SyncPointCreateRequest.cc
+
+test/rbd_mirror/image_sync/unittest_rbd_mirror-test_mock_SyncPointCreateRequest.obj: test/rbd_mirror/image_sync/test_mock_SyncPointCreateRequest.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(unittest_rbd_mirror_CXXFLAGS) $(CXXFLAGS) -MT test/rbd_mirror/image_sync/unittest_rbd_mirror-test_mock_SyncPointCreateRequest.obj -MD -MP -MF test/rbd_mirror/image_sync/$(DEPDIR)/unittest_rbd_mirror-test_mock_SyncPointCreateRequest.Tpo -c -o test/rbd_mirror/image_sync/unittest_rbd_mirror-test_mock_SyncPointCreateRequest.obj `if test -f 'test/rbd_mirror/image_sync/test_mock_SyncPoi [...]
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) test/rbd_mirror/image_sync/$(DEPDIR)/unittest_rbd_mirror-test_mock_SyncPointCreateRequest.Tpo test/rbd_mirror/image_sync/$(DEPDIR)/unittest_rbd_mirror-test_mock_SyncPointCreateRequest.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='test/rbd_mirror/image_sync/test_mock_SyncPointCreateRequest.cc' object='test/rbd_mirror/image_sync/unittest_rbd_mirror-test_mock_SyncPointCreateRequest.obj' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(unittest_rbd_mirror_CXXFLAGS) $(CXXFLAGS) -c -o test/rbd_mirror/image_sync/unittest_rbd_mirror-test_mock_SyncPointCreateRequest.obj `if test -f 'test/rbd_mirror/image_sync/test_mock_SyncPointCreateRequest.cc'; then $(CYGPATH_W) 'test/rbd_mirror/image_sync/test_mock_SyncPointCreateRequest.cc'; else $(CYGPATH_W) '$(srcdir)/test/rbd_mirror/image_sync/test_mock_SyncPointCr [...]
+
+test/rbd_mirror/image_sync/unittest_rbd_mirror-test_mock_SyncPointPruneRequest.o: test/rbd_mirror/image_sync/test_mock_SyncPointPruneRequest.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(unittest_rbd_mirror_CXXFLAGS) $(CXXFLAGS) -MT test/rbd_mirror/image_sync/unittest_rbd_mirror-test_mock_SyncPointPruneRequest.o -MD -MP -MF test/rbd_mirror/image_sync/$(DEPDIR)/unittest_rbd_mirror-test_mock_SyncPointPruneRequest.Tpo -c -o test/rbd_mirror/image_sync/unittest_rbd_mirror-test_mock_SyncPointPruneRequest.o `test -f 'test/rbd_mirror/image_sync/test_mock_SyncPointPruneReq [...]
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) test/rbd_mirror/image_sync/$(DEPDIR)/unittest_rbd_mirror-test_mock_SyncPointPruneRequest.Tpo test/rbd_mirror/image_sync/$(DEPDIR)/unittest_rbd_mirror-test_mock_SyncPointPruneRequest.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='test/rbd_mirror/image_sync/test_mock_SyncPointPruneRequest.cc' object='test/rbd_mirror/image_sync/unittest_rbd_mirror-test_mock_SyncPointPruneRequest.o' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(unittest_rbd_mirror_CXXFLAGS) $(CXXFLAGS) -c -o test/rbd_mirror/image_sync/unittest_rbd_mirror-test_mock_SyncPointPruneRequest.o `test -f 'test/rbd_mirror/image_sync/test_mock_SyncPointPruneRequest.cc' || echo '$(srcdir)/'`test/rbd_mirror/image_sync/test_mock_SyncPointPruneRequest.cc
+
+test/rbd_mirror/image_sync/unittest_rbd_mirror-test_mock_SyncPointPruneRequest.obj: test/rbd_mirror/image_sync/test_mock_SyncPointPruneRequest.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(unittest_rbd_mirror_CXXFLAGS) $(CXXFLAGS) -MT test/rbd_mirror/image_sync/unittest_rbd_mirror-test_mock_SyncPointPruneRequest.obj -MD -MP -MF test/rbd_mirror/image_sync/$(DEPDIR)/unittest_rbd_mirror-test_mock_SyncPointPruneRequest.Tpo -c -o test/rbd_mirror/image_sync/unittest_rbd_mirror-test_mock_SyncPointPruneRequest.obj `if test -f 'test/rbd_mirror/image_sync/test_mock_SyncPointP [...]
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) test/rbd_mirror/image_sync/$(DEPDIR)/unittest_rbd_mirror-test_mock_SyncPointPruneRequest.Tpo test/rbd_mirror/image_sync/$(DEPDIR)/unittest_rbd_mirror-test_mock_SyncPointPruneRequest.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='test/rbd_mirror/image_sync/test_mock_SyncPointPruneRequest.cc' object='test/rbd_mirror/image_sync/unittest_rbd_mirror-test_mock_SyncPointPruneRequest.obj' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(unittest_rbd_mirror_CXXFLAGS) $(CXXFLAGS) -c -o test/rbd_mirror/image_sync/unittest_rbd_mirror-test_mock_SyncPointPruneRequest.obj `if test -f 'test/rbd_mirror/image_sync/test_mock_SyncPointPruneRequest.cc'; then $(CYGPATH_W) 'test/rbd_mirror/image_sync/test_mock_SyncPointPruneRequest.cc'; else $(CYGPATH_W) '$(srcdir)/test/rbd_mirror/image_sync/test_mock_SyncPointPrune [...]
+
+test/rbd_mirror/mock/unittest_rbd_mirror-MockJournaler.o: test/rbd_mirror/mock/MockJournaler.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(unittest_rbd_mirror_CXXFLAGS) $(CXXFLAGS) -MT test/rbd_mirror/mock/unittest_rbd_mirror-MockJournaler.o -MD -MP -MF test/rbd_mirror/mock/$(DEPDIR)/unittest_rbd_mirror-MockJournaler.Tpo -c -o test/rbd_mirror/mock/unittest_rbd_mirror-MockJournaler.o `test -f 'test/rbd_mirror/mock/MockJournaler.cc' || echo '$(srcdir)/'`test/rbd_mirror/mock/MockJournaler.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) test/rbd_mirror/mock/$(DEPDIR)/unittest_rbd_mirror-MockJournaler.Tpo test/rbd_mirror/mock/$(DEPDIR)/unittest_rbd_mirror-MockJournaler.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='test/rbd_mirror/mock/MockJournaler.cc' object='test/rbd_mirror/mock/unittest_rbd_mirror-MockJournaler.o' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(unittest_rbd_mirror_CXXFLAGS) $(CXXFLAGS) -c -o test/rbd_mirror/mock/unittest_rbd_mirror-MockJournaler.o `test -f 'test/rbd_mirror/mock/MockJournaler.cc' || echo '$(srcdir)/'`test/rbd_mirror/mock/MockJournaler.cc
+
+test/rbd_mirror/mock/unittest_rbd_mirror-MockJournaler.obj: test/rbd_mirror/mock/MockJournaler.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(unittest_rbd_mirror_CXXFLAGS) $(CXXFLAGS) -MT test/rbd_mirror/mock/unittest_rbd_mirror-MockJournaler.obj -MD -MP -MF test/rbd_mirror/mock/$(DEPDIR)/unittest_rbd_mirror-MockJournaler.Tpo -c -o test/rbd_mirror/mock/unittest_rbd_mirror-MockJournaler.obj `if test -f 'test/rbd_mirror/mock/MockJournaler.cc'; then $(CYGPATH_W) 'test/rbd_mirror/mock/MockJournaler.cc'; else $(CYGPATH_W) '$ [...]
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) test/rbd_mirror/mock/$(DEPDIR)/unittest_rbd_mirror-MockJournaler.Tpo test/rbd_mirror/mock/$(DEPDIR)/unittest_rbd_mirror-MockJournaler.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='test/rbd_mirror/mock/MockJournaler.cc' object='test/rbd_mirror/mock/unittest_rbd_mirror-MockJournaler.obj' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(unittest_rbd_mirror_CXXFLAGS) $(CXXFLAGS) -c -o test/rbd_mirror/mock/unittest_rbd_mirror-MockJournaler.obj `if test -f 'test/rbd_mirror/mock/MockJournaler.cc'; then $(CYGPATH_W) 'test/rbd_mirror/mock/MockJournaler.cc'; else $(CYGPATH_W) '$(srcdir)/test/rbd_mirror/mock/MockJournaler.cc'; fi`
+
 test/unittest_rbd_replay-test_rbd_replay.o: test/test_rbd_replay.cc
 @am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(unittest_rbd_replay_CXXFLAGS) $(CXXFLAGS) -MT test/unittest_rbd_replay-test_rbd_replay.o -MD -MP -MF test/$(DEPDIR)/unittest_rbd_replay-test_rbd_replay.Tpo -c -o test/unittest_rbd_replay-test_rbd_replay.o `test -f 'test/test_rbd_replay.cc' || echo '$(srcdir)/'`test/test_rbd_replay.cc
 @am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) test/$(DEPDIR)/unittest_rbd_replay-test_rbd_replay.Tpo test/$(DEPDIR)/unittest_rbd_replay-test_rbd_replay.Po
@@ -28317,6 +30230,7 @@ clean-libtool:
 	-rm -rf librbd/.libs librbd/_libs
 	-rm -rf librbd/exclusive_lock/.libs librbd/exclusive_lock/_libs
 	-rm -rf librbd/image/.libs librbd/image/_libs
+	-rm -rf librbd/image_watcher/.libs librbd/image_watcher/_libs
 	-rm -rf librbd/journal/.libs librbd/journal/_libs
 	-rm -rf librbd/object_map/.libs librbd/object_map/_libs
 	-rm -rf librbd/operation/.libs librbd/operation/_libs
@@ -28342,7 +30256,10 @@ clean-libtool:
 	-rm -rf test/rbd_mirror/.libs test/rbd_mirror/_libs
 	-rm -rf test/system/.libs test/system/_libs
 	-rm -rf tools/rbd_mirror/.libs tools/rbd_mirror/_libs
+	-rm -rf tools/rbd_mirror/image_replayer/.libs tools/rbd_mirror/image_replayer/_libs
+	-rm -rf tools/rbd_mirror/image_sync/.libs tools/rbd_mirror/image_sync/_libs
 	-rm -rf tracing/.libs tracing/_libs
+	-rm -rf xxHash/.libs xxHash/_libs
 install-pythonPYTHON: $(python_PYTHON)
 	@$(NORMAL_INSTALL)
 	@list='$(python_PYTHON)'; dlist=; list2=; test -n "$(pythondir)" || list=; \
@@ -28647,7 +30564,7 @@ $(TEST_SUITE_LOG): $(TEST_LOGS)
 	if test -n "$$am__remaking_logs"; then \
 	  echo "fatal: making $(TEST_SUITE_LOG): possible infinite" \
 	       "recursion detected" >&2; \
-	elif test -n "$$redo_logs"; then \
+	else \
 	  am__remaking_logs=yes $(MAKE) $(AM_MAKEFLAGS) $$redo_logs; \
 	fi; \
 	if $(am__make_dryrun); then :; else \
@@ -29549,6 +31466,13 @@ test/cephtool-test-rados.sh.log: test/cephtool-test-rados.sh
 	--log-file $$b.log --trs-file $$b.trs \
 	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
 	"$$tst" $(AM_TESTS_FD_REDIRECT)
+test/test_pool_create.sh.log: test/test_pool_create.sh
+	@p='test/test_pool_create.sh'; \
+	b='test/test_pool_create.sh'; \
+	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
 unittest_bufferlist.sh.log: unittest_bufferlist.sh
 	@p='unittest_bufferlist.sh'; \
 	b='unittest_bufferlist.sh'; \
@@ -29941,6 +31865,8 @@ distclean-generic:
 	-rm -f librbd/exclusive_lock/$(am__dirstamp)
 	-rm -f librbd/image/$(DEPDIR)/$(am__dirstamp)
 	-rm -f librbd/image/$(am__dirstamp)
+	-rm -f librbd/image_watcher/$(DEPDIR)/$(am__dirstamp)
+	-rm -f librbd/image_watcher/$(am__dirstamp)
 	-rm -f librbd/journal/$(DEPDIR)/$(am__dirstamp)
 	-rm -f librbd/journal/$(am__dirstamp)
 	-rm -f librbd/object_map/$(DEPDIR)/$(am__dirstamp)
@@ -30071,6 +31997,10 @@ distclean-generic:
 	-rm -f test/osdc/$(am__dirstamp)
 	-rm -f test/rbd_mirror/$(DEPDIR)/$(am__dirstamp)
 	-rm -f test/rbd_mirror/$(am__dirstamp)
+	-rm -f test/rbd_mirror/image_sync/$(DEPDIR)/$(am__dirstamp)
+	-rm -f test/rbd_mirror/image_sync/$(am__dirstamp)
+	-rm -f test/rbd_mirror/mock/$(DEPDIR)/$(am__dirstamp)
+	-rm -f test/rbd_mirror/mock/$(am__dirstamp)
 	-rm -f test/rgw/$(DEPDIR)/$(am__dirstamp)
 	-rm -f test/rgw/$(am__dirstamp)
 	-rm -f test/system/$(DEPDIR)/$(am__dirstamp)
@@ -30087,10 +32017,16 @@ distclean-generic:
 	-rm -f tools/rbd/action/$(am__dirstamp)
 	-rm -f tools/rbd_mirror/$(DEPDIR)/$(am__dirstamp)
 	-rm -f tools/rbd_mirror/$(am__dirstamp)
+	-rm -f tools/rbd_mirror/image_replayer/$(DEPDIR)/$(am__dirstamp)
+	-rm -f tools/rbd_mirror/image_replayer/$(am__dirstamp)
+	-rm -f tools/rbd_mirror/image_sync/$(DEPDIR)/$(am__dirstamp)
+	-rm -f tools/rbd_mirror/image_sync/$(am__dirstamp)
 	-rm -f tools/rbd_nbd/$(DEPDIR)/$(am__dirstamp)
 	-rm -f tools/rbd_nbd/$(am__dirstamp)
 	-rm -f tracing/$(DEPDIR)/$(am__dirstamp)
 	-rm -f tracing/$(am__dirstamp)
+	-rm -f xxHash/$(DEPDIR)/$(am__dirstamp)
+	-rm -f xxHash/$(am__dirstamp)
 
 maintainer-clean-generic:
 	@echo "This command is intended for maintainers to use"
@@ -30107,7 +32043,7 @@ clean-am: clean-binPROGRAMS clean-checkPROGRAMS \
 	clean-sbinPROGRAMS clean-su_sbinPROGRAMS mostlyclean-am
 
 distclean: distclean-recursive
-	-rm -rf ./$(DEPDIR) arch/$(DEPDIR) auth/$(DEPDIR) auth/cephx/$(DEPDIR) auth/none/$(DEPDIR) auth/unknown/$(DEPDIR) civetweb/src/$(DEPDIR) client/$(DEPDIR) cls/cephfs/$(DEPDIR) cls/hello/$(DEPDIR) cls/journal/$(DEPDIR) cls/lock/$(DEPDIR) cls/log/$(DEPDIR) cls/numops/$(DEPDIR) cls/rbd/$(DEPDIR) cls/refcount/$(DEPDIR) cls/replica_log/$(DEPDIR) cls/rgw/$(DEPDIR) cls/statelog/$(DEPDIR) cls/timeindex/$(DEPDIR) cls/user/$(DEPDIR) cls/version/$(DEPDIR) common/$(DEPDIR) compressor/$(DEPDIR) compr [...]
+	-rm -rf ./$(DEPDIR) arch/$(DEPDIR) auth/$(DEPDIR) auth/cephx/$(DEPDIR) auth/none/$(DEPDIR) auth/unknown/$(DEPDIR) civetweb/src/$(DEPDIR) client/$(DEPDIR) cls/cephfs/$(DEPDIR) cls/hello/$(DEPDIR) cls/journal/$(DEPDIR) cls/lock/$(DEPDIR) cls/log/$(DEPDIR) cls/numops/$(DEPDIR) cls/rbd/$(DEPDIR) cls/refcount/$(DEPDIR) cls/replica_log/$(DEPDIR) cls/rgw/$(DEPDIR) cls/statelog/$(DEPDIR) cls/timeindex/$(DEPDIR) cls/user/$(DEPDIR) cls/version/$(DEPDIR) common/$(DEPDIR) compressor/$(DEPDIR) compr [...]
 	-rm -f Makefile
 distclean-am: clean-am distclean-compile distclean-generic \
 	distclean-hdr distclean-tags
@@ -30164,7 +32100,7 @@ install-ps-am:
 installcheck-am:
 
 maintainer-clean: maintainer-clean-recursive
-	-rm -rf ./$(DEPDIR) arch/$(DEPDIR) auth/$(DEPDIR) auth/cephx/$(DEPDIR) auth/none/$(DEPDIR) auth/unknown/$(DEPDIR) civetweb/src/$(DEPDIR) client/$(DEPDIR) cls/cephfs/$(DEPDIR) cls/hello/$(DEPDIR) cls/journal/$(DEPDIR) cls/lock/$(DEPDIR) cls/log/$(DEPDIR) cls/numops/$(DEPDIR) cls/rbd/$(DEPDIR) cls/refcount/$(DEPDIR) cls/replica_log/$(DEPDIR) cls/rgw/$(DEPDIR) cls/statelog/$(DEPDIR) cls/timeindex/$(DEPDIR) cls/user/$(DEPDIR) cls/version/$(DEPDIR) common/$(DEPDIR) compressor/$(DEPDIR) compr [...]
+	-rm -rf ./$(DEPDIR) arch/$(DEPDIR) auth/$(DEPDIR) auth/cephx/$(DEPDIR) auth/none/$(DEPDIR) auth/unknown/$(DEPDIR) civetweb/src/$(DEPDIR) client/$(DEPDIR) cls/cephfs/$(DEPDIR) cls/hello/$(DEPDIR) cls/journal/$(DEPDIR) cls/lock/$(DEPDIR) cls/log/$(DEPDIR) cls/numops/$(DEPDIR) cls/rbd/$(DEPDIR) cls/refcount/$(DEPDIR) cls/replica_log/$(DEPDIR) cls/rgw/$(DEPDIR) cls/statelog/$(DEPDIR) cls/timeindex/$(DEPDIR) cls/user/$(DEPDIR) cls/version/$(DEPDIR) common/$(DEPDIR) compressor/$(DEPDIR) compr [...]
 	-rm -f Makefile
 maintainer-clean-am: distclean-am maintainer-clean-generic
 
@@ -30242,8 +32178,6 @@ uninstall-am: uninstall-bash_completionDATA uninstall-binPROGRAMS \
 	uninstall-sbinSCRIPTS uninstall-su_sbinPROGRAMS \
 	uninstall-su_sbinSCRIPTS
 
-.PRECIOUS: Makefile
-
 
 # display the output of failed check_SCRIPTS after a failed make check
 export VERBOSE = true
@@ -30262,13 +32196,15 @@ export PYTHONPATH=$(top_srcdir)/src/pybind
 
 @NO_GIT_VERSION_TRUE at export NO_VERSION="yes"
 
-ceph-detect-init-all: ceph-detect-init/virtualenv
+export CEPH_DETECT_INIT_VIRTUALENV = ${CEPH_BUILD_VIRTUALENV}ceph-detect-init-virtualenv
+
+ceph-detect-init-all: ${CEPH_DETECT_INIT_VIRTUALENV}
 
-ceph-detect-init/virtualenv:
-	cd $(srcdir)/ceph-detect-init ; ../tools/setup-virtualenv.sh ; virtualenv/bin/python setup.py develop
+${CEPH_DETECT_INIT_VIRTUALENV}:
+	cd $(srcdir)/ceph-detect-init ; ../tools/setup-virtualenv.sh ${CEPH_DETECT_INIT_VIRTUALENV} ; test -d wheelhouse && export NO_INDEX=--no-index ; ${CEPH_DETECT_INIT_VIRTUALENV}/bin/pip install $$NO_INDEX --use-wheel --find-links=file://$$(pwd)/wheelhouse -e .
 
 ceph-detect-init-clean:
-	cd $(srcdir)/ceph-detect-init ; python setup.py clean ; rm -fr wheelhouse .tox virtualenv .coverage *.egg-info
+	cd $(srcdir)/ceph-detect-init ; python setup.py clean ; rm -fr wheelhouse .tox build ${CEPH_DETECT_INIT_VIRTUALENV} .coverage *.egg-info
 
 ceph-detect-init-install-data:
 	cd $(srcdir)/ceph-detect-init ; \
@@ -30282,13 +32218,15 @@ ceph-detect-init-install-data:
 	fi ; \
 	python setup.py install $$root $$options
 
-ceph-disk-all: ceph-disk/virtualenv
+export CEPH_DISK_VIRTUALENV = ${CEPH_BUILD_VIRTUALENV}ceph-disk-virtualenv
 
-ceph-disk/virtualenv:
-	cd $(srcdir)/ceph-disk ; ../tools/setup-virtualenv.sh ; virtualenv/bin/python setup.py develop
+ceph-disk-all: ${CEPH_DISK_VIRTUALENV}
+
+${CEPH_DISK_VIRTUALENV}:
+	cd $(srcdir)/ceph-disk ; ../tools/setup-virtualenv.sh ${CEPH_DISK_VIRTUALENV} ; test -d wheelhouse && export NO_INDEX=--no-index ; ${CEPH_DISK_VIRTUALENV}/bin/pip install $$NO_INDEX --use-wheel --find-links=file://$$(pwd)/wheelhouse -e .
 
 ceph-disk-clean:
-	cd $(srcdir)/ceph-disk ; python setup.py clean ; rm -fr wheelhouse .tox virtualenv .coverage *.egg-info
+	cd $(srcdir)/ceph-disk ; python setup.py clean ; rm -fr wheelhouse .tox build ${CEPH_DISK_VIRTUALENV} .coverage *.egg-info
 
 ceph-disk-install-data:
 	cd $(srcdir)/ceph-disk ; \
@@ -30308,12 +32246,8 @@ ceph-disk-install-data:
 #	$(srcdir)/crush/crush.h \
 #	$(srcdir)/crush/mapper.h \
 #	$(srcdir)/crush/types.h
-
-# build rocksdb with its own makefile
-# for some stupid reason this needs -fPIC...
-# PORTABLE=1 fixes the aarch64 build (-march=native doesn't work there)
 @ENABLE_SERVER_TRUE@@WITH_SLIBROCKSDB_TRUE at rocksdb/librocksdb.a:
- at ENABLE_SERVER_TRUE@@WITH_SLIBROCKSDB_TRUE@	cd rocksdb && EXTRA_CXXFLAGS=-fPIC PORTABLE=1 make -j$(shell nproc) static_lib
+ at ENABLE_SERVER_TRUE@@WITH_SLIBROCKSDB_TRUE@	cd rocksdb && CC="${CC}" CXX="${CXX}" EXTRA_CXXFLAGS=-fPIC PORTABLE=1 $(MAKE) -j$(shell ${NPROC}) static_lib
 @ENABLE_SERVER_TRUE@@WITH_SPDK_TRUE@${SPDK_SRCDIR}/nvme/libspdk_nvme.a:
 @ENABLE_SERVER_TRUE@@WITH_SPDK_TRUE@	$(MAKE) -C ${SPDK_SRCDIR}/nvme DPDK_INC=${LIBDPDK_CFLAGS}
 @ENABLE_SERVER_TRUE@@WITH_SPDK_TRUE@${SPDK_SRCDIR}/memory/libspdk_memory.a:
@@ -30357,23 +32291,66 @@ common/PluginRegistry.cc: ./ceph_ver.h
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE at test/erasure-code/TestShecPluginGeneric.cc: ./ceph_ver.h
 @ENABLE_SERVER_TRUE@@WITH_OSD_TRUE at test/compressor/compressor_plugin_example.cc: ./ceph_ver.h
 
+# 
+# test_rgw_token_SOURCES = test/test_rgw_token.cc
+# test_rgw_token_CXXFLAGS = $(UNITTEST_CXXFLAGS)
+# test_rgw_token_LDADD = $(UNITTEST_LDADD) \
+# 	librgw.la $(PTHREAD_LIBS) $(LIBOS) $(CEPH_GLOBAL) $(EXTRALIBS)
+# bin_DEBUGPROGRAMS += test_rgw_token
+
+# test_rgw_ldap_SOURCES = rgw/rgw_ldap.cc test/test_rgw_ldap.cc
+# test_rgw_ldap_CXXFLAGS = $(UNITTEST_CXXFLAGS)
+# test_rgw_ldap_LDADD = $(UNITTEST_LDADD) \
+# 	librados.la $(PTHREAD_LIBS) $(LIBOS) $(CEPH_GLOBAL) ${OPENLDAP_LIBS}
+# 	$(EXTRALIBS)
+# bin_DEBUGPROGRAMS += test_rgw_ldap
+
 # target to build but not run the unit tests
 unittests:: $(check_PROGRAMS)
 
 @WITH_LTTNG_TRUE at tracing/%.h: tracing/%.tp
 @WITH_LTTNG_TRUE@	$(LTTNG_GEN_TP_PROG) $< -o tracing/$*.h
 
- at ENABLE_CLIENT_TRUE@@WITH_CYTHON_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE at pybind-all: librbd.la ${srcdir}/ceph_ver.h
- at ENABLE_CLIENT_TRUE@@WITH_CYTHON_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	cd $(srcdir)/pybind; $(PY_DISTUTILS) build \
+ at ENABLE_CLIENT_TRUE@@WITH_CYTHON_TRUE@@WITH_RADOS_TRUE at rados-pybind-all: librados.la ${srcdir}/ceph_ver.h
+ at ENABLE_CLIENT_TRUE@@WITH_CYTHON_TRUE@@WITH_RADOS_TRUE@	cd $(srcdir)/pybind/rados; $(PY_DISTUTILS) build \
+ at ENABLE_CLIENT_TRUE@@WITH_CYTHON_TRUE@@WITH_RADOS_TRUE@	--build-base $(shell readlink -f $(builddir))/build \
+ at ENABLE_CLIENT_TRUE@@WITH_CYTHON_TRUE@@WITH_RADOS_TRUE@	--verbose
+
+ at ENABLE_CLIENT_TRUE@@WITH_CYTHON_TRUE@@WITH_RADOS_TRUE at rados-pybind-clean: ${srcdir}/ceph_ver.h
+ at ENABLE_CLIENT_TRUE@@WITH_CYTHON_TRUE@@WITH_RADOS_TRUE@	cd $(srcdir)/pybind/rados; $(PY_DISTUTILS) clean \
+ at ENABLE_CLIENT_TRUE@@WITH_CYTHON_TRUE@@WITH_RADOS_TRUE@	--build-base $(shell readlink -f $(builddir))/build \
+ at ENABLE_CLIENT_TRUE@@WITH_CYTHON_TRUE@@WITH_RADOS_TRUE@	--verbose
+
+ at ENABLE_CLIENT_TRUE@@WITH_CYTHON_TRUE@@WITH_RADOS_TRUE at rados-pybind-install-exec: ${srcdir}/ceph_ver.h
+ at ENABLE_CLIENT_TRUE@@WITH_CYTHON_TRUE@@WITH_RADOS_TRUE@	if test "$(DESTDIR)" ; then \
+ at ENABLE_CLIENT_TRUE@@WITH_CYTHON_TRUE@@WITH_RADOS_TRUE@		if lsb_release -si | grep --quiet 'Ubuntu\|Debian\|Devuan' ; then \
+ at ENABLE_CLIENT_TRUE@@WITH_CYTHON_TRUE@@WITH_RADOS_TRUE@			options=--install-layout=deb ; \
+ at ENABLE_CLIENT_TRUE@@WITH_CYTHON_TRUE@@WITH_RADOS_TRUE@		else \
+ at ENABLE_CLIENT_TRUE@@WITH_CYTHON_TRUE@@WITH_RADOS_TRUE@			options=--prefix=/usr ; \
+ at ENABLE_CLIENT_TRUE@@WITH_CYTHON_TRUE@@WITH_RADOS_TRUE@		fi ; \
+ at ENABLE_CLIENT_TRUE@@WITH_CYTHON_TRUE@@WITH_RADOS_TRUE@		root="--root=$(DESTDIR)" ; \
+ at ENABLE_CLIENT_TRUE@@WITH_CYTHON_TRUE@@WITH_RADOS_TRUE@	else \
+ at ENABLE_CLIENT_TRUE@@WITH_CYTHON_TRUE@@WITH_RADOS_TRUE@		options=--prefix=$(prefix) ; \
+ at ENABLE_CLIENT_TRUE@@WITH_CYTHON_TRUE@@WITH_RADOS_TRUE@	fi ; \
+ at ENABLE_CLIENT_TRUE@@WITH_CYTHON_TRUE@@WITH_RADOS_TRUE@	cd $(srcdir)/pybind/rados; $(PY_DISTUTILS) build \
+ at ENABLE_CLIENT_TRUE@@WITH_CYTHON_TRUE@@WITH_RADOS_TRUE@	--build-base $(shell readlink -f $(builddir))/build \
+ at ENABLE_CLIENT_TRUE@@WITH_CYTHON_TRUE@@WITH_RADOS_TRUE@	install \
+ at ENABLE_CLIENT_TRUE@@WITH_CYTHON_TRUE@@WITH_RADOS_TRUE@	$$options $$root \
+ at ENABLE_CLIENT_TRUE@@WITH_CYTHON_TRUE@@WITH_RADOS_TRUE@	--single-version-externally-managed \
+ at ENABLE_CLIENT_TRUE@@WITH_CYTHON_TRUE@@WITH_RADOS_TRUE@	--record /dev/null \
+ at ENABLE_CLIENT_TRUE@@WITH_CYTHON_TRUE@@WITH_RADOS_TRUE@	--verbose
+
+ at ENABLE_CLIENT_TRUE@@WITH_CYTHON_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE at rbd-pybind-all: librbd.la ${srcdir}/ceph_ver.h
+ at ENABLE_CLIENT_TRUE@@WITH_CYTHON_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	cd $(srcdir)/pybind/rbd; $(PY_DISTUTILS) build \
 @ENABLE_CLIENT_TRUE@@WITH_CYTHON_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	--build-base $(shell readlink -f $(builddir))/build \
 @ENABLE_CLIENT_TRUE@@WITH_CYTHON_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	--verbose
 
- at ENABLE_CLIENT_TRUE@@WITH_CYTHON_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE at pybind-clean: ${srcdir}/ceph_ver.h
- at ENABLE_CLIENT_TRUE@@WITH_CYTHON_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	cd $(srcdir)/pybind; $(PY_DISTUTILS) clean \
+ at ENABLE_CLIENT_TRUE@@WITH_CYTHON_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE at rbd-pybind-clean: ${srcdir}/ceph_ver.h
+ at ENABLE_CLIENT_TRUE@@WITH_CYTHON_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	cd $(srcdir)/pybind/rbd; $(PY_DISTUTILS) clean \
 @ENABLE_CLIENT_TRUE@@WITH_CYTHON_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	--build-base $(shell readlink -f $(builddir))/build \
 @ENABLE_CLIENT_TRUE@@WITH_CYTHON_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	--verbose
 
- at ENABLE_CLIENT_TRUE@@WITH_CYTHON_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE at pybind-install-exec: ${srcdir}/ceph_ver.h
+ at ENABLE_CLIENT_TRUE@@WITH_CYTHON_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE at rbd-pybind-install-exec: ${srcdir}/ceph_ver.h
 @ENABLE_CLIENT_TRUE@@WITH_CYTHON_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	if test "$(DESTDIR)" ; then \
 @ENABLE_CLIENT_TRUE@@WITH_CYTHON_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@		if lsb_release -si | grep --quiet 'Ubuntu\|Debian\|Devuan' ; then \
 @ENABLE_CLIENT_TRUE@@WITH_CYTHON_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@			options=--install-layout=deb ; \
@@ -30384,13 +32361,42 @@ unittests:: $(check_PROGRAMS)
 @ENABLE_CLIENT_TRUE@@WITH_CYTHON_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	else \
 @ENABLE_CLIENT_TRUE@@WITH_CYTHON_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@		options=--prefix=$(prefix) ; \
 @ENABLE_CLIENT_TRUE@@WITH_CYTHON_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	fi ; \
- at ENABLE_CLIENT_TRUE@@WITH_CYTHON_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	cd $(srcdir)/pybind; $(PY_DISTUTILS) build \
+ at ENABLE_CLIENT_TRUE@@WITH_CYTHON_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	cd $(srcdir)/pybind/rbd; $(PY_DISTUTILS) build \
 @ENABLE_CLIENT_TRUE@@WITH_CYTHON_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	--build-base $(shell readlink -f $(builddir))/build \
 @ENABLE_CLIENT_TRUE@@WITH_CYTHON_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	install \
 @ENABLE_CLIENT_TRUE@@WITH_CYTHON_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	$$options $$root \
 @ENABLE_CLIENT_TRUE@@WITH_CYTHON_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	--single-version-externally-managed \
 @ENABLE_CLIENT_TRUE@@WITH_CYTHON_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	--record /dev/null \
 @ENABLE_CLIENT_TRUE@@WITH_CYTHON_TRUE@@WITH_RADOS_TRUE@@WITH_RBD_TRUE@	--verbose
+
+ at ENABLE_CLIENT_TRUE@@WITH_CEPHFS_TRUE@@WITH_CYTHON_TRUE@@WITH_RADOS_TRUE at cephfs-pybind-all: libcephfs.la ${srcdir}/ceph_ver.h
+ at ENABLE_CLIENT_TRUE@@WITH_CEPHFS_TRUE@@WITH_CYTHON_TRUE@@WITH_RADOS_TRUE@	cd $(srcdir)/pybind/cephfs; $(PY_DISTUTILS) build \
+ at ENABLE_CLIENT_TRUE@@WITH_CEPHFS_TRUE@@WITH_CYTHON_TRUE@@WITH_RADOS_TRUE@	--build-base $(shell readlink -f $(builddir))/build \
+ at ENABLE_CLIENT_TRUE@@WITH_CEPHFS_TRUE@@WITH_CYTHON_TRUE@@WITH_RADOS_TRUE@	--verbose
+
+ at ENABLE_CLIENT_TRUE@@WITH_CEPHFS_TRUE@@WITH_CYTHON_TRUE@@WITH_RADOS_TRUE at cephfs-pybind-clean: ${srcdir}/ceph_ver.h
+ at ENABLE_CLIENT_TRUE@@WITH_CEPHFS_TRUE@@WITH_CYTHON_TRUE@@WITH_RADOS_TRUE@	cd $(srcdir)/pybind/cephfs; $(PY_DISTUTILS) clean \
+ at ENABLE_CLIENT_TRUE@@WITH_CEPHFS_TRUE@@WITH_CYTHON_TRUE@@WITH_RADOS_TRUE@	--build-base $(shell readlink -f $(builddir))/build \
+ at ENABLE_CLIENT_TRUE@@WITH_CEPHFS_TRUE@@WITH_CYTHON_TRUE@@WITH_RADOS_TRUE@	--verbose
+
+ at ENABLE_CLIENT_TRUE@@WITH_CEPHFS_TRUE@@WITH_CYTHON_TRUE@@WITH_RADOS_TRUE at cephfs-pybind-install-exec: ${srcdir}/ceph_ver.h
+ at ENABLE_CLIENT_TRUE@@WITH_CEPHFS_TRUE@@WITH_CYTHON_TRUE@@WITH_RADOS_TRUE@	if test "$(DESTDIR)" ; then \
+ at ENABLE_CLIENT_TRUE@@WITH_CEPHFS_TRUE@@WITH_CYTHON_TRUE@@WITH_RADOS_TRUE@		if lsb_release -si | grep --quiet 'Ubuntu\|Debian\|Devuan' ; then \
+ at ENABLE_CLIENT_TRUE@@WITH_CEPHFS_TRUE@@WITH_CYTHON_TRUE@@WITH_RADOS_TRUE@			options=--install-layout=deb ; \
+ at ENABLE_CLIENT_TRUE@@WITH_CEPHFS_TRUE@@WITH_CYTHON_TRUE@@WITH_RADOS_TRUE@		else \
+ at ENABLE_CLIENT_TRUE@@WITH_CEPHFS_TRUE@@WITH_CYTHON_TRUE@@WITH_RADOS_TRUE@			options=--prefix=/usr ; \
+ at ENABLE_CLIENT_TRUE@@WITH_CEPHFS_TRUE@@WITH_CYTHON_TRUE@@WITH_RADOS_TRUE@		fi ; \
+ at ENABLE_CLIENT_TRUE@@WITH_CEPHFS_TRUE@@WITH_CYTHON_TRUE@@WITH_RADOS_TRUE@		root="--root=$(DESTDIR)" ; \
+ at ENABLE_CLIENT_TRUE@@WITH_CEPHFS_TRUE@@WITH_CYTHON_TRUE@@WITH_RADOS_TRUE@	else \
+ at ENABLE_CLIENT_TRUE@@WITH_CEPHFS_TRUE@@WITH_CYTHON_TRUE@@WITH_RADOS_TRUE@		options=--prefix=$(prefix) ; \
+ at ENABLE_CLIENT_TRUE@@WITH_CEPHFS_TRUE@@WITH_CYTHON_TRUE@@WITH_RADOS_TRUE@	fi ; \
+ at ENABLE_CLIENT_TRUE@@WITH_CEPHFS_TRUE@@WITH_CYTHON_TRUE@@WITH_RADOS_TRUE@	cd $(srcdir)/pybind/cephfs; $(PY_DISTUTILS) build \
+ at ENABLE_CLIENT_TRUE@@WITH_CEPHFS_TRUE@@WITH_CYTHON_TRUE@@WITH_RADOS_TRUE@	--build-base $(shell readlink -f $(builddir))/build \
+ at ENABLE_CLIENT_TRUE@@WITH_CEPHFS_TRUE@@WITH_CYTHON_TRUE@@WITH_RADOS_TRUE@	install \
+ at ENABLE_CLIENT_TRUE@@WITH_CEPHFS_TRUE@@WITH_CYTHON_TRUE@@WITH_RADOS_TRUE@	$$options $$root \
+ at ENABLE_CLIENT_TRUE@@WITH_CEPHFS_TRUE@@WITH_CYTHON_TRUE@@WITH_RADOS_TRUE@	--single-version-externally-managed \
+ at ENABLE_CLIENT_TRUE@@WITH_CEPHFS_TRUE@@WITH_CYTHON_TRUE@@WITH_RADOS_TRUE@	--record /dev/null \
+ at ENABLE_CLIENT_TRUE@@WITH_CEPHFS_TRUE@@WITH_CYTHON_TRUE@@WITH_RADOS_TRUE@	--verbose
 $(shell_scripts): Makefile
 $(shell_scripts): %: %.in
 	rm -f $@ $@.tmp
diff --git a/src/acconfig.h.in b/src/acconfig.h.in
index 8a4dad2..7641adb 100644
--- a/src/acconfig.h.in
+++ b/src/acconfig.h.in
@@ -39,6 +39,9 @@
 /* yasm can also build the isa-l */
 #undef HAVE_BETTER_YASM_ELF64
 
+/* have boost::asio::coroutine */
+#undef HAVE_BOOST_ASIO_COROUTINE
+
 /* have boost::random::discrete_distribution */
 #undef HAVE_BOOST_RANDOM_DISCRETE_DISTRIBUTION
 
@@ -222,6 +225,9 @@
 /* Define to 1 if you have the <netinet/in.h> header file. */
 #undef HAVE_NETINET_IN_H
 
+/* Defined if OpenLDAP enabled */
+#undef HAVE_OPENLDAP
+
 /* Support (PCLMUL) Carry-Free Muliplication */
 #undef HAVE_PCLMUL
 
@@ -249,6 +255,9 @@
 /* Define if you have pthread_spin_init */
 #undef HAVE_PTHREAD_SPINLOCK
 
+/* Define to 1 if you have the `pwritev' function. */
+#undef HAVE_PWRITEV
+
 /* Define if you have res_nquery */
 #undef HAVE_RES_NQUERY
 
@@ -431,7 +440,8 @@
 /* Define to 1 if the system has the type `__u8'. */
 #undef HAVE___U8
 
-/* Define to the sub-directory where libtool stores uninstalled libraries. */
+/* Define to the sub-directory in which libtool stores uninstalled libraries.
+   */
 #undef LT_OBJDIR
 
 /* Defined if you do not have atomic_ops */
diff --git a/src/ceph-crush-location b/src/ceph-crush-location
index d683a7d..1f33f38 100755
--- a/src/ceph-crush-location
+++ b/src/ceph-crush-location
@@ -20,10 +20,10 @@ if [ `dirname $0` = "." ] && [ $PWD != "/usr/bin" ]; then
     LIBDIR=.
     ETCDIR=.
 else
-    BINDIR=/usr/local/bin
-    SBINDIR=/usr/local/sbin
-    LIBDIR=/usr/local/lib/ceph
-    ETCDIR=/usr/local/etc/ceph
+    BINDIR=/usr/bin
+    SBINDIR=/usr/sbin
+    LIBDIR=/usr/lib/ceph
+    ETCDIR=/etc/ceph
 fi
 
 usage_exit() {
diff --git a/src/ceph-detect-init/Makefile.am b/src/ceph-detect-init/Makefile.am
index 45196a5..0d199e7 100644
--- a/src/ceph-detect-init/Makefile.am
+++ b/src/ceph-detect-init/Makefile.am
@@ -53,13 +53,15 @@ EXTRA_DIST += \
 	ceph-detect-init/tests/test_all.py \
 	ceph-detect-init/tox.ini
 
-ceph-detect-init-all: ceph-detect-init/virtualenv
+export CEPH_DETECT_INIT_VIRTUALENV = ${CEPH_BUILD_VIRTUALENV}ceph-detect-init-virtualenv
 
-ceph-detect-init/virtualenv:
-	cd $(srcdir)/ceph-detect-init ; ../tools/setup-virtualenv.sh ; virtualenv/bin/python setup.py develop
+ceph-detect-init-all: ${CEPH_DETECT_INIT_VIRTUALENV}
+
+${CEPH_DETECT_INIT_VIRTUALENV}:
+	cd $(srcdir)/ceph-detect-init ; ../tools/setup-virtualenv.sh ${CEPH_DETECT_INIT_VIRTUALENV} ; test -d wheelhouse && export NO_INDEX=--no-index ; ${CEPH_DETECT_INIT_VIRTUALENV}/bin/pip install $$NO_INDEX --use-wheel --find-links=file://$$(pwd)/wheelhouse -e .
 
 ceph-detect-init-clean:
-	cd $(srcdir)/ceph-detect-init ; python setup.py clean ; rm -fr wheelhouse .tox virtualenv .coverage *.egg-info
+	cd $(srcdir)/ceph-detect-init ; python setup.py clean ; rm -fr wheelhouse .tox build ${CEPH_DETECT_INIT_VIRTUALENV} .coverage *.egg-info
 
 ceph-detect-init-install-data:
 	cd $(srcdir)/ceph-detect-init ; \
diff --git a/src/ceph-detect-init/ceph_detect_init/__init__.py b/src/ceph-detect-init/ceph_detect_init/__init__.py
index cc9b2c0..a2bcc7c 100644
--- a/src/ceph-detect-init/ceph_detect_init/__init__.py
+++ b/src/ceph-detect-init/ceph_detect_init/__init__.py
@@ -1,5 +1,3 @@
-#!/usr/bin/env python
-#
 # Copyright (C) 2015 <contact at redhat.com>
 #
 # Author: Alfredo Deza <adeza at redhat.com>
diff --git a/src/ceph-detect-init/ceph_detect_init/suse/__init__.py b/src/ceph-detect-init/ceph_detect_init/suse/__init__.py
index 69bf7c4..0c3753b 100644
--- a/src/ceph-detect-init/ceph_detect_init/suse/__init__.py
+++ b/src/ceph-detect-init/ceph_detect_init/suse/__init__.py
@@ -8,10 +8,6 @@ def choose_init():
 
     Returns the name of a init system (upstart, sysvinit ...).
     """
-    init_mapping = {
-        '11': 'sysvinit',   # SLE_11
-        '12': 'systemd',    # SLE_12
-        '13.1': 'systemd',  # openSUSE_13.1
-        '13.2': 'systemd',  # openSUSE_13.2
-    }
-    return init_mapping.get(release, 'sysvinit')
+    if release and int(release.split('.')[0]) >= 12:
+        return 'systemd'
+    return 'sysvinit'
diff --git a/src/ceph-detect-init/run-tox.sh b/src/ceph-detect-init/run-tox.sh
index 6a8e073..1333264 100755
--- a/src/ceph-detect-init/run-tox.sh
+++ b/src/ceph-detect-init/run-tox.sh
@@ -18,9 +18,10 @@
 #
 
 # run from the ceph-detect-init directory or from its parent
+: ${CEPH_DETECT_INIT_VIRTUALENV:=ceph-detect-init-virtualenv}
 test -d ceph-detect-init && cd ceph-detect-init
-source virtualenv/bin/activate
-tox > virtualenv/tox.out 2>&1
+source ${CEPH_DETECT_INIT_VIRTUALENV}/bin/activate
+tox > ${CEPH_DETECT_INIT_VIRTUALENV}/tox.out 2>&1
 status=$?
-grep -v InterpreterNotFound < virtualenv/tox.out
+grep -v InterpreterNotFound < ${CEPH_DETECT_INIT_VIRTUALENV}/tox.out
 exit $status
diff --git a/src/ceph-detect-init/tests/test_all.py b/src/ceph-detect-init/tests/test_all.py
index f444eeb..22cff5b 100644
--- a/src/ceph-detect-init/tests/test_all.py
+++ b/src/ceph-detect-init/tests/test_all.py
@@ -49,6 +49,14 @@ class TestCephDetectInit(testtools.TestCase):
                                  codename='wheezy'):
             self.assertEqual('sysvinit', debian.choose_init())
         with mock.patch.multiple('ceph_detect_init.debian',
+                                 distro='debian',
+                                 codename='squeeze'):
+            self.assertEqual('sysvinit', debian.choose_init())
+        with mock.patch.multiple('ceph_detect_init.debian',
+                                 distro='debian',
+                                 codename='jessie'):
+            self.assertEqual('systemd', debian.choose_init())
+        with mock.patch.multiple('ceph_detect_init.debian',
                                  distro='ubuntu',
                                  codename='trusty'):
             self.assertEqual('upstart', debian.choose_init())
@@ -56,6 +64,10 @@ class TestCephDetectInit(testtools.TestCase):
                                  distro='ubuntu',
                                  codename='vivid'):
             self.assertEqual('systemd', debian.choose_init())
+        with mock.patch.multiple('ceph_detect_init.debian',
+                                 distro='not-debian',
+                                 codename='andy'):
+            self.assertIs(None, debian.choose_init())
 
     def test_fedora(self):
         with mock.patch('ceph_detect_init.fedora.release',
diff --git a/src/ceph-disk/Makefile.am b/src/ceph-disk/Makefile.am
index a0f68de..952a486 100644
--- a/src/ceph-disk/Makefile.am
+++ b/src/ceph-disk/Makefile.am
@@ -29,13 +29,15 @@ EXTRA_DIST += \
 	ceph-disk/tests/test_main.py \
 	ceph-disk/tox.ini
 
-ceph-disk-all: ceph-disk/virtualenv
+export CEPH_DISK_VIRTUALENV = ${CEPH_BUILD_VIRTUALENV}ceph-disk-virtualenv
 
-ceph-disk/virtualenv:
-	cd $(srcdir)/ceph-disk ; ../tools/setup-virtualenv.sh ; virtualenv/bin/python setup.py develop
+ceph-disk-all: ${CEPH_DISK_VIRTUALENV}
+
+${CEPH_DISK_VIRTUALENV}:
+	cd $(srcdir)/ceph-disk ; ../tools/setup-virtualenv.sh ${CEPH_DISK_VIRTUALENV} ; test -d wheelhouse && export NO_INDEX=--no-index ; ${CEPH_DISK_VIRTUALENV}/bin/pip install $$NO_INDEX --use-wheel --find-links=file://$$(pwd)/wheelhouse -e .
 
 ceph-disk-clean:
-	cd $(srcdir)/ceph-disk ; python setup.py clean ; rm -fr wheelhouse .tox virtualenv .coverage *.egg-info
+	cd $(srcdir)/ceph-disk ; python setup.py clean ; rm -fr wheelhouse .tox build ${CEPH_DISK_VIRTUALENV} .coverage *.egg-info
 
 ceph-disk-install-data:
 	cd $(srcdir)/ceph-disk ; \
diff --git a/src/ceph-disk/ceph_disk/main.py b/src/ceph-disk/ceph_disk/main.py
index d9277b1..d0ec596 100755
--- a/src/ceph-disk/ceph_disk/main.py
+++ b/src/ceph-disk/ceph_disk/main.py
@@ -1,6 +1,6 @@
 #!/usr/bin/env python
 #
-# Copyright (C) 2015 Red Hat <contact at redhat.com>
+# Copyright (C) 2015, 2016 Red Hat <contact at redhat.com>
 # Copyright (C) 2014 Inktank <info at inktank.com>
 # Copyright (C) 2014 Cloudwatt <libre.licensing at cloudwatt.com>
 # Copyright (C) 2014 Catalyst.net Ltd
@@ -19,6 +19,7 @@
 #
 
 import argparse
+import base64
 import errno
 import fcntl
 import json
@@ -35,8 +36,13 @@ import time
 import shlex
 import pwd
 import grp
+import types
+import textwrap
 
 CEPH_OSD_ONDISK_MAGIC = 'ceph osd volume v026'
+CEPH_LOCKBOX_ONDISK_MAGIC = 'ceph lockbox volume v001'
+
+KEY_MANAGEMENT_MODE_V1 = 'ceph-mon v1'
 
 PTYPE = {
     'regular': {
@@ -54,6 +60,10 @@ PTYPE = {
             'ready': '4fbd7e29-9d25-41b8-afd0-062c0ceff05d',
             'tobe': '89c57f98-2fe5-4dc0-89c1-f3ad0ceff2be',
         },
+        'lockbox': {
+            'ready': 'fb3aabf9-d25f-47cc-bf5e-721d1816496b',
+            'tobe': 'fb3aabf9-d25f-47cc-bf5e-721d181642be',
+        },
     },
     'luks': {
         'journal': {
@@ -96,6 +106,10 @@ PTYPE = {
             'ready': '4fbd7e29-8ae0-4982-bf9d-5a8d867af560',
             'tobe': '89c57f98-8ae0-4982-bf9d-5a8d867af560',
         },
+        'lockbox': {
+            'ready': '7f4a666a-16f3-47a2-8445-152ef4d03f6c',
+            'tobe': '7f4a666a-16f3-47a2-8445-152ef4d032be',
+        },
     },
 }
 
@@ -223,6 +237,10 @@ if LOG_NAME == '__main__':
     LOG_NAME = os.path.basename(sys.argv[0])
 LOG = logging.getLogger(LOG_NAME)
 
+# Allow user-preferred values for subprocess user and group
+CEPH_PREF_USER = None
+CEPH_PREF_GROUP = None
+
 
 class filelock(object):
     def __init__(self, fn):
@@ -931,12 +949,39 @@ def get_osd_id(path):
 
 
 def get_ceph_user():
-    try:
-        pwd.getpwnam('ceph')
-        grp.getgrnam('ceph')
-        return 'ceph'
-    except KeyError:
-        return 'root'
+    global CEPH_PREF_USER
+
+    if CEPH_PREF_USER is not None:
+        try:
+            pwd.getpwnam(CEPH_PREF_USER)
+            return CEPH_PREF_USER
+        except KeyError:
+            print "No such user: " + CEPH_PREF_USER
+            sys.exit(2)
+    else:
+        try:
+            pwd.getpwnam('ceph')
+            return 'ceph'
+        except KeyError:
+            return 'root'
+
+
+def get_ceph_group():
+    global CEPH_PREF_GROUP
+
+    if CEPH_PREF_GROUP is not None:
+        try:
+            grp.getgrnam(CEPH_PREF_GROUP)
+            return CEPH_PREF_GROUP
+        except KeyError:
+            print "No such group: " + CEPH_PREF_GROUP
+            sys.exit(2)
+    else:
+        try:
+            grp.getgrnam('ceph')
+            return 'ceph'
+        except KeyError:
+            return 'root'
 
 
 def path_set_context(path):
@@ -1054,49 +1099,58 @@ def get_dmcrypt_key_path(
     return path
 
 
-def get_or_create_dmcrypt_key(
+def get_dmcrypt_key(
     _uuid,
     key_dir,
-    key_size,
     luks
 ):
-    """
-    Get path to existing dmcrypt key or create a new key file.
-
-    :return: Path to the dmcrypt key file.
-    """
-    path = get_dmcrypt_key_path(_uuid, key_dir, luks)
+    legacy_path = get_dmcrypt_key_path(_uuid, key_dir, luks)
+    if os.path.exists(legacy_path):
+        return (legacy_path,)
+    path = os.path.join(STATEDIR, 'osd-lockbox', _uuid)
     if os.path.exists(path):
-        return path
-
-    # make a new key
-    try:
-        if not os.path.exists(key_dir):
-            os.makedirs(key_dir, stat.S_IRUSR | stat.S_IWUSR | stat.S_IXUSR)
-        with file('/dev/urandom', 'rb') as i:
-            key = i.read(key_size / 8)
-            fd = os.open(path, os.O_WRONLY | os.O_CREAT,
-                         stat.S_IRUSR | stat.S_IWUSR)
-            assert os.write(fd, key) == len(key)
-            os.close(fd)
-        return path
-    except:
-        raise Error('unable to read or create dm-crypt key', path)
+        mode = get_oneliner(path, 'key-management-mode')
+        osd_uuid = get_oneliner(path, 'osd-uuid')
+        if mode == KEY_MANAGEMENT_MODE_V1:
+            key, stderr, ret = command(
+                [
+                    'ceph',
+                    '--name',
+                    'client.osd-lockbox.' + osd_uuid,
+                    '--keyring',
+                    os.path.join(path, 'keyring'),
+                    'config-key',
+                    'get',
+                    'dm-crypt/osd/' + osd_uuid + '/luks',
+                ],
+            )
+            LOG.debug("stderr " + stderr)
+            assert ret == 0
+            return base64.b64decode(key)
+        else:
+            raise Error('unknown key-management-mode ' + str(mode))
+    raise Error('unable to read dm-crypt key', path, legacy_path)
 
 
 def _dmcrypt_map(
     rawdev,
-    keypath,
+    key,
     _uuid,
     cryptsetup_parameters,
     luks,
     format_dev=False,
 ):
-    """
-    Maps a device to a dmcrypt device.
+    dev = dmcrypt_is_mapped(_uuid)
+    if dev:
+        return dev
 
-    :return: Path to the dmcrypt device.
-    """
+    if isinstance(key, types.TupleType):
+        # legacy, before lockbox
+        assert os.path.exists(key[0])
+        keypath = key[0]
+        key = None
+    else:
+        keypath = '-'
     dev = '/dev/mapper/' + _uuid
     luksFormat_args = [
         'cryptsetup',
@@ -1125,15 +1179,27 @@ def _dmcrypt_map(
         rawdev,
     ] + cryptsetup_parameters
 
+    def run(args, stdin):
+        LOG.info(" ".join(args))
+        process = subprocess.Popen(
+            args,
+            stdin=subprocess.PIPE,
+            stdout=subprocess.PIPE,
+            stderr=subprocess.PIPE)
+        out, err = process.communicate(stdin)
+        LOG.debug(out)
+        LOG.error(err)
+        assert process.returncode == 0
+
     try:
         if luks:
             if format_dev:
-                command_check_call(luksFormat_args)
-            command_check_call(luksOpen_args)
+                run(luksFormat_args, key)
+            run(luksOpen_args, key)
         else:
             # Plain mode has no format function, nor any validation
             # that the key is correct.
-            command_check_call(create_args)
+            run(create_args, key)
         # set proper ownership of mapped device
         command_check_call(['chown', 'ceph:ceph', dev])
         return dev
@@ -1145,9 +1211,8 @@ def _dmcrypt_map(
 def dmcrypt_unmap(
     _uuid
 ):
-    """
-    Removes the dmcrypt device with the given UUID.
-    """
+    if not os.path.exists('/dev/mapper/' + _uuid):
+        return
     retries = 0
     while True:
         try:
@@ -1180,10 +1245,16 @@ def mount(
     if options is None:
         options = MOUNT_OPTIONS.get(fstype, '')
 
+    myTemp = STATEDIR + '/tmp'
+    # mkdtemp expect 'dir' to be existing on the system
+    # Let's be sure it's always the case
+    if not os.path.exists(myTemp):
+        os.makedirs(myTemp)
+
     # mount
     path = tempfile.mkdtemp(
         prefix='mnt.',
-        dir=STATEDIR + '/tmp',
+        dir=myTemp,
     )
     try:
         LOG.debug('Mounting %s on %s with options %s', dev, path, options)
@@ -1455,8 +1526,14 @@ class Device(object):
         return num
 
     def ptype_tobe_for_name(self, name):
+        LOG.debug("name = " + name)
         if name == 'data':
             name = 'osd'
+        if name == 'lockbox':
+            if is_mpath(self.path):
+                return PTYPE['mpath']['lockbox']['tobe']
+            else:
+                return PTYPE['regular']['lockbox']['tobe']
         if self.ptype_map is None:
             partition = DevicePartition.factory(
                 path=self.path, dev=None, args=self.args)
@@ -1552,7 +1629,7 @@ class DevicePartitionCrypt(DevicePartition):
 
     def __init__(self, args):
         super(DevicePartitionCrypt, self).__init__(args)
-        self.osd_dm_keypath = None
+        self.osd_dm_key = None
         self.cryptsetup_parameters = CryptHelpers.get_cryptsetup_parameters(
             self.args)
         self.dmcrypt_type = CryptHelpers.get_dmcrypt_type(self.args)
@@ -1565,7 +1642,7 @@ class DevicePartitionCrypt(DevicePartition):
         self.setup_crypt()
         self.dev = _dmcrypt_map(
             rawdev=self.rawdev,
-            keypath=self.osd_dm_keypath,
+            key=self.osd_dm_key,
             _uuid=self.get_uuid(),
             cryptsetup_parameters=self.cryptsetup_parameters,
             luks=self.luks(),
@@ -1580,7 +1657,6 @@ class DevicePartitionCrypt(DevicePartition):
     def format(self):
         self.setup_crypt()
         self.map()
-        self.unmap()
 
 
 class DevicePartitionCryptPlain(DevicePartitionCrypt):
@@ -1589,14 +1665,14 @@ class DevicePartitionCryptPlain(DevicePartitionCrypt):
         return False
 
     def setup_crypt(self):
-        if self.osd_dm_keypath is not None:
+        if self.osd_dm_key is not None:
             return
 
         self.cryptsetup_parameters += ['--key-size', str(self.dmcrypt_keysize)]
 
-        self.osd_dm_keypath = get_or_create_dmcrypt_key(
+        self.osd_dm_key = get_dmcrypt_key(
             self.get_uuid(), self.args.dmcrypt_key_dir,
-            self.dmcrypt_keysize, False)
+            False)
 
     def set_variables_ptype(self):
         self.ptype_map = PTYPE['plain']
@@ -1608,7 +1684,7 @@ class DevicePartitionCryptLuks(DevicePartitionCrypt):
         return True
 
     def setup_crypt(self):
-        if self.osd_dm_keypath is not None:
+        if self.osd_dm_key is not None:
             return
 
         if self.dmcrypt_keysize == 1024:
@@ -1620,9 +1696,9 @@ class DevicePartitionCryptLuks(DevicePartitionCrypt):
             self.cryptsetup_parameters += ['--key-size',
                                            str(self.dmcrypt_keysize)]
 
-        self.osd_dm_keypath = get_or_create_dmcrypt_key(
+        self.osd_dm_key = get_dmcrypt_key(
             self.get_uuid(), self.args.dmcrypt_key_dir,
-            self.dmcrypt_keysize, True)
+            True)
 
     def set_variables_ptype(self):
         self.ptype_map = PTYPE['luks']
@@ -1667,6 +1743,7 @@ class Prepare(object):
         parents = [
             Prepare.parser(),
             PrepareData.parser(),
+            Lockbox.parser(),
         ]
         parents.extend(PrepareFilestore.parent_parsers())
         parents.extend(PrepareBluestore.parent_parsers())
@@ -1700,6 +1777,8 @@ class Prepare(object):
 class PrepareFilestore(Prepare):
 
     def __init__(self, args):
+        if args.dmcrypt:
+            self.lockbox = Lockbox(args)
         self.data = PrepareFilestoreData(args)
         self.journal = PrepareJournal(args)
 
@@ -1710,12 +1789,16 @@ class PrepareFilestore(Prepare):
         ]
 
     def prepare_locked(self):
+        if self.data.args.dmcrypt:
+            self.lockbox.prepare()
         self.data.prepare(self.journal)
 
 
 class PrepareBluestore(Prepare):
 
     def __init__(self, args):
+        if args.dmcrypt:
+            self.lockbox = Lockbox(args)
         self.data = PrepareBluestoreData(args)
         self.block = PrepareBluestoreBlock(args)
 
@@ -1737,6 +1820,8 @@ class PrepareBluestore(Prepare):
         ]
 
     def prepare_locked(self):
+        if self.data.args.dmcrypt:
+            self.lockbox.prepare()
         self.data.prepare(self.block)
 
 
@@ -1755,8 +1840,7 @@ class PrepareSpace(object):
         self.args = args
         self.set_type()
         self.space_size = self.get_space_size()
-        if (getattr(self.args, self.name) and
-                getattr(self.args, self.name + '_uuid') is None):
+        if getattr(self.args, self.name + '_uuid') is None:
             setattr(self.args, self.name + '_uuid', str(uuid.uuid4()))
         self.space_symlink = None
         self.space_dmcrypt = None
@@ -1836,7 +1920,7 @@ class PrepareSpace(object):
             name,
             metavar=name.upper(),
             nargs='?',
-            help=('path to OSD %s disk block device;' % name,
+            help=('path to OSD %s disk block device;' % name +
                   ' leave out to store %s in file' % name),
         )
         return parser
@@ -1977,6 +2061,7 @@ class PrepareSpace(object):
 
         if isinstance(partition, DevicePartitionCrypt):
             partition.format()
+            partition.map()
 
             command_check_call(
                 [
@@ -2097,7 +2182,7 @@ class CryptHelpers(object):
 
     @staticmethod
     def get_dmcrypt_type(args):
-        if args.dmcrypt:
+        if hasattr(args, 'dmcrypt') and args.dmcrypt:
             dmcrypt_type = get_conf(
                 cluster=args.cluster,
                 variable='osd_dmcrypt_type',
@@ -2114,6 +2199,167 @@ class CryptHelpers(object):
             return None
 
 
+class Lockbox(object):
+
+    def __init__(self, args):
+        self.args = args
+        self.partition = None
+        self.device = None
+
+        if hasattr(self.args, 'lockbox') and self.args.lockbox is None:
+            self.args.lockbox = self.args.data
+
+    def set_partition(self, partition):
+        self.partition = partition
+
+    @staticmethod
+    def parser():
+        parser = argparse.ArgumentParser(add_help=False)
+        parser.add_argument(
+            '--lockbox',
+            help='path to the device to store the lockbox',
+        )
+        parser.add_argument(
+            '--lockbox-uuid',
+            metavar='UUID',
+            help='unique lockbox uuid',
+        )
+        return parser
+
+    def create_partition(self):
+        self.device = Device.factory(self.args.lockbox, argparse.Namespace())
+        partition_number = 3
+        self.device.create_partition(uuid=self.args.lockbox_uuid,
+                                     name='lockbox',
+                                     num=partition_number,
+                                     size=10)  # MB
+        return self.device.get_partition(partition_number)
+
+    def set_or_create_partition(self):
+        if is_partition(self.args.lockbox):
+            LOG.debug('OSD lockbox device %s is a partition',
+                      self.args.lockbox)
+            self.partition = DevicePartition.factory(
+                path=None, dev=self.args.lockbox, args=self.args)
+            ptype = partition.get_ptype()
+            ready = Ptype.get_ready_by_type('lockbox')
+            if ptype not in ready:
+                LOG.warning('incorrect partition UUID: %s, expected %s'
+                            % (ptype, str(ready)))
+        else:
+            LOG.debug('Creating osd partition on %s',
+                      self.args.lockbox)
+            self.partition = self.create_partition()
+
+    def create_key(self):
+        key_size = CryptHelpers.get_dmcrypt_keysize(self.args)
+        key = open('/dev/urandom', 'rb').read(key_size / 8)
+        base64_key = base64.b64encode(key)
+        command_check_call(
+            [
+                'ceph',
+                'config-key',
+                'put',
+                'dm-crypt/osd/' + self.args.osd_uuid + '/luks',
+                base64_key,
+            ],
+        )
+        keyring, stderr, ret = command(
+            [
+                'ceph',
+                'auth',
+                'get-or-create',
+                'client.osd-lockbox.' + self.args.osd_uuid,
+                'mon',
+                ('allow command "config-key get" with key="dm-crypt/osd/' +
+                 self.args.osd_uuid + '/luks"'),
+            ],
+        )
+        LOG.debug("stderr " + stderr)
+        assert ret == 0
+        path = self.get_mount_point()
+        open(os.path.join(path, 'keyring'), 'w').write(keyring)
+        write_one_line(path, 'key-management-mode', KEY_MANAGEMENT_MODE_V1)
+
+    def symlink_spaces(self, path):
+        target = self.get_mount_point()
+        for name in Space.NAMES:
+            if (hasattr(self.args, name + '_uuid') and
+                    getattr(self.args, name + '_uuid')):
+                uuid = getattr(self.args, name + '_uuid')
+                symlink = os.path.join(STATEDIR, 'osd-lockbox', uuid)
+                adjust_symlink(target, symlink)
+                write_one_line(path, name + '-uuid', uuid)
+
+    def populate(self):
+        maybe_mkdir(os.path.join(STATEDIR, 'osd-lockbox'))
+        args = ['mkfs', '-t', 'ext4', self.partition.get_dev()]
+        LOG.debug('Creating lockbox fs on %s: ' + str(" ".join(args)))
+        command_check_call(args)
+        path = self.get_mount_point()
+        maybe_mkdir(path)
+        args = ['mount', '-t', 'ext4', self.partition.get_dev(), path]
+        LOG.debug('Mounting lockbox ' + str(" ".join(args)))
+        command_check_call(args)
+        write_one_line(path, 'osd-uuid', self.args.osd_uuid)
+        self.create_key()
+        self.symlink_spaces(path)
+        write_one_line(path, 'magic', CEPH_LOCKBOX_ONDISK_MAGIC)
+        if self.device is not None:
+            command_check_call(
+                [
+                    'sgdisk',
+                    '--typecode={num}:{uuid}'.format(
+                        num=self.partition.get_partition_number(),
+                        uuid=self.partition.ptype_for_name('lockbox'),
+                    ),
+                    '--',
+                    get_partition_base(self.partition.get_dev()),
+                ],
+            )
+
+    def get_mount_point(self):
+        return os.path.join(STATEDIR, 'osd-lockbox', self.args.osd_uuid)
+
+    def get_osd_uuid(self):
+        return self.args.osd_uuid
+
+    def activate(self):
+        path = is_mounted(self.partition.get_dev())
+        if path:
+            LOG.info("Lockbox already mounted at " + path)
+            return
+
+        path = tempfile.mkdtemp(
+            prefix='mnt.',
+            dir=STATEDIR + '/tmp',
+        )
+        args = ['mount', '-t', 'ext4', '-o', 'ro',
+                self.partition.get_dev(),
+                path]
+        LOG.debug('Mounting lockbox temporarily ' + str(" ".join(args)))
+        command_check_call(args)
+        self.args.osd_uuid = get_oneliner(path, 'osd-uuid')
+        command_check_call(['umount', path])
+        LOG.debug('Mounting lockbox readonly ' + str(" ".join(args)))
+        args = ['mount', '-t', 'ext4', '-o', 'ro',
+                self.partition.get_dev(),
+                self.get_mount_point()]
+        command_check_call(args)
+        for name in Space.NAMES + ('osd',):
+            uuid_path = os.path.join(self.get_mount_point(), name + '-uuid')
+            if os.path.exists(uuid_path):
+                uuid = get_oneliner(self.get_mount_point(), name + '-uuid')
+                dev = os.path.join('/dev/disk/by-partuuid/', uuid.lower())
+                args = ['ceph-disk', 'trigger', dev]
+                command_check_call(args)
+
+    def prepare(self):
+        verify_not_in_use(self.args.lockbox, check_partitions=True)
+        self.set_or_create_partition()
+        self.populate()
+
+
 class PrepareData(object):
 
     FILE = 1
@@ -2221,7 +2467,8 @@ class PrepareData(object):
         if not os.path.exists(self.args.data):
             raise Error('data path for device does not exist',
                         self.args.data)
-        verify_not_in_use(self.args.data, True)
+        verify_not_in_use(self.args.data,
+                          check_partitions=not self.args.dmcrypt)
 
     def set_variables(self):
         if self.args.fs_type is None:
@@ -2293,9 +2540,10 @@ class PrepareData(object):
             self.partition = DevicePartition.factory(
                 path=None, dev=self.args.data, args=self.args)
             ptype = partition.get_ptype()
-            if ptype != ptype_osd:
+            ready = Ptype.get_ready_by_type('osd')
+            if ptype not in ready:
                 LOG.warning('incorrect partition UUID: %s, expected %s'
-                            % (ptype, ptype_osd))
+                            % (ptype, str(ready)))
         else:
             LOG.debug('Creating osd partition on %s',
                       self.args.data)
@@ -2444,7 +2692,7 @@ def mkfs(
                 '--osd-uuid', fsid,
                 '--keyring', os.path.join(path, 'keyring'),
                 '--setuser', get_ceph_user(),
-                '--setgroup', get_ceph_user(),
+                '--setgroup', get_ceph_group(),
             ],
         )
 
@@ -2678,6 +2926,14 @@ def detect_fstype(
     return fstype
 
 
+def dmcrypt_is_mapped(uuid):
+    path = os.path.join('/dev/mapper', uuid)
+    if os.path.exists(path):
+        return path
+    else:
+        return None
+
+
 def dmcrypt_map(dev, dmcrypt_key_dir):
     ptype = get_partition_type(dev)
     if ptype in Ptype.get_ready_by_type('plain'):
@@ -2690,10 +2946,10 @@ def dmcrypt_map(dev, dmcrypt_key_dir):
         raise Error('--dmcrypt called for dev %s with invalid ptype %s'
                     % (dev, ptype))
     part_uuid = get_partition_uuid(dev)
-    dmcrypt_key_path = get_dmcrypt_key_path(part_uuid, dmcrypt_key_dir, luks)
+    dmcrypt_key = get_dmcrypt_key(part_uuid, dmcrypt_key_dir, luks)
     return _dmcrypt_map(
         rawdev=dev,
-        keypath=dmcrypt_key_path,
+        key=dmcrypt_key,
         _uuid=part_uuid,
         cryptsetup_parameters=cryptsetup_parameters,
         luks=luks,
@@ -2986,6 +3242,7 @@ def main_activate(args):
     cluster = None
     osd_id = None
 
+    LOG.info('path = ' + str(args.path))
     if not os.path.exists(args.path):
         raise Error('%s does not exist' % args.path)
 
@@ -3047,6 +3304,23 @@ def main_activate(args):
         activate_lock.release()  # noqa
 
 
+def main_activate_lockbox(args):
+    activate_lock.acquire()  # noqa
+    try:
+        main_activate_lockbox_protected(args)
+    finally:
+        activate_lock.release()  # noqa
+
+
+def main_activate_lockbox_protected(args):
+    partition = DevicePartition.factory(
+        path=None, dev=args.path, args=args)
+
+    lockbox = Lockbox(args)
+    lockbox.set_partition(partition)
+    lockbox.activate()
+
+
 ###########################
 
 def _mark_osd_out(cluster, osd_id):
@@ -3177,17 +3451,21 @@ def main_deactivate_locked(args):
         LOG.info("OSD already out/down. Do not do anything now.")
         return
 
-    # remove 'ready', 'active', and INIT-specific files.
-    _remove_osd_directory_files(mounted_path, args.cluster)
+    if not args.once:
+        # remove 'ready', 'active', and INIT-specific files.
+        _remove_osd_directory_files(mounted_path, args.cluster)
 
-    # Write deactivate to osd directory!
-    with open(os.path.join(mounted_path, 'deactive'), 'w'):
-        path_set_context(os.path.join(mounted_path, 'deactive'))
+        # Write deactivate to osd directory!
+        with open(os.path.join(mounted_path, 'deactive'), 'w'):
+            path_set_context(os.path.join(mounted_path, 'deactive'))
 
     unmount(mounted_path)
     LOG.info("Umount `%s` successfully.", mounted_path)
 
     if dmcrypt:
+        lockbox = os.path.join(STATEDIR, 'osd-lockbox')
+        command(['umount', os.path.join(lockbox, target_dev['uuid'])])
+
         dmcrypt_unmap(target_dev['uuid'])
         for name in Space.NAMES:
             if name + '_uuid' in target_dev:
@@ -3227,24 +3505,71 @@ def _deallocate_osd_id(cluster, osd_id):
     ])
 
 
+def _remove_lockbox(uuid):
+    command([
+        'ceph',
+        'auth',
+        'del',
+        'client.osd-lockbox.' + uuid,
+    ])
+    command([
+        'ceph',
+        'config-key',
+        'del',
+        'dm-crypt/osd/' + uuid + '/luks',
+    ])
+    lockbox = os.path.join(STATEDIR, 'osd-lockbox')
+    if not os.path.exists(lockbox):
+        return
+    canonical = os.path.join(lockbox, uuid)
+    command(['umount', canonical])
+    for name in os.listdir(lockbox):
+        path = os.path.join(lockbox, name)
+        if (os.path.islink(path) and os.readlink(path) == canonical):
+            os.unlink(path)
+
+
 def destroy_lookup_device(args, predicate, description):
     devices = list_devices()
     for device in devices:
         for partition in device.get('partitions', []):
+            if partition['type'] == 'lockbox':
+                if not is_mounted(partition['path']):
+                    main_activate_lockbox_protected(
+                        argparse.Namespace(verbose=args.verbose,
+                                           path=partition['path']))
+    for device in devices:
+        for partition in device.get('partitions', []):
             if partition['dmcrypt']:
-                dmcrypt_path = dmcrypt_map(partition['path'],
-                                           args.dmcrypt_key_dir)
+                dmcrypt_path = dmcrypt_is_mapped(partition['uuid'])
+                if dmcrypt_path:
+                    unmap = False
+                else:
+                    dmcrypt_path = dmcrypt_map(partition['path'],
+                                               args.dmcrypt_key_dir)
+                    unmap = True
                 list_dev_osd(dmcrypt_path, {}, partition)
-                dmcrypt_unmap(partition['uuid'])
+                if unmap:
+                    dmcrypt_unmap(partition['uuid'])
+                dmcrypt = True
+            else:
+                dmcrypt = False
             if predicate(partition):
-                return partition
+                return (dmcrypt, partition)
     raise Error('found no device matching ', description)
 
 
 def main_destroy(args):
+    activate_lock.acquire()  # noqa
+    try:
+        main_destroy_locked(args)
+    finally:
+        activate_lock.release()  # noqa
+
+
+def main_destroy_locked(args):
     osd_id = args.destroy_by_id
     path = args.path
-    dmcrypt = False
     target_dev = None
 
     if path:
@@ -3253,11 +3578,11 @@ def main_destroy(args):
         path = os.path.realpath(path)
 
     if path:
-        target_dev = destroy_lookup_device(
+        (dmcrypt, target_dev) = destroy_lookup_device(
             args, lambda x: x.get('path') == path,
             path)
     elif osd_id:
-        target_dev = destroy_lookup_device(
+        (dmcrypt, target_dev) = destroy_lookup_device(
             args, lambda x: x.get('whoami') == osd_id,
             'osd id ' + str(osd_id))
 
@@ -3289,6 +3614,7 @@ def main_destroy(args):
         for name in Space.NAMES:
             if target_dev.get(name + '_uuid'):
                 dmcrypt_unmap(target_dev[name + '_uuid'])
+        _remove_lockbox(target_dev['uuid'])
 
     # Check zap flag. If we found zap flag, we need to find device for
     # destroy this osd data.
@@ -3391,7 +3717,7 @@ def main_activate_all(args):
 
         if tag in Ptype.get_ready_by_name('osd'):
 
-            if Ptype.is_dmcrpyt(tag, 'osd'):
+            if Ptype.is_dmcrypt(tag, 'osd'):
                 path = os.path.join('/dev/mapper', uuid)
             else:
                 path = os.path.join(dir, name)
@@ -3545,6 +3871,40 @@ def list_dev_osd(dev, uuid_map, desc):
             pass
 
 
+def list_dev_lockbox(dev, uuid_map, desc):
+    desc['mount'] = is_mounted(dev)
+    desc['fs_type'] = get_dev_fs(dev)
+    desc['state'] = 'unprepared'
+    if desc['mount']:
+        desc['state'] = 'active'
+        desc['osd_uuid'] = get_oneliner(desc['mount'], 'osd-uuid')
+    elif desc['fs_type']:
+        try:
+            tpath = tempfile.mkdtemp(prefix='mnt.', dir=STATEDIR + '/tmp')
+            args = ['mount', '-t', 'ext4', dev, tpath]
+            LOG.debug('Mounting lockbox ' + str(" ".join(args)))
+            command_check_call(args)
+            magic = get_oneliner(tpath, 'magic')
+            if magic is not None:
+                desc['magic'] = magic
+                desc['state'] = 'prepared'
+                desc['osd_uuid'] = get_oneliner(tpath, 'osd-uuid')
+            unmount(tpath)
+        except subprocess.CalledProcessError:
+            pass
+    if desc.get('osd_uuid') in uuid_map:
+        desc['lockbox_for'] = uuid_map[desc['osd_uuid']]
+
+
+def list_format_lockbox_plain(dev):
+    desc = []
+    if dev.get('lockbox_for'):
+        desc.append('for ' + dev['lockbox_for'])
+    elif dev.get('osd_uuid'):
+        desc.append('for osd ' + dev['osd_uuid'])
+    return desc
+
+
 def list_format_more_osd_info_plain(dev):
     desc = []
     if dev.get('ceph_fsid'):
@@ -3565,6 +3925,10 @@ def list_format_dev_plain(dev, prefix=''):
     if dev['ptype'] == PTYPE['regular']['osd']['ready']:
         desc = (['ceph data', dev['state']] +
                 list_format_more_osd_info_plain(dev))
+    elif dev['ptype'] in (PTYPE['regular']['lockbox']['ready'],
+                          PTYPE['mpath']['lockbox']['ready']):
+        desc = (['ceph lockbox', dev['state']] +
+                list_format_lockbox_plain(dev))
     elif Ptype.is_dmcrypt(dev['ptype'], 'osd'):
         dmcrypt = dev['dmcrypt']
         if not dmcrypt['holders']:
@@ -3639,6 +4003,12 @@ def list_dev(dev, uuid_map, space_map):
         if ptype == PTYPE['mpath']['osd']['ready']:
             info['multipath'] = True
         list_dev_osd(dev, uuid_map, info)
+    elif ptype in (PTYPE['regular']['lockbox']['ready'],
+                   PTYPE['mpath']['lockbox']['ready']):
+        info['type'] = 'lockbox'
+        if ptype == PTYPE['mpath']['osd']['ready']:
+            info['multipath'] = True
+        list_dev_lockbox(dev, uuid_map, info)
     elif ptype == PTYPE['plain']['osd']['ready']:
         holders = is_held(dev)
         info['type'] = 'data'
@@ -3754,6 +4124,14 @@ def list_devices():
 
 
 def main_list(args):
+    activate_lock.acquire()  # noqa
+    try:
+        main_list_protected(args)
+    finally:
+        activate_lock.release()  # noqa
+
+
+def main_list_protected(args):
     devices = list_devices()
     if args.path:
         paths = []
@@ -3854,7 +4232,7 @@ def main_trigger(args):
     LOG.debug("main_trigger: " + str(args))
     if is_systemd() and not args.sync:
         # http://www.freedesktop.org/software/systemd/man/systemd-escape.html
-        escaped_dev = args.dev.replace('-', '\\x2d')
+        escaped_dev = args.dev[1:].replace('-', '\\x2d')
         service = 'ceph-disk@{dev}.service'.format(dev=escaped_dev)
         LOG.info('systemd detected, triggering %s' % service)
         command(
@@ -3888,220 +4266,94 @@ def main_trigger(args):
         partid=partid,
     ))
 
+    ceph_disk = ['ceph-disk']
+    if args.verbose:
+        ceph_disk.append('--verbose')
+
     if parttype in (PTYPE['regular']['osd']['ready'],
                     PTYPE['mpath']['osd']['ready']):
-        command(
+        out, err, ret = command(
+            ceph_disk +
             [
-                'ceph-disk',
                 'activate',
                 args.dev,
             ]
         )
-    elif parttype in (PTYPE['regular']['journal']['ready'],
-                      PTYPE['mpath']['journal']['ready']):
-        command(
-            [
-                'ceph-disk',
-                'activate-journal',
-                args.dev,
-            ]
-        )
 
-        # journals are easy: map, chown, activate-journal
-    elif parttype == PTYPE['plain']['journal']['ready']:
-        command(
+    elif parttype in (PTYPE['plain']['osd']['ready'],
+                      PTYPE['luks']['osd']['ready']):
+        out, err, ret = command(
+            ceph_disk +
             [
-                '/sbin/cryptsetup',
-                '--key-file',
-                '/etc/ceph/dmcrypt-keys/{partid}'.format(partid=partid),
-                '--key-size',
-                '256',
-                'create',
-                partid,
+                'activate',
+                '--dmcrypt',
                 args.dev,
             ]
         )
-        newdev = '/dev/mapper/' + partid
-        count = 0
-        while not os.path.exists(newdev) and count <= 10:
-            time.sleep(1)
-            count += 1
-        command(
-            [
-                '/bin/chown',
-                'ceph:ceph',
-                newdev,
-            ]
-        )
-        command(
+
+    elif parttype in (PTYPE['regular']['journal']['ready'],
+                      PTYPE['mpath']['journal']['ready']):
+        out, err, ret = command(
+            ceph_disk +
             [
-                '/usr/sbin/ceph-disk',
                 'activate-journal',
-                newdev,
-            ]
-        )
-    elif parttype == PTYPE['luks']['journal']['ready']:
-        command(
-            [
-                '/sbin/cryptsetup',
-                '--key-file',
-                '/etc/ceph/dmcrypt-keys/{partid}.luks.key'.format(
-                    partid=partid),
-                'luksOpen',
                 args.dev,
-                partid,
-            ]
-        )
-        newdev = '/dev/mapper/' + partid
-        count = 0
-        while not os.path.exists(newdev) and count <= 10:
-            time.sleep(1)
-            count += 1
-        command(
-            [
-                '/bin/chown',
-                'ceph:ceph',
-                newdev,
             ]
         )
-        command(
+
+    elif parttype in (PTYPE['plain']['journal']['ready'],
+                      PTYPE['luks']['journal']['ready']):
+        out, err, ret = command(
+            ceph_disk +
             [
-                '/usr/sbin/ceph-disk',
                 'activate-journal',
-                newdev,
+                '--dmcrypt',
+                args.dev,
             ]
         )
 
     elif parttype in (PTYPE['regular']['block']['ready'],
                       PTYPE['mpath']['block']['ready']):
-        command(
+        out, err, ret = command(
+            ceph_disk +
             [
-                'ceph-disk',
                 'activate-block',
                 args.dev,
             ]
         )
 
-        # blocks are easy: map, chown, activate-block
-    elif parttype == PTYPE['plain']['block']['ready']:
-        command(
-            [
-                '/sbin/cryptsetup',
-                '--key-file',
-                '/etc/ceph/dmcrypt-keys/{partid}'.format(partid=partid),
-                '--key-size',
-                '256',
-                'create',
-                partid,
-                args.dev,
-            ]
-        )
-        newdev = '/dev/mapper/' + partid
-        count = 0
-        while not os.path.exists(newdev) and count <= 10:
-            time.sleep(1)
-            count += 1
-        command(
-            [
-                '/bin/chown',
-                'ceph:ceph',
-                newdev,
-            ]
-        )
-        command(
-            [
-                '/usr/sbin/ceph-disk',
-                'activate-block',
-                newdev,
-            ]
-        )
-    elif parttype == PTYPE['luks']['block']['ready']:
-        command(
-            [
-                '/sbin/cryptsetup',
-                '--key-file',
-                '/etc/ceph/dmcrypt-keys/{partid}.luks.key'.format(
-                    partid=partid),
-                'luksOpen',
-                args.dev,
-                partid,
-            ]
-        )
-        newdev = '/dev/mapper/' + partid
-        count = 0
-        while not os.path.exists(newdev) and count <= 10:
-            time.sleep(1)
-            count += 1
-        command(
-            [
-                '/bin/chown',
-                'ceph:ceph',
-                newdev,
-            ]
-        )
-        command(
+    elif parttype in (PTYPE['plain']['block']['ready'],
+                      PTYPE['luks']['block']['ready']):
+        out, err, ret = command(
+            ceph_disk +
             [
-                '/usr/sbin/ceph-disk',
                 'activate-block',
-                newdev,
-            ]
-        )
-
-        # osd data: map, activate
-    elif parttype == PTYPE['plain']['osd']['ready']:
-        command(
-            [
-                '/sbin/cryptsetup',
-                '--key-file',
-                '/etc/ceph/dmcrypt-keys/{partid}'.format(partid=partid),
-                '--key-size',
-                '256',
-                'create',
-                partid,
+                '--dmcrypt',
                 args.dev,
             ]
         )
-        newdev = '/dev/mapper/' + partid
-        count = 0
-        while not os.path.exists(newdev) and count <= 10:
-            time.sleep(1)
-            count += 1
-        command(
-            [
-                '/usr/sbin/ceph-disk',
-                'activate',
-                newdev,
-            ]
-        )
 
-    elif parttype == PTYPE['luks']['osd']['ready']:
-        command(
+    elif parttype in (PTYPE['regular']['lockbox']['ready'],
+                      PTYPE['mpath']['lockbox']['ready']):
+        out, err, ret = command(
+            ceph_disk +
             [
-                '/sbin/cryptsetup',
-                '--key-file',
-                '/etc/ceph/dmcrypt-keys/{partid}.luks.key'.format(
-                    partid=partid),
-                'luksOpen',
+                'activate-lockbox',
                 args.dev,
-                partid,
-            ]
-        )
-        newdev = '/dev/mapper/' + partid
-        count = 0
-        while not os.path.exists(newdev) and count <= 10:
-            time.sleep(1)
-            count += 1
-        command(
-            [
-                '/usr/sbin/ceph-disk',
-                'activate',
-                newdev,
             ]
         )
 
     else:
         raise Error('unrecognized partition type %s' % parttype)
 
+    if ret != 0:
+        LOG.info(out)
+        LOG.error(err)
+        raise Error('return code ' + str(ret))
+    else:
+        LOG.debug(out)
+        LOG.debug(err)
+
 
 def setup_statedir(dir):
     # XXX The following use of globals makes linting
@@ -4165,6 +4417,18 @@ def parse_args(argv):
         help=('directory in which ceph configuration files are found '
               '(default /etc/ceph)'),
     )
+    parser.add_argument(
+        '--setuser',
+        metavar='USER',
+        default=None,
+        help='use the given user for subprocesses, rather than ceph or root'
+    )
+    parser.add_argument(
+        '--setgroup',
+        metavar='GROUP',
+        default=None,
+        help='use the given group for subprocesses, rather than ceph or root'
+    )
     parser.set_defaults(
         # we want to hold on to this, for later
         prog=parser.prog,
@@ -4178,6 +4442,7 @@ def parse_args(argv):
 
     Prepare.set_subparser(subparsers)
     make_activate_parser(subparsers)
+    make_activate_lockbox_parser(subparsers)
     make_activate_block_parser(subparsers)
     make_activate_journal_parser(subparsers)
     make_activate_all_parser(subparsers)
@@ -4195,12 +4460,37 @@ def parse_args(argv):
 def make_trigger_parser(subparsers):
     trigger_parser = subparsers.add_parser(
         'trigger',
-        help='Trigger an event (caled by udev)')
+        formatter_class=argparse.RawDescriptionHelpFormatter,
+        description=textwrap.fill(textwrap.dedent("""\
+        The partition given in argument is activated. The type of the
+        partition (data, lockbox, journal etc.) is detected by its
+        type. If the init system is upstart or systemd, the activation is
+        delegated to it and runs asynchronously, which
+        helps reduce the execution time of udev actions.
+        """)),
+        help='activate any device (called by udev)')
     trigger_parser.add_argument(
         'dev',
         help=('device'),
     )
     trigger_parser.add_argument(
+        '--cluster',
+        metavar='NAME',
+        default='ceph',
+        help='cluster name to assign this disk to',
+    )
+    trigger_parser.add_argument(
+        '--dmcrypt',
+        action='store_true', default=None,
+        help='map devices with dm-crypt',
+    )
+    trigger_parser.add_argument(
+        '--dmcrypt-key-dir',
+        metavar='KEYDIR',
+        default='/etc/ceph/dmcrypt-keys',
+        help='directory where dm-crypt keys are stored',
+    )
+    trigger_parser.add_argument(
         '--sync',
         action='store_true', default=None,
         help=('do operation synchronously; do not trigger systemd'),
@@ -4214,6 +4504,21 @@ def make_trigger_parser(subparsers):
 def make_activate_parser(subparsers):
     activate_parser = subparsers.add_parser(
         'activate',
+        formatter_class=argparse.RawDescriptionHelpFormatter,
+        description=textwrap.fill(textwrap.dedent("""\
+        Activate the OSD found at PATH (can be a directory
+        or a device partition, possibly encrypted). When
+        activated for the first time, a unique OSD id is obtained
+        from the cluster. If PATH is a directory, a symbolic
+        link is added in {statedir}/osd/ceph-$id. If PATH is
+        a partition, it is mounted on {statedir}/osd/ceph-$id.
+        Finally, the OSD daemon is run.
+
+        If the OSD depends on auxiliary partitions (journal, block, ...)
+        they need to be available otherwise activation will fail. It
+        may happen if a journal is encrypted and cryptsetup was not
+        run yet.
+        """.format(statedir=STATEDIR))),
         help='Activate a Ceph OSD')
     activate_parser.add_argument(
         '--mount',
@@ -4241,7 +4546,6 @@ def make_activate_parser(subparsers):
     activate_parser.add_argument(
         'path',
         metavar='PATH',
-        nargs='?',
         help='path to block device or directory',
     )
     activate_parser.add_argument(
@@ -4267,6 +4571,47 @@ def make_activate_parser(subparsers):
     return activate_parser
 
 
+def make_activate_lockbox_parser(subparsers):
+    parser = subparsers.add_parser(
+        'activate-lockbox',
+        formatter_class=argparse.RawDescriptionHelpFormatter,
+        description=textwrap.fill(textwrap.dedent("""\
+        Mount the partition found at PATH on {statedir}/osd-lockbox/$uuid
+        where $uuid uniquely identifies the OSD that needs this lockbox
+        to retrieve keys from the monitor and unlock its partitions.
+
+        If the OSD has one or more auxiliary devices (journal, block, ...)
+        symbolic links are created at {statedir}/osd-lockbox/$other_uuid
+        and point to {statedir}/osd-lockbox/$uuid. This will, for instance,
+        allow a journal encrypted in a partition identified by $other_uuid to
+        fetch the keys it needs from the monitor.
+
+        Finally the OSD is activated, as it would be with ceph-disk activate.
+        """.format(statedir=STATEDIR))),
+        help='Activate a Ceph lockbox')
+    parser.add_argument(
+        '--activate-key',
+        help='bootstrap-osd keyring path template (%(default)s)',
+        dest='activate_key_template',
+    )
+    parser.add_argument(
+        '--dmcrypt-key-dir',
+        metavar='KEYDIR',
+        default='/etc/ceph/dmcrypt-keys',
+        help='directory where dm-crypt keys are stored',
+    )
+    parser.add_argument(
+        'path',
+        metavar='PATH',
+        help='path to block device',
+    )
+    parser.set_defaults(
+        activate_key_template='{statedir}/bootstrap-osd/{cluster}.keyring',
+        func=main_activate_lockbox,
+    )
+    return parser
+
+
 def make_activate_block_parser(subparsers):
     return make_activate_space_parser('block', subparsers)
 
@@ -4278,6 +4623,15 @@ def make_activate_journal_parser(subparsers):
 def make_activate_space_parser(name, subparsers):
     activate_space_parser = subparsers.add_parser(
         'activate-%s' % name,
+        formatter_class=argparse.RawDescriptionHelpFormatter,
+        description=textwrap.fill(textwrap.dedent("""\
+        Activating a {name} partition is only meaningfull
+        if it is encrypted and it will map it using
+        cryptsetup.
+
+        Finally the corresponding OSD is activated,
+        as it would be with ceph-disk activate.
+        """.format(name=name))),
         help='Activate an OSD via its %s device' % name)
     activate_space_parser.add_argument(
         'dev',
@@ -4324,6 +4678,12 @@ def make_activate_space_parser(name, subparsers):
 def make_activate_all_parser(subparsers):
     activate_all_parser = subparsers.add_parser(
         'activate-all',
+        formatter_class=argparse.RawDescriptionHelpFormatter,
+        description=textwrap.fill(textwrap.dedent("""\
+        Activate all OSD partitions found in /dev/disk/by-parttypeuuid.
+        The partitions containing auxiliary devices (journal, block, ...)
+        are not activated.
+        """)),
         help='Activate all tagged OSD partitions')
     activate_all_parser.add_argument(
         '--activate-key',
@@ -4348,6 +4708,11 @@ def make_activate_all_parser(subparsers):
 def make_list_parser(subparsers):
     list_parser = subparsers.add_parser(
         'list',
+        formatter_class=argparse.RawDescriptionHelpFormatter,
+        description=textwrap.fill(textwrap.dedent("""\
+        Display all partitions on the system and their
+        associated Ceph information, if any.
+        """)),
         help='List disks, partitions, and Ceph OSDs')
     list_parser.add_argument(
         '--format',
@@ -4370,11 +4735,15 @@ def make_list_parser(subparsers):
 def make_suppress_parser(subparsers):
     suppress_parser = subparsers.add_parser(
         'suppress-activate',
+        formatter_class=argparse.RawDescriptionHelpFormatter,
+        description=textwrap.fill(textwrap.dedent("""\
+        Add a prefix to the list of suppressed device names
+        so that they are ignored by all activate* subcommands.
+        """)),
         help='Suppress activate on a device (prefix)')
     suppress_parser.add_argument(
         'path',
         metavar='PATH',
-        nargs='?',
         help='path to block device or directory',
     )
     suppress_parser.set_defaults(
@@ -4383,11 +4752,16 @@ def make_suppress_parser(subparsers):
 
     unsuppress_parser = subparsers.add_parser(
         'unsuppress-activate',
+        formatter_class=argparse.RawDescriptionHelpFormatter,
+        description=textwrap.fill(textwrap.dedent("""\
+        Remove a prefix from the list of suppressed device names
+        so that they are no longer ignored by all
+        activate* subcommands.
+        """)),
         help='Stop suppressing activate on a device (prefix)')
     unsuppress_parser.add_argument(
         'path',
         metavar='PATH',
-        nargs='?',
         help='path to block device or directory',
     )
     unsuppress_parser.set_defaults(
@@ -4399,6 +4773,25 @@ def make_suppress_parser(subparsers):
 def make_deactivate_parser(subparsers):
     deactivate_parser = subparsers.add_parser(
         'deactivate',
+        formatter_class=argparse.RawDescriptionHelpFormatter,
+        description=textwrap.fill(textwrap.dedent("""\
+        Deactivate the OSD located at PATH. It stops the OSD daemon
+        and optionally marks it out (with --mark-out). The content of
+        the OSD is left untouched.
+
+        By default, the, ready, active, INIT-specific files are
+        removed (so that it is not automatically re-activated by the
+        udev rules or ceph-disk trigger) and the file deactive is
+        created to remember the OSD is deactivated.
+
+        If the --once option is given, the ready, active, INIT-specific
+        files are not removed and the OSD will reactivate whenever
+        ceph-disk trigger is run on one of the devices (journal, data,
+        block, lockbox, ...).
+
+        If the OSD is dmcrypt, remove the data dmcrypt map. When
+        deactivate finishes, the OSD is down.
+        """)),
         help='Deactivate a Ceph OSD')
     deactivate_parser.add_argument(
         '--cluster',
@@ -4422,6 +4815,11 @@ def make_deactivate_parser(subparsers):
         action='store_true', default=False,
         help='option to mark the osd out',
     )
+    deactivate_parser.add_argument(
+        '--once',
+        action='store_true', default=False,
+        help='does not need --reactivate to activate again',
+    )
     deactivate_parser.set_defaults(
         func=main_deactivate,
     )
@@ -4430,6 +4828,13 @@ def make_deactivate_parser(subparsers):
 def make_destroy_parser(subparsers):
     destroy_parser = subparsers.add_parser(
         'destroy',
+        formatter_class=argparse.RawDescriptionHelpFormatter,
+        description=textwrap.fill(textwrap.dedent("""\
+        Destroy the OSD located at PATH.
+        It removes the OSD from the cluster, the crushmap and
+        deallocates the OSD id. An OSD must be down before it
+        can be destroyed.
+        """)),
         help='Destroy a Ceph OSD')
     destroy_parser.add_argument(
         '--cluster',
@@ -4469,6 +4874,13 @@ def make_destroy_parser(subparsers):
 def make_zap_parser(subparsers):
     zap_parser = subparsers.add_parser(
         'zap',
+        formatter_class=argparse.RawDescriptionHelpFormatter,
+        description=textwrap.fill(textwrap.dedent("""\
+        Zap/erase/destroy a device's partition table and contents. It
+        actually uses sgdisk and it's option --zap-all to
+        destroy both GPT and MBR data structures so that the disk
+        becomes suitable for repartitioning.
+        """)),
         help='Zap/erase/destroy a device\'s partition table (and contents)')
     zap_parser.add_argument(
         'dev',
@@ -4494,6 +4906,11 @@ def main(argv):
     setup_statedir(args.statedir)
     setup_sysconfdir(args.sysconfdir)
 
+    global CEPH_PREF_USER
+    CEPH_PREF_USER = args.setuser
+    global CEPH_PREF_GROUP
+    CEPH_PREF_GROUP = args.setgroup
+
     if args.verbose:
         args.func(args)
     else:
@@ -4508,13 +4925,14 @@ def setup_logging(verbose, log_stdout):
     if log_stdout:
         ch = logging.StreamHandler(stream=sys.stdout)
         ch.setLevel(loglevel)
-        formatter = logging.Formatter('%(filename)s: %(message)s')
+        formatter = logging.Formatter('%(funcName)s: %(message)s')
         ch.setFormatter(formatter)
         LOG.addHandler(ch)
         LOG.setLevel(loglevel)
     else:
         logging.basicConfig(
             level=loglevel,
+            format='%(funcName)s: %(message)s',
         )
 
 
diff --git a/src/ceph-disk/run-tox.sh b/src/ceph-disk/run-tox.sh
index 1d2b30f..1979af8 100755
--- a/src/ceph-disk/run-tox.sh
+++ b/src/ceph-disk/run-tox.sh
@@ -16,9 +16,10 @@
 #
 
 # run from the ceph-disk directory or from its parent
+: ${CEPH_DISK_VIRTUALENV:=ceph-disk-virtualenv}
 test -d ceph-disk && cd ceph-disk
-source virtualenv/bin/activate
-tox > virtualenv/tox.out 2>&1
+source ${CEPH_DISK_VIRTUALENV}/bin/activate
+tox > ${CEPH_DISK_VIRTUALENV}/tox.out 2>&1
 status=$?
-grep -v InterpreterNotFound < virtualenv/tox.out
+grep -v InterpreterNotFound < ${CEPH_DISK_VIRTUALENV}/tox.out
 exit $status
diff --git a/src/ceph-disk/tests/test_main.py b/src/ceph-disk/tests/test_main.py
index fe85eb7..f59824c 100644
--- a/src/ceph-disk/tests/test_main.py
+++ b/src/ceph-disk/tests/test_main.py
@@ -32,6 +32,8 @@ class TestCephDisk(object):
         main.setup_logging(verbose=True, log_stdout=False)
 
     def test_main_list_json(self, capsys):
+        data = tempfile.mkdtemp()
+        main.setup_statedir(data)
         args = main.parse_args(['list', '--format', 'json'])
         with patch.multiple(
                 main,
@@ -39,8 +41,11 @@ class TestCephDisk(object):
             main.main_list(args)
             out, err = capsys.readouterr()
             assert '{}\n' == out
+        shutil.rmtree(data)
 
     def test_main_list_plain(self, capsys):
+        data = tempfile.mkdtemp()
+        main.setup_statedir(data)
         args = main.parse_args(['list'])
         with patch.multiple(
                 main,
@@ -48,6 +53,7 @@ class TestCephDisk(object):
             main.main_list(args)
             out, err = capsys.readouterr()
             assert '' == out
+        shutil.rmtree(data)
 
     def test_list_format_more_osd_info_plain(self):
         dev = {
@@ -315,7 +321,7 @@ class TestCephDisk(object):
             partition_uuid = "56244cf5-83ef-4984-888a-2d8b8e0e04b2"
             disk = "Xda"
             partition = "Xda1"
-            holders = ["dm-0"]
+            holders = ["dm-dummy"]
             with patch.multiple(
                     main,
                     is_held=lambda dev: holders,
@@ -346,7 +352,7 @@ class TestCephDisk(object):
             partition_uuid = "56244cf5-83ef-4984-888a-2d8b8e0e04b2"
             disk = "Xda"
             partition = "Xda1"
-            holders = ["dm-0", "dm-1"]
+            holders = ["dm-dummy", "dm-dummy1"]
             with patch.multiple(
                     main,
                     is_held=lambda dev: holders,
@@ -451,9 +457,9 @@ class TestCephDisk(object):
         data_uuid = "56244cf5-83ef-4984-888a-2d8b8e0e04b2"
         disk = "Xda"
         data = "Xda1"
-        data_holder = "dm-0"
+        data_holder = "dm-dummy"
         space = "Xda2"
-        space_holder = "dm-0"
+        space_holder = "dm-dummy"
         mount_path = '/mount/path'
         fs_type = 'ext4'
         space_uuid = "7ad5e65a-0ca5-40e4-a896-62a74ca61c55"
@@ -1152,6 +1158,8 @@ class TestCephDiskDeactivateAndDestroy(unittest.TestCase):
             main.unmount(path)
 
     def test_main_destroy(self):
+        data = tempfile.mkdtemp()
+        main.setup_statedir(data)
         OSD_UUID = '4fbd7e29-9d25-41b8-afd0-062c0ceff05d'
         MPATH_OSD_UUID = '4fbd7e29-8ae0-4982-bf9d-5a8d867af560'
         part_uuid = '0ce28a16-6d5d-11e5-aec3-fa163e5c167b'
@@ -1161,6 +1169,7 @@ class TestCephDiskDeactivateAndDestroy(unittest.TestCase):
         fake_devices_normal = [{'path': '/dev/sdY',
                                 'partitions': [{
                                     'dmcrypt': {},
+                                    'type': 'osd',
                                     'ptype': OSD_UUID,
                                     'path': '/dev/sdY1',
                                     'whoami': '5566',
@@ -1170,6 +1179,7 @@ class TestCephDiskDeactivateAndDestroy(unittest.TestCase):
                                {'path': '/dev/sdX',
                                 'partitions': [{
                                     'dmcrypt': {},
+                                    'type': 'osd',
                                     'ptype': MPATH_OSD_UUID,
                                     'path': '/dev/sdX1',
                                     'whoami': '7788',
@@ -1245,6 +1255,7 @@ class TestCephDiskDeactivateAndDestroy(unittest.TestCase):
                 _check_osd_status=lambda cluster, osd_id: 1,
         ):
             self.assertRaises(Exception, main.main_destroy, args)
+        shutil.rmtree(data)
 
     def test_remove_from_crush_map_fail(self):
         cluster = 'ceph'
diff --git a/src/ceph.in b/src/ceph.in
index e9df0cf..79c2263 100755
--- a/src/ceph.in
+++ b/src/ceph.in
@@ -19,11 +19,17 @@ License version 2, as published by the Free Software
 Foundation.  See file COPYING.
 """
 
+from __future__ import print_function
 import codecs
 import os
 import sys
 import platform
 
+try:
+    input = raw_input
+except NameError:
+    pass
+
 CEPH_GIT_VER="@CEPH_GIT_VER@"
 CEPH_GIT_NICE_VER="@CEPH_GIT_NICE_VER@"
 
@@ -36,7 +42,7 @@ MYPATH = os.path.abspath(__file__)
 MYDIR = os.path.dirname(MYPATH)
 DEVMODEMSG = '*** DEVELOPER MODE: setting PATH, PYTHONPATH and LD_LIBRARY_PATH ***'
 
-def respawn_in_path(lib_path, pybind_path):
+def respawn_in_path(lib_path, pybind_path, pythonlib_path):
     execv_cmd = ['python']
     if 'CEPH_DBG' in os.environ:
         execv_cmd += ['-mpdb']
@@ -51,19 +57,30 @@ def respawn_in_path(lib_path, pybind_path):
     if lib_path_var in os.environ:
         if lib_path not in os.environ[lib_path_var]:
             os.environ[lib_path_var] += ':' + lib_path
-            print >> sys.stderr, DEVMODEMSG
+            print(DEVMODEMSG, file=sys.stderr)
             os.execvp(py_binary, execv_cmd + sys.argv)
     else:
         os.environ[lib_path_var] = lib_path
-        print >> sys.stderr, DEVMODEMSG
+        print(DEVMODEMSG, file=sys.stderr)
         os.execvp(py_binary, execv_cmd + sys.argv)
     sys.path.insert(0, os.path.join(MYDIR, pybind_path))
+    sys.path.insert(0, os.path.join(MYDIR, pythonlib_path))
+
+def get_pythonlib_dir():
+    """Returns the name of a distutils build directory"""
+    import sysconfig
+    f = "lib.{platform}-{version[0]}.{version[1]}"
+    name = f.format(platform=sysconfig.get_platform(),
+                    version=sys.version_info)
+    return os.path.join('build', name)
 
 if MYDIR.endswith('src') and \
    os.path.exists(os.path.join(MYDIR, '.libs')) and \
-   os.path.exists(os.path.join(MYDIR, 'pybind')):
+   os.path.exists(os.path.join(MYDIR, 'pybind')) and \
+   os.path.exists(os.path.join(MYDIR, 'build')):
 
-    respawn_in_path(os.path.join(MYDIR, '.libs'), "pybind")
+    pythonlib_path = get_pythonlib_dir()
+    respawn_in_path(os.path.join(MYDIR, '.libs'), "pybind", pythonlib_path)
     if os.environ.has_key('PATH') and MYDIR not in os.environ['PATH']:
         os.environ['PATH'] += ':' + MYDIR
 
@@ -81,9 +98,11 @@ elif os.path.exists(os.path.join(os.getcwd(), "CMakeCache.txt")) \
         # Developer mode, but in a cmake build dir instead of the src dir
         lib_path = os.path.join(os.getcwd(), "src")
         pybind_path = os.path.join(src_path, "src", "pybind")
-        respawn_in_path(lib_path, pybind_path)
+        pythonlib_path = os.path.join(src_path, "src", get_pythonlib_dir())
+        respawn_in_path(lib_path, pybind_path, pythonlib_path)
 
-    sys.path.insert(0, os.path.join(MYDIR, pybind_path))
+        sys.path.insert(0, os.path.join(MYDIR, pybind_path))
+        sys.path.insert(0, os.path.join(MYDIR, pythonlib_path))
 
     # Add src/ to path for e.g. ceph-conf
     if os.environ.has_key('PATH') and lib_path not in os.environ['PATH']:
@@ -101,7 +120,7 @@ import subprocess
 from ceph_argparse import \
     concise_sig, descsort, parse_json_funcsigs, \
     matchnum, validate_command, find_cmd_target, \
-    send_command, json_command
+    send_command, json_command, run_in_thread
 
 from ceph_daemon import DaemonWatcher, admin_socket
 
@@ -229,7 +248,7 @@ def parse_cmdargs(args=None, target=''):
 
 
 def hdr(s):
-    print '\n', s, '\n', '=' * len(s)
+    print('\n', s, '\n', '=' * len(s))
 
 def do_basic_help(parser, args):
     """
@@ -249,9 +268,8 @@ def do_extended_help(parser, args):
                                          prefix='get_command_descriptions',
                                          timeout=10)
         if ret:
-            print >> sys.stderr, \
-                "couldn't get command descriptions for {0}: {1}".\
-                format(target, outs)
+            print("couldn't get command descriptions for {0}: {1}".\
+                format(target, outs), file=sys.stderr)
         else:
             help_for_sigs(outbuf, partial)
 
@@ -371,7 +389,7 @@ PROMPT = 'ceph> '
 if sys.stdin.isatty():
     def read_input():
         while True:
-            line = raw_input(PROMPT).rstrip()
+            line = input(PROMPT).rstrip()
             if line in ['q', 'quit', 'Q', 'exit']:
                 return None
             if line:
@@ -399,7 +417,7 @@ def new_style_command(parsed_args, cmdargs, target, sigdict, inbuf, verbose):
         for cmdtag in sorted(sigdict.keys()):
             cmd = sigdict[cmdtag]
             sig = cmd['sig']
-            print '{0}: {1}'.format(cmdtag, concise_sig(sig))
+            print('{0}: {1}'.format(cmdtag, concise_sig(sig)))
 
     if True:
         if cmdargs:
@@ -413,7 +431,7 @@ def new_style_command(parsed_args, cmdargs, target, sigdict, inbuf, verbose):
         else:
             if sys.stdin.isatty():
                 # do the command-interpreter looping
-                # for raw_input to do readline cmd editing
+                # for input to do readline cmd editing
                 import readline  # noqa
 
             while True:
@@ -424,35 +442,35 @@ def new_style_command(parsed_args, cmdargs, target, sigdict, inbuf, verbose):
                 try:
                     target = find_cmd_target(cmdargs)
                 except Exception as e:
-                    print >> sys.stderr, \
-                            'error handling command target: {0}'.format(e)
+                    print('error handling command target: {0}'.format(e), 
+                        file=sys.stderr)
                     continue
                 if len(cmdargs) and cmdargs[0] == 'tell':
-                    print >> sys.stderr, \
-                          'Can not use \'tell\' in interactive mode.'
+                    print('Can not use \'tell\' in interactive mode.', 
+                        file=sys.stderr)
                     continue
                 valid_dict = validate_command(sigdict, cmdargs, verbose)
                 if valid_dict:
                     if parsed_args.output_format:
                         valid_dict['format'] = parsed_args.output_format
                     if verbose:
-                        print >> sys.stderr, "Submitting command ", valid_dict
+                        print("Submitting command ", valid_dict, file=sys.stderr)
                     ret, outbuf, outs = json_command(cluster_handle,
                                                      target=target,
                                                      argdict=valid_dict)
                     if ret:
                         ret = abs(ret)
-                        print >> sys.stderr, \
-                            'Error: {0} {1}'.format(ret, errno.errorcode.get(ret, 'Unknown'))
+                        print('Error: {0} {1}'.format(ret, errno.errorcode.get(ret, 'Unknown')), 
+                            file=sys.stderr)
                     if outbuf:
-                        print outbuf
+                        print(outbuf)
                     if outs:
-                        print >> sys.stderr, 'Status:\n', outs
+                        print('Status:\n', outs, file=sys.stderr)
                 else:
-                    print >> sys.stderr, "Invalid command"
+                    print("Invalid command", file=sys.stderr)
 
     if verbose:
-        print >> sys.stderr, "Submitting command ", valid_dict
+        print("Submitting command ", valid_dict, file=sys.stderr)
     return json_command(cluster_handle, target=target, argdict=valid_dict,
                         inbuf=inbuf)
 
@@ -480,16 +498,14 @@ def complete(sigdict, args, target):
         matched = matchnum(args, sig, partial=True)
         if (matched > best_match_cnt):
             if complete_verbose:
-                print >> sys.stderr, \
-                    "better match: {0} > {1}: {2}:{3} ".format(matched,
-                                  best_match_cnt, cmdtag, concise_sig(sig))
+                print("better match: {0} > {1}: {2}:{3} ".format(matched,
+                        best_match_cnt, cmdtag, concise_sig(sig)),  file=sys.stderr)
             best_match_cnt = matched
             bestcmds = [{cmdtag:cmd}]
         elif matched == best_match_cnt:
             if complete_verbose:
-                print >> sys.stderr, \
-                    "equal match: {0} > {1}: {2}:{3} ".format(matched,
-                                  best_match_cnt, cmdtag, concise_sig(sig))
+                print("equal match: {0} > {1}: {2}:{3} ".format(matched,
+                        best_match_cnt, cmdtag, concise_sig(sig)), file=sys.stderr)
             bestcmds.append({cmdtag:cmd})
 
     # look through all matching sigs
@@ -503,15 +519,15 @@ def complete(sigdict, args, target):
             fullindex = matchnum(args, sig, partial=False) - 1
             partindex = matchnum(args, sig, partial=True) - 1
             if complete_verbose:
-                print >> sys.stderr, '{}: f {} p {} len {}'.format(sig, fullindex, partindex, len(sig))
+                print('{}: f {} p {} len {}'.format(sig, fullindex, partindex, len(sig)), file=sys.stderr)
             if fullindex == partindex and fullindex + 1 < len(sig):
                 d = sig[fullindex + 1]
             else:
                 d = sig[partindex]
             comps.append(str(d))
     if complete_verbose:
-        print >> sys.stderr, '\n'.join(comps)
-    print '\n'.join(comps)
+        print('\n'.join(comps), file=sys.stderr)
+    print('\n'.join(comps))
 
     return 0
 
@@ -520,18 +536,18 @@ def complete(sigdict, args, target):
 ###
 def ping_monitor(cluster_handle, name, timeout):
     if 'mon.' not in name:
-        print >> sys.stderr, '"ping" expects a monitor to ping; try "ping mon.<id>"'
+        print('"ping" expects a monitor to ping; try "ping mon.<id>"', file=sys.stderr)
         return 1
 
     mon_id = name[len('mon.'):]
     if (mon_id == '*') :
-        cluster_handle.connect(timeout=timeout)
+        run_in_thread(cluster_handle.connect, timeout=timeout)
         for m in monids() :
-            s = cluster_handle.ping_monitor(m)
-            print "mon.{0}".format(m) + '\n' + s
+            s = run_in_thread(cluster_handle.ping_monitor, m)
+            print("mon.{0}".format(m) + '\n' + s)
     else :
-            s = cluster_handle.ping_monitor(mon_id)
-            print s
+            s = run_in_thread(cluster_handle.ping_monitor, mon_id)
+            print(s)
     return 0
 
 ###
@@ -549,18 +565,18 @@ def main():
     parser, parsed_args, childargs = parse_cmdargs()
 
     if parsed_args.version:
-        print 'ceph version {0} ({1})'.format(CEPH_GIT_NICE_VER, CEPH_GIT_VER)  # noqa
+        print('ceph version {0} ({1})'.format(CEPH_GIT_NICE_VER, CEPH_GIT_VER))  # noqa
         return 0
 
     global verbose
     verbose = parsed_args.verbose
 
     if verbose:
-        print >> sys.stderr, "parsed_args: {0}, childargs: {1}".format(parsed_args, childargs)
+        print("parsed_args: {0}, childargs: {1}".format(parsed_args, childargs), file=sys.stderr)
 
     if parsed_args.admin_socket_nope:
-        print >> sys.stderr, '--admin-socket is used by daemons; '\
-        'you probably mean --admin-daemon/daemon'
+        print('--admin-socket is used by daemons; '\
+            'you probably mean --admin-daemon/daemon', file=sys.stderr)
         return 1
 
     # pass on --id, --name, --conf
@@ -597,14 +613,13 @@ def main():
                     sockpath = ceph_conf(parsed_args, 'admin_socket',
                                          childargs[1])
                 except Exception as e:
-                    print >> sys.stderr, \
-                        'Can\'t get admin socket path: ' + str(e)
+                    print('Can\'t get admin socket path: ' + str(e), file=sys.stderr)
                     return errno.EINVAL
             # for both:
             childargs = childargs[2:]
         else:
-            print >> sys.stderr, '{0} requires at least {1} arguments'.format(
-                childargs[0], require_args)
+            print('{0} requires at least {1} arguments'.format(childargs[0], require_args), 
+                file=sys.stderr) 
             return errno.EINVAL
 
     if sockpath and daemon_perf:
@@ -616,20 +631,21 @@ def main():
                 if interval < 0:
                     raise ValueError
             except ValueError:
-                print >> sys.stderr, 'daemonperf: interval should be a positive number'
+                print('daemonperf: interval should be a positive number', file=sys.stderr)
                 return errno.EINVAL
         if len(childargs) > 1:
             if not childargs[1].isdigit():
-                print >> sys.stderr, 'daemonperf: count should be a positive integer'
+                print('daemonperf: count should be a positive integer', file=sys.stderr)
                 return errno.EINVAL
             count = int(childargs[1])
         DaemonWatcher(sockpath).run(interval, count)
         return 0
     elif sockpath:
         try:
-            print admin_socket(sockpath, childargs, format)
+            print(admin_socket(sockpath, childargs, format))
         except Exception as e:
-            print >> sys.stderr, 'admin_socket: {0}'.format(e)
+            print('admin_socket: {0}'.format(e))
+            print('admin_socket: {0}'.format(e), file=sys.stderr)
             return errno.EINVAL
         return 0
 
@@ -658,23 +674,23 @@ def main():
         injectargs = childargs[position:]
         childargs = childargs[:position]
         if verbose:
-            print >> sys.stderr, 'Separate childargs {0} from injectargs {1}'.\
-                format(childargs, injectargs)
+            print('Separate childargs {0} from injectargs {1}'.format(childargs, injectargs), 
+                file=sys.stderr)
     else:
         injectargs = None
 
-    clustername = 'ceph'
+    clustername = None
     if parsed_args.cluster:
         clustername = parsed_args.cluster
 
     try:
-        cluster_handle = rados.Rados(name=name, clustername=clustername,
-                                     conf_defaults=conf_defaults,
-                                     conffile=conffile)
-        retargs = cluster_handle.conf_parse_argv(childargs)
+        cluster_handle = run_in_thread(rados.Rados,
+                                       name=name, clustername=clustername,
+                                       conf_defaults=conf_defaults,
+                                       conffile=conffile)
+        retargs = run_in_thread(cluster_handle.conf_parse_argv, childargs)
     except rados.Error as e:
-        print >> sys.stderr, 'Error initializing cluster client: {0}'.\
-            format(repr(e))
+        print('Error initializing cluster client: {0}'.format(repr(e)), file=sys.stderr)
         return 1
 
     childargs = retargs
@@ -692,7 +708,8 @@ def main():
     if len(childargs) >= 2 and \
         childargs[0] in ['mon', 'osd'] and \
         childargs[1] == 'tell':
-        print >> sys.stderr, '"{0} tell" is deprecated; try "tell {0}.<id> <command> [options...]" instead (id can be "*") '.format(childargs[0])
+        print('"{0} tell" is deprecated; try "tell {0}.<id> <command> [options...]" instead (id can be "*") '.format(childargs[0]), 
+            file=sys.stderr)
         return 1
 
     if childargs in [['mon'], ['osd']]:
@@ -704,27 +721,25 @@ def main():
             timeout = 5
 
         hdr('Monitor commands:')
-        print '[Contacting monitor, timeout after %d seconds]' % timeout
+        print('[Contacting monitor, timeout after %d seconds]' % timeout)
 
     if childargs and childargs[0] == 'ping':
         if len(childargs) < 2:
-            print >> sys.stderr, '"ping" requires a monitor name as argument: "ping mon.<id>"'
+            print('"ping" requires a monitor name as argument: "ping mon.<id>"', file=sys.stderr)
             return 1
 
     try:
         if childargs and childargs[0] == 'ping':
             return ping_monitor(cluster_handle, childargs[1], timeout)
-        cluster_handle.connect(timeout=timeout)
+        run_in_thread(cluster_handle.connect, timeout=timeout)
     except KeyboardInterrupt:
-        print >> sys.stderr, 'Cluster connection aborted'
+        print('Cluster connection aborted', file=sys.stderr)
         return 1
     except rados.PermissionDeniedError as e:
-        print >> sys.stderr, 'Error connecting to cluster: {0}'.\
-            format(e.__class__.__name__)
+        print('Error connecting to cluster: {0}'.format(e.__class__.__name__), file=sys.stderr)
         return errno.EACCES
     except Exception as e:
-        print >> sys.stderr, 'Error connecting to cluster: {0}'.\
-            format(e.__class__.__name__)
+        print('Error connecting to cluster: {0}'.format(e.__class__.__name__), file=sys.stderr)
         return 1
 
     if parsed_args.help:
@@ -743,7 +758,7 @@ def main():
 
         # an awfully simple callback
         def watch_cb(arg, line, who, stamp_sec, stamp_nsec, seq, level, msg):
-            print line
+            print(line)
             sys.stdout.flush()
 
         # first do a ceph status
@@ -755,13 +770,13 @@ def main():
             if ret == 0:
                 outbuf += outs
         if ret:
-            print >> sys.stderr, "status query failed: ", outs
+            print("status query failed: ", outs, file=sys.stderr)
             return ret
-        print outbuf
+        print(outbuf)
 
         # this instance keeps the watch connection alive, but is
         # otherwise unused
-        rados.MonitorLog(cluster_handle, level, watch_cb, 0)
+        run_in_thread(cluster_handle.monitor_log, level, watch_cb, 0)
 
         # loop forever letting watch_cb print lines
         try:
@@ -777,7 +792,7 @@ def main():
             with open(parsed_args.input_file, 'r') as f:
                 inbuf = f.read()
         except Exception as e:
-            print >> sys.stderr, 'Can\'t open input file {0}: {1}'.format(parsed_args.input_file, e)
+            print('Can\'t open input file {0}: {1}'.format(parsed_args.input_file, e), file=sys.stderr)
             return 1
 
     # prepare output file, if any
@@ -785,9 +800,7 @@ def main():
         try:
             outf = open(parsed_args.output_file, 'w')
         except Exception as e:
-            print >> sys.stderr, \
-                'Can\'t open output file {0}: {1}'.\
-                format(parsed_args.output_file, e)
+            print('Can\'t open output file {0}: {1}'.format(parsed_args.output_file, e), file=sys.stderr)
             return 1
 
     # -s behaves like a command (ceph status).
@@ -797,8 +810,7 @@ def main():
     try:
         target = find_cmd_target(childargs)
     except Exception as e:
-        print >> sys.stderr, \
-                'error handling command target: {0}'.format(e)
+        print('error handling command target: {0}'.format(e), file=sys.stderr)
         return 1
 
     # Repulsive hack to handle tell: lop off 'tell' and target
@@ -813,9 +825,9 @@ def main():
         if injectargs:
             childargs = injectargs
         if not len(childargs):
-            print >> sys.stderr, \
-                '"{0} tell" requires additional arguments.'.format(sys.argv[0]), \
-                'Try "{0} tell <name> <command> [options...]" instead.'.format(sys.argv[0])
+            print('"{0} tell" requires additional arguments.'.format(sys.argv[0]),
+                'Try "{0} tell <name> <command> [options...]" instead.'.format(sys.argv[0]), 
+                file=sys.stderr)
             return errno.EINVAL
 
     # fetch JSON sigs from command
@@ -846,7 +858,7 @@ def main():
         if ret == -errno.EINVAL:
             # send command to old monitor or OSD
             if verbose:
-                print prefix + '{0} to old {1}'.format(' '.join(childargs), target[0])
+                print(prefix + '{0} to old {1}'.format(' '.join(childargs), target[0]))
             compat = True
             if parsed_args.output_format:
                 childargs.extend(['--format', parsed_args.output_format])
@@ -879,11 +891,12 @@ def main():
                                                           sigdict, inbuf, verbose)
                     if ret < 0:
                         ret = -ret
-                        print >> sys.stderr, prefix + 'Second attempt of previously successful command failed with {0}: {1}'.format(errno.errorcode.get(ret, 'Unknown'), outs)
+                        print(prefix + 'Second attempt of previously successful command failed with {0}: {1}'.format(errno.errorcode.get(ret, 'Unknown'), outs), 
+                            file=sys.stderr) 
 
         if ret < 0:
             ret = -ret
-            print >> sys.stderr, prefix + 'Error {0}: {1}'.format(errno.errorcode.get(ret, 'Unknown'), outs)
+            print('Error {0}: {1}'.format(errno.errorcode.get(ret, 'Unknown'), outs), file=sys.stderr)
             if len(targets) > 1:
                 final_ret = ret
             else:
@@ -893,10 +906,10 @@ def main():
         if compat:
             if ret == 0:
                 # old cli/mon would send status string to stdout on non-error
-                print outs
+                print(outs)
         else:
             if outs:
-                print >> sys.stderr, prefix + outs
+                print(prefix + outs, file=sys.stderr)
 
         sys.stdout.flush()
 
@@ -939,5 +952,5 @@ if __name__ == '__main__':
     retval = main()
     # shutdown explicitly; Rados() does not
     if cluster_handle:
-        cluster_handle.shutdown()
+        run_in_thread(cluster_handle.shutdown)
     sys.exit(retval)
diff --git a/src/ceph_fuse.cc b/src/ceph_fuse.cc
index 27f430d..1b72288 100644
--- a/src/ceph_fuse.cc
+++ b/src/ceph_fuse.cc
@@ -30,7 +30,9 @@ using namespace std;
 
 #include "common/Timer.h"
 #include "common/ceph_argparse.h"
+#if defined(__linux__)
 #include "common/linux_version.h"
+#endif
 #include "global/global_init.h"
 #include "common/safe_io.h"
        
diff --git a/src/ceph_mds.cc b/src/ceph_mds.cc
index 08eee5e..fda5a37 100644
--- a/src/ceph_mds.cc
+++ b/src/ceph_mds.cc
@@ -160,6 +160,8 @@ int main(int argc, const char **argv)
   Messenger *msgr = Messenger::create(g_ceph_context, g_conf->ms_type,
 				      entity_name_t::MDS(-1), "mds",
 				      getpid());
+  if (!msgr)
+    exit(1);
   msgr->set_cluster_protocol(CEPH_MDS_PROTOCOL);
 
   cout << "starting " << g_conf->name << " at " << msgr->get_myaddr()
diff --git a/src/ceph_mon.cc b/src/ceph_mon.cc
index 79d9e37..4bb5c4a 100644
--- a/src/ceph_mon.cc
+++ b/src/ceph_mon.cc
@@ -666,13 +666,15 @@ int main(int argc, const char **argv)
 				      entity_name_t::MON(rank),
 				      "mon",
 				      0);
+  if (!msgr)
+    exit(1);
   msgr->set_cluster_protocol(CEPH_MON_PROTOCOL);
   msgr->set_default_send_priority(CEPH_MSG_PRIO_HIGH);
 
   uint64_t supported =
     CEPH_FEATURE_UID |
     CEPH_FEATURE_NOSRCADDR |
-    CEPH_FEATURE_MONCLOCKCHECK |
+    DEPRECATED_CEPH_FEATURE_MONCLOCKCHECK |
     CEPH_FEATURE_PGID64 |
     CEPH_FEATURE_MSG_AUTH;
   msgr->set_default_policy(Messenger::Policy::stateless_server(supported, 0));
diff --git a/src/ceph_osd.cc b/src/ceph_osd.cc
index ce5b9ef..0c25fb6 100644
--- a/src/ceph_osd.cc
+++ b/src/ceph_osd.cc
@@ -85,7 +85,7 @@ void usage()
        << "                    check whether a journal is allowed\n"
        << "  --check-needs-journal\n"
        << "                    check whether a journal is required\n"
-       << "  --debug_osd <N>   set debug level (e.g. 10)"
+       << "  --debug_osd <N>   set debug level (e.g. 10)\n"
        << "  --get-device-fsid PATH\n"
        << "                    get OSD fsid for the given block device\n"
        << std::endl;
@@ -257,7 +257,8 @@ int main(int argc, const char **argv)
   ObjectStore *store = ObjectStore::create(g_ceph_context,
 					   store_type,
 					   g_conf->osd_data,
-					   g_conf->osd_journal);
+					   g_conf->osd_journal,
+                                           g_conf->osd_os_flags);
   if (!store) {
     derr << "unable to create object store" << dendl;
     return -ENODEV;
@@ -461,6 +462,8 @@ int main(int argc, const char **argv)
   Messenger *ms_objecter = Messenger::create(g_ceph_context, g_conf->ms_type,
 					     entity_name_t::OSD(whoami), "ms_objecter",
 					     getpid());
+  if (!ms_public || !ms_cluster || !ms_hbclient || !ms_hb_back_server || !ms_hb_front_server || !ms_objecter)
+    exit(1);
   ms_cluster->set_cluster_protocol(CEPH_OSD_PROTOCOL);
   ms_hbclient->set_cluster_protocol(CEPH_OSD_PROTOCOL);
   ms_hb_back_server->set_cluster_protocol(CEPH_OSD_PROTOCOL);
@@ -491,13 +494,7 @@ int main(int argc, const char **argv)
   uint64_t osd_required =
     CEPH_FEATURE_UID |
     CEPH_FEATURE_PGID64 |
-    CEPH_FEATURE_OSDENC |
-    CEPH_FEATURE_OSD_SNAPMAPPER |
-    CEPH_FEATURE_INDEP_PG_MAP |
-    CEPH_FEATURE_OSD_PACKED_RECOVERY |
-    CEPH_FEATURE_RECOVERY_RESERVATION |
-    CEPH_FEATURE_BACKFILL_RESERVATION |
-    CEPH_FEATURE_CHUNKY_SCRUB;
+    CEPH_FEATURE_OSDENC;
 
   ms_public->set_default_policy(Messenger::Policy::stateless_server(supported, 0));
   ms_public->set_policy_throttlers(entity_name_t::TYPE_CLIENT,
diff --git a/src/civetweb/src/civetweb.c b/src/civetweb/src/civetweb.c
index 0385b8f..967d853 100644
--- a/src/civetweb/src/civetweb.c
+++ b/src/civetweb/src/civetweb.c
@@ -3994,7 +3994,6 @@ static void parse_http_headers(char **buf, struct mg_request_info *ri)
     }
 }
 
-#ifndef RGW
 static int is_valid_http_method(const char *method)
 {
     return !strcmp(method, "GET") || !strcmp(method, "POST") ||
@@ -4004,7 +4003,6 @@ static int is_valid_http_method(const char *method)
            || !strcmp(method, "MKCOL")
            ;
 }
-#endif
 
 /* Parse HTTP request, fill in mg_request_info structure.
    This function modifies the buffer by NUL-terminating
diff --git a/src/client/Client.cc b/src/client/Client.cc
index 1e1c9af..7530e3d 100644
--- a/src/client/Client.cc
+++ b/src/client/Client.cc
@@ -67,6 +67,7 @@ using namespace std;
 #include "messages/MGenericMessage.h"
 
 #include "messages/MMDSMap.h"
+#include "messages/MFSMap.h"
 
 #include "mon/MonClient.h"
 
@@ -171,8 +172,8 @@ bool Client::CommandHook::call(std::string command, cmdmap_t& cmdmap,
 // -------------
 
 dir_result_t::dir_result_t(Inode *in)
-  : inode(in), offset(0), this_offset(2), next_offset(2),
-    release_count(0), ordered_count(0), start_shared_gen(0),
+  : inode(in), owner_uid(-1), owner_gid(-1), offset(0), this_offset(2),
+    next_offset(2), release_count(0), ordered_count(0), start_shared_gen(0),
     buffer(0) {
 }
 
@@ -253,7 +254,7 @@ Client::Client(Messenger *m, MonClient *mc)
     objecter_finisher(m->cct),
     tick_event(NULL),
     monclient(mc), messenger(m), whoami(m->get_myname().num()),
-    cap_epoch_barrier(0),
+    cap_epoch_barrier(0), fsmap(nullptr),
     last_tid(0), oldest_tid(0), last_flush_tid(1),
     initialized(false), authenticated(false),
     mounted(false), unmounting(false),
@@ -321,6 +322,7 @@ Client::~Client()
   delete filer;
   delete objecter;
   delete mdsmap;
+  delete fsmap;
 
   delete logger;
 }
@@ -337,6 +339,12 @@ void Client::tear_down_cache()
   }
   fd_map.clear();
 
+  while (!opened_dirs.empty()) {
+    dir_result_t *dirp = *opened_dirs.begin();
+    ldout(cct, 1) << "tear_down_cache forcing close of dir " << dirp << " ino " << dirp->inode->ino << dendl;
+    _closedir(dirp);
+  }
+
   // caps!
   // *** FIXME ***
 
@@ -362,7 +370,10 @@ void Client::tear_down_cache()
 
 inodeno_t Client::get_root_ino()
 {
-  return root->ino;
+  if (use_faked_inos())
+    return root->faked_ino;
+  else
+    return root->ino;
 }
 
 Inode *Client::get_root()
@@ -487,7 +498,17 @@ int Client::init()
   objecter->start();
 
   monclient->set_want_keys(CEPH_ENTITY_TYPE_MDS | CEPH_ENTITY_TYPE_OSD);
-  monclient->sub_want("mdsmap", 0, 0);
+
+  std::string want = "mdsmap";
+  const auto &want_ns = cct->_conf->client_mds_namespace;
+  if (want_ns != FS_CLUSTER_ID_NONE) {
+    std::ostringstream oss;
+    oss << want << "." << want_ns;
+    want = oss.str();
+  }
+  ldout(cct, 10) << "Subscribing to map '" << want << "'" << dendl;
+
+  monclient->sub_want(want, 0, 0);
   monclient->renew_subs();
 
   // logger
@@ -1389,7 +1410,7 @@ mds_rank_t Client::choose_target_mds(MetaRequest *req)
 
 random_mds:
   if (mds < 0) {
-    mds = mdsmap->get_random_up_mds();
+    mds = _get_random_up_mds();
     ldout(cct, 10) << "did not get mds through better means, so chose random mds " << mds << dendl;
   }
 
@@ -1596,7 +1617,7 @@ int Client::make_request(MetaRequest *request,
 
 	if (!mdsmap->is_active_or_stopping(mds)) {
 	  ldout(cct, 10) << "hmm, still have no address for mds." << mds << ", trying a random mds" << dendl;
-	  request->resend_mds = mdsmap->get_random_up_mds();
+	  request->resend_mds = _get_random_up_mds();
 	  continue;
 	}
       }
@@ -2287,7 +2308,7 @@ void Client::_handle_full_flag(int64_t pool)
   {
     Inode *inode = i->second;
     if (inode->oset.dirty_or_tx
-        && (pool == -1 || inode->layout.fl_pg_pool == pool)) {
+        && (pool == -1 || inode->layout.pool_id == pool)) {
       ldout(cct, 4) << __func__ << ": FULL: inode 0x" << std::hex << i->first << std::dec
         << " has dirty objects, purging and setting ENOSPC" << dendl;
       objectcacher->purge_set(&inode->oset);
@@ -2352,6 +2373,9 @@ bool Client::ms_dispatch(Message *m)
   case CEPH_MSG_MDS_MAP:
     handle_mds_map(static_cast<MMDSMap*>(m));
     break;
+  case CEPH_MSG_FS_MAP:
+    handle_fs_map(static_cast<MFSMap*>(m));
+    break;
   case CEPH_MSG_CLIENT_SESSION:
     handle_client_session(static_cast<MClientSession*>(m));
     break;
@@ -2410,6 +2434,17 @@ bool Client::ms_dispatch(Message *m)
   return true;
 }
 
+void Client::handle_fs_map(MFSMap *m)
+{
+  delete fsmap;
+  fsmap = new FSMap;
+  fsmap->decode(m->get_encoded());
+  m->put();
+
+  signal_cond_list(waiting_for_fsmap);
+
+  monclient->sub_got("fsmap", fsmap->get_epoch());
+}
 
 void Client::handle_mds_map(MMDSMap* m)
 {
@@ -3113,15 +3148,15 @@ void Client::send_cap(Inode *in, MetaSession *session, Cap *cap,
     m->head.xattr_version = in->xattr_version;
   }
   
-  m->head.layout = in->layout;
-  m->head.size = in->size;
-  m->head.max_size = in->max_size;
-  m->head.truncate_seq = in->truncate_seq;
-  m->head.truncate_size = in->truncate_size;
-  in->mtime.encode_timeval(&m->head.mtime);
-  in->atime.encode_timeval(&m->head.atime);
-  in->ctime.encode_timeval(&m->head.ctime);
-  m->head.time_warp_seq = in->time_warp_seq;
+  m->layout = in->layout;
+  m->size = in->size;
+  m->max_size = in->max_size;
+  m->truncate_seq = in->truncate_seq;
+  m->truncate_size = in->truncate_size;
+  m->mtime = in->mtime;
+  m->atime = in->atime;
+  m->ctime = in->ctime;
+  m->time_warp_seq = in->time_warp_seq;
     
   if (flush & CEPH_CAP_FILE_WR) {
     m->inline_version = in->inline_version;
@@ -3395,15 +3430,15 @@ void Client::flush_snaps(Inode *in, bool all_again, CapSnap *again)
     m->head.gid = capsnap->gid;
     m->head.mode = capsnap->mode;
 
-    m->head.size = capsnap->size;
+    m->size = capsnap->size;
 
     m->head.xattr_version = capsnap->xattr_version;
     ::encode(capsnap->xattrs, m->xattrbl);
 
-    capsnap->ctime.encode_timeval(&m->head.ctime);
-    capsnap->mtime.encode_timeval(&m->head.mtime);
-    capsnap->atime.encode_timeval(&m->head.atime);
-    m->head.time_warp_seq = capsnap->time_warp_seq;
+    m->ctime = capsnap->ctime;
+    m->mtime = capsnap->mtime;
+    m->atime = capsnap->atime;
+    m->time_warp_seq = capsnap->time_warp_seq;
 
     if (capsnap->dirty & CEPH_CAP_FILE_WR) {
       m->inline_version = in->inline_version;
@@ -3542,7 +3577,7 @@ bool Client::_flush(Inode *in, Context *onfinish)
     return true;
   }
 
-  if (objecter->osdmap_pool_full(in->layout.fl_pg_pool)) {
+  if (objecter->osdmap_pool_full(in->layout.pool_id)) {
     ldout(cct, 1) << __func__ << ": FULL, purging for ENOSPC" << dendl;
     objectcacher->purge_set(&in->oset);
     if (onfinish) {
@@ -4176,7 +4211,7 @@ bool Client::adjust_realm_parent(SnapRealm *realm, inodeno_t parent)
 static bool has_new_snaps(const SnapContext& old_snapc,
 			  const SnapContext& new_snapc)
 {
-	return !new_snapc.snaps.empty() && new_snapc.snaps[0] > old_snapc.seq;
+  return !new_snapc.snaps.empty() && new_snapc.snaps[0] > old_snapc.seq;
 }
 
 
@@ -4281,9 +4316,8 @@ void Client::handle_snap(MClientSnap *m)
 
   got_mds_push(session);
 
-  list<Inode*> to_move;
+  map<Inode*, SnapContext> to_move;
   SnapRealm *realm = 0;
-  SnapContext old_snapc;
 
   if (m->head.op == CEPH_SNAP_OP_SPLIT) {
     assert(m->head.split);
@@ -4295,7 +4329,6 @@ void Client::handle_snap(MClientSnap *m)
     // flush, then move, ino's.
     realm = get_snap_realm(info.ino());
     ldout(cct, 10) << " splitting off " << *realm << dendl;
-    old_snapc = realm->get_snap_context();
     for (vector<inodeno_t>::iterator p = m->split_inos.begin();
 	 p != m->split_inos.end();
 	 ++p) {
@@ -4313,8 +4346,8 @@ void Client::handle_snap(MClientSnap *m)
 
 
 	in->snaprealm_item.remove_myself();
+	to_move[in] = in->snaprealm->get_snap_context();
 	put_snap_realm(in->snaprealm);
-	to_move.push_back(in);
       }
     }
 
@@ -4334,15 +4367,14 @@ void Client::handle_snap(MClientSnap *m)
   update_snap_trace(m->bl, m->head.op != CEPH_SNAP_OP_DESTROY);
 
   if (realm) {
-    bool queue_snap = has_new_snaps(old_snapc, realm->get_snap_context());
-    for (list<Inode*>::iterator p = to_move.begin(); p != to_move.end(); ++p) {
-      Inode *in = *p;
+    for (auto p = to_move.begin(); p != to_move.end(); ++p) {
+      Inode *in = p->first;
       in->snaprealm = realm;
       realm->inodes_with_caps.push_back(&in->snaprealm_item);
       realm->nref++;
       // queue for snap writeback
-      if (queue_snap)
-	queue_cap_snap(in, old_snapc);
+      if (has_new_snaps(p->second, realm->get_snap_context()))
+	queue_cap_snap(in, p->second);
     }
     put_snap_realm(realm);
   }
@@ -4816,6 +4848,7 @@ void Client::handle_cap_grant(MetaSession *session, Inode *in, Cap *cap, MClient
 
 int Client::_getgrouplist(gid_t** sgids, int uid, int gid)
 {
+  // cppcheck-suppress variableScope
   int sgid_count;
   gid_t *sgid_buf;
 
@@ -4875,9 +4908,8 @@ int Client::inode_permission(Inode *in, uid_t uid, UserGroups& groups, unsigned
   if (uid == 0)
     return 0;
 
-  int ret;
   if (uid != in->uid && (in->mode & S_IRWXG)) {
-    ret = _posix_acl_permission(in, uid, groups, want);
+    int ret = _posix_acl_permission(in, uid, groups, want);
     if (ret != -EAGAIN)
       return ret;
   }
@@ -5140,8 +5172,8 @@ inodeno_t Client::_get_inodeno(Inode *in)
 /**
  * Resolve an MDS spec to a list of MDS daemon GIDs.
  *
- * The spec is a string representing a GID, rank or name/id.  It may
- * be * in which case it matches all GIDs.
+ * The spec is a string representing a GID, rank, filesystem:rank, or name/id.
+ * It may be '*' in which case it matches all GIDs.
  *
  * If no error is returned, the `targets` vector will be populated with at least
  * one MDS.
@@ -5150,57 +5182,58 @@ int Client::resolve_mds(
     const std::string &mds_spec,
     std::vector<mds_gid_t> *targets)
 {
+  assert(fsmap != nullptr);
+  assert(targets != nullptr);
+
+  mds_role_t role;
+  std::stringstream ss;
+  int role_r = fsmap->parse_role(mds_spec, &role, ss);
+  if (role_r == 0) {
+    // We got a role, resolve it to a GID
+    ldout(cct, 10) << __func__ << ": resolved '" << mds_spec << "' to role '"
+      << role << "'" << dendl;
+    targets->push_back(
+        fsmap->get_filesystem(role.fscid)->mds_map.get_info(role.rank).global_id);
+    return 0;
+  }
+
   std::string strtol_err;
   long long rank_or_gid = strict_strtoll(mds_spec.c_str(), 10, &strtol_err);
   if (strtol_err.empty()) {
-    // If it parses as an integer, it's GID or a rank
-    if (rank_or_gid >= 0 && rank_or_gid < MAX_MDS) {
-      const mds_rank_t mds_rank = mds_rank_t(rank_or_gid);
-
-      if (mdsmap->is_dne(mds_rank)) {
-        lderr(cct) << __func__ << ": MDS rank " << mds_rank << " does not exist" << dendl;
-        return -ENOENT;
-      }
-
-      if (!mdsmap->is_up(mds_rank)) {
-        lderr(cct) << __func__ << ": MDS rank " << mds_rank << " is not up" << dendl;
-        return -EAGAIN;
-      }
-
-      const mds_gid_t mds_gid = mdsmap->get_info(mds_rank).global_id;
-      ldout(cct, 10) << __func__ << ": resolved rank " << mds_rank << " to GID " << mds_gid << dendl;
+    // It is a possible GID
+    const mds_gid_t mds_gid = mds_gid_t(rank_or_gid);
+    if (fsmap->gid_exists(mds_gid)) {
+      ldout(cct, 10) << __func__ << ": validated GID " << mds_gid << dendl;
       targets->push_back(mds_gid);
     } else {
-      const mds_gid_t mds_gid = mds_gid_t(rank_or_gid);
-      if (mdsmap->is_dne_gid(mds_gid)) {
-        lderr(cct) << __func__ << ": GID " << mds_gid << " not in MDS map" << dendl;
-        return -ENOENT;
-      } else {
-        ldout(cct, 10) << __func__ << ": validated GID " << mds_gid << dendl;
-        targets->push_back(mds_gid);
-      }
+      lderr(cct) << __func__ << ": GID " << mds_gid << " not in MDS map"
+                 << dendl;
+      return -ENOENT;
     }
   } else if (mds_spec == "*") {
     // It is a wildcard: use all MDSs
-    const std::map<mds_gid_t, MDSMap::mds_info_t> &mds_info = mdsmap->get_mds_info();
+    const auto mds_info = fsmap->get_mds_info();
 
     if (mds_info.empty()) {
       lderr(cct) << __func__ << ": * passed but no MDS daemons found" << dendl;
       return -ENOENT;
     }
 
-    for (std::map<mds_gid_t, MDSMap::mds_info_t>::const_iterator i = mds_info.begin();
-        i != mds_info.end(); ++i) {
-      targets->push_back(i->first);
+    for (const auto i : mds_info) {
+      targets->push_back(i.first);
     }
   } else {
     // It did not parse as an integer, it is not a wildcard, it must be a name
-    const mds_gid_t mds_gid = mdsmap->find_mds_gid_by_name(mds_spec);
+    const mds_gid_t mds_gid = fsmap->find_mds_gid_by_name(mds_spec);
     if (mds_gid == 0) {
       lderr(cct) << "MDS ID '" << mds_spec << "' not found" << dendl;
+
+      lderr(cct) << "FSMap: " << *fsmap << dendl;
+
       return -ENOENT;
     } else {
-      ldout(cct, 10) << __func__ << ": resolved ID '" << mds_spec << "' to GID " << mds_gid << dendl;
+      ldout(cct, 10) << __func__ << ": resolved ID '" << mds_spec
+                     << "' to GID " << mds_gid << dendl;
       targets->push_back(mds_gid);
     }
   }
@@ -5258,10 +5291,33 @@ int Client::mds_command(
     return r;
   }
 
-  // Block until we have an MDSMap to resolve IDs
-  if (mdsmap->get_epoch() == 0) {
-    wait_on_list(waiting_for_mdsmap);
+  // Retrieve FSMap to enable looking up daemon addresses.  We need FSMap
+  // rather than MDSMap because no one MDSMap contains all the daemons, and
+  // a `tell` can address any daemon.
+  version_t fsmap_latest;
+  do {
+    C_SaferCond cond;
+    monclient->get_version("fsmap", &fsmap_latest, NULL, &cond);
+    client_lock.Unlock();
+    r = cond.wait();
+    client_lock.Lock();
+  } while (r == -EAGAIN);
+  ldout(cct, 20) << "Learned FSMap version " << fsmap_latest << dendl;
+
+  if (r < 0) {
+    lderr(cct) << "Failed to learn FSMap version: " << cpp_strerror(r) << dendl;
+    return r;
+  }
+
+  if (fsmap == nullptr || fsmap->get_epoch() < fsmap_latest) {
+    monclient->sub_want("fsmap", fsmap_latest, CEPH_SUBSCRIBE_ONETIME);
+    monclient->renew_subs();
+    wait_on_list(waiting_for_fsmap);
   }
+  assert(fsmap != nullptr);
+  assert(fsmap->get_epoch() >= fsmap_latest);
+  ldout(cct, 20) << "Finished waiting for FSMap version " << fsmap_latest
+    << dendl;
 
   // Look up MDS target(s) of the command
   std::vector<mds_gid_t> targets;
@@ -5273,10 +5329,10 @@ int Client::mds_command(
   // If daemons are laggy, we won't send them commands.  If all
   // are laggy then we fail.
   std::vector<mds_gid_t> non_laggy;
-  for (std::vector<mds_gid_t>::iterator target = targets.begin();
-      target != targets.end(); ++target) {
-    if (!mdsmap->is_laggy_gid(*target)) {
-      non_laggy.push_back(*target);
+  for (const auto gid : targets) {
+    const auto info = fsmap->get_info_gid(gid);
+    if (!info.laggy()) {
+      non_laggy.push_back(gid);
     }
   }
   if (non_laggy.size() == 0) {
@@ -5286,12 +5342,12 @@ int Client::mds_command(
 
   // Send commands to targets
   C_GatherBuilder gather(cct, onfinish);
-  for (std::vector<mds_gid_t>::iterator target = non_laggy.begin();
-      target != non_laggy.end(); ++target) {
+  for (const auto target_gid : non_laggy) {
     ceph_tid_t tid = ++last_tid;
+    const auto info = fsmap->get_info_gid(target_gid);
 
     // Open a connection to the target MDS
-    entity_inst_t inst = mdsmap->get_info_gid(*target).get_inst();
+    entity_inst_t inst = info.get_inst();
     ConnectionRef conn = messenger->get_connection(inst);
 
     // Generate CommandOp state
@@ -5300,11 +5356,11 @@ int Client::mds_command(
     op.on_finish = gather.new_sub();
     op.outbl = outbl;
     op.outs = outs;
-    op.mds_gid = *target;
+    op.mds_gid = target_gid;
     op.con = conn;
     commands[op.tid] = op;
 
-    ldout(cct, 4) << __func__ << ": new command op to " << *target
+    ldout(cct, 4) << __func__ << ": new command op to " << target_gid
       << " tid=" << op.tid << cmd << dendl;
 
     // Construct and send MCommand
@@ -5485,6 +5541,19 @@ void Client::unmount()
     ldout(cct, 0) << " destroyed lost open file " << fh << " on " << *fh->inode << dendl;
     _release_fh(fh);
   }
+  
+  while (!ll_unclosed_fh_set.empty()) {
+    set<Fh*>::iterator it = ll_unclosed_fh_set.begin();
+    ll_unclosed_fh_set.erase(*it);
+    ldout(cct, 0) << " destroyed lost open file " << *it << " on " << *((*it)->inode) << dendl;
+    _release_fh(*it);
+  }
+
+  while (!opened_dirs.empty()) {
+    dir_result_t *dirp = *opened_dirs.begin();
+    ldout(cct, 0) << " destroyed lost open dir " << dirp << " on " << *dirp->inode << dendl;
+    _closedir(dirp);
+  }
 
   _ll_drop_pins();
 
@@ -5568,7 +5637,8 @@ void Client::flush_cap_releases()
   for (map<mds_rank_t,MetaSession*>::iterator p = mds_sessions.begin();
        p != mds_sessions.end();
        ++p) {
-    if (p->second->release && mdsmap->is_clientreplay_or_active_or_stopping(p->first)) {
+    if (p->second->release && mdsmap->is_clientreplay_or_active_or_stopping(
+          p->first)) {
       if (cct->_conf->client_inject_release_failure) {
         ldout(cct, 20) << __func__ << " injecting failure to send cap release message" << dendl;
         p->second->release->put();
@@ -6470,14 +6540,16 @@ int Client::fill_stat(Inode *in, struct stat *st, frag_info_t *dirstat, nest_inf
   stat_set_mtime_sec(st, in->mtime.sec());
   stat_set_mtime_nsec(st, in->mtime.nsec());
   if (in->is_dir()) {
-    //st->st_size = in->dirstat.size();
-    st->st_size = in->rstat.rbytes;
+    if (cct->_conf->client_dirsize_rbytes)
+      st->st_size = in->rstat.rbytes;
+    else
+      st->st_size = in->dirstat.size();
     st->st_blocks = 1;
   } else {
     st->st_size = in->size;
     st->st_blocks = (in->size + 511) >> 9;
   }
-  st->st_blksize = MAX(in->layout.fl_stripe_unit, 4096);
+  st->st_blksize = MAX(in->layout.stripe_unit, 4096);
 
   if (dirstat)
     *dirstat = in->dirstat;
@@ -6689,6 +6761,7 @@ int Client::_opendir(Inode *in, dir_result_t **dirpp, int uid, int gid)
   if (!in->is_dir())
     return -ENOTDIR;
   *dirpp = new dir_result_t(in);
+  opened_dirs.insert(*dirpp);
   if (in->dir) {
     (*dirpp)->release_count = in->dir->release_count;
     (*dirpp)->ordered_count = in->dir->ordered_count;
@@ -6721,6 +6794,7 @@ void Client::_closedir(dir_result_t *dirp)
     dirp->inode.reset();
   }
   _readdir_drop_dirp_buffer(dirp);
+  opened_dirs.erase(dirp);
   delete dirp;
 }
 
@@ -7543,7 +7617,7 @@ Fh *Client::_create_fh(Inode *in, int flags, int cmode)
   }
 
   const md_config_t *conf = cct->_conf;
-  loff_t p = in->layout.fl_stripe_count * in->layout.fl_object_size;
+  loff_t p = in->layout.stripe_count * in->layout.object_size;
   f->readahead.set_trigger_requests(1);
   f->readahead.set_min_readahead_size(conf->client_readahead_min);
   uint64_t max_readahead = Readahead::NO_LIMIT;
@@ -7556,7 +7630,7 @@ Fh *Client::_create_fh(Inode *in, int flags, int cmode)
   f->readahead.set_max_readahead_size(max_readahead);
   vector<uint64_t> alignments;
   alignments.push_back(p);
-  alignments.push_back(in->layout.fl_stripe_unit);
+  alignments.push_back(in->layout.stripe_unit);
   f->readahead.set_alignments(alignments);
 
   return f;
@@ -7659,6 +7733,7 @@ int Client::close(int fd)
     return -EBADF;
   int err = _release_fh(fh);
   fd_map.erase(fd);
+  put_fd(fd);
   ldout(cct, 3) << "close exit(" << fd << ")" << dendl;
   return err;
 }
@@ -8216,7 +8291,7 @@ int Client::_write(Fh *f, int64_t offset, uint64_t size, const char *buf,
   //ldout(cct, 7) << "write fh " << fh << " size " << size << " offset " << offset << dendl;
   Inode *in = f->inode.get();
 
-  if (objecter->osdmap_pool_full(in->layout.fl_pg_pool)) {
+  if (objecter->osdmap_pool_full(in->layout.pool_id)) {
     return -ENOSPC;
   }
 
@@ -8764,11 +8839,11 @@ int Client::_do_filelock(Inode *in, Fh *fh, int lock_type, int op, int sleep,
       ceph_lock_state_t *lock_state;
       if (lock_type == CEPH_LOCK_FCNTL) {
 	if (!in->fcntl_locks)
-	  in->fcntl_locks = new ceph_lock_state_t(cct);
+	  in->fcntl_locks = new ceph_lock_state_t(cct, CEPH_LOCK_FCNTL);
 	lock_state = in->fcntl_locks;
       } else if (lock_type == CEPH_LOCK_FLOCK) {
 	if (!in->flock_locks)
-	  in->flock_locks = new ceph_lock_state_t(cct);
+	  in->flock_locks = new ceph_lock_state_t(cct, CEPH_LOCK_FLOCK);
 	lock_state = in->flock_locks;
       } else {
 	assert(0);
@@ -8779,11 +8854,11 @@ int Client::_do_filelock(Inode *in, Fh *fh, int lock_type, int op, int sleep,
       if (fh) {
 	if (lock_type == CEPH_LOCK_FCNTL) {
 	  if (!fh->fcntl_locks)
-	    fh->fcntl_locks = new ceph_lock_state_t(cct);
+	    fh->fcntl_locks = new ceph_lock_state_t(cct, CEPH_LOCK_FCNTL);
 	  lock_state = fh->fcntl_locks;
 	} else {
 	  if (!fh->flock_locks)
-	    fh->flock_locks = new ceph_lock_state_t(cct);
+	    fh->flock_locks = new ceph_lock_state_t(cct, CEPH_LOCK_FLOCK);
 	  lock_state = fh->flock_locks;
 	}
 	_update_lock_state(fl, owner, lock_state);
@@ -8918,7 +8993,7 @@ void Client::_update_lock_state(struct flock *fl, uint64_t owner,
     list<ceph_filelock> activated_locks;
     lock_state->remove_lock(filelock, activated_locks);
   } else {
-    bool r = lock_state->add_lock(filelock, false, false);
+    bool r = lock_state->add_lock(filelock, false, false, NULL);
     assert(r);
   }
 }
@@ -9969,53 +10044,56 @@ size_t Client::_vxattrcb_quota_max_files(Inode *in, char *val, size_t size)
 
 bool Client::_vxattrcb_layout_exists(Inode *in)
 {
-  char *p = (char *)&in->layout;
-  for (size_t s = 0; s < sizeof(in->layout); s++, p++)
-    if (*p)
-      return true;
-  return false;
+  return in->layout != file_layout_t();
 }
 size_t Client::_vxattrcb_layout(Inode *in, char *val, size_t size)
 {
   int r = snprintf(val, size,
       "stripe_unit=%lld stripe_count=%lld object_size=%lld pool=",
-      (unsigned long long)in->layout.fl_stripe_unit,
-      (unsigned long long)in->layout.fl_stripe_count,
-      (unsigned long long)in->layout.fl_object_size);
+      (unsigned long long)in->layout.stripe_unit,
+      (unsigned long long)in->layout.stripe_count,
+      (unsigned long long)in->layout.object_size);
   objecter->with_osdmap([&](const OSDMap& o) {
-      if (o.have_pg_pool(in->layout.fl_pg_pool))
+      if (o.have_pg_pool(in->layout.pool_id))
 	r += snprintf(val + r, size - r, "%s",
-		      o.get_pool_name(in->layout.fl_pg_pool).c_str());
+		      o.get_pool_name(in->layout.pool_id).c_str());
       else
 	r += snprintf(val + r, size - r, "%" PRIu64,
-		      (uint64_t)in->layout.fl_pg_pool);
+		      (uint64_t)in->layout.pool_id);
     });
+  if (in->layout.pool_ns.length())
+    r += snprintf(val + r, size - r, " pool_namespace=%s",
+		  in->layout.pool_ns.c_str());
   return r;
 }
 size_t Client::_vxattrcb_layout_stripe_unit(Inode *in, char *val, size_t size)
 {
-  return snprintf(val, size, "%lld", (unsigned long long)in->layout.fl_stripe_unit);
+  return snprintf(val, size, "%lld", (unsigned long long)in->layout.stripe_unit);
 }
 size_t Client::_vxattrcb_layout_stripe_count(Inode *in, char *val, size_t size)
 {
-  return snprintf(val, size, "%lld", (unsigned long long)in->layout.fl_stripe_count);
+  return snprintf(val, size, "%lld", (unsigned long long)in->layout.stripe_count);
 }
 size_t Client::_vxattrcb_layout_object_size(Inode *in, char *val, size_t size)
 {
-  return snprintf(val, size, "%lld", (unsigned long long)in->layout.fl_object_size);
+  return snprintf(val, size, "%lld", (unsigned long long)in->layout.object_size);
 }
 size_t Client::_vxattrcb_layout_pool(Inode *in, char *val, size_t size)
 {
   size_t r;
   objecter->with_osdmap([&](const OSDMap& o) {
-      if (o.have_pg_pool(in->layout.fl_pg_pool))
+      if (o.have_pg_pool(in->layout.pool_id))
 	r = snprintf(val, size, "%s", o.get_pool_name(
-		       in->layout.fl_pg_pool).c_str());
+		       in->layout.pool_id).c_str());
       else
-	r = snprintf(val, size, "%" PRIu64, (uint64_t)in->layout.fl_pg_pool);
+	r = snprintf(val, size, "%" PRIu64, (uint64_t)in->layout.pool_id);
     });
   return r;
 }
+size_t Client::_vxattrcb_layout_pool_namespace(Inode *in, char *val, size_t size)
+{
+  return snprintf(val, size, "%s", in->layout.pool_ns.c_str());
+}
 size_t Client::_vxattrcb_dir_entries(Inode *in, char *val, size_t size)
 {
   return snprintf(val, size, "%lld", (unsigned long long)(in->dirstat.nfiles + in->dirstat.nsubdirs));
@@ -10090,6 +10168,7 @@ const Client::VXattr Client::_dir_vxattrs[] = {
   XATTR_LAYOUT_FIELD(dir, layout, stripe_count),
   XATTR_LAYOUT_FIELD(dir, layout, object_size),
   XATTR_LAYOUT_FIELD(dir, layout, pool),
+  XATTR_LAYOUT_FIELD(dir, layout, pool_namespace),
   XATTR_NAME_CEPH(dir, entries),
   XATTR_NAME_CEPH(dir, files),
   XATTR_NAME_CEPH(dir, subdirs),
@@ -10122,6 +10201,7 @@ const Client::VXattr Client::_file_vxattrs[] = {
   XATTR_LAYOUT_FIELD(file, layout, stripe_count),
   XATTR_LAYOUT_FIELD(file, layout, object_size),
   XATTR_LAYOUT_FIELD(file, layout, pool),
+  XATTR_LAYOUT_FIELD(file, layout, pool_namespace),
   { name: "" }     /* Required table terminator */
 };
 
@@ -10882,7 +10962,7 @@ int Client::ll_osdaddr(int osd, uint32_t *addr)
 uint32_t Client::ll_stripe_unit(Inode *in)
 {
   Mutex::Locker lock(client_lock);
-  return in->layout.fl_stripe_unit;
+  return in->layout.stripe_unit;
 }
 
 uint64_t Client::ll_snap_seq(Inode *in)
@@ -10891,14 +10971,14 @@ uint64_t Client::ll_snap_seq(Inode *in)
   return in->snaprealm->seq;
 }
 
-int Client::ll_file_layout(Inode *in, ceph_file_layout *layout)
+int Client::ll_file_layout(Inode *in, file_layout_t *layout)
 {
   Mutex::Locker lock(client_lock);
   *layout = in->layout;
   return 0;
 }
 
-int Client::ll_file_layout(Fh *fh, ceph_file_layout *layout)
+int Client::ll_file_layout(Fh *fh, file_layout_t *layout)
 {
   return ll_file_layout(fh->inode.get(), layout);
 }
@@ -10911,13 +10991,13 @@ int Client::ll_file_layout(Fh *fh, ceph_file_layout *layout)
    tractable and works for demonstration purposes. */
 
 int Client::ll_get_stripe_osd(Inode *in, uint64_t blockno,
-			      ceph_file_layout* layout)
+			      file_layout_t* layout)
 {
   Mutex::Locker lock(client_lock);
   inodeno_t ino = ll_get_inodeno(in);
-  uint32_t object_size = layout->fl_object_size;
-  uint32_t su = layout->fl_stripe_unit;
-  uint32_t stripe_count = layout->fl_stripe_count;
+  uint32_t object_size = layout->object_size;
+  uint32_t su = layout->stripe_unit;
+  uint32_t stripe_count = layout->stripe_count;
   uint64_t stripes_per_object = object_size / su;
 
   uint64_t stripeno = blockno / stripe_count;    // which horizontal stripe        (Y)
@@ -10928,7 +11008,7 @@ int Client::ll_get_stripe_osd(Inode *in, uint64_t blockno,
   object_t oid = file_object_t(ino, objectno);
   return objecter->with_osdmap([&](const OSDMap& o) {
       ceph_object_layout olayout =
-	o.file_to_object_layout(oid, *layout, string());
+	o.file_to_object_layout(oid, *layout);
       pg_t pg = (pg_t)olayout.ol_pgid;
       vector<int> osds;
       int primary;
@@ -10942,9 +11022,9 @@ int Client::ll_get_stripe_osd(Inode *in, uint64_t blockno,
 uint64_t Client::ll_get_internal_offset(Inode *in, uint64_t blockno)
 {
   Mutex::Locker lock(client_lock);
-  ceph_file_layout *layout=&(in->layout);
-  uint32_t object_size = layout->fl_object_size;
-  uint32_t su = layout->fl_stripe_unit;
+  file_layout_t *layout=&(in->layout);
+  uint32_t object_size = layout->object_size;
+  uint32_t su = layout->stripe_unit;
   uint64_t stripes_per_object = object_size / su;
 
   return (blockno % stripes_per_object) * su;
@@ -10967,13 +11047,7 @@ int Client::ll_opendir(Inode *in, int flags, dir_result_t** dirpp,
       return r;
   }
 
-  int r = 0;
-  if (vino.snapid == CEPH_SNAPDIR) {
-    *dirpp = new dir_result_t(in);
-  } else {
-    r = _opendir(in, dirpp, uid, gid);
-  }
-
+  int r = _opendir(in, dirpp, uid, gid);
   tout(cct) << (unsigned long)*dirpp << std::endl;
 
   ldout(cct, 3) << "ll_opendir " << vino << " = " << r << " (" << *dirpp << ")"
@@ -11029,6 +11103,9 @@ int Client::ll_open(Inode *in, int flags, Fh **fhp, int uid, int gid)
 
  out:
   Fh *fhptr = fhp ? *fhp : NULL;
+  if (fhptr) {
+    ll_unclosed_fh_set.insert(fhptr);
+  }
   tout(cct) << (unsigned long)fhptr << std::endl;
   ldout(cct, 3) << "ll_open " << vino << " " << flags << " = " << r << " (" <<
     fhptr << ")" << dendl;
@@ -11100,6 +11177,9 @@ out:
     attr->st_ino = 0;
 
   Fh *fhptr = fhp ? *fhp : NULL;
+  if (fhptr) {
+    ll_unclosed_fh_set.insert(fhptr);
+  }
   tout(cct) << (unsigned long)fhptr << std::endl;
   tout(cct) << attr->st_ino << std::endl;
   ldout(cct, 3) << "ll_create " << parent << " " << name << " 0" << oct <<
@@ -11142,7 +11222,7 @@ int Client::ll_read_block(Inode *in, uint64_t blockid,
 			  char *buf,
 			  uint64_t offset,
 			  uint64_t length,
-			  ceph_file_layout* layout)
+			  file_layout_t* layout)
 {
   Mutex::Locker lock(client_lock);
   Mutex flock("Client::ll_read_block flock");
@@ -11155,7 +11235,7 @@ int Client::ll_read_block(Inode *in, uint64_t blockid,
   bufferlist bl;
 
   objecter->read(oid,
-		 object_locator_t(layout->fl_pg_pool),
+		 object_locator_t(layout->pool_id),
 		 offset,
 		 length,
 		 vino.snapid,
@@ -11179,7 +11259,7 @@ int Client::ll_read_block(Inode *in, uint64_t blockid,
 
 int Client::ll_write_block(Inode *in, uint64_t blockid,
 			   char* buf, uint64_t offset,
-			   uint64_t length, ceph_file_layout* layout,
+			   uint64_t length, file_layout_t* layout,
 			   uint64_t snapseq, uint32_t sync)
 {
   Mutex flock("Client::ll_write_block flock");
@@ -11224,7 +11304,7 @@ int Client::ll_write_block(Inode *in, uint64_t blockid,
   client_lock.Lock();
 
   objecter->write(oid,
-		  object_locator_t(layout->fl_pg_pool),
+		  object_locator_t(layout->pool_id),
 		  offset,
 		  length,
 		  fakesnap,
@@ -11326,8 +11406,8 @@ int Client::_fallocate(Fh *fh, int mode, int64_t offset, int64_t length)
 
   Inode *in = fh->inode.get();
 
-  if (objecter->osdmap_pool_full(in->layout.fl_pg_pool)
-      && !(mode & FALLOC_FL_PUNCH_HOLE)) {
+  if (objecter->osdmap_pool_full(in->layout.pool_id) &&
+      !(mode & FALLOC_FL_PUNCH_HOLE)) {
     return -ENOSPC;
   }
 
@@ -11495,6 +11575,8 @@ int Client::ll_release(Fh *fh)
   tout(cct) << "ll_release (fh)" << std::endl;
   tout(cct) << (unsigned long)fh << std::endl;
 
+  if (ll_unclosed_fh_set.count(fh))
+    ll_unclosed_fh_set.erase(fh);
   return _release_fh(fh);
 }
 
@@ -11557,7 +11639,7 @@ void Client::ll_interrupt(void *d)
 
 // expose file layouts
 
-int Client::describe_layout(const char *relpath, ceph_file_layout *lp)
+int Client::describe_layout(const char *relpath, file_layout_t *lp)
 {
   Mutex::Locker lock(client_lock);
 
@@ -11573,7 +11655,7 @@ int Client::describe_layout(const char *relpath, ceph_file_layout *lp)
   return 0;
 }
 
-int Client::fdescribe_layout(int fd, ceph_file_layout *lp)
+int Client::fdescribe_layout(int fd, file_layout_t *lp)
 {
   Mutex::Locker lock(client_lock);
 
@@ -11650,7 +11732,7 @@ int Client::get_file_extent_osds(int fd, loff_t off, loff_t *len, vector<int>& o
    * remainder.
    */
   if (len) {
-    uint64_t su = in->layout.fl_stripe_unit;
+    uint64_t su = in->layout.stripe_unit;
     *len = su - (off % su);
   }
 
@@ -11981,7 +12063,7 @@ int Client::check_pool_perm(Inode *in, int need)
   if (!cct->_conf->client_check_pool_perm)
     return 0;
 
-  int64_t pool = in->layout.fl_pg_pool;
+  int64_t pool = in->layout.pool_id;
   int have = 0;
   while (true) {
     std::map<int64_t, int>::iterator it = pool_perms.find(pool);
@@ -12253,3 +12335,19 @@ void intrusive_ptr_release(Inode *in)
 {
   in->client->put_inode(in);
 }
+
+mds_rank_t Client::_get_random_up_mds() const
+{
+  assert(client_lock.is_locked_by_me());
+
+  std::set<mds_rank_t> up;
+  mdsmap->get_up_mds_set(up);
+
+  if (up.empty())
+    return -1;
+  std::set<mds_rank_t>::const_iterator p = up.begin();
+  for (int n = rand() % up.size(); n; n--)
+    ++p;
+  return *p;
+}
+
diff --git a/src/client/Client.h b/src/client/Client.h
index ccee486..67b5c5e 100644
--- a/src/client/Client.h
+++ b/src/client/Client.h
@@ -30,6 +30,7 @@ using std::set;
 using std::map;
 using std::fstream;
 
+#include "include/unordered_set.h"
 #include "include/unordered_map.h"
 
 #include "include/filepath.h"
@@ -56,7 +57,7 @@ using std::fstream;
 #include "InodeRef.h"
 #include "UserGroups.h"
 
-class MDSMap;
+class FSMap;
 class MonClient;
 
 class CephContext;
@@ -292,6 +293,10 @@ protected:
   map<mds_rank_t, MetaSession*> mds_sessions;  // mds -> push seq
   list<Cond*> waiting_for_mdsmap;
 
+  // FSMap, for when using mds_command
+  list<Cond*> waiting_for_fsmap;
+  FSMap *fsmap;
+
   // MDS command state
   std::map<ceph_tid_t, CommandOp> commands;
   void handle_command_reply(MCommandReply *m);
@@ -421,6 +426,8 @@ protected:
   // file handles, etc.
   interval_set<int> free_fd_set;  // unused fds
   ceph::unordered_map<int, Fh*> fd_map;
+  set<Fh*> ll_unclosed_fh_set;
+  ceph::unordered_set<dir_result_t*> opened_dirs;
   
   int get_fd() {
     int fd = free_fd_set.range_start();
@@ -568,6 +575,7 @@ protected:
 
   // messaging
   void handle_mds_map(class MMDSMap *m);
+  void handle_fs_map(class MFSMap *m);
   void handle_osd_map(class MOSDMap *m);
 
   void handle_lease(MClientLease *m);
@@ -830,6 +838,7 @@ private:
   size_t _vxattrcb_layout_stripe_count(Inode *in, char *val, size_t size);
   size_t _vxattrcb_layout_object_size(Inode *in, char *val, size_t size);
   size_t _vxattrcb_layout_pool(Inode *in, char *val, size_t size);
+  size_t _vxattrcb_layout_pool_namespace(Inode *in, char *val, size_t size);
   size_t _vxattrcb_dir_entries(Inode *in, char *val, size_t size);
   size_t _vxattrcb_dir_files(Inode *in, char *val, size_t size);
   size_t _vxattrcb_dir_subdirs(Inode *in, char *val, size_t size);
@@ -866,6 +875,9 @@ private:
   int _posix_acl_create(Inode *dir, mode_t *mode, bufferlist& xattrs_bl, int uid, int gid);
   int _posix_acl_chmod(Inode *in, mode_t mode, int uid, int gid);
   int _posix_acl_permission(Inode *in, uid_t uid, UserGroups& groups, unsigned want);
+
+  mds_rank_t _get_random_up_mds() const;
+
 public:
   int mount(const std::string &mount_root, bool require_mds=false);
   void unmount();
@@ -994,8 +1006,8 @@ public:
   int lazyio_synchronize(int fd, loff_t offset, size_t count);
 
   // expose file layout
-  int describe_layout(const char *path, ceph_file_layout* layout);
-  int fdescribe_layout(int fd, ceph_file_layout* layout);
+  int describe_layout(const char *path, file_layout_t* layout);
+  int fdescribe_layout(int fd, file_layout_t* layout);
   int get_file_stripe_address(int fd, loff_t offset, vector<entity_addr_t>& address);
   int get_file_extent_osds(int fd, loff_t off, loff_t *len, vector<int>& osds);
   int get_osd_addr(int osd, entity_addr_t& addr);
@@ -1064,11 +1076,11 @@ public:
 		struct stat *attr, Inode **out, Fh **fhp, int uid = -1,
 		int gid = -1);
   int ll_read_block(Inode *in, uint64_t blockid, char *buf,  uint64_t offset,
-		    uint64_t length, ceph_file_layout* layout);
+		    uint64_t length, file_layout_t* layout);
 
   int ll_write_block(Inode *in, uint64_t blockid,
 		     char* buf, uint64_t offset,
-		     uint64_t length, ceph_file_layout* layout,
+		     uint64_t length, file_layout_t* layout,
 		     uint64_t snapseq, uint32_t sync);
   int ll_commit_blocks(Inode *in, uint64_t offset, uint64_t length);
 
@@ -1077,7 +1089,7 @@ public:
   int ll_listxattr_chunks(Inode *in, char *names, size_t size,
 			  int *cookie, int *eol, int uid, int gid);
   uint32_t ll_stripe_unit(Inode *in);
-  int ll_file_layout(Inode *in, ceph_file_layout *layout);
+  int ll_file_layout(Inode *in, file_layout_t *layout);
   uint64_t ll_snap_seq(Inode *in);
 
   int ll_read(Fh *fh, loff_t off, loff_t len, bufferlist *bl);
@@ -1090,14 +1102,14 @@ public:
   int ll_getlk(Fh *fh, struct flock *fl, uint64_t owner);
   int ll_setlk(Fh *fh, struct flock *fl, uint64_t owner, int sleep);
   int ll_flock(Fh *fh, int cmd, uint64_t owner);
-  int ll_file_layout(Fh *fh, ceph_file_layout *layout);
+  int ll_file_layout(Fh *fh, file_layout_t *layout);
   void ll_interrupt(void *d);
   bool ll_handle_umask() {
     return acl_type != NO_ACL;
   }
 
   int ll_get_stripe_osd(struct Inode *in, uint64_t blockno,
-			ceph_file_layout* layout);
+			file_layout_t* layout);
   uint64_t ll_get_internal_offset(struct Inode *in, uint64_t blockno);
 
   int ll_num_osds(void);
diff --git a/src/client/Inode.cc b/src/client/Inode.cc
index 14ff341..51c9d62 100644
--- a/src/client/Inode.cc
+++ b/src/client/Inode.cc
@@ -329,9 +329,7 @@ void Inode::dump(Formatter *f) const
   f->dump_stream("atime") << atime;
   f->dump_int("time_warp_seq", time_warp_seq);
 
-  f->open_object_section("layout");
-  ::dump(layout, f);
-  f->close_section();
+  f->dump_object("layout", layout);
   if (is_dir()) {
     f->open_object_section("dir_layout");
     ::dump(dir_layout, f);
diff --git a/src/client/Inode.h b/src/client/Inode.h
index dd2ad99..c92b103 100644
--- a/src/client/Inode.h
+++ b/src/client/Inode.h
@@ -177,7 +177,7 @@ struct Inode {
 
   // file (data access)
   ceph_dir_layout dir_layout;
-  ceph_file_layout layout;
+  file_layout_t layout;
   uint64_t   size;        // on directory, # dentries
   uint32_t   truncate_seq;
   uint64_t   truncate_size;
@@ -205,10 +205,7 @@ struct Inode {
   bool is_file()    const { return (mode & S_IFMT) == S_IFREG; }
 
   bool has_dir_layout() const {
-    for (unsigned c = 0; c < sizeof(layout); c++)
-      if (*((const char *)&layout + c))
-	return true;
-    return false;
+    return layout != file_layout_t();
   }
 
   __u32 hash_dentry_name(const string &dn) {
@@ -298,7 +295,7 @@ struct Inode {
 
   xlist<MetaRequest*> unsafe_ops;
 
-  Inode(Client *c, vinodeno_t vino, ceph_file_layout *newlayout)
+  Inode(Client *c, vinodeno_t vino, file_layout_t *newlayout)
     : client(c), ino(vino.ino), snapid(vino.snapid), faked_ino(0),
       rdev(0), mode(0), uid(0), gid(0), nlink(0),
       size(0), truncate_seq(1), truncate_size(-1),
@@ -312,14 +309,13 @@ struct Inode {
       snap_caps(0), snap_cap_refs(0),
       cap_item(this), flushing_cap_item(this),
       snaprealm(0), snaprealm_item(this),
-      oset((void *)this, newlayout->fl_pg_pool, ino),
+      oset((void *)this, newlayout->pool_id, ino),
       reported_size(0), wanted_max_size(0), requested_max_size(0),
       _ref(0), ll_ref(0), dir(0), dn_set(),
       fcntl_locks(NULL), flock_locks(NULL),
       async_err(0)
   {
     memset(&dir_layout, 0, sizeof(dir_layout));
-    memset(&layout, 0, sizeof(layout));
     memset(&quota, 0, sizeof(quota));
   }
   ~Inode() { }
diff --git a/src/client/MetaRequest.h b/src/client/MetaRequest.h
index d21e5c5..8098a0f 100644
--- a/src/client/MetaRequest.h
+++ b/src/client/MetaRequest.h
@@ -73,7 +73,6 @@ public:
   xlist<MetaRequest*>::item unsafe_item;
   xlist<MetaRequest*>::item unsafe_dir_item;
   xlist<MetaRequest*>::item unsafe_target_item;
-  Mutex lock; //for get/set sync
 
   Cond  *caller_cond;          // who to take up
   Cond  *dispatch_cond;        // who to kick back
@@ -97,7 +96,6 @@ public:
     readdir_offset(0), readdir_end(false), readdir_num(0),
     got_unsafe(false), item(this), unsafe_item(this),
     unsafe_dir_item(this), unsafe_target_item(this),
-    lock("MetaRequest lock"),
     caller_cond(0), dispatch_cond(0) {
     memset(&head, 0, sizeof(ceph_mds_request_head));
     head.op = op;
diff --git a/src/client/SyntheticClient.cc b/src/client/SyntheticClient.cc
index 8a84a48..78fd7ce 100644
--- a/src/client/SyntheticClient.cc
+++ b/src/client/SyntheticClient.cc
@@ -2401,13 +2401,8 @@ int SyntheticClient::object_rw(int nobj, int osize, int wrpc,
 int SyntheticClient::read_random(string& fn, int size, int rdsize)   // size is in MB, wrsize in bytes
 {
   uint64_t chunks = (uint64_t)size * (uint64_t)(1024*1024) / (uint64_t)rdsize;
-
   int fd = client->open(fn.c_str(), O_RDWR);
   dout(5) << "reading from " << fn << " fd " << fd << dendl;
-   
- // dout(0) << "READING FROM  " << fn << " fd " << fd << dendl;
-
- // dout(0) << "filename " << fn << " size:" << size  << " read size|" << rdsize << "|" <<  "\ chunks: |" << chunks <<"|" <<  dendl;
 
   if (fd < 0) return fd;
   int offset = 0;
@@ -2425,97 +2420,70 @@ int SyntheticClient::read_random(string& fn, int size, int rdsize)   // size is
     // use rand instead ??
     double x = drand48();
 
-    //dout(0) << "RANDOM NUMBER RETURN |" << x << "|" << dendl;
-
     // cleanup before call 'new'
     if (buf != NULL) {
 	delete[] buf;
 	buf = NULL;
     }
-    if ( x < 0.5) 
-    {
-        //dout(0) << "DECIDED TO READ " << x << dendl;
+    if (x < 0.5) {
         buf = new char[rdsize]; 
         memset(buf, 1, rdsize);
         read=true;
-    }
-    else
-    {
-       // dout(0) << "DECIDED TO WRITE " << x << dendl;
+    } else {
         buf = new char[rdsize+100];   // 1 MB
         memset(buf, 7, rdsize);
     }
-
-    //double  y  = drand48() ;
-
-    //dout(0) << "OFFSET is |" << offset << "| chunks |" << chunks<<  dendl;
     
-    if ( read)
-    {
+    if (read) {
         offset=(rand())%(chunks+1);
         dout(2) << "reading block " << offset << "/" << chunks << dendl;
 
-        int r = client->read(fd, buf, rdsize,
-                        offset*rdsize);
+        int r = client->read(fd, buf, rdsize, offset*rdsize);
         if (r < rdsize) {
-                  dout(1) << "read_file got r = " << r << ", probably end of file" << dendl;
-    }
-    }
-    else
-    {
-        dout(2) << "writing block " << offset << "/" << chunks << dendl;
-
-    // fill buf with a 16 byte fingerprint
-    // 64 bits : file offset
-    // 64 bits : client id
-    // = 128 bits (16 bytes)
-
-      //if (true )
-      //{
-      //int count = rand()%10;
+	  dout(1) << "read_file got r = " << r << ", probably end of file" << dendl;
+	}
+    } else {
+      dout(2) << "writing block " << offset << "/" << chunks << dendl;
 
-      //for ( int j=0;j<count; j++ )
-      //{
+      // fill buf with a 16 byte fingerprint
+      // 64 bits : file offset
+      // 64 bits : client id
+      // = 128 bits (16 bytes)
 
       offset=(rand())%(chunks+1);
-    uint64_t *p = (uint64_t*)buf;
-    while ((char*)p < buf + rdsize) {
-      *p = offset*rdsize + (char*)p - buf;      
-      p++;
-      *p = client->get_nodeid().v;
-      p++;
-    }
+      uint64_t *p = (uint64_t*)buf;
+      while ((char*)p < buf + rdsize) {
+	*p = offset*rdsize + (char*)p - buf;      
+	p++;
+	*p = client->get_nodeid().v;
+	p++;
+      }
 
       client->write(fd, buf, rdsize,
                         offset*rdsize);
-      //}
-      //}
     }
 
     // verify fingerprint
-    if ( read )
-    {
-    int bad = 0;
-    int64_t *p = (int64_t*)buf;
-    int64_t readoff, readclient;
-    while ((char*)p + 32 < buf + rdsize) {
-      readoff = *p;
-      int64_t wantoff = offset*rdsize + (int64_t)((char*)p - buf);
-      p++;
-      readclient = *p;
-      p++;
-      if (readoff != wantoff ||
-	  readclient != client->get_nodeid()) {
-        if (!bad)
-          dout(0) << "WARNING: wrong data from OSD, block says fileoffset=" << readoff << " client=" << readclient
-		  << ", should be offset " << wantoff << " clietn " << client->get_nodeid()
-		  << dendl;
-        bad++;
+    if (read) {
+      int bad = 0;
+      int64_t *p = (int64_t*)buf;
+      while ((char*)p + 32 < buf + rdsize) {
+	int64_t readoff = *p;
+	int64_t wantoff = offset*rdsize + (int64_t)((char*)p - buf);
+	p++;
+	int64_t readclient = *p;
+	p++;
+	if (readoff != wantoff || readclient != client->get_nodeid()) {
+	  if (!bad)
+	    dout(0) << "WARNING: wrong data from OSD, block says fileoffset=" << readoff << " client=" << readclient
+		    << ", should be offset " << wantoff << " clietn " << client->get_nodeid()
+		    << dendl;
+	  bad++;
+	}
       }
+      if (bad) 
+	dout(0) << " + " << (bad-1) << " other bad 16-byte bits in this block" << dendl;
     }
-    if (bad) 
-      dout(0) << " + " << (bad-1) << " other bad 16-byte bits in this block" << dendl;
-  }
   }
   
   client->close(fd);
@@ -2524,19 +2492,6 @@ int SyntheticClient::read_random(string& fn, int size, int rdsize)   // size is
   return 0;
 }
 
-
-//#include<stdio.h>
-//#include<stdlib.h>
-
-int normdist(int min, int max, int stdev) /* specifies input values */;
-//main()
-//{
- // for ( int i=0; i < 10; i++ )
- //  normdist ( 0 , 10, 1 );
-   
-//}
-
-
 int normdist(int min, int max, int stdev) /* specifies input values */
 {
   /* min: Minimum value; max: Maximum value; stdev: degree of deviation */
@@ -2574,14 +2529,9 @@ int normdist(int min, int max, int stdev) /* specifies input values */
 int SyntheticClient::read_random_ex(string& fn, int size, int rdsize)   // size is in MB, wrsize in bytes
 {
   uint64_t chunks = (uint64_t)size * (uint64_t)(1024*1024) / (uint64_t)rdsize;
-  
   int fd = client->open(fn.c_str(), O_RDWR);
   dout(5) << "reading from " << fn << " fd " << fd << dendl;
   
-  // dout(0) << "READING FROM  " << fn << " fd " << fd << dendl;
-  
-  // dout(0) << "filename " << fn << " size:" << size  << " read size|" << rdsize << "|" <<  "\ chunks: |" << chunks <<"|" <<  dendl;
-  
   if (fd < 0) return fd;
   int offset = 0;
   char * buf = NULL;
@@ -2598,53 +2548,29 @@ int SyntheticClient::read_random_ex(string& fn, int size, int rdsize)   // size
     // use rand instead ??
     double x = drand48();
     
-    //dout(0) << "RANDOM NUMBER RETURN |" << x << "|" << dendl;
-    
     // cleanup before call 'new'
     if (buf != NULL) {
-	delete[] buf;
-	buf = NULL;
+      delete[] buf;
+      buf = NULL;
+    }
+    if (x < 0.5) {
+      buf = new char[rdsize]; 
+      memset(buf, 1, rdsize);
+      read=true;
+    } else {
+      buf = new char[rdsize+100];   // 1 MB
+      memset(buf, 7, rdsize);
     }
-    if ( x < 0.5) 
-      {
-        //dout(0) << "DECIDED TO READ " << x << dendl;
-        buf = new char[rdsize]; 
-        memset(buf, 1, rdsize);
-        read=true;
-      }
-    else
-      {
-	// dout(0) << "DECIDED TO WRITE " << x << dendl;
-        buf = new char[rdsize+100];   // 1 MB
-        memset(buf, 7, rdsize);
-      }
-    
-    //double  y  = drand48() ;
-    
-    //dout(0) << "OFFSET is |" << offset << "| chunks |" << chunks<<  dendl;
     
-    if ( read)
-      {
-        //offset=(rand())%(chunks+1);
+    if (read) {
+      dout(2) << "reading block " << offset << "/" << chunks << dendl;
 	
-	/*    if ( chunks > 10000 ) 
-	      offset= normdist( 0 , chunks/1000 , 5  )*1000;
-	      else if ( chunks > 1000 )
-	      offset= normdist( 0 , chunks/100 , 5  )*100;
-	      else if ( chunks > 100 )
-	      offset= normdist( 0 , chunks/20 , 5  )*20;*/
-	
-	
-        dout(2) << "reading block " << offset << "/" << chunks << dendl;
-	
-        int r = client->read(fd, buf, rdsize,
+      int r = client->read(fd, buf, rdsize,
 			     offset*rdsize);
-        if (r < rdsize) {
-	  dout(1) << "read_file got r = " << r << ", probably end of file" << dendl;
-	}
+      if (r < rdsize) {
+	dout(1) << "read_file got r = " << r << ", probably end of file" << dendl;
       }
-    else
-      {
+    } else {
         dout(2) << "writing block " << offset << "/" << chunks << dendl;
 	
 	// fill buf with a 16 byte fingerprint
@@ -2652,52 +2578,43 @@ int SyntheticClient::read_random_ex(string& fn, int size, int rdsize)   // size
 	// 64 bits : client id
 	// = 128 bits (16 bytes)
 	
-	//if (true )
-	//{
 	int count = rand()%10;
 	
-	for ( int j=0;j<count; j++ )
-	  {
-	    
-	    offset=(rand())%(chunks+1);
-	    uint64_t *p = (uint64_t*)buf;
-	    while ((char*)p < buf + rdsize) {
-	      *p = offset*rdsize + (char*)p - buf;      
-	      p++;
-	      *p = client->get_nodeid().v;
-	      p++;
-	    }
-	    
-	    client->write(fd, buf, rdsize,
-			  offset*rdsize);
+	for ( int j=0;j<count; j++ ) {
+	  offset=(rand())%(chunks+1);
+	  uint64_t *p = (uint64_t*)buf;
+	  while ((char*)p < buf + rdsize) {
+	    *p = offset*rdsize + (char*)p - buf;      
+	    p++;
+	    *p = client->get_nodeid().v;
+	    p++;
 	  }
-	//}
-      }
+	    
+	  client->write(fd, buf, rdsize, offset*rdsize);
+	}
+    }
     
     // verify fingerprint
-    if ( read )
-      {
-	int bad = 0;
-	int64_t *p = (int64_t*)buf;
-	int64_t readoff, readclient;
-	while ((char*)p + 32 < buf + rdsize) {
-	  readoff = *p;
-	  int64_t wantoff = offset*rdsize + (int64_t)((char*)p - buf);
-	  p++;
-	  readclient = *p;
-	  p++;
-	  if (readoff != wantoff ||
-	      readclient != client->get_nodeid()) {
-	    if (!bad)
-	      dout(0) << "WARNING: wrong data from OSD, block says fileoffset=" << readoff << " client=" << readclient
-		      << ", should be offset " << wantoff << " clietn " << client->get_nodeid()
-		      << dendl;
-	    bad++;
-	  }
+    if (read) {
+      int bad = 0;
+      int64_t *p = (int64_t*)buf;
+      while ((char*)p + 32 < buf + rdsize) {
+	int64_t readoff = *p;
+	int64_t wantoff = offset*rdsize + (int64_t)((char*)p - buf);
+	p++;
+	int64_t readclient = *p;
+	p++;
+	if (readoff != wantoff || readclient != client->get_nodeid()) { 
+	  if (!bad)
+	    dout(0) << "WARNING: wrong data from OSD, block says fileoffset=" << readoff << " client=" << readclient
+		    << ", should be offset " << wantoff << " clietn " << client->get_nodeid()
+		    << dendl;
+	  bad++;
 	}
-	if (bad) 
-	  dout(0) << " + " << (bad-1) << " other bad 16-byte bits in this block" << dendl;
       }
+      if (bad) 
+	dout(0) << " + " << (bad-1) << " other bad 16-byte bits in this block" << dendl;
+    }
   }
   
   client->close(fd);
diff --git a/src/client/fuse_ll.cc b/src/client/fuse_ll.cc
index bc55ffd..c6e533b 100644
--- a/src/client/fuse_ll.cc
+++ b/src/client/fuse_ll.cc
@@ -328,11 +328,33 @@ static void fuse_ll_mkdir(fuse_req_t req, fuse_ino_t parent, const char *name,
 {
   CephFuse::Handle *cfuse = fuse_ll_req_prepare(req);
   const struct fuse_ctx *ctx = fuse_req_ctx(req);
-  Inode *i2, *i1 = cfuse->iget(parent);
+  Inode *i2, *i1;
   struct fuse_entry_param fe;
 
   memset(&fe, 0, sizeof(fe));
 
+#ifdef HAVE_SYS_SYNCFS
+  if (cfuse->fino_snap(parent) == CEPH_SNAPDIR &&
+      cfuse->client->cct->_conf->fuse_multithreaded &&
+      cfuse->client->cct->_conf->fuse_syncfs_on_mksnap) {
+    int err = 0;
+    int fd = ::open(cfuse->mountpoint, O_RDONLY | O_DIRECTORY);
+    if (fd < 0) {
+      err = -errno;
+    } else {
+      int r = ::syncfs(fd);
+      if (r < 0)
+	err = -errno;
+      ::close(fd);
+    }
+    if (err) {
+      fuse_reply_err(req, err);
+      return;
+    }
+  }
+#endif
+
+  i1 = cfuse->iget(parent);
   int r = cfuse->client->ll_mkdir(i1, name, mode, &fe.attr, &i2, ctx->uid,
 				  ctx->gid);
   if (r == 0) {
@@ -507,14 +529,14 @@ static void fuse_ll_ioctl(fuse_req_t req, fuse_ino_t ino, int cmd, void *arg, st
 
   switch(cmd) {
     case CEPH_IOC_GET_LAYOUT: {
-      struct ceph_file_layout layout;
+      file_layout_t layout;
       struct ceph_ioctl_layout l;
       Fh *fh = (Fh*)fi->fh;
       cfuse->client->ll_file_layout(fh, &layout);
-      l.stripe_unit = layout.fl_stripe_unit;
-      l.stripe_count = layout.fl_stripe_count;
-      l.object_size = layout.fl_object_size;
-      l.data_pool = layout.fl_pg_pool;
+      l.stripe_unit = layout.stripe_unit;
+      l.stripe_count = layout.stripe_count;
+      l.object_size = layout.object_size;
+      l.data_pool = layout.pool_id;
       fuse_reply_ioctl(req, 0, &l, sizeof(struct ceph_ioctl_layout));
     }
     break;
@@ -1045,6 +1067,9 @@ int CephFuse::Handle::loop()
 
 uint64_t CephFuse::Handle::fino_snap(uint64_t fino)
 {
+  if (fino == FUSE_ROOT_ID)
+    return CEPH_NOSNAP;
+
   if (client->use_faked_inos()) {
     vinodeno_t vino  = client->map_faked_ino(fino);
     return vino.snapid;
@@ -1058,11 +1083,12 @@ uint64_t CephFuse::Handle::fino_snap(uint64_t fino)
 
 Inode * CephFuse::Handle::iget(fuse_ino_t fino)
 {
+  if (fino == FUSE_ROOT_ID)
+    return client->get_root();
+
   if (client->use_faked_inos()) {
     return client->ll_get_inode((ino_t)fino);
   } else {
-    if (fino == 1)
-      fino = inodeno_t(client->get_root_ino());
     vinodeno_t vino(FINO_INO(fino), fino_snap(fino));
     return client->ll_get_inode(vino);
   }
@@ -1077,8 +1103,14 @@ uint64_t CephFuse::Handle::make_fake_ino(inodeno_t ino, snapid_t snapid)
 {
   if (client->use_faked_inos()) {
     // already faked by libcephfs
+    if (ino == client->get_root_ino())
+      return FUSE_ROOT_ID;
+
     return ino;
   } else {
+    if (snapid == CEPH_NOSNAP && ino == client->get_root_ino())
+      return FUSE_ROOT_ID;
+
     Mutex::Locker l(stag_lock);
     uint64_t stag;
     if (snap_stag_map.count(snapid) == 0) {
diff --git a/src/cls/Makefile-client.am b/src/cls/Makefile-client.am
index 642d167..3e26db0 100644
--- a/src/cls/Makefile-client.am
+++ b/src/cls/Makefile-client.am
@@ -13,26 +13,26 @@ libcls_refcount_client_la_SOURCES = \
 noinst_LTLIBRARIES += libcls_refcount_client.la
 DENCODER_DEPS += libcls_refcount_client.la
 
-libcls_version_client_a_SOURCES =  \
+libcls_version_client_la_SOURCES =  \
 	cls/version/cls_version_client.cc \
 	cls/version/cls_version_types.cc
-noinst_LIBRARIES += libcls_version_client.a
+noinst_LTLIBRARIES += libcls_version_client.la
 
-libcls_log_client_a_SOURCES = cls/log/cls_log_client.cc
-noinst_LIBRARIES += libcls_log_client.a
+libcls_log_client_la_SOURCES = cls/log/cls_log_client.cc
+noinst_LTLIBRARIES += libcls_log_client.la
 
-libcls_statelog_client_a_SOURCES = cls/statelog/cls_statelog_client.cc
-noinst_LIBRARIES += libcls_statelog_client.a
+libcls_statelog_client_la_SOURCES = cls/statelog/cls_statelog_client.cc
+noinst_LTLIBRARIES += libcls_statelog_client.la
 
-libcls_timeindex_client_a_SOURCES = cls/timeindex/cls_timeindex_client.cc
-noinst_LIBRARIES += libcls_timeindex_client.a
+libcls_timeindex_client_la_SOURCES = cls/timeindex/cls_timeindex_client.cc
+noinst_LTLIBRARIES += libcls_timeindex_client.la
 
-libcls_replica_log_client_a_SOURCES = \
+libcls_replica_log_client_la_SOURCES = \
 	cls/replica_log/cls_replica_log_types.cc \
 	cls/replica_log/cls_replica_log_ops.cc \
 	cls/replica_log/cls_replica_log_client.cc
-noinst_LIBRARIES += libcls_replica_log_client.a
-DENCODER_DEPS += libcls_replica_log_client.a
+noinst_LTLIBRARIES += libcls_replica_log_client.la
+DENCODER_DEPS += libcls_replica_log_client.la
 
 libcls_rgw_client_la_SOURCES = \
 	cls/rgw/cls_rgw_client.cc \
@@ -47,12 +47,12 @@ libcls_rbd_client_la_SOURCES = \
 noinst_LTLIBRARIES += libcls_rbd_client.la
 DENCODER_DEPS += libcls_rbd_client.la
 
-libcls_user_client_a_SOURCES = cls/user/cls_user_client.cc \
+libcls_user_client_la_SOURCES = cls/user/cls_user_client.cc \
 	cls/user/cls_user_types.cc \
 	cls/user/cls_user_ops.cc
-DENCODER_DEPS += libcls_user_client.a
+DENCODER_DEPS += libcls_user_client.la
 
-noinst_LIBRARIES += libcls_user_client.a
+noinst_LTLIBRARIES += libcls_user_client.la
 
 libcls_cephfs_client_la_SOURCES = cls/cephfs/cls_cephfs_client.cc
 noinst_LTLIBRARIES += libcls_cephfs_client.la
diff --git a/src/cls/cephfs/cls_cephfs_client.cc b/src/cls/cephfs/cls_cephfs_client.cc
index dc94528..9bc97ae 100644
--- a/src/cls/cephfs/cls_cephfs_client.cc
+++ b/src/cls/cephfs/cls_cephfs_client.cc
@@ -54,7 +54,7 @@ int ClsCephFSClient::fetch_inode_accumulate_result(
   librados::IoCtx &ctx,
   const std::string &oid,
   inode_backtrace_t *backtrace,
-  ceph_file_layout *layout,
+  file_layout_t *layout,
   AccumulateResult *result)
 {
   assert(backtrace != NULL);
diff --git a/src/cls/cephfs/cls_cephfs_client.h b/src/cls/cephfs/cls_cephfs_client.h
index ddd8456..51d1223 100644
--- a/src/cls/cephfs/cls_cephfs_client.h
+++ b/src/cls/cephfs/cls_cephfs_client.h
@@ -20,7 +20,7 @@ class ClsCephFSClient
       librados::IoCtx &ctx,
       const std::string &oid,
       inode_backtrace_t *backtrace,
-      ceph_file_layout *layout,
+      file_layout_t *layout,
       AccumulateResult *result);
 
   static void build_tag_filter(
diff --git a/src/cls/hello/cls_hello.cc b/src/cls/hello/cls_hello.cc
index 878130f..2751d3c 100644
--- a/src/cls/hello/cls_hello.cc
+++ b/src/cls/hello/cls_hello.cc
@@ -3,7 +3,7 @@
 
 /*
  * This is a simple example RADOS class, designed to be usable as a
- * template from implementing new methods.
+ * template for implementing new methods.
  *
  * Our goal here is to illustrate the interface between the OSD and
  * the class and demonstrate what kinds of things a class can do.
diff --git a/src/cls/journal/cls_journal.cc b/src/cls/journal/cls_journal.cc
index f87c2b2..472b100 100644
--- a/src/cls/journal/cls_journal.cc
+++ b/src/cls/journal/cls_journal.cc
@@ -26,7 +26,8 @@ cls_method_handle_t h_journal_get_active_set;
 cls_method_handle_t h_journal_set_active_set;
 cls_method_handle_t h_journal_get_client;
 cls_method_handle_t h_journal_client_register;
-cls_method_handle_t h_journal_client_update;
+cls_method_handle_t h_journal_client_update_data;
+cls_method_handle_t h_journal_client_update_state;
 cls_method_handle_t h_journal_client_unregister;
 cls_method_handle_t h_journal_client_commit;
 cls_method_handle_t h_journal_client_list;
@@ -151,13 +152,8 @@ int expire_tags(cls_method_context_t hctx, const std::string *skip_client_id) {
         return -EIO;
       }
 
-      // cannot expire tags if a client hasn't committed yet
-      if (client.commit_position.entry_positions.empty()) {
-        return 0;
-      }
-
-      for (auto entry_position : client.commit_position.entry_positions) {
-        minimum_tag_tid = MIN(minimum_tag_tid, entry_position.tag_tid);
+      for (auto object_position : client.commit_position.object_positions) {
+        minimum_tag_tid = MIN(minimum_tag_tid, object_position.tag_tid);
       }
     }
     if (!vals.empty()) {
@@ -165,6 +161,11 @@ int expire_tags(cls_method_context_t hctx, const std::string *skip_client_id) {
     }
   } while (r == MAX_KEYS_READ);
 
+  // cannot expire tags if a client hasn't committed yet
+  if (minimum_tag_tid == std::numeric_limits<uint64_t>::max()) {
+    return 0;
+  }
+
   // compute the minimum in-use tag for each class
   std::map<uint64_t, uint64_t> minimum_tag_class_to_tids;
   typedef enum { TAG_PASS_CALCULATE_MINIMUMS,
@@ -571,8 +572,8 @@ int journal_client_register(cls_method_context_t hctx, bufferlist *in,
  * Output:
  * @returns 0 on success, negative error code on failure
  */
-int journal_client_update(cls_method_context_t hctx, bufferlist *in,
-                          bufferlist *out) {
+int journal_client_update_data(cls_method_context_t hctx, bufferlist *in,
+                               bufferlist *out) {
   std::string id;
   bufferlist data;
   try {
@@ -602,6 +603,45 @@ int journal_client_update(cls_method_context_t hctx, bufferlist *in,
 /**
  * Input:
  * @param id (string) - unique client id
+ * @param state (uint8_t) - client state
+ *
+ * Output:
+ * @returns 0 on success, negative error code on failure
+ */
+int journal_client_update_state(cls_method_context_t hctx, bufferlist *in,
+                                bufferlist *out) {
+  std::string id;
+  cls::journal::ClientState state;
+  bufferlist data;
+  try {
+    bufferlist::iterator iter = in->begin();
+    ::decode(id, iter);
+    uint8_t state_raw;
+    ::decode(state_raw, iter);
+    state = static_cast<cls::journal::ClientState>(state_raw);
+  } catch (const buffer::error &err) {
+    CLS_ERR("failed to decode input parameters: %s", err.what());
+    return -EINVAL;
+  }
+
+  std::string key(key_from_client_id(id));
+  cls::journal::Client client;
+  int r = read_key(hctx, key, &client);
+  if (r < 0) {
+    return r;
+  }
+
+  client.state = state;
+  r = write_key(hctx, key, client);
+  if (r < 0) {
+    return r;
+  }
+  return 0;
+}
+
+/**
+ * Input:
+ * @param id (string) - unique client id
  *
  * Output:
  * @returns 0 on success, negative error code on failure
@@ -665,8 +705,8 @@ int journal_client_commit(cls_method_context_t hctx, bufferlist *in,
   if (r < 0) {
     return r;
   }
-  if (commit_position.entry_positions.size() > splay_width) {
-    CLS_ERR("too many entry positions");
+  if (commit_position.object_positions.size() > splay_width) {
+    CLS_ERR("too many object positions");
     return -EINVAL;
   }
 
@@ -918,8 +958,8 @@ int journal_tag_list(cls_method_context_t hctx, bufferlist *in,
     return r;
   }
 
-  for (auto entry_position : client.commit_position.entry_positions) {
-    minimum_tag_tid = MIN(minimum_tag_tid, entry_position.tag_tid);
+  for (auto object_position : client.commit_position.object_positions) {
+    minimum_tag_tid = MIN(minimum_tag_tid, object_position.tag_tid);
   }
 
   // compute minimum tags in use per-class
@@ -928,7 +968,7 @@ int journal_tag_list(cls_method_context_t hctx, bufferlist *in,
   typedef enum { TAG_PASS_CALCULATE_MINIMUMS,
                  TAG_PASS_LIST,
                  TAG_PASS_DONE } TagPass;
-  int tag_pass = (client.commit_position.entry_positions.empty() ?
+  int tag_pass = (minimum_tag_tid == std::numeric_limits<uint64_t>::max() ?
     TAG_PASS_LIST : TAG_PASS_CALCULATE_MINIMUMS);
   std::string last_read = HEADER_KEY_TAG_PREFIX;
   do {
@@ -1069,9 +1109,14 @@ void CEPH_CLS_API __cls_init()
   cls_register_cxx_method(h_class, "client_register",
                           CLS_METHOD_RD | CLS_METHOD_WR,
                           journal_client_register, &h_journal_client_register);
-  cls_register_cxx_method(h_class, "client_update",
+  cls_register_cxx_method(h_class, "client_update_data",
+                          CLS_METHOD_RD | CLS_METHOD_WR,
+                          journal_client_update_data,
+                          &h_journal_client_update_data);
+  cls_register_cxx_method(h_class, "client_update_state",
                           CLS_METHOD_RD | CLS_METHOD_WR,
-                          journal_client_update, &h_journal_client_update);
+                          journal_client_update_state,
+                          &h_journal_client_update_state);
   cls_register_cxx_method(h_class, "client_unregister",
                           CLS_METHOD_RD | CLS_METHOD_WR,
                           journal_client_unregister,
diff --git a/src/cls/journal/cls_journal_client.cc b/src/cls/journal/cls_journal_client.cc
index 3295964..7fbfb51 100644
--- a/src/cls/journal/cls_journal_client.cc
+++ b/src/cls/journal/cls_journal_client.cc
@@ -274,28 +274,45 @@ void client_register(librados::ObjectWriteOperation *op,
   op->exec("journal", "client_register", bl);
 }
 
-int client_update(librados::IoCtx &ioctx, const std::string &oid,
-                  const std::string &id, const bufferlist &data) {
+int client_update_data(librados::IoCtx &ioctx, const std::string &oid,
+                       const std::string &id, const bufferlist &data) {
   librados::ObjectWriteOperation op;
-  client_update(&op, id, data);
+  client_update_data(&op, id, data);
   return ioctx.operate(oid, &op);
 }
 
-void client_update(librados::ObjectWriteOperation *op,
-                   const std::string &id, const bufferlist &data) {
+void client_update_data(librados::ObjectWriteOperation *op,
+                        const std::string &id, const bufferlist &data) {
   bufferlist bl;
   ::encode(id, bl);
   ::encode(data, bl);
-  op->exec("journal", "client_update", bl);
+  op->exec("journal", "client_update_data", bl);
+}
+
+int client_update_state(librados::IoCtx &ioctx, const std::string &oid,
+                        const std::string &id, cls::journal::ClientState state) {
+  bufferlist bl;
+  ::encode(id, bl);
+  ::encode(static_cast<uint8_t>(state), bl);
+
+  librados::ObjectWriteOperation op;
+  op.exec("journal", "client_update_state", bl);
+  return ioctx.operate(oid, &op);
 }
 
 int client_unregister(librados::IoCtx &ioctx, const std::string &oid,
                        const std::string &id) {
-  bufferlist inbl;
-  ::encode(id, inbl);
+  librados::ObjectWriteOperation op;
+  client_unregister(&op, id);
+  return ioctx.operate(oid, &op);
+}
 
-  bufferlist outbl;
-  return ioctx.exec(oid, "journal", "client_unregister", inbl, outbl);
+void client_unregister(librados::ObjectWriteOperation *op,
+		       const std::string &id) {
+
+  bufferlist bl;
+  ::encode(id, bl);
+  op->exec("journal", "client_unregister", bl);
 }
 
 void client_commit(librados::ObjectWriteOperation *op, const std::string &id,
diff --git a/src/cls/journal/cls_journal_client.h b/src/cls/journal/cls_journal_client.h
index 37b0143..94ba4b2 100644
--- a/src/cls/journal/cls_journal_client.h
+++ b/src/cls/journal/cls_journal_client.h
@@ -45,13 +45,17 @@ int client_register(librados::IoCtx &ioctx, const std::string &oid,
 void client_register(librados::ObjectWriteOperation *op,
                      const std::string &id, const bufferlist &data);
 
-int client_update(librados::IoCtx &ioctx, const std::string &oid,
-                  const std::string &id, const bufferlist &data);
-void client_update(librados::ObjectWriteOperation *op,
-                   const std::string &id, const bufferlist &data);
+int client_update_data(librados::IoCtx &ioctx, const std::string &oid,
+                       const std::string &id, const bufferlist &data);
+void client_update_data(librados::ObjectWriteOperation *op,
+                        const std::string &id, const bufferlist &data);
+int client_update_state(librados::IoCtx &ioctx, const std::string &oid,
+                        const std::string &id, cls::journal::ClientState state);
 
 int client_unregister(librados::IoCtx &ioctx, const std::string &oid,
                       const std::string &id);
+void client_unregister(librados::ObjectWriteOperation *op,
+		       const std::string &id);
 
 void client_commit(librados::ObjectWriteOperation *op, const std::string &id,
                    const cls::journal::ObjectSetPosition &commit_position);
diff --git a/src/cls/journal/cls_journal_types.cc b/src/cls/journal/cls_journal_types.cc
index 8a94d10..6dd5664 100644
--- a/src/cls/journal/cls_journal_types.cc
+++ b/src/cls/journal/cls_journal_types.cc
@@ -2,56 +2,56 @@
 // vim: ts=8 sw=2 smarttab
 
 #include "cls/journal/cls_journal_types.h"
+#include "include/stringify.h"
 #include "common/Formatter.h"
 
 namespace cls {
 namespace journal {
 
-void EntryPosition::encode(bufferlist& bl) const {
+void ObjectPosition::encode(bufferlist& bl) const {
   ENCODE_START(1, 1, bl);
+  ::encode(object_number, bl);
   ::encode(tag_tid, bl);
   ::encode(entry_tid, bl);
   ENCODE_FINISH(bl);
 }
 
-void EntryPosition::decode(bufferlist::iterator& iter) {
+void ObjectPosition::decode(bufferlist::iterator& iter) {
   DECODE_START(1, iter);
+  ::decode(object_number, iter);
   ::decode(tag_tid, iter);
   ::decode(entry_tid, iter);
   DECODE_FINISH(iter);
 }
 
-void EntryPosition::dump(Formatter *f) const {
+void ObjectPosition::dump(Formatter *f) const {
+  f->dump_unsigned("object_number", object_number);
   f->dump_unsigned("tag_tid", tag_tid);
   f->dump_unsigned("entry_tid", entry_tid);
 }
 
-void EntryPosition::generate_test_instances(std::list<EntryPosition *> &o) {
-  o.push_back(new EntryPosition());
-  o.push_back(new EntryPosition(1, 2));
+void ObjectPosition::generate_test_instances(std::list<ObjectPosition *> &o) {
+  o.push_back(new ObjectPosition());
+  o.push_back(new ObjectPosition(1, 2, 3));
 }
 
 void ObjectSetPosition::encode(bufferlist& bl) const {
   ENCODE_START(1, 1, bl);
-  ::encode(object_number, bl);
-  ::encode(entry_positions, bl);
+  ::encode(object_positions, bl);
   ENCODE_FINISH(bl);
 }
 
 void ObjectSetPosition::decode(bufferlist::iterator& iter) {
   DECODE_START(1, iter);
-  ::decode(object_number, iter);
-  ::decode(entry_positions, iter);
+  ::decode(object_positions, iter);
   DECODE_FINISH(iter);
 }
 
 void ObjectSetPosition::dump(Formatter *f) const {
-  f->dump_unsigned("object_number", object_number);
-  f->open_array_section("entry_positions");
-  for (EntryPositions::const_iterator it = entry_positions.begin();
-       it != entry_positions.end(); ++it) {
-    f->open_object_section("entry_position");
-    it->dump(f);
+  f->open_array_section("object_positions");
+  for (auto &pos : object_positions) {
+    f->open_object_section("object_position");
+    pos.dump(f);
     f->close_section();
   }
   f->close_section();
@@ -60,7 +60,7 @@ void ObjectSetPosition::dump(Formatter *f) const {
 void ObjectSetPosition::generate_test_instances(
     std::list<ObjectSetPosition *> &o) {
   o.push_back(new ObjectSetPosition());
-  o.push_back(new ObjectSetPosition(1, {{1, 120}, {2, 121}}));
+  o.push_back(new ObjectSetPosition({{0, 1, 120}, {121, 2, 121}}));
 }
 
 void Client::encode(bufferlist& bl) const {
@@ -68,6 +68,7 @@ void Client::encode(bufferlist& bl) const {
   ::encode(id, bl);
   ::encode(data, bl);
   ::encode(commit_position, bl);
+  ::encode(static_cast<uint8_t>(state), bl);
   ENCODE_FINISH(bl);
 }
 
@@ -76,6 +77,10 @@ void Client::decode(bufferlist::iterator& iter) {
   ::decode(id, iter);
   ::decode(data, iter);
   ::decode(commit_position, iter);
+
+  uint8_t state_raw;
+  ::decode(state_raw, iter);
+  state = static_cast<ClientState>(state_raw);
   DECODE_FINISH(iter);
 }
 
@@ -89,6 +94,8 @@ void Client::dump(Formatter *f) const {
   f->open_object_section("commit_position");
   commit_position.dump(f);
   f->close_section();
+
+  f->dump_string("state", stringify(state));
 }
 
 void Client::generate_test_instances(std::list<Client *> &o) {
@@ -97,7 +104,7 @@ void Client::generate_test_instances(std::list<Client *> &o) {
 
   o.push_back(new Client());
   o.push_back(new Client("id", data));
-  o.push_back(new Client("id", data, {1, {{1, 120}, {2, 121}}}));
+  o.push_back(new Client("id", data, {{{1, 2, 120}, {2, 3, 121}}}));
 }
 
 void Tag::encode(bufferlist& bl) const {
@@ -133,20 +140,36 @@ void Tag::generate_test_instances(std::list<Tag *> &o) {
   o.push_back(new Tag(123, 234, data));
 }
 
+std::ostream &operator<<(std::ostream &os, const ClientState &state) {
+  switch (state) {
+  case CLIENT_STATE_CONNECTED:
+    os << "connected";
+    break;
+  case CLIENT_STATE_DISCONNECTED:
+    os << "disconnected";
+    break;
+  default:
+    os << "unknown (" << static_cast<uint32_t>(state) << ")";
+    break;
+  }
+  return os;
+}
+
 std::ostream &operator<<(std::ostream &os,
-                         const EntryPosition &entry_position) {
-  os << "[tag_tid=" << entry_position.tag_tid << ", entry_tid="
-     << entry_position.entry_tid << "]";
+                         const ObjectPosition &object_position) {
+  os << "["
+     << "object_number=" << object_position.object_number << ", "
+     << "tag_tid=" << object_position.tag_tid << ", "
+     << "entry_tid=" << object_position.entry_tid << "]";
   return os;
 }
 
 std::ostream &operator<<(std::ostream &os,
                          const ObjectSetPosition &object_set_position) {
-  os << "[object_number=" << object_set_position.object_number << ", "
-     << "positions=[";
+  os << "[positions=[";
   std::string delim;
-  for (auto &entry_position : object_set_position.entry_positions) {
-    os << entry_position << delim;
+  for (auto &object_position : object_set_position.object_positions) {
+    os << delim << object_position;
     delim = ", ";
   }
   os << "]]";
@@ -155,10 +178,8 @@ std::ostream &operator<<(std::ostream &os,
 
 std::ostream &operator<<(std::ostream &os, const Client &client) {
   os << "[id=" << client.id << ", "
-     << "data=";
-  client.data.hexdump(os);
-  os << ", "
-     << "commit_position=" << client.commit_position << "]";
+     << "commit_position=" << client.commit_position << ", "
+     << "state=" << client.state << "]";
   return os;
 }
 
diff --git a/src/cls/journal/cls_journal_types.h b/src/cls/journal/cls_journal_types.h
index 19a1fcb..0381aff 100644
--- a/src/cls/journal/cls_journal_types.h
+++ b/src/cls/journal/cls_journal_types.h
@@ -19,69 +19,81 @@ class Formatter;
 namespace cls {
 namespace journal {
 
-struct EntryPosition {
+struct ObjectPosition {
+  uint64_t object_number;
   uint64_t tag_tid;
   uint64_t entry_tid;
 
-  EntryPosition() : tag_tid(0), entry_tid(0) {}
-  EntryPosition(uint64_t _tag_tid, uint64_t _entry_tid)
-    : tag_tid(_tag_tid), entry_tid(_entry_tid) {}
+  ObjectPosition() : object_number(0), tag_tid(0), entry_tid(0) {}
+  ObjectPosition(uint64_t _object_number, uint64_t _tag_tid,
+                 uint64_t _entry_tid)
+    : object_number(_object_number), tag_tid(_tag_tid), entry_tid(_entry_tid) {}
 
-  inline bool operator==(const EntryPosition& rhs) const {
-    return (tag_tid == rhs.tag_tid && entry_tid == rhs.entry_tid);
+  inline bool operator==(const ObjectPosition& rhs) const {
+    return (object_number == rhs.object_number &&
+            tag_tid == rhs.tag_tid &&
+            entry_tid == rhs.entry_tid);
   }
 
   void encode(bufferlist& bl) const;
   void decode(bufferlist::iterator& iter);
   void dump(Formatter *f) const;
 
-  inline bool operator<(const EntryPosition &rhs) const {
-    if (tag_tid != rhs.tag_tid) {
+  inline bool operator<(const ObjectPosition &rhs) const {
+    if (object_number != rhs.object_number) {
+      return object_number < rhs.object_number;
+    } else if (tag_tid != rhs.tag_tid) {
       return tag_tid < rhs.tag_tid;
     }
     return entry_tid < rhs.entry_tid;
   }
 
-  static void generate_test_instances(std::list<EntryPosition *> &o);
+  static void generate_test_instances(std::list<ObjectPosition *> &o);
 };
 
-typedef std::list<EntryPosition> EntryPositions;
+typedef std::list<ObjectPosition> ObjectPositions;
 
 struct ObjectSetPosition {
-  uint64_t object_number;
-  EntryPositions entry_positions;
+  // stored in most-recent -> least recent committed entry order
+  ObjectPositions object_positions;
 
-  ObjectSetPosition() : object_number(0) {}
-  ObjectSetPosition(uint64_t _object_number,
-                    const EntryPositions &_entry_positions)
-    : object_number(_object_number), entry_positions(_entry_positions) {}
+  ObjectSetPosition() {}
+  ObjectSetPosition(const ObjectPositions &_object_positions)
+    : object_positions(_object_positions) {}
 
   void encode(bufferlist& bl) const;
   void decode(bufferlist::iterator& iter);
   void dump(Formatter *f) const;
 
   inline bool operator==(const ObjectSetPosition &rhs) const {
-    return (object_number == rhs.object_number &&
-            entry_positions == rhs.entry_positions);
+    return (object_positions == rhs.object_positions);
   }
 
   static void generate_test_instances(std::list<ObjectSetPosition *> &o);
 };
 
+enum ClientState {
+  CLIENT_STATE_CONNECTED = 0,
+  CLIENT_STATE_DISCONNECTED = 1
+};
+
 struct Client {
   std::string id;
   bufferlist data;
   ObjectSetPosition commit_position;
+  ClientState state;
 
-  Client() {}
+  Client() : state(CLIENT_STATE_CONNECTED) {}
   Client(const std::string& _id, const bufferlist &_data,
-         const ObjectSetPosition &_commit_position = ObjectSetPosition())
-    : id(_id), data(_data), commit_position(_commit_position) {}
+         const ObjectSetPosition &_commit_position = ObjectSetPosition(),
+         ClientState _state = CLIENT_STATE_CONNECTED)
+    : id(_id), data(_data), commit_position(_commit_position), state(_state) {}
 
   inline bool operator==(const Client &rhs) const {
     return (id == rhs.id &&
             data.contents_equal(rhs.data) &&
-            commit_position == rhs.commit_position);
+            commit_position == rhs.commit_position &&
+            state == rhs.state);
   }
   inline bool operator<(const Client &rhs) const {
     return (id < rhs.id);
@@ -121,13 +133,14 @@ struct Tag {
   static void generate_test_instances(std::list<Tag *> &o);
 };
 
-WRITE_CLASS_ENCODER(EntryPosition);
+WRITE_CLASS_ENCODER(ObjectPosition);
 WRITE_CLASS_ENCODER(ObjectSetPosition);
 WRITE_CLASS_ENCODER(Client);
 WRITE_CLASS_ENCODER(Tag);
 
+std::ostream &operator<<(std::ostream &os, const ClientState &state);
 std::ostream &operator<<(std::ostream &os,
-                         const EntryPosition &entry_position);
+                         const ObjectPosition &object_position);
 std::ostream &operator<<(std::ostream &os,
                          const ObjectSetPosition &object_set_position);
 std::ostream &operator<<(std::ostream &os,
diff --git a/src/cls/log/cls_log.cc b/src/cls/log/cls_log.cc
index 23df866..89745bb 100644
--- a/src/cls/log/cls_log.cc
+++ b/src/cls/log/cls_log.cc
@@ -120,16 +120,20 @@ static int cls_log_add(cls_method_context_t hctx, bufferlist *in, bufferlist *ou
     string index;
 
     utime_t timestamp = entry.timestamp;
-    if (timestamp < header.max_time)
+    if (op.monotonic_inc && timestamp < header.max_time)
       timestamp = header.max_time;
     else if (timestamp > header.max_time)
       header.max_time = timestamp;
 
-    get_index(hctx, timestamp, index);
+    if (entry.id.empty()) {
+      get_index(hctx, timestamp, index);
+      entry.id = index;
+    } else {
+      index = entry.id;
+    }
 
     CLS_LOG(0, "storing entry at %s", index.c_str());
 
-    entry.id = index;
 
     if (index > header.max_marker)
       header.max_marker = index;
diff --git a/src/cls/log/cls_log_client.cc b/src/cls/log/cls_log_client.cc
index 0334deb..88e1045 100644
--- a/src/cls/log/cls_log_client.cc
+++ b/src/cls/log/cls_log_client.cc
@@ -10,7 +10,7 @@ using namespace librados;
 
 
 
-void cls_log_add(librados::ObjectWriteOperation& op, list<cls_log_entry>& entries)
+void cls_log_add(librados::ObjectWriteOperation& op, list<cls_log_entry>& entries, bool monotonic_inc)
 {
   bufferlist in;
   cls_log_add_op call;
diff --git a/src/cls/log/cls_log_client.h b/src/cls/log/cls_log_client.h
index 16229c9..c96dbb0 100644
--- a/src/cls/log/cls_log_client.h
+++ b/src/cls/log/cls_log_client.h
@@ -12,7 +12,7 @@
 void cls_log_add_prepare_entry(cls_log_entry& entry, const utime_t& timestamp,
                  const string& section, const string& name, bufferlist& bl);
 
-void cls_log_add(librados::ObjectWriteOperation& op, list<cls_log_entry>& entry);
+void cls_log_add(librados::ObjectWriteOperation& op, list<cls_log_entry>& entries, bool monotonic_inc);
 void cls_log_add(librados::ObjectWriteOperation& op, cls_log_entry& entry);
 void cls_log_add(librados::ObjectWriteOperation& op, const utime_t& timestamp,
                  const string& section, const string& name, bufferlist& bl);
diff --git a/src/cls/log/cls_log_ops.h b/src/cls/log/cls_log_ops.h
index ad251fd..3c91523 100644
--- a/src/cls/log/cls_log_ops.h
+++ b/src/cls/log/cls_log_ops.h
@@ -9,18 +9,23 @@
 
 struct cls_log_add_op {
   list<cls_log_entry> entries;
+  bool monotonic_inc;
 
-  cls_log_add_op() {}
+  cls_log_add_op() : monotonic_inc(true) {}
 
   void encode(bufferlist& bl) const {
-    ENCODE_START(1, 1, bl);
+    ENCODE_START(2, 1, bl);
     ::encode(entries, bl);
+    ::encode(monotonic_inc, bl);
     ENCODE_FINISH(bl);
   }
 
   void decode(bufferlist::iterator& bl) {
-    DECODE_START(1, bl);
+    DECODE_START(2, bl);
     ::decode(entries, bl);
+    if (struct_v >= 2) {
+      ::decode(monotonic_inc, bl);
+    }
     DECODE_FINISH(bl);
   }
 };
diff --git a/src/cls/rbd/cls_rbd.cc b/src/cls/rbd/cls_rbd.cc
index 36271da..036ad8a 100644
--- a/src/cls/rbd/cls_rbd.cc
+++ b/src/cls/rbd/cls_rbd.cc
@@ -111,19 +111,26 @@ cls_method_handle_t h_old_snapshots_list;
 cls_method_handle_t h_old_snapshot_add;
 cls_method_handle_t h_old_snapshot_remove;
 cls_method_handle_t h_old_snapshot_rename;
-cls_method_handle_t h_mirror_is_enabled;
-cls_method_handle_t h_mirror_set_enabled;
+cls_method_handle_t h_mirror_uuid_get;
+cls_method_handle_t h_mirror_uuid_set;
+cls_method_handle_t h_mirror_mode_get;
+cls_method_handle_t h_mirror_mode_set;
 cls_method_handle_t h_mirror_peer_list;
 cls_method_handle_t h_mirror_peer_add;
 cls_method_handle_t h_mirror_peer_remove;
 cls_method_handle_t h_mirror_peer_set_client;
 cls_method_handle_t h_mirror_peer_set_cluster;
+cls_method_handle_t h_mirror_image_list;
+cls_method_handle_t h_mirror_image_get;
+cls_method_handle_t h_mirror_image_set;
+cls_method_handle_t h_mirror_image_remove;
 
 #define RBD_MAX_KEYS_READ 64
 #define RBD_SNAP_KEY_PREFIX "snapshot_"
 #define RBD_DIR_ID_KEY_PREFIX "id_"
 #define RBD_DIR_NAME_KEY_PREFIX "name_"
 #define RBD_METADATA_KEY_PREFIX "metadata_"
+#define RBD_MAX_OBJECT_MAP_OBJECT_COUNT 256000000
 
 static int snap_read_header(cls_method_context_t hctx, bufferlist& bl)
 {
@@ -200,6 +207,15 @@ static int read_key(cls_method_context_t hctx, const string &key, T *out)
   return 0;
 }
 
+static int remove_key(cls_method_context_t hctx, const string &key) {
+  int r = cls_cxx_map_remove_key(hctx, key);
+  if (r < 0 && r != -ENOENT) {
+      CLS_ERR("failed to remove key: %s", key.c_str());
+      return r;
+  }
+  return 0;
+}
+
 static bool is_valid_id(const string &id) {
   if (!id.size())
     return false;
@@ -356,8 +372,8 @@ int get_features(cls_method_context_t hctx, bufferlist *in, bufferlist *out)
  * set the image features
  *
  * Input:
- * @params features image features
- * @params mask image feature mask
+ * @param features image features
+ * @param mask image feature mask
  *
  * Output:
  * none
@@ -376,12 +392,6 @@ int set_features(cls_method_context_t hctx, bufferlist *in, bufferlist *out)
     return -EINVAL;
   }
 
-  if ((mask & RBD_FEATURES_MUTABLE) != mask) {
-    CLS_ERR("Attempting to set immutable feature: %" PRIu64,
-            mask & ~RBD_FEATURES_MUTABLE);
-    return -EINVAL;
-  }
-
   // check that features exists to make sure this is a header object
   // that was created correctly
   uint64_t orig_features = 0;
@@ -392,6 +402,21 @@ int set_features(cls_method_context_t hctx, bufferlist *in, bufferlist *out)
     return r;
   }
 
+  uint64_t enabled_features = features & mask;
+  if ((enabled_features & RBD_FEATURES_MUTABLE) != enabled_features) {
+    CLS_ERR("Attempting to enable immutable feature: %" PRIu64,
+            enabled_features & ~RBD_FEATURES_MUTABLE);
+    return -EINVAL;
+  }
+
+  uint64_t disabled_features = ~features & mask;
+  uint64_t disable_mask = (RBD_FEATURES_MUTABLE | RBD_FEATURES_DISABLE_ONLY);
+  if ((disabled_features & disable_mask) != disabled_features) {
+       CLS_ERR("Attempting to disable immutable feature: %" PRIu64,
+               enabled_features & ~disable_mask);
+       return -EINVAL;
+  }
+
   features = (orig_features & ~mask) | (features & mask);
   CLS_LOG(10, "set_features features=%" PRIu64 " orig_features=%" PRIu64,
           features, orig_features);
@@ -845,9 +870,9 @@ int get_flags(cls_method_context_t hctx, bufferlist *in, bufferlist *out)
  * set the image flags
  *
  * Input:
- * @params flags image flags
- * @params mask image flag mask
- * @params snap_id which snapshot to update, or CEPH_NOSNAP (uint64_t)
+ * @param flags image flags
+ * @param mask image flag mask
+ * @param snap_id which snapshot to update, or CEPH_NOSNAP (uint64_t)
  *
  * Output:
  * none
@@ -2234,6 +2259,12 @@ int object_map_resize(cls_method_context_t hctx, bufferlist *in, bufferlist *out
     return -EINVAL;
   }
 
+  // protect against excessive memory requirements
+  if (object_count > RBD_MAX_OBJECT_MAP_OBJECT_COUNT) {
+    CLS_ERR("object map too large: %" PRIu64, object_count);
+    return -EINVAL;
+  }
+
   BitVector<2> object_map;
   int r = object_map_read(hctx, object_map);
   if ((r < 0) && (r != -ENOENT)) {
@@ -2925,32 +2956,30 @@ int old_snapshot_rename(cls_method_context_t hctx, bufferlist *in, bufferlist *o
 
 namespace mirror {
 
+static const std::string UUID("mirror_uuid");
+static const std::string MODE("mirror_mode");
 static const std::string PEER_KEY_PREFIX("mirror_peer_");
+static const std::string IMAGE_KEY_PREFIX("image_");
 
 std::string peer_key(const std::string &uuid) {
   return PEER_KEY_PREFIX + uuid;
 }
 
-int is_enabled(cls_method_context_t hctx, bool *enabled) {
-  bufferlist bl;
-  int r = cls_cxx_map_get_val(hctx, "mirror_enabled", &bl);
-  if (r < 0 && r != -ENOENT) {
-    CLS_ERR("error reading mirror enabled flag: %s",
-            cpp_strerror(r).c_str());
-    return r;
-  }
+std::string image_key(const string &image_id) {
+  return IMAGE_KEY_PREFIX + image_id;
+}
 
-  if (r == 0) {
-    try {
-      bufferlist::iterator bl_it = bl.begin();
-      ::decode(*enabled, bl_it);
-    } catch (const buffer::error &err) {
-      CLS_ERR("could not decode flag");
-      return -EIO;
+int uuid_get(cls_method_context_t hctx, std::string *mirror_uuid) {
+  bufferlist mirror_uuid_bl;
+  int r = cls_cxx_map_get_val(hctx, mirror::UUID, &mirror_uuid_bl);
+  if (r < 0) {
+    if (r != -ENOENT) {
+      CLS_ERR("error reading mirror uuid: %s", cpp_strerror(r).c_str());
     }
-  } else {
-    *enabled = false;
+    return r;
   }
+
+  *mirror_uuid = std::string(mirror_uuid_bl.c_str(), mirror_uuid_bl.length());
   return 0;
 }
 
@@ -2983,12 +3012,12 @@ int read_peers(cls_method_context_t hctx,
   return 0;
 }
 
-int read_peer(cls_method_context_t hctx, const std::string &uuid,
+int read_peer(cls_method_context_t hctx, const std::string &id,
               cls::rbd::MirrorPeer *peer) {
   bufferlist bl;
-  int r = cls_cxx_map_get_val(hctx, peer_key(uuid), &bl);
+  int r = cls_cxx_map_get_val(hctx, peer_key(id), &bl);
   if (r < 0) {
-    CLS_ERR("error reading peer '%s': %s", uuid.c_str(),
+    CLS_ERR("error reading peer '%s': %s", id.c_str(),
             cpp_strerror(r).c_str());
     return r;
   }
@@ -2997,20 +3026,119 @@ int read_peer(cls_method_context_t hctx, const std::string &uuid,
     bufferlist::iterator bl_it = bl.begin();
     ::decode(*peer, bl_it);
   } catch (const buffer::error &err) {
-    CLS_ERR("could not decode peer '%s'", uuid.c_str());
+    CLS_ERR("could not decode peer '%s'", id.c_str());
     return -EIO;
   }
   return 0;
 }
 
-int write_peer(cls_method_context_t hctx, const std::string &uuid,
+int write_peer(cls_method_context_t hctx, const std::string &id,
                const cls::rbd::MirrorPeer &peer) {
   bufferlist bl;
   ::encode(peer, bl);
 
-  int r = cls_cxx_map_set_val(hctx, peer_key(uuid), &bl);
+  int r = cls_cxx_map_set_val(hctx, peer_key(id), &bl);
+  if (r < 0) {
+    CLS_ERR("error writing peer '%s': %s", id.c_str(),
+            cpp_strerror(r).c_str());
+    return r;
+  }
+  return 0;
+}
+
+int image_list_ids(cls_method_context_t hctx, vector<string> *image_ids) {
+  string last_read = IMAGE_KEY_PREFIX;
+  int max_read = RBD_MAX_KEYS_READ;
+  int r = max_read;
+  while (r == max_read) {
+    set<string> keys;
+    r = cls_cxx_map_get_keys(hctx, last_read, max_read, &keys);
+    if (r < 0) {
+      CLS_ERR("error reading mirrored images: %s", cpp_strerror(r).c_str());
+      return r;
+    }
+
+    for (auto &image_key : keys) {
+      if (0 != image_key.compare(0, IMAGE_KEY_PREFIX.size(), IMAGE_KEY_PREFIX)) {
+	return 0;
+      }
+      image_ids->push_back(image_key.substr(IMAGE_KEY_PREFIX.size()));
+    }
+  }
+  return 0;
+}
+
+int image_get(cls_method_context_t hctx, const string &image_id,
+	      cls::rbd::MirrorImage *mirror_image) {
+  bufferlist bl;
+  int r = cls_cxx_map_get_val(hctx, image_key(image_id), &bl);
+  if (r < 0) {
+    if (r != -ENOENT) {
+      CLS_ERR("error reading mirrored image '%s': '%s'", image_id.c_str(),
+	      cpp_strerror(r).c_str());
+    }
+    return r;
+  }
+
+  try {
+    bufferlist::iterator it = bl.begin();
+    ::decode(*mirror_image, it);
+  } catch (const buffer::error &err) {
+    CLS_ERR("could not decode mirrored image '%s'", image_id.c_str());
+    return -EIO;
+  }
+
+  return 0;
+}
+
+int image_set(cls_method_context_t hctx, const string &image_id,
+	      const cls::rbd::MirrorImage &mirror_image) {
+  bufferlist bl;
+  ::encode(mirror_image, bl);
+
+  // don't overwrite the key if it already exists with a different
+  // global_image_id
+  cls::rbd::MirrorImage existing_mirror_image;
+  int r = image_get(hctx, image_id, &existing_mirror_image);
+  if (r < 0 && r != -ENOENT) {
+    CLS_ERR("error reading mirrored image '%s': '%s'", image_id.c_str(),
+	    cpp_strerror(r).c_str());
+    return r;
+  }
+
+  if (r != -ENOENT &&
+      existing_mirror_image.global_image_id != mirror_image.global_image_id) {
+    return -EEXIST;
+  }
+
+  r = cls_cxx_map_set_val(hctx, image_key(image_id), &bl);
+  if (r < 0) {
+    CLS_ERR("error adding mirrored image '%s': %s", image_id.c_str(),
+            cpp_strerror(r).c_str());
+    return r;
+  }
+  return 0;
+}
+
+int image_remove(cls_method_context_t hctx, const string &image_id) {
+  bufferlist bl;
+  cls::rbd::MirrorImage mirror_image;
+  int r = image_get(hctx, image_id, &mirror_image);
+  if (r < 0) {
+    if (r != -ENOENT) {
+      CLS_ERR("error reading mirrored image '%s': '%s'", image_id.c_str(),
+	      cpp_strerror(r).c_str());
+    }
+    return r;
+  }
+
+  if (mirror_image.state != cls::rbd::MIRROR_IMAGE_STATE_DISABLING) {
+    return -EBUSY;
+  }
+
+  r = cls_cxx_map_remove_key(hctx, image_key(image_id));
   if (r < 0) {
-    CLS_ERR("error writing peer '%s': %s", uuid.c_str(),
+    CLS_ERR("error removing mirrored image '%s': %s", image_id.c_str(),
             cpp_strerror(r).c_str());
     return r;
   }
@@ -3024,51 +3152,134 @@ int write_peer(cls_method_context_t hctx, const std::string &uuid,
  * none
  *
  * Output:
- * @param bool: true if enabled
+ * @param uuid (std::string)
  * @returns 0 on success, negative error code on failure
  */
-int mirror_is_enabled(cls_method_context_t hctx, bufferlist *in,
-                      bufferlist *out) {
-  bool enabled;
-  int r = mirror::is_enabled(hctx, &enabled);
+int mirror_uuid_get(cls_method_context_t hctx, bufferlist *in,
+                    bufferlist *out) {
+  std::string mirror_uuid;
+  int r = mirror::uuid_get(hctx, &mirror_uuid);
   if (r < 0) {
     return r;
   }
 
-  ::encode(enabled, *out);
+  ::encode(mirror_uuid, *out);
   return 0;
 }
 
 /**
  * Input:
- * @param enabled (bool)
+ * @param mirror_uuid (std::string)
  *
  * Output:
  * @returns 0 on success, negative error code on failure
  */
-int mirror_set_enabled(cls_method_context_t hctx, bufferlist *in,
-                       bufferlist *out) {
-  bool enabled;
+int mirror_uuid_set(cls_method_context_t hctx, bufferlist *in,
+                    bufferlist *out) {
+  std::string mirror_uuid;
   try {
     bufferlist::iterator bl_it = in->begin();
-    ::decode(enabled, bl_it);
+    ::decode(mirror_uuid, bl_it);
   } catch (const buffer::error &err) {
     return -EINVAL;
   }
 
+  if (mirror_uuid.empty()) {
+    CLS_ERR("cannot set empty mirror uuid");
+    return -EINVAL;
+  }
+
+  uint32_t mirror_mode;
+  int r = read_key(hctx, mirror::MODE, &mirror_mode);
+  if (r < 0 && r != -ENOENT) {
+    return r;
+  } else if (r == 0 && mirror_mode != cls::rbd::MIRROR_MODE_DISABLED) {
+    CLS_ERR("cannot set mirror uuid while mirroring enabled");
+    return -EINVAL;
+  }
+
+  bufferlist mirror_uuid_bl;
+  mirror_uuid_bl.append(mirror_uuid);
+  r = cls_cxx_map_set_val(hctx, mirror::UUID, &mirror_uuid_bl);
+  if (r < 0) {
+    CLS_ERR("failed to set mirror uuid");
+    return r;
+  }
+  return 0;
+}
+
+/**
+ * Input:
+ * none
+ *
+ * Output:
+ * @param cls::rbd::MirrorMode (uint32_t)
+ * @returns 0 on success, negative error code on failure
+ */
+int mirror_mode_get(cls_method_context_t hctx, bufferlist *in,
+                    bufferlist *out) {
+  uint32_t mirror_mode_decode;
+  int r = read_key(hctx, mirror::MODE, &mirror_mode_decode);
+  if (r < 0) {
+    return r;
+  }
+
+  ::encode(mirror_mode_decode, *out);
+  return 0;
+}
+
+/**
+ * Input:
+ * @param mirror_mode (cls::rbd::MirrorMode) (uint32_t)
+ *
+ * Output:
+ * @returns 0 on success, negative error code on failure
+ */
+int mirror_mode_set(cls_method_context_t hctx, bufferlist *in,
+                    bufferlist *out) {
+  uint32_t mirror_mode_decode;
+  try {
+    bufferlist::iterator bl_it = in->begin();
+    ::decode(mirror_mode_decode, bl_it);
+  } catch (const buffer::error &err) {
+    return -EINVAL;
+  }
+
+  bool enabled;
+  switch (static_cast<cls::rbd::MirrorMode>(mirror_mode_decode)) {
+  case cls::rbd::MIRROR_MODE_DISABLED:
+    enabled = false;
+    break;
+  case cls::rbd::MIRROR_MODE_IMAGE:
+  case cls::rbd::MIRROR_MODE_POOL:
+    enabled = true;
+    break;
+  default:
+    CLS_ERR("invalid mirror mode: %d", mirror_mode_decode);
+    return -EINVAL;
+  }
+
   int r;
   if (enabled) {
+    std::string mirror_uuid;
+    r = mirror::uuid_get(hctx, &mirror_uuid);
+    if (r == -ENOENT) {
+      return -EINVAL;
+    } else if (r < 0) {
+      return r;
+    }
+
     bufferlist bl;
-    ::encode(enabled, bl);
+    ::encode(mirror_mode_decode, bl);
 
-    r = cls_cxx_map_set_val(hctx, "mirror_enabled", &bl);
+    r = cls_cxx_map_set_val(hctx, mirror::MODE, &bl);
     if (r < 0) {
       CLS_ERR("error enabling mirroring: %s", cpp_strerror(r).c_str());
       return r;
     }
   } else {
     std::vector<cls::rbd::MirrorPeer> peers;
-    int r = mirror::read_peers(hctx, &peers);
+    r = mirror::read_peers(hctx, &peers);
     if (r < 0 && r != -ENOENT) {
       return r;
     }
@@ -3078,9 +3289,13 @@ int mirror_set_enabled(cls_method_context_t hctx, bufferlist *in,
       return -EBUSY;
     }
 
-    r = cls_cxx_map_remove_key(hctx, "mirror_enabled");
-    if (r < 0 && r != -ENOENT) {
-      CLS_ERR("error disabling mirroring: %s", cpp_strerror(r).c_str());
+    r = remove_key(hctx, mirror::MODE);
+    if (r < 0) {
+      return r;
+    }
+
+    r = remove_key(hctx, mirror::UUID);
+    if (r < 0) {
       return r;
     }
   }
@@ -3124,14 +3339,25 @@ int mirror_peer_add(cls_method_context_t hctx, bufferlist *in,
     return -EINVAL;
   }
 
-  bool enabled;
-  int r = mirror::is_enabled(hctx, &enabled);
-  if (r < 0) {
+  uint32_t mirror_mode_decode;
+  int r = read_key(hctx, mirror::MODE, &mirror_mode_decode);
+  if (r < 0 && r != -ENOENT) {
     return r;
-  }
-  if (!enabled) {
+  } else if (r == -ENOENT ||
+             mirror_mode_decode == cls::rbd::MIRROR_MODE_DISABLED) {
     CLS_ERR("mirroring must be enabled on the pool");
     return -EINVAL;
+  } else if (!mirror_peer.is_valid()) {
+    CLS_ERR("mirror peer is not valid");
+    return -EINVAL;
+  }
+
+  std::string mirror_uuid;
+  r = mirror::uuid_get(hctx, &mirror_uuid);
+  if (mirror_peer.uuid == mirror_uuid) {
+    CLS_ERR("peer uuid '%s' matches pool mirroring uuid",
+            mirror_uuid.c_str());
+    return -EINVAL;
   }
 
   std::vector<cls::rbd::MirrorPeer> peers;
@@ -3141,12 +3367,14 @@ int mirror_peer_add(cls_method_context_t hctx, bufferlist *in,
   }
 
   for (auto const &peer : peers) {
-    if (peer.cluster_uuid == mirror_peer.cluster_uuid) {
-      CLS_ERR("peer cluster uuid '%s' alread exists",
-              peer.cluster_uuid.c_str());
-      return -EEXIST;
-    } else if (peer.cluster_name == mirror_peer.cluster_name) {
-      CLS_ERR("peer cluster name '%s' alread exists",
+    if (peer.uuid == mirror_peer.uuid) {
+      CLS_ERR("peer uuid '%s' already exists",
+              peer.uuid.c_str());
+      return -ESTALE;
+    } else if (peer.cluster_name == mirror_peer.cluster_name &&
+               (peer.pool_id == -1 || mirror_peer.pool_id == -1 ||
+                peer.pool_id == mirror_peer.pool_id)) {
+      CLS_ERR("peer cluster name '%s' already exists",
               peer.cluster_name.c_str());
       return -EEXIST;
     }
@@ -3154,7 +3382,7 @@ int mirror_peer_add(cls_method_context_t hctx, bufferlist *in,
 
   bufferlist bl;
   ::encode(mirror_peer, bl);
-  r = cls_cxx_map_set_val(hctx, mirror::peer_key(mirror_peer.cluster_uuid),
+  r = cls_cxx_map_set_val(hctx, mirror::peer_key(mirror_peer.uuid),
                           &bl);
   if (r < 0) {
     CLS_ERR("error adding peer: %s", cpp_strerror(r).c_str());
@@ -3165,22 +3393,22 @@ int mirror_peer_add(cls_method_context_t hctx, bufferlist *in,
 
 /**
  * Input:
- * @param cluster_uuid (std::string)
+ * @param uuid (std::string)
  *
  * Output:
  * @returns 0 on success, negative error code on failure
  */
 int mirror_peer_remove(cls_method_context_t hctx, bufferlist *in,
                        bufferlist *out) {
-  std::string cluster_uuid;
+  std::string uuid;
   try {
     bufferlist::iterator it = in->begin();
-    ::decode(cluster_uuid, it);
+    ::decode(uuid, it);
   } catch (const buffer::error &err) {
     return -EINVAL;
   }
 
-  int r = cls_cxx_map_remove_key(hctx, mirror::peer_key(cluster_uuid));
+  int r = cls_cxx_map_remove_key(hctx, mirror::peer_key(uuid));
   if (r < 0 && r != -ENOENT) {
     CLS_ERR("error removing peer: %s", cpp_strerror(r).c_str());
     return r;
@@ -3190,7 +3418,7 @@ int mirror_peer_remove(cls_method_context_t hctx, bufferlist *in,
 
 /**
  * Input:
- * @param cluster_uuid (std::string)
+ * @param uuid (std::string)
  * @param client_name (std::string)
  *
  * Output:
@@ -3198,24 +3426,24 @@ int mirror_peer_remove(cls_method_context_t hctx, bufferlist *in,
  */
 int mirror_peer_set_client(cls_method_context_t hctx, bufferlist *in,
                            bufferlist *out) {
-  std::string cluster_uuid;
+  std::string uuid;
   std::string client_name;
   try {
     bufferlist::iterator it = in->begin();
-    ::decode(cluster_uuid, it);
+    ::decode(uuid, it);
     ::decode(client_name, it);
   } catch (const buffer::error &err) {
     return -EINVAL;
   }
 
   cls::rbd::MirrorPeer peer;
-  int r = mirror::read_peer(hctx, cluster_uuid, &peer);
+  int r = mirror::read_peer(hctx, uuid, &peer);
   if (r < 0) {
     return r;
   }
 
   peer.client_name = client_name;
-  r = mirror::write_peer(hctx, cluster_uuid, peer);
+  r = mirror::write_peer(hctx, uuid, peer);
   if (r < 0) {
     return r;
   }
@@ -3224,7 +3452,7 @@ int mirror_peer_set_client(cls_method_context_t hctx, bufferlist *in,
 
 /**
  * Input:
- * @param cluster_uuid (std::string)
+ * @param uuid (std::string)
  * @param cluster_name (std::string)
  *
  * Output:
@@ -3232,24 +3460,124 @@ int mirror_peer_set_client(cls_method_context_t hctx, bufferlist *in,
  */
 int mirror_peer_set_cluster(cls_method_context_t hctx, bufferlist *in,
                             bufferlist *out) {
-  std::string cluster_uuid;
+  std::string uuid;
   std::string cluster_name;
   try {
     bufferlist::iterator it = in->begin();
-    ::decode(cluster_uuid, it);
+    ::decode(uuid, it);
     ::decode(cluster_name, it);
   } catch (const buffer::error &err) {
     return -EINVAL;
   }
 
   cls::rbd::MirrorPeer peer;
-  int r = mirror::read_peer(hctx, cluster_uuid, &peer);
+  int r = mirror::read_peer(hctx, uuid, &peer);
   if (r < 0) {
     return r;
   }
 
   peer.cluster_name = cluster_name;
-  r = mirror::write_peer(hctx, cluster_uuid, peer);
+  r = mirror::write_peer(hctx, uuid, peer);
+  if (r < 0) {
+    return r;
+  }
+  return 0;
+}
+
+/**
+ * Input:
+ * none
+ *
+ * Output:
+ * @param std::vector<std::string>: collection of image_ids
+ * @returns 0 on success, negative error code on failure
+ */
+int mirror_image_list(cls_method_context_t hctx, bufferlist *in,
+		     bufferlist *out) {
+  vector<string> image_ids;
+  int r = mirror::image_list_ids(hctx, &image_ids);
+  if (r < 0) {
+    return r;
+  }
+
+  ::encode(image_ids, *out);
+  return 0;
+}
+
+/**
+ * Input:
+ * @param image_id (std::string)
+ *
+ * Output:
+ * @param cls::rbd::MirrorImage - metadata associated with the image_id
+ * @returns 0 on success, negative error code on failure
+ */
+int mirror_image_get(cls_method_context_t hctx, bufferlist *in,
+		     bufferlist *out) {
+  string image_id;
+  try {
+    bufferlist::iterator it = in->begin();
+    ::decode(image_id, it);
+  } catch (const buffer::error &err) {
+    return -EINVAL;
+  }
+
+  cls::rbd::MirrorImage mirror_image;
+  int r = mirror::image_get(hctx, image_id, &mirror_image);
+  if (r < 0) {
+    return r;
+  }
+
+  ::encode(mirror_image, *out);
+  return 0;
+}
+
+/**
+ * Input:
+ * @param image_id (std::string)
+ * @param mirror_image (cls::rbd::MirrorImage)
+ *
+ * Output:
+ * @returns 0 on success, negative error code on failure
+ * @returns -EEXIST if there's an existing image_id with a different global_image_id
+ */
+int mirror_image_set(cls_method_context_t hctx, bufferlist *in,
+		     bufferlist *out) {
+  string image_id;
+  cls::rbd::MirrorImage mirror_image;
+  try {
+    bufferlist::iterator it = in->begin();
+    ::decode(image_id, it);
+    ::decode(mirror_image, it);
+  } catch (const buffer::error &err) {
+    return -EINVAL;
+  }
+
+  int r = mirror::image_set(hctx, image_id, mirror_image);
+  if (r < 0) {
+    return r;
+  }
+  return 0;
+}
+
+/**
+ * Input:
+ * @param image_id (std::string)
+ *
+ * Output:
+ * @returns 0 on success, negative error code on failure
+ */
+int mirror_image_remove(cls_method_context_t hctx, bufferlist *in,
+			bufferlist *out) {
+  string image_id;
+  try {
+    bufferlist::iterator it = in->begin();
+    ::decode(image_id, it);
+  } catch (const buffer::error &err) {
+    return -EINVAL;
+  }
+
+  int r = mirror::image_remove(hctx, image_id);
   if (r < 0) {
     return r;
   }
@@ -3413,12 +3741,17 @@ void __cls_init()
 			  CLS_METHOD_RD | CLS_METHOD_WR,
 			  old_snapshot_rename, &h_old_snapshot_rename);
 
-  /* methods for the rbd_pool_settings object */
-  cls_register_cxx_method(h_class, "mirror_is_enabled", CLS_METHOD_RD,
-                          mirror_is_enabled, &h_mirror_is_enabled);
-  cls_register_cxx_method(h_class, "mirror_set_enabled",
+  /* methods for the rbd_mirroring object */
+  cls_register_cxx_method(h_class, "mirror_uuid_get", CLS_METHOD_RD,
+                          mirror_uuid_get, &h_mirror_uuid_get);
+  cls_register_cxx_method(h_class, "mirror_uuid_set",
                           CLS_METHOD_RD | CLS_METHOD_WR,
-                          mirror_set_enabled, &h_mirror_set_enabled);
+                          mirror_uuid_set, &h_mirror_uuid_set);
+  cls_register_cxx_method(h_class, "mirror_mode_get", CLS_METHOD_RD,
+                          mirror_mode_get, &h_mirror_mode_get);
+  cls_register_cxx_method(h_class, "mirror_mode_set",
+                          CLS_METHOD_RD | CLS_METHOD_WR,
+                          mirror_mode_set, &h_mirror_mode_set);
   cls_register_cxx_method(h_class, "mirror_peer_list", CLS_METHOD_RD,
                           mirror_peer_list, &h_mirror_peer_list);
   cls_register_cxx_method(h_class, "mirror_peer_add",
@@ -3433,5 +3766,15 @@ void __cls_init()
   cls_register_cxx_method(h_class, "mirror_peer_set_cluster",
                           CLS_METHOD_RD | CLS_METHOD_WR,
                           mirror_peer_set_cluster, &h_mirror_peer_set_cluster);
+  cls_register_cxx_method(h_class, "mirror_image_list", CLS_METHOD_RD,
+                          mirror_image_list, &h_mirror_image_list);
+  cls_register_cxx_method(h_class, "mirror_image_get", CLS_METHOD_RD,
+                          mirror_image_get, &h_mirror_image_get);
+  cls_register_cxx_method(h_class, "mirror_image_set",
+                          CLS_METHOD_RD | CLS_METHOD_WR,
+                          mirror_image_set, &h_mirror_image_set);
+  cls_register_cxx_method(h_class, "mirror_image_remove",
+                          CLS_METHOD_RD | CLS_METHOD_WR,
+                          mirror_image_remove, &h_mirror_image_remove);
   return;
 }
diff --git a/src/cls/rbd/cls_rbd_client.cc b/src/cls/rbd/cls_rbd_client.cc
index d8199e5..30b872b 100644
--- a/src/cls/rbd/cls_rbd_client.cc
+++ b/src/cls/rbd/cls_rbd_client.cc
@@ -758,25 +758,37 @@ namespace librbd {
       return 0;
     }
 
-    int dir_get_name(librados::IoCtx *ioctx, const std::string &oid,
-		     const std::string &id, std::string *name)
-    {
-      bufferlist in, out;
-      ::encode(id, in);
-      int r = ioctx->exec(oid, "rbd", "dir_get_name", in, out);
-      if (r < 0)
-	return r;
+    void dir_get_name_start(librados::ObjectReadOperation *op,
+			    const std::string &id) {
+      bufferlist in_bl;
+      ::encode(id, in_bl);
+      op->exec("rbd", "dir_get_name", in_bl);
+    }
 
-      bufferlist::iterator iter = out.begin();
+    int dir_get_name_finish(bufferlist::iterator *it, std::string *name) {
       try {
-	::decode(*name, iter);
+	::decode(*name, *it);
       } catch (const buffer::error &err) {
 	return -EBADMSG;
       }
-
       return 0;
     }
 
+    int dir_get_name(librados::IoCtx *ioctx, const std::string &oid,
+		     const std::string &id, std::string *name) {
+      librados::ObjectReadOperation op;
+      dir_get_name_start(&op, id);
+
+      bufferlist out_bl;
+      int r = ioctx->operate(oid, &op, &out_bl);
+      if (r < 0) {
+        return r;
+      }
+
+      bufferlist::iterator it = out_bl.begin();
+      return dir_get_name_finish(&it, name);
+    }
+
     int dir_list(librados::IoCtx *ioctx, const std::string &oid,
 		 const std::string &start, uint64_t max_return,
 		 map<string, string> *images)
@@ -968,13 +980,45 @@ namespace librbd {
       return 0;
     }
 
-    int mirror_is_enabled(librados::IoCtx *ioctx, bool *enabled) {
+    int mirror_uuid_get(librados::IoCtx *ioctx, std::string *uuid) {
+      bufferlist in_bl;
+      bufferlist out_bl;
+      int r = ioctx->exec(RBD_MIRRORING, "rbd", "mirror_uuid_get", in_bl,
+                          out_bl);
+      if (r < 0) {
+        return r;
+      }
+
+      try {
+        bufferlist::iterator bl_it = out_bl.begin();
+        ::decode(*uuid, bl_it);
+      } catch (const buffer::error &err) {
+        return -EBADMSG;
+      }
+      return 0;
+    }
+
+    int mirror_uuid_set(librados::IoCtx *ioctx, const std::string &uuid) {
+      bufferlist in_bl;
+      ::encode(uuid, in_bl);
+
+      bufferlist out_bl;
+      int r = ioctx->exec(RBD_MIRRORING, "rbd", "mirror_uuid_set", in_bl,
+                          out_bl);
+      if (r < 0) {
+        return r;
+      }
+      return 0;
+    }
+
+    int mirror_mode_get(librados::IoCtx *ioctx,
+                        cls::rbd::MirrorMode *mirror_mode) {
       bufferlist in_bl;
       bufferlist out_bl;
-      int r = ioctx->exec(RBD_POOL_SETTINGS, "rbd", "mirror_is_enabled", in_bl,
+      int r = ioctx->exec(RBD_MIRRORING, "rbd", "mirror_mode_get", in_bl,
                           out_bl);
       if (r == -ENOENT) {
-        *enabled = false;
+        *mirror_mode = cls::rbd::MIRROR_MODE_DISABLED;
         return 0;
       } else if (r < 0) {
         return r;
@@ -982,19 +1026,22 @@ namespace librbd {
 
       try {
         bufferlist::iterator bl_it = out_bl.begin();
-        ::decode(*enabled, bl_it);
+        uint32_t mirror_mode_decode;
+        ::decode(mirror_mode_decode, bl_it);
+        *mirror_mode = static_cast<cls::rbd::MirrorMode>(mirror_mode_decode);
       } catch (const buffer::error &err) {
         return -EBADMSG;
       }
       return 0;
     }
 
-    int mirror_set_enabled(librados::IoCtx *ioctx, bool enabled) {
+    int mirror_mode_set(librados::IoCtx *ioctx,
+                        cls::rbd::MirrorMode mirror_mode) {
       bufferlist in_bl;
-      ::encode(enabled, in_bl);
+      ::encode(static_cast<uint32_t>(mirror_mode), in_bl);
 
       bufferlist out_bl;
-      int r = ioctx->exec(RBD_POOL_SETTINGS, "rbd", "mirror_set_enabled", in_bl,
+      int r = ioctx->exec(RBD_MIRRORING, "rbd", "mirror_mode_set", in_bl,
                           out_bl);
       if (r < 0) {
         return r;
@@ -1006,7 +1053,7 @@ namespace librbd {
                          std::vector<cls::rbd::MirrorPeer> *peers) {
       bufferlist in_bl;
       bufferlist out_bl;
-      int r = ioctx->exec(RBD_POOL_SETTINGS, "rbd", "mirror_peer_list", in_bl,
+      int r = ioctx->exec(RBD_MIRRORING, "rbd", "mirror_peer_list", in_bl,
                           out_bl);
       if (r < 0) {
         return r;
@@ -1022,15 +1069,15 @@ namespace librbd {
       return 0;
     }
 
-    int mirror_peer_add(librados::IoCtx *ioctx, const std::string &cluster_uuid,
+    int mirror_peer_add(librados::IoCtx *ioctx, const std::string &uuid,
                         const std::string &cluster_name,
-                        const std::string &client_name) {
-      cls::rbd::MirrorPeer peer(cluster_uuid, cluster_name, client_name);
+                        const std::string &client_name, int64_t pool_id) {
+      cls::rbd::MirrorPeer peer(uuid, cluster_name, client_name, pool_id);
       bufferlist in_bl;
       ::encode(peer, in_bl);
 
       bufferlist out_bl;
-      int r = ioctx->exec(RBD_POOL_SETTINGS, "rbd", "mirror_peer_add", in_bl,
+      int r = ioctx->exec(RBD_MIRRORING, "rbd", "mirror_peer_add", in_bl,
                           out_bl);
       if (r < 0) {
         return r;
@@ -1039,12 +1086,12 @@ namespace librbd {
     }
 
     int mirror_peer_remove(librados::IoCtx *ioctx,
-                           const std::string &cluster_uuid) {
+                           const std::string &uuid) {
       bufferlist in_bl;
-      ::encode(cluster_uuid, in_bl);
+      ::encode(uuid, in_bl);
 
       bufferlist out_bl;
-      int r = ioctx->exec(RBD_POOL_SETTINGS, "rbd", "mirror_peer_remove", in_bl,
+      int r = ioctx->exec(RBD_MIRRORING, "rbd", "mirror_peer_remove", in_bl,
                           out_bl);
       if (r < 0) {
         return r;
@@ -1053,14 +1100,14 @@ namespace librbd {
     }
 
     int mirror_peer_set_client(librados::IoCtx *ioctx,
-                               const std::string &cluster_uuid,
+                               const std::string &uuid,
                                const std::string &client_name) {
       bufferlist in_bl;
-      ::encode(cluster_uuid, in_bl);
+      ::encode(uuid, in_bl);
       ::encode(client_name, in_bl);
 
       bufferlist out_bl;
-      int r = ioctx->exec(RBD_POOL_SETTINGS, "rbd", "mirror_peer_set_client",
+      int r = ioctx->exec(RBD_MIRRORING, "rbd", "mirror_peer_set_client",
                           in_bl, out_bl);
       if (r < 0) {
         return r;
@@ -1069,14 +1116,14 @@ namespace librbd {
     }
 
     int mirror_peer_set_cluster(librados::IoCtx *ioctx,
-                                const std::string &cluster_uuid,
+                                const std::string &uuid,
                                 const std::string &cluster_name) {
       bufferlist in_bl;
-      ::encode(cluster_uuid, in_bl);
+      ::encode(uuid, in_bl);
       ::encode(cluster_name, in_bl);
 
       bufferlist out_bl;
-      int r = ioctx->exec(RBD_POOL_SETTINGS, "rbd", "mirror_peer_set_cluster",
+      int r = ioctx->exec(RBD_MIRRORING, "rbd", "mirror_peer_set_cluster",
                           in_bl, out_bl);
       if (r < 0) {
         return r;
@@ -1084,5 +1131,74 @@ namespace librbd {
       return 0;
     }
 
+    int mirror_image_list(librados::IoCtx *ioctx,
+			  std::vector<std::string> *image_ids) {
+      bufferlist in_bl;
+      bufferlist out_bl;
+      int r = ioctx->exec(RBD_MIRRORING, "rbd", "mirror_image_list", in_bl,
+			  out_bl);
+      if (r < 0) {
+        return r;
+      }
+
+      image_ids->clear();
+      try {
+        bufferlist::iterator bl_it = out_bl.begin();
+        ::decode(*image_ids, bl_it);
+      } catch (const buffer::error &err) {
+        return -EBADMSG;
+      }
+      return 0;
+    }
+
+    int mirror_image_get(librados::IoCtx *ioctx, const std::string &image_id,
+			 cls::rbd::MirrorImage *mirror_image) {
+      bufferlist in_bl;
+      bufferlist out_bl;
+      ::encode(image_id, in_bl);
+
+      int r = ioctx->exec(RBD_MIRRORING, "rbd", "mirror_image_get", in_bl,
+			  out_bl);
+      if (r < 0) {
+        return r;
+      }
+
+      try {
+        bufferlist::iterator bl_it = out_bl.begin();
+        ::decode(*mirror_image, bl_it);
+      } catch (const buffer::error &err) {
+        return -EBADMSG;
+      }
+      return 0;
+    }
+
+    int mirror_image_set(librados::IoCtx *ioctx, const std::string &image_id,
+			 const cls::rbd::MirrorImage &mirror_image) {
+      bufferlist in_bl;
+      ::encode(image_id, in_bl);
+      ::encode(mirror_image, in_bl);
+
+      bufferlist out_bl;
+      int r = ioctx->exec(RBD_MIRRORING, "rbd", "mirror_image_set", in_bl,
+			  out_bl);
+      if (r < 0) {
+        return r;
+      }
+      return 0;
+    }
+
+    int mirror_image_remove(librados::IoCtx *ioctx, const std::string &image_id) {
+      bufferlist in_bl;
+      ::encode(image_id, in_bl);
+
+      bufferlist out_bl;
+      int r = ioctx->exec(RBD_MIRRORING, "rbd", "mirror_image_remove", in_bl,
+			  out_bl);
+      if (r < 0) {
+        return r;
+      }
+      return 0;
+    }
+
   } // namespace cls_client
 } // namespace librbd
diff --git a/src/cls/rbd/cls_rbd_client.h b/src/cls/rbd/cls_rbd_client.h
index 928158a..3248f78 100644
--- a/src/cls/rbd/cls_rbd_client.h
+++ b/src/cls/rbd/cls_rbd_client.h
@@ -152,6 +152,9 @@ namespace librbd {
     // operations on rbd_directory objects
     int dir_get_id(librados::IoCtx *ioctx, const std::string &oid,
 		   const std::string &name, std::string *id);
+    void dir_get_name_start(librados::ObjectReadOperation *op,
+			    const std::string &id);
+    int dir_get_name_finish(bufferlist::iterator *it, std::string *name);
     int dir_get_name(librados::IoCtx *ioctx, const std::string &oid,
 		     const std::string &id, std::string *name);
     int dir_list(librados::IoCtx *ioctx, const std::string &oid,
@@ -203,22 +206,35 @@ namespace librbd {
 			  std::vector<uint64_t> *sizes,
 			  ::SnapContext *snapc);
 
-    // operations on the rbd_pool_settings object
-    int mirror_is_enabled(librados::IoCtx *ioctx, bool *enabled);
-    int mirror_set_enabled(librados::IoCtx *ioctx, bool enabled);
+    // operations on the rbd_mirroring object
+    int mirror_uuid_get(librados::IoCtx *ioctx, std::string *uuid);
+    int mirror_uuid_set(librados::IoCtx *ioctx, const std::string &uuid);
+    int mirror_mode_get(librados::IoCtx *ioctx,
+                        cls::rbd::MirrorMode *mirror_mode);
+    int mirror_mode_set(librados::IoCtx *ioctx,
+                        cls::rbd::MirrorMode mirror_mode);
     int mirror_peer_list(librados::IoCtx *ioctx,
                          std::vector<cls::rbd::MirrorPeer> *peers);
-    int mirror_peer_add(librados::IoCtx *ioctx, const std::string &cluster_uuid,
+    int mirror_peer_add(librados::IoCtx *ioctx, const std::string &uuid,
                         const std::string &cluster_name,
-                        const std::string &client_name);
+                        const std::string &client_name,
+                        int64_t pool_id = -1);
     int mirror_peer_remove(librados::IoCtx *ioctx,
-                           const std::string &cluster_uuid);
+                           const std::string &uuid);
     int mirror_peer_set_client(librados::IoCtx *ioctx,
-                               const std::string &cluster_uuid,
+                               const std::string &uuid,
                                const std::string &client_name);
     int mirror_peer_set_cluster(librados::IoCtx *ioctx,
-                                const std::string &cluster_uuid,
+                                const std::string &uuid,
                                 const std::string &cluster_name);
+    int mirror_image_list(librados::IoCtx *ioctx,
+			  std::vector<std::string> *image_ids);
+    int mirror_image_get(librados::IoCtx *ioctx, const std::string &image_id,
+			 cls::rbd::MirrorImage *mirror_image);
+    int mirror_image_set(librados::IoCtx *ioctx, const std::string &image_id,
+			 const cls::rbd::MirrorImage &mirror_image);
+    int mirror_image_remove(librados::IoCtx *ioctx,
+			    const std::string &image_id);
 
   } // namespace cls_client
 } // namespace librbd
diff --git a/src/cls/rbd/cls_rbd_types.cc b/src/cls/rbd/cls_rbd_types.cc
index dca84c5..3f68522 100644
--- a/src/cls/rbd/cls_rbd_types.cc
+++ b/src/cls/rbd/cls_rbd_types.cc
@@ -9,42 +9,121 @@ namespace rbd {
 
 void MirrorPeer::encode(bufferlist &bl) const {
   ENCODE_START(1, 1, bl);
-  ::encode(cluster_uuid, bl);
+  ::encode(uuid, bl);
   ::encode(cluster_name, bl);
   ::encode(client_name, bl);
+  ::encode(pool_id, bl);
   ENCODE_FINISH(bl);
 }
 
 void MirrorPeer::decode(bufferlist::iterator &it) {
   DECODE_START(1, it);
-  ::decode(cluster_uuid, it);
+  ::decode(uuid, it);
   ::decode(cluster_name, it);
   ::decode(client_name, it);
+  ::decode(pool_id, it);
   DECODE_FINISH(it);
 }
 
 void MirrorPeer::dump(Formatter *f) const {
-  f->dump_string("cluster_uuid", cluster_uuid);
+  f->dump_string("uuid", uuid);
   f->dump_string("cluster_name", cluster_name);
   f->dump_string("client_name", client_name);
+  f->dump_int("pool_id", pool_id);
 }
 
 void MirrorPeer::generate_test_instances(std::list<MirrorPeer*> &o) {
   o.push_back(new MirrorPeer());
-  o.push_back(new MirrorPeer("uuid-123", "cluster name", "client name"));
+  o.push_back(new MirrorPeer("uuid-123", "cluster name", "client name", 123));
 }
 
 bool MirrorPeer::operator==(const MirrorPeer &rhs) const {
-  return (cluster_uuid == rhs.cluster_uuid &&
+  return (uuid == rhs.uuid &&
           cluster_name == rhs.cluster_name &&
-          client_name == rhs.client_name);
+          client_name == rhs.client_name &&
+          pool_id == rhs.pool_id);
+}
+
+std::ostream& operator<<(std::ostream& os, const MirrorMode& mirror_mode) {
+  switch (mirror_mode) {
+  case MIRROR_MODE_DISABLED:
+    os << "disabled";
+    break;
+  case MIRROR_MODE_IMAGE:
+    os << "image";
+    break;
+  case MIRROR_MODE_POOL:
+    os << "pool";
+    break;
+  default:
+    os << "unknown (" << static_cast<uint32_t>(mirror_mode) << ")";
+    break;
+  }
+  return os;
 }
 
 std::ostream& operator<<(std::ostream& os, const MirrorPeer& peer) {
   os << "["
-     << "cluster_uuid=" << peer.cluster_uuid << ", "
+     << "uuid=" << peer.uuid << ", "
      << "cluster_name=" << peer.cluster_name << ", "
-     << "client_name=" << peer.client_name << "]";
+     << "client_name=" << peer.client_name;
+  if (peer.pool_id != -1) {
+    os << ", pool_id=" << peer.pool_id;
+  }
+  os << "]";
+  return os;
+}
+
+void MirrorImage::encode(bufferlist &bl) const {
+  ENCODE_START(1, 1, bl);
+  ::encode(global_image_id, bl);
+  ::encode(static_cast<uint8_t>(state), bl);
+  ENCODE_FINISH(bl);
+}
+
+void MirrorImage::decode(bufferlist::iterator &it) {
+  uint8_t int_state;
+  DECODE_START(1, it);
+  ::decode(global_image_id, it);
+  ::decode(int_state, it);
+  state = static_cast<MirrorImageState>(int_state);
+  DECODE_FINISH(it);
+}
+
+void MirrorImage::dump(Formatter *f) const {
+  f->dump_string("global_image_id", global_image_id);
+  f->dump_int("state", state);
+}
+
+void MirrorImage::generate_test_instances(std::list<MirrorImage*> &o) {
+  o.push_back(new MirrorImage());
+  o.push_back(new MirrorImage("uuid-123", MIRROR_IMAGE_STATE_ENABLED));
+  o.push_back(new MirrorImage("uuid-abc", MIRROR_IMAGE_STATE_DISABLING));
+}
+
+bool MirrorImage::operator==(const MirrorImage &rhs) const {
+  return global_image_id == rhs.global_image_id && state == rhs.state;
+}
+
+std::ostream& operator<<(std::ostream& os, const MirrorImageState& mirror_state) {
+  switch (mirror_state) {
+  case MIRROR_IMAGE_STATE_DISABLING:
+    os << "disabling";
+    break;
+  case MIRROR_IMAGE_STATE_ENABLED:
+    os << "enabled";
+    break;
+  default:
+    os << "unknown (" << static_cast<uint32_t>(mirror_state) << ")";
+    break;
+  }
+  return os;
+}
+
+std::ostream& operator<<(std::ostream& os, const MirrorImage& mirror_image) {
+  os << "["
+     << "global_image_id=" << mirror_image.global_image_id << ", "
+     << "state=" << mirror_image.state << "]";
   return os;
 }
 
diff --git a/src/cls/rbd/cls_rbd_types.h b/src/cls/rbd/cls_rbd_types.h
index a4564ce..e318914 100644
--- a/src/cls/rbd/cls_rbd_types.h
+++ b/src/cls/rbd/cls_rbd_types.h
@@ -15,18 +15,29 @@ namespace ceph { class Formatter; }
 namespace cls {
 namespace rbd {
 
+enum MirrorMode {
+  MIRROR_MODE_DISABLED = 0,
+  MIRROR_MODE_IMAGE    = 1,
+  MIRROR_MODE_POOL     = 2
+};
+
 struct MirrorPeer {
   MirrorPeer() {
   }
-  MirrorPeer(const std::string &cluster_uuid, const std::string &cluster_name,
-             const std::string &client_name)
-    : cluster_uuid(cluster_uuid), cluster_name(cluster_name),
-      client_name(client_name) {
+  MirrorPeer(const std::string &uuid, const std::string &cluster_name,
+             const std::string &client_name, int64_t pool_id)
+    : uuid(uuid), cluster_name(cluster_name), client_name(client_name),
+      pool_id(pool_id) {
   }
 
-  std::string cluster_uuid;
+  std::string uuid;
   std::string cluster_name;
   std::string client_name;
+  int64_t pool_id = -1;
+
+  inline bool is_valid() const {
+    return (!uuid.empty() && !cluster_name.empty() && !client_name.empty());
+  }
 
   void encode(bufferlist &bl) const;
   void decode(bufferlist::iterator &it);
@@ -37,10 +48,38 @@ struct MirrorPeer {
   bool operator==(const MirrorPeer &rhs) const;
 };
 
+std::ostream& operator<<(std::ostream& os, const MirrorMode& mirror_mode);
 std::ostream& operator<<(std::ostream& os, const MirrorPeer& peer);
 
 WRITE_CLASS_ENCODER(MirrorPeer);
 
+enum MirrorImageState {
+  MIRROR_IMAGE_STATE_DISABLING = 0,
+  MIRROR_IMAGE_STATE_ENABLED   = 1
+};
+
+struct MirrorImage {
+  MirrorImage() {}
+  MirrorImage(const std::string &global_image_id, MirrorImageState state)
+    : global_image_id(global_image_id), state(state) {}
+
+  std::string global_image_id;
+  MirrorImageState state = MIRROR_IMAGE_STATE_DISABLING;
+
+  void encode(bufferlist &bl) const;
+  void decode(bufferlist::iterator &it);
+  void dump(Formatter *f) const;
+
+  static void generate_test_instances(std::list<MirrorImage*> &o);
+
+  bool operator==(const MirrorImage &rhs) const;
+};
+
+std::ostream& operator<<(std::ostream& os, const MirrorImageState& mirror_state);
+std::ostream& operator<<(std::ostream& os, const MirrorImage& mirror_image);
+
+WRITE_CLASS_ENCODER(MirrorImage);
+
 } // namespace rbd
 } // namespace cls
 
diff --git a/src/cls/rgw/cls_rgw.cc b/src/cls/rgw/cls_rgw.cc
index 088e2c5..f59658c 100644
--- a/src/cls/rgw/cls_rgw.cc
+++ b/src/cls/rgw/cls_rgw.cc
@@ -9,7 +9,7 @@
 #include <stdlib.h>
 #include <errno.h>
 
-#include "include/utime.h"
+#include "common/ceph_time.h"
 #include "objclass/objclass.h"
 #include "cls/rgw/cls_rgw_ops.h"
 #include "common/Clock.h"
@@ -36,7 +36,9 @@ cls_method_handle_t h_rgw_bucket_read_olh_log;
 cls_method_handle_t h_rgw_bucket_trim_olh_log;
 cls_method_handle_t h_rgw_bucket_clear_olh;
 cls_method_handle_t h_rgw_obj_remove;
+cls_method_handle_t h_rgw_obj_store_pg_ver;
 cls_method_handle_t h_rgw_obj_check_attrs_prefix;
+cls_method_handle_t h_rgw_obj_check_mtime;
 cls_method_handle_t h_rgw_bi_get_op;
 cls_method_handle_t h_rgw_bi_put_op;
 cls_method_handle_t h_rgw_bi_list_op;
@@ -112,10 +114,11 @@ static bool bi_entry_gt(const string& first, const string& second)
   return first > second;
 }
 
-static void get_time_key(utime_t& ut, string *key)
+static void get_time_key(real_time& ut, string *key)
 {
   char buf[32];
-  snprintf(buf, 32, "%011llu.%09u", (unsigned long long)ut.sec(), ut.nsec());
+  ceph_timespec ts = ceph::real_clock::to_ceph_timespec(ut);
+  snprintf(buf, 32, "%011llu.%09u", (unsigned long long)ts.tv_sec, (unsigned int)ts.tv_nsec);
   *key = buf;
 }
 
@@ -138,9 +141,9 @@ static void bi_log_index_key(cls_method_context_t hctx, string& key, string& id,
 }
 
 static int log_index_operation(cls_method_context_t hctx, cls_rgw_obj_key& obj_key, RGWModifyOp op,
-                               string& tag, utime_t& timestamp,
+                               string& tag, real_time& timestamp,
                                rgw_bucket_entry_ver& ver, RGWPendingState state, uint64_t index_ver,
-                               string& max_marker, uint16_t bilog_flags)
+                               string& max_marker, uint16_t bilog_flags, string *owner, string *owner_display_name)
 {
   bufferlist bl;
 
@@ -155,6 +158,12 @@ static int log_index_operation(cls_method_context_t hctx, cls_rgw_obj_key& obj_k
   entry.index_ver = index_ver;
   entry.tag = tag;
   entry.bilog_flags = bilog_flags;
+  if (owner) {
+    entry.owner = *owner;
+  }
+  if (owner_display_name) {
+    entry.owner_display_name = *owner_display_name;
+  }
 
   string key;
   bi_log_index_key(hctx, key, entry.id, index_ver);
@@ -670,7 +679,7 @@ int rgw_bucket_prepare_op(cls_method_context_t hctx, bufferlist *in, bufferlist
 
   // fill in proper state
   struct rgw_bucket_pending_info info;
-  info.timestamp = ceph_clock_now(g_ceph_context);
+  info.timestamp = real_clock::now();
   info.state = CLS_RGW_STATE_PENDING_MODIFY;
   info.op = op.op;
   entry.pending_map.insert(pair<string, rgw_bucket_pending_info>(op.tag, info));
@@ -684,7 +693,7 @@ int rgw_bucket_prepare_op(cls_method_context_t hctx, bufferlist *in, bufferlist
 
   if (op.log_op) {
     rc = log_index_operation(hctx, op.key, op.op, op.tag, entry.meta.mtime,
-                             entry.ver, info.state, header.ver, header.max_marker, op.bilog_flags);
+                             entry.ver, info.state, header.ver, header.max_marker, op.bilog_flags, NULL, NULL);
     if (rc < 0)
       return rc;
   }
@@ -813,7 +822,7 @@ int rgw_bucket_complete_op(cls_method_context_t hctx, bufferlist *in, bufferlist
   }
 
   entry.index_ver = header.ver;
-  entry.flags = 0; /* resetting entry flags, entry might have been previously a delete marker */
+  entry.flags = (entry.key.instance.empty() ? 0 : RGW_BUCKET_DIRENT_FLAG_VER); /* resetting entry flags, entry might have been previously a delete marker */
 
   if (op.tag.size()) {
     map<string, struct rgw_bucket_pending_info>::iterator pinter = entry.pending_map.find(op.tag);
@@ -840,7 +849,7 @@ int rgw_bucket_complete_op(cls_method_context_t hctx, bufferlist *in, bufferlist
   if (cancel) {
     if (op.log_op) {
       rc = log_index_operation(hctx, op.key, op.op, op.tag, entry.meta.mtime, entry.ver,
-                               CLS_RGW_STATE_COMPLETE, header.ver, header.max_marker, op.bilog_flags);
+                               CLS_RGW_STATE_COMPLETE, header.ver, header.max_marker, op.bilog_flags, NULL, NULL);
       if (rc < 0)
         return rc;
     }
@@ -900,7 +909,7 @@ int rgw_bucket_complete_op(cls_method_context_t hctx, bufferlist *in, bufferlist
 
   if (op.log_op) {
     rc = log_index_operation(hctx, op.key, op.op, op.tag, entry.meta.mtime, entry.ver,
-                             CLS_RGW_STATE_COMPLETE, header.ver, header.max_marker, op.bilog_flags);
+                             CLS_RGW_STATE_COMPLETE, header.ver, header.max_marker, op.bilog_flags, NULL, NULL);
     if (rc < 0)
       return rc;
   }
@@ -925,7 +934,7 @@ int rgw_bucket_complete_op(cls_method_context_t hctx, bufferlist *in, bufferlist
 
     if (op.log_op) {
       rc = log_index_operation(hctx, remove_key, CLS_RGW_OP_DEL, op.tag, remove_entry.meta.mtime,
-                               remove_entry.ver, CLS_RGW_STATE_COMPLETE, header.ver, header.max_marker, op.bilog_flags);
+                               remove_entry.ver, CLS_RGW_STATE_COMPLETE, header.ver, header.max_marker, op.bilog_flags, NULL, NULL);
       if (rc < 0)
         continue;
     }
@@ -1175,6 +1184,9 @@ public:
     return 0;
   }
 
+  real_time mtime() {
+    return instance_entry.meta.mtime;
+  }
 };
 
 
@@ -1378,6 +1390,18 @@ static int rgw_bucket_link_olh(cls_method_context_t hctx, bufferlist *in, buffer
     return ret;
   }
 
+  if (existed && !real_clock::is_zero(op.unmod_since)) {
+    struct timespec mtime = ceph::real_clock::to_timespec(obj.mtime());
+    struct timespec unmod = ceph::real_clock::to_timespec(op.unmod_since);
+    if (!op.high_precision_time) {
+      mtime.tv_nsec = 0;
+      unmod.tv_nsec = 0;
+    }
+    if (mtime >= unmod) {
+      return 0; /* no need to set error, we just return 0 and avoid writing to the bi log */
+    }
+  }
+
   bool removing;
 
   /*
@@ -1498,10 +1522,19 @@ static int rgw_bucket_link_olh(cls_method_context_t hctx, bufferlist *in, buffer
     rgw_bucket_entry_ver ver;
     ver.epoch = (op.olh_epoch ? op.olh_epoch : olh.get_epoch());
 
+    string *powner = NULL;
+    string *powner_display_name = NULL;
+
+    if (op.delete_marker) {
+      powner = &entry.meta.owner;
+      powner_display_name = &entry.meta.owner_display_name;
+    }
+
     RGWModifyOp operation = (op.delete_marker ? CLS_RGW_OP_LINK_OLH_DM : CLS_RGW_OP_LINK_OLH);
     ret = log_index_operation(hctx, op.key, operation, op.op_tag,
                               entry.meta.mtime, ver,
-                              CLS_RGW_STATE_COMPLETE, header.ver, header.max_marker, op.bilog_flags | RGW_BILOG_FLAG_VERSIONED_OP);
+                              CLS_RGW_STATE_COMPLETE, header.ver, header.max_marker, op.bilog_flags | RGW_BILOG_FLAG_VERSIONED_OP,
+                              powner, powner_display_name);
     if (ret < 0)
       return ret;
   }
@@ -1628,11 +1661,11 @@ static int rgw_bucket_unlink_instance(cls_method_context_t hctx, bufferlist *in,
     rgw_bucket_entry_ver ver;
     ver.epoch = (op.olh_epoch ? op.olh_epoch : olh.get_epoch());
 
-    utime_t mtime = ceph_clock_now(g_ceph_context); /* mtime has no real meaning in instance removal context */
+    real_time mtime = real_clock::now(); /* mtime has no real meaning in instance removal context */
     ret = log_index_operation(hctx, op.key, CLS_RGW_OP_UNLINK_INSTANCE, op.op_tag,
                               mtime, ver,
                               CLS_RGW_STATE_COMPLETE, header.ver, header.max_marker,
-                              op.bilog_flags | RGW_BILOG_FLAG_VERSIONED_OP);
+                              op.bilog_flags | RGW_BILOG_FLAG_VERSIONED_OP, NULL, NULL);
     if (ret < 0)
       return ret;
   }
@@ -1816,7 +1849,6 @@ int rgw_dir_suggest_changes(cls_method_context_t hctx, bufferlist *in, bufferlis
   bufferlist header_bl;
   struct rgw_bucket_dir_header header;
   bool header_changed = false;
-  uint64_t tag_timeout;
 
   int rc = read_bucket_header(hctx, &header);
   if (rc < 0) {
@@ -1824,7 +1856,7 @@ int rgw_dir_suggest_changes(cls_method_context_t hctx, bufferlist *in, bufferlis
     return rc;
   }
 
-  tag_timeout = (header.tag_timeout ? header.tag_timeout : CEPH_RGW_TAG_TIMEOUT);
+  timespan tag_timeout(header.tag_timeout ? header.tag_timeout : CEPH_RGW_TAG_TIMEOUT);
 
   bufferlist::iterator in_iter = in->begin();
 
@@ -1856,7 +1888,7 @@ int rgw_dir_suggest_changes(cls_method_context_t hctx, bufferlist *in, bufferlis
         return -EINVAL;
       }
 
-      utime_t cur_time = ceph_clock_now(g_ceph_context);
+      real_time cur_time = real_clock::now();
       map<string, struct rgw_bucket_pending_info>::iterator iter =
                 cur_disk.pending_map.begin();
       while(iter != cur_disk.pending_map.end()) {
@@ -1986,6 +2018,30 @@ static int rgw_obj_remove(cls_method_context_t hctx, bufferlist *in, bufferlist
   return 0;
 }
 
+static int rgw_obj_store_pg_ver(cls_method_context_t hctx, bufferlist *in, bufferlist *out)
+{
+  // decode request
+  rgw_cls_obj_store_pg_ver_op op;
+  bufferlist::iterator iter = in->begin();
+  try {
+    ::decode(op, iter);
+  } catch (buffer::error& err) {
+    CLS_LOG(0, "ERROR: %s(): failed to decode request", __func__);
+    return -EINVAL;
+  }
+
+  bufferlist bl;
+  uint64_t ver = cls_current_version(hctx);
+  ::encode(ver, bl);
+  int ret = cls_cxx_setxattr(hctx, op.attr.c_str(), &bl);
+  if (ret < 0) {
+    CLS_LOG(0, "ERROR: %s(): cls_cxx_setxattr (attr=%s) returned %d", __func__, op.attr.c_str(), ret);
+    return ret;
+  }
+
+  return 0;
+}
+
 static int rgw_obj_check_attrs_prefix(cls_method_context_t hctx, bufferlist *in, bufferlist *out)
 {
   // decode request
@@ -2029,6 +2085,69 @@ static int rgw_obj_check_attrs_prefix(cls_method_context_t hctx, bufferlist *in,
   return 0;
 }
 
+static int rgw_obj_check_mtime(cls_method_context_t hctx, bufferlist *in, bufferlist *out)
+{
+  // decode request
+  rgw_cls_obj_check_mtime op;
+  bufferlist::iterator iter = in->begin();
+  try {
+    ::decode(op, iter);
+  } catch (buffer::error& err) {
+    CLS_LOG(0, "ERROR: %s(): failed to decode request", __func__);
+    return -EINVAL;
+  }
+
+  real_time obj_ut;
+  int ret = cls_cxx_stat2(hctx, NULL, &obj_ut);
+  if (ret < 0 && ret != -ENOENT) {
+    CLS_LOG(0, "ERROR: %s(): cls_cxx_stat() returned %d", __func__, ret);
+    return ret;
+  }
+  if (ret == -ENOENT) {
+    CLS_LOG(10, "object does not exist, skipping check");
+  }
+
+  ceph_timespec obj_ts = ceph::real_clock::to_ceph_timespec(obj_ut);
+  ceph_timespec op_ts = ceph::real_clock::to_ceph_timespec(op.mtime);
+
+  if (!op.high_precision_time) {
+    obj_ts.tv_nsec = 0;
+    op_ts.tv_nsec = 0;
+  }
+
+  CLS_LOG(10, "%s: obj_ut=%lld.%06lld op.mtime=%lld.%06lld", __func__,
+          (long long)obj_ts.tv_sec, (long long)obj_ts.tv_nsec,
+          (long long)op_ts.tv_sec, (long long)op_ts.tv_nsec);
+
+  bool check;
+
+  switch (op.type) {
+  case CLS_RGW_CHECK_TIME_MTIME_EQ:
+    check = (obj_ts == op_ts);
+    break;
+  case CLS_RGW_CHECK_TIME_MTIME_LT:
+    check = (obj_ts < op_ts);
+    break;
+  case CLS_RGW_CHECK_TIME_MTIME_LE:
+    check = (obj_ts <= op_ts);
+    break;
+  case CLS_RGW_CHECK_TIME_MTIME_GT:
+    check = (obj_ts > op_ts);
+    break;
+  case CLS_RGW_CHECK_TIME_MTIME_GE:
+    check = (obj_ts >= op_ts);
+    break;
+  default:
+    return -EINVAL;
+  };
+
+  if (!check) {
+    return -ECANCELED;
+  }
+
+  return 0;
+}
+
 static int rgw_bi_get_op(cls_method_context_t hctx, bufferlist *in, bufferlist *out)
 {
   // decode request
@@ -2474,14 +2593,14 @@ static void usage_record_prefix_by_user(string& user, uint64_t epoch, string& ke
   key = buf;
 }
 
-static void usage_record_name_by_time(uint64_t epoch, string& user, string& bucket, string& key)
+static void usage_record_name_by_time(uint64_t epoch, const string& user, string& bucket, string& key)
 {
   char buf[32 + user.size() + bucket.size()];
   snprintf(buf, sizeof(buf), "%011llu_%s_%s", (long long unsigned)epoch, user.c_str(), bucket.c_str());
   key = buf;
 }
 
-static void usage_record_name_by_user(string& user, uint64_t epoch, string& bucket, string& key)
+static void usage_record_name_by_user(const string& user, uint64_t epoch, string& bucket, string& key)
 {
   char buf[32 + user.size() + bucket.size()];
   snprintf(buf, sizeof(buf), "%s_%011llu_%s", user.c_str(), (long long unsigned)epoch, bucket.c_str());
@@ -2521,9 +2640,12 @@ int rgw_user_usage_log_add(cls_method_context_t hctx, bufferlist *in, bufferlist
   for (iter = info.entries.begin(); iter != info.entries.end(); ++iter) {
     rgw_usage_log_entry& entry = *iter;
     string key_by_time;
-    usage_record_name_by_time(entry.epoch, entry.owner, entry.bucket, key_by_time);
 
-    CLS_LOG(10, "rgw_user_usage_log_add user=%s bucket=%s\n", entry.owner.c_str(), entry.bucket.c_str());
+    rgw_user *puser = (entry.payer.empty() ? &entry.owner : &entry.payer);
+
+    usage_record_name_by_time(entry.epoch, puser->to_str(), entry.bucket, key_by_time);
+
+    CLS_LOG(10, "rgw_user_usage_log_add user=%s bucket=%s\n", puser->to_str().c_str(), entry.bucket.c_str());
 
     bufferlist record_bl;
     int ret = cls_cxx_map_get_val(hctx, key_by_time, &record_bl);
@@ -2547,7 +2669,7 @@ int rgw_user_usage_log_add(cls_method_context_t hctx, bufferlist *in, bufferlist
       return ret;
 
     string key_by_user;
-    usage_record_name_by_user(entry.owner, entry.epoch, entry.bucket, key_by_user);
+    usage_record_name_by_user(puser->to_str(), entry.epoch, entry.bucket, key_by_user);
     ret = cls_cxx_map_set_val(hctx, key_by_user, &new_record_bl);
     if (ret < 0)
       return ret;
@@ -2649,7 +2771,13 @@ static int usage_iterate_range(cls_method_context_t hctx, uint64_t start, uint64
 static int usage_log_read_cb(cls_method_context_t hctx, const string& key, rgw_usage_log_entry& entry, void *param)
 {
   map<rgw_user_bucket, rgw_usage_log_entry> *usage = (map<rgw_user_bucket, rgw_usage_log_entry> *)param;
-  rgw_user_bucket ub(entry.owner, entry.bucket);
+  rgw_user *puser;
+  if (!entry.payer.empty()) {
+    puser = &entry.payer;
+  } else {
+    puser = &entry.owner;
+  }
+  rgw_user_bucket ub(puser->to_str(), entry.bucket);
   rgw_usage_log_entry& le = (*usage)[ub];
   le.aggregate(entry);
  
@@ -2691,8 +2819,9 @@ static int usage_log_trim_cb(cls_method_context_t hctx, const string& key, rgw_u
   string key_by_time;
   string key_by_user;
 
-  usage_record_name_by_time(entry.epoch, entry.owner, entry.bucket, key_by_time);
-  usage_record_name_by_user(entry.owner, entry.epoch, entry.bucket, key_by_user);
+  string o = entry.owner.to_str();
+  usage_record_name_by_time(entry.epoch, o, entry.bucket, key_by_time);
+  usage_record_name_by_user(o, entry.epoch, entry.bucket, key_by_user);
 
   int ret = cls_cxx_map_remove_key(hctx, key_by_time);
   if (ret < 0)
@@ -2814,8 +2943,8 @@ static int gc_update_entry(cls_method_context_t hctx, uint32_t expiration_secs,
       return ret;
     }
   }
-  info.time = ceph_clock_now(g_ceph_context);
-  info.time += expiration_secs;
+  info.time = ceph::real_clock::now();
+  info.time += make_timespan(expiration_secs);
   ret = gc_omap_set(hctx, GC_OBJ_NAME_INDEX, info.tag, &info);
   if (ret < 0)
     return ret;
@@ -2910,7 +3039,7 @@ static int gc_iterate_entries(cls_method_context_t hctx, const string& marker, b
   }
 
   if (expired_only) {
-    utime_t now = ceph_clock_now(g_ceph_context);
+    real_time now = ceph::real_clock::now();
     string now_str;
     get_time_key(now, &now_str);
     prepend_index_prefix(now_str, GC_OBJ_TIME_INDEX, &end_key);
@@ -3075,7 +3204,9 @@ void __cls_init()
   cls_register_cxx_method(h_class, "bucket_clear_olh", CLS_METHOD_RD | CLS_METHOD_WR, rgw_bucket_clear_olh, &h_rgw_bucket_clear_olh);
 
   cls_register_cxx_method(h_class, "obj_remove", CLS_METHOD_RD | CLS_METHOD_WR, rgw_obj_remove, &h_rgw_obj_remove);
+  cls_register_cxx_method(h_class, "obj_store_pg_ver", CLS_METHOD_WR, rgw_obj_store_pg_ver, &h_rgw_obj_store_pg_ver);
   cls_register_cxx_method(h_class, "obj_check_attrs_prefix", CLS_METHOD_RD, rgw_obj_check_attrs_prefix, &h_rgw_obj_check_attrs_prefix);
+  cls_register_cxx_method(h_class, "obj_check_mtime", CLS_METHOD_RD, rgw_obj_check_mtime, &h_rgw_obj_check_mtime);
 
   cls_register_cxx_method(h_class, "bi_get", CLS_METHOD_RD, rgw_bi_get_op, &h_rgw_bi_get_op);
   cls_register_cxx_method(h_class, "bi_put", CLS_METHOD_RD | CLS_METHOD_WR, rgw_bi_put_op, &h_rgw_bi_put_op);
diff --git a/src/cls/rgw/cls_rgw_client.cc b/src/cls/rgw/cls_rgw_client.cc
index 62034f2..40041aa 100644
--- a/src/cls/rgw/cls_rgw_client.cc
+++ b/src/cls/rgw/cls_rgw_client.cc
@@ -208,6 +208,15 @@ void cls_rgw_remove_obj(librados::ObjectWriteOperation& o, list<string>& keep_at
   o.exec("rgw", "obj_remove", in);
 }
 
+void cls_rgw_obj_store_pg_ver(librados::ObjectWriteOperation& o, const string& attr)
+{
+  bufferlist in;
+  struct rgw_cls_obj_store_pg_ver_op call;
+  call.attr = attr;
+  ::encode(call, in);
+  o.exec("rgw", "obj_store_pg_ver", in);
+}
+
 void cls_rgw_obj_check_attrs_prefix(librados::ObjectOperation& o, const string& prefix, bool fail_if_exist)
 {
   bufferlist in;
@@ -218,6 +227,17 @@ void cls_rgw_obj_check_attrs_prefix(librados::ObjectOperation& o, const string&
   o.exec("rgw", "obj_check_attrs_prefix", in);
 }
 
+void cls_rgw_obj_check_mtime(librados::ObjectOperation& o, const real_time& mtime, bool high_precision_time, RGWCheckMTimeType type)
+{
+  bufferlist in;
+  struct rgw_cls_obj_check_mtime call;
+  call.mtime = mtime;
+  call.high_precision_time = high_precision_time;
+  call.type = type;
+  ::encode(call, in);
+  o.exec("rgw", "obj_check_mtime", in);
+}
+
 int cls_rgw_bi_get(librados::IoCtx& io_ctx, const string oid,
                    BIIndexType index_type, cls_rgw_obj_key& key,
                    rgw_cls_bi_entry *entry)
@@ -287,7 +307,7 @@ int cls_rgw_bi_list(librados::IoCtx& io_ctx, const string oid,
 
 int cls_rgw_bucket_link_olh(librados::IoCtx& io_ctx, const string& oid, const cls_rgw_obj_key& key, bufferlist& olh_tag,
                             bool delete_marker, const string& op_tag, struct rgw_bucket_dir_entry_meta *meta,
-                            uint64_t olh_epoch, bool log_op)
+                            uint64_t olh_epoch, ceph::real_time unmod_since, bool high_precision_time, bool log_op)
 {
   bufferlist in, out;
   struct rgw_cls_link_olh_op call;
@@ -300,6 +320,8 @@ int cls_rgw_bucket_link_olh(librados::IoCtx& io_ctx, const string& oid, const cl
   }
   call.olh_epoch = olh_epoch;
   call.log_op = log_op;
+  call.unmod_since = unmod_since;
+  call.high_precision_time = high_precision_time;
   ::encode(call, in);
   int r = io_ctx.exec(oid, "rgw", "bucket_link_olh", in, out);
   if (r < 0)
diff --git a/src/cls/rgw/cls_rgw_client.h b/src/cls/rgw/cls_rgw_client.h
index 37c856f..130a009 100644
--- a/src/cls/rgw/cls_rgw_client.h
+++ b/src/cls/rgw/cls_rgw_client.h
@@ -8,6 +8,7 @@
 #include "cls_rgw_ops.h"
 #include "common/RefCountedObj.h"
 #include "include/compat.h"
+#include "common/ceph_time.h"
 
 // Forward declaration
 class BucketIndexAioManager;
@@ -315,7 +316,9 @@ void cls_rgw_bucket_complete_op(librados::ObjectWriteOperation& o, RGWModifyOp o
                                 uint16_t bilog_op);
 
 void cls_rgw_remove_obj(librados::ObjectWriteOperation& o, list<string>& keep_attr_prefixes);
+void cls_rgw_obj_store_pg_ver(librados::ObjectWriteOperation& o, const string& attr);
 void cls_rgw_obj_check_attrs_prefix(librados::ObjectOperation& o, const string& prefix, bool fail_if_exist);
+void cls_rgw_obj_check_mtime(librados::ObjectOperation& o, const ceph::real_time& mtime, bool high_precision_time, RGWCheckMTimeType type);
 
 int cls_rgw_bi_get(librados::IoCtx& io_ctx, const string oid,
                    BIIndexType index_type, cls_rgw_obj_key& key,
@@ -328,7 +331,7 @@ int cls_rgw_bi_list(librados::IoCtx& io_ctx, const string oid,
 
 int cls_rgw_bucket_link_olh(librados::IoCtx& io_ctx, const string& oid, const cls_rgw_obj_key& key, bufferlist& olh_tag,
                             bool delete_marker, const string& op_tag, struct rgw_bucket_dir_entry_meta *meta,
-                            uint64_t olh_epoch, bool log_op);
+                            uint64_t olh_epoch, ceph::real_time unmod_since, bool high_precision_time, bool log_op);
 int cls_rgw_bucket_unlink_instance(librados::IoCtx& io_ctx, const string& oid, const cls_rgw_obj_key& key, const string& op_tag,
                                    uint64_t olh_epoch, bool log_op);
 int cls_rgw_get_olh_log(librados::IoCtx& io_ctx, string& oid, librados::ObjectReadOperation& op, const cls_rgw_obj_key& olh, uint64_t ver_marker,
diff --git a/src/cls/rgw/cls_rgw_ops.cc b/src/cls/rgw/cls_rgw_ops.cc
index 23beb4e..2cf3619 100644
--- a/src/cls/rgw/cls_rgw_ops.cc
+++ b/src/cls/rgw/cls_rgw_ops.cc
@@ -3,6 +3,7 @@
 
 #include "common/Formatter.h"
 #include "common/ceph_json.h"
+#include "include/utime.h"
 
 void rgw_cls_tag_timeout_op::dump(Formatter *f) const
 {
@@ -175,6 +176,9 @@ void rgw_cls_link_olh_op::dump(Formatter *f) const
   ::encode_json("olh_epoch", olh_epoch, f);
   ::encode_json("log_op", log_op, f);
   ::encode_json("bilog_flags", (uint32_t)bilog_flags, f);
+  utime_t ut(unmod_since);
+  ::encode_json("unmod_since", ut, f);
+  ::encode_json("high_precision_time", high_precision_time, f);
 }
 
 void rgw_cls_unlink_instance_op::generate_test_instances(list<rgw_cls_unlink_instance_op*>& o)
diff --git a/src/cls/rgw/cls_rgw_ops.h b/src/cls/rgw/cls_rgw_ops.h
index 0a0686f..3f2c8d9 100644
--- a/src/cls/rgw/cls_rgw_ops.h
+++ b/src/cls/rgw/cls_rgw_ops.h
@@ -4,6 +4,7 @@
 #include <map>
 
 #include "include/types.h"
+#include "common/ceph_time.h"
 #include "cls/rgw/cls_rgw_types.h"
 
 struct rgw_cls_tag_timeout_op
@@ -164,11 +165,13 @@ struct rgw_cls_link_olh_op {
   uint64_t olh_epoch;
   bool log_op;
   uint16_t bilog_flags;
+  real_time unmod_since; /* only create delete marker if newer then this */
+  bool high_precision_time;
 
-  rgw_cls_link_olh_op() : delete_marker(false), olh_epoch(0), log_op(false), bilog_flags(0) {}
+  rgw_cls_link_olh_op() : delete_marker(false), olh_epoch(0), log_op(false), bilog_flags(0), high_precision_time(false) {}
 
   void encode(bufferlist& bl) const {
-    ENCODE_START(1, 1, bl);
+    ENCODE_START(4, 1, bl);
     ::encode(key, bl);
     ::encode(olh_tag, bl);
     ::encode(delete_marker, bl);
@@ -177,11 +180,15 @@ struct rgw_cls_link_olh_op {
     ::encode(olh_epoch, bl);
     ::encode(log_op, bl);
     ::encode(bilog_flags, bl);
+    time_t t = ceph::real_clock::to_time_t(unmod_since);
+    ::encode(t, bl);
+    ::encode(unmod_since, bl);
+    ::encode(high_precision_time, bl);
     ENCODE_FINISH(bl);
   }
 
   void decode(bufferlist::iterator& bl) {
-    DECODE_START(1, bl);
+    DECODE_START(4, bl);
     ::decode(key, bl);
     ::decode(olh_tag, bl);
     ::decode(delete_marker, bl);
@@ -190,6 +197,17 @@ struct rgw_cls_link_olh_op {
     ::decode(olh_epoch, bl);
     ::decode(log_op, bl);
     ::decode(bilog_flags, bl);
+    if (struct_v == 2) {
+      time_t t;
+      ::decode(t, bl);
+      unmod_since = ceph::real_clock::from_time_t(t);
+    }
+    if (struct_v >= 3) {
+      ::decode(unmod_since, bl);
+    }
+    if (struct_v >= 4) {
+      ::decode(high_precision_time, bl);
+    }
     DECODE_FINISH(bl);
   }
 
@@ -437,6 +455,23 @@ struct rgw_cls_obj_remove_op {
 };
 WRITE_CLASS_ENCODER(rgw_cls_obj_remove_op)
 
+struct rgw_cls_obj_store_pg_ver_op {
+  string attr;
+
+  void encode(bufferlist& bl) const {
+    ENCODE_START(1, 1, bl);
+    ::encode(attr, bl);
+    ENCODE_FINISH(bl);
+  }
+
+  void decode(bufferlist::iterator& bl) {
+    DECODE_START(1, bl);
+    ::decode(attr, bl);
+    DECODE_FINISH(bl);
+  }
+};
+WRITE_CLASS_ENCODER(rgw_cls_obj_store_pg_ver_op)
+
 struct rgw_cls_obj_check_attrs_prefix {
   string check_prefix;
   bool fail_if_exist;
@@ -459,18 +494,54 @@ struct rgw_cls_obj_check_attrs_prefix {
 };
 WRITE_CLASS_ENCODER(rgw_cls_obj_check_attrs_prefix)
 
+struct rgw_cls_obj_check_mtime {
+  ceph::real_time mtime;
+  RGWCheckMTimeType type;
+  bool high_precision_time;
+
+  rgw_cls_obj_check_mtime() : type(CLS_RGW_CHECK_TIME_MTIME_EQ), high_precision_time(false) {}
+
+  void encode(bufferlist& bl) const {
+    ENCODE_START(2, 1, bl);
+    ::encode(mtime, bl);
+    ::encode((uint8_t)type, bl);
+    ::encode(high_precision_time, bl);
+    ENCODE_FINISH(bl);
+  }
+
+  void decode(bufferlist::iterator& bl) {
+    DECODE_START(2, bl);
+    ::decode(mtime, bl);
+    uint8_t c;
+    ::decode(c, bl);
+    type = (RGWCheckMTimeType)c;
+    if (struct_v >= 2) {
+      ::decode(high_precision_time, bl);
+    }
+    DECODE_FINISH(bl);
+  }
+};
+WRITE_CLASS_ENCODER(rgw_cls_obj_check_mtime)
+
 struct rgw_cls_usage_log_add_op {
   rgw_usage_log_info info;
+  rgw_user user;
 
   void encode(bufferlist& bl) const {
-    ENCODE_START(1, 1, bl);
+    ENCODE_START(2, 1, bl);
     ::encode(info, bl);
+    ::encode(user.to_str(), bl);
     ENCODE_FINISH(bl);
   }
 
   void decode(bufferlist::iterator& bl) {
-    DECODE_START(1, bl);
+    DECODE_START(2, bl);
     ::decode(info, bl);
+    if (struct_v >= 2) {
+      string s;
+      ::decode(s, bl);
+      user.from_str(s);
+    }
     DECODE_FINISH(bl);
   }
 };
diff --git a/src/cls/rgw/cls_rgw_types.cc b/src/cls/rgw/cls_rgw_types.cc
index faec1a3..79a5272 100644
--- a/src/cls/rgw/cls_rgw_types.cc
+++ b/src/cls/rgw/cls_rgw_types.cc
@@ -2,6 +2,7 @@
 #include "cls/rgw/cls_rgw_types.h"
 #include "common/Formatter.h"
 #include "common/ceph_json.h"
+#include "include/utime.h"
 
 
 void rgw_bucket_pending_info::generate_test_instances(list<rgw_bucket_pending_info*>& o)
@@ -16,7 +17,8 @@ void rgw_bucket_pending_info::generate_test_instances(list<rgw_bucket_pending_in
 void rgw_bucket_pending_info::dump(Formatter *f) const
 {
   encode_json("state", (int)state, f);
-  encode_json("timestamp", timestamp, f);
+  utime_t ut(timestamp);
+  encode_json("timestamp", ut, f);
   encode_json("op", (int)op, f);
 }
 
@@ -24,7 +26,8 @@ void rgw_bucket_pending_info::decode_json(JSONObj *obj) {
   int val;
   JSONDecoder::decode_json("state", val, obj);
   state = (RGWPendingState)val;
-  JSONDecoder::decode_json("timestamp", timestamp, obj);
+  utime_t ut(timestamp);
+  JSONDecoder::decode_json("timestamp", ut, obj);
   JSONDecoder::decode_json("op", val, obj);
   op = (uint8_t)val;
 }
@@ -51,7 +54,8 @@ void rgw_bucket_dir_entry_meta::dump(Formatter *f) const
 {
   encode_json("category", (int)category, f);
   encode_json("size", size, f);
-  encode_json("mtime", mtime, f);
+  utime_t ut(mtime);
+  encode_json("mtime", ut, f);
   encode_json("etag", etag, f);
   encode_json("owner", owner, f);
   encode_json("owner_display_name", owner_display_name, f);
@@ -64,7 +68,8 @@ void rgw_bucket_dir_entry_meta::decode_json(JSONObj *obj) {
   JSONDecoder::decode_json("category", val, obj);
   category = (uint8_t)val;
   JSONDecoder::decode_json("size", size, obj);
-  JSONDecoder::decode_json("mtime", mtime, obj);
+  utime_t ut(mtime);
+  JSONDecoder::decode_json("mtime", ut, obj);
   JSONDecoder::decode_json("etag", etag, obj);
   JSONDecoder::decode_json("owner", owner, obj);
   JSONDecoder::decode_json("owner_display_name", owner_display_name, obj);
@@ -308,6 +313,52 @@ void rgw_bucket_olh_log_entry::decode_json(JSONObj *obj)
   JSONDecoder::decode_json("key", key, obj);
   JSONDecoder::decode_json("delete_marker", delete_marker, obj);
 }
+void rgw_bi_log_entry::decode_json(JSONObj *obj)
+{
+  JSONDecoder::decode_json("op_id", id, obj);
+  JSONDecoder::decode_json("op_tag", tag, obj);
+  string op_str;
+  JSONDecoder::decode_json("op", op_str, obj);
+  if (op_str == "write") {
+    op = CLS_RGW_OP_ADD;
+  } else if (op_str == "del") {
+    op = CLS_RGW_OP_DEL;
+  } else if (op_str == "cancel") {
+    op = CLS_RGW_OP_CANCEL;
+  } else if (op_str == "unknown") {
+    op = CLS_RGW_OP_UNKNOWN;
+  } else if (op_str == "link_olh") {
+    op = CLS_RGW_OP_LINK_OLH;
+  } else if (op_str == "link_olh_del") {
+    op = CLS_RGW_OP_LINK_OLH_DM;
+  } else if (op_str == "unlink_instance") {
+    op = CLS_RGW_OP_UNLINK_INSTANCE;
+  } else {
+    op = CLS_RGW_OP_UNKNOWN;
+  }
+  JSONDecoder::decode_json("object", object, obj);
+  JSONDecoder::decode_json("instance", instance, obj);
+  string state_str;
+  JSONDecoder::decode_json("state", state_str, obj);
+  if (state_str == "pending") {
+    state = CLS_RGW_STATE_PENDING_MODIFY;
+  } else if (state_str == "complete") {
+    state = CLS_RGW_STATE_COMPLETE;
+  } else {
+    state = CLS_RGW_STATE_UNKNOWN;
+  }
+  JSONDecoder::decode_json("index_ver", index_ver, obj);
+  utime_t ut;
+  JSONDecoder::decode_json("timestamp", ut, obj);
+  timestamp = ut.to_real_time();
+  uint32_t f;
+  JSONDecoder::decode_json("bilog_flags", f, obj);
+  JSONDecoder::decode_json("ver", ver, obj);
+  bilog_flags = (uint16_t)f;
+  JSONDecoder::decode_json("owner", owner, obj);
+  JSONDecoder::decode_json("owner_display_name", owner_display_name, obj);
+}
+
 void rgw_bi_log_entry::dump(Formatter *f) const
 {
   f->dump_string("op_id", id);
@@ -355,11 +406,15 @@ void rgw_bi_log_entry::dump(Formatter *f) const
   }
 
   f->dump_int("index_ver", index_ver);
-  timestamp.gmtime(f->dump_stream("timestamp"));
+  utime_t ut(timestamp);
+  ut.gmtime_nsec(f->dump_stream("timestamp"));
   f->open_object_section("ver");
   ver.dump(f);
   f->close_section();
+  f->dump_int("bilog_flags", bilog_flags);
   f->dump_bool("versioned", (bilog_flags & RGW_BILOG_FLAG_VERSIONED_OP) != 0);
+  f->dump_string("owner", owner);
+  f->dump_string("owner_display_name", owner_display_name);
 }
 
 void rgw_bi_log_entry::generate_test_instances(list<rgw_bi_log_entry*>& ls)
@@ -368,7 +423,7 @@ void rgw_bi_log_entry::generate_test_instances(list<rgw_bi_log_entry*>& ls)
   ls.push_back(new rgw_bi_log_entry);
   ls.back()->id = "midf";
   ls.back()->object = "obj";
-  ls.back()->timestamp = utime_t(2, 3);
+  ls.back()->timestamp = ceph::real_clock::from_ceph_timespec({2, 3});
   ls.back()->index_ver = 4323;
   ls.back()->tag = "tagasdfds";
   ls.back()->op = CLS_RGW_OP_DEL;
diff --git a/src/cls/rgw/cls_rgw_types.h b/src/cls/rgw/cls_rgw_types.h
index dfa9286..a7d3b7a 100644
--- a/src/cls/rgw/cls_rgw_types.h
+++ b/src/cls/rgw/cls_rgw_types.h
@@ -4,9 +4,11 @@
 #include <map>
 
 #include "include/types.h"
-#include "include/utime.h"
+#include "common/ceph_time.h"
 #include "common/Formatter.h"
 
+#include "rgw/rgw_basic_types.h"
+
 #define CEPH_RGW_REMOVE 'r'
 #define CEPH_RGW_UPDATE 'u'
 #define CEPH_RGW_TAG_TIMEOUT 60*60*24
@@ -20,6 +22,7 @@ namespace ceph {
 enum RGWPendingState {
   CLS_RGW_STATE_PENDING_MODIFY = 0,
   CLS_RGW_STATE_COMPLETE       = 1,
+  CLS_RGW_STATE_UNKNOWN        = 2,
 };
 
 enum RGWModifyOp {
@@ -36,9 +39,17 @@ enum RGWBILogFlags {
   RGW_BILOG_FLAG_VERSIONED_OP = 0x1,
 };
 
+enum RGWCheckMTimeType {
+  CLS_RGW_CHECK_TIME_MTIME_EQ = 0,
+  CLS_RGW_CHECK_TIME_MTIME_LT = 1,
+  CLS_RGW_CHECK_TIME_MTIME_LE = 2,
+  CLS_RGW_CHECK_TIME_MTIME_GT = 3,
+  CLS_RGW_CHECK_TIME_MTIME_GE = 4,
+};
+
 struct rgw_bucket_pending_info {
   RGWPendingState state;
-  utime_t timestamp;
+  ceph::real_time timestamp;
   uint8_t op;
 
   rgw_bucket_pending_info() : state(CLS_RGW_STATE_PENDING_MODIFY), op(0) {}
@@ -69,7 +80,7 @@ WRITE_CLASS_ENCODER(rgw_bucket_pending_info)
 struct rgw_bucket_dir_entry_meta {
   uint8_t category;
   uint64_t size;
-  utime_t mtime;
+  ceph::real_time mtime;
   string etag;
   string owner;
   string owner_display_name;
@@ -77,7 +88,7 @@ struct rgw_bucket_dir_entry_meta {
   uint64_t accounted_size;
 
   rgw_bucket_dir_entry_meta() :
-  category(0), size(0), accounted_size(0) { mtime.set_from_double(0); }
+  category(0), size(0), accounted_size(0) { }
 
   void encode(bufferlist &bl) const {
     ENCODE_START(4, 3, bl);
@@ -463,18 +474,20 @@ struct rgw_bi_log_entry {
   string id;
   string object;
   string instance;
-  utime_t timestamp;
+  ceph::real_time timestamp;
   rgw_bucket_entry_ver ver;
   RGWModifyOp op;
   RGWPendingState state;
   uint64_t index_ver;
   string tag;
   uint16_t bilog_flags;
+  string owner; /* only being set if it's a delete marker */
+  string owner_display_name; /* only being set if it's a delete marker */
 
   rgw_bi_log_entry() : op(CLS_RGW_OP_UNKNOWN), state(CLS_RGW_STATE_PENDING_MODIFY), index_ver(0), bilog_flags(0) {}
 
   void encode(bufferlist &bl) const {
-    ENCODE_START(2, 1, bl);
+    ENCODE_START(3, 1, bl);
     ::encode(id, bl);
     ::encode(object, bl);
     ::encode(timestamp, bl);
@@ -487,6 +500,8 @@ struct rgw_bi_log_entry {
     encode_packed_val(index_ver, bl);
     ::encode(instance, bl);
     ::encode(bilog_flags, bl);
+    ::encode(owner, bl);
+    ::encode(owner_display_name, bl);
     ENCODE_FINISH(bl);
   }
   void decode(bufferlist::iterator &bl) {
@@ -506,10 +521,19 @@ struct rgw_bi_log_entry {
       ::decode(instance, bl);
       ::decode(bilog_flags, bl);
     }
+    if (struct_v >= 3) {
+      ::decode(owner, bl);
+      ::decode(owner_display_name, bl);
+    }
     DECODE_FINISH(bl);
   }
   void dump(Formatter *f) const;
+  void decode_json(JSONObj *obj);
   static void generate_test_instances(list<rgw_bi_log_entry*>& o);
+  
+  bool is_versioned() {
+    return ((bilog_flags & RGW_BILOG_FLAG_VERSIONED_OP) != 0);
+  }
 };
 WRITE_CLASS_ENCODER(rgw_bi_log_entry)
 
@@ -640,7 +664,8 @@ WRITE_CLASS_ENCODER(rgw_usage_data)
 
 
 struct rgw_usage_log_entry {
-  string owner;
+  rgw_user owner;
+  rgw_user payer; /* if empty, same as owner */
   string bucket;
   uint64_t epoch;
   rgw_usage_data total_usage; /* this one is kept for backwards compatibility */
@@ -648,10 +673,11 @@ struct rgw_usage_log_entry {
 
   rgw_usage_log_entry() : epoch(0) {}
   rgw_usage_log_entry(string& o, string& b) : owner(o), bucket(b), epoch(0) {}
+  rgw_usage_log_entry(string& o, string& p, string& b) : owner(o), payer(p), bucket(b), epoch(0) {}
 
   void encode(bufferlist& bl) const {
-    ENCODE_START(2, 1, bl);
-    ::encode(owner, bl);
+    ENCODE_START(3, 1, bl);
+    ::encode(owner.to_str(), bl);
     ::encode(bucket, bl);
     ::encode(epoch, bl);
     ::encode(total_usage.bytes_sent, bl);
@@ -659,13 +685,16 @@ struct rgw_usage_log_entry {
     ::encode(total_usage.ops, bl);
     ::encode(total_usage.successful_ops, bl);
     ::encode(usage_map, bl);
+    ::encode(payer.to_str(), bl);
     ENCODE_FINISH(bl);
   }
 
 
    void decode(bufferlist::iterator& bl) {
-    DECODE_START(2, bl);
-    ::decode(owner, bl);
+    DECODE_START(3, bl);
+    string s;
+    ::decode(s, bl);
+    owner.from_str(s);
     ::decode(bucket, bl);
     ::decode(epoch, bl);
     ::decode(total_usage.bytes_sent, bl);
@@ -677,6 +706,11 @@ struct rgw_usage_log_entry {
     } else {
       ::decode(usage_map, bl);
     }
+    if (struct_v >= 3) {
+      string p;
+      ::decode(p, bl);
+      payer.from_str(p);
+    }
     DECODE_FINISH(bl);
   }
 
@@ -685,7 +719,9 @@ struct rgw_usage_log_entry {
       owner = e.owner;
       bucket = e.bucket;
       epoch = e.epoch;
+      payer = e.payer;
     }
+
     map<string, rgw_usage_data>::const_iterator iter;
     for (iter = e.usage_map.begin(); iter != e.usage_map.end(); ++iter) {
       if (!categories || !categories->size() || categories->count(iter->first)) {
@@ -734,7 +770,7 @@ struct rgw_user_bucket {
   string bucket;
 
   rgw_user_bucket() {}
-  rgw_user_bucket(string &u, string& b) : user(u), bucket(b) {}
+  rgw_user_bucket(const string& u, const string& b) : user(u), bucket(b) {}
 
   void encode(bufferlist& bl) const {
     ENCODE_START(1, 1, bl);
@@ -855,7 +891,7 @@ struct cls_rgw_gc_obj_info
 {
   string tag;
   cls_rgw_obj_chain chain;
-  utime_t time;
+  ceph::real_time time;
 
   cls_rgw_gc_obj_info() {}
 
@@ -886,7 +922,8 @@ struct cls_rgw_gc_obj_info
     ls.push_back(new cls_rgw_gc_obj_info);
     ls.push_back(new cls_rgw_gc_obj_info);
     ls.back()->tag = "footag";
-    ls.back()->time = utime_t(21, 32);
+    ceph_timespec ts{21, 32};
+    ls.back()->time = ceph::real_clock::from_ceph_timespec(ts);
   }
 };
 WRITE_CLASS_ENCODER(cls_rgw_gc_obj_info)
diff --git a/src/cls/user/cls_user_client.cc b/src/cls/user/cls_user_client.cc
index 279117e..b2b4cbb 100644
--- a/src/cls/user/cls_user_client.cc
+++ b/src/cls/user/cls_user_client.cc
@@ -18,7 +18,7 @@ void cls_user_set_buckets(librados::ObjectWriteOperation& op, list<cls_user_buck
   cls_user_set_buckets_op call;
   call.entries = entries;
   call.add = add;
-  call.time = ceph_clock_now(NULL);
+  call.time = real_clock::now();
   ::encode(call, in);
   op.exec("user", "set_buckets_info", in);
 }
@@ -27,7 +27,7 @@ void cls_user_complete_stats_sync(librados::ObjectWriteOperation& op)
 {
   bufferlist in;
   cls_user_complete_stats_sync_op call;
-  call.time = ceph_clock_now(NULL);
+  call.time = real_clock::now();
   ::encode(call, in);
   op.exec("user", "complete_stats_sync", in);
 }
diff --git a/src/cls/user/cls_user_ops.cc b/src/cls/user/cls_user_ops.cc
index c50ab6a..68fc841 100644
--- a/src/cls/user/cls_user_ops.cc
+++ b/src/cls/user/cls_user_ops.cc
@@ -10,7 +10,7 @@ void cls_user_set_buckets_op::dump(Formatter *f) const
 {
   encode_json("entries", entries, f);
   encode_json("add", add, f);
-  encode_json("time", time, f);
+  encode_json("time", utime_t(time), f);
 }
 
 void cls_user_set_buckets_op::generate_test_instances(list<cls_user_set_buckets_op*>& ls)
@@ -23,7 +23,7 @@ void cls_user_set_buckets_op::generate_test_instances(list<cls_user_set_buckets_
     op->entries.push_back(e);
   }
   op->add = true;
-  op->time = utime_t(1, 0);
+  op->time = utime_t(1, 0).to_real_time();
   ls.push_back(op);
 }
 
@@ -101,14 +101,14 @@ void cls_user_get_header_ret::generate_test_instances(list<cls_user_get_header_r
 
 void cls_user_complete_stats_sync_op::dump(Formatter *f) const
 {
-  encode_json("time", time, f);
+  encode_json("time", utime_t(time), f);
 }
 
 void cls_user_complete_stats_sync_op::generate_test_instances(list<cls_user_complete_stats_sync_op*>& ls)
 {
   ls.push_back(new cls_user_complete_stats_sync_op);
   cls_user_complete_stats_sync_op *op = new cls_user_complete_stats_sync_op;
-  op->time = utime_t(12345, 0);
+  op->time = utime_t(12345, 0).to_real_time();
   ls.push_back(op);
 }
 
diff --git a/src/cls/user/cls_user_ops.h b/src/cls/user/cls_user_ops.h
index 9b3686e..0e90b22 100644
--- a/src/cls/user/cls_user_ops.h
+++ b/src/cls/user/cls_user_ops.h
@@ -6,11 +6,12 @@
 
 #include "include/types.h"
 #include "cls_user_types.h"
+#include "common/ceph_time.h"
 
 struct cls_user_set_buckets_op {
   list<cls_user_bucket_entry> entries;
   bool add;
-  utime_t time; /* op time */
+  real_time time; /* op time */
 
   cls_user_set_buckets_op() : add(false) {}
 
@@ -159,7 +160,7 @@ struct cls_user_get_header_ret {
 WRITE_CLASS_ENCODER(cls_user_get_header_ret)
 
 struct cls_user_complete_stats_sync_op {
-  utime_t time;
+  real_time time;
 
   cls_user_complete_stats_sync_op() {}
 
diff --git a/src/cls/user/cls_user_types.cc b/src/cls/user/cls_user_types.cc
index b3a00f0..b8fc71a 100644
--- a/src/cls/user/cls_user_types.cc
+++ b/src/cls/user/cls_user_types.cc
@@ -40,7 +40,7 @@ void cls_user_bucket_entry::dump(Formatter *f) const
   encode_json("bucket", bucket, f);
   encode_json("size", size, f);
   encode_json("size_rounded", size_rounded, f);
-  encode_json("creation_time", creation_time, f);
+  encode_json("creation_time", utime_t(creation_time), f);
   encode_json("count", count, f);
   encode_json("user_stats_sync", user_stats_sync, f);
 }
@@ -50,7 +50,7 @@ void cls_user_gen_test_bucket_entry(cls_user_bucket_entry *entry, int i)
   cls_user_gen_test_bucket(&entry->bucket, i);
   entry->size = i + 1;
   entry->size_rounded = i + 2;
-  entry->creation_time = i + 3;
+  entry->creation_time = real_clock::from_time_t(i + 3);
   entry->count = i + 4;
   entry->user_stats_sync = true;
 }
@@ -88,15 +88,15 @@ void cls_user_stats::generate_test_instances(list<cls_user_stats*>& ls)
 void cls_user_gen_test_header(cls_user_header *h)
 {
   cls_user_gen_test_stats(&h->stats);
-  h->last_stats_sync = utime_t(1, 0);
-  h->last_stats_update = utime_t(2, 0);
+  h->last_stats_sync = utime_t(1, 0).to_real_time();
+  h->last_stats_update = utime_t(2, 0).to_real_time();
 }
   
 void cls_user_header::dump(Formatter *f) const
 {
   encode_json("stats", stats, f);
-  encode_json("last_stats_sync", last_stats_sync, f);
-  encode_json("last_stats_update", last_stats_update, f);
+  encode_json("last_stats_sync", utime_t(last_stats_sync), f);
+  encode_json("last_stats_update", utime_t(last_stats_update), f);
 }
 
 void cls_user_header::generate_test_instances(list<cls_user_header*>& ls)
diff --git a/src/cls/user/cls_user_types.h b/src/cls/user/cls_user_types.h
index 5abb488..9d5506a 100644
--- a/src/cls/user/cls_user_types.h
+++ b/src/cls/user/cls_user_types.h
@@ -7,6 +7,7 @@
 #include "include/encoding.h"
 #include "include/types.h"
 #include "include/utime.h"
+#include "common/ceph_time.h"
 
 /*
  * this needs to be compatible with with rgw_bucket, as it replaces it
@@ -72,16 +73,16 @@ struct cls_user_bucket_entry {
   cls_user_bucket bucket;
   size_t size;
   size_t size_rounded;
-  time_t creation_time;
+  real_time creation_time;
   uint64_t count;
   bool user_stats_sync;
 
-  cls_user_bucket_entry() : size(0), size_rounded(0), creation_time(0), count(0), user_stats_sync(false) {}
+  cls_user_bucket_entry() : size(0), size_rounded(0), count(0), user_stats_sync(false) {}
 
   void encode(bufferlist& bl) const {
-    ENCODE_START(6, 5, bl);
+    ENCODE_START(7, 5, bl);
     uint64_t s = size;
-    __u32 mt = creation_time;
+    __u32 mt = ceph::real_clock::to_time_t(creation_time);
     string empty_str;  // originally had the bucket name here, but we encode bucket later
     ::encode(empty_str, bl);
     ::encode(s, bl);
@@ -91,6 +92,7 @@ struct cls_user_bucket_entry {
     s = size_rounded;
     ::encode(s, bl);
     ::encode(user_stats_sync, bl);
+    ::encode(creation_time, bl);
     ENCODE_FINISH(bl);
   }
   void decode(bufferlist::iterator& bl) {
@@ -102,7 +104,9 @@ struct cls_user_bucket_entry {
     ::decode(s, bl);
     ::decode(mt, bl);
     size = s;
-    creation_time = mt;
+    if (struct_v < 7) {
+      creation_time = ceph::real_clock::from_time_t(mt);
+    }
     if (struct_v >= 2)
       ::decode(count, bl);
     if (struct_v >= 3)
@@ -112,6 +116,8 @@ struct cls_user_bucket_entry {
     size_rounded = s;
     if (struct_v >= 6)
       ::decode(user_stats_sync, bl);
+    if (struct_v >= 7)
+      ::decode(creation_time, bl);
     DECODE_FINISH(bl);
   }
   void dump(Formatter *f) const;
@@ -154,8 +160,8 @@ WRITE_CLASS_ENCODER(cls_user_stats)
  */
 struct cls_user_header {
   cls_user_stats stats;
-  utime_t last_stats_sync;     /* last time a full stats sync completed */
-  utime_t last_stats_update;   /* last time a stats update was done */
+  ceph::real_time last_stats_sync;     /* last time a full stats sync completed */
+  ceph::real_time last_stats_update;   /* last time a stats update was done */
 
   void encode(bufferlist& bl) const {
      ENCODE_START(1, 1, bl);
diff --git a/src/common/Continuation.h b/src/common/Continuation.h
index c7e3057..856c6b8 100644
--- a/src/common/Continuation.h
+++ b/src/common/Continuation.h
@@ -116,7 +116,6 @@ protected:
    virtual void _done() {
      on_finish->complete(rval);
      on_finish = NULL;
-     delete this;
      return;
    }
 
@@ -149,6 +148,7 @@ private:
     if (done ||
         (reported_done && stages_processing.empty())) {
       _done();
+      delete this;
     }
   }
 
diff --git a/src/common/Formatter.h b/src/common/Formatter.h
index d74fab7..6aeb05d 100644
--- a/src/common/Formatter.h
+++ b/src/common/Formatter.h
@@ -97,6 +97,7 @@ namespace ceph {
     virtual void output_header() {};
     virtual void output_footer() {};
     void flush(std::ostream& os);
+    using Formatter::flush; // don't hide Formatter::flush(bufferlist &bl)
     void reset();
     virtual void open_array_section(const char *name);
     void open_array_section_in_ns(const char *name, const char *ns);
@@ -142,6 +143,7 @@ namespace ceph {
     virtual void output_footer();
 
     void flush(std::ostream& os);
+    using Formatter::flush; // don't hide Formatter::flush(bufferlist &bl)
     void reset();
     void open_array_section(const char *name);
     void open_array_section_in_ns(const char *name, const char *ns);
@@ -184,6 +186,7 @@ namespace ceph {
     virtual void output_header() {};
     virtual void output_footer() {};
     void flush(std::ostream& os);
+    using Formatter::flush; // don't hide Formatter::flush(bufferlist &bl)
     void reset();
     virtual void open_array_section(const char *name);
     void open_array_section_in_ns(const char *name, const char *ns);
diff --git a/src/common/Graylog.cc b/src/common/Graylog.cc
index 8dde3d0..dd4f3b2 100644
--- a/src/common/Graylog.cc
+++ b/src/common/Graylog.cc
@@ -5,16 +5,15 @@
 
 #include <iostream>
 #include <sstream>
-#include <memory>
 
 #include <arpa/inet.h>
 
-#include <boost/asio.hpp>
-#include <boost/iostreams/filtering_stream.hpp>
-#include <boost/iostreams/filter/zlib.hpp>
 #include <boost/lexical_cast.hpp>
 
 #include "common/Formatter.h"
+#include "common/LogEntry.h"
+#include "log/Entry.h"
+#include "log/SubsystemMap.h"
 #include "include/uuid.h"
 
 namespace ceph {
@@ -71,7 +70,7 @@ void Graylog::set_hostname(const std::string& host)
   m_hostname = host;
 }
 
-void Graylog::set_fsid(uuid_d fsid)
+void Graylog::set_fsid(const uuid_d& fsid)
 {
   std::vector<char> buf(40);
   fsid.print(&buf[0]);
diff --git a/src/common/Graylog.h b/src/common/Graylog.h
index 7caa656..e305e08 100644
--- a/src/common/Graylog.h
+++ b/src/common/Graylog.h
@@ -7,19 +7,25 @@
 
 #include <memory>
 
-#include <boost/thread/mutex.hpp>
 #include <boost/asio.hpp>
 #include <boost/iostreams/filtering_stream.hpp>
 #include <boost/iostreams/filter/zlib.hpp>
 
-#include "log/Entry.h"
-#include "log/SubsystemMap.h"
-#include "common/LogEntry.h"
 #include "include/memory.h"
+#include "include/assert.h"  // boost clobbers this
+
+struct uuid_d;
+class LogEntry;
 
 namespace ceph {
+
+class Formatter;
+
 namespace log {
 
+struct Entry;
+class SubsystemMap;
+
 // Graylog logging backend: Convert log datastructures (LogEntry, Entry) to
 // GELF (http://www.graylog2.org/resources/gelf/specification) and send it
 // to a GELF UDP receiver
@@ -41,11 +47,11 @@ class Graylog
    * until set_destination is called
    * @param logger Value for key "_logger" in GELF
    */
-  Graylog(std::string logger);
+  explicit Graylog(std::string logger);
   virtual ~Graylog();
 
   void set_hostname(const std::string& host);
-  void set_fsid(uuid_d fsid);
+  void set_fsid(const uuid_d& fsid);
 
   void set_destination(const std::string& host, int port);
 
diff --git a/src/common/HTMLFormatter.cc b/src/common/HTMLFormatter.cc
index b10c296..63474ad 100644
--- a/src/common/HTMLFormatter.cc
+++ b/src/common/HTMLFormatter.cc
@@ -35,7 +35,7 @@
 namespace ceph {
 
 HTMLFormatter::HTMLFormatter(bool pretty)
-: XMLFormatter(pretty), m_header_done(false), m_status(0), m_status_name(NULL)
+: XMLFormatter(pretty), m_status(0), m_status_name(NULL)
 {
 }
 
diff --git a/src/common/HTMLFormatter.h b/src/common/HTMLFormatter.h
index c165efc..69c82a5 100644
--- a/src/common/HTMLFormatter.h
+++ b/src/common/HTMLFormatter.h
@@ -37,9 +37,7 @@ namespace ceph {
     /* with attrs */
     void dump_string_with_attrs(const char *name, const std::string& s, const FormatterAttrs& attrs);
   private:
-	template <typename T> void dump_template(const char *name, T arg);
-
-    bool m_header_done;
+    template <typename T> void dump_template(const char *name, T arg);
 
     int m_status;
     const char* m_status_name;
diff --git a/src/common/LogClient.cc b/src/common/LogClient.cc
index 5300c41..237ce4b 100644
--- a/src/common/LogClient.cc
+++ b/src/common/LogClient.cc
@@ -16,6 +16,7 @@
 
 #include "include/types.h"
 #include "include/str_map.h"
+#include "include/uuid.h"
 
 #include "msg/Messenger.h"
 #include "msg/Message.h"
@@ -34,6 +35,9 @@
 #include <sys/mount.h>
 #endif // DARWIN
 
+#include "common/Graylog.h"
+// wipe the assert() introduced by boost headers included by Graylog.h
+#include "include/assert.h"
 #include "common/LogClient.h"
 
 #include "common/config.h"
diff --git a/src/common/LogClient.h b/src/common/LogClient.h
index 84682ea..3bb4e47 100644
--- a/src/common/LogClient.h
+++ b/src/common/LogClient.h
@@ -17,8 +17,6 @@
 
 #include "common/LogEntry.h"
 #include "common/Mutex.h"
-#include "include/uuid.h"
-#include "common/Graylog.h"
 
 #include <iosfwd>
 #include <sstream>
@@ -29,10 +27,17 @@ class MLogAck;
 class Messenger;
 class MonMap;
 class Message;
+struct uuid_d;
 struct Connection;
 
 class LogChannel;
 
+namespace ceph {
+namespace log {
+  class Graylog;
+}
+}
+
 int parse_log_client_options(CephContext *cct,
 			     map<string,string> &log_to_monitors,
 			     map<string,string> &log_to_syslog,
@@ -177,7 +182,7 @@ private:
   std::string syslog_facility;
   bool log_to_syslog;
   bool log_to_monitors;
-  ceph::log::Graylog::Ref graylog;
+  shared_ptr<ceph::log::Graylog> graylog;
 
 
   friend class LogClientTemp;
diff --git a/src/common/Makefile.am b/src/common/Makefile.am
index 2851cf2..8b30eea 100644
--- a/src/common/Makefile.am
+++ b/src/common/Makefile.am
@@ -23,12 +23,14 @@ libcommon_internal_la_SOURCES = \
 	common/Finisher.cc \
 	common/environment.cc\
 	common/assert.cc \
+	xxHash/xxhash.c \
 	common/run_cmd.cc \
 	common/WorkQueue.cc \
 	common/ConfUtils.cc \
 	common/MemoryModel.cc \
 	common/armor.c \
 	common/fd.cc \
+	common/fs_types.cc \
 	common/safe_io.c \
 	common/snap_types.cc \
 	common/str_list.cc \
@@ -73,7 +75,9 @@ libcommon_internal_la_SOURCES = \
 	common/Cycles.cc \
 	common/ContextCompletion.cc \
 	common/TracepointProvider.cc \
-	common/PluginRegistry.cc
+	common/PluginRegistry.cc \
+	common/scrub_types.cc \
+	common/blkdev.cc
 
 common/PluginRegistry.cc: ./ceph_ver.h
 
@@ -101,12 +105,6 @@ libcommon_internal_la_SOURCES += \
         common/aix_errno.cc
 endif
 
-# used by RBD and FileStore
-if LINUX
-libcommon_internal_la_SOURCES += \
-	common/blkdev.cc
-endif
-
 if ENABLE_XIO
 libcommon_internal_la_SOURCES += \
 	common/address_helper.cc
@@ -122,9 +120,11 @@ libcommon_internal_la_SOURCES += \
 	osd/ECMsgTypes.cc \
 	osd/HitSet.cc \
 	mds/MDSMap.cc \
+	mds/FSMap.cc \
 	mds/inode_backtrace.cc \
 	mds/mdstypes.cc \
 	mds/flock.cc
+
 LIBCOMMON_DEPS += libcommon_internal.la
 noinst_LTLIBRARIES += libcommon_internal.la
 
@@ -154,7 +154,10 @@ noinst_HEADERS += \
 	common/sctp_crc32.h \
 	common/crc32c_intel_baseline.h \
 	common/crc32c_intel_fast.h \
-	common/crc32c_aarch64.h
+	common/crc32c_aarch64.h \
+	common/cohort_lru.h \
+	common/sstring.hh \
+	xxHash/xxhash.h
 
 
 # important; libmsg before libauth!
@@ -274,6 +277,7 @@ noinst_HEADERS += \
 	common/TracepointProvider.h \
 	common/event_socket.h \
 	common/PluginRegistry.h \
+	common/scrub_types.h \
 	common/ceph_time.h \
 	common/ceph_timer.h \
 	common/align.h \
diff --git a/src/common/MemoryModel.cc b/src/common/MemoryModel.cc
index 336c82a..92442b2 100644
--- a/src/common/MemoryModel.cc
+++ b/src/common/MemoryModel.cc
@@ -4,7 +4,9 @@
 #include "MemoryModel.h"
 #include "common/config.h"
 #include "debug.h"
+#if defined(__linux__)
 #include <malloc.h>
+#endif
 
 #include <fstream>
 
diff --git a/src/common/PluginRegistry.h b/src/common/PluginRegistry.h
index ab9abc1..1b09570 100644
--- a/src/common/PluginRegistry.h
+++ b/src/common/PluginRegistry.h
@@ -39,7 +39,7 @@ namespace ceph {
     void *library;
     CephContext *cct;
 
-    explicit Plugin(CephContext *cct) : cct(cct) {}
+    explicit Plugin(CephContext *cct) : library(NULL), cct(cct) {}
     virtual ~Plugin() {}
   };
 
diff --git a/src/common/RWLock.h b/src/common/RWLock.h
index 84aba2a..eddfa17 100644
--- a/src/common/RWLock.h
+++ b/src/common/RWLock.h
@@ -24,7 +24,7 @@
 #include "include/atomic.h"
 #include "common/valgrind.h"
 
-class RWLock
+class RWLock final
 {
   mutable pthread_rwlock_t L;
   std::string name;
@@ -35,13 +35,24 @@ class RWLock
   std::string unique_name(const char* name) const;
 
 public:
-  RWLock(const RWLock& other);
-  const RWLock& operator=(const RWLock& other);
+  RWLock(const RWLock& other) = delete;
+  const RWLock& operator=(const RWLock& other) = delete;
 
-  RWLock(const std::string &n, bool track_lock=true, bool ld=true)
+  RWLock(const std::string &n, bool track_lock=true, bool ld=true, bool prioritize_write=false)
     : name(n), id(-1), nrlock(0), nwlock(0), track(track_lock),
       lockdep(ld) {
-    pthread_rwlock_init(&L, NULL);
+    if (prioritize_write) {
+      pthread_rwlockattr_t attr;
+      pthread_rwlockattr_init(&attr);
+      // PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP
+      //   Setting the lock kind to this avoids writer starvation as long as
+      //   long as any read locking is not done in a recursive fashion.
+      pthread_rwlockattr_setkind_np(&attr,
+          PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP);
+      pthread_rwlock_init(&L, &attr);
+    } else {
+      pthread_rwlock_init(&L, NULL);
+    }
     ANNOTATE_BENIGN_RACE_SIZED(&id, sizeof(id), "RWLock lockdep id");
     ANNOTATE_BENIGN_RACE_SIZED(&nrlock, sizeof(nrlock), "RWlock nrlock");
     ANNOTATE_BENIGN_RACE_SIZED(&nwlock, sizeof(nwlock), "RWlock nwlock");
@@ -57,7 +68,7 @@ public:
     assert(track);
     return (nwlock.read() > 0);
   }
-  virtual ~RWLock() {
+  ~RWLock() {
     // The following check is racy but we are about to destroy
     // the object and we assume that there are no other users.
     if (track)
@@ -246,4 +257,4 @@ public:
   };
 };
 
-#endif // !_Mutex_Posix_
+#endif // !CEPH_RWLock_Posix__H
diff --git a/src/common/SubProcess.h b/src/common/SubProcess.h
index 82070ac..6106f75 100644
--- a/src/common/SubProcess.h
+++ b/src/common/SubProcess.h
@@ -87,7 +87,7 @@ public:
 
   void kill(int signo = SIGTERM) const;
 
-  const char* err() const;
+  const std::string err() const;
 
 protected:
   bool is_child() const { return pid == 0; }
@@ -219,8 +219,8 @@ inline void SubProcess::kill(int signo) const {
   assert(ret == 0);
 }
 
-inline const char* SubProcess::err() const {
-  return errstr.str().c_str();
+inline const std::string SubProcess::err() const {
+  return errstr.str();
 }
 
 class fd_buf : public std::streambuf {
diff --git a/src/common/Thread.cc b/src/common/Thread.cc
index 4d40016..1f716f9 100644
--- a/src/common/Thread.cc
+++ b/src/common/Thread.cc
@@ -54,7 +54,8 @@ Thread::Thread()
     pid(0),
     ioprio_class(-1),
     ioprio_priority(-1),
-    cpuid(-1)
+    cpuid(-1),
+    thread_name(NULL)
 {
 }
 
@@ -81,6 +82,8 @@ void *Thread::entry_wrapper()
   }
   if (pid && cpuid >= 0)
     _set_affinity(cpuid);
+
+  pthread_setname_np(pthread_self(), thread_name);
   return entry();
 }
 
@@ -145,6 +148,9 @@ int Thread::try_create(size_t stacksize)
 
 void Thread::create(const char *name, size_t stacksize)
 {
+  assert(strlen(name) < 16);
+  thread_name = name;
+
   int ret = try_create(stacksize);
   if (ret != 0) {
     char buf[256];
@@ -152,9 +158,6 @@ void Thread::create(const char *name, size_t stacksize)
 	     "failed with error %d", ret);
     dout_emergency(buf);
     assert(ret == 0);
-  } else if (thread_id > 0) {
-      assert(strlen(name) < 16);
-      pthread_setname_np(thread_id, name);
   }
 }
 
diff --git a/src/common/Thread.h b/src/common/Thread.h
index deced8f..54fd750 100644
--- a/src/common/Thread.h
+++ b/src/common/Thread.h
@@ -25,6 +25,7 @@ class Thread {
   pid_t pid;
   int ioprio_class, ioprio_priority;
   int cpuid;
+  const char *thread_name;
 
   void *entry_wrapper();
 
diff --git a/src/common/Throttle.cc b/src/common/Throttle.cc
index 469c808..3b909ee 100644
--- a/src/common/Throttle.cc
+++ b/src/common/Throttle.cc
@@ -2,6 +2,7 @@
 // vim: ts=8 sw=2 smarttab
 
 #include <errno.h>
+#include <thread>
 
 #include "common/Throttle.h"
 #include "common/dout.h"
@@ -237,6 +238,185 @@ int64_t Throttle::put(int64_t c)
   return count.read();
 }
 
+bool BackoffThrottle::set_params(
+  double _low_threshhold,
+  double _high_threshhold,
+  double _expected_throughput,
+  double _high_multiple,
+  double _max_multiple,
+  uint64_t _throttle_max,
+  ostream *errstream)
+{
+  bool valid = true;
+  if (_low_threshhold > _high_threshhold) {
+    valid = false;
+    if (errstream) {
+      *errstream << "low_threshhold (" << _low_threshhold
+		 << ") > high_threshhold (" << _high_threshhold
+		 << ")" << std::endl;
+    }
+  }
+
+  if (_high_multiple > _max_multiple) {
+    valid = false;
+    if (errstream) {
+      *errstream << "_high_multiple (" << _high_multiple
+		 << ") > _max_multiple (" << _max_multiple
+		 << ")" << std::endl;
+    }
+  }
+
+  if (_low_threshhold > 1 || _low_threshhold < 0) {
+    valid = false;
+    if (errstream) {
+      *errstream << "invalid low_threshhold (" << _low_threshhold << ")"
+		 << std::endl;
+    }
+  }
+
+  if (_high_threshhold > 1 || _high_threshhold < 0) {
+    valid = false;
+    if (errstream) {
+      *errstream << "invalid high_threshhold (" << _high_threshhold << ")"
+		 << std::endl;
+    }
+  }
+
+  if (_max_multiple < 0) {
+    valid = false;
+    if (errstream) {
+      *errstream << "invalid _max_multiple ("
+		 << _max_multiple << ")"
+		 << std::endl;
+    }
+  }
+
+  if (_high_multiple < 0) {
+    valid = false;
+    if (errstream) {
+      *errstream << "invalid _high_multiple ("
+		 << _high_multiple << ")"
+		 << std::endl;
+    }
+  }
+
+  if (_expected_throughput < 0) {
+    valid = false;
+    if (errstream) {
+      *errstream << "invalid _expected_throughput("
+		 << _expected_throughput << ")"
+		 << std::endl;
+    }
+  }
+
+  if (!valid)
+    return false;
+
+  locker l(lock);
+  low_threshhold = _low_threshhold;
+  high_threshhold = _high_threshhold;
+  high_delay_per_count = _high_multiple / _expected_throughput;
+  max_delay_per_count = _max_multiple / _expected_throughput;
+  max = _throttle_max;
+
+  if (high_threshhold - low_threshhold > 0) {
+    s0 = high_delay_per_count / (high_threshhold - low_threshhold);
+  } else {
+    low_threshhold = high_threshhold;
+    s0 = 0;
+  }
+
+  if (1 - high_threshhold > 0) {
+    s1 = (max_delay_per_count - high_delay_per_count)
+      / (1 - high_threshhold);
+  } else {
+    high_threshhold = 1;
+    s1 = 0;
+  }
+
+  _kick_waiters();
+  return true;
+}
+
+std::chrono::duration<double> BackoffThrottle::_get_delay(uint64_t c) const
+{
+  if (max == 0)
+    return std::chrono::duration<double>(0);
+
+  double r = ((double)current) / ((double)max);
+  if (r < low_threshhold) {
+    return std::chrono::duration<double>(0);
+  } else if (r < high_threshhold) {
+    return c * std::chrono::duration<double>(
+      (r - low_threshhold) * s0);
+  } else {
+    return c * std::chrono::duration<double>(
+      high_delay_per_count + ((r - high_threshhold) * s1));
+  }
+}
+
+std::chrono::duration<double> BackoffThrottle::get(uint64_t c)
+{
+  locker l(lock);
+  auto delay = _get_delay(c);
+
+  // fast path
+  if (delay == std::chrono::duration<double>(0) &&
+      waiters.empty() &&
+      ((max == 0) || (current == 0) || ((current + c) <= max))) {
+    current += c;
+    return std::chrono::duration<double>(0);
+  }
+
+  auto ticket = _push_waiter();
+
+  while (waiters.begin() != ticket) {
+    (*ticket)->wait(l);
+  }
+
+  auto start = std::chrono::system_clock::now();
+  delay = _get_delay(c);
+  while (((start + delay) > std::chrono::system_clock::now()) ||
+	 !((max == 0) || (current == 0) || ((current + c) <= max))) {
+    assert(ticket == waiters.begin());
+    (*ticket)->wait_until(l, start + delay);
+    delay = _get_delay(c);
+  }
+  waiters.pop_front();
+  _kick_waiters();
+
+  current += c;
+  return std::chrono::system_clock::now() - start;
+}
+
+uint64_t BackoffThrottle::put(uint64_t c)
+{
+  locker l(lock);
+  assert(current >= c);
+  current -= c;
+  _kick_waiters();
+  return current;
+}
+
+uint64_t BackoffThrottle::take(uint64_t c)
+{
+  locker l(lock);
+  current += c;
+  return current;
+}
+
+uint64_t BackoffThrottle::get_current()
+{
+  locker l(lock);
+  return current;
+}
+
+uint64_t BackoffThrottle::get_max()
+{
+  locker l(lock);
+  return max;
+}
+
 SimpleThrottle::SimpleThrottle(uint64_t max, bool ignore_enoent)
   : m_lock("SimpleThrottle"),
     m_max(max),
diff --git a/src/common/Throttle.h b/src/common/Throttle.h
index c04a931..f182c0c 100644
--- a/src/common/Throttle.h
+++ b/src/common/Throttle.h
@@ -8,6 +8,9 @@
 #include "Cond.h"
 #include <list>
 #include <map>
+#include <iostream>
+#include <condition_variable>
+#include <chrono>
 #include "include/atomic.h"
 #include "include/Context.h"
 
@@ -111,6 +114,105 @@ public:
   }
 };
 
+/**
+ * BackoffThrottle
+ *
+ * Creates a throttle which gradually induces delays when get() is called
+ * based on params low_threshhold, high_threshhold, expected_throughput,
+ * high_multiple, and max_multiple.
+ *
+ * In [0, low_threshhold), we want no delay.
+ *
+ * In [low_threshhold, high_threshhold), delays should be injected based
+ * on a line from 0 at low_threshhold to
+ * high_multiple * (1/expected_throughput) at high_threshhold.
+ *
+ * In [high_threshhold, 1), we want delays injected based on a line from
+ * (high_multiple * (1/expected_throughput)) at high_threshhold to
+ * (high_multiple * (1/expected_throughput)) +
+ * (max_multiple * (1/expected_throughput)) at 1.
+ *
+ * Let the current throttle ratio (current/max) be r, low_threshhold be l,
+ * high_threshhold be h, high_delay (high_multiple / expected_throughput) be e,
+ * and max_delay (max_muliple / expected_throughput) be m.
+ *
+ * delay = 0, r \in [0, l)
+ * delay = (r - l) * (e / (h - l)), r \in [l, h)
+ * delay = h + (r - h)((m - e)/(1 - h))
+ */
+class BackoffThrottle {
+  std::mutex lock;
+  using locker = std::unique_lock<std::mutex>;
+
+  unsigned next_cond = 0;
+
+  /// allocated once to avoid constantly allocating new ones
+  vector<std::condition_variable> conds;
+
+  /// pointers into conds
+  list<std::condition_variable*> waiters;
+
+  std::list<std::condition_variable*>::iterator _push_waiter() {
+    unsigned next = next_cond++;
+    if (next_cond == conds.size())
+      next_cond = 0;
+    return waiters.insert(waiters.end(), &(conds[next]));
+  }
+
+  void _kick_waiters() {
+    if (!waiters.empty())
+      waiters.front()->notify_all();
+  }
+
+  /// see above, values are in [0, 1].
+  double low_threshhold = 0;
+  double high_threshhold = 1;
+
+  /// see above, values are in seconds
+  double high_delay_per_count = 0;
+  double max_delay_per_count = 0;
+
+  /// Filled in in set_params
+  double s0 = 0; ///< e / (h - l), l != h, 0 otherwise
+  double s1 = 0; ///< (m - e)/(1 - h), 1 != h, 0 otherwise
+
+  /// max
+  uint64_t max = 0;
+  uint64_t current = 0;
+
+  std::chrono::duration<double> _get_delay(uint64_t c) const;
+
+public:
+  /**
+   * set_params
+   *
+   * Sets params.  If the params are invalid, returns false
+   * and populates errstream (if non-null) with a user compreshensible
+   * explanation.
+   */
+  bool set_params(
+    double low_threshhold,
+    double high_threshhold,
+    double expected_throughput,
+    double high_multiple,
+    double max_multiple,
+    uint64_t throttle_max,
+    ostream *errstream);
+
+  std::chrono::duration<double> get(uint64_t c = 1);
+  std::chrono::duration<double> wait() {
+    return get(0);
+  }
+  uint64_t put(uint64_t c = 1);
+  uint64_t take(uint64_t c = 1);
+  uint64_t get_current();
+  uint64_t get_max();
+
+  BackoffThrottle(
+    unsigned expected_concurrency ///< [in] determines size of conds
+    ) : conds(expected_concurrency) {}
+};
+
 
 /**
  * @class SimpleThrottle
diff --git a/src/common/TrackedOp.cc b/src/common/TrackedOp.cc
index f76587e..37e918a 100644
--- a/src/common/TrackedOp.cc
+++ b/src/common/TrackedOp.cc
@@ -203,8 +203,7 @@ bool OpTracker::check_ops_in_flight(std::vector<string> &warning_vector)
 
   int slow = 0;     // total slow
   int warned = 0;   // total logged
-  for (uint32_t iter = 0;
-       iter < num_optracker_shards && warned < log_threshold; iter++) {
+  for (uint32_t iter = 0; iter < num_optracker_shards; iter++) {
     ShardedTrackingData* sdata = sharded_in_flight_list[iter];
     assert(NULL != sdata);
     Mutex::Locker locker(sdata->ops_in_flight_lock_sharded);
@@ -215,12 +214,10 @@ bool OpTracker::check_ops_in_flight(std::vector<string> &warning_vector)
       slow++;
 
       // exponential backoff of warning intervals
-      if (((*i)->get_initiated() +
-	 (complaint_time * (*i)->warn_interval_multiplier)) < now) {
-      // will warn
+      if (warned < log_threshold &&
+         ((*i)->get_initiated() + (complaint_time * (*i)->warn_interval_multiplier)) < now) {
+        // will warn, increase counter
         warned++;
-        if (warned > log_threshold)
-          break;
 
         utime_t age = now - (*i)->get_initiated();
         stringstream ss;
@@ -247,7 +244,7 @@ bool OpTracker::check_ops_in_flight(std::vector<string> &warning_vector)
     warning_vector[0] = ss.str();
   }
 
-  return warned;
+  return warned > 0;
 }
 
 void OpTracker::get_age_ms_histogram(pow2_hist_t *h)
diff --git a/src/common/WeightedPriorityQueue.h b/src/common/WeightedPriorityQueue.h
index 6a77a6c..b1c48f3 100644
--- a/src/common/WeightedPriorityQueue.h
+++ b/src/common/WeightedPriorityQueue.h
@@ -15,345 +15,277 @@
 #ifndef WP_QUEUE_H
 #define WP_QUEUE_H
 
-#include "common/Formatter.h"
-#include "common/OpQueue.h"
+#include "OpQueue.h"
 
-#include <map>
-#include <list>
+#include <boost/intrusive/list.hpp>
+#include <boost/intrusive/rbtree.hpp>
+#include <boost/intrusive/avl_set.hpp>
 
-/**
- * Weighted Priority queue with strict priority queue
- *
- * This queue attempts to be fair to all classes of
- * operations but is also weighted so that higher classes
- * get more share of the operations.
- */
-
-template <typename T, typename K>
-class WeightedPriorityQueue : public OpQueue <T, K> {
-  int64_t total_priority;
+namespace bi = boost::intrusive;
 
-  typedef std::list<std::pair<unsigned, T>> ListPairs;
-  static unsigned filter_list_pairs(
-    ListPairs *l, std::function<bool (T)> f,
-    std::list<T> *out) {
-    unsigned ret = 0;
-    if (out) {
-      for (typename ListPairs::reverse_iterator i = l->rbegin();
-	   i != l->rend();
-	   ++i) {
-	if (f(i->second)) {
-	  out->push_front(i->second);
-	}
-      }
-    }
-    for (typename ListPairs::iterator i = l->begin();
-	 i != l->end(); ) {
-      if (f(i->second)) {
-	l->erase(i++);
-	++ret;
-      } else {
-	++i;
-      }
-    }
-    return ret;
+template <typename T>
+class MapKey
+{
+  public:
+  bool operator()(const unsigned i, const T &k) const
+  {
+    return i < k.key;
   }
+  bool operator()(const T &k, const unsigned i) const
+  {
+    return k.key < i;
+  }
+};
 
-  struct SubQueue {
-  private:
-    typedef std::map<K, ListPairs> Classes;
-    Classes q;
-    typename Classes::iterator cur;
-    unsigned q_size;
+template <typename T>
+class DelItem
+{
   public:
-    SubQueue(const SubQueue &other)
-      : q(other.q),
-	cur(q.begin()),
-	q_size(0) {}
-    SubQueue()
-      :	cur(q.begin()),
-	q_size(0) {}
-    void enqueue_front(K cl, unsigned cost, T item) {
-      q[cl].push_front(std::make_pair(cost, item));
-      if (cur == q.end()) {
-	cur = q.begin();
-      }
-      ++q_size;
-    }
-    void enqueue(K cl, unsigned cost, T item) {
-      q[cl].push_back(std::make_pair(cost, item));
-      if (cur == q.end()) {
-	cur = q.begin();
-      }
-      ++q_size;
-    }
-    std::pair<unsigned, T> front() const {
-      assert(!q.empty());
-      assert(cur != q.end());
-      assert(!cur->second.empty());
-      return cur->second.front();
-    }
-    void pop_front() {
-      assert(!q.empty());
-      assert(cur != q.end());
-      assert(!cur->second.empty());
-      cur->second.pop_front();
-      if (cur->second.empty()) {
-	cur = q.erase(cur);
-      } else {
-	++cur;
-      }
-      if (cur == q.end()) {
-	cur = q.begin();
+  void operator()(T* delete_this)
+    { delete delete_this; }
+};
+
+template <typename T, typename K>
+class WeightedPriorityQueue :  public OpQueue <T, K>
+{
+  private:
+    class ListPair : public bi::list_base_hook<>
+    {
+      public:
+	K klass;
+        unsigned cost;
+        T item;
+        ListPair(K& k, unsigned c, T& i) :
+	  klass(k),
+          cost(c),
+          item(i)
+          {}
+    };
+    class SubQueue : public bi::set_base_hook<>
+    {
+      typedef bi::list<ListPair> QueueItems;
+      typedef typename QueueItems::iterator QI;
+      public:
+	unsigned key;	// priority
+	QueueItems qitems;
+	SubQueue(unsigned& p) :
+	  key(p)
+	  {}
+      bool empty() const {
+        return qitems.empty();
       }
-      --q_size;
-    }
-    unsigned size() const {
-      return q_size;
-    }
-    bool empty() const {
-      return (q_size == 0);
-    }
-    unsigned remove_by_filter(std::function<bool (T)> f, std::list<T> *out) {
-      unsigned count = 0;
-      for (typename Classes::iterator i = q.begin();
-	   i != q.end(); ) {
-	count += filter_list_pairs(&(i->second), f, out);
-	if (i->second.empty()) {
-	  if (cur == i) {
-	    ++cur;
-	  }
-	  q.erase(i++);
+      void insert(K& cl, unsigned cost, T& item, bool front = false) {
+	if (front) {
+	  qitems.push_front(*new ListPair(cl, cost, item));
 	} else {
-	  ++i;
+	  qitems.push_back(*new ListPair(cl, cost, item));
 	}
       }
-      if (cur == q.end()) {
-	cur = q.begin();
+      unsigned get_cost() const {
+	return qitems.begin()->cost;
       }
-      q_size -= count;
-      return count;
-    }
-    unsigned remove_by_class(K k, std::list<T> *out) {
-      typename Classes::iterator i = q.find(k);
-      if (i == q.end()) {
-	return 0;
+      T pop() {
+	T ret = qitems.begin()->item;
+	qitems.erase_and_dispose(qitems.begin(), DelItem<ListPair>());
+	return ret;
       }
-      unsigned count = i->second.size();
-      q_size -= count;
-      if (out) {
-	for (typename ListPairs::reverse_iterator j =
-	       i->second.rbegin();
-	     j != i->second.rend();
-	     ++j) {
-	  out->push_front(j->second);
-	}
+      unsigned filter_list_pairs(std::function<bool (T)>& f, std::list<T>* out) {
+	unsigned count = 0;
+        // intrusive containers can't erase with a reverse_iterator
+        // so we have to walk backwards on our own. Since there is
+        // no iterator before begin, we have to test at the end.
+        for (QI i = --qitems.end();; --i) {
+          if (f(i->item)) {
+            if (out) {
+              out->push_front(i->item);
+            }
+            i = qitems.erase_and_dispose(i, DelItem<ListPair>());
+            ++count;
+          }
+          if (i == qitems.begin()) {
+            break;
+          }
+        }
+	return count;
       }
-      if (i == cur) {
-	++cur;
+      unsigned filter_class(K& cl, std::list<T>* out) {
+	unsigned count = 0;
+        for (QI i = --qitems.end();; --i) {
+	  if (i->klass == cl) {
+	    if (out) {
+	      out->push_front(i->item);
+	    }
+	    i = qitems.erase_and_dispose(i, DelItem<ListPair>());
+	    ++count;
+	  }
+	  if (i == qitems.begin()) {
+	    break;
+	  }
+        }
+	return count;
       }
-      q.erase(i);
-      if (cur == q.end()) {
-	cur = q.begin();
+      void dump(ceph::Formatter *f) const {
+	f->dump_int("num_keys", qitems.size());
+	f->dump_int("first_item_cost", qitems.begin()->cost);
       }
-      return count;
-    }
+    };
+    class Queue {
+      typedef bi::rbtree<SubQueue> SubQueues;
+      typedef typename SubQueues::iterator Sit;
+      SubQueues queues;
+      unsigned total_prio;
+      unsigned max_cost;
+      public:
+	unsigned size;
+	Queue() :
+	  total_prio(0),
+	  max_cost(0),
+	  size(0)
+	  {}
+	bool empty() const {
+	  return !size;
+	}
+	void insert(unsigned p, K& cl, unsigned cost, T& item, bool front = false) {
+	  typename SubQueues::insert_commit_data insert_data;
+      	  std::pair<typename SubQueues::iterator, bool> ret =
+      	    queues.insert_unique_check(p, MapKey<SubQueue>(), insert_data);
+      	  if (ret.second) {
+      	    ret.first = queues.insert_unique_commit(*new SubQueue(p), insert_data);
+	    total_prio += p;
+      	  }
+      	  ret.first->insert(cl, cost, item, front);
+	  if (cost > max_cost) {
+	    max_cost = cost;
+	  }
+	  ++size;
+	}
+	T pop(bool strict = false) {
+	  --size;
+	  Sit i = --queues.end();
+	  if (strict) {
+	    T ret = i->pop();
+	    if (i->empty()) {
+	      queues.erase_and_dispose(i, DelItem<SubQueue>());
+	    }
+	    return ret;
+	  }
+	  if (queues.size() > 1) {
+	    while (true) {
+	      // Pick a new priority out of the total priority.
+	      unsigned prio = rand() % total_prio + 1;
+	      unsigned tp = total_prio - i->key;
+	      // Find the priority coresponding to the picked number.
+	      // Subtract high priorities to low priorities until the picked number
+	      // is more than the total and try to dequeue that priority.
+	      // Reverse the direction from previous implementation because there is a higher
+	      // chance of dequeuing a high priority op so spend less time spinning.
+	      while (prio <= tp) {
+		--i;
+		tp -= i->key;
+	      }
+	      // Flip a coin to see if this priority gets to run based on cost.
+	      // The next op's cost is multiplied by .9 and subtracted from the
+	      // max cost seen. Ops with lower costs will have a larger value
+	      // and allow them to be selected easier than ops with high costs.
+	      if (max_cost == 0 || rand() % max_cost <=
+		  (max_cost - ((i->get_cost() * 9) / 10))) {
+		break;
+	      }
+	      i = --queues.end();
+	    }
+	  }
+	  T ret = i->pop();
+	  if (i->empty()) {
+	    total_prio -= i->key;
+	    queues.erase_and_dispose(i, DelItem<SubQueue>());
+	  }
+	  return ret;
+	}
+	void filter_list_pairs(std::function<bool (T)>& f, std::list<T>* out) {
+	  for (Sit i = queues.begin(); i != queues.end();) {
+      	    size -= i->filter_list_pairs(f, out);
+	    if (i->empty()) {
+	      total_prio -= i->key;
+	      i = queues.erase_and_dispose(i, DelItem<SubQueue>());
+	    } else {
+	      ++i;
+	    }
+      	  }
+	}
+	void filter_class(K& cl, std::list<T>* out) {
+	  for (Sit i = queues.begin(); i != queues.end();) {
+	    size -= i->filter_class(cl, out);
+	    if (i->empty()) {
+	      total_prio -= i->key;
+	      i = queues.erase_and_dispose(i, DelItem<SubQueue>());
+	    } else {
+	      ++i;
+	    }
+	  }
+	}
+	void dump(ceph::Formatter *f) const {
+	  for (typename SubQueues::const_iterator i = queues.begin();
+	        i != queues.end(); ++i) {
+	    f->dump_int("total_priority", total_prio);
+	    f->dump_int("max_cost", max_cost);
+	    f->open_object_section("subqueue");
+	    f->dump_int("priority", i->key);
+	    i->dump(f);
+	    f->close_section();
+	  }
+	}
+    };
 
-    void dump(ceph::Formatter *f) const {
-      f->dump_int("num_keys", q.size());
-      if (!empty()) {
-	f->dump_int("first_item_cost", front().first);
+    Queue strict;
+    Queue normal;
+  public:
+    WeightedPriorityQueue(unsigned max_per, unsigned min_c) :
+      strict(),
+      normal()
+      {
+	std::srand(time(0));
       }
+    unsigned length() const override final {
+      return strict.size + normal.size;
     }
-  };
-
-  unsigned high_size, wrr_size;
-  unsigned max_cost;
-
-  typedef std::map<unsigned, SubQueue> SubQueues;
-  SubQueues high_queue;
-  SubQueues queue;
-  typename SubQueues::reverse_iterator dq;
-
-  SubQueue *create_queue(unsigned priority) {
-    typename SubQueues::iterator p = queue.find(priority);
-    if (p != queue.end()) {
-      return &p->second;
+    void remove_by_filter(std::function<bool (T)> f, std::list<T>* removed = 0) override final {
+      strict.filter_list_pairs(f, removed);
+      normal.filter_list_pairs(f, removed);
     }
-    total_priority += priority;
-    SubQueue *sq = &queue[priority];
-    return sq;
-  }
-
-  void remove_queue(unsigned priority) {
-    assert(queue.count(priority));
-    dq = (typename SubQueues::reverse_iterator) queue.erase(queue.find(priority));
-    if (dq == queue.rend()) {
-      dq = queue.rbegin();
+    void remove_by_class(K cl, std::list<T>* removed = 0) override final {
+      strict.filter_class(cl, removed);
+      normal.filter_class(cl, removed);
     }
-    total_priority -= priority;
-    assert(total_priority >= 0);
-  }
-
-public:
-  WeightedPriorityQueue(unsigned max_per, unsigned min_c)
-    : total_priority(0),
-      high_size(0),
-      wrr_size(0),
-      max_cost(0),
-      dq(queue.rbegin())
-  {
-    srand(time(0));
-  }
-
-  unsigned length() const override final {
-    return high_size + wrr_size;
-  }
-
-  void remove_by_filter(
-      std::function<bool (T)> f, std::list<T> *removed = 0) override final {
-    for (typename SubQueues::iterator i = queue.begin();
-	 i != queue.end(); ++i) {
-      wrr_size -= i->second.remove_by_filter(f, removed);
-      unsigned priority = i->first;
-      if (i->second.empty()) {
-	remove_queue(priority);
-      }
+    bool empty() const override final {
+      return !(strict.size + normal.size);
     }
-    for (typename SubQueues::iterator i = high_queue.begin();
-	 i != high_queue.end();
-	 ) {
-      high_size -= i->second.remove_by_filter(f, removed);
-      if (i->second.empty()) {
-	high_queue.erase(i++);
-      } else {
-	++i;
-      }
+    void enqueue_strict(K cl, unsigned p, T item) override final {
+      strict.insert(p, cl, 0, item);
     }
-  }
-
-  void remove_by_class(K k, std::list<T> *out = 0) override final {
-    for (typename SubQueues::iterator i = queue.begin();
-	 i != queue.end(); ++i) {
-      wrr_size -= i->second.remove_by_class(k, out);
-      unsigned priority = i->first;
-      if (i->second.empty()) {
-	remove_queue(priority);
-      }
+    void enqueue_strict_front(K cl, unsigned p, T item) override final {
+      strict.insert(p, cl, 0, item, true);
     }
-    for (typename SubQueues::iterator i = high_queue.begin();
-	 i != high_queue.end();
-	 ) {
-      high_size -= i->second.remove_by_class(k, out);
-      if (i->second.empty()) {
-	high_queue.erase(i++);
-      } else {
-	++i;
-      }
+    void enqueue(K cl, unsigned p, unsigned cost, T item) override final {
+      normal.insert(p, cl, cost, item);
     }
-  }
-
-  void enqueue_strict(K cl, unsigned priority, T item) override final {
-    high_queue[priority].enqueue(cl, 0, item);
-    ++high_size;
-  }
-
-  void enqueue_strict_front(K cl, unsigned priority, T item) override final {
-    high_queue[priority].enqueue_front(cl, 0, item);
-    ++high_size;
-  }
-
-  void enqueue(K cl, unsigned priority, unsigned cost, T item) override final {
-    if (cost > max_cost) {
-      max_cost = cost;
-    }
-    create_queue(priority)->enqueue(cl, cost, item);
-    ++wrr_size;
-  }
-
-  void enqueue_front(K cl, unsigned priority, unsigned cost, T item) override final {
-    if (cost > max_cost) {
-      max_cost = cost;
-    }
-    create_queue(priority)->enqueue_front(cl, cost, item);
-    ++wrr_size;
-  }
-
-  bool empty() const override final {
-    assert(total_priority >= 0);
-    assert((total_priority == 0) || !queue.empty());
-    return (high_size + wrr_size  == 0) ? true : false;
-  }
-
-  T dequeue() override final {
-    assert(!empty());
-
-    if (!high_queue.empty()) {
-      T ret = high_queue.rbegin()->second.front().second;
-      high_queue.rbegin()->second.pop_front();
-      if (high_queue.rbegin()->second.empty()) {
-	high_queue.erase(high_queue.rbegin()->first);
-      }
-      --high_size;
-      return ret;
+    void enqueue_front(K cl, unsigned p, unsigned cost, T item) override final {
+      normal.insert(p, cl, cost, item, true);
     }
-    // If there is more than one priority, choose one to run.
-    if (dq->second.size() != wrr_size) {
-      while (true) {
-	// Pick a new priority out of the total priority.
-	unsigned prio = rand() % total_priority;
-	typename SubQueues::iterator i = queue.begin();
-	unsigned tp = i->first;
-	// Find the priority coresponding to the picked number.
-	// Add low priorities to high priorities until the picked number
-	// is less than the total and try to dequeue that priority.
-	while (prio > tp) {
-	  ++i;
-	  tp += i->first;
-	}
-	dq = (typename SubQueues::reverse_iterator) ++i;
-	// Flip a coin to see if this priority gets to run based on cost.
-	// The next op's cost is multiplied by .9 and subtracted from the
-	// max cost seen. Ops with lower costs will have a larger value
-	// and allow them to be selected easier than ops with high costs.
-	if (max_cost == 0 || rand() % max_cost <=
-	    (max_cost - ((dq->second.front().first * 9) / 10))){
-	  break;
-	}
+    T dequeue() {
+      assert(strict.size + normal.size > 0);
+      if (!strict.empty()) {
+	return strict.pop(true);
       }
+      return normal.pop();
     }
-    T ret = dq->second.front().second;
-    dq->second.pop_front();
-    if (dq->second.empty()) {
-      remove_queue(dq->first);
-    }
-    --wrr_size;
-    return ret;
-  }
-
-  void dump(ceph::Formatter *f) const {
-    f->dump_int("total_priority", total_priority);
-    f->open_array_section("high_queues");
-    for (typename SubQueues::const_iterator p = high_queue.begin();
-	 p != high_queue.end();
-	 ++p) {
-      f->open_object_section("subqueue");
-      f->dump_int("priority", p->first);
-      p->second.dump(f);
+    void dump(ceph::Formatter *f) const {
+      f->open_array_section("high_queues");
+      strict.dump(f);
       f->close_section();
-    }
-    f->close_section();
-    f->open_array_section("queues");
-    for (typename SubQueues::const_iterator p = queue.begin();
-	 p != queue.end();
-	 ++p) {
-      f->open_object_section("subqueue");
-      f->dump_int("priority", p->first);
-      p->second.dump(f);
+      f->open_array_section("queues");
+      normal.dump(f);
       f->close_section();
     }
-    f->close_section();
-  }
 };
 
 #endif
diff --git a/src/common/admin_socket.cc b/src/common/admin_socket.cc
index aa0146f..aedaed5 100644
--- a/src/common/admin_socket.cc
+++ b/src/common/admin_socket.cc
@@ -109,6 +109,7 @@ AdminSocket::AdminSocket(CephContext *cct)
     m_sock_fd(-1),
     m_shutdown_rd_fd(-1),
     m_shutdown_wr_fd(-1),
+    in_hook(false),
     m_lock("AdminSocket::m_lock"),
     m_version_hook(NULL),
     m_help_hook(NULL),
@@ -286,6 +287,17 @@ void* AdminSocket::entry()
   ldout(m_cct, 5) << "entry exit" << dendl;
 }
 
+void AdminSocket::chown(uid_t uid, gid_t gid)
+{
+  if (m_sock_fd >= 0) {
+    int r = ::fchown(m_sock_fd, uid, gid);
+    if (r < 0) {
+      r = -errno;
+      lderr(m_cct) << "AdminSocket: failed to chown socket: "
+		   << cpp_strerror(r) << dendl;
+    }
+  }
+}
 
 bool AdminSocket::do_accept()
 {
@@ -384,9 +396,22 @@ bool AdminSocket::do_accept()
     lderr(m_cct) << "AdminSocket: request '" << c << "' not defined" << dendl;
   } else {
     string args;
-    if (match != c)
+    if (match != c) {
       args = c.substr(match.length() + 1);
-    bool success = p->second->call(match, cmdmap, format, out);
+    }
+
+    // Drop lock to avoid cycles in cases where the hook takes
+    // the same lock that was held during calls to register/unregister,
+    // and set in_hook to allow unregister to wait for us before
+    // removing this hook.
+    in_hook = true;
+    auto match_hook = p->second;
+    m_lock.Unlock();
+    bool success = match_hook->call(match, cmdmap, format, out);
+    m_lock.Lock();
+    in_hook = false;
+    in_hook_cond.Signal();
+
     if (!success) {
       ldout(m_cct, 0) << "AdminSocket: request '" << match << "' args '" << args
 		      << "' to " << p->second << " failed" << dendl;
@@ -439,6 +464,14 @@ int AdminSocket::unregister_command(std::string command)
     m_hooks.erase(command);
     m_descs.erase(command);
     m_help.erase(command);
+
+    // If we are currently processing a command, wait for it to
+    // complete in case it referenced the hook that we are
+    // unregistering.
+    if (in_hook) {
+      in_hook_cond.Wait(m_lock);
+    }
+
     ret = 0;
   } else {
     ldout(m_cct, 5) << "unregister_command " << command << " ENOENT" << dendl;
diff --git a/src/common/admin_socket.h b/src/common/admin_socket.h
index bad235a..2526471 100644
--- a/src/common/admin_socket.h
+++ b/src/common/admin_socket.h
@@ -22,6 +22,7 @@
 #include <map>
 #include "include/buffer_fwd.h"
 #include "common/cmdparse.h"
+#include "common/Cond.h"
 
 class AdminSocket;
 class CephContext;
@@ -63,7 +64,11 @@ public:
   int register_command(std::string command, std::string cmddesc, AdminSocketHook *hook, std::string help);
 
   /**
-   * unregister an admin socket command
+   * unregister an admin socket command.
+   *
+   * If a command is currently in progress, this will block until it
+   * is done.  For that reason, you must not hold any locks required
+   * by your hook while you call this.
    *
    * @param command command string
    * @return 0 on succest, -ENOENT if command dne.
@@ -71,7 +76,9 @@ public:
   int unregister_command(std::string command);
 
   bool init(const std::string &path);
-  
+
+  void chown(uid_t uid, gid_t gid);
+
 private:
   AdminSocket(const AdminSocket& rhs);
   AdminSocket& operator=(const AdminSocket &rhs);
@@ -91,6 +98,8 @@ private:
   int m_shutdown_rd_fd;
   int m_shutdown_wr_fd;
 
+  bool in_hook;
+  Cond in_hook_cond;
   Mutex m_lock;    // protects m_hooks, m_descs, m_help
   AdminSocketHook *m_version_hook, *m_help_hook, *m_getdescs_hook;
 
diff --git a/src/common/bit_vector.hpp b/src/common/bit_vector.hpp
index f66294b..06600e9 100644
--- a/src/common/bit_vector.hpp
+++ b/src/common/bit_vector.hpp
@@ -35,6 +35,7 @@ private:
   BOOST_STATIC_ASSERT((_bit_count != 0) && !(_bit_count & (_bit_count - 1)));
   BOOST_STATIC_ASSERT(_bit_count <= BITS_PER_BYTE);
 public:
+  static const uint32_t BLOCK_SIZE;
 
   class ConstReference {
   public:
@@ -111,6 +112,9 @@ private:
 };
 
 template <uint8_t _b>
+const uint32_t BitVector<_b>::BLOCK_SIZE = 4096;
+
+template <uint8_t _b>
 BitVector<_b>::BitVector() : m_size(0), m_crc_enabled(true)
 {
 }
@@ -135,7 +139,7 @@ void BitVector<_b>::resize(uint64_t size) {
   }
   m_size = size;
 
-  uint64_t block_count = (buffer_size + CEPH_PAGE_SIZE - 1) / CEPH_PAGE_SIZE;
+  uint64_t block_count = (buffer_size + BLOCK_SIZE - 1) / BLOCK_SIZE;
   m_data_crcs.resize(block_count);
 }
 
@@ -190,26 +194,26 @@ uint64_t BitVector<_b>::get_header_length() const {
 template <uint8_t _b>
 void BitVector<_b>::encode_data(bufferlist& bl, uint64_t byte_offset,
 				uint64_t byte_length) const {
-  assert(byte_offset % CEPH_PAGE_SIZE == 0);
+  assert(byte_offset % BLOCK_SIZE == 0);
   assert(byte_offset + byte_length == m_data.length() ||
-	 byte_length % CEPH_PAGE_SIZE == 0);
+	 byte_length % BLOCK_SIZE == 0);
 
   uint64_t end_offset = byte_offset + byte_length;
   while (byte_offset < end_offset) {
-    uint64_t len = MIN(CEPH_PAGE_SIZE, end_offset - byte_offset);
+    uint64_t len = MIN(BLOCK_SIZE, end_offset - byte_offset);
 
     bufferlist bit;
     bit.substr_of(m_data, byte_offset, len);
-    m_data_crcs[byte_offset / CEPH_PAGE_SIZE] = bit.crc32c(0);
+    m_data_crcs[byte_offset / BLOCK_SIZE] = bit.crc32c(0);
 
     bl.claim_append(bit);
-    byte_offset += CEPH_PAGE_SIZE;
+    byte_offset += BLOCK_SIZE;
   }
 }
 
 template <uint8_t _b>
 void BitVector<_b>::decode_data(bufferlist::iterator& it, uint64_t byte_offset) {
-  assert(byte_offset % CEPH_PAGE_SIZE == 0);
+  assert(byte_offset % BLOCK_SIZE == 0);
   if (it.end()) {
     return;
   }
@@ -225,12 +229,12 @@ void BitVector<_b>::decode_data(bufferlist::iterator& it, uint64_t byte_offset)
   }
 
   while (byte_offset < end_offset) {
-    uint64_t len = MIN(CEPH_PAGE_SIZE, end_offset - byte_offset);
+    uint64_t len = MIN(BLOCK_SIZE, end_offset - byte_offset);
 
     bufferlist bit;
     it.copy(len, bit);
     if (m_crc_enabled &&
-	m_data_crcs[byte_offset / CEPH_PAGE_SIZE] != bit.crc32c(0)) {
+	m_data_crcs[byte_offset / BLOCK_SIZE] != bit.crc32c(0)) {
       throw buffer::malformed_input("invalid data block CRC");
     }
     data.append(bit);
@@ -250,15 +254,15 @@ template <uint8_t _b>
 void BitVector<_b>::get_data_extents(uint64_t offset, uint64_t length,
 				     uint64_t *byte_offset,
 				     uint64_t *byte_length) const {
-  // read CEPH_PAGE_SIZE-aligned chunks
+  // read BLOCK_SIZE-aligned chunks
   assert(length > 0 && offset + length <= m_size);
   uint64_t shift;
   compute_index(offset, byte_offset, &shift);
-  *byte_offset -= (*byte_offset % CEPH_PAGE_SIZE);
+  *byte_offset -= (*byte_offset % BLOCK_SIZE);
 
   uint64_t end_offset;
   compute_index(offset + length - 1, &end_offset, &shift);
-  end_offset += (CEPH_PAGE_SIZE - (end_offset % CEPH_PAGE_SIZE));
+  end_offset += (BLOCK_SIZE - (end_offset % BLOCK_SIZE));
   assert(*byte_offset <= end_offset);
 
   *byte_length = end_offset - *byte_offset;
@@ -292,7 +296,7 @@ void BitVector<_b>::decode_footer(bufferlist::iterator& it) {
       throw buffer::malformed_input("incorrect header CRC");
     }
 
-    uint64_t block_count = (m_data.length() + CEPH_PAGE_SIZE - 1) / CEPH_PAGE_SIZE;
+    uint64_t block_count = (m_data.length() + BLOCK_SIZE - 1) / BLOCK_SIZE;
     ::decode(m_data_crcs, footer_it);
     if (m_data_crcs.size() != block_count) {
       throw buffer::malformed_input("invalid data block CRCs");
diff --git a/src/common/blkdev.cc b/src/common/blkdev.cc
index f013a7b..ec6e849 100644
--- a/src/common/blkdev.cc
+++ b/src/common/blkdev.cc
@@ -275,5 +275,24 @@ int get_device_by_uuid(uuid_d dev_uuid, const char* label, char* partition,
   return -EOPNOTSUPP;
 }
 #else
-# error "Unable to query block device size: unsupported platform, please report."
+int get_block_device_size(int fd, int64_t *psize)
+{
+  return -EOPNOTSUPP;
+}
+
+bool block_device_support_discard(const char *devname)
+{
+  return false;
+}
+
+int block_device_discard(int fd, int64_t offset, int64_t len)
+{
+  return -EOPNOTSUPP;
+}
+
+int get_device_by_uuid(uuid_d dev_uuid, const char* label, char* partition,
+	char* device)
+{
+  return -EOPNOTSUPP;
+}
 #endif
diff --git a/src/common/buffer.cc b/src/common/buffer.cc
index 5a2f60f..0368979 100644
--- a/src/common/buffer.cc
+++ b/src/common/buffer.cc
@@ -39,6 +39,9 @@
 #include <ostream>
 namespace ceph {
 
+#define CEPH_BUFFER_ALLOC_UNIT  (MIN(CEPH_PAGE_SIZE, 4096))
+#define CEPH_BUFFER_APPEND_SIZE (CEPH_BUFFER_ALLOC_UNIT - sizeof(raw_combined))
+
 #ifdef BUFFER_DEBUG
 static simple_spinlock_t buffer_debug_lock = SIMPLE_SPINLOCK_INITIALIZER;
 # define bdout { simple_spin_lock(&buffer_debug_lock); std::cout
@@ -235,6 +238,56 @@ static simple_spinlock_t buffer_debug_lock = SIMPLE_SPINLOCK_INITIALIZER;
     }
   };
 
+  /*
+   * raw_combined is always placed within a single allocation along
+   * with the data buffer.  the data goes at the beginning, and
+   * raw_combined at the end.
+   */
+  class buffer::raw_combined : public buffer::raw {
+    size_t alignment;
+  public:
+    raw_combined(char *dataptr, unsigned l, unsigned align=0)
+      : raw(dataptr, l),
+	alignment(align) {
+      inc_total_alloc(len);
+      inc_history_alloc(len);
+    }
+    ~raw_combined() {
+      dec_total_alloc(len);
+    }
+    raw* clone_empty() {
+      return create(len, alignment);
+    }
+
+    static raw_combined *create(unsigned len, unsigned align=0) {
+      if (!align)
+	align = sizeof(size_t);
+      size_t rawlen = ROUND_UP_TO(sizeof(buffer::raw_combined),
+				  alignof(buffer::raw_combined));
+      size_t datalen = ROUND_UP_TO(len, alignof(buffer::raw_combined));
+
+#ifdef DARWIN
+      char *ptr = (char *) valloc(rawlen + datalen);
+#else
+      char *ptr = 0;
+      int r = ::posix_memalign((void**)(void*)&ptr, align, rawlen + datalen);
+      if (r)
+	throw bad_alloc();
+#endif /* DARWIN */
+      if (!ptr)
+	throw bad_alloc();
+
+      // actual data first, since it has presumably larger alignment restriction
+      // then put the raw_combined at the end
+      return new (ptr + datalen) raw_combined(ptr, len, align);
+    }
+
+    static void operator delete(void *ptr) {
+      raw_combined *raw = (raw_combined *)ptr;
+      ::free((void *)raw->data);
+    }
+  };
+
   class buffer::raw_malloc : public buffer::raw {
   public:
     explicit raw_malloc(unsigned l) : raw(l) {
@@ -635,12 +688,13 @@ static simple_spinlock_t buffer_debug_lock = SIMPLE_SPINLOCK_INITIALIZER;
 #endif /* HAVE_XIO */
 
   buffer::raw* buffer::copy(const char *c, unsigned len) {
-    raw* r = new raw_char(len);
+    raw* r = buffer::create_aligned(len, sizeof(size_t));
     memcpy(r->data, c, len);
     return r;
   }
+
   buffer::raw* buffer::create(unsigned len) {
-    return new raw_char(len);
+    return buffer::create_aligned(len, sizeof(size_t));
   }
   buffer::raw* buffer::claim_char(unsigned len, char *buf) {
     return new raw_char(len, buf);
@@ -654,14 +708,28 @@ static simple_spinlock_t buffer_debug_lock = SIMPLE_SPINLOCK_INITIALIZER;
   buffer::raw* buffer::create_static(unsigned len, char *buf) {
     return new raw_static(buf, len);
   }
+
   buffer::raw* buffer::create_aligned(unsigned len, unsigned align) {
+    // If alignment is a page multiple, use a separate buffer::raw to
+    // avoid fragmenting the heap.
+    //
+    // Somewhat unexpectedly, I see consistently better performance
+    // from raw_combined than from raw even when the allocation size is
+    // a page multiple (but alignment is not).
+    //
+    // I also see better performance from a separate buffer::raw once the
+    // size passes 8KB.
+    if ((align & ~CEPH_PAGE_MASK) == 0 ||
+	len >= CEPH_PAGE_SIZE * 2) {
 #ifndef __CYGWIN__
-    //return new raw_mmap_pages(len);
-    return new raw_posix_aligned(len, align);
+      return new raw_posix_aligned(len, align);
 #else
-    return new raw_hack_aligned(len, align);
+      return new raw_hack_aligned(len, align);
 #endif
+    }
+    return raw_combined::create(len, align);
   }
+
   buffer::raw* buffer::create_page_aligned(unsigned len) {
     return create_aligned(len, CEPH_PAGE_SIZE);
   }
@@ -962,6 +1030,17 @@ static simple_spinlock_t buffer_debug_lock = SIMPLE_SPINLOCK_INITIALIZER;
     }*/
 
   template<bool is_const>
+  buffer::list::iterator_impl<is_const>::iterator_impl(bl_t *l, unsigned o)
+    : bl(l), ls(&bl->_buffers), off(0), p(ls->begin()), p_off(0)
+  {
+    advance(o);
+  }
+
+  template<bool is_const>
+  buffer::list::iterator_impl<is_const>::iterator_impl(const buffer::list::iterator& i)
+    : iterator_impl<is_const>(i.bl, i.off, i.p, i.p_off) {}
+
+  template<bool is_const>
   void buffer::list::iterator_impl<is_const>::advance(int o)
   {
     //cout << this << " advance " << o << " from " << off << " (p_off " << p_off << " in " << p->length() << ")" << std::endl;
@@ -1009,12 +1088,6 @@ static simple_spinlock_t buffer_debug_lock = SIMPLE_SPINLOCK_INITIALIZER;
   }
 
   template<bool is_const>
-  bool buffer::list::iterator_impl<is_const>::operator!=(const buffer::list::iterator_impl<is_const>& rhs) const
-  {
-    return bl == rhs.bl && off == rhs.off;
-  }
-
-  template<bool is_const>
   char buffer::list::iterator_impl<is_const>::operator*() const
   {
     if (p == ls->end())
@@ -1131,6 +1204,14 @@ static simple_spinlock_t buffer_debug_lock = SIMPLE_SPINLOCK_INITIALIZER;
   template class buffer::list::iterator_impl<true>;
   template class buffer::list::iterator_impl<false>;
 
+  buffer::list::iterator::iterator(bl_t *l, unsigned o)
+    : iterator_impl(l, o)
+  {}
+
+  buffer::list::iterator::iterator(bl_t *l, unsigned o, list_iter_t ip, unsigned po)
+    : iterator_impl(l, o, ip, po)
+  {}
+
   void buffer::list::iterator::advance(int o)
   {
     buffer::list::iterator_impl<false>::advance(o);
@@ -1232,7 +1313,6 @@ static simple_spinlock_t buffer_debug_lock = SIMPLE_SPINLOCK_INITIALIZER;
     }
   }
 
-
   // -- buffer::list --
 
   buffer::list::list(list&& other)
@@ -1315,6 +1395,13 @@ static simple_spinlock_t buffer_debug_lock = SIMPLE_SPINLOCK_INITIALIZER;
     return true;
   }
 
+  bool buffer::list::is_provided_buffer(const char *dst) const
+  {
+    if (_buffers.empty())
+      return false;
+    return (is_contiguous() && (_buffers.front().c_str() == dst));
+  }
+
   bool buffer::list::is_aligned(unsigned align) const
   {
     for (std::list<ptr>::const_iterator it = _buffers.begin();
@@ -1385,7 +1472,7 @@ static simple_spinlock_t buffer_debug_lock = SIMPLE_SPINLOCK_INITIALIZER;
 	break;  // done
     }
   }
-  
+
   bool buffer::list::is_contiguous() const
   {
     return &(*_buffers.begin()) == &(*_buffers.rbegin());
@@ -1568,7 +1655,7 @@ static simple_spinlock_t buffer_debug_lock = SIMPLE_SPINLOCK_INITIALIZER;
     unsigned gap = append_buffer.unused_tail_length();
     if (!gap) {
       // make a new append_buffer!
-      append_buffer = create_aligned(CEPH_BUFFER_APPEND_SIZE, CEPH_BUFFER_APPEND_SIZE);
+      append_buffer = raw_combined::create(CEPH_BUFFER_APPEND_SIZE);
       append_buffer.set_length(0);   // unused, so far.
     }
     append(append_buffer, append_buffer.append(c) - 1, 1);	// add segment to the list
@@ -1590,9 +1677,12 @@ static simple_spinlock_t buffer_debug_lock = SIMPLE_SPINLOCK_INITIALIZER;
       if (len == 0)
         break;  // done!
       
-      // make a new append_buffer!
-      unsigned alen = CEPH_BUFFER_APPEND_SIZE * (((len-1) / CEPH_BUFFER_APPEND_SIZE) + 1);
-      append_buffer = create_aligned(alen, CEPH_BUFFER_APPEND_SIZE);
+      // make a new append_buffer.  fill out a complete page, factoring in the
+      // raw_combined overhead.
+      size_t need = ROUND_UP_TO(len, sizeof(size_t)) + sizeof(raw_combined);
+      size_t alen = ROUND_UP_TO(need, CEPH_BUFFER_ALLOC_UNIT) -
+	sizeof(raw_combined);
+      append_buffer = raw_combined::create(alen);
       append_buffer.set_length(0);   // unused, so far.
     }
   }
@@ -1923,8 +2013,7 @@ ssize_t buffer::list::read_fd(int fd, size_t len)
     // available for raw_pipe until we actually inspect the data
     return 0;
   }
-  int s = ROUND_UP_TO(len, CEPH_BUFFER_APPEND_SIZE);
-  bufferptr bp = buffer::create_aligned(s, CEPH_BUFFER_APPEND_SIZE);
+  bufferptr bp = buffer::create(len);
   ssize_t ret = safe_read(fd, (void*)bp.c_str(), len);
   if (ret >= 0) {
     bp.set_length(ret);
@@ -1974,6 +2063,46 @@ int buffer::list::write_file(const char *fn, int mode)
   return 0;
 }
 
+static int do_writev(int fd, struct iovec *vec, uint64_t offset, unsigned veclen, unsigned bytes)
+{
+  ssize_t r = 0;
+  while (bytes > 0) {
+#ifdef HAVE_PWRITEV
+    r = ::pwritev(fd, vec, veclen, offset);
+#else
+    r = ::lseek64(fd, offset, SEEK_SET);
+    if (r != offset) {
+      r = -errno;
+      return r;
+    }
+    r = ::writev(fd, vec, veclen);
+#endif
+    if (r < 0) {
+      if (errno == EINTR)
+        continue;
+      return -errno;
+    }
+
+    bytes -= r;
+    offset += r;
+    if (bytes == 0) break;
+
+    while (r > 0) {
+      if (vec[0].iov_len <= (size_t)r) {
+        // drain this whole item
+        r -= vec[0].iov_len;
+        ++vec;
+        --veclen;
+      } else {
+        vec[0].iov_base = (char *)vec[0].iov_base + r;
+        vec[0].iov_len -= r;
+        break;
+      }
+    }
+  }
+  return 0;
+}
+
 int buffer::list::write_fd(int fd) const
 {
   if (can_zero_copy())
@@ -2029,6 +2158,34 @@ int buffer::list::write_fd(int fd) const
   return 0;
 }
 
+int buffer::list::write_fd(int fd, uint64_t offset) const
+{
+  iovec iov[IOV_MAX];
+
+  std::list<ptr>::const_iterator p = _buffers.begin();
+  uint64_t left_pbrs = _buffers.size();
+  while (left_pbrs) {
+    ssize_t bytes = 0;
+    unsigned iovlen = 0;
+    uint64_t size = MIN(left_pbrs, IOV_MAX);
+    left_pbrs -= size;
+    while (size > 0) {
+      iov[iovlen].iov_base = (void *)p->c_str();
+      iov[iovlen].iov_len = p->length();
+      iovlen++;
+      bytes += p->length();
+      ++p;
+      size--;
+    }
+
+    int r = do_writev(fd, iov, offset, iovlen, bytes);
+    if (r < 0)
+      return r;
+    offset += bytes;
+  }
+  return 0;
+}
+
 void buffer::list::prepare_iov(std::vector<iovec> *piov) const
 {
   piov->resize(_buffers.size());
diff --git a/src/common/ceph_context.cc b/src/common/ceph_context.cc
index 5470807..e873c9f 100644
--- a/src/common/ceph_context.cc
+++ b/src/common/ceph_context.cc
@@ -27,6 +27,7 @@
 #include "common/errno.h"
 #include "common/lockdep.h"
 #include "common/Formatter.h"
+#include "common/Graylog.h"
 #include "log/Log.h"
 #include "auth/Crypto.h"
 #include "include/str_list.h"
@@ -438,6 +439,10 @@ CephContext::CephContext(uint32_t module_type_, int init_flags_)
     _log(NULL),
     _module_type(module_type_),
     _init_flags(init_flags_),
+    _set_uid(0),
+    _set_gid(0),
+    _set_uid_string(),
+    _set_gid_string(),
     _crypto_inited(false),
     _service_thread(NULL),
     _log_obs(NULL),
diff --git a/src/common/ceph_context.h b/src/common/ceph_context.h
index 99b2181..cdb66f5 100644
--- a/src/common/ceph_context.h
+++ b/src/common/ceph_context.h
@@ -153,6 +153,28 @@ public:
     return _plugin_registry;
   }
 
+  void set_uid_gid(uid_t u, gid_t g) {
+    _set_uid = u;
+    _set_gid = g;
+  }
+  uid_t get_set_uid() const {
+    return _set_uid;
+  }
+  gid_t get_set_gid() const {
+    return _set_gid;
+  }
+
+  void set_uid_gid_strings(std::string u, std::string g) {
+    _set_uid_string = u;
+    _set_gid_string = g;
+  }
+  std::string get_set_uid_string() const {
+    return _set_uid_string;
+  }
+  std::string get_set_gid_string() const {
+    return _set_gid_string;
+  }
+
 private:
   struct SingletonWrapper : boost::noncopyable {
     virtual ~SingletonWrapper() {}
@@ -179,6 +201,11 @@ private:
 
   int _init_flags;
 
+  uid_t _set_uid; ///< uid to drop privs to
+  gid_t _set_gid; ///< gid to drop privs to
+  std::string _set_uid_string;
+  std::string _set_gid_string;
+
   bool _crypto_inited;
 
   /* libcommon service thread.
diff --git a/src/common/ceph_crypto.cc b/src/common/ceph_crypto.cc
index de5a03b..6da3232 100644
--- a/src/common/ceph_crypto.cc
+++ b/src/common/ceph_crypto.cc
@@ -36,6 +36,10 @@ ceph::crypto::HMACSHA1::~HMACSHA1()
 {
 }
 
+ceph::crypto::HMACSHA256::~HMACSHA256()
+{
+}
+
 #elif defined(USE_NSS)
 
 // for SECMOD_RestartModules()
@@ -85,7 +89,7 @@ void ceph::crypto::shutdown()
   pthread_mutex_unlock(&crypto_init_mutex);
 }
 
-ceph::crypto::HMACSHA1::~HMACSHA1()
+ceph::crypto::HMAC::~HMAC()
 {
   PK11_DestroyContext(ctx, PR_TRUE);
   PK11_FreeSymKey(symkey);
diff --git a/src/common/ceph_crypto.h b/src/common/ceph_crypto.h
index 10055f6..689128f 100644
--- a/src/common/ceph_crypto.h
+++ b/src/common/ceph_crypto.h
@@ -6,6 +6,7 @@
 #define CEPH_CRYPTO_MD5_DIGESTSIZE 16
 #define CEPH_CRYPTO_HMACSHA1_DIGESTSIZE 20
 #define CEPH_CRYPTO_SHA1_DIGESTSIZE 20
+#define CEPH_CRYPTO_HMACSHA256_DIGESTSIZE 32
 #define CEPH_CRYPTO_SHA256_DIGESTSIZE 32
 
 #ifdef USE_CRYPTOPP
@@ -36,6 +37,15 @@ namespace ceph {
 	}
       ~HMACSHA1();
     };
+
+    class HMACSHA256: public CryptoPP::HMAC<CryptoPP::SHA256> {
+    public:
+      HMACSHA256 (const byte *key, size_t length)
+        : CryptoPP::HMAC<CryptoPP::SHA256>(key, length)
+        {
+        }
+      ~HMACSHA256();
+    };
   }
 }
 #elif defined(USE_NSS)
@@ -61,10 +71,9 @@ namespace ceph {
     class Digest {
     private:
       PK11Context *ctx;
-      SECOidTag sec_type;
       size_t digest_size;
     public:
-      Digest (SECOidTag _type, size_t _digest_size) : sec_type(_type), digest_size(_digest_size) {
+      Digest (SECOidTag _type, size_t _digest_size) : digest_size(_digest_size) {
 	ctx = PK11_CreateDigestContext(_type);
 	assert(ctx);
 	Restart();
@@ -108,31 +117,33 @@ namespace ceph {
       SHA256 () : Digest(SEC_OID_SHA256, CEPH_CRYPTO_SHA256_DIGESTSIZE) { }
     };
 
-    class HMACSHA1 {
+    class HMAC {
     private:
       PK11SlotInfo *slot;
       PK11SymKey *symkey;
       PK11Context *ctx;
+      unsigned int digest_size;
     public:
-      HMACSHA1 (const byte *key, size_t length) {
-	slot = PK11_GetBestSlot(CKM_SHA_1_HMAC, NULL);
+      HMAC (CK_MECHANISM_TYPE cktype, unsigned int digestsize, const byte *key, size_t length) {
+        digest_size = digestsize;
+	slot = PK11_GetBestSlot(cktype, NULL);
 	assert(slot);
 	SECItem keyItem;
 	keyItem.type = siBuffer;
 	keyItem.data = (unsigned char*)key;
 	keyItem.len = length;
-	symkey = PK11_ImportSymKey(slot, CKM_SHA_1_HMAC, PK11_OriginUnwrap,
+	symkey = PK11_ImportSymKey(slot, cktype, PK11_OriginUnwrap,
 				   CKA_SIGN,  &keyItem, NULL);
 	assert(symkey);
 	SECItem param;
 	param.type = siBuffer;
 	param.data = NULL;
 	param.len = 0;
-	ctx = PK11_CreateContextBySymKey(CKM_SHA_1_HMAC, CKA_SIGN, symkey, &param);
+	ctx = PK11_CreateContextBySymKey(cktype, CKA_SIGN, symkey, &param);
 	assert(ctx);
 	Restart();
       }
-      ~HMACSHA1 ();
+      ~HMAC ();
       void Restart() {
 	SECStatus s;
 	s = PK11_DigestBegin(ctx);
@@ -146,12 +157,22 @@ namespace ceph {
       void Final (byte *digest) {
 	SECStatus s;
 	unsigned int dummy;
-	s = PK11_DigestFinal(ctx, digest, &dummy, CEPH_CRYPTO_HMACSHA1_DIGESTSIZE);
+	s = PK11_DigestFinal(ctx, digest, &dummy, digest_size);
 	assert(s == SECSuccess);
-	assert(dummy == CEPH_CRYPTO_HMACSHA1_DIGESTSIZE);
+	assert(dummy == digest_size);
 	Restart();
       }
     };
+
+    class HMACSHA1 : public HMAC {
+    public:
+      HMACSHA1 (const byte *key, size_t length) : HMAC(CKM_SHA_1_HMAC, CEPH_CRYPTO_HMACSHA1_DIGESTSIZE, key, length) { }
+    };
+
+    class HMACSHA256 : public HMAC {
+    public:
+      HMACSHA256 (const byte *key, size_t length) : HMAC(CKM_SHA256_HMAC, CEPH_CRYPTO_HMACSHA256_DIGESTSIZE, key, length) { }
+    };
   }
 }
 
diff --git a/src/common/ceph_json.h b/src/common/ceph_json.h
index e69055b..a812d7a 100644
--- a/src/common/ceph_json.h
+++ b/src/common/ceph_json.h
@@ -5,7 +5,18 @@
 #include <include/types.h>
 #include <list>
 
+#ifdef _ASSERT_H
+#define NEED_ASSERT_H
+#pragma push_macro("_ASSERT_H")
+#endif
+
 #include "json_spirit/json_spirit.h"
+#undef _ASSERT_H
+
+#ifdef NEED_ASSERT_H
+#pragma pop_macro("_ASSERT_H")
+#endif
+
 #include "Formatter.h"
 
 
@@ -154,6 +165,36 @@ void decode_json_obj(list<T>& l, JSONObj *obj)
 }
 
 template<class T>
+void decode_json_obj(deque<T>& l, JSONObj *obj)
+{
+  l.clear();
+
+  JSONObjIter iter = obj->find_first();
+
+  for (; !iter.end(); ++iter) {
+    T val;
+    JSONObj *o = *iter;
+    decode_json_obj(val, o);
+    l.push_back(val);
+  }
+}
+
+template<class T>
+void decode_json_obj(set<T>& l, JSONObj *obj)
+{
+  l.clear();
+
+  JSONObjIter iter = obj->find_first();
+
+  for (; !iter.end(); ++iter) {
+    T val;
+    JSONObj *o = *iter;
+    decode_json_obj(val, o);
+    l.insert(val);
+  }
+}
+
+template<class T>
 void decode_json_obj(vector<T>& l, JSONObj *obj)
 {
   l.clear();
@@ -306,36 +347,28 @@ void encode_json(const char *name, const bufferlist& bl, ceph::Formatter *f);
 void encode_json(const char *name, long long val, ceph::Formatter *f);
 void encode_json(const char *name, long long unsigned val, ceph::Formatter *f);
 
-template<class K, class V>
-static void encode_json(const char *name, const std::map<K, V>& m, ceph::Formatter *f)
+template<class T>
+static void encode_json(const char *name, const std::list<T>& l, ceph::Formatter *f)
 {
   f->open_array_section(name);
-  for (typename std::map<K, V>::const_iterator i = m.begin(); i != m.end(); ++i) {
-    f->open_object_section("entry");
-    encode_json("key", i->first, f);
-    encode_json("val", i->second, f);
-    f->close_section();
+  for (typename std::list<T>::const_iterator iter = l.begin(); iter != l.end(); ++iter) {
+    encode_json("obj", *iter, f);
   }
   f->close_section();
 }
-
-template<class K, class V>
-static void encode_json(const char *name, const std::multimap<K, V>& m, ceph::Formatter *f)
+template<class T>
+static void encode_json(const char *name, const std::deque<T>& l, ceph::Formatter *f)
 {
   f->open_array_section(name);
-  for (typename std::multimap<K, V>::const_iterator i = m.begin(); i != m.end(); ++i) {
-    f->open_object_section("entry");
-    encode_json("key", i->first, f);
-    encode_json("val", i->second, f);
-    f->close_section();
+  for (typename std::deque<T>::const_iterator iter = l.begin(); iter != l.end(); ++iter) {
+    encode_json("obj", *iter, f);
   }
   f->close_section();
-}
-template<class T>
-static void encode_json(const char *name, const std::list<T>& l, ceph::Formatter *f)
+}template<class T>
+static void encode_json(const char *name, const std::set<T>& l, ceph::Formatter *f)
 {
   f->open_array_section(name);
-  for (typename std::list<T>::const_iterator iter = l.begin(); iter != l.end(); ++iter) {
+  for (typename std::set<T>::const_iterator iter = l.begin(); iter != l.end(); ++iter) {
     encode_json("obj", *iter, f);
   }
   f->close_section();
@@ -352,6 +385,31 @@ static void encode_json(const char *name, const std::vector<T>& l, ceph::Formatt
 }
 
 template<class K, class V>
+static void encode_json(const char *name, const std::map<K, V>& m, ceph::Formatter *f)
+{
+  f->open_array_section(name);
+  for (typename std::map<K, V>::const_iterator i = m.begin(); i != m.end(); ++i) {
+    f->open_object_section("entry");
+    encode_json("key", i->first, f);
+    encode_json("val", i->second, f);
+    f->close_section();
+  }
+  f->close_section();
+}
+
+template<class K, class V>
+static void encode_json(const char *name, const std::multimap<K, V>& m, ceph::Formatter *f)
+{
+  f->open_array_section(name);
+  for (typename std::multimap<K, V>::const_iterator i = m.begin(); i != m.end(); ++i) {
+    f->open_object_section("entry");
+    encode_json("key", i->first, f);
+    encode_json("val", i->second, f);
+    f->close_section();
+  }
+  f->close_section();
+}
+template<class K, class V>
 void encode_json_map(const char *name, const map<K, V>& m, ceph::Formatter *f)
 {
   f->open_array_section(name);
diff --git a/src/common/ceph_strings.cc b/src/common/ceph_strings.cc
index 6f262e1..2fef541 100644
--- a/src/common/ceph_strings.cc
+++ b/src/common/ceph_strings.cc
@@ -135,8 +135,10 @@ const char *ceph_mds_op_name(int op)
 	case CEPH_MDS_OP_GETFILELOCK: return "getfilelock";
 	case CEPH_MDS_OP_FRAGMENTDIR: return "fragmentdir";
 	case CEPH_MDS_OP_EXPORTDIR: return "exportdir";
-	case CEPH_MDS_OP_VALIDATE: return "validate_path";
 	case CEPH_MDS_OP_FLUSH: return "flush_path";
+	case CEPH_MDS_OP_ENQUEUE_SCRUB: return "enqueue_scrub";
+	case CEPH_MDS_OP_REPAIR_FRAGSTATS: return "repair_fragstats";
+	case CEPH_MDS_OP_REPAIR_INODESTATS: return "repair_inodestats";
 	}
 	return "???";
 }
diff --git a/src/common/ceph_time.h b/src/common/ceph_time.h
index f0e188f..ef187c0 100644
--- a/src/common/ceph_time.h
+++ b/src/common/ceph_time.h
@@ -75,6 +75,10 @@ namespace ceph {
       // introducing configurable clock skew.
       static time_point now(const CephContext* cct) noexcept;
 
+      static bool is_zero(const time_point& t) {
+        return (t == time_point::min());
+      }
+
       // Allow conversion to/from any clock with the same interface as
       // std::chrono::system_clock)
       template<typename Clock, typename Duration>
diff --git a/src/common/cohort_lru.h b/src/common/cohort_lru.h
new file mode 100644
index 0000000..19a5c45
--- /dev/null
+++ b/src/common/cohort_lru.h
@@ -0,0 +1,468 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+/*
+ * Copyright (C) 2015 CohortFS, LLC.
+ *
+ * This is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software
+ * Foundation.	See file COPYING.
+ *
+ */
+
+#ifndef COHORT_LRU_H
+#define COHORT_LRU_H
+
+#include <stdint.h>
+#include <atomic>
+#include <boost/intrusive/list.hpp>
+#include <boost/intrusive/rbtree.hpp>
+#include <boost/intrusive/avltree.hpp>
+#include <mutex>
+#include <atomic>
+#include <vector>
+#include <algorithm>
+#include <iostream>
+#include "common/likely.h"
+
+#ifndef CACHE_LINE_SIZE
+#define CACHE_LINE_SIZE 64 /* XXX arch-specific define */
+#endif
+#define CACHE_PAD(_n) char __pad ## _n [CACHE_LINE_SIZE]
+
+namespace cohort {
+
+  namespace lru {
+
+    namespace bi = boost::intrusive;
+
+    /* public flag values */
+    constexpr uint32_t FLAG_NONE = 0x0000;
+    constexpr uint32_t FLAG_INITIAL = 0x0001;
+
+    enum class Edge : std::uint8_t
+    {
+      MRU = 0,
+      LRU
+    };
+
+    typedef bi::link_mode<bi::safe_link> link_mode; // for debugging
+
+    class Object
+    {
+    private:
+      uint32_t lru_flags;
+      std::atomic<uint32_t> lru_refcnt;
+      std::atomic<uint32_t> lru_adj;
+      bi::list_member_hook< link_mode > lru_hook;
+
+      typedef bi::list<Object,
+		       bi::member_hook<
+			 Object, bi::list_member_hook< link_mode >,
+			 &Object::lru_hook >,
+		       bi::constant_time_size<true>> Queue;
+
+    public:
+
+      Object() : lru_flags(FLAG_NONE), lru_refcnt(0), lru_adj(0) {}
+
+      uint32_t get_refcnt() const { return lru_refcnt; }
+
+      virtual bool reclaim() = 0;
+
+      virtual ~Object() {}
+
+    private:
+      template <typename LK>
+      friend class LRU;
+    };
+
+    /* allocator & recycler interface (create or re-use LRU objects) */
+    class ObjectFactory
+    {
+    public:
+      virtual Object* alloc(void) = 0;
+      virtual void recycle(Object*) = 0;
+      virtual ~ObjectFactory() {};
+    };
+
+    template <typename LK>
+    class LRU
+    {
+    private:
+
+      struct Lane {
+	LK lock;
+	Object::Queue q;
+	// Object::Queue pinned; /* placeholder for possible expansion */
+	CACHE_PAD(0);
+	Lane() {}
+      };
+
+      Lane *qlane;
+      int n_lanes;
+      std::atomic<uint32_t> evict_lane;
+      const uint32_t lane_hiwat;
+
+      static constexpr uint32_t lru_adj_modulus = 5;
+
+      static constexpr uint32_t SENTINEL_REFCNT = 1;
+
+      /* internal flag values */
+      static constexpr uint32_t FLAG_INLRU = 0x0001;
+      static constexpr uint32_t FLAG_PINNED  = 0x0002; // possible future use
+      static constexpr uint32_t FLAG_EVICTING = 0x0004;
+
+      Lane& lane_of(void* addr) {
+	return qlane[(uint64_t)(addr) % n_lanes];
+      }
+
+      uint32_t next_evict_lane() {
+	return (evict_lane++ % n_lanes);
+      }
+
+      bool can_reclaim(Object* o) {
+	return ((o->lru_refcnt == SENTINEL_REFCNT) &&
+		(!(o->lru_flags & FLAG_EVICTING)));
+      }
+
+      Object* evict_block() {
+	uint32_t lane_ix = next_evict_lane();
+	for (int ix = 0; ix < n_lanes; ++ix,
+	       lane_ix = next_evict_lane()) {
+	  Lane& lane = qlane[lane_ix];
+	  /* hiwat check */
+	  /* XXX try the hiwat check unlocked, then recheck locked */
+	  if (lane.q.size() > lane_hiwat) {
+	    lane.lock.lock();
+	    if (lane.q.size() <= lane_hiwat) {
+	      lane.lock.unlock();
+	      continue;
+	    }
+	  } else
+	    continue;
+	  // XXXX if object at LRU has refcnt==1, take it
+	  Object* o = &(lane.q.back());
+	  if (can_reclaim(o)) {
+	    ++(o->lru_refcnt);
+	    o->lru_flags |= FLAG_EVICTING;
+	    lane.lock.unlock();
+	    if (o->reclaim()) {
+	      lane.lock.lock();
+	      --(o->lru_refcnt);
+	      /* assertions that o state has not changed across
+	       * relock */
+	      assert(o->lru_refcnt == SENTINEL_REFCNT);
+	      assert(o->lru_flags & FLAG_INLRU);
+	      Object::Queue::iterator it =
+		Object::Queue::s_iterator_to(*o);
+	      lane.q.erase(it);
+	      lane.lock.unlock();
+	      return o;
+	    } else {
+	      // XXX can't make unreachable (means what?)
+	      lane.lock.lock();
+	      --(o->lru_refcnt);
+	      o->lru_flags &= ~FLAG_EVICTING;
+	      /* unlock in next block */
+	    }
+	  } /* can_reclaim(o) */
+	  lane.lock.unlock();
+	} /* each lane */
+	return nullptr;
+      } /* evict_block */
+
+    public:
+
+      LRU(int lanes, uint32_t _hiwat)
+	: n_lanes(lanes), evict_lane(0), lane_hiwat(_hiwat)
+	  {
+	    assert(n_lanes > 0);
+	    qlane = new Lane[n_lanes];
+	  }
+
+      ~LRU() { delete[] qlane; }
+
+      bool ref(Object* o, uint32_t flags) {
+	++(o->lru_refcnt);
+	if (flags & FLAG_INITIAL) {
+	  if ((++(o->lru_adj) % lru_adj_modulus) == 0) {
+	    Lane& lane = lane_of(o);
+	    lane.lock.lock();
+	    /* move to MRU */
+	    Object::Queue::iterator it =
+	      Object::Queue::s_iterator_to(*o);
+	    lane.q.erase(it);
+	    lane.q.push_front(*o);
+	    lane.lock.unlock();
+	  } /* adj */
+	} /* initial ref */
+	return true;
+      } /* ref */
+
+      void unref(Object* o, uint32_t flags) {
+	uint32_t refcnt = --(o->lru_refcnt);
+	if (unlikely(refcnt == 0)) {
+	  Lane& lane = lane_of(o);
+	  lane.lock.lock();
+	  refcnt = o->lru_refcnt.load();
+	  if (unlikely(refcnt == 0)) {
+	    Object::Queue::iterator it =
+	      Object::Queue::s_iterator_to(*o);
+	    lane.q.erase(it);
+	    delete o;
+	  }
+	  lane.lock.unlock();
+	}
+      } /* unref */
+
+      Object* insert(ObjectFactory* fac, Edge edge, uint32_t flags) {
+	/* use supplied functor to re-use an evicted object, or
+	 * allocate a new one of the descendant type */
+	Object* o = evict_block();
+	if (o)
+	  fac->recycle(o); /* recycle existing object */
+	else
+	  o = fac->alloc(); /* get a new one */
+
+	o->lru_flags = FLAG_INLRU;
+
+	Lane& lane = lane_of(o);
+	lane.lock.lock();
+	switch (edge) {
+	case Edge::MRU:
+	  lane.q.push_front(*o);
+	  break;
+	case Edge::LRU:
+	  lane.q.push_back(*o);
+	  break;
+	default:
+	  abort();
+	  break;
+	}
+	if (flags & FLAG_INITIAL)
+	  o->lru_refcnt += 2; /* sentinel ref + initial */
+	else
+	  ++(o->lru_refcnt); /* sentinel */
+	lane.lock.unlock();
+	return o;
+      } /* insert */
+
+    };
+
+    template <typename T, typename TTree, typename CLT, typename CEQ,
+	      typename K, typename LK>
+    class TreeX
+    {
+    public:
+
+      static constexpr uint32_t FLAG_NONE = 0x0000;
+      static constexpr uint32_t FLAG_LOCK = 0x0001;
+      static constexpr uint32_t FLAG_UNLOCK = 0x0002;
+      static constexpr uint32_t FLAG_UNLOCK_ON_MISS = 0x0004;
+
+      typedef T value_type;
+      typedef TTree container_type;
+      typedef typename TTree::iterator iterator;
+      typedef std::pair<iterator, bool> check_result;
+      typedef typename TTree::insert_commit_data insert_commit_data;
+      int n_part;
+      int csz;
+
+      typedef std::unique_lock<LK> unique_lock;
+
+      struct Partition {
+	LK lock;
+	TTree tr;
+	T** cache;
+	int csz;
+	CACHE_PAD(0);
+
+	Partition() : tr(), cache(nullptr), csz(0) {}
+
+	~Partition() {
+	  if (csz)
+	    ::operator delete(cache);
+	}
+      };
+
+      struct Latch {
+	Partition* p;
+	LK* lock;
+	insert_commit_data commit_data;
+      };
+
+      Partition& partition_of_scalar(uint64_t x) {
+	return part[x % n_part];
+      }
+
+      Partition& get(uint8_t x) {
+	return part[x];
+      }
+
+      Partition*& get() {
+	return part;
+      }
+
+      void lock() {
+	std::for_each(locks.begin(), locks.end(),
+		      [](LK* lk){ lk->lock(); });
+      }
+
+      void unlock() {
+	std::for_each(locks.begin(), locks.end(),
+		      [](LK* lk){ lk->unlock(); });
+      }
+
+      TreeX(int n_part=1, int csz=127) : n_part(n_part), csz(csz) {
+	assert(n_part > 0);
+	part = new Partition[n_part];
+	for (int ix = 0; ix < n_part; ++ix) {
+	  Partition& p = part[ix];
+	  if (csz) {
+	    p.csz = csz;
+	    p.cache = (T**) ::operator new(csz * sizeof(T*));
+	    memset(p.cache, 0, csz * sizeof(T*));
+	  }
+	  locks.push_back(&p.lock);
+	}
+      }
+
+      ~TreeX() {
+	delete[] part;
+      }
+
+      T* find(uint64_t hk, const K& k, uint32_t flags) {
+	T* v;
+	Latch lat;
+	uint32_t slot = 0;
+	lat.p = &(partition_of_scalar(hk));
+	if (flags & FLAG_LOCK) {
+	  lat.lock = &lat.p->lock;
+	  lat.lock->lock();
+	}
+	if (csz) { /* template specialize? */
+	  slot = hk % csz;
+	  v = lat.p->cache[slot];
+	  if (v) {
+	    if (CEQ()(*v, k)) {
+	      if (flags & FLAG_LOCK)
+		lat.lock->unlock();
+	      return v;
+	    }
+	    v = nullptr;
+	  }
+	} else {
+	  v = nullptr;
+	}
+	iterator it = lat.p->tr.find(k, CLT());
+	if (it != lat.p->tr.end()){
+	  v = &(*(it));
+	  if (csz) {
+	    /* fill cache slot at hk */
+	    lat.p->cache[slot] = v;
+	  }
+	}
+	if (flags & FLAG_LOCK)
+	  lat.lock->unlock();
+	return v;
+      } /* find */
+
+      T* find_latch(uint64_t hk, const K& k, Latch& lat,
+		    uint32_t flags) {
+	uint32_t slot = 0;
+	T* v;
+	lat.p = &(partition_of_scalar(hk));
+	lat.lock = &lat.p->lock;
+	if (flags & FLAG_LOCK)
+	  lat.lock->lock();
+	if (csz) { /* template specialize? */
+	  slot = hk % csz;
+	  v = lat.p->cache[slot];
+	  if (v) {
+	    if (CEQ()(*v, k)) {
+	      if (flags & (FLAG_LOCK|FLAG_UNLOCK))
+		lat.lock->unlock();
+	      return v;
+	    }
+	    v = nullptr;
+	  }
+	} else {
+	  v = nullptr;
+	}
+	check_result r = lat.p->tr.insert_unique_check(
+	  k, CLT(), lat.commit_data);
+	if (! r.second /* !insertable (i.e., !found) */) {
+	  v = &(*(r.first));
+	  if (csz) {
+	    /* fill cache slot at hk */
+	    lat.p->cache[slot] = v;
+	  }
+	}
+	if (flags & (FLAG_LOCK|FLAG_UNLOCK))
+	  lat.lock->unlock();
+	return v;
+      } /* find_latch */
+
+      void insert_latched(T* v, Latch& lat, uint32_t flags) {
+	(void) lat.p->tr.insert_unique_commit(*v, lat.commit_data);
+	if (flags & FLAG_UNLOCK)
+	  lat.lock->unlock();
+      } /* insert_latched */
+
+      void insert(uint64_t hk, T* v, uint32_t flags) {
+	Partition& p = partition_of_scalar(hk);
+	if (flags & FLAG_LOCK)
+	  p.lock.lock();
+	p.tr.insert_unique(*v);
+	if (flags & FLAG_LOCK)
+	  p.lock.unlock();
+      } /* insert */
+
+      void remove(uint64_t hk, T* v, uint32_t flags) {
+	Partition& p = partition_of_scalar(hk);
+	iterator it = TTree::s_iterator_to(*v);
+	if (flags & FLAG_LOCK)
+	  p.lock.lock();
+	p.tr.erase(it);
+	if (csz) { /* template specialize? */
+	  uint32_t slot = hk % csz;
+	  T* v2 = p.cache[slot];
+	  /* we are intrusive, just compare addresses */
+	  if (v == v2)
+	    p.cache[slot] = nullptr;
+	}
+	if (flags & FLAG_LOCK)
+	  p.lock.unlock();
+      } /* remove */
+
+      void drain(std::function<void(T*)> uref,
+		 uint32_t flags = FLAG_NONE) {
+	/* clear a table, call supplied function on
+	 * each element found (e.g., retuns sentinel
+	 * references) */
+	for (int t_ix = 0; t_ix < n_part; ++t_ix) {
+	  Partition& p = part[t_ix];
+	  if (flags & FLAG_LOCK) /* LOCKED */
+	    p.lock.lock();
+	  while (p.tr.size() > 0) {
+	    iterator it = p.tr.begin();
+	    T* v = &(*it);
+	    p.tr.erase(it); /* must precede uref(v), in
+			     * safe_link mode */
+	    uref(v);
+	  }
+	  if (flags & FLAG_LOCK) /* we locked it, !LOCKED */
+	    p.lock.unlock();
+	} /* each partition */
+      } /* drain */
+
+    private:
+      Partition *part;
+      std::vector<LK*> locks;
+    };
+
+  } /* namespace LRU */
+} /* namespace cohort */
+
+#endif /* COHORT_LRU_H */
diff --git a/src/common/common_init.h b/src/common/common_init.h
index 6d11ef3..1184222 100644
--- a/src/common/common_init.h
+++ b/src/common/common_init.h
@@ -37,6 +37,9 @@ enum common_init_flags_t {
 
   // don't do anything daemonish, like create /var/run/ceph, or print a banner
   CINIT_FLAG_NO_DAEMON_ACTIONS = 0x8,
+
+  // don't drop privileges
+  CINIT_FLAG_DEFER_DROP_PRIVILEGES = 0x16,
 };
 
 /*
diff --git a/src/common/config.cc b/src/common/config.cc
index d67a96b..622e237 100644
--- a/src/common/config.cc
+++ b/src/common/config.cc
@@ -58,17 +58,6 @@ using std::string;
 
 const char *CEPH_CONF_FILE_DEFAULT = "$data_dir/config, /etc/ceph/$cluster.conf, ~/.ceph/$cluster.conf, $cluster.conf";
 
-// file layouts
-struct ceph_file_layout g_default_file_layout = {
- fl_stripe_unit: init_le32(1<<22),
- fl_stripe_count: init_le32(1),
- fl_object_size: init_le32(1<<22),
- fl_cas_hash: init_le32(0),
- fl_object_stripe_unit: init_le32(0),
- fl_unused: init_le32(-1),
- fl_pg_pool : init_le32(-1),
-};
-
 #define _STR(x) #x
 #define STRINGIFY(x) _STR(x)
 
@@ -121,7 +110,7 @@ int ceph_resolve_file_search(const std::string& filename_list,
 }
 
 md_config_t::md_config_t()
-  : cluster("ceph"),
+  : cluster(""),
 
 #define OPTION_OPT_INT(name, def_val) name(def_val),
 #define OPTION_OPT_LONGLONG(name, def_val) name((1LL) * def_val),
@@ -199,13 +188,22 @@ void md_config_t::remove_observer(md_config_obs_t* observer_)
 }
 
 int md_config_t::parse_config_files(const char *conf_files,
-				    std::deque<std::string> *parse_errors,
 				    std::ostream *warnings,
 				    int flags)
 {
   Mutex::Locker l(lock);
+
   if (internal_safe_to_start_threads)
     return -ENOSYS;
+
+  if (!cluster.size() && !conf_files) {
+    /*
+     * set the cluster name to 'ceph' when neither cluster name nor
+     * configuration file are specified.
+     */
+    cluster = "ceph";
+  }
+
   if (!conf_files) {
     const char *c = getenv("CEPH_CONF");
     if (c) {
@@ -220,6 +218,7 @@ int md_config_t::parse_config_files(const char *conf_files,
 
   std::list<std::string> cfl;
   get_str_list(conf_files, cfl);
+
   auto p = cfl.begin();
   while (p != cfl.end()) {
     // expand $data_dir?
@@ -236,11 +235,10 @@ int md_config_t::parse_config_files(const char *conf_files,
       ++p;
     }
   }
-  return parse_config_files_impl(cfl, parse_errors, warnings);
+  return parse_config_files_impl(cfl, warnings);
 }
 
 int md_config_t::parse_config_files_impl(const std::list<std::string> &conf_files,
-					 std::deque<std::string> *parse_errors,
 					 std::ostream *warnings)
 {
   assert(lock.is_locked());
@@ -251,7 +249,7 @@ int md_config_t::parse_config_files_impl(const std::list<std::string> &conf_file
     cf.clear();
     string fn = *c;
     expand_meta(fn, warnings);
-    int ret = cf.parse_file(fn.c_str(), parse_errors, warnings);
+    int ret = cf.parse_file(fn.c_str(), &parse_errors, warnings);
     if (ret == 0)
       break;
     else if (ret != -ENOENT)
@@ -260,6 +258,26 @@ int md_config_t::parse_config_files_impl(const std::list<std::string> &conf_file
   if (c == conf_files.end())
     return -EINVAL;
 
+  if (cluster.size() == 0) {
+    /*
+     * If cluster name is not set yet, use the prefix of the
+     * basename of configuration file as cluster name.
+     */
+    const char *fn = c->c_str();
+    std::string name(basename(fn));
+    int pos = name.find(".conf");
+    if (pos < 0) {
+      /*
+       * If the configuration file does not follow $cluster.conf
+       * convention, we do the last try and assign the cluster to
+       * 'ceph'.
+       */
+      cluster = "ceph";
+    } else {
+      cluster = name.substr(0, pos);      
+    }
+  }
+
   std::vector <std::string> my_sections;
   _get_my_sections(my_sections);
   for (int i = 0; i < NUM_CONFIG_OPTIONS; i++) {
@@ -302,15 +320,14 @@ int md_config_t::parse_config_files_impl(const std::list<std::string> &conf_file
   }
   if (!old_style_section_names.empty()) {
     ostringstream oss;
-    oss << "ERROR! old-style section name(s) found: ";
+    cerr << "ERROR! old-style section name(s) found: ";
     string sep;
     for (std::deque < std::string >::const_iterator os = old_style_section_names.begin();
 	 os != old_style_section_names.end(); ++os) {
-      oss << sep << *os;
+      cerr << sep << *os;
       sep = ", ";
     }
-    oss << ". Please use the new style section names that include a period.";
-    parse_errors->push_back(oss.str());
+    cerr << ". Please use the new style section names that include a period.";
   }
   return 0;
 }
@@ -580,7 +597,11 @@ int md_config_t::parse_injectargs(std::vector<const char*>& args,
 void md_config_t::apply_changes(std::ostream *oss)
 {
   Mutex::Locker l(lock);
-  _apply_changes(oss);
+  /*
+   * apply changes until the cluster name is assigned
+   */
+  if (cluster.size())
+    _apply_changes(oss);
 }
 
 bool md_config_t::_internal_field(const string& s)
@@ -1205,3 +1226,8 @@ void md_config_t::diff(
       diff->insert(make_pair(opt->name, make_pair(local_val, other_val)));
   }
 }
+
+void md_config_t::complain_about_parse_errors(CephContext *cct)
+{
+  ::complain_about_parse_errors(cct, &parse_errors);
+}
diff --git a/src/common/config.h b/src/common/config.h
index 79c4437..2977f42 100644
--- a/src/common/config.h
+++ b/src/common/config.h
@@ -15,8 +15,6 @@
 #ifndef CEPH_CONFIG_H
 #define CEPH_CONFIG_H
 
-extern struct ceph_file_layout g_default_file_layout;
-
 #include <iosfwd>
 #include <vector>
 #include <map>
@@ -106,7 +104,6 @@ public:
 
   // Parse a config file
   int parse_config_files(const char *conf_files,
-			 std::deque<std::string> *parse_errors,
 			 std::ostream *warnings, int flags);
 
   // Absorb config settings from the environment
@@ -162,6 +159,9 @@ public:
   void diff(const md_config_t *other,
             map<string,pair<string,string> > *diff, set<string> *unknown);
 
+  /// print/log warnings/errors from parsing the config
+  void complain_about_parse_errors(CephContext *cct);
+
 private:
   void _show_config(std::ostream *out, Formatter *f);
 
@@ -176,7 +176,6 @@ private:
   int parse_injectargs(std::vector<const char*>& args,
 		      std::ostream *oss);
   int parse_config_files_impl(const std::list<std::string> &conf_files,
-			      std::deque<std::string> *parse_errors,
 			      std::ostream *warnings);
 
   int set_val_impl(const char *val, const config_option *opt);
@@ -197,6 +196,9 @@ private:
 
   // The configuration file we read, or NULL if we haven't read one.
   ConfFile cf;
+public:
+  std::deque<std::string> parse_errors;
+private:
 
   obs_map_t observers;
   changed_set_t changed;
diff --git a/src/common/config_opts.h b/src/common/config_opts.h
index 04dafac..aea9c16 100644
--- a/src/common/config_opts.h
+++ b/src/common/config_opts.h
@@ -195,7 +195,7 @@ OPTION(ms_inject_delay_probability, OPT_DOUBLE, 0) // range [0, 1]
 OPTION(ms_inject_internal_delays, OPT_DOUBLE, 0)   // seconds
 OPTION(ms_dump_on_send, OPT_BOOL, false)           // hexdump msg to log on send
 OPTION(ms_dump_corrupt_message_level, OPT_INT, 1)  // debug level to hexdump undecodeable messages at
-OPTION(ms_async_op_threads, OPT_INT, 2)
+OPTION(ms_async_op_threads, OPT_INT, 3)
 OPTION(ms_async_set_affinity, OPT_BOOL, true)
 // example: ms_async_affinity_cores = 0,1
 // The number of coreset is expected to equal to ms_async_op_threads, otherwise
@@ -235,7 +235,7 @@ OPTION(mon_osd_max_op_age, OPT_DOUBLE, 32)     // max op age before we get conce
 OPTION(mon_osd_max_split_count, OPT_INT, 32) // largest number of PGs per "involved" OSD to let split create
 OPTION(mon_osd_allow_primary_temp, OPT_BOOL, false)  // allow primary_temp to be set in the osdmap
 OPTION(mon_osd_allow_primary_affinity, OPT_BOOL, false)  // allow primary_affinity to be set in the osdmap
-OPTION(mon_osd_prime_pg_temp, OPT_BOOL, false)  // prime osdmap with pg mapping changes
+OPTION(mon_osd_prime_pg_temp, OPT_BOOL, true)  // prime osdmap with pg mapping changes
 OPTION(mon_osd_prime_pg_temp_max_time, OPT_FLOAT, .5)  // max time to spend priming
 OPTION(mon_osd_pool_ec_fast_read, OPT_BOOL, false) // whether turn on fast read on the pool or not
 OPTION(mon_stat_smooth_intervals, OPT_INT, 2)  // smooth stats over last N PGMap maps
@@ -248,6 +248,7 @@ OPTION(mon_accept_timeout_factor, OPT_FLOAT, 2.0)    // on leader, if paxos upda
 OPTION(mon_clock_drift_allowed, OPT_FLOAT, .050) // allowed clock drift between monitors
 OPTION(mon_clock_drift_warn_backoff, OPT_FLOAT, 5) // exponential backoff for clock drift warnings
 OPTION(mon_timecheck_interval, OPT_FLOAT, 300.0) // on leader, timecheck (clock drift check) interval (seconds)
+OPTION(mon_timecheck_skew_interval, OPT_FLOAT, 30.0) // on leader, timecheck (clock drift check) interval when in presence of a skew (seconds)
 OPTION(mon_pg_create_interval, OPT_FLOAT, 30.0) // no more than every 30s
 OPTION(mon_pg_stuck_threshold, OPT_INT, 300) // number of seconds after which pgs can be considered inactive, unclean, or stale (see doc/control.rst under dump_stuck for more info)
 OPTION(mon_pg_min_inactive, OPT_U64, 1) // the number of PGs which have to be inactive longer than 'mon_pg_stuck_threshold' before health goes into ERR. 0 means disabled, never go into ERR.
@@ -265,7 +266,9 @@ OPTION(mon_globalid_prealloc, OPT_U32, 10000)   // how many globalids to preallo
 OPTION(mon_osd_report_timeout, OPT_INT, 900)    // grace period before declaring unresponsive OSDs dead
 OPTION(mon_force_standby_active, OPT_BOOL, true) // should mons force standby-replay mds to be active
 OPTION(mon_warn_on_old_mons, OPT_BOOL, true) // should mons set health to WARN if part of quorum is old?
-OPTION(mon_warn_on_legacy_crush_tunables, OPT_BOOL, true) // warn if crush tunables are not optimal
+OPTION(mon_warn_on_legacy_crush_tunables, OPT_BOOL, true) // warn if crush tunables are too old (older than mon_min_crush_required_version)
+OPTION(mon_crush_min_required_version, OPT_STR, "firefly")
+OPTION(mon_warn_on_crush_straw_calc_version_zero, OPT_BOOL, true) // warn if crush straw_calc_version==0
 OPTION(mon_warn_on_osd_down_out_interval_zero, OPT_BOOL, true) // warn if 'mon_osd_down_out_interval == 0'
 OPTION(mon_warn_on_cache_pools_without_hit_sets, OPT_BOOL, true)
 OPTION(mon_min_osdmap_epochs, OPT_INT, 500)
@@ -281,6 +284,8 @@ OPTION(mon_daemon_bytes, OPT_U64, 400ul << 20)  // mds, osd message memory cap (
 OPTION(mon_max_log_entries_per_event, OPT_INT, 4096)
 OPTION(mon_reweight_min_pgs_per_osd, OPT_U64, 10)   // min pgs per osd for reweight-by-pg command
 OPTION(mon_reweight_min_bytes_per_osd, OPT_U64, 100*1024*1024)   // min bytes per osd for reweight-by-utilization command
+OPTION(mon_reweight_max_osds, OPT_INT, 4)   // max osds to change per reweight-by-* command
+OPTION(mon_reweight_max_change, OPT_DOUBLE, 0.05)
 OPTION(mon_health_data_update_interval, OPT_FLOAT, 60.0)
 OPTION(mon_health_to_clog, OPT_BOOL, true)
 OPTION(mon_health_to_clog_interval, OPT_INT, 3600)
@@ -388,6 +393,7 @@ OPTION(client_inject_fixed_oldest_tid, OPT_BOOL, false)  // synthetic client bug
 OPTION(client_metadata, OPT_STR, "")
 OPTION(client_acl_type, OPT_STR, "")
 OPTION(client_permissions, OPT_BOOL, true)
+OPTION(client_dirsize_rbytes, OPT_BOOL, true)
 
 // note: the max amount of "in flight" dirty data is roughly (max - target)
 OPTION(fuse_use_invalidate_cb, OPT_BOOL, false) // use fuse 2.8+ invalidate callback to keep page cache consistent
@@ -398,11 +404,13 @@ OPTION(fuse_atomic_o_trunc, OPT_BOOL, true)
 OPTION(fuse_debug, OPT_BOOL, false)
 OPTION(fuse_multithreaded, OPT_BOOL, true)
 OPTION(fuse_require_active_mds, OPT_BOOL, true) // if ceph_fuse requires active mds server
+OPTION(fuse_syncfs_on_mksnap, OPT_BOOL, true)
 
 OPTION(client_try_dentry_invalidate, OPT_BOOL, true) // the client should try to use dentry invaldation instead of remounting, on kernels it believes that will work for
 OPTION(client_die_on_failed_remount, OPT_BOOL, true)
 OPTION(client_check_pool_perm, OPT_BOOL, true)
 OPTION(client_use_faked_inos, OPT_BOOL, false)
+OPTION(client_mds_namespace, OPT_INT, -1)
 
 OPTION(crush_location, OPT_STR, "")       // whitespace-separated list of key=value pairs describing crush location
 
@@ -453,8 +461,7 @@ OPTION(mds_log_pause, OPT_BOOL, false)
 OPTION(mds_log_skip_corrupt_events, OPT_BOOL, false)
 OPTION(mds_log_max_events, OPT_INT, -1)
 OPTION(mds_log_events_per_segment, OPT_INT, 1024)
-OPTION(mds_log_segment_size, OPT_INT, 0)  // segment size for mds log,
-	      // defaults to g_default_file_layout.fl_object_size (4MB)
+OPTION(mds_log_segment_size, OPT_INT, 0)  // segment size for mds log, default to default file_layout_t
 OPTION(mds_log_max_segments, OPT_U32, 30)
 OPTION(mds_log_max_expiring, OPT_INT, 20)
 OPTION(mds_bal_sample_interval, OPT_FLOAT, 3.0)  // every 5 seconds
@@ -542,6 +549,9 @@ OPTION(mds_root_ino_gid, OPT_INT, 0) // The GID of / on new filesystems
 
 OPTION(mds_max_scrub_ops_in_progress, OPT_INT, 5) // the number of simultaneous scrubs allowed
 
+// Maximum number of damaged frags/dentries before whole MDS rank goes damaged
+OPTION(mds_damage_table_max_entries, OPT_INT, 10000)
+
 // If true, compact leveldb store on mount
 OPTION(osd_compact_leveldb_on_mount, OPT_BOOL, false)
 
@@ -578,6 +588,12 @@ OPTION(osd_uuid, OPT_UUID, uuid_d())
 OPTION(osd_data, OPT_STR, "/var/lib/ceph/osd/$cluster-$id")
 OPTION(osd_journal, OPT_STR, "/var/lib/ceph/osd/$cluster-$id/journal")
 OPTION(osd_journal_size, OPT_INT, 5120)         // in mb
+// flags for specific control purpose during osd mount() process. 
+// e.g., can be 1 to skip over replaying journal
+// or 2 to skip over mounting omap or 3 to skip over both.
+// This might be helpful in case the journal is totally corrupted
+// and we still want to bring the osd daemon back normally, etc.
+OPTION(osd_os_flags, OPT_U32, 0)
 OPTION(osd_max_write_size, OPT_INT, 90)
 OPTION(osd_max_pgls, OPT_U64, 1024) // max number of pgls entries to return
 OPTION(osd_client_message_size_cap, OPT_U64, 500*1024L*1024L) // client data allowed in-memory (in bytes)
@@ -586,6 +602,8 @@ OPTION(osd_pg_op_threshold_ratio, OPT_U64, 2)             // the expected maximu
 OPTION(osd_pg_bits, OPT_INT, 6)  // bits per osd
 OPTION(osd_pgp_bits, OPT_INT, 6)  // bits per osd
 OPTION(osd_crush_chooseleaf_type, OPT_INT, 1) // 1 = host
+// This parameter is not consumed by ceph C code but the upstart scripts.
+// OPTION(osd_crush_initial_weight, OPT_DOUBLE, 0) // the initial weight is for newly added osds.
 OPTION(osd_pool_use_gmt_hitset, OPT_BOOL, true) // try to use gmt for hitset archive names if all osds in cluster support it.
 OPTION(osd_pool_default_crush_rule, OPT_INT, -1) // deprecated for osd_pool_default_crush_replicated_ruleset
 OPTION(osd_pool_default_crush_replicated_ruleset, OPT_INT, CEPH_DEFAULT_CRUSH_REPLICATED_RULESET)
@@ -632,6 +650,10 @@ OPTION(osd_hit_set_min_size, OPT_INT, 1000)  // min target size for a HitSet
 OPTION(osd_hit_set_max_size, OPT_INT, 100000)  // max target size for a HitSet
 OPTION(osd_hit_set_namespace, OPT_STR, ".ceph-internal") // rados namespace for hit_set tracking
 
+// conservative default throttling values
+OPTION(osd_tier_promote_max_objects_sec, OPT_U64, 5 * 1024*1024)
+OPTION(osd_tier_promote_max_bytes_sec, OPT_U64, 25)
+
 OPTION(osd_tier_default_cache_mode, OPT_STR, "writeback")
 OPTION(osd_tier_default_cache_hit_set_count, OPT_INT, 4)
 OPTION(osd_tier_default_cache_hit_set_period, OPT_INT, 1200)
@@ -869,6 +891,7 @@ OPTION(bdev_inject_crash_flush_delay, OPT_INT, 2) // wait N more seconds on flus
 OPTION(bdev_aio, OPT_BOOL, true)
 OPTION(bdev_aio_poll_ms, OPT_INT, 250)  // milliseconds
 OPTION(bdev_aio_max_queue_depth, OPT_INT, 32)
+OPTION(bdev_block_size, OPT_INT, 4096)
 
 // if yes, osd will unbind all NVMe devices from kernel driver and bind them
 // to the uio_pci_generic driver. The purpose is to prevent the case where
@@ -910,7 +933,7 @@ OPTION(bluestore_max_dir_size, OPT_U32, 1000000)
 OPTION(bluestore_min_alloc_size, OPT_U32, 64*1024)
 OPTION(bluestore_onode_map_size, OPT_U32, 1024)   // onodes per collection
 OPTION(bluestore_cache_tails, OPT_BOOL, true)   // cache tail blocks in Onode
-OPTION(bluestore_backend, OPT_STR, "rocksdb")
+OPTION(bluestore_kvbackend, OPT_STR, "rocksdb")
 OPTION(bluestore_rocksdb_options, OPT_STR, "compression=kNoCompression,max_write_buffer_number=16,min_write_buffer_number_to_merge=3,recycle_log_file_num=16")
 OPTION(bluestore_fsck_on_mount, OPT_BOOL, false)
 OPTION(bluestore_fsck_on_umount, OPT_BOOL, false)
@@ -974,6 +997,9 @@ OPTION(filestore_wbthrottle_xfs_inodes_start_flusher, OPT_U64, 500)
 OPTION(filestore_wbthrottle_btrfs_inodes_hard_limit, OPT_U64, 5000)
 OPTION(filestore_wbthrottle_xfs_inodes_hard_limit, OPT_U64, 5000)
 
+//Introduce a O_DSYNC write in the filestore
+OPTION(filestore_odsync_write, OPT_BOOL, false)
+
 // Tests index failure paths
 OPTION(filestore_index_retry_probability, OPT_DOUBLE, 0)
 
@@ -1008,6 +1034,7 @@ OPTION(filestore_btrfs_clone_range, OPT_BOOL, true)
 OPTION(filestore_zfs_snap, OPT_BOOL, false) // zfsonlinux is still unstable
 OPTION(filestore_fsync_flushes_journal_data, OPT_BOOL, false)
 OPTION(filestore_fiemap, OPT_BOOL, false)     // (try to) use fiemap
+OPTION(filestore_punch_hole, OPT_BOOL, false)
 OPTION(filestore_seek_data_hole, OPT_BOOL, false)     // (try to) use seek_data/hole
 OPTION(filestore_fadvise, OPT_BOOL, true)
 //collect device partition information for management application to use
@@ -1025,10 +1052,25 @@ OPTION(filestore_xfs_extsize, OPT_BOOL, false)
 OPTION(filestore_journal_parallel, OPT_BOOL, false)
 OPTION(filestore_journal_writeahead, OPT_BOOL, false)
 OPTION(filestore_journal_trailing, OPT_BOOL, false)
-OPTION(filestore_queue_max_ops, OPT_INT, 50)
-OPTION(filestore_queue_max_bytes, OPT_INT, 100 << 20)
-OPTION(filestore_queue_committing_max_ops, OPT_INT, 500)        // this is ON TOP of filestore_queue_max_*
-OPTION(filestore_queue_committing_max_bytes, OPT_INT, 100 << 20) //  "
+OPTION(filestore_queue_max_ops, OPT_U64, 50)
+OPTION(filestore_queue_max_bytes, OPT_U64, 100 << 20)
+
+OPTION(filestore_caller_concurrency, OPT_INT, 10)
+
+/// Expected filestore throughput in B/s
+OPTION(filestore_expected_throughput_bytes, OPT_DOUBLE, 100 << 20)
+/// Expected filestore throughput in ops/s
+OPTION(filestore_expected_throughput_ops, OPT_DOUBLE, 100)
+
+/// Filestore max delay multiple (probably don't need to change)
+OPTION(filestore_queue_max_delay_multiple, OPT_DOUBLE, 10)
+/// Filestore max delay multiple (probably don't need to change)
+OPTION(filestore_queue_high_delay_multiple, OPT_DOUBLE, 2)
+
+/// Use above to inject delays intended to keep the op queue between low and high
+OPTION(filestore_queue_low_threshhold, OPT_DOUBLE, 0.2)
+OPTION(filestore_queue_high_threshhold, OPT_DOUBLE, 0.8)
+
 OPTION(filestore_op_threads, OPT_INT, 2)
 OPTION(filestore_op_thread_timeout, OPT_INT, 60)
 OPTION(filestore_op_thread_suicide_timeout, OPT_INT, 180)
@@ -1050,6 +1092,7 @@ OPTION(filestore_debug_verify_split, OPT_BOOL, false)
 OPTION(journal_dio, OPT_BOOL, true)
 OPTION(journal_aio, OPT_BOOL, true)
 OPTION(journal_force_aio, OPT_BOOL, false)
+OPTION(journal_block_size, OPT_INT, 4096)
 
 // max bytes to search ahead in journal searching for corruption
 OPTION(journal_max_corrupt_search, OPT_U64, 10<<20)
@@ -1057,8 +1100,16 @@ OPTION(journal_block_align, OPT_BOOL, true)
 OPTION(journal_write_header_frequency, OPT_U64, 0)
 OPTION(journal_max_write_bytes, OPT_INT, 10 << 20)
 OPTION(journal_max_write_entries, OPT_INT, 100)
-OPTION(journal_queue_max_ops, OPT_INT, 300)
-OPTION(journal_queue_max_bytes, OPT_INT, 32 << 20)
+
+/// Target range for journal fullness
+OPTION(journal_throttle_low_threshhold, OPT_DOUBLE, 0.5)
+OPTION(journal_throttle_high_threshhold, OPT_DOUBLE, 0.8)
+
+/// Multiple over expected at high_threshhold (probably don't need to change)
+OPTION(journal_throttle_high_multiple, OPT_DOUBLE, 2)
+/// Multiple over expected at max (probably don't need to change)
+OPTION(journal_throttle_max_multiple, OPT_DOUBLE, 10)
+
 OPTION(journal_align_min_size, OPT_INT, 64 << 10)  // align data payloads >= this.
 OPTION(journal_replay_from, OPT_INT, 0)
 OPTION(journal_zero_on_create, OPT_BOOL, false)
@@ -1117,9 +1168,11 @@ OPTION(rbd_default_format, OPT_INT, 2)
 OPTION(rbd_default_order, OPT_INT, 22)
 OPTION(rbd_default_stripe_count, OPT_U64, 0) // changing requires stripingv2 feature
 OPTION(rbd_default_stripe_unit, OPT_U64, 0) // changing to non-object size requires stripingv2 feature
-OPTION(rbd_default_features, OPT_INT, 3) // only applies to format 2 images
-					 // +1 for layering, +2 for stripingv2,
-					 // +4 for exclusive lock, +8 for object map
+OPTION(rbd_default_features, OPT_INT, 61)   // only applies to format 2 images
+					    // +1 for layering, +2 for stripingv2,
+					    // +4 for exclusive lock, +8 for object map
+					    // +16 for fast-diff, +32 for deep-flatten,
+					    // +64 for journaling
 
 OPTION(rbd_default_map_options, OPT_STR, "") // default rbd map -o / --options
 
@@ -1179,17 +1232,38 @@ OPTION(rgw_swift_url_prefix, OPT_STR, "swift") // entry point for which a url is
 OPTION(rgw_swift_auth_url, OPT_STR, "")        // default URL to go and verify tokens for v1 auth (if not using internal swift auth)
 OPTION(rgw_swift_auth_entry, OPT_STR, "auth")  // entry point for which a url is considered a swift auth url
 OPTION(rgw_swift_tenant_name, OPT_STR, "")  // tenant name to use for swift access
+OPTION(rgw_swift_account_in_url, OPT_BOOL, false)  // assume that URL always contain the account (aka tenant) part
 OPTION(rgw_swift_enforce_content_length, OPT_BOOL, false)  // enforce generation of Content-Length even in cost of performance or scalability
 OPTION(rgw_keystone_url, OPT_STR, "")  // url for keystone server
 OPTION(rgw_keystone_admin_token, OPT_STR, "")  // keystone admin token (shared secret)
 OPTION(rgw_keystone_admin_user, OPT_STR, "")  // keystone admin user name
 OPTION(rgw_keystone_admin_password, OPT_STR, "")  // keystone admin user password
-OPTION(rgw_keystone_admin_tenant, OPT_STR, "")  // keystone admin user tenant
+OPTION(rgw_keystone_admin_tenant, OPT_STR, "")  // keystone admin user tenant (for keystone v2.0)
+OPTION(rgw_keystone_admin_project, OPT_STR, "")  // keystone admin user project (for keystone v3)
+OPTION(rgw_keystone_admin_domain, OPT_STR, "")  // keystone admin user domain
+OPTION(rgw_keystone_api_version, OPT_INT, 2) // Version of Keystone API to use (2 or 3)
 OPTION(rgw_keystone_accepted_roles, OPT_STR, "Member, admin")  // roles required to serve requests
 OPTION(rgw_keystone_token_cache_size, OPT_INT, 10000)  // max number of entries in keystone token cache
 OPTION(rgw_keystone_revocation_interval, OPT_INT, 15 * 60)  // seconds between tokens revocation check
+OPTION(rgw_keystone_verify_ssl, OPT_BOOL, true) // should we try to verify keystone's ssl
+OPTION(rgw_keystone_implicit_tenants, OPT_BOOL, false)  // create new users in their own tenants of the same name
 OPTION(rgw_s3_auth_use_rados, OPT_BOOL, true)  // should we try to use the internal credentials for s3?
 OPTION(rgw_s3_auth_use_keystone, OPT_BOOL, false)  // should we try to use keystone for s3?
+
+/* OpenLDAP-style LDAP parameter strings */
+/* rgw_ldap_uri  space-separated list of LDAP servers in URI format */
+OPTION(rgw_ldap_uri, OPT_STR, "ldaps://<ldap.your.domain>")
+/* rgw_ldap_binddn  LDAP entry RGW will bind with (user match) */
+OPTION(rgw_ldap_binddn, OPT_STR, "uid=admin,cn=users,dc=example,dc=com")
+/* rgw_ldap_searchdn  LDAP search base (basedn) */
+OPTION(rgw_ldap_searchdn, OPT_STR, "cn=users,cn=accounts,dc=example,dc=com")
+/* rgw_ldap_dnattr  LDAP attribute containing RGW user names (to form binddns)*/
+OPTION(rgw_ldap_dnattr, OPT_STR, "uid")
+/* rgw_ldap_secret  file containing credentials for rgw_ldap_binddn */
+OPTION(rgw_ldap_secret, OPT_STR, "/etc/openldap/secret")
+/* rgw_s3_auth_use_ldap  use LDAP for RGW auth? */
+OPTION(rgw_s3_auth_use_ldap, OPT_BOOL, false)
+
 OPTION(rgw_admin_entry, OPT_STR, "admin")  // entry point for which a url is considered an admin request
 OPTION(rgw_enforce_swift_acls, OPT_BOOL, true)
 OPTION(rgw_swift_token_expiration, OPT_INT, 24 * 3600) // time in seconds for swift token expiration
@@ -1201,11 +1275,33 @@ OPTION(rgw_thread_pool_size, OPT_INT, 100)
 OPTION(rgw_num_control_oids, OPT_INT, 8)
 OPTION(rgw_num_rados_handles, OPT_U32, 1)
 
+/* The following are tunables for caches of RGW NFS (and other file
+ * client) objects.
+ *
+ * The file handle cache is a partitioned hash table
+ * (fhcache_partitions), each with a closed hash part and backing
+ * b-tree mapping.  The number of partions is expected to be a small
+ * prime, the cache size something larger but less than 5K, the total
+ * size of the cache is n_part * cache_size.
+ */
+OPTION(rgw_nfs_lru_lanes, OPT_INT, 5)
+OPTION(rgw_nfs_lru_lane_hiwat, OPT_INT, 911)
+OPTION(rgw_nfs_fhcache_partitions, OPT_INT, 3)
+OPTION(rgw_nfs_fhcache_size, OPT_INT, 2017) /* 3*2017=6051 */
+
 OPTION(rgw_zone, OPT_STR, "") // zone name
 OPTION(rgw_zone_root_pool, OPT_STR, ".rgw.root")    // pool where zone specific info is stored
+OPTION(rgw_default_zone_info_oid, OPT_STR, "default.zone")  // oid where default zone info is stored
 OPTION(rgw_region, OPT_STR, "") // region name
-OPTION(rgw_region_root_pool, OPT_STR, ".rgw.root")  // pool where all region info is stored
 OPTION(rgw_default_region_info_oid, OPT_STR, "default.region")  // oid where default region info is stored
+OPTION(rgw_zonegroup, OPT_STR, "") // zone group name
+OPTION(rgw_zonegroup_root_pool, OPT_STR, ".rgw.root")  // pool where all zone group info is stored
+OPTION(rgw_default_zonegroup_info_oid, OPT_STR, "default.zonegroup")  // oid where default zone group info is stored
+OPTION(rgw_realm, OPT_STR, "") // realm name
+OPTION(rgw_realm_root_pool, OPT_STR, ".rgw.root")  // pool where all realm info is stored
+OPTION(rgw_default_realm_info_oid, OPT_STR, "default.realm")  // oid where default realm info is stored
+OPTION(rgw_period_root_pool, OPT_STR, ".rgw.root")  // pool where all period info is stored
+OPTION(rgw_period_latest_epoch_info_oid, OPT_STR, ".latest_epoch") // oid where current period info is stored
 OPTION(rgw_log_nonexistent_bucket, OPT_BOOL, false)
 OPTION(rgw_log_object_name, OPT_STR, "%Y-%m-%d-%H-%i-%n")      // man date to see codes (a subset are supported)
 OPTION(rgw_log_object_name_utc, OPT_BOOL, false)
@@ -1281,6 +1377,17 @@ OPTION(rgw_objexp_chunk_size, OPT_U32, 100) // maximum number of entries in a si
 
 OPTION(rgw_enable_static_website, OPT_BOOL, false) // enable static website feature
 
+OPTION(rgw_num_async_rados_threads, OPT_INT, 32) // num of threads to use for async rados operations
+OPTION(rgw_md_notify_interval_msec, OPT_INT, 200) // metadata changes notification interval to followers
+OPTION(rgw_run_sync_thread, OPT_BOOL, true) // whether radosgw (not radosgw-admin) spawns the sync thread
+OPTION(rgw_sync_lease_period, OPT_INT, 120) // time in second for lease that rgw takes on a specific log (or log shard)
+
+OPTION(rgw_realm_reconfigure_delay, OPT_DOUBLE, 2) // seconds to wait before reloading realm configuration
+OPTION(rgw_period_push_interval, OPT_DOUBLE, 2) // seconds to wait before retrying "period push"
+OPTION(rgw_period_push_interval_max, OPT_DOUBLE, 30) // maximum interval after exponential backoff
+
+OPTION(rgw_swift_versioning_enabled, OPT_BOOL, false) // whether swift object versioning feature is enabled
+
 OPTION(mutex_perf_counter, OPT_BOOL, false) // enable/disable mutex perf counter
 OPTION(throttler_perf_counter, OPT_BOOL, true) // enable/disable throttler perf counter
 
diff --git a/src/common/dout.h b/src/common/dout.h
index 22befd6..9f8fd27 100644
--- a/src/common/dout.h
+++ b/src/common/dout.h
@@ -39,6 +39,14 @@ inline std::ostream& operator<<(std::ostream& out, _bad_endl_use_dendl_t) {
   return out;
 }
 
+class DoutPrefixProvider {
+public:
+  virtual string gen_prefix() const = 0;
+  virtual CephContext *get_cct() const = 0;
+  virtual unsigned get_subsys() const = 0;
+  virtual ~DoutPrefixProvider() {}
+};
+
 // generic macros
 #define dout_prefix *_dout
 
@@ -58,6 +66,8 @@ inline std::ostream& operator<<(std::ostream& out, _bad_endl_use_dendl_t) {
 #define ldout(cct, v)  dout_impl(cct, dout_subsys, v) dout_prefix
 #define lderr(cct) dout_impl(cct, ceph_subsys_, -1) dout_prefix
 
+#define ldpp_dout(dpp, v) if (dpp) dout_impl(dpp->get_cct(), dpp->get_subsys(), v) (*_dout << dpp->gen_prefix())
+
 #define lgeneric_subdout(cct, sub, v) dout_impl(cct, ceph_subsys_##sub, v) *_dout
 #define lgeneric_dout(cct, v) dout_impl(cct, ceph_subsys_, v) *_dout
 #define lgeneric_derr(cct) dout_impl(cct, ceph_subsys_, -1) *_dout
diff --git a/src/common/fs_types.cc b/src/common/fs_types.cc
new file mode 100644
index 0000000..741e4f1
--- /dev/null
+++ b/src/common/fs_types.cc
@@ -0,0 +1,124 @@
+
+#include "include/fs_types.h"
+#include "common/Formatter.h"
+#include "include/ceph_features.h"
+
+void dump(const ceph_file_layout& l, Formatter *f)
+{
+  f->dump_unsigned("stripe_unit", l.fl_stripe_unit);
+  f->dump_unsigned("stripe_count", l.fl_stripe_count);
+  f->dump_unsigned("object_size", l.fl_object_size);
+  if (l.fl_cas_hash)
+    f->dump_unsigned("cas_hash", l.fl_cas_hash);
+  if (l.fl_object_stripe_unit)
+    f->dump_unsigned("object_stripe_unit", l.fl_object_stripe_unit);
+  if (l.fl_pg_pool)
+    f->dump_unsigned("pg_pool", l.fl_pg_pool);
+}
+
+void dump(const ceph_dir_layout& l, Formatter *f)
+{
+  f->dump_unsigned("dir_hash", l.dl_dir_hash);
+}
+
+
+// file_layout_t
+
+bool file_layout_t::is_valid() const
+{
+  /* stripe unit, object size must be non-zero, 64k increment */
+  if (!stripe_unit || (stripe_unit & (CEPH_MIN_STRIPE_UNIT-1)))
+    return false;
+  if (!object_size || (object_size & (CEPH_MIN_STRIPE_UNIT-1)))
+    return false;
+  /* object size must be a multiple of stripe unit */
+  if (object_size < stripe_unit || object_size % stripe_unit)
+    return false;
+  /* stripe count must be non-zero */
+  if (!stripe_count)
+    return false;
+  return true;
+}
+
+void file_layout_t::from_legacy(const ceph_file_layout& fl)
+{
+  stripe_unit = fl.fl_stripe_unit;
+  stripe_count = fl.fl_stripe_count;
+  object_size = fl.fl_object_size;
+  pool_id = (int32_t)fl.fl_pg_pool;
+  // in the legacy encoding, pool 0 was undefined.
+  if (pool_id == 0)
+    pool_id = -1;
+  pool_ns.clear();
+}
+
+void file_layout_t::to_legacy(ceph_file_layout *fl) const
+{
+  fl->fl_stripe_unit = stripe_unit;
+  fl->fl_stripe_count = stripe_count;
+  fl->fl_object_size = object_size;
+  fl->fl_cas_hash = 0;
+  fl->fl_object_stripe_unit = 0;
+  fl->fl_unused = 0;
+  // in the legacy encoding, pool 0 was undefined.
+  if (pool_id >= 0)
+    fl->fl_pg_pool = pool_id;
+  else
+    fl->fl_pg_pool = 0;
+}
+
+void file_layout_t::encode(bufferlist& bl, uint64_t features) const
+{
+  if ((features & CEPH_FEATURE_FS_FILE_LAYOUT_V2) == 0) {
+    ceph_file_layout fl;
+    assert((stripe_unit & 0xff) == 0);  // first byte must be 0
+    to_legacy(&fl);
+    ::encode(fl, bl);
+    return;
+  }
+
+  ENCODE_START(2, 2, bl);
+  ::encode(stripe_unit, bl);
+  ::encode(stripe_count, bl);
+  ::encode(object_size, bl);
+  ::encode(pool_id, bl);
+  ::encode(pool_ns, bl);
+  ENCODE_FINISH(bl);
+}
+
+void file_layout_t::decode(bufferlist::iterator& p)
+{
+  if (*p == 0) {
+    ceph_file_layout fl;
+    ::decode(fl, p);
+    from_legacy(fl);
+    return;
+  }
+  DECODE_START(2, p);
+  ::decode(stripe_unit, p);
+  ::decode(stripe_count, p);
+  ::decode(object_size, p);
+  ::decode(pool_id, p);
+  ::decode(pool_ns, p);
+  DECODE_FINISH(p);
+}
+
+void file_layout_t::dump(Formatter *f) const
+{
+  f->dump_unsigned("stripe_unit", stripe_unit);
+  f->dump_unsigned("stripe_count", stripe_count);
+  f->dump_unsigned("object_size", object_size);
+  f->dump_unsigned("pool_id", pool_id);
+  f->dump_string("pool_ns", pool_ns);
+}
+
+void file_layout_t::generate_test_instances(list<file_layout_t*>& o)
+{
+  o.push_back(new file_layout_t);
+  o.push_back(new file_layout_t);
+  o.back()->stripe_unit = 4096;
+  o.back()->stripe_count = 16;
+  o.back()->object_size = 1048576;
+  o.back()->pool_id = 3;
+  o.back()->pool_ns = "myns";
+}
diff --git a/src/common/hobject.cc b/src/common/hobject.cc
index 9e84219..51403d7 100644
--- a/src/common/hobject.cc
+++ b/src/common/hobject.cc
@@ -384,6 +384,7 @@ int cmp_bitwise(const hobject_t& l, const hobject_t& r)
 // version 5.
 void ghobject_t::encode(bufferlist& bl) const
 {
+  // when changing this, remember to update encoded_size() too.
   ENCODE_START(6, 3, bl);
   ::encode(hobj.key, bl);
   ::encode(hobj.oid, bl);
@@ -398,6 +399,47 @@ void ghobject_t::encode(bufferlist& bl) const
   ENCODE_FINISH(bl);
 }
 
+size_t ghobject_t::encoded_size() const
+{
+  // this is not in order of encoding or appearance, but rather
+  // in order of known constants first, so it can be (mostly) computed
+  // at compile time.
+  //  - encoding header + 3 string lengths
+  size_t r = sizeof(ceph_le32) + 2 * sizeof(__u8) + 3 * sizeof(__u32);
+
+  // hobj.snap
+  r += sizeof(uint64_t);
+
+  // hobj.hash
+  r += sizeof(uint32_t);
+
+  // hobj.max
+  r += sizeof(bool);
+
+  // hobj.pool
+  r += sizeof(uint64_t);
+
+  // hobj.generation
+  r += sizeof(uint64_t);
+
+  // hobj.shard_id
+  r += sizeof(int8_t);
+
+  // max
+  r += sizeof(bool);
+
+  // hobj.key
+  r += hobj.key.size();
+
+  // hobj.oid
+  r += hobj.oid.name.size();
+
+  // hobj.nspace
+  r += hobj.nspace.size();
+
+  return r;
+}
+
 void ghobject_t::decode(bufferlist::iterator& bl)
 {
   DECODE_START_LEGACY_COMPAT_LEN(6, 3, 3, bl);
@@ -499,7 +541,7 @@ ostream& operator<<(ostream& out, const ghobject_t& o)
     return out << "GHMAX";
   if (o.shard_id != shard_id_t::NO_SHARD)
     out << std::hex << o.shard_id << std::dec;
-  out << '@' << o.hobj << '@';
+  out << '#' << o.hobj << '#';
   if (o.generation != ghobject_t::NO_GEN)
     out << std::hex << (unsigned long long)(o.generation) << std::dec;
   return out;
@@ -516,12 +558,12 @@ bool ghobject_t::parse(const string& s)
     return true;
   }
 
-  // look for shard@ prefix
+  // look for shard# prefix
   const char *start = s.c_str();
   const char *p;
   int sh = shard_id_t::NO_SHARD;
   for (p = start; *p && isxdigit(*p); ++p) ;
-  if (!*p && *p != '@')
+  if (!*p && *p != '#')
     return false;
   if (p > start) {
     int r = sscanf(s.c_str(), "%x", &sh);
@@ -532,13 +574,13 @@ bool ghobject_t::parse(const string& s)
     ++start;
   }
 
-  // look for @generation suffix
+  // look for #generation suffix
   long long unsigned g = NO_GEN;
   const char *last = start + strlen(start) - 1;
   p = last;
   while (isxdigit(*p))
     p--;
-  if (*p != '@')
+  if (*p != '#')
     return false;
   if (p < last) {
     sscanf(p + 1, "%llx", &g);
diff --git a/src/common/hobject.h b/src/common/hobject.h
index b823708..0cc96fb 100644
--- a/src/common/hobject.h
+++ b/src/common/hobject.h
@@ -442,6 +442,7 @@ public:
   void encode(bufferlist& bl) const;
   void decode(bufferlist::iterator& bl);
   void decode(json_spirit::Value& v);
+  size_t encoded_size() const;
   void dump(Formatter *f) const;
   static void generate_test_instances(list<ghobject_t*>& o);
   friend int cmp_nibblewise(const ghobject_t& l, const ghobject_t& r);
diff --git a/src/common/mutex_debug.h b/src/common/mutex_debug.h
index c92a88f..75117c6 100644
--- a/src/common/mutex_debug.h
+++ b/src/common/mutex_debug.h
@@ -139,13 +139,22 @@ public:
   mutex_debug_impl(const std::string &n = std::string(), bool bt = false,
 		   CephContext *cct = nullptr) :
     mutex_debugging<mutex_debug_impl<Recursive> >(n, bt, cct) {
+    pthread_mutexattr_t a;
+    pthread_mutexattr_init(&a);
+    int r;
     if (recursive)
-      m = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
+      r = pthread_mutexattr_settype(&a, PTHREAD_MUTEX_RECURSIVE);
     else
-      m = PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP;
+      r = pthread_mutexattr_settype(&a, PTHREAD_MUTEX_ERRORCHECK);
+    assert(r == 0);
+    r = pthread_mutex_init(&m, &a);
+    assert(r == 0);
   }
   // Mutex is Destructible
-  ~mutex_debug_impl() = default;
+  ~mutex_debug_impl() {
+    int r = pthread_mutex_destroy(&m);
+    assert(r == 0);
+  }
 
   // Mutex concept is non-Copyable
   mutex_debug_impl(const mutex_debug_impl&) = delete;
diff --git a/src/common/obj_bencher.cc b/src/common/obj_bencher.cc
index a6dc3e8..9a2215e 100644
--- a/src/common/obj_bencher.cc
+++ b/src/common/obj_bencher.cc
@@ -28,28 +28,43 @@
 #include <sstream>
 #include <vector>
 
-
 const std::string BENCH_LASTRUN_METADATA = "benchmark_last_metadata";
 const std::string BENCH_PREFIX = "benchmark_data";
+static char cached_hostname[30] = {0};
+int cached_pid = 0;
 
 static std::string generate_object_prefix(int pid = 0) {
-  char hostname[30];
-  gethostname(hostname, sizeof(hostname)-1);
-  hostname[sizeof(hostname)-1] = 0;
+  if (cached_hostname[0] == 0) {
+    gethostname(cached_hostname, sizeof(cached_hostname)-1);
+    cached_hostname[sizeof(cached_hostname)-1] = 0;
+  }
 
-  if (!pid)
-    pid = getpid();
+  if (!cached_pid) {
+    if (!pid)
+      pid = getpid();
+    cached_pid = pid;
+  }
 
   std::ostringstream oss;
-  oss << BENCH_PREFIX << "_" << hostname << "_" << pid;
+  oss << BENCH_PREFIX << "_" << cached_hostname << "_" << cached_pid;
   return oss.str();
 }
 
 static std::string generate_object_name(int objnum, int pid = 0)
 {
-  std::ostringstream oss;
-  oss << generate_object_prefix(pid) << "_object" << objnum;
-  return oss.str();
+  if (cached_hostname[0] == 0) {
+    gethostname(cached_hostname, sizeof(cached_hostname)-1);
+    cached_hostname[sizeof(cached_hostname)-1] = 0;
+  }
+  if (!cached_pid) {
+    if (!pid)
+      pid = getpid();
+    cached_pid = pid;
+  }
+
+  char name[1024];
+  size_t l = sprintf(&name[0], "%s_%s_%d_object%d", BENCH_PREFIX.c_str(), cached_hostname, cached_pid, objnum);
+  return string(&name[0], l);
 }
 
 static void sanitize_object_contents (bench_data *data, size_t length) {
@@ -508,7 +523,7 @@ int ObjBencher::write_bench(int secondsToRun,
     ++data.started;
     ++data.in_flight;
     if (max_objects &&
-	data.started > (int)((data.object_size * max_objects + data.op_size - 1) /
+	data.started >= (int)((data.object_size * max_objects + data.op_size - 1) /
 			     data.op_size))
       break;
   }
@@ -553,7 +568,7 @@ int ObjBencher::write_bench(int secondsToRun,
        << "Total writes made:      " << data.finished << std::endl
        << "Write size:             " << data.op_size << std::endl
        << "Object size:            " << data.object_size << std::endl      
-       << "Bandwidth (MB/sec):     " << setprecision(3) << bandwidth << std::endl
+       << "Bandwidth (MB/sec):     " << setprecision(6) << bandwidth << std::endl
        << "Stddev Bandwidth:       " << vec_stddev(data.history.bandwidth) << std::endl
        << "Max bandwidth (MB/sec): " << data.idata.max_bandwidth << std::endl
        << "Min bandwidth (MB/sec): " << data.idata.min_bandwidth << std::endl
@@ -802,7 +817,7 @@ int ObjBencher::seq_read_bench(int seconds_to_run, int num_objects, int concurre
        << "Total reads made:     " << data.finished << std::endl
        << "Read size:            " << data.op_size << std::endl
        << "Object size:          " << data.object_size << std::endl
-       << "Bandwidth (MB/sec):   " << setprecision(3) << bandwidth << std::endl
+       << "Bandwidth (MB/sec):   " << setprecision(6) << bandwidth << std::endl
        << "Average IOPS          " << (int)(data.finished/runtime) << std::endl
        << "Stddev IOPS:          " << vec_stddev(data.history.iops) << std::endl
        << "Max IOPS:             " << data.idata.max_iops << std::endl
@@ -827,7 +842,7 @@ int ObjBencher::seq_read_bench(int seconds_to_run, int num_objects, int concurre
 
   completions_done();
 
-  return 0;
+  return (errors > 0 ? -EIO : 0);
 
  ERR:
   lock.Lock();
@@ -1035,7 +1050,7 @@ int ObjBencher::rand_read_bench(int seconds_to_run, int num_objects, int concurr
        << "Total reads made:     " << data.finished << std::endl
        << "Read size:            " << data.op_size << std::endl
        << "Object size:          " << data.object_size << std::endl
-       << "Bandwidth (MB/sec):   " << setprecision(3) << bandwidth << std::endl
+       << "Bandwidth (MB/sec):   " << setprecision(6) << bandwidth << std::endl
        << "Average IOPS:         " << (int)(data.finished/runtime) << std::endl
        << "Stddev IOPS:          " << vec_stddev(data.history.iops) << std::endl
        << "Max IOPS:             " << data.idata.max_iops << std::endl
@@ -1059,7 +1074,7 @@ int ObjBencher::rand_read_bench(int seconds_to_run, int num_objects, int concurr
   }
   completions_done();
 
-  return 0;
+  return (errors > 0 ? -EIO : 0);
 
  ERR:
   lock.Lock();
@@ -1411,5 +1426,5 @@ int ObjBencher::clean_up_slow(const std::string& prefix, int concurrentios) {
   lock.Lock();
   data.done = 1;
   lock.Unlock();
-  return -5;
+  return -EIO;
 }
diff --git a/src/common/page.cc b/src/common/page.cc
index 6ba4215..7a252a6 100644
--- a/src/common/page.cc
+++ b/src/common/page.cc
@@ -14,6 +14,6 @@ namespace ceph {
 
   unsigned _page_size = sysconf(_SC_PAGESIZE);
   unsigned long _page_mask = ~(unsigned long)(_page_size - 1);
-  unsigned _page_shift = _get_bits_of(_page_size);
+  unsigned _page_shift = _get_bits_of(_page_size - 1);
 
 }
diff --git a/src/common/scrub_types.cc b/src/common/scrub_types.cc
new file mode 100644
index 0000000..3342a49
--- /dev/null
+++ b/src/common/scrub_types.cc
@@ -0,0 +1,248 @@
+#include "scrub_types.h"
+
+using namespace librados;
+
+void object_id_wrapper::encode(bufferlist& bl) const
+{
+  ENCODE_START(1, 1, bl);
+  ::encode(name, bl);
+  ::encode(nspace, bl);
+  ::encode(locator, bl);
+  ::encode(snap, bl);
+  ENCODE_FINISH(bl);
+}
+
+void object_id_wrapper::decode(bufferlist::iterator& bp)
+{
+  DECODE_START(1, bp);
+  ::decode(name, bp);
+  ::decode(nspace, bp);
+  ::decode(locator, bp);
+  ::decode(snap, bp);
+  DECODE_FINISH(bp);
+}
+
+static void encode(const object_id_t& obj, bufferlist& bl)
+{
+  reinterpret_cast<const object_id_wrapper&>(obj).encode(bl);
+}
+
+void shard_info_wrapper::set_object(const ScrubMap::object& object)
+{
+  for (auto attr : object.attrs) {
+    bufferlist bl;
+    bl.push_back(attr.second);
+    attrs.insert(std::make_pair(attr.first, std::move(bl)));
+  }
+  size = object.size;
+  if (object.omap_digest_present) {
+    omap_digest_present = true;
+    omap_digest = object.omap_digest;
+  }
+  if (object.digest_present) {
+    data_digest_present = true;
+    data_digest = object.digest;
+  }
+  if (object.read_error) {
+    errors |= SHARD_READ_ERR;
+  }
+  if (object.stat_error) {
+    errors |= SHARD_STAT_ERR;
+  }
+}
+
+void shard_info_wrapper::encode(bufferlist& bl) const
+{
+  ENCODE_START(1, 1, bl);
+  ::encode(errors, bl);
+  if (has_shard_missing()) {
+    return;
+  }
+  ::encode(attrs, bl);
+  ::encode(size, bl);
+  ::encode(omap_digest_present, bl);
+  ::encode(omap_digest, bl);
+  ::encode(data_digest_present, bl);
+  ::encode(data_digest, bl);
+  ENCODE_FINISH(bl);
+}
+
+void shard_info_wrapper::decode(bufferlist::iterator& bp)
+{
+  DECODE_START(1, bp);
+  ::decode(errors, bp);
+  if (has_shard_missing()) {
+    return;
+  }
+  ::decode(attrs, bp);
+  ::decode(size, bp);
+  ::decode(omap_digest_present, bp);
+  ::decode(omap_digest, bp);
+  ::decode(data_digest_present, bp);
+  ::decode(data_digest, bp);
+  DECODE_FINISH(bp);
+}
+
+inconsistent_obj_wrapper::inconsistent_obj_wrapper(const hobject_t& hoid)
+  : inconsistent_obj_t{librados::object_id_t{hoid.oid.name,
+                                 hoid.nspace,
+                                 hoid.get_key(), hoid.snap}}
+{}
+
+void inconsistent_obj_wrapper::add_shard(const pg_shard_t& pgs,
+                                         const shard_info_wrapper& shard)
+{
+  errors |= shard.errors;
+  shards[pgs.osd] = shard;
+}
+
+void
+inconsistent_obj_wrapper::set_auth_missing(const hobject_t& hoid,
+                                           const map<pg_shard_t, ScrubMap*>& maps)
+{
+  errors |= (err_t::SHARD_MISSING |
+             err_t::SHARD_READ_ERR |
+             err_t::OMAP_DIGEST_MISMATCH |
+             err_t::DATA_DIGEST_MISMATCH |
+             err_t::ATTR_MISMATCH);
+  for (auto pg_map : maps) {
+    auto oid_object = pg_map.second->objects.find(hoid);
+    shard_info_wrapper shard;
+    if (oid_object == pg_map.second->objects.end()) {
+      shard.set_missing();
+    } else {
+      shard.set_object(oid_object->second);
+    }
+      shards[pg_map.first.osd] = shard;
+  }
+}
+
+namespace librados {
+  static void encode(const shard_info_t& shard, bufferlist& bl)
+  {
+    reinterpret_cast<const shard_info_wrapper&>(shard).encode(bl);
+  }
+}
+
+void inconsistent_obj_wrapper::encode(bufferlist& bl) const
+{
+  ENCODE_START(1, 1, bl);
+  ::encode(errors, bl);
+  ::encode(object, bl);
+  ::encode(shards, bl);
+  ENCODE_FINISH(bl);
+}
+
+void inconsistent_obj_wrapper::decode(bufferlist::iterator& bp)
+{
+  DECODE_START(1, bp);
+  ::decode(errors, bp);
+  ::decode(object, bp);
+  ::decode(shards, bp);
+  DECODE_FINISH(bp);
+}
+
+inconsistent_snapset_wrapper::inconsistent_snapset_wrapper(const hobject_t& hoid)
+  : inconsistent_snapset_t{object_id_t{hoid.oid.name,
+                                       hoid.nspace,
+                                       hoid.get_key(),
+                                       hoid.snap}}
+{}
+
+using inc_snapset_t = inconsistent_snapset_t;
+
+void inconsistent_snapset_wrapper::set_headless()
+{
+  errors |= inc_snapset_t::HEADLESS_CLONE;
+}
+
+void inconsistent_snapset_wrapper::set_ss_attr_missing()
+{
+  errors |= inc_snapset_t::ATTR_MISSING;
+}
+
+void inconsistent_snapset_wrapper::set_ss_attr_corrupted()
+{
+  errors |= inc_snapset_t::ATTR_CORRUPTED;
+}
+
+void inconsistent_snapset_wrapper::set_clone_missing(snapid_t snap)
+{
+  errors |= inc_snapset_t::CLONE_MISSING;
+  missing.push_back(snap);
+}
+
+void inconsistent_snapset_wrapper::set_snapset_mismatch()
+{
+  errors |= inc_snapset_t::SNAP_MISMATCH;
+}
+
+void inconsistent_snapset_wrapper::set_head_mismatch()
+{
+  errors |= inc_snapset_t::HEAD_MISMATCH;
+}
+
+void inconsistent_snapset_wrapper::set_size_mismatch()
+{
+  errors |= inc_snapset_t::SIZE_MISMATCH;
+}
+
+void inconsistent_snapset_wrapper::encode(bufferlist& bl) const
+{
+  ENCODE_START(1, 1, bl);
+  ::encode(errors, bl);
+  ::encode(object, bl);
+  ::encode(clones, bl);
+  ::encode(missing, bl);
+  ENCODE_FINISH(bl);
+}
+
+void inconsistent_snapset_wrapper::decode(bufferlist::iterator& bp)
+{
+  DECODE_START(1, bp);
+  ::decode(errors, bp);
+  ::decode(object, bp);
+  ::decode(clones, bp);
+  ::decode(missing, bp);
+  DECODE_FINISH(bp);
+}
+
+void scrub_ls_arg_t::encode(bufferlist& bl) const
+{
+  ENCODE_START(1, 1, bl);
+  ::encode(interval, bl);
+  ::encode(get_snapsets, bl);
+  ::encode(start_after.name, bl);
+  ::encode(start_after.nspace, bl);
+  ::encode(start_after.snap, bl);
+  ::encode(max_return, bl);
+  ENCODE_FINISH(bl);
+}
+
+void scrub_ls_arg_t::decode(bufferlist::iterator& bp)
+{
+  DECODE_START(1, bp);
+  ::decode(interval, bp);
+  ::decode(get_snapsets, bp);
+  ::decode(start_after.name, bp);
+  ::decode(start_after.nspace, bp);
+  ::decode(start_after.snap, bp);
+  ::decode(max_return, bp);
+  DECODE_FINISH(bp);
+}
+
+void scrub_ls_result_t::encode(bufferlist& bl) const
+{
+  ENCODE_START(1, 1, bl);
+  ::encode(interval, bl);
+  ::encode(vals, bl);
+  ENCODE_FINISH(bl);
+}
+
+void scrub_ls_result_t::decode(bufferlist::iterator& bp)
+{
+  DECODE_START(1, bp);
+  ::decode(interval, bp);
+  ::decode(vals, bp);
+  DECODE_FINISH(bp);
+}
diff --git a/src/common/scrub_types.h b/src/common/scrub_types.h
new file mode 100644
index 0000000..c9f4fda
--- /dev/null
+++ b/src/common/scrub_types.h
@@ -0,0 +1,141 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+
+#ifndef CEPH_SCRUB_TYPES_H
+#define CEPH_SCRUB_TYPES_H
+
+#include "include/rados/rados_types.hpp"
+#include "common/hobject.h"
+#include "osd/osd_types.h"
+
+
+// wrappers around scrub types to offer the necessary bits other than
+// the minimal set that the lirados requires
+struct object_id_wrapper : public librados::object_id_t {
+  object_id_wrapper(const hobject_t& hoid)
+    : object_id_t{hoid.oid.name, hoid.nspace, hoid.get_key(), hoid.snap}
+  {}
+  void encode(bufferlist& bl) const;
+  void decode(bufferlist::iterator& bl);
+};
+
+WRITE_CLASS_ENCODER(object_id_wrapper)
+
+inline void decode(librados::object_id_t& obj, bufferlist::iterator& bp) {
+  reinterpret_cast<object_id_wrapper&>(obj).decode(bp);
+}
+
+struct shard_info_wrapper : public librados::shard_info_t {
+public:
+  shard_info_wrapper() = default;
+  shard_info_wrapper(const ScrubMap::object& object) {
+    set_object(object);
+  }
+  void set_object(const ScrubMap::object& object);
+  void set_missing() {
+    errors |= err_t::SHARD_MISSING;
+  }
+  void set_omap_digest_mismatch() {
+    errors |= err_t::OMAP_DIGEST_MISMATCH;
+  }
+  void set_omap_digest_mismatch_oi() {
+    errors |= err_t::OMAP_DIGEST_MISMATCH_OI;
+  }
+  void set_data_digest_mismatch() {
+    errors |= err_t::DATA_DIGEST_MISMATCH;
+  }
+  void set_data_digest_mismatch_oi() {
+    errors |= err_t::DATA_DIGEST_MISMATCH_OI;
+  }
+  void set_size_mismatch() {
+    errors |= err_t::SIZE_MISMATCH;
+  }
+  void set_attr_missing() {
+    errors |= err_t::ATTR_MISMATCH;
+  }
+  void set_attr_mismatch() {
+    errors |= err_t::ATTR_MISMATCH;
+  }
+  void set_attr_unexpected() {
+    errors |= err_t::ATTR_MISMATCH;
+  }
+  void encode(bufferlist& bl) const;
+  void decode(bufferlist::iterator& bp);
+};
+
+WRITE_CLASS_ENCODER(shard_info_wrapper)
+
+namespace librados {
+  inline void decode(librados::shard_info_t& shard,
+		     bufferlist::iterator& bp) {
+    reinterpret_cast<shard_info_wrapper&>(shard).decode(bp);
+  }
+}
+
+struct inconsistent_obj_wrapper : librados::inconsistent_obj_t {
+  inconsistent_obj_wrapper(const hobject_t& hoid);
+
+  void add_shard(const pg_shard_t& pgs, const shard_info_wrapper& shard);
+  void set_auth_missing(const hobject_t& hoid,
+                        const map<pg_shard_t, ScrubMap*>& map);
+  void encode(bufferlist& bl) const;
+  void decode(bufferlist::iterator& bp);
+};
+
+WRITE_CLASS_ENCODER(inconsistent_obj_wrapper)
+
+inline void decode(librados::inconsistent_obj_t& obj,
+		   bufferlist::iterator& bp) {
+  reinterpret_cast<inconsistent_obj_wrapper&>(obj).decode(bp);
+}
+
+struct inconsistent_snapset_wrapper : public librados::inconsistent_snapset_t {
+  inconsistent_snapset_wrapper() = default;
+  inconsistent_snapset_wrapper(const hobject_t& head);
+  void set_headless();
+  // soid claims that it is a head or a snapdir, but its SS_ATTR
+  // is missing.
+  void set_ss_attr_missing();
+  void set_ss_attr_corrupted();
+  // snapset with missing clone
+  void set_clone_missing(snapid_t);
+  // the snapset is not consistent with itself
+  void set_snapset_mismatch();
+  // soid.snap inconsistent with snapset
+  void set_head_mismatch();
+  void set_size_mismatch();
+
+  void encode(bufferlist& bl) const;
+  void decode(bufferlist::iterator& bp);
+};
+
+WRITE_CLASS_ENCODER(inconsistent_snapset_wrapper)
+
+namespace librados {
+  inline void decode(librados::inconsistent_snapset_t& snapset,
+		     bufferlist::iterator& bp) {
+    reinterpret_cast<inconsistent_snapset_wrapper&>(snapset).decode(bp);
+  }
+}
+
+struct scrub_ls_arg_t {
+  uint32_t interval;
+  uint32_t get_snapsets;
+  librados::object_id_t start_after;
+  uint64_t max_return;
+  void encode(bufferlist& bl) const;
+  void decode(bufferlist::iterator& bl);
+};
+
+WRITE_CLASS_ENCODER(scrub_ls_arg_t);
+
+struct scrub_ls_result_t {
+  epoch_t interval;
+  std::vector<bufferlist> vals;
+  void encode(bufferlist& bl) const;
+  void decode(bufferlist::iterator& bl);
+};
+
+WRITE_CLASS_ENCODER(scrub_ls_result_t);
+
+#endif
diff --git a/src/common/snap_types.h b/src/common/snap_types.h
index 76d5c53..af0d025 100644
--- a/src/common/snap_types.h
+++ b/src/common/snap_types.h
@@ -2,6 +2,7 @@
 #define __CEPH_SNAP_TYPES_H
 
 #include "include/types.h"
+#include "include/fs_types.h"
 
 namespace ceph {
 
diff --git a/src/common/sstring.hh b/src/common/sstring.hh
new file mode 100644
index 0000000..8d2c92c
--- /dev/null
+++ b/src/common/sstring.hh
@@ -0,0 +1,669 @@
+/*
+ * This file is open source software, licensed to you under the terms
+ * of the Apache License, Version 2.0 (the "License").  See the NOTICE file
+ * distributed with this work for additional information regarding copyright
+ * ownership.  You may not use this file except in compliance with the License.
+ *
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+/*
+ * Copyright 2014 Cloudius Systems
+ */
+/*
+ * C++2014 dependencies removed.  Uses of std::string_view adapted to
+ * boost::string_ref.  Matt Benjamin <mbenjamin at redhat.com>
+ */
+
+#ifndef SSTRING_HH_
+#define SSTRING_HH_
+
+#include <stdint.h>
+#include <algorithm>
+#include <string>
+#include <cstring>
+#include <stdexcept>
+#include <initializer_list>
+#include <iostream>
+#include <functional>
+#include <cstdio>
+#include <type_traits>
+#include <boost/utility/string_ref.hpp>
+
+template <typename char_type, typename Size, Size max_size>
+class basic_sstring;
+
+using sstring = basic_sstring<char, uint32_t, 15>;
+
+template <typename string_type = sstring, typename T>
+inline string_type to_sstring(T value);
+
+template <typename char_type, typename Size, Size max_size>
+class basic_sstring {
+    static_assert(
+            (std::is_same<char_type, char>::value
+             || std::is_same<char_type, signed char>::value
+             || std::is_same<char_type, unsigned char>::value),
+            "basic_sstring only supports single byte char types");
+    union contents {
+        struct external_type {
+            char_type* str;
+            Size size;
+            int8_t pad;
+        } external;
+        struct internal_type {
+            char_type str[max_size];
+            int8_t size;
+        } internal;
+        static_assert(sizeof(external_type) <= sizeof(internal_type), "max_size too small");
+        static_assert(max_size <= 127, "max_size too large");
+    } u;
+    bool is_internal() const noexcept {
+        return u.internal.size >= 0;
+    }
+    bool is_external() const noexcept {
+        return !is_internal();
+    }
+    const char_type* str() const {
+        return is_internal() ? u.internal.str : u.external.str;
+    }
+    char_type* str() {
+        return is_internal() ? u.internal.str : u.external.str;
+    }
+
+    template <typename string_type, typename T>
+    static inline string_type to_sstring_sprintf(T value, const char* fmt) {
+        char tmp[sizeof(value) * 3 + 2];
+        auto len = std::sprintf(tmp, fmt, value);
+        using ch_type = typename string_type::value_type;
+        return string_type(reinterpret_cast<ch_type*>(tmp), len);
+    }
+
+    template <typename string_type>
+    static inline string_type to_sstring(int value) {
+        return to_sstring_sprintf<string_type>(value, "%d");
+    }
+
+    template <typename string_type>
+    static inline string_type to_sstring(unsigned value) {
+        return to_sstring_sprintf<string_type>(value, "%u");
+    }
+
+    template <typename string_type>
+    static inline string_type to_sstring(long value) {
+        return to_sstring_sprintf<string_type>(value, "%ld");
+    }
+
+    template <typename string_type>
+    static inline string_type to_sstring(unsigned long value) {
+        return to_sstring_sprintf<string_type>(value, "%lu");
+    }
+
+    template <typename string_type>
+    static inline string_type to_sstring(long long value) {
+        return to_sstring_sprintf<string_type>(value, "%lld");
+    }
+
+    template <typename string_type>
+    static inline string_type to_sstring(unsigned long long value) {
+        return to_sstring_sprintf<string_type>(value, "%llu");
+    }
+
+    template <typename string_type>
+    static inline string_type to_sstring(float value) {
+        return to_sstring_sprintf<string_type>(value, "%g");
+    }
+
+    template <typename string_type>
+    static inline string_type to_sstring(double value) {
+        return to_sstring_sprintf<string_type>(value, "%g");
+    }
+
+    template <typename string_type>
+    static inline string_type to_sstring(long double value) {
+        return to_sstring_sprintf<string_type>(value, "%Lg");
+    }
+
+    template <typename string_type>
+    static inline string_type to_sstring(const char* value) {
+        return string_type(value);
+    }
+
+    template <typename string_type>
+    static inline string_type to_sstring(sstring value) {
+        return value;
+    }
+
+public:
+    using value_type = char_type;
+    using traits_type = std::char_traits<char_type>;
+    using allocator_type = std::allocator<char_type>;
+    using reference = char_type&;
+    using const_reference = const char_type&;
+    using pointer = char_type*;
+    using const_pointer = const char_type*;
+    using iterator = char_type*;
+    using const_iterator = const char_type*;
+    // FIXME: add reverse_iterator and friend
+    using difference_type = ssize_t;  // std::make_signed_t<Size> can be too small
+    using size_type = Size;
+    static constexpr size_type  npos = static_cast<size_type>(-1);
+public:
+    struct initialized_later {};
+
+    basic_sstring() noexcept {
+        u.internal.size = 0;
+        u.internal.str[0] = '\0';
+    }
+    basic_sstring(const basic_sstring& x) {
+        if (x.is_internal()) {
+            u.internal = x.u.internal;
+        } else {
+            u.internal.size = -1;
+            u.external.str = reinterpret_cast<char_type*>(std::malloc(x.u.external.size + 1));
+            if (!u.external.str) {
+                throw std::bad_alloc();
+            }
+            std::copy(x.u.external.str, x.u.external.str + x.u.external.size + 1, u.external.str);
+            u.external.size = x.u.external.size;
+        }
+    }
+    basic_sstring(basic_sstring&& x) noexcept {
+        u = x.u;
+        x.u.internal.size = 0;
+        x.u.internal.str[0] = '\0';
+    }
+    basic_sstring(initialized_later, size_t size) {
+        if (size_type(size) != size) {
+            throw std::overflow_error("sstring overflow");
+        }
+        if (size + 1 <= sizeof(u.internal.str)) {
+            u.internal.str[size] = '\0';
+            u.internal.size = size;
+        } else {
+            u.internal.size = -1;
+            u.external.str = reinterpret_cast<char_type*>(std::malloc(size + 1));
+            if (!u.external.str) {
+                throw std::bad_alloc();
+            }
+            u.external.size = size;
+            u.external.str[size] = '\0';
+        }
+    }
+    basic_sstring(const char_type* x, size_t size) {
+        if (size_type(size) != size) {
+            throw std::overflow_error("sstring overflow");
+        }
+        if (size + 1 <= sizeof(u.internal.str)) {
+            std::copy(x, x + size, u.internal.str);
+            u.internal.str[size] = '\0';
+            u.internal.size = size;
+        } else {
+            u.internal.size = -1;
+            u.external.str = reinterpret_cast<char_type*>(std::malloc(size + 1));
+            if (!u.external.str) {
+                throw std::bad_alloc();
+            }
+            u.external.size = size;
+            std::copy(x, x + size, u.external.str);
+            u.external.str[size] = '\0';
+        }
+    }
+
+    basic_sstring(size_t size, char_type x) : basic_sstring(initialized_later(), size) {
+        memset(begin(), x, size);
+    }
+
+    basic_sstring(const char* x) : basic_sstring(reinterpret_cast<const char_type*>(x), std::strlen(x)) {}
+    basic_sstring(std::basic_string<char_type>& x) : basic_sstring(x.c_str(), x.size()) {}
+    basic_sstring(std::initializer_list<char_type> x) : basic_sstring(x.begin(), x.end() - x.begin()) {}
+    basic_sstring(const char_type* b, const char_type* e) : basic_sstring(b, e - b) {}
+    basic_sstring(const std::basic_string<char_type>& s)
+        : basic_sstring(s.data(), s.size()) {}
+    template <typename InputIterator>
+    basic_sstring(InputIterator first, InputIterator last)
+            : basic_sstring(initialized_later(), std::distance(first, last)) {
+        std::copy(first, last, begin());
+    }
+    ~basic_sstring() noexcept {
+        if (is_external()) {
+            std::free(u.external.str);
+        }
+    }
+    basic_sstring& operator=(const basic_sstring& x) {
+        basic_sstring tmp(x);
+        swap(tmp);
+        return *this;
+    }
+    basic_sstring& operator=(basic_sstring&& x) noexcept {
+        if (this != &x) {
+            swap(x);
+            x.reset();
+        }
+        return *this;
+    }
+    operator std::basic_string<char_type>() const {
+        return { str(), size() };
+    }
+    size_t size() const noexcept {
+        return is_internal() ? u.internal.size : u.external.size;
+    }
+
+    size_t length() const noexcept {
+        return size();
+    }
+
+    size_t find(char_type t, size_t pos = 0) const noexcept {
+        const char_type* it = str() + pos;
+        const char_type* end = str() + size();
+        while (it < end) {
+            if (*it == t) {
+                return it - str();
+            }
+            it++;
+        }
+        return npos;
+    }
+
+    size_t find(const basic_sstring& s, size_t pos = 0) const noexcept {
+        const char_type* it = str() + pos;
+        const char_type* end = str() + size();
+        const char_type* c_str = s.str();
+        const char_type* c_str_end = s.str() + s.size();
+
+        while (it < end) {
+            auto i = it;
+            auto j = c_str;
+            while ( i < end && j < c_str_end && *i == *j) {
+                i++;
+                j++;
+            }
+            if (j == c_str_end) {
+                return it - str();
+            }
+            it++;
+        }
+        return npos;
+    }
+
+    /**
+     * find_last_of find the last occurrence of c in the string.
+     * When pos is specified, the search only includes characters
+     * at or before position pos.
+     *
+     */
+    size_t find_last_of (char_type c, size_t pos = npos) const noexcept {
+        const char_type* str_start = str();
+        if (size()) {
+            if (pos >= size()) {
+                pos = size() - 1;
+            }
+            const char_type* p = str_start + pos + 1;
+            do {
+                p--;
+                if (*p == c) {
+                    return (p - str_start);
+                }
+            } while (p != str_start);
+        }
+        return npos;
+    }
+
+    /**
+     *  Append a C substring.
+     *  @param s  The C string to append.
+     *  @param n  The number of characters to append.
+     *  @return  Reference to this string.
+     */
+    basic_sstring& append (const char_type* s, size_t n) {
+        basic_sstring ret(initialized_later(), size() + n);
+        std::copy(begin(), end(), ret.begin());
+        std::copy(s, s + n, ret.begin() + size());
+        *this = std::move(ret);
+        return *this;
+    }
+
+    /**
+     *  Replace characters with a value of a C style substring.
+     *
+     */
+    basic_sstring& replace(size_type pos, size_type n1, const char_type* s,
+             size_type n2) {
+        if (pos > size()) {
+            throw std::out_of_range("sstring::replace out of range");
+        }
+
+        if (n1 > size() - pos) {
+            n1 = size() - pos;
+        }
+
+        if (n1 == n2) {
+            if (n2) {
+                std::copy(s, s + n2, begin() + pos);
+            }
+            return *this;
+        }
+        basic_sstring ret(initialized_later(), size() + n2 - n1);
+        char_type* p= ret.begin();
+        std::copy(begin(), begin() + pos, p);
+        p += pos;
+        if (n2) {
+            std::copy(s, s + n2, p);
+        }
+        p += n2;
+        std::copy(begin() + pos + n1, end(), p);
+        *this = std::move(ret);
+        return *this;
+    }
+
+    template <class InputIterator>
+    basic_sstring& replace (const_iterator i1, const_iterator i2,
+            InputIterator first, InputIterator last) {
+        if (i1 < begin() || i1 > end() || i2 < begin()) {
+            throw std::out_of_range("sstring::replace out of range");
+        }
+        if (i2 > end()) {
+            i2 = end();
+        }
+
+        if (i2 - i1 == last - first) {
+            //in place replacement
+            std::copy(first, last, const_cast<char_type*>(i1));
+            return *this;
+        }
+        basic_sstring ret(initialized_later(), size() + (last - first) - (i2 - i1));
+        char_type* p = ret.begin();
+        p = std::copy(cbegin(), i1, p);
+        p = std::copy(first, last, p);
+        std::copy(i2, cend(), p);
+        *this = std::move(ret);
+        return *this;
+    }
+
+    iterator erase(iterator first, iterator last) {
+        size_t pos = first - begin();
+        replace(pos, last - first, nullptr, 0);
+        return begin() + pos;
+    }
+
+    /**
+     * Inserts additional characters into the string right before
+     * the character indicated by p.
+     */
+    template <class InputIterator>
+    void insert(const_iterator p, InputIterator beg, InputIterator end) {
+        replace(p, p, beg, end);
+    }
+
+    /**
+     *  Returns a read/write reference to the data at the last
+     *  element of the string.
+     *  This function shall not be called on empty strings.
+     */
+    reference
+    back() noexcept {
+        return operator[](size() - 1);
+    }
+
+    /**
+     *  Returns a  read-only (constant) reference to the data at the last
+     *  element of the string.
+     *  This function shall not be called on empty strings.
+     */
+    const_reference
+    back() const noexcept {
+        return operator[](size() - 1);
+    }
+
+    basic_sstring substr(size_t from, size_t len = npos)  const {
+        if (from > size()) {
+            throw std::out_of_range("sstring::substr out of range");
+        }
+        if (len > size() - from) {
+            len = size() - from;
+        }
+        if (len == 0) {
+            return "";
+        }
+        return { str() + from , len };
+    }
+
+    const char_type& at(size_t pos) const {
+        if (pos >= size()) {
+            throw std::out_of_range("sstring::at out of range");
+        }
+        return *(str() + pos);
+    }
+
+    char_type& at(size_t pos) {
+        if (pos >= size()) {
+            throw std::out_of_range("sstring::at out of range");
+        }
+        return *(str() + pos);
+    }
+
+    bool empty() const noexcept {
+        return u.internal.size == 0;
+    }
+    void reset() noexcept {
+        if (is_external()) {
+            std::free(u.external.str);
+        }
+        u.internal.size = 0;
+        u.internal.str[0] = '\0';
+    }
+
+    int compare(const basic_sstring& x) const noexcept {
+        auto n = traits_type::compare(begin(), x.begin(), std::min(size(), x.size()));
+        if (n != 0) {
+            return n;
+        }
+        if (size() < x.size()) {
+            return -1;
+        } else if (size() > x.size()) {
+            return 1;
+        } else {
+            return 0;
+        }
+    }
+
+    int compare(size_t pos, size_t sz, const basic_sstring& x) const {
+        if (pos > size()) {
+            throw std::out_of_range("pos larger than string size");
+        }
+
+        sz = std::min(size() - pos, sz);
+        auto n = traits_type::compare(begin() + pos, x.begin(), std::min(sz, x.size()));
+        if (n != 0) {
+            return n;
+        }
+        if (sz < x.size()) {
+            return -1;
+        } else if (sz > x.size()) {
+            return 1;
+        } else {
+            return 0;
+        }
+    }
+
+    void swap(basic_sstring& x) noexcept {
+        contents tmp;
+        tmp = x.u;
+        x.u = u;
+        u = tmp;
+    }
+    const char_type* c_str() const {
+        return str();
+    }
+    const char_type* begin() const { return str(); }
+    const char_type* end() const { return str() + size(); }
+    const char_type* cbegin() const { return str(); }
+    const char_type* cend() const { return str() + size(); }
+    char_type* begin() { return str(); }
+    char_type* end() { return str() + size(); }
+    bool operator==(const basic_sstring& x) const {
+        return size() == x.size() && std::equal(begin(), end(), x.begin());
+    }
+    bool operator!=(const basic_sstring& x) const {
+        return !operator==(x);
+    }
+    bool operator<(const basic_sstring& x) const {
+        return compare(x) < 0;
+    }
+    basic_sstring operator+(const basic_sstring& x) const {
+        basic_sstring ret(initialized_later(), size() + x.size());
+        std::copy(begin(), end(), ret.begin());
+        std::copy(x.begin(), x.end(), ret.begin() + size());
+        return ret;
+    }
+    basic_sstring& operator+=(const basic_sstring& x) {
+        return *this = *this + x;
+    }
+    char_type& operator[](size_type pos) {
+        return str()[pos];
+    }
+    const char_type& operator[](size_type pos) const {
+        return str()[pos];
+    }
+    operator boost::basic_string_ref<char_type, traits_type>() const {
+		return boost::basic_string_ref<char_type, traits_type>(str(), size());
+    }
+    template <typename string_type, typename T>
+    friend inline string_type to_sstring(T value);
+};
+template <typename char_type, typename Size, Size max_size>
+constexpr Size basic_sstring<char_type, Size, max_size>::npos;
+
+template <typename char_type, typename size_type, size_type Max, size_type N>
+inline
+basic_sstring<char_type, size_type, Max>
+operator+(const char(&s)[N], const basic_sstring<char_type, size_type, Max>& t) {
+    using sstring = basic_sstring<char_type, size_type, Max>;
+    // don't copy the terminating NUL character
+    sstring ret(typename sstring::initialized_later(), N-1 + t.size());
+    auto p = std::copy(std::begin(s), std::end(s)-1, ret.begin());
+    std::copy(t.begin(), t.end(), p);
+    return ret;
+}
+
+template <size_t N>
+static inline
+size_t str_len(const char(&s)[N]) { return N - 1; }
+
+template <size_t N>
+static inline
+const char* str_begin(const char(&s)[N]) { return s; }
+
+template <size_t N>
+static inline
+const char* str_end(const char(&s)[N]) { return str_begin(s) + str_len(s); }
+
+template <typename char_type, typename size_type, size_type max_size>
+static inline
+const char_type* str_begin(const basic_sstring<char_type, size_type, max_size>& s) { return s.begin(); }
+
+template <typename char_type, typename size_type, size_type max_size>
+static inline
+const char_type* str_end(const basic_sstring<char_type, size_type, max_size>& s) { return s.end(); }
+
+template <typename char_type, typename size_type, size_type max_size>
+static inline
+size_type str_len(const basic_sstring<char_type, size_type, max_size>& s) { return s.size(); }
+
+template <typename First, typename Second, typename... Tail>
+static inline
+size_t str_len(const First& first, const Second& second, const Tail&... tail) {
+    return str_len(first) + str_len(second, tail...);
+}
+
+template <typename char_type, typename size_type, size_type max_size>
+inline
+void swap(basic_sstring<char_type, size_type, max_size>& x,
+          basic_sstring<char_type, size_type, max_size>& y) noexcept
+{
+    return x.swap(y);
+}
+
+template <typename char_type, typename size_type, size_type max_size, typename char_traits>
+inline
+std::basic_ostream<char_type, char_traits>&
+operator<<(std::basic_ostream<char_type, char_traits>& os,
+        const basic_sstring<char_type, size_type, max_size>& s) {
+    return os.write(s.begin(), s.size());
+}
+
+template <typename char_type, typename size_type, size_type max_size, typename char_traits>
+inline
+std::basic_istream<char_type, char_traits>&
+operator>>(std::basic_istream<char_type, char_traits>& is,
+        basic_sstring<char_type, size_type, max_size>& s) {
+    std::string tmp;
+    is >> tmp;
+    s = tmp;
+    return is;
+}
+
+namespace std {
+
+template <typename char_type, typename size_type, size_type max_size>
+struct hash<basic_sstring<char_type, size_type, max_size>> {
+    size_t operator()(const basic_sstring<char_type, size_type, max_size>& s) const {
+		using traits_type = std::char_traits<char_type>;
+		return std::hash<boost::basic_string_ref<char_type,traits_type>>()(s);
+    }
+};
+
+}
+
+static inline
+char* copy_str_to(char* dst) {
+    return dst;
+}
+
+template <typename Head, typename... Tail>
+static inline
+char* copy_str_to(char* dst, const Head& head, const Tail&... tail) {
+    return copy_str_to(std::copy(str_begin(head), str_end(head), dst), tail...);
+}
+
+template <typename String = sstring, typename... Args>
+static String make_sstring(Args&&... args)
+{
+    String ret(sstring::initialized_later(), str_len(args...));
+    copy_str_to(ret.begin(), args...);
+    return ret;
+}
+
+template <typename string_type, typename T>
+inline string_type to_sstring(T value) {
+    return sstring::to_sstring<string_type>(value);
+}
+
+#if 0 /* XXX conflicts w/Ceph types.h */
+template <typename T>
+inline
+std::ostream& operator<<(std::ostream& os, const std::vector<T>& v) {
+    bool first = true;
+    os << "{";
+    for (auto&& elem : v) {
+        if (!first) {
+            os << ", ";
+        } else {
+            first = false;
+        }
+        os << elem;
+    }
+    os << "}";
+    return os;
+}
+#endif
+
+#endif /* SSTRING_HH_ */
diff --git a/src/common/strtol.cc b/src/common/strtol.cc
index fdab2cf..50598b9 100644
--- a/src/common/strtol.cc
+++ b/src/common/strtol.cc
@@ -166,14 +166,21 @@ T strict_si_cast(const char *str, std::string *err)
     *err = "strict_sistrtoll: value should not be negative";
     return 0;
   }
-  if (ll < (long long)std::numeric_limits<T>::min() >> m) {
+  if (static_cast<unsigned>(m) >= sizeof(T) * CHAR_BIT) {
+    *err = ("strict_sistrtoll: the SI prefix is too large for the designated "
+	    "type");
+    return 0;
+  }
+  using promoted_t = typename std::common_type<decltype(ll), T>::type;
+  if (static_cast<promoted_t>(ll) <
+      static_cast<promoted_t>(std::numeric_limits<T>::min()) >> m) {
     *err = "strict_sistrtoll: value seems to be too small";
     return 0;
   }
-  if (ll > std::numeric_limits<T>::max() >> m) {
+  if (static_cast<promoted_t>(ll) >
+      static_cast<promoted_t>(std::numeric_limits<T>::max()) >> m) {
     *err = "strict_sistrtoll: value seems to be too large";
     return 0;
-
   }
   return (ll << m);
 }
diff --git a/src/common/strtol.h b/src/common/strtol.h
index ed86568..2f4c4ce 100644
--- a/src/common/strtol.h
+++ b/src/common/strtol.h
@@ -34,4 +34,26 @@ uint64_t strict_sistrtoll(const char *str, std::string *err);
 template<typename T>
 T strict_si_cast(const char *str, std::string *err);
 
+/* On enter buf points to the end of the buffer, e.g. where the least
+ * significant digit of the input number will be printed. Returns pointer to
+ * where the most significant digit were printed, including zero padding.
+ * Does NOT add zero at the end of buffer, this is responsibility of the caller.
+ */
+template<typename T, const unsigned base = 10, const unsigned width = 1>
+static inline
+char* ritoa(T u, char *buf)
+{
+  static_assert(std::is_unsigned<T>::value, "signed types are not supported");
+  static_assert(base <= 16, "extend character map below to support higher bases");
+  unsigned digits = 0;
+  while (u) {
+    *--buf = "0123456789abcdef"[u % base];
+    u /= base;
+    digits++;
+  }
+  while (digits++ < width)
+    *--buf = '0';
+  return buf;
+}
+
 #endif
diff --git a/src/common/utf8.c b/src/common/utf8.c
index 5bf0a5b..3bc77c3 100644
--- a/src/common/utf8.c
+++ b/src/common/utf8.c
@@ -16,9 +16,6 @@
 #include <stdio.h>
 #include <string.h>
 
-#define MAX_UTF8_SZ 6
-#define INVALID_UTF8_CHAR 0xfffffffful
-
 static int high_bits_set(int c)
 {
 	int ret = 0;
diff --git a/src/common/utf8.h b/src/common/utf8.h
index 28649ef..83efe6f 100644
--- a/src/common/utf8.h
+++ b/src/common/utf8.h
@@ -15,6 +15,9 @@
 #ifndef CEPH_COMMON_UTF8_H
 #define CEPH_COMMON_UTF8_H
 
+#define MAX_UTF8_SZ 6
+#define INVALID_UTF8_CHAR 0xfffffffful
+
 #ifdef __cplusplus
 extern "C" {
 #endif
diff --git a/src/compressor/zlib/CompressionPluginZlib.cc b/src/compressor/zlib/CompressionPluginZlib.cc
index d303d7f..90fd561 100644
--- a/src/compressor/zlib/CompressionPluginZlib.cc
+++ b/src/compressor/zlib/CompressionPluginZlib.cc
@@ -25,7 +25,7 @@
 class CompressionPluginZlib : public CompressionPlugin {
 public:
 
-  CompressionPluginZlib(CephContext *cct) : CompressionPlugin(cct)
+  explicit CompressionPluginZlib(CephContext *cct) : CompressionPlugin(cct)
   {}
 
   virtual int factory(CompressorRef *cs,
diff --git a/src/compressor/zlib/CompressionZlib.cc b/src/compressor/zlib/CompressionZlib.cc
index fd03bdc..9717971 100644
--- a/src/compressor/zlib/CompressionZlib.cc
+++ b/src/compressor/zlib/CompressionZlib.cc
@@ -44,7 +44,7 @@ const char* CompressionZlib::get_method_name()
 
 int CompressionZlib::compress(const bufferlist &in, bufferlist &out)
 {
-  int ret, flush;
+  int ret;
   unsigned have;
   z_stream strm;
   unsigned char* c_in;
@@ -71,7 +71,7 @@ int CompressionZlib::compress(const bufferlist &in, bufferlist &out)
     ++i;
 
     strm.avail_in = len;
-    flush = i != in.buffers().end() ? Z_NO_FLUSH : Z_FINISH;
+    int flush = i != in.buffers().end() ? Z_NO_FLUSH : Z_FINISH;
 
     strm.next_in = c_in;
 
diff --git a/src/crush/CrushTester.cc b/src/crush/CrushTester.cc
index da1ed94..2ebe8c2 100644
--- a/src/crush/CrushTester.cc
+++ b/src/crush/CrushTester.cc
@@ -8,6 +8,13 @@
 #include <algorithm>
 #include <stdlib.h>
 #include <boost/lexical_cast.hpp>
+// to workaround https://svn.boost.org/trac/boost/ticket/9501
+#ifdef _LIBCPP_VERSION
+#include <boost/version.hpp>
+#if BOOST_VERSION < 105600
+#define ICL_USE_BOOST_MOVE_IMPLEMENTATION
+#endif
+#endif
 #include <boost/icl/interval_map.hpp>
 #include <boost/algorithm/string/join.hpp>
 #include <common/SubProcess.h>
diff --git a/src/crush/CrushWrapper.cc b/src/crush/CrushWrapper.cc
index 72739fd..9fb4202 100644
--- a/src/crush/CrushWrapper.cc
+++ b/src/crush/CrushWrapper.cc
@@ -1568,6 +1568,9 @@ void CrushWrapper::dump_tunables(Formatter *f) const
   f->dump_int("optimal_tunables", (int)has_optimal_tunables());
   f->dump_int("legacy_tunables", (int)has_legacy_tunables());
 
+  // be helpful about minimum version required
+  f->dump_string("minimum_required_version", get_min_required_version());
+
   f->dump_int("require_feature_tunables", (int)has_nondefault_tunables());
   f->dump_int("require_feature_tunables2", (int)has_nondefault_tunables2());
   f->dump_int("has_v2_rules", (int)has_v2_rules());
diff --git a/src/crush/CrushWrapper.h b/src/crush/CrushWrapper.h
index 77baa2c..1f9c878 100644
--- a/src/crush/CrushWrapper.h
+++ b/src/crush/CrushWrapper.h
@@ -164,7 +164,7 @@ public:
     crush->straw_calc_version = 1;
   }
   void set_tunables_default() {
-    set_tunables_bobtail();
+    set_tunables_firefly();
     crush->straw_calc_version = 1;
   }
 
@@ -232,7 +232,6 @@ public:
       crush->chooseleaf_descend_once == 0 &&
       crush->chooseleaf_vary_r == 0 &&
       crush->chooseleaf_stable == 0 &&
-      crush->straw_calc_version == 0 &&
       crush->allowed_bucket_algs == CRUSH_LEGACY_ALLOWED_BUCKET_ALGS;
   }
   bool has_bobtail_tunables() const {
@@ -243,7 +242,6 @@ public:
       crush->chooseleaf_descend_once == 1 &&
       crush->chooseleaf_vary_r == 0 &&
       crush->chooseleaf_stable == 0 &&
-      crush->straw_calc_version == 0 &&
       crush->allowed_bucket_algs == CRUSH_LEGACY_ALLOWED_BUCKET_ALGS;
   }
   bool has_firefly_tunables() const {
@@ -254,7 +252,6 @@ public:
       crush->chooseleaf_descend_once == 1 &&
       crush->chooseleaf_vary_r == 1 &&
       crush->chooseleaf_stable == 0 &&
-      crush->straw_calc_version == 0 &&
       crush->allowed_bucket_algs == CRUSH_LEGACY_ALLOWED_BUCKET_ALGS;
   }
   bool has_hammer_tunables() const {
@@ -265,7 +262,6 @@ public:
       crush->chooseleaf_descend_once == 1 &&
       crush->chooseleaf_vary_r == 1 &&
       crush->chooseleaf_stable == 0 &&
-      crush->straw_calc_version == 1 &&
       crush->allowed_bucket_algs == ((1 << CRUSH_BUCKET_UNIFORM) |
 				      (1 << CRUSH_BUCKET_LIST) |
 				      (1 << CRUSH_BUCKET_STRAW) |
@@ -279,7 +275,6 @@ public:
       crush->chooseleaf_descend_once == 1 &&
       crush->chooseleaf_vary_r == 1 &&
       crush->chooseleaf_stable == 1 &&
-      crush->straw_calc_version == 1 &&
       crush->allowed_bucket_algs == ((1 << CRUSH_BUCKET_UNIFORM) |
 				      (1 << CRUSH_BUCKET_LIST) |
 				      (1 << CRUSH_BUCKET_STRAW) |
@@ -321,6 +316,19 @@ public:
   bool is_v3_rule(unsigned ruleid) const;
   bool is_v5_rule(unsigned ruleid) const;
 
+  string get_min_required_version() const {
+    if (has_v5_rules() || has_nondefault_tunables5())
+      return "jewel";
+    else if (has_v4_buckets())
+      return "hammer";
+    else if (has_nondefault_tunables3())
+      return "firefly";
+    else if (has_nondefault_tunables2() || has_nondefault_tunables())
+      return "bobtail";
+    else
+      return "argonaut";
+  }
+
   // default bucket types
   unsigned get_default_bucket_alg() const {
     // in order of preference
diff --git a/src/erasure-code/jerasure/ErasureCodeJerasure.h b/src/erasure-code/jerasure/ErasureCodeJerasure.h
index 67fc360..31d049f 100644
--- a/src/erasure-code/jerasure/ErasureCodeJerasure.h
+++ b/src/erasure-code/jerasure/ErasureCodeJerasure.h
@@ -158,7 +158,8 @@ public:
   explicit ErasureCodeJerasureCauchy(const char *technique) :
     ErasureCodeJerasure(technique),
     bitmatrix(0),
-    schedule(0)
+    schedule(0),
+    packetsize(0)
   {
     DEFAULT_K = "7";
     DEFAULT_M = "3";
@@ -211,7 +212,8 @@ public:
   explicit ErasureCodeJerasureLiberation(const char *technique = "liberation") :
     ErasureCodeJerasure(technique),
     bitmatrix(0),
-    schedule(0)
+    schedule(0),
+    packetsize(0)
   {
     DEFAULT_K = "2";
     DEFAULT_M = "2";
diff --git a/src/erasure-code/jerasure/gf-complete/include/gf_complete.h b/src/erasure-code/jerasure/gf-complete/include/gf_complete.h
deleted file mode 100644
index c4783e8..0000000
--- a/src/erasure-code/jerasure/gf-complete/include/gf_complete.h
+++ /dev/null
@@ -1,204 +0,0 @@
-/* 
- * GF-Complete: A Comprehensive Open Source Library for Galois Field Arithmetic
- * James S. Plank, Ethan L. Miller, Kevin M. Greenan,
- * Benjamin A. Arnold, John A. Burnum, Adam W. Disney, Allen C. McBride.
- *
- * gf_complete.h
- *
- * The main include file for gf_complete. 
- */
-
-#ifndef _GF_COMPLETE_H_
-#define _GF_COMPLETE_H_
-#include <stdint.h>
-
-#ifdef INTEL_SSE4
-  #ifdef __SSE4_2__
-    #include <nmmintrin.h>
-  #endif
-  #ifdef __SSE4_1__
-    #include <smmintrin.h>
-  #endif
-#endif
-
-#ifdef INTEL_SSSE3
-  #include <tmmintrin.h>
-#endif
-
-#ifdef INTEL_SSE2
-  #include <emmintrin.h>
-#endif
-
-#ifdef INTEL_SSE4_PCLMUL
-  #include <wmmintrin.h>
-#endif
-
-#if defined(ARM_NEON)
-  #include <arm_neon.h>
-#endif
-
-
-/* These are the different ways to perform multiplication.
-   Not all are implemented for all values of w.
-   See the paper for an explanation of how they work. */
-
-typedef enum {GF_MULT_DEFAULT,
-              GF_MULT_SHIFT,
-              GF_MULT_CARRY_FREE,
-              GF_MULT_CARRY_FREE_GK,
-              GF_MULT_GROUP,
-              GF_MULT_BYTWO_p,
-              GF_MULT_BYTWO_b,
-              GF_MULT_TABLE,
-              GF_MULT_LOG_TABLE,
-              GF_MULT_LOG_ZERO,
-              GF_MULT_LOG_ZERO_EXT,
-              GF_MULT_SPLIT_TABLE,
-              GF_MULT_COMPOSITE } gf_mult_type_t;
-
-/* These are the different ways to optimize region 
-   operations.  They are bits because you can compose them.
-   Certain optimizations only apply to certain gf_mult_type_t's.  
-   Again, please see documentation for how to use these */
-   
-#define GF_REGION_DEFAULT      (0x0)
-#define GF_REGION_DOUBLE_TABLE (0x1)
-#define GF_REGION_QUAD_TABLE   (0x2)
-#define GF_REGION_LAZY         (0x4)
-#define GF_REGION_SIMD         (0x8)
-#define GF_REGION_SSE          (0x8)
-#define GF_REGION_NOSIMD       (0x10)
-#define GF_REGION_NOSSE        (0x10)
-#define GF_REGION_ALTMAP       (0x20)
-#define GF_REGION_CAUCHY       (0x40)
-
-typedef uint32_t gf_region_type_t;
-
-/* These are different ways to implement division.
-   Once again, it's best to use "DEFAULT".  However,
-   there are times when you may want to experiment
-   with the others. */
-
-typedef enum { GF_DIVIDE_DEFAULT,
-               GF_DIVIDE_MATRIX,
-               GF_DIVIDE_EUCLID } gf_division_type_t;
-
-/* We support w=4,8,16,32,64 and 128 with their own data types and
-   operations for multiplication, division, etc.  We also support
-   a "gen" type so that you can do general gf arithmetic for any 
-   value of w from 1 to 32.  You can perform a "region" operation
-   on these if you use "CAUCHY" as the mapping. 
- */
-
-typedef uint32_t    gf_val_32_t;
-typedef uint64_t    gf_val_64_t;
-typedef uint64_t   *gf_val_128_t;
-
-extern int _gf_errno;
-extern void gf_error();
-
-typedef struct gf *GFP;
-
-typedef union gf_func_a_b {
-    gf_val_32_t  (*w32) (GFP gf, gf_val_32_t a,  gf_val_32_t b);
-    gf_val_64_t  (*w64) (GFP gf, gf_val_64_t a,  gf_val_64_t b);
-    void         (*w128)(GFP gf, gf_val_128_t a, gf_val_128_t b, gf_val_128_t c);
-} gf_func_a_b;
-  
-typedef union {
-  gf_val_32_t  (*w32) (GFP gf, gf_val_32_t a);
-  gf_val_64_t  (*w64) (GFP gf, gf_val_64_t a);
-  void         (*w128)(GFP gf, gf_val_128_t a, gf_val_128_t b);
-} gf_func_a;
-  
-typedef union {
-  void  (*w32) (GFP gf, void *src, void *dest, gf_val_32_t val,  int bytes, int add);
-  void  (*w64) (GFP gf, void *src, void *dest, gf_val_64_t val,  int bytes, int add);
-  void  (*w128)(GFP gf, void *src, void *dest, gf_val_128_t val, int bytes, int add);
-} gf_region;
-
-typedef union {
-  gf_val_32_t  (*w32) (GFP gf, void *start, int bytes, int index);
-  gf_val_64_t  (*w64) (GFP gf, void *start, int bytes, int index);
-  void         (*w128)(GFP gf, void *start, int bytes, int index, gf_val_128_t rv);
-} gf_extract;
-
-typedef struct gf {
-  gf_func_a_b    multiply;
-  gf_func_a_b    divide;
-  gf_func_a      inverse;
-  gf_region      multiply_region;
-  gf_extract     extract_word;
-  void           *scratch;
-} gf_t;
-    
-/* Initializes the GF to defaults.  Pass it a pointer to a gf_t.
-   Returns 0 on failure, 1 on success. */
-
-extern int gf_init_easy(GFP gf, int w);
-
-/* Initializes the GF changing the defaults.
-   Returns 0 on failure, 1 on success.
-   Pass it a pointer to a gf_t.
-   For mult_type and divide_type, use one of gf_mult_type_t gf_divide_type_t .  
-   For region_type, OR together the GF_REGION_xxx's defined above.  
-   Use 0 as prim_poly for defaults.  Otherwise, the leading 1 is optional.
-   Use NULL for scratch_memory to have init_hard allocate memory.  Otherwise,
-   use gf_scratch_size() to determine how big scratch_memory has to be.
- */
-
-extern int gf_init_hard(GFP gf, 
-                        int w, 
-                        int mult_type, 
-                        int region_type, 
-                        int divide_type, 
-                        uint64_t prim_poly,
-                        int arg1, 
-                        int arg2,
-                        GFP base_gf,
-                        void *scratch_memory);
-
-/* Determines the size for scratch_memory.  
-   Returns 0 on failure and non-zero on success. */
-
-extern int gf_scratch_size(int w, 
-                           int mult_type, 
-                           int region_type, 
-                           int divide_type, 
-                           int arg1, 
-                           int arg2);
-
-/* This reports the gf_scratch_size of a gf_t that has already been created */
-
-extern int gf_size(GFP gf);
-
-/* Frees scratch memory if gf_init_easy/gf_init_hard called malloc.
-   If recursive = 1, then it calls itself recursively on base_gf. */
-
-extern int gf_free(GFP gf, int recursive);
-
-/* This is support for inline single multiplications and divisions.
-   I know it's yucky, but if you've got to be fast, you've got to be fast.
-   We support inlining for w=4, w=8 and w=16.  
-
-   To use inline multiplication and division with w=4 or 8, you should use the 
-   default gf_t, or one with a single table.  Otherwise, gf_w4/8_get_mult_table()
-   will return NULL. Similarly, with w=16, the gf_t must be LOG */
-
-uint8_t *gf_w4_get_mult_table(GFP gf);
-uint8_t *gf_w4_get_div_table(GFP gf);
-
-#define GF_W4_INLINE_MULTDIV(table, a, b) (table[((a)<<4)|(b)])
-
-uint8_t *gf_w8_get_mult_table(GFP gf);
-uint8_t *gf_w8_get_div_table(GFP gf);
-
-#define GF_W8_INLINE_MULTDIV(table, a, b) (table[(((uint32_t) (a))<<8)|(b)])
-
-uint16_t *gf_w16_get_log_table(GFP gf);
-uint16_t *gf_w16_get_mult_alog_table(GFP gf);
-uint16_t *gf_w16_get_div_alog_table(GFP gf);
-
-#define GF_W16_INLINE_MULT(log, alog, a, b) ((a) == 0 || (b) == 0) ? 0 : (alog[(uint32_t)log[a]+(uint32_t)log[b]])
-#define GF_W16_INLINE_DIV(log, alog, a, b) ((a) == 0 || (b) == 0) ? 0 : (alog[(int)log[a]-(int)log[b]])
-#endif
diff --git a/src/erasure-code/jerasure/gf-complete/include/gf_general.h b/src/erasure-code/jerasure/gf-complete/include/gf_general.h
deleted file mode 100644
index 9a5de52..0000000
--- a/src/erasure-code/jerasure/gf-complete/include/gf_general.h
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * GF-Complete: A Comprehensive Open Source Library for Galois Field Arithmetic
- * James S. Plank, Ethan L. Miller, Kevin M. Greenan,
- * Benjamin A. Arnold, John A. Burnum, Adam W. Disney, Allen C. McBride.
- *
- * gf_general.h
- *
- * This file has helper routines for doing basic GF operations with any
- * legal value of w.  The problem is that w <= 32, w=64 and w=128 all have
- * different data types, which is a pain.  The procedures in this file try
- * to alleviate that pain.  They are used in gf_unit and gf_time.
- */
-
-#pragma once
-
-#include <stdio.h>
-#include <getopt.h>
-#include <stdint.h>
-#include <string.h>
-#include <stdlib.h>
-#include <time.h>
-
-#include "gf_complete.h"
-
-typedef union {
-  uint32_t w32;
-  uint64_t w64;
-  uint64_t w128[2];
-} gf_general_t;
-
-void gf_general_set_zero(gf_general_t *v, int w);
-void gf_general_set_one(gf_general_t *v, int w);
-void gf_general_set_two(gf_general_t *v, int w);
-
-int gf_general_is_zero(gf_general_t *v, int w);
-int gf_general_is_one(gf_general_t *v, int w);
-int gf_general_are_equal(gf_general_t *v1, gf_general_t *v2, int w);
-
-void gf_general_val_to_s(gf_general_t *v, int w, char *s, int hex);
-int  gf_general_s_to_val(gf_general_t *v, int w, char *s, int hex);
-
-void gf_general_set_random(gf_general_t *v, int w, int zero_ok);
-
-void gf_general_add(gf_t *gf, gf_general_t *a, gf_general_t *b, gf_general_t *c);
-void gf_general_multiply(gf_t *gf, gf_general_t *a, gf_general_t *b, gf_general_t *c);
-void gf_general_divide(gf_t *gf, gf_general_t *a, gf_general_t *b, gf_general_t *c);
-void gf_general_inverse(gf_t *gf, gf_general_t *a, gf_general_t *b);
-
-void gf_general_do_region_multiply(gf_t *gf, gf_general_t *a, 
-                                   void *ra, void *rb, 
-                                   int bytes, int xor);
-
-void gf_general_do_region_check(gf_t *gf, gf_general_t *a, 
-                                void *orig_a, void *orig_target, void *final_target, 
-                                int bytes, int xor);
-
-
-/* Which is M, D or I for multiply, divide or inverse. */
-
-void gf_general_set_up_single_timing_test(int w, void *ra, void *rb, int size);
-int  gf_general_do_single_timing_test(gf_t *gf, void *ra, void *rb, int size, char which);
diff --git a/src/erasure-code/jerasure/gf-complete/include/gf_int.h b/src/erasure-code/jerasure/gf-complete/include/gf_int.h
deleted file mode 100644
index 32866f4..0000000
--- a/src/erasure-code/jerasure/gf-complete/include/gf_int.h
+++ /dev/null
@@ -1,200 +0,0 @@
-/*
- * GF-Complete: A Comprehensive Open Source Library for Galois Field Arithmetic
- * James S. Plank, Ethan L. Miller, Kevin M. Greenan,
- * Benjamin A. Arnold, John A. Burnum, Adam W. Disney, Allen C. McBride.
- *
- * gf_int.h
- *
- * Internal code for Galois field routines.  This is not meant for 
- * users to include, but for the internal GF files to use. 
- */
-
-#pragma once
-
-#include "gf_complete.h"
-
-#include <string.h>
-
-extern void     timer_start (double *t);
-extern double   timer_split (const double *t);
-extern void     galois_fill_random (void *buf, int len, unsigned int seed);
-
-typedef struct {
-  int mult_type;
-  int region_type;
-  int divide_type;
-  int w;
-  uint64_t prim_poly;
-  int free_me;
-  int arg1;
-  int arg2;
-  gf_t *base_gf;
-  void *private;
-} gf_internal_t;
-
-extern int gf_w4_init (gf_t *gf);
-extern int gf_w4_scratch_size(int mult_type, int region_type, int divide_type, int arg1, int arg2);
-
-extern int gf_w8_init (gf_t *gf);
-extern int gf_w8_scratch_size(int mult_type, int region_type, int divide_type, int arg1, int arg2);
-
-extern int gf_w16_init (gf_t *gf);
-extern int gf_w16_scratch_size(int mult_type, int region_type, int divide_type, int arg1, int arg2);
-
-extern int gf_w32_init (gf_t *gf);
-extern int gf_w32_scratch_size(int mult_type, int region_type, int divide_type, int arg1, int arg2);
-
-extern int gf_w64_init (gf_t *gf);
-extern int gf_w64_scratch_size(int mult_type, int region_type, int divide_type, int arg1, int arg2);
-
-extern int gf_w128_init (gf_t *gf);
-extern int gf_w128_scratch_size(int mult_type, int region_type, int divide_type, int arg1, int arg2);
-
-extern int gf_wgen_init (gf_t *gf);
-extern int gf_wgen_scratch_size(int w, int mult_type, int region_type, int divide_type, int arg1, int arg2);
-
-void gf_wgen_cauchy_region(gf_t *gf, void *src, void *dest, gf_val_32_t val, int bytes, int xor);
-gf_val_32_t gf_wgen_extract_word(gf_t *gf, void *start, int bytes, int index);
-
-extern void gf_alignment_error(char *s, int a);
-
-extern uint32_t gf_bitmatrix_inverse(uint32_t y, int w, uint32_t pp);
-
-/* This returns the correct default for prim_poly when base is used as the base
-   field for COMPOSITE.  It returns 0 if we don't have a default prim_poly. */
-
-extern uint64_t gf_composite_get_default_poly(gf_t *base);
-
-/* This structure lets you define a region multiply.  It helps because you can handle
-   unaligned portions of the data with the procedures below, which really cleans
-   up the code. */
-
-typedef struct {
-  gf_t *gf;
-  void *src;
-  void *dest;
-  int bytes;
-  uint64_t val;
-  int xor;
-  int align;           /* The number of bytes to which to align. */
-  void *s_start;       /* The start and the top of the aligned region. */
-  void *d_start;
-  void *s_top;
-  void *d_top;
-} gf_region_data;
-
-/* This lets you set up one of these in one call. It also sets the start/top pointers. */
-
-void gf_set_region_data(gf_region_data *rd,
-                        gf_t *gf,
-                        void *src,
-                        void *dest,
-                        int bytes,
-                        uint64_t val,
-                        int xor,
-                        int align);
-
-/* This performs gf->multiply.32() on all of the unaligned bytes in the beginning of the region */
-
-extern void gf_do_initial_region_alignment(gf_region_data *rd);
-
-/* This performs gf->multiply.32() on all of the unaligned bytes in the end of the region */
-
-extern void gf_do_final_region_alignment(gf_region_data *rd);
-
-extern void gf_two_byte_region_table_multiply(gf_region_data *rd, uint16_t *base);
-
-extern void gf_multby_zero(void *dest, int bytes, int xor);
-extern void gf_multby_one(void *src, void *dest, int bytes, int xor);
-
-typedef enum {GF_E_MDEFDIV, /* Dev != Default && Mult == Default */
-              GF_E_MDEFREG, /* Reg != Default && Mult == Default */
-              GF_E_MDEFARG, /* Args != Default && Mult == Default */
-              GF_E_DIVCOMP, /* Mult == Composite && Div != Default */
-              GF_E_CAUCOMP, /* Mult == Composite && Reg == CAUCHY */
-              GF_E_DOUQUAD, /* Reg == DOUBLE && Reg == QUAD */
-              GF_E_SIMD_NO, /* Reg == SIMD && Reg == NOSIMD */
-              GF_E_CAUCHYB, /* Reg == CAUCHY && Other Reg */
-              GF_E_CAUGT32, /* Reg == CAUCHY && w > 32*/
-              GF_E_ARG1SET, /* Arg1 != 0 && Mult \notin COMPOSITE/SPLIT/GROUP */
-              GF_E_ARG2SET, /* Arg2 != 0 && Mult \notin SPLIT/GROUP */
-              GF_E_MATRIXW, /* Div == MATRIX && w > 32 */
-              GF_E_BAD___W, /* Illegal w */
-              GF_E_DOUBLET, /* Reg == DOUBLE && Mult != TABLE */
-              GF_E_DOUBLEW, /* Reg == DOUBLE && w \notin {4,8} */
-              GF_E_DOUBLEJ, /* Reg == DOUBLE && other Reg */
-              GF_E_DOUBLEL, /* Reg == DOUBLE & LAZY but w = 4 */
-              GF_E_QUAD__T, /* Reg == QUAD && Mult != TABLE */
-              GF_E_QUAD__W, /* Reg == QUAD && w != 4 */
-              GF_E_QUAD__J, /* Reg == QUAD && other Reg */
-              GF_E_LAZY__X, /* Reg == LAZY && not DOUBLE or QUAD*/
-              GF_E_ALTSHIF, /* Mult == Shift && Reg == ALTMAP */
-              GF_E_SSESHIF, /* Mult == Shift && Reg == SIMD|NOSIMD */
-              GF_E_ALT_CFM, /* Mult == CARRY_FREE && Reg == ALTMAP */
-              GF_E_SSE_CFM, /* Mult == CARRY_FREE && Reg == SIMD|NOSIMD */
-              GF_E_PCLMULX, /* Mult == Carry_Free && No PCLMUL */
-              GF_E_ALT_BY2, /* Mult == Bytwo_x && Reg == ALTMAP */
-              GF_E_BY2_SSE, /* Mult == Bytwo_x && Reg == SSE && No SSE2 */
-              GF_E_LOGBADW, /* Mult == LOGx, w too big*/
-              GF_E_LOG___J, /* Mult == LOGx, && Reg == SSE|ALTMAP|NOSSE */
-              GF_E_ZERBADW, /* Mult == LOG_ZERO, w \notin {8,16} */
-              GF_E_ZEXBADW, /* Mult == LOG_ZERO_EXT, w != 8 */
-              GF_E_LOGPOLY, /* Mult == LOG & poly not primitive */
-              GF_E_GR_ARGX, /* Mult == GROUP, Bad arg1/2 */
-              GF_E_GR_W_48, /* Mult == GROUP, w \in { 4, 8 } */
-              GF_E_GR_W_16, /* Mult == GROUP, w == 16, arg1 != 4 || arg2 != 4 */
-              GF_E_GR_128A, /* Mult == GROUP, w == 128, bad args */
-              GF_E_GR_A_27, /* Mult == GROUP, either arg > 27 */
-              GF_E_GR_AR_W, /* Mult == GROUP, either arg > w  */
-              GF_E_GR____J, /* Mult == GROUP, Reg == SSE|ALTMAP|NOSSE */
-              GF_E_TABLE_W, /* Mult == TABLE, w too big */
-              GF_E_TAB_SSE, /* Mult == TABLE, SIMD|NOSIMD only apply to w == 4 */
-              GF_E_TABSSE3, /* Mult == TABLE, Need SSSE3 for SSE */
-              GF_E_TAB_ALT, /* Mult == TABLE, Reg == ALTMAP */
-              GF_E_SP128AR, /* Mult == SPLIT, w=128, Bad arg1/arg2 */
-              GF_E_SP128AL, /* Mult == SPLIT, w=128, SSE requires ALTMAP */
-              GF_E_SP128AS, /* Mult == SPLIT, w=128, ALTMAP requires SSE */
-              GF_E_SP128_A, /* Mult == SPLIT, w=128, ALTMAP only with 4/128 */
-              GF_E_SP128_S, /* Mult == SPLIT, w=128, SSE only with 4/128 */
-              GF_E_SPLIT_W, /* Mult == SPLIT, Bad w (8, 16, 32, 64, 128)  */
-              GF_E_SP_16AR, /* Mult == SPLIT, w=16, Bad arg1/arg2 */
-              GF_E_SP_16_A, /* Mult == SPLIT, w=16, ALTMAP only with 4/16 */
-              GF_E_SP_16_S, /* Mult == SPLIT, w=16, SSE only with 4/16 */
-              GF_E_SP_32AR, /* Mult == SPLIT, w=32, Bad arg1/arg2 */
-              GF_E_SP_32AS, /* Mult == SPLIT, w=32, ALTMAP requires SSE */
-              GF_E_SP_32_A, /* Mult == SPLIT, w=32, ALTMAP only with 4/32 */
-              GF_E_SP_32_S, /* Mult == SPLIT, w=32, SSE only with 4/32 */
-              GF_E_SP_64AR, /* Mult == SPLIT, w=64, Bad arg1/arg2 */
-              GF_E_SP_64AS, /* Mult == SPLIT, w=64, ALTMAP requires SSE */
-              GF_E_SP_64_A, /* Mult == SPLIT, w=64, ALTMAP only with 4/64 */
-              GF_E_SP_64_S, /* Mult == SPLIT, w=64, SSE only with 4/64 */
-              GF_E_SP_8_AR, /* Mult == SPLIT, w=8, Bad arg1/arg2 */
-              GF_E_SP_8__A, /* Mult == SPLIT, w=8, no ALTMAP */
-              GF_E_SP_SSE3, /* Mult == SPLIT, Need SSSE3 for SSE */
-              GF_E_COMP_A2, /* Mult == COMP, arg1 must be = 2 */
-              GF_E_COMP_SS, /* Mult == COMP, SIMD|NOSIMD */
-              GF_E_COMP__W, /* Mult == COMP, Bad w. */
-              GF_E_UNKFLAG, /* Unknown flag in create_from.... */
-              GF_E_UNKNOWN, /* Unknown mult_type. */
-              GF_E_UNK_REG, /* Unknown region_type. */
-              GF_E_UNK_DIV, /* Unknown divide_type. */
-              GF_E_CFM___W, /* Mult == CFM,  Bad w. */
-              GF_E_CFM4POL, /* Mult == CFM & Prim Poly has high bits set. */
-              GF_E_CFM8POL, /* Mult == CFM & Prim Poly has high bits set. */
-              GF_E_CF16POL, /* Mult == CFM & Prim Poly has high bits set. */
-              GF_E_CF32POL, /* Mult == CFM & Prim Poly has high bits set. */
-              GF_E_CF64POL, /* Mult == CFM & Prim Poly has high bits set. */
-              GF_E_FEWARGS, /* Too few args in argc/argv. */
-              GF_E_BADPOLY, /* Bad primitive polynomial -- too many bits set. */
-              GF_E_COMP_PP, /* Bad primitive polynomial -- bigger than sub-field. */
-              GF_E_COMPXPP, /* Can't derive a default pp for composite field. */
-              GF_E_BASE__W, /* Composite -- Base field is the wrong size. */
-              GF_E_TWOMULT, /* In create_from... two -m's. */
-              GF_E_TWO_DIV, /* In create_from... two -d's. */
-              GF_E_POLYSPC, /* Bad numbera after -p. */
-              GF_E_SPLITAR, /* Ran out of arguments in SPLIT */
-              GF_E_SPLITNU, /* Arguments not integers in SPLIT. */
-              GF_E_GROUPAR, /* Ran out of arguments in GROUP */
-              GF_E_GROUPNU, /* Arguments not integers in GROUP. */
-              GF_E_DEFAULT } gf_error_type_t;
-
diff --git a/src/erasure-code/jerasure/gf-complete/include/gf_method.h b/src/erasure-code/jerasure/gf-complete/include/gf_method.h
deleted file mode 100644
index 880b349..0000000
--- a/src/erasure-code/jerasure/gf-complete/include/gf_method.h
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- * GF-Complete: A Comprehensive Open Source Library for Galois Field Arithmetic
- * James S. Plank, Ethan L. Miller, Kevin M. Greenan,
- * Benjamin A. Arnold, John A. Burnum, Adam W. Disney, Allen C. McBride.
- *
- * gf_method.h
- *
- * Parses argv to figure out the flags and arguments.  Creates the gf.
- */
-
-#pragma once
-
-#include "gf_complete.h"
-
-/* Parses argv starting at "starting".  
-   
-   Returns 0 on failure.
-   On success, it returns one past the last argument it read in argv. */
-
-extern int create_gf_from_argv(gf_t *gf, int w, int argc, char **argv, int starting);
diff --git a/src/erasure-code/jerasure/gf-complete/include/gf_rand.h b/src/erasure-code/jerasure/gf-complete/include/gf_rand.h
deleted file mode 100644
index 24294ad..0000000
--- a/src/erasure-code/jerasure/gf-complete/include/gf_rand.h
+++ /dev/null
@@ -1,22 +0,0 @@
-/* 
- * GF-Complete: A Comprehensive Open Source Library for Galois Field Arithmetic
- * James S. Plank, Ethan L. Miller, Kevin M. Greenan,
- * Benjamin A. Arnold, John A. Burnum, Adam W. Disney, Allen C. McBride.
- *
- * gf_rand.h
- *
- * Random number generation, using the "Mother of All" random number generator.  */
-
-#pragma once
-#include <stdint.h>
-#include <stdio.h>
-#include <stdlib.h>
-
-/* These are all pretty self-explanatory */
-uint32_t MOA_Random_32();
-uint64_t MOA_Random_64();
-void     MOA_Random_128(uint64_t *x);
-uint32_t MOA_Random_W(int w, int zero_ok);
-void MOA_Fill_Random_Region (void *reg, int size);   /* reg should be aligned to 4 bytes, but
-                                                        size can be anything. */
-void     MOA_Seed(uint32_t seed);
diff --git a/src/erasure-code/jerasure/gf-complete/include/gf_w16.h b/src/erasure-code/jerasure/gf-complete/include/gf_w16.h
deleted file mode 100644
index fb4c0e9..0000000
--- a/src/erasure-code/jerasure/gf-complete/include/gf_w16.h
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * GF-Complete: A Comprehensive Open Source Library for Galois Field Arithmetic
- * James S. Plank, Ethan L. Miller, Kevin M. Greenan,
- * Benjamin A. Arnold, John A. Burnum, Adam W. Disney, Allen C. McBride.
- *
- * gf_w16.h
- *
- * Defines and data structures for 16-bit Galois fields
- */
-
-#ifndef GF_COMPLETE_GF_W16_H
-#define GF_COMPLETE_GF_W16_H
-
-#include <stdint.h>
-
-#define GF_FIELD_WIDTH (16)
-#define GF_FIELD_SIZE (1 << GF_FIELD_WIDTH)
-#define GF_MULT_GROUP_SIZE GF_FIELD_SIZE-1
-
-#define GF_BASE_FIELD_WIDTH (8)
-#define GF_BASE_FIELD_SIZE       (1 << GF_BASE_FIELD_WIDTH)
-
-struct gf_w16_logtable_data {
-    uint16_t      log_tbl[GF_FIELD_SIZE];
-    uint16_t      antilog_tbl[GF_FIELD_SIZE * 2];
-    uint16_t      inv_tbl[GF_FIELD_SIZE];
-    uint16_t      *d_antilog;
-};
-
-struct gf_w16_zero_logtable_data {
-    int           log_tbl[GF_FIELD_SIZE];
-    uint16_t      _antilog_tbl[GF_FIELD_SIZE * 4];
-    uint16_t      *antilog_tbl;
-    uint16_t      inv_tbl[GF_FIELD_SIZE];
-};
-
-struct gf_w16_lazytable_data {
-    uint16_t      log_tbl[GF_FIELD_SIZE];
-    uint16_t      antilog_tbl[GF_FIELD_SIZE * 2];
-    uint16_t      inv_tbl[GF_FIELD_SIZE];
-    uint16_t      *d_antilog;
-    uint16_t      lazytable[GF_FIELD_SIZE];
-};
-
-struct gf_w16_bytwo_data {
-    uint64_t prim_poly;
-    uint64_t mask1;
-    uint64_t mask2;
-};
-
-struct gf_w16_split_8_8_data {
-    uint16_t      tables[3][256][256];
-};
-
-struct gf_w16_group_4_4_data {
-    uint16_t reduce[16];
-    uint16_t shift[16];
-};
-
-struct gf_w16_composite_data {
-  uint8_t *mult_table;
-};
-
-void gf_w16_neon_split_init(gf_t *gf);
-
-#endif /* GF_COMPLETE_GF_W16_H */
diff --git a/src/erasure-code/jerasure/gf-complete/include/gf_w32.h b/src/erasure-code/jerasure/gf-complete/include/gf_w32.h
deleted file mode 100644
index 3396402..0000000
--- a/src/erasure-code/jerasure/gf-complete/include/gf_w32.h
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * GF-Complete: A Comprehensive Open Source Library for Galois Field Arithmetic
- * James S. Plank, Ethan L. Miller, Kevin M. Greenan,
- * Benjamin A. Arnold, John A. Burnum, Adam W. Disney, Allen C. McBride.
- *
- * gf_w32.h
- *
- * Defines and data structures for 32-bit Galois fields
- */
-
-#ifndef GF_COMPLETE_GF_W32_H
-#define GF_COMPLETE_GF_W32_H
-
-#include <stdint.h>
-
-#define GF_FIELD_WIDTH (32)
-#define GF_FIRST_BIT (1 << 31)
-
-#define GF_BASE_FIELD_WIDTH (16)
-#define GF_BASE_FIELD_SIZE       (1 << GF_BASE_FIELD_WIDTH)
-#define GF_BASE_FIELD_GROUP_SIZE  GF_BASE_FIELD_SIZE-1
-#define GF_MULTBY_TWO(p) (((p) & GF_FIRST_BIT) ? (((p) << 1) ^ h->prim_poly) : (p) << 1)
-
-struct gf_split_2_32_lazy_data {
-    uint32_t      tables[16][4];
-    uint32_t      last_value;
-};
-
-struct gf_w32_split_8_8_data {
-    uint32_t      tables[7][256][256];
-    uint32_t      region_tables[4][256];
-    uint32_t      last_value;
-};
-
-struct gf_w32_group_data {
-    uint32_t *reduce;
-    uint32_t *shift;
-    int      tshift;
-    uint64_t rmask;
-    uint32_t *memory;
-};
-
-struct gf_split_16_32_lazy_data {
-    uint32_t      tables[2][(1<<16)];
-    uint32_t      last_value;
-};
-
-struct gf_split_8_32_lazy_data {
-    uint32_t      tables[4][256];
-    uint32_t      last_value;
-};
-
-struct gf_split_4_32_lazy_data {
-    uint32_t      tables[8][16];
-    uint32_t      last_value;
-};
-
-struct gf_w32_bytwo_data {
-    uint64_t prim_poly;
-    uint64_t mask1;
-    uint64_t mask2;
-};
-
-struct gf_w32_composite_data {
-  uint16_t *log;
-  uint16_t *alog;
-};
-
-void gf_w32_neon_split_init(gf_t *gf);
-
-#endif /* GF_COMPLETE_GF_W32_H */
diff --git a/src/erasure-code/jerasure/gf-complete/include/gf_w4.h b/src/erasure-code/jerasure/gf-complete/include/gf_w4.h
deleted file mode 100644
index 8ee94a3..0000000
--- a/src/erasure-code/jerasure/gf-complete/include/gf_w4.h
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * GF-Complete: A Comprehensive Open Source Library for Galois Field Arithmetic
- * James S. Plank, Ethan L. Miller, Kevin M. Greenan,
- * Benjamin A. Arnold, John A. Burnum, Adam W. Disney, Allen C. McBride.
- *
- * gf_w4.h
- *
- * Defines and data structures for 4-bit Galois fields
- */
-
-#ifndef GF_COMPLETE_GF_W4_H
-#define GF_COMPLETE_GF_W4_H
-
-#include <stdint.h>
-
-#define GF_FIELD_WIDTH      4
-#define GF_DOUBLE_WIDTH     (GF_FIELD_WIDTH*2)
-#define GF_FIELD_SIZE       (1 << GF_FIELD_WIDTH)
-#define GF_MULT_GROUP_SIZE       (GF_FIELD_SIZE-1)
-
-/* ------------------------------------------------------------
-   JSP: Each implementation has its own data, which is allocated
-   at one time as part of the handle. For that reason, it
-   shouldn't be hierarchical -- i.e. one should be able to
-   allocate it with one call to malloc. */
-
-struct gf_logtable_data {
-    uint8_t      log_tbl[GF_FIELD_SIZE];
-    uint8_t      antilog_tbl[GF_FIELD_SIZE * 2];
-    uint8_t      *antilog_tbl_div;
-};
-
-struct gf_single_table_data {
-    uint8_t      mult[GF_FIELD_SIZE][GF_FIELD_SIZE];
-    uint8_t      div[GF_FIELD_SIZE][GF_FIELD_SIZE];
-};
-
-struct gf_double_table_data {
-    uint8_t      div[GF_FIELD_SIZE][GF_FIELD_SIZE];
-    uint8_t      mult[GF_FIELD_SIZE][GF_FIELD_SIZE*GF_FIELD_SIZE];
-};
-struct gf_quad_table_data {
-    uint8_t      div[GF_FIELD_SIZE][GF_FIELD_SIZE];
-    uint16_t     mult[GF_FIELD_SIZE][(1<<16)];
-};
-
-struct gf_quad_table_lazy_data {
-    uint8_t      div[GF_FIELD_SIZE][GF_FIELD_SIZE];
-    uint8_t      smult[GF_FIELD_SIZE][GF_FIELD_SIZE];
-    uint16_t     mult[(1 << 16)];
-};
-
-struct gf_bytwo_data {
-    uint64_t prim_poly;
-    uint64_t mask1;
-    uint64_t mask2;
-};
-
-// ARM NEON init functions
-int gf_w4_neon_cfm_init(gf_t *gf);
-void gf_w4_neon_single_table_init(gf_t *gf);
-
-#endif /* GF_COMPLETE_GF_W4_H */
diff --git a/src/erasure-code/jerasure/gf-complete/include/gf_w64.h b/src/erasure-code/jerasure/gf-complete/include/gf_w64.h
deleted file mode 100644
index 9a74a81..0000000
--- a/src/erasure-code/jerasure/gf-complete/include/gf_w64.h
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * GF-Complete: A Comprehensive Open Source Library for Galois Field Arithmetic
- * James S. Plank, Ethan L. Miller, Kevin M. Greenan,
- * Benjamin A. Arnold, John A. Burnum, Adam W. Disney, Allen C. McBride.
- *
- * gf_w64.h
- *
- * Defines and data structures for 64-bit Galois fields
- */
-
-#ifndef GF_COMPLETE_GF_W64_H
-#define GF_COMPLETE_GF_W64_H
-
-#include <stdint.h>
-
-#define GF_FIELD_WIDTH (64)
-#define GF_FIRST_BIT (1ULL << 63)
-
-#define GF_BASE_FIELD_WIDTH (32)
-#define GF_BASE_FIELD_SIZE       (1ULL << GF_BASE_FIELD_WIDTH)
-#define GF_BASE_FIELD_GROUP_SIZE  GF_BASE_FIELD_SIZE-1
-
-struct gf_w64_group_data {
-    uint64_t *reduce;
-    uint64_t *shift;
-    uint64_t *memory;
-};
-
-struct gf_split_4_64_lazy_data {
-    uint64_t      tables[16][16];
-    uint64_t      last_value;
-};
-
-struct gf_split_8_64_lazy_data {
-    uint64_t      tables[8][(1<<8)];
-    uint64_t      last_value;
-};
-
-struct gf_split_16_64_lazy_data {
-    uint64_t      tables[4][(1<<16)];
-    uint64_t      last_value;
-};
-
-struct gf_split_8_8_data {
-    uint64_t      tables[15][256][256];
-};
-
-void gf_w64_neon_split_init(gf_t *gf);
-
-#endif /* GF_COMPLETE_GF_W64_H */
diff --git a/src/erasure-code/jerasure/gf-complete/include/gf_w8.h b/src/erasure-code/jerasure/gf-complete/include/gf_w8.h
deleted file mode 100644
index 938fcfd..0000000
--- a/src/erasure-code/jerasure/gf-complete/include/gf_w8.h
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- * GF-Complete: A Comprehensive Open Source Library for Galois Field Arithmetic
- * James S. Plank, Ethan L. Miller, Kevin M. Greenan,
- * Benjamin A. Arnold, John A. Burnum, Adam W. Disney, Allen C. McBride.
- *
- * gf_w8.c
- *
- * Defines and data stuctures for 8-bit Galois fields
- */
-
-#ifndef GF_COMPLETE_GF_W8_H
-#define GF_COMPLETE_GF_W8_H
-
-#include "gf_int.h"
-#include <stdint.h>
-
-#define GF_FIELD_WIDTH (8)
-#define GF_FIELD_SIZE       (1 << GF_FIELD_WIDTH)
-#define GF_HALF_SIZE       (1 << (GF_FIELD_WIDTH/2))
-#define GF_MULT_GROUP_SIZE       GF_FIELD_SIZE-1
-
-#define GF_BASE_FIELD_WIDTH (4)
-#define GF_BASE_FIELD_SIZE       (1 << GF_BASE_FIELD_WIDTH)
-
-struct gf_w8_logtable_data {
-    uint8_t         log_tbl[GF_FIELD_SIZE];
-    uint8_t         antilog_tbl[GF_FIELD_SIZE * 2];
-    uint8_t         inv_tbl[GF_FIELD_SIZE];
-};
-
-struct gf_w8_logzero_table_data {
-    short           log_tbl[GF_FIELD_SIZE];  /* Make this signed, so that we can divide easily */
-    uint8_t         antilog_tbl[512+512+1];
-    uint8_t         *div_tbl;
-    uint8_t         *inv_tbl;
-};
-
-struct gf_w8_logzero_small_table_data {
-    short           log_tbl[GF_FIELD_SIZE];  /* Make this signed, so that we can divide easily */
-    uint8_t         antilog_tbl[255*3];
-    uint8_t         inv_tbl[GF_FIELD_SIZE];
-    uint8_t         *div_tbl;
-};
-
-struct gf_w8_composite_data {
-  uint8_t *mult_table;
-};
-
-/* Don't change the order of these relative to gf_w8_half_table_data */
-
-struct gf_w8_default_data {
-  uint8_t     high[GF_FIELD_SIZE][GF_HALF_SIZE];
-  uint8_t     low[GF_FIELD_SIZE][GF_HALF_SIZE];
-  uint8_t     divtable[GF_FIELD_SIZE][GF_FIELD_SIZE];
-  uint8_t     multtable[GF_FIELD_SIZE][GF_FIELD_SIZE];
-};
-
-struct gf_w8_half_table_data {
-  uint8_t     high[GF_FIELD_SIZE][GF_HALF_SIZE];
-  uint8_t     low[GF_FIELD_SIZE][GF_HALF_SIZE];
-};
-
-struct gf_w8_single_table_data {
-  uint8_t     divtable[GF_FIELD_SIZE][GF_FIELD_SIZE];
-  uint8_t     multtable[GF_FIELD_SIZE][GF_FIELD_SIZE];
-};
-
-struct gf_w8_double_table_data {
-    uint8_t         div[GF_FIELD_SIZE][GF_FIELD_SIZE];
-    uint16_t        mult[GF_FIELD_SIZE][GF_FIELD_SIZE*GF_FIELD_SIZE];
-};
-
-struct gf_w8_double_table_lazy_data {
-    uint8_t         div[GF_FIELD_SIZE][GF_FIELD_SIZE];
-    uint8_t         smult[GF_FIELD_SIZE][GF_FIELD_SIZE];
-    uint16_t        mult[GF_FIELD_SIZE*GF_FIELD_SIZE];
-};
-
-struct gf_w4_logtable_data {
-    uint8_t         log_tbl[GF_BASE_FIELD_SIZE];
-    uint8_t         antilog_tbl[GF_BASE_FIELD_SIZE * 2];
-    uint8_t         *antilog_tbl_div;
-};
-
-struct gf_w4_single_table_data {
-    uint8_t         div[GF_BASE_FIELD_SIZE][GF_BASE_FIELD_SIZE];
-    uint8_t         mult[GF_BASE_FIELD_SIZE][GF_BASE_FIELD_SIZE];
-};
-
-struct gf_w8_bytwo_data {
-    uint64_t prim_poly;
-    uint64_t mask1;
-    uint64_t mask2;
-};
-
-int gf_w8_neon_cfm_init(gf_t *gf);
-void gf_w8_neon_split_init(gf_t *gf);
-
-#endif /* GF_COMPLETE_GF_W8_H */
diff --git a/src/erasure-code/jerasure/gf-complete/src/gf.c b/src/erasure-code/jerasure/gf-complete/src/gf.c
deleted file mode 100644
index 835fb12..0000000
--- a/src/erasure-code/jerasure/gf-complete/src/gf.c
+++ /dev/null
@@ -1,1076 +0,0 @@
-/*
- * GF-Complete: A Comprehensive Open Source Library for Galois Field Arithmetic
- * James S. Plank, Ethan L. Miller, Kevin M. Greenan,
- * Benjamin A. Arnold, John A. Burnum, Adam W. Disney, Allen C. McBride.
- *
- * gf.c
- *
- * Generic routines for Galois fields
- */
-
-#include "gf_int.h"
-#include <stdio.h>
-#include <stdlib.h>
-#include <assert.h>
-
-int _gf_errno = GF_E_DEFAULT;
-
-void gf_error()
-{
-  char *s;
-
-  switch(_gf_errno) {
-    case GF_E_DEFAULT: s = "No Error."; break;
-    case GF_E_TWOMULT: s = "Cannot specify two -m's."; break;
-    case GF_E_TWO_DIV: s = "Cannot specify two -d's."; break;
-    case GF_E_POLYSPC: s = "-p needs to be followed by a number in hex (0x optional)."; break;
-    case GF_E_GROUPAR: s = "Ran out of arguments in -m GROUP."; break;
-    case GF_E_GROUPNU: s = "In -m GROUP g_s g_r -- g_s and g_r need to be numbers."; break;
-    case GF_E_SPLITAR: s = "Ran out of arguments in -m SPLIT."; break;
-    case GF_E_SPLITNU: s = "In -m SPLIT w_a w_b -- w_a and w_b need to be numbers."; break;
-    case GF_E_FEWARGS: s = "Not enough arguments (Perhaps end with '-'?)"; break;
-    case GF_E_CFM___W: s = "-m CARRY_FREE, w must be 4, 8, 16, 32, 64 or 128."; break;
-    case GF_E_COMPXPP: s = "-m COMPOSITE, No poly specified, and we don't have a default for the given sub-field."; break;
-    case GF_E_BASE__W: s = "-m COMPOSITE and the base field is not for w/2."; break;
-    case GF_E_CFM4POL: s = "-m CARRY_FREE, w=4. (Prim-poly & 0xc) must equal 0."; break;
-    case GF_E_CFM8POL: s = "-m CARRY_FREE, w=8. (Prim-poly & 0x80) must equal 0."; break;
-    case GF_E_CF16POL: s = "-m CARRY_FREE, w=16. (Prim-poly & 0xe000) must equal 0."; break;
-    case GF_E_CF32POL: s = "-m CARRY_FREE, w=32. (Prim-poly & 0xfe000000) must equal 0."; break;
-    case GF_E_CF64POL: s = "-m CARRY_FREE, w=64. (Prim-poly & 0xfffe000000000000ULL) must equal 0."; break;
-    case GF_E_MDEFDIV: s = "If multiplication method == default, can't change division."; break;
-    case GF_E_MDEFREG: s = "If multiplication method == default, can't change region."; break;
-    case GF_E_MDEFARG: s = "If multiplication method == default, can't use arg1/arg2."; break;
-    case GF_E_DIVCOMP: s = "Cannot change the division technique with -m COMPOSITE."; break;
-    case GF_E_DOUQUAD: s = "Cannot specify -r DOUBLE and -r QUAD."; break;
-    case GF_E_SIMD_NO: s = "Cannot specify -r SIMD and -r NOSIMD."; break;
-    case GF_E_CAUCHYB: s = "Cannot specify -r CAUCHY and any other -r."; break;
-    case GF_E_CAUCOMP: s = "Cannot specify -m COMPOSITE and -r CAUCHY."; break;
-    case GF_E_CAUGT32: s = "Cannot specify -r CAUCHY with w > 32."; break;
-    case GF_E_ARG1SET: s = "Only use arg1 with SPLIT, GROUP or COMPOSITE."; break;
-    case GF_E_ARG2SET: s = "Only use arg2 with SPLIT or GROUP."; break;
-    case GF_E_MATRIXW: s = "Cannot specify -d MATRIX with w > 32."; break;
-    case GF_E_BAD___W: s = "W must be 1-32, 64 or 128."; break;
-    case GF_E_DOUBLET: s = "Can only specify -r DOUBLE with -m TABLE."; break;
-    case GF_E_DOUBLEW: s = "Can only specify -r DOUBLE w = 4 or w = 8."; break;
-    case GF_E_DOUBLEJ: s = "Cannot specify -r DOUBLE with -r ALTMAP|SIMD|NOSIMD."; break;
-    case GF_E_DOUBLEL: s = "Can only specify -r DOUBLE -r LAZY with w = 8"; break;
-    case GF_E_QUAD__T: s = "Can only specify -r QUAD with -m TABLE."; break;
-    case GF_E_QUAD__W: s = "Can only specify -r QUAD w = 4."; break;
-    case GF_E_QUAD__J: s = "Cannot specify -r QUAD with -r ALTMAP|SIMD|NOSIMD."; break;
-    case GF_E_BADPOLY: s = "Bad primitive polynomial (high bits set)."; break;
-    case GF_E_COMP_PP: s = "Bad primitive polynomial -- bigger than sub-field."; break;
-    case GF_E_LAZY__X: s = "If -r LAZY, then -r must be DOUBLE or QUAD."; break;
-    case GF_E_ALTSHIF: s = "Cannot specify -m SHIFT and -r ALTMAP."; break;
-    case GF_E_SSESHIF: s = "Cannot specify -m SHIFT and -r SIMD|NOSIMD."; break;
-    case GF_E_ALT_CFM: s = "Cannot specify -m CARRY_FREE and -r ALTMAP."; break;
-    case GF_E_SSE_CFM: s = "Cannot specify -m CARRY_FREE and -r SIMD|NOSIMD."; break;
-    case GF_E_PCLMULX: s = "Specified -m CARRY_FREE, but PCLMUL is not supported."; break;
-    case GF_E_ALT_BY2: s = "Cannot specify -m BYTWO_x and -r ALTMAP."; break;
-    case GF_E_BY2_SSE: s = "Specified -m BYTWO_x -r SIMD, but SSE2 is not supported."; break;
-    case GF_E_LOGBADW: s = "With Log Tables, w must be <= 27."; break;
-    case GF_E_LOG___J: s = "Cannot use Log tables with -r ALTMAP|SIMD|NOSIMD."; break;
-    case GF_E_LOGPOLY: s = "Cannot use Log tables because the polynomial is not primitive."; break;
-    case GF_E_ZERBADW: s = "With -m LOG_ZERO, w must be 8 or 16."; break;
-    case GF_E_ZEXBADW: s = "With -m LOG_ZERO_EXT, w must be 8."; break;
-    case GF_E_GR_ARGX: s = "With -m GROUP, arg1 and arg2 must be >= 0."; break;
-    case GF_E_GR_W_48: s = "With -m GROUP, w cannot be 4 or 8."; break;
-    case GF_E_GR_W_16: s = "With -m GROUP, w == 16, arg1 and arg2 must be 4."; break;
-    case GF_E_GR_128A: s = "With -m GROUP, w == 128, arg1 must be 4, and arg2 in { 4,8,16 }."; break;
-    case GF_E_GR_A_27: s = "With -m GROUP, arg1 and arg2 must be <= 27."; break;
-    case GF_E_GR_AR_W: s = "With -m GROUP, arg1 and arg2 must be <= w."; break;
-    case GF_E_GR____J: s = "Cannot use GROUP with -r ALTMAP|SIMD|NOSIMD."; break;
-    case GF_E_TABLE_W: s = "With -m TABLE, w must be < 15, or == 16."; break;
-    case GF_E_TAB_SSE: s = "With -m TABLE, SIMD|NOSIMD only applies to w=4."; break;
-    case GF_E_TABSSE3: s = "With -m TABLE, -r SIMD, you need SSSE3 supported."; break;
-    case GF_E_TAB_ALT: s = "With -m TABLE, you cannot use ALTMAP."; break;
-    case GF_E_SP128AR: s = "With -m SPLIT, w=128, bad arg1/arg2."; break;
-    case GF_E_SP128AL: s = "With -m SPLIT, w=128, -r SIMD requires -r ALTMAP."; break;
-    case GF_E_SP128AS: s = "With -m SPLIT, w=128, ALTMAP needs SSSE3 supported."; break;
-    case GF_E_SP128_A: s = "With -m SPLIT, w=128, -r ALTMAP only with arg1/arg2 = 4/128."; break;
-    case GF_E_SP128_S: s = "With -m SPLIT, w=128, -r SIMD|NOSIMD only with arg1/arg2 = 4/128."; break;
-    case GF_E_SPLIT_W: s = "With -m SPLIT, w must be in {8, 16, 32, 64, 128}."; break;
-    case GF_E_SP_16AR: s = "With -m SPLIT, w=16, Bad arg1/arg2."; break;
-    case GF_E_SP_16_A: s = "With -m SPLIT, w=16, -r ALTMAP only with arg1/arg2 = 4/16."; break;
-    case GF_E_SP_16_S: s = "With -m SPLIT, w=16, -r SIMD|NOSIMD only with arg1/arg2 = 4/16."; break;
-    case GF_E_SP_32AR: s = "With -m SPLIT, w=32, Bad arg1/arg2."; break;
-    case GF_E_SP_32AS: s = "With -m SPLIT, w=32, -r ALTMAP needs SSSE3 supported."; break;
-    case GF_E_SP_32_A: s = "With -m SPLIT, w=32, -r ALTMAP only with arg1/arg2 = 4/32."; break;
-    case GF_E_SP_32_S: s = "With -m SPLIT, w=32, -r SIMD|NOSIMD only with arg1/arg2 = 4/32."; break;
-    case GF_E_SP_64AR: s = "With -m SPLIT, w=64, Bad arg1/arg2."; break;
-    case GF_E_SP_64AS: s = "With -m SPLIT, w=64, -r ALTMAP needs SSSE3 supported."; break;
-    case GF_E_SP_64_A: s = "With -m SPLIT, w=64, -r ALTMAP only with arg1/arg2 = 4/64."; break;
-    case GF_E_SP_64_S: s = "With -m SPLIT, w=64, -r SIMD|NOSIMD only with arg1/arg2 = 4/64."; break;
-    case GF_E_SP_8_AR: s = "With -m SPLIT, w=8, Bad arg1/arg2."; break;
-    case GF_E_SP_8__A: s = "With -m SPLIT, w=8, Can't have -r ALTMAP."; break;
-    case GF_E_SP_SSE3: s = "With -m SPLIT, Need SSSE3 support for SIMD."; break;
-    case GF_E_COMP_A2: s = "With -m COMPOSITE, arg1 must equal 2."; break;
-    case GF_E_COMP_SS: s = "With -m COMPOSITE, -r SIMD and -r NOSIMD do not apply."; break;
-    case GF_E_COMP__W: s = "With -m COMPOSITE, w must be 8, 16, 32, 64 or 128."; break;
-    case GF_E_UNKFLAG: s = "Unknown method flag - should be -m, -d, -r or -p."; break;
-    case GF_E_UNKNOWN: s = "Unknown multiplication type."; break;
-    case GF_E_UNK_REG: s = "Unknown region type."; break;
-    case GF_E_UNK_DIV: s = "Unknown division type."; break;
-    default: s = "Undefined error.";
-  }
-
-  fprintf(stderr, "%s\n", s);
-}
-
-uint64_t gf_composite_get_default_poly(gf_t *base) 
-{
-  gf_internal_t *h;
-  uint64_t rv;
-
-  h = (gf_internal_t *) base->scratch;
-  if (h->w == 4) {
-    if (h->mult_type == GF_MULT_COMPOSITE) return 0;
-    if (h->prim_poly == 0x13) return 2;
-    return 0;
-  } 
-  if (h->w == 8) {
-    if (h->mult_type == GF_MULT_COMPOSITE) return 0;
-    if (h->prim_poly == 0x11d) return 3;
-    return 0;
-  }
-  if (h->w == 16) {
-    if (h->mult_type == GF_MULT_COMPOSITE) {
-      rv = gf_composite_get_default_poly(h->base_gf);
-      if (rv != h->prim_poly) return 0;
-      if (rv == 3) return 0x105;
-      return 0;
-    } else {
-      if (h->prim_poly == 0x1100b) return 2;
-      if (h->prim_poly == 0x1002d) return 7;
-      return 0;
-    }
-  }
-  if (h->w == 32) {
-    if (h->mult_type == GF_MULT_COMPOSITE) {
-      rv = gf_composite_get_default_poly(h->base_gf);
-      if (rv != h->prim_poly) return 0;
-      if (rv == 2) return 0x10005;
-      if (rv == 7) return 0x10008;
-      if (rv == 0x105) return 0x10002;
-      return 0;
-    } else {
-      if (h->prim_poly == 0x400007) return 2;
-      if (h->prim_poly == 0xc5) return 3;
-      return 0;
-    }
-  }
-  if (h->w == 64) {
-    if (h->mult_type == GF_MULT_COMPOSITE) {
-      rv = gf_composite_get_default_poly(h->base_gf);
-      if (rv != h->prim_poly) return 0;
-      if (rv == 3) return 0x100000009ULL;
-      if (rv == 2) return 0x100000004ULL;
-      if (rv == 0x10005) return 0x100000003ULL;
-      if (rv == 0x10002) return 0x100000005ULL;
-      if (rv == 0x10008) return 0x100000006ULL;  /* JSP: (0x0x100000003 works too, 
-                                                    but I want to differentiate cases). */
-      return 0;
-    } else {
-      if (h->prim_poly == 0x1bULL) return 2;
-      return 0;
-    }
-  }
-  return 0;
-}
-
-int gf_error_check(int w, int mult_type, int region_type, int divide_type,
-                   int arg1, int arg2, uint64_t poly, gf_t *base)
-{
-  int sse3 = 0;
-  int sse2 = 0;
-  int pclmul = 0;
-  int rdouble, rquad, rlazy, rsimd, rnosimd, raltmap, rcauchy, tmp;
-  gf_internal_t *sub;
-
-  rdouble = (region_type & GF_REGION_DOUBLE_TABLE);
-  rquad   = (region_type & GF_REGION_QUAD_TABLE);
-  rlazy   = (region_type & GF_REGION_LAZY);
-  rsimd   = (region_type & GF_REGION_SIMD);
-  rnosimd = (region_type & GF_REGION_NOSIMD);
-  raltmap = (region_type & GF_REGION_ALTMAP);
-  rcauchy = (region_type & GF_REGION_CAUCHY);
-
-  if (divide_type != GF_DIVIDE_DEFAULT &&
-      divide_type != GF_DIVIDE_MATRIX && 
-      divide_type != GF_DIVIDE_EUCLID) {
-    _gf_errno = GF_E_UNK_DIV;
-    return 0;
-  }
-
-  tmp = ( GF_REGION_DOUBLE_TABLE | GF_REGION_QUAD_TABLE | GF_REGION_LAZY |
-          GF_REGION_SIMD | GF_REGION_NOSIMD | GF_REGION_ALTMAP |
-          GF_REGION_CAUCHY );
-  if (region_type & (~tmp)) { _gf_errno = GF_E_UNK_REG; return 0; }
-
-#ifdef INTEL_SSE2
-  sse2 = 1;
-#endif
-
-#ifdef INTEL_SSSE3
-  sse3 = 1;
-#endif
-
-#ifdef INTEL_SSE4_PCLMUL
-  pclmul = 1;
-#endif
-
-#ifdef ARM_NEON
-  pclmul = 1;
-  sse3 = 1;
-#endif
-
-
-  if (w < 1 || (w > 32 && w != 64 && w != 128)) { _gf_errno = GF_E_BAD___W; return 0; }
-    
-  if (mult_type != GF_MULT_COMPOSITE && w < 64) {
-    if ((poly >> (w+1)) != 0)                   { _gf_errno = GF_E_BADPOLY; return 0; }
-  }
-
-  if (mult_type == GF_MULT_DEFAULT) {
-    if (divide_type != GF_DIVIDE_DEFAULT) { _gf_errno = GF_E_MDEFDIV; return 0; }
-    if (region_type != GF_REGION_DEFAULT) { _gf_errno = GF_E_MDEFREG; return 0; }
-    if (arg1 != 0 || arg2 != 0)           { _gf_errno = GF_E_MDEFARG; return 0; }
-    return 1;
-  }
-  
-  if (rsimd && rnosimd)                              { _gf_errno = GF_E_SIMD_NO; return 0; }
-  if (rcauchy && w > 32)                             { _gf_errno = GF_E_CAUGT32; return 0; }
-  if (rcauchy && region_type != GF_REGION_CAUCHY)    { _gf_errno = GF_E_CAUCHYB; return 0; }
-  if (rcauchy && mult_type == GF_MULT_COMPOSITE)     { _gf_errno = GF_E_CAUCOMP; return 0; }
-
-  if (arg1 != 0 && mult_type != GF_MULT_COMPOSITE && 
-      mult_type != GF_MULT_SPLIT_TABLE && mult_type != GF_MULT_GROUP) {
-    _gf_errno = GF_E_ARG1SET;
-    return 0;
-  }
-
-  if (arg2 != 0 && mult_type != GF_MULT_SPLIT_TABLE && mult_type != GF_MULT_GROUP) {
-    _gf_errno = GF_E_ARG2SET;
-    return 0;
-  }
-
-  if (divide_type == GF_DIVIDE_MATRIX && w > 32) { _gf_errno = GF_E_MATRIXW; return 0; }
-
-  if (rdouble) {
-    if (rquad)                      { _gf_errno = GF_E_DOUQUAD; return 0; }
-    if (mult_type != GF_MULT_TABLE) { _gf_errno = GF_E_DOUBLET; return 0; }
-    if (w != 4 && w != 8)           { _gf_errno = GF_E_DOUBLEW; return 0; }
-    if (rsimd || rnosimd || raltmap) { _gf_errno = GF_E_DOUBLEJ; return 0; }
-    if (rlazy && w == 4)            { _gf_errno = GF_E_DOUBLEL; return 0; }
-    return 1;
-  }
-
-  if (rquad) {
-    if (mult_type != GF_MULT_TABLE) { _gf_errno = GF_E_QUAD__T; return 0; }
-    if (w != 4)                     { _gf_errno = GF_E_QUAD__W; return 0; }
-    if (rsimd || rnosimd || raltmap) { _gf_errno = GF_E_QUAD__J; return 0; }
-    return 1;
-  }
-
-  if (rlazy)                        { _gf_errno = GF_E_LAZY__X; return 0; }
-
-  if (mult_type == GF_MULT_SHIFT) {
-    if (raltmap)                    { _gf_errno = GF_E_ALTSHIF; return 0; }
-    if (rsimd || rnosimd)           { _gf_errno = GF_E_SSESHIF; return 0; }
-    return 1;
-  }
-
-  if (mult_type == GF_MULT_CARRY_FREE) {
-    if (w != 4 && w != 8 && w != 16 &&
-        w != 32 && w != 64 && w != 128)            { _gf_errno = GF_E_CFM___W; return 0; }
-    if (w == 4 && (poly & 0xc))                    { _gf_errno = GF_E_CFM4POL; return 0; }
-    if (w == 8 && (poly & 0x80))                   { _gf_errno = GF_E_CFM8POL; return 0; }
-    if (w == 16 && (poly & 0xe000))                { _gf_errno = GF_E_CF16POL; return 0; }
-    if (w == 32 && (poly & 0xfe000000))            { _gf_errno = GF_E_CF32POL; return 0; }
-    if (w == 64 && (poly & 0xfffe000000000000ULL)) { _gf_errno = GF_E_CF64POL; return 0; }
-    if (raltmap)                                   { _gf_errno = GF_E_ALT_CFM; return 0; }
-    if (rsimd || rnosimd)                          { _gf_errno = GF_E_SSE_CFM; return 0; }
-    if (!pclmul)                                   { _gf_errno = GF_E_PCLMULX; return 0; }
-    return 1;
-  }
-
-  if (mult_type == GF_MULT_CARRY_FREE_GK) {
-    if (w != 4 && w != 8 && w != 16 &&
-        w != 32 && w != 64 && w != 128)            { _gf_errno = GF_E_CFM___W; return 0; }
-    if (raltmap)                                   { _gf_errno = GF_E_ALT_CFM; return 0; }
-    if (rsimd || rnosimd)                          { _gf_errno = GF_E_SSE_CFM; return 0; }
-    if (!pclmul)                                   { _gf_errno = GF_E_PCLMULX; return 0; }
-    return 1;
-  }
-
-  if (mult_type == GF_MULT_BYTWO_p || mult_type == GF_MULT_BYTWO_b) {
-    if (raltmap)                    { _gf_errno = GF_E_ALT_BY2; return 0; }
-    if (rsimd && !sse2)              { _gf_errno = GF_E_BY2_SSE; return 0; }
-    return 1;
-  }
-
-  if (mult_type == GF_MULT_LOG_TABLE || mult_type == GF_MULT_LOG_ZERO
-                                     || mult_type == GF_MULT_LOG_ZERO_EXT ) {
-    if (w > 27)                     { _gf_errno = GF_E_LOGBADW; return 0; }
-    if (raltmap || rsimd || rnosimd) { _gf_errno = GF_E_LOG___J; return 0; }
-
-    if (mult_type == GF_MULT_LOG_TABLE) return 1;
-
-    if (w != 8 && w != 16)          { _gf_errno = GF_E_ZERBADW; return 0; }
-
-    if (mult_type == GF_MULT_LOG_ZERO) return 1;
-
-    if (w != 8)                     { _gf_errno = GF_E_ZEXBADW; return 0; }
-    return 1;
-  }
-
-  if (mult_type == GF_MULT_GROUP) {
-    if (arg1 <= 0 || arg2 <= 0)                 { _gf_errno = GF_E_GR_ARGX; return 0; }
-    if (w == 4 || w == 8)                       { _gf_errno = GF_E_GR_W_48; return 0; }
-    if (w == 16 && (arg1 != 4 || arg2 != 4))     { _gf_errno = GF_E_GR_W_16; return 0; }
-    if (w == 128 && (arg1 != 4 || 
-       (arg2 != 4 && arg2 != 8 && arg2 != 16))) { _gf_errno = GF_E_GR_128A; return 0; }
-    if (arg1 > 27 || arg2 > 27)                 { _gf_errno = GF_E_GR_A_27; return 0; }
-    if (arg1 > w || arg2 > w)                   { _gf_errno = GF_E_GR_AR_W; return 0; }
-    if (raltmap || rsimd || rnosimd)            { _gf_errno = GF_E_GR____J; return 0; }
-    return 1;
-  }
-  
-  if (mult_type == GF_MULT_TABLE) {
-    if (w != 16 && w >= 15)                     { _gf_errno = GF_E_TABLE_W; return 0; }
-    if (w != 4 && (rsimd || rnosimd))           { _gf_errno = GF_E_TAB_SSE; return 0; }
-    if (rsimd && !sse3)                         { _gf_errno = GF_E_TABSSE3; return 0; }
-    if (raltmap)                                { _gf_errno = GF_E_TAB_ALT; return 0; }
-    return 1;
-  }
-
-  if (mult_type == GF_MULT_SPLIT_TABLE) {
-    if (arg1 > arg2) {
-      tmp = arg1;
-      arg1 = arg2;
-      arg2 = tmp;
-    }
-    if (w == 8) {
-      if (arg1 != 4 || arg2 != 8)               { _gf_errno = GF_E_SP_8_AR; return 0; }
-      if (rsimd && !sse3)                       { _gf_errno = GF_E_SP_SSE3; return 0; }
-      if (raltmap)                              { _gf_errno = GF_E_SP_8__A; return 0; }
-    } else if (w == 16) {
-      if ((arg1 == 8 && arg2 == 8) ||
-          (arg1 == 8 && arg2 == 16)) {
-        if (rsimd || rnosimd)                   { _gf_errno = GF_E_SP_16_S; return 0; }
-        if (raltmap)                            { _gf_errno = GF_E_SP_16_A; return 0; }
-      } else if (arg1 == 4 && arg2 == 16) {
-        if (rsimd && !sse3)                     { _gf_errno = GF_E_SP_SSE3; return 0; }
-      } else                                    { _gf_errno = GF_E_SP_16AR; return 0; }
-    } else if (w == 32) {
-      if ((arg1 == 8 && arg2 == 8) ||
-          (arg1 == 8 && arg2 == 32) ||
-          (arg1 == 16 && arg2 == 32)) {
-        if (rsimd || rnosimd)                   { _gf_errno = GF_E_SP_32_S; return 0; }
-        if (raltmap)                            { _gf_errno = GF_E_SP_32_A; return 0; }
-      } else if (arg1 == 4 && arg2 == 32) {
-        if (rsimd && !sse3)                     { _gf_errno = GF_E_SP_SSE3; return 0; }
-        if (raltmap && !sse3)                   { _gf_errno = GF_E_SP_32AS; return 0; }
-        if (raltmap && rnosimd)                 { _gf_errno = GF_E_SP_32AS; return 0; }
-      } else                                    { _gf_errno = GF_E_SP_32AR; return 0; }
-    } else if (w == 64) {
-      if ((arg1 == 8 && arg2 == 8) ||
-          (arg1 == 8 && arg2 == 64) ||
-          (arg1 == 16 && arg2 == 64)) {
-        if (rsimd || rnosimd)                   { _gf_errno = GF_E_SP_64_S; return 0; }
-        if (raltmap)                            { _gf_errno = GF_E_SP_64_A; return 0; }
-      } else if (arg1 == 4 && arg2 == 64) {
-        if (rsimd && !sse3)                     { _gf_errno = GF_E_SP_SSE3; return 0; }
-        if (raltmap && !sse3)                   { _gf_errno = GF_E_SP_64AS; return 0; }
-        if (raltmap && rnosimd)                 { _gf_errno = GF_E_SP_64AS; return 0; }
-      } else                                    { _gf_errno = GF_E_SP_64AR; return 0; }
-    } else if (w == 128) {
-      if (arg1 == 8 && arg2 == 128) {
-        if (rsimd || rnosimd)                   { _gf_errno = GF_E_SP128_S; return 0; }
-        if (raltmap)                            { _gf_errno = GF_E_SP128_A; return 0; }
-      } else if (arg1 == 4 && arg2 == 128) {
-        if (rsimd && !sse3)                     { _gf_errno = GF_E_SP_SSE3; return 0; }
-        if (raltmap && !sse3)                   { _gf_errno = GF_E_SP128AS; return 0; }
-        if (raltmap && rnosimd)                 { _gf_errno = GF_E_SP128AS; return 0; }
-      } else                                    { _gf_errno = GF_E_SP128AR; return 0; }
-    } else                                      { _gf_errno = GF_E_SPLIT_W; return 0; }
-    return 1;
-  }
-
-  if (mult_type == GF_MULT_COMPOSITE) {
-    if (w != 8 && w != 16 && w != 32 
-               && w != 64 && w != 128)          { _gf_errno = GF_E_COMP__W; return 0; }
-    if (w < 128 && (poly >> (w/2)) != 0)                   { _gf_errno = GF_E_COMP_PP; return 0; }
-    if (divide_type != GF_DIVIDE_DEFAULT)       { _gf_errno = GF_E_DIVCOMP; return 0; }
-    if (arg1 != 2)                              { _gf_errno = GF_E_COMP_A2; return 0; }
-    if (rsimd || rnosimd)                       { _gf_errno = GF_E_COMP_SS; return 0; }
-    if (base != NULL) {
-      sub = (gf_internal_t *) base->scratch;
-      if (sub->w != w/2)                      { _gf_errno = GF_E_BASE__W; return 0; }
-      if (poly == 0) {
-        if (gf_composite_get_default_poly(base) == 0) { _gf_errno = GF_E_COMPXPP; return 0; }
-      }
-    }
-    return 1;
-  }
-
-  _gf_errno = GF_E_UNKNOWN; 
-  return 0;
-}
-
-int gf_scratch_size(int w, 
-                    int mult_type, 
-                    int region_type, 
-                    int divide_type, 
-                    int arg1, 
-                    int arg2)
-{
-  if (gf_error_check(w, mult_type, region_type, divide_type, arg1, arg2, 0, NULL) == 0) return 0;
-
-  switch(w) {
-    case 4: return gf_w4_scratch_size(mult_type, region_type, divide_type, arg1, arg2);
-    case 8: return gf_w8_scratch_size(mult_type, region_type, divide_type, arg1, arg2);
-    case 16: return gf_w16_scratch_size(mult_type, region_type, divide_type, arg1, arg2);
-    case 32: return gf_w32_scratch_size(mult_type, region_type, divide_type, arg1, arg2);
-    case 64: return gf_w64_scratch_size(mult_type, region_type, divide_type, arg1, arg2);
-    case 128: return gf_w128_scratch_size(mult_type, region_type, divide_type, arg1, arg2);
-    default: return gf_wgen_scratch_size(w, mult_type, region_type, divide_type, arg1, arg2);
-  }
-}
-
-extern int gf_size(gf_t *gf)
-{
-  gf_internal_t *h;
-  int s;
-
-  s = sizeof(gf_t);
-  h = (gf_internal_t *) gf->scratch;
-  s += gf_scratch_size(h->w, h->mult_type, h->region_type, h->divide_type, h->arg1, h->arg2);
-  if (h->mult_type == GF_MULT_COMPOSITE) s += gf_size(h->base_gf);
-  return s;
-}
-
-
-int gf_init_easy(gf_t *gf, int w)
-{
-  return gf_init_hard(gf, w, GF_MULT_DEFAULT, GF_REGION_DEFAULT, GF_DIVIDE_DEFAULT, 
-                      0, 0, 0, NULL, NULL);
-}
-
-/* Allen: What's going on here is this function is putting info into the
-       scratch mem of gf, and then calling the relevant REAL init
-       func for the word size.  Probably done this way to consolidate
-       those aspects of initialization that don't rely on word size,
-       and then take care of word-size-specific stuff. */
-
-int gf_init_hard(gf_t *gf, int w, int mult_type, 
-                        int region_type,
-                        int divide_type,
-                        uint64_t prim_poly,
-                        int arg1, int arg2,
-                        gf_t *base_gf,
-                        void *scratch_memory) 
-{
-  int sz;
-  gf_internal_t *h;
- 
-  if (gf_error_check(w, mult_type, region_type, divide_type, 
-                     arg1, arg2, prim_poly, base_gf) == 0) return 0;
-
-  sz = gf_scratch_size(w, mult_type, region_type, divide_type, arg1, arg2);
-  if (sz <= 0) return 0;  /* This shouldn't happen, as all errors should get caught
-                             in gf_error_check() */
-  
-  if (scratch_memory == NULL) {
-    h = (gf_internal_t *) malloc(sz);
-    h->free_me = 1;
-  } else {
-    h = scratch_memory;
-    h->free_me = 0;
-  }
-  gf->scratch = (void *) h;
-  h->mult_type = mult_type;
-  h->region_type = region_type;
-  h->divide_type = divide_type;
-  h->w = w;
-  h->prim_poly = prim_poly;
-  h->arg1 = arg1;
-  h->arg2 = arg2;
-  h->base_gf = base_gf;
-  h->private = (void *) gf->scratch;
-  h->private = (uint8_t *)h->private + (sizeof(gf_internal_t));
-  gf->extract_word.w32 = NULL;
-
-  switch(w) {
-    case 4: return gf_w4_init(gf);
-    case 8: return gf_w8_init(gf);
-    case 16: return gf_w16_init(gf);
-    case 32: return gf_w32_init(gf);
-    case 64: return gf_w64_init(gf);
-    case 128: return gf_w128_init(gf);
-    default: return gf_wgen_init(gf);
-  }
-}
-
-int gf_free(gf_t *gf, int recursive)
-{
-  gf_internal_t *h;
-
-  h = (gf_internal_t *) gf->scratch;
-  if (recursive && h->base_gf != NULL) {
-    gf_free(h->base_gf, 1);
-    free(h->base_gf);
-  }
-  if (h->free_me) free(h);
-  return 0; /* Making compiler happy */
-}
-
-void gf_alignment_error(char *s, int a)
-{
-  fprintf(stderr, "Alignment error in %s:\n", s);
-  fprintf(stderr, "   The source and destination buffers must be aligned to each other,\n");
-  fprintf(stderr, "   and they must be aligned to a %d-byte address.\n", a);
-  assert(0);
-}
-
-static 
-void gf_invert_binary_matrix(uint32_t *mat, uint32_t *inv, int rows) {
-  int cols, i, j;
-  uint32_t tmp;
-
-  cols = rows;
-
-  for (i = 0; i < rows; i++) inv[i] = (1 << i);
-
-  /* First -- convert into upper triangular */
-
-  for (i = 0; i < cols; i++) {
-
-    /* Swap rows if we ave a zero i,i element.  If we can't swap, then the
-       matrix was not invertible */
-
-    if ((mat[i] & (1 << i)) == 0) {
-      for (j = i+1; j < rows && (mat[j] & (1 << i)) == 0; j++) ;
-      if (j == rows) {
-        fprintf(stderr, "galois_invert_matrix: Matrix not invertible!!\n");
-        assert(0);
-      }
-      tmp = mat[i]; mat[i] = mat[j]; mat[j] = tmp;
-      tmp = inv[i]; inv[i] = inv[j]; inv[j] = tmp;
-    }
-
-    /* Now for each j>i, add A_ji*Ai to Aj */
-    for (j = i+1; j != rows; j++) {
-      if ((mat[j] & (1 << i)) != 0) {
-        mat[j] ^= mat[i];
-        inv[j] ^= inv[i];
-      }
-    }
-  }
-
-  /* Now the matrix is upper triangular.  Start at the top and multiply down */
-
-  for (i = rows-1; i >= 0; i--) {
-    for (j = 0; j < i; j++) {
-      if (mat[j] & (1 << i)) {
-        /*  mat[j] ^= mat[i]; */
-        inv[j] ^= inv[i];
-      }
-    }
-  }
-}
-
-uint32_t gf_bitmatrix_inverse(uint32_t y, int w, uint32_t pp) 
-{
-  uint32_t mat[32], inv[32], mask;
-  int i;
-
-  mask = (w == 32) ? 0xffffffff : ((uint32_t)1 << w) - 1;
-  for (i = 0; i < w; i++) {
-    mat[i] = y;
-
-    if (y & (1 << (w-1))) {
-      y = y << 1;
-      y = ((y ^ pp) & mask);
-    } else {
-      y = y << 1;
-    }
-  }
-
-  gf_invert_binary_matrix(mat, inv, w);
-  return inv[0];
-}
-
-void gf_two_byte_region_table_multiply(gf_region_data *rd, uint16_t *base)
-{
-  uint64_t a, prod;
-  int xor;
-  uint64_t *s64, *d64, *top;
-
-  s64 = rd->s_start;
-  d64 = rd->d_start;
-  top = rd->d_top;
-  xor = rd->xor;
-  
-  if (xor) {
-    while (d64 != top) {
-      a = *s64;
-      prod = base[a >> 48];
-      a <<= 16;
-      prod <<= 16;
-      prod ^= base[a >> 48];
-      a <<= 16;
-      prod <<= 16;
-      prod ^= base[a >> 48];
-      a <<= 16;
-      prod <<= 16;
-      prod ^= base[a >> 48];
-      prod ^= *d64;
-      *d64 = prod;
-      s64++;
-      d64++;
-    }
-  } else {
-    while (d64 != top) {
-      a = *s64;
-      prod = base[a >> 48];
-      a <<= 16;
-      prod <<= 16;
-      prod ^= base[a >> 48];
-      a <<= 16;
-      prod <<= 16;
-      prod ^= base[a >> 48];
-      a <<= 16;
-      prod <<= 16;
-      prod ^= base[a >> 48];
-      *d64 = prod;
-      s64++;
-      d64++;
-    }
-  }
-}
-
-static void gf_slow_multiply_region(gf_region_data *rd, void *src, void *dest, void *s_top)
-{
-  uint8_t *s8, *d8;
-  uint16_t *s16, *d16;
-  uint32_t *s32, *d32;
-  uint64_t *s64, *d64;
-  gf_internal_t *h;
-  int wb;
-  uint32_t p, a;
-
-  h = rd->gf->scratch;
-  wb = (h->w)/8;
-  if (wb == 0) wb = 1;
-  
-  while (src < s_top) {
-    switch (h->w) {
-    case 8:
-      s8 = (uint8_t *) src;
-      d8 = (uint8_t *) dest;
-      *d8 = (rd->xor) ? (*d8 ^ rd->gf->multiply.w32(rd->gf, rd->val, *s8)) : 
-                      rd->gf->multiply.w32(rd->gf, rd->val, *s8);
-      break;
-    case 4:
-      s8 = (uint8_t *) src;
-      d8 = (uint8_t *) dest;
-      a = *s8;
-      p = rd->gf->multiply.w32(rd->gf, rd->val, a&0xf);
-      p |= (rd->gf->multiply.w32(rd->gf, rd->val, a >> 4) << 4);
-      if (rd->xor) p ^= *d8;
-      *d8 = p;
-      break;
-    case 16:
-      s16 = (uint16_t *) src;
-      d16 = (uint16_t *) dest;
-      *d16 = (rd->xor) ? (*d16 ^ rd->gf->multiply.w32(rd->gf, rd->val, *s16)) : 
-                      rd->gf->multiply.w32(rd->gf, rd->val, *s16);
-      break;
-    case 32:
-      s32 = (uint32_t *) src;
-      d32 = (uint32_t *) dest;
-      *d32 = (rd->xor) ? (*d32 ^ rd->gf->multiply.w32(rd->gf, rd->val, *s32)) : 
-                      rd->gf->multiply.w32(rd->gf, rd->val, *s32);
-      break;
-    case 64:
-      s64 = (uint64_t *) src;
-      d64 = (uint64_t *) dest;
-      *d64 = (rd->xor) ? (*d64 ^ rd->gf->multiply.w64(rd->gf, rd->val, *s64)) : 
-                      rd->gf->multiply.w64(rd->gf, rd->val, *s64);
-      break;
-    default:
-      fprintf(stderr, "Error: gf_slow_multiply_region: w=%d not implemented.\n", h->w);
-      exit(1);
-    }
-    src = (uint8_t *)src + wb;
-    dest = (uint8_t *)dest + wb;
-  }
-}
-
-/* JSP - The purpose of this procedure is to error check alignment,
-   and to set up the region operation so that it can best leverage
-   large words.
-
-   It stores its information in rd.
-
-   Assuming you're not doing Cauchy coding, (see below for that),
-   then w will be 4, 8, 16, 32 or 64. It can't be 128 (probably
-   should change that).
-
-   src and dest must then be aligned on ceil(w/8)-byte boundaries.
-   Moreover, bytes must be a multiple of ceil(w/8).  If the variable
-   align is equal to ceil(w/8), then we will set s_start = src,
-   d_start = dest, s_top to (src+bytes) and d_top to (dest+bytes).
-   And we return -- the implementation will go ahead and do the
-   multiplication on individual words (e.g. using discrete logs).
-
-   If align is greater than ceil(w/8), then the implementation needs
-   to work on groups of "align" bytes.  For example, suppose you are
-   implementing BYTWO, without SSE. Then you will be doing the region
-   multiplication in units of 8 bytes, so align = 8. Or, suppose you
-   are doing a Quad table in GF(2^4). You will be doing the region
-   multiplication in units of 2 bytes, so align = 2. Or, suppose you
-   are doing split multiplication with SSE operations in GF(2^8).
-   Then align = 16. Worse yet, suppose you are doing split
-   multiplication with SSE operations in GF(2^16), with or without
-   ALTMAP. Then, you will be doing the multiplication on 256 bits at
-   a time.  So align = 32.
-
-   When align does not equal ceil(w/8), we split the region
-   multiplication into three parts.  We are going to make s_start be
-   the first address greater than or equal to src that is a multiple
-   of align.  s_top is going to be the largest address >= src+bytes
-   such that (s_top - s_start) is a multiple of align.  We do the
-   same with d_start and d_top.  When we say that "src and dest must
-   be aligned with respect to each other, we mean that s_start-src
-   must equal d_start-dest.
-
-   Now, the region multiplication is done in three parts -- the part
-   between src and s_start must be done using single words.
-   Similarly, the part between s_top and src+bytes must also be done
-   using single words.  The part between s_start and s_top will be
-   done in chunks of "align" bytes.
-
-   One final thing -- if align > 16, then s_start and d_start will be
-   aligned on a 16 byte boundary.  Perhaps we should have two
-   variables: align and chunksize.  Then we'd have s_start & d_start
-   aligned to "align", and have s_top-s_start be a multiple of
-   chunksize.  That may be less confusing, but it would be a big
-   change.
-
-   Finally, if align = -1, then we are doing Cauchy multiplication,
-   using only XOR's.  In this case, we're not going to care about
-   alignment because we are just doing XOR's.  Instead, the only
-   thing we care about is that bytes must be a multiple of w.
-
-   This is not to say that alignment doesn't matter in performance
-   with XOR's.  See that discussion in gf_multby_one().
-
-   After you call gf_set_region_data(), the procedure
-   gf_do_initial_region_alignment() calls gf->multiply.w32() on
-   everything between src and s_start.  The procedure
-   gf_do_final_region_alignment() calls gf->multiply.w32() on
-   everything between s_top and src+bytes.
-   */
-
-void gf_set_region_data(gf_region_data *rd,
-  gf_t *gf,
-  void *src,
-  void *dest,
-  int bytes,
-  uint64_t val,
-  int xor,
-  int align)
-{
-  gf_internal_t *h = NULL;
-  int wb;
-  uint32_t a;
-  unsigned long uls, uld;
-
-  if (gf == NULL) {  /* JSP - Can be NULL if you're just doing XOR's */
-    wb = 1;
-  } else {
-    h = gf->scratch;
-    wb = (h->w)/8;
-    if (wb == 0) wb = 1;
-  }
-  
-  rd->gf = gf;
-  rd->src = src;
-  rd->dest = dest;
-  rd->bytes = bytes;
-  rd->val = val;
-  rd->xor = xor;
-  rd->align = align;
-
-  uls = (unsigned long) src;
-  uld = (unsigned long) dest;
-
-  a = (align <= 16) ? align : 16;
-
-  if (align == -1) { /* JSP: This is cauchy.  Error check bytes, then set up the pointers
-                        so that there are no alignment regions. */
-    if (h != NULL && bytes % h->w != 0) {
-      fprintf(stderr, "Error in region multiply operation.\n");
-      fprintf(stderr, "The size must be a multiple of %d bytes.\n", h->w);
-      assert(0);
-    }
-  
-    rd->s_start = src;
-    rd->d_start = dest;
-    rd->s_top = (uint8_t *)src + bytes;
-    rd->d_top = (uint8_t *)src + bytes;
-    return;
-  }
-
-  if (uls % a != uld % a) {
-    fprintf(stderr, "Error in region multiply operation.\n");
-    fprintf(stderr, "The source & destination pointers must be aligned with respect\n");
-    fprintf(stderr, "to each other along a %d byte boundary.\n", a);
-    fprintf(stderr, "Src = 0x%lx.  Dest = 0x%lx\n", (unsigned long) src,
-            (unsigned long) dest);
-    assert(0);
-  }
-
-  if (uls % wb != 0) {
-    fprintf(stderr, "Error in region multiply operation.\n");
-    fprintf(stderr, "The pointers must be aligned along a %d byte boundary.\n", wb);
-    fprintf(stderr, "Src = 0x%lx.  Dest = 0x%lx\n", (unsigned long) src,
-            (unsigned long) dest);
-    assert(0);
-  }
-
-  if (bytes % wb != 0) {
-    fprintf(stderr, "Error in region multiply operation.\n");
-    fprintf(stderr, "The size must be a multiple of %d bytes.\n", wb);
-    assert(0);
-  }
-
-  uls %= a;
-  if (uls != 0) uls = (a-uls);
-  rd->s_start = (uint8_t *)rd->src + uls;
-  rd->d_start = (uint8_t *)rd->dest + uls;
-  bytes -= uls;
-  bytes -= (bytes % align);
-  rd->s_top = (uint8_t *)rd->s_start + bytes;
-  rd->d_top = (uint8_t *)rd->d_start + bytes;
-
-}
-
-void gf_do_initial_region_alignment(gf_region_data *rd)
-{
-  gf_slow_multiply_region(rd, rd->src, rd->dest, rd->s_start);
-}
-
-void gf_do_final_region_alignment(gf_region_data *rd)
-{
-  gf_slow_multiply_region(rd, rd->s_top, rd->d_top, (uint8_t *)rd->src+rd->bytes);
-}
-
-void gf_multby_zero(void *dest, int bytes, int xor) 
-{
-  if (xor) return;
-  bzero(dest, bytes);
-  return;
-}
-
-/* JSP - gf_multby_one tries to do this in the most efficient way
-   possible.  If xor = 0, then simply call memcpy() since that
-   should be optimized by the system.  Otherwise, try to do the xor
-   in the following order:
-
-   If src and dest are aligned with respect to each other on 16-byte
-   boundaries and you have SSE instructions, then use aligned SSE
-   instructions.
-
-   If they aren't but you still have SSE instructions, use unaligned
-   SSE instructions.
-
-   If there are no SSE instructions, but they are aligned with
-   respect to each other on 8-byte boundaries, then do them with
-   uint64_t's.
-
-   Otherwise, call gf_unaligned_xor(), which does the following:
-   align a destination pointer along an 8-byte boundary, and then
-   memcpy 32 bytes at a time from the src pointer to an array of
-   doubles.  I'm not sure if that's the best -- probably needs
-   testing, but this seems like it could be a black hole.
- */
-
-static void gf_unaligned_xor(void *src, void *dest, int bytes);
-
-void gf_multby_one(void *src, void *dest, int bytes, int xor) 
-{
-#ifdef   INTEL_SSE2
-  __m128i ms, md;
-#endif
-  unsigned long uls, uld;
-  uint8_t *s8, *d8;
-  uint64_t *s64, *d64, *dtop64;
-  gf_region_data rd;
-
-  if (!xor) {
-    memcpy(dest, src, bytes);
-    return;
-  }
-  uls = (unsigned long) src;
-  uld = (unsigned long) dest;
-
-#ifdef   INTEL_SSE2
-  int abytes;
-  s8 = (uint8_t *) src;
-  d8 = (uint8_t *) dest;
-  if (uls % 16 == uld % 16) {
-    gf_set_region_data(&rd, NULL, src, dest, bytes, 1, xor, 16);
-    while (s8 != rd.s_start) {
-      *d8 ^= *s8;
-      d8++;
-      s8++;
-    }
-    while (s8 < (uint8_t *) rd.s_top) {
-      ms = _mm_load_si128 ((__m128i *)(s8));
-      md = _mm_load_si128 ((__m128i *)(d8));
-      md = _mm_xor_si128(md, ms);
-      _mm_store_si128((__m128i *)(d8), md);
-      s8 += 16;
-      d8 += 16;
-    }
-    while (s8 != (uint8_t *) src + bytes) {
-      *d8 ^= *s8;
-      d8++;
-      s8++;
-    }
-    return;
-  }
-
-  abytes = (bytes & 0xfffffff0);
-
-  while (d8 < (uint8_t *) dest + abytes) {
-    ms = _mm_loadu_si128 ((__m128i *)(s8));
-    md = _mm_loadu_si128 ((__m128i *)(d8));
-    md = _mm_xor_si128(md, ms);
-    _mm_storeu_si128((__m128i *)(d8), md);
-    s8 += 16;
-    d8 += 16;
-  }
-  while (d8 != (uint8_t *) dest+bytes) {
-    *d8 ^= *s8;
-    d8++;
-    s8++;
-  }
-  return;
-#endif
-#if defined(ARM_NEON)
-  s8 = (uint8_t *) src;
-  d8 = (uint8_t *) dest;
-
-  if (uls % 16 == uld % 16) {
-    gf_set_region_data(&rd, NULL, src, dest, bytes, 1, xor, 16);
-    while (s8 != rd.s_start) {
-      *d8 ^= *s8;
-      s8++;
-      d8++;
-    }
-    while (s8 < (uint8_t *) rd.s_top) {
-      uint8x16_t vs = vld1q_u8 (s8);
-      uint8x16_t vd = vld1q_u8 (d8);
-      uint8x16_t vr = veorq_u8 (vs, vd);
-      vst1q_u8 (d8, vr);
-      s8 += 16;
-      d8 += 16;
-    }
-  } else {
-    while (s8 + 15 < (uint8_t *) src + bytes) {
-      uint8x16_t vs = vld1q_u8 (s8);
-      uint8x16_t vd = vld1q_u8 (d8);
-      uint8x16_t vr = veorq_u8 (vs, vd);
-      vst1q_u8 (d8, vr);
-      s8 += 16;
-      d8 += 16;
-    }
-  }
-  while (s8 < (uint8_t *) src + bytes) {
-    *d8 ^= *s8;
-    s8++;
-    d8++;
-  }
-  return;
-#endif
-  if (uls % 8 != uld % 8) {
-    gf_unaligned_xor(src, dest, bytes);
-    return;
-  }
-  
-  gf_set_region_data(&rd, NULL, src, dest, bytes, 1, xor, 8);
-  s8 = (uint8_t *) src;
-  d8 = (uint8_t *) dest;
-  while (d8 != rd.d_start) {
-    *d8 ^= *s8;
-    d8++;
-    s8++;
-  }
-  dtop64 = (uint64_t *) rd.d_top;
-
-  d64 = (uint64_t *) rd.d_start;
-  s64 = (uint64_t *) rd.s_start;
-
-  while (d64 < dtop64) {
-    *d64 ^= *s64;
-    d64++;
-    s64++;
-  }
-
-  s8 = (uint8_t *) rd.s_top;
-  d8 = (uint8_t *) rd.d_top;
-
-  while (d8 != (uint8_t *) dest+bytes) {
-    *d8 ^= *s8;
-    d8++;
-    s8++;
-  }
-  return;
-}
-
-#define UNALIGNED_BUFSIZE (8)
-
-static void gf_unaligned_xor(void *src, void *dest, int bytes)
-{
-  uint64_t scopy[UNALIGNED_BUFSIZE], *d64;
-  int i;
-  gf_region_data rd;
-  uint8_t *s8, *d8;
-
-  /* JSP - call gf_set_region_data(), but use dest in both places.  This is
-     because I only want to set up dest.  If I used src, gf_set_region_data()
-     would fail because src and dest are not aligned to each other wrt 
-     8-byte pointers.  I know this will actually align d_start to 16 bytes.
-     If I change gf_set_region_data() to split alignment & chunksize, then 
-     I could do this correctly. */
-
-  gf_set_region_data(&rd, NULL, dest, dest, bytes, 1, 1, 8*UNALIGNED_BUFSIZE);
-  s8 = (uint8_t *) src;
-  d8 = (uint8_t *) dest;
-
-  while (d8 < (uint8_t *) rd.d_start) {
-    *d8 ^= *s8;
-    d8++;
-    s8++;
-  }
-  
-  d64 = (uint64_t *) d8;
-  while (d64 < (uint64_t *) rd.d_top) {
-    memcpy(scopy, s8, 8*UNALIGNED_BUFSIZE);
-    s8 += 8*UNALIGNED_BUFSIZE;
-    for (i = 0; i < UNALIGNED_BUFSIZE; i++) {
-      *d64 ^= scopy[i];
-      d64++;
-    }
-  }
-  
-  d8 = (uint8_t *) d64;
-  while (d8 < (uint8_t *) ((uint8_t *)dest+bytes)) {
-    *d8 ^= *s8;
-    d8++;
-    s8++;
-  }
-}
diff --git a/src/erasure-code/jerasure/gf-complete/src/gf_general.c b/src/erasure-code/jerasure/gf-complete/src/gf_general.c
deleted file mode 100644
index 7f187b5..0000000
--- a/src/erasure-code/jerasure/gf-complete/src/gf_general.c
+++ /dev/null
@@ -1,539 +0,0 @@
-/*
- * GF-Complete: A Comprehensive Open Source Library for Galois Field Arithmetic
- * James S. Plank, Ethan L. Miller, Kevin M. Greenan,
- * Benjamin A. Arnold, John A. Burnum, Adam W. Disney, Allen C. McBride.
- *
- * gf_general.c
- *
- * This file has helper routines for doing basic GF operations with any
- * legal value of w.  The problem is that w <= 32, w=64 and w=128 all have
- * different data types, which is a pain.  The procedures in this file try
- * to alleviate that pain.  They are used in gf_unit and gf_time.
- */
-
-#include <stdio.h>
-#include <getopt.h>
-#include <stdint.h>
-#include <string.h>
-#include <stdlib.h>
-#include <time.h>
-#include <assert.h>
-
-#include "gf_complete.h"
-#include "gf_int.h"
-#include "gf_method.h"
-#include "gf_rand.h"
-#include "gf_general.h"
-
-void gf_general_set_zero(gf_general_t *v, int w)
-{
-  if (w <= 32) {
-    v->w32 = 0;
-  } else if (w <= 64) {
-    v->w64 = 0;
-  } else {
-    v->w128[0] = 0;
-    v->w128[1] = 0;
-  }
-}
-
-void gf_general_set_one(gf_general_t *v, int w)
-{
-  if (w <= 32) {
-    v->w32 = 1;
-  } else if (w <= 64) {
-    v->w64 = 1;
-  } else {
-    v->w128[0] = 0;
-    v->w128[1] = 1;
-  }
-}
-
-void gf_general_set_two(gf_general_t *v, int w)
-{
-  if (w <= 32) {
-    v->w32 = 2;
-  } else if (w <= 64) {
-    v->w64 = 2;
-  } else {
-    v->w128[0] = 0;
-    v->w128[1] = 2;
-  }
-}
-
-int gf_general_is_zero(gf_general_t *v, int w) 
-{
-  if (w <= 32) {
-    return (v->w32 == 0);
-  } else if (w <= 64) {
-    return (v->w64 == 0);
-  } else {
-    return (v->w128[0] == 0 && v->w128[1] == 0);
-  }
-}
-
-int gf_general_is_one(gf_general_t *v, int w) 
-{
-  if (w <= 32) {
-    return (v->w32 == 1);
-  } else if (w <= 64) {
-    return (v->w64 == 1);
-  } else {
-    return (v->w128[0] == 0 && v->w128[1] == 1);
-  }
-}
-
-void gf_general_set_random(gf_general_t *v, int w, int zero_ok) 
-{
-  if (w <= 32) {
-      v->w32 = MOA_Random_W(w, zero_ok);
-  } else if (w <= 64) {
-    while (1) {
-      v->w64 = MOA_Random_64();
-      if (v->w64 != 0 || zero_ok) return;
-    }
-  } else {
-    while (1) {
-      MOA_Random_128(v->w128);
-      if (v->w128[0] != 0 || v->w128[1] != 0 || zero_ok) return;
-    }
-  }
-}
-
-void gf_general_val_to_s(gf_general_t *v, int w, char *s, int hex)
-{
-  if (w <= 32) {
-    if (hex) {
-      sprintf(s, "%x", v->w32);
-    } else {
-      sprintf(s, "%u", v->w32);
-    }
-  } else if (w <= 64) {
-    if (hex) {
-      sprintf(s, "%llx", (long long unsigned int) v->w64);
-    } else {
-      sprintf(s, "%lld", (long long unsigned int) v->w64);
-    }
-  } else {
-    if (v->w128[0] == 0) {
-      sprintf(s, "%llx", (long long unsigned int) v->w128[1]);
-    } else {
-      sprintf(s, "%llx%016llx", (long long unsigned int) v->w128[0], 
-                                (long long unsigned int) v->w128[1]);
-    }
-  }
-}
-
-int gf_general_s_to_val(gf_general_t *v, int w, char *s, int hex)
-{
-  int l;
-  int save;
-
-  if (w <= 32) {
-    if (hex) {
-      if (sscanf(s, "%x", &(v->w32)) == 0) return 0;
-    } else {
-      if (sscanf(s, "%u", &(v->w32)) == 0) return 0;
-    }
-    if (w == 32) return 1;
-    if (w == 31) {
-      if (v->w32 & (1 << 31)) return 0;
-      return 1;
-    } 
-    if (v->w32 & ~((1 << w)-1)) return 0;
-    return 1;
-  } else if (w <= 64) {
-    if (hex) return (sscanf(s, "%llx", (long long unsigned int *) (&(v->w64))) == 1);
-    return (sscanf(s, "%lld", (long long int *) (&(v->w64))) == 1);
-  } else {
-    if (!hex) return 0;
-    l = strlen(s);
-    if (l <= 16) {
-      v->w128[0] = 0;
-      return (sscanf(s, "%llx", (long long unsigned int *) (&(v->w128[1]))) == 1);
-    } else {
-      if (l > 32) return 0;
-      save = s[l-16];
-      s[l-16] = '\0';
-      if (sscanf(s, "%llx", (long long unsigned int *) (&(v->w128[0]))) == 0) {
-        s[l-16] = save;
-        return 0;
-      }
-      return (sscanf(s+(l-16), "%llx", (long long unsigned int *) (&(v->w128[1]))) == 1);
-    }
-  }
-}
-    
-void gf_general_add(gf_t *gf, gf_general_t *a, gf_general_t *b, gf_general_t *c)
-{
-  gf_internal_t *h;
-  int w;
-
-  h = (gf_internal_t *) gf->scratch;
-  w = h->w;
-
-  if (w <= 32) {
-    c->w32 = a->w32 ^ b->w32;
-  } else if (w <= 64) {
-    c->w64 = a->w64 ^ b->w64;
-  } else {
-    c->w128[0] = a->w128[0] ^ b->w128[0];
-    c->w128[1] = a->w128[1] ^ b->w128[1];
-  }
-}
-  
-void gf_general_multiply(gf_t *gf, gf_general_t *a, gf_general_t *b, gf_general_t *c)
-{
-  gf_internal_t *h;
-  int w;
-
-  h = (gf_internal_t *) gf->scratch;
-  w = h->w;
-
-  if (w <= 32) {
-    c->w32 = gf->multiply.w32(gf, a->w32, b->w32);
-  } else if (w <= 64) {
-    c->w64 = gf->multiply.w64(gf, a->w64, b->w64);
-  } else {
-    gf->multiply.w128(gf, a->w128, b->w128, c->w128);
-  }
-}
-  
-void gf_general_divide(gf_t *gf, gf_general_t *a, gf_general_t *b, gf_general_t *c)
-{
-  gf_internal_t *h;
-  int w;
-
-  h = (gf_internal_t *) gf->scratch;
-  w = h->w;
-
-  if (w <= 32) {
-    c->w32 = gf->divide.w32(gf, a->w32, b->w32);
-  } else if (w <= 64) {
-    c->w64 = gf->divide.w64(gf, a->w64, b->w64);
-  } else {
-    gf->divide.w128(gf, a->w128, b->w128, c->w128);
-  }
-}
-  
-void gf_general_inverse(gf_t *gf, gf_general_t *a, gf_general_t *b)
-{
-  gf_internal_t *h;
-  int w;
-
-  h = (gf_internal_t *) gf->scratch;
-  w = h->w;
-
-  if (w <= 32) {
-    b->w32 = gf->inverse.w32(gf, a->w32);
-  } else if (w <= 64) {
-    b->w64 = gf->inverse.w64(gf, a->w64);
-  } else {
-    gf->inverse.w128(gf, a->w128, b->w128);
-  }
-}
-  
-int gf_general_are_equal(gf_general_t *v1, gf_general_t *v2, int w)
-{
-  if (w <= 32) {
-    return (v1->w32 == v2->w32);
-  } else if (w <= 64) {
-    return (v1->w64 == v2->w64);
-  } else {
-    return (v1->w128[0] == v2->w128[0] &&
-            v1->w128[1] == v2->w128[1]);
-  }
-}
-
-void gf_general_do_region_multiply(gf_t *gf, gf_general_t *a, void *ra, void *rb, int bytes, int xor)
-{
-  gf_internal_t *h;
-  int w;
-
-  h = (gf_internal_t *) gf->scratch;
-  w = h->w;
-
-  if (w <= 32) {
-    gf->multiply_region.w32(gf, ra, rb, a->w32, bytes, xor);
-  } else if (w <= 64) {
-    gf->multiply_region.w64(gf, ra, rb, a->w64, bytes, xor);
-  } else {
-    gf->multiply_region.w128(gf, ra, rb, a->w128, bytes, xor);
-  }
-}
-
-void gf_general_do_region_check(gf_t *gf, gf_general_t *a, void *orig_a, void *orig_target, void *final_target, int bytes, int xor)
-{
-  gf_internal_t *h;
-  int w, words, i;
-  gf_general_t oa, ot, ft, sb;
-  char sa[50], soa[50], sot[50], sft[50], ssb[50];
-
-  h = (gf_internal_t *) gf->scratch;
-  w = h->w;
-
-  words = (bytes * 8) / w;
-  for (i = 0; i < words; i++) {
-    if (w <= 32) {
-      oa.w32 = gf->extract_word.w32(gf, orig_a, bytes, i);
-      ot.w32 = gf->extract_word.w32(gf, orig_target, bytes, i);
-      ft.w32 = gf->extract_word.w32(gf, final_target, bytes, i);
-      sb.w32 = gf->multiply.w32(gf, a->w32, oa.w32);
-      if (xor) sb.w32 ^= ot.w32;
-    } else if (w <= 64) {
-      oa.w64 = gf->extract_word.w64(gf, orig_a, bytes, i);
-      ot.w64 = gf->extract_word.w64(gf, orig_target, bytes, i);
-      ft.w64 = gf->extract_word.w64(gf, final_target, bytes, i);
-      sb.w64 = gf->multiply.w64(gf, a->w64, oa.w64);
-      if (xor) sb.w64 ^= ot.w64;
-    } else {
-      gf->extract_word.w128(gf, orig_a, bytes, i, oa.w128);
-      gf->extract_word.w128(gf, orig_target, bytes, i, ot.w128);
-      gf->extract_word.w128(gf, final_target, bytes, i, ft.w128);
-      gf->multiply.w128(gf, a->w128, oa.w128, sb.w128);
-      if (xor) {
-        sb.w128[0] ^= ot.w128[0];
-        sb.w128[1] ^= ot.w128[1];
-      }
-    }
-
-    if (!gf_general_are_equal(&ft, &sb, w)) {
-      
-      fprintf(stderr,"Problem with region multiply (all values in hex):\n");
-      fprintf(stderr,"   Target address base: 0x%lx.  Word 0x%x of 0x%x.  Xor: %d\n", 
-                 (unsigned long) final_target, i, words, xor);
-      gf_general_val_to_s(a, w, sa, 1);
-      gf_general_val_to_s(&oa, w, soa, 1);
-      gf_general_val_to_s(&ot, w, sot, 1);
-      gf_general_val_to_s(&ft, w, sft, 1);
-      gf_general_val_to_s(&sb, w, ssb, 1);
-      fprintf(stderr,"   Value: %s\n", sa);
-      fprintf(stderr,"   Original source word: %s\n", soa);
-      if (xor) fprintf(stderr,"   XOR with target word: %s\n", sot);
-      fprintf(stderr,"   Product word: %s\n", sft);
-      fprintf(stderr,"   It should be: %s\n", ssb);
-      assert(0);
-    }
-  }
-}
-
-void gf_general_set_up_single_timing_test(int w, void *ra, void *rb, int size)
-{
-  void *top;
-  gf_general_t g;
-  uint8_t *r8, *r8a;
-  uint16_t *r16;
-  uint32_t *r32;
-  uint64_t *r64;
-  int i;
-
-  top = (uint8_t *)rb+size;
-
-  /* If w is 8, 16, 32, 64 or 128, fill the regions with random bytes.
-     However, don't allow for zeros in rb, because that will screw up
-     division.
-     
-     When w is 4, you fill the regions with random 4-bit words in each byte.
-
-     Otherwise, treat every four bytes as an uint32_t
-     and fill it with a random value mod (1 << w).
-   */
-
-  if (w == 8 || w == 16 || w == 32 || w == 64 || w == 128) {
-    MOA_Fill_Random_Region (ra, size);
-    while (rb < top) {
-      gf_general_set_random(&g, w, 0);
-      switch (w) {
-        case 8: 
-          r8 = (uint8_t *) rb;
-          *r8 = g.w32;
-          break;
-        case 16: 
-          r16 = (uint16_t *) rb;
-          *r16 = g.w32;
-          break;
-        case 32: 
-          r32 = (uint32_t *) rb;
-          *r32 = g.w32;
-          break;
-        case 64:
-          r64 = (uint64_t *) rb;
-          *r64 = g.w64;
-          break;
-        case 128: 
-          r64 = (uint64_t *) rb;
-          r64[0] = g.w128[0];
-          r64[1] = g.w128[1];
-          break;
-      }
-      rb = (uint8_t *)rb + (w/8);
-    }
-  } else if (w == 4) {
-    r8a = (uint8_t *) ra;
-    r8 = (uint8_t *) rb;
-    while (r8 < (uint8_t *) top) {
-      gf_general_set_random(&g, w, 1);
-      *r8a = g.w32;
-      gf_general_set_random(&g, w, 0);
-      *r8 = g.w32;
-      r8a++;
-      r8++;
-    }
-  } else {
-    r32 = (uint32_t *) ra;
-    for (i = 0; i < size/4; i++) r32[i] = MOA_Random_W(w, 1);
-    r32 = (uint32_t *) rb;
-    for (i = 0; i < size/4; i++) r32[i] = MOA_Random_W(w, 0);
-  }
-}
-
-/* This sucks, but in order to time, you really need to avoid putting ifs in 
-   the inner loops.  So, I'm doing a separate timing test for each w: 
-   (4 & 8), 16, 32, 64, 128 and everything else.  Fortunately, the "everything else"
-   tests can be equivalent to w=32.
-
-   I'm also putting the results back into ra, because otherwise, the optimizer might
-   figure out that we're not really doing anything in the inner loops and it 
-   will chuck that. */
-
-int gf_general_do_single_timing_test(gf_t *gf, void *ra, void *rb, int size, char test)
-{
-  gf_internal_t *h;
-  void *top;
-  uint8_t *r8a, *r8b, *top8;
-  uint16_t *r16a, *r16b, *top16;
-  uint32_t *r32a, *r32b, *top32;
-  uint64_t *r64a, *r64b, *top64, *r64c;
-  int w, rv;
-
-  h = (gf_internal_t *) gf->scratch;
-  w = h->w;
-  top = (uint8_t *)ra + size;
-
-  if (w == 8 || w == 4) {
-    r8a = (uint8_t *) ra; 
-    r8b = (uint8_t *) rb; 
-    top8 = (uint8_t *) top;
-    if (test == 'M') {
-      while (r8a < top8) {
-        *r8a = gf->multiply.w32(gf, *r8a, *r8b);
-        r8a++;
-        r8b++;
-      }
-    } else if (test == 'D') {
-      while (r8a < top8) {
-        *r8a = gf->divide.w32(gf, *r8a, *r8b);
-        r8a++;
-        r8b++;
-      }
-    } else if (test == 'I') {
-      while (r8a < top8) {
-        *r8a = gf->inverse.w32(gf, *r8a);
-        r8a++;
-      }
-    }
-    return (top8 - (uint8_t *) ra);
-  }
-
-  if (w == 16) {
-    r16a = (uint16_t *) ra; 
-    r16b = (uint16_t *) rb; 
-    top16 = (uint16_t *) top;
-    if (test == 'M') {
-      while (r16a < top16) {
-        *r16a = gf->multiply.w32(gf, *r16a, *r16b);
-        r16a++;
-        r16b++;
-      }
-    } else if (test == 'D') {
-      while (r16a < top16) {
-        *r16a = gf->divide.w32(gf, *r16a, *r16b);
-        r16a++;
-        r16b++;
-      }
-    } else if (test == 'I') {
-      while (r16a < top16) {
-        *r16a = gf->inverse.w32(gf, *r16a);
-        r16a++;
-      }
-    }
-    return (top16 - (uint16_t *) ra);
-  }
-  if (w <= 32) {
-    r32a = (uint32_t *) ra; 
-    r32b = (uint32_t *) rb; 
-    top32 = (uint32_t *) ra + (size/4); /* This is for the "everything elses" */
-    
-    if (test == 'M') {
-      while (r32a < top32) {
-        *r32a = gf->multiply.w32(gf, *r32a, *r32b);
-        r32a++;
-        r32b++;
-      }
-    } else if (test == 'D') {
-      while (r32a < top32) {
-        *r32a = gf->divide.w32(gf, *r32a, *r32b);
-        r32a++;
-        r32b++;
-      }
-    } else if (test == 'I') {
-      while (r32a < top32) {
-        *r32a = gf->inverse.w32(gf, *r32a);
-        r32a++;
-      }
-    }
-    return (top32 - (uint32_t *) ra);
-  }
-  if (w == 64) {
-    r64a = (uint64_t *) ra; 
-    r64b = (uint64_t *) rb; 
-    top64 = (uint64_t *) top;
-    if (test == 'M') {
-      while (r64a < top64) {
-        *r64a = gf->multiply.w64(gf, *r64a, *r64b);
-        r64a++;
-        r64b++;
-      }
-    } else if (test == 'D') {
-      while (r64a < top64) {
-        *r64a = gf->divide.w64(gf, *r64a, *r64b);
-        r64a++;
-        r64b++;
-      }
-    } else if (test == 'I') {
-      while (r64a < top64) {
-        *r64a = gf->inverse.w64(gf, *r64a);
-        r64a++;
-      }
-    }
-    return (top64 - (uint64_t *) ra);
-  }
-  if (w == 128) {
-    r64a = (uint64_t *) ra; 
-    r64c = r64a;
-    r64a += 2;
-    r64b = (uint64_t *) rb; 
-    top64 = (uint64_t *) top;
-    rv = (top64 - r64a)/2;
-    if (test == 'M') {
-      while (r64a < top64) {
-        gf->multiply.w128(gf, r64a, r64b, r64c);
-        r64a += 2;
-        r64b += 2;
-      }
-    } else if (test == 'D') {
-      while (r64a < top64) {
-        gf->divide.w128(gf, r64a, r64b, r64c);
-        r64a += 2;
-        r64b += 2;
-      }
-    } else if (test == 'I') {
-      while (r64a < top64) {
-        gf->inverse.w128(gf, r64a, r64c);
-        r64a += 2;
-      }
-    }
-    return rv;
-  }
-  return 0;
-}
diff --git a/src/erasure-code/jerasure/gf-complete/src/gf_method.c b/src/erasure-code/jerasure/gf-complete/src/gf_method.c
deleted file mode 100644
index 2210305..0000000
--- a/src/erasure-code/jerasure/gf-complete/src/gf_method.c
+++ /dev/null
@@ -1,193 +0,0 @@
-/*
- * GF-Complete: A Comprehensive Open Source Library for Galois Field Arithmetic
- * James S. Plank, Ethan L. Miller, Kevin M. Greenan,
- * Benjamin A. Arnold, John A. Burnum, Adam W. Disney, Allen C. McBride.
- *
- * gf_method.c
- *
- * Parses argv to figure out the mult_type and arguments.  Returns the gf.
- */
-
-#include <stdio.h>
-#include <stdint.h>
-#include <string.h>
-#include <stdlib.h>
-#include <time.h>
-
-#include "gf_complete.h"
-#include "gf_int.h"
-#include "gf_method.h"
-
-int create_gf_from_argv(gf_t *gf, int w, int argc, char **argv, int starting)
-{
-  int mult_type, divide_type, region_type;
-  int arg1, arg2;
-  uint64_t prim_poly;
-  gf_t *base;
-
-  mult_type = GF_MULT_DEFAULT;
-  region_type = GF_REGION_DEFAULT;
-  divide_type = GF_DIVIDE_DEFAULT;
-  prim_poly = 0;
-  base = NULL;
-  arg1 = 0;
-  arg2 = 0;
-  while (1) {
-    if (argc > starting) {
-      if (strcmp(argv[starting], "-m") == 0) {
-        starting++;
-        if (mult_type != GF_MULT_DEFAULT) {
-          if (base != NULL) gf_free(base, 1);
-          _gf_errno = GF_E_TWOMULT;
-          return 0;
-        }
-        if (strcmp(argv[starting], "SHIFT") == 0) {
-          mult_type = GF_MULT_SHIFT;
-          starting++;
-        } else if (strcmp(argv[starting], "CARRY_FREE") == 0) {
-          mult_type = GF_MULT_CARRY_FREE;
-          starting++;
-        } else if (strcmp(argv[starting], "CARRY_FREE_GK") == 0) {
-          mult_type = GF_MULT_CARRY_FREE_GK;
-          starting++;
-        } else if (strcmp(argv[starting], "GROUP") == 0) {
-          mult_type = GF_MULT_GROUP;
-          if (argc < starting + 3) {
-            _gf_errno = GF_E_GROUPAR;
-            return 0;
-          }
-          if (sscanf(argv[starting+1], "%d", &arg1) == 0 ||
-              sscanf(argv[starting+2], "%d", &arg2) == 0) {
-            _gf_errno = GF_E_GROUPNU;
-            return 0;
-          }
-          starting += 3;
-        } else if (strcmp(argv[starting], "BYTWO_p") == 0) {
-          mult_type = GF_MULT_BYTWO_p;
-          starting++;
-        } else if (strcmp(argv[starting], "BYTWO_b") == 0) {
-          mult_type = GF_MULT_BYTWO_b;
-          starting++;
-        } else if (strcmp(argv[starting], "TABLE") == 0) {
-          mult_type = GF_MULT_TABLE;
-          starting++;
-        } else if (strcmp(argv[starting], "LOG") == 0) {
-          mult_type = GF_MULT_LOG_TABLE;
-          starting++;
-        } else if (strcmp(argv[starting], "LOG_ZERO") == 0) {
-          mult_type = GF_MULT_LOG_ZERO;
-          starting++;
-        } else if (strcmp(argv[starting], "LOG_ZERO_EXT") == 0) {
-          mult_type = GF_MULT_LOG_ZERO_EXT;
-          starting++;
-        } else if (strcmp(argv[starting], "SPLIT") == 0) {
-          mult_type = GF_MULT_SPLIT_TABLE;
-          if (argc < starting + 3) {
-            _gf_errno = GF_E_SPLITAR;
-            return 0;
-          }
-          if (sscanf(argv[starting+1], "%d", &arg1) == 0 ||
-              sscanf(argv[starting+2], "%d", &arg2) == 0) {
-            _gf_errno = GF_E_SPLITNU;
-            return 0;
-          }
-          starting += 3;
-        } else if (strcmp(argv[starting], "COMPOSITE") == 0) {
-          mult_type = GF_MULT_COMPOSITE;
-          if (argc < starting + 2) { _gf_errno = GF_E_FEWARGS; return 0; }
-          if (sscanf(argv[starting+1], "%d", &arg1) == 0) {
-            _gf_errno = GF_E_COMP_A2;
-            return 0;
-          }
-          starting += 2;
-          base = (gf_t *) malloc(sizeof(gf_t));
-          starting = create_gf_from_argv(base, w/arg1, argc, argv, starting);
-          if (starting == 0) {
-            free(base);
-            return 0;
-          }
-        } else {
-          _gf_errno = GF_E_UNKNOWN;
-          return 0;
-        }
-      } else if (strcmp(argv[starting], "-r") == 0) {
-        starting++;
-        if (strcmp(argv[starting], "DOUBLE") == 0) {
-          region_type |= GF_REGION_DOUBLE_TABLE;
-          starting++;
-        } else if (strcmp(argv[starting], "QUAD") == 0) {
-          region_type |= GF_REGION_QUAD_TABLE;
-          starting++;
-        } else if (strcmp(argv[starting], "LAZY") == 0) {
-          region_type |= GF_REGION_LAZY;
-          starting++;
-        } else if (strcmp(argv[starting], "SIMD") == 0) {
-          region_type |= GF_REGION_SIMD;
-          starting++;
-        } else if (strcmp(argv[starting], "NOSIMD") == 0) {
-          region_type |= GF_REGION_NOSIMD;
-          starting++;
-        } else if (strcmp(argv[starting], "SSE") == 0) {
-          region_type |= GF_REGION_SIMD;
-          starting++;
-        } else if (strcmp(argv[starting], "NOSSE") == 0) {
-          region_type |= GF_REGION_NOSIMD;
-          starting++;
-        } else if (strcmp(argv[starting], "CAUCHY") == 0) {
-          region_type |= GF_REGION_CAUCHY;
-          starting++;
-        } else if (strcmp(argv[starting], "ALTMAP") == 0) {
-          region_type |= GF_REGION_ALTMAP;
-          starting++;
-        } else {
-          if (base != NULL) gf_free(base, 1);
-          _gf_errno = GF_E_UNK_REG;
-          return 0;
-        }
-      } else if (strcmp(argv[starting], "-p") == 0) {
-        starting++;
-        if (sscanf(argv[starting], "%llx", (long long unsigned int *)(&prim_poly)) == 0) {
-          if (base != NULL) gf_free(base, 1);
-          _gf_errno = GF_E_POLYSPC;
-          return 0;
-        }
-        starting++;
-      } else if (strcmp(argv[starting], "-d") == 0) {
-        starting++;
-        if (divide_type != GF_DIVIDE_DEFAULT) {
-          if (base != NULL) gf_free(base, 1);
-          _gf_errno = GF_E_TWO_DIV;
-          return 0;
-        } else if (strcmp(argv[starting], "EUCLID") == 0) {
-          divide_type = GF_DIVIDE_EUCLID;
-          starting++;
-        } else if (strcmp(argv[starting], "MATRIX") == 0) {
-          divide_type = GF_DIVIDE_MATRIX;
-          starting++;
-        } else {
-          _gf_errno = GF_E_UNK_DIV;
-          return 0;
-        }
-      } else if (strcmp(argv[starting], "-") == 0) {
-         /*
-         printf("Scratch size: %d\n", gf_scratch_size(w, 
-                                      mult_type, region_type, divide_type, arg1, arg2));
-         */
-        if (gf_init_hard(gf, w, mult_type, region_type, divide_type, 
-                         prim_poly, arg1, arg2, base, NULL) == 0) {
-          if (base != NULL) gf_free(base, 1);
-          return 0;
-        } else
-          return starting + 1;
-      } else {
-        if (base != NULL) gf_free(base, 1);
-        _gf_errno = GF_E_UNKFLAG;
-        return 0;
-      }
-    } else {
-      if (base != NULL) gf_free(base, 1);
-      _gf_errno = GF_E_FEWARGS;
-      return 0;
-    }
-  }
-}
diff --git a/src/erasure-code/jerasure/gf-complete/src/gf_rand.c b/src/erasure-code/jerasure/gf-complete/src/gf_rand.c
deleted file mode 100644
index a9aa7ad..0000000
--- a/src/erasure-code/jerasure/gf-complete/src/gf_rand.c
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * GF-Complete: A Comprehensive Open Source Library for Galois Field Arithmetic
- * James S. Plank, Ethan L. Miller, Kevin M. Greenan,
- * Benjamin A. Arnold, John A. Burnum, Adam W. Disney, Allen C. McBride.
- *
- * gf_rand.c -- Random number generator.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdint.h>
-#include "gf_rand.h"
-
-/* Lifted the "Mother of All" random number generator from http://www.agner.org/random/ */
-
-static uint32_t MOA_X[5];
-
-uint32_t MOA_Random_32() {
-  uint64_t sum;
-  sum = (uint64_t)2111111111UL * (uint64_t)MOA_X[3] +
-     (uint64_t)1492 * (uint64_t)(MOA_X[2]) +
-     (uint64_t)1776 * (uint64_t)(MOA_X[1]) +
-     (uint64_t)5115 * (uint64_t)(MOA_X[0]) +
-     (uint64_t)MOA_X[4];
-  MOA_X[3] = MOA_X[2];  MOA_X[2] = MOA_X[1];  MOA_X[1] = MOA_X[0];
-  MOA_X[4] = (uint32_t)(sum >> 32);
-  MOA_X[0] = (uint32_t)sum;
-  return MOA_X[0];
-}
-
-uint64_t MOA_Random_64() {
-  uint64_t sum;
-
-  sum = MOA_Random_32();
-  sum <<= 32;
-  sum |= MOA_Random_32();
-  return sum;
-}
-
-void MOA_Random_128(uint64_t *x) {
-  x[0] = MOA_Random_64();
-  x[1] = MOA_Random_64();
-  return;
-}
-
-uint32_t MOA_Random_W(int w, int zero_ok)
-{
-  uint32_t b;
-
-  do {
-    b = MOA_Random_32();
-    if (w == 31) b &= 0x7fffffff;
-    if (w < 31)  b %= (1 << w);
-  } while (!zero_ok && b == 0);
-  return b;
-}
-
-void MOA_Seed(uint32_t seed) {
-  int i;
-  uint32_t s = seed;
-  for (i = 0; i < 5; i++) {
-    s = s * 29943829 - 1;
-    MOA_X[i] = s;
-  }
-  for (i=0; i<19; i++) MOA_Random_32();
-}
-
-
-void MOA_Fill_Random_Region (void *reg, int size)
-{
-  uint32_t *r32;
-  uint8_t *r8;
-  int i;
-
-  r32 = (uint32_t *) reg;
-  r8 = (uint8_t *) reg;
-  for (i = 0; i < size/4; i++) r32[i] = MOA_Random_32();
-  for (i *= 4; i < size; i++) r8[i] = MOA_Random_W(8, 1);
-}
-
diff --git a/src/erasure-code/jerasure/gf-complete/src/gf_w128.c b/src/erasure-code/jerasure/gf-complete/src/gf_w128.c
deleted file mode 100644
index b6cfeba..0000000
--- a/src/erasure-code/jerasure/gf-complete/src/gf_w128.c
+++ /dev/null
@@ -1,1783 +0,0 @@
-/*
- * GF-Complete: A Comprehensive Open Source Library for Galois Field Arithmetic
- * James S. Plank, Ethan L. Miller, Kevin M. Greenan,
- * Benjamin A. Arnold, John A. Burnum, Adam W. Disney, Allen C. McBride.
- *
- * gf_w128.c
- *
- * Routines for 128-bit Galois fields
- */
-
-#include "gf_int.h"
-#include <stdio.h>
-#include <stdlib.h>
-
-#define GF_FIELD_WIDTH (128)
-
-#define two_x(a) {\
-  a[0] <<= 1; \
-  if (a[1] & 1ULL << 63) a[0] ^= 1; \
-  a[1] <<= 1; }
-  
-#define a_get_b(a, i, b, j) {\
-  a[i] = b[j]; \
-  a[i + 1] = b[j + 1];}
-
-#define set_zero(a, i) {\
-  a[i] = 0; \
-  a[i + 1] = 0;}
-
-struct gf_w128_split_4_128_data {
-  uint64_t last_value[2];
-  uint64_t tables[2][32][16];
-};
-
-struct gf_w128_split_8_128_data {
-  uint64_t last_value[2];
-  uint64_t tables[2][16][256];
-};
-
-typedef struct gf_group_tables_s {
-  gf_val_128_t m_table;
-  gf_val_128_t r_table;
-} gf_group_tables_t;
-
-#define MM_PRINT8(s, r) { uint8_t blah[16], ii; printf("%-12s", s); _mm_storeu_si128((__m128i *)blah, r); for (ii = 0; ii < 16; ii += 1) printf("%s%02x", (ii%4==0) ? "   " : " ", blah[15-ii]); printf("\n"); }
-
-static
-void
-gf_w128_multiply_region_from_single(gf_t *gf, void *src, void *dest, gf_val_128_t val, int bytes,
-int xor)
-{
-    uint32_t i;
-    gf_val_128_t s128;
-    gf_val_128_t d128;
-    uint64_t c128[2];
-    gf_region_data rd;
-
-    /* We only do this to check on alignment. */
-    gf_set_region_data(&rd, gf, src, dest, bytes, 0, xor, 8);
-
-    if (val[0] == 0) {
-      if (val[1] == 0) { gf_multby_zero(dest, bytes, xor); return; }
-      if (val[1] == 1) { gf_multby_one(src, dest, bytes, xor); return; }
-    }
-
-    set_zero(c128, 0);
-
-    s128 = (gf_val_128_t) src;
-    d128 = (gf_val_128_t) dest;
-
-    if (xor) {
-      for (i = 0; i < bytes/sizeof(gf_val_64_t); i += 2) {
-        gf->multiply.w128(gf, &s128[i], val, c128);
-        d128[i] ^= c128[0];
-        d128[i+1] ^= c128[1];
-      }
-    } else {
-      for (i = 0; i < bytes/sizeof(gf_val_64_t); i += 2) {
-        gf->multiply.w128(gf, &s128[i], val, &d128[i]);
-      }
-    }
-}
-
-#if defined(INTEL_SSE4_PCLMUL)
-static
-void
-gf_w128_clm_multiply_region_from_single(gf_t *gf, void *src, void *dest, gf_val_128_t val, int bytes,
-int xor)
-{
-    uint32_t i;
-    gf_val_128_t s128;
-    gf_val_128_t d128;
-    gf_region_data rd;
-    __m128i     a,b;
-    __m128i     result0,result1;
-    __m128i     prim_poly;
-    __m128i     c,d,e,f;
-    gf_internal_t * h = gf->scratch;
-    prim_poly = _mm_set_epi32(0, 0, 0, (uint32_t)h->prim_poly);
-    /* We only do this to check on alignment. */
-    gf_set_region_data(&rd, gf, src, dest, bytes, 0, xor, 8);
-
-    if (val[0] == 0) {
-      if (val[1] == 0) { gf_multby_zero(dest, bytes, xor); return; }
-      if (val[1] == 1) { gf_multby_one(src, dest, bytes, xor); return; }
-    }
-
-    s128 = (gf_val_128_t) src;
-    d128 = (gf_val_128_t) dest;
-
-    if (xor) {
-      for (i = 0; i < bytes/sizeof(gf_val_64_t); i += 2) {
-        a = _mm_insert_epi64 (_mm_setzero_si128(), s128[i+1], 0);
-        b = _mm_insert_epi64 (a, val[1], 0);
-        a = _mm_insert_epi64 (a, s128[i], 1);
-        b = _mm_insert_epi64 (b, val[0], 1);
-    
-        c = _mm_clmulepi64_si128 (a, b, 0x00); /*low-low*/
-        f = _mm_clmulepi64_si128 (a, b, 0x01); /*high-low*/
-        e = _mm_clmulepi64_si128 (a, b, 0x10); /*low-high*/
-        d = _mm_clmulepi64_si128 (a, b, 0x11); /*high-high*/
-
-        /* now reusing a and b as temporary variables*/
-        result0 = _mm_setzero_si128();
-        result1 = result0;
-
-        result0 = _mm_xor_si128 (result0, _mm_insert_epi64 (d, 0, 0));
-        a = _mm_xor_si128 (_mm_srli_si128 (e, 8), _mm_insert_epi64 (d, 0, 1));
-        result0 = _mm_xor_si128 (result0, _mm_xor_si128 (_mm_srli_si128 (f, 8), a));
-
-        a = _mm_xor_si128 (_mm_slli_si128 (e, 8), _mm_insert_epi64 (c, 0, 0));
-        result1 = _mm_xor_si128 (result1, _mm_xor_si128 (_mm_slli_si128 (f, 8), a));
-        result1 = _mm_xor_si128 (result1, _mm_insert_epi64 (c, 0, 1));
-        /* now we have constructed our 'result' with result0 being the carry bits, and we have to reduce. */
-
-        a = _mm_srli_si128 (result0, 8);
-        b = _mm_clmulepi64_si128 (a, prim_poly, 0x00);
-        result0 = _mm_xor_si128 (result0, _mm_srli_si128 (b, 8));
-        result1 = _mm_xor_si128 (result1, _mm_slli_si128 (b, 8));
-
-        a = _mm_insert_epi64 (result0, 0, 1);
-        b = _mm_clmulepi64_si128 (a, prim_poly, 0x00);
-        result1 = _mm_xor_si128 (result1, b); 
-        d128[i] ^= (uint64_t)_mm_extract_epi64(result1,1);
-        d128[i+1] ^= (uint64_t)_mm_extract_epi64(result1,0);
-      }
-    } else {
-      for (i = 0; i < bytes/sizeof(gf_val_64_t); i += 2) {
-        a = _mm_insert_epi64 (_mm_setzero_si128(), s128[i+1], 0);
-        b = _mm_insert_epi64 (a, val[1], 0);
-        a = _mm_insert_epi64 (a, s128[i], 1);
-        b = _mm_insert_epi64 (b, val[0], 1);
-
-        c = _mm_clmulepi64_si128 (a, b, 0x00); /*low-low*/
-        f = _mm_clmulepi64_si128 (a, b, 0x01); /*high-low*/
-        e = _mm_clmulepi64_si128 (a, b, 0x10); /*low-high*/ 
-        d = _mm_clmulepi64_si128 (a, b, 0x11); /*high-high*/ 
-
-        /* now reusing a and b as temporary variables*/
-        result0 = _mm_setzero_si128();
-        result1 = result0;
-
-        result0 = _mm_xor_si128 (result0, _mm_insert_epi64 (d, 0, 0));
-        a = _mm_xor_si128 (_mm_srli_si128 (e, 8), _mm_insert_epi64 (d, 0, 1));
-        result0 = _mm_xor_si128 (result0, _mm_xor_si128 (_mm_srli_si128 (f, 8), a));
-
-        a = _mm_xor_si128 (_mm_slli_si128 (e, 8), _mm_insert_epi64 (c, 0, 0));
-        result1 = _mm_xor_si128 (result1, _mm_xor_si128 (_mm_slli_si128 (f, 8), a));
-        result1 = _mm_xor_si128 (result1, _mm_insert_epi64 (c, 0, 1));
-        /* now we have constructed our 'result' with result0 being the carry bits, and we have to reduce.*/
-
-        a = _mm_srli_si128 (result0, 8);
-        b = _mm_clmulepi64_si128 (a, prim_poly, 0x00);
-        result0 = _mm_xor_si128 (result0, _mm_srli_si128 (b, 8));
-        result1 = _mm_xor_si128 (result1, _mm_slli_si128 (b, 8));
-
-        a = _mm_insert_epi64 (result0, 0, 1);
-        b = _mm_clmulepi64_si128 (a, prim_poly, 0x00);
-        result1 = _mm_xor_si128 (result1, b);
-        d128[i] = (uint64_t)_mm_extract_epi64(result1,1);
-        d128[i+1] = (uint64_t)_mm_extract_epi64(result1,0);
-      }
-    }
-}
-#endif
-
-/*
- * Some w128 notes:
- * --Big Endian
- * --return values allocated beforehand
- */
-
-#define GF_W128_IS_ZERO(val) (val[0] == 0 && val[1] == 0)
-
-void
-gf_w128_shift_multiply(gf_t *gf, gf_val_128_t a128, gf_val_128_t b128, gf_val_128_t c128)
-{
-  /* ordered highest bit to lowest l[0] l[1] r[0] r[1] */
-  uint64_t pl[2], pr[2], ppl[2], ppr[2], i, a[2], bl[2], br[2], one, lbit;
-  gf_internal_t *h;
-
-  h = (gf_internal_t *) gf->scratch;
-
-  if (GF_W128_IS_ZERO(a128) || GF_W128_IS_ZERO(b128)) {
-    set_zero(c128, 0);
-    return;
-  }
-
-  a_get_b(a, 0, a128, 0);
-  a_get_b(br, 0, b128, 0);
-  set_zero(bl, 0);
-
-  one = 1;
-  lbit = (one << 63);
-
-  set_zero(pl, 0);
-  set_zero(pr, 0);
-
-  /* Allen: a*b for right half of a */
-  for (i = 0; i < GF_FIELD_WIDTH/2; i++) {
-    if (a[1] & (one << i)) {
-      pl[1] ^= bl[1];
-      pr[0] ^= br[0];
-      pr[1] ^= br[1];
-    }
-    bl[1] <<= 1;
-    if (br[0] & lbit) bl[1] ^= 1;
-    br[0] <<= 1;
-    if (br[1] & lbit) br[0] ^= 1;
-    br[1] <<= 1;
-  }
-
-  /* Allen: a*b for left half of a */
-  for (i = 0; i < GF_FIELD_WIDTH/2; i++) {
-    if (a[0] & (one << i)) {
-      pl[0] ^= bl[0];
-      pl[1] ^= bl[1];
-      pr[0] ^= br[0];
-    }
-    bl[0] <<= 1;
-    if (bl[1] & lbit) bl[0] ^= 1;
-    bl[1] <<= 1;
-    if (br[0] & lbit) bl[1] ^= 1;
-    br[0] <<= 1;
-  }
-
-  /* Allen: do first half of reduction (based on left quarter of initial product) */
-  one = lbit >> 1;
-  ppl[0] = one; /* Allen: introduce leading one of primitive polynomial */
-  ppl[1] = h->prim_poly >> 2;
-  ppr[0] = h->prim_poly << (GF_FIELD_WIDTH/2-2);
-  ppr[1] = 0;
-  while (one != 0) {
-    if (pl[0] & one) {
-      pl[0] ^= ppl[0];
-      pl[1] ^= ppl[1];
-      pr[0] ^= ppr[0];
-      pr[1] ^= ppr[1];
-    }
-    one >>= 1;
-    ppr[1] >>= 1;
-    if (ppr[0] & 1) ppr[1] ^= lbit;
-    ppr[0] >>= 1;
-    if (ppl[1] & 1) ppr[0] ^= lbit;
-    ppl[1] >>= 1;
-    if (ppl[0] & 1) ppl[1] ^= lbit;
-    ppl[0] >>= 1;
-  }
-
-  /* Allen: final half of reduction */
-  one = lbit;
-  while (one != 0) {
-    if (pl[1] & one) {
-      pl[1] ^= ppl[1];
-      pr[0] ^= ppr[0];
-      pr[1] ^= ppr[1];
-    }
-    one >>= 1;
-    ppr[1] >>= 1;
-    if (ppr[0] & 1) ppr[1] ^= lbit;
-    ppr[0] >>= 1;
-    if (ppl[1] & 1) ppr[0] ^= lbit;
-    ppl[1] >>= 1;
-  }
-
-  /* Allen: if we really want to optimize this we can just be using c128 instead of pr all along */
-  c128[0] = pr[0];
-  c128[1] = pr[1];
-
-  return;
-}
-
-void
-gf_w128_clm_multiply(gf_t *gf, gf_val_128_t a128, gf_val_128_t b128, gf_val_128_t c128)
-{
-#if defined(INTEL_SSE4_PCLMUL)
-
-    __m128i     a,b;
-    __m128i     result0,result1;
-    __m128i     prim_poly;
-    __m128i     c,d,e,f;
-    gf_internal_t * h = gf->scratch;
-    
-    a = _mm_insert_epi64 (_mm_setzero_si128(), a128[1], 0);
-    b = _mm_insert_epi64 (a, b128[1], 0);
-    a = _mm_insert_epi64 (a, a128[0], 1);
-    b = _mm_insert_epi64 (b, b128[0], 1);
-
-    prim_poly = _mm_set_epi32(0, 0, 0, (uint32_t)h->prim_poly);
-
-    /* we need to test algorithm 2 later*/
-    c = _mm_clmulepi64_si128 (a, b, 0x00); /*low-low*/
-    f = _mm_clmulepi64_si128 (a, b, 0x01); /*high-low*/
-    e = _mm_clmulepi64_si128 (a, b, 0x10); /*low-high*/
-    d = _mm_clmulepi64_si128 (a, b, 0x11); /*high-high*/
-    
-    /* now reusing a and b as temporary variables*/
-    result0 = _mm_setzero_si128();
-    result1 = result0;
-
-    result0 = _mm_xor_si128 (result0, _mm_insert_epi64 (d, 0, 0));
-    a = _mm_xor_si128 (_mm_srli_si128 (e, 8), _mm_insert_epi64 (d, 0, 1));
-    result0 = _mm_xor_si128 (result0, _mm_xor_si128 (_mm_srli_si128 (f, 8), a));
-
-    a = _mm_xor_si128 (_mm_slli_si128 (e, 8), _mm_insert_epi64 (c, 0, 0));
-    result1 = _mm_xor_si128 (result1, _mm_xor_si128 (_mm_slli_si128 (f, 8), a));
-    result1 = _mm_xor_si128 (result1, _mm_insert_epi64 (c, 0, 1));
-    /* now we have constructed our 'result' with result0 being the carry bits, and we have to reduce.*/
-    
-    a = _mm_srli_si128 (result0, 8);
-    b = _mm_clmulepi64_si128 (a, prim_poly, 0x00);
-    result0 = _mm_xor_si128 (result0, _mm_srli_si128 (b, 8));
-    result1 = _mm_xor_si128 (result1, _mm_slli_si128 (b, 8));
-    
-    a = _mm_insert_epi64 (result0, 0, 1);
-    b = _mm_clmulepi64_si128 (a, prim_poly, 0x00);
-    result1 = _mm_xor_si128 (result1, b);
-
-    c128[0] = (uint64_t)_mm_extract_epi64(result1,1);
-    c128[1] = (uint64_t)_mm_extract_epi64(result1,0);
-#endif
-return;
-}
-
-void
-gf_w128_bytwo_p_multiply(gf_t *gf, gf_val_128_t a128, gf_val_128_t b128, gf_val_128_t c128)
-{
-  uint64_t amask[2], pmask, pp, prod[2]; /*John: pmask is always the highest bit set, and the rest zeros. amask changes, it's a countdown.*/
-  uint64_t topbit; /* this is used as a boolean value */
-  gf_internal_t *h;
-
-  h = (gf_internal_t *) gf->scratch;
-  pp = h->prim_poly;
-  prod[0] = 0;
-  prod[1] = 0;
-  pmask = 0x8000000000000000ULL;
-  amask[0] = 0x8000000000000000ULL;
-  amask[1] = 0;
-
-  while (amask[1] != 0 || amask[0] != 0) {
-    topbit = (prod[0] & pmask);
-    prod[0] <<= 1;
-    if (prod[1] & pmask) prod[0] ^= 1;
-    prod[1] <<= 1;
-    if (topbit) prod[1] ^= pp;
-    if ((a128[0] & amask[0]) || (a128[1] & amask[1])) {
-      prod[0] ^= b128[0];
-      prod[1] ^= b128[1];
-    }
-    amask[1] >>= 1;
-    if (amask[0] & 1) amask[1] ^= pmask;
-    amask[0] >>= 1;
-  }
-  c128[0] = prod [0];
-  c128[1] = prod [1];
-  return;
-}
-
-void
-gf_w128_sse_bytwo_p_multiply(gf_t *gf, gf_val_128_t a128, gf_val_128_t b128, gf_val_128_t c128)
-{
-#if defined(INTEL_SSE4)
-  int i;
-  __m128i a, b, pp, prod, amask, u_middle_one; 
-  /*John: pmask is always the highest bit set, and the rest zeros. amask changes, it's a countdown.*/
-  uint32_t topbit, middlebit, pmask; /* this is used as a boolean value */
-  gf_internal_t *h;
-
-
-  h = (gf_internal_t *) gf->scratch;
-  pp = _mm_set_epi32(0, 0, 0, (uint32_t)h->prim_poly);
-  prod = _mm_setzero_si128();
-  a = _mm_insert_epi64(prod, a128[1], 0x0);
-  a = _mm_insert_epi64(a, a128[0], 0x1);
-  b = _mm_insert_epi64(prod, b128[1], 0x0);
-  b = _mm_insert_epi64(b, b128[0], 0x1);
-  pmask = 0x80000000;
-  amask = _mm_insert_epi32(prod, 0x80000000, 0x3);
-  u_middle_one = _mm_insert_epi32(prod, 1, 0x2);
-  
-  for (i = 0; i < 64; i++) {
-    topbit = (_mm_extract_epi32(prod, 0x3) & pmask);
-    middlebit = (_mm_extract_epi32(prod, 0x1) & pmask);
-    prod = _mm_slli_epi64(prod, 1); /* this instruction loses the middle bit */
-    if (middlebit) {
-      prod = _mm_xor_si128(prod, u_middle_one);
-    }
-    if (topbit) {
-      prod = _mm_xor_si128(prod, pp);
-    }
-    if (((uint64_t)_mm_extract_epi64(_mm_and_si128(a, amask), 1))) {
-      prod = _mm_xor_si128(prod, b);
-    }
-    amask = _mm_srli_epi64(amask, 1); /*so does this one, but we can just replace after loop*/
-  }
-  amask = _mm_insert_epi32(amask, 1 << 31, 0x1);
-  for (i = 64; i < 128; i++) {
-    topbit = (_mm_extract_epi32(prod, 0x3) & pmask);
-    middlebit = (_mm_extract_epi32(prod, 0x1) & pmask);
-    prod = _mm_slli_epi64(prod, 1);
-    if (middlebit) prod = _mm_xor_si128(prod, u_middle_one);
-    if (topbit) prod = _mm_xor_si128(prod, pp);
-    if (((uint64_t)_mm_extract_epi64(_mm_and_si128(a, amask), 0))) {
-      prod = _mm_xor_si128(prod, b);
-    }
-    amask = _mm_srli_epi64(amask, 1);
-  }
-  c128[0] = (uint64_t)_mm_extract_epi64(prod, 1);
-  c128[1] = (uint64_t)_mm_extract_epi64(prod, 0);
-#endif
-  return;
-}
-
-
-/* Ben: This slow function implements sse instrutions for bytwo_b because why not */
-void
-gf_w128_sse_bytwo_b_multiply(gf_t *gf, gf_val_128_t a128, gf_val_128_t b128, gf_val_128_t c128)
-{
-#if defined(INTEL_SSE4)
-  __m128i a, b, lmask, hmask, pp, c, middle_one;
-  gf_internal_t *h;
-  uint64_t topbit, middlebit;
-
-  h = (gf_internal_t *) gf->scratch;
-  
-  c = _mm_setzero_si128();
-  lmask = _mm_insert_epi64(c, 1ULL << 63, 0);
-  hmask = _mm_insert_epi64(c, 1ULL << 63, 1);
-  b = _mm_insert_epi64(c, a128[0], 1);
-  b = _mm_insert_epi64(b, a128[1], 0);
-  a = _mm_insert_epi64(c, b128[0], 1);
-  a = _mm_insert_epi64(a, b128[1], 0);
-  pp = _mm_insert_epi64(c, h->prim_poly, 0);
-  middle_one = _mm_insert_epi64(c, 1, 0x1);
-
-  while (1) {
-    if (_mm_extract_epi32(a, 0x0) & 1) {
-      c = _mm_xor_si128(c, b);
-    }
-    middlebit = (_mm_extract_epi32(a, 0x2) & 1);
-    a = _mm_srli_epi64(a, 1);
-    if (middlebit) a = _mm_xor_si128(a, lmask);
-    if ((_mm_extract_epi64(a, 0x1) == 0ULL) && (_mm_extract_epi64(a, 0x0) == 0ULL)){
-      c128[0] = _mm_extract_epi64(c, 0x1);
-      c128[1] = _mm_extract_epi64(c, 0x0);
-      return;
-    }
-    topbit = (_mm_extract_epi64(_mm_and_si128(b, hmask), 1));
-    middlebit = (_mm_extract_epi64(_mm_and_si128(b, lmask), 0));
-    b = _mm_slli_epi64(b, 1);
-    if (middlebit) b = _mm_xor_si128(b, middle_one);
-    if (topbit) b = _mm_xor_si128(b, pp);
-  }
-#endif
-}
-
-void
-gf_w128_bytwo_b_multiply(gf_t *gf, gf_val_128_t a128, gf_val_128_t b128, gf_val_128_t c128)
-{
-  uint64_t bmask, pp;
-  gf_internal_t *h;
-  uint64_t a[2], b[2], c[2];
-
-  h = (gf_internal_t *) gf->scratch;
-
-  bmask = (1ULL << 63);
-  set_zero(c, 0);
-  b[0] = a128[0];
-  b[1] = a128[1];
-  a[0] = b128[0];
-  a[1] = b128[1];
-  
-  while (1) {
-    if (a[1] & 1) {
-      c[0] ^= b[0];
-      c[1] ^= b[1];
-    }
-    a[1] >>= 1;
-    if (a[0] & 1) a[1] ^= bmask;
-    a[0] >>= 1;
-    if (a[1] == 0 && a[0] == 0) {
-      c128[0] = c[0];
-      c128[1] = c[1];
-      return;
-    }
-    pp = (b[0] & bmask);
-    b[0] <<= 1;
-    if (b[1] & bmask) b[0] ^= 1;
-    b[1] <<= 1;
-    if (pp) b[1] ^= h->prim_poly;
-  }
-}
-
-static
-void
-gf_w128_split_4_128_multiply_region(gf_t *gf, void *src, void *dest, gf_val_128_t val, int bytes, int xor)
-{
-  int i, j, k;
-  uint64_t pp;
-  gf_internal_t *h;
-  uint64_t *s64, *d64, *top;
-  gf_region_data rd;
-  uint64_t v[2], s;
-  struct gf_w128_split_4_128_data *ld;
-
-  /* We only do this to check on alignment. */
-  gf_set_region_data(&rd, gf, src, dest, bytes, 0, xor, 8);
-
-  if (val[0] == 0) {
-    if (val[1] == 0) { gf_multby_zero(dest, bytes, xor); return; }
-    if (val[1] == 1) { gf_multby_one(src, dest, bytes, xor); return; }
-  }
-    
-  h = (gf_internal_t *) gf->scratch;
-  ld = (struct gf_w128_split_4_128_data *) h->private;
-
-  s64 = (uint64_t *) rd.s_start;
-  d64 = (uint64_t *) rd.d_start;
-  top = (uint64_t *) rd.d_top;
-
-  if (val[0] != ld->last_value[0] || val[1] != ld->last_value[1]) {
-    v[0] = val[0];
-    v[1] = val[1];
-    for (i = 0; i < 32; i++) {
-      ld->tables[0][i][0] = 0;
-      ld->tables[1][i][0] = 0;
-      for (j = 1; j < 16; j <<= 1) {
-        for (k = 0; k < j; k++) {
-          ld->tables[0][i][k^j] = (v[0] ^ ld->tables[0][i][k]);
-          ld->tables[1][i][k^j] = (v[1] ^ ld->tables[1][i][k]);
-        }
-        pp = (v[0] & (1ULL << 63));
-        v[0] <<= 1;
-        if (v[1] & (1ULL << 63)) v[0] ^= 1;
-        v[1] <<= 1;
-        if (pp) v[1] ^= h->prim_poly;
-      }
-    }
-  }
-  ld->last_value[0] = val[0];
-  ld->last_value[1] = val[1];
-
-/*
-  for (i = 0; i < 32; i++) {
-    for (j = 0; j < 16; j++) {
-      printf("%2d %2d %016llx %016llx\n", i, j, ld->tables[0][i][j], ld->tables[1][i][j]);
-    }
-    printf("\n");
-  }
- */
-  while (d64 < top) {
-    v[0] = (xor) ? d64[0] : 0;
-    v[1] = (xor) ? d64[1] : 0;
-    s = s64[1];
-    i = 0;
-    while (s != 0) {
-      v[0] ^= ld->tables[0][i][s&0xf];
-      v[1] ^= ld->tables[1][i][s&0xf];
-      s >>= 4;
-      i++;
-    }
-    s = s64[0];
-    i = 16;
-    while (s != 0) {
-      v[0] ^= ld->tables[0][i][s&0xf];
-      v[1] ^= ld->tables[1][i][s&0xf];
-      s >>= 4;
-      i++;
-    }
-    d64[0] = v[0];
-    d64[1] = v[1];
-    s64 += 2;
-    d64 += 2;
-  }
-}
-
-#if defined(INTEL_SSSE3) && defined(INTEL_SSE4)
-static
-void
-gf_w128_split_4_128_sse_multiply_region(gf_t *gf, void *src, void *dest, gf_val_128_t val, int bytes, int xor)
-{
-  gf_internal_t *h;
-  int i, j, k;
-  uint64_t pp, v[2], s, *s64, *d64, *top;
-  __m128i p, tables[32][16];
-  struct gf_w128_split_4_128_data *ld;
-  gf_region_data rd;
-
-  if (val[0] == 0) {
-    if (val[1] == 0) { gf_multby_zero(dest, bytes, xor); return; }
-    if (val[1] == 1) { gf_multby_one(src, dest, bytes, xor); return; }
-  }
-
-  h = (gf_internal_t *) gf->scratch;
-  
-  /* We only do this to check on alignment. */
-  gf_set_region_data(&rd, gf, src, dest, bytes, 0, xor, 16);
-
-  /* Doing this instead of gf_do_initial_region_alignment() because that doesn't hold 128-bit vals */
-
-  gf_w128_multiply_region_from_single(gf, src, dest, val, ((uint8_t *)rd.s_start-(uint8_t *)src), xor);
-
-  s64 = (uint64_t *) rd.s_start;
-  d64 = (uint64_t *) rd.d_start;
-  top = (uint64_t *) rd.d_top;
- 
-  ld = (struct gf_w128_split_4_128_data *) h->private;
-
-  if (val[0] != ld->last_value[0] || val[1] != ld->last_value[1]) {
-    v[0] = val[0];
-    v[1] = val[1];
-    for (i = 0; i < 32; i++) {
-      ld->tables[0][i][0] = 0;
-      ld->tables[1][i][0] = 0;
-      for (j = 1; j < 16; j <<= 1) {
-        for (k = 0; k < j; k++) {
-          ld->tables[0][i][k^j] = (v[0] ^ ld->tables[0][i][k]);
-          ld->tables[1][i][k^j] = (v[1] ^ ld->tables[1][i][k]);
-        }
-        pp = (v[0] & (1ULL << 63));
-        v[0] <<= 1;
-        if (v[1] & (1ULL << 63)) v[0] ^= 1;
-        v[1] <<= 1;
-        if (pp) v[1] ^= h->prim_poly;
-      }
-    }
-  }
-
-  ld->last_value[0] = val[0];
-  ld->last_value[1] = val[1];
-
-  for (i = 0; i < 32; i++) {
-    for (j = 0; j < 16; j++) {
-      v[0] = ld->tables[0][i][j];
-      v[1] = ld->tables[1][i][j];
-      tables[i][j] = _mm_loadu_si128((__m128i *) v);
-
-/*
-      printf("%2d %2d: ", i, j);
-      MM_PRINT8("", tables[i][j]); */
-    }
-  }
-
-  while (d64 != top) {
-
-    if (xor) {
-      p = _mm_load_si128 ((__m128i *) d64);
-    } else {
-      p = _mm_setzero_si128();
-    }
-    s = *s64;
-    s64++;
-    for (i = 0; i < 16; i++) {
-      j = (s&0xf);
-      s >>= 4;
-      p = _mm_xor_si128(p, tables[16+i][j]);
-    }
-    s = *s64;
-    s64++;
-    for (i = 0; i < 16; i++) {
-      j = (s&0xf);
-      s >>= 4;
-      p = _mm_xor_si128(p, tables[i][j]);
-    }
-    _mm_store_si128((__m128i *) d64, p);
-    d64 += 2;
-  }
-
-  /* Doing this instead of gf_do_final_region_alignment() because that doesn't hold 128-bit vals */
-
-  gf_w128_multiply_region_from_single(gf, rd.s_top, rd.d_top, val, ((uint8_t *)src+bytes)-(uint8_t *)rd.s_top, xor);
-}
-#endif
-
-#if defined(INTEL_SSSE3) && defined(INTEL_SSE4)
-static
-void
-gf_w128_split_4_128_sse_altmap_multiply_region(gf_t *gf, void *src, void *dest, gf_val_128_t val, int bytes, int xor)
-{
-  gf_internal_t *h;
-  int i, j, k;
-  uint64_t pp, v[2], *s64, *d64, *top;
-  __m128i si, tables[32][16], p[16], v0, mask1;
-  struct gf_w128_split_4_128_data *ld;
-  uint8_t btable[16];
-  gf_region_data rd;
-
-  if (val[0] == 0) {
-    if (val[1] == 0) { gf_multby_zero(dest, bytes, xor); return; }
-    if (val[1] == 1) { gf_multby_one(src, dest, bytes, xor); return; }
-  }
-
-  h = (gf_internal_t *) gf->scratch;
-  
-  /* We only do this to check on alignment. */
-  gf_set_region_data(&rd, gf, src, dest, bytes, 0, xor, 256);
-
-  /* Doing this instead of gf_do_initial_region_alignment() because that doesn't hold 128-bit vals */
-
-  gf_w128_multiply_region_from_single(gf, src, dest, val, ((uint8_t *)rd.s_start-(uint8_t *)src), xor);
-
-  s64 = (uint64_t *) rd.s_start;
-  d64 = (uint64_t *) rd.d_start;
-  top = (uint64_t *) rd.d_top;
- 
-  ld = (struct gf_w128_split_4_128_data *) h->private;
-
-  if (val[0] != ld->last_value[0] || val[1] != ld->last_value[1]) {
-    v[0] = val[0];
-    v[1] = val[1];
-    for (i = 0; i < 32; i++) {
-      ld->tables[0][i][0] = 0;
-      ld->tables[1][i][0] = 0;
-      for (j = 1; j < 16; j <<= 1) {
-        for (k = 0; k < j; k++) {
-          ld->tables[0][i][k^j] = (v[0] ^ ld->tables[0][i][k]);
-          ld->tables[1][i][k^j] = (v[1] ^ ld->tables[1][i][k]);
-        }
-        pp = (v[0] & (1ULL << 63));
-        v[0] <<= 1;
-        if (v[1] & (1ULL << 63)) v[0] ^= 1;
-        v[1] <<= 1;
-        if (pp) v[1] ^= h->prim_poly;
-      }
-    }
-  }
-
-  ld->last_value[0] = val[0];
-  ld->last_value[1] = val[1];
-
-  for (i = 0; i < 32; i++) {
-    for (j = 0; j < 16; j++) {
-      for (k = 0; k < 16; k++) {
-        btable[k] = (uint8_t) ld->tables[1-(j/8)][i][k];
-        ld->tables[1-(j/8)][i][k] >>= 8;
-      }
-      tables[i][j] = _mm_loadu_si128((__m128i *) btable);
-/*
-      printf("%2d %2d: ", i, j);
-      MM_PRINT8("", tables[i][j]);
- */
-    }
-  }
-
-
-  mask1 = _mm_set1_epi8(0xf);
-
-  while (d64 != top) {
-
-    if (xor) {
-      for (i = 0; i < 16; i++) p[i] = _mm_load_si128 ((__m128i *) (d64+i*2));
-    } else {
-      for (i = 0; i < 16; i++) p[i] = _mm_setzero_si128();
-    }
-    i = 0;
-    for (k = 0; k < 16; k++) {
-      v0 = _mm_load_si128((__m128i *) s64); 
-      s64 += 2;
-      
-      si = _mm_and_si128(v0, mask1);
-  
-      for (j = 0; j < 16; j++) {
-        p[j] = _mm_xor_si128(p[j], _mm_shuffle_epi8(tables[i][j], si));
-      }
-      i++;
-      v0 = _mm_srli_epi32(v0, 4);
-      si = _mm_and_si128(v0, mask1);
-      for (j = 0; j < 16; j++) {
-        p[j] = _mm_xor_si128(p[j], _mm_shuffle_epi8(tables[i][j], si));
-      }
-      i++;
-    }
-    for (i = 0; i < 16; i++) {
-      _mm_store_si128((__m128i *) d64, p[i]);
-      d64 += 2;
-    }
-  }
-  /* Doing this instead of gf_do_final_region_alignment() because that doesn't hold 128-bit vals */
-
-  gf_w128_multiply_region_from_single(gf, rd.s_top, rd.d_top, val, ((uint8_t *)src+bytes)-(uint8_t *)rd.s_top, xor);
-}
-#endif
-
-static
-void
-gf_w128_split_8_128_multiply_region(gf_t *gf, void *src, void *dest, gf_val_128_t val, int bytes, int xor)
-{
-  int i, j, k;
-  uint64_t pp;
-  gf_internal_t *h;
-  uint64_t *s64, *d64, *top;
-  gf_region_data rd;
-  uint64_t v[2], s;
-  struct gf_w128_split_8_128_data *ld;
-
-  /* Check on alignment. Ignore it otherwise. */
-  gf_set_region_data(&rd, gf, src, dest, bytes, 0, xor, 8);
-
-  if (val[0] == 0) {
-    if (val[1] == 0) { gf_multby_zero(dest, bytes, xor); return; }
-    if (val[1] == 1) { gf_multby_one(src, dest, bytes, xor); return; }
-  }
-    
-  h = (gf_internal_t *) gf->scratch;
-  ld = (struct gf_w128_split_8_128_data *) h->private;
-
-  s64 = (uint64_t *) rd.s_start;
-  d64 = (uint64_t *) rd.d_start;
-  top = (uint64_t *) rd.d_top;
-
-  if (val[0] != ld->last_value[0] || val[1] != ld->last_value[1]) {
-    v[0] = val[0];
-    v[1] = val[1];
-    for (i = 0; i < 16; i++) {
-      ld->tables[0][i][0] = 0;
-      ld->tables[1][i][0] = 0;
-      for (j = 1; j < (1 << 8); j <<= 1) {
-        for (k = 0; k < j; k++) {
-          ld->tables[0][i][k^j] = (v[0] ^ ld->tables[0][i][k]);
-          ld->tables[1][i][k^j] = (v[1] ^ ld->tables[1][i][k]);
-        }
-        pp = (v[0] & (1ULL << 63));
-        v[0] <<= 1;
-        if (v[1] & (1ULL << 63)) v[0] ^= 1;
-        v[1] <<= 1;
-        if (pp) v[1] ^= h->prim_poly;
-      }
-    }
-  }
-  ld->last_value[0] = val[0];
-  ld->last_value[1] = val[1];
-
-  while (d64 < top) {
-    v[0] = (xor) ? d64[0] : 0;
-    v[1] = (xor) ? d64[1] : 0;
-    s = s64[1];
-    i = 0;
-    while (s != 0) {
-      v[0] ^= ld->tables[0][i][s&0xff];
-      v[1] ^= ld->tables[1][i][s&0xff];
-      s >>= 8;
-      i++;
-    }
-    s = s64[0];
-    i = 8;
-    while (s != 0) {
-      v[0] ^= ld->tables[0][i][s&0xff];
-      v[1] ^= ld->tables[1][i][s&0xff];
-      s >>= 8;
-      i++;
-    }
-    d64[0] = v[0];
-    d64[1] = v[1];
-    s64 += 2;
-    d64 += 2;
-  }
-}
-
-void
-gf_w128_bytwo_b_multiply_region(gf_t *gf, void *src, void *dest, gf_val_128_t val, int bytes, int xor)
-{
-  uint64_t bmask, pp;
-  gf_internal_t *h;
-  uint64_t a[2], c[2], b[2], *s64, *d64, *top;
-  gf_region_data rd;
-
-  /* We only do this to check on alignment. */
-  gf_set_region_data(&rd, gf, src, dest, bytes, 0, xor, 8);
-
-  if (val[0] == 0) {
-    if (val[1] == 0) { gf_multby_zero(dest, bytes, xor); return; }
-    if (val[1] == 1) { gf_multby_one(src, dest, bytes, xor); return; }
-  }
-    
-  h = (gf_internal_t *) gf->scratch;
-  s64 = (uint64_t *) rd.s_start;
-  d64 = (uint64_t *) rd.d_start;
-  top = (uint64_t *) rd.d_top;
-  bmask = (1ULL << 63);
-
-  while (d64 < top) {
-    set_zero(c, 0);
-    b[0] = s64[0];
-    b[1] = s64[1];
-    a[0] = val[0];
-    a[1] = val[1];
-
-    while (a[0] != 0) {
-      if (a[1] & 1) {
-        c[0] ^= b[0];
-        c[1] ^= b[1];
-      }
-      a[1] >>= 1;
-      if (a[0] & 1) a[1] ^= bmask;
-      a[0] >>= 1;
-      pp = (b[0] & bmask);
-      b[0] <<= 1;
-      if (b[1] & bmask) b[0] ^= 1;    
-      b[1] <<= 1;
-      if (pp) b[1] ^= h->prim_poly;
-    }
-    while (1) {
-      if (a[1] & 1) {
-        c[0] ^= b[0];
-        c[1] ^= b[1];
-      }
-      a[1] >>= 1;
-      if (a[1] == 0) break;
-      pp = (b[0] & bmask);
-      b[0] <<= 1;
-      if (b[1] & bmask) b[0] ^= 1;    
-      b[1] <<= 1;
-      if (pp) b[1] ^= h->prim_poly;
-    }
-    if (xor) {
-      d64[0] ^= c[0];
-      d64[1] ^= c[1];
-    } else {
-      d64[0] = c[0];
-      d64[1] = c[1];
-    }
-    s64 += 2;
-    d64 += 2;
-  }
-}
-
-static
-void gf_w128_group_m_init(gf_t *gf, gf_val_128_t b128)
-{
-  int i, j;
-  int g_m;
-  uint64_t prim_poly, lbit;
-  gf_internal_t *scratch;
-  gf_group_tables_t *gt;
-  uint64_t a128[2];
-  scratch = (gf_internal_t *) gf->scratch;
-  gt = scratch->private;
-  g_m = scratch->arg1;
-  prim_poly = scratch->prim_poly;
-
-
-  set_zero(gt->m_table, 0);
-  a_get_b(gt->m_table, 2, b128, 0);
-  lbit = 1;
-  lbit <<= 63;
-
-  for (i = 2; i < (1 << g_m); i <<= 1) {
-    a_get_b(a128, 0, gt->m_table, 2 * (i >> 1));
-    two_x(a128);
-    a_get_b(gt->m_table, 2 * i, a128, 0);
-    if (gt->m_table[2 * (i >> 1)] & lbit) gt->m_table[(2 * i) + 1] ^= prim_poly;
-    for (j = 0; j < i; j++) {
-      gt->m_table[(2 * i) + (2 * j)] = gt->m_table[(2 * i)] ^ gt->m_table[(2 * j)];
-      gt->m_table[(2 * i) + (2 * j) + 1] = gt->m_table[(2 * i) + 1] ^ gt->m_table[(2 * j) + 1];
-    }
-  }
-  return;
-}
-
-void
-gf_w128_group_multiply(GFP gf, gf_val_128_t a128, gf_val_128_t b128, gf_val_128_t c128)
-{
-  int i;
-  /* index_r, index_m, total_m (if g_r > g_m) */
-  int i_r, i_m, t_m;
-  int mask_m, mask_r;
-  int g_m, g_r;
-  uint64_t p_i[2], a[2];
-  gf_internal_t *scratch;
-  gf_group_tables_t *gt;
-
-  scratch = (gf_internal_t *) gf->scratch;
-  gt = scratch->private;
-  g_m = scratch->arg1;
-  g_r = scratch->arg2;
-
-  mask_m = (1 << g_m) - 1;
-  mask_r = (1 << g_r) - 1;
-
-  if (b128[0] != gt->m_table[2] || b128[1] != gt->m_table[3]) {
-    gf_w128_group_m_init(gf, b128);
-  }
-  
-  p_i[0] = 0;
-  p_i[1] = 0;
-  a[0] = a128[0];
-  a[1] = a128[1];
-
-  t_m = 0;
-  i_r = 0;
-
-  /* Top 64 bits */
-  for (i = ((GF_FIELD_WIDTH / 2) / g_m) - 1; i >= 0; i--) {
-    i_m = (a[0] >> (i * g_m)) & mask_m;
-    i_r ^= (p_i[0] >> (64 - g_m)) & mask_r;
-    p_i[0] <<= g_m;
-    p_i[0] ^= (p_i[1] >> (64-g_m));
-    p_i[1] <<= g_m;
-    p_i[0] ^= gt->m_table[2 * i_m];
-    p_i[1] ^= gt->m_table[(2 * i_m) + 1];
-    t_m += g_m;
-    if (t_m == g_r) {
-      p_i[1] ^= gt->r_table[i_r];
-      t_m = 0;
-      i_r = 0;
-    } else {
-      i_r <<= g_m;
-    }
-  }
-
-  for (i = ((GF_FIELD_WIDTH / 2) / g_m) - 1; i >= 0; i--) {
-    i_m = (a[1] >> (i * g_m)) & mask_m;
-    i_r ^= (p_i[0] >> (64 - g_m)) & mask_r;
-    p_i[0] <<= g_m;
-    p_i[0] ^= (p_i[1] >> (64-g_m));
-    p_i[1] <<= g_m;
-    p_i[0] ^= gt->m_table[2 * i_m];
-    p_i[1] ^= gt->m_table[(2 * i_m) + 1];
-    t_m += g_m;
-    if (t_m == g_r) {
-      p_i[1] ^= gt->r_table[i_r];
-      t_m = 0;
-      i_r = 0;
-    } else {
-      i_r <<= g_m;
-    }
-  }
-  c128[0] = p_i[0];
-  c128[1] = p_i[1];
-}
-
-static
-void
-gf_w128_group_multiply_region(gf_t *gf, void *src, void *dest, gf_val_128_t val, int bytes, int xor)
-{
-  int i;
-  int i_r, i_m, t_m;
-  int mask_m, mask_r;
-  int g_m, g_r;
-  uint64_t p_i[2], a[2];
-  gf_internal_t *scratch;
-  gf_group_tables_t *gt;
-  gf_region_data rd;
-  uint64_t *a128, *c128, *top;
-
-  /* We only do this to check on alignment. */
-  gf_set_region_data(&rd, gf, src, dest, bytes, 0, xor, 8);
-      
-  if (val[0] == 0) {
-    if (val[1] == 0) { gf_multby_zero(dest, bytes, xor); return; }
-    if (val[1] == 1) { gf_multby_one(src, dest, bytes, xor); return; }
-  }
-    
-  scratch = (gf_internal_t *) gf->scratch;
-  gt = scratch->private;
-  g_m = scratch->arg1;
-  g_r = scratch->arg2;
-
-  mask_m = (1 << g_m) - 1;
-  mask_r = (1 << g_r) - 1;
-
-  if (val[0] != gt->m_table[2] || val[1] != gt->m_table[3]) {
-    gf_w128_group_m_init(gf, val);
-  }
-
-  a128 = (uint64_t *) src;
-  c128 = (uint64_t *) dest;
-  top = (uint64_t *) rd.d_top;
-
-  while (c128 < top) {
-    p_i[0] = 0;
-    p_i[1] = 0;
-    a[0] = a128[0];
-    a[1] = a128[1];
-  
-    t_m = 0;
-    i_r = 0;
-  
-    /* Top 64 bits */
-    for (i = ((GF_FIELD_WIDTH / 2) / g_m) - 1; i >= 0; i--) {
-      i_m = (a[0] >> (i * g_m)) & mask_m;
-      i_r ^= (p_i[0] >> (64 - g_m)) & mask_r;
-      p_i[0] <<= g_m;
-      p_i[0] ^= (p_i[1] >> (64-g_m));
-      p_i[1] <<= g_m;
-      
-      p_i[0] ^= gt->m_table[2 * i_m];
-      p_i[1] ^= gt->m_table[(2 * i_m) + 1];
-      t_m += g_m;
-      if (t_m == g_r) {
-        p_i[1] ^= gt->r_table[i_r];
-        t_m = 0;
-        i_r = 0;
-      } else {
-        i_r <<= g_m;
-      }
-    }
-    for (i = ((GF_FIELD_WIDTH / 2) / g_m) - 1; i >= 0; i--) {
-      i_m = (a[1] >> (i * g_m)) & mask_m;
-      i_r ^= (p_i[0] >> (64 - g_m)) & mask_r;
-      p_i[0] <<= g_m;
-      p_i[0] ^= (p_i[1] >> (64-g_m));
-      p_i[1] <<= g_m;
-      p_i[0] ^= gt->m_table[2 * i_m];
-      p_i[1] ^= gt->m_table[(2 * i_m) + 1];
-      t_m += g_m;
-      if (t_m == g_r) {
-        p_i[1] ^= gt->r_table[i_r];
-        t_m = 0;
-        i_r = 0;
-      } else {
-        i_r <<= g_m;
-      }
-    }
-  
-    if (xor) {
-      c128[0] ^= p_i[0];
-      c128[1] ^= p_i[1];
-    } else {
-      c128[0] = p_i[0];
-      c128[1] = p_i[1];
-    }
-    a128 += 2;
-    c128 += 2;
-  }
-}
-
-/* a^-1 -> b */
-  void
-gf_w128_euclid(GFP gf, gf_val_128_t a128, gf_val_128_t b128)
-{
-  uint64_t e_i[2], e_im1[2], e_ip1[2];
-  uint64_t d_i, d_im1, d_ip1;
-  uint64_t y_i[2], y_im1[2], y_ip1[2];
-  uint64_t c_i[2];
-  uint64_t *b;
-  uint64_t one = 1;
-
-  /* This needs to return some sort of error (in b128?) */
-  if (a128[0] == 0 && a128[1] == 0) return;
-
-  b = (uint64_t *) b128;
-
-  e_im1[0] = 0;
-  e_im1[1] = ((gf_internal_t *) (gf->scratch))->prim_poly;
-  e_i[0] = a128[0];
-  e_i[1] = a128[1];
-  d_im1 = 128;
-
-  //Allen: I think d_i starts at 63 here, and checks each bit of a, starting at MSB, looking for the first nonzero bit
-  //so d_i should be 0 if this half of a is all 0s, otherwise it should be the position from right of the first-from-left zero bit of this half of a.
-  //BUT if d_i is 0 at end we won't know yet if the rightmost bit of this half is 1 or not
-
-  for (d_i = (d_im1-1) % 64; ((one << d_i) & e_i[0]) == 0 && d_i > 0; d_i--) ;
-
-  //Allen: this is testing just the first half of the stop condition above, so if it holds we know we did not find a nonzero bit yet
-
-  if (!((one << d_i) & e_i[0])) {
-
-    //Allen: this is doing the same thing on the other half of a. In other words, we're still searching for a nonzero bit of a.
-    // but not bothering to test if d_i hits zero, which is fine because we've already tested for a=0.
-
-    for (d_i = (d_im1-1) % 64; ((one << d_i) & e_i[1]) == 0; d_i--) ;
-
-  } else {
-
-    //Allen: if a 1 was found in more-significant half of a, make d_i the ACTUAL index of the first nonzero bit in the entire a.
-
-    d_i += 64;
-  }
-  y_i[0] = 0;
-  y_i[1] = 1;
-  y_im1[0] = 0;
-  y_im1[1] = 0;
-
-  while (!(e_i[0] == 0 && e_i[1] == 1)) {
-
-    e_ip1[0] = e_im1[0];
-    e_ip1[1] = e_im1[1];
-    d_ip1 = d_im1;
-    c_i[0] = 0;
-    c_i[1] = 0;
-
-    while (d_ip1 >= d_i) {
-      if ((d_ip1 - d_i) >= 64) {
-        c_i[0] ^= (one << ((d_ip1 - d_i) - 64));
-        e_ip1[0] ^= (e_i[1] << ((d_ip1 - d_i) - 64));
-      } else {
-        c_i[1] ^= (one << (d_ip1 - d_i));
-        e_ip1[0] ^= (e_i[0] << (d_ip1 - d_i));
-        if (d_ip1 - d_i > 0) e_ip1[0] ^= (e_i[1] >> (64 - (d_ip1 - d_i)));
-        e_ip1[1] ^= (e_i[1] << (d_ip1 - d_i));
-      }
-      d_ip1--;
-      if (e_ip1[0] == 0 && e_ip1[1] == 0) { b[0] = 0; b[1] = 0; return; }
-      while (d_ip1 >= 64 && (e_ip1[0] & (one << (d_ip1 - 64))) == 0) d_ip1--;
-      while (d_ip1 <  64 && (e_ip1[1] & (one << d_ip1)) == 0) d_ip1--;
-    }
-    gf->multiply.w128(gf, c_i, y_i, y_ip1);
-    y_ip1[0] ^= y_im1[0];
-    y_ip1[1] ^= y_im1[1];
-
-    y_im1[0] = y_i[0];
-    y_im1[1] = y_i[1];
-
-    y_i[0] = y_ip1[0];
-    y_i[1] = y_ip1[1];
-
-    e_im1[0] = e_i[0];
-    e_im1[1] = e_i[1];
-    d_im1 = d_i;
-    e_i[0] = e_ip1[0];
-    e_i[1] = e_ip1[1];
-    d_i = d_ip1;
-  }
-
-  b[0] = y_i[0];
-  b[1] = y_i[1];
-  return;
-}
-
-  void
-gf_w128_divide_from_inverse(GFP gf, gf_val_128_t a128, gf_val_128_t b128, gf_val_128_t c128)
-{
-  uint64_t d[2];
-  gf->inverse.w128(gf, b128, d);
-  gf->multiply.w128(gf, a128, d, c128);
-  return;
-}
-
-  void
-gf_w128_inverse_from_divide(GFP gf, gf_val_128_t a128, gf_val_128_t b128)
-{
-  uint64_t one128[2];
-  one128[0] = 0;
-  one128[1] = 1;
-  gf->divide.w128(gf, one128, a128, b128);
-  return;
-}
-
-
-static
-  void
-gf_w128_composite_inverse(gf_t *gf, gf_val_128_t a, gf_val_128_t inv)
-{
-  gf_internal_t *h = (gf_internal_t *) gf->scratch;
-  gf_t *base_gf = h->base_gf;
-  uint64_t a0 = a[1];
-  uint64_t a1 = a[0];
-  uint64_t c0, c1, d, tmp;
-  uint64_t a0inv, a1inv;
-
-  if (a0 == 0) {
-    a1inv = base_gf->inverse.w64(base_gf, a1);
-    c0 = base_gf->multiply.w64(base_gf, a1inv, h->prim_poly);
-    c1 = a1inv;
-  } else if (a1 == 0) {
-    c0 = base_gf->inverse.w64(base_gf, a0);
-    c1 = 0;
-  } else {
-    a1inv = base_gf->inverse.w64(base_gf, a1);
-    a0inv = base_gf->inverse.w64(base_gf, a0);
-
-    d = base_gf->multiply.w64(base_gf, a1, a0inv);
-
-    tmp = (base_gf->multiply.w64(base_gf, a1, a0inv) ^ base_gf->multiply.w64(base_gf, a0, a1inv) ^ h->prim_poly);
-    tmp = base_gf->inverse.w64(base_gf, tmp);
-
-    d = base_gf->multiply.w64(base_gf, d, tmp);
-
-    c0 = base_gf->multiply.w64(base_gf, (d^1), a0inv);
-    c1 = base_gf->multiply.w64(base_gf, d, a1inv);
-  }
-  inv[0] = c1;
-  inv[1] = c0;
-}
-
-static
-  void
-gf_w128_composite_multiply(gf_t *gf, gf_val_128_t a, gf_val_128_t b, gf_val_128_t rv)
-{
-  gf_internal_t *h = (gf_internal_t *) gf->scratch;
-  gf_t *base_gf = h->base_gf;
-  uint64_t b0 = b[1];
-  uint64_t b1 = b[0];
-  uint64_t a0 = a[1];
-  uint64_t a1 = a[0];
-  uint64_t a1b1;
-
-  a1b1 = base_gf->multiply.w64(base_gf, a1, b1);
-
-  rv[1] = (base_gf->multiply.w64(base_gf, a0, b0) ^ a1b1);
-  rv[0] = base_gf->multiply.w64(base_gf, a1, b0) ^ 
-    base_gf->multiply.w64(base_gf, a0, b1) ^ 
-    base_gf->multiply.w64(base_gf, a1b1, h->prim_poly);
-}
-
-static
-  void
-gf_w128_composite_multiply_region(gf_t *gf, void *src, void *dest, gf_val_128_t val, int bytes, int xor)
-{
-  gf_internal_t *h = (gf_internal_t *) gf->scratch;
-  gf_t *base_gf = h->base_gf;
-  uint64_t b0 = val[1];
-  uint64_t b1 = val[0];
-  uint64_t *s64, *d64;
-  uint64_t *top;
-  uint64_t a0, a1, a1b1;
-  gf_region_data rd;
-
-  if (val[0] == 0 && val[1] == 0) { gf_multby_zero(dest, bytes, xor); return; }
-
-  gf_set_region_data(&rd, gf, src, dest, bytes, 0, xor, 8);
-
-  s64 = rd.s_start;
-  d64 = rd.d_start;
-  top = rd.d_top;
-
-  if (xor) {
-    while (d64 < top) {
-      a1 = s64[0];
-      a0 = s64[1];
-      a1b1 = base_gf->multiply.w64(base_gf, a1, b1);
-
-      d64[1] ^= (base_gf->multiply.w64(base_gf, a0, b0) ^ a1b1);
-      d64[0] ^= (base_gf->multiply.w64(base_gf, a1, b0) ^ 
-          base_gf->multiply.w64(base_gf, a0, b1) ^ 
-          base_gf->multiply.w64(base_gf, a1b1, h->prim_poly));
-      s64 += 2;
-      d64 += 2;
-    }
-  } else {
-    while (d64 < top) {
-      a1 = s64[0];
-      a0 = s64[1];
-      a1b1 = base_gf->multiply.w64(base_gf, a1, b1);
-
-      d64[1] = (base_gf->multiply.w64(base_gf, a0, b0) ^ a1b1);
-      d64[0] = (base_gf->multiply.w64(base_gf, a1, b0) ^ 
-          base_gf->multiply.w64(base_gf, a0, b1) ^ 
-          base_gf->multiply.w64(base_gf, a1b1, h->prim_poly));
-      s64 += 2;
-      d64 += 2;
-    }
-  }
-}
-
-static
-void
-gf_w128_composite_multiply_region_alt(gf_t *gf, void *src, void *dest, gf_val_128_t val, int bytes, int 
-    xor)
-{
-  gf_internal_t *h = (gf_internal_t *) gf->scratch;  gf_t *base_gf = h->base_gf;
-  gf_val_64_t val0 = val[1];
-  gf_val_64_t val1 = val[0];
-  uint8_t *slow, *shigh;
-  uint8_t *dlow, *dhigh, *top;
-  int sub_reg_size;
-  gf_region_data rd;
-
-  gf_set_region_data(&rd, gf, src, dest, bytes, 0, xor, 64);
-  gf_w128_multiply_region_from_single(gf, src, dest, val, ((uint8_t *)rd.s_start-(uint8_t *)src), xor);
-
-  slow = (uint8_t *) rd.s_start;
-  dlow = (uint8_t *) rd.d_start;
-  top = (uint8_t*) rd.d_top;
-  sub_reg_size = (top - dlow)/2;
-  shigh = slow + sub_reg_size;
-  dhigh = dlow + sub_reg_size;
-
-  base_gf->multiply_region.w64(base_gf, slow, dlow, val0, sub_reg_size, xor);
-  base_gf->multiply_region.w64(base_gf, shigh, dlow, val1, sub_reg_size, 1);
-  base_gf->multiply_region.w64(base_gf, slow, dhigh, val1, sub_reg_size, xor);
-  base_gf->multiply_region.w64(base_gf, shigh, dhigh, val0, sub_reg_size, 1);
-  base_gf->multiply_region.w64(base_gf, shigh, dhigh, base_gf->multiply.w64(base_gf, h->prim_poly, val1
-        ), sub_reg_size, 1);
-
-  gf_w128_multiply_region_from_single(gf, rd.s_top, rd.d_top, val, ((uint8_t *)src+bytes)-(uint8_t *)rd.s_top, xor);
-}
-
-
-  static
-int gf_w128_composite_init(gf_t *gf)
-{
-  gf_internal_t *h = (gf_internal_t *) gf->scratch;
-
-  if (h->region_type & GF_REGION_ALTMAP) {
-    gf->multiply_region.w128 = gf_w128_composite_multiply_region_alt;   
-  } else {
-    gf->multiply_region.w128 = gf_w128_composite_multiply_region;
-  }
-
-  gf->multiply.w128 = gf_w128_composite_multiply;
-  gf->divide.w128 = gf_w128_divide_from_inverse;
-  gf->inverse.w128 = gf_w128_composite_inverse;
-
-  return 1;
-}
-
-static
-int gf_w128_cfm_init(gf_t *gf)
-{
-#if defined(INTEL_SSE4_PCLMUL)
-  gf->inverse.w128 = gf_w128_euclid;
-  gf->multiply.w128 = gf_w128_clm_multiply;
-  gf->multiply_region.w128 = gf_w128_clm_multiply_region_from_single;
-  return 1;
-#endif
-
-  return 0;
-}
-
-static
-int gf_w128_shift_init(gf_t *gf)
-{
-  gf->multiply.w128 = gf_w128_shift_multiply;
-  gf->inverse.w128 = gf_w128_euclid;
-  gf->multiply_region.w128 = gf_w128_multiply_region_from_single;
-  return 1;
-}
-
-  static
-int gf_w128_bytwo_init(gf_t *gf)
-{
-  gf_internal_t *h;
-  h = (gf_internal_t *) gf->scratch;
-
-  if (h->mult_type == GF_MULT_BYTWO_p) {
-    gf->multiply.w128 = gf_w128_bytwo_p_multiply;
-    /*gf->multiply.w128 = gf_w128_sse_bytwo_p_multiply;*/
-    /* John: the sse function is slower.*/
-  } else {
-    gf->multiply.w128 = gf_w128_bytwo_b_multiply;
-    /*gf->multiply.w128 = gf_w128_sse_bytwo_b_multiply;
-Ben: This sse function is also slower. */
-  }
-  gf->inverse.w128 = gf_w128_euclid;
-  gf->multiply_region.w128 = gf_w128_bytwo_b_multiply_region;
-  return 1;
-}
-
-/*
- * Because the prim poly is only 8 bits and we are limiting g_r to 16, I do not need the high 64
- * bits in all of these numbers.
- */
-  static
-void gf_w128_group_r_init(gf_t *gf)
-{
-  int i, j;
-  int g_r;
-  uint64_t pp;
-  gf_internal_t *scratch;
-  gf_group_tables_t *gt;
-  scratch = (gf_internal_t *) gf->scratch;
-  gt = scratch->private;
-  g_r = scratch->arg2;
-  pp = scratch->prim_poly;
-
-  gt->r_table[0] = 0;
-  for (i = 1; i < (1 << g_r); i++) {
-    gt->r_table[i] = 0;
-    for (j = 0; j < g_r; j++) {
-      if (i & (1 << j)) {
-        gt->r_table[i] ^= (pp << j);
-      }
-    }
-  }
-  return;
-}
-
-#if 0 // defined(INTEL_SSE4)
-  static
-void gf_w128_group_r_sse_init(gf_t *gf)
-{
-  int i, j;
-  int g_r;
-  uint64_t pp;
-  gf_internal_t *scratch;
-  gf_group_tables_t *gt;
-  scratch = (gf_internal_t *) gf->scratch;
-  gt = scratch->private;
-  __m128i zero = _mm_setzero_si128();
-  __m128i *table = (__m128i *)(gt->r_table);
-  g_r = scratch->arg2;
-  pp = scratch->prim_poly;
-  table[0] = zero;
-  for (i = 1; i < (1 << g_r); i++) {
-    table[i] = zero;
-    for (j = 0; j < g_r; j++) {
-      if (i & (1 << j)) {
-        table[i] = _mm_xor_si128(table[i], _mm_insert_epi64(zero, pp << j, 0));
-      }
-    }
-  }
-  return;
-}
-#endif
-
-  static 
-int gf_w128_split_init(gf_t *gf)
-{
-  struct gf_w128_split_4_128_data *sd4;
-  struct gf_w128_split_8_128_data *sd8;
-  gf_internal_t *h;
-
-  h = (gf_internal_t *) gf->scratch;
-
-  gf->multiply.w128 = gf_w128_bytwo_p_multiply;
-#if defined(INTEL_SSE4_PCLMUL)
-  if (!(h->region_type & GF_REGION_NOSIMD)){
-    gf->multiply.w128 = gf_w128_clm_multiply;
-  }
-#endif
-
-  gf->inverse.w128 = gf_w128_euclid;
-
-  if ((h->arg1 != 4 && h->arg2 != 4) || h->mult_type == GF_MULT_DEFAULT) {
-    sd8 = (struct gf_w128_split_8_128_data *) h->private;
-    sd8->last_value[0] = 0;
-    sd8->last_value[1] = 0;
-    gf->multiply_region.w128 = gf_w128_split_8_128_multiply_region;
-  } else {
-    sd4 = (struct gf_w128_split_4_128_data *) h->private;
-    sd4->last_value[0] = 0;
-    sd4->last_value[1] = 0;
-    if((h->region_type & GF_REGION_ALTMAP))
-    {
-      #ifdef INTEL_SSE4
-        if(!(h->region_type & GF_REGION_NOSIMD))
-          gf->multiply_region.w128 = gf_w128_split_4_128_sse_altmap_multiply_region;
-        else
-          return 0;
-      #else
-        return 0;
-      #endif
-    }
-    else {
-      #ifdef INTEL_SSE4
-        if(!(h->region_type & GF_REGION_NOSIMD))
-          gf->multiply_region.w128 = gf_w128_split_4_128_sse_multiply_region;
-        else
-          gf->multiply_region.w128 = gf_w128_split_4_128_multiply_region;
-      #else
-      gf->multiply_region.w128 = gf_w128_split_4_128_multiply_region;
-      #endif
-    }
-  }
-  return 1;
-}
-
-
-static
-int gf_w128_group_init(gf_t *gf)
-{
-  gf_internal_t *scratch;
-  gf_group_tables_t *gt;
-  int g_r, size_r;
-
-  scratch = (gf_internal_t *) gf->scratch;
-  gt = scratch->private;
-  g_r = scratch->arg2;
-  size_r = (1 << g_r);
-
-  gt->r_table = (gf_val_128_t)((uint8_t *)scratch->private + (2 * sizeof(uint64_t *)));
-  gt->m_table = gt->r_table + size_r;
-  gt->m_table[2] = 0;
-  gt->m_table[3] = 0;
-
-  gf->multiply.w128 = gf_w128_group_multiply;
-  gf->inverse.w128 = gf_w128_euclid;
-  gf->multiply_region.w128 = gf_w128_group_multiply_region;
-
-  gf_w128_group_r_init(gf);
-
-  return 1;
-}
-
-void gf_w128_extract_word(gf_t *gf, void *start, int bytes, int index, gf_val_128_t rv)
-{
-  gf_val_128_t s;
-
-  s = (gf_val_128_t) start;
-  s += (index * 2); 
-  memcpy(rv, s, 16);
-}
-
-static void gf_w128_split_extract_word(gf_t *gf, void *start, int bytes, int index, gf_val_128_t rv)
-{
-  int i, blocks;
-  uint64_t *r64, tmp;
-  uint8_t *r8;
-  gf_region_data rd;
-
-  gf_set_region_data(&rd, gf, start, start, bytes, 0, 0, 256);
-  r64 = (uint64_t *) start;
-  if ((r64 + index*2 < (uint64_t *) rd.d_start) ||
-      (r64 + index*2 >= (uint64_t *) rd.d_top)) {
-    memcpy(rv, r64+(index*2), 16);
-    return;
-  }
-
-  index -= (((uint64_t *) rd.d_start) - r64)/2;
-  r64 = (uint64_t *) rd.d_start;
-
-  blocks = index/16;
-  r64 += (blocks*32);
-  index %= 16;
-  r8 = (uint8_t *) r64;
-  r8 += index;
-  rv[0] = 0;
-  rv[1] = 0;
-
-  for (i = 0; i < 8; i++) {
-    tmp = *r8;
-    rv[1] |= (tmp << (i*8));
-    r8 += 16;
-  }
-
-  for (i = 0; i < 8; i++) {
-    tmp = *r8;
-    rv[0] |= (tmp << (i*8));
-    r8 += 16;
-  }
-  return;
-}
-
-  static
-void gf_w128_composite_extract_word(gf_t *gf, void *start, int bytes, int index, gf_val_128_t rv)
-{
-  int sub_size;
-  gf_internal_t *h;
-  uint8_t *r8, *top;
-  uint64_t *r64;
-  gf_region_data rd;
-
-  h = (gf_internal_t *) gf->scratch;
-  gf_set_region_data(&rd, gf, start, start, bytes, 0, 0, 64);
-  r64 = (uint64_t *) start;
-  if ((r64 + index*2 < (uint64_t *) rd.d_start) ||
-      (r64 + index*2 >= (uint64_t *) rd.d_top)) {
-    memcpy(rv, r64+(index*2), 16);
-    return;
-  }
-  index -= (((uint64_t *) rd.d_start) - r64)/2;
-  r8 = (uint8_t *) rd.d_start;
-  top = (uint8_t *) rd.d_top;
-  sub_size = (top-r8)/2;
-
-  rv[1] = h->base_gf->extract_word.w64(h->base_gf, r8, sub_size, index);
-  rv[0] = h->base_gf->extract_word.w64(h->base_gf, r8+sub_size, sub_size, index);
-  
-  return;
-}
-
-int gf_w128_scratch_size(int mult_type, int region_type, int divide_type, int arg1, int arg2)
-{
-  int size_m, size_r;
-  if (divide_type==GF_DIVIDE_MATRIX) return 0;
-
-  switch(mult_type)
-  {
-    case GF_MULT_CARRY_FREE:
-      return sizeof(gf_internal_t);
-      break;
-    case GF_MULT_SHIFT:
-      return sizeof(gf_internal_t);
-      break;
-    case GF_MULT_BYTWO_p:
-    case GF_MULT_BYTWO_b:
-      return sizeof(gf_internal_t);
-      break;
-    case GF_MULT_DEFAULT: 
-    case GF_MULT_SPLIT_TABLE:
-      if ((arg1 == 4 && arg2 == 128) || (arg1 == 128 && arg2 == 4)) {
-        return sizeof(gf_internal_t) + sizeof(struct gf_w128_split_4_128_data) + 64;
-      } else if ((arg1 == 8 && arg2 == 128) || (arg1 == 128 && arg2 == 8) || mult_type == GF_MULT_DEFAULT) {
-        return sizeof(gf_internal_t) + sizeof(struct gf_w128_split_8_128_data) + 64;
-      }
-      return 0;
-      break;
-    case GF_MULT_GROUP:
-      /* JSP We've already error checked the arguments. */
-      size_m = (1 << arg1) * 2 * sizeof(uint64_t);
-      size_r = (1 << arg2) * 2 * sizeof(uint64_t);
-      /* 
-       * two pointers prepend the table data for structure
-       * because the tables are of dynamic size
-       */
-      return sizeof(gf_internal_t) + size_m + size_r + 4 * sizeof(uint64_t *);
-      break;
-    case GF_MULT_COMPOSITE:
-      if (arg1 == 2) {
-        return sizeof(gf_internal_t) + 4;
-      } else {
-        return 0;
-      }
-      break;
-
-    default:
-      return 0;
-   }
-}
-
-int gf_w128_init(gf_t *gf)
-{
-  gf_internal_t *h;
-  int no_default_flag = 0;
-
-  h = (gf_internal_t *) gf->scratch;
-  
-  /* Allen: set default primitive polynomial / irreducible polynomial if needed */
-
-  if (h->prim_poly == 0) {
-    if (h->mult_type == GF_MULT_COMPOSITE) {
-      h->prim_poly = gf_composite_get_default_poly(h->base_gf);
-      if (h->prim_poly == 0) return 0; /* This shouldn't happen */
-    } else {
-      h->prim_poly = 0x87; /* Omitting the leftmost 1 as in w=32 */
-    }
-    if (no_default_flag == 1) {
-      fprintf(stderr,"Code contains no default irreducible polynomial for given base field\n");
-      return 0;
-    }
-  }
-
-  gf->multiply.w128 = NULL;
-  gf->divide.w128 = NULL;
-  gf->inverse.w128 = NULL;
-  gf->multiply_region.w128 = NULL;
-  switch(h->mult_type) {
-    case GF_MULT_BYTWO_p:
-    case GF_MULT_BYTWO_b:      if (gf_w128_bytwo_init(gf) == 0) return 0; break;
-    case GF_MULT_CARRY_FREE:   if (gf_w128_cfm_init(gf) == 0) return 0; break;
-    case GF_MULT_SHIFT:        if (gf_w128_shift_init(gf) == 0) return 0; break;
-    case GF_MULT_GROUP:        if (gf_w128_group_init(gf) == 0) return 0; break;
-    case GF_MULT_DEFAULT: 
-    case GF_MULT_SPLIT_TABLE:  if (gf_w128_split_init(gf) == 0) return 0; break;
-    case GF_MULT_COMPOSITE:    if (gf_w128_composite_init(gf) == 0) return 0; break;
-    default: return 0;
-  }
-
-  /* Ben: Used to be h->region_type == GF_REGION_ALTMAP, but failed since there
-     are multiple flags in h->region_type */
-  if (h->mult_type == GF_MULT_SPLIT_TABLE && (h->region_type & GF_REGION_ALTMAP)) {
-    gf->extract_word.w128 = gf_w128_split_extract_word;
-  } else if (h->mult_type == GF_MULT_COMPOSITE && h->region_type == GF_REGION_ALTMAP) {
-    gf->extract_word.w128 = gf_w128_composite_extract_word;
-  } else {
-    gf->extract_word.w128 = gf_w128_extract_word;
-  }
-
-  if (h->divide_type == GF_DIVIDE_EUCLID) {
-    gf->divide.w128 = gf_w128_divide_from_inverse;
-  } 
-
-  if (gf->inverse.w128 != NULL && gf->divide.w128 == NULL) {
-    gf->divide.w128 = gf_w128_divide_from_inverse;
-  }
-  if (gf->inverse.w128 == NULL && gf->divide.w128 != NULL) {
-    gf->inverse.w128 = gf_w128_inverse_from_divide;
-  }
-  return 1;
-}
diff --git a/src/erasure-code/jerasure/gf-complete/src/gf_w16.c b/src/erasure-code/jerasure/gf-complete/src/gf_w16.c
deleted file mode 100644
index 4e026b2..0000000
--- a/src/erasure-code/jerasure/gf-complete/src/gf_w16.c
+++ /dev/null
@@ -1,2452 +0,0 @@
-/*
- * GF-Complete: A Comprehensive Open Source Library for Galois Field Arithmetic
- * James S. Plank, Ethan L. Miller, Kevin M. Greenan,
- * Benjamin A. Arnold, John A. Burnum, Adam W. Disney, Allen C. McBride.
- *
- * gf_w16.c
- *
- * Routines for 16-bit Galois fields
- */
-
-#include "gf_int.h"
-#include <stdio.h>
-#include <stdlib.h>
-#include "gf_w16.h"
-
-#define AB2(ip, am1 ,am2, b, t1, t2) {\
-  t1 = (b << 1) & am1;\
-  t2 = b & am2; \
-  t2 = ((t2 << 1) - (t2 >> (GF_FIELD_WIDTH-1))); \
-  b = (t1 ^ (t2 & ip));}
-
-#define SSE_AB2(pp, m1 ,m2, va, t1, t2) {\
-          t1 = _mm_and_si128(_mm_slli_epi64(va, 1), m1); \
-          t2 = _mm_and_si128(va, m2); \
-          t2 = _mm_sub_epi64 (_mm_slli_epi64(t2, 1), _mm_srli_epi64(t2, (GF_FIELD_WIDTH-1))); \
-          va = _mm_xor_si128(t1, _mm_and_si128(t2, pp)); }
-
-#define MM_PRINT(s, r) { uint8_t blah[16], ii; printf("%-12s", s); _mm_storeu_si128((__m128i *)blah, r); for (ii = 0; ii < 16; ii += 2) printf("  %02x %02x", blah[15-ii], blah[14-ii]); printf("\n"); }
-
-#define GF_FIRST_BIT (1 << 15)
-#define GF_MULTBY_TWO(p) (((p) & GF_FIRST_BIT) ? (((p) << 1) ^ h->prim_poly) : (p) << 1)
-
-static
-inline
-gf_val_32_t gf_w16_inverse_from_divide (gf_t *gf, gf_val_32_t a)
-{
-  return gf->divide.w32(gf, 1, a);
-}
-
-static
-inline
-gf_val_32_t gf_w16_divide_from_inverse (gf_t *gf, gf_val_32_t a, gf_val_32_t b)
-{
-  b = gf->inverse.w32(gf, b);
-  return gf->multiply.w32(gf, a, b);
-}
-
-static
-void
-gf_w16_multiply_region_from_single(gf_t *gf, void *src, void *dest, gf_val_32_t val, int bytes, int xor)
-{
-  gf_region_data rd;
-  uint16_t *s16;
-  uint16_t *d16;
-  
-  if (val == 0) { gf_multby_zero(dest, bytes, xor); return; }
-  if (val == 1) { gf_multby_one(src, dest, bytes, xor); return; }
-
-  gf_set_region_data(&rd, gf, src, dest, bytes, val, xor, 2);
-  gf_do_initial_region_alignment(&rd);
-
-  s16 = (uint16_t *) rd.s_start;
-  d16 = (uint16_t *) rd.d_start;
-
-  if (xor) {
-    while (d16 < ((uint16_t *) rd.d_top)) {
-      *d16 ^= gf->multiply.w32(gf, val, *s16);
-      d16++;
-      s16++;
-    } 
-  } else {
-    while (d16 < ((uint16_t *) rd.d_top)) {
-      *d16 = gf->multiply.w32(gf, val, *s16);
-      d16++;
-      s16++;
-    } 
-  }
-  gf_do_final_region_alignment(&rd);
-}
-
-#if defined(INTEL_SSE4_PCLMUL)
-static
-void
-gf_w16_clm_multiply_region_from_single_2(gf_t *gf, void *src, void *dest, gf_val_32_t val, int bytes, int xor)
-{
-  gf_region_data rd;
-  uint16_t *s16;
-  uint16_t *d16;
-  __m128i         a, b;
-  __m128i         result;
-  __m128i         prim_poly;
-  __m128i         w;
-  gf_internal_t * h = gf->scratch;
-  prim_poly = _mm_set_epi32(0, 0, 0, (uint32_t)(h->prim_poly & 0x1ffffULL));
-
-  if (val == 0) { gf_multby_zero(dest, bytes, xor); return; }
-  if (val == 1) { gf_multby_one(src, dest, bytes, xor); return; }
-
-  gf_set_region_data(&rd, gf, src, dest, bytes, val, xor, 2);
-  gf_do_initial_region_alignment(&rd);
-
-  a = _mm_insert_epi32 (_mm_setzero_si128(), val, 0);
-  
-  s16 = (uint16_t *) rd.s_start;
-  d16 = (uint16_t *) rd.d_start;
-
-  if (xor) {
-    while (d16 < ((uint16_t *) rd.d_top)) {
-
-      /* see gf_w16_clm_multiply() to see explanation of method */
-      
-      b = _mm_insert_epi32 (a, (gf_val_32_t)(*s16), 0);
-      result = _mm_clmulepi64_si128 (a, b, 0);
-      w = _mm_clmulepi64_si128 (prim_poly, _mm_srli_si128 (result, 2), 0);
-      result = _mm_xor_si128 (result, w);
-      w = _mm_clmulepi64_si128 (prim_poly, _mm_srli_si128 (result, 2), 0);
-      result = _mm_xor_si128 (result, w);
-
-      *d16 ^= ((gf_val_32_t)_mm_extract_epi32(result, 0));
-      d16++;
-      s16++;
-    } 
-  } else {
-    while (d16 < ((uint16_t *) rd.d_top)) {
-      
-      /* see gf_w16_clm_multiply() to see explanation of method */
-      
-      b = _mm_insert_epi32 (a, (gf_val_32_t)(*s16), 0);
-      result = _mm_clmulepi64_si128 (a, b, 0);
-      w = _mm_clmulepi64_si128 (prim_poly, _mm_srli_si128 (result, 2), 0);
-      result = _mm_xor_si128 (result, w);
-      w = _mm_clmulepi64_si128 (prim_poly, _mm_srli_si128 (result, 2), 0);
-      result = _mm_xor_si128 (result, w);
-      
-      *d16 = ((gf_val_32_t)_mm_extract_epi32(result, 0));
-      d16++;
-      s16++;
-    } 
-  }
-  gf_do_final_region_alignment(&rd);
-}
-#endif
-
-#if defined(INTEL_SSE4_PCLMUL)
-static
-void
-gf_w16_clm_multiply_region_from_single_3(gf_t *gf, void *src, void *dest, gf_val_32_t val, int bytes, int xor)
-{
-  gf_region_data rd;
-  uint16_t *s16;
-  uint16_t *d16;
-
-  __m128i         a, b;
-  __m128i         result;
-  __m128i         prim_poly;
-  __m128i         w;
-  gf_internal_t * h = gf->scratch;
-  prim_poly = _mm_set_epi32(0, 0, 0, (uint32_t)(h->prim_poly & 0x1ffffULL));
-
-  if (val == 0) { gf_multby_zero(dest, bytes, xor); return; }
-  if (val == 1) { gf_multby_one(src, dest, bytes, xor); return; }
-
-  a = _mm_insert_epi32 (_mm_setzero_si128(), val, 0);
-  
-  gf_set_region_data(&rd, gf, src, dest, bytes, val, xor, 2);
-  gf_do_initial_region_alignment(&rd);
-
-  s16 = (uint16_t *) rd.s_start;
-  d16 = (uint16_t *) rd.d_start;
-
-  if (xor) {
-    while (d16 < ((uint16_t *) rd.d_top)) {
-      
-      /* see gf_w16_clm_multiply() to see explanation of method */
-      
-      b = _mm_insert_epi32 (a, (gf_val_32_t)(*s16), 0);
-      result = _mm_clmulepi64_si128 (a, b, 0);
-      w = _mm_clmulepi64_si128 (prim_poly, _mm_srli_si128 (result, 2), 0);
-      result = _mm_xor_si128 (result, w);
-      w = _mm_clmulepi64_si128 (prim_poly, _mm_srli_si128 (result, 2), 0);
-      result = _mm_xor_si128 (result, w);
-      w = _mm_clmulepi64_si128 (prim_poly, _mm_srli_si128 (result, 2), 0);
-      result = _mm_xor_si128 (result, w);
-
-      *d16 ^= ((gf_val_32_t)_mm_extract_epi32(result, 0));
-      d16++;
-      s16++;
-    } 
-  } else {
-    while (d16 < ((uint16_t *) rd.d_top)) {
-      
-      /* see gf_w16_clm_multiply() to see explanation of method */
-      
-      b = _mm_insert_epi32 (a, (gf_val_32_t)(*s16), 0);
-      result = _mm_clmulepi64_si128 (a, b, 0);
-      w = _mm_clmulepi64_si128 (prim_poly, _mm_srli_si128 (result, 2), 0);
-      result = _mm_xor_si128 (result, w);
-      w = _mm_clmulepi64_si128 (prim_poly, _mm_srli_si128 (result, 2), 0);
-      result = _mm_xor_si128 (result, w);
-      w = _mm_clmulepi64_si128 (prim_poly, _mm_srli_si128 (result, 2), 0);
-      result = _mm_xor_si128 (result, w);
-      
-      *d16 = ((gf_val_32_t)_mm_extract_epi32(result, 0));
-      d16++;
-      s16++;
-    } 
-  }
-  gf_do_final_region_alignment(&rd);
-}
-#endif
-
-#if defined(INTEL_SSE4_PCLMUL)
-static
-void
-gf_w16_clm_multiply_region_from_single_4(gf_t *gf, void *src, void *dest, gf_val_32_t val, int bytes, int xor)
-{
-  gf_region_data rd;
-  uint16_t *s16;
-  uint16_t *d16;
-
-  __m128i         a, b;
-  __m128i         result;
-  __m128i         prim_poly;
-  __m128i         w;
-  gf_internal_t * h = gf->scratch;
-  prim_poly = _mm_set_epi32(0, 0, 0, (uint32_t)(h->prim_poly & 0x1ffffULL));
-
-  if (val == 0) { gf_multby_zero(dest, bytes, xor); return; }
-  if (val == 1) { gf_multby_one(src, dest, bytes, xor); return; }
-
-  gf_set_region_data(&rd, gf, src, dest, bytes, val, xor, 2);
-  gf_do_initial_region_alignment(&rd);
-
-  a = _mm_insert_epi32 (_mm_setzero_si128(), val, 0);
-  
-  s16 = (uint16_t *) rd.s_start;
-  d16 = (uint16_t *) rd.d_start;
-
-  if (xor) {
-    while (d16 < ((uint16_t *) rd.d_top)) {
-      
-      /* see gf_w16_clm_multiply() to see explanation of method */
-      
-      b = _mm_insert_epi32 (a, (gf_val_32_t)(*s16), 0);
-      result = _mm_clmulepi64_si128 (a, b, 0);
-      w = _mm_clmulepi64_si128 (prim_poly, _mm_srli_si128 (result, 2), 0);
-      result = _mm_xor_si128 (result, w);
-      w = _mm_clmulepi64_si128 (prim_poly, _mm_srli_si128 (result, 2), 0);
-      result = _mm_xor_si128 (result, w);
-      w = _mm_clmulepi64_si128 (prim_poly, _mm_srli_si128 (result, 2), 0);
-      result = _mm_xor_si128 (result, w);
-      w = _mm_clmulepi64_si128 (prim_poly, _mm_srli_si128 (result, 2), 0);
-      result = _mm_xor_si128 (result, w);
-
-      *d16 ^= ((gf_val_32_t)_mm_extract_epi32(result, 0));
-      d16++;
-      s16++;
-    } 
-  } else {
-    while (d16 < ((uint16_t *) rd.d_top)) {
-      
-      /* see gf_w16_clm_multiply() to see explanation of method */
-      
-      b = _mm_insert_epi32 (a, (gf_val_32_t)(*s16), 0);
-      result = _mm_clmulepi64_si128 (a, b, 0);
-      w = _mm_clmulepi64_si128 (prim_poly, _mm_srli_si128 (result, 2), 0);
-      result = _mm_xor_si128 (result, w);
-      w = _mm_clmulepi64_si128 (prim_poly, _mm_srli_si128 (result, 2), 0);
-      result = _mm_xor_si128 (result, w);
-      w = _mm_clmulepi64_si128 (prim_poly, _mm_srli_si128 (result, 2), 0);
-      result = _mm_xor_si128 (result, w);
-      w = _mm_clmulepi64_si128 (prim_poly, _mm_srli_si128 (result, 2), 0);
-      result = _mm_xor_si128 (result, w);
-      
-      *d16 = ((gf_val_32_t)_mm_extract_epi32(result, 0));
-      d16++;
-      s16++;
-    } 
-  }
-  gf_do_final_region_alignment(&rd);
-}
-#endif
-
-static
-inline
-gf_val_32_t gf_w16_euclid (gf_t *gf, gf_val_32_t b)
-{
-  gf_val_32_t e_i, e_im1, e_ip1;
-  gf_val_32_t d_i, d_im1, d_ip1;
-  gf_val_32_t y_i, y_im1, y_ip1;
-  gf_val_32_t c_i;
-
-  if (b == 0) return -1;
-  e_im1 = ((gf_internal_t *) (gf->scratch))->prim_poly;
-  e_i = b;
-  d_im1 = 16;
-  for (d_i = d_im1; ((1 << d_i) & e_i) == 0; d_i--) ;
-  y_i = 1;
-  y_im1 = 0;
-
-  while (e_i != 1) {
-
-    e_ip1 = e_im1;
-    d_ip1 = d_im1;
-    c_i = 0;
-
-    while (d_ip1 >= d_i) {
-      c_i ^= (1 << (d_ip1 - d_i));
-      e_ip1 ^= (e_i << (d_ip1 - d_i));
-      if (e_ip1 == 0) return 0;
-      while ((e_ip1 & (1 << d_ip1)) == 0) d_ip1--;
-    }
-
-    y_ip1 = y_im1 ^ gf->multiply.w32(gf, c_i, y_i);
-    y_im1 = y_i;
-    y_i = y_ip1;
-
-    e_im1 = e_i;
-    d_im1 = d_i;
-    e_i = e_ip1;
-    d_i = d_ip1;
-  }
-
-  return y_i;
-}
-
-static
-gf_val_32_t gf_w16_extract_word(gf_t *gf, void *start, int bytes, int index)
-{
-  uint16_t *r16, rv;
-
-  r16 = (uint16_t *) start;
-  rv = r16[index];
-  return rv;
-}
-
-static
-gf_val_32_t gf_w16_composite_extract_word(gf_t *gf, void *start, int bytes, int index)
-{
-  int sub_size;
-  gf_internal_t *h;
-  uint8_t *r8, *top;
-  uint16_t a, b, *r16;
-  gf_region_data rd;
-
-  h = (gf_internal_t *) gf->scratch;
-  gf_set_region_data(&rd, gf, start, start, bytes, 0, 0, 32);
-  r16 = (uint16_t *) start;
-  if (r16 + index < (uint16_t *) rd.d_start) return r16[index];
-  if (r16 + index >= (uint16_t *) rd.d_top) return r16[index];
-  index -= (((uint16_t *) rd.d_start) - r16);
-  r8 = (uint8_t *) rd.d_start;
-  top = (uint8_t *) rd.d_top;
-  sub_size = (top-r8)/2;
-
-  a = h->base_gf->extract_word.w32(h->base_gf, r8, sub_size, index);
-  b = h->base_gf->extract_word.w32(h->base_gf, r8+sub_size, sub_size, index);
-  return (a | (b << 8));
-}
-
-static
-gf_val_32_t gf_w16_split_extract_word(gf_t *gf, void *start, int bytes, int index)
-{
-  uint16_t *r16, rv;
-  uint8_t *r8;
-  gf_region_data rd;
-
-  gf_set_region_data(&rd, gf, start, start, bytes, 0, 0, 32);
-  r16 = (uint16_t *) start;
-  if (r16 + index < (uint16_t *) rd.d_start) return r16[index];
-  if (r16 + index >= (uint16_t *) rd.d_top) return r16[index];
-  index -= (((uint16_t *) rd.d_start) - r16);
-  r8 = (uint8_t *) rd.d_start;
-  r8 += ((index & 0xfffffff0)*2);
-  r8 += (index & 0xf);
-  rv = (*r8 << 8);
-  r8 += 16;
-  rv |= *r8;
-  return rv;
-}
-
-static
-inline
-gf_val_32_t gf_w16_matrix (gf_t *gf, gf_val_32_t b)
-{
-  return gf_bitmatrix_inverse(b, 16, ((gf_internal_t *) (gf->scratch))->prim_poly);
-}
-
-/* JSP: GF_MULT_SHIFT: The world's dumbest multiplication algorithm.  I only
-   include it for completeness.  It does have the feature that it requires no
-   extra memory.  
- */
-
-static
-inline
-gf_val_32_t
-gf_w16_clm_multiply_2 (gf_t *gf, gf_val_32_t a16, gf_val_32_t b16)
-{
-  gf_val_32_t rv = 0;
-
-#if defined(INTEL_SSE4_PCLMUL)
-
-  __m128i         a, b;
-  __m128i         result;
-  __m128i         prim_poly;
-  __m128i         w;
-  gf_internal_t * h = gf->scratch;
-
-  a = _mm_insert_epi32 (_mm_setzero_si128(), a16, 0);
-  b = _mm_insert_epi32 (a, b16, 0);
-
-  prim_poly = _mm_set_epi32(0, 0, 0, (uint32_t)(h->prim_poly & 0x1ffffULL));
-
-  /* Do the initial multiply */
-  
-  result = _mm_clmulepi64_si128 (a, b, 0);
-
-  /* Ben: Do prim_poly reduction twice. We are guaranteed that we will only
-     have to do the reduction at most twice, because (w-2)/z == 2. Where
-     z is equal to the number of zeros after the leading 1
-
-     _mm_clmulepi64_si128 is the carryless multiply operation. Here
-     _mm_srli_si128 shifts the result to the right by 2 bytes. This allows
-     us to multiply the prim_poly by the leading bits of the result. We
-     then xor the result of that operation back with the result.*/
-
-  w = _mm_clmulepi64_si128 (prim_poly, _mm_srli_si128 (result, 2), 0);
-  result = _mm_xor_si128 (result, w);
-  w = _mm_clmulepi64_si128 (prim_poly, _mm_srli_si128 (result, 2), 0);
-  result = _mm_xor_si128 (result, w);
-
-  /* Extracts 32 bit value from result. */
-  
-  rv = ((gf_val_32_t)_mm_extract_epi32(result, 0));
-
-
-#endif
-  return rv;
-}
-
-static
-inline
-gf_val_32_t
-gf_w16_clm_multiply_3 (gf_t *gf, gf_val_32_t a16, gf_val_32_t b16)
-{
-  gf_val_32_t rv = 0;
-
-#if defined(INTEL_SSE4_PCLMUL)
-
-  __m128i         a, b;
-  __m128i         result;
-  __m128i         prim_poly;
-  __m128i         w;
-  gf_internal_t * h = gf->scratch;
-
-  a = _mm_insert_epi32 (_mm_setzero_si128(), a16, 0);
-  b = _mm_insert_epi32 (a, b16, 0);
-
-  prim_poly = _mm_set_epi32(0, 0, 0, (uint32_t)(h->prim_poly & 0x1ffffULL));
-
-  /* Do the initial multiply */
-  
-  result = _mm_clmulepi64_si128 (a, b, 0);
-
-  w = _mm_clmulepi64_si128 (prim_poly, _mm_srli_si128 (result, 2), 0);
-  result = _mm_xor_si128 (result, w);
-  w = _mm_clmulepi64_si128 (prim_poly, _mm_srli_si128 (result, 2), 0);
-  result = _mm_xor_si128 (result, w);
-  w = _mm_clmulepi64_si128 (prim_poly, _mm_srli_si128 (result, 2), 0);
-  result = _mm_xor_si128 (result, w);
-
-  /* Extracts 32 bit value from result. */
-  
-  rv = ((gf_val_32_t)_mm_extract_epi32(result, 0));
-
-
-#endif
-  return rv;
-}
-
-static
-inline
-gf_val_32_t
-gf_w16_clm_multiply_4 (gf_t *gf, gf_val_32_t a16, gf_val_32_t b16)
-{
-  gf_val_32_t rv = 0;
-
-#if defined(INTEL_SSE4_PCLMUL)
-
-  __m128i         a, b;
-  __m128i         result;
-  __m128i         prim_poly;
-  __m128i         w;
-  gf_internal_t * h = gf->scratch;
-
-  a = _mm_insert_epi32 (_mm_setzero_si128(), a16, 0);
-  b = _mm_insert_epi32 (a, b16, 0);
-
-  prim_poly = _mm_set_epi32(0, 0, 0, (uint32_t)(h->prim_poly & 0x1ffffULL));
-
-  /* Do the initial multiply */
-  
-  result = _mm_clmulepi64_si128 (a, b, 0);
-
-  w = _mm_clmulepi64_si128 (prim_poly, _mm_srli_si128 (result, 2), 0);
-  result = _mm_xor_si128 (result, w);
-  w = _mm_clmulepi64_si128 (prim_poly, _mm_srli_si128 (result, 2), 0);
-  result = _mm_xor_si128 (result, w);
-  w = _mm_clmulepi64_si128 (prim_poly, _mm_srli_si128 (result, 2), 0);
-  result = _mm_xor_si128 (result, w);
-  w = _mm_clmulepi64_si128 (prim_poly, _mm_srli_si128 (result, 2), 0);
-  result = _mm_xor_si128 (result, w);
-
-  /* Extracts 32 bit value from result. */
-  
-  rv = ((gf_val_32_t)_mm_extract_epi32(result, 0));
-
-
-#endif
-  return rv;
-}
-
-
-static
-inline
- gf_val_32_t
-gf_w16_shift_multiply (gf_t *gf, gf_val_32_t a16, gf_val_32_t b16)
-{
-  gf_val_32_t product, i, pp, a, b;
-  gf_internal_t *h;
-
-  a = a16;
-  b = b16;
-  h = (gf_internal_t *) gf->scratch;
-  pp = h->prim_poly;
-
-  product = 0;
-
-  for (i = 0; i < GF_FIELD_WIDTH; i++) { 
-    if (a & (1 << i)) product ^= (b << i);
-  }
-  for (i = (GF_FIELD_WIDTH*2-2); i >= GF_FIELD_WIDTH; i--) {
-    if (product & (1 << i)) product ^= (pp << (i-GF_FIELD_WIDTH)); 
-  }
-  return product;
-}
-
-static 
-int gf_w16_shift_init(gf_t *gf)
-{
-  gf->multiply.w32 = gf_w16_shift_multiply;
-  return 1;
-}
-
-static 
-int gf_w16_cfm_init(gf_t *gf)
-{
-#if defined(INTEL_SSE4_PCLMUL)
-  gf_internal_t *h;
-
-  h = (gf_internal_t *) gf->scratch;
-  
-  /*Ben: Determining how many reductions to do */
-  
-  if ((0xfe00 & h->prim_poly) == 0) {
-    gf->multiply.w32 = gf_w16_clm_multiply_2;
-    gf->multiply_region.w32 = gf_w16_clm_multiply_region_from_single_2;
-  } else if((0xf000 & h->prim_poly) == 0) {
-    gf->multiply.w32 = gf_w16_clm_multiply_3;
-    gf->multiply_region.w32 = gf_w16_clm_multiply_region_from_single_3;
-  } else if ((0xe000 & h->prim_poly) == 0) {
-    gf->multiply.w32 = gf_w16_clm_multiply_4;
-    gf->multiply_region.w32 = gf_w16_clm_multiply_region_from_single_4;
-  } else {
-    return 0;
-  } 
-  return 1;
-#endif
-
-  return 0;
-}
-
-/* KMG: GF_MULT_LOGTABLE: */
-
-static
-void
-gf_w16_log_multiply_region(gf_t *gf, void *src, void *dest, gf_val_32_t val, int bytes, int xor)
-{
-  uint16_t *s16, *d16;
-  int lv;
-  struct gf_w16_logtable_data *ltd;
-  gf_region_data rd;
-
-  if (val == 0) { gf_multby_zero(dest, bytes, xor); return; }
-  if (val == 1) { gf_multby_one(src, dest, bytes, xor); return; }
-
-  gf_set_region_data(&rd, gf, src, dest, bytes, val, xor, 2);
-  gf_do_initial_region_alignment(&rd);
-
-  ltd = (struct gf_w16_logtable_data *) ((gf_internal_t *) gf->scratch)->private;
-  s16 = (uint16_t *) rd.s_start;
-  d16 = (uint16_t *) rd.d_start;
-
-  lv = ltd->log_tbl[val];
-
-  if (xor) {
-    while (d16 < (uint16_t *) rd.d_top) {
-      *d16 ^= (*s16 == 0 ? 0 : ltd->antilog_tbl[lv + ltd->log_tbl[*s16]]);
-      d16++;
-      s16++;
-    }
-  } else {
-    while (d16 < (uint16_t *) rd.d_top) {
-      *d16 = (*s16 == 0 ? 0 : ltd->antilog_tbl[lv + ltd->log_tbl[*s16]]);
-      d16++;
-      s16++;
-    }
-  }
-  gf_do_final_region_alignment(&rd);
-}
-
-static
-inline
-gf_val_32_t
-gf_w16_log_multiply(gf_t *gf, gf_val_32_t a, gf_val_32_t b)
-{
-  struct gf_w16_logtable_data *ltd;
-
-  ltd = (struct gf_w16_logtable_data *) ((gf_internal_t *) gf->scratch)->private;
-  return (a == 0 || b == 0) ? 0 : ltd->antilog_tbl[(int) ltd->log_tbl[a] + (int) ltd->log_tbl[b]];
-}
-
-static
-inline
-gf_val_32_t
-gf_w16_log_divide(gf_t *gf, gf_val_32_t a, gf_val_32_t b)
-{
-  int log_sum = 0;
-  struct gf_w16_logtable_data *ltd;
-
-  if (a == 0 || b == 0) return 0;
-  ltd = (struct gf_w16_logtable_data *) ((gf_internal_t *) gf->scratch)->private;
-
-  log_sum = (int) ltd->log_tbl[a] - (int) ltd->log_tbl[b];
-  return (ltd->d_antilog[log_sum]);
-}
-
-static
-gf_val_32_t
-gf_w16_log_inverse(gf_t *gf, gf_val_32_t a)
-{
-  struct gf_w16_logtable_data *ltd;
-
-  ltd = (struct gf_w16_logtable_data *) ((gf_internal_t *) gf->scratch)->private;
-  return (ltd->inv_tbl[a]);
-}
-
-static
-int gf_w16_log_init(gf_t *gf)
-{
-  gf_internal_t *h;
-  struct gf_w16_logtable_data *ltd;
-  int i, b;
-  int check = 0;
-
-  h = (gf_internal_t *) gf->scratch;
-  ltd = h->private;
-  
-  for (i = 0; i < GF_MULT_GROUP_SIZE+1; i++)
-    ltd->log_tbl[i] = 0;
-  ltd->d_antilog = ltd->antilog_tbl + GF_MULT_GROUP_SIZE;
-
-  b = 1;
-  for (i = 0; i < GF_MULT_GROUP_SIZE; i++) {
-      if (ltd->log_tbl[b] != 0) check = 1;
-      ltd->log_tbl[b] = i;
-      ltd->antilog_tbl[i] = b;
-      ltd->antilog_tbl[i+GF_MULT_GROUP_SIZE] = b;
-      b <<= 1;
-      if (b & GF_FIELD_SIZE) {
-          b = b ^ h->prim_poly;
-      }
-  }
-
-  /* If you can't construct the log table, there's a problem.  This code is used for
-     some other implementations (e.g. in SPLIT), so if the log table doesn't work in 
-     that instance, use CARRY_FREE / SHIFT instead. */
-
-  if (check) {
-    if (h->mult_type != GF_MULT_LOG_TABLE) {
-
-#if defined(INTEL_SSE4_PCLMUL)
-      return gf_w16_cfm_init(gf);
-#endif
-      return gf_w16_shift_init(gf);
-    } else {
-      _gf_errno = GF_E_LOGPOLY;
-      return 0;
-    }
-  }
-
-  ltd->inv_tbl[0] = 0;  /* Not really, but we need to fill it with something  */
-  ltd->inv_tbl[1] = 1;
-  for (i = 2; i < GF_FIELD_SIZE; i++) {
-    ltd->inv_tbl[i] = ltd->antilog_tbl[GF_MULT_GROUP_SIZE-ltd->log_tbl[i]];
-  }
-
-  gf->inverse.w32 = gf_w16_log_inverse;
-  gf->divide.w32 = gf_w16_log_divide;
-  gf->multiply.w32 = gf_w16_log_multiply;
-  gf->multiply_region.w32 = gf_w16_log_multiply_region;
-
-  return 1;
-}
-
-/* JSP: GF_MULT_SPLIT_TABLE: Using 8 multiplication tables to leverage SSE instructions.
-*/
-
-
-/* Ben: Does alternate mapping multiplication using a split table in the
- lazy method without sse instructions*/
-
-static 
-void
-gf_w16_split_4_16_lazy_nosse_altmap_multiply_region(gf_t *gf, void *src, void *dest, gf_val_32_t val, int bytes, int xor)
-{
-  uint64_t i, j, c, prod;
-  uint8_t *s8, *d8, *top;
-  uint16_t table[4][16];
-  gf_region_data rd;
-
-  if (val == 0) { gf_multby_zero(dest, bytes, xor); return; }
-  if (val == 1) { gf_multby_one(src, dest, bytes, xor); return; }
-
-  gf_set_region_data(&rd, gf, src, dest, bytes, val, xor, 32);
-  gf_do_initial_region_alignment(&rd);    
-
-  /*Ben: Constructs lazy multiplication table*/
-
-  for (j = 0; j < 16; j++) {
-    for (i = 0; i < 4; i++) {
-      c = (j << (i*4));
-      table[i][j] = gf->multiply.w32(gf, c, val);
-    }
-  }
-
-  /*Ben: s8 is the start of source, d8 is the start of dest, top is end of dest region. */
-  
-  s8 = (uint8_t *) rd.s_start;
-  d8 = (uint8_t *) rd.d_start;
-  top = (uint8_t *) rd.d_top;
-
-
-  while (d8 < top) {
-    
-    /*Ben: Multiplies across 16 two byte quantities using alternate mapping 
-       high bits are on the left, low bits are on the right. */
-  
-    for (j=0;j<16;j++) {
-    
-      /*Ben: If the xor flag is set, the product should include what is in dest */
-      prod = (xor) ? ((uint16_t)(*d8)<<8) ^ *(d8+16) : 0;
-
-      /*Ben: xors all 4 table lookups into the product variable*/
-      
-      prod ^= ((table[0][*(s8+16)&0xf]) ^
-          (table[1][(*(s8+16)&0xf0)>>4]) ^
-          (table[2][*(s8)&0xf]) ^
-          (table[3][(*(s8)&0xf0)>>4]));
-
-      /*Ben: Stores product in the destination and moves on*/
-      
-      *d8 = (uint8_t)(prod >> 8);
-      *(d8+16) = (uint8_t)(prod & 0x00ff);
-      s8++;
-      d8++;
-    }
-    s8+=16;
-    d8+=16;
-  }
-  gf_do_final_region_alignment(&rd);
-}
-
-static
-  void
-gf_w16_split_4_16_lazy_multiply_region(gf_t *gf, void *src, void *dest, gf_val_32_t val, int bytes, int xor)
-{
-  uint64_t i, j, a, c, prod;
-  uint16_t *s16, *d16, *top;
-  uint16_t table[4][16];
-  gf_region_data rd;
-
-  if (val == 0) { gf_multby_zero(dest, bytes, xor); return; }
-  if (val == 1) { gf_multby_one(src, dest, bytes, xor); return; }
-
-  gf_set_region_data(&rd, gf, src, dest, bytes, val, xor, 2);
-  gf_do_initial_region_alignment(&rd);    
-
-  for (j = 0; j < 16; j++) {
-    for (i = 0; i < 4; i++) {
-      c = (j << (i*4));
-      table[i][j] = gf->multiply.w32(gf, c, val);
-    }
-  }
-
-  s16 = (uint16_t *) rd.s_start;
-  d16 = (uint16_t *) rd.d_start;
-  top = (uint16_t *) rd.d_top;
-
-  while (d16 < top) {
-    a = *s16;
-    prod = (xor) ? *d16 : 0;
-    for (i = 0; i < 4; i++) {
-      prod ^= table[i][a&0xf];
-      a >>= 4;
-    }
-    *d16 = prod;
-    s16++;
-    d16++;
-  }
-}
-
-static
-void
-gf_w16_split_8_16_lazy_multiply_region(gf_t *gf, void *src, void *dest, gf_val_32_t val, int bytes, int xor)
-{
-  uint64_t j, k, v, a, prod, *s64, *d64, *top64;
-  gf_internal_t *h;
-  uint64_t htable[256], ltable[256];
-  gf_region_data rd;
-
-  if (val == 0) { gf_multby_zero(dest, bytes, xor); return; }
-  if (val == 1) { gf_multby_one(src, dest, bytes, xor); return; }
-
-  gf_set_region_data(&rd, gf, src, dest, bytes, val, xor, 8);
-  gf_do_initial_region_alignment(&rd);
-  
-  h = (gf_internal_t *) gf->scratch;
-
-  v = val;
-  ltable[0] = 0;
-  for (j = 1; j < 256; j <<= 1) {
-    for (k = 0; k < j; k++) ltable[k^j] = (v ^ ltable[k]);
-    v = GF_MULTBY_TWO(v);
-  }
-  htable[0] = 0;
-  for (j = 1; j < 256; j <<= 1) {
-    for (k = 0; k < j; k++) htable[k^j] = (v ^ htable[k]);
-    v = GF_MULTBY_TWO(v);
-  }
-
-  s64 = (uint64_t *) rd.s_start;
-  d64 = (uint64_t *) rd.d_start;
-  top64 = (uint64_t *) rd.d_top;
-  
-/* Does Unrolling Matter?  -- Doesn't seem to.
-  while (d64 != top64) {
-    a = *s64;
-
-    prod = htable[a >> 56];
-    a <<= 8;
-    prod ^= ltable[a >> 56];
-    a <<= 8;
-    prod <<= 16;
-
-    prod ^= htable[a >> 56];
-    a <<= 8;
-    prod ^= ltable[a >> 56];
-    a <<= 8;
-    prod <<= 16;
-
-    prod ^= htable[a >> 56];
-    a <<= 8;
-    prod ^= ltable[a >> 56];
-    a <<= 8;
-    prod <<= 16;
-
-    prod ^= htable[a >> 56];
-    a <<= 8;
-    prod ^= ltable[a >> 56];
-    prod ^= ((xor) ? *d64 : 0); 
-    *d64 = prod;
-    s64++;
-    d64++;
-  }
-*/
-  
-  while (d64 != top64) {
-    a = *s64;
-
-    prod = 0;
-    for (j = 0; j < 4; j++) {
-      prod <<= 16;
-      prod ^= htable[a >> 56];
-      a <<= 8;
-      prod ^= ltable[a >> 56];
-      a <<= 8;
-    }
-
-    //JSP: We can move the conditional outside the while loop, but we need to fully test it to understand which is better.
-   
-    prod ^= ((xor) ? *d64 : 0); 
-    *d64 = prod;
-    s64++;
-    d64++;
-  }
-  gf_do_final_region_alignment(&rd);
-}
-
-static void
-gf_w16_table_lazy_multiply_region(gf_t *gf, void *src, void *dest, gf_val_32_t val, int bytes, int xor)
-{
-  uint64_t c;
-  gf_internal_t *h;
-  struct gf_w16_lazytable_data *ltd;
-  gf_region_data rd;
-
-  if (val == 0) { gf_multby_zero(dest, bytes, xor); return; }
-  if (val == 1) { gf_multby_one(src, dest, bytes, xor); return; }
-
-  gf_set_region_data(&rd, gf, src, dest, bytes, val, xor, 8);
-  gf_do_initial_region_alignment(&rd);
-
-  h = (gf_internal_t *) gf->scratch;
-  ltd = (struct gf_w16_lazytable_data *) h->private;
-
-  ltd->lazytable[0] = 0;
-
-  /*
-  a = val;
-  c = 1;
-  pp = h->prim_poly;
-
-  do {
-    ltd->lazytable[c] = a;
-    c <<= 1;
-    if (c & (1 << GF_FIELD_WIDTH)) c ^= pp;
-    a <<= 1;
-    if (a & (1 << GF_FIELD_WIDTH)) a ^= pp;
-  } while (c != 1);
-  */
-
-  for (c = 1; c < GF_FIELD_SIZE; c++) {
-    ltd->lazytable[c] = gf_w16_shift_multiply(gf, c, val);
-  }
-   
-  gf_two_byte_region_table_multiply(&rd, ltd->lazytable);
-  gf_do_final_region_alignment(&rd);
-}
-
-static
-void
-gf_w16_split_4_16_lazy_sse_multiply_region(gf_t *gf, void *src, void *dest, gf_val_32_t val, int bytes, int xor)
-{
-#ifdef INTEL_SSSE3
-  uint64_t i, j, *s64, *d64, *top64;;
-  uint64_t c, prod;
-  uint8_t low[4][16];
-  uint8_t high[4][16];
-  gf_region_data rd;
-
-  __m128i  mask, ta, tb, ti, tpl, tph, tlow[4], thigh[4], tta, ttb, lmask;
-
-  if (val == 0) { gf_multby_zero(dest, bytes, xor); return; }
-  if (val == 1) { gf_multby_one(src, dest, bytes, xor); return; }
-
-  gf_set_region_data(&rd, gf, src, dest, bytes, val, xor, 32);
-  gf_do_initial_region_alignment(&rd);
-
-  for (j = 0; j < 16; j++) {
-    for (i = 0; i < 4; i++) {
-      c = (j << (i*4));
-      prod = gf->multiply.w32(gf, c, val);
-      low[i][j] = (prod & 0xff);
-      high[i][j] = (prod >> 8);
-    }
-  }
-
-  for (i = 0; i < 4; i++) {
-    tlow[i] = _mm_loadu_si128((__m128i *)low[i]);
-    thigh[i] = _mm_loadu_si128((__m128i *)high[i]);
-  }
-
-  s64 = (uint64_t *) rd.s_start;
-  d64 = (uint64_t *) rd.d_start;
-  top64 = (uint64_t *) rd.d_top;
-
-  mask = _mm_set1_epi8 (0x0f);
-  lmask = _mm_set1_epi16 (0xff);
-
-  if (xor) {
-    while (d64 != top64) {
-      
-      ta = _mm_load_si128((__m128i *) s64);
-      tb = _mm_load_si128((__m128i *) (s64+2));
-
-      tta = _mm_srli_epi16(ta, 8);
-      ttb = _mm_srli_epi16(tb, 8);
-      tpl = _mm_and_si128(tb, lmask);
-      tph = _mm_and_si128(ta, lmask);
-
-      tb = _mm_packus_epi16(tpl, tph);
-      ta = _mm_packus_epi16(ttb, tta);
-
-      ti = _mm_and_si128 (mask, tb);
-      tph = _mm_shuffle_epi8 (thigh[0], ti);
-      tpl = _mm_shuffle_epi8 (tlow[0], ti);
-  
-      tb = _mm_srli_epi16(tb, 4);
-      ti = _mm_and_si128 (mask, tb);
-      tpl = _mm_xor_si128(_mm_shuffle_epi8 (tlow[1], ti), tpl);
-      tph = _mm_xor_si128(_mm_shuffle_epi8 (thigh[1], ti), tph);
-
-      ti = _mm_and_si128 (mask, ta);
-      tpl = _mm_xor_si128(_mm_shuffle_epi8 (tlow[2], ti), tpl);
-      tph = _mm_xor_si128(_mm_shuffle_epi8 (thigh[2], ti), tph);
-  
-      ta = _mm_srli_epi16(ta, 4);
-      ti = _mm_and_si128 (mask, ta);
-      tpl = _mm_xor_si128(_mm_shuffle_epi8 (tlow[3], ti), tpl);
-      tph = _mm_xor_si128(_mm_shuffle_epi8 (thigh[3], ti), tph);
-
-      ta = _mm_unpackhi_epi8(tpl, tph);
-      tb = _mm_unpacklo_epi8(tpl, tph);
-
-      tta = _mm_load_si128((__m128i *) d64);
-      ta = _mm_xor_si128(ta, tta);
-      ttb = _mm_load_si128((__m128i *) (d64+2));
-      tb = _mm_xor_si128(tb, ttb); 
-      _mm_store_si128 ((__m128i *)d64, ta);
-      _mm_store_si128 ((__m128i *)(d64+2), tb);
-
-      d64 += 4;
-      s64 += 4;
-      
-    }
-  } else {
-    while (d64 != top64) {
-      
-      ta = _mm_load_si128((__m128i *) s64);
-      tb = _mm_load_si128((__m128i *) (s64+2));
-
-      tta = _mm_srli_epi16(ta, 8);
-      ttb = _mm_srli_epi16(tb, 8);
-      tpl = _mm_and_si128(tb, lmask);
-      tph = _mm_and_si128(ta, lmask);
-
-      tb = _mm_packus_epi16(tpl, tph);
-      ta = _mm_packus_epi16(ttb, tta);
-
-      ti = _mm_and_si128 (mask, tb);
-      tph = _mm_shuffle_epi8 (thigh[0], ti);
-      tpl = _mm_shuffle_epi8 (tlow[0], ti);
-  
-      tb = _mm_srli_epi16(tb, 4);
-      ti = _mm_and_si128 (mask, tb);
-      tpl = _mm_xor_si128(_mm_shuffle_epi8 (tlow[1], ti), tpl);
-      tph = _mm_xor_si128(_mm_shuffle_epi8 (thigh[1], ti), tph);
-
-      ti = _mm_and_si128 (mask, ta);
-      tpl = _mm_xor_si128(_mm_shuffle_epi8 (tlow[2], ti), tpl);
-      tph = _mm_xor_si128(_mm_shuffle_epi8 (thigh[2], ti), tph);
-  
-      ta = _mm_srli_epi16(ta, 4);
-      ti = _mm_and_si128 (mask, ta);
-      tpl = _mm_xor_si128(_mm_shuffle_epi8 (tlow[3], ti), tpl);
-      tph = _mm_xor_si128(_mm_shuffle_epi8 (thigh[3], ti), tph);
-
-      ta = _mm_unpackhi_epi8(tpl, tph);
-      tb = _mm_unpacklo_epi8(tpl, tph);
-
-      _mm_store_si128 ((__m128i *)d64, ta);
-      _mm_store_si128 ((__m128i *)(d64+2), tb);
-
-      d64 += 4;
-      s64 += 4;
-    }
-  }
-
-  gf_do_final_region_alignment(&rd);
-#endif
-}
-
-static
-void
-gf_w16_split_4_16_lazy_sse_altmap_multiply_region(gf_t *gf, void *src, void *dest, gf_val_32_t val, int bytes, int xor)
-{
-#ifdef INTEL_SSSE3
-  uint64_t i, j, *s64, *d64, *top64;;
-  uint64_t c, prod;
-  uint8_t low[4][16];
-  uint8_t high[4][16];
-  gf_region_data rd;
-  __m128i  mask, ta, tb, ti, tpl, tph, tlow[4], thigh[4];
-
-  if (val == 0) { gf_multby_zero(dest, bytes, xor); return; }
-  if (val == 1) { gf_multby_one(src, dest, bytes, xor); return; }
-
-  gf_set_region_data(&rd, gf, src, dest, bytes, val, xor, 32);
-  gf_do_initial_region_alignment(&rd);
-
-  for (j = 0; j < 16; j++) {
-    for (i = 0; i < 4; i++) {
-      c = (j << (i*4));
-      prod = gf->multiply.w32(gf, c, val);
-      low[i][j] = (prod & 0xff);
-      high[i][j] = (prod >> 8);
-    }
-  }
-
-  for (i = 0; i < 4; i++) {
-    tlow[i] = _mm_loadu_si128((__m128i *)low[i]);
-    thigh[i] = _mm_loadu_si128((__m128i *)high[i]);
-  }
-
-  s64 = (uint64_t *) rd.s_start;
-  d64 = (uint64_t *) rd.d_start;
-  top64 = (uint64_t *) rd.d_top;
-
-  mask = _mm_set1_epi8 (0x0f);
-
-  if (xor) {
-    while (d64 != top64) {
-
-      ta = _mm_load_si128((__m128i *) s64);
-      tb = _mm_load_si128((__m128i *) (s64+2));
-
-      ti = _mm_and_si128 (mask, tb);
-      tph = _mm_shuffle_epi8 (thigh[0], ti);
-      tpl = _mm_shuffle_epi8 (tlow[0], ti);
-  
-      tb = _mm_srli_epi16(tb, 4);
-      ti = _mm_and_si128 (mask, tb);
-      tpl = _mm_xor_si128(_mm_shuffle_epi8 (tlow[1], ti), tpl);
-      tph = _mm_xor_si128(_mm_shuffle_epi8 (thigh[1], ti), tph);
-
-      ti = _mm_and_si128 (mask, ta);
-      tpl = _mm_xor_si128(_mm_shuffle_epi8 (tlow[2], ti), tpl);
-      tph = _mm_xor_si128(_mm_shuffle_epi8 (thigh[2], ti), tph);
-  
-      ta = _mm_srli_epi16(ta, 4);
-      ti = _mm_and_si128 (mask, ta);
-      tpl = _mm_xor_si128(_mm_shuffle_epi8 (tlow[3], ti), tpl);
-      tph = _mm_xor_si128(_mm_shuffle_epi8 (thigh[3], ti), tph);
-
-      ta = _mm_load_si128((__m128i *) d64);
-      tph = _mm_xor_si128(tph, ta);
-      _mm_store_si128 ((__m128i *)d64, tph);
-      tb = _mm_load_si128((__m128i *) (d64+2));
-      tpl = _mm_xor_si128(tpl, tb);
-      _mm_store_si128 ((__m128i *)(d64+2), tpl);
-
-      d64 += 4;
-      s64 += 4;
-    }
-  } else {
-    while (d64 != top64) {
-
-      ta = _mm_load_si128((__m128i *) s64);
-      tb = _mm_load_si128((__m128i *) (s64+2));
-
-      ti = _mm_and_si128 (mask, tb);
-      tph = _mm_shuffle_epi8 (thigh[0], ti);
-      tpl = _mm_shuffle_epi8 (tlow[0], ti);
-  
-      tb = _mm_srli_epi16(tb, 4);
-      ti = _mm_and_si128 (mask, tb);
-      tpl = _mm_xor_si128(_mm_shuffle_epi8 (tlow[1], ti), tpl);
-      tph = _mm_xor_si128(_mm_shuffle_epi8 (thigh[1], ti), tph);
-
-      ti = _mm_and_si128 (mask, ta);
-      tpl = _mm_xor_si128(_mm_shuffle_epi8 (tlow[2], ti), tpl);
-      tph = _mm_xor_si128(_mm_shuffle_epi8 (thigh[2], ti), tph);
-  
-      ta = _mm_srli_epi16(ta, 4);
-      ti = _mm_and_si128 (mask, ta);
-      tpl = _mm_xor_si128(_mm_shuffle_epi8 (tlow[3], ti), tpl);
-      tph = _mm_xor_si128(_mm_shuffle_epi8 (thigh[3], ti), tph);
-
-      _mm_store_si128 ((__m128i *)d64, tph);
-      _mm_store_si128 ((__m128i *)(d64+2), tpl);
-
-      d64 += 4;
-      s64 += 4;
-      
-    }
-  }
-  gf_do_final_region_alignment(&rd);
-
-#endif
-}
-
-uint32_t 
-gf_w16_split_8_8_multiply(gf_t *gf, gf_val_32_t a, gf_val_32_t b)
-{
-  uint32_t alow, blow;
-  struct gf_w16_split_8_8_data *d8;
-  gf_internal_t *h;
-
-  h = (gf_internal_t *) gf->scratch;
-  d8 = (struct gf_w16_split_8_8_data *) h->private;
-
-  alow = a & 0xff;
-  blow = b & 0xff;
-  a >>= 8;
-  b >>= 8;
-
-  return d8->tables[0][alow][blow] ^
-         d8->tables[1][alow][b] ^
-         d8->tables[1][a][blow] ^
-         d8->tables[2][a][b];
-}
-
-static 
-int gf_w16_split_init(gf_t *gf)
-{
-  gf_internal_t *h;
-  struct gf_w16_split_8_8_data *d8;
-  int i, j, exp, issse3;
-  int isneon = 0;
-  uint32_t p, basep, tmp;
-
-  h = (gf_internal_t *) gf->scratch;
-
-#ifdef INTEL_SSSE3
-  issse3 = 1;
-#else
-  issse3 = 0;
-#endif
-#ifdef ARM_NEON
-  isneon = 1;
-#endif
-
-  if (h->arg1 == 8 && h->arg2 == 8) {
-    d8 = (struct gf_w16_split_8_8_data *) h->private;
-    basep = 1;
-    for (exp = 0; exp < 3; exp++) {
-      for (j = 0; j < 256; j++) d8->tables[exp][0][j] = 0;
-      for (i = 0; i < 256; i++) d8->tables[exp][i][0] = 0;
-      d8->tables[exp][1][1] = basep;
-      for (i = 2; i < 256; i++) {
-        if (i&1) {
-          p = d8->tables[exp][i^1][1];
-          d8->tables[exp][i][1] = p ^ basep;
-        } else {
-          p = d8->tables[exp][i>>1][1];
-          d8->tables[exp][i][1] = GF_MULTBY_TWO(p);
-        }
-      }
-      for (i = 1; i < 256; i++) {
-        p = d8->tables[exp][i][1];
-        for (j = 1; j < 256; j++) {
-          if (j&1) {
-            d8->tables[exp][i][j] = d8->tables[exp][i][j^1] ^ p;
-          } else {
-            tmp = d8->tables[exp][i][j>>1];
-            d8->tables[exp][i][j] = GF_MULTBY_TWO(tmp);
-          }
-        }
-      }
-      for (i = 0; i < 8; i++) basep = GF_MULTBY_TWO(basep);
-    }
-    gf->multiply.w32 = gf_w16_split_8_8_multiply;
-    gf->multiply_region.w32 = gf_w16_split_8_16_lazy_multiply_region;
-    return 1;
-
-  }
-
-  /* We'll be using LOG for multiplication, unless the pp isn't primitive.
-     In that case, we'll be using SHIFT. */
-
-  gf_w16_log_init(gf);
-
-  /* Defaults */
-
-  if (issse3) {
-    gf->multiply_region.w32 = gf_w16_split_4_16_lazy_sse_multiply_region;
-  } else if (isneon) {
-#ifdef ARM_NEON
-    gf_w16_neon_split_init(gf);
-#endif
-  } else {
-    gf->multiply_region.w32 = gf_w16_split_8_16_lazy_multiply_region;
-  }
-
-
-  if ((h->arg1 == 8 && h->arg2 == 16) || (h->arg2 == 8 && h->arg1 == 16)) {
-    gf->multiply_region.w32 = gf_w16_split_8_16_lazy_multiply_region;
-
-  } else if ((h->arg1 == 4 && h->arg2 == 16) || (h->arg2 == 4 && h->arg1 == 16)) {
-    if (issse3 || isneon) {
-      if(h->region_type & GF_REGION_ALTMAP && h->region_type & GF_REGION_NOSIMD)
-        gf->multiply_region.w32 = gf_w16_split_4_16_lazy_nosse_altmap_multiply_region;
-      else if(h->region_type & GF_REGION_NOSIMD)
-        gf->multiply_region.w32 = gf_w16_split_4_16_lazy_multiply_region;
-      else if(h->region_type & GF_REGION_ALTMAP && issse3)
-        gf->multiply_region.w32 = gf_w16_split_4_16_lazy_sse_altmap_multiply_region;
-    } else {
-      if(h->region_type & GF_REGION_SIMD)
-        return 0;
-      else if(h->region_type & GF_REGION_ALTMAP)
-        gf->multiply_region.w32 = gf_w16_split_4_16_lazy_nosse_altmap_multiply_region;
-      else
-        gf->multiply_region.w32 = gf_w16_split_4_16_lazy_multiply_region;
-    }
-  }
-
-  return 1;
-}
-
-static 
-int gf_w16_table_init(gf_t *gf)
-{
-  gf_w16_log_init(gf);
-
-  gf->multiply_region.w32 = gf_w16_table_lazy_multiply_region; 
-  return 1;
-}
-
-static
-void
-gf_w16_log_zero_multiply_region(gf_t *gf, void *src, void *dest, gf_val_32_t val, int bytes, int xor)
-{
-  uint16_t lv;
-  int i;
-  uint16_t *s16, *d16, *top16;
-  struct gf_w16_zero_logtable_data *ltd;
-  gf_region_data rd;
-
-  if (val == 0) { gf_multby_zero(dest, bytes, xor); return; }
-  if (val == 1) { gf_multby_one(src, dest, bytes, xor); return; }
-
-  gf_set_region_data(&rd, gf, src, dest, bytes, val, xor, 2);
-  gf_do_initial_region_alignment(&rd);
-
-  ltd = (struct gf_w16_zero_logtable_data*) ((gf_internal_t *) gf->scratch)->private;
-  s16 = (uint16_t *) rd.s_start;
-  d16 = (uint16_t *) rd.d_start;
-  top16 = (uint16_t *) rd.d_top;
-  bytes = top16 - d16;
-
-  lv = ltd->log_tbl[val];
-
-  if (xor) {
-    for (i = 0; i < bytes; i++) {
-      d16[i] ^= (ltd->antilog_tbl[lv + ltd->log_tbl[s16[i]]]);
-    }
-  } else {
-    for (i = 0; i < bytes; i++) {
-      d16[i] = (ltd->antilog_tbl[lv + ltd->log_tbl[s16[i]]]);
-    }
-  }
-
-  /* This isn't necessary. */
-  
-  gf_do_final_region_alignment(&rd);
-}
-
-/* Here -- double-check Kevin */
-
-static
-inline
-gf_val_32_t
-gf_w16_log_zero_multiply (gf_t *gf, gf_val_32_t a, gf_val_32_t b)
-{
-  struct gf_w16_zero_logtable_data *ltd;
-
-  ltd = (struct gf_w16_zero_logtable_data *) ((gf_internal_t *) gf->scratch)->private;
-  return ltd->antilog_tbl[ltd->log_tbl[a] + ltd->log_tbl[b]];
-}
-
-static
-inline
-gf_val_32_t
-gf_w16_log_zero_divide (gf_t *gf, gf_val_32_t a, gf_val_32_t b)
-{
-  int log_sum = 0;
-  struct gf_w16_zero_logtable_data *ltd;
-
-  if (a == 0 || b == 0) return 0;
-  ltd = (struct gf_w16_zero_logtable_data *) ((gf_internal_t *) gf->scratch)->private;
-
-  log_sum = ltd->log_tbl[a] - ltd->log_tbl[b] + (GF_MULT_GROUP_SIZE);
-  return (ltd->antilog_tbl[log_sum]);
-}
-
-static
-gf_val_32_t
-gf_w16_log_zero_inverse (gf_t *gf, gf_val_32_t a)
-{
-  struct gf_w16_zero_logtable_data *ltd;
-
-  ltd = (struct gf_w16_zero_logtable_data *) ((gf_internal_t *) gf->scratch)->private;
-  return (ltd->inv_tbl[a]);
-}
-
-static
-inline
-gf_val_32_t
-gf_w16_bytwo_p_multiply (gf_t *gf, gf_val_32_t a, gf_val_32_t b)
-{
-  uint32_t prod, pp, pmask, amask;
-  gf_internal_t *h;
-  
-  h = (gf_internal_t *) gf->scratch;
-  pp = h->prim_poly;
-
-  
-  prod = 0;
-  pmask = 0x8000;
-  amask = 0x8000;
-
-  while (amask != 0) {
-    if (prod & pmask) {
-      prod = ((prod << 1) ^ pp);
-    } else {
-      prod <<= 1;
-    }
-    if (a & amask) prod ^= b;
-    amask >>= 1;
-  }
-  return prod;
-}
-
-static
-inline
-gf_val_32_t
-gf_w16_bytwo_b_multiply (gf_t *gf, gf_val_32_t a, gf_val_32_t b)
-{
-  uint32_t prod, pp, bmask;
-  gf_internal_t *h;
-  
-  h = (gf_internal_t *) gf->scratch;
-  pp = h->prim_poly;
-
-  prod = 0;
-  bmask = 0x8000;
-
-  while (1) {
-    if (a & 1) prod ^= b;
-    a >>= 1;
-    if (a == 0) return prod;
-    if (b & bmask) {
-      b = ((b << 1) ^ pp);
-    } else {
-      b <<= 1;
-    }
-  }
-}
-
-static
-void 
-gf_w16_bytwo_p_nosse_multiply_region(gf_t *gf, void *src, void *dest, gf_val_32_t val, int bytes, int xor)
-{
-  uint64_t *s64, *d64, t1, t2, ta, prod, amask;
-  gf_region_data rd;
-  struct gf_w16_bytwo_data *btd;
-    
-  if (val == 0) { gf_multby_zero(dest, bytes, xor); return; }
-  if (val == 1) { gf_multby_one(src, dest, bytes, xor); return; }
-
-  btd = (struct gf_w16_bytwo_data *) ((gf_internal_t *) (gf->scratch))->private;
-
-  gf_set_region_data(&rd, gf, src, dest, bytes, val, xor, 8);
-  gf_do_initial_region_alignment(&rd);
-
-  s64 = (uint64_t *) rd.s_start;
-  d64 = (uint64_t *) rd.d_start;
-
-  if (xor) {
-    while (s64 < (uint64_t *) rd.s_top) {
-      prod = 0;
-      amask = 0x8000;
-      ta = *s64;
-      while (amask != 0) {
-        AB2(btd->prim_poly, btd->mask1, btd->mask2, prod, t1, t2);
-        if (val & amask) prod ^= ta;
-        amask >>= 1;
-      }
-      *d64 ^= prod;
-      d64++;
-      s64++;
-    }
-  } else { 
-    while (s64 < (uint64_t *) rd.s_top) {
-      prod = 0;
-      amask = 0x8000;
-      ta = *s64;
-      while (amask != 0) {
-        AB2(btd->prim_poly, btd->mask1, btd->mask2, prod, t1, t2);
-        if (val & amask) prod ^= ta;
-        amask >>= 1;
-      }
-      *d64 = prod;
-      d64++;
-      s64++;
-    }
-  }
-  gf_do_final_region_alignment(&rd);
-}
-
-#define BYTWO_P_ONESTEP {\
-      SSE_AB2(pp, m1 ,m2, prod, t1, t2); \
-      t1 = _mm_and_si128(v, one); \
-      t1 = _mm_sub_epi16(t1, one); \
-      t1 = _mm_and_si128(t1, ta); \
-      prod = _mm_xor_si128(prod, t1); \
-      v = _mm_srli_epi64(v, 1); }
-
-#ifdef INTEL_SSE2
-static
-void 
-gf_w16_bytwo_p_sse_multiply_region(gf_t *gf, void *src, void *dest, gf_val_32_t val, int bytes, int xor)
-{
-  int i;
-  uint8_t *s8, *d8;
-  uint32_t vrev;
-  __m128i pp, m1, m2, ta, prod, t1, t2, tp, one, v;
-  struct gf_w16_bytwo_data *btd;
-  gf_region_data rd;
-    
-  if (val == 0) { gf_multby_zero(dest, bytes, xor); return; }
-  if (val == 1) { gf_multby_one(src, dest, bytes, xor); return; }
-
-  btd = (struct gf_w16_bytwo_data *) ((gf_internal_t *) (gf->scratch))->private;
-
-  gf_set_region_data(&rd, gf, src, dest, bytes, val, xor, 16);
-  gf_do_initial_region_alignment(&rd);
-
-  vrev = 0;
-  for (i = 0; i < 16; i++) {
-    vrev <<= 1;
-    if (!(val & (1 << i))) vrev |= 1;
-  }
-
-  s8 = (uint8_t *) rd.s_start;
-  d8 = (uint8_t *) rd.d_start;
-
-  pp = _mm_set1_epi16(btd->prim_poly&0xffff);
-  m1 = _mm_set1_epi16((btd->mask1)&0xffff);
-  m2 = _mm_set1_epi16((btd->mask2)&0xffff);
-  one = _mm_set1_epi16(1);
-
-  while (d8 < (uint8_t *) rd.d_top) {
-    prod = _mm_setzero_si128();
-    v = _mm_set1_epi16(vrev);
-    ta = _mm_load_si128((__m128i *) s8);
-    tp = (!xor) ? _mm_setzero_si128() : _mm_load_si128((__m128i *) d8);
-    BYTWO_P_ONESTEP;
-    BYTWO_P_ONESTEP;
-    BYTWO_P_ONESTEP;
-    BYTWO_P_ONESTEP;
-    BYTWO_P_ONESTEP;
-    BYTWO_P_ONESTEP;
-    BYTWO_P_ONESTEP;
-    BYTWO_P_ONESTEP;
-    BYTWO_P_ONESTEP;
-    BYTWO_P_ONESTEP;
-    BYTWO_P_ONESTEP;
-    BYTWO_P_ONESTEP;
-    BYTWO_P_ONESTEP;
-    BYTWO_P_ONESTEP;
-    BYTWO_P_ONESTEP;
-    BYTWO_P_ONESTEP;
-    _mm_store_si128((__m128i *) d8, _mm_xor_si128(prod, tp));
-    d8 += 16;
-    s8 += 16;
-  }
-  gf_do_final_region_alignment(&rd);
-}
-#endif
-
-#ifdef INTEL_SSE2
-static
-void
-gf_w16_bytwo_b_sse_region_2_noxor(gf_region_data *rd, struct gf_w16_bytwo_data *btd)
-{
-  uint8_t *d8, *s8;
-  __m128i pp, m1, m2, t1, t2, va;
-
-  s8 = (uint8_t *) rd->s_start;
-  d8 = (uint8_t *) rd->d_start;
-
-  pp = _mm_set1_epi16(btd->prim_poly&0xffff);
-  m1 = _mm_set1_epi16((btd->mask1)&0xffff);
-  m2 = _mm_set1_epi16((btd->mask2)&0xffff);
-
-  while (d8 < (uint8_t *) rd->d_top) {
-    va = _mm_load_si128 ((__m128i *)(s8));
-    SSE_AB2(pp, m1, m2, va, t1, t2);
-    _mm_store_si128((__m128i *)d8, va);
-    d8 += 16;
-    s8 += 16;
-  }
-}
-#endif
-
-#ifdef INTEL_SSE2
-static
-void
-gf_w16_bytwo_b_sse_region_2_xor(gf_region_data *rd, struct gf_w16_bytwo_data *btd)
-{
-  uint8_t *d8, *s8;
-  __m128i pp, m1, m2, t1, t2, va, vb;
-
-  s8 = (uint8_t *) rd->s_start;
-  d8 = (uint8_t *) rd->d_start;
-
-  pp = _mm_set1_epi16(btd->prim_poly&0xffff);
-  m1 = _mm_set1_epi16((btd->mask1)&0xffff);
-  m2 = _mm_set1_epi16((btd->mask2)&0xffff);
-
-  while (d8 < (uint8_t *) rd->d_top) {
-    va = _mm_load_si128 ((__m128i *)(s8));
-    SSE_AB2(pp, m1, m2, va, t1, t2);
-    vb = _mm_load_si128 ((__m128i *)(d8));
-    vb = _mm_xor_si128(vb, va);
-    _mm_store_si128((__m128i *)d8, vb);
-    d8 += 16;
-    s8 += 16;
-  }
-}
-#endif
-
-
-#ifdef INTEL_SSE2
-static
-void 
-gf_w16_bytwo_b_sse_multiply_region(gf_t *gf, void *src, void *dest, gf_val_32_t val, int bytes, int xor)
-{
-  int itb;
-  uint8_t *d8, *s8;
-  __m128i pp, m1, m2, t1, t2, va, vb;
-  struct gf_w16_bytwo_data *btd;
-  gf_region_data rd;
-    
-  if (val == 0) { gf_multby_zero(dest, bytes, xor); return; }
-  if (val == 1) { gf_multby_one(src, dest, bytes, xor); return; }
-
-  gf_set_region_data(&rd, gf, src, dest, bytes, val, xor, 16);
-  gf_do_initial_region_alignment(&rd);
-
-  btd = (struct gf_w16_bytwo_data *) ((gf_internal_t *) (gf->scratch))->private;
-
-  if (val == 2) {
-    if (xor) {
-      gf_w16_bytwo_b_sse_region_2_xor(&rd, btd);
-    } else {
-      gf_w16_bytwo_b_sse_region_2_noxor(&rd, btd);
-    }
-    gf_do_final_region_alignment(&rd);
-    return;
-  }
-
-  s8 = (uint8_t *) rd.s_start;
-  d8 = (uint8_t *) rd.d_start;
-
-  pp = _mm_set1_epi16(btd->prim_poly&0xffff);
-  m1 = _mm_set1_epi16((btd->mask1)&0xffff);
-  m2 = _mm_set1_epi16((btd->mask2)&0xffff);
-
-  while (d8 < (uint8_t *) rd.d_top) {
-    va = _mm_load_si128 ((__m128i *)(s8));
-    vb = (!xor) ? _mm_setzero_si128() : _mm_load_si128 ((__m128i *)(d8));
-    itb = val;
-    while (1) {
-      if (itb & 1) vb = _mm_xor_si128(vb, va);
-      itb >>= 1;
-      if (itb == 0) break;
-      SSE_AB2(pp, m1, m2, va, t1, t2);
-    }
-    _mm_store_si128((__m128i *)d8, vb);
-    d8 += 16;
-    s8 += 16;
-  }
-
-  gf_do_final_region_alignment(&rd);
-}
-#endif
-
-static
-void 
-gf_w16_bytwo_b_nosse_multiply_region(gf_t *gf, void *src, void *dest, gf_val_32_t val, int bytes, int xor)
-{
-  uint64_t *s64, *d64, t1, t2, ta, tb, prod;
-  struct gf_w16_bytwo_data *btd;
-  gf_region_data rd;
-
-  if (val == 0) { gf_multby_zero(dest, bytes, xor); return; }
-  if (val == 1) { gf_multby_one(src, dest, bytes, xor); return; }
-
-  gf_set_region_data(&rd, gf, src, dest, bytes, val, xor, 16);
-  gf_do_initial_region_alignment(&rd);
-
-  btd = (struct gf_w16_bytwo_data *) ((gf_internal_t *) (gf->scratch))->private;
-  s64 = (uint64_t *) rd.s_start;
-  d64 = (uint64_t *) rd.d_start;
-
-  switch (val) {
-  case 2:
-    if (xor) {
-      while (d64 < (uint64_t *) rd.d_top) {
-        ta = *s64;
-        AB2(btd->prim_poly, btd->mask1, btd->mask2, ta, t1, t2);
-        *d64 ^= ta;
-        d64++;
-        s64++;
-      }
-    } else {
-      while (d64 < (uint64_t *) rd.d_top) {
-        ta = *s64;
-        AB2(btd->prim_poly, btd->mask1, btd->mask2, ta, t1, t2);
-        *d64 = ta;
-        d64++;
-        s64++;
-      }
-    }
-    break; 
-  case 3:
-    if (xor) {
-      while (d64 < (uint64_t *) rd.d_top) {
-        ta = *s64;
-        prod = ta;
-        AB2(btd->prim_poly, btd->mask1, btd->mask2, ta, t1, t2);
-        *d64 ^= (ta ^ prod);
-        d64++;
-        s64++;
-      }
-    } else {
-      while (d64 < (uint64_t *) rd.d_top) {
-        ta = *s64;
-        prod = ta;
-        AB2(btd->prim_poly, btd->mask1, btd->mask2, ta, t1, t2);
-        *d64 = (ta ^ prod);
-        d64++;
-        s64++;
-      }
-    }
-    break; 
-  case 4:
-    if (xor) {
-      while (d64 < (uint64_t *) rd.d_top) {
-        ta = *s64;
-        AB2(btd->prim_poly, btd->mask1, btd->mask2, ta, t1, t2);
-        AB2(btd->prim_poly, btd->mask1, btd->mask2, ta, t1, t2);
-        *d64 ^= ta;
-        d64++;
-        s64++;
-      }
-    } else {
-      while (d64 < (uint64_t *) rd.d_top) {
-        ta = *s64;
-        AB2(btd->prim_poly, btd->mask1, btd->mask2, ta, t1, t2);
-        AB2(btd->prim_poly, btd->mask1, btd->mask2, ta, t1, t2);
-        *d64 = ta;
-        d64++;
-        s64++;
-      }
-    }
-    break; 
-  case 5:
-    if (xor) {
-      while (d64 < (uint64_t *) rd.d_top) {
-        ta = *s64;
-        prod = ta;
-        AB2(btd->prim_poly, btd->mask1, btd->mask2, ta, t1, t2);
-        AB2(btd->prim_poly, btd->mask1, btd->mask2, ta, t1, t2);
-        *d64 ^= (ta ^ prod);
-        d64++;
-        s64++;
-      }
-    } else {
-      while (d64 < (uint64_t *) rd.d_top) {
-        ta = *s64;
-        prod = ta;
-        AB2(btd->prim_poly, btd->mask1, btd->mask2, ta, t1, t2);
-        AB2(btd->prim_poly, btd->mask1, btd->mask2, ta, t1, t2);
-        *d64 = ta ^ prod;
-        d64++;
-        s64++;
-      }
-    }
-    break;
-  default:
-    if (xor) {
-      while (d64 < (uint64_t *) rd.d_top) {
-        prod = *d64 ;
-        ta = *s64;
-        tb = val;
-        while (1) {
-          if (tb & 1) prod ^= ta;
-          tb >>= 1;
-          if (tb == 0) break;
-          AB2(btd->prim_poly, btd->mask1, btd->mask2, ta, t1, t2);
-        }
-        *d64 = prod;
-        d64++;
-        s64++;
-      }
-    } else {
-      while (d64 < (uint64_t *) rd.d_top) {
-        prod = 0 ;
-        ta = *s64;
-        tb = val;
-        while (1) {
-          if (tb & 1) prod ^= ta;
-          tb >>= 1;
-          if (tb == 0) break;
-          AB2(btd->prim_poly, btd->mask1, btd->mask2, ta, t1, t2);
-        }
-        *d64 = prod;
-        d64++;
-        s64++;
-      }
-    }
-    break;
-  }
-  gf_do_final_region_alignment(&rd);
-}
-
-static
-int gf_w16_bytwo_init(gf_t *gf)
-{
-  gf_internal_t *h;
-  uint64_t ip, m1, m2;
-  struct gf_w16_bytwo_data *btd;
-
-  h = (gf_internal_t *) gf->scratch;
-  btd = (struct gf_w16_bytwo_data *) (h->private);
-  ip = h->prim_poly & 0xffff;
-  m1 = 0xfffe;
-  m2 = 0x8000;
-  btd->prim_poly = 0;
-  btd->mask1 = 0;
-  btd->mask2 = 0;
-
-  while (ip != 0) {
-    btd->prim_poly |= ip;
-    btd->mask1 |= m1;
-    btd->mask2 |= m2;
-    ip <<= GF_FIELD_WIDTH;
-    m1 <<= GF_FIELD_WIDTH;
-    m2 <<= GF_FIELD_WIDTH;
-  }
-
-  if (h->mult_type == GF_MULT_BYTWO_p) {
-    gf->multiply.w32 = gf_w16_bytwo_p_multiply;
-    #ifdef INTEL_SSE2
-      if (h->region_type & GF_REGION_NOSIMD)
-        gf->multiply_region.w32 = gf_w16_bytwo_p_nosse_multiply_region;
-      else
-        gf->multiply_region.w32 = gf_w16_bytwo_p_sse_multiply_region;
-    #else
-      gf->multiply_region.w32 = gf_w16_bytwo_p_nosse_multiply_region;
-      if(h->region_type & GF_REGION_SIMD)
-        return 0;
-    #endif
-  } else {
-    gf->multiply.w32 = gf_w16_bytwo_b_multiply;
-    #ifdef INTEL_SSE2
-      if (h->region_type & GF_REGION_NOSIMD)
-        gf->multiply_region.w32 = gf_w16_bytwo_b_nosse_multiply_region;
-      else
-        gf->multiply_region.w32 = gf_w16_bytwo_b_sse_multiply_region;
-    #else
-      gf->multiply_region.w32 = gf_w16_bytwo_b_nosse_multiply_region;
-      if(h->region_type & GF_REGION_SIMD)
-        return 0;
-    #endif
-  }
-
-  return 1;
-}
-
-static
-int gf_w16_log_zero_init(gf_t *gf)
-{
-  gf_internal_t *h;
-  struct gf_w16_zero_logtable_data *ltd;
-  int i, b;
-
-  h = (gf_internal_t *) gf->scratch;
-  ltd = h->private;
-
-  ltd->log_tbl[0] = (-GF_MULT_GROUP_SIZE) + 1;
-
-  bzero(&(ltd->_antilog_tbl[0]), sizeof(ltd->_antilog_tbl));
-
-  ltd->antilog_tbl = &(ltd->_antilog_tbl[GF_FIELD_SIZE * 2]);
-
-  b = 1;
-  for (i = 0; i < GF_MULT_GROUP_SIZE; i++) {
-      ltd->log_tbl[b] = (uint16_t)i;
-      ltd->antilog_tbl[i] = (uint16_t)b;
-      ltd->antilog_tbl[i+GF_MULT_GROUP_SIZE] = (uint16_t)b;
-      b <<= 1;
-      if (b & GF_FIELD_SIZE) {
-          b = b ^ h->prim_poly;
-      }
-  }
-  ltd->inv_tbl[0] = 0;  /* Not really, but we need to fill it with something  */
-  ltd->inv_tbl[1] = 1;
-  for (i = 2; i < GF_FIELD_SIZE; i++) {
-    ltd->inv_tbl[i] = ltd->antilog_tbl[GF_MULT_GROUP_SIZE-ltd->log_tbl[i]];
-  }
-
-  gf->inverse.w32 = gf_w16_log_zero_inverse;
-  gf->divide.w32 = gf_w16_log_zero_divide;
-  gf->multiply.w32 = gf_w16_log_zero_multiply;
-  gf->multiply_region.w32 = gf_w16_log_zero_multiply_region;
-  return 1;
-}
-
-static
-gf_val_32_t
-gf_w16_composite_multiply_recursive(gf_t *gf, gf_val_32_t a, gf_val_32_t b)
-{
-  gf_internal_t *h = (gf_internal_t *) gf->scratch;
-  gf_t *base_gf = h->base_gf;
-  uint8_t b0 = b & 0x00ff;
-  uint8_t b1 = (b & 0xff00) >> 8;
-  uint8_t a0 = a & 0x00ff;
-  uint8_t a1 = (a & 0xff00) >> 8;
-  uint8_t a1b1;
-  uint16_t rv;
-
-  a1b1 = base_gf->multiply.w32(base_gf, a1, b1);
-
-  rv = ((base_gf->multiply.w32(base_gf, a0, b0) ^ a1b1) | ((base_gf->multiply.w32(base_gf, a1, b0) ^ base_gf->multiply.w32(base_gf, a0, b1) ^ base_gf->multiply.w32(base_gf, a1b1, h->prim_poly)) << 8));
-  return rv;
-}
-
-static
-gf_val_32_t
-gf_w16_composite_multiply_inline(gf_t *gf, gf_val_32_t a, gf_val_32_t b)
-{
-  gf_internal_t *h = (gf_internal_t *) gf->scratch;
-  uint8_t b0 = b & 0x00ff;
-  uint8_t b1 = (b & 0xff00) >> 8;
-  uint8_t a0 = a & 0x00ff;
-  uint8_t a1 = (a & 0xff00) >> 8;
-  uint8_t a1b1, *mt;
-  uint16_t rv;
-  struct gf_w16_composite_data *cd;
-
-  cd = (struct gf_w16_composite_data *) h->private;
-  mt = cd->mult_table;
-
-  a1b1 = GF_W8_INLINE_MULTDIV(mt, a1, b1);
-
-  rv = ((GF_W8_INLINE_MULTDIV(mt, a0, b0) ^ a1b1) | ((GF_W8_INLINE_MULTDIV(mt, a1, b0) ^ GF_W8_INLINE_MULTDIV(mt, a0, b1) ^ GF_W8_INLINE_MULTDIV(mt, a1b1, h->prim_poly)) << 8));
-  return rv;
-}
-
-/*
- * Composite field division trick (explained in 2007 tech report)
- *
- * Compute a / b = a*b^-1, where p(x) = x^2 + sx + 1
- *
- * let c = b^-1
- *
- * c*b = (s*b1c1+b1c0+b0c1)x+(b1c1+b0c0)
- *
- * want (s*b1c1+b1c0+b0c1) = 0 and (b1c1+b0c0) = 1
- *
- * let d = b1c1 and d+1 = b0c0
- *
- * solve s*b1c1+b1c0+b0c1 = 0
- *
- * solution: d = (b1b0^-1)(b1b0^-1+b0b1^-1+s)^-1
- *
- * c0 = (d+1)b0^-1
- * c1 = d*b1^-1
- *
- * a / b = a * c
- */
-
-static
-gf_val_32_t
-gf_w16_composite_inverse(gf_t *gf, gf_val_32_t a)
-{
-  gf_internal_t *h = (gf_internal_t *) gf->scratch;
-  gf_t *base_gf = h->base_gf;
-  uint8_t a0 = a & 0x00ff;
-  uint8_t a1 = (a & 0xff00) >> 8;
-  uint8_t c0, c1, d, tmp;
-  uint16_t c;
-  uint8_t a0inv, a1inv;
-
-  if (a0 == 0) {
-    a1inv = base_gf->inverse.w32(base_gf, a1);
-    c0 = base_gf->multiply.w32(base_gf, a1inv, h->prim_poly);
-    c1 = a1inv;
-  } else if (a1 == 0) {
-    c0 = base_gf->inverse.w32(base_gf, a0);
-    c1 = 0;
-  } else {
-    a1inv = base_gf->inverse.w32(base_gf, a1);
-    a0inv = base_gf->inverse.w32(base_gf, a0);
-
-    d = base_gf->multiply.w32(base_gf, a1, a0inv);
-
-    tmp = (base_gf->multiply.w32(base_gf, a1, a0inv) ^ base_gf->multiply.w32(base_gf, a0, a1inv) ^ h->prim_poly);
-    tmp = base_gf->inverse.w32(base_gf, tmp);
-
-    d = base_gf->multiply.w32(base_gf, d, tmp);
-
-    c0 = base_gf->multiply.w32(base_gf, (d^1), a0inv);
-    c1 = base_gf->multiply.w32(base_gf, d, a1inv);
-  }
-
-  c = c0 | (c1 << 8);
-
-  return c;
-}
-
-static
-void
-gf_w16_composite_multiply_region(gf_t *gf, void *src, void *dest, gf_val_32_t val, int bytes, int xor)
-{
-  gf_internal_t *h = (gf_internal_t *) gf->scratch;
-  gf_t *base_gf = h->base_gf;
-  uint8_t b0 = val & 0x00ff;
-  uint8_t b1 = (val & 0xff00) >> 8;
-  uint16_t *s16, *d16, *top;
-  uint8_t a0, a1, a1b1, *mt;
-  gf_region_data rd;
-  struct gf_w16_composite_data *cd;
-
-  cd = (struct gf_w16_composite_data *) h->private;
-  mt = cd->mult_table;
-  
-  if (val == 0) { gf_multby_zero(dest, bytes, xor); return; }
-  gf_set_region_data(&rd, gf, src, dest, bytes, val, xor, 2);
-
-  s16 = rd.s_start;
-  d16 = rd.d_start;
-  top = rd.d_top;
-
-  if (mt == NULL) {
-    if (xor) {
-      while (d16 < top) {
-        a0 = (*s16) & 0x00ff;
-        a1 = ((*s16) & 0xff00) >> 8;
-        a1b1 = base_gf->multiply.w32(base_gf, a1, b1);
-  
-        (*d16) ^= ((base_gf->multiply.w32(base_gf, a0, b0) ^ a1b1) |
-                  ((base_gf->multiply.w32(base_gf, a1, b0) ^ 
-                    base_gf->multiply.w32(base_gf, a0, b1) ^ 
-                    base_gf->multiply.w32(base_gf, a1b1, h->prim_poly)) << 8));
-        s16++;
-        d16++;
-      }
-    } else {
-      while (d16 < top) {
-        a0 = (*s16) & 0x00ff;
-        a1 = ((*s16) & 0xff00) >> 8;
-        a1b1 = base_gf->multiply.w32(base_gf, a1, b1);
-  
-        (*d16) = ((base_gf->multiply.w32(base_gf, a0, b0) ^ a1b1) |
-                  ((base_gf->multiply.w32(base_gf, a1, b0) ^ 
-                    base_gf->multiply.w32(base_gf, a0, b1) ^ 
-                    base_gf->multiply.w32(base_gf, a1b1, h->prim_poly)) << 8));
-        s16++;
-        d16++;
-      }
-    }
-  } else {
-    if (xor) {
-      while (d16 < top) {
-        a0 = (*s16) & 0x00ff;
-        a1 = ((*s16) & 0xff00) >> 8;
-        a1b1 = GF_W8_INLINE_MULTDIV(mt, a1, b1);
-  
-        (*d16) ^= ((GF_W8_INLINE_MULTDIV(mt, a0, b0) ^ a1b1) |
-                  ((GF_W8_INLINE_MULTDIV(mt, a1, b0) ^ 
-                    GF_W8_INLINE_MULTDIV(mt, a0, b1) ^ 
-                    GF_W8_INLINE_MULTDIV(mt, a1b1, h->prim_poly)) << 8));
-        s16++;
-        d16++;
-      }
-    } else {
-      while (d16 < top) {
-        a0 = (*s16) & 0x00ff;
-        a1 = ((*s16) & 0xff00) >> 8;
-        a1b1 = GF_W8_INLINE_MULTDIV(mt, a1, b1);
-  
-        (*d16) = ((GF_W8_INLINE_MULTDIV(mt, a0, b0) ^ a1b1) |
-                  ((GF_W8_INLINE_MULTDIV(mt, a1, b0) ^ 
-                    GF_W8_INLINE_MULTDIV(mt, a0, b1) ^ 
-                    GF_W8_INLINE_MULTDIV(mt, a1b1, h->prim_poly)) << 8));
-        s16++;
-        d16++;
-      }
-    }
-  }
-}
-
-static
-void
-gf_w16_composite_multiply_region_alt(gf_t *gf, void *src, void *dest, gf_val_32_t val, int bytes, int xor)
-{
-  gf_internal_t *h = (gf_internal_t *) gf->scratch;
-  gf_t *base_gf = h->base_gf;
-  uint8_t val0 = val & 0x00ff;
-  uint8_t val1 = (val & 0xff00) >> 8;
-  gf_region_data rd;
-  int sub_reg_size;
-  uint8_t *slow, *shigh;
-  uint8_t *dlow, *dhigh, *top;;
-
-  /* JSP: I want the two pointers aligned wrt each other on 16 byte 
-     boundaries.  So I'm going to make sure that the area on 
-     which the two operate is a multiple of 32. Of course, that 
-     junks up the mapping, but so be it -- that's why we have extract_word.... */
-
-  gf_set_region_data(&rd, gf, src, dest, bytes, val, xor, 32);
-  gf_do_initial_region_alignment(&rd);
-
-  slow = (uint8_t *) rd.s_start;
-  dlow = (uint8_t *) rd.d_start;
-  top = (uint8_t *)  rd.d_top;
-  sub_reg_size = (top - dlow)/2;
-  shigh = slow + sub_reg_size;
-  dhigh = dlow + sub_reg_size;
-
-  base_gf->multiply_region.w32(base_gf, slow, dlow, val0, sub_reg_size, xor);
-  base_gf->multiply_region.w32(base_gf, shigh, dlow, val1, sub_reg_size, 1);
-  base_gf->multiply_region.w32(base_gf, slow, dhigh, val1, sub_reg_size, xor);
-  base_gf->multiply_region.w32(base_gf, shigh, dhigh, val0, sub_reg_size, 1);
-  base_gf->multiply_region.w32(base_gf, shigh, dhigh, base_gf->multiply.w32(base_gf, h->prim_poly, val1), sub_reg_size, 1);
-
-  gf_do_final_region_alignment(&rd);
-}
-
-static
-int gf_w16_composite_init(gf_t *gf)
-{
-  gf_internal_t *h = (gf_internal_t *) gf->scratch;
-  struct gf_w16_composite_data *cd;
-
-  if (h->base_gf == NULL) return 0;
-
-  cd = (struct gf_w16_composite_data *) h->private;
-  cd->mult_table = gf_w8_get_mult_table(h->base_gf);
-
-  if (h->region_type & GF_REGION_ALTMAP) {
-    gf->multiply_region.w32 = gf_w16_composite_multiply_region_alt;
-  } else {
-    gf->multiply_region.w32 = gf_w16_composite_multiply_region;
-  }
-
-  if (cd->mult_table == NULL) {
-    gf->multiply.w32 = gf_w16_composite_multiply_recursive;
-  } else {
-    gf->multiply.w32 = gf_w16_composite_multiply_inline;
-  }
-  gf->divide.w32 = NULL;
-  gf->inverse.w32 = gf_w16_composite_inverse;
-
-  return 1;
-}
-
-static
-void
-gf_w16_group_4_set_shift_tables(uint16_t *shift, uint16_t val, gf_internal_t *h)
-{
-  int i, j;
-
-  shift[0] = 0;
-  for (i = 0; i < 16; i += 2) {
-    j = (shift[i>>1] << 1);
-    if (j & (1 << 16)) j ^= h->prim_poly;
-    shift[i] = j;
-    shift[i^1] = j^val;
-  }
-}
-
-static
-inline
-gf_val_32_t
-gf_w16_group_4_4_multiply(gf_t *gf, gf_val_32_t a, gf_val_32_t b)
-{
-  uint16_t p, l, ind, r, a16;
-
-  struct gf_w16_group_4_4_data *d44;
-  gf_internal_t *h = (gf_internal_t *) gf->scratch;
-
-  d44 = (struct gf_w16_group_4_4_data *) h->private;
-  gf_w16_group_4_set_shift_tables(d44->shift, b, h);
-
-  a16 = a;
-  ind = a16 >> 12;
-  a16 <<= 4;
-  p = d44->shift[ind];
-  r = p & 0xfff;
-  l = p >> 12;
-  ind = a16 >> 12;
-  a16 <<= 4;
-  p = (d44->shift[ind] ^ d44->reduce[l] ^ (r << 4));
-  r = p & 0xfff;
-  l = p >> 12;
-  ind = a16 >> 12;
-  a16 <<= 4;
-  p = (d44->shift[ind] ^ d44->reduce[l] ^ (r << 4));
-  r = p & 0xfff;
-  l = p >> 12;
-  ind = a16 >> 12;
-  p = (d44->shift[ind] ^ d44->reduce[l] ^ (r << 4));
-  return p;
-}
-
-static
-void gf_w16_group_4_4_region_multiply(gf_t *gf, void *src, void *dest, gf_val_32_t val, int bytes, int xor)
-{
-  uint16_t p, l, ind, r, a16, p16;
-  struct gf_w16_group_4_4_data *d44;
-  gf_region_data rd;
-  uint16_t *s16, *d16, *top;
-  
-  if (val == 0) { gf_multby_zero(dest, bytes, xor); return; }
-  if (val == 1) { gf_multby_one(src, dest, bytes, xor); return; }
-
-  gf_internal_t *h = (gf_internal_t *) gf->scratch;
-  d44 = (struct gf_w16_group_4_4_data *) h->private;
-  gf_w16_group_4_set_shift_tables(d44->shift, val, h);
-
-  gf_set_region_data(&rd, gf, src, dest, bytes, val, xor, 2);
-  gf_do_initial_region_alignment(&rd);
-
-  s16 = (uint16_t *) rd.s_start;
-  d16 = (uint16_t *) rd.d_start;
-  top = (uint16_t *) rd.d_top;
-
-  while (d16 < top) {
-    a16 = *s16;
-    p16 = (xor) ? *d16 : 0;
-    ind = a16 >> 12;
-    a16 <<= 4;
-    p = d44->shift[ind];
-    r = p & 0xfff;
-    l = p >> 12;
-    ind = a16 >> 12;
-    a16 <<= 4;
-    p = (d44->shift[ind] ^ d44->reduce[l] ^ (r << 4));
-    r = p & 0xfff;
-    l = p >> 12;
-    ind = a16 >> 12;
-    a16 <<= 4;
-    p = (d44->shift[ind] ^ d44->reduce[l] ^ (r << 4));
-    r = p & 0xfff;
-    l = p >> 12;
-    ind = a16 >> 12;
-    p = (d44->shift[ind] ^ d44->reduce[l] ^ (r << 4));
-    p ^= p16;
-    *d16 = p;
-    d16++;
-    s16++;
-  }
-  gf_do_final_region_alignment(&rd);
-}
-
-static
-int gf_w16_group_init(gf_t *gf)
-{
-  int i, j, p;
-  struct gf_w16_group_4_4_data *d44;
-  gf_internal_t *h = (gf_internal_t *) gf->scratch;
-
-  d44 = (struct gf_w16_group_4_4_data *) h->private;
-  d44->reduce[0] = 0;
-  for (i = 0; i < 16; i++) {
-    p = 0;
-    for (j = 0; j < 4; j++) {
-      if (i & (1 << j)) p ^= (h->prim_poly << j);
-    }
-    d44->reduce[p>>16] = (p&0xffff);
-  }
-
-  gf->multiply.w32 = gf_w16_group_4_4_multiply;
-  gf->divide.w32 = NULL;
-  gf->inverse.w32 = NULL;
-  gf->multiply_region.w32 = gf_w16_group_4_4_region_multiply;
-
-  return 1;
-}
-
-int gf_w16_scratch_size(int mult_type, int region_type, int divide_type, int arg1, int arg2)
-{
-  switch(mult_type)
-  {
-    case GF_MULT_TABLE:
-      return sizeof(gf_internal_t) + sizeof(struct gf_w16_lazytable_data) + 64;
-      break;
-    case GF_MULT_BYTWO_p:
-    case GF_MULT_BYTWO_b:
-      return sizeof(gf_internal_t) + sizeof(struct gf_w16_bytwo_data);
-      break;
-    case GF_MULT_LOG_ZERO:
-      return sizeof(gf_internal_t) + sizeof(struct gf_w16_zero_logtable_data) + 64;
-      break;
-    case GF_MULT_LOG_TABLE:
-      return sizeof(gf_internal_t) + sizeof(struct gf_w16_logtable_data) + 64;
-      break;
-    case GF_MULT_DEFAULT:
-    case GF_MULT_SPLIT_TABLE: 
-      if (arg1 == 8 && arg2 == 8) {
-        return sizeof(gf_internal_t) + sizeof(struct gf_w16_split_8_8_data) + 64;
-      } else if ((arg1 == 8 && arg2 == 16) || (arg2 == 8 && arg1 == 16)) {
-        return sizeof(gf_internal_t) + sizeof(struct gf_w16_logtable_data) + 64;
-      } else if (mult_type == GF_MULT_DEFAULT || 
-                 (arg1 == 4 && arg2 == 16) || (arg2 == 4 && arg1 == 16)) {
-        return sizeof(gf_internal_t) + sizeof(struct gf_w16_logtable_data) + 64;
-      }
-      return 0;
-      break;
-    case GF_MULT_GROUP:     
-      return sizeof(gf_internal_t) + sizeof(struct gf_w16_group_4_4_data) + 64;
-      break;
-    case GF_MULT_CARRY_FREE:
-      return sizeof(gf_internal_t);
-      break;
-    case GF_MULT_SHIFT:
-      return sizeof(gf_internal_t);
-      break;
-    case GF_MULT_COMPOSITE:
-      return sizeof(gf_internal_t) + sizeof(struct gf_w16_composite_data) + 64;
-      break;
-
-    default:
-      return 0;
-   }
-   return 0;
-}
-
-int gf_w16_init(gf_t *gf)
-{
-  gf_internal_t *h;
-
-  h = (gf_internal_t *) gf->scratch;
-
-  /* Allen: set default primitive polynomial / irreducible polynomial if needed */
-
-  if (h->prim_poly == 0) {
-    if (h->mult_type == GF_MULT_COMPOSITE) {
-      h->prim_poly = gf_composite_get_default_poly(h->base_gf);
-      if (h->prim_poly == 0) return 0;
-    } else { 
-
-     /* Allen: use the following primitive polynomial to make 
-               carryless multiply work more efficiently for GF(2^16).
-
-        h->prim_poly = 0x1002d;
-
-        The following is the traditional primitive polynomial for GF(2^16) */
-
-      h->prim_poly = 0x1100b;
-    } 
-  }
-
-  if (h->mult_type != GF_MULT_COMPOSITE) h->prim_poly |= (1 << 16);
-
-  gf->multiply.w32 = NULL;
-  gf->divide.w32 = NULL;
-  gf->inverse.w32 = NULL;
-  gf->multiply_region.w32 = NULL;
-
-  switch(h->mult_type) {
-    case GF_MULT_LOG_ZERO:    if (gf_w16_log_zero_init(gf) == 0) return 0; break;
-    case GF_MULT_LOG_TABLE:   if (gf_w16_log_init(gf) == 0) return 0; break;
-    case GF_MULT_DEFAULT: 
-    case GF_MULT_SPLIT_TABLE: if (gf_w16_split_init(gf) == 0) return 0; break;
-    case GF_MULT_TABLE:       if (gf_w16_table_init(gf) == 0) return 0; break;
-    case GF_MULT_CARRY_FREE:  if (gf_w16_cfm_init(gf) == 0) return 0; break;
-    case GF_MULT_SHIFT:       if (gf_w16_shift_init(gf) == 0) return 0; break;
-    case GF_MULT_COMPOSITE:   if (gf_w16_composite_init(gf) == 0) return 0; break;
-    case GF_MULT_BYTWO_p: 
-    case GF_MULT_BYTWO_b:     if (gf_w16_bytwo_init(gf) == 0) return 0; break;
-    case GF_MULT_GROUP:       if (gf_w16_group_init(gf) == 0) return 0; break;
-    default: return 0;
-  }
-  if (h->divide_type == GF_DIVIDE_EUCLID) {
-    gf->divide.w32 = gf_w16_divide_from_inverse;
-    gf->inverse.w32 = gf_w16_euclid;
-  } else if (h->divide_type == GF_DIVIDE_MATRIX) {
-    gf->divide.w32 = gf_w16_divide_from_inverse;
-    gf->inverse.w32 = gf_w16_matrix;
-  }
-
-  if (gf->divide.w32 == NULL) {
-    gf->divide.w32 = gf_w16_divide_from_inverse;
-    if (gf->inverse.w32 == NULL) gf->inverse.w32 = gf_w16_euclid;
-  }
-
-  if (gf->inverse.w32 == NULL)  gf->inverse.w32 = gf_w16_inverse_from_divide;
-
-  if (h->region_type & GF_REGION_ALTMAP) {
-    if (h->mult_type == GF_MULT_COMPOSITE) {
-      gf->extract_word.w32 = gf_w16_composite_extract_word;
-    } else {
-      gf->extract_word.w32 = gf_w16_split_extract_word;
-    }
-  } else if (h->region_type == GF_REGION_CAUCHY) {
-    gf->multiply_region.w32 = gf_wgen_cauchy_region;
-    gf->extract_word.w32 = gf_wgen_extract_word;
-  } else {
-    gf->extract_word.w32 = gf_w16_extract_word;
-  }
-  if (gf->multiply_region.w32 == NULL) {
-    gf->multiply_region.w32 = gf_w16_multiply_region_from_single;
-  }
-  return 1;
-}
-
-/* Inline setup functions */
-
-uint16_t *gf_w16_get_log_table(gf_t *gf)
-{
-  struct gf_w16_logtable_data *ltd;
-
-  if (gf->multiply.w32 == gf_w16_log_multiply) {
-    ltd = (struct gf_w16_logtable_data *) ((gf_internal_t *) gf->scratch)->private;
-    return (uint16_t *) ltd->log_tbl;
-  }
-  return NULL;
-}
-
-uint16_t *gf_w16_get_mult_alog_table(gf_t *gf)
-{
-  gf_internal_t *h;
-  struct gf_w16_logtable_data *ltd;
-
-  h = (gf_internal_t *) gf->scratch;
-  if (gf->multiply.w32 == gf_w16_log_multiply) {
-    ltd = (struct gf_w16_logtable_data *) h->private;
-    return (uint16_t *) ltd->antilog_tbl;
-  }
-  return NULL;
-}
-
-uint16_t *gf_w16_get_div_alog_table(gf_t *gf)
-{
-  gf_internal_t *h;
-  struct gf_w16_logtable_data *ltd;
-
-  h = (gf_internal_t *) gf->scratch;
-  if (gf->multiply.w32 == gf_w16_log_multiply) {
-    ltd = (struct gf_w16_logtable_data *) h->private;
-    return (uint16_t *) ltd->d_antilog;
-  }
-  return NULL;
-}
diff --git a/src/erasure-code/jerasure/gf-complete/src/gf_w32.c b/src/erasure-code/jerasure/gf-complete/src/gf_w32.c
deleted file mode 100644
index 854a6e4..0000000
--- a/src/erasure-code/jerasure/gf-complete/src/gf_w32.c
+++ /dev/null
@@ -1,2823 +0,0 @@
-/*
- * GF-Complete: A Comprehensive Open Source Library for Galois Field Arithmetic
- * James S. Plank, Ethan L. Miller, Kevin M. Greenan,
- * Benjamin A. Arnold, John A. Burnum, Adam W. Disney, Allen C. McBride.
- *
- * gf_w32.c
- *
- * Routines for 32-bit Galois fields
- */
-
-
-#include "gf_int.h"
-#include <stdio.h>
-#include <stdlib.h>
-#include "gf_w32.h"
-
-#define MM_PRINT32(s, r) { uint8_t blah[16], ii; printf("%-12s", s); _mm_storeu_si128((__m128i *)blah, r); for (ii = 0; ii < 16; ii += 4) printf(" %02x%02x%02x%02x", blah[15-ii], blah[14-ii], blah[13-ii], blah[12-ii]); printf("\n"); }
-
-#define MM_PRINT8(s, r) { uint8_t blah[16], ii; printf("%-12s", s); _mm_storeu_si128((__m128i *)blah, r); for (ii = 0; ii < 16; ii += 1) printf("%s%02x", (ii%4==0) ? "   " : " ", blah[15-ii]); printf("\n"); }
-
-#define AB2(ip, am1 ,am2, b, t1, t2) {\
-  t1 = (b << 1) & am1;\
-  t2 = b & am2; \
-  t2 = ((t2 << 1) - (t2 >> (GF_FIELD_WIDTH-1))); \
-  b = (t1 ^ (t2 & ip));}
-
-#define SSE_AB2(pp, m1 ,m2, va, t1, t2) {\
-          t1 = _mm_and_si128(_mm_slli_epi64(va, 1), m1); \
-          t2 = _mm_and_si128(va, m2); \
-          t2 = _mm_sub_epi64 (_mm_slli_epi64(t2, 1), _mm_srli_epi64(t2, (GF_FIELD_WIDTH-1))); \
-          va = _mm_xor_si128(t1, _mm_and_si128(t2, pp)); }
-
-static
-inline
-uint32_t gf_w32_inverse_from_divide (gf_t *gf, uint32_t a)
-{
-  return gf->divide.w32(gf, 1, a);
-}
-
-static
-inline
-uint32_t gf_w32_divide_from_inverse (gf_t *gf, uint32_t a, uint32_t b)
-{
-  b = gf->inverse.w32(gf, b);
-  return gf->multiply.w32(gf, a, b);
-}
-
-static
-void
-gf_w32_multiply_region_from_single(gf_t *gf, void *src, void *dest, uint32_t val, int bytes, int 
-xor)
-{
-  uint32_t i;
-  uint32_t *s32;
-  uint32_t *d32;
-   
-  s32 = (uint32_t *) src;
-  d32 = (uint32_t *) dest; 
- 
-  if (xor) {
-    for (i = 0; i < bytes/sizeof(uint32_t); i++) {
-      d32[i] ^= gf->multiply.w32(gf, val, s32[i]);
-    } 
-  } else {
-    for (i = 0; i < bytes/sizeof(uint32_t); i++) {
-      d32[i] = gf->multiply.w32(gf, val, s32[i]);
-    } 
-  }
-}
-
-#if defined(INTEL_SSE4_PCLMUL)
-
-static 
-void
-gf_w32_clm_multiply_region_from_single_2(gf_t *gf, void *src, void *dest, uint32_t val, int bytes, int xor)
-{
-
-  uint32_t i;
-  uint32_t *s32;
-  uint32_t *d32;
-  
-  __m128i         a, b;
-  __m128i         result;
-  __m128i         prim_poly;
-  __m128i         w;
-  gf_internal_t * h = gf->scratch;
-  
-  prim_poly = _mm_set_epi32(0, 0, 1, (uint32_t)(h->prim_poly & 0xffffffffULL));
-   
-  if (val == 0) { gf_multby_zero(dest, bytes, xor); return; }
-  if (val == 1) { gf_multby_one(src, dest, bytes, xor); return; }
-
-  a = _mm_insert_epi32 (_mm_setzero_si128(), val, 0);
-  s32 = (uint32_t *) src;
-  d32 = (uint32_t *) dest; 
- 
-  if (xor) {
-    for (i = 0; i < bytes/sizeof(uint32_t); i++) {
-      b = _mm_insert_epi32 (a, s32[i], 0);
-      result = _mm_clmulepi64_si128 (a, b, 0);
-      w = _mm_clmulepi64_si128 (prim_poly, _mm_srli_si128 (result, 4), 0);
-      result = _mm_xor_si128 (result, w);
-      w = _mm_clmulepi64_si128 (prim_poly, _mm_srli_si128 (result, 4), 0);
-      result = _mm_xor_si128 (result, w);
-      d32[i] ^= ((gf_val_32_t)_mm_extract_epi32(result, 0));
-    } 
-  } else {
-    for (i = 0; i < bytes/sizeof(uint32_t); i++) {
-      b = _mm_insert_epi32 (a, s32[i], 0);
-      result = _mm_clmulepi64_si128 (a, b, 0);
-      w = _mm_clmulepi64_si128 (prim_poly, _mm_srli_si128 (result, 4), 0);
-      result = _mm_xor_si128 (result, w);
-      w = _mm_clmulepi64_si128 (prim_poly, _mm_srli_si128 (result, 4), 0);
-      result = _mm_xor_si128 (result, w);
-      d32[i] = ((gf_val_32_t)_mm_extract_epi32(result, 0));
-    } 
-  }
-}
-#endif
-
-#if defined(INTEL_SSE4_PCLMUL) 
-
-static 
-void
-gf_w32_clm_multiply_region_from_single_3(gf_t *gf, void *src, void *dest, uint32_t val, int bytes, int xor)
-{
-
-  uint32_t i;
-  uint32_t *s32;
-  uint32_t *d32;
-  
-  __m128i         a, b;
-  __m128i         result;
-  __m128i         prim_poly;
-  __m128i         w;
-  gf_internal_t * h = gf->scratch;
-  
-  prim_poly = _mm_set_epi32(0, 0, 1, (uint32_t)(h->prim_poly & 0xffffffffULL));
-
-  if (val == 0) { gf_multby_zero(dest, bytes, xor); return; }
-  if (val == 1) { gf_multby_one(src, dest, bytes, xor); return; }
-  
-  a = _mm_insert_epi32 (_mm_setzero_si128(), val, 0);
-  
-  s32 = (uint32_t *) src;
-  d32 = (uint32_t *) dest; 
- 
-  if (xor) {
-    for (i = 0; i < bytes/sizeof(uint32_t); i++) {
-      b = _mm_insert_epi32 (a, s32[i], 0);
-      result = _mm_clmulepi64_si128 (a, b, 0);
-      w = _mm_clmulepi64_si128 (prim_poly, _mm_srli_si128 (result, 4), 0);
-      result = _mm_xor_si128 (result, w);
-      w = _mm_clmulepi64_si128 (prim_poly, _mm_srli_si128 (result, 4), 0);
-      result = _mm_xor_si128 (result, w);
-      w = _mm_clmulepi64_si128 (prim_poly, _mm_srli_si128 (result, 4), 0);
-      result = _mm_xor_si128 (result, w);
-      d32[i] ^= ((gf_val_32_t)_mm_extract_epi32(result, 0));
-    } 
-  } else {
-    for (i = 0; i < bytes/sizeof(uint32_t); i++) {
-      b = _mm_insert_epi32 (a, s32[i], 0);
-      result = _mm_clmulepi64_si128 (a, b, 0);
-      w = _mm_clmulepi64_si128 (prim_poly, _mm_srli_si128 (result, 4), 0);
-      result = _mm_xor_si128 (result, w);
-      w = _mm_clmulepi64_si128 (prim_poly, _mm_srli_si128 (result, 4), 0);
-      result = _mm_xor_si128 (result, w);
-      w = _mm_clmulepi64_si128 (prim_poly, _mm_srli_si128 (result, 4), 0);
-      result = _mm_xor_si128 (result, w);
-      d32[i] = ((gf_val_32_t)_mm_extract_epi32(result, 0));
-    } 
-  }
-}
-#endif
-
-#if defined(INTEL_SSE4_PCLMUL)
-static 
-void
-gf_w32_clm_multiply_region_from_single_4(gf_t *gf, void *src, void *dest, uint32_t val, int bytes, int xor)
-{
-  uint32_t i;
-  uint32_t *s32;
-  uint32_t *d32;
-  
-  __m128i         a, b;
-  __m128i         result;
-  __m128i         prim_poly;
-  __m128i         w;
-  gf_internal_t * h = gf->scratch;
-  
-  prim_poly = _mm_set_epi32(0, 0, 1, (uint32_t)(h->prim_poly & 0xffffffffULL));
-
-  if (val == 0) { gf_multby_zero(dest, bytes, xor); return; }
-  if (val == 1) { gf_multby_one(src, dest, bytes, xor); return; }
-  
-  a = _mm_insert_epi32 (_mm_setzero_si128(), val, 0);
-  
-  s32 = (uint32_t *) src;
-  d32 = (uint32_t *) dest; 
- 
-  if (xor) {
-    for (i = 0; i < bytes/sizeof(uint32_t); i++) {
-      b = _mm_insert_epi32 (a, s32[i], 0);
-      result = _mm_clmulepi64_si128 (a, b, 0);
-      w = _mm_clmulepi64_si128 (prim_poly, _mm_srli_si128 (result, 4), 0);
-      result = _mm_xor_si128 (result, w);
-      w = _mm_clmulepi64_si128 (prim_poly, _mm_srli_si128 (result, 4), 0);
-      result = _mm_xor_si128 (result, w);
-      w = _mm_clmulepi64_si128 (prim_poly, _mm_srli_si128 (result, 4), 0);
-      result = _mm_xor_si128 (result, w);
-      w = _mm_clmulepi64_si128 (prim_poly, _mm_srli_si128 (result, 4), 0);
-      result = _mm_xor_si128 (result, w);
-      d32[i] ^= ((gf_val_32_t)_mm_extract_epi32(result, 0));
-    } 
-  } else {
-    for (i = 0; i < bytes/sizeof(uint32_t); i++) {
-      b = _mm_insert_epi32 (a, s32[i], 0);
-      result = _mm_clmulepi64_si128 (a, b, 0);
-      w = _mm_clmulepi64_si128 (prim_poly, _mm_srli_si128 (result, 4), 0);
-      result = _mm_xor_si128 (result, w);
-      w = _mm_clmulepi64_si128 (prim_poly, _mm_srli_si128 (result, 4), 0);
-      result = _mm_xor_si128 (result, w);
-      w = _mm_clmulepi64_si128 (prim_poly, _mm_srli_si128 (result, 4), 0);
-      result = _mm_xor_si128 (result, w);
-      w = _mm_clmulepi64_si128 (prim_poly, _mm_srli_si128 (result, 4), 0);
-      result = _mm_xor_si128 (result, w);
-      d32[i] = ((gf_val_32_t)_mm_extract_epi32(result, 0));
-    } 
-  }
-}
-#endif
-
-static
-inline
-uint32_t gf_w32_euclid (gf_t *gf, uint32_t b)
-{
-  uint32_t e_i, e_im1, e_ip1;
-  uint32_t d_i, d_im1, d_ip1;
-  uint32_t y_i, y_im1, y_ip1;
-  uint32_t c_i;
-
-  if (b == 0) return -1;
-  e_im1 = ((gf_internal_t *) (gf->scratch))->prim_poly; 
-  e_i = b;
-  d_im1 = 32;
-  for (d_i = d_im1-1; ((1 << d_i) & e_i) == 0; d_i--) ;
-  y_i = 1;
-  y_im1 = 0;
-
-  while (e_i != 1) {
-
-    e_ip1 = e_im1;
-    d_ip1 = d_im1;
-    c_i = 0;
-
-    while (d_ip1 >= d_i) {
-      c_i ^= (1 << (d_ip1 - d_i));
-      e_ip1 ^= (e_i << (d_ip1 - d_i));
-      d_ip1--;
-      if (e_ip1 == 0) return 0;
-      while ((e_ip1 & (1 << d_ip1)) == 0) d_ip1--;
-    }
-
-    y_ip1 = y_im1 ^ gf->multiply.w32(gf, c_i, y_i);
-    y_im1 = y_i;
-    y_i = y_ip1;
-
-    e_im1 = e_i;
-    d_im1 = d_i;
-    e_i = e_ip1;
-    d_i = d_ip1;
-  }
-
-  return y_i;
-}
-
-static
-gf_val_32_t gf_w32_extract_word(gf_t *gf, void *start, int bytes, int index)
-{
-  uint32_t *r32, rv;
-
-  r32 = (uint32_t *) start;
-  rv = r32[index];
-  return rv;
-}
-
-static
-gf_val_32_t gf_w32_composite_extract_word(gf_t *gf, void *start, int bytes, int index)
-{
-  int sub_size;
-  gf_internal_t *h;
-  uint8_t *r8, *top;
-  uint32_t a, b, *r32;
-  gf_region_data rd;
-
-  h = (gf_internal_t *) gf->scratch;
-  gf_set_region_data(&rd, gf, start, start, bytes, 0, 0, 32);
-  r32 = (uint32_t *) start;
-  if (r32 + index < (uint32_t *) rd.d_start) return r32[index];
-  if (r32 + index >= (uint32_t *) rd.d_top) return r32[index];
-  index -= (((uint32_t *) rd.d_start) - r32);
-  r8 = (uint8_t *) rd.d_start;
-  top = (uint8_t *) rd.d_top;
-  sub_size = (top-r8)/2;
-
-  a = h->base_gf->extract_word.w32(h->base_gf, r8, sub_size, index);
-  b = h->base_gf->extract_word.w32(h->base_gf, r8+sub_size, sub_size, index);
-  return (a | (b << 16));
-}
-
-static
-gf_val_32_t gf_w32_split_extract_word(gf_t *gf, void *start, int bytes, int index)
-{
-  int i;
-  uint32_t *r32, rv;
-  uint8_t *r8;
-  gf_region_data rd;
-
-  gf_set_region_data(&rd, gf, start, start, bytes, 0, 0, 64);
-  r32 = (uint32_t *) start;
-  if (r32 + index < (uint32_t *) rd.d_start) return r32[index];
-  if (r32 + index >= (uint32_t *) rd.d_top) return r32[index];
-  index -= (((uint32_t *) rd.d_start) - r32);
-  r8 = (uint8_t *) rd.d_start;
-  r8 += ((index & 0xfffffff0)*4);
-  r8 += (index & 0xf);
-  r8 += 48;
-  rv =0;
-  for (i = 0; i < 4; i++) {
-    rv <<= 8;
-    rv |= *r8;
-    r8 -= 16;
-  }
-  return rv;
-}
-
-
-static
-inline
-uint32_t gf_w32_matrix (gf_t *gf, uint32_t b)
-{
-  return gf_bitmatrix_inverse(b, 32, ((gf_internal_t *) (gf->scratch))->prim_poly);
-}
-
-/* JSP: GF_MULT_SHIFT: The world's dumbest multiplication algorithm.  I only
-   include it for completeness.  It does have the feature that it requires no
-   extra memory.  
-*/
-
-static
-inline
-gf_val_32_t
-gf_w32_cfmgk_multiply (gf_t *gf, gf_val_32_t a32, gf_val_32_t b32)
-{
-  gf_val_32_t rv = 0;
-
-#if defined(INTEL_SSE4_PCLMUL)
-
-  __m128i         a, b;
-  __m128i         result;
-  __m128i         w;
-  __m128i         g, q;
-  gf_internal_t * h = gf->scratch;
-  uint64_t        g_star, q_plus;
-
-  q_plus = *(uint64_t *) h->private;
-  g_star = *((uint64_t *) h->private + 1);
-
-  a = _mm_insert_epi32 (_mm_setzero_si128(), a32, 0);
-  b = _mm_insert_epi32 (a, b32, 0);
-  g = _mm_insert_epi64 (a, g_star, 0);
-  q = _mm_insert_epi64 (a, q_plus, 0);
-  
-  result = _mm_clmulepi64_si128 (a, b, 0);
-  w = _mm_clmulepi64_si128 (q, _mm_srli_si128 (result, 4), 0);
-  w = _mm_clmulepi64_si128 (g, _mm_srli_si128 (w, 4), 0);
-  result = _mm_xor_si128 (result, w);
-
-  /* Extracts 32 bit value from result. */
-  rv = ((gf_val_32_t)_mm_extract_epi32(result, 0));
-#endif
-  return rv;
-}
-
-#if defined(INTEL_SSE4_PCLMUL)
-
-static 
-void
-gf_w32_cfmgk_multiply_region_from_single(gf_t *gf, void *src, void *dest, uint32_t val, int bytes, int xor)
-{
-
-  uint32_t i;
-  uint32_t *s32;
-  uint32_t *d32;
-  
-  __m128i         a, b;
-  __m128i         result;
-  __m128i         w;
-  __m128i         g, q;
-  gf_internal_t * h = gf->scratch;
-  uint64_t        g_star, q_plus;
-  
-  if (val == 0) { gf_multby_zero(dest, bytes, xor); return; }
-  if (val == 1) { gf_multby_one(src, dest, bytes, xor); return; }
-
-  q_plus = *(uint64_t *) h->private;
-  g_star = *((uint64_t *) h->private + 1);
-
-  g = _mm_insert_epi64 (a, g_star, 0);
-  q = _mm_insert_epi64 (a, q_plus, 0);
-  a = _mm_insert_epi32 (_mm_setzero_si128(), val, 0);
-  s32 = (uint32_t *) src;
-  d32 = (uint32_t *) dest; 
- 
-  if (xor) {
-    for (i = 0; i < bytes/sizeof(uint32_t); i++) {
-      b = _mm_insert_epi32 (a, s32[i], 0);
-      result = _mm_clmulepi64_si128 (a, b, 0);
-      w = _mm_clmulepi64_si128 (q, _mm_srli_si128 (result, 4), 0);
-      w = _mm_clmulepi64_si128 (g, _mm_srli_si128 (w, 4), 0);
-      result = _mm_xor_si128 (result, w);
-      d32[i] ^= ((gf_val_32_t)_mm_extract_epi32(result, 0));
-    } 
-  } else {
-    for (i = 0; i < bytes/sizeof(uint32_t); i++) {
-      b = _mm_insert_epi32 (a, s32[i], 0);
-      result = _mm_clmulepi64_si128 (a, b, 0);
-      w = _mm_clmulepi64_si128 (q, _mm_srli_si128 (result, 4), 0);
-      w = _mm_clmulepi64_si128 (g, _mm_srli_si128 (w, 4), 0);
-      result = _mm_xor_si128 (result, w);
-      d32[i] = ((gf_val_32_t)_mm_extract_epi32(result, 0));
-    } 
-  }
-}
-#endif
-
-
-static
-inline
-gf_val_32_t
-gf_w32_clm_multiply_2 (gf_t *gf, gf_val_32_t a32, gf_val_32_t b32)
-{
-  gf_val_32_t rv = 0;
-
-#if defined(INTEL_SSE4_PCLMUL)
-
-  __m128i         a, b;
-  __m128i         result;
-  __m128i         prim_poly;
-  __m128i         w;
-  gf_internal_t * h = gf->scratch;
-
-
-  a = _mm_insert_epi32 (_mm_setzero_si128(), a32, 0);
-  b = _mm_insert_epi32 (a, b32, 0);
-  
-  prim_poly = _mm_set_epi32(0, 0, 1, (uint32_t)(h->prim_poly & 0xffffffffULL));
-  
-  /* Do the initial multiply */
-
-  result = _mm_clmulepi64_si128 (a, b, 0);
-
-  /* Ben: Do prim_poly reduction twice. We are guaranteed that we will only
-     have to do the reduction at most twice, because (w-2)/z == 2. Where
-     z is equal to the number of zeros after the leading 1 
-
-   _mm_clmulepi64_si128 is the carryless multiply operation. Here
-   _mm_srli_si128 shifts the result to the right by 4 bytes. This allows
-   us to multiply the prim_poly by the leading bits of the result. We
-   then xor the result of that operation back with the result.*/
-
-  w = _mm_clmulepi64_si128 (prim_poly, _mm_srli_si128 (result, 4), 0);
-  result = _mm_xor_si128 (result, w);
-  w = _mm_clmulepi64_si128 (prim_poly, _mm_srli_si128 (result, 4), 0);
-  result = _mm_xor_si128 (result, w);
-
-  /* Extracts 32 bit value from result. */
-  rv = ((gf_val_32_t)_mm_extract_epi32(result, 0));
-#endif
-  return rv;
-}
-
-static
-inline
-gf_val_32_t
-gf_w32_clm_multiply_3 (gf_t *gf, gf_val_32_t a32, gf_val_32_t b32)
-{
-  gf_val_32_t rv = 0;
-
-#if defined(INTEL_SSE4_PCLMUL)
-
-  __m128i         a, b;
-  __m128i         result;
-  __m128i         prim_poly;
-  __m128i         w;
-  gf_internal_t * h = gf->scratch;
-
-
-  a = _mm_insert_epi32 (_mm_setzero_si128(), a32, 0);
-  b = _mm_insert_epi32 (a, b32, 0);
-
-  prim_poly = _mm_set_epi32(0, 0, 1, (uint32_t)(h->prim_poly & 0xffffffffULL));
-
-  /* Do the initial multiply */
-  
-  result = _mm_clmulepi64_si128 (a, b, 0);
-
-  w = _mm_clmulepi64_si128 (prim_poly, _mm_srli_si128 (result, 4), 0);
-  result = _mm_xor_si128 (result, w);
-  w = _mm_clmulepi64_si128 (prim_poly, _mm_srli_si128 (result, 4), 0);
-  result = _mm_xor_si128 (result, w);
-  w = _mm_clmulepi64_si128 (prim_poly, _mm_srli_si128 (result, 4), 0);
-  result = _mm_xor_si128 (result, w);
-
-  /* Extracts 32 bit value from result. */
-  
-  rv = ((gf_val_32_t)_mm_extract_epi32(result, 0));
-#endif
-  return rv;
-}
-
-static
-inline
-gf_val_32_t
-gf_w32_clm_multiply_4 (gf_t *gf, gf_val_32_t a32, gf_val_32_t b32)
-{
-  gf_val_32_t rv = 0;
-
-#if defined(INTEL_SSE4_PCLMUL)
-
-  __m128i         a, b;
-  __m128i         result;
-  __m128i         prim_poly;
-  __m128i         w;
-  gf_internal_t * h = gf->scratch;
-
-
-  a = _mm_insert_epi32 (_mm_setzero_si128(), a32, 0);
-  b = _mm_insert_epi32 (a, b32, 0);
-
-  prim_poly = _mm_set_epi32(0, 0, 1, (uint32_t)(h->prim_poly & 0xffffffffULL));
-
-  /* Do the initial multiply */
-  
-  result = _mm_clmulepi64_si128 (a, b, 0);
-
-  w = _mm_clmulepi64_si128 (prim_poly, _mm_srli_si128 (result, 4), 0);
-  result = _mm_xor_si128 (result, w);
-  w = _mm_clmulepi64_si128 (prim_poly, _mm_srli_si128 (result, 4), 0);
-  result = _mm_xor_si128 (result, w);
-  w = _mm_clmulepi64_si128 (prim_poly, _mm_srli_si128 (result, 4), 0);
-  result = _mm_xor_si128 (result, w);
-  w = _mm_clmulepi64_si128 (prim_poly, _mm_srli_si128 (result, 4), 0);
-  result = _mm_xor_si128 (result, w);
-
-  /* Extracts 32 bit value from result. */
-  
-  rv = ((gf_val_32_t)_mm_extract_epi32(result, 0));
-#endif
-  return rv;
-}
-
-
-static
-inline
-uint32_t
-gf_w32_shift_multiply (gf_t *gf, uint32_t a32, uint32_t b32)
-{
-  uint64_t product, i, pp, a, b, one;
-  gf_internal_t *h;
-
-  a = a32;
-  b = b32;
-  h = (gf_internal_t *) gf->scratch;
-  one = 1;
-  pp = h->prim_poly | (one << 32);
-
-  product = 0;
-
-  for (i = 0; i < GF_FIELD_WIDTH; i++) { 
-    if (a & (one << i)) product ^= (b << i);
-  }
-  for (i = (GF_FIELD_WIDTH*2-2); i >= GF_FIELD_WIDTH; i--) {
-    if (product & (one << i)) product ^= (pp << (i-GF_FIELD_WIDTH)); 
-  }
-  return product;
-}
-
-  static 
-int gf_w32_cfmgk_init(gf_t *gf)
-{
-  gf->inverse.w32 = gf_w32_euclid;
-  gf->multiply_region.w32 = gf_w32_multiply_region_from_single;
-  
-#if defined(INTEL_SSE4_PCLMUL)
-  gf_internal_t *h;
-
-  h = (gf_internal_t *) gf->scratch;
-  gf->multiply.w32 = gf_w32_cfmgk_multiply;
-  gf->multiply_region.w32 = gf_w32_cfmgk_multiply_region_from_single;
-
-  uint64_t *q_plus = (uint64_t *) h->private;
-  uint64_t *g_star = (uint64_t *) h->private + 1;
-
-  uint64_t tmp = h->prim_poly << 32;
-  *q_plus = 1ULL << 32;
-
-  int i;
-  for(i = 63; i >= 32; i--)
-    if((1ULL << i) & tmp)
-    {
-      *q_plus |= 1ULL << (i-32);
-      tmp ^= h->prim_poly << (i-32);
-    }
-
-  *g_star = h->prim_poly & ((1ULL << 32) - 1);
-
-  return 1;
-#endif
-
-  return 0;
-}
-
-  static 
-int gf_w32_cfm_init(gf_t *gf)
-{
-  gf->inverse.w32 = gf_w32_euclid;
-  gf->multiply_region.w32 = gf_w32_multiply_region_from_single;
-  
-  /*Ben: We also check to see if the prim poly will work for pclmul */
-  /*Ben: Check to see how many reduction steps it will take*/
-
-#if defined(INTEL_SSE4_PCLMUL)
-  gf_internal_t *h;
-
-  h = (gf_internal_t *) gf->scratch;
-
-  if ((0xfffe0000 & h->prim_poly) == 0){ 
-    gf->multiply.w32 = gf_w32_clm_multiply_2;
-    gf->multiply_region.w32 = gf_w32_clm_multiply_region_from_single_2;
-  }else if ((0xffc00000 & h->prim_poly) == 0){
-    gf->multiply.w32 = gf_w32_clm_multiply_3;
-    gf->multiply_region.w32 = gf_w32_clm_multiply_region_from_single_3;
-  }else if ((0xfe000000 & h->prim_poly) == 0){
-    gf->multiply.w32 = gf_w32_clm_multiply_4;
-    gf->multiply_region.w32 = gf_w32_clm_multiply_region_from_single_4;
-  } else {
-    return 0;
-  }
-  return 1;
-  #endif
-
-  return 0;
-}
-
-  static 
-int gf_w32_shift_init(gf_t *gf)
-{
-  gf->inverse.w32 = gf_w32_euclid;
-  gf->multiply_region.w32 = gf_w32_multiply_region_from_single;
-  gf->multiply.w32 = gf_w32_shift_multiply;
-  return 1;
-}
-
-static
-  void
-gf_w32_group_set_shift_tables(uint32_t *shift, uint32_t val, gf_internal_t *h)
-{
-  uint32_t i;
-  uint32_t j;
-
-  shift[0] = 0;
-
-  for (i = 1; i < ((uint32_t)1 << h->arg1); i <<= 1) {
-    for (j = 0; j < i; j++) shift[i|j] = shift[j]^val;
-    if (val & GF_FIRST_BIT) {
-      val <<= 1;
-      val ^= h->prim_poly;
-    } else {
-      val <<= 1;
-    }
-  }
-}
-
-  static
-void gf_w32_group_s_equals_r_multiply_region(gf_t *gf, void *src, void *dest, gf_val_32_t val, int bytes, int xor)
-{
-  int leftover, rs;
-  uint32_t p, l, ind, a32;
-  int bits_left;
-  int g_s;
-  gf_region_data rd;
-  uint32_t *s32, *d32, *top;
-  struct gf_w32_group_data *gd;
-  gf_internal_t *h = (gf_internal_t *) gf->scratch;
-
-  if (val == 0) { gf_multby_zero(dest, bytes, xor); return; }
-  if (val == 1) { gf_multby_one(src, dest, bytes, xor); return; }
-
-  gd = (struct gf_w32_group_data *) h->private;
-  g_s = h->arg1;
-  gf_w32_group_set_shift_tables(gd->shift, val, h);
-
-  gf_set_region_data(&rd, gf, src, dest, bytes, val, xor, 4);
-  gf_do_initial_region_alignment(&rd);
-
-  s32 = (uint32_t *) rd.s_start;
-  d32 = (uint32_t *) rd.d_start;
-  top = (uint32_t *) rd.d_top;
-
-  leftover = 32 % g_s;
-  if (leftover == 0) leftover = g_s;
-
-  while (d32 < top) {
-    rs = 32 - leftover;
-    a32 = *s32;
-    ind = a32 >> rs;
-    a32 <<= leftover;
-    p = gd->shift[ind];
-
-    bits_left = rs;
-    rs = 32 - g_s;
-
-    while (bits_left > 0) {
-      bits_left -= g_s;
-      ind = a32 >> rs;
-      a32 <<= g_s;
-      l = p >> rs;
-      p = (gd->shift[ind] ^ gd->reduce[l] ^ (p << g_s));
-    }
-    if (xor) p ^= *d32;
-    *d32 = p;
-    d32++;
-    s32++;
-  }
-  gf_do_final_region_alignment(&rd);
-}
-
-  static
-void gf_w32_group_multiply_region(gf_t *gf, void *src, void *dest, gf_val_32_t val, int bytes, int xor)
-{
-  uint32_t *s32, *d32, *top;
-  int i;
-  int leftover;
-  uint64_t p, l, r;
-  uint32_t a32, ind;
-  int g_s, g_r;
-  struct gf_w32_group_data *gd;
-  gf_region_data rd;
-
-  if (val == 0) { gf_multby_zero(dest, bytes, xor); return; }
-  if (val == 1) { gf_multby_one(src, dest, bytes, xor); return; }
-
-  gf_internal_t *h = (gf_internal_t *) gf->scratch;
-  g_s = h->arg1;
-  g_r = h->arg2;
-  gd = (struct gf_w32_group_data *) h->private;
-  gf_w32_group_set_shift_tables(gd->shift, val, h);
-
-  leftover = GF_FIELD_WIDTH % g_s;
-  if (leftover == 0) leftover = g_s;
-
-  gd = (struct gf_w32_group_data *) h->private;
-  gf_w32_group_set_shift_tables(gd->shift, val, h);
-
-  gf_set_region_data(&rd, gf, src, dest, bytes, val, xor, 4);
-  gf_do_initial_region_alignment(&rd);
-
-  s32 = (uint32_t *) rd.s_start;
-  d32 = (uint32_t *) rd.d_start;
-  top = (uint32_t *) rd.d_top;
-
-  while (d32 < top) {
-    a32 = *s32;
-    ind = a32 >> (GF_FIELD_WIDTH - leftover);
-    p = gd->shift[ind];
-    p <<= g_s;
-    a32 <<= leftover;
-  
-    i = (GF_FIELD_WIDTH - leftover);
-    while (i > g_s) {
-      ind = a32 >> (GF_FIELD_WIDTH-g_s);
-      p ^= gd->shift[ind];
-      a32 <<= g_s;
-      p <<= g_s;
-      i -= g_s;
-    }
-  
-    ind = a32 >> (GF_FIELD_WIDTH-g_s);
-    p ^= gd->shift[ind];
-  
-    for (i = gd->tshift ; i >= 0; i -= g_r) {
-      l = p & (gd->rmask << i);
-      r = gd->reduce[l >> (i+32)];
-      r <<= (i);
-      p ^= r;
-    }
-
-    if (xor) p ^= *d32;
-    *d32 = p;
-    d32++;
-    s32++;
-  }
-  gf_do_final_region_alignment(&rd);
-}
-
-static
-inline
-gf_val_32_t
-gf_w32_group_s_equals_r_multiply(gf_t *gf, gf_val_32_t a, gf_val_32_t b)
-{
-  int leftover, rs;
-  uint32_t p, l, ind, a32;
-  int bits_left;
-  int g_s;
-
-  struct gf_w32_group_data *gd;
-  gf_internal_t *h = (gf_internal_t *) gf->scratch;
-  g_s = h->arg1;
-
-  gd = (struct gf_w32_group_data *) h->private;
-  gf_w32_group_set_shift_tables(gd->shift, b, h);
-
-  leftover = 32 % g_s;
-  if (leftover == 0) leftover = g_s;
-
-  rs = 32 - leftover;
-  a32 = a;
-  ind = a32 >> rs;
-  a32 <<= leftover;
-  p = gd->shift[ind];
-
-  bits_left = rs;
-  rs = 32 - g_s;
-
-  while (bits_left > 0) {
-    bits_left -= g_s;
-    ind = a32 >> rs;
-    a32 <<= g_s;
-    l = p >> rs;
-    p = (gd->shift[ind] ^ gd->reduce[l] ^ (p << g_s));
-  }
-  return p;
-}
-
-static
-inline
-gf_val_32_t
-gf_w32_group_4_4_multiply(gf_t *gf, gf_val_32_t a, gf_val_32_t b)
-{
-  uint32_t p, l, ind, a32;
-
-  struct gf_w32_group_data *d44;
-  gf_internal_t *h = (gf_internal_t *) gf->scratch;
-
-  d44 = (struct gf_w32_group_data *) h->private;
-  gf_w32_group_set_shift_tables(d44->shift, b, h);
-
-  a32 = a;
-  ind = a32 >> 28;
-  a32 <<= 4;
-  p = d44->shift[ind];
-  ind = a32 >> 28;
-  a32 <<= 4;
-  l = p >> 28;
-  p = (d44->shift[ind] ^ d44->reduce[l] ^ (p << 4));
-  ind = a32 >> 28;
-  a32 <<= 4;
-  l = p >> 28;
-  p = (d44->shift[ind] ^ d44->reduce[l] ^ (p << 4));
-  ind = a32 >> 28;
-  a32 <<= 4;
-  l = p >> 28;
-  p = (d44->shift[ind] ^ d44->reduce[l] ^ (p << 4));
-  ind = a32 >> 28;
-  a32 <<= 4;
-  l = p >> 28;
-  p = (d44->shift[ind] ^ d44->reduce[l] ^ (p << 4));
-  ind = a32 >> 28;
-  a32 <<= 4;
-  l = p >> 28;
-  p = (d44->shift[ind] ^ d44->reduce[l] ^ (p << 4));
-  ind = a32 >> 28;
-  a32 <<= 4;
-  l = p >> 28;
-  p = (d44->shift[ind] ^ d44->reduce[l] ^ (p << 4));
-  ind = a32 >> 28;
-  l = p >> 28;
-  p = (d44->shift[ind] ^ d44->reduce[l] ^ (p << 4));
-  return p;
-}
-
-static
-inline
-gf_val_32_t
-gf_w32_group_multiply(gf_t *gf, gf_val_32_t a, gf_val_32_t b)
-{
-  int i;
-  int leftover;
-  uint64_t p, l, r;
-  uint32_t a32, ind;
-  int g_s, g_r;
-  struct gf_w32_group_data *gd;
-
-  gf_internal_t *h = (gf_internal_t *) gf->scratch;
-  g_s = h->arg1;
-  g_r = h->arg2;
-  gd = (struct gf_w32_group_data *) h->private;
-  gf_w32_group_set_shift_tables(gd->shift, b, h);
-
-  leftover = GF_FIELD_WIDTH % g_s;
-  if (leftover == 0) leftover = g_s;
-
-  a32 = a;
-  ind = a32 >> (GF_FIELD_WIDTH - leftover);
-  p = gd->shift[ind];
-  p <<= g_s;
-  a32 <<= leftover;
-
-  i = (GF_FIELD_WIDTH - leftover);
-  while (i > g_s) {
-    ind = a32 >> (GF_FIELD_WIDTH-g_s);
-    p ^= gd->shift[ind];
-    a32 <<= g_s;
-    p <<= g_s;
-    i -= g_s;
-  }
-
-  ind = a32 >> (GF_FIELD_WIDTH-g_s);
-  p ^= gd->shift[ind];
-
-  for (i = gd->tshift ; i >= 0; i -= g_r) {
-    l = p & (gd->rmask << i);
-    r = gd->reduce[l >> (i+32)];
-    r <<= (i);
-    p ^= r;
-  }
-  return p;
-}
-
-static
-inline
-gf_val_32_t
-gf_w32_bytwo_b_multiply (gf_t *gf, gf_val_32_t a, gf_val_32_t b)
-{
-  uint32_t prod, pp, bmask;
-  gf_internal_t *h;
-
-  h = (gf_internal_t *) gf->scratch;
-  pp = h->prim_poly;
-
-  prod = 0;
-  bmask = 0x80000000;
-
-  while (1) {
-    if (a & 1) prod ^= b;
-    a >>= 1;
-    if (a == 0) return prod;
-    if (b & bmask) {
-      b = ((b << 1) ^ pp);
-    } else {
-      b <<= 1;
-    }
-  }
-}
-
-static
-inline
-gf_val_32_t
-gf_w32_bytwo_p_multiply (gf_t *gf, gf_val_32_t a, gf_val_32_t b)
-{
-  uint32_t prod, pp, pmask, amask;
-  gf_internal_t *h;
-
-  h = (gf_internal_t *) gf->scratch;
-  pp = h->prim_poly;
-
-
-  prod = 0;
-  pmask = 0x80000000;
-  amask = 0x80000000;
-
-  while (amask != 0) {
-    if (prod & pmask) {
-      prod = ((prod << 1) ^ pp);
-    } else {
-      prod <<= 1;
-    }
-    if (a & amask) prod ^= b;
-    amask >>= 1;
-  }
-  return prod;
-}
-
-static
-void
-gf_w32_bytwo_p_nosse_multiply_region(gf_t *gf, void *src, void *dest, gf_val_32_t val, int bytes, int xor)
-{
-  uint64_t *s64, *d64, t1, t2, ta, prod, amask;
-  gf_region_data rd;
-  struct gf_w32_bytwo_data *btd;
-
-  if (val == 0) { gf_multby_zero(dest, bytes, xor); return; }
-  if (val == 1) { gf_multby_one(src, dest, bytes, xor); return; }
-
-  btd = (struct gf_w32_bytwo_data *) ((gf_internal_t *) (gf->scratch))->private;
-
-  gf_set_region_data(&rd, gf, src, dest, bytes, val, xor, 8);
-  gf_do_initial_region_alignment(&rd);
-
-  s64 = (uint64_t *) rd.s_start;
-  d64 = (uint64_t *) rd.d_start;
-
-  if (xor) {
-    while (s64 < (uint64_t *) rd.s_top) {
-      prod = 0;
-      amask = 0x80000000;
-      ta = *s64;
-      while (amask != 0) {
-        AB2(btd->prim_poly, btd->mask1, btd->mask2, prod, t1, t2);
-        if (val & amask) prod ^= ta;
-        amask >>= 1;
-      }
-      *d64 ^= prod;
-      d64++;
-      s64++;
-    }
-  } else {
-    while (s64 < (uint64_t *) rd.s_top) {
-      prod = 0;
-      amask = 0x80000000;
-      ta = *s64;
-      while (amask != 0) {
-        AB2(btd->prim_poly, btd->mask1, btd->mask2, prod, t1, t2);
-        if (val & amask) prod ^= ta;
-        amask >>= 1;
-      }
-      *d64 = prod;
-      d64++;
-      s64++;
-    }
-  }
-  gf_do_final_region_alignment(&rd);
-}
-
-#define BYTWO_P_ONESTEP {\
-      SSE_AB2(pp, m1 ,m2, prod, t1, t2); \
-      t1 = _mm_and_si128(v, one); \
-      t1 = _mm_sub_epi32(t1, one); \
-      t1 = _mm_and_si128(t1, ta); \
-      prod = _mm_xor_si128(prod, t1); \
-      v = _mm_srli_epi64(v, 1); }
-
-#ifdef INTEL_SSE2
-static
-void
-gf_w32_bytwo_p_sse_multiply_region(gf_t *gf, void *src, void *dest, gf_val_32_t val, int bytes, int xor)
-{
-  int i;
-  uint8_t *s8, *d8;
-  uint32_t vrev;
-  __m128i pp, m1, m2, ta, prod, t1, t2, tp, one, v;
-  struct gf_w32_bytwo_data *btd;
-  gf_region_data rd;
-   
-  if (val == 0) { gf_multby_zero(dest, bytes, xor); return; }
-  if (val == 1) { gf_multby_one(src, dest, bytes, xor); return; }
-
-  btd = (struct gf_w32_bytwo_data *) ((gf_internal_t *) (gf->scratch))->private;
-
-  gf_set_region_data(&rd, gf, src, dest, bytes, val, xor, 16);
-  gf_do_initial_region_alignment(&rd);
-
-  vrev = 0;
-  for (i = 0; i < 32; i++) {
-    vrev <<= 1;
-    if (!(val & (1 << i))) vrev |= 1;
-  }
-
-  s8 = (uint8_t *) rd.s_start;
-  d8 = (uint8_t *) rd.d_start;
-
-  pp = _mm_set1_epi32(btd->prim_poly&0xffffffff);
-  m1 = _mm_set1_epi32((btd->mask1)&0xffffffff);
-  m2 = _mm_set1_epi32((btd->mask2)&0xffffffff);
-  one = _mm_set1_epi32(1);
-
-  while (d8 < (uint8_t *) rd.d_top) {
-    prod = _mm_setzero_si128();
-    v = _mm_set1_epi32(vrev);
-    ta = _mm_load_si128((__m128i *) s8);
-    tp = (!xor) ? _mm_setzero_si128() : _mm_load_si128((__m128i *) d8);
-    BYTWO_P_ONESTEP; BYTWO_P_ONESTEP; BYTWO_P_ONESTEP; BYTWO_P_ONESTEP;
-    BYTWO_P_ONESTEP; BYTWO_P_ONESTEP; BYTWO_P_ONESTEP; BYTWO_P_ONESTEP;
-    BYTWO_P_ONESTEP; BYTWO_P_ONESTEP; BYTWO_P_ONESTEP; BYTWO_P_ONESTEP;
-    BYTWO_P_ONESTEP; BYTWO_P_ONESTEP; BYTWO_P_ONESTEP; BYTWO_P_ONESTEP;
-    BYTWO_P_ONESTEP; BYTWO_P_ONESTEP; BYTWO_P_ONESTEP; BYTWO_P_ONESTEP;
-    BYTWO_P_ONESTEP; BYTWO_P_ONESTEP; BYTWO_P_ONESTEP; BYTWO_P_ONESTEP;
-    BYTWO_P_ONESTEP; BYTWO_P_ONESTEP; BYTWO_P_ONESTEP; BYTWO_P_ONESTEP;
-    BYTWO_P_ONESTEP; BYTWO_P_ONESTEP; BYTWO_P_ONESTEP; BYTWO_P_ONESTEP;
-    _mm_store_si128((__m128i *) d8, _mm_xor_si128(prod, tp));
-    d8 += 16;
-    s8 += 16;
-  }
-  gf_do_final_region_alignment(&rd);
-}
-#endif
-
-static
-void
-gf_w32_bytwo_b_nosse_multiply_region(gf_t *gf, void *src, void *dest, gf_val_32_t val, int bytes, int xor)
-{
-  uint64_t *s64, *d64, t1, t2, ta, tb, prod;
-  struct gf_w32_bytwo_data *btd;
-  gf_region_data rd;
-
-  if (val == 0) { gf_multby_zero(dest, bytes, xor); return; }
-  if (val == 1) { gf_multby_one(src, dest, bytes, xor); return; }
-
-  gf_set_region_data(&rd, gf, src, dest, bytes, val, xor, 32);
-  gf_do_initial_region_alignment(&rd);
-
-  btd = (struct gf_w32_bytwo_data *) ((gf_internal_t *) (gf->scratch))->private;
-  s64 = (uint64_t *) rd.s_start;
-  d64 = (uint64_t *) rd.d_start;
-
-  switch (val) {
-  case 2:
-    if (xor) {
-      while (d64 < (uint64_t *) rd.d_top) {
-        ta = *s64;
-        AB2(btd->prim_poly, btd->mask1, btd->mask2, ta, t1, t2);
-        *d64 ^= ta;
-        d64++;
-        s64++;
-      }
-    } else {
-      while (d64 < (uint64_t *) rd.d_top) {
-        ta = *s64;
-        AB2(btd->prim_poly, btd->mask1, btd->mask2, ta, t1, t2);
-        *d64 = ta;
-        d64++;
-        s64++;
-      }
-    }
-    break;
-  case 3:
-    if (xor) {
-      while (d64 < (uint64_t *) rd.d_top) {
-        ta = *s64;
-        prod = ta;
-        AB2(btd->prim_poly, btd->mask1, btd->mask2, ta, t1, t2);
-        *d64 ^= (ta ^ prod);
-        d64++;
-        s64++;
-      }
-    } else {
-      while (d64 < (uint64_t *) rd.d_top) {
-        ta = *s64;
-        prod = ta;
-        AB2(btd->prim_poly, btd->mask1, btd->mask2, ta, t1, t2);
-        *d64 = (ta ^ prod);
-        d64++;
-        s64++;
-      }
-    }
-    break;
-  case 4:
-    if (xor) {
-      while (d64 < (uint64_t *) rd.d_top) {
-        ta = *s64;
-        AB2(btd->prim_poly, btd->mask1, btd->mask2, ta, t1, t2);
-        AB2(btd->prim_poly, btd->mask1, btd->mask2, ta, t1, t2);
-        *d64 ^= ta;
-        d64++;
-        s64++;
-      }
-    } else {
-      while (d64 < (uint64_t *) rd.d_top) {
-        ta = *s64;
-        AB2(btd->prim_poly, btd->mask1, btd->mask2, ta, t1, t2);
-        AB2(btd->prim_poly, btd->mask1, btd->mask2, ta, t1, t2);
-        *d64 = ta;
-        d64++;
-        s64++;
-      }
-    }
-    break;
-  case 5:
-    if (xor) {
-      while (d64 < (uint64_t *) rd.d_top) {
-        ta = *s64;
-        prod = ta;
-        AB2(btd->prim_poly, btd->mask1, btd->mask2, ta, t1, t2);
-        AB2(btd->prim_poly, btd->mask1, btd->mask2, ta, t1, t2);
-        *d64 ^= (ta ^ prod);
-        d64++;
-        s64++;
-      }
-    } else {
-      while (d64 < (uint64_t *) rd.d_top) {
-        ta = *s64;
-        prod = ta;
-        AB2(btd->prim_poly, btd->mask1, btd->mask2, ta, t1, t2);
-        AB2(btd->prim_poly, btd->mask1, btd->mask2, ta, t1, t2);
-        *d64 = ta ^ prod;
-        d64++;
-        s64++;
-      }
-    }
-    break;
-  default:
-    if (xor) {
-      while (d64 < (uint64_t *) rd.d_top) {
-        prod = *d64 ;
-        ta = *s64;
-        tb = val;
-        while (1) {
-          if (tb & 1) prod ^= ta;
-          tb >>= 1;
-          if (tb == 0) break;
-          AB2(btd->prim_poly, btd->mask1, btd->mask2, ta, t1, t2);
-        }
-        *d64 = prod;
-        d64++;
-        s64++;
-      }
-    } else {
-      while (d64 < (uint64_t *) rd.d_top) {
-        prod = 0 ;
-        ta = *s64;
-        tb = val;
-        while (1) {
-          if (tb & 1) prod ^= ta;
-          tb >>= 1;
-          if (tb == 0) break;
-          AB2(btd->prim_poly, btd->mask1, btd->mask2, ta, t1, t2);
-        }
-        *d64 = prod;
-        d64++;
-        s64++;
-      }
-    }
-    break;
-  }
-  gf_do_final_region_alignment(&rd);
-}
-
-#ifdef INTEL_SSE2
-static
-void
-gf_w32_bytwo_b_sse_region_2_noxor(gf_region_data *rd, struct gf_w32_bytwo_data *btd)
-{
-  uint8_t *d8, *s8;
-  __m128i pp, m1, m2, t1, t2, va;
-
-  s8 = (uint8_t *) rd->s_start;
-  d8 = (uint8_t *) rd->d_start;
-
-  pp = _mm_set1_epi32(btd->prim_poly&0xffffffff);
-  m1 = _mm_set1_epi32((btd->mask1)&0xffffffff);
-  m2 = _mm_set1_epi32((btd->mask2)&0xffffffff);
-
-  while (d8 < (uint8_t *) rd->d_top) {
-    va = _mm_load_si128 ((__m128i *)(s8));
-    SSE_AB2(pp, m1, m2, va, t1, t2);
-    _mm_store_si128((__m128i *)d8, va);
-    d8 += 16;
-    s8 += 16;
-  }
-}
-#endif
-
-#ifdef INTEL_SSE2
-static
-void
-gf_w32_bytwo_b_sse_region_2_xor(gf_region_data *rd, struct gf_w32_bytwo_data *btd)
-{
-  uint8_t *d8, *s8;
-  __m128i pp, m1, m2, t1, t2, va, vb;
-
-  s8 = (uint8_t *) rd->s_start;
-  d8 = (uint8_t *) rd->d_start;
-
-  pp = _mm_set1_epi32(btd->prim_poly&0xffffffff);
-  m1 = _mm_set1_epi32((btd->mask1)&0xffffffff);
-  m2 = _mm_set1_epi32((btd->mask2)&0xffffffff);
-
-  while (d8 < (uint8_t *) rd->d_top) {
-    va = _mm_load_si128 ((__m128i *)(s8));
-    SSE_AB2(pp, m1, m2, va, t1, t2);
-    vb = _mm_load_si128 ((__m128i *)(d8));
-    vb = _mm_xor_si128(vb, va);
-    _mm_store_si128((__m128i *)d8, vb);
-    d8 += 16;
-    s8 += 16;
-  }
-}
-#endif
-
-
-#ifdef INTEL_SSE2
-static
-void 
-gf_w32_bytwo_b_sse_multiply_region(gf_t *gf, void *src, void *dest, gf_val_32_t val, int bytes, int xor)
-{
-  uint32_t itb;
-  uint8_t *d8, *s8;
-  __m128i pp, m1, m2, t1, t2, va, vb;
-  struct gf_w32_bytwo_data *btd;
-  gf_region_data rd;
-    
-  if (val == 0) { gf_multby_zero(dest, bytes, xor); return; }
-  if (val == 1) { gf_multby_one(src, dest, bytes, xor); return; }
-
-  gf_set_region_data(&rd, gf, src, dest, bytes, val, xor, 16);
-  gf_do_initial_region_alignment(&rd);
-
-  btd = (struct gf_w32_bytwo_data *) ((gf_internal_t *) (gf->scratch))->private;
-
-  if (val == 2) {
-    if (xor) {
-      gf_w32_bytwo_b_sse_region_2_xor(&rd, btd);
-    } else {
-      gf_w32_bytwo_b_sse_region_2_noxor(&rd, btd);
-    }
-    gf_do_final_region_alignment(&rd);
-    return;
-  }
-
-  s8 = (uint8_t *) rd.s_start;
-  d8 = (uint8_t *) rd.d_start;
-
-  pp = _mm_set1_epi32(btd->prim_poly&0xffffffff);
-  m1 = _mm_set1_epi32((btd->mask1)&0xffffffff);
-  m2 = _mm_set1_epi32((btd->mask2)&0xffffffff);
-
-  while (d8 < (uint8_t *) rd.d_top) {
-    va = _mm_load_si128 ((__m128i *)(s8));
-    vb = (!xor) ? _mm_setzero_si128() : _mm_load_si128 ((__m128i *)(d8));
-    itb = val;
-    while (1) {
-      if (itb & 1) vb = _mm_xor_si128(vb, va);
-      itb >>= 1;
-      if (itb == 0) break;
-      SSE_AB2(pp, m1, m2, va, t1, t2);
-    }
-    _mm_store_si128((__m128i *)d8, vb);
-    d8 += 16;
-    s8 += 16;
-  }
-
-  gf_do_final_region_alignment(&rd);
-}
-#endif
-
-static
-int gf_w32_bytwo_init(gf_t *gf)
-{
-  gf_internal_t *h;
-  uint64_t ip, m1, m2;
-  struct gf_w32_bytwo_data *btd;
-
-  h = (gf_internal_t *) gf->scratch;
-  btd = (struct gf_w32_bytwo_data *) (h->private);
-  ip = h->prim_poly & 0xffffffff;
-  m1 = 0xfffffffe;
-  m2 = 0x80000000;
-  btd->prim_poly = 0;
-  btd->mask1 = 0;
-  btd->mask2 = 0;
-
-  while (ip != 0) {
-    btd->prim_poly |= ip;
-    btd->mask1 |= m1;
-    btd->mask2 |= m2;
-    ip <<= GF_FIELD_WIDTH;
-    m1 <<= GF_FIELD_WIDTH;
-    m2 <<= GF_FIELD_WIDTH;
-  }
-
-  if (h->mult_type == GF_MULT_BYTWO_p) {
-    gf->multiply.w32 = gf_w32_bytwo_p_multiply;
-    #ifdef INTEL_SSE2
-      if (h->region_type & GF_REGION_NOSIMD)
-        gf->multiply_region.w32 = gf_w32_bytwo_p_nosse_multiply_region; 
-      else
-        gf->multiply_region.w32 = gf_w32_bytwo_p_sse_multiply_region; 
-    #else
-      gf->multiply_region.w32 = gf_w32_bytwo_p_nosse_multiply_region; 
-      if(h->region_type & GF_REGION_SIMD)
-        return 0;
-    #endif
-  } else {
-    gf->multiply.w32 = gf_w32_bytwo_b_multiply; 
-    #ifdef INTEL_SSE2
-      if (h->region_type & GF_REGION_NOSIMD)
-        gf->multiply_region.w32 = gf_w32_bytwo_b_nosse_multiply_region; 
-      else
-        gf->multiply_region.w32 = gf_w32_bytwo_b_sse_multiply_region; 
-    #else
-      gf->multiply_region.w32 = gf_w32_bytwo_b_nosse_multiply_region; 
-      if(h->region_type & GF_REGION_SIMD)
-        return 0;
-    #endif
-  }
-
-  gf->inverse.w32 = gf_w32_euclid;
-  return 1;
-}
-
-static
-inline
-uint32_t
-gf_w32_split_8_8_multiply (gf_t *gf, uint32_t a32, uint32_t b32)
-{
-  uint32_t product, i, j, mask, tb;
-  gf_internal_t *h;
-  struct gf_w32_split_8_8_data *d8;
-  
-  h = (gf_internal_t *) gf->scratch;
-  d8 = (struct gf_w32_split_8_8_data *) h->private;
-  product = 0;
-  mask = 0xff;
-
-  for (i = 0; i < 4; i++) {
-    tb = b32;
-    for (j = 0; j < 4; j++) {
-      product ^= d8->tables[i+j][a32&mask][tb&mask];
-      tb >>= 8;
-    }
-    a32 >>= 8;
-  }
-  return product;
-}
-
-static
-inline
-void
-gf_w32_split_8_32_lazy_multiply_region(gf_t *gf, void *src, void *dest, uint32_t val, int bytes, int xor)
-{
-  gf_internal_t *h;
-  uint32_t *s32, *d32, *top, p, a, v;
-  struct gf_split_8_32_lazy_data *d8;
-  struct gf_w32_split_8_8_data *d88;
-  uint32_t *t[4];
-  int i, j, k, change;
-  uint32_t pp;
-  gf_region_data rd;
-  
-  if (val == 0) { gf_multby_zero(dest, bytes, xor); return; }
-  if (val == 1) { gf_multby_one(src, dest, bytes, xor); return; }
-
-  h = (gf_internal_t *) gf->scratch;
-  if (h->arg1 == 32 || h->arg2 == 32 || h->mult_type == GF_MULT_DEFAULT) {
-    d8 = (struct gf_split_8_32_lazy_data *) h->private;
-    for (i = 0; i < 4; i++) t[i] = d8->tables[i];
-    change = (val != d8->last_value);
-    if (change) d8->last_value = val;
-  } else {
-    d88 = (struct gf_w32_split_8_8_data *) h->private;
-    for (i = 0; i < 4; i++) t[i] = d88->region_tables[i];
-    change = (val != d88->last_value);
-    if (change) d88->last_value = val;
-  }
-  pp = h->prim_poly;
-
-  gf_set_region_data(&rd, gf, src, dest, bytes, val, xor, 4);
-  gf_do_initial_region_alignment(&rd);
-
-  s32 = (uint32_t *) rd.s_start;
-  d32 = (uint32_t *) rd.d_start;
-  top = (uint32_t *) rd.d_top;
-  
-  if (change) {
-    v = val;
-    for (i = 0; i < 4; i++) {
-      t[i][0] = 0;
-      for (j = 1; j < 256; j <<= 1) {
-        for (k = 0; k < j; k++) {
-          t[i][k^j] = (v ^ t[i][k]);
-        }
-        v = (v & GF_FIRST_BIT) ? ((v << 1) ^ pp) : (v << 1);
-      }
-    }
-  } 
-
-  while (d32 < top) {
-    p = (xor) ? *d32 : 0;
-    a = *s32;
-    i = 0;
-    while (a != 0) {
-      v = (a & 0xff);
-      p ^= t[i][v];
-      a >>= 8;
-      i++;
-    }
-    *d32 = p;
-    d32++;
-    s32++;
-  }
-  gf_do_final_region_alignment(&rd);
-}
-
-static
-inline
-void
-gf_w32_split_16_32_lazy_multiply_region(gf_t *gf, void *src, void *dest, uint32_t val, int bytes, int xor)
-{
-  gf_internal_t *h;
-  uint32_t *s32, *d32, *top, p, a, v;
-  struct gf_split_16_32_lazy_data *d16;
-  uint32_t *t[2];
-  int i, j, k, change;
-  uint32_t pp;
-  gf_region_data rd;
-  
-  if (val == 0) { gf_multby_zero(dest, bytes, xor); return; }
-  if (val == 1) { gf_multby_one(src, dest, bytes, xor); return; }
-
-  h = (gf_internal_t *) gf->scratch;
-  d16 = (struct gf_split_16_32_lazy_data *) h->private;
-  for (i = 0; i < 2; i++) t[i] = d16->tables[i];
-  change = (val != d16->last_value);
-  if (change) d16->last_value = val;
-
-  pp = h->prim_poly;
-
-  gf_set_region_data(&rd, gf, src, dest, bytes, val, xor, 4);
-  gf_do_initial_region_alignment(&rd);
-
-  s32 = (uint32_t *) rd.s_start;
-  d32 = (uint32_t *) rd.d_start;
-  top = (uint32_t *) rd.d_top;
-  
-  if (change) {
-    v = val;
-    for (i = 0; i < 2; i++) {
-      t[i][0] = 0;
-      for (j = 1; j < (1 << 16); j <<= 1) {
-        for (k = 0; k < j; k++) {
-          t[i][k^j] = (v ^ t[i][k]);
-        }
-        v = (v & GF_FIRST_BIT) ? ((v << 1) ^ pp) : (v << 1);
-      }
-    }
-  } 
-
-  while (d32 < top) {
-    p = (xor) ? *d32 : 0;
-    a = *s32;
-    i = 0;
-    while (a != 0 && i < 2) {
-      v = (a & 0xffff);
-      p ^= t[i][v];
-      a >>= 16;
-      i++;
-    }
-    *d32 = p;
-    d32++;
-    s32++;
-  }
-  gf_do_final_region_alignment(&rd);
-}
-
-static
-void
-gf_w32_split_2_32_lazy_multiply_region(gf_t *gf, void *src, void *dest, uint32_t val, int bytes, int xor)
-{
-  gf_internal_t *h;
-  struct gf_split_2_32_lazy_data *ld;
-  int i;
-  uint32_t pp, v, v2, s, *s32, *d32, *top;
-  gf_region_data rd;
- 
-  if (val == 0) { gf_multby_zero(dest, bytes, xor); return; }
-  if (val == 1) { gf_multby_one(src, dest, bytes, xor); return; }
-
-  gf_set_region_data(&rd, gf, src, dest, bytes, val, xor, 4);
-  gf_do_initial_region_alignment(&rd);
-
-  h = (gf_internal_t *) gf->scratch;
-  pp = h->prim_poly;
-
-  ld = (struct gf_split_2_32_lazy_data *) h->private;
-  
-  if (ld->last_value != val) {
-    v = val;
-    for (i = 0; i < 16; i++) {
-      v2 = (v << 1);
-      if (v & GF_FIRST_BIT) v2 ^= pp;
-      ld->tables[i][0] = 0;
-      ld->tables[i][1] = v;
-      ld->tables[i][2] = v2;
-      ld->tables[i][3] = (v2 ^ v);
-      v = (v2 << 1);
-      if (v2 & GF_FIRST_BIT) v ^= pp;
-    }
-  }
-  ld->last_value = val;
-
-  s32 = (uint32_t *) rd.s_start;
-  d32 = (uint32_t *) rd.d_start;
-  top = (uint32_t *) rd.d_top;
-
-  while (d32 != top) {
-    v = (xor) ? *d32 : 0;
-    s = *s32;
-    i = 0;
-    while (s != 0) {
-      v ^= ld->tables[i][s&3];
-      s >>= 2;
-      i++;
-    }
-    *d32 = v;
-    d32++;
-    s32++;
-  }
-  gf_do_final_region_alignment(&rd);
-}
-
-#ifdef INTEL_SSSE3
-static
-void
-gf_w32_split_2_32_lazy_sse_multiply_region(gf_t *gf, void *src, void *dest, uint32_t val, int bytes, int xor)
-{
-  gf_internal_t *h;
-  int i, tindex;
-  uint32_t pp, v, v2, *s32, *d32, *top;
-  __m128i vi, si, pi, shuffler, tables[16], adder, xi, mask1, mask2;
-  gf_region_data rd;
- 
-  if (val == 0) { gf_multby_zero(dest, bytes, xor); return; }
-  if (val == 1) { gf_multby_one(src, dest, bytes, xor); return; }
-
-  gf_set_region_data(&rd, gf, src, dest, bytes, val, xor, 32);
-  gf_do_initial_region_alignment(&rd);
-
-  h = (gf_internal_t *) gf->scratch;
-  pp = h->prim_poly;
-  
-  s32 = (uint32_t *) rd.s_start;
-  d32 = (uint32_t *) rd.d_start;
-  top = (uint32_t *) rd.d_top;
-  
-  v = val;
-  for (i = 0; i < 16; i++) {
-    v2 = (v << 1);
-    if (v & GF_FIRST_BIT) v2 ^= pp;
-    tables[i] = _mm_set_epi32(v2 ^ v, v2, v, 0);
-    v = (v2 << 1);
-    if (v2 & GF_FIRST_BIT) v ^= pp;
-  }
-
-  shuffler = _mm_set_epi8(0xc, 0xc, 0xc, 0xc, 8, 8, 8, 8, 4, 4, 4, 4, 0, 0, 0, 0);
-  adder = _mm_set_epi8(3, 2, 1, 0, 3, 2, 1, 0, 3, 2, 1, 0, 3, 2, 1, 0);
-  mask1 = _mm_set1_epi8(0x3);
-  mask2 = _mm_set1_epi8(0xc);
-
-  while (d32 != top) {
-    pi = (xor) ? _mm_load_si128 ((__m128i *) d32) : _mm_setzero_si128();
-    vi = _mm_load_si128((__m128i *) s32);
- 
-    tindex = 0;
-    for (i = 0; i < 4; i++) {
-      si = _mm_shuffle_epi8(vi, shuffler);
-
-      xi = _mm_and_si128(si, mask1);
-      xi = _mm_slli_epi16(xi, 2);
-      xi = _mm_xor_si128(xi, adder);
-      pi = _mm_xor_si128(pi, _mm_shuffle_epi8(tables[tindex], xi));
-      tindex++;
-
-      xi = _mm_and_si128(si, mask2);
-      xi = _mm_xor_si128(xi, adder);
-      pi = _mm_xor_si128(pi, _mm_shuffle_epi8(tables[tindex], xi));
-      si = _mm_srli_epi16(si, 2);
-      tindex++;
-
-      xi = _mm_and_si128(si, mask2);
-      xi = _mm_xor_si128(xi, adder);
-      pi = _mm_xor_si128(pi, _mm_shuffle_epi8(tables[tindex], xi));
-      si = _mm_srli_epi16(si, 2);
-      tindex++;
-
-      xi = _mm_and_si128(si, mask2);
-      xi = _mm_xor_si128(xi, adder);
-      pi = _mm_xor_si128(pi, _mm_shuffle_epi8(tables[tindex], xi));
-      tindex++;
-      
-      vi = _mm_srli_epi32(vi, 8);
-    }
-    _mm_store_si128((__m128i *) d32, pi);
-    d32 += 4;
-    s32 += 4;
-  }
-
-  gf_do_final_region_alignment(&rd);
-
-}
-#endif
-
-static
-void
-gf_w32_split_4_32_lazy_multiply_region(gf_t *gf, void *src, void *dest, uint32_t val, int bytes, int xor)
-{
-  gf_internal_t *h;
-  struct gf_split_4_32_lazy_data *ld;
-  int i, j, k;
-  uint32_t pp, v, s, *s32, *d32, *top;
-  gf_region_data rd;
- 
-  if (val == 0) { gf_multby_zero(dest, bytes, xor); return; }
-  if (val == 1) { gf_multby_one(src, dest, bytes, xor); return; }
-
-  h = (gf_internal_t *) gf->scratch;
-  pp = h->prim_poly;
-
-  ld = (struct gf_split_4_32_lazy_data *) h->private;
-
-  gf_set_region_data(&rd, gf, src, dest, bytes, val, xor, 4);
-  gf_do_initial_region_alignment(&rd);
-  
-  if (ld->last_value != val) {
-    v = val;
-    for (i = 0; i < 8; i++) {
-      ld->tables[i][0] = 0;
-      for (j = 1; j < 16; j <<= 1) {
-        for (k = 0; k < j; k++) {
-          ld->tables[i][k^j] = (v ^ ld->tables[i][k]);
-        }
-        v = (v & GF_FIRST_BIT) ? ((v << 1) ^ pp) : (v << 1);
-      }
-    }
-  }
-  ld->last_value = val;
-
-  s32 = (uint32_t *) rd.s_start;
-  d32 = (uint32_t *) rd.d_start;
-  top = (uint32_t *) rd.d_top;
-
-  while (d32 != top) {
-    v = (xor) ? *d32 : 0;
-    s = *s32;
-    i = 0;
-    while (s != 0) {
-      v ^= ld->tables[i][s&0xf];
-      s >>= 4;
-      i++;
-    }
-    *d32 = v;
-    d32++;
-    s32++;
-  }
-  gf_do_final_region_alignment(&rd);
-}
-
-static
-void
-gf_w32_split_4_32_lazy_sse_altmap_multiply_region(gf_t *gf, void *src, void *dest, uint32_t val, int bytes, int xor)
-{
-#ifdef INTEL_SSSE3
-  gf_internal_t *h;
-  int i, j, k;
-  uint32_t pp, v, *s32, *d32, *top;
-  __m128i si, tables[8][4], p0, p1, p2, p3, mask1, v0, v1, v2, v3;
-  struct gf_split_4_32_lazy_data *ld;
-  uint8_t btable[16];
-  gf_region_data rd;
- 
-  if (val == 0) { gf_multby_zero(dest, bytes, xor); return; }
-  if (val == 1) { gf_multby_one(src, dest, bytes, xor); return; }
-
-  h = (gf_internal_t *) gf->scratch;
-  pp = h->prim_poly;
-  
-  gf_set_region_data(&rd, gf, src, dest, bytes, val, xor, 64);
-  gf_do_initial_region_alignment(&rd);
-
-  s32 = (uint32_t *) rd.s_start;
-  d32 = (uint32_t *) rd.d_start;
-  top = (uint32_t *) rd.d_top;
-  
-  ld = (struct gf_split_4_32_lazy_data *) h->private;
- 
-  v = val;
-  for (i = 0; i < 8; i++) {
-    ld->tables[i][0] = 0;
-    for (j = 1; j < 16; j <<= 1) {
-      for (k = 0; k < j; k++) {
-        ld->tables[i][k^j] = (v ^ ld->tables[i][k]);
-      }
-      v = (v & GF_FIRST_BIT) ? ((v << 1) ^ pp) : (v << 1);
-    }
-    for (j = 0; j < 4; j++) {
-      for (k = 0; k < 16; k++) {
-        btable[k] = (uint8_t) ld->tables[i][k];
-        ld->tables[i][k] >>= 8;
-      }
-      tables[i][j] = _mm_loadu_si128((__m128i *) btable);
-    }
-  }
-
-  mask1 = _mm_set1_epi8(0xf);
-
-  if (xor) {
-    while (d32 != top) {
-      p0 = _mm_load_si128 ((__m128i *) d32);
-      p1 = _mm_load_si128 ((__m128i *) (d32+4));
-      p2 = _mm_load_si128 ((__m128i *) (d32+8));
-      p3 = _mm_load_si128 ((__m128i *) (d32+12));
-  
-      v0 = _mm_load_si128((__m128i *) s32); s32 += 4;
-      v1 = _mm_load_si128((__m128i *) s32); s32 += 4;
-      v2 = _mm_load_si128((__m128i *) s32); s32 += 4;
-      v3 = _mm_load_si128((__m128i *) s32); s32 += 4;
-  
-      si = _mm_and_si128(v0, mask1);
-      p0 = _mm_xor_si128(p0, _mm_shuffle_epi8(tables[0][0], si));
-      p1 = _mm_xor_si128(p1, _mm_shuffle_epi8(tables[0][1], si));
-      p2 = _mm_xor_si128(p2, _mm_shuffle_epi8(tables[0][2], si));
-      p3 = _mm_xor_si128(p3, _mm_shuffle_epi8(tables[0][3], si));
-      
-      v0 = _mm_srli_epi32(v0, 4);
-      si = _mm_and_si128(v0, mask1);
-      p0 = _mm_xor_si128(p0, _mm_shuffle_epi8(tables[1][0], si));
-      p1 = _mm_xor_si128(p1, _mm_shuffle_epi8(tables[1][1], si));
-      p2 = _mm_xor_si128(p2, _mm_shuffle_epi8(tables[1][2], si));
-      p3 = _mm_xor_si128(p3, _mm_shuffle_epi8(tables[1][3], si));
-  
-      si = _mm_and_si128(v1, mask1);
-      p0 = _mm_xor_si128(p0, _mm_shuffle_epi8(tables[2][0], si));
-      p1 = _mm_xor_si128(p1, _mm_shuffle_epi8(tables[2][1], si));
-      p2 = _mm_xor_si128(p2, _mm_shuffle_epi8(tables[2][2], si));
-      p3 = _mm_xor_si128(p3, _mm_shuffle_epi8(tables[2][3], si));
-      
-      v1 = _mm_srli_epi32(v1, 4);
-      si = _mm_and_si128(v1, mask1);
-      p0 = _mm_xor_si128(p0, _mm_shuffle_epi8(tables[3][0], si));
-      p1 = _mm_xor_si128(p1, _mm_shuffle_epi8(tables[3][1], si));
-      p2 = _mm_xor_si128(p2, _mm_shuffle_epi8(tables[3][2], si));
-      p3 = _mm_xor_si128(p3, _mm_shuffle_epi8(tables[3][3], si));
-  
-      si = _mm_and_si128(v2, mask1);
-      p0 = _mm_xor_si128(p0, _mm_shuffle_epi8(tables[4][0], si));
-      p1 = _mm_xor_si128(p1, _mm_shuffle_epi8(tables[4][1], si));
-      p2 = _mm_xor_si128(p2, _mm_shuffle_epi8(tables[4][2], si));
-      p3 = _mm_xor_si128(p3, _mm_shuffle_epi8(tables[4][3], si));
-      
-      v2 = _mm_srli_epi32(v2, 4);
-      si = _mm_and_si128(v2, mask1);
-      p0 = _mm_xor_si128(p0, _mm_shuffle_epi8(tables[5][0], si));
-      p1 = _mm_xor_si128(p1, _mm_shuffle_epi8(tables[5][1], si));
-      p2 = _mm_xor_si128(p2, _mm_shuffle_epi8(tables[5][2], si));
-      p3 = _mm_xor_si128(p3, _mm_shuffle_epi8(tables[5][3], si));
-  
-      si = _mm_and_si128(v3, mask1);
-      p0 = _mm_xor_si128(p0, _mm_shuffle_epi8(tables[6][0], si));
-      p1 = _mm_xor_si128(p1, _mm_shuffle_epi8(tables[6][1], si));
-      p2 = _mm_xor_si128(p2, _mm_shuffle_epi8(tables[6][2], si));
-      p3 = _mm_xor_si128(p3, _mm_shuffle_epi8(tables[6][3], si));
-      
-      v3 = _mm_srli_epi32(v3, 4);
-      si = _mm_and_si128(v3, mask1);
-      p0 = _mm_xor_si128(p0, _mm_shuffle_epi8(tables[7][0], si));
-      p1 = _mm_xor_si128(p1, _mm_shuffle_epi8(tables[7][1], si));
-      p2 = _mm_xor_si128(p2, _mm_shuffle_epi8(tables[7][2], si));
-      p3 = _mm_xor_si128(p3, _mm_shuffle_epi8(tables[7][3], si));
-  
-      _mm_store_si128((__m128i *) d32, p0);
-      _mm_store_si128((__m128i *) (d32+4), p1);
-      _mm_store_si128((__m128i *) (d32+8), p2);
-      _mm_store_si128((__m128i *) (d32+12), p3);
-      d32 += 16;
-    } 
-  } else {
-    while (d32 != top) {
-  
-      v0 = _mm_load_si128((__m128i *) s32); s32 += 4;
-      v1 = _mm_load_si128((__m128i *) s32); s32 += 4;
-      v2 = _mm_load_si128((__m128i *) s32); s32 += 4;
-      v3 = _mm_load_si128((__m128i *) s32); s32 += 4;
-
-      si = _mm_and_si128(v0, mask1);
-      p0 = _mm_shuffle_epi8(tables[0][0], si);
-      p1 = _mm_shuffle_epi8(tables[0][1], si);
-      p2 = _mm_shuffle_epi8(tables[0][2], si);
-      p3 = _mm_shuffle_epi8(tables[0][3], si);
-      
-      v0 = _mm_srli_epi32(v0, 4);
-      si = _mm_and_si128(v0, mask1);
-      p0 = _mm_xor_si128(p0, _mm_shuffle_epi8(tables[1][0], si));
-      p1 = _mm_xor_si128(p1, _mm_shuffle_epi8(tables[1][1], si));
-      p2 = _mm_xor_si128(p2, _mm_shuffle_epi8(tables[1][2], si));
-      p3 = _mm_xor_si128(p3, _mm_shuffle_epi8(tables[1][3], si));
-  
-      si = _mm_and_si128(v1, mask1);
-      p0 = _mm_xor_si128(p0, _mm_shuffle_epi8(tables[2][0], si));
-      p1 = _mm_xor_si128(p1, _mm_shuffle_epi8(tables[2][1], si));
-      p2 = _mm_xor_si128(p2, _mm_shuffle_epi8(tables[2][2], si));
-      p3 = _mm_xor_si128(p3, _mm_shuffle_epi8(tables[2][3], si));
-      
-      v1 = _mm_srli_epi32(v1, 4);
-      si = _mm_and_si128(v1, mask1);
-      p0 = _mm_xor_si128(p0, _mm_shuffle_epi8(tables[3][0], si));
-      p1 = _mm_xor_si128(p1, _mm_shuffle_epi8(tables[3][1], si));
-      p2 = _mm_xor_si128(p2, _mm_shuffle_epi8(tables[3][2], si));
-      p3 = _mm_xor_si128(p3, _mm_shuffle_epi8(tables[3][3], si));
-  
-      si = _mm_and_si128(v2, mask1);
-      p0 = _mm_xor_si128(p0, _mm_shuffle_epi8(tables[4][0], si));
-      p1 = _mm_xor_si128(p1, _mm_shuffle_epi8(tables[4][1], si));
-      p2 = _mm_xor_si128(p2, _mm_shuffle_epi8(tables[4][2], si));
-      p3 = _mm_xor_si128(p3, _mm_shuffle_epi8(tables[4][3], si));
-      
-      v2 = _mm_srli_epi32(v2, 4);
-      si = _mm_and_si128(v2, mask1);
-      p0 = _mm_xor_si128(p0, _mm_shuffle_epi8(tables[5][0], si));
-      p1 = _mm_xor_si128(p1, _mm_shuffle_epi8(tables[5][1], si));
-      p2 = _mm_xor_si128(p2, _mm_shuffle_epi8(tables[5][2], si));
-      p3 = _mm_xor_si128(p3, _mm_shuffle_epi8(tables[5][3], si));
-  
-      si = _mm_and_si128(v3, mask1);
-      p0 = _mm_xor_si128(p0, _mm_shuffle_epi8(tables[6][0], si));
-      p1 = _mm_xor_si128(p1, _mm_shuffle_epi8(tables[6][1], si));
-      p2 = _mm_xor_si128(p2, _mm_shuffle_epi8(tables[6][2], si));
-      p3 = _mm_xor_si128(p3, _mm_shuffle_epi8(tables[6][3], si));
-      
-      v3 = _mm_srli_epi32(v3, 4);
-      si = _mm_and_si128(v3, mask1);
-      p0 = _mm_xor_si128(p0, _mm_shuffle_epi8(tables[7][0], si));
-      p1 = _mm_xor_si128(p1, _mm_shuffle_epi8(tables[7][1], si));
-      p2 = _mm_xor_si128(p2, _mm_shuffle_epi8(tables[7][2], si));
-      p3 = _mm_xor_si128(p3, _mm_shuffle_epi8(tables[7][3], si));
-  
-      _mm_store_si128((__m128i *) d32, p0);
-      _mm_store_si128((__m128i *) (d32+4), p1);
-      _mm_store_si128((__m128i *) (d32+8), p2);
-      _mm_store_si128((__m128i *) (d32+12), p3);
-      d32 += 16;
-    } 
-  }
-
-  gf_do_final_region_alignment(&rd);
-
-#endif
-}
-
-
-static
-void
-gf_w32_split_4_32_lazy_sse_multiply_region(gf_t *gf, void *src, void *dest, uint32_t val, int bytes, int xor)
-{
-#ifdef INTEL_SSSE3
-  gf_internal_t *h;
-  int i, j, k;
-  uint32_t pp, v, *s32, *d32, *top, tmp_table[16];
-  __m128i si, tables[8][4], p0, p1, p2, p3, mask1, v0, v1, v2, v3, mask8;
-  __m128i tv1, tv2, tv3, tv0;
-  uint8_t btable[16];
-  gf_region_data rd;
-
-  if (val == 0) { gf_multby_zero(dest, bytes, xor); return; }
-  if (val == 1) { gf_multby_one(src, dest, bytes, xor); return; }
-
-  h = (gf_internal_t *) gf->scratch;
-  pp = h->prim_poly;
-  
-  gf_set_region_data(&rd, gf, src, dest, bytes, val, xor, 64);
-  gf_do_initial_region_alignment(&rd);
-
-  s32 = (uint32_t *) rd.s_start;
-  d32 = (uint32_t *) rd.d_start;
-  top = (uint32_t *) rd.d_top;
-
-  v = val;
-  for (i = 0; i < 8; i++) {
-    tmp_table[0] = 0;
-    for (j = 1; j < 16; j <<= 1) {
-      for (k = 0; k < j; k++) {
-        tmp_table[k^j] = (v ^ tmp_table[k]);
-      }
-      v = (v & GF_FIRST_BIT) ? ((v << 1) ^ pp) : (v << 1);
-    }
-    for (j = 0; j < 4; j++) {
-      for (k = 0; k < 16; k++) {
-        btable[k] = (uint8_t) tmp_table[k];
-        tmp_table[k] >>= 8;
-      }
-      tables[i][j] = _mm_loadu_si128((__m128i *) btable);
-    }
-  }
-
-  mask1 = _mm_set1_epi8(0xf);
-  mask8 = _mm_set1_epi16(0xff);
-
-  if (xor) {
-    while (d32 != top) {
-      v0 = _mm_load_si128((__m128i *) s32); s32 += 4;
-      v1 = _mm_load_si128((__m128i *) s32); s32 += 4;
-      v2 = _mm_load_si128((__m128i *) s32); s32 += 4;
-      v3 = _mm_load_si128((__m128i *) s32); s32 += 4;
-  
-      p0 = _mm_srli_epi16(v0, 8);
-      p1 = _mm_srli_epi16(v1, 8);
-      p2 = _mm_srli_epi16(v2, 8);
-      p3 = _mm_srli_epi16(v3, 8);
-
-      tv0 = _mm_and_si128(v0, mask8);
-      tv1 = _mm_and_si128(v1, mask8);
-      tv2 = _mm_and_si128(v2, mask8);
-      tv3 = _mm_and_si128(v3, mask8);
-
-      v0 = _mm_packus_epi16(p1, p0);
-      v1 = _mm_packus_epi16(tv1, tv0);
-      v2 = _mm_packus_epi16(p3, p2);
-      v3 = _mm_packus_epi16(tv3, tv2);
-
-      p0 = _mm_srli_epi16(v0, 8);
-      p1 = _mm_srli_epi16(v1, 8);
-      p2 = _mm_srli_epi16(v2, 8);
-      p3 = _mm_srli_epi16(v3, 8);
-
-      tv0 = _mm_and_si128(v0, mask8);
-      tv1 = _mm_and_si128(v1, mask8);
-      tv2 = _mm_and_si128(v2, mask8);
-      tv3 = _mm_and_si128(v3, mask8);
-
-      v0 = _mm_packus_epi16(p2, p0);
-      v1 = _mm_packus_epi16(p3, p1);
-      v2 = _mm_packus_epi16(tv2, tv0);
-      v3 = _mm_packus_epi16(tv3, tv1);
-
-      si = _mm_and_si128(v0, mask1);
-      p0 = _mm_shuffle_epi8(tables[6][0], si);
-      p1 = _mm_shuffle_epi8(tables[6][1], si);
-      p2 = _mm_shuffle_epi8(tables[6][2], si);
-      p3 = _mm_shuffle_epi8(tables[6][3], si);
-      
-      v0 = _mm_srli_epi32(v0, 4);
-      si = _mm_and_si128(v0, mask1);
-      p0 = _mm_xor_si128(p0, _mm_shuffle_epi8(tables[7][0], si));
-      p1 = _mm_xor_si128(p1, _mm_shuffle_epi8(tables[7][1], si));
-      p2 = _mm_xor_si128(p2, _mm_shuffle_epi8(tables[7][2], si));
-      p3 = _mm_xor_si128(p3, _mm_shuffle_epi8(tables[7][3], si));
-  
-      si = _mm_and_si128(v1, mask1);
-      p0 = _mm_xor_si128(p0, _mm_shuffle_epi8(tables[4][0], si));
-      p1 = _mm_xor_si128(p1, _mm_shuffle_epi8(tables[4][1], si));
-      p2 = _mm_xor_si128(p2, _mm_shuffle_epi8(tables[4][2], si));
-      p3 = _mm_xor_si128(p3, _mm_shuffle_epi8(tables[4][3], si));
-      
-      v1 = _mm_srli_epi32(v1, 4);
-      si = _mm_and_si128(v1, mask1);
-      p0 = _mm_xor_si128(p0, _mm_shuffle_epi8(tables[5][0], si));
-      p1 = _mm_xor_si128(p1, _mm_shuffle_epi8(tables[5][1], si));
-      p2 = _mm_xor_si128(p2, _mm_shuffle_epi8(tables[5][2], si));
-      p3 = _mm_xor_si128(p3, _mm_shuffle_epi8(tables[5][3], si));
-  
-      si = _mm_and_si128(v2, mask1);
-      p0 = _mm_xor_si128(p0, _mm_shuffle_epi8(tables[2][0], si));
-      p1 = _mm_xor_si128(p1, _mm_shuffle_epi8(tables[2][1], si));
-      p2 = _mm_xor_si128(p2, _mm_shuffle_epi8(tables[2][2], si));
-      p3 = _mm_xor_si128(p3, _mm_shuffle_epi8(tables[2][3], si));
-      
-      v2 = _mm_srli_epi32(v2, 4);
-      si = _mm_and_si128(v2, mask1);
-      p0 = _mm_xor_si128(p0, _mm_shuffle_epi8(tables[3][0], si));
-      p1 = _mm_xor_si128(p1, _mm_shuffle_epi8(tables[3][1], si));
-      p2 = _mm_xor_si128(p2, _mm_shuffle_epi8(tables[3][2], si));
-      p3 = _mm_xor_si128(p3, _mm_shuffle_epi8(tables[3][3], si));
-  
-      si = _mm_and_si128(v3, mask1);
-      p0 = _mm_xor_si128(p0, _mm_shuffle_epi8(tables[0][0], si));
-      p1 = _mm_xor_si128(p1, _mm_shuffle_epi8(tables[0][1], si));
-      p2 = _mm_xor_si128(p2, _mm_shuffle_epi8(tables[0][2], si));
-      p3 = _mm_xor_si128(p3, _mm_shuffle_epi8(tables[0][3], si));
-      
-      v3 = _mm_srli_epi32(v3, 4);
-      si = _mm_and_si128(v3, mask1);
-      p0 = _mm_xor_si128(p0, _mm_shuffle_epi8(tables[1][0], si));
-      p1 = _mm_xor_si128(p1, _mm_shuffle_epi8(tables[1][1], si));
-      p2 = _mm_xor_si128(p2, _mm_shuffle_epi8(tables[1][2], si));
-      p3 = _mm_xor_si128(p3, _mm_shuffle_epi8(tables[1][3], si));
-  
-      tv0 = _mm_unpackhi_epi8(p1, p3);
-      tv1 = _mm_unpackhi_epi8(p0, p2);
-      tv2 = _mm_unpacklo_epi8(p1, p3);
-      tv3 = _mm_unpacklo_epi8(p0, p2);
-
-      p0 = _mm_unpackhi_epi8(tv1, tv0);
-      p1 = _mm_unpacklo_epi8(tv1, tv0);
-      p2 = _mm_unpackhi_epi8(tv3, tv2);
-      p3 = _mm_unpacklo_epi8(tv3, tv2);
-
-      v0 = _mm_load_si128 ((__m128i *) d32);
-      v1 = _mm_load_si128 ((__m128i *) (d32+4));
-      v2 = _mm_load_si128 ((__m128i *) (d32+8));
-      v3 = _mm_load_si128 ((__m128i *) (d32+12));
-  
-      p0 = _mm_xor_si128(p0, v0);
-      p1 = _mm_xor_si128(p1, v1);
-      p2 = _mm_xor_si128(p2, v2);
-      p3 = _mm_xor_si128(p3, v3);
-
-      _mm_store_si128((__m128i *) d32, p0);
-      _mm_store_si128((__m128i *) (d32+4), p1);
-      _mm_store_si128((__m128i *) (d32+8), p2);
-      _mm_store_si128((__m128i *) (d32+12), p3);
-      d32 += 16;
-    } 
-  } else {
-    while (d32 != top) {
-      v0 = _mm_load_si128((__m128i *) s32); s32 += 4;
-      v1 = _mm_load_si128((__m128i *) s32); s32 += 4;
-      v2 = _mm_load_si128((__m128i *) s32); s32 += 4;
-      v3 = _mm_load_si128((__m128i *) s32); s32 += 4;
- 
-      p0 = _mm_srli_epi16(v0, 8);
-      p1 = _mm_srli_epi16(v1, 8);
-      p2 = _mm_srli_epi16(v2, 8);
-      p3 = _mm_srli_epi16(v3, 8);
-      
-      tv0 = _mm_and_si128(v0, mask8);
-      tv1 = _mm_and_si128(v1, mask8);
-      tv2 = _mm_and_si128(v2, mask8);
-      tv3 = _mm_and_si128(v3, mask8);
-      
-      v0 = _mm_packus_epi16(p1, p0);
-      v1 = _mm_packus_epi16(tv1, tv0);
-      v2 = _mm_packus_epi16(p3, p2);
-      v3 = _mm_packus_epi16(tv3, tv2);
-      
-      p0 = _mm_srli_epi16(v0, 8);
-      p1 = _mm_srli_epi16(v1, 8);
-      p2 = _mm_srli_epi16(v2, 8);
-      p3 = _mm_srli_epi16(v3, 8);
-     
-      tv0 = _mm_and_si128(v0, mask8);
-      tv1 = _mm_and_si128(v1, mask8);
-      tv2 = _mm_and_si128(v2, mask8);
-      tv3 = _mm_and_si128(v3, mask8);
-      
-      v0 = _mm_packus_epi16(p2, p0);
-      v1 = _mm_packus_epi16(p3, p1);
-      v2 = _mm_packus_epi16(tv2, tv0);
-      v3 = _mm_packus_epi16(tv3, tv1);
-      
-      si = _mm_and_si128(v0, mask1);
-      p0 = _mm_shuffle_epi8(tables[6][0], si);
-      p1 = _mm_shuffle_epi8(tables[6][1], si);
-      p2 = _mm_shuffle_epi8(tables[6][2], si);
-      p3 = _mm_shuffle_epi8(tables[6][3], si);
-      
-      v0 = _mm_srli_epi32(v0, 4);
-      si = _mm_and_si128(v0, mask1);
-      p0 = _mm_xor_si128(p0, _mm_shuffle_epi8(tables[7][0], si));
-      p1 = _mm_xor_si128(p1, _mm_shuffle_epi8(tables[7][1], si));
-      p2 = _mm_xor_si128(p2, _mm_shuffle_epi8(tables[7][2], si));
-      p3 = _mm_xor_si128(p3, _mm_shuffle_epi8(tables[7][3], si));
-  
-      si = _mm_and_si128(v1, mask1);
-      p0 = _mm_xor_si128(p0, _mm_shuffle_epi8(tables[4][0], si));
-      p1 = _mm_xor_si128(p1, _mm_shuffle_epi8(tables[4][1], si));
-      p2 = _mm_xor_si128(p2, _mm_shuffle_epi8(tables[4][2], si));
-      p3 = _mm_xor_si128(p3, _mm_shuffle_epi8(tables[4][3], si));
-      
-      v1 = _mm_srli_epi32(v1, 4);
-      si = _mm_and_si128(v1, mask1);
-      p0 = _mm_xor_si128(p0, _mm_shuffle_epi8(tables[5][0], si));
-      p1 = _mm_xor_si128(p1, _mm_shuffle_epi8(tables[5][1], si));
-      p2 = _mm_xor_si128(p2, _mm_shuffle_epi8(tables[5][2], si));
-      p3 = _mm_xor_si128(p3, _mm_shuffle_epi8(tables[5][3], si));
-  
-      si = _mm_and_si128(v2, mask1);
-      p0 = _mm_xor_si128(p0, _mm_shuffle_epi8(tables[2][0], si));
-      p1 = _mm_xor_si128(p1, _mm_shuffle_epi8(tables[2][1], si));
-      p2 = _mm_xor_si128(p2, _mm_shuffle_epi8(tables[2][2], si));
-      p3 = _mm_xor_si128(p3, _mm_shuffle_epi8(tables[2][3], si));
-      
-      v2 = _mm_srli_epi32(v2, 4);
-      si = _mm_and_si128(v2, mask1);
-      p0 = _mm_xor_si128(p0, _mm_shuffle_epi8(tables[3][0], si));
-      p1 = _mm_xor_si128(p1, _mm_shuffle_epi8(tables[3][1], si));
-      p2 = _mm_xor_si128(p2, _mm_shuffle_epi8(tables[3][2], si));
-      p3 = _mm_xor_si128(p3, _mm_shuffle_epi8(tables[3][3], si));
-  
-      si = _mm_and_si128(v3, mask1);
-      p0 = _mm_xor_si128(p0, _mm_shuffle_epi8(tables[0][0], si));
-      p1 = _mm_xor_si128(p1, _mm_shuffle_epi8(tables[0][1], si));
-      p2 = _mm_xor_si128(p2, _mm_shuffle_epi8(tables[0][2], si));
-      p3 = _mm_xor_si128(p3, _mm_shuffle_epi8(tables[0][3], si));
-      
-      v3 = _mm_srli_epi32(v3, 4);
-      si = _mm_and_si128(v3, mask1);
-      p0 = _mm_xor_si128(p0, _mm_shuffle_epi8(tables[1][0], si));
-      p1 = _mm_xor_si128(p1, _mm_shuffle_epi8(tables[1][1], si));
-      p2 = _mm_xor_si128(p2, _mm_shuffle_epi8(tables[1][2], si));
-      p3 = _mm_xor_si128(p3, _mm_shuffle_epi8(tables[1][3], si)); 
-  
-      tv0 = _mm_unpackhi_epi8(p1, p3);
-      tv1 = _mm_unpackhi_epi8(p0, p2);
-      tv2 = _mm_unpacklo_epi8(p1, p3);
-      tv3 = _mm_unpacklo_epi8(p0, p2);
-      
-      p0 = _mm_unpackhi_epi8(tv1, tv0);
-      p1 = _mm_unpacklo_epi8(tv1, tv0);
-      p2 = _mm_unpackhi_epi8(tv3, tv2);
-      p3 = _mm_unpacklo_epi8(tv3, tv2);
-      
-      _mm_store_si128((__m128i *) d32, p0);
-      _mm_store_si128((__m128i *) (d32+4), p1);
-      _mm_store_si128((__m128i *) (d32+8), p2);
-      _mm_store_si128((__m128i *) (d32+12), p3);
-      d32 += 16;
-    } 
-  }
-  gf_do_final_region_alignment(&rd);
-
-#endif
-}
-
-static 
-int gf_w32_split_init(gf_t *gf)
-{
-  gf_internal_t *h;
-  struct gf_split_2_32_lazy_data *ld2;
-  struct gf_split_4_32_lazy_data *ld4;
-  struct gf_w32_split_8_8_data *d8;
-  struct gf_split_8_32_lazy_data *d32;
-  struct gf_split_16_32_lazy_data *d16;
-  uint32_t p, basep;
-  int i, j, exp, ispclmul, issse3;
-  int isneon = 0;
-
-#if defined(INTEL_SSE4_PCLMUL)
-  ispclmul = 1;
-#else
-  ispclmul = 0;
-#endif
-
-#ifdef INTEL_SSSE3
-  issse3 = 1;
-#else
-  issse3 = 0;
-#endif
-#ifdef ARM_NEON
-  isneon = 1;
-#endif
-
-  h = (gf_internal_t *) gf->scratch;
-
-  /* Defaults */
-  
-  gf->inverse.w32 = gf_w32_euclid;
-
-  /* JSP: First handle single multiplication:  
-     If args == 8, then we're doing split 8 8.  
-     Otherwise, if PCLMUL, we use that.
-     Otherwise, we use bytwo_p.
-   */
-
-  if (h->arg1 == 8 && h->arg2 == 8) {
-    gf->multiply.w32 = gf_w32_split_8_8_multiply;
-  } else if (ispclmul) {
-    if ((0xfffe0000 & h->prim_poly) == 0){
-      gf->multiply.w32 = gf_w32_clm_multiply_2;
-    } else if ((0xffc00000 & h->prim_poly) == 0){
-      gf->multiply.w32 = gf_w32_clm_multiply_3;
-    } else if ((0xfe000000 & h->prim_poly) == 0){
-     gf->multiply.w32 = gf_w32_clm_multiply_4;
-    }
-  } else {
-    gf->multiply.w32 = gf_w32_bytwo_p_multiply;
-  }
-
-  /* Easy cases: 16/32 and 2/32 */
-
-  if ((h->arg1 == 16 && h->arg2 == 32) || (h->arg1 == 32 && h->arg2 == 16)) {
-    d16 = (struct gf_split_16_32_lazy_data *) h->private;
-    d16->last_value = 0;
-    gf->multiply_region.w32 = gf_w32_split_16_32_lazy_multiply_region;
-    return 1;
-  }
-
-  if ((h->arg1 == 2 && h->arg2 == 32) || (h->arg1 == 32 && h->arg2 == 2)) {
-    ld2 = (struct gf_split_2_32_lazy_data *) h->private;
-    ld2->last_value = 0;
-    #ifdef INTEL_SSSE3
-      if (!(h->region_type & GF_REGION_NOSIMD))
-        gf->multiply_region.w32 = gf_w32_split_2_32_lazy_sse_multiply_region;
-      else
-        gf->multiply_region.w32 = gf_w32_split_2_32_lazy_multiply_region;
-    #else
-      gf->multiply_region.w32 = gf_w32_split_2_32_lazy_multiply_region;
-      if(h->region_type & GF_REGION_SIMD) return 0;
-    #endif
-    return 1;
-  } 
-
-  /* 4/32 or Default + SSE - There is no ALTMAP/NOSSE. */
-
-  if ((h->arg1 == 4 && h->arg2 == 32) || (h->arg1 == 32 && h->arg2 == 4) ||
-      ((issse3 || isneon) && h->mult_type == GF_REGION_DEFAULT)) {
-    ld4 = (struct gf_split_4_32_lazy_data *) h->private;
-    ld4->last_value = 0;
-    if ((h->region_type & GF_REGION_NOSIMD) || !(issse3 || isneon)) {
-      gf->multiply_region.w32 = gf_w32_split_4_32_lazy_multiply_region;
-    } else if (isneon) {
-#ifdef ARM_NEON
-      gf_w32_neon_split_init(gf);
-#endif
-    } else if (h->region_type & GF_REGION_ALTMAP) {
-      gf->multiply_region.w32 = gf_w32_split_4_32_lazy_sse_altmap_multiply_region;
-    } else {
-      gf->multiply_region.w32 = gf_w32_split_4_32_lazy_sse_multiply_region;
-    }
-    return 1;
-  } 
-
-  /* 8/32 or Default + no SSE */
-
-  if ((h->arg1 == 8 && h->arg2 == 32) || (h->arg1 == 32 && h->arg2 == 8) || 
-       h->mult_type == GF_MULT_DEFAULT) {
-    d32 = (struct gf_split_8_32_lazy_data *) h->private;
-    d32->last_value = 0;
-    gf->multiply_region.w32 = gf_w32_split_8_32_lazy_multiply_region;
-    return 1;
-  }
-
-  /* Finally, if args == 8, then we have to set up the tables here. */
-
-  if (h->arg1 == 8 && h->arg2 == 8) {
-    d8 = (struct gf_w32_split_8_8_data *) h->private;
-    d8->last_value = 0;
-    gf->multiply.w32 = gf_w32_split_8_8_multiply;
-    gf->multiply_region.w32 = gf_w32_split_8_32_lazy_multiply_region;
-    basep = 1;
-    for (exp = 0; exp < 7; exp++) {
-      for (j = 0; j < 256; j++) d8->tables[exp][0][j] = 0;
-      for (i = 0; i < 256; i++) d8->tables[exp][i][0] = 0;
-      d8->tables[exp][1][1] = basep;
-      for (i = 2; i < 256; i++) {
-        if (i&1) {
-          p = d8->tables[exp][i^1][1];
-          d8->tables[exp][i][1] = p ^ basep;
-        } else {
-          p = d8->tables[exp][i>>1][1];
-          d8->tables[exp][i][1] = GF_MULTBY_TWO(p);
-        }
-      }
-      for (i = 1; i < 256; i++) {
-        p = d8->tables[exp][i][1];
-        for (j = 1; j < 256; j++) {
-          if (j&1) {
-            d8->tables[exp][i][j] = d8->tables[exp][i][j^1] ^ p;
-          } else {
-            d8->tables[exp][i][j] = GF_MULTBY_TWO(d8->tables[exp][i][j>>1]);
-          }
-        }
-      }
-      for (i = 0; i < 8; i++) basep = GF_MULTBY_TWO(basep);
-    }
-    return 1;
-  }
-
-  /* If we get here, then the arguments were bad. */
-
-  return 0;
-}
-
-static
-int gf_w32_group_init(gf_t *gf)
-{
-  uint32_t i, j, p, index;
-  struct gf_w32_group_data *gd;
-  gf_internal_t *h = (gf_internal_t *) gf->scratch;
-  uint32_t g_r, g_s;
-
-  g_s = h->arg1;
-  g_r = h->arg2;
-
-  gd = (struct gf_w32_group_data *) h->private;
-  gd->shift = (uint32_t *) (&(gd->memory));
-  gd->reduce = gd->shift + (1 << g_s);
-
-  gd->rmask = (1 << g_r) - 1;
-  gd->rmask <<= 32;
-
-  gd->tshift = 32 % g_s;
-  if (gd->tshift == 0) gd->tshift = g_s;
-  gd->tshift = (32 - gd->tshift);
-  gd->tshift = ((gd->tshift-1)/g_r) * g_r;
-
-  gd->reduce[0] = 0;
-  for (i = 0; i < ((uint32_t)1 << g_r); i++) {
-    p = 0;
-    index = 0;
-    for (j = 0; j < g_r; j++) {
-      if (i & (1 << j)) {
-        p ^= (h->prim_poly << j);
-        index ^= (1 << j);
-        index ^= (h->prim_poly >> (32-j));
-      }
-    }
-    gd->reduce[index] = p;
-  }
-
-  if (g_s == g_r) {
-    gf->multiply.w32 = gf_w32_group_s_equals_r_multiply;
-    gf->multiply_region.w32 = gf_w32_group_s_equals_r_multiply_region; 
-  } else {
-    gf->multiply.w32 = gf_w32_group_multiply;
-    gf->multiply_region.w32 = gf_w32_group_multiply_region;
-  }
-  gf->divide.w32 = NULL;
-  gf->inverse.w32 = gf_w32_euclid;
-
-  return 1;
-}
-
-
-static
-uint32_t
-gf_w32_composite_multiply_recursive(gf_t *gf, uint32_t a, uint32_t b)
-{
-  gf_internal_t *h = (gf_internal_t *) gf->scratch;
-  gf_t *base_gf = h->base_gf;
-  uint32_t b0 = b & 0x0000ffff;
-  uint32_t b1 = (b & 0xffff0000) >> 16;
-  uint32_t a0 = a & 0x0000ffff;
-  uint32_t a1 = (a & 0xffff0000) >> 16;
-  uint32_t a1b1;
-  uint32_t rv;
-  a1b1 = base_gf->multiply.w32(base_gf, a1, b1);
-
-  rv = ((base_gf->multiply.w32(base_gf, a1, b0) ^ base_gf->multiply.w32(base_gf, a0, b1) ^ base_gf->multiply.w32(base_gf, a1b1, h->prim_poly)) << 16) | (base_gf->multiply.w32(base_gf, a0, b0) ^ a1b1);
-  return rv;
-}
-
-/* JSP: This could be made faster. Someday, when I'm bored. */
-
-static
-uint32_t
-gf_w32_composite_multiply_inline(gf_t *gf, uint32_t a, uint32_t b)
-{
-  gf_internal_t *h = (gf_internal_t *) gf->scratch;
-  uint32_t b0 = b & 0x0000ffff;
-  uint32_t b1 = b >> 16;
-  uint32_t a0 = a & 0x0000ffff;
-  uint32_t a1 = a >> 16;
-  uint32_t a1b1, prod;
-  uint16_t *log, *alog;
-  struct gf_w32_composite_data *cd;
-
-  cd = (struct gf_w32_composite_data *) h->private;
-  log = cd->log;
-  alog = cd->alog;
-
-  a1b1 = GF_W16_INLINE_MULT(log, alog, a1, b1);
-  prod = GF_W16_INLINE_MULT(log, alog, a1, b0);
-  prod ^= GF_W16_INLINE_MULT(log, alog, a0, b1);
-  prod ^= GF_W16_INLINE_MULT(log, alog, a1b1, h->prim_poly);
-  prod <<= 16;
-  prod ^= GF_W16_INLINE_MULT(log, alog, a0, b0);
-  prod ^= a1b1;
-  return prod;
-}
-
-/*
- * Composite field division trick (explained in 2007 tech report)
- *
- * Compute a / b = a*b^-1, where p(x) = x^2 + sx + 1
- *
- * let c = b^-1
- *
- * c*b = (s*b1c1+b1c0+b0c1)x+(b1c1+b0c0)
- *
- * want (s*b1c1+b1c0+b0c1) = 0 and (b1c1+b0c0) = 1
- *
- * let d = b1c1 and d+1 = b0c0
- *
- * solve s*b1c1+b1c0+b0c1 = 0
- *
- * solution: d = (b1b0^-1)(b1b0^-1+b0b1^-1+s)^-1
- *
- * c0 = (d+1)b0^-1
- * c1 = d*b1^-1
- *
- * a / b = a * c
- */
-
-static
-uint32_t
-gf_w32_composite_inverse(gf_t *gf, uint32_t a)
-{
-  gf_internal_t *h = (gf_internal_t *) gf->scratch;
-  gf_t *base_gf = h->base_gf;
-  uint16_t a0 = a & 0x0000ffff;
-  uint16_t a1 = (a & 0xffff0000) >> 16;
-  uint16_t c0, c1, d, tmp;
-  uint32_t c;
-  uint16_t a0inv, a1inv;
-
-  if (a0 == 0) {
-    a1inv = base_gf->inverse.w32(base_gf, a1);
-    c0 = base_gf->multiply.w32(base_gf, a1inv, h->prim_poly);
-    c1 = a1inv;
-  } else if (a1 == 0) {
-    c0 = base_gf->inverse.w32(base_gf, a0);
-    c1 = 0;
-  } else {
-    a1inv = base_gf->inverse.w32(base_gf, a1);
-    a0inv = base_gf->inverse.w32(base_gf, a0);
-
-    d = base_gf->multiply.w32(base_gf, a1, a0inv);
-
-    tmp = (base_gf->multiply.w32(base_gf, a1, a0inv) ^ base_gf->multiply.w32(base_gf, a0, a1inv) ^ h->prim_poly);
-    tmp = base_gf->inverse.w32(base_gf, tmp);
-
-    d = base_gf->multiply.w32(base_gf, d, tmp);
-
-    c0 = base_gf->multiply.w32(base_gf, (d^1), a0inv);
-    c1 = base_gf->multiply.w32(base_gf, d, a1inv);
-  }
-
-  c = c0 | (c1 << 16);
-
-  return c;
-}
-
-static
-void
-gf_w32_composite_multiply_region(gf_t *gf, void *src, void *dest, uint32_t val, int bytes, int xor)
-{
-  gf_internal_t *h = (gf_internal_t *) gf->scratch;
-  gf_t *base_gf = h->base_gf;
-  uint32_t b0 = val & 0x0000ffff;
-  uint32_t b1 = (val & 0xffff0000) >> 16;
-  uint32_t *s32, *d32, *top;
-  uint16_t a0, a1, a1b1, *log, *alog;
-  uint32_t prod;
-  gf_region_data rd;
-  struct gf_w32_composite_data *cd;
-
-  cd = (struct gf_w32_composite_data *) h->private;
-  log = cd->log;
-  alog = cd->alog;
-
-  if (val == 0) { gf_multby_zero(dest, bytes, xor); return; }
-  gf_set_region_data(&rd, gf, src, dest, bytes, val, xor, 4);
-  
-  s32 = rd.s_start;
-  d32 = rd.d_start;
-  top = rd.d_top;
-
-  if (log == NULL) {
-    if (xor) {
-      while (d32 < top) {
-        a0 = *s32 & 0x0000ffff;
-        a1 = (*s32 & 0xffff0000) >> 16;
-        a1b1 = base_gf->multiply.w32(base_gf, a1, b1);
-  
-        *d32 ^= ((base_gf->multiply.w32(base_gf, a0, b0) ^ a1b1) |
-                  ((base_gf->multiply.w32(base_gf, a1, b0) ^ base_gf->multiply.w32(base_gf, a0, b1) ^ base_gf->multiply.w32(base_gf, a1b1, h->prim_poly)) << 16)); 
-        s32++;
-        d32++;
-      }
-    } else {
-      while (d32 < top) {
-        a0 = *s32 & 0x0000ffff;
-        a1 = (*s32 & 0xffff0000) >> 16;
-        a1b1 = base_gf->multiply.w32(base_gf, a1, b1);
-  
-        *d32 = ((base_gf->multiply.w32(base_gf, a0, b0) ^ a1b1) |
-                  ((base_gf->multiply.w32(base_gf, a1, b0) ^ base_gf->multiply.w32(base_gf, a0, b1) ^ base_gf->multiply.w32(base_gf, a1b1, h->prim_poly)) << 16)); 
-        s32++;
-        d32++;
-      }
-    }
-  } else {
-    if (xor) {
-      while (d32 < top) {
-        a0 = *s32 & 0x0000ffff;
-        a1 = (*s32 & 0xffff0000) >> 16;
-        a1b1 = GF_W16_INLINE_MULT(log, alog, a1, b1);
-
-        prod = GF_W16_INLINE_MULT(log, alog, a1, b0);
-        prod ^= GF_W16_INLINE_MULT(log, alog, a0, b1);
-        prod ^= GF_W16_INLINE_MULT(log, alog, a1b1, h->prim_poly);
-        prod <<= 16;
-        prod ^= GF_W16_INLINE_MULT(log, alog, a0, b0);
-        prod ^= a1b1;
-        *d32 ^= prod;
-        s32++;
-        d32++;
-      }
-    } else {
-      while (d32 < top) {
-        a0 = *s32 & 0x0000ffff;
-        a1 = (*s32 & 0xffff0000) >> 16;
-        a1b1 = GF_W16_INLINE_MULT(log, alog, a1, b1);
-  
-        prod = GF_W16_INLINE_MULT(log, alog, a1, b0);
-        prod ^= GF_W16_INLINE_MULT(log, alog, a0, b1);
-        prod ^= GF_W16_INLINE_MULT(log, alog, a1b1, h->prim_poly);
-        prod <<= 16;
-        prod ^= GF_W16_INLINE_MULT(log, alog, a0, b0);
-        prod ^= a1b1;
-        
-        *d32 = prod;
-        s32++;
-        d32++;
-      }
-    }
-  }
-}
-
-static
-void
-gf_w32_composite_multiply_region_alt(gf_t *gf, void *src, void *dest, uint32_t val, int bytes, int xor)
-{
-  gf_internal_t *h = (gf_internal_t *) gf->scratch;
-  gf_t *base_gf = h->base_gf;
-  uint16_t    val0 = val & 0x0000ffff;
-  uint16_t    val1 = (val & 0xffff0000) >> 16;
-  gf_region_data rd;
-  int sub_reg_size;
-  uint8_t *slow, *shigh;
-  uint8_t *dlow, *dhigh, *top;
-
-  /* JSP: I want the two pointers aligned wrt each other on 16 byte
-     boundaries.  So I'm going to make sure that the area on
-     which the two operate is a multiple of 32. Of course, that
-     junks up the mapping, but so be it -- that's why we have extract_word.... */
-
-  gf_set_region_data(&rd, gf, src, dest, bytes, val, xor, 32);
-  gf_do_initial_region_alignment(&rd);
-
-  slow = (uint8_t *) rd.s_start;
-  dlow = (uint8_t *) rd.d_start;
-  top = (uint8_t *)  rd.d_top;
-  sub_reg_size = (top - dlow)/2;
-  shigh = slow + sub_reg_size;
-  dhigh = dlow + sub_reg_size;
-  
-  base_gf->multiply_region.w32(base_gf, slow, dlow, val0, sub_reg_size, xor);
-  base_gf->multiply_region.w32(base_gf, shigh, dlow, val1, sub_reg_size, 1);
-  base_gf->multiply_region.w32(base_gf, slow, dhigh, val1, sub_reg_size, xor);
-  base_gf->multiply_region.w32(base_gf, shigh, dhigh, val0, sub_reg_size, 1);
-  base_gf->multiply_region.w32(base_gf, shigh, dhigh, base_gf->multiply.w32(base_gf, h->prim_poly, val1), sub_reg_size, 1);
-
-  gf_do_final_region_alignment(&rd);
-}
-
-static
-int gf_w32_composite_init(gf_t *gf)
-{
-  gf_internal_t *h = (gf_internal_t *) gf->scratch;
-  struct gf_w32_composite_data *cd;
-
-  if (h->base_gf == NULL) return 0;
-
-  cd = (struct gf_w32_composite_data *) h->private;
-  cd->log = gf_w16_get_log_table(h->base_gf);
-  cd->alog = gf_w16_get_mult_alog_table(h->base_gf);
-
-  if (h->region_type & GF_REGION_ALTMAP) {
-    gf->multiply_region.w32 = gf_w32_composite_multiply_region_alt;
-  } else {
-    gf->multiply_region.w32 = gf_w32_composite_multiply_region;
-  }
-
-  if (cd->log == NULL) {
-    gf->multiply.w32 = gf_w32_composite_multiply_recursive;
-  } else {
-    gf->multiply.w32 = gf_w32_composite_multiply_inline; 
-  }
-  gf->divide.w32 = NULL;
-  gf->inverse.w32 = gf_w32_composite_inverse;
-
-  return 1;
-}
-
-
-
-int gf_w32_scratch_size(int mult_type, int region_type, int divide_type, int arg1, int arg2)
-{
-  int issse3 = 0;
-  int isneon = 0;
-
-#ifdef INTEL_SSSE3
-  issse3 = 1;
-#endif
-#ifdef ARM_NEON
-  isneon = 1;
-#endif
-
-  switch(mult_type)
-  {
-    case GF_MULT_BYTWO_p:
-    case GF_MULT_BYTWO_b:
-      return sizeof(gf_internal_t) + sizeof(struct gf_w32_bytwo_data) + 64;
-      break;
-    case GF_MULT_GROUP: 
-      return sizeof(gf_internal_t) + sizeof(struct gf_w32_group_data) +
-               sizeof(uint32_t) * (1 << arg1) +
-               sizeof(uint32_t) * (1 << arg2) + 64;
-      break;
-    case GF_MULT_DEFAULT:
-
-    case GF_MULT_SPLIT_TABLE: 
-        if (arg1 == 8 && arg2 == 8){
-          return sizeof(gf_internal_t) + sizeof(struct gf_w32_split_8_8_data) + 64;
-        }
-        if ((arg1 == 16 && arg2 == 32) || (arg2 == 16 && arg1 == 32)) {
-          return sizeof(gf_internal_t) + sizeof(struct gf_split_16_32_lazy_data) + 64;
-        }
-        if ((arg1 == 2 && arg2 == 32) || (arg2 == 2 && arg1 == 32)) {
-          return sizeof(gf_internal_t) + sizeof(struct gf_split_2_32_lazy_data) + 64;
-        }
-        if ((arg1 == 8 && arg2 == 32) || (arg2 == 8 && arg1 == 32) || 
-             (mult_type == GF_MULT_DEFAULT && !(issse3 || isneon))) {
-          return sizeof(gf_internal_t) + sizeof(struct gf_split_8_32_lazy_data) + 64;
-        }
-        if ((arg1 == 4 && arg2 == 32) || 
-            (arg2 == 4 && arg1 == 32) ||
-            mult_type == GF_MULT_DEFAULT) {
-          return sizeof(gf_internal_t) + sizeof(struct gf_split_4_32_lazy_data) + 64;
-        }
-        return 0;
-    case GF_MULT_CARRY_FREE:
-      return sizeof(gf_internal_t);
-      break;
-    case GF_MULT_CARRY_FREE_GK:
-      return sizeof(gf_internal_t) + sizeof(uint64_t)*2;
-      break;
-    case GF_MULT_SHIFT:
-      return sizeof(gf_internal_t);
-      break;
-    case GF_MULT_COMPOSITE:
-      return sizeof(gf_internal_t) + sizeof(struct gf_w32_composite_data) + 64;
-      break;
-
-    default:
-      return 0;
-   }
-   return 0;
-}
-
-int gf_w32_init(gf_t *gf)
-{
-  gf_internal_t *h;
-
-  h = (gf_internal_t *) gf->scratch;
-  
-  /* Allen: set default primitive polynomial / irreducible polynomial if needed */
-
-  if (h->prim_poly == 0) {
-    if (h->mult_type == GF_MULT_COMPOSITE) { 
-      h->prim_poly = gf_composite_get_default_poly(h->base_gf);
-      if (h->prim_poly == 0) return 0; /* This shouldn't happen */
-    } else { 
-
-      /* Allen: use the following primitive polynomial to make carryless multiply work more efficiently for GF(2^32).*/
-
-      /* h->prim_poly = 0xc5; */
-
-      /* Allen: The following is the traditional primitive polynomial for GF(2^32) */
-
-      h->prim_poly = 0x400007;
-    } 
-  }
-
-  /* No leading one */
-
-  if(h->mult_type != GF_MULT_COMPOSITE) h->prim_poly &= 0xffffffff;
-    
-  gf->multiply.w32 = NULL;
-  gf->divide.w32 = NULL;
-  gf->inverse.w32 = NULL;
-  gf->multiply_region.w32 = NULL;
-
-  switch(h->mult_type) {
-    case GF_MULT_CARRY_FREE:    if (gf_w32_cfm_init(gf) == 0) return 0; break;
-    case GF_MULT_CARRY_FREE_GK: if (gf_w32_cfmgk_init(gf) == 0) return 0; break;
-    case GF_MULT_SHIFT:         if (gf_w32_shift_init(gf) == 0) return 0; break;
-    case GF_MULT_COMPOSITE:     if (gf_w32_composite_init(gf) == 0) return 0; break;
-    case GF_MULT_DEFAULT: 
-    case GF_MULT_SPLIT_TABLE:   if (gf_w32_split_init(gf) == 0) return 0; break;
-    case GF_MULT_GROUP:         if (gf_w32_group_init(gf) == 0) return 0; break;
-    case GF_MULT_BYTWO_p:   
-    case GF_MULT_BYTWO_b:       if (gf_w32_bytwo_init(gf) == 0) return 0; break;
-    default: return 0;
-  }
-  if (h->divide_type == GF_DIVIDE_EUCLID) {
-    gf->divide.w32 = gf_w32_divide_from_inverse;
-    gf->inverse.w32 = gf_w32_euclid;
-  } else if (h->divide_type == GF_DIVIDE_MATRIX) {
-    gf->divide.w32 = gf_w32_divide_from_inverse;
-    gf->inverse.w32 = gf_w32_matrix;
-  }
-
-  if (gf->inverse.w32 != NULL && gf->divide.w32 == NULL) {
-    gf->divide.w32 = gf_w32_divide_from_inverse;
-  }
-  if (gf->inverse.w32 == NULL && gf->divide.w32 != NULL) {
-    gf->inverse.w32 = gf_w32_inverse_from_divide;
-  }
-  if (h->region_type == GF_REGION_CAUCHY) {
-    gf->extract_word.w32 = gf_wgen_extract_word;
-    gf->multiply_region.w32 = gf_wgen_cauchy_region;
-  } else if (h->region_type & GF_REGION_ALTMAP) {
-    if (h->mult_type == GF_MULT_COMPOSITE) {
-      gf->extract_word.w32 = gf_w32_composite_extract_word;
-    } else {
-      gf->extract_word.w32 = gf_w32_split_extract_word;
-    }
-  } else {
-    gf->extract_word.w32 = gf_w32_extract_word;
-  }
-  return 1;
-}
diff --git a/src/erasure-code/jerasure/gf-complete/src/gf_w4.c b/src/erasure-code/jerasure/gf-complete/src/gf_w4.c
deleted file mode 100644
index 0e86aa8..0000000
--- a/src/erasure-code/jerasure/gf-complete/src/gf_w4.c
+++ /dev/null
@@ -1,2051 +0,0 @@
-/*
- * GF-Complete: A Comprehensive Open Source Library for Galois Field Arithmetic
- * James S. Plank, Ethan L. Miller, Kevin M. Greenan,
- * Benjamin A. Arnold, John A. Burnum, Adam W. Disney, Allen C. McBride.
- *
- * gf_w4.c
- *
- * Routines for 4-bit Galois fields
- */
-
-#include "gf_int.h"
-#include <stdio.h>
-#include <stdlib.h>
-#include "gf_w4.h"
-
-#define AB2(ip, am1 ,am2, b, t1, t2) {\
-  t1 = (b << 1) & am1;\
-  t2 = b & am2; \
-  t2 = ((t2 << 1) - (t2 >> (GF_FIELD_WIDTH-1))); \
-  b = (t1 ^ (t2 & ip));}
-
-// ToDo(KMG/JSP): Why is 0x88 hard-coded?
-#define SSE_AB2(pp, m1, va, t1, t2) {\
-          t1 = _mm_and_si128(_mm_slli_epi64(va, 1), m1); \
-          t2 = _mm_and_si128(va, _mm_set1_epi8(0x88)); \
-          t2 = _mm_sub_epi64 (_mm_slli_epi64(t2, 1), _mm_srli_epi64(t2, (GF_FIELD_WIDTH-1))); \
-          va = _mm_xor_si128(t1, _mm_and_si128(t2, pp)); }
-
-/* ------------------------------------------------------------
-   JSP: These are basic and work from multiple implementations.
- */
-
-static
-inline
-gf_val_32_t gf_w4_inverse_from_divide (gf_t *gf, gf_val_32_t a)
-{
-  return gf->divide.w32(gf, 1, a);
-}
-
-static
-inline
-gf_val_32_t gf_w4_divide_from_inverse (gf_t *gf, gf_val_32_t a, gf_val_32_t b)
-{
-  b = gf->inverse.w32(gf, b);
-  return gf->multiply.w32(gf, a, b);
-}
-
-static
-inline
-gf_val_32_t gf_w4_euclid (gf_t *gf, gf_val_32_t b)
-{
-  gf_val_32_t e_i, e_im1, e_ip1;
-  gf_val_32_t d_i, d_im1, d_ip1;
-  gf_val_32_t y_i, y_im1, y_ip1;
-  gf_val_32_t c_i;
-
-  if (b == 0) return -1;
-  e_im1 = ((gf_internal_t *) (gf->scratch))->prim_poly;
-  e_i = b;
-  d_im1 = 4;
-  for (d_i = d_im1; ((1 << d_i) & e_i) == 0; d_i--) ;
-  y_i = 1;
-  y_im1 = 0;
-
-  while (e_i != 1) {
-    e_ip1 = e_im1;
-    d_ip1 = d_im1;
-    c_i = 0;
-
-    while (d_ip1 >= d_i) {
-      c_i ^= (1 << (d_ip1 - d_i));
-      e_ip1 ^= (e_i << (d_ip1 - d_i));
-      if (e_ip1 == 0) return 0;
-      while ((e_ip1 & (1 << d_ip1)) == 0) d_ip1--;
-    }
-
-    y_ip1 = y_im1 ^ gf->multiply.w32(gf, c_i, y_i);
-    y_im1 = y_i;
-    y_i = y_ip1;
-
-    e_im1 = e_i;
-    d_im1 = d_i;
-    e_i = e_ip1;
-    d_i = d_ip1;
-  }
-
-  return y_i;
-}
-
-static 
-gf_val_32_t gf_w4_extract_word(gf_t *gf, void *start, int bytes, int index)
-{
-  uint8_t *r8, v;
-
-  r8 = (uint8_t *) start;
-  v = r8[index/2];
-  if (index%2) {
-    return v >> 4;
-  } else {
-    return v&0xf;
-  }
-}
-
-
-static
-inline
-gf_val_32_t gf_w4_matrix (gf_t *gf, gf_val_32_t b)
-{
-  return gf_bitmatrix_inverse(b, 4, ((gf_internal_t *) (gf->scratch))->prim_poly);
-}
-
-
-static
-inline
-gf_val_32_t
-gf_w4_shift_multiply (gf_t *gf, gf_val_32_t a, gf_val_32_t b)
-{
-  uint8_t product, i, pp;
-  gf_internal_t *h;
-  
-  h = (gf_internal_t *) gf->scratch;
-  pp = h->prim_poly;
-
-  product = 0;
-
-  for (i = 0; i < GF_FIELD_WIDTH; i++) { 
-    if (a & (1 << i)) product ^= (b << i);
-  }
-  for (i = (GF_FIELD_WIDTH*2-2); i >= GF_FIELD_WIDTH; i--) {
-    if (product & (1 << i)) product ^= (pp << (i-GF_FIELD_WIDTH)); 
-  }
-  return product;
-}
-
-/* Ben: This function works, but it is 33% slower than the normal shift mult */
-
-static
-inline
-gf_val_32_t
-gf_w4_clm_multiply (gf_t *gf, gf_val_32_t a4, gf_val_32_t b4)
-{
-  gf_val_32_t rv = 0;
-
-#if defined(INTEL_SSE4_PCLMUL)
-
-  __m128i         a, b;
-  __m128i         result;
-  __m128i         prim_poly;
-  __m128i         w;
-  gf_internal_t * h = gf->scratch;
-
-  a = _mm_insert_epi32 (_mm_setzero_si128(), a4, 0);
-  b = _mm_insert_epi32 (a, b4, 0);
-
-  prim_poly = _mm_set_epi32(0, 0, 0, (uint32_t)(h->prim_poly & 0x1fULL));
-
-  /* Do the initial multiply */
-
-  result = _mm_clmulepi64_si128 (a, b, 0);
-
-  /* Ben/JSP: Do prim_poly reduction once. We are guaranteed that we will only
-     have to do the reduction only once, because (w-2)/z == 1. Where
-     z is equal to the number of zeros after the leading 1.
-
-     _mm_clmulepi64_si128 is the carryless multiply operation. Here
-     _mm_srli_epi64 shifts the result to the right by 4 bits. This allows
-     us to multiply the prim_poly by the leading bits of the result. We
-     then xor the result of that operation back with the result. */
-
-  w = _mm_clmulepi64_si128 (prim_poly, _mm_srli_epi64 (result, 4), 0);
-  result = _mm_xor_si128 (result, w);
-
-  /* Extracts 32 bit value from result. */
-
-  rv = ((gf_val_32_t)_mm_extract_epi32(result, 0));
-#endif
-  return rv;
-}
-
-static
-void
-gf_w4_multiply_region_from_single(gf_t *gf, void *src, void *dest, gf_val_32_t val, int bytes, int 
-    xor)
-{
-  gf_region_data rd;
-  uint8_t *s8;
-  uint8_t *d8;
-
-  if (val == 0) { gf_multby_zero(dest, bytes, xor); return; }
-  if (val == 1) { gf_multby_one(src, dest, bytes, xor); return; }
-
-  gf_set_region_data(&rd, gf, src, dest, bytes, val, xor, 1);
-  gf_do_initial_region_alignment(&rd);
-
-  s8 = (uint8_t *) rd.s_start;
-  d8 = (uint8_t *) rd.d_start;
-
-  if (xor) {
-    while (d8 < ((uint8_t *) rd.d_top)) {
-      *d8 ^= (gf->multiply.w32(gf, val, (*s8 & 0xf)) | 
-             ((gf->multiply.w32(gf, val, (*s8 >> 4))) << 4));
-      d8++;
-      s8++;
-    }
-  } else {
-    while (d8 < ((uint8_t *) rd.d_top)) {
-      *d8 = (gf->multiply.w32(gf, val, (*s8 & 0xf)) | 
-             ((gf->multiply.w32(gf, val, (*s8 >> 4))) << 4));
-      d8++;
-      s8++;
-    }
-  }
-  gf_do_final_region_alignment(&rd);
-}
-
-/* ------------------------------------------------------------
-  IMPLEMENTATION: LOG_TABLE: 
-
-  JSP: This is a basic log-antilog implementation.  
-       I'm not going to spend any time optimizing it because the
-       other techniques are faster for both single and region
-       operations. 
- */
-
-static
-inline
-gf_val_32_t
-gf_w4_log_multiply (gf_t *gf, gf_val_32_t a, gf_val_32_t b)
-{
-  struct gf_logtable_data *ltd;
-    
-  ltd = (struct gf_logtable_data *) ((gf_internal_t *) (gf->scratch))->private;
-  return (a == 0 || b == 0) ? 0 : ltd->antilog_tbl[(unsigned)(ltd->log_tbl[a] + ltd->log_tbl[b])];
-}
-
-static
-inline
-gf_val_32_t
-gf_w4_log_divide (gf_t *gf, gf_val_32_t a, gf_val_32_t b)
-{
-  int log_sum = 0;
-  struct gf_logtable_data *ltd;
-    
-  if (a == 0 || b == 0) return 0;
-  ltd = (struct gf_logtable_data *) ((gf_internal_t *) (gf->scratch))->private;
-
-  log_sum = ltd->log_tbl[a] - ltd->log_tbl[b];
-  return (ltd->antilog_tbl_div[log_sum]);
-}
-
-static
-void 
-gf_w4_log_multiply_region(gf_t *gf, void *src, void *dest, gf_val_32_t val, int bytes, int xor)
-{
-  int i;
-  uint8_t lv, b, c;
-  uint8_t *s8, *d8;
-  
-  struct gf_logtable_data *ltd;
-
-  if (val == 0) { gf_multby_zero(dest, bytes, xor); return; }
-  if (val == 1) { gf_multby_one(src, dest, bytes, xor); return; }
-
-  ltd = (struct gf_logtable_data *) ((gf_internal_t *) (gf->scratch))->private;
-  s8 = (uint8_t *) src;
-  d8 = (uint8_t *) dest;
-
-  lv = ltd->log_tbl[val];
-
-  for (i = 0; i < bytes; i++) {
-    c = (xor) ? d8[i] : 0;
-    b = (s8[i] >> GF_FIELD_WIDTH);
-    c ^= (b == 0) ? 0 : (ltd->antilog_tbl[lv + ltd->log_tbl[b]] << GF_FIELD_WIDTH);
-    b = (s8[i] & 0xf);
-    c ^= (b == 0) ? 0 : ltd->antilog_tbl[lv + ltd->log_tbl[b]];
-    d8[i] = c;
-  }
-}
-
-static 
-int gf_w4_log_init(gf_t *gf)
-{
-  gf_internal_t *h;
-  struct gf_logtable_data *ltd;
-  int i, b;
-
-  h = (gf_internal_t *) gf->scratch;
-  ltd = h->private;
-
-  for (i = 0; i < GF_FIELD_SIZE; i++)
-    ltd->log_tbl[i]=0;
-
-  ltd->antilog_tbl_div = ltd->antilog_tbl + (GF_FIELD_SIZE-1);
-  b = 1;
-  i = 0;
-  do {
-    if (ltd->log_tbl[b] != 0 && i != 0) {
-      fprintf(stderr, "Cannot construct log table: Polynomial is not primitive.\n\n");
-      return 0;
-    }
-    ltd->log_tbl[b] = i;
-    ltd->antilog_tbl[i] = b;
-    ltd->antilog_tbl[i+GF_FIELD_SIZE-1] = b;
-    b <<= 1;
-    i++;
-    if (b & GF_FIELD_SIZE) b = b ^ h->prim_poly;
-  } while (b != 1);
-
-  if (i != GF_FIELD_SIZE - 1) {
-    _gf_errno = GF_E_LOGPOLY;
-    return 0;
-  }
-    
-  gf->inverse.w32 = gf_w4_inverse_from_divide;
-  gf->divide.w32 = gf_w4_log_divide;
-  gf->multiply.w32 = gf_w4_log_multiply;
-  gf->multiply_region.w32 = gf_w4_log_multiply_region;
-  return 1;
-}
-
-/* ------------------------------------------------------------
-  IMPLEMENTATION: SINGLE TABLE: JSP. 
- */
-
-static
-inline
-gf_val_32_t
-gf_w4_single_table_multiply (gf_t *gf, gf_val_32_t a, gf_val_32_t b)
-{
-  struct gf_single_table_data *std;
-    
-  std = (struct gf_single_table_data *) ((gf_internal_t *) (gf->scratch))->private;
-  return std->mult[a][b];
-}
-
-static
-inline
-gf_val_32_t
-gf_w4_single_table_divide (gf_t *gf, gf_val_32_t a, gf_val_32_t b)
-{
-  struct gf_single_table_data *std;
-    
-  std = (struct gf_single_table_data *) ((gf_internal_t *) (gf->scratch))->private;
-  return std->div[a][b];
-}
-
-static
-void 
-gf_w4_single_table_multiply_region(gf_t *gf, void *src, void *dest, gf_val_32_t val, int bytes, int xor)
-{
-  int i;
-  uint8_t b, c;
-  uint8_t *s8, *d8;
-  
-  struct gf_single_table_data *std;
-
-  if (val == 0) { gf_multby_zero(dest, bytes, xor); return; }
-  if (val == 1) { gf_multby_one(src, dest, bytes, xor); return; }
-
-  std = (struct gf_single_table_data *) ((gf_internal_t *) (gf->scratch))->private;
-  s8 = (uint8_t *) src;
-  d8 = (uint8_t *) dest;
-
-  for (i = 0; i < bytes; i++) {
-    c = (xor) ? d8[i] : 0;
-    b = (s8[i] >> GF_FIELD_WIDTH);
-    c ^= (std->mult[val][b] << GF_FIELD_WIDTH);
-    b = (s8[i] & 0xf);
-    c ^= (std->mult[val][b]);
-    d8[i] = c;
-  }
-}
-
-#define MM_PRINT(s, r) { uint8_t blah[16]; printf("%-12s", s); _mm_storeu_si128((__m128i *)blah, r); for (i = 0; i < 16; i++) printf(" %02x", blah[i]); printf("\n"); }
-
-#ifdef INTEL_SSSE3
-static
-void 
-gf_w4_single_table_sse_multiply_region(gf_t *gf, void *src, void *dest, gf_val_32_t val, int bytes, int xor)
-{
-  gf_region_data rd;
-  uint8_t *base, *sptr, *dptr, *top;
-  __m128i  tl, loset, r, va, th;
-  
-  struct gf_single_table_data *std;
-    
-  if (val == 0) { gf_multby_zero(dest, bytes, xor); return; }
-  if (val == 1) { gf_multby_one(src, dest, bytes, xor); return; }
-
-  gf_set_region_data(&rd, gf, src, dest, bytes, val, xor, 16);
-
-  std = (struct gf_single_table_data *) ((gf_internal_t *) (gf->scratch))->private;
-  base = (uint8_t *) std->mult;
-  base += (val << GF_FIELD_WIDTH);
-
-  gf_do_initial_region_alignment(&rd);
-
-  tl = _mm_loadu_si128((__m128i *)base);
-  th = _mm_slli_epi64(tl, 4);
-  loset = _mm_set1_epi8 (0x0f);
-
-  sptr = rd.s_start;
-  dptr = rd.d_start;
-  top = rd.s_top;
-
-  while (sptr < (uint8_t *) top) {
-    va = _mm_load_si128 ((__m128i *)(sptr));
-    r = _mm_and_si128 (loset, va);
-    r = _mm_shuffle_epi8 (tl, r);
-    va = _mm_srli_epi64 (va, 4);
-    va = _mm_and_si128 (loset, va);
-    va = _mm_shuffle_epi8 (th, va);
-    r = _mm_xor_si128 (r, va);
-    va = (xor) ? _mm_load_si128 ((__m128i *)(dptr)) : _mm_setzero_si128(); 
-    r = _mm_xor_si128 (r, va);
-    _mm_store_si128 ((__m128i *)(dptr), r);
-    dptr += 16;
-    sptr += 16;
-  }
-  gf_do_final_region_alignment(&rd);
-
-}
-#endif
-
-static 
-int gf_w4_single_table_init(gf_t *gf)
-{
-  gf_internal_t *h;
-  struct gf_single_table_data *std;
-  int a, b, prod;
-
-
-  h = (gf_internal_t *) gf->scratch;
-  std = (struct gf_single_table_data *)h->private;
-
-  bzero(std->mult, sizeof(uint8_t) * GF_FIELD_SIZE * GF_FIELD_SIZE);
-  bzero(std->div, sizeof(uint8_t) * GF_FIELD_SIZE * GF_FIELD_SIZE);
-
-  for (a = 1; a < GF_FIELD_SIZE; a++) {
-    for (b = 1; b < GF_FIELD_SIZE; b++) {
-      prod = gf_w4_shift_multiply(gf, a, b);
-      std->mult[a][b] = prod;
-      std->div[prod][b] = a;
-    }
-  }
-
-  gf->inverse.w32 = NULL;
-  gf->divide.w32 = gf_w4_single_table_divide;
-  gf->multiply.w32 = gf_w4_single_table_multiply;
-  #if defined(INTEL_SSSE3) || defined(ARM_NEON)
-    if(h->region_type & (GF_REGION_NOSIMD | GF_REGION_CAUCHY))
-      gf->multiply_region.w32 = gf_w4_single_table_multiply_region;
-    else
-    #if defined(INTEL_SSSE3)
-      gf->multiply_region.w32 = gf_w4_single_table_sse_multiply_region;
-    #elif defined(ARM_NEON)
-      gf_w4_neon_single_table_init(gf);
-    #endif
-  #else
-    gf->multiply_region.w32 = gf_w4_single_table_multiply_region;
-    if (h->region_type & GF_REGION_SIMD) return 0;
-  #endif
-
-  return 1;
-}
-
-/* ------------------------------------------------------------
-  IMPLEMENTATION: DOUBLE TABLE: JSP. 
- */
-
-static
-inline
-gf_val_32_t
-gf_w4_double_table_multiply (gf_t *gf, gf_val_32_t a, gf_val_32_t b)
-{
-  struct gf_double_table_data *std;
-    
-  std = (struct gf_double_table_data *) ((gf_internal_t *) (gf->scratch))->private;
-  return std->mult[a][b];
-}
-
-static
-inline
-gf_val_32_t
-gf_w4_double_table_divide (gf_t *gf, gf_val_32_t a, gf_val_32_t b)
-{
-  struct gf_double_table_data *std;
-    
-  std = (struct gf_double_table_data *) ((gf_internal_t *) (gf->scratch))->private;
-  return std->div[a][b];
-}
-
-static
-void 
-gf_w4_double_table_multiply_region(gf_t *gf, void *src, void *dest, gf_val_32_t val, int bytes, int xor)
-{
-  int i;
-  uint8_t *s8, *d8, *base;
-  gf_region_data rd;
-  struct gf_double_table_data *std;
-    
-  if (val == 0) { gf_multby_zero(dest, bytes, xor); return; }
-  if (val == 1) { gf_multby_one(src, dest, bytes, xor); return; }
-
-  gf_set_region_data(&rd, gf, src, dest, bytes, val, xor, 8);
-
-  std = (struct gf_double_table_data *) ((gf_internal_t *) (gf->scratch))->private;
-  s8 = (uint8_t *) src;
-  d8 = (uint8_t *) dest;
-  base = (uint8_t *) std->mult;
-  base += (val << GF_DOUBLE_WIDTH);
-
-  if (xor) {
-    for (i = 0; i < bytes; i++) d8[i] ^= base[s8[i]];
-  } else {
-    for (i = 0; i < bytes; i++) d8[i] = base[s8[i]];
-  }
-}
-
-static 
-int gf_w4_double_table_init(gf_t *gf)
-{
-  gf_internal_t *h;
-  struct gf_double_table_data *std;
-  int a, b, c, prod, ab;
-  uint8_t mult[GF_FIELD_SIZE][GF_FIELD_SIZE];
-
-  h = (gf_internal_t *) gf->scratch;
-  std = (struct gf_double_table_data *)h->private;
-
-  bzero(mult, sizeof(uint8_t) * GF_FIELD_SIZE * GF_FIELD_SIZE);
-  bzero(std->div, sizeof(uint8_t) * GF_FIELD_SIZE * GF_FIELD_SIZE);
-
-  for (a = 1; a < GF_FIELD_SIZE; a++) {
-    for (b = 1; b < GF_FIELD_SIZE; b++) {
-      prod = gf_w4_shift_multiply(gf, a, b);
-      mult[a][b] = prod;
-      std->div[prod][b] = a;
-    }
-  }
-  bzero(std->mult, sizeof(uint8_t) * GF_FIELD_SIZE * GF_FIELD_SIZE * GF_FIELD_SIZE);
-  for (a = 0; a < GF_FIELD_SIZE; a++) {
-    for (b = 0; b < GF_FIELD_SIZE; b++) {
-      ab = mult[a][b];
-      for (c = 0; c < GF_FIELD_SIZE; c++) {
-        std->mult[a][(b << 4) | c] = ((ab << 4) | mult[a][c]);
-      }
-    }
-  }
-
-  gf->inverse.w32 = NULL;
-  gf->divide.w32 = gf_w4_double_table_divide;
-  gf->multiply.w32 = gf_w4_double_table_multiply;
-  gf->multiply_region.w32 = gf_w4_double_table_multiply_region;
-  return 1;
-}
-
-
-static
-inline
-gf_val_32_t
-gf_w4_quad_table_lazy_divide (gf_t *gf, gf_val_32_t a, gf_val_32_t b)
-{
-  struct gf_quad_table_lazy_data *std;
-    
-  std = (struct gf_quad_table_lazy_data *) ((gf_internal_t *) (gf->scratch))->private;
-  return std->div[a][b];
-}
-
-static
-inline
-gf_val_32_t
-gf_w4_quad_table_lazy_multiply (gf_t *gf, gf_val_32_t a, gf_val_32_t b)
-{
-  struct gf_quad_table_lazy_data *std;
-    
-  std = (struct gf_quad_table_lazy_data *) ((gf_internal_t *) (gf->scratch))->private;
-  return std->smult[a][b];
-}
-
-static
-inline
-gf_val_32_t
-gf_w4_quad_table_divide (gf_t *gf, gf_val_32_t a, gf_val_32_t b)
-{
-  struct gf_quad_table_data *std;
-    
-  std = (struct gf_quad_table_data *) ((gf_internal_t *) (gf->scratch))->private;
-  return std->div[a][b];
-}
-
-static
-inline
-gf_val_32_t
-gf_w4_quad_table_multiply (gf_t *gf, gf_val_32_t a, gf_val_32_t b)
-{
-  struct gf_quad_table_data *std;
-  uint16_t v;
-    
-  std = (struct gf_quad_table_data *) ((gf_internal_t *) (gf->scratch))->private;
-  v = std->mult[a][b];
-  return v;
-}
-
-static
-void 
-gf_w4_quad_table_multiply_region(gf_t *gf, void *src, void *dest, gf_val_32_t val, int bytes, int xor)
-{
-  uint16_t *base;
-  gf_region_data rd;
-  struct gf_quad_table_data *std;
-  struct gf_quad_table_lazy_data *ltd;
-  gf_internal_t *h;
-  int a, b, c, d, va, vb, vc, vd;
-    
-  if (val == 0) { gf_multby_zero(dest, bytes, xor); return; }
-  if (val == 1) { gf_multby_one(src, dest, bytes, xor); return; }
-
-  h = (gf_internal_t *) (gf->scratch);
-  if (h->region_type & GF_REGION_LAZY) {
-    ltd = (struct gf_quad_table_lazy_data *) ((gf_internal_t *) (gf->scratch))->private;
-    base = ltd->mult;
-    for (a = 0; a < 16; a++) {
-      va = (ltd->smult[val][a] << 12);
-      for (b = 0; b < 16; b++) {
-        vb = (ltd->smult[val][b] << 8);
-        for (c = 0; c < 16; c++) {
-          vc = (ltd->smult[val][c] << 4);
-          for (d = 0; d < 16; d++) {
-            vd = ltd->smult[val][d];
-            base[(a << 12) | (b << 8) | (c << 4) | d ] = (va | vb | vc | vd);
-          }
-        }
-      }
-    }
-  } else {
-    std = (struct gf_quad_table_data *) ((gf_internal_t *) (gf->scratch))->private;
-    base = &(std->mult[val][0]);
-  }
-
-  gf_set_region_data(&rd, gf, src, dest, bytes, val, xor, 8);
-  gf_do_initial_region_alignment(&rd);
-  gf_two_byte_region_table_multiply(&rd, base);
-  gf_do_final_region_alignment(&rd);
-}
-
-static 
-int gf_w4_quad_table_init(gf_t *gf)
-{
-  gf_internal_t *h;
-  struct gf_quad_table_data *std;
-  int prod, val, a, b, c, d, va, vb, vc, vd;
-  uint8_t mult[GF_FIELD_SIZE][GF_FIELD_SIZE];
-
-  h = (gf_internal_t *) gf->scratch;
-  std = (struct gf_quad_table_data *)h->private;
-
-  bzero(mult, sizeof(uint8_t) * GF_FIELD_SIZE * GF_FIELD_SIZE);
-  bzero(std->div, sizeof(uint8_t) * GF_FIELD_SIZE * GF_FIELD_SIZE);
-
-  for (a = 1; a < GF_FIELD_SIZE; a++) {
-    for (b = 1; b < GF_FIELD_SIZE; b++) {
-      prod = gf_w4_shift_multiply(gf, a, b);
-      mult[a][b] = prod;
-      std->div[prod][b] = a;
-    }
-  }
-
-  for (val = 0; val < 16; val++) {
-    for (a = 0; a < 16; a++) {
-      va = (mult[val][a] << 12);
-      for (b = 0; b < 16; b++) {
-        vb = (mult[val][b] << 8);
-        for (c = 0; c < 16; c++) {
-          vc = (mult[val][c] << 4);
-          for (d = 0; d < 16; d++) {
-            vd = mult[val][d];
-            std->mult[val][(a << 12) | (b << 8) | (c << 4) | d ] = (va | vb | vc | vd);
-          }
-        }
-      }
-    }
-  }
-
-  gf->inverse.w32 = NULL;
-  gf->divide.w32 = gf_w4_quad_table_divide;
-  gf->multiply.w32 = gf_w4_quad_table_multiply;
-  gf->multiply_region.w32 = gf_w4_quad_table_multiply_region;
-  return 1;
-}
-static 
-int gf_w4_quad_table_lazy_init(gf_t *gf)
-{
-  gf_internal_t *h;
-  struct gf_quad_table_lazy_data *std;
-  int a, b, prod, loga, logb;
-  uint8_t log_tbl[GF_FIELD_SIZE];
-  uint8_t antilog_tbl[GF_FIELD_SIZE*2];
-
-  h = (gf_internal_t *) gf->scratch;
-  std = (struct gf_quad_table_lazy_data *)h->private;
-
-  b = 1;
-  for (a = 0; a < GF_MULT_GROUP_SIZE; a++) {
-      log_tbl[b] = a;
-      antilog_tbl[a] = b;
-      antilog_tbl[a+GF_MULT_GROUP_SIZE] = b;
-      b <<= 1;
-      if (b & GF_FIELD_SIZE) {
-          b = b ^ h->prim_poly;
-      }
-  }
-
-  bzero(std->smult, sizeof(uint8_t) * GF_FIELD_SIZE * GF_FIELD_SIZE);
-  bzero(std->div, sizeof(uint8_t) * GF_FIELD_SIZE * GF_FIELD_SIZE);
-
-  for (a = 1; a < GF_FIELD_SIZE; a++) {
-    loga = log_tbl[a];
-    for (b = 1; b < GF_FIELD_SIZE; b++) {
-      logb = log_tbl[b];
-      prod = antilog_tbl[loga+logb];
-      std->smult[a][b] = prod;
-      std->div[prod][b] = a;
-    }
-  }
-
-  gf->inverse.w32 = NULL;
-  gf->divide.w32 = gf_w4_quad_table_lazy_divide;
-  gf->multiply.w32 = gf_w4_quad_table_lazy_multiply;
-  gf->multiply_region.w32 = gf_w4_quad_table_multiply_region;
-  return 1;
-}
-
-static 
-int gf_w4_table_init(gf_t *gf)
-{
-  int rt;
-  gf_internal_t *h;
-  int simd = 0;
-
-#if defined(INTEL_SSSE3) || defined(ARM_NEON)
-  simd = 1;
-#endif
-
-  h = (gf_internal_t *) gf->scratch;
-  rt = (h->region_type);
-
-  if (h->mult_type == GF_MULT_DEFAULT && !simd) rt |= GF_REGION_DOUBLE_TABLE;
-
-  if (rt & GF_REGION_DOUBLE_TABLE) {
-    return gf_w4_double_table_init(gf);
-  } else if (rt & GF_REGION_QUAD_TABLE) {
-    if (rt & GF_REGION_LAZY) {
-      return gf_w4_quad_table_lazy_init(gf);
-    } else {
-      return gf_w4_quad_table_init(gf);
-    }
-  } else {
-    return gf_w4_single_table_init(gf);
-  }
-  return 0;
-}
-
-/* ------------------------------------------------------------
-   JSP: GF_MULT_BYTWO_p and _b: See the paper.
-*/
-
-static
-inline
-gf_val_32_t
-gf_w4_bytwo_p_multiply (gf_t *gf, gf_val_32_t a, gf_val_32_t b)
-{
-  uint32_t prod, pp, pmask, amask;
-  gf_internal_t *h;
-  
-  h = (gf_internal_t *) gf->scratch;
-  pp = h->prim_poly;
-
-  
-  prod = 0;
-  pmask = 0x8;
-  amask = 0x8;
-
-  while (amask != 0) {
-    if (prod & pmask) {
-      prod = ((prod << 1) ^ pp);
-    } else {
-      prod <<= 1;
-    }
-    if (a & amask) prod ^= b;
-    amask >>= 1;
-  }
-  return prod;
-}
-
-static
-inline
-gf_val_32_t
-gf_w4_bytwo_b_multiply (gf_t *gf, gf_val_32_t a, gf_val_32_t b)
-{
-  uint32_t prod, pp, bmask;
-  gf_internal_t *h;
-  
-  h = (gf_internal_t *) gf->scratch;
-  pp = h->prim_poly;
-
-  prod = 0;
-  bmask = 0x8;
-
-  while (1) {
-    if (a & 1) prod ^= b;
-    a >>= 1;
-    if (a == 0) return prod;
-    if (b & bmask) {
-      b = ((b << 1) ^ pp);
-    } else {
-      b <<= 1;
-    }
-  }
-}
-
-static
-void 
-gf_w4_bytwo_p_nosse_multiply_region(gf_t *gf, void *src, void *dest, gf_val_32_t val, int bytes, int xor)
-{
-  uint64_t *s64, *d64, t1, t2, ta, prod, amask;
-  gf_region_data rd;
-  struct gf_bytwo_data *btd;
-    
-  if (val == 0) { gf_multby_zero(dest, bytes, xor); return; }
-  if (val == 1) { gf_multby_one(src, dest, bytes, xor); return; }
-
-  btd = (struct gf_bytwo_data *) ((gf_internal_t *) (gf->scratch))->private;
-
-  gf_set_region_data(&rd, gf, src, dest, bytes, val, xor, 8);
-  gf_do_initial_region_alignment(&rd);
-
-  s64 = (uint64_t *) rd.s_start;
-  d64 = (uint64_t *) rd.d_start;
-
-  if (xor) {
-    while (s64 < (uint64_t *) rd.s_top) {
-      prod = 0;
-      amask = 0x8;
-      ta = *s64;
-      while (amask != 0) {
-        AB2(btd->prim_poly, btd->mask1, btd->mask2, prod, t1, t2);
-        if (val & amask) prod ^= ta;
-        amask >>= 1;
-      }
-      *d64 ^= prod;
-      d64++;
-      s64++;
-    }
-  } else { 
-    while (s64 < (uint64_t *) rd.s_top) {
-      prod = 0;
-      amask = 0x8;
-      ta = *s64;
-      while (amask != 0) {
-        AB2(btd->prim_poly, btd->mask1, btd->mask2, prod, t1, t2);
-        if (val & amask) prod ^= ta;
-        amask >>= 1;
-      }
-      *d64 = prod;
-      d64++;
-      s64++;
-    }
-  }
-  gf_do_final_region_alignment(&rd);
-}
-
-#define BYTWO_P_ONESTEP {\
-      SSE_AB2(pp, m1, prod, t1, t2); \
-      t1 = _mm_and_si128(v, one); \
-      t1 = _mm_sub_epi8(t1, one); \
-      t1 = _mm_and_si128(t1, ta); \
-      prod = _mm_xor_si128(prod, t1); \
-      v = _mm_srli_epi64(v, 1); }
-
-#ifdef INTEL_SSE2
-static
-void
-gf_w4_bytwo_p_sse_multiply_region(gf_t *gf, void *src, void *dest, gf_val_32_t val, int bytes, int xor)
-{
-  int i;
-  uint8_t *s8, *d8;
-  uint8_t vrev;
-  __m128i pp, m1, ta, prod, t1, t2, tp, one, v;
-  struct gf_bytwo_data *btd;
-  gf_region_data rd;
-
-  if (val == 0) { gf_multby_zero(dest, bytes, xor); return; }
-  if (val == 1) { gf_multby_one(src, dest, bytes, xor); return; }
-
-  btd = (struct gf_bytwo_data *) ((gf_internal_t *) (gf->scratch))->private;
-
-  gf_set_region_data(&rd, gf, src, dest, bytes, val, xor, 16);
-  gf_do_initial_region_alignment(&rd);
-
-  vrev = 0;
-  for (i = 0; i < 4; i++) {
-    vrev <<= 1;
-    if (!(val & (1 << i))) vrev |= 1;
-  }
-
-  s8 = (uint8_t *) rd.s_start;
-  d8 = (uint8_t *) rd.d_start;
-
-  pp = _mm_set1_epi8(btd->prim_poly&0xff);
-  m1 = _mm_set1_epi8((btd->mask1)&0xff);
-  one = _mm_set1_epi8(1);
-
-  while (d8 < (uint8_t *) rd.d_top) {
-    prod = _mm_setzero_si128();
-    v = _mm_set1_epi8(vrev);
-    ta = _mm_load_si128((__m128i *) s8);
-    tp = (!xor) ? _mm_setzero_si128() : _mm_load_si128((__m128i *) d8);
-    BYTWO_P_ONESTEP;
-    BYTWO_P_ONESTEP;
-    BYTWO_P_ONESTEP;
-    BYTWO_P_ONESTEP;
-    _mm_store_si128((__m128i *) d8, _mm_xor_si128(prod, tp));
-    d8 += 16;
-    s8 += 16;
-  }
-  gf_do_final_region_alignment(&rd);
-}
-#endif
-
-/*
-static
-void 
-gf_w4_bytwo_b_sse_multiply_region(gf_t *gf, void *src, void *dest, gf_val_32_t val, int bytes, int xor)
-{
-#ifdef INTEL_SSE2
-  uint8_t *d8, *s8, tb;
-  __m128i pp, m1, m2, t1, t2, va, vb;
-  struct gf_bytwo_data *btd;
-  gf_region_data rd;
-    
-  if (val == 0) { gf_multby_zero(dest, bytes, xor); return; }
-  if (val == 1) { gf_multby_one(src, dest, bytes, xor); return; }
-
-  gf_set_region_data(&rd, gf, src, dest, bytes, val, xor, 16);
-  gf_do_initial_region_alignment(&rd);
-
-  s8 = (uint8_t *) rd.s_start;
-  d8 = (uint8_t *) rd.d_start;
-
-  btd = (struct gf_bytwo_data *) ((gf_internal_t *) (gf->scratch))->private;
-
-  pp = _mm_set1_epi8(btd->prim_poly&0xff);
-  m1 = _mm_set1_epi8((btd->mask1)&0xff);
-  m2 = _mm_set1_epi8((btd->mask2)&0xff);
-
-  if (xor) {
-    while (d8 < (uint8_t *) rd.d_top) {
-      va = _mm_load_si128 ((__m128i *)(s8));
-      vb = _mm_load_si128 ((__m128i *)(d8));
-      tb = val;
-      while (1) {
-        if (tb & 1) vb = _mm_xor_si128(vb, va);
-        tb >>= 1;
-        if (tb == 0) break;
-        SSE_AB2(pp, m1, m2, va, t1, t2);
-      }
-      _mm_store_si128((__m128i *)d8, vb);
-      d8 += 16;
-      s8 += 16;
-    }
-  } else {
-    while (d8 < (uint8_t *) rd.d_top) {
-      va = _mm_load_si128 ((__m128i *)(s8));
-      vb = _mm_setzero_si128 ();
-      tb = val;
-      while (1) {
-        if (tb & 1) vb = _mm_xor_si128(vb, va);
-        tb >>= 1;
-        if (tb == 0) break;
-        t1 = _mm_and_si128(_mm_slli_epi64(va, 1), m1);
-        t2 = _mm_and_si128(va, m2);
-        t2 = _mm_sub_epi64 (
-          _mm_slli_epi64(t2, 1), _mm_srli_epi64(t2, (GF_FIELD_WIDTH-1)));
-        va = _mm_xor_si128(t1, _mm_and_si128(t2, pp));
-      }
-      _mm_store_si128((__m128i *)d8, vb);
-      d8 += 16;
-      s8 += 16;
-    }
-  }
-  gf_do_final_region_alignment(&rd);
-#endif
-}
-*/
-
-#ifdef INTEL_SSE2
-static 
-void
-gf_w4_bytwo_b_sse_region_2_noxor(gf_region_data *rd, struct gf_bytwo_data *btd)
-{
-  uint8_t *d8, *s8;
-  __m128i pp, m1, t1, t2, va;
-
-  s8 = (uint8_t *) rd->s_start;
-  d8 = (uint8_t *) rd->d_start;
-
-  pp = _mm_set1_epi8(btd->prim_poly&0xff);
-  m1 = _mm_set1_epi8((btd->mask1)&0xff);
-
-  while (d8 < (uint8_t *) rd->d_top) {
-    va = _mm_load_si128 ((__m128i *)(s8));
-    SSE_AB2(pp, m1, va, t1, t2);
-    _mm_store_si128((__m128i *)d8, va);
-    d8 += 16;
-    s8 += 16;
-  }
-}
-#endif
-
-#ifdef INTEL_SSE2
-static 
-void
-gf_w4_bytwo_b_sse_region_2_xor(gf_region_data *rd, struct gf_bytwo_data *btd)
-{
-  uint8_t *d8, *s8;
-  __m128i pp, m1, t1, t2, va, vb;
-
-  s8 = (uint8_t *) rd->s_start;
-  d8 = (uint8_t *) rd->d_start;
-
-  pp = _mm_set1_epi8(btd->prim_poly&0xff);
-  m1 = _mm_set1_epi8((btd->mask1)&0xff);
-
-  while (d8 < (uint8_t *) rd->d_top) {
-    va = _mm_load_si128 ((__m128i *)(s8));
-    SSE_AB2(pp, m1, va, t1, t2);
-    vb = _mm_load_si128 ((__m128i *)(d8));
-    vb = _mm_xor_si128(vb, va);
-    _mm_store_si128((__m128i *)d8, vb);
-    d8 += 16;
-    s8 += 16;
-  }
-}
-#endif
-
-#ifdef INTEL_SSE2
-static 
-void
-gf_w4_bytwo_b_sse_region_4_noxor(gf_region_data *rd, struct gf_bytwo_data *btd)
-{
-  uint8_t *d8, *s8;
-  __m128i pp, m1, t1, t2, va;
-
-  s8 = (uint8_t *) rd->s_start;
-  d8 = (uint8_t *) rd->d_start;
-
-  pp = _mm_set1_epi8(btd->prim_poly&0xff);
-  m1 = _mm_set1_epi8((btd->mask1)&0xff);
-
-  while (d8 < (uint8_t *) rd->d_top) {
-    va = _mm_load_si128 ((__m128i *)(s8));
-    SSE_AB2(pp, m1, va, t1, t2);
-    SSE_AB2(pp, m1, va, t1, t2);
-    _mm_store_si128((__m128i *)d8, va);
-    d8 += 16;
-    s8 += 16;
-  }
-}
-#endif
-
-#ifdef INTEL_SSE2
-static 
-void
-gf_w4_bytwo_b_sse_region_4_xor(gf_region_data *rd, struct gf_bytwo_data *btd)
-{
-  uint8_t *d8, *s8;
-  __m128i pp, m1, t1, t2, va, vb;
-
-  s8 = (uint8_t *) rd->s_start;
-  d8 = (uint8_t *) rd->d_start;
-
-  pp = _mm_set1_epi8(btd->prim_poly&0xff);
-  m1 = _mm_set1_epi8((btd->mask1)&0xff);
-
-  while (d8 < (uint8_t *) rd->d_top) {
-    va = _mm_load_si128 ((__m128i *)(s8));
-    SSE_AB2(pp, m1, va, t1, t2);
-    SSE_AB2(pp, m1, va, t1, t2);
-    vb = _mm_load_si128 ((__m128i *)(d8));
-    vb = _mm_xor_si128(vb, va);
-    _mm_store_si128((__m128i *)d8, vb);
-    d8 += 16;
-    s8 += 16;
-  }
-}
-#endif
-
-
-#ifdef INTEL_SSE2
-static 
-void
-gf_w4_bytwo_b_sse_region_3_noxor(gf_region_data *rd, struct gf_bytwo_data *btd)
-{
-  uint8_t *d8, *s8;
-  __m128i pp, m1, t1, t2, va, vb;
-
-  s8 = (uint8_t *) rd->s_start;
-  d8 = (uint8_t *) rd->d_start;
-
-  pp = _mm_set1_epi8(btd->prim_poly&0xff);
-  m1 = _mm_set1_epi8((btd->mask1)&0xff);
-
-  while (d8 < (uint8_t *) rd->d_top) {
-    va = _mm_load_si128 ((__m128i *)(s8));
-    vb = va;
-    SSE_AB2(pp, m1, va, t1, t2);
-    va = _mm_xor_si128(va, vb);
-    _mm_store_si128((__m128i *)d8, va);
-    d8 += 16;
-    s8 += 16;
-  }
-}
-#endif
-
-#ifdef INTEL_SSE2
-static 
-void
-gf_w4_bytwo_b_sse_region_3_xor(gf_region_data *rd, struct gf_bytwo_data *btd)
-{
-  uint8_t *d8, *s8;
-  __m128i pp, m1, t1, t2, va, vb;
-
-  s8 = (uint8_t *) rd->s_start;
-  d8 = (uint8_t *) rd->d_start;
-
-  pp = _mm_set1_epi8(btd->prim_poly&0xff);
-  m1 = _mm_set1_epi8((btd->mask1)&0xff);
-
-  while (d8 < (uint8_t *) rd->d_top) {
-    va = _mm_load_si128 ((__m128i *)(s8));
-    vb = _mm_xor_si128(_mm_load_si128 ((__m128i *)(d8)), va);
-    SSE_AB2(pp, m1, va, t1, t2);
-    vb = _mm_xor_si128(vb, va);
-    _mm_store_si128((__m128i *)d8, vb);
-    d8 += 16;
-    s8 += 16;
-  }
-}
-#endif
-
-#ifdef INTEL_SSE2
-static 
-void
-gf_w4_bytwo_b_sse_region_5_noxor(gf_region_data *rd, struct gf_bytwo_data *btd)
-{
-  uint8_t *d8, *s8;
-  __m128i pp, m1, t1, t2, va, vb;
-
-  s8 = (uint8_t *) rd->s_start;
-  d8 = (uint8_t *) rd->d_start;
-
-  pp = _mm_set1_epi8(btd->prim_poly&0xff);
-  m1 = _mm_set1_epi8((btd->mask1)&0xff);
-
-  while (d8 < (uint8_t *) rd->d_top) {
-    va = _mm_load_si128 ((__m128i *)(s8));
-    vb = va;
-    SSE_AB2(pp, m1, va, t1, t2);
-    SSE_AB2(pp, m1, va, t1, t2);
-    va = _mm_xor_si128(va, vb);
-    _mm_store_si128((__m128i *)d8, va);
-    d8 += 16;
-    s8 += 16;
-  }
-}
-#endif
-
-#ifdef INTEL_SSE2
-static 
-void
-gf_w4_bytwo_b_sse_region_5_xor(gf_region_data *rd, struct gf_bytwo_data *btd)
-{
-  uint8_t *d8, *s8;
-  __m128i pp, m1, t1, t2, va, vb;
-
-  s8 = (uint8_t *) rd->s_start;
-  d8 = (uint8_t *) rd->d_start;
-
-  pp = _mm_set1_epi8(btd->prim_poly&0xff);
-  m1 = _mm_set1_epi8((btd->mask1)&0xff);
-
-  while (d8 < (uint8_t *) rd->d_top) {
-    va = _mm_load_si128 ((__m128i *)(s8));
-    vb = _mm_xor_si128(_mm_load_si128 ((__m128i *)(d8)), va);
-    SSE_AB2(pp, m1, va, t1, t2);
-    SSE_AB2(pp, m1, va, t1, t2);
-    vb = _mm_xor_si128(vb, va);
-    _mm_store_si128((__m128i *)d8, vb);
-    d8 += 16;
-    s8 += 16;
-  }
-}
-#endif
-
-#ifdef INTEL_SSE2
-static 
-void
-gf_w4_bytwo_b_sse_region_7_noxor(gf_region_data *rd, struct gf_bytwo_data *btd)
-{
-  uint8_t *d8, *s8;
-  __m128i pp, m1, t1, t2, va, vb;
-
-  s8 = (uint8_t *) rd->s_start;
-  d8 = (uint8_t *) rd->d_start;
-
-  pp = _mm_set1_epi8(btd->prim_poly&0xff);
-  m1 = _mm_set1_epi8((btd->mask1)&0xff);
-
-  while (d8 < (uint8_t *) rd->d_top) {
-    va = _mm_load_si128 ((__m128i *)(s8));
-    vb = va;
-    SSE_AB2(pp, m1, va, t1, t2);
-    vb = _mm_xor_si128(va, vb);
-    SSE_AB2(pp, m1, va, t1, t2);
-    va = _mm_xor_si128(va, vb);
-    _mm_store_si128((__m128i *)d8, va);
-    d8 += 16;
-    s8 += 16;
-  }
-}
-#endif
-
-#ifdef INTEL_SSE2
-static 
-void
-gf_w4_bytwo_b_sse_region_7_xor(gf_region_data *rd, struct gf_bytwo_data *btd)
-{
-  uint8_t *d8, *s8;
-  __m128i pp, m1, t1, t2, va, vb;
-
-  s8 = (uint8_t *) rd->s_start;
-  d8 = (uint8_t *) rd->d_start;
-
-  pp = _mm_set1_epi8(btd->prim_poly&0xff);
-  m1 = _mm_set1_epi8((btd->mask1)&0xff);
-
-  while (d8 < (uint8_t *) rd->d_top) {
-    va = _mm_load_si128 ((__m128i *)(s8));
-    vb = _mm_xor_si128(_mm_load_si128 ((__m128i *)(d8)), va);
-    SSE_AB2(pp, m1, va, t1, t2);
-    vb = _mm_xor_si128(vb, va);
-    SSE_AB2(pp, m1, va, t1, t2);
-    vb = _mm_xor_si128(vb, va);
-    _mm_store_si128((__m128i *)d8, vb);
-    d8 += 16;
-    s8 += 16;
-  }
-}
-#endif
-
-#ifdef INTEL_SSE2
-static 
-void
-gf_w4_bytwo_b_sse_region_6_noxor(gf_region_data *rd, struct gf_bytwo_data *btd)
-{
-  uint8_t *d8, *s8;
-  __m128i pp, m1, t1, t2, va, vb;
-
-  s8 = (uint8_t *) rd->s_start;
-  d8 = (uint8_t *) rd->d_start;
-
-  pp = _mm_set1_epi8(btd->prim_poly&0xff);
-  m1 = _mm_set1_epi8((btd->mask1)&0xff);
-
-  while (d8 < (uint8_t *) rd->d_top) {
-    va = _mm_load_si128 ((__m128i *)(s8));
-    SSE_AB2(pp, m1, va, t1, t2);
-    vb = va;
-    SSE_AB2(pp, m1, va, t1, t2);
-    va = _mm_xor_si128(va, vb);
-    _mm_store_si128((__m128i *)d8, va);
-    d8 += 16;
-    s8 += 16;
-  }
-}
-#endif
-
-#ifdef INTEL_SSE2
-static 
-void
-gf_w4_bytwo_b_sse_region_6_xor(gf_region_data *rd, struct gf_bytwo_data *btd)
-{
-  uint8_t *d8, *s8;
-  __m128i pp, m1, t1, t2, va, vb;
-
-  s8 = (uint8_t *) rd->s_start;
-  d8 = (uint8_t *) rd->d_start;
-
-  pp = _mm_set1_epi8(btd->prim_poly&0xff);
-  m1 = _mm_set1_epi8((btd->mask1)&0xff);
-
-  while (d8 < (uint8_t *) rd->d_top) {
-    va = _mm_load_si128 ((__m128i *)(s8));
-    SSE_AB2(pp, m1, va, t1, t2);
-    vb = _mm_xor_si128(_mm_load_si128 ((__m128i *)(d8)), va);
-    SSE_AB2(pp, m1, va, t1, t2);
-    vb = _mm_xor_si128(vb, va);
-    _mm_store_si128((__m128i *)d8, vb);
-    d8 += 16;
-    s8 += 16;
-  }
-}
-#endif
-
-#ifdef INTEL_SSE2
-static
-void 
-gf_w4_bytwo_b_sse_multiply_region(gf_t *gf, void *src, void *dest, gf_val_32_t val, int bytes, int xor)
-{
-  uint8_t *d8, *s8, tb;
-  __m128i pp, m1, m2, t1, t2, va, vb;
-  struct gf_bytwo_data *btd;
-  gf_region_data rd;
-    
-  if (val == 0) { gf_multby_zero(dest, bytes, xor); return; }
-  if (val == 1) { gf_multby_one(src, dest, bytes, xor); return; }
-
-  gf_set_region_data(&rd, gf, src, dest, bytes, val, xor, 16);
-  gf_do_initial_region_alignment(&rd);
-
-  s8 = (uint8_t *) rd.s_start;
-  d8 = (uint8_t *) rd.d_start;
-
-  btd = (struct gf_bytwo_data *) ((gf_internal_t *) (gf->scratch))->private;
-
-  switch (val) {
-    case 2:
-      if (!xor) {
-        gf_w4_bytwo_b_sse_region_2_noxor(&rd, btd);
-      } else {
-        gf_w4_bytwo_b_sse_region_2_xor(&rd, btd);
-      }
-      gf_do_final_region_alignment(&rd);
-      return;
-    case 3:
-      if (!xor) {
-        gf_w4_bytwo_b_sse_region_3_noxor(&rd, btd);
-      } else {
-        gf_w4_bytwo_b_sse_region_3_xor(&rd, btd);
-      }
-      gf_do_final_region_alignment(&rd);
-      return;
-    case 4:
-      if (!xor) {
-        gf_w4_bytwo_b_sse_region_4_noxor(&rd, btd);
-      } else {
-        gf_w4_bytwo_b_sse_region_4_xor(&rd, btd);
-      }
-      gf_do_final_region_alignment(&rd);
-      return;
-    case 5:
-      if (!xor) {
-        gf_w4_bytwo_b_sse_region_5_noxor(&rd, btd);
-      } else {
-        gf_w4_bytwo_b_sse_region_5_xor(&rd, btd);
-      }
-      gf_do_final_region_alignment(&rd);
-      return;
-    case 6:
-      if (!xor) {
-        gf_w4_bytwo_b_sse_region_6_noxor(&rd, btd);
-      } else {
-        gf_w4_bytwo_b_sse_region_6_xor(&rd, btd);
-      }
-      gf_do_final_region_alignment(&rd);
-      return;
-    case 7:
-      if (!xor) {
-        gf_w4_bytwo_b_sse_region_7_noxor(&rd, btd);
-      } else {
-        gf_w4_bytwo_b_sse_region_7_xor(&rd, btd);
-      }
-      gf_do_final_region_alignment(&rd);
-      return;
-  }
-
-  pp = _mm_set1_epi8(btd->prim_poly&0xff);
-  m1 = _mm_set1_epi8((btd->mask1)&0xff);
-  m2 = _mm_set1_epi8((btd->mask2)&0xff);
-
-  if (xor) {
-    while (d8 < (uint8_t *) rd.d_top) {
-      va = _mm_load_si128 ((__m128i *)(s8));
-      vb = _mm_load_si128 ((__m128i *)(d8));
-      tb = val;
-      while (1) {
-        if (tb & 1) vb = _mm_xor_si128(vb, va);
-        tb >>= 1;
-        if (tb == 0) break;
-        SSE_AB2(pp, m1, va, t1, t2);
-      }
-      _mm_store_si128((__m128i *)d8, vb);
-      d8 += 16;
-      s8 += 16;
-    }
-  } else {
-    while (d8 < (uint8_t *) rd.d_top) {
-      va = _mm_load_si128 ((__m128i *)(s8));
-      vb = _mm_setzero_si128 ();
-      tb = val;
-      while (1) {
-        if (tb & 1) vb = _mm_xor_si128(vb, va);
-        tb >>= 1;
-        if (tb == 0) break;
-        t1 = _mm_and_si128(_mm_slli_epi64(va, 1), m1);
-        t2 = _mm_and_si128(va, m2);
-        t2 = _mm_sub_epi64 (
-          _mm_slli_epi64(t2, 1), _mm_srli_epi64(t2, (GF_FIELD_WIDTH-1)));
-        va = _mm_xor_si128(t1, _mm_and_si128(t2, pp));
-      }
-      _mm_store_si128((__m128i *)d8, vb);
-      d8 += 16;
-      s8 += 16;
-    }
-  }
-  gf_do_final_region_alignment(&rd);
-}
-#endif
-
-static
-void 
-gf_w4_bytwo_b_nosse_multiply_region(gf_t *gf, void *src, void *dest, gf_val_32_t val, int bytes, int xor)
-{
-  uint64_t *s64, *d64, t1, t2, ta, tb, prod;
-  struct gf_bytwo_data *btd;
-  gf_region_data rd;
-
-  if (val == 0) { gf_multby_zero(dest, bytes, xor); return; }
-  if (val == 1) { gf_multby_one(src, dest, bytes, xor); return; }
-
-  gf_set_region_data(&rd, gf, src, dest, bytes, val, xor, 16);
-  gf_do_initial_region_alignment(&rd);
-
-  btd = (struct gf_bytwo_data *) ((gf_internal_t *) (gf->scratch))->private;
-  s64 = (uint64_t *) rd.s_start;
-  d64 = (uint64_t *) rd.d_start;
-
-  switch (val) {
-  case 1:
-    if (xor) {
-      while (d64 < (uint64_t *) rd.d_top) {
-        *d64 ^= *s64;
-        d64++;
-        s64++;
-      }
-    } else {
-      while (d64 < (uint64_t *) rd.d_top) {
-        *d64 = *s64;
-        d64++;
-        s64++;
-      }
-    }
-    break;
-  case 2:
-    if (xor) {
-      while (d64 < (uint64_t *) rd.d_top) {
-        ta = *s64;
-        AB2(btd->prim_poly, btd->mask1, btd->mask2, ta, t1, t2);
-        *d64 ^= ta;
-        d64++;
-        s64++;
-      }
-    } else {
-      while (d64 < (uint64_t *) rd.d_top) {
-        ta = *s64;
-        AB2(btd->prim_poly, btd->mask1, btd->mask2, ta, t1, t2);
-        *d64 = ta;
-        d64++;
-        s64++;
-      }
-    }
-    break; 
-  case 3:
-    if (xor) {
-      while (d64 < (uint64_t *) rd.d_top) {
-        ta = *s64;
-        prod = ta;
-        AB2(btd->prim_poly, btd->mask1, btd->mask2, ta, t1, t2);
-        *d64 ^= (ta ^ prod);
-        d64++;
-        s64++;
-      }
-    } else {
-      while (d64 < (uint64_t *) rd.d_top) {
-        ta = *s64;
-        prod = ta;
-        AB2(btd->prim_poly, btd->mask1, btd->mask2, ta, t1, t2);
-        *d64 = (ta ^ prod);
-        d64++;
-        s64++;
-      }
-    }
-    break; 
-  case 4:
-    if (xor) {
-      while (d64 < (uint64_t *) rd.d_top) {
-        ta = *s64;
-        AB2(btd->prim_poly, btd->mask1, btd->mask2, ta, t1, t2);
-        AB2(btd->prim_poly, btd->mask1, btd->mask2, ta, t1, t2);
-        *d64 ^= ta;
-        d64++;
-        s64++;
-      }
-    } else {
-      while (d64 < (uint64_t *) rd.d_top) {
-        ta = *s64;
-        AB2(btd->prim_poly, btd->mask1, btd->mask2, ta, t1, t2);
-        AB2(btd->prim_poly, btd->mask1, btd->mask2, ta, t1, t2);
-        *d64 = ta;
-        d64++;
-        s64++;
-      }
-    }
-    break; 
-  case 5:
-    if (xor) {
-      while (d64 < (uint64_t *) rd.d_top) {
-        ta = *s64;
-        prod = ta;
-        AB2(btd->prim_poly, btd->mask1, btd->mask2, ta, t1, t2);
-        AB2(btd->prim_poly, btd->mask1, btd->mask2, ta, t1, t2);
-        *d64 ^= (ta ^ prod);
-        d64++;
-        s64++;
-      }
-    } else {
-      while (d64 < (uint64_t *) rd.d_top) {
-        ta = *s64;
-        prod = ta;
-        AB2(btd->prim_poly, btd->mask1, btd->mask2, ta, t1, t2);
-        AB2(btd->prim_poly, btd->mask1, btd->mask2, ta, t1, t2);
-        *d64 = ta ^ prod;
-        d64++;
-        s64++;
-      }
-    }
-    break;
-  case 6:
-    if (xor) {
-      while (d64 < (uint64_t *) rd.d_top) {
-        ta = *s64;
-        AB2(btd->prim_poly, btd->mask1, btd->mask2, ta, t1, t2);
-        prod = ta;
-        AB2(btd->prim_poly, btd->mask1, btd->mask2, ta, t1, t2);
-        *d64 ^= (ta ^ prod);
-        d64++;
-        s64++;
-      }
-    } else {
-      while (d64 < (uint64_t *) rd.d_top) {
-        ta = *s64;
-        AB2(btd->prim_poly, btd->mask1, btd->mask2, ta, t1, t2);
-        prod = ta;
-        AB2(btd->prim_poly, btd->mask1, btd->mask2, ta, t1, t2);
-        *d64 = ta ^ prod;
-        d64++;
-        s64++;
-      }
-    }
-    break;
-  case 7:
-    if (xor) {
-      while (d64 < (uint64_t *) rd.d_top) {
-        ta = *s64;
-        prod = ta;
-        AB2(btd->prim_poly, btd->mask1, btd->mask2, ta, t1, t2);
-        prod ^= ta;
-        AB2(btd->prim_poly, btd->mask1, btd->mask2, ta, t1, t2);
-        *d64 ^= (ta ^ prod);
-        d64++;
-        s64++;
-      }
-    } else {
-      while (d64 < (uint64_t *) rd.d_top) {
-        ta = *s64;
-        prod = ta;
-        AB2(btd->prim_poly, btd->mask1, btd->mask2, ta, t1, t2);
-        prod ^= ta;
-        AB2(btd->prim_poly, btd->mask1, btd->mask2, ta, t1, t2);
-        *d64 = ta ^ prod;
-        d64++;
-        s64++;
-      }
-    }
-    break; 
-  case 8:
-    if (xor) {
-      while (d64 < (uint64_t *) rd.d_top) {
-        ta = *s64;
-        AB2(btd->prim_poly, btd->mask1, btd->mask2, ta, t1, t2);
-        AB2(btd->prim_poly, btd->mask1, btd->mask2, ta, t1, t2);
-        AB2(btd->prim_poly, btd->mask1, btd->mask2, ta, t1, t2);
-        *d64 ^= ta;
-        d64++;
-        s64++;
-      }
-    } else {
-      while (d64 < (uint64_t *) rd.d_top) {
-        ta = *s64;
-        AB2(btd->prim_poly, btd->mask1, btd->mask2, ta, t1, t2);
-        AB2(btd->prim_poly, btd->mask1, btd->mask2, ta, t1, t2);
-        AB2(btd->prim_poly, btd->mask1, btd->mask2, ta, t1, t2);
-        *d64 = ta;
-        d64++;
-        s64++;
-      }
-    }
-    break; 
-  case 9:
-    if (xor) {
-      while (d64 < (uint64_t *) rd.d_top) {
-        ta = *s64;
-        prod = ta;
-        AB2(btd->prim_poly, btd->mask1, btd->mask2, ta, t1, t2);
-        AB2(btd->prim_poly, btd->mask1, btd->mask2, ta, t1, t2);
-        AB2(btd->prim_poly, btd->mask1, btd->mask2, ta, t1, t2);
-        *d64 ^= (ta ^ prod);
-        d64++;
-        s64++;
-      }
-    } else {
-      while (d64 < (uint64_t *) rd.d_top) {
-        ta = *s64;
-        prod = ta;
-        AB2(btd->prim_poly, btd->mask1, btd->mask2, ta, t1, t2);
-        AB2(btd->prim_poly, btd->mask1, btd->mask2, ta, t1, t2);
-        AB2(btd->prim_poly, btd->mask1, btd->mask2, ta, t1, t2);
-        *d64 = (ta ^ prod);
-        d64++;
-        s64++;
-      }
-    }
-    break; 
-  case 10:
-    if (xor) {
-      while (d64 < (uint64_t *) rd.d_top) {
-        ta = *s64;
-        AB2(btd->prim_poly, btd->mask1, btd->mask2, ta, t1, t2);
-        prod = ta;
-        AB2(btd->prim_poly, btd->mask1, btd->mask2, ta, t1, t2);
-        AB2(btd->prim_poly, btd->mask1, btd->mask2, ta, t1, t2);
-        *d64 ^= (ta ^ prod);
-        d64++;
-        s64++;
-      }
-    } else {
-      while (d64 < (uint64_t *) rd.d_top) {
-        ta = *s64;
-        AB2(btd->prim_poly, btd->mask1, btd->mask2, ta, t1, t2);
-        prod = ta;
-        AB2(btd->prim_poly, btd->mask1, btd->mask2, ta, t1, t2);
-        AB2(btd->prim_poly, btd->mask1, btd->mask2, ta, t1, t2);
-        *d64 = (ta ^ prod);
-        d64++;
-        s64++;
-      }
-    }
-    break; 
-  case 11:
-    if (xor) {
-      while (d64 < (uint64_t *) rd.d_top) {
-        ta = *s64;
-        prod = ta;
-        AB2(btd->prim_poly, btd->mask1, btd->mask2, ta, t1, t2);
-        prod ^= ta;
-        AB2(btd->prim_poly, btd->mask1, btd->mask2, ta, t1, t2);
-        AB2(btd->prim_poly, btd->mask1, btd->mask2, ta, t1, t2);
-        *d64 ^= (ta ^ prod);
-        d64++;
-        s64++;
-      }
-    } else {
-      while (d64 < (uint64_t *) rd.d_top) {
-        ta = *s64;
-        prod = ta;
-        AB2(btd->prim_poly, btd->mask1, btd->mask2, ta, t1, t2);
-        prod ^= ta;
-        AB2(btd->prim_poly, btd->mask1, btd->mask2, ta, t1, t2);
-        AB2(btd->prim_poly, btd->mask1, btd->mask2, ta, t1, t2);
-        *d64 = (ta ^ prod);
-        d64++;
-        s64++;
-      }
-    }
-    break; 
-  case 12:
-    if (xor) {
-      while (d64 < (uint64_t *) rd.d_top) {
-        ta = *s64;
-        AB2(btd->prim_poly, btd->mask1, btd->mask2, ta, t1, t2);
-        AB2(btd->prim_poly, btd->mask1, btd->mask2, ta, t1, t2);
-        prod = ta;
-        AB2(btd->prim_poly, btd->mask1, btd->mask2, ta, t1, t2);
-        *d64 ^= (ta ^ prod);
-        d64++;
-        s64++;
-      }
-    } else {
-      while (d64 < (uint64_t *) rd.d_top) {
-        ta = *s64;
-        AB2(btd->prim_poly, btd->mask1, btd->mask2, ta, t1, t2);
-        AB2(btd->prim_poly, btd->mask1, btd->mask2, ta, t1, t2);
-        prod = ta;
-        AB2(btd->prim_poly, btd->mask1, btd->mask2, ta, t1, t2);
-        *d64 = (ta ^ prod);
-        d64++;
-        s64++;
-      }
-    }
-    break; 
-  case 13:
-    if (xor) {
-      while (d64 < (uint64_t *) rd.d_top) {
-        ta = *s64;
-        prod = ta;
-        AB2(btd->prim_poly, btd->mask1, btd->mask2, ta, t1, t2);
-        AB2(btd->prim_poly, btd->mask1, btd->mask2, ta, t1, t2);
-        prod ^= ta;
-        AB2(btd->prim_poly, btd->mask1, btd->mask2, ta, t1, t2);
-        *d64 ^= (ta ^ prod);
-        d64++;
-        s64++;
-      }
-    } else {
-      while (d64 < (uint64_t *) rd.d_top) {
-        ta = *s64;
-        prod = ta;
-        AB2(btd->prim_poly, btd->mask1, btd->mask2, ta, t1, t2);
-        AB2(btd->prim_poly, btd->mask1, btd->mask2, ta, t1, t2);
-        prod ^= ta;
-        AB2(btd->prim_poly, btd->mask1, btd->mask2, ta, t1, t2);
-        *d64 = (ta ^ prod);
-        d64++;
-        s64++;
-      }
-    }
-    break; 
-  case 14:
-    if (xor) {
-      while (d64 < (uint64_t *) rd.d_top) {
-        ta = *s64;
-        AB2(btd->prim_poly, btd->mask1, btd->mask2, ta, t1, t2);
-        prod = ta;
-        AB2(btd->prim_poly, btd->mask1, btd->mask2, ta, t1, t2);
-        prod ^= ta;
-        AB2(btd->prim_poly, btd->mask1, btd->mask2, ta, t1, t2);
-        *d64 ^= (ta ^ prod);
-        d64++;
-        s64++;
-      }
-    } else {
-      while (d64 < (uint64_t *) rd.d_top) {
-        ta = *s64;
-        AB2(btd->prim_poly, btd->mask1, btd->mask2, ta, t1, t2);
-        prod = ta;
-        AB2(btd->prim_poly, btd->mask1, btd->mask2, ta, t1, t2);
-        prod ^= ta;
-        AB2(btd->prim_poly, btd->mask1, btd->mask2, ta, t1, t2);
-        *d64 = (ta ^ prod);
-        d64++;
-        s64++;
-      }
-    }
-    break; 
-  case 15:
-    if (xor) {
-      while (d64 < (uint64_t *) rd.d_top) {
-        ta = *s64;
-        prod = ta;
-        AB2(btd->prim_poly, btd->mask1, btd->mask2, ta, t1, t2);
-        prod ^= ta;
-        AB2(btd->prim_poly, btd->mask1, btd->mask2, ta, t1, t2);
-        prod ^= ta;
-        AB2(btd->prim_poly, btd->mask1, btd->mask2, ta, t1, t2);
-        *d64 ^= (ta ^ prod);
-        d64++;
-        s64++;
-      }
-    } else {
-      while (d64 < (uint64_t *) rd.d_top) {
-        ta = *s64;
-        prod = ta;
-        AB2(btd->prim_poly, btd->mask1, btd->mask2, ta, t1, t2);
-        prod ^= ta;
-        AB2(btd->prim_poly, btd->mask1, btd->mask2, ta, t1, t2);
-        prod ^= ta;
-        AB2(btd->prim_poly, btd->mask1, btd->mask2, ta, t1, t2);
-        *d64 = (ta ^ prod);
-        d64++;
-        s64++;
-      }
-    }
-    break; 
-  default:
-    if (xor) {
-      while (d64 < (uint64_t *) rd.d_top) {
-        prod = *d64 ;
-        ta = *s64;
-        tb = val;
-        while (1) {
-          if (tb & 1) prod ^= ta;
-          tb >>= 1;
-          if (tb == 0) break;
-          AB2(btd->prim_poly, btd->mask1, btd->mask2, ta, t1, t2);
-        }
-        *d64 = prod;
-        d64++;
-        s64++;
-      }
-    } else {
-      while (d64 < (uint64_t *) rd.d_top) {
-        prod = 0 ;
-        ta = *s64;
-        tb = val;
-        while (1) {
-          if (tb & 1) prod ^= ta;
-          tb >>= 1;
-          if (tb == 0) break;
-          AB2(btd->prim_poly, btd->mask1, btd->mask2, ta, t1, t2);
-        }
-        *d64 = prod;
-        d64++;
-        s64++;
-      }
-    }
-    break;
-  }
-  gf_do_final_region_alignment(&rd);
-}
-
-static 
-int gf_w4_bytwo_init(gf_t *gf)
-{
-  gf_internal_t *h;
-  uint64_t ip, m1, m2;
-  struct gf_bytwo_data *btd;
-
-  h = (gf_internal_t *) gf->scratch;
-  btd = (struct gf_bytwo_data *) (h->private);
-  ip = h->prim_poly & 0xf;
-  m1 = 0xe;
-  m2 = 0x8;
-  btd->prim_poly = 0;
-  btd->mask1 = 0;
-  btd->mask2 = 0;
-
-  while (ip != 0) {
-    btd->prim_poly |= ip;
-    btd->mask1 |= m1;
-    btd->mask2 |= m2;
-    ip <<= GF_FIELD_WIDTH;
-    m1 <<= GF_FIELD_WIDTH;
-    m2 <<= GF_FIELD_WIDTH;
-  }
-
-  if (h->mult_type == GF_MULT_BYTWO_p) {
-    gf->multiply.w32 = gf_w4_bytwo_p_multiply;
-    #ifdef INTEL_SSE2
-      if (h->region_type & GF_REGION_NOSIMD)
-        gf->multiply_region.w32 = gf_w4_bytwo_p_nosse_multiply_region;
-      else
-        gf->multiply_region.w32 = gf_w4_bytwo_p_sse_multiply_region;
-    #else
-      gf->multiply_region.w32 = gf_w4_bytwo_p_nosse_multiply_region;
-      if (h->region_type & GF_REGION_SIMD)
-        return 0;
-    #endif
-  } else {
-    gf->multiply.w32 = gf_w4_bytwo_b_multiply;
-    #ifdef INTEL_SSE2
-      if (h->region_type & GF_REGION_NOSIMD)
-        gf->multiply_region.w32 = gf_w4_bytwo_b_nosse_multiply_region;
-      else
-        gf->multiply_region.w32 = gf_w4_bytwo_b_sse_multiply_region;
-    #else
-      gf->multiply_region.w32 = gf_w4_bytwo_b_nosse_multiply_region;
-      if (h->region_type & GF_REGION_SIMD)
-        return 0;
-    #endif
-  }
-  return 1;
-}
-
-
-static 
-int gf_w4_cfm_init(gf_t *gf)
-{
-#if defined(INTEL_SSE4_PCLMUL)
-  gf->multiply.w32 = gf_w4_clm_multiply;
-  return 1;
-#elif defined(ARM_NEON)
-  return gf_w4_neon_cfm_init(gf);
-#endif
-  return 0;
-}
-
-static 
-int gf_w4_shift_init(gf_t *gf)
-{
-  gf->multiply.w32 = gf_w4_shift_multiply;
-  return 1;
-}
-
-/* JSP: I'm putting all error-checking into gf_error_check(), so you don't 
-   have to do error checking in scratch_size or in init */
-
-int gf_w4_scratch_size(int mult_type, int region_type, int divide_type, int arg1, int arg2)
-{
-  int issse3 = 0, isneon = 0;
-
-#ifdef INTEL_SSSE3
-  issse3 = 1;
-#endif
-#ifdef ARM_NEON
-  isneon = 1;
-#endif
-
-  switch(mult_type)
-  {
-    case GF_MULT_BYTWO_p:
-    case GF_MULT_BYTWO_b:
-      return sizeof(gf_internal_t) + sizeof(struct gf_bytwo_data);
-      break;
-    case GF_MULT_DEFAULT:
-    case GF_MULT_TABLE:
-      if (region_type == GF_REGION_CAUCHY) {
-        return sizeof(gf_internal_t) + sizeof(struct gf_single_table_data) + 64;
-      }
-
-      if (mult_type == GF_MULT_DEFAULT && !(issse3 || isneon))
-          region_type = GF_REGION_DOUBLE_TABLE;
-
-      if (region_type & GF_REGION_DOUBLE_TABLE) {
-        return sizeof(gf_internal_t) + sizeof(struct gf_double_table_data) + 64;
-      } else if (region_type & GF_REGION_QUAD_TABLE) {
-        if ((region_type & GF_REGION_LAZY) == 0) {
-          return sizeof(gf_internal_t) + sizeof(struct gf_quad_table_data) + 64;
-        } else {
-          return sizeof(gf_internal_t) + sizeof(struct gf_quad_table_lazy_data) + 64;
-        }
-      } else {
-        return sizeof(gf_internal_t) + sizeof(struct gf_single_table_data) + 64;
-      }
-      break;
-
-    case GF_MULT_LOG_TABLE:
-      return sizeof(gf_internal_t) + sizeof(struct gf_logtable_data) + 64;
-      break;
-    case GF_MULT_CARRY_FREE:
-      return sizeof(gf_internal_t);
-      break;
-    case GF_MULT_SHIFT:
-      return sizeof(gf_internal_t);
-      break;
-    default:
-      return 0;
-   }
-  return 0;
-}
-
-int
-gf_w4_init (gf_t *gf)
-{
-  gf_internal_t *h;
-
-  h = (gf_internal_t *) gf->scratch;
-  if (h->prim_poly == 0) h->prim_poly = 0x13;
-  h->prim_poly |= 0x10;
-  gf->multiply.w32 = NULL;
-  gf->divide.w32 = NULL;
-  gf->inverse.w32 = NULL;
-  gf->multiply_region.w32 = NULL;
-  gf->extract_word.w32 = gf_w4_extract_word;
-
-  switch(h->mult_type) {
-    case GF_MULT_CARRY_FREE: if (gf_w4_cfm_init(gf) == 0) return 0; break;
-    case GF_MULT_SHIFT:      if (gf_w4_shift_init(gf) == 0) return 0; break;
-    case GF_MULT_BYTWO_p:   
-    case GF_MULT_BYTWO_b:    if (gf_w4_bytwo_init(gf) == 0) return 0; break;
-    case GF_MULT_LOG_TABLE:  if (gf_w4_log_init(gf) == 0) return 0; break;
-    case GF_MULT_DEFAULT:   
-    case GF_MULT_TABLE:      if (gf_w4_table_init(gf) == 0) return 0; break;
-    default: return 0;
-  }
-
-  if (h->divide_type == GF_DIVIDE_EUCLID) {
-    gf->divide.w32 = gf_w4_divide_from_inverse;
-    gf->inverse.w32 = gf_w4_euclid;
-  } else if (h->divide_type == GF_DIVIDE_MATRIX) {
-    gf->divide.w32 = gf_w4_divide_from_inverse;
-    gf->inverse.w32 = gf_w4_matrix;
-  }
-
-  if (gf->divide.w32 == NULL) {
-    gf->divide.w32 = gf_w4_divide_from_inverse;
-    if (gf->inverse.w32 == NULL) gf->inverse.w32 = gf_w4_euclid;
-  }
-
-  if (gf->inverse.w32 == NULL)  gf->inverse.w32 = gf_w4_inverse_from_divide;
-
-  if (h->region_type == GF_REGION_CAUCHY) {
-    gf->multiply_region.w32 = gf_wgen_cauchy_region;
-    gf->extract_word.w32 = gf_wgen_extract_word;
-  }
-
-  if (gf->multiply_region.w32 == NULL) {
-    gf->multiply_region.w32 = gf_w4_multiply_region_from_single;
-  }
-
-  return 1;
-}
-
-/* Inline setup functions */
-
-uint8_t *gf_w4_get_mult_table(gf_t *gf)
-{
-  gf_internal_t *h;
-  struct gf_single_table_data *std;
-  
-  h = (gf_internal_t *) gf->scratch;
-  if (gf->multiply.w32 == gf_w4_single_table_multiply) {
-    std = (struct gf_single_table_data *) h->private;
-    return (uint8_t *) std->mult;
-  } 
-  return NULL;
-}
-    
-uint8_t *gf_w4_get_div_table(gf_t *gf)
-{
-  gf_internal_t *h;
-  struct gf_single_table_data *std;
-  
-  h = (gf_internal_t *) gf->scratch;
-  if (gf->multiply.w32 == gf_w4_single_table_multiply) {
-    std = (struct gf_single_table_data *) h->private;
-    return (uint8_t *) std->div;
-  } 
-  return NULL;
-}
-
diff --git a/src/erasure-code/jerasure/gf-complete/src/gf_w64.c b/src/erasure-code/jerasure/gf-complete/src/gf_w64.c
deleted file mode 100644
index ba75d8c..0000000
--- a/src/erasure-code/jerasure/gf-complete/src/gf_w64.c
+++ /dev/null
@@ -1,2218 +0,0 @@
-/*
- * GF-Complete: A Comprehensive Open Source Library for Galois Field Arithmetic
- * James S. Plank, Ethan L. Miller, Kevin M. Greenan,
- * Benjamin A. Arnold, John A. Burnum, Adam W. Disney, Allen C. McBride.
- *
- * gf_w64.c
- *
- * Routines for 64-bit Galois fields
- */
-
-#include "gf_int.h"
-#include <stdio.h>
-#include <stdlib.h>
-#include "gf_w64.h"
-
-static
-inline
-gf_val_64_t gf_w64_inverse_from_divide (gf_t *gf, gf_val_64_t a)
-{
-  return gf->divide.w64(gf, 1, a);
-}
-
-#define MM_PRINT8(s, r) { uint8_t blah[16], ii; printf("%-12s", s); _mm_storeu_si128((__m128i *)blah, r); for (ii = 0; ii < 16; ii += 1) printf("%s%02x", (ii%4==0) ? "   " : " ", blah[15-ii]); printf("\n"); }
-
-static
-inline
-gf_val_64_t gf_w64_divide_from_inverse (gf_t *gf, gf_val_64_t a, gf_val_64_t b)
-{
-  b = gf->inverse.w64(gf, b);
-  return gf->multiply.w64(gf, a, b);
-}
-
-static
-void
-gf_w64_multiply_region_from_single(gf_t *gf, void *src, void *dest, gf_val_64_t val, int bytes, int
-xor)
-{
-  uint32_t i;
-  gf_val_64_t *s64;
-  gf_val_64_t *d64;
-
-  s64 = (gf_val_64_t *) src;
-  d64 = (gf_val_64_t *) dest;
-
-  if (val == 0) { gf_multby_zero(dest, bytes, xor); return; }
-  if (val == 1) { gf_multby_one(src, dest, bytes, xor); return; }
-
-  if (xor) {
-    for (i = 0; i < bytes/sizeof(gf_val_64_t); i++) {
-      d64[i] ^= gf->multiply.w64(gf, val, s64[i]);
-    }
-  } else {
-    for (i = 0; i < bytes/sizeof(gf_val_64_t); i++) {
-      d64[i] = gf->multiply.w64(gf, val, s64[i]);
-    }
-  }
-}
-
-#if defined(INTEL_SSE4_PCLMUL) 
-static
-void
-gf_w64_clm_multiply_region_from_single_2(gf_t *gf, void *src, void *dest, gf_val_64_t val, int bytes, int
-xor)
-{
-  gf_val_64_t *s64, *d64, *top;
-  gf_region_data rd;
-
-  __m128i         a, b;
-  __m128i         result, r1;
-  __m128i         prim_poly;
-  __m128i         w;
-  __m128i         m1, m3, m4;
-  gf_internal_t * h = gf->scratch;
-  
-  if (val == 0) { gf_multby_zero(dest, bytes, xor); return; }
-  if (val == 1) { gf_multby_one(src, dest, bytes, xor); return; }
-  
-  gf_set_region_data(&rd, gf, src, dest, bytes, val, xor, 16);
-  gf_do_initial_region_alignment(&rd);
-
-  prim_poly = _mm_set_epi32(0, 0, 0, (uint32_t)(h->prim_poly & 0xffffffffULL));
-  b = _mm_insert_epi64 (_mm_setzero_si128(), val, 0);
-  m1 = _mm_set_epi32(0, 0, 0, (uint32_t)0xffffffff);
-  m3 = _mm_slli_si128(m1, 8);
-  m4 = _mm_slli_si128(m3, 4);
-
-  s64 = (gf_val_64_t *) rd.s_start;
-  d64 = (gf_val_64_t *) rd.d_start;
-  top = (gf_val_64_t *) rd.d_top;
-
-  if (xor) {
-    while (d64 != top) {
-      a = _mm_load_si128((__m128i *) s64);  
-      result = _mm_clmulepi64_si128 (a, b, 1);
-
-      w = _mm_clmulepi64_si128 (_mm_and_si128(result, m4), prim_poly, 1);
-      result = _mm_xor_si128 (result, w);
-      w = _mm_clmulepi64_si128 (_mm_and_si128(result, m3), prim_poly, 1);
-      r1 = _mm_xor_si128 (result, w);
-
-      result = _mm_clmulepi64_si128 (a, b, 0);
-
-      w = _mm_clmulepi64_si128 (_mm_and_si128(result, m4), prim_poly, 1);
-      result = _mm_xor_si128 (result, w);
-
-      w = _mm_clmulepi64_si128 (_mm_and_si128(result, m3), prim_poly, 1);
-      result = _mm_xor_si128 (result, w);
-
-      result = _mm_unpacklo_epi64(result, r1);
-      
-      r1 = _mm_load_si128((__m128i *) d64);
-      result = _mm_xor_si128(r1, result);
-      _mm_store_si128((__m128i *) d64, result);
-      d64 += 2;
-      s64 += 2;
-    }
-  } else {
-    while (d64 != top) {
-      
-      a = _mm_load_si128((__m128i *) s64);  
-      result = _mm_clmulepi64_si128 (a, b, 1);
-
-      w = _mm_clmulepi64_si128 (_mm_and_si128(result, m4), prim_poly, 1);
-      result = _mm_xor_si128 (result, w);
-      w = _mm_clmulepi64_si128 (_mm_and_si128(result, m3), prim_poly, 1);
-      r1 = _mm_xor_si128 (result, w);
-
-      result = _mm_clmulepi64_si128 (a, b, 0);
-
-      w = _mm_clmulepi64_si128 (_mm_and_si128(result, m4), prim_poly, 1);
-      result = _mm_xor_si128 (result, w);
-      w = _mm_clmulepi64_si128 (_mm_and_si128(result, m3), prim_poly, 1);
-      result = _mm_xor_si128 (result, w);
-      
-      result = _mm_unpacklo_epi64(result, r1);
-
-      _mm_store_si128((__m128i *) d64, result);
-      d64 += 2;
-      s64 += 2;
-    }
-  }
-  gf_do_final_region_alignment(&rd);
-}
-#endif
-
-#if defined(INTEL_SSE4_PCLMUL)
-static
-void
-gf_w64_clm_multiply_region_from_single_4(gf_t *gf, void *src, void *dest, gf_val_64_t val, int bytes, int
-xor)
-{
-  gf_val_64_t *s64, *d64, *top;
-  gf_region_data rd;
-
-  __m128i         a, b;
-  __m128i         result, r1;
-  __m128i         prim_poly;
-  __m128i         w;
-  __m128i         m1, m3, m4;
-  gf_internal_t * h = gf->scratch;
-  
-  if (val == 0) { gf_multby_zero(dest, bytes, xor); return; }
-  if (val == 1) { gf_multby_one(src, dest, bytes, xor); return; }
-  
-  gf_set_region_data(&rd, gf, src, dest, bytes, val, xor, 16);
-  gf_do_initial_region_alignment(&rd);
-  
-  prim_poly = _mm_set_epi32(0, 0, 0, (uint32_t)(h->prim_poly & 0xffffffffULL));
-  b = _mm_insert_epi64 (_mm_setzero_si128(), val, 0);
-  m1 = _mm_set_epi32(0, 0, 0, (uint32_t)0xffffffff);
-  m3 = _mm_slli_si128(m1, 8);
-  m4 = _mm_slli_si128(m3, 4);
-
-  s64 = (gf_val_64_t *) rd.s_start;
-  d64 = (gf_val_64_t *) rd.d_start;
-  top = (gf_val_64_t *) rd.d_top;
-
-  if (xor) {
-    while (d64 != top) {
-      a = _mm_load_si128((__m128i *) s64);
-      result = _mm_clmulepi64_si128 (a, b, 1);
-
-      w = _mm_clmulepi64_si128 (_mm_and_si128(result, m4), prim_poly, 1);
-      result = _mm_xor_si128 (result, w);
-      w = _mm_clmulepi64_si128 (_mm_and_si128(result, m3), prim_poly, 1);
-      r1 = _mm_xor_si128 (result, w);
-
-      result = _mm_clmulepi64_si128 (a, b, 0);
-
-      w = _mm_clmulepi64_si128 (_mm_and_si128(result, m4), prim_poly, 1);
-      result = _mm_xor_si128 (result, w);
-
-      w = _mm_clmulepi64_si128 (_mm_and_si128(result, m3), prim_poly, 1);
-      result = _mm_xor_si128 (result, w);
-
-      result = _mm_unpacklo_epi64(result, r1);
-
-      r1 = _mm_load_si128((__m128i *) d64);
-      result = _mm_xor_si128(r1, result);
-      _mm_store_si128((__m128i *) d64, result);
-      d64 += 2;
-      s64 += 2;
-    }
-  } else {
-    while (d64 != top) {
-      a = _mm_load_si128((__m128i *) s64);
-      result = _mm_clmulepi64_si128 (a, b, 1);
-
-      w = _mm_clmulepi64_si128 (_mm_and_si128(result, m4), prim_poly, 1);
-      result = _mm_xor_si128 (result, w);
-      w = _mm_clmulepi64_si128 (_mm_and_si128(result, m3), prim_poly, 1);
-      r1 = _mm_xor_si128 (result, w);
-
-      result = _mm_clmulepi64_si128 (a, b, 0);
-
-      w = _mm_clmulepi64_si128 (_mm_and_si128(result, m4), prim_poly, 1);
-      result = _mm_xor_si128 (result, w);
-      w = _mm_clmulepi64_si128 (_mm_and_si128(result, m3), prim_poly, 1);
-      result = _mm_xor_si128 (result, w);
-
-      result = _mm_unpacklo_epi64(result, r1);
-
-      _mm_store_si128((__m128i *) d64, result);
-      d64 += 2;
-      s64 += 2; 
-    }
-  }
-  gf_do_final_region_alignment(&rd);
-}
-#endif
-
-static
-  inline
-gf_val_64_t gf_w64_euclid (gf_t *gf, gf_val_64_t b)
-{
-  gf_val_64_t e_i, e_im1, e_ip1;
-  gf_val_64_t d_i, d_im1, d_ip1;
-  gf_val_64_t y_i, y_im1, y_ip1;
-  gf_val_64_t c_i;
-  gf_val_64_t one = 1;
-
-  if (b == 0) return -1;
-  e_im1 = ((gf_internal_t *) (gf->scratch))->prim_poly;
-  e_i = b;
-  d_im1 = 64;
-  for (d_i = d_im1-1; ((one << d_i) & e_i) == 0; d_i--) ;
-  y_i = 1;
-  y_im1 = 0;
-
-  while (e_i != 1) {
-
-    e_ip1 = e_im1;
-    d_ip1 = d_im1;
-    c_i = 0;
-
-    while (d_ip1 >= d_i) {
-      c_i ^= (one << (d_ip1 - d_i));
-      e_ip1 ^= (e_i << (d_ip1 - d_i));
-      d_ip1--;
-      if (e_ip1 == 0) return 0;
-      while ((e_ip1 & (one << d_ip1)) == 0) d_ip1--;
-    }
-
-    y_ip1 = y_im1 ^ gf->multiply.w64(gf, c_i, y_i);
-    y_im1 = y_i;
-    y_i = y_ip1;
-
-    e_im1 = e_i;
-    d_im1 = d_i;
-    e_i = e_ip1;
-    d_i = d_ip1;
-  }
-
-  return y_i;
-}
-
-/* JSP: GF_MULT_SHIFT: The world's dumbest multiplication algorithm.  I only
-   include it for completeness.  It does have the feature that it requires no
-   extra memory.  
-*/
-
-static
-inline
-gf_val_64_t
-gf_w64_shift_multiply (gf_t *gf, gf_val_64_t a64, gf_val_64_t b64)
-{
-  uint64_t pl, pr, ppl, ppr, i, a, bl, br, one, lbit;
-  gf_internal_t *h;
-
-  h = (gf_internal_t *) gf->scratch;
-  
-  /* Allen: set leading one of primitive polynomial */
-  
-  a = a64;
-  bl = 0;
-  br = b64;
-  one = 1;
-  lbit = (one << 63);
-
-  pl = 0; /* Allen: left side of product */
-  pr = 0; /* Allen: right side of product */
-
-  /* Allen: unlike the corresponding functions for smaller word sizes,
-   * this loop carries out the initial carryless multiply by
-   * shifting b itself rather than simply looking at successively
-   * higher shifts of b */
-  
-  for (i = 0; i < GF_FIELD_WIDTH; i++) {
-    if (a & (one << i)) {
-      pl ^= bl;
-      pr ^= br;
-    }
-
-    bl <<= 1;
-    if (br & lbit) bl ^= 1;
-    br <<= 1;
-  }
-
-  /* Allen: the name of the variable "one" is no longer descriptive at this point */
-  
-  one = lbit >> 1;
-  ppl = (h->prim_poly >> 2) | one;
-  ppr = (h->prim_poly << (GF_FIELD_WIDTH-2));
-  while (one != 0) {
-    if (pl & one) {
-      pl ^= ppl;
-      pr ^= ppr;
-    }
-    one >>= 1;
-    ppr >>= 1;
-    if (ppl & 1) ppr ^= lbit;
-    ppl >>= 1;
-  }
-  return pr;
-}
-
-/*
- * ELM: Use the Intel carryless multiply instruction to do very fast 64x64 multiply.
- */
-
-static
-inline
-gf_val_64_t
-gf_w64_clm_multiply_2 (gf_t *gf, gf_val_64_t a64, gf_val_64_t b64)
-{
-       gf_val_64_t rv = 0;
-
-#if defined(INTEL_SSE4_PCLMUL) 
-
-        __m128i         a, b;
-        __m128i         result;
-        __m128i         prim_poly;
-        __m128i         v, w;
-        gf_internal_t * h = gf->scratch;
-
-        a = _mm_insert_epi64 (_mm_setzero_si128(), a64, 0);
-        b = _mm_insert_epi64 (a, b64, 0); 
-        prim_poly = _mm_set_epi32(0, 0, 0, (uint32_t)(h->prim_poly & 0xffffffffULL));
-        /* Do the initial multiply */
-   
-        result = _mm_clmulepi64_si128 (a, b, 0);
-        
-        /* Mask off the high order 32 bits using subtraction of the polynomial.
-         * NOTE: this part requires that the polynomial have at least 32 leading 0 bits.
-         */
-
-        /* Adam: We cant include the leading one in the 64 bit pclmul,
-         so we need to split up the high 8 bytes of the result into two 
-         parts before we multiply them with the prim_poly.*/
-
-        v = _mm_insert_epi32 (_mm_srli_si128 (result, 8), 0, 0);
-        w = _mm_clmulepi64_si128 (prim_poly, v, 0);
-        result = _mm_xor_si128 (result, w);
-        v = _mm_insert_epi32 (_mm_srli_si128 (result, 8), 0, 1);
-        w = _mm_clmulepi64_si128 (prim_poly, v, 0);
-        result = _mm_xor_si128 (result, w);
-
-        rv = ((gf_val_64_t)_mm_extract_epi64(result, 0));
-#endif
-        return rv;
-}
- 
-static
-inline
-gf_val_64_t
-gf_w64_clm_multiply_4 (gf_t *gf, gf_val_64_t a64, gf_val_64_t b64)
-{
-  gf_val_64_t rv = 0;
-
-#if defined(INTEL_SSE4_PCLMUL) 
-
-  __m128i         a, b;
-  __m128i         result;
-  __m128i         prim_poly;
-  __m128i         v, w;
-  gf_internal_t * h = gf->scratch;
-
-  a = _mm_insert_epi64 (_mm_setzero_si128(), a64, 0);
-  b = _mm_insert_epi64 (a, b64, 0);
-  prim_poly = _mm_set_epi32(0, 0, 0, (uint32_t)(h->prim_poly & 0xffffffffULL));
- 
-  /* Do the initial multiply */
-  
-  result = _mm_clmulepi64_si128 (a, b, 0);
-
-  v = _mm_insert_epi32 (_mm_srli_si128 (result, 8), 0, 0);
-  w = _mm_clmulepi64_si128 (prim_poly, v, 0);
-  result = _mm_xor_si128 (result, w);
-  v = _mm_insert_epi32 (_mm_srli_si128 (result, 8), 0, 1);
-  w = _mm_clmulepi64_si128 (prim_poly, v, 0);
-  result = _mm_xor_si128 (result, w);
-  
-  v = _mm_insert_epi32 (_mm_srli_si128 (result, 8), 0, 0);
-  w = _mm_clmulepi64_si128 (prim_poly, v, 0);
-  result = _mm_xor_si128 (result, w);
-  v = _mm_insert_epi32 (_mm_srli_si128 (result, 8), 0, 1);
-  w = _mm_clmulepi64_si128 (prim_poly, v, 0);
-  result = _mm_xor_si128 (result, w);
-
-  rv = ((gf_val_64_t)_mm_extract_epi64(result, 0));
-#endif
-  return rv;
-}
-
-
-  void
-gf_w64_clm_multiply_region(gf_t *gf, void *src, void *dest, uint64_t val, int bytes, int xor)
-{
-#if defined(INTEL_SSE4_PCLMUL) 
-  gf_internal_t *h;
-  uint8_t *s8, *d8, *dtop;
-  gf_region_data rd;
-  __m128i  v, b, m, prim_poly, c, fr, w, result;
-
-  if (val == 0) { gf_multby_zero(dest, bytes, xor); return; }
-  if (val == 1) { gf_multby_one(src, dest, bytes, xor); return; }
-
-  h = (gf_internal_t *) gf->scratch;
-
-  gf_set_region_data(&rd, gf, src, dest, bytes, val, xor, 16);
-  gf_do_initial_region_alignment(&rd);
-
-  s8 = (uint8_t *) rd.s_start;
-  d8 = (uint8_t *) rd.d_start;
-  dtop = (uint8_t *) rd.d_top;
-
-  v = _mm_insert_epi64(_mm_setzero_si128(), val, 0);
-  m = _mm_set_epi32(0, 0, 0xffffffff, 0xffffffff);
-  prim_poly = _mm_set_epi32(0, 0, 0, (uint32_t)(h->prim_poly & 0xffffffffULL));
-
-  if (xor) {
-    while (d8 != dtop) {
-      b = _mm_load_si128((__m128i *) s8);
-      result = _mm_clmulepi64_si128 (b, v, 0);
-      c = _mm_insert_epi32 (_mm_srli_si128 (result, 8), 0, 0);
-      w = _mm_clmulepi64_si128 (prim_poly, c, 0);
-      result = _mm_xor_si128 (result, w);
-      c = _mm_insert_epi32 (_mm_srli_si128 (result, 8), 0, 1);
-      w = _mm_clmulepi64_si128 (prim_poly, c, 0);
-      fr = _mm_xor_si128 (result, w);
-      fr = _mm_and_si128 (fr, m);
-
-      result = _mm_clmulepi64_si128 (b, v, 1);
-      c = _mm_insert_epi32 (_mm_srli_si128 (result, 8), 0, 0);
-      w = _mm_clmulepi64_si128 (prim_poly, c, 0);
-      result = _mm_xor_si128 (result, w);
-      c = _mm_insert_epi32 (_mm_srli_si128 (result, 8), 0, 1);
-      w = _mm_clmulepi64_si128 (prim_poly, c, 0);
-      result = _mm_xor_si128 (result, w);
-      result = _mm_slli_si128 (result, 8);
-      fr = _mm_xor_si128 (result, fr);
-      result = _mm_load_si128((__m128i *) d8);
-      fr = _mm_xor_si128 (result, fr);
-
-      _mm_store_si128((__m128i *) d8, fr);
-      d8 += 16;
-      s8 += 16;
-    }
-  } else {
-    while (d8 < dtop) {
-      b = _mm_load_si128((__m128i *) s8);
-      result = _mm_clmulepi64_si128 (b, v, 0);
-      c = _mm_insert_epi32 (_mm_srli_si128 (result, 8), 0, 0);
-      w = _mm_clmulepi64_si128 (prim_poly, c, 0);
-      result = _mm_xor_si128 (result, w);
-      c = _mm_insert_epi32 (_mm_srli_si128 (result, 8), 0, 1);
-      w = _mm_clmulepi64_si128 (prim_poly, c, 0);
-      fr = _mm_xor_si128 (result, w);
-      fr = _mm_and_si128 (fr, m);
-  
-      result = _mm_clmulepi64_si128 (b, v, 1);
-      c = _mm_insert_epi32 (_mm_srli_si128 (result, 8), 0, 0);
-      w = _mm_clmulepi64_si128 (prim_poly, c, 0);
-      result = _mm_xor_si128 (result, w);
-      c = _mm_insert_epi32 (_mm_srli_si128 (result, 8), 0, 1);
-      w = _mm_clmulepi64_si128 (prim_poly, c, 0);
-      result = _mm_xor_si128 (result, w);
-      result = _mm_slli_si128 (result, 8);
-      fr = _mm_xor_si128 (result, fr);
-  
-      _mm_store_si128((__m128i *) d8, fr);
-      d8 += 16;
-      s8 += 16;
-    }
-  }
-  gf_do_final_region_alignment(&rd);
-#endif
-}
-
-void
-gf_w64_split_4_64_lazy_multiply_region(gf_t *gf, void *src, void *dest, uint64_t val, int bytes, int xor)
-{
-  gf_internal_t *h;
-  struct gf_split_4_64_lazy_data *ld;
-  int i, j, k;
-  uint64_t pp, v, s, *s64, *d64, *top;
-  gf_region_data rd;
-
-  if (val == 0) { gf_multby_zero(dest, bytes, xor); return; }
-  if (val == 1) { gf_multby_one(src, dest, bytes, xor); return; }
-
-  h = (gf_internal_t *) gf->scratch;
-  pp = h->prim_poly;
-
-  ld = (struct gf_split_4_64_lazy_data *) h->private;
-
-  gf_set_region_data(&rd, gf, src, dest, bytes, val, xor, 8);
-  gf_do_initial_region_alignment(&rd);
-
-  if (ld->last_value != val) {
-    v = val;
-    for (i = 0; i < 16; i++) {
-      ld->tables[i][0] = 0;
-      for (j = 1; j < 16; j <<= 1) {
-        for (k = 0; k < j; k++) {
-          ld->tables[i][k^j] = (v ^ ld->tables[i][k]);
-        }
-        v = (v & GF_FIRST_BIT) ? ((v << 1) ^ pp) : (v << 1);
-      }
-    }
-  }
-  ld->last_value = val;
-
-  s64 = (uint64_t *) rd.s_start;
-  d64 = (uint64_t *) rd.d_start;
-  top = (uint64_t *) rd.d_top;
-
-  while (d64 != top) {
-    v = (xor) ? *d64 : 0;
-    s = *s64;
-    i = 0;
-    while (s != 0) {
-      v ^= ld->tables[i][s&0xf];
-      s >>= 4;
-      i++;
-    }
-    *d64 = v;
-    d64++;
-    s64++;
-  }
-  gf_do_final_region_alignment(&rd);
-}
-
-static
-inline
-uint64_t
-gf_w64_split_8_8_multiply (gf_t *gf, uint64_t a64, uint64_t b64)
-{
-  uint64_t product, i, j, mask, tb;
-  gf_internal_t *h;
-  struct gf_split_8_8_data *d8;
- 
-  h = (gf_internal_t *) gf->scratch;
-  d8 = (struct gf_split_8_8_data *) h->private;
-  product = 0;
-  mask = 0xff;
-
-  for (i = 0; a64 != 0; i++) {
-    tb = b64;
-    for (j = 0; tb != 0; j++) {
-      product ^= d8->tables[i+j][a64&mask][tb&mask];
-      tb >>= 8;
-    }
-    a64 >>= 8;
-  }
-  return product;
-}
-
-void
-gf_w64_split_8_64_lazy_multiply_region(gf_t *gf, void *src, void *dest, uint64_t val, int bytes, int xor)
-{
-  gf_internal_t *h;
-  struct gf_split_8_64_lazy_data *ld;
-  int i, j, k;
-  uint64_t pp, v, s, *s64, *d64, *top;
-  gf_region_data rd;
-
-  if (val == 0) { gf_multby_zero(dest, bytes, xor); return; }
-  if (val == 1) { gf_multby_one(src, dest, bytes, xor); return; }
-
-  h = (gf_internal_t *) gf->scratch;
-  pp = h->prim_poly;
-
-  ld = (struct gf_split_8_64_lazy_data *) h->private;
-
-  gf_set_region_data(&rd, gf, src, dest, bytes, val, xor, 4);
-  gf_do_initial_region_alignment(&rd);
-
-  if (ld->last_value != val) {
-    v = val;
-    for (i = 0; i < 8; i++) {
-      ld->tables[i][0] = 0;
-      for (j = 1; j < 256; j <<= 1) {
-        for (k = 0; k < j; k++) {
-          ld->tables[i][k^j] = (v ^ ld->tables[i][k]);
-        }
-        v = (v & GF_FIRST_BIT) ? ((v << 1) ^ pp) : (v << 1);
-      }
-    }
-  }
-  ld->last_value = val;
-
-  s64 = (uint64_t *) rd.s_start;
-  d64 = (uint64_t *) rd.d_start;
-  top = (uint64_t *) rd.d_top;
-
-  while (d64 != top) {
-    v = (xor) ? *d64 : 0;
-    s = *s64;
-    i = 0;
-    while (s != 0) {
-      v ^= ld->tables[i][s&0xff];
-      s >>= 8;
-      i++;
-    }
-    *d64 = v;
-    d64++;
-    s64++;
-  }
-  gf_do_final_region_alignment(&rd);
-}
-
-void
-gf_w64_split_16_64_lazy_multiply_region(gf_t *gf, void *src, void *dest, uint64_t val, int bytes, int xor)
-{
-  gf_internal_t *h;
-  struct gf_split_16_64_lazy_data *ld;
-  int i, j, k;
-  uint64_t pp, v, s, *s64, *d64, *top;
-  gf_region_data rd;
-
-  if (val == 0) { gf_multby_zero(dest, bytes, xor); return; }
-  if (val == 1) { gf_multby_one(src, dest, bytes, xor); return; }
-
-  h = (gf_internal_t *) gf->scratch;
-  pp = h->prim_poly;
-
-  ld = (struct gf_split_16_64_lazy_data *) h->private;
-
-  gf_set_region_data(&rd, gf, src, dest, bytes, val, xor, 4);
-  gf_do_initial_region_alignment(&rd);
-
-  if (ld->last_value != val) {
-    v = val;
-    for (i = 0; i < 4; i++) {
-      ld->tables[i][0] = 0;
-      for (j = 1; j < (1<<16); j <<= 1) {
-        for (k = 0; k < j; k++) {
-          ld->tables[i][k^j] = (v ^ ld->tables[i][k]);
-        }
-        v = (v & GF_FIRST_BIT) ? ((v << 1) ^ pp) : (v << 1);
-      }
-    }
-  }
-  ld->last_value = val;
-
-  s64 = (uint64_t *) rd.s_start;
-  d64 = (uint64_t *) rd.d_start;
-  top = (uint64_t *) rd.d_top;
-
-  while (d64 != top) {
-    v = (xor) ? *d64 : 0;
-    s = *s64;
-    i = 0;
-    while (s != 0) {
-      v ^= ld->tables[i][s&0xffff];
-      s >>= 16;
-      i++;
-    }
-    *d64 = v;
-    d64++;
-    s64++;
-  }
-  gf_do_final_region_alignment(&rd);
-}
-
-static 
-int gf_w64_shift_init(gf_t *gf)
-{
-  gf->multiply.w64 = gf_w64_shift_multiply;
-  gf->inverse.w64 = gf_w64_euclid;
-  gf->multiply_region.w64 = gf_w64_multiply_region_from_single;
-  return 1;
-}
-
-static 
-int gf_w64_cfm_init(gf_t *gf)
-{
-  gf->inverse.w64 = gf_w64_euclid;
-  gf->multiply_region.w64 = gf_w64_multiply_region_from_single;
-
-#if defined(INTEL_SSE4_PCLMUL) 
-  gf_internal_t *h;
-
-  h = (gf_internal_t *) gf->scratch;
-
-  if ((0xfffffffe00000000ULL & h->prim_poly) == 0){ 
-    gf->multiply.w64 = gf_w64_clm_multiply_2;
-    gf->multiply_region.w64 = gf_w64_clm_multiply_region_from_single_2; 
-  }else if((0xfffe000000000000ULL & h->prim_poly) == 0){
-    gf->multiply.w64 = gf_w64_clm_multiply_4;
-    gf->multiply_region.w64 = gf_w64_clm_multiply_region_from_single_4;
-  } else {
-    return 0;
-  }
-  return 1;
-#endif
-
-  return 0;
-}
-
-static
-void
-gf_w64_group_set_shift_tables(uint64_t *shift, uint64_t val, gf_internal_t *h)
-{
-  uint64_t i;
-  uint64_t j;
-  uint64_t one = 1;
-  int g_s;
-
-  g_s = h->arg1;
-  shift[0] = 0;
- 
-  for (i = 1; i < ((uint64_t)1 << g_s); i <<= 1) {
-    for (j = 0; j < i; j++) shift[i|j] = shift[j]^val;
-    if (val & (one << 63)) {
-      val <<= 1;
-      val ^= h->prim_poly;
-    } else {
-      val <<= 1;
-    }
-  }
-}
-
-static
-inline
-gf_val_64_t
-gf_w64_group_multiply(gf_t *gf, gf_val_64_t a, gf_val_64_t b)
-{
-  uint64_t top, bot, mask, tp;
-  int g_s, g_r, lshift, rshift;
-  struct gf_w64_group_data *gd;
-
-  gf_internal_t *h = (gf_internal_t *) gf->scratch;
-  g_s = h->arg1;
-  g_r = h->arg2;
-  gd = (struct gf_w64_group_data *) h->private;
-  gf_w64_group_set_shift_tables(gd->shift, b, h);
-
-  mask = (((uint64_t)1 << g_s) - 1);
-  top = 0;
-  bot = gd->shift[a&mask];
-  a >>= g_s; 
-
-  if (a == 0) return bot;
-  lshift = 0;
-  rshift = 64;
-
-  do {              /* Shifting out is straightfoward */
-    lshift += g_s;
-    rshift -= g_s;
-    tp = gd->shift[a&mask];
-    top ^= (tp >> rshift);
-    bot ^= (tp << lshift);
-    a >>= g_s; 
-  } while (a != 0);
-
-  /* Reducing is a bit gross, because I don't zero out the index bits of top.
-     The reason is that we throw top away.  Even better, that last (tp >> rshift)
-     is going to be ignored, so it doesn't matter how (tp >> 64) is implemented. */
-     
-  lshift = ((lshift-1) / g_r) * g_r;
-  rshift = 64 - lshift;
-  mask = ((uint64_t)1 << g_r) - 1;
-  while (lshift >= 0) {
-    tp = gd->reduce[(top >> lshift) & mask];
-    top ^= (tp >> rshift);
-    bot ^= (tp << lshift);
-    lshift -= g_r;
-    rshift += g_r;
-  }
-    
-  return bot;
-}
-
-static
-void gf_w64_group_multiply_region(gf_t *gf, void *src, void *dest, gf_val_64_t val, int bytes, int xor)
-{
-  int i, fzb;
-  uint64_t a64, smask, rmask, top, bot, tp;
-  int lshift, rshift, g_s, g_r;
-  gf_region_data rd;
-  uint64_t *s64, *d64, *dtop;
-  struct gf_w64_group_data *gd;
-  gf_internal_t *h = (gf_internal_t *) gf->scratch;
-
-  if (val == 0) { gf_multby_zero(dest, bytes, xor); return; }
-  if (val == 1) { gf_multby_one(src, dest, bytes, xor); return; }
-
-  gd = (struct gf_w64_group_data *) h->private;
-  g_s = h->arg1;
-  g_r = h->arg2;
-  gf_w64_group_set_shift_tables(gd->shift, val, h);
-
-  for (i = 63; !(val & (1ULL << i)); i--) ;
-  i += g_s;
-  
-  /* i is the bit position of the first zero bit in any element of
-                           gd->shift[] */
-  
-  if (i > 64) i = 64;   
-  
-  fzb = i;
-
-  gf_set_region_data(&rd, gf, src, dest, bytes, val, xor, 4);
-  
-  gf_do_initial_region_alignment(&rd);
-
-  s64 = (uint64_t *) rd.s_start;
-  d64 = (uint64_t *) rd.d_start;
-  dtop = (uint64_t *) rd.d_top;
-
-  smask = ((uint64_t)1 << g_s) - 1;
-  rmask = ((uint64_t)1 << g_r) - 1;
-
-  while (d64 < dtop) {
-    a64 = *s64;
-    
-    top = 0;
-    bot = gd->shift[a64&smask];
-    a64 >>= g_s;
-    i = fzb;
-
-    if (a64 != 0) {
-      lshift = 0;
-      rshift = 64;
-  
-      do {  
-        lshift += g_s;
-        rshift -= g_s;
-        tp = gd->shift[a64&smask];
-        top ^= (tp >> rshift);
-        bot ^= (tp << lshift);
-        a64 >>= g_s;
-      } while (a64 != 0);
-      i += lshift;
-  
-      lshift = ((i-64-1) / g_r) * g_r;
-      rshift = 64 - lshift;
-      while (lshift >= 0) {
-        tp = gd->reduce[(top >> lshift) & rmask];
-        top ^= (tp >> rshift);    
-        bot ^= (tp << lshift);
-        lshift -= g_r;
-        rshift += g_r;
-      }
-    }
-
-    if (xor) bot ^= *d64;
-    *d64 = bot;
-    d64++;
-    s64++;
-  }
-  gf_do_final_region_alignment(&rd);
-}
-
-static
-inline
-gf_val_64_t
-gf_w64_group_s_equals_r_multiply(gf_t *gf, gf_val_64_t a, gf_val_64_t b)
-{
-  int leftover, rs;
-  uint64_t p, l, ind, a64;
-  int bits_left;
-  int g_s;
-
-  struct gf_w64_group_data *gd;
-  gf_internal_t *h = (gf_internal_t *) gf->scratch;
-  g_s = h->arg1;
-
-  gd = (struct gf_w64_group_data *) h->private;
-  gf_w64_group_set_shift_tables(gd->shift, b, h);
-
-  leftover = 64 % g_s;
-  if (leftover == 0) leftover = g_s;
-
-  rs = 64 - leftover;
-  a64 = a;
-  ind = a64 >> rs;
-  a64 <<= leftover;
-  p = gd->shift[ind];
-
-  bits_left = rs;
-  rs = 64 - g_s;
-
-  while (bits_left > 0) {
-    bits_left -= g_s;
-    ind = a64 >> rs;
-    a64 <<= g_s;
-    l = p >> rs;
-    p = (gd->shift[ind] ^ gd->reduce[l] ^ (p << g_s));
-  }
-  return p;
-}
-
-static
-void gf_w64_group_s_equals_r_multiply_region(gf_t *gf, void *src, void *dest, gf_val_64_t val, int bytes, int xor)
-{
-  int leftover, rs;
-  uint64_t p, l, ind, a64;
-  int bits_left;
-  int g_s;
-  gf_region_data rd;
-  uint64_t *s64, *d64, *top;
-  struct gf_w64_group_data *gd;
-  gf_internal_t *h = (gf_internal_t *) gf->scratch;
-
-  if (val == 0) { gf_multby_zero(dest, bytes, xor); return; }
-  if (val == 1) { gf_multby_one(src, dest, bytes, xor); return; }
-
-  gd = (struct gf_w64_group_data *) h->private;
-  g_s = h->arg1;
-  gf_w64_group_set_shift_tables(gd->shift, val, h);
-
-  gf_set_region_data(&rd, gf, src, dest, bytes, val, xor, 4);
-  gf_do_initial_region_alignment(&rd);
-
-  s64 = (uint64_t *) rd.s_start;
-  d64 = (uint64_t *) rd.d_start;
-  top = (uint64_t *) rd.d_top;
-
-  leftover = 64 % g_s;
-  if (leftover == 0) leftover = g_s;
-
-  while (d64 < top) {
-    rs = 64 - leftover;
-    a64 = *s64;
-    ind = a64 >> rs;
-    a64 <<= leftover;
-    p = gd->shift[ind];
-
-    bits_left = rs;
-    rs = 64 - g_s;
-
-    while (bits_left > 0) {
-      bits_left -= g_s;
-      ind = a64 >> rs;
-      a64 <<= g_s;
-      l = p >> rs;
-      p = (gd->shift[ind] ^ gd->reduce[l] ^ (p << g_s));
-    }
-    if (xor) p ^= *d64;
-    *d64 = p;
-    d64++;
-    s64++;
-  }
-  gf_do_final_region_alignment(&rd);
-}
-
-
-static
-int gf_w64_group_init(gf_t *gf)
-{
-  uint64_t i, j, p, index;
-  struct gf_w64_group_data *gd;
-  gf_internal_t *h = (gf_internal_t *) gf->scratch;
-  uint64_t g_r, g_s;
-
-  g_s = h->arg1;
-  g_r = h->arg2;
-
-  gd = (struct gf_w64_group_data *) h->private;
-  gd->shift = (uint64_t *) (&(gd->memory));
-  gd->reduce = gd->shift + (1 << g_s);
-
-  gd->reduce[0] = 0;
-  for (i = 0; i < ((uint64_t)1 << g_r); i++) {
-    p = 0;
-    index = 0;
-    for (j = 0; j < g_r; j++) {
-      if (i & (1 << j)) {
-        p ^= (h->prim_poly << j);
-        index ^= (1 << j);
-        if (j > 0) index ^= (h->prim_poly >> (64-j)); 
-      }
-    }
-    gd->reduce[index] = p;
-  }
-
-  if (g_s == g_r) {
-    gf->multiply.w64 = gf_w64_group_s_equals_r_multiply;
-    gf->multiply_region.w64 = gf_w64_group_s_equals_r_multiply_region; 
-  } else {
-    gf->multiply.w64 = gf_w64_group_multiply;
-    gf->multiply_region.w64 = gf_w64_group_multiply_region; 
-  }
-  gf->divide.w64 = NULL;
-  gf->inverse.w64 = gf_w64_euclid;
-
-  return 1;
-}
-
-static
-gf_val_64_t gf_w64_extract_word(gf_t *gf, void *start, int bytes, int index)
-{
-  uint64_t *r64, rv;
-
-  r64 = (uint64_t *) start;
-  rv = r64[index];
-  return rv;
-}
-
-static
-gf_val_64_t gf_w64_composite_extract_word(gf_t *gf, void *start, int bytes, int index)
-{
-  int sub_size;
-  gf_internal_t *h;
-  uint8_t *r8, *top;
-  uint64_t a, b, *r64;
-  gf_region_data rd;
-
-  h = (gf_internal_t *) gf->scratch;
-  gf_set_region_data(&rd, gf, start, start, bytes, 0, 0, 32);
-  r64 = (uint64_t *) start;
-  if (r64 + index < (uint64_t *) rd.d_start) return r64[index];
-  if (r64 + index >= (uint64_t *) rd.d_top) return r64[index];
-  index -= (((uint64_t *) rd.d_start) - r64);
-  r8 = (uint8_t *) rd.d_start;
-  top = (uint8_t *) rd.d_top;
-  sub_size = (top-r8)/2;
-
-  a = h->base_gf->extract_word.w32(h->base_gf, r8, sub_size, index);
-  b = h->base_gf->extract_word.w32(h->base_gf, r8+sub_size, sub_size, index);
-  return (a | ((uint64_t)b << 32));
-}
-
-static
-gf_val_64_t gf_w64_split_extract_word(gf_t *gf, void *start, int bytes, int index)
-{
-  int i;
-  uint64_t *r64, rv;
-  uint8_t *r8;
-  gf_region_data rd;
-
-  gf_set_region_data(&rd, gf, start, start, bytes, 0, 0, 128);
-  r64 = (uint64_t *) start;
-  if (r64 + index < (uint64_t *) rd.d_start) return r64[index];
-  if (r64 + index >= (uint64_t *) rd.d_top) return r64[index];
-  index -= (((uint64_t *) rd.d_start) - r64);
-  r8 = (uint8_t *) rd.d_start;
-  r8 += ((index & 0xfffffff0)*8);
-  r8 += (index & 0xf);
-  r8 += 112;
-  rv =0;
-  for (i = 0; i < 8; i++) {
-    rv <<= 8;
-    rv |= *r8;
-    r8 -= 16;
-  }
-  return rv;
-}
-
-static
-inline
-gf_val_64_t
-gf_w64_bytwo_b_multiply (gf_t *gf, gf_val_64_t a, gf_val_64_t b)
-{
-  uint64_t prod, pp, bmask;
-  gf_internal_t *h;
-
-  h = (gf_internal_t *) gf->scratch;
-  pp = h->prim_poly;
-
-  prod = 0;
-  bmask = 0x8000000000000000ULL;
-
-  while (1) {
-    if (a & 1) prod ^= b;
-    a >>= 1;
-    if (a == 0) return prod;
-    if (b & bmask) {
-      b = ((b << 1) ^ pp);
-    } else {
-      b <<= 1;
-    }
-  }
-}
-
-static
-inline
-gf_val_64_t
-gf_w64_bytwo_p_multiply (gf_t *gf, gf_val_64_t a, gf_val_64_t b)
-{
-  uint64_t prod, pp, pmask, amask;
-  gf_internal_t *h;
-
-  h = (gf_internal_t *) gf->scratch;
-  pp = h->prim_poly;
-
-  prod = 0;
-  
-  /* changed from declare then shift to just declare.*/
-  
-  pmask = 0x8000000000000000ULL;
-  amask = 0x8000000000000000ULL;
-
-  while (amask != 0) {
-    if (prod & pmask) {
-      prod = ((prod << 1) ^ pp);
-    } else {
-      prod <<= 1;
-    }
-    if (a & amask) prod ^= b;
-    amask >>= 1;
-  }
-  return prod;
-}
-
-static
-void
-gf_w64_bytwo_p_nosse_multiply_region(gf_t *gf, void *src, void *dest, gf_val_64_t val, int bytes, int xor)
-{
-  uint64_t *s64, *d64, ta, prod, amask, pmask, pp;
-  gf_region_data rd;
-  gf_internal_t *h;
-
-  if (val == 0) { gf_multby_zero(dest, bytes, xor); return; }
-  if (val == 1) { gf_multby_one(src, dest, bytes, xor); return; }
-
-  gf_set_region_data(&rd, gf, src, dest, bytes, val, xor, 8);
-  gf_do_initial_region_alignment(&rd);
-
-  h = (gf_internal_t *) gf->scratch;
-
-  s64 = (uint64_t *) rd.s_start;
-  d64 = (uint64_t *) rd.d_start;
-  pmask = 0x80000000;
-  pmask <<= 32;
-  pp = h->prim_poly;
-
-  if (xor) {
-    while (s64 < (uint64_t *) rd.s_top) {
-      prod = 0;
-      amask = pmask;
-      ta = *s64;
-      while (amask != 0) {
-        prod = (prod & pmask) ? ((prod << 1) ^ pp) : (prod << 1);
-        if (val & amask) prod ^= ta;
-        amask >>= 1;
-      }
-      *d64 ^= prod;
-      d64++;
-      s64++;
-    }
-  } else {
-    while (s64 < (uint64_t *) rd.s_top) {
-      prod = 0;
-      amask = pmask;
-      ta = *s64;
-      while (amask != 0) {
-        prod = (prod & pmask) ? ((prod << 1) ^ pp) : (prod << 1);
-        if (val & amask) prod ^= ta;
-        amask >>= 1;
-      }
-      *d64 = prod;
-      d64++;
-      s64++;
-    }
-  }
-  gf_do_final_region_alignment(&rd);
-}
-
-static
-void
-gf_w64_bytwo_b_nosse_multiply_region(gf_t *gf, void *src, void *dest, gf_val_64_t val, int bytes, int xor)
-{
-  uint64_t *s64, *d64, ta, tb, prod, bmask, pp;
-  gf_region_data rd;
-  gf_internal_t *h;
-
-  if (val == 0) { gf_multby_zero(dest, bytes, xor); return; }
-  if (val == 1) { gf_multby_one(src, dest, bytes, xor); return; }
-
-  gf_set_region_data(&rd, gf, src, dest, bytes, val, xor, 8);
-  gf_do_initial_region_alignment(&rd);
-
-  h = (gf_internal_t *) gf->scratch;
-
-  s64 = (uint64_t *) rd.s_start;
-  d64 = (uint64_t *) rd.d_start;
-  bmask = 0x80000000;
-  bmask <<= 32;
-  pp = h->prim_poly;
-
-  if (xor) {
-    while (s64 < (uint64_t *) rd.s_top) {
-      prod = 0;
-      tb = val;
-      ta = *s64;
-      while (1) {
-        if (tb & 1) prod ^= ta;
-        tb >>= 1;
-        if (tb == 0) break;
-        ta = (ta & bmask) ? ((ta << 1) ^ pp) : (ta << 1);
-      }
-      *d64 ^= prod;
-      d64++;
-      s64++;
-    }
-  } else {
-    while (s64 < (uint64_t *) rd.s_top) {
-      prod = 0;
-      tb = val;
-      ta = *s64;
-      while (1) {
-        if (tb & 1) prod ^= ta;
-        tb >>= 1;
-        if (tb == 0) break;
-        ta = (ta & bmask) ? ((ta << 1) ^ pp) : (ta << 1);
-      }
-      *d64 = prod;
-      d64++;
-      s64++;
-    }
-  }
-  gf_do_final_region_alignment(&rd);
-}
-
-#define SSE_AB2(pp, m1 ,m2, va, t1, t2) {\
-          t1 = _mm_and_si128(_mm_slli_epi64(va, 1), m1); \
-          t2 = _mm_and_si128(va, m2); \
-          t2 = _mm_sub_epi64 (_mm_slli_epi64(t2, 1), _mm_srli_epi64(t2, (GF_FIELD_WIDTH-1))); \
-          va = _mm_xor_si128(t1, _mm_and_si128(t2, pp)); }
-
-#define BYTWO_P_ONESTEP {\
-      SSE_AB2(pp, m1 ,m2, prod, t1, t2); \
-      t1 = _mm_and_si128(v, one); \
-      t1 = _mm_sub_epi64(t1, one); \
-      t1 = _mm_and_si128(t1, ta); \
-      prod = _mm_xor_si128(prod, t1); \
-      v = _mm_srli_epi64(v, 1); }
-
-
-void gf_w64_bytwo_p_sse_multiply_region(gf_t *gf, void *src, void *dest, gf_val_64_t val, int bytes, int xor)
-{
-#ifdef INTEL_SSE2
-  int i;
-  uint8_t *s8, *d8;
-  uint64_t vrev, one64;
-  uint64_t amask;
-  __m128i pp, m1, m2, ta, prod, t1, t2, tp, one, v;
-  gf_region_data rd;
-  gf_internal_t *h;
-  
-  if (val == 0) { gf_multby_zero(dest, bytes, xor); return; }
-  if (val == 1) { gf_multby_one(src, dest, bytes, xor); return; }
-
-  gf_set_region_data(&rd, gf, src, dest, bytes, val, xor, 16);
-  gf_do_initial_region_alignment(&rd);
-
-  h = (gf_internal_t *) gf->scratch;
-  one64 = 1;
-  vrev = 0;
-  for (i = 0; i < 64; i++) {
-    vrev <<= 1;
-    if (!(val & (one64 << i))) vrev |= 1;
-  }
-
-  s8 = (uint8_t *) rd.s_start;
-  d8 = (uint8_t *) rd.d_start;
-
-  amask = -1;
-  amask ^= 1;
-  pp = _mm_set1_epi64x(h->prim_poly);
-  m1 = _mm_set1_epi64x(amask);
-  m2 = _mm_set1_epi64x(one64 << 63);
-  one = _mm_set1_epi64x(1);
-
-  while (d8 < (uint8_t *) rd.d_top) {
-    prod = _mm_setzero_si128();
-    v = _mm_set1_epi64x(vrev);
-    ta = _mm_load_si128((__m128i *) s8);
-    tp = (!xor) ? _mm_setzero_si128() : _mm_load_si128((__m128i *) d8);
-    BYTWO_P_ONESTEP; BYTWO_P_ONESTEP; BYTWO_P_ONESTEP; BYTWO_P_ONESTEP;
-    BYTWO_P_ONESTEP; BYTWO_P_ONESTEP; BYTWO_P_ONESTEP; BYTWO_P_ONESTEP;
-    BYTWO_P_ONESTEP; BYTWO_P_ONESTEP; BYTWO_P_ONESTEP; BYTWO_P_ONESTEP;
-    BYTWO_P_ONESTEP; BYTWO_P_ONESTEP; BYTWO_P_ONESTEP; BYTWO_P_ONESTEP;
-    BYTWO_P_ONESTEP; BYTWO_P_ONESTEP; BYTWO_P_ONESTEP; BYTWO_P_ONESTEP;
-    BYTWO_P_ONESTEP; BYTWO_P_ONESTEP; BYTWO_P_ONESTEP; BYTWO_P_ONESTEP;
-    BYTWO_P_ONESTEP; BYTWO_P_ONESTEP; BYTWO_P_ONESTEP; BYTWO_P_ONESTEP;
-    BYTWO_P_ONESTEP; BYTWO_P_ONESTEP; BYTWO_P_ONESTEP; BYTWO_P_ONESTEP;
-    BYTWO_P_ONESTEP; BYTWO_P_ONESTEP; BYTWO_P_ONESTEP; BYTWO_P_ONESTEP;
-    BYTWO_P_ONESTEP; BYTWO_P_ONESTEP; BYTWO_P_ONESTEP; BYTWO_P_ONESTEP;
-    BYTWO_P_ONESTEP; BYTWO_P_ONESTEP; BYTWO_P_ONESTEP; BYTWO_P_ONESTEP;
-    BYTWO_P_ONESTEP; BYTWO_P_ONESTEP; BYTWO_P_ONESTEP; BYTWO_P_ONESTEP;
-    BYTWO_P_ONESTEP; BYTWO_P_ONESTEP; BYTWO_P_ONESTEP; BYTWO_P_ONESTEP;
-    BYTWO_P_ONESTEP; BYTWO_P_ONESTEP; BYTWO_P_ONESTEP; BYTWO_P_ONESTEP;
-    BYTWO_P_ONESTEP; BYTWO_P_ONESTEP; BYTWO_P_ONESTEP; BYTWO_P_ONESTEP;
-    BYTWO_P_ONESTEP; BYTWO_P_ONESTEP; BYTWO_P_ONESTEP; BYTWO_P_ONESTEP;
-    _mm_store_si128((__m128i *) d8, _mm_xor_si128(prod, tp));
-    d8 += 16;
-    s8 += 16;
-  }
-  gf_do_final_region_alignment(&rd);
-#endif
-}
-
-#ifdef INTEL_SSE2
-static
-void
-gf_w64_bytwo_b_sse_region_2_xor(gf_region_data *rd)
-{
-  uint64_t one64, amask;
-  uint8_t *d8, *s8;
-  __m128i pp, m1, m2, t1, t2, va, vb;
-  gf_internal_t *h;
-
-  s8 = (uint8_t *) rd->s_start;
-  d8 = (uint8_t *) rd->d_start;
-
-  h = (gf_internal_t *) rd->gf->scratch;
-  one64 = 1;
-  amask = -1;
-  amask ^= 1;
-  pp = _mm_set1_epi64x(h->prim_poly);
-  m1 = _mm_set1_epi64x(amask);
-  m2 = _mm_set1_epi64x(one64 << 63);
-
-  while (d8 < (uint8_t *) rd->d_top) {
-    va = _mm_load_si128 ((__m128i *)(s8));
-    SSE_AB2(pp, m1, m2, va, t1, t2);
-    vb = _mm_load_si128 ((__m128i *)(d8));
-    vb = _mm_xor_si128(vb, va);
-    _mm_store_si128((__m128i *)d8, vb);
-    d8 += 16;
-    s8 += 16;
-  }
-}
-#endif
-
-#ifdef INTEL_SSE2
-static
-void
-gf_w64_bytwo_b_sse_region_2_noxor(gf_region_data *rd)
-{
-  uint64_t one64, amask;
-  uint8_t *d8, *s8;
-  __m128i pp, m1, m2, t1, t2, va;
-  gf_internal_t *h;
-
-  s8 = (uint8_t *) rd->s_start;
-  d8 = (uint8_t *) rd->d_start;
-
-  h = (gf_internal_t *) rd->gf->scratch;
-  one64 = 1;
-  amask = -1;
-  amask ^= 1;
-  pp = _mm_set1_epi64x(h->prim_poly);
-  m1 = _mm_set1_epi64x(amask);
-  m2 = _mm_set1_epi64x(one64 << 63);
-
-  while (d8 < (uint8_t *) rd->d_top) {
-    va = _mm_load_si128 ((__m128i *)(s8));
-    SSE_AB2(pp, m1, m2, va, t1, t2);
-    _mm_store_si128((__m128i *)d8, va);
-    d8 += 16;
-    s8 += 16;
-  }
-}
-#endif
-
-#ifdef INTEL_SSE2
-static
-void
-gf_w64_bytwo_b_sse_multiply_region(gf_t *gf, void *src, void *dest, gf_val_64_t val, int bytes, int xor)
-{
-  uint64_t itb, amask, one64;
-  uint8_t *d8, *s8;
-  __m128i pp, m1, m2, t1, t2, va, vb;
-  gf_region_data rd;
-  gf_internal_t *h;
-
-  if (val == 0) { gf_multby_zero(dest, bytes, xor); return; }
-  if (val == 1) { gf_multby_one(src, dest, bytes, xor); return; }
-
-  gf_set_region_data(&rd, gf, src, dest, bytes, val, xor, 16);
-  gf_do_initial_region_alignment(&rd);
-
-  if (val == 2) {
-    if (xor) {
-      gf_w64_bytwo_b_sse_region_2_xor(&rd);
-    } else {
-      gf_w64_bytwo_b_sse_region_2_noxor(&rd);
-    }
-    gf_do_final_region_alignment(&rd);
-    return;
-  }
-
-  s8 = (uint8_t *) rd.s_start;
-  d8 = (uint8_t *) rd.d_start;
-  h = (gf_internal_t *) gf->scratch;
-
-  one64 = 1;
-  amask = -1;
-  amask ^= 1;
-  pp = _mm_set1_epi64x(h->prim_poly);
-  m1 = _mm_set1_epi64x(amask);
-  m2 = _mm_set1_epi64x(one64 << 63);
-
-  while (d8 < (uint8_t *) rd.d_top) {
-    va = _mm_load_si128 ((__m128i *)(s8));
-    vb = (!xor) ? _mm_setzero_si128() : _mm_load_si128 ((__m128i *)(d8));
-    itb = val;
-    while (1) {
-      if (itb & 1) vb = _mm_xor_si128(vb, va);
-      itb >>= 1;
-      if (itb == 0) break;
-      SSE_AB2(pp, m1, m2, va, t1, t2);
-    }
-    _mm_store_si128((__m128i *)d8, vb);
-    d8 += 16;
-    s8 += 16;
-  }
-
-  gf_do_final_region_alignment(&rd);
-}
-#endif
-
-
-static
-int gf_w64_bytwo_init(gf_t *gf)
-{
-  gf_internal_t *h;
-
-  h = (gf_internal_t *) gf->scratch;
-
-  if (h->mult_type == GF_MULT_BYTWO_p) {
-    gf->multiply.w64 = gf_w64_bytwo_p_multiply;
-    #ifdef INTEL_SSE2 
-      if (h->region_type & GF_REGION_NOSIMD)
-        gf->multiply_region.w64 = gf_w64_bytwo_p_nosse_multiply_region; 
-      else
-        gf->multiply_region.w64 = gf_w64_bytwo_p_sse_multiply_region; 
-    #else
-      gf->multiply_region.w64 = gf_w64_bytwo_p_nosse_multiply_region; 
-      if(h->region_type & GF_REGION_SIMD)
-        return 0;
-    #endif
-  } else {
-    gf->multiply.w64 = gf_w64_bytwo_b_multiply;
-    #ifdef INTEL_SSE2 
-      if (h->region_type & GF_REGION_NOSIMD)
-        gf->multiply_region.w64 = gf_w64_bytwo_b_nosse_multiply_region; 
-      else
-        gf->multiply_region.w64 = gf_w64_bytwo_b_sse_multiply_region; 
-    #else
-      gf->multiply_region.w64 = gf_w64_bytwo_b_nosse_multiply_region; 
-      if(h->region_type & GF_REGION_SIMD)
-        return 0;
-    #endif
-  }
-  gf->inverse.w64 = gf_w64_euclid;
-  return 1;
-}
-
-
-static
-gf_val_64_t
-gf_w64_composite_multiply(gf_t *gf, gf_val_64_t a, gf_val_64_t b)
-{
-  gf_internal_t *h = (gf_internal_t *) gf->scratch;
-  gf_t *base_gf = h->base_gf;
-  uint32_t b0 = b & 0x00000000ffffffff;
-  uint32_t b1 = (b & 0xffffffff00000000) >> 32;
-  uint32_t a0 = a & 0x00000000ffffffff;
-  uint32_t a1 = (a & 0xffffffff00000000) >> 32;
-  uint32_t a1b1;
-
-  a1b1 = base_gf->multiply.w32(base_gf, a1, b1);
-
-  return ((uint64_t)(base_gf->multiply.w32(base_gf, a0, b0) ^ a1b1) | 
-         ((uint64_t)(base_gf->multiply.w32(base_gf, a1, b0) ^ base_gf->multiply.w32(base_gf, a0, b1) ^ base_gf->multiply.w32(base_gf, a1b1, h->prim_poly)) << 32));
-}
-
-/*
- * Composite field division trick (explained in 2007 tech report)
- *
- * Compute a / b = a*b^-1, where p(x) = x^2 + sx + 1
- *
- * let c = b^-1
- *
- * c*b = (s*b1c1+b1c0+b0c1)x+(b1c1+b0c0)
- *
- * want (s*b1c1+b1c0+b0c1) = 0 and (b1c1+b0c0) = 1
- *
- * let d = b1c1 and d+1 = b0c0
- *
- * solve s*b1c1+b1c0+b0c1 = 0
- *
- * solution: d = (b1b0^-1)(b1b0^-1+b0b1^-1+s)^-1
- *
- * c0 = (d+1)b0^-1
- * c1 = d*b1^-1
- *
- * a / b = a * c
- */
-
-static
-gf_val_64_t
-gf_w64_composite_inverse(gf_t *gf, gf_val_64_t a)
-{
-  gf_internal_t *h = (gf_internal_t *) gf->scratch;
-  gf_t *base_gf = h->base_gf;
-  uint32_t a0 = a & 0x00000000ffffffff;
-  uint32_t a1 = (a & 0xffffffff00000000) >> 32;
-  uint32_t c0, c1, d, tmp;
-  uint64_t c;
-  uint32_t a0inv, a1inv;
-
-  if (a0 == 0) {
-    a1inv = base_gf->inverse.w32(base_gf, a1);
-    c0 = base_gf->multiply.w32(base_gf, a1inv, h->prim_poly);
-    c1 = a1inv;
-  } else if (a1 == 0) {
-    c0 = base_gf->inverse.w32(base_gf, a0);
-    c1 = 0;
-  } else {
-    a1inv = base_gf->inverse.w32(base_gf, a1);
-    a0inv = base_gf->inverse.w32(base_gf, a0);
-
-    d = base_gf->multiply.w32(base_gf, a1, a0inv);
-
-    tmp = (base_gf->multiply.w32(base_gf, a1, a0inv) ^ base_gf->multiply.w32(base_gf, a0, a1inv) ^ h->prim_poly);
-    tmp = base_gf->inverse.w32(base_gf, tmp);
-
-    d = base_gf->multiply.w32(base_gf, d, tmp);
-
-    c0 = base_gf->multiply.w32(base_gf, (d^1), a0inv);
-    c1 = base_gf->multiply.w32(base_gf, d, a1inv);
-  }
-
-  c = c0 | ((uint64_t)c1 << 32);
-
-  return c;
-}
-
-static
-void
-gf_w64_composite_multiply_region(gf_t *gf, void *src, void *dest, gf_val_64_t val, int bytes, int xor)
-{
-  gf_internal_t *h = (gf_internal_t *) gf->scratch;
-  gf_t *base_gf = h->base_gf;
-  uint32_t b0 = val & 0x00000000ffffffff;
-  uint32_t b1 = (val & 0xffffffff00000000) >> 32;
-  uint64_t *s64, *d64;
-  uint64_t *top;
-  uint64_t a0, a1, a1b1;
-  gf_region_data rd;
-
-  if (val == 0) { gf_multby_zero(dest, bytes, xor); return; }
-  gf_set_region_data(&rd, gf, src, dest, bytes, val, xor, 8);
-
-  s64 = rd.s_start;
-  d64 = rd.d_start;
-  top = rd.d_top;
-  
-  if (xor) {
-    while (d64 < top) {
-      a0 = *s64 & 0x00000000ffffffff;
-      a1 = (*s64 & 0xffffffff00000000) >> 32;
-      a1b1 = base_gf->multiply.w32(base_gf, a1, b1);
-
-      *d64 ^= ((uint64_t)(base_gf->multiply.w32(base_gf, a0, b0) ^ a1b1) |
-                ((uint64_t)(base_gf->multiply.w32(base_gf, a1, b0) ^ base_gf->multiply.w32(base_gf, a0, b1) ^ base_gf->multiply.w32(base_gf, a1b1, h->prim_poly)) << 32));
-      s64++;
-      d64++;
-    }
-  } else {
-    while (d64 < top) {
-      a0 = *s64 & 0x00000000ffffffff;
-      a1 = (*s64 & 0xffffffff00000000) >> 32;
-      a1b1 = base_gf->multiply.w32(base_gf, a1, b1);
-
-      *d64 = ((base_gf->multiply.w32(base_gf, a0, b0) ^ a1b1) |
-                ((uint64_t)(base_gf->multiply.w32(base_gf, a1, b0) ^ base_gf->multiply.w32(base_gf, a0, b1) ^ base_gf->multiply.w32(base_gf, a1b1, h->prim_poly)) << 32));
-      s64++;
-      d64++;
-    }
-  }
-}
-
-static
-void
-gf_w64_composite_multiply_region_alt(gf_t *gf, void *src, void *dest, gf_val_64_t val, int bytes, int xor)
-{
-  gf_internal_t *h = (gf_internal_t *) gf->scratch;
-  gf_t *base_gf = h->base_gf;
-  gf_val_32_t val0 = val & 0x00000000ffffffff;
-  gf_val_32_t val1 = (val & 0xffffffff00000000) >> 32;
-  uint8_t *slow, *shigh;
-  uint8_t *dlow, *dhigh, *top;
-  int sub_reg_size;
-  gf_region_data rd;
-
-  if (!xor) {
-    memset(dest, 0, bytes);
-  }
-  
-  gf_set_region_data(&rd, gf, src, dest, bytes, val, xor, 32);
-  gf_do_initial_region_alignment(&rd);
-
-  slow = (uint8_t *) rd.s_start;
-  dlow = (uint8_t *) rd.d_start;
-  top = (uint8_t*) rd.d_top;
-  sub_reg_size = (top - dlow)/2;
-  shigh = slow + sub_reg_size;
-  dhigh = dlow + sub_reg_size;
-
-  base_gf->multiply_region.w32(base_gf, slow, dlow, val0, sub_reg_size, xor);
-  base_gf->multiply_region.w32(base_gf, shigh, dlow, val1, sub_reg_size, 1);
-  base_gf->multiply_region.w32(base_gf, slow, dhigh, val1, sub_reg_size, xor);
-  base_gf->multiply_region.w32(base_gf, shigh, dhigh, val0, sub_reg_size, 1);
-  base_gf->multiply_region.w32(base_gf, shigh, dhigh, base_gf->multiply.w32(base_gf, h->prim_poly, val1), sub_reg_size, 1);
-
-  gf_do_final_region_alignment(&rd);
-}
-
-
-
-static
-int gf_w64_composite_init(gf_t *gf)
-{
-  gf_internal_t *h = (gf_internal_t *) gf->scratch;
-
-  if (h->region_type & GF_REGION_ALTMAP) {
-    gf->multiply_region.w64 = gf_w64_composite_multiply_region_alt;
-  } else {
-    gf->multiply_region.w64 = gf_w64_composite_multiply_region;
-  }
-
-  gf->multiply.w64 = gf_w64_composite_multiply;
-  gf->divide.w64 = NULL;
-  gf->inverse.w64 = gf_w64_composite_inverse;
-
-  return 1;
-}
-
-#ifdef INTEL_SSSE3
-static
-  void
-gf_w64_split_4_64_lazy_sse_altmap_multiply_region(gf_t *gf, void *src, void *dest, uint64_t val, int bytes, int xor)
-{
-  gf_internal_t *h;
-  int i, j, k;
-  uint64_t pp, v, *s64, *d64, *top;
-  __m128i si, tables[16][8], p[8], v0, mask1;
-  struct gf_split_4_64_lazy_data *ld;
-  uint8_t btable[16];
-  gf_region_data rd;
-
-  if (val == 0) { gf_multby_zero(dest, bytes, xor); return; }
-  if (val == 1) { gf_multby_one(src, dest, bytes, xor); return; }
-
-  h = (gf_internal_t *) gf->scratch;
-  pp = h->prim_poly;
-
-  gf_set_region_data(&rd, gf, src, dest, bytes, val, xor, 128);
-  gf_do_initial_region_alignment(&rd);
-
-  s64 = (uint64_t *) rd.s_start;
-  d64 = (uint64_t *) rd.d_start;
-  top = (uint64_t *) rd.d_top;
- 
-  ld = (struct gf_split_4_64_lazy_data *) h->private;
-
-  v = val;
-  for (i = 0; i < 16; i++) {
-    ld->tables[i][0] = 0;
-    for (j = 1; j < 16; j <<= 1) {
-      for (k = 0; k < j; k++) {
-        ld->tables[i][k^j] = (v ^ ld->tables[i][k]);
-      }
-      v = (v & GF_FIRST_BIT) ? ((v << 1) ^ pp) : (v << 1);
-    }
-    for (j = 0; j < 8; j++) {
-      for (k = 0; k < 16; k++) {
-        btable[k] = (uint8_t) ld->tables[i][k];
-        ld->tables[i][k] >>= 8;
-      }
-      tables[i][j] = _mm_loadu_si128((__m128i *) btable);
-    }
-  }
-
-  mask1 = _mm_set1_epi8(0xf);
-
-  while (d64 != top) {
-
-    if (xor) {
-      for (i = 0; i < 8; i++) p[i] = _mm_load_si128 ((__m128i *) (d64+i*2));
-    } else {
-      for (i = 0; i < 8; i++) p[i] = _mm_setzero_si128();
-    }
-    i = 0;
-    for (k = 0; k < 8; k++) {
-      v0 = _mm_load_si128((__m128i *) s64); 
-      /* MM_PRINT8("v", v0); */
-      s64 += 2;
-      
-      si = _mm_and_si128(v0, mask1);
-  
-      for (j = 0; j < 8; j++) {
-        p[j] = _mm_xor_si128(p[j], _mm_shuffle_epi8(tables[i][j], si));
-      }
-      i++;
-      v0 = _mm_srli_epi32(v0, 4);
-      si = _mm_and_si128(v0, mask1);
-      for (j = 0; j < 8; j++) {
-        p[j] = _mm_xor_si128(p[j], _mm_shuffle_epi8(tables[i][j], si));
-      }
-      i++;
-    }
-    for (i = 0; i < 8; i++) {
-      /* MM_PRINT8("v", p[i]); */
-      _mm_store_si128((__m128i *) d64, p[i]);
-      d64 += 2;
-    }
-  }
-  gf_do_final_region_alignment(&rd);
-}
-#endif
-
-#ifdef INTEL_SSE4
-static
-  void
-gf_w64_split_4_64_lazy_sse_multiply_region(gf_t *gf, void *src, void *dest, uint64_t val, int bytes, int xor)
-{
-  gf_internal_t *h;
-  int i, j, k;
-  uint64_t pp, v, *s64, *d64, *top;
-  __m128i si, tables[16][8], p[8], st[8], mask1, mask8, mask16, t1;
-  struct gf_split_4_64_lazy_data *ld;
-  uint8_t btable[16];
-  gf_region_data rd;
-
-  if (val == 0) { gf_multby_zero(dest, bytes, xor); return; }
-  if (val == 1) { gf_multby_one(src, dest, bytes, xor); return; }
-
-  h = (gf_internal_t *) gf->scratch;
-  pp = h->prim_poly;
-
-  gf_set_region_data(&rd, gf, src, dest, bytes, val, xor, 128);
-  gf_do_initial_region_alignment(&rd);
-
-  s64 = (uint64_t *) rd.s_start;
-  d64 = (uint64_t *) rd.d_start;
-  top = (uint64_t *) rd.d_top;
- 
-  ld = (struct gf_split_4_64_lazy_data *) h->private;
-
-  v = val;
-  for (i = 0; i < 16; i++) {
-    ld->tables[i][0] = 0;
-    for (j = 1; j < 16; j <<= 1) {
-      for (k = 0; k < j; k++) {
-        ld->tables[i][k^j] = (v ^ ld->tables[i][k]);
-      }
-      v = (v & GF_FIRST_BIT) ? ((v << 1) ^ pp) : (v << 1);
-    }
-    for (j = 0; j < 8; j++) {
-      for (k = 0; k < 16; k++) {
-        btable[k] = (uint8_t) ld->tables[i][k];
-        ld->tables[i][k] >>= 8;
-      }
-      tables[i][j] = _mm_loadu_si128((__m128i *) btable);
-    }
-  }
-
-  mask1 = _mm_set1_epi8(0xf);
-  mask8 = _mm_set1_epi16(0xff);
-  mask16 = _mm_set1_epi32(0xffff);
-
-  while (d64 != top) {
-
-    for (i = 0; i < 8; i++) p[i] = _mm_setzero_si128();
-
-    for (k = 0; k < 8; k++) {
-      st[k]  = _mm_load_si128((__m128i *) s64); 
-      s64 += 2;
-    }
-
-    for (k = 0; k < 4; k ++) {
-      st[k] = _mm_shuffle_epi32(st[k], _MM_SHUFFLE(3,1,2,0));
-      st[k+4] = _mm_shuffle_epi32(st[k+4], _MM_SHUFFLE(2,0,3,1));
-      t1 = _mm_blend_epi16(st[k], st[k+4], 0xf0);
-      st[k] = _mm_srli_si128(st[k], 8);
-      st[k+4] = _mm_slli_si128(st[k+4], 8);
-      st[k+4] = _mm_blend_epi16(st[k], st[k+4], 0xf0);
-      st[k] = t1;
-    }
-
-/*
-    printf("After pack pass 1\n");
-    for (k = 0; k < 8; k++) {
-      MM_PRINT8("v", st[k]);
-    }
-    printf("\n");
- */
-    
-    t1 = _mm_packus_epi32(_mm_and_si128(st[0], mask16), _mm_and_si128(st[2], mask16));
-    st[2] = _mm_packus_epi32(_mm_srli_epi32(st[0], 16), _mm_srli_epi32(st[2], 16));
-    st[0] = t1;
-    t1 = _mm_packus_epi32(_mm_and_si128(st[1], mask16), _mm_and_si128(st[3], mask16));
-    st[3] = _mm_packus_epi32(_mm_srli_epi32(st[1], 16), _mm_srli_epi32(st[3], 16));
-    st[1] = t1;
-    t1 = _mm_packus_epi32(_mm_and_si128(st[4], mask16), _mm_and_si128(st[6], mask16));
-    st[6] = _mm_packus_epi32(_mm_srli_epi32(st[4], 16), _mm_srli_epi32(st[6], 16));
-    st[4] = t1;
-    t1 = _mm_packus_epi32(_mm_and_si128(st[5], mask16), _mm_and_si128(st[7], mask16));
-    st[7] = _mm_packus_epi32(_mm_srli_epi32(st[5], 16), _mm_srli_epi32(st[7], 16));
-    st[5] = t1;
-
-/*
-    printf("After pack pass 2\n");
-    for (k = 0; k < 8; k++) {
-      MM_PRINT8("v", st[k]);
-    }
-    printf("\n");
- */
-    t1 = _mm_packus_epi16(_mm_and_si128(st[0], mask8), _mm_and_si128(st[1], mask8));
-    st[1] = _mm_packus_epi16(_mm_srli_epi16(st[0], 8), _mm_srli_epi16(st[1], 8));
-    st[0] = t1;
-    t1 = _mm_packus_epi16(_mm_and_si128(st[2], mask8), _mm_and_si128(st[3], mask8));
-    st[3] = _mm_packus_epi16(_mm_srli_epi16(st[2], 8), _mm_srli_epi16(st[3], 8));
-    st[2] = t1;
-    t1 = _mm_packus_epi16(_mm_and_si128(st[4], mask8), _mm_and_si128(st[5], mask8));
-    st[5] = _mm_packus_epi16(_mm_srli_epi16(st[4], 8), _mm_srli_epi16(st[5], 8));
-    st[4] = t1;
-    t1 = _mm_packus_epi16(_mm_and_si128(st[6], mask8), _mm_and_si128(st[7], mask8));
-    st[7] = _mm_packus_epi16(_mm_srli_epi16(st[6], 8), _mm_srli_epi16(st[7], 8));
-    st[6] = t1;
-
-/*
-    printf("After final pack pass 2\n");
-    for (k = 0; k < 8; k++) {
-      MM_PRINT8("v", st[k]);
-    }
- */
-    i = 0;
-    for (k = 0; k < 8; k++) {
-      si = _mm_and_si128(st[k], mask1);
-  
-      for (j = 0; j < 8; j++) {
-        p[j] = _mm_xor_si128(p[j], _mm_shuffle_epi8(tables[i][j], si));
-      }
-      i++;
-      st[k] = _mm_srli_epi32(st[k], 4);
-      si = _mm_and_si128(st[k], mask1);
-      for (j = 0; j < 8; j++) {
-        p[j] = _mm_xor_si128(p[j], _mm_shuffle_epi8(tables[i][j], si));
-      }
-      i++;
-    }
-
-    t1 = _mm_unpacklo_epi8(p[0], p[1]);
-    p[1] = _mm_unpackhi_epi8(p[0], p[1]);
-    p[0] = t1;
-    t1 = _mm_unpacklo_epi8(p[2], p[3]);
-    p[3] = _mm_unpackhi_epi8(p[2], p[3]);
-    p[2] = t1;
-    t1 = _mm_unpacklo_epi8(p[4], p[5]);
-    p[5] = _mm_unpackhi_epi8(p[4], p[5]);
-    p[4] = t1;
-    t1 = _mm_unpacklo_epi8(p[6], p[7]);
-    p[7] = _mm_unpackhi_epi8(p[6], p[7]);
-    p[6] = t1;
-
-/*
-    printf("After unpack pass 1:\n");
-    for (i = 0; i < 8; i++) {
-      MM_PRINT8("v", p[i]);
-    }
- */
-
-    t1 = _mm_unpacklo_epi16(p[0], p[2]);
-    p[2] = _mm_unpackhi_epi16(p[0], p[2]);
-    p[0] = t1;
-    t1 = _mm_unpacklo_epi16(p[1], p[3]);
-    p[3] = _mm_unpackhi_epi16(p[1], p[3]);
-    p[1] = t1;
-    t1 = _mm_unpacklo_epi16(p[4], p[6]);
-    p[6] = _mm_unpackhi_epi16(p[4], p[6]);
-    p[4] = t1;
-    t1 = _mm_unpacklo_epi16(p[5], p[7]);
-    p[7] = _mm_unpackhi_epi16(p[5], p[7]);
-    p[5] = t1;
-
-/*
-    printf("After unpack pass 2:\n");
-    for (i = 0; i < 8; i++) {
-      MM_PRINT8("v", p[i]);
-    }
- */
-
-    t1 = _mm_unpacklo_epi32(p[0], p[4]);
-    p[4] = _mm_unpackhi_epi32(p[0], p[4]);
-    p[0] = t1;
-    t1 = _mm_unpacklo_epi32(p[1], p[5]);
-    p[5] = _mm_unpackhi_epi32(p[1], p[5]);
-    p[1] = t1;
-    t1 = _mm_unpacklo_epi32(p[2], p[6]);
-    p[6] = _mm_unpackhi_epi32(p[2], p[6]);
-    p[2] = t1;
-    t1 = _mm_unpacklo_epi32(p[3], p[7]);
-    p[7] = _mm_unpackhi_epi32(p[3], p[7]);
-    p[3] = t1;
-
-    if (xor) {
-      for (i = 0; i < 8; i++) {
-        t1 = _mm_load_si128((__m128i *) d64);
-        _mm_store_si128((__m128i *) d64, _mm_xor_si128(p[i], t1));
-        d64 += 2;
-      }
-    } else {
-      for (i = 0; i < 8; i++) {
-        _mm_store_si128((__m128i *) d64, p[i]);
-        d64 += 2;
-      }
-    }
-
-  }
-
-  gf_do_final_region_alignment(&rd);
-}
-#endif
-
-#define GF_MULTBY_TWO(p) (((p) & GF_FIRST_BIT) ? (((p) << 1) ^ h->prim_poly) : (p) << 1);
-
-static
-int gf_w64_split_init(gf_t *gf)
-{
-  gf_internal_t *h;
-  struct gf_split_4_64_lazy_data *d4;
-  struct gf_split_8_64_lazy_data *d8;
-  struct gf_split_8_8_data *d88;
-  struct gf_split_16_64_lazy_data *d16;
-  uint64_t p, basep;
-  int exp, i, j;
-
-  h = (gf_internal_t *) gf->scratch;
-
-  /* Defaults */
-
-  gf->multiply_region.w64 = gf_w64_multiply_region_from_single;
-
-  gf->multiply.w64 = gf_w64_bytwo_p_multiply; 
-
-#if defined(INTEL_SSE4_PCLMUL) 
-  if ((!(h->region_type & GF_REGION_NOSIMD) &&
-     (h->arg1 == 64 || h->arg2 == 64)) ||
-     h->mult_type == GF_MULT_DEFAULT){
-   
-    if ((0xfffffffe00000000ULL & h->prim_poly) == 0){ 
-      gf->multiply.w64 = gf_w64_clm_multiply_2;
-      gf->multiply_region.w64 = gf_w64_clm_multiply_region_from_single_2; 
-    }else if((0xfffe000000000000ULL & h->prim_poly) == 0){
-      gf->multiply.w64 = gf_w64_clm_multiply_4;
-      gf->multiply_region.w64 = gf_w64_clm_multiply_region_from_single_4; 
-    }else{
-      return 0;
-    }
-  }
-#endif
-
-  gf->inverse.w64 = gf_w64_euclid;
-
-  /* Allen: set region pointers for default mult type. Single pointers are
-   * taken care of above (explicitly for sse, implicitly for no sse). */
-
-#if defined(INTEL_SSE4) || defined(ARCH_AARCH64)
-  if (h->mult_type == GF_MULT_DEFAULT) {
-    d4 = (struct gf_split_4_64_lazy_data *) h->private;
-    d4->last_value = 0;
-#if defined(INTEL_SSE4)
-    gf->multiply_region.w64 = gf_w64_split_4_64_lazy_sse_multiply_region; 
-#elif defined(ARCH_AARCH64)
-    gf_w64_neon_split_init(gf);
-#endif
-  }
-#else
-  if (h->mult_type == GF_MULT_DEFAULT) {
-    d8 = (struct gf_split_8_64_lazy_data *) h->private;
-    d8->last_value = 0;
-    gf->multiply_region.w64 = gf_w64_split_8_64_lazy_multiply_region;
-  }
-#endif
-
-  if ((h->arg1 == 4 && h->arg2 == 64) || (h->arg1 == 64 && h->arg2 == 4)) {
-    d4 = (struct gf_split_4_64_lazy_data *) h->private;
-    d4->last_value = 0;
-
-    if((h->region_type & GF_REGION_ALTMAP) && (h->region_type & GF_REGION_NOSIMD)) return 0;
-    if(h->region_type & GF_REGION_ALTMAP)
-    {
-      #ifdef INTEL_SSSE3
-        gf->multiply_region.w64 = gf_w64_split_4_64_lazy_sse_altmap_multiply_region; 
-      #elif defined(ARCH_AARCH64)
-        gf_w64_neon_split_init(gf);
-      #else
-        return 0;
-      #endif
-    }
-    else //no altmap
-    {
-      #if defined(INTEL_SSE4) || defined(ARCH_AARCH64)
-        if(h->region_type & GF_REGION_NOSIMD)
-          gf->multiply_region.w64 = gf_w64_split_4_64_lazy_multiply_region;
-        else
-        #if defined(INTEL_SSE4)
-          gf->multiply_region.w64 = gf_w64_split_4_64_lazy_sse_multiply_region;
-        #elif defined(ARCH_AARCH64)
-          gf_w64_neon_split_init(gf);
-        #endif
-      #else
-        gf->multiply_region.w64 = gf_w64_split_4_64_lazy_multiply_region;
-        if(h->region_type & GF_REGION_SIMD)
-          return 0;
-      #endif
-    }
-  }
-  if ((h->arg1 == 8 && h->arg2 == 64) || (h->arg1 == 64 && h->arg2 == 8)) {
-    d8 = (struct gf_split_8_64_lazy_data *) h->private;
-    d8->last_value = 0;
-    gf->multiply_region.w64 = gf_w64_split_8_64_lazy_multiply_region;
-  }
-  if ((h->arg1 == 16 && h->arg2 == 64) || (h->arg1 == 64 && h->arg2 == 16)) {
-    d16 = (struct gf_split_16_64_lazy_data *) h->private;
-    d16->last_value = 0;
-    gf->multiply_region.w64 = gf_w64_split_16_64_lazy_multiply_region;
-  }
-  if ((h->arg1 == 8 && h->arg2 == 8)) {
-    d88 = (struct gf_split_8_8_data *) h->private;
-    gf->multiply.w64 = gf_w64_split_8_8_multiply;
-
-    /* The performance of this guy sucks, so don't bother with a region op */
-    
-    basep = 1;
-    for (exp = 0; exp < 15; exp++) {
-      for (j = 0; j < 256; j++) d88->tables[exp][0][j] = 0;
-      for (i = 0; i < 256; i++) d88->tables[exp][i][0] = 0;
-      d88->tables[exp][1][1] = basep;
-      for (i = 2; i < 256; i++) {
-        if (i&1) {
-          p = d88->tables[exp][i^1][1];
-          d88->tables[exp][i][1] = p ^ basep;
-        } else {
-          p = d88->tables[exp][i>>1][1];
-          d88->tables[exp][i][1] = GF_MULTBY_TWO(p);
-        }
-      }
-      for (i = 1; i < 256; i++) {
-        p = d88->tables[exp][i][1];
-        for (j = 1; j < 256; j++) {
-          if (j&1) {
-            d88->tables[exp][i][j] = d88->tables[exp][i][j^1] ^ p;
-          } else {
-            d88->tables[exp][i][j] = GF_MULTBY_TWO(d88->tables[exp][i][j>>1]);
-          }
-        }
-      }
-      for (i = 0; i < 8; i++) basep = GF_MULTBY_TWO(basep);
-    }
-  }
-  return 1;
-}
-
-int gf_w64_scratch_size(int mult_type, int region_type, int divide_type, int arg1, int arg2)
-{
-  switch(mult_type)
-  {
-    case GF_MULT_SHIFT:
-      return sizeof(gf_internal_t);
-      break;
-    case GF_MULT_CARRY_FREE:
-      return sizeof(gf_internal_t);
-      break;
-    case GF_MULT_BYTWO_p:
-    case GF_MULT_BYTWO_b:
-      return sizeof(gf_internal_t);
-      break;
-
-    case GF_MULT_DEFAULT:
-
-      /* Allen: set the *local* arg1 and arg2, just for scratch size purposes,
-       * then fall through to split table scratch size code. */
-
-#if defined(INTEL_SSE4) || defined(ARCH_AARCH64)
-      arg1 = 64;
-      arg2 = 4;
-#else
-      arg1 = 64;
-      arg2 = 8;
-#endif
-
-    case GF_MULT_SPLIT_TABLE:
-        if (arg1 == 8 && arg2 == 8) {
-          return sizeof(gf_internal_t) + sizeof(struct gf_split_8_8_data) + 64;
-        }
-        if ((arg1 == 16 && arg2 == 64) || (arg2 == 16 && arg1 == 64)) {
-          return sizeof(gf_internal_t) + sizeof(struct gf_split_16_64_lazy_data) + 64;
-        }
-        if ((arg1 == 8 && arg2 == 64) || (arg2 == 8 && arg1 == 64)) {
-          return sizeof(gf_internal_t) + sizeof(struct gf_split_8_64_lazy_data) + 64;
-        }
-
-        if ((arg1 == 64 && arg2 == 4) || (arg1 == 4 && arg2 == 64)) {
-          return sizeof(gf_internal_t) + sizeof(struct gf_split_4_64_lazy_data) + 64;
-        }
-        return 0;
-    case GF_MULT_GROUP:
-      return sizeof(gf_internal_t) + sizeof(struct gf_w64_group_data) +
-               sizeof(uint64_t) * (1 << arg1) +
-               sizeof(uint64_t) * (1 << arg2) + 64;
-      break;
-    case GF_MULT_COMPOSITE:
-      if (arg1 == 2) return sizeof(gf_internal_t) + 64;
-      return 0;
-      break;
-    default:
-      return 0;
-   }
-}
-
-int gf_w64_init(gf_t *gf)
-{
-  gf_internal_t *h;
-  int no_default_flag = 0;
-
-  h = (gf_internal_t *) gf->scratch;
-  
-  /* Allen: set default primitive polynomial / irreducible polynomial if needed */
-
-  /* Omitting the leftmost 1 as in w=32 */
-
-  if (h->prim_poly == 0) {
-    if (h->mult_type == GF_MULT_COMPOSITE) {
-      h->prim_poly = gf_composite_get_default_poly(h->base_gf);
-      if (h->prim_poly == 0) return 0; /* This shouldn't happen */
-    } else {
-      h->prim_poly = 0x1b;
-    } 
-    if (no_default_flag == 1) { 
-      fprintf(stderr,"Code contains no default irreducible polynomial for given base field\n"); 
-      return 0; 
-    } 
-  }
-
-  gf->multiply.w64 = NULL;
-  gf->divide.w64 = NULL;
-  gf->inverse.w64 = NULL;
-  gf->multiply_region.w64 = NULL;
-
-  switch(h->mult_type) {
-    case GF_MULT_CARRY_FREE:  if (gf_w64_cfm_init(gf) == 0) return 0; break;
-    case GF_MULT_SHIFT:       if (gf_w64_shift_init(gf) == 0) return 0; break;
-    case GF_MULT_COMPOSITE:   if (gf_w64_composite_init(gf) == 0) return 0; break;
-    case GF_MULT_DEFAULT:
-    case GF_MULT_SPLIT_TABLE: if (gf_w64_split_init(gf) == 0) return 0; break; 
-    case GF_MULT_GROUP:       if (gf_w64_group_init(gf) == 0) return 0; break; 
-    case GF_MULT_BYTWO_p:
-    case GF_MULT_BYTWO_b:     if (gf_w64_bytwo_init(gf) == 0) return 0; break;
-    default: return 0;
-  }
-  if (h->divide_type == GF_DIVIDE_EUCLID) {
-    gf->divide.w64 = gf_w64_divide_from_inverse;
-    gf->inverse.w64 = gf_w64_euclid;
-  } 
-
-  if (gf->inverse.w64 != NULL && gf->divide.w64 == NULL) {
-    gf->divide.w64 = gf_w64_divide_from_inverse;
-  }
-  if (gf->inverse.w64 == NULL && gf->divide.w64 != NULL) {
-    gf->inverse.w64 = gf_w64_inverse_from_divide;
-  }
-
-  if (h->region_type == GF_REGION_CAUCHY) return 0;
-
-  if (h->region_type & GF_REGION_ALTMAP) {
-    if (h->mult_type == GF_MULT_COMPOSITE) {
-      gf->extract_word.w64 = gf_w64_composite_extract_word;
-    } else if (h->mult_type == GF_MULT_SPLIT_TABLE) {
-      gf->extract_word.w64 = gf_w64_split_extract_word;
-    }
-  } else {
-    gf->extract_word.w64 = gf_w64_extract_word;
-  }
-
-  return 1;
-}
diff --git a/src/erasure-code/jerasure/gf-complete/src/gf_w8.c b/src/erasure-code/jerasure/gf-complete/src/gf_w8.c
deleted file mode 100644
index 276799f..0000000
--- a/src/erasure-code/jerasure/gf-complete/src/gf_w8.c
+++ /dev/null
@@ -1,2392 +0,0 @@
-/*
- * GF-Complete: A Comprehensive Open Source Library for Galois Field Arithmetic
- * James S. Plank, Ethan L. Miller, Kevin M. Greenan,
- * Benjamin A. Arnold, John A. Burnum, Adam W. Disney, Allen C. McBride.
- *
- * gf_w8.c
- *
- * Routines for 8-bit Galois fields
- */
-
-#include "gf_int.h"
-#include "gf_w8.h"
-#include <stdio.h>
-#include <stdlib.h>
-#include <assert.h>
-
-#define AB2(ip, am1 ,am2, b, t1, t2) {\
-  t1 = (b << 1) & am1;\
-  t2 = b & am2; \
-  t2 = ((t2 << 1) - (t2 >> (GF_FIELD_WIDTH-1))); \
-  b = (t1 ^ (t2 & ip));}
-
-#define SSE_AB2(pp, m1 ,m2, va, t1, t2) {\
-          t1 = _mm_and_si128(_mm_slli_epi64(va, 1), m1); \
-          t2 = _mm_and_si128(va, m2); \
-          t2 = _mm_sub_epi64 (_mm_slli_epi64(t2, 1), _mm_srli_epi64(t2, (GF_FIELD_WIDTH-1))); \
-          va = _mm_xor_si128(t1, _mm_and_si128(t2, pp)); }
-
-#define MM_PRINT(s, r) { uint8_t blah[16], ii; printf("%-12s", s); _mm_storeu_si128((__m128i *)blah, r); for (ii = 0; ii < 16; ii += 2) printf("  %02x %02x", blah[15-ii], blah[14-ii]); printf("\n"); }
-
-static
-inline
-uint32_t gf_w8_inverse_from_divide (gf_t *gf, uint32_t a)
-{
-  return gf->divide.w32(gf, 1, a);
-}
-
-static
-inline
-uint32_t gf_w8_divide_from_inverse (gf_t *gf, uint32_t a, uint32_t b)
-{
-  b = gf->inverse.w32(gf, b);
-  return gf->multiply.w32(gf, a, b);
-}
-
-static
-inline
-uint32_t gf_w8_euclid (gf_t *gf, uint32_t b)
-{
-  uint32_t e_i, e_im1, e_ip1;
-  uint32_t d_i, d_im1, d_ip1;
-  uint32_t y_i, y_im1, y_ip1;
-  uint32_t c_i;
-
-  if (b == 0) return -1;
-  e_im1 = ((gf_internal_t *) (gf->scratch))->prim_poly;
-  e_i = b;
-  d_im1 = 8;
-  for (d_i = d_im1; ((1 << d_i) & e_i) == 0; d_i--) ;
-  y_i = 1;
-  y_im1 = 0;
-
-  while (e_i != 1) {
-
-    e_ip1 = e_im1;
-    d_ip1 = d_im1;
-    c_i = 0;
-
-    while (d_ip1 >= d_i) {
-      c_i ^= (1 << (d_ip1 - d_i));
-      e_ip1 ^= (e_i << (d_ip1 - d_i));
-      if (e_ip1 == 0) return 0;
-      while ((e_ip1 & (1 << d_ip1)) == 0) d_ip1--;
-    }
-
-    y_ip1 = y_im1 ^ gf->multiply.w32(gf, c_i, y_i);
-    y_im1 = y_i;
-    y_i = y_ip1;
-
-    e_im1 = e_i;
-    d_im1 = d_i;
-    e_i = e_ip1;
-    d_i = d_ip1;
-  }
-
-  return y_i;
-}
-
-static
-gf_val_32_t gf_w8_extract_word(gf_t *gf, void *start, int bytes, int index)
-{
-  uint8_t *r8;
-
-  r8 = (uint8_t *) start;
-  return r8[index];
-}
-
-static
-gf_val_32_t gf_w8_composite_extract_word(gf_t *gf, void *start, int bytes, int index)
-{
-  int sub_size;
-  gf_internal_t *h;
-  uint8_t *r8, *top;
-  uint8_t a, b;
-  gf_region_data rd;
-
-  h = (gf_internal_t *) gf->scratch;
-  gf_set_region_data(&rd, gf, start, start, bytes, 0, 0, 32);
-  r8 = (uint8_t *) start;
-  if (r8 + index < (uint8_t *) rd.d_start) return r8[index];
-  if (r8 + index >= (uint8_t *) rd.d_top) return r8[index];
-  index -= (((uint8_t *) rd.d_start) - r8);
-  r8 = (uint8_t *) rd.d_start;
-  top = (uint8_t *) rd.d_top;
-  sub_size = (top-r8)/2;
-
-  a = h->base_gf->extract_word.w32(h->base_gf, r8, sub_size, index);
-  b = h->base_gf->extract_word.w32(h->base_gf, r8+sub_size, sub_size, index);
-  return (a | (b << 4));
-}
-
-static
-inline
-uint32_t gf_w8_matrix (gf_t *gf, uint32_t b)
-{
-  return gf_bitmatrix_inverse(b, 8, ((gf_internal_t *) (gf->scratch))->prim_poly);
-}
-
-
-static
-inline
-gf_val_32_t
-gf_w8_clm_multiply_2 (gf_t *gf, gf_val_32_t a8, gf_val_32_t b8)
-{
-  gf_val_32_t rv = 0;
-
-#if defined(INTEL_SSE4_PCLMUL)
-
-  __m128i         a, b;
-  __m128i         result;
-  __m128i         prim_poly;
-  __m128i         w;
-  gf_internal_t * h = gf->scratch;
-
-  a = _mm_insert_epi32 (_mm_setzero_si128(), a8, 0);
-  b = _mm_insert_epi32 (a, b8, 0);
-
-  prim_poly = _mm_set_epi32(0, 0, 0, (uint32_t)(h->prim_poly & 0x1ffULL));
-
-  /* Do the initial multiply */
-
-  result = _mm_clmulepi64_si128 (a, b, 0);
-
-  /* Ben: Do prim_poly reduction twice. We are guaranteed that we will only
-     have to do the reduction at most twice, because (w-2)/z == 2. Where
-     z is equal to the number of zeros after the leading 1
-
-     _mm_clmulepi64_si128 is the carryless multiply operation. Here
-     _mm_srli_si128 shifts the result to the right by 1 byte. This allows
-     us to multiply the prim_poly by the leading bits of the result. We
-     then xor the result of that operation back with the result.*/
-
-  w = _mm_clmulepi64_si128 (prim_poly, _mm_srli_si128 (result, 1), 0);
-  result = _mm_xor_si128 (result, w);
-  w = _mm_clmulepi64_si128 (prim_poly, _mm_srli_si128 (result, 1), 0);
-  result = _mm_xor_si128 (result, w);
-
-  /* Extracts 32 bit value from result. */
-  
-  rv = ((gf_val_32_t)_mm_extract_epi32(result, 0));
-
-#endif
-  return rv;
-}
-
-static
-inline
-gf_val_32_t
-gf_w8_clm_multiply_3 (gf_t *gf, gf_val_32_t a8, gf_val_32_t b8)
-{
-  gf_val_32_t rv = 0;
-
-#if defined(INTEL_SSE4_PCLMUL)
-
-  __m128i         a, b;
-  __m128i         result;
-  __m128i         prim_poly;
-  __m128i         w;
-  gf_internal_t * h = gf->scratch;
-
-  a = _mm_insert_epi32 (_mm_setzero_si128(), a8, 0);
-  b = _mm_insert_epi32 (a, b8, 0);
-
-  prim_poly = _mm_set_epi32(0, 0, 0, (uint32_t)(h->prim_poly & 0x1ffULL));
-
-  /* Do the initial multiply */
-  
-  result = _mm_clmulepi64_si128 (a, b, 0);
-
-  w = _mm_clmulepi64_si128 (prim_poly, _mm_srli_si128 (result, 1), 0);
-  result = _mm_xor_si128 (result, w);
-  w = _mm_clmulepi64_si128 (prim_poly, _mm_srli_si128 (result, 1), 0);
-  result = _mm_xor_si128 (result, w);
-  w = _mm_clmulepi64_si128 (prim_poly, _mm_srli_si128 (result, 1), 0);
-  result = _mm_xor_si128 (result, w);
-
-  /* Extracts 32 bit value from result. */
-  
-  rv = ((gf_val_32_t)_mm_extract_epi32(result, 0));
-
-#endif
-  return rv;
-}
-
-static
-inline
-gf_val_32_t
-gf_w8_clm_multiply_4 (gf_t *gf, gf_val_32_t a8, gf_val_32_t b8)
-{
-  gf_val_32_t rv = 0;
-
-#if defined(INTEL_SSE4_PCLMUL)
-
-  __m128i         a, b;
-  __m128i         result;
-  __m128i         prim_poly;
-  __m128i         w;
-  gf_internal_t * h = gf->scratch;
-
-  a = _mm_insert_epi32 (_mm_setzero_si128(), a8, 0);
-  b = _mm_insert_epi32 (a, b8, 0);
-
-  prim_poly = _mm_set_epi32(0, 0, 0, (uint32_t)(h->prim_poly & 0x1ffULL));
-
-  /* Do the initial multiply */
-  
-  result = _mm_clmulepi64_si128 (a, b, 0);
-
-  w = _mm_clmulepi64_si128 (prim_poly, _mm_srli_si128 (result, 1), 0);
-  result = _mm_xor_si128 (result, w);
-  w = _mm_clmulepi64_si128 (prim_poly, _mm_srli_si128 (result, 1), 0);
-  result = _mm_xor_si128 (result, w);
-  w = _mm_clmulepi64_si128 (prim_poly, _mm_srli_si128 (result, 1), 0);
-  result = _mm_xor_si128 (result, w);
-  w = _mm_clmulepi64_si128 (prim_poly, _mm_srli_si128 (result, 1), 0);
-  result = _mm_xor_si128 (result, w);
-
-  /* Extracts 32 bit value from result. */
-  rv = ((gf_val_32_t)_mm_extract_epi32(result, 0));
-
-#endif
-  return rv;
-}
-
-
-static
-void
-gf_w8_multiply_region_from_single(gf_t *gf, void *src, void *dest, gf_val_32_t val, int bytes, int
-    xor)
-{
-  gf_region_data rd;
-  uint8_t *s8;
-  uint8_t *d8;
-
-  if (val == 0) { gf_multby_zero(dest, bytes, xor); return; }
-  if (val == 1) { gf_multby_one(src, dest, bytes, xor); return; }
-
-  gf_set_region_data(&rd, gf, src, dest, bytes, val, xor, 1);
-  gf_do_initial_region_alignment(&rd);
-
-  s8 = (uint8_t *) rd.s_start;
-  d8 = (uint8_t *) rd.d_start;
-
-  if (xor) {
-    while (d8 < ((uint8_t *) rd.d_top)) {
-      *d8 ^= gf->multiply.w32(gf, val, *s8);
-      d8++;
-      s8++;
-    }
-  } else {
-    while (d8 < ((uint8_t *) rd.d_top)) {
-      *d8 = gf->multiply.w32(gf, val, *s8);
-      d8++;
-      s8++;
-    }
-  }
-  gf_do_final_region_alignment(&rd);
-}
-
-#if defined(INTEL_SSE4_PCLMUL)
-static
-void
-gf_w8_clm_multiply_region_from_single_2(gf_t *gf, void *src, void *dest, gf_val_32_t val, int bytes, int
-    xor)
-{
-  gf_region_data rd;
-  uint8_t *s8;
-  uint8_t *d8;
-
-  __m128i         a, b;
-  __m128i         result;
-  __m128i         prim_poly;
-  __m128i         w;
-  gf_internal_t * h = gf->scratch;
-
-  prim_poly = _mm_set_epi32(0, 0, 0, (uint32_t)(h->prim_poly & 0x1ffULL));
-
-  if (val == 0) { gf_multby_zero(dest, bytes, xor); return; }
-  if (val == 1) { gf_multby_one(src, dest, bytes, xor); return; }
-
-  a = _mm_insert_epi32 (_mm_setzero_si128(), val, 0);
-
-  gf_set_region_data(&rd, gf, src, dest, bytes, val, xor, 1);
-  gf_do_initial_region_alignment(&rd);
-
-  s8 = (uint8_t *) rd.s_start;
-  d8 = (uint8_t *) rd.d_start;
-
-  if (xor) {
-    while (d8 < ((uint8_t *) rd.d_top)) {
-      b = _mm_insert_epi32 (a, (gf_val_32_t)(*s8), 0);
-      result = _mm_clmulepi64_si128 (a, b, 0);
-      w = _mm_clmulepi64_si128 (prim_poly, _mm_srli_si128 (result, 1), 0);
-      result = _mm_xor_si128 (result, w);
-      w = _mm_clmulepi64_si128 (prim_poly, _mm_srli_si128 (result, 1), 0);
-      result = _mm_xor_si128 (result, w);
-      *d8 ^= ((gf_val_32_t)_mm_extract_epi32(result, 0));
-      d8++;
-      s8++;
-    }
-  } else {
-    while (d8 < ((uint8_t *) rd.d_top)) {
-      b = _mm_insert_epi32 (a, (gf_val_32_t)(*s8), 0);
-      result = _mm_clmulepi64_si128 (a, b, 0);
-      w = _mm_clmulepi64_si128 (prim_poly, _mm_srli_si128 (result, 1), 0);
-      result = _mm_xor_si128 (result, w);
-      w = _mm_clmulepi64_si128 (prim_poly, _mm_srli_si128 (result, 1), 0);
-      result = _mm_xor_si128 (result, w);
-      *d8 = ((gf_val_32_t)_mm_extract_epi32(result, 0));
-      d8++;
-      s8++;
-    }
-  }
-  gf_do_final_region_alignment(&rd);
-}
-#endif
-
-#if defined(INTEL_SSE4_PCLMUL)
-static
-void
-gf_w8_clm_multiply_region_from_single_3(gf_t *gf, void *src, void *dest, gf_val_32_t val, int bytes, int
-    xor)
-{
-  gf_region_data rd;
-  uint8_t *s8;
-  uint8_t *d8;
-
-  __m128i         a, b;
-  __m128i         result;
-  __m128i         prim_poly;
-  __m128i         w;
-  gf_internal_t * h = gf->scratch;
-
-  prim_poly = _mm_set_epi32(0, 0, 0, (uint32_t)(h->prim_poly & 0x1ffULL));
-
-  if (val == 0) { gf_multby_zero(dest, bytes, xor); return; }
-  if (val == 1) { gf_multby_one(src, dest, bytes, xor); return; }
-
-  a = _mm_insert_epi32 (_mm_setzero_si128(), val, 0);
-
-  gf_set_region_data(&rd, gf, src, dest, bytes, val, xor, 1);
-  gf_do_initial_region_alignment(&rd);
-
-  s8 = (uint8_t *) rd.s_start;
-  d8 = (uint8_t *) rd.d_start;
-
-  if (xor) {
-    while (d8 < ((uint8_t *) rd.d_top)) {
-      b = _mm_insert_epi32 (a, (gf_val_32_t)(*s8), 0);
-      result = _mm_clmulepi64_si128 (a, b, 0);
-      w = _mm_clmulepi64_si128 (prim_poly, _mm_srli_si128 (result, 1), 0);
-      result = _mm_xor_si128 (result, w);
-      w = _mm_clmulepi64_si128 (prim_poly, _mm_srli_si128 (result, 1), 0);
-      result = _mm_xor_si128 (result, w);
-      w = _mm_clmulepi64_si128 (prim_poly, _mm_srli_si128 (result, 1), 0);
-      result = _mm_xor_si128 (result, w);
-      *d8 ^= ((gf_val_32_t)_mm_extract_epi32(result, 0));
-      d8++;
-      s8++;
-    }
-  } else {
-    while (d8 < ((uint8_t *) rd.d_top)) {
-      b = _mm_insert_epi32 (a, (gf_val_32_t)(*s8), 0);
-      result = _mm_clmulepi64_si128 (a, b, 0);
-      w = _mm_clmulepi64_si128 (prim_poly, _mm_srli_si128 (result, 1), 0);
-      result = _mm_xor_si128 (result, w);
-      w = _mm_clmulepi64_si128 (prim_poly, _mm_srli_si128 (result, 1), 0);
-      result = _mm_xor_si128 (result, w);
-      w = _mm_clmulepi64_si128 (prim_poly, _mm_srli_si128 (result, 1), 0);
-      result = _mm_xor_si128 (result, w);
-      *d8 = ((gf_val_32_t)_mm_extract_epi32(result, 0));
-      d8++;
-      s8++;
-    }
-  }
-  gf_do_final_region_alignment(&rd);
-}
-#endif
-
-#if defined(INTEL_SSE4_PCLMUL)
-static
-void
-gf_w8_clm_multiply_region_from_single_4(gf_t *gf, void *src, void *dest, gf_val_32_t val, int bytes, int
-    xor)
-{
-  gf_region_data rd;
-  uint8_t *s8;
-  uint8_t *d8;
-
-  __m128i         a, b;
-  __m128i         result;
-  __m128i         prim_poly;
-  __m128i         w;
-  gf_internal_t * h = gf->scratch;
-
-  prim_poly = _mm_set_epi32(0, 0, 0, (uint32_t)(h->prim_poly & 0x1ffULL));
-
-  if (val == 0) { gf_multby_zero(dest, bytes, xor); return; }
-  if (val == 1) { gf_multby_one(src, dest, bytes, xor); return; }
-
-  a = _mm_insert_epi32 (_mm_setzero_si128(), val, 0);
-
-  gf_set_region_data(&rd, gf, src, dest, bytes, val, xor, 1);
-  gf_do_initial_region_alignment(&rd);
-
-  s8 = (uint8_t *) rd.s_start;
-  d8 = (uint8_t *) rd.d_start;
-
-  if (xor) {
-    while (d8 < ((uint8_t *) rd.d_top)) {
-      b = _mm_insert_epi32 (a, (gf_val_32_t)(*s8), 0);
-      result = _mm_clmulepi64_si128 (a, b, 0);
-      w = _mm_clmulepi64_si128 (prim_poly, _mm_srli_si128 (result, 1), 0);
-      result = _mm_xor_si128 (result, w);
-      w = _mm_clmulepi64_si128 (prim_poly, _mm_srli_si128 (result, 1), 0);
-      result = _mm_xor_si128 (result, w);
-      w = _mm_clmulepi64_si128 (prim_poly, _mm_srli_si128 (result, 1), 0);
-      result = _mm_xor_si128 (result, w);
-      w = _mm_clmulepi64_si128 (prim_poly, _mm_srli_si128 (result, 1), 0);
-      result = _mm_xor_si128 (result, w);
-      *d8 ^= ((gf_val_32_t)_mm_extract_epi32(result, 0));
-      d8++;
-      s8++;
-    }
-  } else {
-    while (d8 < ((uint8_t *) rd.d_top)) {
-      b = _mm_insert_epi32 (a, (gf_val_32_t)(*s8), 0);
-      result = _mm_clmulepi64_si128 (a, b, 0);
-      w = _mm_clmulepi64_si128 (prim_poly, _mm_srli_si128 (result, 1), 0);
-      result = _mm_xor_si128 (result, w);
-      w = _mm_clmulepi64_si128 (prim_poly, _mm_srli_si128 (result, 1), 0);
-      result = _mm_xor_si128 (result, w);
-      w = _mm_clmulepi64_si128 (prim_poly, _mm_srli_si128 (result, 1), 0);
-      result = _mm_xor_si128 (result, w);
-      w = _mm_clmulepi64_si128 (prim_poly, _mm_srli_si128 (result, 1), 0);
-      result = _mm_xor_si128 (result, w);
-      *d8 = ((gf_val_32_t)_mm_extract_epi32(result, 0));
-      d8++;
-      s8++;
-    }
-  }
-  gf_do_final_region_alignment(&rd);
-}
-#endif
-
-/* ------------------------------------------------------------
-IMPLEMENTATION: SHIFT:
-
-JSP: The world's dumbest multiplication algorithm.  I only
-include it for completeness.  It does have the feature that it requires no
-extra memory.  
- */
-
-static
-inline
-  uint32_t
-gf_w8_shift_multiply (gf_t *gf, uint32_t a8, uint32_t b8)
-{
-  uint16_t product, i, pp, a, b;
-  gf_internal_t *h;
-
-  a = a8;
-  b = b8;
-  h = (gf_internal_t *) gf->scratch;
-  pp = h->prim_poly;
-
-  product = 0;
-
-  for (i = 0; i < GF_FIELD_WIDTH; i++) { 
-    if (a & (1 << i)) product ^= (b << i);
-  }
-  for (i = (GF_FIELD_WIDTH*2-2); i >= GF_FIELD_WIDTH; i--) {
-    if (product & (1 << i)) product ^= (pp << (i-GF_FIELD_WIDTH)); 
-  }
-  return product;
-}
-
-static 
-int gf_w8_cfm_init(gf_t *gf)
-{ 
-#if defined(INTEL_SSE4_PCLMUL)
-  gf_internal_t *h;
-
-  h = (gf_internal_t *) gf->scratch;
-
-    if ((0xe0 & h->prim_poly) == 0){
-      gf->multiply.w32 = gf_w8_clm_multiply_2;
-      gf->multiply_region.w32 = gf_w8_clm_multiply_region_from_single_2;
-    }else if ((0xc0 & h->prim_poly) == 0){
-      gf->multiply.w32 = gf_w8_clm_multiply_3;
-      gf->multiply_region.w32 = gf_w8_clm_multiply_region_from_single_3;
-    }else if ((0x80 & h->prim_poly) == 0){ 
-      gf->multiply.w32 = gf_w8_clm_multiply_4;
-      gf->multiply_region.w32 = gf_w8_clm_multiply_region_from_single_4;
-    }else{
-      return 0;
-    }
-  return 1;
-#elif defined(ARM_NEON)
-  return gf_w8_neon_cfm_init(gf);
-#endif
-
-  return 0;
-
-}
-
-static 
-int gf_w8_shift_init(gf_t *gf)
-{ 
-  gf->multiply.w32 = gf_w8_shift_multiply;  /* The others will be set automatically */
-  return 1;
-}
-
-/* ------------------------------------------------------------
-IMPLEMENTATION: LOG_TABLE:
-
-JSP: Kevin wrote this, and I'm converting it to my structure.
-*/
-
-static
-inline
-  uint32_t
-gf_w8_logzero_multiply (gf_t *gf, uint32_t a, uint32_t b)
-{
-  struct gf_w8_logzero_table_data *ltd;
-
-  ltd = (struct gf_w8_logzero_table_data *) ((gf_internal_t *) gf->scratch)->private;
-  return ltd->antilog_tbl[ltd->log_tbl[a] + ltd->log_tbl[b]];
-}
-
-static
-inline
-  uint32_t
-gf_w8_logzero_divide (gf_t *gf, uint32_t a, uint32_t b)
-{
-  struct gf_w8_logzero_table_data *ltd;
-
-  ltd = (struct gf_w8_logzero_table_data *) ((gf_internal_t *) gf->scratch)->private;
-  return ltd->div_tbl[ltd->log_tbl[a] - ltd->log_tbl[b]];
-}
-
-static
-inline
-  uint32_t
-gf_w8_logzero_small_multiply (gf_t *gf, uint32_t a, uint32_t b)
-{
-  struct gf_w8_logzero_small_table_data *std;
-
-  std = (struct gf_w8_logzero_small_table_data *) ((gf_internal_t *) gf->scratch)->private;
-  if (b == 0) return 0;
-  return std->antilog_tbl[std->log_tbl[a] + std->log_tbl[b]];
-}
-
-static
-inline
-  uint32_t
-gf_w8_logzero_small_divide (gf_t *gf, uint32_t a, uint32_t b)
-{
-  struct gf_w8_logzero_small_table_data *std;
-
-  std = (struct gf_w8_logzero_small_table_data *) ((gf_internal_t *) gf->scratch)->private;
-  return std->div_tbl[std->log_tbl[a] - std->log_tbl[b]];
-}
-
-static
-inline
-  uint32_t
-gf_w8_log_multiply (gf_t *gf, uint32_t a, uint32_t b)
-{
-  struct gf_w8_logtable_data *ltd;
-
-  ltd = (struct gf_w8_logtable_data *) ((gf_internal_t *) gf->scratch)->private;
-  return (a == 0 || b == 0) ? 0 : ltd->antilog_tbl[(unsigned)(ltd->log_tbl[a] + ltd->log_tbl[b])];
-}
-
-static
-inline
-  uint32_t
-gf_w8_log_divide (gf_t *gf, uint32_t a, uint32_t b)
-{
-  int log_sum = 0;
-  struct gf_w8_logtable_data *ltd;
-
-  if (a == 0 || b == 0) return 0;
-  ltd = (struct gf_w8_logtable_data *) ((gf_internal_t *) gf->scratch)->private;
-
-  log_sum = ltd->log_tbl[a] - ltd->log_tbl[b] + (GF_MULT_GROUP_SIZE);
-  return (ltd->antilog_tbl[log_sum]);
-}
-
-static
-  uint32_t
-gf_w8_log_inverse (gf_t *gf, uint32_t a)
-{
-  struct gf_w8_logtable_data *ltd;
-
-  ltd = (struct gf_w8_logtable_data *) ((gf_internal_t *) gf->scratch)->private;
-  return (ltd->inv_tbl[a]);
-}
-
-static
-  uint32_t
-gf_w8_logzero_inverse (gf_t *gf, uint32_t a)
-{
-  struct gf_w8_logzero_table_data *ltd;
-
-  ltd = (struct gf_w8_logzero_table_data *) ((gf_internal_t *) gf->scratch)->private;
-  return (ltd->inv_tbl[a]);
-}
-
-static
-  uint32_t
-gf_w8_logzero_small_inverse (gf_t *gf, uint32_t a)
-{
-  struct gf_w8_logzero_small_table_data *std;
-
-  std = (struct gf_w8_logzero_small_table_data *) ((gf_internal_t *) gf->scratch)->private;
-  return (std->inv_tbl[a]);
-}
-
-static
-  void
-gf_w8_log_multiply_region(gf_t *gf, void *src, void *dest, uint32_t val, int bytes, int xor)
-{
-  int i;
-  uint8_t lv;
-  uint8_t *s8, *d8;
-  struct gf_w8_logtable_data *ltd;
-
-  if (val == 0) { gf_multby_zero(dest, bytes, xor); return; }
-  if (val == 1) { gf_multby_one(src, dest, bytes, xor); return; }
-
-  ltd = (struct gf_w8_logtable_data *) ((gf_internal_t *) gf->scratch)->private;
-  s8 = (uint8_t *) src;
-  d8 = (uint8_t *) dest;
-
-  lv = ltd->log_tbl[val];
-
-  if (xor) {
-    for (i = 0; i < bytes; i++) {
-      d8[i] ^= (s8[i] == 0 ? 0 : ltd->antilog_tbl[lv + ltd->log_tbl[s8[i]]]);
-    }
-  } else {
-    for (i = 0; i < bytes; i++) {
-      d8[i] = (s8[i] == 0 ? 0 : ltd->antilog_tbl[lv + ltd->log_tbl[s8[i]]]);
-    }
-  }
-}
-
-static
-  void
-gf_w8_logzero_multiply_region(gf_t *gf, void *src, void *dest, uint32_t val, int bytes, int xor)
-{
-  int i;
-  uint8_t lv;
-  uint8_t *s8, *d8;
-  struct gf_w8_logzero_table_data *ltd;
-  struct gf_w8_logzero_small_table_data *std;
-  short *log;
-  uint8_t *alt;
-  gf_internal_t *h;
-
-  if (val == 0) { gf_multby_zero(dest, bytes, xor); return; }
-  if (val == 1) { gf_multby_one(src, dest, bytes, xor); return; }
-
-  h = (gf_internal_t *) gf->scratch;
-
-  if (h->arg1 == 1) {
-    std = (struct gf_w8_logzero_small_table_data *) h->private;
-    log = std->log_tbl;
-    alt = std->antilog_tbl;
-  } else {
-    ltd = (struct gf_w8_logzero_table_data *) h->private;
-    log = ltd->log_tbl;
-    alt = ltd->antilog_tbl;
-  }
-  s8 = (uint8_t *) src;
-  d8 = (uint8_t *) dest;
-
-  lv = log[val];
-
-  if (xor) {
-    for (i = 0; i < bytes; i++) {
-      d8[i] ^= (alt[lv + log[s8[i]]]);
-    }
-  } else {
-    for (i = 0; i < bytes; i++) {
-      d8[i] = (alt[lv + log[s8[i]]]);
-    }
-  }
-}
-
-  static
-int gf_w8_log_init(gf_t *gf)
-{
-  gf_internal_t *h;
-  struct gf_w8_logtable_data *ltd = NULL;
-  struct gf_w8_logzero_table_data *ztd = NULL;
-  struct gf_w8_logzero_small_table_data *std = NULL;
-  uint8_t *alt;
-  uint8_t *inv;
-  int i, b;
-  int check = 0;
-
-  h = (gf_internal_t *) gf->scratch;
-  if (h->mult_type == GF_MULT_LOG_TABLE) {
-    ltd = h->private;
-    alt = ltd->antilog_tbl;
-    inv = ltd->inv_tbl;
-  } else if (h->mult_type == GF_MULT_LOG_ZERO) {
-    std = h->private;
-    alt = std->antilog_tbl;
-    std->div_tbl = (alt + 255);
-    inv = std->inv_tbl;
-  } else {
-    ztd = h->private;
-    alt = ztd->antilog_tbl;
-    ztd->inv_tbl = (alt + 512 + 256);
-    ztd->div_tbl = (alt + 255);
-    inv = ztd->inv_tbl;
-  }
-
-  for (i = 0; i < GF_MULT_GROUP_SIZE+1; i++) {
-    if (h->mult_type == GF_MULT_LOG_TABLE)
-      ltd->log_tbl[i] = 0;
-    else if (h->mult_type == GF_MULT_LOG_ZERO)
-      std->log_tbl[i] = 0;
-    else
-      ztd->log_tbl[i] = 0;
-  }
-
-  if (h->mult_type == GF_MULT_LOG_TABLE) {
-    ltd->log_tbl[0] = 0;
-  } else if (h->mult_type == GF_MULT_LOG_ZERO) {
-    std->log_tbl[0] = 510;
-  } else {
-    ztd->log_tbl[0] = 512;
-  }
-
-  b = 1;
-  for (i = 0; i < GF_MULT_GROUP_SIZE; i++) {
-    if (h->mult_type == GF_MULT_LOG_TABLE) {
-      if (ltd->log_tbl[b] != 0) check = 1;
-      ltd->log_tbl[b] = i;
-    } else if (h->mult_type == GF_MULT_LOG_ZERO) {
-      if (std->log_tbl[b] != 0) check = 1;
-      std->log_tbl[b] = i;
-    } else {
-      if (ztd->log_tbl[b] != 0) check = 1;
-      ztd->log_tbl[b] = i;
-    }
-    alt[i] = b;
-    alt[i+GF_MULT_GROUP_SIZE] = b;
-    b <<= 1;
-    if (b & GF_FIELD_SIZE) {
-      b = b ^ h->prim_poly;
-    }
-  }
-  if (check) {
-    _gf_errno = GF_E_LOGPOLY;
-    return 0;
-  }
-
-  if (h->mult_type == GF_MULT_LOG_ZERO) bzero(alt+510, 255);
-
-  if (h->mult_type == GF_MULT_LOG_ZERO_EXT) {
-    bzero(alt+512, 255);
-    alt[512+512] = 0;
-  }
-
-  inv[0] = 0;  /* Not really, but we need to fill it with something  */
-  i = 1;
-  b = GF_MULT_GROUP_SIZE;
-  do {
-    inv[i] = alt[b];
-    i <<= 1;
-    if (i & (1 << 8)) i ^= h->prim_poly;
-    b--;
-  } while (i != 1);
-
-  if (h->mult_type == GF_MULT_LOG_TABLE) {
-    gf->inverse.w32 = gf_w8_log_inverse;
-    gf->divide.w32 = gf_w8_log_divide;
-    gf->multiply.w32 = gf_w8_log_multiply;
-    gf->multiply_region.w32 = gf_w8_log_multiply_region;
-  } else if (h->mult_type == GF_MULT_LOG_ZERO) {
-    gf->inverse.w32 = gf_w8_logzero_small_inverse;
-    gf->divide.w32 = gf_w8_logzero_small_divide;
-    gf->multiply.w32 = gf_w8_logzero_small_multiply;
-    gf->multiply_region.w32 = gf_w8_logzero_multiply_region;
-  } else {
-    gf->inverse.w32 = gf_w8_logzero_inverse;
-    gf->divide.w32 = gf_w8_logzero_divide;
-    gf->multiply.w32 = gf_w8_logzero_multiply;
-    gf->multiply_region.w32 = gf_w8_logzero_multiply_region;
-  }
-  return 1;
-}
-
-/* ------------------------------------------------------------
-IMPLEMENTATION: FULL_TABLE:
-
-JSP: Kevin wrote this, and I'm converting it to my structure.
- */
-
-static
-  gf_val_32_t
-gf_w8_table_multiply(gf_t *gf, gf_val_32_t a, gf_val_32_t b)
-{
-  struct gf_w8_single_table_data *ftd;
-
-  ftd = (struct gf_w8_single_table_data *) ((gf_internal_t *) gf->scratch)->private;
-  return (ftd->multtable[a][b]);
-}
-
-static
-  gf_val_32_t
-gf_w8_table_divide(gf_t *gf, gf_val_32_t a, gf_val_32_t b)
-{
-  struct gf_w8_single_table_data *ftd;
-
-  ftd = (struct gf_w8_single_table_data *) ((gf_internal_t *) gf->scratch)->private;
-  return (ftd->divtable[a][b]);
-}
-
-static
-  gf_val_32_t
-gf_w8_default_multiply(gf_t *gf, gf_val_32_t a, gf_val_32_t b)
-{
-  struct gf_w8_default_data *ftd;
-
-  ftd = (struct gf_w8_default_data *) ((gf_internal_t *) gf->scratch)->private;
-  return (ftd->multtable[a][b]);
-}
-
-#if defined(INTEL_SSSE3) || defined(ARM_NEON)
-static
-  gf_val_32_t
-gf_w8_default_divide(gf_t *gf, gf_val_32_t a, gf_val_32_t b)
-{
-  struct gf_w8_default_data *ftd;
-
-  ftd = (struct gf_w8_default_data *) ((gf_internal_t *) gf->scratch)->private;
-  return (ftd->divtable[a][b]);
-}
-#endif
-
-static
-  gf_val_32_t
-gf_w8_double_table_multiply(gf_t *gf, gf_val_32_t a, gf_val_32_t b)
-{
-  struct gf_w8_double_table_data *ftd;
-
-  ftd = (struct gf_w8_double_table_data *) ((gf_internal_t *) gf->scratch)->private;
-  return (ftd->mult[a][b]);
-}
-
-static
-  gf_val_32_t
-gf_w8_double_table_divide(gf_t *gf, gf_val_32_t a, gf_val_32_t b)
-{
-  struct gf_w8_double_table_data *ftd;
-
-  ftd = (struct gf_w8_double_table_data *) ((gf_internal_t *) gf->scratch)->private;
-  return (ftd->div[a][b]);
-}
-
-static
-  void
-gf_w8_double_table_multiply_region(gf_t *gf, void *src, void *dest, gf_val_32_t val, int bytes, int xor)
-{
-  uint16_t *base;
-  uint32_t b, c, vc, vb;
-  gf_internal_t *h;
-  struct gf_w8_double_table_data  *dtd;
-  struct gf_w8_double_table_lazy_data  *ltd;
-  gf_region_data rd;
-
-  if (val == 0) { gf_multby_zero(dest, bytes, xor); return; }
-  if (val == 1) { gf_multby_one(src, dest, bytes, xor); return; }
-
-  h = (gf_internal_t *) (gf->scratch);
-  if (h->region_type & GF_REGION_LAZY) {
-    ltd = (struct gf_w8_double_table_lazy_data *) h->private;
-    base = ltd->mult;
-    for (b = 0; b < GF_FIELD_SIZE; b++) {
-      vb = (ltd->smult[val][b] << 8);
-      for (c = 0; c < GF_FIELD_SIZE; c++) {
-        vc = ltd->smult[val][c];
-        base[(b << 8)| c] = (vb | vc);
-      }
-    }
-
-  } else {
-    dtd = (struct gf_w8_double_table_data *) h->private;
-    base = &(dtd->mult[val][0]);
-  }
-
-  gf_set_region_data(&rd, gf, src, dest, bytes, val, xor, 8);
-  gf_do_initial_region_alignment(&rd);
-  gf_two_byte_region_table_multiply(&rd, base);
-  gf_do_final_region_alignment(&rd);
-}
-
-static
-  gf_val_32_t
-gf_w8_double_table_lazy_multiply(gf_t *gf, gf_val_32_t a, gf_val_32_t b)
-{
-  struct gf_w8_double_table_lazy_data *ftd;
-
-  ftd = (struct gf_w8_double_table_lazy_data *) ((gf_internal_t *) gf->scratch)->private;
-  return (ftd->smult[a][b]);
-}
-
-static
-  gf_val_32_t
-gf_w8_double_table_lazy_divide(gf_t *gf, gf_val_32_t a, gf_val_32_t b)
-{
-  struct gf_w8_double_table_lazy_data *ftd;
-
-  ftd = (struct gf_w8_double_table_lazy_data *) ((gf_internal_t *) gf->scratch)->private;
-  return (ftd->div[a][b]);
-}
-
-static
-  void
-gf_w8_table_multiply_region(gf_t *gf, void *src, void *dest, gf_val_32_t val, int bytes, int xor)
-{
-  int i;
-  uint8_t *s8, *d8;
-  struct gf_w8_single_table_data *ftd;
-
-  if (val == 0) { gf_multby_zero(dest, bytes, xor); return; }
-  if (val == 1) { gf_multby_one(src, dest, bytes, xor); return; }
-
-  ftd = (struct gf_w8_single_table_data *) ((gf_internal_t *) gf->scratch)->private;
-  s8 = (uint8_t *) src;
-  d8 = (uint8_t *) dest;
-
-  if (xor) {
-    for (i = 0; i < bytes; i++) {
-      d8[i] ^= ftd->multtable[s8[i]][val];
-    }
-  } else {
-    for (i = 0; i < bytes; i++) {
-      d8[i] = ftd->multtable[s8[i]][val];
-    }
-  }
-}
-
-#ifdef INTEL_SSSE3
-static
-  void
-gf_w8_split_multiply_region_sse(gf_t *gf, void *src, void *dest, gf_val_32_t val, int bytes, int xor)
-{
-  uint8_t *bh, *bl, *sptr, *dptr;
-  __m128i  loset, t1, r, va, mth, mtl;
-  struct gf_w8_half_table_data *htd;
-  gf_region_data rd;
-
-  if (val == 0) { gf_multby_zero(dest, bytes, xor); return; }
-  if (val == 1) { gf_multby_one(src, dest, bytes, xor); return; }
-
-  htd = (struct gf_w8_half_table_data *) ((gf_internal_t *) (gf->scratch))->private;
-
-  gf_set_region_data(&rd, gf, src, dest, bytes, val, xor, 16);
-  gf_do_initial_region_alignment(&rd);
-
-  bh = (uint8_t *) htd->high;
-  bh += (val << 4);
-  bl = (uint8_t *) htd->low;
-  bl += (val << 4);
-
-  sptr = rd.s_start;
-  dptr = rd.d_start;
-
-  mth = _mm_loadu_si128 ((__m128i *)(bh));
-  mtl = _mm_loadu_si128 ((__m128i *)(bl));
-  loset = _mm_set1_epi8 (0x0f);
-
-  if (xor) {
-    while (sptr < (uint8_t *) rd.s_top) {
-      va = _mm_load_si128 ((__m128i *)(sptr));
-      t1 = _mm_and_si128 (loset, va);
-      r = _mm_shuffle_epi8 (mtl, t1);
-      va = _mm_srli_epi64 (va, 4);
-      t1 = _mm_and_si128 (loset, va);
-      r = _mm_xor_si128 (r, _mm_shuffle_epi8 (mth, t1));
-      va = _mm_load_si128 ((__m128i *)(dptr));
-      r = _mm_xor_si128 (r, va);
-      _mm_store_si128 ((__m128i *)(dptr), r);
-      dptr += 16;
-      sptr += 16;
-    }
-  } else {
-    while (sptr < (uint8_t *) rd.s_top) {
-      va = _mm_load_si128 ((__m128i *)(sptr));
-      t1 = _mm_and_si128 (loset, va);
-      r = _mm_shuffle_epi8 (mtl, t1);
-      va = _mm_srli_epi64 (va, 4);
-      t1 = _mm_and_si128 (loset, va);
-      r = _mm_xor_si128 (r, _mm_shuffle_epi8 (mth, t1));
-      _mm_store_si128 ((__m128i *)(dptr), r);
-      dptr += 16;
-      sptr += 16;
-    }
-  }
-
-  gf_do_final_region_alignment(&rd);
-}
-#endif
-
-
-/* ------------------------------------------------------------
-IMPLEMENTATION: FULL_TABLE:
- */
-
-static
-  gf_val_32_t
-gf_w8_split_multiply(gf_t *gf, gf_val_32_t a, gf_val_32_t b)
-{
-  struct gf_w8_half_table_data *htd;
-  htd = (struct gf_w8_half_table_data *) ((gf_internal_t *) gf->scratch)->private;
-
-  return htd->high[b][a>>4] ^ htd->low[b][a&0xf];
-}
-
-static
-  void
-gf_w8_split_multiply_region(gf_t *gf, void *src, void *dest, gf_val_32_t val, int bytes, int xor)
-{
-  int i;
-  uint8_t *s8, *d8;
-  struct gf_w8_half_table_data *htd;
-
-  if (val == 0) { gf_multby_zero(dest, bytes, xor); return; }
-  if (val == 1) { gf_multby_one(src, dest, bytes, xor); return; }
-
-  htd = (struct gf_w8_half_table_data *) ((gf_internal_t *) gf->scratch)->private;
-  s8 = (uint8_t *) src;
-  d8 = (uint8_t *) dest;
-
-  if (xor) {
-    for (i = 0; i < bytes; i++) {
-      d8[i] ^= (htd->high[val][s8[i]>>4] ^ htd->low[val][s8[i]&0xf]);
-    }
-  } else {
-    for (i = 0; i < bytes; i++) {
-      d8[i] = (htd->high[val][s8[i]>>4] ^ htd->low[val][s8[i]&0xf]);
-    }
-  }
-}
-
-
-  static
-int gf_w8_split_init(gf_t *gf)
-{
-  gf_internal_t *h;
-  struct gf_w8_half_table_data *htd;
-  int a, b;
-
-  h = (gf_internal_t *) gf->scratch;
-  htd = (struct gf_w8_half_table_data *)h->private;
-
-  bzero(htd->high, sizeof(uint8_t)*GF_FIELD_SIZE*GF_HALF_SIZE);
-  bzero(htd->low, sizeof(uint8_t)*GF_FIELD_SIZE*GF_HALF_SIZE);
-
-  for (a = 1; a < GF_FIELD_SIZE; a++) {
-    for (b = 1; b < GF_HALF_SIZE; b++) {
-      htd->low[a][b] = gf_w8_shift_multiply(gf,a,b);
-      htd->high[a][b] = gf_w8_shift_multiply(gf,a,b<<4);
-    }
-  }
-
-  gf->multiply.w32 = gf_w8_split_multiply;
-  
-  #if defined(INTEL_SSSE3) || defined(ARM_NEON)
-    if (h->region_type & GF_REGION_NOSIMD)
-      gf->multiply_region.w32 = gf_w8_split_multiply_region;
-    else
-    #if defined(INTEL_SSSE3)
-      gf->multiply_region.w32 = gf_w8_split_multiply_region_sse;
-    #elif defined(ARM_NEON)
-      gf_w8_neon_split_init(gf);
-    #endif
-  #else
-    gf->multiply_region.w32 = gf_w8_split_multiply_region;
-    if(h->region_type & GF_REGION_SIMD)
-      return 0;
-  #endif
-
-  return 1;
-}
-
-/* JSP: This is disgusting, but it is what it is.  If there is no SSE,
-   then the default is equivalent to single table.  If there is SSE, then
-   we use the "gf_w8_default_data" which is a hybrid of SPLIT & TABLE. */
-   
-static
-int gf_w8_table_init(gf_t *gf)
-{
-  gf_internal_t *h;
-  struct gf_w8_single_table_data *ftd = NULL;
-  struct gf_w8_double_table_data *dtd = NULL;
-  struct gf_w8_double_table_lazy_data *ltd = NULL;
-  struct gf_w8_default_data *dd = NULL;
-  int a, b, c, prod, scase, use_simd;
-
-  h = (gf_internal_t *) gf->scratch;
-
-#if defined(INTEL_SSSE3) || defined(ARM_NEON)
-  use_simd = 1;
-#else
-  use_simd = 0;
-#endif
-
-  if (h->mult_type == GF_MULT_DEFAULT && use_simd) {
-    dd = (struct gf_w8_default_data *)h->private;
-    scase = 3;
-    bzero(dd->high, sizeof(uint8_t) * GF_FIELD_SIZE * GF_HALF_SIZE);
-    bzero(dd->low, sizeof(uint8_t) * GF_FIELD_SIZE * GF_HALF_SIZE);
-    bzero(dd->divtable, sizeof(uint8_t) * GF_FIELD_SIZE * GF_FIELD_SIZE);
-    bzero(dd->multtable, sizeof(uint8_t) * GF_FIELD_SIZE * GF_FIELD_SIZE);
-  } else if (h->mult_type == GF_MULT_DEFAULT || 
-             h->region_type == 0 || (h->region_type & GF_REGION_CAUCHY)) {
-    ftd = (struct gf_w8_single_table_data *)h->private;
-    bzero(ftd->divtable, sizeof(uint8_t) * GF_FIELD_SIZE * GF_FIELD_SIZE);
-    bzero(ftd->multtable, sizeof(uint8_t) * GF_FIELD_SIZE * GF_FIELD_SIZE);
-    scase = 0;
-  } else if (h->region_type == GF_REGION_DOUBLE_TABLE) {
-    dtd = (struct gf_w8_double_table_data *)h->private;
-    bzero(dtd->div, sizeof(uint8_t) * GF_FIELD_SIZE * GF_FIELD_SIZE);
-    bzero(dtd->mult, sizeof(uint16_t) * GF_FIELD_SIZE * GF_FIELD_SIZE * GF_FIELD_SIZE);
-    scase = 1;
-  } else if (h->region_type == (GF_REGION_DOUBLE_TABLE | GF_REGION_LAZY)) {
-    ltd = (struct gf_w8_double_table_lazy_data *)h->private;
-    bzero(ltd->div, sizeof(uint8_t) * GF_FIELD_SIZE * GF_FIELD_SIZE);
-    bzero(ltd->smult, sizeof(uint8_t) * GF_FIELD_SIZE * GF_FIELD_SIZE);
-    scase = 2;
-  } else {
-    fprintf(stderr, "Internal error in gf_w8_table_init\n");
-    assert(0);
-  }
-
-  for (a = 1; a < GF_FIELD_SIZE; a++) {
-    for (b = 1; b < GF_FIELD_SIZE; b++) {
-      prod = gf_w8_shift_multiply(gf,a,b);
-      switch (scase) {
-        case 0: 
-          ftd->multtable[a][b] = prod;
-          ftd->divtable[prod][b] = a;
-          break;
-        case 1:
-          dtd->div[prod][b] = a;
-          for (c = 0; c < GF_FIELD_SIZE; c++) {
-            dtd->mult[a][(c<<8)|b] |= prod;
-            dtd->mult[a][(b<<8)|c] |= (prod<<8);
-          }
-          break;
-        case 2:
-          ltd->div[prod][b] = a;
-          ltd->smult[a][b] = prod;
-          break;
-        case 3:
-          dd->multtable[a][b] = prod;
-          dd->divtable[prod][b] = a;
-          if ((b & 0xf) == b) { dd->low[a][b] = prod; }
-          if ((b & 0xf0) == b) { dd->high[a][b>>4] = prod; }
-          break;
-      }
-    }
-  }
-
-  gf->inverse.w32 = NULL; /* Will set from divide */
-  switch (scase) {
-    case 0: 
-      gf->divide.w32 = gf_w8_table_divide;
-      gf->multiply.w32 = gf_w8_table_multiply;
-      gf->multiply_region.w32 = gf_w8_table_multiply_region;
-      break;
-    case 1:
-      gf->divide.w32 = gf_w8_double_table_divide;
-      gf->multiply.w32 = gf_w8_double_table_multiply;
-      gf->multiply_region.w32 = gf_w8_double_table_multiply_region;
-      break;
-    case 2:
-      gf->divide.w32 = gf_w8_double_table_lazy_divide;
-      gf->multiply.w32 = gf_w8_double_table_lazy_multiply;
-      gf->multiply_region.w32 = gf_w8_double_table_multiply_region;
-      break;
-    case 3:
-#if defined(INTEL_SSSE3) || defined(ARM_NEON)
-      gf->divide.w32 = gf_w8_default_divide;
-      gf->multiply.w32 = gf_w8_default_multiply;
-#if defined(INTEL_SSSE3)
-      gf->multiply_region.w32 = gf_w8_split_multiply_region_sse;
-#elif defined(ARM_NEON)
-      gf_w8_neon_split_init(gf);
-#endif
-#endif
-      break;
-  }
-  return 1;
-}
-
-static
-  void
-gf_w8_composite_multiply_region_alt(gf_t *gf, void *src, void *dest, gf_val_32_t val, int bytes, int xor)
-{
-  gf_internal_t *h = (gf_internal_t *) gf->scratch;
-  gf_t *base_gf = h->base_gf;
-  uint8_t val0 = val & 0x0f;
-  uint8_t val1 = (val & 0xf0) >> 4;
-  gf_region_data rd;
-  int sub_reg_size;
-
-  if (val == 0) {
-    if (xor) return;
-    bzero(dest, bytes);
-    return;
-  }
-
-  gf_set_region_data(&rd, gf, src, dest, bytes, val, xor, 32);
-  gf_do_initial_region_alignment(&rd);
-
-  sub_reg_size = ((uint8_t *)rd.d_top - (uint8_t *)rd.d_start) / 2;
-
-  base_gf->multiply_region.w32(base_gf, rd.s_start, rd.d_start, val0, sub_reg_size, xor);
-  base_gf->multiply_region.w32(base_gf, (uint8_t *)rd.s_start+sub_reg_size, rd.d_start, val1, sub_reg_size, 1);
-  base_gf->multiply_region.w32(base_gf, rd.s_start, (uint8_t *)rd.d_start+sub_reg_size, val1, sub_reg_size, xor);
-  base_gf->multiply_region.w32(base_gf, (uint8_t *)rd.s_start+sub_reg_size, (uint8_t *)rd.d_start+sub_reg_size, val0, sub_reg_size, 1);
-  base_gf->multiply_region.w32(base_gf, (uint8_t *)rd.s_start+sub_reg_size, (uint8_t *)rd.d_start+sub_reg_size, base_gf->multiply.w32(base_gf, h->prim_poly, val1), sub_reg_size, 1);
-
-   gf_do_final_region_alignment(&rd);
-}
-
-static
-gf_val_32_t
-gf_w8_composite_multiply_recursive(gf_t *gf, gf_val_32_t a, gf_val_32_t b)
-{
-  gf_internal_t *h = (gf_internal_t *) gf->scratch;
-  gf_t *base_gf = h->base_gf;
-  uint8_t b0 = b & 0x0f; 
-  uint8_t b1 = (b & 0xf0) >> 4; 
-  uint8_t a0 = a & 0x0f; 
-  uint8_t a1 = (a & 0xf0) >> 4; 
-  uint8_t a1b1;
-
-  a1b1 = base_gf->multiply.w32(base_gf, a1, b1);
-
-  return ((base_gf->multiply.w32(base_gf, a0, b0) ^ a1b1) | 
-          ((base_gf->multiply.w32(base_gf, a1, b0) ^ 
-           base_gf->multiply.w32(base_gf, a0, b1) ^ 
-           base_gf->multiply.w32(base_gf, a1b1, h->prim_poly)) << 4));
-}
-
-static
-gf_val_32_t
-gf_w8_composite_multiply_inline(gf_t *gf, gf_val_32_t a, gf_val_32_t b)
-{
-  gf_internal_t *h = (gf_internal_t *) gf->scratch;
-  uint8_t b0 = b & 0x0f; 
-  uint8_t b1 = (b & 0xf0) >> 4; 
-  uint8_t a0 = a & 0x0f; 
-  uint8_t a1 = (a & 0xf0) >> 4; 
-  uint8_t a1b1, *mt;
-  struct gf_w8_composite_data *cd;
-
-  cd = (struct gf_w8_composite_data *) h->private;
-  mt = cd->mult_table;
-
-  a1b1 = GF_W4_INLINE_MULTDIV(mt, a1, b1);
-
-  return ((GF_W4_INLINE_MULTDIV(mt, a0, b0) ^ a1b1) | 
-          ((GF_W4_INLINE_MULTDIV(mt, a1, b0) ^ 
-           GF_W4_INLINE_MULTDIV(mt, a0, b1) ^ 
-           GF_W4_INLINE_MULTDIV(mt, a1b1, h->prim_poly)) << 4));
-}
-
-/*
- * Composite field division trick (explained in 2007 tech report) 
- *
- * Compute a / b = a*b^-1, where p(x) = x^2 + sx + 1 
- * 
- * let c = b^-1
- *
- * c*b = (s*b1c1+b1c0+b0c1)x+(b1c1+b0c0)
- * 
- * want (s*b1c1+b1c0+b0c1) = 0 and (b1c1+b0c0) = 1 
- *
- * let d = b1c1 and d+1 = b0c0
- *
- * solve s*b1c1+b1c0+b0c1 = 0
- *
- * solution: d = (b1b0^-1)(b1b0^-1+b0b1^-1+s)^-1
- *
- * c0 = (d+1)b0^-1
- * c1 = d*b1^-1
- * 
- * a / b = a * c
- */
-
-static
-gf_val_32_t
-gf_w8_composite_inverse(gf_t *gf, gf_val_32_t a)
-{
-  gf_internal_t *h = (gf_internal_t *) gf->scratch;
-  gf_t *base_gf = h->base_gf;
-  uint8_t a0 = a & 0x0f; 
-  uint8_t a1 = (a & 0xf0) >> 4; 
-  uint8_t c0, c1, c, d, tmp;
-  uint8_t a0inv, a1inv; 
-
-  if (a0 == 0) {
-    a1inv = base_gf->inverse.w32(base_gf, a1) & 0xf;
-    c0 = base_gf->multiply.w32(base_gf, a1inv, h->prim_poly);
-    c1 = a1inv;
-  } else if (a1 == 0) {
-    c0 = base_gf->inverse.w32(base_gf, a0);
-    c1 = 0;
-  } else {
-    a1inv = base_gf->inverse.w32(base_gf, a1) & 0xf;
-    a0inv = base_gf->inverse.w32(base_gf, a0) & 0xf;
-
-    d = base_gf->multiply.w32(base_gf, a1, a0inv) & 0xf;
-
-    tmp = (base_gf->multiply.w32(base_gf, a1, a0inv) ^ base_gf->multiply.w32(base_gf, a0, a1inv) ^ h->prim_poly) & 0xf;
-    tmp = base_gf->inverse.w32(base_gf, tmp) & 0xf;
-
-    d = base_gf->multiply.w32(base_gf, d, tmp) & 0xf;
-
-    c0 = base_gf->multiply.w32(base_gf, (d^1), a0inv) & 0xf; 
-    c1 = base_gf->multiply.w32(base_gf, d, a1inv) & 0xf; 
-  }
-
-  c = c0 | (c1 << 4);
-
-  return c;
-}
-
-static
-void
-gf_w8_composite_multiply_region(gf_t *gf, void *src, void *dest, gf_val_32_t val, int bytes, int xor)
-{
-  gf_region_data rd;
-  gf_internal_t *h = (gf_internal_t *) gf->scratch;
-  gf_t *base_gf = h->base_gf;
-  uint8_t b0 = val & 0x0f; 
-  uint8_t b1 = (val & 0xf0) >> 4; 
-  uint8_t *s8;
-  uint8_t *d8; 
-  uint8_t *mt;
-  uint8_t a0, a1, a1b1;
-  struct gf_w8_composite_data *cd;
-
-  cd = (struct gf_w8_composite_data *) h->private;
-
-  if (val == 0) {
-    if (xor) return;
-    bzero(dest, bytes);
-    return;
-  }
-
-  gf_set_region_data(&rd, gf, src, dest, bytes, val, xor, 1);
-  gf_do_initial_region_alignment(&rd);
-  
-  
-  s8 = (uint8_t *) rd.s_start;
-  d8 = (uint8_t *) rd.d_start;
-
-  mt = cd->mult_table;
-  if (mt == NULL) {
-    if (xor) {
-      while (d8 < (uint8_t *) rd.d_top) {
-        a0 = *s8 & 0x0f; 
-        a1 = (*s8 & 0xf0) >> 4; 
-        a1b1 = base_gf->multiply.w32(base_gf, a1, b1);
-  
-        *d8 ^= ((base_gf->multiply.w32(base_gf, a0, b0) ^ a1b1) | 
-               ((base_gf->multiply.w32(base_gf, a1, b0) ^ 
-                 base_gf->multiply.w32(base_gf, a0, b1) ^ 
-                 base_gf->multiply.w32(base_gf, a1b1, h->prim_poly)) << 4));
-        s8++;
-        d8++;
-      }
-    } else {
-      while (d8 < (uint8_t *) rd.d_top) {
-        a0 = *s8 & 0x0f; 
-        a1 = (*s8 & 0xf0) >> 4; 
-        a1b1 = base_gf->multiply.w32(base_gf, a1, b1);
-  
-        *d8 = ((base_gf->multiply.w32(base_gf, a0, b0) ^ a1b1) | 
-              ((base_gf->multiply.w32(base_gf, a1, b0) ^ 
-                base_gf->multiply.w32(base_gf, a0, b1) ^ 
-                base_gf->multiply.w32(base_gf, a1b1, h->prim_poly)) << 4));
-        s8++;
-        d8++;
-      }
-    }
-  } else {
-    if (xor) {
-      while (d8 < (uint8_t *) rd.d_top) {
-        a0 = *s8 & 0x0f; 
-        a1 = (*s8 & 0xf0) >> 4; 
-        a1b1 = GF_W4_INLINE_MULTDIV(mt, a1, b1);
-  
-        *d8 ^= ((GF_W4_INLINE_MULTDIV(mt, a0, b0) ^ a1b1) | 
-               ((GF_W4_INLINE_MULTDIV(mt, a1, b0) ^ 
-                 GF_W4_INLINE_MULTDIV(mt, a0, b1) ^ 
-                 GF_W4_INLINE_MULTDIV(mt, a1b1, h->prim_poly)) << 4));
-        s8++;
-        d8++;
-      }
-    } else {
-      while (d8 < (uint8_t *) rd.d_top) {
-        a0 = *s8 & 0x0f; 
-        a1 = (*s8 & 0xf0) >> 4; 
-        a1b1 = GF_W4_INLINE_MULTDIV(mt, a1, b1);
-  
-        *d8 = ((GF_W4_INLINE_MULTDIV(mt, a0, b0) ^ a1b1) | 
-              ((GF_W4_INLINE_MULTDIV(mt, a1, b0) ^ 
-                GF_W4_INLINE_MULTDIV(mt, a0, b1) ^ 
-                GF_W4_INLINE_MULTDIV(mt, a1b1, h->prim_poly)) << 4));
-        s8++;
-        d8++;
-      }
-    }
-  }
-  gf_do_final_region_alignment(&rd);
-  return;
-}
-
-static
-int gf_w8_composite_init(gf_t *gf)
-{
-  gf_internal_t *h = (gf_internal_t *) gf->scratch;
-  struct gf_w8_composite_data *cd;
-
-  if (h->base_gf == NULL) return 0;
-
-  cd = (struct gf_w8_composite_data *) h->private;
-  cd->mult_table = gf_w4_get_mult_table(h->base_gf);
-
-  if (h->region_type & GF_REGION_ALTMAP) {
-    gf->multiply_region.w32 = gf_w8_composite_multiply_region_alt;
-  } else {
-    gf->multiply_region.w32 = gf_w8_composite_multiply_region;
-  }
-
-  if (cd->mult_table == NULL) {
-    gf->multiply.w32 = gf_w8_composite_multiply_recursive;
-  } else {
-    gf->multiply.w32 = gf_w8_composite_multiply_inline;
-  }
-  gf->divide.w32 = NULL;
-  gf->inverse.w32 = gf_w8_composite_inverse;
-
-  return 1;
-}
-
-static
-inline
-  gf_val_32_t
-gf_w8_bytwo_p_multiply (gf_t *gf, gf_val_32_t a, gf_val_32_t b)
-{
-  uint32_t prod, pp, pmask, amask;
-  gf_internal_t *h;
-
-  h = (gf_internal_t *) gf->scratch;
-  pp = h->prim_poly;
-
-
-  prod = 0;
-  pmask = 0x80;
-  amask = 0x80;
-
-  while (amask != 0) {
-    if (prod & pmask) {
-      prod = ((prod << 1) ^ pp);
-    } else {
-      prod <<= 1;
-    }
-    if (a & amask) prod ^= b;
-    amask >>= 1;
-  }
-  return prod;
-}
-
-static
-inline
-  gf_val_32_t
-gf_w8_bytwo_b_multiply (gf_t *gf, gf_val_32_t a, gf_val_32_t b)
-{
-  uint32_t prod, pp, bmask;
-  gf_internal_t *h;
-
-  h = (gf_internal_t *) gf->scratch;
-  pp = h->prim_poly;
-
-  prod = 0;
-  bmask = 0x80;
-
-  while (1) {
-    if (a & 1) prod ^= b;
-    a >>= 1;
-    if (a == 0) return prod;
-    if (b & bmask) {
-      b = ((b << 1) ^ pp);
-    } else {
-      b <<= 1;
-    }
-  }
-}
-
-static
-  void 
-gf_w8_bytwo_p_nosse_multiply_region(gf_t *gf, void *src, void *dest, gf_val_32_t val, int bytes, int xor)
-{
-  uint64_t *s64, *d64, t1, t2, ta, prod, amask;
-  gf_region_data rd;
-  struct gf_w8_bytwo_data *btd;
-
-  if (val == 0) { gf_multby_zero(dest, bytes, xor); return; }
-  if (val == 1) { gf_multby_one(src, dest, bytes, xor); return; }
-
-  btd = (struct gf_w8_bytwo_data *) ((gf_internal_t *) (gf->scratch))->private;
-
-  gf_set_region_data(&rd, gf, src, dest, bytes, val, xor, 8);
-  gf_do_initial_region_alignment(&rd);
-
-  s64 = (uint64_t *) rd.s_start;
-  d64 = (uint64_t *) rd.d_start;
-
-  if (xor) {
-    while (s64 < (uint64_t *) rd.s_top) {
-      prod = 0;
-      amask = 0x80;
-      ta = *s64;
-      while (amask != 0) {
-        AB2(btd->prim_poly, btd->mask1, btd->mask2, prod, t1, t2);
-        if (val & amask) prod ^= ta;
-        amask >>= 1;
-      }
-      *d64 ^= prod;
-      d64++;
-      s64++;
-    }
-  } else { 
-    while (s64 < (uint64_t *) rd.s_top) {
-      prod = 0;
-      amask = 0x80;
-      ta = *s64;
-      while (amask != 0) {
-        AB2(btd->prim_poly, btd->mask1, btd->mask2, prod, t1, t2);
-        if (val & amask) prod ^= ta;
-        amask >>= 1;
-      }
-      *d64 = prod;
-      d64++;
-      s64++;
-    }
-  }
-  gf_do_final_region_alignment(&rd);
-}
-
-#define BYTWO_P_ONESTEP {\
-  SSE_AB2(pp, m1 ,m2, prod, t1, t2); \
-  t1 = _mm_and_si128(v, one); \
-  t1 = _mm_sub_epi8(t1, one); \
-  t1 = _mm_and_si128(t1, ta); \
-  prod = _mm_xor_si128(prod, t1); \
-  v = _mm_srli_epi64(v, 1); }
-
-#ifdef INTEL_SSE2
-static
-  void 
-gf_w8_bytwo_p_sse_multiply_region(gf_t *gf, void *src, void *dest, gf_val_32_t val, int bytes, int xor)
-{
-  int i;
-  uint8_t *s8, *d8;
-  uint8_t vrev;
-  __m128i pp, m1, m2, ta, prod, t1, t2, tp, one, v;
-  struct gf_w8_bytwo_data *btd;
-  gf_region_data rd;
-
-  if (val == 0) { gf_multby_zero(dest, bytes, xor); return; }
-  if (val == 1) { gf_multby_one(src, dest, bytes, xor); return; }
-
-  btd = (struct gf_w8_bytwo_data *) ((gf_internal_t *) (gf->scratch))->private;
-
-  gf_set_region_data(&rd, gf, src, dest, bytes, val, xor, 16);
-  gf_do_initial_region_alignment(&rd);
-
-  vrev = 0;
-  for (i = 0; i < 8; i++) {
-    vrev <<= 1;
-    if (!(val & (1 << i))) vrev |= 1;
-  }
-
-  s8 = (uint8_t *) rd.s_start;
-  d8 = (uint8_t *) rd.d_start;
-
-  pp = _mm_set1_epi8(btd->prim_poly&0xff);
-  m1 = _mm_set1_epi8((btd->mask1)&0xff);
-  m2 = _mm_set1_epi8((btd->mask2)&0xff);
-  one = _mm_set1_epi8(1);
-
-  while (d8 < (uint8_t *) rd.d_top) {
-    prod = _mm_setzero_si128();
-    v = _mm_set1_epi8(vrev);
-    ta = _mm_load_si128((__m128i *) s8);
-    tp = (!xor) ? _mm_setzero_si128() : _mm_load_si128((__m128i *) d8);
-    BYTWO_P_ONESTEP;
-    BYTWO_P_ONESTEP;
-    BYTWO_P_ONESTEP;
-    BYTWO_P_ONESTEP;
-    BYTWO_P_ONESTEP;
-    BYTWO_P_ONESTEP;
-    BYTWO_P_ONESTEP;
-    BYTWO_P_ONESTEP;
-    _mm_store_si128((__m128i *) d8, _mm_xor_si128(prod, tp));
-    d8 += 16;
-    s8 += 16;
-  }
-  gf_do_final_region_alignment(&rd);
-}
-#endif
-
-#ifdef INTEL_SSE2
-static
-  void
-gf_w8_bytwo_b_sse_region_2_noxor(gf_region_data *rd, struct gf_w8_bytwo_data *btd)
-{
-  uint8_t *d8, *s8;
-  __m128i pp, m1, m2, t1, t2, va;
-
-  s8 = (uint8_t *) rd->s_start;
-  d8 = (uint8_t *) rd->d_start;
-
-  pp = _mm_set1_epi8(btd->prim_poly&0xff);
-  m1 = _mm_set1_epi8((btd->mask1)&0xff);
-  m2 = _mm_set1_epi8((btd->mask2)&0xff);
-
-  while (d8 < (uint8_t *) rd->d_top) {
-    va = _mm_load_si128 ((__m128i *)(s8));
-    SSE_AB2(pp, m1, m2, va, t1, t2);
-    _mm_store_si128((__m128i *)d8, va);
-    d8 += 16;
-    s8 += 16;
-  }
-}
-#endif
-
-#ifdef INTEL_SSE2
-static
-  void
-gf_w8_bytwo_b_sse_region_2_xor(gf_region_data *rd, struct gf_w8_bytwo_data *btd)
-{
-  uint8_t *d8, *s8;
-  __m128i pp, m1, m2, t1, t2, va, vb;
-
-  s8 = (uint8_t *) rd->s_start;
-  d8 = (uint8_t *) rd->d_start;
-
-  pp = _mm_set1_epi8(btd->prim_poly&0xff);
-  m1 = _mm_set1_epi8((btd->mask1)&0xff);
-  m2 = _mm_set1_epi8((btd->mask2)&0xff);
-
-  while (d8 < (uint8_t *) rd->d_top) {
-    va = _mm_load_si128 ((__m128i *)(s8));
-    SSE_AB2(pp, m1, m2, va, t1, t2);
-    vb = _mm_load_si128 ((__m128i *)(d8));
-    vb = _mm_xor_si128(vb, va);
-    _mm_store_si128((__m128i *)d8, vb);
-    d8 += 16;
-    s8 += 16;
-  }
-}
-#endif
-
-
-#ifdef INTEL_SSE2
-static
-  void 
-gf_w8_bytwo_b_sse_multiply_region(gf_t *gf, void *src, void *dest, gf_val_32_t val, int bytes, int xor)
-{
-  int itb;
-  uint8_t *d8, *s8;
-  __m128i pp, m1, m2, t1, t2, va, vb;
-  struct gf_w8_bytwo_data *btd;
-  gf_region_data rd;
-
-  if (val == 0) { gf_multby_zero(dest, bytes, xor); return; }
-  if (val == 1) { gf_multby_one(src, dest, bytes, xor); return; }
-
-  gf_set_region_data(&rd, gf, src, dest, bytes, val, xor, 16);
-  gf_do_initial_region_alignment(&rd);
-
-  btd = (struct gf_w8_bytwo_data *) ((gf_internal_t *) (gf->scratch))->private;
-
-  if (val == 2) {
-    if (xor) {
-      gf_w8_bytwo_b_sse_region_2_xor(&rd, btd);
-    } else {
-      gf_w8_bytwo_b_sse_region_2_noxor(&rd, btd);
-    }
-    gf_do_final_region_alignment(&rd);
-    return;
-  }
-
-  s8 = (uint8_t *) rd.s_start;
-  d8 = (uint8_t *) rd.d_start;
-
-  pp = _mm_set1_epi8(btd->prim_poly&0xff);
-  m1 = _mm_set1_epi8((btd->mask1)&0xff);
-  m2 = _mm_set1_epi8((btd->mask2)&0xff);
-
-  while (d8 < (uint8_t *) rd.d_top) {
-    va = _mm_load_si128 ((__m128i *)(s8));
-    vb = (!xor) ? _mm_setzero_si128() : _mm_load_si128 ((__m128i *)(d8));
-    itb = val;
-    while (1) {
-      if (itb & 1) vb = _mm_xor_si128(vb, va);
-      itb >>= 1;
-      if (itb == 0) break;
-      SSE_AB2(pp, m1, m2, va, t1, t2);
-    }
-    _mm_store_si128((__m128i *)d8, vb);
-    d8 += 16;
-    s8 += 16;
-  }
-
-  gf_do_final_region_alignment(&rd);
-}
-#endif
-
-static
-  void 
-gf_w8_bytwo_b_nosse_multiply_region(gf_t *gf, void *src, void *dest, gf_val_32_t val, int bytes, int xor)
-{
-  uint64_t *s64, *d64, t1, t2, ta, tb, prod;
-  struct gf_w8_bytwo_data *btd;
-  gf_region_data rd;
-
-  if (val == 0) { gf_multby_zero(dest, bytes, xor); return; }
-  if (val == 1) { gf_multby_one(src, dest, bytes, xor); return; }
-
-  gf_set_region_data(&rd, gf, src, dest, bytes, val, xor, 16);
-  gf_do_initial_region_alignment(&rd);
-
-  btd = (struct gf_w8_bytwo_data *) ((gf_internal_t *) (gf->scratch))->private;
-  s64 = (uint64_t *) rd.s_start;
-  d64 = (uint64_t *) rd.d_start;
-
-  switch (val) {
-    case 2:
-      if (xor) {
-        while (d64 < (uint64_t *) rd.d_top) {
-          ta = *s64;
-          AB2(btd->prim_poly, btd->mask1, btd->mask2, ta, t1, t2);
-          *d64 ^= ta;
-          d64++;
-          s64++;
-        }
-      } else {
-        while (d64 < (uint64_t *) rd.d_top) {
-          ta = *s64;
-          AB2(btd->prim_poly, btd->mask1, btd->mask2, ta, t1, t2);
-          *d64 = ta;
-          d64++;
-          s64++;
-        }
-      }
-      break; 
-    case 3:
-      if (xor) {
-        while (d64 < (uint64_t *) rd.d_top) {
-          ta = *s64;
-          prod = ta;
-          AB2(btd->prim_poly, btd->mask1, btd->mask2, ta, t1, t2);
-          *d64 ^= (ta ^ prod);
-          d64++;
-          s64++;
-        }
-      } else {
-        while (d64 < (uint64_t *) rd.d_top) {
-          ta = *s64;
-          prod = ta;
-          AB2(btd->prim_poly, btd->mask1, btd->mask2, ta, t1, t2);
-          *d64 = (ta ^ prod);
-          d64++;
-          s64++;
-        }
-      }
-      break; 
-    case 4:
-      if (xor) {
-        while (d64 < (uint64_t *) rd.d_top) {
-          ta = *s64;
-          AB2(btd->prim_poly, btd->mask1, btd->mask2, ta, t1, t2);
-          AB2(btd->prim_poly, btd->mask1, btd->mask2, ta, t1, t2);
-          *d64 ^= ta;
-          d64++;
-          s64++;
-        }
-      } else {
-        while (d64 < (uint64_t *) rd.d_top) {
-          ta = *s64;
-          AB2(btd->prim_poly, btd->mask1, btd->mask2, ta, t1, t2);
-          AB2(btd->prim_poly, btd->mask1, btd->mask2, ta, t1, t2);
-          *d64 = ta;
-          d64++;
-          s64++;
-        }
-      }
-      break; 
-    case 5:
-      if (xor) {
-        while (d64 < (uint64_t *) rd.d_top) {
-          ta = *s64;
-          prod = ta;
-          AB2(btd->prim_poly, btd->mask1, btd->mask2, ta, t1, t2);
-          AB2(btd->prim_poly, btd->mask1, btd->mask2, ta, t1, t2);
-          *d64 ^= (ta ^ prod);
-          d64++;
-          s64++;
-        }
-      } else {
-        while (d64 < (uint64_t *) rd.d_top) {
-          ta = *s64;
-          prod = ta;
-          AB2(btd->prim_poly, btd->mask1, btd->mask2, ta, t1, t2);
-          AB2(btd->prim_poly, btd->mask1, btd->mask2, ta, t1, t2);
-          *d64 = ta ^ prod;
-          d64++;
-          s64++;
-        }
-      }
-      break;
-    case 6:
-      if (xor) {
-        while (d64 < (uint64_t *) rd.d_top) {
-          ta = *s64;
-          AB2(btd->prim_poly, btd->mask1, btd->mask2, ta, t1, t2);
-          prod = ta;
-          AB2(btd->prim_poly, btd->mask1, btd->mask2, ta, t1, t2);
-          *d64 ^= (ta ^ prod);
-          d64++;
-          s64++;
-        }
-      } else {
-        while (d64 < (uint64_t *) rd.d_top) {
-          ta = *s64;
-          AB2(btd->prim_poly, btd->mask1, btd->mask2, ta, t1, t2);
-          prod = ta;
-          AB2(btd->prim_poly, btd->mask1, btd->mask2, ta, t1, t2);
-          *d64 = ta ^ prod;
-          d64++;
-          s64++;
-        }
-      }
-      break;
-      /*
-         case 7:
-         if (xor) {
-         while (d64 < (uint64_t *) rd.d_top) {
-         ta = *s64;
-         prod = ta;
-         AB2(btd->prim_poly, btd->mask1, btd->mask2, ta, t1, t2);
-         prod ^= ta;
-         AB2(btd->prim_poly, btd->mask1, btd->mask2, ta, t1, t2);
-       *d64 ^= (ta ^ prod);
-       d64++;
-       s64++;
-       }
-       } else {
-       while (d64 < (uint64_t *) rd.d_top) {
-       ta = *s64;
-       prod = ta;
-       AB2(btd->prim_poly, btd->mask1, btd->mask2, ta, t1, t2);
-       prod ^= ta;
-       AB2(btd->prim_poly, btd->mask1, btd->mask2, ta, t1, t2);
-       *d64 = ta ^ prod;
-       d64++;
-       s64++;
-       }
-       }
-       break; 
-       */
-    case 8:
-      if (xor) {
-        while (d64 < (uint64_t *) rd.d_top) {
-          ta = *s64;
-          AB2(btd->prim_poly, btd->mask1, btd->mask2, ta, t1, t2);
-          AB2(btd->prim_poly, btd->mask1, btd->mask2, ta, t1, t2);
-          AB2(btd->prim_poly, btd->mask1, btd->mask2, ta, t1, t2);
-          *d64 ^= ta;
-          d64++;
-          s64++;
-        }
-      } else {
-        while (d64 < (uint64_t *) rd.d_top) {
-          ta = *s64;
-          AB2(btd->prim_poly, btd->mask1, btd->mask2, ta, t1, t2);
-          AB2(btd->prim_poly, btd->mask1, btd->mask2, ta, t1, t2);
-          AB2(btd->prim_poly, btd->mask1, btd->mask2, ta, t1, t2);
-          *d64 = ta;
-          d64++;
-          s64++;
-        }
-      }
-      break; 
-      /*
-         case 9:
-         if (xor) {
-         while (d64 < (uint64_t *) rd.d_top) {
-         ta = *s64;
-         prod = ta;
-         AB2(btd->prim_poly, btd->mask1, btd->mask2, ta, t1, t2);
-         AB2(btd->prim_poly, btd->mask1, btd->mask2, ta, t1, t2);
-         AB2(btd->prim_poly, btd->mask1, btd->mask2, ta, t1, t2);
-       *d64 ^= (ta ^ prod);
-       d64++;
-       s64++;
-       }
-       } else {
-       while (d64 < (uint64_t *) rd.d_top) {
-       ta = *s64;
-       prod = ta;
-       AB2(btd->prim_poly, btd->mask1, btd->mask2, ta, t1, t2);
-       AB2(btd->prim_poly, btd->mask1, btd->mask2, ta, t1, t2);
-       AB2(btd->prim_poly, btd->mask1, btd->mask2, ta, t1, t2);
-       *d64 = (ta ^ prod);
-       d64++;
-       s64++;
-       }
-       }
-       break; 
-       case 10:
-       if (xor) {
-       while (d64 < (uint64_t *) rd.d_top) {
-       ta = *s64;
-       AB2(btd->prim_poly, btd->mask1, btd->mask2, ta, t1, t2);
-       prod = ta;
-       AB2(btd->prim_poly, btd->mask1, btd->mask2, ta, t1, t2);
-       AB2(btd->prim_poly, btd->mask1, btd->mask2, ta, t1, t2);
-       *d64 ^= (ta ^ prod);
-       d64++;
-       s64++;
-       }
-       } else {
-       while (d64 < (uint64_t *) rd.d_top) {
-       ta = *s64;
-       AB2(btd->prim_poly, btd->mask1, btd->mask2, ta, t1, t2);
-       prod = ta;
-       AB2(btd->prim_poly, btd->mask1, btd->mask2, ta, t1, t2);
-       AB2(btd->prim_poly, btd->mask1, btd->mask2, ta, t1, t2);
-       *d64 = (ta ^ prod);
-       d64++;
-       s64++;
-       }
-       }
-       break; 
-       case 11:
-       if (xor) {
-       while (d64 < (uint64_t *) rd.d_top) {
-       ta = *s64;
-       prod = ta;
-       AB2(btd->prim_poly, btd->mask1, btd->mask2, ta, t1, t2);
-       prod ^= ta;
-       AB2(btd->prim_poly, btd->mask1, btd->mask2, ta, t1, t2);
-       AB2(btd->prim_poly, btd->mask1, btd->mask2, ta, t1, t2);
-       *d64 ^= (ta ^ prod);
-       d64++;
-       s64++;
-       }
-       } else {
-       while (d64 < (uint64_t *) rd.d_top) {
-       ta = *s64;
-       prod = ta;
-       AB2(btd->prim_poly, btd->mask1, btd->mask2, ta, t1, t2);
-       prod ^= ta;
-       AB2(btd->prim_poly, btd->mask1, btd->mask2, ta, t1, t2);
-      AB2(btd->prim_poly, btd->mask1, btd->mask2, ta, t1, t2);
-      *d64 = (ta ^ prod);
-      d64++;
-      s64++;
-      }
-  }
-  break; 
-    case 12:
-  if (xor) {
-    while (d64 < (uint64_t *) rd.d_top) {
-      ta = *s64;
-      AB2(btd->prim_poly, btd->mask1, btd->mask2, ta, t1, t2);
-      AB2(btd->prim_poly, btd->mask1, btd->mask2, ta, t1, t2);
-      prod = ta;
-      AB2(btd->prim_poly, btd->mask1, btd->mask2, ta, t1, t2);
-      *d64 ^= (ta ^ prod);
-      d64++;
-      s64++;
-    }
-  } else {
-    while (d64 < (uint64_t *) rd.d_top) {
-      ta = *s64;
-      AB2(btd->prim_poly, btd->mask1, btd->mask2, ta, t1, t2);
-      AB2(btd->prim_poly, btd->mask1, btd->mask2, ta, t1, t2);
-      prod = ta;
-      AB2(btd->prim_poly, btd->mask1, btd->mask2, ta, t1, t2);
-      *d64 = (ta ^ prod);
-      d64++;
-      s64++;
-    }
-  }
-  break; 
-    case 13:
-  if (xor) {
-    while (d64 < (uint64_t *) rd.d_top) {
-      ta = *s64;
-      prod = ta;
-      AB2(btd->prim_poly, btd->mask1, btd->mask2, ta, t1, t2);
-      AB2(btd->prim_poly, btd->mask1, btd->mask2, ta, t1, t2);
-      prod ^= ta;
-      AB2(btd->prim_poly, btd->mask1, btd->mask2, ta, t1, t2);
-      *d64 ^= (ta ^ prod);
-      d64++;
-      s64++;
-    }
-  } else {
-    while (d64 < (uint64_t *) rd.d_top) {
-      ta = *s64;
-      prod = ta;
-      AB2(btd->prim_poly, btd->mask1, btd->mask2, ta, t1, t2);
-      AB2(btd->prim_poly, btd->mask1, btd->mask2, ta, t1, t2);
-      prod ^= ta;
-      AB2(btd->prim_poly, btd->mask1, btd->mask2, ta, t1, t2);
-      *d64 = (ta ^ prod);
-      d64++;
-      s64++;
-    }
-  }
-  break; 
-    case 14:
-  if (xor) {
-    while (d64 < (uint64_t *) rd.d_top) {
-      ta = *s64;
-      AB2(btd->prim_poly, btd->mask1, btd->mask2, ta, t1, t2);
-      prod = ta;
-      AB2(btd->prim_poly, btd->mask1, btd->mask2, ta, t1, t2);
-      prod ^= ta;
-      AB2(btd->prim_poly, btd->mask1, btd->mask2, ta, t1, t2);
-      *d64 ^= (ta ^ prod);
-      d64++;
-      s64++;
-    }
-  } else {
-    while (d64 < (uint64_t *) rd.d_top) {
-      ta = *s64;
-      AB2(btd->prim_poly, btd->mask1, btd->mask2, ta, t1, t2);
-      prod = ta;
-      AB2(btd->prim_poly, btd->mask1, btd->mask2, ta, t1, t2);
-      prod ^= ta;
-      AB2(btd->prim_poly, btd->mask1, btd->mask2, ta, t1, t2);
-      *d64 = (ta ^ prod);
-      d64++;
-      s64++;
-    }
-  }
-  break; 
-    case 15:
-  if (xor) {
-    while (d64 < (uint64_t *) rd.d_top) {
-      ta = *s64;
-      prod = ta;
-      AB2(btd->prim_poly, btd->mask1, btd->mask2, ta, t1, t2);
-      prod ^= ta;
-      AB2(btd->prim_poly, btd->mask1, btd->mask2, ta, t1, t2);
-      prod ^= ta;
-      AB2(btd->prim_poly, btd->mask1, btd->mask2, ta, t1, t2);
-      *d64 ^= (ta ^ prod);
-      d64++;
-      s64++;
-    }
-  } else {
-    while (d64 < (uint64_t *) rd.d_top) {
-      ta = *s64;
-      prod = ta;
-      AB2(btd->prim_poly, btd->mask1, btd->mask2, ta, t1, t2);
-      prod ^= ta;
-      AB2(btd->prim_poly, btd->mask1, btd->mask2, ta, t1, t2);
-      prod ^= ta;
-      AB2(btd->prim_poly, btd->mask1, btd->mask2, ta, t1, t2);
-      *d64 = (ta ^ prod);
-      d64++;
-      s64++;
-    }
-  }
-  break; 
-  */
-    default:
-    if (xor) {
-      while (d64 < (uint64_t *) rd.d_top) {
-        prod = *d64 ;
-        ta = *s64;
-        tb = val;
-        while (1) {
-          if (tb & 1) prod ^= ta;
-          tb >>= 1;
-          if (tb == 0) break;
-          AB2(btd->prim_poly, btd->mask1, btd->mask2, ta, t1, t2);
-        }
-        *d64 = prod;
-        d64++;
-        s64++;
-      }
-    } else {
-      while (d64 < (uint64_t *) rd.d_top) {
-        prod = 0 ;
-        ta = *s64;
-        tb = val;
-        while (1) {
-          if (tb & 1) prod ^= ta;
-          tb >>= 1;
-          if (tb == 0) break;
-          AB2(btd->prim_poly, btd->mask1, btd->mask2, ta, t1, t2);
-        }
-        *d64 = prod;
-        d64++;
-        s64++;
-      }
-    }
-    break;
-  }
-  gf_do_final_region_alignment(&rd);
-}
-
-  static
-int gf_w8_bytwo_init(gf_t *gf)
-{
-  gf_internal_t *h;
-  uint64_t ip, m1, m2;
-  struct gf_w8_bytwo_data *btd;
-
-  h = (gf_internal_t *) gf->scratch;
-  btd = (struct gf_w8_bytwo_data *) (h->private);
-  ip = h->prim_poly & 0xff;
-  m1 = 0xfe;
-  m2 = 0x80;
-  btd->prim_poly = 0;
-  btd->mask1 = 0;
-  btd->mask2 = 0;
-
-  while (ip != 0) {
-    btd->prim_poly |= ip;
-    btd->mask1 |= m1;
-    btd->mask2 |= m2;
-    ip <<= GF_FIELD_WIDTH;
-    m1 <<= GF_FIELD_WIDTH;
-    m2 <<= GF_FIELD_WIDTH;
-  }
-
-  if (h->mult_type == GF_MULT_BYTWO_p) {
-    gf->multiply.w32 = gf_w8_bytwo_p_multiply;
-#ifdef INTEL_SSE2
-    if (h->region_type & GF_REGION_NOSIMD)
-      gf->multiply_region.w32 = gf_w8_bytwo_p_nosse_multiply_region;
-    else
-      gf->multiply_region.w32 = gf_w8_bytwo_p_sse_multiply_region;
-#else
-    gf->multiply_region.w32 = gf_w8_bytwo_p_nosse_multiply_region;
-    if(h->region_type & GF_REGION_SIMD)
-      return 0;
-#endif
-  } else {
-    gf->multiply.w32 = gf_w8_bytwo_b_multiply;
-#ifdef INTEL_SSE2
-    if (h->region_type & GF_REGION_NOSIMD)
-      gf->multiply_region.w32 = gf_w8_bytwo_b_nosse_multiply_region;
-    else
-      gf->multiply_region.w32 = gf_w8_bytwo_b_sse_multiply_region;
-#else
-    gf->multiply_region.w32 = gf_w8_bytwo_b_nosse_multiply_region;
-    if(h->region_type & GF_REGION_SIMD)
-      return 0;
-#endif
-  }
-  return 1;
-}
-
-
-/* ------------------------------------------------------------
-   General procedures.
-   You don't need to error check here on in init, because it's done
-   for you in gf_error_check().
- */
-
-int gf_w8_scratch_size(int mult_type, int region_type, int divide_type, int arg1, int arg2)
-{
-  switch(mult_type)
-  {
-    case GF_MULT_DEFAULT:
-#if defined(INTEL_SSSE3) || defined(ARM_NEON)
-      return sizeof(gf_internal_t) + sizeof(struct gf_w8_default_data) + 64;
-#endif
-      return sizeof(gf_internal_t) + sizeof(struct gf_w8_single_table_data) + 64;
-    case GF_MULT_TABLE:
-      if (region_type == GF_REGION_CAUCHY) {
-        return sizeof(gf_internal_t) + sizeof(struct gf_w8_single_table_data) + 64;
-      }
-
-      if (region_type == GF_REGION_DEFAULT) {
-        return sizeof(gf_internal_t) + sizeof(struct gf_w8_single_table_data) + 64;
-      } 
-      if (region_type & GF_REGION_DOUBLE_TABLE) {
-        if (region_type == GF_REGION_DOUBLE_TABLE) {
-          return sizeof(gf_internal_t) + sizeof(struct gf_w8_double_table_data) + 64;
-        } else if (region_type == (GF_REGION_DOUBLE_TABLE | GF_REGION_LAZY)) {
-          return sizeof(gf_internal_t) + sizeof(struct gf_w8_double_table_lazy_data) + 64;
-        } else {
-          return 0;
-        }
-      }
-      return 0;
-      break;
-    case GF_MULT_BYTWO_p:
-    case GF_MULT_BYTWO_b:
-      return sizeof(gf_internal_t) + sizeof(struct gf_w8_bytwo_data);
-      break;
-    case GF_MULT_SPLIT_TABLE:
-      if ((arg1 == 4 && arg2 == 8) || (arg1 == 8 && arg2 == 4)) {
-        return sizeof(gf_internal_t) + sizeof(struct gf_w8_half_table_data) + 64;
-      }
-      break;
-    case GF_MULT_LOG_TABLE:
-      return sizeof(gf_internal_t) + sizeof(struct gf_w8_logtable_data) + 64;
-      break;
-    case GF_MULT_LOG_ZERO:
-      return sizeof(gf_internal_t) + sizeof(struct gf_w8_logzero_small_table_data) + 64;
-      break;
-    case GF_MULT_LOG_ZERO_EXT:
-      return sizeof(gf_internal_t) + sizeof(struct gf_w8_logzero_table_data) + 64;
-      break;
-    case GF_MULT_CARRY_FREE:
-      return sizeof(gf_internal_t);
-      break;
-    case GF_MULT_SHIFT:
-      return sizeof(gf_internal_t);
-      break;
-    case GF_MULT_COMPOSITE:
-      return sizeof(gf_internal_t) + sizeof(struct gf_w8_composite_data) + 64;
-    default:
-      return 0;
-  }
-  return 0;
-}
-
-int gf_w8_init(gf_t *gf)
-{
-  gf_internal_t *h;
-
-  h = (gf_internal_t *) gf->scratch;
-
-  /* Allen: set default primitive polynomial / irreducible polynomial if needed */
-
-  if (h->prim_poly == 0) {
-    if (h->mult_type == GF_MULT_COMPOSITE) { 
-      h->prim_poly = gf_composite_get_default_poly(h->base_gf);
-      if (h->prim_poly == 0) return 0;   /* JSP: This shouldn't happen, but just in case. */
-    } else {             
-      h->prim_poly = 0x11d;
-    } 
-  }
-  if (h->mult_type != GF_MULT_COMPOSITE) { 
-    h->prim_poly |= 0x100;
-  }
-
-  gf->multiply.w32 = NULL;
-  gf->divide.w32 = NULL;
-  gf->inverse.w32 = NULL;
-  gf->multiply_region.w32 = NULL;
-  gf->extract_word.w32 = gf_w8_extract_word;
-
-  switch(h->mult_type) {
-    case GF_MULT_DEFAULT:      
-    case GF_MULT_TABLE:        if (gf_w8_table_init(gf) == 0) return 0; break;
-    case GF_MULT_BYTWO_p:
-    case GF_MULT_BYTWO_b:      if (gf_w8_bytwo_init(gf) == 0) return 0; break;
-    case GF_MULT_LOG_ZERO:
-    case GF_MULT_LOG_ZERO_EXT:
-    case GF_MULT_LOG_TABLE:    if (gf_w8_log_init(gf) == 0) return 0; break;
-    case GF_MULT_CARRY_FREE:   if (gf_w8_cfm_init(gf) == 0) return 0; break;
-    case GF_MULT_SHIFT:        if (gf_w8_shift_init(gf) == 0) return 0; break;
-    case GF_MULT_SPLIT_TABLE:  if (gf_w8_split_init(gf) == 0) return 0; break;
-    case GF_MULT_COMPOSITE:    if (gf_w8_composite_init(gf) == 0) return 0; break;
-    default: return 0;
-  }
-
-  if (h->divide_type == GF_DIVIDE_EUCLID) {
-    gf->divide.w32 = gf_w8_divide_from_inverse;
-    gf->inverse.w32 = gf_w8_euclid;
-  } else if (h->divide_type == GF_DIVIDE_MATRIX) {
-    gf->divide.w32 = gf_w8_divide_from_inverse;
-    gf->inverse.w32 = gf_w8_matrix;
-  }
-
-  if (gf->divide.w32 == NULL) {
-    gf->divide.w32 = gf_w8_divide_from_inverse;
-    if (gf->inverse.w32 == NULL) gf->inverse.w32 = gf_w8_euclid;
-  }
-
-  if (gf->inverse.w32 == NULL)  gf->inverse.w32 = gf_w8_inverse_from_divide;
-
-  if (h->mult_type == GF_MULT_COMPOSITE && (h->region_type & GF_REGION_ALTMAP)) {
-    gf->extract_word.w32 = gf_w8_composite_extract_word;
-  }
-
-  if (h->region_type == GF_REGION_CAUCHY) {
-    gf->multiply_region.w32 = gf_wgen_cauchy_region;
-    gf->extract_word.w32 = gf_wgen_extract_word;
-  }
-
-  if (gf->multiply_region.w32 == NULL) {
-    gf->multiply_region.w32 = gf_w8_multiply_region_from_single;
-  }
-
-  return 1;
-}
-
-
-/* Inline setup functions */
-
-uint8_t *gf_w8_get_mult_table(gf_t *gf)
-{
-  gf_internal_t *h;
-  struct gf_w8_default_data *ftd;
-  struct gf_w8_single_table_data *std;
-
-  h = (gf_internal_t *) gf->scratch;
-  if (gf->multiply.w32 == gf_w8_default_multiply) {
-    ftd = (struct gf_w8_default_data *) h->private;
-    return (uint8_t *) ftd->multtable;
-  } else if (gf->multiply.w32 == gf_w8_table_multiply) {
-    std = (struct gf_w8_single_table_data *) h->private;
-    return (uint8_t *) std->multtable;
-  }
-  return NULL;
-}
-
-uint8_t *gf_w8_get_div_table(gf_t *gf)
-{
-  struct gf_w8_default_data *ftd;
-  struct gf_w8_single_table_data *std;
-
-  if (gf->multiply.w32 == gf_w8_default_multiply) {
-    ftd = (struct gf_w8_default_data *) ((gf_internal_t *) gf->scratch)->private;
-    return (uint8_t *) ftd->divtable;
-  } else if (gf->multiply.w32 == gf_w8_table_multiply) {
-    std = (struct gf_w8_single_table_data *) ((gf_internal_t *) gf->scratch)->private;
-    return (uint8_t *) std->divtable;
-  }
-  return NULL;
-}
diff --git a/src/erasure-code/jerasure/gf-complete/src/gf_wgen.c b/src/erasure-code/jerasure/gf-complete/src/gf_wgen.c
deleted file mode 100644
index ebc50a5..0000000
--- a/src/erasure-code/jerasure/gf-complete/src/gf_wgen.c
+++ /dev/null
@@ -1,1019 +0,0 @@
-/*
- * GF-Complete: A Comprehensive Open Source Library for Galois Field Arithmetic
- * James S. Plank, Ethan L. Miller, Kevin M. Greenan,
- * Benjamin A. Arnold, John A. Burnum, Adam W. Disney, Allen C. McBride.
- *
- * gf_wgen.c
- *
- * Routines for Galois fields for general w < 32.  For specific w, 
-   like 4, 8, 16, 32, 64 and 128, see the other files.
- */
-
-#include "gf_int.h"
-#include <stdio.h>
-#include <stdlib.h>
-
-struct gf_wgen_table_w8_data {
-  uint8_t *mult;
-  uint8_t *div;
-  uint8_t base;
-};
-
-struct gf_wgen_table_w16_data {
-  uint16_t *mult;
-  uint16_t *div;
-  uint16_t base;
-};
-
-struct gf_wgen_log_w8_data {
-  uint8_t *log;
-  uint8_t *anti;
-  uint8_t *danti;
-  uint8_t base;
-};
-
-struct gf_wgen_log_w16_data {
-  uint16_t *log;
-  uint16_t *anti;
-  uint16_t *danti;
-  uint16_t base;
-};
-
-struct gf_wgen_log_w32_data {
-  uint32_t *log;
-  uint32_t *anti;
-  uint32_t *danti;
-  uint32_t base;
-};
-
-struct gf_wgen_group_data {
-    uint32_t *reduce;
-    uint32_t *shift;
-    uint32_t mask;
-    uint64_t rmask;
-    int tshift;
-    uint32_t memory;
-};
-
-static
-inline
-gf_val_32_t gf_wgen_inverse_from_divide (gf_t *gf, gf_val_32_t a)
-{
-  return gf->divide.w32(gf, 1, a);
-}
-
-static
-inline
-gf_val_32_t gf_wgen_divide_from_inverse (gf_t *gf, gf_val_32_t a, gf_val_32_t b)
-{
-  b = gf->inverse.w32(gf, b);
-  return gf->multiply.w32(gf, a, b);
-}
-
-static
-inline
-gf_val_32_t gf_wgen_euclid (gf_t *gf, gf_val_32_t b)
-{
-  
-  gf_val_32_t e_i, e_im1, e_ip1;
-  gf_val_32_t d_i, d_im1, d_ip1;
-  gf_val_32_t y_i, y_im1, y_ip1;
-  gf_val_32_t c_i;
-
-  if (b == 0) return -1;
-  e_im1 = ((gf_internal_t *) (gf->scratch))->prim_poly;
-  e_i = b;
-  d_im1 = ((gf_internal_t *) (gf->scratch))->w;
-  for (d_i = d_im1; ((1 << d_i) & e_i) == 0; d_i--) ;
-  y_i = 1;
-  y_im1 = 0;
-
-  while (e_i != 1) {
-
-    e_ip1 = e_im1;
-    d_ip1 = d_im1;
-    c_i = 0;
-
-    while (d_ip1 >= d_i) {
-      c_i ^= (1 << (d_ip1 - d_i));
-      e_ip1 ^= (e_i << (d_ip1 - d_i));
-      if (e_ip1 == 0) return 0;
-      while ((e_ip1 & (1 << d_ip1)) == 0) d_ip1--;
-    }
-
-    y_ip1 = y_im1 ^ gf->multiply.w32(gf, c_i, y_i);
-    y_im1 = y_i;
-    y_i = y_ip1;
-
-    e_im1 = e_i;
-    d_im1 = d_i;
-    e_i = e_ip1;
-    d_i = d_ip1;
-  }
-
-  return y_i;
-}
-
-gf_val_32_t gf_wgen_extract_word(gf_t *gf, void *start, int bytes, int index)
-{
-  uint8_t *ptr;
-  uint32_t rv;
-  int rs;
-  int byte, bit, i;
-  gf_internal_t *h;
-
-  h = (gf_internal_t *) gf->scratch;
-  rs = bytes / h->w;
-  byte = index/8;
-  bit = index%8;
-
-  ptr = (uint8_t *) start;
-  ptr += bytes;
-  ptr -= rs;
-  ptr += byte;
-
-  rv = 0;
-  for (i = 0; i < h->w; i++) {
-    rv <<= 1;
-    if ((*ptr) & (1 << bit)) rv |= 1;
-    ptr -= rs;
-  }
-  
-  return rv;
-}
-
-static
-inline
-gf_val_32_t gf_wgen_matrix (gf_t *gf, gf_val_32_t b)
-{
-  return gf_bitmatrix_inverse(b, ((gf_internal_t *) (gf->scratch))->w, 
-              ((gf_internal_t *) (gf->scratch))->prim_poly);
-}
-
-static
-inline
-uint32_t
-gf_wgen_shift_multiply (gf_t *gf, uint32_t a32, uint32_t b32)
-{
-  uint64_t product, i, pp, a, b, one;
-  gf_internal_t *h;
- 
-  a = a32;
-  b = b32;
-  h = (gf_internal_t *) gf->scratch;
-  one = 1;
-  pp = h->prim_poly | (one << h->w);
-
-  product = 0;
-
-  for (i = 0; i < (uint64_t)h->w; i++) {
-    if (a & (one << i)) product ^= (b << i);
-  }
-  for (i = h->w*2-1; i >= (uint64_t)h->w; i--) {
-    if (product & (one << i)) product ^= (pp << (i-h->w));
-  }
-  return product;
-}
-
-static 
-int gf_wgen_shift_init(gf_t *gf)
-{
-  gf->multiply.w32 = gf_wgen_shift_multiply;
-  gf->inverse.w32 = gf_wgen_euclid;
-  return 1;
-}
-
-static
-gf_val_32_t
-gf_wgen_bytwo_b_multiply (gf_t *gf, gf_val_32_t a, gf_val_32_t b)
-{
-  uint32_t prod, pp, bmask;
-  gf_internal_t *h;
-
-  h = (gf_internal_t *) gf->scratch;
-  pp = h->prim_poly;
-
-  prod = 0;
-  bmask = (1 << (h->w-1));
-
-  while (1) {
-    if (a & 1) prod ^= b;
-    a >>= 1;
-    if (a == 0) return prod;
-    if (b & bmask) {
-      b = ((b << 1) ^ pp);
-    } else {
-      b <<= 1;
-    }
-  }
-}
-
-static 
-int gf_wgen_bytwo_b_init(gf_t *gf)
-{
-  gf->multiply.w32 = gf_wgen_bytwo_b_multiply;
-  gf->inverse.w32 = gf_wgen_euclid;
-  return 1;
-}
-
-static
-inline
-gf_val_32_t
-gf_wgen_bytwo_p_multiply (gf_t *gf, gf_val_32_t a, gf_val_32_t b)
-{
-  uint32_t prod, pp, pmask, amask;
-  gf_internal_t *h;
-
-  h = (gf_internal_t *) gf->scratch;
-  pp = h->prim_poly;
-
-  prod = 0;
-  pmask = (1 << ((h->w)-1)); /*Ben: Had an operator precedence warning here*/
-  amask = pmask;
-
-  while (amask != 0) {
-    if (prod & pmask) {
-      prod = ((prod << 1) ^ pp);
-    } else {
-      prod <<= 1;
-    }
-    if (a & amask) prod ^= b;
-    amask >>= 1;
-  }
-  return prod;
-}
-
-
-static 
-int gf_wgen_bytwo_p_init(gf_t *gf)
-{
-  gf->multiply.w32 = gf_wgen_bytwo_p_multiply;
-  gf->inverse.w32 = gf_wgen_euclid;
-  return 1;
-}
-
-static
-void
-gf_wgen_group_set_shift_tables(uint32_t *shift, uint32_t val, gf_internal_t *h)
-{
-  uint32_t i;
-  uint32_t j;
-  int g_s;
-
-  if (h->mult_type == GF_MULT_DEFAULT) {
-    g_s = 2;
-  } else {
-    g_s = h->arg1;
-  }
-
-  shift[0] = 0;
-
-  for (i = 1; i < ((uint32_t)1 << g_s); i <<= 1) {
-    for (j = 0; j < i; j++) shift[i|j] = shift[j]^val;
-    if (val & (1 << (h->w-1))) {
-      val <<= 1;
-      val ^= h->prim_poly;
-    } else {
-      val <<= 1;
-    }
-  }
-}
-
-static
-inline
-gf_val_32_t
-gf_wgen_group_s_equals_r_multiply(gf_t *gf, gf_val_32_t a, gf_val_32_t b)
-{
-  int leftover, rs;
-  uint32_t p, l, ind, a32;
-  int bits_left;
-  int g_s;
-  int w;
-
-  struct gf_wgen_group_data *gd;
-  gf_internal_t *h = (gf_internal_t *) gf->scratch;
-  g_s = h->arg1;
-  w = h->w;
-
-  gd = (struct gf_wgen_group_data *) h->private;
-  gf_wgen_group_set_shift_tables(gd->shift, b, h);
-
-  leftover = w % g_s;
-  if (leftover == 0) leftover = g_s;
-
-  rs = w - leftover;
-  a32 = a;
-  ind = a32 >> rs;
-  a32 <<= leftover;
-  a32 &= gd->mask;
-  p = gd->shift[ind];
-
-  bits_left = rs;
-  rs = w - g_s;
-
-  while (bits_left > 0) {
-    bits_left -= g_s;
-    ind = a32 >> rs;
-    a32 <<= g_s;
-    a32 &= gd->mask;
-    l = p >> rs;
-    p = (gd->shift[ind] ^ gd->reduce[l] ^ (p << g_s)) & gd->mask;
-  }
-  return p;
-}
-
-char *bits(uint32_t v)
-{
-  char *rv;
-  int i, j;
-
-  rv = malloc(30);
-  j = 0;
-  for (i = 27; i >= 0; i--) {
-    rv[j] = '0' + ((v & (1 << i)) ? 1 : 0);
-    j++;
-  }
-  rv[j] = '\0';
-  return rv;
-}
-char *bits_56(uint64_t v)
-{
-  char *rv;
-  int i, j;
-  uint64_t one;
-
-  one = 1;
-
-  rv = malloc(60);
-  j = 0;
-  for (i = 55; i >= 0; i--) {
-    rv[j] = '0' + ((v & (one << i)) ? 1 : 0);
-    j++;
-  }
-  rv[j] = '\0';
-  return rv;
-}
-
-static
-inline
-gf_val_32_t
-gf_wgen_group_multiply(gf_t *gf, gf_val_32_t a, gf_val_32_t b)
-{
-  int i;
-  int leftover;
-  uint64_t p, l, r;
-  uint32_t a32, ind;
-  int g_s, g_r;
-  struct gf_wgen_group_data *gd;
-  int w;
-
-  gf_internal_t *h = (gf_internal_t *) gf->scratch;
-  if (h->mult_type == GF_MULT_DEFAULT) {
-    g_s = 2;
-    g_r = 8;
-  } else {
-    g_s = h->arg1;
-    g_r = h->arg2;
-  }
-  w = h->w;
-  gd = (struct gf_wgen_group_data *) h->private;
-  gf_wgen_group_set_shift_tables(gd->shift, b, h);
-
-  leftover = w % g_s;
-  if (leftover == 0) leftover = g_s;
-
-  a32 = a;
-  ind = a32 >> (w - leftover);
-  p = gd->shift[ind];
-  p <<= g_s;
-  a32 <<= leftover;
-  a32 &= gd->mask;
-
-  i = (w - leftover);
-  while (i > g_s) {
-    ind = a32 >> (w-g_s);
-    p ^= gd->shift[ind];
-    a32 <<= g_s;
-    a32 &= gd->mask;
-    p <<= g_s;
-    i -= g_s;
-  }
-
-  ind = a32 >> (h->w-g_s);
-  p ^= gd->shift[ind];
-
-  for (i = gd->tshift ; i >= 0; i -= g_r) {
-    l = p & (gd->rmask << i);
-    r = gd->reduce[l >> (i+w)];
-    r <<= (i);
-    p ^= r;
-  }
-  return p & gd->mask;
-}
-
-static
-int gf_wgen_group_init(gf_t *gf)
-{
-  uint32_t i, j, p, index;
-  struct gf_wgen_group_data *gd;
-  gf_internal_t *h = (gf_internal_t *) gf->scratch;
-  uint32_t g_s, g_r;
-
-  if (h->mult_type == GF_MULT_DEFAULT) {
-    g_s = 2;
-    g_r = 8;
-  } else {
-    g_s = h->arg1;
-    g_r = h->arg2;
-  }
-  gd = (struct gf_wgen_group_data *) h->private;
-  gd->shift = &(gd->memory);
-  gd->reduce = gd->shift + (1 << g_s);
-  gd->mask = (h->w != 31) ? ((1 << h->w)-1) : 0x7fffffff;
-
-  gd->rmask = (1 << g_r) - 1;
-  gd->rmask <<= h->w;
-
-  gd->tshift = h->w % g_s;
-  if (gd->tshift == 0) gd->tshift = g_s;
-  gd->tshift = (h->w - gd->tshift);
-  gd->tshift = ((gd->tshift-1)/g_r) * g_r;
-
-  gd->reduce[0] = 0;
-  for (i = 0; i < ((uint32_t)1 << g_r); i++) {
-    p = 0;
-    index = 0;
-    for (j = 0; j < g_r; j++) {
-      if (i & (1 << j)) {
-        p ^= (h->prim_poly << j);
-        index ^= (h->prim_poly >> (h->w-j));
-      }
-    }
-    gd->reduce[index] = (p & gd->mask);
-  }
-
-  if (g_s == g_r) {
-    gf->multiply.w32 = gf_wgen_group_s_equals_r_multiply;
-  } else {
-    gf->multiply.w32 = gf_wgen_group_multiply; 
-  }
-  gf->divide.w32 = NULL;
-  gf->divide.w32 = NULL;
-  return 1;
-}
-
-
-static
-gf_val_32_t
-gf_wgen_table_8_multiply(gf_t *gf, gf_val_32_t a, gf_val_32_t b)
-{
-  gf_internal_t *h;
-  struct gf_wgen_table_w8_data *std;
-  
-  h = (gf_internal_t *) gf->scratch;
-  std = (struct gf_wgen_table_w8_data *) h->private;
-
-  return (std->mult[(a<<h->w)+b]);
-}
-
-static
-gf_val_32_t
-gf_wgen_table_8_divide(gf_t *gf, gf_val_32_t a, gf_val_32_t b)
-{
-  gf_internal_t *h;
-  struct gf_wgen_table_w8_data *std;
-  
-  h = (gf_internal_t *) gf->scratch;
-  std = (struct gf_wgen_table_w8_data *) h->private;
-
-  return (std->div[(a<<h->w)+b]);
-}
-
-static 
-int gf_wgen_table_8_init(gf_t *gf)
-{
-  gf_internal_t *h;
-  int w;
-  struct gf_wgen_table_w8_data *std;
-  uint32_t a, b, p;
-  
-  h = (gf_internal_t *) gf->scratch;
-  w = h->w;
-  std = (struct gf_wgen_table_w8_data *) h->private;
-  
-  std->mult = &(std->base);
-  std->div = std->mult + ((1<<h->w)*(1<<h->w));
-  
-  for (a = 0; a < ((uint32_t)1 << w); a++) {
-    std->mult[a] = 0;
-    std->mult[a<<w] = 0;
-    std->div[a] = 0;
-    std->div[a<<w] = 0;
-  }
-    
-  for (a = 1; a < ((uint32_t)1 << w); a++) {
-    for (b = 1; b < ((uint32_t)1 << w); b++) {
-      p = gf_wgen_shift_multiply(gf, a, b);
-      std->mult[(a<<w)|b] = p;
-      std->div[(p<<w)|a] = b;
-    }
-  }
-
-  gf->multiply.w32 = gf_wgen_table_8_multiply;
-  gf->divide.w32 = gf_wgen_table_8_divide;
-  return 1;
-}
-
-static
-gf_val_32_t
-gf_wgen_table_16_multiply(gf_t *gf, gf_val_32_t a, gf_val_32_t b)
-{
-  gf_internal_t *h;
-  struct gf_wgen_table_w16_data *std;
-  
-  h = (gf_internal_t *) gf->scratch;
-  std = (struct gf_wgen_table_w16_data *) h->private;
-
-  return (std->mult[(a<<h->w)+b]);
-}
-
-static
-gf_val_32_t
-gf_wgen_table_16_divide(gf_t *gf, gf_val_32_t a, gf_val_32_t b)
-{
-  gf_internal_t *h;
-  struct gf_wgen_table_w16_data *std;
-  
-  h = (gf_internal_t *) gf->scratch;
-  std = (struct gf_wgen_table_w16_data *) h->private;
-
-  return (std->div[(a<<h->w)+b]);
-}
-
-static 
-int gf_wgen_table_16_init(gf_t *gf)
-{
-  gf_internal_t *h;
-  int w;
-  struct gf_wgen_table_w16_data *std;
-  uint32_t a, b, p;
-  
-  h = (gf_internal_t *) gf->scratch;
-  w = h->w;
-  std = (struct gf_wgen_table_w16_data *) h->private;
-  
-  std->mult = &(std->base);
-  std->div = std->mult + ((1<<h->w)*(1<<h->w));
-  
-  for (a = 0; a < ((uint32_t)1 << w); a++) {
-    std->mult[a] = 0;
-    std->mult[a<<w] = 0;
-    std->div[a] = 0;
-    std->div[a<<w] = 0;
-  }
-  
-  for (a = 1; a < ((uint32_t)1 << w); a++) {
-    for (b = 1; b < ((uint32_t)1 << w); b++) {
-      p = gf_wgen_shift_multiply(gf, a, b);
-      std->mult[(a<<w)|b] = p;
-      std->div[(p<<w)|a] = b;
-    }
-  }
-
-  gf->multiply.w32 = gf_wgen_table_16_multiply;
-  gf->divide.w32 = gf_wgen_table_16_divide;
-  return 1;
-}
-
-static 
-int gf_wgen_table_init(gf_t *gf)
-{
-  gf_internal_t *h;
-  
-  h = (gf_internal_t *) gf->scratch;
-  if (h->w <= 8) return gf_wgen_table_8_init(gf);
-  if (h->w <= 14) return gf_wgen_table_16_init(gf);
-
-  /* Returning zero to make the compiler happy, but this won't get 
-     executed, because it is tested in _scratch_space. */
-
-  return 0;
-}
-
-static
-gf_val_32_t
-gf_wgen_log_8_multiply(gf_t *gf, gf_val_32_t a, gf_val_32_t b)
-{
-  gf_internal_t *h;
-  struct gf_wgen_log_w8_data *std;
-  
-  h = (gf_internal_t *) gf->scratch;
-  std = (struct gf_wgen_log_w8_data *) h->private;
-
-  if (a == 0 || b == 0) return 0;
-  return (std->anti[std->log[a]+std->log[b]]);
-}
-
-static
-gf_val_32_t
-gf_wgen_log_8_divide(gf_t *gf, gf_val_32_t a, gf_val_32_t b)
-{
-  gf_internal_t *h;
-  struct gf_wgen_log_w8_data *std;
-  int index;
-  
-  h = (gf_internal_t *) gf->scratch;
-  std = (struct gf_wgen_log_w8_data *) h->private;
-
-  if (a == 0 || b == 0) return 0;
-  index = std->log[a];
-  index -= std->log[b];
-
-  return (std->danti[index]);
-}
-
-static 
-int gf_wgen_log_8_init(gf_t *gf)
-{
-  gf_internal_t *h;
-  struct gf_wgen_log_w8_data *std;
-  int w;
-  uint32_t a, i;
-  int check = 0;
-  
-  h = (gf_internal_t *) gf->scratch;
-  w = h->w;
-  std = (struct gf_wgen_log_w8_data *) h->private;
-  
-  std->log = &(std->base);
-  std->anti = std->log + (1<<h->w);
-  std->danti = std->anti + (1<<h->w)-1;
-  
-  for (i = 0; i < ((uint32_t)1 << w); i++)
-    std->log[i] = 0;
-
-  a = 1;
-  for(i=0; i < ((uint32_t)1<<w)-1; i++)
-  {
-    if (std->log[a] != 0) check = 1;
-    std->log[a] = i;
-    std->anti[i] = a;
-    std->danti[i] = a;
-    a <<= 1;
-    if(a & (1<<w))
-      a ^= h->prim_poly;
-    //a &= ((1 << w)-1);
-  }
-
-  if (check != 0) {
-    _gf_errno = GF_E_LOGPOLY;
-    return 0;
-  }
-
-  gf->multiply.w32 = gf_wgen_log_8_multiply;
-  gf->divide.w32 = gf_wgen_log_8_divide;
-  return 1;
-}
-
-static
-gf_val_32_t
-gf_wgen_log_16_multiply(gf_t *gf, gf_val_32_t a, gf_val_32_t b)
-{
-  gf_internal_t *h;
-  struct gf_wgen_log_w16_data *std;
-  
-  h = (gf_internal_t *) gf->scratch;
-  std = (struct gf_wgen_log_w16_data *) h->private;
-
-  if (a == 0 || b == 0) return 0;
-  return (std->anti[std->log[a]+std->log[b]]);
-}
-
-static
-gf_val_32_t
-gf_wgen_log_16_divide(gf_t *gf, gf_val_32_t a, gf_val_32_t b)
-{
-  gf_internal_t *h;
-  struct gf_wgen_log_w16_data *std;
-  int index;
-  
-  h = (gf_internal_t *) gf->scratch;
-  std = (struct gf_wgen_log_w16_data *) h->private;
-
-  if (a == 0 || b == 0) return 0;
-  index = std->log[a];
-  index -= std->log[b];
-
-  return (std->danti[index]);
-}
-
-static 
-int gf_wgen_log_16_init(gf_t *gf)
-{
-  gf_internal_t *h;
-  struct gf_wgen_log_w16_data *std;
-  int w;
-  uint32_t a, i;
-  int check = 0;
-  
-  h = (gf_internal_t *) gf->scratch;
-  w = h->w;
-  std = (struct gf_wgen_log_w16_data *) h->private;
-  
-  std->log = &(std->base);
-  std->anti = std->log + (1<<h->w);
-  std->danti = std->anti + (1<<h->w)-1;
- 
-  for (i = 0; i < ((uint32_t)1 << w); i++)
-    std->log[i] = 0;
-
-  a = 1;
-  for(i=0; i < ((uint32_t)1<<w)-1; i++)
-  {
-    if (std->log[a] != 0) check = 1;
-    std->log[a] = i;
-    std->anti[i] = a;
-    std->danti[i] = a;
-    a <<= 1;
-    if(a & (1<<w))
-      a ^= h->prim_poly;
-    //a &= ((1 << w)-1);
-  }
-
-  if (check) {
-    if (h->mult_type != GF_MULT_LOG_TABLE) return gf_wgen_shift_init(gf);
-    _gf_errno = GF_E_LOGPOLY;
-    return 0;
-  }
-  
-  gf->multiply.w32 = gf_wgen_log_16_multiply;
-  gf->divide.w32 = gf_wgen_log_16_divide;
-  return 1;
-}
-
-static
-gf_val_32_t
-gf_wgen_log_32_multiply(gf_t *gf, gf_val_32_t a, gf_val_32_t b)
-{
-  gf_internal_t *h;
-  struct gf_wgen_log_w32_data *std;
-  
-  h = (gf_internal_t *) gf->scratch;
-  std = (struct gf_wgen_log_w32_data *) h->private;
-
-  if (a == 0 || b == 0) return 0;
-  return (std->anti[std->log[a]+std->log[b]]);
-}
-
-static
-gf_val_32_t
-gf_wgen_log_32_divide(gf_t *gf, gf_val_32_t a, gf_val_32_t b)
-{
-  gf_internal_t *h;
-  struct gf_wgen_log_w32_data *std;
-  int index;
-  
-  h = (gf_internal_t *) gf->scratch;
-  std = (struct gf_wgen_log_w32_data *) h->private;
-
-  if (a == 0 || b == 0) return 0;
-  index = std->log[a];
-  index -= std->log[b];
-
-  return (std->danti[index]);
-}
-
-static 
-int gf_wgen_log_32_init(gf_t *gf)
-{
-  gf_internal_t *h;
-  struct gf_wgen_log_w32_data *std;
-  int w;
-  uint32_t a, i;
-  int check = 0;
-
-  h = (gf_internal_t *) gf->scratch;
-  w = h->w;
-  std = (struct gf_wgen_log_w32_data *) h->private;
-  
-  std->log = &(std->base);
-  std->anti = std->log + (1<<h->w);
-  std->danti = std->anti + (1<<h->w)-1;
-  
-  for (i = 0; i < ((uint32_t)1 << w); i++)
-    std->log[i] = 0;
-
-  a = 1;
-  for(i=0; i < ((uint32_t)1<<w)-1; i++)
-  {
-    if (std->log[a] != 0) check = 1;
-    std->log[a] = i;
-    std->anti[i] = a;
-    std->danti[i] = a;
-    a <<= 1;
-    if(a & (1<<w))
-      a ^= h->prim_poly;
-    //a &= ((1 << w)-1);
-  }
-
-  if (check != 0) {
-    _gf_errno = GF_E_LOGPOLY;
-    return 0;
-  }
-
-  gf->multiply.w32 = gf_wgen_log_32_multiply;
-  gf->divide.w32 = gf_wgen_log_32_divide;
-  return 1;
-}
-
-static 
-int gf_wgen_log_init(gf_t *gf)
-{
-  gf_internal_t *h;
-  
-  h = (gf_internal_t *) gf->scratch;
-  if (h->w <= 8) return gf_wgen_log_8_init(gf);
-  if (h->w <= 16) return gf_wgen_log_16_init(gf);
-  if (h->w <= 32) return gf_wgen_log_32_init(gf); 
-
-  /* Returning zero to make the compiler happy, but this won't get 
-     executed, because it is tested in _scratch_space. */
-
-  return 0;
-}
-
-int gf_wgen_scratch_size(int w, int mult_type, int region_type, int divide_type, int arg1, int arg2)
-{
-
-  switch(mult_type)
-  {
-    case GF_MULT_DEFAULT: 
-      if (w <= 8) {
-          return sizeof(gf_internal_t) + sizeof(struct gf_wgen_table_w8_data) +
-               sizeof(uint8_t)*(1 << w)*(1<<w)*2 + 64;
-      } else if (w <= 16) {
-        return sizeof(gf_internal_t) + sizeof(struct gf_wgen_log_w16_data) +
-               sizeof(uint16_t)*(1 << w)*3;
-      } else {
-        return sizeof(gf_internal_t) + sizeof(struct gf_wgen_group_data) +
-               sizeof(uint32_t) * (1 << 2) +
-               sizeof(uint32_t) * (1 << 8) + 64;
-      }
-    case GF_MULT_SHIFT:
-    case GF_MULT_BYTWO_b:
-    case GF_MULT_BYTWO_p:
-      return sizeof(gf_internal_t);
-      break;
-    case GF_MULT_GROUP:
-      return sizeof(gf_internal_t) + sizeof(struct gf_wgen_group_data) +
-               sizeof(uint32_t) * (1 << arg1) +
-               sizeof(uint32_t) * (1 << arg2) + 64;
-      break;
-
-    case GF_MULT_TABLE: 
-      if (w <= 8) {
-        return sizeof(gf_internal_t) + sizeof(struct gf_wgen_table_w8_data) +
-               sizeof(uint8_t)*(1 << w)*(1<<w)*2 + 64;
-      } else if (w < 15) {
-        return sizeof(gf_internal_t) + sizeof(struct gf_wgen_table_w16_data) +
-               sizeof(uint16_t)*(1 << w)*(1<<w)*2 + 64;
-      } 
-      return 0;
-    case GF_MULT_LOG_TABLE: 
-      if (w <= 8) {
-        return sizeof(gf_internal_t) + sizeof(struct gf_wgen_log_w8_data) +
-               sizeof(uint8_t)*(1 << w)*3;
-      } else if (w <= 16) {
-        return sizeof(gf_internal_t) + sizeof(struct gf_wgen_log_w16_data) +
-               sizeof(uint16_t)*(1 << w)*3;
-      } else if (w <= 27) {
-        return sizeof(gf_internal_t) + sizeof(struct gf_wgen_log_w32_data) +
-               sizeof(uint32_t)*(1 << w)*3;
-      } else 
-      return 0;
-    default:
-      return 0;
-   }
-}
-
-void
-gf_wgen_cauchy_region(gf_t *gf, void *src, void *dest, gf_val_32_t val, int bytes, int xor)
-{
-  gf_internal_t *h;
-  gf_region_data rd;
-  int written;    
-  int rs, i, j;
-
-  gf_set_region_data(&rd, gf, src, dest, bytes, val, xor, -1);
-
-  if (val == 0) { gf_multby_zero(dest, bytes, xor); return; }
-  if (val == 1) { gf_multby_one(src, dest, bytes, xor); return; }
-
-  h = (gf_internal_t *) gf->scratch;
-  rs = bytes / (h->w);
-  
-  written = (xor) ? 0xffffffff : 0;
-  for (i = 0; i < h->w; i++) {
-    for (j = 0; j < h->w; j++) {
-      if (val & (1 << j)) {
-        gf_multby_one(src, ((uint8_t *)dest) + j*rs, rs, (written & (1 << j)));
-        written |= (1 << j);
-      }
-    }
-    src = (uint8_t *)src + rs;
-    val = gf->multiply.w32(gf, val, 2);
-  }
-}
-
-int gf_wgen_init(gf_t *gf)
-{
-  gf_internal_t *h;
-
-  h = (gf_internal_t *) gf->scratch;
-  if (h->prim_poly == 0) {
-    switch (h->w) {
-      case 1: h->prim_poly = 1; break;
-      case 2: h->prim_poly = 7; break;
-      case 3: h->prim_poly = 013; break;
-      case 4: h->prim_poly = 023; break;
-      case 5: h->prim_poly = 045; break;
-      case 6: h->prim_poly = 0103; break;
-      case 7: h->prim_poly = 0211; break;
-      case 8: h->prim_poly = 0435; break;
-      case 9: h->prim_poly = 01021; break;
-      case 10: h->prim_poly = 02011; break;
-      case 11: h->prim_poly = 04005; break;
-      case 12: h->prim_poly = 010123; break;
-      case 13: h->prim_poly = 020033; break;
-      case 14: h->prim_poly = 042103; break;
-      case 15: h->prim_poly = 0100003; break;
-      case 16: h->prim_poly = 0210013; break;
-      case 17: h->prim_poly = 0400011; break;
-      case 18: h->prim_poly = 01000201; break;
-      case 19: h->prim_poly = 02000047; break;
-      case 20: h->prim_poly = 04000011; break;
-      case 21: h->prim_poly = 010000005; break;
-      case 22: h->prim_poly = 020000003; break;
-      case 23: h->prim_poly = 040000041; break;
-      case 24: h->prim_poly = 0100000207; break;
-      case 25: h->prim_poly = 0200000011; break;
-      case 26: h->prim_poly = 0400000107; break;
-      case 27: h->prim_poly = 01000000047; break;
-      case 28: h->prim_poly = 02000000011; break;
-      case 29: h->prim_poly = 04000000005; break;
-      case 30: h->prim_poly = 010040000007; break;
-      case 31: h->prim_poly = 020000000011; break;
-      case 32: h->prim_poly = 00020000007; break;
-      default: fprintf(stderr, "gf_wgen_init: w not defined yet\n"); exit(1);
-    }
-  } else {
-    if (h->w == 32) {
-      h->prim_poly &= 0xffffffff;
-    } else {
-      h->prim_poly |= (1 << h->w);
-      if (h->prim_poly & ~((1ULL<<(h->w+1))-1)) return 0;
-    }
-  }
-
-  gf->multiply.w32 = NULL;
-  gf->divide.w32 = NULL;
-  gf->inverse.w32 = NULL;
-  gf->multiply_region.w32 = gf_wgen_cauchy_region;
-  gf->extract_word.w32 = gf_wgen_extract_word;
-
-  switch(h->mult_type) {
-    case GF_MULT_DEFAULT:
-      if (h->w <= 8) {
-        if (gf_wgen_table_init(gf) == 0) return 0; 
-      } else if (h->w <= 16) {
-        if (gf_wgen_log_init(gf) == 0) return 0; 
-      } else {
-        if (gf_wgen_bytwo_p_init(gf) == 0) return 0; 
-      }
-      break;
-    case GF_MULT_SHIFT:     if (gf_wgen_shift_init(gf) == 0) return 0; break;
-    case GF_MULT_BYTWO_b:     if (gf_wgen_bytwo_b_init(gf) == 0) return 0; break;
-    case GF_MULT_BYTWO_p:     if (gf_wgen_bytwo_p_init(gf) == 0) return 0; break;
-    case GF_MULT_GROUP:     if (gf_wgen_group_init(gf) == 0) return 0; break;
-    case GF_MULT_TABLE:     if (gf_wgen_table_init(gf) == 0) return 0; break;
-    case GF_MULT_LOG_TABLE: if (gf_wgen_log_init(gf) == 0) return 0; break;
-    default: return 0;
-  }
-  if (h->divide_type == GF_DIVIDE_EUCLID) {
-    gf->divide.w32 = gf_wgen_divide_from_inverse;
-    gf->inverse.w32 = gf_wgen_euclid;
-  } else if (h->divide_type == GF_DIVIDE_MATRIX) {
-    gf->divide.w32 = gf_wgen_divide_from_inverse;
-    gf->inverse.w32 = gf_wgen_matrix;
-  }
-
-  if (gf->inverse.w32== NULL && gf->divide.w32 == NULL) gf->inverse.w32 = gf_wgen_euclid;
-
-  if (gf->inverse.w32 != NULL && gf->divide.w32 == NULL) {
-    gf->divide.w32 = gf_wgen_divide_from_inverse;
-  }
-  if (gf->inverse.w32 == NULL && gf->divide.w32 != NULL) {
-    gf->inverse.w32 = gf_wgen_inverse_from_divide;
-  }
-  return 1;
-}
diff --git a/src/erasure-code/jerasure/gf-complete/src/neon/gf_w16_neon.c b/src/erasure-code/jerasure/gf-complete/src/neon/gf_w16_neon.c
deleted file mode 100644
index 95bfd80..0000000
--- a/src/erasure-code/jerasure/gf-complete/src/neon/gf_w16_neon.c
+++ /dev/null
@@ -1,356 +0,0 @@
-/*
- * GF-Complete: A Comprehensive Open Source Library for Galois Field Arithmetic
- * James S. Plank, Ethan L. Miller, Kevin M. Greenan,
- * Benjamin A. Arnold, John A. Burnum, Adam W. Disney, Allen C. McBride.
- *
- * Copyright (c) 2014: Janne Grunau <j at jannau.net>
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- *  - Redistributions of source code must retain the above copyright
- *     notice, this list of conditions and the following disclaimer.
- *
- *  - Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- *  - Neither the name of the University of Tennessee nor the names of its
- *    contributors may be used to endorse or promote products derived
- *    from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
- * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
- * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
- * WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- *
- *
- * gf_w16_neon.c
- *
- * Neon routines for 16-bit Galois fields
- *
- */
-
-#include "gf_int.h"
-#include <stdio.h>
-#include <stdlib.h>
-#include "gf_w16.h"
-
-#ifdef ARCH_AARCH64
-static
-inline
-void
-neon_w16_split_4_multiply_region(gf_t *gf, uint16_t *src, uint16_t *dst,
-                                 uint16_t *d_end, uint8_t *tbl,
-                                 gf_val_32_t val, int xor)
-{
-  unsigned i;
-  uint8_t *high = tbl + 4 * 16;
-  uint16x8_t va0, va1, r0, r1;
-  uint8x16_t loset, rl, rh;
-  uint8x16x2_t va;
-
-  uint8x16_t tbl_h[4], tbl_l[4];
-  for (i = 0; i < 4; i++) {
-      tbl_l[i] = vld1q_u8(tbl + i*16);
-      tbl_h[i] = vld1q_u8(high + i*16);
-  }
-
-  loset = vdupq_n_u8(0xf);
-
-  while (dst < d_end) {
-      va0 = vld1q_u16(src);
-      va1 = vld1q_u16(src + 8);
-
-      va = vtrnq_u8(vreinterpretq_u8_u16(va0), vreinterpretq_u8_u16(va1));
-
-      rl = vqtbl1q_u8(tbl_l[0], vandq_u8(va.val[0], loset));
-      rh = vqtbl1q_u8(tbl_h[0], vandq_u8(va.val[0], loset));
-      rl = veorq_u8(rl, vqtbl1q_u8(tbl_l[2], vandq_u8(va.val[1], loset)));
-      rh = veorq_u8(rh, vqtbl1q_u8(tbl_h[2], vandq_u8(va.val[1], loset)));
-
-      va.val[0] = vshrq_n_u8(va.val[0], 4);
-      va.val[1] = vshrq_n_u8(va.val[1], 4);
-
-      rl = veorq_u8(rl, vqtbl1q_u8(tbl_l[1], va.val[0]));
-      rh = veorq_u8(rh, vqtbl1q_u8(tbl_h[1], va.val[0]));
-      rl = veorq_u8(rl, vqtbl1q_u8(tbl_l[3], va.val[1]));
-      rh = veorq_u8(rh, vqtbl1q_u8(tbl_h[3], va.val[1]));
-
-      va = vtrnq_u8(rl, rh);
-      r0 = vreinterpretq_u16_u8(va.val[0]);
-      r1 = vreinterpretq_u16_u8(va.val[1]);
-
-      if (xor) {
-          va0 = vld1q_u16(dst);
-          va1 = vld1q_u16(dst + 8);
-          r0 = veorq_u16(r0, va0);
-          r1 = veorq_u16(r1, va1);
-      }
-      vst1q_u16(dst, r0);
-      vst1q_u16(dst + 8, r1);
-
-      src += 16;
-      dst += 16;
-  }
-}
-
-static
-inline
-void
-neon_w16_split_4_altmap_multiply_region(gf_t *gf, uint8_t *src,
-                                        uint8_t *dst, uint8_t *d_end,
-                                        uint8_t *tbl, gf_val_32_t val,
-                                        int xor)
-{
-  unsigned i;
-  uint8_t *high = tbl + 4 * 16;
-  uint8x16_t vh, vl, rh, rl;
-  uint8x16_t loset;
-
-  uint8x16_t tbl_h[4], tbl_l[4];
-  for (i = 0; i < 4; i++) {
-      tbl_l[i] = vld1q_u8(tbl + i*16);
-      tbl_h[i] = vld1q_u8(high + i*16);
-  }
-
-  loset = vdupq_n_u8(0xf);
-
-  while (dst < d_end) {
-      vh = vld1q_u8(src);
-      vl = vld1q_u8(src + 16);
-
-      rl = vqtbl1q_u8(tbl_l[0], vandq_u8(vl, loset));
-      rh = vqtbl1q_u8(tbl_h[0], vandq_u8(vl, loset));
-      rl = veorq_u8(rl, vqtbl1q_u8(tbl_l[2], vandq_u8(vh, loset)));
-      rh = veorq_u8(rh, vqtbl1q_u8(tbl_h[2], vandq_u8(vh, loset)));
-
-      vl = vshrq_n_u8(vl, 4);
-      vh = vshrq_n_u8(vh, 4);
-
-      rl = veorq_u8(rl, vqtbl1q_u8(tbl_l[1], vl));
-      rh = veorq_u8(rh, vqtbl1q_u8(tbl_h[1], vl));
-      rl = veorq_u8(rl, vqtbl1q_u8(tbl_l[3], vh));
-      rh = veorq_u8(rh, vqtbl1q_u8(tbl_h[3], vh));
-
-      if (xor) {
-          vh = vld1q_u8(dst);
-          vl = vld1q_u8(dst + 16);
-          rh = veorq_u8(rh, vh);
-          rl = veorq_u8(rl, vl);
-      }
-      vst1q_u8(dst, rh);
-      vst1q_u8(dst + 16, rl);
-
-      src += 32;
-      dst += 32;
-  }
-}
-
-#else /* ARCH_AARCH64 */
-
-static
-inline
-void
-neon_w16_split_4_multiply_region(gf_t *gf, uint16_t *src, uint16_t *dst,
-                                 uint16_t *d_end, uint8_t *tbl,
-                                 gf_val_32_t val, int xor)
-{
-  unsigned i;
-  uint8_t *high = tbl + 4 * 16;
-  uint16x8_t va, r;
-  uint8x8_t loset, vb, vc, rl, rh;
-
-  uint8x8x2_t tbl_h[4], tbl_l[4];
-  for (i = 0; i < 4; i++) {
-      tbl_l[i].val[0] = vld1_u8(tbl + i*16);
-      tbl_l[i].val[1] = vld1_u8(tbl + i*16 + 8);
-      tbl_h[i].val[0] = vld1_u8(high + i*16);
-      tbl_h[i].val[1] = vld1_u8(high + i*16 + 8);
-  }
-
-  loset = vdup_n_u8(0xf);
-
-  while (dst < d_end) {
-      va = vld1q_u16(src);
-
-      vb = vmovn_u16(va);
-      vc = vshrn_n_u16(va, 8);
-
-      rl = vtbl2_u8(tbl_l[0], vand_u8(vb, loset));
-      rh = vtbl2_u8(tbl_h[0], vand_u8(vb, loset));
-      vb = vshr_n_u8(vb, 4);
-      rl = veor_u8(rl, vtbl2_u8(tbl_l[2], vand_u8(vc, loset)));
-      rh = veor_u8(rh, vtbl2_u8(tbl_h[2], vand_u8(vc, loset)));
-      vc = vshr_n_u8(vc, 4);
-      rl = veor_u8(rl, vtbl2_u8(tbl_l[1], vb));
-      rh = veor_u8(rh, vtbl2_u8(tbl_h[1], vb));
-      rl = veor_u8(rl, vtbl2_u8(tbl_l[3], vc));
-      rh = veor_u8(rh, vtbl2_u8(tbl_h[3], vc));
-
-      r  = vmovl_u8(rl);
-      r  = vorrq_u16(r, vshll_n_u8(rh, 8));
-
-      if (xor) {
-          va = vld1q_u16(dst);
-          r = veorq_u16(r, va);
-      }
-      vst1q_u16(dst, r);
-
-      src += 8;
-      dst += 8;
-  }
-}
-
-static
-inline
-void
-neon_w16_split_4_altmap_multiply_region(gf_t *gf, uint8_t *src,
-                                        uint8_t *dst, uint8_t *d_end,
-                                        uint8_t *tbl, gf_val_32_t val,
-                                        int xor)
-{
-  unsigned i;
-  uint8_t *high = tbl + 4 * 16;
-  uint8x8_t vh0, vh1, vl0, vl1, r0, r1, r2, r3;
-  uint8x8_t loset;
-
-  uint8x8x2_t tbl_h[4], tbl_l[4];
-  for (i = 0; i < 4; i++) {
-      tbl_l[i].val[0] = vld1_u8(tbl + i*16);
-      tbl_l[i].val[1] = vld1_u8(tbl + i*16 + 8);
-      tbl_h[i].val[0] = vld1_u8(high + i*16);
-      tbl_h[i].val[1] = vld1_u8(high + i*16 + 8);
-  }
-
-  loset = vdup_n_u8(0xf);
-
-  while (dst < d_end) {
-      vh0 = vld1_u8(src);
-      vh1 = vld1_u8(src + 8);
-      vl0 = vld1_u8(src + 16);
-      vl1 = vld1_u8(src + 24);
-
-      r0 = vtbl2_u8(tbl_l[0], vand_u8(vh0, loset));
-      r1 = vtbl2_u8(tbl_h[0], vand_u8(vh1, loset));
-      r2 = vtbl2_u8(tbl_l[2], vand_u8(vl0, loset));
-      r3 = vtbl2_u8(tbl_h[2], vand_u8(vl1, loset));
-
-      vh0 = vshr_n_u8(vh0, 4);
-      vh1 = vshr_n_u8(vh1, 4);
-      vl0 = vshr_n_u8(vl0, 4);
-      vl1 = vshr_n_u8(vl1, 4);
-
-      r0 = veor_u8(r0, vtbl2_u8(tbl_l[1], vh0));
-      r1 = veor_u8(r1, vtbl2_u8(tbl_h[1], vh1));
-      r2 = veor_u8(r2, vtbl2_u8(tbl_l[3], vl0));
-      r3 = veor_u8(r3, vtbl2_u8(tbl_h[3], vl1));
-
-      if (xor) {
-          vh0 = vld1_u8(dst);
-          vh1 = vld1_u8(dst + 8);
-          vl0 = vld1_u8(dst + 16);
-          vl1 = vld1_u8(dst + 24);
-          r0  = veor_u8(r0, vh0);
-          r1  = veor_u8(r1, vh1);
-          r2  = veor_u8(r2, vl0);
-          r3  = veor_u8(r3, vl1);
-      }
-      vst1_u8(dst,      r0);
-      vst1_u8(dst +  8, r1);
-      vst1_u8(dst + 16, r2);
-      vst1_u8(dst + 24, r3);
-
-      src += 32;
-      dst += 32;
-  }
-}
-#endif /* ARCH_AARCH64 */
-
-static
-inline
-void
-neon_w16_split_4_16_lazy_multiply_region(gf_t *gf, void *src, void *dest,
-                                         gf_val_32_t val, int bytes, int xor,
-                                         int altmap)
-{
-  gf_region_data rd;
-  unsigned i, j;
-  uint64_t c, prod;
-  uint8_t tbl[2 * 4 * 16];
-  uint8_t *high = tbl + 4 * 16;
-
-  if (val == 0) { gf_multby_zero(dest, bytes, xor); return; }
-  if (val == 1) { gf_multby_one(src, dest, bytes, xor); return; }
-
-  for (i = 0; i < 4; i++) {
-    for (j = 0; j < 16; j++) {
-      c = (j << (i*4));
-      prod = gf->multiply.w32(gf, c, val);
-      tbl[i*16 + j]  = prod & 0xff;
-      high[i*16 + j] = prod >> 8;
-    }
-  }
-
-  gf_set_region_data(&rd, gf, src, dest, bytes, val, xor, 32);
-  gf_do_initial_region_alignment(&rd);
-
-  if (altmap) {
-    uint8_t *s8   = rd.s_start;
-    uint8_t *d8   = rd.d_start;
-    uint8_t *end8 = rd.d_top;
-    if (xor)
-      neon_w16_split_4_altmap_multiply_region(gf, s8, d8, end8, tbl, val, 1);
-    else
-      neon_w16_split_4_altmap_multiply_region(gf, s8, d8, end8, tbl, val, 0);
-  } else {
-    uint16_t *s16   = rd.s_start;
-    uint16_t *d16   = rd.d_start;
-    uint16_t *end16 = rd.d_top;
-    if (xor)
-      neon_w16_split_4_multiply_region(gf, s16, d16, end16, tbl, val, 1);
-    else
-      neon_w16_split_4_multiply_region(gf, s16, d16, end16, tbl, val, 0);
-  }
-
-  gf_do_final_region_alignment(&rd);
-}
-
-static
-void
-gf_w16_split_4_16_lazy_multiply_region_neon(gf_t *gf, void *src, void *dest,
-                                            gf_val_32_t val, int bytes, int xor)
-{
-  neon_w16_split_4_16_lazy_multiply_region(gf, src, dest, val, bytes, xor, 0);
-}
-
-static
-void
-gf_w16_split_4_16_lazy_altmap_multiply_region_neon(gf_t *gf, void *src,
-                                                   void *dest,
-                                                   gf_val_32_t val, int bytes,
-                                                   int xor)
-{
-  neon_w16_split_4_16_lazy_multiply_region(gf, src, dest, val, bytes, xor, 1);
-}
-
-
-void gf_w16_neon_split_init(gf_t *gf)
-{
-  gf_internal_t *h = (gf_internal_t *) gf->scratch;
-
-  if (h->region_type & GF_REGION_ALTMAP)
-    gf->multiply_region.w32 = gf_w16_split_4_16_lazy_altmap_multiply_region_neon;
-  else
-    gf->multiply_region.w32 = gf_w16_split_4_16_lazy_multiply_region_neon;
-}
diff --git a/src/erasure-code/jerasure/gf-complete/src/neon/gf_w32_neon.c b/src/erasure-code/jerasure/gf-complete/src/neon/gf_w32_neon.c
deleted file mode 100644
index 8231eb3..0000000
--- a/src/erasure-code/jerasure/gf-complete/src/neon/gf_w32_neon.c
+++ /dev/null
@@ -1,269 +0,0 @@
-/*
- * GF-Complete: A Comprehensive Open Source Library for Galois Field Arithmetic
- * James S. Plank, Ethan L. Miller, Kevin M. Greenan,
- * Benjamin A. Arnold, John A. Burnum, Adam W. Disney, Allen C. McBride.
- *
- * Copyright (c) 2014: Janne Grunau <j at jannau.net>
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- *  - Redistributions of source code must retain the above copyright
- *     notice, this list of conditions and the following disclaimer.
- *
- *  - Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- *  - Neither the name of the University of Tennessee nor the names of its
- *    contributors may be used to endorse or promote products derived
- *    from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
- * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
- * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
- * WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- *
- * gf_w32_neon.c
- *
- * Neon routines for 32-bit Galois fields
- *
- */
-
-
-#include "gf_int.h"
-#include <stdio.h>
-#include <stdlib.h>
-#include "gf_w32.h"
-
-#ifndef ARCH_AARCH64
-#define vqtbl1q_u8(tbl, v) vcombine_u8(vtbl2_u8(tbl, vget_low_u8(v)),   \
-                                       vtbl2_u8(tbl, vget_high_u8(v)))
-#endif
-
-static
-void
-neon_w32_split_4_32_multiply_region(gf_t *gf, uint32_t *src, uint32_t *dst,
-                                    uint32_t *d_end, uint8_t btable[8][4][16],
-                                    uint32_t val, int xor, int altmap)
-{
-  int i, j;
-#ifdef ARCH_AARCH64
-  uint8x16_t tables[8][4];
-#else
-  uint8x8x2_t tables[8][4];
-#endif
-  uint32x4_t v0, v1, v2, v3, s0, s1, s2, s3;
-  uint8x16_t p0, p1, p2, p3, si, mask1;
-  uint16x8x2_t r0, r1;
-  uint8x16x2_t q0, q1;
-
-  for (i = 0; i < 8; i++) {
-    for (j = 0; j < 4; j++) {
-#ifdef ARCH_AARCH64
-      tables[i][j] = vld1q_u8(btable[i][j]);
-#else
-      tables[i][j].val[0] = vld1_u8(btable[i][j]);
-      tables[i][j].val[1] = vld1_u8(btable[i][j] + 8);
-#endif
-    }
-  }
-
-  mask1 = vdupq_n_u8(0xf);
-
-  while (dst < d_end) {
-
-      v0 = vld1q_u32(src); src += 4;
-      v1 = vld1q_u32(src); src += 4;
-      v2 = vld1q_u32(src); src += 4;
-      v3 = vld1q_u32(src); src += 4;
-
-      if (altmap) {
-          q0.val[0] = vreinterpretq_u8_u32(v0);
-          q0.val[1] = vreinterpretq_u8_u32(v1);
-          q1.val[0] = vreinterpretq_u8_u32(v2);
-          q1.val[1] = vreinterpretq_u8_u32(v3);
-      } else {
-          r0 = vtrnq_u16(vreinterpretq_u16_u32(v0), vreinterpretq_u16_u32(v2));
-          r1 = vtrnq_u16(vreinterpretq_u16_u32(v1), vreinterpretq_u16_u32(v3));
-
-          q0 = vtrnq_u8(vreinterpretq_u8_u16(r0.val[0]),
-                        vreinterpretq_u8_u16(r1.val[0]));
-          q1 = vtrnq_u8(vreinterpretq_u8_u16(r0.val[1]),
-                        vreinterpretq_u8_u16(r1.val[1]));
-      }
-
-      si = vandq_u8(q0.val[0], mask1);
-      p0 = vqtbl1q_u8(tables[0][0], si);
-      p1 = vqtbl1q_u8(tables[0][1], si);
-      p2 = vqtbl1q_u8(tables[0][2], si);
-      p3 = vqtbl1q_u8(tables[0][3], si);
-
-      si = vshrq_n_u8(q0.val[0], 4);
-      p0 = veorq_u8(p0, vqtbl1q_u8(tables[1][0], si));
-      p1 = veorq_u8(p1, vqtbl1q_u8(tables[1][1], si));
-      p2 = veorq_u8(p2, vqtbl1q_u8(tables[1][2], si));
-      p3 = veorq_u8(p3, vqtbl1q_u8(tables[1][3], si));
-
-      si = vandq_u8(q0.val[1], mask1);
-      p0 = veorq_u8(p0, vqtbl1q_u8(tables[2][0], si));
-      p1 = veorq_u8(p1, vqtbl1q_u8(tables[2][1], si));
-      p2 = veorq_u8(p2, vqtbl1q_u8(tables[2][2], si));
-      p3 = veorq_u8(p3, vqtbl1q_u8(tables[2][3], si));
-
-      si = vshrq_n_u8(q0.val[1], 4);
-      p0 = veorq_u8(p0, vqtbl1q_u8(tables[3][0], si));
-      p1 = veorq_u8(p1, vqtbl1q_u8(tables[3][1], si));
-      p2 = veorq_u8(p2, vqtbl1q_u8(tables[3][2], si));
-      p3 = veorq_u8(p3, vqtbl1q_u8(tables[3][3], si));
-
-      si = vandq_u8(q1.val[0], mask1);
-      p0 = veorq_u8(p0, vqtbl1q_u8(tables[4][0], si));
-      p1 = veorq_u8(p1, vqtbl1q_u8(tables[4][1], si));
-      p2 = veorq_u8(p2, vqtbl1q_u8(tables[4][2], si));
-      p3 = veorq_u8(p3, vqtbl1q_u8(tables[4][3], si));
-
-      si = vshrq_n_u8(q1.val[0], 4);
-      p0 = veorq_u8(p0, vqtbl1q_u8(tables[5][0], si));
-      p1 = veorq_u8(p1, vqtbl1q_u8(tables[5][1], si));
-      p2 = veorq_u8(p2, vqtbl1q_u8(tables[5][2], si));
-      p3 = veorq_u8(p3, vqtbl1q_u8(tables[5][3], si));
-
-      si = vandq_u8(q1.val[1], mask1);
-      p0 = veorq_u8(p0, vqtbl1q_u8(tables[6][0], si));
-      p1 = veorq_u8(p1, vqtbl1q_u8(tables[6][1], si));
-      p2 = veorq_u8(p2, vqtbl1q_u8(tables[6][2], si));
-      p3 = veorq_u8(p3, vqtbl1q_u8(tables[6][3], si));
-
-      si = vshrq_n_u8(q1.val[1], 4);
-      p0 = veorq_u8(p0, vqtbl1q_u8(tables[7][0], si));
-      p1 = veorq_u8(p1, vqtbl1q_u8(tables[7][1], si));
-      p2 = veorq_u8(p2, vqtbl1q_u8(tables[7][2], si));
-      p3 = veorq_u8(p3, vqtbl1q_u8(tables[7][3], si));
-
-      if (altmap) {
-          s0 = vreinterpretq_u32_u8(p0);
-          s1 = vreinterpretq_u32_u8(p1);
-          s2 = vreinterpretq_u32_u8(p2);
-          s3 = vreinterpretq_u32_u8(p3);
-      } else {
-          q0 = vtrnq_u8(p0, p1);
-          q1 = vtrnq_u8(p2, p3);
-
-          r0 = vtrnq_u16(vreinterpretq_u16_u8(q0.val[0]),
-                         vreinterpretq_u16_u8(q1.val[0]));
-          r1 = vtrnq_u16(vreinterpretq_u16_u8(q0.val[1]),
-                         vreinterpretq_u16_u8(q1.val[1]));
-
-          s0 = vreinterpretq_u32_u16(r0.val[0]);
-          s1 = vreinterpretq_u32_u16(r1.val[0]);
-          s2 = vreinterpretq_u32_u16(r0.val[1]);
-          s3 = vreinterpretq_u32_u16(r1.val[1]);
-      }
-
-      if (xor) {
-          v0 = vld1q_u32(dst);
-          v1 = vld1q_u32(dst + 4);
-          v2 = vld1q_u32(dst + 8);
-          v3 = vld1q_u32(dst + 12);
-          s0 = veorq_u32(s0, v0);
-          s1 = veorq_u32(s1, v1);
-          s2 = veorq_u32(s2, v2);
-          s3 = veorq_u32(s3, v3);
-      }
-
-      vst1q_u32(dst,      s0);
-      vst1q_u32(dst + 4,  s1);
-      vst1q_u32(dst + 8,  s2);
-      vst1q_u32(dst + 12, s3);
-
-      dst += 16;
-  }
-}
-
-static
-inline
-void
-neon_w32_split_4_32_lazy_multiply_region(gf_t *gf, void *src, void *dest, uint32_t val, int bytes, int xor, int altmap)
-{
-  gf_internal_t *h;
-  int i, j, k;
-  uint32_t pp, v, *s32, *d32, *top, tmp_table[16];
-  uint8_t btable[8][4][16];
-  gf_region_data rd;
-
-  if (val == 0) { gf_multby_zero(dest, bytes, xor); return; }
-  if (val == 1) { gf_multby_one(src, dest, bytes, xor); return; }
-
-  h = (gf_internal_t *) gf->scratch;
-  pp = h->prim_poly;
-
-  gf_set_region_data(&rd, gf, src, dest, bytes, val, xor, 64);
-  gf_do_initial_region_alignment(&rd);
-
-  s32 = (uint32_t *) rd.s_start;
-  d32 = (uint32_t *) rd.d_start;
-  top = (uint32_t *) rd.d_top;
-
-  v = val;
-  for (i = 0; i < 8; i++) {
-    tmp_table[0] = 0;
-    for (j = 1; j < 16; j <<= 1) {
-      for (k = 0; k < j; k++) {
-        tmp_table[k^j] = (v ^ tmp_table[k]);
-      }
-      v = (v & GF_FIRST_BIT) ? ((v << 1) ^ pp) : (v << 1);
-    }
-    for (j = 0; j < 4; j++) {
-      for (k = 0; k < 16; k++) {
-        btable[i][j][k] = (uint8_t) tmp_table[k];
-        tmp_table[k] >>= 8;
-      }
-    }
-  }
-
-  if (xor)
-    neon_w32_split_4_32_multiply_region(gf, s32, d32, top, btable, val, 1, altmap);
-  else
-    neon_w32_split_4_32_multiply_region(gf, s32, d32, top, btable, val, 0, altmap);
-
-  gf_do_final_region_alignment(&rd);
-}
-
-static
-void
-gf_w32_split_4_32_lazy_multiply_region_neon(gf_t *gf, void *src, void *dest,
-                                            gf_val_32_t val, int bytes, int xor)
-{
-  neon_w32_split_4_32_lazy_multiply_region(gf, src, dest, val, bytes, xor, 0);
-}
-
-static
-void
-gf_w32_split_4_32_lazy_altmap_multiply_region_neon(gf_t *gf, void *src,
-                                                   void *dest, gf_val_32_t val,
-                                                   int bytes, int xor)
-{
-  neon_w32_split_4_32_lazy_multiply_region(gf, src, dest, val, bytes, xor, 1);
-}
-
-void gf_w32_neon_split_init(gf_t *gf)
-{
-  gf_internal_t *h = (gf_internal_t *) gf->scratch;
-
-  if (h->region_type & GF_REGION_ALTMAP)
-      gf->multiply_region.w32 = gf_w32_split_4_32_lazy_altmap_multiply_region_neon;
-  else
-      gf->multiply_region.w32 = gf_w32_split_4_32_lazy_multiply_region_neon;
-
-}
diff --git a/src/erasure-code/jerasure/gf-complete/src/neon/gf_w4_neon.c b/src/erasure-code/jerasure/gf-complete/src/neon/gf_w4_neon.c
deleted file mode 100644
index 3a21432..0000000
--- a/src/erasure-code/jerasure/gf-complete/src/neon/gf_w4_neon.c
+++ /dev/null
@@ -1,247 +0,0 @@
-/*
- * GF-Complete: A Comprehensive Open Source Library for Galois Field Arithmetic
- * James S. Plank, Ethan L. Miller, Kevin M. Greenan,
- * Benjamin A. Arnold, John A. Burnum, Adam W. Disney, Allen C. McBride.
- *
- * Copyright (c) 2014: Janne Grunau <j at jannau.net>
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- *  - Redistributions of source code must retain the above copyright
- *     notice, this list of conditions and the following disclaimer.
- *
- *  - Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- *  - Neither the name of the University of Tennessee nor the names of its
- *    contributors may be used to endorse or promote products derived
- *    from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
- * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
- * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
- * WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- *
- * gf_w4_neon.c
- *
- * Neon routines for 4-bit Galois fields
- *
- */
-
-#include "gf_int.h"
-#include <stdio.h>
-#include <stdlib.h>
-#include "gf_w4.h"
-
-static
-gf_val_32_t
-gf_w4_neon_clm_multiply (gf_t *gf, gf_val_32_t a4, gf_val_32_t b4)
-{
-  gf_val_32_t rv = 0;
-  poly8x8_t       result, prim_poly;
-  poly8x8_t       a, b, w;
-  uint8x8_t       v;
-  gf_internal_t * h = gf->scratch;
-
-  a =  vdup_n_p8 (a4);
-  b =  vdup_n_p8 (b4);
-
-  prim_poly = vdup_n_p8 ((uint32_t)(h->prim_poly & 0x1fULL));
-
-  /* Do the initial multiply */
-  result = vmul_p8 (a, b);
-  v = vshr_n_u8 (vreinterpret_u8_p8(result), 4);
-  w = vmul_p8 (prim_poly, vreinterpret_p8_u8(v));
-  result = vreinterpret_p8_u8 (veor_u8 (vreinterpret_u8_p8(result), vreinterpret_u8_p8(w)));
-
-  /* Extracts 32 bit value from result. */
-  rv = (gf_val_32_t)vget_lane_u8 (vreinterpret_u8_p8 (result), 0);
-
-  return rv;
-}
-
-static inline void
-neon_clm_multiply_region_from_single (gf_t *gf, uint8_t *s8, uint8_t *d8,
-                                      gf_val_32_t val, uint8_t *d_end, int xor)
-{
-  gf_internal_t * h = gf->scratch;
-  poly8x8_t       prim_poly;
-  poly8x8_t       a, w, even, odd;
-  uint8x8_t       b, c, v, mask;
-
-  a         = vdup_n_p8 (val);
-  mask      = vdup_n_u8 (0xf);
-  prim_poly = vdup_n_p8 ((uint8_t)(h->prim_poly & 0x1fULL));
-
-  while (d8 < d_end) {
-    b = vld1_u8 (s8);
-
-    even = vreinterpret_p8_u8 (vand_u8 (b, mask));
-    odd  = vreinterpret_p8_u8 (vshr_n_u8 (b, 4));
-
-    if (xor)
-        c = vld1_u8 (d8);
-
-    even = vmul_p8 (a, even);
-    odd  = vmul_p8 (a, odd);
-
-    v = vshr_n_u8 (vreinterpret_u8_p8(even), 4);
-    w = vmul_p8 (prim_poly, vreinterpret_p8_u8(v));
-    even = vreinterpret_p8_u8 (veor_u8 (vreinterpret_u8_p8(even), vreinterpret_u8_p8(w)));
-
-    v = vshr_n_u8 (vreinterpret_u8_p8(odd), 4);
-    w = vmul_p8 (prim_poly, vreinterpret_p8_u8(v));
-    odd = vreinterpret_p8_u8 (veor_u8 (vreinterpret_u8_p8(odd), vreinterpret_u8_p8(w)));
-
-    v = veor_u8 (vreinterpret_u8_p8 (even), vshl_n_u8 (vreinterpret_u8_p8 (odd), 4));
-
-    if (xor)
-      v = veor_u8 (c, v);
-
-    vst1_u8 (d8, v);
-
-    d8 += 8;
-    s8 += 8;
-  }
-}
-
-
-static void
-gf_w4_neon_clm_multiply_region_from_single (gf_t *gf, void *src, void *dest,
-                                            gf_val_32_t val, int bytes, int xor)
-{
-  gf_region_data rd;
-  uint8_t *s8;
-  uint8_t *d8;
-
-  if (val == 0) { gf_multby_zero(dest, bytes, xor); return; }
-  if (val == 1) { gf_multby_one(src, dest, bytes, xor); return; }
-
-  gf_set_region_data(&rd, gf, src, dest, bytes, val, xor, 16);
-  gf_do_initial_region_alignment(&rd);
-
-  s8 = (uint8_t *) rd.s_start;
-  d8 = (uint8_t *) rd.d_start;
-
-  if (xor)
-    neon_clm_multiply_region_from_single (gf, s8, d8, val, rd.d_top, 1);
-  else
-    neon_clm_multiply_region_from_single (gf, s8, d8, val, rd.d_top, 0);
-
-  gf_do_final_region_alignment(&rd);
-}
-
-#ifndef ARCH_AARCH64
-#define vqtbl1q_u8(tbl, v) vcombine_u8(vtbl2_u8(tbl, vget_low_u8(v)),   \
-                                       vtbl2_u8(tbl, vget_high_u8(v)))
-#endif
-
-static
-inline
-void
-w4_single_table_multiply_region_neon(gf_t *gf, uint8_t *src, uint8_t *dst,
-                                     uint8_t * d_end, gf_val_32_t val, int xor)
-{
-  struct gf_single_table_data *std;
-  uint8_t *base;
-  uint8x16_t r, va, vh, vl, loset;
-
-#ifdef ARCH_AARCH64
-  uint8x16_t th, tl;
-#else
-  uint8x8x2_t th, tl;
-#endif
-
-  std = (struct gf_single_table_data *) ((gf_internal_t *) (gf->scratch))->private;
-  base = (uint8_t *) std->mult;
-  base += (val << GF_FIELD_WIDTH);
-
-#ifdef ARCH_AARCH64
-  tl = vld1q_u8 (base);
-  th = vshlq_n_u8 (tl, 4);
-#else
-  tl.val[0] = vld1_u8 (base);
-  tl.val[1] = vld1_u8 (base + 8);
-  th.val[0] =  vshl_n_u8 (tl.val[0], 4);
-  th.val[1] =  vshl_n_u8 (tl.val[1], 4);
-#endif
-
-  loset = vdupq_n_u8(0xf);
-
-  while (dst < d_end) {
-      va = vld1q_u8 (src);
-
-      vh = vshrq_n_u8 (va, 4);
-      vl = vandq_u8 (va, loset);
-
-      if (xor)
-        va = vld1q_u8 (dst);
-
-      vh = vqtbl1q_u8 (th, vh);
-      vl = vqtbl1q_u8 (tl, vl);
-
-      r = veorq_u8 (vh, vl);
-
-      if (xor)
-        r = veorq_u8 (va, r);
-
-      vst1q_u8 (dst, r);
-
-    dst += 16;
-    src += 16;
-  }
-}
-
-static
-void
-gf_w4_single_table_multiply_region_neon(gf_t *gf, void *src, void *dest,
-                                        gf_val_32_t val, int bytes, int xor)
-{
-  gf_region_data rd;
-  uint8_t *sptr, *dptr, *top;
-
-  if (val == 0) { gf_multby_zero(dest, bytes, xor); return; }
-  if (val == 1) { gf_multby_one(src, dest, bytes, xor); return; }
-
-  gf_set_region_data(&rd, gf, src, dest, bytes, val, xor, 16);
-  gf_do_initial_region_alignment(&rd);
-
-  sptr = rd.s_start;
-  dptr = rd.d_start;
-  top  = rd.d_top;
-
-  if (xor)
-      w4_single_table_multiply_region_neon(gf, sptr, dptr, top, val, 1);
-  else
-      w4_single_table_multiply_region_neon(gf, sptr, dptr, top, val, 0);
-
-  gf_do_final_region_alignment(&rd);
-
-}
-
-
-int gf_w4_neon_cfm_init(gf_t *gf)
-{
-  // single clm multiplication probably pointless
-  gf->multiply.w32 = gf_w4_neon_clm_multiply;
-  gf->multiply_region.w32 = gf_w4_neon_clm_multiply_region_from_single;
-
-  return 1;
-}
-
-void gf_w4_neon_single_table_init(gf_t *gf)
-{
-  gf->multiply_region.w32 = gf_w4_single_table_multiply_region_neon;
-}
diff --git a/src/erasure-code/jerasure/gf-complete/src/neon/gf_w64_neon.c b/src/erasure-code/jerasure/gf-complete/src/neon/gf_w64_neon.c
deleted file mode 100644
index 0eca9c7..0000000
--- a/src/erasure-code/jerasure/gf-complete/src/neon/gf_w64_neon.c
+++ /dev/null
@@ -1,333 +0,0 @@
-/*
- * GF-Complete: A Comprehensive Open Source Library for Galois Field Arithmetic
- * James S. Plank, Ethan L. Miller, Kevin M. Greenan,
- * Benjamin A. Arnold, John A. Burnum, Adam W. Disney, Allen C. McBride.
- *
- * Copyright (c) 2014: Janne Grunau <j at jannau.net>
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- *  - Redistributions of source code must retain the above copyright
- *     notice, this list of conditions and the following disclaimer.
- *
- *  - Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- *  - Neither the name of the University of Tennessee nor the names of its
- *    contributors may be used to endorse or promote products derived
- *    from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
- * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
- * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
- * WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- *
- * gf_w64_neon.c
- *
- * Neon routines for 64-bit Galois fields
- *
- */
-
-#include "gf_int.h"
-#include <stdio.h>
-#include <stdlib.h>
-#include "gf_w64.h"
-
-
-#ifndef ARCH_AARCH64
-#define vqtbl1q_u8(tbl, v) vcombine_u8(vtbl2_u8(tbl, vget_low_u8(v)),   \
-                                       vtbl2_u8(tbl, vget_high_u8(v)))
-#endif
-
-static
-inline
-void
-neon_w64_split_4_lazy_altmap_multiply_region(gf_t *gf, uint64_t *src,
-                                             uint64_t *dst, uint64_t *d_end,
-                                             uint64_t val, int xor)
-{
-  unsigned i, j, k;
-  uint8_t btable[16];
-#ifdef ARCH_AARCH64
-  uint8x16_t tables[16][8];
-#else
-  uint8x8x2_t tables[16][8];
-#endif
-  uint8x16_t p[8], mask1, si;
-
-  gf_internal_t *h = (gf_internal_t *) gf->scratch;
-  struct gf_split_4_64_lazy_data *ld = (struct gf_split_4_64_lazy_data *) h->private;
-
-  for (i = 0; i < 16; i++) {
-    for (j = 0; j < 8; j++) {
-      for (k = 0; k < 16; k++) {
-        btable[k] = (uint8_t) ld->tables[i][k];
-        ld->tables[i][k] >>= 8;
-      }
-#ifdef ARCH_AARCH64
-      tables[i][j] = vld1q_u8(btable);
-#else
-      tables[i][j].val[0] = vld1_u8(btable);
-      tables[i][j].val[1] = vld1_u8(btable + 8);
-#endif
-    }
-  }
-
-  mask1 = vdupq_n_u8(0xf);
-
-  while (dst < d_end) {
-
-    if (xor) {
-      for (i = 0; i < 8; i++)
-        p[i] = vld1q_u8((uint8_t *) (dst + i * 2));
-    } else {
-      for (i = 0; i < 8; i++)
-        p[i] = vdupq_n_u8(0);
-    }
-
-    i = 0;
-    for (k = 0; k < 8; k++) {
-      uint8x16_t v0 = vld1q_u8((uint8_t *) src);
-      src += 2;
-
-      si = vandq_u8(v0, mask1);
-      for (j = 0; j < 8; j++) {
-        p[j] = veorq_u8(p[j], vqtbl1q_u8(tables[i][j], si));
-      }
-      i++;
-      si = vshrq_n_u8(v0, 4);
-      for (j = 0; j < 8; j++) {
-        p[j] = veorq_u8(p[j], vqtbl1q_u8(tables[i][j], si));
-      }
-      i++;
-
-    }
-    for (i = 0; i < 8; i++) {
-      vst1q_u8((uint8_t *) dst, p[i]);
-      dst += 2;
-    }
-  }
-}
-
-static
-inline
-void
-neon_w64_split_4_lazy_multiply_region(gf_t *gf, uint64_t *src, uint64_t *dst,
-                                      uint64_t *d_end, uint64_t val, int xor)
-{
-  unsigned i, j, k;
-  uint8_t btable[16];
-#ifdef ARCH_AARCH64
-  uint8x16_t tables[16][8];
-#else
-  uint8x8x2_t tables[16][8];
-#endif
-  uint8x16_t p[8], mask1, si;
-  uint64x2_t st[8];
-  uint32x4x2_t s32[4];
-  uint16x8x2_t s16[4];
-  uint8x16x2_t s8[4];
-
-  gf_internal_t *h = (gf_internal_t *) gf->scratch;
-  struct gf_split_4_64_lazy_data *ld = (struct gf_split_4_64_lazy_data *) h->private;
-
-  for (i = 0; i < 16; i++) {
-    for (j = 0; j < 8; j++) {
-      for (k = 0; k < 16; k++) {
-        btable[k] = (uint8_t) ld->tables[i][k];
-        ld->tables[i][k] >>= 8;
-      }
-#ifdef ARCH_AARCH64
-      tables[i][j] = vld1q_u8(btable);
-#else
-      tables[i][j].val[0] = vld1_u8(btable);
-      tables[i][j].val[1] = vld1_u8(btable + 8);
-#endif
-    }
-  }
-
-  mask1 = vdupq_n_u8(0xf);
-
-  while (dst < d_end) {
-
-    for (k = 0; k < 8; k++) {
-      st[k]  = vld1q_u64(src);
-      src += 2;
-      p[k] = vdupq_n_u8(0);
-    }
-
-    s32[0] = vuzpq_u32(vreinterpretq_u32_u64(st[0]),
-                       vreinterpretq_u32_u64(st[1]));
-    s32[1] = vuzpq_u32(vreinterpretq_u32_u64(st[2]),
-                       vreinterpretq_u32_u64(st[3]));
-    s32[2] = vuzpq_u32(vreinterpretq_u32_u64(st[4]),
-                       vreinterpretq_u32_u64(st[5]));
-    s32[3] = vuzpq_u32(vreinterpretq_u32_u64(st[6]),
-                       vreinterpretq_u32_u64(st[7]));
-
-    s16[0] = vuzpq_u16(vreinterpretq_u16_u32(s32[0].val[0]),
-                       vreinterpretq_u16_u32(s32[1].val[0]));
-    s16[1] = vuzpq_u16(vreinterpretq_u16_u32(s32[2].val[0]),
-                       vreinterpretq_u16_u32(s32[3].val[0]));
-    s16[2] = vuzpq_u16(vreinterpretq_u16_u32(s32[0].val[1]),
-                       vreinterpretq_u16_u32(s32[1].val[1]));
-    s16[3] = vuzpq_u16(vreinterpretq_u16_u32(s32[2].val[1]),
-                       vreinterpretq_u16_u32(s32[3].val[1]));
-
-    s8[0]  = vuzpq_u8(vreinterpretq_u8_u16(s16[0].val[0]),
-                      vreinterpretq_u8_u16(s16[1].val[0]));
-    s8[1]  = vuzpq_u8(vreinterpretq_u8_u16(s16[0].val[1]),
-                      vreinterpretq_u8_u16(s16[1].val[1]));
-    s8[2]  = vuzpq_u8(vreinterpretq_u8_u16(s16[2].val[0]),
-                      vreinterpretq_u8_u16(s16[3].val[0]));
-    s8[3]  = vuzpq_u8(vreinterpretq_u8_u16(s16[2].val[1]),
-                      vreinterpretq_u8_u16(s16[3].val[1]));
-
-    i = 0;
-    for (k = 0; k < 8; k++) {
-      si = vandq_u8(s8[k >> 1].val[k & 1], mask1);
-      for (j = 0; j < 8; j++) {
-        p[j] = veorq_u8(p[j], vqtbl1q_u8(tables[i][j], si));
-      }
-      i++;
-      si = vshrq_n_u8(s8[k >> 1].val[k & 1], 4);
-      for (j = 0; j < 8; j++) {
-        p[j] = veorq_u8(p[j], vqtbl1q_u8(tables[i][j], si));
-      }
-      i++;
-    }
-
-    s8[0]  = vzipq_u8(p[0], p[1]);
-    s8[1]  = vzipq_u8(p[2], p[3]);
-    s8[2]  = vzipq_u8(p[4], p[5]);
-    s8[3]  = vzipq_u8(p[6], p[7]);
-
-    s16[0] = vzipq_u16(vreinterpretq_u16_u8(s8[0].val[0]),
-                       vreinterpretq_u16_u8(s8[1].val[0]));
-    s16[1] = vzipq_u16(vreinterpretq_u16_u8(s8[2].val[0]),
-                       vreinterpretq_u16_u8(s8[3].val[0]));
-    s16[2] = vzipq_u16(vreinterpretq_u16_u8(s8[0].val[1]),
-                       vreinterpretq_u16_u8(s8[1].val[1]));
-    s16[3] = vzipq_u16(vreinterpretq_u16_u8(s8[2].val[1]),
-                       vreinterpretq_u16_u8(s8[3].val[1]));
-
-    s32[0] = vzipq_u32(vreinterpretq_u32_u16(s16[0].val[0]),
-                       vreinterpretq_u32_u16(s16[1].val[0]));
-    s32[1] = vzipq_u32(vreinterpretq_u32_u16(s16[0].val[1]),
-                       vreinterpretq_u32_u16(s16[1].val[1]));
-    s32[2] = vzipq_u32(vreinterpretq_u32_u16(s16[2].val[0]),
-                       vreinterpretq_u32_u16(s16[3].val[0]));
-    s32[3] = vzipq_u32(vreinterpretq_u32_u16(s16[2].val[1]),
-                       vreinterpretq_u32_u16(s16[3].val[1]));
-
-    for (k = 0; k < 8; k ++) {
-        st[k] = vreinterpretq_u64_u32(s32[k >> 1].val[k & 1]);
-    }
-
-    if (xor) {
-      for (i = 0; i < 8; i++) {
-        uint64x2_t t1 = vld1q_u64(dst);
-        vst1q_u64(dst, veorq_u64(st[i], t1));
-        dst += 2;
-      }
-    } else {
-      for (i = 0; i < 8; i++) {
-        vst1q_u64(dst, st[i]);
-        dst += 2;
-      }
-    }
-
-  }
-}
-
-static
-void
-gf_w64_neon_split_4_lazy_multiply_region(gf_t *gf, void *src, void *dest,
-                                         uint64_t val, int bytes, int xor,
-                                         int altmap)
-{
-  gf_internal_t *h;
-  int i, j, k;
-  uint64_t pp, v, *s64, *d64, *top;
-  struct gf_split_4_64_lazy_data *ld;
-  gf_region_data rd;
-
-  if (val == 0) { gf_multby_zero(dest, bytes, xor); return; }
-  if (val == 1) { gf_multby_one(src, dest, bytes, xor); return; }
-
-  gf_set_region_data(&rd, gf, src, dest, bytes, val, xor, 128);
-  gf_do_initial_region_alignment(&rd);
-
-  s64 = (uint64_t *) rd.s_start;
-  d64 = (uint64_t *) rd.d_start;
-  top = (uint64_t *) rd.d_top;
-
-  h = (gf_internal_t *) gf->scratch;
-  pp = h->prim_poly;
-  ld = (struct gf_split_4_64_lazy_data *) h->private;
-
-  v = val;
-  for (i = 0; i < 16; i++) {
-    ld->tables[i][0] = 0;
-    for (j = 1; j < 16; j <<= 1) {
-      for (k = 0; k < j; k++) {
-        ld->tables[i][k^j] = (v ^ ld->tables[i][k]);
-      }
-      v = (v & GF_FIRST_BIT) ? ((v << 1) ^ pp) : (v << 1);
-    }
-  }
-
-  if (altmap) {
-    if (xor)
-      neon_w64_split_4_lazy_altmap_multiply_region(gf, s64, d64, top, val, 1);
-    else
-      neon_w64_split_4_lazy_altmap_multiply_region(gf, s64, d64, top, val, 0);
-  } else {
-    if (xor)
-      neon_w64_split_4_lazy_multiply_region(gf, s64, d64, top, val, 1);
-    else
-      neon_w64_split_4_lazy_multiply_region(gf, s64, d64, top, val, 0);
-  }
-
-  gf_do_final_region_alignment(&rd);
-}
-
-static
-void
-gf_w64_split_4_64_lazy_multiply_region_neon(gf_t *gf, void *src, void *dest,
-                                            uint64_t val, int bytes, int xor)
-{
-  gf_w64_neon_split_4_lazy_multiply_region(gf, src, dest, val, bytes, xor, 0);
-}
-
-static
-void
-gf_w64_split_4_64_lazy_altmap_multiply_region_neon(gf_t *gf, void *src,
-                                                   void *dest, uint64_t val,
-                                                   int bytes, int xor)
-{
-  gf_w64_neon_split_4_lazy_multiply_region(gf, src, dest, val, bytes, xor, 1);
-}
-
-void gf_w64_neon_split_init(gf_t *gf)
-{
-  gf_internal_t *h = (gf_internal_t *) gf->scratch;
-
-  if (h->region_type & GF_REGION_ALTMAP)
-      gf->multiply_region.w64 = gf_w64_split_4_64_lazy_altmap_multiply_region_neon;
-  else
-      gf->multiply_region.w64 = gf_w64_split_4_64_lazy_multiply_region_neon;
-
-}
diff --git a/src/erasure-code/jerasure/gf-complete/src/neon/gf_w8_neon.c b/src/erasure-code/jerasure/gf-complete/src/neon/gf_w8_neon.c
deleted file mode 100644
index 930a916..0000000
--- a/src/erasure-code/jerasure/gf-complete/src/neon/gf_w8_neon.c
+++ /dev/null
@@ -1,302 +0,0 @@
-/*
- * GF-Complete: A Comprehensive Open Source Library for Galois Field Arithmetic
- * James S. Plank, Ethan L. Miller, Kevin M. Greenan,
- * Benjamin A. Arnold, John A. Burnum, Adam W. Disney, Allen C. McBride.
- *
- * Copyright (c) 2014: Janne Grunau <j at jannau.net>
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- *  - Redistributions of source code must retain the above copyright
- *     notice, this list of conditions and the following disclaimer.
- *
- *  - Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- *  - Neither the name of the University of Tennessee nor the names of its
- *    contributors may be used to endorse or promote products derived
- *    from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
- * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
- * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
- * WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- *
- * gf_w8_neon.c
- *
- * Neon optimized routines for 8-bit Galois fields
- *
- */
-
-#include "gf_int.h"
-#include "gf_w8.h"
-#include <stdio.h>
-#include <stdlib.h>
-
-/* ARM NEON reducing macro for the carry free multiplication
- *   vmull_p8 is the carryless multiply operation. Here vshrn_n_u16 shifts
- *   the result to the right by 1 byte. This allows us to multiply
- *   the prim_poly by the leading bits of the result. We then xor the result
- *   of that operation back with the result. */
-#define NEON_CFM_REDUCE(v, w, result, prim_poly, initial)               \
-  do {								        \
-    if (initial)                                                        \
-      v = vshrn_n_u16 (vreinterpretq_u16_p16(result), 8);               \
-    else                                                                \
-      v = veor_u8 (v, vshrn_n_u16 (vreinterpretq_u16_p16(result), 8));  \
-    w = vmull_p8 (prim_poly, vreinterpret_p8_u8(v));                    \
-    result = vreinterpretq_p16_u16 (veorq_u16 (vreinterpretq_u16_p16(result), vreinterpretq_u16_p16(w))); \
-  } while (0)
-
-static
-inline
-gf_val_32_t
-gf_w8_neon_clm_multiply_x (gf_t *gf, gf_val_32_t a8, gf_val_32_t b8, int x)
-{
-  gf_val_32_t rv = 0;
-  poly8x8_t       a, b;
-  uint8x8_t       v;
-  poly16x8_t      result;
-  poly8x8_t       prim_poly;
-  poly16x8_t      w;
-  gf_internal_t * h = gf->scratch;
-
-  a =  vdup_n_p8 (a8);
-  b =  vdup_n_p8 (b8);
-
-  prim_poly = vdup_n_p8 ((uint32_t)(h->prim_poly & 0x1ffULL));
-
-  /* Do the initial multiply */
-  result = vmull_p8 (a, b);
-
-  /* Ben: Do prim_poly reduction twice. We are guaranteed that we will only
-     have to do the reduction at most twice, because (w-2)/z == 2. Where
-     z is equal to the number of zeros after the leading 1 */
-  NEON_CFM_REDUCE (v, w, result, prim_poly, 1);
-  NEON_CFM_REDUCE (v, w, result, prim_poly, 0);
-  if (x >= 3) {
-    NEON_CFM_REDUCE (v, w, result, prim_poly, 0);
-  }
-  if (x >= 4) {
-    NEON_CFM_REDUCE (v, w, result, prim_poly, 0);
-  }
-  /* Extracts 32 bit value from result. */
-  rv = (gf_val_32_t)vget_lane_u8 (vmovn_u16 (vreinterpretq_u16_p16 (result)), 0);
-
-  return rv;
-}
-
-#define CLM_MULTIPLY(x) \
-static gf_val_32_t gf_w8_neon_clm_multiply_ ## x (gf_t *gf, gf_val_32_t a8, gf_val_32_t b8) \
-{\
-    return gf_w8_neon_clm_multiply_x (gf, a8, b8, x);\
-}
-
-CLM_MULTIPLY(2)
-CLM_MULTIPLY(3)
-CLM_MULTIPLY(4)
-
-static inline void
-neon_clm_multiply_region_from_single_x(gf_t *gf, uint8_t *s8, uint8_t *d8,
-                                       gf_val_32_t val, uint8_t *d_end,
-                                       int xor, int x)
-{
-  gf_internal_t * h = gf->scratch;
-  poly8x8_t       a, b;
-  uint8x8_t       c, v;
-  poly16x8_t      result;
-  poly8x8_t       prim_poly;
-  poly16x8_t      w;
-
-  a         = vdup_n_p8 (val);
-  prim_poly = vdup_n_p8 ((uint8_t)(h->prim_poly & 0xffULL));
-
-  while (d8 < d_end) {
-    b = vld1_p8 ((poly8_t *) s8);
-
-    if (xor)
-        c = vld1_u8 (d8);
-
-    result = vmull_p8 (a, b);
-
-    NEON_CFM_REDUCE(v, w, result, prim_poly, 1);
-    NEON_CFM_REDUCE (v, w, result, prim_poly, 0);
-    if (x >= 3) {
-      NEON_CFM_REDUCE (v, w, result, prim_poly, 0);
-    }
-    if (x >= 4) {
-      NEON_CFM_REDUCE (v, w, result, prim_poly, 0);
-    }
-    v = vmovn_u16 (vreinterpretq_u16_p16 (result));
-    if (xor)
-      v = veor_u8 (c, v);
-
-    vst1_u8 (d8, v);
-
-    d8 += 8;
-    s8 += 8;
-  }
-}
-
-#define CLM_MULT_REGION(x)                                              \
-static void                                                             \
-gf_w8_neon_clm_multiply_region_from_single_ ## x (gf_t *gf, void *src,  \
-                                                  void *dest,           \
-                                                  gf_val_32_t val, int bytes, \
-                                                  int xor)              \
-{                                                                       \
-  gf_region_data rd;                                                    \
-  uint8_t *s8;                                                          \
-  uint8_t *d8;                                                          \
-                                                                        \
-  if (val == 0) { gf_multby_zero(dest, bytes, xor); return; }           \
-  if (val == 1) { gf_multby_one(src, dest, bytes, xor); return; }       \
-                                                                        \
-  gf_set_region_data(&rd, gf, src, dest, bytes, val, xor, 16);          \
-  gf_do_initial_region_alignment(&rd);                                  \
-  s8 = (uint8_t *) rd.s_start;                                          \
-  d8 = (uint8_t *) rd.d_start;                                          \
-                                                                        \
-  if (xor)                                                              \
-    neon_clm_multiply_region_from_single_x (gf, s8, d8, val, rd.d_top, 1, x); \
-  else                                                                  \
-    neon_clm_multiply_region_from_single_x (gf, s8, d8, val, rd.d_top, 0, x);\
-  gf_do_final_region_alignment(&rd);                                    \
-}
-
-CLM_MULT_REGION(2)
-CLM_MULT_REGION(3)
-CLM_MULT_REGION(4)
-
-
-int gf_w8_neon_cfm_init(gf_t *gf)
-{
-  gf_internal_t *h;
-
-  h = (gf_internal_t *) gf->scratch;
-
-  if ((0xe0 & h->prim_poly) == 0){
-    gf->multiply.w32 = gf_w8_neon_clm_multiply_2;
-    gf->multiply_region.w32 = gf_w8_neon_clm_multiply_region_from_single_2;
-  }else if ((0xc0 & h->prim_poly) == 0){
-    gf->multiply.w32 = gf_w8_neon_clm_multiply_3;
-    gf->multiply_region.w32 = gf_w8_neon_clm_multiply_region_from_single_3;
-  }else if ((0x80 & h->prim_poly) == 0){
-    gf->multiply.w32 = gf_w8_neon_clm_multiply_4;
-    gf->multiply_region.w32 = gf_w8_neon_clm_multiply_region_from_single_4;
-  }else{
-    return 0;
-  }
-  return 1;
-}
-
-#ifndef ARCH_AARCH64
-#define vqtbl1q_u8(tbl, v) vcombine_u8(vtbl2_u8(tbl, vget_low_u8(v)),   \
-                                       vtbl2_u8(tbl, vget_high_u8(v)))
-#endif
-
-static
-void
-gf_w8_split_multiply_region_neon(gf_t *gf, void *src, void *dest, gf_val_32_t val, int bytes, int xor)
-{
-  uint8_t *bh, *bl, *sptr, *dptr;
-  uint8x16_t r, va, vh, vl, loset;
-#ifdef ARCH_AARCH64
-  uint8x16_t mth, mtl;
-#else
-  uint8x8x2_t mth, mtl;
-#endif
-  struct gf_w8_half_table_data *htd;
-  gf_region_data rd;
-
-  if (val == 0) { gf_multby_zero(dest, bytes, xor); return; }
-  if (val == 1) { gf_multby_one(src, dest, bytes, xor); return; }
-
-  htd = (struct gf_w8_half_table_data *) ((gf_internal_t *) (gf->scratch))->private;
-
-  gf_set_region_data(&rd, gf, src, dest, bytes, val, xor, 16);
-  gf_do_initial_region_alignment(&rd);
-
-  bh = (uint8_t *) htd->high;
-  bh += (val << 4);
-  bl = (uint8_t *) htd->low;
-  bl += (val << 4);
-
-  sptr = rd.s_start;
-  dptr = rd.d_start;
-
-#ifdef ARCH_AARCH64
-  mth = vld1q_u8 (bh);
-  mtl = vld1q_u8 (bl);
-#else
-  mth.val[0] = vld1_u8 (bh);
-  mtl.val[0] = vld1_u8 (bl);
-  mth.val[1] = vld1_u8 (bh + 8);
-  mtl.val[1] = vld1_u8 (bl + 8);
-#endif
-
-  loset = vdupq_n_u8(0xf);
-
-  if (xor) {
-    while (sptr < (uint8_t *) rd.s_top) {
-      va = vld1q_u8 (sptr);
-
-      vh = vshrq_n_u8 (va, 4);
-      vl = vandq_u8 (va, loset);
-      va = vld1q_u8 (dptr);
-
-      vh = vqtbl1q_u8 (mth, vh);
-      vl = vqtbl1q_u8 (mtl, vl);
-
-      r = veorq_u8 (vh, vl);
-
-      vst1q_u8 (dptr, veorq_u8 (va, r));
-
-      dptr += 16;
-      sptr += 16;
-    }
-  } else {
-    while (sptr < (uint8_t *) rd.s_top) {
-      va = vld1q_u8 (sptr);
-
-      vh = vshrq_n_u8 (va, 4);
-      vl = vandq_u8 (va, loset);
-#ifdef ARCH_AARCH64
-      vh = vqtbl1q_u8 (mth, vh);
-      vl = vqtbl1q_u8 (mtl, vl);
-#else
-      vh = vcombine_u8 (vtbl2_u8 (mth, vget_low_u8 (vh)),
-			vtbl2_u8 (mth, vget_high_u8 (vh)));
-      vl = vcombine_u8 (vtbl2_u8 (mtl, vget_low_u8 (vl)),
-			vtbl2_u8 (mtl, vget_high_u8 (vl)));
-#endif
-
-      r = veorq_u8 (vh, vl);
-
-      vst1q_u8(dptr, r);
-
-      dptr += 16;
-      sptr += 16;
-    }
-  }
-
-  gf_do_final_region_alignment(&rd);
-}
-
-
-void gf_w8_neon_split_init(gf_t *gf)
-{
-  gf->multiply_region.w32 = gf_w8_split_multiply_region_neon;
-}
diff --git a/src/erasure-code/jerasure/jerasure/include/cauchy.h b/src/erasure-code/jerasure/jerasure/include/cauchy.h
deleted file mode 100644
index a4fad6b..0000000
--- a/src/erasure-code/jerasure/jerasure/include/cauchy.h
+++ /dev/null
@@ -1,45 +0,0 @@
-/* *
- * Copyright (c) 2013, James S. Plank and Kevin Greenan
- * All rights reserved.
- *
- * Jerasure - A C/C++ Library for a Variety of Reed-Solomon and RAID-6 Erasure
- * Coding Techniques
- *
- * Revision 2.0: Galois Field backend now links to GF-Complete
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- *  - Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *
- *  - Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- *  - Neither the name of the University of Tennessee nor the names of its
- *    contributors may be used to endorse or promote products derived
- *    from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
- * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
- * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
- * WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-
-extern int *cauchy_original_coding_matrix(int k, int m, int w);
-extern int *cauchy_xy_coding_matrix(int k, int m, int w, int *x, int *y);
-extern void cauchy_improve_coding_matrix(int k, int m, int w, int *matrix);
-extern int *cauchy_good_general_coding_matrix(int k, int m, int w);
-extern int cauchy_n_ones(int n, int w);
diff --git a/src/erasure-code/jerasure/jerasure/include/galois.h b/src/erasure-code/jerasure/jerasure/include/galois.h
deleted file mode 100644
index b57ef3c..0000000
--- a/src/erasure-code/jerasure/jerasure/include/galois.h
+++ /dev/null
@@ -1,100 +0,0 @@
-/* *
- * Copyright (c) 2013, James S. Plank and Kevin Greenan
- * All rights reserved.
- *
- * Jerasure - A C/C++ Library for a Variety of Reed-Solomon and RAID-6 Erasure
- * Coding Techniques
- *
- * Revision 2.0: Galois Field backend now links to GF-Complete
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- *  - Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *
- *  - Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- *  - Neither the name of the University of Tennessee nor the names of its
- *    contributors may be used to endorse or promote products derived
- *    from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
- * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
- * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
- * WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-
-#ifndef _GALOIS_H
-#define _GALOIS_H
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <gf_complete.h>
-
-extern int galois_init_default_field(int w);
-extern void galois_change_technique(gf_t *gf, int w);
-
-extern int galois_single_multiply(int a, int b, int w);
-extern int galois_single_divide(int a, int b, int w);
-extern int galois_inverse(int x, int w);
-
-void galois_region_xor(           char *src,         /* Source Region */
-                                  char *dest,        /* Dest Region (holds result) */
-                                  int nbytes);      /* Number of bytes in region */
-
-/* These multiply regions in w=8, w=16 and w=32.  They are much faster
-   than calling galois_single_multiply.  The regions must be long word aligned. */
-
-void galois_w08_region_multiply(char *region,       /* Region to multiply */
-                                  int multby,       /* Number to multiply by */
-                                  int nbytes,       /* Number of bytes in region */
-                                  char *r2,         /* If r2 != NULL, products go here.  
-                                                       Otherwise region is overwritten */
-                                  int add);         /* If (r2 != NULL && add) the produce is XOR'd with r2 */
-
-void galois_w16_region_multiply(char *region,       /* Region to multiply */
-                                  int multby,       /* Number to multiply by */
-                                  int nbytes,       /* Number of bytes in region */
-                                  char *r2,         /* If r2 != NULL, products go here.  
-                                                       Otherwise region is overwritten */
-                                  int add);         /* If (r2 != NULL && add) the produce is XOR'd with r2 */
-
-void galois_w32_region_multiply(char *region,       /* Region to multiply */
-                                  int multby,       /* Number to multiply by */
-                                  int nbytes,       /* Number of bytes in region */
-                                  char *r2,         /* If r2 != NULL, products go here.  
-                                                       Otherwise region is overwritten */
-                                  int add);         /* If (r2 != NULL && add) the produce is XOR'd with r2 */
-
-gf_t* galois_init_field(int w,
-                             int mult_type,
-                             int region_type,
-                             int divide_type,
-                             uint64_t prim_poly,
-                             int arg1,
-                             int arg2);
-
-gf_t* galois_init_composite_field(int w,
-                                int region_type,
-                                int divide_type,
-                                int degree,
-                                gf_t* base_gf);
-
-gf_t * galois_get_field_ptr(int w);
-
-
-#endif
diff --git a/src/erasure-code/jerasure/jerasure/include/jerasure.h b/src/erasure-code/jerasure/jerasure/include/jerasure.h
deleted file mode 100644
index 0836780..0000000
--- a/src/erasure-code/jerasure/jerasure/include/jerasure.h
+++ /dev/null
@@ -1,294 +0,0 @@
-/* *
- * Copyright (c) 2013, James S. Plank and Kevin Greenan
- * All rights reserved.
- *
- * Jerasure - A C/C++ Library for a Variety of Reed-Solomon and RAID-6 Erasure
- * Coding Techniques
- *
- * Revision 2.0: Galois Field backend now links to GF-Complete
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- *  - Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *
- *  - Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- *  - Neither the name of the University of Tennessee nor the names of its
- *    contributors may be used to endorse or promote products derived
- *    from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
- * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
- * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
- * WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-
-#ifndef _JERASURE_H
-#define _JERASURE_H
-
-/* This uses procedures from the Galois Field arithmetic library */
-
-#include "galois.h"
-
-/* ------------------------------------------------------------ */
-/* In all of the routines below:
-
-   k = Number of data devices
-   m = Number of coding devices
-   w = Word size
-
-   data_ptrs = An array of k pointers to data which is size bytes.  
-               Size must be a multiple of sizeof(long).
-               Pointers must also be longword aligned.
- 
-   coding_ptrs = An array of m pointers to coding data which is size bytes.
-
-   packetsize = The size of a coding block with bitmatrix coding. 
-                When you code with a bitmatrix, you will use w packets
-                of size packetsize.
-
-   matrix = an array of k*m integers.  
-            It represents an m by k matrix.
-            Element i,j is in matrix[i*k+j];
-
-   bitmatrix = an array of k*m*w*w integers.
-            It represents an mw by kw matrix.
-            Element i,j is in matrix[i*k*w+j];
-
-   erasures = an array of id's of erased devices. 
-              Id's are integers between 0 and k+m-1.
-              Id's 0 to k-1 are id's of data devices.
-              Id's k to k+m-1 are id's of coding devices: 
-                  Coding device id = id-k.
-              If there are e erasures, erasures[e] = -1.
-
-   schedule = an array of schedule operations.  
-
-              If there are m operations, then schedule[m][0] = -1.
-
-   operation = an array of 5 integers:
-
-          0 = operation: 0 for copy, 1 for xor (-1 for end)
-          1 = source device (0 - k+m-1)
-          2 = source packet (0 - w-1)
-          3 = destination device (0 - k+m-1)
-          4 = destination packet (0 - w-1)
- */
-
-/* ---------------------------------------------------------------  */
-/* Bitmatrices / schedules ---------------------------------------- */
-/*
- - jerasure_matrix_to_bitmatrix turns a m X k matrix in GF(2^w) into a
-                              wm X wk bitmatrix (in GF(2)).  This is
-                              explained in the Cauchy Reed-Solomon coding
-                              paper.
-
- - jerasure_dumb_bitmatrix_to_schedule turns a bitmatrix into a schedule 
-                              using the straightforward algorithm -- just
-                              schedule the dot products defined by each
-                              row of the matrix.
-
- - jerasure_smart_bitmatrix_to_schedule turns a bitmatrix into a schedule,
-                              but tries to use previous dot products to
-                              calculate new ones.  This is the optimization
-                              explained in the original Liberation code paper.
-
- - jerasure_generate_schedule_cache precalcalculate all the schedule for the
-                              given distribution bitmatrix.  M must equal 2.
- 
- - jerasure_free_schedule frees a schedule that was allocated with 
-                              jerasure_XXX_bitmatrix_to_schedule.
- 
- - jerasure_free_schedule_cache frees a schedule cache that was created with 
-                              jerasure_generate_schedule_cache.
- */
-
-int *jerasure_matrix_to_bitmatrix(int k, int m, int w, int *matrix);
-int **jerasure_dumb_bitmatrix_to_schedule(int k, int m, int w, int *bitmatrix);
-int **jerasure_smart_bitmatrix_to_schedule(int k, int m, int w, int *bitmatrix);
-int ***jerasure_generate_schedule_cache(int k, int m, int w, int *bitmatrix, int smart);
-
-void jerasure_free_schedule(int **schedule);
-void jerasure_free_schedule_cache(int k, int m, int ***cache);
-
-
-/* ------------------------------------------------------------ */
-/* Encoding - these are all straightforward.  jerasure_matrix_encode only 
-   works with w = 8|16|32.  */
-
-void jerasure_do_parity(int k, char **data_ptrs, char *parity_ptr, int size);
-
-void jerasure_matrix_encode(int k, int m, int w, int *matrix,
-                          char **data_ptrs, char **coding_ptrs, int size);
-
-void jerasure_bitmatrix_encode(int k, int m, int w, int *bitmatrix,
-                            char **data_ptrs, char **coding_ptrs, int size, int packetsize);
-
-void jerasure_schedule_encode(int k, int m, int w, int **schedule,
-                                  char **data_ptrs, char **coding_ptrs, int size, int packetsize);
-
-/* ------------------------------------------------------------ */
-/* Decoding. -------------------------------------------------- */
-
-/* These return integers, because the matrix may not be invertible. 
-   
-   The parameter row_k_ones should be set to 1 if row k of the matrix
-   (or rows kw to (k+1)w+1) of th distribution matrix are all ones
-   (or all identity matrices).  Then you can improve the performance
-   of decoding when there is more than one failure, and the parity
-   device didn't fail.  You do it by decoding all but one of the data
-   devices, and then decoding the last data device from the data devices
-   and the parity device.
-
-   jerasure_schedule_decode_lazy generates the schedule on the fly.
-
-   jerasure_matrix_decode only works when w = 8|16|32.
-
-   jerasure_make_decoding_matrix/bitmatrix make the k*k decoding matrix
-         (or wk*wk bitmatrix) by taking the rows corresponding to k
-         non-erased devices of the distribution matrix, and then
-         inverting that matrix.
-
-         You should already have allocated the decoding matrix and
-         dm_ids, which is a vector of k integers.  These will be
-         filled in appropriately.  dm_ids[i] is the id of element
-         i of the survivors vector.  I.e. row i of the decoding matrix
-         times dm_ids equals data drive i.
-
-         Both of these routines take "erased" instead of "erasures".
-         Erased is a vector with k+m elements, which has 0 or 1 for 
-         each device's id, according to whether the device is erased.
- 
-   jerasure_erasures_to_erased allocates and returns erased from erasures.
-    
- */
-
-int jerasure_matrix_decode(int k, int m, int w, 
-                          int *matrix, int row_k_ones, int *erasures,
-                          char **data_ptrs, char **coding_ptrs, int size);
-                          
-int jerasure_bitmatrix_decode(int k, int m, int w, 
-                            int *bitmatrix, int row_k_ones, int *erasures,
-                            char **data_ptrs, char **coding_ptrs, int size, int packetsize);
-
-int jerasure_schedule_decode_lazy(int k, int m, int w, int *bitmatrix, int *erasures,
-                            char **data_ptrs, char **coding_ptrs, int size, int packetsize,
-                            int smart);
-
-int jerasure_schedule_decode_cache(int k, int m, int w, int ***scache, int *erasures,
-                            char **data_ptrs, char **coding_ptrs, int size, int packetsize);
-
-int jerasure_make_decoding_matrix(int k, int m, int w, int *matrix, int *erased, 
-                                  int *decoding_matrix, int *dm_ids);
-
-int jerasure_make_decoding_bitmatrix(int k, int m, int w, int *matrix, int *erased, 
-                                  int *decoding_matrix, int *dm_ids);
-
-int *jerasure_erasures_to_erased(int k, int m, int *erasures);
-
-/* ------------------------------------------------------------ */
-/* These perform dot products and schedules. -------------------*/
-/*
-   src_ids is a matrix of k id's (0 - k-1 for data devices, k - k+m-1
-   for coding devices) that identify the source devices.  Dest_id is
-   the id of the destination device.
-
-   jerasure_matrix_dotprod only works when w = 8|16|32.
-
-   jerasure_do_scheduled_operations executes the schedule on w*packetsize worth of
-   bytes from each device.  ptrs is an array of pointers which should have as many
-   elements as the highest referenced device in the schedule.
-
- */
- 
-void jerasure_matrix_dotprod(int k, int w, int *matrix_row,
-                          int *src_ids, int dest_id,
-                          char **data_ptrs, char **coding_ptrs, int size);
-
-void jerasure_bitmatrix_dotprod(int k, int w, int *bitmatrix_row,
-                             int *src_ids, int dest_id,
-                             char **data_ptrs, char **coding_ptrs, int size, int packetsize);
-
-void jerasure_do_scheduled_operations(char **ptrs, int **schedule, int packetsize);
-
-/* ------------------------------------------------------------ */
-/* Matrix Inversion ------------------------------------------- */
-/*
-   The two matrix inversion functions work on rows*rows matrices of
-   ints.  If a bitmatrix, then each int will just be zero or one.
-   Otherwise, they will be elements of gf(2^w).  Obviously, you can
-   do bit matrices with crs_invert_matrix() and set w = 1, but
-   crs_invert_bitmatrix will be more efficient.
-
-   The two invertible functions return whether a matrix is invertible.
-   They are more efficient than the inverstion functions.
-
-   Mat will be destroyed when the matrix inversion or invertible
-   testing is done.  Sorry.
-
-   Inv must be allocated by the caller.
-
-   The two invert_matrix functions return 0 on success, and -1 if the
-   matrix is uninvertible.
-
-   The two invertible function simply return whether the matrix is
-   invertible.  (0 or 1). Mat will be destroyed.
- */
-
-int jerasure_invert_matrix(int *mat, int *inv, int rows, int w);
-int jerasure_invert_bitmatrix(int *mat, int *inv, int rows);
-int jerasure_invertible_matrix(int *mat, int rows, int w);
-int jerasure_invertible_bitmatrix(int *mat, int rows);
-
-/* ------------------------------------------------------------ */
-/* Basic matrix operations -------------------------------------*/
-/*
-   Each of the print_matrix routines require a w.  In jerasure_print_matrix,
-   this is to calculate the field width.  In jerasure_print_bitmatrix, it is
-   to put spaces between the bits.
-
-   jerasure_matrix_multiply is a simple matrix multiplier in GF(2^w).  It returns a r1*c2
-   matrix, which is the product of the two input matrices.  It allocates
-   the product.  Obviously, c1 should equal r2.  However, this is not
-   validated by the procedure.  
-*/
-
-void jerasure_print_matrix(int *matrix, int rows, int cols, int w);
-void jerasure_print_bitmatrix(int *matrix, int rows, int cols, int w);
-
-
-int *jerasure_matrix_multiply(int *m1, int *m2, int r1, int c1, int r2, int c2, int w);
-
-/* ------------------------------------------------------------ */
-/* Stats ------------------------------------------------------ */
-/*
-  jerasure_get_stats fills in a vector of three doubles:
-
-      fill_in[0] is the number of bytes that have been XOR'd
-      fill_in[1] is the number of bytes that have been copied
-      fill_in[2] is the number of bytes that have been multiplied
-                 by a constant in GF(2^w)
-
-  When jerasure_get_stats() is called, it resets its values.
- */
-
-void jerasure_get_stats(double *fill_in);
-
-int jerasure_autoconf_test();
-
-#endif
diff --git a/src/erasure-code/jerasure/jerasure/include/liberation.h b/src/erasure-code/jerasure/jerasure/include/liberation.h
deleted file mode 100644
index f2fb723..0000000
--- a/src/erasure-code/jerasure/jerasure/include/liberation.h
+++ /dev/null
@@ -1,47 +0,0 @@
-/* *
- * Copyright (c) 2013, James S. Plank and Kevin Greenan
- * All rights reserved.
- *
- * Jerasure - A C/C++ Library for a Variety of Reed-Solomon and RAID-6 Erasure
- * Coding Techniques
- *
- * Revision 2.0: Galois Field backend now links to GF-Complete
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- *  - Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *
- *  - Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- *  - Neither the name of the University of Tennessee nor the names of its
- *    contributors may be used to endorse or promote products derived
- *    from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
- * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
- * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
- * WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-
-#ifndef _LIBERATION
-
-extern int *liberation_coding_bitmatrix(int k, int w);
-extern int *liber8tion_coding_bitmatrix(int k);
-extern int *blaum_roth_coding_bitmatrix(int k, int w);
-
-#endif
diff --git a/src/erasure-code/jerasure/jerasure/include/reed_sol.h b/src/erasure-code/jerasure/jerasure/include/reed_sol.h
deleted file mode 100644
index d2d8fe8..0000000
--- a/src/erasure-code/jerasure/jerasure/include/reed_sol.h
+++ /dev/null
@@ -1,50 +0,0 @@
-/* *
- * Copyright (c) 2013, James S. Plank and Kevin Greenan
- * All rights reserved.
- *
- * Jerasure - A C/C++ Library for a Variety of Reed-Solomon and RAID-6 Erasure
- * Coding Techniques
- *
- * Revision 2.0: Galois Field backend now links to GF-Complete
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- *  - Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *
- *  - Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- *  - Neither the name of the University of Tennessee nor the names of its
- *    contributors may be used to endorse or promote products derived
- *    from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
- * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
- * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
- * WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-
-extern int *reed_sol_vandermonde_coding_matrix(int k, int m, int w);
-extern int *reed_sol_extended_vandermonde_matrix(int rows, int cols, int w);
-extern int *reed_sol_big_vandermonde_distribution_matrix(int rows, int cols, int w);
-
-extern int reed_sol_r6_encode(int k, int w, char **data_ptrs, char **coding_ptrs, int size);
-extern int *reed_sol_r6_coding_matrix(int k, int w);
-
-extern void reed_sol_galois_w08_region_multby_2(char *region, int nbytes);
-extern void reed_sol_galois_w16_region_multby_2(char *region, int nbytes);
-extern void reed_sol_galois_w32_region_multby_2(char *region, int nbytes);
diff --git a/src/erasure-code/jerasure/jerasure/src/cauchy.c b/src/erasure-code/jerasure/jerasure/src/cauchy.c
deleted file mode 100644
index f63dfb7..0000000
--- a/src/erasure-code/jerasure/jerasure/src/cauchy.c
+++ /dev/null
@@ -1,405 +0,0 @@
-/* *
- * Copyright (c) 2014, James S. Plank and Kevin Greenan
- * All rights reserved.
- *
- * Jerasure - A C/C++ Library for a Variety of Reed-Solomon and RAID-6 Erasure
- * Coding Techniques
- *
- * Revision 2.0: Galois Field backend now links to GF-Complete
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- *  - Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *
- *  - Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- *  - Neither the name of the University of Tennessee nor the names of its
- *    contributors may be used to endorse or promote products derived
- *    from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
- * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
- * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
- * WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-/* Jerasure's authors:
-
-   Revision 2.x - 2014: James S. Plank and Kevin M. Greenan
-   Revision 1.2 - 2008: James S. Plank, Scott Simmerman and Catherine D. Schuman.
-   Revision 1.0 - 2007: James S. Plank
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "galois.h"
-#include "jerasure.h"
-#include "cauchy.h"
-
-static int PPs[33] = { -1, -1, -1, -1, -1, -1, -1, -1,
-                       -1, -1, -1, -1, -1, -1, -1, -1,
-                       -1, -1, -1, -1, -1, -1, -1, -1,
-                       -1, -1, -1, -1, -1, -1, -1, -1, -1 };
-static int NOs[33];
-static int ONEs[33][33];
-
-static int *cbest_0;
-static int *cbest_1;
-static int cbest_2[3];
-static int cbest_3[7];
-static int cbest_4[15];
-static int cbest_5[31];
-static int cbest_6[63];
-static int cbest_7[127];
-static int cbest_8[255];
-static int cbest_9[511];
-static int cbest_10[1023];
-static int cbest_11[1023];
-static int *cbest_12, *cbest_13, *cbest_14, *cbest_15, *cbest_16, *cbest_17, *cbest_18, *cbest_19, *cbest_20,
-           *cbest_21, *cbest_22, *cbest_23, *cbest_24, *cbest_25, *cbest_26, *cbest_27, *cbest_28, *cbest_29, *cbest_30,
-           *cbest_31, *cbest_32;
-
-static int cbest_max_k[33] = { -1, -1, 3, 7, 15, 31, 63, 127, 255, 511, 1023, 1023, -1,
-     -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-     -1, -1, -1, -1 };
-
-static int cbest_init = 0;
-
-static int *cbest_all[33];
-
-
-#define talloc(type, num) (type *) malloc(sizeof(type)*(num))
-
-int cauchy_n_ones(int n, int w)
-{
-  int no;
-  int cno;
-  int nones;
-  int i, j;
-  int highbit;
-
-  highbit = (1 << (w-1));
-
-  if (PPs[w] == -1) {
-    nones = 0;
-    PPs[w] = galois_single_multiply(highbit, 2, w);
-    for (i = 0; i < w; i++) {
-      if (PPs[w] & (1 << i)) {
-        ONEs[w][nones] = (1 << i);
-        nones++;
-      }
-    }
-    NOs[w] = nones;
-  }
-
-  no = 0;
-  for (i = 0; i < w; i++) if (n & (1 << i)) no++;
-  cno = no;
-  for (i = 1; i < w; i++) {
-    if (n & highbit) {
-      n ^= highbit;
-      n <<= 1;
-      n ^= PPs[w];
-      cno--;
-      for (j = 0; j < NOs[w]; j++) {
-        cno += (n & ONEs[w][j]) ? 1 : -1;
-      }
-    } else {
-      n <<= 1;
-    } 
-    no += cno;
-  }
-  return no;
-}
-  
-int *cauchy_original_coding_matrix(int k, int m, int w)
-{
-  int *matrix;
-  int i, j, index;
-
-  if (w < 31 && (k+m) > (1 << w)) return NULL;
-  matrix = talloc(int, k*m);
-  if (matrix == NULL) return NULL;
-  index = 0;
-  for (i = 0; i < m; i++) {
-    for (j = 0; j < k; j++) {
-      matrix[index] = galois_single_divide(1, (i ^ (m+j)), w);
-      index++;
-    }
-  }
-  return matrix;
-}
-
-int *cauchy_xy_coding_matrix(int k, int m, int w, int *X, int *Y)
-{
-  int index, i, j;
-  int *matrix;
-
-  matrix = talloc(int, k*m);
-  if (matrix == NULL) { return NULL; }
-  index = 0;
-  for (i = 0; i < m; i++) {
-    for (j = 0; j < k; j++) {
-      matrix[index] = galois_single_divide(1, (X[i] ^ Y[j]), w);
-      index++;
-    }
-  }
-  return matrix;
-}
-
-void cauchy_improve_coding_matrix(int k, int m, int w, int *matrix)
-{
-  int index, i, j, x;
-  int tmp;
-  int bno, tno, bno_index;
-
-  for (j = 0; j < k; j++) {
-    if (matrix[j] != 1) {
-      tmp = galois_single_divide(1, matrix[j], w);
-      index = j;
-      for (i = 0; i < m; i++) {
-        matrix[index] = galois_single_multiply(matrix[index], tmp, w);
-        index += k;
-      }
-    }
-  }
-  for (i = 1; i < m; i++) {
-    bno = 0;
-    index = i*k;
-    for (j = 0; j < k; j++) bno += cauchy_n_ones(matrix[index+j], w);
-    bno_index = -1;
-    for (j = 0; j < k; j++) {
-      if (matrix[index+j] != 1) {
-        tmp = galois_single_divide(1, matrix[index+j], w);
-        tno = 0;
-        for (x = 0; x < k; x++) {
-          tno += cauchy_n_ones(galois_single_multiply(matrix[index+x], tmp, w), w);
-        }
-        if (tno < bno) {
-          bno = tno;
-          bno_index = j;
-        }
-      }
-    }
-    if (bno_index != -1) {
-      tmp = galois_single_divide(1, matrix[index+bno_index], w);
-      for (j = 0; j < k; j++) {
-        matrix[index+j] = galois_single_multiply(matrix[index+j], tmp, w);
-      }
-    }
-  }
-}
-
-int *cauchy_good_general_coding_matrix(int k, int m, int w)
-{
-  int *matrix, i;
-
-  if (m == 2 && k <= cbest_max_k[w]) {
-    matrix = talloc(int, k*m);
-    if (matrix == NULL) return NULL;
-    if (!cbest_init) {
-      cbest_init = 1;
-      cbest_all[0] = cbest_0; cbest_all[1] = cbest_1; cbest_all[2] = cbest_2; cbest_all[3] = cbest_3; cbest_all[4] =
-      cbest_4; cbest_all[5] = cbest_5; cbest_all[6] = cbest_6; cbest_all[7] = cbest_7; cbest_all[8] = cbest_8;
-      cbest_all[9] = cbest_9; cbest_all[10] = cbest_10; cbest_all[11] = cbest_11; cbest_all[12] = cbest_12;
-      cbest_all[13] = cbest_13; cbest_all[14] = cbest_14; cbest_all[15] = cbest_15; cbest_all[16] = cbest_16;
-      cbest_all[17] = cbest_17; cbest_all[18] = cbest_18; cbest_all[19] = cbest_19; cbest_all[20] = cbest_20;
-      cbest_all[21] = cbest_21; cbest_all[22] = cbest_22; cbest_all[23] = cbest_23; cbest_all[24] = cbest_24;
-      cbest_all[25] = cbest_25; cbest_all[26] = cbest_26; cbest_all[27] = cbest_27; cbest_all[28] = cbest_28;
-      cbest_all[29] = cbest_29; cbest_all[30] = cbest_30; cbest_all[31] = cbest_31; cbest_all[32] = (int *) cbest_32;
-    }
-    for (i = 0; i < k; i++) {
-      matrix[i] = 1;
-      matrix[i+k] = cbest_all[w][i];
-    }
-    return matrix;
-  } else {
-    matrix = cauchy_original_coding_matrix(k, m, w);
-    if (matrix == NULL) return NULL;
-    cauchy_improve_coding_matrix(k, m, w, matrix);
-    return matrix;
-  }
-}
-
-static int cbest_2[3] = { 1, 2, 3 };
-static int cbest_3[7] = { 1, 2, 5, 4, 7, 3, 6 };
-
-static int cbest_4[15] = { 1, 2, 9, 4, 8, 13, 3, 6, 12, 5, 11, 15, 10, 14, 7 };
-
-static int cbest_5[31] = { 1, 2, 18, 4, 9, 8, 22, 16, 3, 11, 19, 5, 10, 6, 20, 27, 13, 23, 26, 12,
-    17, 25, 24, 31, 30, 7, 15, 21, 29, 14, 28 };
-
-static int cbest_6[63] = { 1, 2, 33, 4, 8, 49, 16, 32, 57, 3, 6, 12, 24, 48, 5, 35, 9, 37, 10, 17,
-    41, 51, 56, 61, 18, 28, 53, 14, 20, 34, 7, 13, 25, 36, 59, 26, 39, 40, 45, 50, 60, 52, 63,
-    11, 30, 55, 19, 22, 29, 43, 58, 15, 21, 38, 44, 47, 62, 27, 54, 42, 31, 23, 46 };
-
-static int cbest_7[127] = { 1, 2, 68, 4, 34, 8, 17, 16, 76, 32, 38, 3, 64, 69, 5, 19, 35, 70, 6, 9,
-    18, 102, 10, 36, 85, 12, 21, 42, 51, 72, 77, 84, 20, 25, 33, 50, 78, 98, 24, 39, 49, 100, 110
-   , 48, 65, 93, 40, 66, 71, 92, 7, 46, 55, 87, 96, 103, 106, 11, 23, 37, 54, 81, 86, 108, 13,
-    22, 27, 43, 53, 73, 80, 14, 26, 52, 74, 79, 99, 119, 44, 95, 101, 104, 111, 118, 29, 59, 89,
-    94, 117, 28, 41, 58, 67, 88, 115, 116, 47, 57, 83, 97, 107, 114, 127, 56, 82, 109, 113, 126,
-    112, 125, 15, 63, 75, 123, 124, 31, 45, 62, 91, 105, 122, 30, 61, 90, 121, 60, 120 };
-
-static int cbest_8[255] = { 1, 2, 142, 4, 71, 8, 70, 173, 3, 35, 143, 16, 17, 67, 134, 140, 172, 6, 34
-   , 69, 201, 216, 5, 33, 86, 12, 65, 138, 158, 159, 175, 10, 32, 43, 66, 108, 130, 193, 234, 9,
-    24, 25, 50, 68, 79, 100, 132, 174, 200, 217, 20, 21, 42, 48, 87, 169, 41, 54, 64, 84, 96, 117
-   , 154, 155, 165, 226, 77, 82, 135, 136, 141, 168, 192, 218, 238, 7, 18, 19, 39, 40, 78, 113,
-    116, 128, 164, 180, 195, 205, 220, 232, 14, 26, 27, 58, 109, 156, 157, 203, 235, 13, 28, 29, 38
-   , 51, 56, 75, 85, 90, 101, 110, 112, 139, 171, 11, 37, 49, 52, 76, 83, 102, 119, 131, 150, 151
-   , 167, 182, 184, 188, 197, 219, 224, 45, 55, 80, 94, 97, 133, 170, 194, 204, 221, 227, 236, 36,
-    47, 73, 92, 98, 104, 118, 152, 153, 166, 202, 207, 239, 251, 22, 23, 44, 74, 91, 148, 149, 161
-   , 181, 190, 233, 46, 59, 88, 137, 146, 147, 163, 196, 208, 212, 222, 250, 57, 81, 95, 106, 111,
-    129, 160, 176, 199, 243, 249, 15, 53, 72, 93, 103, 115, 125, 162, 183, 185, 189, 206, 225, 255,
-    186, 210, 230, 237, 242, 248, 30, 31, 62, 89, 99, 105, 114, 121, 124, 178, 209, 213, 223, 228,
-    241, 254, 60, 191, 198, 247, 120, 240, 107, 127, 144, 145, 177, 211, 214, 246, 245, 123, 126,
-    187, 231, 253, 63, 179, 229, 244, 61, 122, 215, 252 };
-
-static int cbest_9[511] = { 1, 2, 264, 4, 132, 8, 66, 16, 33, 32, 280, 64, 140, 128, 3, 70, 265, 5,
-    133, 256, 266, 6, 9, 35, 67, 134, 268, 396, 10, 17, 34, 330, 12, 18, 68, 198, 297, 20, 37, 74
-   , 136, 148, 165, 281, 296, 24, 36, 41, 65, 82, 99, 164, 272, 282, 388, 40, 49, 98, 141, 194,
-    284, 328, 412, 48, 97, 129, 142, 196, 346, 71, 72, 96, 130, 313, 392, 80, 206, 257, 267, 312,
-    334, 7, 135, 156, 173, 192, 258, 269, 397, 404, 11, 78, 144, 161, 172, 260, 270, 299, 331, 344,
-    398, 13, 19, 39, 69, 86, 103, 160, 167, 199, 202, 298, 322, 384, 14, 21, 38, 43, 75, 102, 137,
-    149, 166, 204, 289, 332, 408, 462, 22, 25, 42, 51, 83, 101, 138, 150, 273, 283, 288, 301, 350,
-    389, 429, 26, 50, 76, 100, 195, 274, 285, 300, 329, 363, 390, 413, 428, 28, 45, 84, 143, 197,
-    200, 214, 231, 276, 286, 315, 320, 347, 362, 414, 458, 44, 53, 73, 90, 107, 131, 152, 169, 181,
-    230, 314, 338, 361, 393, 400, 454, 460, 52, 57, 81, 106, 115, 168, 175, 180, 207, 229, 305, 335
-   , 348, 360, 394, 421, 478, 56, 105, 114, 157, 163, 174, 193, 210, 227, 228, 259, 304, 317, 326,
-    405, 420, 445, 79, 104, 113, 145, 158, 162, 212, 226, 261, 271, 316, 345, 379, 399, 406, 444,
-    450, 456, 87, 88, 112, 146, 203, 225, 262, 291, 323, 336, 378, 385, 425, 452, 474, 15, 205, 222
-   , 224, 239, 290, 303, 333, 367, 377, 386, 409, 424, 431, 463, 470, 476, 23, 139, 151, 189, 208,
-    238, 302, 324, 351, 366, 376, 410, 430, 437, 27, 47, 77, 94, 111, 177, 188, 237, 275, 293, 342,
-    365, 391, 436, 448, 29, 46, 55, 85, 110, 119, 171, 176, 183, 201, 215, 218, 235, 236, 277, 287,
-    292, 321, 355, 364, 415, 417, 459, 466, 472, 30, 54, 59, 91, 109, 118, 153, 170, 182, 220, 234,
-    278, 307, 339, 354, 401, 416, 423, 441, 455, 461, 468, 495, 58, 108, 117, 154, 233, 306, 319,
-    349, 353, 383, 395, 402, 422, 440, 447, 479, 494, 92, 116, 211, 232, 318, 327, 340, 352, 382,
-    446, 493, 61, 159, 213, 216, 247, 309, 381, 407, 427, 451, 457, 464, 491, 492, 60, 89, 123, 147
-   , 185, 246, 263, 308, 337, 371, 380, 426, 433, 453, 475, 487, 490, 122, 184, 191, 223, 245, 370,
-    387, 432, 439, 471, 477, 486, 489, 511, 121, 179, 190, 209, 243, 244, 295, 325, 359, 369, 411,
-    438, 485, 488, 510, 95, 120, 178, 242, 294, 343, 358, 368, 419, 449, 483, 484, 509, 219, 241,
-    357, 418, 443, 467, 473, 482, 507, 508, 31, 221, 240, 255, 279, 356, 442, 469, 481, 503, 506,
-    155, 254, 403, 480, 502, 505, 63, 93, 127, 253, 311, 341, 375, 501, 504, 62, 126, 187, 217, 251
-   , 252, 310, 374, 435, 465, 499, 500, 125, 186, 250, 373, 434, 498, 124, 249, 372, 497, 248, 496
-    };
-
-static int cbest_10[1023] = { 1, 2, 516, 4, 258, 8, 129, 16, 32, 580, 64, 128, 290, 145, 256, 3, 512,
-    517, 5, 259, 518, 588, 6, 9, 18, 36, 72, 144, 774, 10, 17, 131, 262, 288, 524, 645, 12, 33,
-    133, 266, 294, 387, 532, 576, 581, 20, 34, 65, 137, 274, 548, 582, 24, 66, 291, 838, 40, 68,
-    130, 147, 161, 322, 644, 709, 806, 48, 132, 193, 257, 386, 596, 80, 136, 298, 419, 612, 661, 772
-   , 96, 149, 260, 272, 306, 403, 513, 146, 153, 160, 264, 292, 385, 514, 519, 544, 584, 589, 708,
-    870, 7, 19, 37, 73, 192, 354, 590, 770, 775, 11, 38, 74, 177, 263, 289, 418, 520, 525, 534, 641
-   , 660, 725, 802, 836, 846, 13, 22, 76, 148, 209, 267, 295, 320, 330, 402, 526, 528, 533, 577,
-    647, 717, 804, 14, 21, 26, 35, 44, 135, 152, 165, 201, 275, 304, 384, 401, 435, 549, 578, 583,
-    604, 608, 782, 903, 25, 52, 67, 88, 139, 270, 296, 391, 417, 550, 620, 653, 790, 834, 839, 41,
-    50, 69, 104, 141, 176, 278, 302, 323, 395, 423, 540, 598, 640, 705, 724, 807, 866, 28, 42, 49,
-    70, 82, 100, 163, 208, 282, 310, 556, 592, 597, 646, 663, 677, 711, 716, 868, 878, 81, 134, 151
-   , 164, 195, 200, 299, 326, 352, 362, 400, 434, 564, 613, 657, 768, 773, 902, 967, 97, 138, 155,
-    169, 197, 261, 273, 307, 358, 390, 416, 433, 451, 614, 652, 733, 800, 814, 844, 854, 935, 56, 84
-   , 98, 140, 181, 217, 265, 293, 328, 338, 394, 422, 515, 545, 585, 704, 788, 822, 871, 919, 162,
-    179, 276, 355, 407, 427, 546, 586, 591, 616, 662, 669, 676, 710, 727, 741, 771, 780, 901, 39, 75
-   , 150, 157, 194, 211, 225, 268, 280, 308, 314, 389, 411, 439, 521, 530, 535, 628, 656, 721, 803,
-    832, 837, 842, 847, 966, 23, 77, 112, 154, 168, 196, 300, 321, 331, 393, 421, 432, 450, 522, 527
-   , 529, 552, 606, 643, 673, 693, 713, 732, 805, 864, 874, 934, 999, 15, 27, 45, 54, 78, 90, 108,
-    180, 216, 305, 483, 560, 579, 600, 605, 609, 719, 778, 783, 852, 876, 886, 899, 918, 983, 46, 53
-   , 89, 167, 178, 185, 203, 213, 271, 297, 324, 334, 336, 360, 370, 406, 426, 467, 542, 551, 610,
-    621, 649, 668, 726, 740, 786, 791, 810, 820, 835, 900, 917, 931, 951, 965, 975, 30, 51, 105, 156
-   , 205, 210, 224, 279, 303, 356, 366, 388, 405, 410, 438, 449, 459, 536, 541, 594, 599, 622, 655,
-    720, 812, 818, 862, 867, 933, 29, 43, 71, 83, 92, 101, 106, 143, 173, 283, 311, 312, 346, 392,
-    409, 420, 437, 443, 557, 566, 593, 642, 659, 672, 692, 707, 712, 737, 757, 869, 879, 911, 998,
-    60, 102, 241, 327, 353, 363, 399, 425, 482, 558, 565, 624, 679, 718, 735, 749, 769, 798, 898,
-    963, 982, 58, 86, 166, 183, 184, 202, 212, 219, 233, 286, 359, 431, 466, 615, 636, 648, 689, 729
-   , 801, 815, 840, 845, 850, 855, 884, 916, 930, 950, 964, 974, 981, 995, 1015, 57, 85, 99, 120,
-    171, 199, 204, 229, 318, 329, 339, 368, 404, 448, 458, 465, 499, 654, 671, 685, 784, 789, 823,
-    872, 882, 915, 932, 949, 997, 1007, 116, 142, 159, 172, 277, 408, 436, 442, 455, 481, 491, 547,
-    572, 587, 617, 630, 658, 665, 706, 723, 736, 756, 776, 781, 816, 860, 894, 897, 910, 947, 991,
-    114, 221, 240, 269, 281, 309, 315, 332, 342, 344, 378, 398, 424, 441, 475, 487, 531, 618, 629,
-    678, 695, 734, 743, 748, 808, 833, 843, 929, 943, 962, 973, 113, 182, 189, 218, 227, 232, 301,
-    364, 374, 430, 457, 523, 553, 562, 602, 607, 688, 728, 753, 796, 830, 865, 875, 927, 980, 994,
-    1014, 55, 79, 91, 109, 170, 187, 198, 215, 228, 284, 415, 464, 498, 554, 561, 601, 670, 675, 684
-   , 715, 745, 765, 779, 848, 853, 877, 887, 909, 914, 948, 979, 996, 1006, 1013, 47, 110, 158, 249
-   , 316, 325, 335, 337, 361, 371, 397, 447, 454, 480, 490, 497, 538, 543, 611, 632, 664, 722, 787,
-    811, 821, 880, 896, 913, 946, 961, 971, 990, 1011, 31, 94, 220, 245, 357, 367, 429, 440, 474,
-    486, 537, 595, 623, 651, 681, 694, 701, 742, 759, 813, 819, 858, 863, 892, 928, 942, 945, 972,
-    989, 993, 1003, 1023, 62, 93, 107, 188, 207, 226, 237, 243, 313, 340, 347, 376, 456, 471, 473,
-    507, 567, 568, 626, 752, 890, 907, 926, 1005, 61, 103, 124, 175, 186, 214, 372, 414, 453, 463,
-    489, 503, 559, 625, 638, 674, 691, 714, 731, 739, 744, 764, 794, 799, 828, 908, 925, 939, 959,
-    978, 1012, 59, 87, 122, 248, 287, 350, 396, 413, 446, 485, 495, 496, 637, 751, 826, 841, 851,
-    885, 912, 941, 960, 970, 977, 1010, 118, 121, 235, 244, 319, 369, 382, 428, 445, 574, 650, 667,
-    680, 700, 758, 761, 785, 873, 883, 944, 988, 992, 1002, 1009, 1022, 117, 206, 223, 231, 236, 242
-   , 470, 472, 506, 573, 631, 687, 777, 817, 856, 861, 895, 906, 987, 1004, 1021, 115, 174, 191, 333
-   , 343, 345, 379, 452, 462, 469, 488, 502, 505, 619, 690, 697, 730, 738, 755, 809, 888, 924, 938,
-    958, 969, 1019, 253, 365, 375, 412, 484, 494, 501, 563, 603, 750, 767, 792, 797, 831, 923, 940,
-    957, 976, 1001, 234, 251, 285, 348, 444, 479, 555, 634, 666, 760, 824, 849, 905, 955, 1008, 111,
-    222, 230, 247, 317, 380, 461, 511, 539, 633, 686, 703, 747, 881, 937, 986, 1020, 95, 190, 468,
-    493, 504, 570, 696, 754, 859, 893, 968, 985, 1018, 63, 126, 252, 341, 377, 500, 569, 627, 683,
-    766, 891, 922, 956, 1000, 1017, 125, 239, 250, 373, 478, 639, 795, 829, 904, 921, 954, 123, 246,
-    351, 460, 477, 510, 702, 746, 763, 827, 936, 953, 119, 383, 492, 509, 575, 984, 682, 699, 857,
-    1016, 238, 255, 889, 920, 476, 762, 793, 952, 349, 508, 635, 825, 381, 698, 254, 571, 127 };
-
-static int cbest_11[1023] = { 1,
-    2, 1026, 4, 513, 8, 16, 1282, 32, 64, 641, 128, 256, 512, 1346, 1024, 3, 673, 1027, 5, 10, 20, 40, 80, 160, 320,
-    640, 6, 9, 515, 1030, 1280, 1539, 17, 517, 1034, 1283, 12, 18, 33, 521, 1042, 1362, 34, 65, 529, 1058, 1286, 1795,
-    24, 36, 66, 129, 545, 643, 1090, 1290, 1667, 68, 130, 257, 577, 645, 672, 1154, 1298, 1344, 48, 72, 132, 258, 336,
-    649, 681, 1314, 1347, 136, 168, 260, 514, 657, 769, 1538, 1923, 84, 96, 144, 264, 516, 1025, 1350, 1410, 1859, 42,
-    272, 520, 705, 1032, 1354, 11, 21, 41, 81, 161, 192, 288, 321, 528, 675, 1028, 1537, 1699, 1794, 7, 22, 82, 162,
-    322, 544, 642, 677, 897, 1031, 1046, 1066, 1106, 1186, 1281, 1366, 1378, 1666, 14, 44, 164, 324, 384, 523, 533,
-    553, 576, 593, 644, 833, 1035, 1040, 1288, 1360, 1987, 13, 19, 28, 88, 328, 519, 648, 680, 689, 1043, 1056, 1284,
-    1363, 1474, 1543, 1793, 1955, 26, 35, 56, 176, 656, 768, 1038, 1059, 1088, 1287, 1302, 1322, 1442, 1547, 1665,
-    1922, 25, 37, 52, 67, 112, 340, 352, 525, 531, 737, 1091, 1152, 1291, 1296, 1555, 1858, 1875, 38, 69, 74, 104, 131,
-    224, 547, 651, 661, 683, 704, 721, 961, 1050, 1062, 1155, 1299, 1312, 1345, 1370, 1571, 1799, 49, 70, 73, 133, 138,
-    148, 170, 208, 259, 337, 448, 537, 549, 579, 647, 674, 929, 1094, 1294, 1315, 1352, 1536, 1603, 1671, 1698, 1803,
-    1921, 50, 134, 137, 169, 261, 266, 276, 296, 338, 416, 581, 676, 896, 1074, 1098, 1158, 1348, 1394, 1408, 1675,
-    1707, 1811, 1857, 2019, 76, 85, 97, 145, 262, 265, 522, 532, 552, 561, 585, 592, 653, 659, 685, 771, 832, 849,
-    1064, 1162, 1194, 1306, 1318, 1351, 1386, 1411, 1506, 1683, 1827, 1986, 2003, 43, 86, 98, 140, 146, 172, 273, 344,
-    518, 688, 773, 1033, 1110, 1122, 1170, 1355, 1490, 1542, 1697, 1792, 1927, 1954, 100, 193, 268, 274, 289, 597, 609,
-    665, 697, 707, 777, 1029, 1044, 1104, 1184, 1330, 1364, 1376, 1414, 1546, 1664, 1731, 1863, 1931, 1963, 23, 46, 83,
-    92, 152, 163, 184, 194, 290, 323, 368, 524, 530, 555, 693, 709, 736, 753, 785, 993, 1036, 1047, 1067, 1107, 1187,
-    1218, 1320, 1358, 1367, 1379, 1418, 1450, 1545, 1554, 1867, 1874, 1939, 1985, 15, 30, 45, 60, 90, 120, 165, 180,
-    196, 240, 280, 292, 325, 330, 360, 385, 480, 546, 650, 660, 679, 682, 713, 720, 745, 801, 899, 960, 977, 1041,
-    1289, 1361, 1426, 1472, 1541, 1570, 1703, 1798, 1953, 29, 58, 89, 116, 166, 200, 232, 326, 329, 386, 464, 535, 536,
-    548, 578, 595, 646, 835, 901, 928, 1048, 1057, 1070, 1190, 1285, 1300, 1368, 1382, 1440, 1475, 1559, 1579, 1602,
-    1619, 1670, 1802, 1879, 1891, 1920, 27, 57, 177, 304, 388, 527, 557, 580, 691, 725, 837, 905, 937, 1039, 1054,
-    1089, 1114, 1292, 1303, 1323, 1374, 1443, 1553, 1674, 1706, 1715, 1801, 1810, 1856, 1873, 1991, 2018, 2035, 53,
-    106, 113, 178, 212, 332, 341, 353, 392, 424, 541, 560, 584, 601, 652, 658, 684, 770, 841, 848, 913, 1060, 1082,
-    1096, 1153, 1202, 1297, 1402, 1478, 1522, 1569, 1673, 1682, 1705, 1797, 1826, 1959, 1995, 2002, 2027, 39, 54, 75,
-    105, 114, 225, 342, 354, 400, 539, 569, 739, 772, 1051, 1063, 1078, 1092, 1138, 1160, 1192, 1304, 1313, 1326, 1371,
-    1384, 1398, 1446, 1482, 1514, 1551, 1601, 1669, 1696, 1763, 1815, 1835, 1926, 71, 139, 149, 171, 209, 226, 298,
-    356, 449, 565, 596, 608, 625, 663, 664, 696, 706, 723, 741, 776, 853, 865, 963, 1072, 1095, 1130, 1156, 1250, 1295,
-    1310, 1353, 1392, 1687, 1730, 1747, 1809, 1862, 1930, 1962, 1971, 2007, 2017, 51, 78, 108, 135, 150, 210, 228, 267,
-    277, 297, 339, 348, 417, 450, 551, 554, 587, 617, 655, 687, 692, 708, 752, 784, 931, 965, 992, 1009, 1075, 1099,
-    1159, 1174, 1234, 1316, 1338, 1349, 1395, 1409, 1458, 1494, 1504, 1544, 1563, 1575, 1681, 1825, 1866, 1883, 1929,
-    1938, 1961, 1984, 2001, 77, 142, 174, 263, 278, 346, 376, 418, 452, 496, 583, 669, 678, 701, 712, 729, 744, 761,
-    800, 898, 933, 969, 976, 1001, 1065, 1108, 1120, 1163, 1168, 1195, 1307, 1319, 1334, 1356, 1387, 1416, 1448, 1488,
-    1507, 1540, 1607, 1702, 1807, 1865, 1925, 1952, 87, 99, 141, 147, 156, 173, 188, 216, 248, 270, 300, 345, 372, 420,
-    456, 488, 534, 563, 594, 667, 699, 757, 779, 789, 809, 834, 851, 900, 1102, 1111, 1123, 1171, 1328, 1412, 1491,
-    1558, 1578, 1587, 1611, 1618, 1679, 1711, 1729, 1861, 1878, 1890, 1907, 1943, 2023, 94, 101, 124, 154, 186, 244,
-    269, 275, 284, 526, 556, 589, 690, 724, 775, 836, 904, 936, 945, 981, 1045, 1068, 1105, 1166, 1185, 1198, 1216,
-    1331, 1365, 1377, 1390, 1415, 1430, 1510, 1552, 1577, 1714, 1800, 1819, 1831, 1872, 1899, 1937, 1990, 2034, 47, 62,
-    93, 102, 122, 153, 185, 195, 282, 291, 312, 362, 369, 432, 468, 540, 599, 600, 611, 715, 747, 840, 857, 912, 1037,
-    1052, 1112, 1126, 1219, 1321, 1359, 1372, 1419, 1424, 1451, 1568, 1623, 1635, 1672, 1691, 1701, 1704, 1723, 1796,
-    1958, 1994, 2011, 2026, 2043, 31, 61, 91, 121, 181, 197, 202, 234, 241, 281, 293, 308, 331, 361, 370, 481, 538,
-    568, 613, 695, 711, 738, 755, 781, 787, 995, 1080, 1118, 1178, 1188, 1210, 1380, 1400, 1427, 1473, 1498, 1530,
-    1550, 1557, 1600, 1617, 1668, 1719, 1735, 1762, 1779, 1814, 1834, 1843, 1877, 1889, 1935, 1967, 1993, 2025, 2039,
-    59, 117, 167, 182, 198, 201, 233, 242, 294, 327, 387, 465, 482, 559, 564, 605, 624, 662, 722, 740, 803, 852, 864,
-    881, 907, 917, 939, 962, 979, 997, 1049, 1071, 1086, 1146, 1191, 1206, 1222, 1266, 1301, 1324, 1369, 1383, 1406,
-    1422, 1441, 1454, 1480, 1512, 1526, 1549, 1686, 1713, 1739, 1746, 1771, 1808, 1833, 1871, 1970, 1989, 2006, 2016,
-    2033, 118, 305, 334, 364, 389, 394, 404, 426, 466, 484, 543, 550, 573, 586, 603, 616, 633, 654, 686, 717, 749, 793,
-    805, 843, 873, 903, 930, 964, 1008, 1055, 1115, 1128, 1142, 1200, 1226, 1258, 1293, 1308, 1375, 1476, 1520, 1562,
-    1574, 1680, 1824 };
-
diff --git a/src/erasure-code/jerasure/jerasure/src/galois.c b/src/erasure-code/jerasure/jerasure/src/galois.c
deleted file mode 100644
index 82702db..0000000
--- a/src/erasure-code/jerasure/jerasure/src/galois.c
+++ /dev/null
@@ -1,365 +0,0 @@
-/* *
- * Copyright (c) 2014, James S. Plank and Kevin Greenan
- * All rights reserved.
- *
- * Jerasure - A C/C++ Library for a Variety of Reed-Solomon and RAID-6 Erasure
- * Coding Techniques
- *
- * Revision 2.0: Galois Field backend now links to GF-Complete
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- *  - Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *
- *  - Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- *  - Neither the name of the University of Tennessee nor the names of its
- *    contributors may be used to endorse or promote products derived
- *    from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
- * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
- * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
- * WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-/* Jerasure's authors:
-
-   Revision 2.x - 2014: James S. Plank and Kevin M. Greenan
-   Revision 1.2 - 2008: James S. Plank, Scott Simmerman and Catherine D. Schuman.
-   Revision 1.0 - 2007: James S. Plank
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <assert.h>
-
-#include "galois.h"
-
-#define MAX_GF_INSTANCES 64
-gf_t *gfp_array[MAX_GF_INSTANCES] = { 0 };
-int  gfp_is_composite[MAX_GF_INSTANCES] = { 0 };
-
-gf_t *galois_get_field_ptr(int w)
-{
-  if (gfp_array[w] != NULL) {
-    return gfp_array[w];
-  }
-
-  return NULL;
-}
-
-gf_t* galois_init_field(int w,
-                        int mult_type,
-                        int region_type,
-                        int divide_type,
-                        uint64_t prim_poly,
-                        int arg1,
-                        int arg2)
-{
-  int scratch_size;
-  void *scratch_memory;
-  gf_t *gfp;
-
-  if (w <= 0 || w > 32) {
-    fprintf(stderr, "ERROR -- cannot init default Galois field for w=%d\n", w);
-    assert(0);
-  }
-
-  gfp = (gf_t *) malloc(sizeof(gf_t));
-  if (!gfp) {
-    fprintf(stderr, "ERROR -- cannot allocate memory for Galois field w=%d\n", w);
-    assert(0);
-  }
-
-  scratch_size = gf_scratch_size(w, mult_type, region_type, divide_type, arg1, arg2);
-  if (!scratch_size) {
-    fprintf(stderr, "ERROR -- cannot get scratch size for base field w=%d\n", w);
-    assert(0);
-  }
-
-  scratch_memory = malloc(scratch_size);
-  if (!scratch_memory) {
-    fprintf(stderr, "ERROR -- cannot get scratch memory for base field w=%d\n", w);
-    assert(0);
-  }
-
-  if(!gf_init_hard(gfp,
-                   w, 
-                   mult_type, 
-                   region_type, 
-                   divide_type, 
-                   prim_poly, 
-                   arg1, 
-                   arg2, 
-                   NULL, 
-                   scratch_memory))
-  {
-    fprintf(stderr, "ERROR -- cannot init default Galois field for w=%d\n", w);
-    assert(0);
-  }
-
-  gfp_is_composite[w] = 0;
-  return gfp;
-}
-
-gf_t* galois_init_composite_field(int w,
-                                int region_type,
-                                int divide_type,
-                                int degree,
-                                gf_t* base_gf)
-{
-  int scratch_size;
-  void *scratch_memory;
-  gf_t *gfp;
-  
-  if (w <= 0 || w > 32) {
-    fprintf(stderr, "ERROR -- cannot init composite field for w=%d\n", w);
-    assert(0);
-  }
-  
-  gfp = (gf_t *) malloc(sizeof(gf_t));
-  if (!gfp) {
-    fprintf(stderr, "ERROR -- cannot allocate memory for Galois field w=%d\n", w);
-    assert(0);
-  }
-
-  scratch_size = gf_scratch_size(w, GF_MULT_COMPOSITE, region_type, divide_type, degree, 0);
-  if (!scratch_size) {
-    fprintf(stderr, "ERROR -- cannot get scratch size for composite field w=%d\n", w);
-    assert(0);
-  }
-
-  scratch_memory = malloc(scratch_size);
-  if (!scratch_memory) {
-    fprintf(stderr, "ERROR -- cannot get scratch memory for composite field w=%d\n", w);
-    assert(0);
-  }
-
-  if(!gf_init_hard(gfp,
-                   w,
-                   GF_MULT_COMPOSITE,
-                   region_type,
-                   divide_type,
-                   0, 
-                   degree, 
-                   0, 
-                   base_gf,
-                   scratch_memory))
-  {
-    fprintf(stderr, "ERROR -- cannot init default composite field for w=%d\n", w);
-    assert(0);
-  }
-  gfp_is_composite[w] = 1;
-  return gfp;
-}
-
-int galois_init_default_field(int w)
-{
-  if (gfp_array[w] == NULL) {
-    gfp_array[w] = (gf_t*)malloc(sizeof(gf_t));
-    if(gfp_array[w] == NULL)
-      return ENOMEM;
-    if (!gf_init_easy(gfp_array[w], w))
-      return EINVAL;
-  }
-  return 0;
-}
-
-static void galois_init(int w)
-{
-  if (w <= 0 || w > 32) {
-    fprintf(stderr, "ERROR -- cannot init default Galois field for w=%d\n", w);
-    assert(0);
-  }
-
-  switch (galois_init_default_field(w)) {
-  case ENOMEM:
-    fprintf(stderr, "ERROR -- cannot allocate memory for Galois field w=%d\n", w);
-    assert(0);
-    break;
-  case EINVAL:
-    fprintf(stderr, "ERROR -- cannot init default Galois field for w=%d\n", w);
-    assert(0);
-    break;
-  }
-}
-
-
-static int is_valid_gf(gf_t *gf, int w)
-{
-  // TODO: I assume we may eventually
-  // want to do w=64 and 128, so w
-  // will be needed to perform this check
-  (void)w;
-
-  if (gf == NULL) {
-    return 0;
-  }
-  if (gf->multiply.w32 == NULL) {
-    return 0;
-  }
-  if (gf->multiply_region.w32 == NULL) {
-    return 0;
-  }
-  if (gf->divide.w32 == NULL) {
-    return 0;
-  }
-  if (gf->inverse.w32 == NULL) {
-    return 0;
-  }
-  if (gf->extract_word.w32 == NULL) {
-    return 0;
-  }
-
-  return 1;
-}
-
-void galois_change_technique(gf_t *gf, int w)
-{
-  if (w <= 0 || w > 32) {
-    fprintf(stderr, "ERROR -- cannot support Galois field for w=%d\n", w);
-    assert(0);
-  }
-
-  if (!is_valid_gf(gf, w)) {
-    fprintf(stderr, "ERROR -- overriding with invalid Galois field for w=%d\n", w);
-    assert(0);
-  }
-
-  if (gfp_array[w] != NULL) {
-    gf_free(gfp_array[w], gfp_is_composite[w]);
-  }
-
-  gfp_array[w] = gf;
-}
-
-int galois_single_multiply(int x, int y, int w)
-{
-  if (x == 0 || y == 0) return 0;
-  
-  if (gfp_array[w] == NULL) {
-    galois_init(w);
-  }
-
-  if (w <= 32) {
-    return gfp_array[w]->multiply.w32(gfp_array[w], x, y);
-  } else {
-    fprintf(stderr, "ERROR -- Galois field not implemented for w=%d\n", w);
-    return 0;
-  }
-}
-
-int galois_single_divide(int x, int y, int w)
-{
-  if (x == 0) return 0;
-  if (y == 0) return -1;
-
-  if (gfp_array[w] == NULL) {
-    galois_init(w);
-  }
-
-  if (w <= 32) {
-    return gfp_array[w]->divide.w32(gfp_array[w], x, y);
-  } else {
-    fprintf(stderr, "ERROR -- Galois field not implemented for w=%d\n", w);
-    return 0;
-  }
-}
-
-void galois_w08_region_multiply(char *region,      /* Region to multiply */
-                                  int multby,       /* Number to multiply by */
-                                  int nbytes,        /* Number of bytes in region */
-                                  char *r2,          /* If r2 != NULL, products go here */
-                                  int add)
-{
-  if (gfp_array[8] == NULL) {
-    galois_init(8);
-  }
-  gfp_array[8]->multiply_region.w32(gfp_array[8], region, r2, multby, nbytes, add);
-}
-
-void galois_w16_region_multiply(char *region,      /* Region to multiply */
-                                  int multby,       /* Number to multiply by */
-                                  int nbytes,        /* Number of bytes in region */
-                                  char *r2,          /* If r2 != NULL, products go here */
-                                  int add)
-{
-  if (gfp_array[16] == NULL) {
-    galois_init(16);
-  }
-  gfp_array[16]->multiply_region.w32(gfp_array[16], region, r2, multby, nbytes, add);
-}
-
-
-void galois_w32_region_multiply(char *region,      /* Region to multiply */
-                                  int multby,       /* Number to multiply by */
-                                  int nbytes,        /* Number of bytes in region */
-                                  char *r2,          /* If r2 != NULL, products go here */
-                                  int add)
-{
-  if (gfp_array[32] == NULL) {
-    galois_init(32);
-  }
-  gfp_array[32]->multiply_region.w32(gfp_array[32], region, r2, multby, nbytes, add);
-}
-
-void galois_w8_region_xor(void *src, void *dest, int nbytes)
-{
-  if (gfp_array[8] == NULL) {
-    galois_init(8);
-  }
-  gfp_array[8]->multiply_region.w32(gfp_array[32], src, dest, 1, nbytes, 1);
-}
-
-void galois_w16_region_xor(void *src, void *dest, int nbytes)
-{
-  if (gfp_array[16] == NULL) {
-    galois_init(16);
-  }
-  gfp_array[16]->multiply_region.w32(gfp_array[16], src, dest, 1, nbytes, 1);
-}
-
-void galois_w32_region_xor(void *src, void *dest, int nbytes)
-{
-  if (gfp_array[32] == NULL) {
-    galois_init(32);
-  }
-  gfp_array[32]->multiply_region.w32(gfp_array[32], src, dest, 1, nbytes, 1);
-}
-
-void galois_region_xor(char *src, char *dest, int nbytes)
-{
-  if (nbytes >= 16) {
-    galois_w32_region_xor(src, dest, nbytes);
-  } else {
-    int i = 0;
-    for (i = 0; i < nbytes; i++) {
-      *dest ^= *src;
-      dest++;
-      src++;
-    } 
-  }
-}
-
-int galois_inverse(int y, int w)
-{
-  if (y == 0) return -1;
-  return galois_single_divide(1, y, w);
-}
diff --git a/src/erasure-code/jerasure/jerasure/src/jerasure.c b/src/erasure-code/jerasure/jerasure/src/jerasure.c
deleted file mode 100644
index 4297653..0000000
--- a/src/erasure-code/jerasure/jerasure/src/jerasure.c
+++ /dev/null
@@ -1,1388 +0,0 @@
-/* *
- * Copyright (c) 2014, James S. Plank and Kevin Greenan
- * All rights reserved.
- *
- * Jerasure - A C/C++ Library for a Variety of Reed-Solomon and RAID-6 Erasure
- * Coding Techniques
- *
- * Revision 2.0: Galois Field backend now links to GF-Complete
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- *  - Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *
- *  - Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- *  - Neither the name of the University of Tennessee nor the names of its
- *    contributors may be used to endorse or promote products derived
- *    from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
- * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
- * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
- * WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-/* Jerasure's authors:
-
-   Revision 2.x - 2014: James S. Plank and Kevin M. Greenan
-   Revision 1.2 - 2008: James S. Plank, Scott Simmerman and Catherine D. Schuman.
-   Revision 1.0 - 2007: James S. Plank
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <assert.h>
-
-#include "galois.h"
-#include "jerasure.h"
-
-#define talloc(type, num) (type *) malloc(sizeof(type)*(num))
-
-static double jerasure_total_xor_bytes = 0;
-static double jerasure_total_gf_bytes = 0;
-static double jerasure_total_memcpy_bytes = 0;
-
-void jerasure_print_matrix(int *m, int rows, int cols, int w)
-{
-  int i, j;
-  int fw;
-  char s[30];
-  unsigned int w2;
-
-  if (w == 32) {
-    fw = 10;
-  } else {
-    w2 = (1 << w);
-    sprintf(s, "%u", w2-1);
-    fw = strlen(s);
-  }
-
-  for (i = 0; i < rows; i++) {
-    for (j = 0; j < cols; j++) {
-      if (j != 0) printf(" ");
-      printf("%*u", fw, m[i*cols+j]); 
-    }
-    printf("\n");
-  }
-}
-
-void jerasure_print_bitmatrix(int *m, int rows, int cols, int w)
-{
-  int i, j;
-
-  for (i = 0; i < rows; i++) {
-    if (i != 0 && i%w == 0) printf("\n");
-    for (j = 0; j < cols; j++) {
-      if (j != 0 && j%w == 0) printf(" ");
-      printf("%d", m[i*cols+j]); 
-    }
-    printf("\n");
-  }
-}
-
-int jerasure_make_decoding_matrix(int k, int m, int w, int *matrix, int *erased, int *decoding_matrix, int *dm_ids)
-{
-  int i, j, *tmpmat;
-
-  j = 0;
-  for (i = 0; j < k; i++) {
-    if (erased[i] == 0) {
-      dm_ids[j] = i;
-      j++;
-    }
-  }
-
-  tmpmat = talloc(int, k*k);
-  if (tmpmat == NULL) { return -1; }
-  for (i = 0; i < k; i++) {
-    if (dm_ids[i] < k) {
-      for (j = 0; j < k; j++) tmpmat[i*k+j] = 0;
-      tmpmat[i*k+dm_ids[i]] = 1;
-    } else {
-      for (j = 0; j < k; j++) {
-        tmpmat[i*k+j] = matrix[(dm_ids[i]-k)*k+j];
-      }
-    }
-  }
-
-  i = jerasure_invert_matrix(tmpmat, decoding_matrix, k, w);
-  free(tmpmat);
-  return i;
-}
-
-/* Internal Routine */
-int jerasure_make_decoding_bitmatrix(int k, int m, int w, int *matrix, int *erased, int *decoding_matrix, int *dm_ids)
-{
-  int i, j, *tmpmat;
-  int index, mindex;
-
-  j = 0;
-  for (i = 0; j < k; i++) {
-    if (erased[i] == 0) {
-      dm_ids[j] = i;
-      j++;
-    }
-  }
-
-  tmpmat = talloc(int, k*k*w*w);
-  if (tmpmat == NULL) { return -1; }
-  for (i = 0; i < k; i++) {
-    if (dm_ids[i] < k) {
-      index = i*k*w*w;
-      for (j = 0; j < k*w*w; j++) tmpmat[index+j] = 0;
-      index = i*k*w*w+dm_ids[i]*w;
-      for (j = 0; j < w; j++) {
-        tmpmat[index] = 1;
-        index += (k*w+1);
-      }
-    } else {
-      index = i*k*w*w;
-      mindex = (dm_ids[i]-k)*k*w*w;
-      for (j = 0; j < k*w*w; j++) {
-        tmpmat[index+j] = matrix[mindex+j];
-      }
-    }
-  }
-
-  i = jerasure_invert_bitmatrix(tmpmat, decoding_matrix, k*w);
-  free(tmpmat);
-  return i;
-}
-
-int jerasure_matrix_decode(int k, int m, int w, int *matrix, int row_k_ones, int *erasures,
-                          char **data_ptrs, char **coding_ptrs, int size)
-{
-  int i, edd, lastdrive;
-  int *tmpids;
-  int *erased, *decoding_matrix, *dm_ids;
-
-  if (w != 8 && w != 16 && w != 32) return -1;
-
-  erased = jerasure_erasures_to_erased(k, m, erasures);
-  if (erased == NULL) return -1;
-
-  /* Find the number of data drives failed */
-
-  lastdrive = k;
-
-  edd = 0;
-  for (i = 0; i < k; i++) {
-    if (erased[i]) {
-      edd++;
-      lastdrive = i;
-    }
-  }
-    
-  /* You only need to create the decoding matrix in the following cases:
-
-      1. edd > 0 and row_k_ones is false.
-      2. edd > 0 and row_k_ones is true and coding device 0 has been erased.
-      3. edd > 1
-
-      We're going to use lastdrive to denote when to stop decoding data.
-      At this point in the code, it is equal to the last erased data device.
-      However, if we can't use the parity row to decode it (i.e. row_k_ones=0
-         or erased[k] = 1, we're going to set it to k so that the decoding 
-         pass will decode all data.
-   */
-
-  if (!row_k_ones || erased[k]) lastdrive = k;
-
-  dm_ids = NULL;
-  decoding_matrix = NULL;
-
-  if (edd > 1 || (edd > 0 && (!row_k_ones || erased[k]))) {
-    dm_ids = talloc(int, k);
-    if (dm_ids == NULL) {
-      free(erased);
-      return -1;
-    }
-
-    decoding_matrix = talloc(int, k*k);
-    if (decoding_matrix == NULL) {
-      free(erased);
-      free(dm_ids);
-      return -1;
-    }
-
-    if (jerasure_make_decoding_matrix(k, m, w, matrix, erased, decoding_matrix, dm_ids) < 0) {
-      free(erased);
-      free(dm_ids);
-      free(decoding_matrix);
-      return -1;
-    }
-  }
-
-  /* Decode the data drives.  
-     If row_k_ones is true and coding device 0 is intact, then only decode edd-1 drives.
-     This is done by stopping at lastdrive.
-     We test whether edd > 0 so that we can exit the loop early if we're done.
-   */
-
-  for (i = 0; edd > 0 && i < lastdrive; i++) {
-    if (erased[i]) {
-      jerasure_matrix_dotprod(k, w, decoding_matrix+(i*k), dm_ids, i, data_ptrs, coding_ptrs, size);
-      edd--;
-    }
-  }
-
-  /* Then if necessary, decode drive lastdrive */
-
-  if (edd > 0) {
-    tmpids = talloc(int, k);
-    for (i = 0; i < k; i++) {
-      tmpids[i] = (i < lastdrive) ? i : i+1;
-    }
-    jerasure_matrix_dotprod(k, w, matrix, tmpids, lastdrive, data_ptrs, coding_ptrs, size);
-    free(tmpids);
-  }
-  
-  /* Finally, re-encode any erased coding devices */
-
-  for (i = 0; i < m; i++) {
-    if (erased[k+i]) {
-      jerasure_matrix_dotprod(k, w, matrix+(i*k), NULL, i+k, data_ptrs, coding_ptrs, size);
-    }
-  }
-
-  free(erased);
-  if (dm_ids != NULL) free(dm_ids);
-  if (decoding_matrix != NULL) free(decoding_matrix);
-
-  return 0;
-}
-
-
-int *jerasure_matrix_to_bitmatrix(int k, int m, int w, int *matrix) 
-{
-  int *bitmatrix;
-  int rowelts, rowindex, colindex, elt, i, j, l, x;
-
-  bitmatrix = talloc(int, k*m*w*w);
-  if (matrix == NULL) { return NULL; }
-
-  rowelts = k * w;
-  rowindex = 0;
-
-  for (i = 0; i < m; i++) {
-    colindex = rowindex;
-    for (j = 0; j < k; j++) {
-      elt = matrix[i*k+j];
-      for (x = 0; x < w; x++) {
-        for (l = 0; l < w; l++) {
-          bitmatrix[colindex+x+l*rowelts] = ((elt & (1 << l)) ? 1 : 0);
-        }
-        elt = galois_single_multiply(elt, 2, w);
-      }
-      colindex += w;
-    }
-    rowindex += rowelts * w;
-  }
-  return bitmatrix;
-}
-
-void jerasure_matrix_encode(int k, int m, int w, int *matrix,
-                          char **data_ptrs, char **coding_ptrs, int size)
-{
-  int i;
-  
-  if (w != 8 && w != 16 && w != 32) {
-    fprintf(stderr, "ERROR: jerasure_matrix_encode() and w is not 8, 16 or 32\n");
-    assert(0);
-  }
-
-  for (i = 0; i < m; i++) {
-    jerasure_matrix_dotprod(k, w, matrix+(i*k), NULL, k+i, data_ptrs, coding_ptrs, size);
-  }
-}
-
-void jerasure_bitmatrix_dotprod(int k, int w, int *bitmatrix_row,
-                             int *src_ids, int dest_id,
-                             char **data_ptrs, char **coding_ptrs, int size, int packetsize)
-{
-  int j, sindex, pstarted, index, x, y;
-  char *dptr, *pptr, *bdptr, *bpptr;
-
-  if (size%(w*packetsize) != 0) {
-    fprintf(stderr, "jerasure_bitmatrix_dotprod - size%c(w*packetsize)) must = 0\n", '%');
-    assert(0);
-  }
-
-  bpptr = (dest_id < k) ? data_ptrs[dest_id] : coding_ptrs[dest_id-k];
-
-  for (sindex = 0; sindex < size; sindex += (packetsize*w)) {
-    index = 0;
-    for (j = 0; j < w; j++) {
-      pstarted = 0;
-      pptr = bpptr + sindex + j*packetsize;
-      for (x = 0; x < k; x++) {
-        if (src_ids == NULL) {
-          bdptr = data_ptrs[x];
-        } else if (src_ids[x] < k) {
-          bdptr = data_ptrs[src_ids[x]];
-        } else {
-          bdptr = coding_ptrs[src_ids[x]-k];
-        }
-        for (y = 0; y < w; y++) {
-          if (bitmatrix_row[index]) {
-            dptr = bdptr + sindex + y*packetsize;
-            if (!pstarted) {
-              memcpy(pptr, dptr, packetsize);
-              jerasure_total_memcpy_bytes += packetsize;
-              pstarted = 1;
-            } else {
-              galois_region_xor(dptr, pptr, packetsize);
-              jerasure_total_xor_bytes += packetsize;
-            }
-          }
-          index++;
-        }
-      }
-    }
-  }
-}
-
-void jerasure_do_parity(int k, char **data_ptrs, char *parity_ptr, int size) 
-{
-  int i;
-
-  memcpy(parity_ptr, data_ptrs[0], size);
-  jerasure_total_memcpy_bytes += size;
-  
-  for (i = 1; i < k; i++) {
-    galois_region_xor(data_ptrs[i], parity_ptr, size);
-    jerasure_total_xor_bytes += size;
-  }
-}
-
-int jerasure_invert_matrix(int *mat, int *inv, int rows, int w)
-{
-  int cols, i, j, k, x, rs2;
-  int row_start, tmp, inverse;
- 
-  cols = rows;
-
-  k = 0;
-  for (i = 0; i < rows; i++) {
-    for (j = 0; j < cols; j++) {
-      inv[k] = (i == j) ? 1 : 0;
-      k++;
-    }
-  }
-
-  /* First -- convert into upper triangular  */
-  for (i = 0; i < cols; i++) {
-    row_start = cols*i;
-
-    /* Swap rows if we ave a zero i,i element.  If we can't swap, then the 
-       matrix was not invertible  */
-
-    if (mat[row_start+i] == 0) { 
-      for (j = i+1; j < rows && mat[cols*j+i] == 0; j++) ;
-      if (j == rows) return -1;
-      rs2 = j*cols;
-      for (k = 0; k < cols; k++) {
-        tmp = mat[row_start+k];
-        mat[row_start+k] = mat[rs2+k];
-        mat[rs2+k] = tmp;
-        tmp = inv[row_start+k];
-        inv[row_start+k] = inv[rs2+k];
-        inv[rs2+k] = tmp;
-      }
-    }
- 
-    /* Multiply the row by 1/element i,i  */
-    tmp = mat[row_start+i];
-    if (tmp != 1) {
-      inverse = galois_single_divide(1, tmp, w);
-      for (j = 0; j < cols; j++) { 
-        mat[row_start+j] = galois_single_multiply(mat[row_start+j], inverse, w);
-        inv[row_start+j] = galois_single_multiply(inv[row_start+j], inverse, w);
-      }
-    }
-
-    /* Now for each j>i, add A_ji*Ai to Aj  */
-    k = row_start+i;
-    for (j = i+1; j != cols; j++) {
-      k += cols;
-      if (mat[k] != 0) {
-        if (mat[k] == 1) {
-          rs2 = cols*j;
-          for (x = 0; x < cols; x++) {
-            mat[rs2+x] ^= mat[row_start+x];
-            inv[rs2+x] ^= inv[row_start+x];
-          }
-        } else {
-          tmp = mat[k];
-          rs2 = cols*j;
-          for (x = 0; x < cols; x++) {
-            mat[rs2+x] ^= galois_single_multiply(tmp, mat[row_start+x], w);
-            inv[rs2+x] ^= galois_single_multiply(tmp, inv[row_start+x], w);
-          }
-        }
-      }
-    }
-  }
-
-  /* Now the matrix is upper triangular.  Start at the top and multiply down  */
-
-  for (i = rows-1; i >= 0; i--) {
-    row_start = i*cols;
-    for (j = 0; j < i; j++) {
-      rs2 = j*cols;
-      if (mat[rs2+i] != 0) {
-        tmp = mat[rs2+i];
-        mat[rs2+i] = 0; 
-        for (k = 0; k < cols; k++) {
-          inv[rs2+k] ^= galois_single_multiply(tmp, inv[row_start+k], w);
-        }
-      }
-    }
-  }
-  return 0;
-}
-
-int jerasure_invertible_matrix(int *mat, int rows, int w)
-{
-  int cols, i, j, k, x, rs2;
-  int row_start, tmp, inverse;
- 
-  cols = rows;
-
-  /* First -- convert into upper triangular  */
-  for (i = 0; i < cols; i++) {
-    row_start = cols*i;
-
-    /* Swap rows if we ave a zero i,i element.  If we can't swap, then the 
-       matrix was not invertible  */
-
-    if (mat[row_start+i] == 0) { 
-      for (j = i+1; j < rows && mat[cols*j+i] == 0; j++) ;
-      if (j == rows) return 0;
-      rs2 = j*cols;
-      for (k = 0; k < cols; k++) {
-        tmp = mat[row_start+k];
-        mat[row_start+k] = mat[rs2+k];
-        mat[rs2+k] = tmp;
-      }
-    }
- 
-    /* Multiply the row by 1/element i,i  */
-    tmp = mat[row_start+i];
-    if (tmp != 1) {
-      inverse = galois_single_divide(1, tmp, w);
-      for (j = 0; j < cols; j++) { 
-        mat[row_start+j] = galois_single_multiply(mat[row_start+j], inverse, w);
-      }
-    }
-
-    /* Now for each j>i, add A_ji*Ai to Aj  */
-    k = row_start+i;
-    for (j = i+1; j != cols; j++) {
-      k += cols;
-      if (mat[k] != 0) {
-        if (mat[k] == 1) {
-          rs2 = cols*j;
-          for (x = 0; x < cols; x++) {
-            mat[rs2+x] ^= mat[row_start+x];
-          }
-        } else {
-          tmp = mat[k];
-          rs2 = cols*j;
-          for (x = 0; x < cols; x++) {
-            mat[rs2+x] ^= galois_single_multiply(tmp, mat[row_start+x], w);
-          }
-        }
-      }
-    }
-  }
-  return 1;
-}
-
-/* Converts a list-style version of the erasures into an array of k+m elements
-   where the element = 1 if the index has been erased, and zero otherwise */
-
-int *jerasure_erasures_to_erased(int k, int m, int *erasures)
-{
-  int td;
-  int t_non_erased;
-  int *erased;
-  int i;
-
-  td = k+m;
-  erased = talloc(int, td);
-  if (erased == NULL) return NULL;
-  t_non_erased = td;
-
-  for (i = 0; i < td; i++) erased[i] = 0;
-
-  for (i = 0; erasures[i] != -1; i++) {
-    if (erased[erasures[i]] == 0) {
-      erased[erasures[i]] = 1;
-      t_non_erased--;
-      if (t_non_erased < k) {
-        free(erased);
-        return NULL;
-      }
-    }
-  }
-  return erased;
-}
-  
-void jerasure_free_schedule(int **schedule)
-{
-  int i;
-
-  for (i = 0; schedule[i][0] >= 0; i++) free(schedule[i]);
-  free(schedule[i]);
-  free(schedule);
-}
-
-void jerasure_free_schedule_cache(int k, int m, int ***cache)
-{
-  int e1, e2;
-
-  if (m != 2) {
-    fprintf(stderr, "jerasure_free_schedule_cache(): m must equal 2\n");
-    assert(0);
-  }
-
-  for (e1 = 0; e1 < k+m; e1++) {
-    for (e2 = 0; e2 < e1; e2++) {
-      jerasure_free_schedule(cache[e1*(k+m)+e2]);
-    }
-    jerasure_free_schedule(cache[e1*(k+m)+e1]);
-  }
-  free(cache);
-}
-
-void jerasure_matrix_dotprod(int k, int w, int *matrix_row,
-                          int *src_ids, int dest_id,
-                          char **data_ptrs, char **coding_ptrs, int size)
-{
-  int init;
-  char *dptr, *sptr;
-  int i;
-
-  if (w != 1 && w != 8 && w != 16 && w != 32) {
-    fprintf(stderr, "ERROR: jerasure_matrix_dotprod() called and w is not 1, 8, 16 or 32\n");
-    assert(0);
-  }
-
-  init = 0;
-
-  dptr = (dest_id < k) ? data_ptrs[dest_id] : coding_ptrs[dest_id-k];
-
-  /* First copy or xor any data that does not need to be multiplied by a factor */
-
-  for (i = 0; i < k; i++) {
-    if (matrix_row[i] == 1) {
-      if (src_ids == NULL) {
-        sptr = data_ptrs[i];
-      } else if (src_ids[i] < k) {
-        sptr = data_ptrs[src_ids[i]];
-      } else {
-        sptr = coding_ptrs[src_ids[i]-k];
-      }
-      if (init == 0) {
-        memcpy(dptr, sptr, size);
-        jerasure_total_memcpy_bytes += size;
-        init = 1;
-      } else {
-        galois_region_xor(sptr, dptr, size);
-        jerasure_total_xor_bytes += size;
-      }
-    }
-  }
-
-  /* Now do the data that needs to be multiplied by a factor */
-
-  for (i = 0; i < k; i++) {
-    if (matrix_row[i] != 0 && matrix_row[i] != 1) {
-      if (src_ids == NULL) {
-        sptr = data_ptrs[i];
-      } else if (src_ids[i] < k) {
-        sptr = data_ptrs[src_ids[i]];
-      } else {
-        sptr = coding_ptrs[src_ids[i]-k];
-      }
-      switch (w) {
-        case 8:  galois_w08_region_multiply(sptr, matrix_row[i], size, dptr, init); break;
-        case 16: galois_w16_region_multiply(sptr, matrix_row[i], size, dptr, init); break;
-        case 32: galois_w32_region_multiply(sptr, matrix_row[i], size, dptr, init); break;
-      }
-      jerasure_total_gf_bytes += size;
-      init = 1;
-    }
-  }
-}
-
-
-int jerasure_bitmatrix_decode(int k, int m, int w, int *bitmatrix, int row_k_ones, int *erasures,
-                            char **data_ptrs, char **coding_ptrs, int size, int packetsize)
-{
-  int i;
-  int *erased;
-  int *decoding_matrix;
-  int *dm_ids;
-  int edd, *tmpids, lastdrive;
-  
-  erased = jerasure_erasures_to_erased(k, m, erasures);
-  if (erased == NULL) return -1;
-
-  /* See jerasure_matrix_decode for the logic of this routine.  This one works just like
-     it, but calls the bitmatrix ops instead */
-
-  lastdrive = k;
-    
-  edd = 0;
-  for (i = 0; i < k; i++) {
-    if (erased[i]) {
-      edd++;
-      lastdrive = i;
-    } 
-  }
-
-  if (row_k_ones != 1 || erased[k]) lastdrive = k;
-  
-  dm_ids = NULL;
-  decoding_matrix = NULL;
-  
-  if (edd > 1 || (edd > 0 && (row_k_ones != 1 || erased[k]))) {
-
-    dm_ids = talloc(int, k);
-    if (dm_ids == NULL) {
-      free(erased);
-      return -1;
-    }
-  
-    decoding_matrix = talloc(int, k*k*w*w);
-    if (decoding_matrix == NULL) {
-      free(erased);
-      free(dm_ids);
-      return -1;
-    }
-  
-    if (jerasure_make_decoding_bitmatrix(k, m, w, bitmatrix, erased, decoding_matrix, dm_ids) < 0) {
-      free(erased);
-      free(dm_ids);
-      free(decoding_matrix);
-      return -1;
-    }
-  }
-
-  for (i = 0; edd > 0 && i < lastdrive; i++) {
-    if (erased[i]) {
-      jerasure_bitmatrix_dotprod(k, w, decoding_matrix+i*k*w*w, dm_ids, i, data_ptrs, coding_ptrs, size, packetsize);
-      edd--;
-    }
-  }
-
-  if (edd > 0) {
-    tmpids = talloc(int, k);
-    for (i = 0; i < k; i++) {
-      tmpids[i] = (i < lastdrive) ? i : i+1;
-    }
-    jerasure_bitmatrix_dotprod(k, w, bitmatrix, tmpids, lastdrive, data_ptrs, coding_ptrs, size, packetsize);
-    free(tmpids);
-  }
-
-  for (i = 0; i < m; i++) {
-    if (erased[k+i]) {
-      jerasure_bitmatrix_dotprod(k, w, bitmatrix+i*k*w*w, NULL, k+i, data_ptrs, coding_ptrs, size, packetsize);
-    }
-  }
-
-  free(erased);
-  if (dm_ids != NULL) free(dm_ids);
-  if (decoding_matrix != NULL) free(decoding_matrix);
-
-  return 0;
-}
-
-static char **set_up_ptrs_for_scheduled_decoding(int k, int m, int *erasures, char **data_ptrs, char **coding_ptrs)
-{
-  int ddf, cdf;
-  int *erased;
-  char **ptrs;
-  int i, j, x;
-
-  ddf = 0;
-  cdf = 0;
-  for (i = 0; erasures[i] != -1; i++) {
-    if (erasures[i] < k) ddf++; else cdf++;
-  }
-  
-  erased = jerasure_erasures_to_erased(k, m, erasures);
-  if (erased == NULL) return NULL;
-
-  /* Set up ptrs.  It will be as follows:
-
-       - If data drive i has not failed, then ptrs[i] = data_ptrs[i].
-       - If data drive i has failed, then ptrs[i] = coding_ptrs[j], where j is the 
-            lowest unused non-failed coding drive.
-       - Elements k to k+ddf-1 are data_ptrs[] of the failed data drives.
-       - Elements k+ddf to k+ddf+cdf-1 are coding_ptrs[] of the failed data drives.
-
-       The array row_ids contains the ids of ptrs.
-       The array ind_to_row_ids contains the row_id of drive i.
-  
-       However, we're going to set row_ids and ind_to_row in a different procedure.
-   */
-         
-  ptrs = talloc(char *, k+m);
-
-  j = k;
-  x = k;
-  for (i = 0; i < k; i++) {
-    if (erased[i] == 0) {
-      ptrs[i] = data_ptrs[i];
-    } else {
-      while (erased[j]) j++;
-      ptrs[i] = coding_ptrs[j-k];
-      j++;
-      ptrs[x] = data_ptrs[i];
-      x++;
-    }
-  }
-  for (i = k; i < k+m; i++) {
-    if (erased[i]) {
-      ptrs[x] = coding_ptrs[i-k];
-      x++;
-    }
-  }
-  free(erased);
-  return ptrs;
-}
-
-static int set_up_ids_for_scheduled_decoding(int k, int m, int *erasures, int *row_ids, int *ind_to_row)
-{
-  int ddf, cdf;
-  int *erased;
-  int i, j, x;
-
-  ddf = 0;
-  cdf = 0;
-  for (i = 0; erasures[i] != -1; i++) {
-    if (erasures[i] < k) ddf++; else cdf++;
-  }
-  
-  erased = jerasure_erasures_to_erased(k, m, erasures);
-  if (erased == NULL) return -1;
-
-  /* See set_up_ptrs_for_scheduled_decoding for how these are set */
-
-  j = k;
-  x = k;
-  for (i = 0; i < k; i++) {
-    if (erased[i] == 0) {
-      row_ids[i] = i;
-      ind_to_row[i] = i;
-    } else {
-      while (erased[j]) j++;
-      row_ids[i] = j;
-      ind_to_row[j] = i;
-      j++;
-      row_ids[x] = i;
-      ind_to_row[i] = x;
-      x++;
-    }
-  }
-  for (i = k; i < k+m; i++) {
-    if (erased[i]) {
-      row_ids[x] = i;
-      ind_to_row[i] = x;
-      x++;
-    }
-  }
-  free(erased);
-  return 0;
-}
-
-static int **jerasure_generate_decoding_schedule(int k, int m, int w, int *bitmatrix, int *erasures, int smart)
-{
-  int i, j, x, drive, y, index, z;
-  int *decoding_matrix, *inverse, *real_decoding_matrix;
-  int *ptr;
-  int *row_ids;
-  int *ind_to_row;
-  int ddf, cdf;
-  int **schedule;
-  int *b1, *b2;
- 
- /* First, figure out the number of data drives that have failed, and the
-    number of coding drives that have failed: ddf and cdf */
-
-  ddf = 0;
-  cdf = 0;
-  for (i = 0; erasures[i] != -1; i++) {
-    if (erasures[i] < k) ddf++; else cdf++;
-  }
-  
-  row_ids = talloc(int, k+m);
-  ind_to_row = talloc(int, k+m);
-
-  if (set_up_ids_for_scheduled_decoding(k, m, erasures, row_ids, ind_to_row) < 0) return NULL;
-
-  /* Now, we're going to create one decoding matrix which is going to 
-     decode everything with one call.  The hope is that the scheduler
-     will do a good job.    This matrix has w*e rows, where e is the
-     number of erasures (ddf+cdf) */
-
-  real_decoding_matrix = talloc(int, k*w*(cdf+ddf)*w);
-
-  /* First, if any data drives have failed, then initialize the first
-     ddf*w rows of the decoding matrix from the standard decoding
-     matrix inversion */
-
-  if (ddf > 0) {
-    
-    decoding_matrix = talloc(int, k*k*w*w);
-    ptr = decoding_matrix;
-    for (i = 0; i < k; i++) {
-      if (row_ids[i] == i) {
-        bzero(ptr, k*w*w*sizeof(int));
-        for (x = 0; x < w; x++) {
-          ptr[x+i*w+x*k*w] = 1;
-        } 
-      } else {
-        memcpy(ptr, bitmatrix+k*w*w*(row_ids[i]-k), k*w*w*sizeof(int));
-      }
-      ptr += (k*w*w);
-    }
-    inverse = talloc(int, k*k*w*w);
-    jerasure_invert_bitmatrix(decoding_matrix, inverse, k*w);
-
-/*    printf("\nMatrix to invert\n");
-    jerasure_print_bitmatrix(decoding_matrix, k*w, k*w, w);
-    printf("\n");
-    printf("\nInverse\n");
-    jerasure_print_bitmatrix(inverse, k*w, k*w, w);
-    printf("\n"); */
-
-    free(decoding_matrix);
-    ptr = real_decoding_matrix;
-    for (i = 0; i < ddf; i++) {
-      memcpy(ptr, inverse+k*w*w*row_ids[k+i], sizeof(int)*k*w*w);
-      ptr += (k*w*w);
-    }
-    free(inverse);
-  } 
-
-  /* Next, here comes the hard part.  For each coding node that needs
-     to be decoded, you start by putting its rows of the distribution
-     matrix into the decoding matrix.  If there were no failed data
-     nodes, then you're done.  However, if there have been failed
-     data nodes, then you need to modify the columns that correspond
-     to the data nodes.  You do that by first zeroing them.  Then
-     whereever there is a one in the distribution matrix, you XOR
-     in the corresponding row from the failed data node's entry in
-     the decoding matrix.  The whole process kind of makes my head
-     spin, but it works.
-   */
-
-  for (x = 0; x < cdf; x++) {
-    drive = row_ids[x+ddf+k]-k;
-    ptr = real_decoding_matrix + k*w*w*(ddf+x);
-    memcpy(ptr, bitmatrix+drive*k*w*w, sizeof(int)*k*w*w);
-
-    for (i = 0; i < k; i++) {
-      if (row_ids[i] != i) {
-        for (j = 0; j < w; j++) {
-          bzero(ptr+j*k*w+i*w, sizeof(int)*w);
-        }
-      }  
-    }
-
-    /* There's the yucky part */
-
-    index = drive*k*w*w;
-    for (i = 0; i < k; i++) {
-      if (row_ids[i] != i) {
-        b1 = real_decoding_matrix+(ind_to_row[i]-k)*k*w*w;
-        for (j = 0; j < w; j++) {
-          b2 = ptr + j*k*w;
-          for (y = 0; y < w; y++) {
-            if (bitmatrix[index+j*k*w+i*w+y]) {
-              for (z = 0; z < k*w; z++) {
-                b2[z] = b2[z] ^ b1[z+y*k*w];
-              }
-            }
-          }
-        }
-      }  
-    }
-  }
-
-/*
-  printf("\n\nReal Decoding Matrix\n\n");
-  jerasure_print_bitmatrix(real_decoding_matrix, (ddf+cdf)*w, k*w, w);
-  printf("\n"); */
-  if (smart) {
-    schedule = jerasure_smart_bitmatrix_to_schedule(k, ddf+cdf, w, real_decoding_matrix);
-  } else {
-    schedule = jerasure_dumb_bitmatrix_to_schedule(k, ddf+cdf, w, real_decoding_matrix);
-  }
-  free(row_ids);
-  free(ind_to_row);
-  free(real_decoding_matrix);
-  return schedule;
-}
-
-int jerasure_schedule_decode_lazy(int k, int m, int w, int *bitmatrix, int *erasures,
-                            char **data_ptrs, char **coding_ptrs, int size, int packetsize, 
-                            int smart)
-{
-  int i, tdone;
-  char **ptrs;
-  int **schedule;
- 
-  ptrs = set_up_ptrs_for_scheduled_decoding(k, m, erasures, data_ptrs, coding_ptrs);
-  if (ptrs == NULL) return -1;
-
-  schedule = jerasure_generate_decoding_schedule(k, m, w, bitmatrix, erasures, smart);
-  if (schedule == NULL) {
-    free(ptrs);
-    return -1;
-  }
-
-  for (tdone = 0; tdone < size; tdone += packetsize*w) {
-  jerasure_do_scheduled_operations(ptrs, schedule, packetsize);
-    for (i = 0; i < k+m; i++) ptrs[i] += (packetsize*w);
-  }
-
-  jerasure_free_schedule(schedule);
-  free(ptrs);
-
-  return 0;
-}
-
-int jerasure_schedule_decode_cache(int k, int m, int w, int ***scache, int *erasures,
-                            char **data_ptrs, char **coding_ptrs, int size, int packetsize)
-{
-  int i, tdone;
-  char **ptrs;
-  int **schedule;
-  int index;
- 
-  if (erasures[1] == -1) {
-    index = erasures[0]*(k+m) + erasures[0];
-  } else if (erasures[2] == -1) {
-    index = erasures[0]*(k+m) + erasures[1];
-  } else {
-    return -1;
-  }
-
-  schedule = scache[index];
-
-  ptrs = set_up_ptrs_for_scheduled_decoding(k, m, erasures, data_ptrs, coding_ptrs);
-  if (ptrs == NULL) return -1;
-
-
-  for (tdone = 0; tdone < size; tdone += packetsize*w) {
-  jerasure_do_scheduled_operations(ptrs, schedule, packetsize);
-    for (i = 0; i < k+m; i++) ptrs[i] += (packetsize*w);
-  }
-
-  free(ptrs);
-
-  return 0;
-}
-
-/* This only works when m = 2 */
-
-int ***jerasure_generate_schedule_cache(int k, int m, int w, int *bitmatrix, int smart)
-{
-  int ***scache;
-  int erasures[3];
-  int e1, e2;
- 
-  /* Ok -- this is yucky, but it's how I'm doing it.  You will make an index out
-     of erasures, which will be  e1*(k+m)+(e2).  If there is no e2, then e2 = e1.
-     Isn't that clever and confusing.  Sorry.
-
-     We're not going to worry about ordering -- in other words, the schedule for
-     e1,e2 will be the same as e2,e1.  They will have the same pointer -- the 
-     schedule will not be duplicated. */
-
-  if (m != 2) return NULL;
-
-  scache = talloc(int **, (k+m)*(k+m+1));
-  if (scache == NULL) return NULL;
-  
-  for (e1 = 0; e1 < k+m; e1++) {
-    erasures[0] = e1;
-    for (e2 = 0; e2 < e1; e2++) {
-      erasures[1] = e2;
-      erasures[2] = -1;
-      scache[e1*(k+m)+e2] = jerasure_generate_decoding_schedule(k, m, w, bitmatrix, erasures, smart);
-      scache[e2*(k+m)+e1] = scache[e1*(k+m)+e2];
-    }
-    erasures[1] = -1;
-    scache[e1*(k+m)+e1] = jerasure_generate_decoding_schedule(k, m, w, bitmatrix, erasures, smart);
-  }
-  return scache;
-
-}
-
-int jerasure_invert_bitmatrix(int *mat, int *inv, int rows)
-{
-  int cols, i, j, k;
-  int tmp;
- 
-  cols = rows;
-
-  k = 0;
-  for (i = 0; i < rows; i++) {
-    for (j = 0; j < cols; j++) {
-      inv[k] = (i == j) ? 1 : 0;
-      k++;
-    }
-  }
-
-  /* First -- convert into upper triangular */
-
-  for (i = 0; i < cols; i++) {
-
-    /* Swap rows if we have a zero i,i element.  If we can't swap, then the 
-       matrix was not invertible */
-
-    if ((mat[i*cols+i]) == 0) { 
-      for (j = i+1; j < rows && (mat[j*cols+i]) == 0; j++) ;
-      if (j == rows) return -1;
-      for (k = 0; k < cols; k++) {
-        tmp = mat[i*cols+k]; mat[i*cols+k] = mat[j*cols+k]; mat[j*cols+k] = tmp;
-        tmp = inv[i*cols+k]; inv[i*cols+k] = inv[j*cols+k]; inv[j*cols+k] = tmp;
-      }
-    }
- 
-    /* Now for each j>i, add A_ji*Ai to Aj */
-    for (j = i+1; j != rows; j++) {
-      if (mat[j*cols+i] != 0) {
-        for (k = 0; k < cols; k++) {
-          mat[j*cols+k] ^= mat[i*cols+k]; 
-          inv[j*cols+k] ^= inv[i*cols+k];
-        }
-      }
-    }
-  }
-
-  /* Now the matrix is upper triangular.  Start at the top and multiply down */
-
-  for (i = rows-1; i >= 0; i--) {
-    for (j = 0; j < i; j++) {
-      if (mat[j*cols+i]) {
-        for (k = 0; k < cols; k++) {
-          mat[j*cols+k] ^= mat[i*cols+k]; 
-          inv[j*cols+k] ^= inv[i*cols+k];
-        }
-      }
-    }
-  } 
-  return 0;
-}
-
-int jerasure_invertible_bitmatrix(int *mat, int rows)
-{
-  int cols, i, j, k;
-  int tmp;
- 
-  cols = rows;
-
-  /* First -- convert into upper triangular */
-
-  for (i = 0; i < cols; i++) {
-
-    /* Swap rows if we have a zero i,i element.  If we can't swap, then the 
-       matrix was not invertible */
-
-    if ((mat[i*cols+i]) == 0) { 
-      for (j = i+1; j < rows && (mat[j*cols+i]) == 0; j++) ;
-      if (j == rows) return 0;
-      for (k = 0; k < cols; k++) {
-        tmp = mat[i*cols+k]; mat[i*cols+k] = mat[j*cols+k]; mat[j*cols+k] = tmp;
-      }
-    }
- 
-    /* Now for each j>i, add A_ji*Ai to Aj */
-    for (j = i+1; j != rows; j++) {
-      if (mat[j*cols+i] != 0) {
-        for (k = 0; k < cols; k++) {
-          mat[j*cols+k] ^= mat[i*cols+k]; 
-        }
-      }
-    }
-  }
-  return 1;
-}
-
-  
-int *jerasure_matrix_multiply(int *m1, int *m2, int r1, int c1, int r2, int c2, int w)
-{
-  int *product, i, j, k;
-
-  product = (int *) malloc(sizeof(int)*r1*c2);
-  for (i = 0; i < r1*c2; i++) product[i] = 0;
-
-  for (i = 0; i < r1; i++) {
-    for (j = 0; j < c2; j++) {
-      for (k = 0; k < r2; k++) {
-        product[i*c2+j] ^= galois_single_multiply(m1[i*c1+k], m2[k*c2+j], w);
-      }
-    }
-  }
-  return product;
-}
-
-void jerasure_get_stats(double *fill_in)
-{
-  fill_in[0] = jerasure_total_xor_bytes;
-  fill_in[1] = jerasure_total_gf_bytes;
-  fill_in[2] = jerasure_total_memcpy_bytes;
-  jerasure_total_xor_bytes = 0;
-  jerasure_total_gf_bytes = 0;
-  jerasure_total_memcpy_bytes = 0;
-}
-
-void jerasure_do_scheduled_operations(char **ptrs, int **operations, int packetsize)
-{
-  char *sptr;
-  char *dptr;
-  int op;
-
-  for (op = 0; operations[op][0] >= 0; op++) {
-    sptr = ptrs[operations[op][0]] + operations[op][1]*packetsize;
-    dptr = ptrs[operations[op][2]] + operations[op][3]*packetsize;
-    if (operations[op][4]) {
-/*      printf("%d,%d %d,%d\n", operations[op][0], 
-      operations[op][1], 
-      operations[op][2], 
-      operations[op][3]); 
-      printf("xor(0x%x, 0x%x -> 0x%x, %d)\n", sptr, dptr, dptr, packetsize); */
-      galois_region_xor(sptr, dptr, packetsize);
-      jerasure_total_xor_bytes += packetsize;
-    } else {
-/*      printf("memcpy(0x%x <- 0x%x)\n", dptr, sptr); */
-      memcpy(dptr, sptr, packetsize);
-      jerasure_total_memcpy_bytes += packetsize;
-    }
-  }  
-}
-
-void jerasure_schedule_encode(int k, int m, int w, int **schedule,
-                                   char **data_ptrs, char **coding_ptrs, int size, int packetsize)
-{
-  char **ptr_copy;
-  int i, tdone;
-
-  ptr_copy = talloc(char *, (k+m));
-  for (i = 0; i < k; i++) ptr_copy[i] = data_ptrs[i];
-  for (i = 0; i < m; i++) ptr_copy[i+k] = coding_ptrs[i];
-  for (tdone = 0; tdone < size; tdone += packetsize*w) {
-    jerasure_do_scheduled_operations(ptr_copy, schedule, packetsize);
-    for (i = 0; i < k+m; i++) ptr_copy[i] += (packetsize*w);
-  }
-  free(ptr_copy);
-}
-    
-int **jerasure_dumb_bitmatrix_to_schedule(int k, int m, int w, int *bitmatrix)
-{
-  int **operations;
-  int op;
-  int index, optodo, i, j;
-
-  operations = talloc(int *, k*m*w*w+1);
-  op = 0;
-  
-  index = 0;
-  for (i = 0; i < m*w; i++) {
-    optodo = 0;
-    for (j = 0; j < k*w; j++) {
-      if (bitmatrix[index]) {
-        operations[op] = talloc(int, 5);
-        operations[op][4] = optodo;
-        operations[op][0] = j/w;
-        operations[op][1] = j%w;
-        operations[op][2] = k+i/w;
-        operations[op][3] = i%w;
-        optodo = 1;
-        op++;
-        
-      }
-      index++;
-    }
-  }
-  operations[op] = talloc(int, 5);
-  operations[op][0] = -1;
-  return operations;
-}
-
-int **jerasure_smart_bitmatrix_to_schedule(int k, int m, int w, int *bitmatrix)
-{
-  int **operations;
-  int op;
-  int i, j;
-  int *diff, *from, *b1, *flink, *blink;
-  int *ptr, no, row;
-  int optodo;
-  int bestrow = 0, bestdiff, top;
-
-/*   printf("Scheduling:\n\n");
-  jerasure_print_bitmatrix(bitmatrix, m*w, k*w, w); */
-
-  operations = talloc(int *, k*m*w*w+1);
-  op = 0;
-  
-  diff = talloc(int, m*w);
-  from = talloc(int, m*w);
-  flink = talloc(int, m*w);
-  blink = talloc(int, m*w);
-
-  ptr = bitmatrix;
-
-  bestdiff = k*w+1;
-  top = 0;
-  for (i = 0; i < m*w; i++) {
-    no = 0;
-    for (j = 0; j < k*w; j++) {
-      no += *ptr;
-      ptr++;
-    }
-    diff[i] = no;
-    from[i] = -1;
-    flink[i] = i+1;
-    blink[i] = i-1;
-    if (no < bestdiff) {
-      bestdiff = no;
-      bestrow = i;
-    }
-  }
-
-  flink[m*w-1] = -1;
-  
-  while (top != -1) {
-    row = bestrow;
-    /* printf("Doing row %d - %d from %d\n", row, diff[row], from[row]);  */
-
-    if (blink[row] == -1) {
-      top = flink[row];
-      if (top != -1) blink[top] = -1;
-    } else {
-      flink[blink[row]] = flink[row];
-      if (flink[row] != -1) {
-        blink[flink[row]] = blink[row];
-      }
-    }
-
-    ptr = bitmatrix + row*k*w;
-    if (from[row] == -1) {
-      optodo = 0;
-      for (j = 0; j < k*w; j++) {
-        if (ptr[j]) {
-          operations[op] = talloc(int, 5);
-          operations[op][4] = optodo;
-          operations[op][0] = j/w;
-          operations[op][1] = j%w;
-          operations[op][2] = k+row/w;
-          operations[op][3] = row%w;
-          optodo = 1;
-          op++;
-        }
-      }
-    } else {
-      operations[op] = talloc(int, 5);
-      operations[op][4] = 0;
-      operations[op][0] = k+from[row]/w;
-      operations[op][1] = from[row]%w;
-      operations[op][2] = k+row/w;
-      operations[op][3] = row%w;
-      op++;
-      b1 = bitmatrix + from[row]*k*w;
-      for (j = 0; j < k*w; j++) {
-        if (ptr[j] ^ b1[j]) {
-          operations[op] = talloc(int, 5);
-          operations[op][4] = 1;
-          operations[op][0] = j/w;
-          operations[op][1] = j%w;
-          operations[op][2] = k+row/w;
-          operations[op][3] = row%w;
-          optodo = 1;
-          op++;
-        }
-      }
-    }
-    bestdiff = k*w+1;
-    for (i = top; i != -1; i = flink[i]) {
-      no = 1;
-      b1 = bitmatrix + i*k*w;
-      for (j = 0; j < k*w; j++) no += (ptr[j] ^ b1[j]);
-      if (no < diff[i]) {
-        from[i] = row;
-        diff[i] = no;
-      }
-      if (diff[i] < bestdiff) {
-        bestdiff = diff[i];
-        bestrow = i;
-      }
-    }
-  }
-  
-  operations[op] = talloc(int, 5);
-  operations[op][0] = -1;
-  free(from);
-  free(diff);
-  free(blink);
-  free(flink);
-
-  return operations;
-}
-
-void jerasure_bitmatrix_encode(int k, int m, int w, int *bitmatrix,
-                            char **data_ptrs, char **coding_ptrs, int size, int packetsize)
-{
-  int i;
-
-  if (packetsize%sizeof(long) != 0) {
-    fprintf(stderr, "jerasure_bitmatrix_encode - packetsize(%d) %c sizeof(long) != 0\n", packetsize, '%');
-    assert(0);
-  }
-  if (size%(packetsize*w) != 0) {
-    fprintf(stderr, "jerasure_bitmatrix_encode - size(%d) %c (packetsize(%d)*w(%d))) != 0\n", 
-         size, '%', packetsize, w);
-    assert(0);
-  }
-
-  for (i = 0; i < m; i++) {
-    jerasure_bitmatrix_dotprod(k, w, bitmatrix+i*k*w*w, NULL, k+i, data_ptrs, coding_ptrs, size, packetsize);
-  }
-}
-
-/*
- * Exported function for use by autoconf to perform quick 
- * spot-check.
- */
-int jerasure_autoconf_test()
-{
-  int x = galois_single_multiply(1, 2, 8);
-  if (x != 2) {
-    return -1;
-  }
-  return 0;
-}
-
diff --git a/src/erasure-code/jerasure/jerasure/src/liberation.c b/src/erasure-code/jerasure/jerasure/src/liberation.c
deleted file mode 100644
index 11a1c4f..0000000
--- a/src/erasure-code/jerasure/jerasure/src/liberation.c
+++ /dev/null
@@ -1,262 +0,0 @@
-/* *
- * Copyright (c) 2014, James S. Plank and Kevin Greenan
- * All rights reserved.
- *
- * Jerasure - A C/C++ Library for a Variety of Reed-Solomon and RAID-6 Erasure
- * Coding Techniques
- *
- * Revision 2.0: Galois Field backend now links to GF-Complete
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- *  - Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *
- *  - Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- *  - Neither the name of the University of Tennessee nor the names of its
- *    contributors may be used to endorse or promote products derived
- *    from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
- * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
- * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
- * WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-/* Jerasure's authors:
-
-   Revision 2.x - 2014: James S. Plank and Kevin M. Greenan
-   Revision 1.2 - 2008: James S. Plank, Scott Simmerman and Catherine D. Schuman.
-   Revision 1.0 - 2007: James S. Plank
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "galois.h"
-#include "jerasure.h"
-#include "liberation.h"
-
-#define talloc(type, num) (type *) malloc(sizeof(type)*(num))
-
-int *liberation_coding_bitmatrix(int k, int w)
-{
-  int *matrix, i, j, index;
-
-  if (k > w) return NULL;
-  matrix = talloc(int, 2*k*w*w);
-  if (matrix == NULL) return NULL;
-  bzero(matrix, sizeof(int)*2*k*w*w);
-  
-  /* Set up identity matrices */
-
-  for(i = 0; i < w; i++) {
-    index = i*k*w+i;
-    for (j = 0; j < k; j++) {
-      matrix[index] = 1;
-      index += w;
-    }
-  }
-
-  /* Set up liberation matrices */
-
-  for (j = 0; j < k; j++) {
-    index = k*w*w+j*w;
-    for (i = 0; i < w; i++) {
-      matrix[index+(j+i)%w] = 1;
-      index += (k*w);
-    }
-    if (j > 0) {
-      i = (j*((w-1)/2))%w;
-      matrix[k*w*w+j*w+i*k*w+(i+j-1)%w] = 1;
-    }
-  }
-  return matrix;
-}
-  
-
-int *liber8tion_coding_bitmatrix(int k)
-{
-  int *matrix, i, j, index;
-  int w;
-
-  w = 8;
-  if (k > w) return NULL;
-  matrix = talloc(int, 2*k*w*w);
-  if (matrix == NULL) return NULL;
-  bzero(matrix, sizeof(int)*2*k*w*w);
-  
-  /* Set up identity matrices */
-
-  for(i = 0; i < w; i++) {
-    index = i*k*w+i;
-    for (j = 0; j < k; j++) {
-      matrix[index] = 1;
-      index += w;
-    }
-  }
-
-  /* Set up liber8tion matrices */
-
-  index = k*w*w;
-
-  if (k == 0) return matrix;
-  matrix[index+0*k*w+0*w+0] = 1;
-  matrix[index+1*k*w+0*w+1] = 1;
-  matrix[index+2*k*w+0*w+2] = 1;
-  matrix[index+3*k*w+0*w+3] = 1;
-  matrix[index+4*k*w+0*w+4] = 1;
-  matrix[index+5*k*w+0*w+5] = 1;
-  matrix[index+6*k*w+0*w+6] = 1;
-  matrix[index+7*k*w+0*w+7] = 1;
-
-  if (k == 1) return matrix;
-  matrix[index+0*k*w+1*w+7] = 1;
-  matrix[index+1*k*w+1*w+3] = 1;
-  matrix[index+2*k*w+1*w+0] = 1;
-  matrix[index+3*k*w+1*w+2] = 1;
-  matrix[index+4*k*w+1*w+6] = 1;
-  matrix[index+5*k*w+1*w+1] = 1;
-  matrix[index+6*k*w+1*w+5] = 1;
-  matrix[index+7*k*w+1*w+4] = 1;
-  matrix[index+4*k*w+1*w+7] = 1;
-
-  if (k == 2) return matrix;
-  matrix[index+0*k*w+2*w+6] = 1;
-  matrix[index+1*k*w+2*w+2] = 1;
-  matrix[index+2*k*w+2*w+4] = 1;
-  matrix[index+3*k*w+2*w+0] = 1;
-  matrix[index+4*k*w+2*w+7] = 1;
-  matrix[index+5*k*w+2*w+3] = 1;
-  matrix[index+6*k*w+2*w+1] = 1;
-  matrix[index+7*k*w+2*w+5] = 1;
-  matrix[index+1*k*w+2*w+3] = 1;
-
-  if (k == 3) return matrix;
-  matrix[index+0*k*w+3*w+2] = 1;
-  matrix[index+1*k*w+3*w+5] = 1;
-  matrix[index+2*k*w+3*w+7] = 1;
-  matrix[index+3*k*w+3*w+6] = 1;
-  matrix[index+4*k*w+3*w+0] = 1;
-  matrix[index+5*k*w+3*w+3] = 1;
-  matrix[index+6*k*w+3*w+4] = 1;
-  matrix[index+7*k*w+3*w+1] = 1;
-  matrix[index+5*k*w+3*w+4] = 1;
-
-  if (k == 4) return matrix;
-  matrix[index+0*k*w+4*w+5] = 1;
-  matrix[index+1*k*w+4*w+6] = 1;
-  matrix[index+2*k*w+4*w+1] = 1;
-  matrix[index+3*k*w+4*w+7] = 1;
-  matrix[index+4*k*w+4*w+2] = 1;
-  matrix[index+5*k*w+4*w+4] = 1;
-  matrix[index+6*k*w+4*w+3] = 1;
-  matrix[index+7*k*w+4*w+0] = 1;
-  matrix[index+2*k*w+4*w+0] = 1;
-
-  if (k == 5) return matrix;
-  matrix[index+0*k*w+5*w+1] = 1;
-  matrix[index+1*k*w+5*w+2] = 1;
-  matrix[index+2*k*w+5*w+3] = 1;
-  matrix[index+3*k*w+5*w+4] = 1;
-  matrix[index+4*k*w+5*w+5] = 1;
-  matrix[index+5*k*w+5*w+6] = 1;
-  matrix[index+6*k*w+5*w+7] = 1;
-  matrix[index+7*k*w+5*w+0] = 1;
-  matrix[index+7*k*w+5*w+2] = 1;
-
-  if (k == 6) return matrix;
-  matrix[index+0*k*w+6*w+3] = 1;
-  matrix[index+1*k*w+6*w+0] = 1;
-  matrix[index+2*k*w+6*w+6] = 1;
-  matrix[index+3*k*w+6*w+5] = 1;
-  matrix[index+4*k*w+6*w+1] = 1;
-  matrix[index+5*k*w+6*w+7] = 1;
-  matrix[index+6*k*w+6*w+4] = 1;
-  matrix[index+7*k*w+6*w+2] = 1;
-  matrix[index+6*k*w+6*w+5] = 1;
-
-  if (k == 7) return matrix;
-  matrix[index+0*k*w+7*w+4] = 1;
-  matrix[index+1*k*w+7*w+7] = 1;
-  matrix[index+2*k*w+7*w+1] = 1;
-  matrix[index+3*k*w+7*w+5] = 1;
-  matrix[index+4*k*w+7*w+3] = 1;
-  matrix[index+5*k*w+7*w+2] = 1;
-  matrix[index+6*k*w+7*w+0] = 1;
-  matrix[index+7*k*w+7*w+6] = 1;
-  matrix[index+3*k*w+7*w+1] = 1;
-
-  return matrix;
-}
-  
-int *blaum_roth_coding_bitmatrix(int k, int w)
-{
-  int *matrix, i, j, index, l, m, p;
-
-  if (k > w) return NULL ;
-
-  matrix = talloc(int, 2*k*w*w);
-  if (matrix == NULL) return NULL;
-  bzero(matrix, sizeof(int)*2*k*w*w);
-  
-  /* Set up identity matrices */
-
-  for(i = 0; i < w; i++) {
-    index = i*k*w+i;
-    for (j = 0; j < k; j++) {
-      matrix[index] = 1;
-      index += w;
-    }
-  }
-
-  /* Set up blaum_roth matrices -- Ignore identity */
-
-  p = w+1;
-  for (j = 0; j < k; j++) {
-    index = k*w*w+j*w;
-    if (j == 0) {
-      for (l = 0; l < w; l++) {
-        matrix[index+l] = 1;
-        index += k*w;
-      }
-    } else {
-      i = j;
-      for (l = 1; l <= w; l++) {
-        if (l != p-i) {
-          m = l+i;
-          if (m >= p) m -= p;
-          m--;
-          matrix[index+m] = 1;
-        } else {
-          matrix[index+i-1] = 1;
-          if (i%2 == 0) {
-            m = i/2;
-          } else {
-            m = (p/2) + 1 + (i/2);
-          }
-          m--;
-          matrix[index+m] = 1;
-        }
-        index += k*w;
-      }
-    }
-  }
-
-  return matrix;
-}
diff --git a/src/erasure-code/jerasure/jerasure/src/reed_sol.c b/src/erasure-code/jerasure/jerasure/src/reed_sol.c
deleted file mode 100644
index 82edacb..0000000
--- a/src/erasure-code/jerasure/jerasure/src/reed_sol.c
+++ /dev/null
@@ -1,302 +0,0 @@
-/* *
- * Copyright (c) 2014, James S. Plank and Kevin Greenan
- * All rights reserved.
- *
- * Jerasure - A C/C++ Library for a Variety of Reed-Solomon and RAID-6 Erasure
- * Coding Techniques
- *
- * Revision 2.0: Galois Field backend now links to GF-Complete
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- *  - Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *
- *  - Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- *  - Neither the name of the University of Tennessee nor the names of its
- *    contributors may be used to endorse or promote products derived
- *    from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
- * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
- * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
- * WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-/* Jerasure's authors:
-
-   Revision 2.x - 2014: James S. Plank and Kevin M. Greenan
-   Revision 1.2 - 2008: James S. Plank, Scott Simmerman and Catherine D. Schuman.
-   Revision 1.0 - 2007: James S. Plank
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <assert.h>
-
-#include <gf_complete.h>
-#include "galois.h"
-#include "jerasure.h"
-#include "reed_sol.h"
-
-#define talloc(type, num) (type *) malloc(sizeof(type)*(num))
-
-int *reed_sol_r6_coding_matrix(int k, int w)
-{
-  int *matrix;
-  int i, tmp;
-
-  if (w != 8 && w != 16 && w != 32) return NULL;
-
-  matrix = talloc(int, 2*k);
-  if (matrix == NULL) return NULL;
-
-  for (i = 0; i < k; i++) matrix[i] = 1;
-  matrix[k] = 1;
-  tmp = 1;
-  for (i = 1; i < k; i++) {
-    tmp = galois_single_multiply(tmp, 2, w);
-    matrix[k+i] = tmp;
-  }
-  return matrix;
-}
-
-int *reed_sol_vandermonde_coding_matrix(int k, int m, int w)
-{
-  int i, j;
-  int *vdm, *dist;
-
-  vdm = reed_sol_big_vandermonde_distribution_matrix(k+m, k, w);
-  if (vdm == NULL) return NULL;
-  dist = talloc(int, m*k);
-  if (dist == NULL) {
-    free(vdm);
-    return NULL;
-  }
-
-  i = k*k;
-  for (j = 0; j < m*k; j++) {
-    dist[j] = vdm[i];
-    i++;
-  }
-  free(vdm);
-  return dist;
-}
-
-static int prim08 = -1;
-static gf_t GF08;
-
-void reed_sol_galois_w08_region_multby_2(char *region, int nbytes)
-{
-  if (prim08 == -1) {
-    prim08 = galois_single_multiply((1 << 7), 2, 8);
-    if (!gf_init_hard(&GF08, 8, GF_MULT_BYTWO_b, GF_REGION_DEFAULT, GF_DIVIDE_DEFAULT,
-                      prim08, 0, 0, NULL, NULL)) {
-      fprintf(stderr, "Error: Can't initialize the GF for reed_sol_galois_w08_region_multby_2\n");
-      assert(0);
-    }
-  }
-  GF08.multiply_region.w32(&GF08, region, region, 2, nbytes, 0);
-}
-
-static int prim16 = -1;
-static gf_t GF16;
-
-void reed_sol_galois_w16_region_multby_2(char *region, int nbytes)
-{
-  if (prim16 == -1) {
-    prim16 = galois_single_multiply((1 << 15), 2, 16);
-    if (!gf_init_hard(&GF16, 16, GF_MULT_BYTWO_b, GF_REGION_DEFAULT, GF_DIVIDE_DEFAULT,
-                      prim16, 0, 0, NULL, NULL)) {
-      fprintf(stderr, "Error: Can't initialize the GF for reed_sol_galois_w16_region_multby_2\n");
-      assert(0);
-    }
-  }
-  GF16.multiply_region.w32(&GF16, region, region, 2, nbytes, 0);
-}
-
-static int prim32 = -1;
-static gf_t GF32;
-
-void reed_sol_galois_w32_region_multby_2(char *region, int nbytes)
-{
-  if (prim32 == -1) {
-    prim32 = galois_single_multiply((1 << 31), 2, 32);
-    if (!gf_init_hard(&GF32, 32, GF_MULT_BYTWO_b, GF_REGION_DEFAULT, GF_DIVIDE_DEFAULT,
-                      prim32, 0, 0, NULL, NULL)) {
-      fprintf(stderr, "Error: Can't initialize the GF for reed_sol_galois_w32_region_multby_2\n");
-      assert(0);
-    }
-  }
-  GF32.multiply_region.w32(&GF32, region, region, 2, nbytes, 0);
-}
-
-int reed_sol_r6_encode(int k, int w, char **data_ptrs, char **coding_ptrs, int size)
-{
-  int i;
-
-  /* First, put the XOR into coding region 0 */
-
-  memcpy(coding_ptrs[0], data_ptrs[0], size);
-
-  for (i = 1; i < k; i++) galois_region_xor(data_ptrs[i], coding_ptrs[0], size);
-
-  /* Next, put the sum of (2^j)*Dj into coding region 1 */
-
-  memcpy(coding_ptrs[1], data_ptrs[k-1], size);
-
-  for (i = k-2; i >= 0; i--) {
-    switch (w) {
-      case 8:  reed_sol_galois_w08_region_multby_2(coding_ptrs[1], size); break;
-      case 16: reed_sol_galois_w16_region_multby_2(coding_ptrs[1], size); break;
-      case 32: reed_sol_galois_w32_region_multby_2(coding_ptrs[1], size); break;
-      default: return 0;
-    }
-
-    galois_region_xor(data_ptrs[i], coding_ptrs[1], size);
-  }
-  return 1;
-}
-
-int *reed_sol_extended_vandermonde_matrix(int rows, int cols, int w)
-{
-  int *vdm;
-  int i, j, k;
-
-  if (w < 30 && (1 << w) < rows) return NULL;
-  if (w < 30 && (1 << w) < cols) return NULL;
-
-  vdm = talloc(int, rows*cols);
-  if (vdm == NULL) { return NULL; }
-  
-  vdm[0] = 1;
-  for (j = 1; j < cols; j++) vdm[j] = 0;
-  if (rows == 1) return vdm;
-
-  i=(rows-1)*cols;
-  for (j = 0; j < cols-1; j++) vdm[i+j] = 0;
-  vdm[i+j] = 1;
-  if (rows == 2) return vdm;
-
-  for (i = 1; i < rows-1; i++) {
-    k = 1;
-    for (j = 0; j < cols; j++) {
-      vdm[i*cols+j] = k;
-      k = galois_single_multiply(k, i, w);
-    }
-  }
-  return vdm;
-}
-
-int *reed_sol_big_vandermonde_distribution_matrix(int rows, int cols, int w)
-{
-  int *dist;
-  int i, j, k;
-  int sindex, srindex, siindex, tmp;
-
-  if (cols >= rows) return NULL;
-  
-  dist = reed_sol_extended_vandermonde_matrix(rows, cols, w);
-  if (dist == NULL) return NULL;
-
-  sindex = 0;
-  for (i = 1; i < cols; i++) {
-    sindex += cols;
-
-    /* Find an appropriate row -- where i,i != 0 */
-    srindex = sindex+i;
-    for (j = i; j < rows && dist[srindex] == 0; j++) srindex += cols;
-    if (j >= rows) {   /* This should never happen if rows/w are correct */
-      fprintf(stderr, "reed_sol_big_vandermonde_distribution_matrix(%d,%d,%d) - couldn't make matrix\n", 
-             rows, cols, w);
-      assert(0);
-    }
- 
-    /* If necessary, swap rows */
-    if (j != i) {
-      srindex -= i;
-      for (k = 0; k < cols; k++) {
-        tmp = dist[srindex+k];
-        dist[srindex+k] = dist[sindex+k];
-        dist[sindex+k] = tmp;
-      }
-    }
-  
-    /* If Element i,i is not equal to 1, multiply the column by 1/i */
-
-    if (dist[sindex+i] != 1) {
-      tmp = galois_single_divide(1, dist[sindex+i], w);
-      srindex = i;
-      for (j = 0; j < rows; j++) {
-        dist[srindex] = galois_single_multiply(tmp, dist[srindex], w);
-        srindex += cols;
-      }
-    }
- 
-    /* Now, for each element in row i that is not in column 1, you need
-       to make it zero.  Suppose that this is column j, and the element
-       at i,j = e.  Then you want to replace all of column j with 
-       (col-j + col-i*e).   Note, that in row i, col-i = 1 and col-j = e.
-       So (e + 1e) = 0, which is indeed what we want. */
-
-    for (j = 0; j < cols; j++) {
-      tmp = dist[sindex+j];
-      if (j != i && tmp != 0) {
-        srindex = j;
-        siindex = i;
-        for (k = 0; k < rows; k++) {
-          dist[srindex] = dist[srindex] ^ galois_single_multiply(tmp, dist[siindex], w);
-          srindex += cols;
-          siindex += cols;
-        }
-      }
-    }
-  }
-  /* We desire to have row k be all ones.  To do that, multiply
-     the entire column j by 1/dist[k,j].  Then row j by 1/dist[j,j]. */
-
-  sindex = cols*cols;
-  for (j = 0; j < cols; j++) {
-    tmp = dist[sindex];
-    if (tmp != 1) { 
-      tmp = galois_single_divide(1, tmp, w);
-      srindex = sindex;
-      for (i = cols; i < rows; i++) {
-        dist[srindex] = galois_single_multiply(tmp, dist[srindex], w);
-        srindex += cols;
-      }
-    }
-    sindex++;
-  }
-
-  /* Finally, we'd like the first column of each row to be all ones.  To
-     do that, we multiply the row by the inverse of the first element. */
-
-  sindex = cols*(cols+1);
-  for (i = cols+1; i < rows; i++) {
-    tmp = dist[sindex];
-    if (tmp != 1) { 
-      tmp = galois_single_divide(1, tmp, w);
-      for (j = 0; j < cols; j++) dist[sindex+j] = galois_single_multiply(dist[sindex+j], tmp, w);
-    }
-    sindex += cols;
-  }
-
-  return dist;
-}
-
diff --git a/src/global/Makefile.am b/src/global/Makefile.am
index 51fff4b..ed93426 100644
--- a/src/global/Makefile.am
+++ b/src/global/Makefile.am
@@ -4,6 +4,7 @@ libglobal_la_SOURCES = \
 	global/pidfile.cc \
 	global/signal_handler.cc \
 	common/TrackedOp.cc
+
 libglobal_la_LIBADD = $(LIBCOMMON)
 if WITH_LTTNG
 libglobal_la_LIBADD += -ldl -llttng-ust
diff --git a/src/global/global_init.cc b/src/global/global_init.cc
index 7cbfbd0..bd5f606 100644
--- a/src/global/global_init.cc
+++ b/src/global/global_init.cc
@@ -22,6 +22,7 @@
 #include "common/safe_io.h"
 #include "common/signal.h"
 #include "common/version.h"
+#include "common/admin_socket.h"
 #include "global/global_context.h"
 #include "global/global_init.h"
 #include "global/pidfile.h"
@@ -65,10 +66,8 @@ void global_pre_init(std::vector < const char * > *alt_def_args,
 		     int flags,
 		     const char *data_dir_option)
 {
-  // You can only call global_init once.
-  assert(!g_ceph_context);
   std::string conf_file_list;
-  std::string cluster = "ceph";
+  std::string cluster = "";
   CephInitParameters iparams = ceph_argparse_early_args(args, module_type, flags,
 							&cluster, &conf_file_list);
   CephContext *cct = common_preinit(iparams, code_env, flags, data_dir_option);
@@ -79,8 +78,8 @@ void global_pre_init(std::vector < const char * > *alt_def_args,
   if (alt_def_args)
     conf->parse_argv(*alt_def_args);  // alternative default args
 
-  std::deque<std::string> parse_errors;
-  int ret = conf->parse_config_files(c_str_or_null(conf_file_list), &parse_errors, &cerr, flags);
+  int ret = conf->parse_config_files(c_str_or_null(conf_file_list),
+				     &cerr, flags);
   if (ret == -EDOM) {
     dout_emergency("global_init: error parsing config file.\n");
     _exit(1);
@@ -107,21 +106,27 @@ void global_pre_init(std::vector < const char * > *alt_def_args,
 
   conf->parse_argv(args); // argv override
 
-  // Expand metavariables. Invoke configuration observers.
-  conf->apply_changes(NULL);
-
   // Now we're ready to complain about config file parse errors
-  complain_about_parse_errors(cct, &parse_errors);
+  g_conf->complain_about_parse_errors(g_ceph_context);
 }
 
 void global_init(std::vector < const char * > *alt_def_args,
 		 std::vector < const char* >& args,
 		 uint32_t module_type, code_environment_t code_env,
 		 int flags,
-		 const char *data_dir_option)
+		 const char *data_dir_option, bool run_pre_init)
 {
-  global_pre_init(alt_def_args, args, module_type, code_env, flags,
-		  data_dir_option);
+  // Ensure we're not calling the global init functions multiple times.
+  static bool first_run = true;
+  if (run_pre_init) {
+    // We will run pre_init from here (default).
+    assert(!g_ceph_context && first_run);
+    global_pre_init(alt_def_args, args, module_type, code_env, flags);
+  } else {
+    // Caller should have invoked pre_init manually.
+    assert(g_ceph_context && first_run);
+  }
+  first_run = false;
 
   // signal stuff
   int siglist[] = { SIGPIPE, 0 };
@@ -148,10 +153,13 @@ void global_init(std::vector < const char * > *alt_def_args,
   }
 
   // drop privileges?
+  ostringstream priv_ss;
   if (g_conf->setgroup.length() ||
       g_conf->setuser.length()) {
     uid_t uid = 0;  // zero means no change; we can only drop privs here.
     gid_t gid = 0;
+    std::string uid_string;
+    std::string gid_string;
     if (g_conf->setuser.length()) {
       uid = atoi(g_conf->setuser.c_str());
       if (!uid) {
@@ -166,6 +174,7 @@ void global_init(std::vector < const char * > *alt_def_args,
 	}
 	uid = p->pw_uid;
 	gid = p->pw_gid;
+	uid_string = g_conf->setuser;
       }
     }
     if (g_conf->setgroup.length() > 0) {
@@ -181,6 +190,7 @@ void global_init(std::vector < const char * > *alt_def_args,
 	  exit(1);
 	}
 	gid = g->gr_gid;
+	gid_string = g_conf->setgroup;
       }
     }
     if ((uid || gid) &&
@@ -202,28 +212,38 @@ void global_init(std::vector < const char * > *alt_def_args,
 	     << std::endl;
 	uid = 0;
 	gid = 0;
+	uid_string.erase();
+	gid_string.erase();
       } else {
-	dout(10) << "setuser_match_path "
-		 << g_conf->setuser_match_path << " owned by "
-		 << st.st_uid << ":" << st.st_gid << ", doing setuid/gid"
-		 << dendl;
+	priv_ss << "setuser_match_path "
+		<< g_conf->setuser_match_path << " owned by "
+		<< st.st_uid << ":" << st.st_gid << ". ";
       }
     }
-    if (setgid(gid) != 0) {
-      int r = errno;
-      cerr << "unable to setgid " << gid << ": " << cpp_strerror(r)
-	   << std::endl;
-      exit(1);
-    }
-    if (setuid(uid) != 0) {
-      int r = errno;
-      cerr << "unable to setuid " << uid << ": " << cpp_strerror(r)
-	   << std::endl;
-      exit(1);
+    g_ceph_context->set_uid_gid(uid, gid);
+    g_ceph_context->set_uid_gid_strings(uid_string, gid_string);
+    if ((flags & CINIT_FLAG_DEFER_DROP_PRIVILEGES) == 0) {
+      if (setgid(gid) != 0) {
+	int r = errno;
+	cerr << "unable to setgid " << gid << ": " << cpp_strerror(r)
+	     << std::endl;
+	exit(1);
+      }
+      if (setuid(uid) != 0) {
+	int r = errno;
+	cerr << "unable to setuid " << uid << ": " << cpp_strerror(r)
+	     << std::endl;
+	exit(1);
+      }
+      priv_ss << "set uid:gid to " << uid << ":" << gid << " (" << uid_string << ":" << gid_string << ")";
+    } else {
+      priv_ss << "deferred set uid:gid to " << uid << ":" << gid << " (" << uid_string << ":" << gid_string << ")";
     }
-    dout(0) << "set uid:gid to " << uid << ":" << gid << dendl;
   }
 
+  // Expand metavariables. Invoke configuration observers. Open log file.
+  g_conf->apply_changes(NULL);
+
   if (g_conf->run_dir.length() &&
       code_env == CODE_ENVIRONMENT_DAEMON &&
       !(flags & CINIT_FLAG_NO_DAEMON_ACTIONS)) {
@@ -240,6 +260,23 @@ void global_init(std::vector < const char * > *alt_def_args,
   // and opening the log file immediately.
   g_conf->call_all_observers();
 
+  if (priv_ss.str().length()) {
+    dout(0) << priv_ss.str() << dendl;
+
+    if (g_ceph_context->get_set_uid() || g_ceph_context->get_set_gid()) {
+      // fix ownership on log, asok files.  this is sadly a bit of a hack :(
+      g_ceph_context->_log->chown_log_file(
+	g_ceph_context->get_set_uid(),
+	g_ceph_context->get_set_gid());
+      g_ceph_context->get_admin_socket()->chown(
+	g_ceph_context->get_set_uid(),
+	g_ceph_context->get_set_gid());
+    }
+  }
+
+  // Now we're ready to complain about config file parse errors
+  g_conf->complain_about_parse_errors(g_ceph_context);
+
   // test leak checking
   if (g_conf->debug_deliberately_leak_memory) {
     derr << "deliberately leaking some memory" << dendl;
diff --git a/src/global/global_init.h b/src/global/global_init.h
index 0e27d43..79c0bad 100644
--- a/src/global/global_init.h
+++ b/src/global/global_init.h
@@ -35,7 +35,8 @@ void global_init(std::vector < const char * > *alt_def_args,
 		 uint32_t module_type,
 		 code_environment_t code_env,
 		 int flags,
-		 const char *data_dir_option = 0);
+		 const char *data_dir_option = 0,
+		 bool run_pre_init = true);
 
 // just the first half; enough to get config parsed but doesn't start up the
 // cct or log.
diff --git a/src/global/pidfile.cc b/src/global/pidfile.cc
index 17fe680..383181e 100644
--- a/src/global/pidfile.cc
+++ b/src/global/pidfile.cc
@@ -37,6 +37,7 @@
 // when the caller is daemonized but it will show if not (-f)
 //
 #define dout_prefix *_dout
+#define dout_subsys ceph_subsys_
 
 struct pidfh {
   int pf_fd;
@@ -204,8 +205,10 @@ void pidfile_remove()
 
 int pidfile_write(const md_config_t *conf)
 {
-  if (conf->pid_file.empty())
+  if (conf->pid_file.empty()) {
+    dout(0) << __func__ << ": ignore empty --pid-file" << dendl;
     return 0;
+  }
 
   assert(pfh == nullptr);
 
diff --git a/src/gmock/Makefile.in b/src/gmock/Makefile.in
index 4c43153..e1f406a 100644
--- a/src/gmock/Makefile.in
+++ b/src/gmock/Makefile.in
@@ -1,7 +1,7 @@
-# Makefile.in generated by automake 1.15 from Makefile.am.
+# Makefile.in generated by automake 1.14.1 from Makefile.am.
 # @configure_input@
 
-# Copyright (C) 1994-2014 Free Software Foundation, Inc.
+# Copyright (C) 1994-2013 Free Software Foundation, Inc.
 
 # This Makefile.in is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -18,17 +18,7 @@
 
 
 VPATH = @srcdir@
-am__is_gnu_make = { \
-  if test -z '$(MAKELEVEL)'; then \
-    false; \
-  elif test -n '$(MAKE_HOST)'; then \
-    true; \
-  elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
-    true; \
-  else \
-    false; \
-  fi; \
-}
+am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
 am__make_running_with_option = \
   case $${target_option-} in \
       ?) ;; \
@@ -98,14 +88,26 @@ check_PROGRAMS = test/gmock-spec-builders_test$(EXEEXT) \
 @HAVE_PYTHON_TRUE at am__append_1 = test/gmock_fused_test
 @HAVE_PYTHON_TRUE at am__append_2 = test/gmock_fused_test
 subdir = .
+DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
+	$(top_srcdir)/configure $(am__configure_deps) \
+	$(top_srcdir)/build-aux/config.h.in \
+	$(top_srcdir)/scripts/gmock-config.in \
+	$(top_srcdir)/build-aux/depcomp $(pkginclude_HEADERS) \
+	$(pkginclude_internal_HEADERS) \
+	$(top_srcdir)/build-aux/test-driver README build-aux/compile \
+	build-aux/config.guess build-aux/config.sub build-aux/depcomp \
+	build-aux/install-sh build-aux/missing build-aux/ltmain.sh \
+	$(top_srcdir)/build-aux/compile \
+	$(top_srcdir)/build-aux/config.guess \
+	$(top_srcdir)/build-aux/config.sub \
+	$(top_srcdir)/build-aux/install-sh \
+	$(top_srcdir)/build-aux/ltmain.sh \
+	$(top_srcdir)/build-aux/missing
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
 am__aclocal_m4_deps = $(top_srcdir)/gtest/m4/acx_pthread.m4 \
 	$(top_srcdir)/configure.ac
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
 	$(ACLOCAL_M4)
-DIST_COMMON = $(srcdir)/Makefile.am $(top_srcdir)/configure \
-	$(am__configure_deps) $(pkginclude_HEADERS) \
-	$(pkginclude_internal_HEADERS) $(am__DIST_COMMON)
 am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \
  configure.lineno config.status.lineno
 mkinstalldirs = $(install_sh) -d
@@ -454,19 +456,6 @@ TEST_LOG_DRIVER = $(SHELL) $(top_srcdir)/build-aux/test-driver
 TEST_LOG_COMPILE = $(TEST_LOG_COMPILER) $(AM_TEST_LOG_FLAGS) \
 	$(TEST_LOG_FLAGS)
 DIST_SUBDIRS = $(SUBDIRS)
-am__DIST_COMMON = $(srcdir)/Makefile.in \
-	$(top_srcdir)/build-aux/compile \
-	$(top_srcdir)/build-aux/config.guess \
-	$(top_srcdir)/build-aux/config.h.in \
-	$(top_srcdir)/build-aux/config.sub \
-	$(top_srcdir)/build-aux/depcomp \
-	$(top_srcdir)/build-aux/install-sh \
-	$(top_srcdir)/build-aux/ltmain.sh \
-	$(top_srcdir)/build-aux/missing \
-	$(top_srcdir)/build-aux/test-driver \
-	$(top_srcdir)/scripts/gmock-config.in README build-aux/compile \
-	build-aux/config.guess build-aux/config.sub build-aux/depcomp \
-	build-aux/install-sh build-aux/ltmain.sh build-aux/missing
 DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
 distdir = $(PACKAGE)-$(VERSION)
 top_distdir = $(distdir)
@@ -558,7 +547,6 @@ LIBTOOL = @LIBTOOL@
 LIPO = @LIPO@
 LN_S = @LN_S@
 LTLIBOBJS = @LTLIBOBJS@
-LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
 MAKEINFO = @MAKEINFO@
 MANIFEST_TOOL = @MANIFEST_TOOL@
 MKDIR_P = @MKDIR_P@
@@ -632,7 +620,6 @@ pdfdir = @pdfdir@
 prefix = @prefix@
 program_transform_name = @program_transform_name@
 psdir = @psdir@
-runstatedir = @runstatedir@
 sbindir = @sbindir@
 sharedstatedir = @sharedstatedir@
 srcdir = @srcdir@
@@ -783,6 +770,7 @@ $(srcdir)/Makefile.in:  $(srcdir)/Makefile.am  $(am__configure_deps)
 	echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign Makefile'; \
 	$(am__cd) $(top_srcdir) && \
 	  $(AUTOMAKE) --foreign Makefile
+.PRECIOUS: Makefile
 Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
 	@case '$?' in \
 	  *config.status*) \
@@ -1167,7 +1155,7 @@ $(TEST_SUITE_LOG): $(TEST_LOGS)
 	if test -n "$$am__remaking_logs"; then \
 	  echo "fatal: making $(TEST_SUITE_LOG): possible infinite" \
 	       "recursion detected" >&2; \
-	elif test -n "$$redo_logs"; then \
+	else \
 	  am__remaking_logs=yes $(MAKE) $(AM_MAKEFLAGS) $$redo_logs; \
 	fi; \
 	if $(am__make_dryrun); then :; else \
@@ -1394,15 +1382,15 @@ dist-xz: distdir
 	$(am__post_remove_distdir)
 
 dist-tarZ: distdir
-	@echo WARNING: "Support for distribution archives compressed with" \
-		       "legacy program 'compress' is deprecated." >&2
+	@echo WARNING: "Support for shar distribution archives is" \
+	               "deprecated." >&2
 	@echo WARNING: "It will be removed altogether in Automake 2.0" >&2
 	tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z
 	$(am__post_remove_distdir)
 
 dist-shar: distdir
-	@echo WARNING: "Support for shar distribution archives is" \
-	               "deprecated." >&2
+	@echo WARNING: "Support for distribution archives compressed with" \
+		       "legacy program 'compress' is deprecated." >&2
 	@echo WARNING: "It will be removed altogether in Automake 2.0" >&2
 	shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz
 	$(am__post_remove_distdir)
@@ -1437,17 +1425,17 @@ distcheck: dist
 	esac
 	chmod -R a-w $(distdir)
 	chmod u+w $(distdir)
-	mkdir $(distdir)/_build $(distdir)/_build/sub $(distdir)/_inst
+	mkdir $(distdir)/_build $(distdir)/_inst
 	chmod a-w $(distdir)
 	test -d $(distdir)/_build || exit 0; \
 	dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \
 	  && dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \
 	  && am__cwd=`pwd` \
-	  && $(am__cd) $(distdir)/_build/sub \
-	  && ../../configure \
+	  && $(am__cd) $(distdir)/_build \
+	  && ../configure \
 	    $(AM_DISTCHECK_CONFIGURE_FLAGS) \
 	    $(DISTCHECK_CONFIGURE_FLAGS) \
-	    --srcdir=../.. --prefix="$$dc_install_base" \
+	    --srcdir=.. --prefix="$$dc_install_base" \
 	  && $(MAKE) $(AM_MAKEFLAGS) \
 	  && $(MAKE) $(AM_MAKEFLAGS) dvi \
 	  && $(MAKE) $(AM_MAKEFLAGS) check \
@@ -1655,8 +1643,6 @@ uninstall-am: uninstall-pkgincludeHEADERS \
 	uninstall-pkgincludeHEADERS \
 	uninstall-pkginclude_internalHEADERS
 
-.PRECIOUS: Makefile
-
 
 @HAVE_PYTHON_TRUE@  # Tests that fused gmock files compile and work.
 
diff --git a/src/gmock/aclocal.m4 b/src/gmock/aclocal.m4
index 1c87fd9..bed39b9 100644
--- a/src/gmock/aclocal.m4
+++ b/src/gmock/aclocal.m4
@@ -1,6 +1,6 @@
-# generated automatically by aclocal 1.15 -*- Autoconf -*-
+# generated automatically by aclocal 1.14.1 -*- Autoconf -*-
 
-# Copyright (C) 1996-2014 Free Software Foundation, Inc.
+# Copyright (C) 1996-2013 Free Software Foundation, Inc.
 
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -22,7 +22,9 @@ To do so, use the procedure documented by the package, typically 'autoreconf'.])
 
 # libtool.m4 - Configure libtool for the host system. -*-Autoconf-*-
 #
-#   Copyright (C) 1996-2001, 2003-2015 Free Software Foundation, Inc.
+#   Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005,
+#                 2006, 2007, 2008, 2009, 2010, 2011 Free Software
+#                 Foundation, Inc.
 #   Written by Gordon Matzigkeit, 1996
 #
 # This file is free software; the Free Software Foundation gives
@@ -30,30 +32,36 @@ To do so, use the procedure documented by the package, typically 'autoreconf'.])
 # modifications, as long as this notice is preserved.
 
 m4_define([_LT_COPYING], [dnl
-# Copyright (C) 2014 Free Software Foundation, Inc.
-# This is free software; see the source for copying conditions.  There is NO
-# warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-
-# GNU Libtool is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of of the License, or
-# (at your option) any later version.
+#   Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005,
+#                 2006, 2007, 2008, 2009, 2010, 2011 Free Software
+#                 Foundation, Inc.
+#   Written by Gordon Matzigkeit, 1996
+#
+#   This file is part of GNU Libtool.
+#
+# GNU Libtool is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2 of
+# the License, or (at your option) any later version.
 #
-# As a special exception to the GNU General Public License, if you
-# distribute this file as part of a program or library that is built
-# using GNU Libtool, you may include this file under the  same
-# distribution terms that you use for the rest of that program.
+# As a special exception to the GNU General Public License,
+# if you distribute this file as part of a program or library that
+# is built using GNU Libtool, you may include this file under the
+# same distribution terms that you use for the rest of that program.
 #
-# GNU Libtool is distributed in the hope that it will be useful, but
-# WITHOUT ANY WARRANTY; without even the implied warranty of
+# GNU Libtool is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 # GNU General Public License for more details.
 #
 # You should have received a copy of the GNU General Public License
-# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+# along with GNU Libtool; see the file COPYING.  If not, a copy
+# can be downloaded from http://www.gnu.org/licenses/gpl.html, or
+# obtained by writing to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 ])
 
-# serial 58 LT_INIT
+# serial 57 LT_INIT
 
 
 # LT_PREREQ(VERSION)
@@ -81,7 +89,7 @@ esac
 # LT_INIT([OPTIONS])
 # ------------------
 AC_DEFUN([LT_INIT],
-[AC_PREREQ([2.62])dnl We use AC_PATH_PROGS_FEATURE_CHECK
+[AC_PREREQ([2.58])dnl We use AC_INCLUDES_DEFAULT
 AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT])dnl
 AC_BEFORE([$0], [LT_LANG])dnl
 AC_BEFORE([$0], [LT_OUTPUT])dnl
@@ -105,7 +113,7 @@ dnl Parse OPTIONS
 _LT_SET_OPTIONS([$0], [$1])
 
 # This can be used to rebuild libtool when needed
-LIBTOOL_DEPS=$ltmain
+LIBTOOL_DEPS="$ltmain"
 
 # Always use our own libtool.
 LIBTOOL='$(SHELL) $(top_builddir)/libtool'
@@ -125,43 +133,26 @@ dnl AC_DEFUN([AC_PROG_LIBTOOL], [])
 dnl AC_DEFUN([AM_PROG_LIBTOOL], [])
 
 
-# _LT_PREPARE_CC_BASENAME
-# -----------------------
-m4_defun([_LT_PREPARE_CC_BASENAME], [
-# Calculate cc_basename.  Skip known compiler wrappers and cross-prefix.
-func_cc_basename ()
-{
-    for cc_temp in @S|@*""; do
-      case $cc_temp in
-        compile | *[[\\/]]compile | ccache | *[[\\/]]ccache ) ;;
-        distcc | *[[\\/]]distcc | purify | *[[\\/]]purify ) ;;
-        \-*) ;;
-        *) break;;
-      esac
-    done
-    func_cc_basename_result=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"`
-}
-])# _LT_PREPARE_CC_BASENAME
-
-
 # _LT_CC_BASENAME(CC)
 # -------------------
-# It would be clearer to call AC_REQUIREs from _LT_PREPARE_CC_BASENAME,
-# but that macro is also expanded into generated libtool script, which
-# arranges for $SED and $ECHO to be set by different means.
+# Calculate cc_basename.  Skip known compiler wrappers and cross-prefix.
 m4_defun([_LT_CC_BASENAME],
-[m4_require([_LT_PREPARE_CC_BASENAME])dnl
-AC_REQUIRE([_LT_DECL_SED])dnl
-AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH])dnl
-func_cc_basename $1
-cc_basename=$func_cc_basename_result
+[for cc_temp in $1""; do
+  case $cc_temp in
+    compile | *[[\\/]]compile | ccache | *[[\\/]]ccache ) ;;
+    distcc | *[[\\/]]distcc | purify | *[[\\/]]purify ) ;;
+    \-*) ;;
+    *) break;;
+  esac
+done
+cc_basename=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"`
 ])
 
 
 # _LT_FILEUTILS_DEFAULTS
 # ----------------------
 # It is okay to use these file commands and assume they have been set
-# sensibly after 'm4_require([_LT_FILEUTILS_DEFAULTS])'.
+# sensibly after `m4_require([_LT_FILEUTILS_DEFAULTS])'.
 m4_defun([_LT_FILEUTILS_DEFAULTS],
 [: ${CP="cp -f"}
 : ${MV="mv -f"}
@@ -208,16 +199,15 @@ m4_require([_LT_CHECK_SHAREDLIB_FROM_LINKLIB])dnl
 m4_require([_LT_CMD_OLD_ARCHIVE])dnl
 m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl
 m4_require([_LT_WITH_SYSROOT])dnl
-m4_require([_LT_CMD_TRUNCATE])dnl
 
 _LT_CONFIG_LIBTOOL_INIT([
-# See if we are running on zsh, and set the options that allow our
+# See if we are running on zsh, and set the options which allow our
 # commands through without removal of \ escapes INIT.
-if test -n "\${ZSH_VERSION+set}"; then
+if test -n "\${ZSH_VERSION+set}" ; then
    setopt NO_GLOB_SUBST
 fi
 ])
-if test -n "${ZSH_VERSION+set}"; then
+if test -n "${ZSH_VERSION+set}" ; then
    setopt NO_GLOB_SUBST
 fi
 
@@ -230,7 +220,7 @@ aix3*)
   # AIX sometimes has problems with the GCC collect2 program.  For some
   # reason, if we set the COLLECT_NAMES environment variable, the problems
   # vanish in a puff of smoke.
-  if test set != "${COLLECT_NAMES+set}"; then
+  if test "X${COLLECT_NAMES+set}" != Xset; then
     COLLECT_NAMES=
     export COLLECT_NAMES
   fi
@@ -241,14 +231,14 @@ esac
 ofile=libtool
 can_build_shared=yes
 
-# All known linkers require a '.a' archive for static linking (except MSVC,
+# All known linkers require a `.a' archive for static linking (except MSVC,
 # which needs '.lib').
 libext=a
 
-with_gnu_ld=$lt_cv_prog_gnu_ld
+with_gnu_ld="$lt_cv_prog_gnu_ld"
 
-old_CC=$CC
-old_CFLAGS=$CFLAGS
+old_CC="$CC"
+old_CFLAGS="$CFLAGS"
 
 # Set sane defaults for various variables
 test -z "$CC" && CC=cc
@@ -301,21 +291,21 @@ no_glob_subst='s/\*/\\\*/g'
 
 # _LT_PROG_LTMAIN
 # ---------------
-# Note that this code is called both from 'configure', and 'config.status'
+# Note that this code is called both from `configure', and `config.status'
 # now that we use AC_CONFIG_COMMANDS to generate libtool.  Notably,
-# 'config.status' has no value for ac_aux_dir unless we are using Automake,
+# `config.status' has no value for ac_aux_dir unless we are using Automake,
 # so we pass a copy along to make sure it has a sensible value anyway.
 m4_defun([_LT_PROG_LTMAIN],
 [m4_ifdef([AC_REQUIRE_AUX_FILE], [AC_REQUIRE_AUX_FILE([ltmain.sh])])dnl
 _LT_CONFIG_LIBTOOL_INIT([ac_aux_dir='$ac_aux_dir'])
-ltmain=$ac_aux_dir/ltmain.sh
+ltmain="$ac_aux_dir/ltmain.sh"
 ])# _LT_PROG_LTMAIN
 
 
 
 # So that we can recreate a full libtool script including additional
 # tags, we accumulate the chunks of code to send to AC_CONFIG_COMMANDS
-# in macros and then make a single call at the end using the 'libtool'
+# in macros and then make a single call at the end using the `libtool'
 # label.
 
 
@@ -447,8 +437,8 @@ m4_define([_lt_decl_all_varnames],
 
 # _LT_CONFIG_STATUS_DECLARE([VARNAME])
 # ------------------------------------
-# Quote a variable value, and forward it to 'config.status' so that its
-# declaration there will have the same value as in 'configure'.  VARNAME
+# Quote a variable value, and forward it to `config.status' so that its
+# declaration there will have the same value as in `configure'.  VARNAME
 # must have a single quote delimited value for this to work.
 m4_define([_LT_CONFIG_STATUS_DECLARE],
 [$1='`$ECHO "$][$1" | $SED "$delay_single_quote_subst"`'])
@@ -472,7 +462,7 @@ m4_defun([_LT_CONFIG_STATUS_DECLARATIONS],
 # Output comment and list of tags supported by the script
 m4_defun([_LT_LIBTOOL_TAGS],
 [_LT_FORMAT_COMMENT([The names of the tagged configurations supported by this script])dnl
-available_tags='_LT_TAGS'dnl
+available_tags="_LT_TAGS"dnl
 ])
 
 
@@ -500,7 +490,7 @@ m4_ifval([$2], [_$2])[]m4_popdef([_libtool_name])[]dnl
 # _LT_LIBTOOL_CONFIG_VARS
 # -----------------------
 # Produce commented declarations of non-tagged libtool config variables
-# suitable for insertion in the LIBTOOL CONFIG section of the 'libtool'
+# suitable for insertion in the LIBTOOL CONFIG section of the `libtool'
 # script.  Tagged libtool config variables (even for the LIBTOOL CONFIG
 # section) are produced by _LT_LIBTOOL_TAG_VARS.
 m4_defun([_LT_LIBTOOL_CONFIG_VARS],
@@ -526,8 +516,8 @@ m4_define([_LT_TAGVAR], [m4_ifval([$2], [$1_$2], [$1])])
 # Send accumulated output to $CONFIG_STATUS.  Thanks to the lists of
 # variables for single and double quote escaping we saved from calls
 # to _LT_DECL, we can put quote escaped variables declarations
-# into 'config.status', and then the shell code to quote escape them in
-# for loops in 'config.status'.  Finally, any additional code accumulated
+# into `config.status', and then the shell code to quote escape them in
+# for loops in `config.status'.  Finally, any additional code accumulated
 # from calls to _LT_CONFIG_LIBTOOL_INIT is expanded.
 m4_defun([_LT_CONFIG_COMMANDS],
 [AC_PROVIDE_IFELSE([LT_OUTPUT],
@@ -573,7 +563,7 @@ for var in lt_decl_all_varnames([[ \
 ]], lt_decl_quote_varnames); do
     case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in
     *[[\\\\\\\`\\"\\\$]]*)
-      eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$sed_quote_subst\\"\\\`\\\\\\"" ## exclude from sc_prohibit_nested_quotes
+      eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$sed_quote_subst\\"\\\`\\\\\\""
       ;;
     *)
       eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\""
@@ -586,7 +576,7 @@ for var in lt_decl_all_varnames([[ \
 ]], lt_decl_dquote_varnames); do
     case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in
     *[[\\\\\\\`\\"\\\$]]*)
-      eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\"" ## exclude from sc_prohibit_nested_quotes
+      eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\""
       ;;
     *)
       eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\""
@@ -602,7 +592,7 @@ _LT_OUTPUT_LIBTOOL_INIT
 # Generate a child script FILE with all initialization necessary to
 # reuse the environment learned by the parent script, and make the
 # file executable.  If COMMENT is supplied, it is inserted after the
-# '#!' sequence but before initialization text begins.  After this
+# `#!' sequence but before initialization text begins.  After this
 # macro, additional text can be appended to FILE to form the body of
 # the child script.  The macro ends with non-zero status if the
 # file could not be fully written (such as if the disk is full).
@@ -624,7 +614,7 @@ AS_SHELL_SANITIZE
 _AS_PREPARE
 exec AS_MESSAGE_FD>&1
 _ASEOF
-test 0 = "$lt_write_fail" && chmod +x $1[]dnl
+test $lt_write_fail = 0 && chmod +x $1[]dnl
 m4_popdef([AS_MESSAGE_LOG_FD])])])# _LT_GENERATED_FILE_INIT
 
 # LT_OUTPUT
@@ -647,7 +637,7 @@ exec AS_MESSAGE_LOG_FD>>config.log
 } >&AS_MESSAGE_LOG_FD
 
 lt_cl_help="\
-'$as_me' creates a local libtool stub from the current configuration,
+\`$as_me' creates a local libtool stub from the current configuration,
 for use in further configure time tests before the real libtool is
 generated.
 
@@ -669,7 +659,7 @@ Copyright (C) 2011 Free Software Foundation, Inc.
 This config.lt script is free software; the Free Software Foundation
 gives unlimited permision to copy, distribute and modify it."
 
-while test 0 != $[#]
+while test $[#] != 0
 do
   case $[1] in
     --version | --v* | -V )
@@ -682,10 +672,10 @@ do
       lt_cl_silent=: ;;
 
     -*) AC_MSG_ERROR([unrecognized option: $[1]
-Try '$[0] --help' for more information.]) ;;
+Try \`$[0] --help' for more information.]) ;;
 
     *) AC_MSG_ERROR([unrecognized argument: $[1]
-Try '$[0] --help' for more information.]) ;;
+Try \`$[0] --help' for more information.]) ;;
   esac
   shift
 done
@@ -711,7 +701,7 @@ chmod +x "$CONFIG_LT"
 # open by configure.  Here we exec the FD to /dev/null, effectively closing
 # config.log, so it can be properly (re)opened and appended to by config.lt.
 lt_cl_success=:
-test yes = "$silent" &&
+test "$silent" = yes &&
   lt_config_lt_args="$lt_config_lt_args --quiet"
 exec AS_MESSAGE_LOG_FD>/dev/null
 $SHELL "$CONFIG_LT" $lt_config_lt_args || lt_cl_success=false
@@ -731,31 +721,27 @@ m4_defun([_LT_CONFIG],
 _LT_CONFIG_SAVE_COMMANDS([
   m4_define([_LT_TAG], m4_if([$1], [], [C], [$1]))dnl
   m4_if(_LT_TAG, [C], [
-    # See if we are running on zsh, and set the options that allow our
+    # See if we are running on zsh, and set the options which allow our
     # commands through without removal of \ escapes.
-    if test -n "${ZSH_VERSION+set}"; then
+    if test -n "${ZSH_VERSION+set}" ; then
       setopt NO_GLOB_SUBST
     fi
 
-    cfgfile=${ofile}T
+    cfgfile="${ofile}T"
     trap "$RM \"$cfgfile\"; exit 1" 1 2 15
     $RM "$cfgfile"
 
     cat <<_LT_EOF >> "$cfgfile"
 #! $SHELL
-# Generated automatically by $as_me ($PACKAGE) $VERSION
+
+# `$ECHO "$ofile" | sed 's%^.*/%%'` - Provide generalized library-building support services.
+# Generated automatically by $as_me ($PACKAGE$TIMESTAMP) $VERSION
 # Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
 # NOTE: Changes made to this file will be lost: look at ltmain.sh.
-
-# Provide generalized library-building support services.
-# Written by Gordon Matzigkeit, 1996
-
+#
 _LT_COPYING
 _LT_LIBTOOL_TAGS
 
-# Configured defaults for sys_lib_dlsearch_path munging.
-: \${LT_SYS_LIBRARY_PATH="$configure_time_lt_sys_library_path"}
-
 # ### BEGIN LIBTOOL CONFIG
 _LT_LIBTOOL_CONFIG_VARS
 _LT_LIBTOOL_TAG_VARS
@@ -763,24 +749,13 @@ _LT_LIBTOOL_TAG_VARS
 
 _LT_EOF
 
-    cat <<'_LT_EOF' >> "$cfgfile"
-
-# ### BEGIN FUNCTIONS SHARED WITH CONFIGURE
-
-_LT_PREPARE_MUNGE_PATH_LIST
-_LT_PREPARE_CC_BASENAME
-
-# ### END FUNCTIONS SHARED WITH CONFIGURE
-
-_LT_EOF
-
   case $host_os in
   aix3*)
     cat <<\_LT_EOF >> "$cfgfile"
 # AIX sometimes has problems with the GCC collect2 program.  For some
 # reason, if we set the COLLECT_NAMES environment variable, the problems
 # vanish in a puff of smoke.
-if test set != "${COLLECT_NAMES+set}"; then
+if test "X${COLLECT_NAMES+set}" != Xset; then
   COLLECT_NAMES=
   export COLLECT_NAMES
 fi
@@ -797,6 +772,8 @@ _LT_EOF
   sed '$q' "$ltmain" >> "$cfgfile" \
      || (rm -f "$cfgfile"; exit 1)
 
+  _LT_PROG_REPLACE_SHELLFNS
+
    mv -f "$cfgfile" "$ofile" ||
     (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile")
   chmod +x "$ofile"
@@ -814,6 +791,7 @@ _LT_EOF
 [m4_if([$1], [], [
     PACKAGE='$PACKAGE'
     VERSION='$VERSION'
+    TIMESTAMP='$TIMESTAMP'
     RM='$RM'
     ofile='$ofile'], [])
 ])dnl /_LT_CONFIG_SAVE_COMMANDS
@@ -1010,7 +988,7 @@ m4_defun_once([_LT_REQUIRED_DARWIN_CHECKS],[
 
     AC_CACHE_CHECK([for -single_module linker flag],[lt_cv_apple_cc_single_mod],
       [lt_cv_apple_cc_single_mod=no
-      if test -z "$LT_MULTI_MODULE"; then
+      if test -z "${LT_MULTI_MODULE}"; then
 	# By default we will add the -single_module flag. You can override
 	# by either setting the environment variable LT_MULTI_MODULE
 	# non-empty at configure time, or by adding -multi_module to the
@@ -1028,7 +1006,7 @@ m4_defun_once([_LT_REQUIRED_DARWIN_CHECKS],[
 	  cat conftest.err >&AS_MESSAGE_LOG_FD
 	# Otherwise, if the output was created with a 0 exit code from
 	# the compiler, it worked.
-	elif test -f libconftest.dylib && test 0 = "$_lt_result"; then
+	elif test -f libconftest.dylib && test $_lt_result -eq 0; then
 	  lt_cv_apple_cc_single_mod=yes
 	else
 	  cat conftest.err >&AS_MESSAGE_LOG_FD
@@ -1046,7 +1024,7 @@ m4_defun_once([_LT_REQUIRED_DARWIN_CHECKS],[
       AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])],
 	[lt_cv_ld_exported_symbols_list=yes],
 	[lt_cv_ld_exported_symbols_list=no])
-	LDFLAGS=$save_LDFLAGS
+	LDFLAGS="$save_LDFLAGS"
     ])
 
     AC_CACHE_CHECK([for -force_load linker flag],[lt_cv_ld_force_load],
@@ -1068,7 +1046,7 @@ _LT_EOF
       _lt_result=$?
       if test -s conftest.err && $GREP force_load conftest.err; then
 	cat conftest.err >&AS_MESSAGE_LOG_FD
-      elif test -f conftest && test 0 = "$_lt_result" && $GREP forced_load conftest >/dev/null 2>&1; then
+      elif test -f conftest && test $_lt_result -eq 0 && $GREP forced_load conftest >/dev/null 2>&1 ; then
 	lt_cv_ld_force_load=yes
       else
 	cat conftest.err >&AS_MESSAGE_LOG_FD
@@ -1078,32 +1056,32 @@ _LT_EOF
     ])
     case $host_os in
     rhapsody* | darwin1.[[012]])
-      _lt_dar_allow_undefined='$wl-undefined ${wl}suppress' ;;
+      _lt_dar_allow_undefined='${wl}-undefined ${wl}suppress' ;;
     darwin1.*)
-      _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;;
+      _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;;
     darwin*) # darwin 5.x on
       # if running on 10.5 or later, the deployment target defaults
       # to the OS version, if on x86, and 10.4, the deployment
       # target defaults to 10.4. Don't you love it?
       case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in
 	10.0,*86*-darwin8*|10.0,*-darwin[[91]]*)
-	  _lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' ;;
-	10.[[012]][[,.]]*)
-	  _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;;
+	  _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;;
+	10.[[012]]*)
+	  _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;;
 	10.*)
-	  _lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' ;;
+	  _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;;
       esac
     ;;
   esac
-    if test yes = "$lt_cv_apple_cc_single_mod"; then
+    if test "$lt_cv_apple_cc_single_mod" = "yes"; then
       _lt_dar_single_mod='$single_module'
     fi
-    if test yes = "$lt_cv_ld_exported_symbols_list"; then
-      _lt_dar_export_syms=' $wl-exported_symbols_list,$output_objdir/$libname-symbols.expsym'
+    if test "$lt_cv_ld_exported_symbols_list" = "yes"; then
+      _lt_dar_export_syms=' ${wl}-exported_symbols_list,$output_objdir/${libname}-symbols.expsym'
     else
-      _lt_dar_export_syms='~$NMEDIT -s $output_objdir/$libname-symbols.expsym $lib'
+      _lt_dar_export_syms='~$NMEDIT -s $output_objdir/${libname}-symbols.expsym ${lib}'
     fi
-    if test : != "$DSYMUTIL" && test no = "$lt_cv_ld_force_load"; then
+    if test "$DSYMUTIL" != ":" && test "$lt_cv_ld_force_load" = "no"; then
       _lt_dsymutil='~$DSYMUTIL $lib || :'
     else
       _lt_dsymutil=
@@ -1123,29 +1101,29 @@ m4_defun([_LT_DARWIN_LINKER_FEATURES],
   _LT_TAGVAR(hardcode_direct, $1)=no
   _LT_TAGVAR(hardcode_automatic, $1)=yes
   _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported
-  if test yes = "$lt_cv_ld_force_load"; then
-    _LT_TAGVAR(whole_archive_flag_spec, $1)='`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience $wl-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`'
+  if test "$lt_cv_ld_force_load" = "yes"; then
+    _LT_TAGVAR(whole_archive_flag_spec, $1)='`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience ${wl}-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`'
     m4_case([$1], [F77], [_LT_TAGVAR(compiler_needs_object, $1)=yes],
                   [FC],  [_LT_TAGVAR(compiler_needs_object, $1)=yes])
   else
     _LT_TAGVAR(whole_archive_flag_spec, $1)=''
   fi
   _LT_TAGVAR(link_all_deplibs, $1)=yes
-  _LT_TAGVAR(allow_undefined_flag, $1)=$_lt_dar_allow_undefined
+  _LT_TAGVAR(allow_undefined_flag, $1)="$_lt_dar_allow_undefined"
   case $cc_basename in
-     ifort*|nagfor*) _lt_dar_can_shared=yes ;;
+     ifort*) _lt_dar_can_shared=yes ;;
      *) _lt_dar_can_shared=$GCC ;;
   esac
-  if test yes = "$_lt_dar_can_shared"; then
+  if test "$_lt_dar_can_shared" = "yes"; then
     output_verbose_link_cmd=func_echo_all
-    _LT_TAGVAR(archive_cmds, $1)="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dsymutil"
-    _LT_TAGVAR(module_cmds, $1)="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dsymutil"
-    _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dar_export_syms$_lt_dsymutil"
-    _LT_TAGVAR(module_expsym_cmds, $1)="sed -e 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dar_export_syms$_lt_dsymutil"
+    _LT_TAGVAR(archive_cmds, $1)="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}"
+    _LT_TAGVAR(module_cmds, $1)="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}"
+    _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}"
+    _LT_TAGVAR(module_expsym_cmds, $1)="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}"
     m4_if([$1], [CXX],
-[   if test yes != "$lt_cv_apple_cc_single_mod"; then
-      _LT_TAGVAR(archive_cmds, $1)="\$CC -r -keep_private_externs -nostdlib -o \$lib-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$lib-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring$_lt_dsymutil"
-      _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \$lib-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$lib-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring$_lt_dar_export_syms$_lt_dsymutil"
+[   if test "$lt_cv_apple_cc_single_mod" != "yes"; then
+      _LT_TAGVAR(archive_cmds, $1)="\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dsymutil}"
+      _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dar_export_syms}${_lt_dsymutil}"
     fi
 ],[])
   else
@@ -1165,7 +1143,7 @@ m4_defun([_LT_DARWIN_LINKER_FEATURES],
 # Allow to override them for all tags through lt_cv_aix_libpath.
 m4_defun([_LT_SYS_MODULE_PATH_AIX],
 [m4_require([_LT_DECL_SED])dnl
-if test set = "${lt_cv_aix_libpath+set}"; then
+if test "${lt_cv_aix_libpath+set}" = set; then
   aix_libpath=$lt_cv_aix_libpath
 else
   AC_CACHE_VAL([_LT_TAGVAR([lt_cv_aix_libpath_], [$1])],
@@ -1183,7 +1161,7 @@ else
     _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
   fi],[])
   if test -z "$_LT_TAGVAR([lt_cv_aix_libpath_], [$1])"; then
-    _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=/usr/lib:/lib
+    _LT_TAGVAR([lt_cv_aix_libpath_], [$1])="/usr/lib:/lib"
   fi
   ])
   aix_libpath=$_LT_TAGVAR([lt_cv_aix_libpath_], [$1])
@@ -1203,8 +1181,8 @@ m4_define([_LT_SHELL_INIT],
 # -----------------------
 # Find how we can fake an echo command that does not interpret backslash.
 # In particular, with Autoconf 2.60 or later we add some code to the start
-# of the generated configure script that will find a shell with a builtin
-# printf (that we can use as an echo command).
+# of the generated configure script which will find a shell with a builtin
+# printf (which we can use as an echo command).
 m4_defun([_LT_PROG_ECHO_BACKSLASH],
 [ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
 ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO
@@ -1232,10 +1210,10 @@ fi
 # Invoke $ECHO with all args, space-separated.
 func_echo_all ()
 {
-    $ECHO "$*"
+    $ECHO "$*" 
 }
 
-case $ECHO in
+case "$ECHO" in
   printf*) AC_MSG_RESULT([printf]) ;;
   print*) AC_MSG_RESULT([print -r]) ;;
   *) AC_MSG_RESULT([cat]) ;;
@@ -1261,17 +1239,16 @@ _LT_DECL([], [ECHO], [1], [An echo program that protects backslashes])
 AC_DEFUN([_LT_WITH_SYSROOT],
 [AC_MSG_CHECKING([for sysroot])
 AC_ARG_WITH([sysroot],
-[AS_HELP_STRING([--with-sysroot@<:@=DIR@:>@],
-  [Search for dependent libraries within DIR (or the compiler's sysroot
-   if not specified).])],
+[  --with-sysroot[=DIR] Search for dependent libraries within DIR
+                        (or the compiler's sysroot if not specified).],
 [], [with_sysroot=no])
 
 dnl lt_sysroot will always be passed unquoted.  We quote it here
 dnl in case the user passed a directory name.
 lt_sysroot=
-case $with_sysroot in #(
+case ${with_sysroot} in #(
  yes)
-   if test yes = "$GCC"; then
+   if test "$GCC" = yes; then
      lt_sysroot=`$CC --print-sysroot 2>/dev/null`
    fi
    ;; #(
@@ -1281,14 +1258,14 @@ case $with_sysroot in #(
  no|'')
    ;; #(
  *)
-   AC_MSG_RESULT([$with_sysroot])
+   AC_MSG_RESULT([${with_sysroot}])
    AC_MSG_ERROR([The sysroot must be an absolute path.])
    ;;
 esac
 
  AC_MSG_RESULT([${lt_sysroot:-no}])
 _LT_DECL([], [lt_sysroot], [0], [The root where to search for ]dnl
-[dependent libraries, and where our libraries should be installed.])])
+[dependent libraries, and in which our libraries should be installed.])])
 
 # _LT_ENABLE_LOCK
 # ---------------
@@ -1296,33 +1273,31 @@ m4_defun([_LT_ENABLE_LOCK],
 [AC_ARG_ENABLE([libtool-lock],
   [AS_HELP_STRING([--disable-libtool-lock],
     [avoid locking (might break parallel builds)])])
-test no = "$enable_libtool_lock" || enable_libtool_lock=yes
+test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes
 
 # Some flags need to be propagated to the compiler or linker for good
 # libtool support.
 case $host in
 ia64-*-hpux*)
-  # Find out what ABI is being produced by ac_compile, and set mode
-  # options accordingly.
+  # Find out which ABI we are using.
   echo 'int i;' > conftest.$ac_ext
   if AC_TRY_EVAL(ac_compile); then
     case `/usr/bin/file conftest.$ac_objext` in
       *ELF-32*)
-	HPUX_IA64_MODE=32
+	HPUX_IA64_MODE="32"
 	;;
       *ELF-64*)
-	HPUX_IA64_MODE=64
+	HPUX_IA64_MODE="64"
 	;;
     esac
   fi
   rm -rf conftest*
   ;;
 *-*-irix6*)
-  # Find out what ABI is being produced by ac_compile, and set linker
-  # options accordingly.
+  # Find out which ABI we are using.
   echo '[#]line '$LINENO' "configure"' > conftest.$ac_ext
   if AC_TRY_EVAL(ac_compile); then
-    if test yes = "$lt_cv_prog_gnu_ld"; then
+    if test "$lt_cv_prog_gnu_ld" = yes; then
       case `/usr/bin/file conftest.$ac_objext` in
 	*32-bit*)
 	  LD="${LD-ld} -melf32bsmip"
@@ -1351,46 +1326,9 @@ ia64-*-hpux*)
   rm -rf conftest*
   ;;
 
-mips64*-*linux*)
-  # Find out what ABI is being produced by ac_compile, and set linker
-  # options accordingly.
-  echo '[#]line '$LINENO' "configure"' > conftest.$ac_ext
-  if AC_TRY_EVAL(ac_compile); then
-    emul=elf
-    case `/usr/bin/file conftest.$ac_objext` in
-      *32-bit*)
-	emul="${emul}32"
-	;;
-      *64-bit*)
-	emul="${emul}64"
-	;;
-    esac
-    case `/usr/bin/file conftest.$ac_objext` in
-      *MSB*)
-	emul="${emul}btsmip"
-	;;
-      *LSB*)
-	emul="${emul}ltsmip"
-	;;
-    esac
-    case `/usr/bin/file conftest.$ac_objext` in
-      *N32*)
-	emul="${emul}n32"
-	;;
-    esac
-    LD="${LD-ld} -m $emul"
-  fi
-  rm -rf conftest*
-  ;;
-
 x86_64-*kfreebsd*-gnu|x86_64-*linux*|powerpc*-*linux*| \
 s390*-*linux*|s390*-*tpf*|sparc*-*linux*)
-  # Find out what ABI is being produced by ac_compile, and set linker
-  # options accordingly.  Note that the listed cases only cover the
-  # situations where additional linker options are needed (such as when
-  # doing 32-bit compilation for a host where ld defaults to 64-bit, or
-  # vice versa); the common cases where no linker options are needed do
-  # not appear in the list.
+  # Find out which ABI we are using.
   echo 'int i;' > conftest.$ac_ext
   if AC_TRY_EVAL(ac_compile); then
     case `/usr/bin/file conftest.o` in
@@ -1409,10 +1347,10 @@ s390*-*linux*|s390*-*tpf*|sparc*-*linux*)
 		;;
 	    esac
 	    ;;
-	  powerpc64le-*linux*)
+	  powerpc64le-*)
 	    LD="${LD-ld} -m elf32lppclinux"
 	    ;;
-	  powerpc64-*linux*)
+	  powerpc64-*)
 	    LD="${LD-ld} -m elf32ppclinux"
 	    ;;
 	  s390x-*linux*)
@@ -1431,10 +1369,10 @@ s390*-*linux*|s390*-*tpf*|sparc*-*linux*)
 	  x86_64-*linux*)
 	    LD="${LD-ld} -m elf_x86_64"
 	    ;;
-	  powerpcle-*linux*)
+	  powerpcle-*)
 	    LD="${LD-ld} -m elf64lppc"
 	    ;;
-	  powerpc-*linux*)
+	  powerpc-*)
 	    LD="${LD-ld} -m elf64ppc"
 	    ;;
 	  s390*-*linux*|s390*-*tpf*)
@@ -1452,20 +1390,19 @@ s390*-*linux*|s390*-*tpf*|sparc*-*linux*)
 
 *-*-sco3.2v5*)
   # On SCO OpenServer 5, we need -belf to get full-featured binaries.
-  SAVE_CFLAGS=$CFLAGS
+  SAVE_CFLAGS="$CFLAGS"
   CFLAGS="$CFLAGS -belf"
   AC_CACHE_CHECK([whether the C compiler needs -belf], lt_cv_cc_needs_belf,
     [AC_LANG_PUSH(C)
      AC_LINK_IFELSE([AC_LANG_PROGRAM([[]],[[]])],[lt_cv_cc_needs_belf=yes],[lt_cv_cc_needs_belf=no])
      AC_LANG_POP])
-  if test yes != "$lt_cv_cc_needs_belf"; then
+  if test x"$lt_cv_cc_needs_belf" != x"yes"; then
     # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf
-    CFLAGS=$SAVE_CFLAGS
+    CFLAGS="$SAVE_CFLAGS"
   fi
   ;;
 *-*solaris*)
-  # Find out what ABI is being produced by ac_compile, and set linker
-  # options accordingly.
+  # Find out which ABI we are using.
   echo 'int i;' > conftest.$ac_ext
   if AC_TRY_EVAL(ac_compile); then
     case `/usr/bin/file conftest.o` in
@@ -1473,7 +1410,7 @@ s390*-*linux*|s390*-*tpf*|sparc*-*linux*)
       case $lt_cv_prog_gnu_ld in
       yes*)
         case $host in
-        i?86-*-solaris*|x86_64-*-solaris*)
+        i?86-*-solaris*)
           LD="${LD-ld} -m elf_x86_64"
           ;;
         sparc*-*-solaris*)
@@ -1482,7 +1419,7 @@ s390*-*linux*|s390*-*tpf*|sparc*-*linux*)
         esac
         # GNU ld 2.21 introduced _sol2 emulations.  Use them if available.
         if ${LD-ld} -V | grep _sol2 >/dev/null 2>&1; then
-          LD=${LD-ld}_sol2
+          LD="${LD-ld}_sol2"
         fi
         ;;
       *)
@@ -1498,7 +1435,7 @@ s390*-*linux*|s390*-*tpf*|sparc*-*linux*)
   ;;
 esac
 
-need_locks=$enable_libtool_lock
+need_locks="$enable_libtool_lock"
 ])# _LT_ENABLE_LOCK
 
 
@@ -1517,11 +1454,11 @@ AC_CACHE_CHECK([for archiver @FILE support], [lt_cv_ar_at_file],
      [echo conftest.$ac_objext > conftest.lst
       lt_ar_try='$AR $AR_FLAGS libconftest.a @conftest.lst >&AS_MESSAGE_LOG_FD'
       AC_TRY_EVAL([lt_ar_try])
-      if test 0 -eq "$ac_status"; then
+      if test "$ac_status" -eq 0; then
 	# Ensure the archiver fails upon bogus file names.
 	rm -f conftest.$ac_objext libconftest.a
 	AC_TRY_EVAL([lt_ar_try])
-	if test 0 -ne "$ac_status"; then
+	if test "$ac_status" -ne 0; then
           lt_cv_ar_at_file=@
         fi
       fi
@@ -1529,7 +1466,7 @@ AC_CACHE_CHECK([for archiver @FILE support], [lt_cv_ar_at_file],
      ])
   ])
 
-if test no = "$lt_cv_ar_at_file"; then
+if test "x$lt_cv_ar_at_file" = xno; then
   archiver_list_spec=
 else
   archiver_list_spec=$lt_cv_ar_at_file
@@ -1560,7 +1497,7 @@ old_postuninstall_cmds=
 
 if test -n "$RANLIB"; then
   case $host_os in
-  bitrig* | openbsd*)
+  openbsd*)
     old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$tool_oldlib"
     ;;
   *)
@@ -1596,7 +1533,7 @@ AC_CACHE_CHECK([$1], [$2],
   [$2=no
    m4_if([$4], , [ac_outfile=conftest.$ac_objext], [ac_outfile=$4])
    echo "$lt_simple_compile_test_code" > conftest.$ac_ext
-   lt_compiler_flag="$3"  ## exclude from sc_useless_quotes_in_assignment
+   lt_compiler_flag="$3"
    # Insert the option either (1) after the last *FLAGS variable, or
    # (2) before a word containing "conftest.", or (3) at the end.
    # Note that $ac_compile itself does not contain backslashes and begins
@@ -1623,7 +1560,7 @@ AC_CACHE_CHECK([$1], [$2],
    $RM conftest*
 ])
 
-if test yes = "[$]$2"; then
+if test x"[$]$2" = xyes; then
     m4_if([$5], , :, [$5])
 else
     m4_if([$6], , :, [$6])
@@ -1645,7 +1582,7 @@ AC_DEFUN([_LT_LINKER_OPTION],
 m4_require([_LT_DECL_SED])dnl
 AC_CACHE_CHECK([$1], [$2],
   [$2=no
-   save_LDFLAGS=$LDFLAGS
+   save_LDFLAGS="$LDFLAGS"
    LDFLAGS="$LDFLAGS $3"
    echo "$lt_simple_link_test_code" > conftest.$ac_ext
    if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then
@@ -1664,10 +1601,10 @@ AC_CACHE_CHECK([$1], [$2],
      fi
    fi
    $RM -r conftest*
-   LDFLAGS=$save_LDFLAGS
+   LDFLAGS="$save_LDFLAGS"
 ])
 
-if test yes = "[$]$2"; then
+if test x"[$]$2" = xyes; then
     m4_if([$4], , :, [$4])
 else
     m4_if([$5], , :, [$5])
@@ -1688,7 +1625,7 @@ AC_DEFUN([LT_CMD_MAX_LEN],
 AC_MSG_CHECKING([the maximum length of command line arguments])
 AC_CACHE_VAL([lt_cv_sys_max_cmd_len], [dnl
   i=0
-  teststring=ABCD
+  teststring="ABCD"
 
   case $build_os in
   msdosdjgpp*)
@@ -1728,7 +1665,7 @@ AC_CACHE_VAL([lt_cv_sys_max_cmd_len], [dnl
     lt_cv_sys_max_cmd_len=8192;
     ;;
 
-  bitrig* | darwin* | dragonfly* | freebsd* | netbsd* | openbsd*)
+  netbsd* | freebsd* | openbsd* | darwin* | dragonfly*)
     # This has been around since 386BSD, at least.  Likely further.
     if test -x /sbin/sysctl; then
       lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax`
@@ -1779,22 +1716,22 @@ AC_CACHE_VAL([lt_cv_sys_max_cmd_len], [dnl
   *)
     lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null`
     if test -n "$lt_cv_sys_max_cmd_len" && \
-       test undefined != "$lt_cv_sys_max_cmd_len"; then
+	test undefined != "$lt_cv_sys_max_cmd_len"; then
       lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4`
       lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3`
     else
       # Make teststring a little bigger before we do anything with it.
       # a 1K string should be a reasonable start.
-      for i in 1 2 3 4 5 6 7 8; do
+      for i in 1 2 3 4 5 6 7 8 ; do
         teststring=$teststring$teststring
       done
       SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}}
       # If test is not a shell built-in, we'll probably end up computing a
       # maximum length that is only half of the actual maximum length, but
       # we can't tell.
-      while { test X`env echo "$teststring$teststring" 2>/dev/null` \
+      while { test "X"`env echo "$teststring$teststring" 2>/dev/null` \
 	         = "X$teststring$teststring"; } >/dev/null 2>&1 &&
-	      test 17 != "$i" # 1/2 MB should be enough
+	      test $i != 17 # 1/2 MB should be enough
       do
         i=`expr $i + 1`
         teststring=$teststring$teststring
@@ -1810,7 +1747,7 @@ AC_CACHE_VAL([lt_cv_sys_max_cmd_len], [dnl
     ;;
   esac
 ])
-if test -n "$lt_cv_sys_max_cmd_len"; then
+if test -n $lt_cv_sys_max_cmd_len ; then
   AC_MSG_RESULT($lt_cv_sys_max_cmd_len)
 else
   AC_MSG_RESULT(none)
@@ -1838,7 +1775,7 @@ m4_defun([_LT_HEADER_DLFCN],
 # ----------------------------------------------------------------
 m4_defun([_LT_TRY_DLOPEN_SELF],
 [m4_require([_LT_HEADER_DLFCN])dnl
-if test yes = "$cross_compiling"; then :
+if test "$cross_compiling" = yes; then :
   [$4]
 else
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
@@ -1885,9 +1822,9 @@ else
 #  endif
 #endif
 
-/* When -fvisibility=hidden is used, assume the code has been annotated
+/* When -fvisbility=hidden is used, assume the code has been annotated
    correspondingly for the symbols needed.  */
-#if defined __GNUC__ && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3))
+#if defined(__GNUC__) && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3))
 int fnord () __attribute__((visibility("default")));
 #endif
 
@@ -1913,7 +1850,7 @@ int main ()
   return status;
 }]
 _LT_EOF
-  if AC_TRY_EVAL(ac_link) && test -s "conftest$ac_exeext" 2>/dev/null; then
+  if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext} 2>/dev/null; then
     (./conftest; exit; ) >&AS_MESSAGE_LOG_FD 2>/dev/null
     lt_status=$?
     case x$lt_status in
@@ -1934,7 +1871,7 @@ rm -fr conftest*
 # ------------------
 AC_DEFUN([LT_SYS_DLOPEN_SELF],
 [m4_require([_LT_HEADER_DLFCN])dnl
-if test yes != "$enable_dlopen"; then
+if test "x$enable_dlopen" != xyes; then
   enable_dlopen=unknown
   enable_dlopen_self=unknown
   enable_dlopen_self_static=unknown
@@ -1944,52 +1881,44 @@ else
 
   case $host_os in
   beos*)
-    lt_cv_dlopen=load_add_on
+    lt_cv_dlopen="load_add_on"
     lt_cv_dlopen_libs=
     lt_cv_dlopen_self=yes
     ;;
 
   mingw* | pw32* | cegcc*)
-    lt_cv_dlopen=LoadLibrary
+    lt_cv_dlopen="LoadLibrary"
     lt_cv_dlopen_libs=
     ;;
 
   cygwin*)
-    lt_cv_dlopen=dlopen
+    lt_cv_dlopen="dlopen"
     lt_cv_dlopen_libs=
     ;;
 
   darwin*)
-    # if libdl is installed we need to link against it
+  # if libdl is installed we need to link against it
     AC_CHECK_LIB([dl], [dlopen],
-		[lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-ldl],[
-    lt_cv_dlopen=dyld
+		[lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"],[
+    lt_cv_dlopen="dyld"
     lt_cv_dlopen_libs=
     lt_cv_dlopen_self=yes
     ])
     ;;
 
-  tpf*)
-    # Don't try to run any link tests for TPF.  We know it's impossible
-    # because TPF is a cross-compiler, and we know how we open DSOs.
-    lt_cv_dlopen=dlopen
-    lt_cv_dlopen_libs=
-    lt_cv_dlopen_self=no
-    ;;
-
   *)
     AC_CHECK_FUNC([shl_load],
-	  [lt_cv_dlopen=shl_load],
+	  [lt_cv_dlopen="shl_load"],
       [AC_CHECK_LIB([dld], [shl_load],
-	    [lt_cv_dlopen=shl_load lt_cv_dlopen_libs=-ldld],
+	    [lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-ldld"],
 	[AC_CHECK_FUNC([dlopen],
-	      [lt_cv_dlopen=dlopen],
+	      [lt_cv_dlopen="dlopen"],
 	  [AC_CHECK_LIB([dl], [dlopen],
-		[lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-ldl],
+		[lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"],
 	    [AC_CHECK_LIB([svld], [dlopen],
-		  [lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-lsvld],
+		  [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld"],
 	      [AC_CHECK_LIB([dld], [dld_link],
-		    [lt_cv_dlopen=dld_link lt_cv_dlopen_libs=-ldld])
+		    [lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-ldld"])
 	      ])
 	    ])
 	  ])
@@ -1998,21 +1927,21 @@ else
     ;;
   esac
 
-  if test no = "$lt_cv_dlopen"; then
-    enable_dlopen=no
-  else
+  if test "x$lt_cv_dlopen" != xno; then
     enable_dlopen=yes
+  else
+    enable_dlopen=no
   fi
 
   case $lt_cv_dlopen in
   dlopen)
-    save_CPPFLAGS=$CPPFLAGS
-    test yes = "$ac_cv_header_dlfcn_h" && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H"
+    save_CPPFLAGS="$CPPFLAGS"
+    test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H"
 
-    save_LDFLAGS=$LDFLAGS
+    save_LDFLAGS="$LDFLAGS"
     wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\"
 
-    save_LIBS=$LIBS
+    save_LIBS="$LIBS"
     LIBS="$lt_cv_dlopen_libs $LIBS"
 
     AC_CACHE_CHECK([whether a program can dlopen itself],
@@ -2022,7 +1951,7 @@ else
 	    lt_cv_dlopen_self=no, lt_cv_dlopen_self=cross)
     ])
 
-    if test yes = "$lt_cv_dlopen_self"; then
+    if test "x$lt_cv_dlopen_self" = xyes; then
       wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\"
       AC_CACHE_CHECK([whether a statically linked program can dlopen itself],
 	  lt_cv_dlopen_self_static, [dnl
@@ -2032,9 +1961,9 @@ else
       ])
     fi
 
-    CPPFLAGS=$save_CPPFLAGS
-    LDFLAGS=$save_LDFLAGS
-    LIBS=$save_LIBS
+    CPPFLAGS="$save_CPPFLAGS"
+    LDFLAGS="$save_LDFLAGS"
+    LIBS="$save_LIBS"
     ;;
   esac
 
@@ -2126,8 +2055,8 @@ m4_defun([_LT_COMPILER_FILE_LOCKS],
 m4_require([_LT_FILEUTILS_DEFAULTS])dnl
 _LT_COMPILER_C_O([$1])
 
-hard_links=nottested
-if test no = "$_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)" && test no != "$need_locks"; then
+hard_links="nottested"
+if test "$_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)" = no && test "$need_locks" != no; then
   # do not overwrite the value of need_locks provided by the user
   AC_MSG_CHECKING([if we can lock with hard links])
   hard_links=yes
@@ -2137,8 +2066,8 @@ if test no = "$_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)" && test no != "$need_loc
   ln conftest.a conftest.b 2>&5 || hard_links=no
   ln conftest.a conftest.b 2>/dev/null && hard_links=no
   AC_MSG_RESULT([$hard_links])
-  if test no = "$hard_links"; then
-    AC_MSG_WARN(['$CC' does not support '-c -o', so 'make -j' may be unsafe])
+  if test "$hard_links" = no; then
+    AC_MSG_WARN([`$CC' does not support `-c -o', so `make -j' may be unsafe])
     need_locks=warn
   fi
 else
@@ -2165,8 +2094,8 @@ objdir=$lt_cv_objdir
 _LT_DECL([], [objdir], [0],
          [The name of the directory that contains temporary libtool files])dnl
 m4_pattern_allow([LT_OBJDIR])dnl
-AC_DEFINE_UNQUOTED([LT_OBJDIR], "$lt_cv_objdir/",
-  [Define to the sub-directory where libtool stores uninstalled libraries.])
+AC_DEFINE_UNQUOTED(LT_OBJDIR, "$lt_cv_objdir/",
+  [Define to the sub-directory in which libtool stores uninstalled libraries.])
 ])# _LT_CHECK_OBJDIR
 
 
@@ -2178,15 +2107,15 @@ m4_defun([_LT_LINKER_HARDCODE_LIBPATH],
 _LT_TAGVAR(hardcode_action, $1)=
 if test -n "$_LT_TAGVAR(hardcode_libdir_flag_spec, $1)" ||
    test -n "$_LT_TAGVAR(runpath_var, $1)" ||
-   test yes = "$_LT_TAGVAR(hardcode_automatic, $1)"; then
+   test "X$_LT_TAGVAR(hardcode_automatic, $1)" = "Xyes" ; then
 
   # We can hardcode non-existent directories.
-  if test no != "$_LT_TAGVAR(hardcode_direct, $1)" &&
+  if test "$_LT_TAGVAR(hardcode_direct, $1)" != no &&
      # If the only mechanism to avoid hardcoding is shlibpath_var, we
      # have to relink, otherwise we might link with an installed library
      # when we should be linking with a yet-to-be-installed one
-     ## test no != "$_LT_TAGVAR(hardcode_shlibpath_var, $1)" &&
-     test no != "$_LT_TAGVAR(hardcode_minus_L, $1)"; then
+     ## test "$_LT_TAGVAR(hardcode_shlibpath_var, $1)" != no &&
+     test "$_LT_TAGVAR(hardcode_minus_L, $1)" != no; then
     # Linking always hardcodes the temporary library directory.
     _LT_TAGVAR(hardcode_action, $1)=relink
   else
@@ -2200,12 +2129,12 @@ else
 fi
 AC_MSG_RESULT([$_LT_TAGVAR(hardcode_action, $1)])
 
-if test relink = "$_LT_TAGVAR(hardcode_action, $1)" ||
-   test yes = "$_LT_TAGVAR(inherit_rpath, $1)"; then
+if test "$_LT_TAGVAR(hardcode_action, $1)" = relink ||
+   test "$_LT_TAGVAR(inherit_rpath, $1)" = yes; then
   # Fast installation is not supported
   enable_fast_install=no
-elif test yes = "$shlibpath_overrides_runpath" ||
-     test no = "$enable_shared"; then
+elif test "$shlibpath_overrides_runpath" = yes ||
+     test "$enable_shared" = no; then
   # Fast installation is not necessary
   enable_fast_install=needless
 fi
@@ -2229,7 +2158,7 @@ else
 # FIXME - insert some real tests, host_os isn't really good enough
   case $host_os in
   darwin*)
-    if test -n "$STRIP"; then
+    if test -n "$STRIP" ; then
       striplib="$STRIP -x"
       old_striplib="$STRIP -S"
       AC_MSG_RESULT([yes])
@@ -2247,47 +2176,6 @@ _LT_DECL([], [striplib], [1])
 ])# _LT_CMD_STRIPLIB
 
 
-# _LT_PREPARE_MUNGE_PATH_LIST
-# ---------------------------
-# Make sure func_munge_path_list() is defined correctly.
-m4_defun([_LT_PREPARE_MUNGE_PATH_LIST],
-[[# func_munge_path_list VARIABLE PATH
-# -----------------------------------
-# VARIABLE is name of variable containing _space_ separated list of
-# directories to be munged by the contents of PATH, which is string
-# having a format:
-# "DIR[:DIR]:"
-#       string "DIR[ DIR]" will be prepended to VARIABLE
-# ":DIR[:DIR]"
-#       string "DIR[ DIR]" will be appended to VARIABLE
-# "DIRP[:DIRP]::[DIRA:]DIRA"
-#       string "DIRP[ DIRP]" will be prepended to VARIABLE and string
-#       "DIRA[ DIRA]" will be appended to VARIABLE
-# "DIR[:DIR]"
-#       VARIABLE will be replaced by "DIR[ DIR]"
-func_munge_path_list ()
-{
-    case x at S|@2 in
-    x)
-        ;;
-    *:)
-        eval @S|@1=\"`$ECHO @S|@2 | $SED 's/:/ /g'` \@S|@@S|@1\"
-        ;;
-    x:*)
-        eval @S|@1=\"\@S|@@S|@1 `$ECHO @S|@2 | $SED 's/:/ /g'`\"
-        ;;
-    *::*)
-        eval @S|@1=\"\@S|@@S|@1\ `$ECHO @S|@2 | $SED -e 's/.*:://' -e 's/:/ /g'`\"
-        eval @S|@1=\"`$ECHO @S|@2 | $SED -e 's/::.*//' -e 's/:/ /g'`\ \@S|@@S|@1\"
-        ;;
-    *)
-        eval @S|@1=\"`$ECHO @S|@2 | $SED 's/:/ /g'`\"
-        ;;
-    esac
-}
-]])# _LT_PREPARE_PATH_LIST
-
-
 # _LT_SYS_DYNAMIC_LINKER([TAG])
 # -----------------------------
 # PORTME Fill in your ld.so characteristics
@@ -2298,18 +2186,17 @@ m4_require([_LT_FILEUTILS_DEFAULTS])dnl
 m4_require([_LT_DECL_OBJDUMP])dnl
 m4_require([_LT_DECL_SED])dnl
 m4_require([_LT_CHECK_SHELL_FEATURES])dnl
-m4_require([_LT_PREPARE_MUNGE_PATH_LIST])dnl
 AC_MSG_CHECKING([dynamic linker characteristics])
 m4_if([$1],
 	[], [
-if test yes = "$GCC"; then
+if test "$GCC" = yes; then
   case $host_os in
-    darwin*) lt_awk_arg='/^libraries:/,/LR/' ;;
-    *) lt_awk_arg='/^libraries:/' ;;
+    darwin*) lt_awk_arg="/^libraries:/,/LR/" ;;
+    *) lt_awk_arg="/^libraries:/" ;;
   esac
   case $host_os in
-    mingw* | cegcc*) lt_sed_strip_eq='s|=\([[A-Za-z]]:\)|\1|g' ;;
-    *) lt_sed_strip_eq='s|=/|/|g' ;;
+    mingw* | cegcc*) lt_sed_strip_eq="s,=\([[A-Za-z]]:\),\1,g" ;;
+    *) lt_sed_strip_eq="s,=/,/,g" ;;
   esac
   lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e $lt_sed_strip_eq`
   case $lt_search_path_spec in
@@ -2325,35 +2212,28 @@ if test yes = "$GCC"; then
     ;;
   esac
   # Ok, now we have the path, separated by spaces, we can step through it
-  # and add multilib dir if necessary...
+  # and add multilib dir if necessary.
   lt_tmp_lt_search_path_spec=
-  lt_multi_os_dir=/`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null`
-  # ...but if some path component already ends with the multilib dir we assume
-  # that all is fine and trust -print-search-dirs as is (GCC 4.2? or newer).
-  case "$lt_multi_os_dir; $lt_search_path_spec " in
-  "/; "* | "/.; "* | "/./; "* | *"$lt_multi_os_dir "* | *"$lt_multi_os_dir/ "*)
-    lt_multi_os_dir=
-    ;;
-  esac
+  lt_multi_os_dir=`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null`
   for lt_sys_path in $lt_search_path_spec; do
-    if test -d "$lt_sys_path$lt_multi_os_dir"; then
-      lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path$lt_multi_os_dir"
-    elif test -n "$lt_multi_os_dir"; then
+    if test -d "$lt_sys_path/$lt_multi_os_dir"; then
+      lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path/$lt_multi_os_dir"
+    else
       test -d "$lt_sys_path" && \
 	lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path"
     fi
   done
   lt_search_path_spec=`$ECHO "$lt_tmp_lt_search_path_spec" | awk '
-BEGIN {RS = " "; FS = "/|\n";} {
-  lt_foo = "";
-  lt_count = 0;
+BEGIN {RS=" "; FS="/|\n";} {
+  lt_foo="";
+  lt_count=0;
   for (lt_i = NF; lt_i > 0; lt_i--) {
     if ($lt_i != "" && $lt_i != ".") {
       if ($lt_i == "..") {
         lt_count++;
       } else {
         if (lt_count == 0) {
-          lt_foo = "/" $lt_i lt_foo;
+          lt_foo="/" $lt_i lt_foo;
         } else {
           lt_count--;
         }
@@ -2367,7 +2247,7 @@ BEGIN {RS = " "; FS = "/|\n";} {
   # for these hosts.
   case $host_os in
     mingw* | cegcc*) lt_search_path_spec=`$ECHO "$lt_search_path_spec" |\
-      $SED 's|/\([[A-Za-z]]:\)|\1|g'` ;;
+      $SED 's,/\([[A-Za-z]]:\),\1,g'` ;;
   esac
   sys_lib_search_path_spec=`$ECHO "$lt_search_path_spec" | $lt_NL2SP`
 else
@@ -2376,7 +2256,7 @@ fi])
 library_names_spec=
 libname_spec='lib$name'
 soname_spec=
-shrext_cmds=.so
+shrext_cmds=".so"
 postinstall_cmds=
 postuninstall_cmds=
 finish_cmds=
@@ -2393,17 +2273,14 @@ hardcode_into_libs=no
 # flags to be left without arguments
 need_version=unknown
 
-AC_ARG_VAR([LT_SYS_LIBRARY_PATH],
-[User-defined run-time library search path.])
-
 case $host_os in
 aix3*)
   version_type=linux # correct to gnu/linux during the next big refactor
-  library_names_spec='$libname$release$shared_ext$versuffix $libname.a'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a'
   shlibpath_var=LIBPATH
 
   # AIX 3 has no versioning support, so we append a major version to the name.
-  soname_spec='$libname$release$shared_ext$major'
+  soname_spec='${libname}${release}${shared_ext}$major'
   ;;
 
 aix[[4-9]]*)
@@ -2411,91 +2288,41 @@ aix[[4-9]]*)
   need_lib_prefix=no
   need_version=no
   hardcode_into_libs=yes
-  if test ia64 = "$host_cpu"; then
+  if test "$host_cpu" = ia64; then
     # AIX 5 supports IA64
-    library_names_spec='$libname$release$shared_ext$major $libname$release$shared_ext$versuffix $libname$shared_ext'
+    library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}'
     shlibpath_var=LD_LIBRARY_PATH
   else
     # With GCC up to 2.95.x, collect2 would create an import file
     # for dependence libraries.  The import file would start with
-    # the line '#! .'.  This would cause the generated library to
-    # depend on '.', always an invalid library.  This was fixed in
+    # the line `#! .'.  This would cause the generated library to
+    # depend on `.', always an invalid library.  This was fixed in
     # development snapshots of GCC prior to 3.0.
     case $host_os in
       aix4 | aix4.[[01]] | aix4.[[01]].*)
       if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)'
 	   echo ' yes '
-	   echo '#endif'; } | $CC -E - | $GREP yes > /dev/null; then
+	   echo '#endif'; } | ${CC} -E - | $GREP yes > /dev/null; then
 	:
       else
 	can_build_shared=no
       fi
       ;;
     esac
-    # Using Import Files as archive members, it is possible to support
-    # filename-based versioning of shared library archives on AIX. While
-    # this would work for both with and without runtime linking, it will
-    # prevent static linking of such archives. So we do filename-based
-    # shared library versioning with .so extension only, which is used
-    # when both runtime linking and shared linking is enabled.
-    # Unfortunately, runtime linking may impact performance, so we do
-    # not want this to be the default eventually. Also, we use the
-    # versioned .so libs for executables only if there is the -brtl
-    # linker flag in LDFLAGS as well, or --with-aix-soname=svr4 only.
-    # To allow for filename-based versioning support, we need to create
-    # libNAME.so.V as an archive file, containing:
-    # *) an Import File, referring to the versioned filename of the
-    #    archive as well as the shared archive member, telling the
-    #    bitwidth (32 or 64) of that shared object, and providing the
-    #    list of exported symbols of that shared object, eventually
-    #    decorated with the 'weak' keyword
-    # *) the shared object with the F_LOADONLY flag set, to really avoid
-    #    it being seen by the linker.
-    # At run time we better use the real file rather than another symlink,
-    # but for link time we create the symlink libNAME.so -> libNAME.so.V
-
-    case $with_aix_soname,$aix_use_runtimelinking in
-    # AIX (on Power*) has no versioning support, so currently we cannot hardcode correct
+    # AIX (on Power*) has no versioning support, so currently we can not hardcode correct
     # soname into executable. Probably we can add versioning support to
     # collect2, so additional links can be useful in future.
-    aix,yes) # traditional libtool
-      dynamic_linker='AIX unversionable lib.so'
+    if test "$aix_use_runtimelinking" = yes; then
       # If using run time linking (on AIX 4.2 or later) use lib<name>.so
       # instead of lib<name>.a to let people know that these are not
       # typical AIX shared libraries.
-      library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
-      ;;
-    aix,no) # traditional AIX only
-      dynamic_linker='AIX lib.a[(]lib.so.V[)]'
+      library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+    else
       # We preserve .a as extension for shared libraries through AIX4.2
       # and later when we are not doing run time linking.
-      library_names_spec='$libname$release.a $libname.a'
-      soname_spec='$libname$release$shared_ext$major'
-      ;;
-    svr4,*) # full svr4 only
-      dynamic_linker="AIX lib.so.V[(]$shared_archive_member_spec.o[)]"
-      library_names_spec='$libname$release$shared_ext$major $libname$shared_ext'
-      # We do not specify a path in Import Files, so LIBPATH fires.
-      shlibpath_overrides_runpath=yes
-      ;;
-    *,yes) # both, prefer svr4
-      dynamic_linker="AIX lib.so.V[(]$shared_archive_member_spec.o[)], lib.a[(]lib.so.V[)]"
-      library_names_spec='$libname$release$shared_ext$major $libname$shared_ext'
-      # unpreferred sharedlib libNAME.a needs extra handling
-      postinstall_cmds='test -n "$linkname" || linkname="$realname"~func_stripname "" ".so" "$linkname"~$install_shared_prog "$dir/$func_stripname_result.$libext" "$destdir/$func_stripname_result.$libext"~test -z "$tstripme" || test -z "$striplib" || $striplib "$destdir/$func_stripname_result.$libext"'
-      postuninstall_cmds='for n in $library_names $old_library; do :; done~func_stripname "" ".so" "$n"~test "$func_stripname_result" = "$n" || func_append rmfiles " $odir/$func_stripname_result.$libext"'
-      # We do not specify a path in Import Files, so LIBPATH fires.
-      shlibpath_overrides_runpath=yes
-      ;;
-    *,no) # both, prefer aix
-      dynamic_linker="AIX lib.a[(]lib.so.V[)], lib.so.V[(]$shared_archive_member_spec.o[)]"
-      library_names_spec='$libname$release.a $libname.a'
-      soname_spec='$libname$release$shared_ext$major'
-      # unpreferred sharedlib libNAME.so.V and symlink libNAME.so need extra handling
-      postinstall_cmds='test -z "$dlname" || $install_shared_prog $dir/$dlname $destdir/$dlname~test -z "$tstripme" || test -z "$striplib" || $striplib $destdir/$dlname~test -n "$linkname" || linkname=$realname~func_stripname "" ".a" "$linkname"~(cd "$destdir" && $LN_S -f $dlname $func_stripname_result.so)'
-      postuninstall_cmds='test -z "$dlname" || func_append rmfiles " $odir/$dlname"~for n in $old_library $library_names; do :; done~func_stripname "" ".a" "$n"~func_append rmfiles " $odir/$func_stripname_result.so"'
-      ;;
-    esac
+      library_names_spec='${libname}${release}.a $libname.a'
+      soname_spec='${libname}${release}${shared_ext}$major'
+    fi
     shlibpath_var=LIBPATH
   fi
   ;;
@@ -2505,18 +2332,18 @@ amigaos*)
   powerpc)
     # Since July 2007 AmigaOS4 officially supports .so libraries.
     # When compiling the executable, add -use-dynld -Lsobjs: to the compileline.
-    library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
     ;;
   m68k)
     library_names_spec='$libname.ixlibrary $libname.a'
     # Create ${libname}_ixlibrary.a entries in /sys/libs.
-    finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([[^/]]*\)\.ixlibrary$%\1%'\''`; $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done'
+    finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([[^/]]*\)\.ixlibrary$%\1%'\''`; test $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done'
     ;;
   esac
   ;;
 
 beos*)
-  library_names_spec='$libname$shared_ext'
+  library_names_spec='${libname}${shared_ext}'
   dynamic_linker="$host_os ld.so"
   shlibpath_var=LIBRARY_PATH
   ;;
@@ -2524,8 +2351,8 @@ beos*)
 bsdi[[45]]*)
   version_type=linux # correct to gnu/linux during the next big refactor
   need_version=no
-  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
-  soname_spec='$libname$release$shared_ext$major'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
   finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir'
   shlibpath_var=LD_LIBRARY_PATH
   sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib"
@@ -2537,7 +2364,7 @@ bsdi[[45]]*)
 
 cygwin* | mingw* | pw32* | cegcc*)
   version_type=windows
-  shrext_cmds=.dll
+  shrext_cmds=".dll"
   need_version=no
   need_lib_prefix=no
 
@@ -2546,8 +2373,8 @@ cygwin* | mingw* | pw32* | cegcc*)
     # gcc
     library_names_spec='$libname.dll.a'
     # DLL is installed to $(libdir)/../bin by postinstall_cmds
-    postinstall_cmds='base_file=`basename \$file`~
-      dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~
+    postinstall_cmds='base_file=`basename \${file}`~
+      dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~
       dldir=$destdir/`dirname \$dlpath`~
       test -d \$dldir || mkdir -p \$dldir~
       $install_prog $dir/$dlname \$dldir/$dlname~
@@ -2563,17 +2390,17 @@ cygwin* | mingw* | pw32* | cegcc*)
     case $host_os in
     cygwin*)
       # Cygwin DLLs use 'cyg' prefix rather than 'lib'
-      soname_spec='`echo $libname | sed -e 's/^lib/cyg/'``echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext'
+      soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}'
 m4_if([$1], [],[
       sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/lib/w32api"])
       ;;
     mingw* | cegcc*)
       # MinGW DLLs use traditional 'lib' prefix
-      soname_spec='$libname`echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext'
+      soname_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}'
       ;;
     pw32*)
       # pw32 DLLs use 'pw' prefix rather than 'lib'
-      library_names_spec='`echo $libname | sed -e 's/^lib/pw/'``echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext'
+      library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}'
       ;;
     esac
     dynamic_linker='Win32 ld.exe'
@@ -2582,8 +2409,8 @@ m4_if([$1], [],[
   *,cl*)
     # Native MSVC
     libname_spec='$name'
-    soname_spec='$libname`echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext'
-    library_names_spec='$libname.dll.lib'
+    soname_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}'
+    library_names_spec='${libname}.dll.lib'
 
     case $build_os in
     mingw*)
@@ -2610,7 +2437,7 @@ m4_if([$1], [],[
       sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"`
       ;;
     *)
-      sys_lib_search_path_spec=$LIB
+      sys_lib_search_path_spec="$LIB"
       if $ECHO "$sys_lib_search_path_spec" | [$GREP ';[c-zC-Z]:/' >/dev/null]; then
         # It is most probably a Windows format PATH.
         sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'`
@@ -2623,8 +2450,8 @@ m4_if([$1], [],[
     esac
 
     # DLL is installed to $(libdir)/../bin by postinstall_cmds
-    postinstall_cmds='base_file=`basename \$file`~
-      dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~
+    postinstall_cmds='base_file=`basename \${file}`~
+      dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~
       dldir=$destdir/`dirname \$dlpath`~
       test -d \$dldir || mkdir -p \$dldir~
       $install_prog $dir/$dlname \$dldir/$dlname'
@@ -2637,7 +2464,7 @@ m4_if([$1], [],[
 
   *)
     # Assume MSVC wrapper
-    library_names_spec='$libname`echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext $libname.lib'
+    library_names_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext} $libname.lib'
     dynamic_linker='Win32 ld.exe'
     ;;
   esac
@@ -2650,8 +2477,8 @@ darwin* | rhapsody*)
   version_type=darwin
   need_lib_prefix=no
   need_version=no
-  library_names_spec='$libname$release$major$shared_ext $libname$shared_ext'
-  soname_spec='$libname$release$major$shared_ext'
+  library_names_spec='${libname}${release}${major}$shared_ext ${libname}$shared_ext'
+  soname_spec='${libname}${release}${major}$shared_ext'
   shlibpath_overrides_runpath=yes
   shlibpath_var=DYLD_LIBRARY_PATH
   shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`'
@@ -2664,8 +2491,8 @@ dgux*)
   version_type=linux # correct to gnu/linux during the next big refactor
   need_lib_prefix=no
   need_version=no
-  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
-  soname_spec='$libname$release$shared_ext$major'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext'
+  soname_spec='${libname}${release}${shared_ext}$major'
   shlibpath_var=LD_LIBRARY_PATH
   ;;
 
@@ -2683,13 +2510,12 @@ freebsd* | dragonfly*)
   version_type=freebsd-$objformat
   case $version_type in
     freebsd-elf*)
-      library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
-      soname_spec='$libname$release$shared_ext$major'
+      library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}'
       need_version=no
       need_lib_prefix=no
       ;;
     freebsd-*)
-      library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix'
+      library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix'
       need_version=yes
       ;;
   esac
@@ -2719,10 +2545,10 @@ haiku*)
   need_lib_prefix=no
   need_version=no
   dynamic_linker="$host_os runtime_loader"
-  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
-  soname_spec='$libname$release$shared_ext$major'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
   shlibpath_var=LIBRARY_PATH
-  shlibpath_overrides_runpath=no
+  shlibpath_overrides_runpath=yes
   sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib'
   hardcode_into_libs=yes
   ;;
@@ -2740,15 +2566,14 @@ hpux9* | hpux10* | hpux11*)
     dynamic_linker="$host_os dld.so"
     shlibpath_var=LD_LIBRARY_PATH
     shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
-    library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
-    soname_spec='$libname$release$shared_ext$major'
-    if test 32 = "$HPUX_IA64_MODE"; then
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+    soname_spec='${libname}${release}${shared_ext}$major'
+    if test "X$HPUX_IA64_MODE" = X32; then
       sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib"
-      sys_lib_dlsearch_path_spec=/usr/lib/hpux32
     else
       sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64"
-      sys_lib_dlsearch_path_spec=/usr/lib/hpux64
     fi
+    sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
     ;;
   hppa*64*)
     shrext_cmds='.sl'
@@ -2756,8 +2581,8 @@ hpux9* | hpux10* | hpux11*)
     dynamic_linker="$host_os dld.sl"
     shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH
     shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
-    library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
-    soname_spec='$libname$release$shared_ext$major'
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+    soname_spec='${libname}${release}${shared_ext}$major'
     sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64"
     sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
     ;;
@@ -2766,8 +2591,8 @@ hpux9* | hpux10* | hpux11*)
     dynamic_linker="$host_os dld.sl"
     shlibpath_var=SHLIB_PATH
     shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH
-    library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
-    soname_spec='$libname$release$shared_ext$major'
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+    soname_spec='${libname}${release}${shared_ext}$major'
     ;;
   esac
   # HP-UX runs *really* slowly unless shared libraries are mode 555, ...
@@ -2780,8 +2605,8 @@ interix[[3-9]]*)
   version_type=linux # correct to gnu/linux during the next big refactor
   need_lib_prefix=no
   need_version=no
-  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
-  soname_spec='$libname$release$shared_ext$major'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
   dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)'
   shlibpath_var=LD_LIBRARY_PATH
   shlibpath_overrides_runpath=no
@@ -2792,7 +2617,7 @@ irix5* | irix6* | nonstopux*)
   case $host_os in
     nonstopux*) version_type=nonstopux ;;
     *)
-	if test yes = "$lt_cv_prog_gnu_ld"; then
+	if test "$lt_cv_prog_gnu_ld" = yes; then
 		version_type=linux # correct to gnu/linux during the next big refactor
 	else
 		version_type=irix
@@ -2800,8 +2625,8 @@ irix5* | irix6* | nonstopux*)
   esac
   need_lib_prefix=no
   need_version=no
-  soname_spec='$libname$release$shared_ext$major'
-  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$release$shared_ext $libname$shared_ext'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}'
   case $host_os in
   irix5* | nonstopux*)
     libsuff= shlibsuff=
@@ -2820,8 +2645,8 @@ irix5* | irix6* | nonstopux*)
   esac
   shlibpath_var=LD_LIBRARY${shlibsuff}_PATH
   shlibpath_overrides_runpath=no
-  sys_lib_search_path_spec="/usr/lib$libsuff /lib$libsuff /usr/local/lib$libsuff"
-  sys_lib_dlsearch_path_spec="/usr/lib$libsuff /lib$libsuff"
+  sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}"
+  sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}"
   hardcode_into_libs=yes
   ;;
 
@@ -2830,33 +2655,13 @@ linux*oldld* | linux*aout* | linux*coff*)
   dynamic_linker=no
   ;;
 
-linux*android*)
-  version_type=none # Android doesn't support versioned libraries.
-  need_lib_prefix=no
-  need_version=no
-  library_names_spec='$libname$release$shared_ext'
-  soname_spec='$libname$release$shared_ext'
-  finish_cmds=
-  shlibpath_var=LD_LIBRARY_PATH
-  shlibpath_overrides_runpath=yes
-
-  # This implies no fast_install, which is unacceptable.
-  # Some rework will be needed to allow for fast_install
-  # before this can be enabled.
-  hardcode_into_libs=yes
-
-  dynamic_linker='Android linker'
-  # Don't embed -rpath directories since the linker doesn't support them.
-  _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
-  ;;
-
 # This must be glibc/ELF.
 linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*)
   version_type=linux # correct to gnu/linux during the next big refactor
   need_lib_prefix=no
   need_version=no
-  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
-  soname_spec='$libname$release$shared_ext$major'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
   finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir'
   shlibpath_var=LD_LIBRARY_PATH
   shlibpath_overrides_runpath=no
@@ -2881,12 +2686,7 @@ linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*)
   # before this can be enabled.
   hardcode_into_libs=yes
 
-  # Ideally, we could use ldconfig to report *all* directores which are
-  # searched for libraries, however this is still not possible.  Aside from not
-  # being certain /sbin/ldconfig is available, command
-  # 'ldconfig -N -X -v | grep ^/' on 64bit Fedora does not report /usr/lib64,
-  # even though it is searched at run-time.  Try to do the best guess by
-  # appending ld.so.conf contents (and includes) to the search path.
+  # Append ld.so.conf contents to the search path
   if test -f /etc/ld.so.conf; then
     lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \[$]2)); skip = 1; } { if (!skip) print \[$]0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[	 ]*hwcap[	 ]/d;s/[:,	]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '`
     sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra"
@@ -2918,12 +2718,12 @@ netbsd*)
   need_lib_prefix=no
   need_version=no
   if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
-    library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix'
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
     finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
     dynamic_linker='NetBSD (a.out) ld.so'
   else
-    library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
-    soname_spec='$libname$release$shared_ext$major'
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+    soname_spec='${libname}${release}${shared_ext}$major'
     dynamic_linker='NetBSD ld.elf_so'
   fi
   shlibpath_var=LD_LIBRARY_PATH
@@ -2933,7 +2733,7 @@ netbsd*)
 
 newsos6)
   version_type=linux # correct to gnu/linux during the next big refactor
-  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
   shlibpath_var=LD_LIBRARY_PATH
   shlibpath_overrides_runpath=yes
   ;;
@@ -2942,68 +2742,58 @@ newsos6)
   version_type=qnx
   need_lib_prefix=no
   need_version=no
-  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
-  soname_spec='$libname$release$shared_ext$major'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
   shlibpath_var=LD_LIBRARY_PATH
   shlibpath_overrides_runpath=no
   hardcode_into_libs=yes
   dynamic_linker='ldqnx.so'
   ;;
 
-openbsd* | bitrig*)
+openbsd*)
   version_type=sunos
-  sys_lib_dlsearch_path_spec=/usr/lib
+  sys_lib_dlsearch_path_spec="/usr/lib"
   need_lib_prefix=no
-  if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then
-    need_version=no
-  else
-    need_version=yes
-  fi
-  library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix'
+  # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs.
+  case $host_os in
+    openbsd3.3 | openbsd3.3.*)	need_version=yes ;;
+    *)				need_version=no  ;;
+  esac
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
   finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
   shlibpath_var=LD_LIBRARY_PATH
-  shlibpath_overrides_runpath=yes
+  if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+    case $host_os in
+      openbsd2.[[89]] | openbsd2.[[89]].*)
+	shlibpath_overrides_runpath=no
+	;;
+      *)
+	shlibpath_overrides_runpath=yes
+	;;
+      esac
+  else
+    shlibpath_overrides_runpath=yes
+  fi
   ;;
 
 os2*)
   libname_spec='$name'
-  version_type=windows
-  shrext_cmds=.dll
-  need_version=no
+  shrext_cmds=".dll"
   need_lib_prefix=no
-  # OS/2 can only load a DLL with a base name of 8 characters or less.
-  soname_spec='`test -n "$os2dllname" && libname="$os2dllname";
-    v=$($ECHO $release$versuffix | tr -d .-);
-    n=$($ECHO $libname | cut -b -$((8 - ${#v})) | tr . _);
-    $ECHO $n$v`$shared_ext'
-  library_names_spec='${libname}_dll.$libext'
+  library_names_spec='$libname${shared_ext} $libname.a'
   dynamic_linker='OS/2 ld.exe'
-  shlibpath_var=BEGINLIBPATH
-  sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib"
-  sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
-  postinstall_cmds='base_file=`basename \$file`~
-    dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; $ECHO \$dlname'\''`~
-    dldir=$destdir/`dirname \$dlpath`~
-    test -d \$dldir || mkdir -p \$dldir~
-    $install_prog $dir/$dlname \$dldir/$dlname~
-    chmod a+x \$dldir/$dlname~
-    if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then
-      eval '\''$striplib \$dldir/$dlname'\'' || exit \$?;
-    fi'
-  postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; $ECHO \$dlname'\''`~
-    dlpath=$dir/\$dldll~
-    $RM \$dlpath'
+  shlibpath_var=LIBPATH
   ;;
 
 osf3* | osf4* | osf5*)
   version_type=osf
   need_lib_prefix=no
   need_version=no
-  soname_spec='$libname$release$shared_ext$major'
-  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
   shlibpath_var=LD_LIBRARY_PATH
   sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib"
-  sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
+  sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec"
   ;;
 
 rdos*)
@@ -3014,8 +2804,8 @@ solaris*)
   version_type=linux # correct to gnu/linux during the next big refactor
   need_lib_prefix=no
   need_version=no
-  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
-  soname_spec='$libname$release$shared_ext$major'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
   shlibpath_var=LD_LIBRARY_PATH
   shlibpath_overrides_runpath=yes
   hardcode_into_libs=yes
@@ -3025,11 +2815,11 @@ solaris*)
 
 sunos4*)
   version_type=sunos
-  library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
   finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir'
   shlibpath_var=LD_LIBRARY_PATH
   shlibpath_overrides_runpath=yes
-  if test yes = "$with_gnu_ld"; then
+  if test "$with_gnu_ld" = yes; then
     need_lib_prefix=no
   fi
   need_version=yes
@@ -3037,8 +2827,8 @@ sunos4*)
 
 sysv4 | sysv4.3*)
   version_type=linux # correct to gnu/linux during the next big refactor
-  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
-  soname_spec='$libname$release$shared_ext$major'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
   shlibpath_var=LD_LIBRARY_PATH
   case $host_vendor in
     sni)
@@ -3059,24 +2849,24 @@ sysv4 | sysv4.3*)
   ;;
 
 sysv4*MP*)
-  if test -d /usr/nec; then
+  if test -d /usr/nec ;then
     version_type=linux # correct to gnu/linux during the next big refactor
-    library_names_spec='$libname$shared_ext.$versuffix $libname$shared_ext.$major $libname$shared_ext'
-    soname_spec='$libname$shared_ext.$major'
+    library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}'
+    soname_spec='$libname${shared_ext}.$major'
     shlibpath_var=LD_LIBRARY_PATH
   fi
   ;;
 
 sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
-  version_type=sco
+  version_type=freebsd-elf
   need_lib_prefix=no
   need_version=no
-  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext $libname$shared_ext'
-  soname_spec='$libname$release$shared_ext$major'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
   shlibpath_var=LD_LIBRARY_PATH
   shlibpath_overrides_runpath=yes
   hardcode_into_libs=yes
-  if test yes = "$with_gnu_ld"; then
+  if test "$with_gnu_ld" = yes; then
     sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib'
   else
     sys_lib_search_path_spec='/usr/ccs/lib /usr/lib'
@@ -3094,7 +2884,7 @@ tpf*)
   version_type=linux # correct to gnu/linux during the next big refactor
   need_lib_prefix=no
   need_version=no
-  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
   shlibpath_var=LD_LIBRARY_PATH
   shlibpath_overrides_runpath=no
   hardcode_into_libs=yes
@@ -3102,8 +2892,8 @@ tpf*)
 
 uts4*)
   version_type=linux # correct to gnu/linux during the next big refactor
-  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
-  soname_spec='$libname$release$shared_ext$major'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
   shlibpath_var=LD_LIBRARY_PATH
   ;;
 
@@ -3112,30 +2902,20 @@ uts4*)
   ;;
 esac
 AC_MSG_RESULT([$dynamic_linker])
-test no = "$dynamic_linker" && can_build_shared=no
+test "$dynamic_linker" = no && can_build_shared=no
 
 variables_saved_for_relink="PATH $shlibpath_var $runpath_var"
-if test yes = "$GCC"; then
+if test "$GCC" = yes; then
   variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH"
 fi
 
-if test set = "${lt_cv_sys_lib_search_path_spec+set}"; then
-  sys_lib_search_path_spec=$lt_cv_sys_lib_search_path_spec
+if test "${lt_cv_sys_lib_search_path_spec+set}" = set; then
+  sys_lib_search_path_spec="$lt_cv_sys_lib_search_path_spec"
 fi
-
-if test set = "${lt_cv_sys_lib_dlsearch_path_spec+set}"; then
-  sys_lib_dlsearch_path_spec=$lt_cv_sys_lib_dlsearch_path_spec
+if test "${lt_cv_sys_lib_dlsearch_path_spec+set}" = set; then
+  sys_lib_dlsearch_path_spec="$lt_cv_sys_lib_dlsearch_path_spec"
 fi
 
-# remember unaugmented sys_lib_dlsearch_path content for libtool script decls...
-configure_time_dlsearch_path=$sys_lib_dlsearch_path_spec
-
-# ... but it needs LT_SYS_LIBRARY_PATH munging for other configure-time code
-func_munge_path_list sys_lib_dlsearch_path_spec "$LT_SYS_LIBRARY_PATH"
-
-# to be used as default LT_SYS_LIBRARY_PATH value in generated libtool
-configure_time_lt_sys_library_path=$LT_SYS_LIBRARY_PATH
-
 _LT_DECL([], [variables_saved_for_relink], [1],
     [Variables whose values should be saved in libtool wrapper scripts and
     restored at link time])
@@ -3168,41 +2948,39 @@ _LT_DECL([], [hardcode_into_libs], [0],
     [Whether we should hardcode library paths into libraries])
 _LT_DECL([], [sys_lib_search_path_spec], [2],
     [Compile-time system search path for libraries])
-_LT_DECL([sys_lib_dlsearch_path_spec], [configure_time_dlsearch_path], [2],
-    [Detected run-time system search path for libraries])
-_LT_DECL([], [configure_time_lt_sys_library_path], [2],
-    [Explicit LT_SYS_LIBRARY_PATH set during ./configure time])
+_LT_DECL([], [sys_lib_dlsearch_path_spec], [2],
+    [Run-time system search path for libraries])
 ])# _LT_SYS_DYNAMIC_LINKER
 
 
 # _LT_PATH_TOOL_PREFIX(TOOL)
 # --------------------------
-# find a file program that can recognize shared library
+# find a file program which can recognize shared library
 AC_DEFUN([_LT_PATH_TOOL_PREFIX],
 [m4_require([_LT_DECL_EGREP])dnl
 AC_MSG_CHECKING([for $1])
 AC_CACHE_VAL(lt_cv_path_MAGIC_CMD,
 [case $MAGIC_CMD in
 [[\\/*] |  ?:[\\/]*])
-  lt_cv_path_MAGIC_CMD=$MAGIC_CMD # Let the user override the test with a path.
+  lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path.
   ;;
 *)
-  lt_save_MAGIC_CMD=$MAGIC_CMD
-  lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR
+  lt_save_MAGIC_CMD="$MAGIC_CMD"
+  lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
 dnl $ac_dummy forces splitting on constant user-supplied paths.
 dnl POSIX.2 word splitting is done only on the output of word expansions,
 dnl not every word.  This closes a longstanding sh security hole.
   ac_dummy="m4_if([$2], , $PATH, [$2])"
   for ac_dir in $ac_dummy; do
-    IFS=$lt_save_ifs
+    IFS="$lt_save_ifs"
     test -z "$ac_dir" && ac_dir=.
-    if test -f "$ac_dir/$1"; then
-      lt_cv_path_MAGIC_CMD=$ac_dir/"$1"
+    if test -f $ac_dir/$1; then
+      lt_cv_path_MAGIC_CMD="$ac_dir/$1"
       if test -n "$file_magic_test_file"; then
 	case $deplibs_check_method in
 	"file_magic "*)
 	  file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"`
-	  MAGIC_CMD=$lt_cv_path_MAGIC_CMD
+	  MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
 	  if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null |
 	    $EGREP "$file_magic_regex" > /dev/null; then
 	    :
@@ -3225,11 +3003,11 @@ _LT_EOF
       break
     fi
   done
-  IFS=$lt_save_ifs
-  MAGIC_CMD=$lt_save_MAGIC_CMD
+  IFS="$lt_save_ifs"
+  MAGIC_CMD="$lt_save_MAGIC_CMD"
   ;;
 esac])
-MAGIC_CMD=$lt_cv_path_MAGIC_CMD
+MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
 if test -n "$MAGIC_CMD"; then
   AC_MSG_RESULT($MAGIC_CMD)
 else
@@ -3247,7 +3025,7 @@ dnl AC_DEFUN([AC_PATH_TOOL_PREFIX], [])
 
 # _LT_PATH_MAGIC
 # --------------
-# find a file program that can recognize a shared library
+# find a file program which can recognize a shared library
 m4_defun([_LT_PATH_MAGIC],
 [_LT_PATH_TOOL_PREFIX(${ac_tool_prefix}file, /usr/bin$PATH_SEPARATOR$PATH)
 if test -z "$lt_cv_path_MAGIC_CMD"; then
@@ -3274,16 +3052,16 @@ m4_require([_LT_PROG_ECHO_BACKSLASH])dnl
 AC_ARG_WITH([gnu-ld],
     [AS_HELP_STRING([--with-gnu-ld],
 	[assume the C compiler uses GNU ld @<:@default=no@:>@])],
-    [test no = "$withval" || with_gnu_ld=yes],
+    [test "$withval" = no || with_gnu_ld=yes],
     [with_gnu_ld=no])dnl
 
 ac_prog=ld
-if test yes = "$GCC"; then
+if test "$GCC" = yes; then
   # Check if gcc -print-prog-name=ld gives a path.
   AC_MSG_CHECKING([for ld used by $CC])
   case $host in
   *-*-mingw*)
-    # gcc leaves a trailing carriage return, which upsets mingw
+    # gcc leaves a trailing carriage return which upsets mingw
     ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;;
   *)
     ac_prog=`($CC -print-prog-name=ld) 2>&5` ;;
@@ -3297,7 +3075,7 @@ if test yes = "$GCC"; then
       while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do
 	ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"`
       done
-      test -z "$LD" && LD=$ac_prog
+      test -z "$LD" && LD="$ac_prog"
       ;;
   "")
     # If it fails, then pretend we aren't using GCC.
@@ -3308,37 +3086,37 @@ if test yes = "$GCC"; then
     with_gnu_ld=unknown
     ;;
   esac
-elif test yes = "$with_gnu_ld"; then
+elif test "$with_gnu_ld" = yes; then
   AC_MSG_CHECKING([for GNU ld])
 else
   AC_MSG_CHECKING([for non-GNU ld])
 fi
 AC_CACHE_VAL(lt_cv_path_LD,
 [if test -z "$LD"; then
-  lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR
+  lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
   for ac_dir in $PATH; do
-    IFS=$lt_save_ifs
+    IFS="$lt_save_ifs"
     test -z "$ac_dir" && ac_dir=.
     if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then
-      lt_cv_path_LD=$ac_dir/$ac_prog
+      lt_cv_path_LD="$ac_dir/$ac_prog"
       # Check to see if the program is GNU ld.  I'd rather use --version,
       # but apparently some variants of GNU ld only accept -v.
       # Break only if it was the GNU/non-GNU ld that we prefer.
       case `"$lt_cv_path_LD" -v 2>&1 </dev/null` in
       *GNU* | *'with BFD'*)
-	test no != "$with_gnu_ld" && break
+	test "$with_gnu_ld" != no && break
 	;;
       *)
-	test yes != "$with_gnu_ld" && break
+	test "$with_gnu_ld" != yes && break
 	;;
       esac
     fi
   done
-  IFS=$lt_save_ifs
+  IFS="$lt_save_ifs"
 else
-  lt_cv_path_LD=$LD # Let the user override the test with a path.
+  lt_cv_path_LD="$LD" # Let the user override the test with a path.
 fi])
-LD=$lt_cv_path_LD
+LD="$lt_cv_path_LD"
 if test -n "$LD"; then
   AC_MSG_RESULT($LD)
 else
@@ -3392,13 +3170,13 @@ esac
 reload_cmds='$LD$reload_flag -o $output$reload_objs'
 case $host_os in
   cygwin* | mingw* | pw32* | cegcc*)
-    if test yes != "$GCC"; then
+    if test "$GCC" != yes; then
       reload_cmds=false
     fi
     ;;
   darwin*)
-    if test yes = "$GCC"; then
-      reload_cmds='$LTCC $LTCFLAGS -nostdlib $wl-r -o $output$reload_objs'
+    if test "$GCC" = yes; then
+      reload_cmds='$LTCC $LTCFLAGS -nostdlib ${wl}-r -o $output$reload_objs'
     else
       reload_cmds='$LD$reload_flag -o $output$reload_objs'
     fi
@@ -3409,43 +3187,6 @@ _LT_TAGDECL([], [reload_cmds], [2])dnl
 ])# _LT_CMD_RELOAD
 
 
-# _LT_PATH_DD
-# -----------
-# find a working dd
-m4_defun([_LT_PATH_DD],
-[AC_CACHE_CHECK([for a working dd], [ac_cv_path_lt_DD],
-[printf 0123456789abcdef0123456789abcdef >conftest.i
-cat conftest.i conftest.i >conftest2.i
-: ${lt_DD:=$DD}
-AC_PATH_PROGS_FEATURE_CHECK([lt_DD], [dd],
-[if "$ac_path_lt_DD" bs=32 count=1 <conftest2.i >conftest.out 2>/dev/null; then
-  cmp -s conftest.i conftest.out \
-  && ac_cv_path_lt_DD="$ac_path_lt_DD" ac_path_lt_DD_found=:
-fi])
-rm -f conftest.i conftest2.i conftest.out])
-])# _LT_PATH_DD
-
-
-# _LT_CMD_TRUNCATE
-# ----------------
-# find command to truncate a binary pipe
-m4_defun([_LT_CMD_TRUNCATE],
-[m4_require([_LT_PATH_DD])
-AC_CACHE_CHECK([how to truncate binary pipes], [lt_cv_truncate_bin],
-[printf 0123456789abcdef0123456789abcdef >conftest.i
-cat conftest.i conftest.i >conftest2.i
-lt_cv_truncate_bin=
-if "$ac_cv_path_lt_DD" bs=32 count=1 <conftest2.i >conftest.out 2>/dev/null; then
-  cmp -s conftest.i conftest.out \
-  && lt_cv_truncate_bin="$ac_cv_path_lt_DD bs=4096 count=1"
-fi
-rm -f conftest.i conftest2.i conftest.out
-test -z "$lt_cv_truncate_bin" && lt_cv_truncate_bin="$SED -e 4q"])
-_LT_DECL([lt_truncate_bin], [lt_cv_truncate_bin], [1],
-  [Command to truncate a binary pipe])
-])# _LT_CMD_TRUNCATE
-
-
 # _LT_CHECK_MAGIC_METHOD
 # ----------------------
 # how to check for library dependencies
@@ -3461,13 +3202,13 @@ lt_cv_deplibs_check_method='unknown'
 # Need to set the preceding variable on all platforms that support
 # interlibrary dependencies.
 # 'none' -- dependencies not supported.
-# 'unknown' -- same as none, but documents that we really don't know.
+# `unknown' -- same as none, but documents that we really don't know.
 # 'pass_all' -- all dependencies passed with no checks.
 # 'test_compile' -- check by making test program.
 # 'file_magic [[regex]]' -- check by looking for files in library path
-# that responds to the $file_magic_cmd with a given extended regex.
-# If you have 'file' or equivalent on your system and you're not sure
-# whether 'pass_all' will *always* work, you probably want this one.
+# which responds to the $file_magic_cmd with a given extended regex.
+# If you have `file' or equivalent on your system and you're not sure
+# whether `pass_all' will *always* work, you probably want this one.
 
 case $host_os in
 aix[[4-9]]*)
@@ -3494,7 +3235,8 @@ mingw* | pw32*)
   # Base MSYS/MinGW do not provide the 'file' command needed by
   # func_win32_libid shell function, so use a weaker test based on 'objdump',
   # unless we find 'file', for example because we are cross-compiling.
-  if ( file / ) >/dev/null 2>&1; then
+  # func_win32_libid assumes BSD nm, so disallow it if using MS dumpbin.
+  if ( test "$lt_cv_nm_interface" = "BSD nm" && file / ) >/dev/null 2>&1; then
     lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL'
     lt_cv_file_magic_cmd='func_win32_libid'
   else
@@ -3590,8 +3332,8 @@ newos6*)
   lt_cv_deplibs_check_method=pass_all
   ;;
 
-openbsd* | bitrig*)
-  if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then
+openbsd*)
+  if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
     lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|\.so|_pic\.a)$'
   else
     lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$'
@@ -3644,9 +3386,6 @@ sysv4 | sysv4.3*)
 tpf*)
   lt_cv_deplibs_check_method=pass_all
   ;;
-os2*)
-  lt_cv_deplibs_check_method=pass_all
-  ;;
 esac
 ])
 
@@ -3687,38 +3426,33 @@ AC_DEFUN([LT_PATH_NM],
 AC_CACHE_CHECK([for BSD- or MS-compatible name lister (nm)], lt_cv_path_NM,
 [if test -n "$NM"; then
   # Let the user override the test.
-  lt_cv_path_NM=$NM
+  lt_cv_path_NM="$NM"
 else
-  lt_nm_to_check=${ac_tool_prefix}nm
+  lt_nm_to_check="${ac_tool_prefix}nm"
   if test -n "$ac_tool_prefix" && test "$build" = "$host"; then
     lt_nm_to_check="$lt_nm_to_check nm"
   fi
   for lt_tmp_nm in $lt_nm_to_check; do
-    lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR
+    lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
     for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do
-      IFS=$lt_save_ifs
+      IFS="$lt_save_ifs"
       test -z "$ac_dir" && ac_dir=.
-      tmp_nm=$ac_dir/$lt_tmp_nm
-      if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext"; then
+      tmp_nm="$ac_dir/$lt_tmp_nm"
+      if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext" ; then
 	# Check to see if the nm accepts a BSD-compat flag.
-	# Adding the 'sed 1q' prevents false positives on HP-UX, which says:
+	# Adding the `sed 1q' prevents false positives on HP-UX, which says:
 	#   nm: unknown option "B" ignored
 	# Tru64's nm complains that /dev/null is an invalid object file
-	# MSYS converts /dev/null to NUL, MinGW nm treats NUL as empty
-	case $build_os in
-	mingw*) lt_bad_file=conftest.nm/nofile ;;
-	*) lt_bad_file=/dev/null ;;
-	esac
-	case `"$tmp_nm" -B $lt_bad_file 2>&1 | sed '1q'` in
-	*$lt_bad_file* | *'Invalid file or object type'*)
+	case `"$tmp_nm" -B /dev/null 2>&1 | sed '1q'` in
+	*/dev/null* | *'Invalid file or object type'*)
 	  lt_cv_path_NM="$tmp_nm -B"
-	  break 2
+	  break
 	  ;;
 	*)
 	  case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in
 	  */dev/null*)
 	    lt_cv_path_NM="$tmp_nm -p"
-	    break 2
+	    break
 	    ;;
 	  *)
 	    lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but
@@ -3729,21 +3463,21 @@ else
 	esac
       fi
     done
-    IFS=$lt_save_ifs
+    IFS="$lt_save_ifs"
   done
   : ${lt_cv_path_NM=no}
 fi])
-if test no != "$lt_cv_path_NM"; then
-  NM=$lt_cv_path_NM
+if test "$lt_cv_path_NM" != "no"; then
+  NM="$lt_cv_path_NM"
 else
   # Didn't find any BSD compatible name lister, look for dumpbin.
   if test -n "$DUMPBIN"; then :
     # Let the user override the test.
   else
     AC_CHECK_TOOLS(DUMPBIN, [dumpbin "link -dump"], :)
-    case `$DUMPBIN -symbols -headers /dev/null 2>&1 | sed '1q'` in
+    case `$DUMPBIN -symbols /dev/null 2>&1 | sed '1q'` in
     *COFF*)
-      DUMPBIN="$DUMPBIN -symbols -headers"
+      DUMPBIN="$DUMPBIN -symbols"
       ;;
     *)
       DUMPBIN=:
@@ -3751,8 +3485,8 @@ else
     esac
   fi
   AC_SUBST([DUMPBIN])
-  if test : != "$DUMPBIN"; then
-    NM=$DUMPBIN
+  if test "$DUMPBIN" != ":"; then
+    NM="$DUMPBIN"
   fi
 fi
 test -z "$NM" && NM=nm
@@ -3798,8 +3532,8 @@ lt_cv_sharedlib_from_linklib_cmd,
 
 case $host_os in
 cygwin* | mingw* | pw32* | cegcc*)
-  # two different shell functions defined in ltmain.sh;
-  # decide which one to use based on capabilities of $DLLTOOL
+  # two different shell functions defined in ltmain.sh
+  # decide which to use based on capabilities of $DLLTOOL
   case `$DLLTOOL --help 2>&1` in
   *--identify-strict*)
     lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib
@@ -3811,7 +3545,7 @@ cygwin* | mingw* | pw32* | cegcc*)
   ;;
 *)
   # fallback: assume linklib IS sharedlib
-  lt_cv_sharedlib_from_linklib_cmd=$ECHO
+  lt_cv_sharedlib_from_linklib_cmd="$ECHO"
   ;;
 esac
 ])
@@ -3838,28 +3572,13 @@ AC_CACHE_CHECK([if $MANIFEST_TOOL is a manifest tool], [lt_cv_path_mainfest_tool
     lt_cv_path_mainfest_tool=yes
   fi
   rm -f conftest*])
-if test yes != "$lt_cv_path_mainfest_tool"; then
+if test "x$lt_cv_path_mainfest_tool" != xyes; then
   MANIFEST_TOOL=:
 fi
 _LT_DECL([], [MANIFEST_TOOL], [1], [Manifest tool])dnl
 ])# _LT_PATH_MANIFEST_TOOL
 
 
-# _LT_DLL_DEF_P([FILE])
-# ---------------------
-# True iff FILE is a Windows DLL '.def' file.
-# Keep in sync with func_dll_def_p in the libtool script
-AC_DEFUN([_LT_DLL_DEF_P],
-[dnl
-  test DEF = "`$SED -n dnl
-    -e '\''s/^[[	 ]]*//'\'' dnl Strip leading whitespace
-    -e '\''/^\(;.*\)*$/d'\'' dnl      Delete empty lines and comments
-    -e '\''s/^\(EXPORTS\|LIBRARY\)\([[	 ]].*\)*$/DEF/p'\'' dnl
-    -e q dnl                          Only consider the first "real" line
-    $1`" dnl
-])# _LT_DLL_DEF_P
-
-
 # LT_LIB_M
 # --------
 # check for math library
@@ -3871,11 +3590,11 @@ case $host in
   # These system don't have libm, or don't need it
   ;;
 *-ncr-sysv4.3*)
-  AC_CHECK_LIB(mw, _mwvalidcheckl, LIBM=-lmw)
+  AC_CHECK_LIB(mw, _mwvalidcheckl, LIBM="-lmw")
   AC_CHECK_LIB(m, cos, LIBM="$LIBM -lm")
   ;;
 *)
-  AC_CHECK_LIB(m, cos, LIBM=-lm)
+  AC_CHECK_LIB(m, cos, LIBM="-lm")
   ;;
 esac
 AC_SUBST([LIBM])
@@ -3894,7 +3613,7 @@ m4_defun([_LT_COMPILER_NO_RTTI],
 
 _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=
 
-if test yes = "$GCC"; then
+if test "$GCC" = yes; then
   case $cc_basename in
   nvcc*)
     _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -Xcompiler -fno-builtin' ;;
@@ -3946,7 +3665,7 @@ cygwin* | mingw* | pw32* | cegcc*)
   symcode='[[ABCDGISTW]]'
   ;;
 hpux*)
-  if test ia64 = "$host_cpu"; then
+  if test "$host_cpu" = ia64; then
     symcode='[[ABCDEGRST]]'
   fi
   ;;
@@ -3979,44 +3698,14 @@ case `$NM -V 2>&1` in
   symcode='[[ABCDGIRSTW]]' ;;
 esac
 
-if test "$lt_cv_nm_interface" = "MS dumpbin"; then
-  # Gets list of data symbols to import.
-  lt_cv_sys_global_symbol_to_import="sed -n -e 's/^I .* \(.*\)$/\1/p'"
-  # Adjust the below global symbol transforms to fixup imported variables.
-  lt_cdecl_hook=" -e 's/^I .* \(.*\)$/extern __declspec(dllimport) char \1;/p'"
-  lt_c_name_hook=" -e 's/^I .* \(.*\)$/  {\"\1\", (void *) 0},/p'"
-  lt_c_name_lib_hook="\
-  -e 's/^I .* \(lib.*\)$/  {\"\1\", (void *) 0},/p'\
-  -e 's/^I .* \(.*\)$/  {\"lib\1\", (void *) 0},/p'"
-else
-  # Disable hooks by default.
-  lt_cv_sys_global_symbol_to_import=
-  lt_cdecl_hook=
-  lt_c_name_hook=
-  lt_c_name_lib_hook=
-fi
-
 # Transform an extracted symbol line into a proper C declaration.
 # Some systems (esp. on ia64) link data and code symbols differently,
 # so use this general approach.
-lt_cv_sys_global_symbol_to_cdecl="sed -n"\
-$lt_cdecl_hook\
-" -e 's/^T .* \(.*\)$/extern int \1();/p'"\
-" -e 's/^$symcode$symcode* .* \(.*\)$/extern char \1;/p'"
+lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'"
 
 # Transform an extracted symbol line into symbol name and symbol address
-lt_cv_sys_global_symbol_to_c_name_address="sed -n"\
-$lt_c_name_hook\
-" -e 's/^: \(.*\) .*$/  {\"\1\", (void *) 0},/p'"\
-" -e 's/^$symcode$symcode* .* \(.*\)$/  {\"\1\", (void *) \&\1},/p'"
-
-# Transform an extracted symbol line into symbol name with lib prefix and
-# symbol address.
-lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n"\
-$lt_c_name_lib_hook\
-" -e 's/^: \(.*\) .*$/  {\"\1\", (void *) 0},/p'"\
-" -e 's/^$symcode$symcode* .* \(lib.*\)$/  {\"\1\", (void *) \&\1},/p'"\
-" -e 's/^$symcode$symcode* .* \(.*\)$/  {\"lib\1\", (void *) \&\1},/p'"
+lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([[^ ]]*\)[[ ]]*$/  {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/  {\"\2\", (void *) \&\2},/p'"
+lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n -e 's/^: \([[^ ]]*\)[[ ]]*$/  {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \(lib[[^ ]]*\)$/  {\"\2\", (void *) \&\2},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/  {\"lib\2\", (void *) \&\2},/p'"
 
 # Handle CRLF in mingw tool chain
 opt_cr=
@@ -4034,24 +3723,21 @@ for ac_symprfx in "" "_"; do
 
   # Write the raw and C identifiers.
   if test "$lt_cv_nm_interface" = "MS dumpbin"; then
-    # Fake it for dumpbin and say T for any non-static function,
-    # D for any global variable and I for any imported variable.
+    # Fake it for dumpbin and say T for any non-static function
+    # and D for any global variable.
     # Also find C++ and __fastcall symbols from MSVC++,
     # which start with @ or ?.
     lt_cv_sys_global_symbol_pipe="$AWK ['"\
 "     {last_section=section; section=\$ 3};"\
 "     /^COFF SYMBOL TABLE/{for(i in hide) delete hide[i]};"\
 "     /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\
-"     /^ *Symbol name *: /{split(\$ 0,sn,\":\"); si=substr(sn[2],2)};"\
-"     /^ *Type *: code/{print \"T\",si,substr(si,length(prfx))};"\
-"     /^ *Type *: data/{print \"I\",si,substr(si,length(prfx))};"\
 "     \$ 0!~/External *\|/{next};"\
 "     / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\
 "     {if(hide[section]) next};"\
-"     {f=\"D\"}; \$ 0~/\(\).*\|/{f=\"T\"};"\
-"     {split(\$ 0,a,/\||\r/); split(a[2],s)};"\
-"     s[1]~/^[@?]/{print f,s[1],s[1]; next};"\
-"     s[1]~prfx {split(s[1],t,\"@\"); print f,t[1],substr(t[1],length(prfx))}"\
+"     {f=0}; \$ 0~/\(\).*\|/{f=1}; {printf f ? \"T \" : \"D \"};"\
+"     {split(\$ 0, a, /\||\r/); split(a[2], s)};"\
+"     s[1]~/^[@?]/{print s[1], s[1]; next};"\
+"     s[1]~prfx {split(s[1],t,\"@\"); print t[1], substr(t[1],length(prfx))}"\
 "     ' prfx=^$ac_symprfx]"
   else
     lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[[	 ]]\($symcode$symcode*\)[[	 ]][[	 ]]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'"
@@ -4091,11 +3777,11 @@ _LT_EOF
 	if $GREP ' nm_test_func$' "$nlist" >/dev/null; then
 	  cat <<_LT_EOF > conftest.$ac_ext
 /* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests.  */
-#if defined _WIN32 || defined __CYGWIN__ || defined _WIN32_WCE
-/* DATA imports from DLLs on WIN32 can't be const, because runtime
+#if defined(_WIN32) || defined(__CYGWIN__) || defined(_WIN32_WCE)
+/* DATA imports from DLLs on WIN32 con't be const, because runtime
    relocations are performed -- see ld's documentation on pseudo-relocs.  */
 # define LT@&t at _DLSYM_CONST
-#elif defined __osf__
+#elif defined(__osf__)
 /* This system does not cope well with relocations in const data.  */
 # define LT@&t at _DLSYM_CONST
 #else
@@ -4121,7 +3807,7 @@ lt__PROGRAM__LTX_preloaded_symbols[[]] =
 {
   { "@PROGRAM@", (void *) 0 },
 _LT_EOF
-	  $SED "s/^$symcode$symcode* .* \(.*\)$/  {\"\1\", (void *) \&\1},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext
+	  $SED "s/^$symcode$symcode* \(.*\) \(.*\)$/  {\"\2\", (void *) \&\2},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext
 	  cat <<\_LT_EOF >> conftest.$ac_ext
   {0, (void *) 0}
 };
@@ -4141,9 +3827,9 @@ _LT_EOF
 	  mv conftest.$ac_objext conftstm.$ac_objext
 	  lt_globsym_save_LIBS=$LIBS
 	  lt_globsym_save_CFLAGS=$CFLAGS
-	  LIBS=conftstm.$ac_objext
+	  LIBS="conftstm.$ac_objext"
 	  CFLAGS="$CFLAGS$_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)"
-	  if AC_TRY_EVAL(ac_link) && test -s conftest$ac_exeext; then
+	  if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext}; then
 	    pipe_works=yes
 	  fi
 	  LIBS=$lt_globsym_save_LIBS
@@ -4164,7 +3850,7 @@ _LT_EOF
   rm -rf conftest* conftst*
 
   # Do not use the global_symbol_pipe unless it works.
-  if test yes = "$pipe_works"; then
+  if test "$pipe_works" = yes; then
     break
   else
     lt_cv_sys_global_symbol_pipe=
@@ -4191,16 +3877,12 @@ _LT_DECL([global_symbol_pipe], [lt_cv_sys_global_symbol_pipe], [1],
     [Take the output of nm and produce a listing of raw symbols and C names])
 _LT_DECL([global_symbol_to_cdecl], [lt_cv_sys_global_symbol_to_cdecl], [1],
     [Transform the output of nm in a proper C declaration])
-_LT_DECL([global_symbol_to_import], [lt_cv_sys_global_symbol_to_import], [1],
-    [Transform the output of nm into a list of symbols to manually relocate])
 _LT_DECL([global_symbol_to_c_name_address],
     [lt_cv_sys_global_symbol_to_c_name_address], [1],
     [Transform the output of nm in a C name address pair])
 _LT_DECL([global_symbol_to_c_name_address_lib_prefix],
     [lt_cv_sys_global_symbol_to_c_name_address_lib_prefix], [1],
     [Transform the output of nm in a C name address pair when lib prefix is needed])
-_LT_DECL([nm_interface], [lt_cv_nm_interface], [1],
-    [The name lister interface])
 _LT_DECL([], [nm_file_list_spec], [1],
     [Specify filename containing input files for $NM])
 ]) # _LT_CMD_GLOBAL_SYMBOLS
@@ -4216,18 +3898,17 @@ _LT_TAGVAR(lt_prog_compiler_static, $1)=
 
 m4_if([$1], [CXX], [
   # C++ specific cases for pic, static, wl, etc.
-  if test yes = "$GXX"; then
+  if test "$GXX" = yes; then
     _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
     _LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
 
     case $host_os in
     aix*)
       # All AIX code is PIC.
-      if test ia64 = "$host_cpu"; then
+      if test "$host_cpu" = ia64; then
 	# AIX 5 now supports IA64 processor
 	_LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
       fi
-      _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
       ;;
 
     amigaos*)
@@ -4238,8 +3919,8 @@ m4_if([$1], [CXX], [
         ;;
       m68k)
             # FIXME: we need at least 68020 code to build shared libraries, but
-            # adding the '-m68020' flag to GCC prevents building anything better,
-            # like '-m68040'.
+            # adding the `-m68020' flag to GCC prevents building anything better,
+            # like `-m68040'.
             _LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4'
         ;;
       esac
@@ -4255,11 +3936,6 @@ m4_if([$1], [CXX], [
       # (--disable-auto-import) libraries
       m4_if([$1], [GCJ], [],
 	[_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT'])
-      case $host_os in
-      os2*)
-	_LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-static'
-	;;
-      esac
       ;;
     darwin* | rhapsody*)
       # PIC is the default on this platform
@@ -4309,7 +3985,7 @@ m4_if([$1], [CXX], [
     case $host_os in
       aix[[4-9]]*)
 	# All AIX code is PIC.
-	if test ia64 = "$host_cpu"; then
+	if test "$host_cpu" = ia64; then
 	  # AIX 5 now supports IA64 processor
 	  _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
 	else
@@ -4350,14 +4026,14 @@ m4_if([$1], [CXX], [
 	case $cc_basename in
 	  CC*)
 	    _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
-	    _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-a ${wl}archive'
-	    if test ia64 != "$host_cpu"; then
+	    _LT_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive'
+	    if test "$host_cpu" != ia64; then
 	      _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z'
 	    fi
 	    ;;
 	  aCC*)
 	    _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
-	    _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-a ${wl}archive'
+	    _LT_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive'
 	    case $host_cpu in
 	    hppa*64*|ia64*)
 	      # +Z the default
@@ -4394,7 +4070,7 @@ m4_if([$1], [CXX], [
 	    _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
 	    ;;
 	  ecpc* )
-	    # old Intel C++ for x86_64, which still supported -KPIC.
+	    # old Intel C++ for x86_64 which still supported -KPIC.
 	    _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
 	    _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
 	    _LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
@@ -4539,18 +4215,17 @@ m4_if([$1], [CXX], [
   fi
 ],
 [
-  if test yes = "$GCC"; then
+  if test "$GCC" = yes; then
     _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
     _LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
 
     case $host_os in
       aix*)
       # All AIX code is PIC.
-      if test ia64 = "$host_cpu"; then
+      if test "$host_cpu" = ia64; then
 	# AIX 5 now supports IA64 processor
 	_LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
       fi
-      _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
       ;;
 
     amigaos*)
@@ -4561,8 +4236,8 @@ m4_if([$1], [CXX], [
         ;;
       m68k)
             # FIXME: we need at least 68020 code to build shared libraries, but
-            # adding the '-m68020' flag to GCC prevents building anything better,
-            # like '-m68040'.
+            # adding the `-m68020' flag to GCC prevents building anything better,
+            # like `-m68040'.
             _LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4'
         ;;
       esac
@@ -4579,11 +4254,6 @@ m4_if([$1], [CXX], [
       # (--disable-auto-import) libraries
       m4_if([$1], [GCJ], [],
 	[_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT'])
-      case $host_os in
-      os2*)
-	_LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-static'
-	;;
-      esac
       ;;
 
     darwin* | rhapsody*)
@@ -4654,7 +4324,7 @@ m4_if([$1], [CXX], [
     case $host_os in
     aix*)
       _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
-      if test ia64 = "$host_cpu"; then
+      if test "$host_cpu" = ia64; then
 	# AIX 5 now supports IA64 processor
 	_LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
       else
@@ -4662,30 +4332,11 @@ m4_if([$1], [CXX], [
       fi
       ;;
 
-    darwin* | rhapsody*)
-      # PIC is the default on this platform
-      # Common symbols not allowed in MH_DYLIB files
-      _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common'
-      case $cc_basename in
-      nagfor*)
-        # NAG Fortran compiler
-        _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,-Wl,,'
-        _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC'
-        _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
-        ;;
-      esac
-      ;;
-
     mingw* | cygwin* | pw32* | os2* | cegcc*)
       # This hack is so that the source file can tell whether it is being
       # built for inclusion in a dll (and should export symbols for example).
       m4_if([$1], [GCJ], [],
 	[_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT'])
-      case $host_os in
-      os2*)
-	_LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-static'
-	;;
-      esac
       ;;
 
     hpux9* | hpux10* | hpux11*)
@@ -4701,7 +4352,7 @@ m4_if([$1], [CXX], [
 	;;
       esac
       # Is there a better lt_prog_compiler_static that works with the bundled CC?
-      _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-a ${wl}archive'
+      _LT_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive'
       ;;
 
     irix5* | irix6* | nonstopux*)
@@ -4712,7 +4363,7 @@ m4_if([$1], [CXX], [
 
     linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*)
       case $cc_basename in
-      # old Intel for x86_64, which still supported -KPIC.
+      # old Intel for x86_64 which still supported -KPIC.
       ecc*)
 	_LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
 	_LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
@@ -4737,12 +4388,6 @@ m4_if([$1], [CXX], [
 	_LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC'
 	_LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
 	;;
-      tcc*)
-	# Fabrice Bellard et al's Tiny C Compiler
-	_LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
-	_LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
-	_LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
-	;;
       pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*)
         # Portland Group compilers (*not* the Pentium gcc compiler,
 	# which looks to be a dead project)
@@ -4840,7 +4485,7 @@ m4_if([$1], [CXX], [
       ;;
 
     sysv4*MP*)
-      if test -d /usr/nec; then
+      if test -d /usr/nec ;then
 	_LT_TAGVAR(lt_prog_compiler_pic, $1)='-Kconform_pic'
 	_LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
       fi
@@ -4869,7 +4514,7 @@ m4_if([$1], [CXX], [
   fi
 ])
 case $host_os in
-  # For platforms that do not support PIC, -DPIC is meaningless:
+  # For platforms which do not support PIC, -DPIC is meaningless:
   *djgpp*)
     _LT_TAGVAR(lt_prog_compiler_pic, $1)=
     ;;
@@ -4935,21 +4580,17 @@ m4_if([$1], [CXX], [
   case $host_os in
   aix[[4-9]]*)
     # If we're using GNU nm, then we don't want the "-C" option.
-    # -C means demangle to GNU nm, but means don't demangle to AIX nm.
-    # Without the "-l" option, or with the "-B" option, AIX nm treats
-    # weak defined symbols like other global defined symbols, whereas
-    # GNU nm marks them as "W".
-    # While the 'weak' keyword is ignored in the Export File, we need
-    # it in the Import File for the 'aix-soname' feature, so we have
-    # to replace the "-B" option with "-P" for AIX nm.
+    # -C means demangle to AIX nm, but means don't demangle with GNU nm
+    # Also, AIX nm treats weak defined symbols like other global defined
+    # symbols, whereas GNU nm marks them as "W".
     if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then
-      _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && ([substr](\$ 3,1,1) != ".")) { if (\$ 2 == "W") { print \$ 3 " weak" } else { print \$ 3 } } }'\'' | sort -u > $export_symbols'
+      _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols'
     else
-      _LT_TAGVAR(export_symbols_cmds, $1)='`func_echo_all $NM | $SED -e '\''s/B\([[^B]]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && ([substr](\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols'
+      _LT_TAGVAR(export_symbols_cmds, $1)='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols'
     fi
     ;;
   pw32*)
-    _LT_TAGVAR(export_symbols_cmds, $1)=$ltdll_cmds
+    _LT_TAGVAR(export_symbols_cmds, $1)="$ltdll_cmds"
     ;;
   cygwin* | mingw* | cegcc*)
     case $cc_basename in
@@ -4998,9 +4639,9 @@ m4_if([$1], [CXX], [
   # included in the symbol list
   _LT_TAGVAR(include_expsyms, $1)=
   # exclude_expsyms can be an extended regexp of symbols to exclude
-  # it will be wrapped by ' (' and ')$', so one must not match beginning or
-  # end of line.  Example: 'a|bc|.*d.*' will exclude the symbols 'a' and 'bc',
-  # as well as any symbol that contains 'd'.
+  # it will be wrapped by ` (' and `)$', so one must not match beginning or
+  # end of line.  Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc',
+  # as well as any symbol that contains `d'.
   _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*']
   # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out
   # platforms (ab)use it in PIC code, but their linkers get confused if
@@ -5016,7 +4657,7 @@ dnl Note also adjust exclude_expsyms for C++ above.
     # FIXME: the MSVC++ port hasn't been tested in a loooong time
     # When not using gcc, we currently assume that we are using
     # Microsoft Visual C++.
-    if test yes != "$GCC"; then
+    if test "$GCC" != yes; then
       with_gnu_ld=no
     fi
     ;;
@@ -5024,7 +4665,7 @@ dnl Note also adjust exclude_expsyms for C++ above.
     # we just hope/assume this is gcc and not c89 (= MSVC++)
     with_gnu_ld=yes
     ;;
-  openbsd* | bitrig*)
+  openbsd*)
     with_gnu_ld=no
     ;;
   linux* | k*bsd*-gnu | gnu*)
@@ -5037,7 +4678,7 @@ dnl Note also adjust exclude_expsyms for C++ above.
   # On some targets, GNU ld is compatible enough with the native linker
   # that we're better off using the native interface for both.
   lt_use_gnu_ld_interface=no
-  if test yes = "$with_gnu_ld"; then
+  if test "$with_gnu_ld" = yes; then
     case $host_os in
       aix*)
 	# The AIX port of GNU ld has always aspired to compatibility
@@ -5059,24 +4700,24 @@ dnl Note also adjust exclude_expsyms for C++ above.
     esac
   fi
 
-  if test yes = "$lt_use_gnu_ld_interface"; then
+  if test "$lt_use_gnu_ld_interface" = yes; then
     # If archive_cmds runs LD, not CC, wlarc should be empty
-    wlarc='$wl'
+    wlarc='${wl}'
 
     # Set some defaults for GNU ld with shared library support. These
     # are reset later if shared libraries are not supported. Putting them
     # here allows them to be overridden if necessary.
     runpath_var=LD_RUN_PATH
-    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir'
-    _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic'
+    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+    _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic'
     # ancient GNU ld didn't support --whole-archive et. al.
     if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then
-      _LT_TAGVAR(whole_archive_flag_spec, $1)=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive'
+      _LT_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive'
     else
       _LT_TAGVAR(whole_archive_flag_spec, $1)=
     fi
     supports_anon_versioning=no
-    case `$LD -v | $SED -e 's/([^)]\+)\s\+//' 2>&1` in
+    case `$LD -v 2>&1` in
       *GNU\ gold*) supports_anon_versioning=yes ;;
       *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.10.*) ;; # catch versions < 2.11
       *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ...
@@ -5089,7 +4730,7 @@ dnl Note also adjust exclude_expsyms for C++ above.
     case $host_os in
     aix[[3-9]]*)
       # On AIX/PPC, the GNU linker is very broken
-      if test ia64 != "$host_cpu"; then
+      if test "$host_cpu" != ia64; then
 	_LT_TAGVAR(ld_shlibs, $1)=no
 	cat <<_LT_EOF 1>&2
 
@@ -5108,7 +4749,7 @@ _LT_EOF
       case $host_cpu in
       powerpc)
             # see comment about AmigaOS4 .so support
-            _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+            _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
             _LT_TAGVAR(archive_expsym_cmds, $1)=''
         ;;
       m68k)
@@ -5124,7 +4765,7 @@ _LT_EOF
 	_LT_TAGVAR(allow_undefined_flag, $1)=unsupported
 	# Joseph Beckenbach <jrb3 at best.com> says some releases of gcc
 	# support --undefined.  This deserves some investigation.  FIXME
-	_LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+	_LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
       else
 	_LT_TAGVAR(ld_shlibs, $1)=no
       fi
@@ -5134,7 +4775,7 @@ _LT_EOF
       # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless,
       # as there is no search path for DLLs.
       _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
-      _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-all-symbols'
+      _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-all-symbols'
       _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
       _LT_TAGVAR(always_export_symbols, $1)=no
       _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
@@ -5142,89 +4783,61 @@ _LT_EOF
       _LT_TAGVAR(exclude_expsyms, $1)=['[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname']
 
       if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then
-        _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
-	# If the export-symbols file already is a .def file, use it as
-	# is; otherwise, prepend EXPORTS...
-	_LT_TAGVAR(archive_expsym_cmds, $1)='if _LT_DLL_DEF_P([$export_symbols]); then
-          cp $export_symbols $output_objdir/$soname.def;
-        else
-          echo EXPORTS > $output_objdir/$soname.def;
-          cat $export_symbols >> $output_objdir/$soname.def;
-        fi~
-        $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+        _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+	# If the export-symbols file already is a .def file (1st line
+	# is EXPORTS), use it as is; otherwise, prepend...
+	_LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then
+	  cp $export_symbols $output_objdir/$soname.def;
+	else
+	  echo EXPORTS > $output_objdir/$soname.def;
+	  cat $export_symbols >> $output_objdir/$soname.def;
+	fi~
+	$CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
       else
 	_LT_TAGVAR(ld_shlibs, $1)=no
       fi
       ;;
 
     haiku*)
-      _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+      _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
       _LT_TAGVAR(link_all_deplibs, $1)=yes
       ;;
 
-    os2*)
-      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
-      _LT_TAGVAR(hardcode_minus_L, $1)=yes
-      _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
-      shrext_cmds=.dll
-      _LT_TAGVAR(archive_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~
-	$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~
-	$ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~
-	$ECHO EXPORTS >> $output_objdir/$libname.def~
-	emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~
-	$CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~
-	emximp -o $lib $output_objdir/$libname.def'
-      _LT_TAGVAR(archive_expsym_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~
-	$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~
-	$ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~
-	$ECHO EXPORTS >> $output_objdir/$libname.def~
-	prefix_cmds="$SED"~
-	if test EXPORTS = "`$SED 1q $export_symbols`"; then
-	  prefix_cmds="$prefix_cmds -e 1d";
-	fi~
-	prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~
-	cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~
-	$CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~
-	emximp -o $lib $output_objdir/$libname.def'
-      _LT_TAGVAR(old_archive_From_new_cmds, $1)='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def'
-      _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
-      ;;
-
     interix[[3-9]]*)
       _LT_TAGVAR(hardcode_direct, $1)=no
       _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
-      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir'
-      _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E'
+      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
+      _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
       # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc.
       # Instead, shared libraries are loaded at an image base (0x10000000 by
       # default) and relocated if they conflict, which is a slow very memory
       # consuming and fragmenting process.  To avoid this, we pick a random,
       # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link
       # time.  Moving up from 0x10000000 also allows more sbrk(2) space.
-      _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
-      _LT_TAGVAR(archive_expsym_cmds, $1)='sed "s|^|_|" $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--retain-symbols-file,$output_objdir/$soname.expsym $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+      _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+      _LT_TAGVAR(archive_expsym_cmds, $1)='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
       ;;
 
     gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu)
       tmp_diet=no
-      if test linux-dietlibc = "$host_os"; then
+      if test "$host_os" = linux-dietlibc; then
 	case $cc_basename in
 	  diet\ *) tmp_diet=yes;;	# linux-dietlibc with static linking (!diet-dyn)
 	esac
       fi
       if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \
-	 && test no = "$tmp_diet"
+	 && test "$tmp_diet" = no
       then
 	tmp_addflag=' $pic_flag'
 	tmp_sharedflag='-shared'
 	case $cc_basename,$host_cpu in
         pgcc*)				# Portland Group C compiler
-	  _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive'
+	  _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
 	  tmp_addflag=' $pic_flag'
 	  ;;
 	pgf77* | pgf90* | pgf95* | pgfortran*)
 					# Portland Group f77 and f90 compilers
-	  _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive'
+	  _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
 	  tmp_addflag=' $pic_flag -Mnomain' ;;
 	ecc*,ia64* | icc*,ia64*)	# Intel C compiler on ia64
 	  tmp_addflag=' -i_dynamic' ;;
@@ -5235,47 +4848,42 @@ _LT_EOF
 	lf95*)				# Lahey Fortran 8.1
 	  _LT_TAGVAR(whole_archive_flag_spec, $1)=
 	  tmp_sharedflag='--shared' ;;
-        nagfor*)                        # NAGFOR 5.3
-          tmp_sharedflag='-Wl,-shared' ;;
 	xl[[cC]]* | bgxl[[cC]]* | mpixl[[cC]]*) # IBM XL C 8.0 on PPC (deal with xlf below)
 	  tmp_sharedflag='-qmkshrobj'
 	  tmp_addflag= ;;
 	nvcc*)	# Cuda Compiler Driver 2.2
-	  _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive'
+	  _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
 	  _LT_TAGVAR(compiler_needs_object, $1)=yes
 	  ;;
 	esac
 	case `$CC -V 2>&1 | sed 5q` in
 	*Sun\ C*)			# Sun C 5.9
-	  _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive'
+	  _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
 	  _LT_TAGVAR(compiler_needs_object, $1)=yes
 	  tmp_sharedflag='-G' ;;
 	*Sun\ F*)			# Sun Fortran 8.3
 	  tmp_sharedflag='-G' ;;
 	esac
-	_LT_TAGVAR(archive_cmds, $1)='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+	_LT_TAGVAR(archive_cmds, $1)='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
 
-        if test yes = "$supports_anon_versioning"; then
+        if test "x$supports_anon_versioning" = xyes; then
           _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~
-            cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
-            echo "local: *; };" >> $output_objdir/$libname.ver~
-            $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-version-script $wl$output_objdir/$libname.ver -o $lib'
+	    cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
+	    echo "local: *; };" >> $output_objdir/$libname.ver~
+	    $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib'
         fi
 
 	case $cc_basename in
-	tcc*)
-	  _LT_TAGVAR(export_dynamic_flag_spec, $1)='-rdynamic'
-	  ;;
 	xlf* | bgf* | bgxlf* | mpixlf*)
 	  # IBM XL Fortran 10.1 on PPC cannot create shared libs itself
 	  _LT_TAGVAR(whole_archive_flag_spec, $1)='--whole-archive$convenience --no-whole-archive'
-	  _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir'
+	  _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
 	  _LT_TAGVAR(archive_cmds, $1)='$LD -shared $libobjs $deplibs $linker_flags -soname $soname -o $lib'
-	  if test yes = "$supports_anon_versioning"; then
+	  if test "x$supports_anon_versioning" = xyes; then
 	    _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~
-              cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
-              echo "local: *; };" >> $output_objdir/$libname.ver~
-              $LD -shared $libobjs $deplibs $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib'
+	      cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
+	      echo "local: *; };" >> $output_objdir/$libname.ver~
+	      $LD -shared $libobjs $deplibs $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib'
 	  fi
 	  ;;
 	esac
@@ -5289,8 +4897,8 @@ _LT_EOF
 	_LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib'
 	wlarc=
       else
-	_LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
-	_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'
+	_LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+	_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
       fi
       ;;
 
@@ -5308,8 +4916,8 @@ _LT_EOF
 
 _LT_EOF
       elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
-	_LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
-	_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'
+	_LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+	_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
       else
 	_LT_TAGVAR(ld_shlibs, $1)=no
       fi
@@ -5321,7 +4929,7 @@ _LT_EOF
 	_LT_TAGVAR(ld_shlibs, $1)=no
 	cat <<_LT_EOF 1>&2
 
-*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 cannot
+*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 can not
 *** reliably create shared libraries on SCO systems.  Therefore, libtool
 *** is disabling shared libraries support.  We urge you to upgrade GNU
 *** binutils to release 2.16.91.0.3 or newer.  Another option is to modify
@@ -5336,9 +4944,9 @@ _LT_EOF
 	  # DT_RUNPATH tag from executables and libraries.  But doing so
 	  # requires that you compile everything twice, which is a pain.
 	  if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
-	    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir'
-	    _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
-	    _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'
+	    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+	    _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+	    _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
 	  else
 	    _LT_TAGVAR(ld_shlibs, $1)=no
 	  fi
@@ -5355,15 +4963,15 @@ _LT_EOF
 
     *)
       if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
-	_LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
-	_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'
+	_LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+	_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
       else
 	_LT_TAGVAR(ld_shlibs, $1)=no
       fi
       ;;
     esac
 
-    if test no = "$_LT_TAGVAR(ld_shlibs, $1)"; then
+    if test "$_LT_TAGVAR(ld_shlibs, $1)" = no; then
       runpath_var=
       _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=
       _LT_TAGVAR(export_dynamic_flag_spec, $1)=
@@ -5379,7 +4987,7 @@ _LT_EOF
       # Note: this linker hardcodes the directories in LIBPATH if there
       # are no directories specified by -L.
       _LT_TAGVAR(hardcode_minus_L, $1)=yes
-      if test yes = "$GCC" && test -z "$lt_prog_compiler_static"; then
+      if test "$GCC" = yes && test -z "$lt_prog_compiler_static"; then
 	# Neither direct hardcoding nor static linking is supported with a
 	# broken collect2.
 	_LT_TAGVAR(hardcode_direct, $1)=unsupported
@@ -5387,57 +4995,34 @@ _LT_EOF
       ;;
 
     aix[[4-9]]*)
-      if test ia64 = "$host_cpu"; then
+      if test "$host_cpu" = ia64; then
 	# On IA64, the linker does run time linking by default, so we don't
 	# have to do anything special.
 	aix_use_runtimelinking=no
 	exp_sym_flag='-Bexport'
-	no_entry_flag=
+	no_entry_flag=""
       else
 	# If we're using GNU nm, then we don't want the "-C" option.
-	# -C means demangle to GNU nm, but means don't demangle to AIX nm.
-	# Without the "-l" option, or with the "-B" option, AIX nm treats
-	# weak defined symbols like other global defined symbols, whereas
-	# GNU nm marks them as "W".
-	# While the 'weak' keyword is ignored in the Export File, we need
-	# it in the Import File for the 'aix-soname' feature, so we have
-	# to replace the "-B" option with "-P" for AIX nm.
+	# -C means demangle to AIX nm, but means don't demangle with GNU nm
+	# Also, AIX nm treats weak defined symbols like other global
+	# defined symbols, whereas GNU nm marks them as "W".
 	if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then
-	  _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && ([substr](\$ 3,1,1) != ".")) { if (\$ 2 == "W") { print \$ 3 " weak" } else { print \$ 3 } } }'\'' | sort -u > $export_symbols'
+	  _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols'
 	else
-	  _LT_TAGVAR(export_symbols_cmds, $1)='`func_echo_all $NM | $SED -e '\''s/B\([[^B]]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && ([substr](\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols'
+	  _LT_TAGVAR(export_symbols_cmds, $1)='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols'
 	fi
 	aix_use_runtimelinking=no
 
 	# Test if we are trying to use run time linking or normal
 	# AIX style linking. If -brtl is somewhere in LDFLAGS, we
-	# have runtime linking enabled, and use it for executables.
-	# For shared libraries, we enable/disable runtime linking
-	# depending on the kind of the shared library created -
-	# when "with_aix_soname,aix_use_runtimelinking" is:
-	# "aix,no"   lib.a(lib.so.V) shared, rtl:no,  for executables
-	# "aix,yes"  lib.so          shared, rtl:yes, for executables
-	#            lib.a           static archive
-	# "both,no"  lib.so.V(shr.o) shared, rtl:yes
-	#            lib.a(lib.so.V) shared, rtl:no,  for executables
-	# "both,yes" lib.so.V(shr.o) shared, rtl:yes, for executables
-	#            lib.a(lib.so.V) shared, rtl:no
-	# "svr4,*"   lib.so.V(shr.o) shared, rtl:yes, for executables
-	#            lib.a           static archive
+	# need to do runtime linking.
 	case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*)
 	  for ld_flag in $LDFLAGS; do
-	  if (test x-brtl = "x$ld_flag" || test x-Wl,-brtl = "x$ld_flag"); then
+	  if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then
 	    aix_use_runtimelinking=yes
 	    break
 	  fi
 	  done
-	  if test svr4,no = "$with_aix_soname,$aix_use_runtimelinking"; then
-	    # With aix-soname=svr4, we create the lib.so.V shared archives only,
-	    # so we don't have lib.a shared libs to link our executables.
-	    # We have to force runtime linking in this case.
-	    aix_use_runtimelinking=yes
-	    LDFLAGS="$LDFLAGS -Wl,-brtl"
-	  fi
 	  ;;
 	esac
 
@@ -5456,21 +5041,13 @@ _LT_EOF
       _LT_TAGVAR(hardcode_direct_absolute, $1)=yes
       _LT_TAGVAR(hardcode_libdir_separator, $1)=':'
       _LT_TAGVAR(link_all_deplibs, $1)=yes
-      _LT_TAGVAR(file_list_spec, $1)='$wl-f,'
-      case $with_aix_soname,$aix_use_runtimelinking in
-      aix,*) ;; # traditional, no import file
-      svr4,* | *,yes) # use import file
-	# The Import File defines what to hardcode.
-	_LT_TAGVAR(hardcode_direct, $1)=no
-	_LT_TAGVAR(hardcode_direct_absolute, $1)=no
-	;;
-      esac
+      _LT_TAGVAR(file_list_spec, $1)='${wl}-f,'
 
-      if test yes = "$GCC"; then
+      if test "$GCC" = yes; then
 	case $host_os in aix4.[[012]]|aix4.[[012]].*)
 	# We only want to do this on AIX 4.2 and lower, the check
 	# below for broken collect2 doesn't work under 4.3+
-	  collect2name=`$CC -print-prog-name=collect2`
+	  collect2name=`${CC} -print-prog-name=collect2`
 	  if test -f "$collect2name" &&
 	   strings "$collect2name" | $GREP resolve_lib_name >/dev/null
 	  then
@@ -5489,80 +5066,62 @@ _LT_EOF
 	  ;;
 	esac
 	shared_flag='-shared'
-	if test yes = "$aix_use_runtimelinking"; then
-	  shared_flag="$shared_flag "'$wl-G'
+	if test "$aix_use_runtimelinking" = yes; then
+	  shared_flag="$shared_flag "'${wl}-G'
 	fi
-	# Need to ensure runtime linking is disabled for the traditional
-	# shared library, or the linker may eventually find shared libraries
-	# /with/ Import File - we do not want to mix them.
-	shared_flag_aix='-shared'
-	shared_flag_svr4='-shared $wl-G'
+	_LT_TAGVAR(link_all_deplibs, $1)=no
       else
 	# not using gcc
-	if test ia64 = "$host_cpu"; then
+	if test "$host_cpu" = ia64; then
 	# VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release
 	# chokes on -Wl,-G. The following line is correct:
 	  shared_flag='-G'
 	else
-	  if test yes = "$aix_use_runtimelinking"; then
-	    shared_flag='$wl-G'
+	  if test "$aix_use_runtimelinking" = yes; then
+	    shared_flag='${wl}-G'
 	  else
-	    shared_flag='$wl-bM:SRE'
+	    shared_flag='${wl}-bM:SRE'
 	  fi
-	  shared_flag_aix='$wl-bM:SRE'
-	  shared_flag_svr4='$wl-G'
 	fi
       fi
 
-      _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-bexpall'
+      _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-bexpall'
       # It seems that -bexpall does not export symbols beginning with
       # underscore (_), so it is better to generate a list of symbols to export.
       _LT_TAGVAR(always_export_symbols, $1)=yes
-      if test aix,yes = "$with_aix_soname,$aix_use_runtimelinking"; then
+      if test "$aix_use_runtimelinking" = yes; then
 	# Warning - without using the other runtime loading flags (-brtl),
 	# -berok will link without error, but may produce a broken library.
 	_LT_TAGVAR(allow_undefined_flag, $1)='-berok'
         # Determine the default libpath from the value encoded in an
         # empty executable.
         _LT_SYS_MODULE_PATH_AIX([$1])
-        _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-blibpath:$libdir:'"$aix_libpath"
-        _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs $wl'$no_entry_flag' $compiler_flags `if test -n "$allow_undefined_flag"; then func_echo_all "$wl$allow_undefined_flag"; else :; fi` $wl'$exp_sym_flag:\$export_symbols' '$shared_flag
+        _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath"
+        _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then func_echo_all "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag"
       else
-	if test ia64 = "$host_cpu"; then
-	  _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R $libdir:/usr/lib:/lib'
+	if test "$host_cpu" = ia64; then
+	  _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $libdir:/usr/lib:/lib'
 	  _LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs"
-	  _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\$wl$no_entry_flag"' $compiler_flags $wl$allow_undefined_flag '"\$wl$exp_sym_flag:\$export_symbols"
+	  _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols"
 	else
 	 # Determine the default libpath from the value encoded in an
 	 # empty executable.
 	 _LT_SYS_MODULE_PATH_AIX([$1])
-	 _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-blibpath:$libdir:'"$aix_libpath"
+	 _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath"
 	  # Warning - without using the other run time loading flags,
 	  # -berok will link without error, but may produce a broken library.
-	  _LT_TAGVAR(no_undefined_flag, $1)=' $wl-bernotok'
-	  _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-berok'
-	  if test yes = "$with_gnu_ld"; then
+	  _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-bernotok'
+	  _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-berok'
+	  if test "$with_gnu_ld" = yes; then
 	    # We only use this code for GNU lds that support --whole-archive.
-	    _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive$convenience $wl--no-whole-archive'
+	    _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive$convenience ${wl}--no-whole-archive'
 	  else
 	    # Exported symbols can be pulled into shared objects from archives
 	    _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience'
 	  fi
 	  _LT_TAGVAR(archive_cmds_need_lc, $1)=yes
-	  _LT_TAGVAR(archive_expsym_cmds, $1)='$RM -r $output_objdir/$realname.d~$MKDIR $output_objdir/$realname.d'
-	  # -brtl affects multiple linker settings, -berok does not and is overridden later
-	  compiler_flags_filtered='`func_echo_all "$compiler_flags " | $SED -e "s%-brtl\\([[, ]]\\)%-berok\\1%g"`'
-	  if test svr4 != "$with_aix_soname"; then
-	    # This is similar to how AIX traditionally builds its shared libraries.
-	    _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$CC '$shared_flag_aix' -o $output_objdir/$realname.d/$soname $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$realname.d/$soname'
-	  fi
-	  if test aix != "$with_aix_soname"; then
-	    _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$CC '$shared_flag_svr4' -o $output_objdir/$realname.d/$shared_archive_member_spec.o $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$STRIP -e $output_objdir/$realname.d/$shared_archive_member_spec.o~( func_echo_all "#! $soname($shared_archive_member_spec.o)"; if test shr_64 = "$shared_archive_member_spec"; then func_echo_all "# 64"; else func_echo_all "# 3 [...]
-	  else
-	    # used by -dlpreopen to get the symbols
-	    _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$MV  $output_objdir/$realname.d/$soname $output_objdir'
-	  fi
-	  _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$RM -r $output_objdir/$realname.d'
+	  # This is similar to how AIX traditionally builds its shared libraries.
+	  _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname'
 	fi
       fi
       ;;
@@ -5571,7 +5130,7 @@ _LT_EOF
       case $host_cpu in
       powerpc)
             # see comment about AmigaOS4 .so support
-            _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+            _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
             _LT_TAGVAR(archive_expsym_cmds, $1)=''
         ;;
       m68k)
@@ -5601,17 +5160,16 @@ _LT_EOF
 	# Tell ltmain to make .lib files, not .a files.
 	libext=lib
 	# Tell ltmain to make .dll files, not .so files.
-	shrext_cmds=.dll
+	shrext_cmds=".dll"
 	# FIXME: Setting linknames here is a bad hack.
-	_LT_TAGVAR(archive_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~linknames='
-	_LT_TAGVAR(archive_expsym_cmds, $1)='if _LT_DLL_DEF_P([$export_symbols]); then
-            cp "$export_symbols" "$output_objdir/$soname.def";
-            echo "$tool_output_objdir$soname.def" > "$output_objdir/$soname.exp";
-          else
-            $SED -e '\''s/^/-link -EXPORT:/'\'' < $export_symbols > $output_objdir/$soname.exp;
-          fi~
-          $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~
-          linknames='
+	_LT_TAGVAR(archive_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-dll~linknames='
+	_LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then
+	    sed -n -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' -e '1\\\!p' < $export_symbols > $output_objdir/$soname.exp;
+	  else
+	    sed -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' < $export_symbols > $output_objdir/$soname.exp;
+	  fi~
+	  $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~
+	  linknames='
 	# The linker will not automatically build a static lib if we build a DLL.
 	# _LT_TAGVAR(old_archive_from_new_cmds, $1)='true'
 	_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
@@ -5620,18 +5178,18 @@ _LT_EOF
 	# Don't use ranlib
 	_LT_TAGVAR(old_postinstall_cmds, $1)='chmod 644 $oldlib'
 	_LT_TAGVAR(postlink_cmds, $1)='lt_outputfile="@OUTPUT@"~
-          lt_tool_outputfile="@TOOL_OUTPUT@"~
-          case $lt_outputfile in
-            *.exe|*.EXE) ;;
-            *)
-              lt_outputfile=$lt_outputfile.exe
-              lt_tool_outputfile=$lt_tool_outputfile.exe
-              ;;
-          esac~
-          if test : != "$MANIFEST_TOOL" && test -f "$lt_outputfile.manifest"; then
-            $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1;
-            $RM "$lt_outputfile.manifest";
-          fi'
+	  lt_tool_outputfile="@TOOL_OUTPUT@"~
+	  case $lt_outputfile in
+	    *.exe|*.EXE) ;;
+	    *)
+	      lt_outputfile="$lt_outputfile.exe"
+	      lt_tool_outputfile="$lt_tool_outputfile.exe"
+	      ;;
+	  esac~
+	  if test "$MANIFEST_TOOL" != ":" && test -f "$lt_outputfile.manifest"; then
+	    $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1;
+	    $RM "$lt_outputfile.manifest";
+	  fi'
 	;;
       *)
 	# Assume MSVC wrapper
@@ -5640,7 +5198,7 @@ _LT_EOF
 	# Tell ltmain to make .lib files, not .a files.
 	libext=lib
 	# Tell ltmain to make .dll files, not .so files.
-	shrext_cmds=.dll
+	shrext_cmds=".dll"
 	# FIXME: Setting linknames here is a bad hack.
 	_LT_TAGVAR(archive_cmds, $1)='$CC -o $lib $libobjs $compiler_flags `func_echo_all "$deplibs" | $SED '\''s/ -lc$//'\''` -link -dll~linknames='
 	# The linker will automatically build a .lib file if we build a DLL.
@@ -5690,33 +5248,33 @@ _LT_EOF
       ;;
 
     hpux9*)
-      if test yes = "$GCC"; then
-	_LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared $pic_flag $wl+b $wl$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib'
+      if test "$GCC" = yes; then
+	_LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared $pic_flag ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
       else
-	_LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib'
+	_LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
       fi
-      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir'
+      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir'
       _LT_TAGVAR(hardcode_libdir_separator, $1)=:
       _LT_TAGVAR(hardcode_direct, $1)=yes
 
       # hardcode_minus_L: Not really in the search PATH,
       # but as the default location of the library.
       _LT_TAGVAR(hardcode_minus_L, $1)=yes
-      _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E'
+      _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
       ;;
 
     hpux10*)
-      if test yes,no = "$GCC,$with_gnu_ld"; then
-	_LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+      if test "$GCC" = yes && test "$with_gnu_ld" = no; then
+	_LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
       else
 	_LT_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'
       fi
-      if test no = "$with_gnu_ld"; then
-	_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir'
+      if test "$with_gnu_ld" = no; then
+	_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir'
 	_LT_TAGVAR(hardcode_libdir_separator, $1)=:
 	_LT_TAGVAR(hardcode_direct, $1)=yes
 	_LT_TAGVAR(hardcode_direct_absolute, $1)=yes
-	_LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E'
+	_LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
 	# hardcode_minus_L: Not really in the search PATH,
 	# but as the default location of the library.
 	_LT_TAGVAR(hardcode_minus_L, $1)=yes
@@ -5724,25 +5282,25 @@ _LT_EOF
       ;;
 
     hpux11*)
-      if test yes,no = "$GCC,$with_gnu_ld"; then
+      if test "$GCC" = yes && test "$with_gnu_ld" = no; then
 	case $host_cpu in
 	hppa*64*)
-	  _LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl+h $wl$soname -o $lib $libobjs $deplibs $compiler_flags'
+	  _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
 	  ;;
 	ia64*)
-	  _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $wl+h $wl$soname $wl+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
+	  _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
 	  ;;
 	*)
-	  _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+	  _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
 	  ;;
 	esac
       else
 	case $host_cpu in
 	hppa*64*)
-	  _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname -o $lib $libobjs $deplibs $compiler_flags'
+	  _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
 	  ;;
 	ia64*)
-	  _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
+	  _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
 	  ;;
 	*)
 	m4_if($1, [], [
@@ -5750,14 +5308,14 @@ _LT_EOF
 	  # (HP92453-01 A.11.01.20 doesn't, HP92453-01 B.11.X.35175-35176.GP does)
 	  _LT_LINKER_OPTION([if $CC understands -b],
 	    _LT_TAGVAR(lt_cv_prog_compiler__b, $1), [-b],
-	    [_LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags'],
+	    [_LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'],
 	    [_LT_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'])],
-	  [_LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags'])
+	  [_LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'])
 	  ;;
 	esac
       fi
-      if test no = "$with_gnu_ld"; then
-	_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir'
+      if test "$with_gnu_ld" = no; then
+	_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir'
 	_LT_TAGVAR(hardcode_libdir_separator, $1)=:
 
 	case $host_cpu in
@@ -5768,7 +5326,7 @@ _LT_EOF
 	*)
 	  _LT_TAGVAR(hardcode_direct, $1)=yes
 	  _LT_TAGVAR(hardcode_direct_absolute, $1)=yes
-	  _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E'
+	  _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
 
 	  # hardcode_minus_L: Not really in the search PATH,
 	  # but as the default location of the library.
@@ -5779,16 +5337,16 @@ _LT_EOF
       ;;
 
     irix5* | irix6* | nonstopux*)
-      if test yes = "$GCC"; then
-	_LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib'
+      if test "$GCC" = yes; then
+	_LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
 	# Try to use the -exported_symbol ld option, if it does not
 	# work, assume that -exports_file does not work either and
 	# implicitly export all symbols.
 	# This should be the same for all languages, so no per-tag cache variable.
 	AC_CACHE_CHECK([whether the $host_os linker accepts -exported_symbol],
 	  [lt_cv_irix_exported_symbol],
-	  [save_LDFLAGS=$LDFLAGS
-	   LDFLAGS="$LDFLAGS -shared $wl-exported_symbol ${wl}foo $wl-update_registry $wl/dev/null"
+	  [save_LDFLAGS="$LDFLAGS"
+	   LDFLAGS="$LDFLAGS -shared ${wl}-exported_symbol ${wl}foo ${wl}-update_registry ${wl}/dev/null"
 	   AC_LINK_IFELSE(
 	     [AC_LANG_SOURCE(
 	        [AC_LANG_CASE([C], [[int foo (void) { return 0; }]],
@@ -5801,32 +5359,21 @@ _LT_EOF
       end]])])],
 	      [lt_cv_irix_exported_symbol=yes],
 	      [lt_cv_irix_exported_symbol=no])
-           LDFLAGS=$save_LDFLAGS])
-	if test yes = "$lt_cv_irix_exported_symbol"; then
-          _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations $wl-exports_file $wl$export_symbols -o $lib'
+           LDFLAGS="$save_LDFLAGS"])
+	if test "$lt_cv_irix_exported_symbol" = yes; then
+          _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations ${wl}-exports_file ${wl}$export_symbols -o $lib'
 	fi
-	_LT_TAGVAR(link_all_deplibs, $1)=no
       else
-	_LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib'
-	_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -exports_file $export_symbols -o $lib'
+	_LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib'
+	_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -exports_file $export_symbols -o $lib'
       fi
       _LT_TAGVAR(archive_cmds_need_lc, $1)='no'
-      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir'
+      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
       _LT_TAGVAR(hardcode_libdir_separator, $1)=:
       _LT_TAGVAR(inherit_rpath, $1)=yes
       _LT_TAGVAR(link_all_deplibs, $1)=yes
       ;;
 
-    linux*)
-      case $cc_basename in
-      tcc*)
-	# Fabrice Bellard et al's Tiny C Compiler
-	_LT_TAGVAR(ld_shlibs, $1)=yes
-	_LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
-	;;
-      esac
-      ;;
-
     netbsd* | netbsdelf*-gnu)
       if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
 	_LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'  # a.out
@@ -5841,7 +5388,7 @@ _LT_EOF
     newsos6)
       _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
       _LT_TAGVAR(hardcode_direct, $1)=yes
-      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir'
+      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
       _LT_TAGVAR(hardcode_libdir_separator, $1)=:
       _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
       ;;
@@ -5849,19 +5396,27 @@ _LT_EOF
     *nto* | *qnx*)
       ;;
 
-    openbsd* | bitrig*)
+    openbsd*)
       if test -f /usr/libexec/ld.so; then
 	_LT_TAGVAR(hardcode_direct, $1)=yes
 	_LT_TAGVAR(hardcode_shlibpath_var, $1)=no
 	_LT_TAGVAR(hardcode_direct_absolute, $1)=yes
-	if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then
+	if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
 	  _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
-	  _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags $wl-retain-symbols-file,$export_symbols'
-	  _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir'
-	  _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E'
+	  _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols'
+	  _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
+	  _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
 	else
-	  _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
-	  _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir'
+	  case $host_os in
+	   openbsd[[01]].* | openbsd2.[[0-7]] | openbsd2.[[0-7]].*)
+	     _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+	     _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+	     ;;
+	   *)
+	     _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+	     _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
+	     ;;
+	  esac
 	fi
       else
 	_LT_TAGVAR(ld_shlibs, $1)=no
@@ -5872,53 +5427,33 @@ _LT_EOF
       _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
       _LT_TAGVAR(hardcode_minus_L, $1)=yes
       _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
-      shrext_cmds=.dll
-      _LT_TAGVAR(archive_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~
-	$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~
-	$ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~
-	$ECHO EXPORTS >> $output_objdir/$libname.def~
-	emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~
-	$CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~
-	emximp -o $lib $output_objdir/$libname.def'
-      _LT_TAGVAR(archive_expsym_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~
-	$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~
-	$ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~
-	$ECHO EXPORTS >> $output_objdir/$libname.def~
-	prefix_cmds="$SED"~
-	if test EXPORTS = "`$SED 1q $export_symbols`"; then
-	  prefix_cmds="$prefix_cmds -e 1d";
-	fi~
-	prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~
-	cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~
-	$CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~
-	emximp -o $lib $output_objdir/$libname.def'
-      _LT_TAGVAR(old_archive_From_new_cmds, $1)='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def'
-      _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
+      _LT_TAGVAR(archive_cmds, $1)='$ECHO "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~echo DATA >> $output_objdir/$libname.def~echo " SINGLE NONSHARED" >> $output_objdir/$libname.def~echo EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def'
+      _LT_TAGVAR(old_archive_from_new_cmds, $1)='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def'
       ;;
 
     osf3*)
-      if test yes = "$GCC"; then
-	_LT_TAGVAR(allow_undefined_flag, $1)=' $wl-expect_unresolved $wl\*'
-	_LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib'
+      if test "$GCC" = yes; then
+	_LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*'
+	_LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
       else
 	_LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*'
-	_LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib'
+	_LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib'
       fi
       _LT_TAGVAR(archive_cmds_need_lc, $1)='no'
-      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir'
+      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
       _LT_TAGVAR(hardcode_libdir_separator, $1)=:
       ;;
 
     osf4* | osf5*)	# as osf3* with the addition of -msym flag
-      if test yes = "$GCC"; then
-	_LT_TAGVAR(allow_undefined_flag, $1)=' $wl-expect_unresolved $wl\*'
-	_LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $pic_flag $libobjs $deplibs $compiler_flags $wl-msym $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib'
-	_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir'
+      if test "$GCC" = yes; then
+	_LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*'
+	_LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $pic_flag $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+	_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
       else
 	_LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*'
-	_LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib'
+	_LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib'
 	_LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~
-          $CC -shared$allow_undefined_flag $wl-input $wl$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib~$RM $lib.exp'
+	$CC -shared${allow_undefined_flag} ${wl}-input ${wl}$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib~$RM $lib.exp'
 
 	# Both c and cxx compiler support -rpath directly
 	_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir'
@@ -5929,24 +5464,24 @@ _LT_EOF
 
     solaris*)
       _LT_TAGVAR(no_undefined_flag, $1)=' -z defs'
-      if test yes = "$GCC"; then
-	wlarc='$wl'
-	_LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $wl-z ${wl}text $wl-h $wl$soname -o $lib $libobjs $deplibs $compiler_flags'
+      if test "$GCC" = yes; then
+	wlarc='${wl}'
+	_LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
 	_LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
-          $CC -shared $pic_flag $wl-z ${wl}text $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp'
+	  $CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp'
       else
 	case `$CC -V 2>&1` in
 	*"Compilers 5.0"*)
 	  wlarc=''
-	  _LT_TAGVAR(archive_cmds, $1)='$LD -G$allow_undefined_flag -h $soname -o $lib $libobjs $deplibs $linker_flags'
+	  _LT_TAGVAR(archive_cmds, $1)='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags'
 	  _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
-            $LD -G$allow_undefined_flag -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp'
+	  $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp'
 	  ;;
 	*)
-	  wlarc='$wl'
-	  _LT_TAGVAR(archive_cmds, $1)='$CC -G$allow_undefined_flag -h $soname -o $lib $libobjs $deplibs $compiler_flags'
+	  wlarc='${wl}'
+	  _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $compiler_flags'
 	  _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
-            $CC -G$allow_undefined_flag -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp'
+	  $CC -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp'
 	  ;;
 	esac
       fi
@@ -5956,11 +5491,11 @@ _LT_EOF
       solaris2.[[0-5]] | solaris2.[[0-5]].*) ;;
       *)
 	# The compiler driver will combine and reorder linker options,
-	# but understands '-z linker_flag'.  GCC discards it without '$wl',
+	# but understands `-z linker_flag'.  GCC discards it without `$wl',
 	# but is careful enough not to reorder.
 	# Supported since Solaris 2.6 (maybe 2.5.1?)
-	if test yes = "$GCC"; then
-	  _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl-z ${wl}allextract$convenience $wl-z ${wl}defaultextract'
+	if test "$GCC" = yes; then
+	  _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract'
 	else
 	  _LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract'
 	fi
@@ -5970,10 +5505,10 @@ _LT_EOF
       ;;
 
     sunos4*)
-      if test sequent = "$host_vendor"; then
+      if test "x$host_vendor" = xsequent; then
 	# Use $CC to link under sequent, because it throws in some extra .o
 	# files that make .init and .fini sections work.
-	_LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h $soname -o $lib $libobjs $deplibs $compiler_flags'
+	_LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags'
       else
 	_LT_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags'
       fi
@@ -6022,43 +5557,43 @@ _LT_EOF
       ;;
 
     sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*)
-      _LT_TAGVAR(no_undefined_flag, $1)='$wl-z,text'
+      _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text'
       _LT_TAGVAR(archive_cmds_need_lc, $1)=no
       _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
       runpath_var='LD_RUN_PATH'
 
-      if test yes = "$GCC"; then
-	_LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
-	_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+      if test "$GCC" = yes; then
+	_LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
       else
-	_LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
-	_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	_LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
       fi
       ;;
 
     sysv5* | sco3.2v5* | sco5v6*)
-      # Note: We CANNOT use -z defs as we might desire, because we do not
+      # Note: We can NOT use -z defs as we might desire, because we do not
       # link with -lc, and that would cause any symbols used from libc to
       # always be unresolved, which means just about no library would
       # ever link correctly.  If we're not using GNU ld we use -z text
       # though, which does catch some bad symbols but isn't as heavy-handed
       # as -z defs.
-      _LT_TAGVAR(no_undefined_flag, $1)='$wl-z,text'
-      _LT_TAGVAR(allow_undefined_flag, $1)='$wl-z,nodefs'
+      _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text'
+      _LT_TAGVAR(allow_undefined_flag, $1)='${wl}-z,nodefs'
       _LT_TAGVAR(archive_cmds_need_lc, $1)=no
       _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
-      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R,$libdir'
+      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R,$libdir'
       _LT_TAGVAR(hardcode_libdir_separator, $1)=':'
       _LT_TAGVAR(link_all_deplibs, $1)=yes
-      _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-Bexport'
+      _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Bexport'
       runpath_var='LD_RUN_PATH'
 
-      if test yes = "$GCC"; then
-	_LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
-	_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+      if test "$GCC" = yes; then
+	_LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
       else
-	_LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
-	_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	_LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
       fi
       ;;
 
@@ -6073,17 +5608,17 @@ _LT_EOF
       ;;
     esac
 
-    if test sni = "$host_vendor"; then
+    if test x$host_vendor = xsni; then
       case $host in
       sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*)
-	_LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-Blargedynsym'
+	_LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Blargedynsym'
 	;;
       esac
     fi
   fi
 ])
 AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)])
-test no = "$_LT_TAGVAR(ld_shlibs, $1)" && can_build_shared=no
+test "$_LT_TAGVAR(ld_shlibs, $1)" = no && can_build_shared=no
 
 _LT_TAGVAR(with_gnu_ld, $1)=$with_gnu_ld
 
@@ -6100,7 +5635,7 @@ x|xyes)
   # Assume -lc should be added
   _LT_TAGVAR(archive_cmds_need_lc, $1)=yes
 
-  if test yes,yes = "$GCC,$enable_shared"; then
+  if test "$enable_shared" = yes && test "$GCC" = yes; then
     case $_LT_TAGVAR(archive_cmds, $1) in
     *'~'*)
       # FIXME: we may have to deal with multi-command sequences.
@@ -6180,12 +5715,12 @@ _LT_TAGDECL([], [hardcode_libdir_flag_spec], [1],
 _LT_TAGDECL([], [hardcode_libdir_separator], [1],
     [Whether we need a single "-rpath" flag with a separated argument])
 _LT_TAGDECL([], [hardcode_direct], [0],
-    [Set to "yes" if using DIR/libNAME$shared_ext during linking hardcodes
+    [Set to "yes" if using DIR/libNAME${shared_ext} during linking hardcodes
     DIR into the resulting binary])
 _LT_TAGDECL([], [hardcode_direct_absolute], [0],
-    [Set to "yes" if using DIR/libNAME$shared_ext during linking hardcodes
+    [Set to "yes" if using DIR/libNAME${shared_ext} during linking hardcodes
     DIR into the resulting binary and the resulting library dependency is
-    "absolute", i.e impossible to change by setting $shlibpath_var if the
+    "absolute", i.e impossible to change by setting ${shlibpath_var} if the
     library is relocated])
 _LT_TAGDECL([], [hardcode_minus_L], [0],
     [Set to "yes" if using the -LDIR flag during linking hardcodes DIR
@@ -6226,10 +5761,10 @@ dnl    [Compiler flag to generate thread safe objects])
 # ------------------------
 # Ensure that the configuration variables for a C compiler are suitably
 # defined.  These variables are subsequently used by _LT_CONFIG to write
-# the compiler configuration to 'libtool'.
+# the compiler configuration to `libtool'.
 m4_defun([_LT_LANG_C_CONFIG],
 [m4_require([_LT_DECL_EGREP])dnl
-lt_save_CC=$CC
+lt_save_CC="$CC"
 AC_LANG_PUSH(C)
 
 # Source file extension for C test sources.
@@ -6265,18 +5800,18 @@ if test -n "$compiler"; then
   LT_SYS_DLOPEN_SELF
   _LT_CMD_STRIPLIB
 
-  # Report what library types will actually be built
+  # Report which library types will actually be built
   AC_MSG_CHECKING([if libtool supports shared libraries])
   AC_MSG_RESULT([$can_build_shared])
 
   AC_MSG_CHECKING([whether to build shared libraries])
-  test no = "$can_build_shared" && enable_shared=no
+  test "$can_build_shared" = "no" && enable_shared=no
 
   # On AIX, shared libraries and static libraries use the same namespace, and
   # are all built from PIC.
   case $host_os in
   aix3*)
-    test yes = "$enable_shared" && enable_static=no
+    test "$enable_shared" = yes && enable_static=no
     if test -n "$RANLIB"; then
       archive_cmds="$archive_cmds~\$RANLIB \$lib"
       postinstall_cmds='$RANLIB $lib'
@@ -6284,12 +5819,8 @@ if test -n "$compiler"; then
     ;;
 
   aix[[4-9]]*)
-    if test ia64 != "$host_cpu"; then
-      case $enable_shared,$with_aix_soname,$aix_use_runtimelinking in
-      yes,aix,yes) ;;			# shared object as lib.so file only
-      yes,svr4,*) ;;			# shared object as lib.so archive member only
-      yes,*) enable_static=no ;;	# shared object in lib.a archive as well
-      esac
+    if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then
+      test "$enable_shared" = yes && enable_static=no
     fi
     ;;
   esac
@@ -6297,13 +5828,13 @@ if test -n "$compiler"; then
 
   AC_MSG_CHECKING([whether to build static libraries])
   # Make sure either enable_shared or enable_static is yes.
-  test yes = "$enable_shared" || enable_static=yes
+  test "$enable_shared" = yes || enable_static=yes
   AC_MSG_RESULT([$enable_static])
 
   _LT_CONFIG($1)
 fi
 AC_LANG_POP
-CC=$lt_save_CC
+CC="$lt_save_CC"
 ])# _LT_LANG_C_CONFIG
 
 
@@ -6311,14 +5842,14 @@ CC=$lt_save_CC
 # --------------------------
 # Ensure that the configuration variables for a C++ compiler are suitably
 # defined.  These variables are subsequently used by _LT_CONFIG to write
-# the compiler configuration to 'libtool'.
+# the compiler configuration to `libtool'.
 m4_defun([_LT_LANG_CXX_CONFIG],
 [m4_require([_LT_FILEUTILS_DEFAULTS])dnl
 m4_require([_LT_DECL_EGREP])dnl
 m4_require([_LT_PATH_MANIFEST_TOOL])dnl
-if test -n "$CXX" && ( test no != "$CXX" &&
-    ( (test g++ = "$CXX" && `g++ -v >/dev/null 2>&1` ) ||
-    (test g++ != "$CXX"))); then
+if test -n "$CXX" && ( test "X$CXX" != "Xno" &&
+    ( (test "X$CXX" = "Xg++" && `g++ -v >/dev/null 2>&1` ) ||
+    (test "X$CXX" != "Xg++"))) ; then
   AC_PROG_CXXCPP
 else
   _lt_caught_CXX_error=yes
@@ -6360,7 +5891,7 @@ _LT_TAGVAR(objext, $1)=$objext
 # the CXX compiler isn't working.  Some variables (like enable_shared)
 # are currently assumed to apply to all compilers on this platform,
 # and will be corrupted by setting them based on a non-working compiler.
-if test yes != "$_lt_caught_CXX_error"; then
+if test "$_lt_caught_CXX_error" != yes; then
   # Code to be used in simple compile tests
   lt_simple_compile_test_code="int some_variable = 0;"
 
@@ -6402,35 +5933,35 @@ if test yes != "$_lt_caught_CXX_error"; then
   if test -n "$compiler"; then
     # We don't want -fno-exception when compiling C++ code, so set the
     # no_builtin_flag separately
-    if test yes = "$GXX"; then
+    if test "$GXX" = yes; then
       _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin'
     else
       _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=
     fi
 
-    if test yes = "$GXX"; then
+    if test "$GXX" = yes; then
       # Set up default GNU C++ configuration
 
       LT_PATH_LD
 
       # Check if GNU C++ uses GNU ld as the underlying linker, since the
       # archiving commands below assume that GNU ld is being used.
-      if test yes = "$with_gnu_ld"; then
-        _LT_TAGVAR(archive_cmds, $1)='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib'
-        _LT_TAGVAR(archive_expsym_cmds, $1)='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'
+      if test "$with_gnu_ld" = yes; then
+        _LT_TAGVAR(archive_cmds, $1)='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib'
+        _LT_TAGVAR(archive_expsym_cmds, $1)='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
 
-        _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir'
-        _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic'
+        _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+        _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic'
 
         # If archive_cmds runs LD, not CC, wlarc should be empty
         # XXX I think wlarc can be eliminated in ltcf-cxx, but I need to
         #     investigate it a little bit more. (MM)
-        wlarc='$wl'
+        wlarc='${wl}'
 
         # ancient GNU ld didn't support --whole-archive et. al.
         if eval "`$CC -print-prog-name=ld` --help 2>&1" |
 	  $GREP 'no-whole-archive' > /dev/null; then
-          _LT_TAGVAR(whole_archive_flag_spec, $1)=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive'
+          _LT_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive'
         else
           _LT_TAGVAR(whole_archive_flag_spec, $1)=
         fi
@@ -6466,30 +5997,18 @@ if test yes != "$_lt_caught_CXX_error"; then
         _LT_TAGVAR(ld_shlibs, $1)=no
         ;;
       aix[[4-9]]*)
-        if test ia64 = "$host_cpu"; then
+        if test "$host_cpu" = ia64; then
           # On IA64, the linker does run time linking by default, so we don't
           # have to do anything special.
           aix_use_runtimelinking=no
           exp_sym_flag='-Bexport'
-          no_entry_flag=
+          no_entry_flag=""
         else
           aix_use_runtimelinking=no
 
           # Test if we are trying to use run time linking or normal
           # AIX style linking. If -brtl is somewhere in LDFLAGS, we
-          # have runtime linking enabled, and use it for executables.
-          # For shared libraries, we enable/disable runtime linking
-          # depending on the kind of the shared library created -
-          # when "with_aix_soname,aix_use_runtimelinking" is:
-          # "aix,no"   lib.a(lib.so.V) shared, rtl:no,  for executables
-          # "aix,yes"  lib.so          shared, rtl:yes, for executables
-          #            lib.a           static archive
-          # "both,no"  lib.so.V(shr.o) shared, rtl:yes
-          #            lib.a(lib.so.V) shared, rtl:no,  for executables
-          # "both,yes" lib.so.V(shr.o) shared, rtl:yes, for executables
-          #            lib.a(lib.so.V) shared, rtl:no
-          # "svr4,*"   lib.so.V(shr.o) shared, rtl:yes, for executables
-          #            lib.a           static archive
+          # need to do runtime linking.
           case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*)
 	    for ld_flag in $LDFLAGS; do
 	      case $ld_flag in
@@ -6499,13 +6018,6 @@ if test yes != "$_lt_caught_CXX_error"; then
 	        ;;
 	      esac
 	    done
-	    if test svr4,no = "$with_aix_soname,$aix_use_runtimelinking"; then
-	      # With aix-soname=svr4, we create the lib.so.V shared archives only,
-	      # so we don't have lib.a shared libs to link our executables.
-	      # We have to force runtime linking in this case.
-	      aix_use_runtimelinking=yes
-	      LDFLAGS="$LDFLAGS -Wl,-brtl"
-	    fi
 	    ;;
           esac
 
@@ -6524,21 +6036,13 @@ if test yes != "$_lt_caught_CXX_error"; then
         _LT_TAGVAR(hardcode_direct_absolute, $1)=yes
         _LT_TAGVAR(hardcode_libdir_separator, $1)=':'
         _LT_TAGVAR(link_all_deplibs, $1)=yes
-        _LT_TAGVAR(file_list_spec, $1)='$wl-f,'
-        case $with_aix_soname,$aix_use_runtimelinking in
-        aix,*) ;;	# no import file
-        svr4,* | *,yes) # use import file
-          # The Import File defines what to hardcode.
-          _LT_TAGVAR(hardcode_direct, $1)=no
-          _LT_TAGVAR(hardcode_direct_absolute, $1)=no
-          ;;
-        esac
+        _LT_TAGVAR(file_list_spec, $1)='${wl}-f,'
 
-        if test yes = "$GXX"; then
+        if test "$GXX" = yes; then
           case $host_os in aix4.[[012]]|aix4.[[012]].*)
           # We only want to do this on AIX 4.2 and lower, the check
           # below for broken collect2 doesn't work under 4.3+
-	  collect2name=`$CC -print-prog-name=collect2`
+	  collect2name=`${CC} -print-prog-name=collect2`
 	  if test -f "$collect2name" &&
 	     strings "$collect2name" | $GREP resolve_lib_name >/dev/null
 	  then
@@ -6556,84 +6060,64 @@ if test yes != "$_lt_caught_CXX_error"; then
 	  fi
           esac
           shared_flag='-shared'
-	  if test yes = "$aix_use_runtimelinking"; then
-	    shared_flag=$shared_flag' $wl-G'
+	  if test "$aix_use_runtimelinking" = yes; then
+	    shared_flag="$shared_flag "'${wl}-G'
 	  fi
-	  # Need to ensure runtime linking is disabled for the traditional
-	  # shared library, or the linker may eventually find shared libraries
-	  # /with/ Import File - we do not want to mix them.
-	  shared_flag_aix='-shared'
-	  shared_flag_svr4='-shared $wl-G'
         else
           # not using gcc
-          if test ia64 = "$host_cpu"; then
+          if test "$host_cpu" = ia64; then
 	  # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release
 	  # chokes on -Wl,-G. The following line is correct:
 	  shared_flag='-G'
           else
-	    if test yes = "$aix_use_runtimelinking"; then
-	      shared_flag='$wl-G'
+	    if test "$aix_use_runtimelinking" = yes; then
+	      shared_flag='${wl}-G'
 	    else
-	      shared_flag='$wl-bM:SRE'
+	      shared_flag='${wl}-bM:SRE'
 	    fi
-	    shared_flag_aix='$wl-bM:SRE'
-	    shared_flag_svr4='$wl-G'
           fi
         fi
 
-        _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-bexpall'
+        _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-bexpall'
         # It seems that -bexpall does not export symbols beginning with
         # underscore (_), so it is better to generate a list of symbols to
 	# export.
         _LT_TAGVAR(always_export_symbols, $1)=yes
-	if test aix,yes = "$with_aix_soname,$aix_use_runtimelinking"; then
+        if test "$aix_use_runtimelinking" = yes; then
           # Warning - without using the other runtime loading flags (-brtl),
           # -berok will link without error, but may produce a broken library.
-          # The "-G" linker flag allows undefined symbols.
-          _LT_TAGVAR(no_undefined_flag, $1)='-bernotok'
+          _LT_TAGVAR(allow_undefined_flag, $1)='-berok'
           # Determine the default libpath from the value encoded in an empty
           # executable.
           _LT_SYS_MODULE_PATH_AIX([$1])
-          _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-blibpath:$libdir:'"$aix_libpath"
+          _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath"
 
-          _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs $wl'$no_entry_flag' $compiler_flags `if test -n "$allow_undefined_flag"; then func_echo_all "$wl$allow_undefined_flag"; else :; fi` $wl'$exp_sym_flag:\$export_symbols' '$shared_flag
+          _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then func_echo_all "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag"
         else
-          if test ia64 = "$host_cpu"; then
-	    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R $libdir:/usr/lib:/lib'
+          if test "$host_cpu" = ia64; then
+	    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $libdir:/usr/lib:/lib'
 	    _LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs"
-	    _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\$wl$no_entry_flag"' $compiler_flags $wl$allow_undefined_flag '"\$wl$exp_sym_flag:\$export_symbols"
+	    _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols"
           else
 	    # Determine the default libpath from the value encoded in an
 	    # empty executable.
 	    _LT_SYS_MODULE_PATH_AIX([$1])
-	    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-blibpath:$libdir:'"$aix_libpath"
+	    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath"
 	    # Warning - without using the other run time loading flags,
 	    # -berok will link without error, but may produce a broken library.
-	    _LT_TAGVAR(no_undefined_flag, $1)=' $wl-bernotok'
-	    _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-berok'
-	    if test yes = "$with_gnu_ld"; then
+	    _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-bernotok'
+	    _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-berok'
+	    if test "$with_gnu_ld" = yes; then
 	      # We only use this code for GNU lds that support --whole-archive.
-	      _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive$convenience $wl--no-whole-archive'
+	      _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive$convenience ${wl}--no-whole-archive'
 	    else
 	      # Exported symbols can be pulled into shared objects from archives
 	      _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience'
 	    fi
 	    _LT_TAGVAR(archive_cmds_need_lc, $1)=yes
-	    _LT_TAGVAR(archive_expsym_cmds, $1)='$RM -r $output_objdir/$realname.d~$MKDIR $output_objdir/$realname.d'
-	    # -brtl affects multiple linker settings, -berok does not and is overridden later
-	    compiler_flags_filtered='`func_echo_all "$compiler_flags " | $SED -e "s%-brtl\\([[, ]]\\)%-berok\\1%g"`'
-	    if test svr4 != "$with_aix_soname"; then
-	      # This is similar to how AIX traditionally builds its shared
-	      # libraries. Need -bnortl late, we may have -brtl in LDFLAGS.
-	      _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$CC '$shared_flag_aix' -o $output_objdir/$realname.d/$soname $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$realname.d/$soname'
-	    fi
-	    if test aix != "$with_aix_soname"; then
-	      _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$CC '$shared_flag_svr4' -o $output_objdir/$realname.d/$shared_archive_member_spec.o $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$STRIP -e $output_objdir/$realname.d/$shared_archive_member_spec.o~( func_echo_all "#! $soname($shared_archive_member_spec.o)"; if test shr_64 = "$shared_archive_member_spec"; then func_echo_all "# 64"; else func_echo_all "# [...]
-	    else
-	      # used by -dlpreopen to get the symbols
-	      _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$MV  $output_objdir/$realname.d/$soname $output_objdir'
-	    fi
-	    _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$RM -r $output_objdir/$realname.d'
+	    # This is similar to how AIX traditionally builds its shared
+	    # libraries.
+	    _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname'
           fi
         fi
         ;;
@@ -6643,7 +6127,7 @@ if test yes != "$_lt_caught_CXX_error"; then
 	  _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
 	  # Joseph Beckenbach <jrb3 at best.com> says some releases of gcc
 	  # support --undefined.  This deserves some investigation.  FIXME
-	  _LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+	  _LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
 	else
 	  _LT_TAGVAR(ld_shlibs, $1)=no
 	fi
@@ -6671,58 +6155,57 @@ if test yes != "$_lt_caught_CXX_error"; then
 	  # Tell ltmain to make .lib files, not .a files.
 	  libext=lib
 	  # Tell ltmain to make .dll files, not .so files.
-	  shrext_cmds=.dll
+	  shrext_cmds=".dll"
 	  # FIXME: Setting linknames here is a bad hack.
-	  _LT_TAGVAR(archive_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~linknames='
-	  _LT_TAGVAR(archive_expsym_cmds, $1)='if _LT_DLL_DEF_P([$export_symbols]); then
-              cp "$export_symbols" "$output_objdir/$soname.def";
-              echo "$tool_output_objdir$soname.def" > "$output_objdir/$soname.exp";
-            else
-              $SED -e '\''s/^/-link -EXPORT:/'\'' < $export_symbols > $output_objdir/$soname.exp;
-            fi~
-            $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~
-            linknames='
+	  _LT_TAGVAR(archive_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-dll~linknames='
+	  _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then
+	      $SED -n -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' -e '1\\\!p' < $export_symbols > $output_objdir/$soname.exp;
+	    else
+	      $SED -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' < $export_symbols > $output_objdir/$soname.exp;
+	    fi~
+	    $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~
+	    linknames='
 	  # The linker will not automatically build a static lib if we build a DLL.
 	  # _LT_TAGVAR(old_archive_from_new_cmds, $1)='true'
 	  _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
 	  # Don't use ranlib
 	  _LT_TAGVAR(old_postinstall_cmds, $1)='chmod 644 $oldlib'
 	  _LT_TAGVAR(postlink_cmds, $1)='lt_outputfile="@OUTPUT@"~
-            lt_tool_outputfile="@TOOL_OUTPUT@"~
-            case $lt_outputfile in
-              *.exe|*.EXE) ;;
-              *)
-                lt_outputfile=$lt_outputfile.exe
-                lt_tool_outputfile=$lt_tool_outputfile.exe
-                ;;
-            esac~
-            func_to_tool_file "$lt_outputfile"~
-            if test : != "$MANIFEST_TOOL" && test -f "$lt_outputfile.manifest"; then
-              $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1;
-              $RM "$lt_outputfile.manifest";
-            fi'
+	    lt_tool_outputfile="@TOOL_OUTPUT@"~
+	    case $lt_outputfile in
+	      *.exe|*.EXE) ;;
+	      *)
+		lt_outputfile="$lt_outputfile.exe"
+		lt_tool_outputfile="$lt_tool_outputfile.exe"
+		;;
+	    esac~
+	    func_to_tool_file "$lt_outputfile"~
+	    if test "$MANIFEST_TOOL" != ":" && test -f "$lt_outputfile.manifest"; then
+	      $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1;
+	      $RM "$lt_outputfile.manifest";
+	    fi'
 	  ;;
 	*)
 	  # g++
 	  # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless,
 	  # as there is no search path for DLLs.
 	  _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
-	  _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-all-symbols'
+	  _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-all-symbols'
 	  _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
 	  _LT_TAGVAR(always_export_symbols, $1)=no
 	  _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
 
 	  if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then
-	    _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
-	    # If the export-symbols file already is a .def file, use it as
-	    # is; otherwise, prepend EXPORTS...
-	    _LT_TAGVAR(archive_expsym_cmds, $1)='if _LT_DLL_DEF_P([$export_symbols]); then
-              cp $export_symbols $output_objdir/$soname.def;
-            else
-              echo EXPORTS > $output_objdir/$soname.def;
-              cat $export_symbols >> $output_objdir/$soname.def;
-            fi~
-            $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+	    _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+	    # If the export-symbols file already is a .def file (1st line
+	    # is EXPORTS), use it as is; otherwise, prepend...
+	    _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then
+	      cp $export_symbols $output_objdir/$soname.def;
+	    else
+	      echo EXPORTS > $output_objdir/$soname.def;
+	      cat $export_symbols >> $output_objdir/$soname.def;
+	    fi~
+	    $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
 	  else
 	    _LT_TAGVAR(ld_shlibs, $1)=no
 	  fi
@@ -6733,34 +6216,6 @@ if test yes != "$_lt_caught_CXX_error"; then
         _LT_DARWIN_LINKER_FEATURES($1)
 	;;
 
-      os2*)
-	_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
-	_LT_TAGVAR(hardcode_minus_L, $1)=yes
-	_LT_TAGVAR(allow_undefined_flag, $1)=unsupported
-	shrext_cmds=.dll
-	_LT_TAGVAR(archive_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~
-	  $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~
-	  $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~
-	  $ECHO EXPORTS >> $output_objdir/$libname.def~
-	  emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~
-	  $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~
-	  emximp -o $lib $output_objdir/$libname.def'
-	_LT_TAGVAR(archive_expsym_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~
-	  $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~
-	  $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~
-	  $ECHO EXPORTS >> $output_objdir/$libname.def~
-	  prefix_cmds="$SED"~
-	  if test EXPORTS = "`$SED 1q $export_symbols`"; then
-	    prefix_cmds="$prefix_cmds -e 1d";
-	  fi~
-	  prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~
-	  cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~
-	  $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~
-	  emximp -o $lib $output_objdir/$libname.def'
-	_LT_TAGVAR(old_archive_From_new_cmds, $1)='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def'
-	_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
-	;;
-
       dgux*)
         case $cc_basename in
           ec++*)
@@ -6796,14 +6251,14 @@ if test yes != "$_lt_caught_CXX_error"; then
         ;;
 
       haiku*)
-        _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+        _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
         _LT_TAGVAR(link_all_deplibs, $1)=yes
         ;;
 
       hpux9*)
-        _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir'
+        _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir'
         _LT_TAGVAR(hardcode_libdir_separator, $1)=:
-        _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E'
+        _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
         _LT_TAGVAR(hardcode_direct, $1)=yes
         _LT_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH,
 				             # but as the default
@@ -6815,7 +6270,7 @@ if test yes != "$_lt_caught_CXX_error"; then
             _LT_TAGVAR(ld_shlibs, $1)=no
             ;;
           aCC*)
-            _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -b $wl+b $wl$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib'
+            _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -b ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
             # Commands to make compiler produce verbose output that lists
             # what "hidden" libraries, object files and flags are used when
             # linking a shared library.
@@ -6824,11 +6279,11 @@ if test yes != "$_lt_caught_CXX_error"; then
             # explicitly linking system object files so we need to strip them
             # from the output so that they don't get included in the library
             # dependencies.
-            output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP "\-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
+            output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
             ;;
           *)
-            if test yes = "$GXX"; then
-              _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared -nostdlib $pic_flag $wl+b $wl$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib'
+            if test "$GXX" = yes; then
+              _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared -nostdlib $pic_flag ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
             else
               # FIXME: insert proper C++ library support
               _LT_TAGVAR(ld_shlibs, $1)=no
@@ -6838,15 +6293,15 @@ if test yes != "$_lt_caught_CXX_error"; then
         ;;
 
       hpux10*|hpux11*)
-        if test no = "$with_gnu_ld"; then
-	  _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir'
+        if test $with_gnu_ld = no; then
+	  _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir'
 	  _LT_TAGVAR(hardcode_libdir_separator, $1)=:
 
           case $host_cpu in
             hppa*64*|ia64*)
               ;;
             *)
-	      _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E'
+	      _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
               ;;
           esac
         fi
@@ -6872,13 +6327,13 @@ if test yes != "$_lt_caught_CXX_error"; then
           aCC*)
 	    case $host_cpu in
 	      hppa*64*)
-	        _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+	        _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
 	        ;;
 	      ia64*)
-	        _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+	        _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
 	        ;;
 	      *)
-	        _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+	        _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
 	        ;;
 	    esac
 	    # Commands to make compiler produce verbose output that lists
@@ -6889,20 +6344,20 @@ if test yes != "$_lt_caught_CXX_error"; then
 	    # explicitly linking system object files so we need to strip them
 	    # from the output so that they don't get included in the library
 	    # dependencies.
-	    output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP "\-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
+	    output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
 	    ;;
           *)
-	    if test yes = "$GXX"; then
-	      if test no = "$with_gnu_ld"; then
+	    if test "$GXX" = yes; then
+	      if test $with_gnu_ld = no; then
 	        case $host_cpu in
 	          hppa*64*)
-	            _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC $wl+h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+	            _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
 	            ;;
 	          ia64*)
-	            _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $pic_flag $wl+h $wl$soname $wl+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+	            _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $pic_flag ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
 	            ;;
 	          *)
-	            _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+	            _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
 	            ;;
 	        esac
 	      fi
@@ -6917,22 +6372,22 @@ if test yes != "$_lt_caught_CXX_error"; then
       interix[[3-9]]*)
 	_LT_TAGVAR(hardcode_direct, $1)=no
 	_LT_TAGVAR(hardcode_shlibpath_var, $1)=no
-	_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir'
-	_LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E'
+	_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
+	_LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
 	# Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc.
 	# Instead, shared libraries are loaded at an image base (0x10000000 by
 	# default) and relocated if they conflict, which is a slow very memory
 	# consuming and fragmenting process.  To avoid this, we pick a random,
 	# 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link
 	# time.  Moving up from 0x10000000 also allows more sbrk(2) space.
-	_LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
-	_LT_TAGVAR(archive_expsym_cmds, $1)='sed "s|^|_|" $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--retain-symbols-file,$output_objdir/$soname.expsym $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+	_LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+	_LT_TAGVAR(archive_expsym_cmds, $1)='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
 	;;
       irix5* | irix6*)
         case $cc_basename in
           CC*)
 	    # SGI C++
-	    _LT_TAGVAR(archive_cmds, $1)='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib'
+	    _LT_TAGVAR(archive_cmds, $1)='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib'
 
 	    # Archives containing C++ object files must be created using
 	    # "CC -ar", where "CC" is the IRIX C++ compiler.  This is
@@ -6941,17 +6396,17 @@ if test yes != "$_lt_caught_CXX_error"; then
 	    _LT_TAGVAR(old_archive_cmds, $1)='$CC -ar -WR,-u -o $oldlib $oldobjs'
 	    ;;
           *)
-	    if test yes = "$GXX"; then
-	      if test no = "$with_gnu_ld"; then
-	        _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib'
+	    if test "$GXX" = yes; then
+	      if test "$with_gnu_ld" = no; then
+	        _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
 	      else
-	        _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` -o $lib'
+	        _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` -o $lib'
 	      fi
 	    fi
 	    _LT_TAGVAR(link_all_deplibs, $1)=yes
 	    ;;
         esac
-        _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir'
+        _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
         _LT_TAGVAR(hardcode_libdir_separator, $1)=:
         _LT_TAGVAR(inherit_rpath, $1)=yes
         ;;
@@ -6964,8 +6419,8 @@ if test yes != "$_lt_caught_CXX_error"; then
 	    # KCC will only create a shared library if the output file
 	    # ends with ".so" (or ".sl" for HP-UX), so rename the library
 	    # to its proper name (with version) after linking.
-	    _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib'
-	    _LT_TAGVAR(archive_expsym_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib $wl-retain-symbols-file,$export_symbols; mv \$templib $lib'
+	    _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib'
+	    _LT_TAGVAR(archive_expsym_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib ${wl}-retain-symbols-file,$export_symbols; mv \$templib $lib'
 	    # Commands to make compiler produce verbose output that lists
 	    # what "hidden" libraries, object files and flags are used when
 	    # linking a shared library.
@@ -6974,10 +6429,10 @@ if test yes != "$_lt_caught_CXX_error"; then
 	    # explicitly linking system object files so we need to strip them
 	    # from the output so that they don't get included in the library
 	    # dependencies.
-	    output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | $GREP "ld"`; rm -f libconftest$shared_ext; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
+	    output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | $GREP "ld"`; rm -f libconftest$shared_ext; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
 
-	    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir'
-	    _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic'
+	    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
+	    _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic'
 
 	    # Archives containing C++ object files must be created using
 	    # "CC -Bstatic", where "CC" is the KAI C++ compiler.
@@ -6991,59 +6446,59 @@ if test yes != "$_lt_caught_CXX_error"; then
 	    # earlier do not add the objects themselves.
 	    case `$CC -V 2>&1` in
 	      *"Version 7."*)
-	        _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib'
-		_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'
+	        _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib'
+		_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
 		;;
 	      *)  # Version 8.0 or newer
 	        tmp_idyn=
 	        case $host_cpu in
 		  ia64*) tmp_idyn=' -i_dynamic';;
 		esac
-	        _LT_TAGVAR(archive_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
-		_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'
+	        _LT_TAGVAR(archive_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+		_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
 		;;
 	    esac
 	    _LT_TAGVAR(archive_cmds_need_lc, $1)=no
-	    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir'
-	    _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic'
-	    _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive$convenience $wl--no-whole-archive'
+	    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
+	    _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic'
+	    _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive$convenience ${wl}--no-whole-archive'
 	    ;;
           pgCC* | pgcpp*)
             # Portland Group C++ compiler
 	    case `$CC -V` in
 	    *pgCC\ [[1-5]].* | *pgcpp\ [[1-5]].*)
 	      _LT_TAGVAR(prelink_cmds, $1)='tpldir=Template.dir~
-               rm -rf $tpldir~
-               $CC --prelink_objects --instantiation_dir $tpldir $objs $libobjs $compile_deplibs~
-               compile_command="$compile_command `find $tpldir -name \*.o | sort | $NL2SP`"'
+		rm -rf $tpldir~
+		$CC --prelink_objects --instantiation_dir $tpldir $objs $libobjs $compile_deplibs~
+		compile_command="$compile_command `find $tpldir -name \*.o | sort | $NL2SP`"'
 	      _LT_TAGVAR(old_archive_cmds, $1)='tpldir=Template.dir~
-                rm -rf $tpldir~
-                $CC --prelink_objects --instantiation_dir $tpldir $oldobjs$old_deplibs~
-                $AR $AR_FLAGS $oldlib$oldobjs$old_deplibs `find $tpldir -name \*.o | sort | $NL2SP`~
-                $RANLIB $oldlib'
+		rm -rf $tpldir~
+		$CC --prelink_objects --instantiation_dir $tpldir $oldobjs$old_deplibs~
+		$AR $AR_FLAGS $oldlib$oldobjs$old_deplibs `find $tpldir -name \*.o | sort | $NL2SP`~
+		$RANLIB $oldlib'
 	      _LT_TAGVAR(archive_cmds, $1)='tpldir=Template.dir~
-                rm -rf $tpldir~
-                $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~
-                $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib'
+		rm -rf $tpldir~
+		$CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~
+		$CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib'
 	      _LT_TAGVAR(archive_expsym_cmds, $1)='tpldir=Template.dir~
-                rm -rf $tpldir~
-                $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~
-                $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'
+		rm -rf $tpldir~
+		$CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~
+		$CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib'
 	      ;;
 	    *) # Version 6 and above use weak symbols
-	      _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib'
-	      _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'
+	      _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib'
+	      _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib'
 	      ;;
 	    esac
 
-	    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl--rpath $wl$libdir'
-	    _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic'
-	    _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive'
+	    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}--rpath ${wl}$libdir'
+	    _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic'
+	    _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
             ;;
 	  cxx*)
 	    # Compaq C++
-	    _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib'
-	    _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname  -o $lib $wl-retain-symbols-file $wl$export_symbols'
+	    _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib'
+	    _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname  -o $lib ${wl}-retain-symbols-file $wl$export_symbols'
 
 	    runpath_var=LD_RUN_PATH
 	    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir'
@@ -7057,18 +6512,18 @@ if test yes != "$_lt_caught_CXX_error"; then
 	    # explicitly linking system object files so we need to strip them
 	    # from the output so that they don't get included in the library
 	    # dependencies.
-	    output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "X$list" | $Xsed'
+	    output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "X$list" | $Xsed'
 	    ;;
 	  xl* | mpixl* | bgxl*)
 	    # IBM XL 8.0 on PPC, with GNU ld
-	    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir'
-	    _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic'
-	    _LT_TAGVAR(archive_cmds, $1)='$CC -qmkshrobj $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
-	    if test yes = "$supports_anon_versioning"; then
+	    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+	    _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic'
+	    _LT_TAGVAR(archive_cmds, $1)='$CC -qmkshrobj $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+	    if test "x$supports_anon_versioning" = xyes; then
 	      _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~
-                cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
-                echo "local: *; };" >> $output_objdir/$libname.ver~
-                $CC -qmkshrobj $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-version-script $wl$output_objdir/$libname.ver -o $lib'
+		cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
+		echo "local: *; };" >> $output_objdir/$libname.ver~
+		$CC -qmkshrobj $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib'
 	    fi
 	    ;;
 	  *)
@@ -7076,10 +6531,10 @@ if test yes != "$_lt_caught_CXX_error"; then
 	    *Sun\ C*)
 	      # Sun C++ 5.9
 	      _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs'
-	      _LT_TAGVAR(archive_cmds, $1)='$CC -G$allow_undefined_flag -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
-	      _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G$allow_undefined_flag -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-retain-symbols-file $wl$export_symbols'
+	      _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+	      _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file ${wl}$export_symbols'
 	      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
-	      _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive'
+	      _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
 	      _LT_TAGVAR(compiler_needs_object, $1)=yes
 
 	      # Not sure whether something based on
@@ -7137,17 +6592,22 @@ if test yes != "$_lt_caught_CXX_error"; then
         _LT_TAGVAR(ld_shlibs, $1)=yes
 	;;
 
-      openbsd* | bitrig*)
+      openbsd2*)
+        # C++ shared libraries are fairly broken
+	_LT_TAGVAR(ld_shlibs, $1)=no
+	;;
+
+      openbsd*)
 	if test -f /usr/libexec/ld.so; then
 	  _LT_TAGVAR(hardcode_direct, $1)=yes
 	  _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
 	  _LT_TAGVAR(hardcode_direct_absolute, $1)=yes
 	  _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib'
-	  _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir'
-	  if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`"; then
-	    _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-retain-symbols-file,$export_symbols -o $lib'
-	    _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E'
-	    _LT_TAGVAR(whole_archive_flag_spec, $1)=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive'
+	  _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
+	  if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+	    _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file,$export_symbols -o $lib'
+	    _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
+	    _LT_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive'
 	  fi
 	  output_verbose_link_cmd=func_echo_all
 	else
@@ -7163,9 +6623,9 @@ if test yes != "$_lt_caught_CXX_error"; then
 	    # KCC will only create a shared library if the output file
 	    # ends with ".so" (or ".sl" for HP-UX), so rename the library
 	    # to its proper name (with version) after linking.
-	    _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo "$lib" | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib'
+	    _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo "$lib" | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib'
 
-	    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir'
+	    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
 	    _LT_TAGVAR(hardcode_libdir_separator, $1)=:
 
 	    # Archives containing C++ object files must be created using
@@ -7183,17 +6643,17 @@ if test yes != "$_lt_caught_CXX_error"; then
           cxx*)
 	    case $host in
 	      osf3*)
-	        _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-expect_unresolved $wl\*'
-	        _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $soname `test -n "$verstring" && func_echo_all "$wl-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib'
-	        _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir'
+	        _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*'
+	        _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $soname `test -n "$verstring" && func_echo_all "${wl}-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib'
+	        _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
 		;;
 	      *)
 	        _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*'
-	        _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib'
+	        _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib'
 	        _LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done~
-                  echo "-hidden">> $lib.exp~
-                  $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname $wl-input $wl$lib.exp  `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib~
-                  $RM $lib.exp'
+	          echo "-hidden">> $lib.exp~
+	          $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname ${wl}-input ${wl}$lib.exp  `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib~
+	          $RM $lib.exp'
 	        _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir'
 		;;
 	    esac
@@ -7208,21 +6668,21 @@ if test yes != "$_lt_caught_CXX_error"; then
 	    # explicitly linking system object files so we need to strip them
 	    # from the output so that they don't get included in the library
 	    # dependencies.
-	    output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld" | $GREP -v "ld:"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
+	    output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld" | $GREP -v "ld:"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
 	    ;;
 	  *)
-	    if test yes,no = "$GXX,$with_gnu_ld"; then
-	      _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-expect_unresolved $wl\*'
+	    if test "$GXX" = yes && test "$with_gnu_ld" = no; then
+	      _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*'
 	      case $host in
 	        osf3*)
-	          _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib'
+	          _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
 		  ;;
 	        *)
-	          _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-msym $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib'
+	          _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
 		  ;;
 	      esac
 
-	      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir'
+	      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
 	      _LT_TAGVAR(hardcode_libdir_separator, $1)=:
 
 	      # Commands to make compiler produce verbose output that lists
@@ -7268,9 +6728,9 @@ if test yes != "$_lt_caught_CXX_error"; then
 	    # Sun C++ 4.2, 5.x and Centerline C++
             _LT_TAGVAR(archive_cmds_need_lc,$1)=yes
 	    _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs'
-	    _LT_TAGVAR(archive_cmds, $1)='$CC -G$allow_undefined_flag -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+	    _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag}  -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
 	    _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
-              $CC -G$allow_undefined_flag $wl-M $wl$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp'
+	      $CC -G${allow_undefined_flag} ${wl}-M ${wl}$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp'
 
 	    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
 	    _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
@@ -7278,7 +6738,7 @@ if test yes != "$_lt_caught_CXX_error"; then
 	      solaris2.[[0-5]] | solaris2.[[0-5]].*) ;;
 	      *)
 		# The compiler driver will combine and reorder linker options,
-		# but understands '-z linker_flag'.
+		# but understands `-z linker_flag'.
 	        # Supported since Solaris 2.6 (maybe 2.5.1?)
 		_LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract'
 	        ;;
@@ -7295,30 +6755,30 @@ if test yes != "$_lt_caught_CXX_error"; then
 	    ;;
           gcx*)
 	    # Green Hills C++ Compiler
-	    _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-h $wl$soname -o $lib'
+	    _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib'
 
 	    # The C++ compiler must be used to create the archive.
 	    _LT_TAGVAR(old_archive_cmds, $1)='$CC $LDFLAGS -archive -o $oldlib $oldobjs'
 	    ;;
           *)
 	    # GNU C++ compiler with Solaris linker
-	    if test yes,no = "$GXX,$with_gnu_ld"; then
-	      _LT_TAGVAR(no_undefined_flag, $1)=' $wl-z ${wl}defs'
+	    if test "$GXX" = yes && test "$with_gnu_ld" = no; then
+	      _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-z ${wl}defs'
 	      if $CC --version | $GREP -v '^2\.7' > /dev/null; then
-	        _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-h $wl$soname -o $lib'
+	        _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib'
 	        _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
-                  $CC -shared $pic_flag -nostdlib $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp'
+		  $CC -shared $pic_flag -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp'
 
 	        # Commands to make compiler produce verbose output that lists
 	        # what "hidden" libraries, object files and flags are used when
 	        # linking a shared library.
 	        output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"'
 	      else
-	        # g++ 2.7 appears to require '-G' NOT '-shared' on this
+	        # g++ 2.7 appears to require `-G' NOT `-shared' on this
 	        # platform.
-	        _LT_TAGVAR(archive_cmds, $1)='$CC -G -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-h $wl$soname -o $lib'
+	        _LT_TAGVAR(archive_cmds, $1)='$CC -G -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib'
 	        _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
-                  $CC -G -nostdlib $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp'
+		  $CC -G -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp'
 
 	        # Commands to make compiler produce verbose output that lists
 	        # what "hidden" libraries, object files and flags are used when
@@ -7326,11 +6786,11 @@ if test yes != "$_lt_caught_CXX_error"; then
 	        output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"'
 	      fi
 
-	      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R $wl$libdir'
+	      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $wl$libdir'
 	      case $host_os in
 		solaris2.[[0-5]] | solaris2.[[0-5]].*) ;;
 		*)
-		  _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl-z ${wl}allextract$convenience $wl-z ${wl}defaultextract'
+		  _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract'
 		  ;;
 	      esac
 	    fi
@@ -7339,52 +6799,52 @@ if test yes != "$_lt_caught_CXX_error"; then
         ;;
 
     sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*)
-      _LT_TAGVAR(no_undefined_flag, $1)='$wl-z,text'
+      _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text'
       _LT_TAGVAR(archive_cmds_need_lc, $1)=no
       _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
       runpath_var='LD_RUN_PATH'
 
       case $cc_basename in
         CC*)
-	  _LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
-	  _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	  _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	  _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
 	  ;;
 	*)
-	  _LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
-	  _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	  _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	  _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
 	  ;;
       esac
       ;;
 
       sysv5* | sco3.2v5* | sco5v6*)
-	# Note: We CANNOT use -z defs as we might desire, because we do not
+	# Note: We can NOT use -z defs as we might desire, because we do not
 	# link with -lc, and that would cause any symbols used from libc to
 	# always be unresolved, which means just about no library would
 	# ever link correctly.  If we're not using GNU ld we use -z text
 	# though, which does catch some bad symbols but isn't as heavy-handed
 	# as -z defs.
-	_LT_TAGVAR(no_undefined_flag, $1)='$wl-z,text'
-	_LT_TAGVAR(allow_undefined_flag, $1)='$wl-z,nodefs'
+	_LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text'
+	_LT_TAGVAR(allow_undefined_flag, $1)='${wl}-z,nodefs'
 	_LT_TAGVAR(archive_cmds_need_lc, $1)=no
 	_LT_TAGVAR(hardcode_shlibpath_var, $1)=no
-	_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R,$libdir'
+	_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R,$libdir'
 	_LT_TAGVAR(hardcode_libdir_separator, $1)=':'
 	_LT_TAGVAR(link_all_deplibs, $1)=yes
-	_LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-Bexport'
+	_LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Bexport'
 	runpath_var='LD_RUN_PATH'
 
 	case $cc_basename in
           CC*)
-	    _LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
-	    _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	    _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	    _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
 	    _LT_TAGVAR(old_archive_cmds, $1)='$CC -Tprelink_objects $oldobjs~
-              '"$_LT_TAGVAR(old_archive_cmds, $1)"
+	      '"$_LT_TAGVAR(old_archive_cmds, $1)"
 	    _LT_TAGVAR(reload_cmds, $1)='$CC -Tprelink_objects $reload_objs~
-              '"$_LT_TAGVAR(reload_cmds, $1)"
+	      '"$_LT_TAGVAR(reload_cmds, $1)"
 	    ;;
 	  *)
-	    _LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
-	    _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	    _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	    _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
 	    ;;
 	esac
       ;;
@@ -7415,10 +6875,10 @@ if test yes != "$_lt_caught_CXX_error"; then
     esac
 
     AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)])
-    test no = "$_LT_TAGVAR(ld_shlibs, $1)" && can_build_shared=no
+    test "$_LT_TAGVAR(ld_shlibs, $1)" = no && can_build_shared=no
 
-    _LT_TAGVAR(GCC, $1)=$GXX
-    _LT_TAGVAR(LD, $1)=$LD
+    _LT_TAGVAR(GCC, $1)="$GXX"
+    _LT_TAGVAR(LD, $1)="$LD"
 
     ## CAVEAT EMPTOR:
     ## There is no encapsulation within the following macros, do not change
@@ -7445,7 +6905,7 @@ if test yes != "$_lt_caught_CXX_error"; then
   lt_cv_path_LD=$lt_save_path_LD
   lt_cv_prog_gnu_ldcxx=$lt_cv_prog_gnu_ld
   lt_cv_prog_gnu_ld=$lt_save_with_gnu_ld
-fi # test yes != "$_lt_caught_CXX_error"
+fi # test "$_lt_caught_CXX_error" != yes
 
 AC_LANG_POP
 ])# _LT_LANG_CXX_CONFIG
@@ -7467,14 +6927,13 @@ AC_REQUIRE([_LT_DECL_SED])
 AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH])
 func_stripname_cnf ()
 {
-  case @S|@2 in
-  .*) func_stripname_result=`$ECHO "@S|@3" | $SED "s%^@S|@1%%; s%\\\\@S|@2\$%%"`;;
-  *)  func_stripname_result=`$ECHO "@S|@3" | $SED "s%^@S|@1%%; s%@S|@2\$%%"`;;
+  case ${2} in
+  .*) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%\\\\${2}\$%%"`;;
+  *)  func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%${2}\$%%"`;;
   esac
 } # func_stripname_cnf
 ])# _LT_FUNC_STRIPNAME_CNF
 
-
 # _LT_SYS_HIDDEN_LIBDEPS([TAGNAME])
 # ---------------------------------
 # Figure out "hidden" library dependencies from verbose
@@ -7558,13 +7017,13 @@ if AC_TRY_EVAL(ac_compile); then
   pre_test_object_deps_done=no
 
   for p in `eval "$output_verbose_link_cmd"`; do
-    case $prev$p in
+    case ${prev}${p} in
 
     -L* | -R* | -l*)
        # Some compilers place space between "-{L,R}" and the path.
        # Remove the space.
-       if test x-L = "$p" ||
-          test x-R = "$p"; then
+       if test $p = "-L" ||
+          test $p = "-R"; then
 	 prev=$p
 	 continue
        fi
@@ -7580,16 +7039,16 @@ if AC_TRY_EVAL(ac_compile); then
        case $p in
        =*) func_stripname_cnf '=' '' "$p"; p=$lt_sysroot$func_stripname_result ;;
        esac
-       if test no = "$pre_test_object_deps_done"; then
-	 case $prev in
+       if test "$pre_test_object_deps_done" = no; then
+	 case ${prev} in
 	 -L | -R)
 	   # Internal compiler library paths should come after those
 	   # provided the user.  The postdeps already come after the
 	   # user supplied libs so there is no need to process them.
 	   if test -z "$_LT_TAGVAR(compiler_lib_search_path, $1)"; then
-	     _LT_TAGVAR(compiler_lib_search_path, $1)=$prev$p
+	     _LT_TAGVAR(compiler_lib_search_path, $1)="${prev}${p}"
 	   else
-	     _LT_TAGVAR(compiler_lib_search_path, $1)="${_LT_TAGVAR(compiler_lib_search_path, $1)} $prev$p"
+	     _LT_TAGVAR(compiler_lib_search_path, $1)="${_LT_TAGVAR(compiler_lib_search_path, $1)} ${prev}${p}"
 	   fi
 	   ;;
 	 # The "-l" case would never come before the object being
@@ -7597,9 +7056,9 @@ if AC_TRY_EVAL(ac_compile); then
 	 esac
        else
 	 if test -z "$_LT_TAGVAR(postdeps, $1)"; then
-	   _LT_TAGVAR(postdeps, $1)=$prev$p
+	   _LT_TAGVAR(postdeps, $1)="${prev}${p}"
 	 else
-	   _LT_TAGVAR(postdeps, $1)="${_LT_TAGVAR(postdeps, $1)} $prev$p"
+	   _LT_TAGVAR(postdeps, $1)="${_LT_TAGVAR(postdeps, $1)} ${prev}${p}"
 	 fi
        fi
        prev=
@@ -7614,15 +7073,15 @@ if AC_TRY_EVAL(ac_compile); then
 	 continue
        fi
 
-       if test no = "$pre_test_object_deps_done"; then
+       if test "$pre_test_object_deps_done" = no; then
 	 if test -z "$_LT_TAGVAR(predep_objects, $1)"; then
-	   _LT_TAGVAR(predep_objects, $1)=$p
+	   _LT_TAGVAR(predep_objects, $1)="$p"
 	 else
 	   _LT_TAGVAR(predep_objects, $1)="$_LT_TAGVAR(predep_objects, $1) $p"
 	 fi
        else
 	 if test -z "$_LT_TAGVAR(postdep_objects, $1)"; then
-	   _LT_TAGVAR(postdep_objects, $1)=$p
+	   _LT_TAGVAR(postdep_objects, $1)="$p"
 	 else
 	   _LT_TAGVAR(postdep_objects, $1)="$_LT_TAGVAR(postdep_objects, $1) $p"
 	 fi
@@ -7653,6 +7112,51 @@ interix[[3-9]]*)
   _LT_TAGVAR(postdep_objects,$1)=
   _LT_TAGVAR(postdeps,$1)=
   ;;
+
+linux*)
+  case `$CC -V 2>&1 | sed 5q` in
+  *Sun\ C*)
+    # Sun C++ 5.9
+
+    # The more standards-conforming stlport4 library is
+    # incompatible with the Cstd library. Avoid specifying
+    # it if it's in CXXFLAGS. Ignore libCrun as
+    # -library=stlport4 depends on it.
+    case " $CXX $CXXFLAGS " in
+    *" -library=stlport4 "*)
+      solaris_use_stlport4=yes
+      ;;
+    esac
+
+    if test "$solaris_use_stlport4" != yes; then
+      _LT_TAGVAR(postdeps,$1)='-library=Cstd -library=Crun'
+    fi
+    ;;
+  esac
+  ;;
+
+solaris*)
+  case $cc_basename in
+  CC* | sunCC*)
+    # The more standards-conforming stlport4 library is
+    # incompatible with the Cstd library. Avoid specifying
+    # it if it's in CXXFLAGS. Ignore libCrun as
+    # -library=stlport4 depends on it.
+    case " $CXX $CXXFLAGS " in
+    *" -library=stlport4 "*)
+      solaris_use_stlport4=yes
+      ;;
+    esac
+
+    # Adding this requires a known-good setup of shared libraries for
+    # Sun compiler versions before 5.6, else PIC objects from an old
+    # archive will be linked into the output, leading to subtle bugs.
+    if test "$solaris_use_stlport4" != yes; then
+      _LT_TAGVAR(postdeps,$1)='-library=Cstd -library=Crun'
+    fi
+    ;;
+  esac
+  ;;
 esac
 ])
 
@@ -7661,7 +7165,7 @@ case " $_LT_TAGVAR(postdeps, $1) " in
 esac
  _LT_TAGVAR(compiler_lib_search_dirs, $1)=
 if test -n "${_LT_TAGVAR(compiler_lib_search_path, $1)}"; then
- _LT_TAGVAR(compiler_lib_search_dirs, $1)=`echo " ${_LT_TAGVAR(compiler_lib_search_path, $1)}" | $SED -e 's! -L! !g' -e 's!^ !!'`
+ _LT_TAGVAR(compiler_lib_search_dirs, $1)=`echo " ${_LT_TAGVAR(compiler_lib_search_path, $1)}" | ${SED} -e 's! -L! !g' -e 's!^ !!'`
 fi
 _LT_TAGDECL([], [compiler_lib_search_dirs], [1],
     [The directories searched by this compiler when creating a shared library])
@@ -7681,10 +7185,10 @@ _LT_TAGDECL([], [compiler_lib_search_path], [1],
 # --------------------------
 # Ensure that the configuration variables for a Fortran 77 compiler are
 # suitably defined.  These variables are subsequently used by _LT_CONFIG
-# to write the compiler configuration to 'libtool'.
+# to write the compiler configuration to `libtool'.
 m4_defun([_LT_LANG_F77_CONFIG],
 [AC_LANG_PUSH(Fortran 77)
-if test -z "$F77" || test no = "$F77"; then
+if test -z "$F77" || test "X$F77" = "Xno"; then
   _lt_disable_F77=yes
 fi
 
@@ -7721,7 +7225,7 @@ _LT_TAGVAR(objext, $1)=$objext
 # the F77 compiler isn't working.  Some variables (like enable_shared)
 # are currently assumed to apply to all compilers on this platform,
 # and will be corrupted by setting them based on a non-working compiler.
-if test yes != "$_lt_disable_F77"; then
+if test "$_lt_disable_F77" != yes; then
   # Code to be used in simple compile tests
   lt_simple_compile_test_code="\
       subroutine t
@@ -7743,7 +7247,7 @@ if test yes != "$_lt_disable_F77"; then
   _LT_LINKER_BOILERPLATE
 
   # Allow CC to be a program name with arguments.
-  lt_save_CC=$CC
+  lt_save_CC="$CC"
   lt_save_GCC=$GCC
   lt_save_CFLAGS=$CFLAGS
   CC=${F77-"f77"}
@@ -7757,25 +7261,21 @@ if test yes != "$_lt_disable_F77"; then
     AC_MSG_RESULT([$can_build_shared])
 
     AC_MSG_CHECKING([whether to build shared libraries])
-    test no = "$can_build_shared" && enable_shared=no
+    test "$can_build_shared" = "no" && enable_shared=no
 
     # On AIX, shared libraries and static libraries use the same namespace, and
     # are all built from PIC.
     case $host_os in
       aix3*)
-        test yes = "$enable_shared" && enable_static=no
+        test "$enable_shared" = yes && enable_static=no
         if test -n "$RANLIB"; then
           archive_cmds="$archive_cmds~\$RANLIB \$lib"
           postinstall_cmds='$RANLIB $lib'
         fi
         ;;
       aix[[4-9]]*)
-	if test ia64 != "$host_cpu"; then
-	  case $enable_shared,$with_aix_soname,$aix_use_runtimelinking in
-	  yes,aix,yes) ;;		# shared object as lib.so file only
-	  yes,svr4,*) ;;		# shared object as lib.so archive member only
-	  yes,*) enable_static=no ;;	# shared object in lib.a archive as well
-	  esac
+	if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then
+	  test "$enable_shared" = yes && enable_static=no
 	fi
         ;;
     esac
@@ -7783,11 +7283,11 @@ if test yes != "$_lt_disable_F77"; then
 
     AC_MSG_CHECKING([whether to build static libraries])
     # Make sure either enable_shared or enable_static is yes.
-    test yes = "$enable_shared" || enable_static=yes
+    test "$enable_shared" = yes || enable_static=yes
     AC_MSG_RESULT([$enable_static])
 
-    _LT_TAGVAR(GCC, $1)=$G77
-    _LT_TAGVAR(LD, $1)=$LD
+    _LT_TAGVAR(GCC, $1)="$G77"
+    _LT_TAGVAR(LD, $1)="$LD"
 
     ## CAVEAT EMPTOR:
     ## There is no encapsulation within the following macros, do not change
@@ -7804,9 +7304,9 @@ if test yes != "$_lt_disable_F77"; then
   fi # test -n "$compiler"
 
   GCC=$lt_save_GCC
-  CC=$lt_save_CC
-  CFLAGS=$lt_save_CFLAGS
-fi # test yes != "$_lt_disable_F77"
+  CC="$lt_save_CC"
+  CFLAGS="$lt_save_CFLAGS"
+fi # test "$_lt_disable_F77" != yes
 
 AC_LANG_POP
 ])# _LT_LANG_F77_CONFIG
@@ -7816,11 +7316,11 @@ AC_LANG_POP
 # -------------------------
 # Ensure that the configuration variables for a Fortran compiler are
 # suitably defined.  These variables are subsequently used by _LT_CONFIG
-# to write the compiler configuration to 'libtool'.
+# to write the compiler configuration to `libtool'.
 m4_defun([_LT_LANG_FC_CONFIG],
 [AC_LANG_PUSH(Fortran)
 
-if test -z "$FC" || test no = "$FC"; then
+if test -z "$FC" || test "X$FC" = "Xno"; then
   _lt_disable_FC=yes
 fi
 
@@ -7857,7 +7357,7 @@ _LT_TAGVAR(objext, $1)=$objext
 # the FC compiler isn't working.  Some variables (like enable_shared)
 # are currently assumed to apply to all compilers on this platform,
 # and will be corrupted by setting them based on a non-working compiler.
-if test yes != "$_lt_disable_FC"; then
+if test "$_lt_disable_FC" != yes; then
   # Code to be used in simple compile tests
   lt_simple_compile_test_code="\
       subroutine t
@@ -7879,7 +7379,7 @@ if test yes != "$_lt_disable_FC"; then
   _LT_LINKER_BOILERPLATE
 
   # Allow CC to be a program name with arguments.
-  lt_save_CC=$CC
+  lt_save_CC="$CC"
   lt_save_GCC=$GCC
   lt_save_CFLAGS=$CFLAGS
   CC=${FC-"f95"}
@@ -7895,25 +7395,21 @@ if test yes != "$_lt_disable_FC"; then
     AC_MSG_RESULT([$can_build_shared])
 
     AC_MSG_CHECKING([whether to build shared libraries])
-    test no = "$can_build_shared" && enable_shared=no
+    test "$can_build_shared" = "no" && enable_shared=no
 
     # On AIX, shared libraries and static libraries use the same namespace, and
     # are all built from PIC.
     case $host_os in
       aix3*)
-        test yes = "$enable_shared" && enable_static=no
+        test "$enable_shared" = yes && enable_static=no
         if test -n "$RANLIB"; then
           archive_cmds="$archive_cmds~\$RANLIB \$lib"
           postinstall_cmds='$RANLIB $lib'
         fi
         ;;
       aix[[4-9]]*)
-	if test ia64 != "$host_cpu"; then
-	  case $enable_shared,$with_aix_soname,$aix_use_runtimelinking in
-	  yes,aix,yes) ;;		# shared object as lib.so file only
-	  yes,svr4,*) ;;		# shared object as lib.so archive member only
-	  yes,*) enable_static=no ;;	# shared object in lib.a archive as well
-	  esac
+	if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then
+	  test "$enable_shared" = yes && enable_static=no
 	fi
         ;;
     esac
@@ -7921,11 +7417,11 @@ if test yes != "$_lt_disable_FC"; then
 
     AC_MSG_CHECKING([whether to build static libraries])
     # Make sure either enable_shared or enable_static is yes.
-    test yes = "$enable_shared" || enable_static=yes
+    test "$enable_shared" = yes || enable_static=yes
     AC_MSG_RESULT([$enable_static])
 
-    _LT_TAGVAR(GCC, $1)=$ac_cv_fc_compiler_gnu
-    _LT_TAGVAR(LD, $1)=$LD
+    _LT_TAGVAR(GCC, $1)="$ac_cv_fc_compiler_gnu"
+    _LT_TAGVAR(LD, $1)="$LD"
 
     ## CAVEAT EMPTOR:
     ## There is no encapsulation within the following macros, do not change
@@ -7945,7 +7441,7 @@ if test yes != "$_lt_disable_FC"; then
   GCC=$lt_save_GCC
   CC=$lt_save_CC
   CFLAGS=$lt_save_CFLAGS
-fi # test yes != "$_lt_disable_FC"
+fi # test "$_lt_disable_FC" != yes
 
 AC_LANG_POP
 ])# _LT_LANG_FC_CONFIG
@@ -7955,7 +7451,7 @@ AC_LANG_POP
 # --------------------------
 # Ensure that the configuration variables for the GNU Java Compiler compiler
 # are suitably defined.  These variables are subsequently used by _LT_CONFIG
-# to write the compiler configuration to 'libtool'.
+# to write the compiler configuration to `libtool'.
 m4_defun([_LT_LANG_GCJ_CONFIG],
 [AC_REQUIRE([LT_PROG_GCJ])dnl
 AC_LANG_SAVE
@@ -7989,7 +7485,7 @@ CC=${GCJ-"gcj"}
 CFLAGS=$GCJFLAGS
 compiler=$CC
 _LT_TAGVAR(compiler, $1)=$CC
-_LT_TAGVAR(LD, $1)=$LD
+_LT_TAGVAR(LD, $1)="$LD"
 _LT_CC_BASENAME([$compiler])
 
 # GCJ did not exist at the time GCC didn't implicitly link libc in.
@@ -8022,7 +7518,7 @@ CFLAGS=$lt_save_CFLAGS
 # --------------------------
 # Ensure that the configuration variables for the GNU Go compiler
 # are suitably defined.  These variables are subsequently used by _LT_CONFIG
-# to write the compiler configuration to 'libtool'.
+# to write the compiler configuration to `libtool'.
 m4_defun([_LT_LANG_GO_CONFIG],
 [AC_REQUIRE([LT_PROG_GO])dnl
 AC_LANG_SAVE
@@ -8056,7 +7552,7 @@ CC=${GOC-"gccgo"}
 CFLAGS=$GOFLAGS
 compiler=$CC
 _LT_TAGVAR(compiler, $1)=$CC
-_LT_TAGVAR(LD, $1)=$LD
+_LT_TAGVAR(LD, $1)="$LD"
 _LT_CC_BASENAME([$compiler])
 
 # Go did not exist at the time GCC didn't implicitly link libc in.
@@ -8089,7 +7585,7 @@ CFLAGS=$lt_save_CFLAGS
 # -------------------------
 # Ensure that the configuration variables for the Windows resource compiler
 # are suitably defined.  These variables are subsequently used by _LT_CONFIG
-# to write the compiler configuration to 'libtool'.
+# to write the compiler configuration to `libtool'.
 m4_defun([_LT_LANG_RC_CONFIG],
 [AC_REQUIRE([LT_PROG_RC])dnl
 AC_LANG_SAVE
@@ -8105,7 +7601,7 @@ _LT_TAGVAR(objext, $1)=$objext
 lt_simple_compile_test_code='sample MENU { MENUITEM "&Soup", 100, CHECKED }'
 
 # Code to be used in simple link tests
-lt_simple_link_test_code=$lt_simple_compile_test_code
+lt_simple_link_test_code="$lt_simple_compile_test_code"
 
 # ltmain only uses $CC for tagged configurations so make sure $CC is set.
 _LT_TAG_COMPILER
@@ -8115,7 +7611,7 @@ _LT_COMPILER_BOILERPLATE
 _LT_LINKER_BOILERPLATE
 
 # Allow CC to be a program name with arguments.
-lt_save_CC=$CC
+lt_save_CC="$CC"
 lt_save_CFLAGS=$CFLAGS
 lt_save_GCC=$GCC
 GCC=
@@ -8144,7 +7640,7 @@ AC_DEFUN([LT_PROG_GCJ],
 [m4_ifdef([AC_PROG_GCJ], [AC_PROG_GCJ],
   [m4_ifdef([A][M_PROG_GCJ], [A][M_PROG_GCJ],
     [AC_CHECK_TOOL(GCJ, gcj,)
-      test set = "${GCJFLAGS+set}" || GCJFLAGS="-g -O2"
+      test "x${GCJFLAGS+set}" = xset || GCJFLAGS="-g -O2"
       AC_SUBST(GCJFLAGS)])])[]dnl
 ])
 
@@ -8253,7 +7749,7 @@ lt_ac_count=0
 # Add /usr/xpg4/bin/sed as it is typically found on Solaris
 # along with /bin/sed that truncates output.
 for lt_ac_sed in $lt_ac_sed_list /usr/xpg4/bin/sed; do
-  test ! -f "$lt_ac_sed" && continue
+  test ! -f $lt_ac_sed && continue
   cat /dev/null > conftest.in
   lt_ac_count=0
   echo $ECHO_N "0123456789$ECHO_C" >conftest.in
@@ -8270,9 +7766,9 @@ for lt_ac_sed in $lt_ac_sed_list /usr/xpg4/bin/sed; do
     $lt_ac_sed -e 's/a$//' < conftest.nl >conftest.out || break
     cmp -s conftest.out conftest.nl || break
     # 10000 chars as input seems more than enough
-    test 10 -lt "$lt_ac_count" && break
+    test $lt_ac_count -gt 10 && break
     lt_ac_count=`expr $lt_ac_count + 1`
-    if test "$lt_ac_count" -gt "$lt_ac_max"; then
+    if test $lt_ac_count -gt $lt_ac_max; then
       lt_ac_max=$lt_ac_count
       lt_cv_path_SED=$lt_ac_sed
     fi
@@ -8296,7 +7792,27 @@ dnl AC_DEFUN([LT_AC_PROG_SED], [])
 # Find out whether the shell is Bourne or XSI compatible,
 # or has some other useful features.
 m4_defun([_LT_CHECK_SHELL_FEATURES],
-[if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then
+[AC_MSG_CHECKING([whether the shell understands some XSI constructs])
+# Try some XSI features
+xsi_shell=no
+( _lt_dummy="a/b/c"
+  test "${_lt_dummy##*/},${_lt_dummy%/*},${_lt_dummy#??}"${_lt_dummy%"$_lt_dummy"}, \
+      = c,a/b,b/c, \
+    && eval 'test $(( 1 + 1 )) -eq 2 \
+    && test "${#_lt_dummy}" -eq 5' ) >/dev/null 2>&1 \
+  && xsi_shell=yes
+AC_MSG_RESULT([$xsi_shell])
+_LT_CONFIG_LIBTOOL_INIT([xsi_shell='$xsi_shell'])
+
+AC_MSG_CHECKING([whether the shell understands "+="])
+lt_shell_append=no
+( foo=bar; set foo baz; eval "$[1]+=\$[2]" && test "$foo" = barbaz ) \
+    >/dev/null 2>&1 \
+  && lt_shell_append=yes
+AC_MSG_RESULT([$lt_shell_append])
+_LT_CONFIG_LIBTOOL_INIT([lt_shell_append='$lt_shell_append'])
+
+if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then
   lt_unset=unset
 else
   lt_unset=false
@@ -8320,9 +7836,102 @@ _LT_DECL([NL2SP], [lt_NL2SP], [1], [turn newlines into spaces])dnl
 ])# _LT_CHECK_SHELL_FEATURES
 
 
+# _LT_PROG_FUNCTION_REPLACE (FUNCNAME, REPLACEMENT-BODY)
+# ------------------------------------------------------
+# In `$cfgfile', look for function FUNCNAME delimited by `^FUNCNAME ()$' and
+# '^} FUNCNAME ', and replace its body with REPLACEMENT-BODY.
+m4_defun([_LT_PROG_FUNCTION_REPLACE],
+[dnl {
+sed -e '/^$1 ()$/,/^} # $1 /c\
+$1 ()\
+{\
+m4_bpatsubsts([$2], [$], [\\], [^\([	 ]\)], [\\\1])
+} # Extended-shell $1 implementation' "$cfgfile" > $cfgfile.tmp \
+  && mv -f "$cfgfile.tmp" "$cfgfile" \
+    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+])
+
+
+# _LT_PROG_REPLACE_SHELLFNS
+# -------------------------
+# Replace existing portable implementations of several shell functions with
+# equivalent extended shell implementations where those features are available..
+m4_defun([_LT_PROG_REPLACE_SHELLFNS],
+[if test x"$xsi_shell" = xyes; then
+  _LT_PROG_FUNCTION_REPLACE([func_dirname], [dnl
+    case ${1} in
+      */*) func_dirname_result="${1%/*}${2}" ;;
+      *  ) func_dirname_result="${3}" ;;
+    esac])
+
+  _LT_PROG_FUNCTION_REPLACE([func_basename], [dnl
+    func_basename_result="${1##*/}"])
+
+  _LT_PROG_FUNCTION_REPLACE([func_dirname_and_basename], [dnl
+    case ${1} in
+      */*) func_dirname_result="${1%/*}${2}" ;;
+      *  ) func_dirname_result="${3}" ;;
+    esac
+    func_basename_result="${1##*/}"])
+
+  _LT_PROG_FUNCTION_REPLACE([func_stripname], [dnl
+    # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are
+    # positional parameters, so assign one to ordinary parameter first.
+    func_stripname_result=${3}
+    func_stripname_result=${func_stripname_result#"${1}"}
+    func_stripname_result=${func_stripname_result%"${2}"}])
+
+  _LT_PROG_FUNCTION_REPLACE([func_split_long_opt], [dnl
+    func_split_long_opt_name=${1%%=*}
+    func_split_long_opt_arg=${1#*=}])
+
+  _LT_PROG_FUNCTION_REPLACE([func_split_short_opt], [dnl
+    func_split_short_opt_arg=${1#??}
+    func_split_short_opt_name=${1%"$func_split_short_opt_arg"}])
+
+  _LT_PROG_FUNCTION_REPLACE([func_lo2o], [dnl
+    case ${1} in
+      *.lo) func_lo2o_result=${1%.lo}.${objext} ;;
+      *)    func_lo2o_result=${1} ;;
+    esac])
+
+  _LT_PROG_FUNCTION_REPLACE([func_xform], [    func_xform_result=${1%.*}.lo])
+
+  _LT_PROG_FUNCTION_REPLACE([func_arith], [    func_arith_result=$(( $[*] ))])
+
+  _LT_PROG_FUNCTION_REPLACE([func_len], [    func_len_result=${#1}])
+fi
+
+if test x"$lt_shell_append" = xyes; then
+  _LT_PROG_FUNCTION_REPLACE([func_append], [    eval "${1}+=\\${2}"])
+
+  _LT_PROG_FUNCTION_REPLACE([func_append_quoted], [dnl
+    func_quote_for_eval "${2}"
+dnl m4 expansion turns \\\\ into \\, and then the shell eval turns that into \
+    eval "${1}+=\\\\ \\$func_quote_for_eval_result"])
+
+  # Save a `func_append' function call where possible by direct use of '+='
+  sed -e 's%func_append \([[a-zA-Z_]]\{1,\}\) "%\1+="%g' $cfgfile > $cfgfile.tmp \
+    && mv -f "$cfgfile.tmp" "$cfgfile" \
+      || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+  test 0 -eq $? || _lt_function_replace_fail=:
+else
+  # Save a `func_append' function call even when '+=' is not available
+  sed -e 's%func_append \([[a-zA-Z_]]\{1,\}\) "%\1="$\1%g' $cfgfile > $cfgfile.tmp \
+    && mv -f "$cfgfile.tmp" "$cfgfile" \
+      || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+  test 0 -eq $? || _lt_function_replace_fail=:
+fi
+
+if test x"$_lt_function_replace_fail" = x":"; then
+  AC_MSG_WARN([Unable to substitute extended shell functions in $ofile])
+fi
+])
+
 # _LT_PATH_CONVERSION_FUNCTIONS
 # -----------------------------
-# Determine what file name conversion functions should be used by
+# Determine which file name conversion functions should be used by
 # func_to_host_file (and, implicitly, by func_to_host_path).  These are needed
 # for certain cross-compile configurations and native mingw.
 m4_defun([_LT_PATH_CONVERSION_FUNCTIONS],
@@ -8389,15 +7998,15 @@ _LT_DECL([to_tool_file_cmd], [lt_cv_to_tool_file_cmd],
 
 # Helper functions for option handling.                    -*- Autoconf -*-
 #
-#   Copyright (C) 2004-2005, 2007-2009, 2011-2015 Free Software
-#   Foundation, Inc.
+#   Copyright (C) 2004, 2005, 2007, 2008, 2009 Free Software Foundation,
+#   Inc.
 #   Written by Gary V. Vaughan, 2004
 #
 # This file is free software; the Free Software Foundation gives
 # unlimited permission to copy and/or distribute it, with or without
 # modifications, as long as this notice is preserved.
 
-# serial 8 ltoptions.m4
+# serial 7 ltoptions.m4
 
 # This is to help aclocal find these macros, as it can't see m4_define.
 AC_DEFUN([LTOPTIONS_VERSION], [m4_if([1])])
@@ -8418,7 +8027,7 @@ m4_define([_LT_SET_OPTION],
 [m4_define(_LT_MANGLE_OPTION([$1], [$2]))dnl
 m4_ifdef(_LT_MANGLE_DEFUN([$1], [$2]),
         _LT_MANGLE_DEFUN([$1], [$2]),
-    [m4_warning([Unknown $1 option '$2'])])[]dnl
+    [m4_warning([Unknown $1 option `$2'])])[]dnl
 ])
 
 
@@ -8464,15 +8073,13 @@ m4_if([$1],[LT_INIT],[
   dnl
   dnl If no reference was made to various pairs of opposing options, then
   dnl we run the default mode handler for the pair.  For example, if neither
-  dnl 'shared' nor 'disable-shared' was passed, we enable building of shared
+  dnl `shared' nor `disable-shared' was passed, we enable building of shared
   dnl archives by default:
   _LT_UNLESS_OPTIONS([LT_INIT], [shared disable-shared], [_LT_ENABLE_SHARED])
   _LT_UNLESS_OPTIONS([LT_INIT], [static disable-static], [_LT_ENABLE_STATIC])
   _LT_UNLESS_OPTIONS([LT_INIT], [pic-only no-pic], [_LT_WITH_PIC])
   _LT_UNLESS_OPTIONS([LT_INIT], [fast-install disable-fast-install],
-		   [_LT_ENABLE_FAST_INSTALL])
-  _LT_UNLESS_OPTIONS([LT_INIT], [aix-soname=aix aix-soname=both aix-soname=svr4],
-		   [_LT_WITH_AIX_SONAME([aix])])
+  		   [_LT_ENABLE_FAST_INSTALL])
   ])
 ])# _LT_SET_OPTIONS
 
@@ -8500,7 +8107,7 @@ AU_DEFUN([AC_LIBTOOL_DLOPEN],
 [_LT_SET_OPTION([LT_INIT], [dlopen])
 AC_DIAGNOSE([obsolete],
 [$0: Remove this warning and the call to _LT_SET_OPTION when you
-put the 'dlopen' option into LT_INIT's first parameter.])
+put the `dlopen' option into LT_INIT's first parameter.])
 ])
 
 dnl aclocal-1.4 backwards compatibility:
@@ -8536,7 +8143,7 @@ AU_DEFUN([AC_LIBTOOL_WIN32_DLL],
 _LT_SET_OPTION([LT_INIT], [win32-dll])
 AC_DIAGNOSE([obsolete],
 [$0: Remove this warning and the call to _LT_SET_OPTION when you
-put the 'win32-dll' option into LT_INIT's first parameter.])
+put the `win32-dll' option into LT_INIT's first parameter.])
 ])
 
 dnl aclocal-1.4 backwards compatibility:
@@ -8545,9 +8152,9 @@ dnl AC_DEFUN([AC_LIBTOOL_WIN32_DLL], [])
 
 # _LT_ENABLE_SHARED([DEFAULT])
 # ----------------------------
-# implement the --enable-shared flag, and supports the 'shared' and
-# 'disable-shared' LT_INIT options.
-# DEFAULT is either 'yes' or 'no'.  If omitted, it defaults to 'yes'.
+# implement the --enable-shared flag, and supports the `shared' and
+# `disable-shared' LT_INIT options.
+# DEFAULT is either `yes' or `no'.  If omitted, it defaults to `yes'.
 m4_define([_LT_ENABLE_SHARED],
 [m4_define([_LT_ENABLE_SHARED_DEFAULT], [m4_if($1, no, no, yes)])dnl
 AC_ARG_ENABLE([shared],
@@ -8560,14 +8167,14 @@ AC_ARG_ENABLE([shared],
     *)
       enable_shared=no
       # Look at the argument we got.  We use all the common list separators.
-      lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR,
+      lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
       for pkg in $enableval; do
-	IFS=$lt_save_ifs
+	IFS="$lt_save_ifs"
 	if test "X$pkg" = "X$p"; then
 	  enable_shared=yes
 	fi
       done
-      IFS=$lt_save_ifs
+      IFS="$lt_save_ifs"
       ;;
     esac],
     [enable_shared=]_LT_ENABLE_SHARED_DEFAULT)
@@ -8599,9 +8206,9 @@ dnl AC_DEFUN([AM_DISABLE_SHARED], [])
 
 # _LT_ENABLE_STATIC([DEFAULT])
 # ----------------------------
-# implement the --enable-static flag, and support the 'static' and
-# 'disable-static' LT_INIT options.
-# DEFAULT is either 'yes' or 'no'.  If omitted, it defaults to 'yes'.
+# implement the --enable-static flag, and support the `static' and
+# `disable-static' LT_INIT options.
+# DEFAULT is either `yes' or `no'.  If omitted, it defaults to `yes'.
 m4_define([_LT_ENABLE_STATIC],
 [m4_define([_LT_ENABLE_STATIC_DEFAULT], [m4_if($1, no, no, yes)])dnl
 AC_ARG_ENABLE([static],
@@ -8614,14 +8221,14 @@ AC_ARG_ENABLE([static],
     *)
      enable_static=no
       # Look at the argument we got.  We use all the common list separators.
-      lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR,
+      lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
       for pkg in $enableval; do
-	IFS=$lt_save_ifs
+	IFS="$lt_save_ifs"
 	if test "X$pkg" = "X$p"; then
 	  enable_static=yes
 	fi
       done
-      IFS=$lt_save_ifs
+      IFS="$lt_save_ifs"
       ;;
     esac],
     [enable_static=]_LT_ENABLE_STATIC_DEFAULT)
@@ -8653,9 +8260,9 @@ dnl AC_DEFUN([AM_DISABLE_STATIC], [])
 
 # _LT_ENABLE_FAST_INSTALL([DEFAULT])
 # ----------------------------------
-# implement the --enable-fast-install flag, and support the 'fast-install'
-# and 'disable-fast-install' LT_INIT options.
-# DEFAULT is either 'yes' or 'no'.  If omitted, it defaults to 'yes'.
+# implement the --enable-fast-install flag, and support the `fast-install'
+# and `disable-fast-install' LT_INIT options.
+# DEFAULT is either `yes' or `no'.  If omitted, it defaults to `yes'.
 m4_define([_LT_ENABLE_FAST_INSTALL],
 [m4_define([_LT_ENABLE_FAST_INSTALL_DEFAULT], [m4_if($1, no, no, yes)])dnl
 AC_ARG_ENABLE([fast-install],
@@ -8668,14 +8275,14 @@ AC_ARG_ENABLE([fast-install],
     *)
       enable_fast_install=no
       # Look at the argument we got.  We use all the common list separators.
-      lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR,
+      lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
       for pkg in $enableval; do
-	IFS=$lt_save_ifs
+	IFS="$lt_save_ifs"
 	if test "X$pkg" = "X$p"; then
 	  enable_fast_install=yes
 	fi
       done
-      IFS=$lt_save_ifs
+      IFS="$lt_save_ifs"
       ;;
     esac],
     [enable_fast_install=]_LT_ENABLE_FAST_INSTALL_DEFAULT)
@@ -8692,14 +8299,14 @@ AU_DEFUN([AC_ENABLE_FAST_INSTALL],
 [_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[fast-install])
 AC_DIAGNOSE([obsolete],
 [$0: Remove this warning and the call to _LT_SET_OPTION when you put
-the 'fast-install' option into LT_INIT's first parameter.])
+the `fast-install' option into LT_INIT's first parameter.])
 ])
 
 AU_DEFUN([AC_DISABLE_FAST_INSTALL],
 [_LT_SET_OPTION([LT_INIT], [disable-fast-install])
 AC_DIAGNOSE([obsolete],
 [$0: Remove this warning and the call to _LT_SET_OPTION when you put
-the 'disable-fast-install' option into LT_INIT's first parameter.])
+the `disable-fast-install' option into LT_INIT's first parameter.])
 ])
 
 dnl aclocal-1.4 backwards compatibility:
@@ -8707,64 +8314,11 @@ dnl AC_DEFUN([AC_ENABLE_FAST_INSTALL], [])
 dnl AC_DEFUN([AM_DISABLE_FAST_INSTALL], [])
 
 
-# _LT_WITH_AIX_SONAME([DEFAULT])
-# ----------------------------------
-# implement the --with-aix-soname flag, and support the `aix-soname=aix'
-# and `aix-soname=both' and `aix-soname=svr4' LT_INIT options. DEFAULT
-# is either `aix', `both' or `svr4'.  If omitted, it defaults to `aix'.
-m4_define([_LT_WITH_AIX_SONAME],
-[m4_define([_LT_WITH_AIX_SONAME_DEFAULT], [m4_if($1, svr4, svr4, m4_if($1, both, both, aix))])dnl
-shared_archive_member_spec=
-case $host,$enable_shared in
-power*-*-aix[[5-9]]*,yes)
-  AC_MSG_CHECKING([which variant of shared library versioning to provide])
-  AC_ARG_WITH([aix-soname],
-    [AS_HELP_STRING([--with-aix-soname=aix|svr4|both],
-      [shared library versioning (aka "SONAME") variant to provide on AIX, @<:@default=]_LT_WITH_AIX_SONAME_DEFAULT[@:>@.])],
-    [case $withval in
-    aix|svr4|both)
-      ;;
-    *)
-      AC_MSG_ERROR([Unknown argument to --with-aix-soname])
-      ;;
-    esac
-    lt_cv_with_aix_soname=$with_aix_soname],
-    [AC_CACHE_VAL([lt_cv_with_aix_soname],
-      [lt_cv_with_aix_soname=]_LT_WITH_AIX_SONAME_DEFAULT)
-    with_aix_soname=$lt_cv_with_aix_soname])
-  AC_MSG_RESULT([$with_aix_soname])
-  if test aix != "$with_aix_soname"; then
-    # For the AIX way of multilib, we name the shared archive member
-    # based on the bitwidth used, traditionally 'shr.o' or 'shr_64.o',
-    # and 'shr.imp' or 'shr_64.imp', respectively, for the Import File.
-    # Even when GNU compilers ignore OBJECT_MODE but need '-maix64' flag,
-    # the AIX toolchain works better with OBJECT_MODE set (default 32).
-    if test 64 = "${OBJECT_MODE-32}"; then
-      shared_archive_member_spec=shr_64
-    else
-      shared_archive_member_spec=shr
-    fi
-  fi
-  ;;
-*)
-  with_aix_soname=aix
-  ;;
-esac
-
-_LT_DECL([], [shared_archive_member_spec], [0],
-    [Shared archive member basename, for filename based shared library versioning on AIX])dnl
-])# _LT_WITH_AIX_SONAME
-
-LT_OPTION_DEFINE([LT_INIT], [aix-soname=aix], [_LT_WITH_AIX_SONAME([aix])])
-LT_OPTION_DEFINE([LT_INIT], [aix-soname=both], [_LT_WITH_AIX_SONAME([both])])
-LT_OPTION_DEFINE([LT_INIT], [aix-soname=svr4], [_LT_WITH_AIX_SONAME([svr4])])
-
-
 # _LT_WITH_PIC([MODE])
 # --------------------
-# implement the --with-pic flag, and support the 'pic-only' and 'no-pic'
+# implement the --with-pic flag, and support the `pic-only' and `no-pic'
 # LT_INIT options.
-# MODE is either 'yes' or 'no'.  If omitted, it defaults to 'both'.
+# MODE is either `yes' or `no'.  If omitted, it defaults to `both'.
 m4_define([_LT_WITH_PIC],
 [AC_ARG_WITH([pic],
     [AS_HELP_STRING([--with-pic@<:@=PKGS@:>@],
@@ -8775,17 +8329,19 @@ m4_define([_LT_WITH_PIC],
     *)
       pic_mode=default
       # Look at the argument we got.  We use all the common list separators.
-      lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR,
+      lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
       for lt_pkg in $withval; do
-	IFS=$lt_save_ifs
+	IFS="$lt_save_ifs"
 	if test "X$lt_pkg" = "X$lt_p"; then
 	  pic_mode=yes
 	fi
       done
-      IFS=$lt_save_ifs
+      IFS="$lt_save_ifs"
       ;;
     esac],
-    [pic_mode=m4_default([$1], [default])])
+    [pic_mode=default])
+
+test -z "$pic_mode" && pic_mode=m4_default([$1], [default])
 
 _LT_DECL([], [pic_mode], [0], [What type of objects to build])dnl
 ])# _LT_WITH_PIC
@@ -8798,7 +8354,7 @@ AU_DEFUN([AC_LIBTOOL_PICMODE],
 [_LT_SET_OPTION([LT_INIT], [pic-only])
 AC_DIAGNOSE([obsolete],
 [$0: Remove this warning and the call to _LT_SET_OPTION when you
-put the 'pic-only' option into LT_INIT's first parameter.])
+put the `pic-only' option into LT_INIT's first parameter.])
 ])
 
 dnl aclocal-1.4 backwards compatibility:
@@ -8821,8 +8377,7 @@ LT_OPTION_DEFINE([LTDL_INIT], [convenience],
 
 # ltsugar.m4 -- libtool m4 base layer.                         -*-Autoconf-*-
 #
-# Copyright (C) 2004-2005, 2007-2008, 2011-2015 Free Software
-# Foundation, Inc.
+# Copyright (C) 2004, 2005, 2007, 2008 Free Software Foundation, Inc.
 # Written by Gary V. Vaughan, 2004
 #
 # This file is free software; the Free Software Foundation gives
@@ -8855,7 +8410,7 @@ m4_define([_lt_join],
 # ------------
 # Manipulate m4 lists.
 # These macros are necessary as long as will still need to support
-# Autoconf-2.59, which quotes differently.
+# Autoconf-2.59 which quotes differently.
 m4_define([lt_car], [[$1]])
 m4_define([lt_cdr],
 [m4_if([$#], 0, [m4_fatal([$0: cannot be called without arguments])],
@@ -8866,7 +8421,7 @@ m4_define([lt_unquote], $1)
 
 # lt_append(MACRO-NAME, STRING, [SEPARATOR])
 # ------------------------------------------
-# Redefine MACRO-NAME to hold its former content plus 'SEPARATOR''STRING'.
+# Redefine MACRO-NAME to hold its former content plus `SEPARATOR'`STRING'.
 # Note that neither SEPARATOR nor STRING are expanded; they are appended
 # to MACRO-NAME as is (leaving the expansion for when MACRO-NAME is invoked).
 # No SEPARATOR is output if MACRO-NAME was previously undefined (different
@@ -8946,7 +8501,7 @@ m4_define([lt_dict_filter],
 
 # ltversion.m4 -- version numbers			-*- Autoconf -*-
 #
-#   Copyright (C) 2004, 2011-2015 Free Software Foundation, Inc.
+#   Copyright (C) 2004 Free Software Foundation, Inc.
 #   Written by Scott James Remnant, 2004
 #
 # This file is free software; the Free Software Foundation gives
@@ -8955,23 +8510,22 @@ m4_define([lt_dict_filter],
 
 # @configure_input@
 
-# serial 4179 ltversion.m4
+# serial 3337 ltversion.m4
 # This file is part of GNU Libtool
 
-m4_define([LT_PACKAGE_VERSION], [2.4.6])
-m4_define([LT_PACKAGE_REVISION], [2.4.6])
+m4_define([LT_PACKAGE_VERSION], [2.4.2])
+m4_define([LT_PACKAGE_REVISION], [1.3337])
 
 AC_DEFUN([LTVERSION_VERSION],
-[macro_version='2.4.6'
-macro_revision='2.4.6'
+[macro_version='2.4.2'
+macro_revision='1.3337'
 _LT_DECL(, macro_version, 0, [Which release of libtool.m4 was used?])
 _LT_DECL(, macro_revision, 0)
 ])
 
 # lt~obsolete.m4 -- aclocal satisfying obsolete definitions.    -*-Autoconf-*-
 #
-#   Copyright (C) 2004-2005, 2007, 2009, 2011-2015 Free Software
-#   Foundation, Inc.
+#   Copyright (C) 2004, 2005, 2007, 2009 Free Software Foundation, Inc.
 #   Written by Scott James Remnant, 2004.
 #
 # This file is free software; the Free Software Foundation gives
@@ -8982,7 +8536,7 @@ _LT_DECL(, macro_revision, 0)
 
 # These exist entirely to fool aclocal when bootstrapping libtool.
 #
-# In the past libtool.m4 has provided macros via AC_DEFUN (or AU_DEFUN),
+# In the past libtool.m4 has provided macros via AC_DEFUN (or AU_DEFUN)
 # which have later been changed to m4_define as they aren't part of the
 # exported API, or moved to Autoconf or Automake where they belong.
 #
@@ -8996,7 +8550,7 @@ _LT_DECL(, macro_revision, 0)
 # included after everything else.  This provides aclocal with the
 # AC_DEFUNs it wants, but when m4 processes it, it doesn't do anything
 # because those macros already exist, or will be overwritten later.
-# We use AC_DEFUN over AU_DEFUN for compatibility with aclocal-1.6.
+# We use AC_DEFUN over AU_DEFUN for compatibility with aclocal-1.6. 
 #
 # Anytime we withdraw an AC_DEFUN or AU_DEFUN, remember to add it here.
 # Yes, that means every name once taken will need to remain here until
@@ -9068,7 +8622,7 @@ m4_ifndef([_LT_PROG_F77],		[AC_DEFUN([_LT_PROG_F77])])
 m4_ifndef([_LT_PROG_FC],		[AC_DEFUN([_LT_PROG_FC])])
 m4_ifndef([_LT_PROG_CXX],		[AC_DEFUN([_LT_PROG_CXX])])
 
-# Copyright (C) 2002-2014 Free Software Foundation, Inc.
+# Copyright (C) 2002-2013 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -9080,10 +8634,10 @@ m4_ifndef([_LT_PROG_CXX],		[AC_DEFUN([_LT_PROG_CXX])])
 # generated from the m4 files accompanying Automake X.Y.
 # (This private macro should not be called outside this file.)
 AC_DEFUN([AM_AUTOMAKE_VERSION],
-[am__api_version='1.15'
+[am__api_version='1.14'
 dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to
 dnl require some minimum version.  Point them to the right macro.
-m4_if([$1], [1.15], [],
+m4_if([$1], [1.14.1], [],
       [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl
 ])
 
@@ -9099,14 +8653,14 @@ m4_define([_AM_AUTOCONF_VERSION], [])
 # Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced.
 # This function is AC_REQUIREd by AM_INIT_AUTOMAKE.
 AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION],
-[AM_AUTOMAKE_VERSION([1.15])dnl
+[AM_AUTOMAKE_VERSION([1.14.1])dnl
 m4_ifndef([AC_AUTOCONF_VERSION],
   [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl
 _AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))])
 
 # AM_AUX_DIR_EXPAND                                         -*- Autoconf -*-
 
-# Copyright (C) 2001-2014 Free Software Foundation, Inc.
+# Copyright (C) 2001-2013 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -9151,14 +8705,15 @@ _AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))])
 # configured tree to be moved without reconfiguration.
 
 AC_DEFUN([AM_AUX_DIR_EXPAND],
-[AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT])dnl
-# Expand $ac_aux_dir to an absolute path.
-am_aux_dir=`cd "$ac_aux_dir" && pwd`
+[dnl Rely on autoconf to set up CDPATH properly.
+AC_PREREQ([2.50])dnl
+# expand $ac_aux_dir to an absolute path
+am_aux_dir=`cd $ac_aux_dir && pwd`
 ])
 
 # AM_CONDITIONAL                                            -*- Autoconf -*-
 
-# Copyright (C) 1997-2014 Free Software Foundation, Inc.
+# Copyright (C) 1997-2013 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -9189,7 +8744,7 @@ AC_CONFIG_COMMANDS_PRE(
 Usually this means the macro was only invoked conditionally.]])
 fi])])
 
-# Copyright (C) 1999-2014 Free Software Foundation, Inc.
+# Copyright (C) 1999-2013 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -9380,7 +8935,7 @@ _AM_SUBST_NOTMAKE([am__nodep])dnl
 
 # Generate code to set up dependency tracking.              -*- Autoconf -*-
 
-# Copyright (C) 1999-2014 Free Software Foundation, Inc.
+# Copyright (C) 1999-2013 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -9456,7 +9011,7 @@ AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS],
 
 # Do all the work for Automake.                             -*- Autoconf -*-
 
-# Copyright (C) 1996-2014 Free Software Foundation, Inc.
+# Copyright (C) 1996-2013 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -9546,8 +9101,8 @@ AC_REQUIRE([AC_PROG_MKDIR_P])dnl
 # <http://lists.gnu.org/archive/html/automake/2012-07/msg00001.html>
 # <http://lists.gnu.org/archive/html/automake/2012-07/msg00014.html>
 AC_SUBST([mkdir_p], ['$(MKDIR_P)'])
-# We need awk for the "check" target (and possibly the TAP driver).  The
-# system "awk" is bad on some platforms.
+# We need awk for the "check" target.  The system "awk" is bad on
+# some platforms.
 AC_REQUIRE([AC_PROG_AWK])dnl
 AC_REQUIRE([AC_PROG_MAKE_SET])dnl
 AC_REQUIRE([AM_SET_LEADING_DOT])dnl
@@ -9620,11 +9175,7 @@ to "yes", and re-run configure.
 END
     AC_MSG_ERROR([Your 'rm' program is bad, sorry.])
   fi
-fi
-dnl The trailing newline in this macro's definition is deliberate, for
-dnl backward compatibility and to allow trailing 'dnl'-style comments
-dnl after the AM_INIT_AUTOMAKE invocation. See automake bug#16841.
-])
+fi])
 
 dnl Hook into '_AC_COMPILER_EXEEXT' early to learn its expansion.  Do not
 dnl add the conditional right here, as _AC_COMPILER_EXEEXT may be further
@@ -9653,7 +9204,7 @@ for _am_header in $config_headers :; do
 done
 echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count])
 
-# Copyright (C) 2001-2014 Free Software Foundation, Inc.
+# Copyright (C) 2001-2013 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -9664,7 +9215,7 @@ echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_co
 # Define $install_sh.
 AC_DEFUN([AM_PROG_INSTALL_SH],
 [AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
-if test x"${install_sh+set}" != xset; then
+if test x"${install_sh}" != xset; then
   case $am_aux_dir in
   *\ * | *\	*)
     install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;;
@@ -9674,7 +9225,7 @@ if test x"${install_sh+set}" != xset; then
 fi
 AC_SUBST([install_sh])])
 
-# Copyright (C) 2003-2014 Free Software Foundation, Inc.
+# Copyright (C) 2003-2013 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -9695,7 +9246,7 @@ AC_SUBST([am__leading_dot])])
 
 # Check to see how 'make' treats includes.	            -*- Autoconf -*-
 
-# Copyright (C) 2001-2014 Free Software Foundation, Inc.
+# Copyright (C) 2001-2013 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -9745,7 +9296,7 @@ rm -f confinc confmf
 
 # Fake the existence of programs that GNU maintainers use.  -*- Autoconf -*-
 
-# Copyright (C) 1997-2014 Free Software Foundation, Inc.
+# Copyright (C) 1997-2013 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -9784,7 +9335,7 @@ fi
 
 # Helper functions for option handling.                     -*- Autoconf -*-
 
-# Copyright (C) 2001-2014 Free Software Foundation, Inc.
+# Copyright (C) 2001-2013 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -9813,7 +9364,7 @@ AC_DEFUN([_AM_SET_OPTIONS],
 AC_DEFUN([_AM_IF_OPTION],
 [m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])])
 
-# Copyright (C) 1999-2014 Free Software Foundation, Inc.
+# Copyright (C) 1999-2013 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -9860,7 +9411,7 @@ AC_LANG_POP([C])])
 # For backward compatibility.
 AC_DEFUN_ONCE([AM_PROG_CC_C_O], [AC_REQUIRE([AC_PROG_CC])])
 
-# Copyright (C) 1999-2014 Free Software Foundation, Inc.
+# Copyright (C) 1999-2013 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -10095,7 +9646,7 @@ for i in list(range(0, 4)): minverhex = (minverhex << 8) + minver[[i]]
 sys.exit(sys.hexversion < minverhex)"
   AS_IF([AM_RUN_LOG([$1 -c "$prog"])], [$3], [$4])])
 
-# Copyright (C) 2001-2014 Free Software Foundation, Inc.
+# Copyright (C) 2001-2013 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -10114,7 +9665,7 @@ AC_DEFUN([AM_RUN_LOG],
 
 # Check to make sure that the build environment is sane.    -*- Autoconf -*-
 
-# Copyright (C) 1996-2014 Free Software Foundation, Inc.
+# Copyright (C) 1996-2013 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -10195,7 +9746,7 @@ AC_CONFIG_COMMANDS_PRE(
 rm -f conftest.file
 ])
 
-# Copyright (C) 2009-2014 Free Software Foundation, Inc.
+# Copyright (C) 2009-2013 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -10255,7 +9806,7 @@ AC_SUBST([AM_BACKSLASH])dnl
 _AM_SUBST_NOTMAKE([AM_BACKSLASH])dnl
 ])
 
-# Copyright (C) 2001-2014 Free Software Foundation, Inc.
+# Copyright (C) 2001-2013 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -10283,7 +9834,7 @@ fi
 INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s"
 AC_SUBST([INSTALL_STRIP_PROGRAM])])
 
-# Copyright (C) 2006-2014 Free Software Foundation, Inc.
+# Copyright (C) 2006-2013 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -10302,7 +9853,7 @@ AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)])
 
 # Check how to create a tarball.                            -*- Autoconf -*-
 
-# Copyright (C) 2004-2014 Free Software Foundation, Inc.
+# Copyright (C) 2004-2013 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
diff --git a/src/gmock/build-aux/compile b/src/gmock/build-aux/compile
index a85b723..531136b 100755
--- a/src/gmock/build-aux/compile
+++ b/src/gmock/build-aux/compile
@@ -3,7 +3,7 @@
 
 scriptversion=2012-10-14.11; # UTC
 
-# Copyright (C) 1999-2014 Free Software Foundation, Inc.
+# Copyright (C) 1999-2013 Free Software Foundation, Inc.
 # Written by Tom Tromey <tromey at cygnus.com>.
 #
 # This program is free software; you can redistribute it and/or modify
diff --git a/src/gmock/build-aux/config.guess b/src/gmock/build-aux/config.guess
index 1659250..b79252d 100755
--- a/src/gmock/build-aux/config.guess
+++ b/src/gmock/build-aux/config.guess
@@ -1,8 +1,8 @@
 #! /bin/sh
 # Attempt to guess a canonical system name.
-#   Copyright 1992-2015 Free Software Foundation, Inc.
+#   Copyright 1992-2013 Free Software Foundation, Inc.
 
-timestamp='2015-08-20'
+timestamp='2013-06-10'
 
 # This file is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License as published by
@@ -24,12 +24,12 @@ timestamp='2015-08-20'
 # program.  This Exception is an additional permission under section 7
 # of the GNU General Public License, version 3 ("GPLv3").
 #
-# Originally written by Per Bothner; maintained since 2000 by Ben Elliston.
+# Originally written by Per Bothner.
 #
 # You can get the latest version of this script from:
 # http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD
 #
-# Please send patches to <config-patches at gnu.org>.
+# Please send patches with a ChangeLog entry to config-patches at gnu.org.
 
 
 me=`echo "$0" | sed -e 's,.*/,,'`
@@ -50,7 +50,7 @@ version="\
 GNU config.guess ($timestamp)
 
 Originally written by Per Bothner.
-Copyright 1992-2015 Free Software Foundation, Inc.
+Copyright 1992-2013 Free Software Foundation, Inc.
 
 This is free software; see the source for copying conditions.  There is NO
 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
@@ -149,7 +149,7 @@ Linux|GNU|GNU/*)
 	LIBC=gnu
 	#endif
 	EOF
-	eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC' | sed 's, ,,g'`
+	eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC'`
 	;;
 esac
 
@@ -168,27 +168,20 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
 	# Note: NetBSD doesn't particularly care about the vendor
 	# portion of the name.  We always set it to "unknown".
 	sysctl="sysctl -n hw.machine_arch"
-	UNAME_MACHINE_ARCH=`(uname -p 2>/dev/null || \
-	    /sbin/$sysctl 2>/dev/null || \
-	    /usr/sbin/$sysctl 2>/dev/null || \
-	    echo unknown)`
+	UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \
+	    /usr/sbin/$sysctl 2>/dev/null || echo unknown)`
 	case "${UNAME_MACHINE_ARCH}" in
 	    armeb) machine=armeb-unknown ;;
 	    arm*) machine=arm-unknown ;;
 	    sh3el) machine=shl-unknown ;;
 	    sh3eb) machine=sh-unknown ;;
 	    sh5el) machine=sh5le-unknown ;;
-	    earmv*)
-		arch=`echo ${UNAME_MACHINE_ARCH} | sed -e 's,^e\(armv[0-9]\).*$,\1,'`
-		endian=`echo ${UNAME_MACHINE_ARCH} | sed -ne 's,^.*\(eb\)$,\1,p'`
-		machine=${arch}${endian}-unknown
-		;;
 	    *) machine=${UNAME_MACHINE_ARCH}-unknown ;;
 	esac
 	# The Operating System including object format, if it has switched
 	# to ELF recently, or will in the future.
 	case "${UNAME_MACHINE_ARCH}" in
-	    arm*|earm*|i386|m68k|ns32k|sh3*|sparc|vax)
+	    arm*|i386|m68k|ns32k|sh3*|sparc|vax)
 		eval $set_cc_for_build
 		if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \
 			| grep -q __ELF__
@@ -204,13 +197,6 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
 		os=netbsd
 		;;
 	esac
-	# Determine ABI tags.
-	case "${UNAME_MACHINE_ARCH}" in
-	    earm*)
-		expr='s/^earmv[0-9]/-eabi/;s/eb$//'
-		abi=`echo ${UNAME_MACHINE_ARCH} | sed -e "$expr"`
-		;;
-	esac
 	# The OS release
 	# Debian GNU/NetBSD machines have a different userland, and
 	# thus, need a distinct triplet. However, they do not need
@@ -221,13 +207,13 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
 		release='-gnu'
 		;;
 	    *)
-		release=`echo ${UNAME_RELEASE} | sed -e 's/[-_].*//' | cut -d. -f1,2`
+		release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
 		;;
 	esac
 	# Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM:
 	# contains redundant information, the shorter form:
 	# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used.
-	echo "${machine}-${os}${release}${abi}"
+	echo "${machine}-${os}${release}"
 	exit ;;
     *:Bitrig:*:*)
 	UNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'`
@@ -249,9 +235,6 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
     *:MirBSD:*:*)
 	echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE}
 	exit ;;
-    *:Sortix:*:*)
-	echo ${UNAME_MACHINE}-unknown-sortix
-	exit ;;
     alpha:OSF1:*:*)
 	case $UNAME_RELEASE in
 	*4.0)
@@ -596,9 +579,8 @@ EOF
 	else
 		IBM_ARCH=powerpc
 	fi
-	if [ -x /usr/bin/lslpp ] ; then
-		IBM_REV=`/usr/bin/lslpp -Lqc bos.rte.libc |
-			   awk -F: '{ print $3 }' | sed s/[0-9]*$/0/`
+	if [ -x /usr/bin/oslevel ] ; then
+		IBM_REV=`/usr/bin/oslevel`
 	else
 		IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
 	fi
@@ -844,7 +826,7 @@ EOF
     *:MINGW*:*)
 	echo ${UNAME_MACHINE}-pc-mingw32
 	exit ;;
-    *:MSYS*:*)
+    i*:MSYS*:*)
 	echo ${UNAME_MACHINE}-pc-msys
 	exit ;;
     i*:windows32*:*)
@@ -950,9 +932,6 @@ EOF
     crisv32:Linux:*:*)
 	echo ${UNAME_MACHINE}-axis-linux-${LIBC}
 	exit ;;
-    e2k:Linux:*:*)
-	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
-	exit ;;
     frv:Linux:*:*)
 	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
 	exit ;;
@@ -990,10 +969,10 @@ EOF
 	eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'`
 	test x"${CPU}" != x && { echo "${CPU}-unknown-linux-${LIBC}"; exit; }
 	;;
-    openrisc*:Linux:*:*)
-	echo or1k-unknown-linux-${LIBC}
+    or1k:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
 	exit ;;
-    or32:Linux:*:* | or1k*:Linux:*:*)
+    or32:Linux:*:*)
 	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
 	exit ;;
     padre:Linux:*:*)
@@ -1041,7 +1020,7 @@ EOF
 	echo ${UNAME_MACHINE}-dec-linux-${LIBC}
 	exit ;;
     x86_64:Linux:*:*)
-	echo ${UNAME_MACHINE}-pc-linux-${LIBC}
+	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
 	exit ;;
     xtensa*:Linux:*:*)
 	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
@@ -1281,26 +1260,16 @@ EOF
 	if test "$UNAME_PROCESSOR" = unknown ; then
 	    UNAME_PROCESSOR=powerpc
 	fi
-	if test `echo "$UNAME_RELEASE" | sed -e 's/\..*//'` -le 10 ; then
-	    if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then
-		if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \
-		    (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \
-		    grep IS_64BIT_ARCH >/dev/null
-		then
-		    case $UNAME_PROCESSOR in
-			i386) UNAME_PROCESSOR=x86_64 ;;
-			powerpc) UNAME_PROCESSOR=powerpc64 ;;
-		    esac
-		fi
+	if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then
+	    if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \
+		(CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \
+		grep IS_64BIT_ARCH >/dev/null
+	    then
+		case $UNAME_PROCESSOR in
+		    i386) UNAME_PROCESSOR=x86_64 ;;
+		    powerpc) UNAME_PROCESSOR=powerpc64 ;;
+		esac
 	    fi
-	elif test "$UNAME_PROCESSOR" = i386 ; then
-	    # Avoid executing cc on OS X 10.9, as it ships with a stub
-	    # that puts up a graphical alert prompting to install
-	    # developer tools.  Any system running Mac OS X 10.7 or
-	    # later (Darwin 11 and later) is required to have a 64-bit
-	    # processor. This is not true of the ARM version of Darwin
-	    # that Apple uses in portable devices.
-	    UNAME_PROCESSOR=x86_64
 	fi
 	echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE}
 	exit ;;
@@ -1392,6 +1361,154 @@ EOF
 	exit ;;
 esac
 
+eval $set_cc_for_build
+cat >$dummy.c <<EOF
+#ifdef _SEQUENT_
+# include <sys/types.h>
+# include <sys/utsname.h>
+#endif
+main ()
+{
+#if defined (sony)
+#if defined (MIPSEB)
+  /* BFD wants "bsd" instead of "newsos".  Perhaps BFD should be changed,
+     I don't know....  */
+  printf ("mips-sony-bsd\n"); exit (0);
+#else
+#include <sys/param.h>
+  printf ("m68k-sony-newsos%s\n",
+#ifdef NEWSOS4
+	"4"
+#else
+	""
+#endif
+	); exit (0);
+#endif
+#endif
+
+#if defined (__arm) && defined (__acorn) && defined (__unix)
+  printf ("arm-acorn-riscix\n"); exit (0);
+#endif
+
+#if defined (hp300) && !defined (hpux)
+  printf ("m68k-hp-bsd\n"); exit (0);
+#endif
+
+#if defined (NeXT)
+#if !defined (__ARCHITECTURE__)
+#define __ARCHITECTURE__ "m68k"
+#endif
+  int version;
+  version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`;
+  if (version < 4)
+    printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version);
+  else
+    printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version);
+  exit (0);
+#endif
+
+#if defined (MULTIMAX) || defined (n16)
+#if defined (UMAXV)
+  printf ("ns32k-encore-sysv\n"); exit (0);
+#else
+#if defined (CMU)
+  printf ("ns32k-encore-mach\n"); exit (0);
+#else
+  printf ("ns32k-encore-bsd\n"); exit (0);
+#endif
+#endif
+#endif
+
+#if defined (__386BSD__)
+  printf ("i386-pc-bsd\n"); exit (0);
+#endif
+
+#if defined (sequent)
+#if defined (i386)
+  printf ("i386-sequent-dynix\n"); exit (0);
+#endif
+#if defined (ns32000)
+  printf ("ns32k-sequent-dynix\n"); exit (0);
+#endif
+#endif
+
+#if defined (_SEQUENT_)
+    struct utsname un;
+
+    uname(&un);
+
+    if (strncmp(un.version, "V2", 2) == 0) {
+	printf ("i386-sequent-ptx2\n"); exit (0);
+    }
+    if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */
+	printf ("i386-sequent-ptx1\n"); exit (0);
+    }
+    printf ("i386-sequent-ptx\n"); exit (0);
+
+#endif
+
+#if defined (vax)
+# if !defined (ultrix)
+#  include <sys/param.h>
+#  if defined (BSD)
+#   if BSD == 43
+      printf ("vax-dec-bsd4.3\n"); exit (0);
+#   else
+#    if BSD == 199006
+      printf ("vax-dec-bsd4.3reno\n"); exit (0);
+#    else
+      printf ("vax-dec-bsd\n"); exit (0);
+#    endif
+#   endif
+#  else
+    printf ("vax-dec-bsd\n"); exit (0);
+#  endif
+# else
+    printf ("vax-dec-ultrix\n"); exit (0);
+# endif
+#endif
+
+#if defined (alliant) && defined (i860)
+  printf ("i860-alliant-bsd\n"); exit (0);
+#endif
+
+  exit (1);
+}
+EOF
+
+$CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && SYSTEM_NAME=`$dummy` &&
+	{ echo "$SYSTEM_NAME"; exit; }
+
+# Apollos put the system type in the environment.
+
+test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit; }
+
+# Convex versions that predate uname can use getsysinfo(1)
+
+if [ -x /usr/convex/getsysinfo ]
+then
+    case `getsysinfo -f cpu_type` in
+    c1*)
+	echo c1-convex-bsd
+	exit ;;
+    c2*)
+	if getsysinfo -f scalar_acc
+	then echo c32-convex-bsd
+	else echo c2-convex-bsd
+	fi
+	exit ;;
+    c34*)
+	echo c34-convex-bsd
+	exit ;;
+    c38*)
+	echo c38-convex-bsd
+	exit ;;
+    c4*)
+	echo c4-convex-bsd
+	exit ;;
+    esac
+fi
+
 cat >&2 <<EOF
 $0: unable to guess system type
 
diff --git a/src/gmock/build-aux/config.h.in b/src/gmock/build-aux/config.h.in
index 6ea2e69..843b5b1 100644
--- a/src/gmock/build-aux/config.h.in
+++ b/src/gmock/build-aux/config.h.in
@@ -33,7 +33,8 @@
 /* Define to 1 if you have the <unistd.h> header file. */
 #undef HAVE_UNISTD_H
 
-/* Define to the sub-directory where libtool stores uninstalled libraries. */
+/* Define to the sub-directory in which libtool stores uninstalled libraries.
+   */
 #undef LT_OBJDIR
 
 /* Name of package */
diff --git a/src/gmock/build-aux/config.sub b/src/gmock/build-aux/config.sub
index 1acc966..9633db7 100755
--- a/src/gmock/build-aux/config.sub
+++ b/src/gmock/build-aux/config.sub
@@ -1,8 +1,8 @@
 #! /bin/sh
 # Configuration validation subroutine script.
-#   Copyright 1992-2015 Free Software Foundation, Inc.
+#   Copyright 1992-2013 Free Software Foundation, Inc.
 
-timestamp='2015-08-20'
+timestamp='2013-08-10'
 
 # This file is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License as published by
@@ -25,7 +25,7 @@ timestamp='2015-08-20'
 # of the GNU General Public License, version 3 ("GPLv3").
 
 
-# Please send patches to <config-patches at gnu.org>.
+# Please send patches with a ChangeLog entry to config-patches at gnu.org.
 #
 # Configuration subroutine to validate and canonicalize a configuration type.
 # Supply the specified configuration type as an argument.
@@ -68,7 +68,7 @@ Report bugs and patches to <config-patches at gnu.org>."
 version="\
 GNU config.sub ($timestamp)
 
-Copyright 1992-2015 Free Software Foundation, Inc.
+Copyright 1992-2013 Free Software Foundation, Inc.
 
 This is free software; see the source for copying conditions.  There is NO
 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
@@ -117,7 +117,7 @@ maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
 case $maybe_os in
   nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \
   linux-musl* | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \
-  knetbsd*-gnu* | netbsd*-gnu* | netbsd*-eabi* | \
+  knetbsd*-gnu* | netbsd*-gnu* | \
   kopensolaris*-gnu* | \
   storm-chaos* | os2-emx* | rtmk-nova*)
     os=-$maybe_os
@@ -255,18 +255,16 @@ case $basic_machine in
 	| arc | arceb \
 	| arm | arm[bl]e | arme[lb] | armv[2-8] | armv[3-8][lb] | armv7[arm] \
 	| avr | avr32 \
-	| ba \
 	| be32 | be64 \
 	| bfin \
 	| c4x | c8051 | clipper \
 	| d10v | d30v | dlx | dsp16xx \
-	| e2k | epiphany \
-	| fido | fr30 | frv | ft32 \
+	| epiphany \
+	| fido | fr30 | frv \
 	| h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
 	| hexagon \
 	| i370 | i860 | i960 | ia64 \
 	| ip2k | iq2000 \
-	| k1om \
 	| le32 | le64 \
 	| lm32 \
 	| m32c | m32r | m32rle | m68000 | m68k | m88k \
@@ -284,10 +282,8 @@ case $basic_machine in
 	| mips64vr5900 | mips64vr5900el \
 	| mipsisa32 | mipsisa32el \
 	| mipsisa32r2 | mipsisa32r2el \
-	| mipsisa32r6 | mipsisa32r6el \
 	| mipsisa64 | mipsisa64el \
 	| mipsisa64r2 | mipsisa64r2el \
-	| mipsisa64r6 | mipsisa64r6el \
 	| mipsisa64sb1 | mipsisa64sb1el \
 	| mipsisa64sr71k | mipsisa64sr71kel \
 	| mipsr5900 | mipsr5900el \
@@ -299,14 +295,14 @@ case $basic_machine in
 	| nds32 | nds32le | nds32be \
 	| nios | nios2 | nios2eb | nios2el \
 	| ns16k | ns32k \
-	| open8 | or1k | or1knd | or32 \
+	| open8 \
+	| or1k | or32 \
 	| pdp10 | pdp11 | pj | pjl \
 	| powerpc | powerpc64 | powerpc64le | powerpcle \
 	| pyramid \
-	| riscv32 | riscv64 \
 	| rl78 | rx \
 	| score \
-	| sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[234]eb | sheb | shbe | shle | sh[1234]le | sh3ele \
+	| sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \
 	| sh64 | sh64le \
 	| sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \
 	| sparcv8 | sparcv9 | sparcv9b | sparcv9v \
@@ -314,7 +310,6 @@ case $basic_machine in
 	| tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \
 	| ubicom32 \
 	| v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \
-	| visium \
 	| we32k \
 	| x86 | xc16x | xstormy16 | xtensa \
 	| z8k | z80)
@@ -329,10 +324,7 @@ case $basic_machine in
 	c6x)
 		basic_machine=tic6x-unknown
 		;;
-	leon|leon[3-9])
-		basic_machine=sparc-$basic_machine
-		;;
-	m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | nvptx | picochip)
+	m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | picochip)
 		basic_machine=$basic_machine-unknown
 		os=-none
 		;;
@@ -377,20 +369,18 @@ case $basic_machine in
 	| alphapca5[67]-* | alpha64pca5[67]-* | arc-* | arceb-* \
 	| arm-*  | armbe-* | armle-* | armeb-* | armv*-* \
 	| avr-* | avr32-* \
-	| ba-* \
 	| be32-* | be64-* \
 	| bfin-* | bs2000-* \
 	| c[123]* | c30-* | [cjt]90-* | c4x-* \
 	| c8051-* | clipper-* | craynv-* | cydra-* \
 	| d10v-* | d30v-* | dlx-* \
-	| e2k-* | elxsi-* \
+	| elxsi-* \
 	| f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \
 	| h8300-* | h8500-* \
 	| hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \
 	| hexagon-* \
 	| i*86-* | i860-* | i960-* | ia64-* \
 	| ip2k-* | iq2000-* \
-	| k1om-* \
 	| le32-* | le64-* \
 	| lm32-* \
 	| m32c-* | m32r-* | m32rle-* \
@@ -410,10 +400,8 @@ case $basic_machine in
 	| mips64vr5900-* | mips64vr5900el-* \
 	| mipsisa32-* | mipsisa32el-* \
 	| mipsisa32r2-* | mipsisa32r2el-* \
-	| mipsisa32r6-* | mipsisa32r6el-* \
 	| mipsisa64-* | mipsisa64el-* \
 	| mipsisa64r2-* | mipsisa64r2el-* \
-	| mipsisa64r6-* | mipsisa64r6el-* \
 	| mipsisa64sb1-* | mipsisa64sb1el-* \
 	| mipsisa64sr71k-* | mipsisa64sr71kel-* \
 	| mipsr5900-* | mipsr5900el-* \
@@ -425,18 +413,16 @@ case $basic_machine in
 	| nios-* | nios2-* | nios2eb-* | nios2el-* \
 	| none-* | np1-* | ns16k-* | ns32k-* \
 	| open8-* \
-	| or1k*-* \
 	| orion-* \
 	| pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \
 	| powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \
 	| pyramid-* \
-	| riscv32-* | riscv64-* \
 	| rl78-* | romp-* | rs6000-* | rx-* \
 	| sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \
 	| shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \
 	| sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \
 	| sparclite-* \
-	| sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx*-* \
+	| sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx?-* \
 	| tahoe-* \
 	| tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \
 	| tile*-* \
@@ -444,7 +430,6 @@ case $basic_machine in
 	| ubicom32-* \
 	| v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \
 	| vax-* \
-	| visium-* \
 	| we32k-* \
 	| x86-* | x86_64-* | xc16x-* | xps100-* \
 	| xstormy16-* | xtensa*-* \
@@ -521,9 +506,6 @@ case $basic_machine in
 		basic_machine=i386-pc
 		os=-aros
 		;;
-        asmjs)
-		basic_machine=asmjs-unknown
-		;;
 	aux)
 		basic_machine=m68k-apple
 		os=-aux
@@ -785,9 +767,6 @@ case $basic_machine in
 		basic_machine=m68k-isi
 		os=-sysv
 		;;
-	leon-*|leon[3-9]-*)
-		basic_machine=sparc-`echo $basic_machine | sed 's/-.*//'`
-		;;
 	m68knommu)
 		basic_machine=m68k-unknown
 		os=-linux
@@ -843,10 +822,6 @@ case $basic_machine in
 		basic_machine=powerpc-unknown
 		os=-morphos
 		;;
-	moxiebox)
-		basic_machine=moxie-unknown
-		os=-moxiebox
-		;;
 	msdos)
 		basic_machine=i386-pc
 		os=-msdos
@@ -1379,7 +1354,7 @@ case $os in
 	      | -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \
 	      | -sym* | -kopensolaris* | -plan9* \
 	      | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \
-	      | -aos* | -aros* | -cloudabi* | -sortix* \
+	      | -aos* | -aros* \
 	      | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
 	      | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
 	      | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \
@@ -1392,14 +1367,14 @@ case $os in
 	      | -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
 	      | -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \
 	      | -linux-newlib* | -linux-musl* | -linux-uclibc* \
-	      | -uxpv* | -beos* | -mpeix* | -udk* | -moxiebox* \
+	      | -uxpv* | -beos* | -mpeix* | -udk* \
 	      | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \
 	      | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
 	      | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \
 	      | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \
 	      | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \
 	      | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \
-	      | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es* | -tirtos*)
+	      | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es*)
 	# Remember, each alternative MUST END IN *, to match a version number.
 		;;
 	-qnx*)
@@ -1617,6 +1592,9 @@ case $basic_machine in
 	mips*-*)
 		os=-elf
 		;;
+	or1k-*)
+		os=-elf
+		;;
 	or32-*)
 		os=-coff
 		;;
diff --git a/src/gmock/build-aux/depcomp b/src/gmock/build-aux/depcomp
index fc98710..4ebd5b3 100755
--- a/src/gmock/build-aux/depcomp
+++ b/src/gmock/build-aux/depcomp
@@ -3,7 +3,7 @@
 
 scriptversion=2013-05-30.07; # UTC
 
-# Copyright (C) 1999-2014 Free Software Foundation, Inc.
+# Copyright (C) 1999-2013 Free Software Foundation, Inc.
 
 # This program is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
diff --git a/src/gmock/build-aux/install-sh b/src/gmock/build-aux/install-sh
index 59990a1..377bb86 100755
--- a/src/gmock/build-aux/install-sh
+++ b/src/gmock/build-aux/install-sh
@@ -1,7 +1,7 @@
 #!/bin/sh
 # install - install a program, script, or datafile
 
-scriptversion=2014-09-12.12; # UTC
+scriptversion=2011-11-20.07; # UTC
 
 # This originates from X11R5 (mit/util/scripts/install.sh), which was
 # later released in X11R6 (xc/config/util/install.sh) with the
@@ -41,15 +41,19 @@ scriptversion=2014-09-12.12; # UTC
 # This script is compatible with the BSD install script, but was written
 # from scratch.
 
-tab='	'
 nl='
 '
-IFS=" $tab$nl"
+IFS=" ""	$nl"
 
-# Set DOITPROG to "echo" to test this script.
+# set DOITPROG to echo to test this script
 
+# Don't use :- since 4.3BSD and earlier shells don't like it.
 doit=${DOITPROG-}
-doit_exec=${doit:-exec}
+if test -z "$doit"; then
+  doit_exec=exec
+else
+  doit_exec=$doit
+fi
 
 # Put in absolute file names if you don't have them in your path;
 # or use environment vars.
@@ -64,6 +68,17 @@ mvprog=${MVPROG-mv}
 rmprog=${RMPROG-rm}
 stripprog=${STRIPPROG-strip}
 
+posix_glob='?'
+initialize_posix_glob='
+  test "$posix_glob" != "?" || {
+    if (set -f) 2>/dev/null; then
+      posix_glob=
+    else
+      posix_glob=:
+    fi
+  }
+'
+
 posix_mkdir=
 
 # Desired mode of installed file.
@@ -82,7 +97,7 @@ dir_arg=
 dst_arg=
 
 copy_on_change=false
-is_target_a_directory=possibly
+no_target_directory=
 
 usage="\
 Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE
@@ -122,57 +137,46 @@ while test $# -ne 0; do
     -d) dir_arg=true;;
 
     -g) chgrpcmd="$chgrpprog $2"
-        shift;;
+	shift;;
 
     --help) echo "$usage"; exit $?;;
 
     -m) mode=$2
-        case $mode in
-          *' '* | *"$tab"* | *"$nl"* | *'*'* | *'?'* | *'['*)
-            echo "$0: invalid mode: $mode" >&2
-            exit 1;;
-        esac
-        shift;;
+	case $mode in
+	  *' '* | *'	'* | *'
+'*	  | *'*'* | *'?'* | *'['*)
+	    echo "$0: invalid mode: $mode" >&2
+	    exit 1;;
+	esac
+	shift;;
 
     -o) chowncmd="$chownprog $2"
-        shift;;
+	shift;;
 
     -s) stripcmd=$stripprog;;
 
-    -t)
-        is_target_a_directory=always
-        dst_arg=$2
-        # Protect names problematic for 'test' and other utilities.
-        case $dst_arg in
-          -* | [=\(\)!]) dst_arg=./$dst_arg;;
-        esac
-        shift;;
+    -t) dst_arg=$2
+	# Protect names problematic for 'test' and other utilities.
+	case $dst_arg in
+	  -* | [=\(\)!]) dst_arg=./$dst_arg;;
+	esac
+	shift;;
 
-    -T) is_target_a_directory=never;;
+    -T) no_target_directory=true;;
 
     --version) echo "$0 $scriptversion"; exit $?;;
 
-    --) shift
-        break;;
+    --)	shift
+	break;;
 
-    -*) echo "$0: invalid option: $1" >&2
-        exit 1;;
+    -*)	echo "$0: invalid option: $1" >&2
+	exit 1;;
 
     *)  break;;
   esac
   shift
 done
 
-# We allow the use of options -d and -T together, by making -d
-# take the precedence; this is for compatibility with GNU install.
-
-if test -n "$dir_arg"; then
-  if test -n "$dst_arg"; then
-    echo "$0: target directory not allowed when installing a directory." >&2
-    exit 1
-  fi
-fi
-
 if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then
   # When -d is used, all remaining arguments are directories to create.
   # When -t is used, the destination is already specified.
@@ -204,15 +208,6 @@ if test $# -eq 0; then
 fi
 
 if test -z "$dir_arg"; then
-  if test $# -gt 1 || test "$is_target_a_directory" = always; then
-    if test ! -d "$dst_arg"; then
-      echo "$0: $dst_arg: Is not a directory." >&2
-      exit 1
-    fi
-  fi
-fi
-
-if test -z "$dir_arg"; then
   do_exit='(exit $ret); exit $ret'
   trap "ret=129; $do_exit" 1
   trap "ret=130; $do_exit" 2
@@ -228,16 +223,16 @@ if test -z "$dir_arg"; then
 
     *[0-7])
       if test -z "$stripcmd"; then
-        u_plus_rw=
+	u_plus_rw=
       else
-        u_plus_rw='% 200'
+	u_plus_rw='% 200'
       fi
       cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;;
     *)
       if test -z "$stripcmd"; then
-        u_plus_rw=
+	u_plus_rw=
       else
-        u_plus_rw=,u+rw
+	u_plus_rw=,u+rw
       fi
       cp_umask=$mode$u_plus_rw;;
   esac
@@ -274,15 +269,41 @@ do
     # If destination is a directory, append the input filename; won't work
     # if double slashes aren't ignored.
     if test -d "$dst"; then
-      if test "$is_target_a_directory" = never; then
-        echo "$0: $dst_arg: Is a directory" >&2
-        exit 1
+      if test -n "$no_target_directory"; then
+	echo "$0: $dst_arg: Is a directory" >&2
+	exit 1
       fi
       dstdir=$dst
       dst=$dstdir/`basename "$src"`
       dstdir_status=0
     else
-      dstdir=`dirname "$dst"`
+      # Prefer dirname, but fall back on a substitute if dirname fails.
+      dstdir=`
+	(dirname "$dst") 2>/dev/null ||
+	expr X"$dst" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	     X"$dst" : 'X\(//\)[^/]' \| \
+	     X"$dst" : 'X\(//\)$' \| \
+	     X"$dst" : 'X\(/\)' \| . 2>/dev/null ||
+	echo X"$dst" |
+	    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+		   s//\1/
+		   q
+		 }
+		 /^X\(\/\/\)[^/].*/{
+		   s//\1/
+		   q
+		 }
+		 /^X\(\/\/\)$/{
+		   s//\1/
+		   q
+		 }
+		 /^X\(\/\).*/{
+		   s//\1/
+		   q
+		 }
+		 s/.*/./; q'
+      `
+
       test -d "$dstdir"
       dstdir_status=$?
     fi
@@ -293,81 +314,74 @@ do
   if test $dstdir_status != 0; then
     case $posix_mkdir in
       '')
-        # Create intermediate dirs using mode 755 as modified by the umask.
-        # This is like FreeBSD 'install' as of 1997-10-28.
-        umask=`umask`
-        case $stripcmd.$umask in
-          # Optimize common cases.
-          *[2367][2367]) mkdir_umask=$umask;;
-          .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;;
-
-          *[0-7])
-            mkdir_umask=`expr $umask + 22 \
-              - $umask % 100 % 40 + $umask % 20 \
-              - $umask % 10 % 4 + $umask % 2
-            `;;
-          *) mkdir_umask=$umask,go-w;;
-        esac
-
-        # With -d, create the new directory with the user-specified mode.
-        # Otherwise, rely on $mkdir_umask.
-        if test -n "$dir_arg"; then
-          mkdir_mode=-m$mode
-        else
-          mkdir_mode=
-        fi
-
-        posix_mkdir=false
-        case $umask in
-          *[123567][0-7][0-7])
-            # POSIX mkdir -p sets u+wx bits regardless of umask, which
-            # is incompatible with FreeBSD 'install' when (umask & 300) != 0.
-            ;;
-          *)
-            # $RANDOM is not portable (e.g. dash);  use it when possible to
-            # lower collision chance
-            tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$
-            trap 'ret=$?; rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" 2>/dev/null; exit $ret' 0
-
-            # As "mkdir -p" follows symlinks and we work in /tmp possibly;  so
-            # create the $tmpdir first (and fail if unsuccessful) to make sure
-            # that nobody tries to guess the $tmpdir name.
-            if (umask $mkdir_umask &&
-                $mkdirprog $mkdir_mode "$tmpdir" &&
-                exec $mkdirprog $mkdir_mode -p -- "$tmpdir/a/b") >/dev/null 2>&1
-            then
-              if test -z "$dir_arg" || {
-                   # Check for POSIX incompatibilities with -m.
-                   # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or
-                   # other-writable bit of parent directory when it shouldn't.
-                   # FreeBSD 6.1 mkdir -m -p sets mode of existing directory.
-                   test_tmpdir="$tmpdir/a"
-                   ls_ld_tmpdir=`ls -ld "$test_tmpdir"`
-                   case $ls_ld_tmpdir in
-                     d????-?r-*) different_mode=700;;
-                     d????-?--*) different_mode=755;;
-                     *) false;;
-                   esac &&
-                   $mkdirprog -m$different_mode -p -- "$test_tmpdir" && {
-                     ls_ld_tmpdir_1=`ls -ld "$test_tmpdir"`
-                     test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1"
-                   }
-                 }
-              then posix_mkdir=:
-              fi
-              rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir"
-            else
-              # Remove any dirs left behind by ancient mkdir implementations.
-              rmdir ./$mkdir_mode ./-p ./-- "$tmpdir" 2>/dev/null
-            fi
-            trap '' 0;;
-        esac;;
+	# Create intermediate dirs using mode 755 as modified by the umask.
+	# This is like FreeBSD 'install' as of 1997-10-28.
+	umask=`umask`
+	case $stripcmd.$umask in
+	  # Optimize common cases.
+	  *[2367][2367]) mkdir_umask=$umask;;
+	  .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;;
+
+	  *[0-7])
+	    mkdir_umask=`expr $umask + 22 \
+	      - $umask % 100 % 40 + $umask % 20 \
+	      - $umask % 10 % 4 + $umask % 2
+	    `;;
+	  *) mkdir_umask=$umask,go-w;;
+	esac
+
+	# With -d, create the new directory with the user-specified mode.
+	# Otherwise, rely on $mkdir_umask.
+	if test -n "$dir_arg"; then
+	  mkdir_mode=-m$mode
+	else
+	  mkdir_mode=
+	fi
+
+	posix_mkdir=false
+	case $umask in
+	  *[123567][0-7][0-7])
+	    # POSIX mkdir -p sets u+wx bits regardless of umask, which
+	    # is incompatible with FreeBSD 'install' when (umask & 300) != 0.
+	    ;;
+	  *)
+	    tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$
+	    trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0
+
+	    if (umask $mkdir_umask &&
+		exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1
+	    then
+	      if test -z "$dir_arg" || {
+		   # Check for POSIX incompatibilities with -m.
+		   # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or
+		   # other-writable bit of parent directory when it shouldn't.
+		   # FreeBSD 6.1 mkdir -m -p sets mode of existing directory.
+		   ls_ld_tmpdir=`ls -ld "$tmpdir"`
+		   case $ls_ld_tmpdir in
+		     d????-?r-*) different_mode=700;;
+		     d????-?--*) different_mode=755;;
+		     *) false;;
+		   esac &&
+		   $mkdirprog -m$different_mode -p -- "$tmpdir" && {
+		     ls_ld_tmpdir_1=`ls -ld "$tmpdir"`
+		     test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1"
+		   }
+		 }
+	      then posix_mkdir=:
+	      fi
+	      rmdir "$tmpdir/d" "$tmpdir"
+	    else
+	      # Remove any dirs left behind by ancient mkdir implementations.
+	      rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null
+	    fi
+	    trap '' 0;;
+	esac;;
     esac
 
     if
       $posix_mkdir && (
-        umask $mkdir_umask &&
-        $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir"
+	umask $mkdir_umask &&
+	$doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir"
       )
     then :
     else
@@ -377,51 +391,53 @@ do
       # directory the slow way, step by step, checking for races as we go.
 
       case $dstdir in
-        /*) prefix='/';;
-        [-=\(\)!]*) prefix='./';;
-        *)  prefix='';;
+	/*) prefix='/';;
+	[-=\(\)!]*) prefix='./';;
+	*)  prefix='';;
       esac
 
+      eval "$initialize_posix_glob"
+
       oIFS=$IFS
       IFS=/
-      set -f
+      $posix_glob set -f
       set fnord $dstdir
       shift
-      set +f
+      $posix_glob set +f
       IFS=$oIFS
 
       prefixes=
 
       for d
       do
-        test X"$d" = X && continue
-
-        prefix=$prefix$d
-        if test -d "$prefix"; then
-          prefixes=
-        else
-          if $posix_mkdir; then
-            (umask=$mkdir_umask &&
-             $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break
-            # Don't fail if two instances are running concurrently.
-            test -d "$prefix" || exit 1
-          else
-            case $prefix in
-              *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;;
-              *) qprefix=$prefix;;
-            esac
-            prefixes="$prefixes '$qprefix'"
-          fi
-        fi
-        prefix=$prefix/
+	test X"$d" = X && continue
+
+	prefix=$prefix$d
+	if test -d "$prefix"; then
+	  prefixes=
+	else
+	  if $posix_mkdir; then
+	    (umask=$mkdir_umask &&
+	     $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break
+	    # Don't fail if two instances are running concurrently.
+	    test -d "$prefix" || exit 1
+	  else
+	    case $prefix in
+	      *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;;
+	      *) qprefix=$prefix;;
+	    esac
+	    prefixes="$prefixes '$qprefix'"
+	  fi
+	fi
+	prefix=$prefix/
       done
 
       if test -n "$prefixes"; then
-        # Don't fail if two instances are running concurrently.
-        (umask $mkdir_umask &&
-         eval "\$doit_exec \$mkdirprog $prefixes") ||
-          test -d "$dstdir" || exit 1
-        obsolete_mkdir_used=true
+	# Don't fail if two instances are running concurrently.
+	(umask $mkdir_umask &&
+	 eval "\$doit_exec \$mkdirprog $prefixes") ||
+	  test -d "$dstdir" || exit 1
+	obsolete_mkdir_used=true
       fi
     fi
   fi
@@ -456,12 +472,15 @@ do
 
     # If -C, don't bother to copy if it wouldn't change the file.
     if $copy_on_change &&
-       old=`LC_ALL=C ls -dlL "$dst"     2>/dev/null` &&
-       new=`LC_ALL=C ls -dlL "$dsttmp"  2>/dev/null` &&
-       set -f &&
+       old=`LC_ALL=C ls -dlL "$dst"	2>/dev/null` &&
+       new=`LC_ALL=C ls -dlL "$dsttmp"	2>/dev/null` &&
+
+       eval "$initialize_posix_glob" &&
+       $posix_glob set -f &&
        set X $old && old=:$2:$4:$5:$6 &&
        set X $new && new=:$2:$4:$5:$6 &&
-       set +f &&
+       $posix_glob set +f &&
+
        test "$old" = "$new" &&
        $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1
     then
@@ -474,24 +493,24 @@ do
       # to itself, or perhaps because mv is so ancient that it does not
       # support -f.
       {
-        # Now remove or move aside any old file at destination location.
-        # We try this two ways since rm can't unlink itself on some
-        # systems and the destination file might be busy for other
-        # reasons.  In this case, the final cleanup might fail but the new
-        # file should still install successfully.
-        {
-          test ! -f "$dst" ||
-          $doit $rmcmd -f "$dst" 2>/dev/null ||
-          { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null &&
-            { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; }
-          } ||
-          { echo "$0: cannot unlink or rename $dst" >&2
-            (exit 1); exit 1
-          }
-        } &&
-
-        # Now rename the file to the real destination.
-        $doit $mvcmd "$dsttmp" "$dst"
+	# Now remove or move aside any old file at destination location.
+	# We try this two ways since rm can't unlink itself on some
+	# systems and the destination file might be busy for other
+	# reasons.  In this case, the final cleanup might fail but the new
+	# file should still install successfully.
+	{
+	  test ! -f "$dst" ||
+	  $doit $rmcmd -f "$dst" 2>/dev/null ||
+	  { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null &&
+	    { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; }
+	  } ||
+	  { echo "$0: cannot unlink or rename $dst" >&2
+	    (exit 1); exit 1
+	  }
+	} &&
+
+	# Now rename the file to the real destination.
+	$doit $mvcmd "$dsttmp" "$dst"
       }
     fi || exit 1
 
diff --git a/src/gmock/build-aux/ltmain.sh b/src/gmock/build-aux/ltmain.sh
index 147d758..a356aca 100644
--- a/src/gmock/build-aux/ltmain.sh
+++ b/src/gmock/build-aux/ltmain.sh
@@ -1,12 +1,9 @@
-#! /bin/sh
-## DO NOT EDIT - This file generated from ./build-aux/ltmain.in
-##               by inline-source v2014-01-03.01
 
-# libtool (GNU libtool) 2.4.6
-# Provide generalized library-building support services.
+# libtool (GNU libtool) 2.4.2
 # Written by Gordon Matzigkeit <gord at gnu.ai.mit.edu>, 1996
 
-# Copyright (C) 1996-2015 Free Software Foundation, Inc.
+# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, 2006,
+# 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
 # This is free software; see the source for copying conditions.  There is NO
 # warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 
@@ -26,2112 +23,881 @@
 # General Public License for more details.
 #
 # You should have received a copy of the GNU General Public License
-# along with this program.  If not, see <http://www.gnu.org/licenses/>.
-
-
-PROGRAM=libtool
-PACKAGE=libtool
-VERSION="2.4.6 Debian-2.4.6-0.1"
-package_revision=2.4.6
-
-
-## ------ ##
-## Usage. ##
-## ------ ##
-
-# Run './libtool --help' for help with using this script from the
-# command line.
-
-
-## ------------------------------- ##
-## User overridable command paths. ##
-## ------------------------------- ##
-
-# After configure completes, it has a better idea of some of the
-# shell tools we need than the defaults used by the functions shared
-# with bootstrap, so set those here where they can still be over-
-# ridden by the user, but otherwise take precedence.
-
-: ${AUTOCONF="autoconf"}
-: ${AUTOMAKE="automake"}
-
-
-## -------------------------- ##
-## Source external libraries. ##
-## -------------------------- ##
-
-# Much of our low-level functionality needs to be sourced from external
-# libraries, which are installed to $pkgauxdir.
-
-# Set a version string for this script.
-scriptversion=2015-01-20.17; # UTC
-
-# General shell script boiler plate, and helper functions.
-# Written by Gary V. Vaughan, 2004
-
-# Copyright (C) 2004-2015 Free Software Foundation, Inc.
-# This is free software; see the source for copying conditions.  There is NO
-# warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 3 of the License, or
-# (at your option) any later version.
-
-# As a special exception to the GNU General Public License, if you distribute
-# this file as part of a program or library that is built using GNU Libtool,
-# you may include this file under the same distribution terms that you use
-# for the rest of that program.
-
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNES FOR A PARTICULAR PURPOSE. See the GNU
-# General Public License for more details.
-
-# You should have received a copy of the GNU General Public License
-# along with this program. If not, see <http://www.gnu.org/licenses/>.
+# along with GNU Libtool; see the file COPYING.  If not, a copy
+# can be downloaded from http://www.gnu.org/licenses/gpl.html,
+# or obtained by writing to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 
-# Please report bugs or propose patches to gary at gnu.org.
-
-
-## ------ ##
-## Usage. ##
-## ------ ##
-
-# Evaluate this file near the top of your script to gain access to
-# the functions and variables defined here:
+# Usage: $progname [OPTION]... [MODE-ARG]...
+#
+# Provide generalized library-building support services.
 #
-#   . `echo "$0" | ${SED-sed} 's|[^/]*$||'`/build-aux/funclib.sh
+#       --config             show all configuration variables
+#       --debug              enable verbose shell tracing
+#   -n, --dry-run            display commands without modifying any files
+#       --features           display basic configuration information and exit
+#       --mode=MODE          use operation mode MODE
+#       --preserve-dup-deps  don't remove duplicate dependency libraries
+#       --quiet, --silent    don't print informational messages
+#       --no-quiet, --no-silent
+#                            print informational messages (default)
+#       --no-warn            don't display warning messages
+#       --tag=TAG            use configuration variables from tag TAG
+#   -v, --verbose            print more informational messages than default
+#       --no-verbose         don't print the extra informational messages
+#       --version            print version information
+#   -h, --help, --help-all   print short, long, or detailed help message
 #
-# If you need to override any of the default environment variable
-# settings, do that before evaluating this file.
-
-
-## -------------------- ##
-## Shell normalisation. ##
-## -------------------- ##
+# MODE must be one of the following:
+#
+#         clean              remove files from the build directory
+#         compile            compile a source file into a libtool object
+#         execute            automatically set library path, then run a program
+#         finish             complete the installation of libtool libraries
+#         install            install libraries or executables
+#         link               create a library or an executable
+#         uninstall          remove libraries from an installed directory
+#
+# MODE-ARGS vary depending on the MODE.  When passed as first option,
+# `--mode=MODE' may be abbreviated as `MODE' or a unique abbreviation of that.
+# Try `$progname --help --mode=MODE' for a more detailed description of MODE.
+#
+# When reporting a bug, please describe a test case to reproduce it and
+# include the following information:
+#
+#         host-triplet:	$host
+#         shell:		$SHELL
+#         compiler:		$LTCC
+#         compiler flags:		$LTCFLAGS
+#         linker:		$LD (gnu? $with_gnu_ld)
+#         $progname:	(GNU libtool) 2.4.2 Debian-2.4.2-1.7ubuntu1
+#         automake:	$automake_version
+#         autoconf:	$autoconf_version
+#
+# Report bugs to <bug-libtool at gnu.org>.
+# GNU libtool home page: <http://www.gnu.org/software/libtool/>.
+# General help using GNU software: <http://www.gnu.org/gethelp/>.
 
-# Some shells need a little help to be as Bourne compatible as possible.
-# Before doing anything else, make sure all that help has been provided!
+PROGRAM=libtool
+PACKAGE=libtool
+VERSION="2.4.2 Debian-2.4.2-1.7ubuntu1"
+TIMESTAMP=""
+package_revision=1.3337
 
-DUALCASE=1; export DUALCASE # for MKS sh
-if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then :
+# Be Bourne compatible
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
   emulate sh
   NULLCMD=:
-  # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which
+  # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which
   # is contrary to our usage.  Disable this feature.
   alias -g '${1+"$@"}'='"$@"'
   setopt NO_GLOB_SUBST
 else
-  case `(set -o) 2>/dev/null` in *posix*) set -o posix ;; esac
-fi
-
-# NLS nuisances: We save the old values in case they are required later.
-_G_user_locale=
-_G_safe_locale=
-for _G_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES
-do
-  eval "if test set = \"\${$_G_var+set}\"; then
-          save_$_G_var=\$$_G_var
-          $_G_var=C
-	  export $_G_var
-	  _G_user_locale=\"$_G_var=\\\$save_\$_G_var; \$_G_user_locale\"
-	  _G_safe_locale=\"$_G_var=C; \$_G_safe_locale\"
-	fi"
-done
-
-# CDPATH.
-(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
-
-# Make sure IFS has a sensible default
-sp=' '
-nl='
-'
-IFS="$sp	$nl"
-
-# There are apparently some retarded systems that use ';' as a PATH separator!
-if test "${PATH_SEPARATOR+set}" != set; then
-  PATH_SEPARATOR=:
-  (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && {
-    (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 ||
-      PATH_SEPARATOR=';'
-  }
+  case `(set -o) 2>/dev/null` in *posix*) set -o posix;; esac
 fi
+BIN_SH=xpg4; export BIN_SH # for Tru64
+DUALCASE=1; export DUALCASE # for MKS sh
 
-
-
-## ------------------------- ##
-## Locate command utilities. ##
-## ------------------------- ##
-
-
-# func_executable_p FILE
-# ----------------------
-# Check that FILE is an executable regular file.
-func_executable_p ()
-{
-    test -f "$1" && test -x "$1"
-}
-
-
-# func_path_progs PROGS_LIST CHECK_FUNC [PATH]
-# --------------------------------------------
-# Search for either a program that responds to --version with output
-# containing "GNU", or else returned by CHECK_FUNC otherwise, by
-# trying all the directories in PATH with each of the elements of
-# PROGS_LIST.
-#
-# CHECK_FUNC should accept the path to a candidate program, and
-# set $func_check_prog_result if it truncates its output less than
-# $_G_path_prog_max characters.
-func_path_progs ()
+# A function that is used when there is no print builtin or printf.
+func_fallback_echo ()
 {
-    _G_progs_list=$1
-    _G_check_func=$2
-    _G_PATH=${3-"$PATH"}
-
-    _G_path_prog_max=0
-    _G_path_prog_found=false
-    _G_save_IFS=$IFS; IFS=${PATH_SEPARATOR-:}
-    for _G_dir in $_G_PATH; do
-      IFS=$_G_save_IFS
-      test -z "$_G_dir" && _G_dir=.
-      for _G_prog_name in $_G_progs_list; do
-        for _exeext in '' .EXE; do
-          _G_path_prog=$_G_dir/$_G_prog_name$_exeext
-          func_executable_p "$_G_path_prog" || continue
-          case `"$_G_path_prog" --version 2>&1` in
-            *GNU*) func_path_progs_result=$_G_path_prog _G_path_prog_found=: ;;
-            *)     $_G_check_func $_G_path_prog
-		   func_path_progs_result=$func_check_prog_result
-		   ;;
-          esac
-          $_G_path_prog_found && break 3
-        done
-      done
-    done
-    IFS=$_G_save_IFS
-    test -z "$func_path_progs_result" && {
-      echo "no acceptable sed could be found in \$PATH" >&2
-      exit 1
-    }
-}
-
-
-# We want to be able to use the functions in this file before configure
-# has figured out where the best binaries are kept, which means we have
-# to search for them ourselves - except when the results are already set
-# where we skip the searches.
-
-# Unless the user overrides by setting SED, search the path for either GNU
-# sed, or the sed that truncates its output the least.
-test -z "$SED" && {
-  _G_sed_script=s/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/
-  for _G_i in 1 2 3 4 5 6 7; do
-    _G_sed_script=$_G_sed_script$nl$_G_sed_script
-  done
-  echo "$_G_sed_script" 2>/dev/null | sed 99q >conftest.sed
-  _G_sed_script=
-
-  func_check_prog_sed ()
-  {
-    _G_path_prog=$1
-
-    _G_count=0
-    printf 0123456789 >conftest.in
-    while :
-    do
-      cat conftest.in conftest.in >conftest.tmp
-      mv conftest.tmp conftest.in
-      cp conftest.in conftest.nl
-      echo '' >> conftest.nl
-      "$_G_path_prog" -f conftest.sed <conftest.nl >conftest.out 2>/dev/null || break
-      diff conftest.out conftest.nl >/dev/null 2>&1 || break
-      _G_count=`expr $_G_count + 1`
-      if test "$_G_count" -gt "$_G_path_prog_max"; then
-        # Best one so far, save it but keep looking for a better one
-        func_check_prog_result=$_G_path_prog
-        _G_path_prog_max=$_G_count
-      fi
-      # 10*(2^10) chars as input seems more than enough
-      test 10 -lt "$_G_count" && break
-    done
-    rm -f conftest.in conftest.tmp conftest.nl conftest.out
-  }
-
-  func_path_progs "sed gsed" func_check_prog_sed $PATH:/usr/xpg4/bin
-  rm -f conftest.sed
-  SED=$func_path_progs_result
+  eval 'cat <<_LTECHO_EOF
+$1
+_LTECHO_EOF'
 }
 
+# NLS nuisances: We save the old values to restore during execute mode.
+lt_user_locale=
+lt_safe_locale=
+for lt_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES
+do
+  eval "if test \"\${$lt_var+set}\" = set; then
+          save_$lt_var=\$$lt_var
+          $lt_var=C
+	  export $lt_var
+	  lt_user_locale=\"$lt_var=\\\$save_\$lt_var; \$lt_user_locale\"
+	  lt_safe_locale=\"$lt_var=C; \$lt_safe_locale\"
+	fi"
+done
+LC_ALL=C
+LANGUAGE=C
+export LANGUAGE LC_ALL
 
-# Unless the user overrides by setting GREP, search the path for either GNU
-# grep, or the grep that truncates its output the least.
-test -z "$GREP" && {
-  func_check_prog_grep ()
-  {
-    _G_path_prog=$1
-
-    _G_count=0
-    _G_path_prog_max=0
-    printf 0123456789 >conftest.in
-    while :
-    do
-      cat conftest.in conftest.in >conftest.tmp
-      mv conftest.tmp conftest.in
-      cp conftest.in conftest.nl
-      echo 'GREP' >> conftest.nl
-      "$_G_path_prog" -e 'GREP$' -e '-(cannot match)-' <conftest.nl >conftest.out 2>/dev/null || break
-      diff conftest.out conftest.nl >/dev/null 2>&1 || break
-      _G_count=`expr $_G_count + 1`
-      if test "$_G_count" -gt "$_G_path_prog_max"; then
-        # Best one so far, save it but keep looking for a better one
-        func_check_prog_result=$_G_path_prog
-        _G_path_prog_max=$_G_count
-      fi
-      # 10*(2^10) chars as input seems more than enough
-      test 10 -lt "$_G_count" && break
-    done
-    rm -f conftest.in conftest.tmp conftest.nl conftest.out
-  }
+$lt_unset CDPATH
 
-  func_path_progs "grep ggrep" func_check_prog_grep $PATH:/usr/xpg4/bin
-  GREP=$func_path_progs_result
-}
 
+# Work around backward compatibility issue on IRIX 6.5. On IRIX 6.4+, sh
+# is ksh but when the shell is invoked as "sh" and the current value of
+# the _XPG environment variable is not equal to 1 (one), the special
+# positional parameter $0, within a function call, is the name of the
+# function.
+progpath="$0"
 
-## ------------------------------- ##
-## User overridable command paths. ##
-## ------------------------------- ##
 
-# All uppercase variable names are used for environment variables.  These
-# variables can be overridden by the user before calling a script that
-# uses them if a suitable command of that name is not already available
-# in the command search PATH.
 
 : ${CP="cp -f"}
-: ${ECHO="printf %s\n"}
-: ${EGREP="$GREP -E"}
-: ${FGREP="$GREP -F"}
-: ${LN_S="ln -s"}
+test "${ECHO+set}" = set || ECHO=${as_echo-'printf %s\n'}
 : ${MAKE="make"}
 : ${MKDIR="mkdir"}
 : ${MV="mv -f"}
 : ${RM="rm -f"}
 : ${SHELL="${CONFIG_SHELL-/bin/sh}"}
+: ${Xsed="$SED -e 1s/^X//"}
 
+# Global variables:
+EXIT_SUCCESS=0
+EXIT_FAILURE=1
+EXIT_MISMATCH=63  # $? = 63 is used to indicate version mismatch to missing.
+EXIT_SKIP=77	  # $? = 77 is used to indicate a skipped test to automake.
 
-## -------------------- ##
-## Useful sed snippets. ##
-## -------------------- ##
+exit_status=$EXIT_SUCCESS
 
-sed_dirname='s|/[^/]*$||'
-sed_basename='s|^.*/||'
+# Make sure IFS has a sensible default
+lt_nl='
+'
+IFS=" 	$lt_nl"
 
-# Sed substitution that helps us do robust quoting.  It backslashifies
-# metacharacters that are still active within double-quoted strings.
-sed_quote_subst='s|\([`"$\\]\)|\\\1|g'
+dirname="s,/[^/]*$,,"
+basename="s,^.*/,,"
 
-# Same as above, but do not quote variable references.
-sed_double_quote_subst='s/\(["`\\]\)/\\\1/g'
+# func_dirname file append nondir_replacement
+# Compute the dirname of FILE.  If nonempty, add APPEND to the result,
+# otherwise set result to NONDIR_REPLACEMENT.
+func_dirname ()
+{
+    func_dirname_result=`$ECHO "${1}" | $SED "$dirname"`
+    if test "X$func_dirname_result" = "X${1}"; then
+      func_dirname_result="${3}"
+    else
+      func_dirname_result="$func_dirname_result${2}"
+    fi
+} # func_dirname may be replaced by extended shell implementation
 
-# Sed substitution that turns a string into a regex matching for the
-# string literally.
-sed_make_literal_regex='s|[].[^$\\*\/]|\\&|g'
 
-# Sed substitution that converts a w32 file name or path
-# that contains forward slashes, into one that contains
-# (escaped) backslashes.  A very naive implementation.
-sed_naive_backslashify='s|\\\\*|\\|g;s|/|\\|g;s|\\|\\\\|g'
-
-# Re-'\' parameter expansions in output of sed_double_quote_subst that
-# were '\'-ed in input to the same.  If an odd number of '\' preceded a
-# '$' in input to sed_double_quote_subst, that '$' was protected from
-# expansion.  Since each input '\' is now two '\'s, look for any number
-# of runs of four '\'s followed by two '\'s and then a '$'.  '\' that '$'.
-_G_bs='\\'
-_G_bs2='\\\\'
-_G_bs4='\\\\\\\\'
-_G_dollar='\$'
-sed_double_backslash="\
-  s/$_G_bs4/&\\
-/g
-  s/^$_G_bs2$_G_dollar/$_G_bs&/
-  s/\\([^$_G_bs]\\)$_G_bs2$_G_dollar/\\1$_G_bs2$_G_bs$_G_dollar/g
-  s/\n//g"
+# func_basename file
+func_basename ()
+{
+    func_basename_result=`$ECHO "${1}" | $SED "$basename"`
+} # func_basename may be replaced by extended shell implementation
 
 
-## ----------------- ##
-## Global variables. ##
-## ----------------- ##
+# func_dirname_and_basename file append nondir_replacement
+# perform func_basename and func_dirname in a single function
+# call:
+#   dirname:  Compute the dirname of FILE.  If nonempty,
+#             add APPEND to the result, otherwise set result
+#             to NONDIR_REPLACEMENT.
+#             value returned in "$func_dirname_result"
+#   basename: Compute filename of FILE.
+#             value retuned in "$func_basename_result"
+# Implementation must be kept synchronized with func_dirname
+# and func_basename. For efficiency, we do not delegate to
+# those functions but instead duplicate the functionality here.
+func_dirname_and_basename ()
+{
+    # Extract subdirectory from the argument.
+    func_dirname_result=`$ECHO "${1}" | $SED -e "$dirname"`
+    if test "X$func_dirname_result" = "X${1}"; then
+      func_dirname_result="${3}"
+    else
+      func_dirname_result="$func_dirname_result${2}"
+    fi
+    func_basename_result=`$ECHO "${1}" | $SED -e "$basename"`
+} # func_dirname_and_basename may be replaced by extended shell implementation
 
-# Except for the global variables explicitly listed below, the following
-# functions in the '^func_' namespace, and the '^require_' namespace
-# variables initialised in the 'Resource management' section, sourcing
-# this file will not pollute your global namespace with anything
-# else. There's no portable way to scope variables in Bourne shell
-# though, so actually running these functions will sometimes place
-# results into a variable named after the function, and often use
-# temporary variables in the '^_G_' namespace. If you are careful to
-# avoid using those namespaces casually in your sourcing script, things
-# should continue to work as you expect. And, of course, you can freely
-# overwrite any of the functions or variables defined here before
-# calling anything to customize them.
 
-EXIT_SUCCESS=0
-EXIT_FAILURE=1
-EXIT_MISMATCH=63  # $? = 63 is used to indicate version mismatch to missing.
-EXIT_SKIP=77	  # $? = 77 is used to indicate a skipped test to automake.
+# func_stripname prefix suffix name
+# strip PREFIX and SUFFIX off of NAME.
+# PREFIX and SUFFIX must not contain globbing or regex special
+# characters, hashes, percent signs, but SUFFIX may contain a leading
+# dot (in which case that matches only a dot).
+# func_strip_suffix prefix name
+func_stripname ()
+{
+    case ${2} in
+      .*) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%\\\\${2}\$%%"`;;
+      *)  func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%${2}\$%%"`;;
+    esac
+} # func_stripname may be replaced by extended shell implementation
 
-# Allow overriding, eg assuming that you follow the convention of
-# putting '$debug_cmd' at the start of all your functions, you can get
-# bash to show function call trace with:
-#
-#    debug_cmd='eval echo "${FUNCNAME[0]} $*" >&2' bash your-script-name
-debug_cmd=${debug_cmd-":"}
-exit_cmd=:
 
-# By convention, finish your script with:
-#
-#    exit $exit_status
-#
-# so that you can set exit_status to non-zero if you want to indicate
-# something went wrong during execution without actually bailing out at
-# the point of failure.
-exit_status=$EXIT_SUCCESS
+# These SED scripts presuppose an absolute path with a trailing slash.
+pathcar='s,^/\([^/]*\).*$,\1,'
+pathcdr='s,^/[^/]*,,'
+removedotparts=':dotsl
+		s@/\./@/@g
+		t dotsl
+		s,/\.$,/,'
+collapseslashes='s@/\{1,\}@/@g'
+finalslash='s,/*$,/,'
 
-# Work around backward compatibility issue on IRIX 6.5. On IRIX 6.4+, sh
-# is ksh but when the shell is invoked as "sh" and the current value of
-# the _XPG environment variable is not equal to 1 (one), the special
-# positional parameter $0, within a function call, is the name of the
-# function.
-progpath=$0
+# func_normal_abspath PATH
+# Remove doubled-up and trailing slashes, "." path components,
+# and cancel out any ".." path components in PATH after making
+# it an absolute path.
+#             value returned in "$func_normal_abspath_result"
+func_normal_abspath ()
+{
+  # Start from root dir and reassemble the path.
+  func_normal_abspath_result=
+  func_normal_abspath_tpath=$1
+  func_normal_abspath_altnamespace=
+  case $func_normal_abspath_tpath in
+    "")
+      # Empty path, that just means $cwd.
+      func_stripname '' '/' "`pwd`"
+      func_normal_abspath_result=$func_stripname_result
+      return
+    ;;
+    # The next three entries are used to spot a run of precisely
+    # two leading slashes without using negated character classes;
+    # we take advantage of case's first-match behaviour.
+    ///*)
+      # Unusual form of absolute path, do nothing.
+    ;;
+    //*)
+      # Not necessarily an ordinary path; POSIX reserves leading '//'
+      # and for example Cygwin uses it to access remote file shares
+      # over CIFS/SMB, so we conserve a leading double slash if found.
+      func_normal_abspath_altnamespace=/
+    ;;
+    /*)
+      # Absolute path, do nothing.
+    ;;
+    *)
+      # Relative path, prepend $cwd.
+      func_normal_abspath_tpath=`pwd`/$func_normal_abspath_tpath
+    ;;
+  esac
+  # Cancel out all the simple stuff to save iterations.  We also want
+  # the path to end with a slash for ease of parsing, so make sure
+  # there is one (and only one) here.
+  func_normal_abspath_tpath=`$ECHO "$func_normal_abspath_tpath" | $SED \
+        -e "$removedotparts" -e "$collapseslashes" -e "$finalslash"`
+  while :; do
+    # Processed it all yet?
+    if test "$func_normal_abspath_tpath" = / ; then
+      # If we ascended to the root using ".." the result may be empty now.
+      if test -z "$func_normal_abspath_result" ; then
+        func_normal_abspath_result=/
+      fi
+      break
+    fi
+    func_normal_abspath_tcomponent=`$ECHO "$func_normal_abspath_tpath" | $SED \
+        -e "$pathcar"`
+    func_normal_abspath_tpath=`$ECHO "$func_normal_abspath_tpath" | $SED \
+        -e "$pathcdr"`
+    # Figure out what to do with it
+    case $func_normal_abspath_tcomponent in
+      "")
+        # Trailing empty path component, ignore it.
+      ;;
+      ..)
+        # Parent dir; strip last assembled component from result.
+        func_dirname "$func_normal_abspath_result"
+        func_normal_abspath_result=$func_dirname_result
+      ;;
+      *)
+        # Actual path component, append it.
+        func_normal_abspath_result=$func_normal_abspath_result/$func_normal_abspath_tcomponent
+      ;;
+    esac
+  done
+  # Restore leading double-slash if one was found on entry.
+  func_normal_abspath_result=$func_normal_abspath_altnamespace$func_normal_abspath_result
+}
+
+# func_relative_path SRCDIR DSTDIR
+# generates a relative path from SRCDIR to DSTDIR, with a trailing
+# slash if non-empty, suitable for immediately appending a filename
+# without needing to append a separator.
+#             value returned in "$func_relative_path_result"
+func_relative_path ()
+{
+  func_relative_path_result=
+  func_normal_abspath "$1"
+  func_relative_path_tlibdir=$func_normal_abspath_result
+  func_normal_abspath "$2"
+  func_relative_path_tbindir=$func_normal_abspath_result
+
+  # Ascend the tree starting from libdir
+  while :; do
+    # check if we have found a prefix of bindir
+    case $func_relative_path_tbindir in
+      $func_relative_path_tlibdir)
+        # found an exact match
+        func_relative_path_tcancelled=
+        break
+        ;;
+      $func_relative_path_tlibdir*)
+        # found a matching prefix
+        func_stripname "$func_relative_path_tlibdir" '' "$func_relative_path_tbindir"
+        func_relative_path_tcancelled=$func_stripname_result
+        if test -z "$func_relative_path_result"; then
+          func_relative_path_result=.
+        fi
+        break
+        ;;
+      *)
+        func_dirname $func_relative_path_tlibdir
+        func_relative_path_tlibdir=${func_dirname_result}
+        if test "x$func_relative_path_tlibdir" = x ; then
+          # Have to descend all the way to the root!
+          func_relative_path_result=../$func_relative_path_result
+          func_relative_path_tcancelled=$func_relative_path_tbindir
+          break
+        fi
+        func_relative_path_result=../$func_relative_path_result
+        ;;
+    esac
+  done
+
+  # Now calculate path; take care to avoid doubling-up slashes.
+  func_stripname '' '/' "$func_relative_path_result"
+  func_relative_path_result=$func_stripname_result
+  func_stripname '/' '/' "$func_relative_path_tcancelled"
+  if test "x$func_stripname_result" != x ; then
+    func_relative_path_result=${func_relative_path_result}/${func_stripname_result}
+  fi
+
+  # Normalisation. If bindir is libdir, return empty string,
+  # else relative path ending with a slash; either way, target
+  # file name can be directly appended.
+  if test ! -z "$func_relative_path_result"; then
+    func_stripname './' '' "$func_relative_path_result/"
+    func_relative_path_result=$func_stripname_result
+  fi
+}
 
-# The name of this program.
-progname=`$ECHO "$progpath" |$SED "$sed_basename"`
+# The name of this program:
+func_dirname_and_basename "$progpath"
+progname=$func_basename_result
 
-# Make sure we have an absolute progpath for reexecution:
+# Make sure we have an absolute path for reexecution:
 case $progpath in
   [\\/]*|[A-Za-z]:\\*) ;;
   *[\\/]*)
-     progdir=`$ECHO "$progpath" |$SED "$sed_dirname"`
+     progdir=$func_dirname_result
      progdir=`cd "$progdir" && pwd`
-     progpath=$progdir/$progname
+     progpath="$progdir/$progname"
      ;;
   *)
-     _G_IFS=$IFS
+     save_IFS="$IFS"
      IFS=${PATH_SEPARATOR-:}
      for progdir in $PATH; do
-       IFS=$_G_IFS
+       IFS="$save_IFS"
        test -x "$progdir/$progname" && break
      done
-     IFS=$_G_IFS
+     IFS="$save_IFS"
      test -n "$progdir" || progdir=`pwd`
-     progpath=$progdir/$progname
+     progpath="$progdir/$progname"
      ;;
 esac
 
+# Sed substitution that helps us do robust quoting.  It backslashifies
+# metacharacters that are still active within double-quoted strings.
+Xsed="${SED}"' -e 1s/^X//'
+sed_quote_subst='s/\([`"$\\]\)/\\\1/g'
+
+# Same as above, but do not quote variable references.
+double_quote_subst='s/\(["`\\]\)/\\\1/g'
 
-## ----------------- ##
-## Standard options. ##
-## ----------------- ##
+# Sed substitution that turns a string into a regex matching for the
+# string literally.
+sed_make_literal_regex='s,[].[^$\\*\/],\\&,g'
 
-# The following options affect the operation of the functions defined
-# below, and should be set appropriately depending on run-time para-
-# meters passed on the command line.
+# Sed substitution that converts a w32 file name or path
+# which contains forward slashes, into one that contains
+# (escaped) backslashes.  A very naive implementation.
+lt_sed_naive_backslashify='s|\\\\*|\\|g;s|/|\\|g;s|\\|\\\\|g'
+
+# Re-`\' parameter expansions in output of double_quote_subst that were
+# `\'-ed in input to the same.  If an odd number of `\' preceded a '$'
+# in input to double_quote_subst, that '$' was protected from expansion.
+# Since each input `\' is now two `\'s, look for any number of runs of
+# four `\'s followed by two `\'s and then a '$'.  `\' that '$'.
+bs='\\'
+bs2='\\\\'
+bs4='\\\\\\\\'
+dollar='\$'
+sed_double_backslash="\
+  s/$bs4/&\\
+/g
+  s/^$bs2$dollar/$bs&/
+  s/\\([^$bs]\\)$bs2$dollar/\\1$bs2$bs$dollar/g
+  s/\n//g"
 
+# Standard options:
 opt_dry_run=false
+opt_help=false
 opt_quiet=false
 opt_verbose=false
+opt_warning=:
 
-# Categories 'all' and 'none' are always available.  Append any others
-# you will pass as the first argument to func_warning from your own
-# code.
-warning_categories=
+# func_echo arg...
+# Echo program name prefixed message, along with the current mode
+# name if it has been set yet.
+func_echo ()
+{
+    $ECHO "$progname: ${opt_mode+$opt_mode: }$*"
+}
 
-# By default, display warnings according to 'opt_warning_types'.  Set
-# 'warning_func'  to ':' to elide all warnings, or func_fatal_error to
-# treat the next displayed warning as a fatal error.
-warning_func=func_warn_and_continue
+# func_verbose arg...
+# Echo program name prefixed message in verbose mode only.
+func_verbose ()
+{
+    $opt_verbose && func_echo ${1+"$@"}
 
-# Set to 'all' to display all warnings, 'none' to suppress all
-# warnings, or a space delimited list of some subset of
-# 'warning_categories' to display only the listed warnings.
-opt_warning_types=all
+    # A bug in bash halts the script if the last line of a function
+    # fails when set -e is in force, so we need another command to
+    # work around that:
+    :
+}
 
+# func_echo_all arg...
+# Invoke $ECHO with all args, space-separated.
+func_echo_all ()
+{
+    $ECHO "$*"
+}
 
-## -------------------- ##
-## Resource management. ##
-## -------------------- ##
+# func_error arg...
+# Echo program name prefixed message to standard error.
+func_error ()
+{
+    $ECHO "$progname: ${opt_mode+$opt_mode: }"${1+"$@"} 1>&2
+}
 
-# This section contains definitions for functions that each ensure a
-# particular resource (a file, or a non-empty configuration variable for
-# example) is available, and if appropriate to extract default values
-# from pertinent package files. Call them using their associated
-# 'require_*' variable to ensure that they are executed, at most, once.
-#
-# It's entirely deliberate that calling these functions can set
-# variables that don't obey the namespace limitations obeyed by the rest
-# of this file, in order that that they be as useful as possible to
-# callers.
+# func_warning arg...
+# Echo program name prefixed warning message to standard error.
+func_warning ()
+{
+    $opt_warning && $ECHO "$progname: ${opt_mode+$opt_mode: }warning: "${1+"$@"} 1>&2
 
+    # bash bug again:
+    :
+}
 
-# require_term_colors
-# -------------------
-# Allow display of bold text on terminals that support it.
-require_term_colors=func_require_term_colors
-func_require_term_colors ()
+# func_fatal_error arg...
+# Echo program name prefixed message to standard error, and exit.
+func_fatal_error ()
 {
-    $debug_cmd
-
-    test -t 1 && {
-      # COLORTERM and USE_ANSI_COLORS environment variables take
-      # precedence, because most terminfo databases neglect to describe
-      # whether color sequences are supported.
-      test -n "${COLORTERM+set}" && : ${USE_ANSI_COLORS="1"}
-
-      if test 1 = "$USE_ANSI_COLORS"; then
-        # Standard ANSI escape sequences
-        tc_reset=''
-        tc_bold='';   tc_standout=''
-        tc_red='';   tc_green=''
-        tc_blue='';  tc_cyan=''
-      else
-        # Otherwise trust the terminfo database after all.
-        test -n "`tput sgr0 2>/dev/null`" && {
-          tc_reset=`tput sgr0`
-          test -n "`tput bold 2>/dev/null`" && tc_bold=`tput bold`
-          tc_standout=$tc_bold
-          test -n "`tput smso 2>/dev/null`" && tc_standout=`tput smso`
-          test -n "`tput setaf 1 2>/dev/null`" && tc_red=`tput setaf 1`
-          test -n "`tput setaf 2 2>/dev/null`" && tc_green=`tput setaf 2`
-          test -n "`tput setaf 4 2>/dev/null`" && tc_blue=`tput setaf 4`
-          test -n "`tput setaf 5 2>/dev/null`" && tc_cyan=`tput setaf 5`
-        }
-      fi
-    }
+    func_error ${1+"$@"}
+    exit $EXIT_FAILURE
+}
 
-    require_term_colors=:
+# func_fatal_help arg...
+# Echo program name prefixed message to standard error, followed by
+# a help hint, and exit.
+func_fatal_help ()
+{
+    func_error ${1+"$@"}
+    func_fatal_error "$help"
 }
+help="Try \`$progname --help' for more information."  ## default
 
 
-## ----------------- ##
-## Function library. ##
-## ----------------- ##
-
-# This section contains a variety of useful functions to call in your
-# scripts. Take note of the portable wrappers for features provided by
-# some modern shells, which will fall back to slower equivalents on
-# less featureful shells.
-
-
-# func_append VAR VALUE
-# ---------------------
-# Append VALUE onto the existing contents of VAR.
-
-  # We should try to minimise forks, especially on Windows where they are
-  # unreasonably slow, so skip the feature probes when bash or zsh are
-  # being used:
-  if test set = "${BASH_VERSION+set}${ZSH_VERSION+set}"; then
-    : ${_G_HAVE_ARITH_OP="yes"}
-    : ${_G_HAVE_XSI_OPS="yes"}
-    # The += operator was introduced in bash 3.1
-    case $BASH_VERSION in
-      [12].* | 3.0 | 3.0*) ;;
-      *)
-        : ${_G_HAVE_PLUSEQ_OP="yes"}
-        ;;
-    esac
-  fi
-
-  # _G_HAVE_PLUSEQ_OP
-  # Can be empty, in which case the shell is probed, "yes" if += is
-  # useable or anything else if it does not work.
-  test -z "$_G_HAVE_PLUSEQ_OP" \
-    && (eval 'x=a; x+=" b"; test "a b" = "$x"') 2>/dev/null \
-    && _G_HAVE_PLUSEQ_OP=yes
-
-if test yes = "$_G_HAVE_PLUSEQ_OP"
-then
-  # This is an XSI compatible shell, allowing a faster implementation...
-  eval 'func_append ()
-  {
-    $debug_cmd
-
-    eval "$1+=\$2"
-  }'
-else
-  # ...otherwise fall back to using expr, which is often a shell builtin.
-  func_append ()
-  {
-    $debug_cmd
-
-    eval "$1=\$$1\$2"
-  }
-fi
-
-
-# func_append_quoted VAR VALUE
-# ----------------------------
-# Quote VALUE and append to the end of shell variable VAR, separated
-# by a space.
-if test yes = "$_G_HAVE_PLUSEQ_OP"; then
-  eval 'func_append_quoted ()
-  {
-    $debug_cmd
-
-    func_quote_for_eval "$2"
-    eval "$1+=\\ \$func_quote_for_eval_result"
-  }'
-else
-  func_append_quoted ()
-  {
-    $debug_cmd
-
-    func_quote_for_eval "$2"
-    eval "$1=\$$1\\ \$func_quote_for_eval_result"
-  }
-fi
-
-
-# func_append_uniq VAR VALUE
-# --------------------------
-# Append unique VALUE onto the existing contents of VAR, assuming
-# entries are delimited by the first character of VALUE.  For example:
-#
-#   func_append_uniq options " --another-option option-argument"
-#
-# will only append to $options if " --another-option option-argument "
-# is not already present somewhere in $options already (note spaces at
-# each end implied by leading space in second argument).
-func_append_uniq ()
-{
-    $debug_cmd
-
-    eval _G_current_value='`$ECHO $'$1'`'
-    _G_delim=`expr "$2" : '\(.\)'`
-
-    case $_G_delim$_G_current_value$_G_delim in
-      *"$2$_G_delim"*) ;;
-      *) func_append "$@" ;;
-    esac
-}
-
-
-# func_arith TERM...
-# ------------------
-# Set func_arith_result to the result of evaluating TERMs.
-  test -z "$_G_HAVE_ARITH_OP" \
-    && (eval 'test 2 = $(( 1 + 1 ))') 2>/dev/null \
-    && _G_HAVE_ARITH_OP=yes
-
-if test yes = "$_G_HAVE_ARITH_OP"; then
-  eval 'func_arith ()
-  {
-    $debug_cmd
-
-    func_arith_result=$(( $* ))
-  }'
-else
-  func_arith ()
-  {
-    $debug_cmd
-
-    func_arith_result=`expr "$@"`
-  }
-fi
-
-
-# func_basename FILE
-# ------------------
-# Set func_basename_result to FILE with everything up to and including
-# the last / stripped.
-if test yes = "$_G_HAVE_XSI_OPS"; then
-  # If this shell supports suffix pattern removal, then use it to avoid
-  # forking. Hide the definitions single quotes in case the shell chokes
-  # on unsupported syntax...
-  _b='func_basename_result=${1##*/}'
-  _d='case $1 in
-        */*) func_dirname_result=${1%/*}$2 ;;
-        *  ) func_dirname_result=$3        ;;
-      esac'
-
-else
-  # ...otherwise fall back to using sed.
-  _b='func_basename_result=`$ECHO "$1" |$SED "$sed_basename"`'
-  _d='func_dirname_result=`$ECHO "$1"  |$SED "$sed_dirname"`
-      if test "X$func_dirname_result" = "X$1"; then
-        func_dirname_result=$3
-      else
-        func_append func_dirname_result "$2"
-      fi'
-fi
-
-eval 'func_basename ()
-{
-    $debug_cmd
-
-    '"$_b"'
-}'
-
-
-# func_dirname FILE APPEND NONDIR_REPLACEMENT
-# -------------------------------------------
-# Compute the dirname of FILE.  If nonempty, add APPEND to the result,
-# otherwise set result to NONDIR_REPLACEMENT.
-eval 'func_dirname ()
-{
-    $debug_cmd
-
-    '"$_d"'
-}'
-
-
-# func_dirname_and_basename FILE APPEND NONDIR_REPLACEMENT
-# --------------------------------------------------------
-# Perform func_basename and func_dirname in a single function
-# call:
-#   dirname:  Compute the dirname of FILE.  If nonempty,
-#             add APPEND to the result, otherwise set result
-#             to NONDIR_REPLACEMENT.
-#             value returned in "$func_dirname_result"
-#   basename: Compute filename of FILE.
-#             value retuned in "$func_basename_result"
-# For efficiency, we do not delegate to the functions above but instead
-# duplicate the functionality here.
-eval 'func_dirname_and_basename ()
-{
-    $debug_cmd
-
-    '"$_b"'
-    '"$_d"'
-}'
-
-
-# func_echo ARG...
-# ----------------
-# Echo program name prefixed message.
-func_echo ()
-{
-    $debug_cmd
-
-    _G_message=$*
-
-    func_echo_IFS=$IFS
-    IFS=$nl
-    for _G_line in $_G_message; do
-      IFS=$func_echo_IFS
-      $ECHO "$progname: $_G_line"
-    done
-    IFS=$func_echo_IFS
-}
-
-
-# func_echo_all ARG...
-# --------------------
-# Invoke $ECHO with all args, space-separated.
-func_echo_all ()
-{
-    $ECHO "$*"
-}
-
-
-# func_echo_infix_1 INFIX ARG...
-# ------------------------------
-# Echo program name, followed by INFIX on the first line, with any
-# additional lines not showing INFIX.
-func_echo_infix_1 ()
-{
-    $debug_cmd
-
-    $require_term_colors
-
-    _G_infix=$1; shift
-    _G_indent=$_G_infix
-    _G_prefix="$progname: $_G_infix: "
-    _G_message=$*
-
-    # Strip color escape sequences before counting printable length
-    for _G_tc in "$tc_reset" "$tc_bold" "$tc_standout" "$tc_red" "$tc_green" "$tc_blue" "$tc_cyan"
-    do
-      test -n "$_G_tc" && {
-        _G_esc_tc=`$ECHO "$_G_tc" | $SED "$sed_make_literal_regex"`
-        _G_indent=`$ECHO "$_G_indent" | $SED "s|$_G_esc_tc||g"`
-      }
-    done
-    _G_indent="$progname: "`echo "$_G_indent" | $SED 's|.| |g'`"  " ## exclude from sc_prohibit_nested_quotes
-
-    func_echo_infix_1_IFS=$IFS
-    IFS=$nl
-    for _G_line in $_G_message; do
-      IFS=$func_echo_infix_1_IFS
-      $ECHO "$_G_prefix$tc_bold$_G_line$tc_reset" >&2
-      _G_prefix=$_G_indent
-    done
-    IFS=$func_echo_infix_1_IFS
-}
-
-
-# func_error ARG...
-# -----------------
-# Echo program name prefixed message to standard error.
-func_error ()
-{
-    $debug_cmd
-
-    $require_term_colors
-
-    func_echo_infix_1 "  $tc_standout${tc_red}error$tc_reset" "$*" >&2
-}
-
-
-# func_fatal_error ARG...
-# -----------------------
-# Echo program name prefixed message to standard error, and exit.
-func_fatal_error ()
-{
-    $debug_cmd
-
-    func_error "$*"
-    exit $EXIT_FAILURE
-}
-
-
-# func_grep EXPRESSION FILENAME
-# -----------------------------
+# func_grep expression filename
 # Check whether EXPRESSION matches any line of FILENAME, without output.
 func_grep ()
 {
-    $debug_cmd
-
     $GREP "$1" "$2" >/dev/null 2>&1
 }
 
 
-# func_len STRING
-# ---------------
-# Set func_len_result to the length of STRING. STRING may not
-# start with a hyphen.
-  test -z "$_G_HAVE_XSI_OPS" \
-    && (eval 'x=a/b/c;
-      test 5aa/bb/cc = "${#x}${x%%/*}${x%/*}${x#*/}${x##*/}"') 2>/dev/null \
-    && _G_HAVE_XSI_OPS=yes
-
-if test yes = "$_G_HAVE_XSI_OPS"; then
-  eval 'func_len ()
-  {
-    $debug_cmd
-
-    func_len_result=${#1}
-  }'
-else
-  func_len ()
-  {
-    $debug_cmd
-
-    func_len_result=`expr "$1" : ".*" 2>/dev/null || echo $max_cmd_len`
-  }
-fi
-
-
-# func_mkdir_p DIRECTORY-PATH
-# ---------------------------
+# func_mkdir_p directory-path
 # Make sure the entire path to DIRECTORY-PATH is available.
 func_mkdir_p ()
 {
-    $debug_cmd
-
-    _G_directory_path=$1
-    _G_dir_list=
+    my_directory_path="$1"
+    my_dir_list=
 
-    if test -n "$_G_directory_path" && test : != "$opt_dry_run"; then
+    if test -n "$my_directory_path" && test "$opt_dry_run" != ":"; then
 
-      # Protect directory names starting with '-'
-      case $_G_directory_path in
-        -*) _G_directory_path=./$_G_directory_path ;;
+      # Protect directory names starting with `-'
+      case $my_directory_path in
+        -*) my_directory_path="./$my_directory_path" ;;
       esac
 
       # While some portion of DIR does not yet exist...
-      while test ! -d "$_G_directory_path"; do
+      while test ! -d "$my_directory_path"; do
         # ...make a list in topmost first order.  Use a colon delimited
 	# list incase some portion of path contains whitespace.
-        _G_dir_list=$_G_directory_path:$_G_dir_list
+        my_dir_list="$my_directory_path:$my_dir_list"
 
         # If the last portion added has no slash in it, the list is done
-        case $_G_directory_path in */*) ;; *) break ;; esac
+        case $my_directory_path in */*) ;; *) break ;; esac
 
         # ...otherwise throw away the child directory and loop
-        _G_directory_path=`$ECHO "$_G_directory_path" | $SED -e "$sed_dirname"`
+        my_directory_path=`$ECHO "$my_directory_path" | $SED -e "$dirname"`
       done
-      _G_dir_list=`$ECHO "$_G_dir_list" | $SED 's|:*$||'`
+      my_dir_list=`$ECHO "$my_dir_list" | $SED 's,:*$,,'`
 
-      func_mkdir_p_IFS=$IFS; IFS=:
-      for _G_dir in $_G_dir_list; do
-	IFS=$func_mkdir_p_IFS
-        # mkdir can fail with a 'File exist' error if two processes
+      save_mkdir_p_IFS="$IFS"; IFS=':'
+      for my_dir in $my_dir_list; do
+	IFS="$save_mkdir_p_IFS"
+        # mkdir can fail with a `File exist' error if two processes
         # try to create one of the directories concurrently.  Don't
         # stop in that case!
-        $MKDIR "$_G_dir" 2>/dev/null || :
+        $MKDIR "$my_dir" 2>/dev/null || :
       done
-      IFS=$func_mkdir_p_IFS
+      IFS="$save_mkdir_p_IFS"
 
       # Bail out if we (or some other process) failed to create a directory.
-      test -d "$_G_directory_path" || \
-        func_fatal_error "Failed to create '$1'"
+      test -d "$my_directory_path" || \
+        func_fatal_error "Failed to create \`$1'"
     fi
 }
 
 
-# func_mktempdir [BASENAME]
-# -------------------------
+# func_mktempdir [string]
 # Make a temporary directory that won't clash with other running
 # libtool processes, and avoids race conditions if possible.  If
-# given, BASENAME is the basename for that directory.
+# given, STRING is the basename for that directory.
 func_mktempdir ()
 {
-    $debug_cmd
+    my_template="${TMPDIR-/tmp}/${1-$progname}"
 
-    _G_template=${TMPDIR-/tmp}/${1-$progname}
-
-    if test : = "$opt_dry_run"; then
+    if test "$opt_dry_run" = ":"; then
       # Return a directory name, but don't create it in dry-run mode
-      _G_tmpdir=$_G_template-$$
+      my_tmpdir="${my_template}-$$"
     else
 
       # If mktemp works, use that first and foremost
-      _G_tmpdir=`mktemp -d "$_G_template-XXXXXXXX" 2>/dev/null`
+      my_tmpdir=`mktemp -d "${my_template}-XXXXXXXX" 2>/dev/null`
 
-      if test ! -d "$_G_tmpdir"; then
+      if test ! -d "$my_tmpdir"; then
         # Failing that, at least try and use $RANDOM to avoid a race
-        _G_tmpdir=$_G_template-${RANDOM-0}$$
+        my_tmpdir="${my_template}-${RANDOM-0}$$"
 
-        func_mktempdir_umask=`umask`
+        save_mktempdir_umask=`umask`
         umask 0077
-        $MKDIR "$_G_tmpdir"
-        umask $func_mktempdir_umask
+        $MKDIR "$my_tmpdir"
+        umask $save_mktempdir_umask
       fi
 
       # If we're not in dry-run mode, bomb out on failure
-      test -d "$_G_tmpdir" || \
-        func_fatal_error "cannot create temporary directory '$_G_tmpdir'"
-    fi
-
-    $ECHO "$_G_tmpdir"
-}
-
-
-# func_normal_abspath PATH
-# ------------------------
-# Remove doubled-up and trailing slashes, "." path components,
-# and cancel out any ".." path components in PATH after making
-# it an absolute path.
-func_normal_abspath ()
-{
-    $debug_cmd
-
-    # These SED scripts presuppose an absolute path with a trailing slash.
-    _G_pathcar='s|^/\([^/]*\).*$|\1|'
-    _G_pathcdr='s|^/[^/]*||'
-    _G_removedotparts=':dotsl
-		s|/\./|/|g
-		t dotsl
-		s|/\.$|/|'
-    _G_collapseslashes='s|/\{1,\}|/|g'
-    _G_finalslash='s|/*$|/|'
-
-    # Start from root dir and reassemble the path.
-    func_normal_abspath_result=
-    func_normal_abspath_tpath=$1
-    func_normal_abspath_altnamespace=
-    case $func_normal_abspath_tpath in
-      "")
-        # Empty path, that just means $cwd.
-        func_stripname '' '/' "`pwd`"
-        func_normal_abspath_result=$func_stripname_result
-        return
-        ;;
-      # The next three entries are used to spot a run of precisely
-      # two leading slashes without using negated character classes;
-      # we take advantage of case's first-match behaviour.
-      ///*)
-        # Unusual form of absolute path, do nothing.
-        ;;
-      //*)
-        # Not necessarily an ordinary path; POSIX reserves leading '//'
-        # and for example Cygwin uses it to access remote file shares
-        # over CIFS/SMB, so we conserve a leading double slash if found.
-        func_normal_abspath_altnamespace=/
-        ;;
-      /*)
-        # Absolute path, do nothing.
-        ;;
-      *)
-        # Relative path, prepend $cwd.
-        func_normal_abspath_tpath=`pwd`/$func_normal_abspath_tpath
-        ;;
-    esac
-
-    # Cancel out all the simple stuff to save iterations.  We also want
-    # the path to end with a slash for ease of parsing, so make sure
-    # there is one (and only one) here.
-    func_normal_abspath_tpath=`$ECHO "$func_normal_abspath_tpath" | $SED \
-          -e "$_G_removedotparts" -e "$_G_collapseslashes" -e "$_G_finalslash"`
-    while :; do
-      # Processed it all yet?
-      if test / = "$func_normal_abspath_tpath"; then
-        # If we ascended to the root using ".." the result may be empty now.
-        if test -z "$func_normal_abspath_result"; then
-          func_normal_abspath_result=/
-        fi
-        break
-      fi
-      func_normal_abspath_tcomponent=`$ECHO "$func_normal_abspath_tpath" | $SED \
-          -e "$_G_pathcar"`
-      func_normal_abspath_tpath=`$ECHO "$func_normal_abspath_tpath" | $SED \
-          -e "$_G_pathcdr"`
-      # Figure out what to do with it
-      case $func_normal_abspath_tcomponent in
-        "")
-          # Trailing empty path component, ignore it.
-          ;;
-        ..)
-          # Parent dir; strip last assembled component from result.
-          func_dirname "$func_normal_abspath_result"
-          func_normal_abspath_result=$func_dirname_result
-          ;;
-        *)
-          # Actual path component, append it.
-          func_append func_normal_abspath_result "/$func_normal_abspath_tcomponent"
-          ;;
-      esac
-    done
-    # Restore leading double-slash if one was found on entry.
-    func_normal_abspath_result=$func_normal_abspath_altnamespace$func_normal_abspath_result
-}
-
-
-# func_notquiet ARG...
-# --------------------
-# Echo program name prefixed message only when not in quiet mode.
-func_notquiet ()
-{
-    $debug_cmd
-
-    $opt_quiet || func_echo ${1+"$@"}
-
-    # A bug in bash halts the script if the last line of a function
-    # fails when set -e is in force, so we need another command to
-    # work around that:
-    :
-}
-
-
-# func_relative_path SRCDIR DSTDIR
-# --------------------------------
-# Set func_relative_path_result to the relative path from SRCDIR to DSTDIR.
-func_relative_path ()
-{
-    $debug_cmd
-
-    func_relative_path_result=
-    func_normal_abspath "$1"
-    func_relative_path_tlibdir=$func_normal_abspath_result
-    func_normal_abspath "$2"
-    func_relative_path_tbindir=$func_normal_abspath_result
-
-    # Ascend the tree starting from libdir
-    while :; do
-      # check if we have found a prefix of bindir
-      case $func_relative_path_tbindir in
-        $func_relative_path_tlibdir)
-          # found an exact match
-          func_relative_path_tcancelled=
-          break
-          ;;
-        $func_relative_path_tlibdir*)
-          # found a matching prefix
-          func_stripname "$func_relative_path_tlibdir" '' "$func_relative_path_tbindir"
-          func_relative_path_tcancelled=$func_stripname_result
-          if test -z "$func_relative_path_result"; then
-            func_relative_path_result=.
-          fi
-          break
-          ;;
-        *)
-          func_dirname $func_relative_path_tlibdir
-          func_relative_path_tlibdir=$func_dirname_result
-          if test -z "$func_relative_path_tlibdir"; then
-            # Have to descend all the way to the root!
-            func_relative_path_result=../$func_relative_path_result
-            func_relative_path_tcancelled=$func_relative_path_tbindir
-            break
-          fi
-          func_relative_path_result=../$func_relative_path_result
-          ;;
-      esac
-    done
-
-    # Now calculate path; take care to avoid doubling-up slashes.
-    func_stripname '' '/' "$func_relative_path_result"
-    func_relative_path_result=$func_stripname_result
-    func_stripname '/' '/' "$func_relative_path_tcancelled"
-    if test -n "$func_stripname_result"; then
-      func_append func_relative_path_result "/$func_stripname_result"
-    fi
-
-    # Normalisation. If bindir is libdir, return '.' else relative path.
-    if test -n "$func_relative_path_result"; then
-      func_stripname './' '' "$func_relative_path_result"
-      func_relative_path_result=$func_stripname_result
-    fi
-
-    test -n "$func_relative_path_result" || func_relative_path_result=.
-
-    :
-}
-
-
-# func_quote_for_eval ARG...
-# --------------------------
-# Aesthetically quote ARGs to be evaled later.
-# This function returns two values:
-#   i) func_quote_for_eval_result
-#      double-quoted, suitable for a subsequent eval
-#  ii) func_quote_for_eval_unquoted_result
-#      has all characters that are still active within double
-#      quotes backslashified.
-func_quote_for_eval ()
-{
-    $debug_cmd
-
-    func_quote_for_eval_unquoted_result=
-    func_quote_for_eval_result=
-    while test 0 -lt $#; do
-      case $1 in
-        *[\\\`\"\$]*)
-	  _G_unquoted_arg=`printf '%s\n' "$1" |$SED "$sed_quote_subst"` ;;
-        *)
-          _G_unquoted_arg=$1 ;;
-      esac
-      if test -n "$func_quote_for_eval_unquoted_result"; then
-	func_append func_quote_for_eval_unquoted_result " $_G_unquoted_arg"
-      else
-        func_append func_quote_for_eval_unquoted_result "$_G_unquoted_arg"
-      fi
-
-      case $_G_unquoted_arg in
-        # Double-quote args containing shell metacharacters to delay
-        # word splitting, command substitution and variable expansion
-        # for a subsequent eval.
-        # Many Bourne shells cannot handle close brackets correctly
-        # in scan sets, so we specify it separately.
-        *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \	]*|*]*|"")
-          _G_quoted_arg=\"$_G_unquoted_arg\"
-          ;;
-        *)
-          _G_quoted_arg=$_G_unquoted_arg
-	  ;;
-      esac
-
-      if test -n "$func_quote_for_eval_result"; then
-	func_append func_quote_for_eval_result " $_G_quoted_arg"
-      else
-        func_append func_quote_for_eval_result "$_G_quoted_arg"
-      fi
-      shift
-    done
-}
-
-
-# func_quote_for_expand ARG
-# -------------------------
-# Aesthetically quote ARG to be evaled later; same as above,
-# but do not quote variable references.
-func_quote_for_expand ()
-{
-    $debug_cmd
-
-    case $1 in
-      *[\\\`\"]*)
-	_G_arg=`$ECHO "$1" | $SED \
-	    -e "$sed_double_quote_subst" -e "$sed_double_backslash"` ;;
-      *)
-        _G_arg=$1 ;;
-    esac
-
-    case $_G_arg in
-      # Double-quote args containing shell metacharacters to delay
-      # word splitting and command substitution for a subsequent eval.
-      # Many Bourne shells cannot handle close brackets correctly
-      # in scan sets, so we specify it separately.
-      *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \	]*|*]*|"")
-        _G_arg=\"$_G_arg\"
-        ;;
-    esac
-
-    func_quote_for_expand_result=$_G_arg
-}
-
-
-# func_stripname PREFIX SUFFIX NAME
-# ---------------------------------
-# strip PREFIX and SUFFIX from NAME, and store in func_stripname_result.
-# PREFIX and SUFFIX must not contain globbing or regex special
-# characters, hashes, percent signs, but SUFFIX may contain a leading
-# dot (in which case that matches only a dot).
-if test yes = "$_G_HAVE_XSI_OPS"; then
-  eval 'func_stripname ()
-  {
-    $debug_cmd
-
-    # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are
-    # positional parameters, so assign one to ordinary variable first.
-    func_stripname_result=$3
-    func_stripname_result=${func_stripname_result#"$1"}
-    func_stripname_result=${func_stripname_result%"$2"}
-  }'
-else
-  func_stripname ()
-  {
-    $debug_cmd
-
-    case $2 in
-      .*) func_stripname_result=`$ECHO "$3" | $SED -e "s%^$1%%" -e "s%\\\\$2\$%%"`;;
-      *)  func_stripname_result=`$ECHO "$3" | $SED -e "s%^$1%%" -e "s%$2\$%%"`;;
-    esac
-  }
-fi
-
-
-# func_show_eval CMD [FAIL_EXP]
-# -----------------------------
-# Unless opt_quiet is true, then output CMD.  Then, if opt_dryrun is
-# not true, evaluate CMD.  If the evaluation of CMD fails, and FAIL_EXP
-# is given, then evaluate it.
-func_show_eval ()
-{
-    $debug_cmd
-
-    _G_cmd=$1
-    _G_fail_exp=${2-':'}
-
-    func_quote_for_expand "$_G_cmd"
-    eval "func_notquiet $func_quote_for_expand_result"
-
-    $opt_dry_run || {
-      eval "$_G_cmd"
-      _G_status=$?
-      if test 0 -ne "$_G_status"; then
-	eval "(exit $_G_status); $_G_fail_exp"
-      fi
-    }
-}
-
-
-# func_show_eval_locale CMD [FAIL_EXP]
-# ------------------------------------
-# Unless opt_quiet is true, then output CMD.  Then, if opt_dryrun is
-# not true, evaluate CMD.  If the evaluation of CMD fails, and FAIL_EXP
-# is given, then evaluate it.  Use the saved locale for evaluation.
-func_show_eval_locale ()
-{
-    $debug_cmd
-
-    _G_cmd=$1
-    _G_fail_exp=${2-':'}
-
-    $opt_quiet || {
-      func_quote_for_expand "$_G_cmd"
-      eval "func_echo $func_quote_for_expand_result"
-    }
-
-    $opt_dry_run || {
-      eval "$_G_user_locale
-	    $_G_cmd"
-      _G_status=$?
-      eval "$_G_safe_locale"
-      if test 0 -ne "$_G_status"; then
-	eval "(exit $_G_status); $_G_fail_exp"
-      fi
-    }
-}
-
-
-# func_tr_sh
-# ----------
-# Turn $1 into a string suitable for a shell variable name.
-# Result is stored in $func_tr_sh_result.  All characters
-# not in the set a-zA-Z0-9_ are replaced with '_'. Further,
-# if $1 begins with a digit, a '_' is prepended as well.
-func_tr_sh ()
-{
-    $debug_cmd
-
-    case $1 in
-    [0-9]* | *[!a-zA-Z0-9_]*)
-      func_tr_sh_result=`$ECHO "$1" | $SED -e 's/^\([0-9]\)/_\1/' -e 's/[^a-zA-Z0-9_]/_/g'`
-      ;;
-    * )
-      func_tr_sh_result=$1
-      ;;
-    esac
-}
-
-
-# func_verbose ARG...
-# -------------------
-# Echo program name prefixed message in verbose mode only.
-func_verbose ()
-{
-    $debug_cmd
-
-    $opt_verbose && func_echo "$*"
-
-    :
-}
-
-
-# func_warn_and_continue ARG...
-# -----------------------------
-# Echo program name prefixed warning message to standard error.
-func_warn_and_continue ()
-{
-    $debug_cmd
-
-    $require_term_colors
-
-    func_echo_infix_1 "${tc_red}warning$tc_reset" "$*" >&2
-}
-
-
-# func_warning CATEGORY ARG...
-# ----------------------------
-# Echo program name prefixed warning message to standard error. Warning
-# messages can be filtered according to CATEGORY, where this function
-# elides messages where CATEGORY is not listed in the global variable
-# 'opt_warning_types'.
-func_warning ()
-{
-    $debug_cmd
-
-    # CATEGORY must be in the warning_categories list!
-    case " $warning_categories " in
-      *" $1 "*) ;;
-      *) func_internal_error "invalid warning category '$1'" ;;
-    esac
-
-    _G_category=$1
-    shift
-
-    case " $opt_warning_types " in
-      *" $_G_category "*) $warning_func ${1+"$@"} ;;
-    esac
-}
-
-
-# func_sort_ver VER1 VER2
-# -----------------------
-# 'sort -V' is not generally available.
-# Note this deviates from the version comparison in automake
-# in that it treats 1.5 < 1.5.0, and treats 1.4.4a < 1.4-p3a
-# but this should suffice as we won't be specifying old
-# version formats or redundant trailing .0 in bootstrap.conf.
-# If we did want full compatibility then we should probably
-# use m4_version_compare from autoconf.
-func_sort_ver ()
-{
-    $debug_cmd
-
-    printf '%s\n%s\n' "$1" "$2" \
-      | sort -t. -k 1,1n -k 2,2n -k 3,3n -k 4,4n -k 5,5n -k 6,6n -k 7,7n -k 8,8n -k 9,9n
-}
-
-# func_lt_ver PREV CURR
-# ---------------------
-# Return true if PREV and CURR are in the correct order according to
-# func_sort_ver, otherwise false.  Use it like this:
-#
-#  func_lt_ver "$prev_ver" "$proposed_ver" || func_fatal_error "..."
-func_lt_ver ()
-{
-    $debug_cmd
-
-    test "x$1" = x`func_sort_ver "$1" "$2" | $SED 1q`
-}
-
-
-# Local variables:
-# mode: shell-script
-# sh-indentation: 2
-# eval: (add-hook 'before-save-hook 'time-stamp)
-# time-stamp-pattern: "10/scriptversion=%:y-%02m-%02d.%02H; # UTC"
-# time-stamp-time-zone: "UTC"
-# End:
-#! /bin/sh
-
-# Set a version string for this script.
-scriptversion=2014-01-07.03; # UTC
-
-# A portable, pluggable option parser for Bourne shell.
-# Written by Gary V. Vaughan, 2010
-
-# Copyright (C) 2010-2015 Free Software Foundation, Inc.
-# This is free software; see the source for copying conditions.  There is NO
-# warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-
-# You should have received a copy of the GNU General Public License
-# along with this program.  If not, see <http://www.gnu.org/licenses/>.
-
-# Please report bugs or propose patches to gary at gnu.org.
-
-
-## ------ ##
-## Usage. ##
-## ------ ##
-
-# This file is a library for parsing options in your shell scripts along
-# with assorted other useful supporting features that you can make use
-# of too.
-#
-# For the simplest scripts you might need only:
-#
-#   #!/bin/sh
-#   . relative/path/to/funclib.sh
-#   . relative/path/to/options-parser
-#   scriptversion=1.0
-#   func_options ${1+"$@"}
-#   eval set dummy "$func_options_result"; shift
-#   ...rest of your script...
-#
-# In order for the '--version' option to work, you will need to have a
-# suitably formatted comment like the one at the top of this file
-# starting with '# Written by ' and ending with '# warranty; '.
-#
-# For '-h' and '--help' to work, you will also need a one line
-# description of your script's purpose in a comment directly above the
-# '# Written by ' line, like the one at the top of this file.
-#
-# The default options also support '--debug', which will turn on shell
-# execution tracing (see the comment above debug_cmd below for another
-# use), and '--verbose' and the func_verbose function to allow your script
-# to display verbose messages only when your user has specified
-# '--verbose'.
-#
-# After sourcing this file, you can plug processing for additional
-# options by amending the variables from the 'Configuration' section
-# below, and following the instructions in the 'Option parsing'
-# section further down.
-
-## -------------- ##
-## Configuration. ##
-## -------------- ##
-
-# You should override these variables in your script after sourcing this
-# file so that they reflect the customisations you have added to the
-# option parser.
-
-# The usage line for option parsing errors and the start of '-h' and
-# '--help' output messages. You can embed shell variables for delayed
-# expansion at the time the message is displayed, but you will need to
-# quote other shell meta-characters carefully to prevent them being
-# expanded when the contents are evaled.
-usage='$progpath [OPTION]...'
-
-# Short help message in response to '-h' and '--help'.  Add to this or
-# override it after sourcing this library to reflect the full set of
-# options your script accepts.
-usage_message="\
-       --debug        enable verbose shell tracing
-   -W, --warnings=CATEGORY
-                      report the warnings falling in CATEGORY [all]
-   -v, --verbose      verbosely report processing
-       --version      print version information and exit
-   -h, --help         print short or long help message and exit
-"
-
-# Additional text appended to 'usage_message' in response to '--help'.
-long_help_message="
-Warning categories include:
-       'all'          show all warnings
-       'none'         turn off all the warnings
-       'error'        warnings are treated as fatal errors"
-
-# Help message printed before fatal option parsing errors.
-fatal_help="Try '\$progname --help' for more information."
-
-
-
-## ------------------------- ##
-## Hook function management. ##
-## ------------------------- ##
-
-# This section contains functions for adding, removing, and running hooks
-# to the main code.  A hook is just a named list of of function, that can
-# be run in order later on.
-
-# func_hookable FUNC_NAME
-# -----------------------
-# Declare that FUNC_NAME will run hooks added with
-# 'func_add_hook FUNC_NAME ...'.
-func_hookable ()
-{
-    $debug_cmd
-
-    func_append hookable_fns " $1"
-}
-
-
-# func_add_hook FUNC_NAME HOOK_FUNC
-# ---------------------------------
-# Request that FUNC_NAME call HOOK_FUNC before it returns.  FUNC_NAME must
-# first have been declared "hookable" by a call to 'func_hookable'.
-func_add_hook ()
-{
-    $debug_cmd
-
-    case " $hookable_fns " in
-      *" $1 "*) ;;
-      *) func_fatal_error "'$1' does not accept hook functions." ;;
-    esac
-
-    eval func_append ${1}_hooks '" $2"'
-}
-
-
-# func_remove_hook FUNC_NAME HOOK_FUNC
-# ------------------------------------
-# Remove HOOK_FUNC from the list of functions called by FUNC_NAME.
-func_remove_hook ()
-{
-    $debug_cmd
-
-    eval ${1}_hooks='`$ECHO "\$'$1'_hooks" |$SED "s| '$2'||"`'
-}
-
-
-# func_run_hooks FUNC_NAME [ARG]...
-# ---------------------------------
-# Run all hook functions registered to FUNC_NAME.
-# It is assumed that the list of hook functions contains nothing more
-# than a whitespace-delimited list of legal shell function names, and
-# no effort is wasted trying to catch shell meta-characters or preserve
-# whitespace.
-func_run_hooks ()
-{
-    $debug_cmd
-
-    case " $hookable_fns " in
-      *" $1 "*) ;;
-      *) func_fatal_error "'$1' does not support hook funcions.n" ;;
-    esac
-
-    eval _G_hook_fns=\$$1_hooks; shift
-
-    for _G_hook in $_G_hook_fns; do
-      eval $_G_hook '"$@"'
-
-      # store returned options list back into positional
-      # parameters for next 'cmd' execution.
-      eval _G_hook_result=\$${_G_hook}_result
-      eval set dummy "$_G_hook_result"; shift
-    done
-
-    func_quote_for_eval ${1+"$@"}
-    func_run_hooks_result=$func_quote_for_eval_result
-}
-
-
-
-## --------------- ##
-## Option parsing. ##
-## --------------- ##
-
-# In order to add your own option parsing hooks, you must accept the
-# full positional parameter list in your hook function, remove any
-# options that you action, and then pass back the remaining unprocessed
-# options in '<hooked_function_name>_result', escaped suitably for
-# 'eval'.  Like this:
-#
-#    my_options_prep ()
-#    {
-#        $debug_cmd
-#
-#        # Extend the existing usage message.
-#        usage_message=$usage_message'
-#      -s, --silent       don'\''t print informational messages
-#    '
-#
-#        func_quote_for_eval ${1+"$@"}
-#        my_options_prep_result=$func_quote_for_eval_result
-#    }
-#    func_add_hook func_options_prep my_options_prep
-#
-#
-#    my_silent_option ()
-#    {
-#        $debug_cmd
-#
-#        # Note that for efficiency, we parse as many options as we can
-#        # recognise in a loop before passing the remainder back to the
-#        # caller on the first unrecognised argument we encounter.
-#        while test $# -gt 0; do
-#          opt=$1; shift
-#          case $opt in
-#            --silent|-s) opt_silent=: ;;
-#            # Separate non-argument short options:
-#            -s*)         func_split_short_opt "$_G_opt"
-#                         set dummy "$func_split_short_opt_name" \
-#                             "-$func_split_short_opt_arg" ${1+"$@"}
-#                         shift
-#                         ;;
-#            *)            set dummy "$_G_opt" "$*"; shift; break ;;
-#          esac
-#        done
-#
-#        func_quote_for_eval ${1+"$@"}
-#        my_silent_option_result=$func_quote_for_eval_result
-#    }
-#    func_add_hook func_parse_options my_silent_option
-#
-#
-#    my_option_validation ()
-#    {
-#        $debug_cmd
-#
-#        $opt_silent && $opt_verbose && func_fatal_help "\
-#    '--silent' and '--verbose' options are mutually exclusive."
-#
-#        func_quote_for_eval ${1+"$@"}
-#        my_option_validation_result=$func_quote_for_eval_result
-#    }
-#    func_add_hook func_validate_options my_option_validation
-#
-# You'll alse need to manually amend $usage_message to reflect the extra
-# options you parse.  It's preferable to append if you can, so that
-# multiple option parsing hooks can be added safely.
-
-
-# func_options [ARG]...
-# ---------------------
-# All the functions called inside func_options are hookable. See the
-# individual implementations for details.
-func_hookable func_options
-func_options ()
-{
-    $debug_cmd
-
-    func_options_prep ${1+"$@"}
-    eval func_parse_options \
-        ${func_options_prep_result+"$func_options_prep_result"}
-    eval func_validate_options \
-        ${func_parse_options_result+"$func_parse_options_result"}
-
-    eval func_run_hooks func_options \
-        ${func_validate_options_result+"$func_validate_options_result"}
+      test -d "$my_tmpdir" || \
+        func_fatal_error "cannot create temporary directory \`$my_tmpdir'"
+    fi
 
-    # save modified positional parameters for caller
-    func_options_result=$func_run_hooks_result
+    $ECHO "$my_tmpdir"
 }
 
 
-# func_options_prep [ARG]...
-# --------------------------
-# All initialisations required before starting the option parse loop.
-# Note that when calling hook functions, we pass through the list of
-# positional parameters.  If a hook function modifies that list, and
-# needs to propogate that back to rest of this script, then the complete
-# modified list must be put in 'func_run_hooks_result' before
-# returning.
-func_hookable func_options_prep
-func_options_prep ()
+# func_quote_for_eval arg
+# Aesthetically quote ARG to be evaled later.
+# This function returns two values: FUNC_QUOTE_FOR_EVAL_RESULT
+# is double-quoted, suitable for a subsequent eval, whereas
+# FUNC_QUOTE_FOR_EVAL_UNQUOTED_RESULT has merely all characters
+# which are still active within double quotes backslashified.
+func_quote_for_eval ()
 {
-    $debug_cmd
-
-    # Option defaults:
-    opt_verbose=false
-    opt_warning_types=
-
-    func_run_hooks func_options_prep ${1+"$@"}
+    case $1 in
+      *[\\\`\"\$]*)
+	func_quote_for_eval_unquoted_result=`$ECHO "$1" | $SED "$sed_quote_subst"` ;;
+      *)
+        func_quote_for_eval_unquoted_result="$1" ;;
+    esac
 
-    # save modified positional parameters for caller
-    func_options_prep_result=$func_run_hooks_result
+    case $func_quote_for_eval_unquoted_result in
+      # Double-quote args containing shell metacharacters to delay
+      # word splitting, command substitution and and variable
+      # expansion for a subsequent eval.
+      # Many Bourne shells cannot handle close brackets correctly
+      # in scan sets, so we specify it separately.
+      *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \	]*|*]*|"")
+        func_quote_for_eval_result="\"$func_quote_for_eval_unquoted_result\""
+        ;;
+      *)
+        func_quote_for_eval_result="$func_quote_for_eval_unquoted_result"
+    esac
 }
 
 
-# func_parse_options [ARG]...
-# ---------------------------
-# The main option parsing loop.
-func_hookable func_parse_options
-func_parse_options ()
+# func_quote_for_expand arg
+# Aesthetically quote ARG to be evaled later; same as above,
+# but do not quote variable references.
+func_quote_for_expand ()
 {
-    $debug_cmd
-
-    func_parse_options_result=
+    case $1 in
+      *[\\\`\"]*)
+	my_arg=`$ECHO "$1" | $SED \
+	    -e "$double_quote_subst" -e "$sed_double_backslash"` ;;
+      *)
+        my_arg="$1" ;;
+    esac
 
-    # this just eases exit handling
-    while test $# -gt 0; do
-      # Defer to hook functions for initial option parsing, so they
-      # get priority in the event of reusing an option name.
-      func_run_hooks func_parse_options ${1+"$@"}
+    case $my_arg in
+      # Double-quote args containing shell metacharacters to delay
+      # word splitting and command substitution for a subsequent eval.
+      # Many Bourne shells cannot handle close brackets correctly
+      # in scan sets, so we specify it separately.
+      *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \	]*|*]*|"")
+        my_arg="\"$my_arg\""
+        ;;
+    esac
 
-      # Adjust func_parse_options positional parameters to match
-      eval set dummy "$func_run_hooks_result"; shift
+    func_quote_for_expand_result="$my_arg"
+}
 
-      # Break out of the loop if we already parsed every option.
-      test $# -gt 0 || break
 
-      _G_opt=$1
-      shift
-      case $_G_opt in
-        --debug|-x)   debug_cmd='set -x'
-                      func_echo "enabling shell trace mode"
-                      $debug_cmd
-                      ;;
-
-        --no-warnings|--no-warning|--no-warn)
-                      set dummy --warnings none ${1+"$@"}
-                      shift
-		      ;;
+# func_show_eval cmd [fail_exp]
+# Unless opt_silent is true, then output CMD.  Then, if opt_dryrun is
+# not true, evaluate CMD.  If the evaluation of CMD fails, and FAIL_EXP
+# is given, then evaluate it.
+func_show_eval ()
+{
+    my_cmd="$1"
+    my_fail_exp="${2-:}"
 
-        --warnings|--warning|-W)
-                      test $# = 0 && func_missing_arg $_G_opt && break
-                      case " $warning_categories $1" in
-                        *" $1 "*)
-                          # trailing space prevents matching last $1 above
-                          func_append_uniq opt_warning_types " $1"
-                          ;;
-                        *all)
-                          opt_warning_types=$warning_categories
-                          ;;
-                        *none)
-                          opt_warning_types=none
-                          warning_func=:
-                          ;;
-                        *error)
-                          opt_warning_types=$warning_categories
-                          warning_func=func_fatal_error
-                          ;;
-                        *)
-                          func_fatal_error \
-                             "unsupported warning category: '$1'"
-                          ;;
-                      esac
-                      shift
-                      ;;
-
-        --verbose|-v) opt_verbose=: ;;
-        --version)    func_version ;;
-        -\?|-h)       func_usage ;;
-        --help)       func_help ;;
-
-	# Separate optargs to long options (plugins may need this):
-	--*=*)        func_split_equals "$_G_opt"
-	              set dummy "$func_split_equals_lhs" \
-                          "$func_split_equals_rhs" ${1+"$@"}
-                      shift
-                      ;;
-
-       # Separate optargs to short options:
-        -W*)
-                      func_split_short_opt "$_G_opt"
-                      set dummy "$func_split_short_opt_name" \
-                          "$func_split_short_opt_arg" ${1+"$@"}
-                      shift
-                      ;;
-
-        # Separate non-argument short options:
-        -\?*|-h*|-v*|-x*)
-                      func_split_short_opt "$_G_opt"
-                      set dummy "$func_split_short_opt_name" \
-                          "-$func_split_short_opt_arg" ${1+"$@"}
-                      shift
-                      ;;
-
-        --)           break ;;
-        -*)           func_fatal_help "unrecognised option: '$_G_opt'" ;;
-        *)            set dummy "$_G_opt" ${1+"$@"}; shift; break ;;
-      esac
-    done
+    ${opt_silent-false} || {
+      func_quote_for_expand "$my_cmd"
+      eval "func_echo $func_quote_for_expand_result"
+    }
 
-    # save modified positional parameters for caller
-    func_quote_for_eval ${1+"$@"}
-    func_parse_options_result=$func_quote_for_eval_result
+    if ${opt_dry_run-false}; then :; else
+      eval "$my_cmd"
+      my_status=$?
+      if test "$my_status" -eq 0; then :; else
+	eval "(exit $my_status); $my_fail_exp"
+      fi
+    fi
 }
 
 
-# func_validate_options [ARG]...
-# ------------------------------
-# Perform any sanity checks on option settings and/or unconsumed
-# arguments.
-func_hookable func_validate_options
-func_validate_options ()
+# func_show_eval_locale cmd [fail_exp]
+# Unless opt_silent is true, then output CMD.  Then, if opt_dryrun is
+# not true, evaluate CMD.  If the evaluation of CMD fails, and FAIL_EXP
+# is given, then evaluate it.  Use the saved locale for evaluation.
+func_show_eval_locale ()
 {
-    $debug_cmd
-
-    # Display all warnings if -W was not given.
-    test -n "$opt_warning_types" || opt_warning_types=" $warning_categories"
+    my_cmd="$1"
+    my_fail_exp="${2-:}"
 
-    func_run_hooks func_validate_options ${1+"$@"}
-
-    # Bail if the options were screwed!
-    $exit_cmd $EXIT_FAILURE
+    ${opt_silent-false} || {
+      func_quote_for_expand "$my_cmd"
+      eval "func_echo $func_quote_for_expand_result"
+    }
 
-    # save modified positional parameters for caller
-    func_validate_options_result=$func_run_hooks_result
+    if ${opt_dry_run-false}; then :; else
+      eval "$lt_user_locale
+	    $my_cmd"
+      my_status=$?
+      eval "$lt_safe_locale"
+      if test "$my_status" -eq 0; then :; else
+	eval "(exit $my_status); $my_fail_exp"
+      fi
+    fi
 }
 
+# func_tr_sh
+# Turn $1 into a string suitable for a shell variable name.
+# Result is stored in $func_tr_sh_result.  All characters
+# not in the set a-zA-Z0-9_ are replaced with '_'. Further,
+# if $1 begins with a digit, a '_' is prepended as well.
+func_tr_sh ()
+{
+  case $1 in
+  [0-9]* | *[!a-zA-Z0-9_]*)
+    func_tr_sh_result=`$ECHO "$1" | $SED 's/^\([0-9]\)/_\1/; s/[^a-zA-Z0-9_]/_/g'`
+    ;;
+  * )
+    func_tr_sh_result=$1
+    ;;
+  esac
+}
 
 
-## ----------------- ##
-## Helper functions. ##
-## ----------------- ##
-
-# This section contains the helper functions used by the rest of the
-# hookable option parser framework in ascii-betical order.
+# func_version
+# Echo version message to standard output and exit.
+func_version ()
+{
+    $opt_debug
 
+    $SED -n '/(C)/!b go
+	:more
+	/\./!{
+	  N
+	  s/\n# / /
+	  b more
+	}
+	:go
+	/^# '$PROGRAM' (GNU /,/# warranty; / {
+        s/^# //
+	s/^# *$//
+        s/\((C)\)[ 0-9,-]*\( [1-9][0-9]*\)/\1\2/
+        p
+     }' < "$progpath"
+     exit $?
+}
 
-# func_fatal_help ARG...
-# ----------------------
-# Echo program name prefixed message to standard error, followed by
-# a help hint, and exit.
-func_fatal_help ()
+# func_usage
+# Echo short help message to standard output and exit.
+func_usage ()
 {
-    $debug_cmd
+    $opt_debug
 
-    eval \$ECHO \""Usage: $usage"\"
-    eval \$ECHO \""$fatal_help"\"
-    func_error ${1+"$@"}
-    exit $EXIT_FAILURE
+    $SED -n '/^# Usage:/,/^#  *.*--help/ {
+        s/^# //
+	s/^# *$//
+	s/\$progname/'$progname'/
+	p
+    }' < "$progpath"
+    echo
+    $ECHO "run \`$progname --help | more' for full usage"
+    exit $?
 }
 
-
-# func_help
-# ---------
-# Echo long help message to standard output and exit.
+# func_help [NOEXIT]
+# Echo long help message to standard output and exit,
+# unless 'noexit' is passed as argument.
 func_help ()
 {
-    $debug_cmd
-
-    func_usage_message
-    $ECHO "$long_help_message"
-    exit 0
+    $opt_debug
+
+    $SED -n '/^# Usage:/,/# Report bugs to/ {
+	:print
+        s/^# //
+	s/^# *$//
+	s*\$progname*'$progname'*
+	s*\$host*'"$host"'*
+	s*\$SHELL*'"$SHELL"'*
+	s*\$LTCC*'"$LTCC"'*
+	s*\$LTCFLAGS*'"$LTCFLAGS"'*
+	s*\$LD*'"$LD"'*
+	s/\$with_gnu_ld/'"$with_gnu_ld"'/
+	s/\$automake_version/'"`(${AUTOMAKE-automake} --version) 2>/dev/null |$SED 1q`"'/
+	s/\$autoconf_version/'"`(${AUTOCONF-autoconf} --version) 2>/dev/null |$SED 1q`"'/
+	p
+	d
+     }
+     /^# .* home page:/b print
+     /^# General help using/b print
+     ' < "$progpath"
+    ret=$?
+    if test -z "$1"; then
+      exit $ret
+    fi
 }
 
-
-# func_missing_arg ARGNAME
-# ------------------------
+# func_missing_arg argname
 # Echo program name prefixed message to standard error and set global
 # exit_cmd.
 func_missing_arg ()
 {
-    $debug_cmd
+    $opt_debug
 
-    func_error "Missing argument for '$1'."
+    func_error "missing argument for $1."
     exit_cmd=exit
 }
 
 
-# func_split_equals STRING
-# ------------------------
-# Set func_split_equals_lhs and func_split_equals_rhs shell variables after
-# splitting STRING at the '=' sign.
-test -z "$_G_HAVE_XSI_OPS" \
-    && (eval 'x=a/b/c;
-      test 5aa/bb/cc = "${#x}${x%%/*}${x%/*}${x#*/}${x##*/}"') 2>/dev/null \
-    && _G_HAVE_XSI_OPS=yes
-
-if test yes = "$_G_HAVE_XSI_OPS"
-then
-  # This is an XSI compatible shell, allowing a faster implementation...
-  eval 'func_split_equals ()
-  {
-      $debug_cmd
-
-      func_split_equals_lhs=${1%%=*}
-      func_split_equals_rhs=${1#*=}
-      test "x$func_split_equals_lhs" = "x$1" \
-        && func_split_equals_rhs=
-  }'
-else
-  # ...otherwise fall back to using expr, which is often a shell builtin.
-  func_split_equals ()
-  {
-      $debug_cmd
-
-      func_split_equals_lhs=`expr "x$1" : 'x\([^=]*\)'`
-      func_split_equals_rhs=
-      test "x$func_split_equals_lhs" = "x$1" \
-        || func_split_equals_rhs=`expr "x$1" : 'x[^=]*=\(.*\)$'`
-  }
-fi #func_split_equals
-
-
-# func_split_short_opt SHORTOPT
-# -----------------------------
+# func_split_short_opt shortopt
 # Set func_split_short_opt_name and func_split_short_opt_arg shell
 # variables after splitting SHORTOPT after the 2nd character.
-if test yes = "$_G_HAVE_XSI_OPS"
-then
-  # This is an XSI compatible shell, allowing a faster implementation...
-  eval 'func_split_short_opt ()
-  {
-      $debug_cmd
-
-      func_split_short_opt_arg=${1#??}
-      func_split_short_opt_name=${1%"$func_split_short_opt_arg"}
-  }'
-else
-  # ...otherwise fall back to using expr, which is often a shell builtin.
-  func_split_short_opt ()
-  {
-      $debug_cmd
-
-      func_split_short_opt_name=`expr "x$1" : 'x-\(.\)'`
-      func_split_short_opt_arg=`expr "x$1" : 'x-.\(.*\)$'`
-  }
-fi #func_split_short_opt
-
-
-# func_usage
-# ----------
-# Echo short help message to standard output and exit.
-func_usage ()
+func_split_short_opt ()
 {
-    $debug_cmd
+    my_sed_short_opt='1s/^\(..\).*$/\1/;q'
+    my_sed_short_rest='1s/^..\(.*\)$/\1/;q'
 
-    func_usage_message
-    $ECHO "Run '$progname --help |${PAGER-more}' for full usage"
-    exit 0
-}
+    func_split_short_opt_name=`$ECHO "$1" | $SED "$my_sed_short_opt"`
+    func_split_short_opt_arg=`$ECHO "$1" | $SED "$my_sed_short_rest"`
+} # func_split_short_opt may be replaced by extended shell implementation
 
 
-# func_usage_message
-# ------------------
-# Echo short help message to standard output.
-func_usage_message ()
+# func_split_long_opt longopt
+# Set func_split_long_opt_name and func_split_long_opt_arg shell
+# variables after splitting LONGOPT at the `=' sign.
+func_split_long_opt ()
 {
-    $debug_cmd
+    my_sed_long_opt='1s/^\(--[^=]*\)=.*/\1/;q'
+    my_sed_long_arg='1s/^--[^=]*=//'
 
-    eval \$ECHO \""Usage: $usage"\"
-    echo
-    $SED -n 's|^# ||
-        /^Written by/{
-          x;p;x
-        }
-	h
-	/^Written by/q' < "$progpath"
-    echo
-    eval \$ECHO \""$usage_message"\"
-}
+    func_split_long_opt_name=`$ECHO "$1" | $SED "$my_sed_long_opt"`
+    func_split_long_opt_arg=`$ECHO "$1" | $SED "$my_sed_long_arg"`
+} # func_split_long_opt may be replaced by extended shell implementation
 
+exit_cmd=:
 
-# func_version
-# ------------
-# Echo version message to standard output and exit.
-func_version ()
-{
-    $debug_cmd
 
-    printf '%s\n' "$progname $scriptversion"
-    $SED -n '
-        /(C)/!b go
-        :more
-        /\./!{
-          N
-          s|\n# | |
-          b more
-        }
-        :go
-        /^# Written by /,/# warranty; / {
-          s|^# ||
-          s|^# *$||
-          s|\((C)\)[ 0-9,-]*[ ,-]\([1-9][0-9]* \)|\1 \2|
-          p
-        }
-        /^# Written by / {
-          s|^# ||
-          p
-        }
-        /^warranty; /q' < "$progpath"
 
-    exit $?
-}
 
 
-# Local variables:
-# mode: shell-script
-# sh-indentation: 2
-# eval: (add-hook 'before-save-hook 'time-stamp)
-# time-stamp-pattern: "10/scriptversion=%:y-%02m-%02d.%02H; # UTC"
-# time-stamp-time-zone: "UTC"
-# End:
+magic="%%%MAGIC variable%%%"
+magic_exe="%%%MAGIC EXE variable%%%"
 
-# Set a version string.
-scriptversion='(GNU libtool) 2.4.6'
+# Global variables.
+nonopt=
+preserve_args=
+lo2o="s/\\.lo\$/.${objext}/"
+o2lo="s/\\.${objext}\$/.lo/"
+extracted_archives=
+extracted_serial=0
 
+# If this variable is set in any of the actions, the command in it
+# will be execed at the end.  This prevents here-documents from being
+# left over by shells.
+exec_cmd=
 
-# func_echo ARG...
-# ----------------
-# Libtool also displays the current mode in messages, so override
-# funclib.sh func_echo with this custom definition.
-func_echo ()
+# func_append var value
+# Append VALUE to the end of shell variable VAR.
+func_append ()
 {
-    $debug_cmd
-
-    _G_message=$*
-
-    func_echo_IFS=$IFS
-    IFS=$nl
-    for _G_line in $_G_message; do
-      IFS=$func_echo_IFS
-      $ECHO "$progname${opt_mode+: $opt_mode}: $_G_line"
-    done
-    IFS=$func_echo_IFS
-}
-
+    eval "${1}=\$${1}\${2}"
+} # func_append may be replaced by extended shell implementation
 
-# func_warning ARG...
-# -------------------
-# Libtool warnings are not categorized, so override funclib.sh
-# func_warning with this simpler definition.
-func_warning ()
+# func_append_quoted var value
+# Quote VALUE and append to the end of shell variable VAR, separated
+# by a space.
+func_append_quoted ()
 {
-    $debug_cmd
-
-    $warning_func ${1+"$@"}
-}
-
+    func_quote_for_eval "${2}"
+    eval "${1}=\$${1}\\ \$func_quote_for_eval_result"
+} # func_append_quoted may be replaced by extended shell implementation
 
-## ---------------- ##
-## Options parsing. ##
-## ---------------- ##
-
-# Hook in the functions to make sure our own options are parsed during
-# the option parsing loop.
-
-usage='$progpath [OPTION]... [MODE-ARG]...'
-
-# Short help message in response to '-h'.
-usage_message="Options:
-       --config             show all configuration variables
-       --debug              enable verbose shell tracing
-   -n, --dry-run            display commands without modifying any files
-       --features           display basic configuration information and exit
-       --mode=MODE          use operation mode MODE
-       --no-warnings        equivalent to '-Wnone'
-       --preserve-dup-deps  don't remove duplicate dependency libraries
-       --quiet, --silent    don't print informational messages
-       --tag=TAG            use configuration variables from tag TAG
-   -v, --verbose            print more informational messages than default
-       --version            print version information
-   -W, --warnings=CATEGORY  report the warnings falling in CATEGORY [all]
-   -h, --help, --help-all   print short, long, or detailed help message
-"
 
-# Additional text appended to 'usage_message' in response to '--help'.
-func_help ()
+# func_arith arithmetic-term...
+func_arith ()
 {
-    $debug_cmd
-
-    func_usage_message
-    $ECHO "$long_help_message
-
-MODE must be one of the following:
-
-       clean           remove files from the build directory
-       compile         compile a source file into a libtool object
-       execute         automatically set library path, then run a program
-       finish          complete the installation of libtool libraries
-       install         install libraries or executables
-       link            create a library or an executable
-       uninstall       remove libraries from an installed directory
-
-MODE-ARGS vary depending on the MODE.  When passed as first option,
-'--mode=MODE' may be abbreviated as 'MODE' or a unique abbreviation of that.
-Try '$progname --help --mode=MODE' for a more detailed description of MODE.
-
-When reporting a bug, please describe a test case to reproduce it and
-include the following information:
-
-       host-triplet:   $host
-       shell:          $SHELL
-       compiler:       $LTCC
-       compiler flags: $LTCFLAGS
-       linker:         $LD (gnu? $with_gnu_ld)
-       version:        $progname (GNU libtool) 2.4.6
-       automake:       `($AUTOMAKE --version) 2>/dev/null |$SED 1q`
-       autoconf:       `($AUTOCONF --version) 2>/dev/null |$SED 1q`
-
-Report bugs to <bug-libtool at gnu.org>.
-GNU libtool home page: <http://www.gnu.org/s/libtool/>.
-General help using GNU software: <http://www.gnu.org/gethelp/>."
-    exit 0
-}
+    func_arith_result=`expr "${@}"`
+} # func_arith may be replaced by extended shell implementation
 
 
-# func_lo2o OBJECT-NAME
-# ---------------------
-# Transform OBJECT-NAME from a '.lo' suffix to the platform specific
-# object suffix.
+# func_len string
+# STRING may not start with a hyphen.
+func_len ()
+{
+    func_len_result=`expr "${1}" : ".*" 2>/dev/null || echo $max_cmd_len`
+} # func_len may be replaced by extended shell implementation
 
-lo2o=s/\\.lo\$/.$objext/
-o2lo=s/\\.$objext\$/.lo/
 
-if test yes = "$_G_HAVE_XSI_OPS"; then
-  eval 'func_lo2o ()
-  {
-    case $1 in
-      *.lo) func_lo2o_result=${1%.lo}.$objext ;;
-      *   ) func_lo2o_result=$1               ;;
-    esac
-  }'
+# func_lo2o object
+func_lo2o ()
+{
+    func_lo2o_result=`$ECHO "${1}" | $SED "$lo2o"`
+} # func_lo2o may be replaced by extended shell implementation
 
-  # func_xform LIBOBJ-OR-SOURCE
-  # ---------------------------
-  # Transform LIBOBJ-OR-SOURCE from a '.o' or '.c' (or otherwise)
-  # suffix to a '.lo' libtool-object suffix.
-  eval 'func_xform ()
-  {
-    func_xform_result=${1%.*}.lo
-  }'
-else
-  # ...otherwise fall back to using sed.
-  func_lo2o ()
-  {
-    func_lo2o_result=`$ECHO "$1" | $SED "$lo2o"`
-  }
 
-  func_xform ()
-  {
-    func_xform_result=`$ECHO "$1" | $SED 's|\.[^.]*$|.lo|'`
-  }
-fi
+# func_xform libobj-or-source
+func_xform ()
+{
+    func_xform_result=`$ECHO "${1}" | $SED 's/\.[^.]*$/.lo/'`
+} # func_xform may be replaced by extended shell implementation
 
 
-# func_fatal_configuration ARG...
-# -------------------------------
+# func_fatal_configuration arg...
 # Echo program name prefixed message to standard error, followed by
 # a configuration failure hint, and exit.
 func_fatal_configuration ()
 {
-    func__fatal_error ${1+"$@"} \
-      "See the $PACKAGE documentation for more information." \
-      "Fatal configuration error."
+    func_error ${1+"$@"}
+    func_error "See the $PACKAGE documentation for more information."
+    func_fatal_error "Fatal configuration error."
 }
 
 
 # func_config
-# -----------
 # Display the configuration for all the tags in this script.
 func_config ()
 {
@@ -2149,19 +915,17 @@ func_config ()
     exit $?
 }
 
-
 # func_features
-# -------------
 # Display the features supported by this script.
 func_features ()
 {
     echo "host: $host"
-    if test yes = "$build_libtool_libs"; then
+    if test "$build_libtool_libs" = yes; then
       echo "enable shared libraries"
     else
       echo "disable shared libraries"
     fi
-    if test yes = "$build_old_libs"; then
+    if test "$build_old_libs" = yes; then
       echo "enable static libraries"
     else
       echo "disable static libraries"
@@ -2170,350 +934,314 @@ func_features ()
     exit $?
 }
 
-
-# func_enable_tag TAGNAME
-# -----------------------
+# func_enable_tag tagname
 # Verify that TAGNAME is valid, and either flag an error and exit, or
 # enable the TAGNAME tag.  We also add TAGNAME to the global $taglist
 # variable here.
 func_enable_tag ()
 {
-    # Global variable:
-    tagname=$1
+  # Global variable:
+  tagname="$1"
 
-    re_begincf="^# ### BEGIN LIBTOOL TAG CONFIG: $tagname\$"
-    re_endcf="^# ### END LIBTOOL TAG CONFIG: $tagname\$"
-    sed_extractcf=/$re_begincf/,/$re_endcf/p
+  re_begincf="^# ### BEGIN LIBTOOL TAG CONFIG: $tagname\$"
+  re_endcf="^# ### END LIBTOOL TAG CONFIG: $tagname\$"
+  sed_extractcf="/$re_begincf/,/$re_endcf/p"
 
-    # Validate tagname.
-    case $tagname in
-      *[!-_A-Za-z0-9,/]*)
-        func_fatal_error "invalid tag name: $tagname"
-        ;;
-    esac
+  # Validate tagname.
+  case $tagname in
+    *[!-_A-Za-z0-9,/]*)
+      func_fatal_error "invalid tag name: $tagname"
+      ;;
+  esac
 
-    # Don't test for the "default" C tag, as we know it's
-    # there but not specially marked.
-    case $tagname in
-        CC) ;;
+  # Don't test for the "default" C tag, as we know it's
+  # there but not specially marked.
+  case $tagname in
+    CC) ;;
     *)
-        if $GREP "$re_begincf" "$progpath" >/dev/null 2>&1; then
-	  taglist="$taglist $tagname"
-
-	  # Evaluate the configuration.  Be careful to quote the path
-	  # and the sed script, to avoid splitting on whitespace, but
-	  # also don't use non-portable quotes within backquotes within
-	  # quotes we have to do it in 2 steps:
-	  extractedcf=`$SED -n -e "$sed_extractcf" < "$progpath"`
-	  eval "$extractedcf"
-        else
-	  func_error "ignoring unknown tag $tagname"
-        fi
-        ;;
-    esac
+      if $GREP "$re_begincf" "$progpath" >/dev/null 2>&1; then
+	taglist="$taglist $tagname"
+
+	# Evaluate the configuration.  Be careful to quote the path
+	# and the sed script, to avoid splitting on whitespace, but
+	# also don't use non-portable quotes within backquotes within
+	# quotes we have to do it in 2 steps:
+	extractedcf=`$SED -n -e "$sed_extractcf" < "$progpath"`
+	eval "$extractedcf"
+      else
+	func_error "ignoring unknown tag $tagname"
+      fi
+      ;;
+  esac
 }
 
-
 # func_check_version_match
-# ------------------------
 # Ensure that we are using m4 macros, and libtool script from the same
 # release of libtool.
 func_check_version_match ()
 {
-    if test "$package_revision" != "$macro_revision"; then
-      if test "$VERSION" != "$macro_version"; then
-        if test -z "$macro_version"; then
-          cat >&2 <<_LT_EOF
+  if test "$package_revision" != "$macro_revision"; then
+    if test "$VERSION" != "$macro_version"; then
+      if test -z "$macro_version"; then
+        cat >&2 <<_LT_EOF
 $progname: Version mismatch error.  This is $PACKAGE $VERSION, but the
 $progname: definition of this LT_INIT comes from an older release.
 $progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION
 $progname: and run autoconf again.
 _LT_EOF
-        else
-          cat >&2 <<_LT_EOF
+      else
+        cat >&2 <<_LT_EOF
 $progname: Version mismatch error.  This is $PACKAGE $VERSION, but the
 $progname: definition of this LT_INIT comes from $PACKAGE $macro_version.
 $progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION
 $progname: and run autoconf again.
 _LT_EOF
-        fi
-      else
-        cat >&2 <<_LT_EOF
+      fi
+    else
+      cat >&2 <<_LT_EOF
 $progname: Version mismatch error.  This is $PACKAGE $VERSION, revision $package_revision,
 $progname: but the definition of this LT_INIT comes from revision $macro_revision.
 $progname: You should recreate aclocal.m4 with macros from revision $package_revision
 $progname: of $PACKAGE $VERSION and run autoconf again.
 _LT_EOF
-      fi
-
-      exit $EXIT_MISMATCH
     fi
-}
 
+    exit $EXIT_MISMATCH
+  fi
+}
 
-# libtool_options_prep [ARG]...
-# -----------------------------
-# Preparation for options parsed by libtool.
-libtool_options_prep ()
-{
-    $debug_mode
 
-    # Option defaults:
-    opt_config=false
-    opt_dlopen=
-    opt_dry_run=false
-    opt_help=false
-    opt_mode=
-    opt_preserve_dup_deps=false
-    opt_quiet=false
+# Shorthand for --mode=foo, only valid as the first argument
+case $1 in
+clean|clea|cle|cl)
+  shift; set dummy --mode clean ${1+"$@"}; shift
+  ;;
+compile|compil|compi|comp|com|co|c)
+  shift; set dummy --mode compile ${1+"$@"}; shift
+  ;;
+execute|execut|execu|exec|exe|ex|e)
+  shift; set dummy --mode execute ${1+"$@"}; shift
+  ;;
+finish|finis|fini|fin|fi|f)
+  shift; set dummy --mode finish ${1+"$@"}; shift
+  ;;
+install|instal|insta|inst|ins|in|i)
+  shift; set dummy --mode install ${1+"$@"}; shift
+  ;;
+link|lin|li|l)
+  shift; set dummy --mode link ${1+"$@"}; shift
+  ;;
+uninstall|uninstal|uninsta|uninst|unins|unin|uni|un|u)
+  shift; set dummy --mode uninstall ${1+"$@"}; shift
+  ;;
+esac
 
-    nonopt=
-    preserve_args=
 
-    # Shorthand for --mode=foo, only valid as the first argument
-    case $1 in
-    clean|clea|cle|cl)
-      shift; set dummy --mode clean ${1+"$@"}; shift
-      ;;
-    compile|compil|compi|comp|com|co|c)
-      shift; set dummy --mode compile ${1+"$@"}; shift
-      ;;
-    execute|execut|execu|exec|exe|ex|e)
-      shift; set dummy --mode execute ${1+"$@"}; shift
-      ;;
-    finish|finis|fini|fin|fi|f)
-      shift; set dummy --mode finish ${1+"$@"}; shift
-      ;;
-    install|instal|insta|inst|ins|in|i)
-      shift; set dummy --mode install ${1+"$@"}; shift
-      ;;
-    link|lin|li|l)
-      shift; set dummy --mode link ${1+"$@"}; shift
-      ;;
-    uninstall|uninstal|uninsta|uninst|unins|unin|uni|un|u)
-      shift; set dummy --mode uninstall ${1+"$@"}; shift
-      ;;
-    esac
 
-    # Pass back the list of options.
-    func_quote_for_eval ${1+"$@"}
-    libtool_options_prep_result=$func_quote_for_eval_result
-}
-func_add_hook func_options_prep libtool_options_prep
+# Option defaults:
+opt_debug=:
+opt_dry_run=false
+opt_config=false
+opt_preserve_dup_deps=false
+opt_features=false
+opt_finish=false
+opt_help=false
+opt_help_all=false
+opt_silent=:
+opt_warning=:
+opt_verbose=:
+opt_silent=false
+opt_verbose=false
 
 
-# libtool_parse_options [ARG]...
-# ---------------------------------
-# Provide handling for libtool specific options.
-libtool_parse_options ()
+# Parse options once, thoroughly.  This comes as soon as possible in the
+# script to make things like `--version' happen as quickly as we can.
 {
-    $debug_cmd
+  # this just eases exit handling
+  while test $# -gt 0; do
+    opt="$1"
+    shift
+    case $opt in
+      --debug|-x)	opt_debug='set -x'
+			func_echo "enabling shell trace mode"
+			$opt_debug
+			;;
+      --dry-run|--dryrun|-n)
+			opt_dry_run=:
+			;;
+      --config)
+			opt_config=:
+func_config
+			;;
+      --dlopen|-dlopen)
+			optarg="$1"
+			opt_dlopen="${opt_dlopen+$opt_dlopen
+}$optarg"
+			shift
+			;;
+      --preserve-dup-deps)
+			opt_preserve_dup_deps=:
+			;;
+      --features)
+			opt_features=:
+func_features
+			;;
+      --finish)
+			opt_finish=:
+set dummy --mode finish ${1+"$@"}; shift
+			;;
+      --help)
+			opt_help=:
+			;;
+      --help-all)
+			opt_help_all=:
+opt_help=': help-all'
+			;;
+      --mode)
+			test $# = 0 && func_missing_arg $opt && break
+			optarg="$1"
+			opt_mode="$optarg"
+case $optarg in
+  # Valid mode arguments:
+  clean|compile|execute|finish|install|link|relink|uninstall) ;;
+
+  # Catch anything else as an error
+  *) func_error "invalid argument for $opt"
+     exit_cmd=exit
+     break
+     ;;
+esac
+			shift
+			;;
+      --no-silent|--no-quiet)
+			opt_silent=false
+func_append preserve_args " $opt"
+			;;
+      --no-warning|--no-warn)
+			opt_warning=false
+func_append preserve_args " $opt"
+			;;
+      --no-verbose)
+			opt_verbose=false
+func_append preserve_args " $opt"
+			;;
+      --silent|--quiet)
+			opt_silent=:
+func_append preserve_args " $opt"
+        opt_verbose=false
+			;;
+      --verbose|-v)
+			opt_verbose=:
+func_append preserve_args " $opt"
+opt_silent=false
+			;;
+      --tag)
+			test $# = 0 && func_missing_arg $opt && break
+			optarg="$1"
+			opt_tag="$optarg"
+func_append preserve_args " $opt $optarg"
+func_enable_tag "$optarg"
+			shift
+			;;
+
+      -\?|-h)		func_usage				;;
+      --help)		func_help				;;
+      --version)	func_version				;;
+
+      # Separate optargs to long options:
+      --*=*)
+			func_split_long_opt "$opt"
+			set dummy "$func_split_long_opt_name" "$func_split_long_opt_arg" ${1+"$@"}
+			shift
+			;;
+
+      # Separate non-argument short options:
+      -\?*|-h*|-n*|-v*)
+			func_split_short_opt "$opt"
+			set dummy "$func_split_short_opt_name" "-$func_split_short_opt_arg" ${1+"$@"}
+			shift
+			;;
+
+      --)		break					;;
+      -*)		func_fatal_help "unrecognized option \`$opt'" ;;
+      *)		set dummy "$opt" ${1+"$@"};	shift; break  ;;
+    esac
+  done
 
-    # Perform our own loop to consume as many options as possible in
-    # each iteration.
-    while test $# -gt 0; do
-      _G_opt=$1
-      shift
-      case $_G_opt in
-        --dry-run|--dryrun|-n)
-                        opt_dry_run=:
-                        ;;
-
-        --config)       func_config ;;
-
-        --dlopen|-dlopen)
-                        opt_dlopen="${opt_dlopen+$opt_dlopen
-}$1"
-                        shift
-                        ;;
-
-        --preserve-dup-deps)
-                        opt_preserve_dup_deps=: ;;
-
-        --features)     func_features ;;
-
-        --finish)       set dummy --mode finish ${1+"$@"}; shift ;;
-
-        --help)         opt_help=: ;;
-
-        --help-all)     opt_help=': help-all' ;;
-
-        --mode)         test $# = 0 && func_missing_arg $_G_opt && break
-                        opt_mode=$1
-                        case $1 in
-                          # Valid mode arguments:
-                          clean|compile|execute|finish|install|link|relink|uninstall) ;;
-
-                          # Catch anything else as an error
-                          *) func_error "invalid argument for $_G_opt"
-                             exit_cmd=exit
-                             break
-                             ;;
-                        esac
-                        shift
-                        ;;
-
-        --no-silent|--no-quiet)
-                        opt_quiet=false
-                        func_append preserve_args " $_G_opt"
-                        ;;
-
-        --no-warnings|--no-warning|--no-warn)
-                        opt_warning=false
-                        func_append preserve_args " $_G_opt"
-                        ;;
-
-        --no-verbose)
-                        opt_verbose=false
-                        func_append preserve_args " $_G_opt"
-                        ;;
-
-        --silent|--quiet)
-                        opt_quiet=:
-                        opt_verbose=false
-                        func_append preserve_args " $_G_opt"
-                        ;;
-
-        --tag)          test $# = 0 && func_missing_arg $_G_opt && break
-                        opt_tag=$1
-                        func_append preserve_args " $_G_opt $1"
-                        func_enable_tag "$1"
-                        shift
-                        ;;
-
-        --verbose|-v)   opt_quiet=false
-                        opt_verbose=:
-                        func_append preserve_args " $_G_opt"
-                        ;;
-
-	# An option not handled by this hook function:
-        *)		set dummy "$_G_opt" ${1+"$@"};	shift; break  ;;
-      esac
-    done
+  # Validate options:
 
+  # save first non-option argument
+  if test "$#" -gt 0; then
+    nonopt="$opt"
+    shift
+  fi
 
-    # save modified positional parameters for caller
-    func_quote_for_eval ${1+"$@"}
-    libtool_parse_options_result=$func_quote_for_eval_result
-}
-func_add_hook func_parse_options libtool_parse_options
+  # preserve --debug
+  test "$opt_debug" = : || func_append preserve_args " --debug"
 
+  case $host in
+    *cygwin* | *mingw* | *pw32* | *cegcc*)
+      # don't eliminate duplications in $postdeps and $predeps
+      opt_duplicate_compiler_generated_deps=:
+      ;;
+    *)
+      opt_duplicate_compiler_generated_deps=$opt_preserve_dup_deps
+      ;;
+  esac
 
+  $opt_help || {
+    # Sanity checks first:
+    func_check_version_match
 
-# libtool_validate_options [ARG]...
-# ---------------------------------
-# Perform any sanity checks on option settings and/or unconsumed
-# arguments.
-libtool_validate_options ()
-{
-    # save first non-option argument
-    if test 0 -lt $#; then
-      nonopt=$1
-      shift
+    if test "$build_libtool_libs" != yes && test "$build_old_libs" != yes; then
+      func_fatal_configuration "not configured to build any kind of library"
     fi
 
-    # preserve --debug
-    test : = "$debug_cmd" || func_append preserve_args " --debug"
-
-    case $host in
-      # Solaris2 added to fix http://debbugs.gnu.org/cgi/bugreport.cgi?bug=16452
-      # see also: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=59788
-      *cygwin* | *mingw* | *pw32* | *cegcc* | *solaris2* | *os2*)
-        # don't eliminate duplications in $postdeps and $predeps
-        opt_duplicate_compiler_generated_deps=:
-        ;;
-      *)
-        opt_duplicate_compiler_generated_deps=$opt_preserve_dup_deps
-        ;;
-    esac
-
-    $opt_help || {
-      # Sanity checks first:
-      func_check_version_match
-
-      test yes != "$build_libtool_libs" \
-        && test yes != "$build_old_libs" \
-        && func_fatal_configuration "not configured to build any kind of library"
+    # Darwin sucks
+    eval std_shrext=\"$shrext_cmds\"
 
-      # Darwin sucks
-      eval std_shrext=\"$shrext_cmds\"
+    # Only execute mode is allowed to have -dlopen flags.
+    if test -n "$opt_dlopen" && test "$opt_mode" != execute; then
+      func_error "unrecognized option \`-dlopen'"
+      $ECHO "$help" 1>&2
+      exit $EXIT_FAILURE
+    fi
 
-      # Only execute mode is allowed to have -dlopen flags.
-      if test -n "$opt_dlopen" && test execute != "$opt_mode"; then
-        func_error "unrecognized option '-dlopen'"
-        $ECHO "$help" 1>&2
-        exit $EXIT_FAILURE
-      fi
+    # Change the help message to a mode-specific one.
+    generic_help="$help"
+    help="Try \`$progname --help --mode=$opt_mode' for more information."
+  }
 
-      # Change the help message to a mode-specific one.
-      generic_help=$help
-      help="Try '$progname --help --mode=$opt_mode' for more information."
-    }
 
-    # Pass back the unparsed argument list
-    func_quote_for_eval ${1+"$@"}
-    libtool_validate_options_result=$func_quote_for_eval_result
+  # Bail if the options were screwed
+  $exit_cmd $EXIT_FAILURE
 }
-func_add_hook func_validate_options libtool_validate_options
 
 
-# Process options as early as possible so that --help and --version
-# can return quickly.
-func_options ${1+"$@"}
-eval set dummy "$func_options_result"; shift
-
 
 
 ## ----------- ##
 ##    Main.    ##
 ## ----------- ##
 
-magic='%%%MAGIC variable%%%'
-magic_exe='%%%MAGIC EXE variable%%%'
-
-# Global variables.
-extracted_archives=
-extracted_serial=0
-
-# If this variable is set in any of the actions, the command in it
-# will be execed at the end.  This prevents here-documents from being
-# left over by shells.
-exec_cmd=
-
-
-# A function that is used when there is no print builtin or printf.
-func_fallback_echo ()
-{
-  eval 'cat <<_LTECHO_EOF
-$1
-_LTECHO_EOF'
-}
-
-# func_generated_by_libtool
-# True iff stdin has been generated by Libtool. This function is only
-# a basic sanity check; it will hardly flush out determined imposters.
-func_generated_by_libtool_p ()
-{
-  $GREP "^# Generated by .*$PACKAGE" > /dev/null 2>&1
-}
-
 # func_lalib_p file
-# True iff FILE is a libtool '.la' library or '.lo' object file.
+# True iff FILE is a libtool `.la' library or `.lo' object file.
 # This function is only a basic sanity check; it will hardly flush out
 # determined imposters.
 func_lalib_p ()
 {
     test -f "$1" &&
-      $SED -e 4q "$1" 2>/dev/null | func_generated_by_libtool_p
+      $SED -e 4q "$1" 2>/dev/null \
+        | $GREP "^# Generated by .*$PACKAGE" > /dev/null 2>&1
 }
 
 # func_lalib_unsafe_p file
-# True iff FILE is a libtool '.la' library or '.lo' object file.
+# True iff FILE is a libtool `.la' library or `.lo' object file.
 # This function implements the same check as func_lalib_p without
 # resorting to external programs.  To this end, it redirects stdin and
 # closes it afterwards, without saving the original file descriptor.
 # As a safety measure, use it only where a negative result would be
-# fatal anyway.  Works if 'file' does not exist.
+# fatal anyway.  Works if `file' does not exist.
 func_lalib_unsafe_p ()
 {
     lalib_p=no
@@ -2521,13 +1249,13 @@ func_lalib_unsafe_p ()
 	for lalib_p_l in 1 2 3 4
 	do
 	    read lalib_p_line
-	    case $lalib_p_line in
+	    case "$lalib_p_line" in
 		\#\ Generated\ by\ *$PACKAGE* ) lalib_p=yes; break;;
 	    esac
 	done
 	exec 0<&5 5<&-
     fi
-    test yes = "$lalib_p"
+    test "$lalib_p" = yes
 }
 
 # func_ltwrapper_script_p file
@@ -2536,8 +1264,7 @@ func_lalib_unsafe_p ()
 # determined imposters.
 func_ltwrapper_script_p ()
 {
-    test -f "$1" &&
-      $lt_truncate_bin < "$1" 2>/dev/null | func_generated_by_libtool_p
+    func_lalib_p "$1"
 }
 
 # func_ltwrapper_executable_p file
@@ -2562,7 +1289,7 @@ func_ltwrapper_scriptname ()
 {
     func_dirname_and_basename "$1" "" "."
     func_stripname '' '.exe' "$func_basename_result"
-    func_ltwrapper_scriptname_result=$func_dirname_result/$objdir/${func_stripname_result}_ltshwrapper
+    func_ltwrapper_scriptname_result="$func_dirname_result/$objdir/${func_stripname_result}_ltshwrapper"
 }
 
 # func_ltwrapper_p file
@@ -2581,13 +1308,11 @@ func_ltwrapper_p ()
 # FAIL_CMD may read-access the current command in variable CMD!
 func_execute_cmds ()
 {
-    $debug_cmd
-
+    $opt_debug
     save_ifs=$IFS; IFS='~'
     for cmd in $1; do
-      IFS=$sp$nl
-      eval cmd=\"$cmd\"
       IFS=$save_ifs
+      eval cmd=\"$cmd\"
       func_show_eval "$cmd" "${2-:}"
     done
     IFS=$save_ifs
@@ -2599,11 +1324,10 @@ func_execute_cmds ()
 # Note that it is not necessary on cygwin/mingw to append a dot to
 # FILE even if both FILE and FILE.exe exist: automatic-append-.exe
 # behavior happens only for exec(3), not for open(2)!  Also, sourcing
-# 'FILE.' does not work on cygwin managed mounts.
+# `FILE.' does not work on cygwin managed mounts.
 func_source ()
 {
-    $debug_cmd
-
+    $opt_debug
     case $1 in
     */* | *\\*)	. "$1" ;;
     *)		. "./$1" ;;
@@ -2630,10 +1354,10 @@ func_resolve_sysroot ()
 # store the result into func_replace_sysroot_result.
 func_replace_sysroot ()
 {
-  case $lt_sysroot:$1 in
+  case "$lt_sysroot:$1" in
   ?*:"$lt_sysroot"*)
     func_stripname "$lt_sysroot" '' "$1"
-    func_replace_sysroot_result='='$func_stripname_result
+    func_replace_sysroot_result="=$func_stripname_result"
     ;;
   *)
     # Including no sysroot.
@@ -2650,8 +1374,7 @@ func_replace_sysroot ()
 # arg is usually of the form 'gcc ...'
 func_infer_tag ()
 {
-    $debug_cmd
-
+    $opt_debug
     if test -n "$available_tags" && test -z "$tagname"; then
       CC_quoted=
       for arg in $CC; do
@@ -2670,7 +1393,7 @@ func_infer_tag ()
 	for z in $available_tags; do
 	  if $GREP "^# ### BEGIN LIBTOOL TAG CONFIG: $z$" < "$progpath" > /dev/null; then
 	    # Evaluate the configuration.
-	    eval "`$SED -n -e '/^# ### BEGIN LIBTOOL TAG CONFIG: '$z'$/,/^# ### END LIBTOOL TAG CONFIG: '$z'$/p' < $progpath`"
+	    eval "`${SED} -n -e '/^# ### BEGIN LIBTOOL TAG CONFIG: '$z'$/,/^# ### END LIBTOOL TAG CONFIG: '$z'$/p' < $progpath`"
 	    CC_quoted=
 	    for arg in $CC; do
 	      # Double-quote args containing other shell metacharacters.
@@ -2695,7 +1418,7 @@ func_infer_tag ()
 	# line option must be used.
 	if test -z "$tagname"; then
 	  func_echo "unable to infer tagged configuration"
-	  func_fatal_error "specify a tag with '--tag'"
+	  func_fatal_error "specify a tag with \`--tag'"
 #	else
 #	  func_verbose "using $tagname tagged configuration"
 	fi
@@ -2711,15 +1434,15 @@ func_infer_tag ()
 # but don't create it if we're doing a dry run.
 func_write_libtool_object ()
 {
-    write_libobj=$1
-    if test yes = "$build_libtool_libs"; then
-      write_lobj=\'$2\'
+    write_libobj=${1}
+    if test "$build_libtool_libs" = yes; then
+      write_lobj=\'${2}\'
     else
       write_lobj=none
     fi
 
-    if test yes = "$build_old_libs"; then
-      write_oldobj=\'$3\'
+    if test "$build_old_libs" = yes; then
+      write_oldobj=\'${3}\'
     else
       write_oldobj=none
     fi
@@ -2727,7 +1450,7 @@ func_write_libtool_object ()
     $opt_dry_run || {
       cat >${write_libobj}T <<EOF
 # $write_libobj - a libtool object file
-# Generated by $PROGRAM (GNU $PACKAGE) $VERSION
+# Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION
 #
 # Please DO NOT delete this file!
 # It is necessary for linking the library.
@@ -2739,7 +1462,7 @@ pic_object=$write_lobj
 non_pic_object=$write_oldobj
 
 EOF
-      $MV "${write_libobj}T" "$write_libobj"
+      $MV "${write_libobj}T" "${write_libobj}"
     }
 }
 
@@ -2759,9 +1482,8 @@ EOF
 # be empty on error (or when ARG is empty)
 func_convert_core_file_wine_to_w32 ()
 {
-  $debug_cmd
-
-  func_convert_core_file_wine_to_w32_result=$1
+  $opt_debug
+  func_convert_core_file_wine_to_w32_result="$1"
   if test -n "$1"; then
     # Unfortunately, winepath does not exit with a non-zero error code, so we
     # are forced to check the contents of stdout. On the other hand, if the
@@ -2769,9 +1491,9 @@ func_convert_core_file_wine_to_w32 ()
     # *an error message* to stdout. So we must check for both error code of
     # zero AND non-empty stdout, which explains the odd construction:
     func_convert_core_file_wine_to_w32_tmp=`winepath -w "$1" 2>/dev/null`
-    if test "$?" -eq 0 && test -n "$func_convert_core_file_wine_to_w32_tmp"; then
+    if test "$?" -eq 0 && test -n "${func_convert_core_file_wine_to_w32_tmp}"; then
       func_convert_core_file_wine_to_w32_result=`$ECHO "$func_convert_core_file_wine_to_w32_tmp" |
-        $SED -e "$sed_naive_backslashify"`
+        $SED -e "$lt_sed_naive_backslashify"`
     else
       func_convert_core_file_wine_to_w32_result=
     fi
@@ -2792,19 +1514,18 @@ func_convert_core_file_wine_to_w32 ()
 # are convertible, then the result may be empty.
 func_convert_core_path_wine_to_w32 ()
 {
-  $debug_cmd
-
+  $opt_debug
   # unfortunately, winepath doesn't convert paths, only file names
-  func_convert_core_path_wine_to_w32_result=
+  func_convert_core_path_wine_to_w32_result=""
   if test -n "$1"; then
     oldIFS=$IFS
     IFS=:
     for func_convert_core_path_wine_to_w32_f in $1; do
       IFS=$oldIFS
       func_convert_core_file_wine_to_w32 "$func_convert_core_path_wine_to_w32_f"
-      if test -n "$func_convert_core_file_wine_to_w32_result"; then
+      if test -n "$func_convert_core_file_wine_to_w32_result" ; then
         if test -z "$func_convert_core_path_wine_to_w32_result"; then
-          func_convert_core_path_wine_to_w32_result=$func_convert_core_file_wine_to_w32_result
+          func_convert_core_path_wine_to_w32_result="$func_convert_core_file_wine_to_w32_result"
         else
           func_append func_convert_core_path_wine_to_w32_result ";$func_convert_core_file_wine_to_w32_result"
         fi
@@ -2833,8 +1554,7 @@ func_convert_core_path_wine_to_w32 ()
 # environment variable; do not put it in $PATH.
 func_cygpath ()
 {
-  $debug_cmd
-
+  $opt_debug
   if test -n "$LT_CYGPATH" && test -f "$LT_CYGPATH"; then
     func_cygpath_result=`$LT_CYGPATH "$@" 2>/dev/null`
     if test "$?" -ne 0; then
@@ -2843,7 +1563,7 @@ func_cygpath ()
     fi
   else
     func_cygpath_result=
-    func_error "LT_CYGPATH is empty or specifies non-existent file: '$LT_CYGPATH'"
+    func_error "LT_CYGPATH is empty or specifies non-existent file: \`$LT_CYGPATH'"
   fi
 }
 #end: func_cygpath
@@ -2854,11 +1574,10 @@ func_cygpath ()
 # result in func_convert_core_msys_to_w32_result.
 func_convert_core_msys_to_w32 ()
 {
-  $debug_cmd
-
+  $opt_debug
   # awkward: cmd appends spaces to result
   func_convert_core_msys_to_w32_result=`( cmd //c echo "$1" ) 2>/dev/null |
-    $SED -e 's/[ ]*$//' -e "$sed_naive_backslashify"`
+    $SED -e 's/[ ]*$//' -e "$lt_sed_naive_backslashify"`
 }
 #end: func_convert_core_msys_to_w32
 
@@ -2869,14 +1588,13 @@ func_convert_core_msys_to_w32 ()
 # func_to_host_file_result to ARG1).
 func_convert_file_check ()
 {
-  $debug_cmd
-
-  if test -z "$2" && test -n "$1"; then
+  $opt_debug
+  if test -z "$2" && test -n "$1" ; then
     func_error "Could not determine host file name corresponding to"
-    func_error "  '$1'"
+    func_error "  \`$1'"
     func_error "Continuing, but uninstalled executables may not work."
     # Fallback:
-    func_to_host_file_result=$1
+    func_to_host_file_result="$1"
   fi
 }
 # end func_convert_file_check
@@ -2888,11 +1606,10 @@ func_convert_file_check ()
 # func_to_host_file_result to a simplistic fallback value (see below).
 func_convert_path_check ()
 {
-  $debug_cmd
-
+  $opt_debug
   if test -z "$4" && test -n "$3"; then
     func_error "Could not determine the host path corresponding to"
-    func_error "  '$3'"
+    func_error "  \`$3'"
     func_error "Continuing, but uninstalled executables may not work."
     # Fallback.  This is a deliberately simplistic "conversion" and
     # should not be "improved".  See libtool.info.
@@ -2901,7 +1618,7 @@ func_convert_path_check ()
       func_to_host_path_result=`echo "$3" |
         $SED -e "$lt_replace_pathsep_chars"`
     else
-      func_to_host_path_result=$3
+      func_to_host_path_result="$3"
     fi
   fi
 }
@@ -2913,10 +1630,9 @@ func_convert_path_check ()
 # and appending REPL if ORIG matches BACKPAT.
 func_convert_path_front_back_pathsep ()
 {
-  $debug_cmd
-
+  $opt_debug
   case $4 in
-  $1 ) func_to_host_path_result=$3$func_to_host_path_result
+  $1 ) func_to_host_path_result="$3$func_to_host_path_result"
     ;;
   esac
   case $4 in
@@ -2930,7 +1646,7 @@ func_convert_path_front_back_pathsep ()
 ##################################################
 # $build to $host FILE NAME CONVERSION FUNCTIONS #
 ##################################################
-# invoked via '$to_host_file_cmd ARG'
+# invoked via `$to_host_file_cmd ARG'
 #
 # In each case, ARG is the path to be converted from $build to $host format.
 # Result will be available in $func_to_host_file_result.
@@ -2941,8 +1657,7 @@ func_convert_path_front_back_pathsep ()
 # in func_to_host_file_result.
 func_to_host_file ()
 {
-  $debug_cmd
-
+  $opt_debug
   $to_host_file_cmd "$1"
 }
 # end func_to_host_file
@@ -2954,8 +1669,7 @@ func_to_host_file ()
 # in (the comma separated) LAZY, no conversion takes place.
 func_to_tool_file ()
 {
-  $debug_cmd
-
+  $opt_debug
   case ,$2, in
     *,"$to_tool_file_cmd",*)
       func_to_tool_file_result=$1
@@ -2973,7 +1687,7 @@ func_to_tool_file ()
 # Copy ARG to func_to_host_file_result.
 func_convert_file_noop ()
 {
-  func_to_host_file_result=$1
+  func_to_host_file_result="$1"
 }
 # end func_convert_file_noop
 
@@ -2984,12 +1698,11 @@ func_convert_file_noop ()
 # func_to_host_file_result.
 func_convert_file_msys_to_w32 ()
 {
-  $debug_cmd
-
-  func_to_host_file_result=$1
+  $opt_debug
+  func_to_host_file_result="$1"
   if test -n "$1"; then
     func_convert_core_msys_to_w32 "$1"
-    func_to_host_file_result=$func_convert_core_msys_to_w32_result
+    func_to_host_file_result="$func_convert_core_msys_to_w32_result"
   fi
   func_convert_file_check "$1" "$func_to_host_file_result"
 }
@@ -3001,9 +1714,8 @@ func_convert_file_msys_to_w32 ()
 # func_to_host_file_result.
 func_convert_file_cygwin_to_w32 ()
 {
-  $debug_cmd
-
-  func_to_host_file_result=$1
+  $opt_debug
+  func_to_host_file_result="$1"
   if test -n "$1"; then
     # because $build is cygwin, we call "the" cygpath in $PATH; no need to use
     # LT_CYGPATH in this case.
@@ -3019,12 +1731,11 @@ func_convert_file_cygwin_to_w32 ()
 # and a working winepath. Returns result in func_to_host_file_result.
 func_convert_file_nix_to_w32 ()
 {
-  $debug_cmd
-
-  func_to_host_file_result=$1
+  $opt_debug
+  func_to_host_file_result="$1"
   if test -n "$1"; then
     func_convert_core_file_wine_to_w32 "$1"
-    func_to_host_file_result=$func_convert_core_file_wine_to_w32_result
+    func_to_host_file_result="$func_convert_core_file_wine_to_w32_result"
   fi
   func_convert_file_check "$1" "$func_to_host_file_result"
 }
@@ -3036,13 +1747,12 @@ func_convert_file_nix_to_w32 ()
 # Returns result in func_to_host_file_result.
 func_convert_file_msys_to_cygwin ()
 {
-  $debug_cmd
-
-  func_to_host_file_result=$1
+  $opt_debug
+  func_to_host_file_result="$1"
   if test -n "$1"; then
     func_convert_core_msys_to_w32 "$1"
     func_cygpath -u "$func_convert_core_msys_to_w32_result"
-    func_to_host_file_result=$func_cygpath_result
+    func_to_host_file_result="$func_cygpath_result"
   fi
   func_convert_file_check "$1" "$func_to_host_file_result"
 }
@@ -3055,14 +1765,13 @@ func_convert_file_msys_to_cygwin ()
 # in func_to_host_file_result.
 func_convert_file_nix_to_cygwin ()
 {
-  $debug_cmd
-
-  func_to_host_file_result=$1
+  $opt_debug
+  func_to_host_file_result="$1"
   if test -n "$1"; then
     # convert from *nix to w32, then use cygpath to convert from w32 to cygwin.
     func_convert_core_file_wine_to_w32 "$1"
     func_cygpath -u "$func_convert_core_file_wine_to_w32_result"
-    func_to_host_file_result=$func_cygpath_result
+    func_to_host_file_result="$func_cygpath_result"
   fi
   func_convert_file_check "$1" "$func_to_host_file_result"
 }
@@ -3072,7 +1781,7 @@ func_convert_file_nix_to_cygwin ()
 #############################################
 # $build to $host PATH CONVERSION FUNCTIONS #
 #############################################
-# invoked via '$to_host_path_cmd ARG'
+# invoked via `$to_host_path_cmd ARG'
 #
 # In each case, ARG is the path to be converted from $build to $host format.
 # The result will be available in $func_to_host_path_result.
@@ -3096,11 +1805,10 @@ func_convert_file_nix_to_cygwin ()
 to_host_path_cmd=
 func_init_to_host_path_cmd ()
 {
-  $debug_cmd
-
+  $opt_debug
   if test -z "$to_host_path_cmd"; then
     func_stripname 'func_convert_file_' '' "$to_host_file_cmd"
-    to_host_path_cmd=func_convert_path_$func_stripname_result
+    to_host_path_cmd="func_convert_path_${func_stripname_result}"
   fi
 }
 
@@ -3110,8 +1818,7 @@ func_init_to_host_path_cmd ()
 # in func_to_host_path_result.
 func_to_host_path ()
 {
-  $debug_cmd
-
+  $opt_debug
   func_init_to_host_path_cmd
   $to_host_path_cmd "$1"
 }
@@ -3122,7 +1829,7 @@ func_to_host_path ()
 # Copy ARG to func_to_host_path_result.
 func_convert_path_noop ()
 {
-  func_to_host_path_result=$1
+  func_to_host_path_result="$1"
 }
 # end func_convert_path_noop
 
@@ -3133,9 +1840,8 @@ func_convert_path_noop ()
 # func_to_host_path_result.
 func_convert_path_msys_to_w32 ()
 {
-  $debug_cmd
-
-  func_to_host_path_result=$1
+  $opt_debug
+  func_to_host_path_result="$1"
   if test -n "$1"; then
     # Remove leading and trailing path separator characters from ARG.  MSYS
     # behavior is inconsistent here; cygpath turns them into '.;' and ';.';
@@ -3143,7 +1849,7 @@ func_convert_path_msys_to_w32 ()
     func_stripname : : "$1"
     func_to_host_path_tmp1=$func_stripname_result
     func_convert_core_msys_to_w32 "$func_to_host_path_tmp1"
-    func_to_host_path_result=$func_convert_core_msys_to_w32_result
+    func_to_host_path_result="$func_convert_core_msys_to_w32_result"
     func_convert_path_check : ";" \
       "$func_to_host_path_tmp1" "$func_to_host_path_result"
     func_convert_path_front_back_pathsep ":*" "*:" ";" "$1"
@@ -3157,9 +1863,8 @@ func_convert_path_msys_to_w32 ()
 # func_to_host_file_result.
 func_convert_path_cygwin_to_w32 ()
 {
-  $debug_cmd
-
-  func_to_host_path_result=$1
+  $opt_debug
+  func_to_host_path_result="$1"
   if test -n "$1"; then
     # See func_convert_path_msys_to_w32:
     func_stripname : : "$1"
@@ -3178,15 +1883,14 @@ func_convert_path_cygwin_to_w32 ()
 # a working winepath.  Returns result in func_to_host_file_result.
 func_convert_path_nix_to_w32 ()
 {
-  $debug_cmd
-
-  func_to_host_path_result=$1
+  $opt_debug
+  func_to_host_path_result="$1"
   if test -n "$1"; then
     # See func_convert_path_msys_to_w32:
     func_stripname : : "$1"
     func_to_host_path_tmp1=$func_stripname_result
     func_convert_core_path_wine_to_w32 "$func_to_host_path_tmp1"
-    func_to_host_path_result=$func_convert_core_path_wine_to_w32_result
+    func_to_host_path_result="$func_convert_core_path_wine_to_w32_result"
     func_convert_path_check : ";" \
       "$func_to_host_path_tmp1" "$func_to_host_path_result"
     func_convert_path_front_back_pathsep ":*" "*:" ";" "$1"
@@ -3200,16 +1904,15 @@ func_convert_path_nix_to_w32 ()
 # Returns result in func_to_host_file_result.
 func_convert_path_msys_to_cygwin ()
 {
-  $debug_cmd
-
-  func_to_host_path_result=$1
+  $opt_debug
+  func_to_host_path_result="$1"
   if test -n "$1"; then
     # See func_convert_path_msys_to_w32:
     func_stripname : : "$1"
     func_to_host_path_tmp1=$func_stripname_result
     func_convert_core_msys_to_w32 "$func_to_host_path_tmp1"
     func_cygpath -u -p "$func_convert_core_msys_to_w32_result"
-    func_to_host_path_result=$func_cygpath_result
+    func_to_host_path_result="$func_cygpath_result"
     func_convert_path_check : : \
       "$func_to_host_path_tmp1" "$func_to_host_path_result"
     func_convert_path_front_back_pathsep ":*" "*:" : "$1"
@@ -3224,9 +1927,8 @@ func_convert_path_msys_to_cygwin ()
 # func_to_host_file_result.
 func_convert_path_nix_to_cygwin ()
 {
-  $debug_cmd
-
-  func_to_host_path_result=$1
+  $opt_debug
+  func_to_host_path_result="$1"
   if test -n "$1"; then
     # Remove leading and trailing path separator characters from
     # ARG. msys behavior is inconsistent here, cygpath turns them
@@ -3235,7 +1937,7 @@ func_convert_path_nix_to_cygwin ()
     func_to_host_path_tmp1=$func_stripname_result
     func_convert_core_path_wine_to_w32 "$func_to_host_path_tmp1"
     func_cygpath -u -p "$func_convert_core_path_wine_to_w32_result"
-    func_to_host_path_result=$func_cygpath_result
+    func_to_host_path_result="$func_cygpath_result"
     func_convert_path_check : : \
       "$func_to_host_path_tmp1" "$func_to_host_path_result"
     func_convert_path_front_back_pathsep ":*" "*:" : "$1"
@@ -3244,31 +1946,13 @@ func_convert_path_nix_to_cygwin ()
 # end func_convert_path_nix_to_cygwin
 
 
-# func_dll_def_p FILE
-# True iff FILE is a Windows DLL '.def' file.
-# Keep in sync with _LT_DLL_DEF_P in libtool.m4
-func_dll_def_p ()
-{
-  $debug_cmd
-
-  func_dll_def_p_tmp=`$SED -n \
-    -e 's/^[	 ]*//' \
-    -e '/^\(;.*\)*$/d' \
-    -e 's/^\(EXPORTS\|LIBRARY\)\([	 ].*\)*$/DEF/p' \
-    -e q \
-    "$1"`
-  test DEF = "$func_dll_def_p_tmp"
-}
-
-
 # func_mode_compile arg...
 func_mode_compile ()
 {
-    $debug_cmd
-
+    $opt_debug
     # Get the compilation command and the source file.
     base_compile=
-    srcfile=$nonopt  #  always keep a non-empty value in "srcfile"
+    srcfile="$nonopt"  #  always keep a non-empty value in "srcfile"
     suppress_opt=yes
     suppress_output=
     arg_mode=normal
@@ -3281,12 +1965,12 @@ func_mode_compile ()
       case $arg_mode in
       arg  )
 	# do not "continue".  Instead, add this to base_compile
-	lastarg=$arg
+	lastarg="$arg"
 	arg_mode=normal
 	;;
 
       target )
-	libobj=$arg
+	libobj="$arg"
 	arg_mode=normal
 	continue
 	;;
@@ -3296,7 +1980,7 @@ func_mode_compile ()
 	case $arg in
 	-o)
 	  test -n "$libobj" && \
-	    func_fatal_error "you cannot specify '-o' more than once"
+	    func_fatal_error "you cannot specify \`-o' more than once"
 	  arg_mode=target
 	  continue
 	  ;;
@@ -3325,12 +2009,12 @@ func_mode_compile ()
 	  func_stripname '-Wc,' '' "$arg"
 	  args=$func_stripname_result
 	  lastarg=
-	  save_ifs=$IFS; IFS=,
+	  save_ifs="$IFS"; IFS=','
 	  for arg in $args; do
-	    IFS=$save_ifs
+	    IFS="$save_ifs"
 	    func_append_quoted lastarg "$arg"
 	  done
-	  IFS=$save_ifs
+	  IFS="$save_ifs"
 	  func_stripname ' ' '' "$lastarg"
 	  lastarg=$func_stripname_result
 
@@ -3343,8 +2027,8 @@ func_mode_compile ()
 	  # Accept the current argument as the source file.
 	  # The previous "srcfile" becomes the current argument.
 	  #
-	  lastarg=$srcfile
-	  srcfile=$arg
+	  lastarg="$srcfile"
+	  srcfile="$arg"
 	  ;;
 	esac  #  case $arg
 	;;
@@ -3359,13 +2043,13 @@ func_mode_compile ()
       func_fatal_error "you must specify an argument for -Xcompile"
       ;;
     target)
-      func_fatal_error "you must specify a target with '-o'"
+      func_fatal_error "you must specify a target with \`-o'"
       ;;
     *)
       # Get the name of the library object.
       test -z "$libobj" && {
 	func_basename "$srcfile"
-	libobj=$func_basename_result
+	libobj="$func_basename_result"
       }
       ;;
     esac
@@ -3385,7 +2069,7 @@ func_mode_compile ()
     case $libobj in
     *.lo) func_lo2o "$libobj"; obj=$func_lo2o_result ;;
     *)
-      func_fatal_error "cannot determine name of library object from '$libobj'"
+      func_fatal_error "cannot determine name of library object from \`$libobj'"
       ;;
     esac
 
@@ -3394,8 +2078,8 @@ func_mode_compile ()
     for arg in $later; do
       case $arg in
       -shared)
-	test yes = "$build_libtool_libs" \
-	  || func_fatal_configuration "cannot build a shared library"
+	test "$build_libtool_libs" != yes && \
+	  func_fatal_configuration "can not build a shared library"
 	build_old_libs=no
 	continue
 	;;
@@ -3421,17 +2105,17 @@ func_mode_compile ()
     func_quote_for_eval "$libobj"
     test "X$libobj" != "X$func_quote_for_eval_result" \
       && $ECHO "X$libobj" | $GREP '[]~#^*{};<>?"'"'"'	 &()|`$[]' \
-      && func_warning "libobj name '$libobj' may not contain shell special characters."
+      && func_warning "libobj name \`$libobj' may not contain shell special characters."
     func_dirname_and_basename "$obj" "/" ""
-    objname=$func_basename_result
-    xdir=$func_dirname_result
-    lobj=$xdir$objdir/$objname
+    objname="$func_basename_result"
+    xdir="$func_dirname_result"
+    lobj=${xdir}$objdir/$objname
 
     test -z "$base_compile" && \
       func_fatal_help "you must specify a compilation command"
 
     # Delete any leftover library objects.
-    if test yes = "$build_old_libs"; then
+    if test "$build_old_libs" = yes; then
       removelist="$obj $lobj $libobj ${libobj}T"
     else
       removelist="$lobj $libobj ${libobj}T"
@@ -3443,16 +2127,16 @@ func_mode_compile ()
       pic_mode=default
       ;;
     esac
-    if test no = "$pic_mode" && test pass_all != "$deplibs_check_method"; then
+    if test "$pic_mode" = no && test "$deplibs_check_method" != pass_all; then
       # non-PIC code in shared libraries is not supported
       pic_mode=default
     fi
 
     # Calculate the filename of the output object if compiler does
     # not support -o with -c
-    if test no = "$compiler_c_o"; then
-      output_obj=`$ECHO "$srcfile" | $SED 's%^.*/%%; s%\.[^.]*$%%'`.$objext
-      lockfile=$output_obj.lock
+    if test "$compiler_c_o" = no; then
+      output_obj=`$ECHO "$srcfile" | $SED 's%^.*/%%; s%\.[^.]*$%%'`.${objext}
+      lockfile="$output_obj.lock"
     else
       output_obj=
       need_locks=no
@@ -3461,12 +2145,12 @@ func_mode_compile ()
 
     # Lock this critical section if it is needed
     # We use this script file to make the link, it avoids creating a new file
-    if test yes = "$need_locks"; then
+    if test "$need_locks" = yes; then
       until $opt_dry_run || ln "$progpath" "$lockfile" 2>/dev/null; do
 	func_echo "Waiting for $lockfile to be removed"
 	sleep 2
       done
-    elif test warn = "$need_locks"; then
+    elif test "$need_locks" = warn; then
       if test -f "$lockfile"; then
 	$ECHO "\
 *** ERROR, $lockfile exists and contains:
@@ -3474,7 +2158,7 @@ func_mode_compile ()
 
 This indicates that another process is trying to use the same
 temporary object file, and libtool could not work around it because
-your compiler does not support '-c' and '-o' together.  If you
+your compiler does not support \`-c' and \`-o' together.  If you
 repeat this compilation, it may succeed, by chance, but you had better
 avoid parallel builds (make -j) in this platform, or get a better
 compiler."
@@ -3496,11 +2180,11 @@ compiler."
     qsrcfile=$func_quote_for_eval_result
 
     # Only build a PIC object if we are building libtool libraries.
-    if test yes = "$build_libtool_libs"; then
+    if test "$build_libtool_libs" = yes; then
       # Without this assignment, base_compile gets emptied.
       fbsd_hideous_sh_bug=$base_compile
 
-      if test no != "$pic_mode"; then
+      if test "$pic_mode" != no; then
 	command="$base_compile $qsrcfile $pic_flag"
       else
 	# Don't build PIC code
@@ -3517,7 +2201,7 @@ compiler."
       func_show_eval_locale "$command"	\
           'test -n "$output_obj" && $RM $removelist; exit $EXIT_FAILURE'
 
-      if test warn = "$need_locks" &&
+      if test "$need_locks" = warn &&
 	 test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then
 	$ECHO "\
 *** ERROR, $lockfile contains:
@@ -3528,7 +2212,7 @@ $srcfile
 
 This indicates that another process is trying to use the same
 temporary object file, and libtool could not work around it because
-your compiler does not support '-c' and '-o' together.  If you
+your compiler does not support \`-c' and \`-o' together.  If you
 repeat this compilation, it may succeed, by chance, but you had better
 avoid parallel builds (make -j) in this platform, or get a better
 compiler."
@@ -3544,20 +2228,20 @@ compiler."
       fi
 
       # Allow error messages only from the first compilation.
-      if test yes = "$suppress_opt"; then
+      if test "$suppress_opt" = yes; then
 	suppress_output=' >/dev/null 2>&1'
       fi
     fi
 
     # Only build a position-dependent object if we build old libraries.
-    if test yes = "$build_old_libs"; then
-      if test yes != "$pic_mode"; then
+    if test "$build_old_libs" = yes; then
+      if test "$pic_mode" != yes; then
 	# Don't build PIC code
 	command="$base_compile $qsrcfile$pie_flag"
       else
 	command="$base_compile $qsrcfile $pic_flag"
       fi
-      if test yes = "$compiler_c_o"; then
+      if test "$compiler_c_o" = yes; then
 	func_append command " -o $obj"
       fi
 
@@ -3566,7 +2250,7 @@ compiler."
       func_show_eval_locale "$command" \
         '$opt_dry_run || $RM $removelist; exit $EXIT_FAILURE'
 
-      if test warn = "$need_locks" &&
+      if test "$need_locks" = warn &&
 	 test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then
 	$ECHO "\
 *** ERROR, $lockfile contains:
@@ -3577,7 +2261,7 @@ $srcfile
 
 This indicates that another process is trying to use the same
 temporary object file, and libtool could not work around it because
-your compiler does not support '-c' and '-o' together.  If you
+your compiler does not support \`-c' and \`-o' together.  If you
 repeat this compilation, it may succeed, by chance, but you had better
 avoid parallel builds (make -j) in this platform, or get a better
 compiler."
@@ -3597,7 +2281,7 @@ compiler."
       func_write_libtool_object "$libobj" "$objdir/$objname" "$objname"
 
       # Unlock the critical section if it was locked
-      if test no != "$need_locks"; then
+      if test "$need_locks" != no; then
 	removelist=$lockfile
         $RM "$lockfile"
       fi
@@ -3607,7 +2291,7 @@ compiler."
 }
 
 $opt_help || {
-  test compile = "$opt_mode" && func_mode_compile ${1+"$@"}
+  test "$opt_mode" = compile && func_mode_compile ${1+"$@"}
 }
 
 func_mode_help ()
@@ -3627,7 +2311,7 @@ func_mode_help ()
 Remove files from the build directory.
 
 RM is the name of the program to use to delete files associated with each FILE
-(typically '/bin/rm').  RM-OPTIONS are options (such as '-f') to be passed
+(typically \`/bin/rm').  RM-OPTIONS are options (such as \`-f') to be passed
 to RM.
 
 If FILE is a libtool library, object or program, all the files associated
@@ -3646,16 +2330,16 @@ This mode accepts the following additional options:
   -no-suppress      do not suppress compiler output for multiple passes
   -prefer-pic       try to build PIC objects only
   -prefer-non-pic   try to build non-PIC objects only
-  -shared           do not build a '.o' file suitable for static linking
-  -static           only build a '.o' file suitable for static linking
+  -shared           do not build a \`.o' file suitable for static linking
+  -static           only build a \`.o' file suitable for static linking
   -Wc,FLAG          pass FLAG directly to the compiler
 
-COMPILE-COMMAND is a command to be used in creating a 'standard' object file
+COMPILE-COMMAND is a command to be used in creating a \`standard' object file
 from the given SOURCEFILE.
 
 The output file name is determined by removing the directory component from
-SOURCEFILE, then substituting the C source code suffix '.c' with the
-library object suffix, '.lo'."
+SOURCEFILE, then substituting the C source code suffix \`.c' with the
+library object suffix, \`.lo'."
         ;;
 
       execute)
@@ -3668,7 +2352,7 @@ This mode accepts the following additional options:
 
   -dlopen FILE      add the directory containing FILE to the library path
 
-This mode sets the library path environment variable according to '-dlopen'
+This mode sets the library path environment variable according to \`-dlopen'
 flags.
 
 If any of the ARGS are libtool executable wrappers, then they are translated
@@ -3687,7 +2371,7 @@ Complete the installation of libtool libraries.
 Each LIBDIR is a directory that contains libtool libraries.
 
 The commands that this mode executes may require superuser privileges.  Use
-the '--dry-run' option if you just want to see what would be executed."
+the \`--dry-run' option if you just want to see what would be executed."
         ;;
 
       install)
@@ -3697,7 +2381,7 @@ the '--dry-run' option if you just want to see what would be executed."
 Install executables or libraries.
 
 INSTALL-COMMAND is the installation command.  The first component should be
-either the 'install' or 'cp' program.
+either the \`install' or \`cp' program.
 
 The following components of INSTALL-COMMAND are treated specially:
 
@@ -3723,7 +2407,7 @@ The following components of LINK-COMMAND are treated specially:
   -avoid-version    do not add a version suffix if possible
   -bindir BINDIR    specify path to binaries directory (for systems where
                     libraries must be found in the PATH setting at runtime)
-  -dlopen FILE      '-dlpreopen' FILE if it cannot be dlopened at runtime
+  -dlopen FILE      \`-dlpreopen' FILE if it cannot be dlopened at runtime
   -dlpreopen FILE   link in FILE and add its symbols to lt_preloaded_symbols
   -export-dynamic   allow symbols from OUTPUT-FILE to be resolved with dlsym(3)
   -export-symbols SYMFILE
@@ -3737,8 +2421,7 @@ The following components of LINK-COMMAND are treated specially:
   -no-install       link a not-installable executable
   -no-undefined     declare that a library does not refer to external symbols
   -o OUTPUT-FILE    create OUTPUT-FILE from the specified objects
-  -objectlist FILE  use a list of object files found in FILE to specify objects
-  -os2dllname NAME  force a short DLL name on OS/2 (no effect on other OSes)
+  -objectlist FILE  Use a list of object files found in FILE to specify objects
   -precious-files-regex REGEX
                     don't remove output files matching REGEX
   -release RELEASE  specify package release information
@@ -3758,20 +2441,20 @@ The following components of LINK-COMMAND are treated specially:
   -Xlinker FLAG     pass linker-specific FLAG directly to the linker
   -XCClinker FLAG   pass link-specific FLAG to the compiler driver (CC)
 
-All other options (arguments beginning with '-') are ignored.
+All other options (arguments beginning with \`-') are ignored.
 
-Every other argument is treated as a filename.  Files ending in '.la' are
+Every other argument is treated as a filename.  Files ending in \`.la' are
 treated as uninstalled libtool libraries, other files are standard or library
 object files.
 
-If the OUTPUT-FILE ends in '.la', then a libtool library is created,
-only library objects ('.lo' files) may be specified, and '-rpath' is
+If the OUTPUT-FILE ends in \`.la', then a libtool library is created,
+only library objects (\`.lo' files) may be specified, and \`-rpath' is
 required, except when creating a convenience library.
 
-If OUTPUT-FILE ends in '.a' or '.lib', then a standard library is created
-using 'ar' and 'ranlib', or on Windows using 'lib'.
+If OUTPUT-FILE ends in \`.a' or \`.lib', then a standard library is created
+using \`ar' and \`ranlib', or on Windows using \`lib'.
 
-If OUTPUT-FILE ends in '.lo' or '.$objext', then a reloadable object file
+If OUTPUT-FILE ends in \`.lo' or \`.${objext}', then a reloadable object file
 is created, otherwise an executable program is created."
         ;;
 
@@ -3782,7 +2465,7 @@ is created, otherwise an executable program is created."
 Remove libraries from an installation directory.
 
 RM is the name of the program to use to delete files associated with each FILE
-(typically '/bin/rm').  RM-OPTIONS are options (such as '-f') to be passed
+(typically \`/bin/rm').  RM-OPTIONS are options (such as \`-f') to be passed
 to RM.
 
 If FILE is a libtool library, all the files associated with it are deleted.
@@ -3790,17 +2473,17 @@ Otherwise, only FILE itself is deleted using RM."
         ;;
 
       *)
-        func_fatal_help "invalid operation mode '$opt_mode'"
+        func_fatal_help "invalid operation mode \`$opt_mode'"
         ;;
     esac
 
     echo
-    $ECHO "Try '$progname --help' for more information about other modes."
+    $ECHO "Try \`$progname --help' for more information about other modes."
 }
 
 # Now that we've collected a possible --mode arg, show help if necessary
 if $opt_help; then
-  if test : = "$opt_help"; then
+  if test "$opt_help" = :; then
     func_mode_help
   else
     {
@@ -3808,7 +2491,7 @@ if $opt_help; then
       for opt_mode in compile link execute install finish uninstall clean; do
 	func_mode_help
       done
-    } | $SED -n '1p; 2,$s/^Usage:/  or: /p'
+    } | sed -n '1p; 2,$s/^Usage:/  or: /p'
     {
       func_help noexit
       for opt_mode in compile link execute install finish uninstall clean; do
@@ -3816,7 +2499,7 @@ if $opt_help; then
 	func_mode_help
       done
     } |
-    $SED '1d
+    sed '1d
       /^When reporting/,/^Report/{
 	H
 	d
@@ -3833,17 +2516,16 @@ fi
 # func_mode_execute arg...
 func_mode_execute ()
 {
-    $debug_cmd
-
+    $opt_debug
     # The first argument is the command name.
-    cmd=$nonopt
+    cmd="$nonopt"
     test -z "$cmd" && \
       func_fatal_help "you must specify a COMMAND"
 
     # Handle -dlopen flags immediately.
     for file in $opt_dlopen; do
       test -f "$file" \
-	|| func_fatal_help "'$file' is not a file"
+	|| func_fatal_help "\`$file' is not a file"
 
       dir=
       case $file in
@@ -3853,7 +2535,7 @@ func_mode_execute ()
 
 	# Check to see that this really is a libtool archive.
 	func_lalib_unsafe_p "$file" \
-	  || func_fatal_help "'$lib' is not a valid libtool archive"
+	  || func_fatal_help "\`$lib' is not a valid libtool archive"
 
 	# Read the libtool library.
 	dlname=
@@ -3864,18 +2546,18 @@ func_mode_execute ()
 	if test -z "$dlname"; then
 	  # Warn if it was a shared library.
 	  test -n "$library_names" && \
-	    func_warning "'$file' was not linked with '-export-dynamic'"
+	    func_warning "\`$file' was not linked with \`-export-dynamic'"
 	  continue
 	fi
 
 	func_dirname "$file" "" "."
-	dir=$func_dirname_result
+	dir="$func_dirname_result"
 
 	if test -f "$dir/$objdir/$dlname"; then
 	  func_append dir "/$objdir"
 	else
 	  if test ! -f "$dir/$dlname"; then
-	    func_fatal_error "cannot find '$dlname' in '$dir' or '$dir/$objdir'"
+	    func_fatal_error "cannot find \`$dlname' in \`$dir' or \`$dir/$objdir'"
 	  fi
 	fi
 	;;
@@ -3883,18 +2565,18 @@ func_mode_execute ()
       *.lo)
 	# Just add the directory containing the .lo file.
 	func_dirname "$file" "" "."
-	dir=$func_dirname_result
+	dir="$func_dirname_result"
 	;;
 
       *)
-	func_warning "'-dlopen' is ignored for non-libtool libraries and objects"
+	func_warning "\`-dlopen' is ignored for non-libtool libraries and objects"
 	continue
 	;;
       esac
 
       # Get the absolute pathname.
       absdir=`cd "$dir" && pwd`
-      test -n "$absdir" && dir=$absdir
+      test -n "$absdir" && dir="$absdir"
 
       # Now add the directory to shlibpath_var.
       if eval "test -z \"\$$shlibpath_var\""; then
@@ -3906,7 +2588,7 @@ func_mode_execute ()
 
     # This variable tells wrapper scripts just to set shlibpath_var
     # rather than running their programs.
-    libtool_execute_magic=$magic
+    libtool_execute_magic="$magic"
 
     # Check if any of the arguments is a wrapper script.
     args=
@@ -3919,12 +2601,12 @@ func_mode_execute ()
 	if func_ltwrapper_script_p "$file"; then
 	  func_source "$file"
 	  # Transform arg to wrapped name.
-	  file=$progdir/$program
+	  file="$progdir/$program"
 	elif func_ltwrapper_executable_p "$file"; then
 	  func_ltwrapper_scriptname "$file"
 	  func_source "$func_ltwrapper_scriptname_result"
 	  # Transform arg to wrapped name.
-	  file=$progdir/$program
+	  file="$progdir/$program"
 	fi
 	;;
       esac
@@ -3932,15 +2614,7 @@ func_mode_execute ()
       func_append_quoted args "$file"
     done
 
-    if $opt_dry_run; then
-      # Display what would be done.
-      if test -n "$shlibpath_var"; then
-	eval "\$ECHO \"\$shlibpath_var=\$$shlibpath_var\""
-	echo "export $shlibpath_var"
-      fi
-      $ECHO "$cmd$args"
-      exit $EXIT_SUCCESS
-    else
+    if test "X$opt_dry_run" = Xfalse; then
       if test -n "$shlibpath_var"; then
 	# Export the shlibpath_var.
 	eval "export $shlibpath_var"
@@ -3957,18 +2631,25 @@ func_mode_execute ()
       done
 
       # Now prepare to actually exec the command.
-      exec_cmd=\$cmd$args
+      exec_cmd="\$cmd$args"
+    else
+      # Display what would be done.
+      if test -n "$shlibpath_var"; then
+	eval "\$ECHO \"\$shlibpath_var=\$$shlibpath_var\""
+	echo "export $shlibpath_var"
+      fi
+      $ECHO "$cmd$args"
+      exit $EXIT_SUCCESS
     fi
 }
 
-test execute = "$opt_mode" && func_mode_execute ${1+"$@"}
+test "$opt_mode" = execute && func_mode_execute ${1+"$@"}
 
 
 # func_mode_finish arg...
 func_mode_finish ()
 {
-    $debug_cmd
-
+    $opt_debug
     libs=
     libdirs=
     admincmds=
@@ -3982,11 +2663,11 @@ func_mode_finish ()
 	if func_lalib_unsafe_p "$opt"; then
 	  func_append libs " $opt"
 	else
-	  func_warning "'$opt' is not a valid libtool archive"
+	  func_warning "\`$opt' is not a valid libtool archive"
 	fi
 
       else
-	func_fatal_error "invalid argument '$opt'"
+	func_fatal_error "invalid argument \`$opt'"
       fi
     done
 
@@ -4001,12 +2682,12 @@ func_mode_finish ()
       # Remove sysroot references
       if $opt_dry_run; then
         for lib in $libs; do
-          echo "removing references to $lt_sysroot and '=' prefixes from $lib"
+          echo "removing references to $lt_sysroot and \`=' prefixes from $lib"
         done
       else
         tmpdir=`func_mktempdir`
         for lib in $libs; do
-	  $SED -e "$sysroot_cmd s/\([ ']-[LR]\)=/\1/g; s/\([ ']\)=/\1/g" $lib \
+	  sed -e "${sysroot_cmd} s/\([ ']-[LR]\)=/\1/g; s/\([ ']\)=/\1/g" $lib \
 	    > $tmpdir/tmp-la
 	  mv -f $tmpdir/tmp-la $lib
 	done
@@ -4031,7 +2712,7 @@ func_mode_finish ()
     fi
 
     # Exit here if they wanted silent mode.
-    $opt_quiet && exit $EXIT_SUCCESS
+    $opt_silent && exit $EXIT_SUCCESS
 
     if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then
       echo "----------------------------------------------------------------------"
@@ -4042,27 +2723,27 @@ func_mode_finish ()
       echo
       echo "If you ever happen to want to link against installed libraries"
       echo "in a given directory, LIBDIR, you must either use libtool, and"
-      echo "specify the full pathname of the library, or use the '-LLIBDIR'"
+      echo "specify the full pathname of the library, or use the \`-LLIBDIR'"
       echo "flag during linking and do at least one of the following:"
       if test -n "$shlibpath_var"; then
-	echo "   - add LIBDIR to the '$shlibpath_var' environment variable"
+	echo "   - add LIBDIR to the \`$shlibpath_var' environment variable"
 	echo "     during execution"
       fi
       if test -n "$runpath_var"; then
-	echo "   - add LIBDIR to the '$runpath_var' environment variable"
+	echo "   - add LIBDIR to the \`$runpath_var' environment variable"
 	echo "     during linking"
       fi
       if test -n "$hardcode_libdir_flag_spec"; then
 	libdir=LIBDIR
 	eval flag=\"$hardcode_libdir_flag_spec\"
 
-	$ECHO "   - use the '$flag' linker flag"
+	$ECHO "   - use the \`$flag' linker flag"
       fi
       if test -n "$admincmds"; then
 	$ECHO "   - have your system administrator run these commands:$admincmds"
       fi
       if test -f /etc/ld.so.conf; then
-	echo "   - have your system administrator add LIBDIR to '/etc/ld.so.conf'"
+	echo "   - have your system administrator add LIBDIR to \`/etc/ld.so.conf'"
       fi
       echo
 
@@ -4081,20 +2762,18 @@ func_mode_finish ()
     exit $EXIT_SUCCESS
 }
 
-test finish = "$opt_mode" && func_mode_finish ${1+"$@"}
+test "$opt_mode" = finish && func_mode_finish ${1+"$@"}
 
 
 # func_mode_install arg...
 func_mode_install ()
 {
-    $debug_cmd
-
+    $opt_debug
     # There may be an optional sh(1) argument at the beginning of
     # install_prog (especially on Windows NT).
-    if test "$SHELL" = "$nonopt" || test /bin/sh = "$nonopt" ||
+    if test "$nonopt" = "$SHELL" || test "$nonopt" = /bin/sh ||
        # Allow the use of GNU shtool's install command.
-       case $nonopt in *shtool*) :;; *) false;; esac
-    then
+       case $nonopt in *shtool*) :;; *) false;; esac; then
       # Aesthetically quote it.
       func_quote_for_eval "$nonopt"
       install_prog="$func_quote_for_eval_result "
@@ -4121,7 +2800,7 @@ func_mode_install ()
     opts=
     prev=
     install_type=
-    isdir=false
+    isdir=no
     stripme=
     no_mode=:
     for arg
@@ -4134,7 +2813,7 @@ func_mode_install ()
       fi
 
       case $arg in
-      -d) isdir=: ;;
+      -d) isdir=yes ;;
       -f)
 	if $install_cp; then :; else
 	  prev=$arg
@@ -4152,7 +2831,7 @@ func_mode_install ()
       *)
 	# If the previous option needed an argument, then skip it.
 	if test -n "$prev"; then
-	  if test X-m = "X$prev" && test -n "$install_override_mode"; then
+	  if test "x$prev" = x-m && test -n "$install_override_mode"; then
 	    arg2=$install_override_mode
 	    no_mode=false
 	  fi
@@ -4177,7 +2856,7 @@ func_mode_install ()
       func_fatal_help "you must specify an install program"
 
     test -n "$prev" && \
-      func_fatal_help "the '$prev' option requires an argument"
+      func_fatal_help "the \`$prev' option requires an argument"
 
     if test -n "$install_override_mode" && $no_mode; then
       if $install_cp; then :; else
@@ -4199,19 +2878,19 @@ func_mode_install ()
     dest=$func_stripname_result
 
     # Check to see that the destination is a directory.
-    test -d "$dest" && isdir=:
-    if $isdir; then
-      destdir=$dest
+    test -d "$dest" && isdir=yes
+    if test "$isdir" = yes; then
+      destdir="$dest"
       destname=
     else
       func_dirname_and_basename "$dest" "" "."
-      destdir=$func_dirname_result
-      destname=$func_basename_result
+      destdir="$func_dirname_result"
+      destname="$func_basename_result"
 
       # Not a directory, so check to see that there is only one file specified.
       set dummy $files; shift
       test "$#" -gt 1 && \
-	func_fatal_help "'$dest' is not a directory"
+	func_fatal_help "\`$dest' is not a directory"
     fi
     case $destdir in
     [\\/]* | [A-Za-z]:[\\/]*) ;;
@@ -4220,7 +2899,7 @@ func_mode_install ()
 	case $file in
 	*.lo) ;;
 	*)
-	  func_fatal_help "'$destdir' must be an absolute directory name"
+	  func_fatal_help "\`$destdir' must be an absolute directory name"
 	  ;;
 	esac
       done
@@ -4229,7 +2908,7 @@ func_mode_install ()
 
     # This variable tells wrapper scripts just to set variables rather
     # than running their programs.
-    libtool_install_magic=$magic
+    libtool_install_magic="$magic"
 
     staticlibs=
     future_libdirs=
@@ -4249,7 +2928,7 @@ func_mode_install ()
 
 	# Check to see that this really is a libtool archive.
 	func_lalib_unsafe_p "$file" \
-	  || func_fatal_help "'$file' is not a valid libtool archive"
+	  || func_fatal_help "\`$file' is not a valid libtool archive"
 
 	library_names=
 	old_library=
@@ -4271,7 +2950,7 @@ func_mode_install ()
 	fi
 
 	func_dirname "$file" "/" ""
-	dir=$func_dirname_result
+	dir="$func_dirname_result"
 	func_append dir "$objdir"
 
 	if test -n "$relink_command"; then
@@ -4285,7 +2964,7 @@ func_mode_install ()
 	  # are installed into $libdir/../bin (currently, that works fine)
 	  # but it's something to keep an eye on.
 	  test "$inst_prefix_dir" = "$destdir" && \
-	    func_fatal_error "error: cannot install '$file' to a directory not ending in $libdir"
+	    func_fatal_error "error: cannot install \`$file' to a directory not ending in $libdir"
 
 	  if test -n "$inst_prefix_dir"; then
 	    # Stick the inst_prefix_dir data into the link command.
@@ -4294,36 +2973,29 @@ func_mode_install ()
 	    relink_command=`$ECHO "$relink_command" | $SED "s%@inst_prefix_dir@%%"`
 	  fi
 
-	  func_warning "relinking '$file'"
+	  func_warning "relinking \`$file'"
 	  func_show_eval "$relink_command" \
-	    'func_fatal_error "error: relink '\''$file'\'' with the above command before installing it"'
+	    'func_fatal_error "error: relink \`$file'\'' with the above command before installing it"'
 	fi
 
 	# See the names of the shared library.
 	set dummy $library_names; shift
 	if test -n "$1"; then
-	  realname=$1
+	  realname="$1"
 	  shift
 
-	  srcname=$realname
-	  test -n "$relink_command" && srcname=${realname}T
+	  srcname="$realname"
+	  test -n "$relink_command" && srcname="$realname"T
 
 	  # Install the shared library and build the symlinks.
 	  func_show_eval "$install_shared_prog $dir/$srcname $destdir/$realname" \
 	      'exit $?'
-	  tstripme=$stripme
+	  tstripme="$stripme"
 	  case $host_os in
 	  cygwin* | mingw* | pw32* | cegcc*)
 	    case $realname in
 	    *.dll.a)
-	      tstripme=
-	      ;;
-	    esac
-	    ;;
-	  os2*)
-	    case $realname in
-	    *_dll.a)
-	      tstripme=
+	      tstripme=""
 	      ;;
 	    esac
 	    ;;
@@ -4334,7 +3006,7 @@ func_mode_install ()
 
 	  if test "$#" -gt 0; then
 	    # Delete the old symlinks, and create new ones.
-	    # Try 'ln -sf' first, because the 'ln' binary might depend on
+	    # Try `ln -sf' first, because the `ln' binary might depend on
 	    # the symlink we replace!  Solaris /bin/ln does not understand -f,
 	    # so we also need to try rm && ln -s.
 	    for linkname
@@ -4345,14 +3017,14 @@ func_mode_install ()
 	  fi
 
 	  # Do each command in the postinstall commands.
-	  lib=$destdir/$realname
+	  lib="$destdir/$realname"
 	  func_execute_cmds "$postinstall_cmds" 'exit $?'
 	fi
 
 	# Install the pseudo-library for information purposes.
 	func_basename "$file"
-	name=$func_basename_result
-	instname=$dir/${name}i
+	name="$func_basename_result"
+	instname="$dir/$name"i
 	func_show_eval "$install_prog $instname $destdir/$name" 'exit $?'
 
 	# Maybe install the static library, too.
@@ -4364,11 +3036,11 @@ func_mode_install ()
 
 	# Figure out destination file name, if it wasn't already specified.
 	if test -n "$destname"; then
-	  destfile=$destdir/$destname
+	  destfile="$destdir/$destname"
 	else
 	  func_basename "$file"
-	  destfile=$func_basename_result
-	  destfile=$destdir/$destfile
+	  destfile="$func_basename_result"
+	  destfile="$destdir/$destfile"
 	fi
 
 	# Deduce the name of the destination old-style object file.
@@ -4378,11 +3050,11 @@ func_mode_install ()
 	  staticdest=$func_lo2o_result
 	  ;;
 	*.$objext)
-	  staticdest=$destfile
+	  staticdest="$destfile"
 	  destfile=
 	  ;;
 	*)
-	  func_fatal_help "cannot copy a libtool object to '$destfile'"
+	  func_fatal_help "cannot copy a libtool object to \`$destfile'"
 	  ;;
 	esac
 
@@ -4391,7 +3063,7 @@ func_mode_install ()
 	  func_show_eval "$install_prog $file $destfile" 'exit $?'
 
 	# Install the old object if enabled.
-	if test yes = "$build_old_libs"; then
+	if test "$build_old_libs" = yes; then
 	  # Deduce the name of the old-style object file.
 	  func_lo2o "$file"
 	  staticobj=$func_lo2o_result
@@ -4403,23 +3075,23 @@ func_mode_install ()
       *)
 	# Figure out destination file name, if it wasn't already specified.
 	if test -n "$destname"; then
-	  destfile=$destdir/$destname
+	  destfile="$destdir/$destname"
 	else
 	  func_basename "$file"
-	  destfile=$func_basename_result
-	  destfile=$destdir/$destfile
+	  destfile="$func_basename_result"
+	  destfile="$destdir/$destfile"
 	fi
 
 	# If the file is missing, and there is a .exe on the end, strip it
 	# because it is most likely a libtool script we actually want to
 	# install
-	stripped_ext=
+	stripped_ext=""
 	case $file in
 	  *.exe)
 	    if test ! -f "$file"; then
 	      func_stripname '' '.exe' "$file"
 	      file=$func_stripname_result
-	      stripped_ext=.exe
+	      stripped_ext=".exe"
 	    fi
 	    ;;
 	esac
@@ -4447,19 +3119,19 @@ func_mode_install ()
 
 	  # Check the variables that should have been set.
 	  test -z "$generated_by_libtool_version" && \
-	    func_fatal_error "invalid libtool wrapper script '$wrapper'"
+	    func_fatal_error "invalid libtool wrapper script \`$wrapper'"
 
-	  finalize=:
+	  finalize=yes
 	  for lib in $notinst_deplibs; do
 	    # Check to see that each library is installed.
 	    libdir=
 	    if test -f "$lib"; then
 	      func_source "$lib"
 	    fi
-	    libfile=$libdir/`$ECHO "$lib" | $SED 's%^.*/%%g'`
+	    libfile="$libdir/"`$ECHO "$lib" | $SED 's%^.*/%%g'` ### testsuite: skip nested quoting test
 	    if test -n "$libdir" && test ! -f "$libfile"; then
-	      func_warning "'$lib' has not been installed in '$libdir'"
-	      finalize=false
+	      func_warning "\`$lib' has not been installed in \`$libdir'"
+	      finalize=no
 	    fi
 	  done
 
@@ -4467,29 +3139,29 @@ func_mode_install ()
 	  func_source "$wrapper"
 
 	  outputname=
-	  if test no = "$fast_install" && test -n "$relink_command"; then
+	  if test "$fast_install" = no && test -n "$relink_command"; then
 	    $opt_dry_run || {
-	      if $finalize; then
+	      if test "$finalize" = yes; then
 	        tmpdir=`func_mktempdir`
 		func_basename "$file$stripped_ext"
-		file=$func_basename_result
-	        outputname=$tmpdir/$file
+		file="$func_basename_result"
+	        outputname="$tmpdir/$file"
 	        # Replace the output file specification.
 	        relink_command=`$ECHO "$relink_command" | $SED 's%@OUTPUT@%'"$outputname"'%g'`
 
-	        $opt_quiet || {
+	        $opt_silent || {
 	          func_quote_for_expand "$relink_command"
 		  eval "func_echo $func_quote_for_expand_result"
 	        }
 	        if eval "$relink_command"; then :
 	          else
-		  func_error "error: relink '$file' with the above command before installing it"
+		  func_error "error: relink \`$file' with the above command before installing it"
 		  $opt_dry_run || ${RM}r "$tmpdir"
 		  continue
 	        fi
-	        file=$outputname
+	        file="$outputname"
 	      else
-	        func_warning "cannot relink '$file'"
+	        func_warning "cannot relink \`$file'"
 	      fi
 	    }
 	  else
@@ -4526,10 +3198,10 @@ func_mode_install ()
 
     for file in $staticlibs; do
       func_basename "$file"
-      name=$func_basename_result
+      name="$func_basename_result"
 
       # Set up the ranlib parameters.
-      oldlib=$destdir/$name
+      oldlib="$destdir/$name"
       func_to_tool_file "$oldlib" func_convert_file_msys_to_w32
       tool_oldlib=$func_to_tool_file_result
 
@@ -4544,18 +3216,18 @@ func_mode_install ()
     done
 
     test -n "$future_libdirs" && \
-      func_warning "remember to run '$progname --finish$future_libdirs'"
+      func_warning "remember to run \`$progname --finish$future_libdirs'"
 
     if test -n "$current_libdirs"; then
       # Maybe just do a dry run.
       $opt_dry_run && current_libdirs=" -n$current_libdirs"
-      exec_cmd='$SHELL "$progpath" $preserve_args --finish$current_libdirs'
+      exec_cmd='$SHELL $progpath $preserve_args --finish$current_libdirs'
     else
       exit $EXIT_SUCCESS
     fi
 }
 
-test install = "$opt_mode" && func_mode_install ${1+"$@"}
+test "$opt_mode" = install && func_mode_install ${1+"$@"}
 
 
 # func_generate_dlsyms outputname originator pic_p
@@ -4563,17 +3235,16 @@ test install = "$opt_mode" && func_mode_install ${1+"$@"}
 # a dlpreopen symbol table.
 func_generate_dlsyms ()
 {
-    $debug_cmd
-
-    my_outputname=$1
-    my_originator=$2
-    my_pic_p=${3-false}
-    my_prefix=`$ECHO "$my_originator" | $SED 's%[^a-zA-Z0-9]%_%g'`
+    $opt_debug
+    my_outputname="$1"
+    my_originator="$2"
+    my_pic_p="${3-no}"
+    my_prefix=`$ECHO "$my_originator" | sed 's%[^a-zA-Z0-9]%_%g'`
     my_dlsyms=
 
-    if test -n "$dlfiles$dlprefiles" || test no != "$dlself"; then
+    if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then
       if test -n "$NM" && test -n "$global_symbol_pipe"; then
-	my_dlsyms=${my_outputname}S.c
+	my_dlsyms="${my_outputname}S.c"
       else
 	func_error "not configured to extract global symbols from dlpreopened files"
       fi
@@ -4584,7 +3255,7 @@ func_generate_dlsyms ()
       "") ;;
       *.c)
 	# Discover the nlist of each of the dlfiles.
-	nlist=$output_objdir/$my_outputname.nm
+	nlist="$output_objdir/${my_outputname}.nm"
 
 	func_show_eval "$RM $nlist ${nlist}S ${nlist}T"
 
@@ -4592,36 +3263,34 @@ func_generate_dlsyms ()
 	func_verbose "creating $output_objdir/$my_dlsyms"
 
 	$opt_dry_run || $ECHO > "$output_objdir/$my_dlsyms" "\
-/* $my_dlsyms - symbol resolution table for '$my_outputname' dlsym emulation. */
-/* Generated by $PROGRAM (GNU $PACKAGE) $VERSION */
+/* $my_dlsyms - symbol resolution table for \`$my_outputname' dlsym emulation. */
+/* Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION */
 
 #ifdef __cplusplus
 extern \"C\" {
 #endif
 
-#if defined __GNUC__ && (((__GNUC__ == 4) && (__GNUC_MINOR__ >= 4)) || (__GNUC__ > 4))
+#if defined(__GNUC__) && (((__GNUC__ == 4) && (__GNUC_MINOR__ >= 4)) || (__GNUC__ > 4))
 #pragma GCC diagnostic ignored \"-Wstrict-prototypes\"
 #endif
 
 /* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests.  */
-#if defined _WIN32 || defined __CYGWIN__ || defined _WIN32_WCE
-/* DATA imports from DLLs on WIN32 can't be const, because runtime
+#if defined(_WIN32) || defined(__CYGWIN__) || defined(_WIN32_WCE)
+/* DATA imports from DLLs on WIN32 con't be const, because runtime
    relocations are performed -- see ld's documentation on pseudo-relocs.  */
 # define LT_DLSYM_CONST
-#elif defined __osf__
+#elif defined(__osf__)
 /* This system does not cope well with relocations in const data.  */
 # define LT_DLSYM_CONST
 #else
 # define LT_DLSYM_CONST const
 #endif
 
-#define STREQ(s1, s2) (strcmp ((s1), (s2)) == 0)
-
 /* External symbol declarations for the compiler. */\
 "
 
-	if test yes = "$dlself"; then
-	  func_verbose "generating symbol list for '$output'"
+	if test "$dlself" = yes; then
+	  func_verbose "generating symbol list for \`$output'"
 
 	  $opt_dry_run || echo ': @PROGRAM@ ' > "$nlist"
 
@@ -4629,7 +3298,7 @@ extern \"C\" {
 	  progfiles=`$ECHO "$objs$old_deplibs" | $SP2NL | $SED "$lo2o" | $NL2SP`
 	  for progfile in $progfiles; do
 	    func_to_tool_file "$progfile" func_convert_file_msys_to_w32
-	    func_verbose "extracting global C symbols from '$func_to_tool_file_result'"
+	    func_verbose "extracting global C symbols from \`$func_to_tool_file_result'"
 	    $opt_dry_run || eval "$NM $func_to_tool_file_result | $global_symbol_pipe >> '$nlist'"
 	  done
 
@@ -4649,10 +3318,10 @@ extern \"C\" {
 
 	  # Prepare the list of exported symbols
 	  if test -z "$export_symbols"; then
-	    export_symbols=$output_objdir/$outputname.exp
+	    export_symbols="$output_objdir/$outputname.exp"
 	    $opt_dry_run || {
 	      $RM $export_symbols
-	      eval "$SED -n -e '/^: @PROGRAM@ $/d' -e 's/^.* \(.*\)$/\1/p' "'< "$nlist" > "$export_symbols"'
+	      eval "${SED} -n -e '/^: @PROGRAM@ $/d' -e 's/^.* \(.*\)$/\1/p' "'< "$nlist" > "$export_symbols"'
 	      case $host in
 	      *cygwin* | *mingw* | *cegcc* )
                 eval "echo EXPORTS "'> "$output_objdir/$outputname.def"'
@@ -4662,7 +3331,7 @@ extern \"C\" {
 	    }
 	  else
 	    $opt_dry_run || {
-	      eval "$SED -e 's/\([].[*^$]\)/\\\\\1/g' -e 's/^/ /' -e 's/$/$/'"' < "$export_symbols" > "$output_objdir/$outputname.exp"'
+	      eval "${SED} -e 's/\([].[*^$]\)/\\\\\1/g' -e 's/^/ /' -e 's/$/$/'"' < "$export_symbols" > "$output_objdir/$outputname.exp"'
 	      eval '$GREP -f "$output_objdir/$outputname.exp" < "$nlist" > "$nlist"T'
 	      eval '$MV "$nlist"T "$nlist"'
 	      case $host in
@@ -4676,22 +3345,22 @@ extern \"C\" {
 	fi
 
 	for dlprefile in $dlprefiles; do
-	  func_verbose "extracting global C symbols from '$dlprefile'"
+	  func_verbose "extracting global C symbols from \`$dlprefile'"
 	  func_basename "$dlprefile"
-	  name=$func_basename_result
+	  name="$func_basename_result"
           case $host in
 	    *cygwin* | *mingw* | *cegcc* )
 	      # if an import library, we need to obtain dlname
 	      if func_win32_import_lib_p "$dlprefile"; then
 	        func_tr_sh "$dlprefile"
 	        eval "curr_lafile=\$libfile_$func_tr_sh_result"
-	        dlprefile_dlbasename=
+	        dlprefile_dlbasename=""
 	        if test -n "$curr_lafile" && func_lalib_p "$curr_lafile"; then
 	          # Use subshell, to avoid clobbering current variable values
 	          dlprefile_dlname=`source "$curr_lafile" && echo "$dlname"`
-	          if test -n "$dlprefile_dlname"; then
+	          if test -n "$dlprefile_dlname" ; then
 	            func_basename "$dlprefile_dlname"
-	            dlprefile_dlbasename=$func_basename_result
+	            dlprefile_dlbasename="$func_basename_result"
 	          else
 	            # no lafile. user explicitly requested -dlpreopen <import library>.
 	            $sharedlib_from_linklib_cmd "$dlprefile"
@@ -4699,7 +3368,7 @@ extern \"C\" {
 	          fi
 	        fi
 	        $opt_dry_run || {
-	          if test -n "$dlprefile_dlbasename"; then
+	          if test -n "$dlprefile_dlbasename" ; then
 	            eval '$ECHO ": $dlprefile_dlbasename" >> "$nlist"'
 	          else
 	            func_warning "Could not compute DLL name from $name"
@@ -4755,11 +3424,6 @@ extern \"C\" {
 	    echo '/* NONE */' >> "$output_objdir/$my_dlsyms"
 	  fi
 
-	  func_show_eval '$RM "${nlist}I"'
-	  if test -n "$global_symbol_to_import"; then
-	    eval "$global_symbol_to_import"' < "$nlist"S > "$nlist"I'
-	  fi
-
 	  echo >> "$output_objdir/$my_dlsyms" "\
 
 /* The mapping between symbol names and symbols.  */
@@ -4768,30 +3432,11 @@ typedef struct {
   void *address;
 } lt_dlsymlist;
 extern LT_DLSYM_CONST lt_dlsymlist
-lt_${my_prefix}_LTX_preloaded_symbols[];\
-"
-
-	  if test -s "$nlist"I; then
-	    echo >> "$output_objdir/$my_dlsyms" "\
-static void lt_syminit(void)
-{
-  LT_DLSYM_CONST lt_dlsymlist *symbol = lt_${my_prefix}_LTX_preloaded_symbols;
-  for (; symbol->name; ++symbol)
-    {"
-	    $SED 's/.*/      if (STREQ (symbol->name, \"&\")) symbol->address = (void *) \&&;/' < "$nlist"I >> "$output_objdir/$my_dlsyms"
-	    echo >> "$output_objdir/$my_dlsyms" "\
-    }
-}"
-	  fi
-	  echo >> "$output_objdir/$my_dlsyms" "\
+lt_${my_prefix}_LTX_preloaded_symbols[];
 LT_DLSYM_CONST lt_dlsymlist
 lt_${my_prefix}_LTX_preloaded_symbols[] =
-{ {\"$my_originator\", (void *) 0},"
-
-	  if test -s "$nlist"I; then
-	    echo >> "$output_objdir/$my_dlsyms" "\
-  {\"@INIT@\", (void *) &lt_syminit},"
-	  fi
+{\
+  { \"$my_originator\", (void *) 0 },"
 
 	  case $need_lib_prefix in
 	  no)
@@ -4833,7 +3478,9 @@ static const void *lt_preloaded_setup() {
 	  *-*-hpux*)
 	    pic_flag_for_symtable=" $pic_flag"  ;;
 	  *)
-	    $my_pic_p && pic_flag_for_symtable=" $pic_flag"
+	    if test "X$my_pic_p" != Xno; then
+	      pic_flag_for_symtable=" $pic_flag"
+	    fi
 	    ;;
 	  esac
 	  ;;
@@ -4850,10 +3497,10 @@ static const void *lt_preloaded_setup() {
 	func_show_eval '(cd $output_objdir && $LTCC$symtab_cflags -c$no_builtin_flag$pic_flag_for_symtable "$my_dlsyms")' 'exit $?'
 
 	# Clean up the generated files.
-	func_show_eval '$RM "$output_objdir/$my_dlsyms" "$nlist" "${nlist}S" "${nlist}T" "${nlist}I"'
+	func_show_eval '$RM "$output_objdir/$my_dlsyms" "$nlist" "${nlist}S" "${nlist}T"'
 
 	# Transform the symbol file into the correct name.
-	symfileobj=$output_objdir/${my_outputname}S.$objext
+	symfileobj="$output_objdir/${my_outputname}S.$objext"
 	case $host in
 	*cygwin* | *mingw* | *cegcc* )
 	  if test -f "$output_objdir/$my_outputname.def"; then
@@ -4871,7 +3518,7 @@ static const void *lt_preloaded_setup() {
 	esac
 	;;
       *)
-	func_fatal_error "unknown suffix for '$my_dlsyms'"
+	func_fatal_error "unknown suffix for \`$my_dlsyms'"
 	;;
       esac
     else
@@ -4885,32 +3532,6 @@ static const void *lt_preloaded_setup() {
     fi
 }
 
-# func_cygming_gnu_implib_p ARG
-# This predicate returns with zero status (TRUE) if
-# ARG is a GNU/binutils-style import library. Returns
-# with nonzero status (FALSE) otherwise.
-func_cygming_gnu_implib_p ()
-{
-  $debug_cmd
-
-  func_to_tool_file "$1" func_convert_file_msys_to_w32
-  func_cygming_gnu_implib_tmp=`$NM "$func_to_tool_file_result" | eval "$global_symbol_pipe" | $EGREP ' (_head_[A-Za-z0-9_]+_[ad]l*|[A-Za-z0-9_]+_[ad]l*_iname)$'`
-  test -n "$func_cygming_gnu_implib_tmp"
-}
-
-# func_cygming_ms_implib_p ARG
-# This predicate returns with zero status (TRUE) if
-# ARG is an MS-style import library. Returns
-# with nonzero status (FALSE) otherwise.
-func_cygming_ms_implib_p ()
-{
-  $debug_cmd
-
-  func_to_tool_file "$1" func_convert_file_msys_to_w32
-  func_cygming_ms_implib_tmp=`$NM "$func_to_tool_file_result" | eval "$global_symbol_pipe" | $GREP '_NULL_IMPORT_DESCRIPTOR'`
-  test -n "$func_cygming_ms_implib_tmp"
-}
-
 # func_win32_libid arg
 # return the library type of file 'arg'
 #
@@ -4920,9 +3541,8 @@ func_cygming_ms_implib_p ()
 # Despite the name, also deal with 64 bit binaries.
 func_win32_libid ()
 {
-  $debug_cmd
-
-  win32_libid_type=unknown
+  $opt_debug
+  win32_libid_type="unknown"
   win32_fileres=`file -L $1 2>/dev/null`
   case $win32_fileres in
   *ar\ archive\ import\ library*) # definitely import
@@ -4932,29 +3552,16 @@ func_win32_libid ()
     # Keep the egrep pattern in sync with the one in _LT_CHECK_MAGIC_METHOD.
     if eval $OBJDUMP -f $1 | $SED -e '10q' 2>/dev/null |
        $EGREP 'file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)' >/dev/null; then
-      case $nm_interface in
-      "MS dumpbin")
-	if func_cygming_ms_implib_p "$1" ||
-	   func_cygming_gnu_implib_p "$1"
-	then
-	  win32_nmres=import
-	else
-	  win32_nmres=
-	fi
-	;;
-      *)
-	func_to_tool_file "$1" func_convert_file_msys_to_w32
-	win32_nmres=`eval $NM -f posix -A \"$func_to_tool_file_result\" |
-	  $SED -n -e '
+      func_to_tool_file "$1" func_convert_file_msys_to_w32
+      win32_nmres=`eval $NM -f posix -A \"$func_to_tool_file_result\" |
+	$SED -n -e '
 	    1,100{
 		/ I /{
-		    s|.*|import|
+		    s,.*,import,
 		    p
 		    q
 		}
 	    }'`
-	;;
-      esac
       case $win32_nmres in
       import*)  win32_libid_type="x86 archive import";;
       *)        win32_libid_type="x86 archive static";;
@@ -4986,8 +3593,7 @@ func_win32_libid ()
 #    $sharedlib_from_linklib_result
 func_cygming_dll_for_implib ()
 {
-  $debug_cmd
-
+  $opt_debug
   sharedlib_from_linklib_result=`$DLLTOOL --identify-strict --identify "$1"`
 }
 
@@ -5004,8 +3610,7 @@ func_cygming_dll_for_implib ()
 # specified import library.
 func_cygming_dll_for_implib_fallback_core ()
 {
-  $debug_cmd
-
+  $opt_debug
   match_literal=`$ECHO "$1" | $SED "$sed_make_literal_regex"`
   $OBJDUMP -s --section "$1" "$2" 2>/dev/null |
     $SED '/^Contents of section '"$match_literal"':/{
@@ -5041,8 +3646,8 @@ func_cygming_dll_for_implib_fallback_core ()
       /./p' |
     # we now have a list, one entry per line, of the stringified
     # contents of the appropriate section of all members of the
-    # archive that possess that section. Heuristic: eliminate
-    # all those that have a first or second character that is
+    # archive which possess that section. Heuristic: eliminate
+    # all those which have a first or second character that is
     # a '.' (that is, objdump's representation of an unprintable
     # character.) This should work for all archives with less than
     # 0x302f exports -- but will fail for DLLs whose name actually
@@ -5053,6 +3658,30 @@ func_cygming_dll_for_implib_fallback_core ()
     $SED -e '/^\./d;/^.\./d;q'
 }
 
+# func_cygming_gnu_implib_p ARG
+# This predicate returns with zero status (TRUE) if
+# ARG is a GNU/binutils-style import library. Returns
+# with nonzero status (FALSE) otherwise.
+func_cygming_gnu_implib_p ()
+{
+  $opt_debug
+  func_to_tool_file "$1" func_convert_file_msys_to_w32
+  func_cygming_gnu_implib_tmp=`$NM "$func_to_tool_file_result" | eval "$global_symbol_pipe" | $EGREP ' (_head_[A-Za-z0-9_]+_[ad]l*|[A-Za-z0-9_]+_[ad]l*_iname)$'`
+  test -n "$func_cygming_gnu_implib_tmp"
+}
+
+# func_cygming_ms_implib_p ARG
+# This predicate returns with zero status (TRUE) if
+# ARG is an MS-style import library. Returns
+# with nonzero status (FALSE) otherwise.
+func_cygming_ms_implib_p ()
+{
+  $opt_debug
+  func_to_tool_file "$1" func_convert_file_msys_to_w32
+  func_cygming_ms_implib_tmp=`$NM "$func_to_tool_file_result" | eval "$global_symbol_pipe" | $GREP '_NULL_IMPORT_DESCRIPTOR'`
+  test -n "$func_cygming_ms_implib_tmp"
+}
+
 # func_cygming_dll_for_implib_fallback ARG
 # Platform-specific function to extract the
 # name of the DLL associated with the specified
@@ -5066,17 +3695,16 @@ func_cygming_dll_for_implib_fallback_core ()
 #    $sharedlib_from_linklib_result
 func_cygming_dll_for_implib_fallback ()
 {
-  $debug_cmd
-
-  if func_cygming_gnu_implib_p "$1"; then
+  $opt_debug
+  if func_cygming_gnu_implib_p "$1" ; then
     # binutils import library
     sharedlib_from_linklib_result=`func_cygming_dll_for_implib_fallback_core '.idata$7' "$1"`
-  elif func_cygming_ms_implib_p "$1"; then
+  elif func_cygming_ms_implib_p "$1" ; then
     # ms-generated import library
     sharedlib_from_linklib_result=`func_cygming_dll_for_implib_fallback_core '.idata$6' "$1"`
   else
     # unknown
-    sharedlib_from_linklib_result=
+    sharedlib_from_linklib_result=""
   fi
 }
 
@@ -5084,11 +3712,10 @@ func_cygming_dll_for_implib_fallback ()
 # func_extract_an_archive dir oldlib
 func_extract_an_archive ()
 {
-    $debug_cmd
-
-    f_ex_an_ar_dir=$1; shift
-    f_ex_an_ar_oldlib=$1
-    if test yes = "$lock_old_archive_extraction"; then
+    $opt_debug
+    f_ex_an_ar_dir="$1"; shift
+    f_ex_an_ar_oldlib="$1"
+    if test "$lock_old_archive_extraction" = yes; then
       lockfile=$f_ex_an_ar_oldlib.lock
       until $opt_dry_run || ln "$progpath" "$lockfile" 2>/dev/null; do
 	func_echo "Waiting for $lockfile to be removed"
@@ -5097,7 +3724,7 @@ func_extract_an_archive ()
     fi
     func_show_eval "(cd \$f_ex_an_ar_dir && $AR x \"\$f_ex_an_ar_oldlib\")" \
 		   'stat=$?; rm -f "$lockfile"; exit $stat'
-    if test yes = "$lock_old_archive_extraction"; then
+    if test "$lock_old_archive_extraction" = yes; then
       $opt_dry_run || rm -f "$lockfile"
     fi
     if ($AR t "$f_ex_an_ar_oldlib" | sort | sort -uc >/dev/null 2>&1); then
@@ -5111,23 +3738,22 @@ func_extract_an_archive ()
 # func_extract_archives gentop oldlib ...
 func_extract_archives ()
 {
-    $debug_cmd
-
-    my_gentop=$1; shift
+    $opt_debug
+    my_gentop="$1"; shift
     my_oldlibs=${1+"$@"}
-    my_oldobjs=
-    my_xlib=
-    my_xabs=
-    my_xdir=
+    my_oldobjs=""
+    my_xlib=""
+    my_xabs=""
+    my_xdir=""
 
     for my_xlib in $my_oldlibs; do
       # Extract the objects.
       case $my_xlib in
-	[\\/]* | [A-Za-z]:[\\/]*) my_xabs=$my_xlib ;;
+	[\\/]* | [A-Za-z]:[\\/]*) my_xabs="$my_xlib" ;;
 	*) my_xabs=`pwd`"/$my_xlib" ;;
       esac
       func_basename "$my_xlib"
-      my_xlib=$func_basename_result
+      my_xlib="$func_basename_result"
       my_xlib_u=$my_xlib
       while :; do
         case " $extracted_archives " in
@@ -5139,7 +3765,7 @@ func_extract_archives ()
 	esac
       done
       extracted_archives="$extracted_archives $my_xlib_u"
-      my_xdir=$my_gentop/$my_xlib_u
+      my_xdir="$my_gentop/$my_xlib_u"
 
       func_mkdir_p "$my_xdir"
 
@@ -5152,23 +3778,22 @@ func_extract_archives ()
 	  cd $my_xdir || exit $?
 	  darwin_archive=$my_xabs
 	  darwin_curdir=`pwd`
-	  func_basename "$darwin_archive"
-	  darwin_base_archive=$func_basename_result
+	  darwin_base_archive=`basename "$darwin_archive"`
 	  darwin_arches=`$LIPO -info "$darwin_archive" 2>/dev/null | $GREP Architectures 2>/dev/null || true`
 	  if test -n "$darwin_arches"; then
 	    darwin_arches=`$ECHO "$darwin_arches" | $SED -e 's/.*are://'`
 	    darwin_arch=
 	    func_verbose "$darwin_base_archive has multiple architectures $darwin_arches"
-	    for darwin_arch in  $darwin_arches; do
-	      func_mkdir_p "unfat-$$/$darwin_base_archive-$darwin_arch"
-	      $LIPO -thin $darwin_arch -output "unfat-$$/$darwin_base_archive-$darwin_arch/$darwin_base_archive" "$darwin_archive"
-	      cd "unfat-$$/$darwin_base_archive-$darwin_arch"
-	      func_extract_an_archive "`pwd`" "$darwin_base_archive"
+	    for darwin_arch in  $darwin_arches ; do
+	      func_mkdir_p "unfat-$$/${darwin_base_archive}-${darwin_arch}"
+	      $LIPO -thin $darwin_arch -output "unfat-$$/${darwin_base_archive}-${darwin_arch}/${darwin_base_archive}" "${darwin_archive}"
+	      cd "unfat-$$/${darwin_base_archive}-${darwin_arch}"
+	      func_extract_an_archive "`pwd`" "${darwin_base_archive}"
 	      cd "$darwin_curdir"
-	      $RM "unfat-$$/$darwin_base_archive-$darwin_arch/$darwin_base_archive"
+	      $RM "unfat-$$/${darwin_base_archive}-${darwin_arch}/${darwin_base_archive}"
 	    done # $darwin_arches
             ## Okay now we've a bunch of thin objects, gotta fatten them up :)
-	    darwin_filelist=`find unfat-$$ -type f -name \*.o -print -o -name \*.lo -print | $SED -e "$sed_basename" | sort -u`
+	    darwin_filelist=`find unfat-$$ -type f -name \*.o -print -o -name \*.lo -print | $SED -e "$basename" | sort -u`
 	    darwin_file=
 	    darwin_files=
 	    for darwin_file in $darwin_filelist; do
@@ -5190,7 +3815,7 @@ func_extract_archives ()
       my_oldobjs="$my_oldobjs "`find $my_xdir -name \*.$objext -print -o -name \*.lo -print | sort | $NL2SP`
     done
 
-    func_extract_archives_result=$my_oldobjs
+    func_extract_archives_result="$my_oldobjs"
 }
 
 
@@ -5205,7 +3830,7 @@ func_extract_archives ()
 #
 # ARG is the value that the WRAPPER_SCRIPT_BELONGS_IN_OBJDIR
 # variable will take.  If 'yes', then the emitted script
-# will assume that the directory where it is stored is
+# will assume that the directory in which it is stored is
 # the $objdir directory.  This is a cygwin/mingw-specific
 # behavior.
 func_emit_wrapper ()
@@ -5216,7 +3841,7 @@ func_emit_wrapper ()
 #! $SHELL
 
 # $output - temporary wrapper script for $objdir/$outputname
-# Generated by $PROGRAM (GNU $PACKAGE) $VERSION
+# Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION
 #
 # The $output program cannot be directly executed until all the libtool
 # libraries that it depends on are installed.
@@ -5273,9 +3898,9 @@ _LTECHO_EOF'
 
 # Very basic option parsing. These options are (a) specific to
 # the libtool wrapper, (b) are identical between the wrapper
-# /script/ and the wrapper /executable/ that is used only on
+# /script/ and the wrapper /executable/ which is used only on
 # windows platforms, and (c) all begin with the string "--lt-"
-# (application programs are unlikely to have options that match
+# (application programs are unlikely to have options which match
 # this pattern).
 #
 # There are only two supported options: --lt-debug and
@@ -5308,7 +3933,7 @@ func_parse_lt_options ()
 
   # Print the debug banner immediately:
   if test -n \"\$lt_option_debug\"; then
-    echo \"$outputname:$output:\$LINENO: libtool wrapper (GNU $PACKAGE) $VERSION\" 1>&2
+    echo \"${outputname}:${output}:\${LINENO}: libtool wrapper (GNU $PACKAGE$TIMESTAMP) $VERSION\" 1>&2
   fi
 }
 
@@ -5319,7 +3944,7 @@ func_lt_dump_args ()
   lt_dump_args_N=1;
   for lt_arg
   do
-    \$ECHO \"$outputname:$output:\$LINENO: newargv[\$lt_dump_args_N]: \$lt_arg\"
+    \$ECHO \"${outputname}:${output}:\${LINENO}: newargv[\$lt_dump_args_N]: \$lt_arg\"
     lt_dump_args_N=\`expr \$lt_dump_args_N + 1\`
   done
 }
@@ -5333,7 +3958,7 @@ func_exec_program_core ()
   *-*-mingw | *-*-os2* | *-cegcc*)
     $ECHO "\
       if test -n \"\$lt_option_debug\"; then
-        \$ECHO \"$outputname:$output:\$LINENO: newargv[0]: \$progdir\\\\\$program\" 1>&2
+        \$ECHO \"${outputname}:${output}:\${LINENO}: newargv[0]: \$progdir\\\\\$program\" 1>&2
         func_lt_dump_args \${1+\"\$@\"} 1>&2
       fi
       exec \"\$progdir\\\\\$program\" \${1+\"\$@\"}
@@ -5343,7 +3968,7 @@ func_exec_program_core ()
   *)
     $ECHO "\
       if test -n \"\$lt_option_debug\"; then
-        \$ECHO \"$outputname:$output:\$LINENO: newargv[0]: \$progdir/\$program\" 1>&2
+        \$ECHO \"${outputname}:${output}:\${LINENO}: newargv[0]: \$progdir/\$program\" 1>&2
         func_lt_dump_args \${1+\"\$@\"} 1>&2
       fi
       exec \"\$progdir/\$program\" \${1+\"\$@\"}
@@ -5418,13 +4043,13 @@ func_exec_program ()
   test -n \"\$absdir\" && thisdir=\"\$absdir\"
 "
 
-	if test yes = "$fast_install"; then
+	if test "$fast_install" = yes; then
 	  $ECHO "\
   program=lt-'$outputname'$exeext
   progdir=\"\$thisdir/$objdir\"
 
   if test ! -f \"\$progdir/\$program\" ||
-     { file=\`ls -1dt \"\$progdir/\$program\" \"\$progdir/../\$program\" 2>/dev/null | $SED 1q\`; \\
+     { file=\`ls -1dt \"\$progdir/\$program\" \"\$progdir/../\$program\" 2>/dev/null | ${SED} 1q\`; \\
        test \"X\$file\" != \"X\$progdir/\$program\"; }; then
 
     file=\"\$\$-\$program\"
@@ -5441,7 +4066,7 @@ func_exec_program ()
     if test -n \"\$relink_command\"; then
       if relink_command_output=\`eval \$relink_command 2>&1\`; then :
       else
-	\$ECHO \"\$relink_command_output\" >&2
+	$ECHO \"\$relink_command_output\" >&2
 	$RM \"\$progdir/\$file\"
 	exit 1
       fi
@@ -5476,7 +4101,7 @@ func_exec_program ()
 	fi
 
 	# Export our shlibpath_var if we have one.
-	if test yes = "$shlibpath_overrides_runpath" && test -n "$shlibpath_var" && test -n "$temp_rpath"; then
+	if test "$shlibpath_overrides_runpath" = yes && test -n "$shlibpath_var" && test -n "$temp_rpath"; then
 	  $ECHO "\
     # Add our own library path to $shlibpath_var
     $shlibpath_var=\"$temp_rpath\$$shlibpath_var\"
@@ -5496,7 +4121,7 @@ func_exec_program ()
     fi
   else
     # The program doesn't exist.
-    \$ECHO \"\$0: error: '\$progdir/\$program' does not exist\" 1>&2
+    \$ECHO \"\$0: error: \\\`\$progdir/\$program' does not exist\" 1>&2
     \$ECHO \"This script is just a wrapper for \$program.\" 1>&2
     \$ECHO \"See the $PACKAGE documentation for more information.\" 1>&2
     exit 1
@@ -5515,7 +4140,7 @@ func_emit_cwrapperexe_src ()
 	cat <<EOF
 
 /* $cwrappersource - temporary wrapper executable for $objdir/$outputname
-   Generated by $PROGRAM (GNU $PACKAGE) $VERSION
+   Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION
 
    The $output program cannot be directly executed until all the libtool
    libraries that it depends on are installed.
@@ -5550,45 +4175,47 @@ EOF
 #include <fcntl.h>
 #include <sys/stat.h>
 
-#define STREQ(s1, s2) (strcmp ((s1), (s2)) == 0)
-
 /* declarations of non-ANSI functions */
-#if defined __MINGW32__
+#if defined(__MINGW32__)
 # ifdef __STRICT_ANSI__
 int _putenv (const char *);
 # endif
-#elif defined __CYGWIN__
+#elif defined(__CYGWIN__)
 # ifdef __STRICT_ANSI__
 char *realpath (const char *, char *);
 int putenv (char *);
 int setenv (const char *, const char *, int);
 # endif
-/* #elif defined other_platform || defined ... */
+/* #elif defined (other platforms) ... */
 #endif
 
 /* portability defines, excluding path handling macros */
-#if defined _MSC_VER
+#if defined(_MSC_VER)
 # define setmode _setmode
 # define stat    _stat
 # define chmod   _chmod
 # define getcwd  _getcwd
 # define putenv  _putenv
 # define S_IXUSR _S_IEXEC
-#elif defined __MINGW32__
+# ifndef _INTPTR_T_DEFINED
+#  define _INTPTR_T_DEFINED
+#  define intptr_t int
+# endif
+#elif defined(__MINGW32__)
 # define setmode _setmode
 # define stat    _stat
 # define chmod   _chmod
 # define getcwd  _getcwd
 # define putenv  _putenv
-#elif defined __CYGWIN__
+#elif defined(__CYGWIN__)
 # define HAVE_SETENV
 # define FOPEN_WB "wb"
-/* #elif defined other platforms ... */
+/* #elif defined (other platforms) ... */
 #endif
 
-#if defined PATH_MAX
+#if defined(PATH_MAX)
 # define LT_PATHMAX PATH_MAX
-#elif defined MAXPATHLEN
+#elif defined(MAXPATHLEN)
 # define LT_PATHMAX MAXPATHLEN
 #else
 # define LT_PATHMAX 1024
@@ -5607,8 +4234,8 @@ int setenv (const char *, const char *, int);
 # define PATH_SEPARATOR ':'
 #endif
 
-#if defined _WIN32 || defined __MSDOS__ || defined __DJGPP__ || \
-  defined __OS2__
+#if defined (_WIN32) || defined (__MSDOS__) || defined (__DJGPP__) || \
+  defined (__OS2__)
 # define HAVE_DOS_BASED_FILE_SYSTEM
 # define FOPEN_WB "wb"
 # ifndef DIR_SEPARATOR_2
@@ -5641,10 +4268,10 @@ int setenv (const char *, const char *, int);
 
 #define XMALLOC(type, num)      ((type *) xmalloc ((num) * sizeof(type)))
 #define XFREE(stale) do { \
-  if (stale) { free (stale); stale = 0; } \
+  if (stale) { free ((void *) stale); stale = 0; } \
 } while (0)
 
-#if defined LT_DEBUGWRAPPER
+#if defined(LT_DEBUGWRAPPER)
 static int lt_debug = 1;
 #else
 static int lt_debug = 0;
@@ -5673,16 +4300,11 @@ void lt_dump_script (FILE *f);
 EOF
 
 	    cat <<EOF
-#if __GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 5)
-# define externally_visible volatile
-#else
-# define externally_visible __attribute__((externally_visible)) volatile
-#endif
-externally_visible const char * MAGIC_EXE = "$magic_exe";
+volatile const char * MAGIC_EXE = "$magic_exe";
 const char * LIB_PATH_VARNAME = "$shlibpath_var";
 EOF
 
-	    if test yes = "$shlibpath_overrides_runpath" && test -n "$shlibpath_var" && test -n "$temp_rpath"; then
+	    if test "$shlibpath_overrides_runpath" = yes && test -n "$shlibpath_var" && test -n "$temp_rpath"; then
               func_to_host_path "$temp_rpath"
 	      cat <<EOF
 const char * LIB_PATH_VALUE   = "$func_to_host_path_result";
@@ -5706,7 +4328,7 @@ const char * EXE_PATH_VALUE   = "";
 EOF
 	    fi
 
-	    if test yes = "$fast_install"; then
+	    if test "$fast_install" = yes; then
 	      cat <<EOF
 const char * TARGET_PROGRAM_NAME = "lt-$outputname"; /* hopefully, no .exe */
 EOF
@@ -5735,12 +4357,12 @@ main (int argc, char *argv[])
   char *actual_cwrapper_name;
   char *target_name;
   char *lt_argv_zero;
-  int rval = 127;
+  intptr_t rval = 127;
 
   int i;
 
   program_name = (char *) xstrdup (base_name (argv[0]));
-  newargz = XMALLOC (char *, (size_t) argc + 1);
+  newargz = XMALLOC (char *, argc + 1);
 
   /* very simple arg parsing; don't want to rely on getopt
    * also, copy all non cwrapper options to newargz, except
@@ -5749,10 +4371,10 @@ main (int argc, char *argv[])
   newargc=0;
   for (i = 1; i < argc; i++)
     {
-      if (STREQ (argv[i], dumpscript_opt))
+      if (strcmp (argv[i], dumpscript_opt) == 0)
 	{
 EOF
-	    case $host in
+	    case "$host" in
 	      *mingw* | *cygwin* )
 		# make stdout use "unix" line endings
 		echo "          setmode(1,_O_BINARY);"
@@ -5763,12 +4385,12 @@ EOF
 	  lt_dump_script (stdout);
 	  return 0;
 	}
-      if (STREQ (argv[i], debug_opt))
+      if (strcmp (argv[i], debug_opt) == 0)
 	{
           lt_debug = 1;
           continue;
 	}
-      if (STREQ (argv[i], ltwrapper_option_prefix))
+      if (strcmp (argv[i], ltwrapper_option_prefix) == 0)
         {
           /* however, if there is an option in the LTWRAPPER_OPTION_PREFIX
              namespace, but it is not one of the ones we know about and
@@ -5791,7 +4413,7 @@ EOF
 EOF
 	    cat <<EOF
   /* The GNU banner must be the first non-error debug message */
-  lt_debugprintf (__FILE__, __LINE__, "libtool wrapper (GNU $PACKAGE) $VERSION\n");
+  lt_debugprintf (__FILE__, __LINE__, "libtool wrapper (GNU $PACKAGE$TIMESTAMP) $VERSION\n");
 EOF
 	    cat <<"EOF"
   lt_debugprintf (__FILE__, __LINE__, "(main) argv[0]: %s\n", argv[0]);
@@ -5902,7 +4524,7 @@ EOF
 		cat <<"EOF"
   /* execv doesn't actually work on mingw as expected on unix */
   newargz = prepare_spawn (newargz);
-  rval = (int) _spawnv (_P_WAIT, lt_argv_zero, (const char * const *) newargz);
+  rval = _spawnv (_P_WAIT, lt_argv_zero, (const char * const *) newargz);
   if (rval == -1)
     {
       /* failed to start process */
@@ -5947,7 +4569,7 @@ base_name (const char *name)
 {
   const char *base;
 
-#if defined HAVE_DOS_BASED_FILE_SYSTEM
+#if defined (HAVE_DOS_BASED_FILE_SYSTEM)
   /* Skip over the disk name in MSDOS pathnames. */
   if (isalpha ((unsigned char) name[0]) && name[1] == ':')
     name += 2;
@@ -6006,7 +4628,7 @@ find_executable (const char *wrapper)
   const char *p_next;
   /* static buffer for getcwd */
   char tmp[LT_PATHMAX + 1];
-  size_t tmp_len;
+  int tmp_len;
   char *concat_name;
 
   lt_debugprintf (__FILE__, __LINE__, "(find_executable): %s\n",
@@ -6016,7 +4638,7 @@ find_executable (const char *wrapper)
     return NULL;
 
   /* Absolute path? */
-#if defined HAVE_DOS_BASED_FILE_SYSTEM
+#if defined (HAVE_DOS_BASED_FILE_SYSTEM)
   if (isalpha ((unsigned char) wrapper[0]) && wrapper[1] == ':')
     {
       concat_name = xstrdup (wrapper);
@@ -6034,7 +4656,7 @@ find_executable (const char *wrapper)
 	    return concat_name;
 	  XFREE (concat_name);
 	}
-#if defined HAVE_DOS_BASED_FILE_SYSTEM
+#if defined (HAVE_DOS_BASED_FILE_SYSTEM)
     }
 #endif
 
@@ -6057,7 +4679,7 @@ find_executable (const char *wrapper)
 	      for (q = p; *q; q++)
 		if (IS_PATH_SEPARATOR (*q))
 		  break;
-	      p_len = (size_t) (q - p);
+	      p_len = q - p;
 	      p_next = (*q == '\0' ? q : q + 1);
 	      if (p_len == 0)
 		{
@@ -6176,7 +4798,7 @@ strendzap (char *str, const char *pat)
   if (patlen <= len)
     {
       str += len - patlen;
-      if (STREQ (str, pat))
+      if (strcmp (str, pat) == 0)
 	*str = '\0';
     }
   return str;
@@ -6241,7 +4863,7 @@ lt_setenv (const char *name, const char *value)
     char *str = xstrdup (value);
     setenv (name, str, 1);
 #else
-    size_t len = strlen (name) + 1 + strlen (value) + 1;
+    int len = strlen (name) + 1 + strlen (value) + 1;
     char *str = XMALLOC (char, len);
     sprintf (str, "%s=%s", name, value);
     if (putenv (str) != EXIT_SUCCESS)
@@ -6258,8 +4880,8 @@ lt_extend_str (const char *orig_value, const char *add, int to_end)
   char *new_value;
   if (orig_value && *orig_value)
     {
-      size_t orig_value_len = strlen (orig_value);
-      size_t add_len = strlen (add);
+      int orig_value_len = strlen (orig_value);
+      int add_len = strlen (add);
       new_value = XMALLOC (char, add_len + orig_value_len + 1);
       if (to_end)
         {
@@ -6290,10 +4912,10 @@ lt_update_exe_path (const char *name, const char *value)
     {
       char *new_value = lt_extend_str (getenv (name), value, 0);
       /* some systems can't cope with a ':'-terminated path #' */
-      size_t len = strlen (new_value);
-      while ((len > 0) && IS_PATH_SEPARATOR (new_value[len-1]))
+      int len = strlen (new_value);
+      while (((len = strlen (new_value)) > 0) && IS_PATH_SEPARATOR (new_value[len-1]))
         {
-          new_value[--len] = '\0';
+          new_value[len-1] = '\0';
         }
       lt_setenv (name, new_value);
       XFREE (new_value);
@@ -6460,47 +5082,27 @@ EOF
 # True if ARG is an import lib, as indicated by $file_magic_cmd
 func_win32_import_lib_p ()
 {
-    $debug_cmd
-
+    $opt_debug
     case `eval $file_magic_cmd \"\$1\" 2>/dev/null | $SED -e 10q` in
     *import*) : ;;
     *) false ;;
     esac
 }
 
-# func_suncc_cstd_abi
-# !!ONLY CALL THIS FOR SUN CC AFTER $compile_command IS FULLY EXPANDED!!
-# Several compiler flags select an ABI that is incompatible with the
-# Cstd library. Avoid specifying it if any are in CXXFLAGS.
-func_suncc_cstd_abi ()
-{
-    $debug_cmd
-
-    case " $compile_command " in
-    *" -compat=g "*|*\ -std=c++[0-9][0-9]\ *|*" -library=stdcxx4 "*|*" -library=stlport4 "*)
-      suncc_use_cstd_abi=no
-      ;;
-    *)
-      suncc_use_cstd_abi=yes
-      ;;
-    esac
-}
-
 # func_mode_link arg...
 func_mode_link ()
 {
-    $debug_cmd
-
+    $opt_debug
     case $host in
     *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*)
       # It is impossible to link a dll without this setting, and
       # we shouldn't force the makefile maintainer to figure out
-      # what system we are compiling for in order to pass an extra
+      # which system we are compiling for in order to pass an extra
       # flag for every libtool invocation.
       # allow_undefined=no
 
       # FIXME: Unfortunately, there are problems with the above when trying
-      # to make a dll that has undefined symbols, in which case not
+      # to make a dll which has undefined symbols, in which case not
       # even a static library is built.  For now, we need to specify
       # -no-undefined on the libtool link line when we can be certain
       # that all symbols are satisfied, otherwise we get a static library.
@@ -6544,11 +5146,10 @@ func_mode_link ()
     module=no
     no_install=no
     objs=
-    os2dllname=
     non_pic_objects=
     precious_files_regex=
     prefer_static_libs=no
-    preload=false
+    preload=no
     prev=
     prevarg=
     release=
@@ -6560,7 +5161,7 @@ func_mode_link ()
     vinfo=
     vinfo_number=no
     weak_libs=
-    single_module=$wl-single_module
+    single_module="${wl}-single_module"
     func_infer_tag $base_compile
 
     # We need to know -static, to get the right output filenames.
@@ -6568,15 +5169,15 @@ func_mode_link ()
     do
       case $arg in
       -shared)
-	test yes != "$build_libtool_libs" \
-	  && func_fatal_configuration "cannot build a shared library"
+	test "$build_libtool_libs" != yes && \
+	  func_fatal_configuration "can not build a shared library"
 	build_old_libs=no
 	break
 	;;
       -all-static | -static | -static-libtool-libs)
 	case $arg in
 	-all-static)
-	  if test yes = "$build_libtool_libs" && test -z "$link_static_flag"; then
+	  if test "$build_libtool_libs" = yes && test -z "$link_static_flag"; then
 	    func_warning "complete static linking is impossible in this configuration"
 	  fi
 	  if test -n "$link_static_flag"; then
@@ -6609,7 +5210,7 @@ func_mode_link ()
 
     # Go through the arguments, transforming them on the way.
     while test "$#" -gt 0; do
-      arg=$1
+      arg="$1"
       shift
       func_quote_for_eval "$arg"
       qarg=$func_quote_for_eval_unquoted_result
@@ -6626,21 +5227,21 @@ func_mode_link ()
 
 	case $prev in
 	bindir)
-	  bindir=$arg
+	  bindir="$arg"
 	  prev=
 	  continue
 	  ;;
 	dlfiles|dlprefiles)
-	  $preload || {
+	  if test "$preload" = no; then
 	    # Add the symbol object into the linking commands.
 	    func_append compile_command " @SYMFILE@"
 	    func_append finalize_command " @SYMFILE@"
-	    preload=:
-	  }
+	    preload=yes
+	  fi
 	  case $arg in
 	  *.la | *.lo) ;;  # We handle these cases below.
 	  force)
-	    if test no = "$dlself"; then
+	    if test "$dlself" = no; then
 	      dlself=needless
 	      export_dynamic=yes
 	    fi
@@ -6648,9 +5249,9 @@ func_mode_link ()
 	    continue
 	    ;;
 	  self)
-	    if test dlprefiles = "$prev"; then
+	    if test "$prev" = dlprefiles; then
 	      dlself=yes
-	    elif test dlfiles = "$prev" && test yes != "$dlopen_self"; then
+	    elif test "$prev" = dlfiles && test "$dlopen_self" != yes; then
 	      dlself=yes
 	    else
 	      dlself=needless
@@ -6660,7 +5261,7 @@ func_mode_link ()
 	    continue
 	    ;;
 	  *)
-	    if test dlfiles = "$prev"; then
+	    if test "$prev" = dlfiles; then
 	      func_append dlfiles " $arg"
 	    else
 	      func_append dlprefiles " $arg"
@@ -6671,14 +5272,14 @@ func_mode_link ()
 	  esac
 	  ;;
 	expsyms)
-	  export_symbols=$arg
+	  export_symbols="$arg"
 	  test -f "$arg" \
-	    || func_fatal_error "symbol file '$arg' does not exist"
+	    || func_fatal_error "symbol file \`$arg' does not exist"
 	  prev=
 	  continue
 	  ;;
 	expsyms_regex)
-	  export_symbols_regex=$arg
+	  export_symbols_regex="$arg"
 	  prev=
 	  continue
 	  ;;
@@ -6696,13 +5297,7 @@ func_mode_link ()
 	  continue
 	  ;;
 	inst_prefix)
-	  inst_prefix_dir=$arg
-	  prev=
-	  continue
-	  ;;
-	mllvm)
-	  # Clang does not use LLVM to link, so we can simply discard any
-	  # '-mllvm $arg' options when doing the link step.
+	  inst_prefix_dir="$arg"
 	  prev=
 	  continue
 	  ;;
@@ -6726,21 +5321,21 @@ func_mode_link ()
 
 		if test -z "$pic_object" ||
 		   test -z "$non_pic_object" ||
-		   test none = "$pic_object" &&
-		   test none = "$non_pic_object"; then
-		  func_fatal_error "cannot find name of object for '$arg'"
+		   test "$pic_object" = none &&
+		   test "$non_pic_object" = none; then
+		  func_fatal_error "cannot find name of object for \`$arg'"
 		fi
 
 		# Extract subdirectory from the argument.
 		func_dirname "$arg" "/" ""
-		xdir=$func_dirname_result
+		xdir="$func_dirname_result"
 
-		if test none != "$pic_object"; then
+		if test "$pic_object" != none; then
 		  # Prepend the subdirectory the object is found in.
-		  pic_object=$xdir$pic_object
+		  pic_object="$xdir$pic_object"
 
-		  if test dlfiles = "$prev"; then
-		    if test yes = "$build_libtool_libs" && test yes = "$dlopen_support"; then
+		  if test "$prev" = dlfiles; then
+		    if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then
 		      func_append dlfiles " $pic_object"
 		      prev=
 		      continue
@@ -6751,7 +5346,7 @@ func_mode_link ()
 		  fi
 
 		  # CHECK ME:  I think I busted this.  -Ossama
-		  if test dlprefiles = "$prev"; then
+		  if test "$prev" = dlprefiles; then
 		    # Preload the old-style object.
 		    func_append dlprefiles " $pic_object"
 		    prev=
@@ -6759,23 +5354,23 @@ func_mode_link ()
 
 		  # A PIC object.
 		  func_append libobjs " $pic_object"
-		  arg=$pic_object
+		  arg="$pic_object"
 		fi
 
 		# Non-PIC object.
-		if test none != "$non_pic_object"; then
+		if test "$non_pic_object" != none; then
 		  # Prepend the subdirectory the object is found in.
-		  non_pic_object=$xdir$non_pic_object
+		  non_pic_object="$xdir$non_pic_object"
 
 		  # A standard non-PIC object
 		  func_append non_pic_objects " $non_pic_object"
-		  if test -z "$pic_object" || test none = "$pic_object"; then
-		    arg=$non_pic_object
+		  if test -z "$pic_object" || test "$pic_object" = none ; then
+		    arg="$non_pic_object"
 		  fi
 		else
 		  # If the PIC object exists, use it instead.
 		  # $xdir was prepended to $pic_object above.
-		  non_pic_object=$pic_object
+		  non_pic_object="$pic_object"
 		  func_append non_pic_objects " $non_pic_object"
 		fi
 	      else
@@ -6783,7 +5378,7 @@ func_mode_link ()
 		if $opt_dry_run; then
 		  # Extract subdirectory from the argument.
 		  func_dirname "$arg" "/" ""
-		  xdir=$func_dirname_result
+		  xdir="$func_dirname_result"
 
 		  func_lo2o "$arg"
 		  pic_object=$xdir$objdir/$func_lo2o_result
@@ -6791,29 +5386,24 @@ func_mode_link ()
 		  func_append libobjs " $pic_object"
 		  func_append non_pic_objects " $non_pic_object"
 	        else
-		  func_fatal_error "'$arg' is not a valid libtool object"
+		  func_fatal_error "\`$arg' is not a valid libtool object"
 		fi
 	      fi
 	    done
 	  else
-	    func_fatal_error "link input file '$arg' does not exist"
+	    func_fatal_error "link input file \`$arg' does not exist"
 	  fi
 	  arg=$save_arg
 	  prev=
 	  continue
 	  ;;
-	os2dllname)
-	  os2dllname=$arg
-	  prev=
-	  continue
-	  ;;
 	precious_regex)
-	  precious_files_regex=$arg
+	  precious_files_regex="$arg"
 	  prev=
 	  continue
 	  ;;
 	release)
-	  release=-$arg
+	  release="-$arg"
 	  prev=
 	  continue
 	  ;;
@@ -6825,7 +5415,7 @@ func_mode_link ()
 	    func_fatal_error "only absolute run-paths are allowed"
 	    ;;
 	  esac
-	  if test rpath = "$prev"; then
+	  if test "$prev" = rpath; then
 	    case "$rpath " in
 	    *" $arg "*) ;;
 	    *) func_append rpath " $arg" ;;
@@ -6840,7 +5430,7 @@ func_mode_link ()
 	  continue
 	  ;;
 	shrext)
-	  shrext_cmds=$arg
+	  shrext_cmds="$arg"
 	  prev=
 	  continue
 	  ;;
@@ -6880,7 +5470,7 @@ func_mode_link ()
 	esac
       fi # test -n "$prev"
 
-      prevarg=$arg
+      prevarg="$arg"
 
       case $arg in
       -all-static)
@@ -6894,7 +5484,7 @@ func_mode_link ()
 
       -allow-undefined)
 	# FIXME: remove this flag sometime in the future.
-	func_fatal_error "'-allow-undefined' must not be used because it is the default"
+	func_fatal_error "\`-allow-undefined' must not be used because it is the default"
 	;;
 
       -avoid-version)
@@ -6926,7 +5516,7 @@ func_mode_link ()
 	if test -n "$export_symbols" || test -n "$export_symbols_regex"; then
 	  func_fatal_error "more than one -exported-symbols argument is not allowed"
 	fi
-	if test X-export-symbols = "X$arg"; then
+	if test "X$arg" = "X-export-symbols"; then
 	  prev=expsyms
 	else
 	  prev=expsyms_regex
@@ -6960,9 +5550,9 @@ func_mode_link ()
 	func_stripname "-L" '' "$arg"
 	if test -z "$func_stripname_result"; then
 	  if test "$#" -gt 0; then
-	    func_fatal_error "require no space between '-L' and '$1'"
+	    func_fatal_error "require no space between \`-L' and \`$1'"
 	  else
-	    func_fatal_error "need path for '-L' option"
+	    func_fatal_error "need path for \`-L' option"
 	  fi
 	fi
 	func_resolve_sysroot "$func_stripname_result"
@@ -6973,8 +5563,8 @@ func_mode_link ()
 	*)
 	  absdir=`cd "$dir" && pwd`
 	  test -z "$absdir" && \
-	    func_fatal_error "cannot determine absolute directory name of '$dir'"
-	  dir=$absdir
+	    func_fatal_error "cannot determine absolute directory name of \`$dir'"
+	  dir="$absdir"
 	  ;;
 	esac
 	case "$deplibs " in
@@ -7009,7 +5599,7 @@ func_mode_link ()
 	;;
 
       -l*)
-	if test X-lc = "X$arg" || test X-lm = "X$arg"; then
+	if test "X$arg" = "X-lc" || test "X$arg" = "X-lm"; then
 	  case $host in
 	  *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-beos* | *-cegcc* | *-*-haiku*)
 	    # These systems don't actually have a C or math library (as such)
@@ -7017,11 +5607,11 @@ func_mode_link ()
 	    ;;
 	  *-*-os2*)
 	    # These systems don't actually have a C library (as such)
-	    test X-lc = "X$arg" && continue
+	    test "X$arg" = "X-lc" && continue
 	    ;;
-	  *-*-openbsd* | *-*-freebsd* | *-*-dragonfly* | *-*-bitrig*)
+	  *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*)
 	    # Do not include libc due to us having libc/libc_r.
-	    test X-lc = "X$arg" && continue
+	    test "X$arg" = "X-lc" && continue
 	    ;;
 	  *-*-rhapsody* | *-*-darwin1.[012])
 	    # Rhapsody C and math libraries are in the System framework
@@ -7030,16 +5620,16 @@ func_mode_link ()
 	    ;;
 	  *-*-sco3.2v5* | *-*-sco5v6*)
 	    # Causes problems with __ctype
-	    test X-lc = "X$arg" && continue
+	    test "X$arg" = "X-lc" && continue
 	    ;;
 	  *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*)
 	    # Compiler inserts libc in the correct place for threads to work
-	    test X-lc = "X$arg" && continue
+	    test "X$arg" = "X-lc" && continue
 	    ;;
 	  esac
-	elif test X-lc_r = "X$arg"; then
+	elif test "X$arg" = "X-lc_r"; then
 	 case $host in
-	 *-*-openbsd* | *-*-freebsd* | *-*-dragonfly* | *-*-bitrig*)
+	 *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*)
 	   # Do not include libc_r directly, use -pthread flag.
 	   continue
 	   ;;
@@ -7049,11 +5639,6 @@ func_mode_link ()
 	continue
 	;;
 
-      -mllvm)
-	prev=mllvm
-	continue
-	;;
-
       -module)
 	module=yes
 	continue
@@ -7083,7 +5668,7 @@ func_mode_link ()
 	;;
 
       -multi_module)
-	single_module=$wl-multi_module
+	single_module="${wl}-multi_module"
 	continue
 	;;
 
@@ -7097,8 +5682,8 @@ func_mode_link ()
 	*-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-darwin* | *-cegcc*)
 	  # The PATH hackery in wrapper scripts is required on Windows
 	  # and Darwin in order for the loader to find any dlls it needs.
-	  func_warning "'-no-install' is ignored for $host"
-	  func_warning "assuming '-no-fast-install' instead"
+	  func_warning "\`-no-install' is ignored for $host"
+	  func_warning "assuming \`-no-fast-install' instead"
 	  fast_install=no
 	  ;;
 	*) no_install=yes ;;
@@ -7116,11 +5701,6 @@ func_mode_link ()
 	continue
 	;;
 
-      -os2dllname)
-	prev=os2dllname
-	continue
-	;;
-
       -o) prev=output ;;
 
       -precious-files-regex)
@@ -7208,14 +5788,14 @@ func_mode_link ()
 	func_stripname '-Wc,' '' "$arg"
 	args=$func_stripname_result
 	arg=
-	save_ifs=$IFS; IFS=,
+	save_ifs="$IFS"; IFS=','
 	for flag in $args; do
-	  IFS=$save_ifs
+	  IFS="$save_ifs"
           func_quote_for_eval "$flag"
 	  func_append arg " $func_quote_for_eval_result"
 	  func_append compiler_flags " $func_quote_for_eval_result"
 	done
-	IFS=$save_ifs
+	IFS="$save_ifs"
 	func_stripname ' ' '' "$arg"
 	arg=$func_stripname_result
 	;;
@@ -7224,15 +5804,15 @@ func_mode_link ()
 	func_stripname '-Wl,' '' "$arg"
 	args=$func_stripname_result
 	arg=
-	save_ifs=$IFS; IFS=,
+	save_ifs="$IFS"; IFS=','
 	for flag in $args; do
-	  IFS=$save_ifs
+	  IFS="$save_ifs"
           func_quote_for_eval "$flag"
 	  func_append arg " $wl$func_quote_for_eval_result"
 	  func_append compiler_flags " $wl$func_quote_for_eval_result"
 	  func_append linker_flags " $func_quote_for_eval_result"
 	done
-	IFS=$save_ifs
+	IFS="$save_ifs"
 	func_stripname ' ' '' "$arg"
 	arg=$func_stripname_result
 	;;
@@ -7255,7 +5835,7 @@ func_mode_link ()
       # -msg_* for osf cc
       -msg_*)
 	func_quote_for_eval "$arg"
-	arg=$func_quote_for_eval_result
+	arg="$func_quote_for_eval_result"
 	;;
 
       # Flags to be passed through unchanged, with rationale:
@@ -7267,49 +5847,25 @@ func_mode_link ()
       # -m*, -t[45]*, -txscale* architecture-specific flags for GCC
       # -F/path              path to uninstalled frameworks, gcc on darwin
       # -p, -pg, --coverage, -fprofile-*  profiling flags for GCC
-      # -fstack-protector*   stack protector flags for GCC
       # @file                GCC response files
       # -tp=*                Portland pgcc target processor selection
       # --sysroot=*          for sysroot support
-      # -O*, -g*, -flto*, -fwhopr*, -fuse-linker-plugin GCC link-time optimization
-      # -specs=*             GCC specs files
-      # -stdlib=*            select c++ std lib with clang
-      # -fsanitize=*         Clang/GCC memory and address sanitizer
+      # -O*, -flto*, -fwhopr*, -fuse-linker-plugin GCC link-time optimization
       -64|-mips[0-9]|-r[0-9][0-9]*|-xarch=*|-xtarget=*|+DA*|+DD*|-q*|-m*| \
       -t[45]*|-txscale*|-p|-pg|--coverage|-fprofile-*|-F*|@*|-tp=*|--sysroot=*| \
-      -O*|-g*|-flto*|-fwhopr*|-fuse-linker-plugin|-fstack-protector*|-stdlib=*| \
-      -specs=*|-fsanitize=*)
+      -O*|-flto*|-fwhopr*|-fuse-linker-plugin)
         func_quote_for_eval "$arg"
-	arg=$func_quote_for_eval_result
+	arg="$func_quote_for_eval_result"
         func_append compile_command " $arg"
         func_append finalize_command " $arg"
         func_append compiler_flags " $arg"
         continue
         ;;
 
-      -Z*)
-        if test os2 = "`expr $host : '.*\(os2\)'`"; then
-          # OS/2 uses -Zxxx to specify OS/2-specific options
-	  compiler_flags="$compiler_flags $arg"
-	  func_append compile_command " $arg"
-	  func_append finalize_command " $arg"
-	  case $arg in
-	  -Zlinker | -Zstack)
-	    prev=xcompiler
-	    ;;
-	  esac
-	  continue
-        else
-	  # Otherwise treat like 'Some other compiler flag' below
-	  func_quote_for_eval "$arg"
-	  arg=$func_quote_for_eval_result
-        fi
-	;;
-
       # Some other compiler flag.
       -* | +*)
         func_quote_for_eval "$arg"
-	arg=$func_quote_for_eval_result
+	arg="$func_quote_for_eval_result"
 	;;
 
       *.$objext)
@@ -7330,21 +5886,21 @@ func_mode_link ()
 
 	  if test -z "$pic_object" ||
 	     test -z "$non_pic_object" ||
-	     test none = "$pic_object" &&
-	     test none = "$non_pic_object"; then
-	    func_fatal_error "cannot find name of object for '$arg'"
+	     test "$pic_object" = none &&
+	     test "$non_pic_object" = none; then
+	    func_fatal_error "cannot find name of object for \`$arg'"
 	  fi
 
 	  # Extract subdirectory from the argument.
 	  func_dirname "$arg" "/" ""
-	  xdir=$func_dirname_result
+	  xdir="$func_dirname_result"
 
-	  test none = "$pic_object" || {
+	  if test "$pic_object" != none; then
 	    # Prepend the subdirectory the object is found in.
-	    pic_object=$xdir$pic_object
+	    pic_object="$xdir$pic_object"
 
-	    if test dlfiles = "$prev"; then
-	      if test yes = "$build_libtool_libs" && test yes = "$dlopen_support"; then
+	    if test "$prev" = dlfiles; then
+	      if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then
 		func_append dlfiles " $pic_object"
 		prev=
 		continue
@@ -7355,7 +5911,7 @@ func_mode_link ()
 	    fi
 
 	    # CHECK ME:  I think I busted this.  -Ossama
-	    if test dlprefiles = "$prev"; then
+	    if test "$prev" = dlprefiles; then
 	      # Preload the old-style object.
 	      func_append dlprefiles " $pic_object"
 	      prev=
@@ -7363,23 +5919,23 @@ func_mode_link ()
 
 	    # A PIC object.
 	    func_append libobjs " $pic_object"
-	    arg=$pic_object
-	  }
+	    arg="$pic_object"
+	  fi
 
 	  # Non-PIC object.
-	  if test none != "$non_pic_object"; then
+	  if test "$non_pic_object" != none; then
 	    # Prepend the subdirectory the object is found in.
-	    non_pic_object=$xdir$non_pic_object
+	    non_pic_object="$xdir$non_pic_object"
 
 	    # A standard non-PIC object
 	    func_append non_pic_objects " $non_pic_object"
-	    if test -z "$pic_object" || test none = "$pic_object"; then
-	      arg=$non_pic_object
+	    if test -z "$pic_object" || test "$pic_object" = none ; then
+	      arg="$non_pic_object"
 	    fi
 	  else
 	    # If the PIC object exists, use it instead.
 	    # $xdir was prepended to $pic_object above.
-	    non_pic_object=$pic_object
+	    non_pic_object="$pic_object"
 	    func_append non_pic_objects " $non_pic_object"
 	  fi
 	else
@@ -7387,7 +5943,7 @@ func_mode_link ()
 	  if $opt_dry_run; then
 	    # Extract subdirectory from the argument.
 	    func_dirname "$arg" "/" ""
-	    xdir=$func_dirname_result
+	    xdir="$func_dirname_result"
 
 	    func_lo2o "$arg"
 	    pic_object=$xdir$objdir/$func_lo2o_result
@@ -7395,7 +5951,7 @@ func_mode_link ()
 	    func_append libobjs " $pic_object"
 	    func_append non_pic_objects " $non_pic_object"
 	  else
-	    func_fatal_error "'$arg' is not a valid libtool object"
+	    func_fatal_error "\`$arg' is not a valid libtool object"
 	  fi
 	fi
 	;;
@@ -7411,11 +5967,11 @@ func_mode_link ()
 	# A libtool-controlled library.
 
 	func_resolve_sysroot "$arg"
-	if test dlfiles = "$prev"; then
+	if test "$prev" = dlfiles; then
 	  # This library was specified with -dlopen.
 	  func_append dlfiles " $func_resolve_sysroot_result"
 	  prev=
-	elif test dlprefiles = "$prev"; then
+	elif test "$prev" = dlprefiles; then
 	  # The library was specified with -dlpreopen.
 	  func_append dlprefiles " $func_resolve_sysroot_result"
 	  prev=
@@ -7430,7 +5986,7 @@ func_mode_link ()
 	# Unknown arguments in both finalize_command and compile_command need
 	# to be aesthetically quoted because they are evaled later.
 	func_quote_for_eval "$arg"
-	arg=$func_quote_for_eval_result
+	arg="$func_quote_for_eval_result"
 	;;
       esac # arg
 
@@ -7442,9 +5998,9 @@ func_mode_link ()
     done # argument parsing loop
 
     test -n "$prev" && \
-      func_fatal_help "the '$prevarg' option requires an argument"
+      func_fatal_help "the \`$prevarg' option requires an argument"
 
-    if test yes = "$export_dynamic" && test -n "$export_dynamic_flag_spec"; then
+    if test "$export_dynamic" = yes && test -n "$export_dynamic_flag_spec"; then
       eval arg=\"$export_dynamic_flag_spec\"
       func_append compile_command " $arg"
       func_append finalize_command " $arg"
@@ -7453,23 +6009,20 @@ func_mode_link ()
     oldlibs=
     # calculate the name of the file, without its directory
     func_basename "$output"
-    outputname=$func_basename_result
-    libobjs_save=$libobjs
+    outputname="$func_basename_result"
+    libobjs_save="$libobjs"
 
     if test -n "$shlibpath_var"; then
       # get the directories listed in $shlibpath_var
-      eval shlib_search_path=\`\$ECHO \"\$$shlibpath_var\" \| \$SED \'s/:/ /g\'\`
+      eval shlib_search_path=\`\$ECHO \"\${$shlibpath_var}\" \| \$SED \'s/:/ /g\'\`
     else
       shlib_search_path=
     fi
     eval sys_lib_search_path=\"$sys_lib_search_path_spec\"
     eval sys_lib_dlsearch_path=\"$sys_lib_dlsearch_path_spec\"
 
-    # Definition is injected by LT_CONFIG during libtool generation.
-    func_munge_path_list sys_lib_dlsearch_path "$LT_SYS_LIBRARY_PATH"
-
     func_dirname "$output" "/" ""
-    output_objdir=$func_dirname_result$objdir
+    output_objdir="$func_dirname_result$objdir"
     func_to_tool_file "$output_objdir/"
     tool_output_objdir=$func_to_tool_file_result
     # Create the object directory.
@@ -7492,7 +6045,7 @@ func_mode_link ()
     # Find all interdependent deplibs by searching for libraries
     # that are linked more than once (e.g. -la -lb -la)
     for deplib in $deplibs; do
-      if $opt_preserve_dup_deps; then
+      if $opt_preserve_dup_deps ; then
 	case "$libs " in
 	*" $deplib "*) func_append specialdeplibs " $deplib" ;;
 	esac
@@ -7500,7 +6053,7 @@ func_mode_link ()
       func_append libs " $deplib"
     done
 
-    if test lib = "$linkmode"; then
+    if test "$linkmode" = lib; then
       libs="$predeps $libs $compiler_lib_search_path $postdeps"
 
       # Compute libraries that are listed more than once in $predeps
@@ -7532,7 +6085,7 @@ func_mode_link ()
 	  case $file in
 	  *.la) ;;
 	  *)
-	    func_fatal_help "libraries can '-dlopen' only libtool libraries: $file"
+	    func_fatal_help "libraries can \`-dlopen' only libtool libraries: $file"
 	    ;;
 	  esac
 	done
@@ -7540,7 +6093,7 @@ func_mode_link ()
     prog)
 	compile_deplibs=
 	finalize_deplibs=
-	alldeplibs=false
+	alldeplibs=no
 	newdlfiles=
 	newdlprefiles=
 	passes="conv scan dlopen dlpreopen link"
@@ -7552,32 +6105,32 @@ func_mode_link ()
     for pass in $passes; do
       # The preopen pass in lib mode reverses $deplibs; put it back here
       # so that -L comes before libs that need it for instance...
-      if test lib,link = "$linkmode,$pass"; then
+      if test "$linkmode,$pass" = "lib,link"; then
 	## FIXME: Find the place where the list is rebuilt in the wrong
 	##        order, and fix it there properly
         tmp_deplibs=
 	for deplib in $deplibs; do
 	  tmp_deplibs="$deplib $tmp_deplibs"
 	done
-	deplibs=$tmp_deplibs
+	deplibs="$tmp_deplibs"
       fi
 
-      if test lib,link = "$linkmode,$pass" ||
-	 test prog,scan = "$linkmode,$pass"; then
-	libs=$deplibs
+      if test "$linkmode,$pass" = "lib,link" ||
+	 test "$linkmode,$pass" = "prog,scan"; then
+	libs="$deplibs"
 	deplibs=
       fi
-      if test prog = "$linkmode"; then
+      if test "$linkmode" = prog; then
 	case $pass in
-	dlopen) libs=$dlfiles ;;
-	dlpreopen) libs=$dlprefiles ;;
+	dlopen) libs="$dlfiles" ;;
+	dlpreopen) libs="$dlprefiles" ;;
 	link)
 	  libs="$deplibs %DEPLIBS%"
 	  test "X$link_all_deplibs" != Xno && libs="$libs $dependency_libs"
 	  ;;
 	esac
       fi
-      if test lib,dlpreopen = "$linkmode,$pass"; then
+      if test "$linkmode,$pass" = "lib,dlpreopen"; then
 	# Collect and forward deplibs of preopened libtool libs
 	for lib in $dlprefiles; do
 	  # Ignore non-libtool-libs
@@ -7598,26 +6151,26 @@ func_mode_link ()
 	    esac
 	  done
 	done
-	libs=$dlprefiles
+	libs="$dlprefiles"
       fi
-      if test dlopen = "$pass"; then
+      if test "$pass" = dlopen; then
 	# Collect dlpreopened libraries
-	save_deplibs=$deplibs
+	save_deplibs="$deplibs"
 	deplibs=
       fi
 
       for deplib in $libs; do
 	lib=
-	found=false
+	found=no
 	case $deplib in
 	-mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe \
         |-threads|-fopenmp|-openmp|-mp|-xopenmp|-omp|-qsmp=*)
-	  if test prog,link = "$linkmode,$pass"; then
+	  if test "$linkmode,$pass" = "prog,link"; then
 	    compile_deplibs="$deplib $compile_deplibs"
 	    finalize_deplibs="$deplib $finalize_deplibs"
 	  else
 	    func_append compiler_flags " $deplib"
-	    if test lib = "$linkmode"; then
+	    if test "$linkmode" = lib ; then
 		case "$new_inherited_linker_flags " in
 		    *" $deplib "*) ;;
 		    * ) func_append new_inherited_linker_flags " $deplib" ;;
@@ -7627,13 +6180,13 @@ func_mode_link ()
 	  continue
 	  ;;
 	-l*)
-	  if test lib != "$linkmode" && test prog != "$linkmode"; then
-	    func_warning "'-l' is ignored for archives/objects"
+	  if test "$linkmode" != lib && test "$linkmode" != prog; then
+	    func_warning "\`-l' is ignored for archives/objects"
 	    continue
 	  fi
 	  func_stripname '-l' '' "$deplib"
 	  name=$func_stripname_result
-	  if test lib = "$linkmode"; then
+	  if test "$linkmode" = lib; then
 	    searchdirs="$newlib_search_path $lib_search_path $compiler_lib_search_dirs $sys_lib_search_path $shlib_search_path"
 	  else
 	    searchdirs="$newlib_search_path $lib_search_path $sys_lib_search_path $shlib_search_path"
@@ -7641,22 +6194,31 @@ func_mode_link ()
 	  for searchdir in $searchdirs; do
 	    for search_ext in .la $std_shrext .so .a; do
 	      # Search the libtool library
-	      lib=$searchdir/lib$name$search_ext
+	      lib="$searchdir/lib${name}${search_ext}"
 	      if test -f "$lib"; then
-		if test .la = "$search_ext"; then
-		  found=:
+		if test "$search_ext" = ".la"; then
+		  found=yes
 		else
-		  found=false
+		  found=no
 		fi
 		break 2
 	      fi
 	    done
 	  done
-	  if $found; then
-	    # deplib is a libtool library
+	  if test "$found" != yes; then
+	    # deplib doesn't seem to be a libtool library
+	    if test "$linkmode,$pass" = "prog,link"; then
+	      compile_deplibs="$deplib $compile_deplibs"
+	      finalize_deplibs="$deplib $finalize_deplibs"
+	    else
+	      deplibs="$deplib $deplibs"
+	      test "$linkmode" = lib && newdependency_libs="$deplib $newdependency_libs"
+	    fi
+	    continue
+	  else # deplib is a libtool library
 	    # If $allow_libtool_libs_with_static_runtimes && $deplib is a stdlib,
 	    # We need to do some special things here, and not later.
-	    if test yes = "$allow_libtool_libs_with_static_runtimes"; then
+	    if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
 	      case " $predeps $postdeps " in
 	      *" $deplib "*)
 		if func_lalib_p "$lib"; then
@@ -7664,19 +6226,19 @@ func_mode_link ()
 		  old_library=
 		  func_source "$lib"
 		  for l in $old_library $library_names; do
-		    ll=$l
+		    ll="$l"
 		  done
-		  if test "X$ll" = "X$old_library"; then # only static version available
-		    found=false
+		  if test "X$ll" = "X$old_library" ; then # only static version available
+		    found=no
 		    func_dirname "$lib" "" "."
-		    ladir=$func_dirname_result
+		    ladir="$func_dirname_result"
 		    lib=$ladir/$old_library
-		    if test prog,link = "$linkmode,$pass"; then
+		    if test "$linkmode,$pass" = "prog,link"; then
 		      compile_deplibs="$deplib $compile_deplibs"
 		      finalize_deplibs="$deplib $finalize_deplibs"
 		    else
 		      deplibs="$deplib $deplibs"
-		      test lib = "$linkmode" && newdependency_libs="$deplib $newdependency_libs"
+		      test "$linkmode" = lib && newdependency_libs="$deplib $newdependency_libs"
 		    fi
 		    continue
 		  fi
@@ -7685,25 +6247,15 @@ func_mode_link ()
 	      *) ;;
 	      esac
 	    fi
-	  else
-	    # deplib doesn't seem to be a libtool library
-	    if test prog,link = "$linkmode,$pass"; then
-	      compile_deplibs="$deplib $compile_deplibs"
-	      finalize_deplibs="$deplib $finalize_deplibs"
-	    else
-	      deplibs="$deplib $deplibs"
-	      test lib = "$linkmode" && newdependency_libs="$deplib $newdependency_libs"
-	    fi
-	    continue
 	  fi
 	  ;; # -l
 	*.ltframework)
-	  if test prog,link = "$linkmode,$pass"; then
+	  if test "$linkmode,$pass" = "prog,link"; then
 	    compile_deplibs="$deplib $compile_deplibs"
 	    finalize_deplibs="$deplib $finalize_deplibs"
 	  else
 	    deplibs="$deplib $deplibs"
-	    if test lib = "$linkmode"; then
+	    if test "$linkmode" = lib ; then
 		case "$new_inherited_linker_flags " in
 		    *" $deplib "*) ;;
 		    * ) func_append new_inherited_linker_flags " $deplib" ;;
@@ -7716,18 +6268,18 @@ func_mode_link ()
 	  case $linkmode in
 	  lib)
 	    deplibs="$deplib $deplibs"
-	    test conv = "$pass" && continue
+	    test "$pass" = conv && continue
 	    newdependency_libs="$deplib $newdependency_libs"
 	    func_stripname '-L' '' "$deplib"
 	    func_resolve_sysroot "$func_stripname_result"
 	    func_append newlib_search_path " $func_resolve_sysroot_result"
 	    ;;
 	  prog)
-	    if test conv = "$pass"; then
+	    if test "$pass" = conv; then
 	      deplibs="$deplib $deplibs"
 	      continue
 	    fi
-	    if test scan = "$pass"; then
+	    if test "$pass" = scan; then
 	      deplibs="$deplib $deplibs"
 	    else
 	      compile_deplibs="$deplib $compile_deplibs"
@@ -7738,13 +6290,13 @@ func_mode_link ()
 	    func_append newlib_search_path " $func_resolve_sysroot_result"
 	    ;;
 	  *)
-	    func_warning "'-L' is ignored for archives/objects"
+	    func_warning "\`-L' is ignored for archives/objects"
 	    ;;
 	  esac # linkmode
 	  continue
 	  ;; # -L
 	-R*)
-	  if test link = "$pass"; then
+	  if test "$pass" = link; then
 	    func_stripname '-R' '' "$deplib"
 	    func_resolve_sysroot "$func_stripname_result"
 	    dir=$func_resolve_sysroot_result
@@ -7762,7 +6314,7 @@ func_mode_link ()
 	  lib=$func_resolve_sysroot_result
 	  ;;
 	*.$libext)
-	  if test conv = "$pass"; then
+	  if test "$pass" = conv; then
 	    deplibs="$deplib $deplibs"
 	    continue
 	  fi
@@ -7773,26 +6325,21 @@ func_mode_link ()
 	    case " $dlpreconveniencelibs " in
 	    *" $deplib "*) ;;
 	    *)
-	      valid_a_lib=false
+	      valid_a_lib=no
 	      case $deplibs_check_method in
 		match_pattern*)
 		  set dummy $deplibs_check_method; shift
 		  match_pattern_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"`
 		  if eval "\$ECHO \"$deplib\"" 2>/dev/null | $SED 10q \
 		    | $EGREP "$match_pattern_regex" > /dev/null; then
-		    valid_a_lib=:
+		    valid_a_lib=yes
 		  fi
 		;;
 		pass_all)
-		  valid_a_lib=:
+		  valid_a_lib=yes
 		;;
 	      esac
-	      if $valid_a_lib; then
-		echo
-		$ECHO "*** Warning: Linking the shared library $output against the"
-		$ECHO "*** static library $deplib is not portable!"
-		deplibs="$deplib $deplibs"
-	      else
+	      if test "$valid_a_lib" != yes; then
 		echo
 		$ECHO "*** Warning: Trying to link with static lib archive $deplib."
 		echo "*** I have the capability to make that library automatically link in when"
@@ -7800,13 +6347,18 @@ func_mode_link ()
 		echo "*** shared version of the library, which you do not appear to have"
 		echo "*** because the file extensions .$libext of this argument makes me believe"
 		echo "*** that it is just a static archive that I should not use here."
+	      else
+		echo
+		$ECHO "*** Warning: Linking the shared library $output against the"
+		$ECHO "*** static library $deplib is not portable!"
+		deplibs="$deplib $deplibs"
 	      fi
 	      ;;
 	    esac
 	    continue
 	    ;;
 	  prog)
-	    if test link != "$pass"; then
+	    if test "$pass" != link; then
 	      deplibs="$deplib $deplibs"
 	    else
 	      compile_deplibs="$deplib $compile_deplibs"
@@ -7817,10 +6369,10 @@ func_mode_link ()
 	  esac # linkmode
 	  ;; # *.$libext
 	*.lo | *.$objext)
-	  if test conv = "$pass"; then
+	  if test "$pass" = conv; then
 	    deplibs="$deplib $deplibs"
-	  elif test prog = "$linkmode"; then
-	    if test dlpreopen = "$pass" || test yes != "$dlopen_support" || test no = "$build_libtool_libs"; then
+	  elif test "$linkmode" = prog; then
+	    if test "$pass" = dlpreopen || test "$dlopen_support" != yes || test "$build_libtool_libs" = no; then
 	      # If there is no dlopen support or we're linking statically,
 	      # we need to preload.
 	      func_append newdlprefiles " $deplib"
@@ -7833,20 +6385,22 @@ func_mode_link ()
 	  continue
 	  ;;
 	%DEPLIBS%)
-	  alldeplibs=:
+	  alldeplibs=yes
 	  continue
 	  ;;
 	esac # case $deplib
 
-	$found || test -f "$lib" \
-	  || func_fatal_error "cannot find the library '$lib' or unhandled argument '$deplib'"
+	if test "$found" = yes || test -f "$lib"; then :
+	else
+	  func_fatal_error "cannot find the library \`$lib' or unhandled argument \`$deplib'"
+	fi
 
 	# Check to see that this really is a libtool archive.
 	func_lalib_unsafe_p "$lib" \
-	  || func_fatal_error "'$lib' is not a valid libtool archive"
+	  || func_fatal_error "\`$lib' is not a valid libtool archive"
 
 	func_dirname "$lib" "" "."
-	ladir=$func_dirname_result
+	ladir="$func_dirname_result"
 
 	dlname=
 	dlopen=
@@ -7876,19 +6430,19 @@ func_mode_link ()
 	  done
 	fi
 	dependency_libs=`$ECHO " $dependency_libs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'`
-	if test lib,link = "$linkmode,$pass" ||
-	   test prog,scan = "$linkmode,$pass" ||
-	   { test prog != "$linkmode" && test lib != "$linkmode"; }; then
+	if test "$linkmode,$pass" = "lib,link" ||
+	   test "$linkmode,$pass" = "prog,scan" ||
+	   { test "$linkmode" != prog && test "$linkmode" != lib; }; then
 	  test -n "$dlopen" && func_append dlfiles " $dlopen"
 	  test -n "$dlpreopen" && func_append dlprefiles " $dlpreopen"
 	fi
 
-	if test conv = "$pass"; then
+	if test "$pass" = conv; then
 	  # Only check for convenience libraries
 	  deplibs="$lib $deplibs"
 	  if test -z "$libdir"; then
 	    if test -z "$old_library"; then
-	      func_fatal_error "cannot find name of link library for '$lib'"
+	      func_fatal_error "cannot find name of link library for \`$lib'"
 	    fi
 	    # It is a libtool convenience library, so add in its objects.
 	    func_append convenience " $ladir/$objdir/$old_library"
@@ -7896,15 +6450,15 @@ func_mode_link ()
 	    tmp_libs=
 	    for deplib in $dependency_libs; do
 	      deplibs="$deplib $deplibs"
-	      if $opt_preserve_dup_deps; then
+	      if $opt_preserve_dup_deps ; then
 		case "$tmp_libs " in
 		*" $deplib "*) func_append specialdeplibs " $deplib" ;;
 		esac
 	      fi
 	      func_append tmp_libs " $deplib"
 	    done
-	  elif test prog != "$linkmode" && test lib != "$linkmode"; then
-	    func_fatal_error "'$lib' is not a convenience library"
+	  elif test "$linkmode" != prog && test "$linkmode" != lib; then
+	    func_fatal_error "\`$lib' is not a convenience library"
 	  fi
 	  continue
 	fi # $pass = conv
@@ -7913,26 +6467,26 @@ func_mode_link ()
 	# Get the name of the library we link against.
 	linklib=
 	if test -n "$old_library" &&
-	   { test yes = "$prefer_static_libs" ||
-	     test built,no = "$prefer_static_libs,$installed"; }; then
+	   { test "$prefer_static_libs" = yes ||
+	     test "$prefer_static_libs,$installed" = "built,no"; }; then
 	  linklib=$old_library
 	else
 	  for l in $old_library $library_names; do
-	    linklib=$l
+	    linklib="$l"
 	  done
 	fi
 	if test -z "$linklib"; then
-	  func_fatal_error "cannot find name of link library for '$lib'"
+	  func_fatal_error "cannot find name of link library for \`$lib'"
 	fi
 
 	# This library was specified with -dlopen.
-	if test dlopen = "$pass"; then
-	  test -z "$libdir" \
-	    && func_fatal_error "cannot -dlopen a convenience library: '$lib'"
+	if test "$pass" = dlopen; then
+	  if test -z "$libdir"; then
+	    func_fatal_error "cannot -dlopen a convenience library: \`$lib'"
+	  fi
 	  if test -z "$dlname" ||
-	     test yes != "$dlopen_support" ||
-	     test no = "$build_libtool_libs"
-	  then
+	     test "$dlopen_support" != yes ||
+	     test "$build_libtool_libs" = no; then
 	    # If there is no dlname, no dlopen support or we're linking
 	    # statically, we need to preload.  We also need to preload any
 	    # dependent libraries so libltdl's deplib preloader doesn't
@@ -7946,40 +6500,40 @@ func_mode_link ()
 
 	# We need an absolute path.
 	case $ladir in
-	[\\/]* | [A-Za-z]:[\\/]*) abs_ladir=$ladir ;;
+	[\\/]* | [A-Za-z]:[\\/]*) abs_ladir="$ladir" ;;
 	*)
 	  abs_ladir=`cd "$ladir" && pwd`
 	  if test -z "$abs_ladir"; then
-	    func_warning "cannot determine absolute directory name of '$ladir'"
+	    func_warning "cannot determine absolute directory name of \`$ladir'"
 	    func_warning "passing it literally to the linker, although it might fail"
-	    abs_ladir=$ladir
+	    abs_ladir="$ladir"
 	  fi
 	  ;;
 	esac
 	func_basename "$lib"
-	laname=$func_basename_result
+	laname="$func_basename_result"
 
 	# Find the relevant object directory and library name.
-	if test yes = "$installed"; then
+	if test "X$installed" = Xyes; then
 	  if test ! -f "$lt_sysroot$libdir/$linklib" && test -f "$abs_ladir/$linklib"; then
-	    func_warning "library '$lib' was moved."
-	    dir=$ladir
-	    absdir=$abs_ladir
-	    libdir=$abs_ladir
+	    func_warning "library \`$lib' was moved."
+	    dir="$ladir"
+	    absdir="$abs_ladir"
+	    libdir="$abs_ladir"
 	  else
-	    dir=$lt_sysroot$libdir
-	    absdir=$lt_sysroot$libdir
+	    dir="$lt_sysroot$libdir"
+	    absdir="$lt_sysroot$libdir"
 	  fi
-	  test yes = "$hardcode_automatic" && avoidtemprpath=yes
+	  test "X$hardcode_automatic" = Xyes && avoidtemprpath=yes
 	else
 	  if test ! -f "$ladir/$objdir/$linklib" && test -f "$abs_ladir/$linklib"; then
-	    dir=$ladir
-	    absdir=$abs_ladir
+	    dir="$ladir"
+	    absdir="$abs_ladir"
 	    # Remove this search path later
 	    func_append notinst_path " $abs_ladir"
 	  else
-	    dir=$ladir/$objdir
-	    absdir=$abs_ladir/$objdir
+	    dir="$ladir/$objdir"
+	    absdir="$abs_ladir/$objdir"
 	    # Remove this search path later
 	    func_append notinst_path " $abs_ladir"
 	  fi
@@ -7988,11 +6542,11 @@ func_mode_link ()
 	name=$func_stripname_result
 
 	# This library was specified with -dlpreopen.
-	if test dlpreopen = "$pass"; then
-	  if test -z "$libdir" && test prog = "$linkmode"; then
-	    func_fatal_error "only libraries may -dlpreopen a convenience library: '$lib'"
+	if test "$pass" = dlpreopen; then
+	  if test -z "$libdir" && test "$linkmode" = prog; then
+	    func_fatal_error "only libraries may -dlpreopen a convenience library: \`$lib'"
 	  fi
-	  case $host in
+	  case "$host" in
 	    # special handling for platforms with PE-DLLs.
 	    *cygwin* | *mingw* | *cegcc* )
 	      # Linker will automatically link against shared library if both
@@ -8036,9 +6590,9 @@ func_mode_link ()
 
 	if test -z "$libdir"; then
 	  # Link the convenience library
-	  if test lib = "$linkmode"; then
+	  if test "$linkmode" = lib; then
 	    deplibs="$dir/$old_library $deplibs"
-	  elif test prog,link = "$linkmode,$pass"; then
+	  elif test "$linkmode,$pass" = "prog,link"; then
 	    compile_deplibs="$dir/$old_library $compile_deplibs"
 	    finalize_deplibs="$dir/$old_library $finalize_deplibs"
 	  else
@@ -8048,14 +6602,14 @@ func_mode_link ()
 	fi
 
 
-	if test prog = "$linkmode" && test link != "$pass"; then
+	if test "$linkmode" = prog && test "$pass" != link; then
 	  func_append newlib_search_path " $ladir"
 	  deplibs="$lib $deplibs"
 
-	  linkalldeplibs=false
-	  if test no != "$link_all_deplibs" || test -z "$library_names" ||
-	     test no = "$build_libtool_libs"; then
-	    linkalldeplibs=:
+	  linkalldeplibs=no
+	  if test "$link_all_deplibs" != no || test -z "$library_names" ||
+	     test "$build_libtool_libs" = no; then
+	    linkalldeplibs=yes
 	  fi
 
 	  tmp_libs=
@@ -8067,14 +6621,14 @@ func_mode_link ()
 		 ;;
 	    esac
 	    # Need to link against all dependency_libs?
-	    if $linkalldeplibs; then
+	    if test "$linkalldeplibs" = yes; then
 	      deplibs="$deplib $deplibs"
 	    else
 	      # Need to hardcode shared library paths
 	      # or/and link against static libraries
 	      newdependency_libs="$deplib $newdependency_libs"
 	    fi
-	    if $opt_preserve_dup_deps; then
+	    if $opt_preserve_dup_deps ; then
 	      case "$tmp_libs " in
 	      *" $deplib "*) func_append specialdeplibs " $deplib" ;;
 	      esac
@@ -8084,15 +6638,15 @@ func_mode_link ()
 	  continue
 	fi # $linkmode = prog...
 
-	if test prog,link = "$linkmode,$pass"; then
+	if test "$linkmode,$pass" = "prog,link"; then
 	  if test -n "$library_names" &&
-	     { { test no = "$prefer_static_libs" ||
-	         test built,yes = "$prefer_static_libs,$installed"; } ||
+	     { { test "$prefer_static_libs" = no ||
+	         test "$prefer_static_libs,$installed" = "built,yes"; } ||
 	       test -z "$old_library"; }; then
 	    # We need to hardcode the library path
-	    if test -n "$shlibpath_var" && test -z "$avoidtemprpath"; then
+	    if test -n "$shlibpath_var" && test -z "$avoidtemprpath" ; then
 	      # Make sure the rpath contains only unique directories.
-	      case $temp_rpath: in
+	      case "$temp_rpath:" in
 	      *"$absdir:"*) ;;
 	      *) func_append temp_rpath "$absdir:" ;;
 	      esac
@@ -8121,9 +6675,9 @@ func_mode_link ()
 	    esac
 	  fi # $linkmode,$pass = prog,link...
 
-	  if $alldeplibs &&
-	     { test pass_all = "$deplibs_check_method" ||
-	       { test yes = "$build_libtool_libs" &&
+	  if test "$alldeplibs" = yes &&
+	     { test "$deplibs_check_method" = pass_all ||
+	       { test "$build_libtool_libs" = yes &&
 		 test -n "$library_names"; }; }; then
 	    # We only need to search for static libraries
 	    continue
@@ -8132,19 +6686,19 @@ func_mode_link ()
 
 	link_static=no # Whether the deplib will be linked statically
 	use_static_libs=$prefer_static_libs
-	if test built = "$use_static_libs" && test yes = "$installed"; then
+	if test "$use_static_libs" = built && test "$installed" = yes; then
 	  use_static_libs=no
 	fi
 	if test -n "$library_names" &&
-	   { test no = "$use_static_libs" || test -z "$old_library"; }; then
+	   { test "$use_static_libs" = no || test -z "$old_library"; }; then
 	  case $host in
-	  *cygwin* | *mingw* | *cegcc* | *os2*)
+	  *cygwin* | *mingw* | *cegcc*)
 	      # No point in relinking DLLs because paths are not encoded
 	      func_append notinst_deplibs " $lib"
 	      need_relink=no
 	    ;;
 	  *)
-	    if test no = "$installed"; then
+	    if test "$installed" = no; then
 	      func_append notinst_deplibs " $lib"
 	      need_relink=yes
 	    fi
@@ -8154,24 +6708,24 @@ func_mode_link ()
 
 	  # Warn about portability, can't link against -module's on some
 	  # systems (darwin).  Don't bleat about dlopened modules though!
-	  dlopenmodule=
+	  dlopenmodule=""
 	  for dlpremoduletest in $dlprefiles; do
 	    if test "X$dlpremoduletest" = "X$lib"; then
-	      dlopenmodule=$dlpremoduletest
+	      dlopenmodule="$dlpremoduletest"
 	      break
 	    fi
 	  done
-	  if test -z "$dlopenmodule" && test yes = "$shouldnotlink" && test link = "$pass"; then
+	  if test -z "$dlopenmodule" && test "$shouldnotlink" = yes && test "$pass" = link; then
 	    echo
-	    if test prog = "$linkmode"; then
+	    if test "$linkmode" = prog; then
 	      $ECHO "*** Warning: Linking the executable $output against the loadable module"
 	    else
 	      $ECHO "*** Warning: Linking the shared library $output against the loadable module"
 	    fi
 	    $ECHO "*** $linklib is not portable!"
 	  fi
-	  if test lib = "$linkmode" &&
-	     test yes = "$hardcode_into_libs"; then
+	  if test "$linkmode" = lib &&
+	     test "$hardcode_into_libs" = yes; then
 	    # Hardcode the library path.
 	    # Skip directories that are in the system default run-time
 	    # search path.
@@ -8199,43 +6753,43 @@ func_mode_link ()
 	    # figure out the soname
 	    set dummy $library_names
 	    shift
-	    realname=$1
+	    realname="$1"
 	    shift
 	    libname=`eval "\\$ECHO \"$libname_spec\""`
 	    # use dlname if we got it. it's perfectly good, no?
 	    if test -n "$dlname"; then
-	      soname=$dlname
+	      soname="$dlname"
 	    elif test -n "$soname_spec"; then
 	      # bleh windows
 	      case $host in
-	      *cygwin* | mingw* | *cegcc* | *os2*)
+	      *cygwin* | mingw* | *cegcc*)
 	        func_arith $current - $age
 		major=$func_arith_result
-		versuffix=-$major
+		versuffix="-$major"
 		;;
 	      esac
 	      eval soname=\"$soname_spec\"
 	    else
-	      soname=$realname
+	      soname="$realname"
 	    fi
 
 	    # Make a new name for the extract_expsyms_cmds to use
-	    soroot=$soname
+	    soroot="$soname"
 	    func_basename "$soroot"
-	    soname=$func_basename_result
+	    soname="$func_basename_result"
 	    func_stripname 'lib' '.dll' "$soname"
 	    newlib=libimp-$func_stripname_result.a
 
 	    # If the library has no export list, then create one now
 	    if test -f "$output_objdir/$soname-def"; then :
 	    else
-	      func_verbose "extracting exported symbol list from '$soname'"
+	      func_verbose "extracting exported symbol list from \`$soname'"
 	      func_execute_cmds "$extract_expsyms_cmds" 'exit $?'
 	    fi
 
 	    # Create $newlib
 	    if test -f "$output_objdir/$newlib"; then :; else
-	      func_verbose "generating import library for '$soname'"
+	      func_verbose "generating import library for \`$soname'"
 	      func_execute_cmds "$old_archive_from_expsyms_cmds" 'exit $?'
 	    fi
 	    # make sure the library variables are pointing to the new library
@@ -8243,58 +6797,58 @@ func_mode_link ()
 	    linklib=$newlib
 	  fi # test -n "$old_archive_from_expsyms_cmds"
 
-	  if test prog = "$linkmode" || test relink != "$opt_mode"; then
+	  if test "$linkmode" = prog || test "$opt_mode" != relink; then
 	    add_shlibpath=
 	    add_dir=
 	    add=
 	    lib_linked=yes
 	    case $hardcode_action in
 	    immediate | unsupported)
-	      if test no = "$hardcode_direct"; then
-		add=$dir/$linklib
+	      if test "$hardcode_direct" = no; then
+		add="$dir/$linklib"
 		case $host in
-		  *-*-sco3.2v5.0.[024]*) add_dir=-L$dir ;;
-		  *-*-sysv4*uw2*) add_dir=-L$dir ;;
+		  *-*-sco3.2v5.0.[024]*) add_dir="-L$dir" ;;
+		  *-*-sysv4*uw2*) add_dir="-L$dir" ;;
 		  *-*-sysv5OpenUNIX* | *-*-sysv5UnixWare7.[01].[10]* | \
-		    *-*-unixware7*) add_dir=-L$dir ;;
+		    *-*-unixware7*) add_dir="-L$dir" ;;
 		  *-*-darwin* )
-		    # if the lib is a (non-dlopened) module then we cannot
+		    # if the lib is a (non-dlopened) module then we can not
 		    # link against it, someone is ignoring the earlier warnings
 		    if /usr/bin/file -L $add 2> /dev/null |
-			 $GREP ": [^:]* bundle" >/dev/null; then
+			 $GREP ": [^:]* bundle" >/dev/null ; then
 		      if test "X$dlopenmodule" != "X$lib"; then
 			$ECHO "*** Warning: lib $linklib is a module, not a shared library"
-			if test -z "$old_library"; then
+			if test -z "$old_library" ; then
 			  echo
 			  echo "*** And there doesn't seem to be a static archive available"
 			  echo "*** The link will probably fail, sorry"
 			else
-			  add=$dir/$old_library
+			  add="$dir/$old_library"
 			fi
 		      elif test -n "$old_library"; then
-			add=$dir/$old_library
+			add="$dir/$old_library"
 		      fi
 		    fi
 		esac
-	      elif test no = "$hardcode_minus_L"; then
+	      elif test "$hardcode_minus_L" = no; then
 		case $host in
-		*-*-sunos*) add_shlibpath=$dir ;;
+		*-*-sunos*) add_shlibpath="$dir" ;;
 		esac
-		add_dir=-L$dir
-		add=-l$name
-	      elif test no = "$hardcode_shlibpath_var"; then
-		add_shlibpath=$dir
-		add=-l$name
+		add_dir="-L$dir"
+		add="-l$name"
+	      elif test "$hardcode_shlibpath_var" = no; then
+		add_shlibpath="$dir"
+		add="-l$name"
 	      else
 		lib_linked=no
 	      fi
 	      ;;
 	    relink)
-	      if test yes = "$hardcode_direct" &&
-	         test no = "$hardcode_direct_absolute"; then
-		add=$dir/$linklib
-	      elif test yes = "$hardcode_minus_L"; then
-		add_dir=-L$absdir
+	      if test "$hardcode_direct" = yes &&
+	         test "$hardcode_direct_absolute" = no; then
+		add="$dir/$linklib"
+	      elif test "$hardcode_minus_L" = yes; then
+		add_dir="-L$absdir"
 		# Try looking first in the location we're being installed to.
 		if test -n "$inst_prefix_dir"; then
 		  case $libdir in
@@ -8303,10 +6857,10 @@ func_mode_link ()
 		      ;;
 		  esac
 		fi
-		add=-l$name
-	      elif test yes = "$hardcode_shlibpath_var"; then
-		add_shlibpath=$dir
-		add=-l$name
+		add="-l$name"
+	      elif test "$hardcode_shlibpath_var" = yes; then
+		add_shlibpath="$dir"
+		add="-l$name"
 	      else
 		lib_linked=no
 	      fi
@@ -8314,7 +6868,7 @@ func_mode_link ()
 	    *) lib_linked=no ;;
 	    esac
 
-	    if test yes != "$lib_linked"; then
+	    if test "$lib_linked" != yes; then
 	      func_fatal_configuration "unsupported hardcode properties"
 	    fi
 
@@ -8324,15 +6878,15 @@ func_mode_link ()
 	      *) func_append compile_shlibpath "$add_shlibpath:" ;;
 	      esac
 	    fi
-	    if test prog = "$linkmode"; then
+	    if test "$linkmode" = prog; then
 	      test -n "$add_dir" && compile_deplibs="$add_dir $compile_deplibs"
 	      test -n "$add" && compile_deplibs="$add $compile_deplibs"
 	    else
 	      test -n "$add_dir" && deplibs="$add_dir $deplibs"
 	      test -n "$add" && deplibs="$add $deplibs"
-	      if test yes != "$hardcode_direct" &&
-		 test yes != "$hardcode_minus_L" &&
-		 test yes = "$hardcode_shlibpath_var"; then
+	      if test "$hardcode_direct" != yes &&
+		 test "$hardcode_minus_L" != yes &&
+		 test "$hardcode_shlibpath_var" = yes; then
 		case :$finalize_shlibpath: in
 		*":$libdir:"*) ;;
 		*) func_append finalize_shlibpath "$libdir:" ;;
@@ -8341,33 +6895,33 @@ func_mode_link ()
 	    fi
 	  fi
 
-	  if test prog = "$linkmode" || test relink = "$opt_mode"; then
+	  if test "$linkmode" = prog || test "$opt_mode" = relink; then
 	    add_shlibpath=
 	    add_dir=
 	    add=
 	    # Finalize command for both is simple: just hardcode it.
-	    if test yes = "$hardcode_direct" &&
-	       test no = "$hardcode_direct_absolute"; then
-	      add=$libdir/$linklib
-	    elif test yes = "$hardcode_minus_L"; then
-	      add_dir=-L$libdir
-	      add=-l$name
-	    elif test yes = "$hardcode_shlibpath_var"; then
+	    if test "$hardcode_direct" = yes &&
+	       test "$hardcode_direct_absolute" = no; then
+	      add="$libdir/$linklib"
+	    elif test "$hardcode_minus_L" = yes; then
+	      add_dir="-L$libdir"
+	      add="-l$name"
+	    elif test "$hardcode_shlibpath_var" = yes; then
 	      case :$finalize_shlibpath: in
 	      *":$libdir:"*) ;;
 	      *) func_append finalize_shlibpath "$libdir:" ;;
 	      esac
-	      add=-l$name
-	    elif test yes = "$hardcode_automatic"; then
+	      add="-l$name"
+	    elif test "$hardcode_automatic" = yes; then
 	      if test -n "$inst_prefix_dir" &&
-		 test -f "$inst_prefix_dir$libdir/$linklib"; then
-		add=$inst_prefix_dir$libdir/$linklib
+		 test -f "$inst_prefix_dir$libdir/$linklib" ; then
+		add="$inst_prefix_dir$libdir/$linklib"
 	      else
-		add=$libdir/$linklib
+		add="$libdir/$linklib"
 	      fi
 	    else
 	      # We cannot seem to hardcode it, guess we'll fake it.
-	      add_dir=-L$libdir
+	      add_dir="-L$libdir"
 	      # Try looking first in the location we're being installed to.
 	      if test -n "$inst_prefix_dir"; then
 		case $libdir in
@@ -8376,10 +6930,10 @@ func_mode_link ()
 		    ;;
 		esac
 	      fi
-	      add=-l$name
+	      add="-l$name"
 	    fi
 
-	    if test prog = "$linkmode"; then
+	    if test "$linkmode" = prog; then
 	      test -n "$add_dir" && finalize_deplibs="$add_dir $finalize_deplibs"
 	      test -n "$add" && finalize_deplibs="$add $finalize_deplibs"
 	    else
@@ -8387,43 +6941,43 @@ func_mode_link ()
 	      test -n "$add" && deplibs="$add $deplibs"
 	    fi
 	  fi
-	elif test prog = "$linkmode"; then
+	elif test "$linkmode" = prog; then
 	  # Here we assume that one of hardcode_direct or hardcode_minus_L
 	  # is not unsupported.  This is valid on all known static and
 	  # shared platforms.
-	  if test unsupported != "$hardcode_direct"; then
-	    test -n "$old_library" && linklib=$old_library
+	  if test "$hardcode_direct" != unsupported; then
+	    test -n "$old_library" && linklib="$old_library"
 	    compile_deplibs="$dir/$linklib $compile_deplibs"
 	    finalize_deplibs="$dir/$linklib $finalize_deplibs"
 	  else
 	    compile_deplibs="-l$name -L$dir $compile_deplibs"
 	    finalize_deplibs="-l$name -L$dir $finalize_deplibs"
 	  fi
-	elif test yes = "$build_libtool_libs"; then
+	elif test "$build_libtool_libs" = yes; then
 	  # Not a shared library
-	  if test pass_all != "$deplibs_check_method"; then
+	  if test "$deplibs_check_method" != pass_all; then
 	    # We're trying link a shared library against a static one
 	    # but the system doesn't support it.
 
 	    # Just print a warning and add the library to dependency_libs so
 	    # that the program can be linked against the static library.
 	    echo
-	    $ECHO "*** Warning: This system cannot link to static lib archive $lib."
+	    $ECHO "*** Warning: This system can not link to static lib archive $lib."
 	    echo "*** I have the capability to make that library automatically link in when"
 	    echo "*** you link to this library.  But I can only do this if you have a"
 	    echo "*** shared version of the library, which you do not appear to have."
-	    if test yes = "$module"; then
+	    if test "$module" = yes; then
 	      echo "*** But as you try to build a module library, libtool will still create "
 	      echo "*** a static module, that should work as long as the dlopening application"
 	      echo "*** is linked with the -dlopen flag to resolve symbols at runtime."
 	      if test -z "$global_symbol_pipe"; then
 		echo
 		echo "*** However, this would only work if libtool was able to extract symbol"
-		echo "*** lists from a program, using 'nm' or equivalent, but libtool could"
+		echo "*** lists from a program, using \`nm' or equivalent, but libtool could"
 		echo "*** not find such a program.  So, this module is probably useless."
-		echo "*** 'nm' from GNU binutils and a full rebuild may help."
+		echo "*** \`nm' from GNU binutils and a full rebuild may help."
 	      fi
-	      if test no = "$build_old_libs"; then
+	      if test "$build_old_libs" = no; then
 		build_libtool_libs=module
 		build_old_libs=yes
 	      else
@@ -8436,11 +6990,11 @@ func_mode_link ()
 	  fi
 	fi # link shared/static library?
 
-	if test lib = "$linkmode"; then
+	if test "$linkmode" = lib; then
 	  if test -n "$dependency_libs" &&
-	     { test yes != "$hardcode_into_libs" ||
-	       test yes = "$build_old_libs" ||
-	       test yes = "$link_static"; }; then
+	     { test "$hardcode_into_libs" != yes ||
+	       test "$build_old_libs" = yes ||
+	       test "$link_static" = yes; }; then
 	    # Extract -R from dependency_libs
 	    temp_deplibs=
 	    for libdir in $dependency_libs; do
@@ -8454,12 +7008,12 @@ func_mode_link ()
 	      *) func_append temp_deplibs " $libdir";;
 	      esac
 	    done
-	    dependency_libs=$temp_deplibs
+	    dependency_libs="$temp_deplibs"
 	  fi
 
 	  func_append newlib_search_path " $absdir"
 	  # Link against this library
-	  test no = "$link_static" && newdependency_libs="$abs_ladir/$laname $newdependency_libs"
+	  test "$link_static" = no && newdependency_libs="$abs_ladir/$laname $newdependency_libs"
 	  # ... and its dependency_libs
 	  tmp_libs=
 	  for deplib in $dependency_libs; do
@@ -8469,7 +7023,7 @@ func_mode_link ()
                    func_resolve_sysroot "$func_stripname_result";;
               *) func_resolve_sysroot "$deplib" ;;
             esac
-	    if $opt_preserve_dup_deps; then
+	    if $opt_preserve_dup_deps ; then
 	      case "$tmp_libs " in
 	      *" $func_resolve_sysroot_result "*)
                 func_append specialdeplibs " $func_resolve_sysroot_result" ;;
@@ -8478,12 +7032,12 @@ func_mode_link ()
 	    func_append tmp_libs " $func_resolve_sysroot_result"
 	  done
 
-	  if test no != "$link_all_deplibs"; then
+	  if test "$link_all_deplibs" != no; then
 	    # Add the search paths of all dependency libraries
 	    for deplib in $dependency_libs; do
 	      path=
 	      case $deplib in
-	      -L*) path=$deplib ;;
+	      -L*) path="$deplib" ;;
 	      *.la)
 	        func_resolve_sysroot "$deplib"
 	        deplib=$func_resolve_sysroot_result
@@ -8491,12 +7045,12 @@ func_mode_link ()
 		dir=$func_dirname_result
 		# We need an absolute path.
 		case $dir in
-		[\\/]* | [A-Za-z]:[\\/]*) absdir=$dir ;;
+		[\\/]* | [A-Za-z]:[\\/]*) absdir="$dir" ;;
 		*)
 		  absdir=`cd "$dir" && pwd`
 		  if test -z "$absdir"; then
-		    func_warning "cannot determine absolute directory name of '$dir'"
-		    absdir=$dir
+		    func_warning "cannot determine absolute directory name of \`$dir'"
+		    absdir="$dir"
 		  fi
 		  ;;
 		esac
@@ -8504,35 +7058,35 @@ func_mode_link ()
 		case $host in
 		*-*-darwin*)
 		  depdepl=
-		  eval deplibrary_names=`$SED -n -e 's/^library_names=\(.*\)$/\1/p' $deplib`
-		  if test -n "$deplibrary_names"; then
-		    for tmp in $deplibrary_names; do
+		  eval deplibrary_names=`${SED} -n -e 's/^library_names=\(.*\)$/\1/p' $deplib`
+		  if test -n "$deplibrary_names" ; then
+		    for tmp in $deplibrary_names ; do
 		      depdepl=$tmp
 		    done
-		    if test -f "$absdir/$objdir/$depdepl"; then
-		      depdepl=$absdir/$objdir/$depdepl
-		      darwin_install_name=`$OTOOL -L $depdepl | awk '{if (NR == 2) {print $1;exit}}'`
+		    if test -f "$absdir/$objdir/$depdepl" ; then
+		      depdepl="$absdir/$objdir/$depdepl"
+		      darwin_install_name=`${OTOOL} -L $depdepl | awk '{if (NR == 2) {print $1;exit}}'`
                       if test -z "$darwin_install_name"; then
-                          darwin_install_name=`$OTOOL64 -L $depdepl  | awk '{if (NR == 2) {print $1;exit}}'`
+                          darwin_install_name=`${OTOOL64} -L $depdepl  | awk '{if (NR == 2) {print $1;exit}}'`
                       fi
-		      func_append compiler_flags " $wl-dylib_file $wl$darwin_install_name:$depdepl"
-		      func_append linker_flags " -dylib_file $darwin_install_name:$depdepl"
+		      func_append compiler_flags " ${wl}-dylib_file ${wl}${darwin_install_name}:${depdepl}"
+		      func_append linker_flags " -dylib_file ${darwin_install_name}:${depdepl}"
 		      path=
 		    fi
 		  fi
 		  ;;
 		*)
-		  path=-L$absdir/$objdir
+		  path="-L$absdir/$objdir"
 		  ;;
 		esac
 		else
-		  eval libdir=`$SED -n -e 's/^libdir=\(.*\)$/\1/p' $deplib`
+		  eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $deplib`
 		  test -z "$libdir" && \
-		    func_fatal_error "'$deplib' is not a valid libtool archive"
+		    func_fatal_error "\`$deplib' is not a valid libtool archive"
 		  test "$absdir" != "$libdir" && \
-		    func_warning "'$deplib' seems to be moved"
+		    func_warning "\`$deplib' seems to be moved"
 
-		  path=-L$absdir
+		  path="-L$absdir"
 		fi
 		;;
 	      esac
@@ -8544,23 +7098,23 @@ func_mode_link ()
 	  fi # link_all_deplibs != no
 	fi # linkmode = lib
       done # for deplib in $libs
-      if test link = "$pass"; then
-	if test prog = "$linkmode"; then
+      if test "$pass" = link; then
+	if test "$linkmode" = "prog"; then
 	  compile_deplibs="$new_inherited_linker_flags $compile_deplibs"
 	  finalize_deplibs="$new_inherited_linker_flags $finalize_deplibs"
 	else
 	  compiler_flags="$compiler_flags "`$ECHO " $new_inherited_linker_flags" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'`
 	fi
       fi
-      dependency_libs=$newdependency_libs
-      if test dlpreopen = "$pass"; then
+      dependency_libs="$newdependency_libs"
+      if test "$pass" = dlpreopen; then
 	# Link the dlpreopened libraries before other libraries
 	for deplib in $save_deplibs; do
 	  deplibs="$deplib $deplibs"
 	done
       fi
-      if test dlopen != "$pass"; then
-	test conv = "$pass" || {
+      if test "$pass" != dlopen; then
+	if test "$pass" != conv; then
 	  # Make sure lib_search_path contains only unique directories.
 	  lib_search_path=
 	  for dir in $newlib_search_path; do
@@ -8570,12 +7124,12 @@ func_mode_link ()
 	    esac
 	  done
 	  newlib_search_path=
-	}
+	fi
 
-	if test prog,link = "$linkmode,$pass"; then
-	  vars="compile_deplibs finalize_deplibs"
+	if test "$linkmode,$pass" != "prog,link"; then
+	  vars="deplibs"
 	else
-	  vars=deplibs
+	  vars="compile_deplibs finalize_deplibs"
 	fi
 	for var in $vars dependency_libs; do
 	  # Add libraries to $var in reverse order
@@ -8633,93 +7187,62 @@ func_mode_link ()
 	  eval $var=\"$tmp_libs\"
 	done # for var
       fi
-
-      # Add Sun CC postdeps if required:
-      test CXX = "$tagname" && {
-        case $host_os in
-        linux*)
-          case `$CC -V 2>&1 | sed 5q` in
-          *Sun\ C*) # Sun C++ 5.9
-            func_suncc_cstd_abi
-
-            if test no != "$suncc_use_cstd_abi"; then
-              func_append postdeps ' -library=Cstd -library=Crun'
-            fi
-            ;;
-          esac
-          ;;
-
-        solaris*)
-          func_cc_basename "$CC"
-          case $func_cc_basename_result in
-          CC* | sunCC*)
-            func_suncc_cstd_abi
-
-            if test no != "$suncc_use_cstd_abi"; then
-              func_append postdeps ' -library=Cstd -library=Crun'
-            fi
-            ;;
-          esac
-          ;;
-        esac
-      }
-
       # Last step: remove runtime libs from dependency_libs
       # (they stay in deplibs)
       tmp_libs=
-      for i in $dependency_libs; do
+      for i in $dependency_libs ; do
 	case " $predeps $postdeps $compiler_lib_search_path " in
 	*" $i "*)
-	  i=
+	  i=""
 	  ;;
 	esac
-	if test -n "$i"; then
+	if test -n "$i" ; then
 	  func_append tmp_libs " $i"
 	fi
       done
       dependency_libs=$tmp_libs
     done # for pass
-    if test prog = "$linkmode"; then
-      dlfiles=$newdlfiles
+    if test "$linkmode" = prog; then
+      dlfiles="$newdlfiles"
     fi
-    if test prog = "$linkmode" || test lib = "$linkmode"; then
-      dlprefiles=$newdlprefiles
+    if test "$linkmode" = prog || test "$linkmode" = lib; then
+      dlprefiles="$newdlprefiles"
     fi
 
     case $linkmode in
     oldlib)
-      if test -n "$dlfiles$dlprefiles" || test no != "$dlself"; then
-	func_warning "'-dlopen' is ignored for archives"
+      if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then
+	func_warning "\`-dlopen' is ignored for archives"
       fi
 
       case " $deplibs" in
       *\ -l* | *\ -L*)
-	func_warning "'-l' and '-L' are ignored for archives" ;;
+	func_warning "\`-l' and \`-L' are ignored for archives" ;;
       esac
 
       test -n "$rpath" && \
-	func_warning "'-rpath' is ignored for archives"
+	func_warning "\`-rpath' is ignored for archives"
 
       test -n "$xrpath" && \
-	func_warning "'-R' is ignored for archives"
+	func_warning "\`-R' is ignored for archives"
 
       test -n "$vinfo" && \
-	func_warning "'-version-info/-version-number' is ignored for archives"
+	func_warning "\`-version-info/-version-number' is ignored for archives"
 
       test -n "$release" && \
-	func_warning "'-release' is ignored for archives"
+	func_warning "\`-release' is ignored for archives"
 
       test -n "$export_symbols$export_symbols_regex" && \
-	func_warning "'-export-symbols' is ignored for archives"
+	func_warning "\`-export-symbols' is ignored for archives"
 
       # Now set the variables for building old libraries.
       build_libtool_libs=no
-      oldlibs=$output
+      oldlibs="$output"
       func_append objs "$old_deplibs"
       ;;
 
     lib)
-      # Make sure we only generate libraries of the form 'libNAME.la'.
+      # Make sure we only generate libraries of the form `libNAME.la'.
       case $outputname in
       lib*)
 	func_stripname 'lib' '.la' "$outputname"
@@ -8728,10 +7251,10 @@ func_mode_link ()
 	eval libname=\"$libname_spec\"
 	;;
       *)
-	test no = "$module" \
-	  && func_fatal_help "libtool library '$output' must begin with 'lib'"
+	test "$module" = no && \
+	  func_fatal_help "libtool library \`$output' must begin with \`lib'"
 
-	if test no != "$need_lib_prefix"; then
+	if test "$need_lib_prefix" != no; then
 	  # Add the "lib" prefix for modules if required
 	  func_stripname '' '.la' "$outputname"
 	  name=$func_stripname_result
@@ -8745,8 +7268,8 @@ func_mode_link ()
       esac
 
       if test -n "$objs"; then
-	if test pass_all != "$deplibs_check_method"; then
-	  func_fatal_error "cannot build libtool library '$output' from non-libtool objects on this host:$objs"
+	if test "$deplibs_check_method" != pass_all; then
+	  func_fatal_error "cannot build libtool library \`$output' from non-libtool objects on this host:$objs"
 	else
 	  echo
 	  $ECHO "*** Warning: Linking the shared library $output against the non-libtool"
@@ -8755,21 +7278,21 @@ func_mode_link ()
 	fi
       fi
 
-      test no = "$dlself" \
-	|| func_warning "'-dlopen self' is ignored for libtool libraries"
+      test "$dlself" != no && \
+	func_warning "\`-dlopen self' is ignored for libtool libraries"
 
       set dummy $rpath
       shift
-      test 1 -lt "$#" \
-	&& func_warning "ignoring multiple '-rpath's for a libtool library"
+      test "$#" -gt 1 && \
+	func_warning "ignoring multiple \`-rpath's for a libtool library"
 
-      install_libdir=$1
+      install_libdir="$1"
 
       oldlibs=
       if test -z "$rpath"; then
-	if test yes = "$build_libtool_libs"; then
+	if test "$build_libtool_libs" = yes; then
 	  # Building a libtool convenience library.
-	  # Some compilers have problems with a '.al' extension so
+	  # Some compilers have problems with a `.al' extension so
 	  # convenience libraries should have the same extension an
 	  # archive normally would.
 	  oldlibs="$output_objdir/$libname.$libext $oldlibs"
@@ -8778,20 +7301,20 @@ func_mode_link ()
 	fi
 
 	test -n "$vinfo" && \
-	  func_warning "'-version-info/-version-number' is ignored for convenience libraries"
+	  func_warning "\`-version-info/-version-number' is ignored for convenience libraries"
 
 	test -n "$release" && \
-	  func_warning "'-release' is ignored for convenience libraries"
+	  func_warning "\`-release' is ignored for convenience libraries"
       else
 
 	# Parse the version information argument.
-	save_ifs=$IFS; IFS=:
+	save_ifs="$IFS"; IFS=':'
 	set dummy $vinfo 0 0 0
 	shift
-	IFS=$save_ifs
+	IFS="$save_ifs"
 
 	test -n "$7" && \
-	  func_fatal_help "too many parameters to '-version-info'"
+	  func_fatal_help "too many parameters to \`-version-info'"
 
 	# convert absolute version numbers to libtool ages
 	# this retains compatibility with .la files and attempts
@@ -8799,45 +7322,45 @@ func_mode_link ()
 
 	case $vinfo_number in
 	yes)
-	  number_major=$1
-	  number_minor=$2
-	  number_revision=$3
+	  number_major="$1"
+	  number_minor="$2"
+	  number_revision="$3"
 	  #
 	  # There are really only two kinds -- those that
 	  # use the current revision as the major version
 	  # and those that subtract age and use age as
 	  # a minor version.  But, then there is irix
-	  # that has an extra 1 added just for fun
+	  # which has an extra 1 added just for fun
 	  #
 	  case $version_type in
 	  # correct linux to gnu/linux during the next big refactor
-	  darwin|freebsd-elf|linux|osf|windows|none)
+	  darwin|linux|osf|windows|none)
 	    func_arith $number_major + $number_minor
 	    current=$func_arith_result
-	    age=$number_minor
-	    revision=$number_revision
+	    age="$number_minor"
+	    revision="$number_revision"
 	    ;;
-	  freebsd-aout|qnx|sunos)
-	    current=$number_major
-	    revision=$number_minor
-	    age=0
+	  freebsd-aout|freebsd-elf|qnx|sunos)
+	    current="$number_major"
+	    revision="$number_minor"
+	    age="0"
 	    ;;
 	  irix|nonstopux)
 	    func_arith $number_major + $number_minor
 	    current=$func_arith_result
-	    age=$number_minor
-	    revision=$number_minor
+	    age="$number_minor"
+	    revision="$number_minor"
 	    lt_irix_increment=no
 	    ;;
 	  *)
-	    func_fatal_configuration "$modename: unknown library version type '$version_type'"
+	    func_fatal_configuration "$modename: unknown library version type \`$version_type'"
 	    ;;
 	  esac
 	  ;;
 	no)
-	  current=$1
-	  revision=$2
-	  age=$3
+	  current="$1"
+	  revision="$2"
+	  age="$3"
 	  ;;
 	esac
 
@@ -8845,30 +7368,30 @@ func_mode_link ()
 	case $current in
 	0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;;
 	*)
-	  func_error "CURRENT '$current' must be a nonnegative integer"
-	  func_fatal_error "'$vinfo' is not valid version information"
+	  func_error "CURRENT \`$current' must be a nonnegative integer"
+	  func_fatal_error "\`$vinfo' is not valid version information"
 	  ;;
 	esac
 
 	case $revision in
 	0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;;
 	*)
-	  func_error "REVISION '$revision' must be a nonnegative integer"
-	  func_fatal_error "'$vinfo' is not valid version information"
+	  func_error "REVISION \`$revision' must be a nonnegative integer"
+	  func_fatal_error "\`$vinfo' is not valid version information"
 	  ;;
 	esac
 
 	case $age in
 	0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;;
 	*)
-	  func_error "AGE '$age' must be a nonnegative integer"
-	  func_fatal_error "'$vinfo' is not valid version information"
+	  func_error "AGE \`$age' must be a nonnegative integer"
+	  func_fatal_error "\`$vinfo' is not valid version information"
 	  ;;
 	esac
 
 	if test "$age" -gt "$current"; then
-	  func_error "AGE '$age' is greater than the current interface number '$current'"
-	  func_fatal_error "'$vinfo' is not valid version information"
+	  func_error "AGE \`$age' is greater than the current interface number \`$current'"
+	  func_fatal_error "\`$vinfo' is not valid version information"
 	fi
 
 	# Calculate the version variables.
@@ -8883,36 +7406,26 @@ func_mode_link ()
 	  # verstring for coding it into the library header
 	  func_arith $current - $age
 	  major=.$func_arith_result
-	  versuffix=$major.$age.$revision
+	  versuffix="$major.$age.$revision"
 	  # Darwin ld doesn't like 0 for these options...
 	  func_arith $current + 1
 	  minor_current=$func_arith_result
-	  xlcverstring="$wl-compatibility_version $wl$minor_current $wl-current_version $wl$minor_current.$revision"
+	  xlcverstring="${wl}-compatibility_version ${wl}$minor_current ${wl}-current_version ${wl}$minor_current.$revision"
 	  verstring="-compatibility_version $minor_current -current_version $minor_current.$revision"
-          # On Darwin other compilers
-          case $CC in
-              nagfor*)
-                  verstring="$wl-compatibility_version $wl$minor_current $wl-current_version $wl$minor_current.$revision"
-                  ;;
-              *)
-                  verstring="-compatibility_version $minor_current -current_version $minor_current.$revision"
-                  ;;
-          esac
 	  ;;
 
 	freebsd-aout)
-	  major=.$current
-	  versuffix=.$current.$revision
+	  major=".$current"
+	  versuffix=".$current.$revision";
 	  ;;
 
 	freebsd-elf)
-	  func_arith $current - $age
-	  major=.$func_arith_result
-	  versuffix=$major.$age.$revision
+	  major=".$current"
+	  versuffix=".$current"
 	  ;;
 
 	irix | nonstopux)
-	  if test no = "$lt_irix_increment"; then
+	  if test "X$lt_irix_increment" = "Xno"; then
 	    func_arith $current - $age
 	  else
 	    func_arith $current - $age + 1
@@ -8923,74 +7436,69 @@ func_mode_link ()
 	    nonstopux) verstring_prefix=nonstopux ;;
 	    *)         verstring_prefix=sgi ;;
 	  esac
-	  verstring=$verstring_prefix$major.$revision
+	  verstring="$verstring_prefix$major.$revision"
 
 	  # Add in all the interfaces that we are compatible with.
 	  loop=$revision
-	  while test 0 -ne "$loop"; do
+	  while test "$loop" -ne 0; do
 	    func_arith $revision - $loop
 	    iface=$func_arith_result
 	    func_arith $loop - 1
 	    loop=$func_arith_result
-	    verstring=$verstring_prefix$major.$iface:$verstring
+	    verstring="$verstring_prefix$major.$iface:$verstring"
 	  done
 
-	  # Before this point, $major must not contain '.'.
+	  # Before this point, $major must not contain `.'.
 	  major=.$major
-	  versuffix=$major.$revision
+	  versuffix="$major.$revision"
 	  ;;
 
 	linux) # correct to gnu/linux during the next big refactor
 	  func_arith $current - $age
 	  major=.$func_arith_result
-	  versuffix=$major.$age.$revision
+	  versuffix="$major.$age.$revision"
 	  ;;
 
 	osf)
 	  func_arith $current - $age
 	  major=.$func_arith_result
-	  versuffix=.$current.$age.$revision
-	  verstring=$current.$age.$revision
+	  versuffix=".$current.$age.$revision"
+	  verstring="$current.$age.$revision"
 
 	  # Add in all the interfaces that we are compatible with.
 	  loop=$age
-	  while test 0 -ne "$loop"; do
+	  while test "$loop" -ne 0; do
 	    func_arith $current - $loop
 	    iface=$func_arith_result
 	    func_arith $loop - 1
 	    loop=$func_arith_result
-	    verstring=$verstring:$iface.0
+	    verstring="$verstring:${iface}.0"
 	  done
 
 	  # Make executables depend on our current version.
-	  func_append verstring ":$current.0"
+	  func_append verstring ":${current}.0"
 	  ;;
 
 	qnx)
-	  major=.$current
-	  versuffix=.$current
-	  ;;
-
-	sco)
-	  major=.$current
-	  versuffix=.$current
+	  major=".$current"
+	  versuffix=".$current"
 	  ;;
 
 	sunos)
-	  major=.$current
-	  versuffix=.$current.$revision
+	  major=".$current"
+	  versuffix=".$current.$revision"
 	  ;;
 
 	windows)
 	  # Use '-' rather than '.', since we only want one
-	  # extension on DOS 8.3 file systems.
+	  # extension on DOS 8.3 filesystems.
 	  func_arith $current - $age
 	  major=$func_arith_result
-	  versuffix=-$major
+	  versuffix="-$major"
 	  ;;
 
 	*)
-	  func_fatal_configuration "unknown library version type '$version_type'"
+	  func_fatal_configuration "unknown library version type \`$version_type'"
 	  ;;
 	esac
 
@@ -9004,45 +7512,42 @@ func_mode_link ()
 	    verstring=
 	    ;;
 	  *)
-	    verstring=0.0
+	    verstring="0.0"
 	    ;;
 	  esac
-	  if test no = "$need_version"; then
+	  if test "$need_version" = no; then
 	    versuffix=
 	  else
-	    versuffix=.0.0
+	    versuffix=".0.0"
 	  fi
 	fi
 
 	# Remove version info from name if versioning should be avoided
-	if test yes,no = "$avoid_version,$need_version"; then
+	if test "$avoid_version" = yes && test "$need_version" = no; then
 	  major=
 	  versuffix=
-	  verstring=
+	  verstring=""
 	fi
 
 	# Check to see if the archive will have undefined symbols.
-	if test yes = "$allow_undefined"; then
-	  if test unsupported = "$allow_undefined_flag"; then
-	    if test yes = "$build_old_libs"; then
-	      func_warning "undefined symbols not allowed in $host shared libraries; building static only"
-	      build_libtool_libs=no
-	    else
-	      func_fatal_error "can't build $host shared library unless -no-undefined is specified"
-	    fi
+	if test "$allow_undefined" = yes; then
+	  if test "$allow_undefined_flag" = unsupported; then
+	    func_warning "undefined symbols not allowed in $host shared libraries"
+	    build_libtool_libs=no
+	    build_old_libs=yes
 	  fi
 	else
 	  # Don't allow undefined symbols.
-	  allow_undefined_flag=$no_undefined_flag
+	  allow_undefined_flag="$no_undefined_flag"
 	fi
 
       fi
 
-      func_generate_dlsyms "$libname" "$libname" :
+      func_generate_dlsyms "$libname" "$libname" "yes"
       func_append libobjs " $symfileobj"
-      test " " = "$libobjs" && libobjs=
+      test "X$libobjs" = "X " && libobjs=
 
-      if test relink != "$opt_mode"; then
+      if test "$opt_mode" != relink; then
 	# Remove our outputs, but don't remove object files since they
 	# may have been created when compiling PIC objects.
 	removelist=
@@ -9051,8 +7556,8 @@ func_mode_link ()
 	  case $p in
 	    *.$objext | *.gcno)
 	       ;;
-	    $output_objdir/$outputname | $output_objdir/$libname.* | $output_objdir/$libname$release.*)
-	       if test -n "$precious_files_regex"; then
+	    $output_objdir/$outputname | $output_objdir/$libname.* | $output_objdir/${libname}${release}.*)
+	       if test "X$precious_files_regex" != "X"; then
 		 if $ECHO "$p" | $EGREP -e "$precious_files_regex" >/dev/null 2>&1
 		 then
 		   continue
@@ -9068,11 +7573,11 @@ func_mode_link ()
       fi
 
       # Now set the variables for building old libraries.
-      if test yes = "$build_old_libs" && test convenience != "$build_libtool_libs"; then
+      if test "$build_old_libs" = yes && test "$build_libtool_libs" != convenience ; then
 	func_append oldlibs " $output_objdir/$libname.$libext"
 
 	# Transform .lo files to .o files.
-	oldobjs="$objs "`$ECHO "$libobjs" | $SP2NL | $SED "/\.$libext$/d; $lo2o" | $NL2SP`
+	oldobjs="$objs "`$ECHO "$libobjs" | $SP2NL | $SED "/\.${libext}$/d; $lo2o" | $NL2SP`
       fi
 
       # Eliminate all temporary directories.
@@ -9093,13 +7598,13 @@ func_mode_link ()
 	  *) func_append finalize_rpath " $libdir" ;;
 	  esac
 	done
-	if test yes != "$hardcode_into_libs" || test yes = "$build_old_libs"; then
+	if test "$hardcode_into_libs" != yes || test "$build_old_libs" = yes; then
 	  dependency_libs="$temp_xrpath $dependency_libs"
 	fi
       fi
 
       # Make sure dlfiles contains only unique files that won't be dlpreopened
-      old_dlfiles=$dlfiles
+      old_dlfiles="$dlfiles"
       dlfiles=
       for lib in $old_dlfiles; do
 	case " $dlprefiles $dlfiles " in
@@ -9109,7 +7614,7 @@ func_mode_link ()
       done
 
       # Make sure dlprefiles contains only unique files
-      old_dlprefiles=$dlprefiles
+      old_dlprefiles="$dlprefiles"
       dlprefiles=
       for lib in $old_dlprefiles; do
 	case "$dlprefiles " in
@@ -9118,7 +7623,7 @@ func_mode_link ()
 	esac
       done
 
-      if test yes = "$build_libtool_libs"; then
+      if test "$build_libtool_libs" = yes; then
 	if test -n "$rpath"; then
 	  case $host in
 	  *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-beos* | *-cegcc* | *-*-haiku*)
@@ -9142,7 +7647,7 @@ func_mode_link ()
 	    ;;
 	  *)
 	    # Add libc to deplibs on all other systems if necessary.
-	    if test yes = "$build_libtool_need_lc"; then
+	    if test "$build_libtool_need_lc" = "yes"; then
 	      func_append deplibs " -lc"
 	    fi
 	    ;;
@@ -9158,9 +7663,9 @@ func_mode_link ()
 	# I'm not sure if I'm treating the release correctly.  I think
 	# release should show up in the -l (ie -lgmp5) so we don't want to
 	# add it in twice.  Is that correct?
-	release=
-	versuffix=
-	major=
+	release=""
+	versuffix=""
+	major=""
 	newdeplibs=
 	droppeddeps=no
 	case $deplibs_check_method in
@@ -9189,20 +7694,20 @@ EOF
 	      -l*)
 		func_stripname -l '' "$i"
 		name=$func_stripname_result
-		if test yes = "$allow_libtool_libs_with_static_runtimes"; then
+		if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
 		  case " $predeps $postdeps " in
 		  *" $i "*)
 		    func_append newdeplibs " $i"
-		    i=
+		    i=""
 		    ;;
 		  esac
 		fi
-		if test -n "$i"; then
+		if test -n "$i" ; then
 		  libname=`eval "\\$ECHO \"$libname_spec\""`
 		  deplib_matches=`eval "\\$ECHO \"$library_names_spec\""`
 		  set dummy $deplib_matches; shift
 		  deplib_match=$1
-		  if test `expr "$ldd_output" : ".*$deplib_match"` -ne 0; then
+		  if test `expr "$ldd_output" : ".*$deplib_match"` -ne 0 ; then
 		    func_append newdeplibs " $i"
 		  else
 		    droppeddeps=yes
@@ -9232,20 +7737,20 @@ EOF
 		$opt_dry_run || $RM conftest
 		if $LTCC $LTCFLAGS -o conftest conftest.c $i; then
 		  ldd_output=`ldd conftest`
-		  if test yes = "$allow_libtool_libs_with_static_runtimes"; then
+		  if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
 		    case " $predeps $postdeps " in
 		    *" $i "*)
 		      func_append newdeplibs " $i"
-		      i=
+		      i=""
 		      ;;
 		    esac
 		  fi
-		  if test -n "$i"; then
+		  if test -n "$i" ; then
 		    libname=`eval "\\$ECHO \"$libname_spec\""`
 		    deplib_matches=`eval "\\$ECHO \"$library_names_spec\""`
 		    set dummy $deplib_matches; shift
 		    deplib_match=$1
-		    if test `expr "$ldd_output" : ".*$deplib_match"` -ne 0; then
+		    if test `expr "$ldd_output" : ".*$deplib_match"` -ne 0 ; then
 		      func_append newdeplibs " $i"
 		    else
 		      droppeddeps=yes
@@ -9282,24 +7787,24 @@ EOF
 	    -l*)
 	      func_stripname -l '' "$a_deplib"
 	      name=$func_stripname_result
-	      if test yes = "$allow_libtool_libs_with_static_runtimes"; then
+	      if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
 		case " $predeps $postdeps " in
 		*" $a_deplib "*)
 		  func_append newdeplibs " $a_deplib"
-		  a_deplib=
+		  a_deplib=""
 		  ;;
 		esac
 	      fi
-	      if test -n "$a_deplib"; then
+	      if test -n "$a_deplib" ; then
 		libname=`eval "\\$ECHO \"$libname_spec\""`
 		if test -n "$file_magic_glob"; then
 		  libnameglob=`func_echo_all "$libname" | $SED -e $file_magic_glob`
 		else
 		  libnameglob=$libname
 		fi
-		test yes = "$want_nocaseglob" && nocaseglob=`shopt -p nocaseglob`
+		test "$want_nocaseglob" = yes && nocaseglob=`shopt -p nocaseglob`
 		for i in $lib_search_path $sys_lib_search_path $shlib_search_path; do
-		  if test yes = "$want_nocaseglob"; then
+		  if test "$want_nocaseglob" = yes; then
 		    shopt -s nocaseglob
 		    potential_libs=`ls $i/$libnameglob[.-]* 2>/dev/null`
 		    $nocaseglob
@@ -9317,25 +7822,25 @@ EOF
 		      # We might still enter an endless loop, since a link
 		      # loop can be closed while we follow links,
 		      # but so what?
-		      potlib=$potent_lib
+		      potlib="$potent_lib"
 		      while test -h "$potlib" 2>/dev/null; do
-			potliblink=`ls -ld $potlib | $SED 's/.* -> //'`
+			potliblink=`ls -ld $potlib | ${SED} 's/.* -> //'`
 			case $potliblink in
-			[\\/]* | [A-Za-z]:[\\/]*) potlib=$potliblink;;
-			*) potlib=`$ECHO "$potlib" | $SED 's|[^/]*$||'`"$potliblink";;
+			[\\/]* | [A-Za-z]:[\\/]*) potlib="$potliblink";;
+			*) potlib=`$ECHO "$potlib" | $SED 's,[^/]*$,,'`"$potliblink";;
 			esac
 		      done
 		      if eval $file_magic_cmd \"\$potlib\" 2>/dev/null |
 			 $SED -e 10q |
 			 $EGREP "$file_magic_regex" > /dev/null; then
 			func_append newdeplibs " $a_deplib"
-			a_deplib=
+			a_deplib=""
 			break 2
 		      fi
 		  done
 		done
 	      fi
-	      if test -n "$a_deplib"; then
+	      if test -n "$a_deplib" ; then
 		droppeddeps=yes
 		echo
 		$ECHO "*** Warning: linker path does not have real file for library $a_deplib."
@@ -9343,7 +7848,7 @@ EOF
 		echo "*** you link to this library.  But I can only do this if you have a"
 		echo "*** shared version of the library, which you do not appear to have"
 		echo "*** because I did check the linker path looking for a file starting"
-		if test -z "$potlib"; then
+		if test -z "$potlib" ; then
 		  $ECHO "*** with $libname but no candidates were found. (...for file magic test)"
 		else
 		  $ECHO "*** with $libname and none of the candidates passed a file format test"
@@ -9366,30 +7871,30 @@ EOF
 	    -l*)
 	      func_stripname -l '' "$a_deplib"
 	      name=$func_stripname_result
-	      if test yes = "$allow_libtool_libs_with_static_runtimes"; then
+	      if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
 		case " $predeps $postdeps " in
 		*" $a_deplib "*)
 		  func_append newdeplibs " $a_deplib"
-		  a_deplib=
+		  a_deplib=""
 		  ;;
 		esac
 	      fi
-	      if test -n "$a_deplib"; then
+	      if test -n "$a_deplib" ; then
 		libname=`eval "\\$ECHO \"$libname_spec\""`
 		for i in $lib_search_path $sys_lib_search_path $shlib_search_path; do
 		  potential_libs=`ls $i/$libname[.-]* 2>/dev/null`
 		  for potent_lib in $potential_libs; do
-		    potlib=$potent_lib # see symlink-check above in file_magic test
+		    potlib="$potent_lib" # see symlink-check above in file_magic test
 		    if eval "\$ECHO \"$potent_lib\"" 2>/dev/null | $SED 10q | \
 		       $EGREP "$match_pattern_regex" > /dev/null; then
 		      func_append newdeplibs " $a_deplib"
-		      a_deplib=
+		      a_deplib=""
 		      break 2
 		    fi
 		  done
 		done
 	      fi
-	      if test -n "$a_deplib"; then
+	      if test -n "$a_deplib" ; then
 		droppeddeps=yes
 		echo
 		$ECHO "*** Warning: linker path does not have real file for library $a_deplib."
@@ -9397,7 +7902,7 @@ EOF
 		echo "*** you link to this library.  But I can only do this if you have a"
 		echo "*** shared version of the library, which you do not appear to have"
 		echo "*** because I did check the linker path looking for a file starting"
-		if test -z "$potlib"; then
+		if test -z "$potlib" ; then
 		  $ECHO "*** with $libname but no candidates were found. (...for regex pattern test)"
 		else
 		  $ECHO "*** with $libname and none of the candidates passed a file format test"
@@ -9413,18 +7918,18 @@ EOF
 	  done # Gone through all deplibs.
 	  ;;
 	none | unknown | *)
-	  newdeplibs=
+	  newdeplibs=""
 	  tmp_deplibs=`$ECHO " $deplibs" | $SED 's/ -lc$//; s/ -[LR][^ ]*//g'`
-	  if test yes = "$allow_libtool_libs_with_static_runtimes"; then
-	    for i in $predeps $postdeps; do
+	  if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
+	    for i in $predeps $postdeps ; do
 	      # can't use Xsed below, because $i might contain '/'
-	      tmp_deplibs=`$ECHO " $tmp_deplibs" | $SED "s|$i||"`
+	      tmp_deplibs=`$ECHO " $tmp_deplibs" | $SED "s,$i,,"`
 	    done
 	  fi
 	  case $tmp_deplibs in
 	  *[!\	\ ]*)
 	    echo
-	    if test none = "$deplibs_check_method"; then
+	    if test "X$deplibs_check_method" = "Xnone"; then
 	      echo "*** Warning: inter-library dependencies are not supported in this platform."
 	    else
 	      echo "*** Warning: inter-library dependencies are not known to be supported."
@@ -9448,8 +7953,8 @@ EOF
 	  ;;
 	esac
 
-	if test yes = "$droppeddeps"; then
-	  if test yes = "$module"; then
+	if test "$droppeddeps" = yes; then
+	  if test "$module" = yes; then
 	    echo
 	    echo "*** Warning: libtool could not satisfy all declared inter-library"
 	    $ECHO "*** dependencies of module $libname.  Therefore, libtool will create"
@@ -9458,12 +7963,12 @@ EOF
 	    if test -z "$global_symbol_pipe"; then
 	      echo
 	      echo "*** However, this would only work if libtool was able to extract symbol"
-	      echo "*** lists from a program, using 'nm' or equivalent, but libtool could"
+	      echo "*** lists from a program, using \`nm' or equivalent, but libtool could"
 	      echo "*** not find such a program.  So, this module is probably useless."
-	      echo "*** 'nm' from GNU binutils and a full rebuild may help."
+	      echo "*** \`nm' from GNU binutils and a full rebuild may help."
 	    fi
-	    if test no = "$build_old_libs"; then
-	      oldlibs=$output_objdir/$libname.$libext
+	    if test "$build_old_libs" = no; then
+	      oldlibs="$output_objdir/$libname.$libext"
 	      build_libtool_libs=module
 	      build_old_libs=yes
 	    else
@@ -9474,14 +7979,14 @@ EOF
 	    echo "*** automatically added whenever a program is linked with this library"
 	    echo "*** or is declared to -dlopen it."
 
-	    if test no = "$allow_undefined"; then
+	    if test "$allow_undefined" = no; then
 	      echo
 	      echo "*** Since this library must not contain undefined symbols,"
 	      echo "*** because either the platform does not support them or"
 	      echo "*** it was explicitly requested with -no-undefined,"
 	      echo "*** libtool will only create a static version of it."
-	      if test no = "$build_old_libs"; then
-		oldlibs=$output_objdir/$libname.$libext
+	      if test "$build_old_libs" = no; then
+		oldlibs="$output_objdir/$libname.$libext"
 		build_libtool_libs=module
 		build_old_libs=yes
 	      else
@@ -9527,7 +8032,7 @@ EOF
 	*) func_append new_libs " $deplib" ;;
 	esac
       done
-      deplibs=$new_libs
+      deplibs="$new_libs"
 
       # All the library-specific variables (install_libdir is set above).
       library_names=
@@ -9535,25 +8040,25 @@ EOF
       dlname=
 
       # Test again, we may have decided not to build it any more
-      if test yes = "$build_libtool_libs"; then
-	# Remove $wl instances when linking with ld.
+      if test "$build_libtool_libs" = yes; then
+	# Remove ${wl} instances when linking with ld.
 	# FIXME: should test the right _cmds variable.
 	case $archive_cmds in
 	  *\$LD\ *) wl= ;;
         esac
-	if test yes = "$hardcode_into_libs"; then
+	if test "$hardcode_into_libs" = yes; then
 	  # Hardcode the library paths
 	  hardcode_libdirs=
 	  dep_rpath=
-	  rpath=$finalize_rpath
-	  test relink = "$opt_mode" || rpath=$compile_rpath$rpath
+	  rpath="$finalize_rpath"
+	  test "$opt_mode" != relink && rpath="$compile_rpath$rpath"
 	  for libdir in $rpath; do
 	    if test -n "$hardcode_libdir_flag_spec"; then
 	      if test -n "$hardcode_libdir_separator"; then
 		func_replace_sysroot "$libdir"
 		libdir=$func_replace_sysroot_result
 		if test -z "$hardcode_libdirs"; then
-		  hardcode_libdirs=$libdir
+		  hardcode_libdirs="$libdir"
 		else
 		  # Just accumulate the unique libdirs.
 		  case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in
@@ -9578,7 +8083,7 @@ EOF
 	  # Substitute the hardcoded libdirs into the rpath.
 	  if test -n "$hardcode_libdir_separator" &&
 	     test -n "$hardcode_libdirs"; then
-	    libdir=$hardcode_libdirs
+	    libdir="$hardcode_libdirs"
 	    eval "dep_rpath=\"$hardcode_libdir_flag_spec\""
 	  fi
 	  if test -n "$runpath_var" && test -n "$perm_rpath"; then
@@ -9592,8 +8097,8 @@ EOF
 	  test -n "$dep_rpath" && deplibs="$dep_rpath $deplibs"
 	fi
 
-	shlibpath=$finalize_shlibpath
-	test relink = "$opt_mode" || shlibpath=$compile_shlibpath$shlibpath
+	shlibpath="$finalize_shlibpath"
+	test "$opt_mode" != relink && shlibpath="$compile_shlibpath$shlibpath"
 	if test -n "$shlibpath"; then
 	  eval "$shlibpath_var='$shlibpath\$$shlibpath_var'; export $shlibpath_var"
 	fi
@@ -9603,19 +8108,19 @@ EOF
 	eval library_names=\"$library_names_spec\"
 	set dummy $library_names
 	shift
-	realname=$1
+	realname="$1"
 	shift
 
 	if test -n "$soname_spec"; then
 	  eval soname=\"$soname_spec\"
 	else
-	  soname=$realname
+	  soname="$realname"
 	fi
 	if test -z "$dlname"; then
 	  dlname=$soname
 	fi
 
-	lib=$output_objdir/$realname
+	lib="$output_objdir/$realname"
 	linknames=
 	for link
 	do
@@ -9629,7 +8134,7 @@ EOF
 	delfiles=
 	if test -n "$export_symbols" && test -n "$include_expsyms"; then
 	  $opt_dry_run || cp "$export_symbols" "$output_objdir/$libname.uexp"
-	  export_symbols=$output_objdir/$libname.uexp
+	  export_symbols="$output_objdir/$libname.uexp"
 	  func_append delfiles " $export_symbols"
 	fi
 
@@ -9638,31 +8143,31 @@ EOF
 	cygwin* | mingw* | cegcc*)
 	  if test -n "$export_symbols" && test -z "$export_symbols_regex"; then
 	    # exporting using user supplied symfile
-	    func_dll_def_p "$export_symbols" || {
+	    if test "x`$SED 1q $export_symbols`" != xEXPORTS; then
 	      # and it's NOT already a .def file. Must figure out
 	      # which of the given symbols are data symbols and tag
 	      # them as such. So, trigger use of export_symbols_cmds.
 	      # export_symbols gets reassigned inside the "prepare
 	      # the list of exported symbols" if statement, so the
 	      # include_expsyms logic still works.
-	      orig_export_symbols=$export_symbols
+	      orig_export_symbols="$export_symbols"
 	      export_symbols=
 	      always_export_symbols=yes
-	    }
+	    fi
 	  fi
 	  ;;
 	esac
 
 	# Prepare the list of exported symbols
 	if test -z "$export_symbols"; then
-	  if test yes = "$always_export_symbols" || test -n "$export_symbols_regex"; then
-	    func_verbose "generating symbol list for '$libname.la'"
-	    export_symbols=$output_objdir/$libname.exp
+	  if test "$always_export_symbols" = yes || test -n "$export_symbols_regex"; then
+	    func_verbose "generating symbol list for \`$libname.la'"
+	    export_symbols="$output_objdir/$libname.exp"
 	    $opt_dry_run || $RM $export_symbols
 	    cmds=$export_symbols_cmds
-	    save_ifs=$IFS; IFS='~'
+	    save_ifs="$IFS"; IFS='~'
 	    for cmd1 in $cmds; do
-	      IFS=$save_ifs
+	      IFS="$save_ifs"
 	      # Take the normal branch if the nm_file_list_spec branch
 	      # doesn't work or if tool conversion is not needed.
 	      case $nm_file_list_spec~$to_tool_file_cmd in
@@ -9676,7 +8181,7 @@ EOF
 		  try_normal_branch=no
 		  ;;
 	      esac
-	      if test yes = "$try_normal_branch" \
+	      if test "$try_normal_branch" = yes \
 		 && { test "$len" -lt "$max_cmd_len" \
 		      || test "$max_cmd_len" -le -1; }
 	      then
@@ -9687,7 +8192,7 @@ EOF
 		output_la=$func_basename_result
 		save_libobjs=$libobjs
 		save_output=$output
-		output=$output_objdir/$output_la.nm
+		output=${output_objdir}/${output_la}.nm
 		func_to_tool_file "$output"
 		libobjs=$nm_file_list_spec$func_to_tool_file_result
 		func_append delfiles " $output"
@@ -9710,8 +8215,8 @@ EOF
 		break
 	      fi
 	    done
-	    IFS=$save_ifs
-	    if test -n "$export_symbols_regex" && test : != "$skipped_export"; then
+	    IFS="$save_ifs"
+	    if test -n "$export_symbols_regex" && test "X$skipped_export" != "X:"; then
 	      func_show_eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"'
 	      func_show_eval '$MV "${export_symbols}T" "$export_symbols"'
 	    fi
@@ -9719,16 +8224,16 @@ EOF
 	fi
 
 	if test -n "$export_symbols" && test -n "$include_expsyms"; then
-	  tmp_export_symbols=$export_symbols
-	  test -n "$orig_export_symbols" && tmp_export_symbols=$orig_export_symbols
+	  tmp_export_symbols="$export_symbols"
+	  test -n "$orig_export_symbols" && tmp_export_symbols="$orig_export_symbols"
 	  $opt_dry_run || eval '$ECHO "$include_expsyms" | $SP2NL >> "$tmp_export_symbols"'
 	fi
 
-	if test : != "$skipped_export" && test -n "$orig_export_symbols"; then
+	if test "X$skipped_export" != "X:" && test -n "$orig_export_symbols"; then
 	  # The given exports_symbols file has to be filtered, so filter it.
-	  func_verbose "filter symbol list for '$libname.la' to tag DATA exports"
+	  func_verbose "filter symbol list for \`$libname.la' to tag DATA exports"
 	  # FIXME: $output_objdir/$libname.filter potentially contains lots of
-	  # 's' commands, which not all seds can handle. GNU sed should be fine
+	  # 's' commands which not all seds can handle. GNU sed should be fine
 	  # though. Also, the filter scales superlinearly with the number of
 	  # global variables. join(1) would be nice here, but unfortunately
 	  # isn't a blessed tool.
@@ -9747,11 +8252,11 @@ EOF
 	    ;;
 	  esac
 	done
-	deplibs=$tmp_deplibs
+	deplibs="$tmp_deplibs"
 
 	if test -n "$convenience"; then
 	  if test -n "$whole_archive_flag_spec" &&
-	    test yes = "$compiler_needs_object" &&
+	    test "$compiler_needs_object" = yes &&
 	    test -z "$libobjs"; then
 	    # extract the archives, so we have objects to list.
 	    # TODO: could optimize this to just extract one archive.
@@ -9762,7 +8267,7 @@ EOF
 	    eval libobjs=\"\$libobjs $whole_archive_flag_spec\"
 	    test "X$libobjs" = "X " && libobjs=
 	  else
-	    gentop=$output_objdir/${outputname}x
+	    gentop="$output_objdir/${outputname}x"
 	    func_append generated " $gentop"
 
 	    func_extract_archives $gentop $convenience
@@ -9771,18 +8276,18 @@ EOF
 	  fi
 	fi
 
-	if test yes = "$thread_safe" && test -n "$thread_safe_flag_spec"; then
+	if test "$thread_safe" = yes && test -n "$thread_safe_flag_spec"; then
 	  eval flag=\"$thread_safe_flag_spec\"
 	  func_append linker_flags " $flag"
 	fi
 
 	# Make a backup of the uninstalled library when relinking
-	if test relink = "$opt_mode"; then
+	if test "$opt_mode" = relink; then
 	  $opt_dry_run || eval '(cd $output_objdir && $RM ${realname}U && $MV $realname ${realname}U)' || exit $?
 	fi
 
 	# Do each of the archive commands.
-	if test yes = "$module" && test -n "$module_cmds"; then
+	if test "$module" = yes && test -n "$module_cmds" ; then
 	  if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then
 	    eval test_cmds=\"$module_expsym_cmds\"
 	    cmds=$module_expsym_cmds
@@ -9800,7 +8305,7 @@ EOF
 	  fi
 	fi
 
-	if test : != "$skipped_export" &&
+	if test "X$skipped_export" != "X:" &&
 	   func_len " $test_cmds" &&
 	   len=$func_len_result &&
 	   test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then
@@ -9833,8 +8338,8 @@ EOF
 	  last_robj=
 	  k=1
 
-	  if test -n "$save_libobjs" && test : != "$skipped_export" && test yes = "$with_gnu_ld"; then
-	    output=$output_objdir/$output_la.lnkscript
+	  if test -n "$save_libobjs" && test "X$skipped_export" != "X:" && test "$with_gnu_ld" = yes; then
+	    output=${output_objdir}/${output_la}.lnkscript
 	    func_verbose "creating GNU ld script: $output"
 	    echo 'INPUT (' > $output
 	    for obj in $save_libobjs
@@ -9846,14 +8351,14 @@ EOF
 	    func_append delfiles " $output"
 	    func_to_tool_file "$output"
 	    output=$func_to_tool_file_result
-	  elif test -n "$save_libobjs" && test : != "$skipped_export" && test -n "$file_list_spec"; then
-	    output=$output_objdir/$output_la.lnk
+	  elif test -n "$save_libobjs" && test "X$skipped_export" != "X:" && test "X$file_list_spec" != X; then
+	    output=${output_objdir}/${output_la}.lnk
 	    func_verbose "creating linker input file list: $output"
 	    : > $output
 	    set x $save_libobjs
 	    shift
 	    firstobj=
-	    if test yes = "$compiler_needs_object"; then
+	    if test "$compiler_needs_object" = yes; then
 	      firstobj="$1 "
 	      shift
 	    fi
@@ -9868,7 +8373,7 @@ EOF
 	  else
 	    if test -n "$save_libobjs"; then
 	      func_verbose "creating reloadable object files..."
-	      output=$output_objdir/$output_la-$k.$objext
+	      output=$output_objdir/$output_la-${k}.$objext
 	      eval test_cmds=\"$reload_cmds\"
 	      func_len " $test_cmds"
 	      len0=$func_len_result
@@ -9880,13 +8385,13 @@ EOF
 		func_len " $obj"
 		func_arith $len + $func_len_result
 		len=$func_arith_result
-		if test -z "$objlist" ||
+		if test "X$objlist" = X ||
 		   test "$len" -lt "$max_cmd_len"; then
 		  func_append objlist " $obj"
 		else
 		  # The command $test_cmds is almost too long, add a
 		  # command to the queue.
-		  if test 1 -eq "$k"; then
+		  if test "$k" -eq 1 ; then
 		    # The first file doesn't have a previous command to add.
 		    reload_objs=$objlist
 		    eval concat_cmds=\"$reload_cmds\"
@@ -9896,10 +8401,10 @@ EOF
 		    reload_objs="$objlist $last_robj"
 		    eval concat_cmds=\"\$concat_cmds~$reload_cmds~\$RM $last_robj\"
 		  fi
-		  last_robj=$output_objdir/$output_la-$k.$objext
+		  last_robj=$output_objdir/$output_la-${k}.$objext
 		  func_arith $k + 1
 		  k=$func_arith_result
-		  output=$output_objdir/$output_la-$k.$objext
+		  output=$output_objdir/$output_la-${k}.$objext
 		  objlist=" $obj"
 		  func_len " $last_robj"
 		  func_arith $len0 + $func_len_result
@@ -9911,9 +8416,9 @@ EOF
 	      # files will link in the last one created.
 	      test -z "$concat_cmds" || concat_cmds=$concat_cmds~
 	      reload_objs="$objlist $last_robj"
-	      eval concat_cmds=\"\$concat_cmds$reload_cmds\"
+	      eval concat_cmds=\"\${concat_cmds}$reload_cmds\"
 	      if test -n "$last_robj"; then
-	        eval concat_cmds=\"\$concat_cmds~\$RM $last_robj\"
+	        eval concat_cmds=\"\${concat_cmds}~\$RM $last_robj\"
 	      fi
 	      func_append delfiles " $output"
 
@@ -9921,9 +8426,9 @@ EOF
 	      output=
 	    fi
 
-	    ${skipped_export-false} && {
-	      func_verbose "generating symbol list for '$libname.la'"
-	      export_symbols=$output_objdir/$libname.exp
+	    if ${skipped_export-false}; then
+	      func_verbose "generating symbol list for \`$libname.la'"
+	      export_symbols="$output_objdir/$libname.exp"
 	      $opt_dry_run || $RM $export_symbols
 	      libobjs=$output
 	      # Append the command to create the export file.
@@ -9932,16 +8437,16 @@ EOF
 	      if test -n "$last_robj"; then
 		eval concat_cmds=\"\$concat_cmds~\$RM $last_robj\"
 	      fi
-	    }
+	    fi
 
 	    test -n "$save_libobjs" &&
 	      func_verbose "creating a temporary reloadable object file: $output"
 
 	    # Loop through the commands generated above and execute them.
-	    save_ifs=$IFS; IFS='~'
+	    save_ifs="$IFS"; IFS='~'
 	    for cmd in $concat_cmds; do
-	      IFS=$save_ifs
-	      $opt_quiet || {
+	      IFS="$save_ifs"
+	      $opt_silent || {
 		  func_quote_for_expand "$cmd"
 		  eval "func_echo $func_quote_for_expand_result"
 	      }
@@ -9949,7 +8454,7 @@ EOF
 		lt_exit=$?
 
 		# Restore the uninstalled library and exit
-		if test relink = "$opt_mode"; then
+		if test "$opt_mode" = relink; then
 		  ( cd "$output_objdir" && \
 		    $RM "${realname}T" && \
 		    $MV "${realname}U" "$realname" )
@@ -9958,7 +8463,7 @@ EOF
 		exit $lt_exit
 	      }
 	    done
-	    IFS=$save_ifs
+	    IFS="$save_ifs"
 
 	    if test -n "$export_symbols_regex" && ${skipped_export-false}; then
 	      func_show_eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"'
@@ -9966,18 +8471,18 @@ EOF
 	    fi
 	  fi
 
-          ${skipped_export-false} && {
+          if ${skipped_export-false}; then
 	    if test -n "$export_symbols" && test -n "$include_expsyms"; then
-	      tmp_export_symbols=$export_symbols
-	      test -n "$orig_export_symbols" && tmp_export_symbols=$orig_export_symbols
+	      tmp_export_symbols="$export_symbols"
+	      test -n "$orig_export_symbols" && tmp_export_symbols="$orig_export_symbols"
 	      $opt_dry_run || eval '$ECHO "$include_expsyms" | $SP2NL >> "$tmp_export_symbols"'
 	    fi
 
 	    if test -n "$orig_export_symbols"; then
 	      # The given exports_symbols file has to be filtered, so filter it.
-	      func_verbose "filter symbol list for '$libname.la' to tag DATA exports"
+	      func_verbose "filter symbol list for \`$libname.la' to tag DATA exports"
 	      # FIXME: $output_objdir/$libname.filter potentially contains lots of
-	      # 's' commands, which not all seds can handle. GNU sed should be fine
+	      # 's' commands which not all seds can handle. GNU sed should be fine
 	      # though. Also, the filter scales superlinearly with the number of
 	      # global variables. join(1) would be nice here, but unfortunately
 	      # isn't a blessed tool.
@@ -9986,7 +8491,7 @@ EOF
 	      export_symbols=$output_objdir/$libname.def
 	      $opt_dry_run || $SED -f $output_objdir/$libname.filter < $orig_export_symbols > $export_symbols
 	    fi
-	  }
+	  fi
 
 	  libobjs=$output
 	  # Restore the value of output.
@@ -10000,7 +8505,7 @@ EOF
 	  # value of $libobjs for piecewise linking.
 
 	  # Do each of the archive commands.
-	  if test yes = "$module" && test -n "$module_cmds"; then
+	  if test "$module" = yes && test -n "$module_cmds" ; then
 	    if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then
 	      cmds=$module_expsym_cmds
 	    else
@@ -10022,7 +8527,7 @@ EOF
 
 	# Add any objects from preloaded convenience libraries
 	if test -n "$dlprefiles"; then
-	  gentop=$output_objdir/${outputname}x
+	  gentop="$output_objdir/${outputname}x"
 	  func_append generated " $gentop"
 
 	  func_extract_archives $gentop $dlprefiles
@@ -10030,12 +8535,11 @@ EOF
 	  test "X$libobjs" = "X " && libobjs=
 	fi
 
-	save_ifs=$IFS; IFS='~'
+	save_ifs="$IFS"; IFS='~'
 	for cmd in $cmds; do
-	  IFS=$sp$nl
+	  IFS="$save_ifs"
 	  eval cmd=\"$cmd\"
-	  IFS=$save_ifs
-	  $opt_quiet || {
+	  $opt_silent || {
 	    func_quote_for_expand "$cmd"
 	    eval "func_echo $func_quote_for_expand_result"
 	  }
@@ -10043,7 +8547,7 @@ EOF
 	    lt_exit=$?
 
 	    # Restore the uninstalled library and exit
-	    if test relink = "$opt_mode"; then
+	    if test "$opt_mode" = relink; then
 	      ( cd "$output_objdir" && \
 	        $RM "${realname}T" && \
 		$MV "${realname}U" "$realname" )
@@ -10052,10 +8556,10 @@ EOF
 	    exit $lt_exit
 	  }
 	done
-	IFS=$save_ifs
+	IFS="$save_ifs"
 
 	# Restore the uninstalled library and exit
-	if test relink = "$opt_mode"; then
+	if test "$opt_mode" = relink; then
 	  $opt_dry_run || eval '(cd $output_objdir && $RM ${realname}T && $MV $realname ${realname}T && $MV ${realname}U $realname)' || exit $?
 
 	  if test -n "$convenience"; then
@@ -10075,39 +8579,39 @@ EOF
 	done
 
 	# If -module or -export-dynamic was specified, set the dlname.
-	if test yes = "$module" || test yes = "$export_dynamic"; then
+	if test "$module" = yes || test "$export_dynamic" = yes; then
 	  # On all known operating systems, these are identical.
-	  dlname=$soname
+	  dlname="$soname"
 	fi
       fi
       ;;
 
     obj)
-      if test -n "$dlfiles$dlprefiles" || test no != "$dlself"; then
-	func_warning "'-dlopen' is ignored for objects"
+      if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then
+	func_warning "\`-dlopen' is ignored for objects"
       fi
 
       case " $deplibs" in
       *\ -l* | *\ -L*)
-	func_warning "'-l' and '-L' are ignored for objects" ;;
+	func_warning "\`-l' and \`-L' are ignored for objects" ;;
       esac
 
       test -n "$rpath" && \
-	func_warning "'-rpath' is ignored for objects"
+	func_warning "\`-rpath' is ignored for objects"
 
       test -n "$xrpath" && \
-	func_warning "'-R' is ignored for objects"
+	func_warning "\`-R' is ignored for objects"
 
       test -n "$vinfo" && \
-	func_warning "'-version-info' is ignored for objects"
+	func_warning "\`-version-info' is ignored for objects"
 
       test -n "$release" && \
-	func_warning "'-release' is ignored for objects"
+	func_warning "\`-release' is ignored for objects"
 
       case $output in
       *.lo)
 	test -n "$objs$old_deplibs" && \
-	  func_fatal_error "cannot build library object '$output' from non-libtool objects"
+	  func_fatal_error "cannot build library object \`$output' from non-libtool objects"
 
 	libobj=$output
 	func_lo2o "$libobj"
@@ -10115,7 +8619,7 @@ EOF
 	;;
       *)
 	libobj=
-	obj=$output
+	obj="$output"
 	;;
       esac
 
@@ -10128,19 +8632,17 @@ EOF
       # the extraction.
       reload_conv_objs=
       gentop=
-      # if reload_cmds runs $LD directly, get rid of -Wl from
-      # whole_archive_flag_spec and hope we can get by with turning comma
-      # into space.
-      case $reload_cmds in
-        *\$LD[\ \$]*) wl= ;;
-      esac
+      # reload_cmds runs $LD directly, so let us get rid of
+      # -Wl from whole_archive_flag_spec and hope we can get by with
+      # turning comma into space..
+      wl=
+
       if test -n "$convenience"; then
 	if test -n "$whole_archive_flag_spec"; then
 	  eval tmp_whole_archive_flags=\"$whole_archive_flag_spec\"
-	  test -n "$wl" || tmp_whole_archive_flags=`$ECHO "$tmp_whole_archive_flags" | $SED 's|,| |g'`
-	  reload_conv_objs=$reload_objs\ $tmp_whole_archive_flags
+	  reload_conv_objs=$reload_objs\ `$ECHO "$tmp_whole_archive_flags" | $SED 's|,| |g'`
 	else
-	  gentop=$output_objdir/${obj}x
+	  gentop="$output_objdir/${obj}x"
 	  func_append generated " $gentop"
 
 	  func_extract_archives $gentop $convenience
@@ -10149,12 +8651,12 @@ EOF
       fi
 
       # If we're not building shared, we need to use non_pic_objs
-      test yes = "$build_libtool_libs" || libobjs=$non_pic_objects
+      test "$build_libtool_libs" != yes && libobjs="$non_pic_objects"
 
       # Create the old-style object.
-      reload_objs=$objs$old_deplibs' '`$ECHO "$libobjs" | $SP2NL | $SED "/\.$libext$/d; /\.lib$/d; $lo2o" | $NL2SP`' '$reload_conv_objs
+      reload_objs="$objs$old_deplibs "`$ECHO "$libobjs" | $SP2NL | $SED "/\.${libext}$/d; /\.lib$/d; $lo2o" | $NL2SP`" $reload_conv_objs" ### testsuite: skip nested quoting test
 
-      output=$obj
+      output="$obj"
       func_execute_cmds "$reload_cmds" 'exit $?'
 
       # Exit if we aren't doing a library object file.
@@ -10166,7 +8668,7 @@ EOF
 	exit $EXIT_SUCCESS
       fi
 
-      test yes = "$build_libtool_libs" || {
+      if test "$build_libtool_libs" != yes; then
 	if test -n "$gentop"; then
 	  func_show_eval '${RM}r "$gentop"'
 	fi
@@ -10176,12 +8678,12 @@ EOF
 	# $show "echo timestamp > $libobj"
 	# $opt_dry_run || eval "echo timestamp > $libobj" || exit $?
 	exit $EXIT_SUCCESS
-      }
+      fi
 
-      if test -n "$pic_flag" || test default != "$pic_mode"; then
+      if test -n "$pic_flag" || test "$pic_mode" != default; then
 	# Only do commands if we really have different PIC objects.
 	reload_objs="$libobjs $reload_conv_objs"
-	output=$libobj
+	output="$libobj"
 	func_execute_cmds "$reload_cmds" 'exit $?'
       fi
 
@@ -10198,14 +8700,16 @@ EOF
 	          output=$func_stripname_result.exe;;
       esac
       test -n "$vinfo" && \
-	func_warning "'-version-info' is ignored for programs"
+	func_warning "\`-version-info' is ignored for programs"
 
       test -n "$release" && \
-	func_warning "'-release' is ignored for programs"
+	func_warning "\`-release' is ignored for programs"
 
-      $preload \
-	&& test unknown,unknown,unknown = "$dlopen_support,$dlopen_self,$dlopen_self_static" \
-	&& func_warning "'LT_INIT([dlopen])' not used. Assuming no dlopen support."
+      test "$preload" = yes \
+        && test "$dlopen_support" = unknown \
+	&& test "$dlopen_self" = unknown \
+	&& test "$dlopen_self_static" = unknown && \
+	  func_warning "\`LT_INIT([dlopen])' not used. Assuming no dlopen support."
 
       case $host in
       *-*-rhapsody* | *-*-darwin1.[012])
@@ -10219,11 +8723,11 @@ EOF
       *-*-darwin*)
 	# Don't allow lazy linking, it breaks C++ global constructors
 	# But is supposedly fixed on 10.4 or later (yay!).
-	if test CXX = "$tagname"; then
+	if test "$tagname" = CXX ; then
 	  case ${MACOSX_DEPLOYMENT_TARGET-10.0} in
 	    10.[0123])
-	      func_append compile_command " $wl-bind_at_load"
-	      func_append finalize_command " $wl-bind_at_load"
+	      func_append compile_command " ${wl}-bind_at_load"
+	      func_append finalize_command " ${wl}-bind_at_load"
 	    ;;
 	  esac
 	fi
@@ -10259,7 +8763,7 @@ EOF
 	*) func_append new_libs " $deplib" ;;
 	esac
       done
-      compile_deplibs=$new_libs
+      compile_deplibs="$new_libs"
 
 
       func_append compile_command " $compile_deplibs"
@@ -10283,7 +8787,7 @@ EOF
 	if test -n "$hardcode_libdir_flag_spec"; then
 	  if test -n "$hardcode_libdir_separator"; then
 	    if test -z "$hardcode_libdirs"; then
-	      hardcode_libdirs=$libdir
+	      hardcode_libdirs="$libdir"
 	    else
 	      # Just accumulate the unique libdirs.
 	      case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in
@@ -10306,7 +8810,7 @@ EOF
 	fi
 	case $host in
 	*-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*)
-	  testbindir=`$ECHO "$libdir" | $SED -e 's*/lib$*/bin*'`
+	  testbindir=`${ECHO} "$libdir" | ${SED} -e 's*/lib$*/bin*'`
 	  case :$dllsearchpath: in
 	  *":$libdir:"*) ;;
 	  ::) dllsearchpath=$libdir;;
@@ -10323,10 +8827,10 @@ EOF
       # Substitute the hardcoded libdirs into the rpath.
       if test -n "$hardcode_libdir_separator" &&
 	 test -n "$hardcode_libdirs"; then
-	libdir=$hardcode_libdirs
+	libdir="$hardcode_libdirs"
 	eval rpath=\" $hardcode_libdir_flag_spec\"
       fi
-      compile_rpath=$rpath
+      compile_rpath="$rpath"
 
       rpath=
       hardcode_libdirs=
@@ -10334,7 +8838,7 @@ EOF
 	if test -n "$hardcode_libdir_flag_spec"; then
 	  if test -n "$hardcode_libdir_separator"; then
 	    if test -z "$hardcode_libdirs"; then
-	      hardcode_libdirs=$libdir
+	      hardcode_libdirs="$libdir"
 	    else
 	      # Just accumulate the unique libdirs.
 	      case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in
@@ -10359,43 +8863,45 @@ EOF
       # Substitute the hardcoded libdirs into the rpath.
       if test -n "$hardcode_libdir_separator" &&
 	 test -n "$hardcode_libdirs"; then
-	libdir=$hardcode_libdirs
+	libdir="$hardcode_libdirs"
 	eval rpath=\" $hardcode_libdir_flag_spec\"
       fi
-      finalize_rpath=$rpath
+      finalize_rpath="$rpath"
 
-      if test -n "$libobjs" && test yes = "$build_old_libs"; then
+      if test -n "$libobjs" && test "$build_old_libs" = yes; then
 	# Transform all the library objects into standard objects.
 	compile_command=`$ECHO "$compile_command" | $SP2NL | $SED "$lo2o" | $NL2SP`
 	finalize_command=`$ECHO "$finalize_command" | $SP2NL | $SED "$lo2o" | $NL2SP`
       fi
 
-      func_generate_dlsyms "$outputname" "@PROGRAM@" false
+      func_generate_dlsyms "$outputname" "@PROGRAM@" "no"
 
       # template prelinking step
       if test -n "$prelink_cmds"; then
 	func_execute_cmds "$prelink_cmds" 'exit $?'
       fi
 
-      wrappers_required=:
+      wrappers_required=yes
       case $host in
       *cegcc* | *mingw32ce*)
         # Disable wrappers for cegcc and mingw32ce hosts, we are cross compiling anyway.
-        wrappers_required=false
+        wrappers_required=no
         ;;
       *cygwin* | *mingw* )
-        test yes = "$build_libtool_libs" || wrappers_required=false
+        if test "$build_libtool_libs" != yes; then
+          wrappers_required=no
+        fi
         ;;
       *)
-        if test no = "$need_relink" || test yes != "$build_libtool_libs"; then
-          wrappers_required=false
+        if test "$need_relink" = no || test "$build_libtool_libs" != yes; then
+          wrappers_required=no
         fi
         ;;
       esac
-      $wrappers_required || {
+      if test "$wrappers_required" = no; then
 	# Replace the output file specification.
 	compile_command=`$ECHO "$compile_command" | $SED 's%@OUTPUT@%'"$output"'%g'`
-	link_command=$compile_command$compile_rpath
+	link_command="$compile_command$compile_rpath"
 
 	# We have no uninstalled library dependencies, so finalize right now.
 	exit_status=0
@@ -10408,12 +8914,12 @@ EOF
 	fi
 
 	# Delete the generated files.
-	if test -f "$output_objdir/${outputname}S.$objext"; then
-	  func_show_eval '$RM "$output_objdir/${outputname}S.$objext"'
+	if test -f "$output_objdir/${outputname}S.${objext}"; then
+	  func_show_eval '$RM "$output_objdir/${outputname}S.${objext}"'
 	fi
 
 	exit $exit_status
-      }
+      fi
 
       if test -n "$compile_shlibpath$finalize_shlibpath"; then
 	compile_command="$shlibpath_var=\"$compile_shlibpath$finalize_shlibpath\$$shlibpath_var\" $compile_command"
@@ -10443,9 +8949,9 @@ EOF
 	fi
       fi
 
-      if test yes = "$no_install"; then
+      if test "$no_install" = yes; then
 	# We don't need to create a wrapper script.
-	link_command=$compile_var$compile_command$compile_rpath
+	link_command="$compile_var$compile_command$compile_rpath"
 	# Replace the output file specification.
 	link_command=`$ECHO "$link_command" | $SED 's%@OUTPUT@%'"$output"'%g'`
 	# Delete the old output file.
@@ -10462,28 +8968,27 @@ EOF
 	exit $EXIT_SUCCESS
       fi
 
-      case $hardcode_action,$fast_install in
-        relink,*)
-	  # Fast installation is not supported
-	  link_command=$compile_var$compile_command$compile_rpath
-	  relink_command=$finalize_var$finalize_command$finalize_rpath
+      if test "$hardcode_action" = relink; then
+	# Fast installation is not supported
+	link_command="$compile_var$compile_command$compile_rpath"
+	relink_command="$finalize_var$finalize_command$finalize_rpath"
 
-	  func_warning "this platform does not like uninstalled shared libraries"
-	  func_warning "'$output' will be relinked during installation"
-	  ;;
-        *,yes)
-	  link_command=$finalize_var$compile_command$finalize_rpath
-	  relink_command=`$ECHO "$compile_var$compile_command$compile_rpath" | $SED 's%@OUTPUT@%\$progdir/\$file%g'`
-          ;;
-	*,no)
-	  link_command=$compile_var$compile_command$compile_rpath
-	  relink_command=$finalize_var$finalize_command$finalize_rpath
-          ;;
-	*,needless)
-	  link_command=$finalize_var$compile_command$finalize_rpath
-	  relink_command=
-          ;;
-      esac
+	func_warning "this platform does not like uninstalled shared libraries"
+	func_warning "\`$output' will be relinked during installation"
+      else
+	if test "$fast_install" != no; then
+	  link_command="$finalize_var$compile_command$finalize_rpath"
+	  if test "$fast_install" = yes; then
+	    relink_command=`$ECHO "$compile_var$compile_command$compile_rpath" | $SED 's%@OUTPUT@%\$progdir/\$file%g'`
+	  else
+	    # fast_install is set to needless
+	    relink_command=
+	  fi
+	else
+	  link_command="$compile_var$compile_command$compile_rpath"
+	  relink_command="$finalize_var$finalize_command$finalize_rpath"
+	fi
+      fi
 
       # Replace the output file specification.
       link_command=`$ECHO "$link_command" | $SED 's%@OUTPUT@%'"$output_objdir/$outputname"'%g'`
@@ -10540,8 +9045,8 @@ EOF
 	    func_dirname_and_basename "$output" "" "."
 	    output_name=$func_basename_result
 	    output_path=$func_dirname_result
-	    cwrappersource=$output_path/$objdir/lt-$output_name.c
-	    cwrapper=$output_path/$output_name.exe
+	    cwrappersource="$output_path/$objdir/lt-$output_name.c"
+	    cwrapper="$output_path/$output_name.exe"
 	    $RM $cwrappersource $cwrapper
 	    trap "$RM $cwrappersource $cwrapper; exit $EXIT_FAILURE" 1 2 15
 
@@ -10562,7 +9067,7 @@ EOF
 	    trap "$RM $func_ltwrapper_scriptname_result; exit $EXIT_FAILURE" 1 2 15
 	    $opt_dry_run || {
 	      # note: this script will not be executed, so do not chmod.
-	      if test "x$build" = "x$host"; then
+	      if test "x$build" = "x$host" ; then
 		$cwrapper --lt-dump-script > $func_ltwrapper_scriptname_result
 	      else
 		func_emit_wrapper no > $func_ltwrapper_scriptname_result
@@ -10585,27 +9090,25 @@ EOF
     # See if we need to build an old-fashioned archive.
     for oldlib in $oldlibs; do
 
-      case $build_libtool_libs in
-        convenience)
-	  oldobjs="$libobjs_save $symfileobj"
-	  addlibs=$convenience
-	  build_libtool_libs=no
-	  ;;
-	module)
-	  oldobjs=$libobjs_save
-	  addlibs=$old_convenience
+      if test "$build_libtool_libs" = convenience; then
+	oldobjs="$libobjs_save $symfileobj"
+	addlibs="$convenience"
+	build_libtool_libs=no
+      else
+	if test "$build_libtool_libs" = module; then
+	  oldobjs="$libobjs_save"
 	  build_libtool_libs=no
-          ;;
-	*)
+	else
 	  oldobjs="$old_deplibs $non_pic_objects"
-	  $preload && test -f "$symfileobj" \
-	    && func_append oldobjs " $symfileobj"
-	  addlibs=$old_convenience
-	  ;;
-      esac
+	  if test "$preload" = yes && test -f "$symfileobj"; then
+	    func_append oldobjs " $symfileobj"
+	  fi
+	fi
+	addlibs="$old_convenience"
+      fi
 
       if test -n "$addlibs"; then
-	gentop=$output_objdir/${outputname}x
+	gentop="$output_objdir/${outputname}x"
 	func_append generated " $gentop"
 
 	func_extract_archives $gentop $addlibs
@@ -10613,13 +9116,13 @@ EOF
       fi
 
       # Do each command in the archive commands.
-      if test -n "$old_archive_from_new_cmds" && test yes = "$build_libtool_libs"; then
+      if test -n "$old_archive_from_new_cmds" && test "$build_libtool_libs" = yes; then
 	cmds=$old_archive_from_new_cmds
       else
 
 	# Add any objects from preloaded convenience libraries
 	if test -n "$dlprefiles"; then
-	  gentop=$output_objdir/${outputname}x
+	  gentop="$output_objdir/${outputname}x"
 	  func_append generated " $gentop"
 
 	  func_extract_archives $gentop $dlprefiles
@@ -10640,7 +9143,7 @@ EOF
 	  :
 	else
 	  echo "copying selected object files to avoid basename conflicts..."
-	  gentop=$output_objdir/${outputname}x
+	  gentop="$output_objdir/${outputname}x"
 	  func_append generated " $gentop"
 	  func_mkdir_p "$gentop"
 	  save_oldobjs=$oldobjs
@@ -10649,7 +9152,7 @@ EOF
 	  for obj in $save_oldobjs
 	  do
 	    func_basename "$obj"
-	    objbase=$func_basename_result
+	    objbase="$func_basename_result"
 	    case " $oldobjs " in
 	    " ") oldobjs=$obj ;;
 	    *[\ /]"$objbase "*)
@@ -10718,18 +9221,18 @@ EOF
 	    else
 	      # the above command should be used before it gets too long
 	      oldobjs=$objlist
-	      if test "$obj" = "$last_oldobj"; then
+	      if test "$obj" = "$last_oldobj" ; then
 		RANLIB=$save_RANLIB
 	      fi
 	      test -z "$concat_cmds" || concat_cmds=$concat_cmds~
-	      eval concat_cmds=\"\$concat_cmds$old_archive_cmds\"
+	      eval concat_cmds=\"\${concat_cmds}$old_archive_cmds\"
 	      objlist=
 	      len=$len0
 	    fi
 	  done
 	  RANLIB=$save_RANLIB
 	  oldobjs=$objlist
-	  if test -z "$oldobjs"; then
+	  if test "X$oldobjs" = "X" ; then
 	    eval cmds=\"\$concat_cmds\"
 	  else
 	    eval cmds=\"\$concat_cmds~\$old_archive_cmds\"
@@ -10746,7 +9249,7 @@ EOF
     case $output in
     *.la)
       old_library=
-      test yes = "$build_old_libs" && old_library=$libname.$libext
+      test "$build_old_libs" = yes && old_library="$libname.$libext"
       func_verbose "creating $output"
 
       # Preserve any variables that may affect compiler behavior
@@ -10761,31 +9264,31 @@ EOF
 	fi
       done
       # Quote the link command for shipping.
-      relink_command="(cd `pwd`; $SHELL \"$progpath\" $preserve_args --mode=relink $libtool_args @inst_prefix_dir@)"
+      relink_command="(cd `pwd`; $SHELL $progpath $preserve_args --mode=relink $libtool_args @inst_prefix_dir@)"
       relink_command=`$ECHO "$relink_command" | $SED "$sed_quote_subst"`
-      if test yes = "$hardcode_automatic"; then
+      if test "$hardcode_automatic" = yes ; then
 	relink_command=
       fi
 
       # Only create the output if not a dry run.
       $opt_dry_run || {
 	for installed in no yes; do
-	  if test yes = "$installed"; then
+	  if test "$installed" = yes; then
 	    if test -z "$install_libdir"; then
 	      break
 	    fi
-	    output=$output_objdir/${outputname}i
+	    output="$output_objdir/$outputname"i
 	    # Replace all uninstalled libtool libraries with the installed ones
 	    newdependency_libs=
 	    for deplib in $dependency_libs; do
 	      case $deplib in
 	      *.la)
 		func_basename "$deplib"
-		name=$func_basename_result
+		name="$func_basename_result"
 		func_resolve_sysroot "$deplib"
-		eval libdir=`$SED -n -e 's/^libdir=\(.*\)$/\1/p' $func_resolve_sysroot_result`
+		eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $func_resolve_sysroot_result`
 		test -z "$libdir" && \
-		  func_fatal_error "'$deplib' is not a valid libtool archive"
+		  func_fatal_error "\`$deplib' is not a valid libtool archive"
 		func_append newdependency_libs " ${lt_sysroot:+=}$libdir/$name"
 		;;
 	      -L*)
@@ -10801,23 +9304,23 @@ EOF
 	      *) func_append newdependency_libs " $deplib" ;;
 	      esac
 	    done
-	    dependency_libs=$newdependency_libs
+	    dependency_libs="$newdependency_libs"
 	    newdlfiles=
 
 	    for lib in $dlfiles; do
 	      case $lib in
 	      *.la)
 	        func_basename "$lib"
-		name=$func_basename_result
-		eval libdir=`$SED -n -e 's/^libdir=\(.*\)$/\1/p' $lib`
+		name="$func_basename_result"
+		eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib`
 		test -z "$libdir" && \
-		  func_fatal_error "'$lib' is not a valid libtool archive"
+		  func_fatal_error "\`$lib' is not a valid libtool archive"
 		func_append newdlfiles " ${lt_sysroot:+=}$libdir/$name"
 		;;
 	      *) func_append newdlfiles " $lib" ;;
 	      esac
 	    done
-	    dlfiles=$newdlfiles
+	    dlfiles="$newdlfiles"
 	    newdlprefiles=
 	    for lib in $dlprefiles; do
 	      case $lib in
@@ -10827,34 +9330,34 @@ EOF
 		# didn't already link the preopened objects directly into
 		# the library:
 		func_basename "$lib"
-		name=$func_basename_result
-		eval libdir=`$SED -n -e 's/^libdir=\(.*\)$/\1/p' $lib`
+		name="$func_basename_result"
+		eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib`
 		test -z "$libdir" && \
-		  func_fatal_error "'$lib' is not a valid libtool archive"
+		  func_fatal_error "\`$lib' is not a valid libtool archive"
 		func_append newdlprefiles " ${lt_sysroot:+=}$libdir/$name"
 		;;
 	      esac
 	    done
-	    dlprefiles=$newdlprefiles
+	    dlprefiles="$newdlprefiles"
 	  else
 	    newdlfiles=
 	    for lib in $dlfiles; do
 	      case $lib in
-		[\\/]* | [A-Za-z]:[\\/]*) abs=$lib ;;
+		[\\/]* | [A-Za-z]:[\\/]*) abs="$lib" ;;
 		*) abs=`pwd`"/$lib" ;;
 	      esac
 	      func_append newdlfiles " $abs"
 	    done
-	    dlfiles=$newdlfiles
+	    dlfiles="$newdlfiles"
 	    newdlprefiles=
 	    for lib in $dlprefiles; do
 	      case $lib in
-		[\\/]* | [A-Za-z]:[\\/]*) abs=$lib ;;
+		[\\/]* | [A-Za-z]:[\\/]*) abs="$lib" ;;
 		*) abs=`pwd`"/$lib" ;;
 	      esac
 	      func_append newdlprefiles " $abs"
 	    done
-	    dlprefiles=$newdlprefiles
+	    dlprefiles="$newdlprefiles"
 	  fi
 	  $RM $output
 	  # place dlname in correct position for cygwin
@@ -10870,9 +9373,10 @@ EOF
 	  case $host,$output,$installed,$module,$dlname in
 	    *cygwin*,*lai,yes,no,*.dll | *mingw*,*lai,yes,no,*.dll | *cegcc*,*lai,yes,no,*.dll)
 	      # If a -bindir argument was supplied, place the dll there.
-	      if test -n "$bindir"; then
+	      if test "x$bindir" != x ;
+	      then
 		func_relative_path "$install_libdir" "$bindir"
-		tdlname=$func_relative_path_result/$dlname
+		tdlname=$func_relative_path_result$dlname
 	      else
 		# Otherwise fall back on heuristic.
 		tdlname=../bin/$dlname
@@ -10881,7 +9385,7 @@ EOF
 	  esac
 	  $ECHO > $output "\
 # $outputname - a libtool library file
-# Generated by $PROGRAM (GNU $PACKAGE) $VERSION
+# Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION
 #
 # Please DO NOT delete this file!
 # It is necessary for linking the library.
@@ -10895,7 +9399,7 @@ library_names='$library_names'
 # The name of the static archive.
 old_library='$old_library'
 
-# Linker flags that cannot go in dependency_libs.
+# Linker flags that can not go in dependency_libs.
 inherited_linker_flags='$new_inherited_linker_flags'
 
 # Libraries that this one depends upon.
@@ -10921,7 +9425,7 @@ dlpreopen='$dlprefiles'
 
 # Directory that this library needs to be installed in:
 libdir='$install_libdir'"
-	  if test no,yes = "$installed,$need_relink"; then
+	  if test "$installed" = no && test "$need_relink" = yes; then
 	    $ECHO >> $output "\
 relink_command=\"$relink_command\""
 	  fi
@@ -10936,29 +9440,27 @@ relink_command=\"$relink_command\""
     exit $EXIT_SUCCESS
 }
 
-if test link = "$opt_mode" || test relink = "$opt_mode"; then
-  func_mode_link ${1+"$@"}
-fi
+{ test "$opt_mode" = link || test "$opt_mode" = relink; } &&
+    func_mode_link ${1+"$@"}
 
 
 # func_mode_uninstall arg...
 func_mode_uninstall ()
 {
-    $debug_cmd
-
-    RM=$nonopt
+    $opt_debug
+    RM="$nonopt"
     files=
-    rmforce=false
+    rmforce=
     exit_status=0
 
     # This variable tells wrapper scripts just to set variables rather
     # than running their programs.
-    libtool_install_magic=$magic
+    libtool_install_magic="$magic"
 
     for arg
     do
       case $arg in
-      -f) func_append RM " $arg"; rmforce=: ;;
+      -f) func_append RM " $arg"; rmforce=yes ;;
       -*) func_append RM " $arg" ;;
       *) func_append files " $arg" ;;
       esac
@@ -10971,18 +9473,18 @@ func_mode_uninstall ()
 
     for file in $files; do
       func_dirname "$file" "" "."
-      dir=$func_dirname_result
-      if test . = "$dir"; then
-	odir=$objdir
+      dir="$func_dirname_result"
+      if test "X$dir" = X.; then
+	odir="$objdir"
       else
-	odir=$dir/$objdir
+	odir="$dir/$objdir"
       fi
       func_basename "$file"
-      name=$func_basename_result
-      test uninstall = "$opt_mode" && odir=$dir
+      name="$func_basename_result"
+      test "$opt_mode" = uninstall && odir="$dir"
 
       # Remember odir for removal later, being careful to avoid duplicates
-      if test clean = "$opt_mode"; then
+      if test "$opt_mode" = clean; then
 	case " $rmdirs " in
 	  *" $odir "*) ;;
 	  *) func_append rmdirs " $odir" ;;
@@ -10997,11 +9499,11 @@ func_mode_uninstall ()
       elif test -d "$file"; then
 	exit_status=1
 	continue
-      elif $rmforce; then
+      elif test "$rmforce" = yes; then
 	continue
       fi
 
-      rmfiles=$file
+      rmfiles="$file"
 
       case $name in
       *.la)
@@ -11015,7 +9517,7 @@ func_mode_uninstall ()
 	  done
 	  test -n "$old_library" && func_append rmfiles " $odir/$old_library"
 
-	  case $opt_mode in
+	  case "$opt_mode" in
 	  clean)
 	    case " $library_names " in
 	    *" $dlname "*) ;;
@@ -11026,12 +9528,12 @@ func_mode_uninstall ()
 	  uninstall)
 	    if test -n "$library_names"; then
 	      # Do each command in the postuninstall commands.
-	      func_execute_cmds "$postuninstall_cmds" '$rmforce || exit_status=1'
+	      func_execute_cmds "$postuninstall_cmds" 'test "$rmforce" = yes || exit_status=1'
 	    fi
 
 	    if test -n "$old_library"; then
 	      # Do each command in the old_postuninstall commands.
-	      func_execute_cmds "$old_postuninstall_cmds" '$rmforce || exit_status=1'
+	      func_execute_cmds "$old_postuninstall_cmds" 'test "$rmforce" = yes || exit_status=1'
 	    fi
 	    # FIXME: should reinstall the best remaining shared library.
 	    ;;
@@ -11047,19 +9549,21 @@ func_mode_uninstall ()
 	  func_source $dir/$name
 
 	  # Add PIC object to the list of files to remove.
-	  if test -n "$pic_object" && test none != "$pic_object"; then
+	  if test -n "$pic_object" &&
+	     test "$pic_object" != none; then
 	    func_append rmfiles " $dir/$pic_object"
 	  fi
 
 	  # Add non-PIC object to the list of files to remove.
-	  if test -n "$non_pic_object" && test none != "$non_pic_object"; then
+	  if test -n "$non_pic_object" &&
+	     test "$non_pic_object" != none; then
 	    func_append rmfiles " $dir/$non_pic_object"
 	  fi
 	fi
 	;;
 
       *)
-	if test clean = "$opt_mode"; then
+	if test "$opt_mode" = clean ; then
 	  noexename=$name
 	  case $file in
 	  *.exe)
@@ -11086,12 +9590,12 @@ func_mode_uninstall ()
 
 	    # note $name still contains .exe if it was in $file originally
 	    # as does the version of $file that was added into $rmfiles
-	    func_append rmfiles " $odir/$name $odir/${name}S.$objext"
-	    if test yes = "$fast_install" && test -n "$relink_command"; then
+	    func_append rmfiles " $odir/$name $odir/${name}S.${objext}"
+	    if test "$fast_install" = yes && test -n "$relink_command"; then
 	      func_append rmfiles " $odir/lt-$name"
 	    fi
-	    if test "X$noexename" != "X$name"; then
-	      func_append rmfiles " $odir/lt-$noexename.c"
+	    if test "X$noexename" != "X$name" ; then
+	      func_append rmfiles " $odir/lt-${noexename}.c"
 	    fi
 	  fi
 	fi
@@ -11100,7 +9604,7 @@ func_mode_uninstall ()
       func_show_eval "$RM $rmfiles" 'exit_status=1'
     done
 
-    # Try to remove the $objdir's in the directories where we deleted files
+    # Try to remove the ${objdir}s in the directories where we deleted files
     for dir in $rmdirs; do
       if test -d "$dir"; then
 	func_show_eval "rmdir $dir >/dev/null 2>&1"
@@ -11110,17 +9614,16 @@ func_mode_uninstall ()
     exit $exit_status
 }
 
-if test uninstall = "$opt_mode" || test clean = "$opt_mode"; then
-  func_mode_uninstall ${1+"$@"}
-fi
+{ test "$opt_mode" = uninstall || test "$opt_mode" = clean; } &&
+    func_mode_uninstall ${1+"$@"}
 
 test -z "$opt_mode" && {
-  help=$generic_help
+  help="$generic_help"
   func_fatal_help "you must specify a MODE"
 }
 
 test -z "$exec_cmd" && \
-  func_fatal_help "invalid operation mode '$opt_mode'"
+  func_fatal_help "invalid operation mode \`$opt_mode'"
 
 if test -n "$exec_cmd"; then
   eval exec "$exec_cmd"
@@ -11131,7 +9634,7 @@ exit $exit_status
 
 
 # The TAGs below are defined such that we never get into a situation
-# where we disable both kinds of libraries.  Given conflicting
+# in which we disable both kinds of libraries.  Given conflicting
 # choices, we go for a static library, that is the most portable,
 # since we can't tell whether shared libraries were disabled because
 # the user asked for that or because the platform doesn't support
@@ -11154,3 +9657,5 @@ build_old_libs=`case $build_libtool_libs in yes) echo no;; *) echo yes;; esac`
 # mode:shell-script
 # sh-indentation:2
 # End:
+# vi:sw=2
+
diff --git a/src/gmock/build-aux/missing b/src/gmock/build-aux/missing
index f62bbae..db98974 100755
--- a/src/gmock/build-aux/missing
+++ b/src/gmock/build-aux/missing
@@ -3,7 +3,7 @@
 
 scriptversion=2013-10-28.13; # UTC
 
-# Copyright (C) 1996-2014 Free Software Foundation, Inc.
+# Copyright (C) 1996-2013 Free Software Foundation, Inc.
 # Originally written by Fran,cois Pinard <pinard at iro.umontreal.ca>, 1996.
 
 # This program is free software; you can redistribute it and/or modify
diff --git a/src/gmock/build-aux/test-driver b/src/gmock/build-aux/test-driver
index 8e575b0..d306056 100755
--- a/src/gmock/build-aux/test-driver
+++ b/src/gmock/build-aux/test-driver
@@ -3,7 +3,7 @@
 
 scriptversion=2013-07-13.22; # UTC
 
-# Copyright (C) 2011-2014 Free Software Foundation, Inc.
+# Copyright (C) 2011-2013 Free Software Foundation, Inc.
 #
 # This program is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
@@ -106,14 +106,11 @@ trap "st=143; $do_exit" 15
 # Test script is run here.
 "$@" >$log_file 2>&1
 estatus=$?
-
 if test $enable_hard_errors = no && test $estatus -eq 99; then
-  tweaked_estatus=1
-else
-  tweaked_estatus=$estatus
+  estatus=1
 fi
 
-case $tweaked_estatus:$expect_failure in
+case $estatus:$expect_failure in
   0:yes) col=$red res=XPASS recheck=yes gcopy=yes;;
   0:*)   col=$grn res=PASS  recheck=no  gcopy=no;;
   77:*)  col=$blu res=SKIP  recheck=no  gcopy=yes;;
@@ -122,12 +119,6 @@ case $tweaked_estatus:$expect_failure in
   *:*)   col=$red res=FAIL  recheck=yes gcopy=yes;;
 esac
 
-# Report the test outcome and exit status in the logs, so that one can
-# know whether the test passed or failed simply by looking at the '.log'
-# file, without the need of also peaking into the corresponding '.trs'
-# file (automake bug#11814).
-echo "$res $test_name (exit status: $estatus)" >>$log_file
-
 # Report outcome to console.
 echo "${col}${res}${std}: $test_name"
 
diff --git a/src/gmock/configure b/src/gmock/configure
index be52680..04e603a 100755
--- a/src/gmock/configure
+++ b/src/gmock/configure
@@ -655,7 +655,6 @@ HAVE_PYTHON_TRUE
 PYTHON
 CXXCPP
 CPP
-LT_SYS_LIBRARY_PATH
 OTOOL64
 OTOOL
 LIPO
@@ -754,7 +753,6 @@ infodir
 docdir
 oldincludedir
 includedir
-runstatedir
 localstatedir
 sharedstatedir
 sysconfdir
@@ -783,7 +781,6 @@ enable_shared
 enable_static
 with_pic
 enable_fast_install
-with_aix_soname
 with_gnu_ld
 with_sysroot
 enable_libtool_lock
@@ -802,7 +799,6 @@ CPPFLAGS
 CXX
 CXXFLAGS
 CCC
-LT_SYS_LIBRARY_PATH
 CPP
 CXXCPP
 GTEST_CONFIG
@@ -849,7 +845,6 @@ datadir='${datarootdir}'
 sysconfdir='${prefix}/etc'
 sharedstatedir='${prefix}/com'
 localstatedir='${prefix}/var'
-runstatedir='${localstatedir}/run'
 includedir='${prefix}/include'
 oldincludedir='/usr/include'
 docdir='${datarootdir}/doc/${PACKAGE_TARNAME}'
@@ -1102,15 +1097,6 @@ do
   | -silent | --silent | --silen | --sile | --sil)
     silent=yes ;;
 
-  -runstatedir | --runstatedir | --runstatedi | --runstated \
-  | --runstate | --runstat | --runsta | --runst | --runs \
-  | --run | --ru | --r)
-    ac_prev=runstatedir ;;
-  -runstatedir=* | --runstatedir=* | --runstatedi=* | --runstated=* \
-  | --runstate=* | --runstat=* | --runsta=* | --runst=* | --runs=* \
-  | --run=* | --ru=* | --r=*)
-    runstatedir=$ac_optarg ;;
-
   -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
     ac_prev=sbindir ;;
   -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
@@ -1248,7 +1234,7 @@ fi
 for ac_var in	exec_prefix prefix bindir sbindir libexecdir datarootdir \
 		datadir sysconfdir sharedstatedir localstatedir includedir \
 		oldincludedir docdir infodir htmldir dvidir pdfdir psdir \
-		libdir localedir mandir runstatedir
+		libdir localedir mandir
 do
   eval ac_val=\$$ac_var
   # Remove trailing slashes.
@@ -1401,7 +1387,6 @@ Fine tuning of the installation directories:
   --sysconfdir=DIR        read-only single-machine data [PREFIX/etc]
   --sharedstatedir=DIR    modifiable architecture-independent data [PREFIX/com]
   --localstatedir=DIR     modifiable single-machine data [PREFIX/var]
-  --runstatedir=DIR       modifiable per-process data [LOCALSTATEDIR/run]
   --libdir=DIR            object code libraries [EPREFIX/lib]
   --includedir=DIR        C header files [PREFIX/include]
   --oldincludedir=DIR     C header files for non-gcc [/usr/include]
@@ -1462,12 +1447,9 @@ Optional Packages:
   --without-PACKAGE       do not use PACKAGE (same as --with-PACKAGE=no)
   --with-pic[=PKGS]       try to use only PIC/non-PIC objects [default=use
                           both]
-  --with-aix-soname=aix|svr4|both
-                          shared library versioning (aka "SONAME") variant to
-                          provide on AIX, [default=aix].
   --with-gnu-ld           assume the C compiler uses GNU ld [default=no]
-  --with-sysroot[=DIR]    Search for dependent libraries within DIR (or the
-                          compiler's sysroot if not specified).
+  --with-sysroot=DIR Search for dependent libraries within DIR
+                        (or the compiler's sysroot if not specified).
   --with-pthreads         use pthreads (default is yes)
   --with-gtest            Specifies how to find the gtest package. If no
                           arguments are given, the default behavior, a system
@@ -1486,8 +1468,6 @@ Some influential environment variables:
               you have headers in a nonstandard directory <include dir>
   CXX         C++ compiler command
   CXXFLAGS    C++ compiler flags
-  LT_SYS_LIBRARY_PATH
-              User-defined run-time library search path.
   CPP         C preprocessor
   CXXCPP      C++ preprocessor
   GTEST_CONFIG
@@ -2358,7 +2338,7 @@ ac_config_files="$ac_config_files scripts/gmock-config"
 # Initialize Automake with various options. We require at least v1.9, prevent
 # pedantic complaints about package files, and enable various distribution
 # targets.
-am__api_version='1.15'
+am__api_version='1.14'
 
 # Find a good install program.  We prefer a C program (faster),
 # so one script is as good as another.  But avoid the broken or
@@ -2530,8 +2510,8 @@ test "$program_suffix" != NONE &&
 ac_script='s/[\\$]/&&/g;s/;s,x,x,$//'
 program_transform_name=`$as_echo "$program_transform_name" | sed "$ac_script"`
 
-# Expand $ac_aux_dir to an absolute path.
-am_aux_dir=`cd "$ac_aux_dir" && pwd`
+# expand $ac_aux_dir to an absolute path
+am_aux_dir=`cd $ac_aux_dir && pwd`
 
 if test x"${MISSING+set}" != xset; then
   case $am_aux_dir in
@@ -2550,7 +2530,7 @@ else
 $as_echo "$as_me: WARNING: 'missing' script is too old or missing" >&2;}
 fi
 
-if test x"${install_sh+set}" != xset; then
+if test x"${install_sh}" != xset; then
   case $am_aux_dir in
   *\ * | *\	*)
     install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;;
@@ -2878,8 +2858,8 @@ MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"}
 # <http://lists.gnu.org/archive/html/automake/2012-07/msg00014.html>
 mkdir_p='$(MKDIR_P)'
 
-# We need awk for the "check" target (and possibly the TAP driver).  The
-# system "awk" is bad on some platforms.
+# We need awk for the "check" target.  The system "awk" is bad on
+# some platforms.
 # Always define AMTAR for backward compatibility.  Yes, it's still used
 # in the wild :-(  We should find a proper way to deprecate it ...
 AMTAR='$${TAR-tar}'
@@ -2937,7 +2917,6 @@ END
   fi
 fi
 
-
 # Check for programs used in building Google Test.
 ac_ext=c
 ac_cpp='$CPP $CPPFLAGS'
@@ -4377,8 +4356,8 @@ esac
 
 
 
-macro_version='2.4.6'
-macro_revision='2.4.6'
+macro_version='2.4.2'
+macro_revision='1.3337'
 
 
 
@@ -4392,7 +4371,7 @@ macro_revision='2.4.6'
 
 
 
-ltmain=$ac_aux_dir/ltmain.sh
+ltmain="$ac_aux_dir/ltmain.sh"
 
 # Make sure we can run config.sub.
 $SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 ||
@@ -4512,7 +4491,7 @@ func_echo_all ()
     $ECHO ""
 }
 
-case $ECHO in
+case "$ECHO" in
   printf*) { $as_echo "$as_me:${as_lineno-$LINENO}: result: printf" >&5
 $as_echo "printf" >&6; } ;;
   print*) { $as_echo "$as_me:${as_lineno-$LINENO}: result: print -r" >&5
@@ -4835,19 +4814,19 @@ test -z "$GREP" && GREP=grep
 
 # Check whether --with-gnu-ld was given.
 if test "${with_gnu_ld+set}" = set; then :
-  withval=$with_gnu_ld; test no = "$withval" || with_gnu_ld=yes
+  withval=$with_gnu_ld; test "$withval" = no || with_gnu_ld=yes
 else
   with_gnu_ld=no
 fi
 
 ac_prog=ld
-if test yes = "$GCC"; then
+if test "$GCC" = yes; then
   # Check if gcc -print-prog-name=ld gives a path.
   { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ld used by $CC" >&5
 $as_echo_n "checking for ld used by $CC... " >&6; }
   case $host in
   *-*-mingw*)
-    # gcc leaves a trailing carriage return, which upsets mingw
+    # gcc leaves a trailing carriage return which upsets mingw
     ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;;
   *)
     ac_prog=`($CC -print-prog-name=ld) 2>&5` ;;
@@ -4861,7 +4840,7 @@ $as_echo_n "checking for ld used by $CC... " >&6; }
       while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do
 	ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"`
       done
-      test -z "$LD" && LD=$ac_prog
+      test -z "$LD" && LD="$ac_prog"
       ;;
   "")
     # If it fails, then pretend we aren't using GCC.
@@ -4872,7 +4851,7 @@ $as_echo_n "checking for ld used by $CC... " >&6; }
     with_gnu_ld=unknown
     ;;
   esac
-elif test yes = "$with_gnu_ld"; then
+elif test "$with_gnu_ld" = yes; then
   { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU ld" >&5
 $as_echo_n "checking for GNU ld... " >&6; }
 else
@@ -4883,32 +4862,32 @@ if ${lt_cv_path_LD+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   if test -z "$LD"; then
-  lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR
+  lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
   for ac_dir in $PATH; do
-    IFS=$lt_save_ifs
+    IFS="$lt_save_ifs"
     test -z "$ac_dir" && ac_dir=.
     if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then
-      lt_cv_path_LD=$ac_dir/$ac_prog
+      lt_cv_path_LD="$ac_dir/$ac_prog"
       # Check to see if the program is GNU ld.  I'd rather use --version,
       # but apparently some variants of GNU ld only accept -v.
       # Break only if it was the GNU/non-GNU ld that we prefer.
       case `"$lt_cv_path_LD" -v 2>&1 </dev/null` in
       *GNU* | *'with BFD'*)
-	test no != "$with_gnu_ld" && break
+	test "$with_gnu_ld" != no && break
 	;;
       *)
-	test yes != "$with_gnu_ld" && break
+	test "$with_gnu_ld" != yes && break
 	;;
       esac
     fi
   done
-  IFS=$lt_save_ifs
+  IFS="$lt_save_ifs"
 else
-  lt_cv_path_LD=$LD # Let the user override the test with a path.
+  lt_cv_path_LD="$LD" # Let the user override the test with a path.
 fi
 fi
 
-LD=$lt_cv_path_LD
+LD="$lt_cv_path_LD"
 if test -n "$LD"; then
   { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LD" >&5
 $as_echo "$LD" >&6; }
@@ -4951,38 +4930,33 @@ if ${lt_cv_path_NM+:} false; then :
 else
   if test -n "$NM"; then
   # Let the user override the test.
-  lt_cv_path_NM=$NM
+  lt_cv_path_NM="$NM"
 else
-  lt_nm_to_check=${ac_tool_prefix}nm
+  lt_nm_to_check="${ac_tool_prefix}nm"
   if test -n "$ac_tool_prefix" && test "$build" = "$host"; then
     lt_nm_to_check="$lt_nm_to_check nm"
   fi
   for lt_tmp_nm in $lt_nm_to_check; do
-    lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR
+    lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
     for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do
-      IFS=$lt_save_ifs
+      IFS="$lt_save_ifs"
       test -z "$ac_dir" && ac_dir=.
-      tmp_nm=$ac_dir/$lt_tmp_nm
-      if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext"; then
+      tmp_nm="$ac_dir/$lt_tmp_nm"
+      if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext" ; then
 	# Check to see if the nm accepts a BSD-compat flag.
-	# Adding the 'sed 1q' prevents false positives on HP-UX, which says:
+	# Adding the `sed 1q' prevents false positives on HP-UX, which says:
 	#   nm: unknown option "B" ignored
 	# Tru64's nm complains that /dev/null is an invalid object file
-	# MSYS converts /dev/null to NUL, MinGW nm treats NUL as empty
-	case $build_os in
-	mingw*) lt_bad_file=conftest.nm/nofile ;;
-	*) lt_bad_file=/dev/null ;;
-	esac
-	case `"$tmp_nm" -B $lt_bad_file 2>&1 | sed '1q'` in
-	*$lt_bad_file* | *'Invalid file or object type'*)
+	case `"$tmp_nm" -B /dev/null 2>&1 | sed '1q'` in
+	*/dev/null* | *'Invalid file or object type'*)
 	  lt_cv_path_NM="$tmp_nm -B"
-	  break 2
+	  break
 	  ;;
 	*)
 	  case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in
 	  */dev/null*)
 	    lt_cv_path_NM="$tmp_nm -p"
-	    break 2
+	    break
 	    ;;
 	  *)
 	    lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but
@@ -4993,15 +4967,15 @@ else
 	esac
       fi
     done
-    IFS=$lt_save_ifs
+    IFS="$lt_save_ifs"
   done
   : ${lt_cv_path_NM=no}
 fi
 fi
 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_NM" >&5
 $as_echo "$lt_cv_path_NM" >&6; }
-if test no != "$lt_cv_path_NM"; then
-  NM=$lt_cv_path_NM
+if test "$lt_cv_path_NM" != "no"; then
+  NM="$lt_cv_path_NM"
 else
   # Didn't find any BSD compatible name lister, look for dumpbin.
   if test -n "$DUMPBIN"; then :
@@ -5107,9 +5081,9 @@ esac
   fi
 fi
 
-    case `$DUMPBIN -symbols -headers /dev/null 2>&1 | sed '1q'` in
+    case `$DUMPBIN -symbols /dev/null 2>&1 | sed '1q'` in
     *COFF*)
-      DUMPBIN="$DUMPBIN -symbols -headers"
+      DUMPBIN="$DUMPBIN -symbols"
       ;;
     *)
       DUMPBIN=:
@@ -5117,8 +5091,8 @@ fi
     esac
   fi
 
-  if test : != "$DUMPBIN"; then
-    NM=$DUMPBIN
+  if test "$DUMPBIN" != ":"; then
+    NM="$DUMPBIN"
   fi
 fi
 test -z "$NM" && NM=nm
@@ -5169,7 +5143,7 @@ if ${lt_cv_sys_max_cmd_len+:} false; then :
   $as_echo_n "(cached) " >&6
 else
     i=0
-  teststring=ABCD
+  teststring="ABCD"
 
   case $build_os in
   msdosdjgpp*)
@@ -5209,7 +5183,7 @@ else
     lt_cv_sys_max_cmd_len=8192;
     ;;
 
-  bitrig* | darwin* | dragonfly* | freebsd* | netbsd* | openbsd*)
+  netbsd* | freebsd* | openbsd* | darwin* | dragonfly*)
     # This has been around since 386BSD, at least.  Likely further.
     if test -x /sbin/sysctl; then
       lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax`
@@ -5260,22 +5234,22 @@ else
   *)
     lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null`
     if test -n "$lt_cv_sys_max_cmd_len" && \
-       test undefined != "$lt_cv_sys_max_cmd_len"; then
+	test undefined != "$lt_cv_sys_max_cmd_len"; then
       lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4`
       lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3`
     else
       # Make teststring a little bigger before we do anything with it.
       # a 1K string should be a reasonable start.
-      for i in 1 2 3 4 5 6 7 8; do
+      for i in 1 2 3 4 5 6 7 8 ; do
         teststring=$teststring$teststring
       done
       SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}}
       # If test is not a shell built-in, we'll probably end up computing a
       # maximum length that is only half of the actual maximum length, but
       # we can't tell.
-      while { test X`env echo "$teststring$teststring" 2>/dev/null` \
+      while { test "X"`env echo "$teststring$teststring" 2>/dev/null` \
 	         = "X$teststring$teststring"; } >/dev/null 2>&1 &&
-	      test 17 != "$i" # 1/2 MB should be enough
+	      test $i != 17 # 1/2 MB should be enough
       do
         i=`expr $i + 1`
         teststring=$teststring$teststring
@@ -5293,7 +5267,7 @@ else
 
 fi
 
-if test -n "$lt_cv_sys_max_cmd_len"; then
+if test -n $lt_cv_sys_max_cmd_len ; then
   { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_sys_max_cmd_len" >&5
 $as_echo "$lt_cv_sys_max_cmd_len" >&6; }
 else
@@ -5311,6 +5285,30 @@ max_cmd_len=$lt_cv_sys_max_cmd_len
 : ${MV="mv -f"}
 : ${RM="rm -f"}
 
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the shell understands some XSI constructs" >&5
+$as_echo_n "checking whether the shell understands some XSI constructs... " >&6; }
+# Try some XSI features
+xsi_shell=no
+( _lt_dummy="a/b/c"
+  test "${_lt_dummy##*/},${_lt_dummy%/*},${_lt_dummy#??}"${_lt_dummy%"$_lt_dummy"}, \
+      = c,a/b,b/c, \
+    && eval 'test $(( 1 + 1 )) -eq 2 \
+    && test "${#_lt_dummy}" -eq 5' ) >/dev/null 2>&1 \
+  && xsi_shell=yes
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $xsi_shell" >&5
+$as_echo "$xsi_shell" >&6; }
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the shell understands \"+=\"" >&5
+$as_echo_n "checking whether the shell understands \"+=\"... " >&6; }
+lt_shell_append=no
+( foo=bar; set foo baz; eval "$1+=\$2" && test "$foo" = barbaz ) \
+    >/dev/null 2>&1 \
+  && lt_shell_append=yes
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_shell_append" >&5
+$as_echo "$lt_shell_append" >&6; }
+
+
 if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then
   lt_unset=unset
 else
@@ -5433,13 +5431,13 @@ esac
 reload_cmds='$LD$reload_flag -o $output$reload_objs'
 case $host_os in
   cygwin* | mingw* | pw32* | cegcc*)
-    if test yes != "$GCC"; then
+    if test "$GCC" != yes; then
       reload_cmds=false
     fi
     ;;
   darwin*)
-    if test yes = "$GCC"; then
-      reload_cmds='$LTCC $LTCFLAGS -nostdlib $wl-r -o $output$reload_objs'
+    if test "$GCC" = yes; then
+      reload_cmds='$LTCC $LTCFLAGS -nostdlib ${wl}-r -o $output$reload_objs'
     else
       reload_cmds='$LD$reload_flag -o $output$reload_objs'
     fi
@@ -5567,13 +5565,13 @@ lt_cv_deplibs_check_method='unknown'
 # Need to set the preceding variable on all platforms that support
 # interlibrary dependencies.
 # 'none' -- dependencies not supported.
-# 'unknown' -- same as none, but documents that we really don't know.
+# `unknown' -- same as none, but documents that we really don't know.
 # 'pass_all' -- all dependencies passed with no checks.
 # 'test_compile' -- check by making test program.
 # 'file_magic [[regex]]' -- check by looking for files in library path
-# that responds to the $file_magic_cmd with a given extended regex.
-# If you have 'file' or equivalent on your system and you're not sure
-# whether 'pass_all' will *always* work, you probably want this one.
+# which responds to the $file_magic_cmd with a given extended regex.
+# If you have `file' or equivalent on your system and you're not sure
+# whether `pass_all' will *always* work, you probably want this one.
 
 case $host_os in
 aix[4-9]*)
@@ -5600,7 +5598,8 @@ mingw* | pw32*)
   # Base MSYS/MinGW do not provide the 'file' command needed by
   # func_win32_libid shell function, so use a weaker test based on 'objdump',
   # unless we find 'file', for example because we are cross-compiling.
-  if ( file / ) >/dev/null 2>&1; then
+  # func_win32_libid assumes BSD nm, so disallow it if using MS dumpbin.
+  if ( test "$lt_cv_nm_interface" = "BSD nm" && file / ) >/dev/null 2>&1; then
     lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL'
     lt_cv_file_magic_cmd='func_win32_libid'
   else
@@ -5696,8 +5695,8 @@ newos6*)
   lt_cv_deplibs_check_method=pass_all
   ;;
 
-openbsd* | bitrig*)
-  if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then
+openbsd*)
+  if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
     lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|\.so|_pic\.a)$'
   else
     lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$'
@@ -5750,9 +5749,6 @@ sysv4 | sysv4.3*)
 tpf*)
   lt_cv_deplibs_check_method=pass_all
   ;;
-os2*)
-  lt_cv_deplibs_check_method=pass_all
-  ;;
 esac
 
 fi
@@ -5910,8 +5906,8 @@ else
 
 case $host_os in
 cygwin* | mingw* | pw32* | cegcc*)
-  # two different shell functions defined in ltmain.sh;
-  # decide which one to use based on capabilities of $DLLTOOL
+  # two different shell functions defined in ltmain.sh
+  # decide which to use based on capabilities of $DLLTOOL
   case `$DLLTOOL --help 2>&1` in
   *--identify-strict*)
     lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib
@@ -5923,7 +5919,7 @@ cygwin* | mingw* | pw32* | cegcc*)
   ;;
 *)
   # fallback: assume linklib IS sharedlib
-  lt_cv_sharedlib_from_linklib_cmd=$ECHO
+  lt_cv_sharedlib_from_linklib_cmd="$ECHO"
   ;;
 esac
 
@@ -6078,7 +6074,7 @@ if ac_fn_cxx_try_compile "$LINENO"; then :
   ac_status=$?
   $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
   test $ac_status = 0; }
-      if test 0 -eq "$ac_status"; then
+      if test "$ac_status" -eq 0; then
 	# Ensure the archiver fails upon bogus file names.
 	rm -f conftest.$ac_objext libconftest.a
 	{ { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$lt_ar_try\""; } >&5
@@ -6086,7 +6082,7 @@ if ac_fn_cxx_try_compile "$LINENO"; then :
   ac_status=$?
   $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
   test $ac_status = 0; }
-	if test 0 -ne "$ac_status"; then
+	if test "$ac_status" -ne 0; then
           lt_cv_ar_at_file=@
         fi
       fi
@@ -6099,7 +6095,7 @@ fi
 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ar_at_file" >&5
 $as_echo "$lt_cv_ar_at_file" >&6; }
 
-if test no = "$lt_cv_ar_at_file"; then
+if test "x$lt_cv_ar_at_file" = xno; then
   archiver_list_spec=
 else
   archiver_list_spec=$lt_cv_ar_at_file
@@ -6316,7 +6312,7 @@ old_postuninstall_cmds=
 
 if test -n "$RANLIB"; then
   case $host_os in
-  bitrig* | openbsd*)
+  openbsd*)
     old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$tool_oldlib"
     ;;
   *)
@@ -6406,7 +6402,7 @@ cygwin* | mingw* | pw32* | cegcc*)
   symcode='[ABCDGISTW]'
   ;;
 hpux*)
-  if test ia64 = "$host_cpu"; then
+  if test "$host_cpu" = ia64; then
     symcode='[ABCDEGRST]'
   fi
   ;;
@@ -6439,44 +6435,14 @@ case `$NM -V 2>&1` in
   symcode='[ABCDGIRSTW]' ;;
 esac
 
-if test "$lt_cv_nm_interface" = "MS dumpbin"; then
-  # Gets list of data symbols to import.
-  lt_cv_sys_global_symbol_to_import="sed -n -e 's/^I .* \(.*\)$/\1/p'"
-  # Adjust the below global symbol transforms to fixup imported variables.
-  lt_cdecl_hook=" -e 's/^I .* \(.*\)$/extern __declspec(dllimport) char \1;/p'"
-  lt_c_name_hook=" -e 's/^I .* \(.*\)$/  {\"\1\", (void *) 0},/p'"
-  lt_c_name_lib_hook="\
-  -e 's/^I .* \(lib.*\)$/  {\"\1\", (void *) 0},/p'\
-  -e 's/^I .* \(.*\)$/  {\"lib\1\", (void *) 0},/p'"
-else
-  # Disable hooks by default.
-  lt_cv_sys_global_symbol_to_import=
-  lt_cdecl_hook=
-  lt_c_name_hook=
-  lt_c_name_lib_hook=
-fi
-
 # Transform an extracted symbol line into a proper C declaration.
 # Some systems (esp. on ia64) link data and code symbols differently,
 # so use this general approach.
-lt_cv_sys_global_symbol_to_cdecl="sed -n"\
-$lt_cdecl_hook\
-" -e 's/^T .* \(.*\)$/extern int \1();/p'"\
-" -e 's/^$symcode$symcode* .* \(.*\)$/extern char \1;/p'"
+lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'"
 
 # Transform an extracted symbol line into symbol name and symbol address
-lt_cv_sys_global_symbol_to_c_name_address="sed -n"\
-$lt_c_name_hook\
-" -e 's/^: \(.*\) .*$/  {\"\1\", (void *) 0},/p'"\
-" -e 's/^$symcode$symcode* .* \(.*\)$/  {\"\1\", (void *) \&\1},/p'"
-
-# Transform an extracted symbol line into symbol name with lib prefix and
-# symbol address.
-lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n"\
-$lt_c_name_lib_hook\
-" -e 's/^: \(.*\) .*$/  {\"\1\", (void *) 0},/p'"\
-" -e 's/^$symcode$symcode* .* \(lib.*\)$/  {\"\1\", (void *) \&\1},/p'"\
-" -e 's/^$symcode$symcode* .* \(.*\)$/  {\"lib\1\", (void *) \&\1},/p'"
+lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([^ ]*\)[ ]*$/  {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/  {\"\2\", (void *) \&\2},/p'"
+lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n -e 's/^: \([^ ]*\)[ ]*$/  {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([^ ]*\) \(lib[^ ]*\)$/  {\"\2\", (void *) \&\2},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/  {\"lib\2\", (void *) \&\2},/p'"
 
 # Handle CRLF in mingw tool chain
 opt_cr=
@@ -6494,24 +6460,21 @@ for ac_symprfx in "" "_"; do
 
   # Write the raw and C identifiers.
   if test "$lt_cv_nm_interface" = "MS dumpbin"; then
-    # Fake it for dumpbin and say T for any non-static function,
-    # D for any global variable and I for any imported variable.
+    # Fake it for dumpbin and say T for any non-static function
+    # and D for any global variable.
     # Also find C++ and __fastcall symbols from MSVC++,
     # which start with @ or ?.
     lt_cv_sys_global_symbol_pipe="$AWK '"\
 "     {last_section=section; section=\$ 3};"\
 "     /^COFF SYMBOL TABLE/{for(i in hide) delete hide[i]};"\
 "     /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\
-"     /^ *Symbol name *: /{split(\$ 0,sn,\":\"); si=substr(sn[2],2)};"\
-"     /^ *Type *: code/{print \"T\",si,substr(si,length(prfx))};"\
-"     /^ *Type *: data/{print \"I\",si,substr(si,length(prfx))};"\
 "     \$ 0!~/External *\|/{next};"\
 "     / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\
 "     {if(hide[section]) next};"\
-"     {f=\"D\"}; \$ 0~/\(\).*\|/{f=\"T\"};"\
-"     {split(\$ 0,a,/\||\r/); split(a[2],s)};"\
-"     s[1]~/^[@?]/{print f,s[1],s[1]; next};"\
-"     s[1]~prfx {split(s[1],t,\"@\"); print f,t[1],substr(t[1],length(prfx))}"\
+"     {f=0}; \$ 0~/\(\).*\|/{f=1}; {printf f ? \"T \" : \"D \"};"\
+"     {split(\$ 0, a, /\||\r/); split(a[2], s)};"\
+"     s[1]~/^[@?]/{print s[1], s[1]; next};"\
+"     s[1]~prfx {split(s[1],t,\"@\"); print t[1], substr(t[1],length(prfx))}"\
 "     ' prfx=^$ac_symprfx"
   else
     lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[	 ]\($symcode$symcode*\)[	 ][	 ]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'"
@@ -6559,11 +6522,11 @@ _LT_EOF
 	if $GREP ' nm_test_func$' "$nlist" >/dev/null; then
 	  cat <<_LT_EOF > conftest.$ac_ext
 /* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests.  */
-#if defined _WIN32 || defined __CYGWIN__ || defined _WIN32_WCE
-/* DATA imports from DLLs on WIN32 can't be const, because runtime
+#if defined(_WIN32) || defined(__CYGWIN__) || defined(_WIN32_WCE)
+/* DATA imports from DLLs on WIN32 con't be const, because runtime
    relocations are performed -- see ld's documentation on pseudo-relocs.  */
 # define LT_DLSYM_CONST
-#elif defined __osf__
+#elif defined(__osf__)
 /* This system does not cope well with relocations in const data.  */
 # define LT_DLSYM_CONST
 #else
@@ -6589,7 +6552,7 @@ lt__PROGRAM__LTX_preloaded_symbols[] =
 {
   { "@PROGRAM@", (void *) 0 },
 _LT_EOF
-	  $SED "s/^$symcode$symcode* .* \(.*\)$/  {\"\1\", (void *) \&\1},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext
+	  $SED "s/^$symcode$symcode* \(.*\) \(.*\)$/  {\"\2\", (void *) \&\2},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext
 	  cat <<\_LT_EOF >> conftest.$ac_ext
   {0, (void *) 0}
 };
@@ -6609,13 +6572,13 @@ _LT_EOF
 	  mv conftest.$ac_objext conftstm.$ac_objext
 	  lt_globsym_save_LIBS=$LIBS
 	  lt_globsym_save_CFLAGS=$CFLAGS
-	  LIBS=conftstm.$ac_objext
+	  LIBS="conftstm.$ac_objext"
 	  CFLAGS="$CFLAGS$lt_prog_compiler_no_builtin_flag"
 	  if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5
   (eval $ac_link) 2>&5
   ac_status=$?
   $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
-  test $ac_status = 0; } && test -s conftest$ac_exeext; then
+  test $ac_status = 0; } && test -s conftest${ac_exeext}; then
 	    pipe_works=yes
 	  fi
 	  LIBS=$lt_globsym_save_LIBS
@@ -6636,7 +6599,7 @@ _LT_EOF
   rm -rf conftest* conftst*
 
   # Do not use the global_symbol_pipe unless it works.
-  if test yes = "$pipe_works"; then
+  if test "$pipe_works" = yes; then
     break
   else
     lt_cv_sys_global_symbol_pipe=
@@ -6689,16 +6652,6 @@ fi
 
 
 
-
-
-
-
-
-
-
-
-
-
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for sysroot" >&5
 $as_echo_n "checking for sysroot... " >&6; }
 
@@ -6711,9 +6664,9 @@ fi
 
 
 lt_sysroot=
-case $with_sysroot in #(
+case ${with_sysroot} in #(
  yes)
-   if test yes = "$GCC"; then
+   if test "$GCC" = yes; then
      lt_sysroot=`$CC --print-sysroot 2>/dev/null`
    fi
    ;; #(
@@ -6723,8 +6676,8 @@ case $with_sysroot in #(
  no|'')
    ;; #(
  *)
-   { $as_echo "$as_me:${as_lineno-$LINENO}: result: $with_sysroot" >&5
-$as_echo "$with_sysroot" >&6; }
+   { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${with_sysroot}" >&5
+$as_echo "${with_sysroot}" >&6; }
    as_fn_error $? "The sysroot must be an absolute path." "$LINENO" 5
    ;;
 esac
@@ -6736,100 +6689,19 @@ $as_echo "${lt_sysroot:-no}" >&6; }
 
 
 
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a working dd" >&5
-$as_echo_n "checking for a working dd... " >&6; }
-if ${ac_cv_path_lt_DD+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  printf 0123456789abcdef0123456789abcdef >conftest.i
-cat conftest.i conftest.i >conftest2.i
-: ${lt_DD:=$DD}
-if test -z "$lt_DD"; then
-  ac_path_lt_DD_found=false
-  # Loop through the user's path and test for each of PROGNAME-LIST
-  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-    for ac_prog in dd; do
-    for ac_exec_ext in '' $ac_executable_extensions; do
-      ac_path_lt_DD="$as_dir/$ac_prog$ac_exec_ext"
-      as_fn_executable_p "$ac_path_lt_DD" || continue
-if "$ac_path_lt_DD" bs=32 count=1 <conftest2.i >conftest.out 2>/dev/null; then
-  cmp -s conftest.i conftest.out \
-  && ac_cv_path_lt_DD="$ac_path_lt_DD" ac_path_lt_DD_found=:
-fi
-      $ac_path_lt_DD_found && break 3
-    done
-  done
-  done
-IFS=$as_save_IFS
-  if test -z "$ac_cv_path_lt_DD"; then
-    :
-  fi
-else
-  ac_cv_path_lt_DD=$lt_DD
-fi
-
-rm -f conftest.i conftest2.i conftest.out
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_lt_DD" >&5
-$as_echo "$ac_cv_path_lt_DD" >&6; }
-
-
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to truncate binary pipes" >&5
-$as_echo_n "checking how to truncate binary pipes... " >&6; }
-if ${lt_cv_truncate_bin+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  printf 0123456789abcdef0123456789abcdef >conftest.i
-cat conftest.i conftest.i >conftest2.i
-lt_cv_truncate_bin=
-if "$ac_cv_path_lt_DD" bs=32 count=1 <conftest2.i >conftest.out 2>/dev/null; then
-  cmp -s conftest.i conftest.out \
-  && lt_cv_truncate_bin="$ac_cv_path_lt_DD bs=4096 count=1"
-fi
-rm -f conftest.i conftest2.i conftest.out
-test -z "$lt_cv_truncate_bin" && lt_cv_truncate_bin="$SED -e 4q"
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_truncate_bin" >&5
-$as_echo "$lt_cv_truncate_bin" >&6; }
-
-
-
-
-
-
-
-# Calculate cc_basename.  Skip known compiler wrappers and cross-prefix.
-func_cc_basename ()
-{
-    for cc_temp in $*""; do
-      case $cc_temp in
-        compile | *[\\/]compile | ccache | *[\\/]ccache ) ;;
-        distcc | *[\\/]distcc | purify | *[\\/]purify ) ;;
-        \-*) ;;
-        *) break;;
-      esac
-    done
-    func_cc_basename_result=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"`
-}
-
 
 # Check whether --enable-libtool-lock was given.
 if test "${enable_libtool_lock+set}" = set; then :
   enableval=$enable_libtool_lock;
 fi
 
-test no = "$enable_libtool_lock" || enable_libtool_lock=yes
+test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes
 
 # Some flags need to be propagated to the compiler or linker for good
 # libtool support.
 case $host in
 ia64-*-hpux*)
-  # Find out what ABI is being produced by ac_compile, and set mode
-  # options accordingly.
+  # Find out which ABI we are using.
   echo 'int i;' > conftest.$ac_ext
   if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
   (eval $ac_compile) 2>&5
@@ -6838,25 +6710,24 @@ ia64-*-hpux*)
   test $ac_status = 0; }; then
     case `/usr/bin/file conftest.$ac_objext` in
       *ELF-32*)
-	HPUX_IA64_MODE=32
+	HPUX_IA64_MODE="32"
 	;;
       *ELF-64*)
-	HPUX_IA64_MODE=64
+	HPUX_IA64_MODE="64"
 	;;
     esac
   fi
   rm -rf conftest*
   ;;
 *-*-irix6*)
-  # Find out what ABI is being produced by ac_compile, and set linker
-  # options accordingly.
+  # Find out which ABI we are using.
   echo '#line '$LINENO' "configure"' > conftest.$ac_ext
   if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
   (eval $ac_compile) 2>&5
   ac_status=$?
   $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
   test $ac_status = 0; }; then
-    if test yes = "$lt_cv_prog_gnu_ld"; then
+    if test "$lt_cv_prog_gnu_ld" = yes; then
       case `/usr/bin/file conftest.$ac_objext` in
 	*32-bit*)
 	  LD="${LD-ld} -melf32bsmip"
@@ -6885,50 +6756,9 @@ ia64-*-hpux*)
   rm -rf conftest*
   ;;
 
-mips64*-*linux*)
-  # Find out what ABI is being produced by ac_compile, and set linker
-  # options accordingly.
-  echo '#line '$LINENO' "configure"' > conftest.$ac_ext
-  if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
-  (eval $ac_compile) 2>&5
-  ac_status=$?
-  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
-  test $ac_status = 0; }; then
-    emul=elf
-    case `/usr/bin/file conftest.$ac_objext` in
-      *32-bit*)
-	emul="${emul}32"
-	;;
-      *64-bit*)
-	emul="${emul}64"
-	;;
-    esac
-    case `/usr/bin/file conftest.$ac_objext` in
-      *MSB*)
-	emul="${emul}btsmip"
-	;;
-      *LSB*)
-	emul="${emul}ltsmip"
-	;;
-    esac
-    case `/usr/bin/file conftest.$ac_objext` in
-      *N32*)
-	emul="${emul}n32"
-	;;
-    esac
-    LD="${LD-ld} -m $emul"
-  fi
-  rm -rf conftest*
-  ;;
-
 x86_64-*kfreebsd*-gnu|x86_64-*linux*|powerpc*-*linux*| \
 s390*-*linux*|s390*-*tpf*|sparc*-*linux*)
-  # Find out what ABI is being produced by ac_compile, and set linker
-  # options accordingly.  Note that the listed cases only cover the
-  # situations where additional linker options are needed (such as when
-  # doing 32-bit compilation for a host where ld defaults to 64-bit, or
-  # vice versa); the common cases where no linker options are needed do
-  # not appear in the list.
+  # Find out which ABI we are using.
   echo 'int i;' > conftest.$ac_ext
   if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
   (eval $ac_compile) 2>&5
@@ -6951,10 +6781,10 @@ s390*-*linux*|s390*-*tpf*|sparc*-*linux*)
 		;;
 	    esac
 	    ;;
-	  powerpc64le-*linux*)
+	  powerpc64le-*)
 	    LD="${LD-ld} -m elf32lppclinux"
 	    ;;
-	  powerpc64-*linux*)
+	  powerpc64-*)
 	    LD="${LD-ld} -m elf32ppclinux"
 	    ;;
 	  s390x-*linux*)
@@ -6973,10 +6803,10 @@ s390*-*linux*|s390*-*tpf*|sparc*-*linux*)
 	  x86_64-*linux*)
 	    LD="${LD-ld} -m elf_x86_64"
 	    ;;
-	  powerpcle-*linux*)
+	  powerpcle-*)
 	    LD="${LD-ld} -m elf64lppc"
 	    ;;
-	  powerpc-*linux*)
+	  powerpc-*)
 	    LD="${LD-ld} -m elf64ppc"
 	    ;;
 	  s390*-*linux*|s390*-*tpf*)
@@ -6994,7 +6824,7 @@ s390*-*linux*|s390*-*tpf*|sparc*-*linux*)
 
 *-*-sco3.2v5*)
   # On SCO OpenServer 5, we need -belf to get full-featured binaries.
-  SAVE_CFLAGS=$CFLAGS
+  SAVE_CFLAGS="$CFLAGS"
   CFLAGS="$CFLAGS -belf"
   { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler needs -belf" >&5
 $as_echo_n "checking whether the C compiler needs -belf... " >&6; }
@@ -7034,14 +6864,13 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu
 fi
 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_cc_needs_belf" >&5
 $as_echo "$lt_cv_cc_needs_belf" >&6; }
-  if test yes != "$lt_cv_cc_needs_belf"; then
+  if test x"$lt_cv_cc_needs_belf" != x"yes"; then
     # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf
-    CFLAGS=$SAVE_CFLAGS
+    CFLAGS="$SAVE_CFLAGS"
   fi
   ;;
 *-*solaris*)
-  # Find out what ABI is being produced by ac_compile, and set linker
-  # options accordingly.
+  # Find out which ABI we are using.
   echo 'int i;' > conftest.$ac_ext
   if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
   (eval $ac_compile) 2>&5
@@ -7053,7 +6882,7 @@ $as_echo "$lt_cv_cc_needs_belf" >&6; }
       case $lt_cv_prog_gnu_ld in
       yes*)
         case $host in
-        i?86-*-solaris*|x86_64-*-solaris*)
+        i?86-*-solaris*)
           LD="${LD-ld} -m elf_x86_64"
           ;;
         sparc*-*-solaris*)
@@ -7062,7 +6891,7 @@ $as_echo "$lt_cv_cc_needs_belf" >&6; }
         esac
         # GNU ld 2.21 introduced _sol2 emulations.  Use them if available.
         if ${LD-ld} -V | grep _sol2 >/dev/null 2>&1; then
-          LD=${LD-ld}_sol2
+          LD="${LD-ld}_sol2"
         fi
         ;;
       *)
@@ -7078,7 +6907,7 @@ $as_echo "$lt_cv_cc_needs_belf" >&6; }
   ;;
 esac
 
-need_locks=$enable_libtool_lock
+need_locks="$enable_libtool_lock"
 
 if test -n "$ac_tool_prefix"; then
   # Extract the first word of "${ac_tool_prefix}mt", so it can be a program name with args.
@@ -7189,7 +7018,7 @@ else
 fi
 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_mainfest_tool" >&5
 $as_echo "$lt_cv_path_mainfest_tool" >&6; }
-if test yes != "$lt_cv_path_mainfest_tool"; then
+if test "x$lt_cv_path_mainfest_tool" != xyes; then
   MANIFEST_TOOL=:
 fi
 
@@ -7692,7 +7521,7 @@ if ${lt_cv_apple_cc_single_mod+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   lt_cv_apple_cc_single_mod=no
-      if test -z "$LT_MULTI_MODULE"; then
+      if test -z "${LT_MULTI_MODULE}"; then
 	# By default we will add the -single_module flag. You can override
 	# by either setting the environment variable LT_MULTI_MODULE
 	# non-empty at configure time, or by adding -multi_module to the
@@ -7710,7 +7539,7 @@ else
 	  cat conftest.err >&5
 	# Otherwise, if the output was created with a 0 exit code from
 	# the compiler, it worked.
-	elif test -f libconftest.dylib && test 0 = "$_lt_result"; then
+	elif test -f libconftest.dylib && test $_lt_result -eq 0; then
 	  lt_cv_apple_cc_single_mod=yes
 	else
 	  cat conftest.err >&5
@@ -7749,7 +7578,7 @@ else
 fi
 rm -f core conftest.err conftest.$ac_objext \
     conftest$ac_exeext conftest.$ac_ext
-	LDFLAGS=$save_LDFLAGS
+	LDFLAGS="$save_LDFLAGS"
 
 fi
 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_exported_symbols_list" >&5
@@ -7778,7 +7607,7 @@ _LT_EOF
       _lt_result=$?
       if test -s conftest.err && $GREP force_load conftest.err; then
 	cat conftest.err >&5
-      elif test -f conftest && test 0 = "$_lt_result" && $GREP forced_load conftest >/dev/null 2>&1; then
+      elif test -f conftest && test $_lt_result -eq 0 && $GREP forced_load conftest >/dev/null 2>&1 ; then
 	lt_cv_ld_force_load=yes
       else
 	cat conftest.err >&5
@@ -7791,32 +7620,32 @@ fi
 $as_echo "$lt_cv_ld_force_load" >&6; }
     case $host_os in
     rhapsody* | darwin1.[012])
-      _lt_dar_allow_undefined='$wl-undefined ${wl}suppress' ;;
+      _lt_dar_allow_undefined='${wl}-undefined ${wl}suppress' ;;
     darwin1.*)
-      _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;;
+      _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;;
     darwin*) # darwin 5.x on
       # if running on 10.5 or later, the deployment target defaults
       # to the OS version, if on x86, and 10.4, the deployment
       # target defaults to 10.4. Don't you love it?
       case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in
 	10.0,*86*-darwin8*|10.0,*-darwin[91]*)
-	  _lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' ;;
-	10.[012][,.]*)
-	  _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;;
+	  _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;;
+	10.[012]*)
+	  _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;;
 	10.*)
-	  _lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' ;;
+	  _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;;
       esac
     ;;
   esac
-    if test yes = "$lt_cv_apple_cc_single_mod"; then
+    if test "$lt_cv_apple_cc_single_mod" = "yes"; then
       _lt_dar_single_mod='$single_module'
     fi
-    if test yes = "$lt_cv_ld_exported_symbols_list"; then
-      _lt_dar_export_syms=' $wl-exported_symbols_list,$output_objdir/$libname-symbols.expsym'
+    if test "$lt_cv_ld_exported_symbols_list" = "yes"; then
+      _lt_dar_export_syms=' ${wl}-exported_symbols_list,$output_objdir/${libname}-symbols.expsym'
     else
-      _lt_dar_export_syms='~$NMEDIT -s $output_objdir/$libname-symbols.expsym $lib'
+      _lt_dar_export_syms='~$NMEDIT -s $output_objdir/${libname}-symbols.expsym ${lib}'
     fi
-    if test : != "$DSYMUTIL" && test no = "$lt_cv_ld_force_load"; then
+    if test "$DSYMUTIL" != ":" && test "$lt_cv_ld_force_load" = "no"; then
       _lt_dsymutil='~$DSYMUTIL $lib || :'
     else
       _lt_dsymutil=
@@ -7824,41 +7653,6 @@ $as_echo "$lt_cv_ld_force_load" >&6; }
     ;;
   esac
 
-# func_munge_path_list VARIABLE PATH
-# -----------------------------------
-# VARIABLE is name of variable containing _space_ separated list of
-# directories to be munged by the contents of PATH, which is string
-# having a format:
-# "DIR[:DIR]:"
-#       string "DIR[ DIR]" will be prepended to VARIABLE
-# ":DIR[:DIR]"
-#       string "DIR[ DIR]" will be appended to VARIABLE
-# "DIRP[:DIRP]::[DIRA:]DIRA"
-#       string "DIRP[ DIRP]" will be prepended to VARIABLE and string
-#       "DIRA[ DIRA]" will be appended to VARIABLE
-# "DIR[:DIR]"
-#       VARIABLE will be replaced by "DIR[ DIR]"
-func_munge_path_list ()
-{
-    case x$2 in
-    x)
-        ;;
-    *:)
-        eval $1=\"`$ECHO $2 | $SED 's/:/ /g'` \$$1\"
-        ;;
-    x:*)
-        eval $1=\"\$$1 `$ECHO $2 | $SED 's/:/ /g'`\"
-        ;;
-    *::*)
-        eval $1=\"\$$1\ `$ECHO $2 | $SED -e 's/.*:://' -e 's/:/ /g'`\"
-        eval $1=\"`$ECHO $2 | $SED -e 's/::.*//' -e 's/:/ /g'`\ \$$1\"
-        ;;
-    *)
-        eval $1=\"`$ECHO $2 | $SED 's/:/ /g'`\"
-        ;;
-    esac
-}
-
 ac_ext=c
 ac_cpp='$CPP $CPPFLAGS'
 ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
@@ -8143,9 +7937,9 @@ done
 
 func_stripname_cnf ()
 {
-  case $2 in
-  .*) func_stripname_result=`$ECHO "$3" | $SED "s%^$1%%; s%\\\\$2\$%%"`;;
-  *)  func_stripname_result=`$ECHO "$3" | $SED "s%^$1%%; s%$2\$%%"`;;
+  case ${2} in
+  .*) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%\\\\${2}\$%%"`;;
+  *)  func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%${2}\$%%"`;;
   esac
 } # func_stripname_cnf
 
@@ -8172,14 +7966,14 @@ if test "${enable_shared+set}" = set; then :
     *)
       enable_shared=no
       # Look at the argument we got.  We use all the common list separators.
-      lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR,
+      lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
       for pkg in $enableval; do
-	IFS=$lt_save_ifs
+	IFS="$lt_save_ifs"
 	if test "X$pkg" = "X$p"; then
 	  enable_shared=yes
 	fi
       done
-      IFS=$lt_save_ifs
+      IFS="$lt_save_ifs"
       ;;
     esac
 else
@@ -8203,14 +7997,14 @@ if test "${enable_static+set}" = set; then :
     *)
      enable_static=no
       # Look at the argument we got.  We use all the common list separators.
-      lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR,
+      lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
       for pkg in $enableval; do
-	IFS=$lt_save_ifs
+	IFS="$lt_save_ifs"
 	if test "X$pkg" = "X$p"; then
 	  enable_static=yes
 	fi
       done
-      IFS=$lt_save_ifs
+      IFS="$lt_save_ifs"
       ;;
     esac
 else
@@ -8234,14 +8028,14 @@ if test "${with_pic+set}" = set; then :
     *)
       pic_mode=default
       # Look at the argument we got.  We use all the common list separators.
-      lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR,
+      lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
       for lt_pkg in $withval; do
-	IFS=$lt_save_ifs
+	IFS="$lt_save_ifs"
 	if test "X$lt_pkg" = "X$lt_p"; then
 	  pic_mode=yes
 	fi
       done
-      IFS=$lt_save_ifs
+      IFS="$lt_save_ifs"
       ;;
     esac
 else
@@ -8249,6 +8043,8 @@ else
 fi
 
 
+test -z "$pic_mode" && pic_mode=default
+
 
 
 
@@ -8264,14 +8060,14 @@ if test "${enable_fast_install+set}" = set; then :
     *)
       enable_fast_install=no
       # Look at the argument we got.  We use all the common list separators.
-      lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR,
+      lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
       for pkg in $enableval; do
-	IFS=$lt_save_ifs
+	IFS="$lt_save_ifs"
 	if test "X$pkg" = "X$p"; then
 	  enable_fast_install=yes
 	fi
       done
-      IFS=$lt_save_ifs
+      IFS="$lt_save_ifs"
       ;;
     esac
 else
@@ -8285,63 +8081,11 @@ fi
 
 
 
-  shared_archive_member_spec=
-case $host,$enable_shared in
-power*-*-aix[5-9]*,yes)
-  { $as_echo "$as_me:${as_lineno-$LINENO}: checking which variant of shared library versioning to provide" >&5
-$as_echo_n "checking which variant of shared library versioning to provide... " >&6; }
-
-# Check whether --with-aix-soname was given.
-if test "${with_aix_soname+set}" = set; then :
-  withval=$with_aix_soname; case $withval in
-    aix|svr4|both)
-      ;;
-    *)
-      as_fn_error $? "Unknown argument to --with-aix-soname" "$LINENO" 5
-      ;;
-    esac
-    lt_cv_with_aix_soname=$with_aix_soname
-else
-  if ${lt_cv_with_aix_soname+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  lt_cv_with_aix_soname=aix
-fi
-
-    with_aix_soname=$lt_cv_with_aix_soname
-fi
-
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $with_aix_soname" >&5
-$as_echo "$with_aix_soname" >&6; }
-  if test aix != "$with_aix_soname"; then
-    # For the AIX way of multilib, we name the shared archive member
-    # based on the bitwidth used, traditionally 'shr.o' or 'shr_64.o',
-    # and 'shr.imp' or 'shr_64.imp', respectively, for the Import File.
-    # Even when GNU compilers ignore OBJECT_MODE but need '-maix64' flag,
-    # the AIX toolchain works better with OBJECT_MODE set (default 32).
-    if test 64 = "${OBJECT_MODE-32}"; then
-      shared_archive_member_spec=shr_64
-    else
-      shared_archive_member_spec=shr
-    fi
-  fi
-  ;;
-*)
-  with_aix_soname=aix
-  ;;
-esac
-
-
-
-
-
-
-
 
 
 
 # This can be used to rebuild libtool when needed
-LIBTOOL_DEPS=$ltmain
+LIBTOOL_DEPS="$ltmain"
 
 # Always use our own libtool.
 LIBTOOL='$(SHELL) $(top_builddir)/libtool'
@@ -8390,7 +8134,7 @@ test -z "$LN_S" && LN_S="ln -s"
 
 
 
-if test -n "${ZSH_VERSION+set}"; then
+if test -n "${ZSH_VERSION+set}" ; then
    setopt NO_GLOB_SUBST
 fi
 
@@ -8429,7 +8173,7 @@ aix3*)
   # AIX sometimes has problems with the GCC collect2 program.  For some
   # reason, if we set the COLLECT_NAMES environment variable, the problems
   # vanish in a puff of smoke.
-  if test set != "${COLLECT_NAMES+set}"; then
+  if test "X${COLLECT_NAMES+set}" != Xset; then
     COLLECT_NAMES=
     export COLLECT_NAMES
   fi
@@ -8440,14 +8184,14 @@ esac
 ofile=libtool
 can_build_shared=yes
 
-# All known linkers require a '.a' archive for static linking (except MSVC,
+# All known linkers require a `.a' archive for static linking (except MSVC,
 # which needs '.lib').
 libext=a
 
-with_gnu_ld=$lt_cv_prog_gnu_ld
+with_gnu_ld="$lt_cv_prog_gnu_ld"
 
-old_CC=$CC
-old_CFLAGS=$CFLAGS
+old_CC="$CC"
+old_CFLAGS="$CFLAGS"
 
 # Set sane defaults for various variables
 test -z "$CC" && CC=cc
@@ -8456,8 +8200,15 @@ test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS
 test -z "$LD" && LD=ld
 test -z "$ac_objext" && ac_objext=o
 
-func_cc_basename $compiler
-cc_basename=$func_cc_basename_result
+for cc_temp in $compiler""; do
+  case $cc_temp in
+    compile | *[\\/]compile | ccache | *[\\/]ccache ) ;;
+    distcc | *[\\/]distcc | purify | *[\\/]purify ) ;;
+    \-*) ;;
+    *) break;;
+  esac
+done
+cc_basename=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"`
 
 
 # Only perform the check for file, if the check method requires it
@@ -8472,22 +8223,22 @@ if ${lt_cv_path_MAGIC_CMD+:} false; then :
 else
   case $MAGIC_CMD in
 [\\/*] |  ?:[\\/]*)
-  lt_cv_path_MAGIC_CMD=$MAGIC_CMD # Let the user override the test with a path.
+  lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path.
   ;;
 *)
-  lt_save_MAGIC_CMD=$MAGIC_CMD
-  lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR
+  lt_save_MAGIC_CMD="$MAGIC_CMD"
+  lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
   ac_dummy="/usr/bin$PATH_SEPARATOR$PATH"
   for ac_dir in $ac_dummy; do
-    IFS=$lt_save_ifs
+    IFS="$lt_save_ifs"
     test -z "$ac_dir" && ac_dir=.
-    if test -f "$ac_dir/${ac_tool_prefix}file"; then
-      lt_cv_path_MAGIC_CMD=$ac_dir/"${ac_tool_prefix}file"
+    if test -f $ac_dir/${ac_tool_prefix}file; then
+      lt_cv_path_MAGIC_CMD="$ac_dir/${ac_tool_prefix}file"
       if test -n "$file_magic_test_file"; then
 	case $deplibs_check_method in
 	"file_magic "*)
 	  file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"`
-	  MAGIC_CMD=$lt_cv_path_MAGIC_CMD
+	  MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
 	  if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null |
 	    $EGREP "$file_magic_regex" > /dev/null; then
 	    :
@@ -8510,13 +8261,13 @@ _LT_EOF
       break
     fi
   done
-  IFS=$lt_save_ifs
-  MAGIC_CMD=$lt_save_MAGIC_CMD
+  IFS="$lt_save_ifs"
+  MAGIC_CMD="$lt_save_MAGIC_CMD"
   ;;
 esac
 fi
 
-MAGIC_CMD=$lt_cv_path_MAGIC_CMD
+MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
 if test -n "$MAGIC_CMD"; then
   { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5
 $as_echo "$MAGIC_CMD" >&6; }
@@ -8538,22 +8289,22 @@ if ${lt_cv_path_MAGIC_CMD+:} false; then :
 else
   case $MAGIC_CMD in
 [\\/*] |  ?:[\\/]*)
-  lt_cv_path_MAGIC_CMD=$MAGIC_CMD # Let the user override the test with a path.
+  lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path.
   ;;
 *)
-  lt_save_MAGIC_CMD=$MAGIC_CMD
-  lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR
+  lt_save_MAGIC_CMD="$MAGIC_CMD"
+  lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
   ac_dummy="/usr/bin$PATH_SEPARATOR$PATH"
   for ac_dir in $ac_dummy; do
-    IFS=$lt_save_ifs
+    IFS="$lt_save_ifs"
     test -z "$ac_dir" && ac_dir=.
-    if test -f "$ac_dir/file"; then
-      lt_cv_path_MAGIC_CMD=$ac_dir/"file"
+    if test -f $ac_dir/file; then
+      lt_cv_path_MAGIC_CMD="$ac_dir/file"
       if test -n "$file_magic_test_file"; then
 	case $deplibs_check_method in
 	"file_magic "*)
 	  file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"`
-	  MAGIC_CMD=$lt_cv_path_MAGIC_CMD
+	  MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
 	  if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null |
 	    $EGREP "$file_magic_regex" > /dev/null; then
 	    :
@@ -8576,13 +8327,13 @@ _LT_EOF
       break
     fi
   done
-  IFS=$lt_save_ifs
-  MAGIC_CMD=$lt_save_MAGIC_CMD
+  IFS="$lt_save_ifs"
+  MAGIC_CMD="$lt_save_MAGIC_CMD"
   ;;
 esac
 fi
 
-MAGIC_CMD=$lt_cv_path_MAGIC_CMD
+MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
 if test -n "$MAGIC_CMD"; then
   { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5
 $as_echo "$MAGIC_CMD" >&6; }
@@ -8603,7 +8354,7 @@ esac
 
 # Use C for the default configuration in the libtool script
 
-lt_save_CC=$CC
+lt_save_CC="$CC"
 ac_ext=c
 ac_cpp='$CPP $CPPFLAGS'
 ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
@@ -8661,7 +8412,7 @@ if test -n "$compiler"; then
 
 lt_prog_compiler_no_builtin_flag=
 
-if test yes = "$GCC"; then
+if test "$GCC" = yes; then
   case $cc_basename in
   nvcc*)
     lt_prog_compiler_no_builtin_flag=' -Xcompiler -fno-builtin' ;;
@@ -8677,7 +8428,7 @@ else
   lt_cv_prog_compiler_rtti_exceptions=no
    ac_outfile=conftest.$ac_objext
    echo "$lt_simple_compile_test_code" > conftest.$ac_ext
-   lt_compiler_flag="-fno-rtti -fno-exceptions"  ## exclude from sc_useless_quotes_in_assignment
+   lt_compiler_flag="-fno-rtti -fno-exceptions"
    # Insert the option either (1) after the last *FLAGS variable, or
    # (2) before a word containing "conftest.", or (3) at the end.
    # Note that $ac_compile itself does not contain backslashes and begins
@@ -8707,7 +8458,7 @@ fi
 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_rtti_exceptions" >&5
 $as_echo "$lt_cv_prog_compiler_rtti_exceptions" >&6; }
 
-if test yes = "$lt_cv_prog_compiler_rtti_exceptions"; then
+if test x"$lt_cv_prog_compiler_rtti_exceptions" = xyes; then
     lt_prog_compiler_no_builtin_flag="$lt_prog_compiler_no_builtin_flag -fno-rtti -fno-exceptions"
 else
     :
@@ -8725,18 +8476,17 @@ lt_prog_compiler_pic=
 lt_prog_compiler_static=
 
 
-  if test yes = "$GCC"; then
+  if test "$GCC" = yes; then
     lt_prog_compiler_wl='-Wl,'
     lt_prog_compiler_static='-static'
 
     case $host_os in
       aix*)
       # All AIX code is PIC.
-      if test ia64 = "$host_cpu"; then
+      if test "$host_cpu" = ia64; then
 	# AIX 5 now supports IA64 processor
 	lt_prog_compiler_static='-Bstatic'
       fi
-      lt_prog_compiler_pic='-fPIC'
       ;;
 
     amigaos*)
@@ -8747,8 +8497,8 @@ lt_prog_compiler_static=
         ;;
       m68k)
             # FIXME: we need at least 68020 code to build shared libraries, but
-            # adding the '-m68020' flag to GCC prevents building anything better,
-            # like '-m68040'.
+            # adding the `-m68020' flag to GCC prevents building anything better,
+            # like `-m68040'.
             lt_prog_compiler_pic='-m68020 -resident32 -malways-restore-a4'
         ;;
       esac
@@ -8764,11 +8514,6 @@ lt_prog_compiler_static=
       # Although the cygwin gcc ignores -fPIC, still need this for old-style
       # (--disable-auto-import) libraries
       lt_prog_compiler_pic='-DDLL_EXPORT'
-      case $host_os in
-      os2*)
-	lt_prog_compiler_static='$wl-static'
-	;;
-      esac
       ;;
 
     darwin* | rhapsody*)
@@ -8839,7 +8584,7 @@ lt_prog_compiler_static=
     case $host_os in
     aix*)
       lt_prog_compiler_wl='-Wl,'
-      if test ia64 = "$host_cpu"; then
+      if test "$host_cpu" = ia64; then
 	# AIX 5 now supports IA64 processor
 	lt_prog_compiler_static='-Bstatic'
       else
@@ -8847,29 +8592,10 @@ lt_prog_compiler_static=
       fi
       ;;
 
-    darwin* | rhapsody*)
-      # PIC is the default on this platform
-      # Common symbols not allowed in MH_DYLIB files
-      lt_prog_compiler_pic='-fno-common'
-      case $cc_basename in
-      nagfor*)
-        # NAG Fortran compiler
-        lt_prog_compiler_wl='-Wl,-Wl,,'
-        lt_prog_compiler_pic='-PIC'
-        lt_prog_compiler_static='-Bstatic'
-        ;;
-      esac
-      ;;
-
     mingw* | cygwin* | pw32* | os2* | cegcc*)
       # This hack is so that the source file can tell whether it is being
       # built for inclusion in a dll (and should export symbols for example).
       lt_prog_compiler_pic='-DDLL_EXPORT'
-      case $host_os in
-      os2*)
-	lt_prog_compiler_static='$wl-static'
-	;;
-      esac
       ;;
 
     hpux9* | hpux10* | hpux11*)
@@ -8885,7 +8611,7 @@ lt_prog_compiler_static=
 	;;
       esac
       # Is there a better lt_prog_compiler_static that works with the bundled CC?
-      lt_prog_compiler_static='$wl-a ${wl}archive'
+      lt_prog_compiler_static='${wl}-a ${wl}archive'
       ;;
 
     irix5* | irix6* | nonstopux*)
@@ -8896,7 +8622,7 @@ lt_prog_compiler_static=
 
     linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*)
       case $cc_basename in
-      # old Intel for x86_64, which still supported -KPIC.
+      # old Intel for x86_64 which still supported -KPIC.
       ecc*)
 	lt_prog_compiler_wl='-Wl,'
 	lt_prog_compiler_pic='-KPIC'
@@ -8921,12 +8647,6 @@ lt_prog_compiler_static=
 	lt_prog_compiler_pic='-PIC'
 	lt_prog_compiler_static='-Bstatic'
 	;;
-      tcc*)
-	# Fabrice Bellard et al's Tiny C Compiler
-	lt_prog_compiler_wl='-Wl,'
-	lt_prog_compiler_pic='-fPIC'
-	lt_prog_compiler_static='-static'
-	;;
       pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*)
         # Portland Group compilers (*not* the Pentium gcc compiler,
 	# which looks to be a dead project)
@@ -9024,7 +8744,7 @@ lt_prog_compiler_static=
       ;;
 
     sysv4*MP*)
-      if test -d /usr/nec; then
+      if test -d /usr/nec ;then
 	lt_prog_compiler_pic='-Kconform_pic'
 	lt_prog_compiler_static='-Bstatic'
       fi
@@ -9053,7 +8773,7 @@ lt_prog_compiler_static=
   fi
 
 case $host_os in
-  # For platforms that do not support PIC, -DPIC is meaningless:
+  # For platforms which do not support PIC, -DPIC is meaningless:
   *djgpp*)
     lt_prog_compiler_pic=
     ;;
@@ -9085,7 +8805,7 @@ else
   lt_cv_prog_compiler_pic_works=no
    ac_outfile=conftest.$ac_objext
    echo "$lt_simple_compile_test_code" > conftest.$ac_ext
-   lt_compiler_flag="$lt_prog_compiler_pic -DPIC"  ## exclude from sc_useless_quotes_in_assignment
+   lt_compiler_flag="$lt_prog_compiler_pic -DPIC"
    # Insert the option either (1) after the last *FLAGS variable, or
    # (2) before a word containing "conftest.", or (3) at the end.
    # Note that $ac_compile itself does not contain backslashes and begins
@@ -9115,7 +8835,7 @@ fi
 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_works" >&5
 $as_echo "$lt_cv_prog_compiler_pic_works" >&6; }
 
-if test yes = "$lt_cv_prog_compiler_pic_works"; then
+if test x"$lt_cv_prog_compiler_pic_works" = xyes; then
     case $lt_prog_compiler_pic in
      "" | " "*) ;;
      *) lt_prog_compiler_pic=" $lt_prog_compiler_pic" ;;
@@ -9147,7 +8867,7 @@ if ${lt_cv_prog_compiler_static_works+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   lt_cv_prog_compiler_static_works=no
-   save_LDFLAGS=$LDFLAGS
+   save_LDFLAGS="$LDFLAGS"
    LDFLAGS="$LDFLAGS $lt_tmp_static_flag"
    echo "$lt_simple_link_test_code" > conftest.$ac_ext
    if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then
@@ -9166,13 +8886,13 @@ else
      fi
    fi
    $RM -r conftest*
-   LDFLAGS=$save_LDFLAGS
+   LDFLAGS="$save_LDFLAGS"
 
 fi
 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_static_works" >&5
 $as_echo "$lt_cv_prog_compiler_static_works" >&6; }
 
-if test yes = "$lt_cv_prog_compiler_static_works"; then
+if test x"$lt_cv_prog_compiler_static_works" = xyes; then
     :
 else
     lt_prog_compiler_static=
@@ -9292,8 +9012,8 @@ $as_echo "$lt_cv_prog_compiler_c_o" >&6; }
 
 
 
-hard_links=nottested
-if test no = "$lt_cv_prog_compiler_c_o" && test no != "$need_locks"; then
+hard_links="nottested"
+if test "$lt_cv_prog_compiler_c_o" = no && test "$need_locks" != no; then
   # do not overwrite the value of need_locks provided by the user
   { $as_echo "$as_me:${as_lineno-$LINENO}: checking if we can lock with hard links" >&5
 $as_echo_n "checking if we can lock with hard links... " >&6; }
@@ -9305,9 +9025,9 @@ $as_echo_n "checking if we can lock with hard links... " >&6; }
   ln conftest.a conftest.b 2>/dev/null && hard_links=no
   { $as_echo "$as_me:${as_lineno-$LINENO}: result: $hard_links" >&5
 $as_echo "$hard_links" >&6; }
-  if test no = "$hard_links"; then
-    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: '$CC' does not support '-c -o', so 'make -j' may be unsafe" >&5
-$as_echo "$as_me: WARNING: '$CC' does not support '-c -o', so 'make -j' may be unsafe" >&2;}
+  if test "$hard_links" = no; then
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&5
+$as_echo "$as_me: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&2;}
     need_locks=warn
   fi
 else
@@ -9350,9 +9070,9 @@ $as_echo_n "checking whether the $compiler linker ($LD) supports shared librarie
   # included in the symbol list
   include_expsyms=
   # exclude_expsyms can be an extended regexp of symbols to exclude
-  # it will be wrapped by ' (' and ')$', so one must not match beginning or
-  # end of line.  Example: 'a|bc|.*d.*' will exclude the symbols 'a' and 'bc',
-  # as well as any symbol that contains 'd'.
+  # it will be wrapped by ` (' and `)$', so one must not match beginning or
+  # end of line.  Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc',
+  # as well as any symbol that contains `d'.
   exclude_expsyms='_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'
   # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out
   # platforms (ab)use it in PIC code, but their linkers get confused if
@@ -9367,7 +9087,7 @@ $as_echo_n "checking whether the $compiler linker ($LD) supports shared librarie
     # FIXME: the MSVC++ port hasn't been tested in a loooong time
     # When not using gcc, we currently assume that we are using
     # Microsoft Visual C++.
-    if test yes != "$GCC"; then
+    if test "$GCC" != yes; then
       with_gnu_ld=no
     fi
     ;;
@@ -9375,7 +9095,7 @@ $as_echo_n "checking whether the $compiler linker ($LD) supports shared librarie
     # we just hope/assume this is gcc and not c89 (= MSVC++)
     with_gnu_ld=yes
     ;;
-  openbsd* | bitrig*)
+  openbsd*)
     with_gnu_ld=no
     ;;
   linux* | k*bsd*-gnu | gnu*)
@@ -9388,7 +9108,7 @@ $as_echo_n "checking whether the $compiler linker ($LD) supports shared librarie
   # On some targets, GNU ld is compatible enough with the native linker
   # that we're better off using the native interface for both.
   lt_use_gnu_ld_interface=no
-  if test yes = "$with_gnu_ld"; then
+  if test "$with_gnu_ld" = yes; then
     case $host_os in
       aix*)
 	# The AIX port of GNU ld has always aspired to compatibility
@@ -9410,24 +9130,24 @@ $as_echo_n "checking whether the $compiler linker ($LD) supports shared librarie
     esac
   fi
 
-  if test yes = "$lt_use_gnu_ld_interface"; then
+  if test "$lt_use_gnu_ld_interface" = yes; then
     # If archive_cmds runs LD, not CC, wlarc should be empty
-    wlarc='$wl'
+    wlarc='${wl}'
 
     # Set some defaults for GNU ld with shared library support. These
     # are reset later if shared libraries are not supported. Putting them
     # here allows them to be overridden if necessary.
     runpath_var=LD_RUN_PATH
-    hardcode_libdir_flag_spec='$wl-rpath $wl$libdir'
-    export_dynamic_flag_spec='$wl--export-dynamic'
+    hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+    export_dynamic_flag_spec='${wl}--export-dynamic'
     # ancient GNU ld didn't support --whole-archive et. al.
     if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then
-      whole_archive_flag_spec=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive'
+      whole_archive_flag_spec="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive'
     else
       whole_archive_flag_spec=
     fi
     supports_anon_versioning=no
-    case `$LD -v | $SED -e 's/(^)\+)\s\+//' 2>&1` in
+    case `$LD -v 2>&1` in
       *GNU\ gold*) supports_anon_versioning=yes ;;
       *\ [01].* | *\ 2.[0-9].* | *\ 2.10.*) ;; # catch versions < 2.11
       *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ...
@@ -9440,7 +9160,7 @@ $as_echo_n "checking whether the $compiler linker ($LD) supports shared librarie
     case $host_os in
     aix[3-9]*)
       # On AIX/PPC, the GNU linker is very broken
-      if test ia64 != "$host_cpu"; then
+      if test "$host_cpu" != ia64; then
 	ld_shlibs=no
 	cat <<_LT_EOF 1>&2
 
@@ -9459,7 +9179,7 @@ _LT_EOF
       case $host_cpu in
       powerpc)
             # see comment about AmigaOS4 .so support
-            archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+            archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
             archive_expsym_cmds=''
         ;;
       m68k)
@@ -9475,7 +9195,7 @@ _LT_EOF
 	allow_undefined_flag=unsupported
 	# Joseph Beckenbach <jrb3 at best.com> says some releases of gcc
 	# support --undefined.  This deserves some investigation.  FIXME
-	archive_cmds='$CC -nostart $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+	archive_cmds='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
       else
 	ld_shlibs=no
       fi
@@ -9485,7 +9205,7 @@ _LT_EOF
       # _LT_TAGVAR(hardcode_libdir_flag_spec, ) is actually meaningless,
       # as there is no search path for DLLs.
       hardcode_libdir_flag_spec='-L$libdir'
-      export_dynamic_flag_spec='$wl--export-all-symbols'
+      export_dynamic_flag_spec='${wl}--export-all-symbols'
       allow_undefined_flag=unsupported
       always_export_symbols=no
       enable_shared_with_static_runtimes=yes
@@ -9493,89 +9213,61 @@ _LT_EOF
       exclude_expsyms='[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname'
 
       if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then
-        archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
-	# If the export-symbols file already is a .def file, use it as
-	# is; otherwise, prepend EXPORTS...
-	archive_expsym_cmds='if   test DEF = "`$SED -n     -e '\''s/^[	 ]*//'\''     -e '\''/^\(;.*\)*$/d'\''     -e '\''s/^\(EXPORTS\|LIBRARY\)\([	 ].*\)*$/DEF/p'\''     -e q     $export_symbols`" ; then
-          cp $export_symbols $output_objdir/$soname.def;
-        else
-          echo EXPORTS > $output_objdir/$soname.def;
-          cat $export_symbols >> $output_objdir/$soname.def;
-        fi~
-        $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+        archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+	# If the export-symbols file already is a .def file (1st line
+	# is EXPORTS), use it as is; otherwise, prepend...
+	archive_expsym_cmds='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then
+	  cp $export_symbols $output_objdir/$soname.def;
+	else
+	  echo EXPORTS > $output_objdir/$soname.def;
+	  cat $export_symbols >> $output_objdir/$soname.def;
+	fi~
+	$CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
       else
 	ld_shlibs=no
       fi
       ;;
 
     haiku*)
-      archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+      archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
       link_all_deplibs=yes
       ;;
 
-    os2*)
-      hardcode_libdir_flag_spec='-L$libdir'
-      hardcode_minus_L=yes
-      allow_undefined_flag=unsupported
-      shrext_cmds=.dll
-      archive_cmds='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~
-	$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~
-	$ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~
-	$ECHO EXPORTS >> $output_objdir/$libname.def~
-	emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~
-	$CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~
-	emximp -o $lib $output_objdir/$libname.def'
-      archive_expsym_cmds='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~
-	$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~
-	$ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~
-	$ECHO EXPORTS >> $output_objdir/$libname.def~
-	prefix_cmds="$SED"~
-	if test EXPORTS = "`$SED 1q $export_symbols`"; then
-	  prefix_cmds="$prefix_cmds -e 1d";
-	fi~
-	prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~
-	cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~
-	$CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~
-	emximp -o $lib $output_objdir/$libname.def'
-      old_archive_From_new_cmds='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def'
-      enable_shared_with_static_runtimes=yes
-      ;;
-
     interix[3-9]*)
       hardcode_direct=no
       hardcode_shlibpath_var=no
-      hardcode_libdir_flag_spec='$wl-rpath,$libdir'
-      export_dynamic_flag_spec='$wl-E'
+      hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
+      export_dynamic_flag_spec='${wl}-E'
       # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc.
       # Instead, shared libraries are loaded at an image base (0x10000000 by
       # default) and relocated if they conflict, which is a slow very memory
       # consuming and fragmenting process.  To avoid this, we pick a random,
       # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link
       # time.  Moving up from 0x10000000 also allows more sbrk(2) space.
-      archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
-      archive_expsym_cmds='sed "s|^|_|" $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--retain-symbols-file,$output_objdir/$soname.expsym $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+      archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+      archive_expsym_cmds='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
       ;;
 
     gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu)
       tmp_diet=no
-      if test linux-dietlibc = "$host_os"; then
+      if test "$host_os" = linux-dietlibc; then
 	case $cc_basename in
 	  diet\ *) tmp_diet=yes;;	# linux-dietlibc with static linking (!diet-dyn)
 	esac
       fi
       if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \
-	 && test no = "$tmp_diet"
+	 && test "$tmp_diet" = no
       then
 	tmp_addflag=' $pic_flag'
 	tmp_sharedflag='-shared'
 	case $cc_basename,$host_cpu in
         pgcc*)				# Portland Group C compiler
-	  whole_archive_flag_spec='$wl--whole-archive`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive'
+	  whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
 	  tmp_addflag=' $pic_flag'
 	  ;;
 	pgf77* | pgf90* | pgf95* | pgfortran*)
 					# Portland Group f77 and f90 compilers
-	  whole_archive_flag_spec='$wl--whole-archive`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive'
+	  whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
 	  tmp_addflag=' $pic_flag -Mnomain' ;;
 	ecc*,ia64* | icc*,ia64*)	# Intel C compiler on ia64
 	  tmp_addflag=' -i_dynamic' ;;
@@ -9586,47 +9278,42 @@ _LT_EOF
 	lf95*)				# Lahey Fortran 8.1
 	  whole_archive_flag_spec=
 	  tmp_sharedflag='--shared' ;;
-        nagfor*)                        # NAGFOR 5.3
-          tmp_sharedflag='-Wl,-shared' ;;
 	xl[cC]* | bgxl[cC]* | mpixl[cC]*) # IBM XL C 8.0 on PPC (deal with xlf below)
 	  tmp_sharedflag='-qmkshrobj'
 	  tmp_addflag= ;;
 	nvcc*)	# Cuda Compiler Driver 2.2
-	  whole_archive_flag_spec='$wl--whole-archive`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive'
+	  whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
 	  compiler_needs_object=yes
 	  ;;
 	esac
 	case `$CC -V 2>&1 | sed 5q` in
 	*Sun\ C*)			# Sun C 5.9
-	  whole_archive_flag_spec='$wl--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive'
+	  whole_archive_flag_spec='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
 	  compiler_needs_object=yes
 	  tmp_sharedflag='-G' ;;
 	*Sun\ F*)			# Sun Fortran 8.3
 	  tmp_sharedflag='-G' ;;
 	esac
-	archive_cmds='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+	archive_cmds='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
 
-        if test yes = "$supports_anon_versioning"; then
+        if test "x$supports_anon_versioning" = xyes; then
           archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~
-            cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
-            echo "local: *; };" >> $output_objdir/$libname.ver~
-            $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-version-script $wl$output_objdir/$libname.ver -o $lib'
+	    cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
+	    echo "local: *; };" >> $output_objdir/$libname.ver~
+	    $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib'
         fi
 
 	case $cc_basename in
-	tcc*)
-	  export_dynamic_flag_spec='-rdynamic'
-	  ;;
 	xlf* | bgf* | bgxlf* | mpixlf*)
 	  # IBM XL Fortran 10.1 on PPC cannot create shared libs itself
 	  whole_archive_flag_spec='--whole-archive$convenience --no-whole-archive'
-	  hardcode_libdir_flag_spec='$wl-rpath $wl$libdir'
+	  hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
 	  archive_cmds='$LD -shared $libobjs $deplibs $linker_flags -soname $soname -o $lib'
-	  if test yes = "$supports_anon_versioning"; then
+	  if test "x$supports_anon_versioning" = xyes; then
 	    archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~
-              cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
-              echo "local: *; };" >> $output_objdir/$libname.ver~
-              $LD -shared $libobjs $deplibs $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib'
+	      cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
+	      echo "local: *; };" >> $output_objdir/$libname.ver~
+	      $LD -shared $libobjs $deplibs $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib'
 	  fi
 	  ;;
 	esac
@@ -9640,8 +9327,8 @@ _LT_EOF
 	archive_cmds='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib'
 	wlarc=
       else
-	archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
-	archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'
+	archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+	archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
       fi
       ;;
 
@@ -9659,8 +9346,8 @@ _LT_EOF
 
 _LT_EOF
       elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
-	archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
-	archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'
+	archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+	archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
       else
 	ld_shlibs=no
       fi
@@ -9672,7 +9359,7 @@ _LT_EOF
 	ld_shlibs=no
 	cat <<_LT_EOF 1>&2
 
-*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 cannot
+*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 can not
 *** reliably create shared libraries on SCO systems.  Therefore, libtool
 *** is disabling shared libraries support.  We urge you to upgrade GNU
 *** binutils to release 2.16.91.0.3 or newer.  Another option is to modify
@@ -9687,9 +9374,9 @@ _LT_EOF
 	  # DT_RUNPATH tag from executables and libraries.  But doing so
 	  # requires that you compile everything twice, which is a pain.
 	  if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
-	    hardcode_libdir_flag_spec='$wl-rpath $wl$libdir'
-	    archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
-	    archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'
+	    hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+	    archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+	    archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
 	  else
 	    ld_shlibs=no
 	  fi
@@ -9706,15 +9393,15 @@ _LT_EOF
 
     *)
       if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
-	archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
-	archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'
+	archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+	archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
       else
 	ld_shlibs=no
       fi
       ;;
     esac
 
-    if test no = "$ld_shlibs"; then
+    if test "$ld_shlibs" = no; then
       runpath_var=
       hardcode_libdir_flag_spec=
       export_dynamic_flag_spec=
@@ -9730,7 +9417,7 @@ _LT_EOF
       # Note: this linker hardcodes the directories in LIBPATH if there
       # are no directories specified by -L.
       hardcode_minus_L=yes
-      if test yes = "$GCC" && test -z "$lt_prog_compiler_static"; then
+      if test "$GCC" = yes && test -z "$lt_prog_compiler_static"; then
 	# Neither direct hardcoding nor static linking is supported with a
 	# broken collect2.
 	hardcode_direct=unsupported
@@ -9738,57 +9425,34 @@ _LT_EOF
       ;;
 
     aix[4-9]*)
-      if test ia64 = "$host_cpu"; then
+      if test "$host_cpu" = ia64; then
 	# On IA64, the linker does run time linking by default, so we don't
 	# have to do anything special.
 	aix_use_runtimelinking=no
 	exp_sym_flag='-Bexport'
-	no_entry_flag=
+	no_entry_flag=""
       else
 	# If we're using GNU nm, then we don't want the "-C" option.
-	# -C means demangle to GNU nm, but means don't demangle to AIX nm.
-	# Without the "-l" option, or with the "-B" option, AIX nm treats
-	# weak defined symbols like other global defined symbols, whereas
-	# GNU nm marks them as "W".
-	# While the 'weak' keyword is ignored in the Export File, we need
-	# it in the Import File for the 'aix-soname' feature, so we have
-	# to replace the "-B" option with "-P" for AIX nm.
+	# -C means demangle to AIX nm, but means don't demangle with GNU nm
+	# Also, AIX nm treats weak defined symbols like other global
+	# defined symbols, whereas GNU nm marks them as "W".
 	if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then
-	  export_symbols_cmds='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && (substr(\$ 3,1,1) != ".")) { if (\$ 2 == "W") { print \$ 3 " weak" } else { print \$ 3 } } }'\'' | sort -u > $export_symbols'
+	  export_symbols_cmds='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols'
 	else
-	  export_symbols_cmds='`func_echo_all $NM | $SED -e '\''s/B\([^B]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && (substr(\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols'
+	  export_symbols_cmds='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols'
 	fi
 	aix_use_runtimelinking=no
 
 	# Test if we are trying to use run time linking or normal
 	# AIX style linking. If -brtl is somewhere in LDFLAGS, we
-	# have runtime linking enabled, and use it for executables.
-	# For shared libraries, we enable/disable runtime linking
-	# depending on the kind of the shared library created -
-	# when "with_aix_soname,aix_use_runtimelinking" is:
-	# "aix,no"   lib.a(lib.so.V) shared, rtl:no,  for executables
-	# "aix,yes"  lib.so          shared, rtl:yes, for executables
-	#            lib.a           static archive
-	# "both,no"  lib.so.V(shr.o) shared, rtl:yes
-	#            lib.a(lib.so.V) shared, rtl:no,  for executables
-	# "both,yes" lib.so.V(shr.o) shared, rtl:yes, for executables
-	#            lib.a(lib.so.V) shared, rtl:no
-	# "svr4,*"   lib.so.V(shr.o) shared, rtl:yes, for executables
-	#            lib.a           static archive
+	# need to do runtime linking.
 	case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*)
 	  for ld_flag in $LDFLAGS; do
-	  if (test x-brtl = "x$ld_flag" || test x-Wl,-brtl = "x$ld_flag"); then
+	  if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then
 	    aix_use_runtimelinking=yes
 	    break
 	  fi
 	  done
-	  if test svr4,no = "$with_aix_soname,$aix_use_runtimelinking"; then
-	    # With aix-soname=svr4, we create the lib.so.V shared archives only,
-	    # so we don't have lib.a shared libs to link our executables.
-	    # We have to force runtime linking in this case.
-	    aix_use_runtimelinking=yes
-	    LDFLAGS="$LDFLAGS -Wl,-brtl"
-	  fi
 	  ;;
 	esac
 
@@ -9807,21 +9471,13 @@ _LT_EOF
       hardcode_direct_absolute=yes
       hardcode_libdir_separator=':'
       link_all_deplibs=yes
-      file_list_spec='$wl-f,'
-      case $with_aix_soname,$aix_use_runtimelinking in
-      aix,*) ;; # traditional, no import file
-      svr4,* | *,yes) # use import file
-	# The Import File defines what to hardcode.
-	hardcode_direct=no
-	hardcode_direct_absolute=no
-	;;
-      esac
+      file_list_spec='${wl}-f,'
 
-      if test yes = "$GCC"; then
+      if test "$GCC" = yes; then
 	case $host_os in aix4.[012]|aix4.[012].*)
 	# We only want to do this on AIX 4.2 and lower, the check
 	# below for broken collect2 doesn't work under 4.3+
-	  collect2name=`$CC -print-prog-name=collect2`
+	  collect2name=`${CC} -print-prog-name=collect2`
 	  if test -f "$collect2name" &&
 	   strings "$collect2name" | $GREP resolve_lib_name >/dev/null
 	  then
@@ -9840,42 +9496,36 @@ _LT_EOF
 	  ;;
 	esac
 	shared_flag='-shared'
-	if test yes = "$aix_use_runtimelinking"; then
-	  shared_flag="$shared_flag "'$wl-G'
+	if test "$aix_use_runtimelinking" = yes; then
+	  shared_flag="$shared_flag "'${wl}-G'
 	fi
-	# Need to ensure runtime linking is disabled for the traditional
-	# shared library, or the linker may eventually find shared libraries
-	# /with/ Import File - we do not want to mix them.
-	shared_flag_aix='-shared'
-	shared_flag_svr4='-shared $wl-G'
+	link_all_deplibs=no
       else
 	# not using gcc
-	if test ia64 = "$host_cpu"; then
+	if test "$host_cpu" = ia64; then
 	# VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release
 	# chokes on -Wl,-G. The following line is correct:
 	  shared_flag='-G'
 	else
-	  if test yes = "$aix_use_runtimelinking"; then
-	    shared_flag='$wl-G'
+	  if test "$aix_use_runtimelinking" = yes; then
+	    shared_flag='${wl}-G'
 	  else
-	    shared_flag='$wl-bM:SRE'
+	    shared_flag='${wl}-bM:SRE'
 	  fi
-	  shared_flag_aix='$wl-bM:SRE'
-	  shared_flag_svr4='$wl-G'
 	fi
       fi
 
-      export_dynamic_flag_spec='$wl-bexpall'
+      export_dynamic_flag_spec='${wl}-bexpall'
       # It seems that -bexpall does not export symbols beginning with
       # underscore (_), so it is better to generate a list of symbols to export.
       always_export_symbols=yes
-      if test aix,yes = "$with_aix_soname,$aix_use_runtimelinking"; then
+      if test "$aix_use_runtimelinking" = yes; then
 	# Warning - without using the other runtime loading flags (-brtl),
 	# -berok will link without error, but may produce a broken library.
 	allow_undefined_flag='-berok'
         # Determine the default libpath from the value encoded in an
         # empty executable.
-        if test set = "${lt_cv_aix_libpath+set}"; then
+        if test "${lt_cv_aix_libpath+set}" = set; then
   aix_libpath=$lt_cv_aix_libpath
 else
   if ${lt_cv_aix_libpath_+:} false; then :
@@ -9910,7 +9560,7 @@ fi
 rm -f core conftest.err conftest.$ac_objext \
     conftest$ac_exeext conftest.$ac_ext
   if test -z "$lt_cv_aix_libpath_"; then
-    lt_cv_aix_libpath_=/usr/lib:/lib
+    lt_cv_aix_libpath_="/usr/lib:/lib"
   fi
 
 fi
@@ -9918,17 +9568,17 @@ fi
   aix_libpath=$lt_cv_aix_libpath_
 fi
 
-        hardcode_libdir_flag_spec='$wl-blibpath:$libdir:'"$aix_libpath"
-        archive_expsym_cmds='$CC -o $output_objdir/$soname $libobjs $deplibs $wl'$no_entry_flag' $compiler_flags `if test -n "$allow_undefined_flag"; then func_echo_all "$wl$allow_undefined_flag"; else :; fi` $wl'$exp_sym_flag:\$export_symbols' '$shared_flag
+        hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath"
+        archive_expsym_cmds='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then func_echo_all "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag"
       else
-	if test ia64 = "$host_cpu"; then
-	  hardcode_libdir_flag_spec='$wl-R $libdir:/usr/lib:/lib'
+	if test "$host_cpu" = ia64; then
+	  hardcode_libdir_flag_spec='${wl}-R $libdir:/usr/lib:/lib'
 	  allow_undefined_flag="-z nodefs"
-	  archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\$wl$no_entry_flag"' $compiler_flags $wl$allow_undefined_flag '"\$wl$exp_sym_flag:\$export_symbols"
+	  archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols"
 	else
 	 # Determine the default libpath from the value encoded in an
 	 # empty executable.
-	 if test set = "${lt_cv_aix_libpath+set}"; then
+	 if test "${lt_cv_aix_libpath+set}" = set; then
   aix_libpath=$lt_cv_aix_libpath
 else
   if ${lt_cv_aix_libpath_+:} false; then :
@@ -9963,7 +9613,7 @@ fi
 rm -f core conftest.err conftest.$ac_objext \
     conftest$ac_exeext conftest.$ac_ext
   if test -z "$lt_cv_aix_libpath_"; then
-    lt_cv_aix_libpath_=/usr/lib:/lib
+    lt_cv_aix_libpath_="/usr/lib:/lib"
   fi
 
 fi
@@ -9971,33 +9621,21 @@ fi
   aix_libpath=$lt_cv_aix_libpath_
 fi
 
-	 hardcode_libdir_flag_spec='$wl-blibpath:$libdir:'"$aix_libpath"
+	 hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath"
 	  # Warning - without using the other run time loading flags,
 	  # -berok will link without error, but may produce a broken library.
-	  no_undefined_flag=' $wl-bernotok'
-	  allow_undefined_flag=' $wl-berok'
-	  if test yes = "$with_gnu_ld"; then
+	  no_undefined_flag=' ${wl}-bernotok'
+	  allow_undefined_flag=' ${wl}-berok'
+	  if test "$with_gnu_ld" = yes; then
 	    # We only use this code for GNU lds that support --whole-archive.
-	    whole_archive_flag_spec='$wl--whole-archive$convenience $wl--no-whole-archive'
+	    whole_archive_flag_spec='${wl}--whole-archive$convenience ${wl}--no-whole-archive'
 	  else
 	    # Exported symbols can be pulled into shared objects from archives
 	    whole_archive_flag_spec='$convenience'
 	  fi
 	  archive_cmds_need_lc=yes
-	  archive_expsym_cmds='$RM -r $output_objdir/$realname.d~$MKDIR $output_objdir/$realname.d'
-	  # -brtl affects multiple linker settings, -berok does not and is overridden later
-	  compiler_flags_filtered='`func_echo_all "$compiler_flags " | $SED -e "s%-brtl\\([, ]\\)%-berok\\1%g"`'
-	  if test svr4 != "$with_aix_soname"; then
-	    # This is similar to how AIX traditionally builds its shared libraries.
-	    archive_expsym_cmds="$archive_expsym_cmds"'~$CC '$shared_flag_aix' -o $output_objdir/$realname.d/$soname $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$realname.d/$soname'
-	  fi
-	  if test aix != "$with_aix_soname"; then
-	    archive_expsym_cmds="$archive_expsym_cmds"'~$CC '$shared_flag_svr4' -o $output_objdir/$realname.d/$shared_archive_member_spec.o $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$STRIP -e $output_objdir/$realname.d/$shared_archive_member_spec.o~( func_echo_all "#! $soname($shared_archive_member_spec.o)"; if test shr_64 = "$shared_archive_member_spec"; then func_echo_all "# 64"; else func_echo_all "# 32"; fi; cat $export_symbols ) >  [...]
-	  else
-	    # used by -dlpreopen to get the symbols
-	    archive_expsym_cmds="$archive_expsym_cmds"'~$MV  $output_objdir/$realname.d/$soname $output_objdir'
-	  fi
-	  archive_expsym_cmds="$archive_expsym_cmds"'~$RM -r $output_objdir/$realname.d'
+	  # This is similar to how AIX traditionally builds its shared libraries.
+	  archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname'
 	fi
       fi
       ;;
@@ -10006,7 +9644,7 @@ fi
       case $host_cpu in
       powerpc)
             # see comment about AmigaOS4 .so support
-            archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+            archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
             archive_expsym_cmds=''
         ;;
       m68k)
@@ -10036,17 +9674,16 @@ fi
 	# Tell ltmain to make .lib files, not .a files.
 	libext=lib
 	# Tell ltmain to make .dll files, not .so files.
-	shrext_cmds=.dll
+	shrext_cmds=".dll"
 	# FIXME: Setting linknames here is a bad hack.
-	archive_cmds='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~linknames='
-	archive_expsym_cmds='if   test DEF = "`$SED -n     -e '\''s/^[	 ]*//'\''     -e '\''/^\(;.*\)*$/d'\''     -e '\''s/^\(EXPORTS\|LIBRARY\)\([	 ].*\)*$/DEF/p'\''     -e q     $export_symbols`" ; then
-            cp "$export_symbols" "$output_objdir/$soname.def";
-            echo "$tool_output_objdir$soname.def" > "$output_objdir/$soname.exp";
-          else
-            $SED -e '\''s/^/-link -EXPORT:/'\'' < $export_symbols > $output_objdir/$soname.exp;
-          fi~
-          $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~
-          linknames='
+	archive_cmds='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-dll~linknames='
+	archive_expsym_cmds='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then
+	    sed -n -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' -e '1\\\!p' < $export_symbols > $output_objdir/$soname.exp;
+	  else
+	    sed -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' < $export_symbols > $output_objdir/$soname.exp;
+	  fi~
+	  $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~
+	  linknames='
 	# The linker will not automatically build a static lib if we build a DLL.
 	# _LT_TAGVAR(old_archive_from_new_cmds, )='true'
 	enable_shared_with_static_runtimes=yes
@@ -10055,18 +9692,18 @@ fi
 	# Don't use ranlib
 	old_postinstall_cmds='chmod 644 $oldlib'
 	postlink_cmds='lt_outputfile="@OUTPUT@"~
-          lt_tool_outputfile="@TOOL_OUTPUT@"~
-          case $lt_outputfile in
-            *.exe|*.EXE) ;;
-            *)
-              lt_outputfile=$lt_outputfile.exe
-              lt_tool_outputfile=$lt_tool_outputfile.exe
-              ;;
-          esac~
-          if test : != "$MANIFEST_TOOL" && test -f "$lt_outputfile.manifest"; then
-            $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1;
-            $RM "$lt_outputfile.manifest";
-          fi'
+	  lt_tool_outputfile="@TOOL_OUTPUT@"~
+	  case $lt_outputfile in
+	    *.exe|*.EXE) ;;
+	    *)
+	      lt_outputfile="$lt_outputfile.exe"
+	      lt_tool_outputfile="$lt_tool_outputfile.exe"
+	      ;;
+	  esac~
+	  if test "$MANIFEST_TOOL" != ":" && test -f "$lt_outputfile.manifest"; then
+	    $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1;
+	    $RM "$lt_outputfile.manifest";
+	  fi'
 	;;
       *)
 	# Assume MSVC wrapper
@@ -10075,7 +9712,7 @@ fi
 	# Tell ltmain to make .lib files, not .a files.
 	libext=lib
 	# Tell ltmain to make .dll files, not .so files.
-	shrext_cmds=.dll
+	shrext_cmds=".dll"
 	# FIXME: Setting linknames here is a bad hack.
 	archive_cmds='$CC -o $lib $libobjs $compiler_flags `func_echo_all "$deplibs" | $SED '\''s/ -lc$//'\''` -link -dll~linknames='
 	# The linker will automatically build a .lib file if we build a DLL.
@@ -10094,24 +9731,24 @@ fi
   hardcode_direct=no
   hardcode_automatic=yes
   hardcode_shlibpath_var=unsupported
-  if test yes = "$lt_cv_ld_force_load"; then
-    whole_archive_flag_spec='`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience $wl-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`'
+  if test "$lt_cv_ld_force_load" = "yes"; then
+    whole_archive_flag_spec='`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience ${wl}-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`'
 
   else
     whole_archive_flag_spec=''
   fi
   link_all_deplibs=yes
-  allow_undefined_flag=$_lt_dar_allow_undefined
+  allow_undefined_flag="$_lt_dar_allow_undefined"
   case $cc_basename in
-     ifort*|nagfor*) _lt_dar_can_shared=yes ;;
+     ifort*) _lt_dar_can_shared=yes ;;
      *) _lt_dar_can_shared=$GCC ;;
   esac
-  if test yes = "$_lt_dar_can_shared"; then
+  if test "$_lt_dar_can_shared" = "yes"; then
     output_verbose_link_cmd=func_echo_all
-    archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dsymutil"
-    module_cmds="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dsymutil"
-    archive_expsym_cmds="sed 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dar_export_syms$_lt_dsymutil"
-    module_expsym_cmds="sed -e 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dar_export_syms$_lt_dsymutil"
+    archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}"
+    module_cmds="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}"
+    archive_expsym_cmds="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}"
+    module_expsym_cmds="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}"
 
   else
   ld_shlibs=no
@@ -10153,33 +9790,33 @@ fi
       ;;
 
     hpux9*)
-      if test yes = "$GCC"; then
-	archive_cmds='$RM $output_objdir/$soname~$CC -shared $pic_flag $wl+b $wl$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib'
+      if test "$GCC" = yes; then
+	archive_cmds='$RM $output_objdir/$soname~$CC -shared $pic_flag ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
       else
-	archive_cmds='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib'
+	archive_cmds='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
       fi
-      hardcode_libdir_flag_spec='$wl+b $wl$libdir'
+      hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
       hardcode_libdir_separator=:
       hardcode_direct=yes
 
       # hardcode_minus_L: Not really in the search PATH,
       # but as the default location of the library.
       hardcode_minus_L=yes
-      export_dynamic_flag_spec='$wl-E'
+      export_dynamic_flag_spec='${wl}-E'
       ;;
 
     hpux10*)
-      if test yes,no = "$GCC,$with_gnu_ld"; then
-	archive_cmds='$CC -shared $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+      if test "$GCC" = yes && test "$with_gnu_ld" = no; then
+	archive_cmds='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
       else
 	archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'
       fi
-      if test no = "$with_gnu_ld"; then
-	hardcode_libdir_flag_spec='$wl+b $wl$libdir'
+      if test "$with_gnu_ld" = no; then
+	hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
 	hardcode_libdir_separator=:
 	hardcode_direct=yes
 	hardcode_direct_absolute=yes
-	export_dynamic_flag_spec='$wl-E'
+	export_dynamic_flag_spec='${wl}-E'
 	# hardcode_minus_L: Not really in the search PATH,
 	# but as the default location of the library.
 	hardcode_minus_L=yes
@@ -10187,25 +9824,25 @@ fi
       ;;
 
     hpux11*)
-      if test yes,no = "$GCC,$with_gnu_ld"; then
+      if test "$GCC" = yes && test "$with_gnu_ld" = no; then
 	case $host_cpu in
 	hppa*64*)
-	  archive_cmds='$CC -shared $wl+h $wl$soname -o $lib $libobjs $deplibs $compiler_flags'
+	  archive_cmds='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
 	  ;;
 	ia64*)
-	  archive_cmds='$CC -shared $pic_flag $wl+h $wl$soname $wl+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
+	  archive_cmds='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
 	  ;;
 	*)
-	  archive_cmds='$CC -shared $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+	  archive_cmds='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
 	  ;;
 	esac
       else
 	case $host_cpu in
 	hppa*64*)
-	  archive_cmds='$CC -b $wl+h $wl$soname -o $lib $libobjs $deplibs $compiler_flags'
+	  archive_cmds='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
 	  ;;
 	ia64*)
-	  archive_cmds='$CC -b $wl+h $wl$soname $wl+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
+	  archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
 	  ;;
 	*)
 
@@ -10217,7 +9854,7 @@ if ${lt_cv_prog_compiler__b+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   lt_cv_prog_compiler__b=no
-   save_LDFLAGS=$LDFLAGS
+   save_LDFLAGS="$LDFLAGS"
    LDFLAGS="$LDFLAGS -b"
    echo "$lt_simple_link_test_code" > conftest.$ac_ext
    if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then
@@ -10236,14 +9873,14 @@ else
      fi
    fi
    $RM -r conftest*
-   LDFLAGS=$save_LDFLAGS
+   LDFLAGS="$save_LDFLAGS"
 
 fi
 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler__b" >&5
 $as_echo "$lt_cv_prog_compiler__b" >&6; }
 
-if test yes = "$lt_cv_prog_compiler__b"; then
-    archive_cmds='$CC -b $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+if test x"$lt_cv_prog_compiler__b" = xyes; then
+    archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
 else
     archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'
 fi
@@ -10251,8 +9888,8 @@ fi
 	  ;;
 	esac
       fi
-      if test no = "$with_gnu_ld"; then
-	hardcode_libdir_flag_spec='$wl+b $wl$libdir'
+      if test "$with_gnu_ld" = no; then
+	hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
 	hardcode_libdir_separator=:
 
 	case $host_cpu in
@@ -10263,7 +9900,7 @@ fi
 	*)
 	  hardcode_direct=yes
 	  hardcode_direct_absolute=yes
-	  export_dynamic_flag_spec='$wl-E'
+	  export_dynamic_flag_spec='${wl}-E'
 
 	  # hardcode_minus_L: Not really in the search PATH,
 	  # but as the default location of the library.
@@ -10274,8 +9911,8 @@ fi
       ;;
 
     irix5* | irix6* | nonstopux*)
-      if test yes = "$GCC"; then
-	archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib'
+      if test "$GCC" = yes; then
+	archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
 	# Try to use the -exported_symbol ld option, if it does not
 	# work, assume that -exports_file does not work either and
 	# implicitly export all symbols.
@@ -10285,8 +9922,8 @@ $as_echo_n "checking whether the $host_os linker accepts -exported_symbol... " >
 if ${lt_cv_irix_exported_symbol+:} false; then :
   $as_echo_n "(cached) " >&6
 else
-  save_LDFLAGS=$LDFLAGS
-	   LDFLAGS="$LDFLAGS -shared $wl-exported_symbol ${wl}foo $wl-update_registry $wl/dev/null"
+  save_LDFLAGS="$LDFLAGS"
+	   LDFLAGS="$LDFLAGS -shared ${wl}-exported_symbol ${wl}foo ${wl}-update_registry ${wl}/dev/null"
 	   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
 int foo (void) { return 0; }
@@ -10298,35 +9935,24 @@ else
 fi
 rm -f core conftest.err conftest.$ac_objext \
     conftest$ac_exeext conftest.$ac_ext
-           LDFLAGS=$save_LDFLAGS
+           LDFLAGS="$save_LDFLAGS"
 fi
 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_irix_exported_symbol" >&5
 $as_echo "$lt_cv_irix_exported_symbol" >&6; }
-	if test yes = "$lt_cv_irix_exported_symbol"; then
-          archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations $wl-exports_file $wl$export_symbols -o $lib'
+	if test "$lt_cv_irix_exported_symbol" = yes; then
+          archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations ${wl}-exports_file ${wl}$export_symbols -o $lib'
 	fi
-	link_all_deplibs=no
       else
-	archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib'
-	archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -exports_file $export_symbols -o $lib'
+	archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib'
+	archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -exports_file $export_symbols -o $lib'
       fi
       archive_cmds_need_lc='no'
-      hardcode_libdir_flag_spec='$wl-rpath $wl$libdir'
+      hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
       hardcode_libdir_separator=:
       inherit_rpath=yes
       link_all_deplibs=yes
       ;;
 
-    linux*)
-      case $cc_basename in
-      tcc*)
-	# Fabrice Bellard et al's Tiny C Compiler
-	ld_shlibs=yes
-	archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
-	;;
-      esac
-      ;;
-
     netbsd* | netbsdelf*-gnu)
       if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
 	archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'  # a.out
@@ -10341,7 +9967,7 @@ $as_echo "$lt_cv_irix_exported_symbol" >&6; }
     newsos6)
       archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
       hardcode_direct=yes
-      hardcode_libdir_flag_spec='$wl-rpath $wl$libdir'
+      hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
       hardcode_libdir_separator=:
       hardcode_shlibpath_var=no
       ;;
@@ -10349,19 +9975,27 @@ $as_echo "$lt_cv_irix_exported_symbol" >&6; }
     *nto* | *qnx*)
       ;;
 
-    openbsd* | bitrig*)
+    openbsd*)
       if test -f /usr/libexec/ld.so; then
 	hardcode_direct=yes
 	hardcode_shlibpath_var=no
 	hardcode_direct_absolute=yes
-	if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then
+	if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
 	  archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
-	  archive_expsym_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags $wl-retain-symbols-file,$export_symbols'
-	  hardcode_libdir_flag_spec='$wl-rpath,$libdir'
-	  export_dynamic_flag_spec='$wl-E'
+	  archive_expsym_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols'
+	  hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
+	  export_dynamic_flag_spec='${wl}-E'
 	else
-	  archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
-	  hardcode_libdir_flag_spec='$wl-rpath,$libdir'
+	  case $host_os in
+	   openbsd[01].* | openbsd2.[0-7] | openbsd2.[0-7].*)
+	     archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+	     hardcode_libdir_flag_spec='-R$libdir'
+	     ;;
+	   *)
+	     archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+	     hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
+	     ;;
+	  esac
 	fi
       else
 	ld_shlibs=no
@@ -10372,53 +10006,33 @@ $as_echo "$lt_cv_irix_exported_symbol" >&6; }
       hardcode_libdir_flag_spec='-L$libdir'
       hardcode_minus_L=yes
       allow_undefined_flag=unsupported
-      shrext_cmds=.dll
-      archive_cmds='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~
-	$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~
-	$ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~
-	$ECHO EXPORTS >> $output_objdir/$libname.def~
-	emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~
-	$CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~
-	emximp -o $lib $output_objdir/$libname.def'
-      archive_expsym_cmds='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~
-	$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~
-	$ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~
-	$ECHO EXPORTS >> $output_objdir/$libname.def~
-	prefix_cmds="$SED"~
-	if test EXPORTS = "`$SED 1q $export_symbols`"; then
-	  prefix_cmds="$prefix_cmds -e 1d";
-	fi~
-	prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~
-	cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~
-	$CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~
-	emximp -o $lib $output_objdir/$libname.def'
-      old_archive_From_new_cmds='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def'
-      enable_shared_with_static_runtimes=yes
+      archive_cmds='$ECHO "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~echo DATA >> $output_objdir/$libname.def~echo " SINGLE NONSHARED" >> $output_objdir/$libname.def~echo EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def'
+      old_archive_from_new_cmds='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def'
       ;;
 
     osf3*)
-      if test yes = "$GCC"; then
-	allow_undefined_flag=' $wl-expect_unresolved $wl\*'
-	archive_cmds='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib'
+      if test "$GCC" = yes; then
+	allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*'
+	archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
       else
 	allow_undefined_flag=' -expect_unresolved \*'
-	archive_cmds='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib'
+	archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib'
       fi
       archive_cmds_need_lc='no'
-      hardcode_libdir_flag_spec='$wl-rpath $wl$libdir'
+      hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
       hardcode_libdir_separator=:
       ;;
 
     osf4* | osf5*)	# as osf3* with the addition of -msym flag
-      if test yes = "$GCC"; then
-	allow_undefined_flag=' $wl-expect_unresolved $wl\*'
-	archive_cmds='$CC -shared$allow_undefined_flag $pic_flag $libobjs $deplibs $compiler_flags $wl-msym $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib'
-	hardcode_libdir_flag_spec='$wl-rpath $wl$libdir'
+      if test "$GCC" = yes; then
+	allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*'
+	archive_cmds='$CC -shared${allow_undefined_flag} $pic_flag $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+	hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
       else
 	allow_undefined_flag=' -expect_unresolved \*'
-	archive_cmds='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib'
+	archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib'
 	archive_expsym_cmds='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~
-          $CC -shared$allow_undefined_flag $wl-input $wl$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib~$RM $lib.exp'
+	$CC -shared${allow_undefined_flag} ${wl}-input ${wl}$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib~$RM $lib.exp'
 
 	# Both c and cxx compiler support -rpath directly
 	hardcode_libdir_flag_spec='-rpath $libdir'
@@ -10429,24 +10043,24 @@ $as_echo "$lt_cv_irix_exported_symbol" >&6; }
 
     solaris*)
       no_undefined_flag=' -z defs'
-      if test yes = "$GCC"; then
-	wlarc='$wl'
-	archive_cmds='$CC -shared $pic_flag $wl-z ${wl}text $wl-h $wl$soname -o $lib $libobjs $deplibs $compiler_flags'
+      if test "$GCC" = yes; then
+	wlarc='${wl}'
+	archive_cmds='$CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
 	archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
-          $CC -shared $pic_flag $wl-z ${wl}text $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp'
+	  $CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp'
       else
 	case `$CC -V 2>&1` in
 	*"Compilers 5.0"*)
 	  wlarc=''
-	  archive_cmds='$LD -G$allow_undefined_flag -h $soname -o $lib $libobjs $deplibs $linker_flags'
+	  archive_cmds='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags'
 	  archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
-            $LD -G$allow_undefined_flag -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp'
+	  $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp'
 	  ;;
 	*)
-	  wlarc='$wl'
-	  archive_cmds='$CC -G$allow_undefined_flag -h $soname -o $lib $libobjs $deplibs $compiler_flags'
+	  wlarc='${wl}'
+	  archive_cmds='$CC -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $compiler_flags'
 	  archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
-            $CC -G$allow_undefined_flag -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp'
+	  $CC -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp'
 	  ;;
 	esac
       fi
@@ -10456,11 +10070,11 @@ $as_echo "$lt_cv_irix_exported_symbol" >&6; }
       solaris2.[0-5] | solaris2.[0-5].*) ;;
       *)
 	# The compiler driver will combine and reorder linker options,
-	# but understands '-z linker_flag'.  GCC discards it without '$wl',
+	# but understands `-z linker_flag'.  GCC discards it without `$wl',
 	# but is careful enough not to reorder.
 	# Supported since Solaris 2.6 (maybe 2.5.1?)
-	if test yes = "$GCC"; then
-	  whole_archive_flag_spec='$wl-z ${wl}allextract$convenience $wl-z ${wl}defaultextract'
+	if test "$GCC" = yes; then
+	  whole_archive_flag_spec='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract'
 	else
 	  whole_archive_flag_spec='-z allextract$convenience -z defaultextract'
 	fi
@@ -10470,10 +10084,10 @@ $as_echo "$lt_cv_irix_exported_symbol" >&6; }
       ;;
 
     sunos4*)
-      if test sequent = "$host_vendor"; then
+      if test "x$host_vendor" = xsequent; then
 	# Use $CC to link under sequent, because it throws in some extra .o
 	# files that make .init and .fini sections work.
-	archive_cmds='$CC -G $wl-h $soname -o $lib $libobjs $deplibs $compiler_flags'
+	archive_cmds='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags'
       else
 	archive_cmds='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags'
       fi
@@ -10522,43 +10136,43 @@ $as_echo "$lt_cv_irix_exported_symbol" >&6; }
       ;;
 
     sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*)
-      no_undefined_flag='$wl-z,text'
+      no_undefined_flag='${wl}-z,text'
       archive_cmds_need_lc=no
       hardcode_shlibpath_var=no
       runpath_var='LD_RUN_PATH'
 
-      if test yes = "$GCC"; then
-	archive_cmds='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
-	archive_expsym_cmds='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+      if test "$GCC" = yes; then
+	archive_cmds='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	archive_expsym_cmds='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
       else
-	archive_cmds='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
-	archive_expsym_cmds='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	archive_cmds='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	archive_expsym_cmds='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
       fi
       ;;
 
     sysv5* | sco3.2v5* | sco5v6*)
-      # Note: We CANNOT use -z defs as we might desire, because we do not
+      # Note: We can NOT use -z defs as we might desire, because we do not
       # link with -lc, and that would cause any symbols used from libc to
       # always be unresolved, which means just about no library would
       # ever link correctly.  If we're not using GNU ld we use -z text
       # though, which does catch some bad symbols but isn't as heavy-handed
       # as -z defs.
-      no_undefined_flag='$wl-z,text'
-      allow_undefined_flag='$wl-z,nodefs'
+      no_undefined_flag='${wl}-z,text'
+      allow_undefined_flag='${wl}-z,nodefs'
       archive_cmds_need_lc=no
       hardcode_shlibpath_var=no
-      hardcode_libdir_flag_spec='$wl-R,$libdir'
+      hardcode_libdir_flag_spec='${wl}-R,$libdir'
       hardcode_libdir_separator=':'
       link_all_deplibs=yes
-      export_dynamic_flag_spec='$wl-Bexport'
+      export_dynamic_flag_spec='${wl}-Bexport'
       runpath_var='LD_RUN_PATH'
 
-      if test yes = "$GCC"; then
-	archive_cmds='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
-	archive_expsym_cmds='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+      if test "$GCC" = yes; then
+	archive_cmds='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	archive_expsym_cmds='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
       else
-	archive_cmds='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
-	archive_expsym_cmds='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	archive_cmds='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	archive_expsym_cmds='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
       fi
       ;;
 
@@ -10573,10 +10187,10 @@ $as_echo "$lt_cv_irix_exported_symbol" >&6; }
       ;;
     esac
 
-    if test sni = "$host_vendor"; then
+    if test x$host_vendor = xsni; then
       case $host in
       sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*)
-	export_dynamic_flag_spec='$wl-Blargedynsym'
+	export_dynamic_flag_spec='${wl}-Blargedynsym'
 	;;
       esac
     fi
@@ -10584,7 +10198,7 @@ $as_echo "$lt_cv_irix_exported_symbol" >&6; }
 
 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs" >&5
 $as_echo "$ld_shlibs" >&6; }
-test no = "$ld_shlibs" && can_build_shared=no
+test "$ld_shlibs" = no && can_build_shared=no
 
 with_gnu_ld=$with_gnu_ld
 
@@ -10610,7 +10224,7 @@ x|xyes)
   # Assume -lc should be added
   archive_cmds_need_lc=yes
 
-  if test yes,yes = "$GCC,$enable_shared"; then
+  if test "$enable_shared" = yes && test "$GCC" = yes; then
     case $archive_cmds in
     *'~'*)
       # FIXME: we may have to deal with multi-command sequences.
@@ -10825,14 +10439,14 @@ esac
   { $as_echo "$as_me:${as_lineno-$LINENO}: checking dynamic linker characteristics" >&5
 $as_echo_n "checking dynamic linker characteristics... " >&6; }
 
-if test yes = "$GCC"; then
+if test "$GCC" = yes; then
   case $host_os in
-    darwin*) lt_awk_arg='/^libraries:/,/LR/' ;;
-    *) lt_awk_arg='/^libraries:/' ;;
+    darwin*) lt_awk_arg="/^libraries:/,/LR/" ;;
+    *) lt_awk_arg="/^libraries:/" ;;
   esac
   case $host_os in
-    mingw* | cegcc*) lt_sed_strip_eq='s|=\([A-Za-z]:\)|\1|g' ;;
-    *) lt_sed_strip_eq='s|=/|/|g' ;;
+    mingw* | cegcc*) lt_sed_strip_eq="s,=\([A-Za-z]:\),\1,g" ;;
+    *) lt_sed_strip_eq="s,=/,/,g" ;;
   esac
   lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e $lt_sed_strip_eq`
   case $lt_search_path_spec in
@@ -10848,35 +10462,28 @@ if test yes = "$GCC"; then
     ;;
   esac
   # Ok, now we have the path, separated by spaces, we can step through it
-  # and add multilib dir if necessary...
+  # and add multilib dir if necessary.
   lt_tmp_lt_search_path_spec=
-  lt_multi_os_dir=/`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null`
-  # ...but if some path component already ends with the multilib dir we assume
-  # that all is fine and trust -print-search-dirs as is (GCC 4.2? or newer).
-  case "$lt_multi_os_dir; $lt_search_path_spec " in
-  "/; "* | "/.; "* | "/./; "* | *"$lt_multi_os_dir "* | *"$lt_multi_os_dir/ "*)
-    lt_multi_os_dir=
-    ;;
-  esac
+  lt_multi_os_dir=`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null`
   for lt_sys_path in $lt_search_path_spec; do
-    if test -d "$lt_sys_path$lt_multi_os_dir"; then
-      lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path$lt_multi_os_dir"
-    elif test -n "$lt_multi_os_dir"; then
+    if test -d "$lt_sys_path/$lt_multi_os_dir"; then
+      lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path/$lt_multi_os_dir"
+    else
       test -d "$lt_sys_path" && \
 	lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path"
     fi
   done
   lt_search_path_spec=`$ECHO "$lt_tmp_lt_search_path_spec" | awk '
-BEGIN {RS = " "; FS = "/|\n";} {
-  lt_foo = "";
-  lt_count = 0;
+BEGIN {RS=" "; FS="/|\n";} {
+  lt_foo="";
+  lt_count=0;
   for (lt_i = NF; lt_i > 0; lt_i--) {
     if ($lt_i != "" && $lt_i != ".") {
       if ($lt_i == "..") {
         lt_count++;
       } else {
         if (lt_count == 0) {
-          lt_foo = "/" $lt_i lt_foo;
+          lt_foo="/" $lt_i lt_foo;
         } else {
           lt_count--;
         }
@@ -10890,7 +10497,7 @@ BEGIN {RS = " "; FS = "/|\n";} {
   # for these hosts.
   case $host_os in
     mingw* | cegcc*) lt_search_path_spec=`$ECHO "$lt_search_path_spec" |\
-      $SED 's|/\([A-Za-z]:\)|\1|g'` ;;
+      $SED 's,/\([A-Za-z]:\),\1,g'` ;;
   esac
   sys_lib_search_path_spec=`$ECHO "$lt_search_path_spec" | $lt_NL2SP`
 else
@@ -10899,7 +10506,7 @@ fi
 library_names_spec=
 libname_spec='lib$name'
 soname_spec=
-shrext_cmds=.so
+shrext_cmds=".so"
 postinstall_cmds=
 postuninstall_cmds=
 finish_cmds=
@@ -10916,16 +10523,14 @@ hardcode_into_libs=no
 # flags to be left without arguments
 need_version=unknown
 
-
-
 case $host_os in
 aix3*)
   version_type=linux # correct to gnu/linux during the next big refactor
-  library_names_spec='$libname$release$shared_ext$versuffix $libname.a'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a'
   shlibpath_var=LIBPATH
 
   # AIX 3 has no versioning support, so we append a major version to the name.
-  soname_spec='$libname$release$shared_ext$major'
+  soname_spec='${libname}${release}${shared_ext}$major'
   ;;
 
 aix[4-9]*)
@@ -10933,91 +10538,41 @@ aix[4-9]*)
   need_lib_prefix=no
   need_version=no
   hardcode_into_libs=yes
-  if test ia64 = "$host_cpu"; then
+  if test "$host_cpu" = ia64; then
     # AIX 5 supports IA64
-    library_names_spec='$libname$release$shared_ext$major $libname$release$shared_ext$versuffix $libname$shared_ext'
+    library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}'
     shlibpath_var=LD_LIBRARY_PATH
   else
     # With GCC up to 2.95.x, collect2 would create an import file
     # for dependence libraries.  The import file would start with
-    # the line '#! .'.  This would cause the generated library to
-    # depend on '.', always an invalid library.  This was fixed in
+    # the line `#! .'.  This would cause the generated library to
+    # depend on `.', always an invalid library.  This was fixed in
     # development snapshots of GCC prior to 3.0.
     case $host_os in
       aix4 | aix4.[01] | aix4.[01].*)
       if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)'
 	   echo ' yes '
-	   echo '#endif'; } | $CC -E - | $GREP yes > /dev/null; then
+	   echo '#endif'; } | ${CC} -E - | $GREP yes > /dev/null; then
 	:
       else
 	can_build_shared=no
       fi
       ;;
     esac
-    # Using Import Files as archive members, it is possible to support
-    # filename-based versioning of shared library archives on AIX. While
-    # this would work for both with and without runtime linking, it will
-    # prevent static linking of such archives. So we do filename-based
-    # shared library versioning with .so extension only, which is used
-    # when both runtime linking and shared linking is enabled.
-    # Unfortunately, runtime linking may impact performance, so we do
-    # not want this to be the default eventually. Also, we use the
-    # versioned .so libs for executables only if there is the -brtl
-    # linker flag in LDFLAGS as well, or --with-aix-soname=svr4 only.
-    # To allow for filename-based versioning support, we need to create
-    # libNAME.so.V as an archive file, containing:
-    # *) an Import File, referring to the versioned filename of the
-    #    archive as well as the shared archive member, telling the
-    #    bitwidth (32 or 64) of that shared object, and providing the
-    #    list of exported symbols of that shared object, eventually
-    #    decorated with the 'weak' keyword
-    # *) the shared object with the F_LOADONLY flag set, to really avoid
-    #    it being seen by the linker.
-    # At run time we better use the real file rather than another symlink,
-    # but for link time we create the symlink libNAME.so -> libNAME.so.V
-
-    case $with_aix_soname,$aix_use_runtimelinking in
-    # AIX (on Power*) has no versioning support, so currently we cannot hardcode correct
+    # AIX (on Power*) has no versioning support, so currently we can not hardcode correct
     # soname into executable. Probably we can add versioning support to
     # collect2, so additional links can be useful in future.
-    aix,yes) # traditional libtool
-      dynamic_linker='AIX unversionable lib.so'
+    if test "$aix_use_runtimelinking" = yes; then
       # If using run time linking (on AIX 4.2 or later) use lib<name>.so
       # instead of lib<name>.a to let people know that these are not
       # typical AIX shared libraries.
-      library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
-      ;;
-    aix,no) # traditional AIX only
-      dynamic_linker='AIX lib.a(lib.so.V)'
+      library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+    else
       # We preserve .a as extension for shared libraries through AIX4.2
       # and later when we are not doing run time linking.
-      library_names_spec='$libname$release.a $libname.a'
-      soname_spec='$libname$release$shared_ext$major'
-      ;;
-    svr4,*) # full svr4 only
-      dynamic_linker="AIX lib.so.V($shared_archive_member_spec.o)"
-      library_names_spec='$libname$release$shared_ext$major $libname$shared_ext'
-      # We do not specify a path in Import Files, so LIBPATH fires.
-      shlibpath_overrides_runpath=yes
-      ;;
-    *,yes) # both, prefer svr4
-      dynamic_linker="AIX lib.so.V($shared_archive_member_spec.o), lib.a(lib.so.V)"
-      library_names_spec='$libname$release$shared_ext$major $libname$shared_ext'
-      # unpreferred sharedlib libNAME.a needs extra handling
-      postinstall_cmds='test -n "$linkname" || linkname="$realname"~func_stripname "" ".so" "$linkname"~$install_shared_prog "$dir/$func_stripname_result.$libext" "$destdir/$func_stripname_result.$libext"~test -z "$tstripme" || test -z "$striplib" || $striplib "$destdir/$func_stripname_result.$libext"'
-      postuninstall_cmds='for n in $library_names $old_library; do :; done~func_stripname "" ".so" "$n"~test "$func_stripname_result" = "$n" || func_append rmfiles " $odir/$func_stripname_result.$libext"'
-      # We do not specify a path in Import Files, so LIBPATH fires.
-      shlibpath_overrides_runpath=yes
-      ;;
-    *,no) # both, prefer aix
-      dynamic_linker="AIX lib.a(lib.so.V), lib.so.V($shared_archive_member_spec.o)"
-      library_names_spec='$libname$release.a $libname.a'
-      soname_spec='$libname$release$shared_ext$major'
-      # unpreferred sharedlib libNAME.so.V and symlink libNAME.so need extra handling
-      postinstall_cmds='test -z "$dlname" || $install_shared_prog $dir/$dlname $destdir/$dlname~test -z "$tstripme" || test -z "$striplib" || $striplib $destdir/$dlname~test -n "$linkname" || linkname=$realname~func_stripname "" ".a" "$linkname"~(cd "$destdir" && $LN_S -f $dlname $func_stripname_result.so)'
-      postuninstall_cmds='test -z "$dlname" || func_append rmfiles " $odir/$dlname"~for n in $old_library $library_names; do :; done~func_stripname "" ".a" "$n"~func_append rmfiles " $odir/$func_stripname_result.so"'
-      ;;
-    esac
+      library_names_spec='${libname}${release}.a $libname.a'
+      soname_spec='${libname}${release}${shared_ext}$major'
+    fi
     shlibpath_var=LIBPATH
   fi
   ;;
@@ -11027,18 +10582,18 @@ amigaos*)
   powerpc)
     # Since July 2007 AmigaOS4 officially supports .so libraries.
     # When compiling the executable, add -use-dynld -Lsobjs: to the compileline.
-    library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
     ;;
   m68k)
     library_names_spec='$libname.ixlibrary $libname.a'
     # Create ${libname}_ixlibrary.a entries in /sys/libs.
-    finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done'
+    finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done'
     ;;
   esac
   ;;
 
 beos*)
-  library_names_spec='$libname$shared_ext'
+  library_names_spec='${libname}${shared_ext}'
   dynamic_linker="$host_os ld.so"
   shlibpath_var=LIBRARY_PATH
   ;;
@@ -11046,8 +10601,8 @@ beos*)
 bsdi[45]*)
   version_type=linux # correct to gnu/linux during the next big refactor
   need_version=no
-  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
-  soname_spec='$libname$release$shared_ext$major'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
   finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir'
   shlibpath_var=LD_LIBRARY_PATH
   sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib"
@@ -11059,7 +10614,7 @@ bsdi[45]*)
 
 cygwin* | mingw* | pw32* | cegcc*)
   version_type=windows
-  shrext_cmds=.dll
+  shrext_cmds=".dll"
   need_version=no
   need_lib_prefix=no
 
@@ -11068,8 +10623,8 @@ cygwin* | mingw* | pw32* | cegcc*)
     # gcc
     library_names_spec='$libname.dll.a'
     # DLL is installed to $(libdir)/../bin by postinstall_cmds
-    postinstall_cmds='base_file=`basename \$file`~
-      dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~
+    postinstall_cmds='base_file=`basename \${file}`~
+      dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~
       dldir=$destdir/`dirname \$dlpath`~
       test -d \$dldir || mkdir -p \$dldir~
       $install_prog $dir/$dlname \$dldir/$dlname~
@@ -11085,17 +10640,17 @@ cygwin* | mingw* | pw32* | cegcc*)
     case $host_os in
     cygwin*)
       # Cygwin DLLs use 'cyg' prefix rather than 'lib'
-      soname_spec='`echo $libname | sed -e 's/^lib/cyg/'``echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext'
+      soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
 
       sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/lib/w32api"
       ;;
     mingw* | cegcc*)
       # MinGW DLLs use traditional 'lib' prefix
-      soname_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext'
+      soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
       ;;
     pw32*)
       # pw32 DLLs use 'pw' prefix rather than 'lib'
-      library_names_spec='`echo $libname | sed -e 's/^lib/pw/'``echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext'
+      library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
       ;;
     esac
     dynamic_linker='Win32 ld.exe'
@@ -11104,8 +10659,8 @@ cygwin* | mingw* | pw32* | cegcc*)
   *,cl*)
     # Native MSVC
     libname_spec='$name'
-    soname_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext'
-    library_names_spec='$libname.dll.lib'
+    soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
+    library_names_spec='${libname}.dll.lib'
 
     case $build_os in
     mingw*)
@@ -11132,7 +10687,7 @@ cygwin* | mingw* | pw32* | cegcc*)
       sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"`
       ;;
     *)
-      sys_lib_search_path_spec=$LIB
+      sys_lib_search_path_spec="$LIB"
       if $ECHO "$sys_lib_search_path_spec" | $GREP ';[c-zC-Z]:/' >/dev/null; then
         # It is most probably a Windows format PATH.
         sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'`
@@ -11145,8 +10700,8 @@ cygwin* | mingw* | pw32* | cegcc*)
     esac
 
     # DLL is installed to $(libdir)/../bin by postinstall_cmds
-    postinstall_cmds='base_file=`basename \$file`~
-      dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~
+    postinstall_cmds='base_file=`basename \${file}`~
+      dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~
       dldir=$destdir/`dirname \$dlpath`~
       test -d \$dldir || mkdir -p \$dldir~
       $install_prog $dir/$dlname \$dldir/$dlname'
@@ -11159,7 +10714,7 @@ cygwin* | mingw* | pw32* | cegcc*)
 
   *)
     # Assume MSVC wrapper
-    library_names_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext $libname.lib'
+    library_names_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext} $libname.lib'
     dynamic_linker='Win32 ld.exe'
     ;;
   esac
@@ -11172,8 +10727,8 @@ darwin* | rhapsody*)
   version_type=darwin
   need_lib_prefix=no
   need_version=no
-  library_names_spec='$libname$release$major$shared_ext $libname$shared_ext'
-  soname_spec='$libname$release$major$shared_ext'
+  library_names_spec='${libname}${release}${major}$shared_ext ${libname}$shared_ext'
+  soname_spec='${libname}${release}${major}$shared_ext'
   shlibpath_overrides_runpath=yes
   shlibpath_var=DYLD_LIBRARY_PATH
   shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`'
@@ -11186,8 +10741,8 @@ dgux*)
   version_type=linux # correct to gnu/linux during the next big refactor
   need_lib_prefix=no
   need_version=no
-  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
-  soname_spec='$libname$release$shared_ext$major'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext'
+  soname_spec='${libname}${release}${shared_ext}$major'
   shlibpath_var=LD_LIBRARY_PATH
   ;;
 
@@ -11205,13 +10760,12 @@ freebsd* | dragonfly*)
   version_type=freebsd-$objformat
   case $version_type in
     freebsd-elf*)
-      library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
-      soname_spec='$libname$release$shared_ext$major'
+      library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}'
       need_version=no
       need_lib_prefix=no
       ;;
     freebsd-*)
-      library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix'
+      library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix'
       need_version=yes
       ;;
   esac
@@ -11241,10 +10795,10 @@ haiku*)
   need_lib_prefix=no
   need_version=no
   dynamic_linker="$host_os runtime_loader"
-  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
-  soname_spec='$libname$release$shared_ext$major'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
   shlibpath_var=LIBRARY_PATH
-  shlibpath_overrides_runpath=no
+  shlibpath_overrides_runpath=yes
   sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib'
   hardcode_into_libs=yes
   ;;
@@ -11262,15 +10816,14 @@ hpux9* | hpux10* | hpux11*)
     dynamic_linker="$host_os dld.so"
     shlibpath_var=LD_LIBRARY_PATH
     shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
-    library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
-    soname_spec='$libname$release$shared_ext$major'
-    if test 32 = "$HPUX_IA64_MODE"; then
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+    soname_spec='${libname}${release}${shared_ext}$major'
+    if test "X$HPUX_IA64_MODE" = X32; then
       sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib"
-      sys_lib_dlsearch_path_spec=/usr/lib/hpux32
     else
       sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64"
-      sys_lib_dlsearch_path_spec=/usr/lib/hpux64
     fi
+    sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
     ;;
   hppa*64*)
     shrext_cmds='.sl'
@@ -11278,8 +10831,8 @@ hpux9* | hpux10* | hpux11*)
     dynamic_linker="$host_os dld.sl"
     shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH
     shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
-    library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
-    soname_spec='$libname$release$shared_ext$major'
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+    soname_spec='${libname}${release}${shared_ext}$major'
     sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64"
     sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
     ;;
@@ -11288,8 +10841,8 @@ hpux9* | hpux10* | hpux11*)
     dynamic_linker="$host_os dld.sl"
     shlibpath_var=SHLIB_PATH
     shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH
-    library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
-    soname_spec='$libname$release$shared_ext$major'
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+    soname_spec='${libname}${release}${shared_ext}$major'
     ;;
   esac
   # HP-UX runs *really* slowly unless shared libraries are mode 555, ...
@@ -11302,8 +10855,8 @@ interix[3-9]*)
   version_type=linux # correct to gnu/linux during the next big refactor
   need_lib_prefix=no
   need_version=no
-  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
-  soname_spec='$libname$release$shared_ext$major'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
   dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)'
   shlibpath_var=LD_LIBRARY_PATH
   shlibpath_overrides_runpath=no
@@ -11314,7 +10867,7 @@ irix5* | irix6* | nonstopux*)
   case $host_os in
     nonstopux*) version_type=nonstopux ;;
     *)
-	if test yes = "$lt_cv_prog_gnu_ld"; then
+	if test "$lt_cv_prog_gnu_ld" = yes; then
 		version_type=linux # correct to gnu/linux during the next big refactor
 	else
 		version_type=irix
@@ -11322,8 +10875,8 @@ irix5* | irix6* | nonstopux*)
   esac
   need_lib_prefix=no
   need_version=no
-  soname_spec='$libname$release$shared_ext$major'
-  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$release$shared_ext $libname$shared_ext'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}'
   case $host_os in
   irix5* | nonstopux*)
     libsuff= shlibsuff=
@@ -11342,8 +10895,8 @@ irix5* | irix6* | nonstopux*)
   esac
   shlibpath_var=LD_LIBRARY${shlibsuff}_PATH
   shlibpath_overrides_runpath=no
-  sys_lib_search_path_spec="/usr/lib$libsuff /lib$libsuff /usr/local/lib$libsuff"
-  sys_lib_dlsearch_path_spec="/usr/lib$libsuff /lib$libsuff"
+  sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}"
+  sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}"
   hardcode_into_libs=yes
   ;;
 
@@ -11352,33 +10905,13 @@ linux*oldld* | linux*aout* | linux*coff*)
   dynamic_linker=no
   ;;
 
-linux*android*)
-  version_type=none # Android doesn't support versioned libraries.
-  need_lib_prefix=no
-  need_version=no
-  library_names_spec='$libname$release$shared_ext'
-  soname_spec='$libname$release$shared_ext'
-  finish_cmds=
-  shlibpath_var=LD_LIBRARY_PATH
-  shlibpath_overrides_runpath=yes
-
-  # This implies no fast_install, which is unacceptable.
-  # Some rework will be needed to allow for fast_install
-  # before this can be enabled.
-  hardcode_into_libs=yes
-
-  dynamic_linker='Android linker'
-  # Don't embed -rpath directories since the linker doesn't support them.
-  hardcode_libdir_flag_spec='-L$libdir'
-  ;;
-
 # This must be glibc/ELF.
 linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*)
   version_type=linux # correct to gnu/linux during the next big refactor
   need_lib_prefix=no
   need_version=no
-  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
-  soname_spec='$libname$release$shared_ext$major'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
   finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir'
   shlibpath_var=LD_LIBRARY_PATH
   shlibpath_overrides_runpath=no
@@ -11422,12 +10955,7 @@ fi
   # before this can be enabled.
   hardcode_into_libs=yes
 
-  # Ideally, we could use ldconfig to report *all* directores which are
-  # searched for libraries, however this is still not possible.  Aside from not
-  # being certain /sbin/ldconfig is available, command
-  # 'ldconfig -N -X -v | grep ^/' on 64bit Fedora does not report /usr/lib64,
-  # even though it is searched at run-time.  Try to do the best guess by
-  # appending ld.so.conf contents (and includes) to the search path.
+  # Append ld.so.conf contents to the search path
   if test -f /etc/ld.so.conf; then
     lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[	 ]*hwcap[	 ]/d;s/[:,	]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '`
     sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra"
@@ -11459,12 +10987,12 @@ netbsd*)
   need_lib_prefix=no
   need_version=no
   if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
-    library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix'
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
     finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
     dynamic_linker='NetBSD (a.out) ld.so'
   else
-    library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
-    soname_spec='$libname$release$shared_ext$major'
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+    soname_spec='${libname}${release}${shared_ext}$major'
     dynamic_linker='NetBSD ld.elf_so'
   fi
   shlibpath_var=LD_LIBRARY_PATH
@@ -11474,7 +11002,7 @@ netbsd*)
 
 newsos6)
   version_type=linux # correct to gnu/linux during the next big refactor
-  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
   shlibpath_var=LD_LIBRARY_PATH
   shlibpath_overrides_runpath=yes
   ;;
@@ -11483,68 +11011,58 @@ newsos6)
   version_type=qnx
   need_lib_prefix=no
   need_version=no
-  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
-  soname_spec='$libname$release$shared_ext$major'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
   shlibpath_var=LD_LIBRARY_PATH
   shlibpath_overrides_runpath=no
   hardcode_into_libs=yes
   dynamic_linker='ldqnx.so'
   ;;
 
-openbsd* | bitrig*)
+openbsd*)
   version_type=sunos
-  sys_lib_dlsearch_path_spec=/usr/lib
+  sys_lib_dlsearch_path_spec="/usr/lib"
   need_lib_prefix=no
-  if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then
-    need_version=no
-  else
-    need_version=yes
-  fi
-  library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix'
+  # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs.
+  case $host_os in
+    openbsd3.3 | openbsd3.3.*)	need_version=yes ;;
+    *)				need_version=no  ;;
+  esac
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
   finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
   shlibpath_var=LD_LIBRARY_PATH
-  shlibpath_overrides_runpath=yes
+  if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+    case $host_os in
+      openbsd2.[89] | openbsd2.[89].*)
+	shlibpath_overrides_runpath=no
+	;;
+      *)
+	shlibpath_overrides_runpath=yes
+	;;
+      esac
+  else
+    shlibpath_overrides_runpath=yes
+  fi
   ;;
 
 os2*)
   libname_spec='$name'
-  version_type=windows
-  shrext_cmds=.dll
-  need_version=no
+  shrext_cmds=".dll"
   need_lib_prefix=no
-  # OS/2 can only load a DLL with a base name of 8 characters or less.
-  soname_spec='`test -n "$os2dllname" && libname="$os2dllname";
-    v=$($ECHO $release$versuffix | tr -d .-);
-    n=$($ECHO $libname | cut -b -$((8 - ${#v})) | tr . _);
-    $ECHO $n$v`$shared_ext'
-  library_names_spec='${libname}_dll.$libext'
+  library_names_spec='$libname${shared_ext} $libname.a'
   dynamic_linker='OS/2 ld.exe'
-  shlibpath_var=BEGINLIBPATH
-  sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib"
-  sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
-  postinstall_cmds='base_file=`basename \$file`~
-    dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; $ECHO \$dlname'\''`~
-    dldir=$destdir/`dirname \$dlpath`~
-    test -d \$dldir || mkdir -p \$dldir~
-    $install_prog $dir/$dlname \$dldir/$dlname~
-    chmod a+x \$dldir/$dlname~
-    if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then
-      eval '\''$striplib \$dldir/$dlname'\'' || exit \$?;
-    fi'
-  postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; $ECHO \$dlname'\''`~
-    dlpath=$dir/\$dldll~
-    $RM \$dlpath'
+  shlibpath_var=LIBPATH
   ;;
 
 osf3* | osf4* | osf5*)
   version_type=osf
   need_lib_prefix=no
   need_version=no
-  soname_spec='$libname$release$shared_ext$major'
-  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
   shlibpath_var=LD_LIBRARY_PATH
   sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib"
-  sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
+  sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec"
   ;;
 
 rdos*)
@@ -11555,8 +11073,8 @@ solaris*)
   version_type=linux # correct to gnu/linux during the next big refactor
   need_lib_prefix=no
   need_version=no
-  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
-  soname_spec='$libname$release$shared_ext$major'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
   shlibpath_var=LD_LIBRARY_PATH
   shlibpath_overrides_runpath=yes
   hardcode_into_libs=yes
@@ -11566,11 +11084,11 @@ solaris*)
 
 sunos4*)
   version_type=sunos
-  library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
   finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir'
   shlibpath_var=LD_LIBRARY_PATH
   shlibpath_overrides_runpath=yes
-  if test yes = "$with_gnu_ld"; then
+  if test "$with_gnu_ld" = yes; then
     need_lib_prefix=no
   fi
   need_version=yes
@@ -11578,8 +11096,8 @@ sunos4*)
 
 sysv4 | sysv4.3*)
   version_type=linux # correct to gnu/linux during the next big refactor
-  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
-  soname_spec='$libname$release$shared_ext$major'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
   shlibpath_var=LD_LIBRARY_PATH
   case $host_vendor in
     sni)
@@ -11600,24 +11118,24 @@ sysv4 | sysv4.3*)
   ;;
 
 sysv4*MP*)
-  if test -d /usr/nec; then
+  if test -d /usr/nec ;then
     version_type=linux # correct to gnu/linux during the next big refactor
-    library_names_spec='$libname$shared_ext.$versuffix $libname$shared_ext.$major $libname$shared_ext'
-    soname_spec='$libname$shared_ext.$major'
+    library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}'
+    soname_spec='$libname${shared_ext}.$major'
     shlibpath_var=LD_LIBRARY_PATH
   fi
   ;;
 
 sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
-  version_type=sco
+  version_type=freebsd-elf
   need_lib_prefix=no
   need_version=no
-  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext $libname$shared_ext'
-  soname_spec='$libname$release$shared_ext$major'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
   shlibpath_var=LD_LIBRARY_PATH
   shlibpath_overrides_runpath=yes
   hardcode_into_libs=yes
-  if test yes = "$with_gnu_ld"; then
+  if test "$with_gnu_ld" = yes; then
     sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib'
   else
     sys_lib_search_path_spec='/usr/ccs/lib /usr/lib'
@@ -11635,7 +11153,7 @@ tpf*)
   version_type=linux # correct to gnu/linux during the next big refactor
   need_lib_prefix=no
   need_version=no
-  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
   shlibpath_var=LD_LIBRARY_PATH
   shlibpath_overrides_runpath=no
   hardcode_into_libs=yes
@@ -11643,8 +11161,8 @@ tpf*)
 
 uts4*)
   version_type=linux # correct to gnu/linux during the next big refactor
-  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
-  soname_spec='$libname$release$shared_ext$major'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
   shlibpath_var=LD_LIBRARY_PATH
   ;;
 
@@ -11654,35 +11172,20 @@ uts4*)
 esac
 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $dynamic_linker" >&5
 $as_echo "$dynamic_linker" >&6; }
-test no = "$dynamic_linker" && can_build_shared=no
+test "$dynamic_linker" = no && can_build_shared=no
 
 variables_saved_for_relink="PATH $shlibpath_var $runpath_var"
-if test yes = "$GCC"; then
+if test "$GCC" = yes; then
   variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH"
 fi
 
-if test set = "${lt_cv_sys_lib_search_path_spec+set}"; then
-  sys_lib_search_path_spec=$lt_cv_sys_lib_search_path_spec
+if test "${lt_cv_sys_lib_search_path_spec+set}" = set; then
+  sys_lib_search_path_spec="$lt_cv_sys_lib_search_path_spec"
 fi
-
-if test set = "${lt_cv_sys_lib_dlsearch_path_spec+set}"; then
-  sys_lib_dlsearch_path_spec=$lt_cv_sys_lib_dlsearch_path_spec
+if test "${lt_cv_sys_lib_dlsearch_path_spec+set}" = set; then
+  sys_lib_dlsearch_path_spec="$lt_cv_sys_lib_dlsearch_path_spec"
 fi
 
-# remember unaugmented sys_lib_dlsearch_path content for libtool script decls...
-configure_time_dlsearch_path=$sys_lib_dlsearch_path_spec
-
-# ... but it needs LT_SYS_LIBRARY_PATH munging for other configure-time code
-func_munge_path_list sys_lib_dlsearch_path_spec "$LT_SYS_LIBRARY_PATH"
-
-# to be used as default LT_SYS_LIBRARY_PATH value in generated libtool
-configure_time_lt_sys_library_path=$LT_SYS_LIBRARY_PATH
-
-
-
-
-
-
 
 
 
@@ -11779,15 +11282,15 @@ $as_echo_n "checking how to hardcode library paths into programs... " >&6; }
 hardcode_action=
 if test -n "$hardcode_libdir_flag_spec" ||
    test -n "$runpath_var" ||
-   test yes = "$hardcode_automatic"; then
+   test "X$hardcode_automatic" = "Xyes" ; then
 
   # We can hardcode non-existent directories.
-  if test no != "$hardcode_direct" &&
+  if test "$hardcode_direct" != no &&
      # If the only mechanism to avoid hardcoding is shlibpath_var, we
      # have to relink, otherwise we might link with an installed library
      # when we should be linking with a yet-to-be-installed one
-     ## test no != "$_LT_TAGVAR(hardcode_shlibpath_var, )" &&
-     test no != "$hardcode_minus_L"; then
+     ## test "$_LT_TAGVAR(hardcode_shlibpath_var, )" != no &&
+     test "$hardcode_minus_L" != no; then
     # Linking always hardcodes the temporary library directory.
     hardcode_action=relink
   else
@@ -11802,12 +11305,12 @@ fi
 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $hardcode_action" >&5
 $as_echo "$hardcode_action" >&6; }
 
-if test relink = "$hardcode_action" ||
-   test yes = "$inherit_rpath"; then
+if test "$hardcode_action" = relink ||
+   test "$inherit_rpath" = yes; then
   # Fast installation is not supported
   enable_fast_install=no
-elif test yes = "$shlibpath_overrides_runpath" ||
-     test no = "$enable_shared"; then
+elif test "$shlibpath_overrides_runpath" = yes ||
+     test "$enable_shared" = no; then
   # Fast installation is not necessary
   enable_fast_install=needless
 fi
@@ -11817,7 +11320,7 @@ fi
 
 
 
-  if test yes != "$enable_dlopen"; then
+  if test "x$enable_dlopen" != xyes; then
   enable_dlopen=unknown
   enable_dlopen_self=unknown
   enable_dlopen_self_static=unknown
@@ -11827,23 +11330,23 @@ else
 
   case $host_os in
   beos*)
-    lt_cv_dlopen=load_add_on
+    lt_cv_dlopen="load_add_on"
     lt_cv_dlopen_libs=
     lt_cv_dlopen_self=yes
     ;;
 
   mingw* | pw32* | cegcc*)
-    lt_cv_dlopen=LoadLibrary
+    lt_cv_dlopen="LoadLibrary"
     lt_cv_dlopen_libs=
     ;;
 
   cygwin*)
-    lt_cv_dlopen=dlopen
+    lt_cv_dlopen="dlopen"
     lt_cv_dlopen_libs=
     ;;
 
   darwin*)
-    # if libdl is installed we need to link against it
+  # if libdl is installed we need to link against it
     { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5
 $as_echo_n "checking for dlopen in -ldl... " >&6; }
 if ${ac_cv_lib_dl_dlopen+:} false; then :
@@ -11881,10 +11384,10 @@ fi
 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5
 $as_echo "$ac_cv_lib_dl_dlopen" >&6; }
 if test "x$ac_cv_lib_dl_dlopen" = xyes; then :
-  lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-ldl
+  lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"
 else
 
-    lt_cv_dlopen=dyld
+    lt_cv_dlopen="dyld"
     lt_cv_dlopen_libs=
     lt_cv_dlopen_self=yes
 
@@ -11892,18 +11395,10 @@ fi
 
     ;;
 
-  tpf*)
-    # Don't try to run any link tests for TPF.  We know it's impossible
-    # because TPF is a cross-compiler, and we know how we open DSOs.
-    lt_cv_dlopen=dlopen
-    lt_cv_dlopen_libs=
-    lt_cv_dlopen_self=no
-    ;;
-
   *)
     ac_fn_c_check_func "$LINENO" "shl_load" "ac_cv_func_shl_load"
 if test "x$ac_cv_func_shl_load" = xyes; then :
-  lt_cv_dlopen=shl_load
+  lt_cv_dlopen="shl_load"
 else
   { $as_echo "$as_me:${as_lineno-$LINENO}: checking for shl_load in -ldld" >&5
 $as_echo_n "checking for shl_load in -ldld... " >&6; }
@@ -11942,11 +11437,11 @@ fi
 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_shl_load" >&5
 $as_echo "$ac_cv_lib_dld_shl_load" >&6; }
 if test "x$ac_cv_lib_dld_shl_load" = xyes; then :
-  lt_cv_dlopen=shl_load lt_cv_dlopen_libs=-ldld
+  lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-ldld"
 else
   ac_fn_c_check_func "$LINENO" "dlopen" "ac_cv_func_dlopen"
 if test "x$ac_cv_func_dlopen" = xyes; then :
-  lt_cv_dlopen=dlopen
+  lt_cv_dlopen="dlopen"
 else
   { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5
 $as_echo_n "checking for dlopen in -ldl... " >&6; }
@@ -11985,7 +11480,7 @@ fi
 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5
 $as_echo "$ac_cv_lib_dl_dlopen" >&6; }
 if test "x$ac_cv_lib_dl_dlopen" = xyes; then :
-  lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-ldl
+  lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"
 else
   { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -lsvld" >&5
 $as_echo_n "checking for dlopen in -lsvld... " >&6; }
@@ -12024,7 +11519,7 @@ fi
 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_svld_dlopen" >&5
 $as_echo "$ac_cv_lib_svld_dlopen" >&6; }
 if test "x$ac_cv_lib_svld_dlopen" = xyes; then :
-  lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-lsvld
+  lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld"
 else
   { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dld_link in -ldld" >&5
 $as_echo_n "checking for dld_link in -ldld... " >&6; }
@@ -12063,7 +11558,7 @@ fi
 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_dld_link" >&5
 $as_echo "$ac_cv_lib_dld_dld_link" >&6; }
 if test "x$ac_cv_lib_dld_dld_link" = xyes; then :
-  lt_cv_dlopen=dld_link lt_cv_dlopen_libs=-ldld
+  lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-ldld"
 fi
 
 
@@ -12084,21 +11579,21 @@ fi
     ;;
   esac
 
-  if test no = "$lt_cv_dlopen"; then
-    enable_dlopen=no
-  else
+  if test "x$lt_cv_dlopen" != xno; then
     enable_dlopen=yes
+  else
+    enable_dlopen=no
   fi
 
   case $lt_cv_dlopen in
   dlopen)
-    save_CPPFLAGS=$CPPFLAGS
-    test yes = "$ac_cv_header_dlfcn_h" && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H"
+    save_CPPFLAGS="$CPPFLAGS"
+    test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H"
 
-    save_LDFLAGS=$LDFLAGS
+    save_LDFLAGS="$LDFLAGS"
     wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\"
 
-    save_LIBS=$LIBS
+    save_LIBS="$LIBS"
     LIBS="$lt_cv_dlopen_libs $LIBS"
 
     { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether a program can dlopen itself" >&5
@@ -12106,7 +11601,7 @@ $as_echo_n "checking whether a program can dlopen itself... " >&6; }
 if ${lt_cv_dlopen_self+:} false; then :
   $as_echo_n "(cached) " >&6
 else
-  	  if test yes = "$cross_compiling"; then :
+  	  if test "$cross_compiling" = yes; then :
   lt_cv_dlopen_self=cross
 else
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
@@ -12153,9 +11648,9 @@ else
 #  endif
 #endif
 
-/* When -fvisibility=hidden is used, assume the code has been annotated
+/* When -fvisbility=hidden is used, assume the code has been annotated
    correspondingly for the symbols needed.  */
-#if defined __GNUC__ && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3))
+#if defined(__GNUC__) && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3))
 int fnord () __attribute__((visibility("default")));
 #endif
 
@@ -12185,7 +11680,7 @@ _LT_EOF
   (eval $ac_link) 2>&5
   ac_status=$?
   $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
-  test $ac_status = 0; } && test -s "conftest$ac_exeext" 2>/dev/null; then
+  test $ac_status = 0; } && test -s conftest${ac_exeext} 2>/dev/null; then
     (./conftest; exit; ) >&5 2>/dev/null
     lt_status=$?
     case x$lt_status in
@@ -12205,14 +11700,14 @@ fi
 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self" >&5
 $as_echo "$lt_cv_dlopen_self" >&6; }
 
-    if test yes = "$lt_cv_dlopen_self"; then
+    if test "x$lt_cv_dlopen_self" = xyes; then
       wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\"
       { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether a statically linked program can dlopen itself" >&5
 $as_echo_n "checking whether a statically linked program can dlopen itself... " >&6; }
 if ${lt_cv_dlopen_self_static+:} false; then :
   $as_echo_n "(cached) " >&6
 else
-  	  if test yes = "$cross_compiling"; then :
+  	  if test "$cross_compiling" = yes; then :
   lt_cv_dlopen_self_static=cross
 else
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
@@ -12259,9 +11754,9 @@ else
 #  endif
 #endif
 
-/* When -fvisibility=hidden is used, assume the code has been annotated
+/* When -fvisbility=hidden is used, assume the code has been annotated
    correspondingly for the symbols needed.  */
-#if defined __GNUC__ && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3))
+#if defined(__GNUC__) && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3))
 int fnord () __attribute__((visibility("default")));
 #endif
 
@@ -12291,7 +11786,7 @@ _LT_EOF
   (eval $ac_link) 2>&5
   ac_status=$?
   $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
-  test $ac_status = 0; } && test -s "conftest$ac_exeext" 2>/dev/null; then
+  test $ac_status = 0; } && test -s conftest${ac_exeext} 2>/dev/null; then
     (./conftest; exit; ) >&5 2>/dev/null
     lt_status=$?
     case x$lt_status in
@@ -12312,9 +11807,9 @@ fi
 $as_echo "$lt_cv_dlopen_self_static" >&6; }
     fi
 
-    CPPFLAGS=$save_CPPFLAGS
-    LDFLAGS=$save_LDFLAGS
-    LIBS=$save_LIBS
+    CPPFLAGS="$save_CPPFLAGS"
+    LDFLAGS="$save_LDFLAGS"
+    LIBS="$save_LIBS"
     ;;
   esac
 
@@ -12358,7 +11853,7 @@ else
 # FIXME - insert some real tests, host_os isn't really good enough
   case $host_os in
   darwin*)
-    if test -n "$STRIP"; then
+    if test -n "$STRIP" ; then
       striplib="$STRIP -x"
       old_striplib="$STRIP -S"
       { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
@@ -12386,7 +11881,7 @@ fi
 
 
 
-  # Report what library types will actually be built
+  # Report which library types will actually be built
   { $as_echo "$as_me:${as_lineno-$LINENO}: checking if libtool supports shared libraries" >&5
 $as_echo_n "checking if libtool supports shared libraries... " >&6; }
   { $as_echo "$as_me:${as_lineno-$LINENO}: result: $can_build_shared" >&5
@@ -12394,13 +11889,13 @@ $as_echo "$can_build_shared" >&6; }
 
   { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build shared libraries" >&5
 $as_echo_n "checking whether to build shared libraries... " >&6; }
-  test no = "$can_build_shared" && enable_shared=no
+  test "$can_build_shared" = "no" && enable_shared=no
 
   # On AIX, shared libraries and static libraries use the same namespace, and
   # are all built from PIC.
   case $host_os in
   aix3*)
-    test yes = "$enable_shared" && enable_static=no
+    test "$enable_shared" = yes && enable_static=no
     if test -n "$RANLIB"; then
       archive_cmds="$archive_cmds~\$RANLIB \$lib"
       postinstall_cmds='$RANLIB $lib'
@@ -12408,12 +11903,8 @@ $as_echo_n "checking whether to build shared libraries... " >&6; }
     ;;
 
   aix[4-9]*)
-    if test ia64 != "$host_cpu"; then
-      case $enable_shared,$with_aix_soname,$aix_use_runtimelinking in
-      yes,aix,yes) ;;			# shared object as lib.so file only
-      yes,svr4,*) ;;			# shared object as lib.so archive member only
-      yes,*) enable_static=no ;;	# shared object in lib.a archive as well
-      esac
+    if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then
+      test "$enable_shared" = yes && enable_static=no
     fi
     ;;
   esac
@@ -12423,7 +11914,7 @@ $as_echo "$enable_shared" >&6; }
   { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build static libraries" >&5
 $as_echo_n "checking whether to build static libraries... " >&6; }
   # Make sure either enable_shared or enable_static is yes.
-  test yes = "$enable_shared" || enable_static=yes
+  test "$enable_shared" = yes || enable_static=yes
   { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_static" >&5
 $as_echo "$enable_static" >&6; }
 
@@ -12437,11 +11928,11 @@ ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
 ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
 ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
 
-CC=$lt_save_CC
+CC="$lt_save_CC"
 
-      if test -n "$CXX" && ( test no != "$CXX" &&
-    ( (test g++ = "$CXX" && `g++ -v >/dev/null 2>&1` ) ||
-    (test g++ != "$CXX"))); then
+      if test -n "$CXX" && ( test "X$CXX" != "Xno" &&
+    ( (test "X$CXX" = "Xg++" && `g++ -v >/dev/null 2>&1` ) ||
+    (test "X$CXX" != "Xg++"))) ; then
   ac_ext=cpp
 ac_cpp='$CXXCPP $CPPFLAGS'
 ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
@@ -12620,7 +12111,7 @@ objext_CXX=$objext
 # the CXX compiler isn't working.  Some variables (like enable_shared)
 # are currently assumed to apply to all compilers on this platform,
 # and will be corrupted by setting them based on a non-working compiler.
-if test yes != "$_lt_caught_CXX_error"; then
+if test "$_lt_caught_CXX_error" != yes; then
   # Code to be used in simple compile tests
   lt_simple_compile_test_code="int some_variable = 0;"
 
@@ -12681,39 +12172,46 @@ $RM -r conftest*
   CFLAGS=$CXXFLAGS
   compiler=$CC
   compiler_CXX=$CC
-  func_cc_basename $compiler
-cc_basename=$func_cc_basename_result
+  for cc_temp in $compiler""; do
+  case $cc_temp in
+    compile | *[\\/]compile | ccache | *[\\/]ccache ) ;;
+    distcc | *[\\/]distcc | purify | *[\\/]purify ) ;;
+    \-*) ;;
+    *) break;;
+  esac
+done
+cc_basename=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"`
 
 
   if test -n "$compiler"; then
     # We don't want -fno-exception when compiling C++ code, so set the
     # no_builtin_flag separately
-    if test yes = "$GXX"; then
+    if test "$GXX" = yes; then
       lt_prog_compiler_no_builtin_flag_CXX=' -fno-builtin'
     else
       lt_prog_compiler_no_builtin_flag_CXX=
     fi
 
-    if test yes = "$GXX"; then
+    if test "$GXX" = yes; then
       # Set up default GNU C++ configuration
 
 
 
 # Check whether --with-gnu-ld was given.
 if test "${with_gnu_ld+set}" = set; then :
-  withval=$with_gnu_ld; test no = "$withval" || with_gnu_ld=yes
+  withval=$with_gnu_ld; test "$withval" = no || with_gnu_ld=yes
 else
   with_gnu_ld=no
 fi
 
 ac_prog=ld
-if test yes = "$GCC"; then
+if test "$GCC" = yes; then
   # Check if gcc -print-prog-name=ld gives a path.
   { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ld used by $CC" >&5
 $as_echo_n "checking for ld used by $CC... " >&6; }
   case $host in
   *-*-mingw*)
-    # gcc leaves a trailing carriage return, which upsets mingw
+    # gcc leaves a trailing carriage return which upsets mingw
     ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;;
   *)
     ac_prog=`($CC -print-prog-name=ld) 2>&5` ;;
@@ -12727,7 +12225,7 @@ $as_echo_n "checking for ld used by $CC... " >&6; }
       while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do
 	ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"`
       done
-      test -z "$LD" && LD=$ac_prog
+      test -z "$LD" && LD="$ac_prog"
       ;;
   "")
     # If it fails, then pretend we aren't using GCC.
@@ -12738,7 +12236,7 @@ $as_echo_n "checking for ld used by $CC... " >&6; }
     with_gnu_ld=unknown
     ;;
   esac
-elif test yes = "$with_gnu_ld"; then
+elif test "$with_gnu_ld" = yes; then
   { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU ld" >&5
 $as_echo_n "checking for GNU ld... " >&6; }
 else
@@ -12749,32 +12247,32 @@ if ${lt_cv_path_LD+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   if test -z "$LD"; then
-  lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR
+  lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
   for ac_dir in $PATH; do
-    IFS=$lt_save_ifs
+    IFS="$lt_save_ifs"
     test -z "$ac_dir" && ac_dir=.
     if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then
-      lt_cv_path_LD=$ac_dir/$ac_prog
+      lt_cv_path_LD="$ac_dir/$ac_prog"
       # Check to see if the program is GNU ld.  I'd rather use --version,
       # but apparently some variants of GNU ld only accept -v.
       # Break only if it was the GNU/non-GNU ld that we prefer.
       case `"$lt_cv_path_LD" -v 2>&1 </dev/null` in
       *GNU* | *'with BFD'*)
-	test no != "$with_gnu_ld" && break
+	test "$with_gnu_ld" != no && break
 	;;
       *)
-	test yes != "$with_gnu_ld" && break
+	test "$with_gnu_ld" != yes && break
 	;;
       esac
     fi
   done
-  IFS=$lt_save_ifs
+  IFS="$lt_save_ifs"
 else
-  lt_cv_path_LD=$LD # Let the user override the test with a path.
+  lt_cv_path_LD="$LD" # Let the user override the test with a path.
 fi
 fi
 
-LD=$lt_cv_path_LD
+LD="$lt_cv_path_LD"
 if test -n "$LD"; then
   { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LD" >&5
 $as_echo "$LD" >&6; }
@@ -12810,22 +12308,22 @@ with_gnu_ld=$lt_cv_prog_gnu_ld
 
       # Check if GNU C++ uses GNU ld as the underlying linker, since the
       # archiving commands below assume that GNU ld is being used.
-      if test yes = "$with_gnu_ld"; then
-        archive_cmds_CXX='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib'
-        archive_expsym_cmds_CXX='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'
+      if test "$with_gnu_ld" = yes; then
+        archive_cmds_CXX='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib'
+        archive_expsym_cmds_CXX='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
 
-        hardcode_libdir_flag_spec_CXX='$wl-rpath $wl$libdir'
-        export_dynamic_flag_spec_CXX='$wl--export-dynamic'
+        hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir'
+        export_dynamic_flag_spec_CXX='${wl}--export-dynamic'
 
         # If archive_cmds runs LD, not CC, wlarc should be empty
         # XXX I think wlarc can be eliminated in ltcf-cxx, but I need to
         #     investigate it a little bit more. (MM)
-        wlarc='$wl'
+        wlarc='${wl}'
 
         # ancient GNU ld didn't support --whole-archive et. al.
         if eval "`$CC -print-prog-name=ld` --help 2>&1" |
 	  $GREP 'no-whole-archive' > /dev/null; then
-          whole_archive_flag_spec_CXX=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive'
+          whole_archive_flag_spec_CXX="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive'
         else
           whole_archive_flag_spec_CXX=
         fi
@@ -12862,30 +12360,18 @@ $as_echo_n "checking whether the $compiler linker ($LD) supports shared librarie
         ld_shlibs_CXX=no
         ;;
       aix[4-9]*)
-        if test ia64 = "$host_cpu"; then
+        if test "$host_cpu" = ia64; then
           # On IA64, the linker does run time linking by default, so we don't
           # have to do anything special.
           aix_use_runtimelinking=no
           exp_sym_flag='-Bexport'
-          no_entry_flag=
+          no_entry_flag=""
         else
           aix_use_runtimelinking=no
 
           # Test if we are trying to use run time linking or normal
           # AIX style linking. If -brtl is somewhere in LDFLAGS, we
-          # have runtime linking enabled, and use it for executables.
-          # For shared libraries, we enable/disable runtime linking
-          # depending on the kind of the shared library created -
-          # when "with_aix_soname,aix_use_runtimelinking" is:
-          # "aix,no"   lib.a(lib.so.V) shared, rtl:no,  for executables
-          # "aix,yes"  lib.so          shared, rtl:yes, for executables
-          #            lib.a           static archive
-          # "both,no"  lib.so.V(shr.o) shared, rtl:yes
-          #            lib.a(lib.so.V) shared, rtl:no,  for executables
-          # "both,yes" lib.so.V(shr.o) shared, rtl:yes, for executables
-          #            lib.a(lib.so.V) shared, rtl:no
-          # "svr4,*"   lib.so.V(shr.o) shared, rtl:yes, for executables
-          #            lib.a           static archive
+          # need to do runtime linking.
           case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*)
 	    for ld_flag in $LDFLAGS; do
 	      case $ld_flag in
@@ -12895,13 +12381,6 @@ $as_echo_n "checking whether the $compiler linker ($LD) supports shared librarie
 	        ;;
 	      esac
 	    done
-	    if test svr4,no = "$with_aix_soname,$aix_use_runtimelinking"; then
-	      # With aix-soname=svr4, we create the lib.so.V shared archives only,
-	      # so we don't have lib.a shared libs to link our executables.
-	      # We have to force runtime linking in this case.
-	      aix_use_runtimelinking=yes
-	      LDFLAGS="$LDFLAGS -Wl,-brtl"
-	    fi
 	    ;;
           esac
 
@@ -12920,21 +12399,13 @@ $as_echo_n "checking whether the $compiler linker ($LD) supports shared librarie
         hardcode_direct_absolute_CXX=yes
         hardcode_libdir_separator_CXX=':'
         link_all_deplibs_CXX=yes
-        file_list_spec_CXX='$wl-f,'
-        case $with_aix_soname,$aix_use_runtimelinking in
-        aix,*) ;;	# no import file
-        svr4,* | *,yes) # use import file
-          # The Import File defines what to hardcode.
-          hardcode_direct_CXX=no
-          hardcode_direct_absolute_CXX=no
-          ;;
-        esac
+        file_list_spec_CXX='${wl}-f,'
 
-        if test yes = "$GXX"; then
+        if test "$GXX" = yes; then
           case $host_os in aix4.[012]|aix4.[012].*)
           # We only want to do this on AIX 4.2 and lower, the check
           # below for broken collect2 doesn't work under 4.3+
-	  collect2name=`$CC -print-prog-name=collect2`
+	  collect2name=`${CC} -print-prog-name=collect2`
 	  if test -f "$collect2name" &&
 	     strings "$collect2name" | $GREP resolve_lib_name >/dev/null
 	  then
@@ -12952,44 +12423,36 @@ $as_echo_n "checking whether the $compiler linker ($LD) supports shared librarie
 	  fi
           esac
           shared_flag='-shared'
-	  if test yes = "$aix_use_runtimelinking"; then
-	    shared_flag=$shared_flag' $wl-G'
+	  if test "$aix_use_runtimelinking" = yes; then
+	    shared_flag="$shared_flag "'${wl}-G'
 	  fi
-	  # Need to ensure runtime linking is disabled for the traditional
-	  # shared library, or the linker may eventually find shared libraries
-	  # /with/ Import File - we do not want to mix them.
-	  shared_flag_aix='-shared'
-	  shared_flag_svr4='-shared $wl-G'
         else
           # not using gcc
-          if test ia64 = "$host_cpu"; then
+          if test "$host_cpu" = ia64; then
 	  # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release
 	  # chokes on -Wl,-G. The following line is correct:
 	  shared_flag='-G'
           else
-	    if test yes = "$aix_use_runtimelinking"; then
-	      shared_flag='$wl-G'
+	    if test "$aix_use_runtimelinking" = yes; then
+	      shared_flag='${wl}-G'
 	    else
-	      shared_flag='$wl-bM:SRE'
+	      shared_flag='${wl}-bM:SRE'
 	    fi
-	    shared_flag_aix='$wl-bM:SRE'
-	    shared_flag_svr4='$wl-G'
           fi
         fi
 
-        export_dynamic_flag_spec_CXX='$wl-bexpall'
+        export_dynamic_flag_spec_CXX='${wl}-bexpall'
         # It seems that -bexpall does not export symbols beginning with
         # underscore (_), so it is better to generate a list of symbols to
 	# export.
         always_export_symbols_CXX=yes
-	if test aix,yes = "$with_aix_soname,$aix_use_runtimelinking"; then
+        if test "$aix_use_runtimelinking" = yes; then
           # Warning - without using the other runtime loading flags (-brtl),
           # -berok will link without error, but may produce a broken library.
-          # The "-G" linker flag allows undefined symbols.
-          no_undefined_flag_CXX='-bernotok'
+          allow_undefined_flag_CXX='-berok'
           # Determine the default libpath from the value encoded in an empty
           # executable.
-          if test set = "${lt_cv_aix_libpath+set}"; then
+          if test "${lt_cv_aix_libpath+set}" = set; then
   aix_libpath=$lt_cv_aix_libpath
 else
   if ${lt_cv_aix_libpath__CXX+:} false; then :
@@ -13024,7 +12487,7 @@ fi
 rm -f core conftest.err conftest.$ac_objext \
     conftest$ac_exeext conftest.$ac_ext
   if test -z "$lt_cv_aix_libpath__CXX"; then
-    lt_cv_aix_libpath__CXX=/usr/lib:/lib
+    lt_cv_aix_libpath__CXX="/usr/lib:/lib"
   fi
 
 fi
@@ -13032,18 +12495,18 @@ fi
   aix_libpath=$lt_cv_aix_libpath__CXX
 fi
 
-          hardcode_libdir_flag_spec_CXX='$wl-blibpath:$libdir:'"$aix_libpath"
+          hardcode_libdir_flag_spec_CXX='${wl}-blibpath:$libdir:'"$aix_libpath"
 
-          archive_expsym_cmds_CXX='$CC -o $output_objdir/$soname $libobjs $deplibs $wl'$no_entry_flag' $compiler_flags `if test -n "$allow_undefined_flag"; then func_echo_all "$wl$allow_undefined_flag"; else :; fi` $wl'$exp_sym_flag:\$export_symbols' '$shared_flag
+          archive_expsym_cmds_CXX='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then func_echo_all "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag"
         else
-          if test ia64 = "$host_cpu"; then
-	    hardcode_libdir_flag_spec_CXX='$wl-R $libdir:/usr/lib:/lib'
+          if test "$host_cpu" = ia64; then
+	    hardcode_libdir_flag_spec_CXX='${wl}-R $libdir:/usr/lib:/lib'
 	    allow_undefined_flag_CXX="-z nodefs"
-	    archive_expsym_cmds_CXX="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\$wl$no_entry_flag"' $compiler_flags $wl$allow_undefined_flag '"\$wl$exp_sym_flag:\$export_symbols"
+	    archive_expsym_cmds_CXX="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols"
           else
 	    # Determine the default libpath from the value encoded in an
 	    # empty executable.
-	    if test set = "${lt_cv_aix_libpath+set}"; then
+	    if test "${lt_cv_aix_libpath+set}" = set; then
   aix_libpath=$lt_cv_aix_libpath
 else
   if ${lt_cv_aix_libpath__CXX+:} false; then :
@@ -13078,7 +12541,7 @@ fi
 rm -f core conftest.err conftest.$ac_objext \
     conftest$ac_exeext conftest.$ac_ext
   if test -z "$lt_cv_aix_libpath__CXX"; then
-    lt_cv_aix_libpath__CXX=/usr/lib:/lib
+    lt_cv_aix_libpath__CXX="/usr/lib:/lib"
   fi
 
 fi
@@ -13086,34 +12549,22 @@ fi
   aix_libpath=$lt_cv_aix_libpath__CXX
 fi
 
-	    hardcode_libdir_flag_spec_CXX='$wl-blibpath:$libdir:'"$aix_libpath"
+	    hardcode_libdir_flag_spec_CXX='${wl}-blibpath:$libdir:'"$aix_libpath"
 	    # Warning - without using the other run time loading flags,
 	    # -berok will link without error, but may produce a broken library.
-	    no_undefined_flag_CXX=' $wl-bernotok'
-	    allow_undefined_flag_CXX=' $wl-berok'
-	    if test yes = "$with_gnu_ld"; then
+	    no_undefined_flag_CXX=' ${wl}-bernotok'
+	    allow_undefined_flag_CXX=' ${wl}-berok'
+	    if test "$with_gnu_ld" = yes; then
 	      # We only use this code for GNU lds that support --whole-archive.
-	      whole_archive_flag_spec_CXX='$wl--whole-archive$convenience $wl--no-whole-archive'
+	      whole_archive_flag_spec_CXX='${wl}--whole-archive$convenience ${wl}--no-whole-archive'
 	    else
 	      # Exported symbols can be pulled into shared objects from archives
 	      whole_archive_flag_spec_CXX='$convenience'
 	    fi
 	    archive_cmds_need_lc_CXX=yes
-	    archive_expsym_cmds_CXX='$RM -r $output_objdir/$realname.d~$MKDIR $output_objdir/$realname.d'
-	    # -brtl affects multiple linker settings, -berok does not and is overridden later
-	    compiler_flags_filtered='`func_echo_all "$compiler_flags " | $SED -e "s%-brtl\\([, ]\\)%-berok\\1%g"`'
-	    if test svr4 != "$with_aix_soname"; then
-	      # This is similar to how AIX traditionally builds its shared
-	      # libraries. Need -bnortl late, we may have -brtl in LDFLAGS.
-	      archive_expsym_cmds_CXX="$archive_expsym_cmds_CXX"'~$CC '$shared_flag_aix' -o $output_objdir/$realname.d/$soname $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$realname.d/$soname'
-	    fi
-	    if test aix != "$with_aix_soname"; then
-	      archive_expsym_cmds_CXX="$archive_expsym_cmds_CXX"'~$CC '$shared_flag_svr4' -o $output_objdir/$realname.d/$shared_archive_member_spec.o $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$STRIP -e $output_objdir/$realname.d/$shared_archive_member_spec.o~( func_echo_all "#! $soname($shared_archive_member_spec.o)"; if test shr_64 = "$shared_archive_member_spec"; then func_echo_all "# 64"; else func_echo_all "# 32"; fi; cat $export_sy [...]
-	    else
-	      # used by -dlpreopen to get the symbols
-	      archive_expsym_cmds_CXX="$archive_expsym_cmds_CXX"'~$MV  $output_objdir/$realname.d/$soname $output_objdir'
-	    fi
-	    archive_expsym_cmds_CXX="$archive_expsym_cmds_CXX"'~$RM -r $output_objdir/$realname.d'
+	    # This is similar to how AIX traditionally builds its shared
+	    # libraries.
+	    archive_expsym_cmds_CXX="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname'
           fi
         fi
         ;;
@@ -13123,7 +12574,7 @@ fi
 	  allow_undefined_flag_CXX=unsupported
 	  # Joseph Beckenbach <jrb3 at best.com> says some releases of gcc
 	  # support --undefined.  This deserves some investigation.  FIXME
-	  archive_cmds_CXX='$CC -nostart $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+	  archive_cmds_CXX='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
 	else
 	  ld_shlibs_CXX=no
 	fi
@@ -13151,58 +12602,57 @@ fi
 	  # Tell ltmain to make .lib files, not .a files.
 	  libext=lib
 	  # Tell ltmain to make .dll files, not .so files.
-	  shrext_cmds=.dll
+	  shrext_cmds=".dll"
 	  # FIXME: Setting linknames here is a bad hack.
-	  archive_cmds_CXX='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~linknames='
-	  archive_expsym_cmds_CXX='if   test DEF = "`$SED -n     -e '\''s/^[	 ]*//'\''     -e '\''/^\(;.*\)*$/d'\''     -e '\''s/^\(EXPORTS\|LIBRARY\)\([	 ].*\)*$/DEF/p'\''     -e q     $export_symbols`" ; then
-              cp "$export_symbols" "$output_objdir/$soname.def";
-              echo "$tool_output_objdir$soname.def" > "$output_objdir/$soname.exp";
-            else
-              $SED -e '\''s/^/-link -EXPORT:/'\'' < $export_symbols > $output_objdir/$soname.exp;
-            fi~
-            $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~
-            linknames='
+	  archive_cmds_CXX='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-dll~linknames='
+	  archive_expsym_cmds_CXX='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then
+	      $SED -n -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' -e '1\\\!p' < $export_symbols > $output_objdir/$soname.exp;
+	    else
+	      $SED -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' < $export_symbols > $output_objdir/$soname.exp;
+	    fi~
+	    $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~
+	    linknames='
 	  # The linker will not automatically build a static lib if we build a DLL.
 	  # _LT_TAGVAR(old_archive_from_new_cmds, CXX)='true'
 	  enable_shared_with_static_runtimes_CXX=yes
 	  # Don't use ranlib
 	  old_postinstall_cmds_CXX='chmod 644 $oldlib'
 	  postlink_cmds_CXX='lt_outputfile="@OUTPUT@"~
-            lt_tool_outputfile="@TOOL_OUTPUT@"~
-            case $lt_outputfile in
-              *.exe|*.EXE) ;;
-              *)
-                lt_outputfile=$lt_outputfile.exe
-                lt_tool_outputfile=$lt_tool_outputfile.exe
-                ;;
-            esac~
-            func_to_tool_file "$lt_outputfile"~
-            if test : != "$MANIFEST_TOOL" && test -f "$lt_outputfile.manifest"; then
-              $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1;
-              $RM "$lt_outputfile.manifest";
-            fi'
+	    lt_tool_outputfile="@TOOL_OUTPUT@"~
+	    case $lt_outputfile in
+	      *.exe|*.EXE) ;;
+	      *)
+		lt_outputfile="$lt_outputfile.exe"
+		lt_tool_outputfile="$lt_tool_outputfile.exe"
+		;;
+	    esac~
+	    func_to_tool_file "$lt_outputfile"~
+	    if test "$MANIFEST_TOOL" != ":" && test -f "$lt_outputfile.manifest"; then
+	      $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1;
+	      $RM "$lt_outputfile.manifest";
+	    fi'
 	  ;;
 	*)
 	  # g++
 	  # _LT_TAGVAR(hardcode_libdir_flag_spec, CXX) is actually meaningless,
 	  # as there is no search path for DLLs.
 	  hardcode_libdir_flag_spec_CXX='-L$libdir'
-	  export_dynamic_flag_spec_CXX='$wl--export-all-symbols'
+	  export_dynamic_flag_spec_CXX='${wl}--export-all-symbols'
 	  allow_undefined_flag_CXX=unsupported
 	  always_export_symbols_CXX=no
 	  enable_shared_with_static_runtimes_CXX=yes
 
 	  if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then
-	    archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
-	    # If the export-symbols file already is a .def file, use it as
-	    # is; otherwise, prepend EXPORTS...
-	    archive_expsym_cmds_CXX='if   test DEF = "`$SED -n     -e '\''s/^[	 ]*//'\''     -e '\''/^\(;.*\)*$/d'\''     -e '\''s/^\(EXPORTS\|LIBRARY\)\([	 ].*\)*$/DEF/p'\''     -e q     $export_symbols`" ; then
-              cp $export_symbols $output_objdir/$soname.def;
-            else
-              echo EXPORTS > $output_objdir/$soname.def;
-              cat $export_symbols >> $output_objdir/$soname.def;
-            fi~
-            $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+	    archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+	    # If the export-symbols file already is a .def file (1st line
+	    # is EXPORTS), use it as is; otherwise, prepend...
+	    archive_expsym_cmds_CXX='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then
+	      cp $export_symbols $output_objdir/$soname.def;
+	    else
+	      echo EXPORTS > $output_objdir/$soname.def;
+	      cat $export_symbols >> $output_objdir/$soname.def;
+	    fi~
+	    $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
 	  else
 	    ld_shlibs_CXX=no
 	  fi
@@ -13216,27 +12666,27 @@ fi
   hardcode_direct_CXX=no
   hardcode_automatic_CXX=yes
   hardcode_shlibpath_var_CXX=unsupported
-  if test yes = "$lt_cv_ld_force_load"; then
-    whole_archive_flag_spec_CXX='`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience $wl-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`'
+  if test "$lt_cv_ld_force_load" = "yes"; then
+    whole_archive_flag_spec_CXX='`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience ${wl}-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`'
 
   else
     whole_archive_flag_spec_CXX=''
   fi
   link_all_deplibs_CXX=yes
-  allow_undefined_flag_CXX=$_lt_dar_allow_undefined
+  allow_undefined_flag_CXX="$_lt_dar_allow_undefined"
   case $cc_basename in
-     ifort*|nagfor*) _lt_dar_can_shared=yes ;;
+     ifort*) _lt_dar_can_shared=yes ;;
      *) _lt_dar_can_shared=$GCC ;;
   esac
-  if test yes = "$_lt_dar_can_shared"; then
+  if test "$_lt_dar_can_shared" = "yes"; then
     output_verbose_link_cmd=func_echo_all
-    archive_cmds_CXX="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dsymutil"
-    module_cmds_CXX="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dsymutil"
-    archive_expsym_cmds_CXX="sed 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dar_export_syms$_lt_dsymutil"
-    module_expsym_cmds_CXX="sed -e 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dar_export_syms$_lt_dsymutil"
-       if test yes != "$lt_cv_apple_cc_single_mod"; then
-      archive_cmds_CXX="\$CC -r -keep_private_externs -nostdlib -o \$lib-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$lib-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring$_lt_dsymutil"
-      archive_expsym_cmds_CXX="sed 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \$lib-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$lib-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring$_lt_dar_export_syms$_lt_dsymutil"
+    archive_cmds_CXX="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}"
+    module_cmds_CXX="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}"
+    archive_expsym_cmds_CXX="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}"
+    module_expsym_cmds_CXX="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}"
+       if test "$lt_cv_apple_cc_single_mod" != "yes"; then
+      archive_cmds_CXX="\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dsymutil}"
+      archive_expsym_cmds_CXX="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dar_export_syms}${_lt_dsymutil}"
     fi
 
   else
@@ -13245,34 +12695,6 @@ fi
 
 	;;
 
-      os2*)
-	hardcode_libdir_flag_spec_CXX='-L$libdir'
-	hardcode_minus_L_CXX=yes
-	allow_undefined_flag_CXX=unsupported
-	shrext_cmds=.dll
-	archive_cmds_CXX='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~
-	  $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~
-	  $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~
-	  $ECHO EXPORTS >> $output_objdir/$libname.def~
-	  emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~
-	  $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~
-	  emximp -o $lib $output_objdir/$libname.def'
-	archive_expsym_cmds_CXX='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~
-	  $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~
-	  $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~
-	  $ECHO EXPORTS >> $output_objdir/$libname.def~
-	  prefix_cmds="$SED"~
-	  if test EXPORTS = "`$SED 1q $export_symbols`"; then
-	    prefix_cmds="$prefix_cmds -e 1d";
-	  fi~
-	  prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~
-	  cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~
-	  $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~
-	  emximp -o $lib $output_objdir/$libname.def'
-	old_archive_From_new_cmds_CXX='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def'
-	enable_shared_with_static_runtimes_CXX=yes
-	;;
-
       dgux*)
         case $cc_basename in
           ec++*)
@@ -13308,14 +12730,14 @@ fi
         ;;
 
       haiku*)
-        archive_cmds_CXX='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+        archive_cmds_CXX='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
         link_all_deplibs_CXX=yes
         ;;
 
       hpux9*)
-        hardcode_libdir_flag_spec_CXX='$wl+b $wl$libdir'
+        hardcode_libdir_flag_spec_CXX='${wl}+b ${wl}$libdir'
         hardcode_libdir_separator_CXX=:
-        export_dynamic_flag_spec_CXX='$wl-E'
+        export_dynamic_flag_spec_CXX='${wl}-E'
         hardcode_direct_CXX=yes
         hardcode_minus_L_CXX=yes # Not in the search PATH,
 				             # but as the default
@@ -13327,7 +12749,7 @@ fi
             ld_shlibs_CXX=no
             ;;
           aCC*)
-            archive_cmds_CXX='$RM $output_objdir/$soname~$CC -b $wl+b $wl$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib'
+            archive_cmds_CXX='$RM $output_objdir/$soname~$CC -b ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
             # Commands to make compiler produce verbose output that lists
             # what "hidden" libraries, object files and flags are used when
             # linking a shared library.
@@ -13336,11 +12758,11 @@ fi
             # explicitly linking system object files so we need to strip them
             # from the output so that they don't get included in the library
             # dependencies.
-            output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP "\-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
+            output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
             ;;
           *)
-            if test yes = "$GXX"; then
-              archive_cmds_CXX='$RM $output_objdir/$soname~$CC -shared -nostdlib $pic_flag $wl+b $wl$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib'
+            if test "$GXX" = yes; then
+              archive_cmds_CXX='$RM $output_objdir/$soname~$CC -shared -nostdlib $pic_flag ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
             else
               # FIXME: insert proper C++ library support
               ld_shlibs_CXX=no
@@ -13350,15 +12772,15 @@ fi
         ;;
 
       hpux10*|hpux11*)
-        if test no = "$with_gnu_ld"; then
-	  hardcode_libdir_flag_spec_CXX='$wl+b $wl$libdir'
+        if test $with_gnu_ld = no; then
+	  hardcode_libdir_flag_spec_CXX='${wl}+b ${wl}$libdir'
 	  hardcode_libdir_separator_CXX=:
 
           case $host_cpu in
             hppa*64*|ia64*)
               ;;
             *)
-	      export_dynamic_flag_spec_CXX='$wl-E'
+	      export_dynamic_flag_spec_CXX='${wl}-E'
               ;;
           esac
         fi
@@ -13384,13 +12806,13 @@ fi
           aCC*)
 	    case $host_cpu in
 	      hppa*64*)
-	        archive_cmds_CXX='$CC -b $wl+h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+	        archive_cmds_CXX='$CC -b ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
 	        ;;
 	      ia64*)
-	        archive_cmds_CXX='$CC -b $wl+h $wl$soname $wl+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+	        archive_cmds_CXX='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
 	        ;;
 	      *)
-	        archive_cmds_CXX='$CC -b $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+	        archive_cmds_CXX='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
 	        ;;
 	    esac
 	    # Commands to make compiler produce verbose output that lists
@@ -13401,20 +12823,20 @@ fi
 	    # explicitly linking system object files so we need to strip them
 	    # from the output so that they don't get included in the library
 	    # dependencies.
-	    output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP "\-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
+	    output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
 	    ;;
           *)
-	    if test yes = "$GXX"; then
-	      if test no = "$with_gnu_ld"; then
+	    if test "$GXX" = yes; then
+	      if test $with_gnu_ld = no; then
 	        case $host_cpu in
 	          hppa*64*)
-	            archive_cmds_CXX='$CC -shared -nostdlib -fPIC $wl+h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+	            archive_cmds_CXX='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
 	            ;;
 	          ia64*)
-	            archive_cmds_CXX='$CC -shared -nostdlib $pic_flag $wl+h $wl$soname $wl+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+	            archive_cmds_CXX='$CC -shared -nostdlib $pic_flag ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
 	            ;;
 	          *)
-	            archive_cmds_CXX='$CC -shared -nostdlib $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+	            archive_cmds_CXX='$CC -shared -nostdlib $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
 	            ;;
 	        esac
 	      fi
@@ -13429,22 +12851,22 @@ fi
       interix[3-9]*)
 	hardcode_direct_CXX=no
 	hardcode_shlibpath_var_CXX=no
-	hardcode_libdir_flag_spec_CXX='$wl-rpath,$libdir'
-	export_dynamic_flag_spec_CXX='$wl-E'
+	hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir'
+	export_dynamic_flag_spec_CXX='${wl}-E'
 	# Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc.
 	# Instead, shared libraries are loaded at an image base (0x10000000 by
 	# default) and relocated if they conflict, which is a slow very memory
 	# consuming and fragmenting process.  To avoid this, we pick a random,
 	# 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link
 	# time.  Moving up from 0x10000000 also allows more sbrk(2) space.
-	archive_cmds_CXX='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
-	archive_expsym_cmds_CXX='sed "s|^|_|" $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--retain-symbols-file,$output_objdir/$soname.expsym $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+	archive_cmds_CXX='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+	archive_expsym_cmds_CXX='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
 	;;
       irix5* | irix6*)
         case $cc_basename in
           CC*)
 	    # SGI C++
-	    archive_cmds_CXX='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib'
+	    archive_cmds_CXX='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib'
 
 	    # Archives containing C++ object files must be created using
 	    # "CC -ar", where "CC" is the IRIX C++ compiler.  This is
@@ -13453,17 +12875,17 @@ fi
 	    old_archive_cmds_CXX='$CC -ar -WR,-u -o $oldlib $oldobjs'
 	    ;;
           *)
-	    if test yes = "$GXX"; then
-	      if test no = "$with_gnu_ld"; then
-	        archive_cmds_CXX='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib'
+	    if test "$GXX" = yes; then
+	      if test "$with_gnu_ld" = no; then
+	        archive_cmds_CXX='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
 	      else
-	        archive_cmds_CXX='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` -o $lib'
+	        archive_cmds_CXX='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` -o $lib'
 	      fi
 	    fi
 	    link_all_deplibs_CXX=yes
 	    ;;
         esac
-        hardcode_libdir_flag_spec_CXX='$wl-rpath $wl$libdir'
+        hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir'
         hardcode_libdir_separator_CXX=:
         inherit_rpath_CXX=yes
         ;;
@@ -13476,8 +12898,8 @@ fi
 	    # KCC will only create a shared library if the output file
 	    # ends with ".so" (or ".sl" for HP-UX), so rename the library
 	    # to its proper name (with version) after linking.
-	    archive_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib'
-	    archive_expsym_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib $wl-retain-symbols-file,$export_symbols; mv \$templib $lib'
+	    archive_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib'
+	    archive_expsym_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib ${wl}-retain-symbols-file,$export_symbols; mv \$templib $lib'
 	    # Commands to make compiler produce verbose output that lists
 	    # what "hidden" libraries, object files and flags are used when
 	    # linking a shared library.
@@ -13486,10 +12908,10 @@ fi
 	    # explicitly linking system object files so we need to strip them
 	    # from the output so that they don't get included in the library
 	    # dependencies.
-	    output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | $GREP "ld"`; rm -f libconftest$shared_ext; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
+	    output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | $GREP "ld"`; rm -f libconftest$shared_ext; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
 
-	    hardcode_libdir_flag_spec_CXX='$wl-rpath,$libdir'
-	    export_dynamic_flag_spec_CXX='$wl--export-dynamic'
+	    hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir'
+	    export_dynamic_flag_spec_CXX='${wl}--export-dynamic'
 
 	    # Archives containing C++ object files must be created using
 	    # "CC -Bstatic", where "CC" is the KAI C++ compiler.
@@ -13503,59 +12925,59 @@ fi
 	    # earlier do not add the objects themselves.
 	    case `$CC -V 2>&1` in
 	      *"Version 7."*)
-	        archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib'
-		archive_expsym_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'
+	        archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib'
+		archive_expsym_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
 		;;
 	      *)  # Version 8.0 or newer
 	        tmp_idyn=
 	        case $host_cpu in
 		  ia64*) tmp_idyn=' -i_dynamic';;
 		esac
-	        archive_cmds_CXX='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
-		archive_expsym_cmds_CXX='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'
+	        archive_cmds_CXX='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+		archive_expsym_cmds_CXX='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
 		;;
 	    esac
 	    archive_cmds_need_lc_CXX=no
-	    hardcode_libdir_flag_spec_CXX='$wl-rpath,$libdir'
-	    export_dynamic_flag_spec_CXX='$wl--export-dynamic'
-	    whole_archive_flag_spec_CXX='$wl--whole-archive$convenience $wl--no-whole-archive'
+	    hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir'
+	    export_dynamic_flag_spec_CXX='${wl}--export-dynamic'
+	    whole_archive_flag_spec_CXX='${wl}--whole-archive$convenience ${wl}--no-whole-archive'
 	    ;;
           pgCC* | pgcpp*)
             # Portland Group C++ compiler
 	    case `$CC -V` in
 	    *pgCC\ [1-5].* | *pgcpp\ [1-5].*)
 	      prelink_cmds_CXX='tpldir=Template.dir~
-               rm -rf $tpldir~
-               $CC --prelink_objects --instantiation_dir $tpldir $objs $libobjs $compile_deplibs~
-               compile_command="$compile_command `find $tpldir -name \*.o | sort | $NL2SP`"'
+		rm -rf $tpldir~
+		$CC --prelink_objects --instantiation_dir $tpldir $objs $libobjs $compile_deplibs~
+		compile_command="$compile_command `find $tpldir -name \*.o | sort | $NL2SP`"'
 	      old_archive_cmds_CXX='tpldir=Template.dir~
-                rm -rf $tpldir~
-                $CC --prelink_objects --instantiation_dir $tpldir $oldobjs$old_deplibs~
-                $AR $AR_FLAGS $oldlib$oldobjs$old_deplibs `find $tpldir -name \*.o | sort | $NL2SP`~
-                $RANLIB $oldlib'
+		rm -rf $tpldir~
+		$CC --prelink_objects --instantiation_dir $tpldir $oldobjs$old_deplibs~
+		$AR $AR_FLAGS $oldlib$oldobjs$old_deplibs `find $tpldir -name \*.o | sort | $NL2SP`~
+		$RANLIB $oldlib'
 	      archive_cmds_CXX='tpldir=Template.dir~
-                rm -rf $tpldir~
-                $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~
-                $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib'
+		rm -rf $tpldir~
+		$CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~
+		$CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib'
 	      archive_expsym_cmds_CXX='tpldir=Template.dir~
-                rm -rf $tpldir~
-                $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~
-                $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'
+		rm -rf $tpldir~
+		$CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~
+		$CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib'
 	      ;;
 	    *) # Version 6 and above use weak symbols
-	      archive_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib'
-	      archive_expsym_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'
+	      archive_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib'
+	      archive_expsym_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib'
 	      ;;
 	    esac
 
-	    hardcode_libdir_flag_spec_CXX='$wl--rpath $wl$libdir'
-	    export_dynamic_flag_spec_CXX='$wl--export-dynamic'
-	    whole_archive_flag_spec_CXX='$wl--whole-archive`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive'
+	    hardcode_libdir_flag_spec_CXX='${wl}--rpath ${wl}$libdir'
+	    export_dynamic_flag_spec_CXX='${wl}--export-dynamic'
+	    whole_archive_flag_spec_CXX='${wl}--whole-archive`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
             ;;
 	  cxx*)
 	    # Compaq C++
-	    archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib'
-	    archive_expsym_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname  -o $lib $wl-retain-symbols-file $wl$export_symbols'
+	    archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib'
+	    archive_expsym_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname  -o $lib ${wl}-retain-symbols-file $wl$export_symbols'
 
 	    runpath_var=LD_RUN_PATH
 	    hardcode_libdir_flag_spec_CXX='-rpath $libdir'
@@ -13569,18 +12991,18 @@ fi
 	    # explicitly linking system object files so we need to strip them
 	    # from the output so that they don't get included in the library
 	    # dependencies.
-	    output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "X$list" | $Xsed'
+	    output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "X$list" | $Xsed'
 	    ;;
 	  xl* | mpixl* | bgxl*)
 	    # IBM XL 8.0 on PPC, with GNU ld
-	    hardcode_libdir_flag_spec_CXX='$wl-rpath $wl$libdir'
-	    export_dynamic_flag_spec_CXX='$wl--export-dynamic'
-	    archive_cmds_CXX='$CC -qmkshrobj $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
-	    if test yes = "$supports_anon_versioning"; then
+	    hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir'
+	    export_dynamic_flag_spec_CXX='${wl}--export-dynamic'
+	    archive_cmds_CXX='$CC -qmkshrobj $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+	    if test "x$supports_anon_versioning" = xyes; then
 	      archive_expsym_cmds_CXX='echo "{ global:" > $output_objdir/$libname.ver~
-                cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
-                echo "local: *; };" >> $output_objdir/$libname.ver~
-                $CC -qmkshrobj $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-version-script $wl$output_objdir/$libname.ver -o $lib'
+		cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
+		echo "local: *; };" >> $output_objdir/$libname.ver~
+		$CC -qmkshrobj $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib'
 	    fi
 	    ;;
 	  *)
@@ -13588,10 +13010,10 @@ fi
 	    *Sun\ C*)
 	      # Sun C++ 5.9
 	      no_undefined_flag_CXX=' -zdefs'
-	      archive_cmds_CXX='$CC -G$allow_undefined_flag -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
-	      archive_expsym_cmds_CXX='$CC -G$allow_undefined_flag -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-retain-symbols-file $wl$export_symbols'
+	      archive_cmds_CXX='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+	      archive_expsym_cmds_CXX='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file ${wl}$export_symbols'
 	      hardcode_libdir_flag_spec_CXX='-R$libdir'
-	      whole_archive_flag_spec_CXX='$wl--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive'
+	      whole_archive_flag_spec_CXX='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
 	      compiler_needs_object_CXX=yes
 
 	      # Not sure whether something based on
@@ -13649,17 +13071,22 @@ fi
         ld_shlibs_CXX=yes
 	;;
 
-      openbsd* | bitrig*)
+      openbsd2*)
+        # C++ shared libraries are fairly broken
+	ld_shlibs_CXX=no
+	;;
+
+      openbsd*)
 	if test -f /usr/libexec/ld.so; then
 	  hardcode_direct_CXX=yes
 	  hardcode_shlibpath_var_CXX=no
 	  hardcode_direct_absolute_CXX=yes
 	  archive_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib'
-	  hardcode_libdir_flag_spec_CXX='$wl-rpath,$libdir'
-	  if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`"; then
-	    archive_expsym_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-retain-symbols-file,$export_symbols -o $lib'
-	    export_dynamic_flag_spec_CXX='$wl-E'
-	    whole_archive_flag_spec_CXX=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive'
+	  hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir'
+	  if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+	    archive_expsym_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file,$export_symbols -o $lib'
+	    export_dynamic_flag_spec_CXX='${wl}-E'
+	    whole_archive_flag_spec_CXX="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive'
 	  fi
 	  output_verbose_link_cmd=func_echo_all
 	else
@@ -13675,9 +13102,9 @@ fi
 	    # KCC will only create a shared library if the output file
 	    # ends with ".so" (or ".sl" for HP-UX), so rename the library
 	    # to its proper name (with version) after linking.
-	    archive_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo "$lib" | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib'
+	    archive_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo "$lib" | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib'
 
-	    hardcode_libdir_flag_spec_CXX='$wl-rpath,$libdir'
+	    hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir'
 	    hardcode_libdir_separator_CXX=:
 
 	    # Archives containing C++ object files must be created using
@@ -13695,17 +13122,17 @@ fi
           cxx*)
 	    case $host in
 	      osf3*)
-	        allow_undefined_flag_CXX=' $wl-expect_unresolved $wl\*'
-	        archive_cmds_CXX='$CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $soname `test -n "$verstring" && func_echo_all "$wl-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib'
-	        hardcode_libdir_flag_spec_CXX='$wl-rpath $wl$libdir'
+	        allow_undefined_flag_CXX=' ${wl}-expect_unresolved ${wl}\*'
+	        archive_cmds_CXX='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $soname `test -n "$verstring" && func_echo_all "${wl}-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib'
+	        hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir'
 		;;
 	      *)
 	        allow_undefined_flag_CXX=' -expect_unresolved \*'
-	        archive_cmds_CXX='$CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib'
+	        archive_cmds_CXX='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib'
 	        archive_expsym_cmds_CXX='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done~
-                  echo "-hidden">> $lib.exp~
-                  $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname $wl-input $wl$lib.exp  `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib~
-                  $RM $lib.exp'
+	          echo "-hidden">> $lib.exp~
+	          $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname ${wl}-input ${wl}$lib.exp  `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib~
+	          $RM $lib.exp'
 	        hardcode_libdir_flag_spec_CXX='-rpath $libdir'
 		;;
 	    esac
@@ -13720,21 +13147,21 @@ fi
 	    # explicitly linking system object files so we need to strip them
 	    # from the output so that they don't get included in the library
 	    # dependencies.
-	    output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld" | $GREP -v "ld:"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
+	    output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld" | $GREP -v "ld:"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
 	    ;;
 	  *)
-	    if test yes,no = "$GXX,$with_gnu_ld"; then
-	      allow_undefined_flag_CXX=' $wl-expect_unresolved $wl\*'
+	    if test "$GXX" = yes && test "$with_gnu_ld" = no; then
+	      allow_undefined_flag_CXX=' ${wl}-expect_unresolved ${wl}\*'
 	      case $host in
 	        osf3*)
-	          archive_cmds_CXX='$CC -shared -nostdlib $allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib'
+	          archive_cmds_CXX='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
 		  ;;
 	        *)
-	          archive_cmds_CXX='$CC -shared $pic_flag -nostdlib $allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-msym $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib'
+	          archive_cmds_CXX='$CC -shared $pic_flag -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
 		  ;;
 	      esac
 
-	      hardcode_libdir_flag_spec_CXX='$wl-rpath $wl$libdir'
+	      hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir'
 	      hardcode_libdir_separator_CXX=:
 
 	      # Commands to make compiler produce verbose output that lists
@@ -13780,9 +13207,9 @@ fi
 	    # Sun C++ 4.2, 5.x and Centerline C++
             archive_cmds_need_lc_CXX=yes
 	    no_undefined_flag_CXX=' -zdefs'
-	    archive_cmds_CXX='$CC -G$allow_undefined_flag -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+	    archive_cmds_CXX='$CC -G${allow_undefined_flag}  -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
 	    archive_expsym_cmds_CXX='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
-              $CC -G$allow_undefined_flag $wl-M $wl$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp'
+	      $CC -G${allow_undefined_flag} ${wl}-M ${wl}$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp'
 
 	    hardcode_libdir_flag_spec_CXX='-R$libdir'
 	    hardcode_shlibpath_var_CXX=no
@@ -13790,7 +13217,7 @@ fi
 	      solaris2.[0-5] | solaris2.[0-5].*) ;;
 	      *)
 		# The compiler driver will combine and reorder linker options,
-		# but understands '-z linker_flag'.
+		# but understands `-z linker_flag'.
 	        # Supported since Solaris 2.6 (maybe 2.5.1?)
 		whole_archive_flag_spec_CXX='-z allextract$convenience -z defaultextract'
 	        ;;
@@ -13807,30 +13234,30 @@ fi
 	    ;;
           gcx*)
 	    # Green Hills C++ Compiler
-	    archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-h $wl$soname -o $lib'
+	    archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib'
 
 	    # The C++ compiler must be used to create the archive.
 	    old_archive_cmds_CXX='$CC $LDFLAGS -archive -o $oldlib $oldobjs'
 	    ;;
           *)
 	    # GNU C++ compiler with Solaris linker
-	    if test yes,no = "$GXX,$with_gnu_ld"; then
-	      no_undefined_flag_CXX=' $wl-z ${wl}defs'
+	    if test "$GXX" = yes && test "$with_gnu_ld" = no; then
+	      no_undefined_flag_CXX=' ${wl}-z ${wl}defs'
 	      if $CC --version | $GREP -v '^2\.7' > /dev/null; then
-	        archive_cmds_CXX='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-h $wl$soname -o $lib'
+	        archive_cmds_CXX='$CC -shared $pic_flag -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib'
 	        archive_expsym_cmds_CXX='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
-                  $CC -shared $pic_flag -nostdlib $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp'
+		  $CC -shared $pic_flag -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp'
 
 	        # Commands to make compiler produce verbose output that lists
 	        # what "hidden" libraries, object files and flags are used when
 	        # linking a shared library.
 	        output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"'
 	      else
-	        # g++ 2.7 appears to require '-G' NOT '-shared' on this
+	        # g++ 2.7 appears to require `-G' NOT `-shared' on this
 	        # platform.
-	        archive_cmds_CXX='$CC -G -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-h $wl$soname -o $lib'
+	        archive_cmds_CXX='$CC -G -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib'
 	        archive_expsym_cmds_CXX='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
-                  $CC -G -nostdlib $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp'
+		  $CC -G -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp'
 
 	        # Commands to make compiler produce verbose output that lists
 	        # what "hidden" libraries, object files and flags are used when
@@ -13838,11 +13265,11 @@ fi
 	        output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"'
 	      fi
 
-	      hardcode_libdir_flag_spec_CXX='$wl-R $wl$libdir'
+	      hardcode_libdir_flag_spec_CXX='${wl}-R $wl$libdir'
 	      case $host_os in
 		solaris2.[0-5] | solaris2.[0-5].*) ;;
 		*)
-		  whole_archive_flag_spec_CXX='$wl-z ${wl}allextract$convenience $wl-z ${wl}defaultextract'
+		  whole_archive_flag_spec_CXX='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract'
 		  ;;
 	      esac
 	    fi
@@ -13851,52 +13278,52 @@ fi
         ;;
 
     sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*)
-      no_undefined_flag_CXX='$wl-z,text'
+      no_undefined_flag_CXX='${wl}-z,text'
       archive_cmds_need_lc_CXX=no
       hardcode_shlibpath_var_CXX=no
       runpath_var='LD_RUN_PATH'
 
       case $cc_basename in
         CC*)
-	  archive_cmds_CXX='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
-	  archive_expsym_cmds_CXX='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	  archive_cmds_CXX='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	  archive_expsym_cmds_CXX='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
 	  ;;
 	*)
-	  archive_cmds_CXX='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
-	  archive_expsym_cmds_CXX='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	  archive_cmds_CXX='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	  archive_expsym_cmds_CXX='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
 	  ;;
       esac
       ;;
 
       sysv5* | sco3.2v5* | sco5v6*)
-	# Note: We CANNOT use -z defs as we might desire, because we do not
+	# Note: We can NOT use -z defs as we might desire, because we do not
 	# link with -lc, and that would cause any symbols used from libc to
 	# always be unresolved, which means just about no library would
 	# ever link correctly.  If we're not using GNU ld we use -z text
 	# though, which does catch some bad symbols but isn't as heavy-handed
 	# as -z defs.
-	no_undefined_flag_CXX='$wl-z,text'
-	allow_undefined_flag_CXX='$wl-z,nodefs'
+	no_undefined_flag_CXX='${wl}-z,text'
+	allow_undefined_flag_CXX='${wl}-z,nodefs'
 	archive_cmds_need_lc_CXX=no
 	hardcode_shlibpath_var_CXX=no
-	hardcode_libdir_flag_spec_CXX='$wl-R,$libdir'
+	hardcode_libdir_flag_spec_CXX='${wl}-R,$libdir'
 	hardcode_libdir_separator_CXX=':'
 	link_all_deplibs_CXX=yes
-	export_dynamic_flag_spec_CXX='$wl-Bexport'
+	export_dynamic_flag_spec_CXX='${wl}-Bexport'
 	runpath_var='LD_RUN_PATH'
 
 	case $cc_basename in
           CC*)
-	    archive_cmds_CXX='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
-	    archive_expsym_cmds_CXX='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	    archive_cmds_CXX='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	    archive_expsym_cmds_CXX='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
 	    old_archive_cmds_CXX='$CC -Tprelink_objects $oldobjs~
-              '"$old_archive_cmds_CXX"
+	      '"$old_archive_cmds_CXX"
 	    reload_cmds_CXX='$CC -Tprelink_objects $reload_objs~
-              '"$reload_cmds_CXX"
+	      '"$reload_cmds_CXX"
 	    ;;
 	  *)
-	    archive_cmds_CXX='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
-	    archive_expsym_cmds_CXX='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	    archive_cmds_CXX='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	    archive_expsym_cmds_CXX='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
 	    ;;
 	esac
       ;;
@@ -13928,10 +13355,10 @@ fi
 
     { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs_CXX" >&5
 $as_echo "$ld_shlibs_CXX" >&6; }
-    test no = "$ld_shlibs_CXX" && can_build_shared=no
+    test "$ld_shlibs_CXX" = no && can_build_shared=no
 
-    GCC_CXX=$GXX
-    LD_CXX=$LD
+    GCC_CXX="$GXX"
+    LD_CXX="$LD"
 
     ## CAVEAT EMPTOR:
     ## There is no encapsulation within the following macros, do not change
@@ -13975,13 +13402,13 @@ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
   pre_test_object_deps_done=no
 
   for p in `eval "$output_verbose_link_cmd"`; do
-    case $prev$p in
+    case ${prev}${p} in
 
     -L* | -R* | -l*)
        # Some compilers place space between "-{L,R}" and the path.
        # Remove the space.
-       if test x-L = "$p" ||
-          test x-R = "$p"; then
+       if test $p = "-L" ||
+          test $p = "-R"; then
 	 prev=$p
 	 continue
        fi
@@ -13997,16 +13424,16 @@ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
        case $p in
        =*) func_stripname_cnf '=' '' "$p"; p=$lt_sysroot$func_stripname_result ;;
        esac
-       if test no = "$pre_test_object_deps_done"; then
-	 case $prev in
+       if test "$pre_test_object_deps_done" = no; then
+	 case ${prev} in
 	 -L | -R)
 	   # Internal compiler library paths should come after those
 	   # provided the user.  The postdeps already come after the
 	   # user supplied libs so there is no need to process them.
 	   if test -z "$compiler_lib_search_path_CXX"; then
-	     compiler_lib_search_path_CXX=$prev$p
+	     compiler_lib_search_path_CXX="${prev}${p}"
 	   else
-	     compiler_lib_search_path_CXX="${compiler_lib_search_path_CXX} $prev$p"
+	     compiler_lib_search_path_CXX="${compiler_lib_search_path_CXX} ${prev}${p}"
 	   fi
 	   ;;
 	 # The "-l" case would never come before the object being
@@ -14014,9 +13441,9 @@ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
 	 esac
        else
 	 if test -z "$postdeps_CXX"; then
-	   postdeps_CXX=$prev$p
+	   postdeps_CXX="${prev}${p}"
 	 else
-	   postdeps_CXX="${postdeps_CXX} $prev$p"
+	   postdeps_CXX="${postdeps_CXX} ${prev}${p}"
 	 fi
        fi
        prev=
@@ -14031,15 +13458,15 @@ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
 	 continue
        fi
 
-       if test no = "$pre_test_object_deps_done"; then
+       if test "$pre_test_object_deps_done" = no; then
 	 if test -z "$predep_objects_CXX"; then
-	   predep_objects_CXX=$p
+	   predep_objects_CXX="$p"
 	 else
 	   predep_objects_CXX="$predep_objects_CXX $p"
 	 fi
        else
 	 if test -z "$postdep_objects_CXX"; then
-	   postdep_objects_CXX=$p
+	   postdep_objects_CXX="$p"
 	 else
 	   postdep_objects_CXX="$postdep_objects_CXX $p"
 	 fi
@@ -14069,6 +13496,51 @@ interix[3-9]*)
   postdep_objects_CXX=
   postdeps_CXX=
   ;;
+
+linux*)
+  case `$CC -V 2>&1 | sed 5q` in
+  *Sun\ C*)
+    # Sun C++ 5.9
+
+    # The more standards-conforming stlport4 library is
+    # incompatible with the Cstd library. Avoid specifying
+    # it if it's in CXXFLAGS. Ignore libCrun as
+    # -library=stlport4 depends on it.
+    case " $CXX $CXXFLAGS " in
+    *" -library=stlport4 "*)
+      solaris_use_stlport4=yes
+      ;;
+    esac
+
+    if test "$solaris_use_stlport4" != yes; then
+      postdeps_CXX='-library=Cstd -library=Crun'
+    fi
+    ;;
+  esac
+  ;;
+
+solaris*)
+  case $cc_basename in
+  CC* | sunCC*)
+    # The more standards-conforming stlport4 library is
+    # incompatible with the Cstd library. Avoid specifying
+    # it if it's in CXXFLAGS. Ignore libCrun as
+    # -library=stlport4 depends on it.
+    case " $CXX $CXXFLAGS " in
+    *" -library=stlport4 "*)
+      solaris_use_stlport4=yes
+      ;;
+    esac
+
+    # Adding this requires a known-good setup of shared libraries for
+    # Sun compiler versions before 5.6, else PIC objects from an old
+    # archive will be linked into the output, leading to subtle bugs.
+    if test "$solaris_use_stlport4" != yes; then
+      postdeps_CXX='-library=Cstd -library=Crun'
+    fi
+    ;;
+  esac
+  ;;
 esac
 
 
@@ -14077,7 +13549,7 @@ case " $postdeps_CXX " in
 esac
  compiler_lib_search_dirs_CXX=
 if test -n "${compiler_lib_search_path_CXX}"; then
- compiler_lib_search_dirs_CXX=`echo " ${compiler_lib_search_path_CXX}" | $SED -e 's! -L! !g' -e 's!^ !!'`
+ compiler_lib_search_dirs_CXX=`echo " ${compiler_lib_search_path_CXX}" | ${SED} -e 's! -L! !g' -e 's!^ !!'`
 fi
 
 
@@ -14116,18 +13588,17 @@ lt_prog_compiler_static_CXX=
 
 
   # C++ specific cases for pic, static, wl, etc.
-  if test yes = "$GXX"; then
+  if test "$GXX" = yes; then
     lt_prog_compiler_wl_CXX='-Wl,'
     lt_prog_compiler_static_CXX='-static'
 
     case $host_os in
     aix*)
       # All AIX code is PIC.
-      if test ia64 = "$host_cpu"; then
+      if test "$host_cpu" = ia64; then
 	# AIX 5 now supports IA64 processor
 	lt_prog_compiler_static_CXX='-Bstatic'
       fi
-      lt_prog_compiler_pic_CXX='-fPIC'
       ;;
 
     amigaos*)
@@ -14138,8 +13609,8 @@ lt_prog_compiler_static_CXX=
         ;;
       m68k)
             # FIXME: we need at least 68020 code to build shared libraries, but
-            # adding the '-m68020' flag to GCC prevents building anything better,
-            # like '-m68040'.
+            # adding the `-m68020' flag to GCC prevents building anything better,
+            # like `-m68040'.
             lt_prog_compiler_pic_CXX='-m68020 -resident32 -malways-restore-a4'
         ;;
       esac
@@ -14154,11 +13625,6 @@ lt_prog_compiler_static_CXX=
       # Although the cygwin gcc ignores -fPIC, still need this for old-style
       # (--disable-auto-import) libraries
       lt_prog_compiler_pic_CXX='-DDLL_EXPORT'
-      case $host_os in
-      os2*)
-	lt_prog_compiler_static_CXX='$wl-static'
-	;;
-      esac
       ;;
     darwin* | rhapsody*)
       # PIC is the default on this platform
@@ -14208,7 +13674,7 @@ lt_prog_compiler_static_CXX=
     case $host_os in
       aix[4-9]*)
 	# All AIX code is PIC.
-	if test ia64 = "$host_cpu"; then
+	if test "$host_cpu" = ia64; then
 	  # AIX 5 now supports IA64 processor
 	  lt_prog_compiler_static_CXX='-Bstatic'
 	else
@@ -14248,14 +13714,14 @@ lt_prog_compiler_static_CXX=
 	case $cc_basename in
 	  CC*)
 	    lt_prog_compiler_wl_CXX='-Wl,'
-	    lt_prog_compiler_static_CXX='$wl-a ${wl}archive'
-	    if test ia64 != "$host_cpu"; then
+	    lt_prog_compiler_static_CXX='${wl}-a ${wl}archive'
+	    if test "$host_cpu" != ia64; then
 	      lt_prog_compiler_pic_CXX='+Z'
 	    fi
 	    ;;
 	  aCC*)
 	    lt_prog_compiler_wl_CXX='-Wl,'
-	    lt_prog_compiler_static_CXX='$wl-a ${wl}archive'
+	    lt_prog_compiler_static_CXX='${wl}-a ${wl}archive'
 	    case $host_cpu in
 	    hppa*64*|ia64*)
 	      # +Z the default
@@ -14292,7 +13758,7 @@ lt_prog_compiler_static_CXX=
 	    lt_prog_compiler_pic_CXX='-fPIC'
 	    ;;
 	  ecpc* )
-	    # old Intel C++ for x86_64, which still supported -KPIC.
+	    # old Intel C++ for x86_64 which still supported -KPIC.
 	    lt_prog_compiler_wl_CXX='-Wl,'
 	    lt_prog_compiler_pic_CXX='-KPIC'
 	    lt_prog_compiler_static_CXX='-static'
@@ -14437,7 +13903,7 @@ lt_prog_compiler_static_CXX=
   fi
 
 case $host_os in
-  # For platforms that do not support PIC, -DPIC is meaningless:
+  # For platforms which do not support PIC, -DPIC is meaningless:
   *djgpp*)
     lt_prog_compiler_pic_CXX=
     ;;
@@ -14469,7 +13935,7 @@ else
   lt_cv_prog_compiler_pic_works_CXX=no
    ac_outfile=conftest.$ac_objext
    echo "$lt_simple_compile_test_code" > conftest.$ac_ext
-   lt_compiler_flag="$lt_prog_compiler_pic_CXX -DPIC"  ## exclude from sc_useless_quotes_in_assignment
+   lt_compiler_flag="$lt_prog_compiler_pic_CXX -DPIC"
    # Insert the option either (1) after the last *FLAGS variable, or
    # (2) before a word containing "conftest.", or (3) at the end.
    # Note that $ac_compile itself does not contain backslashes and begins
@@ -14499,7 +13965,7 @@ fi
 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_works_CXX" >&5
 $as_echo "$lt_cv_prog_compiler_pic_works_CXX" >&6; }
 
-if test yes = "$lt_cv_prog_compiler_pic_works_CXX"; then
+if test x"$lt_cv_prog_compiler_pic_works_CXX" = xyes; then
     case $lt_prog_compiler_pic_CXX in
      "" | " "*) ;;
      *) lt_prog_compiler_pic_CXX=" $lt_prog_compiler_pic_CXX" ;;
@@ -14525,7 +13991,7 @@ if ${lt_cv_prog_compiler_static_works_CXX+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   lt_cv_prog_compiler_static_works_CXX=no
-   save_LDFLAGS=$LDFLAGS
+   save_LDFLAGS="$LDFLAGS"
    LDFLAGS="$LDFLAGS $lt_tmp_static_flag"
    echo "$lt_simple_link_test_code" > conftest.$ac_ext
    if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then
@@ -14544,13 +14010,13 @@ else
      fi
    fi
    $RM -r conftest*
-   LDFLAGS=$save_LDFLAGS
+   LDFLAGS="$save_LDFLAGS"
 
 fi
 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_static_works_CXX" >&5
 $as_echo "$lt_cv_prog_compiler_static_works_CXX" >&6; }
 
-if test yes = "$lt_cv_prog_compiler_static_works_CXX"; then
+if test x"$lt_cv_prog_compiler_static_works_CXX" = xyes; then
     :
 else
     lt_prog_compiler_static_CXX=
@@ -14664,8 +14130,8 @@ $as_echo "$lt_cv_prog_compiler_c_o_CXX" >&6; }
 
 
 
-hard_links=nottested
-if test no = "$lt_cv_prog_compiler_c_o_CXX" && test no != "$need_locks"; then
+hard_links="nottested"
+if test "$lt_cv_prog_compiler_c_o_CXX" = no && test "$need_locks" != no; then
   # do not overwrite the value of need_locks provided by the user
   { $as_echo "$as_me:${as_lineno-$LINENO}: checking if we can lock with hard links" >&5
 $as_echo_n "checking if we can lock with hard links... " >&6; }
@@ -14677,9 +14143,9 @@ $as_echo_n "checking if we can lock with hard links... " >&6; }
   ln conftest.a conftest.b 2>/dev/null && hard_links=no
   { $as_echo "$as_me:${as_lineno-$LINENO}: result: $hard_links" >&5
 $as_echo "$hard_links" >&6; }
-  if test no = "$hard_links"; then
-    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: '$CC' does not support '-c -o', so 'make -j' may be unsafe" >&5
-$as_echo "$as_me: WARNING: '$CC' does not support '-c -o', so 'make -j' may be unsafe" >&2;}
+  if test "$hard_links" = no; then
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&5
+$as_echo "$as_me: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&2;}
     need_locks=warn
   fi
 else
@@ -14696,21 +14162,17 @@ $as_echo_n "checking whether the $compiler linker ($LD) supports shared librarie
   case $host_os in
   aix[4-9]*)
     # If we're using GNU nm, then we don't want the "-C" option.
-    # -C means demangle to GNU nm, but means don't demangle to AIX nm.
-    # Without the "-l" option, or with the "-B" option, AIX nm treats
-    # weak defined symbols like other global defined symbols, whereas
-    # GNU nm marks them as "W".
-    # While the 'weak' keyword is ignored in the Export File, we need
-    # it in the Import File for the 'aix-soname' feature, so we have
-    # to replace the "-B" option with "-P" for AIX nm.
+    # -C means demangle to AIX nm, but means don't demangle with GNU nm
+    # Also, AIX nm treats weak defined symbols like other global defined
+    # symbols, whereas GNU nm marks them as "W".
     if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then
-      export_symbols_cmds_CXX='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && (substr(\$ 3,1,1) != ".")) { if (\$ 2 == "W") { print \$ 3 " weak" } else { print \$ 3 } } }'\'' | sort -u > $export_symbols'
+      export_symbols_cmds_CXX='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols'
     else
-      export_symbols_cmds_CXX='`func_echo_all $NM | $SED -e '\''s/B\([^B]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && (substr(\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols'
+      export_symbols_cmds_CXX='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols'
     fi
     ;;
   pw32*)
-    export_symbols_cmds_CXX=$ltdll_cmds
+    export_symbols_cmds_CXX="$ltdll_cmds"
     ;;
   cygwin* | mingw* | cegcc*)
     case $cc_basename in
@@ -14733,7 +14195,7 @@ $as_echo_n "checking whether the $compiler linker ($LD) supports shared librarie
 
 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs_CXX" >&5
 $as_echo "$ld_shlibs_CXX" >&6; }
-test no = "$ld_shlibs_CXX" && can_build_shared=no
+test "$ld_shlibs_CXX" = no && can_build_shared=no
 
 with_gnu_ld_CXX=$with_gnu_ld
 
@@ -14750,7 +14212,7 @@ x|xyes)
   # Assume -lc should be added
   archive_cmds_need_lc_CXX=yes
 
-  if test yes,yes = "$GCC,$enable_shared"; then
+  if test "$enable_shared" = yes && test "$GCC" = yes; then
     case $archive_cmds_CXX in
     *'~'*)
       # FIXME: we may have to deal with multi-command sequences.
@@ -14878,7 +14340,7 @@ $as_echo_n "checking dynamic linker characteristics... " >&6; }
 library_names_spec=
 libname_spec='lib$name'
 soname_spec=
-shrext_cmds=.so
+shrext_cmds=".so"
 postinstall_cmds=
 postuninstall_cmds=
 finish_cmds=
@@ -14895,16 +14357,14 @@ hardcode_into_libs=no
 # flags to be left without arguments
 need_version=unknown
 
-
-
 case $host_os in
 aix3*)
   version_type=linux # correct to gnu/linux during the next big refactor
-  library_names_spec='$libname$release$shared_ext$versuffix $libname.a'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a'
   shlibpath_var=LIBPATH
 
   # AIX 3 has no versioning support, so we append a major version to the name.
-  soname_spec='$libname$release$shared_ext$major'
+  soname_spec='${libname}${release}${shared_ext}$major'
   ;;
 
 aix[4-9]*)
@@ -14912,91 +14372,41 @@ aix[4-9]*)
   need_lib_prefix=no
   need_version=no
   hardcode_into_libs=yes
-  if test ia64 = "$host_cpu"; then
+  if test "$host_cpu" = ia64; then
     # AIX 5 supports IA64
-    library_names_spec='$libname$release$shared_ext$major $libname$release$shared_ext$versuffix $libname$shared_ext'
+    library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}'
     shlibpath_var=LD_LIBRARY_PATH
   else
     # With GCC up to 2.95.x, collect2 would create an import file
     # for dependence libraries.  The import file would start with
-    # the line '#! .'.  This would cause the generated library to
-    # depend on '.', always an invalid library.  This was fixed in
+    # the line `#! .'.  This would cause the generated library to
+    # depend on `.', always an invalid library.  This was fixed in
     # development snapshots of GCC prior to 3.0.
     case $host_os in
       aix4 | aix4.[01] | aix4.[01].*)
       if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)'
 	   echo ' yes '
-	   echo '#endif'; } | $CC -E - | $GREP yes > /dev/null; then
+	   echo '#endif'; } | ${CC} -E - | $GREP yes > /dev/null; then
 	:
       else
 	can_build_shared=no
       fi
       ;;
     esac
-    # Using Import Files as archive members, it is possible to support
-    # filename-based versioning of shared library archives on AIX. While
-    # this would work for both with and without runtime linking, it will
-    # prevent static linking of such archives. So we do filename-based
-    # shared library versioning with .so extension only, which is used
-    # when both runtime linking and shared linking is enabled.
-    # Unfortunately, runtime linking may impact performance, so we do
-    # not want this to be the default eventually. Also, we use the
-    # versioned .so libs for executables only if there is the -brtl
-    # linker flag in LDFLAGS as well, or --with-aix-soname=svr4 only.
-    # To allow for filename-based versioning support, we need to create
-    # libNAME.so.V as an archive file, containing:
-    # *) an Import File, referring to the versioned filename of the
-    #    archive as well as the shared archive member, telling the
-    #    bitwidth (32 or 64) of that shared object, and providing the
-    #    list of exported symbols of that shared object, eventually
-    #    decorated with the 'weak' keyword
-    # *) the shared object with the F_LOADONLY flag set, to really avoid
-    #    it being seen by the linker.
-    # At run time we better use the real file rather than another symlink,
-    # but for link time we create the symlink libNAME.so -> libNAME.so.V
-
-    case $with_aix_soname,$aix_use_runtimelinking in
-    # AIX (on Power*) has no versioning support, so currently we cannot hardcode correct
+    # AIX (on Power*) has no versioning support, so currently we can not hardcode correct
     # soname into executable. Probably we can add versioning support to
     # collect2, so additional links can be useful in future.
-    aix,yes) # traditional libtool
-      dynamic_linker='AIX unversionable lib.so'
+    if test "$aix_use_runtimelinking" = yes; then
       # If using run time linking (on AIX 4.2 or later) use lib<name>.so
       # instead of lib<name>.a to let people know that these are not
       # typical AIX shared libraries.
-      library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
-      ;;
-    aix,no) # traditional AIX only
-      dynamic_linker='AIX lib.a(lib.so.V)'
+      library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+    else
       # We preserve .a as extension for shared libraries through AIX4.2
       # and later when we are not doing run time linking.
-      library_names_spec='$libname$release.a $libname.a'
-      soname_spec='$libname$release$shared_ext$major'
-      ;;
-    svr4,*) # full svr4 only
-      dynamic_linker="AIX lib.so.V($shared_archive_member_spec.o)"
-      library_names_spec='$libname$release$shared_ext$major $libname$shared_ext'
-      # We do not specify a path in Import Files, so LIBPATH fires.
-      shlibpath_overrides_runpath=yes
-      ;;
-    *,yes) # both, prefer svr4
-      dynamic_linker="AIX lib.so.V($shared_archive_member_spec.o), lib.a(lib.so.V)"
-      library_names_spec='$libname$release$shared_ext$major $libname$shared_ext'
-      # unpreferred sharedlib libNAME.a needs extra handling
-      postinstall_cmds='test -n "$linkname" || linkname="$realname"~func_stripname "" ".so" "$linkname"~$install_shared_prog "$dir/$func_stripname_result.$libext" "$destdir/$func_stripname_result.$libext"~test -z "$tstripme" || test -z "$striplib" || $striplib "$destdir/$func_stripname_result.$libext"'
-      postuninstall_cmds='for n in $library_names $old_library; do :; done~func_stripname "" ".so" "$n"~test "$func_stripname_result" = "$n" || func_append rmfiles " $odir/$func_stripname_result.$libext"'
-      # We do not specify a path in Import Files, so LIBPATH fires.
-      shlibpath_overrides_runpath=yes
-      ;;
-    *,no) # both, prefer aix
-      dynamic_linker="AIX lib.a(lib.so.V), lib.so.V($shared_archive_member_spec.o)"
-      library_names_spec='$libname$release.a $libname.a'
-      soname_spec='$libname$release$shared_ext$major'
-      # unpreferred sharedlib libNAME.so.V and symlink libNAME.so need extra handling
-      postinstall_cmds='test -z "$dlname" || $install_shared_prog $dir/$dlname $destdir/$dlname~test -z "$tstripme" || test -z "$striplib" || $striplib $destdir/$dlname~test -n "$linkname" || linkname=$realname~func_stripname "" ".a" "$linkname"~(cd "$destdir" && $LN_S -f $dlname $func_stripname_result.so)'
-      postuninstall_cmds='test -z "$dlname" || func_append rmfiles " $odir/$dlname"~for n in $old_library $library_names; do :; done~func_stripname "" ".a" "$n"~func_append rmfiles " $odir/$func_stripname_result.so"'
-      ;;
-    esac
+      library_names_spec='${libname}${release}.a $libname.a'
+      soname_spec='${libname}${release}${shared_ext}$major'
+    fi
     shlibpath_var=LIBPATH
   fi
   ;;
@@ -15006,18 +14416,18 @@ amigaos*)
   powerpc)
     # Since July 2007 AmigaOS4 officially supports .so libraries.
     # When compiling the executable, add -use-dynld -Lsobjs: to the compileline.
-    library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
     ;;
   m68k)
     library_names_spec='$libname.ixlibrary $libname.a'
     # Create ${libname}_ixlibrary.a entries in /sys/libs.
-    finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done'
+    finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done'
     ;;
   esac
   ;;
 
 beos*)
-  library_names_spec='$libname$shared_ext'
+  library_names_spec='${libname}${shared_ext}'
   dynamic_linker="$host_os ld.so"
   shlibpath_var=LIBRARY_PATH
   ;;
@@ -15025,8 +14435,8 @@ beos*)
 bsdi[45]*)
   version_type=linux # correct to gnu/linux during the next big refactor
   need_version=no
-  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
-  soname_spec='$libname$release$shared_ext$major'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
   finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir'
   shlibpath_var=LD_LIBRARY_PATH
   sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib"
@@ -15038,7 +14448,7 @@ bsdi[45]*)
 
 cygwin* | mingw* | pw32* | cegcc*)
   version_type=windows
-  shrext_cmds=.dll
+  shrext_cmds=".dll"
   need_version=no
   need_lib_prefix=no
 
@@ -15047,8 +14457,8 @@ cygwin* | mingw* | pw32* | cegcc*)
     # gcc
     library_names_spec='$libname.dll.a'
     # DLL is installed to $(libdir)/../bin by postinstall_cmds
-    postinstall_cmds='base_file=`basename \$file`~
-      dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~
+    postinstall_cmds='base_file=`basename \${file}`~
+      dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~
       dldir=$destdir/`dirname \$dlpath`~
       test -d \$dldir || mkdir -p \$dldir~
       $install_prog $dir/$dlname \$dldir/$dlname~
@@ -15064,16 +14474,16 @@ cygwin* | mingw* | pw32* | cegcc*)
     case $host_os in
     cygwin*)
       # Cygwin DLLs use 'cyg' prefix rather than 'lib'
-      soname_spec='`echo $libname | sed -e 's/^lib/cyg/'``echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext'
+      soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
 
       ;;
     mingw* | cegcc*)
       # MinGW DLLs use traditional 'lib' prefix
-      soname_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext'
+      soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
       ;;
     pw32*)
       # pw32 DLLs use 'pw' prefix rather than 'lib'
-      library_names_spec='`echo $libname | sed -e 's/^lib/pw/'``echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext'
+      library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
       ;;
     esac
     dynamic_linker='Win32 ld.exe'
@@ -15082,8 +14492,8 @@ cygwin* | mingw* | pw32* | cegcc*)
   *,cl*)
     # Native MSVC
     libname_spec='$name'
-    soname_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext'
-    library_names_spec='$libname.dll.lib'
+    soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
+    library_names_spec='${libname}.dll.lib'
 
     case $build_os in
     mingw*)
@@ -15110,7 +14520,7 @@ cygwin* | mingw* | pw32* | cegcc*)
       sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"`
       ;;
     *)
-      sys_lib_search_path_spec=$LIB
+      sys_lib_search_path_spec="$LIB"
       if $ECHO "$sys_lib_search_path_spec" | $GREP ';[c-zC-Z]:/' >/dev/null; then
         # It is most probably a Windows format PATH.
         sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'`
@@ -15123,8 +14533,8 @@ cygwin* | mingw* | pw32* | cegcc*)
     esac
 
     # DLL is installed to $(libdir)/../bin by postinstall_cmds
-    postinstall_cmds='base_file=`basename \$file`~
-      dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~
+    postinstall_cmds='base_file=`basename \${file}`~
+      dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~
       dldir=$destdir/`dirname \$dlpath`~
       test -d \$dldir || mkdir -p \$dldir~
       $install_prog $dir/$dlname \$dldir/$dlname'
@@ -15137,7 +14547,7 @@ cygwin* | mingw* | pw32* | cegcc*)
 
   *)
     # Assume MSVC wrapper
-    library_names_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext $libname.lib'
+    library_names_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext} $libname.lib'
     dynamic_linker='Win32 ld.exe'
     ;;
   esac
@@ -15150,8 +14560,8 @@ darwin* | rhapsody*)
   version_type=darwin
   need_lib_prefix=no
   need_version=no
-  library_names_spec='$libname$release$major$shared_ext $libname$shared_ext'
-  soname_spec='$libname$release$major$shared_ext'
+  library_names_spec='${libname}${release}${major}$shared_ext ${libname}$shared_ext'
+  soname_spec='${libname}${release}${major}$shared_ext'
   shlibpath_overrides_runpath=yes
   shlibpath_var=DYLD_LIBRARY_PATH
   shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`'
@@ -15163,8 +14573,8 @@ dgux*)
   version_type=linux # correct to gnu/linux during the next big refactor
   need_lib_prefix=no
   need_version=no
-  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
-  soname_spec='$libname$release$shared_ext$major'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext'
+  soname_spec='${libname}${release}${shared_ext}$major'
   shlibpath_var=LD_LIBRARY_PATH
   ;;
 
@@ -15182,13 +14592,12 @@ freebsd* | dragonfly*)
   version_type=freebsd-$objformat
   case $version_type in
     freebsd-elf*)
-      library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
-      soname_spec='$libname$release$shared_ext$major'
+      library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}'
       need_version=no
       need_lib_prefix=no
       ;;
     freebsd-*)
-      library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix'
+      library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix'
       need_version=yes
       ;;
   esac
@@ -15218,10 +14627,10 @@ haiku*)
   need_lib_prefix=no
   need_version=no
   dynamic_linker="$host_os runtime_loader"
-  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
-  soname_spec='$libname$release$shared_ext$major'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
   shlibpath_var=LIBRARY_PATH
-  shlibpath_overrides_runpath=no
+  shlibpath_overrides_runpath=yes
   sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib'
   hardcode_into_libs=yes
   ;;
@@ -15239,15 +14648,14 @@ hpux9* | hpux10* | hpux11*)
     dynamic_linker="$host_os dld.so"
     shlibpath_var=LD_LIBRARY_PATH
     shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
-    library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
-    soname_spec='$libname$release$shared_ext$major'
-    if test 32 = "$HPUX_IA64_MODE"; then
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+    soname_spec='${libname}${release}${shared_ext}$major'
+    if test "X$HPUX_IA64_MODE" = X32; then
       sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib"
-      sys_lib_dlsearch_path_spec=/usr/lib/hpux32
     else
       sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64"
-      sys_lib_dlsearch_path_spec=/usr/lib/hpux64
     fi
+    sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
     ;;
   hppa*64*)
     shrext_cmds='.sl'
@@ -15255,8 +14663,8 @@ hpux9* | hpux10* | hpux11*)
     dynamic_linker="$host_os dld.sl"
     shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH
     shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
-    library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
-    soname_spec='$libname$release$shared_ext$major'
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+    soname_spec='${libname}${release}${shared_ext}$major'
     sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64"
     sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
     ;;
@@ -15265,8 +14673,8 @@ hpux9* | hpux10* | hpux11*)
     dynamic_linker="$host_os dld.sl"
     shlibpath_var=SHLIB_PATH
     shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH
-    library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
-    soname_spec='$libname$release$shared_ext$major'
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+    soname_spec='${libname}${release}${shared_ext}$major'
     ;;
   esac
   # HP-UX runs *really* slowly unless shared libraries are mode 555, ...
@@ -15279,8 +14687,8 @@ interix[3-9]*)
   version_type=linux # correct to gnu/linux during the next big refactor
   need_lib_prefix=no
   need_version=no
-  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
-  soname_spec='$libname$release$shared_ext$major'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
   dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)'
   shlibpath_var=LD_LIBRARY_PATH
   shlibpath_overrides_runpath=no
@@ -15291,7 +14699,7 @@ irix5* | irix6* | nonstopux*)
   case $host_os in
     nonstopux*) version_type=nonstopux ;;
     *)
-	if test yes = "$lt_cv_prog_gnu_ld"; then
+	if test "$lt_cv_prog_gnu_ld" = yes; then
 		version_type=linux # correct to gnu/linux during the next big refactor
 	else
 		version_type=irix
@@ -15299,8 +14707,8 @@ irix5* | irix6* | nonstopux*)
   esac
   need_lib_prefix=no
   need_version=no
-  soname_spec='$libname$release$shared_ext$major'
-  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$release$shared_ext $libname$shared_ext'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}'
   case $host_os in
   irix5* | nonstopux*)
     libsuff= shlibsuff=
@@ -15319,8 +14727,8 @@ irix5* | irix6* | nonstopux*)
   esac
   shlibpath_var=LD_LIBRARY${shlibsuff}_PATH
   shlibpath_overrides_runpath=no
-  sys_lib_search_path_spec="/usr/lib$libsuff /lib$libsuff /usr/local/lib$libsuff"
-  sys_lib_dlsearch_path_spec="/usr/lib$libsuff /lib$libsuff"
+  sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}"
+  sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}"
   hardcode_into_libs=yes
   ;;
 
@@ -15329,33 +14737,13 @@ linux*oldld* | linux*aout* | linux*coff*)
   dynamic_linker=no
   ;;
 
-linux*android*)
-  version_type=none # Android doesn't support versioned libraries.
-  need_lib_prefix=no
-  need_version=no
-  library_names_spec='$libname$release$shared_ext'
-  soname_spec='$libname$release$shared_ext'
-  finish_cmds=
-  shlibpath_var=LD_LIBRARY_PATH
-  shlibpath_overrides_runpath=yes
-
-  # This implies no fast_install, which is unacceptable.
-  # Some rework will be needed to allow for fast_install
-  # before this can be enabled.
-  hardcode_into_libs=yes
-
-  dynamic_linker='Android linker'
-  # Don't embed -rpath directories since the linker doesn't support them.
-  hardcode_libdir_flag_spec_CXX='-L$libdir'
-  ;;
-
 # This must be glibc/ELF.
 linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*)
   version_type=linux # correct to gnu/linux during the next big refactor
   need_lib_prefix=no
   need_version=no
-  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
-  soname_spec='$libname$release$shared_ext$major'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
   finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir'
   shlibpath_var=LD_LIBRARY_PATH
   shlibpath_overrides_runpath=no
@@ -15399,12 +14787,7 @@ fi
   # before this can be enabled.
   hardcode_into_libs=yes
 
-  # Ideally, we could use ldconfig to report *all* directores which are
-  # searched for libraries, however this is still not possible.  Aside from not
-  # being certain /sbin/ldconfig is available, command
-  # 'ldconfig -N -X -v | grep ^/' on 64bit Fedora does not report /usr/lib64,
-  # even though it is searched at run-time.  Try to do the best guess by
-  # appending ld.so.conf contents (and includes) to the search path.
+  # Append ld.so.conf contents to the search path
   if test -f /etc/ld.so.conf; then
     lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[	 ]*hwcap[	 ]/d;s/[:,	]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '`
     sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra"
@@ -15436,12 +14819,12 @@ netbsd*)
   need_lib_prefix=no
   need_version=no
   if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
-    library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix'
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
     finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
     dynamic_linker='NetBSD (a.out) ld.so'
   else
-    library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
-    soname_spec='$libname$release$shared_ext$major'
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+    soname_spec='${libname}${release}${shared_ext}$major'
     dynamic_linker='NetBSD ld.elf_so'
   fi
   shlibpath_var=LD_LIBRARY_PATH
@@ -15451,7 +14834,7 @@ netbsd*)
 
 newsos6)
   version_type=linux # correct to gnu/linux during the next big refactor
-  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
   shlibpath_var=LD_LIBRARY_PATH
   shlibpath_overrides_runpath=yes
   ;;
@@ -15460,68 +14843,58 @@ newsos6)
   version_type=qnx
   need_lib_prefix=no
   need_version=no
-  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
-  soname_spec='$libname$release$shared_ext$major'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
   shlibpath_var=LD_LIBRARY_PATH
   shlibpath_overrides_runpath=no
   hardcode_into_libs=yes
   dynamic_linker='ldqnx.so'
   ;;
 
-openbsd* | bitrig*)
+openbsd*)
   version_type=sunos
-  sys_lib_dlsearch_path_spec=/usr/lib
+  sys_lib_dlsearch_path_spec="/usr/lib"
   need_lib_prefix=no
-  if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then
-    need_version=no
-  else
-    need_version=yes
-  fi
-  library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix'
+  # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs.
+  case $host_os in
+    openbsd3.3 | openbsd3.3.*)	need_version=yes ;;
+    *)				need_version=no  ;;
+  esac
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
   finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
   shlibpath_var=LD_LIBRARY_PATH
-  shlibpath_overrides_runpath=yes
+  if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+    case $host_os in
+      openbsd2.[89] | openbsd2.[89].*)
+	shlibpath_overrides_runpath=no
+	;;
+      *)
+	shlibpath_overrides_runpath=yes
+	;;
+      esac
+  else
+    shlibpath_overrides_runpath=yes
+  fi
   ;;
 
 os2*)
   libname_spec='$name'
-  version_type=windows
-  shrext_cmds=.dll
-  need_version=no
+  shrext_cmds=".dll"
   need_lib_prefix=no
-  # OS/2 can only load a DLL with a base name of 8 characters or less.
-  soname_spec='`test -n "$os2dllname" && libname="$os2dllname";
-    v=$($ECHO $release$versuffix | tr -d .-);
-    n=$($ECHO $libname | cut -b -$((8 - ${#v})) | tr . _);
-    $ECHO $n$v`$shared_ext'
-  library_names_spec='${libname}_dll.$libext'
+  library_names_spec='$libname${shared_ext} $libname.a'
   dynamic_linker='OS/2 ld.exe'
-  shlibpath_var=BEGINLIBPATH
-  sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib"
-  sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
-  postinstall_cmds='base_file=`basename \$file`~
-    dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; $ECHO \$dlname'\''`~
-    dldir=$destdir/`dirname \$dlpath`~
-    test -d \$dldir || mkdir -p \$dldir~
-    $install_prog $dir/$dlname \$dldir/$dlname~
-    chmod a+x \$dldir/$dlname~
-    if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then
-      eval '\''$striplib \$dldir/$dlname'\'' || exit \$?;
-    fi'
-  postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; $ECHO \$dlname'\''`~
-    dlpath=$dir/\$dldll~
-    $RM \$dlpath'
+  shlibpath_var=LIBPATH
   ;;
 
 osf3* | osf4* | osf5*)
   version_type=osf
   need_lib_prefix=no
   need_version=no
-  soname_spec='$libname$release$shared_ext$major'
-  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
   shlibpath_var=LD_LIBRARY_PATH
   sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib"
-  sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
+  sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec"
   ;;
 
 rdos*)
@@ -15532,8 +14905,8 @@ solaris*)
   version_type=linux # correct to gnu/linux during the next big refactor
   need_lib_prefix=no
   need_version=no
-  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
-  soname_spec='$libname$release$shared_ext$major'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
   shlibpath_var=LD_LIBRARY_PATH
   shlibpath_overrides_runpath=yes
   hardcode_into_libs=yes
@@ -15543,11 +14916,11 @@ solaris*)
 
 sunos4*)
   version_type=sunos
-  library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
   finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir'
   shlibpath_var=LD_LIBRARY_PATH
   shlibpath_overrides_runpath=yes
-  if test yes = "$with_gnu_ld"; then
+  if test "$with_gnu_ld" = yes; then
     need_lib_prefix=no
   fi
   need_version=yes
@@ -15555,8 +14928,8 @@ sunos4*)
 
 sysv4 | sysv4.3*)
   version_type=linux # correct to gnu/linux during the next big refactor
-  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
-  soname_spec='$libname$release$shared_ext$major'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
   shlibpath_var=LD_LIBRARY_PATH
   case $host_vendor in
     sni)
@@ -15577,24 +14950,24 @@ sysv4 | sysv4.3*)
   ;;
 
 sysv4*MP*)
-  if test -d /usr/nec; then
+  if test -d /usr/nec ;then
     version_type=linux # correct to gnu/linux during the next big refactor
-    library_names_spec='$libname$shared_ext.$versuffix $libname$shared_ext.$major $libname$shared_ext'
-    soname_spec='$libname$shared_ext.$major'
+    library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}'
+    soname_spec='$libname${shared_ext}.$major'
     shlibpath_var=LD_LIBRARY_PATH
   fi
   ;;
 
 sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
-  version_type=sco
+  version_type=freebsd-elf
   need_lib_prefix=no
   need_version=no
-  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext $libname$shared_ext'
-  soname_spec='$libname$release$shared_ext$major'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
   shlibpath_var=LD_LIBRARY_PATH
   shlibpath_overrides_runpath=yes
   hardcode_into_libs=yes
-  if test yes = "$with_gnu_ld"; then
+  if test "$with_gnu_ld" = yes; then
     sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib'
   else
     sys_lib_search_path_spec='/usr/ccs/lib /usr/lib'
@@ -15612,7 +14985,7 @@ tpf*)
   version_type=linux # correct to gnu/linux during the next big refactor
   need_lib_prefix=no
   need_version=no
-  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
   shlibpath_var=LD_LIBRARY_PATH
   shlibpath_overrides_runpath=no
   hardcode_into_libs=yes
@@ -15620,8 +14993,8 @@ tpf*)
 
 uts4*)
   version_type=linux # correct to gnu/linux during the next big refactor
-  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
-  soname_spec='$libname$release$shared_ext$major'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
   shlibpath_var=LD_LIBRARY_PATH
   ;;
 
@@ -15631,32 +15004,20 @@ uts4*)
 esac
 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $dynamic_linker" >&5
 $as_echo "$dynamic_linker" >&6; }
-test no = "$dynamic_linker" && can_build_shared=no
+test "$dynamic_linker" = no && can_build_shared=no
 
 variables_saved_for_relink="PATH $shlibpath_var $runpath_var"
-if test yes = "$GCC"; then
+if test "$GCC" = yes; then
   variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH"
 fi
 
-if test set = "${lt_cv_sys_lib_search_path_spec+set}"; then
-  sys_lib_search_path_spec=$lt_cv_sys_lib_search_path_spec
+if test "${lt_cv_sys_lib_search_path_spec+set}" = set; then
+  sys_lib_search_path_spec="$lt_cv_sys_lib_search_path_spec"
 fi
-
-if test set = "${lt_cv_sys_lib_dlsearch_path_spec+set}"; then
-  sys_lib_dlsearch_path_spec=$lt_cv_sys_lib_dlsearch_path_spec
+if test "${lt_cv_sys_lib_dlsearch_path_spec+set}" = set; then
+  sys_lib_dlsearch_path_spec="$lt_cv_sys_lib_dlsearch_path_spec"
 fi
 
-# remember unaugmented sys_lib_dlsearch_path content for libtool script decls...
-configure_time_dlsearch_path=$sys_lib_dlsearch_path_spec
-
-# ... but it needs LT_SYS_LIBRARY_PATH munging for other configure-time code
-func_munge_path_list sys_lib_dlsearch_path_spec "$LT_SYS_LIBRARY_PATH"
-
-# to be used as default LT_SYS_LIBRARY_PATH value in generated libtool
-configure_time_lt_sys_library_path=$LT_SYS_LIBRARY_PATH
-
-
-
 
 
 
@@ -15699,15 +15060,15 @@ $as_echo_n "checking how to hardcode library paths into programs... " >&6; }
 hardcode_action_CXX=
 if test -n "$hardcode_libdir_flag_spec_CXX" ||
    test -n "$runpath_var_CXX" ||
-   test yes = "$hardcode_automatic_CXX"; then
+   test "X$hardcode_automatic_CXX" = "Xyes" ; then
 
   # We can hardcode non-existent directories.
-  if test no != "$hardcode_direct_CXX" &&
+  if test "$hardcode_direct_CXX" != no &&
      # If the only mechanism to avoid hardcoding is shlibpath_var, we
      # have to relink, otherwise we might link with an installed library
      # when we should be linking with a yet-to-be-installed one
-     ## test no != "$_LT_TAGVAR(hardcode_shlibpath_var, CXX)" &&
-     test no != "$hardcode_minus_L_CXX"; then
+     ## test "$_LT_TAGVAR(hardcode_shlibpath_var, CXX)" != no &&
+     test "$hardcode_minus_L_CXX" != no; then
     # Linking always hardcodes the temporary library directory.
     hardcode_action_CXX=relink
   else
@@ -15722,12 +15083,12 @@ fi
 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $hardcode_action_CXX" >&5
 $as_echo "$hardcode_action_CXX" >&6; }
 
-if test relink = "$hardcode_action_CXX" ||
-   test yes = "$inherit_rpath_CXX"; then
+if test "$hardcode_action_CXX" = relink ||
+   test "$inherit_rpath_CXX" = yes; then
   # Fast installation is not supported
   enable_fast_install=no
-elif test yes = "$shlibpath_overrides_runpath" ||
-     test no = "$enable_shared"; then
+elif test "$shlibpath_overrides_runpath" = yes ||
+     test "$enable_shared" = no; then
   # Fast installation is not necessary
   enable_fast_install=needless
 fi
@@ -15750,7 +15111,7 @@ fi
   lt_cv_path_LD=$lt_save_path_LD
   lt_cv_prog_gnu_ldcxx=$lt_cv_prog_gnu_ld
   lt_cv_prog_gnu_ld=$lt_save_with_gnu_ld
-fi # test yes != "$_lt_caught_CXX_error"
+fi # test "$_lt_caught_CXX_error" != yes
 
 ac_ext=cpp
 ac_cpp='$CXXCPP $CPPFLAGS'
@@ -17293,7 +16654,6 @@ enable_shared='`$ECHO "$enable_shared" | $SED "$delay_single_quote_subst"`'
 enable_static='`$ECHO "$enable_static" | $SED "$delay_single_quote_subst"`'
 pic_mode='`$ECHO "$pic_mode" | $SED "$delay_single_quote_subst"`'
 enable_fast_install='`$ECHO "$enable_fast_install" | $SED "$delay_single_quote_subst"`'
-shared_archive_member_spec='`$ECHO "$shared_archive_member_spec" | $SED "$delay_single_quote_subst"`'
 SHELL='`$ECHO "$SHELL" | $SED "$delay_single_quote_subst"`'
 ECHO='`$ECHO "$ECHO" | $SED "$delay_single_quote_subst"`'
 PATH_SEPARATOR='`$ECHO "$PATH_SEPARATOR" | $SED "$delay_single_quote_subst"`'
@@ -17343,13 +16703,10 @@ compiler='`$ECHO "$compiler" | $SED "$delay_single_quote_subst"`'
 GCC='`$ECHO "$GCC" | $SED "$delay_single_quote_subst"`'
 lt_cv_sys_global_symbol_pipe='`$ECHO "$lt_cv_sys_global_symbol_pipe" | $SED "$delay_single_quote_subst"`'
 lt_cv_sys_global_symbol_to_cdecl='`$ECHO "$lt_cv_sys_global_symbol_to_cdecl" | $SED "$delay_single_quote_subst"`'
-lt_cv_sys_global_symbol_to_import='`$ECHO "$lt_cv_sys_global_symbol_to_import" | $SED "$delay_single_quote_subst"`'
 lt_cv_sys_global_symbol_to_c_name_address='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address" | $SED "$delay_single_quote_subst"`'
 lt_cv_sys_global_symbol_to_c_name_address_lib_prefix='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address_lib_prefix" | $SED "$delay_single_quote_subst"`'
-lt_cv_nm_interface='`$ECHO "$lt_cv_nm_interface" | $SED "$delay_single_quote_subst"`'
 nm_file_list_spec='`$ECHO "$nm_file_list_spec" | $SED "$delay_single_quote_subst"`'
 lt_sysroot='`$ECHO "$lt_sysroot" | $SED "$delay_single_quote_subst"`'
-lt_cv_truncate_bin='`$ECHO "$lt_cv_truncate_bin" | $SED "$delay_single_quote_subst"`'
 objdir='`$ECHO "$objdir" | $SED "$delay_single_quote_subst"`'
 MAGIC_CMD='`$ECHO "$MAGIC_CMD" | $SED "$delay_single_quote_subst"`'
 lt_prog_compiler_no_builtin_flag='`$ECHO "$lt_prog_compiler_no_builtin_flag" | $SED "$delay_single_quote_subst"`'
@@ -17414,8 +16771,7 @@ finish_cmds='`$ECHO "$finish_cmds" | $SED "$delay_single_quote_subst"`'
 finish_eval='`$ECHO "$finish_eval" | $SED "$delay_single_quote_subst"`'
 hardcode_into_libs='`$ECHO "$hardcode_into_libs" | $SED "$delay_single_quote_subst"`'
 sys_lib_search_path_spec='`$ECHO "$sys_lib_search_path_spec" | $SED "$delay_single_quote_subst"`'
-configure_time_dlsearch_path='`$ECHO "$configure_time_dlsearch_path" | $SED "$delay_single_quote_subst"`'
-configure_time_lt_sys_library_path='`$ECHO "$configure_time_lt_sys_library_path" | $SED "$delay_single_quote_subst"`'
+sys_lib_dlsearch_path_spec='`$ECHO "$sys_lib_dlsearch_path_spec" | $SED "$delay_single_quote_subst"`'
 hardcode_action='`$ECHO "$hardcode_action" | $SED "$delay_single_quote_subst"`'
 enable_dlopen='`$ECHO "$enable_dlopen" | $SED "$delay_single_quote_subst"`'
 enable_dlopen_self='`$ECHO "$enable_dlopen_self" | $SED "$delay_single_quote_subst"`'
@@ -17520,12 +16876,9 @@ CFLAGS \
 compiler \
 lt_cv_sys_global_symbol_pipe \
 lt_cv_sys_global_symbol_to_cdecl \
-lt_cv_sys_global_symbol_to_import \
 lt_cv_sys_global_symbol_to_c_name_address \
 lt_cv_sys_global_symbol_to_c_name_address_lib_prefix \
-lt_cv_nm_interface \
 nm_file_list_spec \
-lt_cv_truncate_bin \
 lt_prog_compiler_no_builtin_flag \
 lt_prog_compiler_pic \
 lt_prog_compiler_wl \
@@ -17591,7 +16944,7 @@ postdeps_CXX \
 compiler_lib_search_path_CXX; do
     case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in
     *[\\\\\\\`\\"\\\$]*)
-      eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$sed_quote_subst\\"\\\`\\\\\\"" ## exclude from sc_prohibit_nested_quotes
+      eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$sed_quote_subst\\"\\\`\\\\\\""
       ;;
     *)
       eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\""
@@ -17618,8 +16971,7 @@ postinstall_cmds \
 postuninstall_cmds \
 finish_cmds \
 sys_lib_search_path_spec \
-configure_time_dlsearch_path \
-configure_time_lt_sys_library_path \
+sys_lib_dlsearch_path_spec \
 reload_cmds_CXX \
 old_archive_cmds_CXX \
 old_archive_from_new_cmds_CXX \
@@ -17633,7 +16985,7 @@ prelink_cmds_CXX \
 postlink_cmds_CXX; do
     case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in
     *[\\\\\\\`\\"\\\$]*)
-      eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\"" ## exclude from sc_prohibit_nested_quotes
+      eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\""
       ;;
     *)
       eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\""
@@ -17642,16 +16994,19 @@ postlink_cmds_CXX; do
 done
 
 ac_aux_dir='$ac_aux_dir'
+xsi_shell='$xsi_shell'
+lt_shell_append='$lt_shell_append'
 
-# See if we are running on zsh, and set the options that allow our
+# See if we are running on zsh, and set the options which allow our
 # commands through without removal of \ escapes INIT.
-if test -n "\${ZSH_VERSION+set}"; then
+if test -n "\${ZSH_VERSION+set}" ; then
    setopt NO_GLOB_SUBST
 fi
 
 
     PACKAGE='$PACKAGE'
     VERSION='$VERSION'
+    TIMESTAMP='$TIMESTAMP'
     RM='$RM'
     ofile='$ofile'
 
@@ -18364,53 +17719,55 @@ $as_echo X"$file" |
  ;;
     "libtool":C)
 
-    # See if we are running on zsh, and set the options that allow our
+    # See if we are running on zsh, and set the options which allow our
     # commands through without removal of \ escapes.
-    if test -n "${ZSH_VERSION+set}"; then
+    if test -n "${ZSH_VERSION+set}" ; then
       setopt NO_GLOB_SUBST
     fi
 
-    cfgfile=${ofile}T
+    cfgfile="${ofile}T"
     trap "$RM \"$cfgfile\"; exit 1" 1 2 15
     $RM "$cfgfile"
 
     cat <<_LT_EOF >> "$cfgfile"
 #! $SHELL
-# Generated automatically by $as_me ($PACKAGE) $VERSION
+
+# `$ECHO "$ofile" | sed 's%^.*/%%'` - Provide generalized library-building support services.
+# Generated automatically by $as_me ($PACKAGE$TIMESTAMP) $VERSION
 # Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
 # NOTE: Changes made to this file will be lost: look at ltmain.sh.
-
-# Provide generalized library-building support services.
-# Written by Gordon Matzigkeit, 1996
-
-# Copyright (C) 2014 Free Software Foundation, Inc.
-# This is free software; see the source for copying conditions.  There is NO
-# warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-
-# GNU Libtool is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of of the License, or
-# (at your option) any later version.
 #
-# As a special exception to the GNU General Public License, if you
-# distribute this file as part of a program or library that is built
-# using GNU Libtool, you may include this file under the  same
-# distribution terms that you use for the rest of that program.
+#   Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005,
+#                 2006, 2007, 2008, 2009, 2010, 2011 Free Software
+#                 Foundation, Inc.
+#   Written by Gordon Matzigkeit, 1996
+#
+#   This file is part of GNU Libtool.
 #
-# GNU Libtool is distributed in the hope that it will be useful, but
-# WITHOUT ANY WARRANTY; without even the implied warranty of
+# GNU Libtool is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2 of
+# the License, or (at your option) any later version.
+#
+# As a special exception to the GNU General Public License,
+# if you distribute this file as part of a program or library that
+# is built using GNU Libtool, you may include this file under the
+# same distribution terms that you use for the rest of that program.
+#
+# GNU Libtool is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 # GNU General Public License for more details.
 #
 # You should have received a copy of the GNU General Public License
-# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+# along with GNU Libtool; see the file COPYING.  If not, a copy
+# can be downloaded from http://www.gnu.org/licenses/gpl.html, or
+# obtained by writing to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 
 
 # The names of the tagged configurations supported by this script.
-available_tags='CXX '
-
-# Configured defaults for sys_lib_dlsearch_path munging.
-: \${LT_SYS_LIBRARY_PATH="$configure_time_lt_sys_library_path"}
+available_tags="CXX "
 
 # ### BEGIN LIBTOOL CONFIG
 
@@ -18430,9 +17787,6 @@ pic_mode=$pic_mode
 # Whether or not to optimize for fast installation.
 fast_install=$enable_fast_install
 
-# Shared archive member basename,for filename based shared library versioning on AIX.
-shared_archive_member_spec=$shared_archive_member_spec
-
 # Shell to use when invoking shell scripts.
 SHELL=$lt_SHELL
 
@@ -18550,27 +17904,18 @@ global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe
 # Transform the output of nm in a proper C declaration.
 global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl
 
-# Transform the output of nm into a list of symbols to manually relocate.
-global_symbol_to_import=$lt_lt_cv_sys_global_symbol_to_import
-
 # Transform the output of nm in a C name address pair.
 global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address
 
 # Transform the output of nm in a C name address pair when lib prefix is needed.
 global_symbol_to_c_name_address_lib_prefix=$lt_lt_cv_sys_global_symbol_to_c_name_address_lib_prefix
 
-# The name lister interface.
-nm_interface=$lt_lt_cv_nm_interface
-
 # Specify filename containing input files for \$NM.
 nm_file_list_spec=$lt_nm_file_list_spec
 
-# The root where to search for dependent libraries,and where our libraries should be installed.
+# The root where to search for dependent libraries,and in which our libraries should be installed.
 lt_sysroot=$lt_sysroot
 
-# Command to truncate a binary pipe.
-lt_truncate_bin=$lt_lt_cv_truncate_bin
-
 # The name of the directory that contains temporary libtool files.
 objdir=$objdir
 
@@ -18661,11 +18006,8 @@ hardcode_into_libs=$hardcode_into_libs
 # Compile-time system search path for libraries.
 sys_lib_search_path_spec=$lt_sys_lib_search_path_spec
 
-# Detected run-time system search path for libraries.
-sys_lib_dlsearch_path_spec=$lt_configure_time_dlsearch_path
-
-# Explicit LT_SYS_LIBRARY_PATH set during ./configure time.
-configure_time_lt_sys_library_path=$lt_configure_time_lt_sys_library_path
+# Run-time system search path for libraries.
+sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec
 
 # Whether dlopen is supported.
 dlopen_support=$enable_dlopen
@@ -18758,13 +18100,13 @@ hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec
 # Whether we need a single "-rpath" flag with a separated argument.
 hardcode_libdir_separator=$lt_hardcode_libdir_separator
 
-# Set to "yes" if using DIR/libNAME\$shared_ext during linking hardcodes
+# Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes
 # DIR into the resulting binary.
 hardcode_direct=$hardcode_direct
 
-# Set to "yes" if using DIR/libNAME\$shared_ext during linking hardcodes
+# Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes
 # DIR into the resulting binary and the resulting library dependency is
-# "absolute",i.e impossible to change by setting \$shlibpath_var if the
+# "absolute",i.e impossible to change by setting \${shlibpath_var} if the
 # library is relocated.
 hardcode_direct_absolute=$hardcode_direct_absolute
 
@@ -18830,72 +18172,13 @@ compiler_lib_search_path=$lt_compiler_lib_search_path
 
 _LT_EOF
 
-    cat <<'_LT_EOF' >> "$cfgfile"
-
-# ### BEGIN FUNCTIONS SHARED WITH CONFIGURE
-
-# func_munge_path_list VARIABLE PATH
-# -----------------------------------
-# VARIABLE is name of variable containing _space_ separated list of
-# directories to be munged by the contents of PATH, which is string
-# having a format:
-# "DIR[:DIR]:"
-#       string "DIR[ DIR]" will be prepended to VARIABLE
-# ":DIR[:DIR]"
-#       string "DIR[ DIR]" will be appended to VARIABLE
-# "DIRP[:DIRP]::[DIRA:]DIRA"
-#       string "DIRP[ DIRP]" will be prepended to VARIABLE and string
-#       "DIRA[ DIRA]" will be appended to VARIABLE
-# "DIR[:DIR]"
-#       VARIABLE will be replaced by "DIR[ DIR]"
-func_munge_path_list ()
-{
-    case x$2 in
-    x)
-        ;;
-    *:)
-        eval $1=\"`$ECHO $2 | $SED 's/:/ /g'` \$$1\"
-        ;;
-    x:*)
-        eval $1=\"\$$1 `$ECHO $2 | $SED 's/:/ /g'`\"
-        ;;
-    *::*)
-        eval $1=\"\$$1\ `$ECHO $2 | $SED -e 's/.*:://' -e 's/:/ /g'`\"
-        eval $1=\"`$ECHO $2 | $SED -e 's/::.*//' -e 's/:/ /g'`\ \$$1\"
-        ;;
-    *)
-        eval $1=\"`$ECHO $2 | $SED 's/:/ /g'`\"
-        ;;
-    esac
-}
-
-
-# Calculate cc_basename.  Skip known compiler wrappers and cross-prefix.
-func_cc_basename ()
-{
-    for cc_temp in $*""; do
-      case $cc_temp in
-        compile | *[\\/]compile | ccache | *[\\/]ccache ) ;;
-        distcc | *[\\/]distcc | purify | *[\\/]purify ) ;;
-        \-*) ;;
-        *) break;;
-      esac
-    done
-    func_cc_basename_result=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"`
-}
-
-
-# ### END FUNCTIONS SHARED WITH CONFIGURE
-
-_LT_EOF
-
   case $host_os in
   aix3*)
     cat <<\_LT_EOF >> "$cfgfile"
 # AIX sometimes has problems with the GCC collect2 program.  For some
 # reason, if we set the COLLECT_NAMES environment variable, the problems
 # vanish in a puff of smoke.
-if test set != "${COLLECT_NAMES+set}"; then
+if test "X${COLLECT_NAMES+set}" != Xset; then
   COLLECT_NAMES=
   export COLLECT_NAMES
 fi
@@ -18904,7 +18187,7 @@ _LT_EOF
   esac
 
 
-ltmain=$ac_aux_dir/ltmain.sh
+ltmain="$ac_aux_dir/ltmain.sh"
 
 
   # We use sed instead of cat because bash on DJGPP gets confused if
@@ -18914,6 +18197,165 @@ ltmain=$ac_aux_dir/ltmain.sh
   sed '$q' "$ltmain" >> "$cfgfile" \
      || (rm -f "$cfgfile"; exit 1)
 
+  if test x"$xsi_shell" = xyes; then
+  sed -e '/^func_dirname ()$/,/^} # func_dirname /c\
+func_dirname ()\
+{\
+\    case ${1} in\
+\      */*) func_dirname_result="${1%/*}${2}" ;;\
+\      *  ) func_dirname_result="${3}" ;;\
+\    esac\
+} # Extended-shell func_dirname implementation' "$cfgfile" > $cfgfile.tmp \
+  && mv -f "$cfgfile.tmp" "$cfgfile" \
+    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+  sed -e '/^func_basename ()$/,/^} # func_basename /c\
+func_basename ()\
+{\
+\    func_basename_result="${1##*/}"\
+} # Extended-shell func_basename implementation' "$cfgfile" > $cfgfile.tmp \
+  && mv -f "$cfgfile.tmp" "$cfgfile" \
+    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+  sed -e '/^func_dirname_and_basename ()$/,/^} # func_dirname_and_basename /c\
+func_dirname_and_basename ()\
+{\
+\    case ${1} in\
+\      */*) func_dirname_result="${1%/*}${2}" ;;\
+\      *  ) func_dirname_result="${3}" ;;\
+\    esac\
+\    func_basename_result="${1##*/}"\
+} # Extended-shell func_dirname_and_basename implementation' "$cfgfile" > $cfgfile.tmp \
+  && mv -f "$cfgfile.tmp" "$cfgfile" \
+    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+  sed -e '/^func_stripname ()$/,/^} # func_stripname /c\
+func_stripname ()\
+{\
+\    # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are\
+\    # positional parameters, so assign one to ordinary parameter first.\
+\    func_stripname_result=${3}\
+\    func_stripname_result=${func_stripname_result#"${1}"}\
+\    func_stripname_result=${func_stripname_result%"${2}"}\
+} # Extended-shell func_stripname implementation' "$cfgfile" > $cfgfile.tmp \
+  && mv -f "$cfgfile.tmp" "$cfgfile" \
+    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+  sed -e '/^func_split_long_opt ()$/,/^} # func_split_long_opt /c\
+func_split_long_opt ()\
+{\
+\    func_split_long_opt_name=${1%%=*}\
+\    func_split_long_opt_arg=${1#*=}\
+} # Extended-shell func_split_long_opt implementation' "$cfgfile" > $cfgfile.tmp \
+  && mv -f "$cfgfile.tmp" "$cfgfile" \
+    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+  sed -e '/^func_split_short_opt ()$/,/^} # func_split_short_opt /c\
+func_split_short_opt ()\
+{\
+\    func_split_short_opt_arg=${1#??}\
+\    func_split_short_opt_name=${1%"$func_split_short_opt_arg"}\
+} # Extended-shell func_split_short_opt implementation' "$cfgfile" > $cfgfile.tmp \
+  && mv -f "$cfgfile.tmp" "$cfgfile" \
+    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+  sed -e '/^func_lo2o ()$/,/^} # func_lo2o /c\
+func_lo2o ()\
+{\
+\    case ${1} in\
+\      *.lo) func_lo2o_result=${1%.lo}.${objext} ;;\
+\      *)    func_lo2o_result=${1} ;;\
+\    esac\
+} # Extended-shell func_lo2o implementation' "$cfgfile" > $cfgfile.tmp \
+  && mv -f "$cfgfile.tmp" "$cfgfile" \
+    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+  sed -e '/^func_xform ()$/,/^} # func_xform /c\
+func_xform ()\
+{\
+    func_xform_result=${1%.*}.lo\
+} # Extended-shell func_xform implementation' "$cfgfile" > $cfgfile.tmp \
+  && mv -f "$cfgfile.tmp" "$cfgfile" \
+    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+  sed -e '/^func_arith ()$/,/^} # func_arith /c\
+func_arith ()\
+{\
+    func_arith_result=$(( $* ))\
+} # Extended-shell func_arith implementation' "$cfgfile" > $cfgfile.tmp \
+  && mv -f "$cfgfile.tmp" "$cfgfile" \
+    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+  sed -e '/^func_len ()$/,/^} # func_len /c\
+func_len ()\
+{\
+    func_len_result=${#1}\
+} # Extended-shell func_len implementation' "$cfgfile" > $cfgfile.tmp \
+  && mv -f "$cfgfile.tmp" "$cfgfile" \
+    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+fi
+
+if test x"$lt_shell_append" = xyes; then
+  sed -e '/^func_append ()$/,/^} # func_append /c\
+func_append ()\
+{\
+    eval "${1}+=\\${2}"\
+} # Extended-shell func_append implementation' "$cfgfile" > $cfgfile.tmp \
+  && mv -f "$cfgfile.tmp" "$cfgfile" \
+    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+  sed -e '/^func_append_quoted ()$/,/^} # func_append_quoted /c\
+func_append_quoted ()\
+{\
+\    func_quote_for_eval "${2}"\
+\    eval "${1}+=\\\\ \\$func_quote_for_eval_result"\
+} # Extended-shell func_append_quoted implementation' "$cfgfile" > $cfgfile.tmp \
+  && mv -f "$cfgfile.tmp" "$cfgfile" \
+    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+  # Save a `func_append' function call where possible by direct use of '+='
+  sed -e 's%func_append \([a-zA-Z_]\{1,\}\) "%\1+="%g' $cfgfile > $cfgfile.tmp \
+    && mv -f "$cfgfile.tmp" "$cfgfile" \
+      || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+  test 0 -eq $? || _lt_function_replace_fail=:
+else
+  # Save a `func_append' function call even when '+=' is not available
+  sed -e 's%func_append \([a-zA-Z_]\{1,\}\) "%\1="$\1%g' $cfgfile > $cfgfile.tmp \
+    && mv -f "$cfgfile.tmp" "$cfgfile" \
+      || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+  test 0 -eq $? || _lt_function_replace_fail=:
+fi
+
+if test x"$_lt_function_replace_fail" = x":"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Unable to substitute extended shell functions in $ofile" >&5
+$as_echo "$as_me: WARNING: Unable to substitute extended shell functions in $ofile" >&2;}
+fi
+
+
    mv -f "$cfgfile" "$ofile" ||
     (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile")
   chmod +x "$ofile"
@@ -19000,13 +18442,13 @@ hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec_CXX
 # Whether we need a single "-rpath" flag with a separated argument.
 hardcode_libdir_separator=$lt_hardcode_libdir_separator_CXX
 
-# Set to "yes" if using DIR/libNAME\$shared_ext during linking hardcodes
+# Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes
 # DIR into the resulting binary.
 hardcode_direct=$hardcode_direct_CXX
 
-# Set to "yes" if using DIR/libNAME\$shared_ext during linking hardcodes
+# Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes
 # DIR into the resulting binary and the resulting library dependency is
-# "absolute",i.e impossible to change by setting \$shlibpath_var if the
+# "absolute",i.e impossible to change by setting \${shlibpath_var} if the
 # library is relocated.
 hardcode_direct_absolute=$hardcode_direct_absolute_CXX
 
diff --git a/src/gmock/gtest/Makefile.in b/src/gmock/gtest/Makefile.in
index 87f521f..1dc844f 100644
--- a/src/gmock/gtest/Makefile.in
+++ b/src/gmock/gtest/Makefile.in
@@ -1,7 +1,7 @@
-# Makefile.in generated by automake 1.15 from Makefile.am.
+# Makefile.in generated by automake 1.14.1 from Makefile.am.
 # @configure_input@
 
-# Copyright (C) 1994-2014 Free Software Foundation, Inc.
+# Copyright (C) 1994-2013 Free Software Foundation, Inc.
 
 # This Makefile.in is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -19,17 +19,7 @@
 
 
 VPATH = @srcdir@
-am__is_gnu_make = { \
-  if test -z '$(MAKELEVEL)'; then \
-    false; \
-  elif test -n '$(MAKE_HOST)'; then \
-    true; \
-  elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
-    true; \
-  else \
-    false; \
-  fi; \
-}
+am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
 am__make_running_with_option = \
   case $${target_option-} in \
       ?) ;; \
@@ -101,6 +91,21 @@ check_PROGRAMS = samples/sample1_unittest$(EXEEXT) \
 @HAVE_PYTHON_TRUE at am__append_1 = test/fused_gtest_test
 @HAVE_PYTHON_TRUE at am__append_2 = test/fused_gtest_test
 subdir = .
+DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
+	$(top_srcdir)/configure $(am__configure_deps) \
+	$(top_srcdir)/build-aux/config.h.in \
+	$(top_srcdir)/scripts/gtest-config.in \
+	$(top_srcdir)/build-aux/depcomp $(pkginclude_HEADERS) \
+	$(pkginclude_internal_HEADERS) \
+	$(top_srcdir)/build-aux/test-driver README build-aux/compile \
+	build-aux/config.guess build-aux/config.sub build-aux/depcomp \
+	build-aux/install-sh build-aux/missing build-aux/ltmain.sh \
+	$(top_srcdir)/build-aux/compile \
+	$(top_srcdir)/build-aux/config.guess \
+	$(top_srcdir)/build-aux/config.sub \
+	$(top_srcdir)/build-aux/install-sh \
+	$(top_srcdir)/build-aux/ltmain.sh \
+	$(top_srcdir)/build-aux/missing
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
 am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \
 	$(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
@@ -108,9 +113,6 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \
 	$(top_srcdir)/m4/acx_pthread.m4 $(top_srcdir)/configure.ac
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
 	$(ACLOCAL_M4)
-DIST_COMMON = $(srcdir)/Makefile.am $(top_srcdir)/configure \
-	$(am__configure_deps) $(pkginclude_HEADERS) \
-	$(pkginclude_internal_HEADERS) $(am__DIST_COMMON)
 am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \
  configure.lineno config.status.lineno
 mkinstalldirs = $(install_sh) -d
@@ -459,19 +461,6 @@ TEST_LOGS = $(am__test_logs2:.test.log=.log)
 TEST_LOG_DRIVER = $(SHELL) $(top_srcdir)/build-aux/test-driver
 TEST_LOG_COMPILE = $(TEST_LOG_COMPILER) $(AM_TEST_LOG_FLAGS) \
 	$(TEST_LOG_FLAGS)
-am__DIST_COMMON = $(srcdir)/Makefile.in \
-	$(top_srcdir)/build-aux/compile \
-	$(top_srcdir)/build-aux/config.guess \
-	$(top_srcdir)/build-aux/config.h.in \
-	$(top_srcdir)/build-aux/config.sub \
-	$(top_srcdir)/build-aux/depcomp \
-	$(top_srcdir)/build-aux/install-sh \
-	$(top_srcdir)/build-aux/ltmain.sh \
-	$(top_srcdir)/build-aux/missing \
-	$(top_srcdir)/build-aux/test-driver \
-	$(top_srcdir)/scripts/gtest-config.in README build-aux/compile \
-	build-aux/config.guess build-aux/config.sub build-aux/depcomp \
-	build-aux/install-sh build-aux/ltmain.sh build-aux/missing
 DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
 distdir = $(PACKAGE)-$(VERSION)
 top_distdir = $(distdir)
@@ -532,7 +521,6 @@ LIBTOOL = @LIBTOOL@
 LIPO = @LIPO@
 LN_S = @LN_S@
 LTLIBOBJS = @LTLIBOBJS@
-LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
 MAKEINFO = @MAKEINFO@
 MANIFEST_TOOL = @MANIFEST_TOOL@
 MKDIR_P = @MKDIR_P@
@@ -606,7 +594,6 @@ pdfdir = @pdfdir@
 prefix = @prefix@
 program_transform_name = @program_transform_name@
 psdir = @psdir@
-runstatedir = @runstatedir@
 sbindir = @sbindir@
 sharedstatedir = @sharedstatedir@
 srcdir = @srcdir@
@@ -827,6 +814,7 @@ $(srcdir)/Makefile.in:  $(srcdir)/Makefile.am  $(am__configure_deps)
 	echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign Makefile'; \
 	$(am__cd) $(top_srcdir) && \
 	  $(AUTOMAKE) --foreign Makefile
+.PRECIOUS: Makefile
 Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
 	@case '$?' in \
 	  *config.status*) \
@@ -1229,7 +1217,7 @@ $(TEST_SUITE_LOG): $(TEST_LOGS)
 	if test -n "$$am__remaking_logs"; then \
 	  echo "fatal: making $(TEST_SUITE_LOG): possible infinite" \
 	       "recursion detected" >&2; \
-	elif test -n "$$redo_logs"; then \
+	else \
 	  am__remaking_logs=yes $(MAKE) $(AM_MAKEFLAGS) $$redo_logs; \
 	fi; \
 	if $(am__make_dryrun); then :; else \
@@ -1438,15 +1426,15 @@ dist-xz: distdir
 	$(am__post_remove_distdir)
 
 dist-tarZ: distdir
-	@echo WARNING: "Support for distribution archives compressed with" \
-		       "legacy program 'compress' is deprecated." >&2
+	@echo WARNING: "Support for shar distribution archives is" \
+	               "deprecated." >&2
 	@echo WARNING: "It will be removed altogether in Automake 2.0" >&2
 	tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z
 	$(am__post_remove_distdir)
 
 dist-shar: distdir
-	@echo WARNING: "Support for shar distribution archives is" \
-	               "deprecated." >&2
+	@echo WARNING: "Support for distribution archives compressed with" \
+		       "legacy program 'compress' is deprecated." >&2
 	@echo WARNING: "It will be removed altogether in Automake 2.0" >&2
 	shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz
 	$(am__post_remove_distdir)
@@ -1481,17 +1469,17 @@ distcheck: dist
 	esac
 	chmod -R a-w $(distdir)
 	chmod u+w $(distdir)
-	mkdir $(distdir)/_build $(distdir)/_build/sub $(distdir)/_inst
+	mkdir $(distdir)/_build $(distdir)/_inst
 	chmod a-w $(distdir)
 	test -d $(distdir)/_build || exit 0; \
 	dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \
 	  && dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \
 	  && am__cwd=`pwd` \
-	  && $(am__cd) $(distdir)/_build/sub \
-	  && ../../configure \
+	  && $(am__cd) $(distdir)/_build \
+	  && ../configure \
 	    $(AM_DISTCHECK_CONFIGURE_FLAGS) \
 	    $(DISTCHECK_CONFIGURE_FLAGS) \
-	    --srcdir=../.. --prefix="$$dc_install_base" \
+	    --srcdir=.. --prefix="$$dc_install_base" \
 	  && $(MAKE) $(AM_MAKEFLAGS) \
 	  && $(MAKE) $(AM_MAKEFLAGS) dvi \
 	  && $(MAKE) $(AM_MAKEFLAGS) check \
@@ -1698,8 +1686,6 @@ uninstall-am: uninstall-m4dataDATA uninstall-pkgincludeHEADERS \
 	uninstall-am uninstall-m4dataDATA uninstall-pkgincludeHEADERS \
 	uninstall-pkginclude_internalHEADERS
 
-.PRECIOUS: Makefile
-
 
 # Build rules for putting fused Google Test files into the distribution
 # package. The user can also create those files by manually running
diff --git a/src/gmock/gtest/aclocal.m4 b/src/gmock/gtest/aclocal.m4
index a83ad2f..8f34cf4 100644
--- a/src/gmock/gtest/aclocal.m4
+++ b/src/gmock/gtest/aclocal.m4
@@ -1,6 +1,6 @@
-# generated automatically by aclocal 1.15 -*- Autoconf -*-
+# generated automatically by aclocal 1.14.1 -*- Autoconf -*-
 
-# Copyright (C) 1996-2014 Free Software Foundation, Inc.
+# Copyright (C) 1996-2013 Free Software Foundation, Inc.
 
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -20,7 +20,7 @@ You have another version of autoconf.  It may work, but is not guaranteed to.
 If you have problems, you may need to regenerate the build system entirely.
 To do so, use the procedure documented by the package, typically 'autoreconf'.])])
 
-# Copyright (C) 2002-2014 Free Software Foundation, Inc.
+# Copyright (C) 2002-2013 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -32,10 +32,10 @@ To do so, use the procedure documented by the package, typically 'autoreconf'.])
 # generated from the m4 files accompanying Automake X.Y.
 # (This private macro should not be called outside this file.)
 AC_DEFUN([AM_AUTOMAKE_VERSION],
-[am__api_version='1.15'
+[am__api_version='1.14'
 dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to
 dnl require some minimum version.  Point them to the right macro.
-m4_if([$1], [1.15], [],
+m4_if([$1], [1.14.1], [],
       [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl
 ])
 
@@ -51,14 +51,14 @@ m4_define([_AM_AUTOCONF_VERSION], [])
 # Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced.
 # This function is AC_REQUIREd by AM_INIT_AUTOMAKE.
 AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION],
-[AM_AUTOMAKE_VERSION([1.15])dnl
+[AM_AUTOMAKE_VERSION([1.14.1])dnl
 m4_ifndef([AC_AUTOCONF_VERSION],
   [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl
 _AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))])
 
 # AM_AUX_DIR_EXPAND                                         -*- Autoconf -*-
 
-# Copyright (C) 2001-2014 Free Software Foundation, Inc.
+# Copyright (C) 2001-2013 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -103,14 +103,15 @@ _AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))])
 # configured tree to be moved without reconfiguration.
 
 AC_DEFUN([AM_AUX_DIR_EXPAND],
-[AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT])dnl
-# Expand $ac_aux_dir to an absolute path.
-am_aux_dir=`cd "$ac_aux_dir" && pwd`
+[dnl Rely on autoconf to set up CDPATH properly.
+AC_PREREQ([2.50])dnl
+# expand $ac_aux_dir to an absolute path
+am_aux_dir=`cd $ac_aux_dir && pwd`
 ])
 
 # AM_CONDITIONAL                                            -*- Autoconf -*-
 
-# Copyright (C) 1997-2014 Free Software Foundation, Inc.
+# Copyright (C) 1997-2013 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -141,7 +142,7 @@ AC_CONFIG_COMMANDS_PRE(
 Usually this means the macro was only invoked conditionally.]])
 fi])])
 
-# Copyright (C) 1999-2014 Free Software Foundation, Inc.
+# Copyright (C) 1999-2013 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -332,7 +333,7 @@ _AM_SUBST_NOTMAKE([am__nodep])dnl
 
 # Generate code to set up dependency tracking.              -*- Autoconf -*-
 
-# Copyright (C) 1999-2014 Free Software Foundation, Inc.
+# Copyright (C) 1999-2013 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -408,7 +409,7 @@ AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS],
 
 # Do all the work for Automake.                             -*- Autoconf -*-
 
-# Copyright (C) 1996-2014 Free Software Foundation, Inc.
+# Copyright (C) 1996-2013 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -498,8 +499,8 @@ AC_REQUIRE([AC_PROG_MKDIR_P])dnl
 # <http://lists.gnu.org/archive/html/automake/2012-07/msg00001.html>
 # <http://lists.gnu.org/archive/html/automake/2012-07/msg00014.html>
 AC_SUBST([mkdir_p], ['$(MKDIR_P)'])
-# We need awk for the "check" target (and possibly the TAP driver).  The
-# system "awk" is bad on some platforms.
+# We need awk for the "check" target.  The system "awk" is bad on
+# some platforms.
 AC_REQUIRE([AC_PROG_AWK])dnl
 AC_REQUIRE([AC_PROG_MAKE_SET])dnl
 AC_REQUIRE([AM_SET_LEADING_DOT])dnl
@@ -572,11 +573,7 @@ to "yes", and re-run configure.
 END
     AC_MSG_ERROR([Your 'rm' program is bad, sorry.])
   fi
-fi
-dnl The trailing newline in this macro's definition is deliberate, for
-dnl backward compatibility and to allow trailing 'dnl'-style comments
-dnl after the AM_INIT_AUTOMAKE invocation. See automake bug#16841.
-])
+fi])
 
 dnl Hook into '_AC_COMPILER_EXEEXT' early to learn its expansion.  Do not
 dnl add the conditional right here, as _AC_COMPILER_EXEEXT may be further
@@ -605,7 +602,7 @@ for _am_header in $config_headers :; do
 done
 echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count])
 
-# Copyright (C) 2001-2014 Free Software Foundation, Inc.
+# Copyright (C) 2001-2013 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -616,7 +613,7 @@ echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_co
 # Define $install_sh.
 AC_DEFUN([AM_PROG_INSTALL_SH],
 [AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
-if test x"${install_sh+set}" != xset; then
+if test x"${install_sh}" != xset; then
   case $am_aux_dir in
   *\ * | *\	*)
     install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;;
@@ -626,7 +623,7 @@ if test x"${install_sh+set}" != xset; then
 fi
 AC_SUBST([install_sh])])
 
-# Copyright (C) 2003-2014 Free Software Foundation, Inc.
+# Copyright (C) 2003-2013 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -647,7 +644,7 @@ AC_SUBST([am__leading_dot])])
 
 # Check to see how 'make' treats includes.	            -*- Autoconf -*-
 
-# Copyright (C) 2001-2014 Free Software Foundation, Inc.
+# Copyright (C) 2001-2013 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -697,7 +694,7 @@ rm -f confinc confmf
 
 # Fake the existence of programs that GNU maintainers use.  -*- Autoconf -*-
 
-# Copyright (C) 1997-2014 Free Software Foundation, Inc.
+# Copyright (C) 1997-2013 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -736,7 +733,7 @@ fi
 
 # Helper functions for option handling.                     -*- Autoconf -*-
 
-# Copyright (C) 2001-2014 Free Software Foundation, Inc.
+# Copyright (C) 2001-2013 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -765,7 +762,7 @@ AC_DEFUN([_AM_SET_OPTIONS],
 AC_DEFUN([_AM_IF_OPTION],
 [m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])])
 
-# Copyright (C) 1999-2014 Free Software Foundation, Inc.
+# Copyright (C) 1999-2013 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -812,7 +809,7 @@ AC_LANG_POP([C])])
 # For backward compatibility.
 AC_DEFUN_ONCE([AM_PROG_CC_C_O], [AC_REQUIRE([AC_PROG_CC])])
 
-# Copyright (C) 1999-2014 Free Software Foundation, Inc.
+# Copyright (C) 1999-2013 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -1047,7 +1044,7 @@ for i in list(range(0, 4)): minverhex = (minverhex << 8) + minver[[i]]
 sys.exit(sys.hexversion < minverhex)"
   AS_IF([AM_RUN_LOG([$1 -c "$prog"])], [$3], [$4])])
 
-# Copyright (C) 2001-2014 Free Software Foundation, Inc.
+# Copyright (C) 2001-2013 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -1066,7 +1063,7 @@ AC_DEFUN([AM_RUN_LOG],
 
 # Check to make sure that the build environment is sane.    -*- Autoconf -*-
 
-# Copyright (C) 1996-2014 Free Software Foundation, Inc.
+# Copyright (C) 1996-2013 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -1147,7 +1144,7 @@ AC_CONFIG_COMMANDS_PRE(
 rm -f conftest.file
 ])
 
-# Copyright (C) 2009-2014 Free Software Foundation, Inc.
+# Copyright (C) 2009-2013 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -1207,7 +1204,7 @@ AC_SUBST([AM_BACKSLASH])dnl
 _AM_SUBST_NOTMAKE([AM_BACKSLASH])dnl
 ])
 
-# Copyright (C) 2001-2014 Free Software Foundation, Inc.
+# Copyright (C) 2001-2013 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -1235,7 +1232,7 @@ fi
 INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s"
 AC_SUBST([INSTALL_STRIP_PROGRAM])])
 
-# Copyright (C) 2006-2014 Free Software Foundation, Inc.
+# Copyright (C) 2006-2013 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -1254,7 +1251,7 @@ AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)])
 
 # Check how to create a tarball.                            -*- Autoconf -*-
 
-# Copyright (C) 2004-2014 Free Software Foundation, Inc.
+# Copyright (C) 2004-2013 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
diff --git a/src/gmock/gtest/build-aux/compile b/src/gmock/gtest/build-aux/compile
index a85b723..531136b 100755
--- a/src/gmock/gtest/build-aux/compile
+++ b/src/gmock/gtest/build-aux/compile
@@ -3,7 +3,7 @@
 
 scriptversion=2012-10-14.11; # UTC
 
-# Copyright (C) 1999-2014 Free Software Foundation, Inc.
+# Copyright (C) 1999-2013 Free Software Foundation, Inc.
 # Written by Tom Tromey <tromey at cygnus.com>.
 #
 # This program is free software; you can redistribute it and/or modify
diff --git a/src/gmock/gtest/build-aux/config.guess b/src/gmock/gtest/build-aux/config.guess
index 1659250..b79252d 100755
--- a/src/gmock/gtest/build-aux/config.guess
+++ b/src/gmock/gtest/build-aux/config.guess
@@ -1,8 +1,8 @@
 #! /bin/sh
 # Attempt to guess a canonical system name.
-#   Copyright 1992-2015 Free Software Foundation, Inc.
+#   Copyright 1992-2013 Free Software Foundation, Inc.
 
-timestamp='2015-08-20'
+timestamp='2013-06-10'
 
 # This file is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License as published by
@@ -24,12 +24,12 @@ timestamp='2015-08-20'
 # program.  This Exception is an additional permission under section 7
 # of the GNU General Public License, version 3 ("GPLv3").
 #
-# Originally written by Per Bothner; maintained since 2000 by Ben Elliston.
+# Originally written by Per Bothner.
 #
 # You can get the latest version of this script from:
 # http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD
 #
-# Please send patches to <config-patches at gnu.org>.
+# Please send patches with a ChangeLog entry to config-patches at gnu.org.
 
 
 me=`echo "$0" | sed -e 's,.*/,,'`
@@ -50,7 +50,7 @@ version="\
 GNU config.guess ($timestamp)
 
 Originally written by Per Bothner.
-Copyright 1992-2015 Free Software Foundation, Inc.
+Copyright 1992-2013 Free Software Foundation, Inc.
 
 This is free software; see the source for copying conditions.  There is NO
 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
@@ -149,7 +149,7 @@ Linux|GNU|GNU/*)
 	LIBC=gnu
 	#endif
 	EOF
-	eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC' | sed 's, ,,g'`
+	eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC'`
 	;;
 esac
 
@@ -168,27 +168,20 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
 	# Note: NetBSD doesn't particularly care about the vendor
 	# portion of the name.  We always set it to "unknown".
 	sysctl="sysctl -n hw.machine_arch"
-	UNAME_MACHINE_ARCH=`(uname -p 2>/dev/null || \
-	    /sbin/$sysctl 2>/dev/null || \
-	    /usr/sbin/$sysctl 2>/dev/null || \
-	    echo unknown)`
+	UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \
+	    /usr/sbin/$sysctl 2>/dev/null || echo unknown)`
 	case "${UNAME_MACHINE_ARCH}" in
 	    armeb) machine=armeb-unknown ;;
 	    arm*) machine=arm-unknown ;;
 	    sh3el) machine=shl-unknown ;;
 	    sh3eb) machine=sh-unknown ;;
 	    sh5el) machine=sh5le-unknown ;;
-	    earmv*)
-		arch=`echo ${UNAME_MACHINE_ARCH} | sed -e 's,^e\(armv[0-9]\).*$,\1,'`
-		endian=`echo ${UNAME_MACHINE_ARCH} | sed -ne 's,^.*\(eb\)$,\1,p'`
-		machine=${arch}${endian}-unknown
-		;;
 	    *) machine=${UNAME_MACHINE_ARCH}-unknown ;;
 	esac
 	# The Operating System including object format, if it has switched
 	# to ELF recently, or will in the future.
 	case "${UNAME_MACHINE_ARCH}" in
-	    arm*|earm*|i386|m68k|ns32k|sh3*|sparc|vax)
+	    arm*|i386|m68k|ns32k|sh3*|sparc|vax)
 		eval $set_cc_for_build
 		if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \
 			| grep -q __ELF__
@@ -204,13 +197,6 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
 		os=netbsd
 		;;
 	esac
-	# Determine ABI tags.
-	case "${UNAME_MACHINE_ARCH}" in
-	    earm*)
-		expr='s/^earmv[0-9]/-eabi/;s/eb$//'
-		abi=`echo ${UNAME_MACHINE_ARCH} | sed -e "$expr"`
-		;;
-	esac
 	# The OS release
 	# Debian GNU/NetBSD machines have a different userland, and
 	# thus, need a distinct triplet. However, they do not need
@@ -221,13 +207,13 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
 		release='-gnu'
 		;;
 	    *)
-		release=`echo ${UNAME_RELEASE} | sed -e 's/[-_].*//' | cut -d. -f1,2`
+		release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
 		;;
 	esac
 	# Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM:
 	# contains redundant information, the shorter form:
 	# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used.
-	echo "${machine}-${os}${release}${abi}"
+	echo "${machine}-${os}${release}"
 	exit ;;
     *:Bitrig:*:*)
 	UNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'`
@@ -249,9 +235,6 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
     *:MirBSD:*:*)
 	echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE}
 	exit ;;
-    *:Sortix:*:*)
-	echo ${UNAME_MACHINE}-unknown-sortix
-	exit ;;
     alpha:OSF1:*:*)
 	case $UNAME_RELEASE in
 	*4.0)
@@ -596,9 +579,8 @@ EOF
 	else
 		IBM_ARCH=powerpc
 	fi
-	if [ -x /usr/bin/lslpp ] ; then
-		IBM_REV=`/usr/bin/lslpp -Lqc bos.rte.libc |
-			   awk -F: '{ print $3 }' | sed s/[0-9]*$/0/`
+	if [ -x /usr/bin/oslevel ] ; then
+		IBM_REV=`/usr/bin/oslevel`
 	else
 		IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
 	fi
@@ -844,7 +826,7 @@ EOF
     *:MINGW*:*)
 	echo ${UNAME_MACHINE}-pc-mingw32
 	exit ;;
-    *:MSYS*:*)
+    i*:MSYS*:*)
 	echo ${UNAME_MACHINE}-pc-msys
 	exit ;;
     i*:windows32*:*)
@@ -950,9 +932,6 @@ EOF
     crisv32:Linux:*:*)
 	echo ${UNAME_MACHINE}-axis-linux-${LIBC}
 	exit ;;
-    e2k:Linux:*:*)
-	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
-	exit ;;
     frv:Linux:*:*)
 	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
 	exit ;;
@@ -990,10 +969,10 @@ EOF
 	eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'`
 	test x"${CPU}" != x && { echo "${CPU}-unknown-linux-${LIBC}"; exit; }
 	;;
-    openrisc*:Linux:*:*)
-	echo or1k-unknown-linux-${LIBC}
+    or1k:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
 	exit ;;
-    or32:Linux:*:* | or1k*:Linux:*:*)
+    or32:Linux:*:*)
 	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
 	exit ;;
     padre:Linux:*:*)
@@ -1041,7 +1020,7 @@ EOF
 	echo ${UNAME_MACHINE}-dec-linux-${LIBC}
 	exit ;;
     x86_64:Linux:*:*)
-	echo ${UNAME_MACHINE}-pc-linux-${LIBC}
+	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
 	exit ;;
     xtensa*:Linux:*:*)
 	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
@@ -1281,26 +1260,16 @@ EOF
 	if test "$UNAME_PROCESSOR" = unknown ; then
 	    UNAME_PROCESSOR=powerpc
 	fi
-	if test `echo "$UNAME_RELEASE" | sed -e 's/\..*//'` -le 10 ; then
-	    if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then
-		if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \
-		    (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \
-		    grep IS_64BIT_ARCH >/dev/null
-		then
-		    case $UNAME_PROCESSOR in
-			i386) UNAME_PROCESSOR=x86_64 ;;
-			powerpc) UNAME_PROCESSOR=powerpc64 ;;
-		    esac
-		fi
+	if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then
+	    if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \
+		(CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \
+		grep IS_64BIT_ARCH >/dev/null
+	    then
+		case $UNAME_PROCESSOR in
+		    i386) UNAME_PROCESSOR=x86_64 ;;
+		    powerpc) UNAME_PROCESSOR=powerpc64 ;;
+		esac
 	    fi
-	elif test "$UNAME_PROCESSOR" = i386 ; then
-	    # Avoid executing cc on OS X 10.9, as it ships with a stub
-	    # that puts up a graphical alert prompting to install
-	    # developer tools.  Any system running Mac OS X 10.7 or
-	    # later (Darwin 11 and later) is required to have a 64-bit
-	    # processor. This is not true of the ARM version of Darwin
-	    # that Apple uses in portable devices.
-	    UNAME_PROCESSOR=x86_64
 	fi
 	echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE}
 	exit ;;
@@ -1392,6 +1361,154 @@ EOF
 	exit ;;
 esac
 
+eval $set_cc_for_build
+cat >$dummy.c <<EOF
+#ifdef _SEQUENT_
+# include <sys/types.h>
+# include <sys/utsname.h>
+#endif
+main ()
+{
+#if defined (sony)
+#if defined (MIPSEB)
+  /* BFD wants "bsd" instead of "newsos".  Perhaps BFD should be changed,
+     I don't know....  */
+  printf ("mips-sony-bsd\n"); exit (0);
+#else
+#include <sys/param.h>
+  printf ("m68k-sony-newsos%s\n",
+#ifdef NEWSOS4
+	"4"
+#else
+	""
+#endif
+	); exit (0);
+#endif
+#endif
+
+#if defined (__arm) && defined (__acorn) && defined (__unix)
+  printf ("arm-acorn-riscix\n"); exit (0);
+#endif
+
+#if defined (hp300) && !defined (hpux)
+  printf ("m68k-hp-bsd\n"); exit (0);
+#endif
+
+#if defined (NeXT)
+#if !defined (__ARCHITECTURE__)
+#define __ARCHITECTURE__ "m68k"
+#endif
+  int version;
+  version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`;
+  if (version < 4)
+    printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version);
+  else
+    printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version);
+  exit (0);
+#endif
+
+#if defined (MULTIMAX) || defined (n16)
+#if defined (UMAXV)
+  printf ("ns32k-encore-sysv\n"); exit (0);
+#else
+#if defined (CMU)
+  printf ("ns32k-encore-mach\n"); exit (0);
+#else
+  printf ("ns32k-encore-bsd\n"); exit (0);
+#endif
+#endif
+#endif
+
+#if defined (__386BSD__)
+  printf ("i386-pc-bsd\n"); exit (0);
+#endif
+
+#if defined (sequent)
+#if defined (i386)
+  printf ("i386-sequent-dynix\n"); exit (0);
+#endif
+#if defined (ns32000)
+  printf ("ns32k-sequent-dynix\n"); exit (0);
+#endif
+#endif
+
+#if defined (_SEQUENT_)
+    struct utsname un;
+
+    uname(&un);
+
+    if (strncmp(un.version, "V2", 2) == 0) {
+	printf ("i386-sequent-ptx2\n"); exit (0);
+    }
+    if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */
+	printf ("i386-sequent-ptx1\n"); exit (0);
+    }
+    printf ("i386-sequent-ptx\n"); exit (0);
+
+#endif
+
+#if defined (vax)
+# if !defined (ultrix)
+#  include <sys/param.h>
+#  if defined (BSD)
+#   if BSD == 43
+      printf ("vax-dec-bsd4.3\n"); exit (0);
+#   else
+#    if BSD == 199006
+      printf ("vax-dec-bsd4.3reno\n"); exit (0);
+#    else
+      printf ("vax-dec-bsd\n"); exit (0);
+#    endif
+#   endif
+#  else
+    printf ("vax-dec-bsd\n"); exit (0);
+#  endif
+# else
+    printf ("vax-dec-ultrix\n"); exit (0);
+# endif
+#endif
+
+#if defined (alliant) && defined (i860)
+  printf ("i860-alliant-bsd\n"); exit (0);
+#endif
+
+  exit (1);
+}
+EOF
+
+$CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && SYSTEM_NAME=`$dummy` &&
+	{ echo "$SYSTEM_NAME"; exit; }
+
+# Apollos put the system type in the environment.
+
+test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit; }
+
+# Convex versions that predate uname can use getsysinfo(1)
+
+if [ -x /usr/convex/getsysinfo ]
+then
+    case `getsysinfo -f cpu_type` in
+    c1*)
+	echo c1-convex-bsd
+	exit ;;
+    c2*)
+	if getsysinfo -f scalar_acc
+	then echo c32-convex-bsd
+	else echo c2-convex-bsd
+	fi
+	exit ;;
+    c34*)
+	echo c34-convex-bsd
+	exit ;;
+    c38*)
+	echo c38-convex-bsd
+	exit ;;
+    c4*)
+	echo c4-convex-bsd
+	exit ;;
+    esac
+fi
+
 cat >&2 <<EOF
 $0: unable to guess system type
 
diff --git a/src/gmock/gtest/build-aux/config.h.in b/src/gmock/gtest/build-aux/config.h.in
index 6ea2e69..843b5b1 100644
--- a/src/gmock/gtest/build-aux/config.h.in
+++ b/src/gmock/gtest/build-aux/config.h.in
@@ -33,7 +33,8 @@
 /* Define to 1 if you have the <unistd.h> header file. */
 #undef HAVE_UNISTD_H
 
-/* Define to the sub-directory where libtool stores uninstalled libraries. */
+/* Define to the sub-directory in which libtool stores uninstalled libraries.
+   */
 #undef LT_OBJDIR
 
 /* Name of package */
diff --git a/src/gmock/gtest/build-aux/config.sub b/src/gmock/gtest/build-aux/config.sub
index 1acc966..9633db7 100755
--- a/src/gmock/gtest/build-aux/config.sub
+++ b/src/gmock/gtest/build-aux/config.sub
@@ -1,8 +1,8 @@
 #! /bin/sh
 # Configuration validation subroutine script.
-#   Copyright 1992-2015 Free Software Foundation, Inc.
+#   Copyright 1992-2013 Free Software Foundation, Inc.
 
-timestamp='2015-08-20'
+timestamp='2013-08-10'
 
 # This file is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License as published by
@@ -25,7 +25,7 @@ timestamp='2015-08-20'
 # of the GNU General Public License, version 3 ("GPLv3").
 
 
-# Please send patches to <config-patches at gnu.org>.
+# Please send patches with a ChangeLog entry to config-patches at gnu.org.
 #
 # Configuration subroutine to validate and canonicalize a configuration type.
 # Supply the specified configuration type as an argument.
@@ -68,7 +68,7 @@ Report bugs and patches to <config-patches at gnu.org>."
 version="\
 GNU config.sub ($timestamp)
 
-Copyright 1992-2015 Free Software Foundation, Inc.
+Copyright 1992-2013 Free Software Foundation, Inc.
 
 This is free software; see the source for copying conditions.  There is NO
 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
@@ -117,7 +117,7 @@ maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
 case $maybe_os in
   nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \
   linux-musl* | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \
-  knetbsd*-gnu* | netbsd*-gnu* | netbsd*-eabi* | \
+  knetbsd*-gnu* | netbsd*-gnu* | \
   kopensolaris*-gnu* | \
   storm-chaos* | os2-emx* | rtmk-nova*)
     os=-$maybe_os
@@ -255,18 +255,16 @@ case $basic_machine in
 	| arc | arceb \
 	| arm | arm[bl]e | arme[lb] | armv[2-8] | armv[3-8][lb] | armv7[arm] \
 	| avr | avr32 \
-	| ba \
 	| be32 | be64 \
 	| bfin \
 	| c4x | c8051 | clipper \
 	| d10v | d30v | dlx | dsp16xx \
-	| e2k | epiphany \
-	| fido | fr30 | frv | ft32 \
+	| epiphany \
+	| fido | fr30 | frv \
 	| h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
 	| hexagon \
 	| i370 | i860 | i960 | ia64 \
 	| ip2k | iq2000 \
-	| k1om \
 	| le32 | le64 \
 	| lm32 \
 	| m32c | m32r | m32rle | m68000 | m68k | m88k \
@@ -284,10 +282,8 @@ case $basic_machine in
 	| mips64vr5900 | mips64vr5900el \
 	| mipsisa32 | mipsisa32el \
 	| mipsisa32r2 | mipsisa32r2el \
-	| mipsisa32r6 | mipsisa32r6el \
 	| mipsisa64 | mipsisa64el \
 	| mipsisa64r2 | mipsisa64r2el \
-	| mipsisa64r6 | mipsisa64r6el \
 	| mipsisa64sb1 | mipsisa64sb1el \
 	| mipsisa64sr71k | mipsisa64sr71kel \
 	| mipsr5900 | mipsr5900el \
@@ -299,14 +295,14 @@ case $basic_machine in
 	| nds32 | nds32le | nds32be \
 	| nios | nios2 | nios2eb | nios2el \
 	| ns16k | ns32k \
-	| open8 | or1k | or1knd | or32 \
+	| open8 \
+	| or1k | or32 \
 	| pdp10 | pdp11 | pj | pjl \
 	| powerpc | powerpc64 | powerpc64le | powerpcle \
 	| pyramid \
-	| riscv32 | riscv64 \
 	| rl78 | rx \
 	| score \
-	| sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[234]eb | sheb | shbe | shle | sh[1234]le | sh3ele \
+	| sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \
 	| sh64 | sh64le \
 	| sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \
 	| sparcv8 | sparcv9 | sparcv9b | sparcv9v \
@@ -314,7 +310,6 @@ case $basic_machine in
 	| tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \
 	| ubicom32 \
 	| v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \
-	| visium \
 	| we32k \
 	| x86 | xc16x | xstormy16 | xtensa \
 	| z8k | z80)
@@ -329,10 +324,7 @@ case $basic_machine in
 	c6x)
 		basic_machine=tic6x-unknown
 		;;
-	leon|leon[3-9])
-		basic_machine=sparc-$basic_machine
-		;;
-	m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | nvptx | picochip)
+	m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | picochip)
 		basic_machine=$basic_machine-unknown
 		os=-none
 		;;
@@ -377,20 +369,18 @@ case $basic_machine in
 	| alphapca5[67]-* | alpha64pca5[67]-* | arc-* | arceb-* \
 	| arm-*  | armbe-* | armle-* | armeb-* | armv*-* \
 	| avr-* | avr32-* \
-	| ba-* \
 	| be32-* | be64-* \
 	| bfin-* | bs2000-* \
 	| c[123]* | c30-* | [cjt]90-* | c4x-* \
 	| c8051-* | clipper-* | craynv-* | cydra-* \
 	| d10v-* | d30v-* | dlx-* \
-	| e2k-* | elxsi-* \
+	| elxsi-* \
 	| f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \
 	| h8300-* | h8500-* \
 	| hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \
 	| hexagon-* \
 	| i*86-* | i860-* | i960-* | ia64-* \
 	| ip2k-* | iq2000-* \
-	| k1om-* \
 	| le32-* | le64-* \
 	| lm32-* \
 	| m32c-* | m32r-* | m32rle-* \
@@ -410,10 +400,8 @@ case $basic_machine in
 	| mips64vr5900-* | mips64vr5900el-* \
 	| mipsisa32-* | mipsisa32el-* \
 	| mipsisa32r2-* | mipsisa32r2el-* \
-	| mipsisa32r6-* | mipsisa32r6el-* \
 	| mipsisa64-* | mipsisa64el-* \
 	| mipsisa64r2-* | mipsisa64r2el-* \
-	| mipsisa64r6-* | mipsisa64r6el-* \
 	| mipsisa64sb1-* | mipsisa64sb1el-* \
 	| mipsisa64sr71k-* | mipsisa64sr71kel-* \
 	| mipsr5900-* | mipsr5900el-* \
@@ -425,18 +413,16 @@ case $basic_machine in
 	| nios-* | nios2-* | nios2eb-* | nios2el-* \
 	| none-* | np1-* | ns16k-* | ns32k-* \
 	| open8-* \
-	| or1k*-* \
 	| orion-* \
 	| pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \
 	| powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \
 	| pyramid-* \
-	| riscv32-* | riscv64-* \
 	| rl78-* | romp-* | rs6000-* | rx-* \
 	| sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \
 	| shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \
 	| sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \
 	| sparclite-* \
-	| sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx*-* \
+	| sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx?-* \
 	| tahoe-* \
 	| tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \
 	| tile*-* \
@@ -444,7 +430,6 @@ case $basic_machine in
 	| ubicom32-* \
 	| v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \
 	| vax-* \
-	| visium-* \
 	| we32k-* \
 	| x86-* | x86_64-* | xc16x-* | xps100-* \
 	| xstormy16-* | xtensa*-* \
@@ -521,9 +506,6 @@ case $basic_machine in
 		basic_machine=i386-pc
 		os=-aros
 		;;
-        asmjs)
-		basic_machine=asmjs-unknown
-		;;
 	aux)
 		basic_machine=m68k-apple
 		os=-aux
@@ -785,9 +767,6 @@ case $basic_machine in
 		basic_machine=m68k-isi
 		os=-sysv
 		;;
-	leon-*|leon[3-9]-*)
-		basic_machine=sparc-`echo $basic_machine | sed 's/-.*//'`
-		;;
 	m68knommu)
 		basic_machine=m68k-unknown
 		os=-linux
@@ -843,10 +822,6 @@ case $basic_machine in
 		basic_machine=powerpc-unknown
 		os=-morphos
 		;;
-	moxiebox)
-		basic_machine=moxie-unknown
-		os=-moxiebox
-		;;
 	msdos)
 		basic_machine=i386-pc
 		os=-msdos
@@ -1379,7 +1354,7 @@ case $os in
 	      | -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \
 	      | -sym* | -kopensolaris* | -plan9* \
 	      | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \
-	      | -aos* | -aros* | -cloudabi* | -sortix* \
+	      | -aos* | -aros* \
 	      | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
 	      | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
 	      | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \
@@ -1392,14 +1367,14 @@ case $os in
 	      | -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
 	      | -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \
 	      | -linux-newlib* | -linux-musl* | -linux-uclibc* \
-	      | -uxpv* | -beos* | -mpeix* | -udk* | -moxiebox* \
+	      | -uxpv* | -beos* | -mpeix* | -udk* \
 	      | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \
 	      | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
 	      | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \
 	      | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \
 	      | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \
 	      | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \
-	      | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es* | -tirtos*)
+	      | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es*)
 	# Remember, each alternative MUST END IN *, to match a version number.
 		;;
 	-qnx*)
@@ -1617,6 +1592,9 @@ case $basic_machine in
 	mips*-*)
 		os=-elf
 		;;
+	or1k-*)
+		os=-elf
+		;;
 	or32-*)
 		os=-coff
 		;;
diff --git a/src/gmock/gtest/build-aux/depcomp b/src/gmock/gtest/build-aux/depcomp
index fc98710..4ebd5b3 100755
--- a/src/gmock/gtest/build-aux/depcomp
+++ b/src/gmock/gtest/build-aux/depcomp
@@ -3,7 +3,7 @@
 
 scriptversion=2013-05-30.07; # UTC
 
-# Copyright (C) 1999-2014 Free Software Foundation, Inc.
+# Copyright (C) 1999-2013 Free Software Foundation, Inc.
 
 # This program is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
diff --git a/src/gmock/gtest/build-aux/install-sh b/src/gmock/gtest/build-aux/install-sh
index 59990a1..377bb86 100755
--- a/src/gmock/gtest/build-aux/install-sh
+++ b/src/gmock/gtest/build-aux/install-sh
@@ -1,7 +1,7 @@
 #!/bin/sh
 # install - install a program, script, or datafile
 
-scriptversion=2014-09-12.12; # UTC
+scriptversion=2011-11-20.07; # UTC
 
 # This originates from X11R5 (mit/util/scripts/install.sh), which was
 # later released in X11R6 (xc/config/util/install.sh) with the
@@ -41,15 +41,19 @@ scriptversion=2014-09-12.12; # UTC
 # This script is compatible with the BSD install script, but was written
 # from scratch.
 
-tab='	'
 nl='
 '
-IFS=" $tab$nl"
+IFS=" ""	$nl"
 
-# Set DOITPROG to "echo" to test this script.
+# set DOITPROG to echo to test this script
 
+# Don't use :- since 4.3BSD and earlier shells don't like it.
 doit=${DOITPROG-}
-doit_exec=${doit:-exec}
+if test -z "$doit"; then
+  doit_exec=exec
+else
+  doit_exec=$doit
+fi
 
 # Put in absolute file names if you don't have them in your path;
 # or use environment vars.
@@ -64,6 +68,17 @@ mvprog=${MVPROG-mv}
 rmprog=${RMPROG-rm}
 stripprog=${STRIPPROG-strip}
 
+posix_glob='?'
+initialize_posix_glob='
+  test "$posix_glob" != "?" || {
+    if (set -f) 2>/dev/null; then
+      posix_glob=
+    else
+      posix_glob=:
+    fi
+  }
+'
+
 posix_mkdir=
 
 # Desired mode of installed file.
@@ -82,7 +97,7 @@ dir_arg=
 dst_arg=
 
 copy_on_change=false
-is_target_a_directory=possibly
+no_target_directory=
 
 usage="\
 Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE
@@ -122,57 +137,46 @@ while test $# -ne 0; do
     -d) dir_arg=true;;
 
     -g) chgrpcmd="$chgrpprog $2"
-        shift;;
+	shift;;
 
     --help) echo "$usage"; exit $?;;
 
     -m) mode=$2
-        case $mode in
-          *' '* | *"$tab"* | *"$nl"* | *'*'* | *'?'* | *'['*)
-            echo "$0: invalid mode: $mode" >&2
-            exit 1;;
-        esac
-        shift;;
+	case $mode in
+	  *' '* | *'	'* | *'
+'*	  | *'*'* | *'?'* | *'['*)
+	    echo "$0: invalid mode: $mode" >&2
+	    exit 1;;
+	esac
+	shift;;
 
     -o) chowncmd="$chownprog $2"
-        shift;;
+	shift;;
 
     -s) stripcmd=$stripprog;;
 
-    -t)
-        is_target_a_directory=always
-        dst_arg=$2
-        # Protect names problematic for 'test' and other utilities.
-        case $dst_arg in
-          -* | [=\(\)!]) dst_arg=./$dst_arg;;
-        esac
-        shift;;
+    -t) dst_arg=$2
+	# Protect names problematic for 'test' and other utilities.
+	case $dst_arg in
+	  -* | [=\(\)!]) dst_arg=./$dst_arg;;
+	esac
+	shift;;
 
-    -T) is_target_a_directory=never;;
+    -T) no_target_directory=true;;
 
     --version) echo "$0 $scriptversion"; exit $?;;
 
-    --) shift
-        break;;
+    --)	shift
+	break;;
 
-    -*) echo "$0: invalid option: $1" >&2
-        exit 1;;
+    -*)	echo "$0: invalid option: $1" >&2
+	exit 1;;
 
     *)  break;;
   esac
   shift
 done
 
-# We allow the use of options -d and -T together, by making -d
-# take the precedence; this is for compatibility with GNU install.
-
-if test -n "$dir_arg"; then
-  if test -n "$dst_arg"; then
-    echo "$0: target directory not allowed when installing a directory." >&2
-    exit 1
-  fi
-fi
-
 if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then
   # When -d is used, all remaining arguments are directories to create.
   # When -t is used, the destination is already specified.
@@ -204,15 +208,6 @@ if test $# -eq 0; then
 fi
 
 if test -z "$dir_arg"; then
-  if test $# -gt 1 || test "$is_target_a_directory" = always; then
-    if test ! -d "$dst_arg"; then
-      echo "$0: $dst_arg: Is not a directory." >&2
-      exit 1
-    fi
-  fi
-fi
-
-if test -z "$dir_arg"; then
   do_exit='(exit $ret); exit $ret'
   trap "ret=129; $do_exit" 1
   trap "ret=130; $do_exit" 2
@@ -228,16 +223,16 @@ if test -z "$dir_arg"; then
 
     *[0-7])
       if test -z "$stripcmd"; then
-        u_plus_rw=
+	u_plus_rw=
       else
-        u_plus_rw='% 200'
+	u_plus_rw='% 200'
       fi
       cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;;
     *)
       if test -z "$stripcmd"; then
-        u_plus_rw=
+	u_plus_rw=
       else
-        u_plus_rw=,u+rw
+	u_plus_rw=,u+rw
       fi
       cp_umask=$mode$u_plus_rw;;
   esac
@@ -274,15 +269,41 @@ do
     # If destination is a directory, append the input filename; won't work
     # if double slashes aren't ignored.
     if test -d "$dst"; then
-      if test "$is_target_a_directory" = never; then
-        echo "$0: $dst_arg: Is a directory" >&2
-        exit 1
+      if test -n "$no_target_directory"; then
+	echo "$0: $dst_arg: Is a directory" >&2
+	exit 1
       fi
       dstdir=$dst
       dst=$dstdir/`basename "$src"`
       dstdir_status=0
     else
-      dstdir=`dirname "$dst"`
+      # Prefer dirname, but fall back on a substitute if dirname fails.
+      dstdir=`
+	(dirname "$dst") 2>/dev/null ||
+	expr X"$dst" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	     X"$dst" : 'X\(//\)[^/]' \| \
+	     X"$dst" : 'X\(//\)$' \| \
+	     X"$dst" : 'X\(/\)' \| . 2>/dev/null ||
+	echo X"$dst" |
+	    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+		   s//\1/
+		   q
+		 }
+		 /^X\(\/\/\)[^/].*/{
+		   s//\1/
+		   q
+		 }
+		 /^X\(\/\/\)$/{
+		   s//\1/
+		   q
+		 }
+		 /^X\(\/\).*/{
+		   s//\1/
+		   q
+		 }
+		 s/.*/./; q'
+      `
+
       test -d "$dstdir"
       dstdir_status=$?
     fi
@@ -293,81 +314,74 @@ do
   if test $dstdir_status != 0; then
     case $posix_mkdir in
       '')
-        # Create intermediate dirs using mode 755 as modified by the umask.
-        # This is like FreeBSD 'install' as of 1997-10-28.
-        umask=`umask`
-        case $stripcmd.$umask in
-          # Optimize common cases.
-          *[2367][2367]) mkdir_umask=$umask;;
-          .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;;
-
-          *[0-7])
-            mkdir_umask=`expr $umask + 22 \
-              - $umask % 100 % 40 + $umask % 20 \
-              - $umask % 10 % 4 + $umask % 2
-            `;;
-          *) mkdir_umask=$umask,go-w;;
-        esac
-
-        # With -d, create the new directory with the user-specified mode.
-        # Otherwise, rely on $mkdir_umask.
-        if test -n "$dir_arg"; then
-          mkdir_mode=-m$mode
-        else
-          mkdir_mode=
-        fi
-
-        posix_mkdir=false
-        case $umask in
-          *[123567][0-7][0-7])
-            # POSIX mkdir -p sets u+wx bits regardless of umask, which
-            # is incompatible with FreeBSD 'install' when (umask & 300) != 0.
-            ;;
-          *)
-            # $RANDOM is not portable (e.g. dash);  use it when possible to
-            # lower collision chance
-            tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$
-            trap 'ret=$?; rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" 2>/dev/null; exit $ret' 0
-
-            # As "mkdir -p" follows symlinks and we work in /tmp possibly;  so
-            # create the $tmpdir first (and fail if unsuccessful) to make sure
-            # that nobody tries to guess the $tmpdir name.
-            if (umask $mkdir_umask &&
-                $mkdirprog $mkdir_mode "$tmpdir" &&
-                exec $mkdirprog $mkdir_mode -p -- "$tmpdir/a/b") >/dev/null 2>&1
-            then
-              if test -z "$dir_arg" || {
-                   # Check for POSIX incompatibilities with -m.
-                   # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or
-                   # other-writable bit of parent directory when it shouldn't.
-                   # FreeBSD 6.1 mkdir -m -p sets mode of existing directory.
-                   test_tmpdir="$tmpdir/a"
-                   ls_ld_tmpdir=`ls -ld "$test_tmpdir"`
-                   case $ls_ld_tmpdir in
-                     d????-?r-*) different_mode=700;;
-                     d????-?--*) different_mode=755;;
-                     *) false;;
-                   esac &&
-                   $mkdirprog -m$different_mode -p -- "$test_tmpdir" && {
-                     ls_ld_tmpdir_1=`ls -ld "$test_tmpdir"`
-                     test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1"
-                   }
-                 }
-              then posix_mkdir=:
-              fi
-              rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir"
-            else
-              # Remove any dirs left behind by ancient mkdir implementations.
-              rmdir ./$mkdir_mode ./-p ./-- "$tmpdir" 2>/dev/null
-            fi
-            trap '' 0;;
-        esac;;
+	# Create intermediate dirs using mode 755 as modified by the umask.
+	# This is like FreeBSD 'install' as of 1997-10-28.
+	umask=`umask`
+	case $stripcmd.$umask in
+	  # Optimize common cases.
+	  *[2367][2367]) mkdir_umask=$umask;;
+	  .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;;
+
+	  *[0-7])
+	    mkdir_umask=`expr $umask + 22 \
+	      - $umask % 100 % 40 + $umask % 20 \
+	      - $umask % 10 % 4 + $umask % 2
+	    `;;
+	  *) mkdir_umask=$umask,go-w;;
+	esac
+
+	# With -d, create the new directory with the user-specified mode.
+	# Otherwise, rely on $mkdir_umask.
+	if test -n "$dir_arg"; then
+	  mkdir_mode=-m$mode
+	else
+	  mkdir_mode=
+	fi
+
+	posix_mkdir=false
+	case $umask in
+	  *[123567][0-7][0-7])
+	    # POSIX mkdir -p sets u+wx bits regardless of umask, which
+	    # is incompatible with FreeBSD 'install' when (umask & 300) != 0.
+	    ;;
+	  *)
+	    tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$
+	    trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0
+
+	    if (umask $mkdir_umask &&
+		exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1
+	    then
+	      if test -z "$dir_arg" || {
+		   # Check for POSIX incompatibilities with -m.
+		   # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or
+		   # other-writable bit of parent directory when it shouldn't.
+		   # FreeBSD 6.1 mkdir -m -p sets mode of existing directory.
+		   ls_ld_tmpdir=`ls -ld "$tmpdir"`
+		   case $ls_ld_tmpdir in
+		     d????-?r-*) different_mode=700;;
+		     d????-?--*) different_mode=755;;
+		     *) false;;
+		   esac &&
+		   $mkdirprog -m$different_mode -p -- "$tmpdir" && {
+		     ls_ld_tmpdir_1=`ls -ld "$tmpdir"`
+		     test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1"
+		   }
+		 }
+	      then posix_mkdir=:
+	      fi
+	      rmdir "$tmpdir/d" "$tmpdir"
+	    else
+	      # Remove any dirs left behind by ancient mkdir implementations.
+	      rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null
+	    fi
+	    trap '' 0;;
+	esac;;
     esac
 
     if
       $posix_mkdir && (
-        umask $mkdir_umask &&
-        $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir"
+	umask $mkdir_umask &&
+	$doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir"
       )
     then :
     else
@@ -377,51 +391,53 @@ do
       # directory the slow way, step by step, checking for races as we go.
 
       case $dstdir in
-        /*) prefix='/';;
-        [-=\(\)!]*) prefix='./';;
-        *)  prefix='';;
+	/*) prefix='/';;
+	[-=\(\)!]*) prefix='./';;
+	*)  prefix='';;
       esac
 
+      eval "$initialize_posix_glob"
+
       oIFS=$IFS
       IFS=/
-      set -f
+      $posix_glob set -f
       set fnord $dstdir
       shift
-      set +f
+      $posix_glob set +f
       IFS=$oIFS
 
       prefixes=
 
       for d
       do
-        test X"$d" = X && continue
-
-        prefix=$prefix$d
-        if test -d "$prefix"; then
-          prefixes=
-        else
-          if $posix_mkdir; then
-            (umask=$mkdir_umask &&
-             $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break
-            # Don't fail if two instances are running concurrently.
-            test -d "$prefix" || exit 1
-          else
-            case $prefix in
-              *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;;
-              *) qprefix=$prefix;;
-            esac
-            prefixes="$prefixes '$qprefix'"
-          fi
-        fi
-        prefix=$prefix/
+	test X"$d" = X && continue
+
+	prefix=$prefix$d
+	if test -d "$prefix"; then
+	  prefixes=
+	else
+	  if $posix_mkdir; then
+	    (umask=$mkdir_umask &&
+	     $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break
+	    # Don't fail if two instances are running concurrently.
+	    test -d "$prefix" || exit 1
+	  else
+	    case $prefix in
+	      *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;;
+	      *) qprefix=$prefix;;
+	    esac
+	    prefixes="$prefixes '$qprefix'"
+	  fi
+	fi
+	prefix=$prefix/
       done
 
       if test -n "$prefixes"; then
-        # Don't fail if two instances are running concurrently.
-        (umask $mkdir_umask &&
-         eval "\$doit_exec \$mkdirprog $prefixes") ||
-          test -d "$dstdir" || exit 1
-        obsolete_mkdir_used=true
+	# Don't fail if two instances are running concurrently.
+	(umask $mkdir_umask &&
+	 eval "\$doit_exec \$mkdirprog $prefixes") ||
+	  test -d "$dstdir" || exit 1
+	obsolete_mkdir_used=true
       fi
     fi
   fi
@@ -456,12 +472,15 @@ do
 
     # If -C, don't bother to copy if it wouldn't change the file.
     if $copy_on_change &&
-       old=`LC_ALL=C ls -dlL "$dst"     2>/dev/null` &&
-       new=`LC_ALL=C ls -dlL "$dsttmp"  2>/dev/null` &&
-       set -f &&
+       old=`LC_ALL=C ls -dlL "$dst"	2>/dev/null` &&
+       new=`LC_ALL=C ls -dlL "$dsttmp"	2>/dev/null` &&
+
+       eval "$initialize_posix_glob" &&
+       $posix_glob set -f &&
        set X $old && old=:$2:$4:$5:$6 &&
        set X $new && new=:$2:$4:$5:$6 &&
-       set +f &&
+       $posix_glob set +f &&
+
        test "$old" = "$new" &&
        $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1
     then
@@ -474,24 +493,24 @@ do
       # to itself, or perhaps because mv is so ancient that it does not
       # support -f.
       {
-        # Now remove or move aside any old file at destination location.
-        # We try this two ways since rm can't unlink itself on some
-        # systems and the destination file might be busy for other
-        # reasons.  In this case, the final cleanup might fail but the new
-        # file should still install successfully.
-        {
-          test ! -f "$dst" ||
-          $doit $rmcmd -f "$dst" 2>/dev/null ||
-          { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null &&
-            { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; }
-          } ||
-          { echo "$0: cannot unlink or rename $dst" >&2
-            (exit 1); exit 1
-          }
-        } &&
-
-        # Now rename the file to the real destination.
-        $doit $mvcmd "$dsttmp" "$dst"
+	# Now remove or move aside any old file at destination location.
+	# We try this two ways since rm can't unlink itself on some
+	# systems and the destination file might be busy for other
+	# reasons.  In this case, the final cleanup might fail but the new
+	# file should still install successfully.
+	{
+	  test ! -f "$dst" ||
+	  $doit $rmcmd -f "$dst" 2>/dev/null ||
+	  { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null &&
+	    { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; }
+	  } ||
+	  { echo "$0: cannot unlink or rename $dst" >&2
+	    (exit 1); exit 1
+	  }
+	} &&
+
+	# Now rename the file to the real destination.
+	$doit $mvcmd "$dsttmp" "$dst"
       }
     fi || exit 1
 
diff --git a/src/gmock/gtest/build-aux/ltmain.sh b/src/gmock/gtest/build-aux/ltmain.sh
index 147d758..a356aca 100644
--- a/src/gmock/gtest/build-aux/ltmain.sh
+++ b/src/gmock/gtest/build-aux/ltmain.sh
@@ -1,12 +1,9 @@
-#! /bin/sh
-## DO NOT EDIT - This file generated from ./build-aux/ltmain.in
-##               by inline-source v2014-01-03.01
 
-# libtool (GNU libtool) 2.4.6
-# Provide generalized library-building support services.
+# libtool (GNU libtool) 2.4.2
 # Written by Gordon Matzigkeit <gord at gnu.ai.mit.edu>, 1996
 
-# Copyright (C) 1996-2015 Free Software Foundation, Inc.
+# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, 2006,
+# 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
 # This is free software; see the source for copying conditions.  There is NO
 # warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 
@@ -26,2112 +23,881 @@
 # General Public License for more details.
 #
 # You should have received a copy of the GNU General Public License
-# along with this program.  If not, see <http://www.gnu.org/licenses/>.
-
-
-PROGRAM=libtool
-PACKAGE=libtool
-VERSION="2.4.6 Debian-2.4.6-0.1"
-package_revision=2.4.6
-
-
-## ------ ##
-## Usage. ##
-## ------ ##
-
-# Run './libtool --help' for help with using this script from the
-# command line.
-
-
-## ------------------------------- ##
-## User overridable command paths. ##
-## ------------------------------- ##
-
-# After configure completes, it has a better idea of some of the
-# shell tools we need than the defaults used by the functions shared
-# with bootstrap, so set those here where they can still be over-
-# ridden by the user, but otherwise take precedence.
-
-: ${AUTOCONF="autoconf"}
-: ${AUTOMAKE="automake"}
-
-
-## -------------------------- ##
-## Source external libraries. ##
-## -------------------------- ##
-
-# Much of our low-level functionality needs to be sourced from external
-# libraries, which are installed to $pkgauxdir.
-
-# Set a version string for this script.
-scriptversion=2015-01-20.17; # UTC
-
-# General shell script boiler plate, and helper functions.
-# Written by Gary V. Vaughan, 2004
-
-# Copyright (C) 2004-2015 Free Software Foundation, Inc.
-# This is free software; see the source for copying conditions.  There is NO
-# warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 3 of the License, or
-# (at your option) any later version.
-
-# As a special exception to the GNU General Public License, if you distribute
-# this file as part of a program or library that is built using GNU Libtool,
-# you may include this file under the same distribution terms that you use
-# for the rest of that program.
-
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNES FOR A PARTICULAR PURPOSE. See the GNU
-# General Public License for more details.
-
-# You should have received a copy of the GNU General Public License
-# along with this program. If not, see <http://www.gnu.org/licenses/>.
+# along with GNU Libtool; see the file COPYING.  If not, a copy
+# can be downloaded from http://www.gnu.org/licenses/gpl.html,
+# or obtained by writing to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 
-# Please report bugs or propose patches to gary at gnu.org.
-
-
-## ------ ##
-## Usage. ##
-## ------ ##
-
-# Evaluate this file near the top of your script to gain access to
-# the functions and variables defined here:
+# Usage: $progname [OPTION]... [MODE-ARG]...
+#
+# Provide generalized library-building support services.
 #
-#   . `echo "$0" | ${SED-sed} 's|[^/]*$||'`/build-aux/funclib.sh
+#       --config             show all configuration variables
+#       --debug              enable verbose shell tracing
+#   -n, --dry-run            display commands without modifying any files
+#       --features           display basic configuration information and exit
+#       --mode=MODE          use operation mode MODE
+#       --preserve-dup-deps  don't remove duplicate dependency libraries
+#       --quiet, --silent    don't print informational messages
+#       --no-quiet, --no-silent
+#                            print informational messages (default)
+#       --no-warn            don't display warning messages
+#       --tag=TAG            use configuration variables from tag TAG
+#   -v, --verbose            print more informational messages than default
+#       --no-verbose         don't print the extra informational messages
+#       --version            print version information
+#   -h, --help, --help-all   print short, long, or detailed help message
 #
-# If you need to override any of the default environment variable
-# settings, do that before evaluating this file.
-
-
-## -------------------- ##
-## Shell normalisation. ##
-## -------------------- ##
+# MODE must be one of the following:
+#
+#         clean              remove files from the build directory
+#         compile            compile a source file into a libtool object
+#         execute            automatically set library path, then run a program
+#         finish             complete the installation of libtool libraries
+#         install            install libraries or executables
+#         link               create a library or an executable
+#         uninstall          remove libraries from an installed directory
+#
+# MODE-ARGS vary depending on the MODE.  When passed as first option,
+# `--mode=MODE' may be abbreviated as `MODE' or a unique abbreviation of that.
+# Try `$progname --help --mode=MODE' for a more detailed description of MODE.
+#
+# When reporting a bug, please describe a test case to reproduce it and
+# include the following information:
+#
+#         host-triplet:	$host
+#         shell:		$SHELL
+#         compiler:		$LTCC
+#         compiler flags:		$LTCFLAGS
+#         linker:		$LD (gnu? $with_gnu_ld)
+#         $progname:	(GNU libtool) 2.4.2 Debian-2.4.2-1.7ubuntu1
+#         automake:	$automake_version
+#         autoconf:	$autoconf_version
+#
+# Report bugs to <bug-libtool at gnu.org>.
+# GNU libtool home page: <http://www.gnu.org/software/libtool/>.
+# General help using GNU software: <http://www.gnu.org/gethelp/>.
 
-# Some shells need a little help to be as Bourne compatible as possible.
-# Before doing anything else, make sure all that help has been provided!
+PROGRAM=libtool
+PACKAGE=libtool
+VERSION="2.4.2 Debian-2.4.2-1.7ubuntu1"
+TIMESTAMP=""
+package_revision=1.3337
 
-DUALCASE=1; export DUALCASE # for MKS sh
-if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then :
+# Be Bourne compatible
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
   emulate sh
   NULLCMD=:
-  # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which
+  # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which
   # is contrary to our usage.  Disable this feature.
   alias -g '${1+"$@"}'='"$@"'
   setopt NO_GLOB_SUBST
 else
-  case `(set -o) 2>/dev/null` in *posix*) set -o posix ;; esac
-fi
-
-# NLS nuisances: We save the old values in case they are required later.
-_G_user_locale=
-_G_safe_locale=
-for _G_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES
-do
-  eval "if test set = \"\${$_G_var+set}\"; then
-          save_$_G_var=\$$_G_var
-          $_G_var=C
-	  export $_G_var
-	  _G_user_locale=\"$_G_var=\\\$save_\$_G_var; \$_G_user_locale\"
-	  _G_safe_locale=\"$_G_var=C; \$_G_safe_locale\"
-	fi"
-done
-
-# CDPATH.
-(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
-
-# Make sure IFS has a sensible default
-sp=' '
-nl='
-'
-IFS="$sp	$nl"
-
-# There are apparently some retarded systems that use ';' as a PATH separator!
-if test "${PATH_SEPARATOR+set}" != set; then
-  PATH_SEPARATOR=:
-  (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && {
-    (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 ||
-      PATH_SEPARATOR=';'
-  }
+  case `(set -o) 2>/dev/null` in *posix*) set -o posix;; esac
 fi
+BIN_SH=xpg4; export BIN_SH # for Tru64
+DUALCASE=1; export DUALCASE # for MKS sh
 
-
-
-## ------------------------- ##
-## Locate command utilities. ##
-## ------------------------- ##
-
-
-# func_executable_p FILE
-# ----------------------
-# Check that FILE is an executable regular file.
-func_executable_p ()
-{
-    test -f "$1" && test -x "$1"
-}
-
-
-# func_path_progs PROGS_LIST CHECK_FUNC [PATH]
-# --------------------------------------------
-# Search for either a program that responds to --version with output
-# containing "GNU", or else returned by CHECK_FUNC otherwise, by
-# trying all the directories in PATH with each of the elements of
-# PROGS_LIST.
-#
-# CHECK_FUNC should accept the path to a candidate program, and
-# set $func_check_prog_result if it truncates its output less than
-# $_G_path_prog_max characters.
-func_path_progs ()
+# A function that is used when there is no print builtin or printf.
+func_fallback_echo ()
 {
-    _G_progs_list=$1
-    _G_check_func=$2
-    _G_PATH=${3-"$PATH"}
-
-    _G_path_prog_max=0
-    _G_path_prog_found=false
-    _G_save_IFS=$IFS; IFS=${PATH_SEPARATOR-:}
-    for _G_dir in $_G_PATH; do
-      IFS=$_G_save_IFS
-      test -z "$_G_dir" && _G_dir=.
-      for _G_prog_name in $_G_progs_list; do
-        for _exeext in '' .EXE; do
-          _G_path_prog=$_G_dir/$_G_prog_name$_exeext
-          func_executable_p "$_G_path_prog" || continue
-          case `"$_G_path_prog" --version 2>&1` in
-            *GNU*) func_path_progs_result=$_G_path_prog _G_path_prog_found=: ;;
-            *)     $_G_check_func $_G_path_prog
-		   func_path_progs_result=$func_check_prog_result
-		   ;;
-          esac
-          $_G_path_prog_found && break 3
-        done
-      done
-    done
-    IFS=$_G_save_IFS
-    test -z "$func_path_progs_result" && {
-      echo "no acceptable sed could be found in \$PATH" >&2
-      exit 1
-    }
-}
-
-
-# We want to be able to use the functions in this file before configure
-# has figured out where the best binaries are kept, which means we have
-# to search for them ourselves - except when the results are already set
-# where we skip the searches.
-
-# Unless the user overrides by setting SED, search the path for either GNU
-# sed, or the sed that truncates its output the least.
-test -z "$SED" && {
-  _G_sed_script=s/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/
-  for _G_i in 1 2 3 4 5 6 7; do
-    _G_sed_script=$_G_sed_script$nl$_G_sed_script
-  done
-  echo "$_G_sed_script" 2>/dev/null | sed 99q >conftest.sed
-  _G_sed_script=
-
-  func_check_prog_sed ()
-  {
-    _G_path_prog=$1
-
-    _G_count=0
-    printf 0123456789 >conftest.in
-    while :
-    do
-      cat conftest.in conftest.in >conftest.tmp
-      mv conftest.tmp conftest.in
-      cp conftest.in conftest.nl
-      echo '' >> conftest.nl
-      "$_G_path_prog" -f conftest.sed <conftest.nl >conftest.out 2>/dev/null || break
-      diff conftest.out conftest.nl >/dev/null 2>&1 || break
-      _G_count=`expr $_G_count + 1`
-      if test "$_G_count" -gt "$_G_path_prog_max"; then
-        # Best one so far, save it but keep looking for a better one
-        func_check_prog_result=$_G_path_prog
-        _G_path_prog_max=$_G_count
-      fi
-      # 10*(2^10) chars as input seems more than enough
-      test 10 -lt "$_G_count" && break
-    done
-    rm -f conftest.in conftest.tmp conftest.nl conftest.out
-  }
-
-  func_path_progs "sed gsed" func_check_prog_sed $PATH:/usr/xpg4/bin
-  rm -f conftest.sed
-  SED=$func_path_progs_result
+  eval 'cat <<_LTECHO_EOF
+$1
+_LTECHO_EOF'
 }
 
+# NLS nuisances: We save the old values to restore during execute mode.
+lt_user_locale=
+lt_safe_locale=
+for lt_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES
+do
+  eval "if test \"\${$lt_var+set}\" = set; then
+          save_$lt_var=\$$lt_var
+          $lt_var=C
+	  export $lt_var
+	  lt_user_locale=\"$lt_var=\\\$save_\$lt_var; \$lt_user_locale\"
+	  lt_safe_locale=\"$lt_var=C; \$lt_safe_locale\"
+	fi"
+done
+LC_ALL=C
+LANGUAGE=C
+export LANGUAGE LC_ALL
 
-# Unless the user overrides by setting GREP, search the path for either GNU
-# grep, or the grep that truncates its output the least.
-test -z "$GREP" && {
-  func_check_prog_grep ()
-  {
-    _G_path_prog=$1
-
-    _G_count=0
-    _G_path_prog_max=0
-    printf 0123456789 >conftest.in
-    while :
-    do
-      cat conftest.in conftest.in >conftest.tmp
-      mv conftest.tmp conftest.in
-      cp conftest.in conftest.nl
-      echo 'GREP' >> conftest.nl
-      "$_G_path_prog" -e 'GREP$' -e '-(cannot match)-' <conftest.nl >conftest.out 2>/dev/null || break
-      diff conftest.out conftest.nl >/dev/null 2>&1 || break
-      _G_count=`expr $_G_count + 1`
-      if test "$_G_count" -gt "$_G_path_prog_max"; then
-        # Best one so far, save it but keep looking for a better one
-        func_check_prog_result=$_G_path_prog
-        _G_path_prog_max=$_G_count
-      fi
-      # 10*(2^10) chars as input seems more than enough
-      test 10 -lt "$_G_count" && break
-    done
-    rm -f conftest.in conftest.tmp conftest.nl conftest.out
-  }
+$lt_unset CDPATH
 
-  func_path_progs "grep ggrep" func_check_prog_grep $PATH:/usr/xpg4/bin
-  GREP=$func_path_progs_result
-}
 
+# Work around backward compatibility issue on IRIX 6.5. On IRIX 6.4+, sh
+# is ksh but when the shell is invoked as "sh" and the current value of
+# the _XPG environment variable is not equal to 1 (one), the special
+# positional parameter $0, within a function call, is the name of the
+# function.
+progpath="$0"
 
-## ------------------------------- ##
-## User overridable command paths. ##
-## ------------------------------- ##
 
-# All uppercase variable names are used for environment variables.  These
-# variables can be overridden by the user before calling a script that
-# uses them if a suitable command of that name is not already available
-# in the command search PATH.
 
 : ${CP="cp -f"}
-: ${ECHO="printf %s\n"}
-: ${EGREP="$GREP -E"}
-: ${FGREP="$GREP -F"}
-: ${LN_S="ln -s"}
+test "${ECHO+set}" = set || ECHO=${as_echo-'printf %s\n'}
 : ${MAKE="make"}
 : ${MKDIR="mkdir"}
 : ${MV="mv -f"}
 : ${RM="rm -f"}
 : ${SHELL="${CONFIG_SHELL-/bin/sh}"}
+: ${Xsed="$SED -e 1s/^X//"}
 
+# Global variables:
+EXIT_SUCCESS=0
+EXIT_FAILURE=1
+EXIT_MISMATCH=63  # $? = 63 is used to indicate version mismatch to missing.
+EXIT_SKIP=77	  # $? = 77 is used to indicate a skipped test to automake.
 
-## -------------------- ##
-## Useful sed snippets. ##
-## -------------------- ##
+exit_status=$EXIT_SUCCESS
 
-sed_dirname='s|/[^/]*$||'
-sed_basename='s|^.*/||'
+# Make sure IFS has a sensible default
+lt_nl='
+'
+IFS=" 	$lt_nl"
 
-# Sed substitution that helps us do robust quoting.  It backslashifies
-# metacharacters that are still active within double-quoted strings.
-sed_quote_subst='s|\([`"$\\]\)|\\\1|g'
+dirname="s,/[^/]*$,,"
+basename="s,^.*/,,"
 
-# Same as above, but do not quote variable references.
-sed_double_quote_subst='s/\(["`\\]\)/\\\1/g'
+# func_dirname file append nondir_replacement
+# Compute the dirname of FILE.  If nonempty, add APPEND to the result,
+# otherwise set result to NONDIR_REPLACEMENT.
+func_dirname ()
+{
+    func_dirname_result=`$ECHO "${1}" | $SED "$dirname"`
+    if test "X$func_dirname_result" = "X${1}"; then
+      func_dirname_result="${3}"
+    else
+      func_dirname_result="$func_dirname_result${2}"
+    fi
+} # func_dirname may be replaced by extended shell implementation
 
-# Sed substitution that turns a string into a regex matching for the
-# string literally.
-sed_make_literal_regex='s|[].[^$\\*\/]|\\&|g'
 
-# Sed substitution that converts a w32 file name or path
-# that contains forward slashes, into one that contains
-# (escaped) backslashes.  A very naive implementation.
-sed_naive_backslashify='s|\\\\*|\\|g;s|/|\\|g;s|\\|\\\\|g'
-
-# Re-'\' parameter expansions in output of sed_double_quote_subst that
-# were '\'-ed in input to the same.  If an odd number of '\' preceded a
-# '$' in input to sed_double_quote_subst, that '$' was protected from
-# expansion.  Since each input '\' is now two '\'s, look for any number
-# of runs of four '\'s followed by two '\'s and then a '$'.  '\' that '$'.
-_G_bs='\\'
-_G_bs2='\\\\'
-_G_bs4='\\\\\\\\'
-_G_dollar='\$'
-sed_double_backslash="\
-  s/$_G_bs4/&\\
-/g
-  s/^$_G_bs2$_G_dollar/$_G_bs&/
-  s/\\([^$_G_bs]\\)$_G_bs2$_G_dollar/\\1$_G_bs2$_G_bs$_G_dollar/g
-  s/\n//g"
+# func_basename file
+func_basename ()
+{
+    func_basename_result=`$ECHO "${1}" | $SED "$basename"`
+} # func_basename may be replaced by extended shell implementation
 
 
-## ----------------- ##
-## Global variables. ##
-## ----------------- ##
+# func_dirname_and_basename file append nondir_replacement
+# perform func_basename and func_dirname in a single function
+# call:
+#   dirname:  Compute the dirname of FILE.  If nonempty,
+#             add APPEND to the result, otherwise set result
+#             to NONDIR_REPLACEMENT.
+#             value returned in "$func_dirname_result"
+#   basename: Compute filename of FILE.
+#             value retuned in "$func_basename_result"
+# Implementation must be kept synchronized with func_dirname
+# and func_basename. For efficiency, we do not delegate to
+# those functions but instead duplicate the functionality here.
+func_dirname_and_basename ()
+{
+    # Extract subdirectory from the argument.
+    func_dirname_result=`$ECHO "${1}" | $SED -e "$dirname"`
+    if test "X$func_dirname_result" = "X${1}"; then
+      func_dirname_result="${3}"
+    else
+      func_dirname_result="$func_dirname_result${2}"
+    fi
+    func_basename_result=`$ECHO "${1}" | $SED -e "$basename"`
+} # func_dirname_and_basename may be replaced by extended shell implementation
 
-# Except for the global variables explicitly listed below, the following
-# functions in the '^func_' namespace, and the '^require_' namespace
-# variables initialised in the 'Resource management' section, sourcing
-# this file will not pollute your global namespace with anything
-# else. There's no portable way to scope variables in Bourne shell
-# though, so actually running these functions will sometimes place
-# results into a variable named after the function, and often use
-# temporary variables in the '^_G_' namespace. If you are careful to
-# avoid using those namespaces casually in your sourcing script, things
-# should continue to work as you expect. And, of course, you can freely
-# overwrite any of the functions or variables defined here before
-# calling anything to customize them.
 
-EXIT_SUCCESS=0
-EXIT_FAILURE=1
-EXIT_MISMATCH=63  # $? = 63 is used to indicate version mismatch to missing.
-EXIT_SKIP=77	  # $? = 77 is used to indicate a skipped test to automake.
+# func_stripname prefix suffix name
+# strip PREFIX and SUFFIX off of NAME.
+# PREFIX and SUFFIX must not contain globbing or regex special
+# characters, hashes, percent signs, but SUFFIX may contain a leading
+# dot (in which case that matches only a dot).
+# func_strip_suffix prefix name
+func_stripname ()
+{
+    case ${2} in
+      .*) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%\\\\${2}\$%%"`;;
+      *)  func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%${2}\$%%"`;;
+    esac
+} # func_stripname may be replaced by extended shell implementation
 
-# Allow overriding, eg assuming that you follow the convention of
-# putting '$debug_cmd' at the start of all your functions, you can get
-# bash to show function call trace with:
-#
-#    debug_cmd='eval echo "${FUNCNAME[0]} $*" >&2' bash your-script-name
-debug_cmd=${debug_cmd-":"}
-exit_cmd=:
 
-# By convention, finish your script with:
-#
-#    exit $exit_status
-#
-# so that you can set exit_status to non-zero if you want to indicate
-# something went wrong during execution without actually bailing out at
-# the point of failure.
-exit_status=$EXIT_SUCCESS
+# These SED scripts presuppose an absolute path with a trailing slash.
+pathcar='s,^/\([^/]*\).*$,\1,'
+pathcdr='s,^/[^/]*,,'
+removedotparts=':dotsl
+		s@/\./@/@g
+		t dotsl
+		s,/\.$,/,'
+collapseslashes='s@/\{1,\}@/@g'
+finalslash='s,/*$,/,'
 
-# Work around backward compatibility issue on IRIX 6.5. On IRIX 6.4+, sh
-# is ksh but when the shell is invoked as "sh" and the current value of
-# the _XPG environment variable is not equal to 1 (one), the special
-# positional parameter $0, within a function call, is the name of the
-# function.
-progpath=$0
+# func_normal_abspath PATH
+# Remove doubled-up and trailing slashes, "." path components,
+# and cancel out any ".." path components in PATH after making
+# it an absolute path.
+#             value returned in "$func_normal_abspath_result"
+func_normal_abspath ()
+{
+  # Start from root dir and reassemble the path.
+  func_normal_abspath_result=
+  func_normal_abspath_tpath=$1
+  func_normal_abspath_altnamespace=
+  case $func_normal_abspath_tpath in
+    "")
+      # Empty path, that just means $cwd.
+      func_stripname '' '/' "`pwd`"
+      func_normal_abspath_result=$func_stripname_result
+      return
+    ;;
+    # The next three entries are used to spot a run of precisely
+    # two leading slashes without using negated character classes;
+    # we take advantage of case's first-match behaviour.
+    ///*)
+      # Unusual form of absolute path, do nothing.
+    ;;
+    //*)
+      # Not necessarily an ordinary path; POSIX reserves leading '//'
+      # and for example Cygwin uses it to access remote file shares
+      # over CIFS/SMB, so we conserve a leading double slash if found.
+      func_normal_abspath_altnamespace=/
+    ;;
+    /*)
+      # Absolute path, do nothing.
+    ;;
+    *)
+      # Relative path, prepend $cwd.
+      func_normal_abspath_tpath=`pwd`/$func_normal_abspath_tpath
+    ;;
+  esac
+  # Cancel out all the simple stuff to save iterations.  We also want
+  # the path to end with a slash for ease of parsing, so make sure
+  # there is one (and only one) here.
+  func_normal_abspath_tpath=`$ECHO "$func_normal_abspath_tpath" | $SED \
+        -e "$removedotparts" -e "$collapseslashes" -e "$finalslash"`
+  while :; do
+    # Processed it all yet?
+    if test "$func_normal_abspath_tpath" = / ; then
+      # If we ascended to the root using ".." the result may be empty now.
+      if test -z "$func_normal_abspath_result" ; then
+        func_normal_abspath_result=/
+      fi
+      break
+    fi
+    func_normal_abspath_tcomponent=`$ECHO "$func_normal_abspath_tpath" | $SED \
+        -e "$pathcar"`
+    func_normal_abspath_tpath=`$ECHO "$func_normal_abspath_tpath" | $SED \
+        -e "$pathcdr"`
+    # Figure out what to do with it
+    case $func_normal_abspath_tcomponent in
+      "")
+        # Trailing empty path component, ignore it.
+      ;;
+      ..)
+        # Parent dir; strip last assembled component from result.
+        func_dirname "$func_normal_abspath_result"
+        func_normal_abspath_result=$func_dirname_result
+      ;;
+      *)
+        # Actual path component, append it.
+        func_normal_abspath_result=$func_normal_abspath_result/$func_normal_abspath_tcomponent
+      ;;
+    esac
+  done
+  # Restore leading double-slash if one was found on entry.
+  func_normal_abspath_result=$func_normal_abspath_altnamespace$func_normal_abspath_result
+}
+
+# func_relative_path SRCDIR DSTDIR
+# generates a relative path from SRCDIR to DSTDIR, with a trailing
+# slash if non-empty, suitable for immediately appending a filename
+# without needing to append a separator.
+#             value returned in "$func_relative_path_result"
+func_relative_path ()
+{
+  func_relative_path_result=
+  func_normal_abspath "$1"
+  func_relative_path_tlibdir=$func_normal_abspath_result
+  func_normal_abspath "$2"
+  func_relative_path_tbindir=$func_normal_abspath_result
+
+  # Ascend the tree starting from libdir
+  while :; do
+    # check if we have found a prefix of bindir
+    case $func_relative_path_tbindir in
+      $func_relative_path_tlibdir)
+        # found an exact match
+        func_relative_path_tcancelled=
+        break
+        ;;
+      $func_relative_path_tlibdir*)
+        # found a matching prefix
+        func_stripname "$func_relative_path_tlibdir" '' "$func_relative_path_tbindir"
+        func_relative_path_tcancelled=$func_stripname_result
+        if test -z "$func_relative_path_result"; then
+          func_relative_path_result=.
+        fi
+        break
+        ;;
+      *)
+        func_dirname $func_relative_path_tlibdir
+        func_relative_path_tlibdir=${func_dirname_result}
+        if test "x$func_relative_path_tlibdir" = x ; then
+          # Have to descend all the way to the root!
+          func_relative_path_result=../$func_relative_path_result
+          func_relative_path_tcancelled=$func_relative_path_tbindir
+          break
+        fi
+        func_relative_path_result=../$func_relative_path_result
+        ;;
+    esac
+  done
+
+  # Now calculate path; take care to avoid doubling-up slashes.
+  func_stripname '' '/' "$func_relative_path_result"
+  func_relative_path_result=$func_stripname_result
+  func_stripname '/' '/' "$func_relative_path_tcancelled"
+  if test "x$func_stripname_result" != x ; then
+    func_relative_path_result=${func_relative_path_result}/${func_stripname_result}
+  fi
+
+  # Normalisation. If bindir is libdir, return empty string,
+  # else relative path ending with a slash; either way, target
+  # file name can be directly appended.
+  if test ! -z "$func_relative_path_result"; then
+    func_stripname './' '' "$func_relative_path_result/"
+    func_relative_path_result=$func_stripname_result
+  fi
+}
 
-# The name of this program.
-progname=`$ECHO "$progpath" |$SED "$sed_basename"`
+# The name of this program:
+func_dirname_and_basename "$progpath"
+progname=$func_basename_result
 
-# Make sure we have an absolute progpath for reexecution:
+# Make sure we have an absolute path for reexecution:
 case $progpath in
   [\\/]*|[A-Za-z]:\\*) ;;
   *[\\/]*)
-     progdir=`$ECHO "$progpath" |$SED "$sed_dirname"`
+     progdir=$func_dirname_result
      progdir=`cd "$progdir" && pwd`
-     progpath=$progdir/$progname
+     progpath="$progdir/$progname"
      ;;
   *)
-     _G_IFS=$IFS
+     save_IFS="$IFS"
      IFS=${PATH_SEPARATOR-:}
      for progdir in $PATH; do
-       IFS=$_G_IFS
+       IFS="$save_IFS"
        test -x "$progdir/$progname" && break
      done
-     IFS=$_G_IFS
+     IFS="$save_IFS"
      test -n "$progdir" || progdir=`pwd`
-     progpath=$progdir/$progname
+     progpath="$progdir/$progname"
      ;;
 esac
 
+# Sed substitution that helps us do robust quoting.  It backslashifies
+# metacharacters that are still active within double-quoted strings.
+Xsed="${SED}"' -e 1s/^X//'
+sed_quote_subst='s/\([`"$\\]\)/\\\1/g'
+
+# Same as above, but do not quote variable references.
+double_quote_subst='s/\(["`\\]\)/\\\1/g'
 
-## ----------------- ##
-## Standard options. ##
-## ----------------- ##
+# Sed substitution that turns a string into a regex matching for the
+# string literally.
+sed_make_literal_regex='s,[].[^$\\*\/],\\&,g'
 
-# The following options affect the operation of the functions defined
-# below, and should be set appropriately depending on run-time para-
-# meters passed on the command line.
+# Sed substitution that converts a w32 file name or path
+# which contains forward slashes, into one that contains
+# (escaped) backslashes.  A very naive implementation.
+lt_sed_naive_backslashify='s|\\\\*|\\|g;s|/|\\|g;s|\\|\\\\|g'
+
+# Re-`\' parameter expansions in output of double_quote_subst that were
+# `\'-ed in input to the same.  If an odd number of `\' preceded a '$'
+# in input to double_quote_subst, that '$' was protected from expansion.
+# Since each input `\' is now two `\'s, look for any number of runs of
+# four `\'s followed by two `\'s and then a '$'.  `\' that '$'.
+bs='\\'
+bs2='\\\\'
+bs4='\\\\\\\\'
+dollar='\$'
+sed_double_backslash="\
+  s/$bs4/&\\
+/g
+  s/^$bs2$dollar/$bs&/
+  s/\\([^$bs]\\)$bs2$dollar/\\1$bs2$bs$dollar/g
+  s/\n//g"
 
+# Standard options:
 opt_dry_run=false
+opt_help=false
 opt_quiet=false
 opt_verbose=false
+opt_warning=:
 
-# Categories 'all' and 'none' are always available.  Append any others
-# you will pass as the first argument to func_warning from your own
-# code.
-warning_categories=
+# func_echo arg...
+# Echo program name prefixed message, along with the current mode
+# name if it has been set yet.
+func_echo ()
+{
+    $ECHO "$progname: ${opt_mode+$opt_mode: }$*"
+}
 
-# By default, display warnings according to 'opt_warning_types'.  Set
-# 'warning_func'  to ':' to elide all warnings, or func_fatal_error to
-# treat the next displayed warning as a fatal error.
-warning_func=func_warn_and_continue
+# func_verbose arg...
+# Echo program name prefixed message in verbose mode only.
+func_verbose ()
+{
+    $opt_verbose && func_echo ${1+"$@"}
 
-# Set to 'all' to display all warnings, 'none' to suppress all
-# warnings, or a space delimited list of some subset of
-# 'warning_categories' to display only the listed warnings.
-opt_warning_types=all
+    # A bug in bash halts the script if the last line of a function
+    # fails when set -e is in force, so we need another command to
+    # work around that:
+    :
+}
 
+# func_echo_all arg...
+# Invoke $ECHO with all args, space-separated.
+func_echo_all ()
+{
+    $ECHO "$*"
+}
 
-## -------------------- ##
-## Resource management. ##
-## -------------------- ##
+# func_error arg...
+# Echo program name prefixed message to standard error.
+func_error ()
+{
+    $ECHO "$progname: ${opt_mode+$opt_mode: }"${1+"$@"} 1>&2
+}
 
-# This section contains definitions for functions that each ensure a
-# particular resource (a file, or a non-empty configuration variable for
-# example) is available, and if appropriate to extract default values
-# from pertinent package files. Call them using their associated
-# 'require_*' variable to ensure that they are executed, at most, once.
-#
-# It's entirely deliberate that calling these functions can set
-# variables that don't obey the namespace limitations obeyed by the rest
-# of this file, in order that that they be as useful as possible to
-# callers.
+# func_warning arg...
+# Echo program name prefixed warning message to standard error.
+func_warning ()
+{
+    $opt_warning && $ECHO "$progname: ${opt_mode+$opt_mode: }warning: "${1+"$@"} 1>&2
 
+    # bash bug again:
+    :
+}
 
-# require_term_colors
-# -------------------
-# Allow display of bold text on terminals that support it.
-require_term_colors=func_require_term_colors
-func_require_term_colors ()
+# func_fatal_error arg...
+# Echo program name prefixed message to standard error, and exit.
+func_fatal_error ()
 {
-    $debug_cmd
-
-    test -t 1 && {
-      # COLORTERM and USE_ANSI_COLORS environment variables take
-      # precedence, because most terminfo databases neglect to describe
-      # whether color sequences are supported.
-      test -n "${COLORTERM+set}" && : ${USE_ANSI_COLORS="1"}
-
-      if test 1 = "$USE_ANSI_COLORS"; then
-        # Standard ANSI escape sequences
-        tc_reset=''
-        tc_bold='';   tc_standout=''
-        tc_red='';   tc_green=''
-        tc_blue='';  tc_cyan=''
-      else
-        # Otherwise trust the terminfo database after all.
-        test -n "`tput sgr0 2>/dev/null`" && {
-          tc_reset=`tput sgr0`
-          test -n "`tput bold 2>/dev/null`" && tc_bold=`tput bold`
-          tc_standout=$tc_bold
-          test -n "`tput smso 2>/dev/null`" && tc_standout=`tput smso`
-          test -n "`tput setaf 1 2>/dev/null`" && tc_red=`tput setaf 1`
-          test -n "`tput setaf 2 2>/dev/null`" && tc_green=`tput setaf 2`
-          test -n "`tput setaf 4 2>/dev/null`" && tc_blue=`tput setaf 4`
-          test -n "`tput setaf 5 2>/dev/null`" && tc_cyan=`tput setaf 5`
-        }
-      fi
-    }
+    func_error ${1+"$@"}
+    exit $EXIT_FAILURE
+}
 
-    require_term_colors=:
+# func_fatal_help arg...
+# Echo program name prefixed message to standard error, followed by
+# a help hint, and exit.
+func_fatal_help ()
+{
+    func_error ${1+"$@"}
+    func_fatal_error "$help"
 }
+help="Try \`$progname --help' for more information."  ## default
 
 
-## ----------------- ##
-## Function library. ##
-## ----------------- ##
-
-# This section contains a variety of useful functions to call in your
-# scripts. Take note of the portable wrappers for features provided by
-# some modern shells, which will fall back to slower equivalents on
-# less featureful shells.
-
-
-# func_append VAR VALUE
-# ---------------------
-# Append VALUE onto the existing contents of VAR.
-
-  # We should try to minimise forks, especially on Windows where they are
-  # unreasonably slow, so skip the feature probes when bash or zsh are
-  # being used:
-  if test set = "${BASH_VERSION+set}${ZSH_VERSION+set}"; then
-    : ${_G_HAVE_ARITH_OP="yes"}
-    : ${_G_HAVE_XSI_OPS="yes"}
-    # The += operator was introduced in bash 3.1
-    case $BASH_VERSION in
-      [12].* | 3.0 | 3.0*) ;;
-      *)
-        : ${_G_HAVE_PLUSEQ_OP="yes"}
-        ;;
-    esac
-  fi
-
-  # _G_HAVE_PLUSEQ_OP
-  # Can be empty, in which case the shell is probed, "yes" if += is
-  # useable or anything else if it does not work.
-  test -z "$_G_HAVE_PLUSEQ_OP" \
-    && (eval 'x=a; x+=" b"; test "a b" = "$x"') 2>/dev/null \
-    && _G_HAVE_PLUSEQ_OP=yes
-
-if test yes = "$_G_HAVE_PLUSEQ_OP"
-then
-  # This is an XSI compatible shell, allowing a faster implementation...
-  eval 'func_append ()
-  {
-    $debug_cmd
-
-    eval "$1+=\$2"
-  }'
-else
-  # ...otherwise fall back to using expr, which is often a shell builtin.
-  func_append ()
-  {
-    $debug_cmd
-
-    eval "$1=\$$1\$2"
-  }
-fi
-
-
-# func_append_quoted VAR VALUE
-# ----------------------------
-# Quote VALUE and append to the end of shell variable VAR, separated
-# by a space.
-if test yes = "$_G_HAVE_PLUSEQ_OP"; then
-  eval 'func_append_quoted ()
-  {
-    $debug_cmd
-
-    func_quote_for_eval "$2"
-    eval "$1+=\\ \$func_quote_for_eval_result"
-  }'
-else
-  func_append_quoted ()
-  {
-    $debug_cmd
-
-    func_quote_for_eval "$2"
-    eval "$1=\$$1\\ \$func_quote_for_eval_result"
-  }
-fi
-
-
-# func_append_uniq VAR VALUE
-# --------------------------
-# Append unique VALUE onto the existing contents of VAR, assuming
-# entries are delimited by the first character of VALUE.  For example:
-#
-#   func_append_uniq options " --another-option option-argument"
-#
-# will only append to $options if " --another-option option-argument "
-# is not already present somewhere in $options already (note spaces at
-# each end implied by leading space in second argument).
-func_append_uniq ()
-{
-    $debug_cmd
-
-    eval _G_current_value='`$ECHO $'$1'`'
-    _G_delim=`expr "$2" : '\(.\)'`
-
-    case $_G_delim$_G_current_value$_G_delim in
-      *"$2$_G_delim"*) ;;
-      *) func_append "$@" ;;
-    esac
-}
-
-
-# func_arith TERM...
-# ------------------
-# Set func_arith_result to the result of evaluating TERMs.
-  test -z "$_G_HAVE_ARITH_OP" \
-    && (eval 'test 2 = $(( 1 + 1 ))') 2>/dev/null \
-    && _G_HAVE_ARITH_OP=yes
-
-if test yes = "$_G_HAVE_ARITH_OP"; then
-  eval 'func_arith ()
-  {
-    $debug_cmd
-
-    func_arith_result=$(( $* ))
-  }'
-else
-  func_arith ()
-  {
-    $debug_cmd
-
-    func_arith_result=`expr "$@"`
-  }
-fi
-
-
-# func_basename FILE
-# ------------------
-# Set func_basename_result to FILE with everything up to and including
-# the last / stripped.
-if test yes = "$_G_HAVE_XSI_OPS"; then
-  # If this shell supports suffix pattern removal, then use it to avoid
-  # forking. Hide the definitions single quotes in case the shell chokes
-  # on unsupported syntax...
-  _b='func_basename_result=${1##*/}'
-  _d='case $1 in
-        */*) func_dirname_result=${1%/*}$2 ;;
-        *  ) func_dirname_result=$3        ;;
-      esac'
-
-else
-  # ...otherwise fall back to using sed.
-  _b='func_basename_result=`$ECHO "$1" |$SED "$sed_basename"`'
-  _d='func_dirname_result=`$ECHO "$1"  |$SED "$sed_dirname"`
-      if test "X$func_dirname_result" = "X$1"; then
-        func_dirname_result=$3
-      else
-        func_append func_dirname_result "$2"
-      fi'
-fi
-
-eval 'func_basename ()
-{
-    $debug_cmd
-
-    '"$_b"'
-}'
-
-
-# func_dirname FILE APPEND NONDIR_REPLACEMENT
-# -------------------------------------------
-# Compute the dirname of FILE.  If nonempty, add APPEND to the result,
-# otherwise set result to NONDIR_REPLACEMENT.
-eval 'func_dirname ()
-{
-    $debug_cmd
-
-    '"$_d"'
-}'
-
-
-# func_dirname_and_basename FILE APPEND NONDIR_REPLACEMENT
-# --------------------------------------------------------
-# Perform func_basename and func_dirname in a single function
-# call:
-#   dirname:  Compute the dirname of FILE.  If nonempty,
-#             add APPEND to the result, otherwise set result
-#             to NONDIR_REPLACEMENT.
-#             value returned in "$func_dirname_result"
-#   basename: Compute filename of FILE.
-#             value retuned in "$func_basename_result"
-# For efficiency, we do not delegate to the functions above but instead
-# duplicate the functionality here.
-eval 'func_dirname_and_basename ()
-{
-    $debug_cmd
-
-    '"$_b"'
-    '"$_d"'
-}'
-
-
-# func_echo ARG...
-# ----------------
-# Echo program name prefixed message.
-func_echo ()
-{
-    $debug_cmd
-
-    _G_message=$*
-
-    func_echo_IFS=$IFS
-    IFS=$nl
-    for _G_line in $_G_message; do
-      IFS=$func_echo_IFS
-      $ECHO "$progname: $_G_line"
-    done
-    IFS=$func_echo_IFS
-}
-
-
-# func_echo_all ARG...
-# --------------------
-# Invoke $ECHO with all args, space-separated.
-func_echo_all ()
-{
-    $ECHO "$*"
-}
-
-
-# func_echo_infix_1 INFIX ARG...
-# ------------------------------
-# Echo program name, followed by INFIX on the first line, with any
-# additional lines not showing INFIX.
-func_echo_infix_1 ()
-{
-    $debug_cmd
-
-    $require_term_colors
-
-    _G_infix=$1; shift
-    _G_indent=$_G_infix
-    _G_prefix="$progname: $_G_infix: "
-    _G_message=$*
-
-    # Strip color escape sequences before counting printable length
-    for _G_tc in "$tc_reset" "$tc_bold" "$tc_standout" "$tc_red" "$tc_green" "$tc_blue" "$tc_cyan"
-    do
-      test -n "$_G_tc" && {
-        _G_esc_tc=`$ECHO "$_G_tc" | $SED "$sed_make_literal_regex"`
-        _G_indent=`$ECHO "$_G_indent" | $SED "s|$_G_esc_tc||g"`
-      }
-    done
-    _G_indent="$progname: "`echo "$_G_indent" | $SED 's|.| |g'`"  " ## exclude from sc_prohibit_nested_quotes
-
-    func_echo_infix_1_IFS=$IFS
-    IFS=$nl
-    for _G_line in $_G_message; do
-      IFS=$func_echo_infix_1_IFS
-      $ECHO "$_G_prefix$tc_bold$_G_line$tc_reset" >&2
-      _G_prefix=$_G_indent
-    done
-    IFS=$func_echo_infix_1_IFS
-}
-
-
-# func_error ARG...
-# -----------------
-# Echo program name prefixed message to standard error.
-func_error ()
-{
-    $debug_cmd
-
-    $require_term_colors
-
-    func_echo_infix_1 "  $tc_standout${tc_red}error$tc_reset" "$*" >&2
-}
-
-
-# func_fatal_error ARG...
-# -----------------------
-# Echo program name prefixed message to standard error, and exit.
-func_fatal_error ()
-{
-    $debug_cmd
-
-    func_error "$*"
-    exit $EXIT_FAILURE
-}
-
-
-# func_grep EXPRESSION FILENAME
-# -----------------------------
+# func_grep expression filename
 # Check whether EXPRESSION matches any line of FILENAME, without output.
 func_grep ()
 {
-    $debug_cmd
-
     $GREP "$1" "$2" >/dev/null 2>&1
 }
 
 
-# func_len STRING
-# ---------------
-# Set func_len_result to the length of STRING. STRING may not
-# start with a hyphen.
-  test -z "$_G_HAVE_XSI_OPS" \
-    && (eval 'x=a/b/c;
-      test 5aa/bb/cc = "${#x}${x%%/*}${x%/*}${x#*/}${x##*/}"') 2>/dev/null \
-    && _G_HAVE_XSI_OPS=yes
-
-if test yes = "$_G_HAVE_XSI_OPS"; then
-  eval 'func_len ()
-  {
-    $debug_cmd
-
-    func_len_result=${#1}
-  }'
-else
-  func_len ()
-  {
-    $debug_cmd
-
-    func_len_result=`expr "$1" : ".*" 2>/dev/null || echo $max_cmd_len`
-  }
-fi
-
-
-# func_mkdir_p DIRECTORY-PATH
-# ---------------------------
+# func_mkdir_p directory-path
 # Make sure the entire path to DIRECTORY-PATH is available.
 func_mkdir_p ()
 {
-    $debug_cmd
-
-    _G_directory_path=$1
-    _G_dir_list=
+    my_directory_path="$1"
+    my_dir_list=
 
-    if test -n "$_G_directory_path" && test : != "$opt_dry_run"; then
+    if test -n "$my_directory_path" && test "$opt_dry_run" != ":"; then
 
-      # Protect directory names starting with '-'
-      case $_G_directory_path in
-        -*) _G_directory_path=./$_G_directory_path ;;
+      # Protect directory names starting with `-'
+      case $my_directory_path in
+        -*) my_directory_path="./$my_directory_path" ;;
       esac
 
       # While some portion of DIR does not yet exist...
-      while test ! -d "$_G_directory_path"; do
+      while test ! -d "$my_directory_path"; do
         # ...make a list in topmost first order.  Use a colon delimited
 	# list incase some portion of path contains whitespace.
-        _G_dir_list=$_G_directory_path:$_G_dir_list
+        my_dir_list="$my_directory_path:$my_dir_list"
 
         # If the last portion added has no slash in it, the list is done
-        case $_G_directory_path in */*) ;; *) break ;; esac
+        case $my_directory_path in */*) ;; *) break ;; esac
 
         # ...otherwise throw away the child directory and loop
-        _G_directory_path=`$ECHO "$_G_directory_path" | $SED -e "$sed_dirname"`
+        my_directory_path=`$ECHO "$my_directory_path" | $SED -e "$dirname"`
       done
-      _G_dir_list=`$ECHO "$_G_dir_list" | $SED 's|:*$||'`
+      my_dir_list=`$ECHO "$my_dir_list" | $SED 's,:*$,,'`
 
-      func_mkdir_p_IFS=$IFS; IFS=:
-      for _G_dir in $_G_dir_list; do
-	IFS=$func_mkdir_p_IFS
-        # mkdir can fail with a 'File exist' error if two processes
+      save_mkdir_p_IFS="$IFS"; IFS=':'
+      for my_dir in $my_dir_list; do
+	IFS="$save_mkdir_p_IFS"
+        # mkdir can fail with a `File exist' error if two processes
         # try to create one of the directories concurrently.  Don't
         # stop in that case!
-        $MKDIR "$_G_dir" 2>/dev/null || :
+        $MKDIR "$my_dir" 2>/dev/null || :
       done
-      IFS=$func_mkdir_p_IFS
+      IFS="$save_mkdir_p_IFS"
 
       # Bail out if we (or some other process) failed to create a directory.
-      test -d "$_G_directory_path" || \
-        func_fatal_error "Failed to create '$1'"
+      test -d "$my_directory_path" || \
+        func_fatal_error "Failed to create \`$1'"
     fi
 }
 
 
-# func_mktempdir [BASENAME]
-# -------------------------
+# func_mktempdir [string]
 # Make a temporary directory that won't clash with other running
 # libtool processes, and avoids race conditions if possible.  If
-# given, BASENAME is the basename for that directory.
+# given, STRING is the basename for that directory.
 func_mktempdir ()
 {
-    $debug_cmd
+    my_template="${TMPDIR-/tmp}/${1-$progname}"
 
-    _G_template=${TMPDIR-/tmp}/${1-$progname}
-
-    if test : = "$opt_dry_run"; then
+    if test "$opt_dry_run" = ":"; then
       # Return a directory name, but don't create it in dry-run mode
-      _G_tmpdir=$_G_template-$$
+      my_tmpdir="${my_template}-$$"
     else
 
       # If mktemp works, use that first and foremost
-      _G_tmpdir=`mktemp -d "$_G_template-XXXXXXXX" 2>/dev/null`
+      my_tmpdir=`mktemp -d "${my_template}-XXXXXXXX" 2>/dev/null`
 
-      if test ! -d "$_G_tmpdir"; then
+      if test ! -d "$my_tmpdir"; then
         # Failing that, at least try and use $RANDOM to avoid a race
-        _G_tmpdir=$_G_template-${RANDOM-0}$$
+        my_tmpdir="${my_template}-${RANDOM-0}$$"
 
-        func_mktempdir_umask=`umask`
+        save_mktempdir_umask=`umask`
         umask 0077
-        $MKDIR "$_G_tmpdir"
-        umask $func_mktempdir_umask
+        $MKDIR "$my_tmpdir"
+        umask $save_mktempdir_umask
       fi
 
       # If we're not in dry-run mode, bomb out on failure
-      test -d "$_G_tmpdir" || \
-        func_fatal_error "cannot create temporary directory '$_G_tmpdir'"
-    fi
-
-    $ECHO "$_G_tmpdir"
-}
-
-
-# func_normal_abspath PATH
-# ------------------------
-# Remove doubled-up and trailing slashes, "." path components,
-# and cancel out any ".." path components in PATH after making
-# it an absolute path.
-func_normal_abspath ()
-{
-    $debug_cmd
-
-    # These SED scripts presuppose an absolute path with a trailing slash.
-    _G_pathcar='s|^/\([^/]*\).*$|\1|'
-    _G_pathcdr='s|^/[^/]*||'
-    _G_removedotparts=':dotsl
-		s|/\./|/|g
-		t dotsl
-		s|/\.$|/|'
-    _G_collapseslashes='s|/\{1,\}|/|g'
-    _G_finalslash='s|/*$|/|'
-
-    # Start from root dir and reassemble the path.
-    func_normal_abspath_result=
-    func_normal_abspath_tpath=$1
-    func_normal_abspath_altnamespace=
-    case $func_normal_abspath_tpath in
-      "")
-        # Empty path, that just means $cwd.
-        func_stripname '' '/' "`pwd`"
-        func_normal_abspath_result=$func_stripname_result
-        return
-        ;;
-      # The next three entries are used to spot a run of precisely
-      # two leading slashes without using negated character classes;
-      # we take advantage of case's first-match behaviour.
-      ///*)
-        # Unusual form of absolute path, do nothing.
-        ;;
-      //*)
-        # Not necessarily an ordinary path; POSIX reserves leading '//'
-        # and for example Cygwin uses it to access remote file shares
-        # over CIFS/SMB, so we conserve a leading double slash if found.
-        func_normal_abspath_altnamespace=/
-        ;;
-      /*)
-        # Absolute path, do nothing.
-        ;;
-      *)
-        # Relative path, prepend $cwd.
-        func_normal_abspath_tpath=`pwd`/$func_normal_abspath_tpath
-        ;;
-    esac
-
-    # Cancel out all the simple stuff to save iterations.  We also want
-    # the path to end with a slash for ease of parsing, so make sure
-    # there is one (and only one) here.
-    func_normal_abspath_tpath=`$ECHO "$func_normal_abspath_tpath" | $SED \
-          -e "$_G_removedotparts" -e "$_G_collapseslashes" -e "$_G_finalslash"`
-    while :; do
-      # Processed it all yet?
-      if test / = "$func_normal_abspath_tpath"; then
-        # If we ascended to the root using ".." the result may be empty now.
-        if test -z "$func_normal_abspath_result"; then
-          func_normal_abspath_result=/
-        fi
-        break
-      fi
-      func_normal_abspath_tcomponent=`$ECHO "$func_normal_abspath_tpath" | $SED \
-          -e "$_G_pathcar"`
-      func_normal_abspath_tpath=`$ECHO "$func_normal_abspath_tpath" | $SED \
-          -e "$_G_pathcdr"`
-      # Figure out what to do with it
-      case $func_normal_abspath_tcomponent in
-        "")
-          # Trailing empty path component, ignore it.
-          ;;
-        ..)
-          # Parent dir; strip last assembled component from result.
-          func_dirname "$func_normal_abspath_result"
-          func_normal_abspath_result=$func_dirname_result
-          ;;
-        *)
-          # Actual path component, append it.
-          func_append func_normal_abspath_result "/$func_normal_abspath_tcomponent"
-          ;;
-      esac
-    done
-    # Restore leading double-slash if one was found on entry.
-    func_normal_abspath_result=$func_normal_abspath_altnamespace$func_normal_abspath_result
-}
-
-
-# func_notquiet ARG...
-# --------------------
-# Echo program name prefixed message only when not in quiet mode.
-func_notquiet ()
-{
-    $debug_cmd
-
-    $opt_quiet || func_echo ${1+"$@"}
-
-    # A bug in bash halts the script if the last line of a function
-    # fails when set -e is in force, so we need another command to
-    # work around that:
-    :
-}
-
-
-# func_relative_path SRCDIR DSTDIR
-# --------------------------------
-# Set func_relative_path_result to the relative path from SRCDIR to DSTDIR.
-func_relative_path ()
-{
-    $debug_cmd
-
-    func_relative_path_result=
-    func_normal_abspath "$1"
-    func_relative_path_tlibdir=$func_normal_abspath_result
-    func_normal_abspath "$2"
-    func_relative_path_tbindir=$func_normal_abspath_result
-
-    # Ascend the tree starting from libdir
-    while :; do
-      # check if we have found a prefix of bindir
-      case $func_relative_path_tbindir in
-        $func_relative_path_tlibdir)
-          # found an exact match
-          func_relative_path_tcancelled=
-          break
-          ;;
-        $func_relative_path_tlibdir*)
-          # found a matching prefix
-          func_stripname "$func_relative_path_tlibdir" '' "$func_relative_path_tbindir"
-          func_relative_path_tcancelled=$func_stripname_result
-          if test -z "$func_relative_path_result"; then
-            func_relative_path_result=.
-          fi
-          break
-          ;;
-        *)
-          func_dirname $func_relative_path_tlibdir
-          func_relative_path_tlibdir=$func_dirname_result
-          if test -z "$func_relative_path_tlibdir"; then
-            # Have to descend all the way to the root!
-            func_relative_path_result=../$func_relative_path_result
-            func_relative_path_tcancelled=$func_relative_path_tbindir
-            break
-          fi
-          func_relative_path_result=../$func_relative_path_result
-          ;;
-      esac
-    done
-
-    # Now calculate path; take care to avoid doubling-up slashes.
-    func_stripname '' '/' "$func_relative_path_result"
-    func_relative_path_result=$func_stripname_result
-    func_stripname '/' '/' "$func_relative_path_tcancelled"
-    if test -n "$func_stripname_result"; then
-      func_append func_relative_path_result "/$func_stripname_result"
-    fi
-
-    # Normalisation. If bindir is libdir, return '.' else relative path.
-    if test -n "$func_relative_path_result"; then
-      func_stripname './' '' "$func_relative_path_result"
-      func_relative_path_result=$func_stripname_result
-    fi
-
-    test -n "$func_relative_path_result" || func_relative_path_result=.
-
-    :
-}
-
-
-# func_quote_for_eval ARG...
-# --------------------------
-# Aesthetically quote ARGs to be evaled later.
-# This function returns two values:
-#   i) func_quote_for_eval_result
-#      double-quoted, suitable for a subsequent eval
-#  ii) func_quote_for_eval_unquoted_result
-#      has all characters that are still active within double
-#      quotes backslashified.
-func_quote_for_eval ()
-{
-    $debug_cmd
-
-    func_quote_for_eval_unquoted_result=
-    func_quote_for_eval_result=
-    while test 0 -lt $#; do
-      case $1 in
-        *[\\\`\"\$]*)
-	  _G_unquoted_arg=`printf '%s\n' "$1" |$SED "$sed_quote_subst"` ;;
-        *)
-          _G_unquoted_arg=$1 ;;
-      esac
-      if test -n "$func_quote_for_eval_unquoted_result"; then
-	func_append func_quote_for_eval_unquoted_result " $_G_unquoted_arg"
-      else
-        func_append func_quote_for_eval_unquoted_result "$_G_unquoted_arg"
-      fi
-
-      case $_G_unquoted_arg in
-        # Double-quote args containing shell metacharacters to delay
-        # word splitting, command substitution and variable expansion
-        # for a subsequent eval.
-        # Many Bourne shells cannot handle close brackets correctly
-        # in scan sets, so we specify it separately.
-        *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \	]*|*]*|"")
-          _G_quoted_arg=\"$_G_unquoted_arg\"
-          ;;
-        *)
-          _G_quoted_arg=$_G_unquoted_arg
-	  ;;
-      esac
-
-      if test -n "$func_quote_for_eval_result"; then
-	func_append func_quote_for_eval_result " $_G_quoted_arg"
-      else
-        func_append func_quote_for_eval_result "$_G_quoted_arg"
-      fi
-      shift
-    done
-}
-
-
-# func_quote_for_expand ARG
-# -------------------------
-# Aesthetically quote ARG to be evaled later; same as above,
-# but do not quote variable references.
-func_quote_for_expand ()
-{
-    $debug_cmd
-
-    case $1 in
-      *[\\\`\"]*)
-	_G_arg=`$ECHO "$1" | $SED \
-	    -e "$sed_double_quote_subst" -e "$sed_double_backslash"` ;;
-      *)
-        _G_arg=$1 ;;
-    esac
-
-    case $_G_arg in
-      # Double-quote args containing shell metacharacters to delay
-      # word splitting and command substitution for a subsequent eval.
-      # Many Bourne shells cannot handle close brackets correctly
-      # in scan sets, so we specify it separately.
-      *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \	]*|*]*|"")
-        _G_arg=\"$_G_arg\"
-        ;;
-    esac
-
-    func_quote_for_expand_result=$_G_arg
-}
-
-
-# func_stripname PREFIX SUFFIX NAME
-# ---------------------------------
-# strip PREFIX and SUFFIX from NAME, and store in func_stripname_result.
-# PREFIX and SUFFIX must not contain globbing or regex special
-# characters, hashes, percent signs, but SUFFIX may contain a leading
-# dot (in which case that matches only a dot).
-if test yes = "$_G_HAVE_XSI_OPS"; then
-  eval 'func_stripname ()
-  {
-    $debug_cmd
-
-    # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are
-    # positional parameters, so assign one to ordinary variable first.
-    func_stripname_result=$3
-    func_stripname_result=${func_stripname_result#"$1"}
-    func_stripname_result=${func_stripname_result%"$2"}
-  }'
-else
-  func_stripname ()
-  {
-    $debug_cmd
-
-    case $2 in
-      .*) func_stripname_result=`$ECHO "$3" | $SED -e "s%^$1%%" -e "s%\\\\$2\$%%"`;;
-      *)  func_stripname_result=`$ECHO "$3" | $SED -e "s%^$1%%" -e "s%$2\$%%"`;;
-    esac
-  }
-fi
-
-
-# func_show_eval CMD [FAIL_EXP]
-# -----------------------------
-# Unless opt_quiet is true, then output CMD.  Then, if opt_dryrun is
-# not true, evaluate CMD.  If the evaluation of CMD fails, and FAIL_EXP
-# is given, then evaluate it.
-func_show_eval ()
-{
-    $debug_cmd
-
-    _G_cmd=$1
-    _G_fail_exp=${2-':'}
-
-    func_quote_for_expand "$_G_cmd"
-    eval "func_notquiet $func_quote_for_expand_result"
-
-    $opt_dry_run || {
-      eval "$_G_cmd"
-      _G_status=$?
-      if test 0 -ne "$_G_status"; then
-	eval "(exit $_G_status); $_G_fail_exp"
-      fi
-    }
-}
-
-
-# func_show_eval_locale CMD [FAIL_EXP]
-# ------------------------------------
-# Unless opt_quiet is true, then output CMD.  Then, if opt_dryrun is
-# not true, evaluate CMD.  If the evaluation of CMD fails, and FAIL_EXP
-# is given, then evaluate it.  Use the saved locale for evaluation.
-func_show_eval_locale ()
-{
-    $debug_cmd
-
-    _G_cmd=$1
-    _G_fail_exp=${2-':'}
-
-    $opt_quiet || {
-      func_quote_for_expand "$_G_cmd"
-      eval "func_echo $func_quote_for_expand_result"
-    }
-
-    $opt_dry_run || {
-      eval "$_G_user_locale
-	    $_G_cmd"
-      _G_status=$?
-      eval "$_G_safe_locale"
-      if test 0 -ne "$_G_status"; then
-	eval "(exit $_G_status); $_G_fail_exp"
-      fi
-    }
-}
-
-
-# func_tr_sh
-# ----------
-# Turn $1 into a string suitable for a shell variable name.
-# Result is stored in $func_tr_sh_result.  All characters
-# not in the set a-zA-Z0-9_ are replaced with '_'. Further,
-# if $1 begins with a digit, a '_' is prepended as well.
-func_tr_sh ()
-{
-    $debug_cmd
-
-    case $1 in
-    [0-9]* | *[!a-zA-Z0-9_]*)
-      func_tr_sh_result=`$ECHO "$1" | $SED -e 's/^\([0-9]\)/_\1/' -e 's/[^a-zA-Z0-9_]/_/g'`
-      ;;
-    * )
-      func_tr_sh_result=$1
-      ;;
-    esac
-}
-
-
-# func_verbose ARG...
-# -------------------
-# Echo program name prefixed message in verbose mode only.
-func_verbose ()
-{
-    $debug_cmd
-
-    $opt_verbose && func_echo "$*"
-
-    :
-}
-
-
-# func_warn_and_continue ARG...
-# -----------------------------
-# Echo program name prefixed warning message to standard error.
-func_warn_and_continue ()
-{
-    $debug_cmd
-
-    $require_term_colors
-
-    func_echo_infix_1 "${tc_red}warning$tc_reset" "$*" >&2
-}
-
-
-# func_warning CATEGORY ARG...
-# ----------------------------
-# Echo program name prefixed warning message to standard error. Warning
-# messages can be filtered according to CATEGORY, where this function
-# elides messages where CATEGORY is not listed in the global variable
-# 'opt_warning_types'.
-func_warning ()
-{
-    $debug_cmd
-
-    # CATEGORY must be in the warning_categories list!
-    case " $warning_categories " in
-      *" $1 "*) ;;
-      *) func_internal_error "invalid warning category '$1'" ;;
-    esac
-
-    _G_category=$1
-    shift
-
-    case " $opt_warning_types " in
-      *" $_G_category "*) $warning_func ${1+"$@"} ;;
-    esac
-}
-
-
-# func_sort_ver VER1 VER2
-# -----------------------
-# 'sort -V' is not generally available.
-# Note this deviates from the version comparison in automake
-# in that it treats 1.5 < 1.5.0, and treats 1.4.4a < 1.4-p3a
-# but this should suffice as we won't be specifying old
-# version formats or redundant trailing .0 in bootstrap.conf.
-# If we did want full compatibility then we should probably
-# use m4_version_compare from autoconf.
-func_sort_ver ()
-{
-    $debug_cmd
-
-    printf '%s\n%s\n' "$1" "$2" \
-      | sort -t. -k 1,1n -k 2,2n -k 3,3n -k 4,4n -k 5,5n -k 6,6n -k 7,7n -k 8,8n -k 9,9n
-}
-
-# func_lt_ver PREV CURR
-# ---------------------
-# Return true if PREV and CURR are in the correct order according to
-# func_sort_ver, otherwise false.  Use it like this:
-#
-#  func_lt_ver "$prev_ver" "$proposed_ver" || func_fatal_error "..."
-func_lt_ver ()
-{
-    $debug_cmd
-
-    test "x$1" = x`func_sort_ver "$1" "$2" | $SED 1q`
-}
-
-
-# Local variables:
-# mode: shell-script
-# sh-indentation: 2
-# eval: (add-hook 'before-save-hook 'time-stamp)
-# time-stamp-pattern: "10/scriptversion=%:y-%02m-%02d.%02H; # UTC"
-# time-stamp-time-zone: "UTC"
-# End:
-#! /bin/sh
-
-# Set a version string for this script.
-scriptversion=2014-01-07.03; # UTC
-
-# A portable, pluggable option parser for Bourne shell.
-# Written by Gary V. Vaughan, 2010
-
-# Copyright (C) 2010-2015 Free Software Foundation, Inc.
-# This is free software; see the source for copying conditions.  There is NO
-# warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-
-# You should have received a copy of the GNU General Public License
-# along with this program.  If not, see <http://www.gnu.org/licenses/>.
-
-# Please report bugs or propose patches to gary at gnu.org.
-
-
-## ------ ##
-## Usage. ##
-## ------ ##
-
-# This file is a library for parsing options in your shell scripts along
-# with assorted other useful supporting features that you can make use
-# of too.
-#
-# For the simplest scripts you might need only:
-#
-#   #!/bin/sh
-#   . relative/path/to/funclib.sh
-#   . relative/path/to/options-parser
-#   scriptversion=1.0
-#   func_options ${1+"$@"}
-#   eval set dummy "$func_options_result"; shift
-#   ...rest of your script...
-#
-# In order for the '--version' option to work, you will need to have a
-# suitably formatted comment like the one at the top of this file
-# starting with '# Written by ' and ending with '# warranty; '.
-#
-# For '-h' and '--help' to work, you will also need a one line
-# description of your script's purpose in a comment directly above the
-# '# Written by ' line, like the one at the top of this file.
-#
-# The default options also support '--debug', which will turn on shell
-# execution tracing (see the comment above debug_cmd below for another
-# use), and '--verbose' and the func_verbose function to allow your script
-# to display verbose messages only when your user has specified
-# '--verbose'.
-#
-# After sourcing this file, you can plug processing for additional
-# options by amending the variables from the 'Configuration' section
-# below, and following the instructions in the 'Option parsing'
-# section further down.
-
-## -------------- ##
-## Configuration. ##
-## -------------- ##
-
-# You should override these variables in your script after sourcing this
-# file so that they reflect the customisations you have added to the
-# option parser.
-
-# The usage line for option parsing errors and the start of '-h' and
-# '--help' output messages. You can embed shell variables for delayed
-# expansion at the time the message is displayed, but you will need to
-# quote other shell meta-characters carefully to prevent them being
-# expanded when the contents are evaled.
-usage='$progpath [OPTION]...'
-
-# Short help message in response to '-h' and '--help'.  Add to this or
-# override it after sourcing this library to reflect the full set of
-# options your script accepts.
-usage_message="\
-       --debug        enable verbose shell tracing
-   -W, --warnings=CATEGORY
-                      report the warnings falling in CATEGORY [all]
-   -v, --verbose      verbosely report processing
-       --version      print version information and exit
-   -h, --help         print short or long help message and exit
-"
-
-# Additional text appended to 'usage_message' in response to '--help'.
-long_help_message="
-Warning categories include:
-       'all'          show all warnings
-       'none'         turn off all the warnings
-       'error'        warnings are treated as fatal errors"
-
-# Help message printed before fatal option parsing errors.
-fatal_help="Try '\$progname --help' for more information."
-
-
-
-## ------------------------- ##
-## Hook function management. ##
-## ------------------------- ##
-
-# This section contains functions for adding, removing, and running hooks
-# to the main code.  A hook is just a named list of of function, that can
-# be run in order later on.
-
-# func_hookable FUNC_NAME
-# -----------------------
-# Declare that FUNC_NAME will run hooks added with
-# 'func_add_hook FUNC_NAME ...'.
-func_hookable ()
-{
-    $debug_cmd
-
-    func_append hookable_fns " $1"
-}
-
-
-# func_add_hook FUNC_NAME HOOK_FUNC
-# ---------------------------------
-# Request that FUNC_NAME call HOOK_FUNC before it returns.  FUNC_NAME must
-# first have been declared "hookable" by a call to 'func_hookable'.
-func_add_hook ()
-{
-    $debug_cmd
-
-    case " $hookable_fns " in
-      *" $1 "*) ;;
-      *) func_fatal_error "'$1' does not accept hook functions." ;;
-    esac
-
-    eval func_append ${1}_hooks '" $2"'
-}
-
-
-# func_remove_hook FUNC_NAME HOOK_FUNC
-# ------------------------------------
-# Remove HOOK_FUNC from the list of functions called by FUNC_NAME.
-func_remove_hook ()
-{
-    $debug_cmd
-
-    eval ${1}_hooks='`$ECHO "\$'$1'_hooks" |$SED "s| '$2'||"`'
-}
-
-
-# func_run_hooks FUNC_NAME [ARG]...
-# ---------------------------------
-# Run all hook functions registered to FUNC_NAME.
-# It is assumed that the list of hook functions contains nothing more
-# than a whitespace-delimited list of legal shell function names, and
-# no effort is wasted trying to catch shell meta-characters or preserve
-# whitespace.
-func_run_hooks ()
-{
-    $debug_cmd
-
-    case " $hookable_fns " in
-      *" $1 "*) ;;
-      *) func_fatal_error "'$1' does not support hook funcions.n" ;;
-    esac
-
-    eval _G_hook_fns=\$$1_hooks; shift
-
-    for _G_hook in $_G_hook_fns; do
-      eval $_G_hook '"$@"'
-
-      # store returned options list back into positional
-      # parameters for next 'cmd' execution.
-      eval _G_hook_result=\$${_G_hook}_result
-      eval set dummy "$_G_hook_result"; shift
-    done
-
-    func_quote_for_eval ${1+"$@"}
-    func_run_hooks_result=$func_quote_for_eval_result
-}
-
-
-
-## --------------- ##
-## Option parsing. ##
-## --------------- ##
-
-# In order to add your own option parsing hooks, you must accept the
-# full positional parameter list in your hook function, remove any
-# options that you action, and then pass back the remaining unprocessed
-# options in '<hooked_function_name>_result', escaped suitably for
-# 'eval'.  Like this:
-#
-#    my_options_prep ()
-#    {
-#        $debug_cmd
-#
-#        # Extend the existing usage message.
-#        usage_message=$usage_message'
-#      -s, --silent       don'\''t print informational messages
-#    '
-#
-#        func_quote_for_eval ${1+"$@"}
-#        my_options_prep_result=$func_quote_for_eval_result
-#    }
-#    func_add_hook func_options_prep my_options_prep
-#
-#
-#    my_silent_option ()
-#    {
-#        $debug_cmd
-#
-#        # Note that for efficiency, we parse as many options as we can
-#        # recognise in a loop before passing the remainder back to the
-#        # caller on the first unrecognised argument we encounter.
-#        while test $# -gt 0; do
-#          opt=$1; shift
-#          case $opt in
-#            --silent|-s) opt_silent=: ;;
-#            # Separate non-argument short options:
-#            -s*)         func_split_short_opt "$_G_opt"
-#                         set dummy "$func_split_short_opt_name" \
-#                             "-$func_split_short_opt_arg" ${1+"$@"}
-#                         shift
-#                         ;;
-#            *)            set dummy "$_G_opt" "$*"; shift; break ;;
-#          esac
-#        done
-#
-#        func_quote_for_eval ${1+"$@"}
-#        my_silent_option_result=$func_quote_for_eval_result
-#    }
-#    func_add_hook func_parse_options my_silent_option
-#
-#
-#    my_option_validation ()
-#    {
-#        $debug_cmd
-#
-#        $opt_silent && $opt_verbose && func_fatal_help "\
-#    '--silent' and '--verbose' options are mutually exclusive."
-#
-#        func_quote_for_eval ${1+"$@"}
-#        my_option_validation_result=$func_quote_for_eval_result
-#    }
-#    func_add_hook func_validate_options my_option_validation
-#
-# You'll alse need to manually amend $usage_message to reflect the extra
-# options you parse.  It's preferable to append if you can, so that
-# multiple option parsing hooks can be added safely.
-
-
-# func_options [ARG]...
-# ---------------------
-# All the functions called inside func_options are hookable. See the
-# individual implementations for details.
-func_hookable func_options
-func_options ()
-{
-    $debug_cmd
-
-    func_options_prep ${1+"$@"}
-    eval func_parse_options \
-        ${func_options_prep_result+"$func_options_prep_result"}
-    eval func_validate_options \
-        ${func_parse_options_result+"$func_parse_options_result"}
-
-    eval func_run_hooks func_options \
-        ${func_validate_options_result+"$func_validate_options_result"}
+      test -d "$my_tmpdir" || \
+        func_fatal_error "cannot create temporary directory \`$my_tmpdir'"
+    fi
 
-    # save modified positional parameters for caller
-    func_options_result=$func_run_hooks_result
+    $ECHO "$my_tmpdir"
 }
 
 
-# func_options_prep [ARG]...
-# --------------------------
-# All initialisations required before starting the option parse loop.
-# Note that when calling hook functions, we pass through the list of
-# positional parameters.  If a hook function modifies that list, and
-# needs to propogate that back to rest of this script, then the complete
-# modified list must be put in 'func_run_hooks_result' before
-# returning.
-func_hookable func_options_prep
-func_options_prep ()
+# func_quote_for_eval arg
+# Aesthetically quote ARG to be evaled later.
+# This function returns two values: FUNC_QUOTE_FOR_EVAL_RESULT
+# is double-quoted, suitable for a subsequent eval, whereas
+# FUNC_QUOTE_FOR_EVAL_UNQUOTED_RESULT has merely all characters
+# which are still active within double quotes backslashified.
+func_quote_for_eval ()
 {
-    $debug_cmd
-
-    # Option defaults:
-    opt_verbose=false
-    opt_warning_types=
-
-    func_run_hooks func_options_prep ${1+"$@"}
+    case $1 in
+      *[\\\`\"\$]*)
+	func_quote_for_eval_unquoted_result=`$ECHO "$1" | $SED "$sed_quote_subst"` ;;
+      *)
+        func_quote_for_eval_unquoted_result="$1" ;;
+    esac
 
-    # save modified positional parameters for caller
-    func_options_prep_result=$func_run_hooks_result
+    case $func_quote_for_eval_unquoted_result in
+      # Double-quote args containing shell metacharacters to delay
+      # word splitting, command substitution and and variable
+      # expansion for a subsequent eval.
+      # Many Bourne shells cannot handle close brackets correctly
+      # in scan sets, so we specify it separately.
+      *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \	]*|*]*|"")
+        func_quote_for_eval_result="\"$func_quote_for_eval_unquoted_result\""
+        ;;
+      *)
+        func_quote_for_eval_result="$func_quote_for_eval_unquoted_result"
+    esac
 }
 
 
-# func_parse_options [ARG]...
-# ---------------------------
-# The main option parsing loop.
-func_hookable func_parse_options
-func_parse_options ()
+# func_quote_for_expand arg
+# Aesthetically quote ARG to be evaled later; same as above,
+# but do not quote variable references.
+func_quote_for_expand ()
 {
-    $debug_cmd
-
-    func_parse_options_result=
+    case $1 in
+      *[\\\`\"]*)
+	my_arg=`$ECHO "$1" | $SED \
+	    -e "$double_quote_subst" -e "$sed_double_backslash"` ;;
+      *)
+        my_arg="$1" ;;
+    esac
 
-    # this just eases exit handling
-    while test $# -gt 0; do
-      # Defer to hook functions for initial option parsing, so they
-      # get priority in the event of reusing an option name.
-      func_run_hooks func_parse_options ${1+"$@"}
+    case $my_arg in
+      # Double-quote args containing shell metacharacters to delay
+      # word splitting and command substitution for a subsequent eval.
+      # Many Bourne shells cannot handle close brackets correctly
+      # in scan sets, so we specify it separately.
+      *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \	]*|*]*|"")
+        my_arg="\"$my_arg\""
+        ;;
+    esac
 
-      # Adjust func_parse_options positional parameters to match
-      eval set dummy "$func_run_hooks_result"; shift
+    func_quote_for_expand_result="$my_arg"
+}
 
-      # Break out of the loop if we already parsed every option.
-      test $# -gt 0 || break
 
-      _G_opt=$1
-      shift
-      case $_G_opt in
-        --debug|-x)   debug_cmd='set -x'
-                      func_echo "enabling shell trace mode"
-                      $debug_cmd
-                      ;;
-
-        --no-warnings|--no-warning|--no-warn)
-                      set dummy --warnings none ${1+"$@"}
-                      shift
-		      ;;
+# func_show_eval cmd [fail_exp]
+# Unless opt_silent is true, then output CMD.  Then, if opt_dryrun is
+# not true, evaluate CMD.  If the evaluation of CMD fails, and FAIL_EXP
+# is given, then evaluate it.
+func_show_eval ()
+{
+    my_cmd="$1"
+    my_fail_exp="${2-:}"
 
-        --warnings|--warning|-W)
-                      test $# = 0 && func_missing_arg $_G_opt && break
-                      case " $warning_categories $1" in
-                        *" $1 "*)
-                          # trailing space prevents matching last $1 above
-                          func_append_uniq opt_warning_types " $1"
-                          ;;
-                        *all)
-                          opt_warning_types=$warning_categories
-                          ;;
-                        *none)
-                          opt_warning_types=none
-                          warning_func=:
-                          ;;
-                        *error)
-                          opt_warning_types=$warning_categories
-                          warning_func=func_fatal_error
-                          ;;
-                        *)
-                          func_fatal_error \
-                             "unsupported warning category: '$1'"
-                          ;;
-                      esac
-                      shift
-                      ;;
-
-        --verbose|-v) opt_verbose=: ;;
-        --version)    func_version ;;
-        -\?|-h)       func_usage ;;
-        --help)       func_help ;;
-
-	# Separate optargs to long options (plugins may need this):
-	--*=*)        func_split_equals "$_G_opt"
-	              set dummy "$func_split_equals_lhs" \
-                          "$func_split_equals_rhs" ${1+"$@"}
-                      shift
-                      ;;
-
-       # Separate optargs to short options:
-        -W*)
-                      func_split_short_opt "$_G_opt"
-                      set dummy "$func_split_short_opt_name" \
-                          "$func_split_short_opt_arg" ${1+"$@"}
-                      shift
-                      ;;
-
-        # Separate non-argument short options:
-        -\?*|-h*|-v*|-x*)
-                      func_split_short_opt "$_G_opt"
-                      set dummy "$func_split_short_opt_name" \
-                          "-$func_split_short_opt_arg" ${1+"$@"}
-                      shift
-                      ;;
-
-        --)           break ;;
-        -*)           func_fatal_help "unrecognised option: '$_G_opt'" ;;
-        *)            set dummy "$_G_opt" ${1+"$@"}; shift; break ;;
-      esac
-    done
+    ${opt_silent-false} || {
+      func_quote_for_expand "$my_cmd"
+      eval "func_echo $func_quote_for_expand_result"
+    }
 
-    # save modified positional parameters for caller
-    func_quote_for_eval ${1+"$@"}
-    func_parse_options_result=$func_quote_for_eval_result
+    if ${opt_dry_run-false}; then :; else
+      eval "$my_cmd"
+      my_status=$?
+      if test "$my_status" -eq 0; then :; else
+	eval "(exit $my_status); $my_fail_exp"
+      fi
+    fi
 }
 
 
-# func_validate_options [ARG]...
-# ------------------------------
-# Perform any sanity checks on option settings and/or unconsumed
-# arguments.
-func_hookable func_validate_options
-func_validate_options ()
+# func_show_eval_locale cmd [fail_exp]
+# Unless opt_silent is true, then output CMD.  Then, if opt_dryrun is
+# not true, evaluate CMD.  If the evaluation of CMD fails, and FAIL_EXP
+# is given, then evaluate it.  Use the saved locale for evaluation.
+func_show_eval_locale ()
 {
-    $debug_cmd
-
-    # Display all warnings if -W was not given.
-    test -n "$opt_warning_types" || opt_warning_types=" $warning_categories"
+    my_cmd="$1"
+    my_fail_exp="${2-:}"
 
-    func_run_hooks func_validate_options ${1+"$@"}
-
-    # Bail if the options were screwed!
-    $exit_cmd $EXIT_FAILURE
+    ${opt_silent-false} || {
+      func_quote_for_expand "$my_cmd"
+      eval "func_echo $func_quote_for_expand_result"
+    }
 
-    # save modified positional parameters for caller
-    func_validate_options_result=$func_run_hooks_result
+    if ${opt_dry_run-false}; then :; else
+      eval "$lt_user_locale
+	    $my_cmd"
+      my_status=$?
+      eval "$lt_safe_locale"
+      if test "$my_status" -eq 0; then :; else
+	eval "(exit $my_status); $my_fail_exp"
+      fi
+    fi
 }
 
+# func_tr_sh
+# Turn $1 into a string suitable for a shell variable name.
+# Result is stored in $func_tr_sh_result.  All characters
+# not in the set a-zA-Z0-9_ are replaced with '_'. Further,
+# if $1 begins with a digit, a '_' is prepended as well.
+func_tr_sh ()
+{
+  case $1 in
+  [0-9]* | *[!a-zA-Z0-9_]*)
+    func_tr_sh_result=`$ECHO "$1" | $SED 's/^\([0-9]\)/_\1/; s/[^a-zA-Z0-9_]/_/g'`
+    ;;
+  * )
+    func_tr_sh_result=$1
+    ;;
+  esac
+}
 
 
-## ----------------- ##
-## Helper functions. ##
-## ----------------- ##
-
-# This section contains the helper functions used by the rest of the
-# hookable option parser framework in ascii-betical order.
+# func_version
+# Echo version message to standard output and exit.
+func_version ()
+{
+    $opt_debug
 
+    $SED -n '/(C)/!b go
+	:more
+	/\./!{
+	  N
+	  s/\n# / /
+	  b more
+	}
+	:go
+	/^# '$PROGRAM' (GNU /,/# warranty; / {
+        s/^# //
+	s/^# *$//
+        s/\((C)\)[ 0-9,-]*\( [1-9][0-9]*\)/\1\2/
+        p
+     }' < "$progpath"
+     exit $?
+}
 
-# func_fatal_help ARG...
-# ----------------------
-# Echo program name prefixed message to standard error, followed by
-# a help hint, and exit.
-func_fatal_help ()
+# func_usage
+# Echo short help message to standard output and exit.
+func_usage ()
 {
-    $debug_cmd
+    $opt_debug
 
-    eval \$ECHO \""Usage: $usage"\"
-    eval \$ECHO \""$fatal_help"\"
-    func_error ${1+"$@"}
-    exit $EXIT_FAILURE
+    $SED -n '/^# Usage:/,/^#  *.*--help/ {
+        s/^# //
+	s/^# *$//
+	s/\$progname/'$progname'/
+	p
+    }' < "$progpath"
+    echo
+    $ECHO "run \`$progname --help | more' for full usage"
+    exit $?
 }
 
-
-# func_help
-# ---------
-# Echo long help message to standard output and exit.
+# func_help [NOEXIT]
+# Echo long help message to standard output and exit,
+# unless 'noexit' is passed as argument.
 func_help ()
 {
-    $debug_cmd
-
-    func_usage_message
-    $ECHO "$long_help_message"
-    exit 0
+    $opt_debug
+
+    $SED -n '/^# Usage:/,/# Report bugs to/ {
+	:print
+        s/^# //
+	s/^# *$//
+	s*\$progname*'$progname'*
+	s*\$host*'"$host"'*
+	s*\$SHELL*'"$SHELL"'*
+	s*\$LTCC*'"$LTCC"'*
+	s*\$LTCFLAGS*'"$LTCFLAGS"'*
+	s*\$LD*'"$LD"'*
+	s/\$with_gnu_ld/'"$with_gnu_ld"'/
+	s/\$automake_version/'"`(${AUTOMAKE-automake} --version) 2>/dev/null |$SED 1q`"'/
+	s/\$autoconf_version/'"`(${AUTOCONF-autoconf} --version) 2>/dev/null |$SED 1q`"'/
+	p
+	d
+     }
+     /^# .* home page:/b print
+     /^# General help using/b print
+     ' < "$progpath"
+    ret=$?
+    if test -z "$1"; then
+      exit $ret
+    fi
 }
 
-
-# func_missing_arg ARGNAME
-# ------------------------
+# func_missing_arg argname
 # Echo program name prefixed message to standard error and set global
 # exit_cmd.
 func_missing_arg ()
 {
-    $debug_cmd
+    $opt_debug
 
-    func_error "Missing argument for '$1'."
+    func_error "missing argument for $1."
     exit_cmd=exit
 }
 
 
-# func_split_equals STRING
-# ------------------------
-# Set func_split_equals_lhs and func_split_equals_rhs shell variables after
-# splitting STRING at the '=' sign.
-test -z "$_G_HAVE_XSI_OPS" \
-    && (eval 'x=a/b/c;
-      test 5aa/bb/cc = "${#x}${x%%/*}${x%/*}${x#*/}${x##*/}"') 2>/dev/null \
-    && _G_HAVE_XSI_OPS=yes
-
-if test yes = "$_G_HAVE_XSI_OPS"
-then
-  # This is an XSI compatible shell, allowing a faster implementation...
-  eval 'func_split_equals ()
-  {
-      $debug_cmd
-
-      func_split_equals_lhs=${1%%=*}
-      func_split_equals_rhs=${1#*=}
-      test "x$func_split_equals_lhs" = "x$1" \
-        && func_split_equals_rhs=
-  }'
-else
-  # ...otherwise fall back to using expr, which is often a shell builtin.
-  func_split_equals ()
-  {
-      $debug_cmd
-
-      func_split_equals_lhs=`expr "x$1" : 'x\([^=]*\)'`
-      func_split_equals_rhs=
-      test "x$func_split_equals_lhs" = "x$1" \
-        || func_split_equals_rhs=`expr "x$1" : 'x[^=]*=\(.*\)$'`
-  }
-fi #func_split_equals
-
-
-# func_split_short_opt SHORTOPT
-# -----------------------------
+# func_split_short_opt shortopt
 # Set func_split_short_opt_name and func_split_short_opt_arg shell
 # variables after splitting SHORTOPT after the 2nd character.
-if test yes = "$_G_HAVE_XSI_OPS"
-then
-  # This is an XSI compatible shell, allowing a faster implementation...
-  eval 'func_split_short_opt ()
-  {
-      $debug_cmd
-
-      func_split_short_opt_arg=${1#??}
-      func_split_short_opt_name=${1%"$func_split_short_opt_arg"}
-  }'
-else
-  # ...otherwise fall back to using expr, which is often a shell builtin.
-  func_split_short_opt ()
-  {
-      $debug_cmd
-
-      func_split_short_opt_name=`expr "x$1" : 'x-\(.\)'`
-      func_split_short_opt_arg=`expr "x$1" : 'x-.\(.*\)$'`
-  }
-fi #func_split_short_opt
-
-
-# func_usage
-# ----------
-# Echo short help message to standard output and exit.
-func_usage ()
+func_split_short_opt ()
 {
-    $debug_cmd
+    my_sed_short_opt='1s/^\(..\).*$/\1/;q'
+    my_sed_short_rest='1s/^..\(.*\)$/\1/;q'
 
-    func_usage_message
-    $ECHO "Run '$progname --help |${PAGER-more}' for full usage"
-    exit 0
-}
+    func_split_short_opt_name=`$ECHO "$1" | $SED "$my_sed_short_opt"`
+    func_split_short_opt_arg=`$ECHO "$1" | $SED "$my_sed_short_rest"`
+} # func_split_short_opt may be replaced by extended shell implementation
 
 
-# func_usage_message
-# ------------------
-# Echo short help message to standard output.
-func_usage_message ()
+# func_split_long_opt longopt
+# Set func_split_long_opt_name and func_split_long_opt_arg shell
+# variables after splitting LONGOPT at the `=' sign.
+func_split_long_opt ()
 {
-    $debug_cmd
+    my_sed_long_opt='1s/^\(--[^=]*\)=.*/\1/;q'
+    my_sed_long_arg='1s/^--[^=]*=//'
 
-    eval \$ECHO \""Usage: $usage"\"
-    echo
-    $SED -n 's|^# ||
-        /^Written by/{
-          x;p;x
-        }
-	h
-	/^Written by/q' < "$progpath"
-    echo
-    eval \$ECHO \""$usage_message"\"
-}
+    func_split_long_opt_name=`$ECHO "$1" | $SED "$my_sed_long_opt"`
+    func_split_long_opt_arg=`$ECHO "$1" | $SED "$my_sed_long_arg"`
+} # func_split_long_opt may be replaced by extended shell implementation
 
+exit_cmd=:
 
-# func_version
-# ------------
-# Echo version message to standard output and exit.
-func_version ()
-{
-    $debug_cmd
 
-    printf '%s\n' "$progname $scriptversion"
-    $SED -n '
-        /(C)/!b go
-        :more
-        /\./!{
-          N
-          s|\n# | |
-          b more
-        }
-        :go
-        /^# Written by /,/# warranty; / {
-          s|^# ||
-          s|^# *$||
-          s|\((C)\)[ 0-9,-]*[ ,-]\([1-9][0-9]* \)|\1 \2|
-          p
-        }
-        /^# Written by / {
-          s|^# ||
-          p
-        }
-        /^warranty; /q' < "$progpath"
 
-    exit $?
-}
 
 
-# Local variables:
-# mode: shell-script
-# sh-indentation: 2
-# eval: (add-hook 'before-save-hook 'time-stamp)
-# time-stamp-pattern: "10/scriptversion=%:y-%02m-%02d.%02H; # UTC"
-# time-stamp-time-zone: "UTC"
-# End:
+magic="%%%MAGIC variable%%%"
+magic_exe="%%%MAGIC EXE variable%%%"
 
-# Set a version string.
-scriptversion='(GNU libtool) 2.4.6'
+# Global variables.
+nonopt=
+preserve_args=
+lo2o="s/\\.lo\$/.${objext}/"
+o2lo="s/\\.${objext}\$/.lo/"
+extracted_archives=
+extracted_serial=0
 
+# If this variable is set in any of the actions, the command in it
+# will be execed at the end.  This prevents here-documents from being
+# left over by shells.
+exec_cmd=
 
-# func_echo ARG...
-# ----------------
-# Libtool also displays the current mode in messages, so override
-# funclib.sh func_echo with this custom definition.
-func_echo ()
+# func_append var value
+# Append VALUE to the end of shell variable VAR.
+func_append ()
 {
-    $debug_cmd
-
-    _G_message=$*
-
-    func_echo_IFS=$IFS
-    IFS=$nl
-    for _G_line in $_G_message; do
-      IFS=$func_echo_IFS
-      $ECHO "$progname${opt_mode+: $opt_mode}: $_G_line"
-    done
-    IFS=$func_echo_IFS
-}
-
+    eval "${1}=\$${1}\${2}"
+} # func_append may be replaced by extended shell implementation
 
-# func_warning ARG...
-# -------------------
-# Libtool warnings are not categorized, so override funclib.sh
-# func_warning with this simpler definition.
-func_warning ()
+# func_append_quoted var value
+# Quote VALUE and append to the end of shell variable VAR, separated
+# by a space.
+func_append_quoted ()
 {
-    $debug_cmd
-
-    $warning_func ${1+"$@"}
-}
-
+    func_quote_for_eval "${2}"
+    eval "${1}=\$${1}\\ \$func_quote_for_eval_result"
+} # func_append_quoted may be replaced by extended shell implementation
 
-## ---------------- ##
-## Options parsing. ##
-## ---------------- ##
-
-# Hook in the functions to make sure our own options are parsed during
-# the option parsing loop.
-
-usage='$progpath [OPTION]... [MODE-ARG]...'
-
-# Short help message in response to '-h'.
-usage_message="Options:
-       --config             show all configuration variables
-       --debug              enable verbose shell tracing
-   -n, --dry-run            display commands without modifying any files
-       --features           display basic configuration information and exit
-       --mode=MODE          use operation mode MODE
-       --no-warnings        equivalent to '-Wnone'
-       --preserve-dup-deps  don't remove duplicate dependency libraries
-       --quiet, --silent    don't print informational messages
-       --tag=TAG            use configuration variables from tag TAG
-   -v, --verbose            print more informational messages than default
-       --version            print version information
-   -W, --warnings=CATEGORY  report the warnings falling in CATEGORY [all]
-   -h, --help, --help-all   print short, long, or detailed help message
-"
 
-# Additional text appended to 'usage_message' in response to '--help'.
-func_help ()
+# func_arith arithmetic-term...
+func_arith ()
 {
-    $debug_cmd
-
-    func_usage_message
-    $ECHO "$long_help_message
-
-MODE must be one of the following:
-
-       clean           remove files from the build directory
-       compile         compile a source file into a libtool object
-       execute         automatically set library path, then run a program
-       finish          complete the installation of libtool libraries
-       install         install libraries or executables
-       link            create a library or an executable
-       uninstall       remove libraries from an installed directory
-
-MODE-ARGS vary depending on the MODE.  When passed as first option,
-'--mode=MODE' may be abbreviated as 'MODE' or a unique abbreviation of that.
-Try '$progname --help --mode=MODE' for a more detailed description of MODE.
-
-When reporting a bug, please describe a test case to reproduce it and
-include the following information:
-
-       host-triplet:   $host
-       shell:          $SHELL
-       compiler:       $LTCC
-       compiler flags: $LTCFLAGS
-       linker:         $LD (gnu? $with_gnu_ld)
-       version:        $progname (GNU libtool) 2.4.6
-       automake:       `($AUTOMAKE --version) 2>/dev/null |$SED 1q`
-       autoconf:       `($AUTOCONF --version) 2>/dev/null |$SED 1q`
-
-Report bugs to <bug-libtool at gnu.org>.
-GNU libtool home page: <http://www.gnu.org/s/libtool/>.
-General help using GNU software: <http://www.gnu.org/gethelp/>."
-    exit 0
-}
+    func_arith_result=`expr "${@}"`
+} # func_arith may be replaced by extended shell implementation
 
 
-# func_lo2o OBJECT-NAME
-# ---------------------
-# Transform OBJECT-NAME from a '.lo' suffix to the platform specific
-# object suffix.
+# func_len string
+# STRING may not start with a hyphen.
+func_len ()
+{
+    func_len_result=`expr "${1}" : ".*" 2>/dev/null || echo $max_cmd_len`
+} # func_len may be replaced by extended shell implementation
 
-lo2o=s/\\.lo\$/.$objext/
-o2lo=s/\\.$objext\$/.lo/
 
-if test yes = "$_G_HAVE_XSI_OPS"; then
-  eval 'func_lo2o ()
-  {
-    case $1 in
-      *.lo) func_lo2o_result=${1%.lo}.$objext ;;
-      *   ) func_lo2o_result=$1               ;;
-    esac
-  }'
+# func_lo2o object
+func_lo2o ()
+{
+    func_lo2o_result=`$ECHO "${1}" | $SED "$lo2o"`
+} # func_lo2o may be replaced by extended shell implementation
 
-  # func_xform LIBOBJ-OR-SOURCE
-  # ---------------------------
-  # Transform LIBOBJ-OR-SOURCE from a '.o' or '.c' (or otherwise)
-  # suffix to a '.lo' libtool-object suffix.
-  eval 'func_xform ()
-  {
-    func_xform_result=${1%.*}.lo
-  }'
-else
-  # ...otherwise fall back to using sed.
-  func_lo2o ()
-  {
-    func_lo2o_result=`$ECHO "$1" | $SED "$lo2o"`
-  }
 
-  func_xform ()
-  {
-    func_xform_result=`$ECHO "$1" | $SED 's|\.[^.]*$|.lo|'`
-  }
-fi
+# func_xform libobj-or-source
+func_xform ()
+{
+    func_xform_result=`$ECHO "${1}" | $SED 's/\.[^.]*$/.lo/'`
+} # func_xform may be replaced by extended shell implementation
 
 
-# func_fatal_configuration ARG...
-# -------------------------------
+# func_fatal_configuration arg...
 # Echo program name prefixed message to standard error, followed by
 # a configuration failure hint, and exit.
 func_fatal_configuration ()
 {
-    func__fatal_error ${1+"$@"} \
-      "See the $PACKAGE documentation for more information." \
-      "Fatal configuration error."
+    func_error ${1+"$@"}
+    func_error "See the $PACKAGE documentation for more information."
+    func_fatal_error "Fatal configuration error."
 }
 
 
 # func_config
-# -----------
 # Display the configuration for all the tags in this script.
 func_config ()
 {
@@ -2149,19 +915,17 @@ func_config ()
     exit $?
 }
 
-
 # func_features
-# -------------
 # Display the features supported by this script.
 func_features ()
 {
     echo "host: $host"
-    if test yes = "$build_libtool_libs"; then
+    if test "$build_libtool_libs" = yes; then
       echo "enable shared libraries"
     else
       echo "disable shared libraries"
     fi
-    if test yes = "$build_old_libs"; then
+    if test "$build_old_libs" = yes; then
       echo "enable static libraries"
     else
       echo "disable static libraries"
@@ -2170,350 +934,314 @@ func_features ()
     exit $?
 }
 
-
-# func_enable_tag TAGNAME
-# -----------------------
+# func_enable_tag tagname
 # Verify that TAGNAME is valid, and either flag an error and exit, or
 # enable the TAGNAME tag.  We also add TAGNAME to the global $taglist
 # variable here.
 func_enable_tag ()
 {
-    # Global variable:
-    tagname=$1
+  # Global variable:
+  tagname="$1"
 
-    re_begincf="^# ### BEGIN LIBTOOL TAG CONFIG: $tagname\$"
-    re_endcf="^# ### END LIBTOOL TAG CONFIG: $tagname\$"
-    sed_extractcf=/$re_begincf/,/$re_endcf/p
+  re_begincf="^# ### BEGIN LIBTOOL TAG CONFIG: $tagname\$"
+  re_endcf="^# ### END LIBTOOL TAG CONFIG: $tagname\$"
+  sed_extractcf="/$re_begincf/,/$re_endcf/p"
 
-    # Validate tagname.
-    case $tagname in
-      *[!-_A-Za-z0-9,/]*)
-        func_fatal_error "invalid tag name: $tagname"
-        ;;
-    esac
+  # Validate tagname.
+  case $tagname in
+    *[!-_A-Za-z0-9,/]*)
+      func_fatal_error "invalid tag name: $tagname"
+      ;;
+  esac
 
-    # Don't test for the "default" C tag, as we know it's
-    # there but not specially marked.
-    case $tagname in
-        CC) ;;
+  # Don't test for the "default" C tag, as we know it's
+  # there but not specially marked.
+  case $tagname in
+    CC) ;;
     *)
-        if $GREP "$re_begincf" "$progpath" >/dev/null 2>&1; then
-	  taglist="$taglist $tagname"
-
-	  # Evaluate the configuration.  Be careful to quote the path
-	  # and the sed script, to avoid splitting on whitespace, but
-	  # also don't use non-portable quotes within backquotes within
-	  # quotes we have to do it in 2 steps:
-	  extractedcf=`$SED -n -e "$sed_extractcf" < "$progpath"`
-	  eval "$extractedcf"
-        else
-	  func_error "ignoring unknown tag $tagname"
-        fi
-        ;;
-    esac
+      if $GREP "$re_begincf" "$progpath" >/dev/null 2>&1; then
+	taglist="$taglist $tagname"
+
+	# Evaluate the configuration.  Be careful to quote the path
+	# and the sed script, to avoid splitting on whitespace, but
+	# also don't use non-portable quotes within backquotes within
+	# quotes we have to do it in 2 steps:
+	extractedcf=`$SED -n -e "$sed_extractcf" < "$progpath"`
+	eval "$extractedcf"
+      else
+	func_error "ignoring unknown tag $tagname"
+      fi
+      ;;
+  esac
 }
 
-
 # func_check_version_match
-# ------------------------
 # Ensure that we are using m4 macros, and libtool script from the same
 # release of libtool.
 func_check_version_match ()
 {
-    if test "$package_revision" != "$macro_revision"; then
-      if test "$VERSION" != "$macro_version"; then
-        if test -z "$macro_version"; then
-          cat >&2 <<_LT_EOF
+  if test "$package_revision" != "$macro_revision"; then
+    if test "$VERSION" != "$macro_version"; then
+      if test -z "$macro_version"; then
+        cat >&2 <<_LT_EOF
 $progname: Version mismatch error.  This is $PACKAGE $VERSION, but the
 $progname: definition of this LT_INIT comes from an older release.
 $progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION
 $progname: and run autoconf again.
 _LT_EOF
-        else
-          cat >&2 <<_LT_EOF
+      else
+        cat >&2 <<_LT_EOF
 $progname: Version mismatch error.  This is $PACKAGE $VERSION, but the
 $progname: definition of this LT_INIT comes from $PACKAGE $macro_version.
 $progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION
 $progname: and run autoconf again.
 _LT_EOF
-        fi
-      else
-        cat >&2 <<_LT_EOF
+      fi
+    else
+      cat >&2 <<_LT_EOF
 $progname: Version mismatch error.  This is $PACKAGE $VERSION, revision $package_revision,
 $progname: but the definition of this LT_INIT comes from revision $macro_revision.
 $progname: You should recreate aclocal.m4 with macros from revision $package_revision
 $progname: of $PACKAGE $VERSION and run autoconf again.
 _LT_EOF
-      fi
-
-      exit $EXIT_MISMATCH
     fi
-}
 
+    exit $EXIT_MISMATCH
+  fi
+}
 
-# libtool_options_prep [ARG]...
-# -----------------------------
-# Preparation for options parsed by libtool.
-libtool_options_prep ()
-{
-    $debug_mode
 
-    # Option defaults:
-    opt_config=false
-    opt_dlopen=
-    opt_dry_run=false
-    opt_help=false
-    opt_mode=
-    opt_preserve_dup_deps=false
-    opt_quiet=false
+# Shorthand for --mode=foo, only valid as the first argument
+case $1 in
+clean|clea|cle|cl)
+  shift; set dummy --mode clean ${1+"$@"}; shift
+  ;;
+compile|compil|compi|comp|com|co|c)
+  shift; set dummy --mode compile ${1+"$@"}; shift
+  ;;
+execute|execut|execu|exec|exe|ex|e)
+  shift; set dummy --mode execute ${1+"$@"}; shift
+  ;;
+finish|finis|fini|fin|fi|f)
+  shift; set dummy --mode finish ${1+"$@"}; shift
+  ;;
+install|instal|insta|inst|ins|in|i)
+  shift; set dummy --mode install ${1+"$@"}; shift
+  ;;
+link|lin|li|l)
+  shift; set dummy --mode link ${1+"$@"}; shift
+  ;;
+uninstall|uninstal|uninsta|uninst|unins|unin|uni|un|u)
+  shift; set dummy --mode uninstall ${1+"$@"}; shift
+  ;;
+esac
 
-    nonopt=
-    preserve_args=
 
-    # Shorthand for --mode=foo, only valid as the first argument
-    case $1 in
-    clean|clea|cle|cl)
-      shift; set dummy --mode clean ${1+"$@"}; shift
-      ;;
-    compile|compil|compi|comp|com|co|c)
-      shift; set dummy --mode compile ${1+"$@"}; shift
-      ;;
-    execute|execut|execu|exec|exe|ex|e)
-      shift; set dummy --mode execute ${1+"$@"}; shift
-      ;;
-    finish|finis|fini|fin|fi|f)
-      shift; set dummy --mode finish ${1+"$@"}; shift
-      ;;
-    install|instal|insta|inst|ins|in|i)
-      shift; set dummy --mode install ${1+"$@"}; shift
-      ;;
-    link|lin|li|l)
-      shift; set dummy --mode link ${1+"$@"}; shift
-      ;;
-    uninstall|uninstal|uninsta|uninst|unins|unin|uni|un|u)
-      shift; set dummy --mode uninstall ${1+"$@"}; shift
-      ;;
-    esac
 
-    # Pass back the list of options.
-    func_quote_for_eval ${1+"$@"}
-    libtool_options_prep_result=$func_quote_for_eval_result
-}
-func_add_hook func_options_prep libtool_options_prep
+# Option defaults:
+opt_debug=:
+opt_dry_run=false
+opt_config=false
+opt_preserve_dup_deps=false
+opt_features=false
+opt_finish=false
+opt_help=false
+opt_help_all=false
+opt_silent=:
+opt_warning=:
+opt_verbose=:
+opt_silent=false
+opt_verbose=false
 
 
-# libtool_parse_options [ARG]...
-# ---------------------------------
-# Provide handling for libtool specific options.
-libtool_parse_options ()
+# Parse options once, thoroughly.  This comes as soon as possible in the
+# script to make things like `--version' happen as quickly as we can.
 {
-    $debug_cmd
+  # this just eases exit handling
+  while test $# -gt 0; do
+    opt="$1"
+    shift
+    case $opt in
+      --debug|-x)	opt_debug='set -x'
+			func_echo "enabling shell trace mode"
+			$opt_debug
+			;;
+      --dry-run|--dryrun|-n)
+			opt_dry_run=:
+			;;
+      --config)
+			opt_config=:
+func_config
+			;;
+      --dlopen|-dlopen)
+			optarg="$1"
+			opt_dlopen="${opt_dlopen+$opt_dlopen
+}$optarg"
+			shift
+			;;
+      --preserve-dup-deps)
+			opt_preserve_dup_deps=:
+			;;
+      --features)
+			opt_features=:
+func_features
+			;;
+      --finish)
+			opt_finish=:
+set dummy --mode finish ${1+"$@"}; shift
+			;;
+      --help)
+			opt_help=:
+			;;
+      --help-all)
+			opt_help_all=:
+opt_help=': help-all'
+			;;
+      --mode)
+			test $# = 0 && func_missing_arg $opt && break
+			optarg="$1"
+			opt_mode="$optarg"
+case $optarg in
+  # Valid mode arguments:
+  clean|compile|execute|finish|install|link|relink|uninstall) ;;
+
+  # Catch anything else as an error
+  *) func_error "invalid argument for $opt"
+     exit_cmd=exit
+     break
+     ;;
+esac
+			shift
+			;;
+      --no-silent|--no-quiet)
+			opt_silent=false
+func_append preserve_args " $opt"
+			;;
+      --no-warning|--no-warn)
+			opt_warning=false
+func_append preserve_args " $opt"
+			;;
+      --no-verbose)
+			opt_verbose=false
+func_append preserve_args " $opt"
+			;;
+      --silent|--quiet)
+			opt_silent=:
+func_append preserve_args " $opt"
+        opt_verbose=false
+			;;
+      --verbose|-v)
+			opt_verbose=:
+func_append preserve_args " $opt"
+opt_silent=false
+			;;
+      --tag)
+			test $# = 0 && func_missing_arg $opt && break
+			optarg="$1"
+			opt_tag="$optarg"
+func_append preserve_args " $opt $optarg"
+func_enable_tag "$optarg"
+			shift
+			;;
+
+      -\?|-h)		func_usage				;;
+      --help)		func_help				;;
+      --version)	func_version				;;
+
+      # Separate optargs to long options:
+      --*=*)
+			func_split_long_opt "$opt"
+			set dummy "$func_split_long_opt_name" "$func_split_long_opt_arg" ${1+"$@"}
+			shift
+			;;
+
+      # Separate non-argument short options:
+      -\?*|-h*|-n*|-v*)
+			func_split_short_opt "$opt"
+			set dummy "$func_split_short_opt_name" "-$func_split_short_opt_arg" ${1+"$@"}
+			shift
+			;;
+
+      --)		break					;;
+      -*)		func_fatal_help "unrecognized option \`$opt'" ;;
+      *)		set dummy "$opt" ${1+"$@"};	shift; break  ;;
+    esac
+  done
 
-    # Perform our own loop to consume as many options as possible in
-    # each iteration.
-    while test $# -gt 0; do
-      _G_opt=$1
-      shift
-      case $_G_opt in
-        --dry-run|--dryrun|-n)
-                        opt_dry_run=:
-                        ;;
-
-        --config)       func_config ;;
-
-        --dlopen|-dlopen)
-                        opt_dlopen="${opt_dlopen+$opt_dlopen
-}$1"
-                        shift
-                        ;;
-
-        --preserve-dup-deps)
-                        opt_preserve_dup_deps=: ;;
-
-        --features)     func_features ;;
-
-        --finish)       set dummy --mode finish ${1+"$@"}; shift ;;
-
-        --help)         opt_help=: ;;
-
-        --help-all)     opt_help=': help-all' ;;
-
-        --mode)         test $# = 0 && func_missing_arg $_G_opt && break
-                        opt_mode=$1
-                        case $1 in
-                          # Valid mode arguments:
-                          clean|compile|execute|finish|install|link|relink|uninstall) ;;
-
-                          # Catch anything else as an error
-                          *) func_error "invalid argument for $_G_opt"
-                             exit_cmd=exit
-                             break
-                             ;;
-                        esac
-                        shift
-                        ;;
-
-        --no-silent|--no-quiet)
-                        opt_quiet=false
-                        func_append preserve_args " $_G_opt"
-                        ;;
-
-        --no-warnings|--no-warning|--no-warn)
-                        opt_warning=false
-                        func_append preserve_args " $_G_opt"
-                        ;;
-
-        --no-verbose)
-                        opt_verbose=false
-                        func_append preserve_args " $_G_opt"
-                        ;;
-
-        --silent|--quiet)
-                        opt_quiet=:
-                        opt_verbose=false
-                        func_append preserve_args " $_G_opt"
-                        ;;
-
-        --tag)          test $# = 0 && func_missing_arg $_G_opt && break
-                        opt_tag=$1
-                        func_append preserve_args " $_G_opt $1"
-                        func_enable_tag "$1"
-                        shift
-                        ;;
-
-        --verbose|-v)   opt_quiet=false
-                        opt_verbose=:
-                        func_append preserve_args " $_G_opt"
-                        ;;
-
-	# An option not handled by this hook function:
-        *)		set dummy "$_G_opt" ${1+"$@"};	shift; break  ;;
-      esac
-    done
+  # Validate options:
 
+  # save first non-option argument
+  if test "$#" -gt 0; then
+    nonopt="$opt"
+    shift
+  fi
 
-    # save modified positional parameters for caller
-    func_quote_for_eval ${1+"$@"}
-    libtool_parse_options_result=$func_quote_for_eval_result
-}
-func_add_hook func_parse_options libtool_parse_options
+  # preserve --debug
+  test "$opt_debug" = : || func_append preserve_args " --debug"
 
+  case $host in
+    *cygwin* | *mingw* | *pw32* | *cegcc*)
+      # don't eliminate duplications in $postdeps and $predeps
+      opt_duplicate_compiler_generated_deps=:
+      ;;
+    *)
+      opt_duplicate_compiler_generated_deps=$opt_preserve_dup_deps
+      ;;
+  esac
 
+  $opt_help || {
+    # Sanity checks first:
+    func_check_version_match
 
-# libtool_validate_options [ARG]...
-# ---------------------------------
-# Perform any sanity checks on option settings and/or unconsumed
-# arguments.
-libtool_validate_options ()
-{
-    # save first non-option argument
-    if test 0 -lt $#; then
-      nonopt=$1
-      shift
+    if test "$build_libtool_libs" != yes && test "$build_old_libs" != yes; then
+      func_fatal_configuration "not configured to build any kind of library"
     fi
 
-    # preserve --debug
-    test : = "$debug_cmd" || func_append preserve_args " --debug"
-
-    case $host in
-      # Solaris2 added to fix http://debbugs.gnu.org/cgi/bugreport.cgi?bug=16452
-      # see also: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=59788
-      *cygwin* | *mingw* | *pw32* | *cegcc* | *solaris2* | *os2*)
-        # don't eliminate duplications in $postdeps and $predeps
-        opt_duplicate_compiler_generated_deps=:
-        ;;
-      *)
-        opt_duplicate_compiler_generated_deps=$opt_preserve_dup_deps
-        ;;
-    esac
-
-    $opt_help || {
-      # Sanity checks first:
-      func_check_version_match
-
-      test yes != "$build_libtool_libs" \
-        && test yes != "$build_old_libs" \
-        && func_fatal_configuration "not configured to build any kind of library"
+    # Darwin sucks
+    eval std_shrext=\"$shrext_cmds\"
 
-      # Darwin sucks
-      eval std_shrext=\"$shrext_cmds\"
+    # Only execute mode is allowed to have -dlopen flags.
+    if test -n "$opt_dlopen" && test "$opt_mode" != execute; then
+      func_error "unrecognized option \`-dlopen'"
+      $ECHO "$help" 1>&2
+      exit $EXIT_FAILURE
+    fi
 
-      # Only execute mode is allowed to have -dlopen flags.
-      if test -n "$opt_dlopen" && test execute != "$opt_mode"; then
-        func_error "unrecognized option '-dlopen'"
-        $ECHO "$help" 1>&2
-        exit $EXIT_FAILURE
-      fi
+    # Change the help message to a mode-specific one.
+    generic_help="$help"
+    help="Try \`$progname --help --mode=$opt_mode' for more information."
+  }
 
-      # Change the help message to a mode-specific one.
-      generic_help=$help
-      help="Try '$progname --help --mode=$opt_mode' for more information."
-    }
 
-    # Pass back the unparsed argument list
-    func_quote_for_eval ${1+"$@"}
-    libtool_validate_options_result=$func_quote_for_eval_result
+  # Bail if the options were screwed
+  $exit_cmd $EXIT_FAILURE
 }
-func_add_hook func_validate_options libtool_validate_options
 
 
-# Process options as early as possible so that --help and --version
-# can return quickly.
-func_options ${1+"$@"}
-eval set dummy "$func_options_result"; shift
-
 
 
 ## ----------- ##
 ##    Main.    ##
 ## ----------- ##
 
-magic='%%%MAGIC variable%%%'
-magic_exe='%%%MAGIC EXE variable%%%'
-
-# Global variables.
-extracted_archives=
-extracted_serial=0
-
-# If this variable is set in any of the actions, the command in it
-# will be execed at the end.  This prevents here-documents from being
-# left over by shells.
-exec_cmd=
-
-
-# A function that is used when there is no print builtin or printf.
-func_fallback_echo ()
-{
-  eval 'cat <<_LTECHO_EOF
-$1
-_LTECHO_EOF'
-}
-
-# func_generated_by_libtool
-# True iff stdin has been generated by Libtool. This function is only
-# a basic sanity check; it will hardly flush out determined imposters.
-func_generated_by_libtool_p ()
-{
-  $GREP "^# Generated by .*$PACKAGE" > /dev/null 2>&1
-}
-
 # func_lalib_p file
-# True iff FILE is a libtool '.la' library or '.lo' object file.
+# True iff FILE is a libtool `.la' library or `.lo' object file.
 # This function is only a basic sanity check; it will hardly flush out
 # determined imposters.
 func_lalib_p ()
 {
     test -f "$1" &&
-      $SED -e 4q "$1" 2>/dev/null | func_generated_by_libtool_p
+      $SED -e 4q "$1" 2>/dev/null \
+        | $GREP "^# Generated by .*$PACKAGE" > /dev/null 2>&1
 }
 
 # func_lalib_unsafe_p file
-# True iff FILE is a libtool '.la' library or '.lo' object file.
+# True iff FILE is a libtool `.la' library or `.lo' object file.
 # This function implements the same check as func_lalib_p without
 # resorting to external programs.  To this end, it redirects stdin and
 # closes it afterwards, without saving the original file descriptor.
 # As a safety measure, use it only where a negative result would be
-# fatal anyway.  Works if 'file' does not exist.
+# fatal anyway.  Works if `file' does not exist.
 func_lalib_unsafe_p ()
 {
     lalib_p=no
@@ -2521,13 +1249,13 @@ func_lalib_unsafe_p ()
 	for lalib_p_l in 1 2 3 4
 	do
 	    read lalib_p_line
-	    case $lalib_p_line in
+	    case "$lalib_p_line" in
 		\#\ Generated\ by\ *$PACKAGE* ) lalib_p=yes; break;;
 	    esac
 	done
 	exec 0<&5 5<&-
     fi
-    test yes = "$lalib_p"
+    test "$lalib_p" = yes
 }
 
 # func_ltwrapper_script_p file
@@ -2536,8 +1264,7 @@ func_lalib_unsafe_p ()
 # determined imposters.
 func_ltwrapper_script_p ()
 {
-    test -f "$1" &&
-      $lt_truncate_bin < "$1" 2>/dev/null | func_generated_by_libtool_p
+    func_lalib_p "$1"
 }
 
 # func_ltwrapper_executable_p file
@@ -2562,7 +1289,7 @@ func_ltwrapper_scriptname ()
 {
     func_dirname_and_basename "$1" "" "."
     func_stripname '' '.exe' "$func_basename_result"
-    func_ltwrapper_scriptname_result=$func_dirname_result/$objdir/${func_stripname_result}_ltshwrapper
+    func_ltwrapper_scriptname_result="$func_dirname_result/$objdir/${func_stripname_result}_ltshwrapper"
 }
 
 # func_ltwrapper_p file
@@ -2581,13 +1308,11 @@ func_ltwrapper_p ()
 # FAIL_CMD may read-access the current command in variable CMD!
 func_execute_cmds ()
 {
-    $debug_cmd
-
+    $opt_debug
     save_ifs=$IFS; IFS='~'
     for cmd in $1; do
-      IFS=$sp$nl
-      eval cmd=\"$cmd\"
       IFS=$save_ifs
+      eval cmd=\"$cmd\"
       func_show_eval "$cmd" "${2-:}"
     done
     IFS=$save_ifs
@@ -2599,11 +1324,10 @@ func_execute_cmds ()
 # Note that it is not necessary on cygwin/mingw to append a dot to
 # FILE even if both FILE and FILE.exe exist: automatic-append-.exe
 # behavior happens only for exec(3), not for open(2)!  Also, sourcing
-# 'FILE.' does not work on cygwin managed mounts.
+# `FILE.' does not work on cygwin managed mounts.
 func_source ()
 {
-    $debug_cmd
-
+    $opt_debug
     case $1 in
     */* | *\\*)	. "$1" ;;
     *)		. "./$1" ;;
@@ -2630,10 +1354,10 @@ func_resolve_sysroot ()
 # store the result into func_replace_sysroot_result.
 func_replace_sysroot ()
 {
-  case $lt_sysroot:$1 in
+  case "$lt_sysroot:$1" in
   ?*:"$lt_sysroot"*)
     func_stripname "$lt_sysroot" '' "$1"
-    func_replace_sysroot_result='='$func_stripname_result
+    func_replace_sysroot_result="=$func_stripname_result"
     ;;
   *)
     # Including no sysroot.
@@ -2650,8 +1374,7 @@ func_replace_sysroot ()
 # arg is usually of the form 'gcc ...'
 func_infer_tag ()
 {
-    $debug_cmd
-
+    $opt_debug
     if test -n "$available_tags" && test -z "$tagname"; then
       CC_quoted=
       for arg in $CC; do
@@ -2670,7 +1393,7 @@ func_infer_tag ()
 	for z in $available_tags; do
 	  if $GREP "^# ### BEGIN LIBTOOL TAG CONFIG: $z$" < "$progpath" > /dev/null; then
 	    # Evaluate the configuration.
-	    eval "`$SED -n -e '/^# ### BEGIN LIBTOOL TAG CONFIG: '$z'$/,/^# ### END LIBTOOL TAG CONFIG: '$z'$/p' < $progpath`"
+	    eval "`${SED} -n -e '/^# ### BEGIN LIBTOOL TAG CONFIG: '$z'$/,/^# ### END LIBTOOL TAG CONFIG: '$z'$/p' < $progpath`"
 	    CC_quoted=
 	    for arg in $CC; do
 	      # Double-quote args containing other shell metacharacters.
@@ -2695,7 +1418,7 @@ func_infer_tag ()
 	# line option must be used.
 	if test -z "$tagname"; then
 	  func_echo "unable to infer tagged configuration"
-	  func_fatal_error "specify a tag with '--tag'"
+	  func_fatal_error "specify a tag with \`--tag'"
 #	else
 #	  func_verbose "using $tagname tagged configuration"
 	fi
@@ -2711,15 +1434,15 @@ func_infer_tag ()
 # but don't create it if we're doing a dry run.
 func_write_libtool_object ()
 {
-    write_libobj=$1
-    if test yes = "$build_libtool_libs"; then
-      write_lobj=\'$2\'
+    write_libobj=${1}
+    if test "$build_libtool_libs" = yes; then
+      write_lobj=\'${2}\'
     else
       write_lobj=none
     fi
 
-    if test yes = "$build_old_libs"; then
-      write_oldobj=\'$3\'
+    if test "$build_old_libs" = yes; then
+      write_oldobj=\'${3}\'
     else
       write_oldobj=none
     fi
@@ -2727,7 +1450,7 @@ func_write_libtool_object ()
     $opt_dry_run || {
       cat >${write_libobj}T <<EOF
 # $write_libobj - a libtool object file
-# Generated by $PROGRAM (GNU $PACKAGE) $VERSION
+# Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION
 #
 # Please DO NOT delete this file!
 # It is necessary for linking the library.
@@ -2739,7 +1462,7 @@ pic_object=$write_lobj
 non_pic_object=$write_oldobj
 
 EOF
-      $MV "${write_libobj}T" "$write_libobj"
+      $MV "${write_libobj}T" "${write_libobj}"
     }
 }
 
@@ -2759,9 +1482,8 @@ EOF
 # be empty on error (or when ARG is empty)
 func_convert_core_file_wine_to_w32 ()
 {
-  $debug_cmd
-
-  func_convert_core_file_wine_to_w32_result=$1
+  $opt_debug
+  func_convert_core_file_wine_to_w32_result="$1"
   if test -n "$1"; then
     # Unfortunately, winepath does not exit with a non-zero error code, so we
     # are forced to check the contents of stdout. On the other hand, if the
@@ -2769,9 +1491,9 @@ func_convert_core_file_wine_to_w32 ()
     # *an error message* to stdout. So we must check for both error code of
     # zero AND non-empty stdout, which explains the odd construction:
     func_convert_core_file_wine_to_w32_tmp=`winepath -w "$1" 2>/dev/null`
-    if test "$?" -eq 0 && test -n "$func_convert_core_file_wine_to_w32_tmp"; then
+    if test "$?" -eq 0 && test -n "${func_convert_core_file_wine_to_w32_tmp}"; then
       func_convert_core_file_wine_to_w32_result=`$ECHO "$func_convert_core_file_wine_to_w32_tmp" |
-        $SED -e "$sed_naive_backslashify"`
+        $SED -e "$lt_sed_naive_backslashify"`
     else
       func_convert_core_file_wine_to_w32_result=
     fi
@@ -2792,19 +1514,18 @@ func_convert_core_file_wine_to_w32 ()
 # are convertible, then the result may be empty.
 func_convert_core_path_wine_to_w32 ()
 {
-  $debug_cmd
-
+  $opt_debug
   # unfortunately, winepath doesn't convert paths, only file names
-  func_convert_core_path_wine_to_w32_result=
+  func_convert_core_path_wine_to_w32_result=""
   if test -n "$1"; then
     oldIFS=$IFS
     IFS=:
     for func_convert_core_path_wine_to_w32_f in $1; do
       IFS=$oldIFS
       func_convert_core_file_wine_to_w32 "$func_convert_core_path_wine_to_w32_f"
-      if test -n "$func_convert_core_file_wine_to_w32_result"; then
+      if test -n "$func_convert_core_file_wine_to_w32_result" ; then
         if test -z "$func_convert_core_path_wine_to_w32_result"; then
-          func_convert_core_path_wine_to_w32_result=$func_convert_core_file_wine_to_w32_result
+          func_convert_core_path_wine_to_w32_result="$func_convert_core_file_wine_to_w32_result"
         else
           func_append func_convert_core_path_wine_to_w32_result ";$func_convert_core_file_wine_to_w32_result"
         fi
@@ -2833,8 +1554,7 @@ func_convert_core_path_wine_to_w32 ()
 # environment variable; do not put it in $PATH.
 func_cygpath ()
 {
-  $debug_cmd
-
+  $opt_debug
   if test -n "$LT_CYGPATH" && test -f "$LT_CYGPATH"; then
     func_cygpath_result=`$LT_CYGPATH "$@" 2>/dev/null`
     if test "$?" -ne 0; then
@@ -2843,7 +1563,7 @@ func_cygpath ()
     fi
   else
     func_cygpath_result=
-    func_error "LT_CYGPATH is empty or specifies non-existent file: '$LT_CYGPATH'"
+    func_error "LT_CYGPATH is empty or specifies non-existent file: \`$LT_CYGPATH'"
   fi
 }
 #end: func_cygpath
@@ -2854,11 +1574,10 @@ func_cygpath ()
 # result in func_convert_core_msys_to_w32_result.
 func_convert_core_msys_to_w32 ()
 {
-  $debug_cmd
-
+  $opt_debug
   # awkward: cmd appends spaces to result
   func_convert_core_msys_to_w32_result=`( cmd //c echo "$1" ) 2>/dev/null |
-    $SED -e 's/[ ]*$//' -e "$sed_naive_backslashify"`
+    $SED -e 's/[ ]*$//' -e "$lt_sed_naive_backslashify"`
 }
 #end: func_convert_core_msys_to_w32
 
@@ -2869,14 +1588,13 @@ func_convert_core_msys_to_w32 ()
 # func_to_host_file_result to ARG1).
 func_convert_file_check ()
 {
-  $debug_cmd
-
-  if test -z "$2" && test -n "$1"; then
+  $opt_debug
+  if test -z "$2" && test -n "$1" ; then
     func_error "Could not determine host file name corresponding to"
-    func_error "  '$1'"
+    func_error "  \`$1'"
     func_error "Continuing, but uninstalled executables may not work."
     # Fallback:
-    func_to_host_file_result=$1
+    func_to_host_file_result="$1"
   fi
 }
 # end func_convert_file_check
@@ -2888,11 +1606,10 @@ func_convert_file_check ()
 # func_to_host_file_result to a simplistic fallback value (see below).
 func_convert_path_check ()
 {
-  $debug_cmd
-
+  $opt_debug
   if test -z "$4" && test -n "$3"; then
     func_error "Could not determine the host path corresponding to"
-    func_error "  '$3'"
+    func_error "  \`$3'"
     func_error "Continuing, but uninstalled executables may not work."
     # Fallback.  This is a deliberately simplistic "conversion" and
     # should not be "improved".  See libtool.info.
@@ -2901,7 +1618,7 @@ func_convert_path_check ()
       func_to_host_path_result=`echo "$3" |
         $SED -e "$lt_replace_pathsep_chars"`
     else
-      func_to_host_path_result=$3
+      func_to_host_path_result="$3"
     fi
   fi
 }
@@ -2913,10 +1630,9 @@ func_convert_path_check ()
 # and appending REPL if ORIG matches BACKPAT.
 func_convert_path_front_back_pathsep ()
 {
-  $debug_cmd
-
+  $opt_debug
   case $4 in
-  $1 ) func_to_host_path_result=$3$func_to_host_path_result
+  $1 ) func_to_host_path_result="$3$func_to_host_path_result"
     ;;
   esac
   case $4 in
@@ -2930,7 +1646,7 @@ func_convert_path_front_back_pathsep ()
 ##################################################
 # $build to $host FILE NAME CONVERSION FUNCTIONS #
 ##################################################
-# invoked via '$to_host_file_cmd ARG'
+# invoked via `$to_host_file_cmd ARG'
 #
 # In each case, ARG is the path to be converted from $build to $host format.
 # Result will be available in $func_to_host_file_result.
@@ -2941,8 +1657,7 @@ func_convert_path_front_back_pathsep ()
 # in func_to_host_file_result.
 func_to_host_file ()
 {
-  $debug_cmd
-
+  $opt_debug
   $to_host_file_cmd "$1"
 }
 # end func_to_host_file
@@ -2954,8 +1669,7 @@ func_to_host_file ()
 # in (the comma separated) LAZY, no conversion takes place.
 func_to_tool_file ()
 {
-  $debug_cmd
-
+  $opt_debug
   case ,$2, in
     *,"$to_tool_file_cmd",*)
       func_to_tool_file_result=$1
@@ -2973,7 +1687,7 @@ func_to_tool_file ()
 # Copy ARG to func_to_host_file_result.
 func_convert_file_noop ()
 {
-  func_to_host_file_result=$1
+  func_to_host_file_result="$1"
 }
 # end func_convert_file_noop
 
@@ -2984,12 +1698,11 @@ func_convert_file_noop ()
 # func_to_host_file_result.
 func_convert_file_msys_to_w32 ()
 {
-  $debug_cmd
-
-  func_to_host_file_result=$1
+  $opt_debug
+  func_to_host_file_result="$1"
   if test -n "$1"; then
     func_convert_core_msys_to_w32 "$1"
-    func_to_host_file_result=$func_convert_core_msys_to_w32_result
+    func_to_host_file_result="$func_convert_core_msys_to_w32_result"
   fi
   func_convert_file_check "$1" "$func_to_host_file_result"
 }
@@ -3001,9 +1714,8 @@ func_convert_file_msys_to_w32 ()
 # func_to_host_file_result.
 func_convert_file_cygwin_to_w32 ()
 {
-  $debug_cmd
-
-  func_to_host_file_result=$1
+  $opt_debug
+  func_to_host_file_result="$1"
   if test -n "$1"; then
     # because $build is cygwin, we call "the" cygpath in $PATH; no need to use
     # LT_CYGPATH in this case.
@@ -3019,12 +1731,11 @@ func_convert_file_cygwin_to_w32 ()
 # and a working winepath. Returns result in func_to_host_file_result.
 func_convert_file_nix_to_w32 ()
 {
-  $debug_cmd
-
-  func_to_host_file_result=$1
+  $opt_debug
+  func_to_host_file_result="$1"
   if test -n "$1"; then
     func_convert_core_file_wine_to_w32 "$1"
-    func_to_host_file_result=$func_convert_core_file_wine_to_w32_result
+    func_to_host_file_result="$func_convert_core_file_wine_to_w32_result"
   fi
   func_convert_file_check "$1" "$func_to_host_file_result"
 }
@@ -3036,13 +1747,12 @@ func_convert_file_nix_to_w32 ()
 # Returns result in func_to_host_file_result.
 func_convert_file_msys_to_cygwin ()
 {
-  $debug_cmd
-
-  func_to_host_file_result=$1
+  $opt_debug
+  func_to_host_file_result="$1"
   if test -n "$1"; then
     func_convert_core_msys_to_w32 "$1"
     func_cygpath -u "$func_convert_core_msys_to_w32_result"
-    func_to_host_file_result=$func_cygpath_result
+    func_to_host_file_result="$func_cygpath_result"
   fi
   func_convert_file_check "$1" "$func_to_host_file_result"
 }
@@ -3055,14 +1765,13 @@ func_convert_file_msys_to_cygwin ()
 # in func_to_host_file_result.
 func_convert_file_nix_to_cygwin ()
 {
-  $debug_cmd
-
-  func_to_host_file_result=$1
+  $opt_debug
+  func_to_host_file_result="$1"
   if test -n "$1"; then
     # convert from *nix to w32, then use cygpath to convert from w32 to cygwin.
     func_convert_core_file_wine_to_w32 "$1"
     func_cygpath -u "$func_convert_core_file_wine_to_w32_result"
-    func_to_host_file_result=$func_cygpath_result
+    func_to_host_file_result="$func_cygpath_result"
   fi
   func_convert_file_check "$1" "$func_to_host_file_result"
 }
@@ -3072,7 +1781,7 @@ func_convert_file_nix_to_cygwin ()
 #############################################
 # $build to $host PATH CONVERSION FUNCTIONS #
 #############################################
-# invoked via '$to_host_path_cmd ARG'
+# invoked via `$to_host_path_cmd ARG'
 #
 # In each case, ARG is the path to be converted from $build to $host format.
 # The result will be available in $func_to_host_path_result.
@@ -3096,11 +1805,10 @@ func_convert_file_nix_to_cygwin ()
 to_host_path_cmd=
 func_init_to_host_path_cmd ()
 {
-  $debug_cmd
-
+  $opt_debug
   if test -z "$to_host_path_cmd"; then
     func_stripname 'func_convert_file_' '' "$to_host_file_cmd"
-    to_host_path_cmd=func_convert_path_$func_stripname_result
+    to_host_path_cmd="func_convert_path_${func_stripname_result}"
   fi
 }
 
@@ -3110,8 +1818,7 @@ func_init_to_host_path_cmd ()
 # in func_to_host_path_result.
 func_to_host_path ()
 {
-  $debug_cmd
-
+  $opt_debug
   func_init_to_host_path_cmd
   $to_host_path_cmd "$1"
 }
@@ -3122,7 +1829,7 @@ func_to_host_path ()
 # Copy ARG to func_to_host_path_result.
 func_convert_path_noop ()
 {
-  func_to_host_path_result=$1
+  func_to_host_path_result="$1"
 }
 # end func_convert_path_noop
 
@@ -3133,9 +1840,8 @@ func_convert_path_noop ()
 # func_to_host_path_result.
 func_convert_path_msys_to_w32 ()
 {
-  $debug_cmd
-
-  func_to_host_path_result=$1
+  $opt_debug
+  func_to_host_path_result="$1"
   if test -n "$1"; then
     # Remove leading and trailing path separator characters from ARG.  MSYS
     # behavior is inconsistent here; cygpath turns them into '.;' and ';.';
@@ -3143,7 +1849,7 @@ func_convert_path_msys_to_w32 ()
     func_stripname : : "$1"
     func_to_host_path_tmp1=$func_stripname_result
     func_convert_core_msys_to_w32 "$func_to_host_path_tmp1"
-    func_to_host_path_result=$func_convert_core_msys_to_w32_result
+    func_to_host_path_result="$func_convert_core_msys_to_w32_result"
     func_convert_path_check : ";" \
       "$func_to_host_path_tmp1" "$func_to_host_path_result"
     func_convert_path_front_back_pathsep ":*" "*:" ";" "$1"
@@ -3157,9 +1863,8 @@ func_convert_path_msys_to_w32 ()
 # func_to_host_file_result.
 func_convert_path_cygwin_to_w32 ()
 {
-  $debug_cmd
-
-  func_to_host_path_result=$1
+  $opt_debug
+  func_to_host_path_result="$1"
   if test -n "$1"; then
     # See func_convert_path_msys_to_w32:
     func_stripname : : "$1"
@@ -3178,15 +1883,14 @@ func_convert_path_cygwin_to_w32 ()
 # a working winepath.  Returns result in func_to_host_file_result.
 func_convert_path_nix_to_w32 ()
 {
-  $debug_cmd
-
-  func_to_host_path_result=$1
+  $opt_debug
+  func_to_host_path_result="$1"
   if test -n "$1"; then
     # See func_convert_path_msys_to_w32:
     func_stripname : : "$1"
     func_to_host_path_tmp1=$func_stripname_result
     func_convert_core_path_wine_to_w32 "$func_to_host_path_tmp1"
-    func_to_host_path_result=$func_convert_core_path_wine_to_w32_result
+    func_to_host_path_result="$func_convert_core_path_wine_to_w32_result"
     func_convert_path_check : ";" \
       "$func_to_host_path_tmp1" "$func_to_host_path_result"
     func_convert_path_front_back_pathsep ":*" "*:" ";" "$1"
@@ -3200,16 +1904,15 @@ func_convert_path_nix_to_w32 ()
 # Returns result in func_to_host_file_result.
 func_convert_path_msys_to_cygwin ()
 {
-  $debug_cmd
-
-  func_to_host_path_result=$1
+  $opt_debug
+  func_to_host_path_result="$1"
   if test -n "$1"; then
     # See func_convert_path_msys_to_w32:
     func_stripname : : "$1"
     func_to_host_path_tmp1=$func_stripname_result
     func_convert_core_msys_to_w32 "$func_to_host_path_tmp1"
     func_cygpath -u -p "$func_convert_core_msys_to_w32_result"
-    func_to_host_path_result=$func_cygpath_result
+    func_to_host_path_result="$func_cygpath_result"
     func_convert_path_check : : \
       "$func_to_host_path_tmp1" "$func_to_host_path_result"
     func_convert_path_front_back_pathsep ":*" "*:" : "$1"
@@ -3224,9 +1927,8 @@ func_convert_path_msys_to_cygwin ()
 # func_to_host_file_result.
 func_convert_path_nix_to_cygwin ()
 {
-  $debug_cmd
-
-  func_to_host_path_result=$1
+  $opt_debug
+  func_to_host_path_result="$1"
   if test -n "$1"; then
     # Remove leading and trailing path separator characters from
     # ARG. msys behavior is inconsistent here, cygpath turns them
@@ -3235,7 +1937,7 @@ func_convert_path_nix_to_cygwin ()
     func_to_host_path_tmp1=$func_stripname_result
     func_convert_core_path_wine_to_w32 "$func_to_host_path_tmp1"
     func_cygpath -u -p "$func_convert_core_path_wine_to_w32_result"
-    func_to_host_path_result=$func_cygpath_result
+    func_to_host_path_result="$func_cygpath_result"
     func_convert_path_check : : \
       "$func_to_host_path_tmp1" "$func_to_host_path_result"
     func_convert_path_front_back_pathsep ":*" "*:" : "$1"
@@ -3244,31 +1946,13 @@ func_convert_path_nix_to_cygwin ()
 # end func_convert_path_nix_to_cygwin
 
 
-# func_dll_def_p FILE
-# True iff FILE is a Windows DLL '.def' file.
-# Keep in sync with _LT_DLL_DEF_P in libtool.m4
-func_dll_def_p ()
-{
-  $debug_cmd
-
-  func_dll_def_p_tmp=`$SED -n \
-    -e 's/^[	 ]*//' \
-    -e '/^\(;.*\)*$/d' \
-    -e 's/^\(EXPORTS\|LIBRARY\)\([	 ].*\)*$/DEF/p' \
-    -e q \
-    "$1"`
-  test DEF = "$func_dll_def_p_tmp"
-}
-
-
 # func_mode_compile arg...
 func_mode_compile ()
 {
-    $debug_cmd
-
+    $opt_debug
     # Get the compilation command and the source file.
     base_compile=
-    srcfile=$nonopt  #  always keep a non-empty value in "srcfile"
+    srcfile="$nonopt"  #  always keep a non-empty value in "srcfile"
     suppress_opt=yes
     suppress_output=
     arg_mode=normal
@@ -3281,12 +1965,12 @@ func_mode_compile ()
       case $arg_mode in
       arg  )
 	# do not "continue".  Instead, add this to base_compile
-	lastarg=$arg
+	lastarg="$arg"
 	arg_mode=normal
 	;;
 
       target )
-	libobj=$arg
+	libobj="$arg"
 	arg_mode=normal
 	continue
 	;;
@@ -3296,7 +1980,7 @@ func_mode_compile ()
 	case $arg in
 	-o)
 	  test -n "$libobj" && \
-	    func_fatal_error "you cannot specify '-o' more than once"
+	    func_fatal_error "you cannot specify \`-o' more than once"
 	  arg_mode=target
 	  continue
 	  ;;
@@ -3325,12 +2009,12 @@ func_mode_compile ()
 	  func_stripname '-Wc,' '' "$arg"
 	  args=$func_stripname_result
 	  lastarg=
-	  save_ifs=$IFS; IFS=,
+	  save_ifs="$IFS"; IFS=','
 	  for arg in $args; do
-	    IFS=$save_ifs
+	    IFS="$save_ifs"
 	    func_append_quoted lastarg "$arg"
 	  done
-	  IFS=$save_ifs
+	  IFS="$save_ifs"
 	  func_stripname ' ' '' "$lastarg"
 	  lastarg=$func_stripname_result
 
@@ -3343,8 +2027,8 @@ func_mode_compile ()
 	  # Accept the current argument as the source file.
 	  # The previous "srcfile" becomes the current argument.
 	  #
-	  lastarg=$srcfile
-	  srcfile=$arg
+	  lastarg="$srcfile"
+	  srcfile="$arg"
 	  ;;
 	esac  #  case $arg
 	;;
@@ -3359,13 +2043,13 @@ func_mode_compile ()
       func_fatal_error "you must specify an argument for -Xcompile"
       ;;
     target)
-      func_fatal_error "you must specify a target with '-o'"
+      func_fatal_error "you must specify a target with \`-o'"
       ;;
     *)
       # Get the name of the library object.
       test -z "$libobj" && {
 	func_basename "$srcfile"
-	libobj=$func_basename_result
+	libobj="$func_basename_result"
       }
       ;;
     esac
@@ -3385,7 +2069,7 @@ func_mode_compile ()
     case $libobj in
     *.lo) func_lo2o "$libobj"; obj=$func_lo2o_result ;;
     *)
-      func_fatal_error "cannot determine name of library object from '$libobj'"
+      func_fatal_error "cannot determine name of library object from \`$libobj'"
       ;;
     esac
 
@@ -3394,8 +2078,8 @@ func_mode_compile ()
     for arg in $later; do
       case $arg in
       -shared)
-	test yes = "$build_libtool_libs" \
-	  || func_fatal_configuration "cannot build a shared library"
+	test "$build_libtool_libs" != yes && \
+	  func_fatal_configuration "can not build a shared library"
 	build_old_libs=no
 	continue
 	;;
@@ -3421,17 +2105,17 @@ func_mode_compile ()
     func_quote_for_eval "$libobj"
     test "X$libobj" != "X$func_quote_for_eval_result" \
       && $ECHO "X$libobj" | $GREP '[]~#^*{};<>?"'"'"'	 &()|`$[]' \
-      && func_warning "libobj name '$libobj' may not contain shell special characters."
+      && func_warning "libobj name \`$libobj' may not contain shell special characters."
     func_dirname_and_basename "$obj" "/" ""
-    objname=$func_basename_result
-    xdir=$func_dirname_result
-    lobj=$xdir$objdir/$objname
+    objname="$func_basename_result"
+    xdir="$func_dirname_result"
+    lobj=${xdir}$objdir/$objname
 
     test -z "$base_compile" && \
       func_fatal_help "you must specify a compilation command"
 
     # Delete any leftover library objects.
-    if test yes = "$build_old_libs"; then
+    if test "$build_old_libs" = yes; then
       removelist="$obj $lobj $libobj ${libobj}T"
     else
       removelist="$lobj $libobj ${libobj}T"
@@ -3443,16 +2127,16 @@ func_mode_compile ()
       pic_mode=default
       ;;
     esac
-    if test no = "$pic_mode" && test pass_all != "$deplibs_check_method"; then
+    if test "$pic_mode" = no && test "$deplibs_check_method" != pass_all; then
       # non-PIC code in shared libraries is not supported
       pic_mode=default
     fi
 
     # Calculate the filename of the output object if compiler does
     # not support -o with -c
-    if test no = "$compiler_c_o"; then
-      output_obj=`$ECHO "$srcfile" | $SED 's%^.*/%%; s%\.[^.]*$%%'`.$objext
-      lockfile=$output_obj.lock
+    if test "$compiler_c_o" = no; then
+      output_obj=`$ECHO "$srcfile" | $SED 's%^.*/%%; s%\.[^.]*$%%'`.${objext}
+      lockfile="$output_obj.lock"
     else
       output_obj=
       need_locks=no
@@ -3461,12 +2145,12 @@ func_mode_compile ()
 
     # Lock this critical section if it is needed
     # We use this script file to make the link, it avoids creating a new file
-    if test yes = "$need_locks"; then
+    if test "$need_locks" = yes; then
       until $opt_dry_run || ln "$progpath" "$lockfile" 2>/dev/null; do
 	func_echo "Waiting for $lockfile to be removed"
 	sleep 2
       done
-    elif test warn = "$need_locks"; then
+    elif test "$need_locks" = warn; then
       if test -f "$lockfile"; then
 	$ECHO "\
 *** ERROR, $lockfile exists and contains:
@@ -3474,7 +2158,7 @@ func_mode_compile ()
 
 This indicates that another process is trying to use the same
 temporary object file, and libtool could not work around it because
-your compiler does not support '-c' and '-o' together.  If you
+your compiler does not support \`-c' and \`-o' together.  If you
 repeat this compilation, it may succeed, by chance, but you had better
 avoid parallel builds (make -j) in this platform, or get a better
 compiler."
@@ -3496,11 +2180,11 @@ compiler."
     qsrcfile=$func_quote_for_eval_result
 
     # Only build a PIC object if we are building libtool libraries.
-    if test yes = "$build_libtool_libs"; then
+    if test "$build_libtool_libs" = yes; then
       # Without this assignment, base_compile gets emptied.
       fbsd_hideous_sh_bug=$base_compile
 
-      if test no != "$pic_mode"; then
+      if test "$pic_mode" != no; then
 	command="$base_compile $qsrcfile $pic_flag"
       else
 	# Don't build PIC code
@@ -3517,7 +2201,7 @@ compiler."
       func_show_eval_locale "$command"	\
           'test -n "$output_obj" && $RM $removelist; exit $EXIT_FAILURE'
 
-      if test warn = "$need_locks" &&
+      if test "$need_locks" = warn &&
 	 test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then
 	$ECHO "\
 *** ERROR, $lockfile contains:
@@ -3528,7 +2212,7 @@ $srcfile
 
 This indicates that another process is trying to use the same
 temporary object file, and libtool could not work around it because
-your compiler does not support '-c' and '-o' together.  If you
+your compiler does not support \`-c' and \`-o' together.  If you
 repeat this compilation, it may succeed, by chance, but you had better
 avoid parallel builds (make -j) in this platform, or get a better
 compiler."
@@ -3544,20 +2228,20 @@ compiler."
       fi
 
       # Allow error messages only from the first compilation.
-      if test yes = "$suppress_opt"; then
+      if test "$suppress_opt" = yes; then
 	suppress_output=' >/dev/null 2>&1'
       fi
     fi
 
     # Only build a position-dependent object if we build old libraries.
-    if test yes = "$build_old_libs"; then
-      if test yes != "$pic_mode"; then
+    if test "$build_old_libs" = yes; then
+      if test "$pic_mode" != yes; then
 	# Don't build PIC code
 	command="$base_compile $qsrcfile$pie_flag"
       else
 	command="$base_compile $qsrcfile $pic_flag"
       fi
-      if test yes = "$compiler_c_o"; then
+      if test "$compiler_c_o" = yes; then
 	func_append command " -o $obj"
       fi
 
@@ -3566,7 +2250,7 @@ compiler."
       func_show_eval_locale "$command" \
         '$opt_dry_run || $RM $removelist; exit $EXIT_FAILURE'
 
-      if test warn = "$need_locks" &&
+      if test "$need_locks" = warn &&
 	 test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then
 	$ECHO "\
 *** ERROR, $lockfile contains:
@@ -3577,7 +2261,7 @@ $srcfile
 
 This indicates that another process is trying to use the same
 temporary object file, and libtool could not work around it because
-your compiler does not support '-c' and '-o' together.  If you
+your compiler does not support \`-c' and \`-o' together.  If you
 repeat this compilation, it may succeed, by chance, but you had better
 avoid parallel builds (make -j) in this platform, or get a better
 compiler."
@@ -3597,7 +2281,7 @@ compiler."
       func_write_libtool_object "$libobj" "$objdir/$objname" "$objname"
 
       # Unlock the critical section if it was locked
-      if test no != "$need_locks"; then
+      if test "$need_locks" != no; then
 	removelist=$lockfile
         $RM "$lockfile"
       fi
@@ -3607,7 +2291,7 @@ compiler."
 }
 
 $opt_help || {
-  test compile = "$opt_mode" && func_mode_compile ${1+"$@"}
+  test "$opt_mode" = compile && func_mode_compile ${1+"$@"}
 }
 
 func_mode_help ()
@@ -3627,7 +2311,7 @@ func_mode_help ()
 Remove files from the build directory.
 
 RM is the name of the program to use to delete files associated with each FILE
-(typically '/bin/rm').  RM-OPTIONS are options (such as '-f') to be passed
+(typically \`/bin/rm').  RM-OPTIONS are options (such as \`-f') to be passed
 to RM.
 
 If FILE is a libtool library, object or program, all the files associated
@@ -3646,16 +2330,16 @@ This mode accepts the following additional options:
   -no-suppress      do not suppress compiler output for multiple passes
   -prefer-pic       try to build PIC objects only
   -prefer-non-pic   try to build non-PIC objects only
-  -shared           do not build a '.o' file suitable for static linking
-  -static           only build a '.o' file suitable for static linking
+  -shared           do not build a \`.o' file suitable for static linking
+  -static           only build a \`.o' file suitable for static linking
   -Wc,FLAG          pass FLAG directly to the compiler
 
-COMPILE-COMMAND is a command to be used in creating a 'standard' object file
+COMPILE-COMMAND is a command to be used in creating a \`standard' object file
 from the given SOURCEFILE.
 
 The output file name is determined by removing the directory component from
-SOURCEFILE, then substituting the C source code suffix '.c' with the
-library object suffix, '.lo'."
+SOURCEFILE, then substituting the C source code suffix \`.c' with the
+library object suffix, \`.lo'."
         ;;
 
       execute)
@@ -3668,7 +2352,7 @@ This mode accepts the following additional options:
 
   -dlopen FILE      add the directory containing FILE to the library path
 
-This mode sets the library path environment variable according to '-dlopen'
+This mode sets the library path environment variable according to \`-dlopen'
 flags.
 
 If any of the ARGS are libtool executable wrappers, then they are translated
@@ -3687,7 +2371,7 @@ Complete the installation of libtool libraries.
 Each LIBDIR is a directory that contains libtool libraries.
 
 The commands that this mode executes may require superuser privileges.  Use
-the '--dry-run' option if you just want to see what would be executed."
+the \`--dry-run' option if you just want to see what would be executed."
         ;;
 
       install)
@@ -3697,7 +2381,7 @@ the '--dry-run' option if you just want to see what would be executed."
 Install executables or libraries.
 
 INSTALL-COMMAND is the installation command.  The first component should be
-either the 'install' or 'cp' program.
+either the \`install' or \`cp' program.
 
 The following components of INSTALL-COMMAND are treated specially:
 
@@ -3723,7 +2407,7 @@ The following components of LINK-COMMAND are treated specially:
   -avoid-version    do not add a version suffix if possible
   -bindir BINDIR    specify path to binaries directory (for systems where
                     libraries must be found in the PATH setting at runtime)
-  -dlopen FILE      '-dlpreopen' FILE if it cannot be dlopened at runtime
+  -dlopen FILE      \`-dlpreopen' FILE if it cannot be dlopened at runtime
   -dlpreopen FILE   link in FILE and add its symbols to lt_preloaded_symbols
   -export-dynamic   allow symbols from OUTPUT-FILE to be resolved with dlsym(3)
   -export-symbols SYMFILE
@@ -3737,8 +2421,7 @@ The following components of LINK-COMMAND are treated specially:
   -no-install       link a not-installable executable
   -no-undefined     declare that a library does not refer to external symbols
   -o OUTPUT-FILE    create OUTPUT-FILE from the specified objects
-  -objectlist FILE  use a list of object files found in FILE to specify objects
-  -os2dllname NAME  force a short DLL name on OS/2 (no effect on other OSes)
+  -objectlist FILE  Use a list of object files found in FILE to specify objects
   -precious-files-regex REGEX
                     don't remove output files matching REGEX
   -release RELEASE  specify package release information
@@ -3758,20 +2441,20 @@ The following components of LINK-COMMAND are treated specially:
   -Xlinker FLAG     pass linker-specific FLAG directly to the linker
   -XCClinker FLAG   pass link-specific FLAG to the compiler driver (CC)
 
-All other options (arguments beginning with '-') are ignored.
+All other options (arguments beginning with \`-') are ignored.
 
-Every other argument is treated as a filename.  Files ending in '.la' are
+Every other argument is treated as a filename.  Files ending in \`.la' are
 treated as uninstalled libtool libraries, other files are standard or library
 object files.
 
-If the OUTPUT-FILE ends in '.la', then a libtool library is created,
-only library objects ('.lo' files) may be specified, and '-rpath' is
+If the OUTPUT-FILE ends in \`.la', then a libtool library is created,
+only library objects (\`.lo' files) may be specified, and \`-rpath' is
 required, except when creating a convenience library.
 
-If OUTPUT-FILE ends in '.a' or '.lib', then a standard library is created
-using 'ar' and 'ranlib', or on Windows using 'lib'.
+If OUTPUT-FILE ends in \`.a' or \`.lib', then a standard library is created
+using \`ar' and \`ranlib', or on Windows using \`lib'.
 
-If OUTPUT-FILE ends in '.lo' or '.$objext', then a reloadable object file
+If OUTPUT-FILE ends in \`.lo' or \`.${objext}', then a reloadable object file
 is created, otherwise an executable program is created."
         ;;
 
@@ -3782,7 +2465,7 @@ is created, otherwise an executable program is created."
 Remove libraries from an installation directory.
 
 RM is the name of the program to use to delete files associated with each FILE
-(typically '/bin/rm').  RM-OPTIONS are options (such as '-f') to be passed
+(typically \`/bin/rm').  RM-OPTIONS are options (such as \`-f') to be passed
 to RM.
 
 If FILE is a libtool library, all the files associated with it are deleted.
@@ -3790,17 +2473,17 @@ Otherwise, only FILE itself is deleted using RM."
         ;;
 
       *)
-        func_fatal_help "invalid operation mode '$opt_mode'"
+        func_fatal_help "invalid operation mode \`$opt_mode'"
         ;;
     esac
 
     echo
-    $ECHO "Try '$progname --help' for more information about other modes."
+    $ECHO "Try \`$progname --help' for more information about other modes."
 }
 
 # Now that we've collected a possible --mode arg, show help if necessary
 if $opt_help; then
-  if test : = "$opt_help"; then
+  if test "$opt_help" = :; then
     func_mode_help
   else
     {
@@ -3808,7 +2491,7 @@ if $opt_help; then
       for opt_mode in compile link execute install finish uninstall clean; do
 	func_mode_help
       done
-    } | $SED -n '1p; 2,$s/^Usage:/  or: /p'
+    } | sed -n '1p; 2,$s/^Usage:/  or: /p'
     {
       func_help noexit
       for opt_mode in compile link execute install finish uninstall clean; do
@@ -3816,7 +2499,7 @@ if $opt_help; then
 	func_mode_help
       done
     } |
-    $SED '1d
+    sed '1d
       /^When reporting/,/^Report/{
 	H
 	d
@@ -3833,17 +2516,16 @@ fi
 # func_mode_execute arg...
 func_mode_execute ()
 {
-    $debug_cmd
-
+    $opt_debug
     # The first argument is the command name.
-    cmd=$nonopt
+    cmd="$nonopt"
     test -z "$cmd" && \
       func_fatal_help "you must specify a COMMAND"
 
     # Handle -dlopen flags immediately.
     for file in $opt_dlopen; do
       test -f "$file" \
-	|| func_fatal_help "'$file' is not a file"
+	|| func_fatal_help "\`$file' is not a file"
 
       dir=
       case $file in
@@ -3853,7 +2535,7 @@ func_mode_execute ()
 
 	# Check to see that this really is a libtool archive.
 	func_lalib_unsafe_p "$file" \
-	  || func_fatal_help "'$lib' is not a valid libtool archive"
+	  || func_fatal_help "\`$lib' is not a valid libtool archive"
 
 	# Read the libtool library.
 	dlname=
@@ -3864,18 +2546,18 @@ func_mode_execute ()
 	if test -z "$dlname"; then
 	  # Warn if it was a shared library.
 	  test -n "$library_names" && \
-	    func_warning "'$file' was not linked with '-export-dynamic'"
+	    func_warning "\`$file' was not linked with \`-export-dynamic'"
 	  continue
 	fi
 
 	func_dirname "$file" "" "."
-	dir=$func_dirname_result
+	dir="$func_dirname_result"
 
 	if test -f "$dir/$objdir/$dlname"; then
 	  func_append dir "/$objdir"
 	else
 	  if test ! -f "$dir/$dlname"; then
-	    func_fatal_error "cannot find '$dlname' in '$dir' or '$dir/$objdir'"
+	    func_fatal_error "cannot find \`$dlname' in \`$dir' or \`$dir/$objdir'"
 	  fi
 	fi
 	;;
@@ -3883,18 +2565,18 @@ func_mode_execute ()
       *.lo)
 	# Just add the directory containing the .lo file.
 	func_dirname "$file" "" "."
-	dir=$func_dirname_result
+	dir="$func_dirname_result"
 	;;
 
       *)
-	func_warning "'-dlopen' is ignored for non-libtool libraries and objects"
+	func_warning "\`-dlopen' is ignored for non-libtool libraries and objects"
 	continue
 	;;
       esac
 
       # Get the absolute pathname.
       absdir=`cd "$dir" && pwd`
-      test -n "$absdir" && dir=$absdir
+      test -n "$absdir" && dir="$absdir"
 
       # Now add the directory to shlibpath_var.
       if eval "test -z \"\$$shlibpath_var\""; then
@@ -3906,7 +2588,7 @@ func_mode_execute ()
 
     # This variable tells wrapper scripts just to set shlibpath_var
     # rather than running their programs.
-    libtool_execute_magic=$magic
+    libtool_execute_magic="$magic"
 
     # Check if any of the arguments is a wrapper script.
     args=
@@ -3919,12 +2601,12 @@ func_mode_execute ()
 	if func_ltwrapper_script_p "$file"; then
 	  func_source "$file"
 	  # Transform arg to wrapped name.
-	  file=$progdir/$program
+	  file="$progdir/$program"
 	elif func_ltwrapper_executable_p "$file"; then
 	  func_ltwrapper_scriptname "$file"
 	  func_source "$func_ltwrapper_scriptname_result"
 	  # Transform arg to wrapped name.
-	  file=$progdir/$program
+	  file="$progdir/$program"
 	fi
 	;;
       esac
@@ -3932,15 +2614,7 @@ func_mode_execute ()
       func_append_quoted args "$file"
     done
 
-    if $opt_dry_run; then
-      # Display what would be done.
-      if test -n "$shlibpath_var"; then
-	eval "\$ECHO \"\$shlibpath_var=\$$shlibpath_var\""
-	echo "export $shlibpath_var"
-      fi
-      $ECHO "$cmd$args"
-      exit $EXIT_SUCCESS
-    else
+    if test "X$opt_dry_run" = Xfalse; then
       if test -n "$shlibpath_var"; then
 	# Export the shlibpath_var.
 	eval "export $shlibpath_var"
@@ -3957,18 +2631,25 @@ func_mode_execute ()
       done
 
       # Now prepare to actually exec the command.
-      exec_cmd=\$cmd$args
+      exec_cmd="\$cmd$args"
+    else
+      # Display what would be done.
+      if test -n "$shlibpath_var"; then
+	eval "\$ECHO \"\$shlibpath_var=\$$shlibpath_var\""
+	echo "export $shlibpath_var"
+      fi
+      $ECHO "$cmd$args"
+      exit $EXIT_SUCCESS
     fi
 }
 
-test execute = "$opt_mode" && func_mode_execute ${1+"$@"}
+test "$opt_mode" = execute && func_mode_execute ${1+"$@"}
 
 
 # func_mode_finish arg...
 func_mode_finish ()
 {
-    $debug_cmd
-
+    $opt_debug
     libs=
     libdirs=
     admincmds=
@@ -3982,11 +2663,11 @@ func_mode_finish ()
 	if func_lalib_unsafe_p "$opt"; then
 	  func_append libs " $opt"
 	else
-	  func_warning "'$opt' is not a valid libtool archive"
+	  func_warning "\`$opt' is not a valid libtool archive"
 	fi
 
       else
-	func_fatal_error "invalid argument '$opt'"
+	func_fatal_error "invalid argument \`$opt'"
       fi
     done
 
@@ -4001,12 +2682,12 @@ func_mode_finish ()
       # Remove sysroot references
       if $opt_dry_run; then
         for lib in $libs; do
-          echo "removing references to $lt_sysroot and '=' prefixes from $lib"
+          echo "removing references to $lt_sysroot and \`=' prefixes from $lib"
         done
       else
         tmpdir=`func_mktempdir`
         for lib in $libs; do
-	  $SED -e "$sysroot_cmd s/\([ ']-[LR]\)=/\1/g; s/\([ ']\)=/\1/g" $lib \
+	  sed -e "${sysroot_cmd} s/\([ ']-[LR]\)=/\1/g; s/\([ ']\)=/\1/g" $lib \
 	    > $tmpdir/tmp-la
 	  mv -f $tmpdir/tmp-la $lib
 	done
@@ -4031,7 +2712,7 @@ func_mode_finish ()
     fi
 
     # Exit here if they wanted silent mode.
-    $opt_quiet && exit $EXIT_SUCCESS
+    $opt_silent && exit $EXIT_SUCCESS
 
     if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then
       echo "----------------------------------------------------------------------"
@@ -4042,27 +2723,27 @@ func_mode_finish ()
       echo
       echo "If you ever happen to want to link against installed libraries"
       echo "in a given directory, LIBDIR, you must either use libtool, and"
-      echo "specify the full pathname of the library, or use the '-LLIBDIR'"
+      echo "specify the full pathname of the library, or use the \`-LLIBDIR'"
       echo "flag during linking and do at least one of the following:"
       if test -n "$shlibpath_var"; then
-	echo "   - add LIBDIR to the '$shlibpath_var' environment variable"
+	echo "   - add LIBDIR to the \`$shlibpath_var' environment variable"
 	echo "     during execution"
       fi
       if test -n "$runpath_var"; then
-	echo "   - add LIBDIR to the '$runpath_var' environment variable"
+	echo "   - add LIBDIR to the \`$runpath_var' environment variable"
 	echo "     during linking"
       fi
       if test -n "$hardcode_libdir_flag_spec"; then
 	libdir=LIBDIR
 	eval flag=\"$hardcode_libdir_flag_spec\"
 
-	$ECHO "   - use the '$flag' linker flag"
+	$ECHO "   - use the \`$flag' linker flag"
       fi
       if test -n "$admincmds"; then
 	$ECHO "   - have your system administrator run these commands:$admincmds"
       fi
       if test -f /etc/ld.so.conf; then
-	echo "   - have your system administrator add LIBDIR to '/etc/ld.so.conf'"
+	echo "   - have your system administrator add LIBDIR to \`/etc/ld.so.conf'"
       fi
       echo
 
@@ -4081,20 +2762,18 @@ func_mode_finish ()
     exit $EXIT_SUCCESS
 }
 
-test finish = "$opt_mode" && func_mode_finish ${1+"$@"}
+test "$opt_mode" = finish && func_mode_finish ${1+"$@"}
 
 
 # func_mode_install arg...
 func_mode_install ()
 {
-    $debug_cmd
-
+    $opt_debug
     # There may be an optional sh(1) argument at the beginning of
     # install_prog (especially on Windows NT).
-    if test "$SHELL" = "$nonopt" || test /bin/sh = "$nonopt" ||
+    if test "$nonopt" = "$SHELL" || test "$nonopt" = /bin/sh ||
        # Allow the use of GNU shtool's install command.
-       case $nonopt in *shtool*) :;; *) false;; esac
-    then
+       case $nonopt in *shtool*) :;; *) false;; esac; then
       # Aesthetically quote it.
       func_quote_for_eval "$nonopt"
       install_prog="$func_quote_for_eval_result "
@@ -4121,7 +2800,7 @@ func_mode_install ()
     opts=
     prev=
     install_type=
-    isdir=false
+    isdir=no
     stripme=
     no_mode=:
     for arg
@@ -4134,7 +2813,7 @@ func_mode_install ()
       fi
 
       case $arg in
-      -d) isdir=: ;;
+      -d) isdir=yes ;;
       -f)
 	if $install_cp; then :; else
 	  prev=$arg
@@ -4152,7 +2831,7 @@ func_mode_install ()
       *)
 	# If the previous option needed an argument, then skip it.
 	if test -n "$prev"; then
-	  if test X-m = "X$prev" && test -n "$install_override_mode"; then
+	  if test "x$prev" = x-m && test -n "$install_override_mode"; then
 	    arg2=$install_override_mode
 	    no_mode=false
 	  fi
@@ -4177,7 +2856,7 @@ func_mode_install ()
       func_fatal_help "you must specify an install program"
 
     test -n "$prev" && \
-      func_fatal_help "the '$prev' option requires an argument"
+      func_fatal_help "the \`$prev' option requires an argument"
 
     if test -n "$install_override_mode" && $no_mode; then
       if $install_cp; then :; else
@@ -4199,19 +2878,19 @@ func_mode_install ()
     dest=$func_stripname_result
 
     # Check to see that the destination is a directory.
-    test -d "$dest" && isdir=:
-    if $isdir; then
-      destdir=$dest
+    test -d "$dest" && isdir=yes
+    if test "$isdir" = yes; then
+      destdir="$dest"
       destname=
     else
       func_dirname_and_basename "$dest" "" "."
-      destdir=$func_dirname_result
-      destname=$func_basename_result
+      destdir="$func_dirname_result"
+      destname="$func_basename_result"
 
       # Not a directory, so check to see that there is only one file specified.
       set dummy $files; shift
       test "$#" -gt 1 && \
-	func_fatal_help "'$dest' is not a directory"
+	func_fatal_help "\`$dest' is not a directory"
     fi
     case $destdir in
     [\\/]* | [A-Za-z]:[\\/]*) ;;
@@ -4220,7 +2899,7 @@ func_mode_install ()
 	case $file in
 	*.lo) ;;
 	*)
-	  func_fatal_help "'$destdir' must be an absolute directory name"
+	  func_fatal_help "\`$destdir' must be an absolute directory name"
 	  ;;
 	esac
       done
@@ -4229,7 +2908,7 @@ func_mode_install ()
 
     # This variable tells wrapper scripts just to set variables rather
     # than running their programs.
-    libtool_install_magic=$magic
+    libtool_install_magic="$magic"
 
     staticlibs=
     future_libdirs=
@@ -4249,7 +2928,7 @@ func_mode_install ()
 
 	# Check to see that this really is a libtool archive.
 	func_lalib_unsafe_p "$file" \
-	  || func_fatal_help "'$file' is not a valid libtool archive"
+	  || func_fatal_help "\`$file' is not a valid libtool archive"
 
 	library_names=
 	old_library=
@@ -4271,7 +2950,7 @@ func_mode_install ()
 	fi
 
 	func_dirname "$file" "/" ""
-	dir=$func_dirname_result
+	dir="$func_dirname_result"
 	func_append dir "$objdir"
 
 	if test -n "$relink_command"; then
@@ -4285,7 +2964,7 @@ func_mode_install ()
 	  # are installed into $libdir/../bin (currently, that works fine)
 	  # but it's something to keep an eye on.
 	  test "$inst_prefix_dir" = "$destdir" && \
-	    func_fatal_error "error: cannot install '$file' to a directory not ending in $libdir"
+	    func_fatal_error "error: cannot install \`$file' to a directory not ending in $libdir"
 
 	  if test -n "$inst_prefix_dir"; then
 	    # Stick the inst_prefix_dir data into the link command.
@@ -4294,36 +2973,29 @@ func_mode_install ()
 	    relink_command=`$ECHO "$relink_command" | $SED "s%@inst_prefix_dir@%%"`
 	  fi
 
-	  func_warning "relinking '$file'"
+	  func_warning "relinking \`$file'"
 	  func_show_eval "$relink_command" \
-	    'func_fatal_error "error: relink '\''$file'\'' with the above command before installing it"'
+	    'func_fatal_error "error: relink \`$file'\'' with the above command before installing it"'
 	fi
 
 	# See the names of the shared library.
 	set dummy $library_names; shift
 	if test -n "$1"; then
-	  realname=$1
+	  realname="$1"
 	  shift
 
-	  srcname=$realname
-	  test -n "$relink_command" && srcname=${realname}T
+	  srcname="$realname"
+	  test -n "$relink_command" && srcname="$realname"T
 
 	  # Install the shared library and build the symlinks.
 	  func_show_eval "$install_shared_prog $dir/$srcname $destdir/$realname" \
 	      'exit $?'
-	  tstripme=$stripme
+	  tstripme="$stripme"
 	  case $host_os in
 	  cygwin* | mingw* | pw32* | cegcc*)
 	    case $realname in
 	    *.dll.a)
-	      tstripme=
-	      ;;
-	    esac
-	    ;;
-	  os2*)
-	    case $realname in
-	    *_dll.a)
-	      tstripme=
+	      tstripme=""
 	      ;;
 	    esac
 	    ;;
@@ -4334,7 +3006,7 @@ func_mode_install ()
 
 	  if test "$#" -gt 0; then
 	    # Delete the old symlinks, and create new ones.
-	    # Try 'ln -sf' first, because the 'ln' binary might depend on
+	    # Try `ln -sf' first, because the `ln' binary might depend on
 	    # the symlink we replace!  Solaris /bin/ln does not understand -f,
 	    # so we also need to try rm && ln -s.
 	    for linkname
@@ -4345,14 +3017,14 @@ func_mode_install ()
 	  fi
 
 	  # Do each command in the postinstall commands.
-	  lib=$destdir/$realname
+	  lib="$destdir/$realname"
 	  func_execute_cmds "$postinstall_cmds" 'exit $?'
 	fi
 
 	# Install the pseudo-library for information purposes.
 	func_basename "$file"
-	name=$func_basename_result
-	instname=$dir/${name}i
+	name="$func_basename_result"
+	instname="$dir/$name"i
 	func_show_eval "$install_prog $instname $destdir/$name" 'exit $?'
 
 	# Maybe install the static library, too.
@@ -4364,11 +3036,11 @@ func_mode_install ()
 
 	# Figure out destination file name, if it wasn't already specified.
 	if test -n "$destname"; then
-	  destfile=$destdir/$destname
+	  destfile="$destdir/$destname"
 	else
 	  func_basename "$file"
-	  destfile=$func_basename_result
-	  destfile=$destdir/$destfile
+	  destfile="$func_basename_result"
+	  destfile="$destdir/$destfile"
 	fi
 
 	# Deduce the name of the destination old-style object file.
@@ -4378,11 +3050,11 @@ func_mode_install ()
 	  staticdest=$func_lo2o_result
 	  ;;
 	*.$objext)
-	  staticdest=$destfile
+	  staticdest="$destfile"
 	  destfile=
 	  ;;
 	*)
-	  func_fatal_help "cannot copy a libtool object to '$destfile'"
+	  func_fatal_help "cannot copy a libtool object to \`$destfile'"
 	  ;;
 	esac
 
@@ -4391,7 +3063,7 @@ func_mode_install ()
 	  func_show_eval "$install_prog $file $destfile" 'exit $?'
 
 	# Install the old object if enabled.
-	if test yes = "$build_old_libs"; then
+	if test "$build_old_libs" = yes; then
 	  # Deduce the name of the old-style object file.
 	  func_lo2o "$file"
 	  staticobj=$func_lo2o_result
@@ -4403,23 +3075,23 @@ func_mode_install ()
       *)
 	# Figure out destination file name, if it wasn't already specified.
 	if test -n "$destname"; then
-	  destfile=$destdir/$destname
+	  destfile="$destdir/$destname"
 	else
 	  func_basename "$file"
-	  destfile=$func_basename_result
-	  destfile=$destdir/$destfile
+	  destfile="$func_basename_result"
+	  destfile="$destdir/$destfile"
 	fi
 
 	# If the file is missing, and there is a .exe on the end, strip it
 	# because it is most likely a libtool script we actually want to
 	# install
-	stripped_ext=
+	stripped_ext=""
 	case $file in
 	  *.exe)
 	    if test ! -f "$file"; then
 	      func_stripname '' '.exe' "$file"
 	      file=$func_stripname_result
-	      stripped_ext=.exe
+	      stripped_ext=".exe"
 	    fi
 	    ;;
 	esac
@@ -4447,19 +3119,19 @@ func_mode_install ()
 
 	  # Check the variables that should have been set.
 	  test -z "$generated_by_libtool_version" && \
-	    func_fatal_error "invalid libtool wrapper script '$wrapper'"
+	    func_fatal_error "invalid libtool wrapper script \`$wrapper'"
 
-	  finalize=:
+	  finalize=yes
 	  for lib in $notinst_deplibs; do
 	    # Check to see that each library is installed.
 	    libdir=
 	    if test -f "$lib"; then
 	      func_source "$lib"
 	    fi
-	    libfile=$libdir/`$ECHO "$lib" | $SED 's%^.*/%%g'`
+	    libfile="$libdir/"`$ECHO "$lib" | $SED 's%^.*/%%g'` ### testsuite: skip nested quoting test
 	    if test -n "$libdir" && test ! -f "$libfile"; then
-	      func_warning "'$lib' has not been installed in '$libdir'"
-	      finalize=false
+	      func_warning "\`$lib' has not been installed in \`$libdir'"
+	      finalize=no
 	    fi
 	  done
 
@@ -4467,29 +3139,29 @@ func_mode_install ()
 	  func_source "$wrapper"
 
 	  outputname=
-	  if test no = "$fast_install" && test -n "$relink_command"; then
+	  if test "$fast_install" = no && test -n "$relink_command"; then
 	    $opt_dry_run || {
-	      if $finalize; then
+	      if test "$finalize" = yes; then
 	        tmpdir=`func_mktempdir`
 		func_basename "$file$stripped_ext"
-		file=$func_basename_result
-	        outputname=$tmpdir/$file
+		file="$func_basename_result"
+	        outputname="$tmpdir/$file"
 	        # Replace the output file specification.
 	        relink_command=`$ECHO "$relink_command" | $SED 's%@OUTPUT@%'"$outputname"'%g'`
 
-	        $opt_quiet || {
+	        $opt_silent || {
 	          func_quote_for_expand "$relink_command"
 		  eval "func_echo $func_quote_for_expand_result"
 	        }
 	        if eval "$relink_command"; then :
 	          else
-		  func_error "error: relink '$file' with the above command before installing it"
+		  func_error "error: relink \`$file' with the above command before installing it"
 		  $opt_dry_run || ${RM}r "$tmpdir"
 		  continue
 	        fi
-	        file=$outputname
+	        file="$outputname"
 	      else
-	        func_warning "cannot relink '$file'"
+	        func_warning "cannot relink \`$file'"
 	      fi
 	    }
 	  else
@@ -4526,10 +3198,10 @@ func_mode_install ()
 
     for file in $staticlibs; do
       func_basename "$file"
-      name=$func_basename_result
+      name="$func_basename_result"
 
       # Set up the ranlib parameters.
-      oldlib=$destdir/$name
+      oldlib="$destdir/$name"
       func_to_tool_file "$oldlib" func_convert_file_msys_to_w32
       tool_oldlib=$func_to_tool_file_result
 
@@ -4544,18 +3216,18 @@ func_mode_install ()
     done
 
     test -n "$future_libdirs" && \
-      func_warning "remember to run '$progname --finish$future_libdirs'"
+      func_warning "remember to run \`$progname --finish$future_libdirs'"
 
     if test -n "$current_libdirs"; then
       # Maybe just do a dry run.
       $opt_dry_run && current_libdirs=" -n$current_libdirs"
-      exec_cmd='$SHELL "$progpath" $preserve_args --finish$current_libdirs'
+      exec_cmd='$SHELL $progpath $preserve_args --finish$current_libdirs'
     else
       exit $EXIT_SUCCESS
     fi
 }
 
-test install = "$opt_mode" && func_mode_install ${1+"$@"}
+test "$opt_mode" = install && func_mode_install ${1+"$@"}
 
 
 # func_generate_dlsyms outputname originator pic_p
@@ -4563,17 +3235,16 @@ test install = "$opt_mode" && func_mode_install ${1+"$@"}
 # a dlpreopen symbol table.
 func_generate_dlsyms ()
 {
-    $debug_cmd
-
-    my_outputname=$1
-    my_originator=$2
-    my_pic_p=${3-false}
-    my_prefix=`$ECHO "$my_originator" | $SED 's%[^a-zA-Z0-9]%_%g'`
+    $opt_debug
+    my_outputname="$1"
+    my_originator="$2"
+    my_pic_p="${3-no}"
+    my_prefix=`$ECHO "$my_originator" | sed 's%[^a-zA-Z0-9]%_%g'`
     my_dlsyms=
 
-    if test -n "$dlfiles$dlprefiles" || test no != "$dlself"; then
+    if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then
       if test -n "$NM" && test -n "$global_symbol_pipe"; then
-	my_dlsyms=${my_outputname}S.c
+	my_dlsyms="${my_outputname}S.c"
       else
 	func_error "not configured to extract global symbols from dlpreopened files"
       fi
@@ -4584,7 +3255,7 @@ func_generate_dlsyms ()
       "") ;;
       *.c)
 	# Discover the nlist of each of the dlfiles.
-	nlist=$output_objdir/$my_outputname.nm
+	nlist="$output_objdir/${my_outputname}.nm"
 
 	func_show_eval "$RM $nlist ${nlist}S ${nlist}T"
 
@@ -4592,36 +3263,34 @@ func_generate_dlsyms ()
 	func_verbose "creating $output_objdir/$my_dlsyms"
 
 	$opt_dry_run || $ECHO > "$output_objdir/$my_dlsyms" "\
-/* $my_dlsyms - symbol resolution table for '$my_outputname' dlsym emulation. */
-/* Generated by $PROGRAM (GNU $PACKAGE) $VERSION */
+/* $my_dlsyms - symbol resolution table for \`$my_outputname' dlsym emulation. */
+/* Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION */
 
 #ifdef __cplusplus
 extern \"C\" {
 #endif
 
-#if defined __GNUC__ && (((__GNUC__ == 4) && (__GNUC_MINOR__ >= 4)) || (__GNUC__ > 4))
+#if defined(__GNUC__) && (((__GNUC__ == 4) && (__GNUC_MINOR__ >= 4)) || (__GNUC__ > 4))
 #pragma GCC diagnostic ignored \"-Wstrict-prototypes\"
 #endif
 
 /* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests.  */
-#if defined _WIN32 || defined __CYGWIN__ || defined _WIN32_WCE
-/* DATA imports from DLLs on WIN32 can't be const, because runtime
+#if defined(_WIN32) || defined(__CYGWIN__) || defined(_WIN32_WCE)
+/* DATA imports from DLLs on WIN32 con't be const, because runtime
    relocations are performed -- see ld's documentation on pseudo-relocs.  */
 # define LT_DLSYM_CONST
-#elif defined __osf__
+#elif defined(__osf__)
 /* This system does not cope well with relocations in const data.  */
 # define LT_DLSYM_CONST
 #else
 # define LT_DLSYM_CONST const
 #endif
 
-#define STREQ(s1, s2) (strcmp ((s1), (s2)) == 0)
-
 /* External symbol declarations for the compiler. */\
 "
 
-	if test yes = "$dlself"; then
-	  func_verbose "generating symbol list for '$output'"
+	if test "$dlself" = yes; then
+	  func_verbose "generating symbol list for \`$output'"
 
 	  $opt_dry_run || echo ': @PROGRAM@ ' > "$nlist"
 
@@ -4629,7 +3298,7 @@ extern \"C\" {
 	  progfiles=`$ECHO "$objs$old_deplibs" | $SP2NL | $SED "$lo2o" | $NL2SP`
 	  for progfile in $progfiles; do
 	    func_to_tool_file "$progfile" func_convert_file_msys_to_w32
-	    func_verbose "extracting global C symbols from '$func_to_tool_file_result'"
+	    func_verbose "extracting global C symbols from \`$func_to_tool_file_result'"
 	    $opt_dry_run || eval "$NM $func_to_tool_file_result | $global_symbol_pipe >> '$nlist'"
 	  done
 
@@ -4649,10 +3318,10 @@ extern \"C\" {
 
 	  # Prepare the list of exported symbols
 	  if test -z "$export_symbols"; then
-	    export_symbols=$output_objdir/$outputname.exp
+	    export_symbols="$output_objdir/$outputname.exp"
 	    $opt_dry_run || {
 	      $RM $export_symbols
-	      eval "$SED -n -e '/^: @PROGRAM@ $/d' -e 's/^.* \(.*\)$/\1/p' "'< "$nlist" > "$export_symbols"'
+	      eval "${SED} -n -e '/^: @PROGRAM@ $/d' -e 's/^.* \(.*\)$/\1/p' "'< "$nlist" > "$export_symbols"'
 	      case $host in
 	      *cygwin* | *mingw* | *cegcc* )
                 eval "echo EXPORTS "'> "$output_objdir/$outputname.def"'
@@ -4662,7 +3331,7 @@ extern \"C\" {
 	    }
 	  else
 	    $opt_dry_run || {
-	      eval "$SED -e 's/\([].[*^$]\)/\\\\\1/g' -e 's/^/ /' -e 's/$/$/'"' < "$export_symbols" > "$output_objdir/$outputname.exp"'
+	      eval "${SED} -e 's/\([].[*^$]\)/\\\\\1/g' -e 's/^/ /' -e 's/$/$/'"' < "$export_symbols" > "$output_objdir/$outputname.exp"'
 	      eval '$GREP -f "$output_objdir/$outputname.exp" < "$nlist" > "$nlist"T'
 	      eval '$MV "$nlist"T "$nlist"'
 	      case $host in
@@ -4676,22 +3345,22 @@ extern \"C\" {
 	fi
 
 	for dlprefile in $dlprefiles; do
-	  func_verbose "extracting global C symbols from '$dlprefile'"
+	  func_verbose "extracting global C symbols from \`$dlprefile'"
 	  func_basename "$dlprefile"
-	  name=$func_basename_result
+	  name="$func_basename_result"
           case $host in
 	    *cygwin* | *mingw* | *cegcc* )
 	      # if an import library, we need to obtain dlname
 	      if func_win32_import_lib_p "$dlprefile"; then
 	        func_tr_sh "$dlprefile"
 	        eval "curr_lafile=\$libfile_$func_tr_sh_result"
-	        dlprefile_dlbasename=
+	        dlprefile_dlbasename=""
 	        if test -n "$curr_lafile" && func_lalib_p "$curr_lafile"; then
 	          # Use subshell, to avoid clobbering current variable values
 	          dlprefile_dlname=`source "$curr_lafile" && echo "$dlname"`
-	          if test -n "$dlprefile_dlname"; then
+	          if test -n "$dlprefile_dlname" ; then
 	            func_basename "$dlprefile_dlname"
-	            dlprefile_dlbasename=$func_basename_result
+	            dlprefile_dlbasename="$func_basename_result"
 	          else
 	            # no lafile. user explicitly requested -dlpreopen <import library>.
 	            $sharedlib_from_linklib_cmd "$dlprefile"
@@ -4699,7 +3368,7 @@ extern \"C\" {
 	          fi
 	        fi
 	        $opt_dry_run || {
-	          if test -n "$dlprefile_dlbasename"; then
+	          if test -n "$dlprefile_dlbasename" ; then
 	            eval '$ECHO ": $dlprefile_dlbasename" >> "$nlist"'
 	          else
 	            func_warning "Could not compute DLL name from $name"
@@ -4755,11 +3424,6 @@ extern \"C\" {
 	    echo '/* NONE */' >> "$output_objdir/$my_dlsyms"
 	  fi
 
-	  func_show_eval '$RM "${nlist}I"'
-	  if test -n "$global_symbol_to_import"; then
-	    eval "$global_symbol_to_import"' < "$nlist"S > "$nlist"I'
-	  fi
-
 	  echo >> "$output_objdir/$my_dlsyms" "\
 
 /* The mapping between symbol names and symbols.  */
@@ -4768,30 +3432,11 @@ typedef struct {
   void *address;
 } lt_dlsymlist;
 extern LT_DLSYM_CONST lt_dlsymlist
-lt_${my_prefix}_LTX_preloaded_symbols[];\
-"
-
-	  if test -s "$nlist"I; then
-	    echo >> "$output_objdir/$my_dlsyms" "\
-static void lt_syminit(void)
-{
-  LT_DLSYM_CONST lt_dlsymlist *symbol = lt_${my_prefix}_LTX_preloaded_symbols;
-  for (; symbol->name; ++symbol)
-    {"
-	    $SED 's/.*/      if (STREQ (symbol->name, \"&\")) symbol->address = (void *) \&&;/' < "$nlist"I >> "$output_objdir/$my_dlsyms"
-	    echo >> "$output_objdir/$my_dlsyms" "\
-    }
-}"
-	  fi
-	  echo >> "$output_objdir/$my_dlsyms" "\
+lt_${my_prefix}_LTX_preloaded_symbols[];
 LT_DLSYM_CONST lt_dlsymlist
 lt_${my_prefix}_LTX_preloaded_symbols[] =
-{ {\"$my_originator\", (void *) 0},"
-
-	  if test -s "$nlist"I; then
-	    echo >> "$output_objdir/$my_dlsyms" "\
-  {\"@INIT@\", (void *) &lt_syminit},"
-	  fi
+{\
+  { \"$my_originator\", (void *) 0 },"
 
 	  case $need_lib_prefix in
 	  no)
@@ -4833,7 +3478,9 @@ static const void *lt_preloaded_setup() {
 	  *-*-hpux*)
 	    pic_flag_for_symtable=" $pic_flag"  ;;
 	  *)
-	    $my_pic_p && pic_flag_for_symtable=" $pic_flag"
+	    if test "X$my_pic_p" != Xno; then
+	      pic_flag_for_symtable=" $pic_flag"
+	    fi
 	    ;;
 	  esac
 	  ;;
@@ -4850,10 +3497,10 @@ static const void *lt_preloaded_setup() {
 	func_show_eval '(cd $output_objdir && $LTCC$symtab_cflags -c$no_builtin_flag$pic_flag_for_symtable "$my_dlsyms")' 'exit $?'
 
 	# Clean up the generated files.
-	func_show_eval '$RM "$output_objdir/$my_dlsyms" "$nlist" "${nlist}S" "${nlist}T" "${nlist}I"'
+	func_show_eval '$RM "$output_objdir/$my_dlsyms" "$nlist" "${nlist}S" "${nlist}T"'
 
 	# Transform the symbol file into the correct name.
-	symfileobj=$output_objdir/${my_outputname}S.$objext
+	symfileobj="$output_objdir/${my_outputname}S.$objext"
 	case $host in
 	*cygwin* | *mingw* | *cegcc* )
 	  if test -f "$output_objdir/$my_outputname.def"; then
@@ -4871,7 +3518,7 @@ static const void *lt_preloaded_setup() {
 	esac
 	;;
       *)
-	func_fatal_error "unknown suffix for '$my_dlsyms'"
+	func_fatal_error "unknown suffix for \`$my_dlsyms'"
 	;;
       esac
     else
@@ -4885,32 +3532,6 @@ static const void *lt_preloaded_setup() {
     fi
 }
 
-# func_cygming_gnu_implib_p ARG
-# This predicate returns with zero status (TRUE) if
-# ARG is a GNU/binutils-style import library. Returns
-# with nonzero status (FALSE) otherwise.
-func_cygming_gnu_implib_p ()
-{
-  $debug_cmd
-
-  func_to_tool_file "$1" func_convert_file_msys_to_w32
-  func_cygming_gnu_implib_tmp=`$NM "$func_to_tool_file_result" | eval "$global_symbol_pipe" | $EGREP ' (_head_[A-Za-z0-9_]+_[ad]l*|[A-Za-z0-9_]+_[ad]l*_iname)$'`
-  test -n "$func_cygming_gnu_implib_tmp"
-}
-
-# func_cygming_ms_implib_p ARG
-# This predicate returns with zero status (TRUE) if
-# ARG is an MS-style import library. Returns
-# with nonzero status (FALSE) otherwise.
-func_cygming_ms_implib_p ()
-{
-  $debug_cmd
-
-  func_to_tool_file "$1" func_convert_file_msys_to_w32
-  func_cygming_ms_implib_tmp=`$NM "$func_to_tool_file_result" | eval "$global_symbol_pipe" | $GREP '_NULL_IMPORT_DESCRIPTOR'`
-  test -n "$func_cygming_ms_implib_tmp"
-}
-
 # func_win32_libid arg
 # return the library type of file 'arg'
 #
@@ -4920,9 +3541,8 @@ func_cygming_ms_implib_p ()
 # Despite the name, also deal with 64 bit binaries.
 func_win32_libid ()
 {
-  $debug_cmd
-
-  win32_libid_type=unknown
+  $opt_debug
+  win32_libid_type="unknown"
   win32_fileres=`file -L $1 2>/dev/null`
   case $win32_fileres in
   *ar\ archive\ import\ library*) # definitely import
@@ -4932,29 +3552,16 @@ func_win32_libid ()
     # Keep the egrep pattern in sync with the one in _LT_CHECK_MAGIC_METHOD.
     if eval $OBJDUMP -f $1 | $SED -e '10q' 2>/dev/null |
        $EGREP 'file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)' >/dev/null; then
-      case $nm_interface in
-      "MS dumpbin")
-	if func_cygming_ms_implib_p "$1" ||
-	   func_cygming_gnu_implib_p "$1"
-	then
-	  win32_nmres=import
-	else
-	  win32_nmres=
-	fi
-	;;
-      *)
-	func_to_tool_file "$1" func_convert_file_msys_to_w32
-	win32_nmres=`eval $NM -f posix -A \"$func_to_tool_file_result\" |
-	  $SED -n -e '
+      func_to_tool_file "$1" func_convert_file_msys_to_w32
+      win32_nmres=`eval $NM -f posix -A \"$func_to_tool_file_result\" |
+	$SED -n -e '
 	    1,100{
 		/ I /{
-		    s|.*|import|
+		    s,.*,import,
 		    p
 		    q
 		}
 	    }'`
-	;;
-      esac
       case $win32_nmres in
       import*)  win32_libid_type="x86 archive import";;
       *)        win32_libid_type="x86 archive static";;
@@ -4986,8 +3593,7 @@ func_win32_libid ()
 #    $sharedlib_from_linklib_result
 func_cygming_dll_for_implib ()
 {
-  $debug_cmd
-
+  $opt_debug
   sharedlib_from_linklib_result=`$DLLTOOL --identify-strict --identify "$1"`
 }
 
@@ -5004,8 +3610,7 @@ func_cygming_dll_for_implib ()
 # specified import library.
 func_cygming_dll_for_implib_fallback_core ()
 {
-  $debug_cmd
-
+  $opt_debug
   match_literal=`$ECHO "$1" | $SED "$sed_make_literal_regex"`
   $OBJDUMP -s --section "$1" "$2" 2>/dev/null |
     $SED '/^Contents of section '"$match_literal"':/{
@@ -5041,8 +3646,8 @@ func_cygming_dll_for_implib_fallback_core ()
       /./p' |
     # we now have a list, one entry per line, of the stringified
     # contents of the appropriate section of all members of the
-    # archive that possess that section. Heuristic: eliminate
-    # all those that have a first or second character that is
+    # archive which possess that section. Heuristic: eliminate
+    # all those which have a first or second character that is
     # a '.' (that is, objdump's representation of an unprintable
     # character.) This should work for all archives with less than
     # 0x302f exports -- but will fail for DLLs whose name actually
@@ -5053,6 +3658,30 @@ func_cygming_dll_for_implib_fallback_core ()
     $SED -e '/^\./d;/^.\./d;q'
 }
 
+# func_cygming_gnu_implib_p ARG
+# This predicate returns with zero status (TRUE) if
+# ARG is a GNU/binutils-style import library. Returns
+# with nonzero status (FALSE) otherwise.
+func_cygming_gnu_implib_p ()
+{
+  $opt_debug
+  func_to_tool_file "$1" func_convert_file_msys_to_w32
+  func_cygming_gnu_implib_tmp=`$NM "$func_to_tool_file_result" | eval "$global_symbol_pipe" | $EGREP ' (_head_[A-Za-z0-9_]+_[ad]l*|[A-Za-z0-9_]+_[ad]l*_iname)$'`
+  test -n "$func_cygming_gnu_implib_tmp"
+}
+
+# func_cygming_ms_implib_p ARG
+# This predicate returns with zero status (TRUE) if
+# ARG is an MS-style import library. Returns
+# with nonzero status (FALSE) otherwise.
+func_cygming_ms_implib_p ()
+{
+  $opt_debug
+  func_to_tool_file "$1" func_convert_file_msys_to_w32
+  func_cygming_ms_implib_tmp=`$NM "$func_to_tool_file_result" | eval "$global_symbol_pipe" | $GREP '_NULL_IMPORT_DESCRIPTOR'`
+  test -n "$func_cygming_ms_implib_tmp"
+}
+
 # func_cygming_dll_for_implib_fallback ARG
 # Platform-specific function to extract the
 # name of the DLL associated with the specified
@@ -5066,17 +3695,16 @@ func_cygming_dll_for_implib_fallback_core ()
 #    $sharedlib_from_linklib_result
 func_cygming_dll_for_implib_fallback ()
 {
-  $debug_cmd
-
-  if func_cygming_gnu_implib_p "$1"; then
+  $opt_debug
+  if func_cygming_gnu_implib_p "$1" ; then
     # binutils import library
     sharedlib_from_linklib_result=`func_cygming_dll_for_implib_fallback_core '.idata$7' "$1"`
-  elif func_cygming_ms_implib_p "$1"; then
+  elif func_cygming_ms_implib_p "$1" ; then
     # ms-generated import library
     sharedlib_from_linklib_result=`func_cygming_dll_for_implib_fallback_core '.idata$6' "$1"`
   else
     # unknown
-    sharedlib_from_linklib_result=
+    sharedlib_from_linklib_result=""
   fi
 }
 
@@ -5084,11 +3712,10 @@ func_cygming_dll_for_implib_fallback ()
 # func_extract_an_archive dir oldlib
 func_extract_an_archive ()
 {
-    $debug_cmd
-
-    f_ex_an_ar_dir=$1; shift
-    f_ex_an_ar_oldlib=$1
-    if test yes = "$lock_old_archive_extraction"; then
+    $opt_debug
+    f_ex_an_ar_dir="$1"; shift
+    f_ex_an_ar_oldlib="$1"
+    if test "$lock_old_archive_extraction" = yes; then
       lockfile=$f_ex_an_ar_oldlib.lock
       until $opt_dry_run || ln "$progpath" "$lockfile" 2>/dev/null; do
 	func_echo "Waiting for $lockfile to be removed"
@@ -5097,7 +3724,7 @@ func_extract_an_archive ()
     fi
     func_show_eval "(cd \$f_ex_an_ar_dir && $AR x \"\$f_ex_an_ar_oldlib\")" \
 		   'stat=$?; rm -f "$lockfile"; exit $stat'
-    if test yes = "$lock_old_archive_extraction"; then
+    if test "$lock_old_archive_extraction" = yes; then
       $opt_dry_run || rm -f "$lockfile"
     fi
     if ($AR t "$f_ex_an_ar_oldlib" | sort | sort -uc >/dev/null 2>&1); then
@@ -5111,23 +3738,22 @@ func_extract_an_archive ()
 # func_extract_archives gentop oldlib ...
 func_extract_archives ()
 {
-    $debug_cmd
-
-    my_gentop=$1; shift
+    $opt_debug
+    my_gentop="$1"; shift
     my_oldlibs=${1+"$@"}
-    my_oldobjs=
-    my_xlib=
-    my_xabs=
-    my_xdir=
+    my_oldobjs=""
+    my_xlib=""
+    my_xabs=""
+    my_xdir=""
 
     for my_xlib in $my_oldlibs; do
       # Extract the objects.
       case $my_xlib in
-	[\\/]* | [A-Za-z]:[\\/]*) my_xabs=$my_xlib ;;
+	[\\/]* | [A-Za-z]:[\\/]*) my_xabs="$my_xlib" ;;
 	*) my_xabs=`pwd`"/$my_xlib" ;;
       esac
       func_basename "$my_xlib"
-      my_xlib=$func_basename_result
+      my_xlib="$func_basename_result"
       my_xlib_u=$my_xlib
       while :; do
         case " $extracted_archives " in
@@ -5139,7 +3765,7 @@ func_extract_archives ()
 	esac
       done
       extracted_archives="$extracted_archives $my_xlib_u"
-      my_xdir=$my_gentop/$my_xlib_u
+      my_xdir="$my_gentop/$my_xlib_u"
 
       func_mkdir_p "$my_xdir"
 
@@ -5152,23 +3778,22 @@ func_extract_archives ()
 	  cd $my_xdir || exit $?
 	  darwin_archive=$my_xabs
 	  darwin_curdir=`pwd`
-	  func_basename "$darwin_archive"
-	  darwin_base_archive=$func_basename_result
+	  darwin_base_archive=`basename "$darwin_archive"`
 	  darwin_arches=`$LIPO -info "$darwin_archive" 2>/dev/null | $GREP Architectures 2>/dev/null || true`
 	  if test -n "$darwin_arches"; then
 	    darwin_arches=`$ECHO "$darwin_arches" | $SED -e 's/.*are://'`
 	    darwin_arch=
 	    func_verbose "$darwin_base_archive has multiple architectures $darwin_arches"
-	    for darwin_arch in  $darwin_arches; do
-	      func_mkdir_p "unfat-$$/$darwin_base_archive-$darwin_arch"
-	      $LIPO -thin $darwin_arch -output "unfat-$$/$darwin_base_archive-$darwin_arch/$darwin_base_archive" "$darwin_archive"
-	      cd "unfat-$$/$darwin_base_archive-$darwin_arch"
-	      func_extract_an_archive "`pwd`" "$darwin_base_archive"
+	    for darwin_arch in  $darwin_arches ; do
+	      func_mkdir_p "unfat-$$/${darwin_base_archive}-${darwin_arch}"
+	      $LIPO -thin $darwin_arch -output "unfat-$$/${darwin_base_archive}-${darwin_arch}/${darwin_base_archive}" "${darwin_archive}"
+	      cd "unfat-$$/${darwin_base_archive}-${darwin_arch}"
+	      func_extract_an_archive "`pwd`" "${darwin_base_archive}"
 	      cd "$darwin_curdir"
-	      $RM "unfat-$$/$darwin_base_archive-$darwin_arch/$darwin_base_archive"
+	      $RM "unfat-$$/${darwin_base_archive}-${darwin_arch}/${darwin_base_archive}"
 	    done # $darwin_arches
             ## Okay now we've a bunch of thin objects, gotta fatten them up :)
-	    darwin_filelist=`find unfat-$$ -type f -name \*.o -print -o -name \*.lo -print | $SED -e "$sed_basename" | sort -u`
+	    darwin_filelist=`find unfat-$$ -type f -name \*.o -print -o -name \*.lo -print | $SED -e "$basename" | sort -u`
 	    darwin_file=
 	    darwin_files=
 	    for darwin_file in $darwin_filelist; do
@@ -5190,7 +3815,7 @@ func_extract_archives ()
       my_oldobjs="$my_oldobjs "`find $my_xdir -name \*.$objext -print -o -name \*.lo -print | sort | $NL2SP`
     done
 
-    func_extract_archives_result=$my_oldobjs
+    func_extract_archives_result="$my_oldobjs"
 }
 
 
@@ -5205,7 +3830,7 @@ func_extract_archives ()
 #
 # ARG is the value that the WRAPPER_SCRIPT_BELONGS_IN_OBJDIR
 # variable will take.  If 'yes', then the emitted script
-# will assume that the directory where it is stored is
+# will assume that the directory in which it is stored is
 # the $objdir directory.  This is a cygwin/mingw-specific
 # behavior.
 func_emit_wrapper ()
@@ -5216,7 +3841,7 @@ func_emit_wrapper ()
 #! $SHELL
 
 # $output - temporary wrapper script for $objdir/$outputname
-# Generated by $PROGRAM (GNU $PACKAGE) $VERSION
+# Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION
 #
 # The $output program cannot be directly executed until all the libtool
 # libraries that it depends on are installed.
@@ -5273,9 +3898,9 @@ _LTECHO_EOF'
 
 # Very basic option parsing. These options are (a) specific to
 # the libtool wrapper, (b) are identical between the wrapper
-# /script/ and the wrapper /executable/ that is used only on
+# /script/ and the wrapper /executable/ which is used only on
 # windows platforms, and (c) all begin with the string "--lt-"
-# (application programs are unlikely to have options that match
+# (application programs are unlikely to have options which match
 # this pattern).
 #
 # There are only two supported options: --lt-debug and
@@ -5308,7 +3933,7 @@ func_parse_lt_options ()
 
   # Print the debug banner immediately:
   if test -n \"\$lt_option_debug\"; then
-    echo \"$outputname:$output:\$LINENO: libtool wrapper (GNU $PACKAGE) $VERSION\" 1>&2
+    echo \"${outputname}:${output}:\${LINENO}: libtool wrapper (GNU $PACKAGE$TIMESTAMP) $VERSION\" 1>&2
   fi
 }
 
@@ -5319,7 +3944,7 @@ func_lt_dump_args ()
   lt_dump_args_N=1;
   for lt_arg
   do
-    \$ECHO \"$outputname:$output:\$LINENO: newargv[\$lt_dump_args_N]: \$lt_arg\"
+    \$ECHO \"${outputname}:${output}:\${LINENO}: newargv[\$lt_dump_args_N]: \$lt_arg\"
     lt_dump_args_N=\`expr \$lt_dump_args_N + 1\`
   done
 }
@@ -5333,7 +3958,7 @@ func_exec_program_core ()
   *-*-mingw | *-*-os2* | *-cegcc*)
     $ECHO "\
       if test -n \"\$lt_option_debug\"; then
-        \$ECHO \"$outputname:$output:\$LINENO: newargv[0]: \$progdir\\\\\$program\" 1>&2
+        \$ECHO \"${outputname}:${output}:\${LINENO}: newargv[0]: \$progdir\\\\\$program\" 1>&2
         func_lt_dump_args \${1+\"\$@\"} 1>&2
       fi
       exec \"\$progdir\\\\\$program\" \${1+\"\$@\"}
@@ -5343,7 +3968,7 @@ func_exec_program_core ()
   *)
     $ECHO "\
       if test -n \"\$lt_option_debug\"; then
-        \$ECHO \"$outputname:$output:\$LINENO: newargv[0]: \$progdir/\$program\" 1>&2
+        \$ECHO \"${outputname}:${output}:\${LINENO}: newargv[0]: \$progdir/\$program\" 1>&2
         func_lt_dump_args \${1+\"\$@\"} 1>&2
       fi
       exec \"\$progdir/\$program\" \${1+\"\$@\"}
@@ -5418,13 +4043,13 @@ func_exec_program ()
   test -n \"\$absdir\" && thisdir=\"\$absdir\"
 "
 
-	if test yes = "$fast_install"; then
+	if test "$fast_install" = yes; then
 	  $ECHO "\
   program=lt-'$outputname'$exeext
   progdir=\"\$thisdir/$objdir\"
 
   if test ! -f \"\$progdir/\$program\" ||
-     { file=\`ls -1dt \"\$progdir/\$program\" \"\$progdir/../\$program\" 2>/dev/null | $SED 1q\`; \\
+     { file=\`ls -1dt \"\$progdir/\$program\" \"\$progdir/../\$program\" 2>/dev/null | ${SED} 1q\`; \\
        test \"X\$file\" != \"X\$progdir/\$program\"; }; then
 
     file=\"\$\$-\$program\"
@@ -5441,7 +4066,7 @@ func_exec_program ()
     if test -n \"\$relink_command\"; then
       if relink_command_output=\`eval \$relink_command 2>&1\`; then :
       else
-	\$ECHO \"\$relink_command_output\" >&2
+	$ECHO \"\$relink_command_output\" >&2
 	$RM \"\$progdir/\$file\"
 	exit 1
       fi
@@ -5476,7 +4101,7 @@ func_exec_program ()
 	fi
 
 	# Export our shlibpath_var if we have one.
-	if test yes = "$shlibpath_overrides_runpath" && test -n "$shlibpath_var" && test -n "$temp_rpath"; then
+	if test "$shlibpath_overrides_runpath" = yes && test -n "$shlibpath_var" && test -n "$temp_rpath"; then
 	  $ECHO "\
     # Add our own library path to $shlibpath_var
     $shlibpath_var=\"$temp_rpath\$$shlibpath_var\"
@@ -5496,7 +4121,7 @@ func_exec_program ()
     fi
   else
     # The program doesn't exist.
-    \$ECHO \"\$0: error: '\$progdir/\$program' does not exist\" 1>&2
+    \$ECHO \"\$0: error: \\\`\$progdir/\$program' does not exist\" 1>&2
     \$ECHO \"This script is just a wrapper for \$program.\" 1>&2
     \$ECHO \"See the $PACKAGE documentation for more information.\" 1>&2
     exit 1
@@ -5515,7 +4140,7 @@ func_emit_cwrapperexe_src ()
 	cat <<EOF
 
 /* $cwrappersource - temporary wrapper executable for $objdir/$outputname
-   Generated by $PROGRAM (GNU $PACKAGE) $VERSION
+   Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION
 
    The $output program cannot be directly executed until all the libtool
    libraries that it depends on are installed.
@@ -5550,45 +4175,47 @@ EOF
 #include <fcntl.h>
 #include <sys/stat.h>
 
-#define STREQ(s1, s2) (strcmp ((s1), (s2)) == 0)
-
 /* declarations of non-ANSI functions */
-#if defined __MINGW32__
+#if defined(__MINGW32__)
 # ifdef __STRICT_ANSI__
 int _putenv (const char *);
 # endif
-#elif defined __CYGWIN__
+#elif defined(__CYGWIN__)
 # ifdef __STRICT_ANSI__
 char *realpath (const char *, char *);
 int putenv (char *);
 int setenv (const char *, const char *, int);
 # endif
-/* #elif defined other_platform || defined ... */
+/* #elif defined (other platforms) ... */
 #endif
 
 /* portability defines, excluding path handling macros */
-#if defined _MSC_VER
+#if defined(_MSC_VER)
 # define setmode _setmode
 # define stat    _stat
 # define chmod   _chmod
 # define getcwd  _getcwd
 # define putenv  _putenv
 # define S_IXUSR _S_IEXEC
-#elif defined __MINGW32__
+# ifndef _INTPTR_T_DEFINED
+#  define _INTPTR_T_DEFINED
+#  define intptr_t int
+# endif
+#elif defined(__MINGW32__)
 # define setmode _setmode
 # define stat    _stat
 # define chmod   _chmod
 # define getcwd  _getcwd
 # define putenv  _putenv
-#elif defined __CYGWIN__
+#elif defined(__CYGWIN__)
 # define HAVE_SETENV
 # define FOPEN_WB "wb"
-/* #elif defined other platforms ... */
+/* #elif defined (other platforms) ... */
 #endif
 
-#if defined PATH_MAX
+#if defined(PATH_MAX)
 # define LT_PATHMAX PATH_MAX
-#elif defined MAXPATHLEN
+#elif defined(MAXPATHLEN)
 # define LT_PATHMAX MAXPATHLEN
 #else
 # define LT_PATHMAX 1024
@@ -5607,8 +4234,8 @@ int setenv (const char *, const char *, int);
 # define PATH_SEPARATOR ':'
 #endif
 
-#if defined _WIN32 || defined __MSDOS__ || defined __DJGPP__ || \
-  defined __OS2__
+#if defined (_WIN32) || defined (__MSDOS__) || defined (__DJGPP__) || \
+  defined (__OS2__)
 # define HAVE_DOS_BASED_FILE_SYSTEM
 # define FOPEN_WB "wb"
 # ifndef DIR_SEPARATOR_2
@@ -5641,10 +4268,10 @@ int setenv (const char *, const char *, int);
 
 #define XMALLOC(type, num)      ((type *) xmalloc ((num) * sizeof(type)))
 #define XFREE(stale) do { \
-  if (stale) { free (stale); stale = 0; } \
+  if (stale) { free ((void *) stale); stale = 0; } \
 } while (0)
 
-#if defined LT_DEBUGWRAPPER
+#if defined(LT_DEBUGWRAPPER)
 static int lt_debug = 1;
 #else
 static int lt_debug = 0;
@@ -5673,16 +4300,11 @@ void lt_dump_script (FILE *f);
 EOF
 
 	    cat <<EOF
-#if __GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 5)
-# define externally_visible volatile
-#else
-# define externally_visible __attribute__((externally_visible)) volatile
-#endif
-externally_visible const char * MAGIC_EXE = "$magic_exe";
+volatile const char * MAGIC_EXE = "$magic_exe";
 const char * LIB_PATH_VARNAME = "$shlibpath_var";
 EOF
 
-	    if test yes = "$shlibpath_overrides_runpath" && test -n "$shlibpath_var" && test -n "$temp_rpath"; then
+	    if test "$shlibpath_overrides_runpath" = yes && test -n "$shlibpath_var" && test -n "$temp_rpath"; then
               func_to_host_path "$temp_rpath"
 	      cat <<EOF
 const char * LIB_PATH_VALUE   = "$func_to_host_path_result";
@@ -5706,7 +4328,7 @@ const char * EXE_PATH_VALUE   = "";
 EOF
 	    fi
 
-	    if test yes = "$fast_install"; then
+	    if test "$fast_install" = yes; then
 	      cat <<EOF
 const char * TARGET_PROGRAM_NAME = "lt-$outputname"; /* hopefully, no .exe */
 EOF
@@ -5735,12 +4357,12 @@ main (int argc, char *argv[])
   char *actual_cwrapper_name;
   char *target_name;
   char *lt_argv_zero;
-  int rval = 127;
+  intptr_t rval = 127;
 
   int i;
 
   program_name = (char *) xstrdup (base_name (argv[0]));
-  newargz = XMALLOC (char *, (size_t) argc + 1);
+  newargz = XMALLOC (char *, argc + 1);
 
   /* very simple arg parsing; don't want to rely on getopt
    * also, copy all non cwrapper options to newargz, except
@@ -5749,10 +4371,10 @@ main (int argc, char *argv[])
   newargc=0;
   for (i = 1; i < argc; i++)
     {
-      if (STREQ (argv[i], dumpscript_opt))
+      if (strcmp (argv[i], dumpscript_opt) == 0)
 	{
 EOF
-	    case $host in
+	    case "$host" in
 	      *mingw* | *cygwin* )
 		# make stdout use "unix" line endings
 		echo "          setmode(1,_O_BINARY);"
@@ -5763,12 +4385,12 @@ EOF
 	  lt_dump_script (stdout);
 	  return 0;
 	}
-      if (STREQ (argv[i], debug_opt))
+      if (strcmp (argv[i], debug_opt) == 0)
 	{
           lt_debug = 1;
           continue;
 	}
-      if (STREQ (argv[i], ltwrapper_option_prefix))
+      if (strcmp (argv[i], ltwrapper_option_prefix) == 0)
         {
           /* however, if there is an option in the LTWRAPPER_OPTION_PREFIX
              namespace, but it is not one of the ones we know about and
@@ -5791,7 +4413,7 @@ EOF
 EOF
 	    cat <<EOF
   /* The GNU banner must be the first non-error debug message */
-  lt_debugprintf (__FILE__, __LINE__, "libtool wrapper (GNU $PACKAGE) $VERSION\n");
+  lt_debugprintf (__FILE__, __LINE__, "libtool wrapper (GNU $PACKAGE$TIMESTAMP) $VERSION\n");
 EOF
 	    cat <<"EOF"
   lt_debugprintf (__FILE__, __LINE__, "(main) argv[0]: %s\n", argv[0]);
@@ -5902,7 +4524,7 @@ EOF
 		cat <<"EOF"
   /* execv doesn't actually work on mingw as expected on unix */
   newargz = prepare_spawn (newargz);
-  rval = (int) _spawnv (_P_WAIT, lt_argv_zero, (const char * const *) newargz);
+  rval = _spawnv (_P_WAIT, lt_argv_zero, (const char * const *) newargz);
   if (rval == -1)
     {
       /* failed to start process */
@@ -5947,7 +4569,7 @@ base_name (const char *name)
 {
   const char *base;
 
-#if defined HAVE_DOS_BASED_FILE_SYSTEM
+#if defined (HAVE_DOS_BASED_FILE_SYSTEM)
   /* Skip over the disk name in MSDOS pathnames. */
   if (isalpha ((unsigned char) name[0]) && name[1] == ':')
     name += 2;
@@ -6006,7 +4628,7 @@ find_executable (const char *wrapper)
   const char *p_next;
   /* static buffer for getcwd */
   char tmp[LT_PATHMAX + 1];
-  size_t tmp_len;
+  int tmp_len;
   char *concat_name;
 
   lt_debugprintf (__FILE__, __LINE__, "(find_executable): %s\n",
@@ -6016,7 +4638,7 @@ find_executable (const char *wrapper)
     return NULL;
 
   /* Absolute path? */
-#if defined HAVE_DOS_BASED_FILE_SYSTEM
+#if defined (HAVE_DOS_BASED_FILE_SYSTEM)
   if (isalpha ((unsigned char) wrapper[0]) && wrapper[1] == ':')
     {
       concat_name = xstrdup (wrapper);
@@ -6034,7 +4656,7 @@ find_executable (const char *wrapper)
 	    return concat_name;
 	  XFREE (concat_name);
 	}
-#if defined HAVE_DOS_BASED_FILE_SYSTEM
+#if defined (HAVE_DOS_BASED_FILE_SYSTEM)
     }
 #endif
 
@@ -6057,7 +4679,7 @@ find_executable (const char *wrapper)
 	      for (q = p; *q; q++)
 		if (IS_PATH_SEPARATOR (*q))
 		  break;
-	      p_len = (size_t) (q - p);
+	      p_len = q - p;
 	      p_next = (*q == '\0' ? q : q + 1);
 	      if (p_len == 0)
 		{
@@ -6176,7 +4798,7 @@ strendzap (char *str, const char *pat)
   if (patlen <= len)
     {
       str += len - patlen;
-      if (STREQ (str, pat))
+      if (strcmp (str, pat) == 0)
 	*str = '\0';
     }
   return str;
@@ -6241,7 +4863,7 @@ lt_setenv (const char *name, const char *value)
     char *str = xstrdup (value);
     setenv (name, str, 1);
 #else
-    size_t len = strlen (name) + 1 + strlen (value) + 1;
+    int len = strlen (name) + 1 + strlen (value) + 1;
     char *str = XMALLOC (char, len);
     sprintf (str, "%s=%s", name, value);
     if (putenv (str) != EXIT_SUCCESS)
@@ -6258,8 +4880,8 @@ lt_extend_str (const char *orig_value, const char *add, int to_end)
   char *new_value;
   if (orig_value && *orig_value)
     {
-      size_t orig_value_len = strlen (orig_value);
-      size_t add_len = strlen (add);
+      int orig_value_len = strlen (orig_value);
+      int add_len = strlen (add);
       new_value = XMALLOC (char, add_len + orig_value_len + 1);
       if (to_end)
         {
@@ -6290,10 +4912,10 @@ lt_update_exe_path (const char *name, const char *value)
     {
       char *new_value = lt_extend_str (getenv (name), value, 0);
       /* some systems can't cope with a ':'-terminated path #' */
-      size_t len = strlen (new_value);
-      while ((len > 0) && IS_PATH_SEPARATOR (new_value[len-1]))
+      int len = strlen (new_value);
+      while (((len = strlen (new_value)) > 0) && IS_PATH_SEPARATOR (new_value[len-1]))
         {
-          new_value[--len] = '\0';
+          new_value[len-1] = '\0';
         }
       lt_setenv (name, new_value);
       XFREE (new_value);
@@ -6460,47 +5082,27 @@ EOF
 # True if ARG is an import lib, as indicated by $file_magic_cmd
 func_win32_import_lib_p ()
 {
-    $debug_cmd
-
+    $opt_debug
     case `eval $file_magic_cmd \"\$1\" 2>/dev/null | $SED -e 10q` in
     *import*) : ;;
     *) false ;;
     esac
 }
 
-# func_suncc_cstd_abi
-# !!ONLY CALL THIS FOR SUN CC AFTER $compile_command IS FULLY EXPANDED!!
-# Several compiler flags select an ABI that is incompatible with the
-# Cstd library. Avoid specifying it if any are in CXXFLAGS.
-func_suncc_cstd_abi ()
-{
-    $debug_cmd
-
-    case " $compile_command " in
-    *" -compat=g "*|*\ -std=c++[0-9][0-9]\ *|*" -library=stdcxx4 "*|*" -library=stlport4 "*)
-      suncc_use_cstd_abi=no
-      ;;
-    *)
-      suncc_use_cstd_abi=yes
-      ;;
-    esac
-}
-
 # func_mode_link arg...
 func_mode_link ()
 {
-    $debug_cmd
-
+    $opt_debug
     case $host in
     *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*)
       # It is impossible to link a dll without this setting, and
       # we shouldn't force the makefile maintainer to figure out
-      # what system we are compiling for in order to pass an extra
+      # which system we are compiling for in order to pass an extra
       # flag for every libtool invocation.
       # allow_undefined=no
 
       # FIXME: Unfortunately, there are problems with the above when trying
-      # to make a dll that has undefined symbols, in which case not
+      # to make a dll which has undefined symbols, in which case not
       # even a static library is built.  For now, we need to specify
       # -no-undefined on the libtool link line when we can be certain
       # that all symbols are satisfied, otherwise we get a static library.
@@ -6544,11 +5146,10 @@ func_mode_link ()
     module=no
     no_install=no
     objs=
-    os2dllname=
     non_pic_objects=
     precious_files_regex=
     prefer_static_libs=no
-    preload=false
+    preload=no
     prev=
     prevarg=
     release=
@@ -6560,7 +5161,7 @@ func_mode_link ()
     vinfo=
     vinfo_number=no
     weak_libs=
-    single_module=$wl-single_module
+    single_module="${wl}-single_module"
     func_infer_tag $base_compile
 
     # We need to know -static, to get the right output filenames.
@@ -6568,15 +5169,15 @@ func_mode_link ()
     do
       case $arg in
       -shared)
-	test yes != "$build_libtool_libs" \
-	  && func_fatal_configuration "cannot build a shared library"
+	test "$build_libtool_libs" != yes && \
+	  func_fatal_configuration "can not build a shared library"
 	build_old_libs=no
 	break
 	;;
       -all-static | -static | -static-libtool-libs)
 	case $arg in
 	-all-static)
-	  if test yes = "$build_libtool_libs" && test -z "$link_static_flag"; then
+	  if test "$build_libtool_libs" = yes && test -z "$link_static_flag"; then
 	    func_warning "complete static linking is impossible in this configuration"
 	  fi
 	  if test -n "$link_static_flag"; then
@@ -6609,7 +5210,7 @@ func_mode_link ()
 
     # Go through the arguments, transforming them on the way.
     while test "$#" -gt 0; do
-      arg=$1
+      arg="$1"
       shift
       func_quote_for_eval "$arg"
       qarg=$func_quote_for_eval_unquoted_result
@@ -6626,21 +5227,21 @@ func_mode_link ()
 
 	case $prev in
 	bindir)
-	  bindir=$arg
+	  bindir="$arg"
 	  prev=
 	  continue
 	  ;;
 	dlfiles|dlprefiles)
-	  $preload || {
+	  if test "$preload" = no; then
 	    # Add the symbol object into the linking commands.
 	    func_append compile_command " @SYMFILE@"
 	    func_append finalize_command " @SYMFILE@"
-	    preload=:
-	  }
+	    preload=yes
+	  fi
 	  case $arg in
 	  *.la | *.lo) ;;  # We handle these cases below.
 	  force)
-	    if test no = "$dlself"; then
+	    if test "$dlself" = no; then
 	      dlself=needless
 	      export_dynamic=yes
 	    fi
@@ -6648,9 +5249,9 @@ func_mode_link ()
 	    continue
 	    ;;
 	  self)
-	    if test dlprefiles = "$prev"; then
+	    if test "$prev" = dlprefiles; then
 	      dlself=yes
-	    elif test dlfiles = "$prev" && test yes != "$dlopen_self"; then
+	    elif test "$prev" = dlfiles && test "$dlopen_self" != yes; then
 	      dlself=yes
 	    else
 	      dlself=needless
@@ -6660,7 +5261,7 @@ func_mode_link ()
 	    continue
 	    ;;
 	  *)
-	    if test dlfiles = "$prev"; then
+	    if test "$prev" = dlfiles; then
 	      func_append dlfiles " $arg"
 	    else
 	      func_append dlprefiles " $arg"
@@ -6671,14 +5272,14 @@ func_mode_link ()
 	  esac
 	  ;;
 	expsyms)
-	  export_symbols=$arg
+	  export_symbols="$arg"
 	  test -f "$arg" \
-	    || func_fatal_error "symbol file '$arg' does not exist"
+	    || func_fatal_error "symbol file \`$arg' does not exist"
 	  prev=
 	  continue
 	  ;;
 	expsyms_regex)
-	  export_symbols_regex=$arg
+	  export_symbols_regex="$arg"
 	  prev=
 	  continue
 	  ;;
@@ -6696,13 +5297,7 @@ func_mode_link ()
 	  continue
 	  ;;
 	inst_prefix)
-	  inst_prefix_dir=$arg
-	  prev=
-	  continue
-	  ;;
-	mllvm)
-	  # Clang does not use LLVM to link, so we can simply discard any
-	  # '-mllvm $arg' options when doing the link step.
+	  inst_prefix_dir="$arg"
 	  prev=
 	  continue
 	  ;;
@@ -6726,21 +5321,21 @@ func_mode_link ()
 
 		if test -z "$pic_object" ||
 		   test -z "$non_pic_object" ||
-		   test none = "$pic_object" &&
-		   test none = "$non_pic_object"; then
-		  func_fatal_error "cannot find name of object for '$arg'"
+		   test "$pic_object" = none &&
+		   test "$non_pic_object" = none; then
+		  func_fatal_error "cannot find name of object for \`$arg'"
 		fi
 
 		# Extract subdirectory from the argument.
 		func_dirname "$arg" "/" ""
-		xdir=$func_dirname_result
+		xdir="$func_dirname_result"
 
-		if test none != "$pic_object"; then
+		if test "$pic_object" != none; then
 		  # Prepend the subdirectory the object is found in.
-		  pic_object=$xdir$pic_object
+		  pic_object="$xdir$pic_object"
 
-		  if test dlfiles = "$prev"; then
-		    if test yes = "$build_libtool_libs" && test yes = "$dlopen_support"; then
+		  if test "$prev" = dlfiles; then
+		    if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then
 		      func_append dlfiles " $pic_object"
 		      prev=
 		      continue
@@ -6751,7 +5346,7 @@ func_mode_link ()
 		  fi
 
 		  # CHECK ME:  I think I busted this.  -Ossama
-		  if test dlprefiles = "$prev"; then
+		  if test "$prev" = dlprefiles; then
 		    # Preload the old-style object.
 		    func_append dlprefiles " $pic_object"
 		    prev=
@@ -6759,23 +5354,23 @@ func_mode_link ()
 
 		  # A PIC object.
 		  func_append libobjs " $pic_object"
-		  arg=$pic_object
+		  arg="$pic_object"
 		fi
 
 		# Non-PIC object.
-		if test none != "$non_pic_object"; then
+		if test "$non_pic_object" != none; then
 		  # Prepend the subdirectory the object is found in.
-		  non_pic_object=$xdir$non_pic_object
+		  non_pic_object="$xdir$non_pic_object"
 
 		  # A standard non-PIC object
 		  func_append non_pic_objects " $non_pic_object"
-		  if test -z "$pic_object" || test none = "$pic_object"; then
-		    arg=$non_pic_object
+		  if test -z "$pic_object" || test "$pic_object" = none ; then
+		    arg="$non_pic_object"
 		  fi
 		else
 		  # If the PIC object exists, use it instead.
 		  # $xdir was prepended to $pic_object above.
-		  non_pic_object=$pic_object
+		  non_pic_object="$pic_object"
 		  func_append non_pic_objects " $non_pic_object"
 		fi
 	      else
@@ -6783,7 +5378,7 @@ func_mode_link ()
 		if $opt_dry_run; then
 		  # Extract subdirectory from the argument.
 		  func_dirname "$arg" "/" ""
-		  xdir=$func_dirname_result
+		  xdir="$func_dirname_result"
 
 		  func_lo2o "$arg"
 		  pic_object=$xdir$objdir/$func_lo2o_result
@@ -6791,29 +5386,24 @@ func_mode_link ()
 		  func_append libobjs " $pic_object"
 		  func_append non_pic_objects " $non_pic_object"
 	        else
-		  func_fatal_error "'$arg' is not a valid libtool object"
+		  func_fatal_error "\`$arg' is not a valid libtool object"
 		fi
 	      fi
 	    done
 	  else
-	    func_fatal_error "link input file '$arg' does not exist"
+	    func_fatal_error "link input file \`$arg' does not exist"
 	  fi
 	  arg=$save_arg
 	  prev=
 	  continue
 	  ;;
-	os2dllname)
-	  os2dllname=$arg
-	  prev=
-	  continue
-	  ;;
 	precious_regex)
-	  precious_files_regex=$arg
+	  precious_files_regex="$arg"
 	  prev=
 	  continue
 	  ;;
 	release)
-	  release=-$arg
+	  release="-$arg"
 	  prev=
 	  continue
 	  ;;
@@ -6825,7 +5415,7 @@ func_mode_link ()
 	    func_fatal_error "only absolute run-paths are allowed"
 	    ;;
 	  esac
-	  if test rpath = "$prev"; then
+	  if test "$prev" = rpath; then
 	    case "$rpath " in
 	    *" $arg "*) ;;
 	    *) func_append rpath " $arg" ;;
@@ -6840,7 +5430,7 @@ func_mode_link ()
 	  continue
 	  ;;
 	shrext)
-	  shrext_cmds=$arg
+	  shrext_cmds="$arg"
 	  prev=
 	  continue
 	  ;;
@@ -6880,7 +5470,7 @@ func_mode_link ()
 	esac
       fi # test -n "$prev"
 
-      prevarg=$arg
+      prevarg="$arg"
 
       case $arg in
       -all-static)
@@ -6894,7 +5484,7 @@ func_mode_link ()
 
       -allow-undefined)
 	# FIXME: remove this flag sometime in the future.
-	func_fatal_error "'-allow-undefined' must not be used because it is the default"
+	func_fatal_error "\`-allow-undefined' must not be used because it is the default"
 	;;
 
       -avoid-version)
@@ -6926,7 +5516,7 @@ func_mode_link ()
 	if test -n "$export_symbols" || test -n "$export_symbols_regex"; then
 	  func_fatal_error "more than one -exported-symbols argument is not allowed"
 	fi
-	if test X-export-symbols = "X$arg"; then
+	if test "X$arg" = "X-export-symbols"; then
 	  prev=expsyms
 	else
 	  prev=expsyms_regex
@@ -6960,9 +5550,9 @@ func_mode_link ()
 	func_stripname "-L" '' "$arg"
 	if test -z "$func_stripname_result"; then
 	  if test "$#" -gt 0; then
-	    func_fatal_error "require no space between '-L' and '$1'"
+	    func_fatal_error "require no space between \`-L' and \`$1'"
 	  else
-	    func_fatal_error "need path for '-L' option"
+	    func_fatal_error "need path for \`-L' option"
 	  fi
 	fi
 	func_resolve_sysroot "$func_stripname_result"
@@ -6973,8 +5563,8 @@ func_mode_link ()
 	*)
 	  absdir=`cd "$dir" && pwd`
 	  test -z "$absdir" && \
-	    func_fatal_error "cannot determine absolute directory name of '$dir'"
-	  dir=$absdir
+	    func_fatal_error "cannot determine absolute directory name of \`$dir'"
+	  dir="$absdir"
 	  ;;
 	esac
 	case "$deplibs " in
@@ -7009,7 +5599,7 @@ func_mode_link ()
 	;;
 
       -l*)
-	if test X-lc = "X$arg" || test X-lm = "X$arg"; then
+	if test "X$arg" = "X-lc" || test "X$arg" = "X-lm"; then
 	  case $host in
 	  *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-beos* | *-cegcc* | *-*-haiku*)
 	    # These systems don't actually have a C or math library (as such)
@@ -7017,11 +5607,11 @@ func_mode_link ()
 	    ;;
 	  *-*-os2*)
 	    # These systems don't actually have a C library (as such)
-	    test X-lc = "X$arg" && continue
+	    test "X$arg" = "X-lc" && continue
 	    ;;
-	  *-*-openbsd* | *-*-freebsd* | *-*-dragonfly* | *-*-bitrig*)
+	  *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*)
 	    # Do not include libc due to us having libc/libc_r.
-	    test X-lc = "X$arg" && continue
+	    test "X$arg" = "X-lc" && continue
 	    ;;
 	  *-*-rhapsody* | *-*-darwin1.[012])
 	    # Rhapsody C and math libraries are in the System framework
@@ -7030,16 +5620,16 @@ func_mode_link ()
 	    ;;
 	  *-*-sco3.2v5* | *-*-sco5v6*)
 	    # Causes problems with __ctype
-	    test X-lc = "X$arg" && continue
+	    test "X$arg" = "X-lc" && continue
 	    ;;
 	  *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*)
 	    # Compiler inserts libc in the correct place for threads to work
-	    test X-lc = "X$arg" && continue
+	    test "X$arg" = "X-lc" && continue
 	    ;;
 	  esac
-	elif test X-lc_r = "X$arg"; then
+	elif test "X$arg" = "X-lc_r"; then
 	 case $host in
-	 *-*-openbsd* | *-*-freebsd* | *-*-dragonfly* | *-*-bitrig*)
+	 *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*)
 	   # Do not include libc_r directly, use -pthread flag.
 	   continue
 	   ;;
@@ -7049,11 +5639,6 @@ func_mode_link ()
 	continue
 	;;
 
-      -mllvm)
-	prev=mllvm
-	continue
-	;;
-
       -module)
 	module=yes
 	continue
@@ -7083,7 +5668,7 @@ func_mode_link ()
 	;;
 
       -multi_module)
-	single_module=$wl-multi_module
+	single_module="${wl}-multi_module"
 	continue
 	;;
 
@@ -7097,8 +5682,8 @@ func_mode_link ()
 	*-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-darwin* | *-cegcc*)
 	  # The PATH hackery in wrapper scripts is required on Windows
 	  # and Darwin in order for the loader to find any dlls it needs.
-	  func_warning "'-no-install' is ignored for $host"
-	  func_warning "assuming '-no-fast-install' instead"
+	  func_warning "\`-no-install' is ignored for $host"
+	  func_warning "assuming \`-no-fast-install' instead"
 	  fast_install=no
 	  ;;
 	*) no_install=yes ;;
@@ -7116,11 +5701,6 @@ func_mode_link ()
 	continue
 	;;
 
-      -os2dllname)
-	prev=os2dllname
-	continue
-	;;
-
       -o) prev=output ;;
 
       -precious-files-regex)
@@ -7208,14 +5788,14 @@ func_mode_link ()
 	func_stripname '-Wc,' '' "$arg"
 	args=$func_stripname_result
 	arg=
-	save_ifs=$IFS; IFS=,
+	save_ifs="$IFS"; IFS=','
 	for flag in $args; do
-	  IFS=$save_ifs
+	  IFS="$save_ifs"
           func_quote_for_eval "$flag"
 	  func_append arg " $func_quote_for_eval_result"
 	  func_append compiler_flags " $func_quote_for_eval_result"
 	done
-	IFS=$save_ifs
+	IFS="$save_ifs"
 	func_stripname ' ' '' "$arg"
 	arg=$func_stripname_result
 	;;
@@ -7224,15 +5804,15 @@ func_mode_link ()
 	func_stripname '-Wl,' '' "$arg"
 	args=$func_stripname_result
 	arg=
-	save_ifs=$IFS; IFS=,
+	save_ifs="$IFS"; IFS=','
 	for flag in $args; do
-	  IFS=$save_ifs
+	  IFS="$save_ifs"
           func_quote_for_eval "$flag"
 	  func_append arg " $wl$func_quote_for_eval_result"
 	  func_append compiler_flags " $wl$func_quote_for_eval_result"
 	  func_append linker_flags " $func_quote_for_eval_result"
 	done
-	IFS=$save_ifs
+	IFS="$save_ifs"
 	func_stripname ' ' '' "$arg"
 	arg=$func_stripname_result
 	;;
@@ -7255,7 +5835,7 @@ func_mode_link ()
       # -msg_* for osf cc
       -msg_*)
 	func_quote_for_eval "$arg"
-	arg=$func_quote_for_eval_result
+	arg="$func_quote_for_eval_result"
 	;;
 
       # Flags to be passed through unchanged, with rationale:
@@ -7267,49 +5847,25 @@ func_mode_link ()
       # -m*, -t[45]*, -txscale* architecture-specific flags for GCC
       # -F/path              path to uninstalled frameworks, gcc on darwin
       # -p, -pg, --coverage, -fprofile-*  profiling flags for GCC
-      # -fstack-protector*   stack protector flags for GCC
       # @file                GCC response files
       # -tp=*                Portland pgcc target processor selection
       # --sysroot=*          for sysroot support
-      # -O*, -g*, -flto*, -fwhopr*, -fuse-linker-plugin GCC link-time optimization
-      # -specs=*             GCC specs files
-      # -stdlib=*            select c++ std lib with clang
-      # -fsanitize=*         Clang/GCC memory and address sanitizer
+      # -O*, -flto*, -fwhopr*, -fuse-linker-plugin GCC link-time optimization
       -64|-mips[0-9]|-r[0-9][0-9]*|-xarch=*|-xtarget=*|+DA*|+DD*|-q*|-m*| \
       -t[45]*|-txscale*|-p|-pg|--coverage|-fprofile-*|-F*|@*|-tp=*|--sysroot=*| \
-      -O*|-g*|-flto*|-fwhopr*|-fuse-linker-plugin|-fstack-protector*|-stdlib=*| \
-      -specs=*|-fsanitize=*)
+      -O*|-flto*|-fwhopr*|-fuse-linker-plugin)
         func_quote_for_eval "$arg"
-	arg=$func_quote_for_eval_result
+	arg="$func_quote_for_eval_result"
         func_append compile_command " $arg"
         func_append finalize_command " $arg"
         func_append compiler_flags " $arg"
         continue
         ;;
 
-      -Z*)
-        if test os2 = "`expr $host : '.*\(os2\)'`"; then
-          # OS/2 uses -Zxxx to specify OS/2-specific options
-	  compiler_flags="$compiler_flags $arg"
-	  func_append compile_command " $arg"
-	  func_append finalize_command " $arg"
-	  case $arg in
-	  -Zlinker | -Zstack)
-	    prev=xcompiler
-	    ;;
-	  esac
-	  continue
-        else
-	  # Otherwise treat like 'Some other compiler flag' below
-	  func_quote_for_eval "$arg"
-	  arg=$func_quote_for_eval_result
-        fi
-	;;
-
       # Some other compiler flag.
       -* | +*)
         func_quote_for_eval "$arg"
-	arg=$func_quote_for_eval_result
+	arg="$func_quote_for_eval_result"
 	;;
 
       *.$objext)
@@ -7330,21 +5886,21 @@ func_mode_link ()
 
 	  if test -z "$pic_object" ||
 	     test -z "$non_pic_object" ||
-	     test none = "$pic_object" &&
-	     test none = "$non_pic_object"; then
-	    func_fatal_error "cannot find name of object for '$arg'"
+	     test "$pic_object" = none &&
+	     test "$non_pic_object" = none; then
+	    func_fatal_error "cannot find name of object for \`$arg'"
 	  fi
 
 	  # Extract subdirectory from the argument.
 	  func_dirname "$arg" "/" ""
-	  xdir=$func_dirname_result
+	  xdir="$func_dirname_result"
 
-	  test none = "$pic_object" || {
+	  if test "$pic_object" != none; then
 	    # Prepend the subdirectory the object is found in.
-	    pic_object=$xdir$pic_object
+	    pic_object="$xdir$pic_object"
 
-	    if test dlfiles = "$prev"; then
-	      if test yes = "$build_libtool_libs" && test yes = "$dlopen_support"; then
+	    if test "$prev" = dlfiles; then
+	      if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then
 		func_append dlfiles " $pic_object"
 		prev=
 		continue
@@ -7355,7 +5911,7 @@ func_mode_link ()
 	    fi
 
 	    # CHECK ME:  I think I busted this.  -Ossama
-	    if test dlprefiles = "$prev"; then
+	    if test "$prev" = dlprefiles; then
 	      # Preload the old-style object.
 	      func_append dlprefiles " $pic_object"
 	      prev=
@@ -7363,23 +5919,23 @@ func_mode_link ()
 
 	    # A PIC object.
 	    func_append libobjs " $pic_object"
-	    arg=$pic_object
-	  }
+	    arg="$pic_object"
+	  fi
 
 	  # Non-PIC object.
-	  if test none != "$non_pic_object"; then
+	  if test "$non_pic_object" != none; then
 	    # Prepend the subdirectory the object is found in.
-	    non_pic_object=$xdir$non_pic_object
+	    non_pic_object="$xdir$non_pic_object"
 
 	    # A standard non-PIC object
 	    func_append non_pic_objects " $non_pic_object"
-	    if test -z "$pic_object" || test none = "$pic_object"; then
-	      arg=$non_pic_object
+	    if test -z "$pic_object" || test "$pic_object" = none ; then
+	      arg="$non_pic_object"
 	    fi
 	  else
 	    # If the PIC object exists, use it instead.
 	    # $xdir was prepended to $pic_object above.
-	    non_pic_object=$pic_object
+	    non_pic_object="$pic_object"
 	    func_append non_pic_objects " $non_pic_object"
 	  fi
 	else
@@ -7387,7 +5943,7 @@ func_mode_link ()
 	  if $opt_dry_run; then
 	    # Extract subdirectory from the argument.
 	    func_dirname "$arg" "/" ""
-	    xdir=$func_dirname_result
+	    xdir="$func_dirname_result"
 
 	    func_lo2o "$arg"
 	    pic_object=$xdir$objdir/$func_lo2o_result
@@ -7395,7 +5951,7 @@ func_mode_link ()
 	    func_append libobjs " $pic_object"
 	    func_append non_pic_objects " $non_pic_object"
 	  else
-	    func_fatal_error "'$arg' is not a valid libtool object"
+	    func_fatal_error "\`$arg' is not a valid libtool object"
 	  fi
 	fi
 	;;
@@ -7411,11 +5967,11 @@ func_mode_link ()
 	# A libtool-controlled library.
 
 	func_resolve_sysroot "$arg"
-	if test dlfiles = "$prev"; then
+	if test "$prev" = dlfiles; then
 	  # This library was specified with -dlopen.
 	  func_append dlfiles " $func_resolve_sysroot_result"
 	  prev=
-	elif test dlprefiles = "$prev"; then
+	elif test "$prev" = dlprefiles; then
 	  # The library was specified with -dlpreopen.
 	  func_append dlprefiles " $func_resolve_sysroot_result"
 	  prev=
@@ -7430,7 +5986,7 @@ func_mode_link ()
 	# Unknown arguments in both finalize_command and compile_command need
 	# to be aesthetically quoted because they are evaled later.
 	func_quote_for_eval "$arg"
-	arg=$func_quote_for_eval_result
+	arg="$func_quote_for_eval_result"
 	;;
       esac # arg
 
@@ -7442,9 +5998,9 @@ func_mode_link ()
     done # argument parsing loop
 
     test -n "$prev" && \
-      func_fatal_help "the '$prevarg' option requires an argument"
+      func_fatal_help "the \`$prevarg' option requires an argument"
 
-    if test yes = "$export_dynamic" && test -n "$export_dynamic_flag_spec"; then
+    if test "$export_dynamic" = yes && test -n "$export_dynamic_flag_spec"; then
       eval arg=\"$export_dynamic_flag_spec\"
       func_append compile_command " $arg"
       func_append finalize_command " $arg"
@@ -7453,23 +6009,20 @@ func_mode_link ()
     oldlibs=
     # calculate the name of the file, without its directory
     func_basename "$output"
-    outputname=$func_basename_result
-    libobjs_save=$libobjs
+    outputname="$func_basename_result"
+    libobjs_save="$libobjs"
 
     if test -n "$shlibpath_var"; then
       # get the directories listed in $shlibpath_var
-      eval shlib_search_path=\`\$ECHO \"\$$shlibpath_var\" \| \$SED \'s/:/ /g\'\`
+      eval shlib_search_path=\`\$ECHO \"\${$shlibpath_var}\" \| \$SED \'s/:/ /g\'\`
     else
       shlib_search_path=
     fi
     eval sys_lib_search_path=\"$sys_lib_search_path_spec\"
     eval sys_lib_dlsearch_path=\"$sys_lib_dlsearch_path_spec\"
 
-    # Definition is injected by LT_CONFIG during libtool generation.
-    func_munge_path_list sys_lib_dlsearch_path "$LT_SYS_LIBRARY_PATH"
-
     func_dirname "$output" "/" ""
-    output_objdir=$func_dirname_result$objdir
+    output_objdir="$func_dirname_result$objdir"
     func_to_tool_file "$output_objdir/"
     tool_output_objdir=$func_to_tool_file_result
     # Create the object directory.
@@ -7492,7 +6045,7 @@ func_mode_link ()
     # Find all interdependent deplibs by searching for libraries
     # that are linked more than once (e.g. -la -lb -la)
     for deplib in $deplibs; do
-      if $opt_preserve_dup_deps; then
+      if $opt_preserve_dup_deps ; then
 	case "$libs " in
 	*" $deplib "*) func_append specialdeplibs " $deplib" ;;
 	esac
@@ -7500,7 +6053,7 @@ func_mode_link ()
       func_append libs " $deplib"
     done
 
-    if test lib = "$linkmode"; then
+    if test "$linkmode" = lib; then
       libs="$predeps $libs $compiler_lib_search_path $postdeps"
 
       # Compute libraries that are listed more than once in $predeps
@@ -7532,7 +6085,7 @@ func_mode_link ()
 	  case $file in
 	  *.la) ;;
 	  *)
-	    func_fatal_help "libraries can '-dlopen' only libtool libraries: $file"
+	    func_fatal_help "libraries can \`-dlopen' only libtool libraries: $file"
 	    ;;
 	  esac
 	done
@@ -7540,7 +6093,7 @@ func_mode_link ()
     prog)
 	compile_deplibs=
 	finalize_deplibs=
-	alldeplibs=false
+	alldeplibs=no
 	newdlfiles=
 	newdlprefiles=
 	passes="conv scan dlopen dlpreopen link"
@@ -7552,32 +6105,32 @@ func_mode_link ()
     for pass in $passes; do
       # The preopen pass in lib mode reverses $deplibs; put it back here
       # so that -L comes before libs that need it for instance...
-      if test lib,link = "$linkmode,$pass"; then
+      if test "$linkmode,$pass" = "lib,link"; then
 	## FIXME: Find the place where the list is rebuilt in the wrong
 	##        order, and fix it there properly
         tmp_deplibs=
 	for deplib in $deplibs; do
 	  tmp_deplibs="$deplib $tmp_deplibs"
 	done
-	deplibs=$tmp_deplibs
+	deplibs="$tmp_deplibs"
       fi
 
-      if test lib,link = "$linkmode,$pass" ||
-	 test prog,scan = "$linkmode,$pass"; then
-	libs=$deplibs
+      if test "$linkmode,$pass" = "lib,link" ||
+	 test "$linkmode,$pass" = "prog,scan"; then
+	libs="$deplibs"
 	deplibs=
       fi
-      if test prog = "$linkmode"; then
+      if test "$linkmode" = prog; then
 	case $pass in
-	dlopen) libs=$dlfiles ;;
-	dlpreopen) libs=$dlprefiles ;;
+	dlopen) libs="$dlfiles" ;;
+	dlpreopen) libs="$dlprefiles" ;;
 	link)
 	  libs="$deplibs %DEPLIBS%"
 	  test "X$link_all_deplibs" != Xno && libs="$libs $dependency_libs"
 	  ;;
 	esac
       fi
-      if test lib,dlpreopen = "$linkmode,$pass"; then
+      if test "$linkmode,$pass" = "lib,dlpreopen"; then
 	# Collect and forward deplibs of preopened libtool libs
 	for lib in $dlprefiles; do
 	  # Ignore non-libtool-libs
@@ -7598,26 +6151,26 @@ func_mode_link ()
 	    esac
 	  done
 	done
-	libs=$dlprefiles
+	libs="$dlprefiles"
       fi
-      if test dlopen = "$pass"; then
+      if test "$pass" = dlopen; then
 	# Collect dlpreopened libraries
-	save_deplibs=$deplibs
+	save_deplibs="$deplibs"
 	deplibs=
       fi
 
       for deplib in $libs; do
 	lib=
-	found=false
+	found=no
 	case $deplib in
 	-mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe \
         |-threads|-fopenmp|-openmp|-mp|-xopenmp|-omp|-qsmp=*)
-	  if test prog,link = "$linkmode,$pass"; then
+	  if test "$linkmode,$pass" = "prog,link"; then
 	    compile_deplibs="$deplib $compile_deplibs"
 	    finalize_deplibs="$deplib $finalize_deplibs"
 	  else
 	    func_append compiler_flags " $deplib"
-	    if test lib = "$linkmode"; then
+	    if test "$linkmode" = lib ; then
 		case "$new_inherited_linker_flags " in
 		    *" $deplib "*) ;;
 		    * ) func_append new_inherited_linker_flags " $deplib" ;;
@@ -7627,13 +6180,13 @@ func_mode_link ()
 	  continue
 	  ;;
 	-l*)
-	  if test lib != "$linkmode" && test prog != "$linkmode"; then
-	    func_warning "'-l' is ignored for archives/objects"
+	  if test "$linkmode" != lib && test "$linkmode" != prog; then
+	    func_warning "\`-l' is ignored for archives/objects"
 	    continue
 	  fi
 	  func_stripname '-l' '' "$deplib"
 	  name=$func_stripname_result
-	  if test lib = "$linkmode"; then
+	  if test "$linkmode" = lib; then
 	    searchdirs="$newlib_search_path $lib_search_path $compiler_lib_search_dirs $sys_lib_search_path $shlib_search_path"
 	  else
 	    searchdirs="$newlib_search_path $lib_search_path $sys_lib_search_path $shlib_search_path"
@@ -7641,22 +6194,31 @@ func_mode_link ()
 	  for searchdir in $searchdirs; do
 	    for search_ext in .la $std_shrext .so .a; do
 	      # Search the libtool library
-	      lib=$searchdir/lib$name$search_ext
+	      lib="$searchdir/lib${name}${search_ext}"
 	      if test -f "$lib"; then
-		if test .la = "$search_ext"; then
-		  found=:
+		if test "$search_ext" = ".la"; then
+		  found=yes
 		else
-		  found=false
+		  found=no
 		fi
 		break 2
 	      fi
 	    done
 	  done
-	  if $found; then
-	    # deplib is a libtool library
+	  if test "$found" != yes; then
+	    # deplib doesn't seem to be a libtool library
+	    if test "$linkmode,$pass" = "prog,link"; then
+	      compile_deplibs="$deplib $compile_deplibs"
+	      finalize_deplibs="$deplib $finalize_deplibs"
+	    else
+	      deplibs="$deplib $deplibs"
+	      test "$linkmode" = lib && newdependency_libs="$deplib $newdependency_libs"
+	    fi
+	    continue
+	  else # deplib is a libtool library
 	    # If $allow_libtool_libs_with_static_runtimes && $deplib is a stdlib,
 	    # We need to do some special things here, and not later.
-	    if test yes = "$allow_libtool_libs_with_static_runtimes"; then
+	    if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
 	      case " $predeps $postdeps " in
 	      *" $deplib "*)
 		if func_lalib_p "$lib"; then
@@ -7664,19 +6226,19 @@ func_mode_link ()
 		  old_library=
 		  func_source "$lib"
 		  for l in $old_library $library_names; do
-		    ll=$l
+		    ll="$l"
 		  done
-		  if test "X$ll" = "X$old_library"; then # only static version available
-		    found=false
+		  if test "X$ll" = "X$old_library" ; then # only static version available
+		    found=no
 		    func_dirname "$lib" "" "."
-		    ladir=$func_dirname_result
+		    ladir="$func_dirname_result"
 		    lib=$ladir/$old_library
-		    if test prog,link = "$linkmode,$pass"; then
+		    if test "$linkmode,$pass" = "prog,link"; then
 		      compile_deplibs="$deplib $compile_deplibs"
 		      finalize_deplibs="$deplib $finalize_deplibs"
 		    else
 		      deplibs="$deplib $deplibs"
-		      test lib = "$linkmode" && newdependency_libs="$deplib $newdependency_libs"
+		      test "$linkmode" = lib && newdependency_libs="$deplib $newdependency_libs"
 		    fi
 		    continue
 		  fi
@@ -7685,25 +6247,15 @@ func_mode_link ()
 	      *) ;;
 	      esac
 	    fi
-	  else
-	    # deplib doesn't seem to be a libtool library
-	    if test prog,link = "$linkmode,$pass"; then
-	      compile_deplibs="$deplib $compile_deplibs"
-	      finalize_deplibs="$deplib $finalize_deplibs"
-	    else
-	      deplibs="$deplib $deplibs"
-	      test lib = "$linkmode" && newdependency_libs="$deplib $newdependency_libs"
-	    fi
-	    continue
 	  fi
 	  ;; # -l
 	*.ltframework)
-	  if test prog,link = "$linkmode,$pass"; then
+	  if test "$linkmode,$pass" = "prog,link"; then
 	    compile_deplibs="$deplib $compile_deplibs"
 	    finalize_deplibs="$deplib $finalize_deplibs"
 	  else
 	    deplibs="$deplib $deplibs"
-	    if test lib = "$linkmode"; then
+	    if test "$linkmode" = lib ; then
 		case "$new_inherited_linker_flags " in
 		    *" $deplib "*) ;;
 		    * ) func_append new_inherited_linker_flags " $deplib" ;;
@@ -7716,18 +6268,18 @@ func_mode_link ()
 	  case $linkmode in
 	  lib)
 	    deplibs="$deplib $deplibs"
-	    test conv = "$pass" && continue
+	    test "$pass" = conv && continue
 	    newdependency_libs="$deplib $newdependency_libs"
 	    func_stripname '-L' '' "$deplib"
 	    func_resolve_sysroot "$func_stripname_result"
 	    func_append newlib_search_path " $func_resolve_sysroot_result"
 	    ;;
 	  prog)
-	    if test conv = "$pass"; then
+	    if test "$pass" = conv; then
 	      deplibs="$deplib $deplibs"
 	      continue
 	    fi
-	    if test scan = "$pass"; then
+	    if test "$pass" = scan; then
 	      deplibs="$deplib $deplibs"
 	    else
 	      compile_deplibs="$deplib $compile_deplibs"
@@ -7738,13 +6290,13 @@ func_mode_link ()
 	    func_append newlib_search_path " $func_resolve_sysroot_result"
 	    ;;
 	  *)
-	    func_warning "'-L' is ignored for archives/objects"
+	    func_warning "\`-L' is ignored for archives/objects"
 	    ;;
 	  esac # linkmode
 	  continue
 	  ;; # -L
 	-R*)
-	  if test link = "$pass"; then
+	  if test "$pass" = link; then
 	    func_stripname '-R' '' "$deplib"
 	    func_resolve_sysroot "$func_stripname_result"
 	    dir=$func_resolve_sysroot_result
@@ -7762,7 +6314,7 @@ func_mode_link ()
 	  lib=$func_resolve_sysroot_result
 	  ;;
 	*.$libext)
-	  if test conv = "$pass"; then
+	  if test "$pass" = conv; then
 	    deplibs="$deplib $deplibs"
 	    continue
 	  fi
@@ -7773,26 +6325,21 @@ func_mode_link ()
 	    case " $dlpreconveniencelibs " in
 	    *" $deplib "*) ;;
 	    *)
-	      valid_a_lib=false
+	      valid_a_lib=no
 	      case $deplibs_check_method in
 		match_pattern*)
 		  set dummy $deplibs_check_method; shift
 		  match_pattern_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"`
 		  if eval "\$ECHO \"$deplib\"" 2>/dev/null | $SED 10q \
 		    | $EGREP "$match_pattern_regex" > /dev/null; then
-		    valid_a_lib=:
+		    valid_a_lib=yes
 		  fi
 		;;
 		pass_all)
-		  valid_a_lib=:
+		  valid_a_lib=yes
 		;;
 	      esac
-	      if $valid_a_lib; then
-		echo
-		$ECHO "*** Warning: Linking the shared library $output against the"
-		$ECHO "*** static library $deplib is not portable!"
-		deplibs="$deplib $deplibs"
-	      else
+	      if test "$valid_a_lib" != yes; then
 		echo
 		$ECHO "*** Warning: Trying to link with static lib archive $deplib."
 		echo "*** I have the capability to make that library automatically link in when"
@@ -7800,13 +6347,18 @@ func_mode_link ()
 		echo "*** shared version of the library, which you do not appear to have"
 		echo "*** because the file extensions .$libext of this argument makes me believe"
 		echo "*** that it is just a static archive that I should not use here."
+	      else
+		echo
+		$ECHO "*** Warning: Linking the shared library $output against the"
+		$ECHO "*** static library $deplib is not portable!"
+		deplibs="$deplib $deplibs"
 	      fi
 	      ;;
 	    esac
 	    continue
 	    ;;
 	  prog)
-	    if test link != "$pass"; then
+	    if test "$pass" != link; then
 	      deplibs="$deplib $deplibs"
 	    else
 	      compile_deplibs="$deplib $compile_deplibs"
@@ -7817,10 +6369,10 @@ func_mode_link ()
 	  esac # linkmode
 	  ;; # *.$libext
 	*.lo | *.$objext)
-	  if test conv = "$pass"; then
+	  if test "$pass" = conv; then
 	    deplibs="$deplib $deplibs"
-	  elif test prog = "$linkmode"; then
-	    if test dlpreopen = "$pass" || test yes != "$dlopen_support" || test no = "$build_libtool_libs"; then
+	  elif test "$linkmode" = prog; then
+	    if test "$pass" = dlpreopen || test "$dlopen_support" != yes || test "$build_libtool_libs" = no; then
 	      # If there is no dlopen support or we're linking statically,
 	      # we need to preload.
 	      func_append newdlprefiles " $deplib"
@@ -7833,20 +6385,22 @@ func_mode_link ()
 	  continue
 	  ;;
 	%DEPLIBS%)
-	  alldeplibs=:
+	  alldeplibs=yes
 	  continue
 	  ;;
 	esac # case $deplib
 
-	$found || test -f "$lib" \
-	  || func_fatal_error "cannot find the library '$lib' or unhandled argument '$deplib'"
+	if test "$found" = yes || test -f "$lib"; then :
+	else
+	  func_fatal_error "cannot find the library \`$lib' or unhandled argument \`$deplib'"
+	fi
 
 	# Check to see that this really is a libtool archive.
 	func_lalib_unsafe_p "$lib" \
-	  || func_fatal_error "'$lib' is not a valid libtool archive"
+	  || func_fatal_error "\`$lib' is not a valid libtool archive"
 
 	func_dirname "$lib" "" "."
-	ladir=$func_dirname_result
+	ladir="$func_dirname_result"
 
 	dlname=
 	dlopen=
@@ -7876,19 +6430,19 @@ func_mode_link ()
 	  done
 	fi
 	dependency_libs=`$ECHO " $dependency_libs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'`
-	if test lib,link = "$linkmode,$pass" ||
-	   test prog,scan = "$linkmode,$pass" ||
-	   { test prog != "$linkmode" && test lib != "$linkmode"; }; then
+	if test "$linkmode,$pass" = "lib,link" ||
+	   test "$linkmode,$pass" = "prog,scan" ||
+	   { test "$linkmode" != prog && test "$linkmode" != lib; }; then
 	  test -n "$dlopen" && func_append dlfiles " $dlopen"
 	  test -n "$dlpreopen" && func_append dlprefiles " $dlpreopen"
 	fi
 
-	if test conv = "$pass"; then
+	if test "$pass" = conv; then
 	  # Only check for convenience libraries
 	  deplibs="$lib $deplibs"
 	  if test -z "$libdir"; then
 	    if test -z "$old_library"; then
-	      func_fatal_error "cannot find name of link library for '$lib'"
+	      func_fatal_error "cannot find name of link library for \`$lib'"
 	    fi
 	    # It is a libtool convenience library, so add in its objects.
 	    func_append convenience " $ladir/$objdir/$old_library"
@@ -7896,15 +6450,15 @@ func_mode_link ()
 	    tmp_libs=
 	    for deplib in $dependency_libs; do
 	      deplibs="$deplib $deplibs"
-	      if $opt_preserve_dup_deps; then
+	      if $opt_preserve_dup_deps ; then
 		case "$tmp_libs " in
 		*" $deplib "*) func_append specialdeplibs " $deplib" ;;
 		esac
 	      fi
 	      func_append tmp_libs " $deplib"
 	    done
-	  elif test prog != "$linkmode" && test lib != "$linkmode"; then
-	    func_fatal_error "'$lib' is not a convenience library"
+	  elif test "$linkmode" != prog && test "$linkmode" != lib; then
+	    func_fatal_error "\`$lib' is not a convenience library"
 	  fi
 	  continue
 	fi # $pass = conv
@@ -7913,26 +6467,26 @@ func_mode_link ()
 	# Get the name of the library we link against.
 	linklib=
 	if test -n "$old_library" &&
-	   { test yes = "$prefer_static_libs" ||
-	     test built,no = "$prefer_static_libs,$installed"; }; then
+	   { test "$prefer_static_libs" = yes ||
+	     test "$prefer_static_libs,$installed" = "built,no"; }; then
 	  linklib=$old_library
 	else
 	  for l in $old_library $library_names; do
-	    linklib=$l
+	    linklib="$l"
 	  done
 	fi
 	if test -z "$linklib"; then
-	  func_fatal_error "cannot find name of link library for '$lib'"
+	  func_fatal_error "cannot find name of link library for \`$lib'"
 	fi
 
 	# This library was specified with -dlopen.
-	if test dlopen = "$pass"; then
-	  test -z "$libdir" \
-	    && func_fatal_error "cannot -dlopen a convenience library: '$lib'"
+	if test "$pass" = dlopen; then
+	  if test -z "$libdir"; then
+	    func_fatal_error "cannot -dlopen a convenience library: \`$lib'"
+	  fi
 	  if test -z "$dlname" ||
-	     test yes != "$dlopen_support" ||
-	     test no = "$build_libtool_libs"
-	  then
+	     test "$dlopen_support" != yes ||
+	     test "$build_libtool_libs" = no; then
 	    # If there is no dlname, no dlopen support or we're linking
 	    # statically, we need to preload.  We also need to preload any
 	    # dependent libraries so libltdl's deplib preloader doesn't
@@ -7946,40 +6500,40 @@ func_mode_link ()
 
 	# We need an absolute path.
 	case $ladir in
-	[\\/]* | [A-Za-z]:[\\/]*) abs_ladir=$ladir ;;
+	[\\/]* | [A-Za-z]:[\\/]*) abs_ladir="$ladir" ;;
 	*)
 	  abs_ladir=`cd "$ladir" && pwd`
 	  if test -z "$abs_ladir"; then
-	    func_warning "cannot determine absolute directory name of '$ladir'"
+	    func_warning "cannot determine absolute directory name of \`$ladir'"
 	    func_warning "passing it literally to the linker, although it might fail"
-	    abs_ladir=$ladir
+	    abs_ladir="$ladir"
 	  fi
 	  ;;
 	esac
 	func_basename "$lib"
-	laname=$func_basename_result
+	laname="$func_basename_result"
 
 	# Find the relevant object directory and library name.
-	if test yes = "$installed"; then
+	if test "X$installed" = Xyes; then
 	  if test ! -f "$lt_sysroot$libdir/$linklib" && test -f "$abs_ladir/$linklib"; then
-	    func_warning "library '$lib' was moved."
-	    dir=$ladir
-	    absdir=$abs_ladir
-	    libdir=$abs_ladir
+	    func_warning "library \`$lib' was moved."
+	    dir="$ladir"
+	    absdir="$abs_ladir"
+	    libdir="$abs_ladir"
 	  else
-	    dir=$lt_sysroot$libdir
-	    absdir=$lt_sysroot$libdir
+	    dir="$lt_sysroot$libdir"
+	    absdir="$lt_sysroot$libdir"
 	  fi
-	  test yes = "$hardcode_automatic" && avoidtemprpath=yes
+	  test "X$hardcode_automatic" = Xyes && avoidtemprpath=yes
 	else
 	  if test ! -f "$ladir/$objdir/$linklib" && test -f "$abs_ladir/$linklib"; then
-	    dir=$ladir
-	    absdir=$abs_ladir
+	    dir="$ladir"
+	    absdir="$abs_ladir"
 	    # Remove this search path later
 	    func_append notinst_path " $abs_ladir"
 	  else
-	    dir=$ladir/$objdir
-	    absdir=$abs_ladir/$objdir
+	    dir="$ladir/$objdir"
+	    absdir="$abs_ladir/$objdir"
 	    # Remove this search path later
 	    func_append notinst_path " $abs_ladir"
 	  fi
@@ -7988,11 +6542,11 @@ func_mode_link ()
 	name=$func_stripname_result
 
 	# This library was specified with -dlpreopen.
-	if test dlpreopen = "$pass"; then
-	  if test -z "$libdir" && test prog = "$linkmode"; then
-	    func_fatal_error "only libraries may -dlpreopen a convenience library: '$lib'"
+	if test "$pass" = dlpreopen; then
+	  if test -z "$libdir" && test "$linkmode" = prog; then
+	    func_fatal_error "only libraries may -dlpreopen a convenience library: \`$lib'"
 	  fi
-	  case $host in
+	  case "$host" in
 	    # special handling for platforms with PE-DLLs.
 	    *cygwin* | *mingw* | *cegcc* )
 	      # Linker will automatically link against shared library if both
@@ -8036,9 +6590,9 @@ func_mode_link ()
 
 	if test -z "$libdir"; then
 	  # Link the convenience library
-	  if test lib = "$linkmode"; then
+	  if test "$linkmode" = lib; then
 	    deplibs="$dir/$old_library $deplibs"
-	  elif test prog,link = "$linkmode,$pass"; then
+	  elif test "$linkmode,$pass" = "prog,link"; then
 	    compile_deplibs="$dir/$old_library $compile_deplibs"
 	    finalize_deplibs="$dir/$old_library $finalize_deplibs"
 	  else
@@ -8048,14 +6602,14 @@ func_mode_link ()
 	fi
 
 
-	if test prog = "$linkmode" && test link != "$pass"; then
+	if test "$linkmode" = prog && test "$pass" != link; then
 	  func_append newlib_search_path " $ladir"
 	  deplibs="$lib $deplibs"
 
-	  linkalldeplibs=false
-	  if test no != "$link_all_deplibs" || test -z "$library_names" ||
-	     test no = "$build_libtool_libs"; then
-	    linkalldeplibs=:
+	  linkalldeplibs=no
+	  if test "$link_all_deplibs" != no || test -z "$library_names" ||
+	     test "$build_libtool_libs" = no; then
+	    linkalldeplibs=yes
 	  fi
 
 	  tmp_libs=
@@ -8067,14 +6621,14 @@ func_mode_link ()
 		 ;;
 	    esac
 	    # Need to link against all dependency_libs?
-	    if $linkalldeplibs; then
+	    if test "$linkalldeplibs" = yes; then
 	      deplibs="$deplib $deplibs"
 	    else
 	      # Need to hardcode shared library paths
 	      # or/and link against static libraries
 	      newdependency_libs="$deplib $newdependency_libs"
 	    fi
-	    if $opt_preserve_dup_deps; then
+	    if $opt_preserve_dup_deps ; then
 	      case "$tmp_libs " in
 	      *" $deplib "*) func_append specialdeplibs " $deplib" ;;
 	      esac
@@ -8084,15 +6638,15 @@ func_mode_link ()
 	  continue
 	fi # $linkmode = prog...
 
-	if test prog,link = "$linkmode,$pass"; then
+	if test "$linkmode,$pass" = "prog,link"; then
 	  if test -n "$library_names" &&
-	     { { test no = "$prefer_static_libs" ||
-	         test built,yes = "$prefer_static_libs,$installed"; } ||
+	     { { test "$prefer_static_libs" = no ||
+	         test "$prefer_static_libs,$installed" = "built,yes"; } ||
 	       test -z "$old_library"; }; then
 	    # We need to hardcode the library path
-	    if test -n "$shlibpath_var" && test -z "$avoidtemprpath"; then
+	    if test -n "$shlibpath_var" && test -z "$avoidtemprpath" ; then
 	      # Make sure the rpath contains only unique directories.
-	      case $temp_rpath: in
+	      case "$temp_rpath:" in
 	      *"$absdir:"*) ;;
 	      *) func_append temp_rpath "$absdir:" ;;
 	      esac
@@ -8121,9 +6675,9 @@ func_mode_link ()
 	    esac
 	  fi # $linkmode,$pass = prog,link...
 
-	  if $alldeplibs &&
-	     { test pass_all = "$deplibs_check_method" ||
-	       { test yes = "$build_libtool_libs" &&
+	  if test "$alldeplibs" = yes &&
+	     { test "$deplibs_check_method" = pass_all ||
+	       { test "$build_libtool_libs" = yes &&
 		 test -n "$library_names"; }; }; then
 	    # We only need to search for static libraries
 	    continue
@@ -8132,19 +6686,19 @@ func_mode_link ()
 
 	link_static=no # Whether the deplib will be linked statically
 	use_static_libs=$prefer_static_libs
-	if test built = "$use_static_libs" && test yes = "$installed"; then
+	if test "$use_static_libs" = built && test "$installed" = yes; then
 	  use_static_libs=no
 	fi
 	if test -n "$library_names" &&
-	   { test no = "$use_static_libs" || test -z "$old_library"; }; then
+	   { test "$use_static_libs" = no || test -z "$old_library"; }; then
 	  case $host in
-	  *cygwin* | *mingw* | *cegcc* | *os2*)
+	  *cygwin* | *mingw* | *cegcc*)
 	      # No point in relinking DLLs because paths are not encoded
 	      func_append notinst_deplibs " $lib"
 	      need_relink=no
 	    ;;
 	  *)
-	    if test no = "$installed"; then
+	    if test "$installed" = no; then
 	      func_append notinst_deplibs " $lib"
 	      need_relink=yes
 	    fi
@@ -8154,24 +6708,24 @@ func_mode_link ()
 
 	  # Warn about portability, can't link against -module's on some
 	  # systems (darwin).  Don't bleat about dlopened modules though!
-	  dlopenmodule=
+	  dlopenmodule=""
 	  for dlpremoduletest in $dlprefiles; do
 	    if test "X$dlpremoduletest" = "X$lib"; then
-	      dlopenmodule=$dlpremoduletest
+	      dlopenmodule="$dlpremoduletest"
 	      break
 	    fi
 	  done
-	  if test -z "$dlopenmodule" && test yes = "$shouldnotlink" && test link = "$pass"; then
+	  if test -z "$dlopenmodule" && test "$shouldnotlink" = yes && test "$pass" = link; then
 	    echo
-	    if test prog = "$linkmode"; then
+	    if test "$linkmode" = prog; then
 	      $ECHO "*** Warning: Linking the executable $output against the loadable module"
 	    else
 	      $ECHO "*** Warning: Linking the shared library $output against the loadable module"
 	    fi
 	    $ECHO "*** $linklib is not portable!"
 	  fi
-	  if test lib = "$linkmode" &&
-	     test yes = "$hardcode_into_libs"; then
+	  if test "$linkmode" = lib &&
+	     test "$hardcode_into_libs" = yes; then
 	    # Hardcode the library path.
 	    # Skip directories that are in the system default run-time
 	    # search path.
@@ -8199,43 +6753,43 @@ func_mode_link ()
 	    # figure out the soname
 	    set dummy $library_names
 	    shift
-	    realname=$1
+	    realname="$1"
 	    shift
 	    libname=`eval "\\$ECHO \"$libname_spec\""`
 	    # use dlname if we got it. it's perfectly good, no?
 	    if test -n "$dlname"; then
-	      soname=$dlname
+	      soname="$dlname"
 	    elif test -n "$soname_spec"; then
 	      # bleh windows
 	      case $host in
-	      *cygwin* | mingw* | *cegcc* | *os2*)
+	      *cygwin* | mingw* | *cegcc*)
 	        func_arith $current - $age
 		major=$func_arith_result
-		versuffix=-$major
+		versuffix="-$major"
 		;;
 	      esac
 	      eval soname=\"$soname_spec\"
 	    else
-	      soname=$realname
+	      soname="$realname"
 	    fi
 
 	    # Make a new name for the extract_expsyms_cmds to use
-	    soroot=$soname
+	    soroot="$soname"
 	    func_basename "$soroot"
-	    soname=$func_basename_result
+	    soname="$func_basename_result"
 	    func_stripname 'lib' '.dll' "$soname"
 	    newlib=libimp-$func_stripname_result.a
 
 	    # If the library has no export list, then create one now
 	    if test -f "$output_objdir/$soname-def"; then :
 	    else
-	      func_verbose "extracting exported symbol list from '$soname'"
+	      func_verbose "extracting exported symbol list from \`$soname'"
 	      func_execute_cmds "$extract_expsyms_cmds" 'exit $?'
 	    fi
 
 	    # Create $newlib
 	    if test -f "$output_objdir/$newlib"; then :; else
-	      func_verbose "generating import library for '$soname'"
+	      func_verbose "generating import library for \`$soname'"
 	      func_execute_cmds "$old_archive_from_expsyms_cmds" 'exit $?'
 	    fi
 	    # make sure the library variables are pointing to the new library
@@ -8243,58 +6797,58 @@ func_mode_link ()
 	    linklib=$newlib
 	  fi # test -n "$old_archive_from_expsyms_cmds"
 
-	  if test prog = "$linkmode" || test relink != "$opt_mode"; then
+	  if test "$linkmode" = prog || test "$opt_mode" != relink; then
 	    add_shlibpath=
 	    add_dir=
 	    add=
 	    lib_linked=yes
 	    case $hardcode_action in
 	    immediate | unsupported)
-	      if test no = "$hardcode_direct"; then
-		add=$dir/$linklib
+	      if test "$hardcode_direct" = no; then
+		add="$dir/$linklib"
 		case $host in
-		  *-*-sco3.2v5.0.[024]*) add_dir=-L$dir ;;
-		  *-*-sysv4*uw2*) add_dir=-L$dir ;;
+		  *-*-sco3.2v5.0.[024]*) add_dir="-L$dir" ;;
+		  *-*-sysv4*uw2*) add_dir="-L$dir" ;;
 		  *-*-sysv5OpenUNIX* | *-*-sysv5UnixWare7.[01].[10]* | \
-		    *-*-unixware7*) add_dir=-L$dir ;;
+		    *-*-unixware7*) add_dir="-L$dir" ;;
 		  *-*-darwin* )
-		    # if the lib is a (non-dlopened) module then we cannot
+		    # if the lib is a (non-dlopened) module then we can not
 		    # link against it, someone is ignoring the earlier warnings
 		    if /usr/bin/file -L $add 2> /dev/null |
-			 $GREP ": [^:]* bundle" >/dev/null; then
+			 $GREP ": [^:]* bundle" >/dev/null ; then
 		      if test "X$dlopenmodule" != "X$lib"; then
 			$ECHO "*** Warning: lib $linklib is a module, not a shared library"
-			if test -z "$old_library"; then
+			if test -z "$old_library" ; then
 			  echo
 			  echo "*** And there doesn't seem to be a static archive available"
 			  echo "*** The link will probably fail, sorry"
 			else
-			  add=$dir/$old_library
+			  add="$dir/$old_library"
 			fi
 		      elif test -n "$old_library"; then
-			add=$dir/$old_library
+			add="$dir/$old_library"
 		      fi
 		    fi
 		esac
-	      elif test no = "$hardcode_minus_L"; then
+	      elif test "$hardcode_minus_L" = no; then
 		case $host in
-		*-*-sunos*) add_shlibpath=$dir ;;
+		*-*-sunos*) add_shlibpath="$dir" ;;
 		esac
-		add_dir=-L$dir
-		add=-l$name
-	      elif test no = "$hardcode_shlibpath_var"; then
-		add_shlibpath=$dir
-		add=-l$name
+		add_dir="-L$dir"
+		add="-l$name"
+	      elif test "$hardcode_shlibpath_var" = no; then
+		add_shlibpath="$dir"
+		add="-l$name"
 	      else
 		lib_linked=no
 	      fi
 	      ;;
 	    relink)
-	      if test yes = "$hardcode_direct" &&
-	         test no = "$hardcode_direct_absolute"; then
-		add=$dir/$linklib
-	      elif test yes = "$hardcode_minus_L"; then
-		add_dir=-L$absdir
+	      if test "$hardcode_direct" = yes &&
+	         test "$hardcode_direct_absolute" = no; then
+		add="$dir/$linklib"
+	      elif test "$hardcode_minus_L" = yes; then
+		add_dir="-L$absdir"
 		# Try looking first in the location we're being installed to.
 		if test -n "$inst_prefix_dir"; then
 		  case $libdir in
@@ -8303,10 +6857,10 @@ func_mode_link ()
 		      ;;
 		  esac
 		fi
-		add=-l$name
-	      elif test yes = "$hardcode_shlibpath_var"; then
-		add_shlibpath=$dir
-		add=-l$name
+		add="-l$name"
+	      elif test "$hardcode_shlibpath_var" = yes; then
+		add_shlibpath="$dir"
+		add="-l$name"
 	      else
 		lib_linked=no
 	      fi
@@ -8314,7 +6868,7 @@ func_mode_link ()
 	    *) lib_linked=no ;;
 	    esac
 
-	    if test yes != "$lib_linked"; then
+	    if test "$lib_linked" != yes; then
 	      func_fatal_configuration "unsupported hardcode properties"
 	    fi
 
@@ -8324,15 +6878,15 @@ func_mode_link ()
 	      *) func_append compile_shlibpath "$add_shlibpath:" ;;
 	      esac
 	    fi
-	    if test prog = "$linkmode"; then
+	    if test "$linkmode" = prog; then
 	      test -n "$add_dir" && compile_deplibs="$add_dir $compile_deplibs"
 	      test -n "$add" && compile_deplibs="$add $compile_deplibs"
 	    else
 	      test -n "$add_dir" && deplibs="$add_dir $deplibs"
 	      test -n "$add" && deplibs="$add $deplibs"
-	      if test yes != "$hardcode_direct" &&
-		 test yes != "$hardcode_minus_L" &&
-		 test yes = "$hardcode_shlibpath_var"; then
+	      if test "$hardcode_direct" != yes &&
+		 test "$hardcode_minus_L" != yes &&
+		 test "$hardcode_shlibpath_var" = yes; then
 		case :$finalize_shlibpath: in
 		*":$libdir:"*) ;;
 		*) func_append finalize_shlibpath "$libdir:" ;;
@@ -8341,33 +6895,33 @@ func_mode_link ()
 	    fi
 	  fi
 
-	  if test prog = "$linkmode" || test relink = "$opt_mode"; then
+	  if test "$linkmode" = prog || test "$opt_mode" = relink; then
 	    add_shlibpath=
 	    add_dir=
 	    add=
 	    # Finalize command for both is simple: just hardcode it.
-	    if test yes = "$hardcode_direct" &&
-	       test no = "$hardcode_direct_absolute"; then
-	      add=$libdir/$linklib
-	    elif test yes = "$hardcode_minus_L"; then
-	      add_dir=-L$libdir
-	      add=-l$name
-	    elif test yes = "$hardcode_shlibpath_var"; then
+	    if test "$hardcode_direct" = yes &&
+	       test "$hardcode_direct_absolute" = no; then
+	      add="$libdir/$linklib"
+	    elif test "$hardcode_minus_L" = yes; then
+	      add_dir="-L$libdir"
+	      add="-l$name"
+	    elif test "$hardcode_shlibpath_var" = yes; then
 	      case :$finalize_shlibpath: in
 	      *":$libdir:"*) ;;
 	      *) func_append finalize_shlibpath "$libdir:" ;;
 	      esac
-	      add=-l$name
-	    elif test yes = "$hardcode_automatic"; then
+	      add="-l$name"
+	    elif test "$hardcode_automatic" = yes; then
 	      if test -n "$inst_prefix_dir" &&
-		 test -f "$inst_prefix_dir$libdir/$linklib"; then
-		add=$inst_prefix_dir$libdir/$linklib
+		 test -f "$inst_prefix_dir$libdir/$linklib" ; then
+		add="$inst_prefix_dir$libdir/$linklib"
 	      else
-		add=$libdir/$linklib
+		add="$libdir/$linklib"
 	      fi
 	    else
 	      # We cannot seem to hardcode it, guess we'll fake it.
-	      add_dir=-L$libdir
+	      add_dir="-L$libdir"
 	      # Try looking first in the location we're being installed to.
 	      if test -n "$inst_prefix_dir"; then
 		case $libdir in
@@ -8376,10 +6930,10 @@ func_mode_link ()
 		    ;;
 		esac
 	      fi
-	      add=-l$name
+	      add="-l$name"
 	    fi
 
-	    if test prog = "$linkmode"; then
+	    if test "$linkmode" = prog; then
 	      test -n "$add_dir" && finalize_deplibs="$add_dir $finalize_deplibs"
 	      test -n "$add" && finalize_deplibs="$add $finalize_deplibs"
 	    else
@@ -8387,43 +6941,43 @@ func_mode_link ()
 	      test -n "$add" && deplibs="$add $deplibs"
 	    fi
 	  fi
-	elif test prog = "$linkmode"; then
+	elif test "$linkmode" = prog; then
 	  # Here we assume that one of hardcode_direct or hardcode_minus_L
 	  # is not unsupported.  This is valid on all known static and
 	  # shared platforms.
-	  if test unsupported != "$hardcode_direct"; then
-	    test -n "$old_library" && linklib=$old_library
+	  if test "$hardcode_direct" != unsupported; then
+	    test -n "$old_library" && linklib="$old_library"
 	    compile_deplibs="$dir/$linklib $compile_deplibs"
 	    finalize_deplibs="$dir/$linklib $finalize_deplibs"
 	  else
 	    compile_deplibs="-l$name -L$dir $compile_deplibs"
 	    finalize_deplibs="-l$name -L$dir $finalize_deplibs"
 	  fi
-	elif test yes = "$build_libtool_libs"; then
+	elif test "$build_libtool_libs" = yes; then
 	  # Not a shared library
-	  if test pass_all != "$deplibs_check_method"; then
+	  if test "$deplibs_check_method" != pass_all; then
 	    # We're trying link a shared library against a static one
 	    # but the system doesn't support it.
 
 	    # Just print a warning and add the library to dependency_libs so
 	    # that the program can be linked against the static library.
 	    echo
-	    $ECHO "*** Warning: This system cannot link to static lib archive $lib."
+	    $ECHO "*** Warning: This system can not link to static lib archive $lib."
 	    echo "*** I have the capability to make that library automatically link in when"
 	    echo "*** you link to this library.  But I can only do this if you have a"
 	    echo "*** shared version of the library, which you do not appear to have."
-	    if test yes = "$module"; then
+	    if test "$module" = yes; then
 	      echo "*** But as you try to build a module library, libtool will still create "
 	      echo "*** a static module, that should work as long as the dlopening application"
 	      echo "*** is linked with the -dlopen flag to resolve symbols at runtime."
 	      if test -z "$global_symbol_pipe"; then
 		echo
 		echo "*** However, this would only work if libtool was able to extract symbol"
-		echo "*** lists from a program, using 'nm' or equivalent, but libtool could"
+		echo "*** lists from a program, using \`nm' or equivalent, but libtool could"
 		echo "*** not find such a program.  So, this module is probably useless."
-		echo "*** 'nm' from GNU binutils and a full rebuild may help."
+		echo "*** \`nm' from GNU binutils and a full rebuild may help."
 	      fi
-	      if test no = "$build_old_libs"; then
+	      if test "$build_old_libs" = no; then
 		build_libtool_libs=module
 		build_old_libs=yes
 	      else
@@ -8436,11 +6990,11 @@ func_mode_link ()
 	  fi
 	fi # link shared/static library?
 
-	if test lib = "$linkmode"; then
+	if test "$linkmode" = lib; then
 	  if test -n "$dependency_libs" &&
-	     { test yes != "$hardcode_into_libs" ||
-	       test yes = "$build_old_libs" ||
-	       test yes = "$link_static"; }; then
+	     { test "$hardcode_into_libs" != yes ||
+	       test "$build_old_libs" = yes ||
+	       test "$link_static" = yes; }; then
 	    # Extract -R from dependency_libs
 	    temp_deplibs=
 	    for libdir in $dependency_libs; do
@@ -8454,12 +7008,12 @@ func_mode_link ()
 	      *) func_append temp_deplibs " $libdir";;
 	      esac
 	    done
-	    dependency_libs=$temp_deplibs
+	    dependency_libs="$temp_deplibs"
 	  fi
 
 	  func_append newlib_search_path " $absdir"
 	  # Link against this library
-	  test no = "$link_static" && newdependency_libs="$abs_ladir/$laname $newdependency_libs"
+	  test "$link_static" = no && newdependency_libs="$abs_ladir/$laname $newdependency_libs"
 	  # ... and its dependency_libs
 	  tmp_libs=
 	  for deplib in $dependency_libs; do
@@ -8469,7 +7023,7 @@ func_mode_link ()
                    func_resolve_sysroot "$func_stripname_result";;
               *) func_resolve_sysroot "$deplib" ;;
             esac
-	    if $opt_preserve_dup_deps; then
+	    if $opt_preserve_dup_deps ; then
 	      case "$tmp_libs " in
 	      *" $func_resolve_sysroot_result "*)
                 func_append specialdeplibs " $func_resolve_sysroot_result" ;;
@@ -8478,12 +7032,12 @@ func_mode_link ()
 	    func_append tmp_libs " $func_resolve_sysroot_result"
 	  done
 
-	  if test no != "$link_all_deplibs"; then
+	  if test "$link_all_deplibs" != no; then
 	    # Add the search paths of all dependency libraries
 	    for deplib in $dependency_libs; do
 	      path=
 	      case $deplib in
-	      -L*) path=$deplib ;;
+	      -L*) path="$deplib" ;;
 	      *.la)
 	        func_resolve_sysroot "$deplib"
 	        deplib=$func_resolve_sysroot_result
@@ -8491,12 +7045,12 @@ func_mode_link ()
 		dir=$func_dirname_result
 		# We need an absolute path.
 		case $dir in
-		[\\/]* | [A-Za-z]:[\\/]*) absdir=$dir ;;
+		[\\/]* | [A-Za-z]:[\\/]*) absdir="$dir" ;;
 		*)
 		  absdir=`cd "$dir" && pwd`
 		  if test -z "$absdir"; then
-		    func_warning "cannot determine absolute directory name of '$dir'"
-		    absdir=$dir
+		    func_warning "cannot determine absolute directory name of \`$dir'"
+		    absdir="$dir"
 		  fi
 		  ;;
 		esac
@@ -8504,35 +7058,35 @@ func_mode_link ()
 		case $host in
 		*-*-darwin*)
 		  depdepl=
-		  eval deplibrary_names=`$SED -n -e 's/^library_names=\(.*\)$/\1/p' $deplib`
-		  if test -n "$deplibrary_names"; then
-		    for tmp in $deplibrary_names; do
+		  eval deplibrary_names=`${SED} -n -e 's/^library_names=\(.*\)$/\1/p' $deplib`
+		  if test -n "$deplibrary_names" ; then
+		    for tmp in $deplibrary_names ; do
 		      depdepl=$tmp
 		    done
-		    if test -f "$absdir/$objdir/$depdepl"; then
-		      depdepl=$absdir/$objdir/$depdepl
-		      darwin_install_name=`$OTOOL -L $depdepl | awk '{if (NR == 2) {print $1;exit}}'`
+		    if test -f "$absdir/$objdir/$depdepl" ; then
+		      depdepl="$absdir/$objdir/$depdepl"
+		      darwin_install_name=`${OTOOL} -L $depdepl | awk '{if (NR == 2) {print $1;exit}}'`
                       if test -z "$darwin_install_name"; then
-                          darwin_install_name=`$OTOOL64 -L $depdepl  | awk '{if (NR == 2) {print $1;exit}}'`
+                          darwin_install_name=`${OTOOL64} -L $depdepl  | awk '{if (NR == 2) {print $1;exit}}'`
                       fi
-		      func_append compiler_flags " $wl-dylib_file $wl$darwin_install_name:$depdepl"
-		      func_append linker_flags " -dylib_file $darwin_install_name:$depdepl"
+		      func_append compiler_flags " ${wl}-dylib_file ${wl}${darwin_install_name}:${depdepl}"
+		      func_append linker_flags " -dylib_file ${darwin_install_name}:${depdepl}"
 		      path=
 		    fi
 		  fi
 		  ;;
 		*)
-		  path=-L$absdir/$objdir
+		  path="-L$absdir/$objdir"
 		  ;;
 		esac
 		else
-		  eval libdir=`$SED -n -e 's/^libdir=\(.*\)$/\1/p' $deplib`
+		  eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $deplib`
 		  test -z "$libdir" && \
-		    func_fatal_error "'$deplib' is not a valid libtool archive"
+		    func_fatal_error "\`$deplib' is not a valid libtool archive"
 		  test "$absdir" != "$libdir" && \
-		    func_warning "'$deplib' seems to be moved"
+		    func_warning "\`$deplib' seems to be moved"
 
-		  path=-L$absdir
+		  path="-L$absdir"
 		fi
 		;;
 	      esac
@@ -8544,23 +7098,23 @@ func_mode_link ()
 	  fi # link_all_deplibs != no
 	fi # linkmode = lib
       done # for deplib in $libs
-      if test link = "$pass"; then
-	if test prog = "$linkmode"; then
+      if test "$pass" = link; then
+	if test "$linkmode" = "prog"; then
 	  compile_deplibs="$new_inherited_linker_flags $compile_deplibs"
 	  finalize_deplibs="$new_inherited_linker_flags $finalize_deplibs"
 	else
 	  compiler_flags="$compiler_flags "`$ECHO " $new_inherited_linker_flags" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'`
 	fi
       fi
-      dependency_libs=$newdependency_libs
-      if test dlpreopen = "$pass"; then
+      dependency_libs="$newdependency_libs"
+      if test "$pass" = dlpreopen; then
 	# Link the dlpreopened libraries before other libraries
 	for deplib in $save_deplibs; do
 	  deplibs="$deplib $deplibs"
 	done
       fi
-      if test dlopen != "$pass"; then
-	test conv = "$pass" || {
+      if test "$pass" != dlopen; then
+	if test "$pass" != conv; then
 	  # Make sure lib_search_path contains only unique directories.
 	  lib_search_path=
 	  for dir in $newlib_search_path; do
@@ -8570,12 +7124,12 @@ func_mode_link ()
 	    esac
 	  done
 	  newlib_search_path=
-	}
+	fi
 
-	if test prog,link = "$linkmode,$pass"; then
-	  vars="compile_deplibs finalize_deplibs"
+	if test "$linkmode,$pass" != "prog,link"; then
+	  vars="deplibs"
 	else
-	  vars=deplibs
+	  vars="compile_deplibs finalize_deplibs"
 	fi
 	for var in $vars dependency_libs; do
 	  # Add libraries to $var in reverse order
@@ -8633,93 +7187,62 @@ func_mode_link ()
 	  eval $var=\"$tmp_libs\"
 	done # for var
       fi
-
-      # Add Sun CC postdeps if required:
-      test CXX = "$tagname" && {
-        case $host_os in
-        linux*)
-          case `$CC -V 2>&1 | sed 5q` in
-          *Sun\ C*) # Sun C++ 5.9
-            func_suncc_cstd_abi
-
-            if test no != "$suncc_use_cstd_abi"; then
-              func_append postdeps ' -library=Cstd -library=Crun'
-            fi
-            ;;
-          esac
-          ;;
-
-        solaris*)
-          func_cc_basename "$CC"
-          case $func_cc_basename_result in
-          CC* | sunCC*)
-            func_suncc_cstd_abi
-
-            if test no != "$suncc_use_cstd_abi"; then
-              func_append postdeps ' -library=Cstd -library=Crun'
-            fi
-            ;;
-          esac
-          ;;
-        esac
-      }
-
       # Last step: remove runtime libs from dependency_libs
       # (they stay in deplibs)
       tmp_libs=
-      for i in $dependency_libs; do
+      for i in $dependency_libs ; do
 	case " $predeps $postdeps $compiler_lib_search_path " in
 	*" $i "*)
-	  i=
+	  i=""
 	  ;;
 	esac
-	if test -n "$i"; then
+	if test -n "$i" ; then
 	  func_append tmp_libs " $i"
 	fi
       done
       dependency_libs=$tmp_libs
     done # for pass
-    if test prog = "$linkmode"; then
-      dlfiles=$newdlfiles
+    if test "$linkmode" = prog; then
+      dlfiles="$newdlfiles"
     fi
-    if test prog = "$linkmode" || test lib = "$linkmode"; then
-      dlprefiles=$newdlprefiles
+    if test "$linkmode" = prog || test "$linkmode" = lib; then
+      dlprefiles="$newdlprefiles"
     fi
 
     case $linkmode in
     oldlib)
-      if test -n "$dlfiles$dlprefiles" || test no != "$dlself"; then
-	func_warning "'-dlopen' is ignored for archives"
+      if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then
+	func_warning "\`-dlopen' is ignored for archives"
       fi
 
       case " $deplibs" in
       *\ -l* | *\ -L*)
-	func_warning "'-l' and '-L' are ignored for archives" ;;
+	func_warning "\`-l' and \`-L' are ignored for archives" ;;
       esac
 
       test -n "$rpath" && \
-	func_warning "'-rpath' is ignored for archives"
+	func_warning "\`-rpath' is ignored for archives"
 
       test -n "$xrpath" && \
-	func_warning "'-R' is ignored for archives"
+	func_warning "\`-R' is ignored for archives"
 
       test -n "$vinfo" && \
-	func_warning "'-version-info/-version-number' is ignored for archives"
+	func_warning "\`-version-info/-version-number' is ignored for archives"
 
       test -n "$release" && \
-	func_warning "'-release' is ignored for archives"
+	func_warning "\`-release' is ignored for archives"
 
       test -n "$export_symbols$export_symbols_regex" && \
-	func_warning "'-export-symbols' is ignored for archives"
+	func_warning "\`-export-symbols' is ignored for archives"
 
       # Now set the variables for building old libraries.
       build_libtool_libs=no
-      oldlibs=$output
+      oldlibs="$output"
       func_append objs "$old_deplibs"
       ;;
 
     lib)
-      # Make sure we only generate libraries of the form 'libNAME.la'.
+      # Make sure we only generate libraries of the form `libNAME.la'.
       case $outputname in
       lib*)
 	func_stripname 'lib' '.la' "$outputname"
@@ -8728,10 +7251,10 @@ func_mode_link ()
 	eval libname=\"$libname_spec\"
 	;;
       *)
-	test no = "$module" \
-	  && func_fatal_help "libtool library '$output' must begin with 'lib'"
+	test "$module" = no && \
+	  func_fatal_help "libtool library \`$output' must begin with \`lib'"
 
-	if test no != "$need_lib_prefix"; then
+	if test "$need_lib_prefix" != no; then
 	  # Add the "lib" prefix for modules if required
 	  func_stripname '' '.la' "$outputname"
 	  name=$func_stripname_result
@@ -8745,8 +7268,8 @@ func_mode_link ()
       esac
 
       if test -n "$objs"; then
-	if test pass_all != "$deplibs_check_method"; then
-	  func_fatal_error "cannot build libtool library '$output' from non-libtool objects on this host:$objs"
+	if test "$deplibs_check_method" != pass_all; then
+	  func_fatal_error "cannot build libtool library \`$output' from non-libtool objects on this host:$objs"
 	else
 	  echo
 	  $ECHO "*** Warning: Linking the shared library $output against the non-libtool"
@@ -8755,21 +7278,21 @@ func_mode_link ()
 	fi
       fi
 
-      test no = "$dlself" \
-	|| func_warning "'-dlopen self' is ignored for libtool libraries"
+      test "$dlself" != no && \
+	func_warning "\`-dlopen self' is ignored for libtool libraries"
 
       set dummy $rpath
       shift
-      test 1 -lt "$#" \
-	&& func_warning "ignoring multiple '-rpath's for a libtool library"
+      test "$#" -gt 1 && \
+	func_warning "ignoring multiple \`-rpath's for a libtool library"
 
-      install_libdir=$1
+      install_libdir="$1"
 
       oldlibs=
       if test -z "$rpath"; then
-	if test yes = "$build_libtool_libs"; then
+	if test "$build_libtool_libs" = yes; then
 	  # Building a libtool convenience library.
-	  # Some compilers have problems with a '.al' extension so
+	  # Some compilers have problems with a `.al' extension so
 	  # convenience libraries should have the same extension an
 	  # archive normally would.
 	  oldlibs="$output_objdir/$libname.$libext $oldlibs"
@@ -8778,20 +7301,20 @@ func_mode_link ()
 	fi
 
 	test -n "$vinfo" && \
-	  func_warning "'-version-info/-version-number' is ignored for convenience libraries"
+	  func_warning "\`-version-info/-version-number' is ignored for convenience libraries"
 
 	test -n "$release" && \
-	  func_warning "'-release' is ignored for convenience libraries"
+	  func_warning "\`-release' is ignored for convenience libraries"
       else
 
 	# Parse the version information argument.
-	save_ifs=$IFS; IFS=:
+	save_ifs="$IFS"; IFS=':'
 	set dummy $vinfo 0 0 0
 	shift
-	IFS=$save_ifs
+	IFS="$save_ifs"
 
 	test -n "$7" && \
-	  func_fatal_help "too many parameters to '-version-info'"
+	  func_fatal_help "too many parameters to \`-version-info'"
 
 	# convert absolute version numbers to libtool ages
 	# this retains compatibility with .la files and attempts
@@ -8799,45 +7322,45 @@ func_mode_link ()
 
 	case $vinfo_number in
 	yes)
-	  number_major=$1
-	  number_minor=$2
-	  number_revision=$3
+	  number_major="$1"
+	  number_minor="$2"
+	  number_revision="$3"
 	  #
 	  # There are really only two kinds -- those that
 	  # use the current revision as the major version
 	  # and those that subtract age and use age as
 	  # a minor version.  But, then there is irix
-	  # that has an extra 1 added just for fun
+	  # which has an extra 1 added just for fun
 	  #
 	  case $version_type in
 	  # correct linux to gnu/linux during the next big refactor
-	  darwin|freebsd-elf|linux|osf|windows|none)
+	  darwin|linux|osf|windows|none)
 	    func_arith $number_major + $number_minor
 	    current=$func_arith_result
-	    age=$number_minor
-	    revision=$number_revision
+	    age="$number_minor"
+	    revision="$number_revision"
 	    ;;
-	  freebsd-aout|qnx|sunos)
-	    current=$number_major
-	    revision=$number_minor
-	    age=0
+	  freebsd-aout|freebsd-elf|qnx|sunos)
+	    current="$number_major"
+	    revision="$number_minor"
+	    age="0"
 	    ;;
 	  irix|nonstopux)
 	    func_arith $number_major + $number_minor
 	    current=$func_arith_result
-	    age=$number_minor
-	    revision=$number_minor
+	    age="$number_minor"
+	    revision="$number_minor"
 	    lt_irix_increment=no
 	    ;;
 	  *)
-	    func_fatal_configuration "$modename: unknown library version type '$version_type'"
+	    func_fatal_configuration "$modename: unknown library version type \`$version_type'"
 	    ;;
 	  esac
 	  ;;
 	no)
-	  current=$1
-	  revision=$2
-	  age=$3
+	  current="$1"
+	  revision="$2"
+	  age="$3"
 	  ;;
 	esac
 
@@ -8845,30 +7368,30 @@ func_mode_link ()
 	case $current in
 	0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;;
 	*)
-	  func_error "CURRENT '$current' must be a nonnegative integer"
-	  func_fatal_error "'$vinfo' is not valid version information"
+	  func_error "CURRENT \`$current' must be a nonnegative integer"
+	  func_fatal_error "\`$vinfo' is not valid version information"
 	  ;;
 	esac
 
 	case $revision in
 	0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;;
 	*)
-	  func_error "REVISION '$revision' must be a nonnegative integer"
-	  func_fatal_error "'$vinfo' is not valid version information"
+	  func_error "REVISION \`$revision' must be a nonnegative integer"
+	  func_fatal_error "\`$vinfo' is not valid version information"
 	  ;;
 	esac
 
 	case $age in
 	0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;;
 	*)
-	  func_error "AGE '$age' must be a nonnegative integer"
-	  func_fatal_error "'$vinfo' is not valid version information"
+	  func_error "AGE \`$age' must be a nonnegative integer"
+	  func_fatal_error "\`$vinfo' is not valid version information"
 	  ;;
 	esac
 
 	if test "$age" -gt "$current"; then
-	  func_error "AGE '$age' is greater than the current interface number '$current'"
-	  func_fatal_error "'$vinfo' is not valid version information"
+	  func_error "AGE \`$age' is greater than the current interface number \`$current'"
+	  func_fatal_error "\`$vinfo' is not valid version information"
 	fi
 
 	# Calculate the version variables.
@@ -8883,36 +7406,26 @@ func_mode_link ()
 	  # verstring for coding it into the library header
 	  func_arith $current - $age
 	  major=.$func_arith_result
-	  versuffix=$major.$age.$revision
+	  versuffix="$major.$age.$revision"
 	  # Darwin ld doesn't like 0 for these options...
 	  func_arith $current + 1
 	  minor_current=$func_arith_result
-	  xlcverstring="$wl-compatibility_version $wl$minor_current $wl-current_version $wl$minor_current.$revision"
+	  xlcverstring="${wl}-compatibility_version ${wl}$minor_current ${wl}-current_version ${wl}$minor_current.$revision"
 	  verstring="-compatibility_version $minor_current -current_version $minor_current.$revision"
-          # On Darwin other compilers
-          case $CC in
-              nagfor*)
-                  verstring="$wl-compatibility_version $wl$minor_current $wl-current_version $wl$minor_current.$revision"
-                  ;;
-              *)
-                  verstring="-compatibility_version $minor_current -current_version $minor_current.$revision"
-                  ;;
-          esac
 	  ;;
 
 	freebsd-aout)
-	  major=.$current
-	  versuffix=.$current.$revision
+	  major=".$current"
+	  versuffix=".$current.$revision";
 	  ;;
 
 	freebsd-elf)
-	  func_arith $current - $age
-	  major=.$func_arith_result
-	  versuffix=$major.$age.$revision
+	  major=".$current"
+	  versuffix=".$current"
 	  ;;
 
 	irix | nonstopux)
-	  if test no = "$lt_irix_increment"; then
+	  if test "X$lt_irix_increment" = "Xno"; then
 	    func_arith $current - $age
 	  else
 	    func_arith $current - $age + 1
@@ -8923,74 +7436,69 @@ func_mode_link ()
 	    nonstopux) verstring_prefix=nonstopux ;;
 	    *)         verstring_prefix=sgi ;;
 	  esac
-	  verstring=$verstring_prefix$major.$revision
+	  verstring="$verstring_prefix$major.$revision"
 
 	  # Add in all the interfaces that we are compatible with.
 	  loop=$revision
-	  while test 0 -ne "$loop"; do
+	  while test "$loop" -ne 0; do
 	    func_arith $revision - $loop
 	    iface=$func_arith_result
 	    func_arith $loop - 1
 	    loop=$func_arith_result
-	    verstring=$verstring_prefix$major.$iface:$verstring
+	    verstring="$verstring_prefix$major.$iface:$verstring"
 	  done
 
-	  # Before this point, $major must not contain '.'.
+	  # Before this point, $major must not contain `.'.
 	  major=.$major
-	  versuffix=$major.$revision
+	  versuffix="$major.$revision"
 	  ;;
 
 	linux) # correct to gnu/linux during the next big refactor
 	  func_arith $current - $age
 	  major=.$func_arith_result
-	  versuffix=$major.$age.$revision
+	  versuffix="$major.$age.$revision"
 	  ;;
 
 	osf)
 	  func_arith $current - $age
 	  major=.$func_arith_result
-	  versuffix=.$current.$age.$revision
-	  verstring=$current.$age.$revision
+	  versuffix=".$current.$age.$revision"
+	  verstring="$current.$age.$revision"
 
 	  # Add in all the interfaces that we are compatible with.
 	  loop=$age
-	  while test 0 -ne "$loop"; do
+	  while test "$loop" -ne 0; do
 	    func_arith $current - $loop
 	    iface=$func_arith_result
 	    func_arith $loop - 1
 	    loop=$func_arith_result
-	    verstring=$verstring:$iface.0
+	    verstring="$verstring:${iface}.0"
 	  done
 
 	  # Make executables depend on our current version.
-	  func_append verstring ":$current.0"
+	  func_append verstring ":${current}.0"
 	  ;;
 
 	qnx)
-	  major=.$current
-	  versuffix=.$current
-	  ;;
-
-	sco)
-	  major=.$current
-	  versuffix=.$current
+	  major=".$current"
+	  versuffix=".$current"
 	  ;;
 
 	sunos)
-	  major=.$current
-	  versuffix=.$current.$revision
+	  major=".$current"
+	  versuffix=".$current.$revision"
 	  ;;
 
 	windows)
 	  # Use '-' rather than '.', since we only want one
-	  # extension on DOS 8.3 file systems.
+	  # extension on DOS 8.3 filesystems.
 	  func_arith $current - $age
 	  major=$func_arith_result
-	  versuffix=-$major
+	  versuffix="-$major"
 	  ;;
 
 	*)
-	  func_fatal_configuration "unknown library version type '$version_type'"
+	  func_fatal_configuration "unknown library version type \`$version_type'"
 	  ;;
 	esac
 
@@ -9004,45 +7512,42 @@ func_mode_link ()
 	    verstring=
 	    ;;
 	  *)
-	    verstring=0.0
+	    verstring="0.0"
 	    ;;
 	  esac
-	  if test no = "$need_version"; then
+	  if test "$need_version" = no; then
 	    versuffix=
 	  else
-	    versuffix=.0.0
+	    versuffix=".0.0"
 	  fi
 	fi
 
 	# Remove version info from name if versioning should be avoided
-	if test yes,no = "$avoid_version,$need_version"; then
+	if test "$avoid_version" = yes && test "$need_version" = no; then
 	  major=
 	  versuffix=
-	  verstring=
+	  verstring=""
 	fi
 
 	# Check to see if the archive will have undefined symbols.
-	if test yes = "$allow_undefined"; then
-	  if test unsupported = "$allow_undefined_flag"; then
-	    if test yes = "$build_old_libs"; then
-	      func_warning "undefined symbols not allowed in $host shared libraries; building static only"
-	      build_libtool_libs=no
-	    else
-	      func_fatal_error "can't build $host shared library unless -no-undefined is specified"
-	    fi
+	if test "$allow_undefined" = yes; then
+	  if test "$allow_undefined_flag" = unsupported; then
+	    func_warning "undefined symbols not allowed in $host shared libraries"
+	    build_libtool_libs=no
+	    build_old_libs=yes
 	  fi
 	else
 	  # Don't allow undefined symbols.
-	  allow_undefined_flag=$no_undefined_flag
+	  allow_undefined_flag="$no_undefined_flag"
 	fi
 
       fi
 
-      func_generate_dlsyms "$libname" "$libname" :
+      func_generate_dlsyms "$libname" "$libname" "yes"
       func_append libobjs " $symfileobj"
-      test " " = "$libobjs" && libobjs=
+      test "X$libobjs" = "X " && libobjs=
 
-      if test relink != "$opt_mode"; then
+      if test "$opt_mode" != relink; then
 	# Remove our outputs, but don't remove object files since they
 	# may have been created when compiling PIC objects.
 	removelist=
@@ -9051,8 +7556,8 @@ func_mode_link ()
 	  case $p in
 	    *.$objext | *.gcno)
 	       ;;
-	    $output_objdir/$outputname | $output_objdir/$libname.* | $output_objdir/$libname$release.*)
-	       if test -n "$precious_files_regex"; then
+	    $output_objdir/$outputname | $output_objdir/$libname.* | $output_objdir/${libname}${release}.*)
+	       if test "X$precious_files_regex" != "X"; then
 		 if $ECHO "$p" | $EGREP -e "$precious_files_regex" >/dev/null 2>&1
 		 then
 		   continue
@@ -9068,11 +7573,11 @@ func_mode_link ()
       fi
 
       # Now set the variables for building old libraries.
-      if test yes = "$build_old_libs" && test convenience != "$build_libtool_libs"; then
+      if test "$build_old_libs" = yes && test "$build_libtool_libs" != convenience ; then
 	func_append oldlibs " $output_objdir/$libname.$libext"
 
 	# Transform .lo files to .o files.
-	oldobjs="$objs "`$ECHO "$libobjs" | $SP2NL | $SED "/\.$libext$/d; $lo2o" | $NL2SP`
+	oldobjs="$objs "`$ECHO "$libobjs" | $SP2NL | $SED "/\.${libext}$/d; $lo2o" | $NL2SP`
       fi
 
       # Eliminate all temporary directories.
@@ -9093,13 +7598,13 @@ func_mode_link ()
 	  *) func_append finalize_rpath " $libdir" ;;
 	  esac
 	done
-	if test yes != "$hardcode_into_libs" || test yes = "$build_old_libs"; then
+	if test "$hardcode_into_libs" != yes || test "$build_old_libs" = yes; then
 	  dependency_libs="$temp_xrpath $dependency_libs"
 	fi
       fi
 
       # Make sure dlfiles contains only unique files that won't be dlpreopened
-      old_dlfiles=$dlfiles
+      old_dlfiles="$dlfiles"
       dlfiles=
       for lib in $old_dlfiles; do
 	case " $dlprefiles $dlfiles " in
@@ -9109,7 +7614,7 @@ func_mode_link ()
       done
 
       # Make sure dlprefiles contains only unique files
-      old_dlprefiles=$dlprefiles
+      old_dlprefiles="$dlprefiles"
       dlprefiles=
       for lib in $old_dlprefiles; do
 	case "$dlprefiles " in
@@ -9118,7 +7623,7 @@ func_mode_link ()
 	esac
       done
 
-      if test yes = "$build_libtool_libs"; then
+      if test "$build_libtool_libs" = yes; then
 	if test -n "$rpath"; then
 	  case $host in
 	  *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-beos* | *-cegcc* | *-*-haiku*)
@@ -9142,7 +7647,7 @@ func_mode_link ()
 	    ;;
 	  *)
 	    # Add libc to deplibs on all other systems if necessary.
-	    if test yes = "$build_libtool_need_lc"; then
+	    if test "$build_libtool_need_lc" = "yes"; then
 	      func_append deplibs " -lc"
 	    fi
 	    ;;
@@ -9158,9 +7663,9 @@ func_mode_link ()
 	# I'm not sure if I'm treating the release correctly.  I think
 	# release should show up in the -l (ie -lgmp5) so we don't want to
 	# add it in twice.  Is that correct?
-	release=
-	versuffix=
-	major=
+	release=""
+	versuffix=""
+	major=""
 	newdeplibs=
 	droppeddeps=no
 	case $deplibs_check_method in
@@ -9189,20 +7694,20 @@ EOF
 	      -l*)
 		func_stripname -l '' "$i"
 		name=$func_stripname_result
-		if test yes = "$allow_libtool_libs_with_static_runtimes"; then
+		if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
 		  case " $predeps $postdeps " in
 		  *" $i "*)
 		    func_append newdeplibs " $i"
-		    i=
+		    i=""
 		    ;;
 		  esac
 		fi
-		if test -n "$i"; then
+		if test -n "$i" ; then
 		  libname=`eval "\\$ECHO \"$libname_spec\""`
 		  deplib_matches=`eval "\\$ECHO \"$library_names_spec\""`
 		  set dummy $deplib_matches; shift
 		  deplib_match=$1
-		  if test `expr "$ldd_output" : ".*$deplib_match"` -ne 0; then
+		  if test `expr "$ldd_output" : ".*$deplib_match"` -ne 0 ; then
 		    func_append newdeplibs " $i"
 		  else
 		    droppeddeps=yes
@@ -9232,20 +7737,20 @@ EOF
 		$opt_dry_run || $RM conftest
 		if $LTCC $LTCFLAGS -o conftest conftest.c $i; then
 		  ldd_output=`ldd conftest`
-		  if test yes = "$allow_libtool_libs_with_static_runtimes"; then
+		  if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
 		    case " $predeps $postdeps " in
 		    *" $i "*)
 		      func_append newdeplibs " $i"
-		      i=
+		      i=""
 		      ;;
 		    esac
 		  fi
-		  if test -n "$i"; then
+		  if test -n "$i" ; then
 		    libname=`eval "\\$ECHO \"$libname_spec\""`
 		    deplib_matches=`eval "\\$ECHO \"$library_names_spec\""`
 		    set dummy $deplib_matches; shift
 		    deplib_match=$1
-		    if test `expr "$ldd_output" : ".*$deplib_match"` -ne 0; then
+		    if test `expr "$ldd_output" : ".*$deplib_match"` -ne 0 ; then
 		      func_append newdeplibs " $i"
 		    else
 		      droppeddeps=yes
@@ -9282,24 +7787,24 @@ EOF
 	    -l*)
 	      func_stripname -l '' "$a_deplib"
 	      name=$func_stripname_result
-	      if test yes = "$allow_libtool_libs_with_static_runtimes"; then
+	      if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
 		case " $predeps $postdeps " in
 		*" $a_deplib "*)
 		  func_append newdeplibs " $a_deplib"
-		  a_deplib=
+		  a_deplib=""
 		  ;;
 		esac
 	      fi
-	      if test -n "$a_deplib"; then
+	      if test -n "$a_deplib" ; then
 		libname=`eval "\\$ECHO \"$libname_spec\""`
 		if test -n "$file_magic_glob"; then
 		  libnameglob=`func_echo_all "$libname" | $SED -e $file_magic_glob`
 		else
 		  libnameglob=$libname
 		fi
-		test yes = "$want_nocaseglob" && nocaseglob=`shopt -p nocaseglob`
+		test "$want_nocaseglob" = yes && nocaseglob=`shopt -p nocaseglob`
 		for i in $lib_search_path $sys_lib_search_path $shlib_search_path; do
-		  if test yes = "$want_nocaseglob"; then
+		  if test "$want_nocaseglob" = yes; then
 		    shopt -s nocaseglob
 		    potential_libs=`ls $i/$libnameglob[.-]* 2>/dev/null`
 		    $nocaseglob
@@ -9317,25 +7822,25 @@ EOF
 		      # We might still enter an endless loop, since a link
 		      # loop can be closed while we follow links,
 		      # but so what?
-		      potlib=$potent_lib
+		      potlib="$potent_lib"
 		      while test -h "$potlib" 2>/dev/null; do
-			potliblink=`ls -ld $potlib | $SED 's/.* -> //'`
+			potliblink=`ls -ld $potlib | ${SED} 's/.* -> //'`
 			case $potliblink in
-			[\\/]* | [A-Za-z]:[\\/]*) potlib=$potliblink;;
-			*) potlib=`$ECHO "$potlib" | $SED 's|[^/]*$||'`"$potliblink";;
+			[\\/]* | [A-Za-z]:[\\/]*) potlib="$potliblink";;
+			*) potlib=`$ECHO "$potlib" | $SED 's,[^/]*$,,'`"$potliblink";;
 			esac
 		      done
 		      if eval $file_magic_cmd \"\$potlib\" 2>/dev/null |
 			 $SED -e 10q |
 			 $EGREP "$file_magic_regex" > /dev/null; then
 			func_append newdeplibs " $a_deplib"
-			a_deplib=
+			a_deplib=""
 			break 2
 		      fi
 		  done
 		done
 	      fi
-	      if test -n "$a_deplib"; then
+	      if test -n "$a_deplib" ; then
 		droppeddeps=yes
 		echo
 		$ECHO "*** Warning: linker path does not have real file for library $a_deplib."
@@ -9343,7 +7848,7 @@ EOF
 		echo "*** you link to this library.  But I can only do this if you have a"
 		echo "*** shared version of the library, which you do not appear to have"
 		echo "*** because I did check the linker path looking for a file starting"
-		if test -z "$potlib"; then
+		if test -z "$potlib" ; then
 		  $ECHO "*** with $libname but no candidates were found. (...for file magic test)"
 		else
 		  $ECHO "*** with $libname and none of the candidates passed a file format test"
@@ -9366,30 +7871,30 @@ EOF
 	    -l*)
 	      func_stripname -l '' "$a_deplib"
 	      name=$func_stripname_result
-	      if test yes = "$allow_libtool_libs_with_static_runtimes"; then
+	      if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
 		case " $predeps $postdeps " in
 		*" $a_deplib "*)
 		  func_append newdeplibs " $a_deplib"
-		  a_deplib=
+		  a_deplib=""
 		  ;;
 		esac
 	      fi
-	      if test -n "$a_deplib"; then
+	      if test -n "$a_deplib" ; then
 		libname=`eval "\\$ECHO \"$libname_spec\""`
 		for i in $lib_search_path $sys_lib_search_path $shlib_search_path; do
 		  potential_libs=`ls $i/$libname[.-]* 2>/dev/null`
 		  for potent_lib in $potential_libs; do
-		    potlib=$potent_lib # see symlink-check above in file_magic test
+		    potlib="$potent_lib" # see symlink-check above in file_magic test
 		    if eval "\$ECHO \"$potent_lib\"" 2>/dev/null | $SED 10q | \
 		       $EGREP "$match_pattern_regex" > /dev/null; then
 		      func_append newdeplibs " $a_deplib"
-		      a_deplib=
+		      a_deplib=""
 		      break 2
 		    fi
 		  done
 		done
 	      fi
-	      if test -n "$a_deplib"; then
+	      if test -n "$a_deplib" ; then
 		droppeddeps=yes
 		echo
 		$ECHO "*** Warning: linker path does not have real file for library $a_deplib."
@@ -9397,7 +7902,7 @@ EOF
 		echo "*** you link to this library.  But I can only do this if you have a"
 		echo "*** shared version of the library, which you do not appear to have"
 		echo "*** because I did check the linker path looking for a file starting"
-		if test -z "$potlib"; then
+		if test -z "$potlib" ; then
 		  $ECHO "*** with $libname but no candidates were found. (...for regex pattern test)"
 		else
 		  $ECHO "*** with $libname and none of the candidates passed a file format test"
@@ -9413,18 +7918,18 @@ EOF
 	  done # Gone through all deplibs.
 	  ;;
 	none | unknown | *)
-	  newdeplibs=
+	  newdeplibs=""
 	  tmp_deplibs=`$ECHO " $deplibs" | $SED 's/ -lc$//; s/ -[LR][^ ]*//g'`
-	  if test yes = "$allow_libtool_libs_with_static_runtimes"; then
-	    for i in $predeps $postdeps; do
+	  if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
+	    for i in $predeps $postdeps ; do
 	      # can't use Xsed below, because $i might contain '/'
-	      tmp_deplibs=`$ECHO " $tmp_deplibs" | $SED "s|$i||"`
+	      tmp_deplibs=`$ECHO " $tmp_deplibs" | $SED "s,$i,,"`
 	    done
 	  fi
 	  case $tmp_deplibs in
 	  *[!\	\ ]*)
 	    echo
-	    if test none = "$deplibs_check_method"; then
+	    if test "X$deplibs_check_method" = "Xnone"; then
 	      echo "*** Warning: inter-library dependencies are not supported in this platform."
 	    else
 	      echo "*** Warning: inter-library dependencies are not known to be supported."
@@ -9448,8 +7953,8 @@ EOF
 	  ;;
 	esac
 
-	if test yes = "$droppeddeps"; then
-	  if test yes = "$module"; then
+	if test "$droppeddeps" = yes; then
+	  if test "$module" = yes; then
 	    echo
 	    echo "*** Warning: libtool could not satisfy all declared inter-library"
 	    $ECHO "*** dependencies of module $libname.  Therefore, libtool will create"
@@ -9458,12 +7963,12 @@ EOF
 	    if test -z "$global_symbol_pipe"; then
 	      echo
 	      echo "*** However, this would only work if libtool was able to extract symbol"
-	      echo "*** lists from a program, using 'nm' or equivalent, but libtool could"
+	      echo "*** lists from a program, using \`nm' or equivalent, but libtool could"
 	      echo "*** not find such a program.  So, this module is probably useless."
-	      echo "*** 'nm' from GNU binutils and a full rebuild may help."
+	      echo "*** \`nm' from GNU binutils and a full rebuild may help."
 	    fi
-	    if test no = "$build_old_libs"; then
-	      oldlibs=$output_objdir/$libname.$libext
+	    if test "$build_old_libs" = no; then
+	      oldlibs="$output_objdir/$libname.$libext"
 	      build_libtool_libs=module
 	      build_old_libs=yes
 	    else
@@ -9474,14 +7979,14 @@ EOF
 	    echo "*** automatically added whenever a program is linked with this library"
 	    echo "*** or is declared to -dlopen it."
 
-	    if test no = "$allow_undefined"; then
+	    if test "$allow_undefined" = no; then
 	      echo
 	      echo "*** Since this library must not contain undefined symbols,"
 	      echo "*** because either the platform does not support them or"
 	      echo "*** it was explicitly requested with -no-undefined,"
 	      echo "*** libtool will only create a static version of it."
-	      if test no = "$build_old_libs"; then
-		oldlibs=$output_objdir/$libname.$libext
+	      if test "$build_old_libs" = no; then
+		oldlibs="$output_objdir/$libname.$libext"
 		build_libtool_libs=module
 		build_old_libs=yes
 	      else
@@ -9527,7 +8032,7 @@ EOF
 	*) func_append new_libs " $deplib" ;;
 	esac
       done
-      deplibs=$new_libs
+      deplibs="$new_libs"
 
       # All the library-specific variables (install_libdir is set above).
       library_names=
@@ -9535,25 +8040,25 @@ EOF
       dlname=
 
       # Test again, we may have decided not to build it any more
-      if test yes = "$build_libtool_libs"; then
-	# Remove $wl instances when linking with ld.
+      if test "$build_libtool_libs" = yes; then
+	# Remove ${wl} instances when linking with ld.
 	# FIXME: should test the right _cmds variable.
 	case $archive_cmds in
 	  *\$LD\ *) wl= ;;
         esac
-	if test yes = "$hardcode_into_libs"; then
+	if test "$hardcode_into_libs" = yes; then
 	  # Hardcode the library paths
 	  hardcode_libdirs=
 	  dep_rpath=
-	  rpath=$finalize_rpath
-	  test relink = "$opt_mode" || rpath=$compile_rpath$rpath
+	  rpath="$finalize_rpath"
+	  test "$opt_mode" != relink && rpath="$compile_rpath$rpath"
 	  for libdir in $rpath; do
 	    if test -n "$hardcode_libdir_flag_spec"; then
 	      if test -n "$hardcode_libdir_separator"; then
 		func_replace_sysroot "$libdir"
 		libdir=$func_replace_sysroot_result
 		if test -z "$hardcode_libdirs"; then
-		  hardcode_libdirs=$libdir
+		  hardcode_libdirs="$libdir"
 		else
 		  # Just accumulate the unique libdirs.
 		  case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in
@@ -9578,7 +8083,7 @@ EOF
 	  # Substitute the hardcoded libdirs into the rpath.
 	  if test -n "$hardcode_libdir_separator" &&
 	     test -n "$hardcode_libdirs"; then
-	    libdir=$hardcode_libdirs
+	    libdir="$hardcode_libdirs"
 	    eval "dep_rpath=\"$hardcode_libdir_flag_spec\""
 	  fi
 	  if test -n "$runpath_var" && test -n "$perm_rpath"; then
@@ -9592,8 +8097,8 @@ EOF
 	  test -n "$dep_rpath" && deplibs="$dep_rpath $deplibs"
 	fi
 
-	shlibpath=$finalize_shlibpath
-	test relink = "$opt_mode" || shlibpath=$compile_shlibpath$shlibpath
+	shlibpath="$finalize_shlibpath"
+	test "$opt_mode" != relink && shlibpath="$compile_shlibpath$shlibpath"
 	if test -n "$shlibpath"; then
 	  eval "$shlibpath_var='$shlibpath\$$shlibpath_var'; export $shlibpath_var"
 	fi
@@ -9603,19 +8108,19 @@ EOF
 	eval library_names=\"$library_names_spec\"
 	set dummy $library_names
 	shift
-	realname=$1
+	realname="$1"
 	shift
 
 	if test -n "$soname_spec"; then
 	  eval soname=\"$soname_spec\"
 	else
-	  soname=$realname
+	  soname="$realname"
 	fi
 	if test -z "$dlname"; then
 	  dlname=$soname
 	fi
 
-	lib=$output_objdir/$realname
+	lib="$output_objdir/$realname"
 	linknames=
 	for link
 	do
@@ -9629,7 +8134,7 @@ EOF
 	delfiles=
 	if test -n "$export_symbols" && test -n "$include_expsyms"; then
 	  $opt_dry_run || cp "$export_symbols" "$output_objdir/$libname.uexp"
-	  export_symbols=$output_objdir/$libname.uexp
+	  export_symbols="$output_objdir/$libname.uexp"
 	  func_append delfiles " $export_symbols"
 	fi
 
@@ -9638,31 +8143,31 @@ EOF
 	cygwin* | mingw* | cegcc*)
 	  if test -n "$export_symbols" && test -z "$export_symbols_regex"; then
 	    # exporting using user supplied symfile
-	    func_dll_def_p "$export_symbols" || {
+	    if test "x`$SED 1q $export_symbols`" != xEXPORTS; then
 	      # and it's NOT already a .def file. Must figure out
 	      # which of the given symbols are data symbols and tag
 	      # them as such. So, trigger use of export_symbols_cmds.
 	      # export_symbols gets reassigned inside the "prepare
 	      # the list of exported symbols" if statement, so the
 	      # include_expsyms logic still works.
-	      orig_export_symbols=$export_symbols
+	      orig_export_symbols="$export_symbols"
 	      export_symbols=
 	      always_export_symbols=yes
-	    }
+	    fi
 	  fi
 	  ;;
 	esac
 
 	# Prepare the list of exported symbols
 	if test -z "$export_symbols"; then
-	  if test yes = "$always_export_symbols" || test -n "$export_symbols_regex"; then
-	    func_verbose "generating symbol list for '$libname.la'"
-	    export_symbols=$output_objdir/$libname.exp
+	  if test "$always_export_symbols" = yes || test -n "$export_symbols_regex"; then
+	    func_verbose "generating symbol list for \`$libname.la'"
+	    export_symbols="$output_objdir/$libname.exp"
 	    $opt_dry_run || $RM $export_symbols
 	    cmds=$export_symbols_cmds
-	    save_ifs=$IFS; IFS='~'
+	    save_ifs="$IFS"; IFS='~'
 	    for cmd1 in $cmds; do
-	      IFS=$save_ifs
+	      IFS="$save_ifs"
 	      # Take the normal branch if the nm_file_list_spec branch
 	      # doesn't work or if tool conversion is not needed.
 	      case $nm_file_list_spec~$to_tool_file_cmd in
@@ -9676,7 +8181,7 @@ EOF
 		  try_normal_branch=no
 		  ;;
 	      esac
-	      if test yes = "$try_normal_branch" \
+	      if test "$try_normal_branch" = yes \
 		 && { test "$len" -lt "$max_cmd_len" \
 		      || test "$max_cmd_len" -le -1; }
 	      then
@@ -9687,7 +8192,7 @@ EOF
 		output_la=$func_basename_result
 		save_libobjs=$libobjs
 		save_output=$output
-		output=$output_objdir/$output_la.nm
+		output=${output_objdir}/${output_la}.nm
 		func_to_tool_file "$output"
 		libobjs=$nm_file_list_spec$func_to_tool_file_result
 		func_append delfiles " $output"
@@ -9710,8 +8215,8 @@ EOF
 		break
 	      fi
 	    done
-	    IFS=$save_ifs
-	    if test -n "$export_symbols_regex" && test : != "$skipped_export"; then
+	    IFS="$save_ifs"
+	    if test -n "$export_symbols_regex" && test "X$skipped_export" != "X:"; then
 	      func_show_eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"'
 	      func_show_eval '$MV "${export_symbols}T" "$export_symbols"'
 	    fi
@@ -9719,16 +8224,16 @@ EOF
 	fi
 
 	if test -n "$export_symbols" && test -n "$include_expsyms"; then
-	  tmp_export_symbols=$export_symbols
-	  test -n "$orig_export_symbols" && tmp_export_symbols=$orig_export_symbols
+	  tmp_export_symbols="$export_symbols"
+	  test -n "$orig_export_symbols" && tmp_export_symbols="$orig_export_symbols"
 	  $opt_dry_run || eval '$ECHO "$include_expsyms" | $SP2NL >> "$tmp_export_symbols"'
 	fi
 
-	if test : != "$skipped_export" && test -n "$orig_export_symbols"; then
+	if test "X$skipped_export" != "X:" && test -n "$orig_export_symbols"; then
 	  # The given exports_symbols file has to be filtered, so filter it.
-	  func_verbose "filter symbol list for '$libname.la' to tag DATA exports"
+	  func_verbose "filter symbol list for \`$libname.la' to tag DATA exports"
 	  # FIXME: $output_objdir/$libname.filter potentially contains lots of
-	  # 's' commands, which not all seds can handle. GNU sed should be fine
+	  # 's' commands which not all seds can handle. GNU sed should be fine
 	  # though. Also, the filter scales superlinearly with the number of
 	  # global variables. join(1) would be nice here, but unfortunately
 	  # isn't a blessed tool.
@@ -9747,11 +8252,11 @@ EOF
 	    ;;
 	  esac
 	done
-	deplibs=$tmp_deplibs
+	deplibs="$tmp_deplibs"
 
 	if test -n "$convenience"; then
 	  if test -n "$whole_archive_flag_spec" &&
-	    test yes = "$compiler_needs_object" &&
+	    test "$compiler_needs_object" = yes &&
 	    test -z "$libobjs"; then
 	    # extract the archives, so we have objects to list.
 	    # TODO: could optimize this to just extract one archive.
@@ -9762,7 +8267,7 @@ EOF
 	    eval libobjs=\"\$libobjs $whole_archive_flag_spec\"
 	    test "X$libobjs" = "X " && libobjs=
 	  else
-	    gentop=$output_objdir/${outputname}x
+	    gentop="$output_objdir/${outputname}x"
 	    func_append generated " $gentop"
 
 	    func_extract_archives $gentop $convenience
@@ -9771,18 +8276,18 @@ EOF
 	  fi
 	fi
 
-	if test yes = "$thread_safe" && test -n "$thread_safe_flag_spec"; then
+	if test "$thread_safe" = yes && test -n "$thread_safe_flag_spec"; then
 	  eval flag=\"$thread_safe_flag_spec\"
 	  func_append linker_flags " $flag"
 	fi
 
 	# Make a backup of the uninstalled library when relinking
-	if test relink = "$opt_mode"; then
+	if test "$opt_mode" = relink; then
 	  $opt_dry_run || eval '(cd $output_objdir && $RM ${realname}U && $MV $realname ${realname}U)' || exit $?
 	fi
 
 	# Do each of the archive commands.
-	if test yes = "$module" && test -n "$module_cmds"; then
+	if test "$module" = yes && test -n "$module_cmds" ; then
 	  if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then
 	    eval test_cmds=\"$module_expsym_cmds\"
 	    cmds=$module_expsym_cmds
@@ -9800,7 +8305,7 @@ EOF
 	  fi
 	fi
 
-	if test : != "$skipped_export" &&
+	if test "X$skipped_export" != "X:" &&
 	   func_len " $test_cmds" &&
 	   len=$func_len_result &&
 	   test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then
@@ -9833,8 +8338,8 @@ EOF
 	  last_robj=
 	  k=1
 
-	  if test -n "$save_libobjs" && test : != "$skipped_export" && test yes = "$with_gnu_ld"; then
-	    output=$output_objdir/$output_la.lnkscript
+	  if test -n "$save_libobjs" && test "X$skipped_export" != "X:" && test "$with_gnu_ld" = yes; then
+	    output=${output_objdir}/${output_la}.lnkscript
 	    func_verbose "creating GNU ld script: $output"
 	    echo 'INPUT (' > $output
 	    for obj in $save_libobjs
@@ -9846,14 +8351,14 @@ EOF
 	    func_append delfiles " $output"
 	    func_to_tool_file "$output"
 	    output=$func_to_tool_file_result
-	  elif test -n "$save_libobjs" && test : != "$skipped_export" && test -n "$file_list_spec"; then
-	    output=$output_objdir/$output_la.lnk
+	  elif test -n "$save_libobjs" && test "X$skipped_export" != "X:" && test "X$file_list_spec" != X; then
+	    output=${output_objdir}/${output_la}.lnk
 	    func_verbose "creating linker input file list: $output"
 	    : > $output
 	    set x $save_libobjs
 	    shift
 	    firstobj=
-	    if test yes = "$compiler_needs_object"; then
+	    if test "$compiler_needs_object" = yes; then
 	      firstobj="$1 "
 	      shift
 	    fi
@@ -9868,7 +8373,7 @@ EOF
 	  else
 	    if test -n "$save_libobjs"; then
 	      func_verbose "creating reloadable object files..."
-	      output=$output_objdir/$output_la-$k.$objext
+	      output=$output_objdir/$output_la-${k}.$objext
 	      eval test_cmds=\"$reload_cmds\"
 	      func_len " $test_cmds"
 	      len0=$func_len_result
@@ -9880,13 +8385,13 @@ EOF
 		func_len " $obj"
 		func_arith $len + $func_len_result
 		len=$func_arith_result
-		if test -z "$objlist" ||
+		if test "X$objlist" = X ||
 		   test "$len" -lt "$max_cmd_len"; then
 		  func_append objlist " $obj"
 		else
 		  # The command $test_cmds is almost too long, add a
 		  # command to the queue.
-		  if test 1 -eq "$k"; then
+		  if test "$k" -eq 1 ; then
 		    # The first file doesn't have a previous command to add.
 		    reload_objs=$objlist
 		    eval concat_cmds=\"$reload_cmds\"
@@ -9896,10 +8401,10 @@ EOF
 		    reload_objs="$objlist $last_robj"
 		    eval concat_cmds=\"\$concat_cmds~$reload_cmds~\$RM $last_robj\"
 		  fi
-		  last_robj=$output_objdir/$output_la-$k.$objext
+		  last_robj=$output_objdir/$output_la-${k}.$objext
 		  func_arith $k + 1
 		  k=$func_arith_result
-		  output=$output_objdir/$output_la-$k.$objext
+		  output=$output_objdir/$output_la-${k}.$objext
 		  objlist=" $obj"
 		  func_len " $last_robj"
 		  func_arith $len0 + $func_len_result
@@ -9911,9 +8416,9 @@ EOF
 	      # files will link in the last one created.
 	      test -z "$concat_cmds" || concat_cmds=$concat_cmds~
 	      reload_objs="$objlist $last_robj"
-	      eval concat_cmds=\"\$concat_cmds$reload_cmds\"
+	      eval concat_cmds=\"\${concat_cmds}$reload_cmds\"
 	      if test -n "$last_robj"; then
-	        eval concat_cmds=\"\$concat_cmds~\$RM $last_robj\"
+	        eval concat_cmds=\"\${concat_cmds}~\$RM $last_robj\"
 	      fi
 	      func_append delfiles " $output"
 
@@ -9921,9 +8426,9 @@ EOF
 	      output=
 	    fi
 
-	    ${skipped_export-false} && {
-	      func_verbose "generating symbol list for '$libname.la'"
-	      export_symbols=$output_objdir/$libname.exp
+	    if ${skipped_export-false}; then
+	      func_verbose "generating symbol list for \`$libname.la'"
+	      export_symbols="$output_objdir/$libname.exp"
 	      $opt_dry_run || $RM $export_symbols
 	      libobjs=$output
 	      # Append the command to create the export file.
@@ -9932,16 +8437,16 @@ EOF
 	      if test -n "$last_robj"; then
 		eval concat_cmds=\"\$concat_cmds~\$RM $last_robj\"
 	      fi
-	    }
+	    fi
 
 	    test -n "$save_libobjs" &&
 	      func_verbose "creating a temporary reloadable object file: $output"
 
 	    # Loop through the commands generated above and execute them.
-	    save_ifs=$IFS; IFS='~'
+	    save_ifs="$IFS"; IFS='~'
 	    for cmd in $concat_cmds; do
-	      IFS=$save_ifs
-	      $opt_quiet || {
+	      IFS="$save_ifs"
+	      $opt_silent || {
 		  func_quote_for_expand "$cmd"
 		  eval "func_echo $func_quote_for_expand_result"
 	      }
@@ -9949,7 +8454,7 @@ EOF
 		lt_exit=$?
 
 		# Restore the uninstalled library and exit
-		if test relink = "$opt_mode"; then
+		if test "$opt_mode" = relink; then
 		  ( cd "$output_objdir" && \
 		    $RM "${realname}T" && \
 		    $MV "${realname}U" "$realname" )
@@ -9958,7 +8463,7 @@ EOF
 		exit $lt_exit
 	      }
 	    done
-	    IFS=$save_ifs
+	    IFS="$save_ifs"
 
 	    if test -n "$export_symbols_regex" && ${skipped_export-false}; then
 	      func_show_eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"'
@@ -9966,18 +8471,18 @@ EOF
 	    fi
 	  fi
 
-          ${skipped_export-false} && {
+          if ${skipped_export-false}; then
 	    if test -n "$export_symbols" && test -n "$include_expsyms"; then
-	      tmp_export_symbols=$export_symbols
-	      test -n "$orig_export_symbols" && tmp_export_symbols=$orig_export_symbols
+	      tmp_export_symbols="$export_symbols"
+	      test -n "$orig_export_symbols" && tmp_export_symbols="$orig_export_symbols"
 	      $opt_dry_run || eval '$ECHO "$include_expsyms" | $SP2NL >> "$tmp_export_symbols"'
 	    fi
 
 	    if test -n "$orig_export_symbols"; then
 	      # The given exports_symbols file has to be filtered, so filter it.
-	      func_verbose "filter symbol list for '$libname.la' to tag DATA exports"
+	      func_verbose "filter symbol list for \`$libname.la' to tag DATA exports"
 	      # FIXME: $output_objdir/$libname.filter potentially contains lots of
-	      # 's' commands, which not all seds can handle. GNU sed should be fine
+	      # 's' commands which not all seds can handle. GNU sed should be fine
 	      # though. Also, the filter scales superlinearly with the number of
 	      # global variables. join(1) would be nice here, but unfortunately
 	      # isn't a blessed tool.
@@ -9986,7 +8491,7 @@ EOF
 	      export_symbols=$output_objdir/$libname.def
 	      $opt_dry_run || $SED -f $output_objdir/$libname.filter < $orig_export_symbols > $export_symbols
 	    fi
-	  }
+	  fi
 
 	  libobjs=$output
 	  # Restore the value of output.
@@ -10000,7 +8505,7 @@ EOF
 	  # value of $libobjs for piecewise linking.
 
 	  # Do each of the archive commands.
-	  if test yes = "$module" && test -n "$module_cmds"; then
+	  if test "$module" = yes && test -n "$module_cmds" ; then
 	    if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then
 	      cmds=$module_expsym_cmds
 	    else
@@ -10022,7 +8527,7 @@ EOF
 
 	# Add any objects from preloaded convenience libraries
 	if test -n "$dlprefiles"; then
-	  gentop=$output_objdir/${outputname}x
+	  gentop="$output_objdir/${outputname}x"
 	  func_append generated " $gentop"
 
 	  func_extract_archives $gentop $dlprefiles
@@ -10030,12 +8535,11 @@ EOF
 	  test "X$libobjs" = "X " && libobjs=
 	fi
 
-	save_ifs=$IFS; IFS='~'
+	save_ifs="$IFS"; IFS='~'
 	for cmd in $cmds; do
-	  IFS=$sp$nl
+	  IFS="$save_ifs"
 	  eval cmd=\"$cmd\"
-	  IFS=$save_ifs
-	  $opt_quiet || {
+	  $opt_silent || {
 	    func_quote_for_expand "$cmd"
 	    eval "func_echo $func_quote_for_expand_result"
 	  }
@@ -10043,7 +8547,7 @@ EOF
 	    lt_exit=$?
 
 	    # Restore the uninstalled library and exit
-	    if test relink = "$opt_mode"; then
+	    if test "$opt_mode" = relink; then
 	      ( cd "$output_objdir" && \
 	        $RM "${realname}T" && \
 		$MV "${realname}U" "$realname" )
@@ -10052,10 +8556,10 @@ EOF
 	    exit $lt_exit
 	  }
 	done
-	IFS=$save_ifs
+	IFS="$save_ifs"
 
 	# Restore the uninstalled library and exit
-	if test relink = "$opt_mode"; then
+	if test "$opt_mode" = relink; then
 	  $opt_dry_run || eval '(cd $output_objdir && $RM ${realname}T && $MV $realname ${realname}T && $MV ${realname}U $realname)' || exit $?
 
 	  if test -n "$convenience"; then
@@ -10075,39 +8579,39 @@ EOF
 	done
 
 	# If -module or -export-dynamic was specified, set the dlname.
-	if test yes = "$module" || test yes = "$export_dynamic"; then
+	if test "$module" = yes || test "$export_dynamic" = yes; then
 	  # On all known operating systems, these are identical.
-	  dlname=$soname
+	  dlname="$soname"
 	fi
       fi
       ;;
 
     obj)
-      if test -n "$dlfiles$dlprefiles" || test no != "$dlself"; then
-	func_warning "'-dlopen' is ignored for objects"
+      if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then
+	func_warning "\`-dlopen' is ignored for objects"
       fi
 
       case " $deplibs" in
       *\ -l* | *\ -L*)
-	func_warning "'-l' and '-L' are ignored for objects" ;;
+	func_warning "\`-l' and \`-L' are ignored for objects" ;;
       esac
 
       test -n "$rpath" && \
-	func_warning "'-rpath' is ignored for objects"
+	func_warning "\`-rpath' is ignored for objects"
 
       test -n "$xrpath" && \
-	func_warning "'-R' is ignored for objects"
+	func_warning "\`-R' is ignored for objects"
 
       test -n "$vinfo" && \
-	func_warning "'-version-info' is ignored for objects"
+	func_warning "\`-version-info' is ignored for objects"
 
       test -n "$release" && \
-	func_warning "'-release' is ignored for objects"
+	func_warning "\`-release' is ignored for objects"
 
       case $output in
       *.lo)
 	test -n "$objs$old_deplibs" && \
-	  func_fatal_error "cannot build library object '$output' from non-libtool objects"
+	  func_fatal_error "cannot build library object \`$output' from non-libtool objects"
 
 	libobj=$output
 	func_lo2o "$libobj"
@@ -10115,7 +8619,7 @@ EOF
 	;;
       *)
 	libobj=
-	obj=$output
+	obj="$output"
 	;;
       esac
 
@@ -10128,19 +8632,17 @@ EOF
       # the extraction.
       reload_conv_objs=
       gentop=
-      # if reload_cmds runs $LD directly, get rid of -Wl from
-      # whole_archive_flag_spec and hope we can get by with turning comma
-      # into space.
-      case $reload_cmds in
-        *\$LD[\ \$]*) wl= ;;
-      esac
+      # reload_cmds runs $LD directly, so let us get rid of
+      # -Wl from whole_archive_flag_spec and hope we can get by with
+      # turning comma into space..
+      wl=
+
       if test -n "$convenience"; then
 	if test -n "$whole_archive_flag_spec"; then
 	  eval tmp_whole_archive_flags=\"$whole_archive_flag_spec\"
-	  test -n "$wl" || tmp_whole_archive_flags=`$ECHO "$tmp_whole_archive_flags" | $SED 's|,| |g'`
-	  reload_conv_objs=$reload_objs\ $tmp_whole_archive_flags
+	  reload_conv_objs=$reload_objs\ `$ECHO "$tmp_whole_archive_flags" | $SED 's|,| |g'`
 	else
-	  gentop=$output_objdir/${obj}x
+	  gentop="$output_objdir/${obj}x"
 	  func_append generated " $gentop"
 
 	  func_extract_archives $gentop $convenience
@@ -10149,12 +8651,12 @@ EOF
       fi
 
       # If we're not building shared, we need to use non_pic_objs
-      test yes = "$build_libtool_libs" || libobjs=$non_pic_objects
+      test "$build_libtool_libs" != yes && libobjs="$non_pic_objects"
 
       # Create the old-style object.
-      reload_objs=$objs$old_deplibs' '`$ECHO "$libobjs" | $SP2NL | $SED "/\.$libext$/d; /\.lib$/d; $lo2o" | $NL2SP`' '$reload_conv_objs
+      reload_objs="$objs$old_deplibs "`$ECHO "$libobjs" | $SP2NL | $SED "/\.${libext}$/d; /\.lib$/d; $lo2o" | $NL2SP`" $reload_conv_objs" ### testsuite: skip nested quoting test
 
-      output=$obj
+      output="$obj"
       func_execute_cmds "$reload_cmds" 'exit $?'
 
       # Exit if we aren't doing a library object file.
@@ -10166,7 +8668,7 @@ EOF
 	exit $EXIT_SUCCESS
       fi
 
-      test yes = "$build_libtool_libs" || {
+      if test "$build_libtool_libs" != yes; then
 	if test -n "$gentop"; then
 	  func_show_eval '${RM}r "$gentop"'
 	fi
@@ -10176,12 +8678,12 @@ EOF
 	# $show "echo timestamp > $libobj"
 	# $opt_dry_run || eval "echo timestamp > $libobj" || exit $?
 	exit $EXIT_SUCCESS
-      }
+      fi
 
-      if test -n "$pic_flag" || test default != "$pic_mode"; then
+      if test -n "$pic_flag" || test "$pic_mode" != default; then
 	# Only do commands if we really have different PIC objects.
 	reload_objs="$libobjs $reload_conv_objs"
-	output=$libobj
+	output="$libobj"
 	func_execute_cmds "$reload_cmds" 'exit $?'
       fi
 
@@ -10198,14 +8700,16 @@ EOF
 	          output=$func_stripname_result.exe;;
       esac
       test -n "$vinfo" && \
-	func_warning "'-version-info' is ignored for programs"
+	func_warning "\`-version-info' is ignored for programs"
 
       test -n "$release" && \
-	func_warning "'-release' is ignored for programs"
+	func_warning "\`-release' is ignored for programs"
 
-      $preload \
-	&& test unknown,unknown,unknown = "$dlopen_support,$dlopen_self,$dlopen_self_static" \
-	&& func_warning "'LT_INIT([dlopen])' not used. Assuming no dlopen support."
+      test "$preload" = yes \
+        && test "$dlopen_support" = unknown \
+	&& test "$dlopen_self" = unknown \
+	&& test "$dlopen_self_static" = unknown && \
+	  func_warning "\`LT_INIT([dlopen])' not used. Assuming no dlopen support."
 
       case $host in
       *-*-rhapsody* | *-*-darwin1.[012])
@@ -10219,11 +8723,11 @@ EOF
       *-*-darwin*)
 	# Don't allow lazy linking, it breaks C++ global constructors
 	# But is supposedly fixed on 10.4 or later (yay!).
-	if test CXX = "$tagname"; then
+	if test "$tagname" = CXX ; then
 	  case ${MACOSX_DEPLOYMENT_TARGET-10.0} in
 	    10.[0123])
-	      func_append compile_command " $wl-bind_at_load"
-	      func_append finalize_command " $wl-bind_at_load"
+	      func_append compile_command " ${wl}-bind_at_load"
+	      func_append finalize_command " ${wl}-bind_at_load"
 	    ;;
 	  esac
 	fi
@@ -10259,7 +8763,7 @@ EOF
 	*) func_append new_libs " $deplib" ;;
 	esac
       done
-      compile_deplibs=$new_libs
+      compile_deplibs="$new_libs"
 
 
       func_append compile_command " $compile_deplibs"
@@ -10283,7 +8787,7 @@ EOF
 	if test -n "$hardcode_libdir_flag_spec"; then
 	  if test -n "$hardcode_libdir_separator"; then
 	    if test -z "$hardcode_libdirs"; then
-	      hardcode_libdirs=$libdir
+	      hardcode_libdirs="$libdir"
 	    else
 	      # Just accumulate the unique libdirs.
 	      case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in
@@ -10306,7 +8810,7 @@ EOF
 	fi
 	case $host in
 	*-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*)
-	  testbindir=`$ECHO "$libdir" | $SED -e 's*/lib$*/bin*'`
+	  testbindir=`${ECHO} "$libdir" | ${SED} -e 's*/lib$*/bin*'`
 	  case :$dllsearchpath: in
 	  *":$libdir:"*) ;;
 	  ::) dllsearchpath=$libdir;;
@@ -10323,10 +8827,10 @@ EOF
       # Substitute the hardcoded libdirs into the rpath.
       if test -n "$hardcode_libdir_separator" &&
 	 test -n "$hardcode_libdirs"; then
-	libdir=$hardcode_libdirs
+	libdir="$hardcode_libdirs"
 	eval rpath=\" $hardcode_libdir_flag_spec\"
       fi
-      compile_rpath=$rpath
+      compile_rpath="$rpath"
 
       rpath=
       hardcode_libdirs=
@@ -10334,7 +8838,7 @@ EOF
 	if test -n "$hardcode_libdir_flag_spec"; then
 	  if test -n "$hardcode_libdir_separator"; then
 	    if test -z "$hardcode_libdirs"; then
-	      hardcode_libdirs=$libdir
+	      hardcode_libdirs="$libdir"
 	    else
 	      # Just accumulate the unique libdirs.
 	      case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in
@@ -10359,43 +8863,45 @@ EOF
       # Substitute the hardcoded libdirs into the rpath.
       if test -n "$hardcode_libdir_separator" &&
 	 test -n "$hardcode_libdirs"; then
-	libdir=$hardcode_libdirs
+	libdir="$hardcode_libdirs"
 	eval rpath=\" $hardcode_libdir_flag_spec\"
       fi
-      finalize_rpath=$rpath
+      finalize_rpath="$rpath"
 
-      if test -n "$libobjs" && test yes = "$build_old_libs"; then
+      if test -n "$libobjs" && test "$build_old_libs" = yes; then
 	# Transform all the library objects into standard objects.
 	compile_command=`$ECHO "$compile_command" | $SP2NL | $SED "$lo2o" | $NL2SP`
 	finalize_command=`$ECHO "$finalize_command" | $SP2NL | $SED "$lo2o" | $NL2SP`
       fi
 
-      func_generate_dlsyms "$outputname" "@PROGRAM@" false
+      func_generate_dlsyms "$outputname" "@PROGRAM@" "no"
 
       # template prelinking step
       if test -n "$prelink_cmds"; then
 	func_execute_cmds "$prelink_cmds" 'exit $?'
       fi
 
-      wrappers_required=:
+      wrappers_required=yes
       case $host in
       *cegcc* | *mingw32ce*)
         # Disable wrappers for cegcc and mingw32ce hosts, we are cross compiling anyway.
-        wrappers_required=false
+        wrappers_required=no
         ;;
       *cygwin* | *mingw* )
-        test yes = "$build_libtool_libs" || wrappers_required=false
+        if test "$build_libtool_libs" != yes; then
+          wrappers_required=no
+        fi
         ;;
       *)
-        if test no = "$need_relink" || test yes != "$build_libtool_libs"; then
-          wrappers_required=false
+        if test "$need_relink" = no || test "$build_libtool_libs" != yes; then
+          wrappers_required=no
         fi
         ;;
       esac
-      $wrappers_required || {
+      if test "$wrappers_required" = no; then
 	# Replace the output file specification.
 	compile_command=`$ECHO "$compile_command" | $SED 's%@OUTPUT@%'"$output"'%g'`
-	link_command=$compile_command$compile_rpath
+	link_command="$compile_command$compile_rpath"
 
 	# We have no uninstalled library dependencies, so finalize right now.
 	exit_status=0
@@ -10408,12 +8914,12 @@ EOF
 	fi
 
 	# Delete the generated files.
-	if test -f "$output_objdir/${outputname}S.$objext"; then
-	  func_show_eval '$RM "$output_objdir/${outputname}S.$objext"'
+	if test -f "$output_objdir/${outputname}S.${objext}"; then
+	  func_show_eval '$RM "$output_objdir/${outputname}S.${objext}"'
 	fi
 
 	exit $exit_status
-      }
+      fi
 
       if test -n "$compile_shlibpath$finalize_shlibpath"; then
 	compile_command="$shlibpath_var=\"$compile_shlibpath$finalize_shlibpath\$$shlibpath_var\" $compile_command"
@@ -10443,9 +8949,9 @@ EOF
 	fi
       fi
 
-      if test yes = "$no_install"; then
+      if test "$no_install" = yes; then
 	# We don't need to create a wrapper script.
-	link_command=$compile_var$compile_command$compile_rpath
+	link_command="$compile_var$compile_command$compile_rpath"
 	# Replace the output file specification.
 	link_command=`$ECHO "$link_command" | $SED 's%@OUTPUT@%'"$output"'%g'`
 	# Delete the old output file.
@@ -10462,28 +8968,27 @@ EOF
 	exit $EXIT_SUCCESS
       fi
 
-      case $hardcode_action,$fast_install in
-        relink,*)
-	  # Fast installation is not supported
-	  link_command=$compile_var$compile_command$compile_rpath
-	  relink_command=$finalize_var$finalize_command$finalize_rpath
+      if test "$hardcode_action" = relink; then
+	# Fast installation is not supported
+	link_command="$compile_var$compile_command$compile_rpath"
+	relink_command="$finalize_var$finalize_command$finalize_rpath"
 
-	  func_warning "this platform does not like uninstalled shared libraries"
-	  func_warning "'$output' will be relinked during installation"
-	  ;;
-        *,yes)
-	  link_command=$finalize_var$compile_command$finalize_rpath
-	  relink_command=`$ECHO "$compile_var$compile_command$compile_rpath" | $SED 's%@OUTPUT@%\$progdir/\$file%g'`
-          ;;
-	*,no)
-	  link_command=$compile_var$compile_command$compile_rpath
-	  relink_command=$finalize_var$finalize_command$finalize_rpath
-          ;;
-	*,needless)
-	  link_command=$finalize_var$compile_command$finalize_rpath
-	  relink_command=
-          ;;
-      esac
+	func_warning "this platform does not like uninstalled shared libraries"
+	func_warning "\`$output' will be relinked during installation"
+      else
+	if test "$fast_install" != no; then
+	  link_command="$finalize_var$compile_command$finalize_rpath"
+	  if test "$fast_install" = yes; then
+	    relink_command=`$ECHO "$compile_var$compile_command$compile_rpath" | $SED 's%@OUTPUT@%\$progdir/\$file%g'`
+	  else
+	    # fast_install is set to needless
+	    relink_command=
+	  fi
+	else
+	  link_command="$compile_var$compile_command$compile_rpath"
+	  relink_command="$finalize_var$finalize_command$finalize_rpath"
+	fi
+      fi
 
       # Replace the output file specification.
       link_command=`$ECHO "$link_command" | $SED 's%@OUTPUT@%'"$output_objdir/$outputname"'%g'`
@@ -10540,8 +9045,8 @@ EOF
 	    func_dirname_and_basename "$output" "" "."
 	    output_name=$func_basename_result
 	    output_path=$func_dirname_result
-	    cwrappersource=$output_path/$objdir/lt-$output_name.c
-	    cwrapper=$output_path/$output_name.exe
+	    cwrappersource="$output_path/$objdir/lt-$output_name.c"
+	    cwrapper="$output_path/$output_name.exe"
 	    $RM $cwrappersource $cwrapper
 	    trap "$RM $cwrappersource $cwrapper; exit $EXIT_FAILURE" 1 2 15
 
@@ -10562,7 +9067,7 @@ EOF
 	    trap "$RM $func_ltwrapper_scriptname_result; exit $EXIT_FAILURE" 1 2 15
 	    $opt_dry_run || {
 	      # note: this script will not be executed, so do not chmod.
-	      if test "x$build" = "x$host"; then
+	      if test "x$build" = "x$host" ; then
 		$cwrapper --lt-dump-script > $func_ltwrapper_scriptname_result
 	      else
 		func_emit_wrapper no > $func_ltwrapper_scriptname_result
@@ -10585,27 +9090,25 @@ EOF
     # See if we need to build an old-fashioned archive.
     for oldlib in $oldlibs; do
 
-      case $build_libtool_libs in
-        convenience)
-	  oldobjs="$libobjs_save $symfileobj"
-	  addlibs=$convenience
-	  build_libtool_libs=no
-	  ;;
-	module)
-	  oldobjs=$libobjs_save
-	  addlibs=$old_convenience
+      if test "$build_libtool_libs" = convenience; then
+	oldobjs="$libobjs_save $symfileobj"
+	addlibs="$convenience"
+	build_libtool_libs=no
+      else
+	if test "$build_libtool_libs" = module; then
+	  oldobjs="$libobjs_save"
 	  build_libtool_libs=no
-          ;;
-	*)
+	else
 	  oldobjs="$old_deplibs $non_pic_objects"
-	  $preload && test -f "$symfileobj" \
-	    && func_append oldobjs " $symfileobj"
-	  addlibs=$old_convenience
-	  ;;
-      esac
+	  if test "$preload" = yes && test -f "$symfileobj"; then
+	    func_append oldobjs " $symfileobj"
+	  fi
+	fi
+	addlibs="$old_convenience"
+      fi
 
       if test -n "$addlibs"; then
-	gentop=$output_objdir/${outputname}x
+	gentop="$output_objdir/${outputname}x"
 	func_append generated " $gentop"
 
 	func_extract_archives $gentop $addlibs
@@ -10613,13 +9116,13 @@ EOF
       fi
 
       # Do each command in the archive commands.
-      if test -n "$old_archive_from_new_cmds" && test yes = "$build_libtool_libs"; then
+      if test -n "$old_archive_from_new_cmds" && test "$build_libtool_libs" = yes; then
 	cmds=$old_archive_from_new_cmds
       else
 
 	# Add any objects from preloaded convenience libraries
 	if test -n "$dlprefiles"; then
-	  gentop=$output_objdir/${outputname}x
+	  gentop="$output_objdir/${outputname}x"
 	  func_append generated " $gentop"
 
 	  func_extract_archives $gentop $dlprefiles
@@ -10640,7 +9143,7 @@ EOF
 	  :
 	else
 	  echo "copying selected object files to avoid basename conflicts..."
-	  gentop=$output_objdir/${outputname}x
+	  gentop="$output_objdir/${outputname}x"
 	  func_append generated " $gentop"
 	  func_mkdir_p "$gentop"
 	  save_oldobjs=$oldobjs
@@ -10649,7 +9152,7 @@ EOF
 	  for obj in $save_oldobjs
 	  do
 	    func_basename "$obj"
-	    objbase=$func_basename_result
+	    objbase="$func_basename_result"
 	    case " $oldobjs " in
 	    " ") oldobjs=$obj ;;
 	    *[\ /]"$objbase "*)
@@ -10718,18 +9221,18 @@ EOF
 	    else
 	      # the above command should be used before it gets too long
 	      oldobjs=$objlist
-	      if test "$obj" = "$last_oldobj"; then
+	      if test "$obj" = "$last_oldobj" ; then
 		RANLIB=$save_RANLIB
 	      fi
 	      test -z "$concat_cmds" || concat_cmds=$concat_cmds~
-	      eval concat_cmds=\"\$concat_cmds$old_archive_cmds\"
+	      eval concat_cmds=\"\${concat_cmds}$old_archive_cmds\"
 	      objlist=
 	      len=$len0
 	    fi
 	  done
 	  RANLIB=$save_RANLIB
 	  oldobjs=$objlist
-	  if test -z "$oldobjs"; then
+	  if test "X$oldobjs" = "X" ; then
 	    eval cmds=\"\$concat_cmds\"
 	  else
 	    eval cmds=\"\$concat_cmds~\$old_archive_cmds\"
@@ -10746,7 +9249,7 @@ EOF
     case $output in
     *.la)
       old_library=
-      test yes = "$build_old_libs" && old_library=$libname.$libext
+      test "$build_old_libs" = yes && old_library="$libname.$libext"
       func_verbose "creating $output"
 
       # Preserve any variables that may affect compiler behavior
@@ -10761,31 +9264,31 @@ EOF
 	fi
       done
       # Quote the link command for shipping.
-      relink_command="(cd `pwd`; $SHELL \"$progpath\" $preserve_args --mode=relink $libtool_args @inst_prefix_dir@)"
+      relink_command="(cd `pwd`; $SHELL $progpath $preserve_args --mode=relink $libtool_args @inst_prefix_dir@)"
       relink_command=`$ECHO "$relink_command" | $SED "$sed_quote_subst"`
-      if test yes = "$hardcode_automatic"; then
+      if test "$hardcode_automatic" = yes ; then
 	relink_command=
       fi
 
       # Only create the output if not a dry run.
       $opt_dry_run || {
 	for installed in no yes; do
-	  if test yes = "$installed"; then
+	  if test "$installed" = yes; then
 	    if test -z "$install_libdir"; then
 	      break
 	    fi
-	    output=$output_objdir/${outputname}i
+	    output="$output_objdir/$outputname"i
 	    # Replace all uninstalled libtool libraries with the installed ones
 	    newdependency_libs=
 	    for deplib in $dependency_libs; do
 	      case $deplib in
 	      *.la)
 		func_basename "$deplib"
-		name=$func_basename_result
+		name="$func_basename_result"
 		func_resolve_sysroot "$deplib"
-		eval libdir=`$SED -n -e 's/^libdir=\(.*\)$/\1/p' $func_resolve_sysroot_result`
+		eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $func_resolve_sysroot_result`
 		test -z "$libdir" && \
-		  func_fatal_error "'$deplib' is not a valid libtool archive"
+		  func_fatal_error "\`$deplib' is not a valid libtool archive"
 		func_append newdependency_libs " ${lt_sysroot:+=}$libdir/$name"
 		;;
 	      -L*)
@@ -10801,23 +9304,23 @@ EOF
 	      *) func_append newdependency_libs " $deplib" ;;
 	      esac
 	    done
-	    dependency_libs=$newdependency_libs
+	    dependency_libs="$newdependency_libs"
 	    newdlfiles=
 
 	    for lib in $dlfiles; do
 	      case $lib in
 	      *.la)
 	        func_basename "$lib"
-		name=$func_basename_result
-		eval libdir=`$SED -n -e 's/^libdir=\(.*\)$/\1/p' $lib`
+		name="$func_basename_result"
+		eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib`
 		test -z "$libdir" && \
-		  func_fatal_error "'$lib' is not a valid libtool archive"
+		  func_fatal_error "\`$lib' is not a valid libtool archive"
 		func_append newdlfiles " ${lt_sysroot:+=}$libdir/$name"
 		;;
 	      *) func_append newdlfiles " $lib" ;;
 	      esac
 	    done
-	    dlfiles=$newdlfiles
+	    dlfiles="$newdlfiles"
 	    newdlprefiles=
 	    for lib in $dlprefiles; do
 	      case $lib in
@@ -10827,34 +9330,34 @@ EOF
 		# didn't already link the preopened objects directly into
 		# the library:
 		func_basename "$lib"
-		name=$func_basename_result
-		eval libdir=`$SED -n -e 's/^libdir=\(.*\)$/\1/p' $lib`
+		name="$func_basename_result"
+		eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib`
 		test -z "$libdir" && \
-		  func_fatal_error "'$lib' is not a valid libtool archive"
+		  func_fatal_error "\`$lib' is not a valid libtool archive"
 		func_append newdlprefiles " ${lt_sysroot:+=}$libdir/$name"
 		;;
 	      esac
 	    done
-	    dlprefiles=$newdlprefiles
+	    dlprefiles="$newdlprefiles"
 	  else
 	    newdlfiles=
 	    for lib in $dlfiles; do
 	      case $lib in
-		[\\/]* | [A-Za-z]:[\\/]*) abs=$lib ;;
+		[\\/]* | [A-Za-z]:[\\/]*) abs="$lib" ;;
 		*) abs=`pwd`"/$lib" ;;
 	      esac
 	      func_append newdlfiles " $abs"
 	    done
-	    dlfiles=$newdlfiles
+	    dlfiles="$newdlfiles"
 	    newdlprefiles=
 	    for lib in $dlprefiles; do
 	      case $lib in
-		[\\/]* | [A-Za-z]:[\\/]*) abs=$lib ;;
+		[\\/]* | [A-Za-z]:[\\/]*) abs="$lib" ;;
 		*) abs=`pwd`"/$lib" ;;
 	      esac
 	      func_append newdlprefiles " $abs"
 	    done
-	    dlprefiles=$newdlprefiles
+	    dlprefiles="$newdlprefiles"
 	  fi
 	  $RM $output
 	  # place dlname in correct position for cygwin
@@ -10870,9 +9373,10 @@ EOF
 	  case $host,$output,$installed,$module,$dlname in
 	    *cygwin*,*lai,yes,no,*.dll | *mingw*,*lai,yes,no,*.dll | *cegcc*,*lai,yes,no,*.dll)
 	      # If a -bindir argument was supplied, place the dll there.
-	      if test -n "$bindir"; then
+	      if test "x$bindir" != x ;
+	      then
 		func_relative_path "$install_libdir" "$bindir"
-		tdlname=$func_relative_path_result/$dlname
+		tdlname=$func_relative_path_result$dlname
 	      else
 		# Otherwise fall back on heuristic.
 		tdlname=../bin/$dlname
@@ -10881,7 +9385,7 @@ EOF
 	  esac
 	  $ECHO > $output "\
 # $outputname - a libtool library file
-# Generated by $PROGRAM (GNU $PACKAGE) $VERSION
+# Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION
 #
 # Please DO NOT delete this file!
 # It is necessary for linking the library.
@@ -10895,7 +9399,7 @@ library_names='$library_names'
 # The name of the static archive.
 old_library='$old_library'
 
-# Linker flags that cannot go in dependency_libs.
+# Linker flags that can not go in dependency_libs.
 inherited_linker_flags='$new_inherited_linker_flags'
 
 # Libraries that this one depends upon.
@@ -10921,7 +9425,7 @@ dlpreopen='$dlprefiles'
 
 # Directory that this library needs to be installed in:
 libdir='$install_libdir'"
-	  if test no,yes = "$installed,$need_relink"; then
+	  if test "$installed" = no && test "$need_relink" = yes; then
 	    $ECHO >> $output "\
 relink_command=\"$relink_command\""
 	  fi
@@ -10936,29 +9440,27 @@ relink_command=\"$relink_command\""
     exit $EXIT_SUCCESS
 }
 
-if test link = "$opt_mode" || test relink = "$opt_mode"; then
-  func_mode_link ${1+"$@"}
-fi
+{ test "$opt_mode" = link || test "$opt_mode" = relink; } &&
+    func_mode_link ${1+"$@"}
 
 
 # func_mode_uninstall arg...
 func_mode_uninstall ()
 {
-    $debug_cmd
-
-    RM=$nonopt
+    $opt_debug
+    RM="$nonopt"
     files=
-    rmforce=false
+    rmforce=
     exit_status=0
 
     # This variable tells wrapper scripts just to set variables rather
     # than running their programs.
-    libtool_install_magic=$magic
+    libtool_install_magic="$magic"
 
     for arg
     do
       case $arg in
-      -f) func_append RM " $arg"; rmforce=: ;;
+      -f) func_append RM " $arg"; rmforce=yes ;;
       -*) func_append RM " $arg" ;;
       *) func_append files " $arg" ;;
       esac
@@ -10971,18 +9473,18 @@ func_mode_uninstall ()
 
     for file in $files; do
       func_dirname "$file" "" "."
-      dir=$func_dirname_result
-      if test . = "$dir"; then
-	odir=$objdir
+      dir="$func_dirname_result"
+      if test "X$dir" = X.; then
+	odir="$objdir"
       else
-	odir=$dir/$objdir
+	odir="$dir/$objdir"
       fi
       func_basename "$file"
-      name=$func_basename_result
-      test uninstall = "$opt_mode" && odir=$dir
+      name="$func_basename_result"
+      test "$opt_mode" = uninstall && odir="$dir"
 
       # Remember odir for removal later, being careful to avoid duplicates
-      if test clean = "$opt_mode"; then
+      if test "$opt_mode" = clean; then
 	case " $rmdirs " in
 	  *" $odir "*) ;;
 	  *) func_append rmdirs " $odir" ;;
@@ -10997,11 +9499,11 @@ func_mode_uninstall ()
       elif test -d "$file"; then
 	exit_status=1
 	continue
-      elif $rmforce; then
+      elif test "$rmforce" = yes; then
 	continue
       fi
 
-      rmfiles=$file
+      rmfiles="$file"
 
       case $name in
       *.la)
@@ -11015,7 +9517,7 @@ func_mode_uninstall ()
 	  done
 	  test -n "$old_library" && func_append rmfiles " $odir/$old_library"
 
-	  case $opt_mode in
+	  case "$opt_mode" in
 	  clean)
 	    case " $library_names " in
 	    *" $dlname "*) ;;
@@ -11026,12 +9528,12 @@ func_mode_uninstall ()
 	  uninstall)
 	    if test -n "$library_names"; then
 	      # Do each command in the postuninstall commands.
-	      func_execute_cmds "$postuninstall_cmds" '$rmforce || exit_status=1'
+	      func_execute_cmds "$postuninstall_cmds" 'test "$rmforce" = yes || exit_status=1'
 	    fi
 
 	    if test -n "$old_library"; then
 	      # Do each command in the old_postuninstall commands.
-	      func_execute_cmds "$old_postuninstall_cmds" '$rmforce || exit_status=1'
+	      func_execute_cmds "$old_postuninstall_cmds" 'test "$rmforce" = yes || exit_status=1'
 	    fi
 	    # FIXME: should reinstall the best remaining shared library.
 	    ;;
@@ -11047,19 +9549,21 @@ func_mode_uninstall ()
 	  func_source $dir/$name
 
 	  # Add PIC object to the list of files to remove.
-	  if test -n "$pic_object" && test none != "$pic_object"; then
+	  if test -n "$pic_object" &&
+	     test "$pic_object" != none; then
 	    func_append rmfiles " $dir/$pic_object"
 	  fi
 
 	  # Add non-PIC object to the list of files to remove.
-	  if test -n "$non_pic_object" && test none != "$non_pic_object"; then
+	  if test -n "$non_pic_object" &&
+	     test "$non_pic_object" != none; then
 	    func_append rmfiles " $dir/$non_pic_object"
 	  fi
 	fi
 	;;
 
       *)
-	if test clean = "$opt_mode"; then
+	if test "$opt_mode" = clean ; then
 	  noexename=$name
 	  case $file in
 	  *.exe)
@@ -11086,12 +9590,12 @@ func_mode_uninstall ()
 
 	    # note $name still contains .exe if it was in $file originally
 	    # as does the version of $file that was added into $rmfiles
-	    func_append rmfiles " $odir/$name $odir/${name}S.$objext"
-	    if test yes = "$fast_install" && test -n "$relink_command"; then
+	    func_append rmfiles " $odir/$name $odir/${name}S.${objext}"
+	    if test "$fast_install" = yes && test -n "$relink_command"; then
 	      func_append rmfiles " $odir/lt-$name"
 	    fi
-	    if test "X$noexename" != "X$name"; then
-	      func_append rmfiles " $odir/lt-$noexename.c"
+	    if test "X$noexename" != "X$name" ; then
+	      func_append rmfiles " $odir/lt-${noexename}.c"
 	    fi
 	  fi
 	fi
@@ -11100,7 +9604,7 @@ func_mode_uninstall ()
       func_show_eval "$RM $rmfiles" 'exit_status=1'
     done
 
-    # Try to remove the $objdir's in the directories where we deleted files
+    # Try to remove the ${objdir}s in the directories where we deleted files
     for dir in $rmdirs; do
       if test -d "$dir"; then
 	func_show_eval "rmdir $dir >/dev/null 2>&1"
@@ -11110,17 +9614,16 @@ func_mode_uninstall ()
     exit $exit_status
 }
 
-if test uninstall = "$opt_mode" || test clean = "$opt_mode"; then
-  func_mode_uninstall ${1+"$@"}
-fi
+{ test "$opt_mode" = uninstall || test "$opt_mode" = clean; } &&
+    func_mode_uninstall ${1+"$@"}
 
 test -z "$opt_mode" && {
-  help=$generic_help
+  help="$generic_help"
   func_fatal_help "you must specify a MODE"
 }
 
 test -z "$exec_cmd" && \
-  func_fatal_help "invalid operation mode '$opt_mode'"
+  func_fatal_help "invalid operation mode \`$opt_mode'"
 
 if test -n "$exec_cmd"; then
   eval exec "$exec_cmd"
@@ -11131,7 +9634,7 @@ exit $exit_status
 
 
 # The TAGs below are defined such that we never get into a situation
-# where we disable both kinds of libraries.  Given conflicting
+# in which we disable both kinds of libraries.  Given conflicting
 # choices, we go for a static library, that is the most portable,
 # since we can't tell whether shared libraries were disabled because
 # the user asked for that or because the platform doesn't support
@@ -11154,3 +9657,5 @@ build_old_libs=`case $build_libtool_libs in yes) echo no;; *) echo yes;; esac`
 # mode:shell-script
 # sh-indentation:2
 # End:
+# vi:sw=2
+
diff --git a/src/gmock/gtest/build-aux/missing b/src/gmock/gtest/build-aux/missing
index f62bbae..db98974 100755
--- a/src/gmock/gtest/build-aux/missing
+++ b/src/gmock/gtest/build-aux/missing
@@ -3,7 +3,7 @@
 
 scriptversion=2013-10-28.13; # UTC
 
-# Copyright (C) 1996-2014 Free Software Foundation, Inc.
+# Copyright (C) 1996-2013 Free Software Foundation, Inc.
 # Originally written by Fran,cois Pinard <pinard at iro.umontreal.ca>, 1996.
 
 # This program is free software; you can redistribute it and/or modify
diff --git a/src/gmock/gtest/build-aux/test-driver b/src/gmock/gtest/build-aux/test-driver
index 8e575b0..d306056 100755
--- a/src/gmock/gtest/build-aux/test-driver
+++ b/src/gmock/gtest/build-aux/test-driver
@@ -3,7 +3,7 @@
 
 scriptversion=2013-07-13.22; # UTC
 
-# Copyright (C) 2011-2014 Free Software Foundation, Inc.
+# Copyright (C) 2011-2013 Free Software Foundation, Inc.
 #
 # This program is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
@@ -106,14 +106,11 @@ trap "st=143; $do_exit" 15
 # Test script is run here.
 "$@" >$log_file 2>&1
 estatus=$?
-
 if test $enable_hard_errors = no && test $estatus -eq 99; then
-  tweaked_estatus=1
-else
-  tweaked_estatus=$estatus
+  estatus=1
 fi
 
-case $tweaked_estatus:$expect_failure in
+case $estatus:$expect_failure in
   0:yes) col=$red res=XPASS recheck=yes gcopy=yes;;
   0:*)   col=$grn res=PASS  recheck=no  gcopy=no;;
   77:*)  col=$blu res=SKIP  recheck=no  gcopy=yes;;
@@ -122,12 +119,6 @@ case $tweaked_estatus:$expect_failure in
   *:*)   col=$red res=FAIL  recheck=yes gcopy=yes;;
 esac
 
-# Report the test outcome and exit status in the logs, so that one can
-# know whether the test passed or failed simply by looking at the '.log'
-# file, without the need of also peaking into the corresponding '.trs'
-# file (automake bug#11814).
-echo "$res $test_name (exit status: $estatus)" >>$log_file
-
 # Report outcome to console.
 echo "${col}${res}${std}: $test_name"
 
diff --git a/src/gmock/gtest/configure b/src/gmock/gtest/configure
index 40b2ed0..efd9c87 100755
--- a/src/gmock/gtest/configure
+++ b/src/gmock/gtest/configure
@@ -647,7 +647,6 @@ HAVE_PYTHON_TRUE
 PYTHON
 CXXCPP
 CPP
-LT_SYS_LIBRARY_PATH
 OTOOL64
 OTOOL
 LIPO
@@ -746,7 +745,6 @@ infodir
 docdir
 oldincludedir
 includedir
-runstatedir
 localstatedir
 sharedstatedir
 sysconfdir
@@ -775,7 +773,6 @@ enable_shared
 enable_static
 with_pic
 enable_fast_install
-with_aix_soname
 with_gnu_ld
 with_sysroot
 enable_libtool_lock
@@ -792,7 +789,6 @@ CPPFLAGS
 CXX
 CXXFLAGS
 CCC
-LT_SYS_LIBRARY_PATH
 CPP
 CXXCPP'
 
@@ -833,7 +829,6 @@ datadir='${datarootdir}'
 sysconfdir='${prefix}/etc'
 sharedstatedir='${prefix}/com'
 localstatedir='${prefix}/var'
-runstatedir='${localstatedir}/run'
 includedir='${prefix}/include'
 oldincludedir='/usr/include'
 docdir='${datarootdir}/doc/${PACKAGE_TARNAME}'
@@ -1086,15 +1081,6 @@ do
   | -silent | --silent | --silen | --sile | --sil)
     silent=yes ;;
 
-  -runstatedir | --runstatedir | --runstatedi | --runstated \
-  | --runstate | --runstat | --runsta | --runst | --runs \
-  | --run | --ru | --r)
-    ac_prev=runstatedir ;;
-  -runstatedir=* | --runstatedir=* | --runstatedi=* | --runstated=* \
-  | --runstate=* | --runstat=* | --runsta=* | --runst=* | --runs=* \
-  | --run=* | --ru=* | --r=*)
-    runstatedir=$ac_optarg ;;
-
   -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
     ac_prev=sbindir ;;
   -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
@@ -1232,7 +1218,7 @@ fi
 for ac_var in	exec_prefix prefix bindir sbindir libexecdir datarootdir \
 		datadir sysconfdir sharedstatedir localstatedir includedir \
 		oldincludedir docdir infodir htmldir dvidir pdfdir psdir \
-		libdir localedir mandir runstatedir
+		libdir localedir mandir
 do
   eval ac_val=\$$ac_var
   # Remove trailing slashes.
@@ -1385,7 +1371,6 @@ Fine tuning of the installation directories:
   --sysconfdir=DIR        read-only single-machine data [PREFIX/etc]
   --sharedstatedir=DIR    modifiable architecture-independent data [PREFIX/com]
   --localstatedir=DIR     modifiable single-machine data [PREFIX/var]
-  --runstatedir=DIR       modifiable per-process data [LOCALSTATEDIR/run]
   --libdir=DIR            object code libraries [EPREFIX/lib]
   --includedir=DIR        C header files [PREFIX/include]
   --oldincludedir=DIR     C header files for non-gcc [/usr/include]
@@ -1441,12 +1426,9 @@ Optional Packages:
   --without-PACKAGE       do not use PACKAGE (same as --with-PACKAGE=no)
   --with-pic[=PKGS]       try to use only PIC/non-PIC objects [default=use
                           both]
-  --with-aix-soname=aix|svr4|both
-                          shared library versioning (aka "SONAME") variant to
-                          provide on AIX, [default=aix].
   --with-gnu-ld           assume the C compiler uses GNU ld [default=no]
-  --with-sysroot[=DIR]    Search for dependent libraries within DIR (or the
-                          compiler's sysroot if not specified).
+  --with-sysroot=DIR Search for dependent libraries within DIR
+                        (or the compiler's sysroot if not specified).
   --with-pthreads         use pthreads (default is yes)
 
 Some influential environment variables:
@@ -1459,8 +1441,6 @@ Some influential environment variables:
               you have headers in a nonstandard directory <include dir>
   CXX         C++ compiler command
   CXXFLAGS    C++ compiler flags
-  LT_SYS_LIBRARY_PATH
-              User-defined run-time library search path.
   CPP         C preprocessor
   CXXCPP      C++ preprocessor
 
@@ -2321,7 +2301,7 @@ ac_config_files="$ac_config_files scripts/gtest-config"
 # Initialize Automake with various options. We require at least v1.9, prevent
 # pedantic complaints about package files, and enable various distribution
 # targets.
-am__api_version='1.15'
+am__api_version='1.14'
 
 # Find a good install program.  We prefer a C program (faster),
 # so one script is as good as another.  But avoid the broken or
@@ -2493,8 +2473,8 @@ test "$program_suffix" != NONE &&
 ac_script='s/[\\$]/&&/g;s/;s,x,x,$//'
 program_transform_name=`$as_echo "$program_transform_name" | sed "$ac_script"`
 
-# Expand $ac_aux_dir to an absolute path.
-am_aux_dir=`cd "$ac_aux_dir" && pwd`
+# expand $ac_aux_dir to an absolute path
+am_aux_dir=`cd $ac_aux_dir && pwd`
 
 if test x"${MISSING+set}" != xset; then
   case $am_aux_dir in
@@ -2513,7 +2493,7 @@ else
 $as_echo "$as_me: WARNING: 'missing' script is too old or missing" >&2;}
 fi
 
-if test x"${install_sh+set}" != xset; then
+if test x"${install_sh}" != xset; then
   case $am_aux_dir in
   *\ * | *\	*)
     install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;;
@@ -2841,8 +2821,8 @@ MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"}
 # <http://lists.gnu.org/archive/html/automake/2012-07/msg00014.html>
 mkdir_p='$(MKDIR_P)'
 
-# We need awk for the "check" target (and possibly the TAP driver).  The
-# system "awk" is bad on some platforms.
+# We need awk for the "check" target.  The system "awk" is bad on
+# some platforms.
 # Always define AMTAR for backward compatibility.  Yes, it's still used
 # in the wild :-(  We should find a proper way to deprecate it ...
 AMTAR='$${TAR-tar}'
@@ -2900,7 +2880,6 @@ END
   fi
 fi
 
-
 # Check for programs used in building Google Test.
 ac_ext=c
 ac_cpp='$CPP $CPPFLAGS'
@@ -4340,8 +4319,8 @@ esac
 
 
 
-macro_version='2.4.6'
-macro_revision='2.4.6'
+macro_version='2.4.2'
+macro_revision='1.3337'
 
 
 
@@ -4355,7 +4334,7 @@ macro_revision='2.4.6'
 
 
 
-ltmain=$ac_aux_dir/ltmain.sh
+ltmain="$ac_aux_dir/ltmain.sh"
 
 # Make sure we can run config.sub.
 $SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 ||
@@ -4475,7 +4454,7 @@ func_echo_all ()
     $ECHO ""
 }
 
-case $ECHO in
+case "$ECHO" in
   printf*) { $as_echo "$as_me:${as_lineno-$LINENO}: result: printf" >&5
 $as_echo "printf" >&6; } ;;
   print*) { $as_echo "$as_me:${as_lineno-$LINENO}: result: print -r" >&5
@@ -4798,19 +4777,19 @@ test -z "$GREP" && GREP=grep
 
 # Check whether --with-gnu-ld was given.
 if test "${with_gnu_ld+set}" = set; then :
-  withval=$with_gnu_ld; test no = "$withval" || with_gnu_ld=yes
+  withval=$with_gnu_ld; test "$withval" = no || with_gnu_ld=yes
 else
   with_gnu_ld=no
 fi
 
 ac_prog=ld
-if test yes = "$GCC"; then
+if test "$GCC" = yes; then
   # Check if gcc -print-prog-name=ld gives a path.
   { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ld used by $CC" >&5
 $as_echo_n "checking for ld used by $CC... " >&6; }
   case $host in
   *-*-mingw*)
-    # gcc leaves a trailing carriage return, which upsets mingw
+    # gcc leaves a trailing carriage return which upsets mingw
     ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;;
   *)
     ac_prog=`($CC -print-prog-name=ld) 2>&5` ;;
@@ -4824,7 +4803,7 @@ $as_echo_n "checking for ld used by $CC... " >&6; }
       while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do
 	ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"`
       done
-      test -z "$LD" && LD=$ac_prog
+      test -z "$LD" && LD="$ac_prog"
       ;;
   "")
     # If it fails, then pretend we aren't using GCC.
@@ -4835,7 +4814,7 @@ $as_echo_n "checking for ld used by $CC... " >&6; }
     with_gnu_ld=unknown
     ;;
   esac
-elif test yes = "$with_gnu_ld"; then
+elif test "$with_gnu_ld" = yes; then
   { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU ld" >&5
 $as_echo_n "checking for GNU ld... " >&6; }
 else
@@ -4846,32 +4825,32 @@ if ${lt_cv_path_LD+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   if test -z "$LD"; then
-  lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR
+  lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
   for ac_dir in $PATH; do
-    IFS=$lt_save_ifs
+    IFS="$lt_save_ifs"
     test -z "$ac_dir" && ac_dir=.
     if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then
-      lt_cv_path_LD=$ac_dir/$ac_prog
+      lt_cv_path_LD="$ac_dir/$ac_prog"
       # Check to see if the program is GNU ld.  I'd rather use --version,
       # but apparently some variants of GNU ld only accept -v.
       # Break only if it was the GNU/non-GNU ld that we prefer.
       case `"$lt_cv_path_LD" -v 2>&1 </dev/null` in
       *GNU* | *'with BFD'*)
-	test no != "$with_gnu_ld" && break
+	test "$with_gnu_ld" != no && break
 	;;
       *)
-	test yes != "$with_gnu_ld" && break
+	test "$with_gnu_ld" != yes && break
 	;;
       esac
     fi
   done
-  IFS=$lt_save_ifs
+  IFS="$lt_save_ifs"
 else
-  lt_cv_path_LD=$LD # Let the user override the test with a path.
+  lt_cv_path_LD="$LD" # Let the user override the test with a path.
 fi
 fi
 
-LD=$lt_cv_path_LD
+LD="$lt_cv_path_LD"
 if test -n "$LD"; then
   { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LD" >&5
 $as_echo "$LD" >&6; }
@@ -4914,38 +4893,33 @@ if ${lt_cv_path_NM+:} false; then :
 else
   if test -n "$NM"; then
   # Let the user override the test.
-  lt_cv_path_NM=$NM
+  lt_cv_path_NM="$NM"
 else
-  lt_nm_to_check=${ac_tool_prefix}nm
+  lt_nm_to_check="${ac_tool_prefix}nm"
   if test -n "$ac_tool_prefix" && test "$build" = "$host"; then
     lt_nm_to_check="$lt_nm_to_check nm"
   fi
   for lt_tmp_nm in $lt_nm_to_check; do
-    lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR
+    lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
     for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do
-      IFS=$lt_save_ifs
+      IFS="$lt_save_ifs"
       test -z "$ac_dir" && ac_dir=.
-      tmp_nm=$ac_dir/$lt_tmp_nm
-      if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext"; then
+      tmp_nm="$ac_dir/$lt_tmp_nm"
+      if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext" ; then
 	# Check to see if the nm accepts a BSD-compat flag.
-	# Adding the 'sed 1q' prevents false positives on HP-UX, which says:
+	# Adding the `sed 1q' prevents false positives on HP-UX, which says:
 	#   nm: unknown option "B" ignored
 	# Tru64's nm complains that /dev/null is an invalid object file
-	# MSYS converts /dev/null to NUL, MinGW nm treats NUL as empty
-	case $build_os in
-	mingw*) lt_bad_file=conftest.nm/nofile ;;
-	*) lt_bad_file=/dev/null ;;
-	esac
-	case `"$tmp_nm" -B $lt_bad_file 2>&1 | sed '1q'` in
-	*$lt_bad_file* | *'Invalid file or object type'*)
+	case `"$tmp_nm" -B /dev/null 2>&1 | sed '1q'` in
+	*/dev/null* | *'Invalid file or object type'*)
 	  lt_cv_path_NM="$tmp_nm -B"
-	  break 2
+	  break
 	  ;;
 	*)
 	  case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in
 	  */dev/null*)
 	    lt_cv_path_NM="$tmp_nm -p"
-	    break 2
+	    break
 	    ;;
 	  *)
 	    lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but
@@ -4956,15 +4930,15 @@ else
 	esac
       fi
     done
-    IFS=$lt_save_ifs
+    IFS="$lt_save_ifs"
   done
   : ${lt_cv_path_NM=no}
 fi
 fi
 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_NM" >&5
 $as_echo "$lt_cv_path_NM" >&6; }
-if test no != "$lt_cv_path_NM"; then
-  NM=$lt_cv_path_NM
+if test "$lt_cv_path_NM" != "no"; then
+  NM="$lt_cv_path_NM"
 else
   # Didn't find any BSD compatible name lister, look for dumpbin.
   if test -n "$DUMPBIN"; then :
@@ -5070,9 +5044,9 @@ esac
   fi
 fi
 
-    case `$DUMPBIN -symbols -headers /dev/null 2>&1 | sed '1q'` in
+    case `$DUMPBIN -symbols /dev/null 2>&1 | sed '1q'` in
     *COFF*)
-      DUMPBIN="$DUMPBIN -symbols -headers"
+      DUMPBIN="$DUMPBIN -symbols"
       ;;
     *)
       DUMPBIN=:
@@ -5080,8 +5054,8 @@ fi
     esac
   fi
 
-  if test : != "$DUMPBIN"; then
-    NM=$DUMPBIN
+  if test "$DUMPBIN" != ":"; then
+    NM="$DUMPBIN"
   fi
 fi
 test -z "$NM" && NM=nm
@@ -5132,7 +5106,7 @@ if ${lt_cv_sys_max_cmd_len+:} false; then :
   $as_echo_n "(cached) " >&6
 else
     i=0
-  teststring=ABCD
+  teststring="ABCD"
 
   case $build_os in
   msdosdjgpp*)
@@ -5172,7 +5146,7 @@ else
     lt_cv_sys_max_cmd_len=8192;
     ;;
 
-  bitrig* | darwin* | dragonfly* | freebsd* | netbsd* | openbsd*)
+  netbsd* | freebsd* | openbsd* | darwin* | dragonfly*)
     # This has been around since 386BSD, at least.  Likely further.
     if test -x /sbin/sysctl; then
       lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax`
@@ -5223,22 +5197,22 @@ else
   *)
     lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null`
     if test -n "$lt_cv_sys_max_cmd_len" && \
-       test undefined != "$lt_cv_sys_max_cmd_len"; then
+	test undefined != "$lt_cv_sys_max_cmd_len"; then
       lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4`
       lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3`
     else
       # Make teststring a little bigger before we do anything with it.
       # a 1K string should be a reasonable start.
-      for i in 1 2 3 4 5 6 7 8; do
+      for i in 1 2 3 4 5 6 7 8 ; do
         teststring=$teststring$teststring
       done
       SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}}
       # If test is not a shell built-in, we'll probably end up computing a
       # maximum length that is only half of the actual maximum length, but
       # we can't tell.
-      while { test X`env echo "$teststring$teststring" 2>/dev/null` \
+      while { test "X"`env echo "$teststring$teststring" 2>/dev/null` \
 	         = "X$teststring$teststring"; } >/dev/null 2>&1 &&
-	      test 17 != "$i" # 1/2 MB should be enough
+	      test $i != 17 # 1/2 MB should be enough
       do
         i=`expr $i + 1`
         teststring=$teststring$teststring
@@ -5256,7 +5230,7 @@ else
 
 fi
 
-if test -n "$lt_cv_sys_max_cmd_len"; then
+if test -n $lt_cv_sys_max_cmd_len ; then
   { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_sys_max_cmd_len" >&5
 $as_echo "$lt_cv_sys_max_cmd_len" >&6; }
 else
@@ -5274,6 +5248,30 @@ max_cmd_len=$lt_cv_sys_max_cmd_len
 : ${MV="mv -f"}
 : ${RM="rm -f"}
 
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the shell understands some XSI constructs" >&5
+$as_echo_n "checking whether the shell understands some XSI constructs... " >&6; }
+# Try some XSI features
+xsi_shell=no
+( _lt_dummy="a/b/c"
+  test "${_lt_dummy##*/},${_lt_dummy%/*},${_lt_dummy#??}"${_lt_dummy%"$_lt_dummy"}, \
+      = c,a/b,b/c, \
+    && eval 'test $(( 1 + 1 )) -eq 2 \
+    && test "${#_lt_dummy}" -eq 5' ) >/dev/null 2>&1 \
+  && xsi_shell=yes
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $xsi_shell" >&5
+$as_echo "$xsi_shell" >&6; }
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the shell understands \"+=\"" >&5
+$as_echo_n "checking whether the shell understands \"+=\"... " >&6; }
+lt_shell_append=no
+( foo=bar; set foo baz; eval "$1+=\$2" && test "$foo" = barbaz ) \
+    >/dev/null 2>&1 \
+  && lt_shell_append=yes
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_shell_append" >&5
+$as_echo "$lt_shell_append" >&6; }
+
+
 if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then
   lt_unset=unset
 else
@@ -5396,13 +5394,13 @@ esac
 reload_cmds='$LD$reload_flag -o $output$reload_objs'
 case $host_os in
   cygwin* | mingw* | pw32* | cegcc*)
-    if test yes != "$GCC"; then
+    if test "$GCC" != yes; then
       reload_cmds=false
     fi
     ;;
   darwin*)
-    if test yes = "$GCC"; then
-      reload_cmds='$LTCC $LTCFLAGS -nostdlib $wl-r -o $output$reload_objs'
+    if test "$GCC" = yes; then
+      reload_cmds='$LTCC $LTCFLAGS -nostdlib ${wl}-r -o $output$reload_objs'
     else
       reload_cmds='$LD$reload_flag -o $output$reload_objs'
     fi
@@ -5530,13 +5528,13 @@ lt_cv_deplibs_check_method='unknown'
 # Need to set the preceding variable on all platforms that support
 # interlibrary dependencies.
 # 'none' -- dependencies not supported.
-# 'unknown' -- same as none, but documents that we really don't know.
+# `unknown' -- same as none, but documents that we really don't know.
 # 'pass_all' -- all dependencies passed with no checks.
 # 'test_compile' -- check by making test program.
 # 'file_magic [[regex]]' -- check by looking for files in library path
-# that responds to the $file_magic_cmd with a given extended regex.
-# If you have 'file' or equivalent on your system and you're not sure
-# whether 'pass_all' will *always* work, you probably want this one.
+# which responds to the $file_magic_cmd with a given extended regex.
+# If you have `file' or equivalent on your system and you're not sure
+# whether `pass_all' will *always* work, you probably want this one.
 
 case $host_os in
 aix[4-9]*)
@@ -5563,7 +5561,8 @@ mingw* | pw32*)
   # Base MSYS/MinGW do not provide the 'file' command needed by
   # func_win32_libid shell function, so use a weaker test based on 'objdump',
   # unless we find 'file', for example because we are cross-compiling.
-  if ( file / ) >/dev/null 2>&1; then
+  # func_win32_libid assumes BSD nm, so disallow it if using MS dumpbin.
+  if ( test "$lt_cv_nm_interface" = "BSD nm" && file / ) >/dev/null 2>&1; then
     lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL'
     lt_cv_file_magic_cmd='func_win32_libid'
   else
@@ -5659,8 +5658,8 @@ newos6*)
   lt_cv_deplibs_check_method=pass_all
   ;;
 
-openbsd* | bitrig*)
-  if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then
+openbsd*)
+  if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
     lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|\.so|_pic\.a)$'
   else
     lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$'
@@ -5713,9 +5712,6 @@ sysv4 | sysv4.3*)
 tpf*)
   lt_cv_deplibs_check_method=pass_all
   ;;
-os2*)
-  lt_cv_deplibs_check_method=pass_all
-  ;;
 esac
 
 fi
@@ -5873,8 +5869,8 @@ else
 
 case $host_os in
 cygwin* | mingw* | pw32* | cegcc*)
-  # two different shell functions defined in ltmain.sh;
-  # decide which one to use based on capabilities of $DLLTOOL
+  # two different shell functions defined in ltmain.sh
+  # decide which to use based on capabilities of $DLLTOOL
   case `$DLLTOOL --help 2>&1` in
   *--identify-strict*)
     lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib
@@ -5886,7 +5882,7 @@ cygwin* | mingw* | pw32* | cegcc*)
   ;;
 *)
   # fallback: assume linklib IS sharedlib
-  lt_cv_sharedlib_from_linklib_cmd=$ECHO
+  lt_cv_sharedlib_from_linklib_cmd="$ECHO"
   ;;
 esac
 
@@ -6041,7 +6037,7 @@ if ac_fn_cxx_try_compile "$LINENO"; then :
   ac_status=$?
   $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
   test $ac_status = 0; }
-      if test 0 -eq "$ac_status"; then
+      if test "$ac_status" -eq 0; then
 	# Ensure the archiver fails upon bogus file names.
 	rm -f conftest.$ac_objext libconftest.a
 	{ { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$lt_ar_try\""; } >&5
@@ -6049,7 +6045,7 @@ if ac_fn_cxx_try_compile "$LINENO"; then :
   ac_status=$?
   $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
   test $ac_status = 0; }
-	if test 0 -ne "$ac_status"; then
+	if test "$ac_status" -ne 0; then
           lt_cv_ar_at_file=@
         fi
       fi
@@ -6062,7 +6058,7 @@ fi
 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ar_at_file" >&5
 $as_echo "$lt_cv_ar_at_file" >&6; }
 
-if test no = "$lt_cv_ar_at_file"; then
+if test "x$lt_cv_ar_at_file" = xno; then
   archiver_list_spec=
 else
   archiver_list_spec=$lt_cv_ar_at_file
@@ -6279,7 +6275,7 @@ old_postuninstall_cmds=
 
 if test -n "$RANLIB"; then
   case $host_os in
-  bitrig* | openbsd*)
+  openbsd*)
     old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$tool_oldlib"
     ;;
   *)
@@ -6369,7 +6365,7 @@ cygwin* | mingw* | pw32* | cegcc*)
   symcode='[ABCDGISTW]'
   ;;
 hpux*)
-  if test ia64 = "$host_cpu"; then
+  if test "$host_cpu" = ia64; then
     symcode='[ABCDEGRST]'
   fi
   ;;
@@ -6402,44 +6398,14 @@ case `$NM -V 2>&1` in
   symcode='[ABCDGIRSTW]' ;;
 esac
 
-if test "$lt_cv_nm_interface" = "MS dumpbin"; then
-  # Gets list of data symbols to import.
-  lt_cv_sys_global_symbol_to_import="sed -n -e 's/^I .* \(.*\)$/\1/p'"
-  # Adjust the below global symbol transforms to fixup imported variables.
-  lt_cdecl_hook=" -e 's/^I .* \(.*\)$/extern __declspec(dllimport) char \1;/p'"
-  lt_c_name_hook=" -e 's/^I .* \(.*\)$/  {\"\1\", (void *) 0},/p'"
-  lt_c_name_lib_hook="\
-  -e 's/^I .* \(lib.*\)$/  {\"\1\", (void *) 0},/p'\
-  -e 's/^I .* \(.*\)$/  {\"lib\1\", (void *) 0},/p'"
-else
-  # Disable hooks by default.
-  lt_cv_sys_global_symbol_to_import=
-  lt_cdecl_hook=
-  lt_c_name_hook=
-  lt_c_name_lib_hook=
-fi
-
 # Transform an extracted symbol line into a proper C declaration.
 # Some systems (esp. on ia64) link data and code symbols differently,
 # so use this general approach.
-lt_cv_sys_global_symbol_to_cdecl="sed -n"\
-$lt_cdecl_hook\
-" -e 's/^T .* \(.*\)$/extern int \1();/p'"\
-" -e 's/^$symcode$symcode* .* \(.*\)$/extern char \1;/p'"
+lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'"
 
 # Transform an extracted symbol line into symbol name and symbol address
-lt_cv_sys_global_symbol_to_c_name_address="sed -n"\
-$lt_c_name_hook\
-" -e 's/^: \(.*\) .*$/  {\"\1\", (void *) 0},/p'"\
-" -e 's/^$symcode$symcode* .* \(.*\)$/  {\"\1\", (void *) \&\1},/p'"
-
-# Transform an extracted symbol line into symbol name with lib prefix and
-# symbol address.
-lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n"\
-$lt_c_name_lib_hook\
-" -e 's/^: \(.*\) .*$/  {\"\1\", (void *) 0},/p'"\
-" -e 's/^$symcode$symcode* .* \(lib.*\)$/  {\"\1\", (void *) \&\1},/p'"\
-" -e 's/^$symcode$symcode* .* \(.*\)$/  {\"lib\1\", (void *) \&\1},/p'"
+lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([^ ]*\)[ ]*$/  {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/  {\"\2\", (void *) \&\2},/p'"
+lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n -e 's/^: \([^ ]*\)[ ]*$/  {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([^ ]*\) \(lib[^ ]*\)$/  {\"\2\", (void *) \&\2},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/  {\"lib\2\", (void *) \&\2},/p'"
 
 # Handle CRLF in mingw tool chain
 opt_cr=
@@ -6457,24 +6423,21 @@ for ac_symprfx in "" "_"; do
 
   # Write the raw and C identifiers.
   if test "$lt_cv_nm_interface" = "MS dumpbin"; then
-    # Fake it for dumpbin and say T for any non-static function,
-    # D for any global variable and I for any imported variable.
+    # Fake it for dumpbin and say T for any non-static function
+    # and D for any global variable.
     # Also find C++ and __fastcall symbols from MSVC++,
     # which start with @ or ?.
     lt_cv_sys_global_symbol_pipe="$AWK '"\
 "     {last_section=section; section=\$ 3};"\
 "     /^COFF SYMBOL TABLE/{for(i in hide) delete hide[i]};"\
 "     /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\
-"     /^ *Symbol name *: /{split(\$ 0,sn,\":\"); si=substr(sn[2],2)};"\
-"     /^ *Type *: code/{print \"T\",si,substr(si,length(prfx))};"\
-"     /^ *Type *: data/{print \"I\",si,substr(si,length(prfx))};"\
 "     \$ 0!~/External *\|/{next};"\
 "     / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\
 "     {if(hide[section]) next};"\
-"     {f=\"D\"}; \$ 0~/\(\).*\|/{f=\"T\"};"\
-"     {split(\$ 0,a,/\||\r/); split(a[2],s)};"\
-"     s[1]~/^[@?]/{print f,s[1],s[1]; next};"\
-"     s[1]~prfx {split(s[1],t,\"@\"); print f,t[1],substr(t[1],length(prfx))}"\
+"     {f=0}; \$ 0~/\(\).*\|/{f=1}; {printf f ? \"T \" : \"D \"};"\
+"     {split(\$ 0, a, /\||\r/); split(a[2], s)};"\
+"     s[1]~/^[@?]/{print s[1], s[1]; next};"\
+"     s[1]~prfx {split(s[1],t,\"@\"); print t[1], substr(t[1],length(prfx))}"\
 "     ' prfx=^$ac_symprfx"
   else
     lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[	 ]\($symcode$symcode*\)[	 ][	 ]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'"
@@ -6522,11 +6485,11 @@ _LT_EOF
 	if $GREP ' nm_test_func$' "$nlist" >/dev/null; then
 	  cat <<_LT_EOF > conftest.$ac_ext
 /* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests.  */
-#if defined _WIN32 || defined __CYGWIN__ || defined _WIN32_WCE
-/* DATA imports from DLLs on WIN32 can't be const, because runtime
+#if defined(_WIN32) || defined(__CYGWIN__) || defined(_WIN32_WCE)
+/* DATA imports from DLLs on WIN32 con't be const, because runtime
    relocations are performed -- see ld's documentation on pseudo-relocs.  */
 # define LT_DLSYM_CONST
-#elif defined __osf__
+#elif defined(__osf__)
 /* This system does not cope well with relocations in const data.  */
 # define LT_DLSYM_CONST
 #else
@@ -6552,7 +6515,7 @@ lt__PROGRAM__LTX_preloaded_symbols[] =
 {
   { "@PROGRAM@", (void *) 0 },
 _LT_EOF
-	  $SED "s/^$symcode$symcode* .* \(.*\)$/  {\"\1\", (void *) \&\1},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext
+	  $SED "s/^$symcode$symcode* \(.*\) \(.*\)$/  {\"\2\", (void *) \&\2},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext
 	  cat <<\_LT_EOF >> conftest.$ac_ext
   {0, (void *) 0}
 };
@@ -6572,13 +6535,13 @@ _LT_EOF
 	  mv conftest.$ac_objext conftstm.$ac_objext
 	  lt_globsym_save_LIBS=$LIBS
 	  lt_globsym_save_CFLAGS=$CFLAGS
-	  LIBS=conftstm.$ac_objext
+	  LIBS="conftstm.$ac_objext"
 	  CFLAGS="$CFLAGS$lt_prog_compiler_no_builtin_flag"
 	  if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5
   (eval $ac_link) 2>&5
   ac_status=$?
   $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
-  test $ac_status = 0; } && test -s conftest$ac_exeext; then
+  test $ac_status = 0; } && test -s conftest${ac_exeext}; then
 	    pipe_works=yes
 	  fi
 	  LIBS=$lt_globsym_save_LIBS
@@ -6599,7 +6562,7 @@ _LT_EOF
   rm -rf conftest* conftst*
 
   # Do not use the global_symbol_pipe unless it works.
-  if test yes = "$pipe_works"; then
+  if test "$pipe_works" = yes; then
     break
   else
     lt_cv_sys_global_symbol_pipe=
@@ -6652,16 +6615,6 @@ fi
 
 
 
-
-
-
-
-
-
-
-
-
-
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for sysroot" >&5
 $as_echo_n "checking for sysroot... " >&6; }
 
@@ -6674,9 +6627,9 @@ fi
 
 
 lt_sysroot=
-case $with_sysroot in #(
+case ${with_sysroot} in #(
  yes)
-   if test yes = "$GCC"; then
+   if test "$GCC" = yes; then
      lt_sysroot=`$CC --print-sysroot 2>/dev/null`
    fi
    ;; #(
@@ -6686,8 +6639,8 @@ case $with_sysroot in #(
  no|'')
    ;; #(
  *)
-   { $as_echo "$as_me:${as_lineno-$LINENO}: result: $with_sysroot" >&5
-$as_echo "$with_sysroot" >&6; }
+   { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${with_sysroot}" >&5
+$as_echo "${with_sysroot}" >&6; }
    as_fn_error $? "The sysroot must be an absolute path." "$LINENO" 5
    ;;
 esac
@@ -6699,100 +6652,19 @@ $as_echo "${lt_sysroot:-no}" >&6; }
 
 
 
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a working dd" >&5
-$as_echo_n "checking for a working dd... " >&6; }
-if ${ac_cv_path_lt_DD+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  printf 0123456789abcdef0123456789abcdef >conftest.i
-cat conftest.i conftest.i >conftest2.i
-: ${lt_DD:=$DD}
-if test -z "$lt_DD"; then
-  ac_path_lt_DD_found=false
-  # Loop through the user's path and test for each of PROGNAME-LIST
-  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-    for ac_prog in dd; do
-    for ac_exec_ext in '' $ac_executable_extensions; do
-      ac_path_lt_DD="$as_dir/$ac_prog$ac_exec_ext"
-      as_fn_executable_p "$ac_path_lt_DD" || continue
-if "$ac_path_lt_DD" bs=32 count=1 <conftest2.i >conftest.out 2>/dev/null; then
-  cmp -s conftest.i conftest.out \
-  && ac_cv_path_lt_DD="$ac_path_lt_DD" ac_path_lt_DD_found=:
-fi
-      $ac_path_lt_DD_found && break 3
-    done
-  done
-  done
-IFS=$as_save_IFS
-  if test -z "$ac_cv_path_lt_DD"; then
-    :
-  fi
-else
-  ac_cv_path_lt_DD=$lt_DD
-fi
-
-rm -f conftest.i conftest2.i conftest.out
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_lt_DD" >&5
-$as_echo "$ac_cv_path_lt_DD" >&6; }
-
-
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to truncate binary pipes" >&5
-$as_echo_n "checking how to truncate binary pipes... " >&6; }
-if ${lt_cv_truncate_bin+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  printf 0123456789abcdef0123456789abcdef >conftest.i
-cat conftest.i conftest.i >conftest2.i
-lt_cv_truncate_bin=
-if "$ac_cv_path_lt_DD" bs=32 count=1 <conftest2.i >conftest.out 2>/dev/null; then
-  cmp -s conftest.i conftest.out \
-  && lt_cv_truncate_bin="$ac_cv_path_lt_DD bs=4096 count=1"
-fi
-rm -f conftest.i conftest2.i conftest.out
-test -z "$lt_cv_truncate_bin" && lt_cv_truncate_bin="$SED -e 4q"
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_truncate_bin" >&5
-$as_echo "$lt_cv_truncate_bin" >&6; }
-
-
-
-
-
-
-
-# Calculate cc_basename.  Skip known compiler wrappers and cross-prefix.
-func_cc_basename ()
-{
-    for cc_temp in $*""; do
-      case $cc_temp in
-        compile | *[\\/]compile | ccache | *[\\/]ccache ) ;;
-        distcc | *[\\/]distcc | purify | *[\\/]purify ) ;;
-        \-*) ;;
-        *) break;;
-      esac
-    done
-    func_cc_basename_result=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"`
-}
-
 
 # Check whether --enable-libtool-lock was given.
 if test "${enable_libtool_lock+set}" = set; then :
   enableval=$enable_libtool_lock;
 fi
 
-test no = "$enable_libtool_lock" || enable_libtool_lock=yes
+test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes
 
 # Some flags need to be propagated to the compiler or linker for good
 # libtool support.
 case $host in
 ia64-*-hpux*)
-  # Find out what ABI is being produced by ac_compile, and set mode
-  # options accordingly.
+  # Find out which ABI we are using.
   echo 'int i;' > conftest.$ac_ext
   if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
   (eval $ac_compile) 2>&5
@@ -6801,25 +6673,24 @@ ia64-*-hpux*)
   test $ac_status = 0; }; then
     case `/usr/bin/file conftest.$ac_objext` in
       *ELF-32*)
-	HPUX_IA64_MODE=32
+	HPUX_IA64_MODE="32"
 	;;
       *ELF-64*)
-	HPUX_IA64_MODE=64
+	HPUX_IA64_MODE="64"
 	;;
     esac
   fi
   rm -rf conftest*
   ;;
 *-*-irix6*)
-  # Find out what ABI is being produced by ac_compile, and set linker
-  # options accordingly.
+  # Find out which ABI we are using.
   echo '#line '$LINENO' "configure"' > conftest.$ac_ext
   if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
   (eval $ac_compile) 2>&5
   ac_status=$?
   $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
   test $ac_status = 0; }; then
-    if test yes = "$lt_cv_prog_gnu_ld"; then
+    if test "$lt_cv_prog_gnu_ld" = yes; then
       case `/usr/bin/file conftest.$ac_objext` in
 	*32-bit*)
 	  LD="${LD-ld} -melf32bsmip"
@@ -6848,50 +6719,9 @@ ia64-*-hpux*)
   rm -rf conftest*
   ;;
 
-mips64*-*linux*)
-  # Find out what ABI is being produced by ac_compile, and set linker
-  # options accordingly.
-  echo '#line '$LINENO' "configure"' > conftest.$ac_ext
-  if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
-  (eval $ac_compile) 2>&5
-  ac_status=$?
-  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
-  test $ac_status = 0; }; then
-    emul=elf
-    case `/usr/bin/file conftest.$ac_objext` in
-      *32-bit*)
-	emul="${emul}32"
-	;;
-      *64-bit*)
-	emul="${emul}64"
-	;;
-    esac
-    case `/usr/bin/file conftest.$ac_objext` in
-      *MSB*)
-	emul="${emul}btsmip"
-	;;
-      *LSB*)
-	emul="${emul}ltsmip"
-	;;
-    esac
-    case `/usr/bin/file conftest.$ac_objext` in
-      *N32*)
-	emul="${emul}n32"
-	;;
-    esac
-    LD="${LD-ld} -m $emul"
-  fi
-  rm -rf conftest*
-  ;;
-
 x86_64-*kfreebsd*-gnu|x86_64-*linux*|powerpc*-*linux*| \
 s390*-*linux*|s390*-*tpf*|sparc*-*linux*)
-  # Find out what ABI is being produced by ac_compile, and set linker
-  # options accordingly.  Note that the listed cases only cover the
-  # situations where additional linker options are needed (such as when
-  # doing 32-bit compilation for a host where ld defaults to 64-bit, or
-  # vice versa); the common cases where no linker options are needed do
-  # not appear in the list.
+  # Find out which ABI we are using.
   echo 'int i;' > conftest.$ac_ext
   if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
   (eval $ac_compile) 2>&5
@@ -6914,10 +6744,10 @@ s390*-*linux*|s390*-*tpf*|sparc*-*linux*)
 		;;
 	    esac
 	    ;;
-	  powerpc64le-*linux*)
+	  powerpc64le-*)
 	    LD="${LD-ld} -m elf32lppclinux"
 	    ;;
-	  powerpc64-*linux*)
+	  powerpc64-*)
 	    LD="${LD-ld} -m elf32ppclinux"
 	    ;;
 	  s390x-*linux*)
@@ -6936,10 +6766,10 @@ s390*-*linux*|s390*-*tpf*|sparc*-*linux*)
 	  x86_64-*linux*)
 	    LD="${LD-ld} -m elf_x86_64"
 	    ;;
-	  powerpcle-*linux*)
+	  powerpcle-*)
 	    LD="${LD-ld} -m elf64lppc"
 	    ;;
-	  powerpc-*linux*)
+	  powerpc-*)
 	    LD="${LD-ld} -m elf64ppc"
 	    ;;
 	  s390*-*linux*|s390*-*tpf*)
@@ -6957,7 +6787,7 @@ s390*-*linux*|s390*-*tpf*|sparc*-*linux*)
 
 *-*-sco3.2v5*)
   # On SCO OpenServer 5, we need -belf to get full-featured binaries.
-  SAVE_CFLAGS=$CFLAGS
+  SAVE_CFLAGS="$CFLAGS"
   CFLAGS="$CFLAGS -belf"
   { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler needs -belf" >&5
 $as_echo_n "checking whether the C compiler needs -belf... " >&6; }
@@ -6997,14 +6827,13 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu
 fi
 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_cc_needs_belf" >&5
 $as_echo "$lt_cv_cc_needs_belf" >&6; }
-  if test yes != "$lt_cv_cc_needs_belf"; then
+  if test x"$lt_cv_cc_needs_belf" != x"yes"; then
     # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf
-    CFLAGS=$SAVE_CFLAGS
+    CFLAGS="$SAVE_CFLAGS"
   fi
   ;;
 *-*solaris*)
-  # Find out what ABI is being produced by ac_compile, and set linker
-  # options accordingly.
+  # Find out which ABI we are using.
   echo 'int i;' > conftest.$ac_ext
   if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
   (eval $ac_compile) 2>&5
@@ -7016,7 +6845,7 @@ $as_echo "$lt_cv_cc_needs_belf" >&6; }
       case $lt_cv_prog_gnu_ld in
       yes*)
         case $host in
-        i?86-*-solaris*|x86_64-*-solaris*)
+        i?86-*-solaris*)
           LD="${LD-ld} -m elf_x86_64"
           ;;
         sparc*-*-solaris*)
@@ -7025,7 +6854,7 @@ $as_echo "$lt_cv_cc_needs_belf" >&6; }
         esac
         # GNU ld 2.21 introduced _sol2 emulations.  Use them if available.
         if ${LD-ld} -V | grep _sol2 >/dev/null 2>&1; then
-          LD=${LD-ld}_sol2
+          LD="${LD-ld}_sol2"
         fi
         ;;
       *)
@@ -7041,7 +6870,7 @@ $as_echo "$lt_cv_cc_needs_belf" >&6; }
   ;;
 esac
 
-need_locks=$enable_libtool_lock
+need_locks="$enable_libtool_lock"
 
 if test -n "$ac_tool_prefix"; then
   # Extract the first word of "${ac_tool_prefix}mt", so it can be a program name with args.
@@ -7152,7 +6981,7 @@ else
 fi
 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_mainfest_tool" >&5
 $as_echo "$lt_cv_path_mainfest_tool" >&6; }
-if test yes != "$lt_cv_path_mainfest_tool"; then
+if test "x$lt_cv_path_mainfest_tool" != xyes; then
   MANIFEST_TOOL=:
 fi
 
@@ -7655,7 +7484,7 @@ if ${lt_cv_apple_cc_single_mod+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   lt_cv_apple_cc_single_mod=no
-      if test -z "$LT_MULTI_MODULE"; then
+      if test -z "${LT_MULTI_MODULE}"; then
 	# By default we will add the -single_module flag. You can override
 	# by either setting the environment variable LT_MULTI_MODULE
 	# non-empty at configure time, or by adding -multi_module to the
@@ -7673,7 +7502,7 @@ else
 	  cat conftest.err >&5
 	# Otherwise, if the output was created with a 0 exit code from
 	# the compiler, it worked.
-	elif test -f libconftest.dylib && test 0 = "$_lt_result"; then
+	elif test -f libconftest.dylib && test $_lt_result -eq 0; then
 	  lt_cv_apple_cc_single_mod=yes
 	else
 	  cat conftest.err >&5
@@ -7712,7 +7541,7 @@ else
 fi
 rm -f core conftest.err conftest.$ac_objext \
     conftest$ac_exeext conftest.$ac_ext
-	LDFLAGS=$save_LDFLAGS
+	LDFLAGS="$save_LDFLAGS"
 
 fi
 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_exported_symbols_list" >&5
@@ -7741,7 +7570,7 @@ _LT_EOF
       _lt_result=$?
       if test -s conftest.err && $GREP force_load conftest.err; then
 	cat conftest.err >&5
-      elif test -f conftest && test 0 = "$_lt_result" && $GREP forced_load conftest >/dev/null 2>&1; then
+      elif test -f conftest && test $_lt_result -eq 0 && $GREP forced_load conftest >/dev/null 2>&1 ; then
 	lt_cv_ld_force_load=yes
       else
 	cat conftest.err >&5
@@ -7754,32 +7583,32 @@ fi
 $as_echo "$lt_cv_ld_force_load" >&6; }
     case $host_os in
     rhapsody* | darwin1.[012])
-      _lt_dar_allow_undefined='$wl-undefined ${wl}suppress' ;;
+      _lt_dar_allow_undefined='${wl}-undefined ${wl}suppress' ;;
     darwin1.*)
-      _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;;
+      _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;;
     darwin*) # darwin 5.x on
       # if running on 10.5 or later, the deployment target defaults
       # to the OS version, if on x86, and 10.4, the deployment
       # target defaults to 10.4. Don't you love it?
       case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in
 	10.0,*86*-darwin8*|10.0,*-darwin[91]*)
-	  _lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' ;;
-	10.[012][,.]*)
-	  _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;;
+	  _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;;
+	10.[012]*)
+	  _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;;
 	10.*)
-	  _lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' ;;
+	  _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;;
       esac
     ;;
   esac
-    if test yes = "$lt_cv_apple_cc_single_mod"; then
+    if test "$lt_cv_apple_cc_single_mod" = "yes"; then
       _lt_dar_single_mod='$single_module'
     fi
-    if test yes = "$lt_cv_ld_exported_symbols_list"; then
-      _lt_dar_export_syms=' $wl-exported_symbols_list,$output_objdir/$libname-symbols.expsym'
+    if test "$lt_cv_ld_exported_symbols_list" = "yes"; then
+      _lt_dar_export_syms=' ${wl}-exported_symbols_list,$output_objdir/${libname}-symbols.expsym'
     else
-      _lt_dar_export_syms='~$NMEDIT -s $output_objdir/$libname-symbols.expsym $lib'
+      _lt_dar_export_syms='~$NMEDIT -s $output_objdir/${libname}-symbols.expsym ${lib}'
     fi
-    if test : != "$DSYMUTIL" && test no = "$lt_cv_ld_force_load"; then
+    if test "$DSYMUTIL" != ":" && test "$lt_cv_ld_force_load" = "no"; then
       _lt_dsymutil='~$DSYMUTIL $lib || :'
     else
       _lt_dsymutil=
@@ -7787,41 +7616,6 @@ $as_echo "$lt_cv_ld_force_load" >&6; }
     ;;
   esac
 
-# func_munge_path_list VARIABLE PATH
-# -----------------------------------
-# VARIABLE is name of variable containing _space_ separated list of
-# directories to be munged by the contents of PATH, which is string
-# having a format:
-# "DIR[:DIR]:"
-#       string "DIR[ DIR]" will be prepended to VARIABLE
-# ":DIR[:DIR]"
-#       string "DIR[ DIR]" will be appended to VARIABLE
-# "DIRP[:DIRP]::[DIRA:]DIRA"
-#       string "DIRP[ DIRP]" will be prepended to VARIABLE and string
-#       "DIRA[ DIRA]" will be appended to VARIABLE
-# "DIR[:DIR]"
-#       VARIABLE will be replaced by "DIR[ DIR]"
-func_munge_path_list ()
-{
-    case x$2 in
-    x)
-        ;;
-    *:)
-        eval $1=\"`$ECHO $2 | $SED 's/:/ /g'` \$$1\"
-        ;;
-    x:*)
-        eval $1=\"\$$1 `$ECHO $2 | $SED 's/:/ /g'`\"
-        ;;
-    *::*)
-        eval $1=\"\$$1\ `$ECHO $2 | $SED -e 's/.*:://' -e 's/:/ /g'`\"
-        eval $1=\"`$ECHO $2 | $SED -e 's/::.*//' -e 's/:/ /g'`\ \$$1\"
-        ;;
-    *)
-        eval $1=\"`$ECHO $2 | $SED 's/:/ /g'`\"
-        ;;
-    esac
-}
-
 ac_ext=c
 ac_cpp='$CPP $CPPFLAGS'
 ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
@@ -8106,9 +7900,9 @@ done
 
 func_stripname_cnf ()
 {
-  case $2 in
-  .*) func_stripname_result=`$ECHO "$3" | $SED "s%^$1%%; s%\\\\$2\$%%"`;;
-  *)  func_stripname_result=`$ECHO "$3" | $SED "s%^$1%%; s%$2\$%%"`;;
+  case ${2} in
+  .*) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%\\\\${2}\$%%"`;;
+  *)  func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%${2}\$%%"`;;
   esac
 } # func_stripname_cnf
 
@@ -8135,14 +7929,14 @@ if test "${enable_shared+set}" = set; then :
     *)
       enable_shared=no
       # Look at the argument we got.  We use all the common list separators.
-      lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR,
+      lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
       for pkg in $enableval; do
-	IFS=$lt_save_ifs
+	IFS="$lt_save_ifs"
 	if test "X$pkg" = "X$p"; then
 	  enable_shared=yes
 	fi
       done
-      IFS=$lt_save_ifs
+      IFS="$lt_save_ifs"
       ;;
     esac
 else
@@ -8166,14 +7960,14 @@ if test "${enable_static+set}" = set; then :
     *)
      enable_static=no
       # Look at the argument we got.  We use all the common list separators.
-      lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR,
+      lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
       for pkg in $enableval; do
-	IFS=$lt_save_ifs
+	IFS="$lt_save_ifs"
 	if test "X$pkg" = "X$p"; then
 	  enable_static=yes
 	fi
       done
-      IFS=$lt_save_ifs
+      IFS="$lt_save_ifs"
       ;;
     esac
 else
@@ -8197,14 +7991,14 @@ if test "${with_pic+set}" = set; then :
     *)
       pic_mode=default
       # Look at the argument we got.  We use all the common list separators.
-      lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR,
+      lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
       for lt_pkg in $withval; do
-	IFS=$lt_save_ifs
+	IFS="$lt_save_ifs"
 	if test "X$lt_pkg" = "X$lt_p"; then
 	  pic_mode=yes
 	fi
       done
-      IFS=$lt_save_ifs
+      IFS="$lt_save_ifs"
       ;;
     esac
 else
@@ -8212,6 +8006,8 @@ else
 fi
 
 
+test -z "$pic_mode" && pic_mode=default
+
 
 
 
@@ -8227,14 +8023,14 @@ if test "${enable_fast_install+set}" = set; then :
     *)
       enable_fast_install=no
       # Look at the argument we got.  We use all the common list separators.
-      lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR,
+      lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
       for pkg in $enableval; do
-	IFS=$lt_save_ifs
+	IFS="$lt_save_ifs"
 	if test "X$pkg" = "X$p"; then
 	  enable_fast_install=yes
 	fi
       done
-      IFS=$lt_save_ifs
+      IFS="$lt_save_ifs"
       ;;
     esac
 else
@@ -8248,63 +8044,11 @@ fi
 
 
 
-  shared_archive_member_spec=
-case $host,$enable_shared in
-power*-*-aix[5-9]*,yes)
-  { $as_echo "$as_me:${as_lineno-$LINENO}: checking which variant of shared library versioning to provide" >&5
-$as_echo_n "checking which variant of shared library versioning to provide... " >&6; }
-
-# Check whether --with-aix-soname was given.
-if test "${with_aix_soname+set}" = set; then :
-  withval=$with_aix_soname; case $withval in
-    aix|svr4|both)
-      ;;
-    *)
-      as_fn_error $? "Unknown argument to --with-aix-soname" "$LINENO" 5
-      ;;
-    esac
-    lt_cv_with_aix_soname=$with_aix_soname
-else
-  if ${lt_cv_with_aix_soname+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  lt_cv_with_aix_soname=aix
-fi
-
-    with_aix_soname=$lt_cv_with_aix_soname
-fi
-
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $with_aix_soname" >&5
-$as_echo "$with_aix_soname" >&6; }
-  if test aix != "$with_aix_soname"; then
-    # For the AIX way of multilib, we name the shared archive member
-    # based on the bitwidth used, traditionally 'shr.o' or 'shr_64.o',
-    # and 'shr.imp' or 'shr_64.imp', respectively, for the Import File.
-    # Even when GNU compilers ignore OBJECT_MODE but need '-maix64' flag,
-    # the AIX toolchain works better with OBJECT_MODE set (default 32).
-    if test 64 = "${OBJECT_MODE-32}"; then
-      shared_archive_member_spec=shr_64
-    else
-      shared_archive_member_spec=shr
-    fi
-  fi
-  ;;
-*)
-  with_aix_soname=aix
-  ;;
-esac
-
-
-
-
-
-
-
 
 
 
 # This can be used to rebuild libtool when needed
-LIBTOOL_DEPS=$ltmain
+LIBTOOL_DEPS="$ltmain"
 
 # Always use our own libtool.
 LIBTOOL='$(SHELL) $(top_builddir)/libtool'
@@ -8353,7 +8097,7 @@ test -z "$LN_S" && LN_S="ln -s"
 
 
 
-if test -n "${ZSH_VERSION+set}"; then
+if test -n "${ZSH_VERSION+set}" ; then
    setopt NO_GLOB_SUBST
 fi
 
@@ -8392,7 +8136,7 @@ aix3*)
   # AIX sometimes has problems with the GCC collect2 program.  For some
   # reason, if we set the COLLECT_NAMES environment variable, the problems
   # vanish in a puff of smoke.
-  if test set != "${COLLECT_NAMES+set}"; then
+  if test "X${COLLECT_NAMES+set}" != Xset; then
     COLLECT_NAMES=
     export COLLECT_NAMES
   fi
@@ -8403,14 +8147,14 @@ esac
 ofile=libtool
 can_build_shared=yes
 
-# All known linkers require a '.a' archive for static linking (except MSVC,
+# All known linkers require a `.a' archive for static linking (except MSVC,
 # which needs '.lib').
 libext=a
 
-with_gnu_ld=$lt_cv_prog_gnu_ld
+with_gnu_ld="$lt_cv_prog_gnu_ld"
 
-old_CC=$CC
-old_CFLAGS=$CFLAGS
+old_CC="$CC"
+old_CFLAGS="$CFLAGS"
 
 # Set sane defaults for various variables
 test -z "$CC" && CC=cc
@@ -8419,8 +8163,15 @@ test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS
 test -z "$LD" && LD=ld
 test -z "$ac_objext" && ac_objext=o
 
-func_cc_basename $compiler
-cc_basename=$func_cc_basename_result
+for cc_temp in $compiler""; do
+  case $cc_temp in
+    compile | *[\\/]compile | ccache | *[\\/]ccache ) ;;
+    distcc | *[\\/]distcc | purify | *[\\/]purify ) ;;
+    \-*) ;;
+    *) break;;
+  esac
+done
+cc_basename=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"`
 
 
 # Only perform the check for file, if the check method requires it
@@ -8435,22 +8186,22 @@ if ${lt_cv_path_MAGIC_CMD+:} false; then :
 else
   case $MAGIC_CMD in
 [\\/*] |  ?:[\\/]*)
-  lt_cv_path_MAGIC_CMD=$MAGIC_CMD # Let the user override the test with a path.
+  lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path.
   ;;
 *)
-  lt_save_MAGIC_CMD=$MAGIC_CMD
-  lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR
+  lt_save_MAGIC_CMD="$MAGIC_CMD"
+  lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
   ac_dummy="/usr/bin$PATH_SEPARATOR$PATH"
   for ac_dir in $ac_dummy; do
-    IFS=$lt_save_ifs
+    IFS="$lt_save_ifs"
     test -z "$ac_dir" && ac_dir=.
-    if test -f "$ac_dir/${ac_tool_prefix}file"; then
-      lt_cv_path_MAGIC_CMD=$ac_dir/"${ac_tool_prefix}file"
+    if test -f $ac_dir/${ac_tool_prefix}file; then
+      lt_cv_path_MAGIC_CMD="$ac_dir/${ac_tool_prefix}file"
       if test -n "$file_magic_test_file"; then
 	case $deplibs_check_method in
 	"file_magic "*)
 	  file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"`
-	  MAGIC_CMD=$lt_cv_path_MAGIC_CMD
+	  MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
 	  if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null |
 	    $EGREP "$file_magic_regex" > /dev/null; then
 	    :
@@ -8473,13 +8224,13 @@ _LT_EOF
       break
     fi
   done
-  IFS=$lt_save_ifs
-  MAGIC_CMD=$lt_save_MAGIC_CMD
+  IFS="$lt_save_ifs"
+  MAGIC_CMD="$lt_save_MAGIC_CMD"
   ;;
 esac
 fi
 
-MAGIC_CMD=$lt_cv_path_MAGIC_CMD
+MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
 if test -n "$MAGIC_CMD"; then
   { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5
 $as_echo "$MAGIC_CMD" >&6; }
@@ -8501,22 +8252,22 @@ if ${lt_cv_path_MAGIC_CMD+:} false; then :
 else
   case $MAGIC_CMD in
 [\\/*] |  ?:[\\/]*)
-  lt_cv_path_MAGIC_CMD=$MAGIC_CMD # Let the user override the test with a path.
+  lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path.
   ;;
 *)
-  lt_save_MAGIC_CMD=$MAGIC_CMD
-  lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR
+  lt_save_MAGIC_CMD="$MAGIC_CMD"
+  lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
   ac_dummy="/usr/bin$PATH_SEPARATOR$PATH"
   for ac_dir in $ac_dummy; do
-    IFS=$lt_save_ifs
+    IFS="$lt_save_ifs"
     test -z "$ac_dir" && ac_dir=.
-    if test -f "$ac_dir/file"; then
-      lt_cv_path_MAGIC_CMD=$ac_dir/"file"
+    if test -f $ac_dir/file; then
+      lt_cv_path_MAGIC_CMD="$ac_dir/file"
       if test -n "$file_magic_test_file"; then
 	case $deplibs_check_method in
 	"file_magic "*)
 	  file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"`
-	  MAGIC_CMD=$lt_cv_path_MAGIC_CMD
+	  MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
 	  if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null |
 	    $EGREP "$file_magic_regex" > /dev/null; then
 	    :
@@ -8539,13 +8290,13 @@ _LT_EOF
       break
     fi
   done
-  IFS=$lt_save_ifs
-  MAGIC_CMD=$lt_save_MAGIC_CMD
+  IFS="$lt_save_ifs"
+  MAGIC_CMD="$lt_save_MAGIC_CMD"
   ;;
 esac
 fi
 
-MAGIC_CMD=$lt_cv_path_MAGIC_CMD
+MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
 if test -n "$MAGIC_CMD"; then
   { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5
 $as_echo "$MAGIC_CMD" >&6; }
@@ -8566,7 +8317,7 @@ esac
 
 # Use C for the default configuration in the libtool script
 
-lt_save_CC=$CC
+lt_save_CC="$CC"
 ac_ext=c
 ac_cpp='$CPP $CPPFLAGS'
 ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
@@ -8628,7 +8379,7 @@ if test -n "$compiler"; then
 
 lt_prog_compiler_no_builtin_flag=
 
-if test yes = "$GCC"; then
+if test "$GCC" = yes; then
   case $cc_basename in
   nvcc*)
     lt_prog_compiler_no_builtin_flag=' -Xcompiler -fno-builtin' ;;
@@ -8644,7 +8395,7 @@ else
   lt_cv_prog_compiler_rtti_exceptions=no
    ac_outfile=conftest.$ac_objext
    echo "$lt_simple_compile_test_code" > conftest.$ac_ext
-   lt_compiler_flag="-fno-rtti -fno-exceptions"  ## exclude from sc_useless_quotes_in_assignment
+   lt_compiler_flag="-fno-rtti -fno-exceptions"
    # Insert the option either (1) after the last *FLAGS variable, or
    # (2) before a word containing "conftest.", or (3) at the end.
    # Note that $ac_compile itself does not contain backslashes and begins
@@ -8674,7 +8425,7 @@ fi
 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_rtti_exceptions" >&5
 $as_echo "$lt_cv_prog_compiler_rtti_exceptions" >&6; }
 
-if test yes = "$lt_cv_prog_compiler_rtti_exceptions"; then
+if test x"$lt_cv_prog_compiler_rtti_exceptions" = xyes; then
     lt_prog_compiler_no_builtin_flag="$lt_prog_compiler_no_builtin_flag -fno-rtti -fno-exceptions"
 else
     :
@@ -8692,18 +8443,17 @@ lt_prog_compiler_pic=
 lt_prog_compiler_static=
 
 
-  if test yes = "$GCC"; then
+  if test "$GCC" = yes; then
     lt_prog_compiler_wl='-Wl,'
     lt_prog_compiler_static='-static'
 
     case $host_os in
       aix*)
       # All AIX code is PIC.
-      if test ia64 = "$host_cpu"; then
+      if test "$host_cpu" = ia64; then
 	# AIX 5 now supports IA64 processor
 	lt_prog_compiler_static='-Bstatic'
       fi
-      lt_prog_compiler_pic='-fPIC'
       ;;
 
     amigaos*)
@@ -8714,8 +8464,8 @@ lt_prog_compiler_static=
         ;;
       m68k)
             # FIXME: we need at least 68020 code to build shared libraries, but
-            # adding the '-m68020' flag to GCC prevents building anything better,
-            # like '-m68040'.
+            # adding the `-m68020' flag to GCC prevents building anything better,
+            # like `-m68040'.
             lt_prog_compiler_pic='-m68020 -resident32 -malways-restore-a4'
         ;;
       esac
@@ -8731,11 +8481,6 @@ lt_prog_compiler_static=
       # Although the cygwin gcc ignores -fPIC, still need this for old-style
       # (--disable-auto-import) libraries
       lt_prog_compiler_pic='-DDLL_EXPORT'
-      case $host_os in
-      os2*)
-	lt_prog_compiler_static='$wl-static'
-	;;
-      esac
       ;;
 
     darwin* | rhapsody*)
@@ -8806,7 +8551,7 @@ lt_prog_compiler_static=
     case $host_os in
     aix*)
       lt_prog_compiler_wl='-Wl,'
-      if test ia64 = "$host_cpu"; then
+      if test "$host_cpu" = ia64; then
 	# AIX 5 now supports IA64 processor
 	lt_prog_compiler_static='-Bstatic'
       else
@@ -8814,29 +8559,10 @@ lt_prog_compiler_static=
       fi
       ;;
 
-    darwin* | rhapsody*)
-      # PIC is the default on this platform
-      # Common symbols not allowed in MH_DYLIB files
-      lt_prog_compiler_pic='-fno-common'
-      case $cc_basename in
-      nagfor*)
-        # NAG Fortran compiler
-        lt_prog_compiler_wl='-Wl,-Wl,,'
-        lt_prog_compiler_pic='-PIC'
-        lt_prog_compiler_static='-Bstatic'
-        ;;
-      esac
-      ;;
-
     mingw* | cygwin* | pw32* | os2* | cegcc*)
       # This hack is so that the source file can tell whether it is being
       # built for inclusion in a dll (and should export symbols for example).
       lt_prog_compiler_pic='-DDLL_EXPORT'
-      case $host_os in
-      os2*)
-	lt_prog_compiler_static='$wl-static'
-	;;
-      esac
       ;;
 
     hpux9* | hpux10* | hpux11*)
@@ -8852,7 +8578,7 @@ lt_prog_compiler_static=
 	;;
       esac
       # Is there a better lt_prog_compiler_static that works with the bundled CC?
-      lt_prog_compiler_static='$wl-a ${wl}archive'
+      lt_prog_compiler_static='${wl}-a ${wl}archive'
       ;;
 
     irix5* | irix6* | nonstopux*)
@@ -8863,7 +8589,7 @@ lt_prog_compiler_static=
 
     linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*)
       case $cc_basename in
-      # old Intel for x86_64, which still supported -KPIC.
+      # old Intel for x86_64 which still supported -KPIC.
       ecc*)
 	lt_prog_compiler_wl='-Wl,'
 	lt_prog_compiler_pic='-KPIC'
@@ -8888,12 +8614,6 @@ lt_prog_compiler_static=
 	lt_prog_compiler_pic='-PIC'
 	lt_prog_compiler_static='-Bstatic'
 	;;
-      tcc*)
-	# Fabrice Bellard et al's Tiny C Compiler
-	lt_prog_compiler_wl='-Wl,'
-	lt_prog_compiler_pic='-fPIC'
-	lt_prog_compiler_static='-static'
-	;;
       pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*)
         # Portland Group compilers (*not* the Pentium gcc compiler,
 	# which looks to be a dead project)
@@ -8991,7 +8711,7 @@ lt_prog_compiler_static=
       ;;
 
     sysv4*MP*)
-      if test -d /usr/nec; then
+      if test -d /usr/nec ;then
 	lt_prog_compiler_pic='-Kconform_pic'
 	lt_prog_compiler_static='-Bstatic'
       fi
@@ -9020,7 +8740,7 @@ lt_prog_compiler_static=
   fi
 
 case $host_os in
-  # For platforms that do not support PIC, -DPIC is meaningless:
+  # For platforms which do not support PIC, -DPIC is meaningless:
   *djgpp*)
     lt_prog_compiler_pic=
     ;;
@@ -9052,7 +8772,7 @@ else
   lt_cv_prog_compiler_pic_works=no
    ac_outfile=conftest.$ac_objext
    echo "$lt_simple_compile_test_code" > conftest.$ac_ext
-   lt_compiler_flag="$lt_prog_compiler_pic -DPIC"  ## exclude from sc_useless_quotes_in_assignment
+   lt_compiler_flag="$lt_prog_compiler_pic -DPIC"
    # Insert the option either (1) after the last *FLAGS variable, or
    # (2) before a word containing "conftest.", or (3) at the end.
    # Note that $ac_compile itself does not contain backslashes and begins
@@ -9082,7 +8802,7 @@ fi
 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_works" >&5
 $as_echo "$lt_cv_prog_compiler_pic_works" >&6; }
 
-if test yes = "$lt_cv_prog_compiler_pic_works"; then
+if test x"$lt_cv_prog_compiler_pic_works" = xyes; then
     case $lt_prog_compiler_pic in
      "" | " "*) ;;
      *) lt_prog_compiler_pic=" $lt_prog_compiler_pic" ;;
@@ -9114,7 +8834,7 @@ if ${lt_cv_prog_compiler_static_works+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   lt_cv_prog_compiler_static_works=no
-   save_LDFLAGS=$LDFLAGS
+   save_LDFLAGS="$LDFLAGS"
    LDFLAGS="$LDFLAGS $lt_tmp_static_flag"
    echo "$lt_simple_link_test_code" > conftest.$ac_ext
    if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then
@@ -9133,13 +8853,13 @@ else
      fi
    fi
    $RM -r conftest*
-   LDFLAGS=$save_LDFLAGS
+   LDFLAGS="$save_LDFLAGS"
 
 fi
 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_static_works" >&5
 $as_echo "$lt_cv_prog_compiler_static_works" >&6; }
 
-if test yes = "$lt_cv_prog_compiler_static_works"; then
+if test x"$lt_cv_prog_compiler_static_works" = xyes; then
     :
 else
     lt_prog_compiler_static=
@@ -9259,8 +8979,8 @@ $as_echo "$lt_cv_prog_compiler_c_o" >&6; }
 
 
 
-hard_links=nottested
-if test no = "$lt_cv_prog_compiler_c_o" && test no != "$need_locks"; then
+hard_links="nottested"
+if test "$lt_cv_prog_compiler_c_o" = no && test "$need_locks" != no; then
   # do not overwrite the value of need_locks provided by the user
   { $as_echo "$as_me:${as_lineno-$LINENO}: checking if we can lock with hard links" >&5
 $as_echo_n "checking if we can lock with hard links... " >&6; }
@@ -9272,9 +8992,9 @@ $as_echo_n "checking if we can lock with hard links... " >&6; }
   ln conftest.a conftest.b 2>/dev/null && hard_links=no
   { $as_echo "$as_me:${as_lineno-$LINENO}: result: $hard_links" >&5
 $as_echo "$hard_links" >&6; }
-  if test no = "$hard_links"; then
-    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: '$CC' does not support '-c -o', so 'make -j' may be unsafe" >&5
-$as_echo "$as_me: WARNING: '$CC' does not support '-c -o', so 'make -j' may be unsafe" >&2;}
+  if test "$hard_links" = no; then
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&5
+$as_echo "$as_me: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&2;}
     need_locks=warn
   fi
 else
@@ -9317,9 +9037,9 @@ $as_echo_n "checking whether the $compiler linker ($LD) supports shared librarie
   # included in the symbol list
   include_expsyms=
   # exclude_expsyms can be an extended regexp of symbols to exclude
-  # it will be wrapped by ' (' and ')$', so one must not match beginning or
-  # end of line.  Example: 'a|bc|.*d.*' will exclude the symbols 'a' and 'bc',
-  # as well as any symbol that contains 'd'.
+  # it will be wrapped by ` (' and `)$', so one must not match beginning or
+  # end of line.  Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc',
+  # as well as any symbol that contains `d'.
   exclude_expsyms='_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'
   # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out
   # platforms (ab)use it in PIC code, but their linkers get confused if
@@ -9334,7 +9054,7 @@ $as_echo_n "checking whether the $compiler linker ($LD) supports shared librarie
     # FIXME: the MSVC++ port hasn't been tested in a loooong time
     # When not using gcc, we currently assume that we are using
     # Microsoft Visual C++.
-    if test yes != "$GCC"; then
+    if test "$GCC" != yes; then
       with_gnu_ld=no
     fi
     ;;
@@ -9342,7 +9062,7 @@ $as_echo_n "checking whether the $compiler linker ($LD) supports shared librarie
     # we just hope/assume this is gcc and not c89 (= MSVC++)
     with_gnu_ld=yes
     ;;
-  openbsd* | bitrig*)
+  openbsd*)
     with_gnu_ld=no
     ;;
   linux* | k*bsd*-gnu | gnu*)
@@ -9355,7 +9075,7 @@ $as_echo_n "checking whether the $compiler linker ($LD) supports shared librarie
   # On some targets, GNU ld is compatible enough with the native linker
   # that we're better off using the native interface for both.
   lt_use_gnu_ld_interface=no
-  if test yes = "$with_gnu_ld"; then
+  if test "$with_gnu_ld" = yes; then
     case $host_os in
       aix*)
 	# The AIX port of GNU ld has always aspired to compatibility
@@ -9377,24 +9097,24 @@ $as_echo_n "checking whether the $compiler linker ($LD) supports shared librarie
     esac
   fi
 
-  if test yes = "$lt_use_gnu_ld_interface"; then
+  if test "$lt_use_gnu_ld_interface" = yes; then
     # If archive_cmds runs LD, not CC, wlarc should be empty
-    wlarc='$wl'
+    wlarc='${wl}'
 
     # Set some defaults for GNU ld with shared library support. These
     # are reset later if shared libraries are not supported. Putting them
     # here allows them to be overridden if necessary.
     runpath_var=LD_RUN_PATH
-    hardcode_libdir_flag_spec='$wl-rpath $wl$libdir'
-    export_dynamic_flag_spec='$wl--export-dynamic'
+    hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+    export_dynamic_flag_spec='${wl}--export-dynamic'
     # ancient GNU ld didn't support --whole-archive et. al.
     if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then
-      whole_archive_flag_spec=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive'
+      whole_archive_flag_spec="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive'
     else
       whole_archive_flag_spec=
     fi
     supports_anon_versioning=no
-    case `$LD -v | $SED -e 's/(^)\+)\s\+//' 2>&1` in
+    case `$LD -v 2>&1` in
       *GNU\ gold*) supports_anon_versioning=yes ;;
       *\ [01].* | *\ 2.[0-9].* | *\ 2.10.*) ;; # catch versions < 2.11
       *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ...
@@ -9407,7 +9127,7 @@ $as_echo_n "checking whether the $compiler linker ($LD) supports shared librarie
     case $host_os in
     aix[3-9]*)
       # On AIX/PPC, the GNU linker is very broken
-      if test ia64 != "$host_cpu"; then
+      if test "$host_cpu" != ia64; then
 	ld_shlibs=no
 	cat <<_LT_EOF 1>&2
 
@@ -9426,7 +9146,7 @@ _LT_EOF
       case $host_cpu in
       powerpc)
             # see comment about AmigaOS4 .so support
-            archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+            archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
             archive_expsym_cmds=''
         ;;
       m68k)
@@ -9442,7 +9162,7 @@ _LT_EOF
 	allow_undefined_flag=unsupported
 	# Joseph Beckenbach <jrb3 at best.com> says some releases of gcc
 	# support --undefined.  This deserves some investigation.  FIXME
-	archive_cmds='$CC -nostart $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+	archive_cmds='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
       else
 	ld_shlibs=no
       fi
@@ -9452,7 +9172,7 @@ _LT_EOF
       # _LT_TAGVAR(hardcode_libdir_flag_spec, ) is actually meaningless,
       # as there is no search path for DLLs.
       hardcode_libdir_flag_spec='-L$libdir'
-      export_dynamic_flag_spec='$wl--export-all-symbols'
+      export_dynamic_flag_spec='${wl}--export-all-symbols'
       allow_undefined_flag=unsupported
       always_export_symbols=no
       enable_shared_with_static_runtimes=yes
@@ -9460,89 +9180,61 @@ _LT_EOF
       exclude_expsyms='[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname'
 
       if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then
-        archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
-	# If the export-symbols file already is a .def file, use it as
-	# is; otherwise, prepend EXPORTS...
-	archive_expsym_cmds='if   test DEF = "`$SED -n     -e '\''s/^[	 ]*//'\''     -e '\''/^\(;.*\)*$/d'\''     -e '\''s/^\(EXPORTS\|LIBRARY\)\([	 ].*\)*$/DEF/p'\''     -e q     $export_symbols`" ; then
-          cp $export_symbols $output_objdir/$soname.def;
-        else
-          echo EXPORTS > $output_objdir/$soname.def;
-          cat $export_symbols >> $output_objdir/$soname.def;
-        fi~
-        $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+        archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+	# If the export-symbols file already is a .def file (1st line
+	# is EXPORTS), use it as is; otherwise, prepend...
+	archive_expsym_cmds='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then
+	  cp $export_symbols $output_objdir/$soname.def;
+	else
+	  echo EXPORTS > $output_objdir/$soname.def;
+	  cat $export_symbols >> $output_objdir/$soname.def;
+	fi~
+	$CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
       else
 	ld_shlibs=no
       fi
       ;;
 
     haiku*)
-      archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+      archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
       link_all_deplibs=yes
       ;;
 
-    os2*)
-      hardcode_libdir_flag_spec='-L$libdir'
-      hardcode_minus_L=yes
-      allow_undefined_flag=unsupported
-      shrext_cmds=.dll
-      archive_cmds='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~
-	$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~
-	$ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~
-	$ECHO EXPORTS >> $output_objdir/$libname.def~
-	emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~
-	$CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~
-	emximp -o $lib $output_objdir/$libname.def'
-      archive_expsym_cmds='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~
-	$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~
-	$ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~
-	$ECHO EXPORTS >> $output_objdir/$libname.def~
-	prefix_cmds="$SED"~
-	if test EXPORTS = "`$SED 1q $export_symbols`"; then
-	  prefix_cmds="$prefix_cmds -e 1d";
-	fi~
-	prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~
-	cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~
-	$CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~
-	emximp -o $lib $output_objdir/$libname.def'
-      old_archive_From_new_cmds='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def'
-      enable_shared_with_static_runtimes=yes
-      ;;
-
     interix[3-9]*)
       hardcode_direct=no
       hardcode_shlibpath_var=no
-      hardcode_libdir_flag_spec='$wl-rpath,$libdir'
-      export_dynamic_flag_spec='$wl-E'
+      hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
+      export_dynamic_flag_spec='${wl}-E'
       # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc.
       # Instead, shared libraries are loaded at an image base (0x10000000 by
       # default) and relocated if they conflict, which is a slow very memory
       # consuming and fragmenting process.  To avoid this, we pick a random,
       # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link
       # time.  Moving up from 0x10000000 also allows more sbrk(2) space.
-      archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
-      archive_expsym_cmds='sed "s|^|_|" $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--retain-symbols-file,$output_objdir/$soname.expsym $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+      archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+      archive_expsym_cmds='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
       ;;
 
     gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu)
       tmp_diet=no
-      if test linux-dietlibc = "$host_os"; then
+      if test "$host_os" = linux-dietlibc; then
 	case $cc_basename in
 	  diet\ *) tmp_diet=yes;;	# linux-dietlibc with static linking (!diet-dyn)
 	esac
       fi
       if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \
-	 && test no = "$tmp_diet"
+	 && test "$tmp_diet" = no
       then
 	tmp_addflag=' $pic_flag'
 	tmp_sharedflag='-shared'
 	case $cc_basename,$host_cpu in
         pgcc*)				# Portland Group C compiler
-	  whole_archive_flag_spec='$wl--whole-archive`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive'
+	  whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
 	  tmp_addflag=' $pic_flag'
 	  ;;
 	pgf77* | pgf90* | pgf95* | pgfortran*)
 					# Portland Group f77 and f90 compilers
-	  whole_archive_flag_spec='$wl--whole-archive`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive'
+	  whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
 	  tmp_addflag=' $pic_flag -Mnomain' ;;
 	ecc*,ia64* | icc*,ia64*)	# Intel C compiler on ia64
 	  tmp_addflag=' -i_dynamic' ;;
@@ -9553,47 +9245,42 @@ _LT_EOF
 	lf95*)				# Lahey Fortran 8.1
 	  whole_archive_flag_spec=
 	  tmp_sharedflag='--shared' ;;
-        nagfor*)                        # NAGFOR 5.3
-          tmp_sharedflag='-Wl,-shared' ;;
 	xl[cC]* | bgxl[cC]* | mpixl[cC]*) # IBM XL C 8.0 on PPC (deal with xlf below)
 	  tmp_sharedflag='-qmkshrobj'
 	  tmp_addflag= ;;
 	nvcc*)	# Cuda Compiler Driver 2.2
-	  whole_archive_flag_spec='$wl--whole-archive`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive'
+	  whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
 	  compiler_needs_object=yes
 	  ;;
 	esac
 	case `$CC -V 2>&1 | sed 5q` in
 	*Sun\ C*)			# Sun C 5.9
-	  whole_archive_flag_spec='$wl--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive'
+	  whole_archive_flag_spec='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
 	  compiler_needs_object=yes
 	  tmp_sharedflag='-G' ;;
 	*Sun\ F*)			# Sun Fortran 8.3
 	  tmp_sharedflag='-G' ;;
 	esac
-	archive_cmds='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+	archive_cmds='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
 
-        if test yes = "$supports_anon_versioning"; then
+        if test "x$supports_anon_versioning" = xyes; then
           archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~
-            cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
-            echo "local: *; };" >> $output_objdir/$libname.ver~
-            $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-version-script $wl$output_objdir/$libname.ver -o $lib'
+	    cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
+	    echo "local: *; };" >> $output_objdir/$libname.ver~
+	    $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib'
         fi
 
 	case $cc_basename in
-	tcc*)
-	  export_dynamic_flag_spec='-rdynamic'
-	  ;;
 	xlf* | bgf* | bgxlf* | mpixlf*)
 	  # IBM XL Fortran 10.1 on PPC cannot create shared libs itself
 	  whole_archive_flag_spec='--whole-archive$convenience --no-whole-archive'
-	  hardcode_libdir_flag_spec='$wl-rpath $wl$libdir'
+	  hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
 	  archive_cmds='$LD -shared $libobjs $deplibs $linker_flags -soname $soname -o $lib'
-	  if test yes = "$supports_anon_versioning"; then
+	  if test "x$supports_anon_versioning" = xyes; then
 	    archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~
-              cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
-              echo "local: *; };" >> $output_objdir/$libname.ver~
-              $LD -shared $libobjs $deplibs $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib'
+	      cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
+	      echo "local: *; };" >> $output_objdir/$libname.ver~
+	      $LD -shared $libobjs $deplibs $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib'
 	  fi
 	  ;;
 	esac
@@ -9607,8 +9294,8 @@ _LT_EOF
 	archive_cmds='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib'
 	wlarc=
       else
-	archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
-	archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'
+	archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+	archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
       fi
       ;;
 
@@ -9626,8 +9313,8 @@ _LT_EOF
 
 _LT_EOF
       elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
-	archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
-	archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'
+	archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+	archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
       else
 	ld_shlibs=no
       fi
@@ -9639,7 +9326,7 @@ _LT_EOF
 	ld_shlibs=no
 	cat <<_LT_EOF 1>&2
 
-*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 cannot
+*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 can not
 *** reliably create shared libraries on SCO systems.  Therefore, libtool
 *** is disabling shared libraries support.  We urge you to upgrade GNU
 *** binutils to release 2.16.91.0.3 or newer.  Another option is to modify
@@ -9654,9 +9341,9 @@ _LT_EOF
 	  # DT_RUNPATH tag from executables and libraries.  But doing so
 	  # requires that you compile everything twice, which is a pain.
 	  if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
-	    hardcode_libdir_flag_spec='$wl-rpath $wl$libdir'
-	    archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
-	    archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'
+	    hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+	    archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+	    archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
 	  else
 	    ld_shlibs=no
 	  fi
@@ -9673,15 +9360,15 @@ _LT_EOF
 
     *)
       if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
-	archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
-	archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'
+	archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+	archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
       else
 	ld_shlibs=no
       fi
       ;;
     esac
 
-    if test no = "$ld_shlibs"; then
+    if test "$ld_shlibs" = no; then
       runpath_var=
       hardcode_libdir_flag_spec=
       export_dynamic_flag_spec=
@@ -9697,7 +9384,7 @@ _LT_EOF
       # Note: this linker hardcodes the directories in LIBPATH if there
       # are no directories specified by -L.
       hardcode_minus_L=yes
-      if test yes = "$GCC" && test -z "$lt_prog_compiler_static"; then
+      if test "$GCC" = yes && test -z "$lt_prog_compiler_static"; then
 	# Neither direct hardcoding nor static linking is supported with a
 	# broken collect2.
 	hardcode_direct=unsupported
@@ -9705,57 +9392,34 @@ _LT_EOF
       ;;
 
     aix[4-9]*)
-      if test ia64 = "$host_cpu"; then
+      if test "$host_cpu" = ia64; then
 	# On IA64, the linker does run time linking by default, so we don't
 	# have to do anything special.
 	aix_use_runtimelinking=no
 	exp_sym_flag='-Bexport'
-	no_entry_flag=
+	no_entry_flag=""
       else
 	# If we're using GNU nm, then we don't want the "-C" option.
-	# -C means demangle to GNU nm, but means don't demangle to AIX nm.
-	# Without the "-l" option, or with the "-B" option, AIX nm treats
-	# weak defined symbols like other global defined symbols, whereas
-	# GNU nm marks them as "W".
-	# While the 'weak' keyword is ignored in the Export File, we need
-	# it in the Import File for the 'aix-soname' feature, so we have
-	# to replace the "-B" option with "-P" for AIX nm.
+	# -C means demangle to AIX nm, but means don't demangle with GNU nm
+	# Also, AIX nm treats weak defined symbols like other global
+	# defined symbols, whereas GNU nm marks them as "W".
 	if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then
-	  export_symbols_cmds='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && (substr(\$ 3,1,1) != ".")) { if (\$ 2 == "W") { print \$ 3 " weak" } else { print \$ 3 } } }'\'' | sort -u > $export_symbols'
+	  export_symbols_cmds='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols'
 	else
-	  export_symbols_cmds='`func_echo_all $NM | $SED -e '\''s/B\([^B]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && (substr(\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols'
+	  export_symbols_cmds='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols'
 	fi
 	aix_use_runtimelinking=no
 
 	# Test if we are trying to use run time linking or normal
 	# AIX style linking. If -brtl is somewhere in LDFLAGS, we
-	# have runtime linking enabled, and use it for executables.
-	# For shared libraries, we enable/disable runtime linking
-	# depending on the kind of the shared library created -
-	# when "with_aix_soname,aix_use_runtimelinking" is:
-	# "aix,no"   lib.a(lib.so.V) shared, rtl:no,  for executables
-	# "aix,yes"  lib.so          shared, rtl:yes, for executables
-	#            lib.a           static archive
-	# "both,no"  lib.so.V(shr.o) shared, rtl:yes
-	#            lib.a(lib.so.V) shared, rtl:no,  for executables
-	# "both,yes" lib.so.V(shr.o) shared, rtl:yes, for executables
-	#            lib.a(lib.so.V) shared, rtl:no
-	# "svr4,*"   lib.so.V(shr.o) shared, rtl:yes, for executables
-	#            lib.a           static archive
+	# need to do runtime linking.
 	case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*)
 	  for ld_flag in $LDFLAGS; do
-	  if (test x-brtl = "x$ld_flag" || test x-Wl,-brtl = "x$ld_flag"); then
+	  if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then
 	    aix_use_runtimelinking=yes
 	    break
 	  fi
 	  done
-	  if test svr4,no = "$with_aix_soname,$aix_use_runtimelinking"; then
-	    # With aix-soname=svr4, we create the lib.so.V shared archives only,
-	    # so we don't have lib.a shared libs to link our executables.
-	    # We have to force runtime linking in this case.
-	    aix_use_runtimelinking=yes
-	    LDFLAGS="$LDFLAGS -Wl,-brtl"
-	  fi
 	  ;;
 	esac
 
@@ -9774,21 +9438,13 @@ _LT_EOF
       hardcode_direct_absolute=yes
       hardcode_libdir_separator=':'
       link_all_deplibs=yes
-      file_list_spec='$wl-f,'
-      case $with_aix_soname,$aix_use_runtimelinking in
-      aix,*) ;; # traditional, no import file
-      svr4,* | *,yes) # use import file
-	# The Import File defines what to hardcode.
-	hardcode_direct=no
-	hardcode_direct_absolute=no
-	;;
-      esac
+      file_list_spec='${wl}-f,'
 
-      if test yes = "$GCC"; then
+      if test "$GCC" = yes; then
 	case $host_os in aix4.[012]|aix4.[012].*)
 	# We only want to do this on AIX 4.2 and lower, the check
 	# below for broken collect2 doesn't work under 4.3+
-	  collect2name=`$CC -print-prog-name=collect2`
+	  collect2name=`${CC} -print-prog-name=collect2`
 	  if test -f "$collect2name" &&
 	   strings "$collect2name" | $GREP resolve_lib_name >/dev/null
 	  then
@@ -9807,42 +9463,36 @@ _LT_EOF
 	  ;;
 	esac
 	shared_flag='-shared'
-	if test yes = "$aix_use_runtimelinking"; then
-	  shared_flag="$shared_flag "'$wl-G'
+	if test "$aix_use_runtimelinking" = yes; then
+	  shared_flag="$shared_flag "'${wl}-G'
 	fi
-	# Need to ensure runtime linking is disabled for the traditional
-	# shared library, or the linker may eventually find shared libraries
-	# /with/ Import File - we do not want to mix them.
-	shared_flag_aix='-shared'
-	shared_flag_svr4='-shared $wl-G'
+	link_all_deplibs=no
       else
 	# not using gcc
-	if test ia64 = "$host_cpu"; then
+	if test "$host_cpu" = ia64; then
 	# VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release
 	# chokes on -Wl,-G. The following line is correct:
 	  shared_flag='-G'
 	else
-	  if test yes = "$aix_use_runtimelinking"; then
-	    shared_flag='$wl-G'
+	  if test "$aix_use_runtimelinking" = yes; then
+	    shared_flag='${wl}-G'
 	  else
-	    shared_flag='$wl-bM:SRE'
+	    shared_flag='${wl}-bM:SRE'
 	  fi
-	  shared_flag_aix='$wl-bM:SRE'
-	  shared_flag_svr4='$wl-G'
 	fi
       fi
 
-      export_dynamic_flag_spec='$wl-bexpall'
+      export_dynamic_flag_spec='${wl}-bexpall'
       # It seems that -bexpall does not export symbols beginning with
       # underscore (_), so it is better to generate a list of symbols to export.
       always_export_symbols=yes
-      if test aix,yes = "$with_aix_soname,$aix_use_runtimelinking"; then
+      if test "$aix_use_runtimelinking" = yes; then
 	# Warning - without using the other runtime loading flags (-brtl),
 	# -berok will link without error, but may produce a broken library.
 	allow_undefined_flag='-berok'
         # Determine the default libpath from the value encoded in an
         # empty executable.
-        if test set = "${lt_cv_aix_libpath+set}"; then
+        if test "${lt_cv_aix_libpath+set}" = set; then
   aix_libpath=$lt_cv_aix_libpath
 else
   if ${lt_cv_aix_libpath_+:} false; then :
@@ -9877,7 +9527,7 @@ fi
 rm -f core conftest.err conftest.$ac_objext \
     conftest$ac_exeext conftest.$ac_ext
   if test -z "$lt_cv_aix_libpath_"; then
-    lt_cv_aix_libpath_=/usr/lib:/lib
+    lt_cv_aix_libpath_="/usr/lib:/lib"
   fi
 
 fi
@@ -9885,17 +9535,17 @@ fi
   aix_libpath=$lt_cv_aix_libpath_
 fi
 
-        hardcode_libdir_flag_spec='$wl-blibpath:$libdir:'"$aix_libpath"
-        archive_expsym_cmds='$CC -o $output_objdir/$soname $libobjs $deplibs $wl'$no_entry_flag' $compiler_flags `if test -n "$allow_undefined_flag"; then func_echo_all "$wl$allow_undefined_flag"; else :; fi` $wl'$exp_sym_flag:\$export_symbols' '$shared_flag
+        hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath"
+        archive_expsym_cmds='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then func_echo_all "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag"
       else
-	if test ia64 = "$host_cpu"; then
-	  hardcode_libdir_flag_spec='$wl-R $libdir:/usr/lib:/lib'
+	if test "$host_cpu" = ia64; then
+	  hardcode_libdir_flag_spec='${wl}-R $libdir:/usr/lib:/lib'
 	  allow_undefined_flag="-z nodefs"
-	  archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\$wl$no_entry_flag"' $compiler_flags $wl$allow_undefined_flag '"\$wl$exp_sym_flag:\$export_symbols"
+	  archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols"
 	else
 	 # Determine the default libpath from the value encoded in an
 	 # empty executable.
-	 if test set = "${lt_cv_aix_libpath+set}"; then
+	 if test "${lt_cv_aix_libpath+set}" = set; then
   aix_libpath=$lt_cv_aix_libpath
 else
   if ${lt_cv_aix_libpath_+:} false; then :
@@ -9930,7 +9580,7 @@ fi
 rm -f core conftest.err conftest.$ac_objext \
     conftest$ac_exeext conftest.$ac_ext
   if test -z "$lt_cv_aix_libpath_"; then
-    lt_cv_aix_libpath_=/usr/lib:/lib
+    lt_cv_aix_libpath_="/usr/lib:/lib"
   fi
 
 fi
@@ -9938,33 +9588,21 @@ fi
   aix_libpath=$lt_cv_aix_libpath_
 fi
 
-	 hardcode_libdir_flag_spec='$wl-blibpath:$libdir:'"$aix_libpath"
+	 hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath"
 	  # Warning - without using the other run time loading flags,
 	  # -berok will link without error, but may produce a broken library.
-	  no_undefined_flag=' $wl-bernotok'
-	  allow_undefined_flag=' $wl-berok'
-	  if test yes = "$with_gnu_ld"; then
+	  no_undefined_flag=' ${wl}-bernotok'
+	  allow_undefined_flag=' ${wl}-berok'
+	  if test "$with_gnu_ld" = yes; then
 	    # We only use this code for GNU lds that support --whole-archive.
-	    whole_archive_flag_spec='$wl--whole-archive$convenience $wl--no-whole-archive'
+	    whole_archive_flag_spec='${wl}--whole-archive$convenience ${wl}--no-whole-archive'
 	  else
 	    # Exported symbols can be pulled into shared objects from archives
 	    whole_archive_flag_spec='$convenience'
 	  fi
 	  archive_cmds_need_lc=yes
-	  archive_expsym_cmds='$RM -r $output_objdir/$realname.d~$MKDIR $output_objdir/$realname.d'
-	  # -brtl affects multiple linker settings, -berok does not and is overridden later
-	  compiler_flags_filtered='`func_echo_all "$compiler_flags " | $SED -e "s%-brtl\\([, ]\\)%-berok\\1%g"`'
-	  if test svr4 != "$with_aix_soname"; then
-	    # This is similar to how AIX traditionally builds its shared libraries.
-	    archive_expsym_cmds="$archive_expsym_cmds"'~$CC '$shared_flag_aix' -o $output_objdir/$realname.d/$soname $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$realname.d/$soname'
-	  fi
-	  if test aix != "$with_aix_soname"; then
-	    archive_expsym_cmds="$archive_expsym_cmds"'~$CC '$shared_flag_svr4' -o $output_objdir/$realname.d/$shared_archive_member_spec.o $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$STRIP -e $output_objdir/$realname.d/$shared_archive_member_spec.o~( func_echo_all "#! $soname($shared_archive_member_spec.o)"; if test shr_64 = "$shared_archive_member_spec"; then func_echo_all "# 64"; else func_echo_all "# 32"; fi; cat $export_symbols ) >  [...]
-	  else
-	    # used by -dlpreopen to get the symbols
-	    archive_expsym_cmds="$archive_expsym_cmds"'~$MV  $output_objdir/$realname.d/$soname $output_objdir'
-	  fi
-	  archive_expsym_cmds="$archive_expsym_cmds"'~$RM -r $output_objdir/$realname.d'
+	  # This is similar to how AIX traditionally builds its shared libraries.
+	  archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname'
 	fi
       fi
       ;;
@@ -9973,7 +9611,7 @@ fi
       case $host_cpu in
       powerpc)
             # see comment about AmigaOS4 .so support
-            archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+            archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
             archive_expsym_cmds=''
         ;;
       m68k)
@@ -10003,17 +9641,16 @@ fi
 	# Tell ltmain to make .lib files, not .a files.
 	libext=lib
 	# Tell ltmain to make .dll files, not .so files.
-	shrext_cmds=.dll
+	shrext_cmds=".dll"
 	# FIXME: Setting linknames here is a bad hack.
-	archive_cmds='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~linknames='
-	archive_expsym_cmds='if   test DEF = "`$SED -n     -e '\''s/^[	 ]*//'\''     -e '\''/^\(;.*\)*$/d'\''     -e '\''s/^\(EXPORTS\|LIBRARY\)\([	 ].*\)*$/DEF/p'\''     -e q     $export_symbols`" ; then
-            cp "$export_symbols" "$output_objdir/$soname.def";
-            echo "$tool_output_objdir$soname.def" > "$output_objdir/$soname.exp";
-          else
-            $SED -e '\''s/^/-link -EXPORT:/'\'' < $export_symbols > $output_objdir/$soname.exp;
-          fi~
-          $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~
-          linknames='
+	archive_cmds='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-dll~linknames='
+	archive_expsym_cmds='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then
+	    sed -n -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' -e '1\\\!p' < $export_symbols > $output_objdir/$soname.exp;
+	  else
+	    sed -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' < $export_symbols > $output_objdir/$soname.exp;
+	  fi~
+	  $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~
+	  linknames='
 	# The linker will not automatically build a static lib if we build a DLL.
 	# _LT_TAGVAR(old_archive_from_new_cmds, )='true'
 	enable_shared_with_static_runtimes=yes
@@ -10022,18 +9659,18 @@ fi
 	# Don't use ranlib
 	old_postinstall_cmds='chmod 644 $oldlib'
 	postlink_cmds='lt_outputfile="@OUTPUT@"~
-          lt_tool_outputfile="@TOOL_OUTPUT@"~
-          case $lt_outputfile in
-            *.exe|*.EXE) ;;
-            *)
-              lt_outputfile=$lt_outputfile.exe
-              lt_tool_outputfile=$lt_tool_outputfile.exe
-              ;;
-          esac~
-          if test : != "$MANIFEST_TOOL" && test -f "$lt_outputfile.manifest"; then
-            $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1;
-            $RM "$lt_outputfile.manifest";
-          fi'
+	  lt_tool_outputfile="@TOOL_OUTPUT@"~
+	  case $lt_outputfile in
+	    *.exe|*.EXE) ;;
+	    *)
+	      lt_outputfile="$lt_outputfile.exe"
+	      lt_tool_outputfile="$lt_tool_outputfile.exe"
+	      ;;
+	  esac~
+	  if test "$MANIFEST_TOOL" != ":" && test -f "$lt_outputfile.manifest"; then
+	    $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1;
+	    $RM "$lt_outputfile.manifest";
+	  fi'
 	;;
       *)
 	# Assume MSVC wrapper
@@ -10042,7 +9679,7 @@ fi
 	# Tell ltmain to make .lib files, not .a files.
 	libext=lib
 	# Tell ltmain to make .dll files, not .so files.
-	shrext_cmds=.dll
+	shrext_cmds=".dll"
 	# FIXME: Setting linknames here is a bad hack.
 	archive_cmds='$CC -o $lib $libobjs $compiler_flags `func_echo_all "$deplibs" | $SED '\''s/ -lc$//'\''` -link -dll~linknames='
 	# The linker will automatically build a .lib file if we build a DLL.
@@ -10061,24 +9698,24 @@ fi
   hardcode_direct=no
   hardcode_automatic=yes
   hardcode_shlibpath_var=unsupported
-  if test yes = "$lt_cv_ld_force_load"; then
-    whole_archive_flag_spec='`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience $wl-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`'
+  if test "$lt_cv_ld_force_load" = "yes"; then
+    whole_archive_flag_spec='`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience ${wl}-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`'
 
   else
     whole_archive_flag_spec=''
   fi
   link_all_deplibs=yes
-  allow_undefined_flag=$_lt_dar_allow_undefined
+  allow_undefined_flag="$_lt_dar_allow_undefined"
   case $cc_basename in
-     ifort*|nagfor*) _lt_dar_can_shared=yes ;;
+     ifort*) _lt_dar_can_shared=yes ;;
      *) _lt_dar_can_shared=$GCC ;;
   esac
-  if test yes = "$_lt_dar_can_shared"; then
+  if test "$_lt_dar_can_shared" = "yes"; then
     output_verbose_link_cmd=func_echo_all
-    archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dsymutil"
-    module_cmds="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dsymutil"
-    archive_expsym_cmds="sed 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dar_export_syms$_lt_dsymutil"
-    module_expsym_cmds="sed -e 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dar_export_syms$_lt_dsymutil"
+    archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}"
+    module_cmds="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}"
+    archive_expsym_cmds="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}"
+    module_expsym_cmds="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}"
 
   else
   ld_shlibs=no
@@ -10120,33 +9757,33 @@ fi
       ;;
 
     hpux9*)
-      if test yes = "$GCC"; then
-	archive_cmds='$RM $output_objdir/$soname~$CC -shared $pic_flag $wl+b $wl$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib'
+      if test "$GCC" = yes; then
+	archive_cmds='$RM $output_objdir/$soname~$CC -shared $pic_flag ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
       else
-	archive_cmds='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib'
+	archive_cmds='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
       fi
-      hardcode_libdir_flag_spec='$wl+b $wl$libdir'
+      hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
       hardcode_libdir_separator=:
       hardcode_direct=yes
 
       # hardcode_minus_L: Not really in the search PATH,
       # but as the default location of the library.
       hardcode_minus_L=yes
-      export_dynamic_flag_spec='$wl-E'
+      export_dynamic_flag_spec='${wl}-E'
       ;;
 
     hpux10*)
-      if test yes,no = "$GCC,$with_gnu_ld"; then
-	archive_cmds='$CC -shared $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+      if test "$GCC" = yes && test "$with_gnu_ld" = no; then
+	archive_cmds='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
       else
 	archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'
       fi
-      if test no = "$with_gnu_ld"; then
-	hardcode_libdir_flag_spec='$wl+b $wl$libdir'
+      if test "$with_gnu_ld" = no; then
+	hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
 	hardcode_libdir_separator=:
 	hardcode_direct=yes
 	hardcode_direct_absolute=yes
-	export_dynamic_flag_spec='$wl-E'
+	export_dynamic_flag_spec='${wl}-E'
 	# hardcode_minus_L: Not really in the search PATH,
 	# but as the default location of the library.
 	hardcode_minus_L=yes
@@ -10154,25 +9791,25 @@ fi
       ;;
 
     hpux11*)
-      if test yes,no = "$GCC,$with_gnu_ld"; then
+      if test "$GCC" = yes && test "$with_gnu_ld" = no; then
 	case $host_cpu in
 	hppa*64*)
-	  archive_cmds='$CC -shared $wl+h $wl$soname -o $lib $libobjs $deplibs $compiler_flags'
+	  archive_cmds='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
 	  ;;
 	ia64*)
-	  archive_cmds='$CC -shared $pic_flag $wl+h $wl$soname $wl+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
+	  archive_cmds='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
 	  ;;
 	*)
-	  archive_cmds='$CC -shared $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+	  archive_cmds='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
 	  ;;
 	esac
       else
 	case $host_cpu in
 	hppa*64*)
-	  archive_cmds='$CC -b $wl+h $wl$soname -o $lib $libobjs $deplibs $compiler_flags'
+	  archive_cmds='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
 	  ;;
 	ia64*)
-	  archive_cmds='$CC -b $wl+h $wl$soname $wl+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
+	  archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
 	  ;;
 	*)
 
@@ -10184,7 +9821,7 @@ if ${lt_cv_prog_compiler__b+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   lt_cv_prog_compiler__b=no
-   save_LDFLAGS=$LDFLAGS
+   save_LDFLAGS="$LDFLAGS"
    LDFLAGS="$LDFLAGS -b"
    echo "$lt_simple_link_test_code" > conftest.$ac_ext
    if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then
@@ -10203,14 +9840,14 @@ else
      fi
    fi
    $RM -r conftest*
-   LDFLAGS=$save_LDFLAGS
+   LDFLAGS="$save_LDFLAGS"
 
 fi
 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler__b" >&5
 $as_echo "$lt_cv_prog_compiler__b" >&6; }
 
-if test yes = "$lt_cv_prog_compiler__b"; then
-    archive_cmds='$CC -b $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+if test x"$lt_cv_prog_compiler__b" = xyes; then
+    archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
 else
     archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'
 fi
@@ -10218,8 +9855,8 @@ fi
 	  ;;
 	esac
       fi
-      if test no = "$with_gnu_ld"; then
-	hardcode_libdir_flag_spec='$wl+b $wl$libdir'
+      if test "$with_gnu_ld" = no; then
+	hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
 	hardcode_libdir_separator=:
 
 	case $host_cpu in
@@ -10230,7 +9867,7 @@ fi
 	*)
 	  hardcode_direct=yes
 	  hardcode_direct_absolute=yes
-	  export_dynamic_flag_spec='$wl-E'
+	  export_dynamic_flag_spec='${wl}-E'
 
 	  # hardcode_minus_L: Not really in the search PATH,
 	  # but as the default location of the library.
@@ -10241,8 +9878,8 @@ fi
       ;;
 
     irix5* | irix6* | nonstopux*)
-      if test yes = "$GCC"; then
-	archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib'
+      if test "$GCC" = yes; then
+	archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
 	# Try to use the -exported_symbol ld option, if it does not
 	# work, assume that -exports_file does not work either and
 	# implicitly export all symbols.
@@ -10252,8 +9889,8 @@ $as_echo_n "checking whether the $host_os linker accepts -exported_symbol... " >
 if ${lt_cv_irix_exported_symbol+:} false; then :
   $as_echo_n "(cached) " >&6
 else
-  save_LDFLAGS=$LDFLAGS
-	   LDFLAGS="$LDFLAGS -shared $wl-exported_symbol ${wl}foo $wl-update_registry $wl/dev/null"
+  save_LDFLAGS="$LDFLAGS"
+	   LDFLAGS="$LDFLAGS -shared ${wl}-exported_symbol ${wl}foo ${wl}-update_registry ${wl}/dev/null"
 	   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
 int foo (void) { return 0; }
@@ -10265,35 +9902,24 @@ else
 fi
 rm -f core conftest.err conftest.$ac_objext \
     conftest$ac_exeext conftest.$ac_ext
-           LDFLAGS=$save_LDFLAGS
+           LDFLAGS="$save_LDFLAGS"
 fi
 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_irix_exported_symbol" >&5
 $as_echo "$lt_cv_irix_exported_symbol" >&6; }
-	if test yes = "$lt_cv_irix_exported_symbol"; then
-          archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations $wl-exports_file $wl$export_symbols -o $lib'
+	if test "$lt_cv_irix_exported_symbol" = yes; then
+          archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations ${wl}-exports_file ${wl}$export_symbols -o $lib'
 	fi
-	link_all_deplibs=no
       else
-	archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib'
-	archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -exports_file $export_symbols -o $lib'
+	archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib'
+	archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -exports_file $export_symbols -o $lib'
       fi
       archive_cmds_need_lc='no'
-      hardcode_libdir_flag_spec='$wl-rpath $wl$libdir'
+      hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
       hardcode_libdir_separator=:
       inherit_rpath=yes
       link_all_deplibs=yes
       ;;
 
-    linux*)
-      case $cc_basename in
-      tcc*)
-	# Fabrice Bellard et al's Tiny C Compiler
-	ld_shlibs=yes
-	archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
-	;;
-      esac
-      ;;
-
     netbsd* | netbsdelf*-gnu)
       if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
 	archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'  # a.out
@@ -10308,7 +9934,7 @@ $as_echo "$lt_cv_irix_exported_symbol" >&6; }
     newsos6)
       archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
       hardcode_direct=yes
-      hardcode_libdir_flag_spec='$wl-rpath $wl$libdir'
+      hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
       hardcode_libdir_separator=:
       hardcode_shlibpath_var=no
       ;;
@@ -10316,19 +9942,27 @@ $as_echo "$lt_cv_irix_exported_symbol" >&6; }
     *nto* | *qnx*)
       ;;
 
-    openbsd* | bitrig*)
+    openbsd*)
       if test -f /usr/libexec/ld.so; then
 	hardcode_direct=yes
 	hardcode_shlibpath_var=no
 	hardcode_direct_absolute=yes
-	if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then
+	if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
 	  archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
-	  archive_expsym_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags $wl-retain-symbols-file,$export_symbols'
-	  hardcode_libdir_flag_spec='$wl-rpath,$libdir'
-	  export_dynamic_flag_spec='$wl-E'
+	  archive_expsym_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols'
+	  hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
+	  export_dynamic_flag_spec='${wl}-E'
 	else
-	  archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
-	  hardcode_libdir_flag_spec='$wl-rpath,$libdir'
+	  case $host_os in
+	   openbsd[01].* | openbsd2.[0-7] | openbsd2.[0-7].*)
+	     archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+	     hardcode_libdir_flag_spec='-R$libdir'
+	     ;;
+	   *)
+	     archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+	     hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
+	     ;;
+	  esac
 	fi
       else
 	ld_shlibs=no
@@ -10339,53 +9973,33 @@ $as_echo "$lt_cv_irix_exported_symbol" >&6; }
       hardcode_libdir_flag_spec='-L$libdir'
       hardcode_minus_L=yes
       allow_undefined_flag=unsupported
-      shrext_cmds=.dll
-      archive_cmds='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~
-	$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~
-	$ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~
-	$ECHO EXPORTS >> $output_objdir/$libname.def~
-	emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~
-	$CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~
-	emximp -o $lib $output_objdir/$libname.def'
-      archive_expsym_cmds='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~
-	$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~
-	$ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~
-	$ECHO EXPORTS >> $output_objdir/$libname.def~
-	prefix_cmds="$SED"~
-	if test EXPORTS = "`$SED 1q $export_symbols`"; then
-	  prefix_cmds="$prefix_cmds -e 1d";
-	fi~
-	prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~
-	cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~
-	$CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~
-	emximp -o $lib $output_objdir/$libname.def'
-      old_archive_From_new_cmds='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def'
-      enable_shared_with_static_runtimes=yes
+      archive_cmds='$ECHO "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~echo DATA >> $output_objdir/$libname.def~echo " SINGLE NONSHARED" >> $output_objdir/$libname.def~echo EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def'
+      old_archive_from_new_cmds='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def'
       ;;
 
     osf3*)
-      if test yes = "$GCC"; then
-	allow_undefined_flag=' $wl-expect_unresolved $wl\*'
-	archive_cmds='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib'
+      if test "$GCC" = yes; then
+	allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*'
+	archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
       else
 	allow_undefined_flag=' -expect_unresolved \*'
-	archive_cmds='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib'
+	archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib'
       fi
       archive_cmds_need_lc='no'
-      hardcode_libdir_flag_spec='$wl-rpath $wl$libdir'
+      hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
       hardcode_libdir_separator=:
       ;;
 
     osf4* | osf5*)	# as osf3* with the addition of -msym flag
-      if test yes = "$GCC"; then
-	allow_undefined_flag=' $wl-expect_unresolved $wl\*'
-	archive_cmds='$CC -shared$allow_undefined_flag $pic_flag $libobjs $deplibs $compiler_flags $wl-msym $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib'
-	hardcode_libdir_flag_spec='$wl-rpath $wl$libdir'
+      if test "$GCC" = yes; then
+	allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*'
+	archive_cmds='$CC -shared${allow_undefined_flag} $pic_flag $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+	hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
       else
 	allow_undefined_flag=' -expect_unresolved \*'
-	archive_cmds='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib'
+	archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib'
 	archive_expsym_cmds='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~
-          $CC -shared$allow_undefined_flag $wl-input $wl$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib~$RM $lib.exp'
+	$CC -shared${allow_undefined_flag} ${wl}-input ${wl}$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib~$RM $lib.exp'
 
 	# Both c and cxx compiler support -rpath directly
 	hardcode_libdir_flag_spec='-rpath $libdir'
@@ -10396,24 +10010,24 @@ $as_echo "$lt_cv_irix_exported_symbol" >&6; }
 
     solaris*)
       no_undefined_flag=' -z defs'
-      if test yes = "$GCC"; then
-	wlarc='$wl'
-	archive_cmds='$CC -shared $pic_flag $wl-z ${wl}text $wl-h $wl$soname -o $lib $libobjs $deplibs $compiler_flags'
+      if test "$GCC" = yes; then
+	wlarc='${wl}'
+	archive_cmds='$CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
 	archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
-          $CC -shared $pic_flag $wl-z ${wl}text $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp'
+	  $CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp'
       else
 	case `$CC -V 2>&1` in
 	*"Compilers 5.0"*)
 	  wlarc=''
-	  archive_cmds='$LD -G$allow_undefined_flag -h $soname -o $lib $libobjs $deplibs $linker_flags'
+	  archive_cmds='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags'
 	  archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
-            $LD -G$allow_undefined_flag -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp'
+	  $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp'
 	  ;;
 	*)
-	  wlarc='$wl'
-	  archive_cmds='$CC -G$allow_undefined_flag -h $soname -o $lib $libobjs $deplibs $compiler_flags'
+	  wlarc='${wl}'
+	  archive_cmds='$CC -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $compiler_flags'
 	  archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
-            $CC -G$allow_undefined_flag -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp'
+	  $CC -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp'
 	  ;;
 	esac
       fi
@@ -10423,11 +10037,11 @@ $as_echo "$lt_cv_irix_exported_symbol" >&6; }
       solaris2.[0-5] | solaris2.[0-5].*) ;;
       *)
 	# The compiler driver will combine and reorder linker options,
-	# but understands '-z linker_flag'.  GCC discards it without '$wl',
+	# but understands `-z linker_flag'.  GCC discards it without `$wl',
 	# but is careful enough not to reorder.
 	# Supported since Solaris 2.6 (maybe 2.5.1?)
-	if test yes = "$GCC"; then
-	  whole_archive_flag_spec='$wl-z ${wl}allextract$convenience $wl-z ${wl}defaultextract'
+	if test "$GCC" = yes; then
+	  whole_archive_flag_spec='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract'
 	else
 	  whole_archive_flag_spec='-z allextract$convenience -z defaultextract'
 	fi
@@ -10437,10 +10051,10 @@ $as_echo "$lt_cv_irix_exported_symbol" >&6; }
       ;;
 
     sunos4*)
-      if test sequent = "$host_vendor"; then
+      if test "x$host_vendor" = xsequent; then
 	# Use $CC to link under sequent, because it throws in some extra .o
 	# files that make .init and .fini sections work.
-	archive_cmds='$CC -G $wl-h $soname -o $lib $libobjs $deplibs $compiler_flags'
+	archive_cmds='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags'
       else
 	archive_cmds='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags'
       fi
@@ -10489,43 +10103,43 @@ $as_echo "$lt_cv_irix_exported_symbol" >&6; }
       ;;
 
     sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*)
-      no_undefined_flag='$wl-z,text'
+      no_undefined_flag='${wl}-z,text'
       archive_cmds_need_lc=no
       hardcode_shlibpath_var=no
       runpath_var='LD_RUN_PATH'
 
-      if test yes = "$GCC"; then
-	archive_cmds='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
-	archive_expsym_cmds='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+      if test "$GCC" = yes; then
+	archive_cmds='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	archive_expsym_cmds='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
       else
-	archive_cmds='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
-	archive_expsym_cmds='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	archive_cmds='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	archive_expsym_cmds='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
       fi
       ;;
 
     sysv5* | sco3.2v5* | sco5v6*)
-      # Note: We CANNOT use -z defs as we might desire, because we do not
+      # Note: We can NOT use -z defs as we might desire, because we do not
       # link with -lc, and that would cause any symbols used from libc to
       # always be unresolved, which means just about no library would
       # ever link correctly.  If we're not using GNU ld we use -z text
       # though, which does catch some bad symbols but isn't as heavy-handed
       # as -z defs.
-      no_undefined_flag='$wl-z,text'
-      allow_undefined_flag='$wl-z,nodefs'
+      no_undefined_flag='${wl}-z,text'
+      allow_undefined_flag='${wl}-z,nodefs'
       archive_cmds_need_lc=no
       hardcode_shlibpath_var=no
-      hardcode_libdir_flag_spec='$wl-R,$libdir'
+      hardcode_libdir_flag_spec='${wl}-R,$libdir'
       hardcode_libdir_separator=':'
       link_all_deplibs=yes
-      export_dynamic_flag_spec='$wl-Bexport'
+      export_dynamic_flag_spec='${wl}-Bexport'
       runpath_var='LD_RUN_PATH'
 
-      if test yes = "$GCC"; then
-	archive_cmds='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
-	archive_expsym_cmds='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+      if test "$GCC" = yes; then
+	archive_cmds='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	archive_expsym_cmds='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
       else
-	archive_cmds='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
-	archive_expsym_cmds='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	archive_cmds='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	archive_expsym_cmds='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
       fi
       ;;
 
@@ -10540,10 +10154,10 @@ $as_echo "$lt_cv_irix_exported_symbol" >&6; }
       ;;
     esac
 
-    if test sni = "$host_vendor"; then
+    if test x$host_vendor = xsni; then
       case $host in
       sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*)
-	export_dynamic_flag_spec='$wl-Blargedynsym'
+	export_dynamic_flag_spec='${wl}-Blargedynsym'
 	;;
       esac
     fi
@@ -10551,7 +10165,7 @@ $as_echo "$lt_cv_irix_exported_symbol" >&6; }
 
 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs" >&5
 $as_echo "$ld_shlibs" >&6; }
-test no = "$ld_shlibs" && can_build_shared=no
+test "$ld_shlibs" = no && can_build_shared=no
 
 with_gnu_ld=$with_gnu_ld
 
@@ -10577,7 +10191,7 @@ x|xyes)
   # Assume -lc should be added
   archive_cmds_need_lc=yes
 
-  if test yes,yes = "$GCC,$enable_shared"; then
+  if test "$enable_shared" = yes && test "$GCC" = yes; then
     case $archive_cmds in
     *'~'*)
       # FIXME: we may have to deal with multi-command sequences.
@@ -10792,14 +10406,14 @@ esac
   { $as_echo "$as_me:${as_lineno-$LINENO}: checking dynamic linker characteristics" >&5
 $as_echo_n "checking dynamic linker characteristics... " >&6; }
 
-if test yes = "$GCC"; then
+if test "$GCC" = yes; then
   case $host_os in
-    darwin*) lt_awk_arg='/^libraries:/,/LR/' ;;
-    *) lt_awk_arg='/^libraries:/' ;;
+    darwin*) lt_awk_arg="/^libraries:/,/LR/" ;;
+    *) lt_awk_arg="/^libraries:/" ;;
   esac
   case $host_os in
-    mingw* | cegcc*) lt_sed_strip_eq='s|=\([A-Za-z]:\)|\1|g' ;;
-    *) lt_sed_strip_eq='s|=/|/|g' ;;
+    mingw* | cegcc*) lt_sed_strip_eq="s,=\([A-Za-z]:\),\1,g" ;;
+    *) lt_sed_strip_eq="s,=/,/,g" ;;
   esac
   lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e $lt_sed_strip_eq`
   case $lt_search_path_spec in
@@ -10815,35 +10429,28 @@ if test yes = "$GCC"; then
     ;;
   esac
   # Ok, now we have the path, separated by spaces, we can step through it
-  # and add multilib dir if necessary...
+  # and add multilib dir if necessary.
   lt_tmp_lt_search_path_spec=
-  lt_multi_os_dir=/`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null`
-  # ...but if some path component already ends with the multilib dir we assume
-  # that all is fine and trust -print-search-dirs as is (GCC 4.2? or newer).
-  case "$lt_multi_os_dir; $lt_search_path_spec " in
-  "/; "* | "/.; "* | "/./; "* | *"$lt_multi_os_dir "* | *"$lt_multi_os_dir/ "*)
-    lt_multi_os_dir=
-    ;;
-  esac
+  lt_multi_os_dir=`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null`
   for lt_sys_path in $lt_search_path_spec; do
-    if test -d "$lt_sys_path$lt_multi_os_dir"; then
-      lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path$lt_multi_os_dir"
-    elif test -n "$lt_multi_os_dir"; then
+    if test -d "$lt_sys_path/$lt_multi_os_dir"; then
+      lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path/$lt_multi_os_dir"
+    else
       test -d "$lt_sys_path" && \
 	lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path"
     fi
   done
   lt_search_path_spec=`$ECHO "$lt_tmp_lt_search_path_spec" | awk '
-BEGIN {RS = " "; FS = "/|\n";} {
-  lt_foo = "";
-  lt_count = 0;
+BEGIN {RS=" "; FS="/|\n";} {
+  lt_foo="";
+  lt_count=0;
   for (lt_i = NF; lt_i > 0; lt_i--) {
     if ($lt_i != "" && $lt_i != ".") {
       if ($lt_i == "..") {
         lt_count++;
       } else {
         if (lt_count == 0) {
-          lt_foo = "/" $lt_i lt_foo;
+          lt_foo="/" $lt_i lt_foo;
         } else {
           lt_count--;
         }
@@ -10857,7 +10464,7 @@ BEGIN {RS = " "; FS = "/|\n";} {
   # for these hosts.
   case $host_os in
     mingw* | cegcc*) lt_search_path_spec=`$ECHO "$lt_search_path_spec" |\
-      $SED 's|/\([A-Za-z]:\)|\1|g'` ;;
+      $SED 's,/\([A-Za-z]:\),\1,g'` ;;
   esac
   sys_lib_search_path_spec=`$ECHO "$lt_search_path_spec" | $lt_NL2SP`
 else
@@ -10866,7 +10473,7 @@ fi
 library_names_spec=
 libname_spec='lib$name'
 soname_spec=
-shrext_cmds=.so
+shrext_cmds=".so"
 postinstall_cmds=
 postuninstall_cmds=
 finish_cmds=
@@ -10883,16 +10490,14 @@ hardcode_into_libs=no
 # flags to be left without arguments
 need_version=unknown
 
-
-
 case $host_os in
 aix3*)
   version_type=linux # correct to gnu/linux during the next big refactor
-  library_names_spec='$libname$release$shared_ext$versuffix $libname.a'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a'
   shlibpath_var=LIBPATH
 
   # AIX 3 has no versioning support, so we append a major version to the name.
-  soname_spec='$libname$release$shared_ext$major'
+  soname_spec='${libname}${release}${shared_ext}$major'
   ;;
 
 aix[4-9]*)
@@ -10900,91 +10505,41 @@ aix[4-9]*)
   need_lib_prefix=no
   need_version=no
   hardcode_into_libs=yes
-  if test ia64 = "$host_cpu"; then
+  if test "$host_cpu" = ia64; then
     # AIX 5 supports IA64
-    library_names_spec='$libname$release$shared_ext$major $libname$release$shared_ext$versuffix $libname$shared_ext'
+    library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}'
     shlibpath_var=LD_LIBRARY_PATH
   else
     # With GCC up to 2.95.x, collect2 would create an import file
     # for dependence libraries.  The import file would start with
-    # the line '#! .'.  This would cause the generated library to
-    # depend on '.', always an invalid library.  This was fixed in
+    # the line `#! .'.  This would cause the generated library to
+    # depend on `.', always an invalid library.  This was fixed in
     # development snapshots of GCC prior to 3.0.
     case $host_os in
       aix4 | aix4.[01] | aix4.[01].*)
       if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)'
 	   echo ' yes '
-	   echo '#endif'; } | $CC -E - | $GREP yes > /dev/null; then
+	   echo '#endif'; } | ${CC} -E - | $GREP yes > /dev/null; then
 	:
       else
 	can_build_shared=no
       fi
       ;;
     esac
-    # Using Import Files as archive members, it is possible to support
-    # filename-based versioning of shared library archives on AIX. While
-    # this would work for both with and without runtime linking, it will
-    # prevent static linking of such archives. So we do filename-based
-    # shared library versioning with .so extension only, which is used
-    # when both runtime linking and shared linking is enabled.
-    # Unfortunately, runtime linking may impact performance, so we do
-    # not want this to be the default eventually. Also, we use the
-    # versioned .so libs for executables only if there is the -brtl
-    # linker flag in LDFLAGS as well, or --with-aix-soname=svr4 only.
-    # To allow for filename-based versioning support, we need to create
-    # libNAME.so.V as an archive file, containing:
-    # *) an Import File, referring to the versioned filename of the
-    #    archive as well as the shared archive member, telling the
-    #    bitwidth (32 or 64) of that shared object, and providing the
-    #    list of exported symbols of that shared object, eventually
-    #    decorated with the 'weak' keyword
-    # *) the shared object with the F_LOADONLY flag set, to really avoid
-    #    it being seen by the linker.
-    # At run time we better use the real file rather than another symlink,
-    # but for link time we create the symlink libNAME.so -> libNAME.so.V
-
-    case $with_aix_soname,$aix_use_runtimelinking in
-    # AIX (on Power*) has no versioning support, so currently we cannot hardcode correct
+    # AIX (on Power*) has no versioning support, so currently we can not hardcode correct
     # soname into executable. Probably we can add versioning support to
     # collect2, so additional links can be useful in future.
-    aix,yes) # traditional libtool
-      dynamic_linker='AIX unversionable lib.so'
+    if test "$aix_use_runtimelinking" = yes; then
       # If using run time linking (on AIX 4.2 or later) use lib<name>.so
       # instead of lib<name>.a to let people know that these are not
       # typical AIX shared libraries.
-      library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
-      ;;
-    aix,no) # traditional AIX only
-      dynamic_linker='AIX lib.a(lib.so.V)'
+      library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+    else
       # We preserve .a as extension for shared libraries through AIX4.2
       # and later when we are not doing run time linking.
-      library_names_spec='$libname$release.a $libname.a'
-      soname_spec='$libname$release$shared_ext$major'
-      ;;
-    svr4,*) # full svr4 only
-      dynamic_linker="AIX lib.so.V($shared_archive_member_spec.o)"
-      library_names_spec='$libname$release$shared_ext$major $libname$shared_ext'
-      # We do not specify a path in Import Files, so LIBPATH fires.
-      shlibpath_overrides_runpath=yes
-      ;;
-    *,yes) # both, prefer svr4
-      dynamic_linker="AIX lib.so.V($shared_archive_member_spec.o), lib.a(lib.so.V)"
-      library_names_spec='$libname$release$shared_ext$major $libname$shared_ext'
-      # unpreferred sharedlib libNAME.a needs extra handling
-      postinstall_cmds='test -n "$linkname" || linkname="$realname"~func_stripname "" ".so" "$linkname"~$install_shared_prog "$dir/$func_stripname_result.$libext" "$destdir/$func_stripname_result.$libext"~test -z "$tstripme" || test -z "$striplib" || $striplib "$destdir/$func_stripname_result.$libext"'
-      postuninstall_cmds='for n in $library_names $old_library; do :; done~func_stripname "" ".so" "$n"~test "$func_stripname_result" = "$n" || func_append rmfiles " $odir/$func_stripname_result.$libext"'
-      # We do not specify a path in Import Files, so LIBPATH fires.
-      shlibpath_overrides_runpath=yes
-      ;;
-    *,no) # both, prefer aix
-      dynamic_linker="AIX lib.a(lib.so.V), lib.so.V($shared_archive_member_spec.o)"
-      library_names_spec='$libname$release.a $libname.a'
-      soname_spec='$libname$release$shared_ext$major'
-      # unpreferred sharedlib libNAME.so.V and symlink libNAME.so need extra handling
-      postinstall_cmds='test -z "$dlname" || $install_shared_prog $dir/$dlname $destdir/$dlname~test -z "$tstripme" || test -z "$striplib" || $striplib $destdir/$dlname~test -n "$linkname" || linkname=$realname~func_stripname "" ".a" "$linkname"~(cd "$destdir" && $LN_S -f $dlname $func_stripname_result.so)'
-      postuninstall_cmds='test -z "$dlname" || func_append rmfiles " $odir/$dlname"~for n in $old_library $library_names; do :; done~func_stripname "" ".a" "$n"~func_append rmfiles " $odir/$func_stripname_result.so"'
-      ;;
-    esac
+      library_names_spec='${libname}${release}.a $libname.a'
+      soname_spec='${libname}${release}${shared_ext}$major'
+    fi
     shlibpath_var=LIBPATH
   fi
   ;;
@@ -10994,18 +10549,18 @@ amigaos*)
   powerpc)
     # Since July 2007 AmigaOS4 officially supports .so libraries.
     # When compiling the executable, add -use-dynld -Lsobjs: to the compileline.
-    library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
     ;;
   m68k)
     library_names_spec='$libname.ixlibrary $libname.a'
     # Create ${libname}_ixlibrary.a entries in /sys/libs.
-    finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done'
+    finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done'
     ;;
   esac
   ;;
 
 beos*)
-  library_names_spec='$libname$shared_ext'
+  library_names_spec='${libname}${shared_ext}'
   dynamic_linker="$host_os ld.so"
   shlibpath_var=LIBRARY_PATH
   ;;
@@ -11013,8 +10568,8 @@ beos*)
 bsdi[45]*)
   version_type=linux # correct to gnu/linux during the next big refactor
   need_version=no
-  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
-  soname_spec='$libname$release$shared_ext$major'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
   finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir'
   shlibpath_var=LD_LIBRARY_PATH
   sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib"
@@ -11026,7 +10581,7 @@ bsdi[45]*)
 
 cygwin* | mingw* | pw32* | cegcc*)
   version_type=windows
-  shrext_cmds=.dll
+  shrext_cmds=".dll"
   need_version=no
   need_lib_prefix=no
 
@@ -11035,8 +10590,8 @@ cygwin* | mingw* | pw32* | cegcc*)
     # gcc
     library_names_spec='$libname.dll.a'
     # DLL is installed to $(libdir)/../bin by postinstall_cmds
-    postinstall_cmds='base_file=`basename \$file`~
-      dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~
+    postinstall_cmds='base_file=`basename \${file}`~
+      dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~
       dldir=$destdir/`dirname \$dlpath`~
       test -d \$dldir || mkdir -p \$dldir~
       $install_prog $dir/$dlname \$dldir/$dlname~
@@ -11052,17 +10607,17 @@ cygwin* | mingw* | pw32* | cegcc*)
     case $host_os in
     cygwin*)
       # Cygwin DLLs use 'cyg' prefix rather than 'lib'
-      soname_spec='`echo $libname | sed -e 's/^lib/cyg/'``echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext'
+      soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
 
       sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/lib/w32api"
       ;;
     mingw* | cegcc*)
       # MinGW DLLs use traditional 'lib' prefix
-      soname_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext'
+      soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
       ;;
     pw32*)
       # pw32 DLLs use 'pw' prefix rather than 'lib'
-      library_names_spec='`echo $libname | sed -e 's/^lib/pw/'``echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext'
+      library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
       ;;
     esac
     dynamic_linker='Win32 ld.exe'
@@ -11071,8 +10626,8 @@ cygwin* | mingw* | pw32* | cegcc*)
   *,cl*)
     # Native MSVC
     libname_spec='$name'
-    soname_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext'
-    library_names_spec='$libname.dll.lib'
+    soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
+    library_names_spec='${libname}.dll.lib'
 
     case $build_os in
     mingw*)
@@ -11099,7 +10654,7 @@ cygwin* | mingw* | pw32* | cegcc*)
       sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"`
       ;;
     *)
-      sys_lib_search_path_spec=$LIB
+      sys_lib_search_path_spec="$LIB"
       if $ECHO "$sys_lib_search_path_spec" | $GREP ';[c-zC-Z]:/' >/dev/null; then
         # It is most probably a Windows format PATH.
         sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'`
@@ -11112,8 +10667,8 @@ cygwin* | mingw* | pw32* | cegcc*)
     esac
 
     # DLL is installed to $(libdir)/../bin by postinstall_cmds
-    postinstall_cmds='base_file=`basename \$file`~
-      dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~
+    postinstall_cmds='base_file=`basename \${file}`~
+      dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~
       dldir=$destdir/`dirname \$dlpath`~
       test -d \$dldir || mkdir -p \$dldir~
       $install_prog $dir/$dlname \$dldir/$dlname'
@@ -11126,7 +10681,7 @@ cygwin* | mingw* | pw32* | cegcc*)
 
   *)
     # Assume MSVC wrapper
-    library_names_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext $libname.lib'
+    library_names_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext} $libname.lib'
     dynamic_linker='Win32 ld.exe'
     ;;
   esac
@@ -11139,8 +10694,8 @@ darwin* | rhapsody*)
   version_type=darwin
   need_lib_prefix=no
   need_version=no
-  library_names_spec='$libname$release$major$shared_ext $libname$shared_ext'
-  soname_spec='$libname$release$major$shared_ext'
+  library_names_spec='${libname}${release}${major}$shared_ext ${libname}$shared_ext'
+  soname_spec='${libname}${release}${major}$shared_ext'
   shlibpath_overrides_runpath=yes
   shlibpath_var=DYLD_LIBRARY_PATH
   shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`'
@@ -11153,8 +10708,8 @@ dgux*)
   version_type=linux # correct to gnu/linux during the next big refactor
   need_lib_prefix=no
   need_version=no
-  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
-  soname_spec='$libname$release$shared_ext$major'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext'
+  soname_spec='${libname}${release}${shared_ext}$major'
   shlibpath_var=LD_LIBRARY_PATH
   ;;
 
@@ -11172,13 +10727,12 @@ freebsd* | dragonfly*)
   version_type=freebsd-$objformat
   case $version_type in
     freebsd-elf*)
-      library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
-      soname_spec='$libname$release$shared_ext$major'
+      library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}'
       need_version=no
       need_lib_prefix=no
       ;;
     freebsd-*)
-      library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix'
+      library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix'
       need_version=yes
       ;;
   esac
@@ -11208,10 +10762,10 @@ haiku*)
   need_lib_prefix=no
   need_version=no
   dynamic_linker="$host_os runtime_loader"
-  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
-  soname_spec='$libname$release$shared_ext$major'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
   shlibpath_var=LIBRARY_PATH
-  shlibpath_overrides_runpath=no
+  shlibpath_overrides_runpath=yes
   sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib'
   hardcode_into_libs=yes
   ;;
@@ -11229,15 +10783,14 @@ hpux9* | hpux10* | hpux11*)
     dynamic_linker="$host_os dld.so"
     shlibpath_var=LD_LIBRARY_PATH
     shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
-    library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
-    soname_spec='$libname$release$shared_ext$major'
-    if test 32 = "$HPUX_IA64_MODE"; then
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+    soname_spec='${libname}${release}${shared_ext}$major'
+    if test "X$HPUX_IA64_MODE" = X32; then
       sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib"
-      sys_lib_dlsearch_path_spec=/usr/lib/hpux32
     else
       sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64"
-      sys_lib_dlsearch_path_spec=/usr/lib/hpux64
     fi
+    sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
     ;;
   hppa*64*)
     shrext_cmds='.sl'
@@ -11245,8 +10798,8 @@ hpux9* | hpux10* | hpux11*)
     dynamic_linker="$host_os dld.sl"
     shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH
     shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
-    library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
-    soname_spec='$libname$release$shared_ext$major'
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+    soname_spec='${libname}${release}${shared_ext}$major'
     sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64"
     sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
     ;;
@@ -11255,8 +10808,8 @@ hpux9* | hpux10* | hpux11*)
     dynamic_linker="$host_os dld.sl"
     shlibpath_var=SHLIB_PATH
     shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH
-    library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
-    soname_spec='$libname$release$shared_ext$major'
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+    soname_spec='${libname}${release}${shared_ext}$major'
     ;;
   esac
   # HP-UX runs *really* slowly unless shared libraries are mode 555, ...
@@ -11269,8 +10822,8 @@ interix[3-9]*)
   version_type=linux # correct to gnu/linux during the next big refactor
   need_lib_prefix=no
   need_version=no
-  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
-  soname_spec='$libname$release$shared_ext$major'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
   dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)'
   shlibpath_var=LD_LIBRARY_PATH
   shlibpath_overrides_runpath=no
@@ -11281,7 +10834,7 @@ irix5* | irix6* | nonstopux*)
   case $host_os in
     nonstopux*) version_type=nonstopux ;;
     *)
-	if test yes = "$lt_cv_prog_gnu_ld"; then
+	if test "$lt_cv_prog_gnu_ld" = yes; then
 		version_type=linux # correct to gnu/linux during the next big refactor
 	else
 		version_type=irix
@@ -11289,8 +10842,8 @@ irix5* | irix6* | nonstopux*)
   esac
   need_lib_prefix=no
   need_version=no
-  soname_spec='$libname$release$shared_ext$major'
-  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$release$shared_ext $libname$shared_ext'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}'
   case $host_os in
   irix5* | nonstopux*)
     libsuff= shlibsuff=
@@ -11309,8 +10862,8 @@ irix5* | irix6* | nonstopux*)
   esac
   shlibpath_var=LD_LIBRARY${shlibsuff}_PATH
   shlibpath_overrides_runpath=no
-  sys_lib_search_path_spec="/usr/lib$libsuff /lib$libsuff /usr/local/lib$libsuff"
-  sys_lib_dlsearch_path_spec="/usr/lib$libsuff /lib$libsuff"
+  sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}"
+  sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}"
   hardcode_into_libs=yes
   ;;
 
@@ -11319,33 +10872,13 @@ linux*oldld* | linux*aout* | linux*coff*)
   dynamic_linker=no
   ;;
 
-linux*android*)
-  version_type=none # Android doesn't support versioned libraries.
-  need_lib_prefix=no
-  need_version=no
-  library_names_spec='$libname$release$shared_ext'
-  soname_spec='$libname$release$shared_ext'
-  finish_cmds=
-  shlibpath_var=LD_LIBRARY_PATH
-  shlibpath_overrides_runpath=yes
-
-  # This implies no fast_install, which is unacceptable.
-  # Some rework will be needed to allow for fast_install
-  # before this can be enabled.
-  hardcode_into_libs=yes
-
-  dynamic_linker='Android linker'
-  # Don't embed -rpath directories since the linker doesn't support them.
-  hardcode_libdir_flag_spec='-L$libdir'
-  ;;
-
 # This must be glibc/ELF.
 linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*)
   version_type=linux # correct to gnu/linux during the next big refactor
   need_lib_prefix=no
   need_version=no
-  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
-  soname_spec='$libname$release$shared_ext$major'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
   finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir'
   shlibpath_var=LD_LIBRARY_PATH
   shlibpath_overrides_runpath=no
@@ -11389,12 +10922,7 @@ fi
   # before this can be enabled.
   hardcode_into_libs=yes
 
-  # Ideally, we could use ldconfig to report *all* directores which are
-  # searched for libraries, however this is still not possible.  Aside from not
-  # being certain /sbin/ldconfig is available, command
-  # 'ldconfig -N -X -v | grep ^/' on 64bit Fedora does not report /usr/lib64,
-  # even though it is searched at run-time.  Try to do the best guess by
-  # appending ld.so.conf contents (and includes) to the search path.
+  # Append ld.so.conf contents to the search path
   if test -f /etc/ld.so.conf; then
     lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[	 ]*hwcap[	 ]/d;s/[:,	]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '`
     sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra"
@@ -11426,12 +10954,12 @@ netbsd*)
   need_lib_prefix=no
   need_version=no
   if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
-    library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix'
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
     finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
     dynamic_linker='NetBSD (a.out) ld.so'
   else
-    library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
-    soname_spec='$libname$release$shared_ext$major'
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+    soname_spec='${libname}${release}${shared_ext}$major'
     dynamic_linker='NetBSD ld.elf_so'
   fi
   shlibpath_var=LD_LIBRARY_PATH
@@ -11441,7 +10969,7 @@ netbsd*)
 
 newsos6)
   version_type=linux # correct to gnu/linux during the next big refactor
-  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
   shlibpath_var=LD_LIBRARY_PATH
   shlibpath_overrides_runpath=yes
   ;;
@@ -11450,68 +10978,58 @@ newsos6)
   version_type=qnx
   need_lib_prefix=no
   need_version=no
-  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
-  soname_spec='$libname$release$shared_ext$major'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
   shlibpath_var=LD_LIBRARY_PATH
   shlibpath_overrides_runpath=no
   hardcode_into_libs=yes
   dynamic_linker='ldqnx.so'
   ;;
 
-openbsd* | bitrig*)
+openbsd*)
   version_type=sunos
-  sys_lib_dlsearch_path_spec=/usr/lib
+  sys_lib_dlsearch_path_spec="/usr/lib"
   need_lib_prefix=no
-  if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then
-    need_version=no
-  else
-    need_version=yes
-  fi
-  library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix'
+  # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs.
+  case $host_os in
+    openbsd3.3 | openbsd3.3.*)	need_version=yes ;;
+    *)				need_version=no  ;;
+  esac
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
   finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
   shlibpath_var=LD_LIBRARY_PATH
-  shlibpath_overrides_runpath=yes
+  if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+    case $host_os in
+      openbsd2.[89] | openbsd2.[89].*)
+	shlibpath_overrides_runpath=no
+	;;
+      *)
+	shlibpath_overrides_runpath=yes
+	;;
+      esac
+  else
+    shlibpath_overrides_runpath=yes
+  fi
   ;;
 
 os2*)
   libname_spec='$name'
-  version_type=windows
-  shrext_cmds=.dll
-  need_version=no
+  shrext_cmds=".dll"
   need_lib_prefix=no
-  # OS/2 can only load a DLL with a base name of 8 characters or less.
-  soname_spec='`test -n "$os2dllname" && libname="$os2dllname";
-    v=$($ECHO $release$versuffix | tr -d .-);
-    n=$($ECHO $libname | cut -b -$((8 - ${#v})) | tr . _);
-    $ECHO $n$v`$shared_ext'
-  library_names_spec='${libname}_dll.$libext'
+  library_names_spec='$libname${shared_ext} $libname.a'
   dynamic_linker='OS/2 ld.exe'
-  shlibpath_var=BEGINLIBPATH
-  sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib"
-  sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
-  postinstall_cmds='base_file=`basename \$file`~
-    dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; $ECHO \$dlname'\''`~
-    dldir=$destdir/`dirname \$dlpath`~
-    test -d \$dldir || mkdir -p \$dldir~
-    $install_prog $dir/$dlname \$dldir/$dlname~
-    chmod a+x \$dldir/$dlname~
-    if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then
-      eval '\''$striplib \$dldir/$dlname'\'' || exit \$?;
-    fi'
-  postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; $ECHO \$dlname'\''`~
-    dlpath=$dir/\$dldll~
-    $RM \$dlpath'
+  shlibpath_var=LIBPATH
   ;;
 
 osf3* | osf4* | osf5*)
   version_type=osf
   need_lib_prefix=no
   need_version=no
-  soname_spec='$libname$release$shared_ext$major'
-  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
   shlibpath_var=LD_LIBRARY_PATH
   sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib"
-  sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
+  sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec"
   ;;
 
 rdos*)
@@ -11522,8 +11040,8 @@ solaris*)
   version_type=linux # correct to gnu/linux during the next big refactor
   need_lib_prefix=no
   need_version=no
-  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
-  soname_spec='$libname$release$shared_ext$major'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
   shlibpath_var=LD_LIBRARY_PATH
   shlibpath_overrides_runpath=yes
   hardcode_into_libs=yes
@@ -11533,11 +11051,11 @@ solaris*)
 
 sunos4*)
   version_type=sunos
-  library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
   finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir'
   shlibpath_var=LD_LIBRARY_PATH
   shlibpath_overrides_runpath=yes
-  if test yes = "$with_gnu_ld"; then
+  if test "$with_gnu_ld" = yes; then
     need_lib_prefix=no
   fi
   need_version=yes
@@ -11545,8 +11063,8 @@ sunos4*)
 
 sysv4 | sysv4.3*)
   version_type=linux # correct to gnu/linux during the next big refactor
-  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
-  soname_spec='$libname$release$shared_ext$major'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
   shlibpath_var=LD_LIBRARY_PATH
   case $host_vendor in
     sni)
@@ -11567,24 +11085,24 @@ sysv4 | sysv4.3*)
   ;;
 
 sysv4*MP*)
-  if test -d /usr/nec; then
+  if test -d /usr/nec ;then
     version_type=linux # correct to gnu/linux during the next big refactor
-    library_names_spec='$libname$shared_ext.$versuffix $libname$shared_ext.$major $libname$shared_ext'
-    soname_spec='$libname$shared_ext.$major'
+    library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}'
+    soname_spec='$libname${shared_ext}.$major'
     shlibpath_var=LD_LIBRARY_PATH
   fi
   ;;
 
 sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
-  version_type=sco
+  version_type=freebsd-elf
   need_lib_prefix=no
   need_version=no
-  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext $libname$shared_ext'
-  soname_spec='$libname$release$shared_ext$major'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
   shlibpath_var=LD_LIBRARY_PATH
   shlibpath_overrides_runpath=yes
   hardcode_into_libs=yes
-  if test yes = "$with_gnu_ld"; then
+  if test "$with_gnu_ld" = yes; then
     sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib'
   else
     sys_lib_search_path_spec='/usr/ccs/lib /usr/lib'
@@ -11602,7 +11120,7 @@ tpf*)
   version_type=linux # correct to gnu/linux during the next big refactor
   need_lib_prefix=no
   need_version=no
-  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
   shlibpath_var=LD_LIBRARY_PATH
   shlibpath_overrides_runpath=no
   hardcode_into_libs=yes
@@ -11610,8 +11128,8 @@ tpf*)
 
 uts4*)
   version_type=linux # correct to gnu/linux during the next big refactor
-  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
-  soname_spec='$libname$release$shared_ext$major'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
   shlibpath_var=LD_LIBRARY_PATH
   ;;
 
@@ -11621,35 +11139,20 @@ uts4*)
 esac
 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $dynamic_linker" >&5
 $as_echo "$dynamic_linker" >&6; }
-test no = "$dynamic_linker" && can_build_shared=no
+test "$dynamic_linker" = no && can_build_shared=no
 
 variables_saved_for_relink="PATH $shlibpath_var $runpath_var"
-if test yes = "$GCC"; then
+if test "$GCC" = yes; then
   variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH"
 fi
 
-if test set = "${lt_cv_sys_lib_search_path_spec+set}"; then
-  sys_lib_search_path_spec=$lt_cv_sys_lib_search_path_spec
+if test "${lt_cv_sys_lib_search_path_spec+set}" = set; then
+  sys_lib_search_path_spec="$lt_cv_sys_lib_search_path_spec"
 fi
-
-if test set = "${lt_cv_sys_lib_dlsearch_path_spec+set}"; then
-  sys_lib_dlsearch_path_spec=$lt_cv_sys_lib_dlsearch_path_spec
+if test "${lt_cv_sys_lib_dlsearch_path_spec+set}" = set; then
+  sys_lib_dlsearch_path_spec="$lt_cv_sys_lib_dlsearch_path_spec"
 fi
 
-# remember unaugmented sys_lib_dlsearch_path content for libtool script decls...
-configure_time_dlsearch_path=$sys_lib_dlsearch_path_spec
-
-# ... but it needs LT_SYS_LIBRARY_PATH munging for other configure-time code
-func_munge_path_list sys_lib_dlsearch_path_spec "$LT_SYS_LIBRARY_PATH"
-
-# to be used as default LT_SYS_LIBRARY_PATH value in generated libtool
-configure_time_lt_sys_library_path=$LT_SYS_LIBRARY_PATH
-
-
-
-
-
-
 
 
 
@@ -11746,15 +11249,15 @@ $as_echo_n "checking how to hardcode library paths into programs... " >&6; }
 hardcode_action=
 if test -n "$hardcode_libdir_flag_spec" ||
    test -n "$runpath_var" ||
-   test yes = "$hardcode_automatic"; then
+   test "X$hardcode_automatic" = "Xyes" ; then
 
   # We can hardcode non-existent directories.
-  if test no != "$hardcode_direct" &&
+  if test "$hardcode_direct" != no &&
      # If the only mechanism to avoid hardcoding is shlibpath_var, we
      # have to relink, otherwise we might link with an installed library
      # when we should be linking with a yet-to-be-installed one
-     ## test no != "$_LT_TAGVAR(hardcode_shlibpath_var, )" &&
-     test no != "$hardcode_minus_L"; then
+     ## test "$_LT_TAGVAR(hardcode_shlibpath_var, )" != no &&
+     test "$hardcode_minus_L" != no; then
     # Linking always hardcodes the temporary library directory.
     hardcode_action=relink
   else
@@ -11769,12 +11272,12 @@ fi
 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $hardcode_action" >&5
 $as_echo "$hardcode_action" >&6; }
 
-if test relink = "$hardcode_action" ||
-   test yes = "$inherit_rpath"; then
+if test "$hardcode_action" = relink ||
+   test "$inherit_rpath" = yes; then
   # Fast installation is not supported
   enable_fast_install=no
-elif test yes = "$shlibpath_overrides_runpath" ||
-     test no = "$enable_shared"; then
+elif test "$shlibpath_overrides_runpath" = yes ||
+     test "$enable_shared" = no; then
   # Fast installation is not necessary
   enable_fast_install=needless
 fi
@@ -11784,7 +11287,7 @@ fi
 
 
 
-  if test yes != "$enable_dlopen"; then
+  if test "x$enable_dlopen" != xyes; then
   enable_dlopen=unknown
   enable_dlopen_self=unknown
   enable_dlopen_self_static=unknown
@@ -11794,23 +11297,23 @@ else
 
   case $host_os in
   beos*)
-    lt_cv_dlopen=load_add_on
+    lt_cv_dlopen="load_add_on"
     lt_cv_dlopen_libs=
     lt_cv_dlopen_self=yes
     ;;
 
   mingw* | pw32* | cegcc*)
-    lt_cv_dlopen=LoadLibrary
+    lt_cv_dlopen="LoadLibrary"
     lt_cv_dlopen_libs=
     ;;
 
   cygwin*)
-    lt_cv_dlopen=dlopen
+    lt_cv_dlopen="dlopen"
     lt_cv_dlopen_libs=
     ;;
 
   darwin*)
-    # if libdl is installed we need to link against it
+  # if libdl is installed we need to link against it
     { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5
 $as_echo_n "checking for dlopen in -ldl... " >&6; }
 if ${ac_cv_lib_dl_dlopen+:} false; then :
@@ -11848,10 +11351,10 @@ fi
 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5
 $as_echo "$ac_cv_lib_dl_dlopen" >&6; }
 if test "x$ac_cv_lib_dl_dlopen" = xyes; then :
-  lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-ldl
+  lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"
 else
 
-    lt_cv_dlopen=dyld
+    lt_cv_dlopen="dyld"
     lt_cv_dlopen_libs=
     lt_cv_dlopen_self=yes
 
@@ -11859,18 +11362,10 @@ fi
 
     ;;
 
-  tpf*)
-    # Don't try to run any link tests for TPF.  We know it's impossible
-    # because TPF is a cross-compiler, and we know how we open DSOs.
-    lt_cv_dlopen=dlopen
-    lt_cv_dlopen_libs=
-    lt_cv_dlopen_self=no
-    ;;
-
   *)
     ac_fn_c_check_func "$LINENO" "shl_load" "ac_cv_func_shl_load"
 if test "x$ac_cv_func_shl_load" = xyes; then :
-  lt_cv_dlopen=shl_load
+  lt_cv_dlopen="shl_load"
 else
   { $as_echo "$as_me:${as_lineno-$LINENO}: checking for shl_load in -ldld" >&5
 $as_echo_n "checking for shl_load in -ldld... " >&6; }
@@ -11909,11 +11404,11 @@ fi
 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_shl_load" >&5
 $as_echo "$ac_cv_lib_dld_shl_load" >&6; }
 if test "x$ac_cv_lib_dld_shl_load" = xyes; then :
-  lt_cv_dlopen=shl_load lt_cv_dlopen_libs=-ldld
+  lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-ldld"
 else
   ac_fn_c_check_func "$LINENO" "dlopen" "ac_cv_func_dlopen"
 if test "x$ac_cv_func_dlopen" = xyes; then :
-  lt_cv_dlopen=dlopen
+  lt_cv_dlopen="dlopen"
 else
   { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5
 $as_echo_n "checking for dlopen in -ldl... " >&6; }
@@ -11952,7 +11447,7 @@ fi
 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5
 $as_echo "$ac_cv_lib_dl_dlopen" >&6; }
 if test "x$ac_cv_lib_dl_dlopen" = xyes; then :
-  lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-ldl
+  lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"
 else
   { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -lsvld" >&5
 $as_echo_n "checking for dlopen in -lsvld... " >&6; }
@@ -11991,7 +11486,7 @@ fi
 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_svld_dlopen" >&5
 $as_echo "$ac_cv_lib_svld_dlopen" >&6; }
 if test "x$ac_cv_lib_svld_dlopen" = xyes; then :
-  lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-lsvld
+  lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld"
 else
   { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dld_link in -ldld" >&5
 $as_echo_n "checking for dld_link in -ldld... " >&6; }
@@ -12030,7 +11525,7 @@ fi
 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_dld_link" >&5
 $as_echo "$ac_cv_lib_dld_dld_link" >&6; }
 if test "x$ac_cv_lib_dld_dld_link" = xyes; then :
-  lt_cv_dlopen=dld_link lt_cv_dlopen_libs=-ldld
+  lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-ldld"
 fi
 
 
@@ -12051,21 +11546,21 @@ fi
     ;;
   esac
 
-  if test no = "$lt_cv_dlopen"; then
-    enable_dlopen=no
-  else
+  if test "x$lt_cv_dlopen" != xno; then
     enable_dlopen=yes
+  else
+    enable_dlopen=no
   fi
 
   case $lt_cv_dlopen in
   dlopen)
-    save_CPPFLAGS=$CPPFLAGS
-    test yes = "$ac_cv_header_dlfcn_h" && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H"
+    save_CPPFLAGS="$CPPFLAGS"
+    test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H"
 
-    save_LDFLAGS=$LDFLAGS
+    save_LDFLAGS="$LDFLAGS"
     wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\"
 
-    save_LIBS=$LIBS
+    save_LIBS="$LIBS"
     LIBS="$lt_cv_dlopen_libs $LIBS"
 
     { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether a program can dlopen itself" >&5
@@ -12073,7 +11568,7 @@ $as_echo_n "checking whether a program can dlopen itself... " >&6; }
 if ${lt_cv_dlopen_self+:} false; then :
   $as_echo_n "(cached) " >&6
 else
-  	  if test yes = "$cross_compiling"; then :
+  	  if test "$cross_compiling" = yes; then :
   lt_cv_dlopen_self=cross
 else
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
@@ -12120,9 +11615,9 @@ else
 #  endif
 #endif
 
-/* When -fvisibility=hidden is used, assume the code has been annotated
+/* When -fvisbility=hidden is used, assume the code has been annotated
    correspondingly for the symbols needed.  */
-#if defined __GNUC__ && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3))
+#if defined(__GNUC__) && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3))
 int fnord () __attribute__((visibility("default")));
 #endif
 
@@ -12152,7 +11647,7 @@ _LT_EOF
   (eval $ac_link) 2>&5
   ac_status=$?
   $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
-  test $ac_status = 0; } && test -s "conftest$ac_exeext" 2>/dev/null; then
+  test $ac_status = 0; } && test -s conftest${ac_exeext} 2>/dev/null; then
     (./conftest; exit; ) >&5 2>/dev/null
     lt_status=$?
     case x$lt_status in
@@ -12172,14 +11667,14 @@ fi
 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self" >&5
 $as_echo "$lt_cv_dlopen_self" >&6; }
 
-    if test yes = "$lt_cv_dlopen_self"; then
+    if test "x$lt_cv_dlopen_self" = xyes; then
       wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\"
       { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether a statically linked program can dlopen itself" >&5
 $as_echo_n "checking whether a statically linked program can dlopen itself... " >&6; }
 if ${lt_cv_dlopen_self_static+:} false; then :
   $as_echo_n "(cached) " >&6
 else
-  	  if test yes = "$cross_compiling"; then :
+  	  if test "$cross_compiling" = yes; then :
   lt_cv_dlopen_self_static=cross
 else
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
@@ -12226,9 +11721,9 @@ else
 #  endif
 #endif
 
-/* When -fvisibility=hidden is used, assume the code has been annotated
+/* When -fvisbility=hidden is used, assume the code has been annotated
    correspondingly for the symbols needed.  */
-#if defined __GNUC__ && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3))
+#if defined(__GNUC__) && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3))
 int fnord () __attribute__((visibility("default")));
 #endif
 
@@ -12258,7 +11753,7 @@ _LT_EOF
   (eval $ac_link) 2>&5
   ac_status=$?
   $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
-  test $ac_status = 0; } && test -s "conftest$ac_exeext" 2>/dev/null; then
+  test $ac_status = 0; } && test -s conftest${ac_exeext} 2>/dev/null; then
     (./conftest; exit; ) >&5 2>/dev/null
     lt_status=$?
     case x$lt_status in
@@ -12279,9 +11774,9 @@ fi
 $as_echo "$lt_cv_dlopen_self_static" >&6; }
     fi
 
-    CPPFLAGS=$save_CPPFLAGS
-    LDFLAGS=$save_LDFLAGS
-    LIBS=$save_LIBS
+    CPPFLAGS="$save_CPPFLAGS"
+    LDFLAGS="$save_LDFLAGS"
+    LIBS="$save_LIBS"
     ;;
   esac
 
@@ -12325,7 +11820,7 @@ else
 # FIXME - insert some real tests, host_os isn't really good enough
   case $host_os in
   darwin*)
-    if test -n "$STRIP"; then
+    if test -n "$STRIP" ; then
       striplib="$STRIP -x"
       old_striplib="$STRIP -S"
       { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
@@ -12353,7 +11848,7 @@ fi
 
 
 
-  # Report what library types will actually be built
+  # Report which library types will actually be built
   { $as_echo "$as_me:${as_lineno-$LINENO}: checking if libtool supports shared libraries" >&5
 $as_echo_n "checking if libtool supports shared libraries... " >&6; }
   { $as_echo "$as_me:${as_lineno-$LINENO}: result: $can_build_shared" >&5
@@ -12361,13 +11856,13 @@ $as_echo "$can_build_shared" >&6; }
 
   { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build shared libraries" >&5
 $as_echo_n "checking whether to build shared libraries... " >&6; }
-  test no = "$can_build_shared" && enable_shared=no
+  test "$can_build_shared" = "no" && enable_shared=no
 
   # On AIX, shared libraries and static libraries use the same namespace, and
   # are all built from PIC.
   case $host_os in
   aix3*)
-    test yes = "$enable_shared" && enable_static=no
+    test "$enable_shared" = yes && enable_static=no
     if test -n "$RANLIB"; then
       archive_cmds="$archive_cmds~\$RANLIB \$lib"
       postinstall_cmds='$RANLIB $lib'
@@ -12375,12 +11870,8 @@ $as_echo_n "checking whether to build shared libraries... " >&6; }
     ;;
 
   aix[4-9]*)
-    if test ia64 != "$host_cpu"; then
-      case $enable_shared,$with_aix_soname,$aix_use_runtimelinking in
-      yes,aix,yes) ;;			# shared object as lib.so file only
-      yes,svr4,*) ;;			# shared object as lib.so archive member only
-      yes,*) enable_static=no ;;	# shared object in lib.a archive as well
-      esac
+    if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then
+      test "$enable_shared" = yes && enable_static=no
     fi
     ;;
   esac
@@ -12390,7 +11881,7 @@ $as_echo "$enable_shared" >&6; }
   { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build static libraries" >&5
 $as_echo_n "checking whether to build static libraries... " >&6; }
   # Make sure either enable_shared or enable_static is yes.
-  test yes = "$enable_shared" || enable_static=yes
+  test "$enable_shared" = yes || enable_static=yes
   { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_static" >&5
 $as_echo "$enable_static" >&6; }
 
@@ -12404,11 +11895,11 @@ ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
 ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
 ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
 
-CC=$lt_save_CC
+CC="$lt_save_CC"
 
-      if test -n "$CXX" && ( test no != "$CXX" &&
-    ( (test g++ = "$CXX" && `g++ -v >/dev/null 2>&1` ) ||
-    (test g++ != "$CXX"))); then
+      if test -n "$CXX" && ( test "X$CXX" != "Xno" &&
+    ( (test "X$CXX" = "Xg++" && `g++ -v >/dev/null 2>&1` ) ||
+    (test "X$CXX" != "Xg++"))) ; then
   ac_ext=cpp
 ac_cpp='$CXXCPP $CPPFLAGS'
 ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
@@ -12587,7 +12078,7 @@ objext_CXX=$objext
 # the CXX compiler isn't working.  Some variables (like enable_shared)
 # are currently assumed to apply to all compilers on this platform,
 # and will be corrupted by setting them based on a non-working compiler.
-if test yes != "$_lt_caught_CXX_error"; then
+if test "$_lt_caught_CXX_error" != yes; then
   # Code to be used in simple compile tests
   lt_simple_compile_test_code="int some_variable = 0;"
 
@@ -12648,39 +12139,46 @@ $RM -r conftest*
   CFLAGS=$CXXFLAGS
   compiler=$CC
   compiler_CXX=$CC
-  func_cc_basename $compiler
-cc_basename=$func_cc_basename_result
+  for cc_temp in $compiler""; do
+  case $cc_temp in
+    compile | *[\\/]compile | ccache | *[\\/]ccache ) ;;
+    distcc | *[\\/]distcc | purify | *[\\/]purify ) ;;
+    \-*) ;;
+    *) break;;
+  esac
+done
+cc_basename=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"`
 
 
   if test -n "$compiler"; then
     # We don't want -fno-exception when compiling C++ code, so set the
     # no_builtin_flag separately
-    if test yes = "$GXX"; then
+    if test "$GXX" = yes; then
       lt_prog_compiler_no_builtin_flag_CXX=' -fno-builtin'
     else
       lt_prog_compiler_no_builtin_flag_CXX=
     fi
 
-    if test yes = "$GXX"; then
+    if test "$GXX" = yes; then
       # Set up default GNU C++ configuration
 
 
 
 # Check whether --with-gnu-ld was given.
 if test "${with_gnu_ld+set}" = set; then :
-  withval=$with_gnu_ld; test no = "$withval" || with_gnu_ld=yes
+  withval=$with_gnu_ld; test "$withval" = no || with_gnu_ld=yes
 else
   with_gnu_ld=no
 fi
 
 ac_prog=ld
-if test yes = "$GCC"; then
+if test "$GCC" = yes; then
   # Check if gcc -print-prog-name=ld gives a path.
   { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ld used by $CC" >&5
 $as_echo_n "checking for ld used by $CC... " >&6; }
   case $host in
   *-*-mingw*)
-    # gcc leaves a trailing carriage return, which upsets mingw
+    # gcc leaves a trailing carriage return which upsets mingw
     ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;;
   *)
     ac_prog=`($CC -print-prog-name=ld) 2>&5` ;;
@@ -12694,7 +12192,7 @@ $as_echo_n "checking for ld used by $CC... " >&6; }
       while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do
 	ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"`
       done
-      test -z "$LD" && LD=$ac_prog
+      test -z "$LD" && LD="$ac_prog"
       ;;
   "")
     # If it fails, then pretend we aren't using GCC.
@@ -12705,7 +12203,7 @@ $as_echo_n "checking for ld used by $CC... " >&6; }
     with_gnu_ld=unknown
     ;;
   esac
-elif test yes = "$with_gnu_ld"; then
+elif test "$with_gnu_ld" = yes; then
   { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU ld" >&5
 $as_echo_n "checking for GNU ld... " >&6; }
 else
@@ -12716,32 +12214,32 @@ if ${lt_cv_path_LD+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   if test -z "$LD"; then
-  lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR
+  lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
   for ac_dir in $PATH; do
-    IFS=$lt_save_ifs
+    IFS="$lt_save_ifs"
     test -z "$ac_dir" && ac_dir=.
     if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then
-      lt_cv_path_LD=$ac_dir/$ac_prog
+      lt_cv_path_LD="$ac_dir/$ac_prog"
       # Check to see if the program is GNU ld.  I'd rather use --version,
       # but apparently some variants of GNU ld only accept -v.
       # Break only if it was the GNU/non-GNU ld that we prefer.
       case `"$lt_cv_path_LD" -v 2>&1 </dev/null` in
       *GNU* | *'with BFD'*)
-	test no != "$with_gnu_ld" && break
+	test "$with_gnu_ld" != no && break
 	;;
       *)
-	test yes != "$with_gnu_ld" && break
+	test "$with_gnu_ld" != yes && break
 	;;
       esac
     fi
   done
-  IFS=$lt_save_ifs
+  IFS="$lt_save_ifs"
 else
-  lt_cv_path_LD=$LD # Let the user override the test with a path.
+  lt_cv_path_LD="$LD" # Let the user override the test with a path.
 fi
 fi
 
-LD=$lt_cv_path_LD
+LD="$lt_cv_path_LD"
 if test -n "$LD"; then
   { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LD" >&5
 $as_echo "$LD" >&6; }
@@ -12777,22 +12275,22 @@ with_gnu_ld=$lt_cv_prog_gnu_ld
 
       # Check if GNU C++ uses GNU ld as the underlying linker, since the
       # archiving commands below assume that GNU ld is being used.
-      if test yes = "$with_gnu_ld"; then
-        archive_cmds_CXX='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib'
-        archive_expsym_cmds_CXX='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'
+      if test "$with_gnu_ld" = yes; then
+        archive_cmds_CXX='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib'
+        archive_expsym_cmds_CXX='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
 
-        hardcode_libdir_flag_spec_CXX='$wl-rpath $wl$libdir'
-        export_dynamic_flag_spec_CXX='$wl--export-dynamic'
+        hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir'
+        export_dynamic_flag_spec_CXX='${wl}--export-dynamic'
 
         # If archive_cmds runs LD, not CC, wlarc should be empty
         # XXX I think wlarc can be eliminated in ltcf-cxx, but I need to
         #     investigate it a little bit more. (MM)
-        wlarc='$wl'
+        wlarc='${wl}'
 
         # ancient GNU ld didn't support --whole-archive et. al.
         if eval "`$CC -print-prog-name=ld` --help 2>&1" |
 	  $GREP 'no-whole-archive' > /dev/null; then
-          whole_archive_flag_spec_CXX=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive'
+          whole_archive_flag_spec_CXX="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive'
         else
           whole_archive_flag_spec_CXX=
         fi
@@ -12829,30 +12327,18 @@ $as_echo_n "checking whether the $compiler linker ($LD) supports shared librarie
         ld_shlibs_CXX=no
         ;;
       aix[4-9]*)
-        if test ia64 = "$host_cpu"; then
+        if test "$host_cpu" = ia64; then
           # On IA64, the linker does run time linking by default, so we don't
           # have to do anything special.
           aix_use_runtimelinking=no
           exp_sym_flag='-Bexport'
-          no_entry_flag=
+          no_entry_flag=""
         else
           aix_use_runtimelinking=no
 
           # Test if we are trying to use run time linking or normal
           # AIX style linking. If -brtl is somewhere in LDFLAGS, we
-          # have runtime linking enabled, and use it for executables.
-          # For shared libraries, we enable/disable runtime linking
-          # depending on the kind of the shared library created -
-          # when "with_aix_soname,aix_use_runtimelinking" is:
-          # "aix,no"   lib.a(lib.so.V) shared, rtl:no,  for executables
-          # "aix,yes"  lib.so          shared, rtl:yes, for executables
-          #            lib.a           static archive
-          # "both,no"  lib.so.V(shr.o) shared, rtl:yes
-          #            lib.a(lib.so.V) shared, rtl:no,  for executables
-          # "both,yes" lib.so.V(shr.o) shared, rtl:yes, for executables
-          #            lib.a(lib.so.V) shared, rtl:no
-          # "svr4,*"   lib.so.V(shr.o) shared, rtl:yes, for executables
-          #            lib.a           static archive
+          # need to do runtime linking.
           case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*)
 	    for ld_flag in $LDFLAGS; do
 	      case $ld_flag in
@@ -12862,13 +12348,6 @@ $as_echo_n "checking whether the $compiler linker ($LD) supports shared librarie
 	        ;;
 	      esac
 	    done
-	    if test svr4,no = "$with_aix_soname,$aix_use_runtimelinking"; then
-	      # With aix-soname=svr4, we create the lib.so.V shared archives only,
-	      # so we don't have lib.a shared libs to link our executables.
-	      # We have to force runtime linking in this case.
-	      aix_use_runtimelinking=yes
-	      LDFLAGS="$LDFLAGS -Wl,-brtl"
-	    fi
 	    ;;
           esac
 
@@ -12887,21 +12366,13 @@ $as_echo_n "checking whether the $compiler linker ($LD) supports shared librarie
         hardcode_direct_absolute_CXX=yes
         hardcode_libdir_separator_CXX=':'
         link_all_deplibs_CXX=yes
-        file_list_spec_CXX='$wl-f,'
-        case $with_aix_soname,$aix_use_runtimelinking in
-        aix,*) ;;	# no import file
-        svr4,* | *,yes) # use import file
-          # The Import File defines what to hardcode.
-          hardcode_direct_CXX=no
-          hardcode_direct_absolute_CXX=no
-          ;;
-        esac
+        file_list_spec_CXX='${wl}-f,'
 
-        if test yes = "$GXX"; then
+        if test "$GXX" = yes; then
           case $host_os in aix4.[012]|aix4.[012].*)
           # We only want to do this on AIX 4.2 and lower, the check
           # below for broken collect2 doesn't work under 4.3+
-	  collect2name=`$CC -print-prog-name=collect2`
+	  collect2name=`${CC} -print-prog-name=collect2`
 	  if test -f "$collect2name" &&
 	     strings "$collect2name" | $GREP resolve_lib_name >/dev/null
 	  then
@@ -12919,44 +12390,36 @@ $as_echo_n "checking whether the $compiler linker ($LD) supports shared librarie
 	  fi
           esac
           shared_flag='-shared'
-	  if test yes = "$aix_use_runtimelinking"; then
-	    shared_flag=$shared_flag' $wl-G'
+	  if test "$aix_use_runtimelinking" = yes; then
+	    shared_flag="$shared_flag "'${wl}-G'
 	  fi
-	  # Need to ensure runtime linking is disabled for the traditional
-	  # shared library, or the linker may eventually find shared libraries
-	  # /with/ Import File - we do not want to mix them.
-	  shared_flag_aix='-shared'
-	  shared_flag_svr4='-shared $wl-G'
         else
           # not using gcc
-          if test ia64 = "$host_cpu"; then
+          if test "$host_cpu" = ia64; then
 	  # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release
 	  # chokes on -Wl,-G. The following line is correct:
 	  shared_flag='-G'
           else
-	    if test yes = "$aix_use_runtimelinking"; then
-	      shared_flag='$wl-G'
+	    if test "$aix_use_runtimelinking" = yes; then
+	      shared_flag='${wl}-G'
 	    else
-	      shared_flag='$wl-bM:SRE'
+	      shared_flag='${wl}-bM:SRE'
 	    fi
-	    shared_flag_aix='$wl-bM:SRE'
-	    shared_flag_svr4='$wl-G'
           fi
         fi
 
-        export_dynamic_flag_spec_CXX='$wl-bexpall'
+        export_dynamic_flag_spec_CXX='${wl}-bexpall'
         # It seems that -bexpall does not export symbols beginning with
         # underscore (_), so it is better to generate a list of symbols to
 	# export.
         always_export_symbols_CXX=yes
-	if test aix,yes = "$with_aix_soname,$aix_use_runtimelinking"; then
+        if test "$aix_use_runtimelinking" = yes; then
           # Warning - without using the other runtime loading flags (-brtl),
           # -berok will link without error, but may produce a broken library.
-          # The "-G" linker flag allows undefined symbols.
-          no_undefined_flag_CXX='-bernotok'
+          allow_undefined_flag_CXX='-berok'
           # Determine the default libpath from the value encoded in an empty
           # executable.
-          if test set = "${lt_cv_aix_libpath+set}"; then
+          if test "${lt_cv_aix_libpath+set}" = set; then
   aix_libpath=$lt_cv_aix_libpath
 else
   if ${lt_cv_aix_libpath__CXX+:} false; then :
@@ -12991,7 +12454,7 @@ fi
 rm -f core conftest.err conftest.$ac_objext \
     conftest$ac_exeext conftest.$ac_ext
   if test -z "$lt_cv_aix_libpath__CXX"; then
-    lt_cv_aix_libpath__CXX=/usr/lib:/lib
+    lt_cv_aix_libpath__CXX="/usr/lib:/lib"
   fi
 
 fi
@@ -12999,18 +12462,18 @@ fi
   aix_libpath=$lt_cv_aix_libpath__CXX
 fi
 
-          hardcode_libdir_flag_spec_CXX='$wl-blibpath:$libdir:'"$aix_libpath"
+          hardcode_libdir_flag_spec_CXX='${wl}-blibpath:$libdir:'"$aix_libpath"
 
-          archive_expsym_cmds_CXX='$CC -o $output_objdir/$soname $libobjs $deplibs $wl'$no_entry_flag' $compiler_flags `if test -n "$allow_undefined_flag"; then func_echo_all "$wl$allow_undefined_flag"; else :; fi` $wl'$exp_sym_flag:\$export_symbols' '$shared_flag
+          archive_expsym_cmds_CXX='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then func_echo_all "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag"
         else
-          if test ia64 = "$host_cpu"; then
-	    hardcode_libdir_flag_spec_CXX='$wl-R $libdir:/usr/lib:/lib'
+          if test "$host_cpu" = ia64; then
+	    hardcode_libdir_flag_spec_CXX='${wl}-R $libdir:/usr/lib:/lib'
 	    allow_undefined_flag_CXX="-z nodefs"
-	    archive_expsym_cmds_CXX="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\$wl$no_entry_flag"' $compiler_flags $wl$allow_undefined_flag '"\$wl$exp_sym_flag:\$export_symbols"
+	    archive_expsym_cmds_CXX="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols"
           else
 	    # Determine the default libpath from the value encoded in an
 	    # empty executable.
-	    if test set = "${lt_cv_aix_libpath+set}"; then
+	    if test "${lt_cv_aix_libpath+set}" = set; then
   aix_libpath=$lt_cv_aix_libpath
 else
   if ${lt_cv_aix_libpath__CXX+:} false; then :
@@ -13045,7 +12508,7 @@ fi
 rm -f core conftest.err conftest.$ac_objext \
     conftest$ac_exeext conftest.$ac_ext
   if test -z "$lt_cv_aix_libpath__CXX"; then
-    lt_cv_aix_libpath__CXX=/usr/lib:/lib
+    lt_cv_aix_libpath__CXX="/usr/lib:/lib"
   fi
 
 fi
@@ -13053,34 +12516,22 @@ fi
   aix_libpath=$lt_cv_aix_libpath__CXX
 fi
 
-	    hardcode_libdir_flag_spec_CXX='$wl-blibpath:$libdir:'"$aix_libpath"
+	    hardcode_libdir_flag_spec_CXX='${wl}-blibpath:$libdir:'"$aix_libpath"
 	    # Warning - without using the other run time loading flags,
 	    # -berok will link without error, but may produce a broken library.
-	    no_undefined_flag_CXX=' $wl-bernotok'
-	    allow_undefined_flag_CXX=' $wl-berok'
-	    if test yes = "$with_gnu_ld"; then
+	    no_undefined_flag_CXX=' ${wl}-bernotok'
+	    allow_undefined_flag_CXX=' ${wl}-berok'
+	    if test "$with_gnu_ld" = yes; then
 	      # We only use this code for GNU lds that support --whole-archive.
-	      whole_archive_flag_spec_CXX='$wl--whole-archive$convenience $wl--no-whole-archive'
+	      whole_archive_flag_spec_CXX='${wl}--whole-archive$convenience ${wl}--no-whole-archive'
 	    else
 	      # Exported symbols can be pulled into shared objects from archives
 	      whole_archive_flag_spec_CXX='$convenience'
 	    fi
 	    archive_cmds_need_lc_CXX=yes
-	    archive_expsym_cmds_CXX='$RM -r $output_objdir/$realname.d~$MKDIR $output_objdir/$realname.d'
-	    # -brtl affects multiple linker settings, -berok does not and is overridden later
-	    compiler_flags_filtered='`func_echo_all "$compiler_flags " | $SED -e "s%-brtl\\([, ]\\)%-berok\\1%g"`'
-	    if test svr4 != "$with_aix_soname"; then
-	      # This is similar to how AIX traditionally builds its shared
-	      # libraries. Need -bnortl late, we may have -brtl in LDFLAGS.
-	      archive_expsym_cmds_CXX="$archive_expsym_cmds_CXX"'~$CC '$shared_flag_aix' -o $output_objdir/$realname.d/$soname $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$realname.d/$soname'
-	    fi
-	    if test aix != "$with_aix_soname"; then
-	      archive_expsym_cmds_CXX="$archive_expsym_cmds_CXX"'~$CC '$shared_flag_svr4' -o $output_objdir/$realname.d/$shared_archive_member_spec.o $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$STRIP -e $output_objdir/$realname.d/$shared_archive_member_spec.o~( func_echo_all "#! $soname($shared_archive_member_spec.o)"; if test shr_64 = "$shared_archive_member_spec"; then func_echo_all "# 64"; else func_echo_all "# 32"; fi; cat $export_sy [...]
-	    else
-	      # used by -dlpreopen to get the symbols
-	      archive_expsym_cmds_CXX="$archive_expsym_cmds_CXX"'~$MV  $output_objdir/$realname.d/$soname $output_objdir'
-	    fi
-	    archive_expsym_cmds_CXX="$archive_expsym_cmds_CXX"'~$RM -r $output_objdir/$realname.d'
+	    # This is similar to how AIX traditionally builds its shared
+	    # libraries.
+	    archive_expsym_cmds_CXX="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname'
           fi
         fi
         ;;
@@ -13090,7 +12541,7 @@ fi
 	  allow_undefined_flag_CXX=unsupported
 	  # Joseph Beckenbach <jrb3 at best.com> says some releases of gcc
 	  # support --undefined.  This deserves some investigation.  FIXME
-	  archive_cmds_CXX='$CC -nostart $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+	  archive_cmds_CXX='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
 	else
 	  ld_shlibs_CXX=no
 	fi
@@ -13118,58 +12569,57 @@ fi
 	  # Tell ltmain to make .lib files, not .a files.
 	  libext=lib
 	  # Tell ltmain to make .dll files, not .so files.
-	  shrext_cmds=.dll
+	  shrext_cmds=".dll"
 	  # FIXME: Setting linknames here is a bad hack.
-	  archive_cmds_CXX='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~linknames='
-	  archive_expsym_cmds_CXX='if   test DEF = "`$SED -n     -e '\''s/^[	 ]*//'\''     -e '\''/^\(;.*\)*$/d'\''     -e '\''s/^\(EXPORTS\|LIBRARY\)\([	 ].*\)*$/DEF/p'\''     -e q     $export_symbols`" ; then
-              cp "$export_symbols" "$output_objdir/$soname.def";
-              echo "$tool_output_objdir$soname.def" > "$output_objdir/$soname.exp";
-            else
-              $SED -e '\''s/^/-link -EXPORT:/'\'' < $export_symbols > $output_objdir/$soname.exp;
-            fi~
-            $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~
-            linknames='
+	  archive_cmds_CXX='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-dll~linknames='
+	  archive_expsym_cmds_CXX='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then
+	      $SED -n -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' -e '1\\\!p' < $export_symbols > $output_objdir/$soname.exp;
+	    else
+	      $SED -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' < $export_symbols > $output_objdir/$soname.exp;
+	    fi~
+	    $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~
+	    linknames='
 	  # The linker will not automatically build a static lib if we build a DLL.
 	  # _LT_TAGVAR(old_archive_from_new_cmds, CXX)='true'
 	  enable_shared_with_static_runtimes_CXX=yes
 	  # Don't use ranlib
 	  old_postinstall_cmds_CXX='chmod 644 $oldlib'
 	  postlink_cmds_CXX='lt_outputfile="@OUTPUT@"~
-            lt_tool_outputfile="@TOOL_OUTPUT@"~
-            case $lt_outputfile in
-              *.exe|*.EXE) ;;
-              *)
-                lt_outputfile=$lt_outputfile.exe
-                lt_tool_outputfile=$lt_tool_outputfile.exe
-                ;;
-            esac~
-            func_to_tool_file "$lt_outputfile"~
-            if test : != "$MANIFEST_TOOL" && test -f "$lt_outputfile.manifest"; then
-              $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1;
-              $RM "$lt_outputfile.manifest";
-            fi'
+	    lt_tool_outputfile="@TOOL_OUTPUT@"~
+	    case $lt_outputfile in
+	      *.exe|*.EXE) ;;
+	      *)
+		lt_outputfile="$lt_outputfile.exe"
+		lt_tool_outputfile="$lt_tool_outputfile.exe"
+		;;
+	    esac~
+	    func_to_tool_file "$lt_outputfile"~
+	    if test "$MANIFEST_TOOL" != ":" && test -f "$lt_outputfile.manifest"; then
+	      $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1;
+	      $RM "$lt_outputfile.manifest";
+	    fi'
 	  ;;
 	*)
 	  # g++
 	  # _LT_TAGVAR(hardcode_libdir_flag_spec, CXX) is actually meaningless,
 	  # as there is no search path for DLLs.
 	  hardcode_libdir_flag_spec_CXX='-L$libdir'
-	  export_dynamic_flag_spec_CXX='$wl--export-all-symbols'
+	  export_dynamic_flag_spec_CXX='${wl}--export-all-symbols'
 	  allow_undefined_flag_CXX=unsupported
 	  always_export_symbols_CXX=no
 	  enable_shared_with_static_runtimes_CXX=yes
 
 	  if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then
-	    archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
-	    # If the export-symbols file already is a .def file, use it as
-	    # is; otherwise, prepend EXPORTS...
-	    archive_expsym_cmds_CXX='if   test DEF = "`$SED -n     -e '\''s/^[	 ]*//'\''     -e '\''/^\(;.*\)*$/d'\''     -e '\''s/^\(EXPORTS\|LIBRARY\)\([	 ].*\)*$/DEF/p'\''     -e q     $export_symbols`" ; then
-              cp $export_symbols $output_objdir/$soname.def;
-            else
-              echo EXPORTS > $output_objdir/$soname.def;
-              cat $export_symbols >> $output_objdir/$soname.def;
-            fi~
-            $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+	    archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+	    # If the export-symbols file already is a .def file (1st line
+	    # is EXPORTS), use it as is; otherwise, prepend...
+	    archive_expsym_cmds_CXX='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then
+	      cp $export_symbols $output_objdir/$soname.def;
+	    else
+	      echo EXPORTS > $output_objdir/$soname.def;
+	      cat $export_symbols >> $output_objdir/$soname.def;
+	    fi~
+	    $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
 	  else
 	    ld_shlibs_CXX=no
 	  fi
@@ -13183,27 +12633,27 @@ fi
   hardcode_direct_CXX=no
   hardcode_automatic_CXX=yes
   hardcode_shlibpath_var_CXX=unsupported
-  if test yes = "$lt_cv_ld_force_load"; then
-    whole_archive_flag_spec_CXX='`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience $wl-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`'
+  if test "$lt_cv_ld_force_load" = "yes"; then
+    whole_archive_flag_spec_CXX='`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience ${wl}-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`'
 
   else
     whole_archive_flag_spec_CXX=''
   fi
   link_all_deplibs_CXX=yes
-  allow_undefined_flag_CXX=$_lt_dar_allow_undefined
+  allow_undefined_flag_CXX="$_lt_dar_allow_undefined"
   case $cc_basename in
-     ifort*|nagfor*) _lt_dar_can_shared=yes ;;
+     ifort*) _lt_dar_can_shared=yes ;;
      *) _lt_dar_can_shared=$GCC ;;
   esac
-  if test yes = "$_lt_dar_can_shared"; then
+  if test "$_lt_dar_can_shared" = "yes"; then
     output_verbose_link_cmd=func_echo_all
-    archive_cmds_CXX="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dsymutil"
-    module_cmds_CXX="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dsymutil"
-    archive_expsym_cmds_CXX="sed 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dar_export_syms$_lt_dsymutil"
-    module_expsym_cmds_CXX="sed -e 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dar_export_syms$_lt_dsymutil"
-       if test yes != "$lt_cv_apple_cc_single_mod"; then
-      archive_cmds_CXX="\$CC -r -keep_private_externs -nostdlib -o \$lib-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$lib-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring$_lt_dsymutil"
-      archive_expsym_cmds_CXX="sed 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \$lib-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$lib-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring$_lt_dar_export_syms$_lt_dsymutil"
+    archive_cmds_CXX="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}"
+    module_cmds_CXX="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}"
+    archive_expsym_cmds_CXX="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}"
+    module_expsym_cmds_CXX="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}"
+       if test "$lt_cv_apple_cc_single_mod" != "yes"; then
+      archive_cmds_CXX="\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dsymutil}"
+      archive_expsym_cmds_CXX="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dar_export_syms}${_lt_dsymutil}"
     fi
 
   else
@@ -13212,34 +12662,6 @@ fi
 
 	;;
 
-      os2*)
-	hardcode_libdir_flag_spec_CXX='-L$libdir'
-	hardcode_minus_L_CXX=yes
-	allow_undefined_flag_CXX=unsupported
-	shrext_cmds=.dll
-	archive_cmds_CXX='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~
-	  $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~
-	  $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~
-	  $ECHO EXPORTS >> $output_objdir/$libname.def~
-	  emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~
-	  $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~
-	  emximp -o $lib $output_objdir/$libname.def'
-	archive_expsym_cmds_CXX='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~
-	  $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~
-	  $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~
-	  $ECHO EXPORTS >> $output_objdir/$libname.def~
-	  prefix_cmds="$SED"~
-	  if test EXPORTS = "`$SED 1q $export_symbols`"; then
-	    prefix_cmds="$prefix_cmds -e 1d";
-	  fi~
-	  prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~
-	  cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~
-	  $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~
-	  emximp -o $lib $output_objdir/$libname.def'
-	old_archive_From_new_cmds_CXX='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def'
-	enable_shared_with_static_runtimes_CXX=yes
-	;;
-
       dgux*)
         case $cc_basename in
           ec++*)
@@ -13275,14 +12697,14 @@ fi
         ;;
 
       haiku*)
-        archive_cmds_CXX='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+        archive_cmds_CXX='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
         link_all_deplibs_CXX=yes
         ;;
 
       hpux9*)
-        hardcode_libdir_flag_spec_CXX='$wl+b $wl$libdir'
+        hardcode_libdir_flag_spec_CXX='${wl}+b ${wl}$libdir'
         hardcode_libdir_separator_CXX=:
-        export_dynamic_flag_spec_CXX='$wl-E'
+        export_dynamic_flag_spec_CXX='${wl}-E'
         hardcode_direct_CXX=yes
         hardcode_minus_L_CXX=yes # Not in the search PATH,
 				             # but as the default
@@ -13294,7 +12716,7 @@ fi
             ld_shlibs_CXX=no
             ;;
           aCC*)
-            archive_cmds_CXX='$RM $output_objdir/$soname~$CC -b $wl+b $wl$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib'
+            archive_cmds_CXX='$RM $output_objdir/$soname~$CC -b ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
             # Commands to make compiler produce verbose output that lists
             # what "hidden" libraries, object files and flags are used when
             # linking a shared library.
@@ -13303,11 +12725,11 @@ fi
             # explicitly linking system object files so we need to strip them
             # from the output so that they don't get included in the library
             # dependencies.
-            output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP "\-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
+            output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
             ;;
           *)
-            if test yes = "$GXX"; then
-              archive_cmds_CXX='$RM $output_objdir/$soname~$CC -shared -nostdlib $pic_flag $wl+b $wl$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib'
+            if test "$GXX" = yes; then
+              archive_cmds_CXX='$RM $output_objdir/$soname~$CC -shared -nostdlib $pic_flag ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
             else
               # FIXME: insert proper C++ library support
               ld_shlibs_CXX=no
@@ -13317,15 +12739,15 @@ fi
         ;;
 
       hpux10*|hpux11*)
-        if test no = "$with_gnu_ld"; then
-	  hardcode_libdir_flag_spec_CXX='$wl+b $wl$libdir'
+        if test $with_gnu_ld = no; then
+	  hardcode_libdir_flag_spec_CXX='${wl}+b ${wl}$libdir'
 	  hardcode_libdir_separator_CXX=:
 
           case $host_cpu in
             hppa*64*|ia64*)
               ;;
             *)
-	      export_dynamic_flag_spec_CXX='$wl-E'
+	      export_dynamic_flag_spec_CXX='${wl}-E'
               ;;
           esac
         fi
@@ -13351,13 +12773,13 @@ fi
           aCC*)
 	    case $host_cpu in
 	      hppa*64*)
-	        archive_cmds_CXX='$CC -b $wl+h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+	        archive_cmds_CXX='$CC -b ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
 	        ;;
 	      ia64*)
-	        archive_cmds_CXX='$CC -b $wl+h $wl$soname $wl+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+	        archive_cmds_CXX='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
 	        ;;
 	      *)
-	        archive_cmds_CXX='$CC -b $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+	        archive_cmds_CXX='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
 	        ;;
 	    esac
 	    # Commands to make compiler produce verbose output that lists
@@ -13368,20 +12790,20 @@ fi
 	    # explicitly linking system object files so we need to strip them
 	    # from the output so that they don't get included in the library
 	    # dependencies.
-	    output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP "\-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
+	    output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
 	    ;;
           *)
-	    if test yes = "$GXX"; then
-	      if test no = "$with_gnu_ld"; then
+	    if test "$GXX" = yes; then
+	      if test $with_gnu_ld = no; then
 	        case $host_cpu in
 	          hppa*64*)
-	            archive_cmds_CXX='$CC -shared -nostdlib -fPIC $wl+h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+	            archive_cmds_CXX='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
 	            ;;
 	          ia64*)
-	            archive_cmds_CXX='$CC -shared -nostdlib $pic_flag $wl+h $wl$soname $wl+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+	            archive_cmds_CXX='$CC -shared -nostdlib $pic_flag ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
 	            ;;
 	          *)
-	            archive_cmds_CXX='$CC -shared -nostdlib $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+	            archive_cmds_CXX='$CC -shared -nostdlib $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
 	            ;;
 	        esac
 	      fi
@@ -13396,22 +12818,22 @@ fi
       interix[3-9]*)
 	hardcode_direct_CXX=no
 	hardcode_shlibpath_var_CXX=no
-	hardcode_libdir_flag_spec_CXX='$wl-rpath,$libdir'
-	export_dynamic_flag_spec_CXX='$wl-E'
+	hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir'
+	export_dynamic_flag_spec_CXX='${wl}-E'
 	# Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc.
 	# Instead, shared libraries are loaded at an image base (0x10000000 by
 	# default) and relocated if they conflict, which is a slow very memory
 	# consuming and fragmenting process.  To avoid this, we pick a random,
 	# 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link
 	# time.  Moving up from 0x10000000 also allows more sbrk(2) space.
-	archive_cmds_CXX='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
-	archive_expsym_cmds_CXX='sed "s|^|_|" $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--retain-symbols-file,$output_objdir/$soname.expsym $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+	archive_cmds_CXX='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+	archive_expsym_cmds_CXX='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
 	;;
       irix5* | irix6*)
         case $cc_basename in
           CC*)
 	    # SGI C++
-	    archive_cmds_CXX='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib'
+	    archive_cmds_CXX='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib'
 
 	    # Archives containing C++ object files must be created using
 	    # "CC -ar", where "CC" is the IRIX C++ compiler.  This is
@@ -13420,17 +12842,17 @@ fi
 	    old_archive_cmds_CXX='$CC -ar -WR,-u -o $oldlib $oldobjs'
 	    ;;
           *)
-	    if test yes = "$GXX"; then
-	      if test no = "$with_gnu_ld"; then
-	        archive_cmds_CXX='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib'
+	    if test "$GXX" = yes; then
+	      if test "$with_gnu_ld" = no; then
+	        archive_cmds_CXX='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
 	      else
-	        archive_cmds_CXX='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` -o $lib'
+	        archive_cmds_CXX='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` -o $lib'
 	      fi
 	    fi
 	    link_all_deplibs_CXX=yes
 	    ;;
         esac
-        hardcode_libdir_flag_spec_CXX='$wl-rpath $wl$libdir'
+        hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir'
         hardcode_libdir_separator_CXX=:
         inherit_rpath_CXX=yes
         ;;
@@ -13443,8 +12865,8 @@ fi
 	    # KCC will only create a shared library if the output file
 	    # ends with ".so" (or ".sl" for HP-UX), so rename the library
 	    # to its proper name (with version) after linking.
-	    archive_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib'
-	    archive_expsym_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib $wl-retain-symbols-file,$export_symbols; mv \$templib $lib'
+	    archive_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib'
+	    archive_expsym_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib ${wl}-retain-symbols-file,$export_symbols; mv \$templib $lib'
 	    # Commands to make compiler produce verbose output that lists
 	    # what "hidden" libraries, object files and flags are used when
 	    # linking a shared library.
@@ -13453,10 +12875,10 @@ fi
 	    # explicitly linking system object files so we need to strip them
 	    # from the output so that they don't get included in the library
 	    # dependencies.
-	    output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | $GREP "ld"`; rm -f libconftest$shared_ext; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
+	    output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | $GREP "ld"`; rm -f libconftest$shared_ext; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
 
-	    hardcode_libdir_flag_spec_CXX='$wl-rpath,$libdir'
-	    export_dynamic_flag_spec_CXX='$wl--export-dynamic'
+	    hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir'
+	    export_dynamic_flag_spec_CXX='${wl}--export-dynamic'
 
 	    # Archives containing C++ object files must be created using
 	    # "CC -Bstatic", where "CC" is the KAI C++ compiler.
@@ -13470,59 +12892,59 @@ fi
 	    # earlier do not add the objects themselves.
 	    case `$CC -V 2>&1` in
 	      *"Version 7."*)
-	        archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib'
-		archive_expsym_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'
+	        archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib'
+		archive_expsym_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
 		;;
 	      *)  # Version 8.0 or newer
 	        tmp_idyn=
 	        case $host_cpu in
 		  ia64*) tmp_idyn=' -i_dynamic';;
 		esac
-	        archive_cmds_CXX='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
-		archive_expsym_cmds_CXX='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'
+	        archive_cmds_CXX='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+		archive_expsym_cmds_CXX='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
 		;;
 	    esac
 	    archive_cmds_need_lc_CXX=no
-	    hardcode_libdir_flag_spec_CXX='$wl-rpath,$libdir'
-	    export_dynamic_flag_spec_CXX='$wl--export-dynamic'
-	    whole_archive_flag_spec_CXX='$wl--whole-archive$convenience $wl--no-whole-archive'
+	    hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir'
+	    export_dynamic_flag_spec_CXX='${wl}--export-dynamic'
+	    whole_archive_flag_spec_CXX='${wl}--whole-archive$convenience ${wl}--no-whole-archive'
 	    ;;
           pgCC* | pgcpp*)
             # Portland Group C++ compiler
 	    case `$CC -V` in
 	    *pgCC\ [1-5].* | *pgcpp\ [1-5].*)
 	      prelink_cmds_CXX='tpldir=Template.dir~
-               rm -rf $tpldir~
-               $CC --prelink_objects --instantiation_dir $tpldir $objs $libobjs $compile_deplibs~
-               compile_command="$compile_command `find $tpldir -name \*.o | sort | $NL2SP`"'
+		rm -rf $tpldir~
+		$CC --prelink_objects --instantiation_dir $tpldir $objs $libobjs $compile_deplibs~
+		compile_command="$compile_command `find $tpldir -name \*.o | sort | $NL2SP`"'
 	      old_archive_cmds_CXX='tpldir=Template.dir~
-                rm -rf $tpldir~
-                $CC --prelink_objects --instantiation_dir $tpldir $oldobjs$old_deplibs~
-                $AR $AR_FLAGS $oldlib$oldobjs$old_deplibs `find $tpldir -name \*.o | sort | $NL2SP`~
-                $RANLIB $oldlib'
+		rm -rf $tpldir~
+		$CC --prelink_objects --instantiation_dir $tpldir $oldobjs$old_deplibs~
+		$AR $AR_FLAGS $oldlib$oldobjs$old_deplibs `find $tpldir -name \*.o | sort | $NL2SP`~
+		$RANLIB $oldlib'
 	      archive_cmds_CXX='tpldir=Template.dir~
-                rm -rf $tpldir~
-                $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~
-                $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib'
+		rm -rf $tpldir~
+		$CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~
+		$CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib'
 	      archive_expsym_cmds_CXX='tpldir=Template.dir~
-                rm -rf $tpldir~
-                $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~
-                $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'
+		rm -rf $tpldir~
+		$CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~
+		$CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib'
 	      ;;
 	    *) # Version 6 and above use weak symbols
-	      archive_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib'
-	      archive_expsym_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'
+	      archive_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib'
+	      archive_expsym_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib'
 	      ;;
 	    esac
 
-	    hardcode_libdir_flag_spec_CXX='$wl--rpath $wl$libdir'
-	    export_dynamic_flag_spec_CXX='$wl--export-dynamic'
-	    whole_archive_flag_spec_CXX='$wl--whole-archive`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive'
+	    hardcode_libdir_flag_spec_CXX='${wl}--rpath ${wl}$libdir'
+	    export_dynamic_flag_spec_CXX='${wl}--export-dynamic'
+	    whole_archive_flag_spec_CXX='${wl}--whole-archive`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
             ;;
 	  cxx*)
 	    # Compaq C++
-	    archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib'
-	    archive_expsym_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname  -o $lib $wl-retain-symbols-file $wl$export_symbols'
+	    archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib'
+	    archive_expsym_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname  -o $lib ${wl}-retain-symbols-file $wl$export_symbols'
 
 	    runpath_var=LD_RUN_PATH
 	    hardcode_libdir_flag_spec_CXX='-rpath $libdir'
@@ -13536,18 +12958,18 @@ fi
 	    # explicitly linking system object files so we need to strip them
 	    # from the output so that they don't get included in the library
 	    # dependencies.
-	    output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "X$list" | $Xsed'
+	    output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "X$list" | $Xsed'
 	    ;;
 	  xl* | mpixl* | bgxl*)
 	    # IBM XL 8.0 on PPC, with GNU ld
-	    hardcode_libdir_flag_spec_CXX='$wl-rpath $wl$libdir'
-	    export_dynamic_flag_spec_CXX='$wl--export-dynamic'
-	    archive_cmds_CXX='$CC -qmkshrobj $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
-	    if test yes = "$supports_anon_versioning"; then
+	    hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir'
+	    export_dynamic_flag_spec_CXX='${wl}--export-dynamic'
+	    archive_cmds_CXX='$CC -qmkshrobj $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+	    if test "x$supports_anon_versioning" = xyes; then
 	      archive_expsym_cmds_CXX='echo "{ global:" > $output_objdir/$libname.ver~
-                cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
-                echo "local: *; };" >> $output_objdir/$libname.ver~
-                $CC -qmkshrobj $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-version-script $wl$output_objdir/$libname.ver -o $lib'
+		cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
+		echo "local: *; };" >> $output_objdir/$libname.ver~
+		$CC -qmkshrobj $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib'
 	    fi
 	    ;;
 	  *)
@@ -13555,10 +12977,10 @@ fi
 	    *Sun\ C*)
 	      # Sun C++ 5.9
 	      no_undefined_flag_CXX=' -zdefs'
-	      archive_cmds_CXX='$CC -G$allow_undefined_flag -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
-	      archive_expsym_cmds_CXX='$CC -G$allow_undefined_flag -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-retain-symbols-file $wl$export_symbols'
+	      archive_cmds_CXX='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+	      archive_expsym_cmds_CXX='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file ${wl}$export_symbols'
 	      hardcode_libdir_flag_spec_CXX='-R$libdir'
-	      whole_archive_flag_spec_CXX='$wl--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive'
+	      whole_archive_flag_spec_CXX='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
 	      compiler_needs_object_CXX=yes
 
 	      # Not sure whether something based on
@@ -13616,17 +13038,22 @@ fi
         ld_shlibs_CXX=yes
 	;;
 
-      openbsd* | bitrig*)
+      openbsd2*)
+        # C++ shared libraries are fairly broken
+	ld_shlibs_CXX=no
+	;;
+
+      openbsd*)
 	if test -f /usr/libexec/ld.so; then
 	  hardcode_direct_CXX=yes
 	  hardcode_shlibpath_var_CXX=no
 	  hardcode_direct_absolute_CXX=yes
 	  archive_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib'
-	  hardcode_libdir_flag_spec_CXX='$wl-rpath,$libdir'
-	  if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`"; then
-	    archive_expsym_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-retain-symbols-file,$export_symbols -o $lib'
-	    export_dynamic_flag_spec_CXX='$wl-E'
-	    whole_archive_flag_spec_CXX=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive'
+	  hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir'
+	  if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+	    archive_expsym_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file,$export_symbols -o $lib'
+	    export_dynamic_flag_spec_CXX='${wl}-E'
+	    whole_archive_flag_spec_CXX="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive'
 	  fi
 	  output_verbose_link_cmd=func_echo_all
 	else
@@ -13642,9 +13069,9 @@ fi
 	    # KCC will only create a shared library if the output file
 	    # ends with ".so" (or ".sl" for HP-UX), so rename the library
 	    # to its proper name (with version) after linking.
-	    archive_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo "$lib" | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib'
+	    archive_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo "$lib" | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib'
 
-	    hardcode_libdir_flag_spec_CXX='$wl-rpath,$libdir'
+	    hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir'
 	    hardcode_libdir_separator_CXX=:
 
 	    # Archives containing C++ object files must be created using
@@ -13662,17 +13089,17 @@ fi
           cxx*)
 	    case $host in
 	      osf3*)
-	        allow_undefined_flag_CXX=' $wl-expect_unresolved $wl\*'
-	        archive_cmds_CXX='$CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $soname `test -n "$verstring" && func_echo_all "$wl-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib'
-	        hardcode_libdir_flag_spec_CXX='$wl-rpath $wl$libdir'
+	        allow_undefined_flag_CXX=' ${wl}-expect_unresolved ${wl}\*'
+	        archive_cmds_CXX='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $soname `test -n "$verstring" && func_echo_all "${wl}-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib'
+	        hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir'
 		;;
 	      *)
 	        allow_undefined_flag_CXX=' -expect_unresolved \*'
-	        archive_cmds_CXX='$CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib'
+	        archive_cmds_CXX='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib'
 	        archive_expsym_cmds_CXX='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done~
-                  echo "-hidden">> $lib.exp~
-                  $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname $wl-input $wl$lib.exp  `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib~
-                  $RM $lib.exp'
+	          echo "-hidden">> $lib.exp~
+	          $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname ${wl}-input ${wl}$lib.exp  `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib~
+	          $RM $lib.exp'
 	        hardcode_libdir_flag_spec_CXX='-rpath $libdir'
 		;;
 	    esac
@@ -13687,21 +13114,21 @@ fi
 	    # explicitly linking system object files so we need to strip them
 	    # from the output so that they don't get included in the library
 	    # dependencies.
-	    output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld" | $GREP -v "ld:"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
+	    output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld" | $GREP -v "ld:"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
 	    ;;
 	  *)
-	    if test yes,no = "$GXX,$with_gnu_ld"; then
-	      allow_undefined_flag_CXX=' $wl-expect_unresolved $wl\*'
+	    if test "$GXX" = yes && test "$with_gnu_ld" = no; then
+	      allow_undefined_flag_CXX=' ${wl}-expect_unresolved ${wl}\*'
 	      case $host in
 	        osf3*)
-	          archive_cmds_CXX='$CC -shared -nostdlib $allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib'
+	          archive_cmds_CXX='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
 		  ;;
 	        *)
-	          archive_cmds_CXX='$CC -shared $pic_flag -nostdlib $allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-msym $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib'
+	          archive_cmds_CXX='$CC -shared $pic_flag -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
 		  ;;
 	      esac
 
-	      hardcode_libdir_flag_spec_CXX='$wl-rpath $wl$libdir'
+	      hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir'
 	      hardcode_libdir_separator_CXX=:
 
 	      # Commands to make compiler produce verbose output that lists
@@ -13747,9 +13174,9 @@ fi
 	    # Sun C++ 4.2, 5.x and Centerline C++
             archive_cmds_need_lc_CXX=yes
 	    no_undefined_flag_CXX=' -zdefs'
-	    archive_cmds_CXX='$CC -G$allow_undefined_flag -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+	    archive_cmds_CXX='$CC -G${allow_undefined_flag}  -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
 	    archive_expsym_cmds_CXX='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
-              $CC -G$allow_undefined_flag $wl-M $wl$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp'
+	      $CC -G${allow_undefined_flag} ${wl}-M ${wl}$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp'
 
 	    hardcode_libdir_flag_spec_CXX='-R$libdir'
 	    hardcode_shlibpath_var_CXX=no
@@ -13757,7 +13184,7 @@ fi
 	      solaris2.[0-5] | solaris2.[0-5].*) ;;
 	      *)
 		# The compiler driver will combine and reorder linker options,
-		# but understands '-z linker_flag'.
+		# but understands `-z linker_flag'.
 	        # Supported since Solaris 2.6 (maybe 2.5.1?)
 		whole_archive_flag_spec_CXX='-z allextract$convenience -z defaultextract'
 	        ;;
@@ -13774,30 +13201,30 @@ fi
 	    ;;
           gcx*)
 	    # Green Hills C++ Compiler
-	    archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-h $wl$soname -o $lib'
+	    archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib'
 
 	    # The C++ compiler must be used to create the archive.
 	    old_archive_cmds_CXX='$CC $LDFLAGS -archive -o $oldlib $oldobjs'
 	    ;;
           *)
 	    # GNU C++ compiler with Solaris linker
-	    if test yes,no = "$GXX,$with_gnu_ld"; then
-	      no_undefined_flag_CXX=' $wl-z ${wl}defs'
+	    if test "$GXX" = yes && test "$with_gnu_ld" = no; then
+	      no_undefined_flag_CXX=' ${wl}-z ${wl}defs'
 	      if $CC --version | $GREP -v '^2\.7' > /dev/null; then
-	        archive_cmds_CXX='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-h $wl$soname -o $lib'
+	        archive_cmds_CXX='$CC -shared $pic_flag -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib'
 	        archive_expsym_cmds_CXX='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
-                  $CC -shared $pic_flag -nostdlib $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp'
+		  $CC -shared $pic_flag -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp'
 
 	        # Commands to make compiler produce verbose output that lists
 	        # what "hidden" libraries, object files and flags are used when
 	        # linking a shared library.
 	        output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"'
 	      else
-	        # g++ 2.7 appears to require '-G' NOT '-shared' on this
+	        # g++ 2.7 appears to require `-G' NOT `-shared' on this
 	        # platform.
-	        archive_cmds_CXX='$CC -G -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-h $wl$soname -o $lib'
+	        archive_cmds_CXX='$CC -G -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib'
 	        archive_expsym_cmds_CXX='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
-                  $CC -G -nostdlib $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp'
+		  $CC -G -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp'
 
 	        # Commands to make compiler produce verbose output that lists
 	        # what "hidden" libraries, object files and flags are used when
@@ -13805,11 +13232,11 @@ fi
 	        output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"'
 	      fi
 
-	      hardcode_libdir_flag_spec_CXX='$wl-R $wl$libdir'
+	      hardcode_libdir_flag_spec_CXX='${wl}-R $wl$libdir'
 	      case $host_os in
 		solaris2.[0-5] | solaris2.[0-5].*) ;;
 		*)
-		  whole_archive_flag_spec_CXX='$wl-z ${wl}allextract$convenience $wl-z ${wl}defaultextract'
+		  whole_archive_flag_spec_CXX='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract'
 		  ;;
 	      esac
 	    fi
@@ -13818,52 +13245,52 @@ fi
         ;;
 
     sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*)
-      no_undefined_flag_CXX='$wl-z,text'
+      no_undefined_flag_CXX='${wl}-z,text'
       archive_cmds_need_lc_CXX=no
       hardcode_shlibpath_var_CXX=no
       runpath_var='LD_RUN_PATH'
 
       case $cc_basename in
         CC*)
-	  archive_cmds_CXX='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
-	  archive_expsym_cmds_CXX='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	  archive_cmds_CXX='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	  archive_expsym_cmds_CXX='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
 	  ;;
 	*)
-	  archive_cmds_CXX='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
-	  archive_expsym_cmds_CXX='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	  archive_cmds_CXX='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	  archive_expsym_cmds_CXX='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
 	  ;;
       esac
       ;;
 
       sysv5* | sco3.2v5* | sco5v6*)
-	# Note: We CANNOT use -z defs as we might desire, because we do not
+	# Note: We can NOT use -z defs as we might desire, because we do not
 	# link with -lc, and that would cause any symbols used from libc to
 	# always be unresolved, which means just about no library would
 	# ever link correctly.  If we're not using GNU ld we use -z text
 	# though, which does catch some bad symbols but isn't as heavy-handed
 	# as -z defs.
-	no_undefined_flag_CXX='$wl-z,text'
-	allow_undefined_flag_CXX='$wl-z,nodefs'
+	no_undefined_flag_CXX='${wl}-z,text'
+	allow_undefined_flag_CXX='${wl}-z,nodefs'
 	archive_cmds_need_lc_CXX=no
 	hardcode_shlibpath_var_CXX=no
-	hardcode_libdir_flag_spec_CXX='$wl-R,$libdir'
+	hardcode_libdir_flag_spec_CXX='${wl}-R,$libdir'
 	hardcode_libdir_separator_CXX=':'
 	link_all_deplibs_CXX=yes
-	export_dynamic_flag_spec_CXX='$wl-Bexport'
+	export_dynamic_flag_spec_CXX='${wl}-Bexport'
 	runpath_var='LD_RUN_PATH'
 
 	case $cc_basename in
           CC*)
-	    archive_cmds_CXX='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
-	    archive_expsym_cmds_CXX='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	    archive_cmds_CXX='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	    archive_expsym_cmds_CXX='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
 	    old_archive_cmds_CXX='$CC -Tprelink_objects $oldobjs~
-              '"$old_archive_cmds_CXX"
+	      '"$old_archive_cmds_CXX"
 	    reload_cmds_CXX='$CC -Tprelink_objects $reload_objs~
-              '"$reload_cmds_CXX"
+	      '"$reload_cmds_CXX"
 	    ;;
 	  *)
-	    archive_cmds_CXX='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
-	    archive_expsym_cmds_CXX='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	    archive_cmds_CXX='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	    archive_expsym_cmds_CXX='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
 	    ;;
 	esac
       ;;
@@ -13895,10 +13322,10 @@ fi
 
     { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs_CXX" >&5
 $as_echo "$ld_shlibs_CXX" >&6; }
-    test no = "$ld_shlibs_CXX" && can_build_shared=no
+    test "$ld_shlibs_CXX" = no && can_build_shared=no
 
-    GCC_CXX=$GXX
-    LD_CXX=$LD
+    GCC_CXX="$GXX"
+    LD_CXX="$LD"
 
     ## CAVEAT EMPTOR:
     ## There is no encapsulation within the following macros, do not change
@@ -13942,13 +13369,13 @@ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
   pre_test_object_deps_done=no
 
   for p in `eval "$output_verbose_link_cmd"`; do
-    case $prev$p in
+    case ${prev}${p} in
 
     -L* | -R* | -l*)
        # Some compilers place space between "-{L,R}" and the path.
        # Remove the space.
-       if test x-L = "$p" ||
-          test x-R = "$p"; then
+       if test $p = "-L" ||
+          test $p = "-R"; then
 	 prev=$p
 	 continue
        fi
@@ -13964,16 +13391,16 @@ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
        case $p in
        =*) func_stripname_cnf '=' '' "$p"; p=$lt_sysroot$func_stripname_result ;;
        esac
-       if test no = "$pre_test_object_deps_done"; then
-	 case $prev in
+       if test "$pre_test_object_deps_done" = no; then
+	 case ${prev} in
 	 -L | -R)
 	   # Internal compiler library paths should come after those
 	   # provided the user.  The postdeps already come after the
 	   # user supplied libs so there is no need to process them.
 	   if test -z "$compiler_lib_search_path_CXX"; then
-	     compiler_lib_search_path_CXX=$prev$p
+	     compiler_lib_search_path_CXX="${prev}${p}"
 	   else
-	     compiler_lib_search_path_CXX="${compiler_lib_search_path_CXX} $prev$p"
+	     compiler_lib_search_path_CXX="${compiler_lib_search_path_CXX} ${prev}${p}"
 	   fi
 	   ;;
 	 # The "-l" case would never come before the object being
@@ -13981,9 +13408,9 @@ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
 	 esac
        else
 	 if test -z "$postdeps_CXX"; then
-	   postdeps_CXX=$prev$p
+	   postdeps_CXX="${prev}${p}"
 	 else
-	   postdeps_CXX="${postdeps_CXX} $prev$p"
+	   postdeps_CXX="${postdeps_CXX} ${prev}${p}"
 	 fi
        fi
        prev=
@@ -13998,15 +13425,15 @@ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
 	 continue
        fi
 
-       if test no = "$pre_test_object_deps_done"; then
+       if test "$pre_test_object_deps_done" = no; then
 	 if test -z "$predep_objects_CXX"; then
-	   predep_objects_CXX=$p
+	   predep_objects_CXX="$p"
 	 else
 	   predep_objects_CXX="$predep_objects_CXX $p"
 	 fi
        else
 	 if test -z "$postdep_objects_CXX"; then
-	   postdep_objects_CXX=$p
+	   postdep_objects_CXX="$p"
 	 else
 	   postdep_objects_CXX="$postdep_objects_CXX $p"
 	 fi
@@ -14036,6 +13463,51 @@ interix[3-9]*)
   postdep_objects_CXX=
   postdeps_CXX=
   ;;
+
+linux*)
+  case `$CC -V 2>&1 | sed 5q` in
+  *Sun\ C*)
+    # Sun C++ 5.9
+
+    # The more standards-conforming stlport4 library is
+    # incompatible with the Cstd library. Avoid specifying
+    # it if it's in CXXFLAGS. Ignore libCrun as
+    # -library=stlport4 depends on it.
+    case " $CXX $CXXFLAGS " in
+    *" -library=stlport4 "*)
+      solaris_use_stlport4=yes
+      ;;
+    esac
+
+    if test "$solaris_use_stlport4" != yes; then
+      postdeps_CXX='-library=Cstd -library=Crun'
+    fi
+    ;;
+  esac
+  ;;
+
+solaris*)
+  case $cc_basename in
+  CC* | sunCC*)
+    # The more standards-conforming stlport4 library is
+    # incompatible with the Cstd library. Avoid specifying
+    # it if it's in CXXFLAGS. Ignore libCrun as
+    # -library=stlport4 depends on it.
+    case " $CXX $CXXFLAGS " in
+    *" -library=stlport4 "*)
+      solaris_use_stlport4=yes
+      ;;
+    esac
+
+    # Adding this requires a known-good setup of shared libraries for
+    # Sun compiler versions before 5.6, else PIC objects from an old
+    # archive will be linked into the output, leading to subtle bugs.
+    if test "$solaris_use_stlport4" != yes; then
+      postdeps_CXX='-library=Cstd -library=Crun'
+    fi
+    ;;
+  esac
+  ;;
 esac
 
 
@@ -14044,7 +13516,7 @@ case " $postdeps_CXX " in
 esac
  compiler_lib_search_dirs_CXX=
 if test -n "${compiler_lib_search_path_CXX}"; then
- compiler_lib_search_dirs_CXX=`echo " ${compiler_lib_search_path_CXX}" | $SED -e 's! -L! !g' -e 's!^ !!'`
+ compiler_lib_search_dirs_CXX=`echo " ${compiler_lib_search_path_CXX}" | ${SED} -e 's! -L! !g' -e 's!^ !!'`
 fi
 
 
@@ -14083,18 +13555,17 @@ lt_prog_compiler_static_CXX=
 
 
   # C++ specific cases for pic, static, wl, etc.
-  if test yes = "$GXX"; then
+  if test "$GXX" = yes; then
     lt_prog_compiler_wl_CXX='-Wl,'
     lt_prog_compiler_static_CXX='-static'
 
     case $host_os in
     aix*)
       # All AIX code is PIC.
-      if test ia64 = "$host_cpu"; then
+      if test "$host_cpu" = ia64; then
 	# AIX 5 now supports IA64 processor
 	lt_prog_compiler_static_CXX='-Bstatic'
       fi
-      lt_prog_compiler_pic_CXX='-fPIC'
       ;;
 
     amigaos*)
@@ -14105,8 +13576,8 @@ lt_prog_compiler_static_CXX=
         ;;
       m68k)
             # FIXME: we need at least 68020 code to build shared libraries, but
-            # adding the '-m68020' flag to GCC prevents building anything better,
-            # like '-m68040'.
+            # adding the `-m68020' flag to GCC prevents building anything better,
+            # like `-m68040'.
             lt_prog_compiler_pic_CXX='-m68020 -resident32 -malways-restore-a4'
         ;;
       esac
@@ -14121,11 +13592,6 @@ lt_prog_compiler_static_CXX=
       # Although the cygwin gcc ignores -fPIC, still need this for old-style
       # (--disable-auto-import) libraries
       lt_prog_compiler_pic_CXX='-DDLL_EXPORT'
-      case $host_os in
-      os2*)
-	lt_prog_compiler_static_CXX='$wl-static'
-	;;
-      esac
       ;;
     darwin* | rhapsody*)
       # PIC is the default on this platform
@@ -14175,7 +13641,7 @@ lt_prog_compiler_static_CXX=
     case $host_os in
       aix[4-9]*)
 	# All AIX code is PIC.
-	if test ia64 = "$host_cpu"; then
+	if test "$host_cpu" = ia64; then
 	  # AIX 5 now supports IA64 processor
 	  lt_prog_compiler_static_CXX='-Bstatic'
 	else
@@ -14215,14 +13681,14 @@ lt_prog_compiler_static_CXX=
 	case $cc_basename in
 	  CC*)
 	    lt_prog_compiler_wl_CXX='-Wl,'
-	    lt_prog_compiler_static_CXX='$wl-a ${wl}archive'
-	    if test ia64 != "$host_cpu"; then
+	    lt_prog_compiler_static_CXX='${wl}-a ${wl}archive'
+	    if test "$host_cpu" != ia64; then
 	      lt_prog_compiler_pic_CXX='+Z'
 	    fi
 	    ;;
 	  aCC*)
 	    lt_prog_compiler_wl_CXX='-Wl,'
-	    lt_prog_compiler_static_CXX='$wl-a ${wl}archive'
+	    lt_prog_compiler_static_CXX='${wl}-a ${wl}archive'
 	    case $host_cpu in
 	    hppa*64*|ia64*)
 	      # +Z the default
@@ -14259,7 +13725,7 @@ lt_prog_compiler_static_CXX=
 	    lt_prog_compiler_pic_CXX='-fPIC'
 	    ;;
 	  ecpc* )
-	    # old Intel C++ for x86_64, which still supported -KPIC.
+	    # old Intel C++ for x86_64 which still supported -KPIC.
 	    lt_prog_compiler_wl_CXX='-Wl,'
 	    lt_prog_compiler_pic_CXX='-KPIC'
 	    lt_prog_compiler_static_CXX='-static'
@@ -14404,7 +13870,7 @@ lt_prog_compiler_static_CXX=
   fi
 
 case $host_os in
-  # For platforms that do not support PIC, -DPIC is meaningless:
+  # For platforms which do not support PIC, -DPIC is meaningless:
   *djgpp*)
     lt_prog_compiler_pic_CXX=
     ;;
@@ -14436,7 +13902,7 @@ else
   lt_cv_prog_compiler_pic_works_CXX=no
    ac_outfile=conftest.$ac_objext
    echo "$lt_simple_compile_test_code" > conftest.$ac_ext
-   lt_compiler_flag="$lt_prog_compiler_pic_CXX -DPIC"  ## exclude from sc_useless_quotes_in_assignment
+   lt_compiler_flag="$lt_prog_compiler_pic_CXX -DPIC"
    # Insert the option either (1) after the last *FLAGS variable, or
    # (2) before a word containing "conftest.", or (3) at the end.
    # Note that $ac_compile itself does not contain backslashes and begins
@@ -14466,7 +13932,7 @@ fi
 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_works_CXX" >&5
 $as_echo "$lt_cv_prog_compiler_pic_works_CXX" >&6; }
 
-if test yes = "$lt_cv_prog_compiler_pic_works_CXX"; then
+if test x"$lt_cv_prog_compiler_pic_works_CXX" = xyes; then
     case $lt_prog_compiler_pic_CXX in
      "" | " "*) ;;
      *) lt_prog_compiler_pic_CXX=" $lt_prog_compiler_pic_CXX" ;;
@@ -14492,7 +13958,7 @@ if ${lt_cv_prog_compiler_static_works_CXX+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   lt_cv_prog_compiler_static_works_CXX=no
-   save_LDFLAGS=$LDFLAGS
+   save_LDFLAGS="$LDFLAGS"
    LDFLAGS="$LDFLAGS $lt_tmp_static_flag"
    echo "$lt_simple_link_test_code" > conftest.$ac_ext
    if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then
@@ -14511,13 +13977,13 @@ else
      fi
    fi
    $RM -r conftest*
-   LDFLAGS=$save_LDFLAGS
+   LDFLAGS="$save_LDFLAGS"
 
 fi
 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_static_works_CXX" >&5
 $as_echo "$lt_cv_prog_compiler_static_works_CXX" >&6; }
 
-if test yes = "$lt_cv_prog_compiler_static_works_CXX"; then
+if test x"$lt_cv_prog_compiler_static_works_CXX" = xyes; then
     :
 else
     lt_prog_compiler_static_CXX=
@@ -14631,8 +14097,8 @@ $as_echo "$lt_cv_prog_compiler_c_o_CXX" >&6; }
 
 
 
-hard_links=nottested
-if test no = "$lt_cv_prog_compiler_c_o_CXX" && test no != "$need_locks"; then
+hard_links="nottested"
+if test "$lt_cv_prog_compiler_c_o_CXX" = no && test "$need_locks" != no; then
   # do not overwrite the value of need_locks provided by the user
   { $as_echo "$as_me:${as_lineno-$LINENO}: checking if we can lock with hard links" >&5
 $as_echo_n "checking if we can lock with hard links... " >&6; }
@@ -14644,9 +14110,9 @@ $as_echo_n "checking if we can lock with hard links... " >&6; }
   ln conftest.a conftest.b 2>/dev/null && hard_links=no
   { $as_echo "$as_me:${as_lineno-$LINENO}: result: $hard_links" >&5
 $as_echo "$hard_links" >&6; }
-  if test no = "$hard_links"; then
-    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: '$CC' does not support '-c -o', so 'make -j' may be unsafe" >&5
-$as_echo "$as_me: WARNING: '$CC' does not support '-c -o', so 'make -j' may be unsafe" >&2;}
+  if test "$hard_links" = no; then
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&5
+$as_echo "$as_me: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&2;}
     need_locks=warn
   fi
 else
@@ -14663,21 +14129,17 @@ $as_echo_n "checking whether the $compiler linker ($LD) supports shared librarie
   case $host_os in
   aix[4-9]*)
     # If we're using GNU nm, then we don't want the "-C" option.
-    # -C means demangle to GNU nm, but means don't demangle to AIX nm.
-    # Without the "-l" option, or with the "-B" option, AIX nm treats
-    # weak defined symbols like other global defined symbols, whereas
-    # GNU nm marks them as "W".
-    # While the 'weak' keyword is ignored in the Export File, we need
-    # it in the Import File for the 'aix-soname' feature, so we have
-    # to replace the "-B" option with "-P" for AIX nm.
+    # -C means demangle to AIX nm, but means don't demangle with GNU nm
+    # Also, AIX nm treats weak defined symbols like other global defined
+    # symbols, whereas GNU nm marks them as "W".
     if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then
-      export_symbols_cmds_CXX='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && (substr(\$ 3,1,1) != ".")) { if (\$ 2 == "W") { print \$ 3 " weak" } else { print \$ 3 } } }'\'' | sort -u > $export_symbols'
+      export_symbols_cmds_CXX='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols'
     else
-      export_symbols_cmds_CXX='`func_echo_all $NM | $SED -e '\''s/B\([^B]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && (substr(\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols'
+      export_symbols_cmds_CXX='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols'
     fi
     ;;
   pw32*)
-    export_symbols_cmds_CXX=$ltdll_cmds
+    export_symbols_cmds_CXX="$ltdll_cmds"
     ;;
   cygwin* | mingw* | cegcc*)
     case $cc_basename in
@@ -14700,7 +14162,7 @@ $as_echo_n "checking whether the $compiler linker ($LD) supports shared librarie
 
 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs_CXX" >&5
 $as_echo "$ld_shlibs_CXX" >&6; }
-test no = "$ld_shlibs_CXX" && can_build_shared=no
+test "$ld_shlibs_CXX" = no && can_build_shared=no
 
 with_gnu_ld_CXX=$with_gnu_ld
 
@@ -14717,7 +14179,7 @@ x|xyes)
   # Assume -lc should be added
   archive_cmds_need_lc_CXX=yes
 
-  if test yes,yes = "$GCC,$enable_shared"; then
+  if test "$enable_shared" = yes && test "$GCC" = yes; then
     case $archive_cmds_CXX in
     *'~'*)
       # FIXME: we may have to deal with multi-command sequences.
@@ -14845,7 +14307,7 @@ $as_echo_n "checking dynamic linker characteristics... " >&6; }
 library_names_spec=
 libname_spec='lib$name'
 soname_spec=
-shrext_cmds=.so
+shrext_cmds=".so"
 postinstall_cmds=
 postuninstall_cmds=
 finish_cmds=
@@ -14862,16 +14324,14 @@ hardcode_into_libs=no
 # flags to be left without arguments
 need_version=unknown
 
-
-
 case $host_os in
 aix3*)
   version_type=linux # correct to gnu/linux during the next big refactor
-  library_names_spec='$libname$release$shared_ext$versuffix $libname.a'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a'
   shlibpath_var=LIBPATH
 
   # AIX 3 has no versioning support, so we append a major version to the name.
-  soname_spec='$libname$release$shared_ext$major'
+  soname_spec='${libname}${release}${shared_ext}$major'
   ;;
 
 aix[4-9]*)
@@ -14879,91 +14339,41 @@ aix[4-9]*)
   need_lib_prefix=no
   need_version=no
   hardcode_into_libs=yes
-  if test ia64 = "$host_cpu"; then
+  if test "$host_cpu" = ia64; then
     # AIX 5 supports IA64
-    library_names_spec='$libname$release$shared_ext$major $libname$release$shared_ext$versuffix $libname$shared_ext'
+    library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}'
     shlibpath_var=LD_LIBRARY_PATH
   else
     # With GCC up to 2.95.x, collect2 would create an import file
     # for dependence libraries.  The import file would start with
-    # the line '#! .'.  This would cause the generated library to
-    # depend on '.', always an invalid library.  This was fixed in
+    # the line `#! .'.  This would cause the generated library to
+    # depend on `.', always an invalid library.  This was fixed in
     # development snapshots of GCC prior to 3.0.
     case $host_os in
       aix4 | aix4.[01] | aix4.[01].*)
       if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)'
 	   echo ' yes '
-	   echo '#endif'; } | $CC -E - | $GREP yes > /dev/null; then
+	   echo '#endif'; } | ${CC} -E - | $GREP yes > /dev/null; then
 	:
       else
 	can_build_shared=no
       fi
       ;;
     esac
-    # Using Import Files as archive members, it is possible to support
-    # filename-based versioning of shared library archives on AIX. While
-    # this would work for both with and without runtime linking, it will
-    # prevent static linking of such archives. So we do filename-based
-    # shared library versioning with .so extension only, which is used
-    # when both runtime linking and shared linking is enabled.
-    # Unfortunately, runtime linking may impact performance, so we do
-    # not want this to be the default eventually. Also, we use the
-    # versioned .so libs for executables only if there is the -brtl
-    # linker flag in LDFLAGS as well, or --with-aix-soname=svr4 only.
-    # To allow for filename-based versioning support, we need to create
-    # libNAME.so.V as an archive file, containing:
-    # *) an Import File, referring to the versioned filename of the
-    #    archive as well as the shared archive member, telling the
-    #    bitwidth (32 or 64) of that shared object, and providing the
-    #    list of exported symbols of that shared object, eventually
-    #    decorated with the 'weak' keyword
-    # *) the shared object with the F_LOADONLY flag set, to really avoid
-    #    it being seen by the linker.
-    # At run time we better use the real file rather than another symlink,
-    # but for link time we create the symlink libNAME.so -> libNAME.so.V
-
-    case $with_aix_soname,$aix_use_runtimelinking in
-    # AIX (on Power*) has no versioning support, so currently we cannot hardcode correct
+    # AIX (on Power*) has no versioning support, so currently we can not hardcode correct
     # soname into executable. Probably we can add versioning support to
     # collect2, so additional links can be useful in future.
-    aix,yes) # traditional libtool
-      dynamic_linker='AIX unversionable lib.so'
+    if test "$aix_use_runtimelinking" = yes; then
       # If using run time linking (on AIX 4.2 or later) use lib<name>.so
       # instead of lib<name>.a to let people know that these are not
       # typical AIX shared libraries.
-      library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
-      ;;
-    aix,no) # traditional AIX only
-      dynamic_linker='AIX lib.a(lib.so.V)'
+      library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+    else
       # We preserve .a as extension for shared libraries through AIX4.2
       # and later when we are not doing run time linking.
-      library_names_spec='$libname$release.a $libname.a'
-      soname_spec='$libname$release$shared_ext$major'
-      ;;
-    svr4,*) # full svr4 only
-      dynamic_linker="AIX lib.so.V($shared_archive_member_spec.o)"
-      library_names_spec='$libname$release$shared_ext$major $libname$shared_ext'
-      # We do not specify a path in Import Files, so LIBPATH fires.
-      shlibpath_overrides_runpath=yes
-      ;;
-    *,yes) # both, prefer svr4
-      dynamic_linker="AIX lib.so.V($shared_archive_member_spec.o), lib.a(lib.so.V)"
-      library_names_spec='$libname$release$shared_ext$major $libname$shared_ext'
-      # unpreferred sharedlib libNAME.a needs extra handling
-      postinstall_cmds='test -n "$linkname" || linkname="$realname"~func_stripname "" ".so" "$linkname"~$install_shared_prog "$dir/$func_stripname_result.$libext" "$destdir/$func_stripname_result.$libext"~test -z "$tstripme" || test -z "$striplib" || $striplib "$destdir/$func_stripname_result.$libext"'
-      postuninstall_cmds='for n in $library_names $old_library; do :; done~func_stripname "" ".so" "$n"~test "$func_stripname_result" = "$n" || func_append rmfiles " $odir/$func_stripname_result.$libext"'
-      # We do not specify a path in Import Files, so LIBPATH fires.
-      shlibpath_overrides_runpath=yes
-      ;;
-    *,no) # both, prefer aix
-      dynamic_linker="AIX lib.a(lib.so.V), lib.so.V($shared_archive_member_spec.o)"
-      library_names_spec='$libname$release.a $libname.a'
-      soname_spec='$libname$release$shared_ext$major'
-      # unpreferred sharedlib libNAME.so.V and symlink libNAME.so need extra handling
-      postinstall_cmds='test -z "$dlname" || $install_shared_prog $dir/$dlname $destdir/$dlname~test -z "$tstripme" || test -z "$striplib" || $striplib $destdir/$dlname~test -n "$linkname" || linkname=$realname~func_stripname "" ".a" "$linkname"~(cd "$destdir" && $LN_S -f $dlname $func_stripname_result.so)'
-      postuninstall_cmds='test -z "$dlname" || func_append rmfiles " $odir/$dlname"~for n in $old_library $library_names; do :; done~func_stripname "" ".a" "$n"~func_append rmfiles " $odir/$func_stripname_result.so"'
-      ;;
-    esac
+      library_names_spec='${libname}${release}.a $libname.a'
+      soname_spec='${libname}${release}${shared_ext}$major'
+    fi
     shlibpath_var=LIBPATH
   fi
   ;;
@@ -14973,18 +14383,18 @@ amigaos*)
   powerpc)
     # Since July 2007 AmigaOS4 officially supports .so libraries.
     # When compiling the executable, add -use-dynld -Lsobjs: to the compileline.
-    library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
     ;;
   m68k)
     library_names_spec='$libname.ixlibrary $libname.a'
     # Create ${libname}_ixlibrary.a entries in /sys/libs.
-    finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done'
+    finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done'
     ;;
   esac
   ;;
 
 beos*)
-  library_names_spec='$libname$shared_ext'
+  library_names_spec='${libname}${shared_ext}'
   dynamic_linker="$host_os ld.so"
   shlibpath_var=LIBRARY_PATH
   ;;
@@ -14992,8 +14402,8 @@ beos*)
 bsdi[45]*)
   version_type=linux # correct to gnu/linux during the next big refactor
   need_version=no
-  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
-  soname_spec='$libname$release$shared_ext$major'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
   finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir'
   shlibpath_var=LD_LIBRARY_PATH
   sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib"
@@ -15005,7 +14415,7 @@ bsdi[45]*)
 
 cygwin* | mingw* | pw32* | cegcc*)
   version_type=windows
-  shrext_cmds=.dll
+  shrext_cmds=".dll"
   need_version=no
   need_lib_prefix=no
 
@@ -15014,8 +14424,8 @@ cygwin* | mingw* | pw32* | cegcc*)
     # gcc
     library_names_spec='$libname.dll.a'
     # DLL is installed to $(libdir)/../bin by postinstall_cmds
-    postinstall_cmds='base_file=`basename \$file`~
-      dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~
+    postinstall_cmds='base_file=`basename \${file}`~
+      dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~
       dldir=$destdir/`dirname \$dlpath`~
       test -d \$dldir || mkdir -p \$dldir~
       $install_prog $dir/$dlname \$dldir/$dlname~
@@ -15031,16 +14441,16 @@ cygwin* | mingw* | pw32* | cegcc*)
     case $host_os in
     cygwin*)
       # Cygwin DLLs use 'cyg' prefix rather than 'lib'
-      soname_spec='`echo $libname | sed -e 's/^lib/cyg/'``echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext'
+      soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
 
       ;;
     mingw* | cegcc*)
       # MinGW DLLs use traditional 'lib' prefix
-      soname_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext'
+      soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
       ;;
     pw32*)
       # pw32 DLLs use 'pw' prefix rather than 'lib'
-      library_names_spec='`echo $libname | sed -e 's/^lib/pw/'``echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext'
+      library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
       ;;
     esac
     dynamic_linker='Win32 ld.exe'
@@ -15049,8 +14459,8 @@ cygwin* | mingw* | pw32* | cegcc*)
   *,cl*)
     # Native MSVC
     libname_spec='$name'
-    soname_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext'
-    library_names_spec='$libname.dll.lib'
+    soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
+    library_names_spec='${libname}.dll.lib'
 
     case $build_os in
     mingw*)
@@ -15077,7 +14487,7 @@ cygwin* | mingw* | pw32* | cegcc*)
       sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"`
       ;;
     *)
-      sys_lib_search_path_spec=$LIB
+      sys_lib_search_path_spec="$LIB"
       if $ECHO "$sys_lib_search_path_spec" | $GREP ';[c-zC-Z]:/' >/dev/null; then
         # It is most probably a Windows format PATH.
         sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'`
@@ -15090,8 +14500,8 @@ cygwin* | mingw* | pw32* | cegcc*)
     esac
 
     # DLL is installed to $(libdir)/../bin by postinstall_cmds
-    postinstall_cmds='base_file=`basename \$file`~
-      dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~
+    postinstall_cmds='base_file=`basename \${file}`~
+      dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~
       dldir=$destdir/`dirname \$dlpath`~
       test -d \$dldir || mkdir -p \$dldir~
       $install_prog $dir/$dlname \$dldir/$dlname'
@@ -15104,7 +14514,7 @@ cygwin* | mingw* | pw32* | cegcc*)
 
   *)
     # Assume MSVC wrapper
-    library_names_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext $libname.lib'
+    library_names_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext} $libname.lib'
     dynamic_linker='Win32 ld.exe'
     ;;
   esac
@@ -15117,8 +14527,8 @@ darwin* | rhapsody*)
   version_type=darwin
   need_lib_prefix=no
   need_version=no
-  library_names_spec='$libname$release$major$shared_ext $libname$shared_ext'
-  soname_spec='$libname$release$major$shared_ext'
+  library_names_spec='${libname}${release}${major}$shared_ext ${libname}$shared_ext'
+  soname_spec='${libname}${release}${major}$shared_ext'
   shlibpath_overrides_runpath=yes
   shlibpath_var=DYLD_LIBRARY_PATH
   shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`'
@@ -15130,8 +14540,8 @@ dgux*)
   version_type=linux # correct to gnu/linux during the next big refactor
   need_lib_prefix=no
   need_version=no
-  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
-  soname_spec='$libname$release$shared_ext$major'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext'
+  soname_spec='${libname}${release}${shared_ext}$major'
   shlibpath_var=LD_LIBRARY_PATH
   ;;
 
@@ -15149,13 +14559,12 @@ freebsd* | dragonfly*)
   version_type=freebsd-$objformat
   case $version_type in
     freebsd-elf*)
-      library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
-      soname_spec='$libname$release$shared_ext$major'
+      library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}'
       need_version=no
       need_lib_prefix=no
       ;;
     freebsd-*)
-      library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix'
+      library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix'
       need_version=yes
       ;;
   esac
@@ -15185,10 +14594,10 @@ haiku*)
   need_lib_prefix=no
   need_version=no
   dynamic_linker="$host_os runtime_loader"
-  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
-  soname_spec='$libname$release$shared_ext$major'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
   shlibpath_var=LIBRARY_PATH
-  shlibpath_overrides_runpath=no
+  shlibpath_overrides_runpath=yes
   sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib'
   hardcode_into_libs=yes
   ;;
@@ -15206,15 +14615,14 @@ hpux9* | hpux10* | hpux11*)
     dynamic_linker="$host_os dld.so"
     shlibpath_var=LD_LIBRARY_PATH
     shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
-    library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
-    soname_spec='$libname$release$shared_ext$major'
-    if test 32 = "$HPUX_IA64_MODE"; then
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+    soname_spec='${libname}${release}${shared_ext}$major'
+    if test "X$HPUX_IA64_MODE" = X32; then
       sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib"
-      sys_lib_dlsearch_path_spec=/usr/lib/hpux32
     else
       sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64"
-      sys_lib_dlsearch_path_spec=/usr/lib/hpux64
     fi
+    sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
     ;;
   hppa*64*)
     shrext_cmds='.sl'
@@ -15222,8 +14630,8 @@ hpux9* | hpux10* | hpux11*)
     dynamic_linker="$host_os dld.sl"
     shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH
     shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
-    library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
-    soname_spec='$libname$release$shared_ext$major'
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+    soname_spec='${libname}${release}${shared_ext}$major'
     sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64"
     sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
     ;;
@@ -15232,8 +14640,8 @@ hpux9* | hpux10* | hpux11*)
     dynamic_linker="$host_os dld.sl"
     shlibpath_var=SHLIB_PATH
     shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH
-    library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
-    soname_spec='$libname$release$shared_ext$major'
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+    soname_spec='${libname}${release}${shared_ext}$major'
     ;;
   esac
   # HP-UX runs *really* slowly unless shared libraries are mode 555, ...
@@ -15246,8 +14654,8 @@ interix[3-9]*)
   version_type=linux # correct to gnu/linux during the next big refactor
   need_lib_prefix=no
   need_version=no
-  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
-  soname_spec='$libname$release$shared_ext$major'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
   dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)'
   shlibpath_var=LD_LIBRARY_PATH
   shlibpath_overrides_runpath=no
@@ -15258,7 +14666,7 @@ irix5* | irix6* | nonstopux*)
   case $host_os in
     nonstopux*) version_type=nonstopux ;;
     *)
-	if test yes = "$lt_cv_prog_gnu_ld"; then
+	if test "$lt_cv_prog_gnu_ld" = yes; then
 		version_type=linux # correct to gnu/linux during the next big refactor
 	else
 		version_type=irix
@@ -15266,8 +14674,8 @@ irix5* | irix6* | nonstopux*)
   esac
   need_lib_prefix=no
   need_version=no
-  soname_spec='$libname$release$shared_ext$major'
-  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$release$shared_ext $libname$shared_ext'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}'
   case $host_os in
   irix5* | nonstopux*)
     libsuff= shlibsuff=
@@ -15286,8 +14694,8 @@ irix5* | irix6* | nonstopux*)
   esac
   shlibpath_var=LD_LIBRARY${shlibsuff}_PATH
   shlibpath_overrides_runpath=no
-  sys_lib_search_path_spec="/usr/lib$libsuff /lib$libsuff /usr/local/lib$libsuff"
-  sys_lib_dlsearch_path_spec="/usr/lib$libsuff /lib$libsuff"
+  sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}"
+  sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}"
   hardcode_into_libs=yes
   ;;
 
@@ -15296,33 +14704,13 @@ linux*oldld* | linux*aout* | linux*coff*)
   dynamic_linker=no
   ;;
 
-linux*android*)
-  version_type=none # Android doesn't support versioned libraries.
-  need_lib_prefix=no
-  need_version=no
-  library_names_spec='$libname$release$shared_ext'
-  soname_spec='$libname$release$shared_ext'
-  finish_cmds=
-  shlibpath_var=LD_LIBRARY_PATH
-  shlibpath_overrides_runpath=yes
-
-  # This implies no fast_install, which is unacceptable.
-  # Some rework will be needed to allow for fast_install
-  # before this can be enabled.
-  hardcode_into_libs=yes
-
-  dynamic_linker='Android linker'
-  # Don't embed -rpath directories since the linker doesn't support them.
-  hardcode_libdir_flag_spec_CXX='-L$libdir'
-  ;;
-
 # This must be glibc/ELF.
 linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*)
   version_type=linux # correct to gnu/linux during the next big refactor
   need_lib_prefix=no
   need_version=no
-  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
-  soname_spec='$libname$release$shared_ext$major'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
   finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir'
   shlibpath_var=LD_LIBRARY_PATH
   shlibpath_overrides_runpath=no
@@ -15366,12 +14754,7 @@ fi
   # before this can be enabled.
   hardcode_into_libs=yes
 
-  # Ideally, we could use ldconfig to report *all* directores which are
-  # searched for libraries, however this is still not possible.  Aside from not
-  # being certain /sbin/ldconfig is available, command
-  # 'ldconfig -N -X -v | grep ^/' on 64bit Fedora does not report /usr/lib64,
-  # even though it is searched at run-time.  Try to do the best guess by
-  # appending ld.so.conf contents (and includes) to the search path.
+  # Append ld.so.conf contents to the search path
   if test -f /etc/ld.so.conf; then
     lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[	 ]*hwcap[	 ]/d;s/[:,	]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '`
     sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra"
@@ -15403,12 +14786,12 @@ netbsd*)
   need_lib_prefix=no
   need_version=no
   if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
-    library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix'
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
     finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
     dynamic_linker='NetBSD (a.out) ld.so'
   else
-    library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
-    soname_spec='$libname$release$shared_ext$major'
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+    soname_spec='${libname}${release}${shared_ext}$major'
     dynamic_linker='NetBSD ld.elf_so'
   fi
   shlibpath_var=LD_LIBRARY_PATH
@@ -15418,7 +14801,7 @@ netbsd*)
 
 newsos6)
   version_type=linux # correct to gnu/linux during the next big refactor
-  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
   shlibpath_var=LD_LIBRARY_PATH
   shlibpath_overrides_runpath=yes
   ;;
@@ -15427,68 +14810,58 @@ newsos6)
   version_type=qnx
   need_lib_prefix=no
   need_version=no
-  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
-  soname_spec='$libname$release$shared_ext$major'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
   shlibpath_var=LD_LIBRARY_PATH
   shlibpath_overrides_runpath=no
   hardcode_into_libs=yes
   dynamic_linker='ldqnx.so'
   ;;
 
-openbsd* | bitrig*)
+openbsd*)
   version_type=sunos
-  sys_lib_dlsearch_path_spec=/usr/lib
+  sys_lib_dlsearch_path_spec="/usr/lib"
   need_lib_prefix=no
-  if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then
-    need_version=no
-  else
-    need_version=yes
-  fi
-  library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix'
+  # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs.
+  case $host_os in
+    openbsd3.3 | openbsd3.3.*)	need_version=yes ;;
+    *)				need_version=no  ;;
+  esac
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
   finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
   shlibpath_var=LD_LIBRARY_PATH
-  shlibpath_overrides_runpath=yes
+  if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+    case $host_os in
+      openbsd2.[89] | openbsd2.[89].*)
+	shlibpath_overrides_runpath=no
+	;;
+      *)
+	shlibpath_overrides_runpath=yes
+	;;
+      esac
+  else
+    shlibpath_overrides_runpath=yes
+  fi
   ;;
 
 os2*)
   libname_spec='$name'
-  version_type=windows
-  shrext_cmds=.dll
-  need_version=no
+  shrext_cmds=".dll"
   need_lib_prefix=no
-  # OS/2 can only load a DLL with a base name of 8 characters or less.
-  soname_spec='`test -n "$os2dllname" && libname="$os2dllname";
-    v=$($ECHO $release$versuffix | tr -d .-);
-    n=$($ECHO $libname | cut -b -$((8 - ${#v})) | tr . _);
-    $ECHO $n$v`$shared_ext'
-  library_names_spec='${libname}_dll.$libext'
+  library_names_spec='$libname${shared_ext} $libname.a'
   dynamic_linker='OS/2 ld.exe'
-  shlibpath_var=BEGINLIBPATH
-  sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib"
-  sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
-  postinstall_cmds='base_file=`basename \$file`~
-    dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; $ECHO \$dlname'\''`~
-    dldir=$destdir/`dirname \$dlpath`~
-    test -d \$dldir || mkdir -p \$dldir~
-    $install_prog $dir/$dlname \$dldir/$dlname~
-    chmod a+x \$dldir/$dlname~
-    if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then
-      eval '\''$striplib \$dldir/$dlname'\'' || exit \$?;
-    fi'
-  postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; $ECHO \$dlname'\''`~
-    dlpath=$dir/\$dldll~
-    $RM \$dlpath'
+  shlibpath_var=LIBPATH
   ;;
 
 osf3* | osf4* | osf5*)
   version_type=osf
   need_lib_prefix=no
   need_version=no
-  soname_spec='$libname$release$shared_ext$major'
-  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
   shlibpath_var=LD_LIBRARY_PATH
   sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib"
-  sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
+  sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec"
   ;;
 
 rdos*)
@@ -15499,8 +14872,8 @@ solaris*)
   version_type=linux # correct to gnu/linux during the next big refactor
   need_lib_prefix=no
   need_version=no
-  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
-  soname_spec='$libname$release$shared_ext$major'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
   shlibpath_var=LD_LIBRARY_PATH
   shlibpath_overrides_runpath=yes
   hardcode_into_libs=yes
@@ -15510,11 +14883,11 @@ solaris*)
 
 sunos4*)
   version_type=sunos
-  library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
   finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir'
   shlibpath_var=LD_LIBRARY_PATH
   shlibpath_overrides_runpath=yes
-  if test yes = "$with_gnu_ld"; then
+  if test "$with_gnu_ld" = yes; then
     need_lib_prefix=no
   fi
   need_version=yes
@@ -15522,8 +14895,8 @@ sunos4*)
 
 sysv4 | sysv4.3*)
   version_type=linux # correct to gnu/linux during the next big refactor
-  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
-  soname_spec='$libname$release$shared_ext$major'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
   shlibpath_var=LD_LIBRARY_PATH
   case $host_vendor in
     sni)
@@ -15544,24 +14917,24 @@ sysv4 | sysv4.3*)
   ;;
 
 sysv4*MP*)
-  if test -d /usr/nec; then
+  if test -d /usr/nec ;then
     version_type=linux # correct to gnu/linux during the next big refactor
-    library_names_spec='$libname$shared_ext.$versuffix $libname$shared_ext.$major $libname$shared_ext'
-    soname_spec='$libname$shared_ext.$major'
+    library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}'
+    soname_spec='$libname${shared_ext}.$major'
     shlibpath_var=LD_LIBRARY_PATH
   fi
   ;;
 
 sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
-  version_type=sco
+  version_type=freebsd-elf
   need_lib_prefix=no
   need_version=no
-  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext $libname$shared_ext'
-  soname_spec='$libname$release$shared_ext$major'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
   shlibpath_var=LD_LIBRARY_PATH
   shlibpath_overrides_runpath=yes
   hardcode_into_libs=yes
-  if test yes = "$with_gnu_ld"; then
+  if test "$with_gnu_ld" = yes; then
     sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib'
   else
     sys_lib_search_path_spec='/usr/ccs/lib /usr/lib'
@@ -15579,7 +14952,7 @@ tpf*)
   version_type=linux # correct to gnu/linux during the next big refactor
   need_lib_prefix=no
   need_version=no
-  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
   shlibpath_var=LD_LIBRARY_PATH
   shlibpath_overrides_runpath=no
   hardcode_into_libs=yes
@@ -15587,8 +14960,8 @@ tpf*)
 
 uts4*)
   version_type=linux # correct to gnu/linux during the next big refactor
-  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
-  soname_spec='$libname$release$shared_ext$major'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
   shlibpath_var=LD_LIBRARY_PATH
   ;;
 
@@ -15598,32 +14971,20 @@ uts4*)
 esac
 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $dynamic_linker" >&5
 $as_echo "$dynamic_linker" >&6; }
-test no = "$dynamic_linker" && can_build_shared=no
+test "$dynamic_linker" = no && can_build_shared=no
 
 variables_saved_for_relink="PATH $shlibpath_var $runpath_var"
-if test yes = "$GCC"; then
+if test "$GCC" = yes; then
   variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH"
 fi
 
-if test set = "${lt_cv_sys_lib_search_path_spec+set}"; then
-  sys_lib_search_path_spec=$lt_cv_sys_lib_search_path_spec
+if test "${lt_cv_sys_lib_search_path_spec+set}" = set; then
+  sys_lib_search_path_spec="$lt_cv_sys_lib_search_path_spec"
 fi
-
-if test set = "${lt_cv_sys_lib_dlsearch_path_spec+set}"; then
-  sys_lib_dlsearch_path_spec=$lt_cv_sys_lib_dlsearch_path_spec
+if test "${lt_cv_sys_lib_dlsearch_path_spec+set}" = set; then
+  sys_lib_dlsearch_path_spec="$lt_cv_sys_lib_dlsearch_path_spec"
 fi
 
-# remember unaugmented sys_lib_dlsearch_path content for libtool script decls...
-configure_time_dlsearch_path=$sys_lib_dlsearch_path_spec
-
-# ... but it needs LT_SYS_LIBRARY_PATH munging for other configure-time code
-func_munge_path_list sys_lib_dlsearch_path_spec "$LT_SYS_LIBRARY_PATH"
-
-# to be used as default LT_SYS_LIBRARY_PATH value in generated libtool
-configure_time_lt_sys_library_path=$LT_SYS_LIBRARY_PATH
-
-
-
 
 
 
@@ -15666,15 +15027,15 @@ $as_echo_n "checking how to hardcode library paths into programs... " >&6; }
 hardcode_action_CXX=
 if test -n "$hardcode_libdir_flag_spec_CXX" ||
    test -n "$runpath_var_CXX" ||
-   test yes = "$hardcode_automatic_CXX"; then
+   test "X$hardcode_automatic_CXX" = "Xyes" ; then
 
   # We can hardcode non-existent directories.
-  if test no != "$hardcode_direct_CXX" &&
+  if test "$hardcode_direct_CXX" != no &&
      # If the only mechanism to avoid hardcoding is shlibpath_var, we
      # have to relink, otherwise we might link with an installed library
      # when we should be linking with a yet-to-be-installed one
-     ## test no != "$_LT_TAGVAR(hardcode_shlibpath_var, CXX)" &&
-     test no != "$hardcode_minus_L_CXX"; then
+     ## test "$_LT_TAGVAR(hardcode_shlibpath_var, CXX)" != no &&
+     test "$hardcode_minus_L_CXX" != no; then
     # Linking always hardcodes the temporary library directory.
     hardcode_action_CXX=relink
   else
@@ -15689,12 +15050,12 @@ fi
 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $hardcode_action_CXX" >&5
 $as_echo "$hardcode_action_CXX" >&6; }
 
-if test relink = "$hardcode_action_CXX" ||
-   test yes = "$inherit_rpath_CXX"; then
+if test "$hardcode_action_CXX" = relink ||
+   test "$inherit_rpath_CXX" = yes; then
   # Fast installation is not supported
   enable_fast_install=no
-elif test yes = "$shlibpath_overrides_runpath" ||
-     test no = "$enable_shared"; then
+elif test "$shlibpath_overrides_runpath" = yes ||
+     test "$enable_shared" = no; then
   # Fast installation is not necessary
   enable_fast_install=needless
 fi
@@ -15717,7 +15078,7 @@ fi
   lt_cv_path_LD=$lt_save_path_LD
   lt_cv_prog_gnu_ldcxx=$lt_cv_prog_gnu_ld
   lt_cv_prog_gnu_ld=$lt_save_with_gnu_ld
-fi # test yes != "$_lt_caught_CXX_error"
+fi # test "$_lt_caught_CXX_error" != yes
 
 ac_ext=cpp
 ac_cpp='$CXXCPP $CPPFLAGS'
@@ -17125,7 +16486,6 @@ enable_shared='`$ECHO "$enable_shared" | $SED "$delay_single_quote_subst"`'
 enable_static='`$ECHO "$enable_static" | $SED "$delay_single_quote_subst"`'
 pic_mode='`$ECHO "$pic_mode" | $SED "$delay_single_quote_subst"`'
 enable_fast_install='`$ECHO "$enable_fast_install" | $SED "$delay_single_quote_subst"`'
-shared_archive_member_spec='`$ECHO "$shared_archive_member_spec" | $SED "$delay_single_quote_subst"`'
 SHELL='`$ECHO "$SHELL" | $SED "$delay_single_quote_subst"`'
 ECHO='`$ECHO "$ECHO" | $SED "$delay_single_quote_subst"`'
 PATH_SEPARATOR='`$ECHO "$PATH_SEPARATOR" | $SED "$delay_single_quote_subst"`'
@@ -17175,13 +16535,10 @@ compiler='`$ECHO "$compiler" | $SED "$delay_single_quote_subst"`'
 GCC='`$ECHO "$GCC" | $SED "$delay_single_quote_subst"`'
 lt_cv_sys_global_symbol_pipe='`$ECHO "$lt_cv_sys_global_symbol_pipe" | $SED "$delay_single_quote_subst"`'
 lt_cv_sys_global_symbol_to_cdecl='`$ECHO "$lt_cv_sys_global_symbol_to_cdecl" | $SED "$delay_single_quote_subst"`'
-lt_cv_sys_global_symbol_to_import='`$ECHO "$lt_cv_sys_global_symbol_to_import" | $SED "$delay_single_quote_subst"`'
 lt_cv_sys_global_symbol_to_c_name_address='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address" | $SED "$delay_single_quote_subst"`'
 lt_cv_sys_global_symbol_to_c_name_address_lib_prefix='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address_lib_prefix" | $SED "$delay_single_quote_subst"`'
-lt_cv_nm_interface='`$ECHO "$lt_cv_nm_interface" | $SED "$delay_single_quote_subst"`'
 nm_file_list_spec='`$ECHO "$nm_file_list_spec" | $SED "$delay_single_quote_subst"`'
 lt_sysroot='`$ECHO "$lt_sysroot" | $SED "$delay_single_quote_subst"`'
-lt_cv_truncate_bin='`$ECHO "$lt_cv_truncate_bin" | $SED "$delay_single_quote_subst"`'
 objdir='`$ECHO "$objdir" | $SED "$delay_single_quote_subst"`'
 MAGIC_CMD='`$ECHO "$MAGIC_CMD" | $SED "$delay_single_quote_subst"`'
 lt_prog_compiler_no_builtin_flag='`$ECHO "$lt_prog_compiler_no_builtin_flag" | $SED "$delay_single_quote_subst"`'
@@ -17246,8 +16603,7 @@ finish_cmds='`$ECHO "$finish_cmds" | $SED "$delay_single_quote_subst"`'
 finish_eval='`$ECHO "$finish_eval" | $SED "$delay_single_quote_subst"`'
 hardcode_into_libs='`$ECHO "$hardcode_into_libs" | $SED "$delay_single_quote_subst"`'
 sys_lib_search_path_spec='`$ECHO "$sys_lib_search_path_spec" | $SED "$delay_single_quote_subst"`'
-configure_time_dlsearch_path='`$ECHO "$configure_time_dlsearch_path" | $SED "$delay_single_quote_subst"`'
-configure_time_lt_sys_library_path='`$ECHO "$configure_time_lt_sys_library_path" | $SED "$delay_single_quote_subst"`'
+sys_lib_dlsearch_path_spec='`$ECHO "$sys_lib_dlsearch_path_spec" | $SED "$delay_single_quote_subst"`'
 hardcode_action='`$ECHO "$hardcode_action" | $SED "$delay_single_quote_subst"`'
 enable_dlopen='`$ECHO "$enable_dlopen" | $SED "$delay_single_quote_subst"`'
 enable_dlopen_self='`$ECHO "$enable_dlopen_self" | $SED "$delay_single_quote_subst"`'
@@ -17352,12 +16708,9 @@ CFLAGS \
 compiler \
 lt_cv_sys_global_symbol_pipe \
 lt_cv_sys_global_symbol_to_cdecl \
-lt_cv_sys_global_symbol_to_import \
 lt_cv_sys_global_symbol_to_c_name_address \
 lt_cv_sys_global_symbol_to_c_name_address_lib_prefix \
-lt_cv_nm_interface \
 nm_file_list_spec \
-lt_cv_truncate_bin \
 lt_prog_compiler_no_builtin_flag \
 lt_prog_compiler_pic \
 lt_prog_compiler_wl \
@@ -17423,7 +16776,7 @@ postdeps_CXX \
 compiler_lib_search_path_CXX; do
     case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in
     *[\\\\\\\`\\"\\\$]*)
-      eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$sed_quote_subst\\"\\\`\\\\\\"" ## exclude from sc_prohibit_nested_quotes
+      eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$sed_quote_subst\\"\\\`\\\\\\""
       ;;
     *)
       eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\""
@@ -17450,8 +16803,7 @@ postinstall_cmds \
 postuninstall_cmds \
 finish_cmds \
 sys_lib_search_path_spec \
-configure_time_dlsearch_path \
-configure_time_lt_sys_library_path \
+sys_lib_dlsearch_path_spec \
 reload_cmds_CXX \
 old_archive_cmds_CXX \
 old_archive_from_new_cmds_CXX \
@@ -17465,7 +16817,7 @@ prelink_cmds_CXX \
 postlink_cmds_CXX; do
     case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in
     *[\\\\\\\`\\"\\\$]*)
-      eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\"" ## exclude from sc_prohibit_nested_quotes
+      eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\""
       ;;
     *)
       eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\""
@@ -17474,16 +16826,19 @@ postlink_cmds_CXX; do
 done
 
 ac_aux_dir='$ac_aux_dir'
+xsi_shell='$xsi_shell'
+lt_shell_append='$lt_shell_append'
 
-# See if we are running on zsh, and set the options that allow our
+# See if we are running on zsh, and set the options which allow our
 # commands through without removal of \ escapes INIT.
-if test -n "\${ZSH_VERSION+set}"; then
+if test -n "\${ZSH_VERSION+set}" ; then
    setopt NO_GLOB_SUBST
 fi
 
 
     PACKAGE='$PACKAGE'
     VERSION='$VERSION'
+    TIMESTAMP='$TIMESTAMP'
     RM='$RM'
     ofile='$ofile'
 
@@ -18196,53 +17551,55 @@ $as_echo X"$file" |
  ;;
     "libtool":C)
 
-    # See if we are running on zsh, and set the options that allow our
+    # See if we are running on zsh, and set the options which allow our
     # commands through without removal of \ escapes.
-    if test -n "${ZSH_VERSION+set}"; then
+    if test -n "${ZSH_VERSION+set}" ; then
       setopt NO_GLOB_SUBST
     fi
 
-    cfgfile=${ofile}T
+    cfgfile="${ofile}T"
     trap "$RM \"$cfgfile\"; exit 1" 1 2 15
     $RM "$cfgfile"
 
     cat <<_LT_EOF >> "$cfgfile"
 #! $SHELL
-# Generated automatically by $as_me ($PACKAGE) $VERSION
+
+# `$ECHO "$ofile" | sed 's%^.*/%%'` - Provide generalized library-building support services.
+# Generated automatically by $as_me ($PACKAGE$TIMESTAMP) $VERSION
 # Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
 # NOTE: Changes made to this file will be lost: look at ltmain.sh.
-
-# Provide generalized library-building support services.
-# Written by Gordon Matzigkeit, 1996
-
-# Copyright (C) 2014 Free Software Foundation, Inc.
-# This is free software; see the source for copying conditions.  There is NO
-# warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-
-# GNU Libtool is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of of the License, or
-# (at your option) any later version.
 #
-# As a special exception to the GNU General Public License, if you
-# distribute this file as part of a program or library that is built
-# using GNU Libtool, you may include this file under the  same
-# distribution terms that you use for the rest of that program.
+#   Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005,
+#                 2006, 2007, 2008, 2009, 2010, 2011 Free Software
+#                 Foundation, Inc.
+#   Written by Gordon Matzigkeit, 1996
+#
+#   This file is part of GNU Libtool.
 #
-# GNU Libtool is distributed in the hope that it will be useful, but
-# WITHOUT ANY WARRANTY; without even the implied warranty of
+# GNU Libtool is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2 of
+# the License, or (at your option) any later version.
+#
+# As a special exception to the GNU General Public License,
+# if you distribute this file as part of a program or library that
+# is built using GNU Libtool, you may include this file under the
+# same distribution terms that you use for the rest of that program.
+#
+# GNU Libtool is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 # GNU General Public License for more details.
 #
 # You should have received a copy of the GNU General Public License
-# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+# along with GNU Libtool; see the file COPYING.  If not, a copy
+# can be downloaded from http://www.gnu.org/licenses/gpl.html, or
+# obtained by writing to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 
 
 # The names of the tagged configurations supported by this script.
-available_tags='CXX '
-
-# Configured defaults for sys_lib_dlsearch_path munging.
-: \${LT_SYS_LIBRARY_PATH="$configure_time_lt_sys_library_path"}
+available_tags="CXX "
 
 # ### BEGIN LIBTOOL CONFIG
 
@@ -18262,9 +17619,6 @@ pic_mode=$pic_mode
 # Whether or not to optimize for fast installation.
 fast_install=$enable_fast_install
 
-# Shared archive member basename,for filename based shared library versioning on AIX.
-shared_archive_member_spec=$shared_archive_member_spec
-
 # Shell to use when invoking shell scripts.
 SHELL=$lt_SHELL
 
@@ -18382,27 +17736,18 @@ global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe
 # Transform the output of nm in a proper C declaration.
 global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl
 
-# Transform the output of nm into a list of symbols to manually relocate.
-global_symbol_to_import=$lt_lt_cv_sys_global_symbol_to_import
-
 # Transform the output of nm in a C name address pair.
 global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address
 
 # Transform the output of nm in a C name address pair when lib prefix is needed.
 global_symbol_to_c_name_address_lib_prefix=$lt_lt_cv_sys_global_symbol_to_c_name_address_lib_prefix
 
-# The name lister interface.
-nm_interface=$lt_lt_cv_nm_interface
-
 # Specify filename containing input files for \$NM.
 nm_file_list_spec=$lt_nm_file_list_spec
 
-# The root where to search for dependent libraries,and where our libraries should be installed.
+# The root where to search for dependent libraries,and in which our libraries should be installed.
 lt_sysroot=$lt_sysroot
 
-# Command to truncate a binary pipe.
-lt_truncate_bin=$lt_lt_cv_truncate_bin
-
 # The name of the directory that contains temporary libtool files.
 objdir=$objdir
 
@@ -18493,11 +17838,8 @@ hardcode_into_libs=$hardcode_into_libs
 # Compile-time system search path for libraries.
 sys_lib_search_path_spec=$lt_sys_lib_search_path_spec
 
-# Detected run-time system search path for libraries.
-sys_lib_dlsearch_path_spec=$lt_configure_time_dlsearch_path
-
-# Explicit LT_SYS_LIBRARY_PATH set during ./configure time.
-configure_time_lt_sys_library_path=$lt_configure_time_lt_sys_library_path
+# Run-time system search path for libraries.
+sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec
 
 # Whether dlopen is supported.
 dlopen_support=$enable_dlopen
@@ -18590,13 +17932,13 @@ hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec
 # Whether we need a single "-rpath" flag with a separated argument.
 hardcode_libdir_separator=$lt_hardcode_libdir_separator
 
-# Set to "yes" if using DIR/libNAME\$shared_ext during linking hardcodes
+# Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes
 # DIR into the resulting binary.
 hardcode_direct=$hardcode_direct
 
-# Set to "yes" if using DIR/libNAME\$shared_ext during linking hardcodes
+# Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes
 # DIR into the resulting binary and the resulting library dependency is
-# "absolute",i.e impossible to change by setting \$shlibpath_var if the
+# "absolute",i.e impossible to change by setting \${shlibpath_var} if the
 # library is relocated.
 hardcode_direct_absolute=$hardcode_direct_absolute
 
@@ -18662,72 +18004,13 @@ compiler_lib_search_path=$lt_compiler_lib_search_path
 
 _LT_EOF
 
-    cat <<'_LT_EOF' >> "$cfgfile"
-
-# ### BEGIN FUNCTIONS SHARED WITH CONFIGURE
-
-# func_munge_path_list VARIABLE PATH
-# -----------------------------------
-# VARIABLE is name of variable containing _space_ separated list of
-# directories to be munged by the contents of PATH, which is string
-# having a format:
-# "DIR[:DIR]:"
-#       string "DIR[ DIR]" will be prepended to VARIABLE
-# ":DIR[:DIR]"
-#       string "DIR[ DIR]" will be appended to VARIABLE
-# "DIRP[:DIRP]::[DIRA:]DIRA"
-#       string "DIRP[ DIRP]" will be prepended to VARIABLE and string
-#       "DIRA[ DIRA]" will be appended to VARIABLE
-# "DIR[:DIR]"
-#       VARIABLE will be replaced by "DIR[ DIR]"
-func_munge_path_list ()
-{
-    case x$2 in
-    x)
-        ;;
-    *:)
-        eval $1=\"`$ECHO $2 | $SED 's/:/ /g'` \$$1\"
-        ;;
-    x:*)
-        eval $1=\"\$$1 `$ECHO $2 | $SED 's/:/ /g'`\"
-        ;;
-    *::*)
-        eval $1=\"\$$1\ `$ECHO $2 | $SED -e 's/.*:://' -e 's/:/ /g'`\"
-        eval $1=\"`$ECHO $2 | $SED -e 's/::.*//' -e 's/:/ /g'`\ \$$1\"
-        ;;
-    *)
-        eval $1=\"`$ECHO $2 | $SED 's/:/ /g'`\"
-        ;;
-    esac
-}
-
-
-# Calculate cc_basename.  Skip known compiler wrappers and cross-prefix.
-func_cc_basename ()
-{
-    for cc_temp in $*""; do
-      case $cc_temp in
-        compile | *[\\/]compile | ccache | *[\\/]ccache ) ;;
-        distcc | *[\\/]distcc | purify | *[\\/]purify ) ;;
-        \-*) ;;
-        *) break;;
-      esac
-    done
-    func_cc_basename_result=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"`
-}
-
-
-# ### END FUNCTIONS SHARED WITH CONFIGURE
-
-_LT_EOF
-
   case $host_os in
   aix3*)
     cat <<\_LT_EOF >> "$cfgfile"
 # AIX sometimes has problems with the GCC collect2 program.  For some
 # reason, if we set the COLLECT_NAMES environment variable, the problems
 # vanish in a puff of smoke.
-if test set != "${COLLECT_NAMES+set}"; then
+if test "X${COLLECT_NAMES+set}" != Xset; then
   COLLECT_NAMES=
   export COLLECT_NAMES
 fi
@@ -18736,7 +18019,7 @@ _LT_EOF
   esac
 
 
-ltmain=$ac_aux_dir/ltmain.sh
+ltmain="$ac_aux_dir/ltmain.sh"
 
 
   # We use sed instead of cat because bash on DJGPP gets confused if
@@ -18746,6 +18029,165 @@ ltmain=$ac_aux_dir/ltmain.sh
   sed '$q' "$ltmain" >> "$cfgfile" \
      || (rm -f "$cfgfile"; exit 1)
 
+  if test x"$xsi_shell" = xyes; then
+  sed -e '/^func_dirname ()$/,/^} # func_dirname /c\
+func_dirname ()\
+{\
+\    case ${1} in\
+\      */*) func_dirname_result="${1%/*}${2}" ;;\
+\      *  ) func_dirname_result="${3}" ;;\
+\    esac\
+} # Extended-shell func_dirname implementation' "$cfgfile" > $cfgfile.tmp \
+  && mv -f "$cfgfile.tmp" "$cfgfile" \
+    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+  sed -e '/^func_basename ()$/,/^} # func_basename /c\
+func_basename ()\
+{\
+\    func_basename_result="${1##*/}"\
+} # Extended-shell func_basename implementation' "$cfgfile" > $cfgfile.tmp \
+  && mv -f "$cfgfile.tmp" "$cfgfile" \
+    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+  sed -e '/^func_dirname_and_basename ()$/,/^} # func_dirname_and_basename /c\
+func_dirname_and_basename ()\
+{\
+\    case ${1} in\
+\      */*) func_dirname_result="${1%/*}${2}" ;;\
+\      *  ) func_dirname_result="${3}" ;;\
+\    esac\
+\    func_basename_result="${1##*/}"\
+} # Extended-shell func_dirname_and_basename implementation' "$cfgfile" > $cfgfile.tmp \
+  && mv -f "$cfgfile.tmp" "$cfgfile" \
+    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+  sed -e '/^func_stripname ()$/,/^} # func_stripname /c\
+func_stripname ()\
+{\
+\    # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are\
+\    # positional parameters, so assign one to ordinary parameter first.\
+\    func_stripname_result=${3}\
+\    func_stripname_result=${func_stripname_result#"${1}"}\
+\    func_stripname_result=${func_stripname_result%"${2}"}\
+} # Extended-shell func_stripname implementation' "$cfgfile" > $cfgfile.tmp \
+  && mv -f "$cfgfile.tmp" "$cfgfile" \
+    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+  sed -e '/^func_split_long_opt ()$/,/^} # func_split_long_opt /c\
+func_split_long_opt ()\
+{\
+\    func_split_long_opt_name=${1%%=*}\
+\    func_split_long_opt_arg=${1#*=}\
+} # Extended-shell func_split_long_opt implementation' "$cfgfile" > $cfgfile.tmp \
+  && mv -f "$cfgfile.tmp" "$cfgfile" \
+    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+  sed -e '/^func_split_short_opt ()$/,/^} # func_split_short_opt /c\
+func_split_short_opt ()\
+{\
+\    func_split_short_opt_arg=${1#??}\
+\    func_split_short_opt_name=${1%"$func_split_short_opt_arg"}\
+} # Extended-shell func_split_short_opt implementation' "$cfgfile" > $cfgfile.tmp \
+  && mv -f "$cfgfile.tmp" "$cfgfile" \
+    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+  sed -e '/^func_lo2o ()$/,/^} # func_lo2o /c\
+func_lo2o ()\
+{\
+\    case ${1} in\
+\      *.lo) func_lo2o_result=${1%.lo}.${objext} ;;\
+\      *)    func_lo2o_result=${1} ;;\
+\    esac\
+} # Extended-shell func_lo2o implementation' "$cfgfile" > $cfgfile.tmp \
+  && mv -f "$cfgfile.tmp" "$cfgfile" \
+    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+  sed -e '/^func_xform ()$/,/^} # func_xform /c\
+func_xform ()\
+{\
+    func_xform_result=${1%.*}.lo\
+} # Extended-shell func_xform implementation' "$cfgfile" > $cfgfile.tmp \
+  && mv -f "$cfgfile.tmp" "$cfgfile" \
+    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+  sed -e '/^func_arith ()$/,/^} # func_arith /c\
+func_arith ()\
+{\
+    func_arith_result=$(( $* ))\
+} # Extended-shell func_arith implementation' "$cfgfile" > $cfgfile.tmp \
+  && mv -f "$cfgfile.tmp" "$cfgfile" \
+    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+  sed -e '/^func_len ()$/,/^} # func_len /c\
+func_len ()\
+{\
+    func_len_result=${#1}\
+} # Extended-shell func_len implementation' "$cfgfile" > $cfgfile.tmp \
+  && mv -f "$cfgfile.tmp" "$cfgfile" \
+    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+fi
+
+if test x"$lt_shell_append" = xyes; then
+  sed -e '/^func_append ()$/,/^} # func_append /c\
+func_append ()\
+{\
+    eval "${1}+=\\${2}"\
+} # Extended-shell func_append implementation' "$cfgfile" > $cfgfile.tmp \
+  && mv -f "$cfgfile.tmp" "$cfgfile" \
+    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+  sed -e '/^func_append_quoted ()$/,/^} # func_append_quoted /c\
+func_append_quoted ()\
+{\
+\    func_quote_for_eval "${2}"\
+\    eval "${1}+=\\\\ \\$func_quote_for_eval_result"\
+} # Extended-shell func_append_quoted implementation' "$cfgfile" > $cfgfile.tmp \
+  && mv -f "$cfgfile.tmp" "$cfgfile" \
+    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+  # Save a `func_append' function call where possible by direct use of '+='
+  sed -e 's%func_append \([a-zA-Z_]\{1,\}\) "%\1+="%g' $cfgfile > $cfgfile.tmp \
+    && mv -f "$cfgfile.tmp" "$cfgfile" \
+      || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+  test 0 -eq $? || _lt_function_replace_fail=:
+else
+  # Save a `func_append' function call even when '+=' is not available
+  sed -e 's%func_append \([a-zA-Z_]\{1,\}\) "%\1="$\1%g' $cfgfile > $cfgfile.tmp \
+    && mv -f "$cfgfile.tmp" "$cfgfile" \
+      || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+  test 0 -eq $? || _lt_function_replace_fail=:
+fi
+
+if test x"$_lt_function_replace_fail" = x":"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Unable to substitute extended shell functions in $ofile" >&5
+$as_echo "$as_me: WARNING: Unable to substitute extended shell functions in $ofile" >&2;}
+fi
+
+
    mv -f "$cfgfile" "$ofile" ||
     (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile")
   chmod +x "$ofile"
@@ -18832,13 +18274,13 @@ hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec_CXX
 # Whether we need a single "-rpath" flag with a separated argument.
 hardcode_libdir_separator=$lt_hardcode_libdir_separator_CXX
 
-# Set to "yes" if using DIR/libNAME\$shared_ext during linking hardcodes
+# Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes
 # DIR into the resulting binary.
 hardcode_direct=$hardcode_direct_CXX
 
-# Set to "yes" if using DIR/libNAME\$shared_ext during linking hardcodes
+# Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes
 # DIR into the resulting binary and the resulting library dependency is
-# "absolute",i.e impossible to change by setting \$shlibpath_var if the
+# "absolute",i.e impossible to change by setting \${shlibpath_var} if the
 # library is relocated.
 hardcode_direct_absolute=$hardcode_direct_absolute_CXX
 
diff --git a/src/gmock/gtest/m4/libtool.m4 b/src/gmock/gtest/m4/libtool.m4
index 10ab284..d7c043f 100644
--- a/src/gmock/gtest/m4/libtool.m4
+++ b/src/gmock/gtest/m4/libtool.m4
@@ -1,6 +1,8 @@
 # libtool.m4 - Configure libtool for the host system. -*-Autoconf-*-
 #
-#   Copyright (C) 1996-2001, 2003-2015 Free Software Foundation, Inc.
+#   Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005,
+#                 2006, 2007, 2008, 2009, 2010, 2011 Free Software
+#                 Foundation, Inc.
 #   Written by Gordon Matzigkeit, 1996
 #
 # This file is free software; the Free Software Foundation gives
@@ -8,30 +10,36 @@
 # modifications, as long as this notice is preserved.
 
 m4_define([_LT_COPYING], [dnl
-# Copyright (C) 2014 Free Software Foundation, Inc.
-# This is free software; see the source for copying conditions.  There is NO
-# warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-
-# GNU Libtool is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of of the License, or
-# (at your option) any later version.
+#   Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005,
+#                 2006, 2007, 2008, 2009, 2010, 2011 Free Software
+#                 Foundation, Inc.
+#   Written by Gordon Matzigkeit, 1996
+#
+#   This file is part of GNU Libtool.
+#
+# GNU Libtool is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2 of
+# the License, or (at your option) any later version.
 #
-# As a special exception to the GNU General Public License, if you
-# distribute this file as part of a program or library that is built
-# using GNU Libtool, you may include this file under the  same
-# distribution terms that you use for the rest of that program.
+# As a special exception to the GNU General Public License,
+# if you distribute this file as part of a program or library that
+# is built using GNU Libtool, you may include this file under the
+# same distribution terms that you use for the rest of that program.
 #
-# GNU Libtool is distributed in the hope that it will be useful, but
-# WITHOUT ANY WARRANTY; without even the implied warranty of
+# GNU Libtool is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 # GNU General Public License for more details.
 #
 # You should have received a copy of the GNU General Public License
-# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+# along with GNU Libtool; see the file COPYING.  If not, a copy
+# can be downloaded from http://www.gnu.org/licenses/gpl.html, or
+# obtained by writing to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 ])
 
-# serial 58 LT_INIT
+# serial 57 LT_INIT
 
 
 # LT_PREREQ(VERSION)
@@ -59,7 +67,7 @@ esac
 # LT_INIT([OPTIONS])
 # ------------------
 AC_DEFUN([LT_INIT],
-[AC_PREREQ([2.62])dnl We use AC_PATH_PROGS_FEATURE_CHECK
+[AC_PREREQ([2.58])dnl We use AC_INCLUDES_DEFAULT
 AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT])dnl
 AC_BEFORE([$0], [LT_LANG])dnl
 AC_BEFORE([$0], [LT_OUTPUT])dnl
@@ -83,7 +91,7 @@ dnl Parse OPTIONS
 _LT_SET_OPTIONS([$0], [$1])
 
 # This can be used to rebuild libtool when needed
-LIBTOOL_DEPS=$ltmain
+LIBTOOL_DEPS="$ltmain"
 
 # Always use our own libtool.
 LIBTOOL='$(SHELL) $(top_builddir)/libtool'
@@ -103,43 +111,26 @@ dnl AC_DEFUN([AC_PROG_LIBTOOL], [])
 dnl AC_DEFUN([AM_PROG_LIBTOOL], [])
 
 
-# _LT_PREPARE_CC_BASENAME
-# -----------------------
-m4_defun([_LT_PREPARE_CC_BASENAME], [
-# Calculate cc_basename.  Skip known compiler wrappers and cross-prefix.
-func_cc_basename ()
-{
-    for cc_temp in @S|@*""; do
-      case $cc_temp in
-        compile | *[[\\/]]compile | ccache | *[[\\/]]ccache ) ;;
-        distcc | *[[\\/]]distcc | purify | *[[\\/]]purify ) ;;
-        \-*) ;;
-        *) break;;
-      esac
-    done
-    func_cc_basename_result=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"`
-}
-])# _LT_PREPARE_CC_BASENAME
-
-
 # _LT_CC_BASENAME(CC)
 # -------------------
-# It would be clearer to call AC_REQUIREs from _LT_PREPARE_CC_BASENAME,
-# but that macro is also expanded into generated libtool script, which
-# arranges for $SED and $ECHO to be set by different means.
+# Calculate cc_basename.  Skip known compiler wrappers and cross-prefix.
 m4_defun([_LT_CC_BASENAME],
-[m4_require([_LT_PREPARE_CC_BASENAME])dnl
-AC_REQUIRE([_LT_DECL_SED])dnl
-AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH])dnl
-func_cc_basename $1
-cc_basename=$func_cc_basename_result
+[for cc_temp in $1""; do
+  case $cc_temp in
+    compile | *[[\\/]]compile | ccache | *[[\\/]]ccache ) ;;
+    distcc | *[[\\/]]distcc | purify | *[[\\/]]purify ) ;;
+    \-*) ;;
+    *) break;;
+  esac
+done
+cc_basename=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"`
 ])
 
 
 # _LT_FILEUTILS_DEFAULTS
 # ----------------------
 # It is okay to use these file commands and assume they have been set
-# sensibly after 'm4_require([_LT_FILEUTILS_DEFAULTS])'.
+# sensibly after `m4_require([_LT_FILEUTILS_DEFAULTS])'.
 m4_defun([_LT_FILEUTILS_DEFAULTS],
 [: ${CP="cp -f"}
 : ${MV="mv -f"}
@@ -186,16 +177,15 @@ m4_require([_LT_CHECK_SHAREDLIB_FROM_LINKLIB])dnl
 m4_require([_LT_CMD_OLD_ARCHIVE])dnl
 m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl
 m4_require([_LT_WITH_SYSROOT])dnl
-m4_require([_LT_CMD_TRUNCATE])dnl
 
 _LT_CONFIG_LIBTOOL_INIT([
-# See if we are running on zsh, and set the options that allow our
+# See if we are running on zsh, and set the options which allow our
 # commands through without removal of \ escapes INIT.
-if test -n "\${ZSH_VERSION+set}"; then
+if test -n "\${ZSH_VERSION+set}" ; then
    setopt NO_GLOB_SUBST
 fi
 ])
-if test -n "${ZSH_VERSION+set}"; then
+if test -n "${ZSH_VERSION+set}" ; then
    setopt NO_GLOB_SUBST
 fi
 
@@ -208,7 +198,7 @@ aix3*)
   # AIX sometimes has problems with the GCC collect2 program.  For some
   # reason, if we set the COLLECT_NAMES environment variable, the problems
   # vanish in a puff of smoke.
-  if test set != "${COLLECT_NAMES+set}"; then
+  if test "X${COLLECT_NAMES+set}" != Xset; then
     COLLECT_NAMES=
     export COLLECT_NAMES
   fi
@@ -219,14 +209,14 @@ esac
 ofile=libtool
 can_build_shared=yes
 
-# All known linkers require a '.a' archive for static linking (except MSVC,
+# All known linkers require a `.a' archive for static linking (except MSVC,
 # which needs '.lib').
 libext=a
 
-with_gnu_ld=$lt_cv_prog_gnu_ld
+with_gnu_ld="$lt_cv_prog_gnu_ld"
 
-old_CC=$CC
-old_CFLAGS=$CFLAGS
+old_CC="$CC"
+old_CFLAGS="$CFLAGS"
 
 # Set sane defaults for various variables
 test -z "$CC" && CC=cc
@@ -279,14 +269,14 @@ no_glob_subst='s/\*/\\\*/g'
 
 # _LT_PROG_LTMAIN
 # ---------------
-# Note that this code is called both from 'configure', and 'config.status'
+# Note that this code is called both from `configure', and `config.status'
 # now that we use AC_CONFIG_COMMANDS to generate libtool.  Notably,
-# 'config.status' has no value for ac_aux_dir unless we are using Automake,
+# `config.status' has no value for ac_aux_dir unless we are using Automake,
 # so we pass a copy along to make sure it has a sensible value anyway.
 m4_defun([_LT_PROG_LTMAIN],
 [m4_ifdef([AC_REQUIRE_AUX_FILE], [AC_REQUIRE_AUX_FILE([ltmain.sh])])dnl
 _LT_CONFIG_LIBTOOL_INIT([ac_aux_dir='$ac_aux_dir'])
-ltmain=$ac_aux_dir/ltmain.sh
+ltmain="$ac_aux_dir/ltmain.sh"
 ])# _LT_PROG_LTMAIN
 
 
@@ -296,7 +286,7 @@ ltmain=$ac_aux_dir/ltmain.sh
 
 # So that we can recreate a full libtool script including additional
 # tags, we accumulate the chunks of code to send to AC_CONFIG_COMMANDS
-# in macros and then make a single call at the end using the 'libtool'
+# in macros and then make a single call at the end using the `libtool'
 # label.
 
 
@@ -431,8 +421,8 @@ m4_define([_lt_decl_all_varnames],
 
 # _LT_CONFIG_STATUS_DECLARE([VARNAME])
 # ------------------------------------
-# Quote a variable value, and forward it to 'config.status' so that its
-# declaration there will have the same value as in 'configure'.  VARNAME
+# Quote a variable value, and forward it to `config.status' so that its
+# declaration there will have the same value as in `configure'.  VARNAME
 # must have a single quote delimited value for this to work.
 m4_define([_LT_CONFIG_STATUS_DECLARE],
 [$1='`$ECHO "$][$1" | $SED "$delay_single_quote_subst"`'])
@@ -456,7 +446,7 @@ m4_defun([_LT_CONFIG_STATUS_DECLARATIONS],
 # Output comment and list of tags supported by the script
 m4_defun([_LT_LIBTOOL_TAGS],
 [_LT_FORMAT_COMMENT([The names of the tagged configurations supported by this script])dnl
-available_tags='_LT_TAGS'dnl
+available_tags="_LT_TAGS"dnl
 ])
 
 
@@ -484,7 +474,7 @@ m4_ifval([$2], [_$2])[]m4_popdef([_libtool_name])[]dnl
 # _LT_LIBTOOL_CONFIG_VARS
 # -----------------------
 # Produce commented declarations of non-tagged libtool config variables
-# suitable for insertion in the LIBTOOL CONFIG section of the 'libtool'
+# suitable for insertion in the LIBTOOL CONFIG section of the `libtool'
 # script.  Tagged libtool config variables (even for the LIBTOOL CONFIG
 # section) are produced by _LT_LIBTOOL_TAG_VARS.
 m4_defun([_LT_LIBTOOL_CONFIG_VARS],
@@ -510,8 +500,8 @@ m4_define([_LT_TAGVAR], [m4_ifval([$2], [$1_$2], [$1])])
 # Send accumulated output to $CONFIG_STATUS.  Thanks to the lists of
 # variables for single and double quote escaping we saved from calls
 # to _LT_DECL, we can put quote escaped variables declarations
-# into 'config.status', and then the shell code to quote escape them in
-# for loops in 'config.status'.  Finally, any additional code accumulated
+# into `config.status', and then the shell code to quote escape them in
+# for loops in `config.status'.  Finally, any additional code accumulated
 # from calls to _LT_CONFIG_LIBTOOL_INIT is expanded.
 m4_defun([_LT_CONFIG_COMMANDS],
 [AC_PROVIDE_IFELSE([LT_OUTPUT],
@@ -557,7 +547,7 @@ for var in lt_decl_all_varnames([[ \
 ]], lt_decl_quote_varnames); do
     case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in
     *[[\\\\\\\`\\"\\\$]]*)
-      eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$sed_quote_subst\\"\\\`\\\\\\"" ## exclude from sc_prohibit_nested_quotes
+      eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$sed_quote_subst\\"\\\`\\\\\\""
       ;;
     *)
       eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\""
@@ -570,7 +560,7 @@ for var in lt_decl_all_varnames([[ \
 ]], lt_decl_dquote_varnames); do
     case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in
     *[[\\\\\\\`\\"\\\$]]*)
-      eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\"" ## exclude from sc_prohibit_nested_quotes
+      eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\""
       ;;
     *)
       eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\""
@@ -586,7 +576,7 @@ _LT_OUTPUT_LIBTOOL_INIT
 # Generate a child script FILE with all initialization necessary to
 # reuse the environment learned by the parent script, and make the
 # file executable.  If COMMENT is supplied, it is inserted after the
-# '#!' sequence but before initialization text begins.  After this
+# `#!' sequence but before initialization text begins.  After this
 # macro, additional text can be appended to FILE to form the body of
 # the child script.  The macro ends with non-zero status if the
 # file could not be fully written (such as if the disk is full).
@@ -608,7 +598,7 @@ AS_SHELL_SANITIZE
 _AS_PREPARE
 exec AS_MESSAGE_FD>&1
 _ASEOF
-test 0 = "$lt_write_fail" && chmod +x $1[]dnl
+test $lt_write_fail = 0 && chmod +x $1[]dnl
 m4_popdef([AS_MESSAGE_LOG_FD])])])# _LT_GENERATED_FILE_INIT
 
 # LT_OUTPUT
@@ -631,7 +621,7 @@ exec AS_MESSAGE_LOG_FD>>config.log
 } >&AS_MESSAGE_LOG_FD
 
 lt_cl_help="\
-'$as_me' creates a local libtool stub from the current configuration,
+\`$as_me' creates a local libtool stub from the current configuration,
 for use in further configure time tests before the real libtool is
 generated.
 
@@ -653,7 +643,7 @@ Copyright (C) 2011 Free Software Foundation, Inc.
 This config.lt script is free software; the Free Software Foundation
 gives unlimited permision to copy, distribute and modify it."
 
-while test 0 != $[#]
+while test $[#] != 0
 do
   case $[1] in
     --version | --v* | -V )
@@ -666,10 +656,10 @@ do
       lt_cl_silent=: ;;
 
     -*) AC_MSG_ERROR([unrecognized option: $[1]
-Try '$[0] --help' for more information.]) ;;
+Try \`$[0] --help' for more information.]) ;;
 
     *) AC_MSG_ERROR([unrecognized argument: $[1]
-Try '$[0] --help' for more information.]) ;;
+Try \`$[0] --help' for more information.]) ;;
   esac
   shift
 done
@@ -695,7 +685,7 @@ chmod +x "$CONFIG_LT"
 # open by configure.  Here we exec the FD to /dev/null, effectively closing
 # config.log, so it can be properly (re)opened and appended to by config.lt.
 lt_cl_success=:
-test yes = "$silent" &&
+test "$silent" = yes &&
   lt_config_lt_args="$lt_config_lt_args --quiet"
 exec AS_MESSAGE_LOG_FD>/dev/null
 $SHELL "$CONFIG_LT" $lt_config_lt_args || lt_cl_success=false
@@ -715,31 +705,27 @@ m4_defun([_LT_CONFIG],
 _LT_CONFIG_SAVE_COMMANDS([
   m4_define([_LT_TAG], m4_if([$1], [], [C], [$1]))dnl
   m4_if(_LT_TAG, [C], [
-    # See if we are running on zsh, and set the options that allow our
+    # See if we are running on zsh, and set the options which allow our
     # commands through without removal of \ escapes.
-    if test -n "${ZSH_VERSION+set}"; then
+    if test -n "${ZSH_VERSION+set}" ; then
       setopt NO_GLOB_SUBST
     fi
 
-    cfgfile=${ofile}T
+    cfgfile="${ofile}T"
     trap "$RM \"$cfgfile\"; exit 1" 1 2 15
     $RM "$cfgfile"
 
     cat <<_LT_EOF >> "$cfgfile"
 #! $SHELL
-# Generated automatically by $as_me ($PACKAGE) $VERSION
+
+# `$ECHO "$ofile" | sed 's%^.*/%%'` - Provide generalized library-building support services.
+# Generated automatically by $as_me ($PACKAGE$TIMESTAMP) $VERSION
 # Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
 # NOTE: Changes made to this file will be lost: look at ltmain.sh.
-
-# Provide generalized library-building support services.
-# Written by Gordon Matzigkeit, 1996
-
+#
 _LT_COPYING
 _LT_LIBTOOL_TAGS
 
-# Configured defaults for sys_lib_dlsearch_path munging.
-: \${LT_SYS_LIBRARY_PATH="$configure_time_lt_sys_library_path"}
-
 # ### BEGIN LIBTOOL CONFIG
 _LT_LIBTOOL_CONFIG_VARS
 _LT_LIBTOOL_TAG_VARS
@@ -747,24 +733,13 @@ _LT_LIBTOOL_TAG_VARS
 
 _LT_EOF
 
-    cat <<'_LT_EOF' >> "$cfgfile"
-
-# ### BEGIN FUNCTIONS SHARED WITH CONFIGURE
-
-_LT_PREPARE_MUNGE_PATH_LIST
-_LT_PREPARE_CC_BASENAME
-
-# ### END FUNCTIONS SHARED WITH CONFIGURE
-
-_LT_EOF
-
   case $host_os in
   aix3*)
     cat <<\_LT_EOF >> "$cfgfile"
 # AIX sometimes has problems with the GCC collect2 program.  For some
 # reason, if we set the COLLECT_NAMES environment variable, the problems
 # vanish in a puff of smoke.
-if test set != "${COLLECT_NAMES+set}"; then
+if test "X${COLLECT_NAMES+set}" != Xset; then
   COLLECT_NAMES=
   export COLLECT_NAMES
 fi
@@ -781,6 +756,8 @@ _LT_EOF
   sed '$q' "$ltmain" >> "$cfgfile" \
      || (rm -f "$cfgfile"; exit 1)
 
+  _LT_PROG_REPLACE_SHELLFNS
+
    mv -f "$cfgfile" "$ofile" ||
     (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile")
   chmod +x "$ofile"
@@ -798,6 +775,7 @@ _LT_EOF
 [m4_if([$1], [], [
     PACKAGE='$PACKAGE'
     VERSION='$VERSION'
+    TIMESTAMP='$TIMESTAMP'
     RM='$RM'
     ofile='$ofile'], [])
 ])dnl /_LT_CONFIG_SAVE_COMMANDS
@@ -996,7 +974,7 @@ m4_defun_once([_LT_REQUIRED_DARWIN_CHECKS],[
 
     AC_CACHE_CHECK([for -single_module linker flag],[lt_cv_apple_cc_single_mod],
       [lt_cv_apple_cc_single_mod=no
-      if test -z "$LT_MULTI_MODULE"; then
+      if test -z "${LT_MULTI_MODULE}"; then
 	# By default we will add the -single_module flag. You can override
 	# by either setting the environment variable LT_MULTI_MODULE
 	# non-empty at configure time, or by adding -multi_module to the
@@ -1014,7 +992,7 @@ m4_defun_once([_LT_REQUIRED_DARWIN_CHECKS],[
 	  cat conftest.err >&AS_MESSAGE_LOG_FD
 	# Otherwise, if the output was created with a 0 exit code from
 	# the compiler, it worked.
-	elif test -f libconftest.dylib && test 0 = "$_lt_result"; then
+	elif test -f libconftest.dylib && test $_lt_result -eq 0; then
 	  lt_cv_apple_cc_single_mod=yes
 	else
 	  cat conftest.err >&AS_MESSAGE_LOG_FD
@@ -1032,7 +1010,7 @@ m4_defun_once([_LT_REQUIRED_DARWIN_CHECKS],[
       AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])],
 	[lt_cv_ld_exported_symbols_list=yes],
 	[lt_cv_ld_exported_symbols_list=no])
-	LDFLAGS=$save_LDFLAGS
+	LDFLAGS="$save_LDFLAGS"
     ])
 
     AC_CACHE_CHECK([for -force_load linker flag],[lt_cv_ld_force_load],
@@ -1054,7 +1032,7 @@ _LT_EOF
       _lt_result=$?
       if test -s conftest.err && $GREP force_load conftest.err; then
 	cat conftest.err >&AS_MESSAGE_LOG_FD
-      elif test -f conftest && test 0 = "$_lt_result" && $GREP forced_load conftest >/dev/null 2>&1; then
+      elif test -f conftest && test $_lt_result -eq 0 && $GREP forced_load conftest >/dev/null 2>&1 ; then
 	lt_cv_ld_force_load=yes
       else
 	cat conftest.err >&AS_MESSAGE_LOG_FD
@@ -1064,32 +1042,32 @@ _LT_EOF
     ])
     case $host_os in
     rhapsody* | darwin1.[[012]])
-      _lt_dar_allow_undefined='$wl-undefined ${wl}suppress' ;;
+      _lt_dar_allow_undefined='${wl}-undefined ${wl}suppress' ;;
     darwin1.*)
-      _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;;
+      _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;;
     darwin*) # darwin 5.x on
       # if running on 10.5 or later, the deployment target defaults
       # to the OS version, if on x86, and 10.4, the deployment
       # target defaults to 10.4. Don't you love it?
       case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in
 	10.0,*86*-darwin8*|10.0,*-darwin[[91]]*)
-	  _lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' ;;
-	10.[[012]][[,.]]*)
-	  _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;;
+	  _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;;
+	10.[[012]]*)
+	  _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;;
 	10.*)
-	  _lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' ;;
+	  _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;;
       esac
     ;;
   esac
-    if test yes = "$lt_cv_apple_cc_single_mod"; then
+    if test "$lt_cv_apple_cc_single_mod" = "yes"; then
       _lt_dar_single_mod='$single_module'
     fi
-    if test yes = "$lt_cv_ld_exported_symbols_list"; then
-      _lt_dar_export_syms=' $wl-exported_symbols_list,$output_objdir/$libname-symbols.expsym'
+    if test "$lt_cv_ld_exported_symbols_list" = "yes"; then
+      _lt_dar_export_syms=' ${wl}-exported_symbols_list,$output_objdir/${libname}-symbols.expsym'
     else
-      _lt_dar_export_syms='~$NMEDIT -s $output_objdir/$libname-symbols.expsym $lib'
+      _lt_dar_export_syms='~$NMEDIT -s $output_objdir/${libname}-symbols.expsym ${lib}'
     fi
-    if test : != "$DSYMUTIL" && test no = "$lt_cv_ld_force_load"; then
+    if test "$DSYMUTIL" != ":" && test "$lt_cv_ld_force_load" = "no"; then
       _lt_dsymutil='~$DSYMUTIL $lib || :'
     else
       _lt_dsymutil=
@@ -1109,29 +1087,29 @@ m4_defun([_LT_DARWIN_LINKER_FEATURES],
   _LT_TAGVAR(hardcode_direct, $1)=no
   _LT_TAGVAR(hardcode_automatic, $1)=yes
   _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported
-  if test yes = "$lt_cv_ld_force_load"; then
-    _LT_TAGVAR(whole_archive_flag_spec, $1)='`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience $wl-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`'
+  if test "$lt_cv_ld_force_load" = "yes"; then
+    _LT_TAGVAR(whole_archive_flag_spec, $1)='`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience ${wl}-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`'
     m4_case([$1], [F77], [_LT_TAGVAR(compiler_needs_object, $1)=yes],
                   [FC],  [_LT_TAGVAR(compiler_needs_object, $1)=yes])
   else
     _LT_TAGVAR(whole_archive_flag_spec, $1)=''
   fi
   _LT_TAGVAR(link_all_deplibs, $1)=yes
-  _LT_TAGVAR(allow_undefined_flag, $1)=$_lt_dar_allow_undefined
+  _LT_TAGVAR(allow_undefined_flag, $1)="$_lt_dar_allow_undefined"
   case $cc_basename in
-     ifort*|nagfor*) _lt_dar_can_shared=yes ;;
+     ifort*) _lt_dar_can_shared=yes ;;
      *) _lt_dar_can_shared=$GCC ;;
   esac
-  if test yes = "$_lt_dar_can_shared"; then
+  if test "$_lt_dar_can_shared" = "yes"; then
     output_verbose_link_cmd=func_echo_all
-    _LT_TAGVAR(archive_cmds, $1)="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dsymutil"
-    _LT_TAGVAR(module_cmds, $1)="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dsymutil"
-    _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dar_export_syms$_lt_dsymutil"
-    _LT_TAGVAR(module_expsym_cmds, $1)="sed -e 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dar_export_syms$_lt_dsymutil"
+    _LT_TAGVAR(archive_cmds, $1)="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}"
+    _LT_TAGVAR(module_cmds, $1)="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}"
+    _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}"
+    _LT_TAGVAR(module_expsym_cmds, $1)="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}"
     m4_if([$1], [CXX],
-[   if test yes != "$lt_cv_apple_cc_single_mod"; then
-      _LT_TAGVAR(archive_cmds, $1)="\$CC -r -keep_private_externs -nostdlib -o \$lib-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$lib-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring$_lt_dsymutil"
-      _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \$lib-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$lib-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring$_lt_dar_export_syms$_lt_dsymutil"
+[   if test "$lt_cv_apple_cc_single_mod" != "yes"; then
+      _LT_TAGVAR(archive_cmds, $1)="\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dsymutil}"
+      _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dar_export_syms}${_lt_dsymutil}"
     fi
 ],[])
   else
@@ -1151,7 +1129,7 @@ m4_defun([_LT_DARWIN_LINKER_FEATURES],
 # Allow to override them for all tags through lt_cv_aix_libpath.
 m4_defun([_LT_SYS_MODULE_PATH_AIX],
 [m4_require([_LT_DECL_SED])dnl
-if test set = "${lt_cv_aix_libpath+set}"; then
+if test "${lt_cv_aix_libpath+set}" = set; then
   aix_libpath=$lt_cv_aix_libpath
 else
   AC_CACHE_VAL([_LT_TAGVAR([lt_cv_aix_libpath_], [$1])],
@@ -1169,7 +1147,7 @@ else
     _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
   fi],[])
   if test -z "$_LT_TAGVAR([lt_cv_aix_libpath_], [$1])"; then
-    _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=/usr/lib:/lib
+    _LT_TAGVAR([lt_cv_aix_libpath_], [$1])="/usr/lib:/lib"
   fi
   ])
   aix_libpath=$_LT_TAGVAR([lt_cv_aix_libpath_], [$1])
@@ -1189,8 +1167,8 @@ m4_define([_LT_SHELL_INIT],
 # -----------------------
 # Find how we can fake an echo command that does not interpret backslash.
 # In particular, with Autoconf 2.60 or later we add some code to the start
-# of the generated configure script that will find a shell with a builtin
-# printf (that we can use as an echo command).
+# of the generated configure script which will find a shell with a builtin
+# printf (which we can use as an echo command).
 m4_defun([_LT_PROG_ECHO_BACKSLASH],
 [ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
 ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO
@@ -1218,10 +1196,10 @@ fi
 # Invoke $ECHO with all args, space-separated.
 func_echo_all ()
 {
-    $ECHO "$*"
+    $ECHO "$*" 
 }
 
-case $ECHO in
+case "$ECHO" in
   printf*) AC_MSG_RESULT([printf]) ;;
   print*) AC_MSG_RESULT([print -r]) ;;
   *) AC_MSG_RESULT([cat]) ;;
@@ -1247,17 +1225,16 @@ _LT_DECL([], [ECHO], [1], [An echo program that protects backslashes])
 AC_DEFUN([_LT_WITH_SYSROOT],
 [AC_MSG_CHECKING([for sysroot])
 AC_ARG_WITH([sysroot],
-[AS_HELP_STRING([--with-sysroot@<:@=DIR@:>@],
-  [Search for dependent libraries within DIR (or the compiler's sysroot
-   if not specified).])],
+[  --with-sysroot[=DIR] Search for dependent libraries within DIR
+                        (or the compiler's sysroot if not specified).],
 [], [with_sysroot=no])
 
 dnl lt_sysroot will always be passed unquoted.  We quote it here
 dnl in case the user passed a directory name.
 lt_sysroot=
-case $with_sysroot in #(
+case ${with_sysroot} in #(
  yes)
-   if test yes = "$GCC"; then
+   if test "$GCC" = yes; then
      lt_sysroot=`$CC --print-sysroot 2>/dev/null`
    fi
    ;; #(
@@ -1267,14 +1244,14 @@ case $with_sysroot in #(
  no|'')
    ;; #(
  *)
-   AC_MSG_RESULT([$with_sysroot])
+   AC_MSG_RESULT([${with_sysroot}])
    AC_MSG_ERROR([The sysroot must be an absolute path.])
    ;;
 esac
 
  AC_MSG_RESULT([${lt_sysroot:-no}])
 _LT_DECL([], [lt_sysroot], [0], [The root where to search for ]dnl
-[dependent libraries, and where our libraries should be installed.])])
+[dependent libraries, and in which our libraries should be installed.])])
 
 # _LT_ENABLE_LOCK
 # ---------------
@@ -1282,33 +1259,31 @@ m4_defun([_LT_ENABLE_LOCK],
 [AC_ARG_ENABLE([libtool-lock],
   [AS_HELP_STRING([--disable-libtool-lock],
     [avoid locking (might break parallel builds)])])
-test no = "$enable_libtool_lock" || enable_libtool_lock=yes
+test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes
 
 # Some flags need to be propagated to the compiler or linker for good
 # libtool support.
 case $host in
 ia64-*-hpux*)
-  # Find out what ABI is being produced by ac_compile, and set mode
-  # options accordingly.
+  # Find out which ABI we are using.
   echo 'int i;' > conftest.$ac_ext
   if AC_TRY_EVAL(ac_compile); then
     case `/usr/bin/file conftest.$ac_objext` in
       *ELF-32*)
-	HPUX_IA64_MODE=32
+	HPUX_IA64_MODE="32"
 	;;
       *ELF-64*)
-	HPUX_IA64_MODE=64
+	HPUX_IA64_MODE="64"
 	;;
     esac
   fi
   rm -rf conftest*
   ;;
 *-*-irix6*)
-  # Find out what ABI is being produced by ac_compile, and set linker
-  # options accordingly.
+  # Find out which ABI we are using.
   echo '[#]line '$LINENO' "configure"' > conftest.$ac_ext
   if AC_TRY_EVAL(ac_compile); then
-    if test yes = "$lt_cv_prog_gnu_ld"; then
+    if test "$lt_cv_prog_gnu_ld" = yes; then
       case `/usr/bin/file conftest.$ac_objext` in
 	*32-bit*)
 	  LD="${LD-ld} -melf32bsmip"
@@ -1337,46 +1312,9 @@ ia64-*-hpux*)
   rm -rf conftest*
   ;;
 
-mips64*-*linux*)
-  # Find out what ABI is being produced by ac_compile, and set linker
-  # options accordingly.
-  echo '[#]line '$LINENO' "configure"' > conftest.$ac_ext
-  if AC_TRY_EVAL(ac_compile); then
-    emul=elf
-    case `/usr/bin/file conftest.$ac_objext` in
-      *32-bit*)
-	emul="${emul}32"
-	;;
-      *64-bit*)
-	emul="${emul}64"
-	;;
-    esac
-    case `/usr/bin/file conftest.$ac_objext` in
-      *MSB*)
-	emul="${emul}btsmip"
-	;;
-      *LSB*)
-	emul="${emul}ltsmip"
-	;;
-    esac
-    case `/usr/bin/file conftest.$ac_objext` in
-      *N32*)
-	emul="${emul}n32"
-	;;
-    esac
-    LD="${LD-ld} -m $emul"
-  fi
-  rm -rf conftest*
-  ;;
-
 x86_64-*kfreebsd*-gnu|x86_64-*linux*|powerpc*-*linux*| \
 s390*-*linux*|s390*-*tpf*|sparc*-*linux*)
-  # Find out what ABI is being produced by ac_compile, and set linker
-  # options accordingly.  Note that the listed cases only cover the
-  # situations where additional linker options are needed (such as when
-  # doing 32-bit compilation for a host where ld defaults to 64-bit, or
-  # vice versa); the common cases where no linker options are needed do
-  # not appear in the list.
+  # Find out which ABI we are using.
   echo 'int i;' > conftest.$ac_ext
   if AC_TRY_EVAL(ac_compile); then
     case `/usr/bin/file conftest.o` in
@@ -1395,10 +1333,10 @@ s390*-*linux*|s390*-*tpf*|sparc*-*linux*)
 		;;
 	    esac
 	    ;;
-	  powerpc64le-*linux*)
+	  powerpc64le-*)
 	    LD="${LD-ld} -m elf32lppclinux"
 	    ;;
-	  powerpc64-*linux*)
+	  powerpc64-*)
 	    LD="${LD-ld} -m elf32ppclinux"
 	    ;;
 	  s390x-*linux*)
@@ -1417,10 +1355,10 @@ s390*-*linux*|s390*-*tpf*|sparc*-*linux*)
 	  x86_64-*linux*)
 	    LD="${LD-ld} -m elf_x86_64"
 	    ;;
-	  powerpcle-*linux*)
+	  powerpcle-*)
 	    LD="${LD-ld} -m elf64lppc"
 	    ;;
-	  powerpc-*linux*)
+	  powerpc-*)
 	    LD="${LD-ld} -m elf64ppc"
 	    ;;
 	  s390*-*linux*|s390*-*tpf*)
@@ -1438,20 +1376,19 @@ s390*-*linux*|s390*-*tpf*|sparc*-*linux*)
 
 *-*-sco3.2v5*)
   # On SCO OpenServer 5, we need -belf to get full-featured binaries.
-  SAVE_CFLAGS=$CFLAGS
+  SAVE_CFLAGS="$CFLAGS"
   CFLAGS="$CFLAGS -belf"
   AC_CACHE_CHECK([whether the C compiler needs -belf], lt_cv_cc_needs_belf,
     [AC_LANG_PUSH(C)
      AC_LINK_IFELSE([AC_LANG_PROGRAM([[]],[[]])],[lt_cv_cc_needs_belf=yes],[lt_cv_cc_needs_belf=no])
      AC_LANG_POP])
-  if test yes != "$lt_cv_cc_needs_belf"; then
+  if test x"$lt_cv_cc_needs_belf" != x"yes"; then
     # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf
-    CFLAGS=$SAVE_CFLAGS
+    CFLAGS="$SAVE_CFLAGS"
   fi
   ;;
 *-*solaris*)
-  # Find out what ABI is being produced by ac_compile, and set linker
-  # options accordingly.
+  # Find out which ABI we are using.
   echo 'int i;' > conftest.$ac_ext
   if AC_TRY_EVAL(ac_compile); then
     case `/usr/bin/file conftest.o` in
@@ -1459,7 +1396,7 @@ s390*-*linux*|s390*-*tpf*|sparc*-*linux*)
       case $lt_cv_prog_gnu_ld in
       yes*)
         case $host in
-        i?86-*-solaris*|x86_64-*-solaris*)
+        i?86-*-solaris*)
           LD="${LD-ld} -m elf_x86_64"
           ;;
         sparc*-*-solaris*)
@@ -1468,7 +1405,7 @@ s390*-*linux*|s390*-*tpf*|sparc*-*linux*)
         esac
         # GNU ld 2.21 introduced _sol2 emulations.  Use them if available.
         if ${LD-ld} -V | grep _sol2 >/dev/null 2>&1; then
-          LD=${LD-ld}_sol2
+          LD="${LD-ld}_sol2"
         fi
         ;;
       *)
@@ -1484,7 +1421,7 @@ s390*-*linux*|s390*-*tpf*|sparc*-*linux*)
   ;;
 esac
 
-need_locks=$enable_libtool_lock
+need_locks="$enable_libtool_lock"
 ])# _LT_ENABLE_LOCK
 
 
@@ -1503,11 +1440,11 @@ AC_CACHE_CHECK([for archiver @FILE support], [lt_cv_ar_at_file],
      [echo conftest.$ac_objext > conftest.lst
       lt_ar_try='$AR $AR_FLAGS libconftest.a @conftest.lst >&AS_MESSAGE_LOG_FD'
       AC_TRY_EVAL([lt_ar_try])
-      if test 0 -eq "$ac_status"; then
+      if test "$ac_status" -eq 0; then
 	# Ensure the archiver fails upon bogus file names.
 	rm -f conftest.$ac_objext libconftest.a
 	AC_TRY_EVAL([lt_ar_try])
-	if test 0 -ne "$ac_status"; then
+	if test "$ac_status" -ne 0; then
           lt_cv_ar_at_file=@
         fi
       fi
@@ -1515,7 +1452,7 @@ AC_CACHE_CHECK([for archiver @FILE support], [lt_cv_ar_at_file],
      ])
   ])
 
-if test no = "$lt_cv_ar_at_file"; then
+if test "x$lt_cv_ar_at_file" = xno; then
   archiver_list_spec=
 else
   archiver_list_spec=$lt_cv_ar_at_file
@@ -1546,7 +1483,7 @@ old_postuninstall_cmds=
 
 if test -n "$RANLIB"; then
   case $host_os in
-  bitrig* | openbsd*)
+  openbsd*)
     old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$tool_oldlib"
     ;;
   *)
@@ -1582,7 +1519,7 @@ AC_CACHE_CHECK([$1], [$2],
   [$2=no
    m4_if([$4], , [ac_outfile=conftest.$ac_objext], [ac_outfile=$4])
    echo "$lt_simple_compile_test_code" > conftest.$ac_ext
-   lt_compiler_flag="$3"  ## exclude from sc_useless_quotes_in_assignment
+   lt_compiler_flag="$3"
    # Insert the option either (1) after the last *FLAGS variable, or
    # (2) before a word containing "conftest.", or (3) at the end.
    # Note that $ac_compile itself does not contain backslashes and begins
@@ -1609,7 +1546,7 @@ AC_CACHE_CHECK([$1], [$2],
    $RM conftest*
 ])
 
-if test yes = "[$]$2"; then
+if test x"[$]$2" = xyes; then
     m4_if([$5], , :, [$5])
 else
     m4_if([$6], , :, [$6])
@@ -1631,7 +1568,7 @@ AC_DEFUN([_LT_LINKER_OPTION],
 m4_require([_LT_DECL_SED])dnl
 AC_CACHE_CHECK([$1], [$2],
   [$2=no
-   save_LDFLAGS=$LDFLAGS
+   save_LDFLAGS="$LDFLAGS"
    LDFLAGS="$LDFLAGS $3"
    echo "$lt_simple_link_test_code" > conftest.$ac_ext
    if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then
@@ -1650,10 +1587,10 @@ AC_CACHE_CHECK([$1], [$2],
      fi
    fi
    $RM -r conftest*
-   LDFLAGS=$save_LDFLAGS
+   LDFLAGS="$save_LDFLAGS"
 ])
 
-if test yes = "[$]$2"; then
+if test x"[$]$2" = xyes; then
     m4_if([$4], , :, [$4])
 else
     m4_if([$5], , :, [$5])
@@ -1674,7 +1611,7 @@ AC_DEFUN([LT_CMD_MAX_LEN],
 AC_MSG_CHECKING([the maximum length of command line arguments])
 AC_CACHE_VAL([lt_cv_sys_max_cmd_len], [dnl
   i=0
-  teststring=ABCD
+  teststring="ABCD"
 
   case $build_os in
   msdosdjgpp*)
@@ -1714,7 +1651,7 @@ AC_CACHE_VAL([lt_cv_sys_max_cmd_len], [dnl
     lt_cv_sys_max_cmd_len=8192;
     ;;
 
-  bitrig* | darwin* | dragonfly* | freebsd* | netbsd* | openbsd*)
+  netbsd* | freebsd* | openbsd* | darwin* | dragonfly*)
     # This has been around since 386BSD, at least.  Likely further.
     if test -x /sbin/sysctl; then
       lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax`
@@ -1765,22 +1702,22 @@ AC_CACHE_VAL([lt_cv_sys_max_cmd_len], [dnl
   *)
     lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null`
     if test -n "$lt_cv_sys_max_cmd_len" && \
-       test undefined != "$lt_cv_sys_max_cmd_len"; then
+	test undefined != "$lt_cv_sys_max_cmd_len"; then
       lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4`
       lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3`
     else
       # Make teststring a little bigger before we do anything with it.
       # a 1K string should be a reasonable start.
-      for i in 1 2 3 4 5 6 7 8; do
+      for i in 1 2 3 4 5 6 7 8 ; do
         teststring=$teststring$teststring
       done
       SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}}
       # If test is not a shell built-in, we'll probably end up computing a
       # maximum length that is only half of the actual maximum length, but
       # we can't tell.
-      while { test X`env echo "$teststring$teststring" 2>/dev/null` \
+      while { test "X"`env echo "$teststring$teststring" 2>/dev/null` \
 	         = "X$teststring$teststring"; } >/dev/null 2>&1 &&
-	      test 17 != "$i" # 1/2 MB should be enough
+	      test $i != 17 # 1/2 MB should be enough
       do
         i=`expr $i + 1`
         teststring=$teststring$teststring
@@ -1796,7 +1733,7 @@ AC_CACHE_VAL([lt_cv_sys_max_cmd_len], [dnl
     ;;
   esac
 ])
-if test -n "$lt_cv_sys_max_cmd_len"; then
+if test -n $lt_cv_sys_max_cmd_len ; then
   AC_MSG_RESULT($lt_cv_sys_max_cmd_len)
 else
   AC_MSG_RESULT(none)
@@ -1824,7 +1761,7 @@ m4_defun([_LT_HEADER_DLFCN],
 # ----------------------------------------------------------------
 m4_defun([_LT_TRY_DLOPEN_SELF],
 [m4_require([_LT_HEADER_DLFCN])dnl
-if test yes = "$cross_compiling"; then :
+if test "$cross_compiling" = yes; then :
   [$4]
 else
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
@@ -1871,9 +1808,9 @@ else
 #  endif
 #endif
 
-/* When -fvisibility=hidden is used, assume the code has been annotated
+/* When -fvisbility=hidden is used, assume the code has been annotated
    correspondingly for the symbols needed.  */
-#if defined __GNUC__ && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3))
+#if defined(__GNUC__) && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3))
 int fnord () __attribute__((visibility("default")));
 #endif
 
@@ -1899,7 +1836,7 @@ int main ()
   return status;
 }]
 _LT_EOF
-  if AC_TRY_EVAL(ac_link) && test -s "conftest$ac_exeext" 2>/dev/null; then
+  if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext} 2>/dev/null; then
     (./conftest; exit; ) >&AS_MESSAGE_LOG_FD 2>/dev/null
     lt_status=$?
     case x$lt_status in
@@ -1920,7 +1857,7 @@ rm -fr conftest*
 # ------------------
 AC_DEFUN([LT_SYS_DLOPEN_SELF],
 [m4_require([_LT_HEADER_DLFCN])dnl
-if test yes != "$enable_dlopen"; then
+if test "x$enable_dlopen" != xyes; then
   enable_dlopen=unknown
   enable_dlopen_self=unknown
   enable_dlopen_self_static=unknown
@@ -1930,52 +1867,44 @@ else
 
   case $host_os in
   beos*)
-    lt_cv_dlopen=load_add_on
+    lt_cv_dlopen="load_add_on"
     lt_cv_dlopen_libs=
     lt_cv_dlopen_self=yes
     ;;
 
   mingw* | pw32* | cegcc*)
-    lt_cv_dlopen=LoadLibrary
+    lt_cv_dlopen="LoadLibrary"
     lt_cv_dlopen_libs=
     ;;
 
   cygwin*)
-    lt_cv_dlopen=dlopen
+    lt_cv_dlopen="dlopen"
     lt_cv_dlopen_libs=
     ;;
 
   darwin*)
-    # if libdl is installed we need to link against it
+  # if libdl is installed we need to link against it
     AC_CHECK_LIB([dl], [dlopen],
-		[lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-ldl],[
-    lt_cv_dlopen=dyld
+		[lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"],[
+    lt_cv_dlopen="dyld"
     lt_cv_dlopen_libs=
     lt_cv_dlopen_self=yes
     ])
     ;;
 
-  tpf*)
-    # Don't try to run any link tests for TPF.  We know it's impossible
-    # because TPF is a cross-compiler, and we know how we open DSOs.
-    lt_cv_dlopen=dlopen
-    lt_cv_dlopen_libs=
-    lt_cv_dlopen_self=no
-    ;;
-
   *)
     AC_CHECK_FUNC([shl_load],
-	  [lt_cv_dlopen=shl_load],
+	  [lt_cv_dlopen="shl_load"],
       [AC_CHECK_LIB([dld], [shl_load],
-	    [lt_cv_dlopen=shl_load lt_cv_dlopen_libs=-ldld],
+	    [lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-ldld"],
 	[AC_CHECK_FUNC([dlopen],
-	      [lt_cv_dlopen=dlopen],
+	      [lt_cv_dlopen="dlopen"],
 	  [AC_CHECK_LIB([dl], [dlopen],
-		[lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-ldl],
+		[lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"],
 	    [AC_CHECK_LIB([svld], [dlopen],
-		  [lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-lsvld],
+		  [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld"],
 	      [AC_CHECK_LIB([dld], [dld_link],
-		    [lt_cv_dlopen=dld_link lt_cv_dlopen_libs=-ldld])
+		    [lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-ldld"])
 	      ])
 	    ])
 	  ])
@@ -1984,21 +1913,21 @@ else
     ;;
   esac
 
-  if test no = "$lt_cv_dlopen"; then
-    enable_dlopen=no
-  else
+  if test "x$lt_cv_dlopen" != xno; then
     enable_dlopen=yes
+  else
+    enable_dlopen=no
   fi
 
   case $lt_cv_dlopen in
   dlopen)
-    save_CPPFLAGS=$CPPFLAGS
-    test yes = "$ac_cv_header_dlfcn_h" && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H"
+    save_CPPFLAGS="$CPPFLAGS"
+    test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H"
 
-    save_LDFLAGS=$LDFLAGS
+    save_LDFLAGS="$LDFLAGS"
     wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\"
 
-    save_LIBS=$LIBS
+    save_LIBS="$LIBS"
     LIBS="$lt_cv_dlopen_libs $LIBS"
 
     AC_CACHE_CHECK([whether a program can dlopen itself],
@@ -2008,7 +1937,7 @@ else
 	    lt_cv_dlopen_self=no, lt_cv_dlopen_self=cross)
     ])
 
-    if test yes = "$lt_cv_dlopen_self"; then
+    if test "x$lt_cv_dlopen_self" = xyes; then
       wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\"
       AC_CACHE_CHECK([whether a statically linked program can dlopen itself],
 	  lt_cv_dlopen_self_static, [dnl
@@ -2018,9 +1947,9 @@ else
       ])
     fi
 
-    CPPFLAGS=$save_CPPFLAGS
-    LDFLAGS=$save_LDFLAGS
-    LIBS=$save_LIBS
+    CPPFLAGS="$save_CPPFLAGS"
+    LDFLAGS="$save_LDFLAGS"
+    LIBS="$save_LIBS"
     ;;
   esac
 
@@ -2112,8 +2041,8 @@ m4_defun([_LT_COMPILER_FILE_LOCKS],
 m4_require([_LT_FILEUTILS_DEFAULTS])dnl
 _LT_COMPILER_C_O([$1])
 
-hard_links=nottested
-if test no = "$_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)" && test no != "$need_locks"; then
+hard_links="nottested"
+if test "$_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)" = no && test "$need_locks" != no; then
   # do not overwrite the value of need_locks provided by the user
   AC_MSG_CHECKING([if we can lock with hard links])
   hard_links=yes
@@ -2123,8 +2052,8 @@ if test no = "$_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)" && test no != "$need_loc
   ln conftest.a conftest.b 2>&5 || hard_links=no
   ln conftest.a conftest.b 2>/dev/null && hard_links=no
   AC_MSG_RESULT([$hard_links])
-  if test no = "$hard_links"; then
-    AC_MSG_WARN(['$CC' does not support '-c -o', so 'make -j' may be unsafe])
+  if test "$hard_links" = no; then
+    AC_MSG_WARN([`$CC' does not support `-c -o', so `make -j' may be unsafe])
     need_locks=warn
   fi
 else
@@ -2151,8 +2080,8 @@ objdir=$lt_cv_objdir
 _LT_DECL([], [objdir], [0],
          [The name of the directory that contains temporary libtool files])dnl
 m4_pattern_allow([LT_OBJDIR])dnl
-AC_DEFINE_UNQUOTED([LT_OBJDIR], "$lt_cv_objdir/",
-  [Define to the sub-directory where libtool stores uninstalled libraries.])
+AC_DEFINE_UNQUOTED(LT_OBJDIR, "$lt_cv_objdir/",
+  [Define to the sub-directory in which libtool stores uninstalled libraries.])
 ])# _LT_CHECK_OBJDIR
 
 
@@ -2164,15 +2093,15 @@ m4_defun([_LT_LINKER_HARDCODE_LIBPATH],
 _LT_TAGVAR(hardcode_action, $1)=
 if test -n "$_LT_TAGVAR(hardcode_libdir_flag_spec, $1)" ||
    test -n "$_LT_TAGVAR(runpath_var, $1)" ||
-   test yes = "$_LT_TAGVAR(hardcode_automatic, $1)"; then
+   test "X$_LT_TAGVAR(hardcode_automatic, $1)" = "Xyes" ; then
 
   # We can hardcode non-existent directories.
-  if test no != "$_LT_TAGVAR(hardcode_direct, $1)" &&
+  if test "$_LT_TAGVAR(hardcode_direct, $1)" != no &&
      # If the only mechanism to avoid hardcoding is shlibpath_var, we
      # have to relink, otherwise we might link with an installed library
      # when we should be linking with a yet-to-be-installed one
-     ## test no != "$_LT_TAGVAR(hardcode_shlibpath_var, $1)" &&
-     test no != "$_LT_TAGVAR(hardcode_minus_L, $1)"; then
+     ## test "$_LT_TAGVAR(hardcode_shlibpath_var, $1)" != no &&
+     test "$_LT_TAGVAR(hardcode_minus_L, $1)" != no; then
     # Linking always hardcodes the temporary library directory.
     _LT_TAGVAR(hardcode_action, $1)=relink
   else
@@ -2186,12 +2115,12 @@ else
 fi
 AC_MSG_RESULT([$_LT_TAGVAR(hardcode_action, $1)])
 
-if test relink = "$_LT_TAGVAR(hardcode_action, $1)" ||
-   test yes = "$_LT_TAGVAR(inherit_rpath, $1)"; then
+if test "$_LT_TAGVAR(hardcode_action, $1)" = relink ||
+   test "$_LT_TAGVAR(inherit_rpath, $1)" = yes; then
   # Fast installation is not supported
   enable_fast_install=no
-elif test yes = "$shlibpath_overrides_runpath" ||
-     test no = "$enable_shared"; then
+elif test "$shlibpath_overrides_runpath" = yes ||
+     test "$enable_shared" = no; then
   # Fast installation is not necessary
   enable_fast_install=needless
 fi
@@ -2215,7 +2144,7 @@ else
 # FIXME - insert some real tests, host_os isn't really good enough
   case $host_os in
   darwin*)
-    if test -n "$STRIP"; then
+    if test -n "$STRIP" ; then
       striplib="$STRIP -x"
       old_striplib="$STRIP -S"
       AC_MSG_RESULT([yes])
@@ -2233,47 +2162,6 @@ _LT_DECL([], [striplib], [1])
 ])# _LT_CMD_STRIPLIB
 
 
-# _LT_PREPARE_MUNGE_PATH_LIST
-# ---------------------------
-# Make sure func_munge_path_list() is defined correctly.
-m4_defun([_LT_PREPARE_MUNGE_PATH_LIST],
-[[# func_munge_path_list VARIABLE PATH
-# -----------------------------------
-# VARIABLE is name of variable containing _space_ separated list of
-# directories to be munged by the contents of PATH, which is string
-# having a format:
-# "DIR[:DIR]:"
-#       string "DIR[ DIR]" will be prepended to VARIABLE
-# ":DIR[:DIR]"
-#       string "DIR[ DIR]" will be appended to VARIABLE
-# "DIRP[:DIRP]::[DIRA:]DIRA"
-#       string "DIRP[ DIRP]" will be prepended to VARIABLE and string
-#       "DIRA[ DIRA]" will be appended to VARIABLE
-# "DIR[:DIR]"
-#       VARIABLE will be replaced by "DIR[ DIR]"
-func_munge_path_list ()
-{
-    case x at S|@2 in
-    x)
-        ;;
-    *:)
-        eval @S|@1=\"`$ECHO @S|@2 | $SED 's/:/ /g'` \@S|@@S|@1\"
-        ;;
-    x:*)
-        eval @S|@1=\"\@S|@@S|@1 `$ECHO @S|@2 | $SED 's/:/ /g'`\"
-        ;;
-    *::*)
-        eval @S|@1=\"\@S|@@S|@1\ `$ECHO @S|@2 | $SED -e 's/.*:://' -e 's/:/ /g'`\"
-        eval @S|@1=\"`$ECHO @S|@2 | $SED -e 's/::.*//' -e 's/:/ /g'`\ \@S|@@S|@1\"
-        ;;
-    *)
-        eval @S|@1=\"`$ECHO @S|@2 | $SED 's/:/ /g'`\"
-        ;;
-    esac
-}
-]])# _LT_PREPARE_PATH_LIST
-
-
 # _LT_SYS_DYNAMIC_LINKER([TAG])
 # -----------------------------
 # PORTME Fill in your ld.so characteristics
@@ -2284,18 +2172,17 @@ m4_require([_LT_FILEUTILS_DEFAULTS])dnl
 m4_require([_LT_DECL_OBJDUMP])dnl
 m4_require([_LT_DECL_SED])dnl
 m4_require([_LT_CHECK_SHELL_FEATURES])dnl
-m4_require([_LT_PREPARE_MUNGE_PATH_LIST])dnl
 AC_MSG_CHECKING([dynamic linker characteristics])
 m4_if([$1],
 	[], [
-if test yes = "$GCC"; then
+if test "$GCC" = yes; then
   case $host_os in
-    darwin*) lt_awk_arg='/^libraries:/,/LR/' ;;
-    *) lt_awk_arg='/^libraries:/' ;;
+    darwin*) lt_awk_arg="/^libraries:/,/LR/" ;;
+    *) lt_awk_arg="/^libraries:/" ;;
   esac
   case $host_os in
-    mingw* | cegcc*) lt_sed_strip_eq='s|=\([[A-Za-z]]:\)|\1|g' ;;
-    *) lt_sed_strip_eq='s|=/|/|g' ;;
+    mingw* | cegcc*) lt_sed_strip_eq="s,=\([[A-Za-z]]:\),\1,g" ;;
+    *) lt_sed_strip_eq="s,=/,/,g" ;;
   esac
   lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e $lt_sed_strip_eq`
   case $lt_search_path_spec in
@@ -2311,35 +2198,28 @@ if test yes = "$GCC"; then
     ;;
   esac
   # Ok, now we have the path, separated by spaces, we can step through it
-  # and add multilib dir if necessary...
+  # and add multilib dir if necessary.
   lt_tmp_lt_search_path_spec=
-  lt_multi_os_dir=/`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null`
-  # ...but if some path component already ends with the multilib dir we assume
-  # that all is fine and trust -print-search-dirs as is (GCC 4.2? or newer).
-  case "$lt_multi_os_dir; $lt_search_path_spec " in
-  "/; "* | "/.; "* | "/./; "* | *"$lt_multi_os_dir "* | *"$lt_multi_os_dir/ "*)
-    lt_multi_os_dir=
-    ;;
-  esac
+  lt_multi_os_dir=`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null`
   for lt_sys_path in $lt_search_path_spec; do
-    if test -d "$lt_sys_path$lt_multi_os_dir"; then
-      lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path$lt_multi_os_dir"
-    elif test -n "$lt_multi_os_dir"; then
+    if test -d "$lt_sys_path/$lt_multi_os_dir"; then
+      lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path/$lt_multi_os_dir"
+    else
       test -d "$lt_sys_path" && \
 	lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path"
     fi
   done
   lt_search_path_spec=`$ECHO "$lt_tmp_lt_search_path_spec" | awk '
-BEGIN {RS = " "; FS = "/|\n";} {
-  lt_foo = "";
-  lt_count = 0;
+BEGIN {RS=" "; FS="/|\n";} {
+  lt_foo="";
+  lt_count=0;
   for (lt_i = NF; lt_i > 0; lt_i--) {
     if ($lt_i != "" && $lt_i != ".") {
       if ($lt_i == "..") {
         lt_count++;
       } else {
         if (lt_count == 0) {
-          lt_foo = "/" $lt_i lt_foo;
+          lt_foo="/" $lt_i lt_foo;
         } else {
           lt_count--;
         }
@@ -2353,7 +2233,7 @@ BEGIN {RS = " "; FS = "/|\n";} {
   # for these hosts.
   case $host_os in
     mingw* | cegcc*) lt_search_path_spec=`$ECHO "$lt_search_path_spec" |\
-      $SED 's|/\([[A-Za-z]]:\)|\1|g'` ;;
+      $SED 's,/\([[A-Za-z]]:\),\1,g'` ;;
   esac
   sys_lib_search_path_spec=`$ECHO "$lt_search_path_spec" | $lt_NL2SP`
 else
@@ -2362,7 +2242,7 @@ fi])
 library_names_spec=
 libname_spec='lib$name'
 soname_spec=
-shrext_cmds=.so
+shrext_cmds=".so"
 postinstall_cmds=
 postuninstall_cmds=
 finish_cmds=
@@ -2379,17 +2259,14 @@ hardcode_into_libs=no
 # flags to be left without arguments
 need_version=unknown
 
-AC_ARG_VAR([LT_SYS_LIBRARY_PATH],
-[User-defined run-time library search path.])
-
 case $host_os in
 aix3*)
   version_type=linux # correct to gnu/linux during the next big refactor
-  library_names_spec='$libname$release$shared_ext$versuffix $libname.a'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a'
   shlibpath_var=LIBPATH
 
   # AIX 3 has no versioning support, so we append a major version to the name.
-  soname_spec='$libname$release$shared_ext$major'
+  soname_spec='${libname}${release}${shared_ext}$major'
   ;;
 
 aix[[4-9]]*)
@@ -2397,91 +2274,41 @@ aix[[4-9]]*)
   need_lib_prefix=no
   need_version=no
   hardcode_into_libs=yes
-  if test ia64 = "$host_cpu"; then
+  if test "$host_cpu" = ia64; then
     # AIX 5 supports IA64
-    library_names_spec='$libname$release$shared_ext$major $libname$release$shared_ext$versuffix $libname$shared_ext'
+    library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}'
     shlibpath_var=LD_LIBRARY_PATH
   else
     # With GCC up to 2.95.x, collect2 would create an import file
     # for dependence libraries.  The import file would start with
-    # the line '#! .'.  This would cause the generated library to
-    # depend on '.', always an invalid library.  This was fixed in
+    # the line `#! .'.  This would cause the generated library to
+    # depend on `.', always an invalid library.  This was fixed in
     # development snapshots of GCC prior to 3.0.
     case $host_os in
       aix4 | aix4.[[01]] | aix4.[[01]].*)
       if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)'
 	   echo ' yes '
-	   echo '#endif'; } | $CC -E - | $GREP yes > /dev/null; then
+	   echo '#endif'; } | ${CC} -E - | $GREP yes > /dev/null; then
 	:
       else
 	can_build_shared=no
       fi
       ;;
     esac
-    # Using Import Files as archive members, it is possible to support
-    # filename-based versioning of shared library archives on AIX. While
-    # this would work for both with and without runtime linking, it will
-    # prevent static linking of such archives. So we do filename-based
-    # shared library versioning with .so extension only, which is used
-    # when both runtime linking and shared linking is enabled.
-    # Unfortunately, runtime linking may impact performance, so we do
-    # not want this to be the default eventually. Also, we use the
-    # versioned .so libs for executables only if there is the -brtl
-    # linker flag in LDFLAGS as well, or --with-aix-soname=svr4 only.
-    # To allow for filename-based versioning support, we need to create
-    # libNAME.so.V as an archive file, containing:
-    # *) an Import File, referring to the versioned filename of the
-    #    archive as well as the shared archive member, telling the
-    #    bitwidth (32 or 64) of that shared object, and providing the
-    #    list of exported symbols of that shared object, eventually
-    #    decorated with the 'weak' keyword
-    # *) the shared object with the F_LOADONLY flag set, to really avoid
-    #    it being seen by the linker.
-    # At run time we better use the real file rather than another symlink,
-    # but for link time we create the symlink libNAME.so -> libNAME.so.V
-
-    case $with_aix_soname,$aix_use_runtimelinking in
-    # AIX (on Power*) has no versioning support, so currently we cannot hardcode correct
+    # AIX (on Power*) has no versioning support, so currently we can not hardcode correct
     # soname into executable. Probably we can add versioning support to
     # collect2, so additional links can be useful in future.
-    aix,yes) # traditional libtool
-      dynamic_linker='AIX unversionable lib.so'
+    if test "$aix_use_runtimelinking" = yes; then
       # If using run time linking (on AIX 4.2 or later) use lib<name>.so
       # instead of lib<name>.a to let people know that these are not
       # typical AIX shared libraries.
-      library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
-      ;;
-    aix,no) # traditional AIX only
-      dynamic_linker='AIX lib.a[(]lib.so.V[)]'
+      library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+    else
       # We preserve .a as extension for shared libraries through AIX4.2
       # and later when we are not doing run time linking.
-      library_names_spec='$libname$release.a $libname.a'
-      soname_spec='$libname$release$shared_ext$major'
-      ;;
-    svr4,*) # full svr4 only
-      dynamic_linker="AIX lib.so.V[(]$shared_archive_member_spec.o[)]"
-      library_names_spec='$libname$release$shared_ext$major $libname$shared_ext'
-      # We do not specify a path in Import Files, so LIBPATH fires.
-      shlibpath_overrides_runpath=yes
-      ;;
-    *,yes) # both, prefer svr4
-      dynamic_linker="AIX lib.so.V[(]$shared_archive_member_spec.o[)], lib.a[(]lib.so.V[)]"
-      library_names_spec='$libname$release$shared_ext$major $libname$shared_ext'
-      # unpreferred sharedlib libNAME.a needs extra handling
-      postinstall_cmds='test -n "$linkname" || linkname="$realname"~func_stripname "" ".so" "$linkname"~$install_shared_prog "$dir/$func_stripname_result.$libext" "$destdir/$func_stripname_result.$libext"~test -z "$tstripme" || test -z "$striplib" || $striplib "$destdir/$func_stripname_result.$libext"'
-      postuninstall_cmds='for n in $library_names $old_library; do :; done~func_stripname "" ".so" "$n"~test "$func_stripname_result" = "$n" || func_append rmfiles " $odir/$func_stripname_result.$libext"'
-      # We do not specify a path in Import Files, so LIBPATH fires.
-      shlibpath_overrides_runpath=yes
-      ;;
-    *,no) # both, prefer aix
-      dynamic_linker="AIX lib.a[(]lib.so.V[)], lib.so.V[(]$shared_archive_member_spec.o[)]"
-      library_names_spec='$libname$release.a $libname.a'
-      soname_spec='$libname$release$shared_ext$major'
-      # unpreferred sharedlib libNAME.so.V and symlink libNAME.so need extra handling
-      postinstall_cmds='test -z "$dlname" || $install_shared_prog $dir/$dlname $destdir/$dlname~test -z "$tstripme" || test -z "$striplib" || $striplib $destdir/$dlname~test -n "$linkname" || linkname=$realname~func_stripname "" ".a" "$linkname"~(cd "$destdir" && $LN_S -f $dlname $func_stripname_result.so)'
-      postuninstall_cmds='test -z "$dlname" || func_append rmfiles " $odir/$dlname"~for n in $old_library $library_names; do :; done~func_stripname "" ".a" "$n"~func_append rmfiles " $odir/$func_stripname_result.so"'
-      ;;
-    esac
+      library_names_spec='${libname}${release}.a $libname.a'
+      soname_spec='${libname}${release}${shared_ext}$major'
+    fi
     shlibpath_var=LIBPATH
   fi
   ;;
@@ -2491,18 +2318,18 @@ amigaos*)
   powerpc)
     # Since July 2007 AmigaOS4 officially supports .so libraries.
     # When compiling the executable, add -use-dynld -Lsobjs: to the compileline.
-    library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
     ;;
   m68k)
     library_names_spec='$libname.ixlibrary $libname.a'
     # Create ${libname}_ixlibrary.a entries in /sys/libs.
-    finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([[^/]]*\)\.ixlibrary$%\1%'\''`; $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done'
+    finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([[^/]]*\)\.ixlibrary$%\1%'\''`; test $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done'
     ;;
   esac
   ;;
 
 beos*)
-  library_names_spec='$libname$shared_ext'
+  library_names_spec='${libname}${shared_ext}'
   dynamic_linker="$host_os ld.so"
   shlibpath_var=LIBRARY_PATH
   ;;
@@ -2510,8 +2337,8 @@ beos*)
 bsdi[[45]]*)
   version_type=linux # correct to gnu/linux during the next big refactor
   need_version=no
-  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
-  soname_spec='$libname$release$shared_ext$major'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
   finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir'
   shlibpath_var=LD_LIBRARY_PATH
   sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib"
@@ -2523,7 +2350,7 @@ bsdi[[45]]*)
 
 cygwin* | mingw* | pw32* | cegcc*)
   version_type=windows
-  shrext_cmds=.dll
+  shrext_cmds=".dll"
   need_version=no
   need_lib_prefix=no
 
@@ -2532,8 +2359,8 @@ cygwin* | mingw* | pw32* | cegcc*)
     # gcc
     library_names_spec='$libname.dll.a'
     # DLL is installed to $(libdir)/../bin by postinstall_cmds
-    postinstall_cmds='base_file=`basename \$file`~
-      dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~
+    postinstall_cmds='base_file=`basename \${file}`~
+      dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~
       dldir=$destdir/`dirname \$dlpath`~
       test -d \$dldir || mkdir -p \$dldir~
       $install_prog $dir/$dlname \$dldir/$dlname~
@@ -2549,17 +2376,17 @@ cygwin* | mingw* | pw32* | cegcc*)
     case $host_os in
     cygwin*)
       # Cygwin DLLs use 'cyg' prefix rather than 'lib'
-      soname_spec='`echo $libname | sed -e 's/^lib/cyg/'``echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext'
+      soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}'
 m4_if([$1], [],[
       sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/lib/w32api"])
       ;;
     mingw* | cegcc*)
       # MinGW DLLs use traditional 'lib' prefix
-      soname_spec='$libname`echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext'
+      soname_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}'
       ;;
     pw32*)
       # pw32 DLLs use 'pw' prefix rather than 'lib'
-      library_names_spec='`echo $libname | sed -e 's/^lib/pw/'``echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext'
+      library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}'
       ;;
     esac
     dynamic_linker='Win32 ld.exe'
@@ -2568,8 +2395,8 @@ m4_if([$1], [],[
   *,cl*)
     # Native MSVC
     libname_spec='$name'
-    soname_spec='$libname`echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext'
-    library_names_spec='$libname.dll.lib'
+    soname_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}'
+    library_names_spec='${libname}.dll.lib'
 
     case $build_os in
     mingw*)
@@ -2596,7 +2423,7 @@ m4_if([$1], [],[
       sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"`
       ;;
     *)
-      sys_lib_search_path_spec=$LIB
+      sys_lib_search_path_spec="$LIB"
       if $ECHO "$sys_lib_search_path_spec" | [$GREP ';[c-zC-Z]:/' >/dev/null]; then
         # It is most probably a Windows format PATH.
         sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'`
@@ -2609,8 +2436,8 @@ m4_if([$1], [],[
     esac
 
     # DLL is installed to $(libdir)/../bin by postinstall_cmds
-    postinstall_cmds='base_file=`basename \$file`~
-      dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~
+    postinstall_cmds='base_file=`basename \${file}`~
+      dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~
       dldir=$destdir/`dirname \$dlpath`~
       test -d \$dldir || mkdir -p \$dldir~
       $install_prog $dir/$dlname \$dldir/$dlname'
@@ -2623,7 +2450,7 @@ m4_if([$1], [],[
 
   *)
     # Assume MSVC wrapper
-    library_names_spec='$libname`echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext $libname.lib'
+    library_names_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext} $libname.lib'
     dynamic_linker='Win32 ld.exe'
     ;;
   esac
@@ -2636,8 +2463,8 @@ darwin* | rhapsody*)
   version_type=darwin
   need_lib_prefix=no
   need_version=no
-  library_names_spec='$libname$release$major$shared_ext $libname$shared_ext'
-  soname_spec='$libname$release$major$shared_ext'
+  library_names_spec='${libname}${release}${major}$shared_ext ${libname}$shared_ext'
+  soname_spec='${libname}${release}${major}$shared_ext'
   shlibpath_overrides_runpath=yes
   shlibpath_var=DYLD_LIBRARY_PATH
   shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`'
@@ -2650,8 +2477,8 @@ dgux*)
   version_type=linux # correct to gnu/linux during the next big refactor
   need_lib_prefix=no
   need_version=no
-  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
-  soname_spec='$libname$release$shared_ext$major'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext'
+  soname_spec='${libname}${release}${shared_ext}$major'
   shlibpath_var=LD_LIBRARY_PATH
   ;;
 
@@ -2669,13 +2496,12 @@ freebsd* | dragonfly*)
   version_type=freebsd-$objformat
   case $version_type in
     freebsd-elf*)
-      library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
-      soname_spec='$libname$release$shared_ext$major'
+      library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}'
       need_version=no
       need_lib_prefix=no
       ;;
     freebsd-*)
-      library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix'
+      library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix'
       need_version=yes
       ;;
   esac
@@ -2705,10 +2531,10 @@ haiku*)
   need_lib_prefix=no
   need_version=no
   dynamic_linker="$host_os runtime_loader"
-  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
-  soname_spec='$libname$release$shared_ext$major'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
   shlibpath_var=LIBRARY_PATH
-  shlibpath_overrides_runpath=no
+  shlibpath_overrides_runpath=yes
   sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib'
   hardcode_into_libs=yes
   ;;
@@ -2726,15 +2552,14 @@ hpux9* | hpux10* | hpux11*)
     dynamic_linker="$host_os dld.so"
     shlibpath_var=LD_LIBRARY_PATH
     shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
-    library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
-    soname_spec='$libname$release$shared_ext$major'
-    if test 32 = "$HPUX_IA64_MODE"; then
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+    soname_spec='${libname}${release}${shared_ext}$major'
+    if test "X$HPUX_IA64_MODE" = X32; then
       sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib"
-      sys_lib_dlsearch_path_spec=/usr/lib/hpux32
     else
       sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64"
-      sys_lib_dlsearch_path_spec=/usr/lib/hpux64
     fi
+    sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
     ;;
   hppa*64*)
     shrext_cmds='.sl'
@@ -2742,8 +2567,8 @@ hpux9* | hpux10* | hpux11*)
     dynamic_linker="$host_os dld.sl"
     shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH
     shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
-    library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
-    soname_spec='$libname$release$shared_ext$major'
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+    soname_spec='${libname}${release}${shared_ext}$major'
     sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64"
     sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
     ;;
@@ -2752,8 +2577,8 @@ hpux9* | hpux10* | hpux11*)
     dynamic_linker="$host_os dld.sl"
     shlibpath_var=SHLIB_PATH
     shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH
-    library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
-    soname_spec='$libname$release$shared_ext$major'
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+    soname_spec='${libname}${release}${shared_ext}$major'
     ;;
   esac
   # HP-UX runs *really* slowly unless shared libraries are mode 555, ...
@@ -2766,8 +2591,8 @@ interix[[3-9]]*)
   version_type=linux # correct to gnu/linux during the next big refactor
   need_lib_prefix=no
   need_version=no
-  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
-  soname_spec='$libname$release$shared_ext$major'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
   dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)'
   shlibpath_var=LD_LIBRARY_PATH
   shlibpath_overrides_runpath=no
@@ -2778,7 +2603,7 @@ irix5* | irix6* | nonstopux*)
   case $host_os in
     nonstopux*) version_type=nonstopux ;;
     *)
-	if test yes = "$lt_cv_prog_gnu_ld"; then
+	if test "$lt_cv_prog_gnu_ld" = yes; then
 		version_type=linux # correct to gnu/linux during the next big refactor
 	else
 		version_type=irix
@@ -2786,8 +2611,8 @@ irix5* | irix6* | nonstopux*)
   esac
   need_lib_prefix=no
   need_version=no
-  soname_spec='$libname$release$shared_ext$major'
-  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$release$shared_ext $libname$shared_ext'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}'
   case $host_os in
   irix5* | nonstopux*)
     libsuff= shlibsuff=
@@ -2806,8 +2631,8 @@ irix5* | irix6* | nonstopux*)
   esac
   shlibpath_var=LD_LIBRARY${shlibsuff}_PATH
   shlibpath_overrides_runpath=no
-  sys_lib_search_path_spec="/usr/lib$libsuff /lib$libsuff /usr/local/lib$libsuff"
-  sys_lib_dlsearch_path_spec="/usr/lib$libsuff /lib$libsuff"
+  sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}"
+  sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}"
   hardcode_into_libs=yes
   ;;
 
@@ -2816,33 +2641,13 @@ linux*oldld* | linux*aout* | linux*coff*)
   dynamic_linker=no
   ;;
 
-linux*android*)
-  version_type=none # Android doesn't support versioned libraries.
-  need_lib_prefix=no
-  need_version=no
-  library_names_spec='$libname$release$shared_ext'
-  soname_spec='$libname$release$shared_ext'
-  finish_cmds=
-  shlibpath_var=LD_LIBRARY_PATH
-  shlibpath_overrides_runpath=yes
-
-  # This implies no fast_install, which is unacceptable.
-  # Some rework will be needed to allow for fast_install
-  # before this can be enabled.
-  hardcode_into_libs=yes
-
-  dynamic_linker='Android linker'
-  # Don't embed -rpath directories since the linker doesn't support them.
-  _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
-  ;;
-
 # This must be glibc/ELF.
 linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*)
   version_type=linux # correct to gnu/linux during the next big refactor
   need_lib_prefix=no
   need_version=no
-  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
-  soname_spec='$libname$release$shared_ext$major'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
   finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir'
   shlibpath_var=LD_LIBRARY_PATH
   shlibpath_overrides_runpath=no
@@ -2867,12 +2672,7 @@ linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*)
   # before this can be enabled.
   hardcode_into_libs=yes
 
-  # Ideally, we could use ldconfig to report *all* directores which are
-  # searched for libraries, however this is still not possible.  Aside from not
-  # being certain /sbin/ldconfig is available, command
-  # 'ldconfig -N -X -v | grep ^/' on 64bit Fedora does not report /usr/lib64,
-  # even though it is searched at run-time.  Try to do the best guess by
-  # appending ld.so.conf contents (and includes) to the search path.
+  # Append ld.so.conf contents to the search path
   if test -f /etc/ld.so.conf; then
     lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \[$]2)); skip = 1; } { if (!skip) print \[$]0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[	 ]*hwcap[	 ]/d;s/[:,	]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '`
     sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra"
@@ -2904,12 +2704,12 @@ netbsd*)
   need_lib_prefix=no
   need_version=no
   if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
-    library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix'
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
     finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
     dynamic_linker='NetBSD (a.out) ld.so'
   else
-    library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
-    soname_spec='$libname$release$shared_ext$major'
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+    soname_spec='${libname}${release}${shared_ext}$major'
     dynamic_linker='NetBSD ld.elf_so'
   fi
   shlibpath_var=LD_LIBRARY_PATH
@@ -2919,7 +2719,7 @@ netbsd*)
 
 newsos6)
   version_type=linux # correct to gnu/linux during the next big refactor
-  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
   shlibpath_var=LD_LIBRARY_PATH
   shlibpath_overrides_runpath=yes
   ;;
@@ -2928,68 +2728,58 @@ newsos6)
   version_type=qnx
   need_lib_prefix=no
   need_version=no
-  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
-  soname_spec='$libname$release$shared_ext$major'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
   shlibpath_var=LD_LIBRARY_PATH
   shlibpath_overrides_runpath=no
   hardcode_into_libs=yes
   dynamic_linker='ldqnx.so'
   ;;
 
-openbsd* | bitrig*)
+openbsd*)
   version_type=sunos
-  sys_lib_dlsearch_path_spec=/usr/lib
+  sys_lib_dlsearch_path_spec="/usr/lib"
   need_lib_prefix=no
-  if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then
-    need_version=no
-  else
-    need_version=yes
-  fi
-  library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix'
+  # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs.
+  case $host_os in
+    openbsd3.3 | openbsd3.3.*)	need_version=yes ;;
+    *)				need_version=no  ;;
+  esac
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
   finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
   shlibpath_var=LD_LIBRARY_PATH
-  shlibpath_overrides_runpath=yes
+  if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+    case $host_os in
+      openbsd2.[[89]] | openbsd2.[[89]].*)
+	shlibpath_overrides_runpath=no
+	;;
+      *)
+	shlibpath_overrides_runpath=yes
+	;;
+      esac
+  else
+    shlibpath_overrides_runpath=yes
+  fi
   ;;
 
 os2*)
   libname_spec='$name'
-  version_type=windows
-  shrext_cmds=.dll
-  need_version=no
+  shrext_cmds=".dll"
   need_lib_prefix=no
-  # OS/2 can only load a DLL with a base name of 8 characters or less.
-  soname_spec='`test -n "$os2dllname" && libname="$os2dllname";
-    v=$($ECHO $release$versuffix | tr -d .-);
-    n=$($ECHO $libname | cut -b -$((8 - ${#v})) | tr . _);
-    $ECHO $n$v`$shared_ext'
-  library_names_spec='${libname}_dll.$libext'
+  library_names_spec='$libname${shared_ext} $libname.a'
   dynamic_linker='OS/2 ld.exe'
-  shlibpath_var=BEGINLIBPATH
-  sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib"
-  sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
-  postinstall_cmds='base_file=`basename \$file`~
-    dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; $ECHO \$dlname'\''`~
-    dldir=$destdir/`dirname \$dlpath`~
-    test -d \$dldir || mkdir -p \$dldir~
-    $install_prog $dir/$dlname \$dldir/$dlname~
-    chmod a+x \$dldir/$dlname~
-    if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then
-      eval '\''$striplib \$dldir/$dlname'\'' || exit \$?;
-    fi'
-  postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; $ECHO \$dlname'\''`~
-    dlpath=$dir/\$dldll~
-    $RM \$dlpath'
+  shlibpath_var=LIBPATH
   ;;
 
 osf3* | osf4* | osf5*)
   version_type=osf
   need_lib_prefix=no
   need_version=no
-  soname_spec='$libname$release$shared_ext$major'
-  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
   shlibpath_var=LD_LIBRARY_PATH
   sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib"
-  sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
+  sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec"
   ;;
 
 rdos*)
@@ -3000,8 +2790,8 @@ solaris*)
   version_type=linux # correct to gnu/linux during the next big refactor
   need_lib_prefix=no
   need_version=no
-  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
-  soname_spec='$libname$release$shared_ext$major'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
   shlibpath_var=LD_LIBRARY_PATH
   shlibpath_overrides_runpath=yes
   hardcode_into_libs=yes
@@ -3011,11 +2801,11 @@ solaris*)
 
 sunos4*)
   version_type=sunos
-  library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
   finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir'
   shlibpath_var=LD_LIBRARY_PATH
   shlibpath_overrides_runpath=yes
-  if test yes = "$with_gnu_ld"; then
+  if test "$with_gnu_ld" = yes; then
     need_lib_prefix=no
   fi
   need_version=yes
@@ -3023,8 +2813,8 @@ sunos4*)
 
 sysv4 | sysv4.3*)
   version_type=linux # correct to gnu/linux during the next big refactor
-  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
-  soname_spec='$libname$release$shared_ext$major'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
   shlibpath_var=LD_LIBRARY_PATH
   case $host_vendor in
     sni)
@@ -3045,24 +2835,24 @@ sysv4 | sysv4.3*)
   ;;
 
 sysv4*MP*)
-  if test -d /usr/nec; then
+  if test -d /usr/nec ;then
     version_type=linux # correct to gnu/linux during the next big refactor
-    library_names_spec='$libname$shared_ext.$versuffix $libname$shared_ext.$major $libname$shared_ext'
-    soname_spec='$libname$shared_ext.$major'
+    library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}'
+    soname_spec='$libname${shared_ext}.$major'
     shlibpath_var=LD_LIBRARY_PATH
   fi
   ;;
 
 sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
-  version_type=sco
+  version_type=freebsd-elf
   need_lib_prefix=no
   need_version=no
-  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext $libname$shared_ext'
-  soname_spec='$libname$release$shared_ext$major'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
   shlibpath_var=LD_LIBRARY_PATH
   shlibpath_overrides_runpath=yes
   hardcode_into_libs=yes
-  if test yes = "$with_gnu_ld"; then
+  if test "$with_gnu_ld" = yes; then
     sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib'
   else
     sys_lib_search_path_spec='/usr/ccs/lib /usr/lib'
@@ -3080,7 +2870,7 @@ tpf*)
   version_type=linux # correct to gnu/linux during the next big refactor
   need_lib_prefix=no
   need_version=no
-  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
   shlibpath_var=LD_LIBRARY_PATH
   shlibpath_overrides_runpath=no
   hardcode_into_libs=yes
@@ -3088,8 +2878,8 @@ tpf*)
 
 uts4*)
   version_type=linux # correct to gnu/linux during the next big refactor
-  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
-  soname_spec='$libname$release$shared_ext$major'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
   shlibpath_var=LD_LIBRARY_PATH
   ;;
 
@@ -3098,30 +2888,20 @@ uts4*)
   ;;
 esac
 AC_MSG_RESULT([$dynamic_linker])
-test no = "$dynamic_linker" && can_build_shared=no
+test "$dynamic_linker" = no && can_build_shared=no
 
 variables_saved_for_relink="PATH $shlibpath_var $runpath_var"
-if test yes = "$GCC"; then
+if test "$GCC" = yes; then
   variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH"
 fi
 
-if test set = "${lt_cv_sys_lib_search_path_spec+set}"; then
-  sys_lib_search_path_spec=$lt_cv_sys_lib_search_path_spec
+if test "${lt_cv_sys_lib_search_path_spec+set}" = set; then
+  sys_lib_search_path_spec="$lt_cv_sys_lib_search_path_spec"
 fi
-
-if test set = "${lt_cv_sys_lib_dlsearch_path_spec+set}"; then
-  sys_lib_dlsearch_path_spec=$lt_cv_sys_lib_dlsearch_path_spec
+if test "${lt_cv_sys_lib_dlsearch_path_spec+set}" = set; then
+  sys_lib_dlsearch_path_spec="$lt_cv_sys_lib_dlsearch_path_spec"
 fi
 
-# remember unaugmented sys_lib_dlsearch_path content for libtool script decls...
-configure_time_dlsearch_path=$sys_lib_dlsearch_path_spec
-
-# ... but it needs LT_SYS_LIBRARY_PATH munging for other configure-time code
-func_munge_path_list sys_lib_dlsearch_path_spec "$LT_SYS_LIBRARY_PATH"
-
-# to be used as default LT_SYS_LIBRARY_PATH value in generated libtool
-configure_time_lt_sys_library_path=$LT_SYS_LIBRARY_PATH
-
 _LT_DECL([], [variables_saved_for_relink], [1],
     [Variables whose values should be saved in libtool wrapper scripts and
     restored at link time])
@@ -3154,41 +2934,39 @@ _LT_DECL([], [hardcode_into_libs], [0],
     [Whether we should hardcode library paths into libraries])
 _LT_DECL([], [sys_lib_search_path_spec], [2],
     [Compile-time system search path for libraries])
-_LT_DECL([sys_lib_dlsearch_path_spec], [configure_time_dlsearch_path], [2],
-    [Detected run-time system search path for libraries])
-_LT_DECL([], [configure_time_lt_sys_library_path], [2],
-    [Explicit LT_SYS_LIBRARY_PATH set during ./configure time])
+_LT_DECL([], [sys_lib_dlsearch_path_spec], [2],
+    [Run-time system search path for libraries])
 ])# _LT_SYS_DYNAMIC_LINKER
 
 
 # _LT_PATH_TOOL_PREFIX(TOOL)
 # --------------------------
-# find a file program that can recognize shared library
+# find a file program which can recognize shared library
 AC_DEFUN([_LT_PATH_TOOL_PREFIX],
 [m4_require([_LT_DECL_EGREP])dnl
 AC_MSG_CHECKING([for $1])
 AC_CACHE_VAL(lt_cv_path_MAGIC_CMD,
 [case $MAGIC_CMD in
 [[\\/*] |  ?:[\\/]*])
-  lt_cv_path_MAGIC_CMD=$MAGIC_CMD # Let the user override the test with a path.
+  lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path.
   ;;
 *)
-  lt_save_MAGIC_CMD=$MAGIC_CMD
-  lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR
+  lt_save_MAGIC_CMD="$MAGIC_CMD"
+  lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
 dnl $ac_dummy forces splitting on constant user-supplied paths.
 dnl POSIX.2 word splitting is done only on the output of word expansions,
 dnl not every word.  This closes a longstanding sh security hole.
   ac_dummy="m4_if([$2], , $PATH, [$2])"
   for ac_dir in $ac_dummy; do
-    IFS=$lt_save_ifs
+    IFS="$lt_save_ifs"
     test -z "$ac_dir" && ac_dir=.
-    if test -f "$ac_dir/$1"; then
-      lt_cv_path_MAGIC_CMD=$ac_dir/"$1"
+    if test -f $ac_dir/$1; then
+      lt_cv_path_MAGIC_CMD="$ac_dir/$1"
       if test -n "$file_magic_test_file"; then
 	case $deplibs_check_method in
 	"file_magic "*)
 	  file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"`
-	  MAGIC_CMD=$lt_cv_path_MAGIC_CMD
+	  MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
 	  if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null |
 	    $EGREP "$file_magic_regex" > /dev/null; then
 	    :
@@ -3211,11 +2989,11 @@ _LT_EOF
       break
     fi
   done
-  IFS=$lt_save_ifs
-  MAGIC_CMD=$lt_save_MAGIC_CMD
+  IFS="$lt_save_ifs"
+  MAGIC_CMD="$lt_save_MAGIC_CMD"
   ;;
 esac])
-MAGIC_CMD=$lt_cv_path_MAGIC_CMD
+MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
 if test -n "$MAGIC_CMD"; then
   AC_MSG_RESULT($MAGIC_CMD)
 else
@@ -3233,7 +3011,7 @@ dnl AC_DEFUN([AC_PATH_TOOL_PREFIX], [])
 
 # _LT_PATH_MAGIC
 # --------------
-# find a file program that can recognize a shared library
+# find a file program which can recognize a shared library
 m4_defun([_LT_PATH_MAGIC],
 [_LT_PATH_TOOL_PREFIX(${ac_tool_prefix}file, /usr/bin$PATH_SEPARATOR$PATH)
 if test -z "$lt_cv_path_MAGIC_CMD"; then
@@ -3260,16 +3038,16 @@ m4_require([_LT_PROG_ECHO_BACKSLASH])dnl
 AC_ARG_WITH([gnu-ld],
     [AS_HELP_STRING([--with-gnu-ld],
 	[assume the C compiler uses GNU ld @<:@default=no@:>@])],
-    [test no = "$withval" || with_gnu_ld=yes],
+    [test "$withval" = no || with_gnu_ld=yes],
     [with_gnu_ld=no])dnl
 
 ac_prog=ld
-if test yes = "$GCC"; then
+if test "$GCC" = yes; then
   # Check if gcc -print-prog-name=ld gives a path.
   AC_MSG_CHECKING([for ld used by $CC])
   case $host in
   *-*-mingw*)
-    # gcc leaves a trailing carriage return, which upsets mingw
+    # gcc leaves a trailing carriage return which upsets mingw
     ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;;
   *)
     ac_prog=`($CC -print-prog-name=ld) 2>&5` ;;
@@ -3283,7 +3061,7 @@ if test yes = "$GCC"; then
       while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do
 	ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"`
       done
-      test -z "$LD" && LD=$ac_prog
+      test -z "$LD" && LD="$ac_prog"
       ;;
   "")
     # If it fails, then pretend we aren't using GCC.
@@ -3294,37 +3072,37 @@ if test yes = "$GCC"; then
     with_gnu_ld=unknown
     ;;
   esac
-elif test yes = "$with_gnu_ld"; then
+elif test "$with_gnu_ld" = yes; then
   AC_MSG_CHECKING([for GNU ld])
 else
   AC_MSG_CHECKING([for non-GNU ld])
 fi
 AC_CACHE_VAL(lt_cv_path_LD,
 [if test -z "$LD"; then
-  lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR
+  lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
   for ac_dir in $PATH; do
-    IFS=$lt_save_ifs
+    IFS="$lt_save_ifs"
     test -z "$ac_dir" && ac_dir=.
     if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then
-      lt_cv_path_LD=$ac_dir/$ac_prog
+      lt_cv_path_LD="$ac_dir/$ac_prog"
       # Check to see if the program is GNU ld.  I'd rather use --version,
       # but apparently some variants of GNU ld only accept -v.
       # Break only if it was the GNU/non-GNU ld that we prefer.
       case `"$lt_cv_path_LD" -v 2>&1 </dev/null` in
       *GNU* | *'with BFD'*)
-	test no != "$with_gnu_ld" && break
+	test "$with_gnu_ld" != no && break
 	;;
       *)
-	test yes != "$with_gnu_ld" && break
+	test "$with_gnu_ld" != yes && break
 	;;
       esac
     fi
   done
-  IFS=$lt_save_ifs
+  IFS="$lt_save_ifs"
 else
-  lt_cv_path_LD=$LD # Let the user override the test with a path.
+  lt_cv_path_LD="$LD" # Let the user override the test with a path.
 fi])
-LD=$lt_cv_path_LD
+LD="$lt_cv_path_LD"
 if test -n "$LD"; then
   AC_MSG_RESULT($LD)
 else
@@ -3378,13 +3156,13 @@ esac
 reload_cmds='$LD$reload_flag -o $output$reload_objs'
 case $host_os in
   cygwin* | mingw* | pw32* | cegcc*)
-    if test yes != "$GCC"; then
+    if test "$GCC" != yes; then
       reload_cmds=false
     fi
     ;;
   darwin*)
-    if test yes = "$GCC"; then
-      reload_cmds='$LTCC $LTCFLAGS -nostdlib $wl-r -o $output$reload_objs'
+    if test "$GCC" = yes; then
+      reload_cmds='$LTCC $LTCFLAGS -nostdlib ${wl}-r -o $output$reload_objs'
     else
       reload_cmds='$LD$reload_flag -o $output$reload_objs'
     fi
@@ -3395,43 +3173,6 @@ _LT_TAGDECL([], [reload_cmds], [2])dnl
 ])# _LT_CMD_RELOAD
 
 
-# _LT_PATH_DD
-# -----------
-# find a working dd
-m4_defun([_LT_PATH_DD],
-[AC_CACHE_CHECK([for a working dd], [ac_cv_path_lt_DD],
-[printf 0123456789abcdef0123456789abcdef >conftest.i
-cat conftest.i conftest.i >conftest2.i
-: ${lt_DD:=$DD}
-AC_PATH_PROGS_FEATURE_CHECK([lt_DD], [dd],
-[if "$ac_path_lt_DD" bs=32 count=1 <conftest2.i >conftest.out 2>/dev/null; then
-  cmp -s conftest.i conftest.out \
-  && ac_cv_path_lt_DD="$ac_path_lt_DD" ac_path_lt_DD_found=:
-fi])
-rm -f conftest.i conftest2.i conftest.out])
-])# _LT_PATH_DD
-
-
-# _LT_CMD_TRUNCATE
-# ----------------
-# find command to truncate a binary pipe
-m4_defun([_LT_CMD_TRUNCATE],
-[m4_require([_LT_PATH_DD])
-AC_CACHE_CHECK([how to truncate binary pipes], [lt_cv_truncate_bin],
-[printf 0123456789abcdef0123456789abcdef >conftest.i
-cat conftest.i conftest.i >conftest2.i
-lt_cv_truncate_bin=
-if "$ac_cv_path_lt_DD" bs=32 count=1 <conftest2.i >conftest.out 2>/dev/null; then
-  cmp -s conftest.i conftest.out \
-  && lt_cv_truncate_bin="$ac_cv_path_lt_DD bs=4096 count=1"
-fi
-rm -f conftest.i conftest2.i conftest.out
-test -z "$lt_cv_truncate_bin" && lt_cv_truncate_bin="$SED -e 4q"])
-_LT_DECL([lt_truncate_bin], [lt_cv_truncate_bin], [1],
-  [Command to truncate a binary pipe])
-])# _LT_CMD_TRUNCATE
-
-
 # _LT_CHECK_MAGIC_METHOD
 # ----------------------
 # how to check for library dependencies
@@ -3447,13 +3188,13 @@ lt_cv_deplibs_check_method='unknown'
 # Need to set the preceding variable on all platforms that support
 # interlibrary dependencies.
 # 'none' -- dependencies not supported.
-# 'unknown' -- same as none, but documents that we really don't know.
+# `unknown' -- same as none, but documents that we really don't know.
 # 'pass_all' -- all dependencies passed with no checks.
 # 'test_compile' -- check by making test program.
 # 'file_magic [[regex]]' -- check by looking for files in library path
-# that responds to the $file_magic_cmd with a given extended regex.
-# If you have 'file' or equivalent on your system and you're not sure
-# whether 'pass_all' will *always* work, you probably want this one.
+# which responds to the $file_magic_cmd with a given extended regex.
+# If you have `file' or equivalent on your system and you're not sure
+# whether `pass_all' will *always* work, you probably want this one.
 
 case $host_os in
 aix[[4-9]]*)
@@ -3480,7 +3221,8 @@ mingw* | pw32*)
   # Base MSYS/MinGW do not provide the 'file' command needed by
   # func_win32_libid shell function, so use a weaker test based on 'objdump',
   # unless we find 'file', for example because we are cross-compiling.
-  if ( file / ) >/dev/null 2>&1; then
+  # func_win32_libid assumes BSD nm, so disallow it if using MS dumpbin.
+  if ( test "$lt_cv_nm_interface" = "BSD nm" && file / ) >/dev/null 2>&1; then
     lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL'
     lt_cv_file_magic_cmd='func_win32_libid'
   else
@@ -3576,8 +3318,8 @@ newos6*)
   lt_cv_deplibs_check_method=pass_all
   ;;
 
-openbsd* | bitrig*)
-  if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then
+openbsd*)
+  if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
     lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|\.so|_pic\.a)$'
   else
     lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$'
@@ -3630,9 +3372,6 @@ sysv4 | sysv4.3*)
 tpf*)
   lt_cv_deplibs_check_method=pass_all
   ;;
-os2*)
-  lt_cv_deplibs_check_method=pass_all
-  ;;
 esac
 ])
 
@@ -3673,38 +3412,33 @@ AC_DEFUN([LT_PATH_NM],
 AC_CACHE_CHECK([for BSD- or MS-compatible name lister (nm)], lt_cv_path_NM,
 [if test -n "$NM"; then
   # Let the user override the test.
-  lt_cv_path_NM=$NM
+  lt_cv_path_NM="$NM"
 else
-  lt_nm_to_check=${ac_tool_prefix}nm
+  lt_nm_to_check="${ac_tool_prefix}nm"
   if test -n "$ac_tool_prefix" && test "$build" = "$host"; then
     lt_nm_to_check="$lt_nm_to_check nm"
   fi
   for lt_tmp_nm in $lt_nm_to_check; do
-    lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR
+    lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
     for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do
-      IFS=$lt_save_ifs
+      IFS="$lt_save_ifs"
       test -z "$ac_dir" && ac_dir=.
-      tmp_nm=$ac_dir/$lt_tmp_nm
-      if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext"; then
+      tmp_nm="$ac_dir/$lt_tmp_nm"
+      if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext" ; then
 	# Check to see if the nm accepts a BSD-compat flag.
-	# Adding the 'sed 1q' prevents false positives on HP-UX, which says:
+	# Adding the `sed 1q' prevents false positives on HP-UX, which says:
 	#   nm: unknown option "B" ignored
 	# Tru64's nm complains that /dev/null is an invalid object file
-	# MSYS converts /dev/null to NUL, MinGW nm treats NUL as empty
-	case $build_os in
-	mingw*) lt_bad_file=conftest.nm/nofile ;;
-	*) lt_bad_file=/dev/null ;;
-	esac
-	case `"$tmp_nm" -B $lt_bad_file 2>&1 | sed '1q'` in
-	*$lt_bad_file* | *'Invalid file or object type'*)
+	case `"$tmp_nm" -B /dev/null 2>&1 | sed '1q'` in
+	*/dev/null* | *'Invalid file or object type'*)
 	  lt_cv_path_NM="$tmp_nm -B"
-	  break 2
+	  break
 	  ;;
 	*)
 	  case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in
 	  */dev/null*)
 	    lt_cv_path_NM="$tmp_nm -p"
-	    break 2
+	    break
 	    ;;
 	  *)
 	    lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but
@@ -3715,21 +3449,21 @@ else
 	esac
       fi
     done
-    IFS=$lt_save_ifs
+    IFS="$lt_save_ifs"
   done
   : ${lt_cv_path_NM=no}
 fi])
-if test no != "$lt_cv_path_NM"; then
-  NM=$lt_cv_path_NM
+if test "$lt_cv_path_NM" != "no"; then
+  NM="$lt_cv_path_NM"
 else
   # Didn't find any BSD compatible name lister, look for dumpbin.
   if test -n "$DUMPBIN"; then :
     # Let the user override the test.
   else
     AC_CHECK_TOOLS(DUMPBIN, [dumpbin "link -dump"], :)
-    case `$DUMPBIN -symbols -headers /dev/null 2>&1 | sed '1q'` in
+    case `$DUMPBIN -symbols /dev/null 2>&1 | sed '1q'` in
     *COFF*)
-      DUMPBIN="$DUMPBIN -symbols -headers"
+      DUMPBIN="$DUMPBIN -symbols"
       ;;
     *)
       DUMPBIN=:
@@ -3737,8 +3471,8 @@ else
     esac
   fi
   AC_SUBST([DUMPBIN])
-  if test : != "$DUMPBIN"; then
-    NM=$DUMPBIN
+  if test "$DUMPBIN" != ":"; then
+    NM="$DUMPBIN"
   fi
 fi
 test -z "$NM" && NM=nm
@@ -3784,8 +3518,8 @@ lt_cv_sharedlib_from_linklib_cmd,
 
 case $host_os in
 cygwin* | mingw* | pw32* | cegcc*)
-  # two different shell functions defined in ltmain.sh;
-  # decide which one to use based on capabilities of $DLLTOOL
+  # two different shell functions defined in ltmain.sh
+  # decide which to use based on capabilities of $DLLTOOL
   case `$DLLTOOL --help 2>&1` in
   *--identify-strict*)
     lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib
@@ -3797,7 +3531,7 @@ cygwin* | mingw* | pw32* | cegcc*)
   ;;
 *)
   # fallback: assume linklib IS sharedlib
-  lt_cv_sharedlib_from_linklib_cmd=$ECHO
+  lt_cv_sharedlib_from_linklib_cmd="$ECHO"
   ;;
 esac
 ])
@@ -3824,28 +3558,13 @@ AC_CACHE_CHECK([if $MANIFEST_TOOL is a manifest tool], [lt_cv_path_mainfest_tool
     lt_cv_path_mainfest_tool=yes
   fi
   rm -f conftest*])
-if test yes != "$lt_cv_path_mainfest_tool"; then
+if test "x$lt_cv_path_mainfest_tool" != xyes; then
   MANIFEST_TOOL=:
 fi
 _LT_DECL([], [MANIFEST_TOOL], [1], [Manifest tool])dnl
 ])# _LT_PATH_MANIFEST_TOOL
 
 
-# _LT_DLL_DEF_P([FILE])
-# ---------------------
-# True iff FILE is a Windows DLL '.def' file.
-# Keep in sync with func_dll_def_p in the libtool script
-AC_DEFUN([_LT_DLL_DEF_P],
-[dnl
-  test DEF = "`$SED -n dnl
-    -e '\''s/^[[	 ]]*//'\'' dnl Strip leading whitespace
-    -e '\''/^\(;.*\)*$/d'\'' dnl      Delete empty lines and comments
-    -e '\''s/^\(EXPORTS\|LIBRARY\)\([[	 ]].*\)*$/DEF/p'\'' dnl
-    -e q dnl                          Only consider the first "real" line
-    $1`" dnl
-])# _LT_DLL_DEF_P
-
-
 # LT_LIB_M
 # --------
 # check for math library
@@ -3857,11 +3576,11 @@ case $host in
   # These system don't have libm, or don't need it
   ;;
 *-ncr-sysv4.3*)
-  AC_CHECK_LIB(mw, _mwvalidcheckl, LIBM=-lmw)
+  AC_CHECK_LIB(mw, _mwvalidcheckl, LIBM="-lmw")
   AC_CHECK_LIB(m, cos, LIBM="$LIBM -lm")
   ;;
 *)
-  AC_CHECK_LIB(m, cos, LIBM=-lm)
+  AC_CHECK_LIB(m, cos, LIBM="-lm")
   ;;
 esac
 AC_SUBST([LIBM])
@@ -3880,7 +3599,7 @@ m4_defun([_LT_COMPILER_NO_RTTI],
 
 _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=
 
-if test yes = "$GCC"; then
+if test "$GCC" = yes; then
   case $cc_basename in
   nvcc*)
     _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -Xcompiler -fno-builtin' ;;
@@ -3932,7 +3651,7 @@ cygwin* | mingw* | pw32* | cegcc*)
   symcode='[[ABCDGISTW]]'
   ;;
 hpux*)
-  if test ia64 = "$host_cpu"; then
+  if test "$host_cpu" = ia64; then
     symcode='[[ABCDEGRST]]'
   fi
   ;;
@@ -3965,44 +3684,14 @@ case `$NM -V 2>&1` in
   symcode='[[ABCDGIRSTW]]' ;;
 esac
 
-if test "$lt_cv_nm_interface" = "MS dumpbin"; then
-  # Gets list of data symbols to import.
-  lt_cv_sys_global_symbol_to_import="sed -n -e 's/^I .* \(.*\)$/\1/p'"
-  # Adjust the below global symbol transforms to fixup imported variables.
-  lt_cdecl_hook=" -e 's/^I .* \(.*\)$/extern __declspec(dllimport) char \1;/p'"
-  lt_c_name_hook=" -e 's/^I .* \(.*\)$/  {\"\1\", (void *) 0},/p'"
-  lt_c_name_lib_hook="\
-  -e 's/^I .* \(lib.*\)$/  {\"\1\", (void *) 0},/p'\
-  -e 's/^I .* \(.*\)$/  {\"lib\1\", (void *) 0},/p'"
-else
-  # Disable hooks by default.
-  lt_cv_sys_global_symbol_to_import=
-  lt_cdecl_hook=
-  lt_c_name_hook=
-  lt_c_name_lib_hook=
-fi
-
 # Transform an extracted symbol line into a proper C declaration.
 # Some systems (esp. on ia64) link data and code symbols differently,
 # so use this general approach.
-lt_cv_sys_global_symbol_to_cdecl="sed -n"\
-$lt_cdecl_hook\
-" -e 's/^T .* \(.*\)$/extern int \1();/p'"\
-" -e 's/^$symcode$symcode* .* \(.*\)$/extern char \1;/p'"
+lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'"
 
 # Transform an extracted symbol line into symbol name and symbol address
-lt_cv_sys_global_symbol_to_c_name_address="sed -n"\
-$lt_c_name_hook\
-" -e 's/^: \(.*\) .*$/  {\"\1\", (void *) 0},/p'"\
-" -e 's/^$symcode$symcode* .* \(.*\)$/  {\"\1\", (void *) \&\1},/p'"
-
-# Transform an extracted symbol line into symbol name with lib prefix and
-# symbol address.
-lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n"\
-$lt_c_name_lib_hook\
-" -e 's/^: \(.*\) .*$/  {\"\1\", (void *) 0},/p'"\
-" -e 's/^$symcode$symcode* .* \(lib.*\)$/  {\"\1\", (void *) \&\1},/p'"\
-" -e 's/^$symcode$symcode* .* \(.*\)$/  {\"lib\1\", (void *) \&\1},/p'"
+lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([[^ ]]*\)[[ ]]*$/  {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/  {\"\2\", (void *) \&\2},/p'"
+lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n -e 's/^: \([[^ ]]*\)[[ ]]*$/  {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \(lib[[^ ]]*\)$/  {\"\2\", (void *) \&\2},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/  {\"lib\2\", (void *) \&\2},/p'"
 
 # Handle CRLF in mingw tool chain
 opt_cr=
@@ -4020,24 +3709,21 @@ for ac_symprfx in "" "_"; do
 
   # Write the raw and C identifiers.
   if test "$lt_cv_nm_interface" = "MS dumpbin"; then
-    # Fake it for dumpbin and say T for any non-static function,
-    # D for any global variable and I for any imported variable.
+    # Fake it for dumpbin and say T for any non-static function
+    # and D for any global variable.
     # Also find C++ and __fastcall symbols from MSVC++,
     # which start with @ or ?.
     lt_cv_sys_global_symbol_pipe="$AWK ['"\
 "     {last_section=section; section=\$ 3};"\
 "     /^COFF SYMBOL TABLE/{for(i in hide) delete hide[i]};"\
 "     /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\
-"     /^ *Symbol name *: /{split(\$ 0,sn,\":\"); si=substr(sn[2],2)};"\
-"     /^ *Type *: code/{print \"T\",si,substr(si,length(prfx))};"\
-"     /^ *Type *: data/{print \"I\",si,substr(si,length(prfx))};"\
 "     \$ 0!~/External *\|/{next};"\
 "     / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\
 "     {if(hide[section]) next};"\
-"     {f=\"D\"}; \$ 0~/\(\).*\|/{f=\"T\"};"\
-"     {split(\$ 0,a,/\||\r/); split(a[2],s)};"\
-"     s[1]~/^[@?]/{print f,s[1],s[1]; next};"\
-"     s[1]~prfx {split(s[1],t,\"@\"); print f,t[1],substr(t[1],length(prfx))}"\
+"     {f=0}; \$ 0~/\(\).*\|/{f=1}; {printf f ? \"T \" : \"D \"};"\
+"     {split(\$ 0, a, /\||\r/); split(a[2], s)};"\
+"     s[1]~/^[@?]/{print s[1], s[1]; next};"\
+"     s[1]~prfx {split(s[1],t,\"@\"); print t[1], substr(t[1],length(prfx))}"\
 "     ' prfx=^$ac_symprfx]"
   else
     lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[[	 ]]\($symcode$symcode*\)[[	 ]][[	 ]]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'"
@@ -4077,11 +3763,11 @@ _LT_EOF
 	if $GREP ' nm_test_func$' "$nlist" >/dev/null; then
 	  cat <<_LT_EOF > conftest.$ac_ext
 /* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests.  */
-#if defined _WIN32 || defined __CYGWIN__ || defined _WIN32_WCE
-/* DATA imports from DLLs on WIN32 can't be const, because runtime
+#if defined(_WIN32) || defined(__CYGWIN__) || defined(_WIN32_WCE)
+/* DATA imports from DLLs on WIN32 con't be const, because runtime
    relocations are performed -- see ld's documentation on pseudo-relocs.  */
 # define LT@&t at _DLSYM_CONST
-#elif defined __osf__
+#elif defined(__osf__)
 /* This system does not cope well with relocations in const data.  */
 # define LT@&t at _DLSYM_CONST
 #else
@@ -4107,7 +3793,7 @@ lt__PROGRAM__LTX_preloaded_symbols[[]] =
 {
   { "@PROGRAM@", (void *) 0 },
 _LT_EOF
-	  $SED "s/^$symcode$symcode* .* \(.*\)$/  {\"\1\", (void *) \&\1},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext
+	  $SED "s/^$symcode$symcode* \(.*\) \(.*\)$/  {\"\2\", (void *) \&\2},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext
 	  cat <<\_LT_EOF >> conftest.$ac_ext
   {0, (void *) 0}
 };
@@ -4127,9 +3813,9 @@ _LT_EOF
 	  mv conftest.$ac_objext conftstm.$ac_objext
 	  lt_globsym_save_LIBS=$LIBS
 	  lt_globsym_save_CFLAGS=$CFLAGS
-	  LIBS=conftstm.$ac_objext
+	  LIBS="conftstm.$ac_objext"
 	  CFLAGS="$CFLAGS$_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)"
-	  if AC_TRY_EVAL(ac_link) && test -s conftest$ac_exeext; then
+	  if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext}; then
 	    pipe_works=yes
 	  fi
 	  LIBS=$lt_globsym_save_LIBS
@@ -4150,7 +3836,7 @@ _LT_EOF
   rm -rf conftest* conftst*
 
   # Do not use the global_symbol_pipe unless it works.
-  if test yes = "$pipe_works"; then
+  if test "$pipe_works" = yes; then
     break
   else
     lt_cv_sys_global_symbol_pipe=
@@ -4177,16 +3863,12 @@ _LT_DECL([global_symbol_pipe], [lt_cv_sys_global_symbol_pipe], [1],
     [Take the output of nm and produce a listing of raw symbols and C names])
 _LT_DECL([global_symbol_to_cdecl], [lt_cv_sys_global_symbol_to_cdecl], [1],
     [Transform the output of nm in a proper C declaration])
-_LT_DECL([global_symbol_to_import], [lt_cv_sys_global_symbol_to_import], [1],
-    [Transform the output of nm into a list of symbols to manually relocate])
 _LT_DECL([global_symbol_to_c_name_address],
     [lt_cv_sys_global_symbol_to_c_name_address], [1],
     [Transform the output of nm in a C name address pair])
 _LT_DECL([global_symbol_to_c_name_address_lib_prefix],
     [lt_cv_sys_global_symbol_to_c_name_address_lib_prefix], [1],
     [Transform the output of nm in a C name address pair when lib prefix is needed])
-_LT_DECL([nm_interface], [lt_cv_nm_interface], [1],
-    [The name lister interface])
 _LT_DECL([], [nm_file_list_spec], [1],
     [Specify filename containing input files for $NM])
 ]) # _LT_CMD_GLOBAL_SYMBOLS
@@ -4202,18 +3884,17 @@ _LT_TAGVAR(lt_prog_compiler_static, $1)=
 
 m4_if([$1], [CXX], [
   # C++ specific cases for pic, static, wl, etc.
-  if test yes = "$GXX"; then
+  if test "$GXX" = yes; then
     _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
     _LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
 
     case $host_os in
     aix*)
       # All AIX code is PIC.
-      if test ia64 = "$host_cpu"; then
+      if test "$host_cpu" = ia64; then
 	# AIX 5 now supports IA64 processor
 	_LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
       fi
-      _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
       ;;
 
     amigaos*)
@@ -4224,8 +3905,8 @@ m4_if([$1], [CXX], [
         ;;
       m68k)
             # FIXME: we need at least 68020 code to build shared libraries, but
-            # adding the '-m68020' flag to GCC prevents building anything better,
-            # like '-m68040'.
+            # adding the `-m68020' flag to GCC prevents building anything better,
+            # like `-m68040'.
             _LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4'
         ;;
       esac
@@ -4241,11 +3922,6 @@ m4_if([$1], [CXX], [
       # (--disable-auto-import) libraries
       m4_if([$1], [GCJ], [],
 	[_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT'])
-      case $host_os in
-      os2*)
-	_LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-static'
-	;;
-      esac
       ;;
     darwin* | rhapsody*)
       # PIC is the default on this platform
@@ -4295,7 +3971,7 @@ m4_if([$1], [CXX], [
     case $host_os in
       aix[[4-9]]*)
 	# All AIX code is PIC.
-	if test ia64 = "$host_cpu"; then
+	if test "$host_cpu" = ia64; then
 	  # AIX 5 now supports IA64 processor
 	  _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
 	else
@@ -4336,14 +4012,14 @@ m4_if([$1], [CXX], [
 	case $cc_basename in
 	  CC*)
 	    _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
-	    _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-a ${wl}archive'
-	    if test ia64 != "$host_cpu"; then
+	    _LT_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive'
+	    if test "$host_cpu" != ia64; then
 	      _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z'
 	    fi
 	    ;;
 	  aCC*)
 	    _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
-	    _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-a ${wl}archive'
+	    _LT_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive'
 	    case $host_cpu in
 	    hppa*64*|ia64*)
 	      # +Z the default
@@ -4380,7 +4056,7 @@ m4_if([$1], [CXX], [
 	    _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
 	    ;;
 	  ecpc* )
-	    # old Intel C++ for x86_64, which still supported -KPIC.
+	    # old Intel C++ for x86_64 which still supported -KPIC.
 	    _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
 	    _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
 	    _LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
@@ -4525,18 +4201,17 @@ m4_if([$1], [CXX], [
   fi
 ],
 [
-  if test yes = "$GCC"; then
+  if test "$GCC" = yes; then
     _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
     _LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
 
     case $host_os in
       aix*)
       # All AIX code is PIC.
-      if test ia64 = "$host_cpu"; then
+      if test "$host_cpu" = ia64; then
 	# AIX 5 now supports IA64 processor
 	_LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
       fi
-      _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
       ;;
 
     amigaos*)
@@ -4547,8 +4222,8 @@ m4_if([$1], [CXX], [
         ;;
       m68k)
             # FIXME: we need at least 68020 code to build shared libraries, but
-            # adding the '-m68020' flag to GCC prevents building anything better,
-            # like '-m68040'.
+            # adding the `-m68020' flag to GCC prevents building anything better,
+            # like `-m68040'.
             _LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4'
         ;;
       esac
@@ -4565,11 +4240,6 @@ m4_if([$1], [CXX], [
       # (--disable-auto-import) libraries
       m4_if([$1], [GCJ], [],
 	[_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT'])
-      case $host_os in
-      os2*)
-	_LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-static'
-	;;
-      esac
       ;;
 
     darwin* | rhapsody*)
@@ -4640,7 +4310,7 @@ m4_if([$1], [CXX], [
     case $host_os in
     aix*)
       _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
-      if test ia64 = "$host_cpu"; then
+      if test "$host_cpu" = ia64; then
 	# AIX 5 now supports IA64 processor
 	_LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
       else
@@ -4648,30 +4318,11 @@ m4_if([$1], [CXX], [
       fi
       ;;
 
-    darwin* | rhapsody*)
-      # PIC is the default on this platform
-      # Common symbols not allowed in MH_DYLIB files
-      _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common'
-      case $cc_basename in
-      nagfor*)
-        # NAG Fortran compiler
-        _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,-Wl,,'
-        _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC'
-        _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
-        ;;
-      esac
-      ;;
-
     mingw* | cygwin* | pw32* | os2* | cegcc*)
       # This hack is so that the source file can tell whether it is being
       # built for inclusion in a dll (and should export symbols for example).
       m4_if([$1], [GCJ], [],
 	[_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT'])
-      case $host_os in
-      os2*)
-	_LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-static'
-	;;
-      esac
       ;;
 
     hpux9* | hpux10* | hpux11*)
@@ -4687,7 +4338,7 @@ m4_if([$1], [CXX], [
 	;;
       esac
       # Is there a better lt_prog_compiler_static that works with the bundled CC?
-      _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-a ${wl}archive'
+      _LT_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive'
       ;;
 
     irix5* | irix6* | nonstopux*)
@@ -4698,7 +4349,7 @@ m4_if([$1], [CXX], [
 
     linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*)
       case $cc_basename in
-      # old Intel for x86_64, which still supported -KPIC.
+      # old Intel for x86_64 which still supported -KPIC.
       ecc*)
 	_LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
 	_LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
@@ -4723,12 +4374,6 @@ m4_if([$1], [CXX], [
 	_LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC'
 	_LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
 	;;
-      tcc*)
-	# Fabrice Bellard et al's Tiny C Compiler
-	_LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
-	_LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
-	_LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
-	;;
       pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*)
         # Portland Group compilers (*not* the Pentium gcc compiler,
 	# which looks to be a dead project)
@@ -4826,7 +4471,7 @@ m4_if([$1], [CXX], [
       ;;
 
     sysv4*MP*)
-      if test -d /usr/nec; then
+      if test -d /usr/nec ;then
 	_LT_TAGVAR(lt_prog_compiler_pic, $1)='-Kconform_pic'
 	_LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
       fi
@@ -4855,7 +4500,7 @@ m4_if([$1], [CXX], [
   fi
 ])
 case $host_os in
-  # For platforms that do not support PIC, -DPIC is meaningless:
+  # For platforms which do not support PIC, -DPIC is meaningless:
   *djgpp*)
     _LT_TAGVAR(lt_prog_compiler_pic, $1)=
     ;;
@@ -4921,21 +4566,17 @@ m4_if([$1], [CXX], [
   case $host_os in
   aix[[4-9]]*)
     # If we're using GNU nm, then we don't want the "-C" option.
-    # -C means demangle to GNU nm, but means don't demangle to AIX nm.
-    # Without the "-l" option, or with the "-B" option, AIX nm treats
-    # weak defined symbols like other global defined symbols, whereas
-    # GNU nm marks them as "W".
-    # While the 'weak' keyword is ignored in the Export File, we need
-    # it in the Import File for the 'aix-soname' feature, so we have
-    # to replace the "-B" option with "-P" for AIX nm.
+    # -C means demangle to AIX nm, but means don't demangle with GNU nm
+    # Also, AIX nm treats weak defined symbols like other global defined
+    # symbols, whereas GNU nm marks them as "W".
     if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then
-      _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && ([substr](\$ 3,1,1) != ".")) { if (\$ 2 == "W") { print \$ 3 " weak" } else { print \$ 3 } } }'\'' | sort -u > $export_symbols'
+      _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols'
     else
-      _LT_TAGVAR(export_symbols_cmds, $1)='`func_echo_all $NM | $SED -e '\''s/B\([[^B]]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && ([substr](\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols'
+      _LT_TAGVAR(export_symbols_cmds, $1)='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols'
     fi
     ;;
   pw32*)
-    _LT_TAGVAR(export_symbols_cmds, $1)=$ltdll_cmds
+    _LT_TAGVAR(export_symbols_cmds, $1)="$ltdll_cmds"
     ;;
   cygwin* | mingw* | cegcc*)
     case $cc_basename in
@@ -4984,9 +4625,9 @@ m4_if([$1], [CXX], [
   # included in the symbol list
   _LT_TAGVAR(include_expsyms, $1)=
   # exclude_expsyms can be an extended regexp of symbols to exclude
-  # it will be wrapped by ' (' and ')$', so one must not match beginning or
-  # end of line.  Example: 'a|bc|.*d.*' will exclude the symbols 'a' and 'bc',
-  # as well as any symbol that contains 'd'.
+  # it will be wrapped by ` (' and `)$', so one must not match beginning or
+  # end of line.  Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc',
+  # as well as any symbol that contains `d'.
   _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*']
   # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out
   # platforms (ab)use it in PIC code, but their linkers get confused if
@@ -5002,7 +4643,7 @@ dnl Note also adjust exclude_expsyms for C++ above.
     # FIXME: the MSVC++ port hasn't been tested in a loooong time
     # When not using gcc, we currently assume that we are using
     # Microsoft Visual C++.
-    if test yes != "$GCC"; then
+    if test "$GCC" != yes; then
       with_gnu_ld=no
     fi
     ;;
@@ -5010,7 +4651,7 @@ dnl Note also adjust exclude_expsyms for C++ above.
     # we just hope/assume this is gcc and not c89 (= MSVC++)
     with_gnu_ld=yes
     ;;
-  openbsd* | bitrig*)
+  openbsd*)
     with_gnu_ld=no
     ;;
   linux* | k*bsd*-gnu | gnu*)
@@ -5023,7 +4664,7 @@ dnl Note also adjust exclude_expsyms for C++ above.
   # On some targets, GNU ld is compatible enough with the native linker
   # that we're better off using the native interface for both.
   lt_use_gnu_ld_interface=no
-  if test yes = "$with_gnu_ld"; then
+  if test "$with_gnu_ld" = yes; then
     case $host_os in
       aix*)
 	# The AIX port of GNU ld has always aspired to compatibility
@@ -5045,24 +4686,24 @@ dnl Note also adjust exclude_expsyms for C++ above.
     esac
   fi
 
-  if test yes = "$lt_use_gnu_ld_interface"; then
+  if test "$lt_use_gnu_ld_interface" = yes; then
     # If archive_cmds runs LD, not CC, wlarc should be empty
-    wlarc='$wl'
+    wlarc='${wl}'
 
     # Set some defaults for GNU ld with shared library support. These
     # are reset later if shared libraries are not supported. Putting them
     # here allows them to be overridden if necessary.
     runpath_var=LD_RUN_PATH
-    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir'
-    _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic'
+    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+    _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic'
     # ancient GNU ld didn't support --whole-archive et. al.
     if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then
-      _LT_TAGVAR(whole_archive_flag_spec, $1)=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive'
+      _LT_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive'
     else
       _LT_TAGVAR(whole_archive_flag_spec, $1)=
     fi
     supports_anon_versioning=no
-    case `$LD -v | $SED -e 's/([^)]\+)\s\+//' 2>&1` in
+    case `$LD -v 2>&1` in
       *GNU\ gold*) supports_anon_versioning=yes ;;
       *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.10.*) ;; # catch versions < 2.11
       *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ...
@@ -5075,7 +4716,7 @@ dnl Note also adjust exclude_expsyms for C++ above.
     case $host_os in
     aix[[3-9]]*)
       # On AIX/PPC, the GNU linker is very broken
-      if test ia64 != "$host_cpu"; then
+      if test "$host_cpu" != ia64; then
 	_LT_TAGVAR(ld_shlibs, $1)=no
 	cat <<_LT_EOF 1>&2
 
@@ -5094,7 +4735,7 @@ _LT_EOF
       case $host_cpu in
       powerpc)
             # see comment about AmigaOS4 .so support
-            _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+            _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
             _LT_TAGVAR(archive_expsym_cmds, $1)=''
         ;;
       m68k)
@@ -5110,7 +4751,7 @@ _LT_EOF
 	_LT_TAGVAR(allow_undefined_flag, $1)=unsupported
 	# Joseph Beckenbach <jrb3 at best.com> says some releases of gcc
 	# support --undefined.  This deserves some investigation.  FIXME
-	_LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+	_LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
       else
 	_LT_TAGVAR(ld_shlibs, $1)=no
       fi
@@ -5120,7 +4761,7 @@ _LT_EOF
       # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless,
       # as there is no search path for DLLs.
       _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
-      _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-all-symbols'
+      _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-all-symbols'
       _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
       _LT_TAGVAR(always_export_symbols, $1)=no
       _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
@@ -5128,89 +4769,61 @@ _LT_EOF
       _LT_TAGVAR(exclude_expsyms, $1)=['[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname']
 
       if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then
-        _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
-	# If the export-symbols file already is a .def file, use it as
-	# is; otherwise, prepend EXPORTS...
-	_LT_TAGVAR(archive_expsym_cmds, $1)='if _LT_DLL_DEF_P([$export_symbols]); then
-          cp $export_symbols $output_objdir/$soname.def;
-        else
-          echo EXPORTS > $output_objdir/$soname.def;
-          cat $export_symbols >> $output_objdir/$soname.def;
-        fi~
-        $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+        _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+	# If the export-symbols file already is a .def file (1st line
+	# is EXPORTS), use it as is; otherwise, prepend...
+	_LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then
+	  cp $export_symbols $output_objdir/$soname.def;
+	else
+	  echo EXPORTS > $output_objdir/$soname.def;
+	  cat $export_symbols >> $output_objdir/$soname.def;
+	fi~
+	$CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
       else
 	_LT_TAGVAR(ld_shlibs, $1)=no
       fi
       ;;
 
     haiku*)
-      _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+      _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
       _LT_TAGVAR(link_all_deplibs, $1)=yes
       ;;
 
-    os2*)
-      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
-      _LT_TAGVAR(hardcode_minus_L, $1)=yes
-      _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
-      shrext_cmds=.dll
-      _LT_TAGVAR(archive_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~
-	$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~
-	$ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~
-	$ECHO EXPORTS >> $output_objdir/$libname.def~
-	emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~
-	$CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~
-	emximp -o $lib $output_objdir/$libname.def'
-      _LT_TAGVAR(archive_expsym_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~
-	$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~
-	$ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~
-	$ECHO EXPORTS >> $output_objdir/$libname.def~
-	prefix_cmds="$SED"~
-	if test EXPORTS = "`$SED 1q $export_symbols`"; then
-	  prefix_cmds="$prefix_cmds -e 1d";
-	fi~
-	prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~
-	cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~
-	$CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~
-	emximp -o $lib $output_objdir/$libname.def'
-      _LT_TAGVAR(old_archive_From_new_cmds, $1)='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def'
-      _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
-      ;;
-
     interix[[3-9]]*)
       _LT_TAGVAR(hardcode_direct, $1)=no
       _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
-      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir'
-      _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E'
+      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
+      _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
       # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc.
       # Instead, shared libraries are loaded at an image base (0x10000000 by
       # default) and relocated if they conflict, which is a slow very memory
       # consuming and fragmenting process.  To avoid this, we pick a random,
       # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link
       # time.  Moving up from 0x10000000 also allows more sbrk(2) space.
-      _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
-      _LT_TAGVAR(archive_expsym_cmds, $1)='sed "s|^|_|" $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--retain-symbols-file,$output_objdir/$soname.expsym $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+      _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+      _LT_TAGVAR(archive_expsym_cmds, $1)='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
       ;;
 
     gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu)
       tmp_diet=no
-      if test linux-dietlibc = "$host_os"; then
+      if test "$host_os" = linux-dietlibc; then
 	case $cc_basename in
 	  diet\ *) tmp_diet=yes;;	# linux-dietlibc with static linking (!diet-dyn)
 	esac
       fi
       if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \
-	 && test no = "$tmp_diet"
+	 && test "$tmp_diet" = no
       then
 	tmp_addflag=' $pic_flag'
 	tmp_sharedflag='-shared'
 	case $cc_basename,$host_cpu in
         pgcc*)				# Portland Group C compiler
-	  _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive'
+	  _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
 	  tmp_addflag=' $pic_flag'
 	  ;;
 	pgf77* | pgf90* | pgf95* | pgfortran*)
 					# Portland Group f77 and f90 compilers
-	  _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive'
+	  _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
 	  tmp_addflag=' $pic_flag -Mnomain' ;;
 	ecc*,ia64* | icc*,ia64*)	# Intel C compiler on ia64
 	  tmp_addflag=' -i_dynamic' ;;
@@ -5221,47 +4834,42 @@ _LT_EOF
 	lf95*)				# Lahey Fortran 8.1
 	  _LT_TAGVAR(whole_archive_flag_spec, $1)=
 	  tmp_sharedflag='--shared' ;;
-        nagfor*)                        # NAGFOR 5.3
-          tmp_sharedflag='-Wl,-shared' ;;
 	xl[[cC]]* | bgxl[[cC]]* | mpixl[[cC]]*) # IBM XL C 8.0 on PPC (deal with xlf below)
 	  tmp_sharedflag='-qmkshrobj'
 	  tmp_addflag= ;;
 	nvcc*)	# Cuda Compiler Driver 2.2
-	  _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive'
+	  _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
 	  _LT_TAGVAR(compiler_needs_object, $1)=yes
 	  ;;
 	esac
 	case `$CC -V 2>&1 | sed 5q` in
 	*Sun\ C*)			# Sun C 5.9
-	  _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive'
+	  _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
 	  _LT_TAGVAR(compiler_needs_object, $1)=yes
 	  tmp_sharedflag='-G' ;;
 	*Sun\ F*)			# Sun Fortran 8.3
 	  tmp_sharedflag='-G' ;;
 	esac
-	_LT_TAGVAR(archive_cmds, $1)='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+	_LT_TAGVAR(archive_cmds, $1)='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
 
-        if test yes = "$supports_anon_versioning"; then
+        if test "x$supports_anon_versioning" = xyes; then
           _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~
-            cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
-            echo "local: *; };" >> $output_objdir/$libname.ver~
-            $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-version-script $wl$output_objdir/$libname.ver -o $lib'
+	    cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
+	    echo "local: *; };" >> $output_objdir/$libname.ver~
+	    $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib'
         fi
 
 	case $cc_basename in
-	tcc*)
-	  _LT_TAGVAR(export_dynamic_flag_spec, $1)='-rdynamic'
-	  ;;
 	xlf* | bgf* | bgxlf* | mpixlf*)
 	  # IBM XL Fortran 10.1 on PPC cannot create shared libs itself
 	  _LT_TAGVAR(whole_archive_flag_spec, $1)='--whole-archive$convenience --no-whole-archive'
-	  _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir'
+	  _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
 	  _LT_TAGVAR(archive_cmds, $1)='$LD -shared $libobjs $deplibs $linker_flags -soname $soname -o $lib'
-	  if test yes = "$supports_anon_versioning"; then
+	  if test "x$supports_anon_versioning" = xyes; then
 	    _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~
-              cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
-              echo "local: *; };" >> $output_objdir/$libname.ver~
-              $LD -shared $libobjs $deplibs $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib'
+	      cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
+	      echo "local: *; };" >> $output_objdir/$libname.ver~
+	      $LD -shared $libobjs $deplibs $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib'
 	  fi
 	  ;;
 	esac
@@ -5275,8 +4883,8 @@ _LT_EOF
 	_LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib'
 	wlarc=
       else
-	_LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
-	_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'
+	_LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+	_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
       fi
       ;;
 
@@ -5294,8 +4902,8 @@ _LT_EOF
 
 _LT_EOF
       elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
-	_LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
-	_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'
+	_LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+	_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
       else
 	_LT_TAGVAR(ld_shlibs, $1)=no
       fi
@@ -5307,7 +4915,7 @@ _LT_EOF
 	_LT_TAGVAR(ld_shlibs, $1)=no
 	cat <<_LT_EOF 1>&2
 
-*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 cannot
+*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 can not
 *** reliably create shared libraries on SCO systems.  Therefore, libtool
 *** is disabling shared libraries support.  We urge you to upgrade GNU
 *** binutils to release 2.16.91.0.3 or newer.  Another option is to modify
@@ -5322,9 +4930,9 @@ _LT_EOF
 	  # DT_RUNPATH tag from executables and libraries.  But doing so
 	  # requires that you compile everything twice, which is a pain.
 	  if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
-	    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir'
-	    _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
-	    _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'
+	    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+	    _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+	    _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
 	  else
 	    _LT_TAGVAR(ld_shlibs, $1)=no
 	  fi
@@ -5341,15 +4949,15 @@ _LT_EOF
 
     *)
       if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
-	_LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
-	_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'
+	_LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+	_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
       else
 	_LT_TAGVAR(ld_shlibs, $1)=no
       fi
       ;;
     esac
 
-    if test no = "$_LT_TAGVAR(ld_shlibs, $1)"; then
+    if test "$_LT_TAGVAR(ld_shlibs, $1)" = no; then
       runpath_var=
       _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=
       _LT_TAGVAR(export_dynamic_flag_spec, $1)=
@@ -5365,7 +4973,7 @@ _LT_EOF
       # Note: this linker hardcodes the directories in LIBPATH if there
       # are no directories specified by -L.
       _LT_TAGVAR(hardcode_minus_L, $1)=yes
-      if test yes = "$GCC" && test -z "$lt_prog_compiler_static"; then
+      if test "$GCC" = yes && test -z "$lt_prog_compiler_static"; then
 	# Neither direct hardcoding nor static linking is supported with a
 	# broken collect2.
 	_LT_TAGVAR(hardcode_direct, $1)=unsupported
@@ -5373,57 +4981,34 @@ _LT_EOF
       ;;
 
     aix[[4-9]]*)
-      if test ia64 = "$host_cpu"; then
+      if test "$host_cpu" = ia64; then
 	# On IA64, the linker does run time linking by default, so we don't
 	# have to do anything special.
 	aix_use_runtimelinking=no
 	exp_sym_flag='-Bexport'
-	no_entry_flag=
+	no_entry_flag=""
       else
 	# If we're using GNU nm, then we don't want the "-C" option.
-	# -C means demangle to GNU nm, but means don't demangle to AIX nm.
-	# Without the "-l" option, or with the "-B" option, AIX nm treats
-	# weak defined symbols like other global defined symbols, whereas
-	# GNU nm marks them as "W".
-	# While the 'weak' keyword is ignored in the Export File, we need
-	# it in the Import File for the 'aix-soname' feature, so we have
-	# to replace the "-B" option with "-P" for AIX nm.
+	# -C means demangle to AIX nm, but means don't demangle with GNU nm
+	# Also, AIX nm treats weak defined symbols like other global
+	# defined symbols, whereas GNU nm marks them as "W".
 	if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then
-	  _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && ([substr](\$ 3,1,1) != ".")) { if (\$ 2 == "W") { print \$ 3 " weak" } else { print \$ 3 } } }'\'' | sort -u > $export_symbols'
+	  _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols'
 	else
-	  _LT_TAGVAR(export_symbols_cmds, $1)='`func_echo_all $NM | $SED -e '\''s/B\([[^B]]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && ([substr](\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols'
+	  _LT_TAGVAR(export_symbols_cmds, $1)='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols'
 	fi
 	aix_use_runtimelinking=no
 
 	# Test if we are trying to use run time linking or normal
 	# AIX style linking. If -brtl is somewhere in LDFLAGS, we
-	# have runtime linking enabled, and use it for executables.
-	# For shared libraries, we enable/disable runtime linking
-	# depending on the kind of the shared library created -
-	# when "with_aix_soname,aix_use_runtimelinking" is:
-	# "aix,no"   lib.a(lib.so.V) shared, rtl:no,  for executables
-	# "aix,yes"  lib.so          shared, rtl:yes, for executables
-	#            lib.a           static archive
-	# "both,no"  lib.so.V(shr.o) shared, rtl:yes
-	#            lib.a(lib.so.V) shared, rtl:no,  for executables
-	# "both,yes" lib.so.V(shr.o) shared, rtl:yes, for executables
-	#            lib.a(lib.so.V) shared, rtl:no
-	# "svr4,*"   lib.so.V(shr.o) shared, rtl:yes, for executables
-	#            lib.a           static archive
+	# need to do runtime linking.
 	case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*)
 	  for ld_flag in $LDFLAGS; do
-	  if (test x-brtl = "x$ld_flag" || test x-Wl,-brtl = "x$ld_flag"); then
+	  if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then
 	    aix_use_runtimelinking=yes
 	    break
 	  fi
 	  done
-	  if test svr4,no = "$with_aix_soname,$aix_use_runtimelinking"; then
-	    # With aix-soname=svr4, we create the lib.so.V shared archives only,
-	    # so we don't have lib.a shared libs to link our executables.
-	    # We have to force runtime linking in this case.
-	    aix_use_runtimelinking=yes
-	    LDFLAGS="$LDFLAGS -Wl,-brtl"
-	  fi
 	  ;;
 	esac
 
@@ -5442,21 +5027,13 @@ _LT_EOF
       _LT_TAGVAR(hardcode_direct_absolute, $1)=yes
       _LT_TAGVAR(hardcode_libdir_separator, $1)=':'
       _LT_TAGVAR(link_all_deplibs, $1)=yes
-      _LT_TAGVAR(file_list_spec, $1)='$wl-f,'
-      case $with_aix_soname,$aix_use_runtimelinking in
-      aix,*) ;; # traditional, no import file
-      svr4,* | *,yes) # use import file
-	# The Import File defines what to hardcode.
-	_LT_TAGVAR(hardcode_direct, $1)=no
-	_LT_TAGVAR(hardcode_direct_absolute, $1)=no
-	;;
-      esac
+      _LT_TAGVAR(file_list_spec, $1)='${wl}-f,'
 
-      if test yes = "$GCC"; then
+      if test "$GCC" = yes; then
 	case $host_os in aix4.[[012]]|aix4.[[012]].*)
 	# We only want to do this on AIX 4.2 and lower, the check
 	# below for broken collect2 doesn't work under 4.3+
-	  collect2name=`$CC -print-prog-name=collect2`
+	  collect2name=`${CC} -print-prog-name=collect2`
 	  if test -f "$collect2name" &&
 	   strings "$collect2name" | $GREP resolve_lib_name >/dev/null
 	  then
@@ -5475,80 +5052,62 @@ _LT_EOF
 	  ;;
 	esac
 	shared_flag='-shared'
-	if test yes = "$aix_use_runtimelinking"; then
-	  shared_flag="$shared_flag "'$wl-G'
+	if test "$aix_use_runtimelinking" = yes; then
+	  shared_flag="$shared_flag "'${wl}-G'
 	fi
-	# Need to ensure runtime linking is disabled for the traditional
-	# shared library, or the linker may eventually find shared libraries
-	# /with/ Import File - we do not want to mix them.
-	shared_flag_aix='-shared'
-	shared_flag_svr4='-shared $wl-G'
+	_LT_TAGVAR(link_all_deplibs, $1)=no
       else
 	# not using gcc
-	if test ia64 = "$host_cpu"; then
+	if test "$host_cpu" = ia64; then
 	# VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release
 	# chokes on -Wl,-G. The following line is correct:
 	  shared_flag='-G'
 	else
-	  if test yes = "$aix_use_runtimelinking"; then
-	    shared_flag='$wl-G'
+	  if test "$aix_use_runtimelinking" = yes; then
+	    shared_flag='${wl}-G'
 	  else
-	    shared_flag='$wl-bM:SRE'
+	    shared_flag='${wl}-bM:SRE'
 	  fi
-	  shared_flag_aix='$wl-bM:SRE'
-	  shared_flag_svr4='$wl-G'
 	fi
       fi
 
-      _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-bexpall'
+      _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-bexpall'
       # It seems that -bexpall does not export symbols beginning with
       # underscore (_), so it is better to generate a list of symbols to export.
       _LT_TAGVAR(always_export_symbols, $1)=yes
-      if test aix,yes = "$with_aix_soname,$aix_use_runtimelinking"; then
+      if test "$aix_use_runtimelinking" = yes; then
 	# Warning - without using the other runtime loading flags (-brtl),
 	# -berok will link without error, but may produce a broken library.
 	_LT_TAGVAR(allow_undefined_flag, $1)='-berok'
         # Determine the default libpath from the value encoded in an
         # empty executable.
         _LT_SYS_MODULE_PATH_AIX([$1])
-        _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-blibpath:$libdir:'"$aix_libpath"
-        _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs $wl'$no_entry_flag' $compiler_flags `if test -n "$allow_undefined_flag"; then func_echo_all "$wl$allow_undefined_flag"; else :; fi` $wl'$exp_sym_flag:\$export_symbols' '$shared_flag
+        _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath"
+        _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then func_echo_all "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag"
       else
-	if test ia64 = "$host_cpu"; then
-	  _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R $libdir:/usr/lib:/lib'
+	if test "$host_cpu" = ia64; then
+	  _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $libdir:/usr/lib:/lib'
 	  _LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs"
-	  _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\$wl$no_entry_flag"' $compiler_flags $wl$allow_undefined_flag '"\$wl$exp_sym_flag:\$export_symbols"
+	  _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols"
 	else
 	 # Determine the default libpath from the value encoded in an
 	 # empty executable.
 	 _LT_SYS_MODULE_PATH_AIX([$1])
-	 _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-blibpath:$libdir:'"$aix_libpath"
+	 _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath"
 	  # Warning - without using the other run time loading flags,
 	  # -berok will link without error, but may produce a broken library.
-	  _LT_TAGVAR(no_undefined_flag, $1)=' $wl-bernotok'
-	  _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-berok'
-	  if test yes = "$with_gnu_ld"; then
+	  _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-bernotok'
+	  _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-berok'
+	  if test "$with_gnu_ld" = yes; then
 	    # We only use this code for GNU lds that support --whole-archive.
-	    _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive$convenience $wl--no-whole-archive'
+	    _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive$convenience ${wl}--no-whole-archive'
 	  else
 	    # Exported symbols can be pulled into shared objects from archives
 	    _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience'
 	  fi
 	  _LT_TAGVAR(archive_cmds_need_lc, $1)=yes
-	  _LT_TAGVAR(archive_expsym_cmds, $1)='$RM -r $output_objdir/$realname.d~$MKDIR $output_objdir/$realname.d'
-	  # -brtl affects multiple linker settings, -berok does not and is overridden later
-	  compiler_flags_filtered='`func_echo_all "$compiler_flags " | $SED -e "s%-brtl\\([[, ]]\\)%-berok\\1%g"`'
-	  if test svr4 != "$with_aix_soname"; then
-	    # This is similar to how AIX traditionally builds its shared libraries.
-	    _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$CC '$shared_flag_aix' -o $output_objdir/$realname.d/$soname $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$realname.d/$soname'
-	  fi
-	  if test aix != "$with_aix_soname"; then
-	    _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$CC '$shared_flag_svr4' -o $output_objdir/$realname.d/$shared_archive_member_spec.o $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$STRIP -e $output_objdir/$realname.d/$shared_archive_member_spec.o~( func_echo_all "#! $soname($shared_archive_member_spec.o)"; if test shr_64 = "$shared_archive_member_spec"; then func_echo_all "# 64"; else func_echo_all "# 3 [...]
-	  else
-	    # used by -dlpreopen to get the symbols
-	    _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$MV  $output_objdir/$realname.d/$soname $output_objdir'
-	  fi
-	  _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$RM -r $output_objdir/$realname.d'
+	  # This is similar to how AIX traditionally builds its shared libraries.
+	  _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname'
 	fi
       fi
       ;;
@@ -5557,7 +5116,7 @@ _LT_EOF
       case $host_cpu in
       powerpc)
             # see comment about AmigaOS4 .so support
-            _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+            _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
             _LT_TAGVAR(archive_expsym_cmds, $1)=''
         ;;
       m68k)
@@ -5587,17 +5146,16 @@ _LT_EOF
 	# Tell ltmain to make .lib files, not .a files.
 	libext=lib
 	# Tell ltmain to make .dll files, not .so files.
-	shrext_cmds=.dll
+	shrext_cmds=".dll"
 	# FIXME: Setting linknames here is a bad hack.
-	_LT_TAGVAR(archive_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~linknames='
-	_LT_TAGVAR(archive_expsym_cmds, $1)='if _LT_DLL_DEF_P([$export_symbols]); then
-            cp "$export_symbols" "$output_objdir/$soname.def";
-            echo "$tool_output_objdir$soname.def" > "$output_objdir/$soname.exp";
-          else
-            $SED -e '\''s/^/-link -EXPORT:/'\'' < $export_symbols > $output_objdir/$soname.exp;
-          fi~
-          $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~
-          linknames='
+	_LT_TAGVAR(archive_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-dll~linknames='
+	_LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then
+	    sed -n -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' -e '1\\\!p' < $export_symbols > $output_objdir/$soname.exp;
+	  else
+	    sed -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' < $export_symbols > $output_objdir/$soname.exp;
+	  fi~
+	  $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~
+	  linknames='
 	# The linker will not automatically build a static lib if we build a DLL.
 	# _LT_TAGVAR(old_archive_from_new_cmds, $1)='true'
 	_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
@@ -5606,18 +5164,18 @@ _LT_EOF
 	# Don't use ranlib
 	_LT_TAGVAR(old_postinstall_cmds, $1)='chmod 644 $oldlib'
 	_LT_TAGVAR(postlink_cmds, $1)='lt_outputfile="@OUTPUT@"~
-          lt_tool_outputfile="@TOOL_OUTPUT@"~
-          case $lt_outputfile in
-            *.exe|*.EXE) ;;
-            *)
-              lt_outputfile=$lt_outputfile.exe
-              lt_tool_outputfile=$lt_tool_outputfile.exe
-              ;;
-          esac~
-          if test : != "$MANIFEST_TOOL" && test -f "$lt_outputfile.manifest"; then
-            $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1;
-            $RM "$lt_outputfile.manifest";
-          fi'
+	  lt_tool_outputfile="@TOOL_OUTPUT@"~
+	  case $lt_outputfile in
+	    *.exe|*.EXE) ;;
+	    *)
+	      lt_outputfile="$lt_outputfile.exe"
+	      lt_tool_outputfile="$lt_tool_outputfile.exe"
+	      ;;
+	  esac~
+	  if test "$MANIFEST_TOOL" != ":" && test -f "$lt_outputfile.manifest"; then
+	    $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1;
+	    $RM "$lt_outputfile.manifest";
+	  fi'
 	;;
       *)
 	# Assume MSVC wrapper
@@ -5626,7 +5184,7 @@ _LT_EOF
 	# Tell ltmain to make .lib files, not .a files.
 	libext=lib
 	# Tell ltmain to make .dll files, not .so files.
-	shrext_cmds=.dll
+	shrext_cmds=".dll"
 	# FIXME: Setting linknames here is a bad hack.
 	_LT_TAGVAR(archive_cmds, $1)='$CC -o $lib $libobjs $compiler_flags `func_echo_all "$deplibs" | $SED '\''s/ -lc$//'\''` -link -dll~linknames='
 	# The linker will automatically build a .lib file if we build a DLL.
@@ -5676,33 +5234,33 @@ _LT_EOF
       ;;
 
     hpux9*)
-      if test yes = "$GCC"; then
-	_LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared $pic_flag $wl+b $wl$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib'
+      if test "$GCC" = yes; then
+	_LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared $pic_flag ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
       else
-	_LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib'
+	_LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
       fi
-      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir'
+      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir'
       _LT_TAGVAR(hardcode_libdir_separator, $1)=:
       _LT_TAGVAR(hardcode_direct, $1)=yes
 
       # hardcode_minus_L: Not really in the search PATH,
       # but as the default location of the library.
       _LT_TAGVAR(hardcode_minus_L, $1)=yes
-      _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E'
+      _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
       ;;
 
     hpux10*)
-      if test yes,no = "$GCC,$with_gnu_ld"; then
-	_LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+      if test "$GCC" = yes && test "$with_gnu_ld" = no; then
+	_LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
       else
 	_LT_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'
       fi
-      if test no = "$with_gnu_ld"; then
-	_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir'
+      if test "$with_gnu_ld" = no; then
+	_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir'
 	_LT_TAGVAR(hardcode_libdir_separator, $1)=:
 	_LT_TAGVAR(hardcode_direct, $1)=yes
 	_LT_TAGVAR(hardcode_direct_absolute, $1)=yes
-	_LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E'
+	_LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
 	# hardcode_minus_L: Not really in the search PATH,
 	# but as the default location of the library.
 	_LT_TAGVAR(hardcode_minus_L, $1)=yes
@@ -5710,25 +5268,25 @@ _LT_EOF
       ;;
 
     hpux11*)
-      if test yes,no = "$GCC,$with_gnu_ld"; then
+      if test "$GCC" = yes && test "$with_gnu_ld" = no; then
 	case $host_cpu in
 	hppa*64*)
-	  _LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl+h $wl$soname -o $lib $libobjs $deplibs $compiler_flags'
+	  _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
 	  ;;
 	ia64*)
-	  _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $wl+h $wl$soname $wl+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
+	  _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
 	  ;;
 	*)
-	  _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+	  _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
 	  ;;
 	esac
       else
 	case $host_cpu in
 	hppa*64*)
-	  _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname -o $lib $libobjs $deplibs $compiler_flags'
+	  _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
 	  ;;
 	ia64*)
-	  _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
+	  _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
 	  ;;
 	*)
 	m4_if($1, [], [
@@ -5736,14 +5294,14 @@ _LT_EOF
 	  # (HP92453-01 A.11.01.20 doesn't, HP92453-01 B.11.X.35175-35176.GP does)
 	  _LT_LINKER_OPTION([if $CC understands -b],
 	    _LT_TAGVAR(lt_cv_prog_compiler__b, $1), [-b],
-	    [_LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags'],
+	    [_LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'],
 	    [_LT_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'])],
-	  [_LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags'])
+	  [_LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'])
 	  ;;
 	esac
       fi
-      if test no = "$with_gnu_ld"; then
-	_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir'
+      if test "$with_gnu_ld" = no; then
+	_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir'
 	_LT_TAGVAR(hardcode_libdir_separator, $1)=:
 
 	case $host_cpu in
@@ -5754,7 +5312,7 @@ _LT_EOF
 	*)
 	  _LT_TAGVAR(hardcode_direct, $1)=yes
 	  _LT_TAGVAR(hardcode_direct_absolute, $1)=yes
-	  _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E'
+	  _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
 
 	  # hardcode_minus_L: Not really in the search PATH,
 	  # but as the default location of the library.
@@ -5765,16 +5323,16 @@ _LT_EOF
       ;;
 
     irix5* | irix6* | nonstopux*)
-      if test yes = "$GCC"; then
-	_LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib'
+      if test "$GCC" = yes; then
+	_LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
 	# Try to use the -exported_symbol ld option, if it does not
 	# work, assume that -exports_file does not work either and
 	# implicitly export all symbols.
 	# This should be the same for all languages, so no per-tag cache variable.
 	AC_CACHE_CHECK([whether the $host_os linker accepts -exported_symbol],
 	  [lt_cv_irix_exported_symbol],
-	  [save_LDFLAGS=$LDFLAGS
-	   LDFLAGS="$LDFLAGS -shared $wl-exported_symbol ${wl}foo $wl-update_registry $wl/dev/null"
+	  [save_LDFLAGS="$LDFLAGS"
+	   LDFLAGS="$LDFLAGS -shared ${wl}-exported_symbol ${wl}foo ${wl}-update_registry ${wl}/dev/null"
 	   AC_LINK_IFELSE(
 	     [AC_LANG_SOURCE(
 	        [AC_LANG_CASE([C], [[int foo (void) { return 0; }]],
@@ -5787,32 +5345,21 @@ _LT_EOF
       end]])])],
 	      [lt_cv_irix_exported_symbol=yes],
 	      [lt_cv_irix_exported_symbol=no])
-           LDFLAGS=$save_LDFLAGS])
-	if test yes = "$lt_cv_irix_exported_symbol"; then
-          _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations $wl-exports_file $wl$export_symbols -o $lib'
+           LDFLAGS="$save_LDFLAGS"])
+	if test "$lt_cv_irix_exported_symbol" = yes; then
+          _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations ${wl}-exports_file ${wl}$export_symbols -o $lib'
 	fi
-	_LT_TAGVAR(link_all_deplibs, $1)=no
       else
-	_LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib'
-	_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -exports_file $export_symbols -o $lib'
+	_LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib'
+	_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -exports_file $export_symbols -o $lib'
       fi
       _LT_TAGVAR(archive_cmds_need_lc, $1)='no'
-      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir'
+      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
       _LT_TAGVAR(hardcode_libdir_separator, $1)=:
       _LT_TAGVAR(inherit_rpath, $1)=yes
       _LT_TAGVAR(link_all_deplibs, $1)=yes
       ;;
 
-    linux*)
-      case $cc_basename in
-      tcc*)
-	# Fabrice Bellard et al's Tiny C Compiler
-	_LT_TAGVAR(ld_shlibs, $1)=yes
-	_LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
-	;;
-      esac
-      ;;
-
     netbsd* | netbsdelf*-gnu)
       if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
 	_LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'  # a.out
@@ -5827,7 +5374,7 @@ _LT_EOF
     newsos6)
       _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
       _LT_TAGVAR(hardcode_direct, $1)=yes
-      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir'
+      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
       _LT_TAGVAR(hardcode_libdir_separator, $1)=:
       _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
       ;;
@@ -5835,19 +5382,27 @@ _LT_EOF
     *nto* | *qnx*)
       ;;
 
-    openbsd* | bitrig*)
+    openbsd*)
       if test -f /usr/libexec/ld.so; then
 	_LT_TAGVAR(hardcode_direct, $1)=yes
 	_LT_TAGVAR(hardcode_shlibpath_var, $1)=no
 	_LT_TAGVAR(hardcode_direct_absolute, $1)=yes
-	if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then
+	if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
 	  _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
-	  _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags $wl-retain-symbols-file,$export_symbols'
-	  _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir'
-	  _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E'
+	  _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols'
+	  _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
+	  _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
 	else
-	  _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
-	  _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir'
+	  case $host_os in
+	   openbsd[[01]].* | openbsd2.[[0-7]] | openbsd2.[[0-7]].*)
+	     _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+	     _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+	     ;;
+	   *)
+	     _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+	     _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
+	     ;;
+	  esac
 	fi
       else
 	_LT_TAGVAR(ld_shlibs, $1)=no
@@ -5858,53 +5413,33 @@ _LT_EOF
       _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
       _LT_TAGVAR(hardcode_minus_L, $1)=yes
       _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
-      shrext_cmds=.dll
-      _LT_TAGVAR(archive_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~
-	$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~
-	$ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~
-	$ECHO EXPORTS >> $output_objdir/$libname.def~
-	emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~
-	$CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~
-	emximp -o $lib $output_objdir/$libname.def'
-      _LT_TAGVAR(archive_expsym_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~
-	$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~
-	$ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~
-	$ECHO EXPORTS >> $output_objdir/$libname.def~
-	prefix_cmds="$SED"~
-	if test EXPORTS = "`$SED 1q $export_symbols`"; then
-	  prefix_cmds="$prefix_cmds -e 1d";
-	fi~
-	prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~
-	cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~
-	$CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~
-	emximp -o $lib $output_objdir/$libname.def'
-      _LT_TAGVAR(old_archive_From_new_cmds, $1)='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def'
-      _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
+      _LT_TAGVAR(archive_cmds, $1)='$ECHO "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~echo DATA >> $output_objdir/$libname.def~echo " SINGLE NONSHARED" >> $output_objdir/$libname.def~echo EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def'
+      _LT_TAGVAR(old_archive_from_new_cmds, $1)='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def'
       ;;
 
     osf3*)
-      if test yes = "$GCC"; then
-	_LT_TAGVAR(allow_undefined_flag, $1)=' $wl-expect_unresolved $wl\*'
-	_LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib'
+      if test "$GCC" = yes; then
+	_LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*'
+	_LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
       else
 	_LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*'
-	_LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib'
+	_LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib'
       fi
       _LT_TAGVAR(archive_cmds_need_lc, $1)='no'
-      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir'
+      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
       _LT_TAGVAR(hardcode_libdir_separator, $1)=:
       ;;
 
     osf4* | osf5*)	# as osf3* with the addition of -msym flag
-      if test yes = "$GCC"; then
-	_LT_TAGVAR(allow_undefined_flag, $1)=' $wl-expect_unresolved $wl\*'
-	_LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $pic_flag $libobjs $deplibs $compiler_flags $wl-msym $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib'
-	_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir'
+      if test "$GCC" = yes; then
+	_LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*'
+	_LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $pic_flag $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+	_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
       else
 	_LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*'
-	_LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib'
+	_LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib'
 	_LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~
-          $CC -shared$allow_undefined_flag $wl-input $wl$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib~$RM $lib.exp'
+	$CC -shared${allow_undefined_flag} ${wl}-input ${wl}$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib~$RM $lib.exp'
 
 	# Both c and cxx compiler support -rpath directly
 	_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir'
@@ -5915,24 +5450,24 @@ _LT_EOF
 
     solaris*)
       _LT_TAGVAR(no_undefined_flag, $1)=' -z defs'
-      if test yes = "$GCC"; then
-	wlarc='$wl'
-	_LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $wl-z ${wl}text $wl-h $wl$soname -o $lib $libobjs $deplibs $compiler_flags'
+      if test "$GCC" = yes; then
+	wlarc='${wl}'
+	_LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
 	_LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
-          $CC -shared $pic_flag $wl-z ${wl}text $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp'
+	  $CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp'
       else
 	case `$CC -V 2>&1` in
 	*"Compilers 5.0"*)
 	  wlarc=''
-	  _LT_TAGVAR(archive_cmds, $1)='$LD -G$allow_undefined_flag -h $soname -o $lib $libobjs $deplibs $linker_flags'
+	  _LT_TAGVAR(archive_cmds, $1)='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags'
 	  _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
-            $LD -G$allow_undefined_flag -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp'
+	  $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp'
 	  ;;
 	*)
-	  wlarc='$wl'
-	  _LT_TAGVAR(archive_cmds, $1)='$CC -G$allow_undefined_flag -h $soname -o $lib $libobjs $deplibs $compiler_flags'
+	  wlarc='${wl}'
+	  _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $compiler_flags'
 	  _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
-            $CC -G$allow_undefined_flag -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp'
+	  $CC -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp'
 	  ;;
 	esac
       fi
@@ -5942,11 +5477,11 @@ _LT_EOF
       solaris2.[[0-5]] | solaris2.[[0-5]].*) ;;
       *)
 	# The compiler driver will combine and reorder linker options,
-	# but understands '-z linker_flag'.  GCC discards it without '$wl',
+	# but understands `-z linker_flag'.  GCC discards it without `$wl',
 	# but is careful enough not to reorder.
 	# Supported since Solaris 2.6 (maybe 2.5.1?)
-	if test yes = "$GCC"; then
-	  _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl-z ${wl}allextract$convenience $wl-z ${wl}defaultextract'
+	if test "$GCC" = yes; then
+	  _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract'
 	else
 	  _LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract'
 	fi
@@ -5956,10 +5491,10 @@ _LT_EOF
       ;;
 
     sunos4*)
-      if test sequent = "$host_vendor"; then
+      if test "x$host_vendor" = xsequent; then
 	# Use $CC to link under sequent, because it throws in some extra .o
 	# files that make .init and .fini sections work.
-	_LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h $soname -o $lib $libobjs $deplibs $compiler_flags'
+	_LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags'
       else
 	_LT_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags'
       fi
@@ -6008,43 +5543,43 @@ _LT_EOF
       ;;
 
     sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*)
-      _LT_TAGVAR(no_undefined_flag, $1)='$wl-z,text'
+      _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text'
       _LT_TAGVAR(archive_cmds_need_lc, $1)=no
       _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
       runpath_var='LD_RUN_PATH'
 
-      if test yes = "$GCC"; then
-	_LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
-	_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+      if test "$GCC" = yes; then
+	_LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
       else
-	_LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
-	_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	_LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
       fi
       ;;
 
     sysv5* | sco3.2v5* | sco5v6*)
-      # Note: We CANNOT use -z defs as we might desire, because we do not
+      # Note: We can NOT use -z defs as we might desire, because we do not
       # link with -lc, and that would cause any symbols used from libc to
       # always be unresolved, which means just about no library would
       # ever link correctly.  If we're not using GNU ld we use -z text
       # though, which does catch some bad symbols but isn't as heavy-handed
       # as -z defs.
-      _LT_TAGVAR(no_undefined_flag, $1)='$wl-z,text'
-      _LT_TAGVAR(allow_undefined_flag, $1)='$wl-z,nodefs'
+      _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text'
+      _LT_TAGVAR(allow_undefined_flag, $1)='${wl}-z,nodefs'
       _LT_TAGVAR(archive_cmds_need_lc, $1)=no
       _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
-      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R,$libdir'
+      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R,$libdir'
       _LT_TAGVAR(hardcode_libdir_separator, $1)=':'
       _LT_TAGVAR(link_all_deplibs, $1)=yes
-      _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-Bexport'
+      _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Bexport'
       runpath_var='LD_RUN_PATH'
 
-      if test yes = "$GCC"; then
-	_LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
-	_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+      if test "$GCC" = yes; then
+	_LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
       else
-	_LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
-	_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	_LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
       fi
       ;;
 
@@ -6059,17 +5594,17 @@ _LT_EOF
       ;;
     esac
 
-    if test sni = "$host_vendor"; then
+    if test x$host_vendor = xsni; then
       case $host in
       sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*)
-	_LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-Blargedynsym'
+	_LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Blargedynsym'
 	;;
       esac
     fi
   fi
 ])
 AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)])
-test no = "$_LT_TAGVAR(ld_shlibs, $1)" && can_build_shared=no
+test "$_LT_TAGVAR(ld_shlibs, $1)" = no && can_build_shared=no
 
 _LT_TAGVAR(with_gnu_ld, $1)=$with_gnu_ld
 
@@ -6086,7 +5621,7 @@ x|xyes)
   # Assume -lc should be added
   _LT_TAGVAR(archive_cmds_need_lc, $1)=yes
 
-  if test yes,yes = "$GCC,$enable_shared"; then
+  if test "$enable_shared" = yes && test "$GCC" = yes; then
     case $_LT_TAGVAR(archive_cmds, $1) in
     *'~'*)
       # FIXME: we may have to deal with multi-command sequences.
@@ -6166,12 +5701,12 @@ _LT_TAGDECL([], [hardcode_libdir_flag_spec], [1],
 _LT_TAGDECL([], [hardcode_libdir_separator], [1],
     [Whether we need a single "-rpath" flag with a separated argument])
 _LT_TAGDECL([], [hardcode_direct], [0],
-    [Set to "yes" if using DIR/libNAME$shared_ext during linking hardcodes
+    [Set to "yes" if using DIR/libNAME${shared_ext} during linking hardcodes
     DIR into the resulting binary])
 _LT_TAGDECL([], [hardcode_direct_absolute], [0],
-    [Set to "yes" if using DIR/libNAME$shared_ext during linking hardcodes
+    [Set to "yes" if using DIR/libNAME${shared_ext} during linking hardcodes
     DIR into the resulting binary and the resulting library dependency is
-    "absolute", i.e impossible to change by setting $shlibpath_var if the
+    "absolute", i.e impossible to change by setting ${shlibpath_var} if the
     library is relocated])
 _LT_TAGDECL([], [hardcode_minus_L], [0],
     [Set to "yes" if using the -LDIR flag during linking hardcodes DIR
@@ -6212,10 +5747,10 @@ dnl    [Compiler flag to generate thread safe objects])
 # ------------------------
 # Ensure that the configuration variables for a C compiler are suitably
 # defined.  These variables are subsequently used by _LT_CONFIG to write
-# the compiler configuration to 'libtool'.
+# the compiler configuration to `libtool'.
 m4_defun([_LT_LANG_C_CONFIG],
 [m4_require([_LT_DECL_EGREP])dnl
-lt_save_CC=$CC
+lt_save_CC="$CC"
 AC_LANG_PUSH(C)
 
 # Source file extension for C test sources.
@@ -6255,18 +5790,18 @@ if test -n "$compiler"; then
   LT_SYS_DLOPEN_SELF
   _LT_CMD_STRIPLIB
 
-  # Report what library types will actually be built
+  # Report which library types will actually be built
   AC_MSG_CHECKING([if libtool supports shared libraries])
   AC_MSG_RESULT([$can_build_shared])
 
   AC_MSG_CHECKING([whether to build shared libraries])
-  test no = "$can_build_shared" && enable_shared=no
+  test "$can_build_shared" = "no" && enable_shared=no
 
   # On AIX, shared libraries and static libraries use the same namespace, and
   # are all built from PIC.
   case $host_os in
   aix3*)
-    test yes = "$enable_shared" && enable_static=no
+    test "$enable_shared" = yes && enable_static=no
     if test -n "$RANLIB"; then
       archive_cmds="$archive_cmds~\$RANLIB \$lib"
       postinstall_cmds='$RANLIB $lib'
@@ -6274,12 +5809,8 @@ if test -n "$compiler"; then
     ;;
 
   aix[[4-9]]*)
-    if test ia64 != "$host_cpu"; then
-      case $enable_shared,$with_aix_soname,$aix_use_runtimelinking in
-      yes,aix,yes) ;;			# shared object as lib.so file only
-      yes,svr4,*) ;;			# shared object as lib.so archive member only
-      yes,*) enable_static=no ;;	# shared object in lib.a archive as well
-      esac
+    if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then
+      test "$enable_shared" = yes && enable_static=no
     fi
     ;;
   esac
@@ -6287,13 +5818,13 @@ if test -n "$compiler"; then
 
   AC_MSG_CHECKING([whether to build static libraries])
   # Make sure either enable_shared or enable_static is yes.
-  test yes = "$enable_shared" || enable_static=yes
+  test "$enable_shared" = yes || enable_static=yes
   AC_MSG_RESULT([$enable_static])
 
   _LT_CONFIG($1)
 fi
 AC_LANG_POP
-CC=$lt_save_CC
+CC="$lt_save_CC"
 ])# _LT_LANG_C_CONFIG
 
 
@@ -6301,14 +5832,14 @@ CC=$lt_save_CC
 # --------------------------
 # Ensure that the configuration variables for a C++ compiler are suitably
 # defined.  These variables are subsequently used by _LT_CONFIG to write
-# the compiler configuration to 'libtool'.
+# the compiler configuration to `libtool'.
 m4_defun([_LT_LANG_CXX_CONFIG],
 [m4_require([_LT_FILEUTILS_DEFAULTS])dnl
 m4_require([_LT_DECL_EGREP])dnl
 m4_require([_LT_PATH_MANIFEST_TOOL])dnl
-if test -n "$CXX" && ( test no != "$CXX" &&
-    ( (test g++ = "$CXX" && `g++ -v >/dev/null 2>&1` ) ||
-    (test g++ != "$CXX"))); then
+if test -n "$CXX" && ( test "X$CXX" != "Xno" &&
+    ( (test "X$CXX" = "Xg++" && `g++ -v >/dev/null 2>&1` ) ||
+    (test "X$CXX" != "Xg++"))) ; then
   AC_PROG_CXXCPP
 else
   _lt_caught_CXX_error=yes
@@ -6350,7 +5881,7 @@ _LT_TAGVAR(objext, $1)=$objext
 # the CXX compiler isn't working.  Some variables (like enable_shared)
 # are currently assumed to apply to all compilers on this platform,
 # and will be corrupted by setting them based on a non-working compiler.
-if test yes != "$_lt_caught_CXX_error"; then
+if test "$_lt_caught_CXX_error" != yes; then
   # Code to be used in simple compile tests
   lt_simple_compile_test_code="int some_variable = 0;"
 
@@ -6392,35 +5923,35 @@ if test yes != "$_lt_caught_CXX_error"; then
   if test -n "$compiler"; then
     # We don't want -fno-exception when compiling C++ code, so set the
     # no_builtin_flag separately
-    if test yes = "$GXX"; then
+    if test "$GXX" = yes; then
       _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin'
     else
       _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=
     fi
 
-    if test yes = "$GXX"; then
+    if test "$GXX" = yes; then
       # Set up default GNU C++ configuration
 
       LT_PATH_LD
 
       # Check if GNU C++ uses GNU ld as the underlying linker, since the
       # archiving commands below assume that GNU ld is being used.
-      if test yes = "$with_gnu_ld"; then
-        _LT_TAGVAR(archive_cmds, $1)='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib'
-        _LT_TAGVAR(archive_expsym_cmds, $1)='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'
+      if test "$with_gnu_ld" = yes; then
+        _LT_TAGVAR(archive_cmds, $1)='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib'
+        _LT_TAGVAR(archive_expsym_cmds, $1)='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
 
-        _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir'
-        _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic'
+        _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+        _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic'
 
         # If archive_cmds runs LD, not CC, wlarc should be empty
         # XXX I think wlarc can be eliminated in ltcf-cxx, but I need to
         #     investigate it a little bit more. (MM)
-        wlarc='$wl'
+        wlarc='${wl}'
 
         # ancient GNU ld didn't support --whole-archive et. al.
         if eval "`$CC -print-prog-name=ld` --help 2>&1" |
 	  $GREP 'no-whole-archive' > /dev/null; then
-          _LT_TAGVAR(whole_archive_flag_spec, $1)=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive'
+          _LT_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive'
         else
           _LT_TAGVAR(whole_archive_flag_spec, $1)=
         fi
@@ -6456,30 +5987,18 @@ if test yes != "$_lt_caught_CXX_error"; then
         _LT_TAGVAR(ld_shlibs, $1)=no
         ;;
       aix[[4-9]]*)
-        if test ia64 = "$host_cpu"; then
+        if test "$host_cpu" = ia64; then
           # On IA64, the linker does run time linking by default, so we don't
           # have to do anything special.
           aix_use_runtimelinking=no
           exp_sym_flag='-Bexport'
-          no_entry_flag=
+          no_entry_flag=""
         else
           aix_use_runtimelinking=no
 
           # Test if we are trying to use run time linking or normal
           # AIX style linking. If -brtl is somewhere in LDFLAGS, we
-          # have runtime linking enabled, and use it for executables.
-          # For shared libraries, we enable/disable runtime linking
-          # depending on the kind of the shared library created -
-          # when "with_aix_soname,aix_use_runtimelinking" is:
-          # "aix,no"   lib.a(lib.so.V) shared, rtl:no,  for executables
-          # "aix,yes"  lib.so          shared, rtl:yes, for executables
-          #            lib.a           static archive
-          # "both,no"  lib.so.V(shr.o) shared, rtl:yes
-          #            lib.a(lib.so.V) shared, rtl:no,  for executables
-          # "both,yes" lib.so.V(shr.o) shared, rtl:yes, for executables
-          #            lib.a(lib.so.V) shared, rtl:no
-          # "svr4,*"   lib.so.V(shr.o) shared, rtl:yes, for executables
-          #            lib.a           static archive
+          # need to do runtime linking.
           case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*)
 	    for ld_flag in $LDFLAGS; do
 	      case $ld_flag in
@@ -6489,13 +6008,6 @@ if test yes != "$_lt_caught_CXX_error"; then
 	        ;;
 	      esac
 	    done
-	    if test svr4,no = "$with_aix_soname,$aix_use_runtimelinking"; then
-	      # With aix-soname=svr4, we create the lib.so.V shared archives only,
-	      # so we don't have lib.a shared libs to link our executables.
-	      # We have to force runtime linking in this case.
-	      aix_use_runtimelinking=yes
-	      LDFLAGS="$LDFLAGS -Wl,-brtl"
-	    fi
 	    ;;
           esac
 
@@ -6514,21 +6026,13 @@ if test yes != "$_lt_caught_CXX_error"; then
         _LT_TAGVAR(hardcode_direct_absolute, $1)=yes
         _LT_TAGVAR(hardcode_libdir_separator, $1)=':'
         _LT_TAGVAR(link_all_deplibs, $1)=yes
-        _LT_TAGVAR(file_list_spec, $1)='$wl-f,'
-        case $with_aix_soname,$aix_use_runtimelinking in
-        aix,*) ;;	# no import file
-        svr4,* | *,yes) # use import file
-          # The Import File defines what to hardcode.
-          _LT_TAGVAR(hardcode_direct, $1)=no
-          _LT_TAGVAR(hardcode_direct_absolute, $1)=no
-          ;;
-        esac
+        _LT_TAGVAR(file_list_spec, $1)='${wl}-f,'
 
-        if test yes = "$GXX"; then
+        if test "$GXX" = yes; then
           case $host_os in aix4.[[012]]|aix4.[[012]].*)
           # We only want to do this on AIX 4.2 and lower, the check
           # below for broken collect2 doesn't work under 4.3+
-	  collect2name=`$CC -print-prog-name=collect2`
+	  collect2name=`${CC} -print-prog-name=collect2`
 	  if test -f "$collect2name" &&
 	     strings "$collect2name" | $GREP resolve_lib_name >/dev/null
 	  then
@@ -6546,84 +6050,64 @@ if test yes != "$_lt_caught_CXX_error"; then
 	  fi
           esac
           shared_flag='-shared'
-	  if test yes = "$aix_use_runtimelinking"; then
-	    shared_flag=$shared_flag' $wl-G'
+	  if test "$aix_use_runtimelinking" = yes; then
+	    shared_flag="$shared_flag "'${wl}-G'
 	  fi
-	  # Need to ensure runtime linking is disabled for the traditional
-	  # shared library, or the linker may eventually find shared libraries
-	  # /with/ Import File - we do not want to mix them.
-	  shared_flag_aix='-shared'
-	  shared_flag_svr4='-shared $wl-G'
         else
           # not using gcc
-          if test ia64 = "$host_cpu"; then
+          if test "$host_cpu" = ia64; then
 	  # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release
 	  # chokes on -Wl,-G. The following line is correct:
 	  shared_flag='-G'
           else
-	    if test yes = "$aix_use_runtimelinking"; then
-	      shared_flag='$wl-G'
+	    if test "$aix_use_runtimelinking" = yes; then
+	      shared_flag='${wl}-G'
 	    else
-	      shared_flag='$wl-bM:SRE'
+	      shared_flag='${wl}-bM:SRE'
 	    fi
-	    shared_flag_aix='$wl-bM:SRE'
-	    shared_flag_svr4='$wl-G'
           fi
         fi
 
-        _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-bexpall'
+        _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-bexpall'
         # It seems that -bexpall does not export symbols beginning with
         # underscore (_), so it is better to generate a list of symbols to
 	# export.
         _LT_TAGVAR(always_export_symbols, $1)=yes
-	if test aix,yes = "$with_aix_soname,$aix_use_runtimelinking"; then
+        if test "$aix_use_runtimelinking" = yes; then
           # Warning - without using the other runtime loading flags (-brtl),
           # -berok will link without error, but may produce a broken library.
-          # The "-G" linker flag allows undefined symbols.
-          _LT_TAGVAR(no_undefined_flag, $1)='-bernotok'
+          _LT_TAGVAR(allow_undefined_flag, $1)='-berok'
           # Determine the default libpath from the value encoded in an empty
           # executable.
           _LT_SYS_MODULE_PATH_AIX([$1])
-          _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-blibpath:$libdir:'"$aix_libpath"
+          _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath"
 
-          _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs $wl'$no_entry_flag' $compiler_flags `if test -n "$allow_undefined_flag"; then func_echo_all "$wl$allow_undefined_flag"; else :; fi` $wl'$exp_sym_flag:\$export_symbols' '$shared_flag
+          _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then func_echo_all "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag"
         else
-          if test ia64 = "$host_cpu"; then
-	    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R $libdir:/usr/lib:/lib'
+          if test "$host_cpu" = ia64; then
+	    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $libdir:/usr/lib:/lib'
 	    _LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs"
-	    _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\$wl$no_entry_flag"' $compiler_flags $wl$allow_undefined_flag '"\$wl$exp_sym_flag:\$export_symbols"
+	    _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols"
           else
 	    # Determine the default libpath from the value encoded in an
 	    # empty executable.
 	    _LT_SYS_MODULE_PATH_AIX([$1])
-	    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-blibpath:$libdir:'"$aix_libpath"
+	    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath"
 	    # Warning - without using the other run time loading flags,
 	    # -berok will link without error, but may produce a broken library.
-	    _LT_TAGVAR(no_undefined_flag, $1)=' $wl-bernotok'
-	    _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-berok'
-	    if test yes = "$with_gnu_ld"; then
+	    _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-bernotok'
+	    _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-berok'
+	    if test "$with_gnu_ld" = yes; then
 	      # We only use this code for GNU lds that support --whole-archive.
-	      _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive$convenience $wl--no-whole-archive'
+	      _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive$convenience ${wl}--no-whole-archive'
 	    else
 	      # Exported symbols can be pulled into shared objects from archives
 	      _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience'
 	    fi
 	    _LT_TAGVAR(archive_cmds_need_lc, $1)=yes
-	    _LT_TAGVAR(archive_expsym_cmds, $1)='$RM -r $output_objdir/$realname.d~$MKDIR $output_objdir/$realname.d'
-	    # -brtl affects multiple linker settings, -berok does not and is overridden later
-	    compiler_flags_filtered='`func_echo_all "$compiler_flags " | $SED -e "s%-brtl\\([[, ]]\\)%-berok\\1%g"`'
-	    if test svr4 != "$with_aix_soname"; then
-	      # This is similar to how AIX traditionally builds its shared
-	      # libraries. Need -bnortl late, we may have -brtl in LDFLAGS.
-	      _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$CC '$shared_flag_aix' -o $output_objdir/$realname.d/$soname $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$realname.d/$soname'
-	    fi
-	    if test aix != "$with_aix_soname"; then
-	      _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$CC '$shared_flag_svr4' -o $output_objdir/$realname.d/$shared_archive_member_spec.o $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$STRIP -e $output_objdir/$realname.d/$shared_archive_member_spec.o~( func_echo_all "#! $soname($shared_archive_member_spec.o)"; if test shr_64 = "$shared_archive_member_spec"; then func_echo_all "# 64"; else func_echo_all "# [...]
-	    else
-	      # used by -dlpreopen to get the symbols
-	      _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$MV  $output_objdir/$realname.d/$soname $output_objdir'
-	    fi
-	    _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$RM -r $output_objdir/$realname.d'
+	    # This is similar to how AIX traditionally builds its shared
+	    # libraries.
+	    _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname'
           fi
         fi
         ;;
@@ -6633,7 +6117,7 @@ if test yes != "$_lt_caught_CXX_error"; then
 	  _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
 	  # Joseph Beckenbach <jrb3 at best.com> says some releases of gcc
 	  # support --undefined.  This deserves some investigation.  FIXME
-	  _LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+	  _LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
 	else
 	  _LT_TAGVAR(ld_shlibs, $1)=no
 	fi
@@ -6661,58 +6145,57 @@ if test yes != "$_lt_caught_CXX_error"; then
 	  # Tell ltmain to make .lib files, not .a files.
 	  libext=lib
 	  # Tell ltmain to make .dll files, not .so files.
-	  shrext_cmds=.dll
+	  shrext_cmds=".dll"
 	  # FIXME: Setting linknames here is a bad hack.
-	  _LT_TAGVAR(archive_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~linknames='
-	  _LT_TAGVAR(archive_expsym_cmds, $1)='if _LT_DLL_DEF_P([$export_symbols]); then
-              cp "$export_symbols" "$output_objdir/$soname.def";
-              echo "$tool_output_objdir$soname.def" > "$output_objdir/$soname.exp";
-            else
-              $SED -e '\''s/^/-link -EXPORT:/'\'' < $export_symbols > $output_objdir/$soname.exp;
-            fi~
-            $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~
-            linknames='
+	  _LT_TAGVAR(archive_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-dll~linknames='
+	  _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then
+	      $SED -n -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' -e '1\\\!p' < $export_symbols > $output_objdir/$soname.exp;
+	    else
+	      $SED -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' < $export_symbols > $output_objdir/$soname.exp;
+	    fi~
+	    $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~
+	    linknames='
 	  # The linker will not automatically build a static lib if we build a DLL.
 	  # _LT_TAGVAR(old_archive_from_new_cmds, $1)='true'
 	  _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
 	  # Don't use ranlib
 	  _LT_TAGVAR(old_postinstall_cmds, $1)='chmod 644 $oldlib'
 	  _LT_TAGVAR(postlink_cmds, $1)='lt_outputfile="@OUTPUT@"~
-            lt_tool_outputfile="@TOOL_OUTPUT@"~
-            case $lt_outputfile in
-              *.exe|*.EXE) ;;
-              *)
-                lt_outputfile=$lt_outputfile.exe
-                lt_tool_outputfile=$lt_tool_outputfile.exe
-                ;;
-            esac~
-            func_to_tool_file "$lt_outputfile"~
-            if test : != "$MANIFEST_TOOL" && test -f "$lt_outputfile.manifest"; then
-              $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1;
-              $RM "$lt_outputfile.manifest";
-            fi'
+	    lt_tool_outputfile="@TOOL_OUTPUT@"~
+	    case $lt_outputfile in
+	      *.exe|*.EXE) ;;
+	      *)
+		lt_outputfile="$lt_outputfile.exe"
+		lt_tool_outputfile="$lt_tool_outputfile.exe"
+		;;
+	    esac~
+	    func_to_tool_file "$lt_outputfile"~
+	    if test "$MANIFEST_TOOL" != ":" && test -f "$lt_outputfile.manifest"; then
+	      $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1;
+	      $RM "$lt_outputfile.manifest";
+	    fi'
 	  ;;
 	*)
 	  # g++
 	  # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless,
 	  # as there is no search path for DLLs.
 	  _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
-	  _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-all-symbols'
+	  _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-all-symbols'
 	  _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
 	  _LT_TAGVAR(always_export_symbols, $1)=no
 	  _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
 
 	  if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then
-	    _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
-	    # If the export-symbols file already is a .def file, use it as
-	    # is; otherwise, prepend EXPORTS...
-	    _LT_TAGVAR(archive_expsym_cmds, $1)='if _LT_DLL_DEF_P([$export_symbols]); then
-              cp $export_symbols $output_objdir/$soname.def;
-            else
-              echo EXPORTS > $output_objdir/$soname.def;
-              cat $export_symbols >> $output_objdir/$soname.def;
-            fi~
-            $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+	    _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+	    # If the export-symbols file already is a .def file (1st line
+	    # is EXPORTS), use it as is; otherwise, prepend...
+	    _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then
+	      cp $export_symbols $output_objdir/$soname.def;
+	    else
+	      echo EXPORTS > $output_objdir/$soname.def;
+	      cat $export_symbols >> $output_objdir/$soname.def;
+	    fi~
+	    $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
 	  else
 	    _LT_TAGVAR(ld_shlibs, $1)=no
 	  fi
@@ -6723,34 +6206,6 @@ if test yes != "$_lt_caught_CXX_error"; then
         _LT_DARWIN_LINKER_FEATURES($1)
 	;;
 
-      os2*)
-	_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
-	_LT_TAGVAR(hardcode_minus_L, $1)=yes
-	_LT_TAGVAR(allow_undefined_flag, $1)=unsupported
-	shrext_cmds=.dll
-	_LT_TAGVAR(archive_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~
-	  $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~
-	  $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~
-	  $ECHO EXPORTS >> $output_objdir/$libname.def~
-	  emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~
-	  $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~
-	  emximp -o $lib $output_objdir/$libname.def'
-	_LT_TAGVAR(archive_expsym_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~
-	  $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~
-	  $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~
-	  $ECHO EXPORTS >> $output_objdir/$libname.def~
-	  prefix_cmds="$SED"~
-	  if test EXPORTS = "`$SED 1q $export_symbols`"; then
-	    prefix_cmds="$prefix_cmds -e 1d";
-	  fi~
-	  prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~
-	  cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~
-	  $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~
-	  emximp -o $lib $output_objdir/$libname.def'
-	_LT_TAGVAR(old_archive_From_new_cmds, $1)='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def'
-	_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
-	;;
-
       dgux*)
         case $cc_basename in
           ec++*)
@@ -6786,14 +6241,14 @@ if test yes != "$_lt_caught_CXX_error"; then
         ;;
 
       haiku*)
-        _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+        _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
         _LT_TAGVAR(link_all_deplibs, $1)=yes
         ;;
 
       hpux9*)
-        _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir'
+        _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir'
         _LT_TAGVAR(hardcode_libdir_separator, $1)=:
-        _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E'
+        _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
         _LT_TAGVAR(hardcode_direct, $1)=yes
         _LT_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH,
 				             # but as the default
@@ -6805,7 +6260,7 @@ if test yes != "$_lt_caught_CXX_error"; then
             _LT_TAGVAR(ld_shlibs, $1)=no
             ;;
           aCC*)
-            _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -b $wl+b $wl$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib'
+            _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -b ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
             # Commands to make compiler produce verbose output that lists
             # what "hidden" libraries, object files and flags are used when
             # linking a shared library.
@@ -6814,11 +6269,11 @@ if test yes != "$_lt_caught_CXX_error"; then
             # explicitly linking system object files so we need to strip them
             # from the output so that they don't get included in the library
             # dependencies.
-            output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP "\-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
+            output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
             ;;
           *)
-            if test yes = "$GXX"; then
-              _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared -nostdlib $pic_flag $wl+b $wl$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib'
+            if test "$GXX" = yes; then
+              _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared -nostdlib $pic_flag ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
             else
               # FIXME: insert proper C++ library support
               _LT_TAGVAR(ld_shlibs, $1)=no
@@ -6828,15 +6283,15 @@ if test yes != "$_lt_caught_CXX_error"; then
         ;;
 
       hpux10*|hpux11*)
-        if test no = "$with_gnu_ld"; then
-	  _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir'
+        if test $with_gnu_ld = no; then
+	  _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir'
 	  _LT_TAGVAR(hardcode_libdir_separator, $1)=:
 
           case $host_cpu in
             hppa*64*|ia64*)
               ;;
             *)
-	      _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E'
+	      _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
               ;;
           esac
         fi
@@ -6862,13 +6317,13 @@ if test yes != "$_lt_caught_CXX_error"; then
           aCC*)
 	    case $host_cpu in
 	      hppa*64*)
-	        _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+	        _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
 	        ;;
 	      ia64*)
-	        _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+	        _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
 	        ;;
 	      *)
-	        _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+	        _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
 	        ;;
 	    esac
 	    # Commands to make compiler produce verbose output that lists
@@ -6879,20 +6334,20 @@ if test yes != "$_lt_caught_CXX_error"; then
 	    # explicitly linking system object files so we need to strip them
 	    # from the output so that they don't get included in the library
 	    # dependencies.
-	    output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP "\-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
+	    output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
 	    ;;
           *)
-	    if test yes = "$GXX"; then
-	      if test no = "$with_gnu_ld"; then
+	    if test "$GXX" = yes; then
+	      if test $with_gnu_ld = no; then
 	        case $host_cpu in
 	          hppa*64*)
-	            _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC $wl+h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+	            _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
 	            ;;
 	          ia64*)
-	            _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $pic_flag $wl+h $wl$soname $wl+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+	            _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $pic_flag ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
 	            ;;
 	          *)
-	            _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+	            _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
 	            ;;
 	        esac
 	      fi
@@ -6907,22 +6362,22 @@ if test yes != "$_lt_caught_CXX_error"; then
       interix[[3-9]]*)
 	_LT_TAGVAR(hardcode_direct, $1)=no
 	_LT_TAGVAR(hardcode_shlibpath_var, $1)=no
-	_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir'
-	_LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E'
+	_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
+	_LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
 	# Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc.
 	# Instead, shared libraries are loaded at an image base (0x10000000 by
 	# default) and relocated if they conflict, which is a slow very memory
 	# consuming and fragmenting process.  To avoid this, we pick a random,
 	# 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link
 	# time.  Moving up from 0x10000000 also allows more sbrk(2) space.
-	_LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
-	_LT_TAGVAR(archive_expsym_cmds, $1)='sed "s|^|_|" $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--retain-symbols-file,$output_objdir/$soname.expsym $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+	_LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+	_LT_TAGVAR(archive_expsym_cmds, $1)='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
 	;;
       irix5* | irix6*)
         case $cc_basename in
           CC*)
 	    # SGI C++
-	    _LT_TAGVAR(archive_cmds, $1)='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib'
+	    _LT_TAGVAR(archive_cmds, $1)='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib'
 
 	    # Archives containing C++ object files must be created using
 	    # "CC -ar", where "CC" is the IRIX C++ compiler.  This is
@@ -6931,17 +6386,17 @@ if test yes != "$_lt_caught_CXX_error"; then
 	    _LT_TAGVAR(old_archive_cmds, $1)='$CC -ar -WR,-u -o $oldlib $oldobjs'
 	    ;;
           *)
-	    if test yes = "$GXX"; then
-	      if test no = "$with_gnu_ld"; then
-	        _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib'
+	    if test "$GXX" = yes; then
+	      if test "$with_gnu_ld" = no; then
+	        _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
 	      else
-	        _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` -o $lib'
+	        _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` -o $lib'
 	      fi
 	    fi
 	    _LT_TAGVAR(link_all_deplibs, $1)=yes
 	    ;;
         esac
-        _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir'
+        _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
         _LT_TAGVAR(hardcode_libdir_separator, $1)=:
         _LT_TAGVAR(inherit_rpath, $1)=yes
         ;;
@@ -6954,8 +6409,8 @@ if test yes != "$_lt_caught_CXX_error"; then
 	    # KCC will only create a shared library if the output file
 	    # ends with ".so" (or ".sl" for HP-UX), so rename the library
 	    # to its proper name (with version) after linking.
-	    _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib'
-	    _LT_TAGVAR(archive_expsym_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib $wl-retain-symbols-file,$export_symbols; mv \$templib $lib'
+	    _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib'
+	    _LT_TAGVAR(archive_expsym_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib ${wl}-retain-symbols-file,$export_symbols; mv \$templib $lib'
 	    # Commands to make compiler produce verbose output that lists
 	    # what "hidden" libraries, object files and flags are used when
 	    # linking a shared library.
@@ -6964,10 +6419,10 @@ if test yes != "$_lt_caught_CXX_error"; then
 	    # explicitly linking system object files so we need to strip them
 	    # from the output so that they don't get included in the library
 	    # dependencies.
-	    output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | $GREP "ld"`; rm -f libconftest$shared_ext; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
+	    output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | $GREP "ld"`; rm -f libconftest$shared_ext; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
 
-	    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir'
-	    _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic'
+	    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
+	    _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic'
 
 	    # Archives containing C++ object files must be created using
 	    # "CC -Bstatic", where "CC" is the KAI C++ compiler.
@@ -6981,59 +6436,59 @@ if test yes != "$_lt_caught_CXX_error"; then
 	    # earlier do not add the objects themselves.
 	    case `$CC -V 2>&1` in
 	      *"Version 7."*)
-	        _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib'
-		_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'
+	        _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib'
+		_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
 		;;
 	      *)  # Version 8.0 or newer
 	        tmp_idyn=
 	        case $host_cpu in
 		  ia64*) tmp_idyn=' -i_dynamic';;
 		esac
-	        _LT_TAGVAR(archive_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
-		_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'
+	        _LT_TAGVAR(archive_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+		_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
 		;;
 	    esac
 	    _LT_TAGVAR(archive_cmds_need_lc, $1)=no
-	    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir'
-	    _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic'
-	    _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive$convenience $wl--no-whole-archive'
+	    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
+	    _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic'
+	    _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive$convenience ${wl}--no-whole-archive'
 	    ;;
           pgCC* | pgcpp*)
             # Portland Group C++ compiler
 	    case `$CC -V` in
 	    *pgCC\ [[1-5]].* | *pgcpp\ [[1-5]].*)
 	      _LT_TAGVAR(prelink_cmds, $1)='tpldir=Template.dir~
-               rm -rf $tpldir~
-               $CC --prelink_objects --instantiation_dir $tpldir $objs $libobjs $compile_deplibs~
-               compile_command="$compile_command `find $tpldir -name \*.o | sort | $NL2SP`"'
+		rm -rf $tpldir~
+		$CC --prelink_objects --instantiation_dir $tpldir $objs $libobjs $compile_deplibs~
+		compile_command="$compile_command `find $tpldir -name \*.o | sort | $NL2SP`"'
 	      _LT_TAGVAR(old_archive_cmds, $1)='tpldir=Template.dir~
-                rm -rf $tpldir~
-                $CC --prelink_objects --instantiation_dir $tpldir $oldobjs$old_deplibs~
-                $AR $AR_FLAGS $oldlib$oldobjs$old_deplibs `find $tpldir -name \*.o | sort | $NL2SP`~
-                $RANLIB $oldlib'
+		rm -rf $tpldir~
+		$CC --prelink_objects --instantiation_dir $tpldir $oldobjs$old_deplibs~
+		$AR $AR_FLAGS $oldlib$oldobjs$old_deplibs `find $tpldir -name \*.o | sort | $NL2SP`~
+		$RANLIB $oldlib'
 	      _LT_TAGVAR(archive_cmds, $1)='tpldir=Template.dir~
-                rm -rf $tpldir~
-                $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~
-                $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib'
+		rm -rf $tpldir~
+		$CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~
+		$CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib'
 	      _LT_TAGVAR(archive_expsym_cmds, $1)='tpldir=Template.dir~
-                rm -rf $tpldir~
-                $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~
-                $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'
+		rm -rf $tpldir~
+		$CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~
+		$CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib'
 	      ;;
 	    *) # Version 6 and above use weak symbols
-	      _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib'
-	      _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'
+	      _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib'
+	      _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib'
 	      ;;
 	    esac
 
-	    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl--rpath $wl$libdir'
-	    _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic'
-	    _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive'
+	    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}--rpath ${wl}$libdir'
+	    _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic'
+	    _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
             ;;
 	  cxx*)
 	    # Compaq C++
-	    _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib'
-	    _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname  -o $lib $wl-retain-symbols-file $wl$export_symbols'
+	    _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib'
+	    _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname  -o $lib ${wl}-retain-symbols-file $wl$export_symbols'
 
 	    runpath_var=LD_RUN_PATH
 	    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir'
@@ -7047,18 +6502,18 @@ if test yes != "$_lt_caught_CXX_error"; then
 	    # explicitly linking system object files so we need to strip them
 	    # from the output so that they don't get included in the library
 	    # dependencies.
-	    output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "X$list" | $Xsed'
+	    output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "X$list" | $Xsed'
 	    ;;
 	  xl* | mpixl* | bgxl*)
 	    # IBM XL 8.0 on PPC, with GNU ld
-	    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir'
-	    _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic'
-	    _LT_TAGVAR(archive_cmds, $1)='$CC -qmkshrobj $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
-	    if test yes = "$supports_anon_versioning"; then
+	    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+	    _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic'
+	    _LT_TAGVAR(archive_cmds, $1)='$CC -qmkshrobj $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+	    if test "x$supports_anon_versioning" = xyes; then
 	      _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~
-                cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
-                echo "local: *; };" >> $output_objdir/$libname.ver~
-                $CC -qmkshrobj $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-version-script $wl$output_objdir/$libname.ver -o $lib'
+		cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
+		echo "local: *; };" >> $output_objdir/$libname.ver~
+		$CC -qmkshrobj $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib'
 	    fi
 	    ;;
 	  *)
@@ -7066,10 +6521,10 @@ if test yes != "$_lt_caught_CXX_error"; then
 	    *Sun\ C*)
 	      # Sun C++ 5.9
 	      _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs'
-	      _LT_TAGVAR(archive_cmds, $1)='$CC -G$allow_undefined_flag -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
-	      _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G$allow_undefined_flag -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-retain-symbols-file $wl$export_symbols'
+	      _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+	      _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file ${wl}$export_symbols'
 	      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
-	      _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive'
+	      _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
 	      _LT_TAGVAR(compiler_needs_object, $1)=yes
 
 	      # Not sure whether something based on
@@ -7127,17 +6582,22 @@ if test yes != "$_lt_caught_CXX_error"; then
         _LT_TAGVAR(ld_shlibs, $1)=yes
 	;;
 
-      openbsd* | bitrig*)
+      openbsd2*)
+        # C++ shared libraries are fairly broken
+	_LT_TAGVAR(ld_shlibs, $1)=no
+	;;
+
+      openbsd*)
 	if test -f /usr/libexec/ld.so; then
 	  _LT_TAGVAR(hardcode_direct, $1)=yes
 	  _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
 	  _LT_TAGVAR(hardcode_direct_absolute, $1)=yes
 	  _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib'
-	  _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir'
-	  if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`"; then
-	    _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-retain-symbols-file,$export_symbols -o $lib'
-	    _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E'
-	    _LT_TAGVAR(whole_archive_flag_spec, $1)=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive'
+	  _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
+	  if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+	    _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file,$export_symbols -o $lib'
+	    _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
+	    _LT_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive'
 	  fi
 	  output_verbose_link_cmd=func_echo_all
 	else
@@ -7153,9 +6613,9 @@ if test yes != "$_lt_caught_CXX_error"; then
 	    # KCC will only create a shared library if the output file
 	    # ends with ".so" (or ".sl" for HP-UX), so rename the library
 	    # to its proper name (with version) after linking.
-	    _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo "$lib" | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib'
+	    _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo "$lib" | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib'
 
-	    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir'
+	    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
 	    _LT_TAGVAR(hardcode_libdir_separator, $1)=:
 
 	    # Archives containing C++ object files must be created using
@@ -7173,17 +6633,17 @@ if test yes != "$_lt_caught_CXX_error"; then
           cxx*)
 	    case $host in
 	      osf3*)
-	        _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-expect_unresolved $wl\*'
-	        _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $soname `test -n "$verstring" && func_echo_all "$wl-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib'
-	        _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir'
+	        _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*'
+	        _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $soname `test -n "$verstring" && func_echo_all "${wl}-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib'
+	        _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
 		;;
 	      *)
 	        _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*'
-	        _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib'
+	        _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib'
 	        _LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done~
-                  echo "-hidden">> $lib.exp~
-                  $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname $wl-input $wl$lib.exp  `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib~
-                  $RM $lib.exp'
+	          echo "-hidden">> $lib.exp~
+	          $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname ${wl}-input ${wl}$lib.exp  `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib~
+	          $RM $lib.exp'
 	        _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir'
 		;;
 	    esac
@@ -7198,21 +6658,21 @@ if test yes != "$_lt_caught_CXX_error"; then
 	    # explicitly linking system object files so we need to strip them
 	    # from the output so that they don't get included in the library
 	    # dependencies.
-	    output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld" | $GREP -v "ld:"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
+	    output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld" | $GREP -v "ld:"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
 	    ;;
 	  *)
-	    if test yes,no = "$GXX,$with_gnu_ld"; then
-	      _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-expect_unresolved $wl\*'
+	    if test "$GXX" = yes && test "$with_gnu_ld" = no; then
+	      _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*'
 	      case $host in
 	        osf3*)
-	          _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib'
+	          _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
 		  ;;
 	        *)
-	          _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-msym $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib'
+	          _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
 		  ;;
 	      esac
 
-	      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir'
+	      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
 	      _LT_TAGVAR(hardcode_libdir_separator, $1)=:
 
 	      # Commands to make compiler produce verbose output that lists
@@ -7258,9 +6718,9 @@ if test yes != "$_lt_caught_CXX_error"; then
 	    # Sun C++ 4.2, 5.x and Centerline C++
             _LT_TAGVAR(archive_cmds_need_lc,$1)=yes
 	    _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs'
-	    _LT_TAGVAR(archive_cmds, $1)='$CC -G$allow_undefined_flag -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+	    _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag}  -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
 	    _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
-              $CC -G$allow_undefined_flag $wl-M $wl$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp'
+	      $CC -G${allow_undefined_flag} ${wl}-M ${wl}$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp'
 
 	    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
 	    _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
@@ -7268,7 +6728,7 @@ if test yes != "$_lt_caught_CXX_error"; then
 	      solaris2.[[0-5]] | solaris2.[[0-5]].*) ;;
 	      *)
 		# The compiler driver will combine and reorder linker options,
-		# but understands '-z linker_flag'.
+		# but understands `-z linker_flag'.
 	        # Supported since Solaris 2.6 (maybe 2.5.1?)
 		_LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract'
 	        ;;
@@ -7285,30 +6745,30 @@ if test yes != "$_lt_caught_CXX_error"; then
 	    ;;
           gcx*)
 	    # Green Hills C++ Compiler
-	    _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-h $wl$soname -o $lib'
+	    _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib'
 
 	    # The C++ compiler must be used to create the archive.
 	    _LT_TAGVAR(old_archive_cmds, $1)='$CC $LDFLAGS -archive -o $oldlib $oldobjs'
 	    ;;
           *)
 	    # GNU C++ compiler with Solaris linker
-	    if test yes,no = "$GXX,$with_gnu_ld"; then
-	      _LT_TAGVAR(no_undefined_flag, $1)=' $wl-z ${wl}defs'
+	    if test "$GXX" = yes && test "$with_gnu_ld" = no; then
+	      _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-z ${wl}defs'
 	      if $CC --version | $GREP -v '^2\.7' > /dev/null; then
-	        _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-h $wl$soname -o $lib'
+	        _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib'
 	        _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
-                  $CC -shared $pic_flag -nostdlib $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp'
+		  $CC -shared $pic_flag -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp'
 
 	        # Commands to make compiler produce verbose output that lists
 	        # what "hidden" libraries, object files and flags are used when
 	        # linking a shared library.
 	        output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"'
 	      else
-	        # g++ 2.7 appears to require '-G' NOT '-shared' on this
+	        # g++ 2.7 appears to require `-G' NOT `-shared' on this
 	        # platform.
-	        _LT_TAGVAR(archive_cmds, $1)='$CC -G -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-h $wl$soname -o $lib'
+	        _LT_TAGVAR(archive_cmds, $1)='$CC -G -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib'
 	        _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
-                  $CC -G -nostdlib $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp'
+		  $CC -G -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp'
 
 	        # Commands to make compiler produce verbose output that lists
 	        # what "hidden" libraries, object files and flags are used when
@@ -7316,11 +6776,11 @@ if test yes != "$_lt_caught_CXX_error"; then
 	        output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"'
 	      fi
 
-	      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R $wl$libdir'
+	      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $wl$libdir'
 	      case $host_os in
 		solaris2.[[0-5]] | solaris2.[[0-5]].*) ;;
 		*)
-		  _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl-z ${wl}allextract$convenience $wl-z ${wl}defaultextract'
+		  _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract'
 		  ;;
 	      esac
 	    fi
@@ -7329,52 +6789,52 @@ if test yes != "$_lt_caught_CXX_error"; then
         ;;
 
     sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*)
-      _LT_TAGVAR(no_undefined_flag, $1)='$wl-z,text'
+      _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text'
       _LT_TAGVAR(archive_cmds_need_lc, $1)=no
       _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
       runpath_var='LD_RUN_PATH'
 
       case $cc_basename in
         CC*)
-	  _LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
-	  _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	  _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	  _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
 	  ;;
 	*)
-	  _LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
-	  _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	  _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	  _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
 	  ;;
       esac
       ;;
 
       sysv5* | sco3.2v5* | sco5v6*)
-	# Note: We CANNOT use -z defs as we might desire, because we do not
+	# Note: We can NOT use -z defs as we might desire, because we do not
 	# link with -lc, and that would cause any symbols used from libc to
 	# always be unresolved, which means just about no library would
 	# ever link correctly.  If we're not using GNU ld we use -z text
 	# though, which does catch some bad symbols but isn't as heavy-handed
 	# as -z defs.
-	_LT_TAGVAR(no_undefined_flag, $1)='$wl-z,text'
-	_LT_TAGVAR(allow_undefined_flag, $1)='$wl-z,nodefs'
+	_LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text'
+	_LT_TAGVAR(allow_undefined_flag, $1)='${wl}-z,nodefs'
 	_LT_TAGVAR(archive_cmds_need_lc, $1)=no
 	_LT_TAGVAR(hardcode_shlibpath_var, $1)=no
-	_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R,$libdir'
+	_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R,$libdir'
 	_LT_TAGVAR(hardcode_libdir_separator, $1)=':'
 	_LT_TAGVAR(link_all_deplibs, $1)=yes
-	_LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-Bexport'
+	_LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Bexport'
 	runpath_var='LD_RUN_PATH'
 
 	case $cc_basename in
           CC*)
-	    _LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
-	    _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	    _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	    _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
 	    _LT_TAGVAR(old_archive_cmds, $1)='$CC -Tprelink_objects $oldobjs~
-              '"$_LT_TAGVAR(old_archive_cmds, $1)"
+	      '"$_LT_TAGVAR(old_archive_cmds, $1)"
 	    _LT_TAGVAR(reload_cmds, $1)='$CC -Tprelink_objects $reload_objs~
-              '"$_LT_TAGVAR(reload_cmds, $1)"
+	      '"$_LT_TAGVAR(reload_cmds, $1)"
 	    ;;
 	  *)
-	    _LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
-	    _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	    _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	    _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
 	    ;;
 	esac
       ;;
@@ -7405,10 +6865,10 @@ if test yes != "$_lt_caught_CXX_error"; then
     esac
 
     AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)])
-    test no = "$_LT_TAGVAR(ld_shlibs, $1)" && can_build_shared=no
+    test "$_LT_TAGVAR(ld_shlibs, $1)" = no && can_build_shared=no
 
-    _LT_TAGVAR(GCC, $1)=$GXX
-    _LT_TAGVAR(LD, $1)=$LD
+    _LT_TAGVAR(GCC, $1)="$GXX"
+    _LT_TAGVAR(LD, $1)="$LD"
 
     ## CAVEAT EMPTOR:
     ## There is no encapsulation within the following macros, do not change
@@ -7435,7 +6895,7 @@ if test yes != "$_lt_caught_CXX_error"; then
   lt_cv_path_LD=$lt_save_path_LD
   lt_cv_prog_gnu_ldcxx=$lt_cv_prog_gnu_ld
   lt_cv_prog_gnu_ld=$lt_save_with_gnu_ld
-fi # test yes != "$_lt_caught_CXX_error"
+fi # test "$_lt_caught_CXX_error" != yes
 
 AC_LANG_POP
 ])# _LT_LANG_CXX_CONFIG
@@ -7457,14 +6917,13 @@ AC_REQUIRE([_LT_DECL_SED])
 AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH])
 func_stripname_cnf ()
 {
-  case @S|@2 in
-  .*) func_stripname_result=`$ECHO "@S|@3" | $SED "s%^@S|@1%%; s%\\\\@S|@2\$%%"`;;
-  *)  func_stripname_result=`$ECHO "@S|@3" | $SED "s%^@S|@1%%; s%@S|@2\$%%"`;;
+  case ${2} in
+  .*) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%\\\\${2}\$%%"`;;
+  *)  func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%${2}\$%%"`;;
   esac
 } # func_stripname_cnf
 ])# _LT_FUNC_STRIPNAME_CNF
 
-
 # _LT_SYS_HIDDEN_LIBDEPS([TAGNAME])
 # ---------------------------------
 # Figure out "hidden" library dependencies from verbose
@@ -7548,13 +7007,13 @@ if AC_TRY_EVAL(ac_compile); then
   pre_test_object_deps_done=no
 
   for p in `eval "$output_verbose_link_cmd"`; do
-    case $prev$p in
+    case ${prev}${p} in
 
     -L* | -R* | -l*)
        # Some compilers place space between "-{L,R}" and the path.
        # Remove the space.
-       if test x-L = "$p" ||
-          test x-R = "$p"; then
+       if test $p = "-L" ||
+          test $p = "-R"; then
 	 prev=$p
 	 continue
        fi
@@ -7570,16 +7029,16 @@ if AC_TRY_EVAL(ac_compile); then
        case $p in
        =*) func_stripname_cnf '=' '' "$p"; p=$lt_sysroot$func_stripname_result ;;
        esac
-       if test no = "$pre_test_object_deps_done"; then
-	 case $prev in
+       if test "$pre_test_object_deps_done" = no; then
+	 case ${prev} in
 	 -L | -R)
 	   # Internal compiler library paths should come after those
 	   # provided the user.  The postdeps already come after the
 	   # user supplied libs so there is no need to process them.
 	   if test -z "$_LT_TAGVAR(compiler_lib_search_path, $1)"; then
-	     _LT_TAGVAR(compiler_lib_search_path, $1)=$prev$p
+	     _LT_TAGVAR(compiler_lib_search_path, $1)="${prev}${p}"
 	   else
-	     _LT_TAGVAR(compiler_lib_search_path, $1)="${_LT_TAGVAR(compiler_lib_search_path, $1)} $prev$p"
+	     _LT_TAGVAR(compiler_lib_search_path, $1)="${_LT_TAGVAR(compiler_lib_search_path, $1)} ${prev}${p}"
 	   fi
 	   ;;
 	 # The "-l" case would never come before the object being
@@ -7587,9 +7046,9 @@ if AC_TRY_EVAL(ac_compile); then
 	 esac
        else
 	 if test -z "$_LT_TAGVAR(postdeps, $1)"; then
-	   _LT_TAGVAR(postdeps, $1)=$prev$p
+	   _LT_TAGVAR(postdeps, $1)="${prev}${p}"
 	 else
-	   _LT_TAGVAR(postdeps, $1)="${_LT_TAGVAR(postdeps, $1)} $prev$p"
+	   _LT_TAGVAR(postdeps, $1)="${_LT_TAGVAR(postdeps, $1)} ${prev}${p}"
 	 fi
        fi
        prev=
@@ -7604,15 +7063,15 @@ if AC_TRY_EVAL(ac_compile); then
 	 continue
        fi
 
-       if test no = "$pre_test_object_deps_done"; then
+       if test "$pre_test_object_deps_done" = no; then
 	 if test -z "$_LT_TAGVAR(predep_objects, $1)"; then
-	   _LT_TAGVAR(predep_objects, $1)=$p
+	   _LT_TAGVAR(predep_objects, $1)="$p"
 	 else
 	   _LT_TAGVAR(predep_objects, $1)="$_LT_TAGVAR(predep_objects, $1) $p"
 	 fi
        else
 	 if test -z "$_LT_TAGVAR(postdep_objects, $1)"; then
-	   _LT_TAGVAR(postdep_objects, $1)=$p
+	   _LT_TAGVAR(postdep_objects, $1)="$p"
 	 else
 	   _LT_TAGVAR(postdep_objects, $1)="$_LT_TAGVAR(postdep_objects, $1) $p"
 	 fi
@@ -7643,6 +7102,51 @@ interix[[3-9]]*)
   _LT_TAGVAR(postdep_objects,$1)=
   _LT_TAGVAR(postdeps,$1)=
   ;;
+
+linux*)
+  case `$CC -V 2>&1 | sed 5q` in
+  *Sun\ C*)
+    # Sun C++ 5.9
+
+    # The more standards-conforming stlport4 library is
+    # incompatible with the Cstd library. Avoid specifying
+    # it if it's in CXXFLAGS. Ignore libCrun as
+    # -library=stlport4 depends on it.
+    case " $CXX $CXXFLAGS " in
+    *" -library=stlport4 "*)
+      solaris_use_stlport4=yes
+      ;;
+    esac
+
+    if test "$solaris_use_stlport4" != yes; then
+      _LT_TAGVAR(postdeps,$1)='-library=Cstd -library=Crun'
+    fi
+    ;;
+  esac
+  ;;
+
+solaris*)
+  case $cc_basename in
+  CC* | sunCC*)
+    # The more standards-conforming stlport4 library is
+    # incompatible with the Cstd library. Avoid specifying
+    # it if it's in CXXFLAGS. Ignore libCrun as
+    # -library=stlport4 depends on it.
+    case " $CXX $CXXFLAGS " in
+    *" -library=stlport4 "*)
+      solaris_use_stlport4=yes
+      ;;
+    esac
+
+    # Adding this requires a known-good setup of shared libraries for
+    # Sun compiler versions before 5.6, else PIC objects from an old
+    # archive will be linked into the output, leading to subtle bugs.
+    if test "$solaris_use_stlport4" != yes; then
+      _LT_TAGVAR(postdeps,$1)='-library=Cstd -library=Crun'
+    fi
+    ;;
+  esac
+  ;;
 esac
 ])
 
@@ -7651,7 +7155,7 @@ case " $_LT_TAGVAR(postdeps, $1) " in
 esac
  _LT_TAGVAR(compiler_lib_search_dirs, $1)=
 if test -n "${_LT_TAGVAR(compiler_lib_search_path, $1)}"; then
- _LT_TAGVAR(compiler_lib_search_dirs, $1)=`echo " ${_LT_TAGVAR(compiler_lib_search_path, $1)}" | $SED -e 's! -L! !g' -e 's!^ !!'`
+ _LT_TAGVAR(compiler_lib_search_dirs, $1)=`echo " ${_LT_TAGVAR(compiler_lib_search_path, $1)}" | ${SED} -e 's! -L! !g' -e 's!^ !!'`
 fi
 _LT_TAGDECL([], [compiler_lib_search_dirs], [1],
     [The directories searched by this compiler when creating a shared library])
@@ -7671,10 +7175,10 @@ _LT_TAGDECL([], [compiler_lib_search_path], [1],
 # --------------------------
 # Ensure that the configuration variables for a Fortran 77 compiler are
 # suitably defined.  These variables are subsequently used by _LT_CONFIG
-# to write the compiler configuration to 'libtool'.
+# to write the compiler configuration to `libtool'.
 m4_defun([_LT_LANG_F77_CONFIG],
 [AC_LANG_PUSH(Fortran 77)
-if test -z "$F77" || test no = "$F77"; then
+if test -z "$F77" || test "X$F77" = "Xno"; then
   _lt_disable_F77=yes
 fi
 
@@ -7711,7 +7215,7 @@ _LT_TAGVAR(objext, $1)=$objext
 # the F77 compiler isn't working.  Some variables (like enable_shared)
 # are currently assumed to apply to all compilers on this platform,
 # and will be corrupted by setting them based on a non-working compiler.
-if test yes != "$_lt_disable_F77"; then
+if test "$_lt_disable_F77" != yes; then
   # Code to be used in simple compile tests
   lt_simple_compile_test_code="\
       subroutine t
@@ -7733,7 +7237,7 @@ if test yes != "$_lt_disable_F77"; then
   _LT_LINKER_BOILERPLATE
 
   # Allow CC to be a program name with arguments.
-  lt_save_CC=$CC
+  lt_save_CC="$CC"
   lt_save_GCC=$GCC
   lt_save_CFLAGS=$CFLAGS
   CC=${F77-"f77"}
@@ -7747,25 +7251,21 @@ if test yes != "$_lt_disable_F77"; then
     AC_MSG_RESULT([$can_build_shared])
 
     AC_MSG_CHECKING([whether to build shared libraries])
-    test no = "$can_build_shared" && enable_shared=no
+    test "$can_build_shared" = "no" && enable_shared=no
 
     # On AIX, shared libraries and static libraries use the same namespace, and
     # are all built from PIC.
     case $host_os in
       aix3*)
-        test yes = "$enable_shared" && enable_static=no
+        test "$enable_shared" = yes && enable_static=no
         if test -n "$RANLIB"; then
           archive_cmds="$archive_cmds~\$RANLIB \$lib"
           postinstall_cmds='$RANLIB $lib'
         fi
         ;;
       aix[[4-9]]*)
-	if test ia64 != "$host_cpu"; then
-	  case $enable_shared,$with_aix_soname,$aix_use_runtimelinking in
-	  yes,aix,yes) ;;		# shared object as lib.so file only
-	  yes,svr4,*) ;;		# shared object as lib.so archive member only
-	  yes,*) enable_static=no ;;	# shared object in lib.a archive as well
-	  esac
+	if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then
+	  test "$enable_shared" = yes && enable_static=no
 	fi
         ;;
     esac
@@ -7773,11 +7273,11 @@ if test yes != "$_lt_disable_F77"; then
 
     AC_MSG_CHECKING([whether to build static libraries])
     # Make sure either enable_shared or enable_static is yes.
-    test yes = "$enable_shared" || enable_static=yes
+    test "$enable_shared" = yes || enable_static=yes
     AC_MSG_RESULT([$enable_static])
 
-    _LT_TAGVAR(GCC, $1)=$G77
-    _LT_TAGVAR(LD, $1)=$LD
+    _LT_TAGVAR(GCC, $1)="$G77"
+    _LT_TAGVAR(LD, $1)="$LD"
 
     ## CAVEAT EMPTOR:
     ## There is no encapsulation within the following macros, do not change
@@ -7794,9 +7294,9 @@ if test yes != "$_lt_disable_F77"; then
   fi # test -n "$compiler"
 
   GCC=$lt_save_GCC
-  CC=$lt_save_CC
-  CFLAGS=$lt_save_CFLAGS
-fi # test yes != "$_lt_disable_F77"
+  CC="$lt_save_CC"
+  CFLAGS="$lt_save_CFLAGS"
+fi # test "$_lt_disable_F77" != yes
 
 AC_LANG_POP
 ])# _LT_LANG_F77_CONFIG
@@ -7806,11 +7306,11 @@ AC_LANG_POP
 # -------------------------
 # Ensure that the configuration variables for a Fortran compiler are
 # suitably defined.  These variables are subsequently used by _LT_CONFIG
-# to write the compiler configuration to 'libtool'.
+# to write the compiler configuration to `libtool'.
 m4_defun([_LT_LANG_FC_CONFIG],
 [AC_LANG_PUSH(Fortran)
 
-if test -z "$FC" || test no = "$FC"; then
+if test -z "$FC" || test "X$FC" = "Xno"; then
   _lt_disable_FC=yes
 fi
 
@@ -7847,7 +7347,7 @@ _LT_TAGVAR(objext, $1)=$objext
 # the FC compiler isn't working.  Some variables (like enable_shared)
 # are currently assumed to apply to all compilers on this platform,
 # and will be corrupted by setting them based on a non-working compiler.
-if test yes != "$_lt_disable_FC"; then
+if test "$_lt_disable_FC" != yes; then
   # Code to be used in simple compile tests
   lt_simple_compile_test_code="\
       subroutine t
@@ -7869,7 +7369,7 @@ if test yes != "$_lt_disable_FC"; then
   _LT_LINKER_BOILERPLATE
 
   # Allow CC to be a program name with arguments.
-  lt_save_CC=$CC
+  lt_save_CC="$CC"
   lt_save_GCC=$GCC
   lt_save_CFLAGS=$CFLAGS
   CC=${FC-"f95"}
@@ -7885,25 +7385,21 @@ if test yes != "$_lt_disable_FC"; then
     AC_MSG_RESULT([$can_build_shared])
 
     AC_MSG_CHECKING([whether to build shared libraries])
-    test no = "$can_build_shared" && enable_shared=no
+    test "$can_build_shared" = "no" && enable_shared=no
 
     # On AIX, shared libraries and static libraries use the same namespace, and
     # are all built from PIC.
     case $host_os in
       aix3*)
-        test yes = "$enable_shared" && enable_static=no
+        test "$enable_shared" = yes && enable_static=no
         if test -n "$RANLIB"; then
           archive_cmds="$archive_cmds~\$RANLIB \$lib"
           postinstall_cmds='$RANLIB $lib'
         fi
         ;;
       aix[[4-9]]*)
-	if test ia64 != "$host_cpu"; then
-	  case $enable_shared,$with_aix_soname,$aix_use_runtimelinking in
-	  yes,aix,yes) ;;		# shared object as lib.so file only
-	  yes,svr4,*) ;;		# shared object as lib.so archive member only
-	  yes,*) enable_static=no ;;	# shared object in lib.a archive as well
-	  esac
+	if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then
+	  test "$enable_shared" = yes && enable_static=no
 	fi
         ;;
     esac
@@ -7911,11 +7407,11 @@ if test yes != "$_lt_disable_FC"; then
 
     AC_MSG_CHECKING([whether to build static libraries])
     # Make sure either enable_shared or enable_static is yes.
-    test yes = "$enable_shared" || enable_static=yes
+    test "$enable_shared" = yes || enable_static=yes
     AC_MSG_RESULT([$enable_static])
 
-    _LT_TAGVAR(GCC, $1)=$ac_cv_fc_compiler_gnu
-    _LT_TAGVAR(LD, $1)=$LD
+    _LT_TAGVAR(GCC, $1)="$ac_cv_fc_compiler_gnu"
+    _LT_TAGVAR(LD, $1)="$LD"
 
     ## CAVEAT EMPTOR:
     ## There is no encapsulation within the following macros, do not change
@@ -7935,7 +7431,7 @@ if test yes != "$_lt_disable_FC"; then
   GCC=$lt_save_GCC
   CC=$lt_save_CC
   CFLAGS=$lt_save_CFLAGS
-fi # test yes != "$_lt_disable_FC"
+fi # test "$_lt_disable_FC" != yes
 
 AC_LANG_POP
 ])# _LT_LANG_FC_CONFIG
@@ -7945,7 +7441,7 @@ AC_LANG_POP
 # --------------------------
 # Ensure that the configuration variables for the GNU Java Compiler compiler
 # are suitably defined.  These variables are subsequently used by _LT_CONFIG
-# to write the compiler configuration to 'libtool'.
+# to write the compiler configuration to `libtool'.
 m4_defun([_LT_LANG_GCJ_CONFIG],
 [AC_REQUIRE([LT_PROG_GCJ])dnl
 AC_LANG_SAVE
@@ -7979,7 +7475,7 @@ CC=${GCJ-"gcj"}
 CFLAGS=$GCJFLAGS
 compiler=$CC
 _LT_TAGVAR(compiler, $1)=$CC
-_LT_TAGVAR(LD, $1)=$LD
+_LT_TAGVAR(LD, $1)="$LD"
 _LT_CC_BASENAME([$compiler])
 
 # GCJ did not exist at the time GCC didn't implicitly link libc in.
@@ -8016,7 +7512,7 @@ CFLAGS=$lt_save_CFLAGS
 # --------------------------
 # Ensure that the configuration variables for the GNU Go compiler
 # are suitably defined.  These variables are subsequently used by _LT_CONFIG
-# to write the compiler configuration to 'libtool'.
+# to write the compiler configuration to `libtool'.
 m4_defun([_LT_LANG_GO_CONFIG],
 [AC_REQUIRE([LT_PROG_GO])dnl
 AC_LANG_SAVE
@@ -8050,7 +7546,7 @@ CC=${GOC-"gccgo"}
 CFLAGS=$GOFLAGS
 compiler=$CC
 _LT_TAGVAR(compiler, $1)=$CC
-_LT_TAGVAR(LD, $1)=$LD
+_LT_TAGVAR(LD, $1)="$LD"
 _LT_CC_BASENAME([$compiler])
 
 # Go did not exist at the time GCC didn't implicitly link libc in.
@@ -8087,7 +7583,7 @@ CFLAGS=$lt_save_CFLAGS
 # -------------------------
 # Ensure that the configuration variables for the Windows resource compiler
 # are suitably defined.  These variables are subsequently used by _LT_CONFIG
-# to write the compiler configuration to 'libtool'.
+# to write the compiler configuration to `libtool'.
 m4_defun([_LT_LANG_RC_CONFIG],
 [AC_REQUIRE([LT_PROG_RC])dnl
 AC_LANG_SAVE
@@ -8103,7 +7599,7 @@ _LT_TAGVAR(objext, $1)=$objext
 lt_simple_compile_test_code='sample MENU { MENUITEM "&Soup", 100, CHECKED }'
 
 # Code to be used in simple link tests
-lt_simple_link_test_code=$lt_simple_compile_test_code
+lt_simple_link_test_code="$lt_simple_compile_test_code"
 
 # ltmain only uses $CC for tagged configurations so make sure $CC is set.
 _LT_TAG_COMPILER
@@ -8113,7 +7609,7 @@ _LT_COMPILER_BOILERPLATE
 _LT_LINKER_BOILERPLATE
 
 # Allow CC to be a program name with arguments.
-lt_save_CC=$CC
+lt_save_CC="$CC"
 lt_save_CFLAGS=$CFLAGS
 lt_save_GCC=$GCC
 GCC=
@@ -8142,7 +7638,7 @@ AC_DEFUN([LT_PROG_GCJ],
 [m4_ifdef([AC_PROG_GCJ], [AC_PROG_GCJ],
   [m4_ifdef([A][M_PROG_GCJ], [A][M_PROG_GCJ],
     [AC_CHECK_TOOL(GCJ, gcj,)
-      test set = "${GCJFLAGS+set}" || GCJFLAGS="-g -O2"
+      test "x${GCJFLAGS+set}" = xset || GCJFLAGS="-g -O2"
       AC_SUBST(GCJFLAGS)])])[]dnl
 ])
 
@@ -8253,7 +7749,7 @@ lt_ac_count=0
 # Add /usr/xpg4/bin/sed as it is typically found on Solaris
 # along with /bin/sed that truncates output.
 for lt_ac_sed in $lt_ac_sed_list /usr/xpg4/bin/sed; do
-  test ! -f "$lt_ac_sed" && continue
+  test ! -f $lt_ac_sed && continue
   cat /dev/null > conftest.in
   lt_ac_count=0
   echo $ECHO_N "0123456789$ECHO_C" >conftest.in
@@ -8270,9 +7766,9 @@ for lt_ac_sed in $lt_ac_sed_list /usr/xpg4/bin/sed; do
     $lt_ac_sed -e 's/a$//' < conftest.nl >conftest.out || break
     cmp -s conftest.out conftest.nl || break
     # 10000 chars as input seems more than enough
-    test 10 -lt "$lt_ac_count" && break
+    test $lt_ac_count -gt 10 && break
     lt_ac_count=`expr $lt_ac_count + 1`
-    if test "$lt_ac_count" -gt "$lt_ac_max"; then
+    if test $lt_ac_count -gt $lt_ac_max; then
       lt_ac_max=$lt_ac_count
       lt_cv_path_SED=$lt_ac_sed
     fi
@@ -8296,7 +7792,27 @@ dnl AC_DEFUN([LT_AC_PROG_SED], [])
 # Find out whether the shell is Bourne or XSI compatible,
 # or has some other useful features.
 m4_defun([_LT_CHECK_SHELL_FEATURES],
-[if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then
+[AC_MSG_CHECKING([whether the shell understands some XSI constructs])
+# Try some XSI features
+xsi_shell=no
+( _lt_dummy="a/b/c"
+  test "${_lt_dummy##*/},${_lt_dummy%/*},${_lt_dummy#??}"${_lt_dummy%"$_lt_dummy"}, \
+      = c,a/b,b/c, \
+    && eval 'test $(( 1 + 1 )) -eq 2 \
+    && test "${#_lt_dummy}" -eq 5' ) >/dev/null 2>&1 \
+  && xsi_shell=yes
+AC_MSG_RESULT([$xsi_shell])
+_LT_CONFIG_LIBTOOL_INIT([xsi_shell='$xsi_shell'])
+
+AC_MSG_CHECKING([whether the shell understands "+="])
+lt_shell_append=no
+( foo=bar; set foo baz; eval "$[1]+=\$[2]" && test "$foo" = barbaz ) \
+    >/dev/null 2>&1 \
+  && lt_shell_append=yes
+AC_MSG_RESULT([$lt_shell_append])
+_LT_CONFIG_LIBTOOL_INIT([lt_shell_append='$lt_shell_append'])
+
+if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then
   lt_unset=unset
 else
   lt_unset=false
@@ -8320,9 +7836,102 @@ _LT_DECL([NL2SP], [lt_NL2SP], [1], [turn newlines into spaces])dnl
 ])# _LT_CHECK_SHELL_FEATURES
 
 
+# _LT_PROG_FUNCTION_REPLACE (FUNCNAME, REPLACEMENT-BODY)
+# ------------------------------------------------------
+# In `$cfgfile', look for function FUNCNAME delimited by `^FUNCNAME ()$' and
+# '^} FUNCNAME ', and replace its body with REPLACEMENT-BODY.
+m4_defun([_LT_PROG_FUNCTION_REPLACE],
+[dnl {
+sed -e '/^$1 ()$/,/^} # $1 /c\
+$1 ()\
+{\
+m4_bpatsubsts([$2], [$], [\\], [^\([	 ]\)], [\\\1])
+} # Extended-shell $1 implementation' "$cfgfile" > $cfgfile.tmp \
+  && mv -f "$cfgfile.tmp" "$cfgfile" \
+    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+])
+
+
+# _LT_PROG_REPLACE_SHELLFNS
+# -------------------------
+# Replace existing portable implementations of several shell functions with
+# equivalent extended shell implementations where those features are available..
+m4_defun([_LT_PROG_REPLACE_SHELLFNS],
+[if test x"$xsi_shell" = xyes; then
+  _LT_PROG_FUNCTION_REPLACE([func_dirname], [dnl
+    case ${1} in
+      */*) func_dirname_result="${1%/*}${2}" ;;
+      *  ) func_dirname_result="${3}" ;;
+    esac])
+
+  _LT_PROG_FUNCTION_REPLACE([func_basename], [dnl
+    func_basename_result="${1##*/}"])
+
+  _LT_PROG_FUNCTION_REPLACE([func_dirname_and_basename], [dnl
+    case ${1} in
+      */*) func_dirname_result="${1%/*}${2}" ;;
+      *  ) func_dirname_result="${3}" ;;
+    esac
+    func_basename_result="${1##*/}"])
+
+  _LT_PROG_FUNCTION_REPLACE([func_stripname], [dnl
+    # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are
+    # positional parameters, so assign one to ordinary parameter first.
+    func_stripname_result=${3}
+    func_stripname_result=${func_stripname_result#"${1}"}
+    func_stripname_result=${func_stripname_result%"${2}"}])
+
+  _LT_PROG_FUNCTION_REPLACE([func_split_long_opt], [dnl
+    func_split_long_opt_name=${1%%=*}
+    func_split_long_opt_arg=${1#*=}])
+
+  _LT_PROG_FUNCTION_REPLACE([func_split_short_opt], [dnl
+    func_split_short_opt_arg=${1#??}
+    func_split_short_opt_name=${1%"$func_split_short_opt_arg"}])
+
+  _LT_PROG_FUNCTION_REPLACE([func_lo2o], [dnl
+    case ${1} in
+      *.lo) func_lo2o_result=${1%.lo}.${objext} ;;
+      *)    func_lo2o_result=${1} ;;
+    esac])
+
+  _LT_PROG_FUNCTION_REPLACE([func_xform], [    func_xform_result=${1%.*}.lo])
+
+  _LT_PROG_FUNCTION_REPLACE([func_arith], [    func_arith_result=$(( $[*] ))])
+
+  _LT_PROG_FUNCTION_REPLACE([func_len], [    func_len_result=${#1}])
+fi
+
+if test x"$lt_shell_append" = xyes; then
+  _LT_PROG_FUNCTION_REPLACE([func_append], [    eval "${1}+=\\${2}"])
+
+  _LT_PROG_FUNCTION_REPLACE([func_append_quoted], [dnl
+    func_quote_for_eval "${2}"
+dnl m4 expansion turns \\\\ into \\, and then the shell eval turns that into \
+    eval "${1}+=\\\\ \\$func_quote_for_eval_result"])
+
+  # Save a `func_append' function call where possible by direct use of '+='
+  sed -e 's%func_append \([[a-zA-Z_]]\{1,\}\) "%\1+="%g' $cfgfile > $cfgfile.tmp \
+    && mv -f "$cfgfile.tmp" "$cfgfile" \
+      || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+  test 0 -eq $? || _lt_function_replace_fail=:
+else
+  # Save a `func_append' function call even when '+=' is not available
+  sed -e 's%func_append \([[a-zA-Z_]]\{1,\}\) "%\1="$\1%g' $cfgfile > $cfgfile.tmp \
+    && mv -f "$cfgfile.tmp" "$cfgfile" \
+      || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+  test 0 -eq $? || _lt_function_replace_fail=:
+fi
+
+if test x"$_lt_function_replace_fail" = x":"; then
+  AC_MSG_WARN([Unable to substitute extended shell functions in $ofile])
+fi
+])
+
 # _LT_PATH_CONVERSION_FUNCTIONS
 # -----------------------------
-# Determine what file name conversion functions should be used by
+# Determine which file name conversion functions should be used by
 # func_to_host_file (and, implicitly, by func_to_host_path).  These are needed
 # for certain cross-compile configurations and native mingw.
 m4_defun([_LT_PATH_CONVERSION_FUNCTIONS],
diff --git a/src/gmock/gtest/m4/ltoptions.m4 b/src/gmock/gtest/m4/ltoptions.m4
index 94b0829..5d9acd8 100644
--- a/src/gmock/gtest/m4/ltoptions.m4
+++ b/src/gmock/gtest/m4/ltoptions.m4
@@ -1,14 +1,14 @@
 # Helper functions for option handling.                    -*- Autoconf -*-
 #
-#   Copyright (C) 2004-2005, 2007-2009, 2011-2015 Free Software
-#   Foundation, Inc.
+#   Copyright (C) 2004, 2005, 2007, 2008, 2009 Free Software Foundation,
+#   Inc.
 #   Written by Gary V. Vaughan, 2004
 #
 # This file is free software; the Free Software Foundation gives
 # unlimited permission to copy and/or distribute it, with or without
 # modifications, as long as this notice is preserved.
 
-# serial 8 ltoptions.m4
+# serial 7 ltoptions.m4
 
 # This is to help aclocal find these macros, as it can't see m4_define.
 AC_DEFUN([LTOPTIONS_VERSION], [m4_if([1])])
@@ -29,7 +29,7 @@ m4_define([_LT_SET_OPTION],
 [m4_define(_LT_MANGLE_OPTION([$1], [$2]))dnl
 m4_ifdef(_LT_MANGLE_DEFUN([$1], [$2]),
         _LT_MANGLE_DEFUN([$1], [$2]),
-    [m4_warning([Unknown $1 option '$2'])])[]dnl
+    [m4_warning([Unknown $1 option `$2'])])[]dnl
 ])
 
 
@@ -75,15 +75,13 @@ m4_if([$1],[LT_INIT],[
   dnl
   dnl If no reference was made to various pairs of opposing options, then
   dnl we run the default mode handler for the pair.  For example, if neither
-  dnl 'shared' nor 'disable-shared' was passed, we enable building of shared
+  dnl `shared' nor `disable-shared' was passed, we enable building of shared
   dnl archives by default:
   _LT_UNLESS_OPTIONS([LT_INIT], [shared disable-shared], [_LT_ENABLE_SHARED])
   _LT_UNLESS_OPTIONS([LT_INIT], [static disable-static], [_LT_ENABLE_STATIC])
   _LT_UNLESS_OPTIONS([LT_INIT], [pic-only no-pic], [_LT_WITH_PIC])
   _LT_UNLESS_OPTIONS([LT_INIT], [fast-install disable-fast-install],
-		   [_LT_ENABLE_FAST_INSTALL])
-  _LT_UNLESS_OPTIONS([LT_INIT], [aix-soname=aix aix-soname=both aix-soname=svr4],
-		   [_LT_WITH_AIX_SONAME([aix])])
+  		   [_LT_ENABLE_FAST_INSTALL])
   ])
 ])# _LT_SET_OPTIONS
 
@@ -114,7 +112,7 @@ AU_DEFUN([AC_LIBTOOL_DLOPEN],
 [_LT_SET_OPTION([LT_INIT], [dlopen])
 AC_DIAGNOSE([obsolete],
 [$0: Remove this warning and the call to _LT_SET_OPTION when you
-put the 'dlopen' option into LT_INIT's first parameter.])
+put the `dlopen' option into LT_INIT's first parameter.])
 ])
 
 dnl aclocal-1.4 backwards compatibility:
@@ -150,7 +148,7 @@ AU_DEFUN([AC_LIBTOOL_WIN32_DLL],
 _LT_SET_OPTION([LT_INIT], [win32-dll])
 AC_DIAGNOSE([obsolete],
 [$0: Remove this warning and the call to _LT_SET_OPTION when you
-put the 'win32-dll' option into LT_INIT's first parameter.])
+put the `win32-dll' option into LT_INIT's first parameter.])
 ])
 
 dnl aclocal-1.4 backwards compatibility:
@@ -159,9 +157,9 @@ dnl AC_DEFUN([AC_LIBTOOL_WIN32_DLL], [])
 
 # _LT_ENABLE_SHARED([DEFAULT])
 # ----------------------------
-# implement the --enable-shared flag, and supports the 'shared' and
-# 'disable-shared' LT_INIT options.
-# DEFAULT is either 'yes' or 'no'.  If omitted, it defaults to 'yes'.
+# implement the --enable-shared flag, and supports the `shared' and
+# `disable-shared' LT_INIT options.
+# DEFAULT is either `yes' or `no'.  If omitted, it defaults to `yes'.
 m4_define([_LT_ENABLE_SHARED],
 [m4_define([_LT_ENABLE_SHARED_DEFAULT], [m4_if($1, no, no, yes)])dnl
 AC_ARG_ENABLE([shared],
@@ -174,14 +172,14 @@ AC_ARG_ENABLE([shared],
     *)
       enable_shared=no
       # Look at the argument we got.  We use all the common list separators.
-      lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR,
+      lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
       for pkg in $enableval; do
-	IFS=$lt_save_ifs
+	IFS="$lt_save_ifs"
 	if test "X$pkg" = "X$p"; then
 	  enable_shared=yes
 	fi
       done
-      IFS=$lt_save_ifs
+      IFS="$lt_save_ifs"
       ;;
     esac],
     [enable_shared=]_LT_ENABLE_SHARED_DEFAULT)
@@ -213,9 +211,9 @@ dnl AC_DEFUN([AM_DISABLE_SHARED], [])
 
 # _LT_ENABLE_STATIC([DEFAULT])
 # ----------------------------
-# implement the --enable-static flag, and support the 'static' and
-# 'disable-static' LT_INIT options.
-# DEFAULT is either 'yes' or 'no'.  If omitted, it defaults to 'yes'.
+# implement the --enable-static flag, and support the `static' and
+# `disable-static' LT_INIT options.
+# DEFAULT is either `yes' or `no'.  If omitted, it defaults to `yes'.
 m4_define([_LT_ENABLE_STATIC],
 [m4_define([_LT_ENABLE_STATIC_DEFAULT], [m4_if($1, no, no, yes)])dnl
 AC_ARG_ENABLE([static],
@@ -228,14 +226,14 @@ AC_ARG_ENABLE([static],
     *)
      enable_static=no
       # Look at the argument we got.  We use all the common list separators.
-      lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR,
+      lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
       for pkg in $enableval; do
-	IFS=$lt_save_ifs
+	IFS="$lt_save_ifs"
 	if test "X$pkg" = "X$p"; then
 	  enable_static=yes
 	fi
       done
-      IFS=$lt_save_ifs
+      IFS="$lt_save_ifs"
       ;;
     esac],
     [enable_static=]_LT_ENABLE_STATIC_DEFAULT)
@@ -267,9 +265,9 @@ dnl AC_DEFUN([AM_DISABLE_STATIC], [])
 
 # _LT_ENABLE_FAST_INSTALL([DEFAULT])
 # ----------------------------------
-# implement the --enable-fast-install flag, and support the 'fast-install'
-# and 'disable-fast-install' LT_INIT options.
-# DEFAULT is either 'yes' or 'no'.  If omitted, it defaults to 'yes'.
+# implement the --enable-fast-install flag, and support the `fast-install'
+# and `disable-fast-install' LT_INIT options.
+# DEFAULT is either `yes' or `no'.  If omitted, it defaults to `yes'.
 m4_define([_LT_ENABLE_FAST_INSTALL],
 [m4_define([_LT_ENABLE_FAST_INSTALL_DEFAULT], [m4_if($1, no, no, yes)])dnl
 AC_ARG_ENABLE([fast-install],
@@ -282,14 +280,14 @@ AC_ARG_ENABLE([fast-install],
     *)
       enable_fast_install=no
       # Look at the argument we got.  We use all the common list separators.
-      lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR,
+      lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
       for pkg in $enableval; do
-	IFS=$lt_save_ifs
+	IFS="$lt_save_ifs"
 	if test "X$pkg" = "X$p"; then
 	  enable_fast_install=yes
 	fi
       done
-      IFS=$lt_save_ifs
+      IFS="$lt_save_ifs"
       ;;
     esac],
     [enable_fast_install=]_LT_ENABLE_FAST_INSTALL_DEFAULT)
@@ -306,14 +304,14 @@ AU_DEFUN([AC_ENABLE_FAST_INSTALL],
 [_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[fast-install])
 AC_DIAGNOSE([obsolete],
 [$0: Remove this warning and the call to _LT_SET_OPTION when you put
-the 'fast-install' option into LT_INIT's first parameter.])
+the `fast-install' option into LT_INIT's first parameter.])
 ])
 
 AU_DEFUN([AC_DISABLE_FAST_INSTALL],
 [_LT_SET_OPTION([LT_INIT], [disable-fast-install])
 AC_DIAGNOSE([obsolete],
 [$0: Remove this warning and the call to _LT_SET_OPTION when you put
-the 'disable-fast-install' option into LT_INIT's first parameter.])
+the `disable-fast-install' option into LT_INIT's first parameter.])
 ])
 
 dnl aclocal-1.4 backwards compatibility:
@@ -321,64 +319,11 @@ dnl AC_DEFUN([AC_ENABLE_FAST_INSTALL], [])
 dnl AC_DEFUN([AM_DISABLE_FAST_INSTALL], [])
 
 
-# _LT_WITH_AIX_SONAME([DEFAULT])
-# ----------------------------------
-# implement the --with-aix-soname flag, and support the `aix-soname=aix'
-# and `aix-soname=both' and `aix-soname=svr4' LT_INIT options. DEFAULT
-# is either `aix', `both' or `svr4'.  If omitted, it defaults to `aix'.
-m4_define([_LT_WITH_AIX_SONAME],
-[m4_define([_LT_WITH_AIX_SONAME_DEFAULT], [m4_if($1, svr4, svr4, m4_if($1, both, both, aix))])dnl
-shared_archive_member_spec=
-case $host,$enable_shared in
-power*-*-aix[[5-9]]*,yes)
-  AC_MSG_CHECKING([which variant of shared library versioning to provide])
-  AC_ARG_WITH([aix-soname],
-    [AS_HELP_STRING([--with-aix-soname=aix|svr4|both],
-      [shared library versioning (aka "SONAME") variant to provide on AIX, @<:@default=]_LT_WITH_AIX_SONAME_DEFAULT[@:>@.])],
-    [case $withval in
-    aix|svr4|both)
-      ;;
-    *)
-      AC_MSG_ERROR([Unknown argument to --with-aix-soname])
-      ;;
-    esac
-    lt_cv_with_aix_soname=$with_aix_soname],
-    [AC_CACHE_VAL([lt_cv_with_aix_soname],
-      [lt_cv_with_aix_soname=]_LT_WITH_AIX_SONAME_DEFAULT)
-    with_aix_soname=$lt_cv_with_aix_soname])
-  AC_MSG_RESULT([$with_aix_soname])
-  if test aix != "$with_aix_soname"; then
-    # For the AIX way of multilib, we name the shared archive member
-    # based on the bitwidth used, traditionally 'shr.o' or 'shr_64.o',
-    # and 'shr.imp' or 'shr_64.imp', respectively, for the Import File.
-    # Even when GNU compilers ignore OBJECT_MODE but need '-maix64' flag,
-    # the AIX toolchain works better with OBJECT_MODE set (default 32).
-    if test 64 = "${OBJECT_MODE-32}"; then
-      shared_archive_member_spec=shr_64
-    else
-      shared_archive_member_spec=shr
-    fi
-  fi
-  ;;
-*)
-  with_aix_soname=aix
-  ;;
-esac
-
-_LT_DECL([], [shared_archive_member_spec], [0],
-    [Shared archive member basename, for filename based shared library versioning on AIX])dnl
-])# _LT_WITH_AIX_SONAME
-
-LT_OPTION_DEFINE([LT_INIT], [aix-soname=aix], [_LT_WITH_AIX_SONAME([aix])])
-LT_OPTION_DEFINE([LT_INIT], [aix-soname=both], [_LT_WITH_AIX_SONAME([both])])
-LT_OPTION_DEFINE([LT_INIT], [aix-soname=svr4], [_LT_WITH_AIX_SONAME([svr4])])
-
-
 # _LT_WITH_PIC([MODE])
 # --------------------
-# implement the --with-pic flag, and support the 'pic-only' and 'no-pic'
+# implement the --with-pic flag, and support the `pic-only' and `no-pic'
 # LT_INIT options.
-# MODE is either 'yes' or 'no'.  If omitted, it defaults to 'both'.
+# MODE is either `yes' or `no'.  If omitted, it defaults to `both'.
 m4_define([_LT_WITH_PIC],
 [AC_ARG_WITH([pic],
     [AS_HELP_STRING([--with-pic@<:@=PKGS@:>@],
@@ -389,17 +334,19 @@ m4_define([_LT_WITH_PIC],
     *)
       pic_mode=default
       # Look at the argument we got.  We use all the common list separators.
-      lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR,
+      lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
       for lt_pkg in $withval; do
-	IFS=$lt_save_ifs
+	IFS="$lt_save_ifs"
 	if test "X$lt_pkg" = "X$lt_p"; then
 	  pic_mode=yes
 	fi
       done
-      IFS=$lt_save_ifs
+      IFS="$lt_save_ifs"
       ;;
     esac],
-    [pic_mode=m4_default([$1], [default])])
+    [pic_mode=default])
+
+test -z "$pic_mode" && pic_mode=m4_default([$1], [default])
 
 _LT_DECL([], [pic_mode], [0], [What type of objects to build])dnl
 ])# _LT_WITH_PIC
@@ -412,7 +359,7 @@ AU_DEFUN([AC_LIBTOOL_PICMODE],
 [_LT_SET_OPTION([LT_INIT], [pic-only])
 AC_DIAGNOSE([obsolete],
 [$0: Remove this warning and the call to _LT_SET_OPTION when you
-put the 'pic-only' option into LT_INIT's first parameter.])
+put the `pic-only' option into LT_INIT's first parameter.])
 ])
 
 dnl aclocal-1.4 backwards compatibility:
diff --git a/src/gmock/gtest/m4/ltsugar.m4 b/src/gmock/gtest/m4/ltsugar.m4
index 48bc934..9000a05 100644
--- a/src/gmock/gtest/m4/ltsugar.m4
+++ b/src/gmock/gtest/m4/ltsugar.m4
@@ -1,7 +1,6 @@
 # ltsugar.m4 -- libtool m4 base layer.                         -*-Autoconf-*-
 #
-# Copyright (C) 2004-2005, 2007-2008, 2011-2015 Free Software
-# Foundation, Inc.
+# Copyright (C) 2004, 2005, 2007, 2008 Free Software Foundation, Inc.
 # Written by Gary V. Vaughan, 2004
 #
 # This file is free software; the Free Software Foundation gives
@@ -34,7 +33,7 @@ m4_define([_lt_join],
 # ------------
 # Manipulate m4 lists.
 # These macros are necessary as long as will still need to support
-# Autoconf-2.59, which quotes differently.
+# Autoconf-2.59 which quotes differently.
 m4_define([lt_car], [[$1]])
 m4_define([lt_cdr],
 [m4_if([$#], 0, [m4_fatal([$0: cannot be called without arguments])],
@@ -45,7 +44,7 @@ m4_define([lt_unquote], $1)
 
 # lt_append(MACRO-NAME, STRING, [SEPARATOR])
 # ------------------------------------------
-# Redefine MACRO-NAME to hold its former content plus 'SEPARATOR''STRING'.
+# Redefine MACRO-NAME to hold its former content plus `SEPARATOR'`STRING'.
 # Note that neither SEPARATOR nor STRING are expanded; they are appended
 # to MACRO-NAME as is (leaving the expansion for when MACRO-NAME is invoked).
 # No SEPARATOR is output if MACRO-NAME was previously undefined (different
diff --git a/src/gmock/gtest/m4/ltversion.m4 b/src/gmock/gtest/m4/ltversion.m4
index fa04b52..07a8602 100644
--- a/src/gmock/gtest/m4/ltversion.m4
+++ b/src/gmock/gtest/m4/ltversion.m4
@@ -1,6 +1,6 @@
 # ltversion.m4 -- version numbers			-*- Autoconf -*-
 #
-#   Copyright (C) 2004, 2011-2015 Free Software Foundation, Inc.
+#   Copyright (C) 2004 Free Software Foundation, Inc.
 #   Written by Scott James Remnant, 2004
 #
 # This file is free software; the Free Software Foundation gives
@@ -9,15 +9,15 @@
 
 # @configure_input@
 
-# serial 4179 ltversion.m4
+# serial 3337 ltversion.m4
 # This file is part of GNU Libtool
 
-m4_define([LT_PACKAGE_VERSION], [2.4.6])
-m4_define([LT_PACKAGE_REVISION], [2.4.6])
+m4_define([LT_PACKAGE_VERSION], [2.4.2])
+m4_define([LT_PACKAGE_REVISION], [1.3337])
 
 AC_DEFUN([LTVERSION_VERSION],
-[macro_version='2.4.6'
-macro_revision='2.4.6'
+[macro_version='2.4.2'
+macro_revision='1.3337'
 _LT_DECL(, macro_version, 0, [Which release of libtool.m4 was used?])
 _LT_DECL(, macro_revision, 0)
 ])
diff --git a/src/gmock/gtest/m4/lt~obsolete.m4 b/src/gmock/gtest/m4/lt~obsolete.m4
index c6b26f8..c573da9 100644
--- a/src/gmock/gtest/m4/lt~obsolete.m4
+++ b/src/gmock/gtest/m4/lt~obsolete.m4
@@ -1,7 +1,6 @@
 # lt~obsolete.m4 -- aclocal satisfying obsolete definitions.    -*-Autoconf-*-
 #
-#   Copyright (C) 2004-2005, 2007, 2009, 2011-2015 Free Software
-#   Foundation, Inc.
+#   Copyright (C) 2004, 2005, 2007, 2009 Free Software Foundation, Inc.
 #   Written by Scott James Remnant, 2004.
 #
 # This file is free software; the Free Software Foundation gives
@@ -12,7 +11,7 @@
 
 # These exist entirely to fool aclocal when bootstrapping libtool.
 #
-# In the past libtool.m4 has provided macros via AC_DEFUN (or AU_DEFUN),
+# In the past libtool.m4 has provided macros via AC_DEFUN (or AU_DEFUN)
 # which have later been changed to m4_define as they aren't part of the
 # exported API, or moved to Autoconf or Automake where they belong.
 #
@@ -26,7 +25,7 @@
 # included after everything else.  This provides aclocal with the
 # AC_DEFUNs it wants, but when m4 processes it, it doesn't do anything
 # because those macros already exist, or will be overwritten later.
-# We use AC_DEFUN over AU_DEFUN for compatibility with aclocal-1.6.
+# We use AC_DEFUN over AU_DEFUN for compatibility with aclocal-1.6. 
 #
 # Anytime we withdraw an AC_DEFUN or AU_DEFUN, remember to add it here.
 # Yes, that means every name once taken will need to remain here until
diff --git a/src/include/CompatSet.h b/src/include/CompatSet.h
index d3afd40..43c1ec1 100644
--- a/src/include/CompatSet.h
+++ b/src/include/CompatSet.h
@@ -154,7 +154,7 @@ struct CompatSet {
    * -1: This CompatSet is missing at least one feature
    *     described in the other. It may still have more features, though.
    */
-  int compare(CompatSet& other) {
+  int compare(const CompatSet& other) {
     if ((other.compat.mask == compat.mask) &&
 	(other.ro_compat.mask == ro_compat.mask) &&
 	(other.incompat.mask == incompat.mask)) return 0;
diff --git a/src/include/Makefile.am b/src/include/Makefile.am
index 900a4c1..d17605f 100644
--- a/src/include/Makefile.am
+++ b/src/include/Makefile.am
@@ -14,6 +14,11 @@ rados_include_DATA = \
 	$(srcdir)/include/crc32c.h \
 	$(srcdir)/include/memory.h
 
+if WITH_RADOSGW
+rados_include_DATA += \
+	$(srcdir)/include/rados/librgw.h \
+	$(srcdir)/include/rados/rgw_file.h
+endif # WITH_RADOSGW
 
 if WITH_RBD
 librbd_includedir = $(includedir)/rbd
@@ -75,6 +80,7 @@ noinst_HEADERS += \
 	include/error.h \
 	include/filepath.h \
 	include/frag.h \
+	include/fs_types.h \
 	include/hash.h \
 	include/inline_memory.h \
 	include/intarith.h \
@@ -110,6 +116,7 @@ noinst_HEADERS += \
 	include/rados/crc32c.h \
 	include/rados/buffer.h \
 	include/rados/buffer_fwd.h \
+	include/rados/rgw_file.h \
 	include/radosstriper/libradosstriper.h \
 	include/radosstriper/libradosstriper.hpp \
 	include/rbd/features.h \
diff --git a/src/include/buffer.h b/src/include/buffer.h
index bc988db..1397ae9 100644
--- a/src/include/buffer.h
+++ b/src/include/buffer.h
@@ -57,8 +57,10 @@
 
 #if __GNUC__ >= 4
   #define CEPH_BUFFER_API  __attribute__ ((visibility ("default")))
+  #define CEPH_BUFFER_DETAILS __attribute__ ((visibility ("hidden")))
 #else
   #define CEPH_BUFFER_API
+  #define CEPH_BUFFER_DETAILS
 #endif
 
 #if defined(HAVE_XIO)
@@ -68,8 +70,6 @@ class XioDispatchHook;
 
 namespace ceph {
 
-const static int CEPH_BUFFER_APPEND_SIZE(4096);
-
 namespace buffer CEPH_BUFFER_API {
   /*
    * exceptions
@@ -134,6 +134,7 @@ namespace buffer CEPH_BUFFER_API {
   class raw_char;
   class raw_pipe;
   class raw_unshareable; // diagnostic, unshareable char buffer
+  class raw_combined;
 
 
   class xio_mempool;
@@ -201,7 +202,9 @@ namespace buffer CEPH_BUFFER_API {
       return (length() % align) == 0;
     }
     bool is_n_page_sized() const { return is_n_align_sized(CEPH_PAGE_SIZE); }
-    bool is_partial() const { return start() > 0 || end() < raw_length(); }
+    bool is_partial() const {
+      return have_raw() && (start() > 0 || end() < raw_length());
+    }
 
     // accessors
     raw *get_raw() const { return _raw; }
@@ -262,8 +265,13 @@ namespace buffer CEPH_BUFFER_API {
     unsigned _memcopy_count; //the total of memcopy using rebuild().
     ptr append_buffer;  // where i put small appends.
 
+  public:
+    class iterator;
+
+  private:
     template <bool is_const>
-    class iterator_impl: public std::iterator<std::forward_iterator_tag, char> {
+    class CEPH_BUFFER_DETAILS iterator_impl
+      : public std::iterator<std::forward_iterator_tag, char> {
     protected:
       typedef typename std::conditional<is_const,
 					const list,
@@ -279,17 +287,16 @@ namespace buffer CEPH_BUFFER_API {
       unsigned off; // in bl
       list_iter_t p;
       unsigned p_off;   // in *p
+      friend class iterator_impl<true>;
 
     public:
       // constructor.  position.
       iterator_impl()
 	: bl(0), ls(0), off(0), p_off(0) {}
-      iterator_impl(bl_t *l, unsigned o=0)
-	: bl(l), ls(&bl->_buffers), off(0), p(ls->begin()), p_off(0) {
-	advance(o);
-      }
+      iterator_impl(bl_t *l, unsigned o=0);
       iterator_impl(bl_t *l, unsigned o, list_iter_t ip, unsigned po)
 	: bl(l), ls(&bl->_buffers), off(o), p(ip), p_off(po) {}
+      iterator_impl(const list::iterator& i);
 
       /// get current iterator offset in buffer::list
       unsigned get_off() const { return off; }
@@ -305,12 +312,11 @@ namespace buffer CEPH_BUFFER_API {
 
       void advance(int o);
       void seek(unsigned o);
-      bool operator!=(const iterator_impl& rhs) const;
       char operator*() const;
       iterator_impl& operator++();
       ptr get_current_ptr() const;
 
-      bl_t& get_bl() { return *bl; }
+      bl_t& get_bl() const { return *bl; }
 
       // copy data out.
       // note that these all _append_ to dest!
@@ -319,6 +325,15 @@ namespace buffer CEPH_BUFFER_API {
       void copy(unsigned len, list &dest);
       void copy(unsigned len, std::string &dest);
       void copy_all(list &dest);
+
+      friend bool operator==(const iterator_impl& lhs,
+			     const iterator_impl& rhs) {
+	return &lhs.get_bl() == &rhs.get_bl() && lhs.get_off() == rhs.get_off();
+      }
+      friend bool operator!=(const iterator_impl& lhs,
+			     const iterator_impl& rhs) {
+	return &lhs.get_bl() != &rhs.get_bl() || lhs.get_off() != rhs.get_off();
+      }
     };
 
   public:
@@ -326,11 +341,9 @@ namespace buffer CEPH_BUFFER_API {
 
     class CEPH_BUFFER_API iterator : public iterator_impl<false> {
     public:
-      iterator(): iterator_impl() {}
-      iterator(bl_t *l, unsigned o=0) :
-	iterator_impl(l, o) {}
-      iterator(bl_t *l, unsigned o, list_iter_t ip, unsigned po) :
-	iterator_impl(l, o, ip, po) {}
+      iterator() = default;
+      iterator(bl_t *l, unsigned o=0);
+      iterator(bl_t *l, unsigned o, list_iter_t ip, unsigned po);
 
       void advance(int o);
       void seek(unsigned o);
@@ -349,6 +362,13 @@ namespace buffer CEPH_BUFFER_API {
       void copy_in(unsigned len, const char *src);
       void copy_in(unsigned len, const char *src, bool crc_reset);
       void copy_in(unsigned len, const list& otherl);
+
+      bool operator==(const iterator& rhs) const {
+	return bl == rhs.bl && off == rhs.off;
+      }
+      bool operator!=(const iterator& rhs) const {
+	return bl != rhs.bl || off != rhs.off;
+      }
     };
 
   private:
@@ -388,6 +408,10 @@ namespace buffer CEPH_BUFFER_API {
       return *this;
     }
 
+    unsigned get_num_buffers() const { return _buffers.size(); }
+    const ptr& front() const { return _buffers.front(); }
+    const ptr& back() const { return _buffers.back(); }
+
     unsigned get_memcopy_count() const {return _memcopy_count; }
     const std::list<ptr>& buffers() const { return _buffers; }
     void swap(list& other);
@@ -409,6 +433,7 @@ namespace buffer CEPH_BUFFER_API {
     bool contents_equal(const buffer::list& other) const;
 
     bool can_zero_copy() const;
+    bool is_provided_buffer(const char *dst) const;
     bool is_aligned(unsigned align) const;
     bool is_page_aligned() const;
     bool is_n_align_sized(unsigned align) const;
@@ -554,6 +579,7 @@ namespace buffer CEPH_BUFFER_API {
     int read_fd_zero_copy(int fd, size_t len);
     int write_file(const char *fn, int mode=0644);
     int write_fd(int fd) const;
+    int write_fd(int fd, uint64_t offset) const;
     int write_fd_zero_copy(int fd) const;
     void prepare_iov(std::vector<iovec> *piov) const;
     uint32_t crc32c(uint32_t crc) const;
@@ -628,6 +654,7 @@ inline bufferhash& operator<<(bufferhash& l, bufferlist &r) {
   l.update(r);
   return l;
 }
+
 }
 
 #if defined(HAVE_XIO)
diff --git a/src/include/ceph_features.h b/src/include/ceph_features.h
index c15d2af..9756746 100755
--- a/src/include/ceph_features.h
+++ b/src/include/ceph_features.h
@@ -3,10 +3,16 @@
 
 /*
  * feature bits
+ *
+ * Feature reuse:
+ * Features marked DEPRECATED: <release> are advertized, but not checked in
+ * <release>
+ * Feature bit values marked as UNUSED are not referenced or checked by any
+ * versions we could be talking to and can be reused.
  */
 #define CEPH_FEATURE_UID            (1ULL<<0)
 #define CEPH_FEATURE_NOSRCADDR      (1ULL<<1)
-#define CEPH_FEATURE_MONCLOCKCHECK  (1ULL<<2)
+#define DEPRECATED_CEPH_FEATURE_MONCLOCKCHECK  (1ULL<<2) // DEPRECATED: JEWEL
 #define CEPH_FEATURE_FLOCK          (1ULL<<3)
 #define CEPH_FEATURE_SUBSCRIBE2     (1ULL<<4)
 #define CEPH_FEATURE_MONNAMES       (1ULL<<5)
@@ -18,27 +24,27 @@
 #define CEPH_FEATURE_PGPOOL3        (1ULL<<11)
 #define CEPH_FEATURE_OSDREPLYMUX    (1ULL<<12)
 #define CEPH_FEATURE_OSDENC         (1ULL<<13)
-#define CEPH_FEATURE_OMAP           (1ULL<<14)
+// UNUSED: (1ULL<<14)
 #define CEPH_FEATURE_MONENC         (1ULL<<15)
-#define CEPH_FEATURE_QUERY_T        (1ULL<<16)
-#define CEPH_FEATURE_INDEP_PG_MAP   (1ULL<<17)
+#define DEPRECATED_CEPH_FEATURE_QUERY_T        (1ULL<<16) // DEPRECATED: JEWEL
+#define DEPRECATED_CEPH_FEATURE_INDEP_PG_MAP   (1ULL<<17) // DEPRECATED: JEWEL
 #define CEPH_FEATURE_CRUSH_TUNABLES (1ULL<<18)
-#define CEPH_FEATURE_CHUNKY_SCRUB   (1ULL<<19)
-#define CEPH_FEATURE_MON_NULLROUTE  (1ULL<<20)
-#define CEPH_FEATURE_MON_GV         (1ULL<<21)
-#define CEPH_FEATURE_BACKFILL_RESERVATION (1ULL<<22)
+#define DEPRECATED_CEPH_FEATURE_CHUNKY_SCRUB (1ULL<<19) // DEPRECATED: JEWEL
+#define DEPRECATED_CEPH_FEATURE_MON_NULLROUTE  (1ULL<<20) // DEPRECATED: JEWEL
+// UNUSED: (1ULL<<21)
+#define DEPRECATED_CEPH_FEATURE_BACKFILL_RESERVATION (1ULL<<22) // DEPRECATED: JEWEL
 #define CEPH_FEATURE_MSG_AUTH	    (1ULL<<23)
-#define CEPH_FEATURE_RECOVERY_RESERVATION (1ULL<<24)
+#define DEPRECATED_CEPH_FEATURE_RECOVERY_RESERVATION (1ULL<<24) // DEPRECATED: JEWEL
 #define CEPH_FEATURE_CRUSH_TUNABLES2 (1ULL<<25)
 #define CEPH_FEATURE_CREATEPOOLID   (1ULL<<26)
 #define CEPH_FEATURE_REPLY_CREATE_INODE   (1ULL<<27)
-#define CEPH_FEATURE_OSD_HBMSGS     (1ULL<<28)
+// UNUSED: (1ULL<<28)
 #define CEPH_FEATURE_MDSENC         (1ULL<<29)
 #define CEPH_FEATURE_OSDHASHPSPOOL  (1ULL<<30)
 #define CEPH_FEATURE_MON_SINGLE_PAXOS (1ULL<<31)
-#define CEPH_FEATURE_OSD_SNAPMAPPER (1ULL<<32)
-#define CEPH_FEATURE_MON_SCRUB      (1ULL<<33)
-#define CEPH_FEATURE_OSD_PACKED_RECOVERY (1ULL<<34)
+#define DEPRECATED_CEPH_FEATURE_OSD_SNAPMAPPER (1ULL<<32) // DEPRECATED: JEWEL
+#define DEPRECATED_CEPH_FEATURE_MON_SCRUB      (1ULL<<33)
+#define DEPRECATED_CEPH_FEATURE_OSD_PACKED_RECOVERY (1ULL<<34) // DEPRECATED: JEWEL
 #define CEPH_FEATURE_OSD_CACHEPOOL (1ULL<<35)
 #define CEPH_FEATURE_CRUSH_V2      (1ULL<<36)  /* new indep; SET_* steps */
 #define CEPH_FEATURE_EXPORT_PEER   (1ULL<<37)
@@ -53,16 +59,16 @@
 #define CEPH_FEATURE_MSGR_KEEPALIVE2   (1ULL<<42)
 #define CEPH_FEATURE_OSD_POOLRESEND    (1ULL<<43)
 #define CEPH_FEATURE_ERASURE_CODE_PLUGINS_V2 (1ULL<<44)
-#define CEPH_FEATURE_OSD_SET_ALLOC_HINT (1ULL<<45)
+#define DEPRECATED_CEPH_FEATURE_OSD_SET_ALLOC_HINT (1ULL<<45) // DEPRECATED: JEWEL
 #define CEPH_FEATURE_OSD_FADVISE_FLAGS (1ULL<<46)
-#define CEPH_FEATURE_OSD_REPOP         (1ULL<<46)   /* overlap with fadvise */
-#define CEPH_FEATURE_OSD_OBJECT_DIGEST  (1ULL<<46)  /* overlap with fadvise */
-#define CEPH_FEATURE_OSD_TRANSACTION_MAY_LAYOUT (1ULL<<46) /* overlap w/ fadvise */
+#define DEPRECATED_CEPH_FEATURE_OSD_REPOP         (1ULL<<46) // DEPRECATED: JEWEL (can't remove until all 1<<46 are ready)
+#define DEPRECATED_CEPH_FEATURE_OSD_OBJECT_DIGEST  (1ULL<<46) // DEPRECATED: JEWEL (can't remove until all 1<<46 are ready)
+#define DEPRECATED_CEPH_FEATURE_OSD_TRANSACTION_MAY_LAYOUT (1ULL<<46) // DEPRECATED: JEWEL (can't remove until all 1<<46 are ready)
 #define CEPH_FEATURE_MDS_QUOTA      (1ULL<<47)
 #define CEPH_FEATURE_CRUSH_V4      (1ULL<<48)  /* straw2 buckets */
-#define CEPH_FEATURE_OSD_MIN_SIZE_RECOVERY (1ULL<<49)
+#define DEPRECATED_CEPH_FEATURE_OSD_MIN_SIZE_RECOVERY (1ULL<<49) // DEPRECATED: JEWEL (can't remove until all 1<<49 are ready)
 // duplicated since it was introduced at the same time as MIN_SIZE_RECOVERY
-#define CEPH_FEATURE_OSD_PROXY_FEATURES (1ULL<<49)  /* overlap w/ above */
+#define DEPRECATED_CEPH_FEATURE_OSD_PROXY_FEATURES (1ULL<<49)  /* overlap w/ above */
 #define CEPH_FEATURE_MON_METADATA (1ULL<<50)
 #define CEPH_FEATURE_OSD_BITWISE_HOBJ_SORT (1ULL<<51) /* can sort objs bitwise */
 #define CEPH_FEATURE_OSD_PROXY_WRITE_FEATURES (1ULL<<52)
@@ -73,9 +79,11 @@
 #define CEPH_FEATURE_MON_STATEFUL_SUB (1ULL<<57) /* stateful mon subscription */
 #define CEPH_FEATURE_MON_ROUTE_OSDMAP (1ULL<<57) /* peon sends osdmaps */
 #define CEPH_FEATURE_OSDSUBOP_NO_SNAPCONTEXT (1ULL<<57) /* overlap, drop unused SnapContext in v12 */
+#define CEPH_FEATURE_SERVER_JEWEL (1ULL<<57)   /* overlap, features introduced in jewel */
 #define CEPH_FEATURE_CRUSH_TUNABLES5	(1ULL<<58) /* chooseleaf stable mode */
 // duplicated since it was introduced at the same time as CEPH_FEATURE_CRUSH_TUNABLES5
-#define CEPH_FEATURE_NEW_OSDOPREPLY_ENCODING   (1ULL<<58) /* New, v7 encoding */
+#define CEPH_FEATURE_NEW_OSDOPREPLY_ENCODING (1ULL<<58) /* New, v7 encoding */
+#define CEPH_FEATURE_FS_FILE_LAYOUT_V2       (1ULL<<58) /* file_layout_t */
 
 #define CEPH_FEATURE_RESERVED2 (1ULL<<61)  /* slow down, we are almost out... */
 #define CEPH_FEATURE_RESERVED  (1ULL<<62)  /* DO NOT USE THIS ... last bit! */
@@ -109,7 +117,7 @@ static inline unsigned long long ceph_sanitize_features(unsigned long long f) {
 #define CEPH_FEATURES_ALL		 \
 	(CEPH_FEATURE_UID |		 \
 	 CEPH_FEATURE_NOSRCADDR |	 \
-	 CEPH_FEATURE_MONCLOCKCHECK |	 \
+	 DEPRECATED_CEPH_FEATURE_MONCLOCKCHECK |	 \
 	 CEPH_FEATURE_FLOCK |		 \
 	 CEPH_FEATURE_SUBSCRIBE2 |	 \
 	 CEPH_FEATURE_MONNAMES |	 \
@@ -121,29 +129,26 @@ static inline unsigned long long ceph_sanitize_features(unsigned long long f) {
 	 CEPH_FEATURE_PGPOOL3 |		 \
 	 CEPH_FEATURE_OSDREPLYMUX |	 \
 	 CEPH_FEATURE_OSDENC |		 \
-	 CEPH_FEATURE_OMAP |		 \
-	 CEPH_FEATURE_QUERY_T |		 \
+	 DEPRECATED_CEPH_FEATURE_QUERY_T |		 \
 	 CEPH_FEATURE_MONENC |		 \
-	 CEPH_FEATURE_INDEP_PG_MAP |	 \
+	 DEPRECATED_CEPH_FEATURE_INDEP_PG_MAP |	 \
 	 CEPH_FEATURE_CRUSH_TUNABLES |	 \
-	 CEPH_FEATURE_CHUNKY_SCRUB |	 \
-	 CEPH_FEATURE_MON_NULLROUTE |	 \
-	 CEPH_FEATURE_MON_GV |		 \
-	 CEPH_FEATURE_BACKFILL_RESERVATION | \
+	 DEPRECATED_CEPH_FEATURE_CHUNKY_SCRUB | \
+	 DEPRECATED_CEPH_FEATURE_MON_NULLROUTE |	 \
+	 DEPRECATED_CEPH_FEATURE_BACKFILL_RESERVATION | \
 	 CEPH_FEATURE_MSG_AUTH |	     \
-	 CEPH_FEATURE_RECOVERY_RESERVATION | \
+	 DEPRECATED_CEPH_FEATURE_RECOVERY_RESERVATION | \
 	 CEPH_FEATURE_CRUSH_TUNABLES2 |	     \
 	 CEPH_FEATURE_CREATEPOOLID |	     \
 	 CEPH_FEATURE_REPLY_CREATE_INODE |   \
-	 CEPH_FEATURE_OSD_HBMSGS |		\
 	 CEPH_FEATURE_MDSENC |			\
 	 CEPH_FEATURE_OSDHASHPSPOOL |       \
 	 CEPH_FEATURE_NEW_OSDOP_ENCODING |        \
          CEPH_FEATURE_NEW_OSDOPREPLY_ENCODING | \
 	 CEPH_FEATURE_MON_SINGLE_PAXOS |    \
-	 CEPH_FEATURE_OSD_SNAPMAPPER |	    \
-	 CEPH_FEATURE_MON_SCRUB	|	    \
-	 CEPH_FEATURE_OSD_PACKED_RECOVERY | \
+	 DEPRECATED_CEPH_FEATURE_OSD_SNAPMAPPER |	    \
+	 DEPRECATED_CEPH_FEATURE_MON_SCRUB	|	    \
+	 DEPRECATED_CEPH_FEATURE_OSD_PACKED_RECOVERY | \
 	 CEPH_FEATURE_OSD_CACHEPOOL |	    \
 	 CEPH_FEATURE_CRUSH_V2 |	    \
 	 CEPH_FEATURE_EXPORT_PEER |	    \
@@ -155,14 +160,14 @@ static inline unsigned long long ceph_sanitize_features(unsigned long long f) {
 	 CEPH_FEATURE_MSGR_KEEPALIVE2 |	\
 	 CEPH_FEATURE_OSD_POOLRESEND |	\
          CEPH_FEATURE_ERASURE_CODE_PLUGINS_V2 |   \
-         CEPH_FEATURE_OSD_SET_ALLOC_HINT |   \
+         DEPRECATED_CEPH_FEATURE_OSD_SET_ALLOC_HINT |   \
 	 CEPH_FEATURE_OSD_FADVISE_FLAGS |     \
-         CEPH_FEATURE_OSD_REPOP |   \
-	 CEPH_FEATURE_OSD_OBJECT_DIGEST	|    \
-         CEPH_FEATURE_OSD_TRANSACTION_MAY_LAYOUT |   \
+         DEPRECATED_CEPH_FEATURE_OSD_REPOP |   \
+	 DEPRECATED_CEPH_FEATURE_OSD_OBJECT_DIGEST	|    \
+         DEPRECATED_CEPH_FEATURE_OSD_TRANSACTION_MAY_LAYOUT |   \
 	 CEPH_FEATURE_MDS_QUOTA | \
          CEPH_FEATURE_CRUSH_V4 |	     \
-         CEPH_FEATURE_OSD_MIN_SIZE_RECOVERY |		 \
+         DEPRECATED_CEPH_FEATURE_OSD_MIN_SIZE_RECOVERY |		 \
 	 CEPH_FEATURE_MON_METADATA |			 \
 	 CEPH_FEATURE_OSD_BITWISE_HOBJ_SORT |		 \
          CEPH_FEATURE_ERASURE_CODE_PLUGINS_V3 |   \
@@ -172,6 +177,8 @@ static inline unsigned long long ceph_sanitize_features(unsigned long long f) {
 	 CEPH_FEATURE_MON_STATEFUL_SUB |	 \
 	 CEPH_FEATURE_MON_ROUTE_OSDMAP |	 \
 	 CEPH_FEATURE_CRUSH_TUNABLES5 |	    \
+	 CEPH_FEATURE_SERVER_JEWEL |  \
+	 CEPH_FEATURE_FS_FILE_LAYOUT_V2 |		 \
 	 0ULL)
 
 #define CEPH_FEATURES_SUPPORTED_DEFAULT  CEPH_FEATURES_ALL
diff --git a/src/include/ceph_fs.h b/src/include/ceph_fs.h
index af49a78..47e6a0b 100644
--- a/src/include/ceph_fs.h
+++ b/src/include/ceph_fs.h
@@ -131,6 +131,9 @@ struct ceph_dir_layout {
 #define CEPH_MSG_OSD_OPREPLY            43
 #define CEPH_MSG_WATCH_NOTIFY           44
 
+/* FSMap subscribers (see all MDS clusters at once) */
+#define CEPH_MSG_FS_MAP                 45
+
 
 /* watch-notify operations */
 enum {
@@ -353,9 +356,10 @@ enum {
 	// internal op
 	CEPH_MDS_OP_FRAGMENTDIR= 0x01500,
 	CEPH_MDS_OP_EXPORTDIR  = 0x01501,
-	CEPH_MDS_OP_VALIDATE   = 0x01502,
-	CEPH_MDS_OP_FLUSH      = 0x01503,
-	CEPH_MDS_OP_ENQUEUE_SCRUB = 0x01504
+	CEPH_MDS_OP_FLUSH      = 0x01502,
+	CEPH_MDS_OP_ENQUEUE_SCRUB  = 0x01503,
+	CEPH_MDS_OP_REPAIR_FRAGSTATS = 0x01504,
+	CEPH_MDS_OP_REPAIR_INODESTATS = 0x01505
 };
 
 extern const char *ceph_mds_op_name(int op);
@@ -489,27 +493,6 @@ struct ceph_mds_reply_cap {
 #define CEPH_CAP_FLAG_AUTH	(1 << 0)	/* cap is issued by auth mds */
 #define CEPH_CAP_FLAG_RELEASE	(1 << 1)        /* ask client to release the cap */
 
-/* inode record, for bundling with mds reply */
-struct ceph_mds_reply_inode {
-	__le64 ino;
-	__le64 snapid;
-	__le32 rdev;
-	__le64 version;                /* inode version */
-	__le64 xattr_version;          /* version for xattr blob */
-	struct ceph_mds_reply_cap cap; /* caps issued for this inode */
-	struct ceph_file_layout layout;
-	struct ceph_timespec ctime, mtime, atime;
-	__le32 time_warp_seq;
-	__le64 size, max_size, truncate_size;
-	__le32 truncate_seq;
-	__le32 mode, uid, gid;
-	__le32 nlink;
-	__le64 files, subdirs, rbytes, rfiles, rsubdirs;  /* dir stats */
-	struct ceph_timespec rctime;
-	struct ceph_frag_tree_head fragtree;  /* (must be at end of struct) */
-} __attribute__ ((packed));
-/* followed by frag array, symlink string, dir layout, xattr blob */
-
 /* reply_lease follows dname, and reply_inode */
 struct ceph_mds_reply_lease {
 	__le16 mask;            /* lease type(s) */
@@ -676,7 +659,7 @@ struct ceph_mds_cap_peer {
 /*
  * caps message, used for capability callbacks, acks, requests, etc.
  */
-struct ceph_mds_caps {
+struct ceph_mds_caps_head {
 	__le32 op;                  /* CEPH_CAP_OP_* */
 	__le64 ino, realm;
 	__le64 cap_id;
@@ -695,7 +678,9 @@ struct ceph_mds_caps {
 	/* xattrlock */
 	__le32 xattr_len;
 	__le64 xattr_version;
+} __attribute__ ((packed));
 
+struct ceph_mds_caps_body_legacy {
 	union {
 		/* all except export */
 		struct {
diff --git a/src/include/compact_map.h b/src/include/compact_map.h
index a530c27..12ba8b3 100644
--- a/src/include/compact_map.h
+++ b/src/include/compact_map.h
@@ -284,6 +284,12 @@ public:
     else
       ::encode((uint32_t)0, bl);
   }
+  void encode(bufferlist &bl, uint64_t features) const {
+    if (map)
+      ::encode(*map, bl, features);
+    else
+      ::encode((uint32_t)0, bl);
+  }
   void decode(bufferlist::iterator& p) {
     uint32_t n;
     ::decode(n, p);
@@ -300,6 +306,11 @@ inline void encode(const compact_map_base<Key, T, Map>& m, bufferlist& bl) {
   m.encode(bl);
 }
 template<class Key, class T, class Map>
+inline void encode(const compact_map_base<Key, T, Map>& m, bufferlist& bl,
+		   uint64_t features) {
+  m.encode(bl, features);
+}
+template<class Key, class T, class Map>
 inline void decode(compact_map_base<Key, T, Map>& m, bufferlist::iterator& p) {
   m.decode(p);
 }
diff --git a/src/include/encoding.h b/src/include/encoding.h
index 3ba5327..2657c62 100644
--- a/src/include/encoding.h
+++ b/src/include/encoding.h
@@ -233,8 +233,8 @@ inline void decode(buffer::ptr& bp, bufferlist::iterator& p)
   p.copy(len, s);
 
   if (len) {
-    if (s.buffers().size() == 1)
-      bp = s.buffers().front();
+    if (s.get_num_buffers() == 1)
+      bp = s.front();
     else
       bp = buffer::copy(s.c_str(), s.length());
   }
@@ -368,24 +368,10 @@ inline void decode(std::pair<A,B> &pa, bufferlist::iterator &p)
 template<class T>
 inline void encode(const std::list<T>& ls, bufferlist& bl)
 {
-  // should i pre- or post- count?
-  if (!ls.empty()) {
-    unsigned pos = bl.length();
-    unsigned n = 0;
-    encode(n, bl);
-    for (typename std::list<T>::const_iterator p = ls.begin(); p != ls.end(); ++p) {
-      n++;
-      encode(*p, bl);
-    }
-    ceph_le32 en;
-    en = n;
-    bl.copy_in(pos, sizeof(en), (char*)&en);
-  } else {
-    __u32 n = (__u32)(ls.size());    // FIXME: this is slow on a list.
-    encode(n, bl);
-    for (typename std::list<T>::const_iterator p = ls.begin(); p != ls.end(); ++p)
-      encode(*p, bl);
-  }
+  __u32 n = (__u32)(ls.size());  // c++11 std::list::size() is O(1)
+  encode(n, bl);
+  for (typename std::list<T>::const_iterator p = ls.begin(); p != ls.end(); ++p)
+    encode(*p, bl);
 }
 template<class T>
 inline void decode(std::list<T>& ls, bufferlist::iterator& p)
@@ -403,24 +389,18 @@ inline void decode(std::list<T>& ls, bufferlist::iterator& p)
 template<class T>
 inline void encode(const std::list<ceph::shared_ptr<T> >& ls, bufferlist& bl)
 {
-  // should i pre- or post- count?
-  if (!ls.empty()) {
-    unsigned pos = bl.length();
-    unsigned n = 0;
-    encode(n, bl);
-    for (typename std::list<ceph::shared_ptr<T> >::const_iterator p = ls.begin(); p != ls.end(); ++p) {
-      n++;
-      encode(**p, bl);
-    }
-    ceph_le32 en;
-    en = n;
-    bl.copy_in(pos, sizeof(en), (char*)&en);
-  } else {
-    __u32 n = (__u32)(ls.size());    // FIXME: this is slow on a list.
-    encode(n, bl);
-    for (typename std::list<ceph::shared_ptr<T> >::const_iterator p = ls.begin(); p != ls.end(); ++p)
-      encode(**p, bl);
-  }
+  __u32 n = (__u32)(ls.size());  // c++11 std::list::size() is O(1)
+  encode(n, bl);
+  for (typename std::list<ceph::shared_ptr<T> >::const_iterator p = ls.begin(); p != ls.end(); ++p)
+    encode(**p, bl);
+}
+template<class T>
+inline void encode(const std::list<ceph::shared_ptr<T> >& ls, bufferlist& bl, uint64_t features)
+{
+  __u32 n = (__u32)(ls.size());  // c++11 std::list::size() is O(1)
+  encode(n, bl);
+  for (typename std::list<ceph::shared_ptr<T> >::const_iterator p = ls.begin(); p != ls.end(); ++p)
+    encode(**p, bl, features);
 }
 template<class T>
 inline void decode(std::list<ceph::shared_ptr<T> >& ls, bufferlist::iterator& p)
@@ -429,7 +409,7 @@ inline void decode(std::list<ceph::shared_ptr<T> >& ls, bufferlist::iterator& p)
   decode(n, p);
   ls.clear();
   while (n--) {
-    ceph::shared_ptr<T> v(new T);
+    ceph::shared_ptr<T> v(std::make_shared<T>());
     decode(*v, p);
     ls.push_back(v);
   }
@@ -595,7 +575,7 @@ inline void decode(std::vector<ceph::shared_ptr<T> >& v, bufferlist::iterator& p
   decode(n, p);
   v.resize(n);
   for (__u32 i=0; i<n; i++) {
-    v[i].reset(new T());
+    v[i] = std::make_shared<T>();
     decode(*v[i], p);
   }
 }
diff --git a/src/include/filepath.h b/src/include/filepath.h
index f731847..15c3783 100644
--- a/src/include/filepath.h
+++ b/src/include/filepath.h
@@ -31,6 +31,7 @@ using namespace std;
 #include "buffer.h"
 #include "encoding.h"
 #include "include/types.h"
+#include "include/fs_types.h"
 
 #include "common/Formatter.h"
 
diff --git a/src/include/fs_types.h b/src/include/fs_types.h
new file mode 100644
index 0000000..388508b
--- /dev/null
+++ b/src/include/fs_types.h
@@ -0,0 +1,106 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+#ifndef CEPH_INCLUDE_FS_TYPES_H
+#define CEPH_INCLUDE_FS_TYPES_H
+
+#include "types.h"
+#include "utime.h"
+
+// --------------------------------------
+// ino
+
+typedef uint64_t _inodeno_t;
+
+struct inodeno_t {
+  _inodeno_t val;
+  inodeno_t() : val(0) {}
+  // cppcheck-suppress noExplicitConstructor
+  inodeno_t(_inodeno_t v) : val(v) {}
+  inodeno_t operator+=(inodeno_t o) { val += o.val; return *this; }
+  operator _inodeno_t() const { return val; }
+
+  void encode(bufferlist& bl) const {
+    ::encode(val, bl);
+  }
+  void decode(bufferlist::iterator& p) {
+    ::decode(val, p);
+  }
+} __attribute__ ((__may_alias__));
+WRITE_CLASS_ENCODER(inodeno_t)
+
+inline ostream& operator<<(ostream& out, inodeno_t ino) {
+  return out << hex << ino.val << dec;
+}
+
+namespace std {
+  template<> struct hash< inodeno_t >
+  {
+    size_t operator()( const inodeno_t& x ) const
+    {
+      static rjhash<uint64_t> H;
+      return H(x.val);
+    }
+  };
+} // namespace std
+
+
+// file modes
+
+static inline bool file_mode_is_readonly(int mode) {
+  return (mode & CEPH_FILE_MODE_WR) == 0;
+}
+
+
+// dentries
+#define MAX_DENTRY_LEN 255
+
+// --
+namespace ceph {
+  class Formatter;
+}
+void dump(const ceph_file_layout& l, ceph::Formatter *f);
+void dump(const ceph_dir_layout& l, ceph::Formatter *f);
+
+
+
+// file_layout_t
+
+struct file_layout_t {
+  // file -> object mapping
+  uint32_t stripe_unit;   ///< stripe unit, in bytes,
+  uint32_t stripe_count;  ///< over this many objects
+  uint32_t object_size;   ///< until objects are this big
+
+  int64_t pool_id;        ///< rados pool id
+  string pool_ns;         ///< rados pool namespace
+
+  file_layout_t(uint32_t su=0, uint32_t sc=0, uint32_t os=0)
+    : stripe_unit(su),
+      stripe_count(sc),
+      object_size(os),
+      pool_id(-1) {
+  }
+
+  static file_layout_t get_default() {
+    return file_layout_t(1<<22, 1, 1<<22);
+  }
+
+  uint64_t get_period() const {
+    return stripe_count * object_size;
+  }
+
+  void from_legacy(const ceph_file_layout& fl);
+  void to_legacy(ceph_file_layout *fl) const;
+
+  bool is_valid() const;
+
+  void encode(bufferlist& bl, uint64_t features) const;
+  void decode(bufferlist::iterator& p);
+  void dump(Formatter *f) const;
+  static void generate_test_instances(list<file_layout_t*>& o);
+};
+WRITE_CLASS_ENCODER_FEATURES(file_layout_t)
+
+WRITE_EQ_OPERATORS_5(file_layout_t, stripe_unit, stripe_count, object_size, pool_id, pool_ns);
+
+#endif
diff --git a/src/include/object.h b/src/include/object.h
index bdc15b5..74a011b 100644
--- a/src/include/object.h
+++ b/src/include/object.h
@@ -89,7 +89,7 @@ namespace std {
 
 struct file_object_t {
   uint64_t ino, bno;
-  mutable char buf[33];
+  mutable char buf[34];
 
   file_object_t(uint64_t i=0, uint64_t b=0) : ino(i), bno(b) {
     buf[0] = 0;
@@ -97,7 +97,7 @@ struct file_object_t {
   
   const char *c_str() const {
     if (!buf[0])
-      sprintf(buf, "%llx.%08llx", (long long unsigned)ino, (long long unsigned)bno);
+      snprintf(buf, sizeof(buf), "%llx.%08llx", (long long unsigned)ino, (long long unsigned)bno);
     return buf;
   }
 
diff --git a/src/include/rados.h b/src/include/rados.h
index dde4d9e..f14d677 100644
--- a/src/include/rados.h
+++ b/src/include/rados.h
@@ -144,6 +144,7 @@ extern const char *ceph_osd_state_name(int s);
 #define CEPH_OSDMAP_NOTIERAGENT (1<<13) /* disable tiering agent */
 #define CEPH_OSDMAP_NOREBALANCE (1<<14) /* block osd backfill unless pg is degraded */
 #define CEPH_OSDMAP_SORTBITWISE (1<<15) /* use bitwise hobject_t sort */
+#define CEPH_OSDMAP_REQUIRE_JEWEL (1<<16) /* require jewel for booting osds */
 
 /*
  * The error code to return when an OSD can't handle a write
@@ -293,7 +294,8 @@ extern const char *ceph_osd_state_name(int s);
 	f(PG_HITSET_LS,	__CEPH_OSD_OP(RD, PG, 3),	"pg-hitset-ls")	    \
 	f(PG_HITSET_GET, __CEPH_OSD_OP(RD, PG, 4),	"pg-hitset-get")    \
 	f(PGNLS,	__CEPH_OSD_OP(RD, PG, 5),	"pgnls")	    \
-	f(PGNLS_FILTER,	__CEPH_OSD_OP(RD, PG, 6),	"pgnls-filter")
+	f(PGNLS_FILTER,	__CEPH_OSD_OP(RD, PG, 6),	"pgnls-filter")     \
+	f(SCRUBLS, __CEPH_OSD_OP(RD, PG, 7), "scrubls")
 
 enum {
 #define GENERATE_ENUM_ENTRY(op, opcode, str)	CEPH_OSD_OP_##op = (opcode),
diff --git a/src/include/rados/buffer.h b/src/include/rados/buffer.h
index bc988db..1397ae9 100644
--- a/src/include/rados/buffer.h
+++ b/src/include/rados/buffer.h
@@ -57,8 +57,10 @@
 
 #if __GNUC__ >= 4
   #define CEPH_BUFFER_API  __attribute__ ((visibility ("default")))
+  #define CEPH_BUFFER_DETAILS __attribute__ ((visibility ("hidden")))
 #else
   #define CEPH_BUFFER_API
+  #define CEPH_BUFFER_DETAILS
 #endif
 
 #if defined(HAVE_XIO)
@@ -68,8 +70,6 @@ class XioDispatchHook;
 
 namespace ceph {
 
-const static int CEPH_BUFFER_APPEND_SIZE(4096);
-
 namespace buffer CEPH_BUFFER_API {
   /*
    * exceptions
@@ -134,6 +134,7 @@ namespace buffer CEPH_BUFFER_API {
   class raw_char;
   class raw_pipe;
   class raw_unshareable; // diagnostic, unshareable char buffer
+  class raw_combined;
 
 
   class xio_mempool;
@@ -201,7 +202,9 @@ namespace buffer CEPH_BUFFER_API {
       return (length() % align) == 0;
     }
     bool is_n_page_sized() const { return is_n_align_sized(CEPH_PAGE_SIZE); }
-    bool is_partial() const { return start() > 0 || end() < raw_length(); }
+    bool is_partial() const {
+      return have_raw() && (start() > 0 || end() < raw_length());
+    }
 
     // accessors
     raw *get_raw() const { return _raw; }
@@ -262,8 +265,13 @@ namespace buffer CEPH_BUFFER_API {
     unsigned _memcopy_count; //the total of memcopy using rebuild().
     ptr append_buffer;  // where i put small appends.
 
+  public:
+    class iterator;
+
+  private:
     template <bool is_const>
-    class iterator_impl: public std::iterator<std::forward_iterator_tag, char> {
+    class CEPH_BUFFER_DETAILS iterator_impl
+      : public std::iterator<std::forward_iterator_tag, char> {
     protected:
       typedef typename std::conditional<is_const,
 					const list,
@@ -279,17 +287,16 @@ namespace buffer CEPH_BUFFER_API {
       unsigned off; // in bl
       list_iter_t p;
       unsigned p_off;   // in *p
+      friend class iterator_impl<true>;
 
     public:
       // constructor.  position.
       iterator_impl()
 	: bl(0), ls(0), off(0), p_off(0) {}
-      iterator_impl(bl_t *l, unsigned o=0)
-	: bl(l), ls(&bl->_buffers), off(0), p(ls->begin()), p_off(0) {
-	advance(o);
-      }
+      iterator_impl(bl_t *l, unsigned o=0);
       iterator_impl(bl_t *l, unsigned o, list_iter_t ip, unsigned po)
 	: bl(l), ls(&bl->_buffers), off(o), p(ip), p_off(po) {}
+      iterator_impl(const list::iterator& i);
 
       /// get current iterator offset in buffer::list
       unsigned get_off() const { return off; }
@@ -305,12 +312,11 @@ namespace buffer CEPH_BUFFER_API {
 
       void advance(int o);
       void seek(unsigned o);
-      bool operator!=(const iterator_impl& rhs) const;
       char operator*() const;
       iterator_impl& operator++();
       ptr get_current_ptr() const;
 
-      bl_t& get_bl() { return *bl; }
+      bl_t& get_bl() const { return *bl; }
 
       // copy data out.
       // note that these all _append_ to dest!
@@ -319,6 +325,15 @@ namespace buffer CEPH_BUFFER_API {
       void copy(unsigned len, list &dest);
       void copy(unsigned len, std::string &dest);
       void copy_all(list &dest);
+
+      friend bool operator==(const iterator_impl& lhs,
+			     const iterator_impl& rhs) {
+	return &lhs.get_bl() == &rhs.get_bl() && lhs.get_off() == rhs.get_off();
+      }
+      friend bool operator!=(const iterator_impl& lhs,
+			     const iterator_impl& rhs) {
+	return &lhs.get_bl() != &rhs.get_bl() || lhs.get_off() != rhs.get_off();
+      }
     };
 
   public:
@@ -326,11 +341,9 @@ namespace buffer CEPH_BUFFER_API {
 
     class CEPH_BUFFER_API iterator : public iterator_impl<false> {
     public:
-      iterator(): iterator_impl() {}
-      iterator(bl_t *l, unsigned o=0) :
-	iterator_impl(l, o) {}
-      iterator(bl_t *l, unsigned o, list_iter_t ip, unsigned po) :
-	iterator_impl(l, o, ip, po) {}
+      iterator() = default;
+      iterator(bl_t *l, unsigned o=0);
+      iterator(bl_t *l, unsigned o, list_iter_t ip, unsigned po);
 
       void advance(int o);
       void seek(unsigned o);
@@ -349,6 +362,13 @@ namespace buffer CEPH_BUFFER_API {
       void copy_in(unsigned len, const char *src);
       void copy_in(unsigned len, const char *src, bool crc_reset);
       void copy_in(unsigned len, const list& otherl);
+
+      bool operator==(const iterator& rhs) const {
+	return bl == rhs.bl && off == rhs.off;
+      }
+      bool operator!=(const iterator& rhs) const {
+	return bl != rhs.bl || off != rhs.off;
+      }
     };
 
   private:
@@ -388,6 +408,10 @@ namespace buffer CEPH_BUFFER_API {
       return *this;
     }
 
+    unsigned get_num_buffers() const { return _buffers.size(); }
+    const ptr& front() const { return _buffers.front(); }
+    const ptr& back() const { return _buffers.back(); }
+
     unsigned get_memcopy_count() const {return _memcopy_count; }
     const std::list<ptr>& buffers() const { return _buffers; }
     void swap(list& other);
@@ -409,6 +433,7 @@ namespace buffer CEPH_BUFFER_API {
     bool contents_equal(const buffer::list& other) const;
 
     bool can_zero_copy() const;
+    bool is_provided_buffer(const char *dst) const;
     bool is_aligned(unsigned align) const;
     bool is_page_aligned() const;
     bool is_n_align_sized(unsigned align) const;
@@ -554,6 +579,7 @@ namespace buffer CEPH_BUFFER_API {
     int read_fd_zero_copy(int fd, size_t len);
     int write_file(const char *fn, int mode=0644);
     int write_fd(int fd) const;
+    int write_fd(int fd, uint64_t offset) const;
     int write_fd_zero_copy(int fd) const;
     void prepare_iov(std::vector<iovec> *piov) const;
     uint32_t crc32c(uint32_t crc) const;
@@ -628,6 +654,7 @@ inline bufferhash& operator<<(bufferhash& l, bufferlist &r) {
   l.update(r);
   return l;
 }
+
 }
 
 #if defined(HAVE_XIO)
diff --git a/src/include/rados/librados.h b/src/include/rados/librados.h
index e9b5c91..44373ff 100644
--- a/src/include/rados/librados.h
+++ b/src/include/rados/librados.h
@@ -615,6 +615,25 @@ CEPH_RADOS_API int rados_wait_for_latest_osdmap(rados_t cluster);
 CEPH_RADOS_API int rados_pool_list(rados_t cluster, char *buf, size_t len);
 
 /**
+ * List inconsistent placement groups of the given pool
+ *
+ * Gets a list of inconsistent placement groups as NULL-terminated strings.
+ * The placement group names will be placed in the supplied buffer one after
+ * another. After the last name, there will be two 0 types in a row.
+ *
+ * If len is too short to fit all the placement group entries we need, we  will
+ * fill as much as we can.
+ *
+ * @param cluster cluster handle
+ * @param pool pool ID
+ * @param buf output buffer
+ * @param len output buffer length
+ * @returns length of the buffer we would need to list all pools
+ */
+CEPH_RADOS_API int rados_inconsistent_pg_list(rados_t cluster, int64_t pool,
+					      char *buf, size_t len);
+
+/**
  * Get a configuration handle for a rados cluster handle
  *
  * This handle is valid only as long as the cluster handle is valid.
@@ -994,6 +1013,8 @@ CEPH_RADOS_API int rados_object_list(rados_ioctx_t io,
     const rados_object_list_cursor start,
     const rados_object_list_cursor finish,
     const size_t result_size,
+    const char *filter_buf,
+    const size_t filter_buf_len,
     rados_object_list_item *results,
     rados_object_list_cursor *next);
 
@@ -2086,6 +2107,34 @@ CEPH_RADOS_API int rados_watch2(rados_ioctx_t io, const char *o, uint64_t *cooki
 				void *arg);
 
 /**
+ * Asynchronous register an interest in an object
+ *
+ * A watch operation registers the client as being interested in
+ * notifications on an object. OSDs keep track of watches on
+ * persistent storage, so they are preserved across cluster changes by
+ * the normal recovery process. If the client loses its connection to
+ * the primary OSD for a watched object, the watch will be removed
+ * after 30 seconds. Watches are automatically reestablished when a new
+ * connection is made, or a placement group switches OSDs.
+ *
+ * @note BUG: watch timeout should be configurable
+ *
+ * @param io the pool the object is in
+ * @param o the object to watch
+ * @param completion what to do when operation has been attempted
+ * @param handle where to store the internal id assigned to this watch
+ * @param watchcb what to do when a notify is received on this object
+ * @param watcherrcb what to do when the watch session encounters an error
+ * @param arg opaque value to pass to the callback
+ * @returns 0 on success, negative error code on failure
+ */
+CEPH_RADOS_API int rados_aio_watch(rados_ioctx_t io, const char *o,
+				   rados_completion_t completion, uint64_t *handle,
+				   rados_watchcb2_t watchcb,
+				   rados_watcherrcb_t watcherrcb,
+				   void *arg);
+
+/**
  * Check on the status of a watch
  *
  * Return the number of milliseconds since the watch was last confirmed.
@@ -2128,6 +2177,20 @@ CEPH_RADOS_API int rados_unwatch(rados_ioctx_t io, const char *o, uint64_t cooki
 CEPH_RADOS_API int rados_unwatch2(rados_ioctx_t io, uint64_t cookie);
 
 /**
+ * Asynchronous unregister an interest in an object
+ *
+ * Once this completes, no more notifies will be sent to us for this
+ * watch. This should be called to clean up unneeded watchers.
+ *
+ * @param io the pool the object is in
+ * @param completion what to do when operation has been attempted
+ * @param cookie which watch to unregister
+ * @returns 0 on success, negative error code on failure
+ */
+CEPH_RADOS_API int rados_aio_unwatch(rados_ioctx_t io, uint64_t cookie,
+                                     rados_completion_t completion);
+
+/**
  * Sychronously notify watchers of an object
  *
  * This blocks until all watchers of the object have received and
@@ -2231,6 +2294,21 @@ CEPH_RADOS_API int rados_notify_ack(rados_ioctx_t io, const char *o,
  * @param cluster the cluster handle
  */
 CEPH_RADOS_API int rados_watch_flush(rados_t cluster);
+/**
+ * Flush watch/notify callbacks
+ *
+ * This call will be nonblock, and the completion will be called
+ * until all pending watch/notify callbacks have been executed and
+ * the queue is empty.  It should usually be called after shutting
+ * down any watches before shutting down the ioctx or
+ * librados to ensure that any callbacks do not misuse the ioctx (for
+ * example by calling rados_notify_ack after the ioctx has been
+ * destroyed).
+ *
+ * @param cluster the cluster handle
+ * @param completion what to do when operation has been attempted
+ */
+CEPH_RADOS_API int rados_aio_watch_flush(rados_t cluster, rados_completion_t completion);
 
 /** @} Watch/Notify */
 
@@ -2541,6 +2619,21 @@ CEPH_RADOS_API int rados_write_op_operate(rados_write_op_t write_op,
 			                  time_t *mtime,
 			                  int flags);
 /**
+ * Perform a write operation synchronously
+ * @param write_op operation to perform
+ * @param io the ioctx that the object is in
+ * @param oid the object id
+ * @param mtime the time to set the mtime to, NULL for the current time
+ * @param flags flags to apply to the entire operation (LIBRADOS_OPERATION_*)
+ */
+
+CEPH_RADOS_API int rados_write_op_operate2(rados_write_op_t write_op,
+                                           rados_ioctx_t io,
+                                           const char *oid,
+                                           struct timespec *mtime,
+                                           int flags);
+
+/**
  * Perform a write operation asynchronously
  * @param write_op operation to perform
  * @param io the ioctx that the object is in
diff --git a/src/include/rados/librados.hpp b/src/include/rados/librados.hpp
index 1287c77..8450f22 100644
--- a/src/include/rados/librados.hpp
+++ b/src/include/rados/librados.hpp
@@ -355,14 +355,13 @@ namespace librados
   class CEPH_RADOS_API ObjectWriteOperation : public ObjectOperation
   {
   protected:
-    time_t *pmtime;
+    time_t *unused;
   public:
-    ObjectWriteOperation() : pmtime(NULL) {}
+    ObjectWriteOperation() : unused(NULL) {}
     ~ObjectWriteOperation() {}
 
-    void mtime(time_t *pt) {
-      pmtime = pt;
-    }
+    void mtime(time_t *pt);
+    void mtime2(struct timespec *pts);
 
     void create(bool exclusive);
     void create(bool exclusive,
@@ -474,6 +473,7 @@ namespace librados
     ~ObjectReadOperation() {}
 
     void stat(uint64_t *psize, time_t *pmtime, int *prval);
+    void stat2(uint64_t *psize, struct timespec *pts, int *prval);
     void getxattr(const char *name, bufferlist *pbl, int *prval);
     void getxattrs(std::map<std::string, bufferlist> *pattrs, int *prval);
     void read(size_t off, uint64_t len, bufferlist *pbl, int *prval);
@@ -697,6 +697,7 @@ namespace librados
     int setxattr(const std::string& oid, const char *name, bufferlist& bl);
     int rmxattr(const std::string& oid, const char *name);
     int stat(const std::string& oid, uint64_t *psize, time_t *pmtime);
+    int stat2(const std::string& oid, uint64_t *psize, struct timespec *pts);
     int exec(const std::string& oid, const char *cls, const char *method,
 	     bufferlist& inbl, bufferlist& outbl);
     /**
@@ -818,6 +819,7 @@ namespace librados
     bool object_list_is_end(const ObjectCursor &oc);
     int object_list(const ObjectCursor &start, const ObjectCursor &finish,
                     const size_t result_count,
+                    const bufferlist &filter,
                     std::vector<ObjectItem> *result,
                     ObjectCursor *next);
     void object_list_slice(
@@ -940,6 +942,7 @@ namespace librados
     int aio_flush_async(AioCompletion *c);
 
     int aio_stat(const std::string& oid, AioCompletion *c, uint64_t *psize, time_t *pmtime);
+    int aio_stat2(const std::string& oid, AioCompletion *c, uint64_t *psize, struct timespec *pts);
 
     /**
      * Cancel aio operation
@@ -989,7 +992,10 @@ namespace librados
     // watch/notify
     int watch2(const std::string& o, uint64_t *handle,
 	       librados::WatchCtx2 *ctx);
+    int aio_watch(const std::string& o, AioCompletion *c, uint64_t *handle,
+	       librados::WatchCtx2 *ctx);
     int unwatch2(uint64_t handle);
+    int aio_unwatch(uint64_t handle, AioCompletion *c);
     /**
      * Send a notify event ot watchers
      *
@@ -1113,6 +1119,17 @@ namespace librados
     IoCtxImpl *io_ctx_impl;
   };
 
+  struct PlacementGroupImpl;
+  struct CEPH_RADOS_API PlacementGroup {
+    PlacementGroup();
+    PlacementGroup(const PlacementGroup&);
+    ~PlacementGroup();
+    bool parse(const char*);
+    std::unique_ptr<PlacementGroupImpl> impl;
+  };
+
+  CEPH_RADOS_API std::ostream& operator<<(std::ostream&, const PlacementGroup&);
+
   class CEPH_RADOS_API Rados
   {
   public:
@@ -1130,6 +1147,7 @@ namespace librados
     int connect();
     void shutdown();
     int watch_flush();
+    int aio_watch_flush(AioCompletion*);
     int conf_read_file(const char * const path) const;
     int conf_parse_argv(int argc, const char ** argv) const;
     int conf_parse_argv_remainder(int argc, const char ** argv,
@@ -1180,6 +1198,51 @@ namespace librados
     int cluster_stat(cluster_stat_t& result);
     int cluster_fsid(std::string *fsid);
 
+    /**
+     * List inconsistent placement groups in the given pool
+     *
+     * @param pool_id the pool id
+     * @param pgs [out] the inconsistent PGs
+     */
+    int get_inconsistent_pgs(int64_t pool_id,
+                             std::vector<PlacementGroup>* pgs);
+    /**
+     * List the inconsistent objects found in a given PG by last scrub
+     *
+     * @param pg the placement group returned by @c pg_list()
+     * @param start_after the first returned @c objects
+     * @param max_return the max number of the returned @c objects
+     * @param c what to do when the operation is complete and safe
+     * @param objects [out] the objects where inconsistencies are found
+     * @param interval [in,out] an epoch indicating current interval
+     * @returns if a non-zero @c interval is specified, will return -EAGAIN i
+     *          the current interval begin epoch is different.
+     */
+    int get_inconsistent_objects(const PlacementGroup& pg,
+                                 const object_id_t &start_after,
+                                 unsigned max_return,
+                                 AioCompletion *c,
+                                 std::vector<inconsistent_obj_t>* objects,
+                                 uint32_t* interval);
+    /**
+     * List the inconsistent snapsets found in a given PG by last scrub
+     *
+     * @param pg the placement group returned by @c pg_list()
+     * @param start_after the first returned @c objects
+     * @param max_return the max number of the returned @c objects
+     * @param c what to do when the operation is complete and safe
+     * @param snapsets [out] the objects where inconsistencies are found
+     * @param interval [in,out] an epoch indicating current interval
+     * @returns if a non-zero @c interval is specified, will return -EAGAIN i
+     *          the current interval begin epoch is different.
+     */
+    int get_inconsistent_snapsets(const PlacementGroup& pg,
+                                  const object_id_t &start_after,
+                                  unsigned max_return,
+                                  AioCompletion *c,
+                                  std::vector<inconsistent_snapset_t>* snapset,
+                                  uint32_t* interval);
+
     /// get/wait for the most recent osdmap
     int wait_for_latest_osdmap();
 
diff --git a/src/include/rados/librgw.h b/src/include/rados/librgw.h
index cc2d6bd..9ba8f3a 100644
--- a/src/include/rados/librgw.h
+++ b/src/include/rados/librgw.h
@@ -11,7 +11,6 @@
  * Foundation.  See file COPYING.
  *
  */
-
 #ifndef CEPH_LIBRGW_H
 #define CEPH_LIBRGW_H
 
@@ -19,17 +18,12 @@
 extern "C" {
 #endif
 
-class CephContext;
-typedef CephContext* librgw_t;
-int librgw_create(librgw_t *rgw, const char * const id);
-int librgw_acl_bin2xml(librgw_t rgw, const char *bin, int bin_len, char **xml);
-void librgw_free_xml(librgw_t rgw, char *xml);
-int librgw_acl_xml2bin(librgw_t rgw, const char *xml, char **bin, int *bin_len);
-void librgw_free_bin(librgw_t rgw, char *bin);
+typedef void* librgw_t;
+int librgw_create(librgw_t *rgw, int argc, char **argv);
 void librgw_shutdown(librgw_t rgw);
 
 #ifdef __cplusplus
 }
 #endif
 
-#endif
+#endif /* CEPH_LIBRGW_H */
diff --git a/src/include/rados/rados_types.hpp b/src/include/rados/rados_types.hpp
index f70d521..d10e5f5 100644
--- a/src/include/rados/rados_types.hpp
+++ b/src/include/rados/rados_types.hpp
@@ -1,11 +1,13 @@
 #ifndef CEPH_RADOS_TYPES_HPP
 #define CEPH_RADOS_TYPES_HPP
 
+#include <map>
 #include <utility>
 #include <vector>
 #include <stdint.h>
 #include <string>
 
+#include "buffer.h"
 #include "rados_types.h"
 
 namespace librados {
@@ -31,6 +33,133 @@ struct snap_set_t {
   snap_set_t() : seq(0) {}
 };
 
+struct object_id_t {
+  std::string name;
+  std::string nspace;
+  std::string locator;
+  snap_t snap = 0;
+  object_id_t() = default;
+  object_id_t(const std::string& name,
+              const std::string& nspace,
+              const std::string& locator,
+              snap_t snap)
+    : name(name),
+      nspace(nspace),
+      locator(locator),
+      snap(snap)
+  {}
+};
+
+struct err_t {
+  enum {
+    SHARD_MISSING        = 1 << 1,
+    SHARD_STAT_ERR       = 1 << 2,
+    SHARD_READ_ERR       = 1 << 3,
+    DATA_DIGEST_MISMATCH = 1 << 4,
+    OMAP_DIGEST_MISMATCH = 1 << 5,
+    SIZE_MISMATCH        = 1 << 6,
+    ATTR_MISMATCH        = 1 << 7,
+    SNAPSET_MISSING      = 1 << 8,
+    DATA_DIGEST_MISMATCH_OI = 1 << 9,
+    OMAP_DIGEST_MISMATCH_OI = 1 << 10,
+    SIZE_MISMATCH_OI        = 1 << 11,
+  };
+  uint64_t errors = 0;
+  bool has_shard_missing() const {
+    return errors & SHARD_MISSING;
+  }
+  bool has_stat_error() const {
+    return errors & SHARD_STAT_ERR;
+  }
+  bool has_read_error() const {
+    return errors & SHARD_READ_ERR;
+  }
+  bool has_data_digest_mismatch() const {
+    return errors & DATA_DIGEST_MISMATCH;
+  }
+  bool has_omap_digest_mismatch() const {
+    return errors & OMAP_DIGEST_MISMATCH;
+  }
+  // deep error
+  bool has_data_digest_mismatch_oi() const {
+    return errors & DATA_DIGEST_MISMATCH_OI;
+  }
+  // deep error
+  bool has_omap_digest_mismatch_oi() const {
+    return errors & OMAP_DIGEST_MISMATCH_OI;
+  }
+  bool has_size_mismatch() const {
+    return errors & SIZE_MISMATCH;
+  }
+  bool has_size_mismatch_oi() const {
+    return errors & SIZE_MISMATCH_OI;
+  }
+  bool has_attr_mismatch() const {
+    return errors & ATTR_MISMATCH;
+  }
+};
+
+struct shard_info_t : err_t {
+  std::map<std::string, ceph::bufferlist> attrs;
+  uint64_t size = -1;
+  bool omap_digest_present = false;
+  uint32_t omap_digest = 0;
+  bool data_digest_present = false;
+  uint32_t data_digest = 0;
+};
+
+struct inconsistent_obj_t : err_t {
+  inconsistent_obj_t() = default;
+  inconsistent_obj_t(const object_id_t& object)
+    : object{object}
+  {}
+  object_id_t object;
+  // osd => shard_info
+  std::map<int32_t, shard_info_t> shards;
+};
+
+struct inconsistent_snapset_t {
+  inconsistent_snapset_t() = default;
+  inconsistent_snapset_t(const object_id_t& head)
+    : object{head}
+  {}
+  enum {
+    ATTR_MISSING   = 1 << 0,
+    ATTR_CORRUPTED = 1 << 1,
+    CLONE_MISSING  = 1 << 2,
+    SNAP_MISMATCH  = 1 << 3,
+    HEAD_MISMATCH  = 1 << 4,
+    HEADLESS_CLONE = 1 << 5,
+    SIZE_MISMATCH  = 1 << 6,
+  };
+  uint64_t errors = 0;
+  object_id_t object;
+  std::vector<snap_t> clones;
+  std::vector<snap_t> missing;
+
+  bool ss_attr_missing() const {
+    return errors & ATTR_MISSING;
+  }
+  bool ss_attr_corrupted() const {
+    return errors & ATTR_CORRUPTED;
+  }
+  bool clone_missing() const  {
+    return errors & CLONE_MISSING;
+  }
+  bool snapset_mismatch() const {
+    return errors & SNAP_MISMATCH;
+  }
+  bool head_mismatch() const {
+    return errors & HEAD_MISMATCH;
+  }
+  bool headless() const {
+    return errors & HEADLESS_CLONE;
+  }
+  bool size_mismatch() const {
+    return errors & SIZE_MISMATCH;
+  }
+};
+
 /**
  * @var all_nspaces
  * Pass as nspace argument to IoCtx::set_namespace()
diff --git a/src/include/rados/rgw_file.h b/src/include/rados/rgw_file.h
new file mode 100644
index 0000000..5eaf291
--- /dev/null
+++ b/src/include/rados/rgw_file.h
@@ -0,0 +1,305 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+/*
+ * convert RGW commands to file commands
+ *
+ * Copyright (C) 2015 Red Hat, Inc.
+ *
+ * This is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software
+ * Foundation.  See file COPYING.
+ *
+ */
+#ifndef RADOS_RGW_FILE_H
+#define RADOS_RGW_FILE_H
+
+#include <sys/types.h>
+#include <stdint.h>
+#include <stdbool.h>
+
+#include "include/rados/librgw.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/*
+ * object types
+ */
+enum rgw_fh_type {
+  RGW_FS_TYPE_FILE = 0,
+  RGW_FS_TYPE_DIRECTORY,
+};
+
+/*
+ * dynamic allocated handle to support nfs handle
+ */
+
+/* content-addressable hash */
+struct rgw_fh_hk {
+  uint64_t bucket;
+  uint64_t object;
+};
+
+struct rgw_file_handle
+{
+  /* content-addressable hash */
+  struct rgw_fh_hk fh_hk;
+  void *fh_private; /* librgw private data */
+  /* object type */
+  enum rgw_fh_type fh_type;
+};
+
+struct rgw_fs
+{
+  librgw_t rgw;
+  void *fs_private;
+  struct rgw_file_handle* root_fh;
+};
+
+
+/* XXX mount info hypothetical--emulate Unix, support at least
+ * UUID-length fsid */
+struct rgw_statvfs {
+    uint64_t  f_bsize;    /* file system block size */
+    uint64_t  f_frsize;   /* fragment size */
+    uint64_t     f_blocks;   /* size of fs in f_frsize units */
+    uint64_t     f_bfree;    /* # free blocks */
+    uint64_t     f_bavail;   /* # free blocks for unprivileged users */
+    uint64_t     f_files;    /* # inodes */
+    uint64_t     f_ffree;    /* # free inodes */
+    uint64_t     f_favail;   /* # free inodes for unprivileged users */
+    uint64_t     f_fsid[2];     /* file system ID */
+    uint64_t     f_flag;     /* mount flags */
+    uint64_t     f_namemax;  /* maximum filename length */
+};
+
+/*
+  lookup object by name (POSIX style)
+*/
+#define RGW_LOOKUP_FLAG_NONE    0x0000
+#define RGW_LOOKUP_FLAG_CREATE  0x0001
+
+int rgw_lookup(struct rgw_fs *rgw_fs,
+	      struct rgw_file_handle *parent_fh, const char *path,
+	      struct rgw_file_handle **fh, uint32_t flags);
+
+/*
+  lookup object by handle (NFS style)
+*/
+int rgw_lookup_handle(struct rgw_fs *rgw_fs, struct rgw_fh_hk *fh_hk,
+		      struct rgw_file_handle **fh, uint32_t flags);
+
+/*
+ * release file handle
+ */
+#define RGW_FH_RELE_FLAG_NONE   0x0000
+
+int rgw_fh_rele(struct rgw_fs *rgw_fs, struct rgw_file_handle *fh,
+		uint32_t flags);
+
+/*
+ attach rgw namespace
+*/
+#define RGW_MOUNT_FLAG_NONE     0x0000
+
+int rgw_mount(librgw_t rgw, const char *uid, const char *key,
+	      const char *secret, struct rgw_fs **rgw_fs,
+	      uint32_t flags);
+
+/*
+ detach rgw namespace
+*/
+#define RGW_UMOUNT_FLAG_NONE    0x0000
+
+int rgw_umount(struct rgw_fs *rgw_fs, uint32_t flags);
+
+
+/*
+  get filesystem attributes
+*/
+#define RGW_STATFS_FLAG_NONE     0x0000
+
+int rgw_statfs(struct rgw_fs *rgw_fs,
+	       struct rgw_file_handle *parent_fh,
+	       struct rgw_statvfs *vfs_st,
+	       uint32_t flags);
+
+
+/*
+  create file
+*/
+#define RGW_CREATE_FLAG_NONE     0x0000
+
+int rgw_create(struct rgw_fs *rgw_fs,
+	       struct rgw_file_handle *parent_fh,
+	       const char *name, mode_t mode, struct stat *st,
+	       struct rgw_file_handle **fh, uint32_t flags);
+
+/*
+  create a new directory
+*/
+#define RGW_MKDIR_FLAG_NONE      0x0000
+
+int rgw_mkdir(struct rgw_fs *rgw_fs,
+	      struct rgw_file_handle *parent_fh,
+	      const char *name, mode_t mode, struct stat *st,
+	      struct rgw_file_handle **fh, uint32_t flags);
+
+/*
+  rename object
+*/
+#define RGW_RENAME_FLAG_NONE      0x0000
+
+int rgw_rename(struct rgw_fs *rgw_fs,
+	       struct rgw_file_handle *olddir, const char* old_name,
+	       struct rgw_file_handle *newdir, const char* new_name,
+	       uint32_t flags);
+
+/*
+  remove file or directory
+*/
+#define RGW_UNLINK_FLAG_NONE      0x0000
+
+int rgw_unlink(struct rgw_fs *rgw_fs,
+	       struct rgw_file_handle *parent_fh, const char* path,
+	       uint32_t flags);
+
+/*
+    read  directory content
+*/
+typedef bool (*rgw_readdir_cb)(const char *name, void *arg, uint64_t offset);
+
+#define RGW_READDIR_FLAG_NONE      0x0000
+#define RGW_READDIR_FLAG_DOTDOT    0x0001 /* send dot names */
+
+int rgw_readdir(struct rgw_fs *rgw_fs,
+		struct rgw_file_handle *parent_fh, uint64_t *offset,
+		rgw_readdir_cb rcb, void *cb_arg, bool *eof,
+		uint32_t flags);
+
+/* XXX (get|set)attr mask bits */
+#define RGW_SETATTR_MODE   1
+#define RGW_SETATTR_UID    2
+#define RGW_SETATTR_GID    4
+#define RGW_SETATTR_MTIME  8
+#define RGW_SETATTR_ATIME 16
+#define RGW_SETATTR_SIZE  32
+#define RGW_SETATTR_CTIME 64
+
+/*
+   get unix attributes for object
+*/
+#define RGW_GETATTR_FLAG_NONE      0x0000
+
+int rgw_getattr(struct rgw_fs *rgw_fs,
+		struct rgw_file_handle *fh, struct stat *st,
+		uint32_t flags);
+
+/*
+   set unix attributes for object
+*/
+#define RGW_SETATTR_FLAG_NONE      0x0000
+
+int rgw_setattr(struct rgw_fs *rgw_fs,
+		struct rgw_file_handle *fh, struct stat *st,
+		uint32_t mask, uint32_t flags);
+
+/*
+   truncate file
+*/
+#define RGW_TRUNCATE_FLAG_NONE     0x0000
+
+int rgw_truncate(struct rgw_fs *rgw_fs,
+		 struct rgw_file_handle *fh, uint64_t size,
+		 uint32_t flags);
+
+/*
+   open file
+*/
+#define RGW_OPEN_FLAG_NONE         0x0000
+#define RGW_OPEN_FLAG_CREATE       0x0001
+
+int rgw_open(struct rgw_fs *rgw_fs, struct rgw_file_handle *parent_fh,
+	    uint32_t flags);
+
+/*
+   close file
+*/
+
+#define RGW_CLOSE_FLAG_NONE        0x0000
+#define RGW_CLOSE_FLAG_RELE        0x0001
+  
+int rgw_close(struct rgw_fs *rgw_fs, struct rgw_file_handle *fh,
+	      uint32_t flags);
+
+/*
+   read data from file
+*/
+#define RGW_READ_FLAG_NONE 0x0000
+
+int rgw_read(struct rgw_fs *rgw_fs,
+	     struct rgw_file_handle *fh, uint64_t offset,
+	     size_t length, size_t *bytes_read, void *buffer,
+	     uint32_t flags);
+
+/*
+   write data to file
+*/
+#define RGW_WRITE_FLAG_NONE      0x0000
+
+int rgw_write(struct rgw_fs *rgw_fs,
+	      struct rgw_file_handle *fh, uint64_t offset,
+	      size_t length, size_t *bytes_written, void *buffer,
+	      uint32_t flags);
+
+#define RGW_UIO_NONE    0x0000
+#define RGW_UIO_GIFT    0x0001
+#define RGW_UIO_FREE    0x0002
+#define RGW_UIO_BUFQ    0x0004
+
+struct rgw_uio;
+typedef void (*rgw_uio_release)(struct rgw_uio *, uint32_t);
+
+/* buffer vector descriptors */
+struct rgw_vio {
+  void *vio_p1;
+  void *vio_u1;
+  void *vio_base;
+  int32_t vio_len;
+};
+  
+struct rgw_uio {
+  rgw_uio_release uio_rele;
+  void *uio_p1;
+  void *uio_u1;
+  uint64_t uio_offset;
+  uint64_t uio_resid;
+  uint32_t uio_cnt;
+  uint32_t uio_flags;
+  struct rgw_vio *uio_vio; /* appended vectors */
+};
+
+typedef struct rgw_uio rgw_uio;
+
+int rgw_readv(struct rgw_fs *rgw_fs,
+	      struct rgw_file_handle *fh, rgw_uio *uio, uint32_t flags);
+
+int rgw_writev(struct rgw_fs *rgw_fs,
+	       struct rgw_file_handle *fh, rgw_uio *uio, uint32_t flags);
+
+/*
+   sync written data
+*/
+#define RGW_FSYNC_FLAG_NONE        0x0000
+
+int rgw_fsync(struct rgw_fs *rgw_fs, struct rgw_file_handle *fh,
+	      uint32_t flags);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* RADOS_RGW_FILE_H */
diff --git a/src/include/rbd/features.h b/src/include/rbd/features.h
index a78e6fc..3e3509d 100644
--- a/src/include/rbd/features.h
+++ b/src/include/rbd/features.h
@@ -36,6 +36,9 @@
                                          RBD_FEATURE_FAST_DIFF      | \
                                          RBD_FEATURE_JOURNALING)
 
+/// features that may be dynamically disabled
+#define RBD_FEATURES_DISABLE_ONLY       (RBD_FEATURE_DEEP_FLATTEN)
+
 /// features that only work when used with a single client
 /// using the image for writes
 #define RBD_FEATURES_SINGLE_CLIENT (RBD_FEATURE_EXCLUSIVE_LOCK | \
diff --git a/src/include/rbd/librbd.h b/src/include/rbd/librbd.h
index dde1a61..49ed98e 100644
--- a/src/include/rbd/librbd.h
+++ b/src/include/rbd/librbd.h
@@ -89,12 +89,30 @@ typedef struct {
   char parent_name[RBD_MAX_IMAGE_NAME_SIZE];  /* deprecated */
 } rbd_image_info_t;
 
+typedef enum {
+  RBD_MIRROR_MODE_DISABLED, /* mirroring is disabled */
+  RBD_MIRROR_MODE_IMAGE,    /* mirroring enabled on a per-image basis */
+  RBD_MIRROR_MODE_POOL      /* mirroring enabled on all journaled images */
+} rbd_mirror_mode_t;
+
 typedef struct {
-  char *cluster_uuid;
+  char *uuid;
   char *cluster_name;
   char *client_name;
 } rbd_mirror_peer_t;
 
+typedef enum {
+  RBD_MIRROR_IMAGE_DISABLING = 0,
+  RBD_MIRROR_IMAGE_ENABLED = 1,
+  RBD_MIRROR_IMAGE_DISABLED = 2
+} rbd_mirror_image_state_t;
+
+typedef struct {
+  char *global_id;
+  rbd_mirror_image_state_t state;
+  bool primary;
+} rbd_mirror_image_info_t;
+
 CEPH_RBD_API void rbd_version(int *major, int *minor, int *extra);
 
 /* image options */
@@ -170,23 +188,25 @@ CEPH_RBD_API int rbd_rename(rados_ioctx_t src_io_ctx, const char *srcname,
                             const char *destname);
 
 /* pool mirroring */
-CEPH_RBD_API int rbd_mirror_is_enabled(rados_ioctx_t io_ctx, bool *enabled);
-CEPH_RBD_API int rbd_mirror_set_enabled(rados_ioctx_t io_ctx, bool enabled);
+CEPH_RBD_API int rbd_mirror_mode_get(rados_ioctx_t io_ctx,
+                                     rbd_mirror_mode_t *mirror_mode);
+CEPH_RBD_API int rbd_mirror_mode_set(rados_ioctx_t io_ctx,
+                                     rbd_mirror_mode_t mirror_mode);
 CEPH_RBD_API int rbd_mirror_peer_add(rados_ioctx_t io_ctx,
-                                     const char *cluster_uuid,
+                                     char *uuid, size_t uuid_max_length,
                                      const char *cluster_name,
                                      const char *client_name);
 CEPH_RBD_API int rbd_mirror_peer_remove(rados_ioctx_t io_ctx,
-                                        const char *cluster_name);
+                                        const char *uuid);
 CEPH_RBD_API int rbd_mirror_peer_list(rados_ioctx_t io_ctx,
                                       rbd_mirror_peer_t *peers, int *max_peers);
 CEPH_RBD_API void rbd_mirror_peer_list_cleanup(rbd_mirror_peer_t *peers,
                                                int max_peers);
 CEPH_RBD_API int rbd_mirror_peer_set_client(rados_ioctx_t io_ctx,
-                                            const char *cluster_uuid,
+                                            const char *uuid,
                                             const char *client_name);
 CEPH_RBD_API int rbd_mirror_peer_set_cluster(rados_ioctx_t io_ctx,
-                                             const char *cluster_uuid,
+                                             const char *uuid,
                                              const char *cluster_name);
 
 CEPH_RBD_API int rbd_open(rados_ioctx_t io, const char *name,
@@ -578,6 +598,15 @@ CEPH_RBD_API int rbd_metadata_remove(rbd_image_t image, const char *key);
 CEPH_RBD_API int rbd_metadata_list(rbd_image_t image, const char *start, uint64_t max,
     char *keys, size_t *key_len, char *values, size_t *vals_len);
 
+// RBD image mirroring support functions
+CEPH_RBD_API int rbd_mirror_image_enable(rbd_image_t image);
+CEPH_RBD_API int rbd_mirror_image_disable(rbd_image_t image, bool force);
+CEPH_RBD_API int rbd_mirror_image_promote(rbd_image_t image, bool force);
+CEPH_RBD_API int rbd_mirror_image_demote(rbd_image_t image);
+CEPH_RBD_API int rbd_mirror_image_resync(rbd_image_t image);
+CEPH_RBD_API int rbd_mirror_image_get_info(rbd_image_t image,
+                                           rbd_mirror_image_info_t *mirror_image_info,
+                                           size_t info_size);
 
 #ifdef __cplusplus
 }
diff --git a/src/include/rbd/librbd.hpp b/src/include/rbd/librbd.hpp
index 7a4a2c7..f328c42 100644
--- a/src/include/rbd/librbd.hpp
+++ b/src/include/rbd/librbd.hpp
@@ -47,11 +47,19 @@ namespace librbd {
   } locker_t;
 
   typedef struct {
-    std::string cluster_uuid;
+    std::string uuid;
     std::string cluster_name;
     std::string client_name;
   } mirror_peer_t;
 
+  typedef rbd_mirror_image_state_t mirror_image_state_t;
+
+  typedef struct {
+    std::string global_id;
+    mirror_image_state_t state;
+    bool primary;
+  } mirror_image_info_t;
+
   typedef rbd_image_info_t image_info_t;
 
   class CEPH_RBD_API ProgressContext
@@ -113,16 +121,16 @@ public:
   int rename(IoCtx& src_io_ctx, const char *srcname, const char *destname);
 
   // RBD pool mirroring support functions
-  int mirror_is_enabled(IoCtx& io_ctx, bool *enabled);
-  int mirror_set_enabled(IoCtx& io_ctx, bool enabled);
-  int mirror_peer_add(IoCtx& io_ctx, const std::string &cluster_uuid,
+  int mirror_mode_get(IoCtx& io_ctx, rbd_mirror_mode_t *mirror_mode);
+  int mirror_mode_set(IoCtx& io_ctx, rbd_mirror_mode_t mirror_mode);
+  int mirror_peer_add(IoCtx& io_ctx, std::string *uuid,
                       const std::string &cluster_name,
                       const std::string &client_name);
-  int mirror_peer_remove(IoCtx& io_ctx, const std::string &cluster_uuid);
+  int mirror_peer_remove(IoCtx& io_ctx, const std::string &uuid);
   int mirror_peer_list(IoCtx& io_ctx, std::vector<mirror_peer_t> *peers);
-  int mirror_peer_set_client(IoCtx& io_ctx, const std::string &cluster_uuid,
+  int mirror_peer_set_client(IoCtx& io_ctx, const std::string &uuid,
                              const std::string &client_name);
-  int mirror_peer_set_cluster(IoCtx& io_ctx, const std::string &cluster_uuid,
+  int mirror_peer_set_cluster(IoCtx& io_ctx, const std::string &uuid,
                               const std::string &cluster_name);
 
 private:
@@ -226,7 +234,7 @@ public:
 
   /* I/O */
   ssize_t read(uint64_t ofs, size_t len, ceph::bufferlist& bl);
-  /* @parmam op_flags see librados.h constants beginning with LIBRADOS_OP_FLAG */
+  /* @param op_flags see librados.h constants beginning with LIBRADOS_OP_FLAG */
   ssize_t read2(uint64_t ofs, size_t len, ceph::bufferlist& bl, int op_flags);
   int64_t read_iterate(uint64_t ofs, size_t len,
 		       int (*cb)(uint64_t, size_t, const char *, void *), void *arg);
@@ -262,12 +270,12 @@ public:
 		    int (*cb)(uint64_t, size_t, int, void *), void *arg);
 
   ssize_t write(uint64_t ofs, size_t len, ceph::bufferlist& bl);
-  /* @parmam op_flags see librados.h constants beginning with LIBRADOS_OP_FLAG */
+  /* @param op_flags see librados.h constants beginning with LIBRADOS_OP_FLAG */
   ssize_t write2(uint64_t ofs, size_t len, ceph::bufferlist& bl, int op_flags);
   int discard(uint64_t ofs, uint64_t len);
 
   int aio_write(uint64_t off, size_t len, ceph::bufferlist& bl, RBD::AioCompletion *c);
-  /* @parmam op_flags see librados.h constants beginning with LIBRADOS_OP_FLAG */
+  /* @param op_flags see librados.h constants beginning with LIBRADOS_OP_FLAG */
   int aio_write2(uint64_t off, size_t len, ceph::bufferlist& bl,
 		  RBD::AioCompletion *c, int op_flags);
   /**
@@ -288,7 +296,7 @@ public:
    * @param c aio completion to notify when read is complete
    */
   int aio_read(uint64_t off, size_t len, ceph::bufferlist& bl, RBD::AioCompletion *c);
-  /* @parmam op_flags see librados.h constants beginning with LIBRADOS_OP_FLAG */
+  /* @param op_flags see librados.h constants beginning with LIBRADOS_OP_FLAG */
   int aio_read2(uint64_t off, size_t len, ceph::bufferlist& bl,
 		  RBD::AioCompletion *c, int op_flags);
   int aio_discard(uint64_t off, uint64_t len, RBD::AioCompletion *c);
@@ -321,6 +329,15 @@ public:
    */
   int metadata_list(const std::string &start, uint64_t max, std::map<std::string, ceph::bufferlist> *pairs);
 
+  // RBD image mirroring support functions
+  int mirror_image_enable();
+  int mirror_image_disable(bool force);
+  int mirror_image_promote(bool force);
+  int mirror_image_demote();
+  int mirror_image_resync();
+  int mirror_image_get_info(mirror_image_info_t *mirror_image_info,
+                            size_t info_size);
+
 private:
   friend class RBD;
 
diff --git a/src/include/rbd_types.h b/src/include/rbd_types.h
index 6ac5ed0..3dfb37a 100644
--- a/src/include/rbd_types.h
+++ b/src/include/rbd_types.h
@@ -59,11 +59,10 @@
 #define RBD_LOCK_NAME		"rbd_lock"
 
 /**
- * rbd_pool_settings object in each pool contains pool-specific settings
- * for configuring features such as async image mirroring to other Ceph
- * clusters.
+ * rbd_mirroring object in each pool contains pool-specific settings
+ * for configuring mirroring.
  */
-#define RBD_POOL_SETTINGS       "rbd_pool_settings"
+#define RBD_MIRRORING       "rbd_mirroring"
 
 #define RBD_MAX_OBJ_NAME_SIZE	96
 #define RBD_MAX_BLOCK_NAME_SIZE 24
diff --git a/src/include/types.h b/src/include/types.h
index 19982db..d8a679f 100644
--- a/src/include/types.h
+++ b/src/include/types.h
@@ -234,6 +234,9 @@ struct ltstr
 };
 
 
+namespace ceph {
+  class Formatter;
+}
 
 #include "encoding.h"
 
@@ -244,7 +247,8 @@ WRITE_RAW_ENCODER(ceph_mds_session_head)
 WRITE_RAW_ENCODER(ceph_mds_request_head)
 WRITE_RAW_ENCODER(ceph_mds_request_release)
 WRITE_RAW_ENCODER(ceph_filelock)
-WRITE_RAW_ENCODER(ceph_mds_caps)
+WRITE_RAW_ENCODER(ceph_mds_caps_head)
+WRITE_RAW_ENCODER(ceph_mds_caps_body_legacy)
 WRITE_RAW_ENCODER(ceph_mds_cap_peer)
 WRITE_RAW_ENCODER(ceph_mds_cap_release)
 WRITE_RAW_ENCODER(ceph_mds_cap_item)
@@ -252,7 +256,7 @@ WRITE_RAW_ENCODER(ceph_mds_lease)
 WRITE_RAW_ENCODER(ceph_mds_snap_head)
 WRITE_RAW_ENCODER(ceph_mds_snap_realm)
 WRITE_RAW_ENCODER(ceph_mds_reply_head)
-WRITE_RAW_ENCODER(ceph_mds_reply_inode)
+WRITE_RAW_ENCODER(ceph_mds_reply_cap)
 WRITE_RAW_ENCODER(ceph_mds_cap_reconnect)
 WRITE_RAW_ENCODER(ceph_mds_snaprealm_reconnect)
 WRITE_RAW_ENCODER(ceph_frag_tree_split)
@@ -308,62 +312,6 @@ inline ostream& operator<<(ostream& out, const client_t& c) {
 
 
 
-// --------------------------------------
-// ino
-
-typedef uint64_t _inodeno_t;
-
-struct inodeno_t {
-  _inodeno_t val;
-  inodeno_t() : val(0) {}
-  // cppcheck-suppress noExplicitConstructor
-  inodeno_t(_inodeno_t v) : val(v) {}
-  inodeno_t operator+=(inodeno_t o) { val += o.val; return *this; }
-  operator _inodeno_t() const { return val; }
-
-  void encode(bufferlist& bl) const {
-    ::encode(val, bl);
-  }
-  void decode(bufferlist::iterator& p) {
-    ::decode(val, p);
-  }
-} __attribute__ ((__may_alias__));
-WRITE_CLASS_ENCODER(inodeno_t)
-
-inline ostream& operator<<(ostream& out, inodeno_t ino) {
-  return out << hex << ino.val << dec;
-}
-
-namespace std {
-  template<> struct hash< inodeno_t >
-  {
-    size_t operator()( const inodeno_t& x ) const
-    {
-      static rjhash<uint64_t> H;
-      return H(x.val);
-    }
-  };
-} // namespace std
-
-
-// file modes
-
-static inline bool file_mode_is_readonly(int mode) {
-  return (mode & CEPH_FILE_MODE_WR) == 0;
-}
-
-
-// dentries
-#define MAX_DENTRY_LEN 255
-
-// --
-namespace ceph {
-  class Formatter;
-}
-void dump(const ceph_file_layout& l, ceph::Formatter *f);
-void dump(const ceph_dir_layout& l, ceph::Formatter *f);
-
-
 // --
 
 struct prettybyte_t {
diff --git a/src/include/utime.h b/src/include/utime.h
index a60501a..d08d804 100644
--- a/src/include/utime.h
+++ b/src/include/utime.h
@@ -23,6 +23,7 @@
 #include "include/types.h"
 #include "include/timegm.h"
 #include "common/strtol.h"
+#include "common/ceph_time.h"
 
 
 // --------
@@ -61,6 +62,10 @@ public:
     tv.tv_sec = v.tv_sec;
     tv.tv_nsec = v.tv_nsec;
   }
+  explicit utime_t(const ceph::real_time& rt) {
+    ceph_timespec ts = real_clock::to_ceph_timespec(rt);
+    decode_timeval(&ts);
+  }
   utime_t(const struct timeval &v) {
     set_from_timeval(&v);
   }
@@ -76,6 +81,12 @@ public:
     tv.tv_nsec = (__u32)((d - (double)tv.tv_sec) * (double)1000000000.0);
   }
 
+  real_time to_real_time() const {
+    ceph_timespec ts;
+    encode_timeval(&ts);
+    return ceph::real_clock::from_ceph_timespec(ts);
+  }
+
   // accessors
   time_t        sec()  const { return tv.tv_sec; } 
   long          usec() const { return tv.tv_nsec/1000; }
@@ -200,6 +211,35 @@ public:
   }
 
   // output
+  ostream& gmtime_nsec(ostream& out) const {
+    out.setf(std::ios::right);
+    char oldfill = out.fill();
+    out.fill('0');
+    if (sec() < ((time_t)(60*60*24*365*10))) {
+      // raw seconds.  this looks like a relative time.
+      out << (long)sec() << "." << std::setw(6) << usec();
+    } else {
+      // localtime.  this looks like an absolute time.
+      //  aim for http://en.wikipedia.org/wiki/ISO_8601
+      struct tm bdt;
+      time_t tt = sec();
+      gmtime_r(&tt, &bdt);
+      out << std::setw(4) << (bdt.tm_year+1900)  // 2007 -> '07'
+	  << '-' << std::setw(2) << (bdt.tm_mon+1)
+	  << '-' << std::setw(2) << bdt.tm_mday
+	  << ' '
+	  << std::setw(2) << bdt.tm_hour
+	  << ':' << std::setw(2) << bdt.tm_min
+	  << ':' << std::setw(2) << bdt.tm_sec;
+      out << "." << std::setw(9) << nsec();
+      out << "Z";
+    }
+    out.fill(oldfill);
+    out.unsetf(std::ios::right);
+    return out;
+  }
+
+  // output
   ostream& asctime(ostream& out) const {
     out.setf(std::ios::right);
     char oldfill = out.fill();
diff --git a/src/init-ceph.in b/src/init-ceph.in
index 5baa8fe..731d103 100755
--- a/src/init-ceph.in
+++ b/src/init-ceph.in
@@ -398,7 +398,7 @@ for name in $what; do
 
 	    if [ "$type" = "osd" ]; then
 		get_conf update_crush "" "osd crush update on start"
-		if [ "${update_crush:-1}" = "1" -o "${update_crush:-1}" = "true" ]; then
+		case "${update_crush:-1}" in 1|[Tt][Rr][Uu][Ee])
 		    # update location in crush
 		    get_conf osd_location_hook "$BINDIR/ceph-crush-location" "osd crush location hook"
 		    osd_location=`$osd_location_hook --cluster $cluster --id $id --type osd`
@@ -410,7 +410,7 @@ for name in $what; do
 			EXIT_STATUS=$ERR
 			continue
 		    fi
-		fi
+		esac
 	    fi
 
 	    echo Starting Ceph $name on $host...
@@ -535,7 +535,9 @@ done
 # activate latent osds?
 if [ "$command" = "start" -a "$BINDIR" != "." ]; then
     if [ "$*" = "" ] || echo $* | grep -q ^osd\$ ; then
-	ceph-disk activate-all
+       if [ -x $SBINDIR/ceph-disk ]; then
+           ceph-disk activate-all
+       fi
     fi
 fi
 
diff --git a/src/java/Makefile.in b/src/java/Makefile.in
index dce51a0..a031874 100644
--- a/src/java/Makefile.in
+++ b/src/java/Makefile.in
@@ -1,7 +1,7 @@
-# Makefile.in generated by automake 1.15 from Makefile.am.
+# Makefile.in generated by automake 1.14.1 from Makefile.am.
 # @configure_input@
 
-# Copyright (C) 1994-2014 Free Software Foundation, Inc.
+# Copyright (C) 1994-2013 Free Software Foundation, Inc.
 
 # This Makefile.in is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -17,17 +17,7 @@
 # automake technique adapted from OpenMPI Java
 
 VPATH = @srcdir@
-am__is_gnu_make = { \
-  if test -z '$(MAKELEVEL)'; then \
-    false; \
-  elif test -n '$(MAKE_HOST)'; then \
-    true; \
-  elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
-    true; \
-  else \
-    false; \
-  fi; \
-}
+am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
 am__make_running_with_option = \
   case $${target_option-} in \
       ?) ;; \
@@ -94,6 +84,7 @@ target_triplet = @target@
 @ENABLE_CEPHFS_JAVA_TRUE@@ENABLE_CLIENT_TRUE@@HAVE_JUNIT4_TRUE@@WITH_CEPHFS_TRUE@@WITH_RADOS_TRUE at am__append_1 = libcephfs-test.jar
 @ENABLE_CEPHFS_JAVA_TRUE@@ENABLE_CLIENT_TRUE@@HAVE_JUNIT4_TRUE@@WITH_CEPHFS_TRUE@@WITH_RADOS_TRUE at am__append_2 = test/com/ceph/fs/*.class libcephfs-test.jar
 subdir = src/java
+DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am README
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
 am__aclocal_m4_deps = $(top_srcdir)/m4/ac_check_classpath.m4 \
 	$(top_srcdir)/m4/ac_prog_jar.m4 \
@@ -112,7 +103,6 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/ac_check_classpath.m4 \
 	$(top_srcdir)/m4/pkg.m4 $(top_srcdir)/configure.ac
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
 	$(ACLOCAL_M4)
-DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON)
 mkinstalldirs = $(install_sh) -d
 CONFIG_HEADER = $(top_builddir)/src/acconfig.h
 CONFIG_CLEAN_FILES =
@@ -166,7 +156,6 @@ am__uninstall_files_from_dir = { \
 am__installdirs = "$(DESTDIR)$(javadir)"
 DATA = $(java_DATA)
 am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
-am__DIST_COMMON = $(srcdir)/Makefile.in README
 DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
 ACLOCAL = @ACLOCAL@
 AMTAR = @AMTAR@
@@ -259,7 +248,6 @@ LN_S = @LN_S@
 LTLIBOBJS = @LTLIBOBJS@
 LTTNG_GEN_TP_CHECK = @LTTNG_GEN_TP_CHECK@
 LTTNG_GEN_TP_PROG = @LTTNG_GEN_TP_PROG@
-LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
 MAKEINFO = @MAKEINFO@
 MANIFEST_TOOL = @MANIFEST_TOOL@
 MKDIR_P = @MKDIR_P@
@@ -286,7 +274,10 @@ PTHREAD_CC = @PTHREAD_CC@
 PTHREAD_CFLAGS = @PTHREAD_CFLAGS@
 PTHREAD_LIBS = @PTHREAD_LIBS@
 PYTHON = @PYTHON@
+PYTHON_CFLAGS = @PYTHON_CFLAGS@
+PYTHON_CONFIG_CHECK = @PYTHON_CONFIG_CHECK@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
+PYTHON_LDFLAGS = @PYTHON_LDFLAGS@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
 PYTHON_PREFIX = @PYTHON_PREFIX@
 PYTHON_VERSION = @PYTHON_VERSION@
@@ -355,7 +346,6 @@ program_transform_name = @program_transform_name@
 psdir = @psdir@
 pyexecdir = @pyexecdir@
 pythondir = @pythondir@
-runstatedir = @runstatedir@
 sbindir = @sbindir@
 sharedstatedir = @sharedstatedir@
 srcdir = @srcdir@
@@ -429,6 +419,7 @@ $(srcdir)/Makefile.in:  $(srcdir)/Makefile.am  $(am__configure_deps)
 	echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign src/java/Makefile'; \
 	$(am__cd) $(top_srcdir) && \
 	  $(AUTOMAKE) --foreign src/java/Makefile
+.PRECIOUS: Makefile
 Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
 	@case '$?' in \
 	  *config.status*) \
@@ -631,8 +622,6 @@ uninstall-am: uninstall-javaDATA
 	mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \
 	ps ps-am tags-am uninstall uninstall-am uninstall-javaDATA
 
-.PRECIOUS: Makefile
-
 
 # note: for the -source 1.5 builds, we add
 #   -Xlint:-options
diff --git a/src/java/java/com/ceph/fs/CephMount.java b/src/java/java/com/ceph/fs/CephMount.java
index a286795..d126714 100644
--- a/src/java/java/com/ceph/fs/CephMount.java
+++ b/src/java/java/com/ceph/fs/CephMount.java
@@ -42,13 +42,14 @@ public class CephMount {
    *
    * Must be synchronized with JNI if changed.
    */
-  public static final int O_RDONLY = 1;
-  public static final int O_RDWR   = 2;
-  public static final int O_APPEND = 4;
-  public static final int O_CREAT  = 8;
-  public static final int O_TRUNC  = 16;
-  public static final int O_EXCL   = 32;
-  public static final int O_WRONLY = 64;
+  public static final int O_RDONLY    = 1;
+  public static final int O_RDWR      = 2;
+  public static final int O_APPEND    = 4;
+  public static final int O_CREAT     = 8;
+  public static final int O_TRUNC     = 16;
+  public static final int O_EXCL      = 32;
+  public static final int O_WRONLY    = 64;
+  public static final int O_DIRECTORY = 128;
 
   /*
    * Whence flags for seek().
diff --git a/src/java/native/libcephfs_jni.cc b/src/java/native/libcephfs_jni.cc
index 050acc3..d0cb7ee 100644
--- a/src/java/native/libcephfs_jni.cc
+++ b/src/java/native/libcephfs_jni.cc
@@ -54,13 +54,14 @@
  * keeping the values in Java and making a cross-JNI up-call to retrieve them,
  * and makes it easy to keep any platform specific value changes in this file.
  */
-#define JAVA_O_RDONLY 1
-#define JAVA_O_RDWR   2
-#define JAVA_O_APPEND 4
-#define JAVA_O_CREAT  8
-#define JAVA_O_TRUNC  16
-#define JAVA_O_EXCL   32
-#define JAVA_O_WRONLY 64
+#define JAVA_O_RDONLY    1
+#define JAVA_O_RDWR      2
+#define JAVA_O_APPEND    4
+#define JAVA_O_CREAT     8
+#define JAVA_O_TRUNC     16
+#define JAVA_O_EXCL      32
+#define JAVA_O_WRONLY    64
+#define JAVA_O_DIRECTORY 128
 
 /*
  * Whence flags for seek(). sync with CephMount.java if changed.
@@ -111,6 +112,7 @@ static inline int fixup_open_flags(jint jflags)
 	FIXUP_OPEN_FLAG(O_TRUNC)
 	FIXUP_OPEN_FLAG(O_EXCL)
 	FIXUP_OPEN_FLAG(O_WRONLY)
+	FIXUP_OPEN_FLAG(O_DIRECTORY)
 
 #undef FIXUP_OPEN_FLAG
 
diff --git a/src/java/test/com/ceph/fs/CephMountTest.java b/src/java/test/com/ceph/fs/CephMountTest.java
index c952c0c..fcc54d8 100644
--- a/src/java/test/com/ceph/fs/CephMountTest.java
+++ b/src/java/test/com/ceph/fs/CephMountTest.java
@@ -73,6 +73,18 @@ public class CephMountTest {
   }
 
   /*
+   * Helper to learn the data pool name, by reading it
+   * from the '/' dir inode.
+   */
+  public String getRootPoolName() throws Exception
+  {
+    int fd = mount.open("/", CephMount.O_DIRECTORY, 0600);
+    String pool = mount.get_file_pool_name(fd);
+    mount.close(fd);
+    return pool;
+  }
+
+  /*
    * Helper function to create a file with the given path and size. The file
    * is filled with size bytes and the file descriptor is returned.
    */
@@ -936,17 +948,11 @@ public class CephMountTest {
     assertTrue(mount.get_stripe_unit_granularity() > 0);
   }
 
-  /*
-   * pool info. below we use "data" and "metadata" pool names which we assume
-   * to exist (they are the default pools created for file data / metadata in
-   * CephFS).
-   */
-
   @Test
   public void test_get_pool_id() throws Exception {
-    /* returns valid pool ids */
-    assertTrue(mount.get_pool_id("data") >= 0);
-    assertTrue(mount.get_pool_id("metadata") >= 0);
+    String data_pool_name = getRootPoolName();
+    /* returns valid pool id */
+    assertTrue(mount.get_pool_id(data_pool_name) >= 0);
 
     /* test non-existent pool name */
     try {
@@ -964,20 +970,22 @@ public class CephMountTest {
     } catch (CephPoolException e) {}
 
     /* test valid pool id */
-    int poolid = mount.get_pool_id("data");
+    String data_pool_name = getRootPoolName();
+    int poolid = mount.get_pool_id(data_pool_name);
     assertTrue(poolid >= 0);
     assertTrue(mount.get_pool_replication(poolid) > 0);
   }
 
   @Test
   public void test_get_file_pool_name() throws Exception {
+    String data_pool_name = getRootPoolName();
     String path = makePath();
     int fd = createFile(path, 1);
     String pool = mount.get_file_pool_name(fd);
     mount.close(fd);
     assertTrue(pool != null);
-    /* assumes using default data pool "data" */
-    assertTrue(pool.compareTo("data") == 0);
+    /* assumes using default data pool */
+    assertTrue(pool.compareTo(data_pool_name) == 0);
     mount.unlink(path);
   }
 
diff --git a/src/journal/FutureImpl.cc b/src/journal/FutureImpl.cc
index c3344ba..11eda44 100644
--- a/src/journal/FutureImpl.cc
+++ b/src/journal/FutureImpl.cc
@@ -2,15 +2,15 @@
 // vim: ts=8 sw=2 smarttab
 
 #include "journal/FutureImpl.h"
-#include "common/Finisher.h"
+#include "journal/JournalMetadata.h"
 #include "journal/Utils.h"
 
 namespace journal {
 
-FutureImpl::FutureImpl(Finisher &finisher, uint64_t tag_tid, uint64_t entry_tid,
-                       uint64_t commit_tid)
-  : RefCountedObject(NULL, 0), m_finisher(finisher), m_tag_tid(tag_tid),
-    m_entry_tid(entry_tid), m_commit_tid(commit_tid),
+FutureImpl::FutureImpl(JournalMetadataPtr journal_metadata, uint64_t tag_tid,
+                       uint64_t entry_tid, uint64_t commit_tid)
+  : RefCountedObject(NULL, 0), m_journal_metadata(journal_metadata),
+    m_tag_tid(tag_tid), m_entry_tid(entry_tid), m_commit_tid(commit_tid),
     m_lock(utils::unique_lock_name("FutureImpl::m_lock", this)), m_safe(false),
     m_consistent(false), m_return_value(0), m_flush_state(FLUSH_STATE_NONE),
     m_consistent_ack(this) {
@@ -51,7 +51,7 @@ void FutureImpl::flush(Context *on_safe) {
   }
 
   if (complete && on_safe != NULL) {
-    m_finisher.queue(on_safe, m_return_value);
+    m_journal_metadata->queue(on_safe, m_return_value);
   } else if (flush_handler) {
     // attached to journal object -- instruct it to flush all entries through
     // this one.  possible to become detached while lock is released, so flush
@@ -69,7 +69,7 @@ void FutureImpl::wait(Context *on_safe) {
       return;
     }
   }
-  m_finisher.queue(on_safe, m_return_value);
+  m_journal_metadata->queue(on_safe, m_return_value);
 }
 
 bool FutureImpl::is_complete() const {
diff --git a/src/journal/FutureImpl.h b/src/journal/FutureImpl.h
index e77f049..0a9eba5 100644
--- a/src/journal/FutureImpl.h
+++ b/src/journal/FutureImpl.h
@@ -14,11 +14,11 @@
 #include "include/assert.h"
 
 class Context;
-class Finisher;
 
 namespace journal {
 
 class FutureImpl;
+class JournalMetadata;
 typedef boost::intrusive_ptr<FutureImpl> FutureImplPtr;
 
 class FutureImpl : public RefCountedObject, boost::noncopyable {
@@ -29,10 +29,11 @@ public:
     virtual void get() = 0;
     virtual void put() = 0;
   };
+  typedef boost::intrusive_ptr<JournalMetadata> JournalMetadataPtr;
   typedef boost::intrusive_ptr<FlushHandler> FlushHandlerPtr;
 
-  FutureImpl(Finisher &finisher, uint64_t tag_tid, uint64_t entry_tid,
-             uint64_t commit_tid);
+  FutureImpl(JournalMetadataPtr journal_metadata, uint64_t tag_tid,
+             uint64_t entry_tid, uint64_t commit_tid);
 
   void init(const FutureImplPtr &prev_future);
 
@@ -95,7 +96,7 @@ private:
     virtual void finish(int r) {}
   };
 
-  Finisher &m_finisher;
+  JournalMetadataPtr m_journal_metadata;
   uint64_t m_tag_tid;
   uint64_t m_entry_tid;
   uint64_t m_commit_tid;
diff --git a/src/journal/JournalMetadata.cc b/src/journal/JournalMetadata.cc
index f8d5574..830b4ca 100644
--- a/src/journal/JournalMetadata.cc
+++ b/src/journal/JournalMetadata.cc
@@ -4,7 +4,6 @@
 #include "journal/JournalMetadata.h"
 #include "journal/Utils.h"
 #include "common/errno.h"
-#include "common/Finisher.h"
 #include "common/Timer.h"
 #include "cls/journal/cls_journal_client.h"
 #include <functional>
@@ -20,35 +19,6 @@ using namespace cls::journal;
 
 namespace {
 
-// does not compare object number
-inline bool entry_positions_less_equal(const ObjectSetPosition &lhs,
-                                       const ObjectSetPosition &rhs) {
-  if (lhs.entry_positions == rhs.entry_positions) {
-    return true;
-  }
-
-  if (lhs.entry_positions.size() < rhs.entry_positions.size()) {
-    return true;
-  } else if (rhs.entry_positions.size() > rhs.entry_positions.size()) {
-    return false;
-  }
-
-  std::map<uint64_t, uint64_t> rhs_tids;
-  for (EntryPositions::const_iterator it = rhs.entry_positions.begin();
-       it != rhs.entry_positions.end(); ++it) {
-    rhs_tids[it->tag_tid] = it->entry_tid;
-  }
-
-  for (EntryPositions::const_iterator it = lhs.entry_positions.begin();
-       it != lhs.entry_positions.end(); ++it) {
-    const EntryPosition &entry_position = *it;
-    if (entry_position.entry_tid < rhs_tids[entry_position.tag_tid]) {
-      return true;
-    }
-  }
-  return false;
-}
-
 struct C_AllocateTag : public Context {
   CephContext *cct;
   librados::IoCtx &ioctx;
@@ -243,16 +213,32 @@ struct C_GetTags : public Context {
   }
 };
 
+struct C_FlushCommitPosition : public Context {
+  Context *commit_position_ctx;
+  Context *on_finish;
+
+  C_FlushCommitPosition(Context *commit_position_ctx, Context *on_finish)
+    : commit_position_ctx(commit_position_ctx), on_finish(on_finish) {
+  }
+  virtual void finish(int r) override {
+    if (commit_position_ctx != nullptr) {
+      commit_position_ctx->complete(r);
+    }
+    on_finish->complete(r);
+  }
+};
+
 } // anonymous namespace
 
-JournalMetadata::JournalMetadata(librados::IoCtx &ioctx,
+JournalMetadata::JournalMetadata(ContextWQ *work_queue, SafeTimer *timer,
+                                 Mutex *timer_lock, librados::IoCtx &ioctx,
                                  const std::string &oid,
                                  const std::string &client_id,
                                  double commit_interval)
     : RefCountedObject(NULL, 0), m_cct(NULL), m_oid(oid),
       m_client_id(client_id), m_commit_interval(commit_interval), m_order(0),
-      m_splay_width(0), m_pool_id(-1), m_initialized(false), m_finisher(NULL),
-      m_timer(NULL), m_timer_lock("JournalMetadata::m_timer_lock"),
+      m_splay_width(0), m_pool_id(-1), m_initialized(false),
+      m_work_queue(work_queue), m_timer(timer), m_timer_lock(timer_lock),
       m_lock("JournalMetadata::m_lock"), m_commit_tid(0), m_watch_ctx(this),
       m_watch_handle(0), m_minimum_set(0), m_active_set(0),
       m_update_notifications(0), m_commit_position_ctx(NULL),
@@ -263,7 +249,7 @@ JournalMetadata::JournalMetadata(librados::IoCtx &ioctx,
 
 JournalMetadata::~JournalMetadata() {
   if (m_initialized) {
-    shutdown();
+    shut_down();
   }
 }
 
@@ -271,12 +257,6 @@ void JournalMetadata::init(Context *on_init) {
   assert(!m_initialized);
   m_initialized = true;
 
-  m_finisher = new Finisher(m_cct);
-  m_finisher->start();
-
-  m_timer = new SafeTimer(m_cct, m_timer_lock, true);
-  m_timer->init();
-
   int r = m_ioctx.watch2(m_oid, &m_watch_handle, &m_watch_ctx);
   if (r < 0) {
     lderr(m_cct) << __func__ << ": failed to watch journal"
@@ -286,11 +266,10 @@ void JournalMetadata::init(Context *on_init) {
   }
 
   C_ImmutableMetadata *ctx = new C_ImmutableMetadata(this, on_init);
-  client::get_immutable_metadata(m_ioctx, m_oid, &m_order, &m_splay_width,
-                                 &m_pool_id, ctx);
+  get_immutable_metadata(&m_order, &m_splay_width, &m_pool_id, ctx);
 }
 
-void JournalMetadata::shutdown() {
+void JournalMetadata::shut_down() {
 
   ldout(m_cct, 20) << __func__ << dendl;
 
@@ -307,52 +286,75 @@ void JournalMetadata::shutdown() {
 
   flush_commit_position();
 
-  if (m_timer != NULL) {
-    Mutex::Locker locker(m_timer_lock);
-    m_timer->shutdown();
-    delete m_timer;
-    m_timer = NULL;
-  }
-
-  if (m_finisher != NULL) {
-    m_finisher->stop();
-    delete m_finisher;
-    m_finisher = NULL;
-  }
-
   librados::Rados rados(m_ioctx);
   rados.watch_flush();
 
   m_async_op_tracker.wait_for_ops();
-  m_ioctx.aio_flush();
 }
 
-int JournalMetadata::register_client(const bufferlist &data) {
+void JournalMetadata::get_immutable_metadata(uint8_t *order,
+					     uint8_t *splay_width,
+					     int64_t *pool_id,
+					     Context *on_finish) {
+  client::get_immutable_metadata(m_ioctx, m_oid, order, splay_width, pool_id,
+				 on_finish);
+}
+
+void JournalMetadata::get_mutable_metadata(uint64_t *minimum_set,
+					   uint64_t *active_set,
+					   RegisteredClients *clients,
+					   Context *on_finish) {
+  client::get_mutable_metadata(m_ioctx, m_oid, minimum_set, active_set, clients,
+			       on_finish);
+}
+
+void JournalMetadata::register_client(const bufferlist &data,
+				      Context *on_finish) {
   ldout(m_cct, 10) << __func__ << ": " << m_client_id << dendl;
-  int r = client::client_register(m_ioctx, m_oid, m_client_id, data);
-  if (r < 0) {
-    lderr(m_cct) << "failed to register journal client '" << m_client_id
-                 << "': " << cpp_strerror(r) << dendl;
-    return r;
-  }
+  librados::ObjectWriteOperation op;
+  client::client_register(&op, m_client_id, data);
+
+  C_NotifyUpdate *ctx = new C_NotifyUpdate(this, on_finish);
 
-  notify_update();
-  return 0;
+  librados::AioCompletion *comp =
+    librados::Rados::aio_create_completion(ctx, NULL,
+                                           utils::rados_ctx_callback);
+  int r = m_ioctx.aio_operate(m_oid, comp, &op);
+  assert(r == 0);
+  comp->release();
 }
 
-int JournalMetadata::unregister_client() {
+void JournalMetadata::update_client(const bufferlist &data,
+				    Context *on_finish) {
+  ldout(m_cct, 10) << __func__ << ": " << m_client_id << dendl;
+  librados::ObjectWriteOperation op;
+  client::client_update_data(&op, m_client_id, data);
+
+  C_NotifyUpdate *ctx = new C_NotifyUpdate(this, on_finish);
+
+  librados::AioCompletion *comp =
+    librados::Rados::aio_create_completion(ctx, NULL,
+                                           utils::rados_ctx_callback);
+  int r = m_ioctx.aio_operate(m_oid, comp, &op);
+  assert(r == 0);
+  comp->release();
+}
+
+void JournalMetadata::unregister_client(Context *on_finish) {
   assert(!m_client_id.empty());
 
   ldout(m_cct, 10) << __func__ << ": " << m_client_id << dendl;
-  int r = client::client_unregister(m_ioctx, m_oid, m_client_id);
-  if (r < 0) {
-    lderr(m_cct) << "failed to unregister journal client '" << m_client_id
-                 << "': " << cpp_strerror(r) << dendl;
-    return r;
-  }
+  librados::ObjectWriteOperation op;
+  client::client_unregister(&op, m_client_id);
+
+  C_NotifyUpdate *ctx = new C_NotifyUpdate(this, on_finish);
 
-  notify_update();
-  return 0;
+  librados::AioCompletion *comp =
+    librados::Rados::aio_create_completion(ctx, NULL,
+                                           utils::rados_ctx_callback);
+  int r = m_ioctx.aio_operate(m_oid, comp, &op);
+  assert(r == 0);
+  comp->release();
 }
 
 void JournalMetadata::allocate_tag(uint64_t tag_class, const bufferlist &data,
@@ -434,48 +436,37 @@ void JournalMetadata::set_active_set(uint64_t object_set) {
 }
 
 void JournalMetadata::flush_commit_position() {
-
   ldout(m_cct, 20) << __func__ << dendl;
 
-  {
-    Mutex::Locker timer_locker(m_timer_lock);
-    Mutex::Locker locker(m_lock);
-    if (m_commit_position_task_ctx == NULL) {
-      return;
-    }
-
-    m_timer->cancel_event(m_commit_position_task_ctx);
-    m_commit_position_task_ctx = NULL;
+  Mutex::Locker timer_locker(*m_timer_lock);
+  Mutex::Locker locker(m_lock);
+  if (m_commit_position_ctx == nullptr) {
+    return;
   }
+
+  cancel_commit_task();
   handle_commit_position_task();
 }
 
-void JournalMetadata::set_commit_position(
-    const ObjectSetPosition &commit_position, Context *on_safe) {
-  assert(on_safe != NULL);
-
-  Context *stale_ctx = nullptr;
-  {
-    Mutex::Locker timer_locker(m_timer_lock);
-    Mutex::Locker locker(m_lock);
-    ldout(m_cct, 20) << __func__ << ": current=" << m_client.commit_position
-                     << ", new=" << commit_position << dendl;
-    if (entry_positions_less_equal(commit_position, m_client.commit_position) ||
-        entry_positions_less_equal(commit_position, m_commit_position)) {
-      stale_ctx = on_safe;
-    } else {
-      stale_ctx = m_commit_position_ctx;
+void JournalMetadata::flush_commit_position(Context *on_safe) {
+  ldout(m_cct, 20) << __func__ << dendl;
 
-      m_client.commit_position = commit_position;
-      m_commit_position = commit_position;
-      m_commit_position_ctx = on_safe;
-      schedule_commit_task();
+  Mutex::Locker timer_locker(*m_timer_lock);
+  Mutex::Locker locker(m_lock);
+  if (m_commit_position_ctx == nullptr) {
+    // nothing to flush
+    if (on_safe != nullptr) {
+      m_work_queue->queue(on_safe, 0);
     }
+    return;
   }
 
-  if (stale_ctx != nullptr) {
-    stale_ctx->complete(-ESTALE);
+  if (on_safe != nullptr) {
+    m_commit_position_ctx = new C_FlushCommitPosition(
+      m_commit_position_ctx, on_safe);
   }
+  cancel_commit_task();
+  handle_commit_position_task();
 }
 
 void JournalMetadata::reserve_entry_tid(uint64_t tag_tid, uint64_t entry_tid) {
@@ -515,9 +506,8 @@ void JournalMetadata::handle_immutable_metadata(int r, Context *on_init) {
 void JournalMetadata::refresh(Context *on_complete) {
   ldout(m_cct, 10) << "refreshing mutable metadata" << dendl;
   C_Refresh *refresh = new C_Refresh(this, on_complete);
-  client::get_mutable_metadata(m_ioctx, m_oid, &refresh->minimum_set,
-                               &refresh->active_set,
-                               &refresh->registered_clients, refresh);
+  get_mutable_metadata(&refresh->minimum_set, &refresh->active_set,
+		       &refresh->registered_clients, refresh);
 }
 
 void JournalMetadata::handle_refresh_complete(C_Refresh *refresh, int r) {
@@ -528,8 +518,8 @@ void JournalMetadata::handle_refresh_complete(C_Refresh *refresh, int r) {
     Client client(m_client_id, bufferlist());
     RegisteredClients::iterator it = refresh->registered_clients.find(client);
     if (it != refresh->registered_clients.end()) {
-      m_minimum_set = refresh->minimum_set;
-      m_active_set = refresh->active_set;
+      m_minimum_set = MAX(m_minimum_set, refresh->minimum_set);
+      m_active_set = MAX(m_active_set, refresh->active_set);
       m_registered_clients = refresh->registered_clients;
       m_client = *it;
 
@@ -554,13 +544,24 @@ void JournalMetadata::handle_refresh_complete(C_Refresh *refresh, int r) {
   }
 }
 
-void JournalMetadata::schedule_commit_task() {
-
+void JournalMetadata::cancel_commit_task() {
   ldout(m_cct, 20) << __func__ << dendl;
 
-  assert(m_timer_lock.is_locked());
+  assert(m_timer_lock->is_locked());
   assert(m_lock.is_locked());
+  assert(m_commit_position_ctx != nullptr);
+  assert(m_commit_position_task_ctx != nullptr);
+
+  m_timer->cancel_event(m_commit_position_task_ctx);
+  m_commit_position_task_ctx = NULL;
+}
+
+void JournalMetadata::schedule_commit_task() {
+  ldout(m_cct, 20) << __func__ << dendl;
 
+  assert(m_timer_lock->is_locked());
+  assert(m_lock.is_locked());
+  assert(m_commit_position_ctx != nullptr);
   if (m_commit_position_task_ctx == NULL) {
     m_commit_position_task_ctx = new C_CommitPositionTask(this);
     m_timer->add_event_after(m_commit_interval, m_commit_position_task_ctx);
@@ -568,10 +569,11 @@ void JournalMetadata::schedule_commit_task() {
 }
 
 void JournalMetadata::handle_commit_position_task() {
-
-  ldout(m_cct, 20) << __func__ << dendl;
-
-  Mutex::Locker locker(m_lock);
+  assert(m_timer_lock->is_locked());
+  assert(m_lock.is_locked());
+  ldout(m_cct, 20) << __func__ << ": "
+                   << "client_id=" << m_client_id << ", "
+                   << "commit_position=" << m_commit_position << dendl;
 
   librados::ObjectWriteOperation op;
   client::client_commit(&op, m_client_id, m_commit_position);
@@ -590,12 +592,12 @@ void JournalMetadata::handle_commit_position_task() {
 }
 
 void JournalMetadata::schedule_watch_reset() {
-  assert(m_timer_lock.is_locked());
+  assert(m_timer_lock->is_locked());
   m_timer->add_event_after(0.1, new C_WatchReset(this));
 }
 
 void JournalMetadata::handle_watch_reset() {
-  assert(m_timer_lock.is_locked());
+  assert(m_timer_lock->is_locked());
   if (!m_initialized) {
     return;
   }
@@ -622,7 +624,7 @@ void JournalMetadata::handle_watch_notify(uint64_t notify_id, uint64_t cookie) {
 
 void JournalMetadata::handle_watch_error(int err) {
   lderr(m_cct) << "journal watch error: " << cpp_strerror(err) << dendl;
-  Mutex::Locker timer_locker(m_timer_lock);
+  Mutex::Locker timer_locker(*m_timer_lock);
   Mutex::Locker locker(m_lock);
 
   // release old watch on error
@@ -646,68 +648,84 @@ uint64_t JournalMetadata::allocate_commit_tid(uint64_t object_num,
 
   ldout(m_cct, 20) << "allocated commit tid: commit_tid=" << commit_tid << " ["
                    << "object_num=" << object_num << ", "
-                   << "tag_tid=" << tag_tid << ", entry_tid=" << entry_tid << "]"
+                   << "tag_tid=" << tag_tid << ", "
+                   << "entry_tid=" << entry_tid << "]"
                    << dendl;
   return commit_tid;
 }
 
-bool JournalMetadata::committed(uint64_t commit_tid,
-                                ObjectSetPosition *object_set_position) {
+void JournalMetadata::committed(uint64_t commit_tid,
+                                const CreateContext &create_context) {
   ldout(m_cct, 20) << "committed tid=" << commit_tid << dendl;
 
-  Mutex::Locker locker(m_lock);
+  ObjectSetPosition commit_position;
+  Context *stale_ctx = nullptr;
   {
+    Mutex::Locker timer_locker(*m_timer_lock);
+    Mutex::Locker locker(m_lock);
+    assert(commit_tid > m_commit_position_tid);
+
+    if (!m_commit_position.object_positions.empty()) {
+      // in-flight commit position update
+      commit_position = m_commit_position;
+    } else {
+      // safe commit position
+      commit_position = m_client.commit_position;
+    }
+
     CommitTids::iterator it = m_pending_commit_tids.find(commit_tid);
     assert(it != m_pending_commit_tids.end());
 
     CommitEntry &commit_entry = it->second;
     commit_entry.committed = true;
-  }
 
-  if (!m_commit_position.entry_positions.empty()) {
-    *object_set_position = m_commit_position;
-  } else {
-    *object_set_position = m_client.commit_position;
-  }
+    bool update_commit_position = false;
+    while (!m_pending_commit_tids.empty()) {
+      CommitTids::iterator it = m_pending_commit_tids.begin();
+      CommitEntry &commit_entry = it->second;
+      if (!commit_entry.committed) {
+        break;
+      }
 
-  bool update_commit_position = false;
-  while (!m_pending_commit_tids.empty()) {
-    CommitTids::iterator it = m_pending_commit_tids.begin();
-    CommitEntry &commit_entry = it->second;
-    if (!commit_entry.committed) {
-      break;
+      commit_position.object_positions.emplace_front(
+        commit_entry.object_num, commit_entry.tag_tid,
+        commit_entry.entry_tid);
+      m_pending_commit_tids.erase(it);
+      update_commit_position = true;
     }
 
-    object_set_position->object_number = commit_entry.object_num;
-    if (!object_set_position->entry_positions.empty() &&
-        object_set_position->entry_positions.front().tag_tid ==
-          commit_entry.tag_tid) {
-      object_set_position->entry_positions.front() = EntryPosition(
-        commit_entry.tag_tid, commit_entry.entry_tid);
-    } else {
-      object_set_position->entry_positions.push_front(EntryPosition(
-        commit_entry.tag_tid, commit_entry.entry_tid));
+    if (!update_commit_position) {
+      return;
     }
-    m_pending_commit_tids.erase(it);
-    update_commit_position = true;
-  }
 
-  if (update_commit_position) {
-    // prune the position to have unique tags in commit-order
-    std::set<uint64_t> in_use_tag_tids;
-    EntryPositions::iterator it = object_set_position->entry_positions.begin();
-    while (it != object_set_position->entry_positions.end()) {
-      if (!in_use_tag_tids.insert(it->tag_tid).second) {
-        it = object_set_position->entry_positions.erase(it);
+    // prune the position to have one position per splay offset
+    std::set<uint8_t> in_use_splay_offsets;
+    ObjectPositions::iterator ob_it = commit_position.object_positions.begin();
+    while (ob_it != commit_position.object_positions.end()) {
+      uint8_t splay_offset = ob_it->object_number % m_splay_width;
+      if (!in_use_splay_offsets.insert(splay_offset).second) {
+        ob_it = commit_position.object_positions.erase(ob_it);
       } else {
-        ++it;
+        ++ob_it;
       }
     }
 
-    ldout(m_cct, 20) << "updated object set position: " << *object_set_position
+    stale_ctx = m_commit_position_ctx;
+    m_commit_position_ctx = create_context();
+    m_commit_position = commit_position;
+    m_commit_position_tid = commit_tid;
+
+    ldout(m_cct, 20) << "updated commit position: " << commit_position << ", "
+                     << "on_safe=" << m_commit_position_ctx << dendl;
+    schedule_commit_task();
+  }
+
+
+  if (stale_ctx != nullptr) {
+    ldout(m_cct, 20) << "canceling stale commit: on_safe=" << stale_ctx
                      << dendl;
+    stale_ctx->complete(-ESTALE);
   }
-  return update_commit_position;
 }
 
 void JournalMetadata::notify_update() {
diff --git a/src/journal/JournalMetadata.h b/src/journal/JournalMetadata.h
index 450169b..8bedb98 100644
--- a/src/journal/JournalMetadata.h
+++ b/src/journal/JournalMetadata.h
@@ -10,17 +10,18 @@
 #include "common/Cond.h"
 #include "common/Mutex.h"
 #include "common/RefCountedObj.h"
+#include "common/WorkQueue.h"
 #include "cls/journal/cls_journal_types.h"
 #include "journal/AsyncOpTracker.h"
 #include <boost/intrusive_ptr.hpp>
 #include <boost/noncopyable.hpp>
 #include <boost/optional.hpp>
+#include <functional>
 #include <list>
 #include <map>
 #include <string>
 #include "include/assert.h"
 
-class Finisher;
 class SafeTimer;
 
 namespace journal {
@@ -30,8 +31,9 @@ typedef boost::intrusive_ptr<JournalMetadata> JournalMetadataPtr;
 
 class JournalMetadata : public RefCountedObject, boost::noncopyable {
 public:
-  typedef cls::journal::EntryPosition EntryPosition;
-  typedef cls::journal::EntryPositions EntryPositions;
+  typedef std::function<Context*()> CreateContext;
+  typedef cls::journal::ObjectPosition ObjectPosition;
+  typedef cls::journal::ObjectPositions ObjectPositions;
   typedef cls::journal::ObjectSetPosition ObjectSetPosition;
   typedef cls::journal::Client Client;
   typedef cls::journal::Tag Tag;
@@ -44,18 +46,28 @@ public:
     virtual void handle_update(JournalMetadata *) = 0;
   };
 
-  JournalMetadata(librados::IoCtx &ioctx, const std::string &oid,
+  JournalMetadata(ContextWQ *work_queue, SafeTimer *timer, Mutex *timer_lock,
+                  librados::IoCtx &ioctx, const std::string &oid,
                   const std::string &client_id, double commit_interval);
   ~JournalMetadata();
 
   void init(Context *on_init);
-  void shutdown();
+  void shut_down();
+
+  bool is_initialized() const { return m_initialized; }
+
+  void get_immutable_metadata(uint8_t *order, uint8_t *splay_width,
+			      int64_t *pool_id, Context *on_finish);
+
+  void get_mutable_metadata(uint64_t *minimum_set, uint64_t *active_set,
+			    RegisteredClients *clients, Context *on_finish);
 
   void add_listener(Listener *listener);
   void remove_listener(Listener *listener);
 
-  int register_client(const bufferlist &data);
-  int unregister_client();
+  void register_client(const bufferlist &data, Context *on_finish);
+  void update_client(const bufferlist &data, Context *on_finish);
+  void unregister_client(Context *on_finish);
 
   void allocate_tag(uint64_t tag_class, const bufferlist &data,
                     Tag *tag, Context *on_finish);
@@ -75,15 +87,15 @@ public:
     return m_pool_id;
   }
 
-  inline Finisher &get_finisher() {
-    return *m_finisher;
+  inline void queue(Context *on_finish, int r) {
+    m_work_queue->queue(on_finish, r);
   }
 
   inline SafeTimer &get_timer() {
     return *m_timer;
   }
   inline Mutex &get_timer_lock() {
-    return m_timer_lock;
+    return *m_timer_lock;
   }
 
   void set_minimum_set(uint64_t object_set);
@@ -99,8 +111,7 @@ public:
   }
 
   void flush_commit_position();
-  void set_commit_position(const ObjectSetPosition &commit_position,
-                           Context *on_safe);
+  void flush_commit_position(Context *on_safe);
   void get_commit_position(ObjectSetPosition *commit_position) const {
     Mutex::Locker locker(m_lock);
     *commit_position = m_client.commit_position;
@@ -120,7 +131,7 @@ public:
 
   uint64_t allocate_commit_tid(uint64_t object_num, uint64_t tag_tid,
                                uint64_t entry_tid);
-  bool committed(uint64_t commit_tid, ObjectSetPosition *object_set_position);
+  void committed(uint64_t commit_tid, const CreateContext &create_context);
 
   void notify_update();
   void async_notify_update();
@@ -185,6 +196,7 @@ private:
       journal_metadata->m_async_op_tracker.finish_op();
     }
     virtual void finish(int r) {
+      Mutex::Locker locker(journal_metadata->m_lock);
       journal_metadata->handle_commit_position_task();
     };
   };
@@ -274,9 +286,9 @@ private:
   int64_t m_pool_id;
   bool m_initialized;
 
-  Finisher *m_finisher;
+  ContextWQ *m_work_queue;
   SafeTimer *m_timer;
-  Mutex m_timer_lock;
+  Mutex *m_timer_lock;
 
   mutable Mutex m_lock;
 
@@ -298,6 +310,7 @@ private:
   size_t m_update_notifications;
   Cond m_update_cond;
 
+  uint64_t m_commit_position_tid = 0;
   ObjectSetPosition m_commit_position;
   Context *m_commit_position_ctx;
   Context *m_commit_position_task_ctx;
@@ -309,6 +322,7 @@ private:
   void refresh(Context *on_finish);
   void handle_refresh_complete(C_Refresh *refresh, int r);
 
+  void cancel_commit_task();
   void schedule_commit_task();
   void handle_commit_position_task();
 
diff --git a/src/journal/JournalPlayer.cc b/src/journal/JournalPlayer.cc
index 45505a3..0d6b177 100644
--- a/src/journal/JournalPlayer.cc
+++ b/src/journal/JournalPlayer.cc
@@ -2,7 +2,6 @@
 // vim: ts=8 sw=2 smarttab
 
 #include "journal/JournalPlayer.h"
-#include "common/Finisher.h"
 #include "journal/Entry.h"
 #include "journal/ReplayHandler.h"
 #include "journal/Utils.h"
@@ -55,30 +54,36 @@ JournalPlayer::JournalPlayer(librados::IoCtx &ioctx,
     m_journal_metadata(journal_metadata), m_replay_handler(replay_handler),
     m_lock("JournalPlayer::m_lock"), m_state(STATE_INIT), m_splay_offset(0),
     m_watch_enabled(false), m_watch_scheduled(false), m_watch_interval(0),
-    m_commit_object(0), m_commit_tag_tid(0) {
+    m_commit_object(0) {
   m_replay_handler->get();
   m_ioctx.dup(ioctx);
   m_cct = reinterpret_cast<CephContext *>(m_ioctx.cct());
 
   ObjectSetPosition commit_position;
   m_journal_metadata->get_commit_position(&commit_position);
-  if (!commit_position.entry_positions.empty()) {
+
+  if (!commit_position.object_positions.empty()) {
+    ldout(m_cct, 5) << "commit position: " << commit_position << dendl;
+
+    // start replay after the last committed entry's object
     uint8_t splay_width = m_journal_metadata->get_splay_width();
-    m_splay_offset = commit_position.object_number % splay_width;
-    m_commit_object = commit_position.object_number;
-    m_commit_tag_tid = commit_position.entry_positions.front().tag_tid;
-
-    for (EntryPositions::const_iterator it =
-           commit_position.entry_positions.begin();
-         it != commit_position.entry_positions.end(); ++it) {
-      const EntryPosition &entry_position = *it;
-      m_commit_tids[entry_position.tag_tid] = entry_position.entry_tid;
+    auto &active_position = commit_position.object_positions.front();
+    m_active_tag_tid = active_position.tag_tid;
+    m_commit_object = active_position.object_number;
+    m_splay_offset = m_commit_object % splay_width;
+    for (auto &position : commit_position.object_positions) {
+      uint8_t splay_offset = position.object_number % splay_width;
+      m_commit_positions[splay_offset] = position;
     }
   }
 }
 
 JournalPlayer::~JournalPlayer() {
   m_async_op_tracker.wait_for_ops();
+  {
+    Mutex::Locker locker(m_lock);
+    assert(m_fetch_object_numbers.empty());
+  }
   m_replay_handler->put();
 }
 
@@ -88,22 +93,38 @@ void JournalPlayer::prefetch() {
   m_state = STATE_PREFETCH;
 
   uint8_t splay_width = m_journal_metadata->get_splay_width();
-  for (uint8_t splay_index = 0; splay_index < splay_width; ++splay_index) {
-    m_prefetch_splay_offsets.insert(splay_index);
+  for (uint8_t splay_offset = 0; splay_offset < splay_width; ++splay_offset) {
+    m_prefetch_splay_offsets.insert(splay_offset);
+  }
+
+  // compute active object for each splay offset (might be before
+  // active set)
+  std::map<uint8_t, uint64_t> splay_offset_to_objects;
+  for (auto &position : m_commit_positions) {
+    assert(splay_offset_to_objects.count(position.first) == 0);
+    splay_offset_to_objects[position.first] = position.second.object_number;
   }
 
-  uint64_t object_set = m_commit_object / splay_width;
+  // prefetch the active object for each splay offset (and the following object)
   uint64_t active_set = m_journal_metadata->get_active_set();
+  uint64_t max_object_number = (splay_width * (active_set + 1)) - 1;
+  std::set<uint64_t> prefetch_object_numbers;
+  for (uint8_t splay_offset = 0; splay_offset < splay_width; ++splay_offset) {
+    uint64_t object_number = splay_offset;
+    if (splay_offset_to_objects.count(splay_offset) != 0) {
+      object_number = splay_offset_to_objects[splay_offset];
+    }
 
-  uint32_t object_count = splay_width *
-                          std::min<uint64_t>(2, active_set - object_set + 1);
-  ldout(m_cct, 10) << __func__ << ": prefetching " << object_count << " "
-                   << "objects" << dendl;
+    prefetch_object_numbers.insert(object_number);
+    if (object_number + splay_width <= max_object_number) {
+      prefetch_object_numbers.insert(object_number + splay_width);
+    }
+  }
 
-  // prefetch starting from the last known commit set
-  uint64_t start_object = object_set * splay_width;
-  for (uint64_t object_number = start_object;
-       object_number < start_object + object_count; ++object_number) {
+  ldout(m_cct, 10) << __func__ << ": prefetching "
+                   << prefetch_object_numbers.size() << " " << "objects"
+                   << dendl;
+  for (auto object_number : prefetch_object_numbers) {
     fetch(object_number);
   }
 }
@@ -118,13 +139,13 @@ void JournalPlayer::prefetch_and_watch(double interval) {
 }
 
 void JournalPlayer::unwatch() {
+  ldout(m_cct, 20) << __func__ << dendl;
   Mutex::Locker locker(m_lock);
   m_watch_enabled = false;
   if (m_watch_scheduled) {
-    ObjectPlayerPtr object_player = get_object_player();
-    assert(object_player);
-
-    object_player->unwatch();
+    for (auto &players : m_object_players) {
+      players.second.begin()->second->unwatch();
+    }
     m_watch_scheduled = false;
   }
 }
@@ -132,56 +153,51 @@ void JournalPlayer::unwatch() {
 bool JournalPlayer::try_pop_front(Entry *entry, uint64_t *commit_tid) {
   ldout(m_cct, 20) << __func__ << dendl;
   Mutex::Locker locker(m_lock);
+
+  m_handler_notified = false;
   if (m_state != STATE_PLAYBACK) {
     return false;
   }
 
-  ObjectPlayerPtr object_player = get_object_player();
-  assert(object_player);
+  if (!is_object_set_ready()) {
+    return false;
+  }
 
-  if (object_player->empty()) {
-    if (m_watch_enabled && !m_watch_scheduled) {
-      object_player->watch(
-        new C_Watch(this, object_player->get_object_number()),
-        m_watch_interval);
-      m_watch_scheduled = true;
-    } else if (!m_watch_enabled && !object_player->is_fetch_in_progress()) {
-      ldout(m_cct, 10) << __func__ << ": replay complete" << dendl;
-      m_journal_metadata->get_finisher().queue(new C_HandleComplete(
-        m_replay_handler), 0);
+  if (!verify_playback_ready()) {
+    if (!m_watch_enabled) {
+      notify_complete(0);
+    } else if (!m_watch_scheduled) {
+      schedule_watch();
     }
     return false;
   }
 
+  ObjectPlayerPtr object_player = get_object_player();
+  assert(object_player && !object_player->empty());
+
   object_player->front(entry);
   object_player->pop_front();
 
   uint64_t last_entry_tid;
-  if (m_journal_metadata->get_last_allocated_entry_tid(
-        entry->get_tag_tid(), &last_entry_tid) &&
-      entry->get_entry_tid() != last_entry_tid + 1) {
+  if (m_active_tag_tid && *m_active_tag_tid != entry->get_tag_tid()) {
+    lderr(m_cct) << "unexpected tag in journal entry: " << *entry << dendl;
+
+    m_state = STATE_ERROR;
+    notify_complete(-ENOMSG);
+    return false;
+  } else if (m_journal_metadata->get_last_allocated_entry_tid(
+               entry->get_tag_tid(), &last_entry_tid) &&
+             entry->get_entry_tid() != last_entry_tid + 1) {
     lderr(m_cct) << "missing prior journal entry: " << *entry << dendl;
 
     m_state = STATE_ERROR;
-    m_journal_metadata->get_finisher().queue(new C_HandleComplete(
-      m_replay_handler), -EINVAL);
+    notify_complete(-ENOMSG);
     return false;
   }
 
-  // skip to next splay offset if we cannot apply the next entry in-sequence
-  if (!object_player->empty()) {
-    Entry peek_entry;
-    object_player->front(&peek_entry);
-    if (peek_entry.get_tag_tid() == entry->get_tag_tid() ||
-        (m_journal_metadata->get_last_allocated_entry_tid(
-           peek_entry.get_tag_tid(), &last_entry_tid) &&
-         last_entry_tid + 1 != peek_entry.get_entry_tid())) {
-      advance_splay_object();
-    }
-  } else {
-    advance_splay_object();
-    remove_empty_object_player(object_player);
-  }
+  m_active_tag_tid = entry->get_tag_tid();
+  advance_splay_object();
+  remove_empty_object_player(object_player);
 
   m_journal_metadata->reserve_entry_tid(entry->get_tag_tid(),
                                         entry->get_entry_tid());
@@ -194,8 +210,9 @@ bool JournalPlayer::try_pop_front(Entry *entry, uint64_t *commit_tid) {
 void JournalPlayer::process_state(uint64_t object_number, int r) {
   ldout(m_cct, 10) << __func__ << ": object_num=" << object_number << ", "
                    << "r=" << r << dendl;
+
+  assert(m_lock.is_locked());
   if (r >= 0) {
-    Mutex::Locker locker(m_lock);
     switch (m_state) {
     case STATE_PREFETCH:
       ldout(m_cct, 10) << "PREFETCH" << dendl;
@@ -216,11 +233,8 @@ void JournalPlayer::process_state(uint64_t object_number, int r) {
   }
 
   if (r < 0) {
-    {
-      Mutex::Locker locker(m_lock);
-      m_state = STATE_ERROR;
-    }
-    m_replay_handler->handle_complete(r);
+    m_state = STATE_ERROR;
+    notify_complete(r);
   }
 }
 
@@ -242,17 +256,28 @@ int JournalPlayer::process_prefetch(uint64_t object_number) {
   ObjectPlayers &object_players = m_object_players[splay_offset];
 
   // prefetch in-order since a newer splay object could prefetch first
-  while (!object_players.begin()->second->is_fetch_in_progress()) {
+  while (m_fetch_object_numbers.count(
+           object_players.begin()->second->get_object_number()) == 0) {
     ObjectPlayerPtr object_player = object_players.begin()->second;
+    uint64_t player_object_number = object_player->get_object_number();
 
     // skip past known committed records
-    if (!m_commit_tids.empty() && !object_player->empty()) {
-      ldout(m_cct, 15) << "seeking known commit position in "
+    if (m_commit_positions.count(splay_offset) != 0 &&
+        !object_player->empty()) {
+      ObjectPosition &position = m_commit_positions[splay_offset];
+
+      ldout(m_cct, 15) << "seeking known commit position " << position << " in "
                        << object_player->get_oid() << dendl;
+
+      bool found_commit = false;
       Entry entry;
-      while (!m_commit_tids.empty() && !object_player->empty()) {
+      while (!object_player->empty()) {
         object_player->front(&entry);
-        if (entry.get_entry_tid() > m_commit_tids[entry.get_tag_tid()]) {
+
+        if (entry.get_tag_tid() == position.tag_tid &&
+            entry.get_entry_tid() == position.entry_tid) {
+          found_commit = true;
+        } else if (found_commit) {
           ldout(m_cct, 10) << "located next uncommitted entry: " << entry
                            << dendl;
           break;
@@ -266,18 +291,23 @@ int JournalPlayer::process_prefetch(uint64_t object_number) {
 
       // if this object contains the commit position, our read should start with
       // the next consistent journal entry in the sequence
-      if (!m_commit_tids.empty() &&
-          object_player->get_object_number() == m_commit_object) {
+      if (player_object_number == m_commit_object) {
         if (object_player->empty()) {
           advance_splay_object();
         } else {
           Entry entry;
           object_player->front(&entry);
-          if (entry.get_tag_tid() == m_commit_tag_tid) {
+          if (entry.get_tag_tid() == position.tag_tid) {
             advance_splay_object();
           }
         }
       }
+
+      // do not search for commit position for this object
+      // if we've already seen it
+      if (found_commit) {
+        m_commit_positions.erase(splay_offset);
+      }
     }
 
     // if the object is empty, pre-fetch the next splay object
@@ -297,21 +327,16 @@ int JournalPlayer::process_prefetch(uint64_t object_number) {
   }
 
   m_state = STATE_PLAYBACK;
-  ObjectPlayerPtr object_player = get_object_player();
-  if (!object_player->empty()) {
-    ldout(m_cct, 10) << __func__ << ": entries available" << dendl;
-    m_journal_metadata->get_finisher().queue(new C_HandleEntriesAvailable(
-      m_replay_handler), 0);
+  if (!is_object_set_ready()) {
+    ldout(m_cct, 10) << __func__ << ": waiting for full object set" << dendl;
+  } else if (verify_playback_ready()) {
+    notify_entries_available();
   } else if (m_watch_enabled) {
-    object_player->watch(
-      new C_Watch(this, object_player->get_object_number()),
-      m_watch_interval);
-    m_watch_scheduled = true;
+    schedule_watch();
   } else {
     ldout(m_cct, 10) << __func__ << ": no uncommitted entries available"
                      << dendl;
-    m_journal_metadata->get_finisher().queue(new C_HandleComplete(
-      m_replay_handler), 0);
+    notify_complete(0);
   }
   return 0;
 }
@@ -320,26 +345,84 @@ int JournalPlayer::process_playback(uint64_t object_number) {
   ldout(m_cct, 10) << __func__ << ": object_num=" << object_number << dendl;
   assert(m_lock.is_locked());
 
-  m_watch_scheduled = false;
+  if (!is_object_set_ready()) {
+    return 0;
+  }
 
   ObjectPlayerPtr object_player = get_object_player();
-  if (object_player->get_object_number() == object_number) {
+  if (verify_playback_ready()) {
+    notify_entries_available();
+  } else if (m_watch_enabled) {
+    schedule_watch();
+  } else {
     uint8_t splay_width = m_journal_metadata->get_splay_width();
     uint64_t active_set = m_journal_metadata->get_active_set();
     uint64_t object_set = object_player->get_object_number() / splay_width;
-    if (!object_player->empty()) {
-      ldout(m_cct, 10) << __func__ << ": entries available" << dendl;
-      m_journal_metadata->get_finisher().queue(new C_HandleEntriesAvailable(
-        m_replay_handler), 0);
-    } else if (object_set == active_set) {
-      ldout(m_cct, 10) << __func__ << ": replay complete" << dendl;
-      m_journal_metadata->get_finisher().queue(new C_HandleComplete(
-        m_replay_handler), 0);
+    if (object_set == active_set) {
+      notify_complete(0);
     }
   }
   return 0;
 }
 
+bool JournalPlayer::is_object_set_ready() const {
+  assert(m_lock.is_locked());
+  if (m_watch_scheduled || !m_fetch_object_numbers.empty()) {
+    return false;
+  }
+  return true;
+}
+
+bool JournalPlayer::verify_playback_ready() {
+  assert(m_lock.is_locked());
+  assert(is_object_set_ready());
+
+  ObjectPlayerPtr object_player = get_object_player();
+  assert(object_player);
+
+  // Verify is the active object player has another entry available
+  // in the sequence
+  Entry entry;
+  bool entry_available = false;
+  if (!object_player->empty()) {
+    entry_available = true;
+    object_player->front(&entry);
+    if (!m_active_tag_tid || entry.get_tag_tid() == *m_active_tag_tid) {
+      return true;
+    }
+  }
+
+  // if we just advanced to this object, make sure we have the latest
+  // set of data before advancing to a new tag
+  if (m_watch_enabled && m_watch_required) {
+    m_watch_required = false;
+    schedule_watch();
+    return false;
+  }
+
+  // NOTE: replay currently does not check tag class to playback multiple tags
+  // from different classes (issue #14909).  When a new tag is discovered, it
+  // is assumed that the previous tag was closed at the last replayable entry.
+  object_player = m_object_players.begin()->second.begin()->second;
+  if (!object_player->empty() && m_active_tag_tid) {
+    object_player->front(&entry);
+    if (entry.get_tag_tid() > *m_active_tag_tid &&
+        entry.get_entry_tid() == 0) {
+      uint8_t splay_width = m_journal_metadata->get_splay_width();
+      m_active_tag_tid = entry.get_tag_tid();
+      m_splay_offset = object_player->get_object_number() / splay_width;
+
+      ldout(m_cct, 20) << __func__ << ": new tag " << entry.get_tag_tid() << " "
+                       << "detected, adjusting offset to "
+                       << static_cast<uint32_t>(m_splay_offset) << dendl;
+      return true;
+    }
+  }
+
+  // if any entry is available, we can test if the sequence is corrupt
+  return entry_available;
+}
+
 const JournalPlayer::ObjectPlayers &JournalPlayer::get_object_players() const {
   assert(m_lock.is_locked());
 
@@ -368,12 +451,14 @@ void JournalPlayer::advance_splay_object() {
   assert(m_lock.is_locked());
   ++m_splay_offset;
   m_splay_offset %= m_journal_metadata->get_splay_width();
+  m_watch_required = true;
   ldout(m_cct, 20) << __func__ << ": new offset "
                    << static_cast<uint32_t>(m_splay_offset) << dendl;
 }
 
 bool JournalPlayer::remove_empty_object_player(const ObjectPlayerPtr &player) {
   assert(m_lock.is_locked());
+  assert(!m_watch_scheduled);
 
   uint8_t splay_width = m_journal_metadata->get_splay_width();
   uint64_t object_set = player->get_object_number() / splay_width;
@@ -401,6 +486,9 @@ void JournalPlayer::fetch(uint64_t object_num) {
 
   std::string oid = utils::get_object_name(m_object_oid_prefix, object_num);
 
+  assert(m_fetch_object_numbers.count(object_num) == 0);
+  m_fetch_object_numbers.insert(object_num);
+
   ldout(m_cct, 10) << __func__ << ": " << oid << dendl;
   C_Fetch *fetch_ctx = new C_Fetch(this, object_num);
   ObjectPlayerPtr object_player(new ObjectPlayer(
@@ -416,11 +504,15 @@ void JournalPlayer::handle_fetched(uint64_t object_num, int r) {
   ldout(m_cct, 10) << __func__ << ": "
                    << utils::get_object_name(m_object_oid_prefix, object_num)
                    << ": r=" << r << dendl;
+
+  Mutex::Locker locker(m_lock);
+  assert(m_fetch_object_numbers.count(object_num) == 1);
+  m_fetch_object_numbers.erase(object_num);
+
   if (r == -ENOENT) {
     r = 0;
   }
   if (r == 0) {
-    Mutex::Locker locker(m_lock);
     uint8_t splay_width = m_journal_metadata->get_splay_width();
     uint8_t splay_offset = object_num % splay_width;
     assert(m_object_players.count(splay_offset) == 1);
@@ -430,15 +522,67 @@ void JournalPlayer::handle_fetched(uint64_t object_num, int r) {
     ObjectPlayerPtr object_player = object_players[object_num];
     remove_empty_object_player(object_player);
   }
-
   process_state(object_num, r);
 }
 
-void JournalPlayer::handle_watch(uint64_t object_num, int r) {
-  ldout(m_cct, 10) << __func__ << ": "
-                   << utils::get_object_name(m_object_oid_prefix, object_num)
-                   << ": r=" << r << dendl;
-  process_state(object_num, r);
+void JournalPlayer::schedule_watch() {
+  ldout(m_cct, 10) << __func__ << dendl;
+  assert(m_lock.is_locked());
+  if (m_watch_scheduled) {
+    return;
+  }
+
+  // poll first splay offset and active splay offset since
+  // new records should only appear in those two objects
+  C_Watch *ctx = new C_Watch(this);
+  ObjectPlayerPtr object_player = get_object_player();
+  object_player->watch(ctx, m_watch_interval);
+
+  uint8_t splay_width = m_journal_metadata->get_splay_width();
+  if (object_player->get_object_number() % splay_width != 0) {
+    ++ctx->pending_fetches;
+
+    object_player = m_object_players.begin()->second.begin()->second;
+    object_player->watch(ctx, m_watch_interval);
+  }
+  m_watch_scheduled = true;
+}
+
+void JournalPlayer::handle_watch(int r) {
+  ldout(m_cct, 10) << __func__ << ": r=" << r << dendl;
+
+  Mutex::Locker locker(m_lock);
+  m_watch_scheduled = false;
+  std::set<uint64_t> object_numbers;
+  for (auto &players : m_object_players) {
+    object_numbers.insert(
+      players.second.begin()->second->get_object_number());
+  }
+
+  for (auto object_num : object_numbers) {
+    process_state(object_num, r);
+  }
+}
+
+void JournalPlayer::notify_entries_available() {
+  assert(m_lock.is_locked());
+  if (m_handler_notified) {
+    return;
+  }
+  m_handler_notified = true;
+
+  ldout(m_cct, 10) << __func__ << ": entries available" << dendl;
+  m_journal_metadata->queue(new C_HandleEntriesAvailable(
+    m_replay_handler), 0);
+}
+
+void JournalPlayer::notify_complete(int r) {
+  assert(m_lock.is_locked());
+  m_handler_notified = true;
+
+  ldout(m_cct, 10) << __func__ << ": replay complete: r=" << r << dendl;
+  m_journal_metadata->queue(new C_HandleComplete(
+    m_replay_handler), r);
 }
 
 } // namespace journal
diff --git a/src/journal/JournalPlayer.h b/src/journal/JournalPlayer.h
index 1e7bdff..476b49b 100644
--- a/src/journal/JournalPlayer.h
+++ b/src/journal/JournalPlayer.h
@@ -12,6 +12,8 @@
 #include "journal/JournalMetadata.h"
 #include "journal/ObjectPlayer.h"
 #include "cls/journal/cls_journal_types.h"
+#include <boost/none.hpp>
+#include <boost/optional.hpp>
 #include <map>
 
 class SafeTimer;
@@ -23,8 +25,8 @@ class ReplayHandler;
 
 class JournalPlayer {
 public:
-  typedef cls::journal::EntryPosition EntryPosition;
-  typedef cls::journal::EntryPositions EntryPositions;
+  typedef cls::journal::ObjectPosition ObjectPosition;
+  typedef cls::journal::ObjectPositions ObjectPositions;
   typedef cls::journal::ObjectSetPosition ObjectSetPosition;
 
   JournalPlayer(librados::IoCtx &ioctx, const std::string &object_oid_prefix,
@@ -40,9 +42,10 @@ public:
 
 private:
   typedef std::set<uint8_t> PrefetchSplayOffsets;
-  typedef std::map<uint64_t, uint64_t> AllocatedEntryTids;
   typedef std::map<uint64_t, ObjectPlayerPtr> ObjectPlayers;
   typedef std::map<uint8_t, ObjectPlayers> SplayedObjectPlayers;
+  typedef std::map<uint8_t, ObjectPosition> SplayedObjectPositions;
+  typedef std::set<uint64_t> ObjectNumbers;
 
   enum State {
     STATE_INIT,
@@ -51,17 +54,6 @@ private:
     STATE_ERROR
   };
 
-  struct C_Watch : public Context {
-    JournalPlayer *player;
-    uint64_t object_num;
-
-    C_Watch(JournalPlayer *p, uint64_t o) : player(p), object_num(o) {
-    }
-    virtual void finish(int r) {
-      player->handle_watch(object_num, r);
-    }
-  };
-
   struct C_Fetch : public Context {
     JournalPlayer *player;
     uint64_t object_num;
@@ -76,6 +68,34 @@ private:
     }
   };
 
+  struct C_Watch : public Context {
+    JournalPlayer *player;
+    uint8_t pending_fetches = 1;
+    int ret_val = 0;
+
+    C_Watch(JournalPlayer *player) : player(player) {
+    }
+
+    virtual void complete(int r) override {
+      player->m_lock.Lock();
+      if (ret_val == 0 && r < 0) {
+        ret_val = r;
+      }
+
+      assert(pending_fetches > 0);
+      if (--pending_fetches == 0) {
+        player->m_lock.Unlock();
+        Context::complete(ret_val);
+      } else {
+        player->m_lock.Unlock();
+      }
+    }
+
+    virtual void finish(int r) override {
+      player->handle_watch(r);
+    }
+  };
+
   librados::IoCtx m_ioctx;
   CephContext *m_cct;
   std::string m_object_oid_prefix;
@@ -92,15 +112,22 @@ private:
   bool m_watch_enabled;
   bool m_watch_scheduled;
   double m_watch_interval;
+  bool m_watch_required = false;
+
+  bool m_handler_notified = false;
+
+  ObjectNumbers m_fetch_object_numbers;
 
   PrefetchSplayOffsets m_prefetch_splay_offsets;
   SplayedObjectPlayers m_object_players;
   uint64_t m_commit_object;
-  uint64_t m_commit_tag_tid;
-  AllocatedEntryTids m_commit_tids;
+  SplayedObjectPositions m_commit_positions;
+  boost::optional<uint64_t> m_active_tag_tid = boost::none;
 
   void advance_splay_object();
 
+  bool is_object_set_ready() const;
+  bool verify_playback_ready();
   const ObjectPlayers &get_object_players() const;
   ObjectPlayerPtr get_object_player() const;
   ObjectPlayerPtr get_next_set_object_player() const;
@@ -112,7 +139,12 @@ private:
 
   void fetch(uint64_t object_num);
   void handle_fetched(uint64_t object_num, int r);
-  void handle_watch(uint64_t object_num, int r);
+
+  void schedule_watch();
+  void handle_watch(int r);
+
+  void notify_entries_available();
+  void notify_complete(int r);
 };
 
 } // namespace journal
diff --git a/src/journal/JournalRecorder.cc b/src/journal/JournalRecorder.cc
index 21ecc2c..065f692 100644
--- a/src/journal/JournalRecorder.cc
+++ b/src/journal/JournalRecorder.cc
@@ -2,7 +2,6 @@
 // vim: ts=8 sw=2 smarttab
 
 #include "journal/JournalRecorder.h"
-#include "common/Finisher.h"
 #include "journal/Entry.h"
 #include "journal/Utils.h"
 
@@ -32,7 +31,7 @@ struct C_Flush : public Context {
     }
     if (pending_flushes.dec() == 0) {
       // ensure all prior callback have been flushed as well
-      journal_metadata->get_finisher().queue(on_finish, ret_val);
+      journal_metadata->queue(on_finish, ret_val);
       delete this;
     }
   }
@@ -81,8 +80,8 @@ Future JournalRecorder::append(uint64_t tag_tid,
   ObjectRecorderPtr object_ptr = get_object(splay_offset);
   uint64_t commit_tid = m_journal_metadata->allocate_commit_tid(
     object_ptr->get_object_number(), tag_tid, entry_tid);
-  FutureImplPtr future(new FutureImpl(m_journal_metadata->get_finisher(),
-                                      tag_tid, entry_tid, commit_tid));
+  FutureImplPtr future(new FutureImpl(m_journal_metadata, tag_tid, entry_tid,
+                                      commit_tid));
   future->init(m_prev_future);
   m_prev_future = future;
 
diff --git a/src/journal/JournalTrimmer.cc b/src/journal/JournalTrimmer.cc
index 9e781ce..68ba5f4 100644
--- a/src/journal/JournalTrimmer.cc
+++ b/src/journal/JournalTrimmer.cc
@@ -5,7 +5,6 @@
 #include "journal/Utils.h"
 #include "common/Cond.h"
 #include "common/errno.h"
-#include "common/Finisher.h"
 #include <limits>
 
 #define dout_subsys ceph_subsys_journaler
@@ -18,13 +17,18 @@ JournalTrimmer::JournalTrimmer(librados::IoCtx &ioctx,
                                const std::string &object_oid_prefix,
                                const JournalMetadataPtr &journal_metadata)
     : m_cct(NULL), m_object_oid_prefix(object_oid_prefix),
-      m_journal_metadata(journal_metadata), m_lock("JournalTrimmer::m_lock"),
-      m_remove_set_pending(false), m_remove_set(0), m_remove_set_ctx(NULL) {
+      m_journal_metadata(journal_metadata), m_metadata_listener(this),
+      m_lock("JournalTrimmer::m_lock"), m_remove_set_pending(false),
+      m_remove_set(0), m_remove_set_ctx(NULL) {
   m_ioctx.dup(ioctx);
   m_cct = reinterpret_cast<CephContext *>(m_ioctx.cct());
+
+  m_journal_metadata->add_listener(&m_metadata_listener);
 }
 
 JournalTrimmer::~JournalTrimmer() {
+  m_journal_metadata->remove_listener(&m_metadata_listener);
+
   m_journal_metadata->flush_commit_position();
   m_async_op_tracker.wait_for_ops();
 }
@@ -63,19 +67,8 @@ int JournalTrimmer::remove_objects(bool force) {
 
 void JournalTrimmer::committed(uint64_t commit_tid) {
   ldout(m_cct, 20) << __func__ << ": commit_tid=" << commit_tid << dendl;
-
-  ObjectSetPosition object_set_position;
-  if (!m_journal_metadata->committed(commit_tid, &object_set_position)) {
-    return;
-  }
-
-  {
-    Mutex::Locker locker(m_lock);
-    m_async_op_tracker.start_op();
-  }
-
-  Context *ctx = new C_CommitPositionSafe(this, object_set_position);
-  m_journal_metadata->set_commit_position(object_set_position, ctx);
+  m_journal_metadata->committed(commit_tid,
+                                m_create_commit_position_safe_context);
 }
 
 void JournalTrimmer::trim_objects(uint64_t minimum_set) {
@@ -121,39 +114,44 @@ void JournalTrimmer::remove_set(uint64_t object_set) {
   }
 }
 
-void JournalTrimmer::handle_commit_position_safe(
-    int r, const ObjectSetPosition &object_set_position) {
-  ldout(m_cct, 20) << __func__ << ": r=" << r << ", pos="
-                   << object_set_position << dendl;
+void JournalTrimmer::handle_metadata_updated() {
+  ldout(m_cct, 20) << __func__ << dendl;
 
   Mutex::Locker locker(m_lock);
-  if (r == 0) {
-    uint8_t splay_width = m_journal_metadata->get_splay_width();
-    uint64_t object_set = object_set_position.object_number / splay_width;
-
-    JournalMetadata::RegisteredClients registered_clients;
-    m_journal_metadata->get_registered_clients(&registered_clients);
-
-    bool trim_permitted = true;
-    for (JournalMetadata::RegisteredClients::iterator it =
-           registered_clients.begin();
-         it != registered_clients.end(); ++it) {
-      const JournalMetadata::Client &client = *it;
-      uint64_t client_object_set = client.commit_position.object_number /
-                                   splay_width;
-      if (client.id != m_journal_metadata->get_client_id() &&
-          client_object_set < object_set) {
-        ldout(m_cct, 20) << "object set " << client_object_set << " still "
-                         << "in-use by client " << client.id << dendl;
-        trim_permitted = false;
-        break;
-      }
+
+  JournalMetadata::RegisteredClients registered_clients;
+  m_journal_metadata->get_registered_clients(&registered_clients);
+
+  uint8_t splay_width = m_journal_metadata->get_splay_width();
+  uint64_t minimum_set = m_journal_metadata->get_minimum_set();
+  uint64_t active_set = m_journal_metadata->get_active_set();
+  uint64_t minimum_commit_set = active_set;
+  std::string minimum_client_id;
+
+  // TODO: add support for trimming past "laggy" clients
+  for (auto &client : registered_clients) {
+    if (client.commit_position.object_positions.empty()) {
+      // client hasn't recorded any commits
+      minimum_commit_set = minimum_set;
+      minimum_client_id = client.id;
+      break;
     }
 
-    if (trim_permitted) {
-      trim_objects(object_set_position.object_number / splay_width);
+    for (auto &position : client.commit_position.object_positions) {
+      uint64_t object_set = position.object_number / splay_width;
+      if (object_set < minimum_commit_set) {
+        minimum_client_id = client.id;
+        minimum_commit_set = object_set;
+      }
     }
   }
+
+  if (minimum_commit_set > minimum_set) {
+    trim_objects(minimum_commit_set);
+  } else {
+    ldout(m_cct, 20) << "object set " << minimum_commit_set << " still "
+                     << "in-use by client " << minimum_client_id << dendl;
+  }
 }
 
 void JournalTrimmer::handle_set_removed(int r, uint64_t object_set) {
@@ -163,23 +161,26 @@ void JournalTrimmer::handle_set_removed(int r, uint64_t object_set) {
   Mutex::Locker locker(m_lock);
   m_remove_set_pending = false;
 
-  if (r == 0 || (r == -ENOENT && m_remove_set_ctx == NULL)) {
+  if (r == -ENOENT) {
+    // no objects within the set existed
+    r = 0;
+  }
+  if (r == 0) {
     // advance the minimum set to the next set
     m_journal_metadata->set_minimum_set(object_set + 1);
+    uint64_t active_set = m_journal_metadata->get_active_set();
     uint64_t minimum_set = m_journal_metadata->get_minimum_set();
 
-    if (m_remove_set > minimum_set) {
+    if (m_remove_set > minimum_set && minimum_set <= active_set) {
       m_remove_set_pending = true;
       remove_set(minimum_set);
     }
-  } else if (r == -ENOENT) {
-    // no objects within the set existed
-    r = 0;
   }
 
-  if (m_remove_set_ctx != NULL && !m_remove_set_pending) {
+  if (m_remove_set_ctx != nullptr && !m_remove_set_pending) {
     ldout(m_cct, 20) << "completing remove set context" << dendl;
     m_remove_set_ctx->complete(r);
+    m_remove_set_ctx = nullptr;
   }
 }
 
diff --git a/src/journal/JournalTrimmer.h b/src/journal/JournalTrimmer.h
index 46db1c5..8c57776 100644
--- a/src/journal/JournalTrimmer.h
+++ b/src/journal/JournalTrimmer.h
@@ -11,6 +11,7 @@
 #include "journal/AsyncOpTracker.h"
 #include "journal/JournalMetadata.h"
 #include "cls/journal/cls_journal_types.h"
+#include <functional>
 
 namespace journal {
 
@@ -26,18 +27,31 @@ public:
   void committed(uint64_t commit_tid);
 
 private:
+  typedef std::function<Context*()> CreateContext;
+
+  struct MetadataListener : public JournalMetadata::Listener {
+    JournalTrimmer *journal_trimmmer;
+
+    MetadataListener(JournalTrimmer *journal_trimmmer)
+      : journal_trimmmer(journal_trimmmer) {
+    }
+    void handle_update(JournalMetadata *) {
+      journal_trimmmer->handle_metadata_updated();
+    }
+  };
+
   struct C_CommitPositionSafe : public Context {
     JournalTrimmer *journal_trimmer;
-    ObjectSetPosition object_set_position;
 
-    C_CommitPositionSafe(JournalTrimmer *_journal_trimmer,
-                         const ObjectSetPosition &_object_set_position)
-      : journal_trimmer(_journal_trimmer),
-        object_set_position(_object_set_position) {}
+    C_CommitPositionSafe(JournalTrimmer *_journal_trimmer)
+      : journal_trimmer(_journal_trimmer) {
+      journal_trimmer->m_async_op_tracker.start_op();
+    }
+    virtual ~C_CommitPositionSafe() {
+      journal_trimmer->m_async_op_tracker.finish_op();
+    }
 
     virtual void finish(int r) {
-      journal_trimmer->handle_commit_position_safe(r, object_set_position);
-      journal_trimmer->m_async_op_tracker.finish_op();
     }
   };
   struct C_RemoveSet : public Context {
@@ -61,6 +75,7 @@ private:
   std::string m_object_oid_prefix;
 
   JournalMetadataPtr m_journal_metadata;
+  MetadataListener m_metadata_listener;
 
   AsyncOpTracker m_async_op_tracker;
 
@@ -70,11 +85,14 @@ private:
   uint64_t m_remove_set;
   Context *m_remove_set_ctx;
 
+  CreateContext m_create_commit_position_safe_context = [this]() {
+      return new C_CommitPositionSafe(this);
+    };
+
   void trim_objects(uint64_t minimum_set);
   void remove_set(uint64_t object_set);
 
-  void handle_commit_position_safe(int r, const ObjectSetPosition &position);
-
+  void handle_metadata_updated();
   void handle_set_removed(int r, uint64_t object_set);
 };
 
diff --git a/src/journal/Journaler.cc b/src/journal/Journaler.cc
index 1eb7e2c..957243b 100644
--- a/src/journal/Journaler.cc
+++ b/src/journal/Journaler.cc
@@ -4,6 +4,8 @@
 #include "journal/Journaler.h"
 #include "include/stringify.h"
 #include "common/errno.h"
+#include "common/Timer.h"
+#include "common/WorkQueue.h"
 #include "journal/Entry.h"
 #include "journal/FutureImpl.h"
 #include "journal/JournalMetadata.h"
@@ -51,31 +53,74 @@ std::string Journaler::object_oid_prefix(int pool_id,
   return JOURNAL_OBJECT_PREFIX + stringify(pool_id) + "." + journal_id + ".";
 }
 
+Journaler::Threads::Threads(CephContext *cct)
+    : timer_lock("Journaler::timer_lock") {
+  thread_pool = new ThreadPool(cct, "Journaler::thread_pool", "tp_journal", 1);
+  thread_pool->start();
+
+  work_queue = new ContextWQ("Journaler::work_queue", 60, thread_pool);
+
+  timer = new SafeTimer(cct, timer_lock, true);
+  timer->init();
+}
+
+Journaler::Threads::~Threads() {
+  {
+    Mutex::Locker timer_locker(timer_lock);
+    timer->shutdown();
+  }
+  delete timer;
+
+  work_queue->drain();
+  delete work_queue;
+
+  thread_pool->stop();
+  delete thread_pool;
+}
+
 Journaler::Journaler(librados::IoCtx &header_ioctx,
+                     const std::string &journal_id,
+                     const std::string &client_id, double commit_interval)
+    : m_threads(new Threads(reinterpret_cast<CephContext*>(header_ioctx.cct()))),
+      m_client_id(client_id) {
+  set_up(m_threads->work_queue, m_threads->timer, &m_threads->timer_lock,
+         header_ioctx, journal_id, commit_interval);
+}
+
+Journaler::Journaler(ContextWQ *work_queue, SafeTimer *timer,
+                     Mutex *timer_lock, librados::IoCtx &header_ioctx,
 		     const std::string &journal_id,
 		     const std::string &client_id, double commit_interval)
-  : m_client_id(client_id), m_metadata(NULL), m_player(NULL), m_recorder(NULL),
-    m_trimmer(NULL)
-{
+    : m_client_id(client_id) {
+  set_up(work_queue, timer, timer_lock, header_ioctx, journal_id,
+         commit_interval);
+}
+
+void Journaler::set_up(ContextWQ *work_queue, SafeTimer *timer,
+                       Mutex *timer_lock, librados::IoCtx &header_ioctx,
+                       const std::string &journal_id, double commit_interval) {
   m_header_ioctx.dup(header_ioctx);
   m_cct = reinterpret_cast<CephContext *>(m_header_ioctx.cct());
 
   m_header_oid = header_oid(journal_id);
   m_object_oid_prefix = object_oid_prefix(m_header_ioctx.get_id(), journal_id);
 
-  m_metadata = new JournalMetadata(m_header_ioctx, m_header_oid, m_client_id,
+  m_metadata = new JournalMetadata(work_queue, timer, timer_lock,
+                                   m_header_ioctx, m_header_oid, m_client_id,
                                    commit_interval);
   m_metadata->get();
 }
 
 Journaler::~Journaler() {
-  if (m_metadata != NULL) {
+  if (m_metadata != nullptr) {
     m_metadata->put();
-    m_metadata = NULL;
+    m_metadata = nullptr;
   }
   delete m_trimmer;
-  assert(m_player == NULL);
-  assert(m_recorder == NULL);
+  assert(m_player == nullptr);
+  assert(m_recorder == nullptr);
+
+  delete m_threads;
 }
 
 int Journaler::exists(bool *header_exists) const {
@@ -116,8 +161,24 @@ int Journaler::init_complete() {
   return 0;
 }
 
-void Journaler::shutdown() {
-  m_metadata->shutdown();
+void Journaler::shut_down() {
+  m_metadata->shut_down();
+}
+
+bool Journaler::is_initialized() const {
+  return m_metadata->is_initialized();
+}
+
+void Journaler::get_immutable_metadata(uint8_t *order, uint8_t *splay_width,
+				       int64_t *pool_id, Context *on_finish) {
+  m_metadata->get_immutable_metadata(order, splay_width, pool_id, on_finish);
+}
+
+void Journaler::get_mutable_metadata(uint64_t *minimum_set,
+				     uint64_t *active_set,
+				     RegisteredClients *clients,
+				     Context *on_finish) {
+  m_metadata->get_mutable_metadata(minimum_set, active_set, clients, on_finish);
 }
 
 int Journaler::create(uint8_t order, uint8_t splay_width, int64_t pool_id) {
@@ -140,7 +201,7 @@ int Journaler::create(uint8_t order, uint8_t splay_width, int64_t pool_id) {
 }
 
 int Journaler::remove(bool force) {
-  m_metadata->shutdown();
+  m_metadata->shut_down();
 
   ldout(m_cct, 5) << "removing journal: " << m_header_oid << dendl;
   int r = m_trimmer->remove_objects(force);
@@ -159,12 +220,46 @@ int Journaler::remove(bool force) {
   return 0;
 }
 
+void Journaler::flush_commit_position(Context *on_safe) {
+  m_metadata->flush_commit_position(on_safe);
+}
+
 int Journaler::register_client(const bufferlist &data) {
-  return m_metadata->register_client(data);
+  C_SaferCond cond;
+  register_client(data, &cond);
+  return cond.wait();
 }
 
 int Journaler::unregister_client() {
-  return m_metadata->unregister_client();
+  C_SaferCond cond;
+  unregister_client(&cond);
+  return cond.wait();
+}
+
+void Journaler::register_client(const bufferlist &data, Context *on_finish) {
+  return m_metadata->register_client(data, on_finish);
+}
+
+void Journaler::update_client(const bufferlist &data, Context *on_finish) {
+  return m_metadata->update_client(data, on_finish);
+}
+
+void Journaler::unregister_client(Context *on_finish) {
+  return m_metadata->unregister_client(on_finish);
+}
+
+int Journaler::get_cached_client(const std::string &client_id,
+                                 cls::journal::Client *client) {
+  RegisteredClients clients;
+  m_metadata->get_registered_clients(&clients);
+
+  auto it = clients.find({client_id, {}});
+  if (it == clients.end()) {
+    return -ENOENT;
+  }
+
+  *client = *it;
+  return 0;
 }
 
 void Journaler::allocate_tag(const bufferlist &data, cls::journal::Tag *tag,
@@ -240,7 +335,7 @@ void Journaler::start_append(int flush_interval, uint64_t flush_bytes,
 void Journaler::stop_append(Context *on_safe) {
   assert(m_recorder != NULL);
 
-  flush(new C_DeleteRecorder(m_recorder, on_safe));
+  flush_append(new C_DeleteRecorder(m_recorder, on_safe));
   m_recorder = NULL;
 }
 
@@ -248,7 +343,7 @@ Future Journaler::append(uint64_t tag_tid, const bufferlist &payload_bl) {
   return m_recorder->append(tag_tid, payload_bl);
 }
 
-void Journaler::flush(Context *on_safe) {
+void Journaler::flush_append(Context *on_safe) {
   m_recorder->flush(on_safe);
 }
 
diff --git a/src/journal/Journaler.h b/src/journal/Journaler.h
index 6702eb4..c0bb137 100644
--- a/src/journal/Journaler.h
+++ b/src/journal/Journaler.h
@@ -15,7 +15,9 @@
 #include <string>
 #include "include/assert.h"
 
+class ContextWQ;
 class SafeTimer;
+class ThreadPool;
 
 namespace journal {
 
@@ -28,7 +30,19 @@ class ReplayHandler;
 
 class Journaler {
 public:
+  struct Threads {
+    Threads(CephContext *cct);
+    ~Threads();
+
+    ThreadPool *thread_pool = nullptr;
+    ContextWQ *work_queue = nullptr;
+
+    SafeTimer *timer = nullptr;
+    Mutex timer_lock;
+  };
+
   typedef std::list<cls::journal::Tag> Tags;
+  typedef std::set<cls::journal::Client> RegisteredClients;
 
   static std::string header_oid(const std::string &journal_id);
   static std::string object_oid_prefix(int pool_id,
@@ -36,6 +50,9 @@ public:
 
   Journaler(librados::IoCtx &header_ioctx, const std::string &journal_id,
 	    const std::string &client_id, double commit_interval);
+  Journaler(ContextWQ *work_queue, SafeTimer *timer, Mutex *timer_lock,
+            librados::IoCtx &header_ioctx, const std::string &journal_id,
+	    const std::string &client_id, double commit_interval);
   ~Journaler();
 
   int exists(bool *header_exists) const;
@@ -43,10 +60,27 @@ public:
   int remove(bool force);
 
   void init(Context *on_init);
-  void shutdown();
+  void shut_down();
+
+  bool is_initialized() const;
+
+  void get_immutable_metadata(uint8_t *order, uint8_t *splay_width,
+			      int64_t *pool_id, Context *on_finish);
+  void get_mutable_metadata(uint64_t *minimum_set, uint64_t *active_set,
+			    RegisteredClients *clients, Context *on_finish);
 
   int register_client(const bufferlist &data);
+  void register_client(const bufferlist &data, Context *on_finish);
+
   int unregister_client();
+  void unregister_client(Context *on_finish);
+
+  void update_client(const bufferlist &data, Context *on_finish);
+
+  int get_cached_client(const std::string &client_id,
+                        cls::journal::Client *client);
+
+  void flush_commit_position(Context *on_safe);
 
   void allocate_tag(const bufferlist &data, cls::journal::Tag *tag,
                     Context *on_finish);
@@ -61,7 +95,7 @@ public:
 
   void start_append(int flush_interval, uint64_t flush_bytes, double flush_age);
   Future append(uint64_t tag_tid, const bufferlist &bl);
-  void flush(Context *on_safe);
+  void flush_append(Context *on_safe);
   void stop_append(Context *on_safe);
 
   void committed(const ReplayEntry &replay_entry);
@@ -84,6 +118,8 @@ private:
     }
   };
 
+  Threads *m_threads = nullptr;
+
   mutable librados::IoCtx m_header_ioctx;
   librados::IoCtx m_data_ioctx;
   CephContext *m_cct;
@@ -92,10 +128,14 @@ private:
   std::string m_header_oid;
   std::string m_object_oid_prefix;
 
-  JournalMetadata *m_metadata;
-  JournalPlayer *m_player;
-  JournalRecorder *m_recorder;
-  JournalTrimmer *m_trimmer;
+  JournalMetadata *m_metadata = nullptr;
+  JournalPlayer *m_player = nullptr;
+  JournalRecorder *m_recorder = nullptr;
+  JournalTrimmer *m_trimmer = nullptr;
+
+  void set_up(ContextWQ *work_queue, SafeTimer *timer, Mutex *timer_lock,
+              librados::IoCtx &header_ioctx, const std::string &journal_id,
+              double commit_interval);
 
   int init_complete();
   void create_player(ReplayHandler *replay_handler);
diff --git a/src/journal/ObjectPlayer.cc b/src/journal/ObjectPlayer.cc
index 56459a5..e890dfa 100644
--- a/src/journal/ObjectPlayer.cc
+++ b/src/journal/ObjectPlayer.cc
@@ -161,7 +161,7 @@ int ObjectPlayer::handle_fetch_complete(int r, const bufferlist &bl) {
   }
 
   if (!m_invalid_ranges.empty()) {
-    r = -EINVAL;
+    r = -EBADMSG;
   }
   return r;
 }
@@ -207,11 +207,10 @@ void ObjectPlayer::handle_watch_fetched(int r) {
     Mutex::Locker timer_locker(m_timer_lock);
     assert(m_watch_in_progress);
     if (r == -ENOENT) {
-      schedule_watch();
-    } else {
-      on_finish = m_watch_ctx;
-      m_watch_ctx = NULL;
+      r = 0;
     }
+    on_finish = m_watch_ctx;
+    m_watch_ctx = NULL;
   }
 
   if (on_finish != NULL) {
diff --git a/src/journal/ObjectPlayer.h b/src/journal/ObjectPlayer.h
index 22b51f6..f68ee37 100644
--- a/src/journal/ObjectPlayer.h
+++ b/src/journal/ObjectPlayer.h
@@ -46,11 +46,6 @@ public:
   void watch(Context *on_fetch, double interval);
   void unwatch();
 
-  inline bool is_fetch_in_progress() const {
-    Mutex::Locker locker(m_lock);
-    return m_fetch_in_progress;
-  }
-
   void front(Entry *entry) const;
   void pop_front();
   inline bool empty() const {
@@ -101,7 +96,6 @@ private:
   SafeTimer &m_timer;
   Mutex &m_timer_lock;
 
-  double m_fetch_interval;
   uint8_t m_order;
 
   double m_watch_interval;
diff --git a/src/journal/ObjectRecorder.cc b/src/journal/ObjectRecorder.cc
index ba8ff4b..c7f62b4 100644
--- a/src/journal/ObjectRecorder.cc
+++ b/src/journal/ObjectRecorder.cc
@@ -47,6 +47,12 @@ bool ObjectRecorder::append(const AppendBuffers &append_buffers) {
   bool schedule_append = false;
   {
     Mutex::Locker locker(m_lock);
+    if (m_overflowed) {
+      m_append_buffers.insert(m_append_buffers.end(),
+                              append_buffers.begin(), append_buffers.end());
+      return false;
+    }
+
     for (AppendBuffers::const_iterator iter = append_buffers.begin();
          iter != append_buffers.end(); ++iter) {
       if (append(*iter, &schedule_append)) {
diff --git a/src/kv/KeyValueDB.h b/src/kv/KeyValueDB.h
index f20b799..c7a83a2 100644
--- a/src/kv/KeyValueDB.h
+++ b/src/kv/KeyValueDB.h
@@ -247,9 +247,7 @@ public:
   }
 
   Iterator get_iterator(const std::string &prefix) {
-    return ceph::shared_ptr<IteratorImpl>(
-      new IteratorImpl(prefix, get_iterator())
-    );
+    return std::make_shared<IteratorImpl>(prefix, get_iterator());
   }
 
   WholeSpaceIterator get_snapshot_iterator() {
@@ -257,9 +255,7 @@ public:
   }
 
   Iterator get_snapshot_iterator(const std::string &prefix) {
-    return ceph::shared_ptr<IteratorImpl>(
-      new IteratorImpl(prefix, get_snapshot_iterator())
-    );
+    return std::make_shared<IteratorImpl>(prefix, get_snapshot_iterator());
   }
 
   virtual uint64_t get_estimated_size(std::map<std::string,uint64_t> &extra) = 0;
diff --git a/src/kv/KineticStore.h b/src/kv/KineticStore.h
index c2be802..496cb4c 100644
--- a/src/kv/KineticStore.h
+++ b/src/kv/KineticStore.h
@@ -95,8 +95,7 @@ public:
   };
 
   KeyValueDB::Transaction get_transaction() {
-    return ceph::shared_ptr< KineticTransactionImpl >(
-      new KineticTransactionImpl(this));
+    return std::make_shared<KineticTransactionImpl>(this);
   }
 
   int submit_transaction(KeyValueDB::Transaction t);
@@ -148,8 +147,7 @@ public:
 
 protected:
   WholeSpaceIterator _get_iterator() {
-    return ceph::shared_ptr<KeyValueDB::WholeSpaceIteratorImpl>(
-								new KineticWholeSpaceIteratorImpl(kinetic_conn.get()));
+    return std::make_shared<KineticWholeSpaceIteratorImpl>(kinetic_conn.get());
   }
 
   // TODO: remove snapshots from interface
diff --git a/src/kv/LevelDBStore.h b/src/kv/LevelDBStore.h
index 8260f8b..766ed19 100644
--- a/src/kv/LevelDBStore.h
+++ b/src/kv/LevelDBStore.h
@@ -199,8 +199,7 @@ public:
   };
 
   KeyValueDB::Transaction get_transaction() {
-    return ceph::shared_ptr< LevelDBTransactionImpl >(
-      new LevelDBTransactionImpl(this));
+    return std::make_shared<LevelDBTransactionImpl>(this);
   }
 
   int submit_transaction(KeyValueDB::Transaction t);
@@ -402,11 +401,8 @@ err:
 
 protected:
   WholeSpaceIterator _get_iterator() {
-    return ceph::shared_ptr<KeyValueDB::WholeSpaceIteratorImpl>(
-      new LevelDBWholeSpaceIteratorImpl(
-	db->NewIterator(leveldb::ReadOptions())
-      )
-    );
+    return std::make_shared<LevelDBWholeSpaceIteratorImpl>(
+	db->NewIterator(leveldb::ReadOptions()));
   }
 
   WholeSpaceIterator _get_snapshot_iterator() {
@@ -416,10 +412,9 @@ protected:
     snapshot = db->GetSnapshot();
     options.snapshot = snapshot;
 
-    return ceph::shared_ptr<KeyValueDB::WholeSpaceIteratorImpl>(
-      new LevelDBSnapshotIteratorImpl(db.get(), snapshot,
-	db->NewIterator(options))
-    );
+    return std::make_shared<LevelDBSnapshotIteratorImpl>(
+        db.get(), snapshot,
+	db->NewIterator(options));
   }
 
 };
diff --git a/src/kv/Makefile.am b/src/kv/Makefile.am
index 060305e..b876171 100644
--- a/src/kv/Makefile.am
+++ b/src/kv/Makefile.am
@@ -16,8 +16,12 @@ if WITH_SLIBROCKSDB
 # build rocksdb with its own makefile
 # for some stupid reason this needs -fPIC...
 # PORTABLE=1 fixes the aarch64 build (-march=native doesn't work there)
+NPROC = nproc
+if FREEBSD
+        NPROC = sysctl -n hw.ncpu
+endif
 rocksdb/librocksdb.a:
-	cd rocksdb && EXTRA_CXXFLAGS=-fPIC PORTABLE=1 make -j$(shell nproc) static_lib
+	cd rocksdb && CC="${CC}" CXX="${CXX}" EXTRA_CXXFLAGS=-fPIC PORTABLE=1 $(MAKE) -j$(shell ${NPROC}) static_lib
 libkv_a_CXXFLAGS += -I rocksdb/include -fPIC
 libkv_a_SOURCES += kv/RocksDBStore.cc
 libkv_a_LIBADD += rocksdb/librocksdb.a
diff --git a/src/kv/RocksDBStore.cc b/src/kv/RocksDBStore.cc
index 923537c..d8751cc 100644
--- a/src/kv/RocksDBStore.cc
+++ b/src/kv/RocksDBStore.cc
@@ -657,11 +657,8 @@ string RocksDBStore::past_prefix(const string &prefix)
 
 RocksDBStore::WholeSpaceIterator RocksDBStore::_get_iterator()
 {
-  return std::shared_ptr<KeyValueDB::WholeSpaceIteratorImpl>(
-    new RocksDBWholeSpaceIteratorImpl(
-      db->NewIterator(rocksdb::ReadOptions())
-    )
-  );
+  return std::make_shared<RocksDBWholeSpaceIteratorImpl>(
+        db->NewIterator(rocksdb::ReadOptions()));
 }
 
 RocksDBStore::WholeSpaceIterator RocksDBStore::_get_snapshot_iterator()
@@ -672,10 +669,8 @@ RocksDBStore::WholeSpaceIterator RocksDBStore::_get_snapshot_iterator()
   snapshot = db->GetSnapshot();
   options.snapshot = snapshot;
 
-  return std::shared_ptr<KeyValueDB::WholeSpaceIteratorImpl>(
-    new RocksDBSnapshotIteratorImpl(db, snapshot,
-      db->NewIterator(options))
-  );
+  return std::make_shared<RocksDBSnapshotIteratorImpl>(
+          db, snapshot, db->NewIterator(options));
 }
 
 RocksDBStore::RocksDBSnapshotIteratorImpl::~RocksDBSnapshotIteratorImpl()
diff --git a/src/kv/RocksDBStore.h b/src/kv/RocksDBStore.h
index 63cbc5a..41508ba 100644
--- a/src/kv/RocksDBStore.h
+++ b/src/kv/RocksDBStore.h
@@ -157,8 +157,7 @@ public:
   };
 
   KeyValueDB::Transaction get_transaction() {
-    return std::shared_ptr< RocksDBTransactionImpl >(
-      new RocksDBTransactionImpl(this));
+    return std::make_shared<RocksDBTransactionImpl>(this);
   }
 
   int submit_transaction(KeyValueDB::Transaction t);
diff --git a/src/libcephfs.cc b/src/libcephfs.cc
index 400669a..037a018 100644
--- a/src/libcephfs.cc
+++ b/src/libcephfs.cc
@@ -173,12 +173,11 @@ public:
 
   int conf_read_file(const char *path_list)
   {
-    std::deque<std::string> parse_errors;
-    int ret = cct->_conf->parse_config_files(path_list, &parse_errors, NULL, 0);
+    int ret = cct->_conf->parse_config_files(path_list, NULL, 0);
     if (ret)
       return ret;
     cct->_conf->apply_changes(NULL);
-    complain_about_parse_errors(cct, &parse_errors);
+    cct->_conf->complain_about_parse_errors(cct);
     return 0;
   }
 
@@ -880,7 +879,7 @@ extern "C" int ceph_sync_fs(struct ceph_mount_info *cmount)
 
 extern "C" int ceph_get_file_stripe_unit(struct ceph_mount_info *cmount, int fh)
 {
-  struct ceph_file_layout l;
+  file_layout_t l;
   int r;
 
   if (!cmount->is_mounted())
@@ -888,12 +887,12 @@ extern "C" int ceph_get_file_stripe_unit(struct ceph_mount_info *cmount, int fh)
   r = cmount->get_client()->fdescribe_layout(fh, &l);
   if (r < 0)
     return r;
-  return l.fl_stripe_unit;
+  return l.stripe_unit;
 }
 
 extern "C" int ceph_get_path_stripe_unit(struct ceph_mount_info *cmount, const char *path)
 {
-  struct ceph_file_layout l;
+  file_layout_t l;
   int r;
 
   if (!cmount->is_mounted())
@@ -901,12 +900,12 @@ extern "C" int ceph_get_path_stripe_unit(struct ceph_mount_info *cmount, const c
   r = cmount->get_client()->describe_layout(path, &l);
   if (r < 0)
     return r;
-  return l.fl_stripe_unit;
+  return l.stripe_unit;
 }
 
 extern "C" int ceph_get_file_stripe_count(struct ceph_mount_info *cmount, int fh)
 {
-  struct ceph_file_layout l;
+  file_layout_t l;
   int r;
 
   if (!cmount->is_mounted())
@@ -914,12 +913,12 @@ extern "C" int ceph_get_file_stripe_count(struct ceph_mount_info *cmount, int fh
   r = cmount->get_client()->fdescribe_layout(fh, &l);
   if (r < 0)
     return r;
-  return l.fl_stripe_count;
+  return l.stripe_count;
 }
 
 extern "C" int ceph_get_path_stripe_count(struct ceph_mount_info *cmount, const char *path)
 {
-  struct ceph_file_layout l;
+  file_layout_t l;
   int r;
 
   if (!cmount->is_mounted())
@@ -927,12 +926,12 @@ extern "C" int ceph_get_path_stripe_count(struct ceph_mount_info *cmount, const
   r = cmount->get_client()->describe_layout(path, &l);
   if (r < 0)
     return r;
-  return l.fl_stripe_count;
+  return l.stripe_count;
 }
 
 extern "C" int ceph_get_file_object_size(struct ceph_mount_info *cmount, int fh)
 {
-  struct ceph_file_layout l;
+  file_layout_t l;
   int r;
 
   if (!cmount->is_mounted())
@@ -940,12 +939,12 @@ extern "C" int ceph_get_file_object_size(struct ceph_mount_info *cmount, int fh)
   r = cmount->get_client()->fdescribe_layout(fh, &l);
   if (r < 0)
     return r;
-  return l.fl_object_size;
+  return l.object_size;
 }
 
 extern "C" int ceph_get_path_object_size(struct ceph_mount_info *cmount, const char *path)
 {
-  struct ceph_file_layout l;
+  file_layout_t l;
   int r;
 
   if (!cmount->is_mounted())
@@ -953,12 +952,12 @@ extern "C" int ceph_get_path_object_size(struct ceph_mount_info *cmount, const c
   r = cmount->get_client()->describe_layout(path, &l);
   if (r < 0)
     return r;
-  return l.fl_object_size;
+  return l.object_size;
 }
 
 extern "C" int ceph_get_file_pool(struct ceph_mount_info *cmount, int fh)
 {
-  struct ceph_file_layout l;
+  file_layout_t l;
   int r;
 
   if (!cmount->is_mounted())
@@ -966,12 +965,12 @@ extern "C" int ceph_get_file_pool(struct ceph_mount_info *cmount, int fh)
   r = cmount->get_client()->fdescribe_layout(fh, &l);
   if (r < 0)
     return r;
-  return l.fl_pg_pool;
+  return l.pool_id;
 }
 
 extern "C" int ceph_get_path_pool(struct ceph_mount_info *cmount, const char *path)
 {
-  struct ceph_file_layout l;
+  file_layout_t l;
   int r;
 
   if (!cmount->is_mounted())
@@ -979,12 +978,12 @@ extern "C" int ceph_get_path_pool(struct ceph_mount_info *cmount, const char *pa
   r = cmount->get_client()->describe_layout(path, &l);
   if (r < 0)
     return r;
-  return l.fl_pg_pool;
+  return l.pool_id;
 }
 
 extern "C" int ceph_get_file_pool_name(struct ceph_mount_info *cmount, int fh, char *buf, size_t len)
 {
-  struct ceph_file_layout l;
+  file_layout_t l;
   int r;
 
   if (!cmount->is_mounted())
@@ -992,7 +991,7 @@ extern "C" int ceph_get_file_pool_name(struct ceph_mount_info *cmount, int fh, c
   r = cmount->get_client()->fdescribe_layout(fh, &l);
   if (r < 0)
     return r;
-  string name = cmount->get_client()->get_pool_name(l.fl_pg_pool);
+  string name = cmount->get_client()->get_pool_name(l.pool_id);
   if (len == 0)
     return name.length();
   if (name.length() > len)
@@ -1016,7 +1015,7 @@ extern "C" int ceph_get_pool_name(struct ceph_mount_info *cmount, int pool, char
 
 extern "C" int ceph_get_path_pool_name(struct ceph_mount_info *cmount, const char *path, char *buf, size_t len)
 {
-  struct ceph_file_layout l;
+  file_layout_t l;
   int r;
 
   if (!cmount->is_mounted())
@@ -1024,7 +1023,7 @@ extern "C" int ceph_get_path_pool_name(struct ceph_mount_info *cmount, const cha
   r = cmount->get_client()->describe_layout(path, &l);
   if (r < 0)
     return r;
-  string name = cmount->get_client()->get_pool_name(l.fl_pg_pool);
+  string name = cmount->get_client()->get_pool_name(l.pool_id);
   if (len == 0)
     return name.length();
   if (name.length() > len)
@@ -1035,7 +1034,7 @@ extern "C" int ceph_get_path_pool_name(struct ceph_mount_info *cmount, const cha
 
 extern "C" int ceph_get_file_layout(struct ceph_mount_info *cmount, int fh, int *stripe_unit, int *stripe_count, int *object_size, int *pg_pool)
 {
-  struct ceph_file_layout l;
+  file_layout_t l;
   int r;
 
   if (!cmount->is_mounted())
@@ -1044,19 +1043,19 @@ extern "C" int ceph_get_file_layout(struct ceph_mount_info *cmount, int fh, int
   if (r < 0)
     return r;
   if (stripe_unit)
-    *stripe_unit = l.fl_stripe_unit;
+    *stripe_unit = l.stripe_unit;
   if (stripe_count)
-    *stripe_count = l.fl_stripe_count;
+    *stripe_count = l.stripe_count;
   if (object_size)
-    *object_size = l.fl_object_size;
+    *object_size = l.object_size;
   if (pg_pool)
-    *pg_pool = l.fl_pg_pool;
+    *pg_pool = l.pool_id;
   return 0;
 }
 
 extern "C" int ceph_get_path_layout(struct ceph_mount_info *cmount, const char *path, int *stripe_unit, int *stripe_count, int *object_size, int *pg_pool)
 {
-  struct ceph_file_layout l;
+  file_layout_t l;
   int r;
 
   if (!cmount->is_mounted())
@@ -1065,19 +1064,19 @@ extern "C" int ceph_get_path_layout(struct ceph_mount_info *cmount, const char *
   if (r < 0)
     return r;
   if (stripe_unit)
-    *stripe_unit = l.fl_stripe_unit;
+    *stripe_unit = l.stripe_unit;
   if (stripe_count)
-    *stripe_count = l.fl_stripe_count;
+    *stripe_count = l.stripe_count;
   if (object_size)
-    *object_size = l.fl_object_size;
+    *object_size = l.object_size;
   if (pg_pool)
-    *pg_pool = l.fl_pg_pool;
+    *pg_pool = l.pool_id;
   return 0;
 }
 
 extern "C" int ceph_get_file_replication(struct ceph_mount_info *cmount, int fh)
 {
-  struct ceph_file_layout l;
+  file_layout_t l;
   int r;
 
   if (!cmount->is_mounted())
@@ -1085,13 +1084,13 @@ extern "C" int ceph_get_file_replication(struct ceph_mount_info *cmount, int fh)
   r = cmount->get_client()->fdescribe_layout(fh, &l);
   if (r < 0)
     return r;
-  int rep = cmount->get_client()->get_pool_replication(l.fl_pg_pool);
+  int rep = cmount->get_client()->get_pool_replication(l.pool_id);
   return rep;
 }
 
 extern "C" int ceph_get_path_replication(struct ceph_mount_info *cmount, const char *path)
 {
-  struct ceph_file_layout l;
+  file_layout_t l;
   int r;
 
   if (!cmount->is_mounted())
@@ -1099,7 +1098,7 @@ extern "C" int ceph_get_path_replication(struct ceph_mount_info *cmount, const c
   r = cmount->get_client()->describe_layout(path, &l);
   if (r < 0)
     return r;
-  int rep = cmount->get_client()->get_pool_replication(l.fl_pg_pool);
+  int rep = cmount->get_client()->get_pool_replication(l.pool_id);
   return rep;
 }
 
@@ -1436,9 +1435,11 @@ extern "C" int ceph_ll_read_block(class ceph_mount_info *cmount,
 				  uint64_t length,
 				  struct ceph_file_layout* layout)
 {
-
-  return (cmount->get_client()->ll_read_block(in, blockid, buf, offset,
-					      length, layout));
+  file_layout_t l;
+  int r = (cmount->get_client()->ll_read_block(in, blockid, buf, offset,
+					       length, &l));
+  l.to_legacy(layout);
+  return r;
 }
 
 extern "C" int ceph_ll_write_block(class ceph_mount_info *cmount,
@@ -1448,8 +1449,11 @@ extern "C" int ceph_ll_write_block(class ceph_mount_info *cmount,
 				   struct ceph_file_layout *layout,
 				   uint64_t snapseq, uint32_t sync)
 {
-  return (cmount->get_client()->ll_write_block(in, blockid, buf, offset,
-					       length, layout, snapseq, sync));
+  file_layout_t l;
+  int r = (cmount->get_client()->ll_write_block(in, blockid, buf, offset,
+						length, &l, snapseq, sync));
+  l.to_legacy(layout);
+  return r;
 }
 
 extern "C" int ceph_ll_commit_blocks(class ceph_mount_info *cmount,
@@ -1640,7 +1644,10 @@ extern "C" uint32_t ceph_ll_file_layout(class ceph_mount_info *cmount,
 					Inode *in,
 					struct ceph_file_layout *layout)
 {
-  return (cmount->get_client()->ll_file_layout(in, layout));
+  file_layout_t l;
+  int r = (cmount->get_client()->ll_file_layout(in, &l));
+  l.to_legacy(layout);
+  return r;
 }
 
 uint64_t ceph_ll_snap_seq(class ceph_mount_info *cmount, Inode *in)
@@ -1652,7 +1659,10 @@ extern "C" int ceph_ll_get_stripe_osd(class ceph_mount_info *cmount,
 				      Inode *in, uint64_t blockno,
 				      struct ceph_file_layout* layout)
 {
-  return (cmount->get_client()->ll_get_stripe_osd(in, blockno, layout));
+  file_layout_t l;
+  int r = (cmount->get_client()->ll_get_stripe_osd(in, blockno, &l));
+  l.to_legacy(layout);
+  return r;
 }
 
 extern "C" int ceph_ll_num_osds(class ceph_mount_info *cmount)
diff --git a/src/librados/IoCtxImpl.cc b/src/librados/IoCtxImpl.cc
index b70c00a..a1479d1 100644
--- a/src/librados/IoCtxImpl.cc
+++ b/src/librados/IoCtxImpl.cc
@@ -89,19 +89,21 @@ struct C_aio_linger_cancel : public Context {
   }
 };
 
-struct C_aio_notify_Complete : public Context {
+struct C_aio_linger_Complete : public Context {
   AioCompletionImpl *c;
   Objecter::LingerOp *linger_op;
+  bool cancel;
 
-  C_aio_notify_Complete(AioCompletionImpl *_c, Objecter::LingerOp *_linger_op)
-    : c(_c), linger_op(_linger_op)
+  C_aio_linger_Complete(AioCompletionImpl *_c, Objecter::LingerOp *_linger_op, bool _cancel)
+    : c(_c), linger_op(_linger_op), cancel(_cancel)
   {
     c->get();
   }
 
   virtual void finish(int r) {
-    c->io->client->finisher.queue(new C_aio_linger_cancel(c->io->objecter,
-                                                          linger_op));
+    if (cancel || r < 0)
+      c->io->client->finisher.queue(new C_aio_linger_cancel(c->io->objecter,
+                                                            linger_op));
 
     c->lock.Lock();
     c->rval = r;
@@ -119,21 +121,65 @@ struct C_aio_notify_Complete : public Context {
   }
 };
 
+struct C_aio_notify_Complete : public C_aio_linger_Complete {
+  Mutex lock;
+  bool acked = false;
+  bool finished = false;
+  int ret_val = 0;
+
+  C_aio_notify_Complete(AioCompletionImpl *_c, Objecter::LingerOp *_linger_op)
+    : C_aio_linger_Complete(_c, _linger_op, false),
+      lock("C_aio_notify_Complete::lock") {
+  }
+
+  void handle_ack(int r) {
+    // invoked by C_aio_notify_Ack
+    lock.Lock();
+    acked = true;
+    complete_unlock(r);
+  }
+
+  virtual void complete(int r) override {
+    // invoked by C_notify_Finish (or C_aio_notify_Ack on failure)
+    lock.Lock();
+    finished = true;
+    complete_unlock(r);
+  }
+
+  void complete_unlock(int r) {
+    if (ret_val == 0 && r < 0) {
+      ret_val = r;
+    }
+
+    if (acked && finished) {
+      lock.Unlock();
+      cancel = true;
+      C_aio_linger_Complete::complete(ret_val);
+    } else {
+      lock.Unlock();
+    }
+  }
+};
+
 struct C_aio_notify_Ack : public Context {
   CephContext *cct;
-  C_notify_Finish *f;
+  C_notify_Finish *onfinish;
+  C_aio_notify_Complete *oncomplete;
 
-  C_aio_notify_Ack(CephContext *_cct, C_notify_Finish *_f)
-    : cct(_cct), f(_f)
+  C_aio_notify_Ack(CephContext *_cct, C_notify_Finish *_onfinish,
+                   C_aio_notify_Complete *_oncomplete)
+    : cct(_cct), onfinish(_onfinish), oncomplete(_oncomplete)
   {
   }
 
   virtual void finish(int r)
   {
-    ldout(cct, 10) << __func__ << " linger op " << f->linger_op << " acked ("
-                   << r << ")" << dendl;
+    ldout(cct, 10) << __func__ << " linger op " << oncomplete->linger_op << " "
+                   << "acked (" << r << ")" << dendl;
+    oncomplete->handle_ack(r);
     if (r < 0) {
-      f->complete(r);
+      // on failure, we won't expect to see a notify_finish callback
+      onfinish->complete(r);
     }
   }
 };
@@ -473,7 +519,6 @@ int librados::IoCtxImpl::nlist(Objecter::NListContext *context, int max_entries)
   Cond cond;
   bool done;
   int r = 0;
-  object_t oid;
   Mutex mylock("IoCtxImpl::nlist::mylock");
 
   if (context->at_end())
@@ -504,7 +549,6 @@ int librados::IoCtxImpl::list(Objecter::ListContext *context, int max_entries)
   Cond cond;
   bool done;
   int r = 0;
-  object_t oid;
   Mutex mylock("IoCtxImpl::list::mylock");
 
   if (context->at_end())
@@ -613,12 +657,10 @@ int librados::IoCtxImpl::clone_range(const object_t& dst_oid,
 }
 
 int librados::IoCtxImpl::operate(const object_t& oid, ::ObjectOperation *o,
-				 time_t *pmtime, int flags)
+				 ceph::real_time *pmtime, int flags)
 {
-  ceph::real_time ut =
-    pmtime ?
-    ceph::real_clock::from_time_t(*pmtime) :
-    ceph::real_clock::now(client->cct);
+  ceph::real_time ut = (pmtime ? *pmtime :
+    ceph::real_clock::now(client->cct));
 
   /* can't write to a snapshot */
   if (snap_seq != CEPH_NOSNAP)
@@ -913,6 +955,19 @@ int librados::IoCtxImpl::aio_stat(const object_t& oid, AioCompletionImpl *c,
   return 0;
 }
 
+int librados::IoCtxImpl::aio_stat2(const object_t& oid, AioCompletionImpl *c,
+				  uint64_t *psize, struct timespec *pts)
+{
+  C_aio_stat2_Ack *onack = new C_aio_stat2_Ack(c, pts);
+
+  c->io = this;
+  c->tid = objecter->stat(oid, oloc,
+			  snap_seq, psize, &onack->mtime, 0,
+			  onack, &c->objver);
+
+  return 0;
+}
+
 int librados::IoCtxImpl::aio_cancel(AioCompletionImpl *c)
 {
   return objecter->op_cancel(c->tid, -ECANCELED);
@@ -972,6 +1027,44 @@ int librados::IoCtxImpl::trunc(const object_t& oid, uint64_t size)
   return operate(oid, &op, NULL);
 }
 
+int librados::IoCtxImpl::get_inconsistent_objects(const pg_t& pg,
+						  const librados::object_id_t& start_after,
+						  uint64_t max_to_get,
+						  AioCompletionImpl *c,
+						  std::vector<inconsistent_obj_t>* objects,
+						  uint32_t* interval)
+{
+  Context *onack = new C_aio_Ack(c);
+  c->is_read = true;
+  c->io = this;
+
+  ::ObjectOperation op;
+  op.scrub_ls(start_after, max_to_get, objects, interval, nullptr);
+  object_locator_t oloc{poolid, pg.ps()};
+  c->tid = objecter->pg_read(oloc.hash, oloc, op, nullptr, CEPH_OSD_FLAG_PGOP, onack,
+			     nullptr, nullptr);
+  return 0;
+}
+
+int librados::IoCtxImpl::get_inconsistent_snapsets(const pg_t& pg,
+						   const librados::object_id_t& start_after,
+						   uint64_t max_to_get,
+						   AioCompletionImpl *c,
+						   std::vector<inconsistent_snapset_t>* snapsets,
+						   uint32_t* interval)
+{
+  Context *onack = new C_aio_Ack(c);
+  c->is_read = true;
+  c->io = this;
+
+  ::ObjectOperation op;
+  op.scrub_ls(start_after, max_to_get, snapsets, interval, nullptr);
+  object_locator_t oloc{poolid, pg.ps()};
+  c->tid = objecter->pg_read(oloc.hash, oloc, op, nullptr, CEPH_OSD_FLAG_PGOP, onack,
+			     nullptr, nullptr);
+  return 0;
+}
+
 int librados::IoCtxImpl::tmap_update(const object_t& oid, bufferlist& cmdbl)
 {
   ::ObjectOperation wr;
@@ -1122,6 +1215,29 @@ int librados::IoCtxImpl::stat(const object_t& oid, uint64_t *psize, time_t *pmti
   return r;
 }
 
+int librados::IoCtxImpl::stat2(const object_t& oid, uint64_t *psize, struct timespec *pts)
+{
+  uint64_t size;
+  ceph::real_time mtime;
+
+  if (!psize)
+    psize = &size;
+
+  ::ObjectOperation rd;
+  prepare_assert_ops(&rd);
+  rd.stat(psize, &mtime, NULL);
+  int r = operate_read(oid, &rd, NULL);
+  if (r < 0) {
+    return r;
+  }
+
+  if (pts) {
+    *pts = ceph::real_clock::to_timespec(mtime);
+  }
+
+  return 0;
+}
+
 int librados::IoCtxImpl::getxattr(const object_t& oid,
 				    const char *name, bufferlist& bl)
 {
@@ -1258,6 +1374,30 @@ int librados::IoCtxImpl::watch(const object_t& oid,
   return r;
 }
 
+int librados::IoCtxImpl::aio_watch(const object_t& oid,
+                                   AioCompletionImpl *c,
+                                   uint64_t *handle,
+                                   librados::WatchCtx *ctx,
+                                   librados::WatchCtx2 *ctx2)
+{
+  Objecter::LingerOp *linger_op = objecter->linger_register(oid, oloc, 0);
+  c->io = this;
+  Context *oncomplete = new C_aio_linger_Complete(c, linger_op, false);
+
+  ::ObjectOperation wr;
+  *handle = linger_op->get_cookie();
+  linger_op->watch_context = new WatchInfo(this, oid, ctx, ctx2);
+
+  prepare_assert_ops(&wr);
+  wr.watch(*handle, CEPH_OSD_WATCH_OP_WATCH);
+  bufferlist bl;
+  objecter->linger_watch(linger_op, wr,
+                         snapc, ceph::real_clock::now(), bl,
+                         oncomplete, &c->objver);
+
+  return 0;
+}
+
 
 int librados::IoCtxImpl::notify_ack(
   const object_t& oid,
@@ -1281,7 +1421,6 @@ int librados::IoCtxImpl::watch_check(uint64_t cookie)
 int librados::IoCtxImpl::unwatch(uint64_t cookie)
 {
   Objecter::LingerOp *linger_op = reinterpret_cast<Objecter::LingerOp*>(cookie);
-  bufferlist inbl, outbl;
   C_SaferCond onfinish;
   version_t ver = 0;
 
@@ -1298,6 +1437,21 @@ int librados::IoCtxImpl::unwatch(uint64_t cookie)
   return r;
 }
 
+int librados::IoCtxImpl::aio_unwatch(uint64_t cookie, AioCompletionImpl *c)
+{
+  c->io = this;
+  Objecter::LingerOp *linger_op = reinterpret_cast<Objecter::LingerOp*>(cookie);
+  Context *oncomplete = new C_aio_linger_Complete(c, linger_op, true);
+
+  ::ObjectOperation wr;
+  prepare_assert_ops(&wr);
+  wr.watch(cookie, CEPH_OSD_WATCH_OP_UNWATCH);
+  objecter->mutate(linger_op->target.base_oid, oloc, wr,
+		   snapc, ceph::real_clock::now(client->cct), 0, NULL,
+		   oncomplete, &c->objver);
+  return 0;
+}
+
 int librados::IoCtxImpl::notify(const object_t& oid, bufferlist& bl,
 				uint64_t timeout_ms,
 				bufferlist *preply_bl,
@@ -1358,12 +1512,12 @@ int librados::IoCtxImpl::aio_notify(const object_t& oid, AioCompletionImpl *c,
 
   c->io = this;
 
-  Context *oncomplete = new C_aio_notify_Complete(c, linger_op);
+  C_aio_notify_Complete *oncomplete = new C_aio_notify_Complete(c, linger_op);
   C_notify_Finish *onnotify = new C_notify_Finish(client->cct, oncomplete,
                                                   objecter, linger_op,
                                                   preply_bl, preply_buf,
                                                   preply_buf_len);
-  Context *onack = new C_aio_notify_Ack(client->cct, onnotify);
+  Context *onack = new C_aio_notify_Ack(client->cct, onnotify, oncomplete);
 
   uint32_t timeout = notify_timeout;
   if (timeout_ms)
@@ -1378,7 +1532,7 @@ int librados::IoCtxImpl::aio_notify(const object_t& oid, AioCompletionImpl *c,
   // Issue RADOS op
   objecter->linger_notify(linger_op,
 			  rd, snap_seq, inbl, NULL,
-			  onack, NULL);
+			  onack, &c->objver);
   return 0;
 }
 
@@ -1488,6 +1642,34 @@ void librados::IoCtxImpl::C_aio_stat_Ack::finish(int r)
   c->put_unlock();
 }
 
+///////////////////////////// C_aio_stat2_Ack ////////////////////////////
+
+librados::IoCtxImpl::C_aio_stat2_Ack::C_aio_stat2_Ack(AioCompletionImpl *_c,
+						     struct timespec *pt)
+   : c(_c), pts(pt)
+{
+  assert(!c->io);
+  c->get();
+}
+
+void librados::IoCtxImpl::C_aio_stat2_Ack::finish(int r)
+{
+  c->lock.Lock();
+  c->rval = r;
+  c->ack = true;
+  c->cond.Signal();
+
+  if (r >= 0 && pts) {
+    *pts = real_clock::to_timespec(mtime);
+  }
+
+  if (c->callback_complete) {
+    c->io->client->finisher.queue(new C_AioComplete(c));
+  }
+
+  c->put_unlock();
+}
+
 //////////////////////////// C_aio_Safe ////////////////////////////////
 
 librados::IoCtxImpl::C_aio_Safe::C_aio_Safe(AioCompletionImpl *_c) : c(_c)
diff --git a/src/librados/IoCtxImpl.h b/src/librados/IoCtxImpl.h
index ff3c235..47ed90a 100644
--- a/src/librados/IoCtxImpl.h
+++ b/src/librados/IoCtxImpl.h
@@ -137,6 +137,7 @@ struct librados::IoCtxImpl {
   int remove(const object_t& oid);
   int remove(const object_t& oid, int flags);
   int stat(const object_t& oid, uint64_t *psize, time_t *pmtime);
+  int stat2(const object_t& oid, uint64_t *psize, struct timespec *pts);
   int trunc(const object_t& oid, uint64_t size);
 
   int tmap_update(const object_t& oid, bufferlist& cmdbl);
@@ -151,7 +152,7 @@ struct librados::IoCtxImpl {
   int getxattrs(const object_t& oid, map<string, bufferlist>& attrset);
   int rmxattr(const object_t& oid, const char *name);
 
-  int operate(const object_t& oid, ::ObjectOperation *o, time_t *pmtime, int flags=0);
+  int operate(const object_t& oid, ::ObjectOperation *o, ceph::real_time *pmtime, int flags=0);
   int operate_read(const object_t& oid, ::ObjectOperation *o, bufferlist *pbl, int flags=0);
   int aio_operate(const object_t& oid, ::ObjectOperation *o,
 		  AioCompletionImpl *c, const SnapContext& snap_context,
@@ -173,6 +174,14 @@ struct librados::IoCtxImpl {
     void finish(int r);
   };
 
+  struct C_aio_stat2_Ack : public Context {
+    librados::AioCompletionImpl *c;
+    struct timespec *pts;
+    ceph::real_time mtime;
+    C_aio_stat2_Ack(AioCompletionImpl *_c, struct timespec *pts);
+    void finish(int r);
+  };
+
   struct C_aio_Safe : public Context {
     AioCompletionImpl *c;
     explicit C_aio_Safe(AioCompletionImpl *_c);
@@ -196,6 +205,7 @@ struct librados::IoCtxImpl {
   int aio_exec(const object_t& oid, AioCompletionImpl *c, const char *cls,
 	       const char *method, bufferlist& inbl, bufferlist *outbl);
   int aio_stat(const object_t& oid, AioCompletionImpl *c, uint64_t *psize, time_t *pmtime);
+  int aio_stat2(const object_t& oid, AioCompletionImpl *c, uint64_t *psize, struct timespec *pts);
   int aio_cancel(AioCompletionImpl *c);
 
   int pool_change_auid(unsigned long long auid);
@@ -206,11 +216,28 @@ struct librados::IoCtxImpl {
   int hit_set_get(uint32_t hash, AioCompletionImpl *c, time_t stamp,
 		  bufferlist *pbl);
 
+  int get_inconsistent_objects(const pg_t& pg,
+			       const librados::object_id_t& start_after,
+			       uint64_t max_to_get,
+			       AioCompletionImpl *c,
+			       std::vector<inconsistent_obj_t>* objects,
+			       uint32_t* interval);
+
+  int get_inconsistent_snapsets(const pg_t& pg,
+				const librados::object_id_t& start_after,
+				uint64_t max_to_get,
+				AioCompletionImpl *c,
+				std::vector<inconsistent_snapset_t>* snapsets,
+				uint32_t* interval);
+
   void set_sync_op_version(version_t ver);
   int watch(const object_t& oid, uint64_t *cookie, librados::WatchCtx *ctx,
 	    librados::WatchCtx2 *ctx2);
+  int aio_watch(const object_t& oid, AioCompletionImpl *c, uint64_t *cookie,
+                librados::WatchCtx *ctx, librados::WatchCtx2 *ctx2);
   int watch_check(uint64_t cookie);
   int unwatch(uint64_t cookie);
+  int aio_unwatch(uint64_t cookie, AioCompletionImpl *c);
   int notify(const object_t& oid, bufferlist& bl, uint64_t timeout_ms,
 	     bufferlist *preplybl, char **preply_buf, size_t *preply_buf_len);
   int notify_ack(const object_t& oid, uint64_t notify_id, uint64_t cookie,
diff --git a/src/librados/RadosClient.cc b/src/librados/RadosClient.cc
index 8994395..38dcb09 100644
--- a/src/librados/RadosClient.cc
+++ b/src/librados/RadosClient.cc
@@ -329,21 +329,25 @@ void librados::RadosClient::shutdown()
     lock.Unlock();
     return;
   }
-  if (state == CONNECTED) {
-    finisher.wait_for_empty();
-    finisher.stop();
-  }
+
   bool need_objecter = false;
   if (objecter && objecter->initialized.read()) {
     need_objecter = true;
   }
+
+  if (state == CONNECTED) {
+    if (need_objecter) {
+      // make sure watch callbacks are flushed
+      watch_flush();
+    }
+    finisher.wait_for_empty();
+    finisher.stop();
+  }
   state = DISCONNECTED;
   instance_id = 0;
   timer.shutdown();   // will drop+retake lock
   lock.Unlock();
   if (need_objecter) {
-    // make sure watch callbacks are flushed
-    watch_flush();
     objecter->shutdown();
   }
   monclient.shutdown();
@@ -357,7 +361,51 @@ void librados::RadosClient::shutdown()
 int librados::RadosClient::watch_flush()
 {
   ldout(cct, 10) << __func__ << " enter" << dendl;
-  objecter->linger_callback_flush();
+  Mutex mylock("RadosClient::watch_flush::mylock");
+  Cond cond;
+  bool done;
+  objecter->linger_callback_flush(new C_SafeCond(&mylock, &cond, &done));
+
+  mylock.Lock();
+  while (!done)
+    cond.Wait(mylock);
+  mylock.Unlock();
+
+  ldout(cct, 10) << __func__ << " exit" << dendl;
+  return 0;
+}
+
+struct C_aio_watch_flush_Complete : public Context {
+  librados::RadosClient *client;
+  librados::AioCompletionImpl *c;
+
+  C_aio_watch_flush_Complete(librados::RadosClient *_client, librados::AioCompletionImpl *_c)
+    : client(_client), c(_c) {
+    c->get();
+  }
+
+  virtual void finish(int r) {
+    c->lock.Lock();
+    c->rval = r;
+    c->ack = true;
+    c->safe = true;
+    c->cond.Signal();
+
+    if (c->callback_complete) {
+      client->finisher.queue(new librados::C_AioComplete(c));
+    }
+    if (c->callback_safe) {
+      client->finisher.queue(new librados::C_AioSafe(c));
+    }
+    c->put_unlock();
+  }
+};
+
+int librados::RadosClient::async_watch_flush(AioCompletionImpl *c)
+{
+  ldout(cct, 10) << __func__ << " enter" << dendl;
+  Context *oncomplete = new C_aio_watch_flush_Complete(this, c);
+  objecter->linger_callback_flush(oncomplete);
   ldout(cct, 10) << __func__ << " exit" << dendl;
   return 0;
 }
@@ -823,6 +871,10 @@ int librados::RadosClient::monitor_log(const string& level, rados_log_callback_t
 {
   Mutex::Locker l(lock);
 
+  if (state != CONNECTED) {
+    return -ENOTCONN;
+  }
+
   if (cb == NULL) {
     // stop watch
     ldout(cct, 10) << __func__ << " removing cb " << (void*)log_cb << dendl;
diff --git a/src/librados/RadosClient.h b/src/librados/RadosClient.h
index e190bfc..217c782 100644
--- a/src/librados/RadosClient.h
+++ b/src/librados/RadosClient.h
@@ -32,6 +32,7 @@ struct md_config_t;
 class Message;
 class MLog;
 class Messenger;
+class AioCompletionImpl;
 
 class librados::RadosClient : public Dispatcher
 {
@@ -82,6 +83,7 @@ public:
   void shutdown();
 
   int watch_flush();
+  int async_watch_flush(AioCompletionImpl *c);
 
   uint64_t get_instance_id();
 
diff --git a/src/librados/librados.cc b/src/librados/librados.cc
index e66d17b..05dfac5 100644
--- a/src/librados/librados.cc
+++ b/src/librados/librados.cc
@@ -17,6 +17,7 @@
 #include "common/config.h"
 #include "common/errno.h"
 #include "common/ceph_argparse.h"
+#include "common/ceph_json.h"
 #include "common/common_init.h"
 #include "common/TracepointProvider.h"
 #include "common/hobject.h"
@@ -89,9 +90,21 @@ TracepointProvider::Traits tracepoint_traits("librados_tp.so", "rados_tracing");
  * +--------------------------------------+
  */
 
+namespace librados {
+
+struct ObjectOperationImpl {
+  ::ObjectOperation o;
+  real_time rt;
+  real_time *prt;
+
+  ObjectOperationImpl() : prt(NULL) {}
+};
+
+}
+
 size_t librados::ObjectOperation::size()
 {
-  ::ObjectOperation *o = (::ObjectOperation *)impl;
+  ::ObjectOperation *o = &impl->o;
   return o->size();
 }
 
@@ -118,25 +131,24 @@ static void set_op_flags(::ObjectOperation *o, int flags)
 //deprcated
 void librados::ObjectOperation::set_op_flags(ObjectOperationFlags flags)
 {
-  ::ObjectOperation *o = (::ObjectOperation *)impl;
-  ::set_op_flags(o, (int)flags);
+  ::set_op_flags(&impl->o, (int)flags);
 }
 
 void librados::ObjectOperation::set_op_flags2(int flags)
 {
-  ::ObjectOperation *o = (::ObjectOperation *)impl;
+  ::ObjectOperation *o = &impl->o;
   ::set_op_flags(o, flags);
 }
 
 void librados::ObjectOperation::cmpxattr(const char *name, uint8_t op, const bufferlist& v)
 {
-  ::ObjectOperation *o = (::ObjectOperation *)impl;
+  ::ObjectOperation *o = &impl->o;
   o->cmpxattr(name, op, CEPH_OSD_CMPXATTR_MODE_STRING, v);
 }
 
 void librados::ObjectOperation::cmpxattr(const char *name, uint8_t op, uint64_t v)
 {
-  ::ObjectOperation *o = (::ObjectOperation *)impl;
+  ::ObjectOperation *o = &impl->o;
   bufferlist bl;
   ::encode(v, bl);
   o->cmpxattr(name, op, CEPH_OSD_CMPXATTR_MODE_U64, bl);
@@ -145,7 +157,7 @@ void librados::ObjectOperation::cmpxattr(const char *name, uint8_t op, uint64_t
 void librados::ObjectOperation::src_cmpxattr(const std::string& src_oid,
 					 const char *name, int op, const bufferlist& v)
 {
-  ::ObjectOperation *o = (::ObjectOperation *)impl;
+  ::ObjectOperation *o = &impl->o;
   object_t oid(src_oid);
   o->src_cmpxattr(oid, CEPH_NOSNAP, name, v, op, CEPH_OSD_CMPXATTR_MODE_STRING);
 }
@@ -153,7 +165,7 @@ void librados::ObjectOperation::src_cmpxattr(const std::string& src_oid,
 void librados::ObjectOperation::src_cmpxattr(const std::string& src_oid,
 					 const char *name, int op, uint64_t val)
 {
-  ::ObjectOperation *o = (::ObjectOperation *)impl;
+  ::ObjectOperation *o = &impl->o;
   object_t oid(src_oid);
   bufferlist bl;
   ::encode(val, bl);
@@ -162,25 +174,25 @@ void librados::ObjectOperation::src_cmpxattr(const std::string& src_oid,
 
 void librados::ObjectOperation::assert_version(uint64_t ver)
 {
-  ::ObjectOperation *o = (::ObjectOperation *)impl;
+  ::ObjectOperation *o = &impl->o;
   o->assert_version(ver);
 }
 
 void librados::ObjectOperation::assert_exists()
 {
-  ::ObjectOperation *o = (::ObjectOperation *)impl;
+  ::ObjectOperation *o = &impl->o;
   o->stat(NULL, (ceph::real_time*) NULL, NULL);
 }
 
 void librados::ObjectOperation::exec(const char *cls, const char *method, bufferlist& inbl)
 {
-  ::ObjectOperation *o = (::ObjectOperation *)impl;
+  ::ObjectOperation *o = &impl->o;
   o->call(cls, method, inbl);
 }
 
 void librados::ObjectOperation::exec(const char *cls, const char *method, bufferlist& inbl, bufferlist *outbl, int *prval)
 {
-  ::ObjectOperation *o = (::ObjectOperation *)impl;
+  ::ObjectOperation *o = &impl->o;
   o->call(cls, method, inbl, outbl, NULL, prval);
 }
 
@@ -201,7 +213,7 @@ public:
 
 void librados::ObjectOperation::exec(const char *cls, const char *method, bufferlist& inbl, librados::ObjectOperationCompletion *completion)
 {
-  ::ObjectOperation *o = (::ObjectOperation *)impl;
+  ::ObjectOperation *o = &impl->o;
 
   ObjectOpCompletionCtx *ctx = new ObjectOpCompletionCtx(completion);
 
@@ -210,13 +222,19 @@ void librados::ObjectOperation::exec(const char *cls, const char *method, buffer
 
 void librados::ObjectReadOperation::stat(uint64_t *psize, time_t *pmtime, int *prval)
 {
-  ::ObjectOperation *o = (::ObjectOperation *)impl;
+  ::ObjectOperation *o = &impl->o;
   o->stat(psize, pmtime, prval);
 }
 
+void librados::ObjectReadOperation::stat2(uint64_t *psize, struct timespec *pts, int *prval)
+{
+  ::ObjectOperation *o = &impl->o;
+  o->stat(psize, pts, prval);
+}
+
 void librados::ObjectReadOperation::read(size_t off, uint64_t len, bufferlist *pbl, int *prval)
 {
-  ::ObjectOperation *o = (::ObjectOperation *)impl;
+  ::ObjectOperation *o = &impl->o;
   o->read(off, len, pbl, prval, NULL);
 }
 
@@ -224,19 +242,19 @@ void librados::ObjectReadOperation::sparse_read(uint64_t off, uint64_t len,
 						std::map<uint64_t,uint64_t> *m,
 						bufferlist *data_bl, int *prval)
 {
-  ::ObjectOperation *o = (::ObjectOperation *)impl;
+  ::ObjectOperation *o = &impl->o;
   o->sparse_read(off, len, m, data_bl, prval);
 }
 
 void librados::ObjectReadOperation::tmap_get(bufferlist *pbl, int *prval)
 {
-  ::ObjectOperation *o = (::ObjectOperation *)impl;
+  ::ObjectOperation *o = &impl->o;
   o->tmap_get(pbl, prval);
 }
 
 void librados::ObjectReadOperation::getxattr(const char *name, bufferlist *pbl, int *prval)
 {
-  ::ObjectOperation *o = (::ObjectOperation *)impl;
+  ::ObjectOperation *o = &impl->o;
   o->getxattr(name, pbl, prval);
 }
 
@@ -247,7 +265,7 @@ void librados::ObjectReadOperation::omap_get_vals(
   std::map<std::string, bufferlist> *out_vals,
   int *prval)
 {
-  ::ObjectOperation *o = (::ObjectOperation *)impl;
+  ::ObjectOperation *o = &impl->o;
   o->omap_get_vals(start_after, filter_prefix, max_return, out_vals, prval);
 }
 
@@ -257,7 +275,7 @@ void librados::ObjectReadOperation::omap_get_vals(
   std::map<std::string, bufferlist> *out_vals,
   int *prval)
 {
-  ::ObjectOperation *o = (::ObjectOperation *)impl;
+  ::ObjectOperation *o = &impl->o;
   o->omap_get_vals(start_after, "", max_return, out_vals, prval);
 }
 
@@ -267,13 +285,13 @@ void librados::ObjectReadOperation::omap_get_keys(
   std::set<std::string> *out_keys,
   int *prval)
 {
-  ::ObjectOperation *o = (::ObjectOperation *)impl;
+  ::ObjectOperation *o = &impl->o;
   o->omap_get_keys(start_after, max_return, out_keys, prval);
 }
 
 void librados::ObjectReadOperation::omap_get_header(bufferlist *bl, int *prval)
 {
-  ::ObjectOperation *o = (::ObjectOperation *)impl;
+  ::ObjectOperation *o = &impl->o;
   o->omap_get_header(bl, prval);
 }
 
@@ -282,7 +300,7 @@ void librados::ObjectReadOperation::omap_get_vals_by_keys(
   std::map<std::string, bufferlist> *map,
   int *prval)
 {
-  ::ObjectOperation *o = (::ObjectOperation *)impl;
+  ::ObjectOperation *o = &impl->o;
   o->omap_get_vals_by_keys(keys, map, prval);
 }
 
@@ -290,7 +308,7 @@ void librados::ObjectOperation::omap_cmp(
   const std::map<std::string, pair<bufferlist, int> > &assertions,
   int *prval)
 {
-  ::ObjectOperation *o = (::ObjectOperation *)impl;
+  ::ObjectOperation *o = &impl->o;
   o->omap_cmp(assertions, prval);
 }
 
@@ -298,7 +316,7 @@ void librados::ObjectReadOperation::list_watchers(
   list<obj_watch_t> *out_watchers,
   int *prval)
 {
-  ::ObjectOperation *o = (::ObjectOperation *)impl;
+  ::ObjectOperation *o = &impl->o;
   o->list_watchers(out_watchers, prval);
 }
 
@@ -306,13 +324,13 @@ void librados::ObjectReadOperation::list_snaps(
   snap_set_t *out_snaps,
   int *prval)
 {
-  ::ObjectOperation *o = (::ObjectOperation *)impl;
+  ::ObjectOperation *o = &impl->o;
   o->list_snaps(out_snaps, prval);
 }
 
 void librados::ObjectReadOperation::is_dirty(bool *is_dirty, int *prval)
 {
-  ::ObjectOperation *o = (::ObjectOperation *)impl;
+  ::ObjectOperation *o = &impl->o;
   o->is_dirty(is_dirty, prval);
 }
 
@@ -335,98 +353,114 @@ int librados::IoCtx::omap_get_vals(const std::string& oid,
 
 void librados::ObjectReadOperation::getxattrs(map<string, bufferlist> *pattrs, int *prval)
 {
-  ::ObjectOperation *o = (::ObjectOperation *)impl;
+  ::ObjectOperation *o = &impl->o;
   o->getxattrs(pattrs, prval);
 }
 
+void librados::ObjectWriteOperation::mtime(time_t *pt)
+{
+  if (pt) {
+    impl->rt = ceph::real_clock::from_time_t(*pt);
+    impl->prt = &impl->rt;
+  }
+}
+
+void librados::ObjectWriteOperation::mtime2(struct timespec *pts)
+{
+  if (pts) {
+    impl->rt = ceph::real_clock::from_timespec(*pts);
+    impl->prt = &impl->rt;
+  }
+}
+
 void librados::ObjectWriteOperation::create(bool exclusive)
 {
-  ::ObjectOperation *o = (::ObjectOperation *)impl;
+  ::ObjectOperation *o = &impl->o;
   o->create(exclusive);
 }
 
 void librados::ObjectWriteOperation::create(bool exclusive,
 					    const std::string& category) // unused
 {
-  ::ObjectOperation *o = (::ObjectOperation *)impl;
+  ::ObjectOperation *o = &impl->o;
   o->create(exclusive);
 }
 
 void librados::ObjectWriteOperation::write(uint64_t off, const bufferlist& bl)
 {
-  ::ObjectOperation *o = (::ObjectOperation *)impl;
+  ::ObjectOperation *o = &impl->o;
   bufferlist c = bl;
   o->write(off, c);
 }
 
 void librados::ObjectWriteOperation::write_full(const bufferlist& bl)
 {
-  ::ObjectOperation *o = (::ObjectOperation *)impl;
+  ::ObjectOperation *o = &impl->o;
   bufferlist c = bl;
   o->write_full(c);
 }
 
 void librados::ObjectWriteOperation::append(const bufferlist& bl)
 {
-  ::ObjectOperation *o = (::ObjectOperation *)impl;
+  ::ObjectOperation *o = &impl->o;
   bufferlist c = bl;
   o->append(c);
 }
 
 void librados::ObjectWriteOperation::remove()
 {
-  ::ObjectOperation *o = (::ObjectOperation *)impl;
+  ::ObjectOperation *o = &impl->o;
   o->remove();
 }
 
 void librados::ObjectWriteOperation::truncate(uint64_t off)
 {
-  ::ObjectOperation *o = (::ObjectOperation *)impl;
+  ::ObjectOperation *o = &impl->o;
   o->truncate(off);
 }
 
 void librados::ObjectWriteOperation::zero(uint64_t off, uint64_t len)
 {
-  ::ObjectOperation *o = (::ObjectOperation *)impl;
+  ::ObjectOperation *o = &impl->o;
   o->zero(off, len);
 }
 
 void librados::ObjectWriteOperation::rmxattr(const char *name)
 {
-  ::ObjectOperation *o = (::ObjectOperation *)impl;
+  ::ObjectOperation *o = &impl->o;
   o->rmxattr(name);
 }
 
 void librados::ObjectWriteOperation::setxattr(const char *name, const bufferlist& v)
 {
-  ::ObjectOperation *o = (::ObjectOperation *)impl;
+  ::ObjectOperation *o = &impl->o;
   o->setxattr(name, v);
 }
 
 void librados::ObjectWriteOperation::omap_set(
   const map<string, bufferlist> &map)
 {
-  ::ObjectOperation *o = (::ObjectOperation *)impl;
+  ::ObjectOperation *o = &impl->o;
   o->omap_set(map);
 }
 
 void librados::ObjectWriteOperation::omap_set_header(const bufferlist &bl)
 {
   bufferlist c = bl;
-  ::ObjectOperation *o = (::ObjectOperation *)impl;
+  ::ObjectOperation *o = &impl->o;
   o->omap_set_header(c);
 }
 
 void librados::ObjectWriteOperation::omap_clear()
 {
-  ::ObjectOperation *o = (::ObjectOperation *)impl;
+  ::ObjectOperation *o = &impl->o;
   o->omap_clear();
 }
 
 void librados::ObjectWriteOperation::omap_rm_keys(
   const std::set<std::string> &to_rm)
 {
-  ::ObjectOperation *o = (::ObjectOperation *)impl;
+  ::ObjectOperation *o = &impl->o;
   o->omap_rm_keys(to_rm);
 }
 
@@ -442,45 +476,45 @@ void librados::ObjectWriteOperation::copy_from2(const std::string& src,
 					        uint64_t src_version,
 					        uint32_t src_fadvise_flags)
 {
-  ::ObjectOperation *o = (::ObjectOperation *)impl;
+  ::ObjectOperation *o = &impl->o;
   o->copy_from(object_t(src), src_ioctx.io_ctx_impl->snap_seq,
 	       src_ioctx.io_ctx_impl->oloc, src_version, 0, src_fadvise_flags);
 }
 
 void librados::ObjectWriteOperation::undirty()
 {
-  ::ObjectOperation *o = (::ObjectOperation *)impl;
+  ::ObjectOperation *o = &impl->o;
   o->undirty();
 }
 
 void librados::ObjectReadOperation::cache_flush()
 {
-  ::ObjectOperation *o = (::ObjectOperation *)impl;
+  ::ObjectOperation *o = &impl->o;
   o->cache_flush();
 }
 
 void librados::ObjectReadOperation::cache_try_flush()
 {
-  ::ObjectOperation *o = (::ObjectOperation *)impl;
+  ::ObjectOperation *o = &impl->o;
   o->cache_try_flush();
 }
 
 void librados::ObjectReadOperation::cache_evict()
 {
-  ::ObjectOperation *o = (::ObjectOperation *)impl;
+  ::ObjectOperation *o = &impl->o;
   o->cache_evict();
 }
 
 void librados::ObjectWriteOperation::tmap_put(const bufferlist &bl)
 {
-  ::ObjectOperation *o = (::ObjectOperation *)impl;
+  ::ObjectOperation *o = &impl->o;
   bufferlist c = bl;
   o->tmap_put(c);
 }
 
 void librados::ObjectWriteOperation::tmap_update(const bufferlist& cmdbl)
 {
-  ::ObjectOperation *o = (::ObjectOperation *)impl;
+  ::ObjectOperation *o = &impl->o;
   bufferlist c = cmdbl;
   o->tmap_update(c);
 }
@@ -489,20 +523,20 @@ void librados::ObjectWriteOperation::clone_range(uint64_t dst_off,
                      const std::string& src_oid, uint64_t src_off,
                      size_t len)
 {
-  ::ObjectOperation *o = (::ObjectOperation *)impl;
+  ::ObjectOperation *o = &impl->o;
   o->clone_range(src_oid, src_off, len, dst_off);
 }
 
 void librados::ObjectWriteOperation::selfmanaged_snap_rollback(snap_t snapid)
 {
-  ::ObjectOperation *o = (::ObjectOperation *)impl;
+  ::ObjectOperation *o = &impl->o;
   o->rollback(snapid);
 }
 
 // You must specify the snapid not the name normally used with pool snapshots
 void librados::ObjectWriteOperation::snap_rollback(snap_t snapid)
 {
-  ::ObjectOperation *o = (::ObjectOperation *)impl;
+  ::ObjectOperation *o = &impl->o;
   o->rollback(snapid);
 }
 
@@ -510,19 +544,19 @@ void librados::ObjectWriteOperation::set_alloc_hint(
                                             uint64_t expected_object_size,
                                             uint64_t expected_write_size)
 {
-  ::ObjectOperation *o = (::ObjectOperation *)impl;
+  ::ObjectOperation *o = &impl->o;
   o->set_alloc_hint(expected_object_size, expected_write_size);
 }
 
 void librados::ObjectWriteOperation::cache_pin()
 {
-  ::ObjectOperation *o = (::ObjectOperation *)impl;
+  ::ObjectOperation *o = &impl->o;
   o->cache_pin();
 }
 
 void librados::ObjectWriteOperation::cache_unpin()
 {
-  ::ObjectOperation *o = (::ObjectOperation *)impl;
+  ::ObjectOperation *o = &impl->o;
   o->cache_unpin();
 }
 
@@ -1226,6 +1260,12 @@ int librados::IoCtx::stat(const std::string& oid, uint64_t *psize, time_t *pmtim
   return io_ctx_impl->stat(obj, psize, pmtime);
 }
 
+int librados::IoCtx::stat2(const std::string& oid, uint64_t *psize, struct timespec *pts)
+{
+  object_t obj(oid);
+  return io_ctx_impl->stat2(obj, psize, pts);
+}
+
 int librados::IoCtx::exec(const std::string& oid, const char *cls, const char *method,
 			  bufferlist& inbl, bufferlist& outbl)
 {
@@ -1375,7 +1415,7 @@ static int translate_flags(int flags)
 int librados::IoCtx::operate(const std::string& oid, librados::ObjectWriteOperation *o)
 {
   object_t obj(oid);
-  return io_ctx_impl->operate(obj, (::ObjectOperation*)o->impl, o->pmtime);
+  return io_ctx_impl->operate(obj, (::ObjectOperation*)o->impl, (ceph::real_time *)o->impl->prt);
 }
 
 int librados::IoCtx::operate(const std::string& oid, librados::ObjectReadOperation *o, bufferlist *pbl)
@@ -1799,6 +1839,15 @@ int librados::IoCtx::watch2(const string& oid, uint64_t *cookie,
   return io_ctx_impl->watch(obj, cookie, NULL, ctx2);
 }
 
+int librados::IoCtx::aio_watch(const string& oid, AioCompletion *c,
+                               uint64_t *cookie,
+                               librados::WatchCtx2 *ctx2)
+{
+  object_t obj(oid);
+  return io_ctx_impl->aio_watch(obj, c->pc, cookie, NULL, ctx2);
+}
+
+
 int librados::IoCtx::unwatch(const string& oid, uint64_t handle)
 {
   return io_ctx_impl->unwatch(handle);
@@ -1809,6 +1858,11 @@ int librados::IoCtx::unwatch2(uint64_t handle)
   return io_ctx_impl->unwatch(handle);
 }
 
+int librados::IoCtx::aio_unwatch(uint64_t handle, AioCompletion *c)
+{
+  return io_ctx_impl->aio_unwatch(handle, c->pc);
+}
+
 int librados::IoCtx::watch_check(uint64_t handle)
 {
   return io_ctx_impl->watch_check(handle);
@@ -2020,6 +2074,13 @@ int librados::Rados::watch_flush()
   return client->watch_flush();
 }
 
+int librados::Rados::aio_watch_flush(AioCompletion *c)
+{
+  if (!client)
+    return -EINVAL;
+  return client->async_watch_flush(c->pc);
+}
+
 void librados::Rados::shutdown()
 {
   if (!client)
@@ -2280,6 +2341,141 @@ int librados::Rados::cluster_fsid(string *fsid)
   return client->get_fsid(fsid);
 }
 
+namespace librados {
+  struct PlacementGroupImpl {
+    pg_t pgid;
+  };
+
+  PlacementGroup::PlacementGroup()
+    : impl{new PlacementGroupImpl}
+  {}
+
+  PlacementGroup::PlacementGroup(const PlacementGroup& pg)
+    : impl{new PlacementGroupImpl}
+  {
+    impl->pgid = pg.impl->pgid;
+  }
+
+  PlacementGroup::~PlacementGroup()
+  {}
+
+  bool PlacementGroup::parse(const char* s)
+  {
+    return impl->pgid.parse(s);
+  }
+}
+
+std::ostream& librados::operator<<(std::ostream& out,
+				   const librados::PlacementGroup& pg)
+{
+  return out << pg.impl->pgid;
+}
+
+namespace {
+  int decode_json(JSONObj *obj, pg_t& pg)
+  {
+    string pg_str;
+    JSONDecoder::decode_json("pgid", pg_str, obj);
+    if (pg.parse(pg_str.c_str())) {
+      return 0;
+    } else {
+      return -EINVAL;
+    }
+  }
+
+  int get_inconsistent_pgs(librados::RadosClient& client,
+			   int64_t pool_id,
+			   std::vector<librados::PlacementGroup>* pgs)
+  {
+    vector<string> cmd = {
+      "{\"prefix\": \"pg ls\","
+      "\"pool\": " + std::to_string(pool_id) + ","
+      "\"states\": [\"inconsistent\"],"
+      "\"format\": \"json\"}"
+    };
+    bufferlist inbl, outbl;
+    string outstring;
+    int ret = client.mon_command(cmd, inbl, &outbl, &outstring);
+    if (ret) {
+      return ret;
+    }
+    if (!outbl.length()) {
+      // no pg returned
+      return ret;
+    }
+    JSONParser parser;
+    if (!parser.parse(outbl.c_str(), outbl.length())) {
+      return -EINVAL;
+    }
+    if (!parser.is_array()) {
+      return -EINVAL;
+    }
+    vector<string> v = parser.get_array_elements();
+    for (auto i : v) {
+      JSONParser pg_json;
+      if (!pg_json.parse(i.c_str(), i.length())) {
+	return -EINVAL;
+      }
+      librados::PlacementGroup pg;
+      if (decode_json(&pg_json, pg.impl->pgid)) {
+	return -EINVAL;
+      }
+      pgs->emplace_back(pg);
+    }
+    return 0;
+  }
+}
+
+int librados::Rados::get_inconsistent_pgs(int64_t pool_id,
+					  std::vector<PlacementGroup>* pgs)
+{
+  return ::get_inconsistent_pgs(*client, pool_id, pgs);
+}
+
+int librados::Rados::get_inconsistent_objects(const PlacementGroup& pg,
+					      const object_id_t &start_after,
+					      unsigned max_return,
+					      AioCompletion *c,
+					      std::vector<inconsistent_obj_t>* objects,
+					      uint32_t* interval)
+{
+  IoCtx ioctx;
+  const pg_t pgid = pg.impl->pgid;
+  int r = ioctx_create2(pgid.pool(), ioctx);
+  if (r < 0) {
+    return r;
+  }
+
+  return ioctx.io_ctx_impl->get_inconsistent_objects(pgid,
+						     start_after,
+						     max_return,
+						     c->pc,
+						     objects,
+						     interval);
+}
+
+int librados::Rados::get_inconsistent_snapsets(const PlacementGroup& pg,
+					       const object_id_t &start_after,
+					       unsigned max_return,
+					       AioCompletion *c,
+					       std::vector<inconsistent_snapset_t>* snapsets,
+					       uint32_t* interval)
+{
+  IoCtx ioctx;
+  const pg_t pgid = pg.impl->pgid;
+  int r = ioctx_create2(pgid.pool(), ioctx);
+  if (r < 0) {
+    return r;
+  }
+
+  return ioctx.io_ctx_impl->get_inconsistent_snapsets(pgid,
+						      start_after,
+						      max_return,
+						      c->pc,
+						      snapsets,
+						      interval);
+}
+
 int librados::Rados::wait_for_latest_osdmap()
 {
   return client->wait_for_latest_osdmap();
@@ -2315,14 +2511,12 @@ librados::AioCompletion *librados::Rados::aio_create_completion(void *cb_arg,
 
 librados::ObjectOperation::ObjectOperation()
 {
-  impl = (ObjectOperationImpl *)new ::ObjectOperation;
+  impl = new ObjectOperationImpl;
 }
 
 librados::ObjectOperation::~ObjectOperation()
 {
-  ::ObjectOperation *o = (::ObjectOperation *)impl;
-  if (o)
-    delete o;
+  delete impl;
 }
 
 ///////////////////////////// C API //////////////////////////////
@@ -2348,7 +2542,7 @@ extern "C" int rados_create(rados_t *pcluster, const char * const id)
   if (id) {
     iparams.name.set(CEPH_ENTITY_TYPE_CLIENT, id);
   }
-  CephContext *cct = rados_create_cct("ceph", &iparams);
+  CephContext *cct = rados_create_cct("", &iparams);
 
   tracepoint(librados, rados_create_enter, id);
   *pcluster = reinterpret_cast<rados_t>(new librados::RadosClient(cct));
@@ -2456,8 +2650,7 @@ extern "C" int rados_conf_read_file(rados_t cluster, const char *path_list)
   tracepoint(librados, rados_conf_read_file_enter, cluster, path_list);
   librados::RadosClient *client = (librados::RadosClient *)cluster;
   md_config_t *conf = client->cct->_conf;
-  std::deque<std::string> parse_errors;
-  int ret = conf->parse_config_files(path_list, &parse_errors, NULL, 0);
+  int ret = conf->parse_config_files(path_list, NULL, 0);
   if (ret) {
     tracepoint(librados, rados_conf_read_file_exit, ret);
     return ret;
@@ -2465,7 +2658,7 @@ extern "C" int rados_conf_read_file(rados_t cluster, const char *path_list)
   conf->parse_env(); // environment variables override
 
   conf->apply_changes(NULL);
-  complain_about_parse_errors(client->cct, &parse_errors);
+  client->cct->_conf->complain_about_parse_errors(client->cct);
   tracepoint(librados, rados_conf_read_file_exit, 0);
   return 0;
 }
@@ -2693,6 +2886,45 @@ extern "C" int rados_pool_list(rados_t cluster, char *buf, size_t len)
   return retval;
 }
 
+CEPH_RADOS_API int rados_inconsistent_pg_list(rados_t cluster, int64_t pool_id,
+					      char *buf, size_t len)
+{
+  tracepoint(librados, rados_inconsistent_pg_list_enter, cluster, pool_id, len);
+  librados::RadosClient *client = (librados::RadosClient *)cluster;
+  std::vector<librados::PlacementGroup> pgs;
+  int r = ::get_inconsistent_pgs(*client, pool_id, &pgs);
+  if (r < 0) {
+    tracepoint(librados, rados_inconsistent_pg_list_exit, r);
+    return r;
+  }
+
+  if (len > 0 && !buf) {
+    tracepoint(librados, rados_inconsistent_pg_list_exit, -EINVAL);
+    return -EINVAL;
+  }
+
+  char *b = buf;
+  if (b)
+    memset(b, 0, len);
+  int needed = 0;
+  for (const auto pg : pgs) {
+    std::ostringstream ss;
+    ss << pg;
+    auto s = ss.str();
+    unsigned rl = s.length() + 1;
+    if (len >= rl) {
+      tracepoint(librados, rados_inconsistent_pg_list_pg, s.c_str());
+      strncat(b, s.c_str(), rl);
+      b += rl;
+      len -= rl;
+    }
+    needed += rl;
+  }
+  int retval = needed + 1;
+  tracepoint(librados, rados_inconsistent_pg_list_exit, retval);
+  return retval;
+}
+
 static void do_out_buffer(bufferlist& outbl, char **outbuf, size_t *outbuflen)
 {
   if (outbuf) {
@@ -3095,7 +3327,7 @@ extern "C" int rados_read(rados_ioctx_t io, const char *o, char *buf, size_t len
       tracepoint(librados, rados_read_exit, -ERANGE, NULL);
       return -ERANGE;
     }
-    if (bl.c_str() != buf)
+    if (!bl.is_provided_buffer(buf))
       bl.copy(0, bl.length(), buf);
     ret = bl.length();    // hrm :/
   }
@@ -3445,7 +3677,7 @@ extern "C" int rados_getxattr(rados_ioctx_t io, const char *o, const char *name,
       tracepoint(librados, rados_getxattr_exit, -ERANGE, buf, 0);
       return -ERANGE;
     }
-    if (bl.c_str() !=  buf)
+    if (!bl.is_provided_buffer(buf))
       bl.copy(0, bl.length(), buf);
     ret = bl.length();
   }
@@ -3678,6 +3910,8 @@ extern "C" int rados_object_list(rados_ioctx_t io,
     const rados_object_list_cursor start,
     const rados_object_list_cursor finish,
     const size_t result_item_count,
+    const char *filter_buf,
+    const size_t filter_buf_len,
     rados_object_list_item *result_items,
     rados_object_list_cursor *next)
 {
@@ -3691,6 +3925,11 @@ extern "C" int rados_object_list(rados_ioctx_t io,
   std::list<librados::ListObjectImpl> result;
   hobject_t next_hash;
 
+  bufferlist filter_bl;
+  if (filter_buf != nullptr) {
+    filter_bl.append(filter_buf, filter_buf_len);
+  }
+
   C_SaferCond cond;
   ctx->objecter->enumerate_objects(
       ctx->poolid,
@@ -3698,6 +3937,7 @@ extern "C" int rados_object_list(rados_ioctx_t io,
       *((hobject_t*)start),
       *((hobject_t*)finish),
       result_item_count,
+      filter_bl,
       &result,
       &next_hash,
       &cond);
@@ -4209,6 +4449,30 @@ extern "C" int rados_watch2(rados_ioctx_t io, const char *o, uint64_t *handle,
   return ret;
 }
 
+extern "C" int rados_aio_watch(rados_ioctx_t io, const char *o,
+                               rados_completion_t completion,
+                               uint64_t *handle,
+                               rados_watchcb2_t watchcb,
+                               rados_watcherrcb_t watcherrcb, void *arg)
+{
+  tracepoint(librados, rados_aio_watch_enter, io, o, completion, handle, watchcb, arg);
+  int ret;
+  if (!completion || !watchcb || !o || !handle) {
+    ret = -EINVAL;
+  } else {
+    uint64_t *cookie = handle;
+    librados::IoCtxImpl *ctx = (librados::IoCtxImpl *)io;
+    object_t oid(o);
+    librados::AioCompletionImpl *c =
+      reinterpret_cast<librados::AioCompletionImpl*>(completion);
+    C_WatchCB2 *wc = new C_WatchCB2(watchcb, watcherrcb, arg);
+    ret = ctx->aio_watch(oid, c, cookie, NULL, wc);
+  }
+  tracepoint(librados, rados_watch_exit, ret, handle ? *handle : 0);
+  return ret;
+}
+
+
 extern "C" int rados_unwatch(rados_ioctx_t io, const char *o, uint64_t handle)
 {
   tracepoint(librados, rados_unwatch_enter, io, o, handle);
@@ -4229,6 +4493,19 @@ extern "C" int rados_unwatch2(rados_ioctx_t io, uint64_t handle)
   return retval;
 }
 
+extern "C" int rados_aio_unwatch(rados_ioctx_t io, uint64_t handle,
+                                 rados_completion_t completion)
+{
+  tracepoint(librados, rados_aio_unwatch_enter, io, handle, completion);
+  uint64_t cookie = handle;
+  librados::IoCtxImpl *ctx = (librados::IoCtxImpl *)io;
+  librados::AioCompletionImpl *c =
+    reinterpret_cast<librados::AioCompletionImpl*>(completion);
+  int retval = ctx->aio_unwatch(cookie, c);
+  tracepoint(librados, rados_aio_unwatch_exit, retval);
+  return retval;
+}
+
 extern "C" int rados_watch_check(rados_ioctx_t io, uint64_t handle)
 {
   tracepoint(librados, rados_watch_check_enter, io, handle);
@@ -4325,6 +4602,16 @@ extern "C" int rados_watch_flush(rados_t cluster)
   return retval;
 }
 
+extern "C" int rados_aio_watch_flush(rados_t cluster, rados_completion_t completion)
+{
+  tracepoint(librados, rados_aio_watch_flush_enter, cluster, completion);
+  librados::RadosClient *client = (librados::RadosClient *)cluster;
+  librados::AioCompletionImpl *c = (librados::AioCompletionImpl*)completion;
+  int retval = client->async_watch_flush(c);
+  tracepoint(librados, rados_aio_watch_flush_exit, retval);
+  return retval;
+}
+
 extern "C" int rados_set_alloc_hint(rados_ioctx_t io, const char *o,
                                     uint64_t expected_object_size,
                                     uint64_t expected_write_size)
@@ -4696,7 +4983,40 @@ extern "C" int rados_write_op_operate(rados_write_op_t write_op,
   object_t obj(oid);
   ::ObjectOperation *oo = (::ObjectOperation *) write_op;
   librados::IoCtxImpl *ctx = (librados::IoCtxImpl *)io;
-  int retval = ctx->operate(obj, oo, mtime, translate_flags(flags));
+
+  ceph::real_time *prt = NULL;
+  ceph::real_time rt;
+
+  if (mtime) {
+    rt = ceph::real_clock::from_time_t(*mtime);
+    prt = &rt;
+  }
+
+  int retval = ctx->operate(obj, oo, prt, translate_flags(flags));
+  tracepoint(librados, rados_write_op_operate_exit, retval);
+  return retval;
+}
+
+extern "C" int rados_write_op_operate2(rados_write_op_t write_op,
+                                       rados_ioctx_t io,
+                                       const char *oid,
+                                       struct timespec *ts,
+                                       int flags)
+{
+  tracepoint(librados, rados_write_op_operate2_enter, write_op, io, oid, ts, flags);
+  object_t obj(oid);
+  ::ObjectOperation *oo = (::ObjectOperation *) write_op;
+  librados::IoCtxImpl *ctx = (librados::IoCtxImpl *)io;
+
+  ceph::real_time *prt = NULL;
+  ceph::real_time rt;
+
+  if (ts) {
+    rt = ceph::real_clock::from_timespec(*ts);
+    prt = &rt;
+  }
+
+  int retval = ctx->operate(obj, oo, prt, translate_flags(flags));
   tracepoint(librados, rados_write_op_operate_exit, retval);
   return retval;
 }
@@ -4815,7 +5135,7 @@ public:
     }
     if (bytes_read)
       *bytes_read = out_bl.length();
-    if (out_buf && out_bl.c_str() != out_buf)
+    if (out_buf && !out_bl.is_provided_buffer(out_buf))
       out_bl.copy(0, out_bl.length(), out_buf);
   }
 };
@@ -5223,6 +5543,7 @@ bool librados::IoCtx::object_list_is_end(const ObjectCursor &oc)
 int librados::IoCtx::object_list(const ObjectCursor &start,
                 const ObjectCursor &finish,
                 const size_t result_item_count,
+                const bufferlist &filter,
                 std::vector<ObjectItem> *result,
                 ObjectCursor *next)
 {
@@ -5239,6 +5560,7 @@ int librados::IoCtx::object_list(const ObjectCursor &start,
       *((hobject_t*)start.c_cursor),
       *((hobject_t*)finish.c_cursor),
       result_item_count,
+      filter,
       &obj_result,
       &next_hash,
       &cond);
diff --git a/src/librados/snap_set_diff.cc b/src/librados/snap_set_diff.cc
index 5db0fb9..9fb166f 100644
--- a/src/librados/snap_set_diff.cc
+++ b/src/librados/snap_set_diff.cc
@@ -15,15 +15,16 @@
  * calculate intervals/extents that vary between two snapshots
  */
 void calc_snap_set_diff(CephContext *cct, const librados::snap_set_t& snap_set,
-			librados::snap_t start,
-			librados::snap_t end,
-			interval_set<uint64_t> *diff, bool *end_exists)
+			librados::snap_t start, librados::snap_t end,
+			interval_set<uint64_t> *diff, uint64_t *end_size,
+                        bool *end_exists)
 {
   ldout(cct, 10) << "calc_snap_set_diff start " << start << " end " << end
 		 << ", snap_set seq " << snap_set.seq << dendl;
   bool saw_start = false;
   uint64_t start_size = 0;
   diff->clear();
+  *end_size = 0;
   *end_exists = false;
 
   for (vector<librados::clone_info_t>::const_iterator r = snap_set.clones.begin();
@@ -44,7 +45,7 @@ void calc_snap_set_diff(CephContext *cct, const librados::snap_set_t& snap_set,
     ldout(cct, 20) << " clone " << r->cloneid << " snaps " << r->snaps
 		   << " -> [" << a << "," << b << "]"
 		   << " size " << r->size << " overlap to next " << r->overlap << dendl;
-    
+
     if (b < start) {
       // this is before start
       ++r;
@@ -65,6 +66,7 @@ void calc_snap_set_diff(CephContext *cct, const librados::snap_set_t& snap_set,
       saw_start = true;
     }
 
+    *end_size = r->size;
     if (end < a) {
       ldout(cct, 20) << " past end " << end << ", end object does not exist" << dendl;
       *end_exists = false;
diff --git a/src/librados/snap_set_diff.h b/src/librados/snap_set_diff.h
index 7bc75cd..acb7196 100644
--- a/src/librados/snap_set_diff.h
+++ b/src/librados/snap_set_diff.h
@@ -11,7 +11,7 @@ class CephContext;
 void calc_snap_set_diff(CephContext *cct,
 			const librados::snap_set_t& snap_set,
 			librados::snap_t start, librados::snap_t end,
-			interval_set<uint64_t> *diff,
+			interval_set<uint64_t> *diff, uint64_t *end_size,
 			bool *end_exists);
 
 #endif
diff --git a/src/libradosstriper/RadosStriperImpl.cc b/src/libradosstriper/RadosStriperImpl.cc
index e9b3bd5..26833ea 100644
--- a/src/libradosstriper/RadosStriperImpl.cc
+++ b/src/libradosstriper/RadosStriperImpl.cc
@@ -105,8 +105,17 @@
 /// format of the extension of rados objects created for a given striped object
 #define RADOS_OBJECT_EXTENSION_FORMAT ".%016llx"
 
-/// default object layout (external declaration)
-extern ceph_file_layout g_default_file_layout;
+/// default object layout
+struct ceph_file_layout default_file_layout = {
+ fl_stripe_unit: init_le32(1<<22),
+ fl_stripe_count: init_le32(1),
+ fl_object_size: init_le32(1<<22),
+ fl_cas_hash: init_le32(0),
+ fl_object_stripe_unit: init_le32(0),
+ fl_unused: init_le32(-1),
+ fl_pg_pool : init_le32(-1),
+};
+
 
 ///////////////////////// CompletionData /////////////////////////////
 
@@ -204,7 +213,7 @@ libradosstriper::RadosStriperImpl::RadosExclusiveLock::~RadosExclusiveLock() {
 
 libradosstriper::RadosStriperImpl::RadosStriperImpl(librados::IoCtx& ioctx, librados::IoCtxImpl *ioctx_impl) :
   m_refCnt(0),lock("RadosStriper Refcont", false, false), m_radosCluster(ioctx), m_ioCtx(ioctx), m_ioCtxImpl(ioctx_impl),
-  m_layout(g_default_file_layout) {}
+  m_layout(default_file_layout) {}
 
 ///////////////////////// layout /////////////////////////////
 
@@ -458,7 +467,10 @@ int libradosstriper::RadosStriperImpl::aio_read(const std::string& soid,
   vector<ObjectExtent> *extents = new vector<ObjectExtent>();
   if (read_len > 0) {
     std::string format = soid + RADOS_OBJECT_EXTENSION_FORMAT;
-    Striper::file_to_extents(cct(), format.c_str(), &layout, off, read_len, 0, *extents);
+    file_layout_t l;
+    l.from_legacy(layout);
+    Striper::file_to_extents(cct(), format.c_str(), &l, off, read_len,
+			     0, *extents);
   }
   
   // create a completion object and transfer ownership of extents and resultbl
@@ -761,7 +773,9 @@ libradosstriper::RadosStriperImpl::internal_aio_write(const std::string& soid,
   // get list of extents to be written to
   vector<ObjectExtent> extents;
   std::string format = soid + RADOS_OBJECT_EXTENSION_FORMAT;
-  Striper::file_to_extents(cct(), format.c_str(), &layout, off, len, 0, extents);
+  file_layout_t l;
+  l.from_legacy(layout);
+  Striper::file_to_extents(cct(), format.c_str(), &l, off, len, 0, extents);
   // go through the extents
   int r = 0;
   for (vector<ObjectExtent>::iterator p = extents.begin(); p != extents.end(); ++p) {
@@ -829,9 +843,10 @@ int libradosstriper::RadosStriperImpl::extract_sizet_attr
   return 0;
 }
 
-int libradosstriper::RadosStriperImpl::internal_get_layout_and_size(const std::string& oid,
-								    ceph_file_layout *layout,
-								    uint64_t *size) 
+int libradosstriper::RadosStriperImpl::internal_get_layout_and_size(
+  const std::string& oid,
+  ceph_file_layout *layout,
+  uint64_t *size)
 {
   // get external attributes of the first rados object
   std::map<std::string, bufferlist> attrs;
@@ -853,10 +868,11 @@ int libradosstriper::RadosStriperImpl::internal_get_layout_and_size(const std::s
   return rc;
 }
 
-int libradosstriper::RadosStriperImpl::openStripedObjectForRead(const std::string& soid,
-								ceph_file_layout *layout,
-								uint64_t *size,
-								std::string *lockCookie)
+int libradosstriper::RadosStriperImpl::openStripedObjectForRead(
+  const std::string& soid,
+  ceph_file_layout *layout,
+  uint64_t *size,
+  std::string *lockCookie)
 {
   // take a lock the first rados object, if it exists and gets its size
   // check, lock and size reading must be atomic and are thus done within a single operation
@@ -1033,7 +1049,9 @@ int libradosstriper::RadosStriperImpl::truncate(const std::string& soid,
     }
     if (exists) {
       // truncate
-      uint64_t new_object_size = Striper::object_truncate_size(cct(), &layout, objectno, size);
+      file_layout_t l;
+      l.from_legacy(layout);
+      uint64_t new_object_size = Striper::object_truncate_size(cct(), &l, objectno, size);
       int rc;
       if (new_object_size > 0 or 0 == objectno) {
 	rc = m_ioCtx.trunc(getObjectId(soid, objectno), new_object_size);
diff --git a/src/libradosstriper/libradosstriper.cc b/src/libradosstriper/libradosstriper.cc
index 969f2d8..352fe39 100644
--- a/src/libradosstriper/libradosstriper.cc
+++ b/src/libradosstriper/libradosstriper.cc
@@ -395,7 +395,7 @@ extern "C" int rados_striper_read(rados_striper_t striper,
   if (ret >= 0) {
     if (bl.length() > len)
       return -ERANGE;
-    if (bl.c_str() != buf)
+    if (!bl.is_provided_buffer(buf))
       bl.copy(0, bl.length(), buf);
     ret = bl.length();    // hrm :/
   }
diff --git a/src/librbd/AioCompletion.cc b/src/librbd/AioCompletion.cc
index ab71c3c..3501032 100644
--- a/src/librbd/AioCompletion.cc
+++ b/src/librbd/AioCompletion.cc
@@ -44,21 +44,25 @@ namespace librbd {
                    << "read_buf=" << reinterpret_cast<void*>(read_buf) << ", "
                    << "real_bl=" <<  reinterpret_cast<void*>(read_bl) << dendl;
     if (rval >= 0 && aio_type == AIO_TYPE_READ) {
-      // FIXME: make the destriper write directly into a buffer so
-      // that we avoid shuffling pointers and copying zeros around.
-      bufferlist bl;
-      destriper.assemble_result(cct, bl, true);
-
-      if (read_buf) {
-	assert(bl.length() == read_buf_len);
-	bl.copy(0, read_buf_len, read_buf);
-	ldout(cct, 20) << "copied resulting " << bl.length()
-		       << " bytes to " << (void*)read_buf << dendl;
-      }
-      if (read_bl) {
-	ldout(cct, 20) << "moving resulting " << bl.length()
-		       << " bytes to bl " << (void*)read_bl << dendl;
-	read_bl->claim(bl);
+      if (read_buf && !read_bl) {
+	destriper.assemble_result(cct, read_buf, read_buf_len);
+      } else {
+	// FIXME: make the destriper write directly into a buffer so
+	// that we avoid shuffling pointers and copying zeros around.
+	bufferlist bl;
+	destriper.assemble_result(cct, bl, true);
+
+	if (read_buf) {
+	  assert(bl.length() == read_buf_len);
+	  bl.copy(0, read_buf_len, read_buf);
+	  ldout(cct, 20) << "copied resulting " << bl.length()
+	    << " bytes to " << (void*)read_buf << dendl;
+	}
+	if (read_bl) {
+	  ldout(cct, 20) << " moving resulting " << bl.length()
+	    << " bytes to bl " << (void*)read_bl << dendl;
+	  read_bl->claim(bl);
+	}
       }
     }
   }
@@ -91,12 +95,7 @@ namespace librbd {
       ictx->journal->commit_io_event(journal_tid, rval);
     }
 
-    // note: possible for image to be closed after op marked finished
     done = true;
-    if (async_op.started()) {
-      async_op.finish_op();
-    }
-
     if (complete_cb) {
       lock.Unlock();
       complete_cb(rbd_comp, complete_arg);
@@ -110,6 +109,11 @@ namespace librbd {
       ictx->event_socket.notify();
     }
     cond.Signal();
+
+    // note: possible for image to be closed after op marked finished
+    if (async_op.started()) {
+      async_op.finish_op();
+    }
     tracepoint(librbd, aio_complete_exit);
   }
 
diff --git a/src/librbd/AioImageRequest.cc b/src/librbd/AioImageRequest.cc
index fc77ea7..e7cfd39 100644
--- a/src/librbd/AioImageRequest.cc
+++ b/src/librbd/AioImageRequest.cc
@@ -222,7 +222,6 @@ void AbstractAioImageWrite::send_request() {
   RWLock::RLocker md_locker(m_image_ctx.md_lock);
 
   bool journaling = false;
-  uint64_t journal_tid = 0;
 
   uint64_t clip_len = m_len;
   ObjectExtents object_extents;
@@ -257,6 +256,7 @@ void AbstractAioImageWrite::send_request() {
   }
 
   if (!object_extents.empty()) {
+    uint64_t journal_tid = 0;
     m_aio_comp->set_request_count(
       cct, object_extents.size() + get_cache_request_count(journaling));
 
@@ -414,11 +414,11 @@ AioObjectRequest *AioImageDiscard::create_object_request(
   CephContext *cct = m_image_ctx.cct;
 
   AioObjectRequest *req;
-  if (object_extent.length == m_image_ctx.layout.fl_object_size) {
+  if (object_extent.length == m_image_ctx.layout.object_size) {
     req = new AioObjectRemove(&m_image_ctx, object_extent.oid.name,
                               object_extent.objectno, snapc, on_finish);
   } else if (object_extent.offset + object_extent.length ==
-               m_image_ctx.layout.fl_object_size) {
+               m_image_ctx.layout.object_size) {
     req = new AioObjectTruncate(&m_image_ctx, object_extent.oid.name,
                                 object_extent.objectno, object_extent.offset,
                                 snapc, on_finish);
diff --git a/src/librbd/AioImageRequestWQ.cc b/src/librbd/AioImageRequestWQ.cc
index 2de18d3..352b7e9 100644
--- a/src/librbd/AioImageRequestWQ.cc
+++ b/src/librbd/AioImageRequestWQ.cc
@@ -22,8 +22,8 @@ AioImageRequestWQ::AioImageRequestWQ(ImageCtx *image_ctx, const string &name,
   : ThreadPool::PointerWQ<AioImageRequest<> >(name, ti, 0, tp),
     m_image_ctx(*image_ctx),
     m_lock(util::unique_lock_name("AioImageRequestWQ::m_lock", this)),
-    m_write_blockers(0), m_in_progress_writes(0), m_queued_writes(0),
-    m_in_flight_ops(0), m_refresh_in_progress(false),
+    m_write_blockers(0), m_in_progress_writes(0), m_queued_reads(0),
+    m_queued_writes(0), m_in_flight_ops(0), m_refresh_in_progress(false),
     m_shutdown(false), m_on_shutdown(nullptr) {
   CephContext *cct = m_image_ctx.cct;
   ldout(cct, 5) << this << " " << ": ictx=" << image_ctx << dendl;
@@ -112,7 +112,17 @@ void AioImageRequestWQ::aio_read(AioCompletion *c, uint64_t off, uint64_t len,
   }
 
   RWLock::RLocker owner_locker(m_image_ctx.owner_lock);
-  if (m_image_ctx.non_blocking_aio || writes_blocked() || !writes_empty()) {
+
+  // if journaling is enabled -- we need to replay the journal because
+  // it might contain an uncommitted write
+  bool lock_required;
+  {
+    RWLock::RLocker locker(m_lock);
+    lock_required = m_require_lock_on_read;
+  }
+
+  if (m_image_ctx.non_blocking_aio || writes_blocked() || !writes_empty() ||
+      lock_required) {
     queue(new AioImageRead(m_image_ctx, c, off, len, buf, pbl, op_flags));
   } else {
     AioImageRequest<>::aio_read(&m_image_ctx, c, off, len, buf, pbl, op_flags);
@@ -138,8 +148,7 @@ void AioImageRequestWQ::aio_write(AioCompletion *c, uint64_t off, uint64_t len,
   }
 
   RWLock::RLocker owner_locker(m_image_ctx.owner_lock);
-  if (m_image_ctx.non_blocking_aio || is_journal_required() ||
-      writes_blocked()) {
+  if (m_image_ctx.non_blocking_aio || writes_blocked()) {
     queue(new AioImageWrite(m_image_ctx, c, off, len, buf, op_flags));
   } else {
     AioImageRequest<>::aio_write(&m_image_ctx, c, off, len, buf, op_flags);
@@ -164,8 +173,7 @@ void AioImageRequestWQ::aio_discard(AioCompletion *c, uint64_t off,
   }
 
   RWLock::RLocker owner_locker(m_image_ctx.owner_lock);
-  if (m_image_ctx.non_blocking_aio || is_journal_required() ||
-      writes_blocked()) {
+  if (m_image_ctx.non_blocking_aio || writes_blocked()) {
     queue(new AioImageDiscard(m_image_ctx, c, off, len));
   } else {
     AioImageRequest<>::aio_discard(&m_image_ctx, c, off, len);
@@ -188,8 +196,7 @@ void AioImageRequestWQ::aio_flush(AioCompletion *c, bool native_async) {
   }
 
   RWLock::RLocker owner_locker(m_image_ctx.owner_lock);
-  if (m_image_ctx.non_blocking_aio || is_journal_required() ||
-      writes_blocked() || !writes_empty()) {
+  if (m_image_ctx.non_blocking_aio || writes_blocked() || !writes_empty()) {
     queue(new AioImageFlush(m_image_ctx, c));
   } else {
     AioImageRequest<>::aio_flush(&m_image_ctx, c);
@@ -218,6 +225,12 @@ void AioImageRequestWQ::shut_down(Context *on_shutdown) {
   m_image_ctx.flush(on_shutdown);
 }
 
+bool AioImageRequestWQ::is_lock_request_needed() const {
+  RWLock::RLocker locker(m_lock);
+  return (m_queued_writes.read() > 0 ||
+          (m_require_lock_on_read && m_queued_reads.read() > 0));
+}
+
 void AioImageRequestWQ::block_writes() {
   C_SaferCond cond_ctx;
   block_writes(&cond_ctx);
@@ -264,18 +277,45 @@ void AioImageRequestWQ::unblock_writes() {
   }
 }
 
+void AioImageRequestWQ::set_require_lock_on_read() {
+  CephContext *cct = m_image_ctx.cct;
+  ldout(cct, 20) << __func__ << dendl;
+
+  RWLock::WLocker locker(m_lock);
+  m_require_lock_on_read = true;
+}
+
+void AioImageRequestWQ::clear_require_lock_on_read() {
+  CephContext *cct = m_image_ctx.cct;
+  ldout(cct, 20) << __func__ << dendl;
+
+  {
+    RWLock::WLocker locker(m_lock);
+    if (!m_require_lock_on_read) {
+      return;
+    }
+
+    m_require_lock_on_read = false;
+  }
+  signal();
+}
+
 void *AioImageRequestWQ::_void_dequeue() {
   AioImageRequest<> *peek_item = front();
   if (peek_item == NULL || m_refresh_in_progress) {
     return NULL;
   }
 
-  if (peek_item->is_write_op()) {
+  {
     RWLock::RLocker locker(m_lock);
-    if (m_write_blockers > 0) {
-      return NULL;
+    if (peek_item->is_write_op()) {
+      if (m_write_blockers > 0) {
+        return NULL;
+      }
+      m_in_progress_writes.inc();
+    } else if (m_require_lock_on_read) {
+      return nullptr;
     }
-    m_in_progress_writes.inc();
   }
 
   AioImageRequest<> *item = reinterpret_cast<AioImageRequest<> *>(
@@ -317,6 +357,9 @@ void AioImageRequestWQ::process(AioImageRequest<> *req) {
           !m_write_blocker_contexts.empty()) {
         writes_blocked = true;
       }
+    } else {
+      assert(m_queued_reads.read() > 0);
+      m_queued_reads.dec();
     }
   }
 
@@ -361,12 +404,6 @@ void AioImageRequestWQ::finish_in_flight_op() {
   m_image_ctx.flush(m_on_shutdown);
 }
 
-bool AioImageRequestWQ::is_journal_required() const {
-  // TODO eliminate once journal startup state is integrated
-  RWLock::RLocker snap_locker(m_image_ctx.snap_lock);
-  return (m_image_ctx.journal != NULL);
-}
-
 bool AioImageRequestWQ::is_lock_required() const {
   assert(m_image_ctx.owner_lock.is_locked());
   if (m_image_ctx.exclusive_lock == NULL) {
@@ -385,11 +422,14 @@ void AioImageRequestWQ::queue(AioImageRequest<> *req) {
   bool write_op = req->is_write_op();
   if (write_op) {
     m_queued_writes.inc();
+  } else {
+    m_queued_reads.inc();
   }
 
   ThreadPool::PointerWQ<AioImageRequest<> >::queue(req);
 
-  if (write_op && is_lock_required()) {
+  if ((write_op && is_lock_required()) ||
+      (!write_op && m_require_lock_on_read)) {
     m_image_ctx.exclusive_lock->request_lock(nullptr);
   }
 }
diff --git a/src/librbd/AioImageRequestWQ.h b/src/librbd/AioImageRequestWQ.h
index 1573e72..fa429fc 100644
--- a/src/librbd/AioImageRequestWQ.h
+++ b/src/librbd/AioImageRequestWQ.h
@@ -37,22 +37,22 @@ public:
   using typename ThreadPool::PointerWQ<AioImageRequest<ImageCtx> >::drain;
   using typename ThreadPool::PointerWQ<AioImageRequest<ImageCtx> >::empty;
 
-  inline bool writes_empty() const {
-    RWLock::RLocker locker(m_lock);
-    return (m_queued_writes.read() == 0);
-  }
+  void shut_down(Context *on_shutdown);
+
+  bool is_lock_request_needed() const;
 
   inline bool writes_blocked() const {
     RWLock::RLocker locker(m_lock);
     return (m_write_blockers > 0);
   }
 
-  void shut_down(Context *on_shutdown);
-
   void block_writes();
   void block_writes(Context *on_blocked);
   void unblock_writes();
 
+  void set_require_lock_on_read();
+  void clear_require_lock_on_read();
+
 protected:
   virtual void *_void_dequeue();
   virtual void process(AioImageRequest<ImageCtx> *req);
@@ -88,7 +88,9 @@ private:
   mutable RWLock m_lock;
   Contexts m_write_blocker_contexts;
   uint32_t m_write_blockers;
+  bool m_require_lock_on_read = false;
   atomic_t m_in_progress_writes;
+  atomic_t m_queued_reads;
   atomic_t m_queued_writes;
   atomic_t m_in_flight_ops;
 
@@ -97,10 +99,14 @@ private:
   bool m_shutdown;
   Context *m_on_shutdown;
 
+  inline bool writes_empty() const {
+    RWLock::RLocker locker(m_lock);
+    return (m_queued_writes.read() == 0);
+  }
+
   int start_in_flight_op(AioCompletion *c);
   void finish_in_flight_op();
 
-  bool is_journal_required() const;
   bool is_lock_required() const;
   void queue(AioImageRequest<ImageCtx> *req);
 
diff --git a/src/librbd/AioObjectRequest.cc b/src/librbd/AioObjectRequest.cc
index 96669ea..77aaa7e 100644
--- a/src/librbd/AioObjectRequest.cc
+++ b/src/librbd/AioObjectRequest.cc
@@ -37,7 +37,7 @@ namespace librbd {
       m_hide_enoent(hide_enoent) {
 
     Striper::extent_to_file(m_ictx->cct, &m_ictx->layout, m_object_no,
-                            0, m_ictx->layout.fl_object_size, m_parent_extents);
+                            0, m_ictx->layout.object_size, m_parent_extents);
 
     RWLock::RLocker snap_locker(m_ictx->snap_lock);
     RWLock::RLocker parent_locker(m_ictx->parent_lock);
@@ -575,4 +575,15 @@ namespace librbd {
 			   << m_object_off << "~" << m_object_len << dendl;
     send_write_op(true);
   }
+  void AioObjectTruncate::send_write() {
+    ldout(m_ictx->cct, 20) << "send_write " << this << " " << m_oid
+			   << " truncate " << m_object_off << dendl;
+    if (!m_object_exist && ! has_parent()) {
+      m_state = LIBRBD_AIO_WRITE_FLAT;
+      Context *ctx = util::create_context_callback<AioObjectRequest>(this);
+      m_ictx->op_work_queue->queue(ctx, 0);
+    } else {
+      AbstractAioObjectWrite::send_write();
+    }
+  }
 }
diff --git a/src/librbd/AioObjectRequest.h b/src/librbd/AioObjectRequest.h
index 7aa06c1..2e9226e 100644
--- a/src/librbd/AioObjectRequest.h
+++ b/src/librbd/AioObjectRequest.h
@@ -318,8 +318,12 @@ namespace librbd {
     }
 
     virtual void pre_object_map_update(uint8_t *new_state) {
-      *new_state = OBJECT_EXISTS;
+      if (!m_object_exist && !has_parent())
+        *new_state = OBJECT_NONEXISTENT;
+      else
+	*new_state = OBJECT_EXISTS;
     }
+    virtual void send_write();
   };
 
   class AioObjectZero : public AbstractAioObjectWrite {
diff --git a/src/librbd/DiffIterate.cc b/src/librbd/DiffIterate.cc
index 9e4bc17..df8287d 100644
--- a/src/librbd/DiffIterate.cc
+++ b/src/librbd/DiffIterate.cc
@@ -113,7 +113,6 @@ private:
   ImageCtx &m_image_ctx;
   librados::IoCtx &m_head_ctx;
   DiffContext &m_diff_context;
-  uint64_t m_request_num;
   std::string m_oid;
   uint64_t m_offset;
   std::vector<ObjectExtent> m_object_extents;
@@ -126,9 +125,11 @@ private:
 
     // calc diff from from_snap_id -> to_snap_id
     interval_set<uint64_t> diff;
+    uint64_t end_size;
     bool end_exists;
     calc_snap_set_diff(cct, m_snap_set, m_diff_context.from_snap_id,
-                       m_diff_context.end_snap_id, &diff, &end_exists);
+                       m_diff_context.end_snap_id, &diff, &end_size,
+                       &end_exists);
     ldout(cct, 20) << "  diff " << diff << " end_exists=" << end_exists
                    << dendl;
     if (diff.empty()) {
@@ -350,7 +351,6 @@ int DiffIterate::diff_object_map(uint64_t from_snap_id, uint64_t to_snap_id,
   }
 
   object_diff_state->clear();
-  int r;
   uint64_t current_snap_id = from_snap_id;
   uint64_t next_snap_id = to_snap_id;
   BitVector<2> prev_object_map;
@@ -372,7 +372,7 @@ int DiffIterate::diff_object_map(uint64_t from_snap_id, uint64_t to_snap_id,
     }
 
     uint64_t flags;
-    r = m_image_ctx.get_flags(from_snap_id, &flags);
+    int r = m_image_ctx.get_flags(from_snap_id, &flags);
     if (r < 0) {
       lderr(cct) << "diff_object_map: failed to retrieve image flags" << dendl;
       return r;
diff --git a/src/librbd/ExclusiveLock.cc b/src/librbd/ExclusiveLock.cc
index 1d0d189..bd945e6 100644
--- a/src/librbd/ExclusiveLock.cc
+++ b/src/librbd/ExclusiveLock.cc
@@ -84,7 +84,7 @@ bool ExclusiveLock<I>::accept_requests() const {
 }
 
 template <typename I>
-void ExclusiveLock<I>::init(Context *on_init) {
+void ExclusiveLock<I>::init(uint64_t features, Context *on_init) {
   assert(m_image_ctx.owner_lock.is_locked());
   ldout(m_image_ctx.cct, 10) << this << " " << __func__ << dendl;
 
@@ -95,6 +95,9 @@ void ExclusiveLock<I>::init(Context *on_init) {
   }
 
   m_image_ctx.aio_work_queue->block_writes(new C_InitComplete(this, on_init));
+  if ((features & RBD_FEATURE_JOURNALING) != 0) {
+    m_image_ctx.aio_work_queue->set_require_lock_on_read();
+  }
 }
 
 template <typename I>
@@ -110,7 +113,7 @@ template <typename I>
 void ExclusiveLock<I>::try_lock(Context *on_tried_lock) {
   {
     Mutex::Locker locker(m_lock);
-    assert(m_image_ctx.owner_lock.is_wlocked());
+    assert(m_image_ctx.owner_lock.is_locked());
     assert(!is_shutdown());
 
     if (m_state != STATE_LOCKED || !m_actions_contexts.empty()) {
@@ -388,6 +391,7 @@ void ExclusiveLock<I>::handle_acquire_lock(int r) {
 
   if (next_state == STATE_LOCKED) {
     m_image_ctx.image_watcher->notify_acquired_lock();
+    m_image_ctx.aio_work_queue->clear_require_lock_on_read();
     m_image_ctx.aio_work_queue->unblock_writes();
   }
 
@@ -430,7 +434,7 @@ void ExclusiveLock<I>::handle_releasing_lock(int r) {
 
 template <typename I>
 void ExclusiveLock<I>::handle_release_lock(int r) {
-  bool pending_writes = false;
+  bool lock_request_needed = false;
   {
     Mutex::Locker locker(m_lock);
     ldout(m_image_ctx.cct, 10) << this << " " << __func__ << ": r=" << r
@@ -441,7 +445,7 @@ void ExclusiveLock<I>::handle_release_lock(int r) {
     if (r >= 0) {
       m_lock.Unlock();
       m_image_ctx.image_watcher->notify_released_lock();
-      pending_writes = !m_image_ctx.aio_work_queue->writes_empty();
+      lock_request_needed = m_image_ctx.aio_work_queue->is_lock_request_needed();
       m_lock.Lock();
 
       m_watch_handle = 0;
@@ -449,8 +453,8 @@ void ExclusiveLock<I>::handle_release_lock(int r) {
     complete_active_action(r < 0 ? STATE_LOCKED : STATE_UNLOCKED, r);
   }
 
-  if (r >= 0 && pending_writes) {
-    // if we have pending writes -- re-request the lock
+  if (r >= 0 && lock_request_needed) {
+    // if we have blocked IO -- re-request the lock
     RWLock::RLocker owner_locker(m_image_ctx.owner_lock);
     request_lock(nullptr);
   }
@@ -461,9 +465,10 @@ void ExclusiveLock<I>::send_shutdown() {
   assert(m_lock.is_locked());
   if (m_state == STATE_UNLOCKED) {
     m_state = STATE_SHUTTING_DOWN;
+    m_image_ctx.aio_work_queue->clear_require_lock_on_read();
     m_image_ctx.aio_work_queue->unblock_writes();
-    m_image_ctx.op_work_queue->queue(util::create_context_callback<
-      ExclusiveLock<I>, &ExclusiveLock<I>::complete_shutdown>(this), 0);
+    m_image_ctx.image_watcher->flush(util::create_context_callback<
+      ExclusiveLock<I>, &ExclusiveLock<I>::complete_shutdown>(this));
     return;
   }
 
@@ -500,6 +505,7 @@ void ExclusiveLock<I>::handle_shutdown(int r) {
     lderr(cct) << "failed to shut down exclusive lock: " << cpp_strerror(r)
                << dendl;
   } else {
+    m_image_ctx.aio_work_queue->clear_require_lock_on_read();
     m_image_ctx.aio_work_queue->unblock_writes();
   }
 
diff --git a/src/librbd/ExclusiveLock.h b/src/librbd/ExclusiveLock.h
index f29ae59..910c67f 100644
--- a/src/librbd/ExclusiveLock.h
+++ b/src/librbd/ExclusiveLock.h
@@ -32,7 +32,7 @@ public:
   bool is_lock_owner() const;
   bool accept_requests() const;
 
-  void init(Context *on_init);
+  void init(uint64_t features, Context *on_init);
   void shut_down(Context *on_shutdown);
 
   void try_lock(Context *on_tried_lock);
diff --git a/src/librbd/ImageCtx.cc b/src/librbd/ImageCtx.cc
index 0961d0e..0f9b5a5 100644
--- a/src/librbd/ImageCtx.cc
+++ b/src/librbd/ImageCtx.cc
@@ -26,6 +26,7 @@
 #include "librbd/operation/ResizeRequest.h"
 #include "librbd/Utils.h"
 
+#include "osdc/Striper.h"
 #include <boost/bind.hpp>
 
 #define dout_subsys ceph_subsys_rbd
@@ -175,10 +176,7 @@ struct C_InvalidateCache : public Context {
     if (snap)
       snap_name = snap;
 
-    asok_hook = new LibrbdAdminSocketHook(this);
-
     memset(&header, 0, sizeof(header));
-    memset(&layout, 0, sizeof(layout));
 
     ThreadPoolSingleton *thread_pool_singleton;
     cct->lookup_or_create_singleton_object<ThreadPoolSingleton>(
@@ -196,6 +194,7 @@ struct C_InvalidateCache : public Context {
     assert(exclusive_lock == NULL);
     assert(object_map == NULL);
     assert(journal == NULL);
+    assert(asok_hook == NULL);
 
     if (perfcounter) {
       perf_stop();
@@ -221,7 +220,6 @@ struct C_InvalidateCache : public Context {
 
     delete op_work_queue;
     delete aio_work_queue;
-    delete asok_hook;
     delete operations;
     delete state;
   }
@@ -234,6 +232,8 @@ struct C_InvalidateCache : public Context {
     }
     apply_metadata_confs();
 
+    asok_hook = new LibrbdAdminSocketHook(this);
+
     string pname = string("librbd-") + id + string("-") +
       data_ctx.get_pool_name() + string("-") + name;
     if (!snap_name.empty()) {
@@ -286,6 +286,14 @@ struct C_InvalidateCache : public Context {
     readahead.set_max_readahead_size(readahead_max_bytes);
   }
 
+  void ImageCtx::shutdown() {
+    delete image_watcher;
+    image_watcher = nullptr;
+
+    delete asok_hook;
+    asok_hook = nullptr;
+  }
+
   void ImageCtx::init_layout()
   {
     if (stripe_unit == 0 || stripe_count == 0) {
@@ -299,11 +307,11 @@ struct C_InvalidateCache : public Context {
     alignments.push_back(stripe_unit); // stripe unit
     readahead.set_alignments(alignments);
 
-    memset(&layout, 0, sizeof(layout));
-    layout.fl_stripe_unit = stripe_unit;
-    layout.fl_stripe_count = stripe_count;
-    layout.fl_object_size = 1ull << order;
-    layout.fl_pg_pool = data_ctx.get_id();  // FIXME: pool id overflow?
+    layout = file_layout_t();
+    layout.stripe_unit = stripe_unit;
+    layout.stripe_count = stripe_count;
+    layout.object_size = 1ull << order;
+    layout.pool_id = data_ctx.get_id();  // FIXME: pool id overflow?
 
     delete[] format_string;
     size_t len = object_prefix.length() + 16;
@@ -316,7 +324,7 @@ struct C_InvalidateCache : public Context {
 
     ldout(cct, 10) << "init_layout stripe_unit " << stripe_unit
 		   << " stripe_count " << stripe_count
-		   << " object_size " << layout.fl_object_size
+		   << " object_size " << layout.object_size
 		   << " prefix " << object_prefix
 		   << " format " << format_string
 		   << dendl;
@@ -534,6 +542,12 @@ struct C_InvalidateCache : public Context {
     return 0;
   }
 
+  uint64_t ImageCtx::get_object_count(snap_t in_snap_id) const {
+    assert(snap_lock.is_locked());
+    uint64_t image_size = get_image_size(in_snap_id);
+    return Striper::get_num_objects(layout, image_size);
+  }
+
   bool ImageCtx::test_features(uint64_t features) const
   {
     RWLock::RLocker l(snap_lock);
@@ -771,17 +785,10 @@ struct C_InvalidateCache : public Context {
     object_cacher->clear_nonexistence(object_set);
   }
 
-  int ImageCtx::register_watch() {
+  void ImageCtx::register_watch(Context *on_finish) {
     assert(image_watcher == NULL);
     image_watcher = new ImageWatcher(*this);
-    return image_watcher->register_watch();
-  }
-
-  void ImageCtx::unregister_watch() {
-    assert(image_watcher != NULL);
-    image_watcher->unregister_watch();
-    delete image_watcher;
-    image_watcher = NULL;
+    image_watcher->register_watch(on_finish);
   }
 
   uint64_t ImageCtx::prune_parent_extents(vector<pair<uint64_t,uint64_t> >& objectx,
@@ -930,13 +937,12 @@ struct C_InvalidateCache : public Context {
         "rbd_journal_pool", false);
 
     string start = METADATA_CONF_PREFIX;
-    int r = 0, j = 0;
     md_config_t local_config_t;
 
     bool retrieve_metadata = !old_format;
     while (retrieve_metadata) {
       map<string, bufferlist> pairs, res;
-      r = cls_client::metadata_list(&md_ctx, header_oid, start, max_conf_items,
+      int r = cls_client::metadata_list(&md_ctx, header_oid, start, max_conf_items,
                                     &pairs);
       if (r == -EOPNOTSUPP || r == -EIO) {
         ldout(cct, 10) << "config metadata not supported by OSD" << dendl;
@@ -955,7 +961,7 @@ struct C_InvalidateCache : public Context {
       for (map<string, bufferlist>::iterator it = res.begin();
            it != res.end(); ++it) {
         string val(it->second.c_str(), it->second.length());
-        j = local_config_t.set_val(it->first.c_str(), val);
+        int j = local_config_t.set_val(it->first.c_str(), val);
         if (j < 0) {
           lderr(cct) << __func__ << " failed to set config " << it->first
                      << " with value " << it->second.c_str() << ": " << j
@@ -1017,4 +1023,27 @@ struct C_InvalidateCache : public Context {
   Journal<ImageCtx> *ImageCtx::create_journal() {
     return new Journal<ImageCtx>(*this);
   }
+
+  void ImageCtx::set_image_name(const std::string &image_name) {
+    // update the name so rename can be invoked repeatedly
+    RWLock::RLocker owner_locker(owner_lock);
+    RWLock::WLocker snap_locker(snap_lock);
+    name = image_name;
+    if (old_format) {
+      header_oid = util::old_header_name(image_name);
+    }
+  }
+
+  void ImageCtx::notify_update() {
+    state->handle_update_notification();
+
+    C_SaferCond ctx;
+    image_watcher->notify_header_update(&ctx);
+    ctx.wait();
+  }
+
+  void ImageCtx::notify_update(Context *on_finish) {
+    state->handle_update_notification();
+    image_watcher->notify_header_update(on_finish);
+  }
 }
diff --git a/src/librbd/ImageCtx.h b/src/librbd/ImageCtx.h
index 689e941..a302a14 100644
--- a/src/librbd/ImageCtx.h
+++ b/src/librbd/ImageCtx.h
@@ -122,7 +122,7 @@ namespace librbd {
     uint64_t stripe_unit, stripe_count;
     uint64_t flags;
 
-    ceph_file_layout layout;
+    file_layout_t layout;
 
     ObjectCacher *object_cacher;
     LibrbdWriteback *writeback_handler;
@@ -197,6 +197,7 @@ namespace librbd {
 	     const char *snap, IoCtx& p, bool read_only);
     ~ImageCtx();
     void init();
+    void shutdown();
     void init_layout();
     void perf_start(std::string name);
     void perf_stop();
@@ -227,6 +228,7 @@ namespace librbd {
                   uint8_t protection_status, uint64_t flags);
     void rm_snap(std::string in_snap_name, librados::snap_t id);
     uint64_t get_image_size(librados::snap_t in_snap_id) const;
+    uint64_t get_object_count(librados::snap_t in_snap_id) const;
     bool test_features(uint64_t test_features) const;
     bool test_features(uint64_t test_features,
                        const RWLock &in_snap_lock) const;
@@ -254,8 +256,7 @@ namespace librbd {
     int invalidate_cache(bool purge_on_error=false);
     void invalidate_cache(Context *on_finish);
     void clear_nonexistence_cache();
-    int register_watch();
-    void unregister_watch();
+    void register_watch(Context *on_finish);
     uint64_t prune_parent_extents(vector<pair<uint64_t,uint64_t> >& objectx,
 				  uint64_t overlap);
 
@@ -275,6 +276,11 @@ namespace librbd {
     Journal<ImageCtx> *create_journal();
 
     void clear_pending_completions();
+
+    void set_image_name(const std::string &name);
+
+    void notify_update();
+    void notify_update(Context *on_finish);
   };
 }
 
diff --git a/src/librbd/ImageState.cc b/src/librbd/ImageState.cc
index 1bf628e..329ad3a 100644
--- a/src/librbd/ImageState.cc
+++ b/src/librbd/ImageState.cc
@@ -5,6 +5,7 @@
 #include "common/dout.h"
 #include "common/errno.h"
 #include "common/Cond.h"
+#include "common/WorkQueue.h"
 #include "librbd/ImageCtx.h"
 #include "librbd/Utils.h"
 #include "librbd/image/CloseRequest.h"
@@ -18,6 +19,7 @@
 
 namespace librbd {
 
+using util::create_async_context_callback;
 using util::create_context_callback;
 
 template <typename I>
@@ -44,12 +46,13 @@ void ImageState<I>::open(Context *on_finish) {
   CephContext *cct = m_image_ctx->cct;
   ldout(cct, 20) << __func__ << dendl;
 
-  Mutex::Locker locker(m_lock);
+  m_lock.Lock();
   assert(m_state == STATE_UNINITIALIZED);
 
   Action action(ACTION_TYPE_OPEN);
   action.refresh_seq = m_refresh_seq;
-  execute_action(action, on_finish);
+
+  execute_action_unlock(action, on_finish);
 }
 
 template <typename I>
@@ -67,12 +70,12 @@ void ImageState<I>::close(Context *on_finish) {
   CephContext *cct = m_image_ctx->cct;
   ldout(cct, 20) << __func__ << dendl;
 
-  Mutex::Locker locker(m_lock);
+  m_lock.Lock();
   assert(!is_closed());
 
   Action action(ACTION_TYPE_CLOSE);
   action.refresh_seq = m_refresh_seq;
-  execute_action(action, on_finish);
+  execute_action_unlock(action, on_finish);
 }
 
 template <typename I>
@@ -112,30 +115,22 @@ void ImageState<I>::refresh(Context *on_finish) {
 
   Action action(ACTION_TYPE_REFRESH);
   action.refresh_seq = m_refresh_seq;
-  execute_action(action, on_finish);
-  m_lock.Unlock();
+  execute_action_unlock(action, on_finish);
 }
 
 template <typename I>
 int ImageState<I>::refresh_if_required() {
-  RWLock::RLocker owner_locker(m_image_ctx->owner_lock);
-  return refresh_if_required(m_image_ctx->owner_lock);
-}
-
-template <typename I>
-int ImageState<I>::refresh_if_required(const RWLock &) {
-  assert(m_image_ctx->owner_lock.is_locked());
-
   C_SaferCond ctx;
   {
-    Mutex::Locker locker(m_lock);
+    m_lock.Lock();
     if (m_last_refresh == m_refresh_seq || is_closed()) {
+      m_lock.Unlock();
       return 0;
     }
 
     Action action(ACTION_TYPE_REFRESH);
     action.refresh_seq = m_refresh_seq;
-    execute_action(action, &ctx);
+    execute_action_unlock(action, &ctx);
   }
 
   return ctx.wait();
@@ -146,10 +141,11 @@ void ImageState<I>::snap_set(const std::string &snap_name, Context *on_finish) {
   CephContext *cct = m_image_ctx->cct;
   ldout(cct, 20) << __func__ << ": snap_name=" << snap_name << dendl;
 
-  Mutex::Locker locker(m_lock);
   Action action(ACTION_TYPE_SET_SNAP);
   action.snap_name = snap_name;
-  execute_action(action, on_finish);
+
+  m_lock.Lock();
+  execute_action_unlock(action, on_finish);
 }
 
 template <typename I>
@@ -200,72 +196,80 @@ void ImageState<I>::append_context(const Action &action, Context *context) {
 }
 
 template <typename I>
-void ImageState<I>::execute_next_action() {
+void ImageState<I>::execute_next_action_unlock() {
   assert(m_lock.is_locked());
   assert(!m_actions_contexts.empty());
   switch (m_actions_contexts.front().first.action_type) {
   case ACTION_TYPE_OPEN:
-    send_open();
+    send_open_unlock();
     return;
   case ACTION_TYPE_CLOSE:
-    send_close();
+    send_close_unlock();
     return;
   case ACTION_TYPE_REFRESH:
-    send_refresh();
+    send_refresh_unlock();
     return;
   case ACTION_TYPE_SET_SNAP:
-    send_set_snap();
+    send_set_snap_unlock();
     return;
   }
   assert(false);
 }
 
 template <typename I>
-void ImageState<I>::execute_action(const Action &action, Context *on_finish) {
+void ImageState<I>::execute_action_unlock(const Action &action,
+                                          Context *on_finish) {
   assert(m_lock.is_locked());
 
   append_context(action, on_finish);
   if (!is_transition_state()) {
-    execute_next_action();
+    execute_next_action_unlock();
+  } else {
+    m_lock.Unlock();
   }
 }
 
 template <typename I>
-void ImageState<I>::complete_action(State next_state, int r) {
+void ImageState<I>::complete_action_unlock(State next_state, int r) {
   assert(m_lock.is_locked());
   assert(!m_actions_contexts.empty());
 
   ActionContexts action_contexts(std::move(m_actions_contexts.front()));
   m_actions_contexts.pop_front();
-  m_state = next_state;
 
+  m_state = next_state;
   m_lock.Unlock();
+
   for (auto ctx : action_contexts.second) {
     ctx->complete(r);
   }
-  m_lock.Lock();
 
-  if (!is_transition_state() && !m_actions_contexts.empty()) {
-    execute_next_action();
+  if (next_state != STATE_CLOSED) {
+    m_lock.Lock();
+    if (!is_transition_state() && !m_actions_contexts.empty()) {
+      execute_next_action_unlock();
+    } else {
+      m_lock.Unlock();
+    }
   }
 }
 
 template <typename I>
-void ImageState<I>::send_open() {
+void ImageState<I>::send_open_unlock() {
   assert(m_lock.is_locked());
   CephContext *cct = m_image_ctx->cct;
   ldout(cct, 10) << this << " " << __func__ << dendl;
 
   m_state = STATE_OPENING;
 
-  Context *ctx = create_context_callback<
-    ImageState<I>, &ImageState<I>::handle_open>(this);
+  Context *ctx = create_async_context_callback(
+    *m_image_ctx, create_context_callback<
+      ImageState<I>, &ImageState<I>::handle_open>(this));
   image::OpenRequest<I> *req = image::OpenRequest<I>::create(
     m_image_ctx, ctx);
 
   m_lock.Unlock();
   req->send();
-  m_lock.Lock();
 }
 
 template <typename I>
@@ -277,12 +281,12 @@ void ImageState<I>::handle_open(int r) {
     lderr(cct) << "failed to open image: " << cpp_strerror(r) << dendl;
   }
 
-  Mutex::Locker locker(m_lock);
-  complete_action(r < 0 ? STATE_UNINITIALIZED : STATE_OPEN, r);
+  m_lock.Lock();
+  complete_action_unlock(r < 0 ? STATE_UNINITIALIZED : STATE_OPEN, r);
 }
 
 template <typename I>
-void ImageState<I>::send_close() {
+void ImageState<I>::send_close_unlock() {
   assert(m_lock.is_locked());
   CephContext *cct = m_image_ctx->cct;
   ldout(cct, 10) << this << " " << __func__ << dendl;
@@ -296,7 +300,6 @@ void ImageState<I>::send_close() {
 
   m_lock.Unlock();
   req->send();
-  m_lock.Lock();
 }
 
 template <typename I>
@@ -309,26 +312,26 @@ void ImageState<I>::handle_close(int r) {
                << dendl;
   }
 
-  Mutex::Locker locker(m_lock);
-  complete_action(STATE_CLOSED, r);
+  m_lock.Lock();
+  complete_action_unlock(STATE_CLOSED, r);
 }
 
 template <typename I>
-void ImageState<I>::send_refresh() {
+void ImageState<I>::send_refresh_unlock() {
   assert(m_lock.is_locked());
   CephContext *cct = m_image_ctx->cct;
   ldout(cct, 10) << this << " " << __func__ << dendl;
 
   m_state = STATE_REFRESHING;
 
-  Context *ctx = create_context_callback<
-    ImageState<I>, &ImageState<I>::handle_refresh>(this);
+  Context *ctx = create_async_context_callback(
+    *m_image_ctx, create_context_callback<
+      ImageState<I>, &ImageState<I>::handle_refresh>(this));
   image::RefreshRequest<I> *req = image::RefreshRequest<I>::create(
     *m_image_ctx, ctx);
 
   m_lock.Unlock();
   req->send();
-  m_lock.Lock();
 }
 
 template <typename I>
@@ -336,7 +339,7 @@ void ImageState<I>::handle_refresh(int r) {
   CephContext *cct = m_image_ctx->cct;
   ldout(cct, 10) << this << " " << __func__ << ": r=" << r << dendl;
 
-  Mutex::Locker locker(m_lock);
+  m_lock.Lock();
   assert(!m_actions_contexts.empty());
 
   ActionContexts &action_contexts(m_actions_contexts.front());
@@ -344,11 +347,11 @@ void ImageState<I>::handle_refresh(int r) {
   assert(m_last_refresh <= action_contexts.first.refresh_seq);
   m_last_refresh = action_contexts.first.refresh_seq;
 
-  complete_action(STATE_OPEN, r);
+  complete_action_unlock(STATE_OPEN, r);
 }
 
 template <typename I>
-void ImageState<I>::send_set_snap() {
+void ImageState<I>::send_set_snap_unlock() {
   assert(m_lock.is_locked());
 
   m_state = STATE_SETTING_SNAP;
@@ -361,14 +364,14 @@ void ImageState<I>::send_set_snap() {
   ldout(cct, 10) << this << " " << __func__ << ": "
                  << "snap_name=" << action_contexts.first.snap_name << dendl;
 
-  Context *ctx = create_context_callback<
-    ImageState<I>, &ImageState<I>::handle_set_snap>(this);
+  Context *ctx = create_async_context_callback(
+    *m_image_ctx, create_context_callback<
+      ImageState<I>, &ImageState<I>::handle_set_snap>(this));
   image::SetSnapRequest<I> *req = image::SetSnapRequest<I>::create(
     *m_image_ctx, action_contexts.first.snap_name, ctx);
 
   m_lock.Unlock();
   req->send();
-  m_lock.Lock();
 }
 
 template <typename I>
@@ -380,8 +383,8 @@ void ImageState<I>::handle_set_snap(int r) {
     lderr(cct) << "failed to set snapshot: " << cpp_strerror(r) << dendl;
   }
 
-  Mutex::Locker locker(m_lock);
-  complete_action(STATE_OPEN, r);
+  m_lock.Lock();
+  complete_action_unlock(STATE_OPEN, r);
 }
 
 } // namespace librbd
diff --git a/src/librbd/ImageState.h b/src/librbd/ImageState.h
index f6a170b..2834116 100644
--- a/src/librbd/ImageState.h
+++ b/src/librbd/ImageState.h
@@ -36,7 +36,6 @@ public:
   int refresh();
   void refresh(Context *on_finish);
   int refresh_if_required();
-  int refresh_if_required(const RWLock &owner_lock);
 
   void snap_set(const std::string &snap_name, Context *on_finish);
 
@@ -97,20 +96,20 @@ private:
   bool is_closed() const;
 
   void append_context(const Action &action, Context *context);
-  void execute_next_action();
-  void execute_action(const Action &action, Context *context);
-  void complete_action(State next_state, int r);
+  void execute_next_action_unlock();
+  void execute_action_unlock(const Action &action, Context *context);
+  void complete_action_unlock(State next_state, int r);
 
-  void send_open();
+  void send_open_unlock();
   void handle_open(int r);
 
-  void send_close();
+  void send_close_unlock();
   void handle_close(int r);
 
-  void send_refresh();
+  void send_refresh_unlock();
   void handle_refresh(int r);
 
-  void send_set_snap();
+  void send_set_snap_unlock();
   void handle_set_snap(int r);
 
 };
diff --git a/src/librbd/ImageWatcher.cc b/src/librbd/ImageWatcher.cc
index 2c5331c..0734490 100644
--- a/src/librbd/ImageWatcher.cc
+++ b/src/librbd/ImageWatcher.cc
@@ -1,5 +1,6 @@
 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
 // vim: ts=8 sw=2 smarttab
+
 #include "librbd/ImageWatcher.h"
 #include "librbd/AioCompletion.h"
 #include "librbd/ExclusiveLock.h"
@@ -10,9 +11,12 @@
 #include "librbd/Operations.h"
 #include "librbd/TaskFinisher.h"
 #include "librbd/Utils.h"
+#include "librbd/image_watcher/Notifier.h"
+#include "librbd/image_watcher/NotifyLockOwner.h"
 #include "include/encoding.h"
 #include "include/stringify.h"
 #include "common/errno.h"
+#include "common/WorkQueue.h"
 #include <sstream>
 #include <boost/bind.hpp>
 #include <boost/function.hpp>
@@ -24,9 +28,47 @@
 
 namespace librbd {
 
+using namespace image_watcher;
 using namespace watch_notify;
+using util::create_context_callback;
+using util::create_rados_safe_callback;
+
+namespace {
+
+struct C_UnwatchAndFlush : public Context {
+  librados::Rados rados;
+  Context *on_finish;
+  bool flushing = false;
+  int ret_val = 0;
+
+  C_UnwatchAndFlush(librados::IoCtx &io_ctx, Context *on_finish)
+    : rados(io_ctx), on_finish(on_finish) {
+  }
+
+  virtual void complete(int r) override {
+    if (ret_val == 0 && r < 0) {
+      ret_val = r;
+    }
+
+    if (!flushing) {
+      flushing = true;
+
+      librados::AioCompletion *aio_comp = create_rados_safe_callback(this);
+      r = rados.aio_watch_flush(aio_comp);
+      assert(r == 0);
+      aio_comp->release();
+    } else {
+      Context::complete(ret_val);
+    }
+  }
+
+  virtual void finish(int r) override {
+    on_finish->complete(r);
+  }
+};
+
+} // anonymous namespace
 
-static const uint64_t	NOTIFY_TIMEOUT = 5000;
 static const double	RETRY_DELAY_SECONDS = 1.0;
 
 ImageWatcher::ImageWatcher(ImageCtx &image_ctx)
@@ -34,56 +76,72 @@ ImageWatcher::ImageWatcher(ImageCtx &image_ctx)
     m_watch_lock(util::unique_lock_name("librbd::ImageWatcher::m_watch_lock", this)),
     m_watch_ctx(*this), m_watch_handle(0),
     m_watch_state(WATCH_STATE_UNREGISTERED),
+    m_task_finisher(new TaskFinisher<Task>(*m_image_ctx.cct)),
     m_async_request_lock(util::unique_lock_name("librbd::ImageWatcher::m_async_request_lock", this)),
-    m_owner_client_id_lock(util::unique_lock_name("librbd::ImageWatcher::m_owner_client_id_lock", this))
+    m_owner_client_id_lock(util::unique_lock_name("librbd::ImageWatcher::m_owner_client_id_lock", this)),
+    m_notifier(image_ctx)
 {
-  m_image_ctx.cct->lookup_or_create_singleton_object<TaskFinisher<Task> >(
-    m_task_finisher, "librbd::task_finisher");
 }
 
 ImageWatcher::~ImageWatcher()
 {
-  m_task_finisher = nullptr;
+  delete m_task_finisher;
   {
     RWLock::RLocker l(m_watch_lock);
     assert(m_watch_state != WATCH_STATE_REGISTERED);
   }
 }
 
-int ImageWatcher::register_watch() {
+void ImageWatcher::register_watch(Context *on_finish) {
   ldout(m_image_ctx.cct, 10) << this << " registering image watcher" << dendl;
 
-  RWLock::WLocker l(m_watch_lock);
+  RWLock::RLocker watch_locker(m_watch_lock);
+  assert(m_watch_state == WATCH_STATE_UNREGISTERED);
+  librados::AioCompletion *aio_comp = create_rados_safe_callback(
+    new C_RegisterWatch(this, on_finish));
+  int r = m_image_ctx.md_ctx.aio_watch(m_image_ctx.header_oid, aio_comp,
+                                       &m_watch_handle, &m_watch_ctx);
+  assert(r == 0);
+  aio_comp->release();
+}
+
+void ImageWatcher::handle_register_watch(int r) {
+  RWLock::WLocker watch_locker(m_watch_lock);
   assert(m_watch_state == WATCH_STATE_UNREGISTERED);
-  int r = m_image_ctx.md_ctx.watch2(m_image_ctx.header_oid,
-				    &m_watch_handle,
-				    &m_watch_ctx);
   if (r < 0) {
-    return r;
+    m_watch_handle = 0;
+  } else if (r >= 0) {
+    m_watch_state = WATCH_STATE_REGISTERED;
   }
-
-  m_watch_state = WATCH_STATE_REGISTERED;
-  return 0;
 }
 
-int ImageWatcher::unregister_watch() {
+void ImageWatcher::unregister_watch(Context *on_finish) {
   ldout(m_image_ctx.cct, 10) << this << " unregistering image watcher" << dendl;
 
   cancel_async_requests();
   m_task_finisher->cancel_all();
 
-  int r = 0;
   {
     RWLock::WLocker l(m_watch_lock);
     if (m_watch_state == WATCH_STATE_REGISTERED) {
-      r = m_image_ctx.md_ctx.unwatch2(m_watch_handle);
+      m_watch_state = WATCH_STATE_UNREGISTERED;
+
+      librados::AioCompletion *aio_comp = create_rados_safe_callback(
+        new C_UnwatchAndFlush(m_image_ctx.md_ctx, on_finish));
+      int r = m_image_ctx.md_ctx.aio_unwatch(m_watch_handle, aio_comp);
+      assert(r == 0);
+      aio_comp->release();
+      return;
+    } else if (m_watch_state == WATCH_STATE_ERROR) {
+      m_watch_state = WATCH_STATE_UNREGISTERED;
     }
-    m_watch_state = WATCH_STATE_UNREGISTERED;
   }
 
-  librados::Rados rados(m_image_ctx.md_ctx);
-  rados.watch_flush();
-  return r;
+  on_finish->complete(0);
+}
+
+void ImageWatcher::flush(Context *on_finish) {
+  m_notifier.flush(on_finish);
 }
 
 void ImageWatcher::schedule_async_progress(const AsyncRequestId &request,
@@ -102,8 +160,7 @@ int ImageWatcher::notify_async_progress(const AsyncRequestId &request,
 
   bufferlist bl;
   ::encode(NotifyMessage(AsyncProgressPayload(request, offset, total)), bl);
-
-  m_image_ctx.md_ctx.notify2(m_image_ctx.header_oid, bl, NOTIFY_TIMEOUT, NULL);
+  m_notifier.notify(bl, nullptr, nullptr);
   return 0;
 }
 
@@ -114,34 +171,36 @@ void ImageWatcher::schedule_async_complete(const AsyncRequestId &request,
   m_task_finisher->queue(ctx);
 }
 
-int ImageWatcher::notify_async_complete(const AsyncRequestId &request,
-					int r) {
+void ImageWatcher::notify_async_complete(const AsyncRequestId &request, int r) {
   ldout(m_image_ctx.cct, 20) << this << " remote async request finished: "
 			     << request << " = " << r << dendl;
 
   bufferlist bl;
   ::encode(NotifyMessage(AsyncCompletePayload(request, r)), bl);
+  m_notifier.notify(bl, nullptr, new FunctionContext(
+    boost::bind(&ImageWatcher::handle_async_complete, this, request, r, _1)));
+}
 
-  if (r >= 0) {
-    librbd::notify_change(m_image_ctx.md_ctx, m_image_ctx.header_oid,
-			  &m_image_ctx);
-  }
-  int ret = m_image_ctx.md_ctx.notify2(m_image_ctx.header_oid, bl,
-				       NOTIFY_TIMEOUT, NULL);
-  if (ret < 0) {
+void ImageWatcher::handle_async_complete(const AsyncRequestId &request, int r,
+                                         int ret_val) {
+  ldout(m_image_ctx.cct, 20) << this << " " << __func__ << ": "
+                             << "request=" << request << ", r=" << ret_val
+                             << dendl;
+  if (ret_val < 0) {
     lderr(m_image_ctx.cct) << this << " failed to notify async complete: "
-			   << cpp_strerror(ret) << dendl;
-    if (ret == -ETIMEDOUT) {
+			   << cpp_strerror(ret_val) << dendl;
+    if (ret_val == -ETIMEDOUT) {
       schedule_async_complete(request, r);
     }
   } else {
-    RWLock::WLocker l(m_async_request_lock);
+    RWLock::WLocker async_request_locker(m_async_request_lock);
     m_async_pending.erase(request);
   }
-  return 0;
 }
 
-int ImageWatcher::notify_flatten(uint64_t request_id, ProgressContext &prog_ctx) {
+void ImageWatcher::notify_flatten(uint64_t request_id,
+                                  ProgressContext &prog_ctx,
+                                  Context *on_finish) {
   assert(m_image_ctx.owner_lock.is_locked());
   assert(m_image_ctx.exclusive_lock &&
          !m_image_ctx.exclusive_lock->is_lock_owner());
@@ -150,12 +209,12 @@ int ImageWatcher::notify_flatten(uint64_t request_id, ProgressContext &prog_ctx)
 
   bufferlist bl;
   ::encode(NotifyMessage(FlattenPayload(async_request_id)), bl);
-
-  return notify_async_request(async_request_id, bl, prog_ctx);
+  notify_async_request(async_request_id, std::move(bl), prog_ctx, on_finish);
 }
 
-int ImageWatcher::notify_resize(uint64_t request_id, uint64_t size,
-				ProgressContext &prog_ctx) {
+void ImageWatcher::notify_resize(uint64_t request_id, uint64_t size,
+				 ProgressContext &prog_ctx,
+                                 Context *on_finish) {
   assert(m_image_ctx.owner_lock.is_locked());
   assert(m_image_ctx.exclusive_lock &&
          !m_image_ctx.exclusive_lock->is_lock_owner());
@@ -164,65 +223,68 @@ int ImageWatcher::notify_resize(uint64_t request_id, uint64_t size,
 
   bufferlist bl;
   ::encode(NotifyMessage(ResizePayload(size, async_request_id)), bl);
-
-  return notify_async_request(async_request_id, bl, prog_ctx);
+  notify_async_request(async_request_id, std::move(bl), prog_ctx, on_finish);
 }
 
-int ImageWatcher::notify_snap_create(const std::string &snap_name) {
+void ImageWatcher::notify_snap_create(const std::string &snap_name,
+                                      Context *on_finish) {
   assert(m_image_ctx.owner_lock.is_locked());
   assert(m_image_ctx.exclusive_lock &&
          !m_image_ctx.exclusive_lock->is_lock_owner());
 
   bufferlist bl;
   ::encode(NotifyMessage(SnapCreatePayload(snap_name)), bl);
-
-  return notify_lock_owner(bl);
+  notify_lock_owner(std::move(bl), on_finish);
 }
 
-int ImageWatcher::notify_snap_rename(const snapid_t &src_snap_id,
-				     const std::string &dst_snap_name) {
+void ImageWatcher::notify_snap_rename(const snapid_t &src_snap_id,
+				      const std::string &dst_snap_name,
+                                      Context *on_finish) {
   assert(m_image_ctx.owner_lock.is_locked());
   assert(m_image_ctx.exclusive_lock &&
          !m_image_ctx.exclusive_lock->is_lock_owner());
 
   bufferlist bl;
   ::encode(NotifyMessage(SnapRenamePayload(src_snap_id, dst_snap_name)), bl);
-
-  return notify_lock_owner(bl);
+  notify_lock_owner(std::move(bl), on_finish);
 }
-int ImageWatcher::notify_snap_remove(const std::string &snap_name) {
+
+void ImageWatcher::notify_snap_remove(const std::string &snap_name,
+                                      Context *on_finish) {
   assert(m_image_ctx.owner_lock.is_locked());
   assert(m_image_ctx.exclusive_lock &&
          !m_image_ctx.exclusive_lock->is_lock_owner());
 
   bufferlist bl;
   ::encode(NotifyMessage(SnapRemovePayload(snap_name)), bl);
-
-  return notify_lock_owner(bl);
+  notify_lock_owner(std::move(bl), on_finish);
 }
 
-int ImageWatcher::notify_snap_protect(const std::string &snap_name) {
+void ImageWatcher::notify_snap_protect(const std::string &snap_name,
+                                       Context *on_finish) {
   assert(m_image_ctx.owner_lock.is_locked());
   assert(m_image_ctx.exclusive_lock &&
          !m_image_ctx.exclusive_lock->is_lock_owner());
 
   bufferlist bl;
   ::encode(NotifyMessage(SnapProtectPayload(snap_name)), bl);
-  return notify_lock_owner(bl);
+  notify_lock_owner(std::move(bl), on_finish);
 }
 
-int ImageWatcher::notify_snap_unprotect(const std::string &snap_name) {
+void ImageWatcher::notify_snap_unprotect(const std::string &snap_name,
+                                         Context *on_finish) {
   assert(m_image_ctx.owner_lock.is_locked());
   assert(m_image_ctx.exclusive_lock &&
          !m_image_ctx.exclusive_lock->is_lock_owner());
 
   bufferlist bl;
   ::encode(NotifyMessage(SnapUnprotectPayload(snap_name)), bl);
-  return notify_lock_owner(bl);
+  notify_lock_owner(std::move(bl), on_finish);
 }
 
-int ImageWatcher::notify_rebuild_object_map(uint64_t request_id,
-                                            ProgressContext &prog_ctx) {
+void ImageWatcher::notify_rebuild_object_map(uint64_t request_id,
+                                             ProgressContext &prog_ctx,
+                                             Context *on_finish) {
   assert(m_image_ctx.owner_lock.is_locked());
   assert(m_image_ctx.exclusive_lock &&
          !m_image_ctx.exclusive_lock->is_lock_owner());
@@ -231,28 +293,27 @@ int ImageWatcher::notify_rebuild_object_map(uint64_t request_id,
 
   bufferlist bl;
   ::encode(NotifyMessage(RebuildObjectMapPayload(async_request_id)), bl);
-
-  return notify_async_request(async_request_id, bl, prog_ctx);
+  notify_async_request(async_request_id, std::move(bl), prog_ctx, on_finish);
 }
 
-int ImageWatcher::notify_rename(const std::string &image_name) {
+void ImageWatcher::notify_rename(const std::string &image_name,
+                                 Context *on_finish) {
   assert(m_image_ctx.owner_lock.is_locked());
   assert(m_image_ctx.exclusive_lock &&
          !m_image_ctx.exclusive_lock->is_lock_owner());
 
   bufferlist bl;
   ::encode(NotifyMessage(RenamePayload(image_name)), bl);
-  return notify_lock_owner(bl);
+  notify_lock_owner(std::move(bl), on_finish);
 }
 
-void ImageWatcher::notify_header_update(librados::IoCtx &io_ctx,
-				        const std::string &oid)
-{
+void ImageWatcher::notify_header_update(Context *on_finish) {
+  ldout(m_image_ctx.cct, 10) << this << ": " << __func__ << dendl;
+
   // supports legacy (empty buffer) clients
   bufferlist bl;
   ::encode(NotifyMessage(HeaderUpdatePayload()), bl);
-
-  io_ctx.notify2(oid, bl, NOTIFY_TIMEOUT, NULL);
+  m_notifier.notify(bl, nullptr, on_finish);
 }
 
 void ImageWatcher::schedule_cancel_async_requests() {
@@ -294,7 +355,7 @@ void ImageWatcher::notify_acquired_lock() {
 
   bufferlist bl;
   ::encode(NotifyMessage(AcquiredLockPayload(client_id)), bl);
-  m_image_ctx.md_ctx.notify2(m_image_ctx.header_oid, bl, NOTIFY_TIMEOUT, NULL);
+  m_notifier.notify(bl, nullptr, nullptr);
 }
 
 void ImageWatcher::notify_released_lock() {
@@ -307,7 +368,7 @@ void ImageWatcher::notify_released_lock() {
 
   bufferlist bl;
   ::encode(NotifyMessage(ReleasedLockPayload(get_client_id())), bl);
-  m_image_ctx.md_ctx.notify2(m_image_ctx.header_oid, bl, NOTIFY_TIMEOUT, NULL);
+  m_notifier.notify(bl, nullptr, nullptr);
 }
 
 void ImageWatcher::schedule_request_lock(bool use_timer, int timer_delay) {
@@ -340,12 +401,24 @@ void ImageWatcher::schedule_request_lock(bool use_timer, int timer_delay) {
 
 void ImageWatcher::notify_request_lock() {
   RWLock::RLocker owner_locker(m_image_ctx.owner_lock);
+  RWLock::RLocker snap_locker(m_image_ctx.snap_lock);
+  assert(!m_image_ctx.exclusive_lock->is_lock_owner());
+
   ldout(m_image_ctx.cct, 10) << this << " notify request lock" << dendl;
 
   bufferlist bl;
   ::encode(NotifyMessage(RequestLockPayload(get_client_id())), bl);
+  notify_lock_owner(std::move(bl), create_context_callback<
+    ImageWatcher, &ImageWatcher::handle_request_lock>(this));
+}
+
+void ImageWatcher::handle_request_lock(int r) {
+  RWLock::RLocker owner_locker(m_image_ctx.owner_lock);
+  RWLock::RLocker snap_locker(m_image_ctx.snap_lock);
+
+  // ExclusiveLock state machine cannot transition
+  assert(!m_image_ctx.exclusive_lock->is_lock_owner());
 
-  int r = notify_lock_owner(bl);
   if (r == -ETIMEDOUT) {
     ldout(m_image_ctx.cct, 5) << this << " timed out requesting lock: retrying"
                               << dendl;
@@ -365,65 +438,23 @@ void ImageWatcher::notify_request_lock() {
   }
 }
 
-int ImageWatcher::notify_lock_owner(bufferlist &bl) {
+void ImageWatcher::notify_lock_owner(bufferlist &&bl, Context *on_finish) {
+  assert(on_finish != nullptr);
   assert(m_image_ctx.owner_lock.is_locked());
+  NotifyLockOwner *notify_lock_owner = NotifyLockOwner::create(
+    m_image_ctx, m_notifier, std::move(bl), on_finish);
+  notify_lock_owner->send();
+}
 
-  // since we need to ack our own notifications, release the owner lock just in
-  // case another notification occurs before this one and it requires the lock
-  bufferlist response_bl;
-  m_image_ctx.owner_lock.put_read();
-  int r = m_image_ctx.md_ctx.notify2(m_image_ctx.header_oid, bl, NOTIFY_TIMEOUT,
-				     &response_bl);
-  m_image_ctx.owner_lock.get_read();
-
-  if (r < 0 && r != -ETIMEDOUT) {
-    lderr(m_image_ctx.cct) << this << " lock owner notification failed: "
-			   << cpp_strerror(r) << dendl;
-    return r;
-  }
-
-  typedef std::map<std::pair<uint64_t, uint64_t>, bufferlist> responses_t;
-  responses_t responses;
-  if (response_bl.length() > 0) {
-    try {
-      bufferlist::iterator iter = response_bl.begin();
-      ::decode(responses, iter);
-    } catch (const buffer::error &err) {
-      lderr(m_image_ctx.cct) << this << " failed to decode response" << dendl;
-      return -EINVAL;
-    }
-  }
-
-  bufferlist response;
-  bool lock_owner_responded = false;
-  for (responses_t::iterator i = responses.begin(); i != responses.end(); ++i) {
-    if (i->second.length() > 0) {
-      if (lock_owner_responded) {
-	lderr(m_image_ctx.cct) << this << " duplicate lock owners detected"
-                               << dendl;
-	return -EIO;
-      }
-      lock_owner_responded = true;
-      response.claim(i->second);
-    }
-  }
-
-  if (!lock_owner_responded) {
-    lderr(m_image_ctx.cct) << this << " no lock owners detected" << dendl;
-    return -ETIMEDOUT;
-  }
-
-  try {
-    bufferlist::iterator iter = response.begin();
-
-    ResponseMessage response_message;
-    ::decode(response_message, iter);
-
-    r = response_message.result;
-  } catch (const buffer::error &err) {
-    r = -EINVAL;
+Context *ImageWatcher::remove_async_request(const AsyncRequestId &id) {
+  RWLock::WLocker async_request_locker(m_async_request_lock);
+  auto it = m_async_requests.find(id);
+  if (it != m_async_requests.end()) {
+    Context *on_complete = it->second.first;
+    m_async_requests.erase(it);
+    return on_complete;
   }
-  return r;
+  return nullptr;
 }
 
 void ImageWatcher::schedule_async_request_timed_out(const AsyncRequestId &id) {
@@ -437,44 +468,45 @@ void ImageWatcher::schedule_async_request_timed_out(const AsyncRequestId &id) {
 }
 
 void ImageWatcher::async_request_timed_out(const AsyncRequestId &id) {
-  RWLock::RLocker l(m_async_request_lock);
-  std::map<AsyncRequestId, AsyncRequest>::iterator it =
-    m_async_requests.find(id);
-  if (it != m_async_requests.end()) {
-    ldout(m_image_ctx.cct, 10) << this << " request timed-out: " << id << dendl;
-    it->second.first->complete(-ERESTART);
+  Context *on_complete = remove_async_request(id);
+  if (on_complete != nullptr) {
+    ldout(m_image_ctx.cct, 5) << "async request timed out: " << id << dendl;
+    m_image_ctx.op_work_queue->queue(on_complete, -ETIMEDOUT);
   }
 }
 
-int ImageWatcher::notify_async_request(const AsyncRequestId &async_request_id,
-				       bufferlist &in,
-				       ProgressContext& prog_ctx) {
+void ImageWatcher::notify_async_request(const AsyncRequestId &async_request_id,
+				        bufferlist &&in,
+				        ProgressContext& prog_ctx,
+                                        Context *on_finish) {
+  assert(on_finish != nullptr);
   assert(m_image_ctx.owner_lock.is_locked());
 
   ldout(m_image_ctx.cct, 10) << this << " async request: " << async_request_id
                              << dendl;
 
-  C_SaferCond ctx;
+  Context *on_notify = new FunctionContext([this, async_request_id](int r) {
+    if (r < 0) {
+      // notification failed -- don't expect updates
+      Context *on_complete = remove_async_request(async_request_id);
+      if (on_complete != nullptr) {
+        on_complete->complete(r);
+      }
+    }
+  });
+  Context *on_complete = new FunctionContext(
+    [this, async_request_id, on_finish](int r) {
+      m_task_finisher->cancel(Task(TASK_CODE_ASYNC_REQUEST, async_request_id));
+      on_finish->complete(r);
+    });
 
   {
-    RWLock::WLocker l(m_async_request_lock);
-    m_async_requests[async_request_id] = AsyncRequest(&ctx, &prog_ctx);
+    RWLock::WLocker async_request_locker(m_async_request_lock);
+    m_async_requests[async_request_id] = AsyncRequest(on_complete, &prog_ctx);
   }
 
-  BOOST_SCOPE_EXIT( (&ctx)(async_request_id)(&m_task_finisher)
-                    (&m_async_requests)(&m_async_request_lock) ) {
-    m_task_finisher->cancel(Task(TASK_CODE_ASYNC_REQUEST, async_request_id));
-
-    RWLock::WLocker l(m_async_request_lock);
-    m_async_requests.erase(async_request_id);
-  } BOOST_SCOPE_EXIT_END
-
   schedule_async_request_timed_out(async_request_id);
-  int r = notify_lock_owner(in);
-  if (r < 0) {
-    return r;
-  }
-  return ctx.wait();
+  notify_lock_owner(std::move(in), on_notify);
 }
 
 int ImageWatcher::prepare_async_request(const AsyncRequestId& async_request_id,
@@ -606,14 +638,12 @@ bool ImageWatcher::handle_payload(const AsyncProgressPayload &payload,
 
 bool ImageWatcher::handle_payload(const AsyncCompletePayload &payload,
                                   C_NotifyAck *ack_ctx) {
-  RWLock::RLocker l(m_async_request_lock);
-  std::map<AsyncRequestId, AsyncRequest>::iterator req_it =
-    m_async_requests.find(payload.async_request_id);
-  if (req_it != m_async_requests.end()) {
+  Context *on_complete = remove_async_request(payload.async_request_id);
+  if (on_complete != nullptr) {
     ldout(m_image_ctx.cct, 10) << this << " request finished: "
                                << payload.async_request_id << "="
 			       << payload.result << dendl;
-    req_it->second.first->complete(payload.result);
+    on_complete->complete(payload.result);
   }
   return true;
 }
@@ -632,7 +662,7 @@ bool ImageWatcher::handle_payload(const FlattenPayload &payload,
     if (new_request) {
       ldout(m_image_ctx.cct, 10) << this << " remote flatten request: "
 				 << payload.async_request_id << dendl;
-      m_image_ctx.operations->flatten(*prog_ctx, ctx);
+      m_image_ctx.operations->execute_flatten(*prog_ctx, ctx);
     }
 
     ::encode(ResponseMessage(r), ack_ctx->out);
@@ -654,7 +684,7 @@ bool ImageWatcher::handle_payload(const ResizePayload &payload,
       ldout(m_image_ctx.cct, 10) << this << " remote resize request: "
 				 << payload.async_request_id << " "
 				 << payload.size << dendl;
-      m_image_ctx.operations->resize(payload.size, *prog_ctx, ctx, 0);
+      m_image_ctx.operations->execute_resize(payload.size, *prog_ctx, ctx, 0);
     }
 
     ::encode(ResponseMessage(r), ack_ctx->out);
@@ -670,8 +700,9 @@ bool ImageWatcher::handle_payload(const SnapCreatePayload &payload,
     ldout(m_image_ctx.cct, 10) << this << " remote snap_create request: "
 			       << payload.snap_name << dendl;
 
-    m_image_ctx.operations->snap_create(payload.snap_name.c_str(),
-                                        new C_ResponseMessage(ack_ctx), 0);
+    m_image_ctx.operations->execute_snap_create(payload.snap_name.c_str(),
+                                                new C_ResponseMessage(ack_ctx),
+                                                0);
     return false;
   }
   return true;
@@ -686,9 +717,9 @@ bool ImageWatcher::handle_payload(const SnapRenamePayload &payload,
 			       << payload.snap_id << " to "
 			       << payload.snap_name << dendl;
 
-    m_image_ctx.operations->snap_rename(payload.snap_id,
-                                        payload.snap_name.c_str(),
-                                        new C_ResponseMessage(ack_ctx));
+    m_image_ctx.operations->execute_snap_rename(payload.snap_id,
+                                                payload.snap_name.c_str(),
+                                                new C_ResponseMessage(ack_ctx));
     return false;
   }
   return true;
@@ -702,8 +733,8 @@ bool ImageWatcher::handle_payload(const SnapRemovePayload &payload,
     ldout(m_image_ctx.cct, 10) << this << " remote snap_remove request: "
 			       << payload.snap_name << dendl;
 
-    m_image_ctx.operations->snap_remove(payload.snap_name.c_str(),
-                                        new C_ResponseMessage(ack_ctx));
+    m_image_ctx.operations->execute_snap_remove(payload.snap_name.c_str(),
+                                                new C_ResponseMessage(ack_ctx));
     return false;
   }
   return true;
@@ -717,8 +748,8 @@ bool ImageWatcher::handle_payload(const SnapProtectPayload& payload,
     ldout(m_image_ctx.cct, 10) << this << " remote snap_protect request: "
                                << payload.snap_name << dendl;
 
-    m_image_ctx.operations->snap_protect(payload.snap_name.c_str(),
-                                         new C_ResponseMessage(ack_ctx));
+    m_image_ctx.operations->execute_snap_protect(payload.snap_name.c_str(),
+                                                 new C_ResponseMessage(ack_ctx));
     return false;
   }
   return true;
@@ -732,8 +763,8 @@ bool ImageWatcher::handle_payload(const SnapUnprotectPayload& payload,
     ldout(m_image_ctx.cct, 10) << this << " remote snap_unprotect request: "
                                << payload.snap_name << dendl;
 
-    m_image_ctx.operations->snap_unprotect(payload.snap_name.c_str(),
-                                           new C_ResponseMessage(ack_ctx));
+    m_image_ctx.operations->execute_snap_unprotect(payload.snap_name.c_str(),
+                                                   new C_ResponseMessage(ack_ctx));
     return false;
   }
   return true;
@@ -753,7 +784,7 @@ bool ImageWatcher::handle_payload(const RebuildObjectMapPayload& payload,
       ldout(m_image_ctx.cct, 10) << this
                                  << " remote rebuild object map request: "
                                  << payload.async_request_id << dendl;
-      m_image_ctx.operations->rebuild_object_map(*prog_ctx, ctx);
+      m_image_ctx.operations->execute_rebuild_object_map(*prog_ctx, ctx);
     }
 
     ::encode(ResponseMessage(r), ack_ctx->out);
@@ -769,7 +800,7 @@ bool ImageWatcher::handle_payload(const RenamePayload& payload,
     ldout(m_image_ctx.cct, 10) << this << " remote rename request: "
                                << payload.image_name << dendl;
 
-    m_image_ctx.operations->rename(payload.image_name.c_str(),
+    m_image_ctx.operations->execute_rename(payload.image_name.c_str(),
                                    new C_ResponseMessage(ack_ctx));
     return false;
   }
@@ -814,7 +845,8 @@ void ImageWatcher::handle_notify(uint64_t notify_id, uint64_t handle,
   }
 
   // if an image refresh is required, refresh before processing the request
-  if (m_image_ctx.state->is_refresh_required()) {
+  if (notify_message.check_for_refresh() &&
+      m_image_ctx.state->is_refresh_required()) {
     m_image_ctx.state->refresh(new C_ProcessPayload(this, notify_id, handle,
                                                     notify_message.payload));
   } else {
diff --git a/src/librbd/ImageWatcher.h b/src/librbd/ImageWatcher.h
index c82ca55..da1c11b 100644
--- a/src/librbd/ImageWatcher.h
+++ b/src/librbd/ImageWatcher.h
@@ -1,14 +1,15 @@
 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
 // vim: ts=8 sw=2 smarttab
+
 #ifndef CEPH_LIBRBD_IMAGE_WATCHER_H
 #define CEPH_LIBRBD_IMAGE_WATCHER_H
 
-#include "common/Cond.h"
 #include "common/Mutex.h"
 #include "common/RWLock.h"
 #include "include/Context.h"
 #include "include/rados/librados.hpp"
 #include "include/rbd/librbd.hpp"
+#include "librbd/image_watcher/Notifier.h"
 #include "librbd/WatchNotifyTypes.h"
 #include <set>
 #include <string>
@@ -29,28 +30,30 @@ public:
   ImageWatcher(ImageCtx& image_ctx);
   ~ImageWatcher();
 
-  int register_watch();
-  int unregister_watch();
-
-  int notify_flatten(uint64_t request_id, ProgressContext &prog_ctx);
-  int notify_resize(uint64_t request_id, uint64_t size,
-                    ProgressContext &prog_ctx);
-  int notify_snap_create(const std::string &snap_name);
-  int notify_snap_rename(const snapid_t &src_snap_id,
-                         const std::string &dst_snap_name);
-  int notify_snap_remove(const std::string &snap_name);
-  int notify_snap_protect(const std::string &snap_name);
-  int notify_snap_unprotect(const std::string &snap_name);
-  int notify_rebuild_object_map(uint64_t request_id,
-                                ProgressContext &prog_ctx);
-  int notify_rename(const std::string &image_name);
+  void register_watch(Context *on_finish);
+  void unregister_watch(Context *on_finish);
+  void flush(Context *on_finish);
+
+  void notify_flatten(uint64_t request_id, ProgressContext &prog_ctx,
+                      Context *on_finish);
+  void notify_resize(uint64_t request_id, uint64_t size,
+                     ProgressContext &prog_ctx, Context *on_finish);
+  void notify_snap_create(const std::string &snap_name, Context *on_finish);
+  void notify_snap_rename(const snapid_t &src_snap_id,
+                          const std::string &dst_snap_name,
+                          Context *on_finish);
+  void notify_snap_remove(const std::string &snap_name, Context *on_finish);
+  void notify_snap_protect(const std::string &snap_name, Context *on_finish);
+  void notify_snap_unprotect(const std::string &snap_name, Context *on_finish);
+  void notify_rebuild_object_map(uint64_t request_id,
+                                 ProgressContext &prog_ctx, Context *on_finish);
+  void notify_rename(const std::string &image_name, Context *on_finish);
 
   void notify_acquired_lock();
   void notify_released_lock();
   void notify_request_lock();
 
-  static void notify_header_update(librados::IoCtx &io_ctx,
-                                   const std::string &oid);
+  void notify_header_update(Context *on_finish);
 
   uint64_t get_watch_handle() const {
     RWLock::RLocker watch_locker(m_watch_lock);
@@ -65,9 +68,7 @@ private:
   };
 
   enum TaskCode {
-    TASK_CODE_ACQUIRED_LOCK,
     TASK_CODE_REQUEST_LOCK,
-    TASK_CODE_RELEASED_LOCK,
     TASK_CODE_CANCEL_ASYNC_REQUESTS,
     TASK_CODE_REREGISTER_WATCH,
     TASK_CODE_ASYNC_REQUEST,
@@ -150,6 +151,18 @@ private:
     ProgressContext *m_prog_ctx;
   };
 
+  struct C_RegisterWatch : public Context {
+    ImageWatcher *image_watcher;
+    Context *on_finish;
+
+    C_RegisterWatch(ImageWatcher *image_watcher, Context *on_finish)
+       : image_watcher(image_watcher), on_finish(on_finish) {
+    }
+    virtual void finish(int r) override {
+      image_watcher->handle_register_watch(r);
+      on_finish->complete(r);
+    }
+  };
   struct C_NotifyAck : public Context {
     ImageWatcher *image_watcher;
     uint64_t notify_id;
@@ -223,28 +236,36 @@ private:
   Mutex m_owner_client_id_lock;
   watch_notify::ClientId m_owner_client_id;
 
+  image_watcher::Notifier m_notifier;
+
+  void handle_register_watch(int r);
+
   void schedule_cancel_async_requests();
   void cancel_async_requests();
 
   void set_owner_client_id(const watch_notify::ClientId &client_id);
   watch_notify::ClientId get_client_id();
 
+  void handle_request_lock(int r);
   void schedule_request_lock(bool use_timer, int timer_delay = -1);
 
-  int notify_lock_owner(bufferlist &bl);
+  void notify_lock_owner(bufferlist &&bl, Context *on_finish);
 
+  Context *remove_async_request(const watch_notify::AsyncRequestId &id);
   void schedule_async_request_timed_out(const watch_notify::AsyncRequestId &id);
   void async_request_timed_out(const watch_notify::AsyncRequestId &id);
-  int notify_async_request(const watch_notify::AsyncRequestId &id,
-                           bufferlist &in, ProgressContext& prog_ctx);
-  void notify_request_leadership();
+  void notify_async_request(const watch_notify::AsyncRequestId &id,
+                            bufferlist &&in, ProgressContext& prog_ctx,
+                            Context *on_finish);
 
   void schedule_async_progress(const watch_notify::AsyncRequestId &id,
                                uint64_t offset, uint64_t total);
   int notify_async_progress(const watch_notify::AsyncRequestId &id,
                             uint64_t offset, uint64_t total);
   void schedule_async_complete(const watch_notify::AsyncRequestId &id, int r);
-  int notify_async_complete(const watch_notify::AsyncRequestId &id, int r);
+  void notify_async_complete(const watch_notify::AsyncRequestId &id, int r);
+  void handle_async_complete(const watch_notify::AsyncRequestId &request, int r,
+                             int ret_val);
 
   int prepare_async_request(const watch_notify::AsyncRequestId& id,
                             bool* new_request, Context** ctx,
diff --git a/src/librbd/Journal.cc b/src/librbd/Journal.cc
index a597671..ec000f9 100644
--- a/src/librbd/Journal.cc
+++ b/src/librbd/Journal.cc
@@ -8,11 +8,14 @@
 #include "librbd/ExclusiveLock.h"
 #include "librbd/ImageCtx.h"
 #include "librbd/journal/Replay.h"
-#include "librbd/journal/Types.h"
 #include "librbd/Utils.h"
+#include "cls/journal/cls_journal_types.h"
 #include "journal/Journaler.h"
 #include "journal/ReplayEntry.h"
 #include "common/errno.h"
+#include "common/Timer.h"
+#include "common/WorkQueue.h"
+#include <boost/scope_exit.hpp>
 
 #define dout_subsys ceph_subsys_rbd
 #undef dout_prefix
@@ -20,9 +23,207 @@
 
 namespace librbd {
 
+namespace {
+
+struct C_DecodeTag : public Context {
+  CephContext *cct;
+  Mutex *lock;
+  uint64_t *tag_tid;
+  journal::TagData *tag_data;
+  Context *on_finish;
+
+  cls::journal::Tag tag;
+
+  C_DecodeTag(CephContext *cct, Mutex *lock, uint64_t *tag_tid,
+              journal::TagData *tag_data, Context *on_finish)
+    : cct(cct), lock(lock), tag_tid(tag_tid), tag_data(tag_data),
+      on_finish(on_finish) {
+  }
+
+  virtual void complete(int r) override {
+    on_finish->complete(process(r));
+    Context::complete(0);
+  }
+  virtual void finish(int r) override {
+  }
+
+  int process(int r) {
+    if (r < 0) {
+      lderr(cct) << "failed to allocate tag: " << cpp_strerror(r) << dendl;
+      return r;
+    }
+
+    Mutex::Locker locker(*lock);
+    *tag_tid = tag.tid;
+
+    bufferlist::iterator data_it = tag.data.begin();
+    r = decode(&data_it, tag_data);
+    if (r < 0) {
+      lderr(cct) << "failed to decode allocated tag" << dendl;
+      return r;
+    }
+
+    ldout(cct, 20) << "allocated journal tag: "
+                   << "tid=" << tag.tid << ", "
+                   << "data=" << *tag_data << dendl;
+    return 0;
+  }
+
+  static int decode(bufferlist::iterator *it,
+                    journal::TagData *tag_data) {
+    try {
+      ::decode(*tag_data, *it);
+    } catch (const buffer::error &err) {
+      return -EBADMSG;
+    }
+    return 0;
+  }
+
+};
+
+struct C_DecodeTags : public Context {
+  CephContext *cct;
+  Mutex *lock;
+  uint64_t *tag_tid;
+  journal::TagData *tag_data;
+  Context *on_finish;
+
+  ::journal::Journaler::Tags tags;
+
+  C_DecodeTags(CephContext *cct, Mutex *lock, uint64_t *tag_tid,
+               journal::TagData *tag_data, Context *on_finish)
+    : cct(cct), lock(lock), tag_tid(tag_tid), tag_data(tag_data),
+      on_finish(on_finish) {
+  }
+
+  virtual void complete(int r) {
+    on_finish->complete(process(r));
+    Context::complete(0);
+  }
+  virtual void finish(int r) override {
+  }
+
+  int process(int r) {
+    if (r < 0) {
+      lderr(cct) << "failed to retrieve journal tags: " << cpp_strerror(r)
+                 << dendl;
+      return r;
+    }
+
+    if (tags.empty()) {
+      lderr(cct) << "no journal tags retrieved" << dendl;
+      return -ENOENT;
+    }
+
+    Mutex::Locker locker(*lock);
+    *tag_tid = tags.back().tid;
+
+    bufferlist::iterator data_it = tags.back().data.begin();
+    r = C_DecodeTag::decode(&data_it, tag_data);
+    if (r < 0) {
+      lderr(cct) << "failed to decode journal tag" << dendl;
+      return r;
+    }
+
+    ldout(cct, 20) << "most recent journal tag: "
+                   << "tid=" << *tag_tid << ", "
+                   << "data=" << *tag_data << dendl;
+    return 0;
+  }
+};
+
+// TODO: once journaler is 100% async, remove separate threads and
+// reuse ImageCtx's thread pool
+class ThreadPoolSingleton : public ThreadPool {
+public:
+  explicit ThreadPoolSingleton(CephContext *cct)
+    : ThreadPool(cct, "librbd::Journal", "tp_librbd_journ", 1) {
+    start();
+  }
+  virtual ~ThreadPoolSingleton() {
+    stop();
+  }
+};
+
+class SafeTimerSingleton : public SafeTimer {
+public:
+  Mutex lock;
+
+  explicit SafeTimerSingleton(CephContext *cct)
+      : SafeTimer(cct, lock, true),
+        lock("librbd::Journal::SafeTimerSingleton::lock") {
+    init();
+  }
+  virtual ~SafeTimerSingleton() {
+    Mutex::Locker locker(lock);
+    shutdown();
+  }
+};
+
+template <typename I, typename J>
+int open_journaler(I *image_ctx, J *journaler, bool *initialized,
+                   journal::ImageClientMeta *client_meta,
+                   journal::TagData *tag_data) {
+  C_SaferCond init_ctx;
+  journaler->init(&init_ctx);
+  int r = init_ctx.wait();
+  *initialized = (r >= 0);
+  if (r < 0) {
+    return r;
+  }
+
+  cls::journal::Client client;
+  r = journaler->get_cached_client(Journal<ImageCtx>::IMAGE_CLIENT_ID, &client);
+  if (r < 0) {
+    return r;
+  }
+
+  librbd::journal::ClientData client_data;
+  bufferlist::iterator bl_it = client.data.begin();
+  try {
+    ::decode(client_data, bl_it);
+  } catch (const buffer::error &err) {
+    return -EINVAL;
+  }
+
+  journal::ImageClientMeta *image_client_meta =
+    boost::get<journal::ImageClientMeta>(&client_data.client_meta);
+  if (image_client_meta == nullptr) {
+    return -EINVAL;
+  }
+  *client_meta = *image_client_meta;
+
+  C_SaferCond get_tags_ctx;
+  Mutex lock("lock");
+  uint64_t tag_tid;
+  C_DecodeTags *tags_ctx = new C_DecodeTags(
+    image_ctx->cct, &lock, &tag_tid, tag_data, &get_tags_ctx);
+  journaler->get_tags(client_meta->tag_class, &tags_ctx->tags, tags_ctx);
+
+  r = get_tags_ctx.wait();
+  if (r < 0) {
+    return r;
+  }
+  return 0;
+}
+
+} // anonymous namespace
+
 using util::create_async_context_callback;
 using util::create_context_callback;
 
+// client id for local image
+template <typename I>
+const std::string Journal<I>::IMAGE_CLIENT_ID("");
+
+// mirror uuid to use for local images
+template <typename I>
+const std::string Journal<I>::LOCAL_MIRROR_UUID("");
+
+// mirror uuid to use for orphaned (demoted) images
+template <typename I>
+const std::string Journal<I>::ORPHAN_MIRROR_UUID("<orphan>");
+
 template <typename I>
 std::ostream &operator<<(std::ostream &os,
                          const typename Journal<I>::State &state) {
@@ -72,11 +273,30 @@ Journal<I>::Journal(I &image_ctx)
     m_event_lock("Journal<I>::m_event_lock"), m_event_tid(0),
     m_blocking_writes(false), m_journal_replay(NULL) {
 
-  ldout(m_image_ctx.cct, 5) << this << ": ictx=" << &m_image_ctx << dendl;
+  CephContext *cct = m_image_ctx.cct;
+  ldout(cct, 5) << this << ": ictx=" << &m_image_ctx << dendl;
+
+  ThreadPoolSingleton *thread_pool_singleton;
+  cct->lookup_or_create_singleton_object<ThreadPoolSingleton>(
+    thread_pool_singleton, "librbd::journal::thread_pool");
+  m_work_queue = new ContextWQ("librbd::journal::work_queue",
+                               cct->_conf->rbd_op_thread_timeout,
+                               thread_pool_singleton);
+
+  SafeTimerSingleton *safe_timer_singleton;
+  cct->lookup_or_create_singleton_object<SafeTimerSingleton>(
+    safe_timer_singleton, "librbd::journal::safe_timer");
+  m_timer = safe_timer_singleton;
+  m_timer_lock = &safe_timer_singleton->lock;
 }
 
 template <typename I>
 Journal<I>::~Journal() {
+  if (m_work_queue != nullptr) {
+    m_work_queue->drain();
+    delete m_work_queue;
+  }
+
   assert(m_state == STATE_UNINITIALIZED || m_state == STATE_CLOSED);
   assert(m_journaler == NULL);
   assert(m_journal_replay == NULL);
@@ -111,7 +331,8 @@ int Journal<I>::create(librados::IoCtx &io_ctx, const std::string &image_id,
     pool_id = data_io_ctx.get_id();
   }
 
-  Journaler journaler(io_ctx, image_id, "", cct->_conf->rbd_journal_commit_age);
+  Journaler journaler(io_ctx, image_id, IMAGE_CLIENT_ID,
+                      cct->_conf->rbd_journal_commit_age);
 
   int r = journaler.create(order, splay_width, pool_id);
   if (r < 0) {
@@ -119,16 +340,9 @@ int Journal<I>::create(librados::IoCtx &io_ctx, const std::string &image_id,
     return r;
   }
 
-  std::string cluster_id;
-  r = rados.cluster_fsid(&cluster_id);
-  if (r < 0) {
-    lderr(cct) << "failed to retrieve cluster id: " << cpp_strerror(r) << dendl;
-    return r;
-  }
-
   // create tag class for this image's journal events
   bufferlist tag_data;
-  ::encode(journal::TagData{cluster_id, pool_id, image_id}, tag_data);
+  ::encode(journal::TagData(), tag_data);
 
   C_SaferCond tag_ctx;
   cls::journal::Tag tag;
@@ -157,7 +371,8 @@ int Journal<I>::remove(librados::IoCtx &io_ctx, const std::string &image_id) {
   CephContext *cct = reinterpret_cast<CephContext *>(io_ctx.cct());
   ldout(cct, 5) << __func__ << ": image=" << image_id << dendl;
 
-  Journaler journaler(io_ctx, image_id, "", cct->_conf->rbd_journal_commit_age);
+  Journaler journaler(io_ctx, image_id, IMAGE_CLIENT_ID,
+                      cct->_conf->rbd_journal_commit_age);
 
   bool journal_exists;
   int r = journaler.exists(&journal_exists);
@@ -192,7 +407,8 @@ int Journal<I>::reset(librados::IoCtx &io_ctx, const std::string &image_id) {
   CephContext *cct = reinterpret_cast<CephContext *>(io_ctx.cct());
   ldout(cct, 5) << __func__ << ": image=" << image_id << dendl;
 
-  Journaler journaler(io_ctx, image_id, "", cct->_conf->rbd_journal_commit_age);
+  Journaler journaler(io_ctx, image_id, IMAGE_CLIENT_ID,
+                      cct->_conf->rbd_journal_commit_age);
 
   C_SaferCond cond;
   journaler.init(&cond);
@@ -228,6 +444,125 @@ int Journal<I>::reset(librados::IoCtx &io_ctx, const std::string &image_id) {
 }
 
 template <typename I>
+int Journal<I>::is_tag_owner(I *image_ctx, bool *is_tag_owner) {
+  std::string mirror_uuid;
+  int r = get_tag_owner(image_ctx, &mirror_uuid);
+  if (r < 0) {
+    return r;
+  }
+
+  *is_tag_owner = (mirror_uuid == LOCAL_MIRROR_UUID);
+  return 0;
+}
+
+template <typename I>
+int Journal<I>::get_tag_owner(I *image_ctx, std::string *mirror_uuid) {
+  CephContext *cct = image_ctx->cct;
+  ldout(cct, 20) << __func__ << dendl;
+
+  Journaler journaler(image_ctx->md_ctx, image_ctx->id, IMAGE_CLIENT_ID,
+                      image_ctx->cct->_conf->rbd_journal_commit_age);
+
+  bool initialized;
+  journal::ImageClientMeta client_meta;
+  journal::TagData tag_data;
+  int r = open_journaler(image_ctx, &journaler, &initialized, &client_meta,
+                         &tag_data);
+  if (r >= 0) {
+    *mirror_uuid = tag_data.mirror_uuid;
+  }
+
+  if (initialized) {
+    journaler.shut_down();
+  }
+  return r;
+}
+
+template <typename I>
+int Journal<I>::allocate_tag(I *image_ctx, const std::string &mirror_uuid) {
+  CephContext *cct = image_ctx->cct;
+  ldout(cct, 20) << __func__ << ": mirror_uuid=" << mirror_uuid << dendl;
+
+  Journaler journaler(image_ctx->md_ctx, image_ctx->id, IMAGE_CLIENT_ID,
+                      image_ctx->cct->_conf->rbd_journal_commit_age);
+
+  bool initialized;
+  journal::ImageClientMeta client_meta;
+  journal::TagData tag_data;
+  int r = open_journaler(image_ctx, &journaler, &initialized, &client_meta,
+                         &tag_data);
+  BOOST_SCOPE_EXIT_ALL(&journaler, &initialized) {
+    if (initialized) {
+      journaler.shut_down();
+    }
+  };
+
+  if (r < 0) {
+    return r;
+  }
+
+  // TODO: inject current commit position into tag data
+  tag_data.mirror_uuid = mirror_uuid;
+  tag_data.predecessor_mirror_uuid = mirror_uuid;
+
+  bufferlist tag_bl;
+  ::encode(tag_data, tag_bl);
+
+  C_SaferCond allocate_tag_ctx;
+  cls::journal::Tag tag;
+  journaler.allocate_tag(client_meta.tag_class, tag_bl, &tag,
+                         &allocate_tag_ctx);
+
+  r = allocate_tag_ctx.wait();
+  if (r < 0) {
+    lderr(cct) << "failed to allocate tag: " << cpp_strerror(r) << dendl;
+    return r;
+  }
+
+  return 0;
+}
+
+template <typename I>
+int Journal<I>::request_resync(I *image_ctx) {
+  CephContext *cct = image_ctx->cct;
+  ldout(cct, 20) << __func__ << dendl;
+
+  Journaler journaler(image_ctx->md_ctx, image_ctx->id, IMAGE_CLIENT_ID,
+                      image_ctx->cct->_conf->rbd_journal_commit_age);
+
+  bool initialized;
+  journal::ImageClientMeta client_meta;
+  journal::TagData tag_data;
+  int r = open_journaler(image_ctx, &journaler, &initialized, &client_meta,
+                         &tag_data);
+  BOOST_SCOPE_EXIT_ALL(&journaler, &initialized) {
+    if (initialized) {
+      journaler.shut_down();
+    }
+  };
+
+  if (r < 0) {
+    return r;
+  }
+
+  client_meta.resync_requested = true;
+
+  journal::ClientData client_data(client_meta);
+  bufferlist client_data_bl;
+  ::encode(client_data, client_data_bl);
+
+  C_SaferCond update_client_ctx;
+  journaler.update_client(client_data_bl, &update_client_ctx);
+
+  r = update_client_ctx.wait();
+  if (r < 0) {
+    lderr(cct) << "failed to update client: " << cpp_strerror(r) << dendl;
+    return r;
+  }
+  return 0;
+}
+
+template <typename I>
 bool Journal<I>::is_journal_ready() const {
   Mutex::Locker locker(m_lock);
   return (m_state == STATE_READY);
@@ -289,6 +624,48 @@ void Journal<I>::close(Context *on_finish) {
 }
 
 template <typename I>
+bool Journal<I>::is_tag_owner() const {
+  return (m_tag_data.mirror_uuid == LOCAL_MIRROR_UUID);
+}
+
+template <typename I>
+void Journal<I>::allocate_tag(const std::string &mirror_uuid,
+                              Context *on_finish) {
+  CephContext *cct = m_image_ctx.cct;
+  ldout(cct, 20) << this << " " << __func__ << ":  mirror_uuid=" << mirror_uuid
+                 << dendl;
+
+  Mutex::Locker locker(m_lock);
+  assert(m_journaler != nullptr && is_tag_owner());
+
+  // NOTE: currently responsibility of caller to provide local mirror
+  // uuid constant or remote peer uuid
+  journal::TagData tag_data;
+  tag_data.mirror_uuid = mirror_uuid;
+
+  // TODO: inject current commit position into tag data (need updated journaler PR)
+  tag_data.predecessor_mirror_uuid = m_tag_data.mirror_uuid;
+
+  bufferlist tag_bl;
+  ::encode(tag_data, tag_bl);
+
+  C_DecodeTag *decode_tag_ctx = new C_DecodeTag(cct, &m_lock, &m_tag_tid,
+                                                &m_tag_data, on_finish);
+  m_journaler->allocate_tag(m_tag_class, tag_bl, &decode_tag_ctx->tag,
+                            decode_tag_ctx);
+}
+
+template <typename I>
+void Journal<I>::flush_commit_position(Context *on_finish) {
+  CephContext *cct = m_image_ctx.cct;
+  ldout(cct, 20) << this << " " << __func__ << dendl;
+
+  Mutex::Locker locker(m_lock);
+  assert(m_journaler != nullptr);
+  m_journaler->flush_commit_position(on_finish);
+}
+
+template <typename I>
 uint64_t Journal<I>::append_io_event(AioCompletion *aio_comp,
                                      journal::EventEntry &&event_entry,
                                      const AioObjectRequests &requests,
@@ -309,8 +686,7 @@ uint64_t Journal<I>::append_io_event(AioCompletion *aio_comp,
     tid = ++m_event_tid;
     assert(tid != 0);
 
-    // TODO: use allocated tag_id
-    future = m_journaler->append(0, bl);
+    future = m_journaler->append(m_tag_tid, bl);
     m_events[tid] = Event(future, aio_comp, requests, offset, length);
   }
 
@@ -395,12 +771,15 @@ void Journal<I>::append_op_event(uint64_t op_tid,
     Mutex::Locker locker(m_lock);
     assert(m_state == STATE_READY);
 
-    // TODO: use allocated tag_id
-    future = m_journaler->append(0, bl);
+    future = m_journaler->append(m_tag_tid, bl);
+
+    // delay committing op event to ensure consistent replay
+    assert(m_op_futures.count(op_tid) == 0);
+    m_op_futures[op_tid] = future;
   }
 
   on_safe = create_async_context_callback(m_image_ctx, on_safe);
-  future.flush(new C_OpEventSafe(this, op_tid, future, on_safe));
+  future.flush(on_safe);
 
   CephContext *cct = m_image_ctx.cct;
   ldout(cct, 10) << this << " " << __func__ << ": "
@@ -419,16 +798,23 @@ void Journal<I>::commit_op_event(uint64_t op_tid, int r) {
   bufferlist bl;
   ::encode(event_entry, bl);
 
-  Future future;
+  Future op_start_future;
+  Future op_finish_future;
   {
     Mutex::Locker locker(m_lock);
     assert(m_state == STATE_READY);
 
-    // TODO: use allocated tag_id
-    future = m_journaler->append(0, bl);
+    // ready to commit op event
+    auto it = m_op_futures.find(op_tid);
+    assert(it != m_op_futures.end());
+    op_start_future = it->second;
+    m_op_futures.erase(it);
+
+    op_finish_future = m_journaler->append(m_tag_tid, bl);
   }
 
-  future.flush(new C_OpEventSafe(this, op_tid, future, nullptr));
+  op_finish_future.flush(new C_OpEventSafe(this, op_tid, op_start_future,
+                                           op_finish_future));
 }
 
 template <typename I>
@@ -493,6 +879,33 @@ typename Journal<I>::Future Journal<I>::wait_event(Mutex &lock, uint64_t tid,
 }
 
 template <typename I>
+int Journal<I>::start_external_replay(journal::Replay<I> **journal_replay) {
+  CephContext *cct = m_image_ctx.cct;
+  ldout(cct, 20) << this << " " << __func__ << dendl;
+
+  Mutex::Locker locker(m_lock);
+  assert(m_state == STATE_READY);
+  assert(m_journal_replay == nullptr);
+
+  transition_state(STATE_REPLAYING, 0);
+  m_journal_replay = journal::Replay<I>::create(m_image_ctx);
+
+  *journal_replay = m_journal_replay;
+  return 0;
+}
+
+template <typename I>
+void Journal<I>::stop_external_replay() {
+  Mutex::Locker locker(m_lock);
+  assert(m_journal_replay != nullptr);
+  assert(m_state == STATE_REPLAYING);
+
+  delete m_journal_replay;
+  m_journal_replay = nullptr;
+  transition_state(STATE_READY, 0);
+}
+
+template <typename I>
 void Journal<I>::create_journaler() {
   CephContext *cct = m_image_ctx.cct;
   ldout(cct, 20) << this << " " << __func__ << dendl;
@@ -502,8 +915,9 @@ void Journal<I>::create_journaler() {
   assert(m_journaler == NULL);
 
   transition_state(STATE_INITIALIZING, 0);
-  m_journaler = new Journaler(m_image_ctx.md_ctx, m_image_ctx.id, "",
-                              m_image_ctx.journal_commit_age);
+  m_journaler = new Journaler(m_work_queue, m_timer, m_timer_lock,
+			      m_image_ctx.md_ctx, m_image_ctx.id,
+			      IMAGE_CLIENT_ID, m_image_ctx.journal_commit_age);
   m_journaler->init(create_async_context_callback(
     m_image_ctx, create_context_callback<
       Journal<I>, &Journal<I>::handle_initialized>(this)));
@@ -574,15 +988,69 @@ void Journal<I>::handle_initialized(int r) {
   ldout(cct, 20) << this << " " << __func__ << ": r=" << r << dendl;
 
   Mutex::Locker locker(m_lock);
+  assert(m_state == STATE_INITIALIZING);
 
   if (r < 0) {
-    lderr(cct) << this << " " << __func__
+    lderr(cct) << this << " " << __func__ << ": "
                << "failed to initialize journal: " << cpp_strerror(r)
                << dendl;
     destroy_journaler(r);
     return;
   }
 
+  // locate the master image client record
+  cls::journal::Client client;
+  r = m_journaler->get_cached_client(Journal<ImageCtx>::IMAGE_CLIENT_ID,
+                                     &client);
+  if (r < 0) {
+    lderr(cct) << "failed to locate master image client" << dendl;
+    destroy_journaler(r);
+    return;
+  }
+
+  librbd::journal::ClientData client_data;
+  bufferlist::iterator bl = client.data.begin();
+  try {
+    ::decode(client_data, bl);
+  } catch (const buffer::error &err) {
+    lderr(cct) << "failed to decode client meta data: " << err.what()
+               << dendl;
+    destroy_journaler(-EINVAL);
+    return;
+  }
+
+  journal::ImageClientMeta *image_client_meta =
+    boost::get<journal::ImageClientMeta>(&client_data.client_meta);
+  if (image_client_meta == nullptr) {
+    lderr(cct) << "failed to extract client meta data" << dendl;
+    destroy_journaler(-EINVAL);
+    return;
+  }
+
+  m_tag_class = image_client_meta->tag_class;
+  ldout(cct, 20) << "client: " << client << ", "
+                 << "image meta: " << *image_client_meta << dendl;
+
+  C_DecodeTags *tags_ctx = new C_DecodeTags(
+    cct, &m_lock, &m_tag_tid, &m_tag_data, create_async_context_callback(
+      m_image_ctx, create_context_callback<
+        Journal<I>, &Journal<I>::handle_get_tags>(this)));
+  m_journaler->get_tags(m_tag_class, &tags_ctx->tags, tags_ctx);
+}
+
+template <typename I>
+void Journal<I>::handle_get_tags(int r) {
+  CephContext *cct = m_image_ctx.cct;
+  ldout(cct, 20) << this << " " << __func__ << ": r=" << r << dendl;
+
+  Mutex::Locker locker(m_lock);
+  assert(m_state == STATE_INITIALIZING);
+
+  if (r < 0) {
+    destroy_journaler(r);
+    return;
+  }
+
   transition_state(STATE_REPLAYING, 0);
   m_journal_replay = journal::Replay<I>::create(m_image_ctx);
   m_journaler->start_replay(&m_replay_handler);
@@ -629,13 +1097,13 @@ void Journal<I>::handle_replay_complete(int r) {
     transition_state(STATE_FLUSHING_RESTART, r);
     m_lock.Unlock();
 
-    m_journal_replay->flush(create_context_callback<
+    m_journal_replay->shut_down(true, create_context_callback<
       Journal<I>, &Journal<I>::handle_flushing_restart>(this));
   } else {
     transition_state(STATE_FLUSHING_REPLAY, 0);
     m_lock.Unlock();
 
-    m_journal_replay->flush(create_context_callback<
+    m_journal_replay->shut_down(false, create_context_callback<
       Journal<I>, &Journal<I>::handle_flushing_replay>(this));
   }
 }
@@ -665,7 +1133,7 @@ void Journal<I>::handle_replay_process_safe(ReplayEntry replay_entry, int r) {
       m_journaler->stop_replay();
       transition_state(STATE_FLUSHING_RESTART, r);
 
-      m_journal_replay->flush(create_context_callback<
+      m_journal_replay->shut_down(true, create_context_callback<
         Journal<I>, &Journal<I>::handle_flushing_restart>(this));
       return;
     } else if (m_state == STATE_FLUSHING_REPLAY) {
@@ -820,8 +1288,9 @@ void Journal<I>::handle_io_event_safe(int r, uint64_t tid) {
 }
 
 template <typename I>
-void Journal<I>::handle_op_event_safe(int r, uint64_t tid, const Future &future,
-                                      Context *on_safe) {
+void Journal<I>::handle_op_event_safe(int r, uint64_t tid,
+                                      const Future &op_start_future,
+                                      const Future &op_finish_future) {
   CephContext *cct = m_image_ctx.cct;
   ldout(cct, 20) << this << " " << __func__ << ": r=" << r << ", "
                  << "tid=" << tid << dendl;
@@ -832,10 +1301,11 @@ void Journal<I>::handle_op_event_safe(int r, uint64_t tid, const Future &future,
     lderr(cct) << "failed to commit op event: "  << cpp_strerror(r) << dendl;
   }
 
-  m_journaler->committed(future);
-  if (on_safe != nullptr) {
-    on_safe->complete(r);
-  }
+  m_journaler->committed(op_start_future);
+  m_journaler->committed(op_finish_future);
+
+  // reduce the replay window after committing an op event
+  m_journaler->flush_commit_position(nullptr);
 }
 
 template <typename I>
diff --git a/src/librbd/Journal.h b/src/librbd/Journal.h
index 2a03907..065b202 100644
--- a/src/librbd/Journal.h
+++ b/src/librbd/Journal.h
@@ -8,18 +8,21 @@
 #include "include/atomic.h"
 #include "include/Context.h"
 #include "include/interval_set.h"
-#include "include/unordered_map.h"
 #include "include/rados/librados.hpp"
 #include "common/Mutex.h"
 #include "journal/Future.h"
 #include "journal/ReplayEntry.h"
 #include "journal/ReplayHandler.h"
+#include "librbd/journal/Types.h"
 #include <algorithm>
 #include <iosfwd>
 #include <list>
 #include <string>
+#include <unordered_map>
 
 class Context;
+class ContextWQ;
+class SafeTimer;
 namespace journal {
 class Journaler;
 }
@@ -32,7 +35,6 @@ class ImageCtx;
 
 namespace journal {
 
-class EventEntry;
 template <typename> class Replay;
 
 template <typename ImageCtxT>
@@ -92,6 +94,10 @@ public:
     STATE_CLOSED
   };
 
+  static const std::string IMAGE_CLIENT_ID;
+  static const std::string LOCAL_MIRROR_UUID;
+  static const std::string ORPHAN_MIRROR_UUID;
+
   typedef std::list<AioObjectRequest *> AioObjectRequests;
 
   Journal(ImageCtxT &image_ctx);
@@ -104,6 +110,11 @@ public:
   static int remove(librados::IoCtx &io_ctx, const std::string &image_id);
   static int reset(librados::IoCtx &io_ctx, const std::string &image_id);
 
+  static int is_tag_owner(ImageCtxT *image_ctx, bool *is_tag_owner);
+  static int get_tag_owner(ImageCtxT *image_ctx, std::string *mirror_uuid);
+  static int allocate_tag(ImageCtxT *image_ctx, const std::string &mirror_uuid);
+  static int request_resync(ImageCtxT *image_ctx);
+
   bool is_journal_ready() const;
   bool is_journal_replaying() const;
 
@@ -112,6 +123,11 @@ public:
   void open(Context *on_finish);
   void close(Context *on_finish);
 
+  bool is_tag_owner() const;
+  void allocate_tag(const std::string &mirror_uuid, Context *on_finish);
+
+  void flush_commit_position(Context *on_finish);
+
   uint64_t append_io_event(AioCompletion *aio_comp,
                            journal::EventEntry &&event_entry,
                            const AioObjectRequests &requests,
@@ -135,6 +151,9 @@ public:
     return op_tid;
   }
 
+  int start_external_replay(journal::Replay<ImageCtxT> **journal_replay);
+  void stop_external_replay();
+
 private:
   ImageCtxT &m_image_ctx;
 
@@ -168,7 +187,8 @@ private:
     }
   };
 
-  typedef ceph::unordered_map<uint64_t, Event> Events;
+  typedef std::unordered_map<uint64_t, Event> Events;
+  typedef std::unordered_map<uint64_t, Future> TidToFutures;
 
   struct C_IOEventSafe : public Context {
     Journal *journal;
@@ -186,16 +206,17 @@ private:
   struct C_OpEventSafe : public Context {
     Journal *journal;
     uint64_t tid;
-    Future future;
-    Context *on_safe;
+    Future op_start_future;
+    Future op_finish_future;
 
-    C_OpEventSafe(Journal *journal, uint64_t tid, const Future &future,
-                  Context *on_safe)
-      : journal(journal), tid(tid), future(future), on_safe(on_safe) {
+    C_OpEventSafe(Journal *journal, uint64_t tid, const Future &op_start_future,
+                  const Future &op_finish_future)
+      : journal(journal), tid(tid), op_start_future(op_start_future),
+        op_finish_future(op_finish_future) {
     }
 
     virtual void finish(int r) {
-      journal->handle_op_event_safe(r, tid, future, on_safe);
+      journal->handle_op_event_safe(r, tid, op_start_future, op_finish_future);
     }
   };
 
@@ -231,9 +252,16 @@ private:
     }
   };
 
+  ContextWQ *m_work_queue = nullptr;
+  SafeTimer *m_timer = nullptr;
+  Mutex *m_timer_lock = nullptr;
+
   Journaler *m_journaler;
   mutable Mutex m_lock;
   State m_state;
+  uint64_t m_tag_class = 0;
+  uint64_t m_tag_tid = 0;
+  journal::TagData m_tag_data;
 
   int m_error_result;
   Contexts m_wait_for_state_contexts;
@@ -246,6 +274,7 @@ private:
   Events m_events;
 
   atomic_t m_op_tid;
+  TidToFutures m_op_futures;
 
   bool m_blocking_writes;
 
@@ -260,6 +289,7 @@ private:
   void complete_event(typename Events::iterator it, int r);
 
   void handle_initialized(int r);
+  void handle_get_tags(int r);
 
   void handle_replay_ready();
   void handle_replay_complete(int r);
@@ -274,8 +304,8 @@ private:
   void handle_journal_destroyed(int r);
 
   void handle_io_event_safe(int r, uint64_t tid);
-  void handle_op_event_safe(int r, uint64_t tid, const Future &future,
-                            Context *on_safe);
+  void handle_op_event_safe(int r, uint64_t tid, const Future &op_start_future,
+                            const Future &op_finish_future);
 
   void stop_recording();
 
diff --git a/src/librbd/LibrbdWriteback.cc b/src/librbd/LibrbdWriteback.cc
index 7a02e6a..231c9b1 100644
--- a/src/librbd/LibrbdWriteback.cc
+++ b/src/librbd/LibrbdWriteback.cc
@@ -218,7 +218,7 @@ namespace librbd {
     // reverse map this object extent onto the parent
     vector<pair<uint64_t,uint64_t> > objectx;
     Striper::extent_to_file(m_ictx->cct, &m_ictx->layout,
-			  object_no, 0, m_ictx->layout.fl_object_size,
+			  object_no, 0, m_ictx->layout.object_size,
 			  objectx);
     uint64_t object_overlap = m_ictx->prune_parent_extents(objectx, overlap);
     bool may = object_overlap > 0;
diff --git a/src/librbd/Makefile.am b/src/librbd/Makefile.am
index 7248f82..2cc5fdf 100644
--- a/src/librbd/Makefile.am
+++ b/src/librbd/Makefile.am
@@ -35,6 +35,8 @@ librbd_internal_la_SOURCES = \
 	librbd/image/RefreshParentRequest.cc \
 	librbd/image/RefreshRequest.cc \
 	librbd/image/SetSnapRequest.cc \
+	librbd/image_watcher/Notifier.cc \
+	librbd/image_watcher/NotifyLockOwner.cc \
 	librbd/journal/Replay.cc \
 	librbd/object_map/InvalidateRequest.cc \
 	librbd/object_map/LockRequest.cc \
@@ -114,6 +116,8 @@ noinst_HEADERS += \
 	librbd/image/RefreshParentRequest.h \
 	librbd/image/RefreshRequest.h \
 	librbd/image/SetSnapRequest.h \
+	librbd/image_watcher/Notifier.h \
+	librbd/image_watcher/NotifyLockOwner.h \
 	librbd/journal/Replay.h \
 	librbd/journal/Types.h \
 	librbd/object_map/InvalidateRequest.h \
diff --git a/src/librbd/Operations.cc b/src/librbd/Operations.cc
index 719baf5..f8151c9 100644
--- a/src/librbd/Operations.cc
+++ b/src/librbd/Operations.cc
@@ -8,6 +8,7 @@
 #include "librbd/ImageCtx.h"
 #include "librbd/ImageState.h"
 #include "librbd/ImageWatcher.h"
+#include "librbd/Utils.h"
 #include "librbd/operation/FlattenRequest.h"
 #include "librbd/operation/RebuildObjectMapRequest.h"
 #include "librbd/operation/RenameRequest.h"
@@ -18,6 +19,7 @@
 #include "librbd/operation/SnapshotRenameRequest.h"
 #include "librbd/operation/SnapshotRollbackRequest.h"
 #include "librbd/operation/SnapshotUnprotectRequest.h"
+#include <set>
 #include <boost/bind.hpp>
 
 #define dout_subsys ceph_subsys_rbd
@@ -26,8 +28,194 @@
 
 namespace librbd {
 
+namespace {
+
+template <typename I>
+struct C_NotifyUpdate : public Context {
+  I &image_ctx;
+  Context *on_finish;
+  bool notified = false;
+
+  C_NotifyUpdate(I &image_ctx, Context *on_finish)
+    : image_ctx(image_ctx), on_finish(on_finish) {
+  }
+
+  virtual void complete(int r) override {
+    if (r < 0 || notified) {
+      Context::complete(r);
+    } else {
+      notified = true;
+      image_ctx.notify_update(this);
+    }
+  }
+  virtual void finish(int r) override {
+    on_finish->complete(r);
+  }
+};
+
+template <typename I>
+struct C_InvokeAsyncRequest : public Context {
+  /**
+   * @verbatim
+   *
+   *               <start>
+   *                  |
+   *    . . . . . .   |   . . . . . . . . . . . . . . . . . .
+   *    .         .   |   .                                 .
+   *    .         v   v   v                                 .
+   *    .       ACQUIRE_LOCK (skip if exclusive lock        .
+   *    .             |       disabled or has lock)         .
+   *    .             |                                     .
+   *    .   /--------/ \--------\   . . . . . . . . . . . . .
+   *    .   |                   |   .
+   *    .   v                   v   .
+   *  LOCAL_REQUEST       REMOTE_REQUEST
+   *        |                   |
+   *        |                   |
+   *        \--------\ /--------/
+   *                  |
+   *                  v
+   *              <finish>
+   *
+   * @endverbatim
+   */
+
+  I &image_ctx;
+  std::string request_type;
+  bool permit_snapshot;
+  boost::function<void(Context*)> local;
+  boost::function<void(Context*)> remote;
+  std::set<int> filter_error_codes;
+  Context *on_finish;
+
+  C_InvokeAsyncRequest(I &image_ctx, const std::string& request_type,
+                       bool permit_snapshot,
+                       const boost::function<void(Context*)>& local,
+                       const boost::function<void(Context*)>& remote,
+                       const std::set<int> &filter_error_codes,
+                       Context *on_finish)
+    : image_ctx(image_ctx), request_type(request_type),
+      permit_snapshot(permit_snapshot), local(local), remote(remote),
+      filter_error_codes(filter_error_codes), on_finish(on_finish) {
+  }
+
+  void send() {
+    send_acquire_exclusive_lock();
+  }
+
+  void send_acquire_exclusive_lock() {
+    RWLock::RLocker owner_locker(image_ctx.owner_lock);
+    {
+      RWLock::RLocker snap_locker(image_ctx.snap_lock);
+      if (image_ctx.read_only ||
+          (!permit_snapshot && image_ctx.snap_id != CEPH_NOSNAP)) {
+        complete(-EROFS);
+        return;
+      }
+    }
+
+    if (image_ctx.exclusive_lock == nullptr) {
+      send_local_request();
+      return;
+    } else if (image_ctx.image_watcher == nullptr) {
+      complete(-EROFS);
+      return;
+    }
+
+    if (image_ctx.exclusive_lock->is_lock_owner() &&
+        image_ctx.exclusive_lock->accept_requests()) {
+      send_local_request();
+      return;
+    }
+
+    CephContext *cct = image_ctx.cct;
+    ldout(cct, 20) << __func__ << dendl;
+
+    Context *ctx = util::create_context_callback<
+      C_InvokeAsyncRequest<I>,
+      &C_InvokeAsyncRequest<I>::handle_acquire_exclusive_lock>(
+        this);
+    image_ctx.exclusive_lock->try_lock(ctx);
+  }
+
+  void handle_acquire_exclusive_lock(int r) {
+    CephContext *cct = image_ctx.cct;
+    ldout(cct, 20) << __func__ << ": r=" << r << dendl;
+
+    RWLock::RLocker owner_locker(image_ctx.owner_lock);
+    if (r < 0) {
+      complete(-EROFS);
+      return;
+    } else if (image_ctx.exclusive_lock->is_lock_owner()) {
+      send_local_request();
+      return;
+    }
+
+    send_remote_request();
+  }
+
+  void send_remote_request() {
+    assert(image_ctx.owner_lock.is_locked());
+
+    CephContext *cct = image_ctx.cct;
+    ldout(cct, 20) << __func__ << dendl;
+
+    Context *ctx = util::create_context_callback<
+      C_InvokeAsyncRequest<I>, &C_InvokeAsyncRequest<I>::handle_remote_request>(
+        this);
+    remote(ctx);
+  }
+
+  void handle_remote_request(int r) {
+    CephContext *cct = image_ctx.cct;
+    ldout(cct, 20) << __func__ << ": r=" << r << dendl;
+
+    if (r != -ETIMEDOUT && r != -ERESTART) {
+      complete(r);
+      return;
+    }
+
+    ldout(cct, 5) << request_type << " timed out notifying lock owner"
+                  << dendl;
+    send_acquire_exclusive_lock();
+  }
+
+  void send_local_request() {
+    assert(image_ctx.owner_lock.is_locked());
+
+    CephContext *cct = image_ctx.cct;
+    ldout(cct, 20) << __func__ << dendl;
+
+    Context *ctx = util::create_context_callback<
+      C_InvokeAsyncRequest<I>, &C_InvokeAsyncRequest<I>::handle_local_request>(
+        this);
+    local(ctx);
+  }
+
+  void handle_local_request(int r) {
+    CephContext *cct = image_ctx.cct;
+    ldout(cct, 20) << __func__ << ": r=" << r << dendl;
+
+    if (r == -ERESTART) {
+      send_acquire_exclusive_lock();
+      return;
+    }
+    complete(r);
+  }
+
+  virtual void finish(int r) override {
+    if (filter_error_codes.count(r) != 0) {
+      r = 0;
+    }
+    on_finish->complete(r);
+  }
+};
+
+} // anonymous namespace
+
 template <typename I>
-Operations<I>::Operations(I &image_ctx) : m_image_ctx(image_ctx) {
+Operations<I>::Operations(I &image_ctx)
+  : m_image_ctx(image_ctx), m_async_request_seq(0) {
 }
 
 template <typename I>
@@ -52,25 +240,24 @@ int Operations<I>::flatten(ProgressContext &prog_ctx) {
     }
   }
 
-  uint64_t request_id = m_async_request_seq.inc();
+  uint64_t request_id = ++m_async_request_seq;
   r = invoke_async_request("flatten", false,
-                           boost::bind(&Operations<I>::flatten, this,
+                           boost::bind(&Operations<I>::execute_flatten, this,
                                        boost::ref(prog_ctx), _1),
                            boost::bind(&ImageWatcher::notify_flatten,
                                        m_image_ctx.image_watcher, request_id,
-                                       boost::ref(prog_ctx)));
+                                       boost::ref(prog_ctx), _1));
 
   if (r < 0 && r != -EINVAL) {
     return r;
   }
-
-  notify_change();
   ldout(cct, 20) << "flatten finished" << dendl;
   return 0;
 }
 
 template <typename I>
-void Operations<I>::flatten(ProgressContext &prog_ctx, Context *on_finish) {
+void Operations<I>::execute_flatten(ProgressContext &prog_ctx,
+                                    Context *on_finish) {
   assert(m_image_ctx.owner_lock.is_locked());
   assert(m_image_ctx.exclusive_lock == nullptr ||
          m_image_ctx.exclusive_lock->is_lock_owner());
@@ -115,7 +302,8 @@ void Operations<I>::flatten(ProgressContext &prog_ctx, Context *on_finish) {
   }
 
   operation::FlattenRequest<I> *req = new operation::FlattenRequest<I>(
-    m_image_ctx, on_finish, object_size, overlap_objects, snapc, prog_ctx);
+    m_image_ctx, new C_NotifyUpdate<I>(m_image_ctx, on_finish), object_size,
+    overlap_objects, snapc, prog_ctx);
   req->send();
 }
 
@@ -129,26 +317,24 @@ int Operations<I>::rebuild_object_map(ProgressContext &prog_ctx) {
     return r;
   }
 
-  uint64_t request_id = m_async_request_seq.inc();
+  uint64_t request_id = ++m_async_request_seq;
   r = invoke_async_request("rebuild object map", true,
-                           boost::bind(&Operations<I>::rebuild_object_map, this,
-                                       boost::ref(prog_ctx), _1),
+                           boost::bind(&Operations<I>::execute_rebuild_object_map,
+                                       this, boost::ref(prog_ctx), _1),
                            boost::bind(&ImageWatcher::notify_rebuild_object_map,
                                        m_image_ctx.image_watcher, request_id,
-                                       boost::ref(prog_ctx)));
+                                       boost::ref(prog_ctx), _1));
 
   ldout(cct, 10) << "rebuild object map finished" << dendl;
   if (r < 0) {
     return r;
   }
-
-  notify_change();
   return 0;
 }
 
 template <typename I>
-void Operations<I>::rebuild_object_map(ProgressContext &prog_ctx,
-                                       Context *on_finish) {
+void Operations<I>::execute_rebuild_object_map(ProgressContext &prog_ctx,
+                                               Context *on_finish) {
   assert(m_image_ctx.owner_lock.is_locked());
   assert(m_image_ctx.exclusive_lock == nullptr ||
          m_image_ctx.exclusive_lock->is_lock_owner());
@@ -166,7 +352,8 @@ void Operations<I>::rebuild_object_map(ProgressContext &prog_ctx,
   }
 
   operation::RebuildObjectMapRequest<I> *req =
-    new operation::RebuildObjectMapRequest<I>(m_image_ctx, on_finish, prog_ctx);
+    new operation::RebuildObjectMapRequest<I>(
+      m_image_ctx, new C_NotifyUpdate<I>(m_image_ctx, on_finish), prog_ctx);
   req->send();
 }
 
@@ -189,17 +376,18 @@ int Operations<I>::rename(const char *dstname) {
 
   if (m_image_ctx.test_features(RBD_FEATURE_JOURNALING)) {
     r = invoke_async_request("rename", true,
-                             boost::bind(&Operations<I>::rename, this,
+                             boost::bind(&Operations<I>::execute_rename, this,
                                          dstname, _1),
                              boost::bind(&ImageWatcher::notify_rename,
-                                         m_image_ctx.image_watcher, dstname));
+                                         m_image_ctx.image_watcher, dstname,
+                                         _1));
     if (r < 0 && r != -EEXIST) {
       return r;
     }
   } else {
     RWLock::RLocker owner_lock(m_image_ctx.owner_lock);
     C_SaferCond cond_ctx;
-    rename(dstname, &cond_ctx);
+    execute_rename(dstname, &cond_ctx);
 
     r = cond_ctx.wait();
     if (r < 0) {
@@ -207,14 +395,12 @@ int Operations<I>::rename(const char *dstname) {
     }
   }
 
-  if (m_image_ctx.old_format) {
-    notify_change();
-  }
+  m_image_ctx.set_image_name(dstname);
   return 0;
 }
 
 template <typename I>
-void Operations<I>::rename(const char *dstname, Context *on_finish) {
+void Operations<I>::execute_rename(const char *dstname, Context *on_finish) {
   assert(m_image_ctx.owner_lock.is_locked());
   if (m_image_ctx.test_features(RBD_FEATURE_JOURNALING)) {
     assert(m_image_ctx.exclusive_lock == nullptr ||
@@ -225,8 +411,11 @@ void Operations<I>::rename(const char *dstname, Context *on_finish) {
   ldout(cct, 5) << this << " " << __func__ << ": dest_name=" << dstname
                 << dendl;
 
-  operation::RenameRequest<I> *req =
-    new operation::RenameRequest<I>(m_image_ctx, on_finish, dstname);
+  if (m_image_ctx.old_format) {
+    on_finish = new C_NotifyUpdate<I>(m_image_ctx, on_finish);
+  }
+  operation::RenameRequest<I> *req = new operation::RenameRequest<I>(
+    m_image_ctx, on_finish, dstname);
   req->send();
 }
 
@@ -245,23 +434,23 @@ int Operations<I>::resize(uint64_t size, ProgressContext& prog_ctx) {
     return r;
   }
 
-  uint64_t request_id = m_async_request_seq.inc();
+  uint64_t request_id = ++m_async_request_seq;
   r = invoke_async_request("resize", false,
-                           boost::bind(&Operations<I>::resize, this,
+                           boost::bind(&Operations<I>::execute_resize, this,
                                        size, boost::ref(prog_ctx), _1, 0),
                            boost::bind(&ImageWatcher::notify_resize,
                                        m_image_ctx.image_watcher, request_id,
-                                       size, boost::ref(prog_ctx)));
+                                       size, boost::ref(prog_ctx), _1));
 
   m_image_ctx.perfcounter->inc(l_librbd_resize);
-  notify_change();
   ldout(cct, 2) << "resize finished" << dendl;
   return r;
 }
 
 template <typename I>
-void Operations<I>::resize(uint64_t size, ProgressContext &prog_ctx,
-                           Context *on_finish, uint64_t journal_op_tid) {
+void Operations<I>::execute_resize(uint64_t size, ProgressContext &prog_ctx,
+                                   Context *on_finish,
+                                   uint64_t journal_op_tid) {
   assert(m_image_ctx.owner_lock.is_locked());
   assert(m_image_ctx.exclusive_lock == nullptr ||
          m_image_ctx.exclusive_lock->is_lock_owner());
@@ -282,48 +471,66 @@ void Operations<I>::resize(uint64_t size, ProgressContext &prog_ctx,
   }
 
   operation::ResizeRequest<I> *req = new operation::ResizeRequest<I>(
-    m_image_ctx, on_finish, size, prog_ctx, journal_op_tid, false);
+    m_image_ctx, new C_NotifyUpdate<I>(m_image_ctx, on_finish), size, prog_ctx,
+    journal_op_tid, false);
   req->send();
 }
 
 template <typename I>
 int Operations<I>::snap_create(const char *snap_name) {
-  CephContext *cct = m_image_ctx.cct;
-  ldout(cct, 5) << this << " " << __func__ << ": snap_name=" << snap_name
-                << dendl;
-
   if (m_image_ctx.read_only) {
     return -EROFS;
   }
 
   int r = m_image_ctx.state->refresh_if_required();
-  if (r < 0)
+  if (r < 0) {
     return r;
-
-  {
-    RWLock::RLocker l(m_image_ctx.snap_lock);
-    if (m_image_ctx.get_snap_id(snap_name) != CEPH_NOSNAP) {
-      return -EEXIST;
-    }
   }
 
-  r = invoke_async_request("snap_create", true,
-                           boost::bind(&Operations<I>::snap_create, this,
-                                       snap_name, _1, 0),
-                           boost::bind(&ImageWatcher::notify_snap_create,
-                                       m_image_ctx.image_watcher, snap_name));
-  if (r < 0 && r != -EEXIST) {
+  C_SaferCond ctx;
+  snap_create(snap_name, &ctx);
+  r = ctx.wait();
+
+  if (r < 0) {
     return r;
   }
 
   m_image_ctx.perfcounter->inc(l_librbd_snap_create);
-  notify_change();
-  return 0;
+  return r;
+}
+
+template <typename I>
+void Operations<I>::snap_create(const char *snap_name, Context *on_finish) {
+  CephContext *cct = m_image_ctx.cct;
+  ldout(cct, 5) << this << " " << __func__ << ": snap_name=" << snap_name
+                << dendl;
+
+  if (m_image_ctx.read_only) {
+    on_finish->complete(-EROFS);
+    return;
+  }
+
+  {
+    RWLock::RLocker snap_locker(m_image_ctx.snap_lock);
+    if (m_image_ctx.get_snap_id(snap_name) != CEPH_NOSNAP) {
+      on_finish->complete(-EEXIST);
+      return;
+    }
+  }
+
+  C_InvokeAsyncRequest<I> *req = new C_InvokeAsyncRequest<I>(
+    m_image_ctx, "snap_create", true,
+    boost::bind(&Operations<I>::execute_snap_create, this, snap_name, _1, 0),
+    boost::bind(&ImageWatcher::notify_snap_create, m_image_ctx.image_watcher,
+                snap_name, _1),
+    {-EEXIST}, on_finish);
+  req->send();
 }
 
 template <typename I>
-void Operations<I>::snap_create(const char *snap_name, Context *on_finish,
-                                uint64_t journal_op_tid) {
+void Operations<I>::execute_snap_create(const char *snap_name,
+                                        Context *on_finish,
+                                        uint64_t journal_op_tid) {
   assert(m_image_ctx.owner_lock.is_locked());
   assert(m_image_ctx.exclusive_lock == nullptr ||
          m_image_ctx.exclusive_lock->is_lock_owner());
@@ -333,8 +540,9 @@ void Operations<I>::snap_create(const char *snap_name, Context *on_finish,
                 << dendl;
 
   operation::SnapshotCreateRequest<I> *req =
-    new operation::SnapshotCreateRequest<I>(m_image_ctx, on_finish, snap_name,
-                                            journal_op_tid);
+    new operation::SnapshotCreateRequest<I>(
+      m_image_ctx, new C_NotifyUpdate<I>(m_image_ctx, on_finish), snap_name,
+      journal_op_tid);
   req->send();
 }
 
@@ -378,21 +586,20 @@ int Operations<I>::snap_rollback(const char *snap_name,
   }
 
   C_SaferCond cond_ctx;
-  snap_rollback(snap_name, prog_ctx, &cond_ctx);
+  execute_snap_rollback(snap_name, prog_ctx, &cond_ctx);
   r = cond_ctx.wait();
   if (r < 0) {
     return r;
   }
 
   m_image_ctx.perfcounter->inc(l_librbd_snap_rollback);
-  notify_change();
   return r;
 }
 
 template <typename I>
-void Operations<I>::snap_rollback(const char *snap_name,
-                                  ProgressContext& prog_ctx,
-                                  Context *on_finish) {
+void Operations<I>::execute_snap_rollback(const char *snap_name,
+                                          ProgressContext& prog_ctx,
+                                          Context *on_finish) {
   assert(m_image_ctx.owner_lock.is_locked());
   CephContext *cct = m_image_ctx.cct;
   ldout(cct, 5) << this << " " << __func__ << ": snap_name=" << snap_name
@@ -414,61 +621,74 @@ void Operations<I>::snap_rollback(const char *snap_name,
 
   // async mode used for journal replay
   operation::SnapshotRollbackRequest<I> *request =
-    new operation::SnapshotRollbackRequest<I>(m_image_ctx, on_finish, snap_name,
-                                              snap_id, new_size, prog_ctx);
+    new operation::SnapshotRollbackRequest<I>(
+      m_image_ctx, new C_NotifyUpdate<I>(m_image_ctx, on_finish), snap_name,
+      snap_id, new_size, prog_ctx);
   request->send();
 }
 
 template <typename I>
 int Operations<I>::snap_remove(const char *snap_name) {
-  CephContext *cct = m_image_ctx.cct;
-  ldout(cct, 5) << this << " " << __func__ << ": snap_name=" << snap_name
-                << dendl;
-
-  if (m_image_ctx.read_only)
+  if (m_image_ctx.read_only) {
     return -EROFS;
+  }
 
   int r = m_image_ctx.state->refresh_if_required();
-  if (r < 0)
+  if (r < 0) {
+    return r;
+  }
+
+  C_SaferCond ctx;
+  snap_remove(snap_name, &ctx);
+  r = ctx.wait();
+
+  if (r < 0) {
     return r;
+  }
+
+  m_image_ctx.perfcounter->inc(l_librbd_snap_remove);
+  return 0;
+}
+
+template <typename I>
+void Operations<I>::snap_remove(const char *snap_name, Context *on_finish) {
+  CephContext *cct = m_image_ctx.cct;
+  ldout(cct, 5) << this << " " << __func__ << ": snap_name=" << snap_name
+                << dendl;
+
+  if (m_image_ctx.read_only) {
+    on_finish->complete(-EROFS);
+    return;
+  }
 
   bool proxy_op = false;
   {
     RWLock::RLocker snap_locker(m_image_ctx.snap_lock);
     if (m_image_ctx.get_snap_id(snap_name) == CEPH_NOSNAP) {
-      return -ENOENT;
+      on_finish->complete(-ENOENT);
+      return;
     }
     proxy_op = ((m_image_ctx.features & RBD_FEATURE_FAST_DIFF) != 0 ||
                 (m_image_ctx.features & RBD_FEATURE_JOURNALING) != 0);
   }
 
   if (proxy_op) {
-    r = invoke_async_request("snap_remove", true,
-                             boost::bind(&Operations<I>::snap_remove, this,
-                                         snap_name, _1),
-                             boost::bind(&ImageWatcher::notify_snap_remove,
-                                         m_image_ctx.image_watcher, snap_name));
-    if (r < 0 && r != -ENOENT) {
-      return r;
-    }
+    C_InvokeAsyncRequest<I> *req = new C_InvokeAsyncRequest<I>(
+      m_image_ctx, "snap_remove", true,
+      boost::bind(&Operations<I>::execute_snap_remove, this, snap_name, _1),
+      boost::bind(&ImageWatcher::notify_snap_remove, m_image_ctx.image_watcher,
+                  snap_name, _1),
+      {-ENOENT}, on_finish);
+    req->send();
   } else {
     RWLock::RLocker owner_lock(m_image_ctx.owner_lock);
-    C_SaferCond cond_ctx;
-    snap_remove(snap_name, &cond_ctx);
-
-    r = cond_ctx.wait();
-    if (r < 0) {
-      return r;
-    }
+    execute_snap_remove(snap_name, on_finish);
   }
-
-  m_image_ctx.perfcounter->inc(l_librbd_snap_remove);
-  notify_change();
-  return 0;
 }
 
 template <typename I>
-void Operations<I>::snap_remove(const char *snap_name, Context *on_finish) {
+void Operations<I>::execute_snap_remove(const char *snap_name,
+                                        Context *on_finish) {
   assert(m_image_ctx.owner_lock.is_locked());
   {
     if ((m_image_ctx.features & RBD_FEATURE_FAST_DIFF) != 0) {
@@ -504,8 +724,9 @@ void Operations<I>::snap_remove(const char *snap_name, Context *on_finish) {
   }
 
   operation::SnapshotRemoveRequest<I> *req =
-    new operation::SnapshotRemoveRequest<I>(m_image_ctx, on_finish, snap_name,
-                                            snap_id);
+    new operation::SnapshotRemoveRequest<I>(
+      m_image_ctx, new C_NotifyUpdate<I>(m_image_ctx, on_finish), snap_name,
+      snap_id);
   req->send();
 }
 
@@ -538,18 +759,18 @@ int Operations<I>::snap_rename(const char *srcname, const char *dstname) {
 
   if (m_image_ctx.test_features(RBD_FEATURE_JOURNALING)) {
     r = invoke_async_request("snap_rename", true,
-                             boost::bind(&Operations<I>::snap_rename, this,
-                                         snap_id, dstname, _1),
+                             boost::bind(&Operations<I>::execute_snap_rename,
+                                         this, snap_id, dstname, _1),
                              boost::bind(&ImageWatcher::notify_snap_rename,
                                          m_image_ctx.image_watcher, snap_id,
-                                         dstname));
+                                         dstname, _1));
     if (r < 0 && r != -EEXIST) {
       return r;
     }
   } else {
     RWLock::RLocker owner_lock(m_image_ctx.owner_lock);
     C_SaferCond cond_ctx;
-    snap_rename(snap_id, dstname, &cond_ctx);
+    execute_snap_rename(snap_id, dstname, &cond_ctx);
 
     r = cond_ctx.wait();
     if (r < 0) {
@@ -558,13 +779,13 @@ int Operations<I>::snap_rename(const char *srcname, const char *dstname) {
   }
 
   m_image_ctx.perfcounter->inc(l_librbd_snap_rename);
-  notify_change();
   return 0;
 }
 
 template <typename I>
-void Operations<I>::snap_rename(const uint64_t src_snap_id,
-                                const char *dst_name, Context *on_finish) {
+void Operations<I>::execute_snap_rename(const uint64_t src_snap_id,
+                                        const char *dst_name,
+                                        Context *on_finish) {
   assert(m_image_ctx.owner_lock.is_locked());
   if ((m_image_ctx.features & RBD_FEATURE_JOURNALING) != 0) {
     assert(m_image_ctx.exclusive_lock == nullptr ||
@@ -577,8 +798,9 @@ void Operations<I>::snap_rename(const uint64_t src_snap_id,
                 << "new_snap_name=" << dst_name << dendl;
 
   operation::SnapshotRenameRequest<I> *req =
-    new operation::SnapshotRenameRequest<I>(m_image_ctx, on_finish, src_snap_id,
-                                            dst_name);
+    new operation::SnapshotRenameRequest<I>(
+      m_image_ctx, new C_NotifyUpdate<I>(m_image_ctx, on_finish), src_snap_id,
+      dst_name);
   req->send();
 }
 
@@ -613,30 +835,30 @@ int Operations<I>::snap_protect(const char *snap_name) {
 
   if (m_image_ctx.test_features(RBD_FEATURE_JOURNALING)) {
     r = invoke_async_request("snap_protect", true,
-                             boost::bind(&Operations<I>::snap_protect, this,
-                                         snap_name, _1),
+                             boost::bind(&Operations<I>::execute_snap_protect,
+                                         this, snap_name, _1),
                              boost::bind(&ImageWatcher::notify_snap_protect,
-                                         m_image_ctx.image_watcher, snap_name));
+                                         m_image_ctx.image_watcher, snap_name,
+                                         _1));
     if (r < 0 && r != -EBUSY) {
       return r;
     }
   } else {
     RWLock::RLocker owner_lock(m_image_ctx.owner_lock);
     C_SaferCond cond_ctx;
-    snap_protect(snap_name, &cond_ctx);
+    execute_snap_protect(snap_name, &cond_ctx);
 
     r = cond_ctx.wait();
     if (r < 0) {
       return r;
     }
   }
-
-  notify_change();
   return 0;
 }
 
 template <typename I>
-void Operations<I>::snap_protect(const char *snap_name, Context *on_finish) {
+void Operations<I>::execute_snap_protect(const char *snap_name,
+                                         Context *on_finish) {
   assert(m_image_ctx.owner_lock.is_locked());
   if (m_image_ctx.test_features(RBD_FEATURE_JOURNALING)) {
     assert(m_image_ctx.exclusive_lock == nullptr ||
@@ -648,7 +870,8 @@ void Operations<I>::snap_protect(const char *snap_name, Context *on_finish) {
                 << dendl;
 
   operation::SnapshotProtectRequest<I> *request =
-    new operation::SnapshotProtectRequest<I>(m_image_ctx, on_finish, snap_name);
+    new operation::SnapshotProtectRequest<I>(
+      m_image_ctx, new C_NotifyUpdate<I>(m_image_ctx, on_finish), snap_name);
   request->send();
 }
 
@@ -683,30 +906,30 @@ int Operations<I>::snap_unprotect(const char *snap_name) {
 
   if (m_image_ctx.test_features(RBD_FEATURE_JOURNALING)) {
     r = invoke_async_request("snap_unprotect", true,
-                             boost::bind(&Operations<I>::snap_unprotect, this,
-                                         snap_name, _1),
+                             boost::bind(&Operations<I>::execute_snap_unprotect,
+                                         this, snap_name, _1),
                              boost::bind(&ImageWatcher::notify_snap_unprotect,
-                                         m_image_ctx.image_watcher, snap_name));
+                                         m_image_ctx.image_watcher, snap_name,
+                                         _1));
     if (r < 0 && r != -EINVAL) {
       return r;
     }
   } else {
     RWLock::RLocker owner_lock(m_image_ctx.owner_lock);
     C_SaferCond cond_ctx;
-    snap_unprotect(snap_name, &cond_ctx);
+    execute_snap_unprotect(snap_name, &cond_ctx);
 
     r = cond_ctx.wait();
     if (r < 0) {
       return r;
     }
   }
-
-  notify_change();
   return 0;
 }
 
 template <typename I>
-void Operations<I>::snap_unprotect(const char *snap_name, Context *on_finish) {
+void Operations<I>::execute_snap_unprotect(const char *snap_name,
+                                           Context *on_finish) {
   assert(m_image_ctx.owner_lock.is_locked());
   if (m_image_ctx.test_features(RBD_FEATURE_JOURNALING)) {
     assert(m_image_ctx.exclusive_lock == nullptr ||
@@ -718,8 +941,8 @@ void Operations<I>::snap_unprotect(const char *snap_name, Context *on_finish) {
                 << dendl;
 
   operation::SnapshotUnprotectRequest<I> *request =
-    new operation::SnapshotUnprotectRequest<I>(m_image_ctx, on_finish,
-                                               snap_name);
+    new operation::SnapshotUnprotectRequest<I>(
+      m_image_ctx, new C_NotifyUpdate<I>(m_image_ctx, on_finish), snap_name);
   request->send();
 }
 
@@ -758,53 +981,16 @@ template <typename I>
 int Operations<I>::invoke_async_request(const std::string& request_type,
                                         bool permit_snapshot,
                                         const boost::function<void(Context*)>& local_request,
-                                        const boost::function<int()>& remote_request) {
-  CephContext *cct = m_image_ctx.cct;
-  int r;
-  do {
-    C_SaferCond ctx;
-    {
-      RWLock::RLocker owner_locker(m_image_ctx.owner_lock);
-      {
-        RWLock::RLocker snap_locker(m_image_ctx.snap_lock);
-        if (m_image_ctx.read_only ||
-            (!permit_snapshot && m_image_ctx.snap_id != CEPH_NOSNAP)) {
-          return -EROFS;
-        }
-      }
-
-      while (m_image_ctx.exclusive_lock != nullptr) {
-        r = prepare_image_update();
-        if (r < 0) {
-          return -EROFS;
-        } else if (m_image_ctx.exclusive_lock->is_lock_owner()) {
-          break;
-        }
-
-        r = remote_request();
-        if (r != -ETIMEDOUT && r != -ERESTART) {
-          return r;
-        }
-        ldout(cct, 5) << request_type << " timed out notifying lock owner"
-                      << dendl;
-      }
-
-      local_request(&ctx);
-    }
-
-    r = ctx.wait();
-    if (r == -ERESTART) {
-      ldout(cct, 5) << request_type << " interrupted: restarting" << dendl;
-    }
-  } while (r == -ERESTART);
-  return r;
-}
-
-template <typename I>
-void Operations<I>::notify_change() {
-  m_image_ctx.state->handle_update_notification();
-  ImageWatcher::notify_header_update(m_image_ctx.md_ctx,
-                                     m_image_ctx.header_oid);
+                                        const boost::function<void(Context*)>& remote_request) {
+  C_SaferCond ctx;
+  C_InvokeAsyncRequest<I> *req = new C_InvokeAsyncRequest<I>(m_image_ctx,
+                                                             request_type,
+                                                             permit_snapshot,
+                                                             local_request,
+                                                             remote_request,
+                                                             {}, &ctx);
+  req->send();
+  return ctx.wait();
 }
 
 } // namespace librbd
diff --git a/src/librbd/Operations.h b/src/librbd/Operations.h
index 70eefde..a32116a 100644
--- a/src/librbd/Operations.h
+++ b/src/librbd/Operations.h
@@ -5,7 +5,7 @@
 #define CEPH_LIBRBD_OPERATIONS_H
 
 #include "include/int_types.h"
-#include "include/atomic.h"
+#include <atomic>
 #include <string>
 #include <boost/function.hpp>
 
@@ -22,50 +22,52 @@ public:
   Operations(ImageCtxT &image_ctx);
 
   int flatten(ProgressContext &prog_ctx);
-  void flatten(ProgressContext &prog_ctx, Context *on_finish);
+  void execute_flatten(ProgressContext &prog_ctx, Context *on_finish);
 
   int rebuild_object_map(ProgressContext &prog_ctx);
-  void rebuild_object_map(ProgressContext &prog_ctx, Context *on_finish);
+  void execute_rebuild_object_map(ProgressContext &prog_ctx,
+                                  Context *on_finish);
 
   int rename(const char *dstname);
-  void rename(const char *dstname, Context *on_finish);
+  void execute_rename(const char *dstname, Context *on_finish);
 
   int resize(uint64_t size, ProgressContext& prog_ctx);
-  void resize(uint64_t size, ProgressContext &prog_ctx, Context *on_finish,
-              uint64_t journal_op_tid);
+  void execute_resize(uint64_t size, ProgressContext &prog_ctx,
+                      Context *on_finish, uint64_t journal_op_tid);
 
   int snap_create(const char *snap_name);
-  void snap_create(const char *snap_name, Context *on_finish,
-                   uint64_t journal_op_tid);
+  void snap_create(const char *snap_name, Context *on_finish);
+  void execute_snap_create(const char *snap_name, Context *on_finish,
+                           uint64_t journal_op_tid);
 
   int snap_rollback(const char *snap_name, ProgressContext& prog_ctx);
-  void snap_rollback(const char *snap_name, ProgressContext& prog_ctx,
-                     Context *on_finish);
+  void execute_snap_rollback(const char *snap_name, ProgressContext& prog_ctx,
+                             Context *on_finish);
 
   int snap_remove(const char *snap_name);
   void snap_remove(const char *snap_name, Context *on_finish);
+  void execute_snap_remove(const char *snap_name, Context *on_finish);
 
   int snap_rename(const char *srcname, const char *dstname);
-  void snap_rename(const uint64_t src_snap_id, const char *dst_name,
-                   Context *on_finish);
+  void execute_snap_rename(const uint64_t src_snap_id, const char *dst_name,
+                           Context *on_finish);
 
   int snap_protect(const char *snap_name);
-  void snap_protect(const char *snap_name, Context *on_finish);
+  void execute_snap_protect(const char *snap_name, Context *on_finish);
 
   int snap_unprotect(const char *snap_name);
-  void snap_unprotect(const char *snap_name, Context *on_finish);
+  void execute_snap_unprotect(const char *snap_name, Context *on_finish);
 
   int prepare_image_update();
 
 private:
   ImageCtxT &m_image_ctx;
-  atomic_t m_async_request_seq;
+  std::atomic<int> m_async_request_seq;
 
   int invoke_async_request(const std::string& request_type,
                            bool permit_snapshot,
-                           const boost::function<void(Context*)>& local_request,
-                           const boost::function<int()>& remote_request);
-  void notify_change();
+                           const boost::function<void(Context*)>& local,
+                           const boost::function<void(Context*)>& remote);
 };
 
 } // namespace librbd
diff --git a/src/librbd/TaskFinisher.h b/src/librbd/TaskFinisher.h
index 8d37a04..201ff01 100644
--- a/src/librbd/TaskFinisher.h
+++ b/src/librbd/TaskFinisher.h
@@ -19,10 +19,10 @@ namespace librbd {
 template <typename Task>
 class TaskFinisher {
 public:
-  TaskFinisher(CephContext *cct)
+  TaskFinisher(CephContext &cct)
     : m_cct(cct), m_lock("librbd::TaskFinisher::m_lock"),
-      m_finisher(new Finisher(cct)),
-      m_safe_timer(new SafeTimer(cct, m_lock, false))
+      m_finisher(new Finisher(&cct)),
+      m_safe_timer(new SafeTimer(&cct, m_lock, false))
   {
     m_finisher->start();
     m_safe_timer->init();
@@ -112,7 +112,7 @@ private:
     Task m_task;
   };
 
-  CephContext *m_cct;
+  CephContext &m_cct;
 
   Mutex m_lock;
   Finisher *m_finisher;
diff --git a/src/librbd/Utils.cc b/src/librbd/Utils.cc
index d89418f..3d73830 100644
--- a/src/librbd/Utils.cc
+++ b/src/librbd/Utils.cc
@@ -27,5 +27,9 @@ std::string unique_lock_name(const std::string &name, void *address) {
   return name + " (" + stringify(address) + ")";
 }
 
+librados::AioCompletion *create_rados_ack_callback(Context *on_finish) {
+  return create_rados_ack_callback<Context, &Context::complete>(on_finish);
+}
+
 } // namespace util
 } // namespace librbd
diff --git a/src/librbd/Utils.h b/src/librbd/Utils.h
index 0986f06..fd881f6 100644
--- a/src/librbd/Utils.h
+++ b/src/librbd/Utils.h
@@ -23,6 +23,13 @@ void rados_callback(rados_completion_t c, void *arg) {
   reinterpret_cast<T*>(arg)->complete(rados_aio_get_return_value(c));
 }
 
+template <typename T, void(T::*MF)(int)>
+void rados_callback(rados_completion_t c, void *arg) {
+  T *obj = reinterpret_cast<T*>(arg);
+  int r = rados_aio_get_return_value(c);
+  (obj->*MF)(r);
+}
+
 template <typename T, Context*(T::*MF)(int*), bool destroy>
 void rados_state_callback(rados_completion_t c, void *arg) {
   T *obj = reinterpret_cast<T*>(arg);
@@ -91,12 +98,20 @@ const std::string header_name(const std::string &image_id);
 const std::string old_header_name(const std::string &image_name);
 std::string unique_lock_name(const std::string &name, void *address);
 
+librados::AioCompletion *create_rados_ack_callback(Context *on_finish);
+
 template <typename T>
 librados::AioCompletion *create_rados_ack_callback(T *obj) {
   return librados::Rados::aio_create_completion(
     obj, &detail::rados_callback<T>, nullptr);
 }
 
+template <typename T, void(T::*MF)(int)>
+librados::AioCompletion *create_rados_ack_callback(T *obj) {
+  return librados::Rados::aio_create_completion(
+    obj, &detail::rados_callback<T, MF>, nullptr);
+}
+
 template <typename T, Context*(T::*MF)(int*), bool destroy=true>
 librados::AioCompletion *create_rados_ack_callback(T *obj) {
   return librados::Rados::aio_create_completion(
@@ -109,6 +124,12 @@ librados::AioCompletion *create_rados_safe_callback(T *obj) {
     obj, nullptr, &detail::rados_callback<T>);
 }
 
+template <typename T, void(T::*MF)(int)>
+librados::AioCompletion *create_rados_safe_callback(T *obj) {
+  return librados::Rados::aio_create_completion(
+    obj, nullptr, &detail::rados_callback<T, MF>);
+}
+
 template <typename T, Context*(T::*MF)(int*), bool destroy=true>
 librados::AioCompletion *create_rados_safe_callback(T *obj) {
   return librados::Rados::aio_create_completion(
diff --git a/src/librbd/WatchNotifyTypes.cc b/src/librbd/WatchNotifyTypes.cc
index f3a6f4b..a40cdc7 100644
--- a/src/librbd/WatchNotifyTypes.cc
+++ b/src/librbd/WatchNotifyTypes.cc
@@ -11,6 +11,14 @@ namespace watch_notify {
 
 namespace {
 
+class CheckForRefreshVisitor  : public boost::static_visitor<bool> {
+public:
+  template <typename Payload>
+  inline bool operator()(const Payload &payload) const {
+    return Payload::CHECK_FOR_REFRESH;
+  }
+};
+
 class EncodePayloadVisitor : public boost::static_visitor<void> {
 public:
   explicit EncodePayloadVisitor(bufferlist &bl) : m_bl(bl) {}
@@ -257,6 +265,10 @@ void UnknownPayload::decode(__u8 version, bufferlist::iterator &iter) {
 void UnknownPayload::dump(Formatter *f) const {
 }
 
+bool NotifyMessage::check_for_refresh() const {
+  return boost::apply_visitor(CheckForRefreshVisitor(), payload);
+}
+
 void NotifyMessage::encode(bufferlist& bl) const {
   ENCODE_START(2, 1, bl);
   boost::apply_visitor(EncodePayloadVisitor(bl), payload);
diff --git a/src/librbd/WatchNotifyTypes.h b/src/librbd/WatchNotifyTypes.h
index 468b45a..a587b23 100644
--- a/src/librbd/WatchNotifyTypes.h
+++ b/src/librbd/WatchNotifyTypes.h
@@ -92,6 +92,7 @@ enum NotifyOp {
 
 struct AcquiredLockPayload {
   static const NotifyOp NOTIFY_OP = NOTIFY_OP_ACQUIRED_LOCK;
+  static const bool CHECK_FOR_REFRESH = true;
 
   ClientId client_id;
 
@@ -105,6 +106,7 @@ struct AcquiredLockPayload {
 
 struct ReleasedLockPayload {
   static const NotifyOp NOTIFY_OP = NOTIFY_OP_RELEASED_LOCK;
+  static const bool CHECK_FOR_REFRESH = true;
 
   ClientId client_id;
 
@@ -118,6 +120,7 @@ struct ReleasedLockPayload {
 
 struct RequestLockPayload {
   static const NotifyOp NOTIFY_OP = NOTIFY_OP_REQUEST_LOCK;
+  static const bool CHECK_FOR_REFRESH = true;
 
   ClientId client_id;
 
@@ -131,6 +134,7 @@ struct RequestLockPayload {
 
 struct HeaderUpdatePayload {
   static const NotifyOp NOTIFY_OP = NOTIFY_OP_HEADER_UPDATE;
+  static const bool CHECK_FOR_REFRESH = false;
 
   void encode(bufferlist &bl) const;
   void decode(__u8 version, bufferlist::iterator &iter);
@@ -152,6 +156,7 @@ protected:
 
 struct AsyncProgressPayload : public AsyncRequestPayloadBase {
   static const NotifyOp NOTIFY_OP = NOTIFY_OP_ASYNC_PROGRESS;
+  static const bool CHECK_FOR_REFRESH = false;
 
   AsyncProgressPayload() : offset(0), total(0) {}
   AsyncProgressPayload(const AsyncRequestId &id, uint64_t offset_, uint64_t total_)
@@ -167,6 +172,7 @@ struct AsyncProgressPayload : public AsyncRequestPayloadBase {
 
 struct AsyncCompletePayload : public AsyncRequestPayloadBase {
   static const NotifyOp NOTIFY_OP = NOTIFY_OP_ASYNC_COMPLETE;
+  static const bool CHECK_FOR_REFRESH = false;
 
   AsyncCompletePayload() {}
   AsyncCompletePayload(const AsyncRequestId &id, int r)
@@ -181,6 +187,7 @@ struct AsyncCompletePayload : public AsyncRequestPayloadBase {
 
 struct FlattenPayload : public AsyncRequestPayloadBase {
   static const NotifyOp NOTIFY_OP = NOTIFY_OP_FLATTEN;
+  static const bool CHECK_FOR_REFRESH = true;
 
   FlattenPayload() {}
   FlattenPayload(const AsyncRequestId &id) : AsyncRequestPayloadBase(id) {}
@@ -188,6 +195,7 @@ struct FlattenPayload : public AsyncRequestPayloadBase {
 
 struct ResizePayload : public AsyncRequestPayloadBase {
   static const NotifyOp NOTIFY_OP = NOTIFY_OP_RESIZE;
+  static const bool CHECK_FOR_REFRESH = true;
 
   ResizePayload() : size(0) {}
   ResizePayload(uint64_t size_, const AsyncRequestId &id)
@@ -202,6 +210,8 @@ struct ResizePayload : public AsyncRequestPayloadBase {
 
 struct SnapPayloadBase {
 public:
+  static const bool CHECK_FOR_REFRESH = true;
+
   std::string snap_name;
 
   void encode(bufferlist &bl) const;
@@ -257,6 +267,7 @@ struct SnapUnprotectPayload : public SnapPayloadBase {
 
 struct RebuildObjectMapPayload : public AsyncRequestPayloadBase {
   static const NotifyOp NOTIFY_OP = NOTIFY_OP_REBUILD_OBJECT_MAP;
+  static const bool CHECK_FOR_REFRESH = true;
 
   RebuildObjectMapPayload() {}
   RebuildObjectMapPayload(const AsyncRequestId &id)
@@ -265,6 +276,7 @@ struct RebuildObjectMapPayload : public AsyncRequestPayloadBase {
 
 struct RenamePayload {
   static const NotifyOp NOTIFY_OP = NOTIFY_OP_RENAME;
+  static const bool CHECK_FOR_REFRESH = true;
 
   RenamePayload() {}
   RenamePayload(const std::string _image_name) : image_name(_image_name) {}
@@ -278,6 +290,7 @@ struct RenamePayload {
 
 struct UnknownPayload {
   static const NotifyOp NOTIFY_OP = static_cast<NotifyOp>(-1);
+  static const bool CHECK_FOR_REFRESH = false;
 
   void encode(bufferlist &bl) const;
   void decode(__u8 version, bufferlist::iterator &iter);
@@ -307,6 +320,8 @@ struct NotifyMessage {
 
   Payload payload;
 
+  bool check_for_refresh() const;
+
   void encode(bufferlist& bl) const;
   void decode(bufferlist::iterator& it);
   void dump(Formatter *f) const;
diff --git a/src/librbd/exclusive_lock/AcquireRequest.cc b/src/librbd/exclusive_lock/AcquireRequest.cc
index 5f49869..d973bf2 100644
--- a/src/librbd/exclusive_lock/AcquireRequest.cc
+++ b/src/librbd/exclusive_lock/AcquireRequest.cc
@@ -10,6 +10,7 @@
 #include "include/stringify.h"
 #include "librbd/ExclusiveLock.h"
 #include "librbd/ImageCtx.h"
+#include "librbd/ImageWatcher.h"
 #include "librbd/Journal.h"
 #include "librbd/ObjectMap.h"
 #include "librbd/Utils.h"
@@ -73,7 +74,28 @@ AcquireRequest<I>::~AcquireRequest() {
 
 template <typename I>
 void AcquireRequest<I>::send() {
+  send_flush_notifies();
+}
+
+template <typename I>
+void AcquireRequest<I>::send_flush_notifies() {
+  CephContext *cct = m_image_ctx.cct;
+  ldout(cct, 10) << __func__ << dendl;
+
+  using klass = AcquireRequest<I>;
+  Context *ctx = create_context_callback<klass, &klass::handle_flush_notifies>(
+    this);
+  m_image_ctx.image_watcher->flush(ctx);
+}
+
+template <typename I>
+Context *AcquireRequest<I>::handle_flush_notifies(int *ret_val) {
+  CephContext *cct = m_image_ctx.cct;
+  ldout(cct, 10) << __func__ << dendl;
+
+  assert(*ret_val == 0);
   send_lock();
+  return nullptr;
 }
 
 template <typename I>
@@ -144,13 +166,65 @@ Context *AcquireRequest<I>::handle_open_journal(int *ret_val) {
   if (*ret_val < 0) {
     lderr(cct) << "failed to open journal: " << cpp_strerror(*ret_val) << dendl;
     m_error_result = *ret_val;
-    return send_close_object_map();
+    send_close_journal();
+    return nullptr;
   }
 
+  send_allocate_journal_tag();
+  return nullptr;
+}
+
+template <typename I>
+void AcquireRequest<I>::send_allocate_journal_tag() {
+  CephContext *cct = m_image_ctx.cct;
+  ldout(cct, 10) << __func__ << dendl;
+
+  if (!m_journal->is_tag_owner()) {
+    lderr(cct) << "local image not promoted" << dendl;
+    m_error_result = -EPERM;
+    send_close_journal();
+    return;
+  }
+
+  using klass = AcquireRequest<I>;
+  Context *ctx = create_context_callback<
+    klass, &klass::handle_allocate_journal_tag>(this);
+  m_journal->allocate_tag(Journal<I>::LOCAL_MIRROR_UUID, ctx);
+}
+
+template <typename I>
+Context *AcquireRequest<I>::handle_allocate_journal_tag(int *ret_val) {
+  CephContext *cct = m_image_ctx.cct;
+  ldout(cct, 10) << __func__ << ": r=" << *ret_val << dendl;
+
+  if (*ret_val < 0) {
+    m_error_result = *ret_val;
+    send_close_journal();
+    return nullptr;
+  }
   return m_on_finish;
 }
 
 template <typename I>
+void AcquireRequest<I>::send_close_journal() {
+  CephContext *cct = m_image_ctx.cct;
+  ldout(cct, 10) << __func__ << dendl;
+
+  using klass = AcquireRequest<I>;
+  Context *ctx = create_context_callback<klass, &klass::handle_close_journal>(
+    this);
+  m_journal->close(ctx);
+}
+
+template <typename I>
+Context *AcquireRequest<I>::handle_close_journal(int *ret_val) {
+  CephContext *cct = m_image_ctx.cct;
+  ldout(cct, 10) << __func__ << ": r=" << *ret_val << dendl;
+
+  return send_close_object_map(ret_val);
+}
+
+template <typename I>
 Context *AcquireRequest<I>::send_open_object_map() {
   if (!m_image_ctx.test_features(RBD_FEATURE_OBJECT_MAP)) {
     return send_open_journal();
@@ -179,9 +253,9 @@ Context *AcquireRequest<I>::handle_open_object_map(int *ret_val) {
 }
 
 template <typename I>
-Context *AcquireRequest<I>::send_close_object_map() {
+Context *AcquireRequest<I>::send_close_object_map(int *ret_val) {
   if (m_object_map == nullptr) {
-    revert();
+    revert(ret_val);
     return m_on_finish;
   }
 
@@ -202,11 +276,7 @@ Context *AcquireRequest<I>::handle_close_object_map(int *ret_val) {
 
   // object map should never result in an error
   assert(*ret_val == 0);
-
-  assert(m_error_result < 0);
-  *ret_val = m_error_result;
-
-  revert();
+  revert(ret_val);
   return m_on_finish;
 }
 
@@ -417,13 +487,16 @@ void AcquireRequest<I>::apply() {
 }
 
 template <typename I>
-void AcquireRequest<I>::revert() {
+void AcquireRequest<I>::revert(int *ret_val) {
   RWLock::WLocker snap_locker(m_image_ctx.snap_lock);
   m_image_ctx.object_map = nullptr;
   m_image_ctx.journal = nullptr;
 
   delete m_object_map;
   delete m_journal;
+
+  assert(m_error_result < 0);
+  *ret_val = m_error_result;
 }
 
 } // namespace exclusive_lock
diff --git a/src/librbd/exclusive_lock/AcquireRequest.h b/src/librbd/exclusive_lock/AcquireRequest.h
index e3a2525..2c4e05b 100644
--- a/src/librbd/exclusive_lock/AcquireRequest.h
+++ b/src/librbd/exclusive_lock/AcquireRequest.h
@@ -35,25 +35,37 @@ private:
    * @verbatim
    *
    * <start>
-   *    |     /---------------------------------------------------------\
-   *    |     |                                                         |
-   *    |     |             (no lockers)                                |
-   *    |     |   . . . . . . . . . . . . . . . . . . . . .             |
-   *    |     |   .                                       .             |
-   *    |     v   v      (EBUSY)                          .             |
-   *    \--> LOCK_IMAGE * * * * * * * > GET_LOCKERS . . . .             |
-   *          .   |                       |                             |
-   *    . . . .   |                       |                             |
-   *    .         v                       v                             |
-   *    .     OPEN_OBJECT_MAP           GET_WATCHERS . . .              |
-   *    .         |                       |              .              |
-   *    .         v                       v              .              |
-   *    . . > OPEN_JOURNAL * *          BLACKLIST        . (blacklist   |
-   *    .         |          *            |              .  disabled)   |
-   *    .         |          v            v              .              |
-   *    .         | CLOSE_OBJECT_MAP    BREAK_LOCK < . . .              |
-   *    .         v          |            |                             |
-   *    . . > <finish> <-----/            \-----------------------------/
+   *    |
+   *    v
+   * FLUSH_NOTIFIES
+   *    |
+   *    |     /-----------------------------------------------------------\
+   *    |     |                                                           |
+   *    |     |             (no lockers)                                  |
+   *    |     |   . . . . . . . . . . . . . . . . . . . . . .             |
+   *    |     |   .                                         .             |
+   *    |     v   v      (EBUSY)                            .             |
+   *    \--> LOCK_IMAGE * * * * * * * >   GET_LOCKERS . . . .             |
+   *          .   |                         |                             |
+   *    . . . .   |                         |                             |
+   *    .         v                         v                             |
+   *    .     OPEN_OBJECT_MAP             GET_WATCHERS . . .              |
+   *    .         |                         |              .              |
+   *    .         v                         v              .              |
+   *    . . > OPEN_JOURNAL * * * * * *    BLACKLIST        . (blacklist   |
+   *    .         |                  *      |              .  disabled)   |
+   *    .         v                  *      v              .              |
+   *    .     ALLOCATE_JOURNAL_TAG   *    BREAK_LOCK < . . .              |
+   *    .         |            *     *      |                             |
+   *    .         |            *     *      \-----------------------------/
+   *    .         |            v     v
+   *    .         |         CLOSE_JOURNAL
+   *    .         |               |
+   *    .         |               v
+   *    .         |         CLOSE_OBJECT_MAP
+   *    .         |               |
+   *    .         v               |
+   *    . . > <finish> <----------/
    *
    * @endverbatim
    */
@@ -81,16 +93,25 @@ private:
 
   int m_error_result;
 
+  void send_flush_notifies();
+  Context *handle_flush_notifies(int *ret_val);
+
   void send_lock();
   Context *handle_lock(int *ret_val);
 
   Context *send_open_journal();
   Context *handle_open_journal(int *ret_val);
 
+  void send_allocate_journal_tag();
+  Context *handle_allocate_journal_tag(int *ret_val);
+
+  void send_close_journal();
+  Context *handle_close_journal(int *ret_val);
+
   Context *send_open_object_map();
   Context *handle_open_object_map(int *ret_val);
 
-  Context *send_close_object_map();
+  Context *send_close_object_map(int *ret_val);
   Context *handle_close_object_map(int *ret_val);
 
   void send_get_lockers();
@@ -106,7 +127,7 @@ private:
   Context *handle_break_lock(int *ret_val);
 
   void apply();
-  void revert();
+  void revert(int *ret_val);
 };
 
 } // namespace exclusive_lock
diff --git a/src/librbd/exclusive_lock/ReleaseRequest.cc b/src/librbd/exclusive_lock/ReleaseRequest.cc
index a96e97b..356beb1 100644
--- a/src/librbd/exclusive_lock/ReleaseRequest.cc
+++ b/src/librbd/exclusive_lock/ReleaseRequest.cc
@@ -11,6 +11,7 @@
 #include "librbd/AioImageRequestWQ.h"
 #include "librbd/ExclusiveLock.h"
 #include "librbd/ImageCtx.h"
+#include "librbd/ImageWatcher.h"
 #include "librbd/Journal.h"
 #include "librbd/ObjectMap.h"
 #include "librbd/Utils.h"
@@ -63,6 +64,9 @@ void ReleaseRequest<I>::send_block_writes() {
 
   {
     RWLock::RLocker owner_locker(m_image_ctx.owner_lock);
+    if (m_image_ctx.test_features(RBD_FEATURE_JOURNALING)) {
+      m_image_ctx.aio_work_queue->set_require_lock_on_read();
+    }
     m_image_ctx.aio_work_queue->block_writes(ctx);
   }
 }
@@ -105,6 +109,27 @@ Context *ReleaseRequest<I>::handle_cancel_op_requests(int *ret_val) {
     m_on_releasing = nullptr;
   }
 
+  send_flush_notifies();
+  return nullptr;
+}
+
+template <typename I>
+void ReleaseRequest<I>::send_flush_notifies() {
+  CephContext *cct = m_image_ctx.cct;
+  ldout(cct, 10) << __func__ << dendl;
+
+  using klass = ReleaseRequest<I>;
+  Context *ctx = create_context_callback<
+    klass, &klass::handle_flush_notifies>(this);
+  m_image_ctx.image_watcher->flush(ctx);
+}
+
+template <typename I>
+Context *ReleaseRequest<I>::handle_flush_notifies(int *ret_val) {
+  CephContext *cct = m_image_ctx.cct;
+  ldout(cct, 10) << __func__ << dendl;
+
+  assert(*ret_val == 0);
   send_close_journal();
   return nullptr;
 }
diff --git a/src/librbd/exclusive_lock/ReleaseRequest.h b/src/librbd/exclusive_lock/ReleaseRequest.h
index ecb1c21..c5bf91c 100644
--- a/src/librbd/exclusive_lock/ReleaseRequest.h
+++ b/src/librbd/exclusive_lock/ReleaseRequest.h
@@ -36,7 +36,10 @@ private:
    * BLOCK_WRITES
    *    |
    *    v
-   * CANCEL_OP_REQUESTS . . . . . . . . . . . .
+   * CANCEL_OP_REQUESTS
+   *    |
+   *    v
+   * FLUSH_NOTIFIES . . . . . . . . . . . . . .
    *    |                                     .
    *    v                                     .
    * CLOSE_JOURNAL                            .
@@ -70,6 +73,9 @@ private:
   void send_cancel_op_requests();
   Context *handle_cancel_op_requests(int *ret_val);
 
+  void send_flush_notifies();
+  Context *handle_flush_notifies(int *ret_val);
+
   void send_close_journal();
   Context *handle_close_journal(int *ret_val);
 
diff --git a/src/librbd/image/CloseRequest.cc b/src/librbd/image/CloseRequest.cc
index 57f04a7..55e25ab 100644
--- a/src/librbd/image/CloseRequest.cc
+++ b/src/librbd/image/CloseRequest.cc
@@ -21,7 +21,6 @@
 namespace librbd {
 namespace image {
 
-
 using util::create_async_context_callback;
 using util::create_context_callback;
 
@@ -34,18 +33,22 @@ CloseRequest<I>::CloseRequest(I *image_ctx, Context *on_finish)
 
 template <typename I>
 void CloseRequest<I>::send() {
-  // TODO
-  send_shut_down_aio_queue();
-  //send_unregister_image_watcher();
+  send_unregister_image_watcher();
 }
 
 template <typename I>
 void CloseRequest<I>::send_unregister_image_watcher() {
+  if (m_image_ctx->image_watcher == nullptr) {
+    send_shut_down_aio_queue();
+    return;
+  }
+
   CephContext *cct = m_image_ctx->cct;
   ldout(cct, 10) << this << " " << __func__ << dendl;
 
   // prevent incoming requests from our peers
-
+  m_image_ctx->image_watcher->unregister_watch(create_context_callback<
+    CloseRequest<I>, &CloseRequest<I>::handle_unregister_image_watcher>(this));
 }
 
 template <typename I>
@@ -202,7 +205,7 @@ void CloseRequest<I>::handle_flush_op_work_queue(int r) {
 template <typename I>
 void CloseRequest<I>::send_close_parent() {
   if (m_image_ctx->parent == nullptr) {
-    finish();
+    send_flush_image_watcher();
     return;
   }
 
@@ -224,15 +227,35 @@ void CloseRequest<I>::handle_close_parent(int r) {
   if (r < 0) {
     lderr(cct) << "error closing parent image: " << cpp_strerror(r) << dendl;
   }
-  finish();
+  send_flush_image_watcher();
 }
 
 template <typename I>
-void CloseRequest<I>::finish() {
-  if (m_image_ctx->image_watcher) {
-    m_image_ctx->unregister_watch();
+void CloseRequest<I>::send_flush_image_watcher() {
+  if (m_image_ctx->image_watcher == nullptr) {
+    finish();
+    return;
   }
 
+  m_image_ctx->image_watcher->flush(create_context_callback<
+    CloseRequest<I>, &CloseRequest<I>::handle_flush_image_watcher>(this));
+}
+
+template <typename I>
+void CloseRequest<I>::handle_flush_image_watcher(int r) {
+  CephContext *cct = m_image_ctx->cct;
+  ldout(cct, 10) << this << " " << __func__ << ": r=" << r << dendl;
+
+  if (r < 0) {
+    lderr(cct) << "error flushing image watcher: " << cpp_strerror(r) << dendl;
+  }
+  save_result(r);
+  finish();
+}
+
+template <typename I>
+void CloseRequest<I>::finish() {
+  m_image_ctx->shutdown();
   m_on_finish->complete(m_error_result);
   delete this;
 }
diff --git a/src/librbd/image/CloseRequest.h b/src/librbd/image/CloseRequest.h
index 08ace95..832cd2e 100644
--- a/src/librbd/image/CloseRequest.h
+++ b/src/librbd/image/CloseRequest.h
@@ -49,13 +49,16 @@ private:
    * SHUTDOWN_CACHE
    *    |
    *    v
-   * FLUSH_OP_WORK_QUEUE  . . . . .
-   *    |                         .
-   *    v                         .
-   * CLOSE_PARENT                 . (no parent)
-   *    |                         .
-   *    v                         .
-   * <finish> < . . . . . . . . . .
+   * FLUSH_OP_WORK_QUEUE . . . . .
+   *    |                        .
+   *    v                        .
+   * CLOSE_PARENT                . (no parent)
+   *    |                        .
+   *    v                        .
+   * FLUSH_IMAGE_WATCHER < . . . .
+   *    |
+   *    v
+   * <finish>
    *
    * @endverbatim
    */
@@ -93,6 +96,9 @@ private:
   void send_close_parent();
   void handle_close_parent(int r);
 
+  void send_flush_image_watcher();
+  void handle_flush_image_watcher(int r);
+
   void finish();
 
   void save_result(int result) {
diff --git a/src/librbd/image/OpenRequest.cc b/src/librbd/image/OpenRequest.cc
index cb0979a..c491039 100644
--- a/src/librbd/image/OpenRequest.cc
+++ b/src/librbd/image/OpenRequest.cc
@@ -19,26 +19,6 @@
 namespace librbd {
 namespace image {
 
-namespace {
-
-template <typename I>
-class C_RegisterWatch : public Context {
-public:
-  I &image_ctx;
-  Context *on_finish;
-
-  C_RegisterWatch(I &image_ctx, Context *on_finish)
-    : image_ctx(image_ctx), on_finish(on_finish) {
-  }
-
-  virtual void finish(int r) {
-    assert(r == 0);
-    on_finish->complete(image_ctx.register_watch());
-  }
-};
-
-} // anonymous namespace
-
 using util::create_context_callback;
 using util::create_rados_ack_callback;
 
@@ -78,6 +58,9 @@ Context *OpenRequest<I>::handle_v1_detect_header(int *result) {
     }
     send_close_image(*result);
   } else {
+    lderr(cct) << "RBD image format 1 is deprecated. "
+               << "Please copy this image to image format 2." << dendl;
+
     m_image_ctx->old_format = true;
     m_image_ctx->header_oid = util::old_header_name(m_image_ctx->name);
     send_register_watch();
@@ -102,7 +85,7 @@ void OpenRequest<I>::send_v2_detect_header() {
                                    comp, &op, &m_out_bl);
     comp->release();
   } else {
-    send_v2_get_immutable_metadata();
+    send_v2_get_name();
   }
 }
 
@@ -141,7 +124,7 @@ void OpenRequest<I>::send_v2_get_id() {
                                     comp, &op, &m_out_bl);
     comp->release();
   } else {
-    send_v2_get_immutable_metadata();
+    send_v2_get_name();
   }
 }
 
@@ -165,6 +148,42 @@ Context *OpenRequest<I>::handle_v2_get_id(int *result) {
 }
 
 template <typename I>
+void OpenRequest<I>::send_v2_get_name() {
+  CephContext *cct = m_image_ctx->cct;
+  ldout(cct, 10) << this << " " << __func__ << dendl;
+
+  librados::ObjectReadOperation op;
+  cls_client::dir_get_name_start(&op, m_image_ctx->id);
+
+  using klass = OpenRequest<I>;
+  librados::AioCompletion *comp = create_rados_ack_callback<
+    klass, &klass::handle_v2_get_name>(this);
+  m_out_bl.clear();
+  m_image_ctx->md_ctx.aio_operate(RBD_DIRECTORY, comp, &op, &m_out_bl);
+  comp->release();
+}
+
+template <typename I>
+Context *OpenRequest<I>::handle_v2_get_name(int *result) {
+  CephContext *cct = m_image_ctx->cct;
+  ldout(cct, 10) << __func__ << ": r=" << *result << dendl;
+
+  if (*result == 0) {
+    bufferlist::iterator it = m_out_bl.begin();
+    *result = cls_client::dir_get_name_finish(&it, &m_image_ctx->name);
+  }
+  if (*result < 0) {
+    lderr(cct) << "failed to retreive name: "
+               << cpp_strerror(*result) << dendl;
+    send_close_image(*result);
+  } else {
+    send_v2_get_immutable_metadata();
+  }
+
+  return nullptr;
+}
+
+template <typename I>
 void OpenRequest<I>::send_v2_get_immutable_metadata() {
   CephContext *cct = m_image_ctx->cct;
   ldout(cct, 10) << this << " " << __func__ << dendl;
@@ -255,12 +274,10 @@ void OpenRequest<I>::send_register_watch() {
     CephContext *cct = m_image_ctx->cct;
     ldout(cct, 10) << this << " " << __func__ << dendl;
 
-    // no librados async version of watch
     using klass = OpenRequest<I>;
-    Context *ctx = new C_RegisterWatch<I>(
-      *m_image_ctx,
-      create_context_callback<klass, &klass::handle_register_watch>(this));
-    m_image_ctx->op_work_queue->queue(ctx);
+    Context *ctx = create_context_callback<
+      klass, &klass::handle_register_watch>(this);
+    m_image_ctx->register_watch(ctx);
   } else {
     send_refresh();
   }
diff --git a/src/librbd/image/OpenRequest.h b/src/librbd/image/OpenRequest.h
index 599fdce..48aed37 100644
--- a/src/librbd/image/OpenRequest.h
+++ b/src/librbd/image/OpenRequest.h
@@ -38,7 +38,7 @@ private:
    *    \-----> V2_DETECT_HEADER                    |             .
    *                |                               |             .
    *                v                               |             .
-   *            V2_GET_ID                           |             .
+   *            V2_GET_ID|NAME                      |             .
    *                |                               |             .
    *                v                               |             .
    *            V2_GET_IMMUTABLE_METADATA           |             .
@@ -78,6 +78,9 @@ private:
   void send_v2_get_id();
   Context *handle_v2_get_id(int *result);
 
+  void send_v2_get_name();
+  Context *handle_v2_get_name(int *result);
+
   void send_v2_get_immutable_metadata();
   Context *handle_v2_get_immutable_metadata(int *result);
 
diff --git a/src/librbd/image/RefreshRequest.cc b/src/librbd/image/RefreshRequest.cc
index 013b1d6..12bee84 100644
--- a/src/librbd/image/RefreshRequest.cc
+++ b/src/librbd/image/RefreshRequest.cc
@@ -5,8 +5,10 @@
 #include "include/stringify.h"
 #include "common/dout.h"
 #include "common/errno.h"
+#include "common/WorkQueue.h"
 #include "cls/lock/cls_lock_client.h"
 #include "cls/rbd/cls_rbd_client.h"
+#include "librbd/AioImageRequestWQ.h"
 #include "librbd/ExclusiveLock.h"
 #include "librbd/ImageCtx.h"
 #include "librbd/Journal.h"
@@ -22,13 +24,15 @@ namespace librbd {
 namespace image {
 
 using util::create_rados_ack_callback;
+using util::create_async_context_callback;
 using util::create_context_callback;
 
 template <typename I>
 RefreshRequest<I>::RefreshRequest(I &image_ctx, Context *on_finish)
-  : m_image_ctx(image_ctx), m_on_finish(on_finish), m_error_result(0),
-    m_flush_aio(false), m_exclusive_lock(nullptr), m_object_map(nullptr),
-    m_journal(nullptr), m_refresh_parent(nullptr) {
+  : m_image_ctx(image_ctx),
+    m_on_finish(create_async_context_callback(m_image_ctx, on_finish)),
+    m_error_result(0), m_flush_aio(false), m_exclusive_lock(nullptr),
+    m_object_map(nullptr), m_journal(nullptr), m_refresh_parent(nullptr) {
 }
 
 template <typename I>
@@ -420,7 +424,7 @@ Context *RefreshRequest<I>::send_v2_init_exclusive_lock() {
     klass, &klass::handle_v2_init_exclusive_lock>(this);
 
   RWLock::RLocker owner_locker(m_image_ctx.owner_lock);
-  m_exclusive_lock->init(ctx);
+  m_exclusive_lock->init(m_features, ctx);
   return nullptr;
 }
 
@@ -448,6 +452,13 @@ Context *RefreshRequest<I>::send_v2_open_journal() {
       m_image_ctx.journal != nullptr ||
       m_image_ctx.exclusive_lock == nullptr ||
       !m_image_ctx.exclusive_lock->is_lock_owner()) {
+
+    // journal dynamically enabled -- doesn't own exclusive lock
+    if ((m_features & RBD_FEATURE_JOURNALING) != 0 &&
+        m_image_ctx.exclusive_lock != nullptr &&
+        m_image_ctx.journal == nullptr) {
+      m_image_ctx.aio_work_queue->set_require_lock_on_read();
+    }
     return send_v2_finalize_refresh_parent();
   }
 
@@ -698,7 +709,7 @@ void RefreshRequest<I>::apply() {
   CephContext *cct = m_image_ctx.cct;
   ldout(cct, 20) << this << " " << __func__ << dendl;
 
-  RWLock::RLocker owner_locker(m_image_ctx.owner_lock);
+  RWLock::WLocker owner_locker(m_image_ctx.owner_lock);
   RWLock::WLocker md_locker(m_image_ctx.md_lock);
 
   {
@@ -779,8 +790,12 @@ void RefreshRequest<I>::apply() {
         std::swap(m_exclusive_lock, m_image_ctx.exclusive_lock);
       }
       if (!m_image_ctx.test_features(RBD_FEATURE_JOURNALING,
-                                     m_image_ctx.snap_lock) ||
-          m_journal != nullptr) {
+                                     m_image_ctx.snap_lock)) {
+        if (m_image_ctx.journal != nullptr) {
+          m_image_ctx.aio_work_queue->clear_require_lock_on_read();
+        }
+        std::swap(m_journal, m_image_ctx.journal);
+      } else if (m_journal != nullptr) {
         std::swap(m_journal, m_image_ctx.journal);
       }
       if (!m_image_ctx.test_features(RBD_FEATURE_OBJECT_MAP,
diff --git a/src/librbd/image/SetSnapRequest.cc b/src/librbd/image/SetSnapRequest.cc
index 9e175b2..ca10e45 100644
--- a/src/librbd/image/SetSnapRequest.cc
+++ b/src/librbd/image/SetSnapRequest.cc
@@ -30,12 +30,10 @@ SetSnapRequest<I>::SetSnapRequest(I &image_ctx, const std::string &snap_name,
 
 template <typename I>
 SetSnapRequest<I>::~SetSnapRequest() {
+  assert(!m_writes_blocked);
   delete m_refresh_parent;
   delete m_object_map;
   delete m_exclusive_lock;
-  if (m_writes_blocked) {
-    m_image_ctx.aio_work_queue->unblock_writes();
-  }
 }
 
 template <typename I>
@@ -76,7 +74,7 @@ void SetSnapRequest<I>::send_init_exclusive_lock() {
     klass, &klass::handle_init_exclusive_lock>(this);
 
   RWLock::RLocker owner_locker(m_image_ctx.owner_lock);
-  m_exclusive_lock->init(ctx);
+  m_exclusive_lock->init(m_image_ctx.features, ctx);
 }
 
 template <typename I>
@@ -87,6 +85,7 @@ Context *SetSnapRequest<I>::handle_init_exclusive_lock(int *result) {
   if (*result < 0) {
     lderr(cct) << "failed to initialize exclusive lock: "
                << cpp_strerror(*result) << dendl;
+    finalize();
     return m_on_finish;
   }
   return send_refresh_parent(result);
@@ -115,6 +114,7 @@ Context *SetSnapRequest<I>::handle_block_writes(int *result) {
   if (*result < 0) {
     lderr(cct) << "failed to block writes: " << cpp_strerror(*result)
                << dendl;
+    finalize();
     return m_on_finish;
   }
 
@@ -126,6 +126,7 @@ Context *SetSnapRequest<I>::handle_block_writes(int *result) {
                     << dendl;
 
       *result = -ENOENT;
+      finalize();
       return m_on_finish;
     }
   }
@@ -163,6 +164,7 @@ Context *SetSnapRequest<I>::handle_shut_down_exclusive_lock(int *result) {
   if (*result < 0) {
     lderr(cct) << "failed to shut down exclusive lock: "
                << cpp_strerror(*result) << dendl;
+    finalize();
     return m_on_finish;
   }
 
@@ -183,6 +185,7 @@ Context *SetSnapRequest<I>::send_refresh_parent(int *result) {
     if (parent_info == nullptr) {
       *result = -ENOENT;
       lderr(cct) << "failed to retrieve snapshot parent info" << dendl;
+      finalize();
       return m_on_finish;
     }
 
@@ -195,6 +198,7 @@ Context *SetSnapRequest<I>::send_refresh_parent(int *result) {
     if (m_snap_id == CEPH_NOSNAP) {
       // object map is loaded when exclusive lock is acquired
       *result = apply();
+      finalize();
       return m_on_finish;
     } else {
       // load snapshot object map
@@ -221,6 +225,7 @@ Context *SetSnapRequest<I>::handle_refresh_parent(int *result) {
   if (*result < 0) {
     lderr(cct) << "failed to refresh snapshot parent: " << cpp_strerror(*result)
                << dendl;
+    finalize();
     return m_on_finish;
   }
 
@@ -228,6 +233,7 @@ Context *SetSnapRequest<I>::handle_refresh_parent(int *result) {
     // object map is loaded when exclusive lock is acquired
     *result = apply();
     if (*result < 0) {
+      finalize();
       return m_on_finish;
     }
 
@@ -243,6 +249,7 @@ Context *SetSnapRequest<I>::send_open_object_map(int *result) {
   if (!m_image_ctx.test_features(RBD_FEATURE_OBJECT_MAP)) {
     *result = apply();
     if (*result < 0) {
+      finalize();
       return m_on_finish;
     }
 
@@ -270,6 +277,7 @@ Context *SetSnapRequest<I>::handle_open_object_map(int *result) {
 
   *result = apply();
   if (*result < 0) {
+    finalize();
     return m_on_finish;
   }
 
@@ -279,6 +287,7 @@ Context *SetSnapRequest<I>::handle_open_object_map(int *result) {
 template <typename I>
 Context *SetSnapRequest<I>::send_finalize_refresh_parent(int *result) {
   if (m_refresh_parent == nullptr) {
+    finalize();
     return m_on_finish;
   }
 
@@ -301,6 +310,7 @@ Context *SetSnapRequest<I>::handle_finalize_refresh_parent(int *result) {
     lderr(cct) << "failed to close parent image: " << cpp_strerror(*result)
                << dendl;
   }
+  finalize();
   return m_on_finish;
 }
 
@@ -309,9 +319,9 @@ int SetSnapRequest<I>::apply() {
   CephContext *cct = m_image_ctx.cct;
   ldout(cct, 10) << __func__ << dendl;
 
+  RWLock::WLocker owner_locker(m_image_ctx.owner_lock);
   RWLock::WLocker snap_locker(m_image_ctx.snap_lock);
   RWLock::WLocker parent_locker(m_image_ctx.parent_lock);
-
   if (m_snap_id != CEPH_NOSNAP) {
     int r = m_image_ctx.snap_set(m_snap_name);
     if (r < 0) {
@@ -331,7 +341,16 @@ int SetSnapRequest<I>::apply() {
 }
 
 template <typename I>
+void SetSnapRequest<I>::finalize() {
+  if (m_writes_blocked) {
+    m_image_ctx.aio_work_queue->unblock_writes();
+    m_writes_blocked = false;
+  }
+}
+
+template <typename I>
 void SetSnapRequest<I>::send_complete() {
+  finalize();
   m_on_finish->complete(0);
   delete this;
 }
diff --git a/src/librbd/image/SetSnapRequest.h b/src/librbd/image/SetSnapRequest.h
index 815614e..fa12032 100644
--- a/src/librbd/image/SetSnapRequest.h
+++ b/src/librbd/image/SetSnapRequest.h
@@ -110,6 +110,7 @@ private:
   Context *handle_finalize_refresh_parent(int *result);
 
   int apply();
+  void finalize();
   void send_complete();
 };
 
diff --git a/src/librbd/image_watcher/Notifier.cc b/src/librbd/image_watcher/Notifier.cc
new file mode 100644
index 0000000..7569f75
--- /dev/null
+++ b/src/librbd/image_watcher/Notifier.cc
@@ -0,0 +1,78 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+
+#include "librbd/image_watcher/Notifier.h"
+#include "common/WorkQueue.h"
+#include "librbd/ImageCtx.h"
+#include "librbd/Utils.h"
+
+#define dout_subsys ceph_subsys_rbd
+#undef dout_prefix
+#define dout_prefix *_dout << "librbd::image_watcher::Notifier: "
+
+namespace librbd {
+namespace image_watcher {
+
+const uint64_t Notifier::NOTIFY_TIMEOUT = 5000;
+
+Notifier::Notifier(ImageCtx &image_ctx)
+  : m_image_ctx(image_ctx),
+    m_aio_notify_lock(util::unique_lock_name(
+      "librbd::image_watcher::Notifier::m_aio_notify_lock", this)) {
+}
+
+Notifier::~Notifier() {
+  Mutex::Locker aio_notify_locker(m_aio_notify_lock);
+  assert(m_pending_aio_notifies == 0);
+}
+
+void Notifier::flush(Context *on_finish) {
+  Mutex::Locker aio_notify_locker(m_aio_notify_lock);
+  if (m_pending_aio_notifies == 0) {
+    m_image_ctx.op_work_queue->queue(on_finish, 0);
+    return;
+  }
+
+  m_aio_notify_flush_ctxs.push_back(on_finish);
+}
+
+void Notifier::notify(bufferlist &bl, bufferlist *out_bl, Context *on_finish) {
+  {
+    Mutex::Locker aio_notify_locker(m_aio_notify_lock);
+    ++m_pending_aio_notifies;
+
+    CephContext *cct = m_image_ctx.cct;
+    ldout(cct, 20) << __func__ << ": pending=" << m_pending_aio_notifies
+                   << dendl;
+  }
+
+  C_AioNotify *ctx = new C_AioNotify(this, on_finish);
+  librados::AioCompletion *comp = util::create_rados_ack_callback(ctx);
+  int r = m_image_ctx.md_ctx.aio_notify(m_image_ctx.header_oid, comp, bl,
+                                        NOTIFY_TIMEOUT, out_bl);
+  assert(r == 0);
+  comp->release();
+}
+
+void Notifier::handle_notify(int r, Context *on_finish) {
+  if (on_finish != nullptr) {
+    m_image_ctx.op_work_queue->queue(on_finish, r);
+  }
+
+  Mutex::Locker aio_notify_locker(m_aio_notify_lock);
+  assert(m_pending_aio_notifies > 0);
+  --m_pending_aio_notifies;
+
+  CephContext *cct = m_image_ctx.cct;
+  ldout(cct, 20) << __func__ << ": pending=" << m_pending_aio_notifies
+                 << dendl;
+  if (m_pending_aio_notifies == 0) {
+    for (auto ctx : m_aio_notify_flush_ctxs) {
+      m_image_ctx.op_work_queue->queue(ctx, 0);
+    }
+    m_aio_notify_flush_ctxs.clear();
+  }
+}
+
+} // namespace image_watcher
+} // namespace librbd
diff --git a/src/librbd/image_watcher/Notifier.h b/src/librbd/image_watcher/Notifier.h
new file mode 100644
index 0000000..aa45a2e
--- /dev/null
+++ b/src/librbd/image_watcher/Notifier.h
@@ -0,0 +1,57 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+
+#ifndef CEPH_LIBRBD_IMAGE_WATCHER_NOTIFIER_H
+#define CEPH_LIBRBD_IMAGE_WATCHER_NOTIFIER_H
+
+#include "include/int_types.h"
+#include "include/buffer.h"
+#include "include/Context.h"
+#include "common/Mutex.h"
+#include <list>
+
+namespace librbd {
+
+struct ImageCtx;
+
+namespace image_watcher {
+
+class Notifier {
+public:
+  static const uint64_t NOTIFY_TIMEOUT;
+
+  Notifier(ImageCtx &image_ctx);
+  ~Notifier();
+
+  void flush(Context *on_finish);
+  void notify(bufferlist &bl, bufferlist *out_bl, Context *on_finish);
+
+private:
+  typedef std::list<Context*> Contexts;
+
+  struct C_AioNotify : public Context {
+    Notifier *notifier;
+    Context *on_finish;
+
+    C_AioNotify(Notifier *notifier, Context *on_finish)
+      : notifier(notifier), on_finish(on_finish) {
+    }
+    virtual void finish(int r) override {
+      notifier->handle_notify(r, on_finish);
+    }
+  };
+
+  ImageCtx &m_image_ctx;
+
+  Mutex m_aio_notify_lock;
+  size_t m_pending_aio_notifies = 0;
+  Contexts m_aio_notify_flush_ctxs;
+
+  void handle_notify(int r, Context *on_finish);
+
+};
+
+} // namespace image_watcher
+} // namespace librbd
+
+#endif // CEPH_LIBRBD_IMAGE_WATCHER_NOTIFIER_H
diff --git a/src/librbd/image_watcher/NotifyLockOwner.cc b/src/librbd/image_watcher/NotifyLockOwner.cc
new file mode 100644
index 0000000..9ee0ebe
--- /dev/null
+++ b/src/librbd/image_watcher/NotifyLockOwner.cc
@@ -0,0 +1,105 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+
+#include "librbd/image_watcher/NotifyLockOwner.h"
+#include "common/errno.h"
+#include "librbd/ImageCtx.h"
+#include "librbd/Utils.h"
+#include "librbd/WatchNotifyTypes.h"
+#include "librbd/image_watcher/Notifier.h"
+#include <map>
+
+#define dout_subsys ceph_subsys_rbd
+#undef dout_prefix
+#define dout_prefix *_dout << "librbd::image_watcher::NotifyLockOwner: " \
+                           << this << " " << __func__
+
+namespace librbd {
+namespace image_watcher {
+
+using namespace watch_notify;
+using util::create_context_callback;
+
+NotifyLockOwner::NotifyLockOwner(ImageCtx &image_ctx, Notifier &notifier,
+                                 bufferlist &&bl, Context *on_finish)
+  : m_image_ctx(image_ctx), m_notifier(notifier), m_bl(std::move(bl)),
+    m_on_finish(on_finish) {
+}
+
+void NotifyLockOwner::send() {
+  send_notify();
+}
+
+void NotifyLockOwner::send_notify() {
+  CephContext *cct = m_image_ctx.cct;
+  ldout(cct, 20) << dendl;
+
+  assert(m_image_ctx.owner_lock.is_locked());
+  m_notifier.notify(m_bl, &m_out_bl, create_context_callback<
+    NotifyLockOwner, &NotifyLockOwner::handle_notify>(this));
+}
+
+void NotifyLockOwner::handle_notify(int r) {
+  CephContext *cct = m_image_ctx.cct;
+  ldout(cct, 20) << ": r=" << r << dendl;
+
+  if (r < 0 && r != -ETIMEDOUT) {
+    lderr(cct) << ": lock owner notification failed: " << cpp_strerror(r)
+               << dendl;
+    finish(r);
+    return;
+  }
+
+  typedef std::map<std::pair<uint64_t, uint64_t>, bufferlist> responses_t;
+  responses_t responses;
+  if (m_out_bl.length() > 0) {
+    try {
+      bufferlist::iterator iter = m_out_bl.begin();
+      ::decode(responses, iter);
+    } catch (const buffer::error &err) {
+      lderr(cct) << ": failed to decode response" << dendl;
+      finish(-EINVAL);
+      return;
+    }
+  }
+
+  bufferlist response;
+  bool lock_owner_responded = false;
+  for (responses_t::iterator i = responses.begin(); i != responses.end(); ++i) {
+    if (i->second.length() > 0) {
+      if (lock_owner_responded) {
+        lderr(cct) << ": duplicate lock owners detected" << dendl;
+        finish(-EINVAL);
+        return;
+      }
+      lock_owner_responded = true;
+      response.claim(i->second);
+    }
+  }
+
+  if (!lock_owner_responded) {
+    lderr(cct) << ": no lock owners detected" << dendl;
+    finish(-ETIMEDOUT);
+    return;
+  }
+
+  try {
+    bufferlist::iterator iter = response.begin();
+
+    ResponseMessage response_message;
+    ::decode(response_message, iter);
+
+    r = response_message.result;
+  } catch (const buffer::error &err) {
+    r = -EINVAL;
+  }
+  finish(r);
+}
+
+void NotifyLockOwner::finish(int r) {
+  m_on_finish->complete(r);
+  delete this;
+}
+
+} // namespace image_watcher
+} // namespace librbd
diff --git a/src/librbd/image_watcher/NotifyLockOwner.h b/src/librbd/image_watcher/NotifyLockOwner.h
new file mode 100644
index 0000000..b4bdb2d
--- /dev/null
+++ b/src/librbd/image_watcher/NotifyLockOwner.h
@@ -0,0 +1,49 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+
+#ifndef CEPH_LIBRBD_IMAGE_WATCHER_NOTIFY_LOCK_OWNER_H
+#define CEPH_LIBRBD_IMAGE_WATCHER_NOTIFY_LOCK_OWNER_H
+
+#include "include/int_types.h"
+#include "include/buffer.h"
+
+class Context;
+
+namespace librbd {
+
+struct ImageCtx;
+
+namespace image_watcher {
+
+class Notifier;
+
+class NotifyLockOwner {
+public:
+  static NotifyLockOwner *create(ImageCtx &image_ctx, Notifier &notifier,
+                                 bufferlist &&bl, Context *on_finish) {
+    return new NotifyLockOwner(image_ctx, notifier, std::move(bl), on_finish);
+  }
+
+  NotifyLockOwner(ImageCtx &image_ctx, Notifier &notifier, bufferlist &&bl,
+                  Context *on_finish);
+
+  void send();
+
+private:
+  ImageCtx &m_image_ctx;
+  Notifier &m_notifier;
+
+  bufferlist m_bl;
+  bufferlist m_out_bl;
+  Context *m_on_finish;
+
+  void send_notify();
+  void handle_notify(int r);
+
+  void finish(int r);
+};
+
+} // namespace image_watcher
+} // namespace librbd
+
+#endif // CEPH_LIBRBD_IMAGE_WATCHER_NOTIFY_LOCK_OWNER_H
diff --git a/src/librbd/internal.cc b/src/librbd/internal.cc
index 928f404..73ebb0a 100644
--- a/src/librbd/internal.cc
+++ b/src/librbd/internal.cc
@@ -6,6 +6,7 @@
 #include <limits.h>
 
 #include "include/types.h"
+#include "include/uuid.h"
 #include "common/ceph_context.h"
 #include "common/dout.h"
 #include "common/errno.h"
@@ -18,6 +19,8 @@
 
 #include "cls/rbd/cls_rbd.h"
 #include "cls/rbd/cls_rbd_client.h"
+#include "cls/journal/cls_journal_types.h"
+#include "cls/journal/cls_journal_client.h"
 
 #include "librbd/AioCompletion.h"
 #include "librbd/AioImageRequest.h"
@@ -31,6 +34,7 @@
 #include "librbd/ImageWatcher.h"
 #include "librbd/internal.h"
 #include "librbd/Journal.h"
+#include "librbd/journal/Types.h"
 #include "librbd/ObjectMap.h"
 #include "librbd/Operations.h"
 #include "librbd/parent_types.h"
@@ -38,6 +42,8 @@
 #include "librbd/operation/TrimRequest.h"
 #include "include/util.h"
 
+#include "journal/Journaler.h"
+
 #include <boost/bind.hpp>
 #include <boost/scope_exit.hpp>
 #include <boost/variant.hpp>
@@ -177,6 +183,23 @@ int validate_pool(IoCtx &io_ctx, CephContext *cct) {
   return 0;
 }
 
+int validate_mirroring_enabled(ImageCtx *ictx) {
+  CephContext *cct = ictx->cct;
+  cls::rbd::MirrorImage mirror_image_internal;
+  int r = cls_client::mirror_image_get(&ictx->md_ctx, ictx->id,
+      &mirror_image_internal);
+  if (r < 0 && r != -ENOENT) {
+    lderr(cct) << "failed to retrieve mirroring state: " << cpp_strerror(r)
+      << dendl;
+    return r;
+  } else if (mirror_image_internal.state !=
+               cls::rbd::MirrorImageState::MIRROR_IMAGE_STATE_ENABLED) {
+    lderr(cct) << "mirroring is not currently enabled" << dendl;
+    return -EINVAL;
+  }
+  return 0;
+}
+
 } // anonymous namespace
 
   int detect_format(IoCtx &io_ctx, const string &name,
@@ -307,16 +330,6 @@ int validate_pool(IoCtx &io_ctx, CephContext *cct) {
     return 0;
   }
 
-  int notify_change(IoCtx& io_ctx, const string& oid, ImageCtx *ictx)
-  {
-    if (ictx) {
-      ictx->state->handle_update_notification();
-    }
-
-    ImageWatcher::notify_header_update(io_ctx, oid);
-    return 0;
-  }
-
   int read_header(IoCtx& io_ctx, const string& header_oid,
 		  struct rbd_obj_header_ondisk *header, uint64_t *ver)
   {
@@ -771,7 +784,7 @@ int validate_pool(IoCtx &io_ctx, CephContext *cct) {
     ostringstream oss;
     CephContext *cct = (CephContext *)io_ctx.cct();
 
-    ceph_file_layout layout;
+    file_layout_t layout;
 
     int r = validate_pool(io_ctx, cct);
     if (r < 0) {
@@ -834,14 +847,14 @@ int validate_pool(IoCtx &io_ctx, CephContext *cct) {
         goto err_remove_header;
       }
 
-      memset(&layout, 0, sizeof(layout));
-      layout.fl_object_size = 1ull << order;
+      layout = file_layout_t();
+      layout.object_size = 1ull << order;
       if (stripe_unit == 0 || stripe_count == 0) {
-        layout.fl_stripe_unit = layout.fl_object_size;
-        layout.fl_stripe_count = 1;
+        layout.stripe_unit = layout.object_size;
+        layout.stripe_count = 1;
       } else {
-        layout.fl_stripe_unit = stripe_unit;
-        layout.fl_stripe_count = stripe_count;
+        layout.stripe_unit = stripe_unit;
+        layout.stripe_count = stripe_count;
       }
 
       librados::ObjectWriteOperation op;
@@ -867,6 +880,33 @@ int validate_pool(IoCtx &io_ctx, CephContext *cct) {
         lderr(cct) << "error creating journal: " << cpp_strerror(r) << dendl;
         goto err_remove_object_map;
       }
+
+      rbd_mirror_mode_t mirror_mode;
+      r = librbd::mirror_mode_get(io_ctx, &mirror_mode);
+      if (r < 0) {
+        lderr(cct) << "error in retrieving pool mirroring status: "
+          << cpp_strerror(r) << dendl;
+        goto err_remove_object_map;
+      }
+
+      if (mirror_mode == RBD_MIRROR_MODE_POOL) {
+        ImageCtx *img_ctx = new ImageCtx("", id, nullptr, io_ctx, false);
+        r = img_ctx->state->open();
+        if (r < 0) {
+          lderr(cct) << "error opening image: " << cpp_strerror(r) << dendl;
+          delete img_ctx;
+          goto err_remove_object_map;
+        }
+        r = mirror_image_enable(img_ctx);
+        if (r < 0) {
+          lderr(cct) << "error enabling mirroring: " << cpp_strerror(r)
+            << dendl;
+          img_ctx->state->close();
+          goto err_remove_object_map;
+        }
+        img_ctx->state->close();
+      }
+
     }
 
     ldout(cct, 2) << "done." << dendl;
@@ -1326,7 +1366,10 @@ int validate_pool(IoCtx &io_ctx, CephContext *cct) {
         return r;
       }
 
-      if ((features & RBD_FEATURES_MUTABLE) != features) {
+      uint64_t disable_mask = (RBD_FEATURES_MUTABLE |
+                               RBD_FEATURES_DISABLE_ONLY);
+      if ((enabled && (features & RBD_FEATURES_MUTABLE) != features) ||
+          (!enabled && (features & disable_mask) != features)) {
         lderr(cct) << "cannot update immutable features" << dendl;
         return -EINVAL;
       } else if (features == 0) {
@@ -1348,6 +1391,7 @@ int validate_pool(IoCtx &io_ctx, CephContext *cct) {
         return 0;
       }
 
+      bool enable_mirroring = false;
       uint64_t features_mask = features;
       uint64_t disable_flags = 0;
       if (enabled) {
@@ -1384,6 +1428,16 @@ int validate_pool(IoCtx &io_ctx, CephContext *cct) {
                        << dendl;
             return r;
           }
+
+          rbd_mirror_mode_t mirror_mode;
+          r = librbd::mirror_mode_get(ictx->md_ctx, &mirror_mode);
+          if (r < 0) {
+            lderr(cct) << "error in retrieving pool mirroring status: "
+              << cpp_strerror(r) << dendl;
+            return r;
+          }
+
+          enable_mirroring = (mirror_mode == RBD_MIRROR_MODE_POOL);
         }
 
         if (enable_flags != 0) {
@@ -1399,7 +1453,8 @@ int validate_pool(IoCtx &io_ctx, CephContext *cct) {
             lderr(cct) << "cannot disable exclusive lock" << dendl;
             return -EINVAL;
           }
-          features_mask |= RBD_FEATURE_OBJECT_MAP;
+          features_mask |= (RBD_FEATURE_OBJECT_MAP |
+                            RBD_FEATURE_JOURNALING);
         }
         if ((features & RBD_FEATURE_OBJECT_MAP) != 0) {
           if ((new_features & RBD_FEATURE_FAST_DIFF) != 0) {
@@ -1418,6 +1473,37 @@ int validate_pool(IoCtx &io_ctx, CephContext *cct) {
           disable_flags = RBD_FLAG_FAST_DIFF_INVALID;
         }
         if ((features & RBD_FEATURE_JOURNALING) != 0) {
+          rbd_mirror_mode_t mirror_mode;
+          r = librbd::mirror_mode_get(ictx->md_ctx, &mirror_mode);
+          if (r < 0) {
+            lderr(cct) << "error in retrieving pool mirroring status: "
+              << cpp_strerror(r) << dendl;
+            return r;
+          }
+
+          if (mirror_mode == RBD_MIRROR_MODE_IMAGE) {
+            cls::rbd::MirrorImage mirror_image;
+            r = cls_client::mirror_image_get(&ictx->md_ctx, ictx->id,
+                                             &mirror_image);
+            if (r < 0 && r != -ENOENT) {
+              lderr(cct) << "error retrieving mirroring state: "
+                << cpp_strerror(r) << dendl;
+            }
+
+            if (mirror_image.state ==
+                cls::rbd::MirrorImageState::MIRROR_IMAGE_STATE_ENABLED) {
+              lderr(cct) << "cannot disable journaling: image mirroring "
+                " enabled and mirror pool mode set to image" << dendl;
+              return -EINVAL;
+            }
+          } else if (mirror_mode == RBD_MIRROR_MODE_POOL) {
+            r = mirror_image_disable(ictx, false);
+            if (r < 0) {
+              lderr(cct) << "error disabling image mirroring: "
+                << cpp_strerror(r) << dendl;
+            }
+          }
+
           r = Journal<>::remove(ictx->md_ctx, ictx->id);
           if (r < 0) {
             lderr(cct) << "error removing image journal: " << cpp_strerror(r)
@@ -1451,9 +1537,26 @@ int validate_pool(IoCtx &io_ctx, CephContext *cct) {
           return r;
         }
       }
-    }
 
-    notify_change(ictx->md_ctx, ictx->header_oid, ictx);
+      if (enable_mirroring) {
+        ImageCtx *img_ctx = new ImageCtx("", ictx->id, nullptr,
+            ictx->md_ctx, false);
+        r = img_ctx->state->open();
+        if (r < 0) {
+          lderr(cct) << "error opening image: " << cpp_strerror(r) << dendl;
+          delete img_ctx;
+        } else {
+          r = mirror_image_enable(img_ctx);
+          if (r < 0) {
+            lderr(cct) << "error enabling mirroring: " << cpp_strerror(r)
+              << dendl;
+          }
+          img_ctx->state->close();
+        }
+      }
+   }
+
+    ictx->notify_update();
     return 0;
   }
 
@@ -1988,7 +2091,7 @@ int validate_pool(IoCtx &io_ctx, CephContext *cct) {
       }
     }
 
-    notify_change(ictx->md_ctx, ictx->header_oid, ictx);
+    ictx->notify_update();
     return 0;
   }
 
@@ -2010,7 +2113,7 @@ int validate_pool(IoCtx &io_ctx, CephContext *cct) {
       }
     }
 
-    notify_change(ictx->md_ctx, ictx->header_oid, ictx);
+    ictx->notify_update();
     return 0;
   }
 
@@ -2073,7 +2176,7 @@ int validate_pool(IoCtx &io_ctx, CephContext *cct) {
 				     RBD_LOCK_NAME, cookie, lock_client);
     if (r < 0)
       return r;
-    notify_change(ictx->md_ctx, ictx->header_oid, ictx);
+    ictx->notify_update();
     return 0;
   }
 
@@ -2306,69 +2409,441 @@ int validate_pool(IoCtx &io_ctx, CephContext *cct) {
     return cls_client::metadata_list(&ictx->md_ctx, ictx->header_oid, start, max, pairs);
   }
 
-  int mirror_is_enabled(IoCtx& io_ctx, bool *enabled) {
-    CephContext *cct = reinterpret_cast<CephContext *>(io_ctx.cct());
-    ldout(cct, 20) << __func__ << dendl;
+  int mirror_image_enable(ImageCtx *ictx) {
+    CephContext *cct = ictx->cct;
+    ldout(cct, 20) << "mirror_image_enable " << ictx << dendl;
 
-    int r = cls_client::mirror_is_enabled(&io_ctx, enabled);
+    if ((ictx->features & RBD_FEATURE_JOURNALING) == 0) {
+      lderr(cct) << "cannot enable mirroring: journaling is not enabled"
+        << dendl;
+      return -EINVAL;
+    }
+
+    bool is_primary;
+    int r = Journal<>::is_tag_owner(ictx, &is_primary);
     if (r < 0) {
-      lderr(cct) << "Failed to retrieve mirror flag: " << cpp_strerror(r)
+      lderr(cct) << "cannot enable mirroring: failed to check tag ownership: "
+        << cpp_strerror(r) << dendl;
+      return r;
+    }
+
+    if (!is_primary) {
+      lderr(cct) <<
+        "cannot enable mirroring: last journal tag not owned by local cluster"
+        << dendl;
+      return -EINVAL;
+    }
+
+    cls::rbd::MirrorImage mirror_image_internal;
+    r = cls_client::mirror_image_get(&ictx->md_ctx, ictx->id,
+                                 &mirror_image_internal);
+    if (r < 0 && r != -ENOENT) {
+      lderr(cct) << "cannot enable mirroring: " << cpp_strerror(r) << dendl;
+      return r;
+    }
+
+    if (mirror_image_internal.state ==
+        cls::rbd::MirrorImageState::MIRROR_IMAGE_STATE_ENABLED) {
+      // mirroring is already enabled
+      return 0;
+    }
+    else if (r != -ENOENT) {
+      lderr(cct) << "cannot enable mirroring: mirroring image is in "
+        "disabling state" << dendl;
+      return -EINVAL;
+    }
+
+    mirror_image_internal.state =
+      cls::rbd::MirrorImageState::MIRROR_IMAGE_STATE_ENABLED;
+
+    uuid_d uuid_gen;
+    uuid_gen.generate_random();
+    mirror_image_internal.global_image_id = uuid_gen.to_string();
+
+    r = cls_client::mirror_image_set(&ictx->md_ctx, ictx->id,
+                                     mirror_image_internal);
+    if (r < 0) {
+      lderr(cct) << "cannot enable mirroring: " << cpp_strerror(r) << dendl;
+      return r;
+    }
+
+    ldout(cct, 20) << "image mirroring is enabled: global_id=" <<
+      mirror_image_internal.global_image_id << dendl;
+
+    return 0;
+  }
+
+  int mirror_image_disable(ImageCtx *ictx, bool force) {
+    CephContext *cct = ictx->cct;
+    ldout(cct, 20) << "mirror_image_disable " << ictx << dendl;
+
+    cls::rbd::MirrorImage mirror_image_internal;
+    std::vector<snap_info_t> snaps;
+    std::set<cls::journal::Client> clients;
+    std::string header_oid;
+
+    bool is_primary;
+    int r = Journal<>::is_tag_owner(ictx, &is_primary);
+    if (r < 0) {
+      lderr(cct) << "cannot disable mirroring: failed to check tag ownership: "
+        << cpp_strerror(r) << dendl;
+      return r;
+    }
+
+    if (!is_primary) {
+      if (!force) {
+        lderr(cct) << "Mirrored image is not the primary, add force option to"
+          " disable mirroring" << dendl;
+        return -EINVAL;
+      }
+      goto remove_mirroring_image;
+    }
+
+    r = cls_client::mirror_image_get(&ictx->md_ctx, ictx->id,
+                                     &mirror_image_internal);
+    if (r < 0 && r != -ENOENT) {
+      lderr(cct) << "cannot disable mirroring: " << cpp_strerror(r) << dendl;
+      return r;
+    }
+    else if (r == -ENOENT) {
+      // mirroring is not enabled for this image
+      ldout(cct, 20) << "ignoring disable command: mirroring is not enabled "
+        "for this image" << dendl;
+      return 0;
+    }
+
+    mirror_image_internal.state =
+      cls::rbd::MirrorImageState::MIRROR_IMAGE_STATE_DISABLING;
+    r = cls_client::mirror_image_set(&ictx->md_ctx, ictx->id,
+                                     mirror_image_internal);
+    if (r < 0) {
+      lderr(cct) << "cannot disable mirroring: " << cpp_strerror(r) << dendl;
+      return r;
+    }
+
+    header_oid = ::journal::Journaler::header_oid(ictx->id);
+
+    while(true) {
+      r = cls::journal::client::client_list(ictx->md_ctx, header_oid, &clients);
+      if (r < 0) {
+        lderr(cct) << "cannot disable mirroring: " << cpp_strerror(r) << dendl;
+        return r;
+      }
+
+      assert(clients.size() >= 1);
+
+      if (clients.size() == 1) {
+        // only local journal client remains
+        break;
+      }
+
+      for (auto client : clients) {
+        journal::ClientData client_data;
+        bufferlist::iterator bl = client.data.begin();
+        ::decode(client_data, bl);
+        journal::ClientMetaType type = client_data.get_client_meta_type();
+
+        if (type != journal::ClientMetaType::MIRROR_PEER_CLIENT_META_TYPE) {
+          continue;
+        }
+
+        journal::MirrorPeerClientMeta client_meta =
+          boost::get<journal::MirrorPeerClientMeta>(client_data.client_meta);
+
+        for (const auto& sync : client_meta.sync_points) {
+          r = ictx->operations->snap_remove(sync.snap_name.c_str());
+          if (r < 0 && r != -ENOENT) {
+            lderr(cct) << "cannot disable mirroring: failed to remove temporary"
+              " snapshot created by remote peer: " << cpp_strerror(r) << dendl;
+            return r;
+          }
+        }
+
+        r = cls::journal::client::client_unregister(ictx->md_ctx, header_oid,
+                                                    client.id);
+        if (r < 0 && r != -ENOENT) {
+          lderr(cct) << "cannot disable mirroring: failed to unregister remote"
+            " journal client: " << cpp_strerror(r) << dendl;
+          return r;
+        }
+      }
+    }
+
+  remove_mirroring_image:
+    r = cls_client::mirror_image_remove(&ictx->md_ctx, ictx->id);
+    if (r < 0) {
+      lderr(cct) << "failed to remove image from mirroring directory: "
+        << cpp_strerror(r) << dendl;
+      return r;
+    }
+
+    ldout(cct, 20) << "removed image state from rbd_mirroring object" << dendl;
+
+    if (is_primary) {
+      // TODO: send notification to mirroring object about update
+    }
+
+    return 0;
+  }
+
+  int mirror_image_promote(ImageCtx *ictx, bool force) {
+    CephContext *cct = ictx->cct;
+    ldout(cct, 20) << __func__ << ": ictx=" << ictx << ", "
+                   << "force=" << force << dendl;
+
+    int r = validate_mirroring_enabled(ictx);
+    if (r < 0) {
+      return r;
+    }
+
+    std::string mirror_uuid;
+    r = Journal<>::get_tag_owner(ictx, &mirror_uuid);
+    if (r < 0) {
+      lderr(cct) << "failed to determine tag ownership: " << cpp_strerror(r)
+                 << dendl;
+      return r;
+    } else if (mirror_uuid == Journal<>::LOCAL_MIRROR_UUID) {
+      lderr(cct) << "image is already primary" << dendl;
+      return -EINVAL;
+    } else if (mirror_uuid != Journal<>::ORPHAN_MIRROR_UUID && !force) {
+      lderr(cct) << "image is still primary within a remote cluster" << dendl;
+      return -EBUSY;
+    }
+
+    // TODO: need interlock with local rbd-mirror daemon to ensure it has stopped
+    //       replay
+
+    r = Journal<>::allocate_tag(ictx, Journal<>::LOCAL_MIRROR_UUID);
+    if (r < 0) {
+      lderr(cct) << "failed to promote image: " << cpp_strerror(r)
                  << dendl;
       return r;
     }
     return 0;
   }
 
-  int mirror_set_enabled(IoCtx& io_ctx, bool enabled) {
-    CephContext *cct = reinterpret_cast<CephContext *>(io_ctx.cct());
-    ldout(cct, 20) << __func__ << ": enabled=" << enabled << dendl;
+  int mirror_image_demote(ImageCtx *ictx) {
+    CephContext *cct = ictx->cct;
+    ldout(cct, 20) << __func__ << ": ictx=" << ictx << dendl;
+
+    int r = validate_mirroring_enabled(ictx);
+    if (r < 0) {
+      return r;
+    }
+
+    bool is_primary;
+    r = Journal<>::is_tag_owner(ictx, &is_primary);
+    if (r < 0) {
+      lderr(cct) << "failed to determine tag ownership: " << cpp_strerror(r)
+                 << dendl;
+      return r;
+    }
+
+    if (!is_primary) {
+      lderr(cct) << "image is not currently the primary" << dendl;
+      return -EINVAL;
+    }
+
+    RWLock::RLocker owner_lock(ictx->owner_lock);
+    C_SaferCond lock_ctx;
+    ictx->exclusive_lock->request_lock(&lock_ctx);
+    r = lock_ctx.wait();
+    if (r < 0) {
+      lderr(cct) << "failed to lock image: " << cpp_strerror(r) << dendl;
+    } else if (!ictx->exclusive_lock->is_lock_owner()) {
+      lderr(cct) << "failed to acquire exclusive lock" << dendl;
+    }
+
+    r = Journal<>::allocate_tag(ictx, Journal<>::ORPHAN_MIRROR_UUID);
+    if (r < 0) {
+      lderr(cct) << "failed to demote image: " << cpp_strerror(r)
+                 << dendl;
+      return r;
+    }
+    return 0;
+  }
+
+  int mirror_image_resync(ImageCtx *ictx) {
+    CephContext *cct = ictx->cct;
+    ldout(cct, 20) << __func__ << ": ictx=" << ictx << dendl;
+
+    int r = validate_mirroring_enabled(ictx);
+    if (r < 0) {
+      return r;
+    }
+
+    std::string mirror_uuid;
+    r = Journal<>::get_tag_owner(ictx, &mirror_uuid);
+    if (r < 0) {
+      lderr(cct) << "failed to determine tag ownership: " << cpp_strerror(r)
+                 << dendl;
+      return r;
+    } else if (mirror_uuid == Journal<>::LOCAL_MIRROR_UUID) {
+      lderr(cct) << "image is primary, cannot resync to itself" << dendl;
+      return -EINVAL;
+    }
+
+    // flag the journal indicating that we want to rebuild the local image
+    r = Journal<>::request_resync(ictx);
+    if (r < 0) {
+      lderr(cct) << "failed to request resync: " << cpp_strerror(r) << dendl;
+      return r;
+    }
+
+    return 0;
+  }
+
+  int mirror_image_get_info(ImageCtx *ictx, mirror_image_info_t *mirror_image_info,
+                            size_t info_size) {
+    CephContext *cct = ictx->cct;
+    ldout(cct, 20) << __func__ << ": ictx=" << ictx << dendl;
+    if (info_size < sizeof(mirror_image_info_t)) {
+      return -ERANGE;
+    }
 
-    int r = cls_client::mirror_set_enabled(&io_ctx, enabled);
+    cls::rbd::MirrorImage mirror_image_internal;
+    int r = cls_client::mirror_image_get(&ictx->md_ctx, ictx->id,
+        &mirror_image_internal);
     if (r < 0 && r != -ENOENT) {
-      lderr(cct) << "Failed to set mirror flag: " << cpp_strerror(r) << dendl;
+      lderr(cct) << "failed to retrieve mirroring state: " << cpp_strerror(r)
+        << dendl;
       return r;
     }
+
+    mirror_image_info->global_id = mirror_image_internal.global_image_id;
+    if (r == -ENOENT) {
+      mirror_image_info->state = RBD_MIRROR_IMAGE_DISABLED;
+    } else {
+      mirror_image_info->state =
+        static_cast<rbd_mirror_image_state_t>(mirror_image_internal.state);
+    }
+
+    if (mirror_image_info->state == RBD_MIRROR_IMAGE_ENABLED) {
+      r = Journal<>::is_tag_owner(ictx, &mirror_image_info->primary);
+      if (r < 0) {
+        lderr(cct) << "failed to check tag ownership: "
+                   << cpp_strerror(r) << dendl;
+        return r;
+      }
+    } else {
+      mirror_image_info->primary = false;
+    }
+
     return 0;
   }
 
-  int mirror_peer_add(IoCtx& io_ctx, const std::string &cluster_uuid,
-                      const std::string &cluster_name,
-                      const std::string &client_name) {
+  int mirror_mode_get(IoCtx& io_ctx, rbd_mirror_mode_t *mirror_mode) {
     CephContext *cct = reinterpret_cast<CephContext *>(io_ctx.cct());
-    ldout(cct, 20) << __func__ << ": uuid=" << cluster_uuid << ", "
-                   << "name=" << cluster_name << ", "
-                   << "client=" << client_name << dendl;
+    ldout(cct, 20) << __func__ << dendl;
 
-    std::string local_cluster_uuid;
-    librados::Rados rados(io_ctx);
-    int r = rados.cluster_fsid(&local_cluster_uuid);
+    cls::rbd::MirrorMode mirror_mode_internal;
+    int r = cls_client::mirror_mode_get(&io_ctx, &mirror_mode_internal);
     if (r < 0) {
-      lderr(cct) << "Failed to retreive cluster uuid" << dendl;
+      lderr(cct) << "Failed to retrieve mirror mode: " << cpp_strerror(r)
+                 << dendl;
       return r;
     }
 
-    if (local_cluster_uuid == cluster_uuid) {
-      lderr(cct) << "Cannot add self as remote peer" << dendl;
+    switch (mirror_mode_internal) {
+    case cls::rbd::MIRROR_MODE_DISABLED:
+    case cls::rbd::MIRROR_MODE_IMAGE:
+    case cls::rbd::MIRROR_MODE_POOL:
+      *mirror_mode = static_cast<rbd_mirror_mode_t>(mirror_mode_internal);
+      break;
+    default:
+      lderr(cct) << "Unknown mirror mode ("
+                 << static_cast<uint32_t>(mirror_mode_internal) << ")"
+                 << dendl;
       return -EINVAL;
     }
+    return 0;
+  }
 
-    r = cls_client::mirror_peer_add(&io_ctx, cluster_uuid, cluster_name,
-                                    client_name);
+  int mirror_mode_set(IoCtx& io_ctx, rbd_mirror_mode_t mirror_mode) {
+    CephContext *cct = reinterpret_cast<CephContext *>(io_ctx.cct());
+    ldout(cct, 20) << __func__ << dendl;
+
+    cls::rbd::MirrorMode next_mirror_mode;
+    switch (mirror_mode) {
+    case RBD_MIRROR_MODE_DISABLED:
+    case RBD_MIRROR_MODE_IMAGE:
+    case RBD_MIRROR_MODE_POOL:
+      next_mirror_mode = static_cast<cls::rbd::MirrorMode>(mirror_mode);
+      break;
+    default:
+      lderr(cct) << "Unknown mirror mode ("
+                 << static_cast<uint32_t>(mirror_mode) << ")" << dendl;
+      return -EINVAL;
+    }
+
+    cls::rbd::MirrorMode current_mirror_mode;
+    int r = cls_client::mirror_mode_get(&io_ctx, &current_mirror_mode);
     if (r < 0) {
-      lderr(cct) << "Failed to add mirror peer '" << cluster_uuid << "': "
-                 << cpp_strerror(r) << dendl;
+      lderr(cct) << "Failed to retrieve mirror mode: " << cpp_strerror(r)
+                 << dendl;
+      return r;
+    }
+
+    if (current_mirror_mode == next_mirror_mode) {
+      return 0;
+    } else if (current_mirror_mode == cls::rbd::MIRROR_MODE_DISABLED) {
+      uuid_d uuid_gen;
+      uuid_gen.generate_random();
+      r = cls_client::mirror_uuid_set(&io_ctx, uuid_gen.to_string());
+      if (r < 0) {
+        lderr(cct) << "Failed to allocate mirroring uuid: " << cpp_strerror(r)
+                   << dendl;
+        return r;
+      }
+    }
+
+    r = cls_client::mirror_mode_set(&io_ctx, next_mirror_mode);
+    if (r < 0) {
+      lderr(cct) << "Failed to set mirror mode: " << cpp_strerror(r) << dendl;
       return r;
     }
     return 0;
   }
 
-  int mirror_peer_remove(IoCtx& io_ctx, const std::string &cluster_uuid) {
+  int mirror_peer_add(IoCtx& io_ctx, std::string *uuid,
+                      const std::string &cluster_name,
+                      const std::string &client_name) {
+    CephContext *cct = reinterpret_cast<CephContext *>(io_ctx.cct());
+    ldout(cct, 20) << __func__ << ": "
+                   << "name=" << cluster_name << ", "
+                   << "client=" << client_name << dendl;
+
+    if (cct->_conf->cluster == cluster_name) {
+      lderr(cct) << "Cannot add self as remote peer" << dendl;
+      return -EINVAL;
+    }
+
+    int r;
+    do {
+      uuid_d uuid_gen;
+      uuid_gen.generate_random();
+
+      *uuid = uuid_gen.to_string();
+      r = cls_client::mirror_peer_add(&io_ctx, *uuid, cluster_name,
+                                      client_name);
+      if (r == -ESTALE) {
+        ldout(cct, 5) << "Duplicate UUID detected, retrying" << dendl;
+      } else if (r < 0) {
+        lderr(cct) << "Failed to add mirror peer '" << uuid << "': "
+                   << cpp_strerror(r) << dendl;
+        return r;
+      }
+    } while (r == -ESTALE);
+    return 0;
+  }
+
+  int mirror_peer_remove(IoCtx& io_ctx, const std::string &uuid) {
     CephContext *cct = reinterpret_cast<CephContext *>(io_ctx.cct());
-    ldout(cct, 20) << __func__ << ": uuid=" << cluster_uuid << dendl;
+    ldout(cct, 20) << __func__ << ": uuid=" << uuid << dendl;
 
-    int r = cls_client::mirror_peer_remove(&io_ctx, cluster_uuid);
+    int r = cls_client::mirror_peer_remove(&io_ctx, uuid);
     if (r < 0 && r != -ENOENT) {
-      lderr(cct) << "Failed to remove peer '" << cluster_uuid << "': "
+      lderr(cct) << "Failed to remove peer '" << uuid << "': "
                  << cpp_strerror(r) << dendl;
       return r;
     }
@@ -2390,7 +2865,7 @@ int validate_pool(IoCtx &io_ctx, CephContext *cct) {
     peers->reserve(mirror_peers.size());
     for (auto &mirror_peer : mirror_peers) {
       mirror_peer_t peer;
-      peer.cluster_uuid = mirror_peer.cluster_uuid;
+      peer.uuid = mirror_peer.uuid;
       peer.cluster_name = mirror_peer.cluster_name;
       peer.client_name = mirror_peer.client_name;
       peers->push_back(peer);
@@ -2398,32 +2873,30 @@ int validate_pool(IoCtx &io_ctx, CephContext *cct) {
     return 0;
   }
 
-  int mirror_peer_set_client(IoCtx& io_ctx, const std::string &cluster_uuid,
+  int mirror_peer_set_client(IoCtx& io_ctx, const std::string &uuid,
                              const std::string &client_name) {
     CephContext *cct = reinterpret_cast<CephContext *>(io_ctx.cct());
-    ldout(cct, 20) << __func__ << ": uuid=" << cluster_uuid << ", "
+    ldout(cct, 20) << __func__ << ": uuid=" << uuid << ", "
                    << "client=" << client_name << dendl;
 
-    int r = cls_client::mirror_peer_set_client(&io_ctx, cluster_uuid,
-                                               client_name);
+    int r = cls_client::mirror_peer_set_client(&io_ctx, uuid, client_name);
     if (r < 0) {
-      lderr(cct) << "Failed to update client '" << cluster_uuid << "': "
+      lderr(cct) << "Failed to update client '" << uuid << "': "
                  << cpp_strerror(r) << dendl;
       return r;
     }
     return 0;
   }
 
-  int mirror_peer_set_cluster(IoCtx& io_ctx, const std::string &cluster_uuid,
+  int mirror_peer_set_cluster(IoCtx& io_ctx, const std::string &uuid,
                               const std::string &cluster_name) {
     CephContext *cct = reinterpret_cast<CephContext *>(io_ctx.cct());
-    ldout(cct, 20) << __func__ << ": uuid=" << cluster_uuid << ", "
+    ldout(cct, 20) << __func__ << ": uuid=" << uuid << ", "
                    << "cluster=" << cluster_name << dendl;
 
-    int r = cls_client::mirror_peer_set_cluster(&io_ctx, cluster_uuid,
-                                                cluster_name);
+    int r = cls_client::mirror_peer_set_cluster(&io_ctx, uuid, cluster_name);
     if (r < 0) {
-      lderr(cct) << "Failed to update cluster '" << cluster_uuid << "': "
+      lderr(cct) << "Failed to update cluster '" << uuid << "': "
                  << cpp_strerror(r) << dendl;
       return r;
     }
diff --git a/src/librbd/internal.h b/src/librbd/internal.h
index 9fac1c1..b92e572 100644
--- a/src/librbd/internal.h
+++ b/src/librbd/internal.h
@@ -142,8 +142,6 @@ namespace librbd {
 
   int read_header_bl(librados::IoCtx& io_ctx, const std::string& md_oid,
 		     ceph::bufferlist& header, uint64_t *ver);
-  int notify_change(librados::IoCtx& io_ctx, const std::string& oid,
-		    ImageCtx *ictx);
   int read_header(librados::IoCtx& io_ctx, const std::string& md_oid,
 		  struct rbd_obj_header_ondisk *header, uint64_t *ver);
   int tmap_set(librados::IoCtx& io_ctx, const std::string& imgname);
@@ -173,18 +171,25 @@ namespace librbd {
   int metadata_set(ImageCtx *ictx, const std::string &key, const std::string &value);
   int metadata_remove(ImageCtx *ictx, const std::string &key);
 
-  int mirror_is_enabled(IoCtx& io_ctx, bool *enabled);
-  int mirror_set_enabled(IoCtx& io_ctx, bool enabled);
-  int mirror_peer_add(IoCtx& io_ctx, const std::string &cluster_uuid,
+  int mirror_mode_get(IoCtx& io_ctx, rbd_mirror_mode_t *mirror_mode);
+  int mirror_mode_set(IoCtx& io_ctx, rbd_mirror_mode_t mirror_mode);
+  int mirror_peer_add(IoCtx& io_ctx, std::string *uuid,
                       const std::string &cluster_name,
                       const std::string &client_name);
-  int mirror_peer_remove(IoCtx& io_ctx, const std::string &cluster_uuid);
+  int mirror_peer_remove(IoCtx& io_ctx, const std::string &uuid);
   int mirror_peer_list(IoCtx& io_ctx, std::vector<mirror_peer_t> *peers);
-  int mirror_peer_set_client(IoCtx& io_ctx, const std::string &cluster_uuid,
+  int mirror_peer_set_client(IoCtx& io_ctx, const std::string &uuid,
                              const std::string &client_name);
-  int mirror_peer_set_cluster(IoCtx& io_ctx, const std::string &cluster_uuid,
+  int mirror_peer_set_cluster(IoCtx& io_ctx, const std::string &uuid,
                               const std::string &cluster_name);
 
+  int mirror_image_enable(ImageCtx *ictx);
+  int mirror_image_disable(ImageCtx *ictx, bool force);
+  int mirror_image_promote(ImageCtx *ictx, bool force);
+  int mirror_image_demote(ImageCtx *ictx);
+  int mirror_image_resync(ImageCtx *ictx);
+  int mirror_image_get_info(ImageCtx *ictx, mirror_image_info_t *mirror_image_info,
+                            size_t info_size);
 }
 
 #endif
diff --git a/src/librbd/journal/Replay.cc b/src/librbd/journal/Replay.cc
index c2cddde..55ba5f3 100644
--- a/src/librbd/journal/Replay.cc
+++ b/src/librbd/journal/Replay.cc
@@ -8,6 +8,8 @@
 #include "librbd/AioCompletion.h"
 #include "librbd/AioImageRequest.h"
 #include "librbd/ImageCtx.h"
+#include "librbd/ImageState.h"
+#include "librbd/ImageWatcher.h"
 #include "librbd/internal.h"
 #include "librbd/Operations.h"
 #include "librbd/Utils.h"
@@ -26,6 +28,89 @@ static const uint64_t IN_FLIGHT_IO_HIGH_WATER_MARK(64);
 
 static NoOpProgressContext no_op_progress_callback;
 
+template <typename I, typename E>
+struct ExecuteOp : public Context {
+  I &image_ctx;
+  E event;
+  Context *on_op_complete;
+
+  ExecuteOp(I &image_ctx, const E &event, Context *on_op_complete)
+    : image_ctx(image_ctx), event(event), on_op_complete(on_op_complete) {
+  }
+
+  void execute(const journal::SnapCreateEvent &_) {
+    image_ctx.operations->execute_snap_create(event.snap_name.c_str(),
+                                              on_op_complete,
+                                              event.op_tid);
+  }
+
+  void execute(const journal::SnapRemoveEvent &_) {
+    image_ctx.operations->execute_snap_remove(event.snap_name.c_str(),
+                                              on_op_complete);
+  }
+
+  void execute(const journal::SnapRenameEvent &_) {
+    image_ctx.operations->execute_snap_rename(event.snap_id,
+                                              event.snap_name.c_str(),
+                                              on_op_complete);
+  }
+
+  void execute(const journal::SnapProtectEvent &_) {
+    image_ctx.operations->execute_snap_protect(event.snap_name.c_str(),
+                                               on_op_complete);
+  }
+
+  void execute(const journal::SnapUnprotectEvent &_) {
+    image_ctx.operations->execute_snap_unprotect(event.snap_name.c_str(),
+                                                 on_op_complete);
+  }
+
+  void execute(const journal::SnapRollbackEvent &_) {
+    image_ctx.operations->execute_snap_rollback(event.snap_name.c_str(),
+                                                no_op_progress_callback,
+                                                on_op_complete);
+  }
+
+  void execute(const journal::RenameEvent &_) {
+    image_ctx.operations->execute_rename(event.image_name.c_str(),
+                                         on_op_complete);
+  }
+
+  void execute(const journal::ResizeEvent &_) {
+    image_ctx.operations->execute_resize(event.size, no_op_progress_callback,
+                                         on_op_complete, event.op_tid);
+  }
+
+  void execute(const journal::FlattenEvent &_) {
+    image_ctx.operations->execute_flatten(no_op_progress_callback,
+                                          on_op_complete);
+  }
+
+  virtual void finish(int r) override {
+    RWLock::RLocker owner_locker(image_ctx.owner_lock);
+    execute(event);
+  }
+};
+
+template <typename I>
+struct C_RefreshIfRequired : public Context {
+  I &image_ctx;
+  Context *on_finish;
+
+  C_RefreshIfRequired(I &image_ctx, Context *on_finish)
+    : image_ctx(image_ctx), on_finish(on_finish) {
+  }
+
+  virtual void finish(int r) override {
+    if (image_ctx.state->is_refresh_required()) {
+      image_ctx.state->refresh(on_finish);
+      return;
+    }
+
+    image_ctx.op_work_queue->queue(on_finish, 0);
+  }
+};
+
 } // anonymous namespace
 
 template <typename I>
@@ -35,7 +120,8 @@ Replay<I>::Replay(I &image_ctx)
 
 template <typename I>
 Replay<I>::~Replay() {
-  assert(m_in_flight_aio == 0);
+  assert(m_in_flight_aio_flush == 0);
+  assert(m_in_flight_aio_modify == 0);
   assert(m_aio_modify_unsafe_contexts.empty());
   assert(m_aio_modify_safe_contexts.empty());
   assert(m_op_events.empty());
@@ -45,7 +131,8 @@ template <typename I>
 void Replay<I>::process(bufferlist::iterator *it, Context *on_ready,
                         Context *on_safe) {
   CephContext *cct = m_image_ctx.cct;
-  ldout(cct, 20) << this << " " << __func__ << dendl;
+  ldout(cct, 20) << this << " " << __func__ << ": "
+                 << "on_ready=" << on_ready << ", on_safe=" << on_safe << dendl;
 
   on_ready = util::create_async_context_callback(m_image_ctx, on_ready);
 
@@ -64,12 +151,13 @@ void Replay<I>::process(bufferlist::iterator *it, Context *on_ready,
 }
 
 template <typename I>
-void Replay<I>::flush(Context *on_finish) {
+void Replay<I>::shut_down(bool cancel_ops, Context *on_finish) {
   CephContext *cct = m_image_ctx.cct;
   ldout(cct, 20) << this << " " << __func__ << dendl;
 
   AioCompletion *flush_comp = nullptr;
   OpTids cancel_op_tids;
+  Contexts op_finish_events;
   on_finish = util::create_async_context_callback(
     m_image_ctx, on_finish);
 
@@ -77,20 +165,32 @@ void Replay<I>::flush(Context *on_finish) {
     Mutex::Locker locker(m_lock);
 
     // safely commit any remaining AIO modify operations
-    if (m_in_flight_aio != 0) {
+    if ((m_in_flight_aio_flush + m_in_flight_aio_modify) != 0) {
       flush_comp = create_aio_flush_completion(nullptr, nullptr);;
     }
 
-    // cancel ops that are waiting to start
     for (auto &op_event_pair : m_op_events) {
-      const OpEvent &op_event = op_event_pair.second;
-      if (op_event.on_start_ready == nullptr) {
-        cancel_op_tids.push_back(op_event_pair.first);
+      OpEvent &op_event = op_event_pair.second;
+      if (cancel_ops) {
+        // cancel ops that are waiting to start (waiting for
+        // OpFinishEvent or waiting for ready)
+        if (op_event.on_start_ready == nullptr &&
+            op_event.on_op_finish_event != nullptr) {
+          cancel_op_tids.push_back(op_event_pair.first);
+        }
+      } else if (op_event.on_op_finish_event != nullptr) {
+        // start ops waiting for OpFinishEvent
+        Context *on_op_finish_event = nullptr;
+        std::swap(on_op_finish_event, op_event.on_op_finish_event);
+        m_image_ctx.op_work_queue->queue(on_op_finish_event, 0);
+      } else if (op_event.on_start_ready != nullptr) {
+        // waiting for op ready
+        op_event_pair.second.finish_on_ready = true;
       }
     }
 
     assert(m_flush_ctx == nullptr);
-    if (!m_op_events.empty() || m_in_flight_aio != 0) {
+    if (!m_op_events.empty() || flush_comp != nullptr) {
       std::swap(m_flush_ctx, on_finish);
     }
   }
@@ -109,10 +209,24 @@ void Replay<I>::flush(Context *on_finish) {
 }
 
 template <typename I>
+void Replay<I>::flush(Context *on_finish) {
+  AioCompletion *aio_comp;
+  {
+    Mutex::Locker locker(m_lock);
+    aio_comp = create_aio_flush_completion(
+      nullptr, util::create_async_context_callback(m_image_ctx, on_finish));
+  }
+
+  RWLock::RLocker owner_locker(m_image_ctx.owner_lock);
+  AioImageRequest<I>::aio_flush(&m_image_ctx, aio_comp);
+}
+
+template <typename I>
 void Replay<I>::replay_op_ready(uint64_t op_tid, Context *on_resume) {
   CephContext *cct = m_image_ctx.cct;
   ldout(cct, 20) << this << " " << __func__ << ": op_tid=" << op_tid << dendl;
 
+  Mutex::Locker locker(m_lock);
   auto op_it = m_op_events.find(op_tid);
   assert(op_it != m_op_events.end());
 
@@ -128,7 +242,7 @@ void Replay<I>::replay_op_ready(uint64_t op_tid, Context *on_resume) {
   on_start_ready->complete(0);
 
   // cancel has been requested -- send error to paused state machine
-  if (m_flush_ctx != nullptr) {
+  if (!op_event.finish_on_ready && m_flush_ctx != nullptr) {
     m_image_ctx.op_work_queue->queue(on_resume, -ERESTART);
     return;
   }
@@ -139,6 +253,11 @@ void Replay<I>::replay_op_ready(uint64_t op_tid, Context *on_resume) {
     [on_resume](int r) {
       on_resume->complete(r);
     });
+
+  // shut down request -- don't expect OpFinishEvent
+  if (op_event.finish_on_ready) {
+    m_image_ctx.op_work_queue->queue(on_resume, 0);
+  }
 }
 
 template <typename I>
@@ -204,6 +323,7 @@ void Replay<I>::handle_event(const journal::OpFinishEvent &event,
                  << "op_tid=" << event.op_tid << dendl;
 
   bool op_in_progress;
+  Context *on_op_complete = nullptr;
   Context *on_op_finish_event = nullptr;
   {
     Mutex::Locker locker(m_lock);
@@ -221,6 +341,7 @@ void Replay<I>::handle_event(const journal::OpFinishEvent &event,
     op_event.on_finish_ready = on_ready;
     op_event.on_finish_safe = on_safe;
     op_in_progress = op_event.op_in_progress;
+    std::swap(on_op_complete, op_event.on_op_complete);
     std::swap(on_op_finish_event, op_event.on_op_finish_event);
   }
 
@@ -229,9 +350,13 @@ void Replay<I>::handle_event(const journal::OpFinishEvent &event,
       // bubble the error up to the in-progress op to cancel it
       on_op_finish_event->complete(event.r);
     } else {
-      // op hasn't been started -- no-op the event
+      // op hasn't been started -- bubble the error up since
+      // our image is now potentially in an inconsistent state
+      // since simple errors should have been caught before
+      // creating the op event
+      delete on_op_complete;
       delete on_op_finish_event;
-      handle_op_complete(event.op_tid, 0);
+      handle_op_complete(event.op_tid, event.r);
     }
     return;
   }
@@ -248,11 +373,20 @@ void Replay<I>::handle_event(const journal::SnapCreateEvent &event,
 
   Mutex::Locker locker(m_lock);
   OpEvent *op_event;
-  Context *on_op_complete = create_op_context_callback(event.op_tid, on_safe,
-                                                       &op_event);
+  Context *on_op_complete = create_op_context_callback(event.op_tid, on_ready,
+                                                       on_safe, &op_event);
+  if (on_op_complete == nullptr) {
+    return;
+  }
+
+  // ignore errors caused due to replay
+  op_event->ignore_error_codes = {-EEXIST};
 
-  m_image_ctx.operations->snap_create(event.snap_name.c_str(), on_op_complete,
-                                      event.op_tid);
+  // avoid lock cycles
+  m_image_ctx.op_work_queue->queue(new C_RefreshIfRequired<I>(
+    m_image_ctx, new ExecuteOp<I, journal::SnapCreateEvent>(m_image_ctx, event,
+                                                            on_op_complete)),
+    0);
 
   // do not process more events until the state machine is ready
   // since it will affect IO
@@ -268,13 +402,18 @@ void Replay<I>::handle_event(const journal::SnapRemoveEvent &event,
 
   Mutex::Locker locker(m_lock);
   OpEvent *op_event;
-  Context *on_op_complete = create_op_context_callback(event.op_tid, on_safe,
-                                                       &op_event);
-  op_event->on_op_finish_event = new FunctionContext(
-    [this, event, on_op_complete](int r) {
-      m_image_ctx.operations->snap_remove(event.snap_name.c_str(),
-                                          on_op_complete);
-    });
+  Context *on_op_complete = create_op_context_callback(event.op_tid, on_ready,
+                                                       on_safe, &op_event);
+  if (on_op_complete == nullptr) {
+    return;
+  }
+
+  op_event->on_op_finish_event = new C_RefreshIfRequired<I>(
+    m_image_ctx, new ExecuteOp<I, journal::SnapRemoveEvent>(m_image_ctx, event,
+                                                            on_op_complete));
+
+  // ignore errors caused due to replay
+  op_event->ignore_error_codes = {-ENOENT};
 
   on_ready->complete(0);
 }
@@ -287,14 +426,18 @@ void Replay<I>::handle_event(const journal::SnapRenameEvent &event,
 
   Mutex::Locker locker(m_lock);
   OpEvent *op_event;
-  Context *on_op_complete = create_op_context_callback(event.op_tid, on_safe,
-                                                       &op_event);
-  op_event->on_op_finish_event = new FunctionContext(
-    [this, event, on_op_complete](int r) {
-      m_image_ctx.operations->snap_rename(event.snap_id,
-                                          event.snap_name.c_str(),
-                                          on_op_complete);
-    });
+  Context *on_op_complete = create_op_context_callback(event.op_tid, on_ready,
+                                                       on_safe, &op_event);
+  if (on_op_complete == nullptr) {
+    return;
+  }
+
+  op_event->on_op_finish_event = new C_RefreshIfRequired<I>(
+    m_image_ctx, new ExecuteOp<I, journal::SnapRenameEvent>(m_image_ctx, event,
+                                                            on_op_complete));
+
+  // ignore errors caused due to replay
+  op_event->ignore_error_codes = {-EEXIST};
 
   on_ready->complete(0);
 }
@@ -307,13 +450,18 @@ void Replay<I>::handle_event(const journal::SnapProtectEvent &event,
 
   Mutex::Locker locker(m_lock);
   OpEvent *op_event;
-  Context *on_op_complete = create_op_context_callback(event.op_tid, on_safe,
-                                                       &op_event);
-  op_event->on_op_finish_event = new FunctionContext(
-    [this, event, on_op_complete](int r) {
-      m_image_ctx.operations->snap_protect(event.snap_name.c_str(),
-                                           on_op_complete);
-    });
+  Context *on_op_complete = create_op_context_callback(event.op_tid, on_ready,
+                                                       on_safe, &op_event);
+  if (on_op_complete == nullptr) {
+    return;
+  }
+
+  op_event->on_op_finish_event = new C_RefreshIfRequired<I>(
+    m_image_ctx, new ExecuteOp<I, journal::SnapProtectEvent>(m_image_ctx, event,
+                                                             on_op_complete));
+
+  // ignore errors caused due to replay
+  op_event->ignore_error_codes = {-EBUSY};
 
   on_ready->complete(0);
 }
@@ -327,13 +475,19 @@ void Replay<I>::handle_event(const journal::SnapUnprotectEvent &event,
 
   Mutex::Locker locker(m_lock);
   OpEvent *op_event;
-  Context *on_op_complete = create_op_context_callback(event.op_tid, on_safe,
-                                                       &op_event);
-  op_event->on_op_finish_event = new FunctionContext(
-    [this, event, on_op_complete](int r) {
-      m_image_ctx.operations->snap_unprotect(event.snap_name.c_str(),
-                                             on_op_complete);
-    });
+  Context *on_op_complete = create_op_context_callback(event.op_tid, on_ready,
+                                                       on_safe, &op_event);
+  if (on_op_complete == nullptr) {
+    return;
+  }
+
+  op_event->on_op_finish_event = new C_RefreshIfRequired<I>(
+    m_image_ctx, new ExecuteOp<I, journal::SnapUnprotectEvent>(m_image_ctx,
+                                                               event,
+                                                               on_op_complete));
+
+  // ignore errors caused due to replay
+  op_event->ignore_error_codes = {-EINVAL};
 
   on_ready->complete(0);
 }
@@ -347,14 +501,16 @@ void Replay<I>::handle_event(const journal::SnapRollbackEvent &event,
 
   Mutex::Locker locker(m_lock);
   OpEvent *op_event;
-  Context *on_op_complete = create_op_context_callback(event.op_tid, on_safe,
-                                                       &op_event);
-  op_event->on_op_finish_event = new FunctionContext(
-    [this, event, on_op_complete](int r) {
-      m_image_ctx.operations->snap_rollback(event.snap_name.c_str(),
-                                            no_op_progress_callback,
-                                            on_op_complete);
-    });
+  Context *on_op_complete = create_op_context_callback(event.op_tid, on_ready,
+                                                       on_safe, &op_event);
+  if (on_op_complete == nullptr) {
+    return;
+  }
+
+  op_event->on_op_finish_event = new C_RefreshIfRequired<I>(
+    m_image_ctx, new ExecuteOp<I, journal::SnapRollbackEvent>(m_image_ctx,
+                                                              event,
+                                                              on_op_complete));
 
   on_ready->complete(0);
 }
@@ -367,12 +523,18 @@ void Replay<I>::handle_event(const journal::RenameEvent &event,
 
   Mutex::Locker locker(m_lock);
   OpEvent *op_event;
-  Context *on_op_complete = create_op_context_callback(event.op_tid, on_safe,
-                                                       &op_event);
-  op_event->on_op_finish_event = new FunctionContext(
-    [this, event, on_op_complete](int r) {
-      m_image_ctx.operations->rename(event.image_name.c_str(), on_op_complete);
-    });
+  Context *on_op_complete = create_op_context_callback(event.op_tid, on_ready,
+                                                       on_safe, &op_event);
+  if (on_op_complete == nullptr) {
+    return;
+  }
+
+  op_event->on_op_finish_event = new C_RefreshIfRequired<I>(
+    m_image_ctx, new ExecuteOp<I, journal::RenameEvent>(m_image_ctx, event,
+                                                        on_op_complete));
+
+  // ignore errors caused due to replay
+  op_event->ignore_error_codes = {-EEXIST};
 
   on_ready->complete(0);
 }
@@ -385,11 +547,16 @@ void Replay<I>::handle_event(const journal::ResizeEvent &event,
 
   Mutex::Locker locker(m_lock);
   OpEvent *op_event;
-  Context *on_op_complete = create_op_context_callback(event.op_tid, on_safe,
-                                                       &op_event);
+  Context *on_op_complete = create_op_context_callback(event.op_tid, on_ready,
+                                                       on_safe, &op_event);
+  if (on_op_complete == nullptr) {
+    return;
+  }
 
-  m_image_ctx.operations->resize(event.size, no_op_progress_callback,
-                                 on_op_complete, event.op_tid);
+  // avoid lock cycles
+  m_image_ctx.op_work_queue->queue(new C_RefreshIfRequired<I>(
+    m_image_ctx, new ExecuteOp<I, journal::ResizeEvent>(m_image_ctx, event,
+                                                        on_op_complete)), 0);
 
   // do not process more events until the state machine is ready
   // since it will affect IO
@@ -405,12 +572,18 @@ void Replay<I>::handle_event(const journal::FlattenEvent &event,
 
   Mutex::Locker locker(m_lock);
   OpEvent *op_event;
-  Context *on_op_complete = create_op_context_callback(event.op_tid, on_safe,
-                                                       &op_event);
-  op_event->on_op_finish_event = new FunctionContext(
-    [this, event, on_op_complete](int r) {
-      m_image_ctx.operations->flatten(no_op_progress_callback, on_op_complete);
-    });
+  Context *on_op_complete = create_op_context_callback(event.op_tid, on_ready,
+                                                       on_safe, &op_event);
+  if (on_op_complete == nullptr) {
+    return;
+  }
+
+  op_event->on_op_finish_event = new C_RefreshIfRequired<I>(
+    m_image_ctx, new ExecuteOp<I, journal::FlattenEvent>(m_image_ctx, event,
+                                                         on_op_complete));
+
+  // ignore errors caused due to replay
+  op_event->ignore_error_codes = {-EINVAL};
 
   on_ready->complete(0);
 }
@@ -425,12 +598,16 @@ void Replay<I>::handle_event(const journal::UnknownEvent &event,
 }
 
 template <typename I>
-void Replay<I>::handle_aio_modify_complete(Context *on_safe, int r) {
+void Replay<I>::handle_aio_modify_complete(Context *on_ready, Context *on_safe,
+                                           int r) {
   Mutex::Locker locker(m_lock);
   CephContext *cct = m_image_ctx.cct;
-  ldout(cct, 20) << this << " " << __func__ << ": on_safe=" << on_safe << ", "
-                 << "r=" << r << dendl;
+  ldout(cct, 20) << this << " " << __func__ << ": on_ready=" << on_ready << ", "
+                 << "on_safe=" << on_safe << ", r=" << r << dendl;
 
+  if (on_ready != nullptr) {
+    on_ready->complete(0);
+  }
   if (r < 0) {
     lderr(cct) << "AIO modify op failed: " << cpp_strerror(r) << dendl;
     on_safe->complete(r);
@@ -455,11 +632,14 @@ void Replay<I>::handle_aio_flush_complete(Context *on_flush_safe,
   Context *on_flush = nullptr;
   {
     Mutex::Locker locker(m_lock);
-    assert(m_in_flight_aio >= on_safe_ctxs.size());
-    m_in_flight_aio -= on_safe_ctxs.size();
+    assert(m_in_flight_aio_flush > 0);
+    assert(m_in_flight_aio_modify >= on_safe_ctxs.size());
+    --m_in_flight_aio_flush;
+    m_in_flight_aio_modify -= on_safe_ctxs.size();
 
     std::swap(on_aio_ready, m_on_aio_ready);
-    if (m_op_events.empty() && m_in_flight_aio == 0) {
+    if (m_op_events.empty() &&
+        (m_in_flight_aio_flush + m_in_flight_aio_modify) == 0) {
       on_flush = m_flush_ctx;
     }
 
@@ -477,26 +657,42 @@ void Replay<I>::handle_aio_flush_complete(Context *on_flush_safe,
     ldout(cct, 10) << "resuming paused AIO" << dendl;
     on_aio_ready->complete(0);
   }
+
+  if (on_flush_safe != nullptr) {
+    on_safe_ctxs.push_back(on_flush_safe);
+  }
   for (auto ctx : on_safe_ctxs) {
+    ldout(cct, 20) << "completing safe context: " << ctx << dendl;
     ctx->complete(r);
   }
-  if (on_flush_safe != nullptr) {
-    on_flush_safe->complete(r);
-  }
+
   if (on_flush != nullptr) {
+    ldout(cct, 20) << "completing flush context: " << on_flush << dendl;
     on_flush->complete(r);
   }
 }
 
 template <typename I>
 Context *Replay<I>::create_op_context_callback(uint64_t op_tid,
+                                               Context *on_ready,
                                                Context *on_safe,
                                                OpEvent **op_event) {
+  CephContext *cct = m_image_ctx.cct;
+
   assert(m_lock.is_locked());
+  if (m_op_events.count(op_tid) != 0) {
+    lderr(cct) << "duplicate op tid detected: " << op_tid << dendl;
+    on_ready->complete(0);
+    on_safe->complete(-EINVAL);
+    return nullptr;
+  }
 
   *op_event = &m_op_events[op_tid];
   (*op_event)->on_start_safe = on_safe;
-  return new C_OpOnComplete(this, op_tid);
+
+  Context *on_op_complete = new C_OpOnComplete(this, op_tid);
+  (*op_event)->on_op_complete = on_op_complete;
+  return on_op_complete;
 }
 
 template <typename I>
@@ -507,6 +703,7 @@ void Replay<I>::handle_op_complete(uint64_t op_tid, int r) {
 
   OpEvent op_event;
   Context *on_flush = nullptr;
+  bool shutting_down = false;
   {
     Mutex::Locker locker(m_lock);
     auto op_it = m_op_events.find(op_tid);
@@ -515,22 +712,41 @@ void Replay<I>::handle_op_complete(uint64_t op_tid, int r) {
     op_event = std::move(op_it->second);
     m_op_events.erase(op_it);
 
-    if (m_op_events.empty() && m_in_flight_aio == 0) {
+    shutting_down = (m_flush_ctx != nullptr);
+    if (m_op_events.empty() &&
+        (m_in_flight_aio_flush + m_in_flight_aio_modify) == 0) {
       on_flush = m_flush_ctx;
     }
   }
 
-  assert(op_event.on_start_ready == nullptr);
-  assert((op_event.on_finish_ready != nullptr &&
-          op_event.on_finish_safe != nullptr) || r == -ERESTART);
+  assert(op_event.on_start_ready == nullptr || (r < 0 && r != -ERESTART));
+  if (op_event.on_start_ready != nullptr) {
+    // blocking op event failed before it became ready
+    assert(op_event.on_finish_ready == nullptr &&
+           op_event.on_finish_safe == nullptr);
+
+    op_event.on_start_ready->complete(0);
+  } else {
+    // event kicked off by OpFinishEvent
+    assert((op_event.on_finish_ready != nullptr &&
+            op_event.on_finish_safe != nullptr) || shutting_down);
+  }
 
   // skipped upon error -- so clean up if non-null
   delete op_event.on_op_finish_event;
+  if (r == -ERESTART) {
+    delete op_event.on_op_complete;
+  }
 
   if (op_event.on_finish_ready != nullptr) {
     op_event.on_finish_ready->complete(0);
   }
 
+  // filter out errors caused by replay of the same op
+  if (r < 0 && op_event.ignore_error_codes.count(r) != 0) {
+    r = 0;
+  }
+
   op_event.on_start_safe->complete(r);
   if (op_event.on_finish_safe != nullptr) {
     op_event.on_finish_safe->complete(r);
@@ -548,18 +764,13 @@ AioCompletion *Replay<I>::create_aio_modify_completion(Context *on_ready,
   CephContext *cct = m_image_ctx.cct;
   assert(m_on_aio_ready == nullptr);
 
-  ++m_in_flight_aio;
+  ++m_in_flight_aio_modify;
   m_aio_modify_unsafe_contexts.push_back(on_safe);
 
   // FLUSH if we hit the low-water mark -- on_safe contexts are
   // completed by flushes-only so that we don't move the journal
   // commit position until safely on-disk
 
-  // when safe, the completion of the next flush will fire the on_safe
-  // callback
-  AioCompletion *aio_comp = AioCompletion::create<Context>(
-    new C_AioModifyComplete(this, on_safe));
-
   *flush_required = (m_aio_modify_unsafe_contexts.size() ==
                        IN_FLIGHT_IO_LOW_WATER_MARK);
   if (*flush_required) {
@@ -572,14 +783,18 @@ AioCompletion *Replay<I>::create_aio_modify_completion(Context *on_ready,
   // * in-flight ops are at a consistent point (snap create has IO flushed,
   //   shrink has adjusted clip boundary, etc) -- should have already been
   //   flagged not-ready
-  if (m_in_flight_aio == IN_FLIGHT_IO_HIGH_WATER_MARK) {
+  if (m_in_flight_aio_modify == IN_FLIGHT_IO_HIGH_WATER_MARK) {
     ldout(cct, 10) << "hit AIO replay high-water mark: pausing replay"
                    << dendl;
-    m_on_aio_ready = on_ready;
-  } else {
-    on_ready->complete(0);
+    assert(m_on_aio_ready == nullptr);
+    std::swap(m_on_aio_ready, on_ready);
   }
 
+  // when the modification is ACKed by librbd, we can process the next
+  // event. when flushed, the completion of the next flush will fire the
+  // on_safe callback
+  AioCompletion *aio_comp = AioCompletion::create<Context>(
+    new C_AioModifyComplete(this, on_ready, on_safe));
   return aio_comp;
 }
 
@@ -588,6 +803,8 @@ AioCompletion *Replay<I>::create_aio_flush_completion(Context *on_ready,
                                                       Context *on_safe) {
   assert(m_lock.is_locked());
 
+  ++m_in_flight_aio_flush;
+
   // associate all prior write/discard ops to this flush request
   AioCompletion *aio_comp = AioCompletion::create<Context>(
       new C_AioFlushComplete(this, on_safe,
diff --git a/src/librbd/journal/Replay.h b/src/librbd/journal/Replay.h
index e0fad8a..5be3406 100644
--- a/src/librbd/journal/Replay.h
+++ b/src/librbd/journal/Replay.h
@@ -34,18 +34,25 @@ public:
   ~Replay();
 
   void process(bufferlist::iterator *it, Context *on_ready, Context *on_safe);
+
+  void shut_down(bool cancel_ops, Context *on_finish);
   void flush(Context *on_finish);
 
   void replay_op_ready(uint64_t op_tid, Context *on_resume);
 
 private:
+  typedef std::unordered_set<int> ReturnValues;
+
   struct OpEvent {
     bool op_in_progress = false;
+    bool finish_on_ready = false;
     Context *on_op_finish_event = nullptr;
     Context *on_start_ready = nullptr;
     Context *on_start_safe = nullptr;
     Context *on_finish_ready = nullptr;
     Context *on_finish_safe = nullptr;
+    Context *on_op_complete = nullptr;
+    ReturnValues ignore_error_codes;
   };
 
   typedef std::list<uint64_t> OpTids;
@@ -66,12 +73,13 @@ private:
 
   struct C_AioModifyComplete : public Context {
     Replay *replay;
+    Context *on_ready;
     Context *on_safe;
-    C_AioModifyComplete(Replay *replay, Context *on_safe)
-      : replay(replay), on_safe(on_safe) {
+    C_AioModifyComplete(Replay *replay, Context *on_ready, Context *on_safe)
+      : replay(replay), on_ready(on_ready), on_safe(on_safe) {
     }
     virtual void finish(int r) {
-      replay->handle_aio_modify_complete(on_safe, r);
+      replay->handle_aio_modify_complete(on_ready, on_safe, r);
     }
   };
 
@@ -108,7 +116,8 @@ private:
 
   Mutex m_lock;
 
-  uint64_t m_in_flight_aio = 0;
+  uint64_t m_in_flight_aio_flush = 0;
+  uint64_t m_in_flight_aio_modify = 0;
   Contexts m_aio_modify_unsafe_contexts;
   ContextSet m_aio_modify_safe_contexts;
 
@@ -146,12 +155,12 @@ private:
   void handle_event(const UnknownEvent &event, Context *on_ready,
                     Context *on_safe);
 
-  void handle_aio_modify_complete(Context *on_safe, int r);
+  void handle_aio_modify_complete(Context *on_ready, Context *on_safe, int r);
   void handle_aio_flush_complete(Context *on_flush_safe, Contexts &on_safe_ctxs,
                                  int r);
 
-  Context *create_op_context_callback(uint64_t op_tid, Context *on_safe,
-                                      OpEvent **op_event);
+  Context *create_op_context_callback(uint64_t op_tid, Context *on_ready,
+                                      Context *on_safe, OpEvent **op_event);
   void handle_op_complete(uint64_t op_tid, int r);
 
   AioCompletion *create_aio_modify_completion(Context *on_ready,
diff --git a/src/librbd/journal/Types.cc b/src/librbd/journal/Types.cc
index 781f793..86fc7e0 100644
--- a/src/librbd/journal/Types.cc
+++ b/src/librbd/journal/Types.cc
@@ -4,6 +4,7 @@
 #include "librbd/journal/Types.h"
 #include "include/assert.h"
 #include "include/stringify.h"
+#include "include/types.h"
 #include "common/Formatter.h"
 
 namespace librbd {
@@ -323,32 +324,81 @@ void EventEntry::generate_test_instances(std::list<EventEntry *> &o) {
 
 void ImageClientMeta::encode(bufferlist& bl) const {
   ::encode(tag_class, bl);
+  ::encode(resync_requested, bl);
 }
 
 void ImageClientMeta::decode(__u8 version, bufferlist::iterator& it) {
   ::decode(tag_class, it);
+  ::decode(resync_requested, it);
 }
 
 void ImageClientMeta::dump(Formatter *f) const {
   f->dump_unsigned("tag_class", tag_class);
+  f->dump_bool("resync_requested", resync_requested);
+}
+
+void MirrorPeerSyncPoint::encode(bufferlist& bl) const {
+  ::encode(snap_name, bl);
+  ::encode(from_snap_name, bl);
+  ::encode(object_number, bl);
+}
+
+void MirrorPeerSyncPoint::decode(__u8 version, bufferlist::iterator& it) {
+  ::decode(snap_name, it);
+  ::decode(from_snap_name, it);
+  ::decode(object_number, it);
+}
+
+void MirrorPeerSyncPoint::dump(Formatter *f) const {
+  f->dump_string("snap_name", snap_name);
+  f->dump_string("from_snap_name", from_snap_name);
+  if (object_number) {
+    f->dump_unsigned("object_number", *object_number);
+  }
 }
 
 void MirrorPeerClientMeta::encode(bufferlist& bl) const {
-  ::encode(cluster_id, bl);
-  ::encode(pool_id, bl);
   ::encode(image_id, bl);
+  ::encode(sync_object_count, bl);
+  ::encode(static_cast<uint32_t>(sync_points.size()), bl);
+  for (auto &sync_point : sync_points) {
+    sync_point.encode(bl);
+  }
+  ::encode(snap_seqs, bl);
 }
 
 void MirrorPeerClientMeta::decode(__u8 version, bufferlist::iterator& it) {
-  ::decode(cluster_id, it);
-  ::decode(pool_id, it);
   ::decode(image_id, it);
+  ::decode(sync_object_count, it);
+
+  uint32_t sync_point_count;
+  ::decode(sync_point_count, it);
+  sync_points.resize(sync_point_count);
+  for (auto &sync_point : sync_points) {
+    sync_point.decode(version, it);
+  }
+
+  ::decode(snap_seqs, it);
 }
 
 void MirrorPeerClientMeta::dump(Formatter *f) const {
-  f->dump_string("cluster_id", cluster_id.c_str());
-  f->dump_int("pool_id", pool_id);
-  f->dump_string("image_id", image_id.c_str());
+  f->dump_string("image_id", image_id);
+  f->dump_unsigned("sync_object_count", sync_object_count);
+  f->open_array_section("sync_points");
+  for (auto &sync_point : sync_points) {
+    f->open_object_section("sync_point");
+    sync_point.dump(f);
+    f->close_section();
+  }
+  f->close_section();
+  f->open_array_section("snap_seqs");
+  for (auto &pair : snap_seqs) {
+    f->open_object_section("snap_seq");
+    f->dump_unsigned("local_snap_seq", pair.first);
+    f->dump_unsigned("peer_snap_seq", pair.second);
+    f->close_section();
+  }
+  f->close_section();
 }
 
 void CliClientMeta::encode(bufferlist& bl) const {
@@ -414,46 +464,46 @@ void ClientData::generate_test_instances(std::list<ClientData *> &o) {
   o.push_back(new ClientData(ImageClientMeta()));
   o.push_back(new ClientData(ImageClientMeta(123)));
   o.push_back(new ClientData(MirrorPeerClientMeta()));
-  o.push_back(new ClientData(MirrorPeerClientMeta("cluster_id", 123, "image_id")));
+  o.push_back(new ClientData(MirrorPeerClientMeta("image_id",
+                                                  {{"snap 2", "snap 1", 123}},
+                                                  {{1, 2}, {3, 4}})));
   o.push_back(new ClientData(CliClientMeta()));
 }
 
 // Journal Tag
 
 void TagData::encode(bufferlist& bl) const {
-  ::encode(cluster_id, bl);
-  ::encode(pool_id, bl);
-  ::encode(image_id, bl);
+  ::encode(mirror_uuid, bl);
+  ::encode(predecessor_mirror_uuid, bl);
+  ::encode(predecessor_commit_valid, bl);
   ::encode(predecessor_tag_tid, bl);
   ::encode(predecessor_entry_tid, bl);
 }
 
 void TagData::decode(bufferlist::iterator& it) {
-  ::decode(cluster_id, it);
-  ::decode(pool_id, it);
-  ::decode(image_id, it);
+  ::decode(mirror_uuid, it);
+  ::decode(predecessor_mirror_uuid, it);
+  ::decode(predecessor_commit_valid, it);
   ::decode(predecessor_tag_tid, it);
   ::decode(predecessor_entry_tid, it);
 }
 
 void TagData::dump(Formatter *f) const {
-  f->dump_string("cluster_id", cluster_id.c_str());
-  f->dump_int("pool_id", pool_id);
-  f->dump_string("image_id", image_id.c_str());
+  f->dump_string("mirror_uuid", mirror_uuid);
+  f->dump_string("predecessor_mirror_uuid", predecessor_mirror_uuid);
+  f->dump_string("predecessor_commit_valid",
+                 predecessor_commit_valid ? "true" : "false");
   f->dump_unsigned("predecessor_tag_tid", predecessor_tag_tid);
   f->dump_unsigned("predecessor_entry_tid", predecessor_entry_tid);
 }
 
 void TagData::generate_test_instances(std::list<TagData *> &o) {
   o.push_back(new TagData());
-  o.push_back(new TagData("cluster_id", 123, "image_id"));
+  o.push_back(new TagData("mirror-uuid"));
+  o.push_back(new TagData("mirror-uuid", "remote-mirror-uuid", true, 123, 234));
 }
 
-} // namespace journal
-} // namespace librbd
-
-std::ostream &operator<<(std::ostream &out,
-                         const librbd::journal::EventType &type) {
+std::ostream &operator<<(std::ostream &out, const EventType &type) {
   using namespace librbd::journal;
 
   switch (type) {
@@ -503,8 +553,7 @@ std::ostream &operator<<(std::ostream &out,
   return out;
 }
 
-std::ostream &operator<<(std::ostream &out,
-                         const librbd::journal::ClientMetaType &type) {
+std::ostream &operator<<(std::ostream &out, const ClientMetaType &type) {
   using namespace librbd::journal;
 
   switch (type) {
@@ -522,5 +571,57 @@ std::ostream &operator<<(std::ostream &out,
     break;
   }
   return out;
+}
+
+std::ostream &operator<<(std::ostream &out, const ImageClientMeta &meta) {
+  out << "[tag_class=" << meta.tag_class << "]";
+  return out;
+}
+
+std::ostream &operator<<(std::ostream &out, const MirrorPeerSyncPoint &sync) {
+  out << "[snap_name=" << sync.snap_name << ", "
+      << "from_snap_name=" << sync.from_snap_name;
+  if (sync.object_number) {
+    out << ", " << *sync.object_number;
+  }
+  out << "]";
+  return out;
+}
+
+std::ostream &operator<<(std::ostream &out, const MirrorPeerClientMeta &meta) {
+  out << "[image_id=" << meta.image_id << ", "
+      << "sync_object_count=" << meta.sync_object_count << ", "
+      << "sync_points=[";
+  std::string delimiter;
+  for (auto &sync_point : meta.sync_points) {
+    out << delimiter << "[" << sync_point << "]";
+    delimiter = ", ";
+  }
+  out << "], snap_seqs=[";
+  delimiter = "";
+  for (auto &pair : meta.snap_seqs) {
+    out << delimiter << "["
+        << "local_snap_seq=" << pair.first << ", "
+        << "peer_snap_seq" << pair.second << "]";
+    delimiter = ", ";
+  }
+  out << "]";
+  return out;
+}
 
+std::ostream &operator<<(std::ostream &out, const TagData &tag_data) {
+  out << "["
+      << "mirror_uuid=" << tag_data.mirror_uuid << ", "
+      << "predecessor_mirror_uuid=" << tag_data.predecessor_mirror_uuid;
+  if (tag_data.predecessor_commit_valid) {
+    out << ", "
+        << "predecessor_tag_tid=" << tag_data.predecessor_tag_tid << ", "
+        << "predecessor_entry_tid=" << tag_data.predecessor_entry_tid;
+  }
+  out << "]";
+  return out;
 }
+
+} // namespace journal
+} // namespace librbd
+
diff --git a/src/librbd/journal/Types.h b/src/librbd/journal/Types.h
index cf4a642..2080399 100644
--- a/src/librbd/journal/Types.h
+++ b/src/librbd/journal/Types.h
@@ -9,6 +9,9 @@
 #include "include/encoding.h"
 #include "include/types.h"
 #include <iosfwd>
+#include <list>
+#include <boost/none.hpp>
+#include <boost/optional.hpp>
 #include <boost/variant.hpp>
 
 namespace ceph {
@@ -305,6 +308,7 @@ struct ImageClientMeta {
   static const ClientMetaType TYPE = IMAGE_CLIENT_META_TYPE;
 
   uint64_t tag_class = 0;
+  bool resync_requested = false;
 
   ImageClientMeta() {
   }
@@ -316,18 +320,61 @@ struct ImageClientMeta {
   void dump(Formatter *f) const;
 };
 
+struct MirrorPeerSyncPoint {
+  typedef boost::optional<uint64_t> ObjectNumber;
+
+  std::string snap_name;
+  std::string from_snap_name;
+  ObjectNumber object_number;
+
+  MirrorPeerSyncPoint() : MirrorPeerSyncPoint("", "", boost::none) {
+  }
+  MirrorPeerSyncPoint(const std::string &snap_name,
+                      const ObjectNumber &object_number)
+    : MirrorPeerSyncPoint(snap_name, "", object_number) {
+  }
+  MirrorPeerSyncPoint(const std::string &snap_name,
+                      const std::string &from_snap_name,
+                      const ObjectNumber &object_number)
+    : snap_name(snap_name), from_snap_name(from_snap_name),
+      object_number(object_number) {
+  }
+
+  inline bool operator==(const MirrorPeerSyncPoint &sync) const {
+    return (snap_name == sync.snap_name &&
+            from_snap_name == sync.from_snap_name &&
+            object_number == sync.object_number);
+  }
+
+  void encode(bufferlist& bl) const;
+  void decode(__u8 version, bufferlist::iterator& it);
+  void dump(Formatter *f) const;
+};
+
 struct MirrorPeerClientMeta {
+  typedef std::list<MirrorPeerSyncPoint> SyncPoints;
+  typedef std::map<uint64_t, uint64_t> SnapSeqs;
+
   static const ClientMetaType TYPE = MIRROR_PEER_CLIENT_META_TYPE;
 
-  std::string cluster_id;
-  int64_t pool_id = 0;
   std::string image_id;
+  uint64_t sync_object_count = 0; ///< maximum number of objects ever sync'ed
+  SyncPoints sync_points;         ///< max two in-use snapshots for sync
+  SnapSeqs snap_seqs;             ///< local to peer snap seq mapping
 
   MirrorPeerClientMeta() {
   }
-  MirrorPeerClientMeta(const std::string &cluster_id, int64_t pool_id,
-                       const std::string &image_id)
-    : cluster_id(cluster_id), pool_id(pool_id), image_id(image_id) {
+  MirrorPeerClientMeta(const std::string &image_id,
+                       const SyncPoints &sync_points = SyncPoints(),
+                       const SnapSeqs &snap_seqs = SnapSeqs())
+    : image_id(image_id), sync_points(sync_points), snap_seqs(snap_seqs) {
+  }
+
+  inline bool operator==(const MirrorPeerClientMeta &meta) const {
+    return (image_id == meta.image_id &&
+            sync_object_count == meta.sync_object_count &&
+            sync_points == meta.sync_points &&
+            snap_seqs == meta.snap_seqs);
   }
 
   void encode(bufferlist& bl) const;
@@ -377,19 +424,27 @@ struct ClientData {
 
 struct TagData {
   // owner of the tag (exclusive lock epoch)
-  std::string cluster_id;
-  int64_t pool_id = 0;
-  std::string image_id;
+  std::string mirror_uuid; // empty if local
 
   // mapping to last committed record of previous tag
+  std::string predecessor_mirror_uuid; // empty if local
+  bool predecessor_commit_valid = false;
   uint64_t predecessor_tag_tid = 0;
   uint64_t predecessor_entry_tid = 0;
 
   TagData() {
   }
-  TagData(const std::string &cluster_id, int64_t pool_id,
-          const std::string &image_id)
-    : cluster_id(cluster_id), pool_id(pool_id), image_id(image_id) {
+  TagData(const std::string &mirror_uuid) : mirror_uuid(mirror_uuid) {
+  }
+  TagData(const std::string &mirror_uuid,
+          const std::string &predecessor_mirror_uuid,
+          bool predecessor_commit_valid,
+          uint64_t predecessor_tag_tid, uint64_t predecessor_entry_tid)
+    : mirror_uuid(mirror_uuid),
+      predecessor_mirror_uuid(predecessor_mirror_uuid),
+      predecessor_commit_valid(predecessor_commit_valid),
+      predecessor_tag_tid(predecessor_tag_tid),
+      predecessor_entry_tid(predecessor_entry_tid) {
   }
 
   void encode(bufferlist& bl) const;
@@ -399,14 +454,16 @@ struct TagData {
   static void generate_test_instances(std::list<TagData *> &o);
 };
 
+std::ostream &operator<<(std::ostream &out, const EventType &type);
+std::ostream &operator<<(std::ostream &out, const ClientMetaType &type);
+std::ostream &operator<<(std::ostream &out, const ImageClientMeta &meta);
+std::ostream &operator<<(std::ostream &out, const MirrorPeerSyncPoint &sync);
+std::ostream &operator<<(std::ostream &out, const MirrorPeerClientMeta &meta);
+std::ostream &operator<<(std::ostream &out, const TagData &tag_data);
+
 } // namespace journal
 } // namespace librbd
 
-std::ostream &operator<<(std::ostream &out,
-                         const librbd::journal::EventType &type);
-std::ostream &operator<<(std::ostream &out,
-                         const librbd::journal::ClientMetaType &type);
-
 WRITE_CLASS_ENCODER(librbd::journal::EventEntry);
 WRITE_CLASS_ENCODER(librbd::journal::ClientData);
 WRITE_CLASS_ENCODER(librbd::journal::TagData);
diff --git a/src/librbd/librbd.cc b/src/librbd/librbd.cc
index 4a47ab2..0cc3f95 100644
--- a/src/librbd/librbd.cc
+++ b/src/librbd/librbd.cc
@@ -379,39 +379,36 @@ namespace librbd {
     return r;
   }
 
-  int RBD::mirror_is_enabled(IoCtx& io_ctx, bool *enabled) {
-    return librbd::mirror_is_enabled(io_ctx, enabled);
+  int RBD::mirror_mode_get(IoCtx& io_ctx, rbd_mirror_mode_t *mirror_mode) {
+    return librbd::mirror_mode_get(io_ctx, mirror_mode);
   }
 
-  int RBD::mirror_set_enabled(IoCtx& io_ctx, bool enabled) {
-    return librbd::mirror_set_enabled(io_ctx, enabled);
+  int RBD::mirror_mode_set(IoCtx& io_ctx, rbd_mirror_mode_t mirror_mode) {
+    return librbd::mirror_mode_set(io_ctx, mirror_mode);
   }
 
-  int RBD::mirror_peer_add(IoCtx& io_ctx, const std::string &cluster_uuid,
+  int RBD::mirror_peer_add(IoCtx& io_ctx, std::string *uuid,
                            const std::string &cluster_name,
                            const std::string &client_name) {
-    return librbd::mirror_peer_add(io_ctx, cluster_uuid, cluster_name,
-                                   client_name);
+    return librbd::mirror_peer_add(io_ctx, uuid, cluster_name, client_name);
   }
 
-  int RBD::mirror_peer_remove(IoCtx& io_ctx, const std::string &cluster_uuid) {
-    return librbd::mirror_peer_remove(io_ctx, cluster_uuid);
+  int RBD::mirror_peer_remove(IoCtx& io_ctx, const std::string &uuid) {
+    return librbd::mirror_peer_remove(io_ctx, uuid);
   }
 
   int RBD::mirror_peer_list(IoCtx& io_ctx, std::vector<mirror_peer_t> *peers) {
     return librbd::mirror_peer_list(io_ctx, peers);
   }
 
-  int RBD::mirror_peer_set_client(IoCtx& io_ctx,
-                                  const std::string &cluster_uuid,
+  int RBD::mirror_peer_set_client(IoCtx& io_ctx, const std::string &uuid,
                                   const std::string &client_name) {
-    return librbd::mirror_peer_set_client(io_ctx, cluster_uuid, client_name);
+    return librbd::mirror_peer_set_client(io_ctx, uuid, client_name);
   }
 
-  int RBD::mirror_peer_set_cluster(IoCtx& io_ctx,
-                                   const std::string &cluster_uuid,
+  int RBD::mirror_peer_set_cluster(IoCtx& io_ctx, const std::string &uuid,
                                    const std::string &cluster_name) {
-    return librbd::mirror_peer_set_cluster(io_ctx, cluster_uuid, cluster_name);
+    return librbd::mirror_peer_set_cluster(io_ctx, uuid, cluster_name);
   }
 
   RBD::AioCompletion::AioCompletion(void *cb_arg, callback_t complete_cb)
@@ -1229,6 +1226,38 @@ namespace librbd {
     return r;
   }
 
+  int Image::mirror_image_enable() {
+    ImageCtx *ictx = (ImageCtx *)ctx;
+    return librbd::mirror_image_enable(ictx);
+  }
+
+  int Image::mirror_image_disable(bool force) {
+    ImageCtx *ictx = (ImageCtx *)ctx;
+    return librbd::mirror_image_disable(ictx, force);
+  }
+
+  int Image::mirror_image_promote(bool force) {
+    ImageCtx *ictx = (ImageCtx *)ctx;
+    return librbd::mirror_image_promote(ictx, force);
+  }
+
+  int Image::mirror_image_demote() {
+    ImageCtx *ictx = (ImageCtx *)ctx;
+    return librbd::mirror_image_demote(ictx);
+  }
+
+  int Image::mirror_image_resync()
+  {
+    ImageCtx *ictx = (ImageCtx *)ctx;
+    return librbd::mirror_image_resync(ictx);
+  }
+
+  int Image::mirror_image_get_info(mirror_image_info_t *mirror_image_info,
+                                   size_t info_size) {
+    ImageCtx *ictx = (ImageCtx *)ctx;
+    return librbd::mirror_image_get_info(ictx, mirror_image_info, info_size);
+  }
+
 } // namespace librbd
 
 extern "C" void rbd_version(int *major, int *minor, int *extra)
@@ -1305,37 +1334,46 @@ extern "C" int rbd_image_options_is_empty(rbd_image_options_t opts)
 }
 
 /* pool mirroring */
-extern "C" int rbd_mirror_is_enabled(rados_ioctx_t p, bool *enabled) {
+extern "C" int rbd_mirror_mode_get(rados_ioctx_t p,
+                                   rbd_mirror_mode_t *mirror_mode) {
   librados::IoCtx io_ctx;
   librados::IoCtx::from_rados_ioctx_t(p, io_ctx);
-  int r = librbd::mirror_is_enabled(io_ctx, enabled);
-  if (r < 0) {
-    return r;
-  }
-  return 0;
+  return librbd::mirror_mode_get(io_ctx, mirror_mode);
 }
 
-extern "C" int rbd_mirror_set_enabled(rados_ioctx_t p, bool enabled) {
+extern "C" int rbd_mirror_mode_set(rados_ioctx_t p,
+                                   rbd_mirror_mode_t mirror_mode) {
   librados::IoCtx io_ctx;
   librados::IoCtx::from_rados_ioctx_t(p, io_ctx);
-  return librbd::mirror_set_enabled(io_ctx, enabled);
+  return librbd::mirror_mode_set(io_ctx, mirror_mode);
 }
 
-extern "C" int rbd_mirror_peer_add(rados_ioctx_t p,
-                                   const char *cluster_uuid,
+extern "C" int rbd_mirror_peer_add(rados_ioctx_t p, char *uuid,
+                                   size_t uuid_max_length,
                                    const char *cluster_name,
                                    const char *client_name) {
+  static const std::size_t UUID_LENGTH = 36;
+
   librados::IoCtx io_ctx;
   librados::IoCtx::from_rados_ioctx_t(p, io_ctx);
-  return librbd::mirror_peer_add(io_ctx, cluster_uuid, cluster_name,
-                                 client_name);
+
+  if (uuid_max_length < UUID_LENGTH + 1) {
+    return -E2BIG;
+  }
+
+  std::string uuid_str;
+  int r = librbd::mirror_peer_add(io_ctx, &uuid_str, cluster_name, client_name);
+  if (r >= 0) {
+    strncpy(uuid, uuid_str.c_str(), uuid_max_length);
+    uuid[uuid_max_length - 1] = '\0';
+  }
+  return r;
 }
 
-extern "C" int rbd_mirror_peer_remove(rados_ioctx_t p,
-                                      const char *cluster_name) {
+extern "C" int rbd_mirror_peer_remove(rados_ioctx_t p, const char *uuid) {
   librados::IoCtx io_ctx;
   librados::IoCtx::from_rados_ioctx_t(p, io_ctx);
-  int r = librbd::mirror_peer_remove(io_ctx, cluster_name);
+  int r = librbd::mirror_peer_remove(io_ctx, uuid);
   return r;
 }
 
@@ -1356,7 +1394,7 @@ extern "C" int rbd_mirror_peer_list(rados_ioctx_t p,
   }
 
   for (int i = 0; i < static_cast<int>(peer_vector.size()); ++i) {
-    peers[i].cluster_uuid = strdup(peer_vector[i].cluster_uuid.c_str());
+    peers[i].uuid = strdup(peer_vector[i].uuid.c_str());
     peers[i].cluster_name = strdup(peer_vector[i].cluster_name.c_str());
     peers[i].client_name = strdup(peer_vector[i].client_name.c_str());
   }
@@ -1367,26 +1405,24 @@ extern "C" int rbd_mirror_peer_list(rados_ioctx_t p,
 extern "C" void rbd_mirror_peer_list_cleanup(rbd_mirror_peer_t *peers,
                                              int max_peers) {
   for (int i = 0; i < max_peers; ++i) {
-    free(peers[i].cluster_uuid);
+    free(peers[i].uuid);
     free(peers[i].cluster_name);
     free(peers[i].client_name);
   }
 }
 
-extern "C" int rbd_mirror_peer_set_client(rados_ioctx_t p,
-                                          const char *cluster_uuid,
+extern "C" int rbd_mirror_peer_set_client(rados_ioctx_t p, const char *uuid,
                                           const char *client_name) {
   librados::IoCtx io_ctx;
   librados::IoCtx::from_rados_ioctx_t(p, io_ctx);
-  return librbd::mirror_peer_set_client(io_ctx, cluster_uuid, client_name);
+  return librbd::mirror_peer_set_client(io_ctx, uuid, client_name);
 }
 
-extern "C" int rbd_mirror_peer_set_cluster(rados_ioctx_t p,
-                                           const char *cluster_uuid,
+extern "C" int rbd_mirror_peer_set_cluster(rados_ioctx_t p, const char *uuid,
                                            const char *cluster_name) {
   librados::IoCtx io_ctx;
   librados::IoCtx::from_rados_ioctx_t(p, io_ctx);
-  return librbd::mirror_peer_set_cluster(io_ctx, cluster_uuid, cluster_name);
+  return librbd::mirror_peer_set_cluster(io_ctx, uuid, cluster_name);
 }
 
 /* images */
@@ -2549,6 +2585,55 @@ extern "C" int rbd_metadata_list(rbd_image_t image, const char *start, uint64_t
   return r;
 }
 
+extern "C" int rbd_mirror_image_enable(rbd_image_t image)
+{
+  librbd::ImageCtx *ictx = (librbd::ImageCtx *)image;
+  return librbd::mirror_image_enable(ictx);
+}
+
+extern "C" int rbd_mirror_image_disable(rbd_image_t image, bool force)
+{
+  librbd::ImageCtx *ictx = (librbd::ImageCtx *)image;
+  return librbd::mirror_image_disable(ictx, force);
+}
+
+extern "C" int rbd_mirror_image_promote(rbd_image_t image, bool force)
+{
+  librbd::ImageCtx *ictx = (librbd::ImageCtx *)image;
+  return librbd::mirror_image_promote(ictx, force);
+}
+
+extern "C" int rbd_mirror_image_demote(rbd_image_t image)
+{
+  librbd::ImageCtx *ictx = (librbd::ImageCtx *)image;
+  return librbd::mirror_image_demote(ictx);
+}
+
+extern "C" int rbd_mirror_image_resync(rbd_image_t image)
+{
+  librbd::ImageCtx *ictx = (librbd::ImageCtx *)image;
+  return librbd::mirror_image_resync(ictx);
+}
+
+extern "C" int rbd_mirror_image_get_info(rbd_image_t image,
+                                         rbd_mirror_image_info_t *mirror_image_info,
+                                         size_t info_size)
+{
+  librbd::ImageCtx *ictx = (librbd::ImageCtx *)image;
+
+  librbd::mirror_image_info_t cpp_mirror_image;
+  int r = librbd::mirror_image_get_info(ictx, &cpp_mirror_image,
+                                        sizeof(cpp_mirror_image));
+  if (r < 0) {
+    return r;
+  }
+
+  mirror_image_info->global_id = strdup(cpp_mirror_image.global_id.c_str());
+  mirror_image_info->state = cpp_mirror_image.state;
+  mirror_image_info->primary = cpp_mirror_image.primary;
+  return 0;
+}
+
 extern "C" int rbd_aio_is_complete(rbd_completion_t c)
 {
   librbd::RBD::AioCompletion *comp = (librbd::RBD::AioCompletion *)c;
diff --git a/src/librbd/operation/RebuildObjectMapRequest.cc b/src/librbd/operation/RebuildObjectMapRequest.cc
index cfb1c11..9b607fe 100644
--- a/src/librbd/operation/RebuildObjectMapRequest.cc
+++ b/src/librbd/operation/RebuildObjectMapRequest.cc
@@ -32,7 +32,8 @@ public:
                  uint64_t snap_id, uint64_t object_no)
     : C_AsyncObjectThrottle<I>(throttle, *image_ctx), m_snap_id(snap_id),
       m_object_no(object_no),
-      m_oid(image_ctx->get_object_name(m_object_no))
+      m_oid(image_ctx->get_object_name(m_object_no)),
+      m_snap_list_ret(0)
   {
     m_io_ctx.dup(image_ctx->md_ctx);
     m_io_ctx.snap_set_read(CEPH_SNAPDIR);
diff --git a/src/librbd/operation/RenameRequest.cc b/src/librbd/operation/RenameRequest.cc
index aa5e09f..3d23579 100644
--- a/src/librbd/operation/RenameRequest.cc
+++ b/src/librbd/operation/RenameRequest.cc
@@ -70,8 +70,12 @@ bool RenameRequest<I>::should_complete(int r) {
     return true;
   }
 
+  if (m_state == STATE_REMOVE_SOURCE_HEADER) {
+    apply();
+    return true;
+  }
+
   RWLock::RLocker owner_lock(image_ctx.owner_lock);
-  bool finished = false;
   switch (m_state) {
   case STATE_READ_SOURCE_HEADER:
     send_write_destination_header();
@@ -82,14 +86,11 @@ bool RenameRequest<I>::should_complete(int r) {
   case STATE_UPDATE_DIRECTORY:
     send_remove_source_header();
     break;
-  case STATE_REMOVE_SOURCE_HEADER:
-    finished = true;
-    break;
   default:
     assert(false);
     break;
   }
-  return finished;
+  return false;
 }
 
 template <typename I>
@@ -187,6 +188,12 @@ void RenameRequest<I>::send_remove_source_header() {
   rados_completion->release();
 }
 
+template <typename I>
+void RenameRequest<I>::apply() {
+  I &image_ctx = this->m_image_ctx;
+  image_ctx.set_image_name(m_dest_name);
+}
+
 } // namespace operation
 } // namespace librbd
 
diff --git a/src/librbd/operation/RenameRequest.h b/src/librbd/operation/RenameRequest.h
index 6b47d07..c2fa14e 100644
--- a/src/librbd/operation/RenameRequest.h
+++ b/src/librbd/operation/RenameRequest.h
@@ -80,6 +80,7 @@ private:
   void send_update_directory();
   void send_remove_source_header();
 
+  void apply();
 };
 
 } // namespace operation
diff --git a/src/librbd/operation/Request.cc b/src/librbd/operation/Request.cc
index d3e8bf6..216da1a 100644
--- a/src/librbd/operation/Request.cc
+++ b/src/librbd/operation/Request.cc
@@ -4,6 +4,7 @@
 #include "librbd/operation/Request.h"
 #include "common/dout.h"
 #include "common/errno.h"
+#include "common/WorkQueue.h"
 #include "librbd/ImageCtx.h"
 #include "librbd/Journal.h"
 #include "librbd/Utils.h"
@@ -84,6 +85,18 @@ void Request<I>::commit_op_event(int r) {
 }
 
 template <typename I>
+void Request<I>::replay_op_ready(Context *on_safe) {
+  I &image_ctx = this->m_image_ctx;
+  assert(image_ctx.owner_lock.is_locked());
+  assert(image_ctx.snap_lock.is_locked());
+  assert(m_op_tid != 0);
+
+  m_appended_op_event = true;
+  image_ctx.journal->replay_op_ready(
+    m_op_tid, util::create_async_context_callback(image_ctx, on_safe));
+}
+
+template <typename I>
 void Request<I>::append_op_event(Context *on_safe) {
   I &image_ctx = this->m_image_ctx;
   assert(image_ctx.owner_lock.is_locked());
diff --git a/src/librbd/operation/Request.h b/src/librbd/operation/Request.h
index 44ff5e2..be4d174 100644
--- a/src/librbd/operation/Request.h
+++ b/src/librbd/operation/Request.h
@@ -44,9 +44,7 @@ protected:
     if (image_ctx.journal != NULL) {
       Context *ctx = util::create_context_callback<T, MF>(request);
       if (image_ctx.journal->is_journal_replaying()) {
-        assert(m_op_tid != 0);
-        m_appended_op_event = true;
-        image_ctx.journal->replay_op_ready(m_op_tid, ctx);
+        replay_op_ready(ctx);
       } else {
         append_op_event(ctx);
       }
@@ -83,6 +81,7 @@ private:
   bool m_appended_op_event = false;
   bool m_committed_op_event = false;
 
+  void replay_op_ready(Context *on_safe);
   void append_op_event(Context *on_safe);
   void handle_op_event_safe(int r);
 
diff --git a/src/librbd/operation/SnapshotCreateRequest.cc b/src/librbd/operation/SnapshotCreateRequest.cc
index 39257a7..e4a1fc3 100644
--- a/src/librbd/operation/SnapshotCreateRequest.cc
+++ b/src/librbd/operation/SnapshotCreateRequest.cc
@@ -170,7 +170,8 @@ template <typename I>
 Context *SnapshotCreateRequest<I>::handle_allocate_snap_id(int *result) {
   I &image_ctx = this->m_image_ctx;
   CephContext *cct = image_ctx.cct;
-  ldout(cct, 5) << this << " " << __func__ << ": r=" << *result << dendl;
+  ldout(cct, 5) << this << " " << __func__ << ": r=" << *result << ", "
+                << "snap_id=" << m_snap_id << dendl;
 
   if (*result < 0) {
     save_result(result);
diff --git a/src/librbd/operation/SnapshotRollbackRequest.cc b/src/librbd/operation/SnapshotRollbackRequest.cc
index e1e472e..8bc5b33 100644
--- a/src/librbd/operation/SnapshotRollbackRequest.cc
+++ b/src/librbd/operation/SnapshotRollbackRequest.cc
@@ -279,6 +279,7 @@ Context *SnapshotRollbackRequest<I>::send_invalidate_cache() {
   CephContext *cct = image_ctx.cct;
   ldout(cct, 5) << this << " " << __func__ << dendl;
 
+  RWLock::RLocker owner_lock(image_ctx.owner_lock);
   Context *ctx = create_context_callback<
     SnapshotRollbackRequest<I>,
     &SnapshotRollbackRequest<I>::handle_invalidate_cache>(this);
diff --git a/src/log/Log.cc b/src/log/Log.cc
index 46dbb71..29e0529 100644
--- a/src/log/Log.cc
+++ b/src/log/Log.cc
@@ -17,6 +17,7 @@
 #include "common/errno.h"
 #include "common/safe_io.h"
 #include "common/Clock.h"
+#include "common/Graylog.h"
 #include "common/valgrind.h"
 #include "common/Formatter.h"
 #include "include/assert.h"
@@ -50,6 +51,9 @@ Log::Log(SubsystemMap *s)
     m_flush_mutex_holder(0),
     m_new(), m_recent(),
     m_fd(-1),
+    m_uid(0),
+    m_gid(0),
+    m_fd_last_error(0),
     m_syslog_log(-2), m_syslog_crash(-2),
     m_stderr_log(1), m_stderr_crash(-1),
     m_graylog_log(-3), m_graylog_crash(-3),
@@ -136,6 +140,14 @@ void Log::reopen_log_file()
     VOID_TEMP_FAILURE_RETRY(::close(m_fd));
   if (m_log_file.length()) {
     m_fd = ::open(m_log_file.c_str(), O_CREAT|O_WRONLY|O_APPEND, 0644);
+    if (m_fd >= 0 && (m_uid || m_gid)) {
+      int r = ::fchown(m_fd, m_uid, m_gid);
+      if (r < 0) {
+	r = -errno;
+	cerr << "failed to chown " << m_log_file << ": " << cpp_strerror(r)
+	     << std::endl;
+      }
+    }
   } else {
     m_fd = -1;
   }
@@ -143,6 +155,20 @@ void Log::reopen_log_file()
   pthread_mutex_unlock(&m_flush_mutex);
 }
 
+void Log::chown_log_file(uid_t uid, gid_t gid)
+{
+  pthread_mutex_lock(&m_flush_mutex);
+  if (m_fd >= 0) {
+    int r = ::fchown(m_fd, uid, gid);
+    if (r < 0) {
+      r = -errno;
+      cerr << "failed to chown " << m_log_file << ": " << cpp_strerror(r)
+	   << std::endl;
+    }
+  }
+  pthread_mutex_unlock(&m_flush_mutex);
+}
+
 void Log::set_syslog_level(int log, int crash)
 {
   pthread_mutex_lock(&m_flush_mutex);
@@ -189,7 +215,7 @@ void Log::submit_entry(Entry *e)
   m_queue_mutex_holder = pthread_self();
 
   if (m_inject_segv)
-    *(int *)(0) = 0xdead;
+    *(volatile int *)(0) = 0xdead;
 
   // wait for flush to catch up
   while (m_new.m_len > m_max_new)
@@ -277,17 +303,28 @@ void Log::_flush(EntryQueue *t, EntryQueue *requeue, bool crash)
     e->hint_size();
     if (do_fd || do_syslog || do_stderr) {
       size_t buflen = 0;
-      char buf[80 + e->size()];
+
+      char *buf;
+      size_t buf_size = 80 + e->size();
+      bool need_dynamic = buf_size >= 0x10000; //avoids >64K buffers
+					       //allocation at stack
+      char buf0[need_dynamic ? 1 : buf_size];
+      if (need_dynamic) {
+        buf = new char[buf_size];
+      } else {
+        buf = buf0;
+      }
 
       if (crash)
-	buflen += snprintf(buf, sizeof(buf), "%6d> ", -t->m_len);
-      buflen += e->m_stamp.sprintf(buf + buflen, sizeof(buf)-buflen);
-      buflen += snprintf(buf + buflen, sizeof(buf)-buflen, " %lx %2d ",
+	buflen += snprintf(buf, buf_size, "%6d> ", -t->m_len);
+      buflen += e->m_stamp.sprintf(buf + buflen, buf_size-buflen);
+      buflen += snprintf(buf + buflen, buf_size-buflen, " %lx %2d ",
 			(unsigned long)e->m_thread, e->m_prio);
 
-      buflen += e->snprintf(buf + buflen, sizeof(buf) - buflen - 1);
-      if (buflen > sizeof(buf) - 1) { //paranoid check, buf was declared to hold everything
-        buflen = sizeof(buf) - 1;
+      buflen += e->snprintf(buf + buflen, buf_size - buflen - 1);
+      if (buflen > buf_size - 1) { //paranoid check, buf was declared
+				   //to hold everything
+        buflen = buf_size - 1;
         buf[buflen] = 0;
       }
 
@@ -301,10 +338,16 @@ void Log::_flush(EntryQueue *t, EntryQueue *requeue, bool crash)
       if (do_fd) {
         buf[buflen] = '\n';
         int r = safe_write(m_fd, buf, buflen+1);
-        if (r < 0)
-          cerr << "problem writing to " << m_log_file << ": " << cpp_strerror(r) << std::endl;
+	if (r != m_fd_last_error) {
+	  if (r < 0)
+	    cerr << "problem writing to " << m_log_file
+		 << ": " << cpp_strerror(r)
+		 << std::endl;
+	  m_fd_last_error = r;
+	}
       }
-
+      if (need_dynamic)
+        delete[] buf;
     }
     if (do_graylog2 && m_graylog) {
       m_graylog->log_entry(e);
diff --git a/src/log/Log.h b/src/log/Log.h
index ba2dc41..687cb9b 100644
--- a/src/log/Log.h
+++ b/src/log/Log.h
@@ -6,18 +6,17 @@
 
 #include "common/Thread.h"
 
-#include <assert.h>
 #include <pthread.h>
-#include <boost/asio.hpp>
 
 #include "Entry.h"
 #include "EntryQueue.h"
 #include "SubsystemMap.h"
-#include "common/Graylog.h"
 
 namespace ceph {
 namespace log {
 
+class Graylog;
+
 class Log : private Thread
 {
   Log **m_indirect_this;
@@ -37,12 +36,16 @@ class Log : private Thread
 
   std::string m_log_file;
   int m_fd;
+  uid_t m_uid;
+  gid_t m_gid;
+
+  int m_fd_last_error;  ///< last error we say writing to fd (if any)
 
   int m_syslog_log, m_syslog_crash;
   int m_stderr_log, m_stderr_crash;
   int m_graylog_log, m_graylog_crash;
 
-  Graylog::Ref m_graylog;
+  shared_ptr<Graylog> m_graylog;
 
   bool m_stop;
 
@@ -66,6 +69,7 @@ public:
   void set_max_recent(int n);
   void set_log_file(std::string fn);
   void reopen_log_file();
+  void chown_log_file(uid_t uid, gid_t gid);
 
   void flush();
 
@@ -78,7 +82,7 @@ public:
   void start_graylog();
   void stop_graylog();
 
-  Graylog::Ref graylog() { return m_graylog; }
+  shared_ptr<Graylog> graylog() { return m_graylog; }
 
   Entry *create_entry(int level, int subsys);
   Entry *create_entry(int level, int subsys, size_t* expected_size);
diff --git a/src/log/test.cc b/src/log/test.cc
index a2df608..4e94add 100644
--- a/src/log/test.cc
+++ b/src/log/test.cc
@@ -210,3 +210,21 @@ TEST(Log, InternalSegv)
 {
   ASSERT_DEATH(do_segv(), ".*");
 }
+
+TEST(Log, LargeLog)
+{
+  SubsystemMap subs;
+  subs.add(1, "foo", 20, 10);
+  Log log(&subs);
+  log.start();
+  log.set_log_file("/tmp/big");
+  log.reopen_log_file();
+  int l = 10;
+  Entry *e = new Entry(ceph_clock_now(NULL), pthread_self(), l, 1);
+
+  std::string msg(10000000, 0);
+  e->set_str(msg);
+  log.submit_entry(e);
+  log.flush();
+  log.stop();
+}
diff --git a/src/mds/Beacon.cc b/src/mds/Beacon.cc
index c28f9aa..81de9e4 100644
--- a/src/mds/Beacon.cc
+++ b/src/mds/Beacon.cc
@@ -202,7 +202,8 @@ void Beacon::_send()
       name,
       epoch,
       want_state,
-      last_seq);
+      last_seq,
+      CEPH_FEATURES_SUPPORTED_DEFAULT);
 
   beacon->set_standby_for_rank(standby_for_rank);
   beacon->set_standby_for_name(standby_for_name);
@@ -312,6 +313,13 @@ void Beacon::notify_health(MDSRank const *mds)
 
   health.metrics.clear();
 
+  // Detect presence of entries in DamageTable
+  if (!mds->damage_table.empty()) {
+    MDSHealthMetric m(MDS_HEALTH_DAMAGE, HEALTH_ERR, std::string(
+          "Metadata damage detected"));
+    health.metrics.push_back(m);
+  }
+
   // Detect MDS_HEALTH_TRIM condition
   // Arbitrary factor of 2, indicates MDS is not trimming promptly
   {
diff --git a/src/mds/CDentry.cc b/src/mds/CDentry.cc
index eb74332..83470dc 100644
--- a/src/mds/CDentry.cc
+++ b/src/mds/CDentry.cc
@@ -621,57 +621,3 @@ std::string CDentry::linkage_t::get_remote_d_type_string() const
     default: assert(0); return "";
   }
 }
-
-void CDentry::scrub_initialize(CDir *parent, bool recurse, bool children,
-                        ScrubHeaderRefConst header,
-                               Context *f)
-{
-  if (!scrub_infop)
-    scrub_info_create();
-  else
-    assert(!scrub_infop->dentry_scrubbing);
-
-  scrub_infop->scrub_parent = parent;
-  scrub_infop->scrub_recursive = recurse;
-  scrub_infop->scrub_children = children;
-  scrub_infop->dentry_scrubbing = true;
-  scrub_infop->on_finish = f;
-  scrub_infop->header = header;
-
-  auth_pin(this);
-}
-
-void CDentry::scrub_finished(Context **c)
-{
-  dout(10) << __func__ << dendl;
-  assert(scrub_info()->dentry_scrubbing);
-
-  if (scrub_infop->scrub_parent) {
-    scrub_infop->scrub_parent->scrub_dentry_finished(this);
-  }
-
-  *c = scrub_infop->on_finish;
-
-  if (scrub_infop->header && scrub_infop->header->origin == this) {
-    // We are at the point that a tagging scrub was initiated
-    LogChannelRef clog = dir->cache->mds->clog;
-    clog->info() << "scrub complete with tag '"
-      << scrub_infop->header->tag << "'";
-  }
-
-  delete scrub_infop;
-  scrub_infop = NULL;
-
-  auth_unpin(this);
-}
-
-void CDentry::scrub_info_create() const
-{
-  assert(!scrub_infop);
-
-  // break out of const-land to set up implicit initial state
-  CDentry *me = const_cast<CDentry*>(this);
-
-  // we don't need to change or set up any default parameters; assign directly
-  me->scrub_infop = new scrub_info_t();
-}
diff --git a/src/mds/CDentry.h b/src/mds/CDentry.h
index 7bf21d6..7861b4d 100644
--- a/src/mds/CDentry.h
+++ b/src/mds/CDentry.h
@@ -81,14 +81,14 @@ public:
   static const int PIN_INODEPIN =     1;  // linked inode is pinned
   static const int PIN_FRAGMENTING = -2;  // containing dir is refragmenting
   static const int PIN_PURGING =      3;
-  static const int PIN_SCRUBQUEUE =   4; // TODO: negative value?
+  static const int PIN_SCRUBPARENT =  4;
 
   const char *pin_name(int p) const {
     switch (p) {
     case PIN_INODEPIN: return "inodepin";
     case PIN_FRAGMENTING: return "fragmenting";
     case PIN_PURGING: return "purging";
-    case PIN_SCRUBQUEUE: return "scrub_enqueued";
+    case PIN_SCRUBPARENT: return "scrubparent";
     default: return generic_pin_name(p);
     }
   }
@@ -140,25 +140,6 @@ public:
     }
     void link_remote(CInode *in);
   };
-  
-  class scrub_info_t {
-  public:
-    CDir *scrub_parent; /// This either matches get_parent_dir() or NULL
-    bool scrub_recursive; /// true if we are scrubbing everything under this
-    bool scrub_children; /// true if we have to scrub all direct children
-    bool dentry_scrubbing; /// safety check
-    bool dentry_children_done; /// safety check
-    bool inode_validated;  /// Has our inode's validate_disk_state run?
-    Context *on_finish; /// called when we finish scrubbing
-    ScrubHeaderRefConst header;
-
-    scrub_info_t() :
-      scrub_parent(NULL), scrub_recursive(false),
-      scrub_children(false), dentry_scrubbing(false),
-      dentry_children_done(false), inode_validated(false),
-      on_finish(NULL)
-    {}
-  };
 
 protected:
   CDir *dir;     // containing dirfrag
@@ -167,34 +148,10 @@ protected:
   
   version_t version;  // dir version when last touched.
   version_t projected_version;  // what it will be when i unlock/commit.
-  scrub_info_t* scrub_infop;
 
 public:
   elist<CDentry*>::item item_dirty;
   elist<CDentry*>::item item_stray;
-  elist<CDentry*>::item item_scrub;
-
-  const scrub_info_t *scrub_info() const {
-    if(!scrub_infop)
-      scrub_info_create();
-    return scrub_infop;
-  }
-  void scrub_initialize(CDir *parent, bool recurse, bool children,
-                        ScrubHeaderRefConst header,
-                        Context *f);
-  void scrub_finished(Context **c);
-  void scrub_children_finished() {
-    scrub_infop->dentry_children_done = true;
-  }
-  void scrub_set_finisher(Context *c) {
-    scrub_infop->on_finish = c;
-  }
-
-private:
-  /**
-   * Create a scrub_info_t struct for the scrub_infop pointer.
-   */
-  void scrub_info_create() const;
 
 protected:
   friend class Migrator;
@@ -221,7 +178,6 @@ public:
     first(f), last(l),
     dir(0),
     version(0), projected_version(0),
-    scrub_infop(NULL),
     item_dirty(this),
     lock(this, &lock_type),
     versionlock(this, &versionlock_type) {
@@ -234,7 +190,6 @@ public:
     first(f), last(l),
     dir(0),
     version(0), projected_version(0),
-    scrub_infop(NULL),
     item_dirty(this),
     lock(this, &lock_type),
     versionlock(this, &versionlock_type) {
@@ -244,8 +199,6 @@ public:
     linkage.remote_d_type = dt;
   }
   ~CDentry() {
-    assert(!scrub_infop);
-    assert(!item_scrub.is_on_list());
     g_num_dn--;
     g_num_dns++;
   }
diff --git a/src/mds/CDir.cc b/src/mds/CDir.cc
index f43c768..9119582 100644
--- a/src/mds/CDir.cc
+++ b/src/mds/CDir.cc
@@ -218,29 +218,43 @@ CDir::CDir(CInode *in, frag_t fg, MDCache *mdcache, bool auth) :
  * If mds_debug_scatterstat is enabled, assert for correctness,
  * otherwise just print out the mismatch and continue.
  */
-bool CDir::check_rstats()
+bool CDir::check_rstats(bool scrub)
 {
-  if (!g_conf->mds_debug_scatterstat)
+  if (!g_conf->mds_debug_scatterstat && !scrub)
     return true;
 
   dout(25) << "check_rstats on " << this << dendl;
   if (!is_complete() || !is_auth() || is_frozen()) {
+    assert(!scrub);
     dout(10) << "check_rstats bailing out -- incomplete or non-auth or frozen dir!" << dendl;
     return true;
   }
 
+  frag_info_t frag_info;
+  nest_info_t nest_info;
+  for (map_t::iterator i = items.begin(); i != items.end(); ++i) {
+    if (i->second->last != CEPH_NOSNAP)
+      continue;
+    CDentry::linkage_t *dnl = i->second->get_linkage();
+    if (dnl->is_primary()) {
+      CInode *in = dnl->get_inode();
+      nest_info.add(in->inode.accounted_rstat);
+      if (in->is_dir())
+	frag_info.nsubdirs++;
+      else
+	frag_info.nfiles++;
+    } else if (dnl->is_remote())
+      frag_info.nfiles++;
+  }
+
+  bool good = true;
   // fragstat
-  if(!(get_num_head_items()==
-      (fnode.fragstat.nfiles + fnode.fragstat.nsubdirs))) {
+  if(!frag_info.same_sums(fnode.fragstat)) {
     dout(1) << "mismatch between head items and fnode.fragstat! printing dentries" << dendl;
     dout(1) << "get_num_head_items() = " << get_num_head_items()
              << "; fnode.fragstat.nfiles=" << fnode.fragstat.nfiles
              << " fnode.fragstat.nsubdirs=" << fnode.fragstat.nsubdirs << dendl;
-    for (map_t::iterator i = items.begin(); i != items.end(); ++i) {
-      //if (i->second->get_linkage()->is_primary())
-        dout(1) << *(i->second) << dendl;
-    }
-    assert(get_num_head_items() == (fnode.fragstat.nfiles + fnode.fragstat.nsubdirs));
+    good = false;
   } else {
     dout(20) << "get_num_head_items() = " << get_num_head_items()
              << "; fnode.fragstat.nfiles=" << fnode.fragstat.nfiles
@@ -248,40 +262,39 @@ bool CDir::check_rstats()
   }
 
   // rstat
-  nest_info_t sub_info;
-  for (map_t::iterator i = items.begin(); i != items.end(); ++i) {
-    if (i->second->get_linkage()->is_primary() &&
-	i->second->last == CEPH_NOSNAP) {
-      sub_info.add(i->second->get_linkage()->inode->inode.accounted_rstat);
-    }
-  }
-
-  if ((!(sub_info.rbytes == fnode.rstat.rbytes)) ||
-      (!(sub_info.rfiles == fnode.rstat.rfiles)) ||
-      (!(sub_info.rsubdirs == fnode.rstat.rsubdirs))) {
+  if (!nest_info.same_sums(fnode.rstat)) {
     dout(1) << "mismatch between child accounted_rstats and my rstats!" << dendl;
-    dout(1) << "total of child dentrys: " << sub_info << dendl;
+    dout(1) << "total of child dentrys: " << nest_info << dendl;
     dout(1) << "my rstats:              " << fnode.rstat << dendl;
-    for (map_t::iterator i = items.begin(); i != items.end(); ++i) {
-      if (i->second->get_linkage()->is_primary()) {
-        dout(1) << *(i->second) << " "
-                << i->second->get_linkage()->inode->inode.accounted_rstat
-                << dendl;
+    good = false;
+  } else {
+    dout(20) << "total of child dentrys: " << nest_info << dendl;
+    dout(20) << "my rstats:              " << fnode.rstat << dendl;
+  }
+
+  if (!good) {
+    if (!scrub) {
+      for (map_t::iterator i = items.begin(); i != items.end(); ++i) {
+	CDentry *dn = i->second;
+	if (dn->get_linkage()->is_primary()) {
+	  CInode *in = dn->get_linkage()->inode;
+	  dout(1) << *dn << " rstat " << in->inode.accounted_rstat << dendl;
+	} else {
+	  dout(1) << *dn << dendl;
+	}
       }
+
+      assert(frag_info.nfiles == fnode.fragstat.nfiles);
+      assert(frag_info.nsubdirs == fnode.fragstat.nsubdirs);
+      assert(nest_info.rbytes == fnode.rstat.rbytes);
+      assert(nest_info.rfiles == fnode.rstat.rfiles);
+      assert(nest_info.rsubdirs == fnode.rstat.rsubdirs);
     }
-  } else {
-    dout(25) << "total of child dentrys: " << sub_info << dendl;
-    dout(25) << "my rstats:              " << fnode.rstat << dendl;
   }
-
-  assert(sub_info.rbytes == fnode.rstat.rbytes);
-  assert(sub_info.rfiles == fnode.rstat.rfiles);
-  assert(sub_info.rsubdirs == fnode.rstat.rsubdirs);
   dout(10) << "check_rstats complete on " << this << dendl;
-  return true;
+  return good;
 }
 
-
 CDentry *CDir::lookup(const char *name, snapid_t snap)
 { 
   dout(20) << "lookup (" << snap << ", '" << name << "')" << dendl;
@@ -1662,6 +1675,12 @@ CDentry *CDir::_load_dentry(
         in->dirfragtree.swap(inode_data.dirfragtree);
         in->xattrs.swap(inode_data.xattrs);
         in->old_inodes.swap(inode_data.old_inodes);
+	if (!in->old_inodes.empty()) {
+	  snapid_t min_first = in->old_inodes.rbegin()->first + 1;
+	  if (min_first > in->first)
+	    in->first = min_first;
+	}
+
         in->oldest_snap = inode_data.oldest_snap;
         in->decode_snap_blob(inode_data.snap_blob);
         if (snaps && !in->snaprealm)
@@ -1701,14 +1720,9 @@ CDentry *CDir::_load_dentry(
       }
     }
   } else {
-    dout(1) << "corrupt directory, i got tag char '" << type << "' pos "
-      << pos << dendl;
-    cache->mds->clog->error() << "Corrupt directory entry '" << key
-      << "' in dirfrag " << *this;
-    // TODO: add a mechanism for selectively marking a path
-    // damaged, rather than marking the whole rank damaged.
-    cache->mds->damaged();
-    assert(0);  // Unreachable: damaged() respawns us
+    std::ostringstream oss;
+    oss << "Invalid tag char '" << type << "' pos " << pos;
+    throw buffer::malformed_input(oss.str());
   }
 
   return dn;
@@ -1815,8 +1829,18 @@ void CDir::_omap_fetched(bufferlist& hdrbl, map<string, bufferlist>& omap,
       cache->mds->clog->warn() << "Corrupt dentry '" << dname << "' in "
                                   "dir frag " << dirfrag() << ": "
                                << err;
-      go_bad();
-      return;
+
+      // Remember that this dentry is damaged.  Subsequent operations
+      // that try to act directly on it will get their EIOs, but this
+      // dirfrag as a whole will continue to look okay (minus the
+      // mysteriously-missing dentry)
+      go_bad_dentry(last, dname);
+
+      // Anyone who was WAIT_DENTRY for this guy will get kicked
+      // to RetryRequest, and hit the DamageTable-interrogating path.
+      // Stats will now be bogus because we will think we're complete,
+      // but have 1 or more missing dentries.
+      continue;
     }
 
     if (dn && want_dn.length() && want_dn == dname) {
@@ -1857,6 +1881,11 @@ void CDir::_omap_fetched(bufferlist& hdrbl, map<string, bufferlist>& omap,
   mark_complete();
   state_clear(STATE_FETCHING);
 
+  if (scrub_infop && scrub_infop->need_scrub_local) {
+    scrub_infop->need_scrub_local = false;
+    scrub_local();
+  }
+
   // open & force frags
   while (!undef_inodes.empty()) {
     CInode *in = undef_inodes.front();
@@ -1875,16 +1904,39 @@ void CDir::_omap_fetched(bufferlist& hdrbl, map<string, bufferlist>& omap,
   finish_waiting(WAIT_COMPLETE, 0);
 }
 
-void CDir::go_bad()
+void CDir::_go_bad()
 {
+  if (get_version() == 0)
+    set_version(1);
   state_set(STATE_BADFRAG);
   // mark complete, !fetching
   mark_complete();
   state_clear(STATE_FETCHING);
   auth_unpin(this);
-  
+
   // kick waiters
-  finish_waiting(WAIT_COMPLETE, 0);
+  finish_waiting(WAIT_COMPLETE, -EIO);
+}
+
+void CDir::go_bad_dentry(snapid_t last, const std::string &dname)
+{
+  const bool fatal = cache->mds->damage_table.notify_dentry(
+      inode->ino(), frag, last, dname);
+  if (fatal) {
+    cache->mds->damaged();
+    assert(0);  // unreachable, damaged() respawns us
+  }
+}
+
+void CDir::go_bad()
+{
+  const bool fatal = cache->mds->damage_table.notify_dirfrag(inode->ino(), frag);
+  if (fatal) {
+    cache->mds->damaged();
+    assert(0);  // unreachable, damaged() respawns us
+  }
+
+  _go_bad();
 }
 
 // -----------------------
@@ -2116,7 +2168,7 @@ void CDir::_encode_dentry(CDentry *dn, bufferlist& bl,
 
     bufferlist snap_blob;
     in->encode_snap_blob(snap_blob);
-    in->encode_bare(bl, &snap_blob);
+    in->encode_bare(bl, cache->mds->mdsmap->get_up_features(), &snap_blob);
   }
 }
 
@@ -2884,7 +2936,7 @@ void CDir::scrub_info_create() const
   me->scrub_infop = si;
 }
 
-void CDir::scrub_initialize()
+void CDir::scrub_initialize(const ScrubHeaderRefConst& header)
 {
   dout(20) << __func__ << dendl;
   assert(is_complete());
@@ -2922,8 +2974,7 @@ void CDir::scrub_initialize()
     }
   }
   scrub_infop->directory_scrubbing = true;
-
-  assert(scrub_local()); // TODO: handle failure
+  scrub_infop->header = header;
 }
 
 void CDir::scrub_finished()
@@ -2947,12 +2998,13 @@ int CDir::_next_dentry_on_set(set<dentry_key_t>& dns, bool missing_okay,
                               MDSInternalContext *cb, CDentry **dnout)
 {
   dentry_key_t dnkey;
+  CDentry *dn;
 
   while (!dns.empty()) {
     set<dentry_key_t>::iterator front = dns.begin();
     dnkey = *front;
-    *dnout = lookup(dnkey.name);
-    if (!*dnout) {
+    dn = lookup(dnkey.name);
+    if (!dn) {
       if (!is_complete() &&
           (!has_bloom() || is_in_bloom(dnkey.name))) {
         // need to re-read this dirfrag
@@ -2974,6 +3026,14 @@ int CDir::_next_dentry_on_set(set<dentry_key_t>& dns, bool missing_okay,
     // okay, we got a  dentry
     dns.erase(dnkey);
 
+    if (dn->get_projected_version() < scrub_infop->last_recursive.version &&
+	!(scrub_infop->header && scrub_infop->header->force)) {
+      dout(15) << " skip dentry " << dnkey.name
+	       << ", no change since last scrub" << dendl;
+      continue;
+    }
+
+    *dnout = dn;
     return 0;
   }
   *dnout = NULL;
@@ -3051,7 +3111,9 @@ void CDir::scrub_maybe_delete_info()
 {
   if (scrub_infop &&
       !scrub_infop->directory_scrubbing &&
+      !scrub_infop->need_scrub_local &&
       !scrub_infop->last_scrub_dirty &&
+      !scrub_infop->pending_scrub_error &&
       scrub_infop->dirty_scrub_stamps.empty()) {
     delete scrub_infop;
     scrub_infop = NULL;
@@ -3061,13 +3123,19 @@ void CDir::scrub_maybe_delete_info()
 bool CDir::scrub_local()
 {
   assert(is_complete());
-  bool rval = check_rstats();
+  bool rval = check_rstats(true);
 
+  scrub_info();
   if (rval) {
-    scrub_info();
     scrub_infop->last_local.time = ceph_clock_now(g_ceph_context);
     scrub_infop->last_local.version = get_projected_version();
+    scrub_infop->pending_scrub_error = false;
     scrub_infop->last_scrub_dirty = true;
+  } else {
+    scrub_infop->pending_scrub_error = true;
+    if (scrub_infop->header &&
+	scrub_infop->header->repair)
+      cache->repair_dirfrag_stats(this);
   }
   return rval;
 }
diff --git a/src/mds/CDir.h b/src/mds/CDir.h
index 44034b8..2748526 100644
--- a/src/mds/CDir.h
+++ b/src/mds/CDir.h
@@ -253,7 +253,9 @@ public:
     scrub_stamps last_local; // when we last did a local scrub
 
     bool directory_scrubbing; /// safety check
+    bool need_scrub_local;
     bool last_scrub_dirty; /// is scrub info dirty or is it flushed to fnode?
+    bool pending_scrub_error;
 
     /// these are lists of children in each stage of scrubbing
     set<dentry_key_t> directories_to_scrub;
@@ -263,7 +265,13 @@ public:
     set<dentry_key_t> others_scrubbing;
     set<dentry_key_t> others_scrubbed;
 
-    scrub_info_t() : directory_scrubbing(false), last_scrub_dirty(false) {}
+    ScrubHeaderRefConst header;
+
+    scrub_info_t() :
+      directory_scrubbing(false),
+      need_scrub_local(false),
+      last_scrub_dirty(false),
+      pending_scrub_error(false) {}
   };
   /**
    * Call to start this CDir on a new scrub.
@@ -271,7 +279,7 @@ public:
    * @pre The CDir is marked complete.
    * @post It has set up its internal scrubbing state.
    */
-  void scrub_initialize();
+  void scrub_initialize(const ScrubHeaderRefConst& header);
   /**
    * Get the next dentry to scrub. Gives you a CDentry* and its meaning. This
    * function will give you all directory-representing dentries before any
@@ -425,7 +433,7 @@ protected:
   unsigned get_num_snap_null() const { return num_snap_null; }
   unsigned get_num_any() const { return num_head_items + num_head_null + num_snap_items + num_snap_null; }
   
-  bool check_rstats();
+  bool check_rstats(bool scrub=false);
 
   void inc_num_dirty() { num_dirty++; }
   void dec_num_dirty() { 
@@ -611,7 +619,17 @@ protected:
       list<CInode*> *undef_inodes);
 
   /**
-   * Mark this fragment as BADFRAG
+   * Mark this fragment as BADFRAG (common part of go_bad and go_bad_dentry)
+   */
+  void _go_bad();
+
+  /**
+   * Go bad due to a damaged dentry (register with damagetable and go BADFRAG)
+   */
+  void go_bad_dentry(snapid_t last, const std::string &dname);
+
+  /**
+   * Go bad due to a damaged header (register with damagetable and go BADFRAG)
    */
   void go_bad();
 
diff --git a/src/mds/CInode.cc b/src/mds/CInode.cc
index 68ebd76..28a1b1a 100644
--- a/src/mds/CInode.cc
+++ b/src/mds/CInode.cc
@@ -385,13 +385,13 @@ void CInode::pop_and_dirty_projected_inode(LogSegment *ls)
   assert(!projected_nodes.empty());
   dout(15) << "pop_and_dirty_projected_inode " << projected_nodes.front()->inode
 	   << " v" << projected_nodes.front()->inode->version << dendl;
-  int64_t old_pool = inode.layout.fl_pg_pool;
+  int64_t old_pool = inode.layout.pool_id;
 
   mark_dirty(projected_nodes.front()->inode->version, ls);
   inode = *projected_nodes.front()->inode;
 
   if (inode.is_backtrace_updated())
-    _mark_dirty_parent(ls, old_pool != inode.layout.fl_pg_pool);
+    _mark_dirty_parent(ls, old_pool != inode.layout.pool_id);
 
   map<string,bufferptr> *px = projected_nodes.front()->xattrs;
   if (px) {
@@ -970,7 +970,7 @@ void CInode::store(MDSInternalContextBase *fin)
   bufferlist bl;
   string magic = CEPH_FS_ONDISK_MAGIC;
   ::encode(magic, bl);
-  encode_store(bl);
+  encode_store(bl, mdcache->mds->mdsmap->get_up_features());
 
   // write it.
   SnapContext snapc;
@@ -1147,7 +1147,7 @@ void CInode::store_backtrace(MDSInternalContextBase *fin, int op_prio)
   if (is_dir()) {
     pool = mdcache->mds->mdsmap->get_metadata_pool();
   } else {
-    pool = inode.layout.fl_pg_pool;
+    pool = inode.layout.pool_id;
   }
 
   inode_backtrace_t bt;
@@ -1161,7 +1161,7 @@ void CInode::store_backtrace(MDSInternalContextBase *fin, int op_prio)
   op.setxattr("parent", parent_bl);
 
   bufferlist layout_bl;
-  ::encode(inode.layout, layout_bl);
+  ::encode(inode.layout, layout_bl, mdcache->mds->mdsmap->get_up_features());
   op.setxattr("layout", layout_bl);
 
   SnapContext snapc;
@@ -1233,7 +1233,7 @@ void CInode::fetch_backtrace(Context *fin, bufferlist *backtrace)
   if (is_dir())
     pool = mdcache->mds->mdsmap->get_metadata_pool();
   else
-    pool = inode.layout.fl_pg_pool;
+    pool = inode.layout.pool_id;
 
   mdcache->fetch_backtrace(inode.ino, pool, *backtrace, fin);
 }
@@ -1294,9 +1294,10 @@ void CInode::verify_diri_backtrace(bufferlist &bl, int err)
 // parent dir
 
 
-void InodeStoreBase::encode_bare(bufferlist &bl, const bufferlist *snap_blob) const
+void InodeStoreBase::encode_bare(bufferlist &bl, uint64_t features,
+				 const bufferlist *snap_blob) const
 {
-  ::encode(inode, bl);
+  ::encode(inode, bl, features);
   if (is_symlink())
     ::encode(symlink, bl);
   ::encode(dirfragtree, bl);
@@ -1305,23 +1306,25 @@ void InodeStoreBase::encode_bare(bufferlist &bl, const bufferlist *snap_blob) co
     ::encode(*snap_blob, bl);
   else
     ::encode(bufferlist(), bl);
-  ::encode(old_inodes, bl);
+  ::encode(old_inodes, bl, features);
   ::encode(oldest_snap, bl);
   ::encode(damage_flags, bl);
 }
 
-void InodeStoreBase::encode(bufferlist &bl, const bufferlist *snap_blob) const
+void InodeStoreBase::encode(bufferlist &bl, uint64_t features,
+			    const bufferlist *snap_blob) const
 {
   ENCODE_START(6, 4, bl);
-  encode_bare(bl, snap_blob);
+  encode_bare(bl, features, snap_blob);
   ENCODE_FINISH(bl);
 }
 
-void CInode::encode_store(bufferlist& bl)
+void CInode::encode_store(bufferlist& bl, uint64_t features)
 {
   bufferlist snap_blob;
   encode_snap_blob(snap_blob);
-  InodeStoreBase::encode(bl, &snap_blob);
+  InodeStoreBase::encode(bl, mdcache->mds->mdsmap->get_up_features(),
+			 &snap_blob);
 }
 
 void InodeStoreBase::decode_bare(bufferlist::iterator &bl,
@@ -1432,7 +1435,7 @@ void CInode::encode_lock_state(int type, bufferlist& bl)
       ::encode(inode.atime, bl);
       ::encode(inode.time_warp_seq, bl);
       if (!is_dir()) {
-	::encode(inode.layout, bl);
+	::encode(inode.layout, bl, mdcache->mds->mdsmap->get_up_features());
 	::encode(inode.size, bl);
 	::encode(inode.truncate_seq, bl);
 	::encode(inode.truncate_size, bl);
@@ -1527,7 +1530,7 @@ void CInode::encode_lock_state(int type, bufferlist& bl)
   case CEPH_LOCK_IPOLICY:
     if (inode.is_dir()) {
       ::encode(inode.version, bl);
-      ::encode(inode.layout, bl);
+      ::encode(inode.layout, bl, mdcache->mds->mdsmap->get_up_features());
       ::encode(inode.quota, bl);
     }
     break;
@@ -2030,8 +2033,7 @@ void CInode::finish_scatter_gather_update(int type)
 	pi->mtime = pi->ctime = pi->dirstat.mtime;
       dout(20) << " final dirstat " << pi->dirstat << dendl;
 
-      if (dirstat.nfiles != pi->dirstat.nfiles ||
-	  dirstat.nsubdirs != pi->dirstat.nsubdirs) {
+      if (!dirstat.same_sums(pi->dirstat)) {
 	bool all = true;
 	list<frag_t> ls;
 	tmpdft.get_leaves_under(frag_t(), ls);
@@ -2041,11 +2043,17 @@ void CInode::finish_scatter_gather_update(int type)
 	    break;
 	  }
 	if (all) {
-	  clog->error() << "unmatched fragstat on " << ino() << ", inode has "
-		       << pi->dirstat << ", dirfrags have " << dirstat << "\n";
-	  assert(!"unmatched fragstat" == g_conf->mds_verify_scatter);
+	  if (state_test(CInode::STATE_REPAIRSTATS)) {
+	    dout(20) << " dirstat mismatch, fixing" << dendl;
+	  } else {
+	    clog->error() << "unmatched fragstat on " << ino() << ", inode has "
+			  << pi->dirstat << ", dirfrags have " << dirstat << "\n";
+	    assert(!"unmatched fragstat" == g_conf->mds_verify_scatter);
+	  }
 	  // trust the dirfrags for now
 	  version_t v = pi->dirstat.version;
+	  if (pi->dirstat.mtime > dirstat.mtime)
+	    dirstat.mtime = pi->dirstat.mtime;
 	  pi->dirstat = dirstat;
 	  pi->dirstat.version = v;
 	}
@@ -2124,9 +2132,7 @@ void CInode::finish_scatter_gather_update(int type)
       }
       dout(20) << " final rstat " << pi->rstat << dendl;
 
-      if (rstat.rfiles != pi->rstat.rfiles ||
-	  rstat.rsubdirs != pi->rstat.rsubdirs ||
-	  rstat.rbytes != pi->rstat.rbytes) {
+      if (!rstat.same_sums(pi->rstat)) {
 	bool all = true;
 	list<frag_t> ls;
 	tmpdft.get_leaves_under(frag_t(), ls);
@@ -2136,11 +2142,17 @@ void CInode::finish_scatter_gather_update(int type)
 	    break;
 	  }
 	if (all) {
-	  clog->error() << "unmatched rstat on " << ino() << ", inode has "
-		       << pi->rstat << ", dirfrags have " << rstat << "\n";
-	  assert(!"unmatched rstat" == g_conf->mds_verify_scatter);
+	  if (state_test(CInode::STATE_REPAIRSTATS)) {
+	    dout(20) << " rstat mismatch, fixing" << dendl;
+	  } else {
+	    clog->error() << "unmatched rstat on " << ino() << ", inode has "
+			  << pi->rstat << ", dirfrags have " << rstat << "\n";
+	    assert(!"unmatched rstat" == g_conf->mds_verify_scatter);
+	  }
 	  // trust the dirfrag for now
 	  version_t v = pi->rstat.version;
+	  if (pi->rstat.rctime > rstat.rctime)
+	    rstat.rctime = pi->rstat.rctime;
 	  pi->rstat = rstat;
 	  pi->rstat.version = v;
 	}
@@ -2899,8 +2911,9 @@ int CInode::get_xlocker_mask(client_t client) const
     (linklock.gcaps_xlocker_mask(client) << linklock.get_cap_shift());
 }
 
-int CInode::get_caps_allowed_for_client(client_t client) const
+int CInode::get_caps_allowed_for_client(Session *session, inode_t *file_i) const
 {
+  client_t client = session->info.inst.name.num();
   int allowed;
   if (client == get_loner()) {
     // as the loner, we get the loner_caps AND any xlocker_caps for things we have xlocked
@@ -2910,9 +2923,14 @@ int CInode::get_caps_allowed_for_client(client_t client) const
   } else {
     allowed = get_caps_allowed_by_type(CAP_ANY);
   }
-  if (inode.inline_data.version != CEPH_INLINE_NONE &&
-      !mdcache->mds->get_session(client)->connection->has_feature(CEPH_FEATURE_MDS_INLINE_DATA))
-    allowed &= ~(CEPH_CAP_FILE_RD | CEPH_CAP_FILE_WR);
+
+  if (!is_dir()) {
+    if ((file_i->inline_data.version != CEPH_INLINE_NONE &&
+	 !session->connection->has_feature(CEPH_FEATURE_MDS_INLINE_DATA)) ||
+	(!file_i->layout.pool_ns.empty() &&
+	 !session->connection->has_feature(CEPH_FEATURE_FS_FILE_LAYOUT_V2)))
+      allowed &= ~(CEPH_CAP_FILE_RD | CEPH_CAP_FILE_WR);
+  }
   return allowed;
 }
 
@@ -3079,18 +3097,8 @@ int CInode::encode_inodestat(bufferlist& bl, Session *session,
     }
   }
   
-  /*
-   * note: encoding matches struct ceph_client_reply_inode
-   */
-  struct ceph_mds_reply_inode e;
-  memset(&e, 0, sizeof(e));
-  e.ino = oi->ino;
-  e.snapid = snapid;  // 0 -> NOSNAP
-  e.rdev = oi->rdev;
-
   // "fake" a version that is old (stable) version, +1 if projected.
-  e.version = (oi->version * 2) + is_projected();
-
+  version_t version = (oi->version * 2) + is_projected();
 
   Capability *cap = get_client_cap(client);
   bool pfile = filelock.is_xlocked_by_client(client) || get_loner() == client;
@@ -3102,87 +3110,80 @@ int CInode::encode_inodestat(bufferlist& bl, Session *session,
   bool plocal = versionlock.get_last_wrlock_client() == client;
   bool ppolicy = policylock.is_xlocked_by_client(client) || get_loner()==client;
   
-  inode_t *i = (pfile|pauth|plink|pxattr|plocal) ? pi : oi;
-  i->ctime.encode_timeval(&e.ctime);
+  inode_t *any_i = (pfile|pauth|plink|pxattr|plocal) ? pi : oi;
   
-  dout(20) << " pfile " << pfile << " pauth " << pauth << " plink " << plink << " pxattr " << pxattr
+  dout(20) << " pfile " << pfile << " pauth " << pauth
+	   << " plink " << plink << " pxattr " << pxattr
 	   << " plocal " << plocal
-	   << " ctime " << i->ctime
+	   << " ctime " << any_i->ctime
 	   << " valid=" << valid << dendl;
 
   // file
-  i = pfile ? pi:oi;
+  inode_t *file_i = pfile ? pi:oi;
+  file_layout_t layout;
   if (is_dir()) {
-    e.layout = (ppolicy ? pi : oi)->layout;
+    layout = (ppolicy ? pi : oi)->layout;
   } else {
-    e.layout = i->layout;
+    layout = file_i->layout;
   }
-  e.size = i->size;
-  e.truncate_seq = i->truncate_seq;
-  e.truncate_size = i->truncate_size;
-  i->mtime.encode_timeval(&e.mtime);
-  i->atime.encode_timeval(&e.atime);
-  e.time_warp_seq = i->time_warp_seq;
 
   // max_size is min of projected, actual
-  e.max_size = MIN(oi->client_ranges.count(client) ? oi->client_ranges[client].range.last : 0,
-		   pi->client_ranges.count(client) ? pi->client_ranges[client].range.last : 0);
-
-  e.files = i->dirstat.nfiles;
-  e.subdirs = i->dirstat.nsubdirs;
+  uint64_t max_size =
+    MIN(oi->client_ranges.count(client) ?
+	oi->client_ranges[client].range.last : 0,
+	pi->client_ranges.count(client) ?
+	pi->client_ranges[client].range.last : 0);
 
   // inline data
   version_t inline_version = 0;
   bufferlist inline_data;
-  if (i->inline_data.version == CEPH_INLINE_NONE) {
+  if (file_i->inline_data.version == CEPH_INLINE_NONE) {
     inline_version = CEPH_INLINE_NONE;
   } else if ((!cap && !no_caps) ||
-	     (cap && cap->client_inline_version < i->inline_data.version) ||
+	     (cap && cap->client_inline_version < file_i->inline_data.version) ||
 	     (getattr_caps & CEPH_CAP_FILE_RD)) { // client requests inline data
-    inline_version = i->inline_data.version;
-    if (i->inline_data.length() > 0)
-      inline_data = i->inline_data.get_data();
+    inline_version = file_i->inline_data.version;
+    if (file_i->inline_data.length() > 0)
+      inline_data = file_i->inline_data.get_data();
   }
 
   // nest (do same as file... :/)
-  i->rstat.rctime.encode_timeval(&e.rctime);
-  e.rbytes = i->rstat.rbytes;
-  e.rfiles = i->rstat.rfiles;
-  e.rsubdirs = i->rstat.rsubdirs;
   if (cap) {
-    cap->last_rbytes = i->rstat.rbytes;
-    cap->last_rsize = i->rstat.rsize();
+    cap->last_rbytes = file_i->rstat.rbytes;
+    cap->last_rsize = file_i->rstat.rsize();
   }
 
   // auth
-  i = pauth ? pi:oi;
-  e.mode = i->mode;
-  e.uid = i->uid;
-  e.gid = i->gid;
+  inode_t *auth_i = pauth ? pi:oi;
 
   // link
-  i = plink ? pi:oi;
-  e.nlink = i->nlink;
+  inode_t *link_i = plink ? pi:oi;
   
   // xattr
-  i = pxattr ? pi:oi;
+  inode_t *xattr_i = pxattr ? pi:oi;
 
   // xattr
   bufferlist xbl;
+  version_t xattr_version;
   if ((!cap && !no_caps) ||
-      (cap && cap->client_xattr_version < i->xattr_version) ||
+      (cap && cap->client_xattr_version < xattr_i->xattr_version) ||
       (getattr_caps & CEPH_CAP_XATTR_SHARED)) { // client requests xattrs
     if (!pxattrs)
       pxattrs = pxattr ? get_projected_xattrs() : &xattrs;
     ::encode(*pxattrs, xbl);
-    e.xattr_version = i->xattr_version;
+    xattr_version = xattr_i->xattr_version;
   } else {
-    e.xattr_version = 0;
+    xattr_version = 0;
   }
   
   // do we have room?
   if (max_bytes) {
-    unsigned bytes = sizeof(e);
+    unsigned bytes = 8 + 8 + 4 + 8 + 8 + sizeof(ceph_mds_reply_cap) +
+      sizeof(struct ceph_file_layout) + 4 + layout.pool_ns.size() +
+      sizeof(struct ceph_timespec) * 3 +
+      4 + 8 + 8 + 8 + 4 + 4 + 4 + 4 + 4 +
+      8 + 8 + 8 + 8 + 8 + sizeof(struct ceph_timespec) +
+      4;
     bytes += sizeof(__u32);
     bytes += (sizeof(__u32) + sizeof(__u32)) * dirfragtree._splits.size();
     bytes += sizeof(__u32) + symlink.length();
@@ -3194,6 +3195,7 @@ int CInode::encode_inodestat(bufferlist& bl, Session *session,
 
 
   // encode caps
+  struct ceph_mds_reply_cap ecap;
   if (snapid != CEPH_NOSNAP) {
     /*
      * snapped inodes (files or dirs) only get read-only caps.  always
@@ -3209,12 +3211,12 @@ int CInode::encode_inodestat(bufferlist& bl, Session *session,
      * tracks caps per-snap and the mds does either per-interval or
      * multiversion.
      */
-    e.cap.caps = valid ? get_caps_allowed_by_type(CAP_ANY) : CEPH_STAT_CAP_INODE;
+    ecap.caps = valid ? get_caps_allowed_by_type(CAP_ANY) : CEPH_STAT_CAP_INODE;
     if (last == CEPH_NOSNAP || is_any_caps())
-      e.cap.caps = e.cap.caps & get_caps_allowed_for_client(client);
-    e.cap.seq = 0;
-    e.cap.mseq = 0;
-    e.cap.realm = 0;
+      ecap.caps = ecap.caps & get_caps_allowed_for_client(session, file_i);
+    ecap.seq = 0;
+    ecap.mseq = 0;
+    ecap.realm = 0;
   } else {
     if (!no_caps && valid && !cap) {
       // add a new cap
@@ -3229,35 +3231,36 @@ int CInode::encode_inodestat(bufferlist& bl, Session *session,
 
     if (!no_caps && valid && cap) {
       int likes = get_caps_liked();
-      int allowed = get_caps_allowed_for_client(client);
+      int allowed = get_caps_allowed_for_client(session, file_i);
       int issue = (cap->wanted() | likes) & allowed;
       cap->issue_norevoke(issue);
       issue = cap->pending();
       cap->set_last_issue();
       cap->set_last_issue_stamp(ceph_clock_now(g_ceph_context));
       cap->clear_new();
-      e.cap.caps = issue;
-      e.cap.wanted = cap->wanted();
-      e.cap.cap_id = cap->get_cap_id();
-      e.cap.seq = cap->get_last_seq();
-      dout(10) << "encode_inodestat issuing " << ccap_string(issue) << " seq " << cap->get_last_seq() << dendl;
-      e.cap.mseq = cap->get_mseq();
-      e.cap.realm = realm->inode->ino();
+      ecap.caps = issue;
+      ecap.wanted = cap->wanted();
+      ecap.cap_id = cap->get_cap_id();
+      ecap.seq = cap->get_last_seq();
+      dout(10) << "encode_inodestat issuing " << ccap_string(issue)
+	       << " seq " << cap->get_last_seq() << dendl;
+      ecap.mseq = cap->get_mseq();
+      ecap.realm = realm->inode->ino();
     } else {
       if (cap)
 	cap->clear_new();
-      e.cap.cap_id = 0;
-      e.cap.caps = 0;
-      e.cap.seq = 0;
-      e.cap.mseq = 0;
-      e.cap.realm = 0;
-      e.cap.wanted = 0;
+      ecap.cap_id = 0;
+      ecap.caps = 0;
+      ecap.seq = 0;
+      ecap.mseq = 0;
+      ecap.realm = 0;
+      ecap.wanted = 0;
     }
   }
-  e.cap.flags = is_auth() ? CEPH_CAP_FLAG_AUTH:0;
-  dout(10) << "encode_inodestat caps " << ccap_string(e.cap.caps)
-	   << " seq " << e.cap.seq << " mseq " << e.cap.mseq
-	   << " xattrv " << e.xattr_version << " len " << xbl.length()
+  ecap.flags = is_auth() ? CEPH_CAP_FLAG_AUTH : 0;
+  dout(10) << "encode_inodestat caps " << ccap_string(ecap.caps)
+	   << " seq " << ecap.seq << " mseq " << ecap.mseq
+	   << " xattrv " << xattr_version << " len " << xbl.length()
 	   << dendl;
 
   if (inline_data.length() && cap) {
@@ -3274,25 +3277,58 @@ int CInode::encode_inodestat(bufferlist& bl, Session *session,
   // include those xattrs?
   if (xbl.length() && cap) {
     if ((cap->pending() | getattr_caps) & CEPH_CAP_XATTR_SHARED) {
-      dout(10) << "including xattrs version " << i->xattr_version << dendl;
-      cap->client_xattr_version = i->xattr_version;
+      dout(10) << "including xattrs version " << xattr_i->xattr_version << dendl;
+      cap->client_xattr_version = xattr_i->xattr_version;
     } else {
-      dout(10) << "dropping xattrs version " << i->xattr_version << dendl;
+      dout(10) << "dropping xattrs version " << xattr_i->xattr_version << dendl;
       xbl.clear(); // no xattrs .. XXX what's this about?!?
-      e.xattr_version = 0;
+      xattr_version = 0;
     }
   }
 
-  // encode
-  e.fragtree.nsplits = dirfragtree._splits.size();
-  ::encode(e, bl);
+  /*
+   * note: encoding matches MClientReply::InodeStat
+   */
+  ::encode(oi->ino, bl);
+  ::encode(snapid, bl);
+  ::encode(oi->rdev, bl);
+  ::encode(version, bl);
+
+  ::encode(xattr_version, bl);
 
-  dirfragtree.encode_nohead(bl);
+  ::encode(ecap, bl);
+  {
+    ceph_file_layout legacy_layout;
+    layout.to_legacy(&legacy_layout);
+    ::encode(legacy_layout, bl);
+  }
+  ::encode(any_i->ctime, bl);
+  ::encode(file_i->mtime, bl);
+  ::encode(file_i->atime, bl);
+  ::encode(file_i->time_warp_seq, bl);
+  ::encode(file_i->size, bl);
+  ::encode(max_size, bl);
+  ::encode(file_i->truncate_size, bl);
+  ::encode(file_i->truncate_seq, bl);
+
+  ::encode(auth_i->mode, bl);
+  ::encode((uint32_t)auth_i->uid, bl);
+  ::encode((uint32_t)auth_i->gid, bl);
+
+  ::encode(link_i->nlink, bl);
+
+  ::encode(file_i->dirstat.nfiles, bl);
+  ::encode(file_i->dirstat.nsubdirs, bl);
+  ::encode(file_i->rstat.rbytes, bl);
+  ::encode(file_i->rstat.rfiles, bl);
+  ::encode(file_i->rstat.rsubdirs, bl);
+  ::encode(file_i->rstat.rctime, bl);
+
+  dirfragtree.encode(bl);
 
   ::encode(symlink, bl);
   if (session->connection->has_feature(CEPH_FEATURE_DIRLAYOUTHASH)) {
-    i = pfile ? pi : oi;
-    ::encode(i->dir_layout, bl);
+    ::encode(file_i->dir_layout, bl);
   }
   ::encode(xbl, bl);
   if (session->connection->has_feature(CEPH_FEATURE_MDS_INLINE_DATA)) {
@@ -3300,8 +3336,11 @@ int CInode::encode_inodestat(bufferlist& bl, Session *session,
     ::encode(inline_data, bl);
   }
   if (session->connection->has_feature(CEPH_FEATURE_MDS_QUOTA)) {
-    i = ppolicy ? pi : oi;
-    ::encode(i->quota, bl);
+    inode_t *policy_i = ppolicy ? pi : oi;
+    ::encode(policy_i->quota, bl);
+  }
+  if (session->connection->has_feature(CEPH_FEATURE_FS_FILE_LAYOUT_V2)) {
+    ::encode(layout.pool_ns, bl);
   }
 
   return valid;
@@ -3321,20 +3360,20 @@ void CInode::encode_cap_message(MClientCaps *m, Capability *cap)
   inode_t *oi = &inode;
   inode_t *pi = get_projected_inode();
   inode_t *i = (pfile|pauth|plink|pxattr) ? pi : oi;
-  i->ctime.encode_timeval(&m->head.ctime);
-  
+
   dout(20) << "encode_cap_message pfile " << pfile
 	   << " pauth " << pauth << " plink " << plink << " pxattr " << pxattr
 	   << " ctime " << i->ctime << dendl;
 
   i = pfile ? pi:oi;
-  m->head.layout = i->layout;
-  m->head.size = i->size;
-  m->head.truncate_seq = i->truncate_seq;
-  m->head.truncate_size = i->truncate_size;
-  i->mtime.encode_timeval(&m->head.mtime);
-  i->atime.encode_timeval(&m->head.atime);
-  m->head.time_warp_seq = i->time_warp_seq;
+  m->layout = i->layout;
+  m->size = i->size;
+  m->truncate_seq = i->truncate_seq;
+  m->truncate_size = i->truncate_size;
+  m->mtime = i->mtime;
+  m->atime = i->atime;
+  m->ctime = i->ctime;
+  m->time_warp_seq = i->time_warp_seq;
 
   if (cap->client_inline_version < i->inline_data.version) {
     m->inline_version = cap->client_inline_version = i->inline_data.version;
@@ -3347,7 +3386,7 @@ void CInode::encode_cap_message(MClientCaps *m, Capability *cap)
   // max_size is min of projected, actual.
   uint64_t oldms = oi->client_ranges.count(client) ? oi->client_ranges[client].range.last : 0;
   uint64_t newms = pi->client_ranges.count(client) ? pi->client_ranges[client].range.last : 0;
-  m->head.max_size = MIN(oldms, newms);
+  m->max_size = MIN(oldms, newms);
 
   i = pauth ? pi:oi;
   m->head.mode = i->mode;
@@ -3370,14 +3409,14 @@ void CInode::encode_cap_message(MClientCaps *m, Capability *cap)
 
 
 
-void CInode::_encode_base(bufferlist& bl)
+void CInode::_encode_base(bufferlist& bl, uint64_t features)
 {
   ::encode(first, bl);
-  ::encode(inode, bl);
+  ::encode(inode, bl, features);
   ::encode(symlink, bl);
   ::encode(dirfragtree, bl);
   ::encode(xattrs, bl);
-  ::encode(old_inodes, bl);
+  ::encode(old_inodes, bl, features);
   ::encode(damage_flags, bl);
   encode_snap(bl);
 }
@@ -3486,8 +3525,8 @@ void CInode::_decode_locks_rejoin(bufferlist::iterator& p, list<MDSInternalConte
 
 void CInode::encode_export(bufferlist& bl)
 {
-  ENCODE_START(5, 4, bl)
-  _encode_base(bl);
+  ENCODE_START(5, 4, bl);
+  _encode_base(bl, mdcache->mds->mdsmap->get_up_features());
 
   ::encode(state, bl);
 
@@ -3645,11 +3684,10 @@ void InodeStore::generate_test_instances(list<InodeStore*> &ls)
 }
 
 void CInode::validate_disk_state(CInode::validated_data *results,
-                                 MDRequestRef &mdr, MDSInternalContext *fin)
+                                 MDSInternalContext *fin)
 {
   class ValidationContinuation : public MDSContinuation {
   public:
-    MDRequestRef mdr;
     MDSInternalContext *fin;
     CInode *in;
     CInode::validated_data *results;
@@ -3663,17 +3701,10 @@ void CInode::validate_disk_state(CInode::validated_data *results,
       DIRFRAGS
     };
 
-    /**
-     * May set either mdr or fin, depending on whether caller is doing
-     * validation in a single MDRequest (i.e. asok) or caller is doing
-     * their own thing (i.e. ScrubStack)
-     */
     ValidationContinuation(CInode *i,
                            CInode::validated_data *data_r,
-                           MDRequestRef &_mdr,
                            MDSInternalContext *fin_) :
                              MDSContinuation(i->mdcache->mds->server),
-                             mdr(_mdr),
                              fin(fin_),
                              in(i),
                              results(data_r),
@@ -3698,28 +3729,23 @@ void CInode::validate_disk_state(CInode::validated_data *results,
       if (in->is_dir())
         pool = in->mdcache->mds->mdsmap->get_metadata_pool();
       else
-        pool = in->inode.layout.fl_pg_pool;
+        pool = in->inode.layout.pool_id;
 
       object_t oid = CInode::get_object_name(in->ino(), frag_t(), "");
 
       ObjectOperation fetch;
-
       fetch.getxattr("parent", bt, bt_r);
-      // We want to tag even if we get ENODATA fetching the backtrace
-      fetch.set_last_op_flags(CEPH_OSD_OP_FLAG_FAILOK);
+      in->mdcache->mds->objecter->read(oid, object_locator_t(pool), fetch, CEPH_NOSNAP,
+				       NULL, 0, fin);
       if (!tag.empty()) {
+	ObjectOperation scrub_tag;
         bufferlist tag_bl;
         ::encode(tag, tag_bl);
-        fetch.setxattr("scrub_tag", tag_bl);
-      }
-      if (tag.empty()) {
-        in->mdcache->mds->objecter->read(oid, object_locator_t(pool), fetch, CEPH_NOSNAP,
-            NULL, 0, fin);
-      } else {
-	SnapContext snapc;
-	in->mdcache->mds->objecter->mutate(oid, object_locator_t(pool), fetch,
-					   snapc,ceph::real_clock::now(
-					     g_ceph_context), 0, NULL, fin);
+        scrub_tag.setxattr("scrub_tag", tag_bl);
+        SnapContext snapc;
+        in->mdcache->mds->objecter->mutate(oid, object_locator_t(pool), scrub_tag, snapc,
+					   ceph::real_clock::now(g_ceph_context),
+					   0, NULL, NULL);
       }
     }
 
@@ -3732,21 +3758,17 @@ void CInode::validate_disk_state(CInode::validated_data *results,
       }
       if (in->is_symlink()) {
         // there's nothing to do for symlinks!
-        results->passed_validation = true;
         return true;
       }
 
-      results->passed_validation = false; // we haven't finished it yet
-
       C_OnFinisher *conf = new C_OnFinisher(get_io_callback(BACKTRACE),
                                             in->mdcache->mds->finisher);
 
       // Whether we have a tag to apply depends on ScrubHeader (if one is
       // present)
-      if (in->get_parent_dn() != nullptr &&
-          in->get_parent_dn()->scrub_info()->header != nullptr) {
+      if (in->scrub_infop && in->scrub_infop->header) {
         // I'm a non-orphan, so look up my ScrubHeader via my linkage
-        const std::string &tag = in->get_parent_dn()->scrub_info()->header->tag;
+        const std::string &tag = in->scrub_infop->header->tag;
         // Rather than using the usual CInode::fetch_backtrace,
         // use a special variant that optionally writes a tag in the same
         // operation.
@@ -3765,14 +3787,23 @@ void CInode::validate_disk_state(CInode::validated_data *results,
       // set up basic result reporting and make sure we got the data
       results->performed_validation = true; // at least, some of it!
       results->backtrace.checked = true;
-      results->backtrace.passed = false; // we'll set it true if we make it
+
+      int64_t pool;
+      if (in->is_dir())
+        pool = in->mdcache->mds->mdsmap->get_metadata_pool();
+      else
+        pool = in->inode.layout.pool_id;
+      inode_backtrace_t& memory_backtrace = results->backtrace.memory_value;
+      in->build_backtrace(pool, memory_backtrace);
+      bool equivalent, divergent;
+      int memory_newer;
 
       // Ignore rval because it's the result of a FAILOK operation
       // from fetch_backtrace_and_tag: the real result is in
       // backtrace.ondisk_read_retval
       if (results->backtrace.ondisk_read_retval != 0) {
         results->backtrace.error_str << "failed to read off disk; see retval";
-        return true;
+	goto next;
       }
 
       // extract the backtrace, and compare it to a newly-constructed one
@@ -3788,35 +3819,26 @@ void CInode::validate_disk_state(CInode::validated_data *results,
         }
         results->backtrace.error_str << "failed to decode on-disk backtrace ("
                                      << bl.length() << " bytes)!";
-        return true;
+	goto next;
       }
-      int64_t pool;
-      if (in->is_dir())
-        pool = in->mdcache->mds->mdsmap->get_metadata_pool();
-      else
-        pool = in->inode.layout.fl_pg_pool;
-      inode_backtrace_t& memory_backtrace = results->backtrace.memory_value;
-      in->build_backtrace(pool, memory_backtrace);
-      bool equivalent, divergent;
-      int memory_newer =
-          memory_backtrace.compare(results->backtrace.ondisk_value,
-                                   &equivalent, &divergent);
+
+      memory_newer = memory_backtrace.compare(results->backtrace.ondisk_value,
+					      &equivalent, &divergent);
+
       if (equivalent) {
         results->backtrace.passed = true;
       } else {
-        results->backtrace.passed = false; // we couldn't validate :(
         if (divergent || memory_newer <= 0) {
           // we're divergent, or don't have a newer version to write
           results->backtrace.error_str <<
               "On-disk backtrace is divergent or newer";
-          return true;
+	  goto next;
         }
       }
-
+next:
       // quit if we're a file, or kick off directory checks otherwise
       // TODO: validate on-disk inode for non-base directories
-      if (in->is_file() || in->is_symlink()) {
-        results->passed_validation = true;
+      if (!in->is_dir()) {
         return true;
       }
 
@@ -3834,14 +3856,14 @@ void CInode::validate_disk_state(CInode::validated_data *results,
         shadow_in->fetch(get_internal_callback(INODE));
         return false;
       } else {
-        return fetch_dirfrag_rstats();
+	results->inode.passed = true;
+        return check_dirfrag_rstats();
       }
     }
 
     bool _inode_disk(int rval) {
       results->inode.checked = true;
       results->inode.ondisk_read_retval = rval;
-      results->inode.passed = false;
       results->inode.ondisk_value = shadow_in->inode;
       results->inode.memory_value = in->inode;
 
@@ -3850,7 +3872,7 @@ void CInode::validate_disk_state(CInode::validated_data *results,
       if (si.version > i.version) {
         // uh, what?
         results->inode.error_str << "On-disk inode is newer than in-memory one!";
-        return true;
+	goto next;
       } else {
         bool divergent = false;
         int r = i.compare(si, &divergent);
@@ -3858,22 +3880,30 @@ void CInode::validate_disk_state(CInode::validated_data *results,
         if (!results->inode.passed) {
           results->inode.error_str <<
               "On-disk inode is divergent or newer than in-memory one!";
-          return true;
+	  goto next;
         }
       }
-      return fetch_dirfrag_rstats();
+next:
+      return check_dirfrag_rstats();
     }
 
-    bool fetch_dirfrag_rstats() {
+    bool check_dirfrag_rstats() {
       MDSGatherBuilder gather(g_ceph_context);
       std::list<frag_t> frags;
       in->dirfragtree.get_leaves(frags);
       for (list<frag_t>::iterator p = frags.begin();
           p != frags.end();
           ++p) {
-        CDir *dirfrag = in->get_or_open_dirfrag(in->mdcache, *p);
-        if (!dirfrag->is_complete())
-          dirfrag->fetch(gather.new_sub(), false);
+        CDir *dir = in->get_or_open_dirfrag(in->mdcache, *p);
+	dir->scrub_info();
+	if (!dir->scrub_infop->header && in->scrub_infop)
+	  dir->scrub_infop->header = in->scrub_infop->header;
+        if (dir->is_complete()) {
+	  dir->scrub_local();
+	} else {
+	  dir->scrub_infop->need_scrub_local = true;
+	  dir->fetch(gather.new_sub(), false);
+	}
       }
       if (gather.has_subs()) {
         gather.set_finisher(get_internal_callback(DIRFRAGS));
@@ -3885,46 +3915,73 @@ void CInode::validate_disk_state(CInode::validated_data *results,
     }
 
     bool _dirfrags(int rval) {
+      int frags_errors = 0;
       // basic reporting setup
-      results->raw_rstats.checked = true;
-      results->raw_rstats.ondisk_read_retval = rval;
-      results->raw_rstats.passed = false; // we'll set it true if we make it
+      results->raw_stats.checked = true;
+      results->raw_stats.ondisk_read_retval = rval;
+
+      results->raw_stats.memory_value.dirstat = in->inode.dirstat;
+      results->raw_stats.memory_value.rstat = in->inode.rstat;
+      frag_info_t& dir_info = results->raw_stats.ondisk_value.dirstat;
+      nest_info_t& nest_info = results->raw_stats.ondisk_value.rstat;
+
       if (rval != 0) {
-        results->raw_rstats.error_str << "Failed to read dirfrags off disk";
-        return true;
+        results->raw_stats.error_str << "Failed to read dirfrags off disk";
+	goto next;
       }
 
       // check each dirfrag...
-      nest_info_t& sub_info = results->raw_rstats.ondisk_value;
       for (compact_map<frag_t,CDir*>::iterator p = in->dirfrags.begin();
 	   p != in->dirfrags.end();
 	   ++p) {
-        if (!p->second->is_complete()) {
-          results->raw_rstats.error_str << "dirfrag is INCOMPLETE despite fetching; probably too large compared to MDS cache size?\n";
-          return true;
-        }
-        // FIXME!!! Don't assert out on damage!
-        assert(p->second->scrub_local());
-        sub_info.add(p->second->fnode.accounted_rstat);
+	CDir *dir = p->second;
+	assert(dir->get_version() > 0);
+	nest_info.add(dir->fnode.accounted_rstat);
+	dir_info.add(dir->fnode.accounted_fragstat);
+	if (dir->scrub_infop &&
+	    dir->scrub_infop->pending_scrub_error) {
+	  dir->scrub_infop->pending_scrub_error = false;
+	  if (dir->scrub_infop->header &&
+	      dir->scrub_infop->header->repair) {
+	    results->raw_stats.error_str
+	      << "dirfrag(" << p->first << ") has bad stats (will be fixed); ";
+	  } else {
+	    results->raw_stats.error_str
+	      << "dirfrag(" << p->first << ") has bad stats; ";
+	  }
+	  frags_errors++;
+	}
       }
+      nest_info.rsubdirs++; // it gets one to account for self
       // ...and that their sum matches our inode settings
-      results->raw_rstats.memory_value = in->inode.rstat;
-      sub_info.rsubdirs++; // it gets one to account for self
-      if (!sub_info.same_sums(in->inode.rstat)) {
-        results->raw_rstats.error_str
-        << "freshly-calculated rstats don't match existing ones";
-        return true;
+      if (!dir_info.same_sums(in->inode.dirstat) ||
+	  !nest_info.same_sums(in->inode.rstat)) {
+	if (in->scrub_infop &&
+	    in->scrub_infop->header &&
+	    in->scrub_infop->header->repair) {
+	  results->raw_stats.error_str
+	    << "freshly-calculated rstats don't match existing ones (will be fixed)";
+	  in->mdcache->repair_inode_stats(in);
+	} else {
+	  results->raw_stats.error_str
+	    << "freshly-calculated rstats don't match existing ones";
+	}
+	goto next;
       }
-      results->raw_rstats.passed = true;
-      // Hurray! We made it through!
-      results->passed_validation = true;
+      if (frags_errors > 0)
+	goto next;
+
+      results->raw_stats.passed = true;
+next:
       return true;
     }
 
     void _done() {
-      if (mdr) {
-        server->respond_to_request(mdr, get_rval());
-      } else if (fin) {
+      if ((!results->raw_stats.checked || results->raw_stats.passed) &&
+	  (!results->backtrace.checked || results->backtrace.passed) &&
+	  (!results->inode.checked || results->inode.passed))
+        results->passed_validation = true;
+      if (fin) {
         fin->complete(get_rval());
       }
     }
@@ -3934,7 +3991,6 @@ void CInode::validate_disk_state(CInode::validated_data *results,
   dout(10) << "scrub starting validate_disk_state on " << *this << dendl;
   ValidationContinuation *vc = new ValidationContinuation(this,
                                                           results,
-                                                          mdr,
                                                           fin);
   vc->begin();
 }
@@ -3955,24 +4011,26 @@ void CInode::validated_data::dump(Formatter *f) const
       f->dump_string("error_str", backtrace.error_str.str());
     }
     f->close_section(); // backtrace
-    f->open_object_section("raw_rstats");
+    f->open_object_section("raw_stats");
     {
-      f->dump_bool("checked", raw_rstats.checked);
-      f->dump_bool("passed", raw_rstats.passed);
-      f->dump_int("read_ret_val", raw_rstats.ondisk_read_retval);
-      f->dump_stream("ondisk_value") << raw_rstats.ondisk_value;
-      f->dump_stream("memory_value") << raw_rstats.memory_value;
-      f->dump_string("error_str", raw_rstats.error_str.str());
+      f->dump_bool("checked", raw_stats.checked);
+      f->dump_bool("passed", raw_stats.passed);
+      f->dump_int("read_ret_val", raw_stats.ondisk_read_retval);
+      f->dump_stream("ondisk_value.dirstat") << raw_stats.ondisk_value.dirstat;
+      f->dump_stream("ondisk_value.rstat") << raw_stats.ondisk_value.rstat;
+      f->dump_stream("memory_value.dirrstat") << raw_stats.memory_value.dirstat;
+      f->dump_stream("memory_value.rstat") << raw_stats.memory_value.rstat;
+      f->dump_string("error_str", raw_stats.error_str.str());
     }
-    f->close_section(); // raw_rstats
+    f->close_section(); // raw_stats
     // dump failure return code
     int rc = 0;
     if (backtrace.checked && backtrace.ondisk_read_retval)
       rc = backtrace.ondisk_read_retval;
     if (inode.checked && inode.ondisk_read_retval)
       rc = inode.ondisk_read_retval;
-    if (raw_rstats.checked && raw_rstats.ondisk_read_retval)
-      rc = raw_rstats.ondisk_read_retval;
+    if (raw_stats.checked && raw_stats.ondisk_read_retval)
+      rc = raw_stats.ondisk_read_retval;
     f->dump_int("return_code", rc);
   }
   f->close_section(); // results
@@ -4110,10 +4168,11 @@ void CInode::scrub_maybe_delete_info()
   }
 }
 
-void CInode::scrub_initialize(version_t scrub_version)
+void CInode::scrub_initialize(CDentry *scrub_parent,
+			      const ScrubHeaderRefConst& header,
+			      MDSInternalContextBase *f)
 {
-  dout(20) << __func__ << " with scrub_version "
-           << scrub_version << dendl;
+  dout(20) << __func__ << " with scrub_version " << get_version() << dendl;
   assert(!scrub_infop || !scrub_infop->scrub_in_progress);
   scrub_info();
   if (!scrub_infop)
@@ -4128,11 +4187,22 @@ void CInode::scrub_initialize(version_t scrub_version)
     for (std::list<frag_t>::iterator i = frags.begin();
         i != frags.end();
         ++i) {
-      scrub_infop->dirfrag_stamps[*i];
+      if (header->force)
+	scrub_infop->dirfrag_stamps[*i].reset();
+      else
+	scrub_infop->dirfrag_stamps[*i];
     }
   }
+
+  if (scrub_parent)
+    scrub_parent->get(CDentry::PIN_SCRUBPARENT);
+  scrub_infop->scrub_parent = scrub_parent;
+  scrub_infop->on_finish = f;
   scrub_infop->scrub_in_progress = true;
-  scrub_infop->scrub_start_version = scrub_version;
+  scrub_infop->children_scrubbed = false;
+  scrub_infop->header = header;
+
+  scrub_infop->scrub_start_version = get_version();
   scrub_infop->scrub_start_stamp = ceph_clock_now(g_ceph_context);
   // right now we don't handle remote inodes
 }
@@ -4199,7 +4269,7 @@ void CInode::scrub_dirfrag_finished(frag_t dirfrag)
   si.last_scrub_version = si.scrub_start_version;
 }
 
-void CInode::scrub_finished(Context **c) {
+void CInode::scrub_finished(MDSInternalContextBase **c) {
   dout(20) << __func__ << dendl;
   assert(scrub_info()->scrub_in_progress);
   for (std::map<frag_t, scrub_stamp_info_t>::iterator i =
@@ -4212,9 +4282,25 @@ void CInode::scrub_finished(Context **c) {
     }
     assert(i->second.last_scrub_version == i->second.scrub_start_version);
   }
+
   scrub_infop->last_scrub_version = scrub_infop->scrub_start_version;
   scrub_infop->last_scrub_stamp = scrub_infop->scrub_start_stamp;
   scrub_infop->last_scrub_dirty = true;
   scrub_infop->scrub_in_progress = false;
-  parent->scrub_finished(c);
+
+  if (scrub_infop->scrub_parent) {
+    CDentry *dn = scrub_infop->scrub_parent;
+    scrub_infop->scrub_parent = NULL;
+    dn->dir->scrub_dentry_finished(dn);
+    dn->put(CDentry::PIN_SCRUBPARENT);
+  }
+
+  *c = scrub_infop->on_finish;
+  scrub_infop->on_finish = NULL;
+
+  if (scrub_infop->header && scrub_infop->header->origin == this) {
+    // We are at the point that a tagging scrub was initiated
+    LogChannelRef clog = mdcache->mds->clog;
+    clog->info() << "scrub complete with tag '" << scrub_infop->header->tag << "'";
+  }
 }
diff --git a/src/mds/CInode.h b/src/mds/CInode.h
index 15fef42..9260c4b 100644
--- a/src/mds/CInode.h
+++ b/src/mds/CInode.h
@@ -89,11 +89,11 @@ public:
   static object_t get_object_name(inodeno_t ino, frag_t fg, const char *suffix);
 
   /* Full serialization for use in ".inode" root inode objects */
-  void encode(bufferlist &bl, const bufferlist *snap_blob=NULL) const;
+  void encode(bufferlist &bl, uint64_t features, const bufferlist *snap_blob=NULL) const;
   void decode(bufferlist::iterator &bl, bufferlist& snap_blob);
 
   /* Serialization without ENCODE_START/FINISH blocks for use embedded in dentry */
-  void encode_bare(bufferlist &bl, const bufferlist *snap_blob=NULL) const;
+  void encode_bare(bufferlist &bl, uint64_t features, const bufferlist *snap_blob=NULL) const;
   void decode_bare(bufferlist::iterator &bl, bufferlist &snap_blob, __u8 struct_v=5);
 
   /* For test/debug output */
@@ -108,14 +108,14 @@ class InodeStore : public InodeStoreBase {
 public:
   bufferlist snap_blob;  // Encoded copy of SnapRealm, because we can't
 			 // rehydrate it without full MDCache
-  void encode(bufferlist &bl) const {
-    InodeStoreBase::encode(bl, &snap_blob);
+  void encode(bufferlist &bl, uint64_t features) const {
+    InodeStoreBase::encode(bl, features, &snap_blob);
   }
   void decode(bufferlist::iterator &bl) {
     InodeStoreBase::decode(bl, snap_blob);
   }
-  void encode_bare(bufferlist &bl) const {
-    InodeStoreBase::encode_bare(bl, &snap_blob);
+  void encode_bare(bufferlist &bl, uint64_t features) const {
+    InodeStoreBase::encode_bare(bl, features, &snap_blob);
   }
   void decode_bare(bufferlist::iterator &bl) {
     InodeStoreBase::decode_bare(bl, snap_blob);
@@ -123,6 +123,7 @@ public:
 
   static void generate_test_instances(std::list<InodeStore*>& ls);
 };
+WRITE_CLASS_ENCODER_FEATURES(InodeStore)
 
 // cached inode wrapper
 class CInode : public MDSCacheObject, public InodeStoreBase {
@@ -170,6 +171,7 @@ public:
   static const int PIN_EXPORTINGCAPS =    22;
   static const int PIN_DIRTYPARENT =      23;
   static const int PIN_DIRWAITER =        24;
+  static const int PIN_SCRUBQUEUE =       25;
 
   const char *pin_name(int p) const {
     switch (p) {
@@ -194,6 +196,7 @@ public:
     case PIN_DIRTYRSTAT: return "dirtyrstat";
     case PIN_DIRTYPARENT: return "dirtyparent";
     case PIN_DIRWAITER: return "dirwaiter";
+    case PIN_SCRUBQUEUE: return "scrubqueue";
     default: return generic_pin_name(p);
     }
   }
@@ -213,6 +216,7 @@ public:
   static const int STATE_STRAYPINNED = (1<<16);
   static const int STATE_FROZENAUTHPIN = (1<<17);
   static const int STATE_DIRTYPOOL =   (1<<18);
+  static const int STATE_REPAIRSTATS = (1<<19);
   // orphan inode needs notification of releasing reference
   static const int STATE_ORPHAN =	STATE_NOTIFYREF;
 
@@ -253,17 +257,30 @@ public:
     /// time we started our most recent finished scrub
     utime_t last_scrub_stamp;
     scrub_stamp_info_t() : scrub_start_version(0), last_scrub_version(0) {}
+    void reset() {
+      scrub_start_version = 0;
+      scrub_start_stamp = utime_t();
+    }
   };
 
   class scrub_info_t : public scrub_stamp_info_t {
   public:
+    CDentry *scrub_parent;
+    MDSInternalContextBase *on_finish;
+
     bool last_scrub_dirty; /// are our stamps dirty with respect to disk state?
     bool scrub_in_progress; /// are we currently scrubbing?
+    bool children_scrubbed;
+
     /// my own (temporary) stamps and versions for each dirfrag we have
     std::map<frag_t, scrub_stamp_info_t> dirfrag_stamps;
 
-    scrub_info_t() : scrub_stamp_info_t(), last_scrub_dirty(false),
-        scrub_in_progress(false) {}
+    ScrubHeaderRefConst header;
+
+    scrub_info_t() : scrub_stamp_info_t(),
+	scrub_parent(NULL), on_finish(NULL),
+	last_scrub_dirty(false), scrub_in_progress(false),
+	children_scrubbed(false) {}
   };
 
   const scrub_info_t *scrub_info() const{
@@ -279,7 +296,9 @@ public:
    * @param scrub_version What version are we scrubbing at (usually, parent
    * directory's get_projected_version())
    */
-  void scrub_initialize(version_t scrub_version);
+  void scrub_initialize(CDentry *scrub_parent,
+			const ScrubHeaderRefConst& header,
+			MDSInternalContextBase *f);
   /**
    * Get the next dirfrag to scrub. Gives you a frag_t in output param which
    * you must convert to a CDir (and possibly load off disk).
@@ -310,7 +329,17 @@ public:
    * @param c An out param which is filled in with a Context* that must
    * be complete()ed.
    */
-  void scrub_finished(Context **c);
+  void scrub_finished(MDSInternalContextBase **c);
+  /**
+   * Report to the CInode that alldirfrags it owns have been scrubbed.
+   */
+  void scrub_children_finished() {
+    scrub_infop->children_scrubbed = true;
+  }
+  void scrub_set_finisher(MDSInternalContextBase *c) {
+    assert(!scrub_infop->on_finish);
+    scrub_infop->on_finish = c;
+  }
 
 private:
   /**
@@ -542,7 +571,7 @@ protected:
 
   ceph_lock_state_t *get_fcntl_lock_state() {
     if (!fcntl_locks)
-      fcntl_locks = new ceph_lock_state_t(g_ceph_context);
+      fcntl_locks = new ceph_lock_state_t(g_ceph_context, CEPH_LOCK_FCNTL);
     return fcntl_locks;
   }
   void clear_fcntl_lock_state() {
@@ -551,7 +580,7 @@ protected:
   }
   ceph_lock_state_t *get_flock_lock_state() {
     if (!flock_locks)
-      flock_locks = new ceph_lock_state_t(g_ceph_context);
+      flock_locks = new ceph_lock_state_t(g_ceph_context, CEPH_LOCK_FLOCK);
     return flock_locks;
   }
   void clear_flock_lock_state() {
@@ -596,6 +625,7 @@ public:
   elist<CInode*>::item item_dirty_dirfrag_dir;
   elist<CInode*>::item item_dirty_dirfrag_nest;
   elist<CInode*>::item item_dirty_dirfrag_dirfragtree;
+  elist<CInode*>::item item_scrub;
 
 public:
   int auth_pin_freeze_allowance;
@@ -743,10 +773,10 @@ public:
 
   void encode_snap_blob(bufferlist &bl);
   void decode_snap_blob(bufferlist &bl);
-  void encode_store(bufferlist& bl);
+  void encode_store(bufferlist& bl, uint64_t features);
   void decode_store(bufferlist::iterator& bl);
 
-  void encode_replica(mds_rank_t rep, bufferlist& bl) {
+  void encode_replica(mds_rank_t rep, bufferlist& bl, uint64_t features) {
     assert(is_auth());
     
     // relax locks?
@@ -756,7 +786,7 @@ public:
     __u32 nonce = add_replica(rep);
     ::encode(nonce, bl);
     
-    _encode_base(bl);
+    _encode_base(bl, features);
     _encode_locks_state_for_replica(bl);
   }
   void decode_replica(bufferlist::iterator& p, bool is_new) {
@@ -781,7 +811,7 @@ public:
   void take_waiting(uint64_t tag, std::list<MDSInternalContextBase*>& ls);
 
   // -- encode/decode helpers --
-  void _encode_base(bufferlist& bl);
+  void _encode_base(bufferlist& bl, uint64_t features);
   void _decode_base(bufferlist::iterator& p);
   void _encode_locks_full(bufferlist& bl);
   void _decode_locks_full(bufferlist::iterator& p);
@@ -954,7 +984,7 @@ public:
   int get_caps_allowed_by_type(int type) const;
   int get_caps_careful() const;
   int get_xlocker_mask(client_t client) const;
-  int get_caps_allowed_for_client(client_t client) const;
+  int get_caps_allowed_for_client(Session *s, inode_t *file_i) const;
 
   // caps issued, wanted
   int get_caps_issued(int *ploner = 0, int *pother = 0, int *pxlocker = 0,
@@ -1075,9 +1105,14 @@ public:
     bool performed_validation;
     bool passed_validation;
 
+    struct raw_stats_t {
+      frag_info_t dirstat;
+      nest_info_t rstat;
+    };
+
     member_status<inode_backtrace_t> backtrace;
     member_status<inode_t> inode;
-    member_status<nest_info_t> raw_rstats;
+    member_status<raw_stats_t> raw_stats;
 
     validated_data() : performed_validation(false),
         passed_validation(false) {}
@@ -1099,7 +1134,6 @@ public:
    * @param fin Context to call back on completion (or NULL)
    */
   void validate_disk_state(validated_data *results,
-                           MDRequestRef& mdr,
                            MDSInternalContext *fin);
   static void dump_validation_results(const validated_data& results,
                                       Formatter *f);
diff --git a/src/mds/DamageTable.cc b/src/mds/DamageTable.cc
new file mode 100644
index 0000000..1c7b191
--- /dev/null
+++ b/src/mds/DamageTable.cc
@@ -0,0 +1,166 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- 
+// vim: ts=8 sw=2 smarttab
+/*
+ * Ceph - scalable distributed file system
+ *
+ * Copyright (C) 2004-2006 Sage Weil <sage at newdream.net>
+ *
+ * This is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software 
+ * Foundation.  See file COPYING.
+ * 
+ */
+
+#include "common/debug.h"
+
+#include "mds/CDir.h"
+
+#include "DamageTable.h"
+
+#define dout_subsys ceph_subsys_mds
+#undef dout_prefix
+#define dout_prefix *_dout << "mds." << rank << ".damage " << __func__ << " "
+
+
+DamageEntry::~DamageEntry()
+{}
+
+bool DamageTable::notify_dentry(
+    inodeno_t ino, frag_t frag,
+    snapid_t snap_id, const std::string &dname)
+{
+  if (oversized()) {
+    return true;
+  }
+
+  // Special cases: damage to these dirfrags is considered fatal to
+  // the MDS rank that owns them.
+  if (
+      (MDS_INO_IS_MDSDIR(ino) && MDS_INO_MDSDIR_OWNER(ino) == rank)
+      ||
+      (MDS_INO_IS_STRAY(ino) && MDS_INO_STRAY_OWNER(ino) == rank)
+     ) {
+    derr << "Damage to dentries in fragment " << frag << " of ino " << ino
+         << "is fatal because it is a system directory for this rank" << dendl;
+    return true;
+  }
+
+  DamageEntryRef entry = std::make_shared<DentryDamage>(
+      ino, frag, dname, snap_id);
+  dentries[DirFragIdent(ino, frag)][DentryIdent(dname, snap_id)] = entry;
+  by_id[entry->id] = entry;
+
+  return false;
+}
+
+bool DamageTable::notify_dirfrag(inodeno_t ino, frag_t frag)
+{
+  // Special cases: damage to these dirfrags is considered fatal to
+  // the MDS rank that owns them.
+  if (
+      (MDS_INO_IS_STRAY(ino) && MDS_INO_STRAY_OWNER(ino) == rank)
+      ||
+      (ino == MDS_INO_ROOT)
+     ) {
+    derr << "Damage to fragment " << frag << " of ino " << ino
+         << " is fatal because it is a system directory for this rank" << dendl;
+    return true;
+  }
+
+  if (oversized()) {
+    return true;
+  }
+
+  DamageEntryRef entry = std::make_shared<DirFragDamage>(ino, frag);
+  dirfrags[DirFragIdent(ino, frag)] = entry;
+  by_id[entry->id] = entry;
+
+  return false;
+}
+
+bool DamageTable::notify_remote_damaged(inodeno_t ino)
+{
+  if (oversized()) {
+    return true;
+  }
+
+  auto entry = std::make_shared<BacktraceDamage>(ino);
+  remotes[ino] = entry;
+  by_id[entry->id] = entry;
+
+  return false;
+}
+
+bool DamageTable::oversized() const
+{
+  return by_id.size() > (size_t)(g_conf->mds_damage_table_max_entries);
+}
+
+bool DamageTable::is_dentry_damaged(
+        const CDir *dir_frag,
+        const std::string &dname,
+        const snapid_t snap_id) const
+{
+  if (dentries.count(
+        DirFragIdent(dir_frag->inode->ino(), dir_frag->frag)
+        ) == 0) {
+    return false;
+  }
+
+  const std::map<DentryIdent, DamageEntryRef> &frag_dentries =
+    dentries.at(DirFragIdent(dir_frag->inode->ino(), dir_frag->frag));
+
+  return frag_dentries.count(DentryIdent(dname, snap_id)) > 0;
+}
+
+bool DamageTable::is_dirfrag_damaged(
+    const CDir *dir_frag) const
+{
+  return dirfrags.count(
+      DirFragIdent(dir_frag->inode->ino(), dir_frag->frag)) > 0;
+}
+
+bool DamageTable::is_remote_damaged(
+    const inodeno_t ino) const
+{
+  return remotes.count(ino) > 0;
+}
+
+void DamageTable::dump(Formatter *f) const
+{
+  f->open_array_section("damage_table");
+  for (const auto &i : by_id)
+  {
+    i.second->dump(f);
+  }
+  f->close_section();
+}
+
+void DamageTable::erase(damage_entry_id_t damage_id)
+{
+  if (by_id.count(damage_id) == 0) {
+    return;
+  }
+
+  DamageEntryRef entry = by_id.at(damage_id);
+  assert(entry->id == damage_id);  // Sanity
+
+  const auto type = entry->get_type();
+  if (type == DAMAGE_ENTRY_DIRFRAG) {
+    auto dirfrag_entry = std::static_pointer_cast<DirFragDamage>(entry);
+    dirfrags.erase(DirFragIdent(dirfrag_entry->ino, dirfrag_entry->frag));
+  } else if (type == DAMAGE_ENTRY_DENTRY) {
+    auto dentry_entry = std::static_pointer_cast<DentryDamage>(entry);
+    dentries.erase(DirFragIdent(dentry_entry->ino, dentry_entry->frag));
+  } else if (type == DAMAGE_ENTRY_BACKTRACE) {
+    auto backtrace_entry = std::static_pointer_cast<BacktraceDamage>(entry);
+    remotes.erase(backtrace_entry->ino);
+  } else {
+    derr << "Invalid type " << type << dendl;
+    assert(0);
+  }
+
+  by_id.erase(damage_id);
+}
+
diff --git a/src/mds/DamageTable.h b/src/mds/DamageTable.h
new file mode 100644
index 0000000..cd82911
--- /dev/null
+++ b/src/mds/DamageTable.h
@@ -0,0 +1,296 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+/*
+ * Ceph - scalable distributed file system
+ *
+ * Copyright (C) 2004-2006 Sage Weil <sage at newdream.net>
+ *
+ * This is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software
+ * Foundation.  See file COPYING.
+ *
+ */
+
+
+#ifndef DAMAGE_TABLE_H_
+#define DAMAGE_TABLE_H_
+
+#include "mdstypes.h"
+#include "auth/Crypto.h"
+
+class CDir;
+
+typedef uint64_t damage_entry_id_t;
+
+typedef enum
+{
+  DAMAGE_ENTRY_DIRFRAG,
+  DAMAGE_ENTRY_DENTRY,
+  DAMAGE_ENTRY_BACKTRACE
+
+} damage_entry_type_t;
+
+class DamageEntry
+{
+  public:
+  damage_entry_id_t id;
+  utime_t reported_at;
+
+  DamageEntry()
+  {
+    id = get_random(0, 0xffffffff);
+    reported_at = ceph_clock_now(g_ceph_context);
+  }
+
+  virtual damage_entry_type_t get_type() const = 0;
+
+  virtual ~DamageEntry();
+
+  virtual void dump(Formatter *f) const = 0;
+};
+
+
+typedef ceph::shared_ptr<DamageEntry> DamageEntryRef;
+
+/**
+ * Record damage to a particular dirfrag, implicitly affecting
+ * any dentries within it.
+ */
+class DirFragDamage : public DamageEntry
+{
+  public:
+  inodeno_t ino;
+  frag_t frag;
+
+  DirFragDamage(inodeno_t ino_, frag_t frag_)
+    : ino(ino_), frag(frag_)
+  {}
+
+  virtual damage_entry_type_t get_type() const
+  {
+    return DAMAGE_ENTRY_DIRFRAG;
+  }
+
+  void dump(Formatter *f) const
+  {
+    f->open_object_section("dir_frag_damage");
+    f->dump_string("damage_type", "dir_frag");
+    f->dump_int("id", id);
+    f->dump_int("ino", ino);
+    f->dump_stream("frag") << frag;
+    f->close_section();
+  }
+};
+
+
+/**
+ * Record damage to a particular dname within a particular dirfrag
+ */
+class DentryDamage : public DamageEntry
+{
+  public:
+  inodeno_t ino;
+  frag_t frag;
+  std::string dname;
+  snapid_t snap_id;
+
+  DentryDamage(
+      inodeno_t ino_,
+      frag_t frag_,
+      std::string dname_,
+      snapid_t snap_id_)
+    : ino(ino_), frag(frag_), dname(dname_), snap_id(snap_id_)
+  {}
+
+  virtual damage_entry_type_t get_type() const
+  {
+    return DAMAGE_ENTRY_DENTRY;
+  }
+
+  void dump(Formatter *f) const
+  {
+    f->open_object_section("dentry_damage");
+    f->dump_string("damage_type", "dentry");
+    f->dump_int("id", id);
+    f->dump_int("ino", ino);
+    f->dump_stream("frag") << frag;
+    f->dump_string("dname", dname);
+    f->dump_stream("snap_id") << snap_id;
+    f->close_section();
+  }
+};
+
+
+/**
+ * Record damage to our ability to look up an ino by number
+ */
+class BacktraceDamage : public DamageEntry
+{
+  public:
+  inodeno_t ino;
+
+  BacktraceDamage(inodeno_t ino_)
+    : ino(ino_)
+  {}
+
+  virtual damage_entry_type_t get_type() const
+  {
+    return DAMAGE_ENTRY_BACKTRACE;
+  }
+
+  void dump(Formatter *f) const
+  {
+    f->open_object_section("backtrace_damage");
+    f->dump_string("damage_type", "backtrace");
+    f->dump_int("id", id);
+    f->dump_int("ino", ino);
+    f->close_section();
+  }
+};
+
+class DirFragIdent
+{
+  public:
+  inodeno_t ino;
+  frag_t frag;
+
+  bool operator<(const DirFragIdent &rhs) const
+  {
+    if (ino == rhs.ino) {
+      return frag < rhs.frag;
+    } else {
+      return ino < rhs.ino;
+    }
+  }
+
+  DirFragIdent(inodeno_t ino_, frag_t frag_)
+    : ino(ino_), frag(frag_)
+  {}
+};
+
+class DentryIdent
+{
+  public:
+  std::string dname;
+  snapid_t snap_id;
+
+  bool operator<(const DentryIdent &rhs) const
+  {
+    if (dname == rhs.dname) {
+      return snap_id < rhs.snap_id;
+    } else {
+      return dname < rhs.dname;
+    }
+  }
+
+  DentryIdent(const std::string &dname_, snapid_t snap_id_)
+    : dname(dname_), snap_id(snap_id_)
+  {}
+};
+
+/**
+ * Registry of in-RADOS metadata damage identified
+ * during forward scrub or during normal fetches.
+ *
+ * Used to indicate damage to the administrator, and
+ * to cache known-bad paths so that we don't hit them
+ * repeatedly.
+ *
+ * Callers notifying damage must check return code; if
+ * an fatal condition is indicated then they should mark the MDS
+ * rank damaged.
+ *
+ * An artificial limit on the number of damage entries
+ * is imposed to avoid this structure growing indefinitely.  If
+ * a notification causes the limit to be exceeded, the fatal
+ * condition will be indicated in the return code and the MDS
+ * rank should be marked damaged.
+ *
+ * Protected by MDS::mds_lock
+ */
+class DamageTable
+{
+protected:
+
+  // Map of all dirfrags reported damaged
+  std::map<DirFragIdent, DamageEntryRef> dirfrags;
+
+  // Store dentries in a map per dirfrag, so that we can
+  // readily look up all the bad dentries in a particular
+  // dirfrag
+  std::map<DirFragIdent, std::map<DentryIdent, DamageEntryRef> > dentries;
+
+  // Map of all inodes which could not be resolved remotely
+  // (i.e. have probably/possibly missing backtraces)
+  std::map<inodeno_t, DamageEntryRef> remotes;
+
+  // All damage, by ID.  This is a secondary index
+  // to the dirfrag, dentry, remote maps.  It exists
+  // to enable external tools to unambiguously operate
+  // on particular entries.
+  std::map<damage_entry_id_t, DamageEntryRef> by_id;
+
+  // I need to know my MDS rank so that I can check if
+  // metadata items are part of my mydir.
+  const mds_rank_t rank;
+
+  bool oversized() const;
+
+public:
+
+  /**
+   * Return true if no damage entries exist
+   */
+  bool empty() const
+  {
+    return by_id.empty();
+  }
+
+  /**
+   * Indicate that a dirfrag cannot be loaded.
+   *
+   * @return true if fatal
+   */
+  bool notify_dirfrag(inodeno_t ino, frag_t frag);
+
+  /**
+   * Indicate that a particular dentry cannot be loaded.
+   *
+   * @return true if fatal
+   */
+  bool notify_dentry(
+    inodeno_t ino, frag_t frag,
+    snapid_t snap_id, const std::string &dname);
+
+  /**
+   * Indicate that a particular Inode could not be loaded by number
+   */
+  bool notify_remote_damaged(
+      inodeno_t ino);
+
+  bool is_dentry_damaged(
+      const CDir *dir_frag,
+      const std::string &dname,
+      const snapid_t snap_id) const;
+
+  bool is_dirfrag_damaged(
+      const CDir *dir_frag) const;
+
+  bool is_remote_damaged(
+      const inodeno_t ino) const;
+
+
+  DamageTable(const mds_rank_t rank_)
+    : rank(rank_)
+  {
+    assert(rank_ != MDS_RANK_NONE);
+  }
+
+  void dump(Formatter *f) const;
+
+  void erase(damage_entry_id_t damage_id);
+};
+
+#endif // DAMAGE_TABLE_H_
+
diff --git a/src/mds/FSMap.cc b/src/mds/FSMap.cc
new file mode 100644
index 0000000..094b78e
--- /dev/null
+++ b/src/mds/FSMap.cc
@@ -0,0 +1,816 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- 
+// vim: ts=8 sw=2 smarttab
+/*
+ * Ceph - scalable distributed file system
+ *
+ * Copyright (C) 2004-2006 Sage Weil <sage at newdream.net>
+ *
+ * This is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software 
+ * Foundation.  See file COPYING.
+ * 
+ */
+
+
+#include "FSMap.h"
+
+#include <sstream>
+using std::stringstream;
+
+
+void Filesystem::dump(Formatter *f) const
+{
+  f->open_object_section("mdsmap");
+  mds_map.dump(f);
+  f->close_section();
+  f->dump_int("id", fscid);
+}
+
+void FSMap::dump(Formatter *f) const
+{
+  f->dump_int("epoch", epoch);
+
+  f->open_object_section("compat");
+  compat.dump(f);
+  f->close_section();
+
+  f->open_array_section("standbys");
+  for (const auto &i : standby_daemons) {
+    f->open_object_section("info");
+    i.second.dump(f);
+    f->dump_int("epoch", standby_epochs.at(i.first));
+    f->close_section();
+  }
+  f->close_section();
+
+  f->open_array_section("filesystems");
+  for (const auto fs : filesystems) {
+    f->open_object_section("filesystem");
+    fs.second->dump(f);
+    f->close_section();
+  }
+  f->close_section();
+}
+
+void FSMap::generate_test_instances(list<FSMap*>& ls)
+{
+  FSMap *m = new FSMap();
+
+  std::list<MDSMap*> mds_map_instances;
+  MDSMap::generate_test_instances(mds_map_instances);
+
+  int k = 20;
+  for (auto i : mds_map_instances) {
+    auto fs = std::make_shared<Filesystem>();
+    fs->fscid = k++;
+    fs->mds_map = *i;
+    delete i;
+    m->filesystems[fs->fscid] = fs;
+  }
+  mds_map_instances.clear();
+
+  ls.push_back(m);
+}
+
+void FSMap::print(ostream& out) const
+{
+  // TODO add a non-json print?
+  JSONFormatter f(true);
+  f.open_object_section("fsmap");
+  dump(&f);
+  f.close_section();
+  f.flush(out);
+}
+
+
+
+void FSMap::print_summary(Formatter *f, ostream *out)
+{
+  map<mds_role_t,string> by_rank;
+  map<string,int> by_state;
+
+  if (f) {
+    f->dump_unsigned("epoch", get_epoch());
+    for (auto i : filesystems) {
+      auto fs = i.second;
+      f->dump_unsigned("id", fs->fscid);
+      f->dump_unsigned("up", fs->mds_map.up.size());
+      f->dump_unsigned("in", fs->mds_map.in.size());
+      f->dump_unsigned("max", fs->mds_map.max_mds);
+    }
+  } else {
+    *out << "e" << get_epoch() << ":";
+    if (filesystems.size() == 1) {
+      auto fs = filesystems.begin()->second;
+      *out << " " << fs->mds_map.up.size() << "/" << fs->mds_map.in.size() << "/"
+           << fs->mds_map.max_mds << " up";
+    } else {
+      for (auto i : filesystems) {
+        auto fs = i.second;
+        *out << " " << fs->mds_map.fs_name << "-" << fs->mds_map.up.size() << "/"
+             << fs->mds_map.in.size() << "/" << fs->mds_map.max_mds << " up";
+      }
+    }
+  }
+
+  if (f) {
+    f->open_array_section("by_rank");
+  }
+
+  const auto all_info = get_mds_info();
+  for (const auto &p : all_info) {
+    const auto &info = p.second;
+    string s = ceph_mds_state_name(info.state);
+    if (info.laggy()) {
+      s += "(laggy or crashed)";
+    }
+
+    const fs_cluster_id_t fscid = mds_roles.at(info.global_id);
+
+    if (info.rank != MDS_RANK_NONE) {
+      if (f) {
+        f->open_object_section("mds");
+        f->dump_unsigned("filesystem_id", fscid);
+        f->dump_unsigned("rank", info.rank);
+        f->dump_string("name", info.name);
+        f->dump_string("status", s);
+        f->close_section();
+      } else {
+        by_rank[mds_role_t(fscid, info.rank)] = info.name + "=" + s;
+      }
+    } else {
+      by_state[s]++;
+    }
+  }
+
+  if (f) {
+    f->close_section();
+  } else {
+    if (!by_rank.empty()) {
+      if (filesystems.size() > 1) {
+        // Disambiguate filesystems
+        std::map<std::string, std::string> pretty;
+        for (auto i : by_rank) {
+          const auto &fs_name = filesystems.at(i.first.fscid)->mds_map.fs_name;
+          std::ostringstream o;
+          o << "[" << fs_name << ":" << i.first.rank << "]";
+          pretty[o.str()] = i.second;
+        }
+        *out << " " << pretty;
+      } else {
+        *out << " " << by_rank;
+      }
+    }
+  }
+
+  for (map<string,int>::reverse_iterator p = by_state.rbegin(); p != by_state.rend(); ++p) {
+    if (f) {
+      f->dump_unsigned(p->first.c_str(), p->second);
+    } else {
+      *out << ", " << p->second << " " << p->first;
+    }
+  }
+
+  size_t failed = 0;
+  size_t damaged = 0;
+  for (auto i : filesystems) {
+    auto fs = i.second;
+    failed += fs->mds_map.failed.size();
+    damaged += fs->mds_map.damaged.size();
+  }
+
+  if (failed > 0) {
+    if (f) {
+      f->dump_unsigned("failed", failed);
+    } else {
+      *out << ", " << failed << " failed";
+    }
+  }
+
+  if (damaged > 0) {
+    if (f) {
+      f->dump_unsigned("damaged", damaged);
+    } else {
+      *out << ", " << damaged << " damaged";
+    }
+  }
+  //if (stopped.size())
+  //out << ", " << stopped.size() << " stopped";
+}
+
+void FSMap::get_health(list<pair<health_status_t,string> >& summary,
+			list<pair<health_status_t,string> > *detail) const
+{
+  for (auto i : filesystems) {
+    auto fs = i.second;
+
+    // TODO: move get_health up into here so that we can qualify
+    // all the messages with what filesystem they're talking about
+    fs->mds_map.get_health(summary, detail);
+  }
+}
+
+void FSMap::encode(bufferlist& bl, uint64_t features) const
+{
+  if (features & CEPH_FEATURE_SERVER_JEWEL) {
+    ENCODE_START(6, 6, bl);
+    ::encode(epoch, bl);
+    ::encode(next_filesystem_id, bl);
+    ::encode(legacy_client_fscid, bl);
+    ::encode(compat, bl);
+    ::encode(enable_multiple, bl);
+    std::vector<Filesystem> fs_list;
+    for (auto i : filesystems) {
+      fs_list.push_back(*(i.second));
+    }
+    ::encode(fs_list, bl);
+    ::encode(mds_roles, bl);
+    ::encode(standby_daemons, bl, features);
+    ::encode(standby_epochs, bl);
+    ENCODE_FINISH(bl);
+  } else {
+    if (filesystems.empty()) {
+      MDSMap disabled_map;
+      disabled_map.epoch = epoch;
+      disabled_map.encode(bl, features);
+    } else {
+      // MDSMonitor should never have created multiple filesystems
+      // until the quorum features indicated Jewel
+      assert(filesystems.size() == 1);
+      auto fs = filesystems.begin()->second;
+
+      // Take the MDSMap for the enabled filesystem, and populated its
+      // mds_info with the standbys to get a pre-jewel-style mon MDSMap.
+      MDSMap full_mdsmap = fs->mds_map;
+      full_mdsmap.epoch = epoch;
+      for (const auto p : standby_daemons) {
+        full_mdsmap.mds_info[p.first] = p.second;
+      }
+      full_mdsmap.encode(bl, features);
+    }
+  }
+}
+
+void FSMap::decode(bufferlist::iterator& p)
+{
+  // Because the mon used to store an MDSMap where we now
+  // store an FSMap, FSMap knows how to decode the legacy
+  // MDSMap format (it never needs to encode it though).
+  MDSMap legacy_mds_map;
+  
+  // The highest MDSMap encoding version before we changed the
+  // MDSMonitor to store an FSMap instead of an MDSMap was
+  // 5, so anything older than 6 is decoded as an MDSMap,
+  // and anything newer is decoded as an FSMap.
+  DECODE_START_LEGACY_COMPAT_LEN_16(6, 4, 4, p);
+  if (struct_v < 6) {
+    // Decoding an MDSMap (upgrade)
+    ::decode(epoch, p);
+    ::decode(legacy_mds_map.flags, p);
+    ::decode(legacy_mds_map.last_failure, p);
+    ::decode(legacy_mds_map.root, p);
+    ::decode(legacy_mds_map.session_timeout, p);
+    ::decode(legacy_mds_map.session_autoclose, p);
+    ::decode(legacy_mds_map.max_file_size, p);
+    ::decode(legacy_mds_map.max_mds, p);
+    ::decode(legacy_mds_map.mds_info, p);
+    if (struct_v < 3) {
+      __u32 n;
+      ::decode(n, p);
+      while (n--) {
+        __u32 m;
+        ::decode(m, p);
+        legacy_mds_map.data_pools.insert(m);
+      }
+      __s32 s;
+      ::decode(s, p);
+      legacy_mds_map.cas_pool = s;
+    } else {
+      ::decode(legacy_mds_map.data_pools, p);
+      ::decode(legacy_mds_map.cas_pool, p);
+    }
+
+    // kclient ignores everything from here
+    __u16 ev = 1;
+    if (struct_v >= 2)
+      ::decode(ev, p);
+    if (ev >= 3)
+      ::decode(legacy_mds_map.compat, p);
+    else
+      legacy_mds_map.compat = get_mdsmap_compat_set_base();
+    if (ev < 5) {
+      __u32 n;
+      ::decode(n, p);
+      legacy_mds_map.metadata_pool = n;
+    } else {
+      ::decode(legacy_mds_map.metadata_pool, p);
+    }
+    ::decode(legacy_mds_map.created, p);
+    ::decode(legacy_mds_map.modified, p);
+    ::decode(legacy_mds_map.tableserver, p);
+    ::decode(legacy_mds_map.in, p);
+    ::decode(legacy_mds_map.inc, p);
+    ::decode(legacy_mds_map.up, p);
+    ::decode(legacy_mds_map.failed, p);
+    ::decode(legacy_mds_map.stopped, p);
+    if (ev >= 4)
+      ::decode(legacy_mds_map.last_failure_osd_epoch, p);
+    if (ev >= 6) {
+      ::decode(legacy_mds_map.ever_allowed_snaps, p);
+      ::decode(legacy_mds_map.explicitly_allowed_snaps, p);
+    } else {
+      legacy_mds_map.ever_allowed_snaps = true;
+      legacy_mds_map.explicitly_allowed_snaps = false;
+    }
+    if (ev >= 7)
+      ::decode(legacy_mds_map.inline_data_enabled, p);
+
+    if (ev >= 8) {
+      assert(struct_v >= 5);
+      ::decode(legacy_mds_map.enabled, p);
+      ::decode(legacy_mds_map.fs_name, p);
+    } else {
+      legacy_mds_map.fs_name = "default";
+      if (epoch > 1) {
+        // If an MDS has ever been started, epoch will be greater than 1,
+        // assume filesystem is enabled.
+        legacy_mds_map.enabled = true;
+      } else {
+        // Upgrading from a cluster that never used an MDS, switch off
+        // filesystem until it's explicitly enabled.
+        legacy_mds_map.enabled = false;
+      }
+    }
+
+    if (ev >= 9) {
+      ::decode(legacy_mds_map.damaged, p);
+    }
+
+    // We're upgrading, populate filesystems from the legacy fields
+    filesystems.clear();
+    standby_daemons.clear();
+    standby_epochs.clear();
+    mds_roles.clear();
+    compat = legacy_mds_map.compat;
+    enable_multiple = false;
+
+    // Synthesise a Filesystem from legacy_mds_map, if enabled
+    if (legacy_mds_map.enabled) {
+      // Construct a Filesystem from the legacy MDSMap
+      auto migrate_fs = std::make_shared<Filesystem>(); 
+      migrate_fs->fscid = FS_CLUSTER_ID_ANONYMOUS;
+      migrate_fs->mds_map = legacy_mds_map;
+      migrate_fs->mds_map.epoch = epoch;
+      filesystems[migrate_fs->fscid] = migrate_fs;
+
+      // Construct mds_roles, standby_daemons, and remove
+      // standbys from the MDSMap in the Filesystem.
+      for (const auto &p : migrate_fs->mds_map.mds_info) {
+        if (p.second.rank == MDS_RANK_NONE) {
+          standby_daemons[p.first] = p.second;
+          standby_epochs[p.first] = epoch;
+          mds_roles[p.first] = FS_CLUSTER_ID_NONE;
+        } else {
+          mds_roles[p.first] = migrate_fs->fscid;
+        }
+      }
+      for (const auto &p : standby_daemons) {
+        migrate_fs->mds_map.mds_info.erase(p.first);
+      }
+
+      legacy_client_fscid = migrate_fs->fscid;
+    } else {
+      legacy_client_fscid = FS_CLUSTER_ID_NONE;
+    }
+  } else {
+    ::decode(epoch, p);
+    ::decode(next_filesystem_id, p);
+    ::decode(legacy_client_fscid, p);
+    ::decode(compat, p);
+    ::decode(enable_multiple, p);
+    std::vector<Filesystem> fs_list;
+    ::decode(fs_list, p);
+    filesystems.clear();
+    for (std::vector<Filesystem>::const_iterator fs = fs_list.begin(); fs != fs_list.end(); ++fs) {
+      filesystems[fs->fscid] = std::make_shared<Filesystem>(*fs);
+    }
+
+    ::decode(mds_roles, p);
+    ::decode(standby_daemons, p);
+    ::decode(standby_epochs, p);
+  }
+
+  DECODE_FINISH(p);
+}
+
+
+void Filesystem::encode(bufferlist& bl) const
+{
+  ENCODE_START(1, 1, bl);
+  ::encode(fscid, bl);
+  bufferlist mdsmap_bl;
+  mds_map.encode(mdsmap_bl, CEPH_FEATURE_PGID64 | CEPH_FEATURE_MDSENC);
+  ::encode(mdsmap_bl, bl);
+  ENCODE_FINISH(bl);
+}
+
+void Filesystem::decode(bufferlist::iterator& p)
+{
+  DECODE_START(1, p);
+  ::decode(fscid, p);
+  bufferlist mdsmap_bl;
+  ::decode(mdsmap_bl, p);
+  bufferlist::iterator mdsmap_bl_iter = mdsmap_bl.begin();
+  mds_map.decode(mdsmap_bl_iter);
+  DECODE_FINISH(p);
+}
+
+int FSMap::parse_filesystem(
+      std::string const &ns_str,
+      std::shared_ptr<const Filesystem> *result
+      ) const
+{
+  std::string ns_err;
+  fs_cluster_id_t fscid = strict_strtol(ns_str.c_str(), 10, &ns_err);
+  if (!ns_err.empty() || filesystems.count(fscid) == 0) {
+    for (auto fs : filesystems) {
+      if (fs.second->mds_map.fs_name == ns_str) {
+        *result = std::const_pointer_cast<const Filesystem>(fs.second);
+        return 0;
+      }
+    }
+    return -ENOENT;
+  } else {
+    *result = get_filesystem(fscid);
+    return 0;
+  }
+}
+
+void Filesystem::print(std::ostream &out) const
+{
+  // TODO add a non-json print?
+  JSONFormatter f;
+  dump(&f);
+  f.flush(out);
+}
+
+mds_gid_t FSMap::find_standby_for(mds_role_t role, const std::string& name) const
+{
+  mds_gid_t result = MDS_GID_NONE;
+
+  // First see if we have a STANDBY_REPLAY
+  auto fs = get_filesystem(role.fscid);
+  for (const auto &i : fs->mds_map.mds_info) {
+    const auto &info = i.second;
+    if (info.rank == role.rank && info.state == MDSMap::STATE_STANDBY_REPLAY) {
+      return info.global_id;
+    }
+  }
+
+  // See if there are any STANDBY daemons available
+  for (const auto &i : standby_daemons) {
+    const auto &gid = i.first;
+    const auto &info = i.second;
+    assert(info.state == MDSMap::STATE_STANDBY);
+    assert(info.rank == MDS_RANK_NONE);
+
+    if (info.laggy()) {
+      continue;
+    }
+
+    if ((info.standby_for_rank == role.rank && info.standby_for_ns == role.fscid)
+        || (name.length() && info.standby_for_name == name)) {
+      // It's a named standby for *me*, use it.
+      return gid;
+    } else if (info.standby_for_rank < 0 && info.standby_for_name.length() == 0)
+      // It's not a named standby for anyone, use it if we don't find
+      // a named standby for me later.
+      result = gid;
+  }
+
+  return result;
+}
+
+mds_gid_t FSMap::find_unused(bool force_standby_active) const {
+  for (const auto &i : standby_daemons) {
+    const auto &gid = i.first;
+    const auto &info = i.second;
+    assert(info.state == MDSMap::STATE_STANDBY);
+
+    if (info.laggy() || info.rank >= 0)
+      continue;
+
+    if ((info.standby_for_rank == MDSMap::MDS_NO_STANDBY_PREF ||
+         info.standby_for_rank == MDSMap::MDS_MATCHED_ACTIVE ||
+         (info.standby_for_rank == MDSMap::MDS_STANDBY_ANY
+          && force_standby_active))) {
+      return gid;
+    }
+  }
+  return MDS_GID_NONE;
+}
+
+mds_gid_t FSMap::find_replacement_for(mds_role_t role, const std::string& name,
+                               bool force_standby_active) const {
+  const mds_gid_t standby = find_standby_for(role, name);
+  if (standby)
+    return standby;
+  else
+    return find_unused(force_standby_active);
+}
+
+void FSMap::sanity() const
+{
+  if (legacy_client_fscid != FS_CLUSTER_ID_NONE) {
+    assert(filesystems.count(legacy_client_fscid) == 1);
+  }
+
+  for (const auto &i : filesystems) {
+    auto fs = i.second;
+    assert(fs->mds_map.compat.compare(compat) == 0);
+    assert(fs->fscid == i.first);
+    for (const auto &j : fs->mds_map.mds_info) {
+      assert(j.second.rank != MDS_RANK_NONE);
+      assert(mds_roles.count(j.first) == 1);
+      assert(standby_daemons.count(j.first) == 0);
+      assert(standby_epochs.count(j.first) == 0);
+      assert(mds_roles.at(j.first) == i.first);
+      if (j.second.state != MDSMap::STATE_STANDBY_REPLAY) {
+        assert(fs->mds_map.up.at(j.second.rank) == j.first);
+        assert(fs->mds_map.failed.count(j.second.rank) == 0);
+        assert(fs->mds_map.damaged.count(j.second.rank) == 0);
+      }
+    }
+
+    for (const auto &j : fs->mds_map.up) {
+      mds_rank_t rank = j.first;
+      assert(fs->mds_map.in.count(rank) == 1);
+      mds_gid_t gid = j.second;
+      assert(fs->mds_map.mds_info.count(gid) == 1);
+    }
+  }
+
+  for (const auto &i : standby_daemons) {
+    assert(i.second.state == MDSMap::STATE_STANDBY);
+    assert(i.second.rank == MDS_RANK_NONE);
+    assert(i.second.global_id == i.first);
+    assert(standby_epochs.count(i.first) == 1);
+    assert(mds_roles.count(i.first) == 1);
+    assert(mds_roles.at(i.first) == FS_CLUSTER_ID_NONE);
+  }
+
+  for (const auto &i : standby_epochs) {
+    assert(standby_daemons.count(i.first) == 1);
+  }
+
+  for (const auto &i : mds_roles) {
+    if (i.second == FS_CLUSTER_ID_NONE) {
+      assert(standby_daemons.count(i.first) == 1);
+    } else {
+      assert(filesystems.count(i.second) == 1);
+      assert(filesystems.at(i.second)->mds_map.mds_info.count(i.first) == 1);
+    }
+  }
+}
+
+void FSMap::promote(
+    mds_gid_t standby_gid,
+    std::shared_ptr<Filesystem> filesystem,
+    mds_rank_t assigned_rank)
+{
+  assert(gid_exists(standby_gid));
+  bool is_standby_replay = mds_roles.at(standby_gid) != FS_CLUSTER_ID_NONE;
+  if (!is_standby_replay) {
+    assert(standby_daemons.count(standby_gid));
+    assert(standby_daemons.at(standby_gid).state == MDSMap::STATE_STANDBY);
+  }
+
+  MDSMap &mds_map = filesystem->mds_map;
+
+  // Insert daemon state to Filesystem
+  if (!is_standby_replay) {
+    mds_map.mds_info[standby_gid] = standby_daemons.at(standby_gid);
+  } else {
+    assert(mds_map.mds_info.count(standby_gid));
+    assert(mds_map.mds_info.at(standby_gid).state == MDSMap::STATE_STANDBY_REPLAY);
+    assert(mds_map.mds_info.at(standby_gid).rank == assigned_rank);
+  }
+  MDSMap::mds_info_t &info = mds_map.mds_info[standby_gid];
+
+  if (mds_map.stopped.count(assigned_rank)) {
+    // The cluster is being expanded with a stopped rank
+    info.state = MDSMap::STATE_STARTING;
+    mds_map.stopped.erase(assigned_rank);
+  } else if (!mds_map.is_in(assigned_rank)) {
+    // The cluster is being expanded with a new rank
+    info.state = MDSMap::STATE_CREATING;
+  } else {
+    // An existing rank is being assigned to a replacement
+    info.state = MDSMap::STATE_REPLAY;
+    mds_map.failed.erase(assigned_rank);
+  }
+  info.rank = assigned_rank;
+  info.inc = ++mds_map.inc[assigned_rank];
+  mds_roles[standby_gid] = filesystem->fscid;
+
+  // Update the rank state in Filesystem
+  mds_map.in.insert(assigned_rank);
+  mds_map.up[assigned_rank] = standby_gid;
+
+  // Remove from the list of standbys
+  if (!is_standby_replay) {
+    standby_daemons.erase(standby_gid);
+    standby_epochs.erase(standby_gid);
+  }
+
+  // Indicate that Filesystem has been modified
+  mds_map.epoch = epoch;
+}
+
+void FSMap::assign_standby_replay(
+    const mds_gid_t standby_gid,
+    const fs_cluster_id_t leader_ns,
+    const mds_rank_t leader_rank)
+{
+  assert(mds_roles.at(standby_gid) == FS_CLUSTER_ID_NONE);
+  assert(gid_exists(standby_gid));
+  assert(!gid_has_rank(standby_gid));
+  assert(standby_daemons.count(standby_gid));
+
+  // Insert to the filesystem
+  auto fs = filesystems.at(leader_ns);
+  fs->mds_map.mds_info[standby_gid] = standby_daemons.at(standby_gid);
+  fs->mds_map.mds_info[standby_gid].rank = leader_rank;
+  fs->mds_map.mds_info[standby_gid].state = MDSMap::STATE_STANDBY_REPLAY;
+  mds_roles[standby_gid] = leader_ns;
+
+  // Remove from the list of standbys
+  standby_daemons.erase(standby_gid);
+  standby_epochs.erase(standby_gid);
+
+  // Indicate that Filesystem has been modified
+  fs->mds_map.epoch = epoch;
+}
+
+void FSMap::erase(mds_gid_t who, epoch_t blacklist_epoch)
+{
+  if (mds_roles.at(who) == FS_CLUSTER_ID_NONE) {
+    standby_daemons.erase(who);
+    standby_epochs.erase(who);
+  } else {
+    auto fs = filesystems.at(mds_roles.at(who));
+    const auto &info = fs->mds_map.mds_info.at(who);
+    if (info.state != MDSMap::STATE_STANDBY_REPLAY) {
+      if (info.state == MDSMap::STATE_CREATING) {
+        // If this gid didn't make it past CREATING, then forget
+        // the rank ever existed so that next time it's handed out
+        // to a gid it'll go back into CREATING.
+        fs->mds_map.in.erase(info.rank);
+      } else {
+        // Put this rank into the failed list so that the next available
+        // STANDBY will pick it up.
+        fs->mds_map.failed.insert(info.rank);
+      }
+      assert(fs->mds_map.up.at(info.rank) == info.global_id);
+      fs->mds_map.up.erase(info.rank);
+    }
+    fs->mds_map.mds_info.erase(who);
+    fs->mds_map.last_failure_osd_epoch = blacklist_epoch;
+    fs->mds_map.epoch = epoch;
+  }
+
+  mds_roles.erase(who);
+}
+
+void FSMap::damaged(mds_gid_t who, epoch_t blacklist_epoch)
+{
+  assert(mds_roles.at(who) != FS_CLUSTER_ID_NONE);
+  auto fs = filesystems.at(mds_roles.at(who));
+  mds_rank_t rank = fs->mds_map.mds_info[who].rank;
+
+  erase(who, blacklist_epoch);
+  fs->mds_map.failed.erase(rank);
+  fs->mds_map.damaged.insert(rank);
+
+  assert(fs->mds_map.epoch == epoch);
+}
+
+/**
+ * Update to indicate that the rank `rank` is to be removed
+ * from the damaged list of the filesystem `fscid`
+ */
+bool FSMap::undamaged(const fs_cluster_id_t fscid, const mds_rank_t rank)
+{
+  auto fs = filesystems.at(fscid);
+
+  if (fs->mds_map.damaged.count(rank)) {
+    fs->mds_map.damaged.erase(rank);
+    fs->mds_map.failed.insert(rank);
+    fs->mds_map.epoch = epoch;
+    return true;
+  } else {
+    return false;
+  }
+}
+
+void FSMap::insert(const MDSMap::mds_info_t &new_info)
+{
+  mds_roles[new_info.global_id] = FS_CLUSTER_ID_NONE;
+  standby_daemons[new_info.global_id] = new_info;
+  standby_epochs[new_info.global_id] = epoch;
+}
+
+void FSMap::stop(mds_gid_t who)
+{
+  assert(mds_roles.at(who) != FS_CLUSTER_ID_NONE);
+  auto fs = filesystems.at(mds_roles.at(who));
+  const auto &info = fs->mds_map.mds_info.at(who);
+  fs->mds_map.up.erase(info.rank);
+  fs->mds_map.in.erase(info.rank);
+  fs->mds_map.stopped.insert(info.rank);
+
+  fs->mds_map.mds_info.erase(who);
+  mds_roles.erase(who);
+
+  fs->mds_map.epoch = epoch;
+}
+
+
+/**
+ * Given one of the following forms:
+ *   <fs name>:<rank>
+ *   <fs id>:<rank>
+ *   <rank>
+ *
+ * Parse into a mds_role_t.  The rank-only form is only valid
+ * if legacy_client_ns is set.
+ */
+int FSMap::parse_role(
+    const std::string &role_str,
+    mds_role_t *role,
+    std::ostream &ss) const
+{
+  auto colon_pos = role_str.find(":");
+
+  if (colon_pos != std::string::npos && colon_pos != role_str.size()) {
+    auto fs_part = role_str.substr(0, colon_pos);
+    auto rank_part = role_str.substr(colon_pos + 1);
+
+    std::string err;
+    fs_cluster_id_t fs_id = FS_CLUSTER_ID_NONE;
+    long fs_id_i = strict_strtol(fs_part.c_str(), 10, &err);
+    if (fs_id_i < 0 || !err.empty()) {
+      // Try resolving as name
+      auto fs = get_filesystem(fs_part);
+      if (fs == nullptr) {
+        ss << "Unknown filesystem name '" << fs_part << "'";
+        return -EINVAL;
+      } else {
+        fs_id = fs->fscid;
+      }
+    } else {
+      fs_id = fs_id_i;
+    }
+
+    mds_rank_t rank;
+    long rank_i = strict_strtol(rank_part.c_str(), 10, &err);
+    if (rank_i < 0 || !err.empty()) {
+      ss << "Invalid rank '" << rank_part << "'";
+      return -EINVAL;
+    } else {
+      rank = rank_i;
+    }
+
+    *role = {fs_id, rank};
+  } else {
+    std::string err;
+    long who_i = strict_strtol(role_str.c_str(), 10, &err);
+    if (who_i < 0 || !err.empty()) {
+      ss << "Invalid rank '" << role_str << "'";
+      return -EINVAL;
+    }
+
+    if (legacy_client_fscid == FS_CLUSTER_ID_NONE) {
+      ss << "No filesystem selected";
+      return -ENOENT;
+    } else {
+      *role = mds_role_t(legacy_client_fscid, who_i);
+    }
+  }
+
+  // Now check that the role actually exists
+  if (get_filesystem(role->fscid) == nullptr) {
+    ss << "Filesystem with ID '" << role->fscid << "' not found";
+    return -ENOENT;
+  }
+
+  auto fs = get_filesystem(role->fscid);
+  if (fs->mds_map.in.count(role->rank) == 0) {
+    ss << "Rank '" << role->rank << "' not found";
+    return -ENOENT;
+  }
+
+  return 0;
+}
+
diff --git a/src/mds/FSMap.h b/src/mds/FSMap.h
new file mode 100644
index 0000000..e14173f
--- /dev/null
+++ b/src/mds/FSMap.h
@@ -0,0 +1,459 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- 
+// vim: ts=8 sw=2 smarttab
+/*
+ * Ceph - scalable distributed file system
+ *
+ * Copyright (C) 2004-2006 Sage Weil <sage at newdream.net>
+ *
+ * This is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software 
+ * Foundation.  See file COPYING.
+ * 
+ */
+
+
+#ifndef CEPH_FSMAP_H
+#define CEPH_FSMAP_H
+
+#include <errno.h>
+
+#include "include/types.h"
+#include "common/Clock.h"
+#include "msg/Message.h"
+#include "mds/MDSMap.h"
+
+#include <set>
+#include <map>
+#include <string>
+
+#include "common/config.h"
+
+#include "include/CompatSet.h"
+#include "include/ceph_features.h"
+#include "common/Formatter.h"
+#include "mds/mdstypes.h"
+
+class CephContext;
+
+#define MDS_FEATURE_INCOMPAT_BASE CompatSet::Feature(1, "base v0.20")
+#define MDS_FEATURE_INCOMPAT_CLIENTRANGES CompatSet::Feature(2, "client writeable ranges")
+#define MDS_FEATURE_INCOMPAT_FILELAYOUT CompatSet::Feature(3, "default file layouts on dirs")
+#define MDS_FEATURE_INCOMPAT_DIRINODE CompatSet::Feature(4, "dir inode in separate object")
+#define MDS_FEATURE_INCOMPAT_ENCODING CompatSet::Feature(5, "mds uses versioned encoding")
+#define MDS_FEATURE_INCOMPAT_OMAPDIRFRAG CompatSet::Feature(6, "dirfrag is stored in omap")
+#define MDS_FEATURE_INCOMPAT_INLINE CompatSet::Feature(7, "mds uses inline data")
+#define MDS_FEATURE_INCOMPAT_NOANCHOR CompatSet::Feature(8, "no anchor table")
+
+#define MDS_FS_NAME_DEFAULT "cephfs"
+
+/**
+ * The MDSMap and any additional fields describing a particular
+ * filesystem (a unique fs_cluster_id_t).
+ */
+class Filesystem
+{
+  public:
+  fs_cluster_id_t fscid;
+  MDSMap mds_map;
+
+  void encode(bufferlist& bl) const;
+  void decode(bufferlist::iterator& p);
+
+  Filesystem()
+    :
+      fscid(FS_CLUSTER_ID_NONE)
+  {
+  }
+
+  void dump(Formatter *f) const;
+  void print(std::ostream& out) const;
+
+  /**
+   * Return true if a daemon is already assigned as
+   * STANDBY_REPLAY for the gid `who`
+   */
+  bool has_standby_replay(mds_gid_t who) const
+  {
+    for (const auto &i : mds_map.mds_info) {
+      const auto &info = i.second;
+      if (info.state == MDSMap::STATE_STANDBY_REPLAY
+          && info.rank == mds_map.mds_info.at(who).rank) {
+        return true;
+      }
+    }
+
+    return false;
+  }
+};
+WRITE_CLASS_ENCODER(Filesystem)
+
+class FSMap {
+protected:
+  epoch_t epoch;
+  uint64_t next_filesystem_id;
+  fs_cluster_id_t legacy_client_fscid;
+  CompatSet compat;
+  bool enable_multiple;
+
+  std::map<fs_cluster_id_t, std::shared_ptr<Filesystem> > filesystems;
+
+  // Remember which Filesystem an MDS daemon's info is stored in
+  // (or in standby_daemons for FS_CLUSTER_ID_NONE)
+  std::map<mds_gid_t, fs_cluster_id_t> mds_roles;
+
+  // For MDS daemons not yet assigned to a Filesystem
+  std::map<mds_gid_t, MDSMap::mds_info_t> standby_daemons;
+  std::map<mds_gid_t, epoch_t> standby_epochs;
+
+public:
+
+  friend class MDSMonitor;
+
+  FSMap() 
+    : epoch(0),
+      next_filesystem_id(FS_CLUSTER_ID_ANONYMOUS + 1),
+      legacy_client_fscid(FS_CLUSTER_ID_NONE),
+      compat(get_mdsmap_compat_set_default()),
+      enable_multiple(false)
+  { }
+
+  FSMap(const FSMap &rhs)
+    :
+      epoch(rhs.epoch),
+      next_filesystem_id(rhs.next_filesystem_id),
+      legacy_client_fscid(rhs.legacy_client_fscid),
+      compat(rhs.compat),
+      enable_multiple(rhs.enable_multiple),
+      mds_roles(rhs.mds_roles),
+      standby_daemons(rhs.standby_daemons),
+      standby_epochs(rhs.standby_epochs)
+  {
+    for (auto &i : rhs.filesystems) {
+      auto fs = i.second;
+      filesystems[fs->fscid] = std::make_shared<Filesystem>(*fs);
+    }
+  }
+
+  FSMap &operator=(const FSMap &rhs)
+  {
+    epoch = rhs.epoch;
+    next_filesystem_id = rhs.next_filesystem_id;
+    legacy_client_fscid = rhs.legacy_client_fscid;
+    compat = rhs.compat;
+    enable_multiple = rhs.enable_multiple;
+    mds_roles = rhs.mds_roles;
+    standby_daemons = rhs.standby_daemons;
+    standby_epochs = rhs.standby_epochs;
+
+    for (auto &i : rhs.filesystems) {
+      auto fs = i.second;
+      filesystems[fs->fscid] = std::make_shared<Filesystem>(*fs);
+    }
+
+    return *this;
+  }
+
+  const CompatSet &get_compat() const {return compat;}
+
+  void set_enable_multiple(const bool v)
+  {
+    enable_multiple = v;
+  }
+
+  bool get_enable_multiple() const
+  {
+    return enable_multiple;
+  }
+
+  /**
+   * Get state of all daemons (for all filesystems, including all standbys)
+   */
+  std::map<mds_gid_t, MDSMap::mds_info_t> get_mds_info() const
+  {
+    std::map<mds_gid_t, MDSMap::mds_info_t> result;
+    for (const auto &i : standby_daemons) {
+      result[i.first] = i.second;
+    }
+
+    for (const auto &i : filesystems) {
+      auto fs_info = i.second->mds_map.get_mds_info();
+      for (auto j : fs_info) {
+        result[j.first] = j.second;
+      }
+    }
+
+    return result;
+  }
+
+  /**
+   * Resolve daemon name to GID
+   */
+  mds_gid_t find_mds_gid_by_name(const std::string& s) const
+  {
+    const auto info = get_mds_info();
+    for (const auto &p : info) {
+      if (p.second.name == s) {
+	return p.first;
+      }
+    }
+    return MDS_GID_NONE;
+  }
+
+  /**
+   * Resolve daemon name to status
+   */
+  const MDSMap::mds_info_t* find_by_name(const std::string& name) const
+  {
+    std::map<mds_gid_t, MDSMap::mds_info_t> result;
+    for (const auto &i : standby_daemons) {
+      if (i.second.name == name) {
+        return &(i.second);
+      }
+    }
+
+    for (const auto &i : filesystems) {
+      const auto &fs_info = i.second->mds_map.get_mds_info();
+      for (const auto &j : fs_info) {
+        if (j.second.name == name) {
+          return &(j.second);
+        }
+      }
+    }
+
+    return nullptr;
+  }
+
+  /**
+   * Does a daemon exist with this GID?
+   */
+  bool gid_exists(mds_gid_t gid) const
+  {
+    return mds_roles.count(gid) > 0;
+  }
+
+  /**
+   * Does a daemon with this GID exist, *and* have an MDS rank assigned?
+   */
+  bool gid_has_rank(mds_gid_t gid) const
+  {
+    return gid_exists(gid) && mds_roles.at(gid) != FS_CLUSTER_ID_NONE;
+  }
+
+  /**
+   * Insert a new MDS daemon, as a standby
+   */
+  void insert(const MDSMap::mds_info_t &new_info);
+
+  /**
+   * Assign an MDS cluster standby replay rank to a standby daemon
+   */
+  void assign_standby_replay(
+      const mds_gid_t standby_gid,
+      const fs_cluster_id_t leader_ns,
+      const mds_rank_t leader_rank);
+
+  /**
+   * Assign an MDS cluster rank to a standby daemon
+   */
+  void promote(
+      mds_gid_t standby_gid,
+      std::shared_ptr<Filesystem> filesystem,
+      mds_rank_t assigned_rank);
+
+  /**
+   * A daemon reports that it is STATE_STOPPED: remove it,
+   * and the rank it held.
+   */
+  void stop(mds_gid_t who);
+
+  /**
+   * The rank held by 'who', if any, is to be relinquished, and
+   * the state for the daemon GID is to be forgotten.
+   */
+  void erase(mds_gid_t who, epoch_t blacklist_epoch);
+
+  /**
+   * Update to indicate that the rank held by 'who' is damaged
+   */
+  void damaged(mds_gid_t who, epoch_t blacklist_epoch);
+
+  /**
+   * Update to indicate that the rank `rank` is to be removed
+   * from the damaged list of the filesystem `fscid`
+   */
+  bool undamaged(const fs_cluster_id_t fscid, const mds_rank_t rank);
+
+  /**
+   * Mutator helper for Filesystem objects: expose a non-const
+   * Filesystem pointer to `fn` and update epochs appropriately.
+   */
+  void modify_filesystem(
+      const fs_cluster_id_t fscid,
+      std::function<void(std::shared_ptr<Filesystem> )> fn)
+  {
+    auto fs = filesystems.at(fscid);
+    fn(fs);
+    fs->mds_map.epoch = epoch;
+  }
+
+  /**
+   * Apply a mutation to the mds_info_t structure for a particular
+   * daemon (identified by GID), and make appropriate updates to epochs.
+   */
+  void modify_daemon(
+      mds_gid_t who,
+      std::function<void(MDSMap::mds_info_t *info)> fn)
+  {
+    if (mds_roles.at(who) == FS_CLUSTER_ID_NONE) {
+      fn(&standby_daemons.at(who));
+      standby_epochs[who] = epoch;
+    } else {
+      auto fs = filesystems[mds_roles.at(who)];
+      auto &info = fs->mds_map.mds_info.at(who);
+      fn(&info);
+
+      fs->mds_map.epoch = epoch;
+    }
+  }
+
+  /**
+   * Given that gid exists in a filesystem or as a standby, return
+   * a reference to its info.
+   */
+  const MDSMap::mds_info_t& get_info_gid(mds_gid_t gid) const
+  {
+    auto fscid = mds_roles.at(gid);
+    if (fscid == FS_CLUSTER_ID_NONE) {
+      return standby_daemons.at(gid);
+    } else {
+      return filesystems.at(fscid)->mds_map.mds_info.at(gid);
+    }
+  }
+
+  /**
+   * A daemon has told us it's compat, and it's too new
+   * for the one we had previously.  Impose the new one
+   * on all filesystems.
+   */
+  void update_compat(CompatSet c)
+  {
+    // We could do something more complicated here to enable
+    // different filesystems to be served by different MDS versions,
+    // but this is a lot simpler because it doesn't require us to
+    // track the compat versions for standby daemons.
+    compat = c;
+    for (auto i : filesystems) {
+      MDSMap &mds_map = i.second->mds_map;
+      mds_map.compat = c;
+      mds_map.epoch = epoch;
+    }
+  }
+
+  std::shared_ptr<const Filesystem> get_legacy_filesystem()
+  {
+    if (legacy_client_fscid == FS_CLUSTER_ID_NONE) {
+      return nullptr;
+    } else {
+      return filesystems.at(legacy_client_fscid);
+    }
+  }
+
+  /**
+   * A daemon has informed us of its offload targets
+   */
+  void update_export_targets(mds_gid_t who, const std::set<mds_rank_t> targets)
+  {
+    auto fscid = mds_roles.at(who);
+    modify_filesystem(fscid, [who, &targets](std::shared_ptr<Filesystem> fs) {
+      fs->mds_map.mds_info.at(who).export_targets = targets;
+    });
+  }
+
+  const std::map<fs_cluster_id_t, std::shared_ptr<Filesystem> > &get_filesystems() const
+  {
+    return filesystems;
+  }
+  bool any_filesystems() const {return !filesystems.empty(); }
+  bool filesystem_exists(fs_cluster_id_t fscid) const
+    {return filesystems.count(fscid) > 0;}
+
+  epoch_t get_epoch() const { return epoch; }
+  void inc_epoch() { epoch++; }
+
+  std::shared_ptr<const Filesystem> get_filesystem(fs_cluster_id_t fscid) const
+  {
+    return std::const_pointer_cast<const Filesystem>(filesystems.at(fscid));
+  }
+
+  int parse_filesystem(
+      std::string const &ns_str,
+      std::shared_ptr<const Filesystem> *result
+      ) const;
+
+  int parse_role(
+      const std::string &role_str,
+      mds_role_t *role,
+      std::ostream &ss) const;
+
+  /**
+   * Return true if this pool is in use by any of the filesystems
+   */
+  bool pool_in_use(int64_t poolid) const {
+    for (auto const &i : filesystems) {
+      if (i.second->mds_map.is_data_pool(poolid)
+          || i.second->mds_map.metadata_pool == poolid) {
+        return true;
+      }
+    }
+    return false;
+  }
+
+  mds_gid_t find_standby_for(mds_role_t mds, const std::string& name) const;
+
+  mds_gid_t find_unused(bool force_standby_active) const;
+
+  mds_gid_t find_replacement_for(mds_role_t mds, const std::string& name,
+                                 bool force_standby_active) const;
+
+  void get_health(list<pair<health_status_t,std::string> >& summary,
+		  list<pair<health_status_t,std::string> > *detail) const;
+
+  std::shared_ptr<const Filesystem> get_filesystem(const std::string &name) const
+  {
+    for (auto &i : filesystems) {
+      if (i.second->mds_map.fs_name == name) {
+        return i.second;
+      }
+    }
+
+    return nullptr;
+  }
+
+  /**
+   * Assert that the FSMap, Filesystem, MDSMap, mds_info_t relations are
+   * all self-consistent.
+   */
+  void sanity() const;
+
+  void encode(bufferlist& bl, uint64_t features) const;
+  void decode(bufferlist::iterator& p);
+  void decode(bufferlist& bl) {
+    bufferlist::iterator p = bl.begin();
+    decode(p);
+  }
+
+  void print(ostream& out) const;
+  void print_summary(Formatter *f, ostream *out);
+
+  void dump(Formatter *f) const;
+  static void generate_test_instances(list<FSMap*>& ls);
+};
+WRITE_CLASS_ENCODER_FEATURES(FSMap)
+
+inline ostream& operator<<(ostream& out, FSMap& m) {
+  m.print_summary(NULL, &out);
+  return out;
+}
+
+#endif
diff --git a/src/mds/Locker.cc b/src/mds/Locker.cc
index 25977fb..ddd99b2 100644
--- a/src/mds/Locker.cc
+++ b/src/mds/Locker.cc
@@ -155,7 +155,7 @@ void Locker::include_snap_rdlocks(set<SimpleLock*>& rdlocks, CInode *in)
 }
 
 void Locker::include_snap_rdlocks_wlayout(set<SimpleLock*>& rdlocks, CInode *in,
-                                  ceph_file_layout **layout)
+					  file_layout_t **layout)
 {
   //rdlock ancestor snaps
   CInode *t = in;
@@ -3149,7 +3149,9 @@ bool Locker::_do_cap_update(CInode *in, Capability *cap,
     return false;
 
   Session *session = static_cast<Session *>(m->get_connection()->get_priv());
-  if (!session->check_access(in, MAY_WRITE, m->caller_uid, m->caller_gid, 0, 0)) {
+  if (session->check_access(in, MAY_WRITE,
+			    m->caller_uid, m->caller_gid, 0, 0) < 0) {
+    session->put();
     dout(10) << "check_access failed, dropping cap update on " << *in << dendl;
     return false;
   }
diff --git a/src/mds/Locker.h b/src/mds/Locker.h
index 8a6581f..653988e 100644
--- a/src/mds/Locker.h
+++ b/src/mds/Locker.h
@@ -72,7 +72,7 @@ protected:
 public:
   void include_snap_rdlocks(set<SimpleLock*>& rdlocks, CInode *in);
   void include_snap_rdlocks_wlayout(set<SimpleLock*>& rdlocks, CInode *in,
-                                    ceph_file_layout **layout);
+                                    file_layout_t **layout);
 
   bool acquire_locks(MDRequestRef& mdr,
 		     set<SimpleLock*> &rdlocks,
diff --git a/src/mds/LogEvent.h b/src/mds/LogEvent.h
index bf57db0..8c1cd1b 100644
--- a/src/mds/LogEvent.h
+++ b/src/mds/LogEvent.h
@@ -84,16 +84,16 @@ public:
   void set_stamp(utime_t t) { stamp = t; }
 
   // encoding
-  virtual void encode(bufferlist& bl) const = 0;
+  virtual void encode(bufferlist& bl, uint64_t features) const = 0;
   virtual void decode(bufferlist::iterator &bl) = 0;
   static LogEvent *decode(bufferlist &bl);
   virtual void dump(Formatter *f) const = 0;
 
-  void encode_with_header(bufferlist& bl) {
+  void encode_with_header(bufferlist& bl, uint64_t features) {
     ::encode(EVENT_NEW_ENCODING, bl);
     ENCODE_START(1, 1, bl)
     ::encode(_type, bl);
-    encode(bl);
+    encode(bl, features);
     ENCODE_FINISH(bl);
   }
 
diff --git a/src/mds/MDCache.cc b/src/mds/MDCache.cc
index 0441f84..9eec056 100644
--- a/src/mds/MDCache.cc
+++ b/src/mds/MDCache.cc
@@ -100,8 +100,6 @@
 
 using namespace std;
 
-extern struct ceph_file_layout g_default_file_layout;
-
 #include "common/config.h"
 #include "include/assert.h"
 
@@ -213,9 +211,6 @@ MDCache::MDCache(MDSRank *m) :
 
   decayrate.set_halflife(g_conf->mds_decay_halflife);
 
-  memset(&default_file_layout, 0, sizeof(default_file_layout));
-  memset(&default_log_layout, 0, sizeof(default_log_layout));
-
   did_shutdown_log_cap = false;
 }
 
@@ -327,23 +322,21 @@ void MDCache::remove_inode(CInode *o)
   delete o; 
 }
 
-ceph_file_layout MDCache::gen_default_file_layout(const MDSMap &mdsmap)
+file_layout_t MDCache::gen_default_file_layout(const MDSMap &mdsmap)
 {
-  ceph_file_layout result = g_default_file_layout;
-  result.fl_pg_pool = mdsmap.get_first_data_pool();
-
+  file_layout_t result = file_layout_t::get_default();
+  result.pool_id = mdsmap.get_first_data_pool();
   return result;
 }
 
-ceph_file_layout MDCache::gen_default_log_layout(const MDSMap &mdsmap)
+file_layout_t MDCache::gen_default_log_layout(const MDSMap &mdsmap)
 {
-  ceph_file_layout result = g_default_file_layout;
-  result.fl_pg_pool = mdsmap.get_metadata_pool();
+  file_layout_t result = file_layout_t::get_default();
+  result.pool_id = mdsmap.get_metadata_pool();
   if (g_conf->mds_log_segment_size > 0) {
-    result.fl_object_size = g_conf->mds_log_segment_size;
-    result.fl_stripe_unit = g_conf->mds_log_segment_size;
+    result.object_size = g_conf->mds_log_segment_size;
+    result.stripe_unit = g_conf->mds_log_segment_size;
   }
-
   return result;
 }
 
@@ -351,7 +344,6 @@ void MDCache::init_layouts()
 {
   default_file_layout = gen_default_file_layout(*(mds->mdsmap));
   default_log_layout = gen_default_log_layout(*(mds->mdsmap));
-
 }
 
 void MDCache::create_unlinked_system_inode(CInode *in, inodeno_t ino,
@@ -369,7 +361,6 @@ void MDCache::create_unlinked_system_inode(CInode *in, inodeno_t ino,
 
   memset(&in->inode.dir_layout, 0, sizeof(in->inode.dir_layout));
   if (in->inode.is_dir()) {
-    memset(&in->inode.layout, 0, sizeof(in->inode.layout));
     in->inode.dir_layout.dl_dir_hash = g_conf->mds_default_dir_hash;
     ++in->inode.rstat.rsubdirs;
   } else {
@@ -404,7 +395,7 @@ CInode *MDCache::create_root_inode()
   i->inode.uid = g_conf->mds_root_ino_uid;
   i->inode.gid = g_conf->mds_root_ino_gid;
   i->inode.layout = default_file_layout;
-  i->inode.layout.fl_pg_pool = mds->mdsmap->get_first_data_pool();
+  i->inode.layout.pool_id = mds->mdsmap->get_first_data_pool();
   return i;
 }
 
@@ -576,10 +567,16 @@ struct C_MDS_RetryOpenRoot : public MDSInternalContext {
   MDCache *cache;
   explicit C_MDS_RetryOpenRoot(MDCache *c) : MDSInternalContext(c->mds), cache(c) {}
   void finish(int r) {
-    if (r < 0)
-      cache->mds->suicide();
-    else
+    if (r < 0) {
+      // If we can't open root, something disastrous has happened: mark
+      // this rank damaged for operator intervention.  Note that
+      // it is not okay to call suicide() here because we are in
+      // a Finisher callback.
+      cache->mds->damaged();
+      assert(0);  // damaged should never return
+    } else {
       cache->open_root();
+    }
   }
 };
 
@@ -698,10 +695,11 @@ void MDCache::populate_mydir()
 	dir = strays[i]->get_or_open_dirfrag(this, fg);
       }
 
-      if (dir->state_test(CDir::STATE_BADFRAG)) {
-        mds->damaged();
-        assert(0);
-      } else if (dir->get_version() == 0) {
+      // DamageTable applies special handling to strays: it will
+      // have damaged() us out if one is damaged.
+      assert(!dir->state_test(CDir::STATE_BADFRAG));
+
+      if (dir->get_version() == 0) {
         dir->fetch(new C_MDS_RetryOpenRoot(this));
         return;
       }
@@ -1614,7 +1612,7 @@ void MDCache::journal_cow_dentry(MutationImpl *mut, EMetaBlob *metablob,
       if (dir_follows+1 > dn->first) {
 	snapid_t oldfirst = dn->first;
 	dn->first = dir_follows+1;
-	if (realm->has_snaps_in_range(oldfirst, dn->last)) {
+	if (realm->has_snaps_in_range(oldfirst, dir_follows)) {
 	  CDentry *olddn = dn->dir->add_remote_dentry(dn->name, in->ino(),  in->d_type(),
 						      oldfirst, dir_follows);
 	  olddn->pre_dirty();
@@ -1645,7 +1643,7 @@ void MDCache::journal_cow_dentry(MutationImpl *mut, EMetaBlob *metablob,
       return;
     }
 
-    if (!realm->has_snaps_in_range(in->first, in->last)) {
+    if (!realm->has_snaps_in_range(in->first, follows)) {
       dout(10) << "journal_cow_dentry no snapshot follows " << follows << " on " << *in << dendl;
       in->first = follows + 1;
       return;
@@ -1670,7 +1668,7 @@ void MDCache::journal_cow_dentry(MutationImpl *mut, EMetaBlob *metablob,
 
     CInode *in = dnl->is_primary() ? dnl->get_inode() : NULL;
 
-    if (!realm->has_snaps_in_range(oldfirst, dn->last)) {
+    if (!realm->has_snaps_in_range(oldfirst, follows)) {
       dout(10) << "journal_cow_dentry no snapshot follows " << follows << " on " << *dn << dendl;
       if (in)
 	in->first = follows+1;
@@ -1721,8 +1719,8 @@ void MDCache::journal_dirty_inode(MutationImpl *mut, EMetaBlob *metablob, CInode
     if (!dn->get_projected_linkage()->is_null())  // no need to cow a null dentry
       journal_cow_dentry(mut, metablob, dn, follows);
     if (in->get_projected_inode()->is_backtrace_updated()) {
-      bool dirty_pool = in->get_projected_inode()->layout.fl_pg_pool !=
-			in->get_previous_projected_inode()->layout.fl_pg_pool;
+      bool dirty_pool = in->get_projected_inode()->layout.pool_id !=
+			in->get_previous_projected_inode()->layout.pool_id;
       metablob->add_primary_dentry(dn, in, true, true, dirty_pool);
     } else {
       metablob->add_primary_dentry(dn, in, true);
@@ -4414,7 +4412,7 @@ void MDCache::handle_cache_rejoin_weak(MMDSCacheRejoin *weak)
 
       if (ack) {
 	acked_inodes.insert(in->vino());
-	ack->add_inode_base(in);
+	ack->add_inode_base(in, mds->mdsmap->get_up_features());
 	bufferlist bl;
 	in->_encode_locks_state_for_rejoin(bl, from);
 	ack->add_inode_locks(in, inonce, bl);
@@ -4435,7 +4433,7 @@ void MDCache::handle_cache_rejoin_weak(MMDSCacheRejoin *weak)
     
     if (ack) {
       acked_inodes.insert(in->vino());
-      ack->add_inode_base(in);
+      ack->add_inode_base(in, mds->mdsmap->get_up_features());
       bufferlist bl;
       in->_encode_locks_state_for_rejoin(bl, from);
       ack->add_inode_locks(in, inonce, bl);
@@ -4453,7 +4451,7 @@ void MDCache::handle_cache_rejoin_weak(MMDSCacheRejoin *weak)
       assert(in);
       dout(10) << " including base inode (due to potential scatterlock update) " << *in << dendl;
       acked_inodes.insert(in->vino());
-      ack->add_inode_base(in);
+      ack->add_inode_base(in, mds->mdsmap->get_up_features());
     }
 
     rejoin_scour_survivor_replicas(from, ack, acked_inodes, gather_locks);
@@ -5890,7 +5888,7 @@ void MDCache::rejoin_send_acks()
 	for (compact_map<mds_rank_t,unsigned>::iterator r = in->replicas_begin();
 	     r != in->replicas_end();
 	     ++r) {
-	  ack[r->first]->add_inode_base(in);
+	  ack[r->first]->add_inode_base(in, mds->mdsmap->get_up_features());
 	  bufferlist bl;
 	  in->_encode_locks_state_for_rejoin(bl, r->first);
 	  ack[r->first]->add_inode_locks(in, ++r->second, bl);
@@ -5907,7 +5905,7 @@ void MDCache::rejoin_send_acks()
     for (compact_map<mds_rank_t,unsigned>::iterator r = root->replicas_begin();
 	 r != root->replicas_end();
 	 ++r) {
-      ack[r->first]->add_inode_base(root);
+      ack[r->first]->add_inode_base(root, mds->mdsmap->get_up_features());
       bufferlist bl;
       root->_encode_locks_state_for_rejoin(bl, r->first);
       ack[r->first]->add_inode_locks(root, ++r->second, bl);
@@ -5916,7 +5914,7 @@ void MDCache::rejoin_send_acks()
     for (compact_map<mds_rank_t,unsigned>::iterator r = myin->replicas_begin();
 	 r != myin->replicas_end();
 	 ++r) {
-      ack[r->first]->add_inode_base(myin);
+      ack[r->first]->add_inode_base(myin, mds->mdsmap->get_up_features());
       bufferlist bl;
       myin->_encode_locks_state_for_rejoin(bl, r->first);
       ack[r->first]->add_inode_locks(myin, ++r->second, bl);
@@ -5930,7 +5928,7 @@ void MDCache::rejoin_send_acks()
     for (compact_map<mds_rank_t,unsigned>::iterator r = in->replicas_begin();
 	 r != in->replicas_end();
 	 ++r)
-      ack[r->first]->add_inode_base(in);
+      ack[r->first]->add_inode_base(in, mds->mdsmap->get_up_features());
   }
 
   // send acks
@@ -7762,6 +7760,14 @@ int MDCache::path_traverse(MDRequestRef& mdr, Message *req, MDSInternalContextBa
     }
     */
 
+    // Before doing dirfrag->dn lookup, compare with DamageTable's
+    // record of which dentries were unreadable
+    if (mds->damage_table.is_dentry_damaged(curdir, path[depth], snapid)) {
+      dout(4) << "traverse: stopped lookup at damaged dentry "
+              << *curdir << "/" << path[depth] << " snap=" << snapid << dendl;
+      return -EIO;
+    }
+
     // dentry
     CDentry *dn = curdir->lookup(path[depth], snapid);
     CDentry::linkage_t *dnl = dn ? dn->get_projected_linkage() : 0;
@@ -7821,6 +7827,11 @@ int MDCache::path_traverse(MDRequestRef& mdr, Message *req, MDSInternalContextBa
 	} else {
           dout(7) << "remote link to " << dnl->get_remote_ino() << ", which i don't have" << dendl;
 	  assert(mdr);  // we shouldn't hit non-primary dentries doing a non-mdr traversal!
+          if (mds->damage_table.is_remote_damaged(dnl->get_remote_ino())) {
+            dout(4) << "traverse: remote dentry points to damaged ino "
+                    << *dn << dendl;
+            return -EIO;
+          }
           open_remote_dentry(dn, true, _get_waiter(mdr, req, fin),
 			     (null_okay && depth == path.depth() - 1));
 	  if (mds->logger) mds->logger->inc(l_mds_traverse_remote_ino);
@@ -7879,6 +7890,15 @@ int MDCache::path_traverse(MDRequestRef& mdr, Message *req, MDSInternalContextBa
 	}
         return -ENOENT;
       } else {
+
+        // Check DamageTable for missing fragments before trying to fetch
+        // this
+        if (mds->damage_table.is_dirfrag_damaged(curdir)) {
+          dout(4) << "traverse: damaged dirfrag " << *curdir
+                  << ", blocking fetch" << dendl;
+          return -EIO;
+        }
+
 	// directory isn't complete; reload
         dout(7) << "traverse: incomplete dir contents for " << *cur << ", fetching" << dendl;
         touch_inode(cur);
@@ -8063,6 +8083,12 @@ void MDCache::_open_remote_dentry_finish(CDentry *dn, inodeno_t ino, MDSInternal
   if (r < 0) {
       dout(0) << "open_remote_dentry_finish bad remote dentry " << *dn << dendl;
       dn->state_set(CDentry::STATE_BADREMOTEINO);
+      bool fatal = mds->damage_table.notify_remote_damaged(
+          dn->get_projected_linkage()->get_remote_ino());
+      if (fatal) {
+        mds->damaged();
+        assert(0);  // unreachable, damaged() respawns us
+      }
   }
   fin->complete(r < 0 ? r : 0);
 }
@@ -8557,7 +8583,7 @@ void MDCache::open_ino(inodeno_t ino, int64_t pool, MDSInternalContextBase* fin,
     info.want_replica = want_replica;
     info.want_xlocked = want_xlocked;
     info.tid = ++open_ino_last_tid;
-    info.pool = pool >= 0 ? pool : default_file_layout.fl_pg_pool;
+    info.pool = pool >= 0 ? pool : default_file_layout.pool_id;
     info.waiters.push_back(fin);
     do_open_ino(ino, info, 0);
   }
@@ -8851,15 +8877,18 @@ void MDCache::dispatch_request(MDRequestRef& mdr)
     case CEPH_MDS_OP_EXPORTDIR:
       migrator->dispatch_export_dir(mdr);
       break;
-    case CEPH_MDS_OP_VALIDATE:
-      scrub_dentry_work(mdr);
-      break;
     case CEPH_MDS_OP_ENQUEUE_SCRUB:
       enqueue_scrub_work(mdr);
       break;
     case CEPH_MDS_OP_FLUSH:
       flush_dentry_work(mdr);
       break;
+    case CEPH_MDS_OP_REPAIR_FRAGSTATS:
+      repair_dirfrag_stats_work(mdr);
+      break;
+    case CEPH_MDS_OP_REPAIR_INODESTATS:
+      repair_inode_stats_work(mdr);
+      break;
     default:
       assert(0);
     }
@@ -9516,7 +9545,7 @@ void MDCache::handle_discover(MDiscover *dis)
 
     // add root
     reply->starts_with = MDiscoverReply::INODE;
-    replicate_inode(cur, from, reply->trace);
+    replicate_inode(cur, from, reply->trace, mds->mdsmap->get_up_features());
     dout(10) << "added base " << *cur << dendl;
   }
   else {
@@ -9741,7 +9770,7 @@ void MDCache::handle_discover(MDiscover *dis)
     CInode *next = dnl->get_inode();
     assert(next->is_auth());
     
-    replicate_inode(next, from, reply->trace);
+    replicate_inode(next, from, reply->trace, mds->mdsmap->get_up_features());
     dout(7) << "handle_discover added inode " << *next << dendl;
     
     // descend, keep going.
@@ -10020,10 +10049,11 @@ CInode *MDCache::add_replica_inode(bufferlist::iterator& p, CDentry *dn, list<MD
  
 void MDCache::replicate_stray(CDentry *straydn, mds_rank_t who, bufferlist& bl)
 {
-  replicate_inode(get_myin(), who, bl);
+  uint64_t features = mds->mdsmap->get_up_features();
+  replicate_inode(get_myin(), who, bl, features);
   replicate_dir(straydn->get_dir()->inode->get_parent_dn()->get_dir(), who, bl);
   replicate_dentry(straydn->get_dir()->inode->get_parent_dn(), who, bl);
-  replicate_inode(straydn->get_dir()->inode, who, bl);
+  replicate_inode(straydn->get_dir()->inode, who, bl, features);
   replicate_dir(straydn->get_dir(), who, bl);
   replicate_dentry(straydn, who, bl);
 }
@@ -10150,7 +10180,8 @@ void MDCache::send_dentry_link(CDentry *dn, MDRequestRef& mdr)
 				     dn->name, dnl->is_primary());
     if (dnl->is_primary()) {
       dout(10) << "  primary " << *dnl->get_inode() << dendl;
-      replicate_inode(dnl->get_inode(), p->first, m->bl);
+      replicate_inode(dnl->get_inode(), p->first, m->bl,
+		      mds->mdsmap->get_up_features());
     } else if (dnl->is_remote()) {
       inodeno_t ino = dnl->get_remote_ino();
       __u8 d_type = dnl->get_remote_d_type();
@@ -11681,56 +11712,57 @@ void C_MDS_RetryRequest::finish(int r)
   cache->dispatch_request(mdr);
 }
 
-class C_scrub_dentry_finish : public Context {
-public:
-  CInode::validated_data results;
-  MDRequestRef mdr;
-  Context *on_finish;
+
+class C_MDS_EnqueueScrub : public Context
+{
   Formatter *formatter;
-  C_scrub_dentry_finish(MDRequestRef& mdr,
-                        Context *fin, Formatter *f) :
-    mdr(mdr), on_finish(fin), formatter(f) {}
+  Context *on_finish;
+public:
+  ScrubHeaderRef header;
+  C_MDS_EnqueueScrub(Formatter *f, Context *fin) :
+    formatter(f), on_finish(fin), header(new ScrubHeader()) {}
+
+  Context *take_finisher() {
+    Context *fin = on_finish;
+    on_finish = NULL;
+    return fin;
+  }
 
   void finish(int r) {
-    if (r >= 0) { // we got into the scrubbing dump it
-      results.dump(formatter);
-    } else { // we failed the lookup or something; dump ourselves
+    if (r < 0) { // we failed the lookup or something; dump ourselves
       formatter->open_object_section("results");
       formatter->dump_int("return_code", r);
       formatter->close_section(); // results
     }
-    on_finish->complete(r);
+    if (on_finish)
+      on_finish->complete(r);
   }
 };
 
-void MDCache::scrub_dentry(const string& path, Formatter *f, Context *fin)
+void MDCache::enqueue_scrub(
+    const string& path,
+    const std::string &tag,
+    bool force, bool recursive, bool repair,
+    Formatter *f, Context *fin)
 {
-  dout(10) << "scrub_dentry " << path << dendl;
-  MDRequestRef mdr = request_start_internal(CEPH_MDS_OP_VALIDATE);
+  dout(10) << __func__ << path << dendl;
+  MDRequestRef mdr = request_start_internal(CEPH_MDS_OP_ENQUEUE_SCRUB);
   filepath fp(path.c_str());
   mdr->set_filepath(fp);
-  C_scrub_dentry_finish *csd = new C_scrub_dentry_finish(mdr, fin, f);
-  mdr->internal_op_finish = csd;
-  mdr->internal_op_private = &csd->results;
-  scrub_dentry_work(mdr);
-}
 
-/**
- * The private data for an OP_ENQUEUE_SCRUB MDRequest
- */
-class EnqueueScrubParams
-{
-  public:
-  const bool recursive;
-  const bool children;
-  const std::string tag;
-  EnqueueScrubParams(bool r, bool c, const std::string &tag_)
-    : recursive(r), children(c), tag(tag_)
-  {}
-};
+  C_MDS_EnqueueScrub *cs = new C_MDS_EnqueueScrub(f, fin);
+  ScrubHeaderRef &header = cs->header;
+  header->tag = tag;
+  header->force = force;
+  header->recursive = recursive;
+  header->repair = repair;
+  header->formatter = f;
 
+  mdr->internal_op_finish = cs;
+  enqueue_scrub_work(mdr);
+}
 
-void MDCache::scrub_dentry_work(MDRequestRef& mdr)
+void MDCache::enqueue_scrub_work(MDRequestRef& mdr)
 {
   set<SimpleLock*> rdlocks, wrlocks, xlocks;
   CInode *in = mds->server->rdlock_path_pin_ref(mdr, 0, rdlocks, true);
@@ -11744,101 +11776,232 @@ void MDCache::scrub_dentry_work(MDRequestRef& mdr)
   if (!locked)
     return;
 
-  CInode::validated_data *vr =
-      static_cast<CInode::validated_data*>(mdr->internal_op_private);
+  C_MDS_EnqueueScrub *cs = static_cast<C_MDS_EnqueueScrub*>(mdr->internal_op_finish);
+  ScrubHeaderRef &header = cs->header;
 
-  in->validate_disk_state(vr, mdr, NULL);
+  // Cannot scrub same dentry twice at same time
+  if (in->scrub_info()->scrub_in_progress) {
+    mds->server->respond_to_request(mdr, -EBUSY);
+    return;
+  }
+
+  header->origin = in;
+
+  // only set completion context for non-recursive scrub, because we don't 
+  // want to block asok caller on long running scrub
+  if (!header->recursive) {
+    Context *fin = cs->take_finisher();
+    mds->scrubstack->enqueue_inode_top(in, header,
+				       new MDSInternalContextWrapper(mds, fin));
+  } else
+    mds->scrubstack->enqueue_inode_bottom(in, header, NULL);
+
+  mds->server->respond_to_request(mdr, 0);
   return;
 }
 
-
-class C_ScrubEnqueued : public Context
-{
-public:
+struct C_MDC_RepairDirfragStats : public MDSInternalContext {
   MDRequestRef mdr;
-  Context *on_finish;
-  Formatter *formatter;
-  C_ScrubEnqueued(MDRequestRef& mdr,
-                  Context *fin, Formatter *f) :
-    mdr(mdr), on_finish(fin), formatter(f) {}
-
+  C_MDC_RepairDirfragStats(MDSRank *_mds, MDRequestRef& m) :
+    MDSInternalContext(_mds), mdr(m) {}
   void finish(int r) {
-#if 0
-    if (r >= 0) { // we got into the scrubbing dump it
-      results.dump(formatter);
-    } else { // we failed the lookup or something; dump ourselves
-      formatter->open_object_section("results");
-      formatter->dump_int("return_code", r);
-      formatter->close_section(); // results
-    }
-#endif
-    on_finish->complete(r);
+    mdr->apply();
+    mds->server->respond_to_request(mdr, r);
   }
 };
 
-void MDCache::enqueue_scrub(
-    const string& path,
-    const std::string &tag,
-    Formatter *f, Context *fin)
+void MDCache::repair_dirfrag_stats(CDir *dir)
 {
-  dout(10) << "scrub_dentry " << path << dendl;
-  MDRequestRef mdr = request_start_internal(CEPH_MDS_OP_ENQUEUE_SCRUB);
-  filepath fp(path.c_str());
-  mdr->set_filepath(fp);
-
-  C_ScrubEnqueued *se = new C_ScrubEnqueued(mdr, fin, f);
-  mdr->internal_op_finish = se;
-  // TODO pass through tag/args
-  mdr->internal_op_private = new EnqueueScrubParams(true, true, tag);
-  enqueue_scrub_work(mdr);
+  MDRequestRef mdr = request_start_internal(CEPH_MDS_OP_REPAIR_FRAGSTATS);
+  mdr->pin(dir);
+  mdr->internal_op_private = dir;
+  mdr->internal_op_finish = new C_MDSInternalNoop;
+  repair_dirfrag_stats_work(mdr);
 }
 
-void MDCache::enqueue_scrub_work(MDRequestRef& mdr)
+void MDCache::repair_dirfrag_stats_work(MDRequestRef& mdr)
 {
+  CDir *dir = static_cast<CDir*>(mdr->internal_op_private);
+  dout(10) << __func__ << " " << *dir << dendl;
+
+  if (!dir->is_auth()) {
+    mds->server->respond_to_request(mdr, -ESTALE);
+    return;
+  }
+
+  if (!mdr->is_auth_pinned(dir) && !dir->can_auth_pin()) {
+    mds->locker->drop_locks(mdr.get());
+    mdr->drop_local_auth_pins();
+    dir->add_waiter(CDir::WAIT_UNFREEZE, new C_MDS_RetryRequest(this, mdr));
+    return;
+  }
+
+  mdr->auth_pin(dir);
+
   set<SimpleLock*> rdlocks, wrlocks, xlocks;
-  CInode *in = mds->server->rdlock_path_pin_ref(mdr, 0, rdlocks, true);
-  if (NULL == in)
+  CInode *diri = dir->inode;
+  rdlocks.insert(&diri->dirfragtreelock);
+  wrlocks.insert(&diri->nestlock);
+  wrlocks.insert(&diri->filelock);
+  if (!mds->locker->acquire_locks(mdr, rdlocks, wrlocks, xlocks))
     return;
 
-  // TODO: Remove this restriction
-  assert(in->is_auth());
+  if (!dir->is_complete()) {
+    dir->fetch(new C_MDS_RetryRequest(this, mdr));
+    return;
+  }
 
-  bool locked = mds->locker->acquire_locks(mdr, rdlocks, wrlocks, xlocks);
-  if (!locked)
+  frag_info_t frag_info;
+  nest_info_t nest_info;
+  for (CDir::map_t::iterator it = dir->begin(); it != dir->end(); ++it) {
+    CDentry *dn = it->second;
+    if (dn->last != CEPH_NOSNAP)
+      continue;
+    CDentry::linkage_t *dnl = dn->get_projected_linkage();
+    if (dnl->is_primary()) {
+      CInode *in = dnl->get_inode();
+      nest_info.add(in->get_projected_inode()->accounted_rstat);
+      if (in->is_dir())
+	frag_info.nsubdirs++;
+      else
+	frag_info.nfiles++;
+    } else if (dnl->is_remote())
+      frag_info.nfiles++;
+  }
+
+  fnode_t *pf = dir->get_projected_fnode();
+  bool good_fragstat = frag_info.same_sums(pf->fragstat);
+  bool good_rstat = nest_info.same_sums(pf->rstat);
+  if (good_fragstat && good_rstat) {
+    dout(10) << __func__ << " no corruption found" << dendl;
+    mds->server->respond_to_request(mdr, 0);
     return;
+  }
 
-  CDentry *dn = in->get_parent_dn();
+  pf = dir->project_fnode();
+  pf->version = dir->pre_dirty();
+  mdr->add_projected_fnode(dir);
 
-  // We got to this inode by path, so it must have a parent
-  assert(dn != NULL);
+  mdr->ls = mds->mdlog->get_current_segment();
+  EUpdate *le = new EUpdate(mds->mdlog, "repair_dirfrag");
+  mds->mdlog->start_entry(le);
 
-  // Not setting a completion context here because we don't
-  // want to block asok caller on long running scrub
-  EnqueueScrubParams *args = static_cast<EnqueueScrubParams*>(
-      mdr->internal_op_private);
-  assert(args != NULL);
+  if (!good_fragstat) {
+    if (pf->fragstat.mtime > frag_info.mtime)
+      frag_info.mtime = pf->fragstat.mtime;
+    pf->fragstat = frag_info;
+    mds->locker->mark_updated_scatterlock(&diri->filelock);
+    mdr->ls->dirty_dirfrag_dir.push_back(&diri->item_dirty_dirfrag_dir);
+    mdr->add_updated_lock(&diri->filelock);
+  }
 
-  // Cannot scrub same dentry twice at same time
-  if (dn->scrub_info()->dentry_scrubbing) {
-    mds->server->respond_to_request(mdr, -EBUSY);
+  if (!good_rstat) {
+    if (pf->rstat.rctime > nest_info.rctime)
+      nest_info.rctime = pf->rstat.rctime;
+    pf->rstat = nest_info;
+    mds->locker->mark_updated_scatterlock(&diri->nestlock);
+    mdr->ls->dirty_dirfrag_nest.push_back(&diri->item_dirty_dirfrag_nest);
+    mdr->add_updated_lock(&diri->nestlock);
+  }
+
+  le->metablob.add_dir_context(dir);
+  le->metablob.add_dir(dir, true);
+
+  mds->mdlog->submit_entry(le, new C_MDC_RepairDirfragStats(mds, mdr));
+}
+
+void MDCache::repair_inode_stats(CInode *diri)
+{
+  MDRequestRef mdr = request_start_internal(CEPH_MDS_OP_REPAIR_INODESTATS);
+  mdr->pin(diri);
+  mdr->internal_op_private = diri;
+  mdr->internal_op_finish = new C_MDSInternalNoop;
+  repair_inode_stats_work(mdr);
+}
+
+void MDCache::repair_inode_stats_work(MDRequestRef& mdr)
+{
+  CInode *diri = static_cast<CInode*>(mdr->internal_op_private);
+  dout(10) << __func__ << " " << *diri << dendl;
+
+  if (!diri->is_auth()) {
+    mds->server->respond_to_request(mdr, -ESTALE);
+    return;
+  }
+  if (!diri->is_dir()) {
+    mds->server->respond_to_request(mdr, -ENOTDIR);
     return;
   }
 
-  ScrubHeaderRef header(new ScrubHeader());
+  set<SimpleLock*> rdlocks, wrlocks, xlocks;
+  std::list<frag_t> frags;
 
-  header->tag = args->tag;
-  header->origin = dn;
+  if (mdr->ls) // already marked filelock/nestlock dirty ?
+    goto do_rdlocks;
 
-  mds->scrubstack->enqueue_dentry_bottom(dn, true, true, header, NULL);
-  delete args;
-  mdr->internal_op_private = NULL;
+  rdlocks.insert(&diri->dirfragtreelock);
+  wrlocks.insert(&diri->nestlock);
+  wrlocks.insert(&diri->filelock);
+  if (!mds->locker->acquire_locks(mdr, rdlocks, wrlocks, xlocks))
+    return;
 
-  // Successfully enqueued
-  mds->server->respond_to_request(mdr, 0);
-  return;
-}
+  // Fetch all dirfrags and mark filelock/nestlock dirty. This will tirgger
+  // the scatter-gather process, which will fix any fragstat/rstat errors.
+  diri->dirfragtree.get_leaves(frags);
+  for (list<frag_t>::iterator p = frags.begin(); p != frags.end(); ++p) {
+    CDir *dir = diri->get_dirfrag(*p);
+    if (!dir) {
+      assert(mdr->is_auth_pinned(diri));
+      dir = diri->get_or_open_dirfrag(this, *p);
+    }
+    if (dir->get_version() == 0) {
+      assert(dir->is_auth());
+      dir->fetch(new C_MDS_RetryRequest(this, mdr));
+      return;
+    }
+  }
+
+  diri->state_set(CInode::STATE_REPAIRSTATS);
+  mdr->ls = mds->mdlog->get_current_segment();
+  mds->locker->mark_updated_scatterlock(&diri->filelock);
+  mdr->ls->dirty_dirfrag_dir.push_back(&diri->item_dirty_dirfrag_dir);
+  mds->locker->mark_updated_scatterlock(&diri->nestlock);
+  mdr->ls->dirty_dirfrag_nest.push_back(&diri->item_dirty_dirfrag_nest);
+
+  mds->locker->drop_locks(mdr.get());
+
+do_rdlocks:
+  // force the scatter-gather process
+  rdlocks.insert(&diri->dirfragtreelock);
+  rdlocks.insert(&diri->nestlock);
+  rdlocks.insert(&diri->filelock);
+  wrlocks.clear();
+  if (!mds->locker->acquire_locks(mdr, rdlocks, wrlocks, xlocks))
+    return;
+
+  diri->state_clear(CInode::STATE_REPAIRSTATS);
+
+  frag_info_t dir_info;
+  nest_info_t nest_info;
+  nest_info.rsubdirs++; // it gets one to account for self
 
+  diri->dirfragtree.get_leaves(frags);
+  for (list<frag_t>::iterator p = frags.begin(); p != frags.end(); ++p) {
+    CDir *dir = diri->get_dirfrag(*p);
+    assert(dir);
+    assert(dir->get_version() > 0);
+    dir_info.add(dir->fnode.accounted_fragstat);
+    nest_info.add(dir->fnode.accounted_rstat);
+  }
 
+  if (!dir_info.same_sums(diri->inode.dirstat) ||
+      !nest_info.same_sums(diri->inode.rstat)) {
+    dout(10) << __func__ << " failed to fix fragstat/rstat on "
+	     << *diri << dendl;
+  }
+
+  mds->server->respond_to_request(mdr, 0);
+}
 
 void MDCache::flush_dentry(const string& path, Context *fin)
 {
diff --git a/src/mds/MDCache.h b/src/mds/MDCache.h
index 3b44d0c..5aadc13 100644
--- a/src/mds/MDCache.h
+++ b/src/mds/MDCache.h
@@ -170,11 +170,11 @@ public:
 
   unsigned max_dir_commit_size;
 
-  static ceph_file_layout gen_default_file_layout(const MDSMap &mdsmap);
-  static ceph_file_layout gen_default_log_layout(const MDSMap &mdsmap);
+  static file_layout_t gen_default_file_layout(const MDSMap &mdsmap);
+  static file_layout_t gen_default_log_layout(const MDSMap &mdsmap);
 
-  ceph_file_layout default_file_layout;
-  ceph_file_layout default_log_layout;
+  file_layout_t default_file_layout;
+  file_layout_t default_log_layout;
 
   void register_perfcounters();
 
@@ -989,10 +989,11 @@ public:
     ::encode(dn->last, bl);
     dn->encode_replica(to, bl);
   }
-  void replicate_inode(CInode *in, mds_rank_t to, bufferlist& bl) {
+  void replicate_inode(CInode *in, mds_rank_t to, bufferlist& bl,
+		       uint64_t features) {
     ::encode(in->inode.ino, bl);  // bleh, minor assymetry here
     ::encode(in->last, bl);
-    in->encode_replica(to, bl);
+    in->encode_replica(to, bl, features);
   }
   
   CDir* add_replica_dir(bufferlist::iterator& p, CInode *diri, mds_rank_t from, list<MDSInternalContextBase*>& finished);
@@ -1128,21 +1129,8 @@ public:
     return p->second;
   }
 
-  void scrub_dentry(const string& path, Formatter *f, Context *fin);
-  /**
-   * Scrub the named dentry only (skip the scrubstack)
-   */
-  void scrub_dentry_work(MDRequestRef& mdr);
-
-  void flush_dentry(const string& path, Context *fin);
+protected:
   void flush_dentry_work(MDRequestRef& mdr);
-
-  /**
-   * Create and start an OP_ENQUEUE_SCRUB
-   */
-  void enqueue_scrub(const string& path, const std::string &tag,
-                     Formatter *f, Context *fin);
-
   /**
    * Resolve path to a dentry and pass it onto the ScrubStack.
    *
@@ -1152,6 +1140,19 @@ public:
    * long time)
    */
   void enqueue_scrub_work(MDRequestRef& mdr);
+  void repair_inode_stats_work(MDRequestRef& mdr);
+  void repair_dirfrag_stats_work(MDRequestRef& mdr);
+  friend class C_MDC_RepairDirfragStats;
+public:
+  void flush_dentry(const string& path, Context *fin);
+  /**
+   * Create and start an OP_ENQUEUE_SCRUB
+   */
+  void enqueue_scrub(const string& path, const std::string &tag,
+                     bool force, bool recursive, bool repair,
+		     Formatter *f, Context *fin);
+  void repair_inode_stats(CInode *diri);
+  void repair_dirfrag_stats(CDir *dir);
 };
 
 class C_MDS_RetryRequest : public MDSInternalContext {
diff --git a/src/mds/MDLog.cc b/src/mds/MDLog.cc
index 86a1945..795ffb3 100644
--- a/src/mds/MDLog.cc
+++ b/src/mds/MDLog.cc
@@ -99,7 +99,13 @@ class C_MDL_WriteError : public MDSIOContextBase {
       mds->respawn();
     } else {
       derr << "unhandled error " << cpp_strerror(r) << ", shutting down..." << dendl;
-      mds->suicide();
+      // Although it's possible that this could be something transient,
+      // it's severe and scary, so disable this rank until an administrator
+      // intervenes.
+      mds->clog->error() << "Unhandled journal write error on MDS rank " <<
+        mds->get_nodeid() << ": " << cpp_strerror(r) << ", shutting down.";
+      mds->damaged();
+      assert(0);  // damaged should never return
     }
   }
 
@@ -382,7 +388,7 @@ void MDLog::_submit_thread()
       LogSegment *ls = le->_segment;
       // encode it, with event type
       bufferlist bl;
-      le->encode_with_header(bl);
+      le->encode_with_header(bl, mds->mdsmap->get_up_features());
 
       uint64_t write_pos = journaler->get_write_pos();
 
@@ -886,7 +892,11 @@ void MDLog::_recovery_thread(MDSInternalContextBase *completion)
   if (g_conf->mds_journal_format > JOURNAL_FORMAT_MAX) {
       dout(0) << "Configuration value for mds_journal_format is out of bounds, max is "
               << JOURNAL_FORMAT_MAX << dendl;
-      mds->suicide();
+
+      // Oh dear, something unreadable in the store for this rank: require
+      // operator intervention.
+      mds->damaged();
+      assert(0);  // damaged should not return
   }
 
   // First, read the pointer object.
@@ -1038,7 +1048,7 @@ void MDLog::_reformat_journal(JournalPointer const &jp_in, Journaler *old_journa
   Journaler *new_journal = new Journaler(jp.back, mds->mdsmap->get_metadata_pool(),
       CEPH_FS_ONDISK_MAGIC, mds->objecter, logger, l_mdl_jlat, &mds->timer, mds->finisher);
   dout(4) << "Writing new journal header " << jp.back << dendl;
-  ceph_file_layout new_layout = old_journal->get_layout();
+  file_layout_t new_layout = old_journal->get_layout();
   new_journal->set_writeable();
   new_journal->create(&new_layout, g_conf->mds_journal_format);
 
@@ -1134,7 +1144,7 @@ void MDLog::_reformat_journal(JournalPointer const &jp_in, Journaler *old_journa
 
       if (modified) {
         bl.clear();
-        le->encode_with_header(bl);
+        le->encode_with_header(bl, mds->mdsmap->get_up_features());
       }
 
       delete le;
diff --git a/src/mds/MDSDaemon.cc b/src/mds/MDSDaemon.cc
index 7e93a98..293d7c8 100644
--- a/src/mds/MDSDaemon.cc
+++ b/src/mds/MDSDaemon.cc
@@ -246,7 +246,9 @@ void MDSDaemon::set_up_admin_socket()
 				     "show slowest recent ops");
   assert(r == 0);
   r = admin_socket->register_command("scrub_path",
-                                     "scrub_path name=path,type=CephString",
+				     "scrub_path name=path,type=CephString "
+				     "name=scrubops,type=CephChoices,"
+				     "strings=force|recursive|repair,n=N,req=false",
                                      asok_hook,
                                      "scrub an inode and output results");
   assert(r == 0);
@@ -684,6 +686,10 @@ COMMAND("session ls " \
 COMMAND("session evict " \
 	"name=filters,type=CephString,n=N,req=false",
 	"Evict client session(s)", "mds", "rw", "cli,rest")
+COMMAND("damage ls",
+	"List detected metadata damage", "mds", "r", "cli,rest")
+COMMAND("damage rm name=damage_id,type=CephInt",
+	"Remove a damage table entry", "mds", "rw", "cli,rest")
 COMMAND("heap " \
 	"name=heapcmd,type=CephChoices,strings=dump|start_profiler|stop_profiler|release|stats", \
 	"show heap usage info (available only if compiled with tcmalloc)", \
@@ -971,7 +977,7 @@ void MDSDaemon::handle_mds_map(MMDSMap *m)
       // here!
       if (g_conf->mds_enforce_unique_name) {
         if (mds_gid_t existing = mdsmap->find_mds_gid_by_name(name)) {
-          MDSMap::mds_info_t& i = mdsmap->get_info_gid(existing);
+          const MDSMap::mds_info_t& i = mdsmap->get_info_gid(existing);
           if (i.global_id > monc->get_global_id()) {
             dout(1) << "handle_mds_map i (" << addr
                     << ") dne in the mdsmap, new instance has larger gid " << i.global_id
@@ -1098,8 +1104,6 @@ void MDSDaemon::suicide()
   }
   beacon.shutdown();
 
-  timer.shutdown();
-
   if (mds_rank) {
     mds_rank->shutdown();
   } else {
@@ -1107,6 +1111,7 @@ void MDSDaemon::suicide()
     if (objecter->initialized.read()) {
       objecter->shutdown();
     }
+    timer.shutdown();
 
     monc->shutdown();
     messenger->shutdown();
diff --git a/src/mds/MDSMap.cc b/src/mds/MDSMap.cc
index 73c2df9..e9b4e85 100644
--- a/src/mds/MDSMap.cc
+++ b/src/mds/MDSMap.cc
@@ -37,6 +37,7 @@ CompatSet get_mdsmap_compat_set_all() {
   feature_incompat.insert(MDS_FEATURE_INCOMPAT_OMAPDIRFRAG);
   feature_incompat.insert(MDS_FEATURE_INCOMPAT_INLINE);
   feature_incompat.insert(MDS_FEATURE_INCOMPAT_NOANCHOR);
+  feature_incompat.insert(MDS_FEATURE_INCOMPAT_FILE_LAYOUT_V2);
 
   return CompatSet(feature_compat, feature_ro_compat, feature_incompat);
 }
@@ -52,6 +53,7 @@ CompatSet get_mdsmap_compat_set_default() {
   feature_incompat.insert(MDS_FEATURE_INCOMPAT_ENCODING);
   feature_incompat.insert(MDS_FEATURE_INCOMPAT_OMAPDIRFRAG);
   feature_incompat.insert(MDS_FEATURE_INCOMPAT_NOANCHOR);
+  feature_incompat.insert(MDS_FEATURE_INCOMPAT_FILE_LAYOUT_V2);
 
   return CompatSet(feature_compat, feature_ro_compat, feature_incompat);
 }
@@ -79,12 +81,14 @@ void MDSMap::mds_info_t::dump(Formatter *f) const
     f->dump_stream("laggy_since") << laggy_since;
   
   f->dump_int("standby_for_rank", standby_for_rank);
+  f->dump_int("standby_for_ns", standby_for_ns);
   f->dump_string("standby_for_name", standby_for_name);
   f->open_array_section("export_targets");
   for (set<mds_rank_t>::iterator p = export_targets.begin();
        p != export_targets.end(); ++p) {
     f->dump_int("mds", *p);
   }
+  f->dump_unsigned("features", mds_features);
   f->close_section();
 }
 
@@ -173,8 +177,9 @@ void MDSMap::generate_test_instances(list<MDSMap*>& ls)
   ls.push_back(m);
 }
 
-void MDSMap::print(ostream& out) 
+void MDSMap::print(ostream& out) const
 {
+  out << "fs_name\t" << fs_name << "\n";
   out << "epoch\t" << epoch << "\n";
   out << "flags\t" << hex << flags << dec << "\n";
   out << "created\t" << created << "\n";
@@ -198,17 +203,15 @@ void MDSMap::print(ostream& out)
   out << "inline_data\t" << (inline_data_enabled ? "enabled" : "disabled") << "\n";
 
   multimap< pair<mds_rank_t, unsigned>, mds_gid_t > foo;
-  for (map<mds_gid_t,mds_info_t>::iterator p = mds_info.begin();
-       p != mds_info.end();
-       ++p)
-    foo.insert(std::make_pair(std::make_pair(p->second.rank, p->second.inc-1), p->first));
-
-  for (multimap< pair<mds_rank_t, unsigned>, mds_gid_t >::iterator p = foo.begin();
-       p != foo.end();
-       ++p) {
-    mds_info_t& info = mds_info[p->second];
+  for (const auto &p : mds_info) {
+    foo.insert(std::make_pair(
+          std::make_pair(p.second.rank, p.second.inc-1), p.first));
+  }
+
+  for (const auto &p : foo) {
+    const mds_info_t& info = mds_info.at(p.second);
     
-    out << p->second << ":\t"
+    out << p.second << ":\t"
 	<< info.addr
 	<< " '" << info.name << "'"
 	<< " mds." << info.rank
@@ -234,7 +237,7 @@ void MDSMap::print(ostream& out)
 
 
 
-void MDSMap::print_summary(Formatter *f, ostream *out)
+void MDSMap::print_summary(Formatter *f, ostream *out) const
 {
   map<mds_rank_t,string> by_rank;
   map<string,int> by_state;
@@ -250,22 +253,20 @@ void MDSMap::print_summary(Formatter *f, ostream *out)
 
   if (f)
     f->open_array_section("by_rank");
-  for (map<mds_gid_t,mds_info_t>::iterator p = mds_info.begin();
-       p != mds_info.end();
-       ++p) {
-    string s = ceph_mds_state_name(p->second.state);
-    if (p->second.laggy())
+  for (const auto &p : mds_info) {
+    string s = ceph_mds_state_name(p.second.state);
+    if (p.second.laggy())
       s += "(laggy or crashed)";
 
-    if (p->second.rank >= 0) {
+    if (p.second.rank >= 0) {
       if (f) {
 	f->open_object_section("mds");
-	f->dump_unsigned("rank", p->second.rank);
-	f->dump_string("name", p->second.name);
+	f->dump_unsigned("rank", p.second.rank);
+	f->dump_string("name", p.second.name);
 	f->dump_string("status", s);
 	f->close_section();
       } else {
-	by_rank[p->second.rank] = p->second.name + "=" + s;
+	by_rank[p.second.rank] = p.second.name + "=" + s;
       }
     } else {
       by_state[s]++;
@@ -398,7 +399,7 @@ void MDSMap::get_health(list<pair<health_status_t,string> >& summary,
 
 void MDSMap::mds_info_t::encode_versioned(bufferlist& bl, uint64_t features) const
 {
-  ENCODE_START(4, 4, bl);
+  ENCODE_START(6, 4, bl);
   ::encode(global_id, bl);
   ::encode(name, bl);
   ::encode(rank, bl);
@@ -410,6 +411,8 @@ void MDSMap::mds_info_t::encode_versioned(bufferlist& bl, uint64_t features) con
   ::encode(standby_for_rank, bl);
   ::encode(standby_for_name, bl);
   ::encode(export_targets, bl);
+  ::encode(mds_features, bl);
+  ::encode(standby_for_ns, bl);
   ENCODE_FINISH(bl);
 }
 
@@ -432,7 +435,7 @@ void MDSMap::mds_info_t::encode_unversioned(bufferlist& bl) const
 
 void MDSMap::mds_info_t::decode(bufferlist::iterator& bl)
 {
-  DECODE_START_LEGACY_COMPAT_LEN(4, 4, 4, bl);
+  DECODE_START_LEGACY_COMPAT_LEN(6, 4, 4, bl);
   ::decode(global_id, bl);
   ::decode(name, bl);
   ::decode(rank, bl);
@@ -445,6 +448,11 @@ void MDSMap::mds_info_t::decode(bufferlist::iterator& bl)
   ::decode(standby_for_name, bl);
   if (struct_v >= 2)
     ::decode(export_targets, bl);
+  if (struct_v >= 5)
+    ::decode(mds_features, bl);
+  if (struct_v >= 6) {
+    ::decode(standby_for_ns, bl);
+  }
   DECODE_FINISH(bl);
 }
 
@@ -556,6 +564,7 @@ void MDSMap::encode(bufferlist& bl, uint64_t features) const
 
 void MDSMap::decode(bufferlist::iterator& p)
 {
+  cached_up_features = 0;
   DECODE_START_LEGACY_COMPAT_LEN_16(5, 4, 4, p);
   ::decode(epoch, p);
   ::decode(flags, p);
@@ -642,12 +651,12 @@ void MDSMap::decode(bufferlist::iterator& p)
 MDSMap::availability_t MDSMap::is_cluster_available() const
 {
   if (epoch == 0) {
-    // This is ambiguous between "mds map was never initialized on mons" and
-    // "we never got an mdsmap from the mons".  Treat it like the latter.
+    // If I'm a client, this means I'm looking at an MDSMap instance
+    // that was never actually initialized from the mons.  Client should
+    // wait.
     return TRANSIENT_UNAVAILABLE;
   }
 
-
   // If a rank is marked damage (unavailable until operator intervenes)
   if (damaged.size()) {
     return STUCK_UNAVAILABLE;
@@ -658,25 +667,14 @@ MDSMap::availability_t MDSMap::is_cluster_available() const
     return STUCK_UNAVAILABLE;
   }
 
-  for (const auto rank : in) {
-    std::string name;
-    if (up.count(rank) != 0) {
-      name = mds_info.at(up.at(rank)).name;
-    }
-    const mds_gid_t replacement = find_replacement_for(rank, name, false);
-    const bool standby_avail = (replacement != MDS_GID_NONE);
-
-    // If the rank is unfilled, and there are no standbys, we're unavailable
-    if (up.count(rank) == 0 && !standby_avail) {
-      return STUCK_UNAVAILABLE;
-    } else if (up.count(rank) && mds_info.at(up.at(rank)).laggy() && !standby_avail) {
-      // If the daemon is laggy and there are no standbys, we're unavailable.
-      // It would be nice to give it some grace here, but to do so callers
-      // would have to poll this time-wise, vs. just waiting for updates
-      // to mdsmap, so it's not worth the complexity.
-      return STUCK_UNAVAILABLE;
-    }
-  }
+  for (const auto rank : in) {                                                  
+  if (up.count(rank) && mds_info.at(up.at(rank)).laggy()) {
+    // This might only be transient, but because we can't see
+    // standbys, we have no way of knowing whether there is a
+    // standby available to replace the laggy guy.
+    return STUCK_UNAVAILABLE;                                                 
+  }                                                                           
+}   
 
   if (get_num_mds(CEPH_MDS_STATE_ACTIVE) > 0) {
     // Nobody looks stuck, so indicate to client they should go ahead
@@ -687,6 +685,11 @@ MDSMap::availability_t MDSMap::is_cluster_available() const
     return AVAILABLE;
   } else {
     // Nothing indicating we were stuck, but nobody active (yet)
-    return TRANSIENT_UNAVAILABLE;
+    //return TRANSIENT_UNAVAILABLE;
+
+    // Because we don't have standbys in the MDSMap any more, we can't
+    // reliably indicate transient vs. stuck, so always say stuck so
+    // that the client doesn't block.
+    return STUCK_UNAVAILABLE;
   }
 }
diff --git a/src/mds/MDSMap.h b/src/mds/MDSMap.h
index 16249b0..314fe4e 100644
--- a/src/mds/MDSMap.h
+++ b/src/mds/MDSMap.h
@@ -70,6 +70,7 @@ extern CompatSet get_mdsmap_compat_set_base(); // pre v0.20
 #define MDS_FEATURE_INCOMPAT_OMAPDIRFRAG CompatSet::Feature(6, "dirfrag is stored in omap")
 #define MDS_FEATURE_INCOMPAT_INLINE CompatSet::Feature(7, "mds uses inline data")
 #define MDS_FEATURE_INCOMPAT_NOANCHOR CompatSet::Feature(8, "no anchor table")
+#define MDS_FEATURE_INCOMPAT_FILE_LAYOUT_V2 CompatSet::Feature(8, "file layout v2")
 
 #define MDS_FS_NAME_DEFAULT "cephfs"
 
@@ -139,10 +140,14 @@ public:
     utime_t laggy_since;
     mds_rank_t standby_for_rank;
     std::string standby_for_name;
+    fs_cluster_id_t standby_for_ns;
     std::set<mds_rank_t> export_targets;
+    uint64_t mds_features;
 
     mds_info_t() : global_id(MDS_GID_NONE), rank(MDS_RANK_NONE), inc(0), state(STATE_STANDBY), state_seq(0),
-		   standby_for_rank(MDS_NO_STANDBY_PREF) { }
+		   standby_for_rank(MDS_NO_STANDBY_PREF),
+                   standby_for_ns(FS_CLUSTER_ID_NONE)
+    { }
 
     bool laggy() const { return !(laggy_since == utime_t()); }
     void clear_laggy() { laggy_since = utime_t(); }
@@ -208,10 +213,14 @@ protected:
 
   bool inline_data_enabled;
 
+  uint64_t cached_up_features;
+
 public:
   CompatSet compat;
 
   friend class MDSMonitor;
+  friend class Filesystem;
+  friend class FSMap;
 
 public:
   MDSMap() 
@@ -227,7 +236,8 @@ public:
       max_mds(0),
       ever_allowed_snaps(false),
       explicitly_allowed_snaps(false),
-      inline_data_enabled(false)
+      inline_data_enabled(false),
+      cached_up_features(0)
   { }
 
   bool get_inline_data_enabled() { return inline_data_enabled; }
@@ -237,12 +247,15 @@ public:
     return utime_t(session_timeout,0);
   }
   uint64_t get_max_filesize() { return max_file_size; }
+  void set_max_filesize(uint64_t m) { max_file_size = m; }
   
   int get_flags() const { return flags; }
   int test_flag(int f) const { return flags & f; }
   void set_flag(int f) { flags |= f; }
   void clear_flag(int f) { flags &= ~f; }
 
+  const std::string &get_fs_name() const {return fs_name;}
+
   void set_snaps_allowed() {
     set_flag(CEPH_MDSMAP_ALLOW_SNAPS);
     ever_allowed_snaps = true;
@@ -272,7 +285,6 @@ public:
 
   const std::set<int64_t> &get_data_pools() const { return data_pools; }
   int64_t get_first_data_pool() const { return *data_pools.begin(); }
-  int64_t get_cas_pool() const { return cas_pool; }
   int64_t get_metadata_pool() const { return metadata_pool; }
   bool is_data_pool(int64_t poolid) const {
     return data_pools.count(poolid);
@@ -282,16 +294,15 @@ public:
     return get_enabled() && (is_data_pool(poolid) || metadata_pool == poolid);
   }
 
-  const std::map<mds_gid_t,mds_info_t>& get_mds_info() { return mds_info; }
-  const mds_info_t& get_mds_info_gid(mds_gid_t gid) {
-    assert(mds_info.count(gid));
-    return mds_info[gid];
+  const std::map<mds_gid_t,mds_info_t>& get_mds_info() const { return mds_info; }
+  const mds_info_t& get_mds_info_gid(mds_gid_t gid) const {
+    return mds_info.at(gid);
   }
-  const mds_info_t& get_mds_info(mds_rank_t m) {
-    assert(up.count(m) && mds_info.count(up[m]));
-    return mds_info[up[m]];
+  const mds_info_t& get_mds_info(mds_rank_t m) const {
+    assert(up.count(m) && mds_info.count(up.at(m)));
+    return mds_info.at(up.at(m));
   }
-  mds_gid_t find_mds_gid_by_name(const std::string& s) {
+  mds_gid_t find_mds_gid_by_name(const std::string& s) const {
     for (std::map<mds_gid_t,mds_info_t>::const_iterator p = mds_info.begin();
 	 p != mds_info.end();
 	 ++p) {
@@ -303,13 +314,13 @@ public:
   }
 
   // counts
-  unsigned get_num_in_mds() {
+  unsigned get_num_in_mds() const {
     return in.size();
   }
-  unsigned get_num_up_mds() {
+  unsigned get_num_up_mds() const {
     return up.size();
   }
-  int get_num_failed_mds() {
+  int get_num_failed_mds() const {
     return failed.size();
   }
   unsigned get_num_mds(int state) const {
@@ -334,22 +345,43 @@ public:
   }
 
   // sets
-  void get_mds_set(std::set<mds_rank_t>& s) {
+  void get_mds_set(std::set<mds_rank_t>& s) const {
     s = in;
   }
-  void get_up_mds_set(std::set<mds_rank_t>& s) {
+  void get_up_mds_set(std::set<mds_rank_t>& s) const {
     for (std::map<mds_rank_t, mds_gid_t>::const_iterator p = up.begin();
 	 p != up.end();
 	 ++p)
       s.insert(p->first);
   }
-  void get_active_mds_set(std::set<mds_rank_t>& s) {
+  void get_active_mds_set(std::set<mds_rank_t>& s) const {
     get_mds_set(s, MDSMap::STATE_ACTIVE);
   }
-  void get_failed_mds_set(std::set<mds_rank_t>& s) {
+  void get_failed_mds_set(std::set<mds_rank_t>& s) const {
     s = failed;
   }
 
+  // features
+  uint64_t get_up_features() {
+    if (!cached_up_features) {
+      bool first = true;
+      for (std::map<mds_rank_t, mds_gid_t>::const_iterator p = up.begin();
+	   p != up.end();
+	   ++p) {
+	std::map<mds_gid_t, mds_info_t>::const_iterator q =
+	  mds_info.find(p->second);
+	assert(q != mds_info.end());
+	if (first) {
+	  cached_up_features = q->second.mds_features;
+	  first = false;
+	} else {
+	  cached_up_features &= q->second.mds_features;
+	}
+      }
+    }
+    return cached_up_features;
+  }
+
   /**
    * Get MDS ranks which are in but not up.
    */
@@ -382,7 +414,7 @@ public:
       if (p->second.state >= STATE_CLIENTREPLAY && p->second.state <= STATE_STOPPING)
 	s.insert(p->second.rank);
   }
-  void get_mds_set(std::set<mds_rank_t>& s, DaemonState state) {
+  void get_mds_set(std::set<mds_rank_t>& s, DaemonState state) const {
     for (std::map<mds_gid_t, mds_info_t>::const_iterator p = mds_info.begin();
 	 p != mds_info.end();
 	 ++p)
@@ -390,72 +422,6 @@ public:
 	s.insert(p->second.rank);
   } 
 
-  int get_random_up_mds() {
-    if (up.empty())
-      return -1;
-    std::map<mds_rank_t, mds_gid_t>::iterator p = up.begin();
-    for (int n = rand() % up.size(); n; n--)
-      ++p;
-    return p->first;
-  }
-
-  const mds_info_t* find_by_name(const std::string& name) const {
-    for (std::map<mds_gid_t, mds_info_t>::const_iterator p = mds_info.begin();
-	 p != mds_info.end();
-	 ++p) {
-      if (p->second.name == name)
-	return &p->second;
-    }
-    return NULL;
-  }
-
-  mds_gid_t find_standby_for(mds_rank_t mds, std::string& name) const {
-    std::map<mds_gid_t, mds_info_t>::const_iterator generic_standby
-      = mds_info.end();
-    for (std::map<mds_gid_t, mds_info_t>::const_iterator p = mds_info.begin();
-	 p != mds_info.end();
-	 ++p) {
-      if ((p->second.state != MDSMap::STATE_STANDBY && p->second.state != MDSMap::STATE_STANDBY_REPLAY) ||
-	  p->second.laggy() ||
-	  p->second.rank >= 0)
-	continue;
-      if (p->second.standby_for_rank == mds || (name.length() && p->second.standby_for_name == name))
-	return p->first;
-      if (p->second.standby_for_rank < 0 && p->second.standby_for_name.length() == 0)
-	generic_standby = p;
-    }
-    if (generic_standby != mds_info.end())
-      return generic_standby->first;
-    return MDS_GID_NONE;
-  }
-
-  mds_gid_t find_unused_for(mds_rank_t mds, std::string& name,
-                            bool force_standby_active) const {
-    for (std::map<mds_gid_t,mds_info_t>::const_iterator p = mds_info.begin();
-         p != mds_info.end();
-         ++p) {
-      if (p->second.state != MDSMap::STATE_STANDBY ||
-          p->second.laggy() ||
-          p->second.rank >= 0)
-        continue;
-      if ((p->second.standby_for_rank == MDS_NO_STANDBY_PREF ||
-           p->second.standby_for_rank == MDS_MATCHED_ACTIVE ||
-           (p->second.standby_for_rank == MDS_STANDBY_ANY && force_standby_active))) {
-        return p->first;
-      }
-    }
-    return MDS_GID_NONE;
-  }
-
-  mds_gid_t find_replacement_for(mds_rank_t mds, std::string& name,
-                                 bool force_standby_active) const {
-    const mds_gid_t standby = find_standby_for(mds, name);
-    if (standby)
-      return standby;
-    else
-      return find_unused_for(mds, name, force_standby_active);
-  }
-
   void get_health(list<pair<health_status_t,std::string> >& summary,
 		  list<pair<health_status_t,std::string> > *detail) const;
 
@@ -516,8 +482,12 @@ public:
     return i->second.state;
   }
 
-  mds_info_t& get_info(mds_rank_t m) { assert(up.count(m)); return mds_info[up[m]]; }
-  mds_info_t& get_info_gid(mds_gid_t gid) { assert(mds_info.count(gid)); return mds_info[gid]; }
+  const mds_info_t& get_info(const mds_rank_t m) const {
+    return mds_info.at(up.at(m));
+  }
+  const mds_info_t& get_info_gid(const mds_gid_t gid) const {
+    return mds_info.at(gid);
+  }
 
   bool is_boot(mds_rank_t m) const { return get_state(m) == STATE_BOOT; }
   bool is_creating(mds_rank_t m) const { return get_state(m) == STATE_CREATING; }
@@ -552,12 +522,9 @@ public:
     return p->second.laggy();
   }
 
-
-  // cluster states
-  bool is_full() const {
-    return mds_rank_t(in.size()) >= max_mds;
-  }
-  bool is_degraded() const {   // degraded = some recovery in process.  fixes active membership and recovery_set.
+  // degraded = some recovery in process.  fixes active membership and
+  // recovery_set.
+  bool is_degraded() const {
     if (!failed.empty() || !damaged.empty())
       return true;
     for (std::map<mds_gid_t,mds_info_t>::const_iterator p = mds_info.begin();
@@ -626,17 +593,14 @@ public:
     return false;
   }
   
-  mds_rank_t get_rank_gid(mds_gid_t gid) {
-    if (mds_info.count(gid))
-      return mds_info[gid].rank;
-    return MDS_RANK_NONE;
+  mds_rank_t get_rank_gid(mds_gid_t gid) const {
+    if (mds_info.count(gid)) {
+      return mds_info.at(gid).rank;
+    } else {
+      return MDS_RANK_NONE;
+    }
   }
 
-  int get_inc(mds_rank_t m) {
-    if (up.count(m)) 
-      return mds_info[up[m]].inc;
-    return 0;
-  }
   int get_inc_gid(mds_gid_t gid) {
     if (mds_info.count(gid))
       return mds_info[gid].inc;
@@ -650,8 +614,8 @@ public:
   }
 
 
-  void print(ostream& out);
-  void print_summary(Formatter *f, ostream *out);
+  void print(ostream& out) const;
+  void print_summary(Formatter *f, ostream *out) const;
 
   void dump(Formatter *f) const;
   static void generate_test_instances(list<MDSMap*>& ls);
diff --git a/src/mds/MDSRank.cc b/src/mds/MDSRank.cc
index 44d6e3d..1647c70 100644
--- a/src/mds/MDSRank.cc
+++ b/src/mds/MDSRank.cc
@@ -56,6 +56,7 @@ MDSRank::MDSRank(
     objecter(objecter_),
     server(NULL), mdcache(NULL), locker(NULL), mdlog(NULL),
     balancer(NULL), scrubstack(NULL),
+    damage_table(whoami_),
     inotable(NULL), snapserver(NULL), snapclient(NULL),
     sessionmap(this), logger(NULL), mlogger(NULL),
     op_tracker(g_ceph_context, g_conf->mds_enable_op_tracker,
@@ -1734,8 +1735,10 @@ bool MDSRankDispatcher::handle_asok_command(
     }
   } else if (command == "scrub_path") {
     string path;
+    vector<string> scrubop_vec;
+    cmd_getval(g_ceph_context, cmdmap, "scrubops", scrubop_vec);
     cmd_getval(g_ceph_context, cmdmap, "path", path);
-    command_scrub_path(f, path);
+    command_scrub_path(f, path, scrubop_vec);
   } else if (command == "tag path") {
     string path;
     cmd_getval(g_ceph_context, cmdmap, "path", path);
@@ -1874,12 +1877,23 @@ void MDSRankDispatcher::dump_sessions(const SessionFilter &filter, Formatter *f)
   f->close_section(); //sessions
 }
 
-void MDSRank::command_scrub_path(Formatter *f, const string& path)
+void MDSRank::command_scrub_path(Formatter *f, const string& path, vector<string>& scrubop_vec)
 {
+  bool force = false;
+  bool recursive = false;
+  bool repair = false;
+  for (vector<string>::iterator i = scrubop_vec.begin() ; i != scrubop_vec.end(); ++i) {
+    if (*i == "force")
+      force = true;
+    else if (*i == "recursive")
+      recursive = true;
+    else if (*i == "repair")
+      repair = true;
+  }
   C_SaferCond scond;
   {
     Mutex::Locker l(mds_lock);
-    mdcache->scrub_dentry(path, f, &scond);
+    mdcache->enqueue_scrub(path, "", force, recursive, repair, f, &scond);
   }
   scond.wait();
   // scrub_dentry() finishers will dump the data for us; we're done!
@@ -1891,7 +1905,7 @@ void MDSRank::command_tag_path(Formatter *f,
   C_SaferCond scond;
   {
     Mutex::Locker l(mds_lock);
-    mdcache->enqueue_scrub(path, tag, f, &scond);
+    mdcache->enqueue_scrub(path, tag, true, true, false, f, &scond);
   }
   scond.wait();
 }
@@ -2570,6 +2584,22 @@ bool MDSRankDispatcher::handle_command(
     evict_sessions(filter);
 
     return true;
+  } else if (prefix == "damage ls") {
+    Formatter *f = new JSONFormatter();
+    damage_table.dump(f);
+    f->flush(*ds);
+    delete f;
+    return true;
+  } else if (prefix == "damage rm") {
+    damage_entry_id_t id = 0;
+    bool got = cmd_getval(g_ceph_context, cmdmap, "damage_id", (int64_t&)id);
+    if (!got) {
+      *r = -EINVAL;
+      return true;
+    }
+
+    damage_table.erase(id);
+    return true;
   } else {
     return false;
   }
diff --git a/src/mds/MDSRank.h b/src/mds/MDSRank.h
index a11f3b9..4da260d 100644
--- a/src/mds/MDSRank.h
+++ b/src/mds/MDSRank.h
@@ -20,6 +20,7 @@
 #include "common/Timer.h"
 
 #include "Beacon.h"
+#include "DamageTable.h"
 #include "MDSMap.h"
 #include "SessionMap.h"
 #include "MDCache.h"
@@ -153,6 +154,7 @@ class MDSRank {
     MDLog        *mdlog;
     MDBalancer   *balancer;
     ScrubStack   *scrubstack;
+    DamageTable  damage_table;
 
     InoTable     *inotable;
 
@@ -364,7 +366,7 @@ class MDSRank {
 
   protected:
     void dump_clientreplay_status(Formatter *f) const;
-    void command_scrub_path(Formatter *f, const string& path);
+    void command_scrub_path(Formatter *f, const string& path, vector<string>& scrubop_vec);
     void command_tag_path(Formatter *f, const string& path,
                           const string &tag);
     void command_flush_path(Formatter *f, const string& path);
diff --git a/src/mds/Makefile-server.am b/src/mds/Makefile-server.am
index 951bb89..97378a2 100644
--- a/src/mds/Makefile-server.am
+++ b/src/mds/Makefile-server.am
@@ -12,6 +12,7 @@ noinst_HEADERS += \
 	mds/CDentry.h \
 	mds/CDir.h \
 	mds/CInode.h \
+	mds/DamageTable.h \
 	mds/Capability.h \
 	mds/InoTable.h \
 	mds/JournalPointer.h \
@@ -30,6 +31,7 @@ noinst_HEADERS += \
 	mds/MDSContext.h \
 	mds/MDSAuthCaps.h \
 	mds/MDSMap.h \
+	mds/FSMap.h \
 	mds/MDSTable.h \
 	mds/MDSTableServer.h \
 	mds/MDSTableClient.h \
diff --git a/src/mds/Makefile.am b/src/mds/Makefile.am
index f3904e1..b7f7e79 100644
--- a/src/mds/Makefile.am
+++ b/src/mds/Makefile.am
@@ -16,6 +16,7 @@ LIBMDS_SOURCES = \
 	mds/CDentry.cc \
 	mds/CDir.cc \
 	mds/CInode.cc \
+	mds/DamageTable.cc \
 	mds/LogEvent.cc \
 	mds/MDSTable.cc \
 	mds/InoTable.cc \
diff --git a/src/mds/Migrator.cc b/src/mds/Migrator.cc
index 4dce94f..3bf7ce2 100644
--- a/src/mds/Migrator.cc
+++ b/src/mds/Migrator.cc
@@ -1019,7 +1019,8 @@ void Migrator::export_frozen(CDir *dir, uint64_t tid)
       bufferlist bl;
       cache->replicate_dentry(cur->inode->parent, it->second.peer, bl);
       dout(7) << "  added " << *cur->inode->parent << dendl;
-      cache->replicate_inode(cur->inode, it->second.peer, bl);
+      cache->replicate_inode(cur->inode, it->second.peer, bl,
+			     mds->mdsmap->get_up_features());
       dout(7) << "  added " << *cur->inode << dendl;
       bl.claim_append(tracebl);
       tracebl.claim(bl);
diff --git a/src/mds/ScrubHeader.h b/src/mds/ScrubHeader.h
index 288f3a3..72231b5 100644
--- a/src/mds/ScrubHeader.h
+++ b/src/mds/ScrubHeader.h
@@ -2,7 +2,7 @@
 #ifndef SCRUB_HEADER_H_
 #define SCRUB_HEADER_H_
 
-class CDentry;
+class CInode;
 
 /**
  * Externally input parameters for a scrub, associated with the root
@@ -13,8 +13,13 @@ class CDentry;
  */
 class ScrubHeader {
 public:
+  CInode *origin;
   std::string tag;
-  CDentry *origin;
+
+  bool force;
+  bool recursive;
+  bool repair;
+  Formatter *formatter;
 };
 typedef ceph::shared_ptr<ScrubHeader> ScrubHeaderRef;
 typedef ceph::shared_ptr<const ScrubHeader> ScrubHeaderRefConst;
diff --git a/src/mds/ScrubStack.cc b/src/mds/ScrubStack.cc
index 0d99beb..1eaddf6 100644
--- a/src/mds/ScrubStack.cc
+++ b/src/mds/ScrubStack.cc
@@ -27,56 +27,54 @@ static ostream& _prefix(std::ostream *_dout, MDSRank *mds) {
   return *_dout << "mds." << mds->get_nodeid() << ".scrubstack ";
 }
 
-void ScrubStack::push_dentry(CDentry *dentry)
+void ScrubStack::push_inode(CInode *in)
 {
-  dout(20) << "pushing " << *dentry << " on top of ScrubStack" << dendl;
-  if (!dentry->item_scrub.is_on_list()) {
-    dentry->get(CDentry::PIN_SCRUBQUEUE);
+  dout(20) << "pushing " << *in << " on top of ScrubStack" << dendl;
+  if (!in->item_scrub.is_on_list()) {
+    in->get(CInode::PIN_SCRUBQUEUE);
     stack_size++;
   }
-  dentry_stack.push_front(&dentry->item_scrub);
+  inode_stack.push_front(&in->item_scrub);
 }
 
-void ScrubStack::push_dentry_bottom(CDentry *dentry)
+void ScrubStack::push_inode_bottom(CInode *in)
 {
-  dout(20) << "pushing " << *dentry << " on bottom of ScrubStack" << dendl;
-  if (!dentry->item_scrub.is_on_list()) {
-    dentry->get(CDentry::PIN_SCRUBQUEUE);
+  dout(20) << "pushing " << *in << " on bottom of ScrubStack" << dendl;
+  if (!in->item_scrub.is_on_list()) {
+    in->get(CInode::PIN_SCRUBQUEUE);
     stack_size++;
   }
-  dentry_stack.push_back(&dentry->item_scrub);
+  inode_stack.push_back(&in->item_scrub);
 }
 
-void ScrubStack::pop_dentry(CDentry *dn)
+void ScrubStack::pop_inode(CInode *in)
 {
-  dout(20) << "popping " << *dn
+  dout(20) << "popping " << *in
           << " off of ScrubStack" << dendl;
-  assert(dn->item_scrub.is_on_list());
-  dn->put(CDentry::PIN_SCRUBQUEUE);
-  dn->item_scrub.remove_myself();
+  assert(in->item_scrub.is_on_list());
+  in->put(CInode::PIN_SCRUBQUEUE);
+  in->item_scrub.remove_myself();
   stack_size--;
 }
 
-void ScrubStack::_enqueue_dentry(CDentry *dn, CDir *parent, bool recursive,
-    bool children, ScrubHeaderRefConst header,
-    MDSInternalContextBase *on_finish, bool top)
+void ScrubStack::_enqueue_inode(CInode *in, CDentry *parent,
+				const ScrubHeaderRefConst& header,
+				MDSInternalContextBase *on_finish, bool top)
 {
-  dout(10) << __func__ << " with {" << *dn << "}"
-           << ", recursive=" << recursive << ", children=" << children
+  dout(10) << __func__ << " with {" << *in << "}"
            << ", on_finish=" << on_finish << ", top=" << top << dendl;
   assert(mdcache->mds->mds_lock.is_locked_by_me());
-  dn->scrub_initialize(parent, recursive, children, header, on_finish);
+  in->scrub_initialize(parent, header, on_finish);
   if (top)
-    push_dentry(dn);
+    push_inode(in);
   else
-    push_dentry_bottom(dn);
+    push_inode_bottom(in);
 }
 
-void ScrubStack::enqueue_dentry(CDentry *dn, bool recursive, bool children,
-                                ScrubHeaderRefConst header,
-                                 MDSInternalContextBase *on_finish, bool top)
+void ScrubStack::enqueue_inode(CInode *in, const ScrubHeaderRefConst& header,
+                               MDSInternalContextBase *on_finish, bool top)
 {
-  _enqueue_dentry(dn, NULL, recursive, children, header, on_finish, top);
+  _enqueue_inode(in, NULL, header, on_finish, top);
   kick_off_scrubs();
 }
 
@@ -85,47 +83,36 @@ void ScrubStack::kick_off_scrubs()
   dout(20) << __func__ << " entering with " << scrubs_in_progress << " in "
               "progress and " << stack_size << " in the stack" << dendl;
   bool can_continue = true;
-  elist<CDentry*>::iterator i = dentry_stack.begin();
+  elist<CInode*>::iterator i = inode_stack.begin();
   while (g_conf->mds_max_scrub_ops_in_progress > scrubs_in_progress &&
       can_continue && !i.end()) {
-    CDentry *cur = *i;
-
-    dout(20) << __func__ << " examining dentry " << *cur << dendl;
-
-    CInode *curi = cur->get_projected_inode();
+    CInode *curi = *i;
     ++i; // we have our reference, push iterator forward
 
+    dout(20) << __func__ << " examining " << *curi << dendl;
+
     if (!curi->is_dir()) {
       // it's a regular file, symlink, or hard link
-      pop_dentry(cur); // we only touch it this once, so remove from stack
+      pop_inode(curi); // we only touch it this once, so remove from stack
 
-      if (curi->is_file()) {
-	if (!cur->scrub_info()->on_finish) {
-	  scrubs_in_progress++;
-	  cur->scrub_set_finisher(&scrub_kick);
-	}
-        scrub_file_dentry(cur);
-        can_continue = true;
-      } else {
-        // drat, we don't do anything with these yet :(
-        dout(5) << "skipping scrub on non-dir, non-file dentry "
-                << *cur << dendl;
-	Context *c = NULL;
-	cur->scrub_finished(&c);
-	assert(c == NULL);
+      if (!curi->scrub_info()->on_finish) {
+	scrubs_in_progress++;
+	curi->scrub_set_finisher(&scrub_kick);
       }
+      scrub_file_inode(curi);
+      can_continue = true;
     } else {
       bool completed; // it's done, so pop it off the stack
       bool terminal; // not done, but we can start ops on other directories
       bool progress; // it added new dentries to the top of the stack
-      scrub_dir_dentry(cur, &progress, &terminal, &completed);
+      scrub_dir_inode(curi, &progress, &terminal, &completed);
       if (completed) {
         dout(20) << __func__ << " dir completed" << dendl;
-        pop_dentry(cur);
+        pop_inode(curi);
       } else if (progress) {
         dout(20) << __func__ << " dir progressed" << dendl;
         // we added new stuff to top of stack, so reset ourselves there
-        i = dentry_stack.begin();
+        i = inode_stack.begin();
       } else {
         dout(20) << __func__ << " dir no-op" << dendl;
       }
@@ -135,110 +122,89 @@ void ScrubStack::kick_off_scrubs()
   }
 }
 
-void ScrubStack::scrub_dir_dentry(CDentry *dn,
-                                  bool *added_children,
-                                  bool *terminal,
-                                  bool *done)
+void ScrubStack::scrub_dir_inode(CInode *in,
+                                 bool *added_children,
+                                 bool *terminal,
+                                 bool *done)
 {
-  assert(dn != NULL);
-  dout(10) << __func__ << *dn << dendl;
-
-  if (!dn->scrub_info()->scrub_children &&
-      !dn->scrub_info()->scrub_recursive) {
-    // TODO: we have to scrub the local dentry/inode, but nothing else
-  }
+  dout(10) << __func__ << *in << dendl;
 
   *added_children = false;
-  *terminal = false;
-  *done = false;
-
-  CInode *in = dn->get_projected_inode();
-  // FIXME: greg -- is get_version the appropriate version?  (i.e. is scrub_version
-  // meant to be an actual version that we're scrubbing, or something else?)
-  if (!in->scrub_info()->scrub_in_progress) {
-    // We may come through here more than once on our way up and down
-    // the stack... or actually is that right?  Should we perhaps
-    // only see ourselves once on the way down and once on the way
-    // back up again, and not do this?
-    in->scrub_initialize(in->get_version());
-  }
-
-  list<frag_t> scrubbing_frags;
-  list<CDir*> scrubbing_cdirs;
-  in->scrub_dirfrags_scrubbing(&scrubbing_frags);
-  dout(20) << __func__ << " iterating over " << scrubbing_frags.size()
-    << " scrubbing frags" << dendl;
-  for (list<frag_t>::iterator i = scrubbing_frags.begin();
-      i != scrubbing_frags.end();
-      ++i) {
-    // turn frags into CDir *
-    CDir *dir = in->get_dirfrag(*i);
-    scrubbing_cdirs.push_back(dir);
-    dout(25) << __func__ << " got CDir " << *dir << " presently scrubbing" << dendl;
-  }
+  bool all_frags_terminal = true;
+  bool all_frags_done = true;
 
+  const ScrubHeaderRefConst& header = in->scrub_info()->header;
+
+  if (header->recursive) {
+    list<frag_t> scrubbing_frags;
+    list<CDir*> scrubbing_cdirs;
+    in->scrub_dirfrags_scrubbing(&scrubbing_frags);
+    dout(20) << __func__ << " iterating over " << scrubbing_frags.size()
+      << " scrubbing frags" << dendl;
+    for (list<frag_t>::iterator i = scrubbing_frags.begin();
+	i != scrubbing_frags.end();
+	++i) {
+      // turn frags into CDir *
+      CDir *dir = in->get_dirfrag(*i);
+      scrubbing_cdirs.push_back(dir);
+      dout(25) << __func__ << " got CDir " << *dir << " presently scrubbing" << dendl;
+    }
 
-  dout(20) << __func__ << " consuming from " << scrubbing_cdirs.size()
-    << " scrubbing cdirs" << dendl;
 
-  list<CDir*>::iterator i = scrubbing_cdirs.begin();
-  bool all_frags_terminal = true;
-  bool all_frags_done = true;
-  while (g_conf->mds_max_scrub_ops_in_progress > scrubs_in_progress) {
-    // select next CDir
-    CDir *cur_dir = NULL;
-    if (i != scrubbing_cdirs.end()) {
-      cur_dir = *i;
-      ++i;
-      dout(20) << __func__ << " got cur_dir = " << *cur_dir << dendl;
-    } else {
-      bool ready = get_next_cdir(in, &cur_dir);
-      dout(20) << __func__ << " get_next_cdir ready=" << ready << dendl;
-      if (cur_dir) {
-        cur_dir->scrub_initialize();
-      }
+    dout(20) << __func__ << " consuming from " << scrubbing_cdirs.size()
+	     << " scrubbing cdirs" << dendl;
 
-      if (ready && cur_dir) {
-        scrubbing_cdirs.push_back(cur_dir);
-      } else if (!ready) {
-        // We are waiting for load of a frag
-        all_frags_done = false;
-        all_frags_terminal = false;
-        break;
+    list<CDir*>::iterator i = scrubbing_cdirs.begin();
+    while (g_conf->mds_max_scrub_ops_in_progress > scrubs_in_progress) {
+      // select next CDir
+      CDir *cur_dir = NULL;
+      if (i != scrubbing_cdirs.end()) {
+	cur_dir = *i;
+	++i;
+	dout(20) << __func__ << " got cur_dir = " << *cur_dir << dendl;
       } else {
-        // Finished with all frags
-        break;
+	bool ready = get_next_cdir(in, &cur_dir);
+	dout(20) << __func__ << " get_next_cdir ready=" << ready << dendl;
+
+	if (ready && cur_dir) {
+	  scrubbing_cdirs.push_back(cur_dir);
+	} else if (!ready) {
+	  // We are waiting for load of a frag
+	  all_frags_done = false;
+	  all_frags_terminal = false;
+	  break;
+	} else {
+	  // Finished with all frags
+	  break;
+	}
       }
+      // scrub that CDir
+      bool frag_added_children = false;
+      bool frag_terminal = true;
+      bool frag_done = false;
+      scrub_dirfrag(cur_dir, header,
+		    &frag_added_children, &frag_terminal, &frag_done);
+      if (frag_done) {
+	cur_dir->inode->scrub_dirfrag_finished(cur_dir->frag);
+      }
+      *added_children |= frag_added_children;
+      all_frags_terminal = all_frags_terminal && frag_terminal;
+      all_frags_done = all_frags_done && frag_done;
     }
-    // scrub that CDir
-    bool frag_added_children = false;
-    bool frag_terminal = true;
-    bool frag_done = false;
-    scrub_dirfrag(cur_dir, &frag_added_children, &frag_terminal, &frag_done);
-    if (frag_done) {
-      // FIXME is this right?  Can we end up hitting this more than
-      // once and is that a problem?
-      cur_dir->inode->scrub_dirfrag_finished(cur_dir->frag);
-    }
-    *added_children |= frag_added_children;
-    all_frags_terminal = all_frags_terminal && frag_terminal;
-    all_frags_done = all_frags_done && frag_done;
+
+    dout(20) << "finished looping; all_frags_terminal=" << all_frags_terminal
+	     << ", all_frags_done=" << all_frags_done << dendl;
+  } else {
+    dout(20) << "!scrub_recursive" << dendl;
   }
 
-  dout(20) << "finished looping; all_frags_terminal=" << all_frags_terminal
-           << ", all_frags_done=" << all_frags_done << dendl;
   if (all_frags_done) {
     assert (!*added_children); // can't do this if children are still pending
 
-    if (!dn->scrub_info()->on_finish) {
-      scrubs_in_progress++;
-      dn->scrub_set_finisher(&scrub_kick);
-    }
-
     // OK, so now I can... fire off a validate on the dir inode, and
     // when it completes, come through here again, noticing that we've
     // set a flag to indicate the the validate happened, and 
-    scrub_dir_dentry_final(dn);
+    scrub_dir_inode_final(in);
   }
 
   *terminal = all_frags_terminal;
@@ -279,9 +245,9 @@ class C_InodeValidated : public MDSInternalContext
   public:
     ScrubStack *stack;
     CInode::validated_data result;
-    CDentry *target;
+    CInode *target;
 
-    C_InodeValidated(MDSRank *mds, ScrubStack *stack_, CDentry *target_)
+    C_InodeValidated(MDSRank *mds, ScrubStack *stack_, CInode *target_)
       : MDSInternalContext(mds), stack(stack_), target(target_)
     {}
 
@@ -292,9 +258,9 @@ class C_InodeValidated : public MDSInternalContext
 };
 
 
-void ScrubStack::scrub_dir_dentry_final(CDentry *dn)
+void ScrubStack::scrub_dir_inode_final(CInode *in)
 {
-  dout(20) << __func__ << *dn << dendl;
+  dout(20) << __func__ << *in << dendl;
 
   // Two passes through this function.  First one triggers inode validation,
   // second one sets finally_done
@@ -303,19 +269,24 @@ void ScrubStack::scrub_dir_dentry_final(CDentry *dn)
   // doing our validate_disk_state on the inode
   // FIXME: the magic-constructing scrub_info() is going to leave
   // an unneeded scrub_infop lying around here
-  if (!dn->scrub_info()->dentry_children_done) {
-    dn->scrub_children_finished();
-    CInode *in = dn->get_projected_inode();
-    C_InodeValidated *fin = new C_InodeValidated(mdcache->mds, this, dn);
-    MDRequestRef null_mdr;
-    in->validate_disk_state(&fin->result, null_mdr, fin);
+  if (!in->scrub_info()->children_scrubbed) {
+    if (!in->scrub_info()->on_finish) {
+      scrubs_in_progress++;
+      in->scrub_set_finisher(&scrub_kick);
+    }
+
+    in->scrub_children_finished();
+    C_InodeValidated *fin = new C_InodeValidated(mdcache->mds, this, in);
+    in->validate_disk_state(&fin->result, fin);
   }
 
   return;
 }
 
-void ScrubStack::scrub_dirfrag(CDir *dir, bool *added_children,
-                               bool *is_terminal, bool *done)
+void ScrubStack::scrub_dirfrag(CDir *dir,
+			       const ScrubHeaderRefConst& header,
+			       bool *added_children, bool *is_terminal,
+			       bool *done)
 {
   assert(dir != NULL);
 
@@ -324,6 +295,7 @@ void ScrubStack::scrub_dirfrag(CDir *dir, bool *added_children,
   *is_terminal = false;
   *done = false;
 
+
   if (!dir->scrub_info()->directory_scrubbing) {
     // Get the frag complete before calling
     // scrub initialize, so that it can populate its lists
@@ -334,7 +306,7 @@ void ScrubStack::scrub_dirfrag(CDir *dir, bool *added_children,
       return;
     }
 
-    dir->scrub_initialize();
+    dir->scrub_initialize(header);
   }
 
   int r = 0;
@@ -343,8 +315,6 @@ void ScrubStack::scrub_dirfrag(CDir *dir, bool *added_children,
     scrubs_in_progress++;
     r = dir->scrub_dentry_next(&scrub_kick, &dn);
     if (r != EAGAIN) {
-      // ctx only used by scrub_dentry_next in EAGAIN case
-      // FIXME It's kind of annoying to keep allocating and deleting a ctx here
       scrubs_in_progress--;
     }
 
@@ -386,57 +356,44 @@ void ScrubStack::scrub_dirfrag(CDir *dir, bool *added_children,
     // never get random IO errors here.
     assert(r == 0);
 
-    CDentry *parent_dn = dir->get_inode()->get_parent_dn();
-    ScrubHeaderRefConst header = parent_dn->scrub_info()->header;
-
-    // FIXME: Do I *really* need to construct a kick context for every
-    // single dentry I'm going to scrub?
-    _enqueue_dentry(dn,
-        dir,
-        parent_dn->scrub_info()->scrub_recursive,
-        false,  // We are already recursing so scrub_children not meaningful
-        header,
-	NULL,
-        true);
+    _enqueue_inode(dn->get_projected_inode(), dn, header, NULL, true);
 
     *added_children = true;
   }
 }
 
-void ScrubStack::scrub_file_dentry(CDentry *dn)
+void ScrubStack::scrub_file_inode(CInode *in)
 {
-  assert(dn->get_linkage()->get_inode() != NULL);
-
-  CInode *in = dn->get_projected_inode();
-  C_InodeValidated *fin = new C_InodeValidated(mdcache->mds, this, dn);
-
+  C_InodeValidated *fin = new C_InodeValidated(mdcache->mds, this, in);
   // At this stage the DN is already past scrub_initialize, so
   // it's in the cache, it has PIN_SCRUBQUEUE and it is authpinned
-  MDRequestRef null_mdr;
-  in->validate_disk_state(&fin->result, null_mdr, fin);
+  in->validate_disk_state(&fin->result, fin);
 }
 
-void ScrubStack::_validate_inode_done(CDentry *dn, int r,
-    const CInode::validated_data &result)
+void ScrubStack::_validate_inode_done(CInode *in, int r,
+				      const CInode::validated_data &result)
 {
   // FIXME: do something real with result!  DamageTable!  Spamming
   // the cluster log for debugging purposes
   LogChannelRef clog = mdcache->mds->clog;
-  clog->info() << __func__ << " " << *dn << " r=" << r;
+  clog->info() << __func__ << " " << *in << " r=" << r;
 #if 0
-  assert(dn->scrub_info_p != NULL);
-  dn->scrub_info_p->inode_validated = true;
+  assert(in->scrub_infop != NULL);
+  in->scrub_infop->inode_validated = true;
 #endif
-
-  Context *c = NULL;
-  CInode *in = dn->get_projected_inode();
-  if (in->is_dir()) {
-    // For directories, inodes undergo a scrub_init/scrub_finish cycle
-    in->scrub_finished(&c);
-  } else {
-    // For regular files, we never touch the scrub_info on the inode,
-    // just the dentry.
-    dn->scrub_finished(&c);
+  const ScrubHeaderRefConst header = in->scrub_info()->header;
+
+  MDSInternalContextBase *c = NULL;
+  in->scrub_finished(&c);
+
+  if (!header->recursive && in == header->origin) {
+    if (r >= 0) { // we got into the scrubbing dump it
+      result.dump(header->formatter);
+    } else { // we failed the lookup or something; dump ourselves
+      header->formatter->open_object_section("results");
+      header->formatter->dump_int("return_code", r);
+      header->formatter->close_section(); // results
+    }
   }
   if (c) {
     finisher->queue(new MDSIOContextWrapper(mdcache->mds, c), 0);
diff --git a/src/mds/ScrubStack.h b/src/mds/ScrubStack.h
index b01ee84..d12b847 100644
--- a/src/mds/ScrubStack.h
+++ b/src/mds/ScrubStack.h
@@ -32,7 +32,7 @@ protected:
   Finisher *finisher;
 
   /// The stack of dentries we want to scrub
-  elist<CDentry*> dentry_stack;
+  elist<CInode*> inode_stack;
   /// current number of dentries we're actually scrubbing
   int scrubs_in_progress;
   ScrubStack *scrubstack; // hack for dout
@@ -55,88 +55,77 @@ public:
   MDCache *mdcache;
   ScrubStack(MDCache *mdc, Finisher *finisher_) :
     finisher(finisher_),
-    dentry_stack(member_offset(CDentry, item_scrub)),
+    inode_stack(member_offset(CInode, item_scrub)),
     scrubs_in_progress(0),
     scrubstack(this),
     stack_size(0),
     scrub_kick(mdc, this),
     mdcache(mdc) {}
   ~ScrubStack() {
-    assert(dentry_stack.empty());
+    assert(inode_stack.empty());
     assert(!scrubs_in_progress);
   }
   /**
-   * Put a dentry on the top of the scrub stack, so it is the highest priority.
+   * Put a inode on the top of the scrub stack, so it is the highest priority.
    * If there are other scrubs in progress, they will not continue scrubbing new
    * entries until this one is completed.
-   * @param dn The dentry to scrub
-   * @param recursive True if we want to recursively scrub the
-   * entire hierarchy under dn.
-   * @param children True if we want to scrub the direct children of
-   * dn but aren't doing a recursive scrub. (Otherwise, all checks are
-   * local to dn's disk state.)
+   * @param in The inodey to scrub
    * @param header The ScrubHeader propagated from whereever this scrub
    *               was initiated
    */
-  void enqueue_dentry_top(CDentry *dn, bool recursive, bool children,
-                          ScrubHeaderRefConst header,
-                          MDSInternalContextBase *on_finish) {
-    enqueue_dentry(dn, recursive, children, header, on_finish, true);
+  void enqueue_inode_top(CInode *in, const ScrubHeaderRefConst& header,
+			 MDSInternalContextBase *on_finish) {
+    enqueue_inode(in, header, on_finish, true);
   }
-  /** Like enqueue_dentry_top, but we wait for all pending scrubs before
+  /** Like enqueue_inode_top, but we wait for all pending scrubs before
    * starting this one.
    */
-  void enqueue_dentry_bottom(CDentry *dn, bool recursive, bool children,
-                             ScrubHeaderRefConst header,
-                             MDSInternalContextBase *on_finish) {
-    enqueue_dentry(dn, recursive, children, header, on_finish, false);
+  void enqueue_inode_bottom(CInode *in, const ScrubHeaderRefConst& header,
+			    MDSInternalContextBase *on_finish) {
+    enqueue_inode(in, header, on_finish, false);
   }
 
 private:
   /**
-   * Put the dentry at either the top or bottom of the stack, with
+   * Put the inode at either the top or bottom of the stack, with
    * the given scrub params, and then try and kick off more scrubbing.
    */
-  void enqueue_dentry(CDentry *dn, bool recursive, bool children,
-                      ScrubHeaderRefConst header,
+  void enqueue_inode(CInode *in, const ScrubHeaderRefConst& header,
+                      MDSInternalContextBase *on_finish, bool top);
+  void _enqueue_inode(CInode *in, CDentry *parent, const ScrubHeaderRefConst& header,
                       MDSInternalContextBase *on_finish, bool top);
-  void _enqueue_dentry(CDentry *dn, CDir *parent, bool recursive, bool children,
-                      ScrubHeaderRefConst header,
-                       MDSInternalContextBase *on_finish, bool top);
   /**
    * Kick off as many scrubs as are appropriate, based on the current
    * state of the stack.
    */
   void kick_off_scrubs();
   /**
-   * Push a dentry on top of the stack.
+   * Push a indoe on top of the stack.
    */
-  inline void push_dentry(CDentry *dentry);
+  inline void push_inode(CInode *in);
   /**
-   * Push a dentry to the bottom of the stack.
+   * Push a inode to the bottom of the stack.
    */
-  inline void push_dentry_bottom(CDentry *dentry);
+  inline void push_inode_bottom(CInode *in);
   /**
-   * Pop the given dentry off the stack.
+   * Pop the given inode off the stack.
    */
-  inline void pop_dentry(CDentry *dn);
+  inline void pop_inode(CInode *in);
 
   /**
-   * Scrub a file-representing dentry.
-   * @param dn The dentry to scrub
-   * @param progress Out pointer to a bool, which will be set to true.
-   * @pre dn->get_projected_inode()->is_file()==true;
+   * Scrub a file inode.
+   * @param in The indoe to scrub
    */
-  void scrub_file_dentry(CDentry *dn);
+  void scrub_file_inode(CInode *in);
 
   /**
    * Callback from completion of CInode::validate_disk_state
-   * @param dn The dentry owning the inode we were validating
+   * @param in The inode we were validating
    * @param r The return status from validate_disk_state
    * @param result Populated results from validate_disk_state
    */
-  void _validate_inode_done(CDentry *dn, int r,
-    const CInode::validated_data &result);
+  void _validate_inode_done(CInode *in, int r,
+			    const CInode::validated_data &result);
   friend class C_InodeValidated;
 
   /**
@@ -152,15 +141,15 @@ private:
    *
    * 4) If all dirfrags have been scrubbed, scrub my inode.
    *
-   * @param dn The CDentry to scrub as a directory
+   * @param in The CInode to scrub as a directory
    * @param added_dentries set to true if we pushed some of our children
    * onto the ScrubStack
    * @param is_terminal set to true if there are no descendant dentries
    * remaining to start scrubbing.
    * @param done set to true if we and all our children have finished scrubbing
    */
-  void scrub_dir_dentry(CDentry *dn, bool *added_children, bool *is_terminal,
-                        bool *done);
+  void scrub_dir_inode(CInode *in, bool *added_children, bool *is_terminal,
+                       bool *done);
   /**
    * Make progress on scrubbing a dirfrag. It may return after each of the
    * following steps, but will report making progress on each one.
@@ -175,14 +164,14 @@ private:
    * progress. Try again later.
    *
    */
-  void scrub_dirfrag(CDir *dir, bool *added_children, bool *is_terminal,
-		     bool *done);
+  void scrub_dirfrag(CDir *dir, const ScrubHeaderRefConst& header,
+		     bool *added_children, bool *is_terminal, bool *done);
   /**
    * Scrub a directory-representing dentry.
    *
-   * @param dn The CDentry of the directory we're doing final scrub on.
+   * @param in The directory inode we're doing final scrub on.
    */
-  void scrub_dir_dentry_final(CDentry *dn);
+  void scrub_dir_inode_final(CInode *in);
 
   /**
    * Get a CDir into memory, and return it if it's already complete.
diff --git a/src/mds/Server.cc b/src/mds/Server.cc
index b9f5b0c..ee2af10 100644
--- a/src/mds/Server.cc
+++ b/src/mds/Server.cc
@@ -2132,14 +2132,17 @@ void Server::handle_slave_auth_pin_ack(MDRequestRef& mdr, MMDSSlaveRequest *ack)
  */
 bool Server::check_access(MDRequestRef& mdr, CInode *in, unsigned mask)
 {
- if (mdr->session && !mdr->session->check_access(
-       in, mask,
-       mdr->client_request->get_caller_uid(),
-       mdr->client_request->get_caller_gid(),
-       mdr->client_request->head.args.setattr.uid,
-       mdr->client_request->head.args.setattr.gid)) {
-    respond_to_request(mdr, -EACCES);
-    return false;
+  if (mdr->session) {
+    int r = mdr->session->check_access(
+      in, mask,
+      mdr->client_request->get_caller_uid(),
+      mdr->client_request->get_caller_gid(),
+      mdr->client_request->head.args.setattr.uid,
+      mdr->client_request->head.args.setattr.gid);
+    if (r < 0) {
+      respond_to_request(mdr, r);
+      return false;
+    }
   }
   return true;
 }
@@ -2248,7 +2251,7 @@ CDentry* Server::prepare_stray_dentry(MDRequestRef& mdr, CInode *in)
  * create a new inode.  set c/m/atime.  hit dir pop.
  */
 CInode* Server::prepare_new_inode(MDRequestRef& mdr, CDir *dir, inodeno_t useino, unsigned mode,
-				  ceph_file_layout *layout) 
+				  file_layout_t *layout)
 {
   CInode *in = new CInode(mdcache);
   
@@ -2294,7 +2297,6 @@ CInode* Server::prepare_new_inode(MDRequestRef& mdr, CDir *dir, inodeno_t useino
   memset(&in->inode.dir_layout, 0, sizeof(in->inode.dir_layout));
   if (in->inode.is_dir()) {
     in->inode.dir_layout.dl_dir_hash = g_conf->mds_default_dir_hash;
-    memset(&in->inode.layout, 0, sizeof(in->inode.layout));
   } else if (layout) {
     in->inode.layout = *layout;
   } else {
@@ -2435,7 +2437,7 @@ CInode* Server::rdlock_path_pin_ref(MDRequestRef& mdr, int n,
 				    bool want_auth,
 				    bool no_want_auth, /* for readdir, who doesn't want auth _even_if_ it's
 							  a snapped dir */
-				    ceph_file_layout **layout,
+				    file_layout_t **layout,
 				    bool no_lookup)    // true if we cannot return a null dentry lease
 {
   const filepath& refpath = n ? mdr->get_filepath2() : mdr->get_filepath();
@@ -2530,7 +2532,7 @@ CInode* Server::rdlock_path_pin_ref(MDRequestRef& mdr, int n,
 CDentry* Server::rdlock_path_xlock_dentry(MDRequestRef& mdr, int n,
 					  set<SimpleLock*>& rdlocks, set<SimpleLock*>& wrlocks, set<SimpleLock*>& xlocks,
 					  bool okexist, bool mustexist, bool alwaysxlock,
-					  ceph_file_layout **layout)
+					  file_layout_t **layout)
 {
   const filepath& refpath = n ? mdr->get_filepath2() : mdr->get_filepath();
 
@@ -2916,7 +2918,7 @@ void Server::handle_client_open(MDRequestRef& mdr)
       return;
 
     if (!check_access(mdr, cur, MAY_WRITE))
-    return;
+      return;
 
     // wait for pending truncate?
     const inode_t *pi = cur->get_projected_inode();
@@ -3073,7 +3075,7 @@ void Server::handle_client_openc(MDRequestRef& mdr)
 
   bool excl = (req->head.args.open.flags & O_EXCL);
   set<SimpleLock*> rdlocks, wrlocks, xlocks;
-  ceph_file_layout *dir_layout = NULL;
+  file_layout_t *dir_layout = NULL;
   CDentry *dn = rdlock_path_xlock_dentry(mdr, 0, rdlocks, wrlocks, xlocks,
                                          !excl, false, false, &dir_layout);
   if (!dn) return;
@@ -3082,7 +3084,7 @@ void Server::handle_client_openc(MDRequestRef& mdr)
     return;
   }
   // set layout
-  ceph_file_layout layout;
+  file_layout_t layout;
   if (dir_layout)
     layout = *dir_layout;
   else
@@ -3093,23 +3095,23 @@ void Server::handle_client_openc(MDRequestRef& mdr)
 
   // fill in any special params from client
   if (req->head.args.open.stripe_unit)
-    layout.fl_stripe_unit = req->head.args.open.stripe_unit;
+    layout.stripe_unit = req->head.args.open.stripe_unit;
   if (req->head.args.open.stripe_count)
-    layout.fl_stripe_count = req->head.args.open.stripe_count;
+    layout.stripe_count = req->head.args.open.stripe_count;
   if (req->head.args.open.object_size)
-    layout.fl_object_size = req->head.args.open.object_size;
+    layout.object_size = req->head.args.open.object_size;
   if (req->get_connection()->has_feature(CEPH_FEATURE_CREATEPOOLID) &&
       (__s32)req->head.args.open.pool >= 0) {
-    layout.fl_pg_pool = req->head.args.open.pool;
+    layout.pool_id = req->head.args.open.pool;
 
     // If client doesn't have capability to modify layout pools, then
     // only permit this request if the requested pool matches what the
     // file would have inherited anyway from its parent.
     CDir *parent = dn->get_dir();
     CInode *parent_in = parent->get_inode();
-    int64_t parent_pool = parent_in->inode.layout.fl_pg_pool;
+    int64_t parent_pool = parent_in->inode.layout.pool_id;
 
-    if (layout.fl_pg_pool != parent_pool) {
+    if (layout.pool_id != parent_pool) {
       access |= MAY_SET_POOL;
     }
 
@@ -3120,13 +3122,13 @@ void Server::handle_client_openc(MDRequestRef& mdr)
     }
   }
 
-  if (!ceph_file_layout_is_valid(&layout)) {
+  if (!layout.is_valid()) {
     dout(10) << " invalid initial file layout" << dendl;
     respond_to_request(mdr, -EINVAL);
     return;
   }
-  if (!mds->mdsmap->is_data_pool(layout.fl_pg_pool)) {
-    dout(10) << " invalid data pool " << layout.fl_pg_pool << dendl;
+  if (!mds->mdsmap->is_data_pool(layout.pool_id)) {
+    dout(10) << " invalid data pool " << layout.pool_id << dendl;
     respond_to_request(mdr, -EINVAL);
     return;
   }
@@ -3165,8 +3167,8 @@ void Server::handle_client_openc(MDRequestRef& mdr)
   dn->push_projected_linkage(in);
 
   in->inode.version = dn->pre_dirty();
-  if (layout.fl_pg_pool != mdcache->default_file_layout.fl_pg_pool)
-    in->inode.add_old_pool(mdcache->default_file_layout.fl_pg_pool);
+  if (layout.pool_id != mdcache->default_file_layout.pool_id)
+    in->inode.add_old_pool(mdcache->default_file_layout.pool_id);
   in->inode.update_backtrace();
   if (cmode & CEPH_FILE_MODE_WR) {
     in->inode.client_ranges[client].range.first = 0;
@@ -3531,14 +3533,17 @@ void Server::handle_client_file_setlock(MDRequestRef& mdr)
     respond_to_request(mdr, 0);
   } else {
     dout(10) << " lock attempt on " << set_lock << dendl;
+    bool deadlock = false;
     if (mdr->more()->flock_was_waiting &&
 	!lock_state->is_waiting(set_lock)) {
       dout(10) << " was waiting for lock but not anymore, must have been canceled " << set_lock << dendl;
       respond_to_request(mdr, -EINTR);
-    } else if (!lock_state->add_lock(set_lock, will_wait, mdr->more()->flock_was_waiting)) {
+    } else if (!lock_state->add_lock(set_lock, will_wait, mdr->more()->flock_was_waiting, &deadlock)) {
       dout(10) << " it failed on this attempt" << dendl;
       // couldn't set lock right now
-      if (!will_wait) {
+      if (deadlock) {
+	respond_to_request(mdr, -EDEADLK);
+      } else if (!will_wait) {
 	respond_to_request(mdr, -EWOULDBLOCK);
       } else {
 	dout(10) << " added to waiting list" << dendl;
@@ -3813,26 +3818,22 @@ void Server::handle_client_setlayout(MDRequestRef& mdr)
   }
 
   // validate layout
-  ceph_file_layout layout = cur->get_projected_inode()->layout;
+  file_layout_t layout = cur->get_projected_inode()->layout;
   // save existing layout for later
-  int64_t old_pool = layout.fl_pg_pool;
+  int64_t old_pool = layout.pool_id;
 
   int access = MAY_WRITE;
 
   if (req->head.args.setlayout.layout.fl_object_size > 0)
-    layout.fl_object_size = req->head.args.setlayout.layout.fl_object_size;
+    layout.object_size = req->head.args.setlayout.layout.fl_object_size;
   if (req->head.args.setlayout.layout.fl_stripe_unit > 0)
-    layout.fl_stripe_unit = req->head.args.setlayout.layout.fl_stripe_unit;
+    layout.stripe_unit = req->head.args.setlayout.layout.fl_stripe_unit;
   if (req->head.args.setlayout.layout.fl_stripe_count > 0)
-    layout.fl_stripe_count=req->head.args.setlayout.layout.fl_stripe_count;
-  if (req->head.args.setlayout.layout.fl_cas_hash > 0)
-    layout.fl_cas_hash = req->head.args.setlayout.layout.fl_cas_hash;
-  if (req->head.args.setlayout.layout.fl_object_stripe_unit > 0)
-    layout.fl_object_stripe_unit = req->head.args.setlayout.layout.fl_object_stripe_unit;
+    layout.stripe_count=req->head.args.setlayout.layout.fl_stripe_count;
   if (req->head.args.setlayout.layout.fl_pg_pool > 0) {
-    layout.fl_pg_pool = req->head.args.setlayout.layout.fl_pg_pool;
+    layout.pool_id = req->head.args.setlayout.layout.fl_pg_pool;
 
-    if (layout.fl_pg_pool != old_pool) {
+    if (layout.pool_id != old_pool) {
       access |= MAY_SET_POOL;
     }
 
@@ -3842,13 +3843,13 @@ void Server::handle_client_setlayout(MDRequestRef& mdr)
       return;
     }
   }
-  if (!ceph_file_layout_is_valid(&layout)) {
+  if (!layout.is_valid()) {
     dout(10) << "bad layout" << dendl;
     respond_to_request(mdr, -EINVAL);
     return;
   }
-  if (!mds->mdsmap->is_data_pool(layout.fl_pg_pool)) {
-    dout(10) << " invalid data pool " << layout.fl_pg_pool << dendl;
+  if (!mds->mdsmap->is_data_pool(layout.pool_id)) {
+    dout(10) << " invalid data pool " << layout.pool_id << dendl;
     respond_to_request(mdr, -EINVAL);
     return;
   }
@@ -3883,7 +3884,7 @@ void Server::handle_client_setdirlayout(MDRequestRef& mdr)
 {
   MClientRequest *req = mdr->client_request;
   set<SimpleLock*> rdlocks, wrlocks, xlocks;
-  ceph_file_layout *dir_layout = NULL;
+  file_layout_t *dir_layout = NULL;
   CInode *cur = rdlock_path_pin_ref(mdr, 0, rdlocks, true, false, &dir_layout);
   if (!cur) return;
 
@@ -3903,7 +3904,7 @@ void Server::handle_client_setdirlayout(MDRequestRef& mdr)
 
   // validate layout
   const inode_t *old_pi = cur->get_projected_inode();
-  ceph_file_layout layout;
+  file_layout_t layout;
   if (old_pi->has_layout())
     layout = old_pi->layout;
   else if (dir_layout)
@@ -3915,33 +3916,29 @@ void Server::handle_client_setdirlayout(MDRequestRef& mdr)
   int access = MAY_WRITE;
 
   if (req->head.args.setlayout.layout.fl_object_size > 0)
-    layout.fl_object_size = req->head.args.setlayout.layout.fl_object_size;
+    layout.object_size = req->head.args.setlayout.layout.fl_object_size;
   if (req->head.args.setlayout.layout.fl_stripe_unit > 0)
-    layout.fl_stripe_unit = req->head.args.setlayout.layout.fl_stripe_unit;
+    layout.stripe_unit = req->head.args.setlayout.layout.fl_stripe_unit;
   if (req->head.args.setlayout.layout.fl_stripe_count > 0)
-    layout.fl_stripe_count=req->head.args.setlayout.layout.fl_stripe_count;
-  if (req->head.args.setlayout.layout.fl_cas_hash > 0)
-    layout.fl_cas_hash = req->head.args.setlayout.layout.fl_cas_hash;
-  if (req->head.args.setlayout.layout.fl_object_stripe_unit > 0)
-    layout.fl_object_stripe_unit = req->head.args.setlayout.layout.fl_object_stripe_unit;
+    layout.stripe_count=req->head.args.setlayout.layout.fl_stripe_count;
   if (req->head.args.setlayout.layout.fl_pg_pool > 0) {
-    if (req->head.args.setlayout.layout.fl_pg_pool != layout.fl_pg_pool) {
+    if (req->head.args.setlayout.layout.fl_pg_pool != layout.pool_id) {
       access |= MAY_SET_POOL;
     }
-    layout.fl_pg_pool = req->head.args.setlayout.layout.fl_pg_pool;
+    layout.pool_id = req->head.args.setlayout.layout.fl_pg_pool;
     // make sure we have as new a map as the client
     if (req->get_mdsmap_epoch() > mds->mdsmap->get_epoch()) {
       mds->wait_for_mdsmap(req->get_mdsmap_epoch(), new C_MDS_RetryRequest(mdcache, mdr));
       return;
     }  
   }
-  if (!ceph_file_layout_is_valid(&layout)) {
+  if (!layout.is_valid()) {
     dout(10) << "bad layout" << dendl;
     respond_to_request(mdr, -EINVAL);
     return;
   }
-  if (!mds->mdsmap->is_data_pool(layout.fl_pg_pool)) {
-    dout(10) << " invalid data pool " << layout.fl_pg_pool << dendl;
+  if (!mds->mdsmap->is_data_pool(layout.pool_id)) {
+    dout(10) << " invalid data pool " << layout.pool_id << dendl;
     respond_to_request(mdr, -EINVAL);
     return;
   }
@@ -3967,7 +3964,7 @@ void Server::handle_client_setdirlayout(MDRequestRef& mdr)
 // XATTRS
 
 int Server::parse_layout_vxattr(string name, string value, const OSDMap& osdmap,
-				ceph_file_layout *layout, bool validate)
+				file_layout_t *layout, bool validate)
 {
   dout(20) << "parse_layout_vxattr name " << name << " value '" << value << "'" << dendl;
   try {
@@ -3992,22 +3989,24 @@ int Server::parse_layout_vxattr(string name, string value, const OSDMap& osdmap,
 	  return r;
       }
     } else if (name == "layout.object_size") {
-      layout->fl_object_size = boost::lexical_cast<unsigned>(value);
+      layout->object_size = boost::lexical_cast<unsigned>(value);
     } else if (name == "layout.stripe_unit") {
-      layout->fl_stripe_unit = boost::lexical_cast<unsigned>(value);
+      layout->stripe_unit = boost::lexical_cast<unsigned>(value);
     } else if (name == "layout.stripe_count") {
-      layout->fl_stripe_count = boost::lexical_cast<unsigned>(value);
+      layout->stripe_count = boost::lexical_cast<unsigned>(value);
     } else if (name == "layout.pool") {
       try {
-	layout->fl_pg_pool = boost::lexical_cast<unsigned>(value);
+	layout->pool_id = boost::lexical_cast<unsigned>(value);
       } catch (boost::bad_lexical_cast const&) {
 	int64_t pool = osdmap.lookup_pg_pool_name(value);
 	if (pool < 0) {
 	  dout(10) << " unknown pool " << value << dendl;
 	  return -ENOENT;
 	}
-	layout->fl_pg_pool = pool;
+	layout->pool_id = pool;
       }
+    } else if (name == "layout.pool_namespace") {
+      layout->pool_ns = value;
     } else {
       dout(10) << " unknown layout vxattr " << name << dendl;
       return -EINVAL;
@@ -4017,12 +4016,12 @@ int Server::parse_layout_vxattr(string name, string value, const OSDMap& osdmap,
     return -EINVAL;
   }
 
-  if (validate && !ceph_file_layout_is_valid(layout)) {
+  if (validate && !layout->is_valid()) {
     dout(10) << "bad layout" << dendl;
     return -EINVAL;
   }
-  if (!mds->mdsmap->is_data_pool(layout->fl_pg_pool)) {
-    dout(10) << " invalid data pool " << layout->fl_pg_pool << dendl;
+  if (!mds->mdsmap->is_data_pool(layout->pool_id)) {
+    dout(10) << " invalid data pool " << layout->pool_id << dendl;
     return -EINVAL;
   }
   return 0;
@@ -4076,7 +4075,7 @@ int Server::parse_quota_vxattr(string name, string value, quota_info_t *quota)
 }
 
 void Server::handle_set_vxattr(MDRequestRef& mdr, CInode *cur,
-			       ceph_file_layout *dir_layout,
+			       file_layout_t *dir_layout,
 			       set<SimpleLock*> rdlocks,
 			       set<SimpleLock*> wrlocks,
 			       set<SimpleLock*> xlocks)
@@ -4096,7 +4095,7 @@ void Server::handle_set_vxattr(MDRequestRef& mdr, CInode *cur,
       return;
     }
 
-    ceph_file_layout layout;
+    file_layout_t layout;
     if (cur->get_projected_inode()->has_layout())
       layout = cur->get_projected_inode()->layout;
     else if (dir_layout)
@@ -4123,7 +4122,7 @@ void Server::handle_set_vxattr(MDRequestRef& mdr, CInode *cur,
           // One day if COMPACT_VERSION of MClientRequest >=3, we can remove those code.
           mdr->waited_for_osdmap = true;
           mds->objecter->wait_for_latest_osdmap(
-      	new C_OnFinisher(new C_IO_Wrapper(mds, new C_MDS_RetryRequest(mdcache, mdr)), mds->finisher));
+	    new C_OnFinisher(new C_IO_Wrapper(mds, new C_MDS_RetryRequest(mdcache, mdr)), mds->finisher));
           return;
         }
         r = -EINVAL;
@@ -4136,7 +4135,7 @@ void Server::handle_set_vxattr(MDRequestRef& mdr, CInode *cur,
     if (!mds->locker->acquire_locks(mdr, rdlocks, wrlocks, xlocks))
       return;
 
-    if (cur->inode.layout.fl_pg_pool != layout.fl_pg_pool) {
+    if (cur->inode.layout.pool_id != layout.pool_id) {
       if (!check_access(mdr, cur, MAY_SET_POOL)) {
         return;
       }
@@ -4154,7 +4153,7 @@ void Server::handle_set_vxattr(MDRequestRef& mdr, CInode *cur,
       respond_to_request(mdr, -ENOTEMPTY);
       return;
     }
-    ceph_file_layout layout = cur->get_projected_inode()->layout;
+    file_layout_t layout = cur->get_projected_inode()->layout;
     rest = name.substr(name.find("layout"));
     int r;
     epoch_t epoch;
@@ -4187,14 +4186,14 @@ void Server::handle_set_vxattr(MDRequestRef& mdr, CInode *cur,
     if (!mds->locker->acquire_locks(mdr, rdlocks, wrlocks, xlocks))
       return;
 
-    if (cur->inode.layout.fl_pg_pool != layout.fl_pg_pool) {
+    if (cur->inode.layout.pool_id != layout.pool_id) {
       if (!check_access(mdr, cur, MAY_SET_POOL)) {
         return;
       }
     }
 
     pi = cur->project_inode();
-    int64_t old_pool = pi->layout.fl_pg_pool;
+    int64_t old_pool = pi->layout.pool_id;
     pi->add_old_pool(old_pool);
     pi->layout = layout;
     pi->ctime = mdr->get_op_stamp();
@@ -4315,8 +4314,8 @@ void Server::handle_client_setxattr(MDRequestRef& mdr)
   set<SimpleLock*> rdlocks, wrlocks, xlocks;
   CInode *cur;
 
-  ceph_file_layout *dir_layout = NULL;
-  if (name.find("ceph.dir.layout") == 0)
+  file_layout_t *dir_layout = NULL;
+  if (name.compare(0, 15, "ceph.dir.layout") == 0)
     cur = rdlock_path_pin_ref(mdr, 0, rdlocks, true, false, &dir_layout);
   else
     cur = rdlock_path_pin_ref(mdr, 0, rdlocks, true);
@@ -4331,7 +4330,7 @@ void Server::handle_client_setxattr(MDRequestRef& mdr)
   int flags = req->head.args.setxattr.flags;
 
   // magic ceph.* namespace?
-  if (name.find("ceph.") == 0) {
+  if (name.compare(0, 5, "ceph.") == 0) {
     handle_set_vxattr(mdr, cur, dir_layout, rdlocks, wrlocks, xlocks);
     return;
   }
@@ -4387,7 +4386,7 @@ void Server::handle_client_removexattr(MDRequestRef& mdr)
   MClientRequest *req = mdr->client_request;
   string name(req->get_path2());
   set<SimpleLock*> rdlocks, wrlocks, xlocks;
-  ceph_file_layout *dir_layout = NULL;
+  file_layout_t *dir_layout = NULL;
   CInode *cur;
   if (name == "ceph.dir.layout")
     cur = rdlock_path_pin_ref(mdr, 0, rdlocks, true, false, &dir_layout);
@@ -4401,7 +4400,7 @@ void Server::handle_client_removexattr(MDRequestRef& mdr)
     return;
   }
 
-  if (name.find("ceph.") == 0) {
+  if (name.compare(0, 5, "ceph.") == 0) {
     handle_remove_vxattr(mdr, cur, rdlocks, wrlocks, xlocks);
     return;
   }
@@ -4498,7 +4497,7 @@ void Server::handle_client_mknod(MDRequestRef& mdr)
   MClientRequest *req = mdr->client_request;
   client_t client = mdr->get_client();
   set<SimpleLock*> rdlocks, wrlocks, xlocks;
-  ceph_file_layout *dir_layout = NULL;
+  file_layout_t *dir_layout = NULL;
   CDentry *dn = rdlock_path_xlock_dentry(mdr, 0, rdlocks, wrlocks, xlocks, false, false, false,
 					 &dir_layout);
   if (!dn) return;
@@ -4519,7 +4518,7 @@ void Server::handle_client_mknod(MDRequestRef& mdr)
     mode |= S_IFREG;
 
   // set layout
-  ceph_file_layout layout;
+  file_layout_t layout;
   if (dir_layout && S_ISREG(mode))
     layout = *dir_layout;
   else
@@ -4536,8 +4535,8 @@ void Server::handle_client_mknod(MDRequestRef& mdr)
   newi->inode.rdev = req->head.args.mknod.rdev;
   newi->inode.version = dn->pre_dirty();
   newi->inode.rstat.rfiles = 1;
-  if (layout.fl_pg_pool != mdcache->default_file_layout.fl_pg_pool)
-    newi->inode.add_old_pool(mdcache->default_file_layout.fl_pg_pool);
+  if (layout.pool_id != mdcache->default_file_layout.pool_id)
+    newi->inode.add_old_pool(mdcache->default_file_layout.pool_id);
   newi->inode.update_backtrace();
 
   // if the client created a _regular_ file via MKNOD, it's highly likely they'll
diff --git a/src/mds/Server.h b/src/mds/Server.h
index 40c71f7..66aa6b9 100644
--- a/src/mds/Server.h
+++ b/src/mds/Server.h
@@ -141,20 +141,20 @@ public:
   CDentry *prepare_null_dentry(MDRequestRef& mdr, CDir *dir, const string& dname, bool okexist=false);
   CDentry *prepare_stray_dentry(MDRequestRef& mdr, CInode *in);
   CInode* prepare_new_inode(MDRequestRef& mdr, CDir *dir, inodeno_t useino, unsigned mode,
-			    ceph_file_layout *layout=NULL);
+			    file_layout_t *layout=NULL);
   void journal_allocated_inos(MDRequestRef& mdr, EMetaBlob *blob);
   void apply_allocated_inos(MDRequestRef& mdr);
 
   CInode* rdlock_path_pin_ref(MDRequestRef& mdr, int n, set<SimpleLock*>& rdlocks, bool want_auth,
 			      bool no_want_auth=false,
-			      ceph_file_layout **layout=NULL,
+			      file_layout_t **layout=NULL,
 			      bool no_lookup=false);
   CDentry* rdlock_path_xlock_dentry(MDRequestRef& mdr, int n,
                                     set<SimpleLock*>& rdlocks,
                                     set<SimpleLock*>& wrlocks,
 				    set<SimpleLock*>& xlocks, bool okexist,
 				    bool mustexist, bool alwaysxlock,
-				    ceph_file_layout **layout=NULL);
+				    file_layout_t **layout=NULL);
 
   CDir* try_open_auth_dirfrag(CInode *diri, frag_t fg, MDRequestRef& mdr);
 
@@ -173,10 +173,10 @@ public:
   void handle_client_setdirlayout(MDRequestRef& mdr);
 
   int parse_layout_vxattr(string name, string value, const OSDMap& osdmap,
-			  ceph_file_layout *layout, bool validate=true);
+			  file_layout_t *layout, bool validate=true);
   int parse_quota_vxattr(string name, string value, quota_info_t *quota);
   void handle_set_vxattr(MDRequestRef& mdr, CInode *cur,
-			 ceph_file_layout *dir_layout,
+			 file_layout_t *dir_layout,
 			 set<SimpleLock*> rdlocks,
 			 set<SimpleLock*> wrlocks,
 			 set<SimpleLock*> xlocks);
diff --git a/src/mds/SessionMap.cc b/src/mds/SessionMap.cc
index 9b4bc7f..1e858e3 100644
--- a/src/mds/SessionMap.cc
+++ b/src/mds/SessionMap.cc
@@ -842,9 +842,9 @@ void Session::decode(bufferlist::iterator &p)
   _update_human_name();
 }
 
-bool Session::check_access(CInode *in, unsigned mask,
-			   int caller_uid, int caller_gid,
-			   int new_uid, int new_gid)
+int Session::check_access(CInode *in, unsigned mask,
+			  int caller_uid, int caller_gid,
+			  int new_uid, int new_gid)
 {
   string path;
   CInode *diri = NULL;
@@ -860,12 +860,20 @@ bool Session::check_access(CInode *in, unsigned mask,
   if (path.length())
     path = path.substr(1);    // drop leading /
 
-  if (auth_caps.is_capable(path, in->inode.uid, in->inode.gid, in->inode.mode,
-			   caller_uid, caller_gid, mask,
-			   new_uid, new_gid)) {
-    return true;
+  if (in->inode.is_dir() &&
+      in->inode.has_layout() &&
+      in->inode.layout.pool_ns.length() &&
+      !connection->has_feature(CEPH_FEATURE_FS_FILE_LAYOUT_V2)) {
+    dout(10) << __func__ << " client doesn't support FS_FILE_LAYOUT_V2" << dendl;
+    return -EIO;
   }
-  return false;
+
+  if (!auth_caps.is_capable(path, in->inode.uid, in->inode.gid, in->inode.mode,
+			    caller_uid, caller_gid, mask,
+			    new_uid, new_gid)) {
+    return -EACCES;
+  }
+  return 0;
 }
 
 int SessionFilter::parse(
diff --git a/src/mds/SessionMap.h b/src/mds/SessionMap.h
index 75a7d07..d03e16c 100644
--- a/src/mds/SessionMap.h
+++ b/src/mds/SessionMap.h
@@ -303,8 +303,8 @@ public:
     completed_requests_dirty = false;
   }
 
-  bool check_access(CInode *in, unsigned mask, int caller_uid, int caller_gid,
-		    int new_uid, int new_gid);
+  int check_access(CInode *in, unsigned mask, int caller_uid, int caller_gid,
+		   int new_uid, int new_gid);
 
 
   Session() : 
diff --git a/src/mds/SnapRealm.cc b/src/mds/SnapRealm.cc
index 12dd67b..b44ca22 100644
--- a/src/mds/SnapRealm.cc
+++ b/src/mds/SnapRealm.cc
@@ -58,21 +58,35 @@ ostream& operator<<(ostream& out, const SnapRealm& realm)
 }
 
 
-void SnapRealm::add_open_past_parent(SnapRealm *parent)
+void SnapRealm::add_open_past_parent(SnapRealm *parent, snapid_t last)
 {
-  open_past_parents[parent->inode->ino()] = parent;
-  parent->open_past_children.insert(this);
-  parent->inode->get(CInode::PIN_PASTSNAPPARENT);
+  auto p = open_past_parents.find(parent->inode->ino());
+  if (p != open_past_parents.end()) {
+    assert(p->second.second.count(last) == 0);
+    p->second.second.insert(last);
+  } else {
+    open_past_parents[parent->inode->ino()].first = parent;
+    open_past_parents[parent->inode->ino()].second.insert(last);
+    parent->open_past_children.insert(this);
+    parent->inode->get(CInode::PIN_PASTSNAPPARENT);
+  }
+  ++num_open_past_parents;
 }
 
-void SnapRealm::remove_open_past_parent(inodeno_t ino)
+void SnapRealm::remove_open_past_parent(inodeno_t ino, snapid_t last)
 {
-  map<inodeno_t,SnapRealm*>::iterator p = open_past_parents.find(ino);
+  auto p = open_past_parents.find(ino);
   assert(p != open_past_parents.end());
-  SnapRealm *parent = p->second;
-  open_past_parents.erase(p);
-  parent->open_past_children.erase(this);
-  parent->inode->put(CInode::PIN_PASTSNAPPARENT);
+  auto q = p->second.second.find(last);
+  assert(q != p->second.second.end());
+  p->second.second.erase(q);
+  --num_open_past_parents;
+  if (p->second.second.empty()) {
+    SnapRealm *parent = p->second.first;
+    open_past_parents.erase(p);
+    parent->open_past_children.erase(this);
+    parent->inode->put(CInode::PIN_PASTSNAPPARENT);
+  }
 }
 
 struct C_SR_RetryOpenParents : public MDSInternalContextBase {
@@ -123,8 +137,8 @@ bool SnapRealm::_open_parents(MDSInternalContextBase *finish, snapid_t first, sn
   }
 
   // and my past parents too!
-  assert(srnode.past_parents.size() >= open_past_parents.size());
-  if (srnode.past_parents.size() > open_past_parents.size()) {
+  assert(srnode.past_parents.size() >= num_open_past_parents);
+  if (srnode.past_parents.size() > num_open_past_parents) {
     for (map<snapid_t, snaplink_t>::iterator p = srnode.past_parents.begin();
 	 p != srnode.past_parents.end(); ) {
       dout(10) << " past_parent [" << p->second.first << "," << p->first << "] is "
@@ -144,8 +158,10 @@ bool SnapRealm::_open_parents(MDSInternalContextBase *finish, snapid_t first, sn
       assert(parent->snaprealm);  // hmm!
       if (!parent->snaprealm->_open_parents(finish, p->second.first, p->first))
 	return false;
-      if (!open_past_parents.count(p->second.ino)) {
-	add_open_past_parent(parent->snaprealm);
+      auto q = open_past_parents.find(p->second.ino);
+      if (q == open_past_parents.end() ||
+	  q->second.second.count(p->first) == 0) {
+	add_open_past_parent(parent->snaprealm, p->first);
       }
       ++p;
     }
@@ -172,8 +188,9 @@ bool SnapRealm::have_past_parents_open(snapid_t first, snapid_t last)
       dout(10) << " past parent " << p->second.ino << " is not open" << dendl;
       return false;
     }
-    if (!open_past_parents[p->second.ino]->have_past_parents_open(MAX(first, p->second.first),
-								  MIN(last, p->first)))
+    SnapRealm *parent_realm = open_past_parents[p->second.ino].first;
+    if (parent_realm->have_past_parents_open(MAX(first, p->second.first),
+					     MIN(last, p->first)))
       return false;
   }
 
@@ -183,11 +200,10 @@ bool SnapRealm::have_past_parents_open(snapid_t first, snapid_t last)
 
 void SnapRealm::close_parents()
 {
-  for (map<inodeno_t,SnapRealm*>::iterator p = open_past_parents.begin();
-       p != open_past_parents.end();
-       ++p) {
-    p->second->inode->put(CInode::PIN_PASTSNAPPARENT);
-    p->second->open_past_children.erase(this);
+  for (auto p = open_past_parents.begin(); p != open_past_parents.end(); ++p) {
+    num_open_past_parents -= p->second.second.size();
+    p->second.first->inode->put(CInode::PIN_PASTSNAPPARENT);
+    p->second.first->open_past_children.erase(this);
   }
   open_past_parents.clear();
 }
@@ -528,7 +544,7 @@ void SnapRealm::prune_past_parents()
 	*q > p->first) {
       dout(10) << "prune_past_parents pruning [" << p->second.first << "," << p->first 
 	       << "] " << p->second.ino << dendl;
-      remove_open_past_parent(p->second.ino);
+      remove_open_past_parent(p->second.ino, p->first);
       srnode.past_parents.erase(p++);
     } else {
       dout(10) << "prune_past_parents keeping [" << p->second.first << "," << p->first 
diff --git a/src/mds/SnapRealm.h b/src/mds/SnapRealm.h
index 92f3de9..4cad809 100644
--- a/src/mds/SnapRealm.h
+++ b/src/mds/SnapRealm.h
@@ -34,8 +34,9 @@ struct SnapRealm {
   bool open;                        // set to true once all past_parents are opened
   SnapRealm *parent;
   set<SnapRealm*> open_children;    // active children that are currently open
-  map<inodeno_t,SnapRealm*> open_past_parents;  // these are explicitly pinned.
   set<SnapRealm*> open_past_children;  // past children who has pinned me
+  map<inodeno_t, pair<SnapRealm*, set<snapid_t> > > open_past_parents;  // these are explicitly pinned.
+  unsigned num_open_past_parents;
 
   // cache
   snapid_t cached_seq;           // max seq over self and all past+present parents.
@@ -53,6 +54,7 @@ struct SnapRealm {
     srnode(),
     mdcache(c), inode(in),
     open(false), parent(0),
+    num_open_past_parents(0),
     inodes_with_caps(0) 
   { }
 
@@ -77,8 +79,8 @@ struct SnapRealm {
     return true;
   }
   bool have_past_parents_open(snapid_t first=1, snapid_t last=CEPH_NOSNAP);
-  void add_open_past_parent(SnapRealm *parent);
-  void remove_open_past_parent(inodeno_t ino);
+  void add_open_past_parent(SnapRealm *parent, snapid_t last);
+  void remove_open_past_parent(inodeno_t ino, snapid_t last);
   void close_parents();
 
   void prune_past_parents();
diff --git a/src/mds/StrayManager.cc b/src/mds/StrayManager.cc
index 6547a26..e6f4959 100644
--- a/src/mds/StrayManager.cc
+++ b/src/mds/StrayManager.cc
@@ -128,16 +128,14 @@ void StrayManager::purge(CDentry *dn, uint32_t op_allowance)
   }
 
   if (in->is_file()) {
-    uint64_t period = (uint64_t)in->inode.layout.fl_object_size *
-		      (uint64_t)in->inode.layout.fl_stripe_count;
     uint64_t to = in->inode.get_max_size();
     to = MAX(in->inode.size, to);
     // when truncating a file, the filer does not delete stripe objects that are
     // truncated to zero. so we need to purge stripe objects up to the max size
     // the file has ever been.
     to = MAX(in->inode.max_size_ever, to);
-    if (to && period) {
-      uint64_t num = (to + period - 1) / period;
+    if (to > 0) {
+      uint64_t num = Striper::get_num_objects(in->inode.layout, to);
       dout(10) << __func__ << " 0~" << to << " objects 0~" << num
 	       << " snapc " << snapc << " on " << *in << dendl;
       filer.purge_range(in->inode.ino, &in->inode.layout, *snapc,
@@ -149,8 +147,8 @@ void StrayManager::purge(CDentry *dn, uint32_t op_allowance)
   inode_t *pi = in->get_projected_inode();
   object_t oid = CInode::get_object_name(pi->ino, frag_t(), "");
   // remove the backtrace object if it was not purged
-  if (!gather.has_subs()) {
-    object_locator_t oloc(pi->layout.fl_pg_pool);
+  if (!gather.has_subs() || !pi->layout.pool_ns.empty()) {
+    object_locator_t oloc(pi->layout.pool_id);
     dout(10) << __func__ << " remove backtrace object " << oid
 	     << " pool " << oloc.pool << " snapc " << snapc << dendl;
     mds->objecter->remove(oid, oloc, *snapc,
@@ -320,12 +318,6 @@ void StrayManager::enqueue(CDentry *dn, bool trunc)
   dn->get(CDentry::PIN_PURGING);
   in->state_set(CInode::STATE_PURGING);
 
-  if (dn->item_stray.is_on_list()) {
-    dn->item_stray.remove_myself();
-    num_strays_delayed--;
-    logger->set(l_mdc_num_strays_delayed, num_strays_delayed);
-  }
-
   /* We must clear this as soon as enqueuing it, to prevent the journal
    * expiry code from seeing a dirty parent and trying to write a backtrace */
   if (!trunc) {
@@ -444,12 +436,10 @@ uint32_t StrayManager::_calculate_ops_required(CInode *in, bool trunc)
     ops_required = 1 + ls.size();
   } else {
     // File, work out concurrent Filer::purge deletes
-    const uint64_t period = (uint64_t)in->inode.layout.fl_object_size *
-		      (uint64_t)in->inode.layout.fl_stripe_count;
     const uint64_t to = MAX(in->inode.max_size_ever,
             MAX(in->inode.size, in->inode.get_max_size()));
 
-    const uint64_t num = MAX(1, (to + period - 1) / period);
+    const uint64_t num = (to > 0) ? Striper::get_num_objects(in->inode.layout, to) : 1;
     ops_required = MIN(num, g_conf->filer_max_purge_ops);
 
     // Account for removing (or zeroing) backtrace
@@ -549,6 +539,15 @@ bool StrayManager::__eval_stray(CDentry *dn, bool delay)
     return false;
   }
 
+  if (dn->item_stray.is_on_list()) {
+    if (delay)
+      return false;
+
+    dn->item_stray.remove_myself();
+    num_strays_delayed--;
+    logger->set(l_mdc_num_strays_delayed, num_strays_delayed);
+  }
+
   // purge?
   if (in->inode.nlink == 0) {
     // past snaprealm parents imply snapped dentry remote links.
@@ -804,27 +803,26 @@ void StrayManager::truncate(CDentry *dn, uint32_t op_allowance)
   dout(10) << " realm " << *realm << dendl;
   const SnapContext *snapc = &realm->get_snap_context();
 
-  uint64_t period = (uint64_t)in->inode.layout.fl_object_size *
-		    (uint64_t)in->inode.layout.fl_stripe_count;
   uint64_t to = in->inode.get_max_size();
   to = MAX(in->inode.size, to);
   // when truncating a file, the filer does not delete stripe objects that are
   // truncated to zero. so we need to purge stripe objects up to the max size
   // the file has ever been.
   to = MAX(in->inode.max_size_ever, to);
-  if (period && to > period) {
-    uint64_t num = (to - 1) / period;
+  if (to > 0) {
+    uint64_t num = Striper::get_num_objects(in->inode.layout, to);
     dout(10) << __func__ << " 0~" << to << " objects 0~" << num
-      << " snapc " << snapc << " on " << *in << dendl;
-    filer.purge_range(in->ino(), &in->inode.layout, *snapc,
-		      1, num, ceph::real_clock::now(g_ceph_context),
-		      0, gather.new_sub());
-  }
+	     << " snapc " << snapc << " on " << *in << dendl;
 
-  // keep backtrace object
-  if (period && to > 0) {
+    // keep backtrace object
+    if (num > 1) {
+      filer.purge_range(in->ino(), &in->inode.layout, *snapc,
+			1, num - 1, ceph::real_clock::now(g_ceph_context),
+			0, gather.new_sub());
+    }
     filer.zero(in->ino(), &in->inode.layout, *snapc,
-	       0, period, ceph::real_clock::now(g_ceph_context),
+	       0, in->inode.layout.object_size,
+	       ceph::real_clock::now(g_ceph_context),
 	       0, true, NULL, gather.new_sub());
   }
 
diff --git a/src/mds/events/ECommitted.h b/src/mds/events/ECommitted.h
index 4cdbbfb..67e312c 100644
--- a/src/mds/events/ECommitted.h
+++ b/src/mds/events/ECommitted.h
@@ -30,7 +30,7 @@ public:
     out << "ECommitted " << reqid;
   }
 
-  void encode(bufferlist &bl) const;
+  void encode(bufferlist &bl, uint64_t features) const;
   void decode(bufferlist::iterator &bl);
   void dump(Formatter *f) const;
   static void generate_test_instances(list<ECommitted*>& ls);
@@ -38,5 +38,6 @@ public:
   void update_segment() {}
   void replay(MDSRank *mds);
 };
+WRITE_CLASS_ENCODER_FEATURES(ECommitted)
 
 #endif
diff --git a/src/mds/events/EExport.h b/src/mds/events/EExport.h
index 64a3373..0690aec 100644
--- a/src/mds/events/EExport.h
+++ b/src/mds/events/EExport.h
@@ -44,12 +44,13 @@ public:
 
   EMetaBlob *get_metablob() { return &metablob; }
 
-  void encode(bufferlist& bl) const;
+  void encode(bufferlist& bl, uint64_t features) const;
   void decode(bufferlist::iterator &bl);
   void dump(Formatter *f) const;
   static void generate_test_instances(list<EExport*>& ls);
   void replay(MDSRank *mds);
 
 };
+WRITE_CLASS_ENCODER_FEATURES(EExport)
 
 #endif
diff --git a/src/mds/events/EFragment.h b/src/mds/events/EFragment.h
index fac7d36..4cc2c36 100644
--- a/src/mds/events/EFragment.h
+++ b/src/mds/events/EFragment.h
@@ -70,11 +70,12 @@ public:
 
   EMetaBlob *get_metablob() { return &metablob; }
 
-  void encode(bufferlist &bl) const;
+  void encode(bufferlist &bl, uint64_t features) const;
   void decode(bufferlist::iterator &bl);
   void dump(Formatter *f) const;
   static void generate_test_instances(list<EFragment*>& ls);
   void replay(MDSRank *mds);
 };
+WRITE_CLASS_ENCODER_FEATURES(EFragment)
 
 #endif
diff --git a/src/mds/events/EImportFinish.h b/src/mds/events/EImportFinish.h
index 4129a4c..bd04ef5 100644
--- a/src/mds/events/EImportFinish.h
+++ b/src/mds/events/EImportFinish.h
@@ -40,7 +40,7 @@ class EImportFinish : public LogEvent {
       out << " failed";
   }
 
-  void encode(bufferlist& bl) const;
+  void encode(bufferlist& bl, uint64_t features) const;
   void decode(bufferlist::iterator &bl);
   void dump(Formatter *f) const;
   static void generate_test_instances(list<EImportFinish*>& ls);
@@ -48,5 +48,6 @@ class EImportFinish : public LogEvent {
   void replay(MDSRank *mds);
 
 };
+WRITE_CLASS_ENCODER_FEATURES(EImportFinish)
 
 #endif
diff --git a/src/mds/events/EImportStart.h b/src/mds/events/EImportStart.h
index 9f47d49..cebf848 100644
--- a/src/mds/events/EImportStart.h
+++ b/src/mds/events/EImportStart.h
@@ -47,7 +47,7 @@ protected:
 
   EMetaBlob *get_metablob() { return &metablob; }
   
-  void encode(bufferlist &bl) const;
+  void encode(bufferlist &bl, uint64_t features) const;
   void decode(bufferlist::iterator &bl);
   void dump(Formatter *f) const;
   static void generate_test_instances(list<EImportStart*>& ls);
@@ -56,5 +56,6 @@ protected:
   void replay(MDSRank *mds);
 
 };
+WRITE_CLASS_ENCODER_FEATURES(EImportStart)
 
 #endif
diff --git a/src/mds/events/EMetaBlob.h b/src/mds/events/EMetaBlob.h
index 8db8f67..77f8c3c 100644
--- a/src/mds/events/EMetaBlob.h
+++ b/src/mds/events/EMetaBlob.h
@@ -100,7 +100,7 @@ public:
     fullbit() {}
     ~fullbit() {}
 
-    void encode(bufferlist& bl) const;
+    void encode(bufferlist& bl, uint64_t features) const;
     void decode(bufferlist::iterator &bl);
     void dump(Formatter *f) const;
     static void generate_test_instances(list<EMetaBlob::fullbit*>& ls);
@@ -130,7 +130,7 @@ public:
       return state_string;
     }
   };
-  WRITE_CLASS_ENCODER(fullbit)
+  WRITE_CLASS_ENCODER_FEATURES(fullbit)
   
   /* remotebit - a dentry + remote inode link (i.e. just an ino)
    */
@@ -262,9 +262,9 @@ public:
     }
 
     // if this changes, update the versioning in encode for it!
-    void _encode_bits() const {
+    void _encode_bits(uint64_t features) const {
       if (!dn_decoded) return;
-      ::encode(dfull, dnbl);
+      ::encode(dfull, dnbl, features);
       ::encode(dremote, dnbl);
       ::encode(dnull, dnbl);
     }
@@ -277,12 +277,12 @@ public:
       dn_decoded = true;
     }
 
-    void encode(bufferlist& bl) const;
+    void encode(bufferlist& bl, uint64_t features) const;
     void decode(bufferlist::iterator &bl);
     void dump(Formatter *f) const;
     static void generate_test_instances(list<dirlump*>& ls);
   };
-  WRITE_CLASS_ENCODER(dirlump)
+  WRITE_CLASS_ENCODER_FEATURES(dirlump)
 
   // my lumps.  preserve the order we added them in a list.
   list<dirfrag_t>         lump_order;
@@ -317,7 +317,7 @@ private:
   list<pair<metareqid_t,uint64_t> > client_flushes;
 
  public:
-  void encode(bufferlist& bl) const;
+  void encode(bufferlist& bl, uint64_t features) const;
   void decode(bufferlist::iterator& bl);
   void get_inodes(std::set<inodeno_t> &inodes) const;
   void get_paths(std::vector<std::string> &paths) const;
@@ -580,11 +580,11 @@ private:
   void update_segment(LogSegment *ls);
   void replay(MDSRank *mds, LogSegment *ls, MDSlaveUpdate *su=NULL);
 };
-WRITE_CLASS_ENCODER(EMetaBlob)
-WRITE_CLASS_ENCODER(EMetaBlob::fullbit)
+WRITE_CLASS_ENCODER_FEATURES(EMetaBlob)
+WRITE_CLASS_ENCODER_FEATURES(EMetaBlob::fullbit)
 WRITE_CLASS_ENCODER(EMetaBlob::remotebit)
 WRITE_CLASS_ENCODER(EMetaBlob::nullbit)
-WRITE_CLASS_ENCODER(EMetaBlob::dirlump)
+WRITE_CLASS_ENCODER_FEATURES(EMetaBlob::dirlump)
 
 inline ostream& operator<<(ostream& out, const EMetaBlob& t) {
   t.print(out);
diff --git a/src/mds/events/ENoOp.h b/src/mds/events/ENoOp.h
index ed825c6..4b26fe6 100644
--- a/src/mds/events/ENoOp.h
+++ b/src/mds/events/ENoOp.h
@@ -24,11 +24,12 @@ public:
   ENoOp() : LogEvent(EVENT_NOOP), pad_size(0) { }
   explicit ENoOp(uint32_t size_) : LogEvent(EVENT_NOOP), pad_size(size_){ }
 
-  void encode(bufferlist& bl) const;
+  void encode(bufferlist& bl, uint64_t features) const;
   void decode(bufferlist::iterator& bl);
   void dump(Formatter *f) const {}
 
   void replay(MDSRank *mds);
 };
+WRITE_CLASS_ENCODER_FEATURES(ENoOp)
 
 #endif
diff --git a/src/mds/events/EOpen.h b/src/mds/events/EOpen.h
index 0c1175b..c48d735 100644
--- a/src/mds/events/EOpen.h
+++ b/src/mds/events/EOpen.h
@@ -44,7 +44,7 @@ public:
     inos.push_back(ino);
   }
 
-  void encode(bufferlist& bl) const;
+  void encode(bufferlist& bl, uint64_t features) const;
   void decode(bufferlist::iterator& bl);
   void dump(Formatter *f) const;
   static void generate_test_instances(list<EOpen*>& ls);
@@ -52,5 +52,6 @@ public:
   void update_segment();
   void replay(MDSRank *mds);
 };
+WRITE_CLASS_ENCODER_FEATURES(EOpen)
 
 #endif
diff --git a/src/mds/events/EResetJournal.h b/src/mds/events/EResetJournal.h
index 5f7e9a3..717781e 100644
--- a/src/mds/events/EResetJournal.h
+++ b/src/mds/events/EResetJournal.h
@@ -24,7 +24,7 @@ class EResetJournal : public LogEvent {
   EResetJournal() : LogEvent(EVENT_RESETJOURNAL) { }
   ~EResetJournal() {}
 
-  void encode(bufferlist& bl) const;
+  void encode(bufferlist& bl, uint64_t features) const;
   void decode(bufferlist::iterator& bl);
   void dump(Formatter *f) const;
   static void generate_test_instances(list<EResetJournal*>& ls);
@@ -34,5 +34,6 @@ class EResetJournal : public LogEvent {
 
   void replay(MDSRank *mds);
 };
+WRITE_CLASS_ENCODER_FEATURES(EResetJournal)
 
 #endif
diff --git a/src/mds/events/ESession.h b/src/mds/events/ESession.h
index c3b2fc0..9fe6b6f 100644
--- a/src/mds/events/ESession.h
+++ b/src/mds/events/ESession.h
@@ -51,7 +51,7 @@ class ESession : public LogEvent {
     cmapv(v),
     inos(i), inotablev(iv) { }
 
-  void encode(bufferlist& bl) const;
+  void encode(bufferlist& bl, uint64_t features) const;
   void decode(bufferlist::iterator& bl);
   void dump(Formatter *f) const;
   static void generate_test_instances(list<ESession*>& ls);
@@ -69,5 +69,6 @@ class ESession : public LogEvent {
   void replay(MDSRank *mds);
   entity_inst_t get_client_inst() const {return client_inst;}
 };
+WRITE_CLASS_ENCODER_FEATURES(ESession)
 
 #endif
diff --git a/src/mds/events/ESessions.h b/src/mds/events/ESessions.h
index 5b5b594..35a6ce7 100644
--- a/src/mds/events/ESessions.h
+++ b/src/mds/events/ESessions.h
@@ -38,7 +38,7 @@ public:
 
   void mark_old_encoding() { old_style_encode = true; }
 
-  void encode(bufferlist &bl) const;
+  void encode(bufferlist &bl, uint64_t features) const;
   void decode_old(bufferlist::iterator &bl);
   void decode_new(bufferlist::iterator &bl);
   void decode(bufferlist::iterator &bl) {
@@ -55,5 +55,6 @@ public:
   void update_segment();
   void replay(MDSRank *mds);  
 };
+WRITE_CLASS_ENCODER_FEATURES(ESessions)
 
 #endif
diff --git a/src/mds/events/ESlaveUpdate.h b/src/mds/events/ESlaveUpdate.h
index 41e1bb0..7b22935 100644
--- a/src/mds/events/ESlaveUpdate.h
+++ b/src/mds/events/ESlaveUpdate.h
@@ -138,12 +138,13 @@ public:
 
   EMetaBlob *get_metablob() { return &commit; }
 
-  void encode(bufferlist& bl) const;
+  void encode(bufferlist& bl, uint64_t features) const;
   void decode(bufferlist::iterator& bl);
   void dump(Formatter *f) const;
   static void generate_test_instances(list<ESlaveUpdate*>& ls);
 
   void replay(MDSRank *mds);
 };
+WRITE_CLASS_ENCODER_FEATURES(ESlaveUpdate)
 
 #endif
diff --git a/src/mds/events/ESubtreeMap.h b/src/mds/events/ESubtreeMap.h
index 9a5f193..e021ecc 100644
--- a/src/mds/events/ESubtreeMap.h
+++ b/src/mds/events/ESubtreeMap.h
@@ -36,12 +36,13 @@ public:
 
   EMetaBlob *get_metablob() { return &metablob; }
 
-  void encode(bufferlist& bl) const;
+  void encode(bufferlist& bl, uint64_t features) const;
   void decode(bufferlist::iterator& bl);
   void dump(Formatter *f) const;
   static void generate_test_instances(list<ESubtreeMap*>& ls);
 
   void replay(MDSRank *mds);
 };
+WRITE_CLASS_ENCODER_FEATURES(ESubtreeMap)
 
 #endif
diff --git a/src/mds/events/ETableClient.h b/src/mds/events/ETableClient.h
index aaa1664..97b2207 100644
--- a/src/mds/events/ETableClient.h
+++ b/src/mds/events/ETableClient.h
@@ -31,7 +31,7 @@ struct ETableClient : public LogEvent {
     LogEvent(EVENT_TABLECLIENT),
     table(t), op(o), tid(ti) { }
 
-  void encode(bufferlist& bl) const;
+  void encode(bufferlist& bl, uint64_t features) const;
   void decode(bufferlist::iterator& bl);
   void dump(Formatter *f) const;
   static void generate_test_instances(list<ETableClient*>& ls);
@@ -44,5 +44,6 @@ struct ETableClient : public LogEvent {
   //void update_segment();
   void replay(MDSRank *mds);  
 };
+WRITE_CLASS_ENCODER_FEATURES(ETableClient)
 
 #endif
diff --git a/src/mds/events/ETableServer.h b/src/mds/events/ETableServer.h
index 826d097..196905a 100644
--- a/src/mds/events/ETableServer.h
+++ b/src/mds/events/ETableServer.h
@@ -36,7 +36,7 @@ struct ETableServer : public LogEvent {
     LogEvent(EVENT_TABLESERVER),
     table(t), op(o), reqid(ri), bymds(m), tid(ti), version(v) { }
 
-  void encode(bufferlist& bl) const;
+  void encode(bufferlist& bl, uint64_t features) const;
   void decode(bufferlist::iterator& bl);
   void dump(Formatter *f) const;
   static void generate_test_instances(list<ETableServer*>& ls);
@@ -54,5 +54,6 @@ struct ETableServer : public LogEvent {
   void update_segment();
   void replay(MDSRank *mds);  
 };
+WRITE_CLASS_ENCODER_FEATURES(ETableServer)
 
 #endif
diff --git a/src/mds/events/EUpdate.h b/src/mds/events/EUpdate.h
index 672af27..7d567e2 100644
--- a/src/mds/events/EUpdate.h
+++ b/src/mds/events/EUpdate.h
@@ -40,7 +40,7 @@ public:
 
   EMetaBlob *get_metablob() { return &metablob; }
 
-  void encode(bufferlist& bl) const;
+  void encode(bufferlist& bl, uint64_t features) const;
   void decode(bufferlist::iterator& bl);
   void dump(Formatter *f) const;
   static void generate_test_instances(list<EUpdate*>& ls);
@@ -49,5 +49,6 @@ public:
   void replay(MDSRank *mds);
   EMetaBlob const *get_metablob() const {return &metablob;}
 };
+WRITE_CLASS_ENCODER_FEATURES(EUpdate)
 
 #endif
diff --git a/src/mds/flock.cc b/src/mds/flock.cc
index e99435e..0955703 100644
--- a/src/mds/flock.cc
+++ b/src/mds/flock.cc
@@ -8,7 +8,27 @@
 
 #define dout_subsys ceph_subsys_mds
 
-bool ceph_lock_state_t::is_waiting(ceph_filelock &fl)
+static multimap<ceph_filelock, ceph_lock_state_t*> global_waiting_locks;
+
+ceph_lock_state_t::~ceph_lock_state_t()
+{
+  if (type == CEPH_LOCK_FCNTL) {
+    for (auto p = waiting_locks.begin(); p != waiting_locks.end(); ++p) {
+      for (auto q = global_waiting_locks.find(p->second);
+	   q != global_waiting_locks.end(); ) {
+	if (q->first != p->second)
+	  break;
+	if (q->second == this) {
+	  global_waiting_locks.erase(q);
+	  break;
+	}
+	++q;
+      }
+    }
+  }
+}
+
+bool ceph_lock_state_t::is_waiting(const ceph_filelock &fl)
 {
   multimap<uint64_t, ceph_filelock>::iterator p = waiting_locks.find(fl.start);
   while (p != waiting_locks.end()) {
@@ -22,12 +42,12 @@ bool ceph_lock_state_t::is_waiting(ceph_filelock &fl)
   return false;
 }
 
-void ceph_lock_state_t::remove_waiting(ceph_filelock& fl)
+void ceph_lock_state_t::remove_waiting(const ceph_filelock& fl)
 {
-  multimap<uint64_t, ceph_filelock>::iterator p = waiting_locks.find(fl.start);
-  while (p != waiting_locks.end()) {
+  for (auto p = waiting_locks.find(fl.start);
+       p != waiting_locks.end(); ) {
     if (p->second.start > fl.start)
-      return;
+      break;
     if (p->second.length == fl.length &&
 	ceph_filelock_owner_equal(p->second, fl)) {
       waiting_locks.erase(p);
@@ -35,14 +55,100 @@ void ceph_lock_state_t::remove_waiting(ceph_filelock& fl)
       if (!client_waiting_lock_counts[(client_t)fl.client]) {
         client_waiting_lock_counts.erase((client_t)fl.client);
       }
-      return;
+      break;
     }
     ++p;
   }
+
+  if (type == CEPH_LOCK_FCNTL) {
+    for (auto q = global_waiting_locks.find(fl);
+	 q != global_waiting_locks.end(); ) {
+      if (q->first != fl)
+	break;
+      if (q->second == this) {
+	global_waiting_locks.erase(q);
+	break;
+      }
+      ++q;
+    }
+  }
+}
+
+bool ceph_lock_state_t::is_deadlock(const ceph_filelock& fl,
+				    list<multimap<uint64_t, ceph_filelock>::iterator>&
+				      overlapping_locks,
+				    const ceph_filelock *first_fl, unsigned depth)
+{
+  ldout(cct,15) << "is_deadlock " << fl << dendl;
+
+  // only for posix lock
+  if (type != CEPH_LOCK_FCNTL)
+    return false;
+
+  // find conflict locks' owners
+  set<ceph_filelock> lock_owners;
+  for (auto p = overlapping_locks.begin();
+       p != overlapping_locks.end();
+       ++p) {
+
+    if (fl.type == CEPH_LOCK_SHARED &&
+	(*p)->second.type == CEPH_LOCK_SHARED)
+      continue;
+
+    // circle detected
+    if (first_fl && ceph_filelock_owner_equal(*first_fl, (*p)->second)) {
+      ldout(cct,15) << " detect deadlock" << dendl;
+      return true;
+    }
+
+    ceph_filelock tmp = (*p)->second;
+    tmp.start = 0;
+    tmp.length = 0;
+    tmp.type = 0;
+    lock_owners.insert(tmp);
+  }
+
+  if (depth >= MAX_DEADLK_DEPTH)
+    return false;
+
+  first_fl = first_fl ? first_fl : &fl;
+  for (auto p = lock_owners.begin();
+       p != lock_owners.end();
+       ++p) {
+    ldout(cct,15) << " conflict lock owner " << *p << dendl;
+    // if conflict lock' owner is waiting for other lock?
+    for (auto q = global_waiting_locks.lower_bound(*p);
+	 q != global_waiting_locks.end();
+	 ++q) {
+      if (!ceph_filelock_owner_equal(q->first, *p))
+	break;
+
+      list<multimap<uint64_t, ceph_filelock>::iterator>
+	_overlapping_locks, _self_overlapping_locks;
+      ceph_lock_state_t& state = *(q->second);
+      if (state.get_overlapping_locks(q->first, _overlapping_locks)) {
+	state.split_by_owner(q->first, _overlapping_locks, _self_overlapping_locks);
+      }
+      if (!_overlapping_locks.empty()) {
+	if (is_deadlock(q->first, _overlapping_locks, first_fl, depth + 1))
+	  return true;
+      }
+    }
+  }
+  return false;
+}
+
+void ceph_lock_state_t::add_waiting(const ceph_filelock& fl)
+{
+  waiting_locks.insert(pair<uint64_t, ceph_filelock>(fl.start, fl));
+  if (type == CEPH_LOCK_FCNTL) {
+    global_waiting_locks.insert(pair<ceph_filelock,ceph_lock_state_t*>(fl, this));
+  }
 }
 
 bool ceph_lock_state_t::add_lock(ceph_filelock& new_lock,
-                                 bool wait_on_fail, bool replay)
+                                 bool wait_on_fail, bool replay,
+				 bool *deadlock)
 {
   ldout(cct,15) << "add_lock " << new_lock << dendl;
   bool ret = false;
@@ -60,14 +166,20 @@ bool ceph_lock_state_t::add_lock(ceph_filelock& new_lock,
       ldout(cct,15) << "overlapping lock, and this lock is exclusive, can't set"
               << dendl;
       if (wait_on_fail && !replay) {
-        waiting_locks.insert(pair<uint64_t, ceph_filelock>(new_lock.start, new_lock));
+	if (is_deadlock(new_lock, overlapping_locks))
+	  *deadlock = true;
+	else
+	  add_waiting(new_lock);
       }
     } else { //shared lock, check for any exclusive locks blocking us
       if (contains_exclusive_lock(overlapping_locks)) { //blocked :(
         ldout(cct,15) << " blocked by exclusive lock in overlapping_locks" << dendl;
-        if (wait_on_fail && !replay) {
-          waiting_locks.insert(pair<uint64_t, ceph_filelock>(new_lock.start, new_lock));
-        }
+	if (wait_on_fail && !replay) {
+	  if (is_deadlock(new_lock, overlapping_locks))
+	    *deadlock = true;
+	  else
+	    add_waiting(new_lock);
+	}
       } else {
         //yay, we can insert a shared lock
         ldout(cct,15) << "inserting shared lock" << dendl;
@@ -190,12 +302,37 @@ bool ceph_lock_state_t::remove_all_from (client_t client)
 {
   bool cleared_any = false;
   if (client_held_lock_counts.count(client)) {
-    remove_all_from(client, held_locks);
+    multimap<uint64_t, ceph_filelock>::iterator iter = held_locks.begin();
+    while (iter != held_locks.end()) {
+      if ((client_t)iter->second.client == client) {
+	held_locks.erase(iter++);
+      } else
+	++iter;
+    }
     client_held_lock_counts.erase(client);
     cleared_any = true;
   }
+
   if (client_waiting_lock_counts.count(client)) {
-    remove_all_from(client, waiting_locks);
+    multimap<uint64_t, ceph_filelock>::iterator iter = waiting_locks.begin();
+    while (iter != waiting_locks.end()) {
+      if ((client_t)iter->second.client != client) {
+	++iter;
+	continue;
+      }
+
+      for (auto p = global_waiting_locks.find(iter->second);
+	   p != global_waiting_locks.end(); ) {
+	if (p->first != iter->second)
+	  break;
+	if (p->second == this) {
+	  global_waiting_locks.erase(p);
+	  break;
+	}
+	++p;
+      }
+      waiting_locks.erase(iter++);
+    }
     client_waiting_lock_counts.erase(client);
   }
   return cleared_any;
@@ -328,18 +465,6 @@ void ceph_lock_state_t::adjust_locks(list<multimap<uint64_t, ceph_filelock>::ite
   }
 }
 
-void ceph_lock_state_t::remove_all_from(client_t client,
-                                        multimap<uint64_t,
-                                          ceph_filelock>& locks)
-{
-  multimap<uint64_t, ceph_filelock>::iterator iter = locks.begin();
-  while (iter != locks.end()) {
-    if ((client_t)iter->second.client == client) {
-      locks.erase(iter++);
-    } else ++iter;
-  }
-}
-
 multimap<uint64_t, ceph_filelock>::iterator
 ceph_lock_state_t::get_lower_bound(uint64_t start,
                                    multimap<uint64_t, ceph_filelock>& lock_map)
@@ -383,7 +508,7 @@ bool ceph_lock_state_t::share_space(
   return ret;
 }
 
-bool ceph_lock_state_t::get_overlapping_locks(ceph_filelock& lock,
+bool ceph_lock_state_t::get_overlapping_locks(const ceph_filelock& lock,
                            list<multimap<uint64_t,
                                ceph_filelock>::iterator> & overlaps,
                            list<multimap<uint64_t,
@@ -428,7 +553,7 @@ bool ceph_lock_state_t::get_overlapping_locks(ceph_filelock& lock,
   return !overlaps.empty();
 }
 
-bool ceph_lock_state_t::get_waiting_overlaps(ceph_filelock& lock,
+bool ceph_lock_state_t::get_waiting_overlaps(const ceph_filelock& lock,
                                              list<multimap<uint64_t,
                                                ceph_filelock>::iterator>&
                                                overlaps)
@@ -445,7 +570,7 @@ bool ceph_lock_state_t::get_waiting_overlaps(ceph_filelock& lock,
   return !overlaps.empty();
 }
 
-void ceph_lock_state_t::split_by_owner(ceph_filelock& owner,
+void ceph_lock_state_t::split_by_owner(const ceph_filelock& owner,
                                        list<multimap<uint64_t,
                                            ceph_filelock>::iterator>& locks,
                                        list<multimap<uint64_t,
diff --git a/src/mds/flock.h b/src/mds/flock.h
index 55ba2b8..fade1a8 100644
--- a/src/mds/flock.h
+++ b/src/mds/flock.h
@@ -9,7 +9,7 @@
 #include "mdstypes.h"
 
 
-inline ostream& operator<<(ostream& out, ceph_filelock& l) {
+inline ostream& operator<<(ostream& out, const ceph_filelock& l) {
   out << "start: " << l.start << ", length: " << l.length
       << ", client: " << l.client << ", owner: " << l.owner
       << ", pid: " << l.pid << ", type: " << (int)l.type
@@ -17,7 +17,7 @@ inline ostream& operator<<(ostream& out, ceph_filelock& l) {
   return out;
 }
 
-inline bool ceph_filelock_owner_equal(ceph_filelock& l, ceph_filelock& r)
+inline bool ceph_filelock_owner_equal(const ceph_filelock& l, const ceph_filelock& r)
 {
   if (l.client != r.client || l.owner != r.owner)
     return false;
@@ -29,17 +29,52 @@ inline bool ceph_filelock_owner_equal(ceph_filelock& l, ceph_filelock& r)
   return l.pid == r.pid;
 }
 
-inline bool operator==(ceph_filelock& l, ceph_filelock& r) {
-  return
-    l.length == r.length &&
-    l.type == r.type &&
-    ceph_filelock_owner_equal(l, r);
+inline int ceph_filelock_owner_compare(const ceph_filelock& l, const ceph_filelock& r)
+{
+  if (l.client != r.client)
+    return l.client > r.client ? 1 : -1;
+  if (l.owner != r.owner)
+    return l.owner > r.owner ? 1 : -1;
+  if (l.owner & (1ULL << 63))
+    return 0;
+  if (l.pid != r.pid)
+    return l.pid > r.pid ? 1 : -1;
+  return 0;
+}
+
+inline int ceph_filelock_compare(const ceph_filelock& l, const ceph_filelock& r)
+{
+  int ret = ceph_filelock_owner_compare(l, r);
+  if (ret)
+    return ret;
+  if (l.start != r.start)
+    return l.start > r.start ? 1 : -1;
+  if (l.length != r.length)
+    return l.length > r.length ? 1 : -1;
+  if (l.type != r.type)
+    return l.type > r.type ? 1 : -1;
+  return 0;
+}
+
+inline bool operator<(const ceph_filelock& l, const ceph_filelock& r)
+{
+  return ceph_filelock_compare(l, r) < 0;
+}
+
+inline bool operator==(const ceph_filelock& l, const ceph_filelock& r) {
+  return ceph_filelock_compare(l, r) == 0;
+}
+
+inline bool operator!=(const ceph_filelock& l, const ceph_filelock& r) {
+  return ceph_filelock_compare(l, r) != 0;
 }
 
 class ceph_lock_state_t {
   CephContext *cct;
+  int type;
 public:
-  explicit ceph_lock_state_t(CephContext *cct_) : cct(cct_) {}
+  explicit ceph_lock_state_t(CephContext *cct_, int type_) : cct(cct_), type(type_) {}
+  ~ceph_lock_state_t();
   multimap<uint64_t, ceph_filelock> held_locks;    // current locks
   multimap<uint64_t, ceph_filelock> waiting_locks; // locks waiting for other locks
   // both of the above are keyed by starting offset
@@ -52,14 +87,13 @@ public:
    * @param fl The filelock to check for
    * @returns True if the lock is waiting, false otherwise
    */
-  bool is_waiting(ceph_filelock &fl);
+  bool is_waiting(const ceph_filelock &fl);
   /**
    * Remove a lock from the waiting_locks list
    *
    * @param fl The filelock to remove
    */
-  void remove_waiting(ceph_filelock& fl);
-
+  void remove_waiting(const ceph_filelock& fl);
   /*
    * Try to set a new lock. If it's blocked and wait_on_fail is true,
    * add the lock to waiting_locks.
@@ -73,7 +107,8 @@ public:
    *
    * @returns true if set, false if not set.
    */
-  bool add_lock(ceph_filelock& new_lock, bool wait_on_fail, bool replay);
+  bool add_lock(ceph_filelock& new_lock, bool wait_on_fail, bool replay,
+		bool *deadlock);
   /**
    * See if a lock is blocked by existing locks. If the lock is blocked,
    * it will be set to the value of the first blocking lock. Otherwise,
@@ -91,11 +126,33 @@ public:
    * @param removal_lock The lock to remove
    * @param activated_locks A return parameter, holding activated wait locks.
    */
-  void remove_lock(ceph_filelock removal_lock,
+  void remove_lock(const ceph_filelock removal_lock,
                    list<ceph_filelock>& activated_locks);
 
   bool remove_all_from(client_t client);
 private:
+  static const unsigned MAX_DEADLK_DEPTH = 5;
+
+  /**
+   * Check if adding the lock causes deadlock
+   *
+   * @param fl The blocking filelock 
+   * @param overlapping_locks list of all overlapping locks 
+   * @param first_fl 
+   * @depth recursion call depth
+   */
+  bool is_deadlock(const ceph_filelock& fl,
+		   list<multimap<uint64_t, ceph_filelock>::iterator>&
+		      overlapping_locks,
+		   const ceph_filelock *first_fl=NULL, unsigned depth=0);
+
+  /**
+   * Add a lock to the waiting_locks list
+   *
+   * @param fl The filelock to add
+   */
+  void add_waiting(const ceph_filelock& fl);
+
   /**
    * Adjust old locks owned by a single process so that process can set
    * a new lock of different type. Handle any changes needed to the old locks
@@ -120,10 +177,6 @@ private:
                     list<multimap<uint64_t, ceph_filelock>::iterator>
                       neighbor_locks);
 
-  //this won't reset the counter map value, do that yourself
-  void remove_all_from(client_t client,
-                       multimap<uint64_t, ceph_filelock>& locks);
-
   //get last lock prior to start position
   multimap<uint64_t, ceph_filelock>::iterator
   get_lower_bound(uint64_t start,
@@ -143,7 +196,7 @@ private:
 		   uint64_t start, uint64_t end);
   
   bool share_space(multimap<uint64_t, ceph_filelock>::iterator& iter,
-                   ceph_filelock &lock) {
+                   const ceph_filelock &lock) {
     uint64_t end = lock.start;
     if (lock.length) {
       end += lock.length - 1;
@@ -158,14 +211,14 @@ private:
    * overlaps: an empty list, to be filled.
    * Returns: true if at least one lock overlaps.
    */
-  bool get_overlapping_locks(ceph_filelock& lock,
+  bool get_overlapping_locks(const ceph_filelock& lock,
                              list<multimap<uint64_t,
                                  ceph_filelock>::iterator> & overlaps,
                              list<multimap<uint64_t,
                                  ceph_filelock>::iterator> *self_neighbors);
 
   
-  bool get_overlapping_locks(ceph_filelock& lock,
+  bool get_overlapping_locks(const ceph_filelock& lock,
 			     list<multimap<uint64_t, ceph_filelock>::iterator>& overlaps) {
     return get_overlapping_locks(lock, overlaps, NULL);
   }
@@ -176,7 +229,7 @@ private:
    * overlaps: an empty list, to be filled
    * Returns: true if at least one waiting_lock overlaps
    */
-  bool get_waiting_overlaps(ceph_filelock& lock,
+  bool get_waiting_overlaps(const ceph_filelock& lock,
                             list<multimap<uint64_t,
                                 ceph_filelock>::iterator>& overlaps);
   /*
@@ -187,7 +240,7 @@ private:
    *        Will have all locks owned by owner removed
    * owned_locks: an empty list, to be filled with the locks owned by owner
    */
-  void split_by_owner(ceph_filelock& owner,
+  void split_by_owner(const ceph_filelock& owner,
 		      list<multimap<uint64_t,
 		          ceph_filelock>::iterator> & locks,
 		      list<multimap<uint64_t,
diff --git a/src/mds/journal.cc b/src/mds/journal.cc
index 406a929..64d4d2a 100644
--- a/src/mds/journal.cc
+++ b/src/mds/journal.cc
@@ -400,13 +400,13 @@ void EMetaBlob::update_segment(LogSegment *ls)
 
 // EMetaBlob::fullbit
 
-void EMetaBlob::fullbit::encode(bufferlist& bl) const {
+void EMetaBlob::fullbit::encode(bufferlist& bl, uint64_t features) const {
   ENCODE_START(8, 5, bl);
   ::encode(dn, bl);
   ::encode(dnfirst, bl);
   ::encode(dnlast, bl);
   ::encode(dnv, bl);
-  ::encode(inode, bl);
+  ::encode(inode, bl, features);
   ::encode(xattrs, bl);
   if (inode.is_symlink())
     ::encode(symlink, bl);
@@ -419,7 +419,7 @@ void EMetaBlob::fullbit::encode(bufferlist& bl) const {
     ::encode(false, bl);
   } else {
     ::encode(true, bl);
-    ::encode(old_inodes, bl);
+    ::encode(old_inodes, bl, features);
   }
   if (!inode.is_dir())
     ::encode(snapbl, bl);
@@ -559,6 +559,12 @@ void EMetaBlob::fullbit::update_inode(MDSRank *mds, CInode *in)
     in->symlink = symlink;
   }
   in->old_inodes = old_inodes;
+  if (!in->old_inodes.empty()) {
+    snapid_t min_first = in->old_inodes.rbegin()->first + 1;
+    if (min_first > in->first)
+      in->first = min_first;
+  }
+
   /*
    * we can do this before linking hte inode bc the split_at would
    * be a no-op.. we have no children (namely open snaprealms) to
@@ -677,7 +683,7 @@ void EMetaBlob::nullbit::generate_test_instances(list<nullbit*>& ls)
 
 // EMetaBlob::dirlump
 
-void EMetaBlob::dirlump::encode(bufferlist& bl) const
+void EMetaBlob::dirlump::encode(bufferlist& bl, uint64_t features) const
 {
   ENCODE_START(2, 2, bl);
   ::encode(fnode, bl);
@@ -685,7 +691,7 @@ void EMetaBlob::dirlump::encode(bufferlist& bl) const
   ::encode(nfull, bl);
   ::encode(nremote, bl);
   ::encode(nnull, bl);
-  _encode_bits();
+  _encode_bits(features);
   ::encode(dnbl, bl);
   ENCODE_FINISH(bl);
 }
@@ -751,12 +757,12 @@ void EMetaBlob::dirlump::generate_test_instances(list<dirlump*>& ls)
 /**
  * EMetaBlob proper
  */
-void EMetaBlob::encode(bufferlist& bl) const
+void EMetaBlob::encode(bufferlist& bl, uint64_t features) const
 {
   ENCODE_START(8, 5, bl);
   ::encode(lump_order, bl);
-  ::encode(lump_map, bl);
-  ::encode(roots, bl);
+  ::encode(lump_map, bl, features);
+  ::encode(roots, bl, features);
   ::encode(table_tids, bl);
   ::encode(opened_ino, bl);
   ::encode(allocated_ino, bl);
@@ -1274,8 +1280,8 @@ void EMetaBlob::replay(MDSRank *mds, LogSegment *logseg, MDSlaveUpdate *slaveup)
 	dir->link_primary_inode(dn, in);
 	dout(10) << "EMetaBlob.replay added " << *in << dendl;
       } else {
-	p->update_inode(mds, in);
 	in->first = p->dnfirst;
+	p->update_inode(mds, in);
 	if (dn->get_linkage()->get_inode() != in && in->get_parent_dn()) {
 	  dout(10) << "EMetaBlob.replay unlinking " << *in << dendl;
 	  unlinked[in] = in->get_parent_dir();
@@ -1696,7 +1702,7 @@ void ESession::replay(MDSRank *mds)
   update_segment();
 }
 
-void ESession::encode(bufferlist &bl) const
+void ESession::encode(bufferlist &bl, uint64_t features) const
 {
   ENCODE_START(4, 3, bl);
   ::encode(stamp, bl);
@@ -1748,7 +1754,7 @@ void ESession::generate_test_instances(list<ESession*>& ls)
 // -----------------------
 // ESessions
 
-void ESessions::encode(bufferlist &bl) const
+void ESessions::encode(bufferlist &bl, uint64_t features) const
 {
   ENCODE_START(1, 1, bl);
   ::encode(client_map, bl);
@@ -1819,7 +1825,7 @@ void ESessions::replay(MDSRank *mds)
 // -----------------------
 // ETableServer
 
-void ETableServer::encode(bufferlist& bl) const
+void ETableServer::encode(bufferlist& bl, uint64_t features) const
 {
   ENCODE_START(3, 3, bl);
   ::encode(stamp, bl);
@@ -1918,7 +1924,7 @@ void ETableServer::replay(MDSRank *mds)
 // ---------------------
 // ETableClient
 
-void ETableClient::encode(bufferlist& bl) const
+void ETableClient::encode(bufferlist& bl, uint64_t features) const
 {
   ENCODE_START(3, 3, bl);
   ::encode(stamp, bl);
@@ -2003,12 +2009,12 @@ void ESnap::replay(MDSRank *mds)
 // -----------------------
 // EUpdate
 
-void EUpdate::encode(bufferlist &bl) const
+void EUpdate::encode(bufferlist &bl, uint64_t features) const
 {
   ENCODE_START(4, 4, bl);
   ::encode(stamp, bl);
   ::encode(type, bl);
-  ::encode(metablob, bl);
+  ::encode(metablob, bl, features);
   ::encode(client_map, bl);
   ::encode(cmapv, bl);
   ::encode(reqid, bl);
@@ -2094,10 +2100,10 @@ void EUpdate::replay(MDSRank *mds)
 // ------------------------
 // EOpen
 
-void EOpen::encode(bufferlist &bl) const {
+void EOpen::encode(bufferlist &bl, uint64_t features) const {
   ENCODE_START(3, 3, bl);
   ::encode(stamp, bl);
-  ::encode(metablob, bl);
+  ::encode(metablob, bl, features);
   ::encode(inos, bl);
   ENCODE_FINISH(bl);
 } 
@@ -2169,7 +2175,7 @@ void ECommitted::replay(MDSRank *mds)
   }
 }
 
-void ECommitted::encode(bufferlist& bl) const
+void ECommitted::encode(bufferlist& bl, uint64_t features) const
 {
   ENCODE_START(3, 3, bl);
   ::encode(stamp, bl);
@@ -2380,7 +2386,7 @@ void rename_rollback::generate_test_instances(list<rename_rollback*>& ls)
   ls.back()->stray.remote_d_type = IFTODT(S_IFREG);
 }
 
-void ESlaveUpdate::encode(bufferlist &bl) const
+void ESlaveUpdate::encode(bufferlist &bl, uint64_t features) const
 {
   ENCODE_START(3, 3, bl);
   ::encode(stamp, bl);
@@ -2389,7 +2395,7 @@ void ESlaveUpdate::encode(bufferlist &bl) const
   ::encode(master, bl);
   ::encode(op, bl);
   ::encode(origop, bl);
-  ::encode(commit, bl);
+  ::encode(commit, bl, features);
   ::encode(rollback, bl);
   ENCODE_FINISH(bl);
 } 
@@ -2472,11 +2478,11 @@ void ESlaveUpdate::replay(MDSRank *mds)
 // -----------------------
 // ESubtreeMap
 
-void ESubtreeMap::encode(bufferlist& bl) const
+void ESubtreeMap::encode(bufferlist& bl, uint64_t features) const
 {
   ENCODE_START(6, 5, bl);
   ::encode(stamp, bl);
-  ::encode(metablob, bl);
+  ::encode(metablob, bl, features);
   ::encode(subtrees, bl);
   ::encode(ambiguous_subtrees, bl);
   ::encode(expire_pos, bl);
@@ -2716,14 +2722,14 @@ void EFragment::replay(MDSRank *mds)
     in->verify_dirfrags();
 }
 
-void EFragment::encode(bufferlist &bl) const {
+void EFragment::encode(bufferlist &bl, uint64_t features) const {
   ENCODE_START(5, 4, bl);
   ::encode(stamp, bl);
   ::encode(op, bl);
   ::encode(ino, bl);
   ::encode(basefrag, bl);
   ::encode(bits, bl);
-  ::encode(metablob, bl);
+  ::encode(metablob, bl, features);
   ::encode(orig_frags, bl);
   ::encode(rollback, bl);
   ENCODE_FINISH(bl);
@@ -2812,11 +2818,11 @@ void EExport::replay(MDSRank *mds)
   mds->mdcache->try_trim_non_auth_subtree(dir);
 }
 
-void EExport::encode(bufferlist& bl) const
+void EExport::encode(bufferlist& bl, uint64_t features) const
 {
   ENCODE_START(3, 3, bl);
   ::encode(stamp, bl);
-  ::encode(metablob, bl);
+  ::encode(metablob, bl, features);
   ::encode(base, bl);
   ::encode(bounds, bl);
   ENCODE_FINISH(bl);
@@ -2907,11 +2913,11 @@ void EImportStart::replay(MDSRank *mds)
   update_segment();
 }
 
-void EImportStart::encode(bufferlist &bl) const {
+void EImportStart::encode(bufferlist &bl, uint64_t features) const {
   ENCODE_START(3, 3, bl);
   ::encode(stamp, bl);
   ::encode(base, bl);
-  ::encode(metablob, bl);
+  ::encode(metablob, bl, features);
   ::encode(bounds, bl);
   ::encode(cmapv, bl);
   ::encode(client_map, bl);
@@ -2975,7 +2981,7 @@ void EImportFinish::replay(MDSRank *mds)
   }
 }
 
-void EImportFinish::encode(bufferlist& bl) const
+void EImportFinish::encode(bufferlist& bl, uint64_t features) const
 {
   ENCODE_START(3, 3, bl);
   ::encode(stamp, bl);
@@ -3010,7 +3016,7 @@ void EImportFinish::generate_test_instances(list<EImportFinish*>& ls)
 // ------------------------
 // EResetJournal
 
-void EResetJournal::encode(bufferlist& bl) const
+void EResetJournal::encode(bufferlist& bl, uint64_t features) const
 {
   ENCODE_START(2, 2, bl);
   ::encode(stamp, bl);
@@ -3055,7 +3061,7 @@ void EResetJournal::replay(MDSRank *mds)
 }
 
 
-void ENoOp::encode(bufferlist &bl) const
+void ENoOp::encode(bufferlist &bl, uint64_t features) const
 {
   ENCODE_START(2, 2, bl);
   ::encode(pad_size, bl);
diff --git a/src/mds/mdstypes.cc b/src/mds/mdstypes.cc
index 08879c3..066b26b 100644
--- a/src/mds/mdstypes.cc
+++ b/src/mds/mdstypes.cc
@@ -7,24 +7,6 @@
 const mds_gid_t MDS_GID_NONE = mds_gid_t(0);
 const mds_rank_t MDS_RANK_NONE = mds_rank_t(-1);
 
-void dump(const ceph_file_layout& l, Formatter *f)
-{
-  f->dump_unsigned("stripe_unit", l.fl_stripe_unit);
-  f->dump_unsigned("stripe_count", l.fl_stripe_count);
-  f->dump_unsigned("object_size", l.fl_object_size);
-  if (l.fl_cas_hash)
-    f->dump_unsigned("cas_hash", l.fl_cas_hash);
-  if (l.fl_object_stripe_unit)
-    f->dump_unsigned("object_stripe_unit", l.fl_object_stripe_unit);
-  if (l.fl_pg_pool)
-    f->dump_unsigned("pg_pool", l.fl_pg_pool);
-}
-
-void dump(const ceph_dir_layout& l, Formatter *f)
-{
-  f->dump_unsigned("dir_hash", l.dl_dir_hash);
-}
-
 
 /*
  * frag_info_t
@@ -254,7 +236,7 @@ void inline_data_t::decode(bufferlist::iterator &p)
 /*
  * inode_t
  */
-void inode_t::encode(bufferlist &bl) const
+void inode_t::encode(bufferlist &bl, uint64_t features) const
 {
   ENCODE_START(13, 6, bl);
 
@@ -274,7 +256,7 @@ void inode_t::encode(bufferlist &bl) const
   }
 
   ::encode(dir_layout, bl);
-  ::encode(layout, bl);
+  ::encode(layout, bl, features);
   ::encode(size, bl);
   ::encode(truncate_seq, bl);
   ::encode(truncate_size, bl);
@@ -399,9 +381,7 @@ void inode_t::dump(Formatter *f) const
   ::dump(dir_layout, f);
   f->close_section();
 
-  f->open_object_section("layout");
-  ::dump(layout, f);
-  f->close_section();
+  f->dump_object("layout", layout);
 
   f->open_array_section("old_pools");
   for (compact_set<int64_t>::const_iterator i = old_pools.begin();
@@ -468,7 +448,7 @@ int inode_t::compare(const inode_t &other, bool *divergent) const
         gid != other.gid ||
         nlink != other.nlink ||
         memcmp(&dir_layout, &other.dir_layout, sizeof(dir_layout)) ||
-        memcmp(&layout, &other.layout, sizeof(layout)) ||
+        layout != other.layout ||
         old_pools != other.old_pools ||
         size != other.size ||
         max_size_ever != other.max_size_ever ||
@@ -520,11 +500,11 @@ bool inode_t::older_is_consistent(const inode_t &other) const
 /*
  * old_inode_t
  */
-void old_inode_t::encode(bufferlist& bl) const
+void old_inode_t::encode(bufferlist& bl, uint64_t features) const
 {
   ENCODE_START(2, 2, bl);
   ::encode(first, bl);
-  ::encode(inode, bl);
+  ::encode(inode, bl, features);
   ::encode(xattrs, bl);
   ENCODE_FINISH(bl);
 }
@@ -1118,8 +1098,10 @@ void MDSCacheObject::dump_states(Formatter *f) const
     f->dump_string("state", "rejoinundef");
 }
 
-void ceph_file_layout_wrapper::dump(Formatter *f) const
+
+ostream& operator<<(ostream &out, const mds_role_t &role)
 {
-  ::dump(static_cast<const ceph_file_layout&>(*this), f);
+  out << role.fscid << ":" << role.rank;
+  return out;
 }
 
diff --git a/src/mds/mdstypes.h b/src/mds/mdstypes.h
index 4e1b926..e789856 100644
--- a/src/mds/mdstypes.h
+++ b/src/mds/mdstypes.h
@@ -21,6 +21,7 @@
 #include "include/interval_set.h"
 #include "include/compact_map.h"
 #include "include/compact_set.h"
+#include "include/fs_types.h"
 
 #include "inode_backtrace.h"
 
@@ -75,10 +76,46 @@
 
 
 typedef int32_t mds_rank_t;
+typedef int32_t fs_cluster_id_t;
+
+
+
 BOOST_STRONG_TYPEDEF(uint64_t, mds_gid_t)
 extern const mds_gid_t MDS_GID_NONE;
+constexpr fs_cluster_id_t FS_CLUSTER_ID_NONE = {-1};
+// The namespace ID of the anonymous default filesystem from legacy systems
+constexpr fs_cluster_id_t FS_CLUSTER_ID_ANONYMOUS = {0};
 extern const mds_rank_t MDS_RANK_NONE;
 
+class mds_role_t
+{
+  public:
+  mds_rank_t rank;
+  fs_cluster_id_t fscid;
+  mds_role_t(fs_cluster_id_t fscid_, mds_rank_t rank_)
+    : rank(rank_), fscid(fscid_)
+  {}
+  mds_role_t()
+    : rank(MDS_RANK_NONE), fscid(FS_CLUSTER_ID_NONE)
+  {}
+  bool operator<(mds_role_t const &rhs) const
+  {
+    if (fscid < rhs.fscid) {
+      return true;
+    } else if (fscid == rhs.fscid) {
+      return rank < rhs.rank;
+    } else {
+      return false;
+    }
+  }
+
+  bool is_none() const
+  {
+    return (rank == MDS_RANK_NONE);
+  }
+};
+std::ostream& operator<<(std::ostream &out, const mds_role_t &role);
+
 
 extern long g_num_ino, g_num_dir, g_num_dn, g_num_cap;
 extern long g_num_inoa, g_num_dira, g_num_dna, g_num_capa;
@@ -160,6 +197,12 @@ struct frag_info_t : public scatter_info_t {
     nsubdirs += other.nsubdirs;
   }
 
+  bool same_sums(const frag_info_t &o) const {
+    return mtime <= o.mtime &&
+	nfiles == o.nfiles &&
+	nsubdirs == o.nsubdirs;
+  }
+
   void encode(bufferlist &bl) const;
   void decode(bufferlist::iterator& bl);
   void dump(Formatter *f) const;
@@ -213,7 +256,7 @@ struct nest_info_t : public scatter_info_t {
   }
 
   bool same_sums(const nest_info_t &o) const {
-    return rctime == o.rctime &&
+    return rctime <= o.rctime &&
         rbytes == o.rbytes &&
         rfiles == o.rfiles &&
         rsubdirs == o.rsubdirs &&
@@ -438,7 +481,7 @@ struct inode_t {
 
   // file (data access)
   ceph_dir_layout  dir_layout;    // [dir only]
-  ceph_file_layout layout;
+  file_layout_t layout;
   compact_set <int64_t> old_pools;
   uint64_t   size;        // on directory, # dentries
   uint64_t   max_size_ever; // max size the file has ever been
@@ -505,20 +548,15 @@ struct inode_t {
   }
 
   bool has_layout() const {
-    // why on earth is there no converse of memchr() in string.h?
-    const char *p = (const char *)&layout;
-    for (size_t i = 0; i < sizeof(layout); i++)
-      if (p[i] != '\0')
-	return true;
-    return false;
+    return layout != file_layout_t();
   }
 
   void clear_layout() {
-    memset(&layout, 0, sizeof(layout));
+    layout = file_layout_t();
   }
 
   uint64_t get_layout_size_increment() {
-    return (uint64_t)layout.fl_object_size * (uint64_t)layout.fl_stripe_count;
+    return layout.get_period();
   }
 
   bool is_dirty_rstat() const { return !(rstat == accounted_rstat); }
@@ -565,7 +603,7 @@ struct inode_t {
     old_pools.insert(l);
   }
 
-  void encode(bufferlist &bl) const;
+  void encode(bufferlist &bl, uint64_t features) const;
   void decode(bufferlist::iterator& bl);
   void dump(Formatter *f) const;
   static void generate_test_instances(list<inode_t*>& ls);
@@ -585,7 +623,7 @@ struct inode_t {
 private:
   bool older_is_consistent(const inode_t &other) const;
 };
-WRITE_CLASS_ENCODER(inode_t)
+WRITE_CLASS_ENCODER_FEATURES(inode_t)
 
 
 /*
@@ -596,12 +634,12 @@ struct old_inode_t {
   inode_t inode;
   std::map<string,bufferptr> xattrs;
 
-  void encode(bufferlist &bl) const;
+  void encode(bufferlist &bl, uint64_t features) const;
   void decode(bufferlist::iterator& bl);
   void dump(Formatter *f) const;
   static void generate_test_instances(list<old_inode_t*>& ls);
 };
-WRITE_CLASS_ENCODER(old_inode_t)
+WRITE_CLASS_ENCODER_FEATURES(old_inode_t)
 
 
 /*
@@ -625,7 +663,7 @@ struct fnode_t {
   void decode(bufferlist::iterator& bl);
   void dump(Formatter *f) const;
   static void generate_test_instances(list<fnode_t*>& ls);
-  fnode_t() : version(0),
+  fnode_t() : version(0), damage_flags(0),
 	      recursive_scrub_version(0), localized_scrub_version(0) {}
 };
 WRITE_CLASS_ENCODER(fnode_t)
@@ -941,7 +979,7 @@ struct dirfrag_t {
 WRITE_CLASS_ENCODER(dirfrag_t)
 
 
-inline std::ostream& operator<<(std::ostream& out, const dirfrag_t df) {
+inline std::ostream& operator<<(std::ostream& out, const dirfrag_t &df) {
   out << df.ino;
   if (!df.frag.is_root()) out << "." << df.frag;
   return out;
@@ -1604,26 +1642,6 @@ inline std::ostream& operator<<(std::ostream& out, mdsco_db_line_prefix o) {
   return out;
 }
 
-class ceph_file_layout_wrapper : public ceph_file_layout
-{
-public:
-  void encode(bufferlist &bl) const
-  {
-    ::encode(static_cast<const ceph_file_layout&>(*this), bl);
-  }
-
-  void decode(bufferlist::iterator &p)
-  {
-    ::decode(static_cast<ceph_file_layout&>(*this), p);
-  }
-
-  static void generate_test_instances(std::list<ceph_file_layout_wrapper*>& ls)
-  {
-  }
-
-  void dump(Formatter *f) const;
-};
-
 // parse a map of keys/values.
 namespace qi = boost::spirit::qi;
 
diff --git a/src/messages/MClientCaps.h b/src/messages/MClientCaps.h
index 1b3f487..2fabbc7 100644
--- a/src/messages/MClientCaps.h
+++ b/src/messages/MClientCaps.h
@@ -20,12 +20,20 @@
 
 
 class MClientCaps : public Message {
-  static const int HEAD_VERSION = 7;
+  static const int HEAD_VERSION = 8;
   static const int COMPAT_VERSION = 1;
 
  public:
-  struct ceph_mds_caps head;
+  struct ceph_mds_caps_head head;
+
+  uint64_t size, max_size, truncate_size;
+  uint32_t truncate_seq;
+  utime_t mtime, atime, ctime;
+  file_layout_t layout;
+  uint32_t time_warp_seq;
+
   struct ceph_mds_cap_peer peer;
+
   bufferlist snapbl;
   bufferlist xattrbl;
   bufferlist flockbl;
@@ -49,16 +57,18 @@ class MClientCaps : public Message {
   inodeno_t get_realm() { return inodeno_t(head.realm); }
   uint64_t get_cap_id() { return head.cap_id; }
 
-  uint64_t get_size() { return head.size;  }
-  uint64_t get_max_size() { return head.max_size;  }
-  __u32 get_truncate_seq() { return head.truncate_seq; }
-  uint64_t get_truncate_size() { return head.truncate_size; }
-  utime_t get_ctime() { return utime_t(head.ctime); }
-  utime_t get_mtime() { return utime_t(head.mtime); }
-  utime_t get_atime() { return utime_t(head.atime); }
-  __u32 get_time_warp_seq() { return head.time_warp_seq; }
-
-  ceph_file_layout& get_layout() { return head.layout; }
+  uint64_t get_size() { return size;  }
+  uint64_t get_max_size() { return max_size;  }
+  __u32 get_truncate_seq() { return truncate_seq; }
+  uint64_t get_truncate_size() { return truncate_size; }
+  utime_t get_ctime() { return ctime; }
+  utime_t get_mtime() { return mtime; }
+  utime_t get_atime() { return atime; }
+  __u32 get_time_warp_seq() { return time_warp_seq; }
+
+  const file_layout_t& get_layout() {
+    return layout;
+  }
 
   int       get_migrate_seq() { return head.migrate_seq; }
   int       get_op() { return head.op; }
@@ -72,14 +82,15 @@ class MClientCaps : public Message {
   void set_caps(int c) { head.caps = c; }
   void set_wanted(int w) { head.wanted = w; }
 
-  void set_max_size(uint64_t ms) { head.max_size = ms; }
+  void set_max_size(uint64_t ms) { max_size = ms; }
 
   void set_migrate_seq(unsigned m) { head.migrate_seq = m; }
   void set_op(int o) { head.op = o; }
 
-  void set_size(loff_t s) { head.size = s; }
-  void set_mtime(const utime_t &t) { t.encode_timeval(&head.mtime); }
-  void set_atime(const utime_t &t) { t.encode_timeval(&head.atime); }
+  void set_size(loff_t s) { size = s; }
+  void set_mtime(const utime_t &t) { mtime = t; }
+  void set_ctime(const utime_t &t) { ctime = t; }
+  void set_atime(const utime_t &t) { atime = t; }
 
   void set_cap_peer(uint64_t id, ceph_seq_t seq, ceph_seq_t mseq, int mds, int flags) {
     peer.cap_id = id;
@@ -96,6 +107,11 @@ class MClientCaps : public Message {
 
   MClientCaps()
     : Message(CEPH_MSG_CLIENT_CAPS, HEAD_VERSION, COMPAT_VERSION),
+      size(0),
+      max_size(0),
+      truncate_size(0),
+      truncate_seq(0),
+      time_warp_seq(0),
       osd_epoch_barrier(0),
       oldest_flush_tid(0),
       caller_uid(0), caller_gid(0) {
@@ -112,6 +128,11 @@ class MClientCaps : public Message {
 	      int mseq,
               epoch_t oeb)
     : Message(CEPH_MSG_CLIENT_CAPS, HEAD_VERSION, COMPAT_VERSION),
+      size(0),
+      max_size(0),
+      truncate_size(0),
+      truncate_seq(0),
+      time_warp_seq(0),
       osd_epoch_barrier(oeb),
       oldest_flush_tid(0),
       caller_uid(0), caller_gid(0) {
@@ -132,6 +153,11 @@ class MClientCaps : public Message {
 	      inodeno_t ino, inodeno_t realm,
 	      uint64_t id, int mseq, epoch_t oeb)
     : Message(CEPH_MSG_CLIENT_CAPS, HEAD_VERSION, COMPAT_VERSION),
+      size(0),
+      max_size(0),
+      truncate_size(0),
+      truncate_seq(0),
+      time_warp_seq(0),
       osd_epoch_barrier(oeb),
       oldest_flush_tid(0),
       caller_uid(0), caller_gid(0) {
@@ -163,12 +189,12 @@ public:
     if (head.migrate_seq)
       out << " mseq " << head.migrate_seq;
 
-    out << " size " << head.size << "/" << head.max_size;
-    if (head.truncate_seq)
-      out << " ts " << head.truncate_seq;
-    out << " mtime " << utime_t(head.mtime);
-    if (head.time_warp_seq)
-      out << " tws " << head.time_warp_seq;
+    out << " size " << size << "/" << max_size;
+    if (truncate_seq)
+      out << " ts " << truncate_seq << "/" << truncate_size;
+    out << " mtime " << mtime;
+    if (time_warp_seq)
+      out << " tws " << time_warp_seq;
 
     if (head.xattr_version)
       out << " xattrs(v=" << head.xattr_version << " l=" << xattrbl.length() << ")";
@@ -179,6 +205,21 @@ public:
   void decode_payload() {
     bufferlist::iterator p = payload.begin();
     ::decode(head, p);
+    ceph_mds_caps_body_legacy body;
+    ::decode(body, p);
+    if (head.op == CEPH_CAP_OP_EXPORT) {
+      peer = body.peer;
+    } else {
+      size = body.size;
+      max_size = body.max_size;
+      truncate_size = body.truncate_size;
+      truncate_seq = body.truncate_seq;
+      mtime = utime_t(body.mtime);
+      atime = utime_t(body.atime);
+      ctime = utime_t(body.ctime);
+      layout.from_legacy(body.layout);
+      time_warp_seq = body.time_warp_seq;
+    }
     ::decode_nohead(head.snap_trace_len, snapbl, p);
 
     assert(middle.length() == head.xattr_len);
@@ -192,8 +233,6 @@ public:
     if (header.version >= 3) {
       if (head.op == CEPH_CAP_OP_IMPORT)
 	::decode(peer, p);
-      else if (head.op == CEPH_CAP_OP_EXPORT)
-	memcpy(&peer, &head.peer, sizeof(peer));
     }
 
     if (header.version >= 4) {
@@ -213,17 +252,31 @@ public:
       ::decode(caller_uid, p);
       ::decode(caller_gid, p);
     }
+    if (header.version >= 8) {
+      ::decode(layout.pool_ns, p);
+    }
   }
   void encode_payload(uint64_t features) {
     header.version = HEAD_VERSION;
     head.snap_trace_len = snapbl.length();
     head.xattr_len = xattrbl.length();
 
-    // record peer in unused fields of cap export message
-    if ((features & CEPH_FEATURE_EXPORT_PEER) && head.op == CEPH_CAP_OP_EXPORT)
-      memcpy(&head.peer, &peer, sizeof(peer));
-
     ::encode(head, payload);
+    ceph_mds_caps_body_legacy body;
+    if (head.op == CEPH_CAP_OP_EXPORT) {
+      body.peer = peer;
+    } else {
+      body.size = size;
+      body.max_size = max_size;
+      body.truncate_size = truncate_size;
+      body.truncate_seq = truncate_seq;
+      mtime.encode_timeval(&body.mtime);
+      atime.encode_timeval(&body.atime);
+      ctime.encode_timeval(&body.ctime);
+      layout.to_legacy(&body.layout);
+      body.time_warp_seq = time_warp_seq;
+    }
+    ::encode(body, payload);
     ::encode_nohead(snapbl, payload);
 
     middle = xattrbl;
@@ -256,6 +309,8 @@ public:
     ::encode(oldest_flush_tid, payload);
     ::encode(caller_uid, payload);
     ::encode(caller_gid, payload);
+
+    ::encode(layout.pool_ns, payload);
   }
 };
 
diff --git a/src/messages/MClientReply.h b/src/messages/MClientReply.h
index d3ee05e..81e1cf2 100644
--- a/src/messages/MClientReply.h
+++ b/src/messages/MClientReply.h
@@ -17,6 +17,7 @@
 #define CEPH_MCLIENTREPLY_H
 
 #include "include/types.h"
+#include "include/fs_types.h"
 #include "MClientRequest.h"
 
 #include "msg/Message.h"
@@ -96,32 +97,31 @@ struct DirStat {
 
 struct InodeStat {
   vinodeno_t vino;
+  uint32_t rdev;
   version_t version;
+  version_t xattr_version;
   ceph_mds_reply_cap cap;
-
-  ceph_file_layout layout;
-  unsigned mode, uid, gid, nlink, rdev;
-  loff_t size, max_size;
-  version_t truncate_seq;
-  uint64_t truncate_size;
+  file_layout_t layout;
   utime_t ctime, mtime, atime;
-  version_t time_warp_seq;
-  bufferlist inline_data;
-  version_t inline_version;
-
+  uint32_t time_warp_seq;
+  uint64_t size, max_size;
+  uint64_t truncate_size;
+  uint32_t truncate_seq;
+  uint32_t mode, uid, gid, nlink;
   frag_info_t dirstat;
   nest_info_t rstat;
-  
-  string  symlink;   // symlink content (if symlink)
+
   fragtree_t dirfragtree;
+  string  symlink;   // symlink content (if symlink)
+
+  ceph_dir_layout dir_layout;
 
-  version_t xattr_version;
   bufferlist xattrbl;
 
-  ceph_dir_layout dir_layout;
+  bufferlist inline_data;
+  version_t inline_version;
 
   quota_info_t quota;
-  //map<string, bufferptr> xattrs;
 
  public:
   InodeStat() {}
@@ -130,36 +130,37 @@ struct InodeStat {
   }
 
   void decode(bufferlist::iterator &p, uint64_t features) {
-    struct ceph_mds_reply_inode e;
-    ::decode(e, p);
-    vino.ino = inodeno_t(e.ino);
-    vino.snapid = snapid_t(e.snapid);
-    version = e.version;
-    layout = e.layout;
-    cap = e.cap;
-    size = e.size;
-    max_size = e.max_size;
-    truncate_seq = e.truncate_seq;
-    truncate_size = e.truncate_size;
-    ctime.decode_timeval(&e.ctime);
-    mtime.decode_timeval(&e.mtime);
-    atime.decode_timeval(&e.atime);
-    time_warp_seq = e.time_warp_seq;
-    mode = e.mode;
-    uid = e.uid;
-    gid = e.gid;
-    nlink = e.nlink;
-    rdev = e.rdev;
-
-    dirstat.nfiles = e.files;
-    dirstat.nsubdirs = e.subdirs;
-
-    rstat.rctime.decode_timeval(&e.rctime);
-    rstat.rbytes = e.rbytes;
-    rstat.rfiles = e.rfiles;
-    rstat.rsubdirs = e.rsubdirs;
-
-    dirfragtree.decode_nohead(e.fragtree.nsplits, p);
+    ::decode(vino.ino, p);
+    ::decode(vino.snapid, p);
+    ::decode(rdev, p);
+    ::decode(version, p);
+    ::decode(xattr_version, p);
+    ::decode(cap, p);
+    {
+      ceph_file_layout legacy_layout;
+      ::decode(legacy_layout, p);
+      layout.from_legacy(legacy_layout);
+    }
+    ::decode(ctime, p);
+    ::decode(mtime, p);
+    ::decode(atime, p);
+    ::decode(time_warp_seq, p);
+    ::decode(size, p);
+    ::decode(max_size, p);
+    ::decode(truncate_size, p);
+    ::decode(truncate_seq, p);
+    ::decode(mode, p);
+    ::decode(uid, p);
+    ::decode(gid, p);
+    ::decode(nlink, p);
+    ::decode(dirstat.nfiles, p);
+    ::decode(dirstat.nsubdirs, p);
+    ::decode(rstat.rbytes, p);
+    ::decode(rstat.rfiles, p);
+    ::decode(rstat.rsubdirs, p);
+    ::decode(rstat.rctime, p);
+
+    ::decode(dirfragtree, p);
 
     ::decode(symlink, p);
     
@@ -168,7 +169,6 @@ struct InodeStat {
     else
       memset(&dir_layout, 0, sizeof(dir_layout));
 
-    xattr_version = e.xattr_version;
     ::decode(xattrbl, p);
 
     if (features & CEPH_FEATURE_MDS_INLINE_DATA) {
@@ -182,6 +182,9 @@ struct InodeStat {
       ::decode(quota, p);
     else
       memset(&quota, 0, sizeof(quota));
+
+    if ((features & CEPH_FEATURE_FS_FILE_LAYOUT_V2))
+      ::decode(layout.pool_ns, p);
   }
   
   // see CInode::encode_inodestat for encoder.
diff --git a/src/messages/MFSMap.h b/src/messages/MFSMap.h
new file mode 100644
index 0000000..dd886b5
--- /dev/null
+++ b/src/messages/MFSMap.h
@@ -0,0 +1,59 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- 
+// vim: ts=8 sw=2 smarttab
+/*
+ * Ceph - scalable distributed file system
+ *
+ * Copyright (C) 2004-2006 Sage Weil <sage at newdream.net>
+ *
+ * This is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software 
+ * Foundation.  See file COPYING.
+ * 
+ */
+
+
+#ifndef CEPH_MFSMAP_H
+#define CEPH_MFSMAP_H
+
+#include "msg/Message.h"
+#include "mds/FSMap.h"
+#include "include/ceph_features.h"
+
+class MFSMap : public Message {
+ public:
+  epoch_t epoch;
+  bufferlist encoded;
+
+  version_t get_epoch() const { return epoch; }
+  bufferlist& get_encoded() { return encoded; }
+
+  MFSMap() : 
+    Message(CEPH_MSG_FS_MAP), epoch(0) {}
+  MFSMap(const uuid_d &f, FSMap *fsmap) :
+    Message(CEPH_MSG_FS_MAP), epoch(fsmap->get_epoch())
+  {
+    fsmap->encode(encoded, -1);
+  }
+private:
+  ~MFSMap() {}
+
+public:
+  const char *get_type_name() const { return "mdsmap"; }
+  void print(ostream& out) const {
+    out << "fsmap(e " << epoch << ")";
+  }
+
+  // marshalling
+  void decode_payload() {
+    bufferlist::iterator p = payload.begin();
+    ::decode(epoch, p);
+    ::decode(encoded, p);
+  }
+  void encode_payload(uint64_t features) {
+    ::encode(epoch, payload);
+    ::encode(encoded, payload);
+  }
+};
+
+#endif
diff --git a/src/messages/MMDSBeacon.h b/src/messages/MMDSBeacon.h
index e04fe37..d932f8a 100644
--- a/src/messages/MMDSBeacon.h
+++ b/src/messages/MMDSBeacon.h
@@ -37,6 +37,7 @@ enum mds_metric_t {
   MDS_HEALTH_CLIENT_LATE_RELEASE_MANY,
   MDS_HEALTH_CLIENT_OLDEST_TID,
   MDS_HEALTH_CLIENT_OLDEST_TID_MANY,
+  MDS_HEALTH_DAMAGE
 };
 
 /**
@@ -120,7 +121,7 @@ WRITE_CLASS_ENCODER(MDSHealth)
 
 class MMDSBeacon : public PaxosServiceMessage {
 
-  static const int HEAD_VERSION = 4;
+  static const int HEAD_VERSION = 5;
   static const int COMPAT_VERSION = 2;
 
   uuid_d fsid;
@@ -138,12 +139,15 @@ class MMDSBeacon : public PaxosServiceMessage {
 
   map<string, string> sys_info;
 
+  uint64_t mds_features;
+
  public:
   MMDSBeacon() : PaxosServiceMessage(MSG_MDS_BEACON, 0, HEAD_VERSION, COMPAT_VERSION) { }
-  MMDSBeacon(const uuid_d &f, mds_gid_t g, string& n, epoch_t les, MDSMap::DaemonState st, version_t se) : 
+  MMDSBeacon(const uuid_d &f, mds_gid_t g, string& n, epoch_t les, MDSMap::DaemonState st, version_t se, uint64_t feat) :
     PaxosServiceMessage(MSG_MDS_BEACON, les, HEAD_VERSION, COMPAT_VERSION),
     fsid(f), global_id(g), name(n), state(st), seq(se),
-    standby_for_rank(MDS_RANK_NONE) {
+    standby_for_rank(MDS_RANK_NONE),
+    mds_features(feat) {
   }
 private:
   ~MMDSBeacon() {}
@@ -158,6 +162,7 @@ public:
   const char *get_type_name() const { return "mdsbeacon"; }
   mds_rank_t get_standby_for_rank() { return standby_for_rank; }
   const string& get_standby_for_name() { return standby_for_name; }
+  uint64_t get_mds_features() const { return mds_features; }
 
   CompatSet const& get_compat() const { return compat; }
   void set_compat(const CompatSet& c) { compat = c; }
@@ -191,6 +196,7 @@ public:
     if (state == MDSMap::STATE_BOOT) {
       ::encode(sys_info, payload);
     }
+    ::encode(mds_features, payload);
   }
   void decode_payload() {
     bufferlist::iterator p = payload.begin();
@@ -211,6 +217,9 @@ public:
 	header.version >= 4) {
       ::decode(sys_info, p);
     }
+    if (header.version >= 5) {
+      ::decode(mds_features, p);
+    }
   }
 };
 
diff --git a/src/messages/MMDSCacheRejoin.h b/src/messages/MMDSCacheRejoin.h
index 979fe9a..111a244 100644
--- a/src/messages/MMDSCacheRejoin.h
+++ b/src/messages/MMDSCacheRejoin.h
@@ -224,11 +224,11 @@ public:
     ::encode(nonce, inode_locks);
     ::encode(bl, inode_locks);
   }
-  void add_inode_base(CInode *in) {
+  void add_inode_base(CInode *in, uint64_t features) {
     ::encode(in->inode.ino, inode_base);
     ::encode(in->last, inode_base);
     bufferlist bl;
-    in->_encode_base(bl);
+    in->_encode_base(bl, features);
     ::encode(bl, inode_base);
   }
   void add_inode_authpin(vinodeno_t ino, const metareqid_t& ri, __u32 attempt) {
diff --git a/src/messages/MMonGetVersionReply.h b/src/messages/MMonGetVersionReply.h
index b13b2f0..5b05276 100644
--- a/src/messages/MMonGetVersionReply.h
+++ b/src/messages/MMonGetVersionReply.h
@@ -32,11 +32,11 @@ public:
   MMonGetVersionReply() : Message(CEPH_MSG_MON_GET_VERSION_REPLY, HEAD_VERSION) { }
 
   const char *get_type_name() const {
-    return "mon_check_map_ack";
+    return "mon_get_version_reply";
   }
 
   void print(ostream& o) const {
-    o << "mon_check_map_ack(handle=" << handle << " version=" << version << ")";
+    o << "mon_get_version_reply(handle=" << handle << " version=" << version << ")";
   }
 
   void encode_payload(uint64_t features) {
diff --git a/src/messages/MMonPaxos.h b/src/messages/MMonPaxos.h
index b8a9d37..00af419 100644
--- a/src/messages/MMonPaxos.h
+++ b/src/messages/MMonPaxos.h
@@ -90,10 +90,7 @@ public:
   }
 
   void encode_payload(uint64_t features) {
-    if ((features & CEPH_FEATURE_MONCLOCKCHECK) == 0)
-      header.version = 0;
-    else
-      header.version = HEAD_VERSION;
+    header.version = HEAD_VERSION;
     ::encode(epoch, payload);
     ::encode(op, payload);
     ::encode(first_committed, payload);
@@ -102,8 +99,7 @@ public:
     ::encode(pn, payload);
     ::encode(uncommitted_pn, payload);
     ::encode(lease_timestamp, payload);
-    if (features & CEPH_FEATURE_MONCLOCKCHECK)
-      ::encode(sent_timestamp, payload);
+    ::encode(sent_timestamp, payload);
     ::encode(latest_version, payload);
     ::encode(latest_value, payload);
     ::encode(values, payload);
diff --git a/src/messages/MOSDPGUpdateLogMissing.h b/src/messages/MOSDPGUpdateLogMissing.h
new file mode 100644
index 0000000..35f3311
--- /dev/null
+++ b/src/messages/MOSDPGUpdateLogMissing.h
@@ -0,0 +1,82 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+/*
+ * Ceph - scalable distributed file system
+ *
+ * Copyright (C) 2004-2006 Sage Weil <sage at newdream.net>
+ *
+ * This is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software
+ * Foundation.  See file COPYING.
+ *
+ */
+
+
+#ifndef CEPH_MOSDPGUPDATELOGMISSING_H
+#define CEPH_MOSDPGUPDATELOGMISSING_H
+
+#include "msg/Message.h"
+
+class MOSDPGUpdateLogMissing : public Message {
+
+  static const int HEAD_VERSION = 1;
+  static const int COMPAT_VERSION = 1;
+
+
+public:
+  epoch_t map_epoch;
+  spg_t pgid;
+  shard_id_t from;
+  ceph_tid_t rep_tid;
+  list<pg_log_entry_t> entries;
+
+  epoch_t get_epoch() const { return map_epoch; }
+  spg_t get_pgid() const { return pgid; }
+  epoch_t get_query_epoch() const { return map_epoch; }
+  ceph_tid_t get_tid() const { return rep_tid; }
+
+  MOSDPGUpdateLogMissing() :
+    Message(MSG_OSD_PG_UPDATE_LOG_MISSING, HEAD_VERSION, COMPAT_VERSION) { }
+  MOSDPGUpdateLogMissing(
+    const list<pg_log_entry_t> &entries,
+    spg_t pgid,
+    shard_id_t from,
+    epoch_t epoch,
+    ceph_tid_t rep_tid)
+    : Message(MSG_OSD_PG_UPDATE_LOG_MISSING, HEAD_VERSION, COMPAT_VERSION),
+      map_epoch(epoch),
+      pgid(pgid),
+      from(from),
+      rep_tid(rep_tid),
+      entries(entries) {}
+
+private:
+  ~MOSDPGUpdateLogMissing() {}
+
+public:
+  const char *get_type_name() const { return "PGUpdateLogMissing"; }
+  void print(ostream& out) const {
+    out << "pg_update_log_missing(" << pgid << " epoch " << map_epoch
+	<< " rep_tid " << rep_tid
+	<< " entries " << entries << ")";
+  }
+
+  void encode_payload(uint64_t features) {
+    ::encode(map_epoch, payload);
+    ::encode(pgid, payload);
+    ::encode(from, payload);
+    ::encode(rep_tid, payload);
+    ::encode(entries, payload);
+  }
+  void decode_payload() {
+    bufferlist::iterator p = payload.begin();
+    ::decode(map_epoch, p);
+    ::decode(pgid, p);
+    ::decode(from, p);
+    ::decode(rep_tid, p);
+    ::decode(entries, p);
+  }
+};
+
+#endif
diff --git a/src/messages/MOSDPGUpdateLogMissingReply.h b/src/messages/MOSDPGUpdateLogMissingReply.h
new file mode 100644
index 0000000..d6ff140
--- /dev/null
+++ b/src/messages/MOSDPGUpdateLogMissingReply.h
@@ -0,0 +1,87 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+/*
+ * Ceph - scalable distributed file system
+ *
+ * Copyright (C) 2004-2006 Sage Weil <sage at newdream.net>
+ *
+ * This is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software
+ * Foundation.  See file COPYING.
+ *
+ */
+
+
+#ifndef CEPH_MOSDPGUPDATELOGMISSINGREPLY_H
+#define CEPH_MOSDPGUPDATELOGMISSINGREPLY_H
+
+#include "msg/Message.h"
+
+class MOSDPGUpdateLogMissingReply : public Message {
+
+  static const int HEAD_VERSION = 1;
+  static const int COMPAT_VERSION = 1;
+
+
+public:
+  epoch_t map_epoch;
+  spg_t pgid;
+  shard_id_t from;
+  ceph_tid_t rep_tid;
+
+  epoch_t get_epoch() const { return map_epoch; }
+  spg_t get_pgid() const { return pgid; }
+  epoch_t get_query_epoch() const { return map_epoch; }
+  ceph_tid_t get_tid() const { return rep_tid; }
+  pg_shard_t get_from() const {
+    return pg_shard_t(get_source().num(), from);
+  }
+
+  MOSDPGUpdateLogMissingReply() :
+    Message(
+      MSG_OSD_PG_UPDATE_LOG_MISSING_REPLY,
+      HEAD_VERSION,
+      COMPAT_VERSION)
+      {}
+  MOSDPGUpdateLogMissingReply(
+    spg_t pgid,
+    shard_id_t from,
+    epoch_t epoch,
+    ceph_tid_t rep_tid)
+    : Message(
+        MSG_OSD_PG_UPDATE_LOG_MISSING_REPLY,
+        HEAD_VERSION,
+        COMPAT_VERSION),
+      map_epoch(epoch),
+      pgid(pgid),
+      from(from),
+      rep_tid(rep_tid)
+    {}
+
+private:
+  ~MOSDPGUpdateLogMissingReply() {}
+
+public:
+  const char *get_type_name() const { return "PGUpdateLogMissingReply"; }
+  void print(ostream& out) const {
+    out << "pg_update_log_missing_reply(" << pgid << " epoch " << map_epoch
+	<< " rep_tid " << rep_tid << ")";
+  }
+
+  void encode_payload(uint64_t features) {
+    ::encode(map_epoch, payload);
+    ::encode(pgid, payload);
+    ::encode(from, payload);
+    ::encode(rep_tid, payload);
+  }
+  void decode_payload() {
+    bufferlist::iterator p = payload.begin();
+    ::decode(map_epoch, p);
+    ::decode(pgid, p);
+    ::decode(from, p);
+    ::decode(rep_tid, p);
+  }
+};
+
+#endif
diff --git a/src/messages/MRoute.h b/src/messages/MRoute.h
index 109574e..a31243c 100644
--- a/src/messages/MRoute.h
+++ b/src/messages/MRoute.h
@@ -73,13 +73,6 @@ public:
   void encode_payload(uint64_t features) {
     ::encode(session_mon_tid, payload);
     ::encode(dest, payload);
-    if ((features & CEPH_FEATURE_MON_NULLROUTE) == 0) {
-      header.version = 1;
-      header.compat_version = 1;
-      assert(msg);
-      encode_message(msg, features, payload);
-      return;
-    }
     bool m = msg ? true : false;
     ::encode(m, payload);
     if (msg)
diff --git a/src/messages/Makefile.am b/src/messages/Makefile.am
index d3f0251..0a19dad 100644
--- a/src/messages/Makefile.am
+++ b/src/messages/Makefile.am
@@ -48,6 +48,7 @@ noinst_HEADERS += \
 	messages/MMDSFindInoReply.h \
 	messages/MMDSFragmentNotify.h \
 	messages/MMDSMap.h \
+	messages/MFSMap.h \
 	messages/MMDSOpenIno.h \
 	messages/MMDSOpenInoReply.h \
 	messages/MMDSResolve.h \
@@ -91,6 +92,8 @@ noinst_HEADERS += \
 	messages/MOSDPGQuery.h \
 	messages/MOSDPGRemove.h \
 	messages/MOSDPGScan.h \
+	messages/MOSDPGUpdateLogMissing.h \
+	messages/MOSDPGUpdateLogMissingReply.h \
 	messages/MOSDECSubOpWrite.h \
 	messages/MOSDECSubOpWriteReply.h \
 	messages/MOSDECSubOpRead.h \
diff --git a/src/mon/AuthMonitor.cc b/src/mon/AuthMonitor.cc
index 8f217fb..10003a1 100644
--- a/src/mon/AuthMonitor.cc
+++ b/src/mon/AuthMonitor.cc
@@ -537,6 +537,7 @@ bool AuthMonitor::preprocess_command(MonOpRequestRef op)
   cmd_getval(g_ceph_context, cmdmap, "prefix", prefix);
   if (prefix == "auth add" ||
       prefix == "auth del" ||
+      prefix == "auth rm" ||
       prefix == "auth get-or-create" ||
       prefix == "auth get-or-create-key" ||
       prefix == "auth import" ||
@@ -990,7 +991,8 @@ bool AuthMonitor::prepare_command(MonOpRequestRef op)
     wait_for_finished_proposal(op, new Monitor::C_Command(mon, op, 0, rs,
 					      get_last_committed() + 1));
     return true;
-  } else if (prefix == "auth del" && !entity_name.empty()) {
+  } else if ((prefix == "auth del" || prefix == "auto rm") &&
+             !entity_name.empty()) {
     KeyServerData::Incremental auth_inc;
     auth_inc.name = entity;
     if (!mon->key_server.contains(auth_inc.name)) {
diff --git a/src/mon/ConfigKeyService.cc b/src/mon/ConfigKeyService.cc
index c4cab9e..59798f2 100644
--- a/src/mon/ConfigKeyService.cc
+++ b/src/mon/ConfigKeyService.cc
@@ -160,7 +160,8 @@ bool ConfigKeyService::service_dispatch(MonOpRequestRef op)
     // return for now; we'll put the message once it's done.
     return true;
 
-  } else if (prefix == "config-key del") {
+  } else if (prefix == "config-key del" ||
+             prefix == "config-key rm") {
     if (!mon->is_leader()) {
       mon->forward_request_leader(op);
       return true;
diff --git a/src/mon/LogMonitor.cc b/src/mon/LogMonitor.cc
index 5aa66e2..391a338 100644
--- a/src/mon/LogMonitor.cc
+++ b/src/mon/LogMonitor.cc
@@ -26,6 +26,7 @@
 #include "messages/MLogAck.h"
 
 #include "common/Timer.h"
+#include "common/Graylog.h"
 
 #include "osd/osd_types.h"
 #include "common/errno.h"
@@ -743,6 +744,32 @@ bool LogMonitor::log_channel_info::do_log_to_syslog(const string &channel) {
   return ret;
 }
 
+ceph::log::Graylog::Ref LogMonitor::log_channel_info::get_graylog(
+    const string &channel)
+{
+  generic_dout(25) << __func__ << " for channel '"
+		   << channel << "'" << dendl;
+
+  if (graylogs.count(channel) == 0) {
+    ceph::log::Graylog::Ref graylog = ceph::log::Graylog::Ref(new ceph::log::Graylog("mon"));
+
+    graylog->set_fsid(g_conf->fsid);
+    graylog->set_hostname(g_conf->host);
+    graylog->set_destination(get_str_map_key(log_to_graylog_host, channel,
+					     &CLOG_CONFIG_DEFAULT_KEY),
+			     atoi(get_str_map_key(log_to_graylog_port, channel,
+						  &CLOG_CONFIG_DEFAULT_KEY).c_str()));
+
+    graylogs[channel] = graylog;
+    generic_dout(20) << __func__ << " for channel '"
+		     << channel << "' to graylog host '"
+		     << log_to_graylog_host[channel] << ":"
+		     << log_to_graylog_port[channel]
+		     << "'" << dendl;
+  }
+  return graylogs[channel];
+}
+
 void LogMonitor::handle_conf_change(const struct md_config_t *conf,
                                     const std::set<std::string> &changed)
 {
diff --git a/src/mon/LogMonitor.h b/src/mon/LogMonitor.h
index d2e3a4a..678c5ff 100644
--- a/src/mon/LogMonitor.h
+++ b/src/mon/LogMonitor.h
@@ -25,12 +25,17 @@ using namespace std;
 
 #include "common/LogEntry.h"
 #include "messages/MLog.h"
-#include "common/Graylog.h"
 
 class MMonCommand;
 
 static const string LOG_META_CHANNEL = "$channel";
 
+namespace ceph {
+namespace log {
+  class Graylog;
+}
+}
+
 class LogMonitor : public PaxosService,
                    public md_config_obs_t {
 private:
@@ -49,7 +54,7 @@ private:
     map<string,string> log_to_graylog_host;
     map<string,string> log_to_graylog_port;
 
-    map<string, ceph::log::Graylog::Ref> graylogs;
+    map<string, shared_ptr<ceph::log::Graylog>> graylogs;
     uuid_d fsid;
     string host;
 
@@ -120,29 +125,7 @@ private:
 			      &CLOG_CONFIG_DEFAULT_KEY) == "true");
     }
 
-    ceph::log::Graylog::Ref get_graylog(const string &channel) {
-      generic_dout(25) << __func__ << " for channel '"
-                       << channel << "'" << dendl;
-
-      if (graylogs.count(channel) == 0) {
-	ceph::log::Graylog::Ref graylog = ceph::log::Graylog::Ref(new ceph::log::Graylog("mon"));
-
-	graylog->set_fsid(g_conf->fsid);
-	graylog->set_hostname(g_conf->host);
-	graylog->set_destination(get_str_map_key(log_to_graylog_host, channel,
-						 &CLOG_CONFIG_DEFAULT_KEY),
-				 atoi(get_str_map_key(log_to_graylog_port, channel,
-						      &CLOG_CONFIG_DEFAULT_KEY).c_str()));
-
-	graylogs[channel] = graylog;
-        generic_dout(20) << __func__ << " for channel '"
-                         << channel << "' to graylog host '"
-			 << log_to_graylog_host[channel] << ":"
-			 << log_to_graylog_port[channel]
-			 << "'" << dendl;
-      }
-      return graylogs[channel];
-    }
+    shared_ptr<ceph::log::Graylog> get_graylog(const string &channel);
   } channels;
 
   void update_log_channels();
diff --git a/src/mon/MDSMonitor.cc b/src/mon/MDSMonitor.cc
index 79d1500..92322e0 100644
--- a/src/mon/MDSMonitor.cc
+++ b/src/mon/MDSMonitor.cc
@@ -1,4 +1,4 @@
-// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- 
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
 // vim: ts=8 sw=2 smarttab
 /*
  * Ceph - scalable distributed file system
@@ -28,6 +28,7 @@
 #include "common/cmdparse.h"
 
 #include "messages/MMDSMap.h"
+#include "messages/MFSMap.h"
 #include "messages/MMDSBeacon.h"
 #include "messages/MMDSLoadTargets.h"
 #include "messages/MMonCommand.h"
@@ -40,14 +41,13 @@
 
 #define dout_subsys ceph_subsys_mon
 #undef dout_prefix
-#define dout_prefix _prefix(_dout, mon, mdsmap)
-static ostream& _prefix(std::ostream *_dout, Monitor *mon, MDSMap const& mdsmap) {
+#define dout_prefix _prefix(_dout, mon, fsmap)
+static ostream& _prefix(std::ostream *_dout, Monitor *mon, FSMap const& fsmap) {
   return *_dout << "mon." << mon->name << "@" << mon->rank
 		<< "(" << mon->get_state_name()
-		<< ").mds e" << mdsmap.get_epoch() << " ";
+		<< ").mds e" << fsmap.get_epoch() << " ";
 }
 
-
 /*
  * Specialized implementation of cmd_getval to allow us to parse
  * out strongly-typedef'd types
@@ -75,29 +75,49 @@ static const string MDS_METADATA_PREFIX("mds_metadata");
 
 // my methods
 
-void MDSMonitor::print_map(MDSMap &m, int dbl)
+void MDSMonitor::print_map(FSMap &m, int dbl)
 {
   dout(dbl) << "print_map\n";
   m.print(*_dout);
   *_dout << dendl;
 }
 
-void MDSMonitor::create_new_fs(MDSMap &m, const std::string &name, int metadata_pool, int data_pool)
+void MDSMonitor::create_new_fs(FSMap &fsm, const std::string &name,
+    int metadata_pool, int data_pool)
 {
-  m.enabled = true;
-  m.fs_name = name;
-  m.max_mds = g_conf->max_mds;
-  m.created = ceph_clock_now(g_ceph_context);
-  m.data_pools.insert(data_pool);
-  m.metadata_pool = metadata_pool;
-  m.cas_pool = -1;
-  m.compat = get_mdsmap_compat_set_default();
-
-  m.session_timeout = g_conf->mds_session_timeout;
-  m.session_autoclose = g_conf->mds_session_autoclose;
-  m.max_file_size = g_conf->mds_max_file_size;
-
-  print_map(m);
+  auto fs = std::make_shared<Filesystem>();
+  fs->mds_map.fs_name = name;
+  fs->mds_map.max_mds = g_conf->max_mds;
+  fs->mds_map.data_pools.insert(data_pool);
+  fs->mds_map.metadata_pool = metadata_pool;
+  fs->mds_map.cas_pool = -1;
+  fs->mds_map.max_file_size = g_conf->mds_max_file_size;
+  fs->mds_map.compat = fsm.compat;
+  fs->mds_map.created = ceph_clock_now(g_ceph_context);
+  fs->mds_map.modified = ceph_clock_now(g_ceph_context);
+  fs->mds_map.session_timeout = g_conf->mds_session_timeout;
+  fs->mds_map.session_autoclose = g_conf->mds_session_autoclose;
+  fs->mds_map.enabled = true;
+  if (mon->get_quorum_features() & CEPH_FEATURE_SERVER_JEWEL) {
+    fs->fscid = fsm.next_filesystem_id++;
+    // ANONYMOUS is only for upgrades from legacy mdsmaps, we should
+    // have initialized next_filesystem_id such that it's never used here.
+    assert(fs->fscid != FS_CLUSTER_ID_ANONYMOUS);
+  } else {
+    // Use anon fscid because this will get thrown away when encoding
+    // as legacy MDSMap for legacy mons.
+    assert(fsm.filesystems.empty());
+    fs->fscid = FS_CLUSTER_ID_ANONYMOUS;
+  }
+  fsm.filesystems[fs->fscid] = fs;
+
+  // Created first filesystem?  Set it as the one
+  // for legacy clients to use
+  if (fsm.filesystems.size() == 1) {
+    fsm.legacy_client_fscid = fs->fscid;
+  }
+
+  print_map(fsm);
 }
 
 
@@ -105,21 +125,18 @@ void MDSMonitor::create_new_fs(MDSMap &m, const std::string &name, int metadata_
 void MDSMonitor::create_initial()
 {
   dout(10) << "create_initial" << dendl;
-
-  // Initial state is a disable MDS map
-  assert(mdsmap.get_enabled() == false);
 }
 
 
 void MDSMonitor::update_from_paxos(bool *need_bootstrap)
 {
   version_t version = get_last_committed();
-  if (version == mdsmap.epoch)
+  if (version == fsmap.epoch)
     return;
-  assert(version >= mdsmap.epoch);
 
   dout(10) << __func__ << " version " << version
-	   << ", my e " << mdsmap.epoch << dendl;
+	   << ", my e " << fsmap.epoch << dendl;
+  assert(version >= fsmap.epoch);
 
   // read and decode
   mdsmap_bl.clear();
@@ -128,11 +145,12 @@ void MDSMonitor::update_from_paxos(bool *need_bootstrap)
 
   assert(mdsmap_bl.length() > 0);
   dout(10) << __func__ << " got " << version << dendl;
-  mdsmap.decode(mdsmap_bl);
+  fsmap.decode(mdsmap_bl);
 
   // new map
   dout(4) << "new map" << dendl;
-  print_map(mdsmap, 0);
+  print_map(fsmap, 0);
+  fsmap.sanity();
 
   check_subs();
   update_logger();
@@ -145,28 +163,36 @@ void MDSMonitor::init()
 
 void MDSMonitor::create_pending()
 {
-  pending_mdsmap = mdsmap;
-  pending_mdsmap.epoch++;
-  dout(10) << "create_pending e" << pending_mdsmap.epoch << dendl;
+  pending_fsmap = fsmap;
+  pending_fsmap.epoch++;
+
+  dout(10) << "create_pending e" << pending_fsmap.epoch << dendl;
 }
 
 void MDSMonitor::encode_pending(MonitorDBStore::TransactionRef t)
 {
-  dout(10) << "encode_pending e" << pending_mdsmap.epoch << dendl;
+  dout(10) << "encode_pending e" << pending_fsmap.epoch << dendl;
 
-  pending_mdsmap.modified = ceph_clock_now(g_ceph_context);
 
   // print map iff 'debug mon = 30' or higher
-  print_map(pending_mdsmap, 30);
+  print_map(pending_fsmap, 30);
+  pending_fsmap.sanity();
+
+  // Set 'modified' on maps modified this epoch
+  for (auto &i : fsmap.filesystems) {
+    if (i.second->mds_map.epoch == fsmap.epoch) {
+      i.second->mds_map.modified = ceph_clock_now(g_ceph_context);
+    }
+  }
 
   // apply to paxos
-  assert(get_last_committed() + 1 == pending_mdsmap.epoch);
+  assert(get_last_committed() + 1 == pending_fsmap.epoch);
   bufferlist mdsmap_bl;
-  pending_mdsmap.encode(mdsmap_bl, mon->get_quorum_features());
+  pending_fsmap.encode(mdsmap_bl, mon->get_quorum_features());
 
   /* put everything in the transaction */
-  put_version(t, pending_mdsmap.epoch, mdsmap_bl);
-  put_last_committed(t, pending_mdsmap.epoch);
+  put_version(t, pending_fsmap.epoch, mdsmap_bl);
+  put_last_committed(t, pending_fsmap.epoch);
 
   // Encode MDSHealth data
   for (std::map<uint64_t, MDSHealth>::iterator i = pending_daemon_health.begin();
@@ -206,10 +232,20 @@ void MDSMonitor::update_logger()
 {
   dout(10) << "update_logger" << dendl;
 
-  mon->cluster_logger->set(l_cluster_num_mds_up, mdsmap.get_num_up_mds());
-  mon->cluster_logger->set(l_cluster_num_mds_in, mdsmap.get_num_in_mds());
-  mon->cluster_logger->set(l_cluster_num_mds_failed, mdsmap.get_num_failed_mds());
-  mon->cluster_logger->set(l_cluster_mds_epoch, mdsmap.get_epoch());
+  uint64_t up = 0;
+  uint64_t in = 0;
+  uint64_t failed = 0;
+  for (const auto &i : fsmap.filesystems) {
+    const MDSMap &mds_map = i.second->mds_map;
+
+    up += mds_map.get_num_up_mds();
+    in += mds_map.get_num_in_mds();
+    failed += mds_map.get_num_failed_mds();
+  }
+  mon->cluster_logger->set(l_cluster_num_mds_up, up);
+  mon->cluster_logger->set(l_cluster_num_mds_in, in);
+  mon->cluster_logger->set(l_cluster_num_mds_failed, failed);
+  mon->cluster_logger->set(l_cluster_mds_epoch, fsmap.get_epoch());
 }
 
 bool MDSMonitor::preprocess_query(MonOpRequestRef op)
@@ -253,6 +289,7 @@ bool MDSMonitor::preprocess_beacon(MonOpRequestRef op)
   mds_gid_t gid = m->get_global_id();
   version_t seq = m->get_seq();
   MDSMap::mds_info_t info;
+  epoch_t effective_epoch = 0;
 
   // check privileges, ignore if fails
   MonSession *session = m->get_session();
@@ -280,8 +317,8 @@ bool MDSMonitor::preprocess_beacon(MonOpRequestRef op)
   }
 
   // check compat
-  if (!m->get_compat().writeable(mdsmap.compat)) {
-    dout(1) << " mds " << m->get_source_inst() << " can't write to mdsmap " << mdsmap.compat << dendl;
+  if (!m->get_compat().writeable(fsmap.compat)) {
+    dout(1) << " mds " << m->get_source_inst() << " can't write to fsmap " << fsmap.compat << dendl;
     goto ignore;
   }
 
@@ -289,23 +326,23 @@ bool MDSMonitor::preprocess_beacon(MonOpRequestRef op)
   if (!mon->is_leader())
     return false;
 
-  if (pending_mdsmap.test_flag(CEPH_MDSMAP_DOWN)) {
-    dout(7) << " mdsmap DOWN flag set, ignoring mds " << m->get_source_inst() << " beacon" << dendl;
-    goto ignore;
-  }
-
   // booted, but not in map?
-  if (pending_mdsmap.is_dne_gid(gid)) {
+  if (!pending_fsmap.gid_exists(gid)) {
     if (state != MDSMap::STATE_BOOT) {
-      dout(7) << "mds_beacon " << *m << " is not in mdsmap (state "
+      dout(7) << "mds_beacon " << *m << " is not in fsmap (state "
               << ceph_mds_state_name(state) << ")" << dendl;
-      mon->send_reply(op, new MMDSMap(mon->monmap->fsid, &mdsmap));
+
+      MDSMap null_map;
+      null_map.epoch = fsmap.epoch;
+      null_map.compat = fsmap.compat;
+      mon->send_reply(op, new MMDSMap(mon->monmap->fsid, &null_map));
       return true;
     } else {
       return false;  // not booted yet.
     }
   }
-  info = pending_mdsmap.get_info_gid(gid);
+  dout(10) << __func__ << ": GID exists in map: " << gid << dendl;
+  info = pending_fsmap.get_info_gid(gid);
 
   // old seq?
   if (info.state_seq > seq) {
@@ -313,10 +350,19 @@ bool MDSMonitor::preprocess_beacon(MonOpRequestRef op)
     goto ignore;
   }
 
-  if (mdsmap.get_epoch() != m->get_last_epoch_seen()) {
-    dout(10) << "mds_beacon " << *m
-	     << " ignoring requested state, because mds hasn't seen latest map" << dendl;
-    goto reply;
+  // Work out the latest epoch that this daemon should have seen
+  {
+    fs_cluster_id_t fscid = pending_fsmap.mds_roles.at(gid);
+    if (fscid == FS_CLUSTER_ID_NONE) {
+      effective_epoch = pending_fsmap.standby_epochs.at(gid);
+    } else {
+      effective_epoch = pending_fsmap.get_filesystem(fscid)->mds_map.epoch;
+    }
+    if (effective_epoch != m->get_last_epoch_seen()) {
+      dout(10) << "mds_beacon " << *m
+               << " ignoring requested state, because mds hasn't seen latest map" << dendl;
+      goto reply;
+    }
   }
 
   if (info.laggy()) {
@@ -347,19 +393,8 @@ bool MDSMonitor::preprocess_beacon(MonOpRequestRef op)
       goto reply;
     }
     
-    if (info.state == MDSMap::STATE_STANDBY &&
-	(state == MDSMap::STATE_STANDBY_REPLAY ||
-	    state == MDSMap::STATE_ONESHOT_REPLAY) &&
-	(pending_mdsmap.is_degraded() ||
-	 ((m->get_standby_for_rank() >= 0) &&
-	     pending_mdsmap.get_state(m->get_standby_for_rank()) < MDSMap::STATE_ACTIVE))) {
-      dout(10) << "mds_beacon can't standby-replay mds." << m->get_standby_for_rank() << " at this time (cluster degraded, or mds not active)" << dendl;
-      dout(10) << "pending_mdsmap.is_degraded()==" << pending_mdsmap.is_degraded()
-          << " rank state: " << ceph_mds_state_name(pending_mdsmap.get_state(m->get_standby_for_rank())) << dendl;
-      goto reply;
-    }
     _note_beacon(m);
-    return false;  // need to update map
+    return false;
   }
 
   // Comparing known daemon health with m->get_health()
@@ -373,10 +408,12 @@ bool MDSMonitor::preprocess_beacon(MonOpRequestRef op)
 
  reply:
   // note time and reply
+  assert(effective_epoch > 0);
   _note_beacon(m);
   mon->send_reply(op,
 		  new MMDSBeacon(mon->monmap->fsid, m->get_global_id(), m->get_name(),
-				 mdsmap.get_epoch(), state, seq));
+				 effective_epoch, state, seq,
+				 CEPH_FEATURES_SUPPORTED_DEFAULT));
   return true;
 
  ignore:
@@ -390,7 +427,6 @@ bool MDSMonitor::preprocess_offload_targets(MonOpRequestRef op)
   op->mark_mdsmon_event(__func__);
   MMDSLoadTargets *m = static_cast<MMDSLoadTargets*>(op->get_req());
   dout(10) << "preprocess_offload_targets " << *m << " from " << m->get_orig_source() << dendl;
-  mds_gid_t gid;
   
   // check privileges, ignore message if fails
   MonSession *session = m->get_session();
@@ -402,9 +438,8 @@ bool MDSMonitor::preprocess_offload_targets(MonOpRequestRef op)
     goto done;
   }
 
-  gid = m->global_id;
-  if (mdsmap.mds_info.count(gid) &&
-      m->targets == mdsmap.mds_info[gid].export_targets)
+  if (fsmap.gid_exists(m->global_id) &&
+      m->targets == fsmap.get_info_gid(m->global_id).export_targets)
     goto done;
 
   return false;
@@ -451,12 +486,6 @@ bool MDSMonitor::prepare_beacon(MonOpRequestRef op)
   MDSMap::DaemonState state = m->get_state();
   version_t seq = m->get_seq();
 
-  // Ignore beacons if filesystem is disabled
-  if (!mdsmap.get_enabled()) {
-    dout(1) << "warning, MDS " << m->get_orig_source_inst() << " up but filesystem disabled" << dendl;
-    return false;
-  }
-
   // Store health
   dout(20) << __func__ << " got health from gid " << gid << " with " << m->get_health().metrics.size() << " metrics." << dendl;
   pending_daemon_health[gid] = m->get_health();
@@ -466,7 +495,7 @@ bool MDSMonitor::prepare_beacon(MonOpRequestRef op)
     // zap previous instance of this name?
     if (g_conf->mds_enforce_unique_name) {
       bool failed_mds = false;
-      while (mds_gid_t existing = pending_mdsmap.find_mds_gid_by_name(m->get_name())) {
+      while (mds_gid_t existing = pending_fsmap.find_mds_gid_by_name(m->get_name())) {
         if (!mon->osdmon()->is_writeable()) {
           mon->osdmon()->wait_for_writeable(op, new C_RetryMessage(this, op));
           return false;
@@ -480,25 +509,35 @@ bool MDSMonitor::prepare_beacon(MonOpRequestRef op)
       }
     }
 
-    // add
-    MDSMap::mds_info_t& info = pending_mdsmap.mds_info[gid];
-    info.global_id = gid;
-    info.name = m->get_name();
-    info.rank = -1;
-    info.addr = addr;
-    info.state = MDSMap::STATE_STANDBY;
-    info.state_seq = seq;
-    info.standby_for_rank = m->get_standby_for_rank();
-    info.standby_for_name = m->get_standby_for_name();
+    // Add this daemon to the map
+    if (pending_fsmap.mds_roles.count(gid) == 0) {
+      MDSMap::mds_info_t new_info;
+      new_info.global_id = gid;
+      new_info.name = m->get_name();
+      new_info.addr = addr;
+      new_info.mds_features = m->get_mds_features();
+      new_info.state = MDSMap::STATE_STANDBY;
+      new_info.state_seq = seq;
+      new_info.standby_for_rank = m->get_standby_for_rank();
+      new_info.standby_for_name = m->get_standby_for_name();
+      pending_fsmap.insert(new_info);
+    }
 
+    // Resolve standby_for_name to a rank
+    const MDSMap::mds_info_t &info = pending_fsmap.get_info_gid(gid);
     if (!info.standby_for_name.empty()) {
-      const MDSMap::mds_info_t *leaderinfo = mdsmap.find_by_name(info.standby_for_name);
+      const MDSMap::mds_info_t *leaderinfo = fsmap.find_by_name(
+          info.standby_for_name);
       if (leaderinfo && (leaderinfo->rank >= 0)) {
-        info.standby_for_rank =
-            mdsmap.find_by_name(info.standby_for_name)->rank;
-        if (mdsmap.is_followable(info.standby_for_rank)) {
-          info.state = MDSMap::STATE_STANDBY_REPLAY;
-        }
+        auto fscid = pending_fsmap.mds_roles.at(leaderinfo->global_id);
+        auto fs = pending_fsmap.get_filesystem(fscid);
+        bool followable = fs->mds_map.is_followable(leaderinfo->rank);
+
+        pending_fsmap.modify_daemon(gid, [fscid, leaderinfo, followable](
+              MDSMap::mds_info_t *info) {
+            info->standby_for_rank = leaderinfo->rank;
+            info->standby_for_ns = fscid;
+        });
       }
     }
 
@@ -507,17 +546,18 @@ bool MDSMonitor::prepare_beacon(MonOpRequestRef op)
     last_beacon[gid].seq = seq;
 
     // new incompat?
-    if (!pending_mdsmap.compat.writeable(m->get_compat())) {
-      dout(10) << " mdsmap " << pending_mdsmap.compat << " can't write to new mds' " << m->get_compat()
-	       << ", updating mdsmap and killing old mds's"
+    if (!pending_fsmap.compat.writeable(m->get_compat())) {
+      dout(10) << " fsmap " << pending_fsmap.compat
+               << " can't write to new mds' " << m->get_compat()
+	       << ", updating fsmap and killing old mds's"
 	       << dendl;
-      pending_mdsmap.compat = m->get_compat();
+      pending_fsmap.update_compat(m->get_compat());
     }
 
     update_metadata(m->get_global_id(), m->get_sys_info());
   } else {
-    // state change
-    MDSMap::mds_info_t& info = pending_mdsmap.get_info_gid(gid);
+    // state update
+    const MDSMap::mds_info_t &info = pending_fsmap.get_info_gid(gid);
 
     if (info.state == MDSMap::STATE_STOPPING && state != MDSMap::STATE_STOPPED ) {
       // we can't transition to any other states from STOPPING
@@ -529,7 +569,11 @@ bool MDSMonitor::prepare_beacon(MonOpRequestRef op)
 
     if (info.laggy()) {
       dout(10) << "prepare_beacon clearing laggy flag on " << addr << dendl;
-      info.clear_laggy();
+      pending_fsmap.modify_daemon(info.global_id, [](MDSMap::mds_info_t *info)
+        {
+          info->clear_laggy();
+        }
+      );
     }
   
     dout(10) << "prepare_beacon mds." << info.rank
@@ -538,37 +582,70 @@ bool MDSMonitor::prepare_beacon(MonOpRequestRef op)
 	     << "  standby_for_rank=" << m->get_standby_for_rank()
 	     << dendl;
     if (state == MDSMap::STATE_STOPPED) {
-      pending_mdsmap.up.erase(info.rank);
-      pending_mdsmap.in.erase(info.rank);
-      pending_mdsmap.stopped.insert(info.rank);
-      pending_mdsmap.mds_info.erase(gid);  // last! info is a ref into this map
+      pending_fsmap.stop(gid);
       last_beacon.erase(gid);
     } else if (state == MDSMap::STATE_STANDBY_REPLAY) {
       if (m->get_standby_for_rank() == MDSMap::MDS_STANDBY_NAME) {
-        /* convert name to rank. If we don't have it, do nothing. The
-	 mds will stay in standby and keep requesting the state change */
         dout(20) << "looking for mds " << m->get_standby_for_name()
                   << " to STANDBY_REPLAY for" << dendl;
-        const MDSMap::mds_info_t *found_mds = NULL;
-        if ((found_mds = mdsmap.find_by_name(m->get_standby_for_name())) &&
-            (found_mds->rank >= 0) &&
-	    mdsmap.is_followable(found_mds->rank)) {
-          info.standby_for_rank = found_mds->rank;
+        auto target_info = pending_fsmap.find_by_name(m->get_standby_for_name());
+        if (target_info == nullptr) {
+          // This name is unknown, do nothing, stay in standby
+          return false;
+        }
+
+        auto target_ns = pending_fsmap.mds_roles.at(target_info->global_id);
+        if (target_ns == FS_CLUSTER_ID_NONE) {
+          // The named daemon is not in a Filesystem, do nothing.
+          return false;
+        }
+
+        auto target_fs = pending_fsmap.get_filesystem(target_ns);
+        if (target_fs->mds_map.is_followable(info.rank)) {
           dout(10) <<" found mds " << m->get_standby_for_name()
-                       << "; it has rank " << info.standby_for_rank << dendl;
-          info.state = MDSMap::STATE_STANDBY_REPLAY;
-          info.state_seq = seq;
+                       << "; it has rank " << target_info->rank << dendl;
+          pending_fsmap.modify_daemon(info.global_id,
+              [target_info, target_ns, seq](MDSMap::mds_info_t *info) {
+            info->standby_for_rank = target_info->rank;
+            info->standby_for_ns = target_ns;
+            info->state = MDSMap::STATE_STANDBY_REPLAY;
+            info->state_seq = seq;
+          });
+        } else {
+          // The named daemon has a rank but isn't followable, do nothing
+          return false;
+        }
+      } else if (m->get_standby_for_rank() >= 0) {
+        // TODO get this from MDS message
+        // >>
+        fs_cluster_id_t target_ns = FS_CLUSTER_ID_NONE;
+        // <<
+
+        mds_role_t target_role = {
+          target_ns == FS_CLUSTER_ID_NONE ?
+            pending_fsmap.legacy_client_fscid : info.standby_for_ns,
+          m->get_standby_for_rank()};
+
+        if (target_role.fscid != FS_CLUSTER_ID_NONE) {
+          auto fs = pending_fsmap.get_filesystem(target_role.fscid);
+          if (fs->mds_map.is_followable(target_role.rank)) {
+            pending_fsmap.modify_daemon(info.global_id,
+                [target_role, seq](MDSMap::mds_info_t *info) {
+              info->standby_for_rank = target_role.rank;
+              info->standby_for_ns = target_role.fscid;
+              info->state = MDSMap::STATE_STANDBY_REPLAY;
+              info->state_seq = seq;
+            });
+          } else {
+            // We know who they want to follow, but he's not in a suitable state
+            return false;
+          }
         } else {
+          // Couldn't resolve to a particular filesystem
           return false;
         }
-      } else if (m->get_standby_for_rank() >= 0 &&
-		 mdsmap.is_followable(m->get_standby_for_rank())) {
-        /* switch to standby-replay for this MDS*/
-        info.state = MDSMap::STATE_STANDBY_REPLAY;
-        info.state_seq = seq;
-        info.standby_for_rank = m->get_standby_for_rank();
       } else { //it's a standby for anybody, and is already in the list
-        assert(pending_mdsmap.get_mds_info().count(info.global_id));
+        assert(pending_fsmap.get_mds_info().count(info.global_id));
         return false;
       }
     } else if (state == MDSMap::STATE_DAMAGED) {
@@ -584,25 +661,18 @@ bool MDSMonitor::prepare_beacon(MonOpRequestRef op)
       dout(4) << __func__ << ": marking rank "
               << info.rank << " damaged" << dendl;
 
-
-      // Blacklist this MDS daemon
       const utime_t until = ceph_clock_now(g_ceph_context);
-      pending_mdsmap.last_failure_osd_epoch = mon->osdmon()->blacklist(
-          info.addr, until);
+      const auto blacklist_epoch = mon->osdmon()->blacklist(info.addr, until);
       request_proposal(mon->osdmon());
-
-      // Clear out daemon state and add rank to damaged list
-      pending_mdsmap.up.erase(info.rank);
-      pending_mdsmap.damaged.insert(info.rank);
+      pending_fsmap.damaged(gid, blacklist_epoch);
       last_beacon.erase(gid);
 
-      // Call erase() last because the `info` reference becomes invalid
-      // after we remove the instance from the map.
-      pending_mdsmap.mds_info.erase(gid);
-
       // Respond to MDS, so that it knows it can continue to shut down
-      mon->send_reply(op, new MMDSBeacon(mon->monmap->fsid, m->get_global_id(),
-                    m->get_name(), mdsmap.get_epoch(), state, seq));
+      mon->send_reply(op,
+		      new MMDSBeacon(
+			mon->monmap->fsid, m->get_global_id(),
+			m->get_name(), fsmap.get_epoch(), state, seq,
+			CEPH_FEATURES_SUPPORTED_DEFAULT));
     } else if (state == MDSMap::STATE_DNE) {
       if (!mon->osdmon()->is_writeable()) {
         dout(4) << __func__ << ": DNE from rank " << info.rank
@@ -616,16 +686,21 @@ bool MDSMonitor::prepare_beacon(MonOpRequestRef op)
       request_proposal(mon->osdmon());
 
       // Respond to MDS, so that it knows it can continue to shut down
-      mon->send_reply(op, new MMDSBeacon(mon->monmap->fsid, m->get_global_id(),
-                    m->get_name(), mdsmap.get_epoch(), state, seq));
+      mon->send_reply(op,
+		      new MMDSBeacon(
+			mon->monmap->fsid, m->get_global_id(),
+			m->get_name(), fsmap.get_epoch(), state, seq,
+			CEPH_FEATURES_SUPPORTED_DEFAULT));
     } else {
-      info.state = state;
-      info.state_seq = seq;
+      pending_fsmap.modify_daemon(gid, [state, seq](MDSMap::mds_info_t *info) {
+        info->state = state;
+        info->state_seq = seq;
+      });
     }
   }
 
   dout(7) << "prepare_beacon pending map now:" << dendl;
-  print_map(pending_mdsmap);
+  print_map(pending_fsmap);
   
   wait_for_finished_proposal(op, new C_Updated(this, op));
 
@@ -637,9 +712,9 @@ bool MDSMonitor::prepare_offload_targets(MonOpRequestRef op)
   op->mark_mdsmon_event(__func__);
   MMDSLoadTargets *m = static_cast<MMDSLoadTargets*>(op->get_req());
   mds_gid_t gid = m->global_id;
-  if (pending_mdsmap.mds_info.count(gid)) {
+  if (pending_fsmap.gid_has_rank(gid)) {
     dout(10) << "prepare_offload_targets " << gid << " " << m->targets << dendl;
-    pending_mdsmap.mds_info[gid].export_targets = m->targets;
+    pending_fsmap.update_export_targets(gid, m->targets);
   } else {
     dout(10) << "prepare_offload_targets " << gid << " not in map" << dendl;
   }
@@ -662,14 +737,18 @@ void MDSMonitor::_updated(MonOpRequestRef op)
 
   if (m->get_state() == MDSMap::STATE_STOPPED) {
     // send the map manually (they're out of the map, so they won't get it automatic)
-    mon->send_reply(op, new MMDSMap(mon->monmap->fsid, &mdsmap));
+    MDSMap null_map;
+    null_map.epoch = fsmap.epoch;
+    null_map.compat = fsmap.compat;
+    mon->send_reply(op, new MMDSMap(mon->monmap->fsid, &null_map));
   } else {
     mon->send_reply(op, new MMDSBeacon(mon->monmap->fsid,
-				      m->get_global_id(),
-				      m->get_name(),
-				      mdsmap.get_epoch(),
-				      m->get_state(),
-				      m->get_seq()));
+				       m->get_global_id(),
+				       m->get_name(),
+				       fsmap.get_epoch(),
+				       m->get_state(),
+				       m->get_seq(),
+				       CEPH_FEATURES_SUPPORTED_DEFAULT));
   }
 }
 
@@ -679,23 +758,26 @@ void MDSMonitor::on_active()
   update_logger();
 
   if (mon->is_leader())
-    mon->clog->info() << "mdsmap " << mdsmap << "\n";
+    mon->clog->info() << "fsmap " << fsmap << "\n";
 }
 
 void MDSMonitor::get_health(list<pair<health_status_t, string> >& summary,
 			    list<pair<health_status_t, string> > *detail,
 			    CephContext* cct) const
 {
-  mdsmap.get_health(summary, detail);
+  fsmap.get_health(summary, detail);
 
   // For each MDS GID...
-  for (std::map<mds_gid_t, MDSMap::mds_info_t>::const_iterator i = mdsmap.mds_info.begin();
-      i != mdsmap.mds_info.end(); ++i) {
+  const auto info_map = fsmap.get_mds_info();
+  for (const auto &i : info_map) {
+    const auto &gid = i.first;
+    const auto &info = i.second;
+
     // Decode MDSHealth
     bufferlist bl;
-    mon->store->get(MDS_HEALTH_PREFIX, stringify(i->first), bl);
+    mon->store->get(MDS_HEALTH_PREFIX, stringify(gid), bl);
     if (!bl.length()) {
-      derr << "Missing health data for MDS " << i->first << dendl;
+      derr << "Missing health data for MDS " << gid << dendl;
       continue;
     }
     MDSHealth health;
@@ -703,7 +785,7 @@ void MDSMonitor::get_health(list<pair<health_status_t, string> >& summary,
     health.decode(bl_i);
 
     for (std::list<MDSHealthMetric>::iterator j = health.metrics.begin(); j != health.metrics.end(); ++j) {
-      int const rank = i->second.rank;
+      int const rank = info.rank;
       std::ostringstream message;
       message << "mds" << rank << ": " << j->message;
       summary.push_back(std::make_pair(j->sev, message.str()));
@@ -733,14 +815,129 @@ void MDSMonitor::get_health(list<pair<health_status_t, string> >& summary,
 
 void MDSMonitor::dump_info(Formatter *f)
 {
-  f->open_object_section("mdsmap");
-  mdsmap.dump(f);
+  f->open_object_section("fsmap");
+  fsmap.dump(f);
   f->close_section();
 
   f->dump_unsigned("mdsmap_first_committed", get_first_committed());
   f->dump_unsigned("mdsmap_last_committed", get_last_committed());
 }
 
+class FileSystemCommandHandler
+{
+protected:
+  std::string prefix;
+
+  /**
+   * Parse true|yes|1 style boolean string from `bool_str`
+   * `result` must be non-null.
+   * `ss` will be populated with error message on error.
+   *
+   * @return 0 on success, else -EINVAL
+   */
+  int parse_bool(
+      const std::string &bool_str,
+      bool *result,
+      std::ostream &ss)
+  {
+    assert(result != nullptr);
+
+    string interr;
+    int64_t n = strict_strtoll(bool_str.c_str(), 10, &interr);
+
+    if (bool_str == "false" || bool_str == "no"
+        || (interr.length() == 0 && n == 0)) {
+      *result = false;
+      return 0;
+    } else if (bool_str == "true" || bool_str == "yes"
+        || (interr.length() == 0 && n == 1)) {
+      *result = true;
+      return 0;
+    } else {
+      ss << "value must be false|no|0 or true|yes|1";
+      return -EINVAL;
+    }
+  }
+
+  /**
+   * Return 0 if the pool is suitable for use with CephFS, or
+   * in case of errors return a negative error code, and populate
+   * the passed stringstream with an explanation.
+   */
+  int _check_pool(
+      OSDMap &osd_map,
+      const int64_t pool_id,
+      std::stringstream *ss) const
+  {
+    assert(ss != NULL);
+
+    const pg_pool_t *pool = osd_map.get_pg_pool(pool_id);
+    if (!pool) {
+      *ss << "pool id '" << pool_id << "' does not exist";
+      return -ENOENT;
+    }
+
+    const string& pool_name = osd_map.get_pool_name(pool_id);
+
+    if (pool->is_erasure()) {
+      // EC pools are only acceptable with a cache tier overlay
+      if (!pool->has_tiers() || !pool->has_read_tier() || !pool->has_write_tier()) {
+        *ss << "pool '" << pool_name << "' (id '" << pool_id << "')"
+           << " is an erasure-code pool";
+        return -EINVAL;
+      }
+
+      // That cache tier overlay must be writeback, not readonly (it's the
+      // write operations like modify+truncate we care about support for)
+      const pg_pool_t *write_tier = osd_map.get_pg_pool(
+          pool->write_tier);
+      assert(write_tier != NULL);  // OSDMonitor shouldn't allow DNE tier
+      if (write_tier->cache_mode == pg_pool_t::CACHEMODE_FORWARD
+          || write_tier->cache_mode == pg_pool_t::CACHEMODE_READONLY) {
+        *ss << "EC pool '" << pool_name << "' has a write tier ("
+            << osd_map.get_pool_name(pool->write_tier)
+            << ") that is configured "
+               "to forward writes.  Use a cache mode such as 'writeback' for "
+               "CephFS";
+        return -EINVAL;
+      }
+    }
+
+    if (pool->is_tier()) {
+      *ss << " pool '" << pool_name << "' (id '" << pool_id
+        << "') is already in use as a cache tier.";
+      return -EINVAL;
+    }
+
+    // Nothing special about this pool, so it is permissible
+    return 0;
+  }
+
+  virtual std::string const &get_prefix() {return prefix;}
+
+public:
+  FileSystemCommandHandler(const std::string &prefix_)
+    : prefix(prefix_)
+  {
+
+  }
+  virtual ~FileSystemCommandHandler()
+  {
+  }
+
+  bool can_handle(std::string const &prefix_)
+  {
+    return get_prefix() == prefix_;
+  }
+
+  virtual int handle(
+    Monitor *mon,
+    FSMap &fsmap,
+    MonOpRequestRef op,
+    map<string, cmd_vartype> &cmdmap,
+    std::stringstream &ss) = 0;
+};
+
 bool MDSMonitor::preprocess_command(MonOpRequestRef op)
 {
   op->mark_mdsmon_event(__func__);
@@ -776,14 +973,14 @@ bool MDSMonitor::preprocess_command(MonOpRequestRef op)
       f->close_section();
       f->flush(ds);
     } else {
-      ds << mdsmap;
+      ds << fsmap;
     }
     r = 0;
   } else if (prefix == "mds dump") {
     int64_t epocharg;
     epoch_t epoch;
 
-    MDSMap *p = &mdsmap;
+    FSMap *p = &fsmap;
     if (cmd_getval(g_ceph_context, cmdmap, "epoch", epocharg)) {
       epoch = epocharg;
       bufferlist b;
@@ -794,14 +991,61 @@ bool MDSMonitor::preprocess_command(MonOpRequestRef op)
       } else {
 	assert(err == 0);
 	assert(b.length());
-	p = new MDSMap;
+	p = new FSMap;
 	p->decode(b);
       }
     }
     if (p) {
       stringstream ds;
+      const MDSMap *mdsmap = nullptr;
+      MDSMap blank;
+      blank.epoch = fsmap.epoch;
+      if (fsmap.legacy_client_fscid != FS_CLUSTER_ID_NONE) {
+        mdsmap = &(fsmap.filesystems[fsmap.legacy_client_fscid]->mds_map);
+      } else {
+        mdsmap = ␣
+      }
       if (f != NULL) {
 	f->open_object_section("mdsmap");
+	mdsmap->dump(f.get());
+	f->close_section();
+	f->flush(ds);
+	r = 0;
+      } else {
+	mdsmap->print(ds);
+	r = 0;
+      } 
+      if (r == 0) {
+	rdata.append(ds);
+	ss << "dumped fsmap epoch " << p->get_epoch();
+      }
+      if (p != &fsmap) {
+	delete p;
+      }
+    }
+  } else if (prefix == "fs dump") {
+    int64_t epocharg;
+    epoch_t epoch;
+
+    FSMap *p = &fsmap;
+    if (cmd_getval(g_ceph_context, cmdmap, "epoch", epocharg)) {
+      epoch = epocharg;
+      bufferlist b;
+      int err = get_version(epoch, b);
+      if (err == -ENOENT) {
+	p = 0;
+	r = -ENOENT;
+      } else {
+	assert(err == 0);
+	assert(b.length());
+	p = new FSMap;
+	p->decode(b);
+      }
+    }
+    if (p) {
+      stringstream ds;
+      if (f != NULL) {
+	f->open_object_section("fsmap");
 	p->dump(f.get());
 	f->close_section();
 	f->flush(ds);
@@ -812,9 +1056,9 @@ bool MDSMonitor::preprocess_command(MonOpRequestRef op)
       } 
       if (r == 0) {
 	rdata.append(ds);
-	ss << "dumped mdsmap epoch " << p->get_epoch();
+	ss << "dumped fsmap epoch " << p->get_epoch();
       }
-      if (p != &mdsmap)
+      if (p != &fsmap)
 	delete p;
     }
   } else if (prefix == "mds metadata") {
@@ -838,15 +1082,15 @@ bool MDSMonitor::preprocess_command(MonOpRequestRef op)
       } else {
 	assert(err == 0);
 	assert(b.length());
-	MDSMap mm;
+	FSMap mm;
 	mm.decode(b);
 	mm.encode(rdata, m->get_connection()->get_features());
-	ss << "got mdsmap epoch " << mm.get_epoch();
+	ss << "got fsmap epoch " << mm.get_epoch();
 	r = 0;
       }
     } else {
-      mdsmap.encode(rdata, m->get_connection()->get_features());
-      ss << "got mdsmap epoch " << mdsmap.get_epoch();
+      fsmap.encode(rdata, m->get_connection()->get_features());
+      ss << "got fsmap epoch " << fsmap.get_epoch();
       r = 0;
     }
   } else if (prefix == "mds tell") {
@@ -857,12 +1101,10 @@ bool MDSMonitor::preprocess_command(MonOpRequestRef op)
 
     if (whostr == "*") {
       r = -ENOENT;
-      const map<mds_gid_t, MDSMap::mds_info_t> mds_info = mdsmap.get_mds_info();
-      for (map<mds_gid_t, MDSMap::mds_info_t>::const_iterator i = mds_info.begin();
-	   i != mds_info.end();
-	   ++i) {
+      const auto info_map = fsmap.get_mds_info();
+      for (const auto &i : info_map) {
 	m->cmd = args_vec;
-	mon->send_command(i->second.get_inst(), m->cmd);
+	mon->send_command(i.second.get_inst(), m->cmd);
 	r = 0;
       }
       if (r == -ENOENT) {
@@ -871,48 +1113,76 @@ bool MDSMonitor::preprocess_command(MonOpRequestRef op)
 	ss << "ok";
       }
     } else {
-      errno = 0;
-      long who_l = strtol(whostr.c_str(), 0, 10);
-      if (!errno && who_l >= 0) {
-        mds_rank_t who = mds_rank_t(who_l);
-	if (mdsmap.is_up(who)) {
-	  m->cmd = args_vec;
-	  mon->send_command(mdsmap.get_inst(who), m->cmd);
-	  r = 0;
-	  ss << "ok";
-	} else {
-	  ss << "mds." << who << " not up";
-	  r = -ENOENT;
-	}
-      } else ss << "specify mds number or *";
+      if (fsmap.legacy_client_fscid) {
+        auto fs = fsmap.filesystems.at(fsmap.legacy_client_fscid);
+        errno = 0;
+        long who_l = strtol(whostr.c_str(), 0, 10);
+        if (!errno && who_l >= 0) {
+          mds_rank_t who = mds_rank_t(who_l);
+          if (fs->mds_map.is_up(who)) {
+            m->cmd = args_vec;
+            mon->send_command(fs->mds_map.get_inst(who), m->cmd);
+            r = 0;
+            ss << "ok";
+          } else {
+            ss << "mds." << who << " not up";
+            r = -ENOENT;
+          }
+        } else {
+          ss << "specify mds number or *";
+        }
+      } else {
+        ss << "no legacy filesystem set";
+      }
     }
   } else if (prefix == "mds compat show") {
       if (f) {
 	f->open_object_section("mds_compat");
-	mdsmap.compat.dump(f.get());
+	fsmap.compat.dump(f.get());
 	f->close_section();
 	f->flush(ds);
       } else {
-	ds << mdsmap.compat;
+	ds << fsmap.compat;
       }
       r = 0;
+  } else if (prefix == "fs get") {
+    string fs_name;
+    cmd_getval(g_ceph_context, cmdmap, "fs_name", fs_name);
+    auto fs = fsmap.get_filesystem(fs_name);
+    if (fs == nullptr) {
+      ss << "filesystem '" << fs_name << "' not found";
+      r = -ENOENT;
+    } else {
+      if (f != nullptr) {
+        f->open_object_section("filesystem");
+        fs->dump(f.get());
+        f->close_section();
+        f->flush(ds);
+        r = 0;
+      } else {
+        fs->print(ds);
+        r = 0;
+      }
+    }
   } else if (prefix == "fs ls") {
     if (f) {
       f->open_array_section("filesystems");
       {
-        if (mdsmap.get_enabled()) {
+        for (const auto i : fsmap.filesystems) {
+          const auto fs = i.second;
           f->open_object_section("filesystem");
           {
-            f->dump_string("name", mdsmap.fs_name);
-            const string &md_pool_name = mon->osdmon()->osdmap.get_pool_name(mdsmap.metadata_pool);
+            const MDSMap &mds_map = fs->mds_map;
+            f->dump_string("name", mds_map.fs_name);
             /* Output both the names and IDs of pools, for use by
              * humans and machines respectively */
-            f->dump_string("metadata_pool", md_pool_name);
-            f->dump_int("metadata_pool_id", mdsmap.metadata_pool);
+            f->dump_string("metadata_pool", mon->osdmon()->osdmap.get_pool_name(
+                  mds_map.metadata_pool));
+            f->dump_int("metadata_pool_id", mds_map.metadata_pool);
             f->open_array_section("data_pool_ids");
             {
-              for (std::set<int64_t>::iterator dpi = mdsmap.data_pools.begin();
-                   dpi != mdsmap.data_pools.end(); ++dpi) {
+              for (auto dpi = mds_map.data_pools.begin();
+                   dpi != mds_map.data_pools.end(); ++dpi) {
                 f->dump_int("data_pool_id", *dpi);
               }
             }
@@ -920,10 +1190,11 @@ bool MDSMonitor::preprocess_command(MonOpRequestRef op)
 
             f->open_array_section("data_pools");
             {
-                for (std::set<int64_t>::iterator dpi = mdsmap.data_pools.begin();
-                   dpi != mdsmap.data_pools.end(); ++dpi) {
-                  const string &pool_name = mon->osdmon()->osdmap.get_pool_name(*dpi);
-                  f->dump_string("data_pool", pool_name);
+                for (auto dpi = mds_map.data_pools.begin();
+                   dpi != mds_map.data_pools.end(); ++dpi) {
+                  const auto &name = mon->osdmon()->osdmap.get_pool_name(
+                      *dpi);
+                  f->dump_string("data_pool", name);
                 }
             }
 
@@ -935,17 +1206,23 @@ bool MDSMonitor::preprocess_command(MonOpRequestRef op)
       f->close_section();
       f->flush(ds);
     } else {
-      if (mdsmap.get_enabled()) {
-        const string &md_pool_name = mon->osdmon()->osdmap.get_pool_name(mdsmap.metadata_pool);
+      for (const auto i : fsmap.filesystems) {
+        const auto fs = i.second;
+        const MDSMap &mds_map = fs->mds_map;
+        const string &md_pool_name = mon->osdmon()->osdmap.get_pool_name(
+            mds_map.metadata_pool);
         
-        ds << "name: " << mdsmap.fs_name << ", metadata pool: " << md_pool_name << ", data pools: [";
-        for (std::set<int64_t>::iterator dpi = mdsmap.data_pools.begin();
-           dpi != mdsmap.data_pools.end(); ++dpi) {
+        ds << "name: " << mds_map.fs_name << ", metadata pool: "
+           << md_pool_name << ", data pools: [";
+        for (std::set<int64_t>::iterator dpi = mds_map.data_pools.begin();
+           dpi != mds_map.data_pools.end(); ++dpi) {
           const string &pool_name = mon->osdmon()->osdmap.get_pool_name(*dpi);
           ds << pool_name << " ";
         }
         ds << "]" << std::endl;
-      } else {
+      }
+
+      if (fsmap.filesystems.empty()) {
         ds << "No filesystems enabled" << std::endl;
       }
     }
@@ -962,86 +1239,75 @@ bool MDSMonitor::preprocess_command(MonOpRequestRef op)
     return false;
 }
 
-void MDSMonitor::fail_mds_gid(mds_gid_t gid)
+bool MDSMonitor::fail_mds_gid(mds_gid_t gid)
 {
-  assert(pending_mdsmap.mds_info.count(gid));
-  MDSMap::mds_info_t& info = pending_mdsmap.mds_info[gid];
-  dout(10) << "fail_mds_gid " << gid << " mds." << info.name << " rank " << info.rank << dendl;
-
-  utime_t until = ceph_clock_now(g_ceph_context);
-  until += g_conf->mds_blacklist_interval;
-
-  pending_mdsmap.last_failure_osd_epoch = mon->osdmon()->blacklist(info.addr, until);
-
-  if (info.rank >= 0) {
-    if (info.state == MDSMap::STATE_CREATING) {
-      // If this gid didn't make it past CREATING, then forget
-      // the rank ever existed so that next time it's handed out
-      // to a gid it'll go back into CREATING.
-      pending_mdsmap.in.erase(info.rank);
-    } else {
-      // Put this rank into the failed list so that the next available STANDBY will
-      // pick it up.
-      pending_mdsmap.failed.insert(info.rank);
-    }
-    pending_mdsmap.up.erase(info.rank);
+  const MDSMap::mds_info_t info = pending_fsmap.get_info_gid(gid);
+  dout(10) << "fail_mds_gid " << gid << " mds." << info.name << " role " << info.rank << dendl;
+
+  epoch_t blacklist_epoch = 0;
+  if (info.rank >= 0 && info.state != MDSMap::STATE_STANDBY_REPLAY) {
+    utime_t until = ceph_clock_now(g_ceph_context);
+    until += g_conf->mds_blacklist_interval;
+    blacklist_epoch = mon->osdmon()->blacklist(info.addr, until);
   }
 
-  pending_mdsmap.mds_info.erase(gid);
-
+  pending_fsmap.erase(gid, blacklist_epoch);
   last_beacon.erase(gid);
+  if (pending_daemon_health.count(gid)) {
+    pending_daemon_health.erase(gid);
+    pending_daemon_health_rm.insert(gid);
+  }
+
+  return blacklist_epoch != 0;
 }
 
 mds_gid_t MDSMonitor::gid_from_arg(const std::string& arg, std::ostream &ss)
 {
+  // Try parsing as a role
+  mds_role_t role;
+  std::ostringstream ignore_err;  // Don't spam 'ss' with parse_role errors
+  int r = parse_role(arg, &role, ignore_err);
+  if (r == 0) {
+    // See if a GID is assigned to this role
+    auto fs = pending_fsmap.get_filesystem(role.fscid);
+    assert(fs != nullptr);  // parse_role ensures it exists
+    if (fs->mds_map.is_up(role.rank)) {
+      dout(10) << __func__ << ": validated rank/GID " << role
+               << " as a rank" << dendl;
+      return fs->mds_map.get_mds_info(role.rank).global_id;
+    }
+  }
+
+  // Try parsing as a gid
   std::string err;
-  unsigned long long rank_or_gid = strict_strtoll(arg.c_str(), 10, &err);
+  unsigned long long maybe_gid = strict_strtoll(arg.c_str(), 10, &err);
   if (!err.empty()) {
-    // Try to interpret the arg as an MDS name
-    const MDSMap::mds_info_t *mds_info = mdsmap.find_by_name(arg);
+    // Not a role or a GID, try as a daemon name
+    const MDSMap::mds_info_t *mds_info = fsmap.find_by_name(arg);
     if (!mds_info) {
       ss << "MDS named '" << arg
 	 << "' does not exist, or is not up";
       return MDS_GID_NONE;
     }
-    if (mds_info->rank >= 0) {
-      dout(10) << __func__ << ": resolved MDS name '" << arg << "' to rank " << rank_or_gid << dendl;
-      rank_or_gid = (unsigned long long)(mds_info->rank);
-    } else {
-      dout(10) << __func__ << ": resolved MDS name '" << arg << "' to GID " << rank_or_gid << dendl;
-      rank_or_gid = mds_info->global_id;
-    }
+    dout(10) << __func__ << ": resolved MDS name '" << arg
+             << "' to GID " << mds_info->global_id << dendl;
+    return mds_info->global_id;
   } else {
+    // Not a role, but parses as a an integer, might be a GID
     dout(10) << __func__ << ": treating MDS reference '" << arg
-	     << "' as an integer " << rank_or_gid << dendl;
-  }
-
-  if (mon->is_leader()) {
-    if (pending_mdsmap.up.count(mds_rank_t(rank_or_gid))) {
-      dout(10) << __func__ << ": validated rank/GID " << rank_or_gid
-	       << " as a rank" << dendl;
-      mds_gid_t gid = pending_mdsmap.up[mds_rank_t(rank_or_gid)];
-      if (pending_mdsmap.mds_info.count(gid)) {
-	return gid;
-      } else {
-	dout(10) << __func__ << ": GID " << rank_or_gid << " was removed." << dendl;
-	return MDS_GID_NONE;
+	     << "' as an integer " << maybe_gid << dendl;
+    if (mon->is_leader()) {
+      if (pending_fsmap.gid_exists(mds_gid_t(maybe_gid))) {
+        return mds_gid_t(maybe_gid);
+      }
+    } else {
+      if (fsmap.gid_exists(mds_gid_t(maybe_gid))) {
+        return mds_gid_t(maybe_gid);
       }
-    } else if (pending_mdsmap.mds_info.count(mds_gid_t(rank_or_gid))) {
-      dout(10) << __func__ << ": validated rank/GID " << rank_or_gid
-	       << " as a GID" << dendl;
-      return mds_gid_t(rank_or_gid);
-    }
-  } else {
-    // mon is a peon
-    if (mdsmap.have_inst(mds_rank_t(rank_or_gid))) {
-      return mdsmap.get_info(mds_rank_t(rank_or_gid)).global_id;
-    } else if (mdsmap.get_state_gid(mds_gid_t(rank_or_gid))) {
-      return mds_gid_t(rank_or_gid);
     }
   }
 
-  dout(1) << __func__ << ": rank/GID " << rank_or_gid
+  dout(1) << __func__ << ": rank/GID " << arg
 	  << " not a existent rank or GID" << dendl;
   return MDS_GID_NONE;
 }
@@ -1087,6 +1353,20 @@ bool MDSMonitor::prepare_command(MonOpRequestRef op)
     return true;
   }
 
+  for (auto h : handlers) {
+    if (h->can_handle(prefix)) {
+      r = h->handle(mon, pending_fsmap, op, cmdmap, ss);
+      if (r == -EAGAIN) {
+        // message has been enqueued for retry; return.
+        dout(4) << __func__ << " enqueue for retry by management_command" << dendl;
+        return false;
+      } else {
+        // Successful or not, we're done: respond.
+        goto out;
+      }
+    }
+  }
+
   /* Execute filesystem add/remove, or pass through to filesystem_command */
   r = management_command(op, prefix, cmdmap, ss);
   if (r >= 0)
@@ -1094,6 +1374,7 @@ bool MDSMonitor::prepare_command(MonOpRequestRef op)
   
   if (r == -EAGAIN) {
     // message has been enqueued for retry; return.
+    dout(4) << __func__ << " enqueue for retry by management_command" << dendl;
     return false;
   } else if (r != -ENOSYS) {
     // MDSMonitor::management_command() returns -ENOSYS if it knows nothing
@@ -1104,18 +1385,36 @@ bool MDSMonitor::prepare_command(MonOpRequestRef op)
     goto out;
   }
 
-  if (!pending_mdsmap.get_enabled()) {
-    ss << "No filesystem configured: use `ceph fs new` to create a filesystem";
-    r = -ENOENT;
-  } else {
-    r = filesystem_command(op, prefix, cmdmap, ss);
-    if (r < 0 && r == -EAGAIN) {
-      // Do not reply, the message has been enqueued for retry
-      return false;
+  r = filesystem_command(op, prefix, cmdmap, ss);
+  if (r >= 0) {
+    goto out;
+  } else if (r == -EAGAIN) {
+    // Do not reply, the message has been enqueued for retry
+    dout(4) << __func__ << " enqueue for retry by filesystem_command" << dendl;
+    return false;
+  } else if (r != -ENOSYS) {
+    goto out;
+  }
+
+  // Only handle legacy commands if there is a filesystem configured
+  if (pending_fsmap.legacy_client_fscid == FS_CLUSTER_ID_NONE) {
+    if (pending_fsmap.filesystems.size() == 0) {
+      ss << "No filesystem configured: use `ceph fs new` to create a filesystem";
+    } else {
+      ss << "No filesystem set for use with legacy commands";
     }
+    r = -EINVAL;
+    goto out;
+  }
+
+  r = legacy_filesystem_command(op, prefix, cmdmap, ss);
+
+  if (r == -ENOSYS && ss.str().empty()) {
+    ss << "unrecognized command";
   }
 
 out:
+  dout(4) << __func__ << " done, r=" << r << dendl;
   /* Compose response */
   string rs;
   getline(ss, rs);
@@ -1186,6 +1485,49 @@ int MDSMonitor::_check_pool(
   return 0;
 }
 
+class FlagSetHandler : public FileSystemCommandHandler
+{
+  public:
+  FlagSetHandler()
+    : FileSystemCommandHandler("fs flag set")
+  {
+  }
+
+  int handle(
+      Monitor *mon,
+      FSMap &fsmap,
+      MonOpRequestRef op,
+      map<string, cmd_vartype> &cmdmap,
+      std::stringstream &ss)
+  {
+    string flag_name;
+    cmd_getval(g_ceph_context, cmdmap, "flag_name", flag_name);
+
+    string flag_val;
+    cmd_getval(g_ceph_context, cmdmap, "val", flag_val);
+
+    if (flag_name == "enable_multiple") {
+      bool flag_bool = false;
+      int r = parse_bool(flag_val, &flag_bool, ss);
+      if (r != 0) {
+        ss << "Invalid boolean value '" << flag_val << "'";
+        return r;
+      }
+
+      bool jewel = mon->get_quorum_features() && CEPH_FEATURE_SERVER_JEWEL;
+      if (flag_bool && !jewel) {
+        ss << "Multiple-filesystems are forbidden until all mons are updated";
+        return -EINVAL;
+      }
+
+      fsmap.set_enable_multiple(flag_bool);
+      return 0;
+    } else {
+      ss << "Unknown flag '" << flag_name << "'";
+      return -EINVAL;
+    }
+  }
+};
 
 /**
  * Handle a command for creating or removing a filesystem.
@@ -1202,56 +1544,13 @@ int MDSMonitor::management_command(
     std::stringstream &ss)
 {
   op->mark_mdsmon_event(__func__);
-  if (prefix == "mds newfs") {
-    /* Legacy `newfs` command, takes pool numbers instead of
-     * names, assumes fs name to be MDS_FS_NAME_DEFAULT, and
-     * can overwrite existing filesystem settings */
-    MDSMap newmap;
-    int64_t metadata, data;
-
-    if (!cmd_getval(g_ceph_context, cmdmap, "metadata", metadata)) {
-      ss << "error parsing 'metadata' value '"
-         << cmd_vartype_stringify(cmdmap["metadata"]) << "'";
-      return -EINVAL;
-    }
-    if (!cmd_getval(g_ceph_context, cmdmap, "data", data)) {
-      ss << "error parsing 'data' value '"
-         << cmd_vartype_stringify(cmdmap["data"]) << "'";
-      return -EINVAL;
-    }
- 
-    int r = _check_pool(data, &ss);
-    if (r < 0) {
-      return r;
-    }
-
-    r = _check_pool(metadata, &ss);
-    if (r < 0) {
-      return r;
-    }
 
-    // be idempotent.. success if it already exists and matches
-    if (mdsmap.get_enabled() &&
-	mdsmap.get_metadata_pool() == metadata &&
-	mdsmap.get_first_data_pool() == data &&
-	mdsmap.fs_name == MDS_FS_NAME_DEFAULT) {
-      ss << "filesystem '" << MDS_FS_NAME_DEFAULT << "' already exists";
-      return 0;
-    }
-
-    string sure;
-    cmd_getval(g_ceph_context, cmdmap, "sure", sure);
-    if (pending_mdsmap.get_enabled() && sure != "--yes-i-really-mean-it") {
-      ss << "this is DANGEROUS and will wipe out the mdsmap's fs, and may clobber data in the new pools you specify.  add --yes-i-really-mean-it if you do.";
-      return -EPERM;
-    } else {
-      newmap.inc = pending_mdsmap.inc;
-      pending_mdsmap = newmap;
-      pending_mdsmap.epoch = mdsmap.epoch + 1;
-      create_new_fs(pending_mdsmap, MDS_FS_NAME_DEFAULT, metadata, data);
-      ss << "new fs with metadata pool " << metadata << " and data pool " << data;
-      return 0;
-    }
+  if (prefix == "mds newfs") {
+    // newfs is the legacy command that in single-filesystem times
+    // used to be equivalent to doing an "fs rm ; fs new".  We
+    // can't do this in a sane way in multi-filesystem world.
+    ss << "'newfs' no longer available.  Please use 'fs new'.";
+    return -EINVAL;
   } else if (prefix == "fs new") {
     string metadata_name;
     cmd_getval(g_ceph_context, cmdmap, "metadata", metadata_name);
@@ -1268,6 +1567,10 @@ int MDSMonitor::management_command(
       ss << "pool '" << data_name << "' does not exist";
       return -ENOENT;
     }
+    if (data == 0) {
+      ss << "pool '" << data_name << "' has id 0, which CephFS does not allow. Use another pool or recreate it to get a non-zero pool id.";
+      return -EINVAL;
+    }
    
     string fs_name;
     cmd_getval(g_ceph_context, cmdmap, "fs_name", fs_name);
@@ -1278,18 +1581,24 @@ int MDSMonitor::management_command(
         return -EINVAL;
     }
 
-    if (pending_mdsmap.get_enabled()
-        && pending_mdsmap.fs_name == fs_name
-        && *(pending_mdsmap.data_pools.begin()) == data
-        && pending_mdsmap.metadata_pool == metadata) {
-      // Identical FS created already, this is a no-op
-      ss << "filesystem '" << fs_name << "' already exists";
-      return 0;
+    if (pending_fsmap.get_filesystem(fs_name)) {
+      auto fs = pending_fsmap.get_filesystem(fs_name);
+      if (*(fs->mds_map.data_pools.begin()) == data
+          && fs->mds_map.metadata_pool == metadata) {
+        // Identical FS created already, this is a no-op
+        ss << "filesystem '" << fs_name << "' already exists";
+        return 0;
+      } else {
+        ss << "filesystem already exists with name '" << fs_name << "'";
+        return -EINVAL;
+      }
     }
 
-    if (pending_mdsmap.get_enabled()) {
-      /* We currently only support one filesystem, so cannot create a second */
-      ss << "A filesystem already exists, use `ceph fs rm` if you wish to delete it";
+    if (pending_fsmap.any_filesystems()
+        && !pending_fsmap.get_enable_multiple()) {
+      ss << "Creation of multiple filesystems is disabled.  To enable "
+            "this experimental feature, use 'ceph fs flag set enable_multiple "
+            "true'";
       return -EINVAL;
     }
 
@@ -1330,12 +1639,7 @@ int MDSMonitor::management_command(
     }
 
     // All checks passed, go ahead and create.
-    MDSMap newmap;
-    newmap.inc = pending_mdsmap.inc;
-    pending_mdsmap = newmap;
-    pending_mdsmap.epoch = mdsmap.epoch + 1;
-    pending_mdsmap.last_failure_osd_epoch = mdsmap.last_failure_osd_epoch;
-    create_new_fs(pending_mdsmap, fs_name, metadata, data);
+    create_new_fs(pending_fsmap, fs_name, metadata, data);
     ss << "new fs with metadata pool " << metadata << " and data pool " << data;
     return 0;
   } else if (prefix == "fs rm") {
@@ -1344,14 +1648,15 @@ int MDSMonitor::management_command(
     //  syntax should apply to multi-FS future)
     string fs_name;
     cmd_getval(g_ceph_context, cmdmap, "fs_name", fs_name);
-    if (!pending_mdsmap.get_enabled() || fs_name != pending_mdsmap.fs_name) {
+    auto fs = pending_fsmap.get_filesystem(fs_name);
+    if (fs == nullptr) {
         // Consider absence success to make deletes idempotent
         ss << "filesystem '" << fs_name << "' does not exist";
         return 0;
     }
 
     // Check that no MDS daemons are active
-    if (!pending_mdsmap.up.empty()) {
+    if (!fs->mds_map.up.empty()) {
       ss << "all MDS daemons must be inactive before removing filesystem";
       return -EINVAL;
     }
@@ -1365,27 +1670,31 @@ int MDSMonitor::management_command(
       return -EPERM;
     }
 
-    MDSMap newmap;
-    newmap.inc = pending_mdsmap.inc;
-    pending_mdsmap = newmap;
-    pending_mdsmap.epoch = mdsmap.epoch + 1;
-    assert(pending_mdsmap.get_enabled() == false);
-    pending_mdsmap.metadata_pool = -1;
-    pending_mdsmap.cas_pool = -1;
-    pending_mdsmap.created = ceph_clock_now(g_ceph_context);
+    if (pending_fsmap.legacy_client_fscid == fs->fscid) {
+      pending_fsmap.legacy_client_fscid = FS_CLUSTER_ID_NONE;
+    }
+
+    // There may be standby_replay daemons left here
+    for (const auto &i : fs->mds_map.mds_info) {
+      assert(i.second.state == MDSMap::STATE_STANDBY_REPLAY);
+      fail_mds_gid(i.first);
+    }
+
+    pending_fsmap.filesystems.erase(fs->fscid);
 
     return 0;
   } else if (prefix == "fs reset") {
     string fs_name;
     cmd_getval(g_ceph_context, cmdmap, "fs_name", fs_name);
-    if (!pending_mdsmap.get_enabled() || fs_name != pending_mdsmap.fs_name) {
+    auto fs = pending_fsmap.get_filesystem(fs_name);
+    if (fs == nullptr) {
         ss << "filesystem '" << fs_name << "' does not exist";
         // Unlike fs rm, we consider this case an error
         return -ENOENT;
     }
 
     // Check that no MDS daemons are active
-    if (!pending_mdsmap.up.empty()) {
+    if (!fs->mds_map.up.empty()) {
       ss << "all MDS daemons must be inactive before resetting filesystem: set the cluster_down flag"
             " and use `ceph mds fail` to make this so";
       return -EINVAL;
@@ -1400,32 +1709,35 @@ int MDSMonitor::management_command(
       return -EPERM;
     }
 
-    MDSMap newmap;
+    FSMap newmap;
+
+    auto new_fs = std::make_shared<Filesystem>();
 
     // Populate rank 0 as existing (so don't go into CREATING)
     // but failed (so that next available MDS is assigned the rank)
-    newmap.in.insert(mds_rank_t(0));
-    newmap.failed.insert(mds_rank_t(0));
+    new_fs->mds_map.in.insert(mds_rank_t(0));
+    new_fs->mds_map.failed.insert(mds_rank_t(0));
 
     // Carry forward what makes sense
-    newmap.data_pools = mdsmap.data_pools;
-    newmap.metadata_pool = mdsmap.metadata_pool;
-    newmap.cas_pool = mdsmap.cas_pool;
-    newmap.fs_name = mdsmap.fs_name;
-    newmap.created = ceph_clock_now(g_ceph_context);
-    newmap.epoch = mdsmap.epoch + 1;
-    newmap.inc = mdsmap.inc;
-    newmap.enabled = mdsmap.enabled;
-    newmap.inline_data_enabled = mdsmap.inline_data_enabled;
-    newmap.compat = get_mdsmap_compat_set_default();
-    newmap.session_timeout = g_conf->mds_session_timeout;
-    newmap.session_autoclose = g_conf->mds_session_autoclose;
-    newmap.max_file_size = g_conf->mds_max_file_size;
-
-    // Persist the new MDSMap
-    pending_mdsmap = newmap;
+    new_fs->fscid = fs->fscid;
+    new_fs->mds_map.inc = fs->mds_map.inc;
+    new_fs->mds_map.inline_data_enabled = fs->mds_map.inline_data_enabled;
+    new_fs->mds_map.max_mds = g_conf->max_mds;
+    new_fs->mds_map.data_pools = fs->mds_map.data_pools;
+    new_fs->mds_map.metadata_pool = fs->mds_map.metadata_pool;
+    new_fs->mds_map.cas_pool = fs->mds_map.cas_pool;
+    new_fs->mds_map.fs_name = fs->mds_map.fs_name;
+    new_fs->mds_map.max_file_size = g_conf->mds_max_file_size;
+    new_fs->mds_map.compat = fsmap.compat;
+    new_fs->mds_map.created = ceph_clock_now(g_ceph_context);
+    new_fs->mds_map.modified = ceph_clock_now(g_ceph_context);
+    new_fs->mds_map.session_timeout = g_conf->mds_session_timeout;
+    new_fs->mds_map.session_autoclose = g_conf->mds_session_autoclose;
+    new_fs->mds_map.enabled = true;
+
+    // Persist the new FSMap
+    pending_fsmap.filesystems[new_fs->fscid] = new_fs;
     return 0;
-
   } else {
     return -ENOSYS;
   }
@@ -1433,67 +1745,53 @@ int MDSMonitor::management_command(
 
 
 /**
- * Handle a command that affects the filesystem (i.e. a filesystem
- * must exist for the command to act upon).
+ * Given one of the following forms:
+ *   <fs name>:<rank>
+ *   <fs id>:<rank>
+ *   <rank>
  *
- * @retval 0        Command was successfully handled and has side effects
- * @retval -EAGAIN  Messages has been requeued for retry
- * @retval -ENOSYS  Unknown command
- * @retval < 0      An error has occurred; **ss** may have been set.
+ * Parse into a mds_role_t.  The rank-only form is only valid
+ * if legacy_client_ns is set.
  */
-int MDSMonitor::filesystem_command(
-    MonOpRequestRef op,
-    std::string const &prefix,
-    map<string, cmd_vartype> &cmdmap,
-    std::stringstream &ss)
+int MDSMonitor::parse_role(
+    const std::string &role_str,
+    mds_role_t *role,
+    std::ostream &ss)
 {
-  op->mark_mdsmon_event(__func__);
-  MMonCommand *m = static_cast<MMonCommand*>(op->get_req());
-  int r = 0;
-  string whostr;
-  cmd_getval(g_ceph_context, cmdmap, "who", whostr);
-  if (prefix == "mds stop" ||
-      prefix == "mds deactivate") {
+  const FSMap *relevant_fsmap = &fsmap;
+  if (mon->is_leader()) {
+    relevant_fsmap = &pending_fsmap;
+  }
+  return relevant_fsmap->parse_role(role_str, role, ss);
+}
+
 
-    int who_i = parse_pos_long(whostr.c_str(), &ss);
-    if (who_i < 0) {
+class SetHandler : public FileSystemCommandHandler
+{
+public:
+  SetHandler()
+    : FileSystemCommandHandler("fs set")
+  {}
+
+  virtual int handle(
+      Monitor *mon,
+      FSMap &fsmap,
+      MonOpRequestRef op,
+      map<string, cmd_vartype> &cmdmap,
+      std::stringstream &ss)
+  {
+    std::string fs_name;
+    if (!cmd_getval(g_ceph_context, cmdmap, "fs_name", fs_name) || fs_name.empty()) {
+      ss << "Missing filesystem name";
       return -EINVAL;
     }
-    mds_rank_t who = mds_rank_t(who_i);
-    if (!pending_mdsmap.is_active(who)) {
-      r = -EEXIST;
-      ss << "mds." << who << " not active (" 
-	 << ceph_mds_state_name(pending_mdsmap.get_state(who)) << ")";
-    } else if (pending_mdsmap.get_root() == who ||
-		pending_mdsmap.get_tableserver() == who) {
-      r = -EINVAL;
-      ss << "can't tell the root (" << pending_mdsmap.get_root()
-	 << ") or tableserver (" << pending_mdsmap.get_tableserver()
-	 << ") to deactivate";
-    } else if (pending_mdsmap.get_num_in_mds() <= size_t(pending_mdsmap.get_max_mds())) {
-      r = -EBUSY;
-      ss << "must decrease max_mds or else MDS will immediately reactivate";
-    } else {
-      r = 0;
-      mds_gid_t gid = pending_mdsmap.up[who];
-      ss << "telling mds." << who << " " << pending_mdsmap.mds_info[gid].addr << " to deactivate";
-      pending_mdsmap.mds_info[gid].state = MDSMap::STATE_STOPPING;
+
+    auto fs = fsmap.get_filesystem(fs_name);
+    if (fs == nullptr) {
+      ss << "Not found: '" << fs_name << "'";
+      return -ENOENT;
     }
 
-  } else if (prefix == "mds set_max_mds") {
-    // NOTE: see also "mds set max_mds", which can modify the same field.
-    int64_t maxmds;
-    if (!cmd_getval(g_ceph_context, cmdmap, "maxmds", maxmds) || maxmds < 0) {
-      return -EINVAL;
-    }
-    if (maxmds > MAX_MDS) {
-      ss << "may not have more than " << MAX_MDS << " MDS ranks";
-      return -EINVAL;
-    }
-    pending_mdsmap.max_mds = maxmds;
-    r = 0;
-    ss << "max_mds = " << pending_mdsmap.max_mds;
-  } else if (prefix == "mds set") {
     string var;
     if (!cmd_getval(g_ceph_context, cmdmap, "var", var) || var.empty()) {
       ss << "Invalid variable";
@@ -1516,9 +1814,20 @@ int MDSMonitor::filesystem_command(
         ss << "may not have more than " << MAX_MDS << " MDS ranks";
         return -EINVAL;
       }
-      pending_mdsmap.max_mds = n;
+      fsmap.modify_filesystem(
+          fs->fscid,
+          [n](std::shared_ptr<Filesystem> fs)
+      {
+        fs->mds_map.set_max_mds(n);
+      });
     } else if (var == "inline_data") {
-      if (val == "true" || val == "yes" || (!interr.length() && n == 1)) {
+      bool enable_inline = false;
+      int r = parse_bool(val, &enable_inline, ss);
+      if (r != 0) {
+        return r;
+      }
+
+      if (enable_inline) {
 	string confirm;
 	if (!cmd_getval(g_ceph_context, cmdmap, "confirm", confirm) ||
 	    confirm != "--yes-i-really-mean-it") {
@@ -1526,15 +1835,26 @@ int MDSMonitor::filesystem_command(
 	  return -EPERM;
 	}
 	ss << "inline data enabled";
-	pending_mdsmap.set_inline_data_enabled(true);
-	pending_mdsmap.compat.incompat.insert(MDS_FEATURE_INCOMPAT_INLINE);
-      } else if (val == "false" || val == "no" ||
-		 (!interr.length() && n == 0)) {
-	ss << "inline data disabled";
-	pending_mdsmap.set_inline_data_enabled(false);
+
+        fsmap.modify_filesystem(
+            fs->fscid,
+            [](std::shared_ptr<Filesystem> fs)
+        {
+          fs->mds_map.set_inline_data_enabled(true);
+        });
+
+        // Update `compat`
+        CompatSet c = fsmap.get_compat();
+        c.incompat.insert(MDS_FEATURE_INCOMPAT_INLINE);
+        fsmap.update_compat(c);
       } else {
-	ss << "value must be false|no|0 or true|yes|1";
-	return -EINVAL;
+	ss << "inline data disabled";
+        fsmap.modify_filesystem(
+            fs->fscid,
+            [](std::shared_ptr<Filesystem> fs)
+        {
+          fs->mds_map.set_inline_data_enabled(false);
+        });
       }
     } else if (var == "max_file_size") {
       if (interr.length()) {
@@ -1545,59 +1865,289 @@ int MDSMonitor::filesystem_command(
 	ss << var << " must at least " << CEPH_MIN_STRIPE_UNIT;
 	return -ERANGE;
       }
-      pending_mdsmap.max_file_size = n;
+      fsmap.modify_filesystem(
+          fs->fscid,
+          [n](std::shared_ptr<Filesystem> fs)
+      {
+        fs->mds_map.set_max_filesize(n);
+      });
     } else if (var == "allow_new_snaps") {
-      if (val == "false" || val == "no" || (interr.length() == 0 && n == 0)) {
-	pending_mdsmap.clear_snaps_allowed();
+      bool enable_snaps = false;
+      int r = parse_bool(val, &enable_snaps, ss);
+      if (r != 0) {
+        return r;
+      }
+
+      if (!enable_snaps) {
+        fsmap.modify_filesystem(
+            fs->fscid,
+            [](std::shared_ptr<Filesystem> fs)
+        {
+          fs->mds_map.clear_snaps_allowed();
+        });
 	ss << "disabled new snapshots";
-      } else if (val == "true" || val == "yes" || (interr.length() == 0 && n == 1)) {
+      } else {
 	string confirm;
 	if (!cmd_getval(g_ceph_context, cmdmap, "confirm", confirm) ||
 	    confirm != "--yes-i-really-mean-it") {
 	  ss << "Snapshots are unstable and will probably break your FS! Set to --yes-i-really-mean-it if you are sure you want to enable them";
 	  return -EPERM;
 	}
-	pending_mdsmap.set_snaps_allowed();
+        fsmap.modify_filesystem(
+            fs->fscid,
+            [](std::shared_ptr<Filesystem> fs)
+        {
+          fs->mds_map.set_snaps_allowed();
+        });
 	ss << "enabled new snapshots";
-      } else {
-	ss << "value must be true|yes|1 or false|no|0";
-	return -EINVAL;
       }
+    } else if (var == "cluster_down") {
+      bool is_down = false;
+      int r = parse_bool(val, &is_down, ss);
+      if (r != 0) {
+        return r;
+      }
+
+      fsmap.modify_filesystem(
+          fs->fscid,
+          [is_down](std::shared_ptr<Filesystem> fs)
+      {
+        if (is_down) {
+          fs->mds_map.set_flag(CEPH_MDSMAP_DOWN);
+        } else {
+          fs->mds_map.clear_flag(CEPH_MDSMAP_DOWN);
+        }
+      });
+
+      ss << "marked " << (is_down ? "down" : "up");
     } else {
       ss << "unknown variable " << var;
       return -EINVAL;
     }
-    r = 0;
-  } else if (prefix == "mds setmap") {
-    string confirm;
-    if (!cmd_getval(g_ceph_context, cmdmap, "confirm", confirm) ||
-	confirm != "--yes-i-really-mean-it") {
-      ss << "WARNING: this can make your filesystem inaccessible! "
-	    "Add --yes-i-really-mean-it if you are sure you wish to continue.";
-      return -EINVAL;;
+
+    return 0;
+  }
+};
+
+class AddDataPoolHandler : public FileSystemCommandHandler
+{
+  public:
+  AddDataPoolHandler()
+    : FileSystemCommandHandler("fs add_data_pool")
+  {}
+
+  int handle(
+      Monitor *mon,
+      FSMap &fsmap,
+      MonOpRequestRef op,
+      map<string, cmd_vartype> &cmdmap,
+      std::stringstream &ss)
+  {
+    string poolname;
+    cmd_getval(g_ceph_context, cmdmap, "pool", poolname);
+
+    std::string fs_name;
+    if (!cmd_getval(g_ceph_context, cmdmap, "fs_name", fs_name)
+        || fs_name.empty()) {
+      ss << "Missing filesystem name";
+      return -EINVAL;
+    }
+
+    auto fs = fsmap.get_filesystem(fs_name);
+    if (fs == nullptr) {
+      ss << "Not found: '" << fs_name << "'";
+      return -ENOENT;
+    }
+
+    int64_t poolid = mon->osdmon()->osdmap.lookup_pg_pool_name(poolname);
+    if (poolid < 0) {
+      string err;
+      poolid = strict_strtol(poolname.c_str(), 10, &err);
+      if (err.length()) {
+	ss << "pool '" << poolname << "' does not exist";
+	return -ENOENT;
+      }
     }
 
-    MDSMap map;
-    try {
-      map.decode(m->get_data());
-    } catch(buffer::error &e) {
-      ss << "invalid mdsmap";
+    int r = _check_pool(mon->osdmon()->osdmap, poolid, &ss);
+    if (r != 0) {
+      return r;
+    }
+
+    fsmap.modify_filesystem(
+        fs->fscid,
+        [poolid](std::shared_ptr<Filesystem> fs)
+    {
+      fs->mds_map.add_data_pool(poolid);
+    });
+
+    ss << "added data pool " << poolid << " to fsmap";
+
+    return 0;
+  }
+};
+
+
+class RemoveDataPoolHandler : public FileSystemCommandHandler
+{
+  public:
+  RemoveDataPoolHandler()
+    : FileSystemCommandHandler("fs rm_data_pool")
+  {}
+
+  int handle(
+      Monitor *mon,
+      FSMap &fsmap,
+      MonOpRequestRef op,
+      map<string, cmd_vartype> &cmdmap,
+      std::stringstream &ss)
+  {
+    string poolname;
+    cmd_getval(g_ceph_context, cmdmap, "pool", poolname);
+
+    std::string fs_name;
+    if (!cmd_getval(g_ceph_context, cmdmap, "fs_name", fs_name)
+        || fs_name.empty()) {
+      ss << "Missing filesystem name";
       return -EINVAL;
     }
-    epoch_t e = 0;
-    int64_t epochnum;
-    if (cmd_getval(g_ceph_context, cmdmap, "epoch", epochnum))
-      e = epochnum;
 
-    if (pending_mdsmap.epoch == e) {
-      map.epoch = pending_mdsmap.epoch;  // make sure epoch is correct
-      pending_mdsmap = map;
-      ss << "set mds map";
-    } else {
-      ss << "next mdsmap epoch " << pending_mdsmap.epoch << " != " << e;
+    auto fs = fsmap.get_filesystem(fs_name);
+    if (fs == nullptr) {
+      ss << "Not found: '" << fs_name << "'";
+      return -ENOENT;
+    }
+
+    int64_t poolid = mon->osdmon()->osdmap.lookup_pg_pool_name(poolname);
+    if (poolid < 0) {
+      string err;
+      poolid = strict_strtol(poolname.c_str(), 10, &err);
+      if (err.length()) {
+	poolid = -1;
+	ss << "pool '" << poolname << "' does not exist";
+        return -ENOENT;
+      } else if (poolid < 0) {
+        ss << "invalid pool id '" << poolid << "'";
+        return -EINVAL;
+      }
+    }
+
+    assert(poolid >= 0);  // Checked by parsing code above
+
+    if (fs->mds_map.get_first_data_pool() == poolid) {
+      poolid = -1;
+      ss << "cannot remove default data pool";
       return -EINVAL;
     }
 
+
+    int r = 0;
+    fsmap.modify_filesystem(fs->fscid,
+        [&r, poolid](std::shared_ptr<Filesystem> fs)
+    {
+      r = fs->mds_map.remove_data_pool(poolid);
+    });
+    if (r == -ENOENT) {
+      // It was already removed, succeed in silence
+      return 0;
+    } else if (r == 0) {
+      // We removed it, succeed
+      ss << "removed data pool " << poolid << " from fsmap";
+      return 0;
+    } else {
+      // Unexpected error, bubble up
+      return r;
+    }
+  }
+};
+
+
+/**
+ * For commands that refer to a particular filesystem,
+ * enable wrapping to implement the legacy version of
+ * the command (like "mds add_data_pool" vs "fs add_data_pool")
+ *
+ * The wrapped handler must expect a fs_name argument in
+ * its command map.
+ */
+template<typename T>
+class LegacyHandler : public T
+{
+  std::string legacy_prefix;
+
+  public:
+  LegacyHandler(const std::string &new_prefix)
+    : T()
+  {
+    legacy_prefix = new_prefix;
+  }
+
+  virtual std::string const &get_prefix() {return legacy_prefix;}
+
+  int handle(
+      Monitor *mon,
+      FSMap &fsmap,
+      MonOpRequestRef op,
+      map<string, cmd_vartype> &cmdmap,
+      std::stringstream &ss)
+  {
+    auto fs = fsmap.get_legacy_filesystem();
+    if (fs == nullptr) {
+      ss << "No filesystem configured";
+      return -ENOENT;
+    }
+    std::map<string, cmd_vartype> modified = cmdmap;
+    modified["fs_name"] = fs->mds_map.get_fs_name();
+    return T::handle(mon, fsmap, op, modified, ss);
+  }
+};
+
+int MDSMonitor::filesystem_command(
+    MonOpRequestRef op,
+    std::string const &prefix,
+    map<string, cmd_vartype> &cmdmap,
+    std::stringstream &ss)
+{
+  dout(4) << __func__ << " prefix='" << prefix << "'" << dendl;
+  op->mark_mdsmon_event(__func__);
+  MMonCommand *m = static_cast<MMonCommand*>(op->get_req());
+  int r = 0;
+  string whostr;
+  cmd_getval(g_ceph_context, cmdmap, "who", whostr);
+
+  if (prefix == "mds stop" ||
+      prefix == "mds deactivate") {
+
+    mds_role_t role;
+    r = parse_role(whostr, &role, ss);
+    if (r < 0 ) {
+      return r;
+    }
+    auto fs = pending_fsmap.get_filesystem(role.fscid);
+
+    if (!fs->mds_map.is_active(role.rank)) {
+      r = -EEXIST;
+      ss << "mds." << role << " not active (" 
+	 << ceph_mds_state_name(fs->mds_map.get_state(role.rank)) << ")";
+    } else if (fs->mds_map.get_root() == role.rank ||
+		fs->mds_map.get_tableserver() == role.rank) {
+      r = -EINVAL;
+      ss << "can't tell the root (" << fs->mds_map.get_root()
+	 << ") or tableserver (" << fs->mds_map.get_tableserver()
+	 << ") to deactivate";
+    } else if (fs->mds_map.get_num_in_mds() <= size_t(fs->mds_map.get_max_mds())) {
+      r = -EBUSY;
+      ss << "must decrease max_mds or else MDS will immediately reactivate";
+    } else {
+      r = 0;
+      mds_gid_t gid = fs->mds_map.up.at(role.rank);
+      ss << "telling mds." << role << " "
+         << pending_fsmap.get_info_gid(gid).addr << " to deactivate";
+
+      pending_fsmap.modify_daemon(gid, [](MDSMap::mds_info_t *info) {
+        info->state = MDSMap::STATE_STOPPING;
+      });
+    }
   } else if (prefix == "mds set_state") {
     mds_gid_t gid;
     if (!cmd_getval(g_ceph_context, cmdmap, "gid", gid)) {
@@ -1611,14 +2161,15 @@ int MDSMonitor::filesystem_command(
          << cmd_vartype_stringify(cmdmap["state"]) << "'";
       return -EINVAL;
     }
-    if (!pending_mdsmap.is_dne_gid(gid)) {
-      MDSMap::mds_info_t& info = pending_mdsmap.get_info_gid(gid);
-      info.state = state;
+    if (pending_fsmap.gid_exists(gid)) {
+      pending_fsmap.modify_daemon(gid, [state](MDSMap::mds_info_t *info) {
+        info->state = state;
+      });
       stringstream ss;
-      ss << "set mds gid " << gid << " to state " << state << " " << ceph_mds_state_name(state);
+      ss << "set mds gid " << gid << " to state " << state << " "
+         << ceph_mds_state_name(state);
       return 0;
     }
-
   } else if (prefix == "mds fail") {
     string who;
     cmd_getval(g_ceph_context, cmdmap, "who", who);
@@ -1627,18 +2178,6 @@ int MDSMonitor::filesystem_command(
       mon->osdmon()->wait_for_writeable(op, new C_RetryMessage(this, op));
       return -EAGAIN; // don't propose yet; wait for message to be retried
     }
-
-  } else if (prefix == "mds repaired") {
-    mds_rank_t rank;
-    cmd_getval(g_ceph_context, cmdmap, "rank", rank);
-    if (pending_mdsmap.damaged.count(rank)) {
-      dout(4) << "repaired: restoring rank " << rank << dendl;
-      pending_mdsmap.damaged.erase(rank);
-      pending_mdsmap.failed.insert(rank);
-    } else {
-      dout(4) << "repaired: no-op on rank " << rank << dendl;
-    }
-    r = 0;
   } else if (prefix == "mds rm") {
     mds_gid_t gid;
     if (!cmd_getval(g_ceph_context, cmdmap, "gid", gid)) {
@@ -1646,54 +2185,50 @@ int MDSMonitor::filesystem_command(
          << cmd_vartype_stringify(cmdmap["gid"]) << "'";
       return -EINVAL;
     }
-    int state = pending_mdsmap.get_state_gid(gid);
-    if (state == 0) {
+    if (!pending_fsmap.gid_exists(gid)) {
       ss << "mds gid " << gid << " dne";
       r = 0;
-    } else if (state > 0) {
-      ss << "cannot remove active mds." << pending_mdsmap.get_info_gid(gid).name
-	 << " rank " << pending_mdsmap.get_info_gid(gid).rank;
-      return -EBUSY;
     } else {
-      pending_mdsmap.mds_info.erase(gid);
-      stringstream ss;
-      ss << "removed mds gid " << gid;
-      return 0;
+      MDSMap::DaemonState state = pending_fsmap.get_info_gid(gid).state;
+      if (state > 0) {
+        ss << "cannot remove active mds." << pending_fsmap.get_info_gid(gid).name
+           << " rank " << pending_fsmap.get_info_gid(gid).rank;
+        return -EBUSY;
+      } else {
+        pending_fsmap.erase(gid, {});
+        stringstream ss;
+        ss << "removed mds gid " << gid;
+        return 0;
+      }
     }
   } else if (prefix == "mds rmfailed") {
-    mds_rank_t who;
     string confirm;
     if (!cmd_getval(g_ceph_context, cmdmap, "confirm", confirm) ||
-	confirm != "--yes-i-really-mean-it") {
-	  ss << "WARNING: this can make your filesystem inaccessible! "
-		"Add --yes-i-really-mean-it if you are sure you wish to continue.";
-	  return -EPERM;
+       confirm != "--yes-i-really-mean-it") {
+         ss << "WARNING: this can make your filesystem inaccessible! "
+               "Add --yes-i-really-mean-it if you are sure you wish to continue.";
+         return -EPERM;
     }
-    if (!cmd_getval(g_ceph_context, cmdmap, "who", who)) {
-      ss << "error parsing 'who' value '"
-         << cmd_vartype_stringify(cmdmap["who"]) << "'";
+    
+    std::string role_str;
+    cmd_getval(g_ceph_context, cmdmap, "who", role_str);
+    mds_role_t role;
+    int r = parse_role(role_str, &role, ss);
+    if (r < 0) {
+      ss << "invalid role '" << role_str << "'";
       return -EINVAL;
     }
-    pending_mdsmap.failed.erase(who);
+
+    pending_fsmap.modify_filesystem(
+        role.fscid,
+        [role](std::shared_ptr<Filesystem> fs)
+    {
+      fs->mds_map.failed.erase(role.rank);
+    });
+
     stringstream ss;
-    ss << "removed failed mds." << who;
+    ss << "removed failed mds." << role;
     return 0;
-  } else if (prefix == "mds cluster_down") {
-    if (pending_mdsmap.test_flag(CEPH_MDSMAP_DOWN)) {
-      ss << "mdsmap already marked DOWN";
-    } else {
-      pending_mdsmap.set_flag(CEPH_MDSMAP_DOWN);
-      ss << "marked mdsmap DOWN";
-    }
-    r = 0;
-  } else if (prefix == "mds cluster_up") {
-    if (pending_mdsmap.test_flag(CEPH_MDSMAP_DOWN)) {
-      pending_mdsmap.clear_flag(CEPH_MDSMAP_DOWN);
-      ss << "unmarked mdsmap DOWN";
-    } else {
-      ss << "mdsmap not marked DOWN";
-    }
-    r = 0;
   } else if (prefix == "mds compat rm_compat") {
     int64_t f;
     if (!cmd_getval(g_ceph_context, cmdmap, "feature", f)) {
@@ -1701,11 +2236,13 @@ int MDSMonitor::filesystem_command(
          << cmd_vartype_stringify(cmdmap["feature"]) << "'";
       return -EINVAL;
     }
-    if (pending_mdsmap.compat.compat.contains(f)) {
+    if (pending_fsmap.compat.compat.contains(f)) {
       ss << "removing compat feature " << f;
-      pending_mdsmap.compat.compat.remove(f);
+      CompatSet modified = pending_fsmap.compat;
+      modified.compat.remove(f);
+      pending_fsmap.update_compat(modified);
     } else {
-      ss << "compat feature " << f << " not present in " << pending_mdsmap.compat;
+      ss << "compat feature " << f << " not present in " << pending_fsmap.compat;
     }
     r = 0;
   } else if (prefix == "mds compat rm_incompat") {
@@ -1715,63 +2252,114 @@ int MDSMonitor::filesystem_command(
          << cmd_vartype_stringify(cmdmap["feature"]) << "'";
       return -EINVAL;
     }
-    if (pending_mdsmap.compat.incompat.contains(f)) {
+    if (pending_fsmap.compat.incompat.contains(f)) {
       ss << "removing incompat feature " << f;
-      pending_mdsmap.compat.incompat.remove(f);
+      CompatSet modified = pending_fsmap.compat;
+      modified.incompat.remove(f);
+      pending_fsmap.update_compat(modified);
     } else {
-      ss << "incompat feature " << f << " not present in " << pending_mdsmap.compat;
+      ss << "incompat feature " << f << " not present in " << pending_fsmap.compat;
     }
     r = 0;
-
-  } else if (prefix == "mds add_data_pool") {
-    string poolname;
-    cmd_getval(g_ceph_context, cmdmap, "pool", poolname);
-    int64_t poolid = mon->osdmon()->osdmap.lookup_pg_pool_name(poolname);
-    if (poolid < 0) {
-      string err;
-      poolid = strict_strtol(poolname.c_str(), 10, &err);
-      if (err.length()) {
-	ss << "pool '" << poolname << "' does not exist";
-	return -ENOENT;
-      }
-    }
-
-    r = _check_pool(poolid, &ss);
-    if (r != 0) {
+  } else if (prefix == "mds repaired") {
+    std::string role_str;
+    cmd_getval(g_ceph_context, cmdmap, "rank", role_str);
+    mds_role_t role;
+    r = parse_role(role_str, &role, ss);
+    if (r < 0) {
       return r;
     }
 
-    pending_mdsmap.add_data_pool(poolid);
-    ss << "added data pool " << poolid << " to mdsmap";
-  } else if (prefix == "mds remove_data_pool") {
-    string poolname;
-    cmd_getval(g_ceph_context, cmdmap, "pool", poolname);
-    int64_t poolid = mon->osdmon()->osdmap.lookup_pg_pool_name(poolname);
-    if (poolid < 0) {
-      string err;
-      poolid = strict_strtol(poolname.c_str(), 10, &err);
-      if (err.length()) {
-	r = -ENOENT;
-	poolid = -1;
-	ss << "pool '" << poolname << "' does not exist";
-      }
+    bool modified = pending_fsmap.undamaged(role.fscid, role.rank);
+    if (modified) {
+      dout(4) << "repaired: restoring rank " << role << dendl;
+    } else {
+      dout(4) << "repaired: no-op on rank " << role << dendl;
     }
 
-    if (pending_mdsmap.get_first_data_pool() == poolid) {
-      r = -EINVAL;
-      poolid = -1;
-      ss << "cannot remove default data pool";
-    }
+    r = 0;
+  } else {
+    return -ENOSYS;
+  }
 
-    if (poolid >= 0) {
-      r = pending_mdsmap.remove_data_pool(poolid);
-      if (r == -ENOENT)
-	r = 0;
-      if (r == 0)
-	ss << "removed data pool " << poolid << " from mdsmap";
+  return r;
+}
+
+/**
+ * Helper to legacy_filesystem_command
+ */
+void MDSMonitor::modify_legacy_filesystem(
+    std::function<void(std::shared_ptr<Filesystem> )> fn)
+{
+  pending_fsmap.modify_filesystem(
+    pending_fsmap.legacy_client_fscid,
+    fn
+  );
+}
+
+
+
+/**
+ * Handle a command that affects the filesystem (i.e. a filesystem
+ * must exist for the command to act upon).
+ *
+ * @retval 0        Command was successfully handled and has side effects
+ * @retval -EAGAIN  Messages has been requeued for retry
+ * @retval -ENOSYS  Unknown command
+ * @retval < 0      An error has occurred; **ss** may have been set.
+ */
+int MDSMonitor::legacy_filesystem_command(
+    MonOpRequestRef op,
+    std::string const &prefix,
+    map<string, cmd_vartype> &cmdmap,
+    std::stringstream &ss)
+{
+  dout(4) << __func__ << " prefix='" << prefix << "'" << dendl;
+  op->mark_mdsmon_event(__func__);
+  int r = 0;
+  string whostr;
+  cmd_getval(g_ceph_context, cmdmap, "who", whostr);
+
+  assert (pending_fsmap.legacy_client_fscid != FS_CLUSTER_ID_NONE);
+
+  if (prefix == "mds set_max_mds") {
+    // NOTE: deprecated by "fs set max_mds"
+    int64_t maxmds;
+    if (!cmd_getval(g_ceph_context, cmdmap, "maxmds", maxmds) || maxmds < 0) {
+      return -EINVAL;
+    }
+    if (maxmds > MAX_MDS) {
+      ss << "may not have more than " << MAX_MDS << " MDS ranks";
+      return -EINVAL;
     }
+
+    modify_legacy_filesystem(
+        [maxmds](std::shared_ptr<Filesystem> fs)
+    {
+      fs->mds_map.set_max_mds(maxmds);
+    });
+
+    r = 0;
+    ss << "max_mds = " << maxmds;
+  } else if (prefix == "mds cluster_down") {
+    // NOTE: deprecated by "fs set cluster_down"
+    modify_legacy_filesystem(
+        [](std::shared_ptr<Filesystem> fs)
+    {
+      fs->mds_map.set_flag(CEPH_MDSMAP_DOWN);
+    });
+    ss << "marked fsmap DOWN";
+    r = 0;
+  } else if (prefix == "mds cluster_up") {
+    // NOTE: deprecated by "fs set cluster_up"
+    modify_legacy_filesystem(
+        [](std::shared_ptr<Filesystem> fs)
+    {
+      fs->mds_map.clear_flag(CEPH_MDSMAP_DOWN);
+    });
+    ss << "unmarked fsmap DOWN";
+    r = 0;
   } else {
-    ss << "unrecognized command";
     return -ENOSYS;
   }
 
@@ -1781,28 +2369,142 @@ int MDSMonitor::filesystem_command(
 
 void MDSMonitor::check_subs()
 {
-  string type = "mdsmap";
-  if (mon->session_map.subs.count(type) == 0)
-    return;
-  xlist<Subscription*>::iterator p = mon->session_map.subs[type]->begin();
-  while (!p.end()) {
-    Subscription *sub = *p;
-    ++p;
-    check_sub(sub);
+  std::list<std::string> types;
+
+  // Subscriptions may be to "fsmap" (MDS and legacy clients),
+  // "fsmap.<namespace>", or to "fsmap" for the full state of all
+  // filesystems.  Build a list of all the types we service
+  // subscriptions for.
+  types.push_back("mdsmap");
+  types.push_back("fsmap");
+  for (const auto &i : fsmap.filesystems) {
+    auto fscid = i.first;
+    std::ostringstream oss;
+    oss << "fsmap." << fscid;
+    types.push_back(oss.str());
+  }
+
+  for (const auto &type : types) {
+    if (mon->session_map.subs.count(type) == 0)
+      return;
+    xlist<Subscription*>::iterator p = mon->session_map.subs[type]->begin();
+    while (!p.end()) {
+      Subscription *sub = *p;
+      ++p;
+      check_sub(sub);
+    }
   }
 }
 
+
 void MDSMonitor::check_sub(Subscription *sub)
 {
-  if (sub->next <= mdsmap.get_epoch()) {
-    sub->session->con->send_message(new MMDSMap(mon->monmap->fsid, &mdsmap));
-    if (sub->onetime)
+  dout(20) << __func__ << ": " << sub->type << dendl;
+
+  if (sub->type == "fsmap") {
+    if (sub->next <= fsmap.get_epoch()) {
+      sub->session->con->send_message(new MFSMap(mon->monmap->fsid, &fsmap));
+      if (sub->onetime) {
+        mon->session_map.remove_sub(sub);
+      } else {
+        sub->next = fsmap.get_epoch() + 1;
+      }
+    }
+  } else {
+    if (sub->next > fsmap.get_epoch()) {
+      return;
+    }
+
+    const bool is_mds = sub->session->inst.name.is_mds();
+    mds_gid_t mds_gid = MDS_GID_NONE;
+    fs_cluster_id_t fscid = FS_CLUSTER_ID_NONE;
+    if (is_mds) {
+      // What (if any) namespace are you assigned to?
+      auto mds_info = fsmap.get_mds_info();
+      for (const auto &i : mds_info) {
+        if (i.second.addr == sub->session->inst.addr) {
+          mds_gid = i.first;
+          fscid = fsmap.mds_roles.at(mds_gid);
+        }
+      }
+    } else {
+      // You're a client.  Did you request a particular
+      // namespace?
+      if (sub->type.find("mdsmap.") == 0) {
+        auto namespace_id_str = sub->type.substr(std::string("mdsmap.").size());
+        dout(10) << __func__ << ": namespace_id " << namespace_id_str << dendl;
+        std::string err;
+        fscid = strict_strtoll(namespace_id_str.c_str(), 10, &err);
+        if (!err.empty()) {
+          // Client asked for a non-existent namespace, send them nothing
+          dout(1) << "Invalid client subscription '" << sub->type
+                  << "'" << dendl;
+          return;
+        }
+        if (fsmap.filesystems.count(fscid) == 0) {
+          // Client asked for a non-existent namespace, send them nothing
+          // TODO: something more graceful for when a client has a filesystem
+          // mounted, and the fileysstem is deleted.  Add a "shut down you fool"
+          // flag to MMDSMap?
+          dout(1) << "Client subscribed to non-existent namespace '" <<
+                  fscid << "'" << dendl;
+          return;
+        }
+      } else {
+        // Unqualified request for "mdsmap": give it the one marked
+        // for use by legacy clients.
+        if (fsmap.legacy_client_fscid != FS_CLUSTER_ID_NONE) {
+          fscid = fsmap.legacy_client_fscid;
+        } else {
+          dout(1) << "Client subscribed for legacy filesystem but "
+                     "none is configured" << dendl;
+          return;
+        }
+      }
+    }
+    dout(10) << __func__ << ": is_mds=" << is_mds << ", fscid= " << fscid << dendl;
+
+    // Work out the effective latest epoch
+    MDSMap *mds_map = nullptr;
+    MDSMap null_map;
+    null_map.compat = fsmap.compat;
+    if (fscid == FS_CLUSTER_ID_NONE) {
+      // For a client, we should have already dropped out
+      assert(is_mds);
+
+      if (fsmap.standby_daemons.count(mds_gid)) {
+        // For an MDS, we need to feed it an MDSMap with its own state in
+        null_map.mds_info[mds_gid] = fsmap.standby_daemons[mds_gid];
+        null_map.epoch = fsmap.standby_epochs[mds_gid];
+      } else {
+        null_map.epoch = fsmap.epoch;
+      }
+      mds_map = &null_map;
+    } else {
+      // Check the effective epoch 
+      mds_map = &(fsmap.filesystems.at(fscid)->mds_map);
+    }
+
+    dout(10) << __func__ << " selected MDS map epoch " <<
+      mds_map->epoch << " for namespace " << fscid << " for subscriber "
+      << sub->session->inst.name << " who wants epoch " << sub->next << dendl;
+
+    assert(mds_map != nullptr);
+    if (sub->next > mds_map->epoch) {
+      return;
+    }
+    auto msg = new MMDSMap(mon->monmap->fsid, mds_map);
+
+    sub->session->con->send_message(msg);
+    if (sub->onetime) {
       mon->session_map.remove_sub(sub);
-    else
-      sub->next = mdsmap.get_epoch() + 1;
+    } else {
+      sub->next = mds_map->get_epoch() + 1;
+    }
   }
 }
 
+
 void MDSMonitor::update_metadata(mds_gid_t gid,
 				 const map<string, string>& metadata)
 {
@@ -1823,7 +2525,7 @@ void MDSMonitor::remove_from_metadata(MonitorDBStore::TransactionRef t)
   bool update = false;
   for (map<mds_gid_t, Metadata>::iterator i = pending_metadata.begin();
        i != pending_metadata.end(); ) {
-    if (pending_mdsmap.get_state_gid(i->first) == MDSMap::STATE_NULL) {
+    if (!pending_fsmap.gid_exists(i->first)) {
       pending_metadata.erase(i++);
       update = true;
     } else {
@@ -1893,11 +2595,12 @@ int MDSMonitor::print_nodes(Formatter *f)
       continue;
     }
     const mds_gid_t gid = it->first;
-    if (mdsmap.get_state_gid(gid) == MDSMap::STATE_NULL) {
+    if (!fsmap.gid_exists(gid)) {
       dout(5) << __func__ << ": GID " << gid << " not existent" << dendl;
       continue;
     }
-    const MDSMap::mds_info_t& mds_info = mdsmap.get_info_gid(gid);
+    const MDSMap::mds_info_t& mds_info = fsmap.get_info_gid(gid);
+    // FIXME: include filesystem name with rank here
     mdses[hostname->second].push_back(mds_info.rank);
   }
 
@@ -1905,270 +2608,309 @@ int MDSMonitor::print_nodes(Formatter *f)
   return 0;
 }
 
-void MDSMonitor::tick()
+/**
+ * If a cluster is undersized (with respect to max_mds), then
+ * attempt to find daemons to grow it.
+ */
+bool MDSMonitor::maybe_expand_cluster(std::shared_ptr<Filesystem> fs)
 {
-  // make sure mds's are still alive
-  // ...if i am an active leader
-  if (!is_active()) return;
-
-  // Do nothing if the filesystem is disabled
-  if (!mdsmap.get_enabled()) return;
-
-  dout(10) << mdsmap << dendl;
-  
   bool do_propose = false;
 
-  if (!mon->is_leader()) return;
+  if (fs->mds_map.test_flag(CEPH_MDSMAP_DOWN)) {
+    return do_propose;
+  }
 
-  // expand mds cluster (add new nodes to @in)?
-  while (pending_mdsmap.get_num_in_mds() < size_t(pending_mdsmap.get_max_mds()) &&
-	 !pending_mdsmap.is_degraded()) {
+  while (fs->mds_map.get_num_in_mds() < size_t(fs->mds_map.get_max_mds()) &&
+	 !fs->mds_map.is_degraded()) {
     mds_rank_t mds = mds_rank_t(0);
     string name;
-    while (pending_mdsmap.is_in(mds))
+    while (fs->mds_map.is_in(mds)) {
       mds++;
-    mds_gid_t newgid = pending_mdsmap.find_replacement_for(mds, name,
+    }
+    mds_gid_t newgid = pending_fsmap.find_replacement_for({fs->fscid, mds}, name,
                          g_conf->mon_force_standby_active);
-    if (!newgid)
+    if (newgid == MDS_GID_NONE) {
       break;
+    }
 
-    MDSMap::mds_info_t& info = pending_mdsmap.mds_info[newgid];
-    dout(1) << "adding standby " << info.addr << " as mds." << mds << dendl;
-    
-    info.rank = mds;
-    if (pending_mdsmap.stopped.count(mds)) {
-      info.state = MDSMap::STATE_STARTING;
-      pending_mdsmap.stopped.erase(mds);
-    } else
-      info.state = MDSMap::STATE_CREATING;
-    info.inc = ++pending_mdsmap.inc[mds];
-    pending_mdsmap.in.insert(mds);
-    pending_mdsmap.up[mds] = newgid;
+    dout(1) << "adding standby " << pending_fsmap.get_info_gid(newgid).addr
+            << " as mds." << mds << dendl;
+    pending_fsmap.promote(newgid, fs, mds);
     do_propose = true;
   }
 
-  // check beacon timestamps
-  utime_t now = ceph_clock_now(g_ceph_context);
-  utime_t cutoff = now;
-  cutoff -= g_conf->mds_beacon_grace;
-
-  // make sure last_beacon is fully populated
-  for (map<mds_gid_t,MDSMap::mds_info_t>::iterator p = pending_mdsmap.mds_info.begin();
-       p != pending_mdsmap.mds_info.end();
-       ++p) {
-    if (last_beacon.count(p->first) == 0) {
-      const MDSMap::mds_info_t& info = p->second;
-      dout(10) << " adding " << p->second.addr << " mds." << info.rank << "." << info.inc
-	       << " " << ceph_mds_state_name(info.state)
-	       << " to last_beacon" << dendl;
-      last_beacon[p->first].stamp = ceph_clock_now(g_ceph_context);
-      last_beacon[p->first].seq = 0;
-    }
-  }
-
-  if (mon->osdmon()->is_writeable()) {
-
-    bool propose_osdmap = false;
-
-    map<mds_gid_t, beacon_info_t>::iterator p = last_beacon.begin();
-    while (p != last_beacon.end()) {
-      mds_gid_t gid = p->first;
-      utime_t since = p->second.stamp;
-      uint64_t seq = p->second.seq;
-      ++p;
-      
-      if (pending_mdsmap.mds_info.count(gid) == 0) {
-	// clean it out
-	last_beacon.erase(gid);
-	continue;
-      }
-
-      if (since >= cutoff)
-	continue;
+  return do_propose;
+}
 
-      MDSMap::mds_info_t& info = pending_mdsmap.mds_info[gid];
 
-      dout(10) << "no beacon from " << gid << " " << info.addr << " mds." << info.rank << "." << info.inc
-	       << " " << ceph_mds_state_name(info.state)
-	       << " since " << since << dendl;
-      
-      // are we in?
-      // and is there a non-laggy standby that can take over for us?
-      mds_gid_t sgid;
-      if (info.rank >= 0 &&
-	  info.state != MDSMap::STATE_STANDBY &&
-	  info.state != MDSMap::STATE_STANDBY_REPLAY &&
-	  (sgid = pending_mdsmap.find_replacement_for(info.rank, info.name, 
-                    g_conf->mon_force_standby_active)) != MDS_GID_NONE) {
-	MDSMap::mds_info_t& si = pending_mdsmap.mds_info[sgid];
-	dout(10) << " replacing " << gid << " " << info.addr << " mds." << info.rank << "." << info.inc
-		 << " " << ceph_mds_state_name(info.state)
-		 << " with " << sgid << "/" << si.name << " " << si.addr << dendl;
-	switch (info.state) {
-	case MDSMap::STATE_CREATING:
-	case MDSMap::STATE_STARTING:
-	  si.state = info.state;
-	  break;
-	case MDSMap::STATE_REPLAY:
-	case MDSMap::STATE_RESOLVE:
-	case MDSMap::STATE_RECONNECT:
-	case MDSMap::STATE_REJOIN:
-	case MDSMap::STATE_CLIENTREPLAY:
-	case MDSMap::STATE_ACTIVE:
-	case MDSMap::STATE_STOPPING:
-	case MDSMap::STATE_DNE:
-	  si.state = MDSMap::STATE_REPLAY;
-	  break;
-	default:
-	  assert(0);
-	}
+/**
+ * If a daemon is laggy, and a suitable replacement
+ * is available, fail this daemon (remove from map) and pass its
+ * role to another daemon.
+ */
+void MDSMonitor::maybe_replace_gid(mds_gid_t gid,
+    const beacon_info_t &beacon,
+    bool *mds_propose, bool *osd_propose)
+{
+  assert(mds_propose != nullptr);
+  assert(osd_propose != nullptr);
+
+  const MDSMap::mds_info_t info = pending_fsmap.get_info_gid(gid);
+  const auto fscid = pending_fsmap.mds_roles.at(gid);
+
+  dout(10) << "no beacon from " << gid << " " << info.addr << " mds."
+    << info.rank << "." << info.inc
+    << " " << ceph_mds_state_name(info.state)
+    << " since " << beacon.stamp << dendl;
+
+  // are we in?
+  // and is there a non-laggy standby that can take over for us?
+  mds_gid_t sgid;
+  if (info.rank >= 0 &&
+      info.state != MDSMap::STATE_STANDBY &&
+      info.state != MDSMap::STATE_STANDBY_REPLAY &&
+      !pending_fsmap.get_filesystem(fscid)->mds_map.test_flag(CEPH_MDSMAP_DOWN) &&
+      (sgid = pending_fsmap.find_replacement_for({fscid, info.rank}, info.name,
+                g_conf->mon_force_standby_active)) != MDS_GID_NONE) {
+    
+    MDSMap::mds_info_t si = pending_fsmap.get_info_gid(sgid);
+    dout(10) << " replacing " << gid << " " << info.addr << " mds."
+      << info.rank << "." << info.inc
+      << " " << ceph_mds_state_name(info.state)
+      << " with " << sgid << "/" << si.name << " " << si.addr << dendl;
+
+    // Remember what NS the old one was in
+    const fs_cluster_id_t fscid = pending_fsmap.mds_roles.at(gid);
+
+    // Remove the old one
+    *osd_propose |= fail_mds_gid(gid);
+
+    // Promote the replacement
+    auto fs = pending_fsmap.filesystems.at(fscid);
+    pending_fsmap.promote(sgid, fs, info.rank);
+
+    *mds_propose = true;
+  } else if (info.state == MDSMap::STATE_STANDBY_REPLAY) {
+    dout(10) << " failing " << gid << " " << info.addr << " mds." << info.rank << "." << info.inc
+      << " " << ceph_mds_state_name(info.state)
+      << dendl;
+    fail_mds_gid(gid);
+    *mds_propose = true;
+  } else {
+    if (info.state == MDSMap::STATE_STANDBY ||
+        info.state == MDSMap::STATE_STANDBY_REPLAY) {
+      // remove it
+      dout(10) << " removing " << gid << " " << info.addr << " mds." << info.rank << "." << info.inc
+        << " " << ceph_mds_state_name(info.state)
+        << " (laggy)" << dendl;
+      fail_mds_gid(gid);
+      *mds_propose = true;
+    } else if (!info.laggy()) {
+      dout(10) << " marking " << gid << " " << info.addr << " mds." << info.rank << "." << info.inc
+        << " " << ceph_mds_state_name(info.state)
+        << " laggy" << dendl;
+      pending_fsmap.modify_daemon(info.global_id, [](MDSMap::mds_info_t *info) {
+          info->laggy_since = ceph_clock_now(g_ceph_context);
+      });
+      *mds_propose = true;
+    }
+    last_beacon.erase(gid);
+  }
+}
 
-	info.state_seq = seq;
-	si.rank = info.rank;
-	si.inc = ++pending_mdsmap.inc[info.rank];
-	pending_mdsmap.up[info.rank] = sgid;
-	if (si.state > 0)
-	  pending_mdsmap.last_failure = pending_mdsmap.epoch;
-	if (si.state > 0 ||
-	    si.state == MDSMap::STATE_CREATING ||
-	    si.state == MDSMap::STATE_STARTING) {
-	  // blacklist laggy mds
-	  utime_t until = now;
-	  until += g_conf->mds_blacklist_interval;
-	  pending_mdsmap.last_failure_osd_epoch = mon->osdmon()->blacklist(info.addr, until);
-	  propose_osdmap = true;
-	}
-	pending_mdsmap.mds_info.erase(gid);
-        pending_daemon_health.erase(gid);
-        pending_daemon_health_rm.insert(gid);
-	last_beacon.erase(gid);
-	do_propose = true;
-      } else if (info.state == MDSMap::STATE_STANDBY_REPLAY) {
-	dout(10) << " failing " << gid << " " << info.addr << " mds." << info.rank << "." << info.inc
-		 << " " << ceph_mds_state_name(info.state)
-		 << dendl;
-	pending_mdsmap.mds_info.erase(gid);
-        pending_daemon_health.erase(gid);
-        pending_daemon_health_rm.insert(gid);
-	last_beacon.erase(gid);
-	do_propose = true;
-      } else {
-	if (info.state == MDSMap::STATE_STANDBY ||
-	    info.state == MDSMap::STATE_STANDBY_REPLAY) {
-	  // remove it
-	  dout(10) << " removing " << gid << " " << info.addr << " mds." << info.rank << "." << info.inc
-		   << " " << ceph_mds_state_name(info.state)
-		   << " (laggy)" << dendl;
-	  pending_mdsmap.mds_info.erase(gid);
-          pending_daemon_health.erase(gid);
-          pending_daemon_health_rm.insert(gid);
-	  do_propose = true;
-	} else if (!info.laggy()) {
-	  dout(10) << " marking " << gid << " " << info.addr << " mds." << info.rank << "." << info.inc
-		   << " " << ceph_mds_state_name(info.state)
-		   << " laggy" << dendl;
-	  info.laggy_since = now;
-	  do_propose = true;
-	}
-	last_beacon.erase(gid);
-      }
-    }
+bool MDSMonitor::maybe_promote_standby(std::shared_ptr<Filesystem> fs)
+{
+  assert(!fs->mds_map.test_flag(CEPH_MDSMAP_DOWN));
 
-    if (propose_osdmap)
-      request_proposal(mon->osdmon());
-  }
+  bool do_propose = false;
 
   // have a standby take over?
   set<mds_rank_t> failed;
-  pending_mdsmap.get_failed_mds_set(failed);
-  if (!failed.empty() && !pending_mdsmap.test_flag(CEPH_MDSMAP_DOWN)) {
+  fs->mds_map.get_failed_mds_set(failed);
+  if (!failed.empty()) {
     set<mds_rank_t>::iterator p = failed.begin();
     while (p != failed.end()) {
       mds_rank_t f = *p++;
-      string name;  // FIXME
-      mds_gid_t sgid = pending_mdsmap.find_replacement_for(f, name,
+      mds_gid_t sgid = pending_fsmap.find_replacement_for({fs->fscid, f}, {},
           g_conf->mon_force_standby_active);
       if (sgid) {
-	MDSMap::mds_info_t& si = pending_mdsmap.mds_info[sgid];
-	dout(0) << " taking over failed mds." << f << " with " << sgid << "/" << si.name << " " << si.addr << dendl;
-	si.state = MDSMap::STATE_REPLAY;
-	si.rank = f;
-	si.inc = ++pending_mdsmap.inc[f];
-	pending_mdsmap.in.insert(f);
-	pending_mdsmap.up[f] = sgid;
-	pending_mdsmap.failed.erase(f);
+        const MDSMap::mds_info_t si = pending_fsmap.get_info_gid(sgid);
+        dout(0) << " taking over failed mds." << f << " with " << sgid
+                << "/" << si.name << " " << si.addr << dendl;
+        pending_fsmap.promote(sgid, fs, f);
 	do_propose = true;
       }
     }
   }
 
-  // have a standby follow someone?
+  // There were no failures to replace, so try using any available standbys
+  // as standby-replay daemons.
   if (failed.empty()) {
-    for (map<mds_gid_t,MDSMap::mds_info_t>::iterator j = pending_mdsmap.mds_info.begin();
-	 j != pending_mdsmap.mds_info.end();
-	 ++j) {
-      MDSMap::mds_info_t& info = j->second;
-      
-      if (info.state != MDSMap::STATE_STANDBY)
-	continue;
+    for (const auto &j : pending_fsmap.standby_daemons) {
+      const auto &gid = j.first;
+      const auto &info = j.second;
+      assert(info.state == MDSMap::STATE_STANDBY);
 
       /*
        * This mds is standby but has no rank assigned.
        * See if we can find it somebody to shadow
        */
-      dout(20) << "gid " << j->first << " is standby and following nobody" << dendl;
+      dout(20) << "gid " << gid << " is standby and following nobody" << dendl;
       
       // standby for someone specific?
       if (info.standby_for_rank >= 0) {
-	if (pending_mdsmap.is_followable(info.standby_for_rank) &&
-	    try_standby_replay(info, pending_mdsmap.mds_info[pending_mdsmap.up[info.standby_for_rank]]))
-	  do_propose = true;
+        // The mds_info_t may or may not tell us exactly which filesystem
+        // the standby_for_rank refers to: lookup via legacy_client_fscid
+        mds_role_t target_role = {
+          info.standby_for_ns == FS_CLUSTER_ID_NONE ?
+            pending_fsmap.legacy_client_fscid : info.standby_for_ns,
+          info.standby_for_rank};
+
+        // If we managed to resolve a full target role
+        if (target_role.fscid != FS_CLUSTER_ID_NONE) {
+          auto fs = pending_fsmap.get_filesystem(target_role.fscid);
+          if (fs->mds_map.is_followable(target_role.rank)) {
+            do_propose |= try_standby_replay(
+                info,
+                *fs,
+                fs->mds_map.get_info(target_role.rank));
+          }
+        }
+
 	continue;
       }
 
       // check everyone
-      for (map<mds_gid_t,MDSMap::mds_info_t>::iterator i = pending_mdsmap.mds_info.begin();
-	   i != pending_mdsmap.mds_info.end();
-	   ++i) {
-	if (i->second.rank >= 0 && pending_mdsmap.is_followable(i->second.rank)) {
-	  if ((info.standby_for_name.length() && info.standby_for_name != i->second.name) ||
-	      info.standby_for_rank >= 0)
-	    continue;   // we're supposed to follow someone else
-
-	  if (info.standby_for_rank == MDSMap::MDS_STANDBY_ANY &&
-	      try_standby_replay(info, i->second)) {
-	    do_propose = true;
-	    break;
-	  }
-	  continue;
-	}
+      for (auto fs_i : pending_fsmap.filesystems) {
+        const MDSMap &mds_map = fs_i.second->mds_map;
+        for (auto mds_i : mds_map.mds_info) {
+          MDSMap::mds_info_t &cand_info = mds_i.second;
+          if (cand_info.rank >= 0 && mds_map.is_followable(cand_info.rank)) {
+            if ((info.standby_for_name.length() && info.standby_for_name != cand_info.name) ||
+                info.standby_for_rank != MDS_RANK_NONE) {
+              continue;   // we're supposed to follow someone else
+            }
+
+            if (info.standby_for_rank == MDSMap::MDS_STANDBY_ANY &&
+                try_standby_replay(info, *(fs_i.second), cand_info)) {
+              do_propose = true;
+              break;
+            }
+            continue;
+          }
+        }
       }
     }
   }
 
-  if (do_propose)
+  return do_propose;
+}
+
+void MDSMonitor::tick()
+{
+  // make sure mds's are still alive
+  // ...if i am an active leader
+  if (!is_active()) return;
+
+  dout(10) << fsmap << dendl;
+
+  bool do_propose = false;
+
+  if (!mon->is_leader()) return;
+
+  // expand mds cluster (add new nodes to @in)?
+  for (auto i : pending_fsmap.filesystems) {
+    do_propose |= maybe_expand_cluster(i.second);
+  }
+
+  // check beacon timestamps
+  utime_t now = ceph_clock_now(g_ceph_context);
+  utime_t cutoff = now;
+  cutoff -= g_conf->mds_beacon_grace;
+
+  // make sure last_beacon is fully populated
+  for (const auto &p : pending_fsmap.mds_roles) {
+    auto &gid = p.first;
+    if (last_beacon.count(gid) == 0) {
+      last_beacon[gid].stamp = ceph_clock_now(g_ceph_context);
+      last_beacon[gid].seq = 0;
+    }
+  }
+
+  // If the OSDMap is writeable, we can blacklist things, so we can
+  // try failing any laggy MDS daemons.  Consider each one for failure.
+  if (mon->osdmon()->is_writeable()) {
+    bool propose_osdmap = false;
+
+    map<mds_gid_t, beacon_info_t>::iterator p = last_beacon.begin();
+    while (p != last_beacon.end()) {
+      mds_gid_t gid = p->first;
+      auto beacon_info = p->second;
+      ++p;
+
+      if (!pending_fsmap.gid_exists(gid)) {
+	// clean it out
+	last_beacon.erase(gid);
+	continue;
+      }
+
+      if (beacon_info.stamp < cutoff) {
+        maybe_replace_gid(gid, beacon_info, &do_propose, &propose_osdmap);
+      }
+    }
+
+    if (propose_osdmap) {
+      request_proposal(mon->osdmon());
+    }
+  }
+
+  for (auto i : pending_fsmap.filesystems) {
+    auto fs = i.second;
+    if (!fs->mds_map.test_flag(CEPH_MDSMAP_DOWN)) {
+      do_propose |= maybe_promote_standby(fs);
+    }
+  }
+
+  if (do_propose) {
     propose_pending();
+  }
 }
 
-bool MDSMonitor::try_standby_replay(MDSMap::mds_info_t& finfo, MDSMap::mds_info_t& ainfo)
+/**
+ * finfo: the would-be follower
+ * leader_fs: the Filesystem containing the would-be leader
+ * ainfo: the would-be leader
+ */
+bool MDSMonitor::try_standby_replay(
+    const MDSMap::mds_info_t& finfo,
+    const Filesystem &leader_fs,
+    const MDSMap::mds_info_t& ainfo)
 {
   // someone else already following?
-  mds_gid_t lgid = pending_mdsmap.find_standby_for(ainfo.rank, ainfo.name);
-  if (lgid) {
-    MDSMap::mds_info_t& sinfo = pending_mdsmap.mds_info[lgid];
-    dout(20) << " mds." << ainfo.rank
-	     << " standby gid " << lgid << " with state "
-	     << ceph_mds_state_name(sinfo.state)
-	     << dendl;
-    if (sinfo.state == MDSMap::STATE_STANDBY_REPLAY) {
-      dout(20) << "  skipping this MDS since it has a follower!" << dendl;
-      return false; // this MDS already has a standby
-    }
+  if (leader_fs.has_standby_replay(ainfo.global_id)) {
+    dout(20) << " mds." << ainfo.rank << " already has a follower" << dendl;
+    return false;
+  } else {
+    // Assign the new role to the standby
+    dout(10) << "  setting to follow mds rank " << ainfo.rank << dendl;
+    pending_fsmap.assign_standby_replay(finfo.global_id, leader_fs.fscid, ainfo.rank);
+    return true;
   }
+}
 
-  // hey, we found an MDS without a standby. Pair them!
-  finfo.standby_for_rank = ainfo.rank;
-  dout(10) << "  setting to shadow mds rank " << finfo.standby_for_rank << dendl;
-  finfo.state = MDSMap::STATE_STANDBY_REPLAY;
-  return true;
+MDSMonitor::MDSMonitor(Monitor *mn, Paxos *p, string service_name)
+  : PaxosService(mn, p, service_name)
+{
+  handlers.push_back(std::make_shared<SetHandler>());
+  handlers.push_back(std::make_shared<LegacyHandler<SetHandler> >("mds set"));
+  handlers.push_back(std::make_shared<FlagSetHandler>());
+  handlers.push_back(std::make_shared<AddDataPoolHandler>());
+  handlers.push_back(std::make_shared<LegacyHandler<AddDataPoolHandler> >(
+        "mds add_data_pool"));
+  handlers.push_back(std::make_shared<RemoveDataPoolHandler>());
+  handlers.push_back(std::make_shared<LegacyHandler<RemoveDataPoolHandler> >(
+        "mds remove_data_pool"));
+  handlers.push_back(std::make_shared<LegacyHandler<RemoveDataPoolHandler> >(
+        "mds rm_data_pool"));
 }
+
diff --git a/src/mon/MDSMonitor.h b/src/mon/MDSMonitor.h
index b755ba9..2f4b193 100644
--- a/src/mon/MDSMonitor.h
+++ b/src/mon/MDSMonitor.h
@@ -25,29 +25,30 @@ using namespace std;
 #include "include/types.h"
 #include "msg/Messenger.h"
 
-#include "mds/MDSMap.h"
+#include "mds/FSMap.h"
 
 #include "PaxosService.h"
 #include "Session.h"
 
 #include "messages/MMDSBeacon.h"
 
-class MMDSGetMap;
 class MMonCommand;
 class MMDSLoadTargets;
+class MMDSMap;
+class FileSystemCommandHandler;
 
 #define MDS_HEALTH_PREFIX "mds_health"
 
 class MDSMonitor : public PaxosService {
  public:
   // mds maps
-  MDSMap mdsmap;          // current
+  FSMap fsmap;          // current
   bufferlist mdsmap_bl;   // encoded
 
-  MDSMap pending_mdsmap;  // current + pending updates
+  FSMap pending_fsmap;  // current + pending updates
 
   // my helpers
-  void print_map(MDSMap &m, int dbl=7);
+  void print_map(FSMap &m, int dbl=7);
 
   class C_Updated : public Context {
     MDSMonitor *mm;
@@ -66,7 +67,7 @@ class MDSMonitor : public PaxosService {
     }
   };
 
-  void create_new_fs(MDSMap &m, const std::string &name, int metadata_pool, int data_pool);
+  void create_new_fs(FSMap &m, const std::string &name, int metadata_pool, int data_pool);
 
   version_t get_trim_to();
 
@@ -100,15 +101,31 @@ class MDSMonitor : public PaxosService {
 		  list<pair<health_status_t,string> > *detail,
 		  CephContext *cct) const override;
   int fail_mds(std::ostream &ss, const std::string &arg);
-  void fail_mds_gid(mds_gid_t gid);
+  /**
+   * Return true if a blacklist was done (i.e. OSD propose needed)
+   */
+  bool fail_mds_gid(mds_gid_t gid);
 
   bool preprocess_command(MonOpRequestRef op);
   bool prepare_command(MonOpRequestRef op);
+
+  int parse_role(
+      const std::string &role_str,
+      mds_role_t *role,
+      std::ostream &ss);
+
   int management_command(
       MonOpRequestRef op,
       std::string const &prefix,
       map<string, cmd_vartype> &cmdmap,
       std::stringstream &ss);
+  void modify_legacy_filesystem(
+      std::function<void(std::shared_ptr<Filesystem> )> fn);
+  int legacy_filesystem_command(
+      MonOpRequestRef op,
+      std::string const &prefix,
+      map<string, cmd_vartype> &cmdmap,
+      std::stringstream &ss);
   int filesystem_command(
       MonOpRequestRef op,
       std::string const &prefix,
@@ -122,14 +139,20 @@ class MDSMonitor : public PaxosService {
   };
   map<mds_gid_t, beacon_info_t> last_beacon;
 
-  bool try_standby_replay(MDSMap::mds_info_t& finfo, MDSMap::mds_info_t& ainfo);
+  bool try_standby_replay(
+      const MDSMap::mds_info_t& finfo,
+      const Filesystem &leader_fs,
+      const MDSMap::mds_info_t& ainfo);
+
+  std::list<std::shared_ptr<FileSystemCommandHandler> > handlers;
 
 public:
-  MDSMonitor(Monitor *mn, Paxos *p, string service_name)
-    : PaxosService(mn, p, service_name)
-  {
-  }
+  MDSMonitor(Monitor *mn, Paxos *p, string service_name);
 
+  bool maybe_promote_standby(std::shared_ptr<Filesystem> fs);
+  bool maybe_expand_cluster(std::shared_ptr<Filesystem> fs);
+  void maybe_replace_gid(mds_gid_t gid, const beacon_info_t &beacon,
+      bool *mds_propose, bool *osd_propose);
   void tick();     // check state, take actions
 
   void dump_info(Formatter *f);
@@ -140,6 +163,7 @@ public:
   void check_sub(Subscription *sub);
 
 private:
+  MDSMap *generate_mds_map(fs_cluster_id_t fscid);
   void update_metadata(mds_gid_t gid, const Metadata& metadata);
   void remove_from_metadata(MonitorDBStore::TransactionRef t);
   int load_metadata(map<mds_gid_t, Metadata>& m);
diff --git a/src/mon/MonCommands.h b/src/mon/MonCommands.h
index bb5a935..a003e3a 100644
--- a/src/mon/MonCommands.h
+++ b/src/mon/MonCommands.h
@@ -141,21 +141,21 @@ COMMAND("pg dump_stuck " \
 	"pg", "r", "cli,rest")
 COMMAND("pg ls-by-pool " \
         "name=poolstr,type=CephString " \
-	"name=states,type=CephChoices,strings=active|clean|down|replay|splitting|scrubbing|scrubq|degraded|inconsistent|peering|repair|recovering|backfill_wait|incomplete|stale|remapped|deep_scrub|backfill|backfill_toofull|recovery_wait|undersized,n=N,req=false ", \
+	"name=states,type=CephChoices,strings=active|clean|down|replay|splitting|scrubbing|scrubq|degraded|inconsistent|peering|repair|recovering|backfill_wait|incomplete|stale|remapped|deep_scrub|backfill|backfill_toofull|recovery_wait|undersized|activating|peered,n=N,req=false ", \
 	"list pg with pool = [poolname | poolid]", "pg", "r", "cli,rest")
 COMMAND("pg ls-by-primary " \
         "name=osd,type=CephOsdName " \
         "name=pool,type=CephInt,req=false " \
-	"name=states,type=CephChoices,strings=active|clean|down|replay|splitting|scrubbing|scrubq|degraded|inconsistent|peering|repair|recovering|backfill_wait|incomplete|stale|remapped|deep_scrub|backfill|backfill_toofull|recovery_wait|undersized,n=N,req=false ", \
+	"name=states,type=CephChoices,strings=active|clean|down|replay|splitting|scrubbing|scrubq|degraded|inconsistent|peering|repair|recovering|backfill_wait|incomplete|stale|remapped|deep_scrub|backfill|backfill_toofull|recovery_wait|undersized|activating|peered,n=N,req=false ", \
 	"list pg with primary = [osd]", "pg", "r", "cli,rest")
 COMMAND("pg ls-by-osd " \
         "name=osd,type=CephOsdName " \
         "name=pool,type=CephInt,req=false " \
-	"name=states,type=CephChoices,strings=active|clean|down|replay|splitting|scrubbing|scrubq|degraded|inconsistent|peering|repair|recovering|backfill_wait|incomplete|stale|remapped|deep_scrub|backfill|backfill_toofull|recovery_wait|undersized,n=N,req=false ", \
+	"name=states,type=CephChoices,strings=active|clean|down|replay|splitting|scrubbing|scrubq|degraded|inconsistent|peering|repair|recovering|backfill_wait|incomplete|stale|remapped|deep_scrub|backfill|backfill_toofull|recovery_wait|undersized|activating|peered,n=N,req=false ", \
 	"list pg on osd [osd]", "pg", "r", "cli,rest")
 COMMAND("pg ls " \
         "name=pool,type=CephInt,req=false " \
-	"name=states,type=CephChoices,strings=active|clean|down|replay|splitting|scrubbing|scrubq|degraded|inconsistent|peering|repair|recovering|backfill_wait|incomplete|stale|remapped|deep_scrub|backfill|backfill_toofull|recovery_wait|undersized,n=N,req=false ", \
+	"name=states,type=CephChoices,strings=active|clean|down|replay|splitting|scrubbing|scrubq|degraded|inconsistent|peering|repair|recovering|backfill_wait|incomplete|stale|remapped|deep_scrub|backfill|backfill_toofull|recovery_wait|undersized|activating|peered,n=N,req=false ", \
 	"list pg with specific pool, osd, state", "pg", "r", "cli,rest")
 COMMAND("pg map name=pgid,type=CephPgid", "show mapping of pg to osds", \
 	"pg", "r", "cli,rest")
@@ -219,6 +219,10 @@ COMMAND("auth del " \
 	"name=entity,type=CephString", \
 	"delete all caps for <name>", \
 	"auth", "rwx", "cli,rest")
+COMMAND("auth rm " \
+	"name=entity,type=CephString", \
+	"remove all caps for <name>", \
+	"auth", "rwx", "cli,rest")
 
 /*
  * Monitor commands (Monitor.cc)
@@ -300,7 +304,11 @@ COMMAND("mon metadata name=id,type=CephString",
 COMMAND("mds stat", "show MDS status", "mds", "r", "cli,rest")
 COMMAND("mds dump " 
 	"name=epoch,type=CephInt,req=false,range=0", \
-	"dump info, optionally from epoch", "mds", "r", "cli,rest")
+	"dump legacy MDS cluster info, optionally from epoch",
+        "mds", "r", "cli,rest")
+COMMAND("fs dump "
+	"name=epoch,type=CephInt,req=false,range=0", \
+	"dump all CephFS status, optionally from epoch", "mds", "r", "cli,rest")
 COMMAND("mds getmap " \
 	"name=epoch,type=CephInt,req=false,range=0", \
 	"get MDS map, optionally from epoch", "mds", "r", "cli,rest")
@@ -325,10 +333,6 @@ COMMAND("mds set " \
 	"name=val,type=CephString "					\
 	"name=confirm,type=CephString,req=false",			\
 	"set mds parameter <var> to <val>", "mds", "rw", "cli,rest")
-COMMAND("mds setmap " \
-	"name=epoch,type=CephInt,range=0 " \
-	"name=confirm,type=CephString,req=false",
-	"set mds map; must supply correct epoch number", "mds", "rw", "cli,rest")
 // arbitrary limit 0-20 below; worth standing on head to make it
 // relate to actual state definitions?
 // #include "include/ceph_fs.h"
@@ -338,12 +342,12 @@ COMMAND("mds set_state " \
 	"set mds state of <gid> to <numeric-state>", "mds", "rw", "cli,rest")
 COMMAND("mds fail name=who,type=CephString", \
 	"force mds to status failed", "mds", "rw", "cli,rest")
-COMMAND("mds repaired name=rank,type=CephInt", \
+COMMAND("mds repaired name=rank,type=CephString", \
 	"mark a damaged MDS rank as no longer damaged", "mds", "rw", "cli,rest")
 COMMAND("mds rm " \
 	"name=gid,type=CephInt,range=0", \
 	"remove nonactive mds", "mds", "rw", "cli,rest")
-COMMAND("mds rmfailed name=who,type=CephInt,range=0 name=confirm,type=CephString,req=false", \
+COMMAND("mds rmfailed name=who,type=CephString name=confirm,type=CephString,req=false", \
 	"remove failed mds", "mds", "rw", "cli,rest")
 COMMAND("mds cluster_down", "take MDS cluster down", "mds", "rw", "cli,rest")
 COMMAND("mds cluster_up", "bring MDS cluster up", "mds", "rw", "cli,rest")
@@ -359,6 +363,9 @@ COMMAND("mds add_data_pool " \
 COMMAND("mds remove_data_pool " \
 	"name=pool,type=CephString", \
 	"remove data pool <pool>", "mds", "rw", "cli,rest")
+COMMAND("mds rm_data_pool " \
+	"name=pool,type=CephString", \
+	"remove data pool <pool>", "mds", "rw", "cli,rest")
 COMMAND("mds newfs " \
 	"name=metadata,type=CephInt,range=0 " \
 	"name=data,type=CephInt,range=0 " \
@@ -384,6 +391,27 @@ COMMAND("fs reset " \
 COMMAND("fs ls ", \
 	"list filesystems", \
 	"fs", "r", "cli,rest")
+COMMAND("fs get name=fs_name,type=CephString", \
+	"get info about one filesystem", \
+	"fs", "r", "cli,rest")
+COMMAND("fs set " \
+	"name=fs_name,type=CephString " \
+	"name=var,type=CephChoices,strings=max_mds|max_file_size"
+        "|allow_new_snaps|inline_data|cluster_down " \
+	"name=val,type=CephString "					\
+	"name=confirm,type=CephString,req=false",			\
+	"set mds parameter <var> to <val>", "mds", "rw", "cli,rest")
+COMMAND("fs flag set name=flag_name,type=CephChoices,strings=enable_multiple "
+        "name=val,type=CephString", \
+	"Set a global CephFS flag", \
+	"fs", "rw", "cli,rest")
+COMMAND("fs add_data_pool name=fs_name,type=CephString " \
+	"name=pool,type=CephString", \
+	"add data pool <pool>", "mds", "rw", "cli,rest")
+COMMAND("fs rm_data_pool name=fs_name,type=CephString " \
+	"name=pool,type=CephString", \
+	"remove data pool <pool>", "mds", "rw", "cli,rest")
+
 /*
  * Monmap commands
  */
@@ -402,6 +430,9 @@ COMMAND("mon add " \
 COMMAND("mon remove " \
 	"name=name,type=CephString", \
 	"remove monitor named <name>", "mon", "rw", "cli,rest")
+COMMAND("mon rm " \
+	"name=name,type=CephString", \
+	"remove monitor named <name>", "mon", "rw", "cli,rest")
 
 /*
  * OSD commands
@@ -671,6 +702,12 @@ COMMAND("osd pool delete " \
 	"name=sure,type=CephChoices,strings=--yes-i-really-really-mean-it,req=false", \
 	"delete pool", \
 	"osd", "rw", "cli,rest")
+COMMAND("osd pool rm " \
+	"name=pool,type=CephPoolname " \
+	"name=pool2,type=CephPoolname,req=false " \
+	"name=sure,type=CephChoices,strings=--yes-i-really-really-mean-it,req=false", \
+	"remove pool", \
+	"osd", "rw", "cli,rest")
 COMMAND("osd pool rename " \
 	"name=srcpool,type=CephPoolname " \
 	"name=destpool,type=CephPoolname", \
@@ -701,15 +738,37 @@ COMMAND("osd pool stats " \
         "name=name,type=CephString,req=false",
         "obtain stats from all pools, or from specified pool",
         "osd", "r", "cli,rest")
+COMMAND("osd utilization",
+	"get basic pg distribution stats",
+	"osd", "r", "cli,rest")
 COMMAND("osd reweight-by-utilization " \
-	"name=oload,type=CephInt,range=100,req=false", \
+	"name=oload,type=CephInt,req=false " \
+	"name=max_change,type=CephFloat,req=false "			\
+	"name=max_osds,type=CephInt,req=false "			\
+	"name=no_increasing,type=CephChoices,strings=--no-increasing,req=false",\
 	"reweight OSDs by utilization [overload-percentage-for-consideration, default 120]", \
 	"osd", "rw", "cli,rest")
+COMMAND("osd test-reweight-by-utilization " \
+	"name=oload,type=CephInt,req=false " \
+	"name=max_change,type=CephFloat,req=false "			\
+	"name=max_osds,type=CephInt,req=false "			\
+	"name=no_increasing,type=CephChoices,strings=--no-increasing,req=false",\
+	"dry run of reweight OSDs by utilization [overload-percentage-for-consideration, default 120]", \
+	"osd", "rw", "cli,rest")
 COMMAND("osd reweight-by-pg " \
-	"name=oload,type=CephInt,range=100 " \
-	"name=pools,type=CephPoolname,n=N,req=false", \
+	"name=oload,type=CephInt,req=false " \
+	"name=max_change,type=CephFloat,req=false "			\
+	"name=max_osds,type=CephInt,req=false "			\
+	"name=pools,type=CephPoolname,n=N,req=false",			\
 	"reweight OSDs by PG distribution [overload-percentage-for-consideration, default 120]", \
 	"osd", "rw", "cli,rest")
+COMMAND("osd test-reweight-by-pg " \
+	"name=oload,type=CephInt,req=false " \
+	"name=max_change,type=CephFloat,req=false "			\
+	"name=max_osds,type=CephInt,req=false "			\
+	"name=pools,type=CephPoolname,n=N,req=false",			\
+	"dry run of reweight OSDs by PG distribution [overload-percentage-for-consideration, default 120]", \
+	"osd", "rw", "cli,rest")
 COMMAND("osd thrash " \
 	"name=num_epochs,type=CephInt,range=0", \
 	"thrash OSDs for <num_epochs>", "osd", "rw", "cli,rest")
@@ -729,6 +788,11 @@ COMMAND("osd tier remove " \
 	"name=tierpool,type=CephPoolname",
 	"remove the tier <tierpool> (the second one) from base pool <pool> (the first one)", \
 	"osd", "rw", "cli,rest")
+COMMAND("osd tier rm " \
+	"name=pool,type=CephPoolname " \
+	"name=tierpool,type=CephPoolname",
+	"remove the tier <tierpool> (the second one) from base pool <pool> (the first one)", \
+	"osd", "rw", "cli,rest")
 COMMAND("osd tier cache-mode " \
 	"name=pool,type=CephPoolname " \
 	"name=mode,type=CephChoices,strings=none|writeback|forward|readonly|readforward|readproxy", \
@@ -740,6 +804,9 @@ COMMAND("osd tier set-overlay " \
 COMMAND("osd tier remove-overlay " \
 	"name=pool,type=CephPoolname ", \
 	"remove the overlay pool for base pool <pool>", "osd", "rw", "cli,rest")
+COMMAND("osd tier rm-overlay " \
+	"name=pool,type=CephPoolname ", \
+	"remove the overlay pool for base pool <pool>", "osd", "rw", "cli,rest")
 
 COMMAND("osd tier add-cache " \
 	"name=pool,type=CephPoolname " \
@@ -762,6 +829,9 @@ COMMAND("config-key put " \
 COMMAND("config-key del " \
 	"name=key,type=CephString", \
 	"delete <key>", "config-key", "rw", "cli,rest")
+COMMAND("config-key rm " \
+	"name=key,type=CephString", \
+	"rm <key>", "config-key", "rw", "cli,rest")
 COMMAND("config-key exists " \
 	"name=key,type=CephString", \
 	"check for <key>'s existence", "config-key", "r", "cli,rest")
diff --git a/src/mon/Monitor.cc b/src/mon/Monitor.cc
index 0af79c7..760d80a 100644
--- a/src/mon/Monitor.cc
+++ b/src/mon/Monitor.cc
@@ -18,6 +18,7 @@
 #include <signal.h>
 #include <limits.h>
 #include <cstring>
+#include <boost/scope_exit.hpp>
 
 #include "Monitor.h"
 #include "common/version.h"
@@ -185,6 +186,7 @@ Monitor::Monitor(CephContext* cct_, string nm, MonitorDBStore *s,
 
   timecheck_round(0),
   timecheck_acks(0),
+  timecheck_rounds_since_clean(0),
   timecheck_event(NULL),
 
   probe_timeout_event(NULL),
@@ -887,6 +889,8 @@ void Monitor::shutdown()
     admin_socket->unregister_command("quorum_status");
     admin_socket->unregister_command("sync_force");
     admin_socket->unregister_command("add_bootstrap_peer_hint");
+    admin_socket->unregister_command("quorum enter");
+    admin_socket->unregister_command("quorum exit");
     admin_socket->unregister_command("ops");
     delete admin_hook;
     admin_hook = NULL;
@@ -1613,7 +1617,6 @@ void Monitor::handle_probe(MonOpRequestRef op)
 void Monitor::handle_probe_probe(MonOpRequestRef op)
 {
   MMonProbe *m = static_cast<MMonProbe*>(op->get_req());
-  MMonProbe *r;
 
   dout(10) << "handle_probe_probe " << m->get_source_inst() << *m
 	   << " features " << m->get_connection()->get_features() << dendl;
@@ -1645,7 +1648,8 @@ void Monitor::handle_probe_probe(MonOpRequestRef op)
 
     }
   }
-
+  
+  MMonProbe *r;
   r = new MMonProbe(monmap->fsid, MMonProbe::OP_REPLY, name, has_ever_joined);
   r->name = name;
   r->quorum = quorum;
@@ -2458,8 +2462,8 @@ void Monitor::get_cluster_status(stringstream &ss, Formatter *f)
     f->open_object_section("pgmap");
     pgmon()->pg_map.print_summary(f, NULL);
     f->close_section();
-    f->open_object_section("mdsmap");
-    mdsmon()->mdsmap.print_summary(f, NULL);
+    f->open_object_section("fsmap");
+    mdsmon()->fsmap.print_summary(f, NULL);
     f->close_section();
     f->close_section();
   } else {
@@ -2469,8 +2473,10 @@ void Monitor::get_cluster_status(stringstream &ss, Formatter *f)
     ss << "     monmap " << *monmap << "\n";
     ss << "            election epoch " << get_epoch()
        << ", quorum " << get_quorum() << " " << get_quorum_names() << "\n";
-    if (mdsmon()->mdsmap.get_enabled())
-      ss << "     mdsmap " << mdsmon()->mdsmap << "\n";
+    if (mdsmon()->fsmap.any_filesystems()) {
+      ss << "     mdsmap " << mdsmon()->fsmap << "\n";
+    }
+
     osdmon()->osdmap.print_summary(NULL, ss);
     pgmon()->pg_map.print_summary(NULL, &ss);
   }
@@ -2557,11 +2563,6 @@ void Monitor::get_locally_supported_monitor_commands(const MonCommand **cmds,
   *cmds = mon_commands;
   *count = ARRAY_SIZE(mon_commands);
 }
-void Monitor::get_leader_supported_commands(const MonCommand **cmds, int *count)
-{
-  *cmds = leader_supported_mon_commands;
-  *count = leader_supported_mon_commands_size;
-}
 void Monitor::get_classic_monitor_commands(const MonCommand **cmds, int *count)
 {
   *cmds = classic_mon_commands;
@@ -2597,8 +2598,15 @@ void Monitor::handle_command(MonOpRequestRef op)
     return;
   }
 
-  MonSession *session = m->get_session();
-  assert(session);
+  MonSession *session = static_cast<MonSession *>(
+    m->get_connection()->get_priv());
+  if (!session) {
+    dout(5) << __func__ << " dropping stray message " << *m << dendl;
+    return;
+  }
+  BOOST_SCOPE_EXIT_ALL(=) {
+    session->put();
+  };
 
   if (m->cmd.empty()) {
     string rs = "No command supplied";
@@ -3254,19 +3262,11 @@ void Monitor::no_reply(MonOpRequestRef op)
   Message *req = op->get_req();
 
   if (session->proxy_con) {
-    if (get_quorum_features() & CEPH_FEATURE_MON_NULLROUTE) {
-      dout(10) << "no_reply to " << req->get_source_inst()
-	       << " via " << session->proxy_con->get_peer_addr()
-	       << " for request " << *req << dendl;
-      session->proxy_con->send_message(new MRoute(session->proxy_tid, NULL));
-      op->mark_event("no_reply: send routed request");
-    } else {
-      dout(10) << "no_reply no quorum nullroute feature for "
-               << req->get_source_inst()
-	       << " via " << session->proxy_con->get_peer_addr()
-	       << " for request " << *req << dendl;
-      op->mark_event("no_reply: no quorum support");
-    }
+    dout(10) << "no_reply to " << req->get_source_inst()
+	     << " via " << session->proxy_con->get_peer_addr()
+	     << " for request " << *req << dendl;
+    session->proxy_con->send_message(new MRoute(session->proxy_tid, NULL));
+    op->mark_event("no_reply: send routed request");
   } else {
     dout(10) << "no_reply to " << req->get_source_inst()
              << " " << *req << dendl;
@@ -3825,8 +3825,7 @@ void Monitor::timecheck_start_round()
   timecheck();
 out:
   dout(10) << __func__ << " setting up next event" << dendl;
-  timecheck_event = new C_TimeCheck(this);
-  timer.add_event_after(g_conf->mon_timecheck_interval, timecheck_event);
+  timecheck_reset_event();
 }
 
 void Monitor::timecheck_finish_round(bool success)
@@ -3840,6 +3839,7 @@ void Monitor::timecheck_finish_round(bool success)
     assert(timecheck_waiting.empty());
     assert(timecheck_acks == quorum.size());
     timecheck_report();
+    timecheck_check_skews();
     return;
   }
 
@@ -3873,6 +3873,69 @@ void Monitor::timecheck_cleanup()
   timecheck_waiting.clear();
   timecheck_skews.clear();
   timecheck_latencies.clear();
+
+  timecheck_rounds_since_clean = 0;
+}
+
+void Monitor::timecheck_reset_event()
+{
+  if (timecheck_event) {
+    timer.cancel_event(timecheck_event);
+    timecheck_event = NULL;
+  }
+
+  double delay =
+    cct->_conf->mon_timecheck_skew_interval * timecheck_rounds_since_clean;
+
+  if (delay <= 0 || delay > cct->_conf->mon_timecheck_interval) {
+    delay = cct->_conf->mon_timecheck_interval;
+  }
+
+  dout(10) << __func__ << " delay " << delay
+           << " rounds_since_clean " << timecheck_rounds_since_clean
+           << dendl;
+
+  timecheck_event = new C_TimeCheck(this);
+  timer.add_event_after(delay, timecheck_event);
+}
+
+void Monitor::timecheck_check_skews()
+{
+  dout(10) << __func__ << dendl;
+  assert(is_leader());
+  assert((timecheck_round % 2) == 0);
+  if (monmap->size() == 1) {
+    assert(0 == "We are alone; we shouldn't have gotten here!");
+    return;
+  }
+  assert(timecheck_latencies.size() == timecheck_skews.size());
+
+  bool found_skew = false;
+  for (map<entity_inst_t, double>::iterator p = timecheck_skews.begin();
+       p != timecheck_skews.end(); ++p) {
+
+    double abs_skew;
+    if (timecheck_has_skew(p->second, &abs_skew)) {
+      dout(10) << __func__
+               << " " << p->first << " skew " << abs_skew << dendl;
+      found_skew = true;
+    }
+  }
+
+  if (found_skew) {
+    ++timecheck_rounds_since_clean;
+    timecheck_reset_event();
+  } else if (timecheck_rounds_since_clean > 0) {
+    dout(1) << __func__
+      << " no clock skews found after " << timecheck_rounds_since_clean
+      << " rounds" << dendl;
+    // make sure the skews are really gone and not just a transient success
+    // this will run just once if not in the presence of skews again.
+    timecheck_rounds_since_clean = 1;
+    timecheck_reset_event();
+    timecheck_rounds_since_clean = 0;
+  }
+
 }
 
 void Monitor::timecheck_report()
@@ -3895,7 +3958,8 @@ void Monitor::timecheck_report()
     m->epoch = get_epoch();
     m->round = timecheck_round;
 
-    for (map<entity_inst_t, double>::iterator it = timecheck_skews.begin(); it != timecheck_skews.end(); ++it) {
+    for (map<entity_inst_t, double>::iterator it = timecheck_skews.begin();
+         it != timecheck_skews.end(); ++it) {
       double skew = it->second;
       double latency = timecheck_latencies[it->first];
 
@@ -3954,10 +4018,10 @@ health_status_t Monitor::timecheck_status(ostringstream &ss,
                                           const double latency)
 {
   health_status_t status = HEALTH_OK;
-  double abs_skew = (skew_bound > 0 ? skew_bound : -skew_bound);
   assert(latency >= 0);
 
-  if (abs_skew > g_conf->mon_clock_drift_allowed) {
+  double abs_skew;
+  if (timecheck_has_skew(skew_bound, &abs_skew)) {
     status = HEALTH_WARN;
     ss << "clock skew " << abs_skew << "s"
        << " > max " << g_conf->mon_clock_drift_allowed << "s";
@@ -4072,11 +4136,7 @@ void Monitor::handle_timecheck_leader(MonOpRequestRef op)
 	   << " delta " << delta << " skew_bound " << skew_bound
 	   << " latency " << latency << dendl;
 
-  if (timecheck_skews.count(other) == 0) {
-    timecheck_skews[other] = skew_bound;
-  } else {
-    timecheck_skews[other] = (timecheck_skews[other]*0.8)+(skew_bound*0.2);
-  }
+  timecheck_skews[other] = skew_bound;
 
   timecheck_acks++;
   if (timecheck_acks == quorum.size()) {
@@ -4186,9 +4246,12 @@ void Monitor::handle_subscribe(MonOpRequestRef op)
 			       p->second.flags & CEPH_SUBSCRIBE_ONETIME,
 			       m->get_connection()->has_feature(CEPH_FEATURE_INCSUBOSDMAP));
 
-    if (p->first == "mdsmap") {
+    if (p->first.find("mdsmap") == 0 || p->first == "fsmap") {
+      dout(10) << __func__ << ": MDS sub '" << p->first << "'" << dendl;
       if ((int)s->is_capable("mds", MON_CAP_R)) {
-        mdsmon()->check_sub(s->sub_map["mdsmap"]);
+        Subscription *sub = s->sub_map[p->first];
+        assert(sub != nullptr);
+        mdsmon()->check_sub(sub);
       }
     } else if (p->first == "osdmap") {
       if ((int)s->is_capable("osd", MON_CAP_R)) {
@@ -4237,6 +4300,8 @@ void Monitor::handle_get_version(MonOpRequestRef op)
 
   if (m->what == "mdsmap") {
     svc = mdsmon();
+  } else if (m->what == "fsmap") {
+    svc = mdsmon();
   } else if (m->what == "osdmap") {
     svc = osdmon();
   } else if (m->what == "monmap") {
@@ -4423,11 +4488,6 @@ int Monitor::scrub_start()
   dout(10) << __func__ << dendl;
   assert(is_leader());
 
-  if ((get_quorum_features() & CEPH_FEATURE_MON_SCRUB) == 0) {
-    clog->warn() << "scrub not supported by entire quorum\n";
-    return -EOPNOTSUPP;
-  }
-
   if (!scrub_result.empty()) {
     clog->info() << "scrub already in progress\n";
     return -EBUSY;
@@ -4946,7 +5006,7 @@ int Monitor::write_default_keyring(bufferlist& bl)
   os << g_conf->mon_data << "/keyring";
 
   int err = 0;
-  int fd = ::open(os.str().c_str(), O_WRONLY|O_CREAT, 0644);
+  int fd = ::open(os.str().c_str(), O_WRONLY|O_CREAT, 0600);
   if (fd < 0) {
     err = -errno;
     dout(0) << __func__ << " failed to open " << os.str() 
diff --git a/src/mon/Monitor.h b/src/mon/Monitor.h
index d506eba..add1c3e 100644
--- a/src/mon/Monitor.h
+++ b/src/mon/Monitor.h
@@ -53,6 +53,7 @@
 #include "include/memory.h"
 #include "include/str_map.h"
 #include <errno.h>
+#include <cmath>
 
 #include "common/TrackedOp.h"
 #include "mon/MonOpRequest.h"
@@ -502,6 +503,15 @@ private:
   version_t timecheck_round;
   unsigned int timecheck_acks;
   utime_t timecheck_round_start;
+  /* When we hit a skew we will start a new round based off of
+   * 'mon_timecheck_skew_interval'. Each new round will be backed off
+   * until we hit 'mon_timecheck_interval' -- which is the typical
+   * interval when not in the presence of a skew.
+   *
+   * This variable tracks the number of rounds with skews since last clean
+   * so that we can report to the user and properly adjust the backoff.
+   */
+  uint64_t timecheck_rounds_since_clean;
   /**
    * Time Check event.
    */
@@ -521,6 +531,8 @@ private:
   void timecheck_finish_round(bool success = true);
   void timecheck_cancel_round();
   void timecheck_cleanup();
+  void timecheck_reset_event();
+  void timecheck_check_skews();
   void timecheck_report();
   void timecheck();
   health_status_t timecheck_status(ostringstream &ss,
@@ -529,6 +541,16 @@ private:
   void handle_timecheck_leader(MonOpRequestRef op);
   void handle_timecheck_peon(MonOpRequestRef op);
   void handle_timecheck(MonOpRequestRef op);
+
+  /**
+   * Returns 'true' if this is considered to be a skew; 'false' otherwise.
+   */
+  bool timecheck_has_skew(const double skew_bound, double *abs) const {
+    double abs_skew = std::fabs(skew_bound);
+    if (abs)
+      *abs = abs_skew;
+    return (abs_skew > g_conf->mon_clock_drift_allowed);
+  }
   /**
    * @}
    */
@@ -964,7 +986,6 @@ public:
 					  bufferlist *rdata);
   void get_locally_supported_monitor_commands(const MonCommand **cmds, int *count);
   void get_classic_monitor_commands(const MonCommand **cmds, int *count);
-  void get_leader_supported_commands(const MonCommand **cmds, int *count);
   /// the Monitor owns this pointer once you pass it in
   void set_leader_supported_commands(const MonCommand *cmds, int size);
   static bool is_keyring_required();
diff --git a/src/mon/MonmapMonitor.cc b/src/mon/MonmapMonitor.cc
index d95455e..1ff6e06 100644
--- a/src/mon/MonmapMonitor.cc
+++ b/src/mon/MonmapMonitor.cc
@@ -414,7 +414,8 @@ bool MonmapMonitor::prepare_command(MonOpRequestRef op)
     dout(0) << __func__ << " proposing new mon." << name << dendl;
     goto reply;
 
-  } else if (prefix == "mon remove") {
+  } else if (prefix == "mon remove" ||
+             prefix == "mon rm") {
     string name;
     cmd_getval(g_ceph_context, cmdmap, "name", name);
     if (!monmap.contains(name)) {
diff --git a/src/mon/OSDMonitor.cc b/src/mon/OSDMonitor.cc
index 42c58a0..4051132 100644
--- a/src/mon/OSDMonitor.cc
+++ b/src/mon/OSDMonitor.cc
@@ -125,6 +125,9 @@ void OSDMonitor::create_initial()
   // new clusters should sort bitwise by default.
   newmap.set_flag(CEPH_OSDMAP_SORTBITWISE);
 
+  // new cluster should require jewel by default
+  newmap.set_flag(CEPH_OSDMAP_REQUIRE_JEWEL);
+
   // encode into pending incremental
   newmap.encode(pending_inc.fullmap, mon->quorum_features | CEPH_FEATURE_RESERVED);
   pending_inc.full_crc = newmap.get_crc();
@@ -475,16 +478,21 @@ void OSDMonitor::update_logger()
  * The osds that will get a lower weight are those with with a utilization
  * percentage 'oload' percent greater than the average utilization.
  */
-int OSDMonitor::reweight_by_utilization(int oload, std::string& out_str,
-					bool by_pg, const set<int64_t> *pools)
+int OSDMonitor::reweight_by_utilization(int oload,
+					double max_changef,
+					int max_osds,
+					bool by_pg, const set<int64_t> *pools,
+					bool no_increasing,
+					bool dry_run,
+					std::stringstream *ss,
+					std::string *out_str,
+					Formatter *f)
 {
   if (oload <= 100) {
-    ostringstream oss;
-    oss << "You must give a percentage higher than 100. "
+    *ss << "You must give a percentage higher than 100. "
       "The reweighting threshold will be calculated as <average-utilization> "
       "times <input-percentage>. For example, an argument of 200 would "
       "reweight OSDs which are twice as utilized as the average OSD.\n";
-    out_str = oss.str();
     return -EINVAL;
   }
 
@@ -520,10 +528,8 @@ int OSDMonitor::reweight_by_utilization(int oload, std::string& out_str,
     }
 
     if (!num_osds || (num_pg_copies / num_osds < g_conf->mon_reweight_min_pgs_per_osd)) {
-      ostringstream oss;
-      oss << "Refusing to reweight: we only have " << num_pg_copies
+      *ss << "Refusing to reweight: we only have " << num_pg_copies
 	  << " PGs across " << num_osds << " osds!\n";
-      out_str = oss.str();
       return -EDOM;
     }
 
@@ -534,17 +540,15 @@ int OSDMonitor::reweight_by_utilization(int oload, std::string& out_str,
     if ((uint64_t)pgm.osd_sum.kb * 1024 / num_osd
 	< g_conf->mon_reweight_min_bytes_per_osd) {
       ostringstream oss;
-      oss << "Refusing to reweight: we only have " << pgm.osd_sum.kb
+      *ss << "Refusing to reweight: we only have " << pgm.osd_sum.kb
 	  << " kb across all osds!\n";
-      out_str = oss.str();
       return -EDOM;
     }
     if ((uint64_t)pgm.osd_sum.kb_used * 1024 / num_osd
 	< g_conf->mon_reweight_min_bytes_per_osd) {
       ostringstream oss;
-      oss << "Refusing to reweight: we only have " << pgm.osd_sum.kb_used
+      *ss << "Refusing to reweight: we only have " << pgm.osd_sum.kb_used
 	  << " kb used across all osds!\n";
-      out_str = oss.str();
       return -EDOM;
     }
 
@@ -557,61 +561,129 @@ int OSDMonitor::reweight_by_utilization(int oload, std::string& out_str,
   // but aggressively adjust weights up whenever possible.
   double underload_util = average_util;
 
+  unsigned max_change = (unsigned)(max_changef * (double)0x10000);
+
   ostringstream oss;
-  char buf[128];
-  snprintf(buf, sizeof(buf), "average %04f, overload %04f. ",
-	   average_util, overload_util);
-  oss << buf;
-  std::string sep;
-  oss << "reweighted: ";
+  if (f) {
+    f->open_object_section("reweight_by_utilization");
+    f->dump_unsigned("overload_min", oload);
+    f->dump_float("max_change", max_changef);
+    f->dump_float("max_change_osds", max_osds);
+    f->dump_float("average_utilization", average_util);
+    f->dump_float("overload_utilization", overload_util);
+  } else {
+    oss << "oload " << oload << "\n";
+    oss << "max_change " << max_changef << "\n";
+    oss << "max_change_osds " << max_osds << "\n";
+    char buf[128];
+    snprintf(buf, sizeof(buf), "average %04f\noverload %04f\n",
+	     average_util, overload_util);
+    oss << buf;
+  }
   bool changed = false;
+  int num_changed = 0;
+
+  // precompute util for each OSD
+  std::vector<std::pair<int, float> > util_by_osd;
   for (ceph::unordered_map<int,osd_stat_t>::const_iterator p =
-	 pgm.osd_stat.begin();
+       pgm.osd_stat.begin();
        p != pgm.osd_stat.end();
        ++p) {
-    float util;
+    std::pair<int, float> osd_util;
+    osd_util.first = p->first;
     if (by_pg) {
-      util = pgs_by_osd[p->first] / osdmap.crush->get_item_weightf(p->first);
+      osd_util.second = pgs_by_osd[p->first] / osdmap.crush->get_item_weightf(p->first);
     } else {
-      util = (double)p->second.kb_used / (double)p->second.kb;
+      osd_util.second = (double)p->second.kb_used / (double)p->second.kb;
     }
+    util_by_osd.push_back(osd_util);
+  }
+
+  // sort and iterate from most to least utilized
+  std::sort(util_by_osd.begin(), util_by_osd.end(), [](std::pair<int, float> l, std::pair<int, float> r) {
+    return l.second > r.second;
+  });
+
+  OSDMap::Incremental newinc;
+
+  if (f)
+    f->open_array_section("reweights");
+
+  for (std::vector<std::pair<int, float> >::const_iterator p =
+	 util_by_osd.begin();
+       p != util_by_osd.end();
+       ++p) {
+    float util = p->second;
+
     if (util >= overload_util) {
-      sep = ", ";
       // Assign a lower weight to overloaded OSDs. The current weight
       // is a factor to take into account the original weights,
       // to represent e.g. differing storage capacities
       unsigned weight = osdmap.get_weight(p->first);
       unsigned new_weight = (unsigned)((average_util / util) * (float)weight);
-      pending_inc.new_weight[p->first] = new_weight;
-      char buf[128];
-      snprintf(buf, sizeof(buf), "osd.%d [%04f -> %04f]", p->first,
-	       (float)weight / (float)0x10000,
-	       (float)new_weight / (float)0x10000);
-      oss << buf << sep;
-      changed = true;
+      new_weight = MAX(new_weight, weight - max_change);
+      newinc.new_weight[p->first] = new_weight;
+      if (!dry_run) {
+	pending_inc.new_weight[p->first] = new_weight;
+	changed = true;
+      }
+      if (f) {
+	f->open_object_section("osd");
+	f->dump_unsigned("osd", p->first);
+	f->dump_float("weight", (float)weight / (float)0x10000);
+	f->dump_float("new_weight", (float)new_weight / (float)0x10000);
+	f->close_section();
+      } else {
+	char buf[128];
+	snprintf(buf, sizeof(buf), "osd.%d weight %04f -> %04f\n", p->first,
+		 (float)weight / (float)0x10000,
+		 (float)new_weight / (float)0x10000);
+	oss << buf;
+      }
+      if (++num_changed >= max_osds)
+	break;
     }
-    if (util <= underload_util) {
+    if (!no_increasing && util <= underload_util) {
       // assign a higher weight.. if we can.
       unsigned weight = osdmap.get_weight(p->first);
       unsigned new_weight = (unsigned)((average_util / util) * (float)weight);
+      new_weight = MIN(new_weight, weight + max_change);
       if (new_weight > 0x10000)
 	new_weight = 0x10000;
       if (new_weight > weight) {
-	sep = ", ";
-	pending_inc.new_weight[p->first] = new_weight;
+	newinc.new_weight[p->first] = new_weight;
+	if (!dry_run) {
+	  pending_inc.new_weight[p->first] = new_weight;
+	  changed = true;
+	}
 	char buf[128];
-	snprintf(buf, sizeof(buf), "osd.%d [%04f -> %04f]", p->first,
+	snprintf(buf, sizeof(buf), "osd.%d weight %04f -> %04f\n", p->first,
 		 (float)weight / (float)0x10000,
 		 (float)new_weight / (float)0x10000);
-	oss << buf << sep;
-	changed = true;
+	oss << buf;
+	if (++num_changed >= max_osds)
+	  break;
       }
     }
   }
-  if (sep.empty()) {
-    oss << "(none)";
+  if (f) {
+    f->close_section();
+  }
+
+  OSDMap newmap;
+  newmap.deepish_copy_from(osdmap);
+  newinc.fsid = newmap.fsid;
+  newinc.epoch = newmap.get_epoch() + 1;
+  newmap.apply_incremental(newinc);
+
+  osdmap.summarize_mapping_stats(&newmap, pools, out_str, f);
+
+  if (f) {
+    f->close_section();
+  } else {
+    *out_str += "\n";
+    *out_str += oss.str();
   }
-  out_str = oss.str();
   dout(10) << "reweight_by_utilization: finished with " << out_str << dendl;
   return changed;
 }
@@ -1871,6 +1943,16 @@ bool OSDMonitor::preprocess_boot(MonOpRequestRef op)
     goto ignore;
   }
 
+  if (osdmap.test_flag(CEPH_OSDMAP_REQUIRE_JEWEL) &&
+      !(m->get_connection()->get_features() & CEPH_FEATURE_SERVER_JEWEL)) {
+    mon->clog->info() << "disallowing boot of OSD "
+		      << m->get_orig_source_inst()
+		      << " because the osdmap requires"
+		      << " CEPH_FEATURE_SERVER_JEWEL"
+		      << " but the osd lacks CEPH_FEATURE_SERVER_JEWEL\n";
+    goto ignore;
+  }
+
   if (osdmap.test_flag(CEPH_OSDMAP_SORTBITWISE) &&
       !(m->osd_features & CEPH_FEATURE_OSD_BITWISE_HOBJ_SORT)) {
     mon->clog->info() << "disallowing boot of OSD "
@@ -2823,9 +2905,22 @@ void OSDMonitor::get_health(list<pair<health_status_t,string> >& summary,
 
     // old crush tunables?
     if (g_conf->mon_warn_on_legacy_crush_tunables) {
-      if (osdmap.crush->has_legacy_tunables()) {
+      string min = osdmap.crush->get_min_required_version();
+      if (min < g_conf->mon_crush_min_required_version) {
+	ostringstream ss;
+	ss << "crush map has legacy tunables (require " << min
+	   << ", min is " << g_conf->mon_crush_min_required_version << ")";
+	summary.push_back(make_pair(HEALTH_WARN, ss.str()));
+	if (detail) {
+	  ss << "; see http://ceph.com/docs/master/rados/operations/crush-map/#tunables";
+	  detail->push_back(make_pair(HEALTH_WARN, ss.str()));
+	}
+      }
+    }
+    if (g_conf->mon_warn_on_crush_straw_calc_version_zero) {
+      if (osdmap.crush->get_straw_calc_version() == 0) {
 	ostringstream ss;
-	ss << "crush map has legacy tunables";
+	ss << "crush map has straw_calc_version=0";
 	summary.push_back(make_pair(HEALTH_WARN, ss.str()));
 	if (detail) {
 	  ss << "; see http://ceph.com/docs/master/rados/operations/crush-map/#tunables";
@@ -3103,6 +3198,15 @@ bool OSDMonitor::preprocess_command(MonOpRequestRef op)
       ds << "max_osd = " << osdmap.get_max_osd() << " in epoch " << osdmap.get_epoch();
       rdata.append(ds);
     }
+  } else if (prefix == "osd utilization") {
+    string out;
+    osdmap.summarize_mapping_stats(NULL, NULL, &out, f.get());
+    if (f)
+      f->flush(rdata);
+    else
+      rdata.append(out);
+    r = 0;
+    goto reply;
   } else if (prefix  == "osd find") {
     int64_t osd;
     if (!cmd_getval(g_ceph_context, cmdmap, "id", osd)) {
@@ -4632,6 +4736,18 @@ int OSDMonitor::prepare_new_pool(string& name, uint64_t auid,
     dout(10) << " prepare_pool_size returns " << r << dendl;
     return r;
   }
+  const int64_t minsize = osdmap.crush->get_rule_mask_min_size(crush_ruleset);
+  if ((int64_t)size < minsize) {
+    *ss << "pool size " << size << " is smaller than crush ruleset name "
+        << crush_ruleset_name << " min size " << minsize;
+    return -EINVAL;
+  }
+  const int64_t maxsize = osdmap.crush->get_rule_mask_max_size(crush_ruleset);
+  if ((int64_t)size > maxsize) {
+    *ss << "pool size " << size << " is bigger than crush ruleset name "
+        << crush_ruleset_name << " max size " << maxsize;
+    return -EINVAL;
+  }
   uint32_t stripe_width = 0;
   r = prepare_pool_stripe_width(pool_type, erasure_code_profile, &stripe_width, ss);
   if (r) {
@@ -4829,7 +4945,8 @@ int OSDMonitor::prepare_command_pool_set(map<string,cmd_vartype> &cmdmap,
        var == "cache_target_full_ratio" || var == "cache_target_dirty_ratio" ||
        var == "cache_target_dirty_high_ratio" ||
        var == "cache_min_flush_age" || var == "cache_min_evict_age" ||
-       var == "hit_set_grade_decay_rate" || var == "hit_set_search_last_n")) {
+       var == "hit_set_grade_decay_rate" || var == "hit_set_search_last_n" ||
+       var == "min_read_recency_for_promote" || var == "min_write_recency_for_promote")) {
     return -EACCES;
   }
 
@@ -6152,6 +6269,13 @@ bool OSDMonitor::prepare_command_impl(MonOpRequestRef op,
 	ss << "not all up OSDs have OSD_BITWISE_HOBJ_SORT feature";
 	err = -EPERM;
       }
+    } else if (key == "require_jewel_osds") {
+      if (osdmap.get_up_osd_features() & CEPH_FEATURE_SERVER_JEWEL) {
+	return prepare_set_flag(op, CEPH_OSDMAP_REQUIRE_JEWEL);
+      } else {
+	ss << "not all up OSDs have CEPH_FEATURE_SERVER_JEWEL feature";
+	err = -EPERM;
+      }
     } else {
       ss << "unrecognized flag '" << key << "'";
       err = -EINVAL;
@@ -6845,8 +6969,9 @@ done:
 					      get_last_committed() + 1));
     return true;
 
-  } else if (prefix == "osd pool delete") {
-    // osd pool delete <poolname> <poolname again> --yes-i-really-really-mean-it
+  } else if (prefix == "osd pool delete" ||
+             prefix == "osd pool rm") {
+    // osd pool delete/rm <poolname> <poolname again> --yes-i-really-really-mean-it
     string poolstr, poolstr2, sure;
     cmd_getval(g_ceph_context, cmdmap, "pool", poolstr);
     cmd_getval(g_ceph_context, cmdmap, "pool2", poolstr2);
@@ -6995,7 +7120,8 @@ done:
     wait_for_finished_proposal(op, new Monitor::C_Command(mon, op, 0, ss.str(),
 					      get_last_committed() + 1));
     return true;
-  } else if (prefix == "osd tier remove") {
+  } else if (prefix == "osd tier remove" ||
+             prefix == "osd tier rm") {
     string poolstr;
     cmd_getval(g_ceph_context, cmdmap, "pool", poolstr);
     int64_t pool_id = osdmap.lookup_pg_pool_name(poolstr);
@@ -7109,7 +7235,8 @@ done:
     wait_for_finished_proposal(op, new Monitor::C_Command(mon, op, 0, ss.str(),
 					      get_last_committed() + 1));
     return true;
-  } else if (prefix == "osd tier remove-overlay") {
+  } else if (prefix == "osd tier remove-overlay" ||
+             prefix == "osd tier rm-overlay") {
     string poolstr;
     cmd_getval(g_ceph_context, cmdmap, "pool", poolstr);
     int64_t pool_id = osdmap.lookup_pg_pool_name(poolstr);
@@ -7368,7 +7495,7 @@ done:
     string field;
     cmd_getval(g_ceph_context, cmdmap, "field", field);
     if (field != "max_objects" && field != "max_bytes") {
-      ss << "unrecognized field '" << field << "'; max_bytes of max_objects";
+      ss << "unrecognized field '" << field << "'; should be 'max_bytes' or 'max_objects'";
       err = -EINVAL;
       goto reply;
     }
@@ -7398,23 +7525,15 @@ done:
 					      get_last_committed() + 1));
     return true;
 
-  } else if (prefix == "osd reweight-by-utilization") {
-    int64_t oload;
-    cmd_getval(g_ceph_context, cmdmap, "oload", oload, int64_t(120));
-    string out_str;
-    err = reweight_by_utilization(oload, out_str, false, NULL);
-    if (err < 0) {
-      ss << "FAILED reweight-by-utilization: " << out_str;
-    } else if (err == 0) {
-      ss << "no change: " << out_str;
-    } else {
-      ss << "SUCCESSFUL reweight-by-utilization: " << out_str;
-      getline(ss, rs);
-      wait_for_finished_proposal(op, new Monitor::C_Command(mon, op, 0, rs,
-						get_last_committed() + 1));
-      return true;
-    }
-  } else if (prefix == "osd reweight-by-pg") {
+  } else if (prefix == "osd reweight-by-pg" ||
+	     prefix == "osd reweight-by-utilization" ||
+	     prefix == "osd test-reweight-by-pg" ||
+	     prefix == "osd test-reweight-by-utilization") {
+    bool by_pg =
+      prefix == "osd reweight-by-pg" || prefix == "osd test-reweight-by-pg";
+    bool dry_run =
+      prefix == "osd test-reweight-by-pg" ||
+      prefix == "osd test-reweight-by-utilization";
     int64_t oload;
     cmd_getval(g_ceph_context, cmdmap, "oload", oload, int64_t(120));
     set<int64_t> pools;
@@ -7429,18 +7548,39 @@ done:
       }
       pools.insert(pool);
     }
+    double max_change = g_conf->mon_reweight_max_change;
+    cmd_getval(g_ceph_context, cmdmap, "max_change", max_change);
+    if (max_change <= 0.0) {
+      ss << "max_change " << max_change << " must be positive";
+      err = -EINVAL;
+      goto reply;
+    }
+    int64_t max_osds = g_conf->mon_reweight_max_osds;
+    cmd_getval(g_ceph_context, cmdmap, "max_osds", max_osds);
+    string no_increasing;
+    cmd_getval(g_ceph_context, cmdmap, "no_increasing", no_increasing);
     string out_str;
-    err = reweight_by_utilization(oload, out_str, true,
-				  pools.empty() ? NULL : &pools);
+    err = reweight_by_utilization(oload,
+				  max_change,
+				  max_osds,
+				  by_pg,
+				  pools.empty() ? NULL : &pools,
+				  no_increasing == "--no-increasing",
+				  dry_run,
+				  &ss, &out_str, f.get());
+    if (f)
+      f->flush(rdata);
+    else
+      rdata.append(out_str);
     if (err < 0) {
-      ss << "FAILED reweight-by-pg: " << out_str;
+      ss << "FAILED reweight-by-pg";
     } else if (err == 0) {
-      ss << "no change: " << out_str;
+      ss << "no change";
     } else {
-      ss << "SUCCESSFUL reweight-by-pg: " << out_str;
-      getline(ss, rs);
-      wait_for_finished_proposal(op, new Monitor::C_Command(mon, op, 0, rs,
-						get_last_committed() + 1));
+      ss << "SUCCESSFUL reweight-by-pg";
+      wait_for_finished_proposal(
+	op,
+	new Monitor::C_Command(mon, op, 0, rs, rdata, get_last_committed() + 1));
       return true;
     }
   } else if (prefix == "osd thrash") {
@@ -7724,8 +7864,8 @@ int OSDMonitor::_check_remove_pool(int64_t pool, const pg_pool_t *p,
   const string& poolstr = osdmap.get_pool_name(pool);
 
   // If the Pool is in use by CephFS, refuse to delete it
-  MDSMap const &pending_mdsmap = mon->mdsmon()->pending_mdsmap;
-  if (pending_mdsmap.pool_in_use(pool)) {
+  FSMap const &pending_fsmap = mon->mdsmon()->pending_fsmap;
+  if (pending_fsmap.pool_in_use(pool)) {
     *ss << "pool '" << poolstr << "' is in use by CephFS";
     return -EBUSY;
   }
@@ -7773,8 +7913,8 @@ bool OSDMonitor::_check_become_tier(
   const std::string &tier_pool_name = osdmap.get_pool_name(tier_pool_id);
   const std::string &base_pool_name = osdmap.get_pool_name(base_pool_id);
 
-  const MDSMap &pending_mdsmap = mon->mdsmon()->pending_mdsmap;
-  if (pending_mdsmap.pool_in_use(tier_pool_id)) {
+  const FSMap &pending_fsmap = mon->mdsmon()->pending_fsmap;
+  if (pending_fsmap.pool_in_use(tier_pool_id)) {
     *ss << "pool '" << tier_pool_name << "' is in use by CephFS";
     *err = -EBUSY;
     return false;
@@ -7823,8 +7963,8 @@ bool OSDMonitor::_check_remove_tier(
   const std::string &base_pool_name = osdmap.get_pool_name(base_pool_id);
 
   // Apply CephFS-specific checks
-  const MDSMap &pending_mdsmap = mon->mdsmon()->pending_mdsmap;
-  if (pending_mdsmap.pool_in_use(base_pool_id)) {
+  const FSMap &pending_fsmap = mon->mdsmon()->pending_fsmap;
+  if (pending_fsmap.pool_in_use(base_pool_id)) {
     if (base_pool->type != pg_pool_t::TYPE_REPLICATED) {
       // If the underlying pool is erasure coded, we can't permit the
       // removal of the replicated tier that CephFS relies on to access it
diff --git a/src/mon/OSDMonitor.h b/src/mon/OSDMonitor.h
index 3e50dae..9d4d33d 100644
--- a/src/mon/OSDMonitor.h
+++ b/src/mon/OSDMonitor.h
@@ -226,10 +226,18 @@ public:
   //            @c Monitor::send_reply() can mark_event with it.
   void send_incremental(epoch_t first, MonSession *session, bool onetime,
 			MonOpRequestRef req = MonOpRequestRef());
-private:
-  int reweight_by_utilization(int oload, std::string& out_str, bool by_pg,
-			      const set<int64_t> *pools);
 
+private:
+  int reweight_by_utilization(int oload,
+			      double max_change,
+			      int max_osds,
+			      bool by_pg,
+			      const set<int64_t> *pools,
+			      bool no_increasing,
+			      bool dry_run,
+			      std::stringstream *ss,
+			      std::string *out_str,
+			      Formatter *f);
   void print_utilization(ostream &out, Formatter *f, bool tree) const;
 
   bool check_source(PaxosServiceMessage *m, uuid_d fsid);
diff --git a/src/mon/PGMap.cc b/src/mon/PGMap.cc
index b81db7c..8116201 100644
--- a/src/mon/PGMap.cc
+++ b/src/mon/PGMap.cc
@@ -459,7 +459,7 @@ void PGMap::remove_osd(int osd)
   }
 }
 
-void PGMap::stat_pg_add(const pg_t &pgid, const pg_stat_t &s, bool nocreating,
+void PGMap::stat_pg_add(const pg_t &pgid, const pg_stat_t &s,
                         bool sameosds)
 {
   pg_pool_sum[pgid.pool()].add(s);
@@ -468,12 +468,10 @@ void PGMap::stat_pg_add(const pg_t &pgid, const pg_stat_t &s, bool nocreating,
   num_pg++;
   num_pg_by_state[s.state]++;
 
-  if (!nocreating) {
-    if (s.state & PG_STATE_CREATING) {
-      creating_pgs.insert(pgid);
-      if (s.acting_primary >= 0) {
-	creating_pgs_by_osd_epoch[s.acting_primary][s.mapping_epoch].insert(pgid);
-      }
+  if (s.state & PG_STATE_CREATING) {
+    creating_pgs.insert(pgid);
+    if (s.acting_primary >= 0) {
+      creating_pgs_by_osd_epoch[s.acting_primary][s.mapping_epoch].insert(pgid);
     }
   }
 
@@ -492,7 +490,7 @@ void PGMap::stat_pg_add(const pg_t &pgid, const pg_stat_t &s, bool nocreating,
     pg_by_osd[*p].insert(pgid);
 }
 
-void PGMap::stat_pg_sub(const pg_t &pgid, const pg_stat_t &s, bool nocreating,
+void PGMap::stat_pg_sub(const pg_t &pgid, const pg_stat_t &s,
                         bool sameosds)
 {
   pool_stat_t& ps = pg_pool_sum[pgid.pool()];
@@ -507,17 +505,15 @@ void PGMap::stat_pg_sub(const pg_t &pgid, const pg_stat_t &s, bool nocreating,
   if (end == 0)
     num_pg_by_state.erase(s.state);
 
-  if (!nocreating) {
-    if (s.state & PG_STATE_CREATING) {
-      creating_pgs.erase(pgid);
-      if (s.acting_primary >= 0) {
-	map<epoch_t,set<pg_t> >& r = creating_pgs_by_osd_epoch[s.acting_primary];
-	r[s.mapping_epoch].erase(pgid);
-	if (r[s.mapping_epoch].empty())
-	  r.erase(s.mapping_epoch);
-	if (r.empty())
-	  creating_pgs_by_osd_epoch.erase(s.acting_primary);
-      }
+  if (s.state & PG_STATE_CREATING) {
+    creating_pgs.erase(pgid);
+    if (s.acting_primary >= 0) {
+      map<epoch_t,set<pg_t> >& r = creating_pgs_by_osd_epoch[s.acting_primary];
+      r[s.mapping_epoch].erase(pgid);
+      if (r[s.mapping_epoch].empty())
+	r.erase(s.mapping_epoch);
+      if (r.empty())
+	creating_pgs_by_osd_epoch.erase(s.acting_primary);
     }
   }
 
@@ -559,9 +555,9 @@ void PGMap::stat_pg_update(const pg_t pgid, pg_stat_t& s,
     s.up == n.up &&
     s.blocked_by == n.blocked_by;
 
-  stat_pg_sub(pgid, s, false, sameosds);
+  stat_pg_sub(pgid, s, sameosds);
   s = n;
-  stat_pg_add(pgid, n, false, sameosds);
+  stat_pg_add(pgid, n, sameosds);
 }
 
 void PGMap::stat_osd_add(const osd_stat_t &s)
diff --git a/src/mon/PGMap.h b/src/mon/PGMap.h
index 8c2b3ca..335c120 100644
--- a/src/mon/PGMap.h
+++ b/src/mon/PGMap.h
@@ -258,9 +258,9 @@ public:
   void redo_full_sets();
   void register_nearfull_status(int osd, const osd_stat_t& s);
   void calc_stats();
-  void stat_pg_add(const pg_t &pgid, const pg_stat_t &s, bool nocreating=false,
+  void stat_pg_add(const pg_t &pgid, const pg_stat_t &s,
 		   bool sameosds=false);
-  void stat_pg_sub(const pg_t &pgid, const pg_stat_t &s, bool nocreating=false,
+  void stat_pg_sub(const pg_t &pgid, const pg_stat_t &s,
 		   bool sameosds=false);
   void stat_pg_update(const pg_t pgid, pg_stat_t &prev, bufferlist::iterator& blp);
   void stat_osd_add(const osd_stat_t &s);
diff --git a/src/mon/PGMonitor.cc b/src/mon/PGMonitor.cc
index 99e2287..eadba02 100644
--- a/src/mon/PGMonitor.cc
+++ b/src/mon/PGMonitor.cc
@@ -440,16 +440,19 @@ void PGMonitor::apply_pgmap_delta(bufferlist& bl)
       r = -ENOENT;
     } else {
       r = mon->store->get(pgmap_pg_prefix, stringify(pgid), pgbl);
-      dout(20) << " refreshing pg " << pgid << " got " << r << " len "
-               << pgbl.length() << dendl;
-
       if (pg_pool_sum_old.count(pgid.pool()) == 0)
 	pg_pool_sum_old[pgid.pool()] = pg_map.pg_pool_sum[pgid.pool()];
     }
 
     if (r >= 0) {
       pg_map.update_pg(pgid, pgbl);
+      dout(20) << " refreshing pg " << pgid
+	       << " " << pg_map.pg_stat[pgid].reported_epoch
+	       << ":" << pg_map.pg_stat[pgid].reported_seq
+	       << " " << pg_state_string(pg_map.pg_stat[pgid].state)
+	       << dendl;
     } else {
+      dout(20) << " removing pg " << pgid << dendl;
       pg_map.remove_pg(pgid);
       if (pgid.ps() == 0)
 	deleted_pools.insert(pgid.pool());
@@ -999,11 +1002,28 @@ void PGMonitor::register_pg(OSDMap *osdmap,
   stats.mapping_epoch = epoch;
 
   if (parent_found) {
-    stats.last_scrub_stamp = pg_map.pg_stat[parent].last_scrub_stamp;
-    stats.last_deep_scrub_stamp = pg_map.pg_stat[parent].last_deep_scrub_stamp;
-    stats.last_clean_scrub_stamp = pg_map.pg_stat[parent].last_clean_scrub_stamp;
+    pg_stat_t &ps = pg_map.pg_stat[parent];
+    stats.last_fresh = ps.last_fresh;
+    stats.last_active = ps.last_active;
+    stats.last_change = ps.last_change;
+    stats.last_peered = ps.last_peered;
+    stats.last_clean = ps.last_clean;
+    stats.last_unstale = ps.last_unstale;
+    stats.last_undegraded = ps.last_undegraded;
+    stats.last_fullsized = ps.last_fullsized;
+    stats.last_scrub_stamp = ps.last_scrub_stamp;
+    stats.last_deep_scrub_stamp = ps.last_deep_scrub_stamp;
+    stats.last_clean_scrub_stamp = ps.last_clean_scrub_stamp;
   } else {
     utime_t now = ceph_clock_now(g_ceph_context);
+    stats.last_fresh = now;
+    stats.last_active = now;
+    stats.last_change = now;
+    stats.last_peered = now;
+    stats.last_clean = now;
+    stats.last_unstale = now;
+    stats.last_undegraded = now;
+    stats.last_fullsized = now;
     stats.last_scrub_stamp = now;
     stats.last_deep_scrub_stamp = now;
     stats.last_clean_scrub_stamp = now;
@@ -1264,9 +1284,11 @@ epoch_t PGMonitor::send_pg_creates(int osd, Connection *con, epoch_t next)
   return last + 1;
 }
 
-void PGMonitor::_mark_pg_stale(pg_t pgid, const pg_stat_t& cur_stat)
+void PGMonitor::_try_mark_pg_stale(
+  OSDMap *osdmap,
+  pg_t pgid,
+  const pg_stat_t& cur_stat)
 {
-  dout(10) << " marking pg " << pgid << " stale" << dendl;
   map<pg_t,pg_stat_t>::iterator q = pending_inc.pg_stat_updates.find(pgid);
   pg_stat_t *stat;
   if (q == pending_inc.pg_stat_updates.end()) {
@@ -1275,7 +1297,12 @@ void PGMonitor::_mark_pg_stale(pg_t pgid, const pg_stat_t& cur_stat)
   } else {
     stat = &q->second;
   }
-  if (stat->acting_primary == cur_stat.acting_primary) {
+  if ((stat->acting_primary == cur_stat.acting_primary) ||
+      ((stat->state & PG_STATE_STALE) == 0 &&
+       stat->acting_primary != -1 &&
+       osdmap->is_down(stat->acting_primary))) {
+    dout(10) << " marking pg " << pgid << " stale (acting_primary "
+	     << stat->acting_primary << ")" << dendl;
     stat->state |= PG_STATE_STALE;  
     stat->last_unstale = ceph_clock_now(g_ceph_context);
   }
@@ -1299,7 +1326,7 @@ bool PGMonitor::check_down_pgs()
       if ((p.second.state & PG_STATE_STALE) == 0 &&
           p.second.acting_primary != -1 &&
           osdmap->is_down(p.second.acting_primary)) {
-	_mark_pg_stale(p.first, p.second);
+	_try_mark_pg_stale(osdmap, p.first, p.second);
 	ret = true;
       }
     }
@@ -1310,7 +1337,7 @@ bool PGMonitor::check_down_pgs()
 	  const pg_stat_t &stat = pg_map.pg_stat[pgid];
 	  if ((stat.state & PG_STATE_STALE) == 0 &&
 	      stat.acting_primary != -1) {
-	    _mark_pg_stale(pgid, stat);
+	    _try_mark_pg_stale(osdmap, pgid, stat);
 	    ret = true;
 	  }
 	}
@@ -1359,7 +1386,7 @@ void PGMonitor::dump_object_stat_sum(TextTable &tbl, Formatter *f,
     int64_t kb_used = SHIFT_ROUND_UP(sum.num_bytes, 10);
     float used = 0.0;
     if (pg_map.osd_sum.kb > 0)
-      used = (float)kb_used / pg_map.osd_sum.kb;
+      used = (float)kb_used * raw_used_rate * curr_object_copies_rate / pg_map.osd_sum.kb;
     tbl << percentify(used*100);
     tbl << si_t(avail);
     tbl << sum.num_objects;
@@ -1394,8 +1421,8 @@ int64_t PGMonitor::get_rule_avail(OSDMap& osdmap, int ruleno) const
 	// calculate proj below.
 	continue;
       }
-      int64_t proj = (float)((osd_info->second).kb_avail * 1024ull) /
-                     (double)p->second;
+      int64_t proj = (int64_t)((double)((osd_info->second).kb_avail * 1024ull) /
+                     (double)p->second);
       if (min < 0 || proj < min)
 	min = proj;
     } else {
@@ -2395,7 +2422,7 @@ void PGMonitor::get_health(list<pair<health_status_t,string> >& summary,
 	if (g_conf->mon_pg_warn_max_object_skew > 0 &&
 	    ratio > g_conf->mon_pg_warn_max_object_skew) {
 	  ostringstream ss;
-	  ss << "pool " << name << " has too few pgs";
+	  ss << "pool " << name << " has many more objects per pg than average (too few pgs?)";
 	  summary.push_back(make_pair(HEALTH_WARN, ss.str()));
 	  if (detail) {
 	    ostringstream ss;
diff --git a/src/mon/PGMonitor.h b/src/mon/PGMonitor.h
index c5af197..d3351f3 100644
--- a/src/mon/PGMonitor.h
+++ b/src/mon/PGMonitor.h
@@ -141,7 +141,7 @@ private:
    * @return true if we updated pending_inc (and should propose)
    */
   bool check_down_pgs();
-  void _mark_pg_stale(pg_t pgid, const pg_stat_t& cur_stat);
+  void _try_mark_pg_stale(OSDMap *osdmap, pg_t pgid, const pg_stat_t& cur_stat);
 
 
   /**
diff --git a/src/mount.fuse.ceph b/src/mount.fuse.ceph
index 785df6c..5290dcc 100755
--- a/src/mount.fuse.ceph
+++ b/src/mount.fuse.ceph
@@ -19,11 +19,23 @@ set -e
 # convert device string to options
 cephargs='--'`echo $1 | sed 's/,/ --/g'`
 
+# get mount point
+mountpoint=$2
+
+shift 2
+
+while [ "$1" != "-o" ]
+do
+        shift
+done
+
+opts=$2
+
 # strip out 'noauto' option; libfuse doesn't like it
-opts=`echo $4 | sed 's/,noauto//' | sed 's/noauto,//'`
+opts=`echo $opts | sed 's/,noauto//' | sed 's/noauto,//'`
 
 # strip out '_netdev' option; libfuse doesn't like it
 opts=`echo $opts | sed 's/,_netdev//' | sed 's/_netdev,//'`
 
 # go
-exec ceph-fuse $cephargs $2 $3 $opts
+exec ceph-fuse $cephargs $mountpoint -o $opts
diff --git a/src/msg/Message.cc b/src/msg/Message.cc
index c29ecef..f84004b 100644
--- a/src/msg/Message.cc
+++ b/src/msg/Message.cc
@@ -111,6 +111,7 @@ using namespace std;
 #include "messages/MMDSSlaveRequest.h"
 
 #include "messages/MMDSMap.h"
+#include "messages/MFSMap.h"
 #include "messages/MMDSBeacon.h"
 #include "messages/MMDSLoadTargets.h"
 #include "messages/MMDSResolve.h"
@@ -170,6 +171,9 @@ using namespace std;
 #include "messages/MOSDECSubOpRead.h"
 #include "messages/MOSDECSubOpReadReply.h"
 
+#include "messages/MOSDPGUpdateLogMissing.h"
+#include "messages/MOSDPGUpdateLogMissingReply.h"
+
 #define DEBUGLVL  10    // debug level of output
 
 #define dout_subsys ceph_subsys_ms
@@ -437,6 +441,12 @@ Message *decode_message(CephContext *cct, int crcflags,
   case MSG_OSD_REPOPREPLY:
     m = new MOSDRepOpReply();
     break;
+  case MSG_OSD_PG_UPDATE_LOG_MISSING:
+    m = new MOSDPGUpdateLogMissing();
+    break;
+  case MSG_OSD_PG_UPDATE_LOG_MISSING_REPLY:
+    m = new MOSDPGUpdateLogMissingReply();
+    break;
 
   case CEPH_MSG_OSD_MAP:
     m = new MOSDMap;
@@ -565,6 +575,9 @@ Message *decode_message(CephContext *cct, int crcflags,
   case CEPH_MSG_MDS_MAP:
     m = new MMDSMap;
     break;
+  case CEPH_MSG_FS_MAP:
+    m = new MFSMap;
+    break;
   case MSG_MDS_BEACON:
     m = new MMDSBeacon;
     break;
diff --git a/src/msg/Message.h b/src/msg/Message.h
index a79dbaa..25b0372 100644
--- a/src/msg/Message.h
+++ b/src/msg/Message.h
@@ -116,6 +116,8 @@
 
 #define MSG_OSD_REPOP         112
 #define MSG_OSD_REPOPREPLY    113
+#define MSG_OSD_PG_UPDATE_LOG_MISSING  114
+#define MSG_OSD_PG_UPDATE_LOG_MISSING_REPLY  115
 
 
 // *** MDS ***
diff --git a/src/msg/Messenger.cc b/src/msg/Messenger.cc
index 1cf6761..0fec5f3 100644
--- a/src/msg/Messenger.cc
+++ b/src/msg/Messenger.cc
@@ -1,6 +1,7 @@
 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
 // vim: ts=8 sw=2 smarttab
 
+#include <thread>
 #include "include/types.h"
 #include "Messenger.h"
 
@@ -23,9 +24,11 @@ Messenger *Messenger::create(CephContext *cct, const string &type,
 			     uint64_t nonce, uint64_t features)
 {
   int r = -1;
-  srand(time(NULL));
-  if (type == "random")
-    r = rand() % 2; // random does not include xio
+  if (type == "random") {
+    thread_local unsigned seed = (unsigned) time(nullptr) +
+      (unsigned) std::hash<std::thread::id>()(std::this_thread::get_id());
+    r = rand_r(&seed) % 2; // random does not include xio
+  }
   if (r == 0 || type == "simple")
     return new SimpleMessenger(cct, name, lname, nonce, features);
   else if ((r == 1 || type == "async") &&
@@ -37,7 +40,7 @@ Messenger *Messenger::create(CephContext *cct, const string &type,
     return new XioMessenger(cct, name, lname, nonce, features);
 #endif
   lderr(cct) << "unrecognized ms_type '" << type << "'" << dendl;
-  return NULL;
+  return nullptr;
 }
 
 /*
diff --git a/src/msg/async/AsyncConnection.cc b/src/msg/async/AsyncConnection.cc
index 9398e91..561d9f5 100644
--- a/src/msg/async/AsyncConnection.cc
+++ b/src/msg/async/AsyncConnection.cc
@@ -45,6 +45,7 @@ ostream& AsyncConnection::_conn_prefix(std::ostream *_dout) {
 // 1. Don't dispatch any event when closed! It may cause AsyncConnection alive even if AsyncMessenger dead
 
 const int AsyncConnection::TCP_PREFETCH_MIN_SIZE = 512;
+const int ASYNC_COALESCE_THRESHOLD = 256;
 
 class C_time_wakeup : public EventCallback {
   AsyncConnectionRef conn;
@@ -344,13 +345,8 @@ ssize_t AsyncConnection::do_sendmsg(struct msghdr &msg, unsigned len, bool more)
 
 // return the remaining bytes, it may larger than the length of ptr
 // else return < 0 means error
-ssize_t AsyncConnection::_try_send(bufferlist &send_bl, bool send, bool more)
+ssize_t AsyncConnection::_try_send(bool send, bool more)
 {
-  ldout(async_msgr->cct, 20) << __func__ << " send bl length is " << send_bl.length() << dendl;
-  if (send_bl.length()) {
-    outcoming_bl.claim_append(send_bl);
-  }
-
   if (!send)
     return 0;
 
@@ -366,7 +362,7 @@ ssize_t AsyncConnection::_try_send(bufferlist &send_bl, bool send, bool more)
   uint64_t left_pbrs = outcoming_bl.buffers().size();
   while (left_pbrs) {
     struct msghdr msg;
-    uint64_t size = MIN(left_pbrs, IOV_MAX);
+    uint64_t size = MIN(left_pbrs, ASYNC_IOV_MAX);
     left_pbrs -= size;
     memset(&msg, 0, sizeof(msg));
     msg.msg_iovlen = 0;
@@ -398,10 +394,8 @@ ssize_t AsyncConnection::_try_send(bufferlist &send_bl, bool send, bool more)
 
   // trim already sent for outcoming_bl
   if (sent_bytes) {
-    bufferlist bl;
     if (sent_bytes < outcoming_bl.length()) {
-      outcoming_bl.splice(sent_bytes, outcoming_bl.length()-sent_bytes, &bl);
-      bl.swap(outcoming_bl);
+      outcoming_bl.splice(0, sent_bytes);
     } else {
       outcoming_bl.clear();
     }
@@ -468,7 +462,7 @@ ssize_t AsyncConnection::read_until(unsigned len, char *p)
       r = read_bulk(sd, p+state_offset, left);
       ldout(async_msgr->cct, 25) << __func__ << " read_bulk left is " << left << " got " << r << dendl;
       if (r < 0) {
-        ldout(async_msgr->cct, 1) << __func__ << " read failed, state is " << get_state_name(state) << dendl;
+        ldout(async_msgr->cct, 1) << __func__ << " read failed" << dendl;
         return -1;
       } else if (r == static_cast<int>(left)) {
         state_offset = 0;
@@ -483,7 +477,7 @@ ssize_t AsyncConnection::read_until(unsigned len, char *p)
       ldout(async_msgr->cct, 25) << __func__ << " read_bulk recv_end is " << recv_end
                                  << " left is " << left << " got " << r << dendl;
       if (r < 0) {
-        ldout(async_msgr->cct, 1) << __func__ << " read failed, state is " << get_state_name(state) << dendl;
+        ldout(async_msgr->cct, 1) << __func__ << " read failed" << dendl;
         return -1;
       }
       recv_end += r;
@@ -500,8 +494,7 @@ ssize_t AsyncConnection::read_until(unsigned len, char *p)
     recv_end = recv_start = 0;
   }
   ldout(async_msgr->cct, 25) << __func__ << " need len " << len << " remaining "
-                             << len - state_offset << " bytes, state is "
-                             << get_state_name(state) << dendl;
+                             << len - state_offset << " bytes" << dendl;
   return len - state_offset;
 }
 
@@ -512,8 +505,7 @@ void AsyncConnection::process()
   bool already_dispatch_writer = false;
   Mutex::Locker l(lock);
   do {
-    ldout(async_msgr->cct, 20) << __func__ << " state is " << get_state_name(state)
-                               << ", prev state is " << get_state_name(prev_state) << dendl;
+    ldout(async_msgr->cct, 20) << __func__ << " prev state is " << get_state_name(prev_state) << dendl;
     prev_state = state;
     switch (state) {
       case STATE_OPEN:
@@ -521,8 +513,7 @@ void AsyncConnection::process()
           char tag = -1;
           r = read_until(sizeof(tag), &tag);
           if (r < 0) {
-            ldout(async_msgr->cct, 1) << __func__ << " read tag failed, state is "
-                                      << get_state_name(state) << dendl;
+            ldout(async_msgr->cct, 1) << __func__ << " read tag failed" << dendl;
             goto fail;
           } else if (r > 0) {
             break;
@@ -1521,13 +1512,15 @@ ssize_t AsyncConnection::_process_connection()
         memset(&connect_msg, 0, sizeof(connect_msg));
         write_lock.Lock();
         can_write = CANWRITE;
+        if (is_queued())
+          center->dispatch_event_external(write_handler);
         write_lock.Unlock();
         break;
       }
 
     default:
       {
-        lderr(async_msgr->cct) << __func__ << " bad state: " << get_state_name(state) << dendl;
+        lderr(async_msgr->cct) << __func__ << " bad state: " << state << dendl;
         assert(0);
       }
   }
@@ -1588,10 +1581,6 @@ int AsyncConnection::handle_connect_reply(ceph_msg_connect &connect, ceph_msg_co
   }
   if (reply.tag == CEPH_MSGR_TAG_WAIT) {
     ldout(async_msgr->cct, 3) << __func__ << " connect got WAIT (connection race)" << dendl;
-    if (!once_ready) {
-      ldout(async_msgr->cct, 1) << __func__ << " got WAIT while connection isn't registered, just closed." << dendl;
-      goto fail;
-    }
     state = STATE_WAIT;
   }
 
@@ -1682,8 +1671,7 @@ ssize_t AsyncConnection::handle_connect_msg(ceph_msg_connect &connect, bufferlis
 
   lock.Lock();
   if (state != STATE_ACCEPTING_WAIT_CONNECT_MSG_AUTH) {
-    ldout(async_msgr->cct, 1) << __func__ << " state changed while accept, it must be mark_down, state="
-                              << get_state_name(state) << dendl;
+    ldout(async_msgr->cct, 1) << __func__ << " state changed while accept, it must be mark_down" << dendl;
     assert(state == STATE_CLOSED);
     goto fail;
   }
@@ -1697,7 +1685,7 @@ ssize_t AsyncConnection::handle_connect_msg(ceph_msg_connect &connect, bufferlis
 
     if (existing->replacing || existing->state == STATE_CLOSED) {
       ldout(async_msgr->cct, 1) << __func__ << " existing racing replace or mark_down happened while replacing."
-                                << " state=" << get_state_name(existing->state) << dendl;
+                                << " existing_state=" << get_state_name(existing->state) << dendl;
       reply.global_seq = existing->peer_global_seq;
       r = _reply_accept(CEPH_MSGR_TAG_RETRY_GLOBAL, connect, reply, authorizer_reply);
       existing->lock.Unlock();
@@ -1727,7 +1715,7 @@ ssize_t AsyncConnection::handle_connect_msg(ceph_msg_connect &connect, bufferlis
     }
 
     ldout(async_msgr->cct, 0) << __func__ << " accept connect_seq " << connect.connect_seq
-                              << " vs existing csq=" << existing->connect_seq << " state="
+                              << " vs existing csq=" << existing->connect_seq << " existing_state="
                               << get_state_name(existing->state) << dendl;
 
     if (connect.connect_seq == 0 && existing->connect_seq > 0) {
@@ -1945,8 +1933,7 @@ ssize_t AsyncConnection::handle_connect_msg(ceph_msg_connect &connect, bufferlis
     goto fail_registered;
   }
   if (state != STATE_ACCEPTING_WAIT_CONNECT_MSG_AUTH) {
-    ldout(async_msgr->cct, 1) << __func__ << " state changed while accept_conn, it must be mark_down, state="
-                              << get_state_name(state) << dendl;
+    ldout(async_msgr->cct, 1) << __func__ << " state changed while accept_conn, it must be mark_down" << dendl;
     assert(state == STATE_CLOSED);
     goto fail_registered;
   }
@@ -2061,7 +2048,7 @@ int AsyncConnection::send_message(Message *m)
     if (!can_fast_prepare)
       prepare_send_message(get_features(), m, bl);
     logger->inc(l_msgr_send_messages_inline);
-    if (write_message(m, bl) < 0) {
+    if (write_message(m, bl, false) < 0) {
       ldout(async_msgr->cct, 1) << __func__ << " send msg failed" << dendl;
       // we want to handle fault within internal thread
       center->dispatch_event_external(write_handler);
@@ -2158,7 +2145,7 @@ int AsyncConnection::randomize_out_seq()
 void AsyncConnection::fault()
 {
   if (state == STATE_CLOSED) {
-    ldout(async_msgr->cct, 10) << __func__ << " state is already " << get_state_name(state) << dendl;
+    ldout(async_msgr->cct, 10) << __func__ << " connection is already closed" << dendl;
     return ;
   }
 
@@ -2189,8 +2176,7 @@ void AsyncConnection::fault()
   if (!once_ready && !is_queued() &&
       state >=STATE_ACCEPTING && state <= STATE_ACCEPTING_WAIT_CONNECT_MSG_AUTH) {
     ldout(async_msgr->cct, 0) << __func__ << " with nothing to send and in the half "
-                              << " accept state just closed, state="
-                              << get_state_name(state) << dendl;
+                              << " accept state just closed" << dendl;
     center->dispatch_event_external(reset_handler);
 
     write_lock.Unlock();
@@ -2305,7 +2291,7 @@ void AsyncConnection::prepare_send_message(uint64_t features, Message *m, buffer
   bl.append(m->get_data());
 }
 
-ssize_t AsyncConnection::write_message(Message *m, bufferlist& bl)
+ssize_t AsyncConnection::write_message(Message *m, bufferlist& bl, bool more)
 {
   assert(can_write == CANWRITE);
   m->set_seq(out_seq.inc());
@@ -2316,7 +2302,8 @@ ssize_t AsyncConnection::write_message(Message *m, bufferlist& bl)
     m->get();
   }
 
-  m->calc_header_crc();
+  if (msgr->crcflags & MSG_CRC_HEADER)
+    m->calc_header_crc();
 
   ceph_msg_header& header = m->get_header();
   ceph_msg_footer& footer = m->get_footer();
@@ -2338,14 +2325,13 @@ ssize_t AsyncConnection::write_message(Message *m, bufferlist& bl)
                                  << "): sig = " << footer.sig << dendl;
     }
   }
+  
+  unsigned original_bl_len = outcoming_bl.length();
 
-  bufferlist complete_bl;
-  // send tag
-  char tag = CEPH_MSGR_TAG_MSG;
-  complete_bl.append(&tag, sizeof(tag));
+  outcoming_bl.append(CEPH_MSGR_TAG_MSG);
 
   if (has_feature(CEPH_FEATURE_NOSRCADDR)) {
-    complete_bl.append((char*)&header, sizeof(header));
+    outcoming_bl.append((char*)&header, sizeof(header));
   } else {
     ceph_msg_header_old oldheader;
     memcpy(&oldheader, &header, sizeof(header));
@@ -2355,7 +2341,7 @@ ssize_t AsyncConnection::write_message(Message *m, bufferlist& bl)
     oldheader.reserved = header.reserved;
     oldheader.crc = ceph_crc32c(0, (unsigned char*)&oldheader,
                                 sizeof(oldheader) - sizeof(oldheader.crc));
-    complete_bl.append((char*)&oldheader, sizeof(oldheader));
+    outcoming_bl.append((char*)&oldheader, sizeof(oldheader));
   }
 
   ldout(async_msgr->cct, 20) << __func__ << " sending message type=" << header.type
@@ -2364,12 +2350,19 @@ ssize_t AsyncConnection::write_message(Message *m, bufferlist& bl)
                              << " data=" << header.data_len
                              << " off " << header.data_off << dendl;
 
-  complete_bl.claim_append(bl);
+  if ((bl.length() <= ASYNC_COALESCE_THRESHOLD) && (bl.buffers().size() > 1)) {
+    std::list<buffer::ptr>::const_iterator pb;
+    for (pb = bl.buffers().begin(); pb != bl.buffers().end(); ++pb) {
+      outcoming_bl.append((char*)pb->c_str(), pb->length());
+    }
+  } else {
+    outcoming_bl.claim_append(bl);  
+  }
 
   // send footer; if receiver doesn't support signatures, use the old footer format
   ceph_msg_footer_old old_footer;
   if (has_feature(CEPH_FEATURE_MSG_AUTH)) {
-    complete_bl.append((char*)&footer, sizeof(footer));
+    outcoming_bl.append((char*)&footer, sizeof(footer));
   } else {
     if (msgr->crcflags & MSG_CRC_HEADER) {
       old_footer.front_crc = footer.front_crc;
@@ -2380,13 +2373,13 @@ ssize_t AsyncConnection::write_message(Message *m, bufferlist& bl)
     }
     old_footer.data_crc = msgr->crcflags & MSG_CRC_DATA ? footer.data_crc : 0;
     old_footer.flags = footer.flags;
-    complete_bl.append((char*)&old_footer, sizeof(old_footer));
+    outcoming_bl.append((char*)&old_footer, sizeof(old_footer));
   }
 
-  logger->inc(l_msgr_send_bytes, complete_bl.length());
+  logger->inc(l_msgr_send_bytes, outcoming_bl.length() - original_bl_len);
   ldout(async_msgr->cct, 20) << __func__ << " sending " << m->get_seq()
                              << " " << m << dendl;
-  ssize_t rc = _try_send(complete_bl);
+  ssize_t rc = _try_send(true, more);
   if (rc < 0) {
     ldout(async_msgr->cct, 1) << __func__ << " error sending " << m << ", "
                               << cpp_strerror(errno) << dendl;
@@ -2435,33 +2428,29 @@ void AsyncConnection::mark_down()
 void AsyncConnection::_send_keepalive_or_ack(bool ack, utime_t *tp)
 {
   assert(write_lock.is_locked());
-  bufferlist bl;
 
-  utime_t t = ceph_clock_now(async_msgr->cct);
-  struct ceph_timespec ts;
-  t.encode_timeval(&ts);
   if (ack) {
     assert(tp);
+    struct ceph_timespec ts;
     tp->encode_timeval(&ts);
-    bl.append(CEPH_MSGR_TAG_KEEPALIVE2_ACK);
-    bl.append((char*)&ts, sizeof(ts));
+    outcoming_bl.append(CEPH_MSGR_TAG_KEEPALIVE2_ACK);
+    outcoming_bl.append((char*)&ts, sizeof(ts));
   } else if (has_feature(CEPH_FEATURE_MSGR_KEEPALIVE2)) {
     struct ceph_timespec ts;
+    utime_t t = ceph_clock_now(async_msgr->cct);
     t.encode_timeval(&ts);
-    bl.append(CEPH_MSGR_TAG_KEEPALIVE2);
-    bl.append((char*)&ts, sizeof(ts));
+    outcoming_bl.append(CEPH_MSGR_TAG_KEEPALIVE2);
+    outcoming_bl.append((char*)&ts, sizeof(ts));
   } else {
-    bl.append(CEPH_MSGR_TAG_KEEPALIVE);
+    outcoming_bl.append(CEPH_MSGR_TAG_KEEPALIVE);
   }
 
   ldout(async_msgr->cct, 10) << __func__ << " try send keepalive or ack" << dendl;
-  _try_send(bl, false, true);
 }
 
 void AsyncConnection::handle_write()
 {
   ldout(async_msgr->cct, 10) << __func__ << " started." << dendl;
-  bufferlist bl;
   ssize_t r = 0;
 
   write_lock.Lock();
@@ -2481,7 +2470,7 @@ void AsyncConnection::handle_write()
       if (!data.length())
         prepare_send_message(get_features(), m, data);
 
-      r = write_message(m, data);
+      r = write_message(m, data, _has_next_outgoing());
       if (r < 0) {
         ldout(async_msgr->cct, 1) << __func__ << " send msg failed" << dendl;
         write_lock.Unlock();
@@ -2495,13 +2484,14 @@ void AsyncConnection::handle_write()
     if (left) {
       ceph_le64 s;
       s = in_seq.read();
-      bl.append(CEPH_MSGR_TAG_ACK);
-      bl.append((char*)&s, sizeof(s));
+      outcoming_bl.append(CEPH_MSGR_TAG_ACK);
+      outcoming_bl.append((char*)&s, sizeof(s));
       ldout(async_msgr->cct, 10) << __func__ << " try send msg ack, acked " << left << " messages" << dendl;
       ack_left.sub(left);
-      r = _try_send(bl, true, true);
+      left = ack_left.read();
+      r = _try_send(true, left);
     } else if (is_queued()) {
-      r = _try_send(bl);
+      r = _try_send();
     }
 
     write_lock.Unlock();
@@ -2514,11 +2504,10 @@ void AsyncConnection::handle_write()
     lock.Lock();
     write_lock.Lock();
     if (state == STATE_STANDBY && !policy.server && is_queued()) {
-      ldout(async_msgr->cct, 10) << __func__ << " state is " << get_state_name(state)
-                                 << " policy.server is false" << dendl;
+      ldout(async_msgr->cct, 10) << __func__ << " policy.server is false" << dendl;
       _connect();
     } else if (sd >= 0 && state != STATE_CONNECTING && state != STATE_CONNECTING_RE && state != STATE_CLOSED) {
-      r = _try_send(bl);
+      r = _try_send();
       if (r < 0) {
         ldout(async_msgr->cct, 1) << __func__ << " send outcoming bl failed" << dendl;
         write_lock.Unlock();
diff --git a/src/msg/async/AsyncConnection.h b/src/msg/async/AsyncConnection.h
index 049c2af..4a76a7c 100644
--- a/src/msg/async/AsyncConnection.h
+++ b/src/msg/async/AsyncConnection.h
@@ -36,6 +36,8 @@ using namespace std;
 
 class AsyncMessenger;
 
+static const int ASYNC_IOV_MAX = (IOV_MAX >= 1024 ? IOV_MAX / 4 : IOV_MAX);
+
 /*
  * AsyncConnection maintains a logic session between two endpoints. In other
  * word, a pair of addresses can find the only AsyncConnection. AsyncConnection
@@ -51,11 +53,12 @@ class AsyncConnection : public Connection {
   ssize_t do_sendmsg(struct msghdr &msg, unsigned len, bool more);
   ssize_t try_send(bufferlist &bl, bool send=true, bool more=false) {
     Mutex::Locker l(write_lock);
-    return _try_send(bl, send, more);
+    outcoming_bl.claim_append(bl);
+    return _try_send(send, more);
   }
   // if "send" is false, it will only append bl to send buffer
   // the main usage is avoid error happen outside messenger threads
-  ssize_t _try_send(bufferlist &bl, bool send=true, bool more=false);
+  ssize_t _try_send(bool send=true, bool more=false);
   ssize_t _send(Message *m);
   void prepare_send_message(uint64_t features, Message *m, bufferlist &bl);
   ssize_t read_until(unsigned needed, char *p);
@@ -72,7 +75,7 @@ class AsyncConnection : public Connection {
   int randomize_out_seq();
   void handle_ack(uint64_t seq);
   void _send_keepalive_or_ack(bool ack=false, utime_t *t=NULL);
-  ssize_t write_message(Message *m, bufferlist& bl);
+  ssize_t write_message(Message *m, bufferlist& bl, bool more);
   ssize_t _reply_accept(char tag, ceph_msg_connect &connect, ceph_msg_connect_reply &reply,
                     bufferlist &authorizer_reply) {
     bufferlist reply_bl;
@@ -115,6 +118,10 @@ class AsyncConnection : public Connection {
     }
     return m;
   }
+  bool _has_next_outgoing() {
+    assert(write_lock.is_locked());
+    return !out_q.empty();
+  }
 
  public:
   AsyncConnection(CephContext *cct, AsyncMessenger *m, EventCenter *c, PerfCounters *p);
@@ -254,7 +261,7 @@ class AsyncConnection : public Connection {
   EventCallbackRef connect_handler;
   EventCallbackRef local_deliver_handler;
   EventCallbackRef wakeup_handler;
-  struct iovec msgvec[IOV_MAX];
+  struct iovec msgvec[ASYNC_IOV_MAX];
   char *recv_buf;
   uint32_t recv_max_prefetch;
   uint32_t recv_start;
diff --git a/src/msg/async/AsyncMessenger.cc b/src/msg/async/AsyncMessenger.cc
index b54db4e..c12ee8e 100644
--- a/src/msg/async/AsyncMessenger.cc
+++ b/src/msg/async/AsyncMessenger.cc
@@ -85,7 +85,7 @@ int Processor::bind(const entity_addr_t &bind_addr, const set<int>& avoid_ports)
   if (r < 0) {
     ::close(listen_sd);
     listen_sd = -1;
-    return -errno;
+    return r;
   }
 
   net.set_socket_options(listen_sd);
@@ -140,6 +140,7 @@ int Processor::bind(const entity_addr_t &bind_addr, const set<int>& avoid_ports)
                          << "-" << msgr->cct->_conf->ms_bind_port_max << ": "
                          << cpp_strerror(errno) << dendl;
         r = -errno;
+        listen_addr.set_port(0); // Clear port before retry, otherwise we shall fail again.
         continue;
       }
       ldout(msgr->cct, 10) << __func__ << " bound on random port " << listen_addr << dendl;
@@ -377,7 +378,7 @@ AsyncMessenger::AsyncMessenger(CephContext *cct, entity_name_t name,
   : SimplePolicyMessenger(cct, name,mname, _nonce),
     processor(this, cct, _nonce),
     lock("AsyncMessenger::lock"),
-    nonce(_nonce), need_addr(true), listen_sd(-1), did_bind(false),
+    nonce(_nonce), need_addr(true), did_bind(false),
     global_seq(0), deleted_lock("AsyncMessenger::deleted_lock"),
     cluster_protocol(0), stopped(true)
 {
diff --git a/src/msg/async/AsyncMessenger.h b/src/msg/async/AsyncMessenger.h
index deea67c..3c7aa0a 100644
--- a/src/msg/async/AsyncMessenger.h
+++ b/src/msg/async/AsyncMessenger.h
@@ -78,8 +78,8 @@ class Worker : public Thread {
     plb.add_u64_counter(l_msgr_send_messages_inline, "msgr_send_messages_inline", "Network sent inline messages");
     plb.add_u64_counter(l_msgr_recv_bytes, "msgr_recv_bytes", "Network received bytes");
     plb.add_u64_counter(l_msgr_send_bytes, "msgr_send_bytes", "Network received bytes");
-    plb.add_u64_counter(l_msgr_created_connections, "msgr_active_connections", "Active connection number");
-    plb.add_u64_counter(l_msgr_active_connections, "msgr_created_connections", "Created connection number");
+    plb.add_u64_counter(l_msgr_created_connections, "msgr_created_connections", "Created connection number");
+    plb.add_u64_counter(l_msgr_active_connections, "msgr_active_connections", "Active connection number");
 
     perf_logger = plb.create_perf_counters();
     cct->get_perfcounters_collection()->add(perf_logger);
@@ -358,7 +358,6 @@ private:
    *  the only writers.
    */
 
-  int listen_sd;
   /**
    *  false; set to true if the AsyncMessenger bound to a specific address;
    *  and set false again by Accepter::stop().
diff --git a/src/msg/async/Event.cc b/src/msg/async/Event.cc
index 00abef4..f242fe7 100644
--- a/src/msg/async/Event.cc
+++ b/src/msg/async/Event.cc
@@ -41,10 +41,9 @@ class C_handle_notify : public EventCallback {
   C_handle_notify(EventCenter *c, CephContext *cc): center(c), cct(cc) {}
   void do_request(int fd_or_id) {
     char c[256];
-    int r;
     do {
       center->already_wakeup.set(0);
-      r = read(fd_or_id, c, sizeof(c));
+      int r = read(fd_or_id, c, sizeof(c));
       if (r < 0) {
         ldout(cct, 1) << __func__ << " read notify pipe failed: " << cpp_strerror(errno) << dendl;
         break;
@@ -92,40 +91,51 @@ int EventCenter::init(int n)
   int fds[2];
   if (pipe(fds) < 0) {
     lderr(cct) << __func__ << " can't create notify pipe" << dendl;
-    return -1;
+    return -errno;
   }
 
   notify_receive_fd = fds[0];
   notify_send_fd = fds[1];
   r = net.set_nonblock(notify_receive_fd);
   if (r < 0) {
-    return -1;
+    return r;
   }
   r = net.set_nonblock(notify_send_fd);
   if (r < 0) {
-    return -1;
+    return r;
   }
 
-  file_events = static_cast<FileEvent *>(malloc(sizeof(FileEvent)*n));
-  memset(file_events, 0, sizeof(FileEvent)*n);
-
+  file_events.resize(n);
   nevent = n;
-  create_file_event(notify_receive_fd, EVENT_READABLE, EventCallbackRef(new C_handle_notify(this, cct)));
+  notify_handler = new C_handle_notify(this, cct),
+  r = create_file_event(notify_receive_fd, EVENT_READABLE, notify_handler);
+  if (r < 0)
+    return r;
   return 0;
 }
 
 EventCenter::~EventCenter()
 {
+  {
+    Mutex::Locker l(external_lock);
+    while (!external_events.empty()) {
+      EventCallbackRef e = external_events.front();
+      if (e)
+        e->do_request(0);
+      external_events.pop_front();
+    }
+  }
+  assert(time_events.empty());
+
   if (notify_receive_fd >= 0) {
     delete_file_event(notify_receive_fd, EVENT_READABLE);
     ::close(notify_receive_fd);
   }
   if (notify_send_fd >= 0)
     ::close(notify_send_fd);
-    
+
   delete driver;
-  if (file_events)
-    free(file_events);
+  delete notify_handler;
 }
 
 
@@ -148,13 +158,7 @@ int EventCenter::create_file_event(int fd, int mask, EventCallbackRef ctxt)
       lderr(cct) << __func__ << " event count is exceed." << dendl;
       return -ERANGE;
     }
-    FileEvent *new_events = static_cast<FileEvent *>(realloc(file_events, sizeof(FileEvent)*new_size));
-    if (!new_events) {
-      lderr(cct) << __func__ << " failed to realloc file_events" << cpp_strerror(errno) << dendl;
-      return -errno;
-    }
-    file_events = new_events;
-    memset(file_events+nevent, 0, sizeof(FileEvent)*(new_size-nevent));
+    file_events.resize(new_size);
     nevent = new_size;
   }
 
@@ -299,13 +303,9 @@ int EventCenter::process_time_events()
    * events to be processed ASAP when this happens: the idea is that
    * processing events earlier is less dangerous than delaying them
    * indefinitely, and practice suggests it is. */
+  bool clock_skewed = false;
   if (now < last_time) {
-    map<utime_t, list<TimeEvent> > changed;
-    for (map<utime_t, list<TimeEvent> >::iterator it = time_events.begin();
-         it != time_events.end(); ++it) {
-      changed[utime_t()].swap(it->second);
-    }
-    time_events.swap(changed);
+    clock_skewed = true;
   }
   last_time = now;
 
@@ -314,7 +314,7 @@ int EventCenter::process_time_events()
   for (map<utime_t, list<TimeEvent> >::iterator it = time_events.begin();
        it != time_events.end(); ) {
     prev = it;
-    if (cur >= it->first) {
+    if (cur >= it->first || clock_skewed) {
       need_process.splice(need_process.end(), it->second);
       ++it;
       time_events.erase(prev);
diff --git a/src/msg/async/Event.h b/src/msg/async/Event.h
index 526f8b3..126a36c 100644
--- a/src/msg/async/Event.h
+++ b/src/msg/async/Event.h
@@ -89,14 +89,14 @@ class EventCenter {
     int mask;
     EventCallbackRef read_cb;
     EventCallbackRef write_cb;
-    FileEvent(): mask(0) {}
+    FileEvent(): mask(0), read_cb(NULL), write_cb(NULL) {}
   };
 
   struct TimeEvent {
     uint64_t id;
     EventCallbackRef time_cb;
 
-    TimeEvent(): id(0) {}
+    TimeEvent(): id(0), time_cb(NULL) {}
   };
 
   CephContext *cct;
@@ -105,7 +105,7 @@ class EventCenter {
   Mutex external_lock, file_lock, time_lock;
   atomic_t external_num_events;
   deque<EventCallbackRef> external_events;
-  FileEvent *file_events;
+  vector<FileEvent> file_events;
   EventDriver *driver;
   map<utime_t, list<TimeEvent> > time_events;
   uint64_t time_event_next_id;
@@ -115,14 +115,12 @@ class EventCenter {
   int notify_send_fd;
   NetHandler net;
   pthread_t owner;
+  EventCallbackRef notify_handler;
 
   int process_time_events();
   FileEvent *_get_file_event(int fd) {
     assert(fd < nevent);
-    FileEvent *p = &file_events[fd];
-    if (!p->mask)
-      new(p) FileEvent();
-    return p;
+    return &file_events[fd];
   }
 
  public:
@@ -134,9 +132,10 @@ class EventCenter {
     file_lock("AsyncMessenger::file_lock"),
     time_lock("AsyncMessenger::time_lock"),
     external_num_events(0),
-    file_events(NULL),
     driver(NULL), time_event_next_id(1),
-    notify_receive_fd(-1), notify_send_fd(-1), net(c), owner(0), already_wakeup(0) {
+    notify_receive_fd(-1), notify_send_fd(-1), net(c), owner(0),
+    notify_handler(NULL),
+    already_wakeup(0) {
     last_time = time(NULL);
   }
   ~EventCenter();
diff --git a/src/msg/async/EventEpoll.cc b/src/msg/async/EventEpoll.cc
index fe6e54d..86e8c9a 100644
--- a/src/msg/async/EventEpoll.cc
+++ b/src/msg/async/EventEpoll.cc
@@ -26,9 +26,8 @@ int EpollDriver::init(int nevent)
 {
   events = (struct epoll_event*)malloc(sizeof(struct epoll_event)*nevent);
   if (!events) {
-    lderr(cct) << __func__ << " unable to malloc memory: "
-                           << cpp_strerror(errno) << dendl;
-    return -errno;
+    lderr(cct) << __func__ << " unable to malloc memory. " << dendl;
+    return -ENOMEM;
   }
   memset(events, 0, sizeof(struct epoll_event)*nevent);
 
@@ -88,7 +87,7 @@ int EpollDriver::del_event(int fd, int cur_mask, int delmask)
     if ((r = epoll_ctl(epfd, EPOLL_CTL_MOD, fd, &ee)) < 0) {
       lderr(cct) << __func__ << " epoll_ctl: modify fd=" << fd << " mask=" << mask
                  << " failed." << cpp_strerror(errno) << dendl;
-      return r;
+      return -errno;
     }
   } else {
     /* Note, Kernel < 2.6.9 requires a non null event pointer even for
@@ -96,7 +95,7 @@ int EpollDriver::del_event(int fd, int cur_mask, int delmask)
     if ((r = epoll_ctl(epfd, EPOLL_CTL_DEL, fd, &ee)) < 0) {
       lderr(cct) << __func__ << " epoll_ctl: delete fd=" << fd
                  << " failed." << cpp_strerror(errno) << dendl;
-      return r;
+      return -errno;
     }
   }
   return 0;
diff --git a/src/msg/async/EventKqueue.cc b/src/msg/async/EventKqueue.cc
index c357a92..54fef5f 100644
--- a/src/msg/async/EventKqueue.cc
+++ b/src/msg/async/EventKqueue.cc
@@ -69,14 +69,13 @@ int KqueueDriver::del_event(int fd, int cur_mask, int delmask)
 {
   ldout(cct, 20) << __func__ << " del event fd=" << fd << " cur mask=" << cur_mask
                  << " delmask=" << delmask << dendl;
-  struct kevent ee;
   struct kevent ke;
   int filter = 0;
-  int r = 0;
   filter |= (delmask & EVENT_READABLE) ? EVFILT_READ : 0;
   filter |= (delmask & EVENT_WRITABLE) ? EVFILT_WRITE : 0;
 
   if (filter) {
+    int r = 0;
     EV_SET(&ke, fd, filter, EV_DELETE, 0, 0, NULL);
     if ((r = kevent(kqfd, &ke, 1, NULL, 0, NULL)) < 0) {
       lderr(cct) << __func__ << " kevent: delete fd=" << fd << " mask=" << filter
diff --git a/src/msg/simple/DispatchQueue.cc b/src/msg/simple/DispatchQueue.cc
index 6f7495e..fed198e 100644
--- a/src/msg/simple/DispatchQueue.cc
+++ b/src/msg/simple/DispatchQueue.cc
@@ -123,16 +123,7 @@ void DispatchQueue::run_local_delivery()
     if (can_fast_dispatch(m)) {
       fast_dispatch(m);
     } else {
-      Mutex::Locker l(lock);
-      add_arrival(m);
-      if (priority >= CEPH_MSG_PRIO_LOW) {
-        mqueue.enqueue_strict(
-            0, priority, QueueItem(m));
-      } else {
-        mqueue.enqueue(
-            0, priority, m->get_cost(), QueueItem(m));
-      }
-      cond.Signal();
+      enqueue(m, priority, 0);
     }
     local_delivery_lock.Lock();
   }
diff --git a/src/msg/simple/Pipe.cc b/src/msg/simple/Pipe.cc
index 9bfa230..f6eee33 100644
--- a/src/msg/simple/Pipe.cc
+++ b/src/msg/simple/Pipe.cc
@@ -2372,7 +2372,7 @@ int Pipe::write_message(const ceph_msg_header& header, const ceph_msg_footer& fo
 	     << " writing " << donow 
 	     << dendl;
     
-    if (msg.msg_iovlen >= IOV_MAX-2) {
+    if (msg.msg_iovlen >= SM_IOV_MAX-2) {
       if (do_sendmsg(&msg, msglen, true))
 	goto fail;
       
diff --git a/src/msg/simple/Pipe.h b/src/msg/simple/Pipe.h
index 664f733..d9e346c 100644
--- a/src/msg/simple/Pipe.h
+++ b/src/msg/simple/Pipe.h
@@ -27,6 +27,8 @@ class SimpleMessenger;
 class IncomingQueue;
 class DispatchQueue;
 
+static const int SM_IOV_MAX = (IOV_MAX >= 1024 ? IOV_MAX / 4 : IOV_MAX);
+
   /**
    * The Pipe is the most complex SimpleMessenger component. It gets
    * two threads, one each for reading and writing on a socket it's handed
@@ -175,7 +177,7 @@ class DispatchQueue;
 
   private:
     int sd;
-    struct iovec msgvec[IOV_MAX];
+    struct iovec msgvec[SM_IOV_MAX];
 #if !defined(MSG_NOSIGNAL) && !defined(SO_NOSIGPIPE)
     sigset_t sigpipe_mask;
     bool sigpipe_pending;
diff --git a/src/msg/xio/XioConnection.cc b/src/msg/xio/XioConnection.cc
index 2f59091..40069fa 100644
--- a/src/msg/xio/XioConnection.cc
+++ b/src/msg/xio/XioConnection.cc
@@ -17,7 +17,7 @@
 #include "XioConnection.h"
 #include "XioMessenger.h"
 #include "messages/MDataPing.h"
-
+#include "msg/msg_types.h"
 #include "auth/none/AuthNoneProtocol.h" // XXX
 
 #include "include/assert.h"
@@ -93,9 +93,7 @@ XioConnection::XioConnection(XioMessenger *m, XioConnection::type _type,
   cstate(this)
 {
   pthread_spin_init(&sp, PTHREAD_PROCESS_PRIVATE);
-  if (xio_conn_type == XioConnection::ACTIVE)
-    peer_addr = peer.addr;
-  peer_type = peer.name.type();
+  set_peer_type(peer.name.type());
   set_peer_addr(peer.addr);
 
   Messenger::Policy policy;
@@ -398,7 +396,7 @@ int XioConnection::on_msg_req(struct xio_session *session,
       peer_type = hdr.peer_type;
       peer_addr = hdr.addr;
       peer.addr = peer_addr;
-      peer.name = hdr.hdr->src;
+      peer.name = entity_name_t(hdr.hdr->src);
       if (xio_conn_type == XioConnection::PASSIVE) {
 	/* XXX kick off feature/authn/authz negotiation
 	 * nb:  very possibly the active side should initiate this, but
@@ -605,8 +603,7 @@ int XioConnection::_mark_down(uint32_t flags)
   if (cstate.policy.resetcheck)
     cstate.flags |= CState::FLAG_RESET;
 
-  // Accelio disconnect
-  xio_disconnect(conn);
+  disconnect();
 
   /* XXX this will almost certainly be called again from
    * on_disconnect_event() */
@@ -685,8 +682,7 @@ int XioConnection::CState::state_fail(Message* m, uint32_t flags)
   xcon->discard_input_queue(flags|OP_FLAG_LOCKED);
   xcon->adjust_clru(flags|OP_FLAG_LOCKED|OP_FLAG_LRU);
 
-  // Accelio disconnect
-  xio_disconnect(xcon->conn);
+  xcon->disconnect();
 
   if (! (flags & OP_FLAG_LOCKED))
     pthread_spin_unlock(&xcon->sp);
diff --git a/src/msg/xio/XioConnection.h b/src/msg/xio/XioConnection.h
index 845d4ab..383f57f 100644
--- a/src/msg/xio/XioConnection.h
+++ b/src/msg/xio/XioConnection.h
@@ -96,7 +96,9 @@ private:
     uint32_t in_seq, out_seq_acked; // atomic<uint64_t>, got receipt
     atomic_t out_seq; // atomic<uint32_t>
 
-    lifecycle() : state(lifecycle::INIT), in_seq(0), out_seq(0) {}
+    lifecycle() : state(lifecycle::INIT), reconnects(0), connect_seq(0),
+		  peer_global_seq(0), in_seq(0), out_seq_acked(0), 
+		  out_seq(0) {}
 
     void set_in_seq(uint32_t seq) {
       in_seq = seq;
@@ -143,11 +145,18 @@ private:
     uint32_t flags;
 
     explicit CState(XioConnection* _xcon)
-      : xcon(_xcon),
+      : features(0),
+	authorizer(NULL),
+	xcon(_xcon),
 	protocol_version(0),
 	session_state(INIT),
 	startup_state(IDLE),
+	reconnects(0),
+	connect_seq(0),
+	global_seq(0),
+	peer_global_seq(0),
 	in_seq(0),
+	out_seq_acked(0),
 	out_seq(0),
 	flags(FLAG_NONE) {}
 
diff --git a/src/msg/xio/XioMessenger.cc b/src/msg/xio/XioMessenger.cc
index a920f7e..b320867 100644
--- a/src/msg/xio/XioMessenger.cc
+++ b/src/msg/xio/XioMessenger.cc
@@ -693,38 +693,13 @@ xio_place_buffers(buffer::list& bl, XioMsg *xmsg, struct xio_msg*& req,
 
 int XioMessenger::bind(const entity_addr_t& addr)
 {
-  const entity_addr_t *a = &addr;
-  struct entity_addr_t _addr = *a;
-
-  if (a->is_blank_ip()) {
-    a = &_addr;
-    std::vector <std::string> my_sections;
-    cct->_conf->get_my_sections(my_sections);
-    std::string rdma_local_str;
-    if (cct->_conf->get_val_from_conf_file(my_sections, "rdma local",
-				      rdma_local_str, true) == 0) {
-      struct entity_addr_t local_rdma_addr;
-      local_rdma_addr = *a;
-      const char *ep;
-      if (!local_rdma_addr.parse(rdma_local_str.c_str(), &ep)) {
-	ldout(cct,0) << "ERROR:  Cannot parse rdma local: " << rdma_local_str << dendl;
-	return -EINVAL;
-      }
-      if (*ep) {
-	ldout(cct,0) << "WARNING: 'rdma local trailing garbage ignored: '" << ep << dendl;
-      }
-      ldout(cct, 2) << "Found rdma_local address " << rdma_local_str.c_str() << dendl;
-      int p = _addr.get_port();
-      _addr.set_sockaddr(reinterpret_cast<struct sockaddr *>(
-			  &local_rdma_addr.ss_addr()));
-      _addr.set_port(p);
-    } else {
-      ldout(cct,0) << "WARNING: need 'rdma local' config for remote use!" <<dendl;
-    }
+  if (addr.is_blank_ip()) {
+      lderr(cct) << "ERROR: need rdma ip for remote use! " << dendl;
+      cout << "Error: xio bind failed. public/cluster ip not specified" << std::endl;
+      return -1;
   }
 
-  entity_addr_t shift_addr = *a;
-
+  entity_addr_t shift_addr = addr;
   string base_uri = xio_uri_from_entity(cct->_conf->xio_transport_type,
 					shift_addr, false /* want_port */);
   ldout(cct,4) << "XioMessenger " << this << " bind: xio_uri "
@@ -736,6 +711,7 @@ int XioMessenger::bind(const entity_addr_t& addr)
     shift_addr.set_port(port0);
     shift_addr.nonce = nonce;
     set_myaddr(shift_addr);
+    need_addr = false;
     did_bind = true;
   }
   return r;
@@ -1003,7 +979,6 @@ ConnectionRef XioMessenger::get_connection(const entity_inst_t& dest)
       delete xcon;
       return NULL;
     }
-    nsessions.inc();
 
     /* this should cause callbacks with user context of conn, but
      * we can always set it explicitly */
@@ -1017,7 +992,15 @@ ConnectionRef XioMessenger::get_connection(const entity_inst_t& dest)
       .out_addr          = NULL,
       .conn_user_context = xcon
     };
+
     xcon->conn = xio_connect(&xcp);
+    if (!xcon->conn) {
+      xio_session_destroy(xcon->session);
+      delete xcon;
+      return NULL;
+    }
+
+    nsessions.inc();
     xcon->connected.set(true);
 
     /* sentinel ref */
diff --git a/src/msg/xio/XioMessenger.h b/src/msg/xio/XioMessenger.h
index d6bb5b5..81ecef1 100644
--- a/src/msg/xio/XioMessenger.h
+++ b/src/msg/xio/XioMessenger.h
@@ -69,8 +69,6 @@ public:
   int _send_message(Message *m, Connection *con);
   int _send_message_impl(Message *m, XioConnection *xcon);
 
-  uint32_t get_magic() { return magic; }
-  void set_magic(int _magic) { magic = _magic; }
   uint32_t get_special_handling() { return special_handling; }
   void set_special_handling(int n) { special_handling = n; }
   int pool_hint(uint32_t size);
diff --git a/src/msg/xio/XioPortal.cc b/src/msg/xio/XioPortal.cc
index 6c00659..c158764 100644
--- a/src/msg/xio/XioPortal.cc
+++ b/src/msg/xio/XioPortal.cc
@@ -76,8 +76,10 @@ int XioPortals::bind(struct xio_session_ops *ops, const string& base_uri,
       // try ports within the configured range
       for (; port_min <= port_max; port_min++) {
         r = portals[i]->bind(ops, base_uri, port_min, &result_port);
-        if (r == 0)
+        if (r == 0) {
+          port_min++;
           break;
+        }
       }
       if (r != 0) {
         lderr(msgr->cct) << "portal.bind unable to bind to " << base_uri
diff --git a/src/msg/xio/XioPortal.h b/src/msg/xio/XioPortal.h
index 3bbc31b..04e16d2 100644
--- a/src/msg/xio/XioPortal.h
+++ b/src/msg/xio/XioPortal.h
@@ -16,6 +16,8 @@
 #ifndef XIO_PORTAL_H
 #define XIO_PORTAL_H
 
+#include <string>
+
 extern "C" {
 #include "libxio.h"
 }
@@ -427,8 +429,10 @@ public:
     }
 
     for (p_ix = 0; p_ix < nportals; ++p_ix) {
+      string thread_name = "ms_xio_";
+      thread_name.append(std::to_string(p_ix));
       portal = portals[p_ix];
-      portal->create(portal->portal_id);
+      portal->create(thread_name.c_str());
     }
   }
 
diff --git a/src/objclass/class_api.cc b/src/objclass/class_api.cc
index a3c065c..1dd05c2 100644
--- a/src/objclass/class_api.cc
+++ b/src/objclass/class_api.cc
@@ -242,6 +242,31 @@ int cls_cxx_stat(cls_method_context_t hctx, uint64_t *size, time_t *mtime)
   return 0;
 }
 
+int cls_cxx_stat2(cls_method_context_t hctx, uint64_t *size, ceph::real_time *mtime)
+{
+  ReplicatedPG::OpContext **pctx = (ReplicatedPG::OpContext **)hctx;
+  vector<OSDOp> ops(1);
+  int ret;
+  ops[0].op.op = CEPH_OSD_OP_STAT;
+  ret = (*pctx)->pg->do_osd_ops(*pctx, ops);
+  if (ret < 0)
+    return ret;
+  bufferlist::iterator iter = ops[0].outdata.begin();
+  real_time ut;
+  uint64_t s;
+  try {
+    ::decode(s, iter);
+    ::decode(ut, iter);
+  } catch (buffer::error& err) {
+    return -EIO;
+  }
+  if (size)
+    *size = s;
+  if (mtime)
+    *mtime = ut;
+  return 0;
+}
+
 int cls_cxx_read(cls_method_context_t hctx, int ofs, int len, bufferlist *outbl)
 {
   ReplicatedPG::OpContext **pctx = (ReplicatedPG::OpContext **)hctx;
diff --git a/src/objclass/objclass.h b/src/objclass/objclass.h
index 0b4e538..08a9d23 100644
--- a/src/objclass/objclass.h
+++ b/src/objclass/objclass.h
@@ -9,6 +9,7 @@
 #include "../include/types.h"
 #include "msg/msg_types.h"
 #include "common/hobject.h"
+#include "common/ceph_time.h"
 
 extern "C" {
 #endif
@@ -142,6 +143,7 @@ extern int cls_register_cxx_filter(cls_handle_t hclass,
 extern int cls_cxx_create(cls_method_context_t hctx, bool exclusive);
 extern int cls_cxx_remove(cls_method_context_t hctx);
 extern int cls_cxx_stat(cls_method_context_t hctx, uint64_t *size, time_t *mtime);
+extern int cls_cxx_stat2(cls_method_context_t hctx, uint64_t *size, ceph::real_time *mtime);
 extern int cls_cxx_read(cls_method_context_t hctx, int ofs, int len, bufferlist *bl);
 extern int cls_cxx_write(cls_method_context_t hctx, int ofs, int len, bufferlist *bl);
 extern int cls_cxx_write_full(cls_method_context_t hctx, bufferlist *bl);
diff --git a/src/ocf/Makefile.in b/src/ocf/Makefile.in
index 85811bc..af674b0 100644
--- a/src/ocf/Makefile.in
+++ b/src/ocf/Makefile.in
@@ -1,7 +1,7 @@
-# Makefile.in generated by automake 1.15 from Makefile.am.
+# Makefile.in generated by automake 1.14.1 from Makefile.am.
 # @configure_input@
 
-# Copyright (C) 1994-2014 Free Software Foundation, Inc.
+# Copyright (C) 1994-2013 Free Software Foundation, Inc.
 
 # This Makefile.in is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -15,17 +15,7 @@
 @SET_MAKE@
 
 VPATH = @srcdir@
-am__is_gnu_make = { \
-  if test -z '$(MAKELEVEL)'; then \
-    false; \
-  elif test -n '$(MAKE_HOST)'; then \
-    true; \
-  elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
-    true; \
-  else \
-    false; \
-  fi; \
-}
+am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
 am__make_running_with_option = \
   case $${target_option-} in \
       ?) ;; \
@@ -90,6 +80,8 @@ build_triplet = @build@
 host_triplet = @host@
 target_triplet = @target@
 subdir = src/ocf
+DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
+	$(srcdir)/ceph.in $(srcdir)/rbd.in
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
 am__aclocal_m4_deps = $(top_srcdir)/m4/ac_check_classpath.m4 \
 	$(top_srcdir)/m4/ac_prog_jar.m4 \
@@ -108,7 +100,6 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/ac_check_classpath.m4 \
 	$(top_srcdir)/m4/pkg.m4 $(top_srcdir)/configure.ac
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
 	$(ACLOCAL_M4)
-DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON)
 mkinstalldirs = $(install_sh) -d
 CONFIG_HEADER = $(top_builddir)/src/acconfig.h
 CONFIG_CLEAN_FILES = ceph rbd
@@ -162,8 +153,6 @@ am__can_run_installinfo = \
     *) (install-info --version) >/dev/null 2>&1;; \
   esac
 am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
-am__DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/ceph.in \
-	$(srcdir)/rbd.in
 DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
 ACLOCAL = @ACLOCAL@
 AMTAR = @AMTAR@
@@ -256,7 +245,6 @@ LN_S = @LN_S@
 LTLIBOBJS = @LTLIBOBJS@
 LTTNG_GEN_TP_CHECK = @LTTNG_GEN_TP_CHECK@
 LTTNG_GEN_TP_PROG = @LTTNG_GEN_TP_PROG@
-LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
 MAKEINFO = @MAKEINFO@
 MANIFEST_TOOL = @MANIFEST_TOOL@
 MKDIR_P = @MKDIR_P@
@@ -283,7 +271,10 @@ PTHREAD_CC = @PTHREAD_CC@
 PTHREAD_CFLAGS = @PTHREAD_CFLAGS@
 PTHREAD_LIBS = @PTHREAD_LIBS@
 PYTHON = @PYTHON@
+PYTHON_CFLAGS = @PYTHON_CFLAGS@
+PYTHON_CONFIG_CHECK = @PYTHON_CONFIG_CHECK@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
+PYTHON_LDFLAGS = @PYTHON_LDFLAGS@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
 PYTHON_PREFIX = @PYTHON_PREFIX@
 PYTHON_VERSION = @PYTHON_VERSION@
@@ -352,7 +343,6 @@ program_transform_name = @program_transform_name@
 psdir = @psdir@
 pyexecdir = @pyexecdir@
 pythondir = @pythondir@
-runstatedir = @runstatedir@
 sbindir = @sbindir@
 sharedstatedir = @sharedstatedir@
 srcdir = @srcdir@
@@ -392,6 +382,7 @@ $(srcdir)/Makefile.in:  $(srcdir)/Makefile.am  $(am__configure_deps)
 	echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign src/ocf/Makefile'; \
 	$(am__cd) $(top_srcdir) && \
 	  $(AUTOMAKE) --foreign src/ocf/Makefile
+.PRECIOUS: Makefile
 Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
 	@case '$?' in \
 	  *config.status*) \
@@ -613,8 +604,6 @@ uninstall-am: uninstall-raSCRIPTS
 	mostlyclean-libtool pdf pdf-am ps ps-am tags-am uninstall \
 	uninstall-am uninstall-hook uninstall-raSCRIPTS
 
-.PRECIOUS: Makefile
-
 
 @WITH_OCF_TRUE at install-data-hook:
 @WITH_OCF_TRUE@	$(LN_S) ceph $(DESTDIR)$(radir)/osd
diff --git a/src/os/Makefile.am b/src/os/Makefile.am
index 41b33d2..6d22778 100644
--- a/src/os/Makefile.am
+++ b/src/os/Makefile.am
@@ -17,6 +17,7 @@ libos_a_SOURCES = \
 	os/filestore/DBObjectMap.cc \
 	os/filestore/FileJournal.cc \
 	os/filestore/FileStore.cc \
+	os/filestore/JournalThrottle.cc \
 	os/filestore/GenericFileStoreBackend.cc \
 	os/filestore/HashIndex.cc \
 	os/filestore/IndexManager.cc \
@@ -75,6 +76,7 @@ noinst_HEADERS += \
 	os/filestore/DBObjectMap.h \
 	os/filestore/FileJournal.h \
 	os/filestore/FileStore.h \
+	os/filestore/JournalThrottle.h \
 	os/filestore/FDCache.h \
 	os/filestore/GenericFileStoreBackend.h \
 	os/filestore/HashIndex.h \
diff --git a/src/os/ObjectStore.cc b/src/os/ObjectStore.cc
index ba638bf..f319e76 100644
--- a/src/os/ObjectStore.cc
+++ b/src/os/ObjectStore.cc
@@ -177,7 +177,7 @@ int ObjectStore::queue_transactions(
   Context *oncomplete,
   TrackedOpRef op = TrackedOpRef())
 {
-  RunOnDeleteRef _complete(new RunOnDelete(oncomplete));
+  RunOnDeleteRef _complete (std::make_shared<RunOnDelete>(oncomplete));
   Context *_onreadable = new Wrapper<RunOnDeleteRef>(
     onreadable, _complete);
   Context *_oncommit = new Wrapper<RunOnDeleteRef>(
diff --git a/src/os/ObjectStore.h b/src/os/ObjectStore.h
index b0b9524..fba6b76 100644
--- a/src/os/ObjectStore.h
+++ b/src/os/ObjectStore.h
@@ -47,11 +47,9 @@ namespace ceph {
 
 enum {
   l_os_first = 84000,
-  l_os_jq_max_ops,
   l_os_jq_ops,
-  l_os_j_ops,
-  l_os_jq_max_bytes,
   l_os_jq_bytes,
+  l_os_j_ops,
   l_os_j_bytes,
   l_os_j_lat,
   l_os_j_wr,
@@ -408,6 +406,8 @@ public:
 
       OP_SETALLOCHINT = 39,  // cid, oid, object_size, write_size
       OP_COLL_HINT = 40, // cid, type, bl
+
+      OP_TRY_RENAME = 41,   // oldcid, oldoid, newoid
     };
 
     // Transaction hint type
@@ -579,7 +579,7 @@ public:
     }
     void register_on_complete(Context *c) {
       if (!c) return;
-      RunOnDeleteRef _complete(new RunOnDelete(c));
+      RunOnDeleteRef _complete (std::make_shared<RunOnDelete>(c));
       register_on_applied(new ContainerContext<RunOnDeleteRef>(_complete));
       register_on_commit(new ContainerContext<RunOnDeleteRef>(_complete));
     }
@@ -808,7 +808,37 @@ public:
         return 1 + 8 + 8 + 4 + 4 + 4 + 4 + 4 + tbl.length();
       else {
         //layout: data_bl + op_bl + coll_index + object_index + data
-        //TODO: maybe we need better way to get encoded bytes;
+
+        // coll_index size, object_index size and sizeof(transaction_data)
+        // all here, so they may be computed at compile-time
+        size_t final_size = sizeof(__u32) * 2 + sizeof(data);
+
+        // coll_index second and object_index second
+        final_size += (coll_index.size() + object_index.size()) * sizeof(__le32);
+
+        // coll_index first
+        for (auto p = coll_index.begin(); p != coll_index.end(); ++p) {
+          final_size += p->first.encoded_size();
+        }
+
+        // object_index first
+        for (auto p = object_index.begin(); p != object_index.end(); ++p) {
+          final_size += p->first.encoded_size();
+        }
+        
+        return data_bl.length() +
+          op_bl.length() +
+          final_size;
+      }
+    }
+
+    /// Retain old version for regression testing purposes
+    uint64_t get_encoded_bytes_test() {
+      if (use_tbl)
+        return 1 + 8 + 8 + 4 + 4 + 4 + 4 + 4 + tbl.length();
+      else {
+        //layout: data_bl + op_bl + coll_index + object_index + data
+
         bufferlist bl;
         ::encode(coll_index, bl);
         ::encode(object_index, bl);
@@ -1415,13 +1445,30 @@ public:
       }
       data.ops++;
     }
+    void try_rename(coll_t cid, const ghobject_t& oldoid,
+                    const ghobject_t& oid) {
+      if (use_tbl) {
+        __u32 op = OP_TRY_RENAME;
+        ::encode(op, tbl);
+        ::encode(cid, tbl);
+        ::encode(oldoid, tbl);
+        ::encode(oid, tbl);
+      } else {
+        Op* _op = _get_next_op();
+        _op->op = OP_TRY_RENAME;
+        _op->cid = _get_coll_id(cid);
+        _op->oid = _get_object_id(oldoid);
+        _op->dest_oid = _get_object_id(oid);
+      }
+      data.ops++;
+    }
 
     // NOTE: Collection attr operations are all DEPRECATED.  new
     // backends need not implement these at all.
 
     /// Set an xattr on a collection
-    void collection_setattr(const coll_t& cid, const string& name, bufferlist& val)
-      __attribute__ ((deprecated)) {
+    void collection_setattr(const coll_t& cid, const string& name,
+			    bufferlist& val) {
       if (use_tbl) {
         __u32 op = OP_COLL_SETATTR;
         ::encode(op, tbl);
@@ -1439,8 +1486,7 @@ public:
     }
 
     /// Remove an xattr from a collection
-    void collection_rmattr(const coll_t& cid, const string& name)
-      __attribute__ ((deprecated)) {
+    void collection_rmattr(const coll_t& cid, const string& name) {
       if (use_tbl) {
         __u32 op = OP_COLL_RMATTR;
         ::encode(op, tbl);
@@ -1455,8 +1501,7 @@ public:
       data.ops++;
     }
     /// Set multiple xattrs on a collection
-    void collection_setattrs(const coll_t& cid, map<string,bufferptr>& aset)
-      __attribute__ ((deprecated)) {
+    void collection_setattrs(const coll_t& cid, map<string,bufferptr>& aset) {
       if (use_tbl) {
         __u32 op = OP_COLL_SETATTRS;
         ::encode(op, tbl);
@@ -1471,8 +1516,7 @@ public:
       data.ops++;
     }
     /// Set multiple xattrs on a collection
-    void collection_setattrs(const coll_t& cid, map<string,bufferlist>& aset)
-      __attribute__ ((deprecated)) {
+    void collection_setattrs(const coll_t& cid, map<string,bufferlist>& aset) {
       if (use_tbl) {
         __u32 op = OP_COLL_SETATTRS;
         ::encode(op, tbl);
@@ -2161,8 +2205,7 @@ public:
    * @returns 0 on success, negative error code on failure
    */
   virtual int collection_getattr(const coll_t& cid, const char *name,
-	                         void *value, size_t size)
-    __attribute__ ((deprecated)) {
+	                         void *value, size_t size) {
     return -EOPNOTSUPP;
   }
 
@@ -2174,8 +2217,8 @@ public:
    * @param bl buffer to receive value
    * @returns 0 on success, negative error code on failure
    */
-  virtual int collection_getattr(const coll_t& cid, const char *name, bufferlist& bl)
-    __attribute__ ((deprecated)) {
+  virtual int collection_getattr(const coll_t& cid, const char *name,
+				 bufferlist& bl) {
     return -EOPNOTSUPP;
   }
 
@@ -2186,8 +2229,8 @@ public:
    * @param aset map of keys and buffers that contain the values
    * @returns 0 on success, negative error code on failure
    */
-  virtual int collection_getattrs(const coll_t& cid, map<string,bufferptr> &aset)
-    __attribute__ ((deprecated)) {
+  virtual int collection_getattrs(const coll_t& cid,
+				  map<string,bufferptr> &aset) {
     return -EOPNOTSUPP;
   }
 
diff --git a/src/os/Transaction.cc b/src/os/Transaction.cc
index dc8b1ab..a72ab7c 100644
--- a/src/os/Transaction.cc
+++ b/src/os/Transaction.cc
@@ -323,6 +323,20 @@ void ObjectStore::Transaction::_build_actions_from_tbl()
       }
       break;
 
+    case Transaction::OP_TRY_RENAME:
+      {
+	coll_t cid;
+	ghobject_t oldoid;
+	ghobject_t newoid;
+
+	::decode(cid, p);
+	::decode(oldoid, p);
+	::decode(newoid, p);
+
+	try_rename(cid, oldoid, newoid);
+      }
+      break;
+
     case Transaction::OP_COLL_SETATTR:
       {
 	coll_t cid;
diff --git a/src/os/bluestore/BlockDevice.cc b/src/os/bluestore/BlockDevice.cc
index ac17b64..829b47e 100644
--- a/src/os/bluestore/BlockDevice.cc
+++ b/src/os/bluestore/BlockDevice.cc
@@ -14,6 +14,7 @@
  *
  */
 
+#include <libgen.h>
 #include <unistd.h>
 
 #include "KernelDevice.h"
@@ -29,26 +30,28 @@
 
 void IOContext::aio_wait()
 {
-  Mutex::Locker l(lock);
+  std::unique_lock<std::mutex> l(lock);
   // see _aio_thread for waker logic
-  num_waiting.inc();
-  while (num_running.read() > 0 || num_reading.read() > 0) {
+  ++num_waiting;
+  while (num_running.load() > 0 || num_reading.load() > 0) {
     dout(10) << __func__ << " " << this
-	     << " waiting for " << num_running.read() << " aios and/or "
-	     << num_reading.read() << " readers to complete" << dendl;
-    cond.Wait(lock);
+	     << " waiting for " << num_running.load() << " aios and/or "
+	     << num_reading.load() << " readers to complete" << dendl;
+    cond.wait(l);
   }
-  num_waiting.dec();
+  --num_waiting;
   dout(20) << __func__ << " " << this << " done" << dendl;
 }
 
 BlockDevice *BlockDevice::create(const string& path, aio_callback_t cb, void *cbpriv)
 {
   string type = "kernel";
-  char buf[10];
+  char buf[PATH_MAX];
   int r = ::readlink(path.c_str(), buf, sizeof(buf));
-  if (r >= 0 && strncmp(buf, SPDK_PREFIX, sizeof(SPDK_PREFIX)-1) == 0) {
-    type = "ust-nvme";
+  if (r >= 0) {
+    char *bname = ::basename(buf);
+    if (strncmp(bname, SPDK_PREFIX, sizeof(SPDK_PREFIX)-1) == 0)
+      type = "ust-nvme";
   }
   dout(1) << __func__ << " path " << path << " type " << type << dendl;
 
@@ -68,21 +71,21 @@ BlockDevice *BlockDevice::create(const string& path, aio_callback_t cb, void *cb
 
 void BlockDevice::queue_reap_ioc(IOContext *ioc)
 {
-  Mutex::Locker l(ioc_reap_lock);
-  if (ioc_reap_count.read() == 0)
-    ioc_reap_count.inc();
+  std::lock_guard<std::mutex> l(ioc_reap_lock);
+  if (ioc_reap_count.load() == 0)
+    ++ioc_reap_count;
   ioc_reap_queue.push_back(ioc);
 }
 
 void BlockDevice::reap_ioc()
 {
-  if (ioc_reap_count.read()) {
-    Mutex::Locker l(ioc_reap_lock);
+  if (ioc_reap_count.load()) {
+    std::lock_guard<std::mutex> l(ioc_reap_lock);
     for (auto p : ioc_reap_queue) {
       dout(20) << __func__ << " reap ioc " << p << dendl;
       delete p;
     }
     ioc_reap_queue.clear();
-    ioc_reap_count.dec();
+    --ioc_reap_count;
   }
 }
diff --git a/src/os/bluestore/BlockDevice.h b/src/os/bluestore/BlockDevice.h
index 955f77c..5815d40 100644
--- a/src/os/bluestore/BlockDevice.h
+++ b/src/os/bluestore/BlockDevice.h
@@ -17,6 +17,10 @@
 #ifndef CEPH_OS_BLUESTORE_BLOCKDEVICE_H
 #define CEPH_OS_BLUESTORE_BLOCKDEVICE_H
 
+#include <atomic>
+#include <condition_variable>
+#include <mutex>
+
 #include "acconfig.h"
 #include "os/fs/FS.h"
 
@@ -30,20 +34,18 @@ struct IOContext {
   void *nvme_task_last = nullptr;
 #endif
 
-  Mutex lock;
-  Cond cond;
-  //interval_set<uint64_t> blocks;  ///< blocks with aio in flight
+  std::mutex lock;
+  std::condition_variable cond;
 
   list<FS::aio_t> pending_aios;    ///< not yet submitted
   list<FS::aio_t> running_aios;    ///< submitting or submitted
-  atomic_t num_pending;
-  atomic_t num_running;
-  atomic_t num_reading;
-  atomic_t num_waiting;
+  std::atomic_int num_pending = {0};
+  std::atomic_int num_running = {0};
+  std::atomic_int num_reading = {0};
+  std::atomic_int num_waiting = {0};
 
   explicit IOContext(void *p)
-    : priv(p),
-      lock("IOContext::lock")
+    : priv(p)
     {}
 
   // no copying
@@ -51,22 +53,29 @@ struct IOContext {
   IOContext &operator=(const IOContext& other);
 
   bool has_aios() {
-    Mutex::Locker l(lock);
-    return num_pending.read() || num_running.read();
+    std::lock_guard<std::mutex> l(lock);
+    return num_pending.load() || num_running.load();
   }
 
   void aio_wait();
+
+  void aio_wake() {
+    if (num_waiting.load()) {
+      std::lock_guard<std::mutex> l(lock);
+      cond.notify_all();
+    }
+  }
 };
 
 
 class BlockDevice {
-  Mutex ioc_reap_lock;
+  std::mutex ioc_reap_lock;
   vector<IOContext*> ioc_reap_queue;
-  atomic_t ioc_reap_count;
+  std::atomic_int ioc_reap_count = {0};
 
 public:
-  BlockDevice(): ioc_reap_lock("BlockDevice::ioc_reap_lock") {}
-  virtual ~BlockDevice() {}
+  BlockDevice() = default;
+  virtual ~BlockDevice() = default;
   typedef void (*aio_callback_t)(void *handle, void *aio);
 
   static BlockDevice *create(
diff --git a/src/os/bluestore/BlueFS.cc b/src/os/bluestore/BlueFS.cc
index a79af94..8a9118f 100644
--- a/src/os/bluestore/BlueFS.cc
+++ b/src/os/bluestore/BlueFS.cc
@@ -1045,7 +1045,7 @@ int BlueFS::_flush_range(FileWriter *h, uint64_t offset, uint64_t length)
     x_off = 0;
   }
   for (unsigned i = 0; i < bdev.size(); ++i) {
-    if (h->iocv[i]->num_pending.read()) {
+    if (h->iocv[i]->has_aios()) {
       bdev[i]->aio_submit(h->iocv[i]);
     }
   }
@@ -1307,6 +1307,7 @@ void BlueFS::_close_writer(FileWriter *h)
 {
   dout(10) << __func__ << " " << h << dendl;
   for (unsigned i=0; i<bdev.size(); ++i) {
+    h->iocv[i]->aio_wait();
     bdev[i]->queue_reap_ioc(h->iocv[i]);
   }
   h->iocv.clear();
diff --git a/src/os/bluestore/BlueStore.cc b/src/os/bluestore/BlueStore.cc
index 2643b88..52f9055 100644
--- a/src/os/bluestore/BlueStore.cc
+++ b/src/os/bluestore/BlueStore.cc
@@ -455,8 +455,7 @@ static void get_wal_key(uint64_t seq, string *out)
 
 void BlueStore::Enode::put()
 {
-  int final = --nref;
-  if (final == 0) {
+  if (--nref == 0) {
     dout(20) << __func__ << " removing self from set " << enode_set << dendl;
     enode_set->uset.erase(*this);
     delete this;
@@ -708,9 +707,6 @@ BlueStore::OnodeRef BlueStore::Collection::get_onode(
 
     // new
     on = new Onode(oid, key);
-    on->dirty = true;
-    if (g_conf->bluestore_debug_misc && !create)
-      on->dirty = false;
   } else {
     // loaded
     assert(r >=0);
@@ -744,7 +740,6 @@ BlueStore::BlueStore(CephContext *cct, const string& path)
     bluefs(NULL),
     bluefs_shared_bdev(0),
     db(NULL),
-    fs(NULL),
     bdev(NULL),
     fm(NULL),
     alloc(NULL),
@@ -836,9 +831,6 @@ int BlueStore::_open_path()
 	 << dendl;
     return r;
   }
-  assert(fs == NULL);
-  fs = FS::create_by_fd(path_fd);
-  dout(1) << __func__ << " using fs driver '" << fs->get_name() << "'" << dendl;
   return 0;
 }
 
@@ -846,8 +838,6 @@ void BlueStore::_close_path()
 {
   VOID_TEMP_FAILURE_RETRY(::close(path_fd));
   path_fd = -1;
-  delete fs;
-  fs = NULL;
 }
 
 int BlueStore::_write_bdev_label(string path, bluestore_bdev_label_t label)
@@ -1132,7 +1122,7 @@ int BlueStore::_open_db(bool create)
 
   string kv_backend;
   if (create) {
-    kv_backend = g_conf->bluestore_backend;
+    kv_backend = g_conf->bluestore_kvbackend;
   } else {
     r = read_meta("kv_backend", &kv_backend);
     if (r < 0) {
@@ -1306,16 +1296,18 @@ int BlueStore::_open_db(bool create)
     }
 
     // wal_dir, too!
-    char walfn[PATH_MAX];
-    snprintf(walfn, sizeof(walfn), "%s/db.wal", path.c_str());
-    r = ::mkdir(walfn, 0755);
-    if (r < 0)
-      r = -errno;
-    if (r < 0 && r != -EEXIST) {
-      derr << __func__ << " failed to create " << walfn
-	   << ": " << cpp_strerror(r)
-	   << dendl;
-      return r;
+    if (g_conf->rocksdb_separate_wal_dir) {
+      char walfn[PATH_MAX];
+      snprintf(walfn, sizeof(walfn), "%s/db.wal", path.c_str());
+      r = ::mkdir(walfn, 0755);
+      if (r < 0)
+	r = -errno;
+      if (r < 0 && r != -EEXIST) {
+	derr << __func__ << " failed to create " << walfn
+	  << ": " << cpp_strerror(r)
+	  << dendl;
+	return r;
+      }
     }
   }
 
@@ -1578,17 +1570,19 @@ int BlueStore::_setup_block_symlink_or_file(
   dout(20) << __func__ << " name " << name << " path " << epath
 	   << " size " << size << " create=" << (int)create << dendl;
   int r = 0;
+  int flags = O_RDWR;
+  if (create)
+    flags |= O_CREAT;
   if (epath.length()) {
-    if (!epath.compare(0, sizeof(SPDK_PREFIX-1), SPDK_PREFIX)) {
-      string symbol_spdk_file = path + "/" + epath;
-      r = ::symlinkat(symbol_spdk_file.c_str(), path_fd, name.c_str());
+    if (!epath.compare(0, sizeof(SPDK_PREFIX)-1, SPDK_PREFIX)) {
+      r = ::symlinkat(epath.c_str(), path_fd, name.c_str());
       if (r < 0) {
         r = -errno;
         derr << __func__ << " failed to create " << name << " symlink to "
-    	     << symbol_spdk_file << ": " << cpp_strerror(r) << dendl;
+    	     << epath << ": " << cpp_strerror(r) << dendl;
         return r;
       }
-      int fd = ::openat(path_fd, epath.c_str(), O_RDWR, 0644);
+      int fd = ::openat(path_fd, epath.c_str(), flags, 0644);
       if (fd < 0) {
 	r = -errno;
 	derr << __func__ << " failed to open " << epath << " file: "
@@ -1611,9 +1605,6 @@ int BlueStore::_setup_block_symlink_or_file(
     }
   }
   if (size) {
-    unsigned flags = O_RDWR;
-    if (create)
-      flags |= O_CREAT;
     int fd = ::openat(path_fd, name.c_str(), flags, 0644);
     if (fd >= 0) {
       // block file is present
@@ -1695,7 +1686,7 @@ int BlueStore::mkfs()
     } else {
       dout(1) << __func__ << " using provided fsid " << fsid << dendl;
     }
-    // we'll write it last.
+    // we'll write it later.
   } else {
     if (!fsid.is_zero() && fsid != old_fsid) {
       derr << __func__ << " on-disk fsid " << old_fsid
@@ -1711,16 +1702,18 @@ int BlueStore::mkfs()
 				   g_conf->bluestore_block_create);
   if (r < 0)
     goto out_close_fsid;
-  r = _setup_block_symlink_or_file("block.wal", g_conf->bluestore_block_wal_path,
-				   g_conf->bluestore_block_wal_size,
-				   g_conf->bluestore_block_wal_create);
-  if (r < 0)
-    goto out_close_fsid;
-  r = _setup_block_symlink_or_file("block.db", g_conf->bluestore_block_db_path,
-				   g_conf->bluestore_block_db_size,
-				   g_conf->bluestore_block_db_create);
-  if (r < 0)
-    goto out_close_fsid;
+  if (g_conf->bluestore_bluefs) {
+    r = _setup_block_symlink_or_file("block.wal", g_conf->bluestore_block_wal_path,
+	g_conf->bluestore_block_wal_size,
+	g_conf->bluestore_block_wal_create);
+    if (r < 0)
+      goto out_close_fsid;
+    r = _setup_block_symlink_or_file("block.db", g_conf->bluestore_block_db_path,
+	g_conf->bluestore_block_db_size,
+	g_conf->bluestore_block_db_create);
+    if (r < 0)
+      goto out_close_fsid;
+  }
 
   r = _open_bdev(true);
   if (r < 0)
@@ -1777,7 +1770,7 @@ int BlueStore::mkfs()
     db->submit_transaction_sync(t);
   }
 
-  r = write_meta("kv_backend", g_conf->bluestore_backend);
+  r = write_meta("kv_backend", g_conf->bluestore_kvbackend);
   if (r < 0)
     goto out_close_alloc;
   r = write_meta("bluefs", stringify((int)g_conf->bluestore_bluefs));
@@ -1815,6 +1808,20 @@ int BlueStore::mount()
 {
   dout(1) << __func__ << " path " << path << dendl;
 
+  {
+    string type;
+    int r = read_meta("type", &type);
+    if (r < 0) {
+      derr << __func__ << " failed to load os-type: " << cpp_strerror(r) << dendl;
+      return r;
+    }
+
+    if (type != "bluestore") {
+      derr << __func__ << " expected bluestore, but type is " << type << dendl;
+      return -EIO;
+    }
+  }
+
   if (g_conf->bluestore_fsck_on_mount) {
     int rc = fsck();
     if (rc < 0)
@@ -2335,7 +2342,7 @@ void BlueStore::_sync()
 {
   dout(10) << __func__ << dendl;
 
-  // flush aios in flght
+  // flush aios in flight
   bdev->flush();
 
   std::unique_lock<std::mutex> l(kv_lock);
@@ -2670,7 +2677,6 @@ int BlueStore::_do_read(
     bl.append_zero(x_len);
     offset += x_len;
     length -= x_len;
-    continue;
   }
   r = bl.length();
 
@@ -2782,7 +2788,6 @@ int BlueStore::fiemap(
     }
     offset += x_len;
     len -= x_len;
-    continue;
   }
 
  out:
@@ -3554,17 +3559,20 @@ void BlueStore::_txc_state_proc(TransContext *txc)
       txc->log_state_latency(logger, l_bluestore_state_io_done_lat);
       txc->state = TransContext::STATE_KV_QUEUED;
       if (!g_conf->bluestore_sync_transaction) {
-	std::lock_guard<std::mutex> l(kv_lock);
 	if (g_conf->bluestore_sync_submit_transaction) {
+	  _txc_update_fm(txc);
 	  db->submit_transaction(txc->t);
 	}
+      } else {
+	_txc_update_fm(txc);
+	db->submit_transaction_sync(txc->t);
+      }
+      {
+	std::lock_guard<std::mutex> l(kv_lock);
 	kv_queue.push_back(txc);
 	kv_cond.notify_one();
-	return;
       }
-      db->submit_transaction_sync(txc->t);
-      break;
-
+      return;
     case TransContext::STATE_KV_QUEUED:
       txc->log_state_latency(logger, l_bluestore_state_kv_queued_lat);
       txc->state = TransContext::STATE_KV_DONE;
@@ -3786,6 +3794,43 @@ void BlueStore::_osr_reap_done(OpSequencer *osr)
   }
 }
 
+void BlueStore::_txc_update_fm(TransContext *txc)
+{
+  if (txc->wal_txn)
+    dout(20) << __func__ << " txc " << txc
+      << " allocated " << txc->allocated
+      << " (will release " << txc->released << " after wal)"
+      << dendl;
+  else
+    dout(20) << __func__ << " txc " << txc
+      << " allocated " << txc->allocated
+      << " released " << txc->released
+      << dendl;
+
+  for (interval_set<uint64_t>::iterator p = txc->allocated.begin();
+      p != txc->allocated.end();
+      ++p) {
+    fm->allocate(p.get_start(), p.get_len(), txc->t);
+  }
+
+  if (txc->wal_txn) {
+    txc->wal_txn->released.swap(txc->released);
+    assert(txc->released.empty());
+  } else {
+    for (interval_set<uint64_t>::iterator p = txc->released.begin();
+	p != txc->released.end();
+	++p) {
+      dout(20) << __func__ << " release " << p.get_start()
+	<< "~" << p.get_len() << dendl;
+      fm->release(p.get_start(), p.get_len(), txc->t);
+
+      if (!g_conf->bluestore_debug_no_reuse_blocks)
+	alloc->release(p.get_start(), p.get_len());
+    }
+  }
+}
+
+
 void BlueStore::_kv_sync_thread()
 {
   dout(10) << __func__ << " start" << dendl;
@@ -3816,54 +3861,21 @@ void BlueStore::_kv_sync_thread()
 
       // allocations and deallocations
       interval_set<uint64_t> released;
-      for (std::deque<TransContext *>::iterator it = kv_committing.begin();
-	   it != kv_committing.end();
-	   ++it) {
-	TransContext *txc = *it;
-	if (txc->wal_txn)
-	  dout(20) << __func__ << " txc " << txc
-		   << " allocated " << txc->allocated
-		   << " (will release " << txc->released << " after wal)"
-		   << dendl;
-	else
-	  dout(20) << __func__ << " txc " << *it
-		   << " allocated " << txc->allocated
-		   << " released " << txc->released
-		   << dendl;
-	for (interval_set<uint64_t>::iterator p = txc->allocated.begin();
-	     p != txc->allocated.end();
-	     ++p) {
-	  fm->allocate(p.get_start(), p.get_len(), txc->t);
-	}
-	if (txc->wal_txn) {
-	  txc->wal_txn->released.swap(txc->released);
-	  assert(txc->released.empty());
-	} else {
-	  released.insert(txc->released);
-	  for (interval_set<uint64_t>::iterator p = txc->released.begin();
-	       p != txc->released.end();
-	       ++p) {
-	    dout(20) << __func__ << " release " << p.get_start()
-		     << "~" << p.get_len() << dendl;
-	    fm->release(p.get_start(), p.get_len(), txc->t);
-	  }
-	}
-      }
       for (std::deque<TransContext *>::iterator it = wal_cleaning.begin();
-	   it != wal_cleaning.end();
-	   ++it) {
+	  it != wal_cleaning.end();
+	  ++it) {
 	TransContext *txc = *it;
 	if (!txc->wal_txn->released.empty()) {
 	  dout(20) << __func__ << " txc " << txc
-		   << " (post-wal) released " << txc->wal_txn->released
-		   << dendl;
+	    << " (post-wal) released " << txc->wal_txn->released
+	    << dendl;
 	  released.insert(txc->wal_txn->released);
 	  for (interval_set<uint64_t>::iterator p =
-		 txc->wal_txn->released.begin();
-	       p != txc->wal_txn->released.end();
-	       ++p) {
+	      txc->wal_txn->released.begin();
+	      p != txc->wal_txn->released.end();
+	      ++p) {
 	    dout(20) << __func__ << " release " << p.get_start()
-		     << "~" << p.get_len() << dendl;
+	      << "~" << p.get_len() << dendl;
 	    fm->release(p.get_start(), p.get_len(), t);
 	  }
 	}
@@ -3899,10 +3911,11 @@ void BlueStore::_kv_sync_thread()
       // flush/barrier on block device
       bdev->flush();
 
-      if (!g_conf->bluestore_sync_submit_transaction) {
+      if (!g_conf->bluestore_sync_transaction && !g_conf->bluestore_sync_submit_transaction) {
 	for (std::deque<TransContext *>::iterator it = kv_committing.begin();
 	     it != kv_committing.end();
 	     ++it) {
+	  _txc_update_fm((*it));
 	  db->submit_transaction((*it)->t);
 	}
       }
@@ -4228,7 +4241,7 @@ void BlueStore::_txc_aio_submit(TransContext *txc)
   bdev->aio_submit(&txc->ioc);
 }
 
-int BlueStore::_txc_add_transaction(TransContext *txc, Transaction *t)
+void BlueStore::_txc_add_transaction(TransContext *txc, Transaction *t)
 {
   Transaction::iterator i = t->begin();
 
@@ -4445,7 +4458,10 @@ int BlueStore::_txc_add_transaction(TransContext *txc, Transaction *t)
     case Transaction::OP_CLONE:
       {
         const ghobject_t& noid = i.get_oid(op->dest_oid);
-	OnodeRef no = c->get_onode(noid, true);
+	OnodeRef& no = ovec[op->dest_oid];
+	if (!no) {
+	  no = c->get_onode(noid, true);
+	}
 	r = _clone(txc, c, o, no);
       }
       break;
@@ -4457,7 +4473,10 @@ int BlueStore::_txc_add_transaction(TransContext *txc, Transaction *t)
     case Transaction::OP_CLONERANGE2:
       {
 	const ghobject_t& noid = i.get_oid(op->dest_oid);
-	OnodeRef no = c->get_onode(noid, true);
+	OnodeRef& no = ovec[op->dest_oid];
+	if (!no) {
+	  no = c->get_onode(noid, true);
+	}
         uint64_t srcoff = op->off;
         uint64_t len = op->len;
         uint64_t dstoff = op->dest_off;
@@ -4478,12 +4497,17 @@ int BlueStore::_txc_add_transaction(TransContext *txc, Transaction *t)
       break;
 
     case Transaction::OP_COLL_MOVE_RENAME:
-      {
+    case Transaction::OP_TRY_RENAME:
+    {
 	assert(op->cid == op->dest_cid);
 	const ghobject_t& noid = i.get_oid(op->dest_oid);
-	OnodeRef no = c->get_onode(noid, true);
+	OnodeRef& no = ovec[op->dest_oid];
+	if (!no) {
+	  no = c->get_onode(noid, false);
+	}
 	r = _rename(txc, c, o, no, noid);
-	o.reset();
+	if (r == -ENOENT && op->op == Transaction::OP_TRY_RENAME)
+	  r = 0;
       }
       break;
 
@@ -4581,8 +4605,6 @@ int BlueStore::_txc_add_transaction(TransContext *txc, Transaction *t)
       }
     }
   }
-
-  return 0;
 }
 
 
@@ -4815,11 +4837,11 @@ void BlueStore::_do_read_all_overlays(bluestore_wal_op_t& wo)
   return;
 }
 
-void BlueStore::_dump_onode(OnodeRef o)
+void BlueStore::_dump_onode(OnodeRef o, int log_level)
 {
-  if (!g_conf->subsys.should_gather(ceph_subsys_bluestore, 30))
+  if (!g_conf->subsys.should_gather(ceph_subsys_bluestore, log_level))
     return;
-  dout(30) << __func__ << " " << o
+  dout(log_level) << __func__ << " " << o
 	   << " nid " << o->onode.nid
 	   << " size " << o->onode.size
 	   << " expected_object_size " << o->onode.expected_object_size
@@ -4828,14 +4850,14 @@ void BlueStore::_dump_onode(OnodeRef o)
   for (map<string,bufferptr>::iterator p = o->onode.attrs.begin();
        p != o->onode.attrs.end();
        ++p) {
-    dout(30) << __func__ << "  attr " << p->first
+    dout(log_level) << __func__ << "  attr " << p->first
 	     << " len " << p->second.length() << dendl;
   }
   uint64_t pos = 0;
   for (map<uint64_t,bluestore_extent_t>::iterator p = o->onode.block_map.begin();
        p != o->onode.block_map.end();
        ++p) {
-    dout(30) << __func__ << "  extent " << p->first << " " << p->second
+    dout(log_level) << __func__ << "  extent " << p->first << " " << p->second
 	     << dendl;
     assert(p->first >= pos);
     pos = p->first + p->second.length;
@@ -4844,13 +4866,13 @@ void BlueStore::_dump_onode(OnodeRef o)
   for (map<uint64_t,bluestore_overlay_t>::iterator p = o->onode.overlay_map.begin();
        p != o->onode.overlay_map.end();
        ++p) {
-    dout(30) << __func__ << "  overlay " << p->first << " " << p->second
+    dout(log_level) << __func__ << "  overlay " << p->first << " " << p->second
 	     << dendl;
     assert(p->first >= pos);
     pos = p->first + p->second.length;
   }
   if (!o->onode.overlay_refs.empty()) {
-    dout(30) << __func__ << "  overlay_refs " << o->onode.overlay_refs << dendl;
+    dout(log_level) << __func__ << "  overlay_refs " << o->onode.overlay_refs << dendl;
   }
 }
 
@@ -5045,7 +5067,7 @@ int BlueStore::_do_allocate(
   bool shared_head = false;
   bool shared_tail = false;
   uint64_t orig_end = orig_offset + orig_length;
-  if (orig_offset / min_alloc_size == orig_end / min_alloc_size) {
+  if (orig_offset / min_alloc_size == (orig_end - 1)/ min_alloc_size && (orig_length != min_alloc_size)) {
     // we fall within the same block
     offset = orig_offset - orig_offset % min_alloc_size;
     length = 0;
@@ -5090,21 +5112,23 @@ int BlueStore::_do_allocate(
     }
 
     // include head?
-    bp = o->onode.find_extent(orig_offset);
     if (head) {
       if (allow_overlay && _can_overlay_write(o, head)) {
 	dout(20) << "  head " << head << " will be captured by overlay" << dendl;
-      } else if (bp == o->onode.block_map.end()) {
-	dout(20) << "  head " << head << " not yet allocated" << dendl;
-	offset -= min_alloc_size;
-	length += min_alloc_size;
-      } else if (bp->second.has_flag(bluestore_extent_t::FLAG_SHARED)) {
-	dout(20) << "  head " << head << " shared" << dendl;
-	offset -= min_alloc_size;
-	length += min_alloc_size;
-	shared_head = true;
       } else {
-	dout(20) << "  head " << head << " will presumably WAL" << dendl;
+        bp = o->onode.find_extent(orig_offset);
+        if (bp == o->onode.block_map.end()) {
+          dout(20) << "  head " << head << " not yet allocated" << dendl;
+          offset -= min_alloc_size;
+          length += min_alloc_size;
+        } else if (bp->second.has_flag(bluestore_extent_t::FLAG_SHARED)) {
+          dout(20) << "  head " << head << " shared" << dendl;
+          offset -= min_alloc_size;
+          length += min_alloc_size;
+          shared_head = true;
+        } else {
+          dout(20) << "  head " << head << " will presumably WAL" << dendl;
+        }
       }
     }
   }
@@ -5158,7 +5182,8 @@ int BlueStore::_do_allocate(
     } else {
       dout(20) << "  tail shared, but no COW needed" << dendl;
     }
-    if (cow_offset_raw & ~block_mask) {
+    if (cow_offset_raw < o->onode.size &&
+	(cow_offset_raw & ~block_mask)) {
       *cow_rmw_tail = bp->second.offset + cow_offset_raw - bp->first;
       dout(20) << "  cow_rmw_tail " << *cow_rmw_tail
 	       << " from " << bp->second << dendl;
@@ -5256,32 +5281,24 @@ int BlueStore::_do_allocate(
 			      &e.offset, &e.length);
       assert(r == 0);
       assert(e.length <= length);  // bc length is a multiple of min_alloc_size
-      if (offset == alloc_start) {
-	if (cow_head_op) {
-	  // we set the COW flag to indicate that all or part of this new extent
-	  // will be copied from the previous allocation.
-	  e.flags |= bluestore_extent_t::FLAG_COW_HEAD;
-	}
-	if (cow_head_op) {
-	  cow_head_op->extent.offset = e.offset;
-	  dout(10) << __func__ << "  final head cow op extent "
-		   << cow_head_op->extent << dendl;
-	}
+      if (offset == alloc_start && cow_head_op) {
+        // we set the COW flag to indicate that all or part of this new extent
+        // will be copied from the previous allocation.
+        e.flags |= bluestore_extent_t::FLAG_COW_HEAD;
+        cow_head_op->extent.offset = e.offset;
+        dout(10) << __func__ << "  final head cow op extent "
+                 << cow_head_op->extent << dendl;
       }
-      if (e.length == length) {
-	if (cow_tail_op) {
-	  // we set the COW flag to indicate that all or part of this new extent
-	  // will be copied from the previous allocation.
-	  e.flags |= bluestore_extent_t::FLAG_COW_TAIL;
-	}
-	if (cow_tail_op) {
-	  // extent.offset is the logical object offset
-	  assert(cow_tail_op->extent.offset >= offset);
-	  assert(cow_tail_op->extent.end() <= offset + length);
-	  cow_tail_op->extent.offset += e.offset - offset;
-	  dout(10) << __func__ << "  final tail cow op extent "
-		   << cow_tail_op->extent << dendl;
-	}
+      if (e.length == length && cow_tail_op) {
+        // we set the COW flag to indicate that all or part of this new extent
+        // will be copied from the previous allocation.
+        e.flags |= bluestore_extent_t::FLAG_COW_TAIL;
+        // extent.offset is the logical object offset
+        assert(cow_tail_op->extent.offset >= offset);
+        assert(cow_tail_op->extent.end() <= offset + length);
+        cow_tail_op->extent.offset += e.offset - offset;
+        dout(10) << __func__ << "  final tail cow op extent "
+                 << cow_tail_op->extent << dendl;
       }
       txc->allocated.insert(e.offset, e.length);
       o->onode.block_map[offset] = e;
@@ -5319,7 +5336,6 @@ int BlueStore::_do_write(
 	   << " bytes in " << o->onode.block_map.size()
 	   << " extents" << dendl;
   _dump_onode(o);
-  o->exists = true;
 
   if (orig_length == 0) {
     return 0;
@@ -5531,6 +5547,7 @@ int BlueStore::_do_write(
 	uint64_t x_off = offset - bp->first;
 	dout(20) << __func__ << " write " << offset << "~" << length
 		 << " x_off " << x_off << dendl;
+	_do_overlay_trim(txc, o, offset, length);
 	bdev->aio_write(bp->second.offset + x_off, bl, &txc->ioc, buffered);
 	bp->second.clear_flag(bluestore_extent_t::FLAG_UNWRITTEN);
 	bp->second.clear_flag(bluestore_extent_t::FLAG_COW_HEAD);
@@ -5590,14 +5607,14 @@ int BlueStore::_do_write(
     if (p->second.has_flag(bluestore_extent_t::FLAG_UNWRITTEN)) {
       derr << __func__ << " left behind an unwritten extent, out of sync with "
 	   << "_do_allocate" << dendl;
-      _dump_onode(o);
+      _dump_onode(o, 0);
       assert(0 == "leaked unwritten extent");
     }
     if (p->second.has_flag(bluestore_extent_t::FLAG_COW_HEAD) ||
 	p->second.has_flag(bluestore_extent_t::FLAG_COW_TAIL)) {
       derr << __func__ << " left behind a COW extent, out of sync with "
 	   << "_do_allocate" << dendl;
-      _dump_onode(o);
+      _dump_onode(o, 0);
       assert(0 == "leaked cow extent");
     }
   }
@@ -5616,6 +5633,7 @@ int BlueStore::_write(TransContext *txc,
   dout(15) << __func__ << " " << c->cid << " " << o->oid
 	   << " " << offset << "~" << length
 	   << dendl;
+  o->exists = true;
   _assign_nid(txc, o);
   int r = _do_write(txc, c, o, offset, length, bl, fadvise_flags);
   txc->write_onode(o);
@@ -5811,7 +5829,9 @@ int BlueStore::_do_truncate(
       uint64_t x_off = old_size - bp->first;
       uint64_t x_len = MIN(ROUND_UP_TO(offset, block_size), x_end) - old_size;
       if (bp->second.has_flag(bluestore_extent_t::FLAG_SHARED)) {
-	_do_write_zero(txc, c, o, old_size, x_len);
+        int r = _do_write_zero(txc, c, o, old_size, x_len);
+        if (r < 0)
+          return r;
 	o->onode.size = offset; // we (maybe) just wrote past eof; reset size
       } else {
 	bluestore_wal_op_t *op = _get_wal_op(txc, o);
@@ -5829,7 +5849,9 @@ int BlueStore::_do_truncate(
     if (bp != o->onode.block_map.end()) {
       uint64_t z_len = block_size - offset % block_size;
       if (bp->second.has_flag(bluestore_extent_t::FLAG_SHARED)) {
-	_do_write_zero(txc, c, o, offset, z_len);
+        int r = _do_write_zero(txc, c, o, offset, z_len);
+        if (r < 0)
+          return r;
 	o->onode.size = offset; // we just wrote past eof; reset size
       } else {
 	bluestore_wal_op_t *op = _get_wal_op(txc, o);
@@ -5904,7 +5926,9 @@ int BlueStore::_do_remove(
   CollectionRef& c,
   OnodeRef o)
 {
-  _do_truncate(txc, c, o, 0);
+  int r = _do_truncate(txc, c, o, 0);
+  if (r < 0)
+    return r;
   if (o->onode.omap_head) {
     _do_omap_clear(txc, o->onode.omap_head);
   }
@@ -5975,8 +5999,14 @@ int BlueStore::_rmattr(TransContext *txc,
   dout(15) << __func__ << " " << c->cid << " " << o->oid
 	   << " " << name << dendl;
   int r = 0;
+  map<string, bufferptr>::iterator it = o->onode.attrs.find(name);
+  if (it == o->onode.attrs.end())
+    goto out;
+
   o->onode.attrs.erase(name);
   txc->write_onode(o);
+
+ out:
   dout(10) << __func__ << " " << c->cid << " " << o->oid
 	   << " " << name << " = " << r << dendl;
   return r;
@@ -5988,8 +6018,14 @@ int BlueStore::_rmattrs(TransContext *txc,
 {
   dout(15) << __func__ << " " << c->cid << " " << o->oid << dendl;
   int r = 0;
+
+  if (o->onode.attrs.empty())
+    goto out;
+
   o->onode.attrs.clear();
   txc->write_onode(o);
+
+ out:
   dout(10) << __func__ << " " << c->cid << " " << o->oid << " = " << r << dendl;
   return r;
 }
@@ -6003,7 +6039,8 @@ void BlueStore::_do_omap_clear(TransContext *txc, uint64_t id)
   it->lower_bound(prefix);
   while (it->valid()) {
     if (it->key() >= tail) {
-      dout(30) << __func__ << "  stop at " << tail << dendl;
+      dout(30) << __func__ << "  stop at " << pretty_binary_string(tail)
+	       << dendl;
       break;
     }
     txc->t->rmkey(PREFIX_OMAP, it->key());
@@ -6185,26 +6222,48 @@ int BlueStore::_clone(TransContext *txc,
     goto out;
 
   if (g_conf->bluestore_clone_cow) {
-    EnodeRef e = c->get_enode(newo->oid.hobj.get_hash());
-    bool marked = false;
-    for (auto& p : oldo->onode.block_map) {
-      if (p.second.has_flag(bluestore_extent_t::FLAG_SHARED)) {
-	e->ref_map.get(p.second.offset, p.second.length);
-      } else {
-	p.second.set_flag(bluestore_extent_t::FLAG_SHARED);
-	e->ref_map.add(p.second.offset, p.second.length, 2);
-	marked = true;
+    if (!oldo->onode.block_map.empty()) {
+      EnodeRef e = c->get_enode(newo->oid.hobj.get_hash());
+      bool marked = false;
+      for (auto& p : oldo->onode.block_map) {
+	if (p.second.has_flag(bluestore_extent_t::FLAG_SHARED)) {
+	  e->ref_map.get(p.second.offset, p.second.length);
+	} else {
+	  p.second.set_flag(bluestore_extent_t::FLAG_SHARED);
+	  e->ref_map.add(p.second.offset, p.second.length, 2);
+	  marked = true;
+	}
+      }
+      dout(20) << __func__ << " hash " << std::hex << e->hash << std::dec << " ref_map now "
+	<< e->ref_map << dendl;
+      newo->onode.block_map = oldo->onode.block_map;
+      newo->enode = e;
+      dout(20) << __func__ << " block_map " << newo->onode.block_map << dendl;
+      txc->write_enode(e);
+      if (marked)
+	txc->write_onode(oldo);
+    }
+
+    //don't care _can_overlay_write()
+    for (auto& v : oldo->onode.overlay_map) {
+      string key;
+      bufferlist val;
+      get_overlay_key(oldo->onode.nid, v.second.key, &key);
+      int r  = db->get(PREFIX_OVERLAY, key, &val);
+      if (r < 0) {
+	derr << __func__ << " get oid " << oldo->oid << " overlay value(key=" << v.second.key
+	  << ")" << "failed: " << cpp_strerror(r) << dendl;
+	goto out;
       }
+
+      newo->onode.overlay_map[v.first] = bluestore_overlay_t(++newo->onode.last_overlay_key, 0, v.second.length);
+      dout(20) << __func__ << " added " << v.first << " " << v.second.length << dendl;
+      key.clear();
+      get_overlay_key(newo->onode.nid, newo->onode.last_overlay_key, &key);
+      txc->t->set(PREFIX_OVERLAY, key, val);
     }
-    dout(20) << __func__ << " hash " << e->hash << " ref_map now "
-	     << e->ref_map << dendl;
-    newo->onode.block_map = oldo->onode.block_map;
+
     newo->onode.size = oldo->onode.size;
-    newo->enode = e;
-    dout(20) << __func__ << " block_map " << newo->onode.block_map << dendl;
-    txc->write_enode(e);
-    if (marked)
-      txc->write_onode(oldo);
   } else {
     // read + write
     r = _do_read(oldo, 0, oldo->onode.size, bl, 0);
@@ -6304,18 +6363,19 @@ int BlueStore::_rename(TransContext *txc,
 	   << new_oid << dendl;
   int r;
   ghobject_t old_oid = oldo->oid;
-  bufferlist bl;
-  string old_key, new_key;
 
-  if (newo && newo->exists) {
-    // destination object already exists, remove it first
-    r = _do_remove(txc, c, newo);
-    if (r < 0)
+  if (newo) {
+    if (newo->exists) {
+      r = -EEXIST;
       goto out;
+    }
+    assert(txc->onodes.count(newo) == 0);
   }
 
   txc->t->rmkey(PREFIX_OBJ, oldo->key);
   txc->write_onode(oldo);
+  newo = oldo;
+  oldo.reset(NULL);
   c->onode_map.rename(old_oid, new_oid);  // this adjusts oldo->{oid,key}
   r = 0;
 
@@ -6372,6 +6432,8 @@ int BlueStore::_remove_collection(TransContext *txc, coll_t cid,
     pair<ghobject_t,OnodeRef> next;
     while ((*c)->onode_map.get_next(next.first, &next)) {
       if (next.second->exists) {
+	dout(10) << __func__ << " " << next.first << " " << next.second
+		 << " exists in onode_map" << dendl;
 	r = -ENOTEMPTY;
 	goto out;
       }
diff --git a/src/os/bluestore/BlueStore.h b/src/os/bluestore/BlueStore.h
index 2899c78..ede2b39 100644
--- a/src/os/bluestore/BlueStore.h
+++ b/src/os/bluestore/BlueStore.h
@@ -31,16 +31,10 @@
 #include "include/unordered_map.h"
 #include "include/memory.h"
 #include "common/Finisher.h"
-#include "common/RWLock.h"
-#include "common/WorkQueue.h"
-#include "common/perf_counters.h"
 #include "os/ObjectStore.h"
-#include "os/fs/FS.h"
-#include "kv/KeyValueDB.h"
 
 #include "bluestore_types.h"
 #include "BlockDevice.h"
-
 class Allocator;
 class FreelistManager;
 class BlueFS;
@@ -136,7 +130,6 @@ public:
     EnodeRef enode;  ///< ref to Enode [optional]
 
     bluestore_onode_t onode;  ///< metadata stored as value in kv store
-    bool dirty;     // ???
     bool exists;
 
     std::mutex flush_lock;  ///< protect flush_txns
@@ -150,7 +143,6 @@ public:
       : nref(0),
 	oid(o),
 	key(k),
-	dirty(false),
 	exists(false) {
     }
 
@@ -498,7 +490,6 @@ private:
   BlueFS *bluefs;
   unsigned bluefs_shared_bdev;  ///< which bluefs bdev we are sharing
   KeyValueDB *db;
-  FS *fs;
   BlockDevice *bdev;
   FreelistManager *fm;
   Allocator *alloc;
@@ -582,16 +573,17 @@ private:
 
   void _assign_nid(TransContext *txc, OnodeRef o);
 
-  void _dump_onode(OnodeRef o);
+  void _dump_onode(OnodeRef o, int log_leverl=30);
 
   TransContext *_txc_create(OpSequencer *osr);
   void _txc_release(TransContext *txc, CollectionRef& c, OnodeRef& onode,
 		    uint64_t offset, uint64_t length,
 		    bool shared);
-  int _txc_add_transaction(TransContext *txc, Transaction *t);
+  void _txc_add_transaction(TransContext *txc, Transaction *t);
   int _txc_finalize(OpSequencer *osr, TransContext *txc);
   void _txc_state_proc(TransContext *txc);
   void _txc_aio_submit(TransContext *txc);
+  void _txc_update_fm(TransContext *txc);
 public:
   void _txc_aio_finish(void *p) {
     _txc_state_proc(static_cast<TransContext*>(p));
@@ -627,41 +619,41 @@ public:
   BlueStore(CephContext *cct, const string& path);
   ~BlueStore();
 
-  string get_type() {
+  string get_type() override {
     return "bluestore";
   }
 
-  bool needs_journal() { return false; };
-  bool wants_journal() { return false; };
-  bool allows_journal() { return false; };
+  bool needs_journal() override { return false; };
+  bool wants_journal() override { return false; };
+  bool allows_journal() override { return false; };
 
   static int get_block_device_fsid(const string& path, uuid_d *fsid);
 
-  bool test_mount_in_use();
+  bool test_mount_in_use() override;
 
-  int mount();
-  int umount();
+  int mount() override;
+  int umount() override;
   void _sync();
 
-  int fsck();
+  int fsck() override;
 
-  unsigned get_max_object_name_length() {
+  unsigned get_max_object_name_length() override {
     return 4096;
   }
-  unsigned get_max_attr_name_length() {
+  unsigned get_max_attr_name_length() override {
     return 256;  // arbitrary; there is no real limit internally
   }
 
-  int mkfs();
-  int mkjournal() {
+  int mkfs() override;
+  int mkjournal() override {
     return 0;
   }
 
 public:
-  int statfs(struct statfs *buf);
+  int statfs(struct statfs *buf) override;
 
-  bool exists(const coll_t& cid, const ghobject_t& oid);
-  bool exists(CollectionHandle &c, const ghobject_t& oid);
+  bool exists(const coll_t& cid, const ghobject_t& oid) override;
+  bool exists(CollectionHandle &c, const ghobject_t& oid) override;
   int stat(
     const coll_t& cid,
     const ghobject_t& oid,
@@ -714,9 +706,9 @@ public:
 
   CollectionHandle open_collection(const coll_t &c) override;
 
-  bool collection_exists(const coll_t& c);
-  bool collection_empty(const coll_t& c);
-  int collection_bits(const coll_t& c);
+  bool collection_exists(const coll_t& c) override;
+  bool collection_empty(const coll_t& c) override;
+  int collection_bits(const coll_t& c) override;
 
   int collection_list(const coll_t& cid, ghobject_t start, ghobject_t end,
 		      bool sort_bitwise, int max,
@@ -762,7 +754,7 @@ public:
     CollectionHandle &c,              ///< [in] Collection containing oid
     const ghobject_t &oid, ///< [in] Object containing omap
     set<string> *keys      ///< [out] Keys defined on oid
-    );
+    ) override;
 
   /// Get key values
   int omap_get_values(
@@ -801,14 +793,14 @@ public:
     const ghobject_t &oid  ///< [in] object
     ) override;
 
-  void set_fsid(uuid_d u) {
+  void set_fsid(uuid_d u) override {
     fsid = u;
   }
-  uuid_d get_fsid() {
+  uuid_d get_fsid() override {
     return fsid;
   }
 
-  objectstore_perf_stat_t get_cur_stats() {
+  objectstore_perf_stat_t get_cur_stats() override {
     return objectstore_perf_stat_t();
   }
 
@@ -816,7 +808,7 @@ public:
     Sequencer *osr,
     vector<Transaction>& tls,
     TrackedOpRef op = TrackedOpRef(),
-    ThreadPool::TPHandle *handle = NULL);
+    ThreadPool::TPHandle *handle = NULL) override;
 
 private:
   // --------------------------------------------------------
diff --git a/src/os/bluestore/KernelDevice.cc b/src/os/bluestore/KernelDevice.cc
index b85b473..5c20a45 100644
--- a/src/os/bluestore/KernelDevice.cc
+++ b/src/os/bluestore/KernelDevice.cc
@@ -119,7 +119,17 @@ int KernelDevice::open(string p)
   } else {
     size = st.st_size;
   }
-  block_size = st.st_blksize;
+
+  // Operate as though the block size is 4 KB.  The backing file
+  // blksize doesn't strictly matter except that some file systems may
+  // require a read/modify/write if we write something smaller than
+  // it.
+  block_size = g_conf->bdev_block_size;
+  if (block_size != (unsigned)st.st_blksize) {
+    dout(1) << __func__ << " backing device/file reports st_blksize "
+	    << st.st_blksize << ", using bdev_block_size "
+	    << block_size << " anyway" << dendl;
+  }
 
   fs = FS::create_by_fd(fd_direct);
   assert(fs);
@@ -240,7 +250,7 @@ void KernelDevice::_aio_thread()
       for (int i = 0; i < r; ++i) {
 	IOContext *ioc = static_cast<IOContext*>(aio[i]->priv);
 	_aio_log_finish(ioc, aio[i]->offset, aio[i]->length);
-	int left = ioc->num_running.dec();
+	int left = --ioc->num_running;
 	int r = aio[i]->get_return_value();
 	dout(10) << __func__ << " finished aio " << aio[i] << " r " << r
 		 << " ioc " << ioc
@@ -249,11 +259,7 @@ void KernelDevice::_aio_thread()
 	if (left == 0) {
 	  // check waiting count before doing callback (which may
 	  // destroy this ioc).
-	  if (ioc->num_waiting.read()) {
-	    dout(20) << __func__ << " waking waiter" << dendl;
-	    Mutex::Locker l(ioc->lock);
-	    ioc->cond.Signal();
-	  }
+	  ioc->aio_wake();
 	  if (ioc->priv) {
 	    aio_callback(aio_callback_priv, ioc->priv);
 	  }
@@ -308,8 +314,8 @@ void KernelDevice::_aio_log_finish(
 void KernelDevice::aio_submit(IOContext *ioc)
 {
   dout(20) << __func__ << " ioc " << ioc
-	   << " pending " << ioc->num_pending.read()
-	   << " running " << ioc->num_running.read()
+	   << " pending " << ioc->num_pending.load()
+	   << " running " << ioc->num_running.load()
 	   << dendl;
   // move these aside, and get our end iterator position now, as the
   // aios might complete as soon as they are submitted and queue more
@@ -318,10 +324,10 @@ void KernelDevice::aio_submit(IOContext *ioc)
   ioc->running_aios.splice(e, ioc->pending_aios);
   list<FS::aio_t>::iterator p = ioc->running_aios.begin();
 
-  int pending = ioc->num_pending.read();
-  ioc->num_running.add(pending);
-  ioc->num_pending.sub(pending);
-  assert(ioc->num_pending.read() == 0);  // we should be only thread doing this
+  int pending = ioc->num_pending.load();
+  ioc->num_running += pending;
+  ioc->num_pending -= pending;
+  assert(ioc->num_pending.load() == 0);  // we should be only thread doing this
 
   bool done = false;
   while (!done) {
@@ -367,9 +373,9 @@ int KernelDevice::aio_write(
   assert(off < size);
   assert(off + len <= size);
 
-  if (!bl.is_n_page_sized() || !bl.is_page_aligned()) {
-    dout(20) << __func__ << " rebuilding buffer to be page-aligned" << dendl;
-    bl.rebuild();
+  if (!bl.is_n_align_sized(block_size) || !bl.is_aligned(block_size)) {
+    dout(20) << __func__ << " rebuilding buffer to be aligned" << dendl;
+    bl.rebuild_aligned(block_size);
   }
 
   dout(40) << "data: ";
@@ -381,7 +387,7 @@ int KernelDevice::aio_write(
 #ifdef HAVE_LIBAIO
   if (aio && dio && !buffered) {
     ioc->pending_aios.push_back(FS::aio_t(ioc, fd_direct));
-    ioc->num_pending.inc();
+    ++ioc->num_pending;
     FS::aio_t& aio = ioc->pending_aios.back();
     if (g_conf->bdev_inject_crash &&
 	rand() % g_conf->bdev_inject_crash == 0) {
@@ -473,7 +479,7 @@ int KernelDevice::read(uint64_t off, uint64_t len, bufferlist *pbl,
   assert(off + len <= size);
 
   _aio_log_start(ioc, off, len);
-  ioc->num_reading.inc();;
+  ++ioc->num_reading;
 
   bufferptr p = buffer::create_page_aligned(len);
   int r = ::pread(buffered ? fd_buffered : fd_direct,
@@ -492,12 +498,8 @@ int KernelDevice::read(uint64_t off, uint64_t len, bufferlist *pbl,
 
  out:
   _aio_log_finish(ioc, off, len);
-  ioc->num_reading.dec();
-  if (ioc->num_waiting.read()) {
-    dout(20) << __func__ << " waking waiter" << dendl;
-    Mutex::Locker l(ioc->lock);
-    ioc->cond.Signal();
-  }
+  --ioc->num_reading;
+  ioc->aio_wake();
   return r < 0 ? r : 0;
 }
 
diff --git a/src/os/bluestore/NVMEDevice.cc b/src/os/bluestore/NVMEDevice.cc
index b570c87..d89a705 100644
--- a/src/os/bluestore/NVMEDevice.cc
+++ b/src/os/bluestore/NVMEDevice.cc
@@ -21,6 +21,7 @@
 #include <fcntl.h>
 #include <unistd.h>
 #include <map>
+#include <thread>
 #ifdef HAVE_SSE
 #include <xmmintrin.h>
 #endif
@@ -63,9 +64,11 @@ rte_mempool *task_pool = nullptr;
 enum {
   l_bluestore_nvmedevice_first = 632430,
   l_bluestore_nvmedevice_aio_write_lat,
+  l_bluestore_nvmedevice_aio_zero_lat,
   l_bluestore_nvmedevice_read_lat,
   l_bluestore_nvmedevice_flush_lat,
   l_bluestore_nvmedevice_aio_write_queue_lat,
+  l_bluestore_nvmedevice_aio_zero_queue_lat,
   l_bluestore_nvmedevice_read_queue_lat,
   l_bluestore_nvmedevice_flush_queue_lat,
   l_bluestore_nvmedevice_queue_ops,
@@ -73,85 +76,84 @@ enum {
   l_bluestore_nvmedevice_last
 };
 
-static void io_complete(void *t, const struct nvme_completion *completion);
-
-static const char *ealargs[] = {
-    "ceph-osd",
-    "-c 0x1", /* This must be the second parameter. It is overwritten by index in main(). */
-    "-n 4",
-};
+static void io_complete(void *t, const struct spdk_nvme_cpl *completion);
 
+int dpdk_thread_adaptor(void *f)
+{
+  (*static_cast<std::function<void ()>*>(f))();
+  return 0;
+}
 
 class SharedDriverData {
+  unsigned id;
   std::string sn;
   std::string name;
-  nvme_controller *ctrlr;
-  nvme_namespace *ns;
+  spdk_nvme_ctrlr *ctrlr;
+  spdk_nvme_ns *ns;
+  std::function<void ()> run_func;
 
   uint64_t block_size = 0;
   uint64_t size = 0;
   std::vector<NVMEDevice*> registered_devices;
-  struct AioCompletionThread : public Thread {
-    SharedDriverData *data;
-    AioCompletionThread(SharedDriverData *d) : data(d) {}
-    void *entry() {
-      data->_aio_thread();
-      return NULL;
-    }
-  } aio_thread;
   friend class AioCompletionThread;
 
   bool aio_stop = false;
-  int ref = 1;
   void _aio_thread();
   void _aio_start() {
-    aio_thread.create("nvme_aio_thread");
+    int r = rte_eal_remote_launch(dpdk_thread_adaptor, static_cast<void*>(&run_func), id);
+    assert(r == 0);
   }
   void _aio_stop() {
-    assert(aio_thread.is_started());
     {
       Mutex::Locker l(queue_lock);
       aio_stop = true;
       queue_cond.Signal();
     }
-    aio_thread.join();
+    int r = rte_eal_wait_lcore(id);
+    assert(r == 0);
     aio_stop = false;
   }
-  atomic_t queue_empty;
+  std::atomic_bool queue_empty;
   Mutex queue_lock;
   Cond queue_cond;
   std::queue<Task*> task_queue;
 
   Mutex flush_lock;
   Cond flush_cond;
-  atomic_t flush_waiters;
+  std::atomic_int flush_waiters;
 
  public:
-  atomic_t inflight_ops;
+  bool zero_command_support;
+  std::atomic_int inflight_ops;
   PerfCounters *logger = nullptr;
 
-  SharedDriverData(const std::string &sn_tag, const std::string &n, nvme_controller *c, nvme_namespace *ns)
-      : sn(sn_tag),
+  SharedDriverData(unsigned i, const std::string &sn_tag, const std::string &n,
+                   spdk_nvme_ctrlr *c, spdk_nvme_ns *ns)
+      : id(i),
+        sn(sn_tag),
         name(n),
         ctrlr(c),
         ns(ns),
-        aio_thread(this),
-        queue_empty(1),
+        run_func([this]() { _aio_thread(); }),
+        queue_empty(false),
         queue_lock("NVMEDevice::queue_lock"),
         flush_lock("NVMEDevice::flush_lock"),
         flush_waiters(0),
         inflight_ops(0) {
-    block_size = nvme_ns_get_sector_size(ns);
-    size = block_size * nvme_ns_get_num_sectors(ns);
+    block_size = spdk_nvme_ns_get_sector_size(ns);
+    size = block_size * spdk_nvme_ns_get_num_sectors(ns);
+    zero_command_support = spdk_nvme_ns_get_flags(ns) & SPDK_NVME_NS_WRITE_ZEROES_SUPPORTED;
 
     PerfCountersBuilder b(g_ceph_context, string("NVMEDevice-AIOThread-"+stringify(this)),
                           l_bluestore_nvmedevice_first, l_bluestore_nvmedevice_last);
     b.add_time_avg(l_bluestore_nvmedevice_aio_write_lat, "aio_write_lat", "Average write completing latency");
+    b.add_time_avg(l_bluestore_nvmedevice_aio_zero_lat, "aio_zero_lat", "Average zero completing latency");
     b.add_time_avg(l_bluestore_nvmedevice_read_lat, "read_lat", "Average read completing latency");
     b.add_time_avg(l_bluestore_nvmedevice_flush_lat, "flush_lat", "Average flush completing latency");
     b.add_u64(l_bluestore_nvmedevice_queue_ops, "queue_ops", "Operations in nvme queue");
     b.add_time_avg(l_bluestore_nvmedevice_polling_lat, "polling_lat", "Average polling latency");
     b.add_time_avg(l_bluestore_nvmedevice_aio_write_queue_lat, "aio_write_queue_lat", "Average queue write request latency");
+    b.add_time_avg(l_bluestore_nvmedevice_aio_zero_queue_lat, "aio_zero_queue_lat", "Average queue zero request latency");
     b.add_time_avg(l_bluestore_nvmedevice_read_queue_lat, "read_queue_lat", "Average queue read request latency");
     b.add_time_avg(l_bluestore_nvmedevice_flush_queue_lat, "flush_queue_lat", "Average queue flush request latency");
     logger = b.create_perf_counters();
@@ -175,7 +177,7 @@ class SharedDriverData {
     _aio_stop();
     std::vector<NVMEDevice*> new_devices;
     for (auto &&it : registered_devices) {
-      if (it == device)
+      if (it != device)
         new_devices.push_back(it);
     }
     registered_devices.swap(new_devices);
@@ -189,25 +191,25 @@ class SharedDriverData {
     return size;
   }
   void queue_task(Task *t, uint64_t ops = 1) {
-    inflight_ops.add(ops);
+    inflight_ops += ops;
     Mutex::Locker l(queue_lock);
     task_queue.push(t);
-    if (queue_empty.read()) {
-      queue_empty.dec();
+    if (queue_empty.load()) {
+      queue_empty = false;
       queue_cond.Signal();
     }
   }
 
   void flush_wait() {
-    if (inflight_ops.read()) {
+    if (inflight_ops.load()) {
       // TODO: this may contains read op
-      dout(1) << __func__ << " existed inflight ops " << inflight_ops.read() << dendl;
+      dout(1) << __func__ << " existed inflight ops " << inflight_ops.load() << dendl;
       Mutex::Locker l(flush_lock);
-      flush_waiters.inc();
-      while (inflight_ops.read()) {
+      ++flush_waiters;
+      while (inflight_ops.load()) {
         flush_cond.Wait(flush_lock);
       }
-      flush_waiters.dec();
+      --flush_waiters;
     }
   }
 };
@@ -215,7 +217,7 @@ class SharedDriverData {
 void SharedDriverData::_aio_thread()
 {
   dout(1) << __func__ << " start" << dendl;
-  if (nvme_register_io_thread() != 0) {
+  if (spdk_nvme_register_io_thread() != 0) {
     assert(0);
   }
 
@@ -227,7 +229,7 @@ void SharedDriverData::_aio_thread()
   while (true) {
     dout(40) << __func__ << " polling" << dendl;
     t = nullptr;
-    if (!queue_empty.read()) {
+    if (!queue_empty.load()) {
       Mutex::Locker l(queue_lock);
       if (!task_queue.empty()) {
         t = task_queue.front();
@@ -235,9 +237,9 @@ void SharedDriverData::_aio_thread()
         logger->set(l_bluestore_nvmedevice_queue_ops, task_queue.size());
       }
       if (!t)
-        queue_empty.inc();
-    } else if (!inflight_ops.read()) {
-      if (flush_waiters.read()) {
+        queue_empty = true;
+    } else if (!inflight_ops.load()) {
+      if (flush_waiters.load()) {
         Mutex::Locker l(flush_lock);
         flush_cond.Signal();
       }
@@ -246,7 +248,7 @@ void SharedDriverData::_aio_thread()
         it->reap_ioc();
 
       Mutex::Locker l(queue_lock);
-      if (queue_empty.read()) {
+      if (queue_empty.load()) {
         lat = ceph_clock_now(g_ceph_context);
         lat -= start;
         logger->tinc(l_bluestore_nvmedevice_polling_lat, lat);
@@ -259,41 +261,52 @@ void SharedDriverData::_aio_thread()
       }
     }
 
-    if (t) {
+    for (; t; t = t->next) {
+      lba_off = t->offset / block_size;
+      lba_count = t->len / block_size;
       switch (t->command) {
         case IOCommand::WRITE_COMMAND:
         {
-          while (t) {
-            lba_off = t->offset / block_size;
-            lba_count = t->len / block_size;
-            dout(20) << __func__ << " write command issued " << lba_off << "~" << lba_count << dendl;
-            r = nvme_ns_cmd_write(ns, t->buf, lba_off, lba_count, io_complete, t, 0);
-            if (r < 0) {
-              t->ctx->nvme_task_first = t->ctx->nvme_task_last = nullptr;
-              rte_free(t->buf);
-              rte_mempool_put(task_pool, t);
-              derr << __func__ << " failed to do write command" << dendl;
-              assert(0);
-            }
-            lat = ceph_clock_now(g_ceph_context);
-            lat -= t->start;
-            logger->tinc(l_bluestore_nvmedevice_aio_write_queue_lat, lat);
-            t = t->next;
+          dout(20) << __func__ << " write command issued " << lba_off << "~" << lba_count << dendl;
+          r = spdk_nvme_ns_cmd_write(ns, t->buf, lba_off, lba_count, io_complete, t, 0);
+          if (r < 0) {
+            t->ctx->nvme_task_first = t->ctx->nvme_task_last = nullptr;
+            rte_free(t->buf);
+            rte_mempool_put(task_pool, t);
+            derr << __func__ << " failed to do write command" << dendl;
+            assert(0);
+          }
+          lat = ceph_clock_now(g_ceph_context);
+          lat -= t->start;
+          logger->tinc(l_bluestore_nvmedevice_aio_write_queue_lat, lat);
+          break;
+        }
+        case IOCommand::ZERO_COMMAND:
+        {
+          dout(20) << __func__ << " zero command issued " << lba_off << "~" << lba_count << dendl;
+          assert(zero_command_support);
+          r = spdk_nvme_ns_cmd_write_zeroes(ns, lba_off, lba_count, io_complete, t, 0);
+          if (r < 0) {
+            t->ctx->nvme_task_first = t->ctx->nvme_task_last = nullptr;
+            rte_mempool_put(task_pool, t);
+            derr << __func__ << " failed to do zero command" << dendl;
+            assert(0);
           }
+          lat = ceph_clock_now(g_ceph_context);
+          lat -= t->start;
+          logger->tinc(l_bluestore_nvmedevice_aio_zero_queue_lat, lat);
           break;
         }
         case IOCommand::READ_COMMAND:
         {
           dout(20) << __func__ << " read command issueed " << lba_off << "~" << lba_count << dendl;
-          lba_off = t->offset / block_size;
-          lba_count = t->len / block_size;
-          r = nvme_ns_cmd_read(ns, t->buf, lba_off, lba_count, io_complete, t, 0);
+          r = spdk_nvme_ns_cmd_read(ns, t->buf, lba_off, lba_count, io_complete, t, 0);
           if (r < 0) {
             derr << __func__ << " failed to read" << dendl;
-            t->ctx->num_reading.dec();
+            --t->ctx->num_reading;
             t->return_code = r;
-            Mutex::Locker l(t->ctx->lock);
-            t->ctx->cond.Signal();
+            std::unique_lock<std::mutex> l(t->ctx->lock);
+            t->ctx->cond.notify_all();
           } else {
             lat = ceph_clock_now(g_ceph_context);
             lat -= t->start;
@@ -304,12 +317,12 @@ void SharedDriverData::_aio_thread()
         case IOCommand::FLUSH_COMMAND:
         {
           dout(20) << __func__ << " flush command issueed " << dendl;
-          r = nvme_ns_cmd_flush(ns, io_complete, t);
+          r = spdk_nvme_ns_cmd_flush(ns, io_complete, t);
           if (r < 0) {
             derr << __func__ << " failed to flush" << dendl;
             t->return_code = r;
-            Mutex::Locker l(t->ctx->lock);
-            t->ctx->cond.Signal();
+            std::unique_lock<std::mutex> l(t->ctx->lock);
+            t->ctx->cond.notify_all();
           } else {
             lat = ceph_clock_now(g_ceph_context);
             lat -= t->start;
@@ -318,8 +331,9 @@ void SharedDriverData::_aio_thread()
           break;
         }
       }
-    } else if (inflight_ops.read()) {
-      nvme_ctrlr_process_io_completions(ctrlr, max);
+    }
+    if (inflight_ops.load()) {
+      spdk_nvme_ctrlr_process_io_completions(ctrlr, max);
       dout(30) << __func__ << " idle, have a pause" << dendl;
 #ifdef HAVE_SSE
       _mm_pause();
@@ -328,170 +342,125 @@ void SharedDriverData::_aio_thread()
 #endif
     }
   }
-  nvme_unregister_io_thread();
+  spdk_nvme_unregister_io_thread();
   dout(1) << __func__ << " end" << dendl;
 }
 
+#define dout_subsys ceph_subsys_bdev
+#undef dout_prefix
+#define dout_prefix *_dout << "bdev "
+
 class NVMEManager {
+ public:
+  struct ProbeContext {
+    string sn_tag;
+    NVMEManager *manager;
+    SharedDriverData *driver;
+    bool done;
+  };
+
+ private:
   Mutex lock;
   bool init = false;
   std::vector<SharedDriverData*> shared_driver_datas;
-
-  static int _scan_nvme_device(const string &sn_tag, string &name, nvme_controller **c, nvme_namespace **ns);
+  std::thread dpdk_thread;
+  std::mutex probe_queue_lock;
+  std::condition_variable probe_queue_cond;
+  std::list<ProbeContext*> probe_queue;
 
  public:
   NVMEManager()
       : lock("NVMEDevice::NVMEManager::lock") {}
   int try_get(const string &sn_tag, SharedDriverData **driver);
+  void register_ctrlr(const string &sn_tag, spdk_nvme_ctrlr *c, struct spdk_pci_device *pci_dev,
+                      SharedDriverData **driver) {
+    assert(lock.is_locked());
+    spdk_nvme_ns *ns;
+    int num_ns = spdk_nvme_ctrlr_get_num_ns(c);
+    string name = spdk_pci_device_get_device_name(pci_dev) ? spdk_pci_device_get_device_name(pci_dev) : "Unknown";
+    assert(num_ns >= 1);
+    if (num_ns > 1) {
+      dout(0) << __func__ << " namespace count larger than 1, currently only use the first namespace" << dendl;
+    }
+    ns = spdk_nvme_ctrlr_get_ns(c, 1);
+    if (!ns) {
+      derr << __func__ << " failed to get namespace at 1" << dendl;
+      assert(0);
+    }
+    dout(1) << __func__ << " successfully attach nvme device at" << name
+            << " " << spdk_pci_device_get_bus(pci_dev) << ":" << spdk_pci_device_get_dev(pci_dev) << ":" << spdk_pci_device_get_func(pci_dev) << dendl;
+
+    // only support one device per osd now!
+    assert(shared_driver_datas.empty());
+    // index 0 is occured by master thread
+    shared_driver_datas.push_back(new SharedDriverData(shared_driver_datas.size()+1, sn_tag, name, c, ns));
+    *driver = shared_driver_datas.back();
+  }
 };
 
 static NVMEManager manager;
 
-#define dout_subsys ceph_subsys_bdev
-#undef dout_prefix
-#define dout_prefix *_dout << "bdev "
-
-int NVMEManager::_scan_nvme_device(const string &sn_tag, string &name, nvme_controller **c, nvme_namespace **ns)
+static bool probe_cb(void *cb_ctx, struct spdk_pci_device *pci_dev)
 {
-  int r = 0;
-  dout(1) << __func__ << " serial number " << sn_tag << dendl;
-
-  pci_device *pci_dev;
-
-  // Search for matching devices
-  pci_id_match match;
-  match.vendor_id = PCI_MATCH_ANY;
-  match.subvendor_id = PCI_MATCH_ANY;
-  match.subdevice_id = PCI_MATCH_ANY;
-  match.device_id = PCI_MATCH_ANY;
-  match.device_class = NVME_CLASS_CODE;
-  match.device_class_mask = 0xFFFFFF;
-
-  pci_device_iterator *iter = pci_id_match_iterator_create(&match);
-
+  NVMEManager::ProbeContext *ctx = static_cast<NVMEManager::ProbeContext*>(cb_ctx);
   char serial_number[128];
-  while ((pci_dev = pci_device_next(iter)) != NULL) {
-    dout(0) << __func__ << " found device at name: " << pci_device_get_device_name(pci_dev)
-            << " bus: " << pci_dev->bus << ":" << pci_dev->dev << ":"
-            << pci_dev->func << " vendor:0x" << pci_dev->vendor_id << " device:0x" << pci_dev->device_id
-            << dendl;
-    r = pci_device_get_serial_number(pci_dev, serial_number, 128);
-    if (r < 0) {
-      dout(10) << __func__ << " failed to get serial number from " << pci_device_get_device_name(pci_dev) << dendl;
-      continue;
-    }
-
-    if (sn_tag.compare(string(serial_number, 16))) {
-      dout(0) << __func__ << " device serial number not match " << serial_number << dendl;
-      continue;
-    }
-    break;
-  }
-  if (pci_dev == NULL) {
-    derr << __func__ << " failed to found nvme serial number " << sn_tag << dendl;
-    return -ENOENT;
-  }
-
-  pci_device_probe(pci_dev);
-  name = pci_device_get_device_name(pci_dev) ? pci_device_get_device_name(pci_dev) : "Unknown";
-  if (pci_device_has_kernel_driver(pci_dev)) {
-    if (pci_device_has_non_uio_driver(pci_dev)) {
-      /*NVMe kernel driver case*/
-      if (g_conf->bdev_nvme_unbind_from_kernel) {
-        r =  pci_device_switch_to_uio_driver(pci_dev);
-        if (r < 0) {
-          derr << __func__ << " device " << name << " " << pci_dev->bus
-               << ":" << pci_dev->dev << ":" << pci_dev->func
-               << " switch to uio driver failed" << dendl;
-          return r;
-        }
-      } else {
-        derr << __func__ << " device has kernel nvme driver attached, exiting..." << dendl;
-        r = -EBUSY;
-        return r;
+  string name = spdk_pci_device_get_device_name(pci_dev) ? spdk_pci_device_get_device_name(pci_dev) : "Unknown";
+  dout(0) << __func__ << " found device at name: " << name
+          << " bus: " << spdk_pci_device_get_bus(pci_dev) << ":" << spdk_pci_device_get_dev(pci_dev) << ":"
+          << spdk_pci_device_get_func(pci_dev) << " vendor:0x" << spdk_pci_device_get_vendor_id(pci_dev) << " device:0x" << spdk_pci_device_get_device_id(pci_dev)
+          << dendl;
+  int r = spdk_pci_device_get_serial_number(pci_dev, serial_number, 128);
+  if (r < 0) {
+    dout(10) << __func__ << " failed to get serial number from " << name << dendl;
+    return false;
+  }
+
+  if (ctx->sn_tag.compare(string(serial_number, 16))) {
+    dout(0) << __func__ << " device serial number not match " << serial_number << dendl;
+    return false;
+  }
+
+  if (spdk_pci_device_has_non_uio_driver(pci_dev)) {
+    /*NVMe kernel driver case*/
+    if (g_conf->bdev_nvme_unbind_from_kernel) {
+      r =  spdk_pci_device_switch_to_uio_driver(pci_dev);
+      if (r < 0) {
+        derr << __func__ << " device " << name
+             << " " << spdk_pci_device_get_bus(pci_dev)
+             << ":" << spdk_pci_device_get_dev(pci_dev)
+             << ":" << spdk_pci_device_get_func(pci_dev)
+             << " switch to uio driver failed" << dendl;
+        return false;
       }
+    } else {
+      derr << __func__ << " device has kernel nvme driver attached" << dendl;
+      return false;
     }
   } else {
-    r =  pci_device_bind_uio_driver(pci_dev, const_cast<char*>(PCI_UIO_DRIVER));
+    r =  spdk_pci_device_bind_uio_driver(pci_dev);
     if (r < 0) {
-      derr << __func__ << " device " << name << " " << pci_dev->bus
-           << ":" << pci_dev->dev << ":" << pci_dev->func
+      derr << __func__ << " device " << name
+           << " " << spdk_pci_device_get_bus(pci_dev)
+           << ":" << spdk_pci_device_get_dev(pci_dev) << ":"
+           << spdk_pci_device_get_func(pci_dev)
            << " bind to uio driver failed, may lack of uio_pci_generic kernel module" << dendl;
-      return r;
+      return false;
     }
   }
 
-  /* Claim the device in case conflict with other ids process */
-  r =  pci_device_claim(pci_dev);
-  if (r < 0) {
-    derr << __func__ << " device " << name << " " << pci_dev->bus
-         << ":" << pci_dev->dev << ":" << pci_dev->func
-         << " claim failed" << dendl;
-    return r;
-  }
-
-  *c = nvme_attach(pci_dev);
-  if (!*c) {
-    derr << __func__ << " device attach nvme failed" << dendl;
-    r = -1;
-    return r;
-  }
-
-  pci_iterator_destroy(iter);
-
-  int num_ns = nvme_ctrlr_get_num_ns(*c);
-  assert(num_ns >= 1);
-  if (num_ns > 1) {
-    dout(0) << __func__ << " namespace count larger than 1, currently only use the first namespace" << dendl;
-  }
-  *ns = nvme_ctrlr_get_ns(*c, 1);
-  if (!*ns) {
-    derr << __func__ << " failed to get namespace at 1" << dendl;
-    return -1;
-  }
-  dout(1) << __func__ << " successfully attach nvme device at" << name
-          << " " << pci_dev->bus << ":" << pci_dev->dev << ":" << pci_dev->func << dendl;
+  return true;
+}
 
-  return 0;
+static void attach_cb(void *cb_ctx, struct spdk_pci_device *dev, struct spdk_nvme_ctrlr *ctrlr)
+{
+  NVMEManager::ProbeContext *ctx = static_cast<NVMEManager::ProbeContext*>(cb_ctx);
+  ctx->manager->register_ctrlr(ctx->sn_tag, ctrlr, dev, &ctx->driver);
 }
 
 int NVMEManager::try_get(const string &sn_tag, SharedDriverData **driver)
 {
   Mutex::Locker l(lock);
   int r = 0;
-  if (!init) {
-    r = rte_eal_init(sizeof(ealargs) / sizeof(ealargs[0]), (char **)(void *)(uintptr_t)ealargs);
-    if (r < 0) {
-      derr << __func__ << " failed to do rte_eal_init" << dendl;
-      return r;
-    }
-
-    request_mempool = rte_mempool_create("nvme_request", 512,
-                                         nvme_request_size(), 128, 0,
-                                         NULL, NULL, NULL, NULL,
-                                         SOCKET_ID_ANY, 0);
-    if (request_mempool == NULL) {
-      derr << __func__ << " failed to create memory pool for nvme requests" << dendl;
-      return -ENOMEM;
-    }
-
-    task_pool = rte_mempool_create(
-        "task_pool", 512, sizeof(Task),
-        64, 0, NULL, NULL, NULL, NULL,
-        SOCKET_ID_ANY, 0);
-    if (task_pool == NULL) {
-      derr << __func__ << " failed to create memory pool for nvme requests" << dendl;
-      return -ENOMEM;
-    }
-
-    pci_system_init();
-    nvme_retry_count = g_conf->bdev_nvme_retry_count;
-    if (nvme_retry_count < 0)
-      nvme_retry_count = NVME_DEFAULT_RETRY_COUNT;
-
-    init = true;
-  }
-
   if (sn_tag.empty()) {
     r = -ENOENT;
     derr << __func__ << " empty serial number: " << cpp_strerror(r) << dendl;
@@ -505,39 +474,102 @@ int NVMEManager::try_get(const string &sn_tag, SharedDriverData **driver)
     }
   }
 
-  nvme_controller *c;
-  nvme_namespace *ns;
-  std::string name;
-  if (_scan_nvme_device(sn_tag, name, &c, &ns) < 0)
-    return -1;
+  if (!init) {
+    init = true;
+    dpdk_thread = std::thread(
+      [this]() {
+        static const char *ealargs[] = {
+            "ceph-osd",
+            "-c 0x3", /* This must be the second parameter. It is overwritten by index in main(). */
+            "-n 4",
+        };
+
+        int r = rte_eal_init(sizeof(ealargs) / sizeof(ealargs[0]), (char **)(void *)(uintptr_t)ealargs);
+        if (r < 0) {
+          derr << __func__ << " failed to do rte_eal_init" << dendl;
+          assert(0);
+        }
+
+        request_mempool = rte_mempool_create("nvme_request", 512,
+                                             spdk_nvme_request_size(), 128, 0,
+                                             NULL, NULL, NULL, NULL,
+                                             SOCKET_ID_ANY, 0);
+        if (request_mempool == NULL) {
+          derr << __func__ << " failed to create memory pool for nvme requests" << dendl;
+          assert(0);
+        }
+
+        task_pool = rte_mempool_create(
+            "task_pool", 512, sizeof(Task),
+            64, 0, NULL, NULL, NULL, NULL,
+            SOCKET_ID_ANY, 0);
+        if (task_pool == NULL) {
+          derr << __func__ << " failed to create memory pool for nvme requests" << dendl;
+          assert(0);
+        }
+
+        pci_system_init();
+        spdk_nvme_retry_count = g_conf->bdev_nvme_retry_count;
+        if (spdk_nvme_retry_count < 0)
+          spdk_nvme_retry_count = SPDK_NVME_DEFAULT_RETRY_COUNT;
+
+        std::unique_lock<std::mutex> l(probe_queue_lock);
+        while (true) {
+          if (!probe_queue.empty()) {
+            ProbeContext* ctxt = probe_queue.front();
+            probe_queue.pop_front();
+            r = spdk_nvme_probe(ctxt, probe_cb, attach_cb);
+            if (r < 0) {
+              assert(!ctxt->driver);
+              derr << __func__ << " device probe nvme failed" << dendl;
+            }
+            ctxt->done = true;
+            probe_queue_cond.notify_all();
+          } else {
+            probe_queue_cond.wait(l);
+          }
+        }
+      }
+    );
+    dpdk_thread.detach();
+  }
 
-  shared_driver_datas.push_back(new SharedDriverData(sn_tag, name, c, ns));
-  *driver = shared_driver_datas.back();
+  ProbeContext ctx = {sn_tag, this, nullptr, false};
+  {
+    std::unique_lock<std::mutex> l(probe_queue_lock);
+    probe_queue.push_back(&ctx);
+    while (!ctx.done)
+      probe_queue_cond.wait(l);
+  }
+  if (!ctx.driver)
+    return -1;
+  *driver = ctx.driver;
 
   return 0;
 }
 
-void io_complete(void *t, const struct nvme_completion *completion)
+void io_complete(void *t, const struct spdk_nvme_cpl *completion)
 {
   Task *task = static_cast<Task*>(t);
   IOContext *ctx = task->ctx;
   SharedDriverData *driver = task->device->get_driver();
-  driver->inflight_ops.dec();
+  int left = --driver->inflight_ops;
   utime_t lat = ceph_clock_now(g_ceph_context);
   lat -= task->start;
-  if (task->command == IOCommand::WRITE_COMMAND) {
-    driver->logger->tinc(l_bluestore_nvmedevice_aio_write_lat, lat);
-    assert(!nvme_completion_is_error(completion));
-    dout(20) << __func__ << " write op successfully, left " << left << dendl;
-    // buffer write won't have ctx, and we will free request later, see `flush`
+  if (task->command == IOCommand::WRITE_COMMAND ||
+      task->command == IOCommand::ZERO_COMMAND) {
+    if (task->command == IOCommand::WRITE_COMMAND)
+      driver->logger->tinc(l_bluestore_nvmedevice_aio_write_lat, lat);
+    else
+      driver->logger->tinc(l_bluestore_nvmedevice_aio_zero_lat, lat);
+    assert(!spdk_nvme_cpl_is_error(completion));
+    dout(20) << __func__ << " write/zero op successfully, left " << left << dendl;
+    // buffer write/zero won't have ctx, and we will free request later, see `flush`
     if (ctx) {
       // check waiting count before doing callback (which may
       // destroy this ioc).
-      if (!ctx->num_running.dec()) {
-        if (ctx->num_waiting.read()) {
-          Mutex::Locker l(ctx->lock);
-          ctx->cond.Signal();
-        }
+      if (!--ctx->num_running) {
+        ctx->aio_wake();
         if (task->device->aio_callback && ctx->priv) {
           task->device->aio_callback(task->device->aio_callback_priv, ctx->priv);
         }
@@ -549,27 +581,27 @@ void io_complete(void *t, const struct nvme_completion *completion)
     }
   } else if (task->command == IOCommand::READ_COMMAND) {
     driver->logger->tinc(l_bluestore_nvmedevice_read_lat, lat);
-    ctx->num_reading.dec();
+    --ctx->num_reading;
     dout(20) << __func__ << " read op successfully" << dendl;
-    if (nvme_completion_is_error(completion))
+    if (spdk_nvme_cpl_is_error(completion))
       task->return_code = -1; // FIXME
     else
       task->return_code = 0;
     {
-      Mutex::Locker l(ctx->lock);
-      ctx->cond.Signal();
+      std::unique_lock<std::mutex> l(ctx->lock);
+      ctx->cond.notify_all();
     }
   } else {
     assert(task->command == IOCommand::FLUSH_COMMAND);
     driver->logger->tinc(l_bluestore_nvmedevice_flush_lat, lat);
     dout(20) << __func__ << " flush op successfully" << dendl;
-    if (nvme_completion_is_error(completion))
+    if (spdk_nvme_cpl_is_error(completion))
       task->return_code = -1; // FIXME
     else
       task->return_code = 0;
     {
-      Mutex::Locker l(ctx->lock);
-      ctx->cond.Signal();
+      std::unique_lock<std::mutex> l(ctx->lock);
+      ctx->cond.notify_all();
     }
   }
 }
@@ -583,8 +615,6 @@ NVMEDevice::NVMEDevice(aio_callback_t cb, void *cbpriv)
       aio_callback(cb),
       aio_callback_priv(cbpriv)
 {
-  zeros = buffer::create_page_aligned(1048576);
-  zeros.zero();
 }
 
 
@@ -603,8 +633,14 @@ int NVMEDevice::open(string p)
   }
   char buf[100];
   r = ::read(fd, buf, sizeof(buf));
+  VOID_TEMP_FAILURE_RETRY(::close(fd));
+  fd = -1; // defensive
   if (r <= 0) {
-    r = -errno;
+    if (r == 0) {
+      r = -EINVAL;
+    } else {
+      r = -errno;
+    }
     derr << __func__ << " unable to read " << p << ": " << cpp_strerror(r) << dendl;
     return r;
   }
@@ -618,6 +654,10 @@ int NVMEDevice::open(string p)
   driver->register_device(this);
   block_size = driver->get_block_size();
   size = driver->get_size();
+  if (!driver->zero_command_support) {
+    zeros = buffer::create_page_aligned(1048576);
+    zeros.zero();
+  }
 
   dout(1) << __func__ << " size " << size << " (" << pretty_si_t(size) << "B)"
           << " block_size " << block_size << " (" << pretty_si_t(block_size)
@@ -693,14 +733,14 @@ int NVMEDevice::flush()
 void NVMEDevice::aio_submit(IOContext *ioc)
 {
   dout(20) << __func__ << " ioc " << ioc << " pending "
-           << ioc->num_pending.read() << " running "
-           << ioc->num_running.read() << dendl;
-  int pending = ioc->num_pending.read();
+           << ioc->num_pending.load() << " running "
+           << ioc->num_running.load() << dendl;
+  int pending = ioc->num_pending.load();
   Task *t = static_cast<Task*>(ioc->nvme_task_first);
   if (pending && t) {
-    ioc->num_running.add(pending);
-    ioc->num_pending.sub(pending);
-    assert(ioc->num_pending.read() == 0);  // we should be only thread doing this
+    ioc->num_running += pending;
+    ioc->num_pending -= pending;
+    assert(ioc->num_pending.load() == 0);  // we should be only thread doing this
     // Only need to push the first entry
     driver->queue_task(t, pending);
     ioc->nvme_task_first = ioc->nvme_task_last = nullptr;
@@ -729,6 +769,8 @@ int NVMEDevice::aio_write(
   }
   t->start = ceph_clock_now(g_ceph_context);
 
+  // TODO: if upper layer alloc memory with known physical address,
+  // we can reduce this copy
   t->buf = rte_malloc(NULL, len, block_size);
   if (t->buf == NULL) {
     derr << __func__ << " task->buf rte_malloc failed" << dendl;
@@ -759,7 +801,7 @@ int NVMEDevice::aio_write(
     if (!first)
       ioc->nvme_task_first = t;
     ioc->nvme_task_last = t;
-    ioc->num_pending.inc();
+    ++ioc->num_pending;
   }
 
   dout(5) << __func__ << " " << off << "~" << len << dendl;
@@ -779,17 +821,46 @@ int NVMEDevice::aio_zero(
   assert(off < size);
   assert(off + len <= size);
 
-  bufferlist bl;
-  while (len > 0) {
-    bufferlist t;
-    t.append(zeros, 0, MIN(zeros.length(), len));
-    len -= t.length();
-    bl.claim_append(t);
-  }
-  bufferlist foo;
-  // note: this works with aio only becaues the actual buffer is
-  // this->zeros, which is page-aligned and never freed.
-  return aio_write(off, bl, ioc, false);
+  if (driver->zero_command_support) {
+    Task *t;
+    int r = rte_mempool_get(task_pool, (void **)&t);
+    if (r < 0) {
+      derr << __func__ << " failed to get task from mempool: " << r << dendl;
+      return r;
+    }
+    t->start = ceph_clock_now(g_ceph_context);
+
+    t->command = IOCommand::ZERO_COMMAND;
+    t->offset = off;
+    t->len = len;
+    t->device = this;
+    t->buf = nullptr;
+    t->return_code = 0;
+    t->next = nullptr;
+    t->ctx = ioc;
+    Task *first = static_cast<Task*>(ioc->nvme_task_first);
+    Task *last = static_cast<Task*>(ioc->nvme_task_last);
+    if (last)
+      last->next = t;
+    if (!first)
+      ioc->nvme_task_first = t;
+    ioc->nvme_task_last = t;
+    ++ioc->num_pending;
+  } else {
+    assert(zeros.length());
+    bufferlist bl;
+    while (len > 0) {
+      bufferlist t;
+      t.append(zeros, 0, MIN(zeros.length(), len));
+      len -= t.length();
+      bl.claim_append(t);
+    }
+    // note: this works with aio only becaues the actual buffer is
+    // this->zeros, which is page-aligned and never freed.
+    return aio_write(off, bl, ioc, false);
+  }
+
+  return 0;
 }
 
 int NVMEDevice::read(uint64_t off, uint64_t len, bufferlist *pbl,
@@ -825,13 +896,13 @@ int NVMEDevice::read(uint64_t off, uint64_t len, bufferlist *pbl,
   t->device = this;
   t->return_code = 1;
   t->next = nullptr;
-  ioc->num_reading.inc();;
+  ++ioc->num_reading;
   driver->queue_task(t);
 
   {
-    Mutex::Locker l(ioc->lock);
+    std::unique_lock<std::mutex> l(ioc->lock);
     while (t->return_code > 0)
-      ioc->cond.Wait(ioc->lock);
+      ioc->cond.wait(l);
   }
   memcpy(p.c_str(), t->buf, len);
   {
@@ -846,10 +917,10 @@ int NVMEDevice::read(uint64_t off, uint64_t len, bufferlist *pbl,
 
  out:
   rte_mempool_put(task_pool, t);
-  if (ioc->num_waiting.read()) {
+  if (ioc->num_waiting.load()) {
     dout(20) << __func__ << " waking waiter" << dendl;
-    Mutex::Locker l(ioc->lock);
-    ioc->cond.Signal();
+    std::unique_lock<std::mutex> l(ioc->lock);
+    ioc->cond.notify_all();
   }
   return r;
 }
@@ -886,13 +957,13 @@ int NVMEDevice::read_buffered(uint64_t off, uint64_t len, char *buf)
   t->device = this;
   t->return_code = 1;
   t->next = nullptr;
-  ioc.num_reading.inc();;
+  ++ioc.num_reading;
   driver->queue_task(t);
 
   {
-    Mutex::Locker l(ioc.lock);
+    std::unique_lock<std::mutex> l(ioc.lock);
     while (t->return_code > 0)
-      ioc.cond.Wait(ioc.lock);
+      ioc.cond.wait(l);
   }
   memcpy(buf, (char*)t->buf+off-aligned_off, len);
   {
diff --git a/src/os/bluestore/NVMEDevice.h b/src/os/bluestore/NVMEDevice.h
index dca5837..a47962b 100644
--- a/src/os/bluestore/NVMEDevice.h
+++ b/src/os/bluestore/NVMEDevice.h
@@ -35,6 +35,7 @@
 enum class IOCommand {
   READ_COMMAND,
   WRITE_COMMAND,
+  ZERO_COMMAND,
   FLUSH_COMMAND
 };
 
diff --git a/src/os/bluestore/StupidAllocator.cc b/src/os/bluestore/StupidAllocator.cc
index 4d8c5f1..584c310 100755
--- a/src/os/bluestore/StupidAllocator.cc
+++ b/src/os/bluestore/StupidAllocator.cc
@@ -85,15 +85,15 @@ static uint64_t aligned_len(btree_interval_set<uint64_t>::iterator p,
 }
 
 int StupidAllocator::allocate(
-  uint64_t need_size, uint64_t alloc_unit, int64_t hint,
+  uint64_t want_size, uint64_t alloc_unit, int64_t hint,
   uint64_t *offset, uint32_t *length)
 {
   std::lock_guard<std::mutex> l(lock);
-  dout(10) << __func__ << " need_size " << need_size
+  dout(10) << __func__ << " want_size " << want_size
 	   << " alloc_unit " << alloc_unit
 	   << " hint " << hint
 	   << dendl;
-  uint64_t want = MAX(alloc_unit, need_size);
+  uint64_t want = MAX(alloc_unit, want_size);
   int bin = _choose_bin(want);
   int orig_bin = bin;
 
@@ -107,7 +107,7 @@ int StupidAllocator::allocate(
     for (bin = orig_bin; bin < (int)free.size(); ++bin) {
       p = free[bin].lower_bound(hint);
       while (p != free[bin].end()) {
-	if (aligned_len(p, alloc_unit) >= need_size) {
+	if (aligned_len(p, alloc_unit) >= want_size) {
 	  goto found;
 	}
 	++p;
@@ -115,11 +115,12 @@ int StupidAllocator::allocate(
     }
   }
 
-  // search up (from origin)
+  // search up (from origin, and skip searched extents by hint)
   for (bin = orig_bin; bin < (int)free.size(); ++bin) {
     p = free[bin].begin();
-    while (p != free[bin].end()) {
-      if (aligned_len(p, alloc_unit) >= need_size) {
+    auto end = hint ? free[bin].lower_bound(hint) : free[bin].end();
+    while (p != end) {
+      if (aligned_len(p, alloc_unit) >= want_size) {
 	goto found;
       }
       ++p;
@@ -139,10 +140,11 @@ int StupidAllocator::allocate(
     }
   }
 
-  // search down (origin)
+  // search down (from origin, and skip searched extents by hint)
   for (bin = orig_bin; bin >= 0; --bin) {
     p = free[bin].begin();
-    while (p != free[bin].end()) {
+    auto end = hint ? free[bin].lower_bound(hint) : free[bin].end();
+    while (p != end) {
       if (aligned_len(p, alloc_unit) >= alloc_unit) {
 	goto found;
       }
@@ -158,7 +160,7 @@ int StupidAllocator::allocate(
   if (skew)
     skew = alloc_unit - skew;
   *offset = p.get_start() + skew;
-  *length = MIN(MAX(alloc_unit, need_size), p.get_len() - skew);
+  *length = MIN(MAX(alloc_unit, want_size), p.get_len() - skew);
   if (g_conf->bluestore_debug_small_allocations) {
     uint64_t max =
       alloc_unit * (rand() % g_conf->bluestore_debug_small_allocations);
diff --git a/src/os/bluestore/StupidAllocator.h b/src/os/bluestore/StupidAllocator.h
index 1b09ace..fa10c5d 100644
--- a/src/os/bluestore/StupidAllocator.h
+++ b/src/os/bluestore/StupidAllocator.h
@@ -34,7 +34,7 @@ public:
   void unreserve(uint64_t unused);
 
   int allocate(
-    uint64_t need_size, uint64_t alloc_unit, int64_t hint,
+    uint64_t want_size, uint64_t alloc_unit, int64_t hint,
     uint64_t *offset, uint32_t *length);
 
   int release(
diff --git a/src/os/filestore/CollectionIndex.h b/src/os/filestore/CollectionIndex.h
index 0d1fc30..942dc23 100644
--- a/src/os/filestore/CollectionIndex.h
+++ b/src/os/filestore/CollectionIndex.h
@@ -77,8 +77,8 @@ protected:
   /// Type of returned paths
   typedef ceph::shared_ptr<Path> IndexedPath;
 
-  static IndexedPath get_testing_path(string path, const coll_t& collection) {
-    return IndexedPath(new Path(path, collection));
+  static IndexedPath get_testing_path(string path, coll_t collection) {
+    return std::make_shared<Path>(path, collection);
   }
 
   static const uint32_t FLAT_INDEX_TAG = 0;
diff --git a/src/os/filestore/DBObjectMap.cc b/src/os/filestore/DBObjectMap.cc
index 0434043..67e17bd 100644
--- a/src/os/filestore/DBObjectMap.cc
+++ b/src/os/filestore/DBObjectMap.cc
@@ -237,7 +237,7 @@ int DBObjectMap::DBObjectMapIteratorImpl::init()
       assert(0);
       return -EINVAL;
     }
-    parent_iter.reset(new DBObjectMapIteratorImpl(map, parent));
+    parent_iter = std::make_shared<DBObjectMapIteratorImpl>(map, parent);
   }
   key_iter = map->db->get_iterator(map->user_prefix(header));
   assert(key_iter);
diff --git a/src/os/filestore/DBObjectMap.h b/src/os/filestore/DBObjectMap.h
index 400c54a..de68f3c 100644
--- a/src/os/filestore/DBObjectMap.h
+++ b/src/os/filestore/DBObjectMap.h
@@ -413,7 +413,7 @@ private:
 
   typedef ceph::shared_ptr<DBObjectMapIteratorImpl> DBObjectMapIterator;
   DBObjectMapIterator _get_iterator(Header header) {
-    return DBObjectMapIterator(new DBObjectMapIteratorImpl(this, header));
+    return std::make_shared<DBObjectMapIteratorImpl>(this, header);
   }
 
   /// sys
diff --git a/src/os/filestore/FileJournal.cc b/src/os/filestore/FileJournal.cc
index 7763c6f..9e40310 100644
--- a/src/os/filestore/FileJournal.cc
+++ b/src/os/filestore/FileJournal.cc
@@ -33,7 +33,9 @@
 #include <sys/mount.h>
 
 #include "common/blkdev.h"
+#if defined(__linux__)
 #include "common/linux_version.h"
+#endif
 
 #if defined(__FreeBSD__)
 #define O_DSYNC O_SYNC
@@ -44,7 +46,8 @@
 #define dout_prefix *_dout << "journal "
 
 const static int64_t ONE_MEG(1 << 20);
-const static int CEPH_MINIMUM_BLOCK_SIZE(4096);
+const static int CEPH_DIRECTIO_ALIGNMENT(4096);
+
 
 int FileJournal::_open(bool forwrite, bool create)
 {
@@ -148,7 +151,7 @@ int FileJournal::_open_block_device()
 	   << dendl;
   max_size = bdev_sz;
 
-  block_size = CEPH_MINIMUM_BLOCK_SIZE;
+  block_size = g_conf->journal_block_size;
 
   if (g_conf->journal_discard) {
     discard = block_device_support_discard(fn.c_str());
@@ -160,6 +163,11 @@ int FileJournal::_open_block_device()
 
 void FileJournal::_check_disk_write_cache() const
 {
+#if !defined(__linux__)
+    dout(10) << "_check_disk_write_cache: not linux, NOT checking disk write "
+      << "cache on raw block device " << fn << dendl;
+    return;
+#else
   ostringstream hdparm_cmd;
   FILE *fp = NULL;
 
@@ -231,6 +239,7 @@ close_f:
   }
 done:
   ;
+#endif // __linux__
 }
 
 int FileJournal::_open_file(int64_t oldsize, blksize_t blksize,
@@ -288,7 +297,7 @@ int FileJournal::_open_file(int64_t oldsize, blksize_t blksize,
   else {
     max_size = oldsize;
   }
-  block_size = MAX(blksize, (blksize_t)CEPH_MINIMUM_BLOCK_SIZE);
+  block_size = g_conf->journal_block_size;
 
   if (create && g_conf->journal_zero_on_create) {
     derr << "FileJournal::_open_file : zeroing journal" << dendl;
@@ -503,9 +512,11 @@ int FileJournal::open(uint64_t fs_op_seq)
 	    << block_size << " (required for direct_io journal mode)" << dendl;
     return -EINVAL;
   }
-  if ((header.alignment % CEPH_MINIMUM_BLOCK_SIZE) && directio) {
-    dout(0) << "open journal alignment " << header.alignment << " is not multiple of minimum block size "
-           << CEPH_MINIMUM_BLOCK_SIZE << " (required for direct_io journal mode)" << dendl;
+  if ((header.alignment % CEPH_DIRECTIO_ALIGNMENT) && directio) {
+    dout(0) << "open journal alignment " << header.alignment
+	    << " is not multiple of minimum directio alignment "
+	    << CEPH_DIRECTIO_ALIGNMENT << " (required for direct_io journal mode)"
+	    << dendl;
     return -EINVAL;
   }
 
@@ -881,9 +892,19 @@ int FileJournal::prepare_multi_write(bufferlist& bl, uint64_t& orig_ops, uint64_
     batch_pop_write(items);
     list<write_item>::iterator it = items.begin();
     while (it != items.end()) {
+      uint64_t bytes = it->bl.length();
       int r = prepare_single_write(*it, bl, queue_pos, orig_ops, orig_bytes);
       if (r == 0) { // prepare ok, delete it
-         items.erase(it++);
+	items.erase(it++);
+#ifdef HAVE_LIBAIO
+	{
+	  Mutex::Locker locker(aio_lock);
+	  assert(aio_write_queue_ops > 0);
+	  aio_write_queue_ops--;
+	  assert(aio_write_queue_bytes >= bytes);
+	  aio_write_queue_bytes -= bytes;
+	}
+#endif
       }
       if (r == -ENOSPC) {
         // the journal maybe full, insert the left item to writeq
@@ -902,7 +923,7 @@ int FileJournal::prepare_multi_write(bufferlist& bl, uint64_t& orig_ops, uint64_
           // throw out what we have so far
           full_state = FULL_FULL;
           while (!writeq_empty()) {
-            put_throttle(1, peek_write().orig_len);
+            complete_write(1, peek_write().orig_len);
             pop_write();
           }
           print_header(header);
@@ -1038,13 +1059,10 @@ void FileJournal::align_bl(off64_t pos, bufferlist& bl)
 {
   // make sure list segments are page aligned
   if (directio && (!bl.is_aligned(block_size) ||
-		   !bl.is_n_align_sized(CEPH_MINIMUM_BLOCK_SIZE))) {
-    assert(0 == "bl should be align");
-    if ((bl.length() & (CEPH_MINIMUM_BLOCK_SIZE - 1)) != 0 ||
-	(pos & (CEPH_MINIMUM_BLOCK_SIZE - 1)) != 0)
-      dout(0) << "rebuild_page_aligned failed, " << bl << dendl;
-    assert((bl.length() & (CEPH_MINIMUM_BLOCK_SIZE - 1)) == 0);
-    assert((pos & (CEPH_MINIMUM_BLOCK_SIZE - 1)) == 0);
+		   !bl.is_n_align_sized(CEPH_DIRECTIO_ALIGNMENT))) {
+    assert((bl.length() & (CEPH_DIRECTIO_ALIGNMENT - 1)) == 0);
+    assert((pos & (CEPH_DIRECTIO_ALIGNMENT - 1)) == 0);
+    assert(0 == "bl was not aligned");
   }
 }
 
@@ -1270,7 +1288,7 @@ void FileJournal::write_thread_entry()
       while (aio_num > 0) {
 	int exp = MIN(aio_num * 2, 24);
 	long unsigned min_new = 1ull << exp;
-	long unsigned cur = throttle_bytes.get_current();
+	uint64_t cur = aio_write_queue_bytes;
 	dout(20) << "write_thread_entry aio throttle: aio num " << aio_num << " bytes " << aio_bytes
 		 << " ... exp " << exp << " min_new " << min_new
 		 << " ... pending " << cur << dendl;
@@ -1297,7 +1315,7 @@ void FileJournal::write_thread_entry()
       if (write_stop) {
 	dout(20) << "write_thread_entry full and stopping, throw out queue and finish up" << dendl;
 	while (!writeq_empty()) {
-	  put_throttle(1, peek_write().orig_len);
+	  complete_write(1, peek_write().orig_len);
 	  pop_write();
 	}
 	print_header(header);
@@ -1324,7 +1342,7 @@ void FileJournal::write_thread_entry()
 #else
     do_write(bl);
 #endif
-    put_throttle(orig_ops, orig_bytes);
+    complete_write(orig_ops, orig_bytes);
   }
 
   dout(10) << "write_thread_entry finish" << dendl;
@@ -1422,7 +1440,7 @@ int FileJournal::write_aio_bl(off64_t& pos, bufferlist& bl, uint64_t seq)
   dout(20) << "write_aio_bl " << pos << "~" << bl.length() << " seq " << seq << dendl;
 
   while (bl.length() > 0) {
-    int max = MIN(bl.buffers().size(), IOV_MAX-1);
+    int max = MIN(bl.get_num_buffers(), IOV_MAX-1);
     iovec *iov = new iovec[max];
     int n = 0;
     unsigned len = 0;
@@ -1631,7 +1649,7 @@ int FileJournal::prepare_entry(vector<ObjectStore::Transaction>& tls, bufferlist
   }
   // footer
   ebl.append((const char*)&h, sizeof(h));
-  ebl.rebuild_aligned(CEPH_MINIMUM_BLOCK_SIZE);
+  ebl.rebuild_aligned(CEPH_DIRECTIO_ALIGNMENT);
   tbl->claim(ebl);
   return h.len;
 }
@@ -1645,20 +1663,32 @@ void FileJournal::submit_entry(uint64_t seq, bufferlist& e, uint32_t orig_len,
 	  << " (" << oncommit << ")" << dendl;
   assert(e.length() > 0);
 
-  throttle_ops.take(1);
-  throttle_bytes.take(orig_len);
   if (osd_op)
     osd_op->mark_event("commit_queued_for_journal_write");
   if (logger) {
-    logger->set(l_os_jq_max_ops, throttle_ops.get_max());
-    logger->set(l_os_jq_max_bytes, throttle_bytes.get_max());
-    logger->set(l_os_jq_ops, throttle_ops.get_current());
-    logger->set(l_os_jq_bytes, throttle_bytes.get_current());
+    logger->inc(l_os_jq_bytes, orig_len);
+    logger->inc(l_os_jq_ops, 1);
+  }
+
+  throttle.register_throttle_seq(seq, e.length());
+  if (logger) {
+    logger->inc(l_os_j_ops, 1);
+    logger->inc(l_os_j_bytes, e.length());
   }
 
   {
-    Mutex::Locker l1(writeq_lock);  // ** lock **
-    Mutex::Locker l2(completions_lock);  // ** lock **
+    Mutex::Locker l1(writeq_lock);
+#ifdef HAVE_LIBAIO
+    Mutex::Locker l2(aio_lock);
+#endif
+    Mutex::Locker l3(completions_lock);
+
+#ifdef HAVE_LIBAIO
+    aio_write_queue_ops++;
+    aio_write_queue_bytes += e.length();
+    aio_cond.Signal();
+#endif
+
     completions.push_back(
       completion_item(
 	seq, oncommit, ceph_clock_now(g_ceph_context), osd_op));
@@ -1685,19 +1715,37 @@ void FileJournal::pop_write()
 {
   assert(write_lock.is_locked());
   Mutex::Locker locker(writeq_lock);
+  if (logger) {
+    logger->dec(l_os_jq_bytes, writeq.front().orig_len);
+    logger->dec(l_os_jq_ops, 1);
+  }
   writeq.pop_front();
 }
 
 void FileJournal::batch_pop_write(list<write_item> &items)
 {
   assert(write_lock.is_locked());
-  Mutex::Locker locker(writeq_lock);
-  writeq.swap(items);
+  {
+    Mutex::Locker locker(writeq_lock);
+    writeq.swap(items);
+  }
+  for (auto &&i : items) {
+    if (logger) {
+      logger->dec(l_os_jq_bytes, i.orig_len);
+      logger->dec(l_os_jq_ops, 1);
+    }
+  }
 }
 
 void FileJournal::batch_unpop_write(list<write_item> &items)
 {
   assert(write_lock.is_locked());
+  for (auto &&i : items) {
+    if (logger) {
+      logger->inc(l_os_jq_bytes, i.orig_len);
+      logger->inc(l_os_jq_ops, 1);
+    }
+  }
   Mutex::Locker locker(writeq_lock);
   writeq.splice(writeq.begin(), items);
 }
@@ -1755,6 +1803,12 @@ void FileJournal::committed_thru(uint64_t seq)
 {
   Mutex::Locker locker(write_lock);
 
+  auto released = throttle.flush(seq);
+  if (logger) {
+    logger->dec(l_os_j_ops, released.first);
+    logger->dec(l_os_j_bytes, released.second);
+  }
+
   if (seq < last_committed_seq) {
     dout(5) << "committed_thru " << seq << " < last_committed_seq " << last_committed_seq << dendl;
     assert(seq >= last_committed_seq);
@@ -1811,7 +1865,7 @@ void FileJournal::committed_thru(uint64_t seq)
     dout(15) << " dropping committed but unwritten seq " << peek_write().seq
 	     << " len " << peek_write().bl.length()
 	     << dendl;
-    put_throttle(1, peek_write().orig_len);
+    complete_write(1, peek_write().orig_len);
     pop_write();
   }
 
@@ -1821,29 +1875,20 @@ void FileJournal::committed_thru(uint64_t seq)
 }
 
 
-void FileJournal::put_throttle(uint64_t ops, uint64_t bytes)
+void FileJournal::complete_write(uint64_t ops, uint64_t bytes)
 {
-  uint64_t new_ops = throttle_ops.put(ops);
-  uint64_t new_bytes = throttle_bytes.put(bytes);
-  dout(5) << "put_throttle finished " << ops << " ops and "
-	   << bytes << " bytes, now "
-	   << new_ops << " ops and " << new_bytes << " bytes"
-	   << dendl;
-
-  if (logger) {
-    logger->inc(l_os_j_ops, ops);
-    logger->inc(l_os_j_bytes, bytes);
-    logger->set(l_os_jq_ops, new_ops);
-    logger->set(l_os_jq_bytes, new_bytes);
-    logger->set(l_os_jq_max_ops, throttle_ops.get_max());
-    logger->set(l_os_jq_max_bytes, throttle_bytes.get_max());
-  }
+  dout(5) << __func__ << " finished " << ops << " ops and "
+	  << bytes << " bytes" << dendl;
 }
 
 int FileJournal::make_writeable()
 {
   dout(10) << __func__ << dendl;
-  int r = _open(true);
+  int r = set_throttle_params();
+  if (r < 0)
+    return r;
+
+  r = _open(true);
   if (r < 0)
     return r;
 
@@ -1854,10 +1899,43 @@ int FileJournal::make_writeable()
   read_pos = 0;
 
   must_write_header = true;
+
   start_writer();
   return 0;
 }
 
+int FileJournal::set_throttle_params()
+{
+  stringstream ss;
+  bool valid = throttle.set_params(
+    g_conf->journal_throttle_low_threshhold,
+    g_conf->journal_throttle_high_threshhold,
+    g_conf->filestore_expected_throughput_bytes,
+    g_conf->journal_throttle_high_multiple,
+    g_conf->journal_throttle_max_multiple,
+    header.max_size - get_top(),
+    &ss);
+
+  if (!valid) {
+    derr << "tried to set invalid params: "
+	 << ss.str()
+	 << dendl;
+  }
+  return valid ? 0 : -EINVAL;
+}
+
+const char** FileJournal::get_tracked_conf_keys() const
+{
+  static const char *KEYS[] = {
+    "journal_throttle_low_threshhold",
+    "journal_throttle_high_threshhold",
+    "journal_throttle_high_multiple",
+    "journal_throttle_max_multiple",
+    "filestore_expected_throughput_bytes",
+    NULL};
+  return KEYS;
+}
+
 void FileJournal::wrap_read_bl(
   off64_t pos,
   int64_t olen,
@@ -1920,6 +1998,16 @@ bool FileJournal::read_entry(
     &ss);
   if (result == SUCCESS) {
     journalq.push_back( pair<uint64_t,off64_t>(seq, pos));
+    uint64_t amount_to_take =
+      next_pos > pos ?
+      next_pos - pos :
+      (header.max_size - pos) + (next_pos - get_top());
+    throttle.take(amount_to_take);
+    throttle.register_throttle_seq(next_seq, amount_to_take);
+    if (logger) {
+      logger->inc(l_os_j_ops, 1);
+      logger->inc(l_os_j_bytes, amount_to_take);
+    }
     if (next_seq > seq) {
       return false;
     } else {
@@ -2037,12 +2125,9 @@ FileJournal::read_entry_result FileJournal::do_read_entry(
   return SUCCESS;
 }
 
-void FileJournal::throttle()
+void FileJournal::reserve_throttle_and_backoff(uint64_t count)
 {
-  if (throttle_ops.wait(g_conf->journal_queue_max_ops))
-    dout(2) << "throttle: waited for ops" << dendl;
-  if (throttle_bytes.wait(g_conf->journal_queue_max_bytes))
-    dout(2) << "throttle: waited for bytes" << dendl;
+  throttle.get(count);
 }
 
 void FileJournal::get_header(
diff --git a/src/os/filestore/FileJournal.h b/src/os/filestore/FileJournal.h
index 92d8b4b..0c50e89 100644
--- a/src/os/filestore/FileJournal.h
+++ b/src/os/filestore/FileJournal.h
@@ -24,6 +24,8 @@ using std::deque;
 #include "common/Mutex.h"
 #include "common/Thread.h"
 #include "common/Throttle.h"
+#include "JournalThrottle.h"
+
 
 #ifdef HAVE_LIBAIO
 # include <libaio.h>
@@ -32,9 +34,11 @@ using std::deque;
 /**
  * Implements journaling on top of block device or file.
  *
- * Lock ordering is write_lock > aio_lock > finisher_lock
+ * Lock ordering is write_lock > aio_lock > (completions_lock | finisher_lock)
  */
-class FileJournal : public Journal {
+class FileJournal :
+  public Journal,
+  public md_config_obs_t {
 public:
   /// Protected by finisher_lock
   struct completion_item {
@@ -265,6 +269,8 @@ private:
   io_context_t aio_ctx;
   list<aio_info> aio_queue;
   int aio_num, aio_bytes;
+  uint64_t aio_write_queue_ops;
+  uint64_t aio_write_queue_bytes;
   /// End protected by aio_lock
 #endif
 
@@ -293,9 +299,23 @@ private:
 
 
   // throttle
-  Throttle throttle_ops, throttle_bytes;
+  int set_throttle_params();
+  const char** get_tracked_conf_keys() const override;
+  void handle_conf_change(
+    const struct md_config_t *conf,
+    const std::set <std::string> &changed) override {
+    for (const char **i = get_tracked_conf_keys();
+	 *i;
+	 ++i) {
+      if (changed.count(string(*i))) {
+	set_throttle_params();
+	return;
+      }
+    }
+  }
 
-  void put_throttle(uint64_t ops, uint64_t bytes);
+  void complete_write(uint64_t ops, uint64_t bytes);
+  JournalThrottle throttle;
 
   // write thread
   Mutex write_lock;
@@ -388,14 +408,15 @@ private:
     aio_lock("FileJournal::aio_lock"),
     aio_ctx(0),
     aio_num(0), aio_bytes(0),
+    aio_write_queue_ops(0),
+    aio_write_queue_bytes(0),
 #endif
     last_committed_seq(0),
     journaled_since_start(0),
     full_state(FULL_NOTFULL),
     fd(-1),
     writing_seq(0),
-    throttle_ops(g_ceph_context, "journal_ops", g_conf->journal_queue_max_ops),
-    throttle_bytes(g_ceph_context, "journal_bytes", g_conf->journal_queue_max_bytes),
+    throttle(g_conf->filestore_caller_concurrency),
     write_lock("FileJournal::write_lock", false, true, false, g_ceph_context),
     write_stop(true),
     aio_stop(true),
@@ -412,10 +433,13 @@ private:
         aio = false;
       }
 #endif
+
+      g_conf->add_observer(this);
   }
   ~FileJournal() {
     assert(fd == -1);
     delete[] zero_buf;
+    g_conf->remove_observer(this);
   }
 
   int check();
@@ -430,7 +454,7 @@ private:
 
   void flush();
 
-  void throttle();
+  void reserve_throttle_and_backoff(uint64_t count);
 
   bool is_writeable() {
     return read_pos == 0;
diff --git a/src/os/filestore/FileStore.cc b/src/os/filestore/FileStore.cc
index 1390b02..6677c86 100644
--- a/src/os/filestore/FileStore.cc
+++ b/src/os/filestore/FileStore.cc
@@ -240,6 +240,9 @@ int FileStore::lfn_open(const coll_t& cid,
 
   if (create)
     flags |= O_CREAT;
+  if (g_conf->filestore_odsync_write) {
+    flags |= O_DSYNC;
+  }
 
   Index index2;
   if (!index) {
@@ -464,7 +467,9 @@ int FileStore::lfn_unlink(const coll_t& cid, const ghobject_t& o,
 
     if (!force_clear_omap) {
       if (hardlink == 0) {
-	  wbthrottle.clear_object(o); // should be only non-cache ref
+          if (!m_disable_wbthrottle) {
+	    wbthrottle.clear_object(o); // should be only non-cache ref
+          }
 	  fdcache.clear(o);
 	  return 0;
       } else if (hardlink == 1) {
@@ -483,7 +488,9 @@ int FileStore::lfn_unlink(const coll_t& cid, const ghobject_t& o,
       if (g_conf->filestore_debug_inject_read_err) {
 	debug_obj_on_delete(o);
       }
-      wbthrottle.clear_object(o); // should be only non-cache ref
+      if (!m_disable_wbthrottle) {
+        wbthrottle.clear_object(o); // should be only non-cache ref
+      }
       fdcache.clear(o);
     } else {
       /* Ensure that replay of this op doesn't result in the object_map
@@ -519,8 +526,10 @@ FileStore::FileStore(const std::string &base, const std::string &jdev, osflagbit
   fdcache(g_ceph_context),
   wbthrottle(g_ceph_context),
   next_osr_id(0),
-  throttle_ops(g_ceph_context, "filestore_ops", g_conf->filestore_queue_max_ops),
-  throttle_bytes(g_ceph_context, "filestore_bytes", g_conf->filestore_queue_max_bytes),
+  m_disable_wbthrottle(g_conf->filestore_odsync_write || 
+                      !g_conf->filestore_wbthrottle_enable),
+  throttle_ops(g_conf->filestore_caller_concurrency),
+  throttle_bytes(g_conf->filestore_caller_concurrency),
   m_ondisk_finisher_num(g_conf->filestore_ondisk_finisher_threads),
   m_apply_finisher_num(g_conf->filestore_apply_finisher_threads),
   op_tp(g_ceph_context, "FileStore::op_tp", "tp_fstore_op", g_conf->filestore_op_threads, "filestore_op_threads"),
@@ -543,10 +552,6 @@ FileStore::FileStore(const std::string &base, const std::string &jdev, osflagbit
   m_journal_force_aio(g_conf->journal_force_aio),
   m_osd_rollback_to_cluster_snap(g_conf->osd_rollback_to_cluster_snap),
   m_osd_use_stale_snap(g_conf->osd_use_stale_snap),
-  m_filestore_queue_max_ops(g_conf->filestore_queue_max_ops),
-  m_filestore_queue_max_bytes(g_conf->filestore_queue_max_bytes),
-  m_filestore_queue_committing_max_ops(g_conf->filestore_queue_committing_max_ops),
-  m_filestore_queue_committing_max_bytes(g_conf->filestore_queue_committing_max_bytes),
   m_filestore_do_dump(false),
   m_filestore_dump_fmt(true),
   m_filestore_sloppy_crc(g_conf->filestore_sloppy_crc),
@@ -585,10 +590,8 @@ FileStore::FileStore(const std::string &base, const std::string &jdev, osflagbit
   // initialize logger
   PerfCountersBuilder plb(g_ceph_context, internal_name, l_os_first, l_os_last);
 
-  plb.add_u64(l_os_jq_max_ops, "journal_queue_max_ops", "Max operations in journal queue");
   plb.add_u64(l_os_jq_ops, "journal_queue_ops", "Operations in journal queue");
   plb.add_u64_counter(l_os_j_ops, "journal_ops", "Total journal entries written");
-  plb.add_u64(l_os_jq_max_bytes, "journal_queue_max_bytes", "Max data in journal queue");
   plb.add_u64(l_os_jq_bytes, "journal_queue_bytes", "Size of journal queue");
   plb.add_u64_counter(l_os_j_bytes, "journal_bytes", "Total operations size in journal");
   plb.add_time_avg(l_os_j_lat, "journal_latency", "Average journal queue completing latency");
@@ -692,6 +695,7 @@ int FileStore::statfs(struct statfs *buf)
   if (::statfs(basedir.c_str(), buf) < 0) {
     int r = -errno;
     assert(!m_filestore_fail_eio || r != -EIO);
+    assert(r != -ENOENT);
     return r;
   }
   return 0;
@@ -757,7 +761,9 @@ void FileStore::create_backend(long f_type)
   switch (f_type) {
 #if defined(__linux__)
   case BTRFS_SUPER_MAGIC:
-    wbthrottle.set_fs(WBThrottle::BTRFS);
+    if (!m_disable_wbthrottle){
+      wbthrottle.set_fs(WBThrottle::BTRFS);
+    }
     break;
 
   case XFS_SUPER_MAGIC:
@@ -877,16 +883,17 @@ int FileStore::mkfs()
     uint64_t initial_seq = 0;
     int fd = read_op_seq(&initial_seq);
     if (fd < 0) {
+      ret = fd;
       derr << "mkfs: failed to create " << current_op_seq_fn << ": "
-	   << cpp_strerror(fd) << dendl;
+	   << cpp_strerror(ret) << dendl;
       goto close_fsid_fd;
     }
     if (initial_seq == 0) {
-      int err = write_op_seq(fd, 1);
-      if (err < 0) {
+      ret = write_op_seq(fd, 1);
+      if (ret < 0) {
 	VOID_TEMP_FAILURE_RETRY(::close(fd));
 	derr << "mkfs: failed to write to " << current_op_seq_fn << ": "
-	     << cpp_strerror(err) << dendl;
+	     << cpp_strerror(ret) << dendl;
 	goto close_fsid_fd;
       }
 
@@ -1271,6 +1278,10 @@ int FileStore::mount()
 
   dout(5) << "basedir " << basedir << " journal " << journalpath << dendl;
 
+  ret = set_throttle_params();
+  if (ret != 0)
+    goto done;
+
   // make sure global base dir exists
   if (::access(basedir.c_str(), R_OK | W_OK)) {
     ret = -errno;
@@ -1332,7 +1343,6 @@ int FileStore::mount()
 
   ret = read_superblock();
   if (ret < 0) {
-    ret = -EINVAL;
     goto close_fsid_fd;
   }
 
@@ -1466,6 +1476,7 @@ int FileStore::mount()
 
   op_fd = read_op_seq(&initial_op_seq);
   if (op_fd < 0) {
+    ret = op_fd;
     derr << "FileStore::mount: read_op_seq failed" << dendl;
     goto close_current_fd;
   }
@@ -1482,6 +1493,7 @@ int FileStore::mount()
     // from it.
     int r = ::creat(nosnapfn, 0644);
     if (r < 0) {
+      ret = -errno;
       derr << "FileStore::mount: failed to create current/nosnap" << dendl;
       goto close_current_fd;
     }
@@ -1594,8 +1606,14 @@ int FileStore::mount()
       index->cleanup();
     }
   }
-
-  wbthrottle.start();
+  if (!m_disable_wbthrottle) {
+    wbthrottle.start();
+  } else {
+    dout(0) << "mount INFO: WbThrottle is disabled" << dendl;
+    if (g_conf->filestore_odsync_write) {
+      dout(0) << "mount INFO: O_DSYNC write is enabled" << dendl;
+    }
+  }
   sync_thread.create("filestore_sync");
 
   if (!(generic_flags & SKIP_JOURNAL_REPLAY)) {
@@ -1654,8 +1672,9 @@ stop_sync:
   sync_cond.Signal();
   lock.Unlock();
   sync_thread.join();
-
-  wbthrottle.stop();
+  if (!m_disable_wbthrottle) {
+    wbthrottle.stop();
+  }
 close_current_fd:
   VOID_TEMP_FAILURE_RETRY(::close(current_fd));
   current_fd = -1;
@@ -1722,7 +1741,9 @@ int FileStore::umount()
   sync_cond.Signal();
   lock.Unlock();
   sync_thread.join();
-  wbthrottle.stop();
+  if (!m_disable_wbthrottle){
+    wbthrottle.stop();
+  }
   op_tp.stop();
 
   journal_stop();
@@ -1819,32 +1840,10 @@ void FileStore::queue_op(OpSequencer *osr, Op *o)
   op_wq.queue(osr);
 }
 
-void FileStore::op_queue_reserve_throttle(Op *o, ThreadPool::TPHandle *handle)
+void FileStore::op_queue_reserve_throttle(Op *o)
 {
-  // Do not call while holding the journal lock!
-  uint64_t max_ops = m_filestore_queue_max_ops;
-  uint64_t max_bytes = m_filestore_queue_max_bytes;
-
-  if (backend->can_checkpoint() && is_committing()) {
-    max_ops += m_filestore_queue_committing_max_ops;
-    max_bytes += m_filestore_queue_committing_max_bytes;
-  }
-
-  logger->set(l_os_oq_max_ops, max_ops);
-  logger->set(l_os_oq_max_bytes, max_bytes);
-
-  if (handle)
-    handle->suspend_tp_timeout();
-  if (throttle_ops.should_wait(1) ||
-    (throttle_bytes.get_current()      // let single large ops through!
-    && throttle_bytes.should_wait(o->bytes))) {
-    dout(2) << "waiting " << throttle_ops.get_current() + 1 << " > " << max_ops << " ops || "
-      << throttle_bytes.get_current() + o->bytes << " > " << max_bytes << dendl;
-  }
   throttle_ops.get();
   throttle_bytes.get(o->bytes);
-  if (handle)
-    handle->reset_tp_timeout();
 
   logger->set(l_os_oq_ops, throttle_ops.get_current());
   logger->set(l_os_oq_bytes, throttle_bytes.get_current());
@@ -1860,7 +1859,9 @@ void FileStore::op_queue_release_throttle(Op *o)
 
 void FileStore::_do_op(OpSequencer *osr, ThreadPool::TPHandle &handle)
 {
-  wbthrottle.throttle();
+  if (!m_disable_wbthrottle) {
+    wbthrottle.throttle();
+  }
   // inject a stall?
   if (g_conf->filestore_inject_stall) {
     int orig = g_conf->filestore_inject_stall;
@@ -1965,11 +1966,20 @@ int FileStore::queue_transactions(Sequencer *posr, vector<Transaction>& tls,
 
   if (journal && journal->is_writeable() && !m_filestore_journal_trailing) {
     Op *o = build_op(tls, onreadable, onreadable_sync, osd_op);
-    op_queue_reserve_throttle(o, handle);
-    journal->throttle();
+
     //prepare and encode transactions data out of lock
     bufferlist tbl;
     int orig_len = journal->prepare_entry(o->tls, &tbl);
+
+    if (handle)
+      handle->suspend_tp_timeout();
+
+    op_queue_reserve_throttle(o);
+    journal->reserve_throttle_and_backoff(tbl.length());
+
+    if (handle)
+      handle->reset_tp_timeout();
+
     uint64_t op_num = submit_manager.op_submit_start();
     o->op = op_num;
 
@@ -2004,7 +2014,13 @@ int FileStore::queue_transactions(Sequencer *posr, vector<Transaction>& tls,
     Op *o = build_op(tls, onreadable, onreadable_sync, osd_op);
     dout(5) << __func__ << " (no journal) " << o << " " << tls << dendl;
 
-    op_queue_reserve_throttle(o, handle);
+    if (handle)
+      handle->suspend_tp_timeout();
+
+    op_queue_reserve_throttle(o);
+
+    if (handle)
+      handle->reset_tp_timeout();
 
     uint64_t op_num = submit_manager.op_submit_start();
     o->op = op_num;
@@ -2660,6 +2676,20 @@ void FileStore::_do_transaction(
       }
       break;
 
+    case Transaction::OP_TRY_RENAME:
+      {
+        coll_t oldcid = i.get_cid(op->cid);
+	coll_t newcid = oldcid;
+        ghobject_t oldoid = i.get_oid(op->oid);
+        ghobject_t newoid = i.get_oid(op->dest_oid);
+	_kludge_temp_object_collection(oldcid, oldoid);
+	_kludge_temp_object_collection(newcid, newoid);
+        tracepoint(objectstore, coll_try_rename_enter);
+        r = _collection_move_rename(oldcid, oldoid, newcid, newoid, spos, true);
+        tracepoint(objectstore, coll_try_rename_exit, r);
+      }
+      break;
+
     case Transaction::OP_COLL_SETATTR:
       {
         coll_t cid = i.get_cid(op->cid);
@@ -2942,7 +2972,7 @@ int FileStore::read(
     return r;
   }
 
-  if (len == 0) {
+  if (offset == 0 && len == 0) {
     struct stat st;
     memset(&st, 0, sizeof(struct stat));
     int r = ::fstat(**fd, &st);
@@ -2969,6 +2999,7 @@ int FileStore::read(
     return got;
   }
   bptr.set_length(got);   // properly size the buffer
+  bl.clear();
   bl.push_back(std::move(bptr));   // put it in the target bufferlist
 
 #ifdef HAVE_POSIX_FADVISE
@@ -2981,7 +3012,7 @@ int FileStore::read(
   if (m_filestore_sloppy_crc && (!replaying || backend->can_checkpoint())) {
     ostringstream ss;
     int errors = backend->_crc_verify_read(**fd, offset, got, bl, &ss);
-    if (errors > 0) {
+    if (errors != 0) {
       dout(0) << "FileStore::read " << cid << "/" << oid << " " << offset << "~"
 	      << got << " ... BAD CRC:\n" << ss.str() << dendl;
       assert(0 == "bad crc on read");
@@ -3194,8 +3225,6 @@ int FileStore::_write(const coll_t& cid, const ghobject_t& oid,
   dout(15) << "write " << cid << "/" << oid << " " << offset << "~" << len << dendl;
   int r;
 
-  int64_t actual;
-
   FDRef fd;
   r = lfn_open(cid, oid, true, &fd);
   if (r < 0) {
@@ -3205,23 +3234,8 @@ int FileStore::_write(const coll_t& cid, const ghobject_t& oid,
     goto out;
   }
 
-  // seek
-  actual = ::lseek64(**fd, offset, SEEK_SET);
-  if (actual < 0) {
-    r = -errno;
-    dout(0) << "write lseek64 to " << offset << " failed: " << cpp_strerror(r) << dendl;
-    lfn_close(fd);
-    goto out;
-  }
-  if (actual != (int64_t)offset) {
-    dout(0) << "write lseek64 to " << offset << " gave bad offset " << actual << dendl;
-    r = -EIO;
-    lfn_close(fd);
-    goto out;
-  }
-
   // write
-  r = bl.write_fd(**fd);
+  r = bl.write_fd(**fd, offset);
   if (r == 0)
     r = bl.length();
 
@@ -3229,12 +3243,16 @@ int FileStore::_write(const coll_t& cid, const ghobject_t& oid,
     int rc = backend->_crc_update_write(**fd, offset, len, bl);
     assert(rc >= 0);
   }
-
-  // flush?
-  if (!replaying &&
-      g_conf->filestore_wbthrottle_enable)
+ 
+  if (replaying || m_disable_wbthrottle) {
+    if (fadvise_flags & CEPH_OSD_OP_FLAG_FADVISE_DONTNEED) {
+        posix_fadvise(**fd, 0, 0, POSIX_FADV_DONTNEED);
+    }
+  } else {
     wbthrottle.queue_wb(fd, oid, offset, len,
-			  fadvise_flags & CEPH_OSD_OP_FLAG_FADVISE_DONTNEED);
+        fadvise_flags & CEPH_OSD_OP_FLAG_FADVISE_DONTNEED);
+  }
+ 
   lfn_close(fd);
 
  out:
@@ -3247,36 +3265,60 @@ int FileStore::_zero(const coll_t& cid, const ghobject_t& oid, uint64_t offset,
   dout(15) << "zero " << cid << "/" << oid << " " << offset << "~" << len << dendl;
   int ret = 0;
 
+  if (g_conf->filestore_punch_hole) {
 #ifdef CEPH_HAVE_FALLOCATE
 # if !defined(DARWIN) && !defined(__FreeBSD__)
-  // first try to punch a hole.
-  FDRef fd;
-  ret = lfn_open(cid, oid, false, &fd);
-  if (ret < 0) {
-    goto out;
-  }
+#    ifdef FALLOC_FL_KEEP_SIZE
+    // first try to punch a hole.
+    FDRef fd;
+    ret = lfn_open(cid, oid, false, &fd);
+    if (ret < 0) {
+      goto out;
+    }
 
-  // first try fallocate
-  ret = fallocate(**fd, FALLOC_FL_PUNCH_HOLE, offset, len);
-  if (ret < 0)
-    ret = -errno;
-  lfn_close(fd);
+    struct stat st;
+    ret = ::fstat(**fd, &st);
+    if (ret < 0) {
+      ret = -errno;
+      lfn_close(fd);
+      goto out;
+    }
 
-  if (ret >= 0 && m_filestore_sloppy_crc) {
-    int rc = backend->_crc_update_zero(**fd, offset, len);
-    assert(rc >= 0);
-  }
+    // first try fallocate
+    ret = fallocate(**fd, FALLOC_FL_KEEP_SIZE | FALLOC_FL_PUNCH_HOLE,
+		    offset, len);
+    if (ret < 0) {
+      ret = -errno;
+    } else {
+      // ensure we extent file size, if needed
+      if (offset + len > (uint64_t)st.st_size) {
+	ret = ::ftruncate(**fd, offset + len);
+	if (ret < 0) {
+	  ret = -errno;
+	  lfn_close(fd);
+	  goto out;
+	}
+      }
+    }
+    lfn_close(fd);
+
+    if (ret >= 0 && m_filestore_sloppy_crc) {
+      int rc = backend->_crc_update_zero(**fd, offset, len);
+      assert(rc >= 0);
+    }
 
-  if (ret == 0)
-    goto out;  // yay!
-  if (ret != -EOPNOTSUPP)
-    goto out;  // some other error
+    if (ret == 0)
+      goto out;  // yay!
+    if (ret != -EOPNOTSUPP)
+      goto out;  // some other error
+#    endif
 # endif
 #endif
+  }
 
   // lame, kernel is old and doesn't support it.
   // write zeros.. yuck!
-  dout(20) << "zero FALLOC_FL_PUNCH_HOLE not supported, falling back to writing zeros" << dendl;
+  dout(20) << "zero falling back to writing zeros" << dendl;
   {
     bufferlist bl;
     bl.append_zero(len);
@@ -3313,16 +3355,21 @@ int FileStore::_clone(const coll_t& cid, const ghobject_t& oldoid, const ghobjec
     }
     r = ::ftruncate(**n, 0);
     if (r < 0) {
+      r = -errno;
       goto out3;
     }
     struct stat st;
-    ::fstat(**o, &st);
-    r = _do_clone_range(**o, **n, 0, st.st_size, 0);
+    r = ::fstat(**o, &st);
     if (r < 0) {
       r = -errno;
       goto out3;
     }
 
+    r = _do_clone_range(**o, **n, 0, st.st_size, 0);
+    if (r < 0) {
+      goto out3;
+    }
+
     dout(20) << "objectmap clone" << dendl;
     r = object_map->clone(oldoid, newoid, &spos);
     if (r < 0 && r != -ENOENT)
@@ -3388,12 +3435,15 @@ int FileStore::_do_sparse_copy_range(int from, int to, uint64_t srcoff, uint64_t
     r = _do_fiemap(from, srcoff, len, &exomap);
   }
 
-  int64_t written = 0;
+ 
+ int64_t written = 0;
+ if (r < 0)
+    goto out;
+
   for (map<uint64_t, uint64_t>::iterator miter = exomap.begin(); miter != exomap.end(); ++miter) {
     uint64_t it_off = miter->first - srcoff + dstoff;
     r = _do_copy_range(from, to, miter->first, miter->second, it_off, true);
     if (r < 0) {
-      r = -errno;
       derr << "FileStore::_do_copy_range: copy error at " << miter->first << "~" << miter->second
              << " to " << it_off << ", " << cpp_strerror(r) << dendl;
       break;
@@ -3482,13 +3532,19 @@ int FileStore::_do_copy_range(int from, int to, uint64_t srcoff, uint64_t len, u
 
     actual = ::lseek64(from, srcoff, SEEK_SET);
     if (actual != (int64_t)srcoff) {
-      r = -errno;
+      if (actual < 0)
+        r = -errno;
+      else
+        r = -EINVAL;
       derr << "lseek64 to " << srcoff << " got " << cpp_strerror(r) << dendl;
       return r;
     }
     actual = ::lseek64(to, dstoff, SEEK_SET);
     if (actual != (int64_t)dstoff) {
-      r = -errno;
+      if (actual < 0)
+        r = -errno;
+      else
+        r = -EINVAL;
       derr << "lseek64 to " << dstoff << " got " << cpp_strerror(r) << dendl;
       return r;
     }
@@ -3730,7 +3786,9 @@ void FileStore::sync_entry()
       logger->tinc(l_os_commit_len, dur);
 
       apply_manager.commit_finish();
-      wbthrottle.clear();
+      if (!m_disable_wbthrottle) {
+        wbthrottle.clear();
+      }
 
       logger->set(l_os_committing, 0);
 
@@ -3901,7 +3959,6 @@ int FileStore::snapshot(const string& name)
 
   int r = backend->create_checkpoint(s, NULL);
   if (r) {
-    r = -errno;
     derr << "snapshot " << name << " failed: " << cpp_strerror(r) << dendl;
   }
 
@@ -4117,7 +4174,6 @@ int FileStore::getattrs(const coll_t& _cid, const ghobject_t& oid, map<string,bu
   if (r < 0) {
     goto out;
   }
-  lfn_close(fd);
 
   if (!spill_out) {
     dout(10) << __func__ << " no xattr exists in object_map r = " << r << dendl;
@@ -4338,8 +4394,10 @@ int FileStore::_rmattrs(const coll_t& cid, const ghobject_t& oid,
       char n[CHAIN_XATTR_MAX_NAME_LEN];
       get_attrname(p->first.c_str(), n, CHAIN_XATTR_MAX_NAME_LEN);
       r = chain_fremovexattr(**fd, n);
-      if (r < 0)
-	break;
+      if (r < 0) {
+        dout(10) << __func__ << " could not remove xattr r = " << r << dendl;
+	goto out_close;
+      }
     }
   }
 
@@ -5088,7 +5146,8 @@ int FileStore::_collection_add(const coll_t& c, const coll_t& oldcid, const ghob
 
 int FileStore::_collection_move_rename(const coll_t& oldcid, const ghobject_t& oldoid,
 				       coll_t c, const ghobject_t& o,
-				       const SequencerPosition& spos)
+				       const SequencerPosition& spos,
+				       bool allow_enoent)
 {
   dout(15) << __func__ << " " << c << "/" << o << " from " << oldcid << "/" << oldoid << dendl;
   int r = 0;
@@ -5120,9 +5179,16 @@ int FileStore::_collection_move_rename(const coll_t& oldcid, const ghobject_t& o
     if (r < 0) {
       // the source collection/object does not exist. If we are replaying, we
       // should be safe, so just return 0 and move on.
-      assert(replaying);
-      dout(10) << __func__ << " " << c << "/" << o << " from "
-	       << oldcid << "/" << oldoid << " (dne, continue replay) " << dendl;
+      if (replaying) {
+	dout(10) << __func__ << " " << c << "/" << o << " from "
+		 << oldcid << "/" << oldoid << " (dne, continue replay) " << dendl;
+      } else if (allow_enoent) {
+	dout(10) << __func__ << " " << c << "/" << o << " from "
+		 << oldcid << "/" << oldoid << " (dne, ignoring enoent)"
+		 << dendl;
+      } else {
+	assert(0 == "ERROR: source must exist");
+      }
       return 0;
     }
     if (dstcmp > 0) {      // if dstcmp == 0 the guard already says "in-progress"
@@ -5435,8 +5501,13 @@ const char** FileStore::get_tracked_conf_keys() const
     "filestore_max_sync_interval",
     "filestore_queue_max_ops",
     "filestore_queue_max_bytes",
-    "filestore_queue_committing_max_ops",
-    "filestore_queue_committing_max_bytes",
+    "filestore_queue_max_ops",
+    "filestore_expected_throughput_bytes",
+    "filestore_expected_throughput_ops",
+    "filestore_queue_low_threshhold",
+    "filestore_queue_high_threshhold",
+    "filestore_queue_high_delay_multiple",
+    "filestore_queue_max_delay_multiple",
     "filestore_commit_timeout",
     "filestore_dump_file",
     "filestore_kill_at",
@@ -5464,12 +5535,21 @@ void FileStore::handle_conf_change(const struct md_config_t *conf,
     Mutex::Locker l(lock);
     set_xattr_limits_via_conf();
   }
+
+  if (changed.count("filestore_queue_max_bytes") ||
+      changed.count("filestore_queue_max_ops") ||
+      changed.count("filestore_expected_throughput_bytes") ||
+      changed.count("filestore_expected_throughput_ops") ||
+      changed.count("filestore_queue_low_threshhold") ||
+      changed.count("filestore_queue_high_threshhold") ||
+      changed.count("filestore_queue_high_delay_multiple") ||
+      changed.count("filestore_queue_max_delay_multiple")) {
+    Mutex::Locker l(lock);
+    set_throttle_params();
+  }
+
   if (changed.count("filestore_min_sync_interval") ||
       changed.count("filestore_max_sync_interval") ||
-      changed.count("filestore_queue_max_ops") ||
-      changed.count("filestore_queue_max_bytes") ||
-      changed.count("filestore_queue_committing_max_ops") ||
-      changed.count("filestore_queue_committing_max_bytes") ||
       changed.count("filestore_kill_at") ||
       changed.count("filestore_fail_eio") ||
       changed.count("filestore_sloppy_crc") ||
@@ -5479,18 +5559,12 @@ void FileStore::handle_conf_change(const struct md_config_t *conf,
     Mutex::Locker l(lock);
     m_filestore_min_sync_interval = conf->filestore_min_sync_interval;
     m_filestore_max_sync_interval = conf->filestore_max_sync_interval;
-    m_filestore_queue_max_ops = conf->filestore_queue_max_ops;
-    m_filestore_queue_max_bytes = conf->filestore_queue_max_bytes;
-    m_filestore_queue_committing_max_ops = conf->filestore_queue_committing_max_ops;
-    m_filestore_queue_committing_max_bytes = conf->filestore_queue_committing_max_bytes;
     m_filestore_kill_at.set(conf->filestore_kill_at);
     m_filestore_fail_eio = conf->filestore_fail_eio;
     m_filestore_fadvise = conf->filestore_fadvise;
     m_filestore_sloppy_crc = conf->filestore_sloppy_crc;
     m_filestore_sloppy_crc_block_size = conf->filestore_sloppy_crc_block_size;
     m_filestore_max_alloc_hint_size = conf->filestore_max_alloc_hint_size;
-    throttle_ops.reset_max(conf->filestore_queue_max_ops);
-    throttle_bytes.reset_max(conf->filestore_queue_max_bytes);
   }
   if (changed.count("filestore_commit_timeout")) {
     Mutex::Locker l(sync_entry_timeo_lock);
@@ -5506,6 +5580,38 @@ void FileStore::handle_conf_change(const struct md_config_t *conf,
   }
 }
 
+int FileStore::set_throttle_params()
+{
+  stringstream ss;
+  bool valid = throttle_bytes.set_params(
+    g_conf->filestore_queue_low_threshhold,
+    g_conf->filestore_queue_high_threshhold,
+    g_conf->filestore_expected_throughput_bytes,
+    g_conf->filestore_queue_high_delay_multiple,
+    g_conf->filestore_queue_max_delay_multiple,
+    g_conf->filestore_queue_max_bytes,
+    &ss);
+
+  valid &= throttle_ops.set_params(
+    g_conf->filestore_queue_low_threshhold,
+    g_conf->filestore_queue_high_threshhold,
+    g_conf->filestore_expected_throughput_ops,
+    g_conf->filestore_queue_high_delay_multiple,
+    g_conf->filestore_queue_max_delay_multiple,
+    g_conf->filestore_queue_max_ops,
+    &ss);
+
+  logger->set(l_os_oq_max_ops, throttle_ops.get_max());
+  logger->set(l_os_oq_max_bytes, throttle_bytes.get_max());
+
+  if (!valid) {
+    derr << "tried to set invalid params: "
+	 << ss.str()
+	 << dendl;
+  }
+  return valid ? 0 : -EINVAL;
+}
+
 void FileStore::dump_start(const std::string& file)
 {
   dout(10) << "dump_start " << file << dendl;
diff --git a/src/os/filestore/FileStore.h b/src/os/filestore/FileStore.h
index 3e4e11f..d81f8b0 100644
--- a/src/os/filestore/FileStore.h
+++ b/src/os/filestore/FileStore.h
@@ -340,8 +340,9 @@ private:
   WBThrottle wbthrottle;
 
   atomic_t next_osr_id;
+  bool m_disable_wbthrottle;
   deque<OpSequencer*> op_queue;
-  Throttle throttle_ops, throttle_bytes;
+  BackoffThrottle throttle_ops, throttle_bytes;
   const int m_ondisk_finisher_num;
   const int m_apply_finisher_num;
   vector<Finisher*> ondisk_finishers;
@@ -387,7 +388,7 @@ private:
 	       Context *onreadable, Context *onreadable_sync,
 	       TrackedOpRef osd_op);
   void queue_op(OpSequencer *osr, Op *o);
-  void op_queue_reserve_throttle(Op *o, ThreadPool::TPHandle *handle = NULL);
+  void op_queue_reserve_throttle(Op *o);
   void op_queue_release_throttle(Op *o);
   void _journaled_ahead(OpSequencer *osr, Op *o, Context *ondisk);
   friend struct C_JournaledAhead;
@@ -675,7 +676,8 @@ public:
 		      const SequencerPosition& spos);
   int _collection_move_rename(const coll_t& oldcid, const ghobject_t& oldoid,
 			      coll_t c, const ghobject_t& o,
-			      const SequencerPosition& spos);
+			      const SequencerPosition& spos,
+			      bool ignore_enoent = false);
 
   int _set_alloc_hint(const coll_t& cid, const ghobject_t& oid,
                       uint64_t expected_object_size,
@@ -710,6 +712,7 @@ private:
   virtual const char** get_tracked_conf_keys() const;
   virtual void handle_conf_change(const struct md_config_t *conf,
 			  const std::set <std::string> &changed);
+  int set_throttle_params();
   float m_filestore_commit_timeout;
   bool m_filestore_journal_parallel;
   bool m_filestore_journal_trailing;
@@ -723,10 +726,6 @@ private:
   bool m_journal_dio, m_journal_aio, m_journal_force_aio;
   std::string m_osd_rollback_to_cluster_snap;
   bool m_osd_use_stale_snap;
-  int m_filestore_queue_max_ops;
-  int m_filestore_queue_max_bytes;
-  int m_filestore_queue_committing_max_ops;
-  int m_filestore_queue_committing_max_bytes;
   bool m_filestore_do_dump;
   std::ofstream m_filestore_dump;
   JSONFormatter m_filestore_dump_fmt;
diff --git a/src/os/filestore/Journal.h b/src/os/filestore/Journal.h
index 236e431..ca30da4 100644
--- a/src/os/filestore/Journal.h
+++ b/src/os/filestore/Journal.h
@@ -49,7 +49,14 @@ public:
   virtual void close() = 0;  ///< close an open journal
 
   virtual void flush() = 0;
-  virtual void throttle() = 0;
+
+  /**
+   * reserve_throttle_and_backoff
+   *
+   * Implementation may throttle or backoff based on ops
+   * reserved here but not yet released using committed_thru.
+   */
+  virtual void reserve_throttle_and_backoff(uint64_t count) = 0;
 
   virtual int dump(ostream& out) { return -EOPNOTSUPP; }
 
diff --git a/src/os/filestore/JournalThrottle.cc b/src/os/filestore/JournalThrottle.cc
new file mode 100644
index 0000000..4a100c6
--- /dev/null
+++ b/src/os/filestore/JournalThrottle.cc
@@ -0,0 +1,67 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+
+#include "JournalThrottle.h"
+#include "include/assert.h"
+
+bool JournalThrottle::set_params(
+  double _low_threshhold,
+  double _high_threshhold,
+  double _expected_throughput,
+  double _high_multiple,
+  double _max_multiple,
+  uint64_t _throttle_max,
+  std::ostream *errstream)
+{
+  return throttle.set_params(
+    _low_threshhold,
+    _high_threshhold,
+    _expected_throughput,
+    _high_multiple,
+    _max_multiple,
+    _throttle_max,
+    errstream);
+}
+
+std::chrono::duration<double> JournalThrottle::get(uint64_t c)
+{
+  return throttle.get(c);
+}
+
+uint64_t JournalThrottle::take(uint64_t c)
+{
+  return throttle.take(c);
+}
+
+void JournalThrottle::register_throttle_seq(uint64_t seq, uint64_t c)
+{
+  locker l(lock);
+  journaled_ops.push_back(std::make_pair(seq, c));
+}
+
+std::pair<uint64_t, uint64_t> JournalThrottle::flush(uint64_t mono_id)
+{
+  uint64_t to_put_bytes = 0;
+  uint64_t to_put_ops = 0;
+  {
+    locker l(lock);
+    while (!journaled_ops.empty() &&
+	   journaled_ops.front().first <= mono_id) {
+      to_put_bytes += journaled_ops.front().second;
+      to_put_ops++;
+      journaled_ops.pop_front();
+    }
+  }
+  throttle.put(to_put_bytes);
+  return make_pair(to_put_ops, to_put_bytes);
+}
+
+uint64_t JournalThrottle::get_current()
+{
+  return throttle.get_current();
+}
+
+uint64_t JournalThrottle::get_max()
+{
+  return throttle.get_max();
+}
diff --git a/src/os/filestore/JournalThrottle.h b/src/os/filestore/JournalThrottle.h
new file mode 100644
index 0000000..8a7ce72
--- /dev/null
+++ b/src/os/filestore/JournalThrottle.h
@@ -0,0 +1,101 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+
+#ifndef CEPH_JOURNAL_THROTTLE_H
+#define CEPH_JOURNAL_THROTTLE_H
+
+#include "common/Throttle.h"
+
+#include <list>
+#include <deque>
+#include <condition_variable>
+#include <thread>
+#include <vector>
+#include <chrono>
+#include <iostream>
+
+/**
+ * JournalThrottle
+ *
+ * Throttle designed to implement dynamic throttling as the journal fills
+ * up.  The goal is to not delay ops at all when the journal is relatively
+ * empty, delay ops somewhat as the journal begins to fill (with the delay
+ * getting linearly longer as the journal fills up to a high water mark),
+ * and to delay much more aggressively (though still linearly with usage)
+ * until we hit the max value.
+ *
+ * The implementation simply wraps BackoffThrottle with a queue of
+ * journaled but not synced ops.
+ *
+ * The usage pattern is as follows:
+ * 1) Call get(seq, bytes) before taking the op_queue_throttle
+ * 2) Once the journal is flushed, flush(max_op_id_flushed)
+ */
+class JournalThrottle {
+  BackoffThrottle throttle;
+
+  std::mutex lock;
+  /// deque<id, count>
+  std::deque<std::pair<uint64_t, uint64_t> > journaled_ops;
+  using locker = std::unique_lock<std::mutex>;
+
+public:
+  /**
+   * set_params
+   *
+   * Sets params.  If the params are invalid, returns false
+   * and populates errstream (if non-null) with a user compreshensible
+   * explanation.
+   */
+  bool set_params(
+    double low_threshhold,
+    double high_threshhold,
+    double expected_throughput,
+    double high_multiple,
+    double max_multiple,
+    uint64_t throttle_max,
+    std::ostream *errstream);
+
+  /**
+   * gets specified throttle for id mono_id, waiting as necessary
+   *
+   * @param c [in] amount to take
+   * @return duration waited
+   */
+  std::chrono::duration<double> get(uint64_t c);
+
+  /**
+   * take
+   *
+   * Takes specified throttle without waiting
+   */
+  uint64_t take(uint64_t c);
+
+  /**
+   * register_throttle_seq
+   *
+   * Registers a sequence number with an amount of throttle to
+   * release upon flush()
+   *
+   * @param seq [in] seq
+   */
+  void register_throttle_seq(uint64_t seq, uint64_t c);
+
+
+  /**
+   * Releases throttle held by ids <= mono_id
+   *
+   * @param mono_id [in] id up to which to flush
+   * @returns pair<ops_flushed, bytes_flushed>
+   */
+  std::pair<uint64_t, uint64_t> flush(uint64_t mono_id);
+
+  uint64_t get_current();
+  uint64_t get_max();
+
+  JournalThrottle(
+    unsigned expected_concurrency ///< [in] determines size of conds
+    ) : throttle(expected_concurrency) {}
+};
+
+#endif
diff --git a/src/os/filestore/JournalingObjectStore.cc b/src/os/filestore/JournalingObjectStore.cc
index 100ae66..a3fbb97 100644
--- a/src/os/filestore/JournalingObjectStore.cc
+++ b/src/os/filestore/JournalingObjectStore.cc
@@ -92,10 +92,14 @@ int JournalingObjectStore::journal_replay(uint64_t fs_op_seq)
     apply_manager.op_apply_finish(seq);
 
     op_seq = seq;
+    count++;
 
     dout(3) << "journal_replay: r = " << r << ", op_seq now " << op_seq << dendl;
   }
 
+  if (count)
+    dout(3) << "journal_replay: total = " << count << dendl;
+
   replaying = false;
 
   submit_manager.set_op_seq(op_seq);
diff --git a/src/os/filestore/LFNIndex.cc b/src/os/filestore/LFNIndex.cc
index 4cc09c3..47436ea 100644
--- a/src/os/filestore/LFNIndex.cc
+++ b/src/os/filestore/LFNIndex.cc
@@ -89,8 +89,19 @@ int LFNIndex::created(const ghobject_t &oid, const char *path)
   if (r < 0)
     goto out;
   r = lfn_created(path_comp, oid, short_name);
-  if (r < 0)
+  if (r < 0) {
+    if (failed) {
+      /* This is hacky, but the only way we get ENOENT from lfn_created here is
+       * if we did a failure injection in _created below AND actually started the
+       * split or merge.  In that case, lfn_created already suceeded, and
+       * WRAP_RETRY already cleaned it up and we are actually done.  In a real
+       * failure, the filestore itself would have ended up calling this with
+       * the new path, not the old one, so we'd find it.
+       */
+      r = 0;
+    }
     goto out;
+  }
   r = _created(path_comp, oid, short_name);
   if (r < 0)
     goto out;
@@ -124,7 +135,7 @@ int LFNIndex::lookup(const ghobject_t &oid,
   if (r < 0)
     goto out;
   string full_path = get_full_path(path, short_name);
-  *out_path = IndexedPath(new Path(full_path, this));
+  *out_path = std::make_shared<Path>(full_path, this);
   r = 0;
   );
 }
@@ -924,10 +935,26 @@ int LFNIndex::lfn_translate(const vector<string> &path,
   if (!lfn_is_hashed_filename(short_name)) {
     return lfn_parse_object_name(short_name, out);
   }
-  // Get lfn_attr
   string full_path = get_full_path(path, short_name);
   char attr[PATH_MAX];
-  int r = chain_getxattr(full_path.c_str(), get_lfn_attr().c_str(), attr, sizeof(attr) - 1);
+  // First, check alt attr
+  int r = chain_getxattr(
+    full_path.c_str(),
+    get_alt_lfn_attr().c_str(),
+    attr,
+    sizeof(attr) - 1);
+  if (r >= 0) {
+    // There is an alt attr, does it match?
+    if (r < (int)sizeof(attr))
+      attr[r] = '\0';
+    if (short_name_matches(short_name.c_str(), attr)) {
+      string long_name(attr);
+      return lfn_parse_object_name(long_name, out);
+    }
+  }
+
+  // Get lfn_attr
+  r = chain_getxattr(full_path.c_str(), get_lfn_attr().c_str(), attr, sizeof(attr) - 1);
   if (r < 0)
     return -errno;
   if (r < (int)sizeof(attr))
@@ -1284,6 +1311,28 @@ void LFNIndex::build_filename(const char *old_filename, int i, char *filename, i
   }
 }
 
+bool LFNIndex::short_name_matches(const char *short_name, const char *cand_long_name)
+{
+  const char *end = short_name;
+  while (*end) ++end;
+  const char *suffix = end;
+  if (suffix > short_name)  --suffix;                   // last char
+  while (suffix > short_name && *suffix != '_') --suffix; // back to first _
+  if (suffix > short_name) --suffix;                   // one behind that
+  while (suffix > short_name && *suffix != '_') --suffix; // back to second _
+
+  int index = -1;
+  char buf[FILENAME_SHORT_LEN + 4];
+  assert((end - suffix) < (int)sizeof(buf));
+  int r = sscanf(suffix, "_%d_%s", &index, buf);
+  if (r < 2)
+    return false;
+  if (strcmp(buf, FILENAME_COOKIE.c_str()) != 0)
+    return false;
+  build_filename(cand_long_name, index, buf, sizeof(buf));
+  return strcmp(short_name, buf) == 0;
+}
+
 string LFNIndex::lfn_get_short_name(const ghobject_t &oid, int i)
 {
   string long_name = lfn_generate_object_name(oid);
diff --git a/src/os/filestore/LFNIndex.h b/src/os/filestore/LFNIndex.h
index 8f04407..1cf4f0b 100644
--- a/src/os/filestore/LFNIndex.h
+++ b/src/os/filestore/LFNIndex.h
@@ -556,6 +556,12 @@ private:
     const string &attr ///< [in] Attribute to mangle.
     ); ///< @return Mangled attribute name.
 
+  /// checks whether long_name could hash to short_name
+  bool short_name_matches(
+    const char *short_name,    ///< [in] name to check against
+    const char *cand_long_name ///< [in] candidate long name
+    );
+
   /// Builds hashed filename
   void build_filename(
     const char *old_filename, ///< [in] Filename to convert.
diff --git a/src/os/kstore/KStore.cc b/src/os/kstore/KStore.cc
index 7de1b16..a2250d8 100644
--- a/src/os/kstore/KStore.cc
+++ b/src/os/kstore/KStore.cc
@@ -403,21 +403,12 @@ static void get_omap_tail(uint64_t id, string *out)
 #undef dout_prefix
 #define dout_prefix *_dout << "kstore.onode(" << this << ") "
 
-KStore::Onode::Onode(const ghobject_t& o, const string& k)
-  : nref(0),
-    oid(o),
-    key(k),
-    dirty(false),
-    exists(true),
-    flush_lock("KStore::Onode::flush_lock") {
-}
-
 void KStore::Onode::flush()
 {
-  Mutex::Locker l(flush_lock);
+  std::unique_lock<std::mutex> l(flush_lock);
   dout(20) << __func__ << " " << flush_txns << dendl;
   while (!flush_txns.empty())
-    flush_cond.Wait(flush_lock);
+    flush_cond.wait(l);
   dout(20) << __func__ << " done" << dendl;
 }
 
@@ -435,7 +426,7 @@ void KStore::OnodeHashLRU::_touch(OnodeRef o)
 
 void KStore::OnodeHashLRU::add(const ghobject_t& oid, OnodeRef o)
 {
-  Mutex::Locker l(lock);
+  std::lock_guard<std::mutex> l(lock);
   dout(30) << __func__ << " " << oid << " " << o << dendl;
   assert(onode_map.count(oid) == 0);
   onode_map[oid] = o;
@@ -444,7 +435,7 @@ void KStore::OnodeHashLRU::add(const ghobject_t& oid, OnodeRef o)
 
 KStore::OnodeRef KStore::OnodeHashLRU::lookup(const ghobject_t& oid)
 {
-  Mutex::Locker l(lock);
+  std::lock_guard<std::mutex> l(lock);
   dout(30) << __func__ << dendl;
   ceph::unordered_map<ghobject_t,OnodeRef>::iterator p = onode_map.find(oid);
   if (p == onode_map.end()) {
@@ -458,30 +449,16 @@ KStore::OnodeRef KStore::OnodeHashLRU::lookup(const ghobject_t& oid)
 
 void KStore::OnodeHashLRU::clear()
 {
-  Mutex::Locker l(lock);
+  std::lock_guard<std::mutex> l(lock);
   dout(10) << __func__ << dendl;
   lru.clear();
   onode_map.clear();
 }
 
-void KStore::OnodeHashLRU::remove(const ghobject_t& oid)
-{
-  Mutex::Locker l(lock);
-  ceph::unordered_map<ghobject_t,OnodeRef>::iterator p = onode_map.find(oid);
-  if (p == onode_map.end()) {
-    dout(30) << __func__ << " " << oid << " miss" << dendl;
-    return;
-  }
-  dout(30) << __func__ << " " << oid << " hit " << p->second << dendl;
-  lru_list_t::iterator pi = lru.iterator_to(*p->second);
-  lru.erase(pi);
-  onode_map.erase(p);
-}
-
 void KStore::OnodeHashLRU::rename(const ghobject_t& old_oid,
 				    const ghobject_t& new_oid)
 {
-  Mutex::Locker l(lock);
+  std::lock_guard<std::mutex> l(lock);
   dout(30) << __func__ << " " << old_oid << " -> " << new_oid << dendl;
   ceph::unordered_map<ghobject_t,OnodeRef>::iterator po, pn;
   po = onode_map.find(old_oid);
@@ -497,7 +474,6 @@ void KStore::OnodeHashLRU::rename(const ghobject_t& old_oid,
 
   // install a non-existent onode it its place
   po->second.reset(new Onode(old_oid, o->key));
-  po->second->exists = false;
   lru.push_back(*po->second);
 
   // fix oid, key
@@ -511,7 +487,7 @@ bool KStore::OnodeHashLRU::get_next(
   const ghobject_t& after,
   pair<ghobject_t,OnodeRef> *next)
 {
-  Mutex::Locker l(lock);
+  std::lock_guard<std::mutex> l(lock);
   dout(20) << __func__ << " after " << after << dendl;
 
   if (after == ghobject_t()) {
@@ -539,7 +515,7 @@ bool KStore::OnodeHashLRU::get_next(
 
 int KStore::OnodeHashLRU::trim(int max)
 {
-  Mutex::Locker l(lock);
+  std::lock_guard<std::mutex> l(lock);
   dout(20) << __func__ << " max " << max
 	   << " size " << onode_map.size() << dendl;
   int trimmed = 0;
@@ -552,7 +528,7 @@ int KStore::OnodeHashLRU::trim(int max)
     --p;
   while (num > 0) {
     Onode *o = &*p;
-    int refs = o->nref.read();
+    int refs = o->nref.load();
     if (refs > 1) {
       dout(20) << __func__ << "  " << o->oid << " has " << refs
 	       << " refs; stopping with " << num << " left to trim" << dendl;
@@ -630,6 +606,7 @@ KStore::OnodeRef KStore::Collection::get_onode(
     // loaded
     assert(r >=0);
     on = new Onode(oid, key);
+    on->exists = true;
     bufferlist::iterator p = v.begin();
     ::decode(on->onode, p);
   }
@@ -653,16 +630,13 @@ KStore::KStore(CephContext *cct, const string& path)
     fsid_fd(-1),
     mounted(false),
     coll_lock("KStore::coll_lock"),
-    nid_lock("KStore::nid_lock"),
     nid_max(0),
     throttle_ops(cct, "kstore_max_ops", cct->_conf->kstore_max_ops),
     throttle_bytes(cct, "kstore_max_bytes", cct->_conf->kstore_max_bytes),
     finisher(cct),
     kv_sync_thread(this),
-    kv_lock("KStore::kv_lock"),
     kv_stop(false),
-    logger(NULL),
-    reap_lock("KStore::reap_lock")
+    logger(NULL)
 {
   _init_logger();
 }
@@ -678,11 +652,22 @@ KStore::~KStore()
 void KStore::_init_logger()
 {
   // XXX
+  PerfCountersBuilder b(g_ceph_context, "KStore",
+                        l_kstore_first, l_kstore_last);
+  b.add_time_avg(l_kstore_state_prepare_lat, "state_prepare_lat", "Average prepare state latency");
+  b.add_time_avg(l_kstore_state_kv_queued_lat, "state_kv_queued_lat", "Average kv_queued state latency");
+  b.add_time_avg(l_kstore_state_kv_done_lat, "state_kv_done_lat", "Average kv_done state latency");
+  b.add_time_avg(l_kstore_state_finishing_lat, "state_finishing_lat", "Average finishing state latency");
+  b.add_time_avg(l_kstore_state_done_lat, "state_done_lat", "Average done state latency");
+  logger = b.create_perf_counters();
+  g_ceph_context->get_perfcounters_collection()->add(logger);
 }
 
 void KStore::_shutdown_logger()
 {
   // XXX
+  g_ceph_context->get_perfcounters_collection()->remove(logger);
+  delete logger;
 }
 
 int KStore::_open_path()
@@ -722,6 +707,7 @@ int KStore::_open_fsid(bool create)
 int KStore::_read_fsid(uuid_d *uuid)
 {
   char fsid_str[40];
+  memset(fsid_str, 0, sizeof(fsid_str));
   int ret = safe_read(fsid_fd, fsid_str, sizeof(fsid_str));
   if (ret < 0) {
     derr << __func__ << " failed: " << cpp_strerror(ret) << dendl;
@@ -1378,13 +1364,12 @@ void KStore::_sync()
 {
   dout(10) << __func__ << dendl;
 
-  kv_lock.Lock();
+  std::unique_lock<std::mutex> l(kv_lock);
   while (!kv_committing.empty() ||
 	 !kv_queue.empty()) {
     dout(20) << " waiting for kv to commit" << dendl;
-    kv_sync_cond.Wait(kv_lock);
+    kv_sync_cond.wait(l);
   }
-  kv_lock.Unlock();
 
   dout(10) << __func__ << " done" << dendl;
 }
@@ -1409,17 +1394,15 @@ KStore::CollectionRef KStore::_get_collection(coll_t cid)
 void KStore::_queue_reap_collection(CollectionRef& c)
 {
   dout(10) << __func__ << " " << c->cid << dendl;
-  Mutex::Locker l(reap_lock);
+  std::lock_guard<std::mutex> l(reap_lock);
   removed_collections.push_back(c);
 }
 
 void KStore::_reap_collections()
 {
-  reap_lock.Lock();
-
   list<CollectionRef> removed_colls;
+  std::lock_guard<std::mutex> l(reap_lock);
   removed_colls.swap(removed_collections);
-  reap_lock.Unlock();
 
   for (list<CollectionRef>::iterator p = removed_colls.begin();
        p != removed_colls.end();
@@ -2170,7 +2153,7 @@ void KStore::_assign_nid(TransContext *txc, OnodeRef o)
 {
   if (o->onode.nid)
     return;
-  Mutex::Locker l(nid_lock);
+  std::lock_guard<std::mutex> l(nid_lock);
   o->onode.nid = ++nid_last;
   dout(20) << __func__ << " " << o->oid << " nid " << o->onode.nid << dendl;
   if (nid_last > nid_max) {
@@ -2198,29 +2181,33 @@ void KStore::_txc_state_proc(TransContext *txc)
 	     << " " << txc->get_state_name() << dendl;
     switch (txc->state) {
     case TransContext::STATE_PREPARE:
+      txc->log_state_latency(logger, l_kstore_state_prepare_lat);
       txc->state = TransContext::STATE_KV_QUEUED;
       if (!g_conf->kstore_sync_transaction) {
-	Mutex::Locker l(kv_lock);
+	std::lock_guard<std::mutex> l(kv_lock);
 	if (g_conf->kstore_sync_submit_transaction) {
 	  db->submit_transaction(txc->t);
 	}
 	kv_queue.push_back(txc);
-	kv_cond.SignalOne();
+	kv_cond.notify_one();
 	return;
       }
       db->submit_transaction_sync(txc->t);
       break;
 
     case TransContext::STATE_KV_QUEUED:
+      txc->log_state_latency(logger, l_kstore_state_kv_queued_lat);
       txc->state = TransContext::STATE_KV_DONE;
       _txc_finish_kv(txc);
       // ** fall-thru **
 
     case TransContext::STATE_KV_DONE:
+      txc->log_state_latency(logger, l_kstore_state_kv_done_lat);
       txc->state = TransContext::STATE_FINISHING;
       break;
 
     case TransContext::TransContext::STATE_FINISHING:
+      txc->log_state_latency(logger, l_kstore_state_finishing_lat);
       _txc_finish(txc);
       return;
 
@@ -2247,7 +2234,7 @@ int KStore::_txc_finalize(OpSequencer *osr, TransContext *txc)
     dout(20) << " onode size is " << bl.length() << dendl;
     txc->t->set(PREFIX_OBJ, (*p)->key, bl);
 
-    Mutex::Locker l((*p)->flush_lock);
+    std::lock_guard<std::mutex> l((*p)->flush_lock);
     (*p)->flush_txns.insert(txc);
   }
 
@@ -2288,13 +2275,13 @@ void KStore::_txc_finish(TransContext *txc)
   for (set<OnodeRef>::iterator p = txc->onodes.begin();
        p != txc->onodes.end();
        ++p) {
-    Mutex::Locker l((*p)->flush_lock);
+    std::lock_guard<std::mutex> l((*p)->flush_lock);
     dout(20) << __func__ << " onode " << *p << " had " << (*p)->flush_txns
 	     << dendl;
     assert((*p)->flush_txns.count(txc));
     (*p)->flush_txns.erase(txc);
     if ((*p)->flush_txns.empty()) {
-      (*p)->flush_cond.Signal();
+      (*p)->flush_cond.notify_all();
       (*p)->clear_pending_stripes();
     }
   }
@@ -2308,16 +2295,17 @@ void KStore::_txc_finish(TransContext *txc)
   }
 
   OpSequencerRef osr = txc->osr;
-  osr->qlock.Lock();
-  txc->state = TransContext::STATE_DONE;
-  osr->qlock.Unlock();
+  {
+    std::lock_guard<std::mutex> l(osr->qlock);
+    txc->state = TransContext::STATE_DONE;
+  }
 
   _osr_reap_done(osr.get());
 }
 
 void KStore::_osr_reap_done(OpSequencer *osr)
 {
-  Mutex::Locker l(osr->qlock);
+  std::lock_guard<std::mutex> l(osr->qlock);
   dout(20) << __func__ << " osr " << osr << dendl;
   while (!osr->q.empty()) {
     TransContext *txc = &osr->q.front();
@@ -2332,8 +2320,9 @@ void KStore::_osr_reap_done(OpSequencer *osr)
     }
 
     osr->q.pop_front();
+    txc->log_state_latency(logger, l_kstore_state_done_lat);
     delete txc;
-    osr->qcond.Signal();
+    osr->qcond.notify_all();
     if (osr->q.empty())
       dout(20) << __func__ << " osr " << osr << " q now empty" << dendl;
   }
@@ -2342,21 +2331,21 @@ void KStore::_osr_reap_done(OpSequencer *osr)
 void KStore::_kv_sync_thread()
 {
   dout(10) << __func__ << " start" << dendl;
-  kv_lock.Lock();
+  std::unique_lock<std::mutex> l(kv_lock);
   while (true) {
     assert(kv_committing.empty());
     if (kv_queue.empty()) {
       if (kv_stop)
 	break;
       dout(20) << __func__ << " sleep" << dendl;
-      kv_sync_cond.Signal();
-      kv_cond.Wait(kv_lock);
+      kv_sync_cond.notify_all();
+      kv_cond.wait(l);
       dout(20) << __func__ << " wake" << dendl;
     } else {
       dout(20) << __func__ << " committing " << kv_queue.size() << dendl;
       kv_committing.swap(kv_queue);
       utime_t start = ceph_clock_now(NULL);
-      kv_lock.Unlock();
+      l.unlock();
 
       dout(30) << __func__ << " committing txc " << kv_committing << dendl;
 
@@ -2383,10 +2372,9 @@ void KStore::_kv_sync_thread()
       // this is as good a place as any ...
       _reap_collections();
 
-      kv_lock.Lock();
+      l.lock();
     }
   }
-  kv_lock.Unlock();
   dout(10) << __func__ << " finish" << dendl;
 }
 
@@ -2444,10 +2432,17 @@ int KStore::queue_transactions(
   return 0;
 }
 
-int KStore::_txc_add_transaction(TransContext *txc, Transaction *t)
+void KStore::_txc_add_transaction(TransContext *txc, Transaction *t)
 {
   Transaction::iterator i = t->begin();
-  int pos = 0;
+
+  dout(30) << __func__ << " transaction dump:\n";
+  JSONFormatter f(true);
+  f.open_object_section("transaction");
+  t->dump(&f);
+  f.close_section();
+  f.flush(*_dout);
+  *_dout << dendl;
 
   vector<CollectionRef> cvec(i.colls.size());
   unsigned j = 0;
@@ -2459,40 +2454,144 @@ int KStore::_txc_add_transaction(TransContext *txc, Transaction *t)
     if (!j && !txc->first_collection)
       txc->first_collection = cvec[j];
   }
+  vector<OnodeRef> ovec(i.objects.size());
 
-  while (i.have_op()) {
+  for (int pos = 0; i.have_op(); ++pos) {
     Transaction::Op *op = i.decode_op();
     int r = 0;
-    CollectionRef &c = cvec[op->cid];
 
+    // no coll or obj
+    if (op->op == Transaction::OP_NOP)
+      continue;
+
+    // collection operations
+    CollectionRef &c = cvec[op->cid];
     switch (op->op) {
-    case Transaction::OP_NOP:
+    case Transaction::OP_RMCOLL:
+      {
+        coll_t cid = i.get_cid(op->cid);
+	r = _remove_collection(txc, cid, &c);
+	if (!r)
+	  continue;
+      }
       break;
-    case Transaction::OP_TOUCH:
+
+    case Transaction::OP_MKCOLL:
+      {
+	assert(!c);
+        coll_t cid = i.get_cid(op->cid);
+	r = _create_collection(txc, cid, op->split_bits, &c);
+	if (!r)
+	  continue;
+      }
+      break;
+
+    case Transaction::OP_SPLIT_COLLECTION:
+      assert(0 == "deprecated");
+      break;
+
+    case Transaction::OP_SPLIT_COLLECTION2:
       {
-        const ghobject_t &oid = i.get_oid(op->oid);
-	r = _touch(txc, c, oid);
+        uint32_t bits = op->split_bits;
+        uint32_t rem = op->split_rem;
+	r = _split_collection(txc, c, cvec[op->dest_cid], bits, rem);
+	if (!r)
+	  continue;
       }
       break;
 
+    case Transaction::OP_COLL_HINT:
+      {
+        uint32_t type = op->hint_type;
+        bufferlist hint;
+        i.decode_bl(hint);
+        bufferlist::iterator hiter = hint.begin();
+        if (type == Transaction::COLL_HINT_EXPECTED_NUM_OBJECTS) {
+          uint32_t pg_num;
+          uint64_t num_objs;
+          ::decode(pg_num, hiter);
+          ::decode(num_objs, hiter);
+          dout(10) << __func__ << " collection hint objects is a no-op, "
+		   << " pg_num " << pg_num << " num_objects " << num_objs
+		   << dendl;
+        } else {
+          // Ignore the hint
+          dout(10) << __func__ << " unknown collection hint " << type << dendl;
+        }
+	continue;
+      }
+      break;
+
+    case Transaction::OP_COLL_SETATTR:
+      r = -EOPNOTSUPP;
+      break;
+
+    case Transaction::OP_COLL_RMATTR:
+      r = -EOPNOTSUPP;
+      break;
+
+    case Transaction::OP_COLL_RENAME:
+      assert(0 == "not implemented");
+      break;
+    }
+    if (r < 0) {
+      dout(0) << " error " << cpp_strerror(r)
+	      << " not handled on operation " << op->op
+	      << " (op " << pos << ", counting from 0)" << dendl;
+      dout(0) << " transaction dump:\n";
+      JSONFormatter f(true);
+      f.open_object_section("transaction");
+      t->dump(&f);
+      f.close_section();
+      f.flush(*_dout);
+      *_dout << dendl;
+      assert(0 == "unexpected error");
+    }
+
+    // object operations
+    RWLock::WLocker l(c->lock);
+    OnodeRef &o = ovec[op->oid];
+    if (!o) {
+      // these operations implicity create the object
+      bool create = false;
+      if (op->op == Transaction::OP_TOUCH ||
+	  op->op == Transaction::OP_WRITE ||
+	  op->op == Transaction::OP_ZERO) {
+	create = true;
+      }
+      ghobject_t oid = i.get_oid(op->oid);
+      o = c->get_onode(oid, create);
+      if (!create) {
+	if (!o || !o->exists) {
+	  dout(10) << __func__ << " op " << op->op << " got ENOENT on "
+		   << oid << dendl;
+	  r = -ENOENT;
+	  goto endop;
+	}
+      }
+    }
+
+    switch (op->op) {
+    case Transaction::OP_TOUCH:
+	r = _touch(txc, c, o);
+      break;
+
     case Transaction::OP_WRITE:
       {
-        const ghobject_t &oid = i.get_oid(op->oid);
         uint64_t off = op->off;
         uint64_t len = op->len;
 	uint32_t fadvise_flags = i.get_fadvise_flags();
         bufferlist bl;
         i.decode_bl(bl);
-	r = _write(txc, c, oid, off, len, bl, fadvise_flags);
+	r = _write(txc, c, o, off, len, bl, fadvise_flags);
       }
       break;
 
     case Transaction::OP_ZERO:
       {
-        const ghobject_t &oid = i.get_oid(op->oid);
         uint64_t off = op->off;
         uint64_t len = op->len;
-	r = _zero(txc, c, oid, off, len);
+	r = _zero(txc, c, o, off, len);
       }
       break;
 
@@ -2504,60 +2603,52 @@ int KStore::_txc_add_transaction(TransContext *txc, Transaction *t)
 
     case Transaction::OP_TRUNCATE:
       {
-        const ghobject_t& oid = i.get_oid(op->oid);
         uint64_t off = op->off;
-	r = _truncate(txc, c, oid, off);
+	r = _truncate(txc, c, o, off);
       }
       break;
 
     case Transaction::OP_REMOVE:
-      {
-        const ghobject_t& oid = i.get_oid(op->oid);
-	r = _remove(txc, c, oid);
-      }
+	r = _remove(txc, c, o);
       break;
 
     case Transaction::OP_SETATTR:
       {
-        const ghobject_t &oid = i.get_oid(op->oid);
         string name = i.decode_string();
         bufferlist bl;
         i.decode_bl(bl);
 	map<string, bufferptr> to_set;
 	to_set[name] = bufferptr(bl.c_str(), bl.length());
-	r = _setattrs(txc, c, oid, to_set);
+	r = _setattrs(txc, c, o, to_set);
       }
       break;
 
     case Transaction::OP_SETATTRS:
       {
-        const ghobject_t& oid = i.get_oid(op->oid);
         map<string, bufferptr> aset;
         i.decode_attrset(aset);
-	r = _setattrs(txc, c, oid, aset);
+	r = _setattrs(txc, c, o, aset);
       }
       break;
 
     case Transaction::OP_RMATTR:
       {
-        const ghobject_t &oid = i.get_oid(op->oid);
 	string name = i.decode_string();
-	r = _rmattr(txc, c, oid, name);
+	r = _rmattr(txc, c, o, name);
       }
       break;
 
     case Transaction::OP_RMATTRS:
       {
-        const ghobject_t &oid = i.get_oid(op->oid);
-	r = _rmattrs(txc, c, oid);
+	r = _rmattrs(txc, c, o);
       }
       break;
 
     case Transaction::OP_CLONE:
       {
-        const ghobject_t& oid = i.get_oid(op->oid);
         const ghobject_t& noid = i.get_oid(op->dest_oid);
-	r = _clone(txc, c, oid, noid);
+	OnodeRef no = c->get_onode(noid, true);
+	r = _clone(txc, c, o, no);
       }
       break;
 
@@ -2567,48 +2658,12 @@ int KStore::_txc_add_transaction(TransContext *txc, Transaction *t)
 
     case Transaction::OP_CLONERANGE2:
       {
-        const ghobject_t &oid = i.get_oid(op->oid);
-        const ghobject_t &noid = i.get_oid(op->dest_oid);
+	const ghobject_t& noid = i.get_oid(op->dest_oid);
+	OnodeRef no = c->get_onode(noid, true);
         uint64_t srcoff = op->off;
         uint64_t len = op->len;
         uint64_t dstoff = op->dest_off;
-	r = _clone_range(txc, c, oid, noid, srcoff, len, dstoff);
-      }
-      break;
-
-    case Transaction::OP_MKCOLL:
-      {
-	assert(!c);
-        coll_t cid = i.get_cid(op->cid);
-	r = _create_collection(txc, cid, op->split_bits, &c);
-      }
-      break;
-
-    case Transaction::OP_COLL_HINT:
-      {
-        uint32_t type = op->hint_type;
-        bufferlist hint;
-        i.decode_bl(hint);
-        bufferlist::iterator hiter = hint.begin();
-        if (type == Transaction::COLL_HINT_EXPECTED_NUM_OBJECTS) {
-          uint32_t pg_num;
-          uint64_t num_objs;
-          ::decode(pg_num, hiter);
-          ::decode(num_objs, hiter);
-          dout(10) << __func__ << " collection hint objects is a no-op, "
-		   << " pg_num " << pg_num << " num_objects " << num_objs
-		   << dendl;
-        } else {
-          // Ignore the hint
-          dout(10) << __func__ << " unknown collection hint " << type << dendl;
-        }
-      }
-      break;
-
-    case Transaction::OP_RMCOLL:
-      {
-        coll_t cid = i.get_cid(op->cid);
-	r = _remove_collection(txc, cid, &c);
+	r = _clone_range(txc, c, o, no, srcoff, len, dstoff);
       }
       break;
 
@@ -2627,80 +2682,64 @@ int KStore::_txc_add_transaction(TransContext *txc, Transaction *t)
     case Transaction::OP_COLL_MOVE_RENAME:
       {
 	assert(op->cid == op->dest_cid);
-        ghobject_t oldoid = i.get_oid(op->oid);
-        ghobject_t newoid = i.get_oid(op->dest_oid);
-	r = _rename(txc, c, oldoid, newoid);
+	const ghobject_t& noid = i.get_oid(op->dest_oid);
+	OnodeRef no = c->get_onode(noid, true);
+	r = _rename(txc, c, o, no, noid);
+	o.reset();
       }
       break;
 
-    case Transaction::OP_COLL_SETATTR:
-      r = -EOPNOTSUPP;
-      break;
-
-    case Transaction::OP_COLL_RMATTR:
-      r = -EOPNOTSUPP;
-      break;
-
-    case Transaction::OP_COLL_RENAME:
-      assert(0 == "not implemented");
+    case Transaction::OP_TRY_RENAME:
+      {
+	const ghobject_t& noid = i.get_oid(op->dest_oid);
+	OnodeRef no = c->get_onode(noid, true);
+	r = _rename(txc, c, o, no, noid);
+	if (r == -ENOENT)
+	  r = 0;
+	o.reset();
+      }
       break;
 
     case Transaction::OP_OMAP_CLEAR:
       {
-        ghobject_t oid = i.get_oid(op->oid);
-	r = _omap_clear(txc, c, oid);
+	r = _omap_clear(txc, c, o);
       }
       break;
     case Transaction::OP_OMAP_SETKEYS:
       {
-        ghobject_t oid = i.get_oid(op->oid);
 	bufferlist aset_bl;
         i.decode_attrset_bl(&aset_bl);
-	r = _omap_setkeys(txc, c, oid, aset_bl);
+	r = _omap_setkeys(txc, c, o, aset_bl);
       }
       break;
     case Transaction::OP_OMAP_RMKEYS:
       {
-        ghobject_t oid = i.get_oid(op->oid);
 	bufferlist keys_bl;
         i.decode_keyset_bl(&keys_bl);
-	r = _omap_rmkeys(txc, c, oid, keys_bl);
+	r = _omap_rmkeys(txc, c, o, keys_bl);
       }
       break;
     case Transaction::OP_OMAP_RMKEYRANGE:
       {
-        ghobject_t oid = i.get_oid(op->oid);
         string first, last;
         first = i.decode_string();
         last = i.decode_string();
-	r = _omap_rmkey_range(txc, c, oid, first, last);
+	r = _omap_rmkey_range(txc, c, o, first, last);
       }
       break;
     case Transaction::OP_OMAP_SETHEADER:
       {
-        ghobject_t oid = i.get_oid(op->oid);
         bufferlist bl;
         i.decode_bl(bl);
-	r = _omap_setheader(txc, c, oid, bl);
-      }
-      break;
-    case Transaction::OP_SPLIT_COLLECTION:
-      assert(0 == "deprecated");
-      break;
-    case Transaction::OP_SPLIT_COLLECTION2:
-      {
-        uint32_t bits = op->split_bits;
-        uint32_t rem = op->split_rem;
-	r = _split_collection(txc, c, cvec[op->dest_cid], bits, rem);
+	r = _omap_setheader(txc, c, o, bl);
       }
       break;
 
     case Transaction::OP_SETALLOCHINT:
       {
-        ghobject_t oid = i.get_oid(op->oid);
         uint64_t expected_object_size = op->expected_object_size;
         uint64_t expected_write_size = op->expected_write_size;
-	r = _setallochint(txc, c, oid,
+	r = _setallochint(txc, c, o,
 			  expected_object_size,
 			  expected_write_size);
       }
@@ -2711,6 +2750,7 @@ int KStore::_txc_add_transaction(TransContext *txc, Transaction *t)
       assert(0);
     }
 
+  endop:
     if (r < 0) {
       bool ok = false;
 
@@ -2753,11 +2793,7 @@ int KStore::_txc_add_transaction(TransContext *txc, Transaction *t)
 	assert(0 == "unexpected error");
       }
     }
-
-    ++pos;
   }
-
-  return 0;
 }
 
 
@@ -2766,18 +2802,15 @@ int KStore::_txc_add_transaction(TransContext *txc, Transaction *t)
 // write operations
 
 int KStore::_touch(TransContext *txc,
-		     CollectionRef& c,
-		     const ghobject_t& oid)
+		   CollectionRef& c,
+		   OnodeRef &o)
 {
-  dout(15) << __func__ << " " << c->cid << " " << oid << dendl;
+  dout(15) << __func__ << " " << c->cid << " " << o->oid << dendl;
   int r = 0;
-  RWLock::WLocker l(c->lock);
-  OnodeRef o = c->get_onode(oid, true);
-  assert(o);
   o->exists = true;
   _assign_nid(txc, o);
   txc->write_onode(o);
-  dout(10) << __func__ << " " << c->cid << " " << oid << " = " << r << dendl;
+  dout(10) << __func__ << " " << c->cid << " " << o->oid << " = " << r << dendl;
   return r;
 }
 
@@ -2828,10 +2861,10 @@ void KStore::_do_remove_stripe(TransContext *txc, OnodeRef o, uint64_t offset)
 }
 
 int KStore::_do_write(TransContext *txc,
-			OnodeRef o,
-			uint64_t offset, uint64_t length,
-			bufferlist& orig_bl,
-			uint32_t fadvise_flags)
+		      OnodeRef o,
+		      uint64_t offset, uint64_t length,
+		      bufferlist& orig_bl,
+		      uint32_t fadvise_flags)
 {
   int r = 0;
 
@@ -2918,39 +2951,37 @@ int KStore::_do_write(TransContext *txc,
 }
 
 int KStore::_write(TransContext *txc,
-		     CollectionRef& c,
-		     const ghobject_t& oid,
-		     uint64_t offset, size_t length,
-		     bufferlist& bl,
-		     uint32_t fadvise_flags)
+		   CollectionRef& c,
+		   OnodeRef& o,
+		   uint64_t offset, size_t length,
+		   bufferlist& bl,
+		   uint32_t fadvise_flags)
 {
-  dout(15) << __func__ << " " << c->cid << " " << oid
+  dout(15) << __func__ << " " << c->cid << " " << o->oid
 	   << " " << offset << "~" << length
 	   << dendl;
-  RWLock::WLocker l(c->lock);
-  OnodeRef o = c->get_onode(oid, true);
   _assign_nid(txc, o);
   int r = _do_write(txc, o, offset, length, bl, fadvise_flags);
   txc->write_onode(o);
 
-  dout(10) << __func__ << " " << c->cid << " " << oid
+  dout(10) << __func__ << " " << c->cid << " " << o->oid
 	   << " " << offset << "~" << length
 	   << " = " << r << dendl;
   return r;
 }
 
 int KStore::_zero(TransContext *txc,
-		    CollectionRef& c,
-		    const ghobject_t& oid,
-		    uint64_t offset, size_t length)
+		  CollectionRef& c,
+		  OnodeRef& o,
+		  uint64_t offset, size_t length)
 {
-  dout(15) << __func__ << " " << c->cid << " " << oid
+  dout(15) << __func__ << " " << c->cid << " " << o->oid
 	   << " " << offset << "~" << length
 	   << dendl;
   int r = 0;
+  o->exists = true;
 
-  RWLock::WLocker l(c->lock);
-  OnodeRef o = c->get_onode(oid, true);
+  _dump_onode(o);
   _assign_nid(txc, o);
 
   uint64_t stripe_size = o->onode.stripe_size;
@@ -2999,7 +3030,7 @@ int KStore::_zero(TransContext *txc,
   }
   txc->write_onode(o);
 
-  dout(10) << __func__ << " " << c->cid << " " << oid
+  dout(10) << __func__ << " " << c->cid << " " << o->oid
 	   << " " << offset << "~" << length
 	   << " = " << r << dendl;
   return r;
@@ -3052,25 +3083,15 @@ int KStore::_do_truncate(TransContext *txc, OnodeRef o, uint64_t offset)
 }
 
 int KStore::_truncate(TransContext *txc,
-			CollectionRef& c,
-			const ghobject_t& oid,
-			uint64_t offset)
+		      CollectionRef& c,
+		      OnodeRef& o,
+		      uint64_t offset)
 {
-  dout(15) << __func__ << " " << c->cid << " " << oid
+  dout(15) << __func__ << " " << c->cid << " " << o->oid
 	   << " " << offset
 	   << dendl;
-  int r = 0;
-
-  RWLock::WLocker l(c->lock);
-  OnodeRef o = c->get_onode(oid, false);
-  if (!o || !o->exists) {
-    r = -ENOENT;
-    goto out;
-  }
-  r = _do_truncate(txc, o, offset);
-
- out:
-  dout(10) << __func__ << " " << c->cid << " " << oid
+  int r = _do_truncate(txc, o, offset);
+  dout(10) << __func__ << " " << c->cid << " " << o->oid
 	   << " " << offset
 	   << " = " << r << dendl;
   return r;
@@ -3096,76 +3117,51 @@ int KStore::_do_remove(TransContext *txc,
 }
 
 int KStore::_remove(TransContext *txc,
-		      CollectionRef& c,
-		      const ghobject_t& oid)
+		    CollectionRef& c,
+		    OnodeRef &o)
 {
-  dout(15) << __func__ << " " << c->cid << " " << oid << dendl;
-  int r;
-  RWLock::WLocker l(c->lock);
-  OnodeRef o = c->get_onode(oid, false);
-  if (!o || !o->exists) {
-    r = -ENOENT;
-    goto out;
-  }
-  r = _do_remove(txc, o);
-
- out:
-  dout(10) << __func__ << " " << c->cid << " " << oid << " = " << r << dendl;
+  dout(15) << __func__ << " " << c->cid << " " << o->oid << dendl;
+  int r = _do_remove(txc, o);
+  dout(10) << __func__ << " " << c->cid << " " << o->oid << " = " << r << dendl;
   return r;
 }
 
 int KStore::_setattr(TransContext *txc,
-		       CollectionRef& c,
-		       const ghobject_t& oid,
-		       const string& name,
-		       bufferptr& val)
+		     CollectionRef& c,
+		     OnodeRef& o,
+		     const string& name,
+		     bufferptr& val)
 {
-  dout(15) << __func__ << " " << c->cid << " " << oid
+  dout(15) << __func__ << " " << c->cid << " " << o->oid
 	   << " " << name << " (" << val.length() << " bytes)"
 	   << dendl;
   int r = 0;
-
-  RWLock::WLocker l(c->lock);
-  OnodeRef o = c->get_onode(oid, false);
-  if (!o || !o->exists) {
-    r = -ENOENT;
-    goto out;
-  }
   o->onode.attrs[name] = val;
   txc->write_onode(o);
-  r = 0;
-
- out:
-  dout(10) << __func__ << " " << c->cid << " " << oid
+  dout(10) << __func__ << " " << c->cid << " " << o->oid
 	   << " " << name << " (" << val.length() << " bytes)"
 	   << " = " << r << dendl;
   return r;
 }
 
 int KStore::_setattrs(TransContext *txc,
-			CollectionRef& c,
-			const ghobject_t& oid,
-			const map<string,bufferptr>& aset)
+		      CollectionRef& c,
+		      OnodeRef& o,
+		      const map<string,bufferptr>& aset)
 {
-  dout(15) << __func__ << " " << c->cid << " " << oid
+  dout(15) << __func__ << " " << c->cid << " " << o->oid
 	   << " " << aset.size() << " keys"
 	   << dendl;
   int r = 0;
-
-  RWLock::WLocker l(c->lock);
-  OnodeRef o = c->get_onode(oid, false);
-  if (!o || !o->exists) {
-    r = -ENOENT;
-    goto out;
-  }
   for (map<string,bufferptr>::const_iterator p = aset.begin();
-       p != aset.end(); ++p)
-    o->onode.attrs[p->first] = p->second;
+       p != aset.end(); ++p) {
+    if (p->second.is_partial())
+      o->onode.attrs[p->first] = bufferptr(p->second.c_str(), p->second.length());
+    else
+      o->onode.attrs[p->first] = p->second;
+  }
   txc->write_onode(o);
-  r = 0;
-
- out:
-  dout(10) << __func__ << " " << c->cid << " " << oid
+  dout(10) << __func__ << " " << c->cid << " " << o->oid
 	   << " " << aset.size() << " keys"
 	   << " = " << r << dendl;
   return r;
@@ -3173,49 +3169,29 @@ int KStore::_setattrs(TransContext *txc,
 
 
 int KStore::_rmattr(TransContext *txc,
-		      CollectionRef& c,
-		      const ghobject_t& oid,
-		      const string& name)
+		    CollectionRef& c,
+		    OnodeRef& o,
+		    const string& name)
 {
-  dout(15) << __func__ << " " << c->cid << " " << oid
+  dout(15) << __func__ << " " << c->cid << " " << o->oid
 	   << " " << name << dendl;
   int r = 0;
-
-  RWLock::WLocker l(c->lock);
-  OnodeRef o = c->get_onode(oid, false);
-  if (!o || !o->exists) {
-    r = -ENOENT;
-    goto out;
-  }
   o->onode.attrs.erase(name);
   txc->write_onode(o);
-  r = 0;
-
- out:
-  dout(10) << __func__ << " " << c->cid << " " << oid
+  dout(10) << __func__ << " " << c->cid << " " << o->oid
 	   << " " << name << " = " << r << dendl;
   return r;
 }
 
 int KStore::_rmattrs(TransContext *txc,
-		       CollectionRef& c,
-		       const ghobject_t& oid)
+		     CollectionRef& c,
+		     OnodeRef& o)
 {
-  dout(15) << __func__ << " " << c->cid << " " << oid << dendl;
+  dout(15) << __func__ << " " << c->cid << " " << o->oid << dendl;
   int r = 0;
-
-  RWLock::WLocker l(c->lock);
-  OnodeRef o = c->get_onode(oid, false);
-  if (!o || !o->exists) {
-    r = -ENOENT;
-    goto out;
-  }
   o->onode.attrs.clear();
   txc->write_onode(o);
-  r = 0;
-
- out:
-  dout(10) << __func__ << " " << c->cid << " " << oid << " = " << r << dendl;
+  dout(10) << __func__ << " " << c->cid << " " << o->oid << " = " << r << dendl;
   return r;
 }
 
@@ -3238,44 +3214,27 @@ void KStore::_do_omap_clear(TransContext *txc, uint64_t id)
 }
 
 int KStore::_omap_clear(TransContext *txc,
-			  CollectionRef& c,
-			  const ghobject_t& oid)
+			CollectionRef& c,
+			OnodeRef& o)
 {
-  dout(15) << __func__ << " " << c->cid << " " << oid << dendl;
+  dout(15) << __func__ << " " << c->cid << " " << o->oid << dendl;
   int r = 0;
-
-  RWLock::WLocker l(c->lock);
-  OnodeRef o = c->get_onode(oid, false);
-  if (!o || !o->exists) {
-    r = -ENOENT;
-    goto out;
-  }
   if (o->onode.omap_head != 0) {
     _do_omap_clear(txc, o->onode.omap_head);
   }
-  r = 0;
-
- out:
-  dout(10) << __func__ << " " << c->cid << " " << oid << " = " << r << dendl;
+  dout(10) << __func__ << " " << c->cid << " " << o->oid << " = " << r << dendl;
   return r;
 }
 
 int KStore::_omap_setkeys(TransContext *txc,
-			    CollectionRef& c,
-			    const ghobject_t& oid,
-			    bufferlist &bl)
+			  CollectionRef& c,
+			  OnodeRef& o,
+			  bufferlist &bl)
 {
-  dout(15) << __func__ << " " << c->cid << " " << oid << dendl;
-  int r = 0;
+  dout(15) << __func__ << " " << c->cid << " " << o->oid << dendl;
+  int r;
   bufferlist::iterator p = bl.begin();
   __u32 num;
-
-  RWLock::WLocker l(c->lock);
-  OnodeRef o = c->get_onode(oid, false);
-  if (!o || !o->exists) {
-    r = -ENOENT;
-    goto out;
-  }
   if (!o->onode.omap_head) {
     o->onode.omap_head = o->onode.nid;
     txc->write_onode(o);
@@ -3293,27 +3252,18 @@ int KStore::_omap_setkeys(TransContext *txc,
     txc->t->set(PREFIX_OMAP, final_key, value);
   }
   r = 0;
-
- out:
-  dout(10) << __func__ << " " << c->cid << " " << oid << " = " << r << dendl;
+  dout(10) << __func__ << " " << c->cid << " " << o->oid << " = " << r << dendl;
   return r;
 }
 
 int KStore::_omap_setheader(TransContext *txc,
-			      CollectionRef& c,
-			      const ghobject_t& oid,
-			      bufferlist& bl)
+			    CollectionRef& c,
+			    OnodeRef &o,
+			    bufferlist& bl)
 {
-  dout(15) << __func__ << " " << c->cid << " " << oid << dendl;
-  int r = 0;
-
-  RWLock::WLocker l(c->lock);
-  OnodeRef o = c->get_onode(oid, false);
+  dout(15) << __func__ << " " << c->cid << " " << o->oid << dendl;
+  int r;
   string key;
-  if (!o || !o->exists) {
-    r = -ENOENT;
-    goto out;
-  }
   if (!o->onode.omap_head) {
     o->onode.omap_head = o->onode.nid;
     txc->write_onode(o);
@@ -3321,28 +3271,20 @@ int KStore::_omap_setheader(TransContext *txc,
   get_omap_header(o->onode.omap_head, &key);
   txc->t->set(PREFIX_OMAP, key, bl);
   r = 0;
-
- out:
-  dout(10) << __func__ << " " << c->cid << " " << oid << " = " << r << dendl;
+  dout(10) << __func__ << " " << c->cid << " " << o->oid << " = " << r << dendl;
   return r;
 }
 
 int KStore::_omap_rmkeys(TransContext *txc,
-			   CollectionRef& c,
-			   const ghobject_t& oid,
-			   bufferlist& bl)
+			 CollectionRef& c,
+			 OnodeRef& o,
+			 bufferlist& bl)
 {
-  dout(15) << __func__ << " " << c->cid << " " << oid << dendl;
+  dout(15) << __func__ << " " << c->cid << " " << o->oid << dendl;
   int r = 0;
   bufferlist::iterator p = bl.begin();
   __u32 num;
 
-  RWLock::WLocker l(c->lock);
-  OnodeRef o = c->get_onode(oid, false);
-  if (!o || !o->exists) {
-    r = -ENOENT;
-    goto out;
-  }
   if (!o->onode.omap_head) {
     r = 0;
     goto out;
@@ -3360,28 +3302,21 @@ int KStore::_omap_rmkeys(TransContext *txc,
   r = 0;
 
  out:
-  dout(10) << __func__ << " " << c->cid << " " << oid << " = " << r << dendl;
+  dout(10) << __func__ << " " << c->cid << " " << o->oid << " = " << r << dendl;
   return r;
 }
 
 int KStore::_omap_rmkey_range(TransContext *txc,
-				CollectionRef& c,
-				const ghobject_t& oid,
-				const string& first, const string& last)
+			      CollectionRef& c,
+			      OnodeRef& o,
+			      const string& first, const string& last)
 {
-  dout(15) << __func__ << " " << c->cid << " " << oid << dendl;
-  int r = 0;
+  dout(15) << __func__ << " " << c->cid << " " << o->oid << dendl;
   KeyValueDB::Iterator it;
   string key_first, key_last;
+  int r = 0;
 
-  RWLock::WLocker l(c->lock);
-  OnodeRef o = c->get_onode(oid, false);
-  if (!o || !o->exists) {
-    r = -ENOENT;
-    goto out;
-  }
   if (!o->onode.omap_head) {
-    r = 0;
     goto out;
   }
   it = db->get_iterator(PREFIX_OMAP);
@@ -3401,34 +3336,25 @@ int KStore::_omap_rmkey_range(TransContext *txc,
   r = 0;
 
  out:
-  dout(10) << __func__ << " " << c->cid << " " << oid << " = " << r << dendl;
+  dout(10) << __func__ << " " << c->cid << " " << o->oid << " = " << r << dendl;
   return r;
 }
 
 int KStore::_setallochint(TransContext *txc,
-			    CollectionRef& c,
-			    const ghobject_t& oid,
-			    uint64_t expected_object_size,
-			    uint64_t expected_write_size)
+			  CollectionRef& c,
+			  OnodeRef& o,
+			  uint64_t expected_object_size,
+			  uint64_t expected_write_size)
 {
-  dout(15) << __func__ << " " << c->cid << " " << oid
+  dout(15) << __func__ << " " << c->cid << " " << o->oid
 	   << " object_size " << expected_object_size
 	   << " write_size " << expected_write_size
 	   << dendl;
   int r = 0;
-  RWLock::WLocker l(c->lock);
-  OnodeRef o = c->get_onode(oid, false);
-  if (!o || !o->exists) {
-    r = -ENOENT;
-    goto out;
-  }
-
   o->onode.expected_object_size = expected_object_size;
   o->onode.expected_write_size = expected_write_size;
   txc->write_onode(o);
-
- out:
-  dout(10) << __func__ << " " << c->cid << " " << oid
+  dout(10) << __func__ << " " << c->cid << " " << o->oid
 	   << " object_size " << expected_object_size
 	   << " write_size " << expected_write_size
 	   << " = " << r << dendl;
@@ -3436,27 +3362,24 @@ int KStore::_setallochint(TransContext *txc,
 }
 
 int KStore::_clone(TransContext *txc,
-		     CollectionRef& c,
-		     const ghobject_t& old_oid,
-		     const ghobject_t& new_oid)
+		   CollectionRef& c,
+		   OnodeRef& oldo,
+		   OnodeRef& newo)
 {
-  dout(15) << __func__ << " " << c->cid << " " << old_oid << " -> "
-	   << new_oid << dendl;
+  dout(15) << __func__ << " " << c->cid << " " << oldo->oid << " -> "
+	   << newo->oid << dendl;
   int r = 0;
+  if (oldo->oid.hobj.get_hash() != newo->oid.hobj.get_hash()) {
+    derr << __func__ << " mismatched hash on " << oldo->oid
+	 << " and " << newo->oid << dendl;
+    return -EINVAL;
+  }
 
-  RWLock::WLocker l(c->lock);
   bufferlist bl;
-  OnodeRef newo;
-  OnodeRef oldo = c->get_onode(old_oid, false);
-  if (!oldo || !oldo->exists) {
-    r = -ENOENT;
-    goto out;
-  }
-  newo = c->get_onode(new_oid, true);
-  assert(newo);
   newo->exists = true;
   _assign_nid(txc, newo);
 
+  // data
   oldo->flush();
 
   r = _do_read(oldo, 0, oldo->onode.size, bl, 0);
@@ -3469,6 +3392,8 @@ int KStore::_clone(TransContext *txc,
     goto out;
 
   r = _do_write(txc, newo, 0, oldo->onode.size, bl, 0);
+  if (r < 0)
+    goto out;
 
   newo->onode.attrs = oldo->onode.attrs;
 
@@ -3504,36 +3429,26 @@ int KStore::_clone(TransContext *txc,
   }
 
   txc->write_onode(newo);
-
   r = 0;
 
  out:
-  dout(10) << __func__ << " " << c->cid << " " << old_oid << " -> "
-	   << new_oid << " = " << r << dendl;
+  dout(10) << __func__ << " " << c->cid << " " << oldo->oid << " -> "
+	   << newo->oid << " = " << r << dendl;
   return r;
 }
 
 int KStore::_clone_range(TransContext *txc,
-			   CollectionRef& c,
-			   const ghobject_t& old_oid,
-			   const ghobject_t& new_oid,
-			   uint64_t srcoff, uint64_t length, uint64_t dstoff)
+			 CollectionRef& c,
+			 OnodeRef& oldo,
+			 OnodeRef& newo,
+			 uint64_t srcoff, uint64_t length, uint64_t dstoff)
 {
-  dout(15) << __func__ << " " << c->cid << " " << old_oid << " -> "
-	   << new_oid << " from " << srcoff << "~" << length
+  dout(15) << __func__ << " " << c->cid << " " << oldo->oid << " -> "
+	   << newo->oid << " from " << srcoff << "~" << length
 	   << " to offset " << dstoff << dendl;
   int r = 0;
 
-  RWLock::WLocker l(c->lock);
   bufferlist bl;
-  OnodeRef newo;
-  OnodeRef oldo = c->get_onode(old_oid, false);
-  if (!oldo || !oldo->exists) {
-    r = -ENOENT;
-    goto out;
-  }
-  newo = c->get_onode(new_oid, true);
-  assert(newo);
   newo->exists = true;
   _assign_nid(txc, newo);
 
@@ -3548,33 +3463,26 @@ int KStore::_clone_range(TransContext *txc,
   r = 0;
 
  out:
-  dout(10) << __func__ << " " << c->cid << " " << old_oid << " -> "
-	   << new_oid << " from " << srcoff << "~" << length
+  dout(10) << __func__ << " " << c->cid << " " << oldo->oid << " -> "
+	   << newo->oid << " from " << srcoff << "~" << length
 	   << " to offset " << dstoff
 	   << " = " << r << dendl;
   return r;
 }
 
 int KStore::_rename(TransContext *txc,
-		      CollectionRef& c,
-		      const ghobject_t& old_oid,
-		      const ghobject_t& new_oid)
+		    CollectionRef& c,
+		    OnodeRef& oldo,
+		    OnodeRef& newo,
+		    const ghobject_t& new_oid)
 {
-  dout(15) << __func__ << " " << c->cid << " " << old_oid << " -> "
+  dout(15) << __func__ << " " << c->cid << " " << oldo->oid << " -> "
 	   << new_oid << dendl;
   int r;
-
-  RWLock::WLocker l(c->lock);
+  ghobject_t old_oid = oldo->oid;
   bufferlist bl;
   string old_key, new_key;
-  OnodeRef newo;
-  OnodeRef oldo = c->get_onode(old_oid, false);
-  if (!oldo || !oldo->exists) {
-    r = -ENOENT;
-    goto out;
-  }
 
-  newo = c->get_onode(new_oid, false);
   if (newo && newo->exists) {
     // destination object already exists, remove it first
     r = _do_remove(txc, newo);
diff --git a/src/os/kstore/KStore.h b/src/os/kstore/KStore.h
index 0710436..4b00663 100644
--- a/src/os/kstore/KStore.h
+++ b/src/os/kstore/KStore.h
@@ -19,6 +19,10 @@
 
 #include <unistd.h>
 
+#include <atomic>
+#include <mutex>
+#include <condition_variable>
+
 #include "include/assert.h"
 #include "include/unordered_map.h"
 #include "include/memory.h"
@@ -26,6 +30,7 @@
 #include "common/RWLock.h"
 #include "common/WorkQueue.h"
 #include "os/ObjectStore.h"
+#include "common/perf_counters.h"
 #include "os/fs/FS.h"
 #include "kv/KeyValueDB.h"
 
@@ -33,6 +38,16 @@
 
 #include "boost/intrusive/list.hpp"
 
+enum {  
+  l_kstore_first = 832430,
+  l_kstore_state_prepare_lat,
+  l_kstore_state_kv_queued_lat,
+  l_kstore_state_kv_done_lat,
+  l_kstore_state_finishing_lat,
+  l_kstore_state_done_lat,
+  l_kstore_last
+};
+
 class KStore : public ObjectStore {
   // -----------------------------------------------------
   // types
@@ -42,7 +57,7 @@ public:
 
   /// an in-memory object
   struct Onode {
-    atomic_t nref;  ///< reference count
+    std::atomic_int nref;  ///< reference count
 
     ghobject_t oid;
     string key;     ///< key under PREFIX_OBJ where we are stored
@@ -52,8 +67,8 @@ public:
     bool dirty;     // ???
     bool exists;
 
-    Mutex flush_lock;  ///< protect flush_txns
-    Cond flush_cond;   ///< wait here for unapplied txns
+    std::mutex flush_lock;  ///< protect flush_txns
+    std::condition_variable flush_cond;   ///< wait here for unapplied txns
     set<TransContext*> flush_txns;   ///< committing txns
 
     uint64_t tail_offset;
@@ -61,14 +76,20 @@ public:
 
     map<uint64_t,bufferlist> pending_stripes;  ///< unwritten stripes
 
-    Onode(const ghobject_t& o, const string& k);
+    Onode(const ghobject_t& o, const string& k)
+      : nref(0),
+	oid(o),
+	key(k),
+	dirty(false),
+	exists(false) {
+    }
 
     void flush();
     void get() {
-      nref.inc();
+      ++nref;
     }
     void put() {
-      if (nref.dec() == 0)
+      if (--nref == 0)
 	delete this;
     }
 
@@ -90,16 +111,15 @@ public:
 	boost::intrusive::list_member_hook<>,
 	&Onode::lru_item> > lru_list_t;
 
-    Mutex lock;
+    std::mutex lock;
     ceph::unordered_map<ghobject_t,OnodeRef> onode_map;  ///< forward lookups
     lru_list_t lru;                                      ///< lru
 
-    OnodeHashLRU() : lock("KStore::OnodeHashLRU::lock") {}
+    OnodeHashLRU() {}
 
     void add(const ghobject_t& oid, OnodeRef o);
     void _touch(OnodeRef o);
     OnodeRef lookup(const ghobject_t& o);
-    void remove(const ghobject_t& o);
     void rename(const ghobject_t& old_oid, const ghobject_t& new_oid);
     void clear();
     bool get_next(const ghobject_t& after, pair<ghobject_t,OnodeRef> *next);
@@ -183,6 +203,13 @@ public:
       return "???";
     }
 
+    void log_state_latency(PerfCounters *logger, int state) {      
+        utime_t lat, now = ceph_clock_now(g_ceph_context);
+        lat = now - start;
+        logger->tinc(state, lat);
+        start = now;
+    }
+
     OpSequencerRef osr;
     boost::intrusive::list_member_hook<> sequencer_item;
 
@@ -196,11 +223,8 @@ public:
     list<Context*> oncommits;  ///< more commit completions
     list<CollectionRef> removed_collections; ///< colls we removed
 
-    Mutex lock;
-    Cond cond;
-
     CollectionRef first_collection;  ///< first referenced collection
-
+    utime_t start;
     explicit TransContext(OpSequencer *o)
       : state(STATE_PREPARE),
 	osr(o),
@@ -209,7 +233,7 @@ public:
 	oncommit(NULL),
 	onreadable(NULL),
 	onreadable_sync(NULL),
-	lock("KStore::TransContext::lock") {
+        start(ceph_clock_now(g_ceph_context)){
       //cout << "txc new " << this << std::endl;
     }
     ~TransContext() {
@@ -223,8 +247,8 @@ public:
 
   class OpSequencer : public Sequencer_impl {
   public:
-    Mutex qlock;
-    Cond qcond;
+    std::mutex qlock;
+    std::condition_variable qcond;
     typedef boost::intrusive::list<
       TransContext,
       boost::intrusive::member_hook<
@@ -237,26 +261,25 @@ public:
 
     OpSequencer()
 	//set the qlock to to PTHREAD_MUTEX_RECURSIVE mode
-      : qlock("KStore::OpSequencer::qlock", true, false),
-	parent(NULL) {
+      : parent(NULL) {
     }
     ~OpSequencer() {
       assert(q.empty());
     }
 
     void queue_new(TransContext *txc) {
-      Mutex::Locker l(qlock);
+      std::lock_guard<std::mutex> l(qlock);
       q.push_back(*txc);
     }
 
     void flush() {
-      Mutex::Locker l(qlock);
+      std::unique_lock<std::mutex> l(qlock);
       while (!q.empty())
-	qcond.Wait(qlock);
+	qcond.wait(l);
     }
 
     bool flush_commit(Context *c) {
-      Mutex::Locker l(qlock);
+      std::lock_guard<std::mutex> l(qlock);
       if (q.empty()) {
 	return true;
       }
@@ -292,7 +315,7 @@ private:
   RWLock coll_lock;    ///< rwlock to protect coll_map
   ceph::unordered_map<coll_t, CollectionRef> coll_map;
 
-  Mutex nid_lock;
+  std::mutex nid_lock;
   uint64_t nid_last;
   uint64_t nid_max;
 
@@ -301,14 +324,14 @@ private:
   Finisher finisher;
 
   KVSyncThread kv_sync_thread;
-  Mutex kv_lock;
-  Cond kv_cond, kv_sync_cond;
+  std::mutex kv_lock;
+  std::condition_variable kv_cond, kv_sync_cond;
   bool kv_stop;
   deque<TransContext*> kv_queue, kv_committing;
 
-  Logger *logger;
-
-  Mutex reap_lock;
+  //Logger *logger;
+  PerfCounters *logger;
+  std::mutex reap_lock;
   list<CollectionRef> removed_collections;
 
 
@@ -342,7 +365,7 @@ private:
 
   TransContext *_txc_create(OpSequencer *osr);
   void _txc_release(TransContext *txc, uint64_t offset, uint64_t length);
-  int _txc_add_transaction(TransContext *txc, Transaction *t);
+  void _txc_add_transaction(TransContext *txc, Transaction *t);
   int _txc_finalize(OpSequencer *osr, TransContext *txc);
   void _txc_state_proc(TransContext *txc);
   void _txc_finish_kv(TransContext *txc);
@@ -353,9 +376,9 @@ private:
   void _kv_sync_thread();
   void _kv_stop() {
     {
-      Mutex::Locker l(kv_lock);
+      std::lock_guard<std::mutex> l(kv_lock);
       kv_stop = true;
-      kv_cond.Signal();
+      kv_cond.notify_all();
     }
     kv_sync_thread.join();
     kv_stop = false;
@@ -518,7 +541,7 @@ private:
 
   int _write(TransContext *txc,
 	     CollectionRef& c,
-	     const ghobject_t& oid,
+	     OnodeRef& o,
 	     uint64_t offset, size_t len,
 	     bufferlist& bl,
 	     uint32_t fadvise_flags);
@@ -529,76 +552,77 @@ private:
 		uint32_t fadvise_flags);
   int _touch(TransContext *txc,
 	     CollectionRef& c,
-	     const ghobject_t& oid);
+	     OnodeRef& o);
   int _zero(TransContext *txc,
 	    CollectionRef& c,
-	    const ghobject_t& oid,
+	    OnodeRef& o,
 	    uint64_t offset, size_t len);
   int _do_truncate(TransContext *txc,
 		   OnodeRef o,
 		   uint64_t offset);
   int _truncate(TransContext *txc,
 		CollectionRef& c,
-		const ghobject_t& oid,
+		OnodeRef& o,
 		uint64_t offset);
   int _remove(TransContext *txc,
 	      CollectionRef& c,
-	      const ghobject_t& oid);
+	      OnodeRef& o);
   int _do_remove(TransContext *txc,
 		 OnodeRef o);
   int _setattr(TransContext *txc,
 	       CollectionRef& c,
-	       const ghobject_t& oid,
+	       OnodeRef& o,
 	       const string& name,
 	       bufferptr& val);
   int _setattrs(TransContext *txc,
 		CollectionRef& c,
-		const ghobject_t& oid,
+		OnodeRef& o,
 		const map<string,bufferptr>& aset);
   int _rmattr(TransContext *txc,
 	      CollectionRef& c,
-	      const ghobject_t& oid,
+	      OnodeRef& o,
 	      const string& name);
   int _rmattrs(TransContext *txc,
 	       CollectionRef& c,
-	       const ghobject_t& oid);
+	       OnodeRef& o);
   void _do_omap_clear(TransContext *txc, uint64_t id);
   int _omap_clear(TransContext *txc,
 		  CollectionRef& c,
-		  const ghobject_t& oid);
+		  OnodeRef& o);
   int _omap_setkeys(TransContext *txc,
 		    CollectionRef& c,
-		    const ghobject_t& oid,
+		    OnodeRef& o,
 		    bufferlist& bl);
   int _omap_setheader(TransContext *txc,
 		      CollectionRef& c,
-		      const ghobject_t& oid,
+		      OnodeRef& o,
 		      bufferlist& header);
   int _omap_rmkeys(TransContext *txc,
 		   CollectionRef& c,
-		   const ghobject_t& oid,
+		   OnodeRef& o,
 		   bufferlist& bl);
   int _omap_rmkey_range(TransContext *txc,
 			CollectionRef& c,
-			const ghobject_t& oid,
+			OnodeRef& o,
 			const string& first, const string& last);
   int _setallochint(TransContext *txc,
 		    CollectionRef& c,
-		    const ghobject_t& oid,
+		    OnodeRef& o,
 		    uint64_t expected_object_size,
 		    uint64_t expected_write_size);
   int _clone(TransContext *txc,
 	     CollectionRef& c,
-	     const ghobject_t& old_oid,
-	     const ghobject_t& new_oid);
+	     OnodeRef& oldo,
+	     OnodeRef& newo);
   int _clone_range(TransContext *txc,
 		   CollectionRef& c,
-		   const ghobject_t& old_oid,
-		   const ghobject_t& new_oid,
+		   OnodeRef& oldo,
+		   OnodeRef& newo,
 		   uint64_t srcoff, uint64_t length, uint64_t dstoff);
   int _rename(TransContext *txc,
 	      CollectionRef& c,
-	      const ghobject_t& old_oid,
+	      OnodeRef& oldo,
+	      OnodeRef& newo,
 	      const ghobject_t& new_oid);
   int _create_collection(TransContext *txc, coll_t cid, unsigned bits,
 			 CollectionRef *c);
diff --git a/src/os/memstore/MemStore.cc b/src/os/memstore/MemStore.cc
index 68972dd..eb06f18 100644
--- a/src/os/memstore/MemStore.cc
+++ b/src/os/memstore/MemStore.cc
@@ -860,6 +860,19 @@ void MemStore::_do_transaction(Transaction& t)
         coll_t newcid = i.get_cid(op->dest_cid);
         ghobject_t newoid = i.get_oid(op->dest_oid);
 	r = _collection_move_rename(oldcid, oldoid, newcid, newoid);
+	if (r == -ENOENT)
+	  r = 0;
+      }
+      break;
+
+    case Transaction::OP_TRY_RENAME:
+      {
+        coll_t cid = i.get_cid(op->cid);
+        ghobject_t oldoid = i.get_oid(op->oid);
+        ghobject_t newoid = i.get_oid(op->dest_oid);
+	r = _collection_move_rename(cid, oldoid, cid, newoid);
+	if (r == -ENOENT)
+	  r = 0;
       }
       break;
 
@@ -1341,15 +1354,8 @@ int MemStore::_collection_move_rename(const coll_t& oldcid, const ghobject_t& ol
     return -ENOENT;
 
   // note: c and oc may be the same
-  if (&(*c) == &(*oc)) {
-    c->lock.get_write();
-  } else if (&(*c) < &(*oc)) {
-    c->lock.get_write();
-    oc->lock.get_write();
-  } else if (&(*c) > &(*oc)) {
-    oc->lock.get_write();
-    c->lock.get_write();
-  }
+  assert(&(*c) == &(*oc));
+  c->lock.get_write();
 
   int r = -EEXIST;
   if (c->object_hash.count(oid))
@@ -1367,8 +1373,6 @@ int MemStore::_collection_move_rename(const coll_t& oldcid, const ghobject_t& ol
   r = 0;
  out:
   c->lock.put_write();
-  if (&(*c) != &(*oc))
-    oc->lock.put_write();
   return r;
 }
 
diff --git a/src/os/memstore/PageSet.h b/src/os/memstore/PageSet.h
index b3e1f13..e989a36 100644
--- a/src/os/memstore/PageSet.h
+++ b/src/os/memstore/PageSet.h
@@ -63,6 +63,9 @@ struct Page {
   }
 
   static Ref create(size_t page_size, uint64_t offset = 0) {
+    // ensure proper alignment of the Page
+    const auto align = alignof(Page);
+    page_size = (page_size + align - 1) & ~(align - 1);
     // allocate the Page and its data in a single buffer
     auto buffer = new char[page_size + sizeof(Page)];
     // place the Page structure at the end of the buffer
diff --git a/src/osd/ECBackend.cc b/src/osd/ECBackend.cc
index feefcd7..975c49b 100644
--- a/src/osd/ECBackend.cc
+++ b/src/osd/ECBackend.cc
@@ -776,6 +776,7 @@ void ECBackend::sub_write_committed(
     r->op.last_complete = last_complete;
     r->op.committed = true;
     r->op.from = get_parent()->whoami_shard();
+    r->set_priority(CEPH_MSG_PRIO_HIGH);
     get_parent()->send_message_osd_cluster(
       get_parent()->primary_shard().osd, r, get_parent()->get_epoch());
   }
@@ -816,6 +817,7 @@ void ECBackend::sub_write_applied(
     r->op.from = get_parent()->whoami_shard();
     r->op.tid = tid;
     r->op.applied = true;
+    r->set_priority(CEPH_MSG_PRIO_HIGH);
     get_parent()->send_message_osd_cluster(
       get_parent()->primary_shard().osd, r, get_parent()->get_epoch());
   }
@@ -833,7 +835,6 @@ void ECBackend::handle_sub_write(
   if (!get_parent()->pgb_is_primary())
     get_parent()->update_stats(op.stats);
   ObjectStore::Transaction localt;
-  localt.set_use_tbl(op.t.get_use_tbl());
   if (!op.temp_added.empty()) {
     add_temp_objs(op.temp_added);
   }
@@ -858,7 +859,7 @@ void ECBackend::handle_sub_write(
     op.trim_to,
     op.trim_rollback_to,
     !(op.t.empty()),
-    &localt);
+    localt);
 
   ReplicatedPG *_rPG = dynamic_cast<ReplicatedPG *>(get_parent());
   if (_rPG && !_rPG->is_undersized() &&
@@ -1342,7 +1343,7 @@ struct MustPrependHashInfo : public ObjectModDesc::Visitor {
 void ECBackend::submit_transaction(
   const hobject_t &hoid,
   const eversion_t &at_version,
-  PGTransaction *_t,
+  PGTransactionUPtr &&_t,
   const eversion_t &trim_to,
   const eversion_t &trim_rollback_to,
   const vector<pg_log_entry_t> &log_entries,
@@ -1370,7 +1371,7 @@ void ECBackend::submit_transaction(
   op->reqid = reqid;
   op->client_op = client_op;
   
-  op->t = static_cast<ECTransaction*>(_t);
+  op->t.reset(static_cast<ECTransaction*>(_t.release()));
 
   set<hobject_t, hobject_t::BitwiseComparator> need_hinfos;
   op->t->get_append_objects(&need_hinfos);
@@ -1776,10 +1777,8 @@ void ECBackend::start_write(Op *op) {
        i != get_parent()->get_actingbackfill_shards().end();
        ++i) {
     trans[i->shard];
-    trans[i->shard].set_use_tbl(parent->transaction_use_tbl());
   }
   ObjectStore::Transaction empty;
-  empty.set_use_tbl(parent->transaction_use_tbl());
 
   op->t->generate_transactions(
     op->unstable_hash_infos,
@@ -1830,7 +1829,6 @@ void ECBackend::start_write(Op *op) {
       op->on_local_applied_sync = 0;
     } else {
       MOSDECSubOpWrite *r = new MOSDECSubOpWrite(sop);
-      r->set_priority(cct->_conf->osd_client_op_priority);
       r->pgid = spg_t(get_parent()->primary_spg_t().pgid, i->shard);
       r->map_epoch = get_parent()->get_epoch();
       get_parent()->send_message_osd_cluster(
@@ -1972,7 +1970,7 @@ void ECBackend::objects_read_async(
 	c)));
 
   start_read_op(
-    cct->_conf->osd_client_op_priority,
+    CEPH_MSG_PRIO_DEFAULT,
     for_read_op,
     OpRequestRef(),
     fast_read, false);
diff --git a/src/osd/ECBackend.h b/src/osd/ECBackend.h
index bee32fd..b691658 100644
--- a/src/osd/ECBackend.h
+++ b/src/osd/ECBackend.h
@@ -95,7 +95,7 @@ public:
   void submit_transaction(
     const hobject_t &hoid,
     const eversion_t &at_version,
-    PGTransaction *t,
+    PGTransactionUPtr &&t,
     const eversion_t &trim_to,
     const eversion_t &trim_rollback_to,
     const vector<pg_log_entry_t> &log_entries,
@@ -359,7 +359,7 @@ public:
     osd_reqid_t reqid;
     OpRequestRef client_op;
 
-    ECTransaction *t;
+    std::unique_ptr<ECTransaction> t;
 
     set<hobject_t, hobject_t::BitwiseComparator> temp_added;
     set<hobject_t, hobject_t::BitwiseComparator> temp_cleared;
@@ -369,7 +369,6 @@ public:
 
     map<hobject_t, ECUtil::HashInfoRef, hobject_t::BitwiseComparator> unstable_hash_infos;
     ~Op() {
-      delete t;
       delete on_local_applied_sync;
       delete on_all_applied;
       delete on_all_commit;
diff --git a/src/osd/ECUtil.h b/src/osd/ECUtil.h
index 968056d..2706bba 100644
--- a/src/osd/ECUtil.h
+++ b/src/osd/ECUtil.h
@@ -33,12 +33,11 @@ const uint64_t CHUNK_PADDING = 8;
 const uint64_t CHUNK_OVERHEAD = 16; // INFO + PADDING
 
 class stripe_info_t {
-  const uint64_t stripe_size;
   const uint64_t stripe_width;
   const uint64_t chunk_size;
 public:
   stripe_info_t(uint64_t stripe_size, uint64_t stripe_width)
-    : stripe_size(stripe_size), stripe_width(stripe_width),
+    : stripe_width(stripe_width),
       chunk_size(stripe_width / stripe_size) {
     assert(stripe_width % stripe_size == 0);
   }
diff --git a/src/osd/Makefile.am b/src/osd/Makefile.am
index 9fafed5..2fba24a 100644
--- a/src/osd/Makefile.am
+++ b/src/osd/Makefile.am
@@ -23,6 +23,7 @@ libosd_a_SOURCES = \
 	osd/ClassHandler.cc \
 	osd/OpRequest.cc \
 	osd/SnapMapper.cc \
+	osd/ScrubStore.cc \
 	objclass/class_api.cc
 
 libosd_a_CXXFLAGS = ${AM_CXXFLAGS}
@@ -49,6 +50,7 @@ noinst_HEADERS += \
 	osd/ECMsgTypes.h \
 	osd/ECTransaction.h \
 	osd/Watch.h \
+	osd/ScrubStore.h \
 	osd/osd_types.h
 
 endif # WITH_OSD
diff --git a/src/osd/OSD.cc b/src/osd/OSD.cc
index cb83446..57242a4 100644
--- a/src/osd/OSD.cc
+++ b/src/osd/OSD.cc
@@ -90,6 +90,8 @@
 #include "messages/MOSDECSubOpWriteReply.h"
 #include "messages/MOSDECSubOpRead.h"
 #include "messages/MOSDECSubOpReadReply.h"
+#include "messages/MOSDPGUpdateLogMissing.h"
+#include "messages/MOSDPGUpdateLogMissingReply.h"
 
 #include "messages/MOSDAlive.h"
 
@@ -221,6 +223,7 @@ OSDService::OSDService(OSD *osd) :
   pg_epoch_lock("OSDService::pg_epoch_lock"),
   publish_lock("OSDService::publish_lock"),
   pre_publish_lock("OSDService::pre_publish_lock"),
+  max_oldest_map(0),
   peer_map_epoch_lock("OSDService::peer_map_epoch_lock"),
   sched_scrub_lock("OSDService::sched_scrub_lock"), scrubs_pending(0),
   scrubs_active(0),
@@ -233,6 +236,10 @@ OSDService::OSDService(OSD *osd) :
   agent_stop_flag(false),
   agent_timer_lock("OSD::agent_timer_lock"),
   agent_timer(osd->client_messenger->cct, agent_timer_lock),
+  promote_probability_millis(1000),
+  last_recalibrate(ceph_clock_now(NULL)),
+  promote_max_objects(0),
+  promote_max_bytes(0),
   objecter(new Objecter(osd->client_messenger->cct, osd->objecter_messenger, osd->monc, NULL, 0, 0)),
   objecter_finisher(osd->client_messenger->cct),
   watch_lock("OSD::watch_lock"),
@@ -460,6 +467,7 @@ void OSDService::start_shutdown()
 
 void OSDService::shutdown()
 {
+  reserver_finisher.wait_for_empty();
   reserver_finisher.stop();
   {
     Mutex::Locker l(watch_lock);
@@ -467,6 +475,7 @@ void OSDService::shutdown()
   }
 
   objecter->shutdown();
+  objecter_finisher.wait_for_empty();
   objecter_finisher.stop();
 
   {
@@ -535,8 +544,11 @@ void OSDService::agent_entry()
 	     << (agent_active ? " active" : " NOT ACTIVE")
 	     << dendl;
     dout(20) << __func__ << " oids " << agent_oids << dendl;
-    if (agent_ops >= g_conf->osd_agent_max_ops || top.empty() ||
-	!agent_active) {
+    int max = g_conf->osd_agent_max_ops - agent_ops;
+    int agent_flush_quota = max;
+    if (!flush_mode_high_count)
+      agent_flush_quota = g_conf->osd_agent_max_low_ops - agent_ops;
+    if (agent_flush_quota <= 0 || top.empty() || !agent_active) {
       agent_cond.Wait(agent_lock);
       continue;
     }
@@ -546,11 +558,9 @@ void OSDService::agent_entry()
       agent_valid_iterator = true;
     }
     PGRef pg = *agent_queue_pos;
-    int max = g_conf->osd_agent_max_ops - agent_ops;
-    int agent_flush_quota = max;
-    if (!flush_mode_high_count)
-      agent_flush_quota = g_conf->osd_agent_max_low_ops - agent_ops;
-    dout(10) << "high_count " << flush_mode_high_count << " agent_ops " << agent_ops << " flush_quota " << agent_flush_quota << dendl;
+    dout(10) << "high_count " << flush_mode_high_count
+	     << " agent_ops " << agent_ops
+	     << " flush_quota " << agent_flush_quota << dendl;
     agent_lock.Unlock();
     if (!pg->agent_work(max, agent_flush_quota)) {
       dout(10) << __func__ << " " << pg->get_pgid()
@@ -592,6 +602,78 @@ void OSDService::agent_stop()
 
 // -------------------------------------
 
+void OSDService::promote_throttle_recalibrate()
+{
+  utime_t now = ceph_clock_now(NULL);
+  double dur = now - last_recalibrate;
+  last_recalibrate = now;
+  unsigned prob = promote_probability_millis.read();
+
+  uint64_t target_obj_sec = g_conf->osd_tier_promote_max_objects_sec;
+  uint64_t target_bytes_sec = g_conf->osd_tier_promote_max_bytes_sec;
+
+  unsigned min_prob = 1;
+
+  uint64_t attempts, obj, bytes;
+  promote_counter.sample_and_attenuate(&attempts, &obj, &bytes);
+  dout(10) << __func__ << " " << attempts << " attempts, promoted "
+	   << obj << " objects and " << pretty_si_t(bytes) << " bytes; target "
+	   << target_obj_sec << " obj/sec or "
+	   << pretty_si_t(target_bytes_sec) << " bytes/sec"
+	   << dendl;
+
+  // calculate what the probability *should* be, given the targets
+  unsigned new_prob;
+  if (attempts && dur > 0) {
+    uint64_t avg_size = 1;
+    if (obj)
+      avg_size = MAX(bytes / obj, 1);
+    unsigned po = (double)target_obj_sec * dur * 1000.0 / (double)attempts;
+    unsigned pb = (double)target_bytes_sec / (double)avg_size * dur * 1000.0
+      / (double)attempts;
+    derr << __func__ << "  po " << po << " pb " << pb << " avg_size " << avg_size << dendl;
+    if (target_obj_sec && target_bytes_sec)
+      new_prob = MIN(po, pb);
+    else if (target_obj_sec)
+      new_prob = po;
+    else if (target_bytes_sec)
+      new_prob = pb;
+    else
+      new_prob = 1000;
+  } else {
+    new_prob = 1000;
+  }
+  dout(20) << __func__ << "  new_prob " << new_prob << dendl;
+
+  // correct for persistent skew between target rate and actual rate, adjust
+  double ratio = 1.0;
+  unsigned actual = 0;
+  if (attempts && obj) {
+    actual = obj * 1000 / attempts;
+    ratio = (double)actual / (double)prob;
+    new_prob = (double)new_prob / ratio;
+  }
+  new_prob = MAX(new_prob, min_prob);
+  new_prob = MIN(new_prob, 1000);
+
+  // adjust
+  prob = (prob + new_prob) / 2;
+  prob = MAX(prob, min_prob);
+  prob = MIN(prob, 1000);
+  dout(10) << __func__ << "  actual " << actual
+	   << ", actual/prob ratio " << ratio
+	   << ", adjusted new_prob " << new_prob
+	   << ", prob " << promote_probability_millis.read() << " -> " << prob
+	   << dendl;
+  promote_probability_millis.set(prob);
+
+  // set hard limits for this interval to mitigate stampedes
+  promote_max_objects = target_obj_sec * OSD::OSD_TICK_INTERVAL * 2;
+  promote_max_bytes = target_bytes_sec * OSD::OSD_TICK_INTERVAL * 2;
+}
+
+// -------------------------------------
+
 float OSDService::get_full_ratio()
 {
   float full_ratio = cct->_conf->osd_failsafe_full_ratio;
@@ -668,6 +750,11 @@ void OSDService::update_osd_stat(vector<int>& hb_peers)
 {
   Mutex::Locker lock(stat_lock);
 
+  osd_stat.hb_in.swap(hb_peers);
+  osd_stat.hb_out.clear();
+
+  osd->op_tracker.get_age_ms_histogram(&osd_stat.op_queue_age_hist);
+
   // fill in osd stats too
   struct statfs stbuf;
   int r = osd->store->statfs(&stbuf);
@@ -688,13 +775,8 @@ void OSDService::update_osd_stat(vector<int>& hb_peers)
   osd->logger->set(l_osd_stat_bytes_used, used);
   osd->logger->set(l_osd_stat_bytes_avail, avail);
 
-  osd_stat.hb_in.swap(hb_peers);
-  osd_stat.hb_out.clear();
-
   check_nearfull_warning(osd_stat);
 
-  osd->op_tracker.get_age_ms_histogram(&osd_stat.op_queue_age_hist);
-
   dout(20) << "update_osd_stat " << osd_stat << dendl;
 }
 
@@ -1102,7 +1184,7 @@ MOSDMap *OSDService::build_incremental_map_msg(epoch_t since, epoch_t to,
                                                OSDSuperblock& sblock)
 {
   MOSDMap *m = new MOSDMap(monc->get_fsid());
-  m->oldest_map = sblock.oldest_map;
+  m->oldest_map = max_oldest_map;
   m->newest_map = sblock.newest_map;
 
   for (epoch_t e = to; e > since; e--) {
@@ -1142,7 +1224,7 @@ void OSDService::send_incremental_map(epoch_t since, Connection *con,
     if (since < sblock.oldest_map) {
       // just send latest full map
       MOSDMap *m = new MOSDMap(monc->get_fsid());
-      m->oldest_map = sblock.oldest_map;
+      m->oldest_map = max_oldest_map;
       m->newest_map = sblock.newest_map;
       get_map_bl(to, m->maps[to]);
       send_map(m, con);
@@ -1318,6 +1400,7 @@ void OSDService::handle_misdirected_op(PG *pg, OpRequestRef op)
        * splitting.  The simplest thing is to detect such cases here and drop
        * them without an error (the client will resend anyway).
        */
+    assert(m->get_map_epoch() <= superblock.newest_map);
     OSDMapRef opmap = try_get_map(m->get_map_epoch());
     if (!opmap) {
       dout(7) << __func__ << ": " << *pg << " no longer have map for "
@@ -1392,7 +1475,7 @@ int OSD::mkfs(CephContext *cct, ObjectStore *store, const string &dev,
     goto free_store;
   }
 
-  ret = store->read(coll_t::meta(), OSD_SUPERBLOCK_POBJECT, 0, 0, sbbl);
+  ret = store->read(coll_t::meta(), OSD_SUPERBLOCK_GOBJECT, 0, 0, sbbl);
   if (ret >= 0) {
     /* if we already have superblock, check content of superblock */
     dout(0) << " have superblock" << dendl;
@@ -1429,10 +1512,10 @@ int OSD::mkfs(CephContext *cct, ObjectStore *store, const string &dev,
 
     ObjectStore::Transaction t;
     t.create_collection(coll_t::meta(), 0);
-    t.write(coll_t::meta(), OSD_SUPERBLOCK_POBJECT, 0, bl.length(), bl);
+    t.write(coll_t::meta(), OSD_SUPERBLOCK_GOBJECT, 0, bl.length(), bl);
     ret = store->apply_transaction(osr.get(), std::move(t));
     if (ret) {
-      derr << "OSD::mkfs: error while writing OSD_SUPERBLOCK_POBJECT: "
+      derr << "OSD::mkfs: error while writing OSD_SUPERBLOCK_GOBJECT: "
 	   << "apply_transaction returned " << ret << dendl;
       goto umount_store;
     }
@@ -1598,7 +1681,7 @@ OSD::OSD(CephContext *cct_, ObjectStore *store_,
   last_pg_create_epoch(0),
   mon_report_lock("OSD::mon_report_lock"),
   stats_ack_timeout(cct->_conf->osd_mon_ack_timeout),
-  up_thru_wanted(0), up_thru_pending(0),
+  up_thru_wanted(0),
   requested_full_first(0),
   requested_full_last(0),
   pg_stat_queue_lock("OSD::pg_stat_queue_lock"),
@@ -1788,7 +1871,7 @@ bool OSD::asok_command(string command, cmdmap_t& cmdmap, string format,
       f->close_section(); //watch
     }
 
-    f->close_section(); //watches
+    f->close_section(); //watchers
   } else if (command == "dump_reservations") {
     f->open_object_section("reservations");
     f->open_object_section("local_reservations");
@@ -1885,6 +1968,7 @@ int OSD::enable_disable_fuse(bool stop)
       derr << __func__ << " failed to rmdir " << mntpath << dendl;
       return r;
     }
+    return 0;
   }
   if (!fuse_store && g_conf->osd_objectstore_fuse) {
     dout(1) << __func__ << " enabling" << dendl;
@@ -2079,6 +2163,7 @@ int OSD::init()
   service.init();
   service.publish_map(osdmap);
   service.publish_superblock(superblock);
+  service.max_oldest_map = superblock.oldest_map;
 
   osd_lock.Unlock();
 
@@ -2493,7 +2578,7 @@ int OSD::shutdown()
   clear_pg_stat_queue();
 
   // finish ops
-  op_shardedwq.drain(); // should already be empty except for lagard PGs
+  op_shardedwq.drain(); // should already be empty except for laggard PGs
   {
     Mutex::Locker l(finished_lock);
     finished.clear(); // zap waiters (bleh, this is messy)
@@ -2653,13 +2738,13 @@ void OSD::write_superblock(ObjectStore::Transaction& t)
 
   bufferlist bl;
   ::encode(superblock, bl);
-  t.write(coll_t::meta(), OSD_SUPERBLOCK_POBJECT, 0, bl.length(), bl);
+  t.write(coll_t::meta(), OSD_SUPERBLOCK_GOBJECT, 0, bl.length(), bl);
 }
 
 int OSD::read_superblock()
 {
   bufferlist bl;
-  int r = store->read(coll_t::meta(), OSD_SUPERBLOCK_POBJECT, 0, 0, bl);
+  int r = store->read(coll_t::meta(), OSD_SUPERBLOCK_GOBJECT, 0, 0, bl);
   if (r < 0)
     return r;
 
@@ -2725,8 +2810,8 @@ void OSD::recursive_remove_collection(ObjectStore *store, spg_t pgid, coll_t tmp
     coll_t(),
     make_snapmapper_oid());
 
-  ceph::shared_ptr<ObjectStore::Sequencer> osr(
-    new ObjectStore::Sequencer("rm"));
+  ceph::shared_ptr<ObjectStore::Sequencer> osr (std::make_shared<
+                                      ObjectStore::Sequencer>("rm"));
   ObjectStore::Transaction t;
   SnapMapper mapper(&driver, 0, 0, 0, pgid.shard);
 
@@ -3321,11 +3406,10 @@ void OSD::build_past_intervals_parallel()
  */
 void OSD::handle_pg_peering_evt(
   spg_t pgid,
-  const pg_info_t& info,
+  const pg_history_t& orig_history,
   pg_interval_map_t& pi,
   epoch_t epoch,
-  pg_shard_t from,
-  bool primary,
+  bool same_primary,
   PG::CephPeeringEvtRef evt)
 {
   if (service.splitting(pgid)) {
@@ -3343,11 +3427,18 @@ void OSD::handle_pg_peering_evt(
       pgid.pgid, &up, &up_primary, &acting, &acting_primary);
     int role = osdmap->calc_pg_role(whoami, acting, acting.size());
 
-    pg_history_t history = info.history;
+    pg_history_t history = orig_history;
     bool valid_history = project_pg_history(
       pgid, history, epoch, up, up_primary, acting, acting_primary);
 
-    if (!valid_history || epoch < history.same_interval_since) {
+    if (same_primary && epoch < history.same_primary_since) {
+      dout(10) << "get_or_create_pg " << pgid << " primary changed in "
+	       << history.same_primary_since << " (msg from " << epoch << ")"
+	       << dendl;
+      return;
+    }
+    if (!valid_history ||
+	(!same_primary && epoch < history.same_interval_since)) {
       dout(10) << "get_or_create_pg " << pgid << " acting changed in "
 	       << history.same_interval_since << " (msg from " << epoch << ")"
 	       << dendl;
@@ -3473,7 +3564,15 @@ void OSD::handle_pg_peering_evt(
   } else {
     // already had it.  did the mapping change?
     PG *pg = _lookup_lock_pg(pgid);
-    if (epoch < pg->info.history.same_interval_since) {
+    if (same_primary && epoch < pg->info.history.same_primary_since) {
+      dout(10) << "get_or_create_pg " << pgid << " primary changed in "
+	       << pg->info.history.same_primary_since
+	       << " (msg from " << epoch << ")"
+	       << dendl;
+      pg->unlock();
+      return;
+    }
+    if (!same_primary && epoch < pg->info.history.same_interval_since) {
       dout(10) << *pg << " get_or_create_pg acting changed in "
 	       << pg->info.history.same_interval_since
 	       << " (msg from " << epoch << ")" << dendl;
@@ -3662,10 +3761,11 @@ void OSD::maybe_update_heartbeat_peers()
     }
   }
 
-  Mutex::Locker l(heartbeat_lock);
   if (!heartbeat_peers_need_update())
     return;
-  heartbeat_need_update = false;
+  heartbeat_clear_peers_need_update();
+
+  Mutex::Locker l(heartbeat_lock);
 
   dout(10) << "maybe_update_heartbeat_peers updating" << dendl;
 
@@ -3699,7 +3799,7 @@ void OSD::maybe_update_heartbeat_peers()
   if (next >= 0)
     want.insert(next);
   int prev = osdmap->get_previous_up_osd_before(whoami);
-  if (prev >= 0)
+  if (prev >= 0 && prev != next)
     want.insert(prev);
 
   for (set<int>::iterator p = want.begin(); p != want.end(); ++p) {
@@ -4118,6 +4218,8 @@ void OSD::tick()
     recovery_tp.wake();
 
     check_replay_queue();
+
+    service.promote_throttle_recalibrate();
   }
 
   // only do waiters if dispatch() isn't currently running.  (if it is,
@@ -4401,9 +4503,12 @@ bool remove_dir(
     store->get_ideal_list_max(),
     &olist,
     &next);
+  // default cont to true, this is safe because caller(OSD::RemoveWQ::_process()) 
+  // will recheck the answer before it really goes on.
+  bool cont = true;
   for (vector<ghobject_t>::iterator i = olist.begin();
        i != olist.end();
-       ++i, ++num) {
+       ++i) {
     if (i->is_pgmeta())
       continue;
     OSDriver::OSTransaction _t(osdriver->get_transaction(&t));
@@ -4412,10 +4517,10 @@ bool remove_dir(
       assert(0);
     }
     t.remove(coll, *i);
-    if (num >= cct->_conf->osd_target_transaction_size) {
+    if (++num >= cct->_conf->osd_target_transaction_size) {
       C_SaferCond waiter;
       store->queue_transaction(osr, std::move(t), &waiter);
-      bool cont = dstate->pause_clearing();
+      cont = dstate->pause_clearing();
       handle.suspend_tp_timeout();
       waiter.wait();
       handle.reset_tp_timeout();
@@ -4427,14 +4532,16 @@ bool remove_dir(
       num = 0;
     }
   }
-  C_SaferCond waiter;
-  store->queue_transaction(osr, std::move(t), &waiter);
-  bool cont = dstate->pause_clearing();
-  handle.suspend_tp_timeout();
-  waiter.wait();
-  handle.reset_tp_timeout();
-  if (cont)
-    cont = dstate->resume_clearing();
+  if (num) {
+    C_SaferCond waiter;
+    store->queue_transaction(osr, std::move(t), &waiter);
+    cont = dstate->pause_clearing();
+    handle.suspend_tp_timeout();
+    waiter.wait();
+    handle.reset_tp_timeout();
+    if (cont)
+      cont = dstate->resume_clearing();
+  }
   // whether there are more objects to remove in the collection
   *finished = next.is_max();
   return cont;
@@ -4795,7 +4902,6 @@ void OSD::send_alive()
   epoch_t up_thru = osdmap->get_up_thru(whoami);
   dout(10) << "send_alive up_thru currently " << up_thru << " want " << up_thru_wanted << dendl;
   if (up_thru_wanted > up_thru) {
-    up_thru_pending = up_thru_wanted;
     dout(10) << "send_alive want " << up_thru_wanted << dendl;
     monc->send_mon_message(new MOSDAlive(osdmap->get_epoch(), up_thru_wanted));
   }
@@ -5291,7 +5397,12 @@ void OSD::do_command(Connection *con, ceph_tid_t tid, vector<string>& cmd, buffe
 	  // simulate pg <pgid> cmd= for pg->do-command
 	  if (prefix != "pg")
 	    cmd_putval(cct, cmdmap, "cmd", prefix);
-	  r = pg->do_command(cmdmap, ss, data, odata);
+	  r = pg->do_command(cmdmap, ss, data, odata, con, tid);
+	  if (r == -EAGAIN) {
+	    pg->unlock();
+	    // don't reply, pg will do so async
+	    return;
+	  }
 	} else {
 	  ss << "not primary for pgid " << pgid;
 
@@ -5322,8 +5433,8 @@ void OSD::do_command(Connection *con, ceph_tid_t tid, vector<string>& cmd, buffe
     cmd_getval(cct, cmdmap, "object_size", osize, (int64_t)0);
     cmd_getval(cct, cmdmap, "object_num", onum, (int64_t)0);
 
-    ceph::shared_ptr<ObjectStore::Sequencer> osr(
-      new ObjectStore::Sequencer("bench"));
+    ceph::shared_ptr<ObjectStore::Sequencer> osr (std::make_shared<
+                                        ObjectStore::Sequencer>("bench"));
 
     uint32_t duration = g_conf->osd_bench_duration;
 
@@ -5591,7 +5702,6 @@ void OSD::do_command(Connection *con, ceph_tid_t tid, vector<string>& cmd, buffe
     reply->set_data(odata);
     con->send_message(reply);
   }
-  return;
 }
 
 
@@ -5949,6 +6059,14 @@ epoch_t op_required_epoch(OpRequestRef op)
     return replica_op_required_epoch<MOSDECSubOpReadReply, MSG_OSD_EC_READ_REPLY>(op);
   case MSG_OSD_REP_SCRUB:
     return replica_op_required_epoch<MOSDRepScrub, MSG_OSD_REP_SCRUB>(op);
+  case MSG_OSD_PG_UPDATE_LOG_MISSING:
+    return replica_op_required_epoch<
+      MOSDPGUpdateLogMissing, MSG_OSD_PG_UPDATE_LOG_MISSING>(
+      op);
+  case MSG_OSD_PG_UPDATE_LOG_MISSING_REPLY:
+    return replica_op_required_epoch<
+      MOSDPGUpdateLogMissingReply, MSG_OSD_PG_UPDATE_LOG_MISSING_REPLY>(
+      op);
   default:
     assert(0);
     return 0;
@@ -6065,6 +6183,15 @@ bool OSD::dispatch_op_fast(OpRequestRef& op, OSDMapRef& osdmap)
   case MSG_OSD_REP_SCRUB:
     handle_replica_op<MOSDRepScrub, MSG_OSD_REP_SCRUB>(op, osdmap);
     break;
+  case MSG_OSD_PG_UPDATE_LOG_MISSING:
+    handle_replica_op<MOSDPGUpdateLogMissing, MSG_OSD_PG_UPDATE_LOG_MISSING>(
+      op, osdmap);
+    break;
+  case MSG_OSD_PG_UPDATE_LOG_MISSING_REPLY:
+    handle_replica_op<MOSDPGUpdateLogMissingReply,
+		      MSG_OSD_PG_UPDATE_LOG_MISSING_REPLY>(
+      op, osdmap);
+    break;
   default:
     assert(0);
   }
@@ -6381,6 +6508,17 @@ void OSD::note_up_osd(int peer)
   service.forget_peer_epoch(peer, osdmap->get_epoch() - 1);
 }
 
+struct C_OnMapCommit : public Context {
+  OSD *osd;
+  epoch_t first, last;
+  MOSDMap *msg;
+  C_OnMapCommit(OSD *o, epoch_t f, epoch_t l, MOSDMap *m)
+    : osd(o), first(f), last(l), msg(m) {}
+  void finish(int r) {
+    osd->_committed_osd_maps(first, last, msg);
+  }
+};
+
 struct C_OnMapApply : public Context {
   OSDService *service;
   list<OSDMapRef> pinned_maps;
@@ -6411,7 +6549,8 @@ void OSD::handle_osd_map(MOSDMap *m)
   assert(osd_lock.is_locked());
   list<OSDMapRef> pinned_maps;
   if (m->fsid != monc->get_fsid()) {
-    dout(0) << "handle_osd_map fsid " << m->fsid << " != " << monc->get_fsid() << dendl;
+    dout(0) << "handle_osd_map fsid " << m->fsid << " != "
+	    << monc->get_fsid() << dendl;
     m->put();
     return;
   }
@@ -6422,7 +6561,8 @@ void OSD::handle_osd_map(MOSDMap *m)
   }
 
   Session *session = static_cast<Session *>(m->get_connection()->get_priv());
-  if (session && !(session->entity_name.is_mon() || session->entity_name.is_osd())) {
+  if (session && !(session->entity_name.is_mon() ||
+		   session->entity_name.is_osd())) {
     //not enough perms!
     dout(10) << "got osd map from Session " << session
              << " which we can't take maps from (not a mon or osd)" << dendl;
@@ -6439,17 +6579,22 @@ void OSD::handle_osd_map(MOSDMap *m)
   epoch_t first = m->get_first();
   epoch_t last = m->get_last();
   dout(3) << "handle_osd_map epochs [" << first << "," << last << "], i have "
-	  << osdmap->get_epoch()
+	  << superblock.newest_map
 	  << ", src has [" << m->oldest_map << "," << m->newest_map << "]"
 	  << dendl;
 
   logger->inc(l_osd_map);
   logger->inc(l_osd_mape, last - first + 1);
-  if (first <= osdmap->get_epoch())
-    logger->inc(l_osd_mape_dup, osdmap->get_epoch() - first + 1);
+  if (first <= superblock.newest_map)
+    logger->inc(l_osd_mape_dup, superblock.newest_map - first + 1);
+  if (service.max_oldest_map < m->oldest_map) {
+    service.max_oldest_map = m->oldest_map;
+    assert(service.max_oldest_map >= superblock.oldest_map);
+  }
 
-  // make sure there is something new, here, before we bother flushing the queues and such
-  if (last <= osdmap->get_epoch()) {
+  // make sure there is something new, here, before we bother flushing
+  // the queues and such
+  if (last <= superblock.newest_map) {
     dout(10) << " no new maps here, dropping" << dendl;
     m->put();
     return;
@@ -6457,11 +6602,11 @@ void OSD::handle_osd_map(MOSDMap *m)
 
   // missing some?
   bool skip_maps = false;
-  if (first > osdmap->get_epoch() + 1) {
-    dout(10) << "handle_osd_map message skips epochs " << osdmap->get_epoch() + 1
-	     << ".." << (first-1) << dendl;
-    if (m->oldest_map <= osdmap->get_epoch() + 1) {
-      osdmap_subscribe(osdmap->get_epoch()+1, false);
+  if (first > superblock.newest_map + 1) {
+    dout(10) << "handle_osd_map message skips epochs "
+	     << superblock.newest_map + 1 << ".." << (first-1) << dendl;
+    if (m->oldest_map <= superblock.newest_map + 1) {
+      osdmap_subscribe(superblock.newest_map + 1, false);
       m->put();
       return;
     }
@@ -6480,7 +6625,7 @@ void OSD::handle_osd_map(MOSDMap *m)
   ObjectStore::Transaction t;
 
   // store new maps: queue for disk and put in the osdmap cache
-  epoch_t start = MAX(osdmap->get_epoch() + 1, first);
+  epoch_t start = MAX(superblock.newest_map + 1, first);
   for (epoch_t e = start; e <= last; e++) {
     map<epoch_t,bufferlist>::iterator p;
     p = m->maps.find(e);
@@ -6561,7 +6706,7 @@ void OSD::handle_osd_map(MOSDMap *m)
   // even if this map isn't from a mon, we may have satisfied our subscription
   monc->sub_got("osdmap", last);
 
-  if (last <= osdmap->get_epoch()) {
+  if (last <= superblock.newest_map) {
     dout(10) << " no new maps here, dropping" << dendl;
     m->put();
     return;
@@ -6578,8 +6723,9 @@ void OSD::handle_osd_map(MOSDMap *m)
       t.remove(coll_t::meta(), get_inc_osdmap_pobject_name(e));
       superblock.oldest_map = e+1;
       num++;
+      // make sure we at least keep pace with incoming maps
       if (num >= cct->_conf->osd_target_transaction_size &&
-	  (uint64_t)num > (last - first))  // make sure we at least keep pace with incoming maps
+	  (uint64_t)num > (last - first))
 	break;
     }
   }
@@ -6587,12 +6733,41 @@ void OSD::handle_osd_map(MOSDMap *m)
   if (!superblock.oldest_map || skip_maps)
     superblock.oldest_map = first;
   superblock.newest_map = last;
+  superblock.current_epoch = last;
 
+  // note in the superblock that we were clean thru the prior epoch
+  epoch_t boot_epoch = service.get_boot_epoch();
+  if (boot_epoch && boot_epoch >= superblock.mounted) {
+    superblock.mounted = boot_epoch;
+    superblock.clean_thru = last;
+  }
+
+  // superblock and commit
+  write_superblock(t);
+  store->queue_transaction(
+    service.meta_osr.get(),
+    std::move(t),
+    new C_OnMapApply(&service, pinned_maps, last),
+    new C_OnMapCommit(this, start, last, m), 0);
+  service.publish_superblock(superblock);
+}
+
+void OSD::_committed_osd_maps(epoch_t first, epoch_t last, MOSDMap *m)
+{
+  dout(10) << __func__ << " " << first << ".." << last << dendl;
+  Mutex::Locker l(osd_lock);
   map_lock.get_write();
 
+  bool do_shutdown = false;
+  bool do_restart = false;
+  bool network_error = false;
+
   // advance through the new maps
-  for (epoch_t cur = start; cur <= superblock.newest_map; cur++) {
-    dout(10) << " advance to epoch " << cur << " (<= newest " << superblock.newest_map << ")" << dendl;
+  for (epoch_t cur = first; cur <= last; cur++) {
+    dout(10) << " advance to epoch " << cur
+	     << " (<= last " << last
+	     << " <= newest_map " << superblock.newest_map
+	     << ")" << dendl;
 
     OSDMapRef newmap = get_map(cur);
     assert(newmap);  // we just cached it above!
@@ -6616,11 +6791,39 @@ void OSD::handle_osd_map(MOSDMap *m)
       }
     }
 
+    if (osdmap->test_flag(CEPH_OSDMAP_NOUP) &&
+	!newmap->test_flag(CEPH_OSDMAP_NOUP)) {
+      dout(10) << __func__ << " NOUP flag cleared in " << newmap->get_epoch()
+	       << dendl;
+      if (is_booting()) {
+	// this captures the case where we sent the boot message while
+	// NOUP was being set on the mon and our boot request was
+	// dropped, and then later it is cleared.  it imperfectly
+	// handles the case where our original boot message was not
+	// dropped and we restart even though we might have booted, but
+	// that is harmless (boot will just take slightly longer).
+	do_restart = true;
+      }
+    }
+
     osdmap = newmap;
 
-    superblock.current_epoch = cur;
-    advance_map();
     had_map_since = ceph_clock_now(cct);
+
+    epoch_t up_epoch;
+    epoch_t boot_epoch;
+    service.retrieve_epochs(&boot_epoch, &up_epoch, NULL);
+    if (!up_epoch &&
+	osdmap->is_up(whoami) &&
+	osdmap->get_inst(whoami) == client_messenger->get_myinst()) {
+      up_epoch = osdmap->get_epoch();
+      dout(10) << "up_epoch is " << up_epoch << dendl;
+      if (!boot_epoch) {
+	boot_epoch = osdmap->get_epoch();
+	dout(10) << "boot_epoch is " << boot_epoch << dendl;
+      }
+      service.set_epochs(&boot_epoch, &up_epoch, NULL);
+    }
   }
 
   epoch_t _bind_epoch = service.get_bind_epoch();
@@ -6638,45 +6841,56 @@ void OSD::handle_osd_map(MOSDMap *m)
     }
   }
 
-  bool do_shutdown = false;
-  bool do_restart = false;
-  bool network_error = false;
   if (osdmap->get_epoch() > 0 &&
       is_active()) {
     if (!osdmap->exists(whoami)) {
       dout(0) << "map says i do not exist.  shutting down." << dendl;
-      do_shutdown = true;   // don't call shutdown() while we have everything paused
+      do_shutdown = true;   // don't call shutdown() while we have
+			    // everything paused
     } else if (!osdmap->is_up(whoami) ||
-	       !osdmap->get_addr(whoami).probably_equals(client_messenger->get_myaddr()) ||
-	       !osdmap->get_cluster_addr(whoami).probably_equals(cluster_messenger->get_myaddr()) ||
-	       !osdmap->get_hb_back_addr(whoami).probably_equals(hb_back_server_messenger->get_myaddr()) ||
+	       !osdmap->get_addr(whoami).probably_equals(
+		 client_messenger->get_myaddr()) ||
+	       !osdmap->get_cluster_addr(whoami).probably_equals(
+		 cluster_messenger->get_myaddr()) ||
+	       !osdmap->get_hb_back_addr(whoami).probably_equals(
+		 hb_back_server_messenger->get_myaddr()) ||
 	       (osdmap->get_hb_front_addr(whoami) != entity_addr_t() &&
-                !osdmap->get_hb_front_addr(whoami).probably_equals(hb_front_server_messenger->get_myaddr()))) {
+                !osdmap->get_hb_front_addr(whoami).probably_equals(
+		  hb_front_server_messenger->get_myaddr()))) {
       if (!osdmap->is_up(whoami)) {
 	if (service.is_preparing_to_stop() || service.is_stopping()) {
 	  service.got_stop_ack();
 	} else {
 	  clog->warn() << "map e" << osdmap->get_epoch()
-		      << " wrongly marked me down";
+		       << " wrongly marked me down";
 	}
-      }
-      else if (!osdmap->get_addr(whoami).probably_equals(client_messenger->get_myaddr()))
+      } else if (!osdmap->get_addr(whoami).probably_equals(
+		   client_messenger->get_myaddr())) {
 	clog->error() << "map e" << osdmap->get_epoch()
-		    << " had wrong client addr (" << osdmap->get_addr(whoami)
-		     << " != my " << client_messenger->get_myaddr() << ")";
-      else if (!osdmap->get_cluster_addr(whoami).probably_equals(cluster_messenger->get_myaddr()))
+		      << " had wrong client addr (" << osdmap->get_addr(whoami)
+		      << " != my " << client_messenger->get_myaddr() << ")";
+      } else if (!osdmap->get_cluster_addr(whoami).probably_equals(
+		   cluster_messenger->get_myaddr())) {
 	clog->error() << "map e" << osdmap->get_epoch()
-		    << " had wrong cluster addr (" << osdmap->get_cluster_addr(whoami)
-		     << " != my " << cluster_messenger->get_myaddr() << ")";
-      else if (!osdmap->get_hb_back_addr(whoami).probably_equals(hb_back_server_messenger->get_myaddr()))
+		      << " had wrong cluster addr ("
+		      << osdmap->get_cluster_addr(whoami)
+		      << " != my " << cluster_messenger->get_myaddr() << ")";
+      } else if (!osdmap->get_hb_back_addr(whoami).probably_equals(
+		   hb_back_server_messenger->get_myaddr())) {
 	clog->error() << "map e" << osdmap->get_epoch()
-		    << " had wrong hb back addr (" << osdmap->get_hb_back_addr(whoami)
-		     << " != my " << hb_back_server_messenger->get_myaddr() << ")";
-      else if (osdmap->get_hb_front_addr(whoami) != entity_addr_t() &&
-               !osdmap->get_hb_front_addr(whoami).probably_equals(hb_front_server_messenger->get_myaddr()))
+		      << " had wrong hb back addr ("
+		      << osdmap->get_hb_back_addr(whoami)
+		      << " != my " << hb_back_server_messenger->get_myaddr()
+		      << ")";
+      } else if (osdmap->get_hb_front_addr(whoami) != entity_addr_t() &&
+		 !osdmap->get_hb_front_addr(whoami).probably_equals(
+		   hb_front_server_messenger->get_myaddr())) {
 	clog->error() << "map e" << osdmap->get_epoch()
-		    << " had wrong hb front addr (" << osdmap->get_hb_front_addr(whoami)
-		     << " != my " << hb_front_server_messenger->get_myaddr() << ")";
+		      << " had wrong hb front addr ("
+		      << osdmap->get_hb_front_addr(whoami)
+		      << " != my " << hb_front_server_messenger->get_myaddr()
+		      << ")";
+      }
 
       if (!service.is_stopping()) {
         epoch_t up_epoch = 0;
@@ -6689,7 +6903,8 @@ void OSD::handle_osd_map(MOSDMap *m)
 	utime_t grace = utime_t(g_conf->osd_max_markdown_period, 0);
 	osd_markdown_log.push_back(now);
 	//clear all out-of-date log
-	while (!osd_markdown_log.empty() && osd_markdown_log.front() + grace < now)
+	while (!osd_markdown_log.empty() &&
+	       osd_markdown_log.front() + grace < now)
 	  osd_markdown_log.pop_front();
 	if ((int)osd_markdown_log.size() > g_conf->osd_max_markdown_count) {
 	  do_restart = false;
@@ -6728,23 +6943,6 @@ void OSD::handle_osd_map(MOSDMap *m)
     }
   }
 
-
-  // note in the superblock that we were clean thru the prior epoch
-  epoch_t boot_epoch = service.get_boot_epoch();
-  if (boot_epoch && boot_epoch >= superblock.mounted) {
-    superblock.mounted = boot_epoch;
-    superblock.clean_thru = osdmap->get_epoch();
-  }
-
-  // superblock and commit
-  write_superblock(t);
-  store->queue_transaction(
-    service.meta_osr.get(),
-    std::move(t),
-    new C_OnMapApply(&service, pinned_maps, osdmap->get_epoch()),
-    0, 0);
-  service.publish_superblock(superblock);
-
   map_lock.put_write();
 
   check_osdmap_features(store);
@@ -6763,15 +6961,18 @@ void OSD::handle_osd_map(MOSDMap *m)
   }
 
   if (m->newest_map && m->newest_map > last) {
-    dout(10) << " msg say newest map is " << m->newest_map << ", requesting more" << dendl;
+    dout(10) << " msg say newest map is " << m->newest_map
+	     << ", requesting more" << dendl;
     osdmap_subscribe(osdmap->get_epoch()+1, false);
   }
   else if (do_shutdown) {
     if (network_error) {
       Mutex::Locker l(heartbeat_lock);
-      map<int,pair<utime_t,entity_inst_t>>::iterator it = failure_pending.begin();
+      map<int,pair<utime_t,entity_inst_t>>::iterator it =
+	failure_pending.begin();
       while (it != failure_pending.end()) {
-        dout(10) << "handle_osd_ping canceling in-flight failure report for osd." << it->first << dendl;
+        dout(10) << "handle_osd_ping canceling in-flight failure report for osd."
+		 << it->first << dendl;
         send_still_alive(osdmap->get_epoch(), it->second.second);
         failure_pending.erase(it++);
       }
@@ -6921,32 +7122,6 @@ bool OSD::advance_pg(
   return true;
 }
 
-/**
- * update service map; check pg creations
- */
-void OSD::advance_map()
-{
-  assert(osd_lock.is_locked());
-
-  dout(7) << "advance_map epoch " << osdmap->get_epoch()
-          << dendl;
-
-  epoch_t up_epoch;
-  epoch_t boot_epoch;
-  service.retrieve_epochs(&boot_epoch, &up_epoch, NULL);
-  if (!up_epoch &&
-      osdmap->is_up(whoami) &&
-      osdmap->get_inst(whoami) == client_messenger->get_myinst()) {
-    up_epoch = osdmap->get_epoch();
-    dout(10) << "up_epoch is " << up_epoch << dendl;
-    if (!boot_epoch) {
-      boot_epoch = osdmap->get_epoch();
-      dout(10) << "boot_epoch is " << boot_epoch << dendl;
-    }
-    service.set_epochs(&boot_epoch, &up_epoch, NULL);
-  }
-}
-
 void OSD::consume_map()
 {
   assert(osd_lock.is_locked());
@@ -7306,42 +7481,32 @@ void OSD::handle_pg_create(OpRequestRef op)
     bool mapped = osdmap->get_primary_shard(on, &pgid);
     assert(mapped);
 
-    // does it already exist?
-    if (_have_pg(pgid)) {
-      dout(10) << "mkpg " << pgid << "  already exists, skipping" << dendl;
-      continue;
-    }
-
+    pg_interval_map_t pi;
     pg_history_t history;
     history.epoch_created = created;
     history.last_scrub_stamp = ci->second;
     history.last_deep_scrub_stamp = ci->second;
+
+    // project history from created epoch (handle_pg_peering_evt does
+    // it from msg send epoch)
     bool valid_history = project_pg_history(
       pgid, history, created, up, up_primary, acting, acting_primary);
-    /* the pg creation message must have come from a mon and therefore
-     * cannot be on the other side of a map gap
-     */
+    // the pg creation message must have come from a mon and therefore
+    // cannot be on the other side of a map gap
     assert(valid_history);
 
-    PG::RecoveryCtx rctx = create_context();
-    const pg_pool_t* pp = osdmap->get_pg_pool(pgid.pool());
-    PG::_create(*rctx.transaction, pgid, pgid.get_split_bits(pp->get_pg_num()));
-    PG::_init(*rctx.transaction, pgid, pp);
-
-    pg_interval_map_t pi;
-    PG *pg = _create_lock_pg(
-      osdmap, pgid, false, false,
-      0, up, up_primary,
-      acting, acting_primary,
-      history, pi,
-      *rctx.transaction);
-    pg->info.last_epoch_started = created;
-    pg->handle_create(&rctx);
-    pg->write_if_dirty(*rctx.transaction);
-    pg->publish_stats_to_osd();
-    pg->unlock();
-    wake_pg_waiters(pgid);
-    dispatch_context(rctx, pg, osdmap);
+    handle_pg_peering_evt(
+      pgid,
+      history,
+      pi,
+      m->epoch,
+      true,  // same primary, bc this is a create
+      PG::CephPeeringEvtRef(
+	new PG::CephPeeringEvt(
+	  m->epoch,
+	  m->epoch,
+	  PG::NullEvt()))
+      );
   }
 
   last_pg_create_epoch = m->epoch;
@@ -7566,8 +7731,9 @@ void OSD::handle_pg_notify(OpRequestRef op)
 
     handle_pg_peering_evt(
       spg_t(it->first.info.pgid.pgid, it->first.to),
-      it->first.info, it->second,
-      it->first.query_epoch, pg_shard_t(from, it->first.from), true,
+      it->first.info.history, it->second,
+      it->first.query_epoch,
+      false, // same interval
       PG::CephPeeringEvtRef(
 	new PG::CephPeeringEvt(
 	  it->first.epoch_sent, it->first.query_epoch,
@@ -7598,8 +7764,8 @@ void OSD::handle_pg_log(OpRequestRef op)
   op->mark_started();
   handle_pg_peering_evt(
     spg_t(m->info.pgid.pgid, m->to),
-    m->info, m->past_intervals, m->get_epoch(),
-    pg_shard_t(from, m->from), false,
+    m->info.history, m->past_intervals, m->get_epoch(),
+    false, // same interval
     PG::CephPeeringEvtRef(
       new PG::CephPeeringEvt(
 	m->get_epoch(), m->get_query_epoch(),
@@ -7632,8 +7798,8 @@ void OSD::handle_pg_info(OpRequestRef op)
 
     handle_pg_peering_evt(
       spg_t(p->first.info.pgid.pgid, p->first.to),
-      p->first.info, p->second, p->first.epoch_sent,
-      pg_shard_t(from, p->first.from), false,
+      p->first.info.history, p->second, p->first.epoch_sent,
+      false, // same interval
       PG::CephPeeringEvtRef(
 	new PG::CephPeeringEvt(
 	  p->first.epoch_sent, p->first.query_epoch,
diff --git a/src/osd/OSD.h b/src/osd/OSD.h
index 169623a..d6a8d2d 100644
--- a/src/osd/OSD.h
+++ b/src/osd/OSD.h
@@ -40,6 +40,7 @@
 #include "messages/MOSDRepScrub.h"
 #include "OpRequest.h"
 
+#include <atomic>
 #include <map>
 #include <memory>
 #include "include/memory.h"
@@ -317,7 +318,7 @@ public:
      * CLEARING_WAITING and QUEUED indicate that the remover will check
      * stop_deleting before queueing any further operations.  CANCELED
      * indicates that the remover has already halted.  DELETED_DIR
-     * indicates that the deletion has been fully queueud.
+     * indicates that the deletion has been fully queued.
      */
     while (status == DELETING_DIR || status == CLEARING_DIR)
       cond.Wait(lock);
@@ -475,6 +476,7 @@ public:
 
   int get_nodeid() const { return whoami; }
 
+  std::atomic<epoch_t> max_oldest_map;
   OSDMapRef osdmap;
   OSDMapRef get_osdmap() {
     Mutex::Locker l(publish_lock);
@@ -781,6 +783,29 @@ public:
     flush_mode_high_count --;
   }
 
+  /// throttle promotion attempts
+  atomic_t promote_probability_millis; ///< probability thousands. one word.
+  PromoteCounter promote_counter;
+  utime_t last_recalibrate;
+  unsigned long promote_max_objects, promote_max_bytes;
+
+  bool promote_throttle() {
+    // NOTE: lockless!  we rely on the probability being a single word.
+    promote_counter.attempt();
+    if ((unsigned)rand() % 1000 > promote_probability_millis.read())
+      return true;  // yes throttle (no promote)
+    if (promote_max_objects &&
+	promote_counter.objects.read() > promote_max_objects)
+      return true;  // yes throttle
+    if (promote_max_bytes &&
+	promote_counter.bytes.read() > promote_max_bytes)
+      return true;  // yes throttle
+    return false;   //  no throttle (promote)
+  }
+  void promote_finish(uint64_t bytes) {
+    promote_counter.finish(bytes);
+  }
+  void promote_throttle_recalibrate();
 
   // -- Objecter, for teiring reads/writes from/to other OSDs --
   Objecter *objecter;
@@ -1541,6 +1566,10 @@ private:
     Mutex::Locker l(heartbeat_update_lock);
     heartbeat_need_update = true;
   }
+  void heartbeat_clear_peers_need_update() {
+    Mutex::Locker l(heartbeat_update_lock);
+    heartbeat_need_update = false;
+  }
   void heartbeat();
   void heartbeat_check();
   void heartbeat_entry();
@@ -1565,7 +1594,7 @@ public:
 
   struct HeartbeatDispatcher : public Dispatcher {
     OSD *osd;
-    explicit HeartbeatDispatcher(OSD *o) : Dispatcher(cct), osd(o) {}
+    explicit HeartbeatDispatcher(OSD *o) : Dispatcher(o->cct), osd(o) {}
     bool ms_dispatch(Message *m) {
       return osd->heartbeat_dispatch(m);
     }
@@ -1851,8 +1880,10 @@ private:
 
   void wait_for_new_map(OpRequestRef op);
   void handle_osd_map(class MOSDMap *m);
+  void _committed_osd_maps(epoch_t first, epoch_t last, class MOSDMap *m);
   void note_down_osd(int osd);
   void note_up_osd(int osd);
+  friend class C_OnMapCommit;
 
   bool advance_pg(
     epoch_t advance_to, PG *pg,
@@ -1860,7 +1891,6 @@ private:
     PG::RecoveryCtx *rctx,
     set<boost::intrusive_ptr<PG> > *split_pgs
   );
-  void advance_map();
   void consume_map();
   void activate_map();
 
@@ -1935,11 +1965,10 @@ protected:
 
   void handle_pg_peering_evt(
     spg_t pgid,
-    const pg_info_t& info,
+    const pg_history_t& orig_history,
     pg_interval_map_t& pi,
     epoch_t epoch,
-    pg_shard_t from,
-    bool primary,
+    bool same_primary,
     PG::CephPeeringEvtRef evt);
   
   void load_pgs();
@@ -2015,7 +2044,6 @@ protected:
 
   // -- alive --
   epoch_t up_thru_wanted;
-  epoch_t up_thru_pending;
 
   void queue_want_up_thru(epoch_t want);
   void send_alive();
@@ -2300,6 +2328,8 @@ protected:
     case MSG_OSD_EC_READ:
     case MSG_OSD_EC_READ_REPLY:
     case MSG_OSD_REP_SCRUB:
+    case MSG_OSD_PG_UPDATE_LOG_MISSING:
+    case MSG_OSD_PG_UPDATE_LOG_MISSING_REPLY:
       return true;
     default:
       return false;
diff --git a/src/osd/OSDMap.cc b/src/osd/OSDMap.cc
index 9de54a9..3798652 100644
--- a/src/osd/OSDMap.cc
+++ b/src/osd/OSDMap.cc
@@ -162,7 +162,7 @@ int OSDMap::Incremental::get_net_marked_out(const OSDMap *previous) const
        ++p) {
     if (p->second == CEPH_OSD_OUT && !previous->is_out(p->first))
       n++;  // marked out
-    if (p->second != CEPH_OSD_OUT && previous->is_out(p->first))
+    else if (p->second != CEPH_OSD_OUT && previous->is_out(p->first))
       n--;  // marked in
   }
   return n;
@@ -283,7 +283,7 @@ bool OSDMap::containing_subtree_is_down(CephContext *cct, int id, int subtree_ty
       return false;
     }
 
-    // is this a big enough subtree to be done?
+    // is this a big enough subtree to be marked as down?
     if (type >= subtree_type) {
       ldout(cct, 30) << "containing_subtree_is_down(" << id << ") = true ... " << type << " >= " << subtree_type << dendl;
       return true;
@@ -1010,7 +1010,7 @@ int OSDMap::identify_osd(const uuid_d& u) const
   return -1;
 }
 
-bool OSDMap::find_osd_on_ip(const entity_addr_t& ip) const
+int OSDMap::find_osd_on_ip(const entity_addr_t& ip) const
 {
   for (int i=0; i<max_osd; i++)
     if (exists(i) && (get_addr(i).is_same_host(ip) || get_cluster_addr(i).is_same_host(ip)))
@@ -2771,8 +2771,8 @@ int OSDMap::build_simple_crush_map(CephContext *cct, CrushWrapper& crush,
     loc["rack"] = "localrack";
     loc["root"] = "default";
     ldout(cct, 10) << " adding osd." << o << " at " << loc << dendl;
-    char name[8];
-    sprintf(name, "osd.%d", o);
+    char name[32];
+    snprintf(name, sizeof(name), "osd.%d", o);
     crush.insert_item(cct, o, 1.0, name, loc);
   }
 
@@ -2875,3 +2875,161 @@ int OSDMap::build_simple_crush_rulesets(CephContext *cct,
   // require the crush_v2 feature of clients
   return 0;
 }
+
+int OSDMap::summarize_mapping_stats(
+  OSDMap *newmap,
+  const set<int64_t> *pools,
+  std::string *out,
+  Formatter *f) const
+{
+  set<int64_t> ls;
+  if (pools) {
+    ls = *pools;
+  } else {
+    for (auto &p : get_pools())
+      ls.insert(p.first);
+  }
+
+  unsigned total_pg = 0;
+  unsigned moved_pg = 0;
+  vector<unsigned> base_by_osd(get_max_osd(), 0);
+  vector<unsigned> new_by_osd(get_max_osd(), 0);
+  for (int64_t pool_id : ls) {
+    const pg_pool_t *pi = get_pg_pool(pool_id);
+    vector<int> up, up2, acting;
+    int up_primary, acting_primary;
+    for (unsigned ps = 0; ps < pi->get_pg_num(); ++ps) {
+      pg_t pgid(ps, pool_id, -1);
+      total_pg += pi->get_size();
+      pg_to_up_acting_osds(pgid, &up, &up_primary,
+			   &acting, &acting_primary);
+      for (int osd : up) {
+	if (osd >= 0 && osd < get_max_osd())
+	  ++base_by_osd[osd];
+      }
+      if (newmap) {
+	newmap->pg_to_up_acting_osds(pgid, &up2, &up_primary,
+				     &acting, &acting_primary);
+	for (int osd : up2) {
+	  if (osd >= 0 && osd < get_max_osd())
+	    ++new_by_osd[osd];
+	}
+	if (pi->type == pg_pool_t::TYPE_ERASURE) {
+	  for (unsigned i=0; i<up.size(); ++i) {
+	    if (up[i] != up2[i]) {
+	      ++moved_pg;
+	    }
+	  }
+	} else if (pi->type == pg_pool_t::TYPE_REPLICATED) {
+	  for (int osd : up) {
+	    if (std::find(up2.begin(), up2.end(), osd) == up2.end()) {
+	      ++moved_pg;
+	    }
+	  }
+	} else {
+	  assert(0 == "unhandled pool type");
+	}
+      }
+    }
+  }
+
+  unsigned num_up_in = 0;
+  for (int osd = 0; osd < get_max_osd(); ++osd) {
+    if (is_up(osd) && is_in(osd))
+      ++num_up_in;
+  }
+  if (!num_up_in) {
+    return -EINVAL;
+  }
+
+  float avg_pg = (float)total_pg / (float)num_up_in;
+  float base_stddev = 0, new_stddev = 0;
+  int min = -1, max = -1;
+  unsigned min_base_pg = 0, max_base_pg = 0;
+  unsigned min_new_pg = 0, max_new_pg = 0;
+  for (int osd = 0; osd < get_max_osd(); ++osd) {
+    if (is_up(osd) && is_in(osd)) {
+      float base_diff = (float)base_by_osd[osd] - avg_pg;
+      base_stddev += base_diff * base_diff;
+      float new_diff = (float)new_by_osd[osd] - avg_pg;
+      new_stddev += new_diff * new_diff;
+      if (min < 0 || min_base_pg < base_by_osd[osd]) {
+	min = osd;
+	min_base_pg = base_by_osd[osd];
+	min_new_pg = new_by_osd[osd];
+      }
+      if (max < 0 || max_base_pg > base_by_osd[osd]) {
+	max = osd;
+	max_base_pg = base_by_osd[osd];
+	max_new_pg = new_by_osd[osd];
+      }
+    }
+  }
+  base_stddev = sqrt(base_stddev / num_up_in);
+  new_stddev = sqrt(new_stddev / num_up_in);
+
+  float edev = sqrt(avg_pg * (1.0 - (1.0 / (double)num_up_in)));
+
+  ostringstream ss;
+  if (f)
+    f->open_object_section("utilization");
+  if (newmap) {
+    if (f) {
+      f->dump_unsigned("moved_pgs", moved_pg);
+      f->dump_unsigned("total_pgs", total_pg);
+    } else {
+      ss << "moved " << moved_pg << " / " << total_pg
+	 << " (" << ((float)moved_pg * 100.0 / (float)total_pg) << "%)\n";
+    }
+  }
+  if (f) {
+    f->dump_float("avg_pgs", avg_pg);
+    f->dump_float("std_dev", base_stddev);
+    f->dump_float("expected_baseline_std_dev", edev);
+    if (newmap)
+      f->dump_float("new_std_dev", new_stddev);
+  } else {
+    ss << "avg " << avg_pg << "\n";
+    ss << "stddev " << base_stddev;
+    if (newmap)
+      ss << " -> " << new_stddev;
+    ss << " (expected baseline " << edev << ")\n";
+  }
+  if (min >= 0) {
+    if (f) {
+      f->dump_unsigned("min_osd", min);
+      f->dump_unsigned("min_osd_pgs", min_base_pg);
+      if (newmap)
+	f->dump_unsigned("new_min_osd_pgs", min_new_pg);
+    } else {
+      ss << "min osd." << min << " with " << min_base_pg;
+      if (newmap)
+	ss << " -> " << min_new_pg;
+      ss << " pgs (" << (float)min_base_pg / avg_pg;
+      if (newmap)
+	ss << " -> " << (float)min_new_pg / avg_pg;
+      ss << " * mean)\n";
+    }
+  }
+  if (max >= 0) {
+    if (f) {
+      f->dump_unsigned("max_osd", max);
+      f->dump_unsigned("max_osd_pgs", max_base_pg);
+      if (newmap)
+	f->dump_unsigned("new_max_osd_pgs", max_new_pg);
+    } else {
+      ss << "max osd." << max << " with " << max_base_pg;
+      if (newmap)
+	ss << " -> " << max_new_pg;
+      ss << " pgs (" << (float)max_base_pg / avg_pg;
+      if (newmap)
+	ss << " -> " << (float)max_new_pg / avg_pg;
+      ss << " * mean)\n";
+    }
+  }
+  if (f)
+    f->close_section();
+  if (out)
+    *out = ss.str();
+  return 0;
+}
diff --git a/src/osd/OSDMap.h b/src/osd/OSDMap.h
index cb8bbf8..affd4c3 100644
--- a/src/osd/OSDMap.h
+++ b/src/osd/OSDMap.h
@@ -270,15 +270,15 @@ private:
 	     flags(0),
 	     num_osd(0), num_up_osd(0), num_in_osd(0),
 	     max_osd(0),
-	     osd_addrs(new addrs_s),
-	     pg_temp(new map<pg_t,vector<int32_t> >),
-	     primary_temp(new map<pg_t,int32_t>),
-	     osd_uuid(new vector<uuid_d>),
+	     osd_addrs(std::make_shared<addrs_s>()),
+	     pg_temp(std::make_shared<map<pg_t,vector<int32_t>>>()),
+	     primary_temp(std::make_shared<map<pg_t,int32_t>>()),
+	     osd_uuid(std::make_shared<vector<uuid_d>>()),
 	     cluster_snapshot_epoch(0),
 	     new_blacklist_entries(false),
 	     cached_up_osd_features(0),
 	     crc_defined(false), crc(0),
-	     crush(new CrushWrapper) {
+	     crush(std::make_shared<CrushWrapper>()) {
     memset(&fsid, 0, sizeof(fsid));
   }
 
@@ -296,6 +296,9 @@ public:
     pg_temp.reset(new map<pg_t,vector<int32_t> >(*o.pg_temp));
     osd_uuid.reset(new vector<uuid_d>(*o.osd_uuid));
 
+    if (o.osd_primary_affinity)
+      osd_primary_affinity.reset(new vector<__u32>(*o.osd_primary_affinity));
+
     // NOTE: this still references shared entity_addr_t's.
     osd_addrs.reset(new addrs_s(*o.osd_addrs));
 
@@ -463,7 +466,7 @@ public:
   bool have_addr(const entity_addr_t& addr) const {
     return identify_osd(addr) >= 0;
   }
-  bool find_osd_on_ip(const entity_addr_t& ip) const;
+  int find_osd_on_ip(const entity_addr_t& ip) const;
   bool have_inst(int osd) const {
     return exists(osd) && is_up(osd); 
   }
@@ -605,17 +608,17 @@ public:
     return pg;
   }
 
-  static object_locator_t file_to_object_locator(const ceph_file_layout& layout) {
-    return object_locator_t(layout.fl_pg_pool);
+  static object_locator_t file_to_object_locator(const file_layout_t& layout) {
+    return object_locator_t(layout.pool_id, layout.pool_ns);
   }
 
-  // XXX: not used, mentioned in psim.cc comment
-  // oid -> pg
-  ceph_object_layout file_to_object_layout(object_t oid, ceph_file_layout& layout, string nspace) const {
-    return make_object_layout(oid, layout.fl_pg_pool, nspace);
+  ceph_object_layout file_to_object_layout(object_t oid,
+					   file_layout_t& layout) const {
+    return make_object_layout(oid, layout.pool_id, layout.pool_ns);
   }
 
-  ceph_object_layout make_object_layout(object_t oid, int pg_pool, string nspace) const;
+  ceph_object_layout make_object_layout(object_t oid, int pg_pool,
+					string nspace) const;
 
   int get_pg_num(int pg_pool) const
   {
@@ -864,6 +867,12 @@ public:
   void print_oneline_summary(ostream& out) const;
   void print_tree(Formatter *f, ostream *out) const;
 
+  int summarize_mapping_stats(
+    OSDMap *newmap,
+    const set<int64_t> *pools,
+    std::string *out,
+    Formatter *f) const;
+
   string get_flag_string() const;
   static string get_flag_string(unsigned flags);
   static void dump_erasure_code_profiles(const map<string,map<string,string> > &profiles,
diff --git a/src/osd/PG.cc b/src/osd/PG.cc
index c2d5b0b..15dc0af 100644
--- a/src/osd/PG.cc
+++ b/src/osd/PG.cc
@@ -17,6 +17,7 @@
 #include "common/config.h"
 #include "OSD.h"
 #include "OpRequest.h"
+#include "ScrubStore.h"
 
 #include "common/Timer.h"
 
@@ -37,6 +38,8 @@
 #include "messages/MOSDECSubOpWriteReply.h"
 #include "messages/MOSDECSubOpRead.h"
 #include "messages/MOSDECSubOpReadReply.h"
+#include "messages/MOSDPGUpdateLogMissing.h"
+#include "messages/MOSDPGUpdateLogMissingReply.h"
 
 #include "messages/MOSDSubOp.h"
 #include "messages/MOSDRepOp.h"
@@ -655,8 +658,6 @@ bool PG::needs_backfill() const
 {
   assert(is_primary());
 
-  bool ret = false;
-
   // We can assume that only possible osds that need backfill
   // are on the backfill_targets vector nodes.
   set<pg_shard_t>::const_iterator end = backfill_targets.end();
@@ -666,13 +667,12 @@ bool PG::needs_backfill() const
     map<pg_shard_t, pg_info_t>::const_iterator pi = peer_info.find(peer);
     if (!pi->second.last_backfill.is_max()) {
       dout(10) << __func__ << " osd." << peer << " has last_backfill " << pi->second.last_backfill << dendl;
-      ret = true;
+      return true;
     }
   }
 
-  if (!ret)
-    dout(10) << __func__ << " does not need backfill" << dendl;
-  return ret;
+  dout(10) << __func__ << " does not need backfill" << dendl;
+  return false;
 }
 
 bool PG::_calc_past_interval_range(epoch_t *start, epoch_t *end, epoch_t oldest_map)
@@ -922,7 +922,6 @@ void PG::clear_primary_state()
   peer_activated.clear();
   min_last_complete_ondisk = eversion_t();
   pg_trim_to = eversion_t();
-  stray_purged.clear();
   might_have_unfound.clear();
 
   last_update_ondisk = eversion_t();
@@ -943,6 +942,21 @@ void PG::clear_primary_state()
   agent_clear();
 }
 
+PG::Scrubber::Scrubber()
+ : reserved(false), reserve_failed(false),
+   epoch_start(0),
+   active(false), queue_snap_trim(false),
+   waiting_on(0), shallow_errors(0), deep_errors(0), fixed(0),
+   must_scrub(false), must_deep_scrub(false), must_repair(false),
+   auto_repair(false),
+   num_digest_updates_pending(0),
+   state(INACTIVE),
+   deep(false),
+   seed(0)
+{}
+
+PG::Scrubber::~Scrubber() {}
+
 /**
  * find_best_info
  *
@@ -1388,7 +1402,6 @@ bool PG::choose_acting(pg_shard_t &auth_log_shard_id)
   // Otherwise, we will go "peered", but not "active"
   if (num_want_acting < pool.info.min_size &&
       (pool.info.ec_pool() ||
-       (!(get_min_peer_features() & CEPH_FEATURE_OSD_MIN_SIZE_RECOVERY)) ||
        !cct->_conf->osd_allow_recovery_below_min_size)) {
     want_acting.clear();
     dout(10) << "choose_acting failed, below min size" << dendl;
@@ -2015,7 +2028,7 @@ void PG::all_activated_and_committed()
 
   queue_peering_event(
     CephPeeringEvtRef(
-      new CephPeeringEvt(
+      std::make_shared<CephPeeringEvt>(
         get_osdmap()->get_epoch(),
         get_osdmap()->get_epoch(),
         AllReplicasActivated())));
@@ -2268,7 +2281,18 @@ void PG::split_into(pg_t child_pgid, PG *child, unsigned split_bits)
   // Info
   child->info.history = info.history;
   child->info.purged_snaps = info.purged_snaps;
-  child->info.set_last_backfill(info.last_backfill, info.last_backfill_bitwise);
+
+  if (info.last_backfill.is_max()) {
+    child->info.set_last_backfill(hobject_t::get_max(),
+				  info.last_backfill_bitwise);
+  } else {
+    // restart backfill on parent and child to be safe.  we could
+    // probably do better in the bitwise sort case, but it's more
+    // fragile (there may be special work to do on backfill completion
+    // in the future).
+    info.set_last_backfill(hobject_t(), info.last_backfill_bitwise);
+    child->info.set_last_backfill(hobject_t(), info.last_backfill_bitwise);
+  }
 
   child->info.stats = info.stats;
   info.stats.stats_invalid = true;
@@ -2353,7 +2377,6 @@ void PG::purge_strays()
 	get_osdmap()->get_epoch(),
 	to_remove);
       osd->send_message_osd_cluster(p->osd, m, get_osdmap()->get_epoch());
-      stray_purged.insert(*p);
     } else {
       dout(10) << "not sending PGRemove to down osd." << *p << dendl;
     }
@@ -2396,21 +2419,22 @@ void PG::update_heartbeat_peers()
 {
   assert(is_locked());
 
+  if (!is_primary())
+    return;
+
   set<int> new_peers;
-  if (is_primary()) {
-    for (unsigned i=0; i<acting.size(); i++) {
-      if (acting[i] != CRUSH_ITEM_NONE)
-	new_peers.insert(acting[i]);
-    }
-    for (unsigned i=0; i<up.size(); i++) {
-      if (up[i] != CRUSH_ITEM_NONE)
-	new_peers.insert(up[i]);
-    }
-    for (map<pg_shard_t,pg_info_t>::iterator p = peer_info.begin();
-	 p != peer_info.end();
-	 ++p)
-      new_peers.insert(p->first.osd);
+  for (unsigned i=0; i<acting.size(); i++) {
+    if (acting[i] != CRUSH_ITEM_NONE)
+      new_peers.insert(acting[i]);
   }
+  for (unsigned i=0; i<up.size(); i++) {
+    if (up[i] != CRUSH_ITEM_NONE)
+      new_peers.insert(up[i]);
+  }
+  for (map<pg_shard_t,pg_info_t>::iterator p = peer_info.begin();
+    p != peer_info.end();
+    ++p)
+    new_peers.insert(p->first.osd);
 
   bool need_update = false;
   heartbeat_peer_lock.Lock();
@@ -2718,8 +2742,8 @@ void PG::upgrade(ObjectStore *store)
   dirty_big_info = true;
   write_if_dirty(t);
 
-  ceph::shared_ptr<ObjectStore::Sequencer> osr(
-    new ObjectStore::Sequencer("upgrade"));
+  ceph::shared_ptr<ObjectStore::Sequencer> osr (std::make_shared<
+                                      ObjectStore::Sequencer>("upgrade"));
   int r = store->apply_transaction(osr.get(), std::move(t));
   if (r != 0) {
     derr << __func__ << ": apply_transaction returned "
@@ -3752,6 +3776,21 @@ int PG::build_scrub_map_chunk(
   return 0;
 }
 
+void PG::Scrubber::cleanup_store(ObjectStore::Transaction *t) {
+  if (!store)
+    return;
+  struct OnComplete : Context {
+    std::unique_ptr<Scrub::Store> store;
+    OnComplete(
+      std::unique_ptr<Scrub::Store> &&store)
+      : store(std::move(store)) {}
+    void finish(int) override {}
+  };
+  store->cleanup(t);
+  t->register_on_complete(new OnComplete(std::move(store)));
+  assert(!store);
+}
+
 void PG::repair_object(
   const hobject_t& soid, list<pair<ScrubMap::object, pg_shard_t> > *ok_peers,
   pg_shard_t bad_peer)
@@ -4010,6 +4049,14 @@ void PG::chunky_scrub(ThreadPool::TPHandle &handle)
 	  scrubber.reserved_peers.clear();
 	}
 
+	{
+	  ObjectStore::Transaction t;
+	  scrubber.cleanup_store(&t);
+	  scrubber.store.reset(Scrub::Store::create(osd->store, &t,
+						    info.pgid, coll));
+	  osd->store->queue_transaction(osr.get(), std::move(t), nullptr);
+	}
+
         // Don't include temporary objects when scrubbing
         scrubber.start = info.pgid.pgid.get_hobj_start();
         scrubber.state = PG::Scrubber::NEW_CHUNK;
@@ -4023,10 +4070,7 @@ void PG::chunky_scrub(ThreadPool::TPHandle &handle)
 	  osd->clog->info(oss);
 	}
 
-	if (get_min_acting_features() & CEPH_FEATURE_OSD_OBJECT_DIGEST)
-	  scrubber.seed = -1; // better, and enables oi digest checks
-	else
-	  scrubber.seed = 0;  // compat
+	scrubber.seed = -1;
 
         break;
 
@@ -4273,13 +4317,8 @@ void PG::scrub_compare_maps()
       maps[*i] = &scrubber.received_maps[*i];
     }
 
-    // can we relate scrub digests to oi digests?
-    bool okseed = (get_min_upacting_features() & CEPH_FEATURE_OSD_OBJECT_DIGEST);
-    assert(okseed == (scrubber.seed == 0xffffffff));
-
     get_pgbackend()->be_compare_scrubmaps(
       maps,
-      okseed,
       state_test(PG_STATE_REPAIR),
       scrubber.missing,
       scrubber.inconsistent,
@@ -4287,6 +4326,7 @@ void PG::scrub_compare_maps()
       missing_digest,
       scrubber.shallow_errors,
       scrubber.deep_errors,
+      scrubber.store.get(),
       info.pgid, acting,
       ss);
     dout(2) << ss.str() << dendl;
@@ -4320,6 +4360,17 @@ void PG::scrub_compare_maps()
 
   // ok, do the pg-type specific scrubbing
   _scrub(authmap, missing_digest);
+  if (!scrubber.store->empty()) {
+    if (state_test(PG_STATE_REPAIR)) {
+      dout(10) << __func__ << ": discarding scrub results" << dendl;
+      scrubber.store->flush(nullptr);
+    } else {
+      dout(10) << __func__ << ": updating scrub object" << dendl;
+      ObjectStore::Transaction t;
+      scrubber.store->flush(&t);
+      osd->store->queue_transaction(osr.get(), std::move(t), nullptr);
+    }
+  }
 }
 
 bool PG::scrub_process_inconsistent()
@@ -4460,7 +4511,7 @@ void PG::scrub_finish()
   if (has_error) {
     queue_peering_event(
       CephPeeringEvtRef(
-	new CephPeeringEvt(
+	std::make_shared<CephPeeringEvt>(
 	  get_osdmap()->get_epoch(),
 	  get_osdmap()->get_epoch(),
 	  DoRecovery())));
@@ -4502,39 +4553,71 @@ void PG::share_pg_info()
   }
 }
 
-/*
- * Share a new segment of this PG's log with some replicas, after PG is active.
- *
- * Updates peer_missing and peer_info.
- */
-void PG::share_pg_log()
+void PG::append_log_entries_update_missing(
+  const list<pg_log_entry_t> &entries,
+  ObjectStore::Transaction &t)
 {
-  dout(10) << __func__ << dendl;
+  assert(!entries.empty());
+  assert(entries.begin()->version > info.last_update);
+
+  PGLogEntryHandler rollbacker;
+  pg_log.append_new_log_entries(
+    info.last_backfill,
+    info.last_backfill_bitwise,
+    entries,
+    &rollbacker);
+  rollbacker.apply(this, &t);
+  info.last_update = pg_log.get_head();
+
+  if (pg_log.get_missing().num_missing() == 0) {
+    // advance last_complete since nothing else is missing!
+    info.last_complete = info.last_update;
+  }
+
+  info.stats.stats_invalid = true;
+  dirty_info = true;
+  write_if_dirty(t);
+}
+
+
+void PG::merge_new_log_entries(
+  const list<pg_log_entry_t> &entries,
+  ObjectStore::Transaction &t)
+{
+  dout(10) << __func__ << " " << entries << dendl;
   assert(is_primary());
 
-  set<pg_shard_t>::const_iterator a = actingbackfill.begin();
-  assert(a != actingbackfill.end());
-  set<pg_shard_t>::const_iterator end = actingbackfill.end();
-  while (a != end) {
-    pg_shard_t peer(*a);
-    ++a;
+  append_log_entries_update_missing(entries, t);
+  for (set<pg_shard_t>::const_iterator i = actingbackfill.begin();
+       i != actingbackfill.end();
+       ++i) {
+    pg_shard_t peer(*i);
     if (peer == pg_whoami) continue;
+    assert(peer_missing.count(peer));
+    assert(peer_info.count(peer));
     pg_missing_t& pmissing(peer_missing[peer]);
     pg_info_t& pinfo(peer_info[peer]);
-
-    MOSDPGLog *m = new MOSDPGLog(
-      peer.shard, pg_whoami.shard,
-      info.last_update.epoch, info);
-    m->log.copy_after(pg_log.get_log(), pinfo.last_update);
-
-    for (list<pg_log_entry_t>::const_iterator i = m->log.log.begin();
-	 i != m->log.log.end();
-	 ++i) {
-      pmissing.add_next_event(*i);
-    }
-    pinfo.last_update = m->log.head;
-
-    osd->send_message_osd_cluster(peer.osd, m, get_osdmap()->get_epoch());
+    PGLog::append_log_entries_update_missing(
+      pinfo.last_backfill,
+      info.last_backfill_bitwise,
+      entries,
+      NULL,
+      pmissing,
+      NULL,
+      this);
+    pinfo.last_update = info.last_update;
+    pinfo.stats.stats_invalid = true;
+  }
+  for (auto &&i: entries) {
+    missing_loc.rebuild(
+      i.soid,
+      get_sort_bitwise(),
+      pg_whoami,
+      actingbackfill,
+      info,
+      pg_log.get_missing(),
+      peer_missing,
+      peer_info);
   }
 }
 
@@ -4769,8 +4852,8 @@ void PG::start_flush(ObjectStore::Transaction *t,
 		     list<Context *> *on_safe)
 {
   // flush in progress ops
-  FlushStateRef flush_trigger(
-    new FlushState(this, get_osdmap()->get_epoch()));
+  FlushStateRef flush_trigger (std::make_shared<FlushState>(
+                               this, get_osdmap()->get_epoch()));
   t->nop();
   flushes_in_progress++;
   on_applied->push_back(new ContainerContext<FlushStateRef>(flush_trigger));
@@ -5262,6 +5345,12 @@ bool PG::can_discard_request(OpRequestRef& op)
     return can_discard_replica_op<MOSDECSubOpReadReply, MSG_OSD_EC_READ_REPLY>(op);
   case MSG_OSD_REP_SCRUB:
     return can_discard_replica_op<MOSDRepScrub, MSG_OSD_REP_SCRUB>(op);
+  case MSG_OSD_PG_UPDATE_LOG_MISSING:
+    return can_discard_replica_op<
+      MOSDPGUpdateLogMissing, MSG_OSD_PG_UPDATE_LOG_MISSING>(op);
+  case MSG_OSD_PG_UPDATE_LOG_MISSING_REPLY:
+    return can_discard_replica_op<
+      MOSDPGUpdateLogMissingReply, MSG_OSD_PG_UPDATE_LOG_MISSING_REPLY>(op);
 
   case MSG_OSD_PG_SCAN:
     return can_discard_scan(op);
@@ -5348,6 +5437,16 @@ bool PG::op_must_wait_for_map(epoch_t cur_epoch, OpRequestRef& op)
     return !have_same_or_newer_map(
       cur_epoch,
       static_cast<MOSDRepScrub*>(op->get_req())->map_epoch);
+
+  case MSG_OSD_PG_UPDATE_LOG_MISSING:
+    return !have_same_or_newer_map(
+      cur_epoch,
+      static_cast<MOSDPGUpdateLogMissing*>(op->get_req())->map_epoch);
+
+  case MSG_OSD_PG_UPDATE_LOG_MISSING_REPLY:
+    return !have_same_or_newer_map(
+      cur_epoch,
+      static_cast<MOSDPGUpdateLogMissingReply*>(op->get_req())->map_epoch);
   }
   assert(0);
   return false;
@@ -5390,7 +5489,7 @@ void PG::queue_null(epoch_t msg_epoch,
 {
   dout(10) << "null" << dendl;
   queue_peering_event(
-    CephPeeringEvtRef(new CephPeeringEvt(msg_epoch, query_epoch,
+    CephPeeringEvtRef(std::make_shared<CephPeeringEvt>(msg_epoch, query_epoch,
 					 NullEvt())));
 }
 
@@ -5398,7 +5497,7 @@ void PG::queue_flushed(epoch_t e)
 {
   dout(10) << "flushed" << dendl;
   queue_peering_event(
-    CephPeeringEvtRef(new CephPeeringEvt(e, e,
+    CephPeeringEvtRef(std::make_shared<CephPeeringEvt>(e, e,
 					 FlushedEvt())));
 }
 
@@ -5408,7 +5507,7 @@ void PG::queue_query(epoch_t msg_epoch,
 {
   dout(10) << "handle_query " << q << " from replica " << from << dendl;
   queue_peering_event(
-    CephPeeringEvtRef(new CephPeeringEvt(msg_epoch, query_epoch,
+    CephPeeringEvtRef(std::make_shared<CephPeeringEvt>(msg_epoch, query_epoch,
 					 MQuery(from, q, query_epoch))));
 }
 
@@ -6570,7 +6669,6 @@ boost::statechart::result PG::RecoveryState::Active::react(const ActMap&)
     if (pg->cct->_conf->osd_auto_mark_unfound_lost) {
       pg->osd->clog->error() << pg->info.pgid.pgid << " has " << unfound
 			    << " objects unfound and apparently lost, would automatically marking lost but NOT IMPLEMENTED\n";
-      //pg->mark_all_unfound_lost(*context< RecoveryMachine >().get_cur_transaction());
     } else
       pg->osd->clog->error() << pg->info.pgid.pgid << " has " << unfound << " objects unfound and apparently lost\n";
   }
@@ -6884,12 +6982,6 @@ boost::statechart::result PG::RecoveryState::Stray::react(const MLogRec& logevt)
 
   ObjectStore::Transaction* t = context<RecoveryMachine>().get_cur_transaction();
   if (msg->info.last_backfill == hobject_t()) {
-    if (!(msg->get_connection()->get_features() & CEPH_FEATURE_OSD_MIN_SIZE_RECOVERY)) {
-      dout(10) << "Got logevt resetting backfill from peer featuring bug"
-	       << " 10780, setting msg->info.last_epoch_started to logevt.query_epoch,"
-	       << " which is the activation epoch." << dendl;
-      msg->info.last_epoch_started = msg->get_query_epoch();
-    }
     // restart backfill
     pg->unreg_next_scrub();
     pg->info = msg->info;
diff --git a/src/osd/PG.h b/src/osd/PG.h
index ff306cc..1df129f 100644
--- a/src/osd/PG.h
+++ b/src/osd/PG.h
@@ -72,6 +72,10 @@ class MOSDPGInfo;
 
 class PG;
 
+namespace Scrub {
+  class Store;
+}
+
 void intrusive_ptr_add_ref(PG *pg);
 void intrusive_ptr_release(PG *pg);
 
@@ -181,11 +185,7 @@ struct PGPool {
  *
  */
 
-class PG {
-public:
-  std::string gen_prefix() const;
-
-  /*** PG ****/
+class PG : DoutPrefixProvider {
 protected:
   OSDService *osd;
   CephContext *cct;
@@ -194,6 +194,11 @@ protected:
 
   virtual PGBackend *get_pgbackend() = 0;
 public:
+  std::string gen_prefix() const;
+  CephContext *get_cct() const { return cct; }
+  unsigned get_subsys() const { return ceph_subsys_osd; }
+
+  /*** PG ****/
   void update_snap_mapper_bits(uint32_t bits) {
     snap_mapper.update_bits(bits);
   }
@@ -262,9 +267,6 @@ public:
     _lock.Unlock();
   }
 
-  void assert_locked() {
-    assert(_lock.is_locked());
-  }
   bool is_locked() const {
     return _lock.is_locked();
   }
@@ -419,6 +421,55 @@ public:
       missing_loc.erase(hoid);
     }
 
+    /// Call to update structures for hoid after a change
+    void rebuild(
+      const hobject_t &hoid,
+      bool sort_bitwise,
+      pg_shard_t self,
+      const set<pg_shard_t> to_recover,
+      const pg_info_t &info,
+      const pg_missing_t &missing,
+      const map<pg_shard_t, pg_missing_t> &pmissing,
+      const map<pg_shard_t, pg_info_t> &pinfo) {
+      recovered(hoid);
+      boost::optional<pg_missing_t::item> item;
+      set<pg_shard_t> have;
+      auto miter = missing.missing.find(hoid);
+      if (miter != missing.missing.end()) {
+	item = miter->second;
+      } else {
+	for (auto &&i: to_recover) {
+	  if (i == self)
+	    continue;
+	  auto pmiter = pmissing.find(i);
+	  assert(pmiter != pmissing.end());
+	  miter = pmiter->second.missing.find(hoid);
+	  if (miter != pmiter->second.missing.end()) {
+	    item = miter->second;
+	    break;
+	  }
+	}
+      }
+      if (!item)
+	return; // recovered!
+
+      needs_recovery_map[hoid] = *item;
+      auto mliter =
+	missing_loc.insert(make_pair(hoid, set<pg_shard_t>())).first;
+      assert(info.last_backfill == hobject_t::get_max());
+      assert(info.last_update >= item->need);
+      if (!missing.is_missing(hoid))
+	mliter->second.insert(self);
+      for (auto &&i: pmissing) {
+	auto pinfoiter = pinfo.find(i.first);
+	assert(pinfoiter != pinfo.end());
+	if (item->need <= pinfoiter->second.last_update &&
+	    cmp(hoid, pinfoiter->second.last_backfill, sort_bitwise) <= 0 &&
+	    !i.second.is_missing(hoid))
+	  mliter->second.insert(i.first);
+      }
+    }
+
     const set<pg_shard_t> &get_locations(const hobject_t &hoid) const {
       return missing_loc.count(hoid) ?
 	missing_loc.find(hoid)->second : empty_set;
@@ -625,7 +676,6 @@ protected:
   set<pg_shard_t> peer_missing_requested;
 
   // i deleted these strays; ignore racing PGInfo from them
-  set<pg_shard_t> stray_purged;
   set<pg_shard_t> peer_activated;
 
   // primary-only, recovery-only state
@@ -850,7 +900,6 @@ public:
   bool adjust_need_up_thru(const OSDMapRef osdmap);
 
   bool all_unfound_are_queried_or_lost(const OSDMapRef osdmap) const;
-  virtual void mark_all_unfound_lost(int how) = 0;
   virtual void dump_recovery_info(Formatter *f) const = 0;
 
   bool calc_min_last_complete_ondisk() {
@@ -916,11 +965,15 @@ public:
     list<pg_log_entry_t> to_rollback;
     set<hobject_t, hobject_t::BitwiseComparator> to_remove;
     list<pg_log_entry_t> to_trim;
+    list<pair<hobject_t, version_t> > to_stash;
     
     // LogEntryHandler
     void remove(const hobject_t &hoid) {
       to_remove.insert(hoid);
     }
+    void try_stash(const hobject_t &hoid, version_t v) {
+      to_stash.push_back(make_pair(hoid, v));
+    }
     void rollback(const pg_log_entry_t &entry) {
       to_rollback.push_back(entry);
     }
@@ -937,6 +990,11 @@ public:
 	SnapRollBacker rollbacker(j->soid, pg, t);
 	j->mod_desc.visit(&rollbacker);
       }
+      for (list<pair<hobject_t, version_t> >::iterator i = to_stash.begin();
+	   i != to_stash.end();
+	   ++i) {
+	pg->get_pgbackend()->try_stash(i->first, i->second, t);
+      }
       for (set<hobject_t, hobject_t::BitwiseComparator>::iterator i = to_remove.begin();
 	   i != to_remove.end();
 	   ++i) {
@@ -1025,7 +1083,7 @@ public:
   void proc_primary_info(ObjectStore::Transaction &t, const pg_info_t &info);
 
   bool have_unfound() const { 
-    return missing_loc.num_unfound();
+    return missing_loc.num_unfound() > 0;
   }
   int get_num_unfound() const {
     return missing_loc.num_unfound();
@@ -1059,28 +1117,13 @@ public:
   void split_into(pg_t child_pgid, PG *child, unsigned split_bits);
   virtual void _split_into(pg_t child_pgid, PG *child, unsigned split_bits) = 0;
 
-  loff_t get_log_write_pos() {
-    return 0;
-  }
-
   friend class C_OSD_RepModify_Commit;
 
 
   // -- scrub --
   struct Scrubber {
-    Scrubber() :
-      reserved(false), reserve_failed(false),
-      epoch_start(0),
-      active(false), queue_snap_trim(false),
-      waiting_on(0), shallow_errors(0), deep_errors(0), fixed(0),
-      must_scrub(false), must_deep_scrub(false), must_repair(false),
-      auto_repair(false),
-      num_digest_updates_pending(0),
-      state(INACTIVE),
-      deep(false),
-      seed(0)
-    {
-    }
+    Scrubber();
+    ~Scrubber();
 
     // metadata
     set<pg_shard_t> reserved_peers;
@@ -1133,6 +1176,7 @@ public:
       FINISH,
     } state;
 
+    std::unique_ptr<Scrub::Store> store;
     // deep scrub
     bool deep;
     uint32_t seed;
@@ -1212,6 +1256,8 @@ public:
       num_digest_updates_pending = 0;
     }
 
+    void create_results(const hobject_t& obj);
+    void cleanup_store(ObjectStore::Transaction *t);
   } scrubber;
 
   bool scrub_after_recovery;
@@ -2061,7 +2107,6 @@ public:
 
  public:
   const spg_t&      get_pgid() const { return pg_id; }
-  int        get_nrep() const { return acting.size(); }
 
   void reset_min_peer_features() {
     peer_features = CEPH_FEATURES_SUPPORTED_DEFAULT;
@@ -2221,8 +2266,19 @@ public:
 
   /// share pg info after a pg is active
   void share_pg_info();
-  /// share new pg log entries after a pg is active
-  void share_pg_log();
+
+
+  void append_log_entries_update_missing(
+    const list<pg_log_entry_t> &entries,
+    ObjectStore::Transaction &t);
+
+  /**
+   * Merge entries updating missing as necessary on all
+   * actingbackfill logs and missings (also missing_loc)
+   */
+  void merge_new_log_entries(
+    const list<pg_log_entry_t> &entries,
+    ObjectStore::Transaction &t);
 
   void reset_interval_flush();
   void start_peering_interval(
@@ -2318,8 +2374,13 @@ public:
   virtual void do_backfill(OpRequestRef op) = 0;
   virtual void snap_trimmer(epoch_t epoch_queued) = 0;
 
-  virtual int do_command(cmdmap_t cmdmap, ostream& ss,
-			 bufferlist& idata, bufferlist& odata) = 0;
+  virtual int do_command(
+    cmdmap_t cmdmap,
+    ostream& ss,
+    bufferlist& idata,
+    bufferlist& odata,
+    ConnectionRef conn,
+    ceph_tid_t tid) = 0;
 
   virtual void on_role_change() = 0;
   virtual void on_pool_change() = 0;
diff --git a/src/osd/PGBackend.cc b/src/osd/PGBackend.cc
index 85bd78b..7351e55 100644
--- a/src/osd/PGBackend.cc
+++ b/src/osd/PGBackend.cc
@@ -17,7 +17,9 @@
 
 
 #include "common/errno.h"
+#include "common/scrub_types.h"
 #include "ReplicatedBackend.h"
+#include "ScrubStore.h"
 #include "ECBackend.h"
 #include "PGBackend.h"
 #include "OSD.h"
@@ -57,6 +59,12 @@ struct RollbackVisitor : public ObjectModDesc::Visitor {
     temp.append(t);
     temp.swap(t);
   }
+  void try_rmobject(version_t old_version) {
+    ObjectStore::Transaction temp;
+    pg->rollback_try_stash(hoid, old_version, &temp);
+    temp.append(t);
+    temp.swap(t);
+  }
   void create() {
     ObjectStore::Transaction temp;
     pg->rollback_create(hoid, &temp);
@@ -80,6 +88,17 @@ void PGBackend::rollback(
 }
 
 
+void PGBackend::try_stash(
+  const hobject_t &hoid,
+  version_t v,
+  ObjectStore::Transaction *t)
+{
+  t->try_rename(
+    coll,
+    ghobject_t(hoid, ghobject_t::NO_GEN, get_parent()->whoami_shard().shard),
+    ghobject_t(hoid, v, get_parent()->whoami_shard().shard));
+}
+
 void PGBackend::on_change_cleanup(ObjectStore::Transaction *t)
 {
   dout(10) << __func__ << dendl;
@@ -251,6 +270,20 @@ void PGBackend::rollback_stash(
     ghobject_t(hoid, ghobject_t::NO_GEN, get_parent()->whoami_shard().shard));
 }
 
+void PGBackend::rollback_try_stash(
+  const hobject_t &hoid,
+  version_t old_version,
+  ObjectStore::Transaction *t) {
+  assert(!hoid.is_temp());
+  t->remove(
+    coll,
+    ghobject_t(hoid, ghobject_t::NO_GEN, get_parent()->whoami_shard().shard));
+  t->try_rename(
+    coll,
+    ghobject_t(hoid, old_version, get_parent()->whoami_shard().shard),
+    ghobject_t(hoid, ghobject_t::NO_GEN, get_parent()->whoami_shard().shard));
+}
+
 void PGBackend::rollback_create(
   const hobject_t &hoid,
   ObjectStore::Transaction *t) {
@@ -367,8 +400,8 @@ enum scrub_error_type PGBackend::be_compare_scrub_objects(
   pg_shard_t auth_shard,
   const ScrubMap::object &auth,
   const object_info_t& auth_oi,
-  bool okseed,
   const ScrubMap::object &candidate,
+  shard_info_wrapper &result,
   ostream &errorstream)
 {
   enum scrub_error_type error = CLEAN;
@@ -385,13 +418,14 @@ enum scrub_error_type PGBackend::be_compare_scrub_objects(
       if (error != CLEAN)
         errorstream << ", ";
       error = DEEP_ERROR;
-      bool known = okseed && auth_oi.is_data_digest() &&
+      bool known = auth_oi.is_data_digest() &&
 	auth.digest == auth_oi.data_digest;
       errorstream << "data_digest 0x" << std::hex << candidate.digest
 		  << " != "
 		  << (known ? "known" : "best guess")
 		  << " data_digest 0x" << auth.digest << std::dec
 		  << " from auth shard " << auth_shard;
+      result.set_data_digest_mismatch();
     }
   }
   if (auth.omap_digest_present && candidate.omap_digest_present) {
@@ -399,13 +433,14 @@ enum scrub_error_type PGBackend::be_compare_scrub_objects(
       if (error != CLEAN)
         errorstream << ", ";
       error = DEEP_ERROR;
-      bool known = okseed && auth_oi.is_omap_digest() &&
+      bool known = auth_oi.is_omap_digest() &&
 	auth.omap_digest == auth_oi.omap_digest;
       errorstream << "omap_digest 0x" << std::hex << candidate.omap_digest
 		  << " != "
 		  << (known ? "known" : "best guess")
 		  << " omap_digest 0x" << auth.omap_digest << std::dec
 		  << " from auth shard " << auth_shard;
+      result.set_omap_digest_mismatch();
     }
   }
   if (!candidate.stat_error && auth.size != candidate.size) {
@@ -418,6 +453,7 @@ enum scrub_error_type PGBackend::be_compare_scrub_objects(
 		<< " != "
                 << (known ? "known" : "best guess")
                 << " size " << auth.size;
+    result.set_size_mismatch();
   }
   for (map<string,bufferptr>::const_iterator i = auth.attrs.begin();
        i != auth.attrs.end();
@@ -428,12 +464,14 @@ enum scrub_error_type PGBackend::be_compare_scrub_objects(
       if (error != DEEP_ERROR)
 	error = SHALLOW_ERROR;
       errorstream << "missing attr " << i->first;
+      result.set_attr_missing();
     } else if (candidate.attrs.find(i->first)->second.cmp(i->second)) {
       if (error != CLEAN)
         errorstream << ", ";
       if (error != DEEP_ERROR)
 	error = SHALLOW_ERROR;
       errorstream << "attr value mismatch " << i->first;
+      result.set_attr_mismatch();
     }
   }
   for (map<string,bufferptr>::const_iterator i = candidate.attrs.begin();
@@ -445,6 +483,7 @@ enum scrub_error_type PGBackend::be_compare_scrub_objects(
       if (error != DEEP_ERROR)
 	error = SHALLOW_ERROR;
       errorstream << "extra attr " << i->first;
+      result.set_attr_unexpected();
     }
   }
   return error;
@@ -454,7 +493,6 @@ map<pg_shard_t, ScrubMap *>::const_iterator
   PGBackend::be_select_auth_object(
   const hobject_t &obj,
   const map<pg_shard_t,ScrubMap*> &maps,
-  bool okseed,
   object_info_t *auth_oi)
 {
   map<pg_shard_t, ScrubMap *>::const_iterator auth = maps.end();
@@ -516,7 +554,7 @@ map<pg_shard_t, ScrubMap *>::const_iterator
       continue;
     }
     if (parent->get_pool().is_replicated()) {
-      if (okseed && oi.is_data_digest() && i->second.digest_present &&
+      if (oi.is_data_digest() && i->second.digest_present &&
 	  oi.data_digest != i->second.digest) {
 	dout(10) << __func__ << ": rejecting osd " << j->first
 		 << " for obj " << obj
@@ -525,7 +563,7 @@ map<pg_shard_t, ScrubMap *>::const_iterator
 		 << std::dec << dendl;
 	continue;
       }
-      if (okseed && oi.is_omap_digest() && i->second.omap_digest_present &&
+      if (oi.is_omap_digest() && i->second.omap_digest_present &&
 	  oi.omap_digest != i->second.omap_digest) {
 	dout(10) << __func__ << ": rejecting osd " << j->first
 		 << " for obj " << obj
@@ -546,13 +584,13 @@ map<pg_shard_t, ScrubMap *>::const_iterator
 
 void PGBackend::be_compare_scrubmaps(
   const map<pg_shard_t,ScrubMap*> &maps,
-  bool okseed,
   bool repair,
   map<hobject_t, set<pg_shard_t>, hobject_t::BitwiseComparator> &missing,
   map<hobject_t, set<pg_shard_t>, hobject_t::BitwiseComparator> &inconsistent,
   map<hobject_t, list<pg_shard_t>, hobject_t::BitwiseComparator> &authoritative,
   map<hobject_t, pair<uint32_t,uint32_t>, hobject_t::BitwiseComparator> &missing_digest,
   int &shallow_errors, int &deep_errors,
+  Scrub::Store *store,
   const spg_t& pgid,
   const vector<int> &acting,
   ostream &errorstream)
@@ -575,9 +613,12 @@ void PGBackend::be_compare_scrubmaps(
        ++k) {
     object_info_t auth_oi;
     map<pg_shard_t, ScrubMap *>::const_iterator auth =
-      be_select_auth_object(*k, maps, okseed, &auth_oi);
+      be_select_auth_object(*k, maps, &auth_oi);
+    inconsistent_obj_wrapper object_error{*k};
+
     list<pg_shard_t> auth_list;
     if (auth == maps.end()) {
+      object_error.set_auth_missing(*k, maps);
       ++shallow_errors;
       errorstream << pgid.pgid << " soid " << *k
 		  << ": failed to pick suitable auth object\n";
@@ -592,15 +633,17 @@ void PGBackend::be_compare_scrubmaps(
     for (j = maps.begin(); j != maps.end(); ++j) {
       if (j == auth)
 	continue;
+      shard_info_wrapper shard_info;
       if (j->second->objects.count(*k)) {
+	shard_info.set_object(j->second->objects[*k]);
 	// Compare
 	stringstream ss;
 	enum scrub_error_type error =
 	  be_compare_scrub_objects(auth->first,
 				   auth_object,
 				   auth_oi,
-				   okseed,
 				   j->second->objects[*k],
+				   shard_info,
 				   ss);
         if (error != CLEAN) {
 	  clean = false;
@@ -620,7 +663,9 @@ void PGBackend::be_compare_scrubmaps(
 	++shallow_errors;
 	errorstream << pgid << " shard " << j->first << " missing " << *k
 		    << "\n";
+	shard_info.set_missing();
       }
+      object_error.add_shard(j->first, shard_info);
     }
     if (!cur_missing.empty()) {
       missing[*k] = cur_missing;
@@ -630,10 +675,11 @@ void PGBackend::be_compare_scrubmaps(
     }
     if (!cur_inconsistent.empty() || !cur_missing.empty()) {
       authoritative[*k] = auth_list;
+      shard_info_wrapper auth_shard{auth_object};
+      object_error.add_shard(auth->first, auth_shard);
     }
 
-    if (okseed &&
-	clean &&
+    if (clean &&
 	parent->get_pool().is_replicated()) {
       enum {
 	NO = 0,
@@ -641,9 +687,24 @@ void PGBackend::be_compare_scrubmaps(
 	FORCE = 2,
       } update = NO;
 
+      if (auth_object.digest_present && auth_object.omap_digest_present &&
+	  (!auth_oi.is_data_digest() || !auth_oi.is_omap_digest())) {
+	dout(20) << __func__ << " missing digest on " << *k << dendl;
+	update = MAYBE;
+      }
+      if (auth_object.digest_present && auth_object.omap_digest_present &&
+	  g_conf->osd_debug_scrub_chance_rewrite_digest &&
+	  (((unsigned)rand() % 100) >
+	   g_conf->osd_debug_scrub_chance_rewrite_digest)) {
+	dout(20) << __func__ << " randomly updating digest on " << *k << dendl;
+	update = MAYBE;
+      }
+
+      shard_info_wrapper auth_shard{auth_object};
       // recorded digest != actual digest?
       if (auth_oi.is_data_digest() && auth_object.digest_present &&
 	  auth_oi.data_digest != auth_object.digest) {
+	auth_shard.set_data_digest_mismatch_oi();
 	++deep_errors;
 	errorstream << pgid << " recorded data digest 0x"
 		    << std::hex << auth_oi.data_digest << " != on disk 0x"
@@ -654,6 +715,7 @@ void PGBackend::be_compare_scrubmaps(
       }
       if (auth_oi.is_omap_digest() && auth_object.omap_digest_present &&
 	  auth_oi.omap_digest != auth_object.omap_digest) {
+	auth_shard.set_omap_digest_mismatch_oi();
 	++deep_errors;
 	errorstream << pgid << " recorded omap digest 0x"
 		    << std::hex << auth_oi.omap_digest << " != on disk 0x"
@@ -662,18 +724,8 @@ void PGBackend::be_compare_scrubmaps(
 	if (repair)
 	  update = FORCE;
       }
+      object_error.add_shard(auth->first, auth_shard);
 
-      if (auth_object.digest_present && auth_object.omap_digest_present &&
-	  (!auth_oi.is_data_digest() || !auth_oi.is_omap_digest())) {
-	dout(20) << __func__ << " missing digest on " << *k << dendl;
-	update = MAYBE;
-      }
-      if (g_conf->osd_debug_scrub_chance_rewrite_digest &&
-	  (((unsigned)rand() % 100) >
-	   g_conf->osd_debug_scrub_chance_rewrite_digest)) {
-	dout(20) << __func__ << " randomly updating digest on " << *k << dendl;
-	update = MAYBE;
-      }
       if (update != NO) {
 	utime_t age = now - auth_oi.local_mtime;
 	if (update == FORCE ||
@@ -688,5 +740,8 @@ void PGBackend::be_compare_scrubmaps(
 	}
       }
     }
+    if (object_error.errors) {
+      store->add_object_error(k->pool, object_error);
+    }
   }
 }
diff --git a/src/osd/PGBackend.h b/src/osd/PGBackend.h
index 7706797..f88c1a0 100644
--- a/src/osd/PGBackend.h
+++ b/src/osd/PGBackend.h
@@ -27,6 +27,11 @@
 #include "common/LogClient.h"
 #include <string>
 
+namespace Scrub {
+  class Store;
+}
+struct shard_info_wrapper;
+
  /**
   * PGBackend
   *
@@ -181,7 +186,7 @@
        const eversion_t &trim_to,
        const eversion_t &trim_rollback_to,
        bool transaction_applied,
-       ObjectStore::Transaction *t) = 0;
+       ObjectStore::Transaction &t) = 0;
 
      virtual void update_peer_last_complete_ondisk(
        pg_shard_t fromosd,
@@ -210,7 +215,6 @@
      virtual uint64_t min_peer_features() const = 0;
      virtual bool sort_bitwise() const = 0;
 
-     virtual bool transaction_use_tbl() = 0;
      virtual hobject_t get_temp_recovery_object(eversion_t version,
 						snapid_t snap) = 0;
 
@@ -467,6 +471,8 @@
      virtual uint64_t get_bytes_written() const = 0;
      virtual ~PGTransaction() {}
    };
+   using PGTransactionUPtr = std::unique_ptr<PGTransaction>;
+
    /// Get implementation specific empty transaction
    virtual PGTransaction *get_transaction() = 0;
 
@@ -474,7 +480,7 @@
    virtual void submit_transaction(
      const hobject_t &hoid,               ///< [in] object
      const eversion_t &at_version,        ///< [in] version
-     PGTransaction *t,                    ///< [in] trans to execute
+     PGTransactionUPtr &&t,               ///< [in] trans to execute (move)
      const eversion_t &trim_to,           ///< [in] trim log to here
      const eversion_t &trim_rollback_to,  ///< [in] trim rollback info to here
      const vector<pg_log_entry_t> &log_entries, ///< [in] log entries for t
@@ -489,6 +495,11 @@
      ) = 0;
 
 
+   void try_stash(
+     const hobject_t &hoid,
+     version_t v,
+     ObjectStore::Transaction *t);
+
    void rollback(
      const hobject_t &hoid,
      const ObjectModDesc &desc,
@@ -512,6 +523,12 @@
      version_t old_version,
      ObjectStore::Transaction *t);
 
+   /// Unstash object to rollback stash
+   void rollback_try_stash(
+     const hobject_t &hoid,
+     version_t old_version,
+     ObjectStore::Transaction *t);
+
    /// Delete object to rollback create
    void rollback_create(
      const hobject_t &hoid,
@@ -569,23 +586,22 @@
      pg_shard_t auth_shard,
      const ScrubMap::object &auth,
      const object_info_t& auth_oi,
-     bool okseed,
      const ScrubMap::object &candidate,
+     shard_info_wrapper& shard_error,
      ostream &errorstream);
    map<pg_shard_t, ScrubMap *>::const_iterator be_select_auth_object(
      const hobject_t &obj,
      const map<pg_shard_t,ScrubMap*> &maps,
-     bool okseed,
      object_info_t *auth_oi);
    void be_compare_scrubmaps(
      const map<pg_shard_t,ScrubMap*> &maps,
-     bool okseed,   ///< true if scrub digests have same seed our oi digests
      bool repair,
      map<hobject_t, set<pg_shard_t>, hobject_t::BitwiseComparator> &missing,
      map<hobject_t, set<pg_shard_t>, hobject_t::BitwiseComparator> &inconsistent,
      map<hobject_t, list<pg_shard_t>, hobject_t::BitwiseComparator> &authoritative,
      map<hobject_t, pair<uint32_t,uint32_t>, hobject_t::BitwiseComparator> &missing_digest,
      int &shallow_errors, int &deep_errors,
+     Scrub::Store *store,
      const spg_t& pgid,
      const vector<int> &acting,
      ostream &errorstream);
diff --git a/src/osd/PGLog.cc b/src/osd/PGLog.cc
index 5165c52..e8f2a3a 100644
--- a/src/osd/PGLog.cc
+++ b/src/osd/PGLog.cc
@@ -21,6 +21,13 @@
 #include "../include/unordered_map.h"
 
 #define dout_subsys ceph_subsys_osd
+#undef dout_prefix
+#define dout_prefix _prefix(_dout, this)
+
+static ostream& _prefix(std::ostream *_dout, const PGLog *pglog)
+{
+  return *_dout << pglog->gen_prefix();
+}
 
 //////////////////// PGLog::IndexedLog ////////////////////
 
@@ -277,7 +284,8 @@ void PGLog::proc_replica_log(
     olog.can_rollback_to,
     omissing,
     0,
-    0);
+    0,
+    this);
 
   if (lu < oinfo.last_update) {
     dout(10) << " peer osd." << from << " last_update now " << lu << dendl;
@@ -330,15 +338,16 @@ void PGLog::_merge_object_divergent_entries(
   eversion_t olog_can_rollback_to,
   pg_missing_t &missing,
   boost::optional<pair<eversion_t, hobject_t> > *new_divergent_prior,
-  LogEntryHandler *rollbacker
+  LogEntryHandler *rollbacker,
+  const DoutPrefixProvider *dpp
   )
 {
-  dout(10) << __func__ << ": merging hoid " << hoid
-	   << " entries: " << entries << dendl;
+  ldpp_dout(dpp, 20) << __func__ << ": merging hoid " << hoid
+		     << " entries: " << entries << dendl;
 
   if (cmp(hoid, info.last_backfill, info.last_backfill_bitwise) > 0) {
-    dout(10) << __func__ << ": hoid " << hoid << " after last_backfill"
-	     << dendl;
+    ldpp_dout(dpp, 10) << __func__ << ": hoid " << hoid << " after last_backfill"
+		       << dendl;
     return;
   }
 
@@ -368,11 +377,11 @@ void PGLog::_merge_object_divergent_entries(
   const bool object_not_in_store =
     !missing.is_missing(hoid) &&
     entries.rbegin()->is_delete();
-  dout(10) << __func__ << ": hoid " << hoid
-	   << " prior_version: " << prior_version
-	   << " first_divergent_update: " << first_divergent_update
-	   << " last_divergent_update: " << last_divergent_update
-	   << dendl;
+  ldpp_dout(dpp, 10) << __func__ << ": hoid " << hoid
+		     << " prior_version: " << prior_version
+		     << " first_divergent_update: " << first_divergent_update
+		     << " last_divergent_update: " << last_divergent_update
+		     << dendl;
 
   ceph::unordered_map<hobject_t, pg_log_entry_t*>::const_iterator objiter =
     log.objects.find(hoid);
@@ -381,8 +390,8 @@ void PGLog::_merge_object_divergent_entries(
     /// Case 1)
     assert(objiter->second->version > last_divergent_update);
 
-    dout(10) << __func__ << ": more recent entry found: "
-	     << *objiter->second << ", already merged" << dendl;
+    ldpp_dout(dpp, 10) << __func__ << ": more recent entry found: "
+		       << *objiter->second << ", already merged" << dendl;
 
     // ensure missing has been updated appropriately
     if (objiter->second->is_update()) {
@@ -397,13 +406,14 @@ void PGLog::_merge_object_divergent_entries(
     return;
   }
 
-  dout(10) << __func__ << ": hoid " << hoid
-	   <<" has no more recent entries in log" << dendl;
+  ldpp_dout(dpp, 10) << __func__ << ": hoid " << hoid
+		     <<" has no more recent entries in log" << dendl;
   if (prior_version == eversion_t() || entries.front().is_clone()) {
     /// Case 2)
-    dout(10) << __func__ << ": hoid " << hoid
-	     << " prior_version or op type indicates creation, deleting"
-	     << dendl;
+    ldpp_dout(dpp, 10) << __func__ << ": hoid " << hoid
+		       << " prior_version or op type indicates creation,"
+		       << " deleting"
+		       << dendl;
     if (missing.is_missing(hoid))
       missing.rm(missing.missing.find(hoid));
     if (rollbacker && !object_not_in_store)
@@ -413,24 +423,25 @@ void PGLog::_merge_object_divergent_entries(
 
   if (missing.is_missing(hoid)) {
     /// Case 3)
-    dout(10) << __func__ << ": hoid " << hoid
-	     << " missing, " << missing.missing[hoid]
-	     << " adjusting" << dendl;
+    ldpp_dout(dpp, 10) << __func__ << ": hoid " << hoid
+		       << " missing, " << missing.missing[hoid]
+		       << " adjusting" << dendl;
 
     if (missing.missing[hoid].have == prior_version) {
-      dout(10) << __func__ << ": hoid " << hoid
+      ldpp_dout(dpp, 10) << __func__ << ": hoid " << hoid
 	       << " missing.have is prior_version " << prior_version
 	       << " removing from missing" << dendl;
       missing.rm(missing.missing.find(hoid));
     } else {
-      dout(10) << __func__ << ": hoid " << hoid
-	       << " missing.have is " << missing.missing[hoid].have
-	       << ", adjusting" << dendl;
+      ldpp_dout(dpp, 10) << __func__ << ": hoid " << hoid
+			 << " missing.have is " << missing.missing[hoid].have
+			 << ", adjusting" << dendl;
       missing.revise_need(hoid, prior_version);
       if (prior_version <= info.log_tail) {
-	dout(10) << __func__ << ": hoid " << hoid
-		 << " prior_version " << prior_version << " <= info.log_tail "
-		 << info.log_tail << dendl;
+	ldpp_dout(dpp, 10) << __func__ << ": hoid " << hoid
+			   << " prior_version " << prior_version
+			   << " <= info.log_tail "
+			   << info.log_tail << dendl;
 	if (new_divergent_prior)
 	  *new_divergent_prior = make_pair(prior_version, hoid);
       }
@@ -438,17 +449,18 @@ void PGLog::_merge_object_divergent_entries(
     return;
   }
 
-  dout(10) << __func__ << ": hoid " << hoid
-	   << " must be rolled back or recovered, attempting to rollback"
-	   << dendl;
+  ldpp_dout(dpp, 10) << __func__ << ": hoid " << hoid
+		     << " must be rolled back or recovered,"
+		     << " attempting to rollback"
+		     << dendl;
   bool can_rollback = true;
   /// Distinguish between 4) and 5)
   for (list<pg_log_entry_t>::const_reverse_iterator i = entries.rbegin();
        i != entries.rend();
        ++i) {
     if (!i->mod_desc.can_rollback() || i->version <= olog_can_rollback_to) {
-      dout(10) << __func__ << ": hoid " << hoid << " cannot rollback "
-	       << *i << dendl;
+      ldpp_dout(dpp, 10) << __func__ << ": hoid " << hoid << " cannot rollback "
+			 << *i << dendl;
       can_rollback = false;
       break;
     }
@@ -460,24 +472,26 @@ void PGLog::_merge_object_divergent_entries(
 	 i != entries.rend();
 	 ++i) {
       assert(i->mod_desc.can_rollback() && i->version > olog_can_rollback_to);
-      dout(10) << __func__ << ": hoid " << hoid
-	       << " rolling back " << *i << dendl;
+      ldpp_dout(dpp, 10) << __func__ << ": hoid " << hoid
+			 << " rolling back " << *i << dendl;
       if (rollbacker)
 	rollbacker->rollback(*i);
     }
-    dout(10) << __func__ << ": hoid " << hoid << " rolled back" << dendl;
+    ldpp_dout(dpp, 10) << __func__ << ": hoid " << hoid
+		       << " rolled back" << dendl;
     return;
   } else {
     /// Case 5)
-    dout(10) << __func__ << ": hoid " << hoid << " cannot roll back, "
-	     << "removing and adding to missing" << dendl;
+    ldpp_dout(dpp, 10) << __func__ << ": hoid " << hoid << " cannot roll back, "
+		       << "removing and adding to missing" << dendl;
     if (rollbacker && !object_not_in_store)
       rollbacker->remove(hoid);
     missing.add(hoid, prior_version, eversion_t());
     if (prior_version <= info.log_tail) {
-      dout(10) << __func__ << ": hoid " << hoid
-	       << " prior_version " << prior_version << " <= info.log_tail "
-	       << info.log_tail << dendl;
+      ldpp_dout(dpp, 10) << __func__ << ": hoid " << hoid
+			 << " prior_version " << prior_version
+			 << " <= info.log_tail "
+			 << info.log_tail << dendl;
       if (new_divergent_prior)
 	*new_divergent_prior = make_pair(prior_version, hoid);
     }
@@ -537,7 +551,8 @@ void PGLog::rewind_divergent_log(ObjectStore::Transaction& t, eversion_t newhead
     log.can_rollback_to,
     missing,
     &new_priors,
-    rollbacker);
+    rollbacker,
+    this);
   for (map<eversion_t, hobject_t>::iterator i = new_priors.begin();
        i != new_priors.end();
        ++i) {
@@ -553,6 +568,44 @@ void PGLog::rewind_divergent_log(ObjectStore::Transaction& t, eversion_t newhead
   dirty_big_info = true;
 }
 
+void PGLog::append_log_entries_update_missing(
+  const hobject_t &last_backfill,
+  bool last_backfill_bitwise,
+  const list<pg_log_entry_t> &entries,
+  IndexedLog *log,
+  pg_missing_t &missing,
+  LogEntryHandler *rollbacker,
+  const DoutPrefixProvider *dpp)
+{
+  if (log && !entries.empty()) {
+    assert(log->head < entries.begin()->version);
+    log->head = entries.rbegin()->version;
+  }
+  for (list<pg_log_entry_t>::const_iterator p = entries.begin();
+       p != entries.end();
+       ++p) {
+    if (log) {
+      log->log.push_back(*p);
+      pg_log_entry_t &ne = log->log.back();
+      ldpp_dout(dpp, 20) << "update missing, append " << ne << dendl;
+      log->index(ne);
+    }
+    if (cmp(p->soid, last_backfill, last_backfill_bitwise) <= 0) {
+      missing.add_next_event(*p);
+      if (rollbacker) {
+	// hack to match PG::mark_all_unfound_lost
+	if (p->is_lost_delete() && p->mod_desc.can_rollback()) {
+	  rollbacker->try_stash(p->soid, p->version.version);
+	} else if (p->is_delete()) {
+	  rollbacker->remove(p->soid);
+	}
+      }
+    }
+  }
+  if (log)
+    log->reset_rollback_info_trimmed_to_riter();
+}
+
 void PGLog::merge_log(ObjectStore::Transaction& t,
                       pg_info_t &oinfo, pg_log_t &olog, pg_shard_t fromosd,
                       pg_info_t &info, LogEntryHandler *rollbacker,
@@ -641,18 +694,6 @@ void PGLog::merge_log(ObjectStore::Transaction& t,
     }
     mark_dirty_from(lower_bound);
 
-    // index, update missing, delete deleted
-    for (list<pg_log_entry_t>::iterator p = from; p != to; ++p) {
-      pg_log_entry_t &ne = *p;
-      dout(20) << "merge_log " << ne << dendl;
-      log.index(ne);
-      if (cmp(ne.soid, info.last_backfill, info.last_backfill_bitwise) <= 0) {
-	missing.add_next_event(ne);
-	if (ne.is_delete())
-	  rollbacker->remove(ne.soid);
-      }
-    }
-      
     // move aside divergent items
     list<pg_log_entry_t> divergent;
     while (!log.empty()) {
@@ -672,9 +713,16 @@ void PGLog::merge_log(ObjectStore::Transaction& t,
       log.log.pop_back();
     }
 
-    // splice
-    log.log.splice(log.log.end(), 
-		   olog.log, from, to);
+    list<pg_log_entry_t> entries;
+    entries.splice(entries.end(), olog.log, from, to);
+    append_log_entries_update_missing(
+      info.last_backfill,
+      info.last_backfill_bitwise,
+      entries,
+      &log,
+      missing,
+      rollbacker,
+      this);
     log.index();   
 
     info.last_update = log.head = olog.head;
@@ -690,7 +738,8 @@ void PGLog::merge_log(ObjectStore::Transaction& t,
       log.can_rollback_to,
       missing,
       &new_priors,
-      rollbacker);
+      rollbacker,
+      this);
     for (map<eversion_t, hobject_t>::iterator i = new_priors.begin();
 	 i != new_priors.end();
 	 ++i) {
@@ -874,15 +923,17 @@ void PGLog::_write_log(
 
 void PGLog::read_log(ObjectStore *store, coll_t pg_coll,
 		     coll_t log_coll,
-		    ghobject_t log_oid,
-		    const pg_info_t &info,
-		    map<eversion_t, hobject_t> &divergent_priors,
-		    IndexedLog &log,
-		    pg_missing_t &missing,
-		    ostringstream &oss,
-		    set<string> *log_keys_debug)
+		     ghobject_t log_oid,
+		     const pg_info_t &info,
+		     map<eversion_t, hobject_t> &divergent_priors,
+		     IndexedLog &log,
+		     pg_missing_t &missing,
+		     ostringstream &oss,
+		     const DoutPrefixProvider *dpp,
+		     set<string> *log_keys_debug)
 {
-  dout(20) << "read_log coll " << pg_coll << " log_oid " << log_oid << dendl;
+  ldpp_dout(dpp, 20) << "read_log coll " << pg_coll
+		     << " log_oid " << log_oid << dendl;
 
   // legacy?
   struct stat st;
@@ -903,25 +954,26 @@ void PGLog::read_log(ObjectStore *store, coll_t pg_coll,
       bufferlist bl = p->value();//Copy bufferlist before creating iterator
       bufferlist::iterator bp = bl.begin();
       if (p->key() == "divergent_priors") {
-        ::decode(divergent_priors, bp);
-        dout(20) << "read_log " << divergent_priors.size() << " divergent_priors" << dendl;
+	::decode(divergent_priors, bp);
+	ldpp_dout(dpp, 20) << "read_log " << divergent_priors.size()
+			   << " divergent_priors" << dendl;
       } else if (p->key() == "can_rollback_to") {
         ::decode(log.can_rollback_to, bp);
       } else if (p->key() == "rollback_info_trimmed_to") {
         ::decode(log.rollback_info_trimmed_to, bp);
       } else {
-        pg_log_entry_t e;
-        e.decode_with_checksum(bp);
-        dout(20) << "read_log " << e << dendl;
-        if (!log.log.empty()) {
-          pg_log_entry_t last_e(log.log.back());
-          assert(last_e.version.version < e.version.version);
-          assert(last_e.version.epoch <= e.version.epoch);
-        }
-        log.log.push_back(e);
-        log.head = e.version;
-        if (log_keys_debug)
-          log_keys_debug->insert(e.get_key_name());
+	pg_log_entry_t e;
+	e.decode_with_checksum(bp);
+	ldpp_dout(dpp, 20) << "read_log " << e << dendl;
+	if (!log.log.empty()) {
+	  pg_log_entry_t last_e(log.log.back());
+	  assert(last_e.version.version < e.version.version);
+	  assert(last_e.version.epoch <= e.version.epoch);
+	}
+	log.log.push_back(e);
+	log.head = e.version;
+	if (log_keys_debug)
+	  log_keys_debug->insert(e.get_key_name());
       }
     }
   }
@@ -930,8 +982,9 @@ void PGLog::read_log(ObjectStore *store, coll_t pg_coll,
 
   // build missing
   if (info.last_complete < info.last_update) {
-    dout(10) << "read_log checking for missing items over interval (" << info.last_complete
-	     << "," << info.last_update << "]" << dendl;
+    ldpp_dout(dpp, 10) << "read_log checking for missing items over interval ("
+		       << info.last_complete
+		       << "," << info.last_update << "]" << dendl;
 
     set<hobject_t, hobject_t::BitwiseComparator> did;
     for (list<pg_log_entry_t>::reverse_iterator i = log.log.rbegin();
@@ -954,11 +1007,12 @@ void PGLog::read_log(ObjectStore *store, coll_t pg_coll,
       if (r >= 0) {
 	object_info_t oi(bv);
 	if (oi.version < i->version) {
-	  dout(15) << "read_log  missing " << *i << " (have " << oi.version << ")" << dendl;
+	  ldpp_dout(dpp, 15) << "read_log  missing " << *i
+			     << " (have " << oi.version << ")" << dendl;
 	  missing.add(i->soid, i->version, oi.version);
 	}
       } else {
-	dout(15) << "read_log  missing " << *i << dendl;
+	ldpp_dout(dpp, 15) << "read_log  missing " << *i << dendl;
 	missing.add(i->soid, i->version, eversion_t());
       }
     }
@@ -992,11 +1046,11 @@ void PGLog::read_log(ObjectStore *store, coll_t pg_coll,
 	 */
 	assert(oi.version == i->first);
       } else {
-	dout(15) << "read_log  missing " << *i << dendl;
+	ldpp_dout(dpp, 15) << "read_log  missing " << *i << dendl;
 	missing.add(i->second, i->first, eversion_t());
       }
     }
   }
-  dout(10) << "read_log done" << dendl;
+  ldpp_dout(dpp, 10) << "read_log done" << dendl;
 }
 
diff --git a/src/osd/PGLog.h b/src/osd/PGLog.h
index 3a9b697..0083303 100644
--- a/src/osd/PGLog.h
+++ b/src/osd/PGLog.h
@@ -30,13 +30,28 @@ using namespace std;
 #define PGLOG_INDEXED_EXTRA_CALLER_OPS (1 << 2)
 #define PGLOG_INDEXED_ALL              (PGLOG_INDEXED_OBJECTS | PGLOG_INDEXED_CALLER_OPS | PGLOG_INDEXED_EXTRA_CALLER_OPS)
 
-struct PGLog {
+struct PGLog : DoutPrefixProvider {
+  DoutPrefixProvider *prefix_provider;
+  string gen_prefix() const {
+    return prefix_provider ? prefix_provider->gen_prefix() : "";
+  }
+  unsigned get_subsys() const {
+    return prefix_provider ? prefix_provider->get_subsys() :
+      (unsigned)ceph_subsys_osd;
+  }
+  CephContext *get_cct() const {
+    return cct;
+  }
+
   ////////////////////////////// sub classes //////////////////////////////
   struct LogEntryHandler {
     virtual void rollback(
       const pg_log_entry_t &entry) = 0;
     virtual void remove(
       const hobject_t &hoid) = 0;
+    virtual void try_stash(
+      const hobject_t &entry,
+      version_t v) = 0;
     virtual void trim(
       const pg_log_entry_t &entry) = 0;
     virtual ~LogEntryHandler() {}
@@ -220,6 +235,13 @@ struct PGLog {
         ++rollback_info_trimmed_to_riter;
     }
 
+    void reset_rollback_info_trimmed_to_riter() {
+      rollback_info_trimmed_to_riter = log.rbegin();
+      while (rollback_info_trimmed_to_riter != log.rend() &&
+	     rollback_info_trimmed_to_riter->version > rollback_info_trimmed_to)
+	++rollback_info_trimmed_to_riter;
+    }
+
     // indexes objects, caller ops and extra caller ops
     void index() {
       objects.clear();
@@ -246,7 +268,7 @@ struct PGLog {
         
       reset_riter();
       indexed_data = PGLOG_INDEXED_ALL;
-        
+      reset_rollback_info_trimmed_to_riter();
     }
 
     void index_objects() const {
@@ -258,7 +280,6 @@ struct PGLog {
        }
  
       indexed_data |= PGLOG_INDEXED_OBJECTS;
-
     }
 
     void index_caller_ops() const {
@@ -479,7 +500,8 @@ protected:
   }
 public:
   // cppcheck-suppress noExplicitConstructor
-  PGLog(CephContext *cct = 0) :
+  PGLog(CephContext *cct, DoutPrefixProvider *dpp = 0) :
+    prefix_provider(dpp),
     dirty_from(eversion_t::max()),
     writeout_from(eversion_t::max()), 
     cct(cct), 
@@ -679,7 +701,8 @@ protected:
     eversion_t olog_can_rollback_to,     ///< [in] rollback boundary
     pg_missing_t &omissing,              ///< [in,out] missing to adjust, use
     boost::optional<pair<eversion_t, hobject_t> > *new_divergent_prior,
-    LogEntryHandler *rollbacker          ///< [in] optional rollbacker object
+    LogEntryHandler *rollbacker,         ///< [in] optional rollbacker object
+    const DoutPrefixProvider *dpp        ///< [in] logging provider
     );
 
   /// Merge all entries using above
@@ -690,7 +713,8 @@ protected:
     eversion_t olog_can_rollback_to,     ///< [in] rollback boundary
     pg_missing_t &omissing,              ///< [in,out] missing to adjust, use
     map<eversion_t, hobject_t> *priors,  ///< [out] target for new priors
-    LogEntryHandler *rollbacker          ///< [in] optional rollbacker object
+    LogEntryHandler *rollbacker,         ///< [in] optional rollbacker object
+    const DoutPrefixProvider *dpp        ///< [in] logging provider
     ) {
     map<hobject_t, list<pg_log_entry_t>, hobject_t::BitwiseComparator > split;
     split_by_object(entries, &split);
@@ -706,7 +730,8 @@ protected:
 	olog_can_rollback_to,
 	omissing,
 	&new_divergent_prior,
-	rollbacker);
+	rollbacker,
+	dpp);
       if (priors && new_divergent_prior) {
 	(*priors)[new_divergent_prior->first] = new_divergent_prior->second;
       }
@@ -733,7 +758,8 @@ protected:
       log.can_rollback_to,
       missing,
       &new_divergent_prior,
-      rollbacker);
+      rollbacker,
+      this);
     if (new_divergent_prior)
       add_divergent_prior(
 	(*new_divergent_prior).first,
@@ -749,6 +775,32 @@ public:
 		 pg_info_t &info, LogEntryHandler *rollbacker,
 		 bool &dirty_info, bool &dirty_big_info);
 
+  static void append_log_entries_update_missing(
+    const hobject_t &last_backfill,
+    bool last_backfill_bitwise,
+    const list<pg_log_entry_t> &entries,
+    IndexedLog *log,
+    pg_missing_t &missing,
+    LogEntryHandler *rollbacker,
+    const DoutPrefixProvider *dpp);
+  void append_new_log_entries(
+    const hobject_t &last_backfill,
+    bool last_backfill_bitwise,
+    const list<pg_log_entry_t> &entries,
+    LogEntryHandler *rollbacker) {
+    append_log_entries_update_missing(
+      last_backfill,
+      last_backfill_bitwise,
+      entries,
+      &log,
+      missing,
+      rollbacker,
+      this);
+    if (!entries.empty()) {
+      mark_writeout_from(entries.begin()->version);
+    }
+  }
+
   void write_log(ObjectStore::Transaction& t,
 		 map<string,bufferlist> *km,
 		 const coll_t& coll,
@@ -785,6 +837,7 @@ public:
     return read_log(
       store, pg_coll, log_coll, log_oid, info, divergent_priors,
       log, missing, oss,
+      this,
       (pg_log_debug ? &log_keys_debug : 0));
   }
 
@@ -793,6 +846,7 @@ public:
     const pg_info_t &info, map<eversion_t, hobject_t> &divergent_priors,
     IndexedLog &log,
     pg_missing_t &missing, ostringstream &oss,
+    const DoutPrefixProvider *dpp = NULL,
     set<string> *log_keys_debug = 0
     );
 };
diff --git a/src/osd/ReplicatedBackend.cc b/src/osd/ReplicatedBackend.cc
index bef96d6..5c6d5e8 100644
--- a/src/osd/ReplicatedBackend.cc
+++ b/src/osd/ReplicatedBackend.cc
@@ -209,15 +209,11 @@ bool ReplicatedBackend::handle_message(
 	return true;
       }
     }
-    else {
-      sub_op_modify_reply<MOSDSubOpReply, MSG_OSD_SUBOPREPLY>(op);
-      return true;
-    }
     break;
   }
 
   case MSG_OSD_REPOPREPLY: {
-    sub_op_modify_reply<MOSDRepOpReply, MSG_OSD_REPOPREPLY>(op);
+    sub_op_modify_reply(op);
     return true;
   }
 
@@ -332,10 +328,8 @@ class RPGTransaction : public PGBackend::PGTransaction {
     return coll;
   }
 public:
-  RPGTransaction(coll_t coll, bool use_tbl)
-    : coll(coll), written(0) {
-    t.set_use_tbl(use_tbl);
-  }
+  RPGTransaction(coll_t coll)
+    : coll(coll), written(0) {}
 
   /// Yields ownership of contained transaction
   ObjectStore::Transaction&& get_transaction() {
@@ -521,7 +515,7 @@ public:
 
 PGBackend::PGTransaction *ReplicatedBackend::get_transaction()
 {
-  return new RPGTransaction(coll, parent->transaction_use_tbl());
+  return new RPGTransaction(coll);
 }
 
 class C_OSD_OnOpCommit : public Context {
@@ -549,7 +543,7 @@ public:
 void ReplicatedBackend::submit_transaction(
   const hobject_t &soid,
   const eversion_t &at_version,
-  PGTransaction *_t,
+  PGTransactionUPtr &&_t,
   const eversion_t &trim_to,
   const eversion_t &trim_rollback_to,
   const vector<pg_log_entry_t> &log_entries,
@@ -561,7 +555,8 @@ void ReplicatedBackend::submit_transaction(
   osd_reqid_t reqid,
   OpRequestRef orig_op)
 {
-  RPGTransaction *t = dynamic_cast<RPGTransaction*>(_t);
+  std::unique_ptr<RPGTransaction> t(
+    static_cast<RPGTransaction*>(_t.release()));
   assert(t);
   ObjectStore::Transaction op_t = t->get_transaction();
 
@@ -599,7 +594,7 @@ void ReplicatedBackend::submit_transaction(
     log_entries,
     hset_history,
     &op,
-    &op_t);
+    op_t);
 
   if (!(t->get_temp_added().empty())) {
     add_temp_objs(t->get_temp_added());
@@ -612,7 +607,7 @@ void ReplicatedBackend::submit_transaction(
     trim_to,
     trim_rollback_to,
     true,
-    &op_t);
+    op_t);
   
   op_t.register_on_applied_sync(on_local_applied_sync);
   op_t.register_on_applied(
@@ -621,10 +616,11 @@ void ReplicatedBackend::submit_transaction(
   op_t.register_on_commit(
     parent->bless_context(
       new C_OSD_OnOpCommit(this, &op)));
+
   vector<ObjectStore::Transaction> tls;
   tls.push_back(std::move(op_t));
+
   parent->queue_transactions(tls, op.op);
-  delete t;
 }
 
 void ReplicatedBackend::op_applied(
@@ -666,13 +662,11 @@ void ReplicatedBackend::op_commit(
   }
 }
 
-template<typename T, int MSGTYPE>
 void ReplicatedBackend::sub_op_modify_reply(OpRequestRef op)
 {
-  T *r = static_cast<T *>(op->get_req());
+  MOSDRepOpReply *r = static_cast<MOSDRepOpReply *>(op->get_req());
   r->finish_decode();
-  assert(r->get_header().type == MSGTYPE);
-  assert(MSGTYPE == MSG_OSD_SUBOPREPLY || MSGTYPE == MSG_OSD_REPOPREPLY);
+  assert(r->get_header().type == MSG_OSD_REPOPREPLY);
 
   op->mark_started();
 
@@ -980,7 +974,6 @@ void ReplicatedBackend::do_push_reply(OpRequestRef op)
   send_pushes(m->get_priority(), _replies);
 }
 
-template<typename T, int MSGTYPE>
 Message * ReplicatedBackend::generate_subop(
   const hobject_t &soid,
   const eversion_t &at_version,
@@ -993,14 +986,13 @@ Message * ReplicatedBackend::generate_subop(
   const vector<pg_log_entry_t> &log_entries,
   boost::optional<pg_hit_set_history_t> &hset_hist,
   InProgressOp *op,
-  ObjectStore::Transaction *op_t,
+  ObjectStore::Transaction &op_t,
   pg_shard_t peer,
   const pg_info_t &pinfo)
 {
   int acks_wanted = CEPH_OSD_FLAG_ACK | CEPH_OSD_FLAG_ONDISK;
-  assert(MSGTYPE == MSG_OSD_SUBOP || MSGTYPE == MSG_OSD_REPOP);
   // forward the write/update/whatever
-  T *wr = new T(
+  MOSDRepOp *wr = new MOSDRepOp(
     reqid, parent->whoami_shard(),
     spg_t(get_info().pgid.pgid, peer.shard),
     soid, acks_wanted,
@@ -1015,10 +1007,9 @@ Message * ReplicatedBackend::generate_subop(
 	     << ", pinfo.last_backfill "
 	     << pinfo.last_backfill << ")" << dendl;
     ObjectStore::Transaction t;
-    t.set_use_tbl(op_t->get_use_tbl());
     ::encode(t, wr->get_data());
   } else {
-    ::encode(*op_t, wr->get_data());
+    ::encode(op_t, wr->get_data());
   }
 
   ::encode(log_entries, wr->logbl);
@@ -1049,7 +1040,7 @@ void ReplicatedBackend::issue_op(
   const vector<pg_log_entry_t> &log_entries,
   boost::optional<pg_hit_set_history_t> &hset_hist,
   InProgressOp *op,
-  ObjectStore::Transaction *op_t)
+  ObjectStore::Transaction &op_t)
 {
 
   if (parent->get_actingbackfill_shards().size() > 1) {
@@ -1069,41 +1060,21 @@ void ReplicatedBackend::issue_op(
     const pg_info_t &pinfo = parent->get_shard_info().find(peer)->second;
 
     Message *wr;
-    uint64_t min_features = parent->min_peer_features();
-    if (!(min_features & CEPH_FEATURE_OSD_REPOP)) {
-      dout(20) << "Talking to old version of OSD, doesn't support RepOp, fall back to SubOp" << dendl;
-      wr = generate_subop<MOSDSubOp, MSG_OSD_SUBOP>(
-	    soid,
-	    at_version,
-	    tid,
-	    reqid,
-	    pg_trim_to,
-	    pg_trim_rollback_to,
-	    new_temp_oid,
-	    discard_temp_oid,
-	    log_entries,
-	    hset_hist,
-	    op,
-	    op_t,
-	    peer,
-	    pinfo);
-    } else {
-      wr = generate_subop<MOSDRepOp, MSG_OSD_REPOP>(
-	    soid,
-	    at_version,
-	    tid,
-	    reqid,
-	    pg_trim_to,
-	    pg_trim_rollback_to,
-	    new_temp_oid,
-	    discard_temp_oid,
-	    log_entries,
-	    hset_hist,
-	    op,
-	    op_t,
-	    peer,
-	    pinfo);
-    }
+    wr = generate_subop(
+      soid,
+      at_version,
+      tid,
+      reqid,
+      pg_trim_to,
+      pg_trim_rollback_to,
+      new_temp_oid,
+      discard_temp_oid,
+      log_entries,
+      hset_hist,
+      op,
+      op_t,
+      peer,
+      pinfo);
 
     get_parent()->send_message_osd_cluster(
       peer.osd, wr, get_osdmap()->get_epoch());
@@ -1111,26 +1082,12 @@ void ReplicatedBackend::issue_op(
 }
 
 // sub op modify
-void ReplicatedBackend::sub_op_modify(OpRequestRef op) {
-  Message *m = op->get_req();
-  int msg_type = m->get_type();
-  if (msg_type == MSG_OSD_SUBOP) {
-    sub_op_modify_impl<MOSDSubOp, MSG_OSD_SUBOP>(op);
-  } else if (msg_type == MSG_OSD_REPOP) {
-    sub_op_modify_impl<MOSDRepOp, MSG_OSD_REPOP>(op);
-  } else {
-    assert(0);
-  }
-}
-
-template<typename T, int MSGTYPE>
-void ReplicatedBackend::sub_op_modify_impl(OpRequestRef op)
+void ReplicatedBackend::sub_op_modify(OpRequestRef op)
 {
-  T *m = static_cast<T *>(op->get_req());
+  MOSDRepOp *m = static_cast<MOSDRepOp *>(op->get_req());
   m->finish_decode();
   int msg_type = m->get_type();
-  assert(MSGTYPE == msg_type);
-  assert(msg_type == MSG_OSD_SUBOP || msg_type == MSG_OSD_REPOP);
+  assert(MSG_OSD_REPOP == msg_type);
 
   const hobject_t& soid = m->poid;
 
@@ -1151,7 +1108,7 @@ void ReplicatedBackend::sub_op_modify_impl(OpRequestRef op)
 
   op->mark_started();
 
-  RepModifyRef rm(new RepModify);
+  RepModifyRef rm(std::make_shared<RepModify>());
   rm->op = op;
   rm->ackerosd = ackerosd;
   rm->last_complete = get_info().last_complete;
@@ -1163,7 +1120,6 @@ void ReplicatedBackend::sub_op_modify_impl(OpRequestRef op)
 
   bufferlist::iterator p = m->get_data().begin();
   ::decode(rm->opt, p);
-  rm->localt.set_use_tbl(rm->opt.get_use_tbl());
 
   if (m->new_temp_oid != hobject_t()) {
     dout(20) << __func__ << " start tracking temp " << m->new_temp_oid << dendl;
@@ -1198,7 +1154,7 @@ void ReplicatedBackend::sub_op_modify_impl(OpRequestRef op)
     m->pg_trim_to,
     m->pg_trim_rollback_to,
     update_snaps,
-    &(rm->localt));
+    rm->localt);
 
   rm->opt.register_on_commit(
     parent->bless_context(
diff --git a/src/osd/ReplicatedBackend.h b/src/osd/ReplicatedBackend.h
index 1f04150..ea4d509 100644
--- a/src/osd/ReplicatedBackend.h
+++ b/src/osd/ReplicatedBackend.h
@@ -347,7 +347,7 @@ public:
   void submit_transaction(
     const hobject_t &hoid,
     const eversion_t &at_version,
-    PGTransaction *t,
+    PGTransactionUPtr &&t,
     const eversion_t &trim_to,
     const eversion_t &trim_rollback_to,
     const vector<pg_log_entry_t> &log_entries,
@@ -361,7 +361,6 @@ public:
     );
 
 private:
-  template<typename T, int MSGTYPE>
   Message * generate_subop(
     const hobject_t &soid,
     const eversion_t &at_version,
@@ -374,7 +373,7 @@ private:
     const vector<pg_log_entry_t> &log_entries,
     boost::optional<pg_hit_set_history_t> &hset_history,
     InProgressOp *op,
-    ObjectStore::Transaction *op_t,
+    ObjectStore::Transaction &op_t,
     pg_shard_t peer,
     const pg_info_t &pinfo);
   void issue_op(
@@ -389,14 +388,11 @@ private:
     const vector<pg_log_entry_t> &log_entries,
     boost::optional<pg_hit_set_history_t> &hset_history,
     InProgressOp *op,
-    ObjectStore::Transaction *op_t);
+    ObjectStore::Transaction &op_t);
   void op_applied(InProgressOp *op);
   void op_commit(InProgressOp *op);
-  template<typename T, int MSGTYPE>
   void sub_op_modify_reply(OpRequestRef op);
   void sub_op_modify(OpRequestRef op);
-  template<typename T, int MSGTYPE>
-  void sub_op_modify_impl(OpRequestRef op);
 
   struct RepModify {
     OpRequestRef op;
diff --git a/src/osd/ReplicatedPG.cc b/src/osd/ReplicatedPG.cc
index 9205118..a50dc51 100644
--- a/src/osd/ReplicatedPG.cc
+++ b/src/osd/ReplicatedPG.cc
@@ -20,9 +20,11 @@
 #include "ReplicatedPG.h"
 #include "OSD.h"
 #include "OpRequest.h"
+#include "ScrubStore.h"
 #include "objclass/objclass.h"
 
 #include "common/errno.h"
+#include "common/scrub_types.h"
 #include "common/perf_counters.h"
 
 #include "messages/MOSDOp.h"
@@ -45,6 +47,9 @@
 #include "messages/MOSDPGPush.h"
 #include "messages/MOSDPGPull.h"
 #include "messages/MOSDPGPushReply.h"
+#include "messages/MOSDPGUpdateLogMissing.h"
+#include "messages/MOSDPGUpdateLogMissingReply.h"
+#include "messages/MCommandReply.h"
 
 #include "Watch.h"
 
@@ -158,7 +163,7 @@ public:
 	if (ctx->op)
 	  ctx->pg->requeue_op(ctx->op);
       }
-      ctx->pg->close_op_ctx(ctx, r);
+      ctx->pg->close_op_ctx(ctx);
     }
   }
 
@@ -681,8 +686,13 @@ int ReplicatedPG::get_pgls_filter(bufferlist::iterator& iter, PGLSFilter **pfilt
 
 // ==========================================================
 
-int ReplicatedPG::do_command(cmdmap_t cmdmap, ostream& ss,
-			     bufferlist& idata, bufferlist& odata)
+int ReplicatedPG::do_command(
+  cmdmap_t cmdmap,
+  ostream& ss,
+  bufferlist& idata,
+  bufferlist& odata,
+  ConnectionRef con,
+  ceph_tid_t tid)
 {
   const pg_missing_t &missing = pg_log.get_missing();
   string prefix;
@@ -787,10 +797,8 @@ int ReplicatedPG::do_command(cmdmap_t cmdmap, ostream& ss,
       return -EINVAL;
     }
 
-    ss << "pg has " << unfound
-       << " objects unfound and apparently lost, marking";
-    mark_all_unfound_lost(mode);
-    return 0;
+    mark_all_unfound_lost(mode, con, tid);
+    return -EAGAIN;
   }
   else if (command == "list_missing") {
     hobject_t offset;
@@ -850,7 +858,7 @@ int ReplicatedPG::do_command(cmdmap_t cmdmap, ostream& ss,
     f->close_section();
     f->flush(odata);
     return 0;
-  };
+  }
 
   ss << "unknown pg command " << prefix;
   return -EINVAL;
@@ -1291,11 +1299,17 @@ void ReplicatedPG::do_pg_op(OpRequestRef op)
       }
       break;
 
+   case CEPH_OSD_OP_SCRUBLS:
+      result = do_scrub_ls(m, &osd_op);
+      break;
 
     default:
       result = -EINVAL;
       break;
     }
+
+    if (result < 0)
+      break;
   }
 
   // reply
@@ -1309,6 +1323,41 @@ void ReplicatedPG::do_pg_op(OpRequestRef op)
   delete filter;
 }
 
+int ReplicatedPG::do_scrub_ls(MOSDOp *m, OSDOp *osd_op)
+{
+  if (m->get_pg() != info.pgid.pgid) {
+    dout(10) << " scrubls pg=" << m->get_pg() << " != " << info.pgid << dendl;
+    return -EINVAL; // hmm?
+  }
+  auto bp = osd_op->indata.begin();
+  scrub_ls_arg_t arg;
+  try {
+    arg.decode(bp);
+  } catch (buffer::error&) {
+    dout(10) << " corrupted scrub_ls_arg_t" << dendl;
+    return -EINVAL;
+  }
+  int r = 0;
+  scrub_ls_result_t result = {.interval = info.history.same_interval_since};
+  if (arg.interval != 0 && arg.interval != info.history.same_interval_since) {
+    r = -EAGAIN;
+  } else if (!scrubber.store) {
+    r = -ENOENT;
+  } else if (arg.get_snapsets) {
+    result.vals = scrubber.store->get_snap_errors(osd->store,
+						  get_pgid().pool(),
+						  arg.start_after,
+						  arg.max_return);
+  } else {
+    result.vals = scrubber.store->get_object_errors(osd->store,
+						    get_pgid().pool(),
+						    arg.start_after,
+						    arg.max_return);
+  }
+  ::encode(result, osd_op->outdata);
+  return r;
+}
+
 void ReplicatedPG::calc_trim_to()
 {
   size_t target = cct->_conf->osd_min_pg_log_entries;
@@ -1450,6 +1499,14 @@ void ReplicatedPG::do_request(
     replica_scrub(op, handle);
     break;
 
+  case MSG_OSD_PG_UPDATE_LOG_MISSING:
+    do_update_log_missing(op);
+    break;
+
+  case MSG_OSD_PG_UPDATE_LOG_MISSING_REPLY:
+    do_update_log_missing_reply(op);
+    break;
+
   default:
     assert(0 == "bad message type in do_request");
   }
@@ -1995,13 +2052,13 @@ void ReplicatedPG::do_op(OpRequestRef& op)
   } else if (!get_rw_locks(write_ordered, ctx)) {
     dout(20) << __func__ << " waiting for rw locks " << dendl;
     op->mark_delayed("waiting for rw locks");
-    close_op_ctx(ctx, -EBUSY);
+    close_op_ctx(ctx);
     return;
   }
 
   if (r) {
     dout(20) << __func__ << " returned an error: " << r << dendl;
-    close_op_ctx(ctx, r);
+    close_op_ctx(ctx);
     osd->reply_op_error(op, r);
     return;
   }
@@ -2030,7 +2087,7 @@ void ReplicatedPG::do_op(OpRequestRef& op)
 	classic = true;
       }
       fill_in_copy_get_noent(op, oid, m->ops[0], classic);
-      close_op_ctx(ctx, -ENOENT);
+      close_op_ctx(ctx);
       return;
     }
     reply_ctx(ctx, -ENOENT);
@@ -2119,8 +2176,6 @@ ReplicatedPG::cache_result_t ReplicatedPG::maybe_handle_cache_detail(
   }
 
   // older versions do not proxy the feature bits.
-  bool can_proxy_read = get_osdmap()->get_up_osd_features() &
-    CEPH_FEATURE_OSD_PROXY_FEATURES;
   bool can_proxy_write = get_osdmap()->get_up_osd_features() &
     CEPH_FEATURE_OSD_PROXY_WRITE_FEATURES;
   OpRequestRef promote_op;
@@ -2131,27 +2186,22 @@ ReplicatedPG::cache_result_t ReplicatedPG::maybe_handle_cache_detail(
 	agent_state->evict_mode == TierAgentState::EVICT_MODE_FULL) {
       if (!op->may_write() && !op->may_cache() &&
 	  !write_ordered && !must_promote) {
-	if (can_proxy_read) {
-	  dout(20) << __func__ << " cache pool full, proxying read" << dendl;
-	  do_proxy_read(op);
-	  return cache_result_t::HANDLED_PROXY;
-	} else {
-	  dout(20) << __func__ << " cache pool full, redirect read" << dendl;
-	  do_cache_redirect(op);
-	  return cache_result_t::HANDLED_REDIRECT;
-	}
-	assert(0 == "unreachable");
+	dout(20) << __func__ << " cache pool full, proxying read" << dendl;
+	do_proxy_read(op);
+	return cache_result_t::HANDLED_PROXY;
       }
       dout(20) << __func__ << " cache pool full, waiting" << dendl;
       block_write_on_full_cache(missing_oid, op);
       return cache_result_t::BLOCKED_FULL;
     }
 
-    if (!hit_set) {
+    if (must_promote || (!hit_set && !op->need_skip_promote())) {
       promote_object(obc, missing_oid, oloc, op, promote_obc);
       return cache_result_t::BLOCKED_PROMOTE;
-    } else if (op->may_write() || op->may_cache()) {
-      if (can_proxy_write && !must_promote) {
+    }
+
+    if (op->may_write() || op->may_cache()) {
+      if (can_proxy_write) {
         do_proxy_write(op, missing_oid);
       } else {
 	// promote if can't proxy the write
@@ -2160,21 +2210,18 @@ ReplicatedPG::cache_result_t ReplicatedPG::maybe_handle_cache_detail(
       }
 
       // Promote too?
-      if (!op->need_skip_promote()) {
-        maybe_promote(obc, missing_oid, oloc, in_hit_set,
+      if (!op->need_skip_promote() && 
+          maybe_promote(obc, missing_oid, oloc, in_hit_set,
 	              pool.info.min_write_recency_for_promote,
 		      OpRequestRef(),
-		      promote_obc);
+		      promote_obc)) {
+	return cache_result_t::BLOCKED_PROMOTE;
       }
       return cache_result_t::HANDLED_PROXY;
     } else {
       bool did_proxy_read = false;
-      if (can_proxy_read && !must_promote) {
-        do_proxy_read(op);
-	did_proxy_read = true;
-      } else {
-        promote_op = op;   // for non-proxy case promote_object needs this
-      }
+      do_proxy_read(op);
+      did_proxy_read = true;
 
       // Avoid duplicate promotion
       if (obc.get() && obc->is_blocked()) {
@@ -2227,7 +2274,7 @@ ReplicatedPG::cache_result_t ReplicatedPG::maybe_handle_cache_detail(
 
   case pg_pool_t::CACHEMODE_READFORWARD:
     // Do writeback to the cache tier for writes
-    if (op->may_write() || write_ordered) {
+    if (op->may_write() || write_ordered || must_promote) {
       if (agent_state &&
 	  agent_state->evict_mode == TierAgentState::EVICT_MODE_FULL) {
 	dout(20) << __func__ << " cache pool full, waiting" << dendl;
@@ -2244,7 +2291,7 @@ ReplicatedPG::cache_result_t ReplicatedPG::maybe_handle_cache_detail(
 
   case pg_pool_t::CACHEMODE_READPROXY:
     // Do writeback to the cache tier for writes
-    if (op->may_write() || write_ordered) {
+    if (op->may_write() || write_ordered || must_promote) {
       if (agent_state &&
 	  agent_state->evict_mode == TierAgentState::EVICT_MODE_FULL) {
 	dout(20) << __func__ << " cache pool full, waiting" << dendl;
@@ -2278,12 +2325,11 @@ bool ReplicatedPG::maybe_promote(ObjectContextRef obc,
 
   switch (recency) {
   case 0:
-    promote_object(obc, missing_oid, oloc, promote_op, promote_obc);
     break;
   case 1:
     // Check if in the current hit set
     if (in_hit_set) {
-      promote_object(obc, missing_oid, oloc, promote_op, promote_obc);
+      break;
     } else {
       // not promoting
       return false;
@@ -2309,15 +2355,18 @@ bool ReplicatedPG::maybe_promote(ObjectContextRef obc,
 	}
       }
       if (count >= recency) {
-	promote_object(obc, missing_oid, oloc, promote_op);
-      } else {
-	// not promoting
-	return false;
+	break;
       }
+      return false;	// not promoting
     }
     break;
   }
 
+  if (osd->promote_throttle()) {
+    dout(10) << __func__ << " promote throttled" << dendl;
+    return false;
+  }
+  promote_object(obc, missing_oid, oloc, promote_op, promote_obc);
   return true;
 }
 
@@ -2388,7 +2437,7 @@ void ReplicatedPG::do_proxy_read(OpRequestRef op)
 
   dout(10) << __func__ << " Start proxy read for " << *m << dendl;
 
-  ProxyReadOpRef prdop(new ProxyReadOp(op, soid, m->ops));
+  ProxyReadOpRef prdop(std::make_shared<ProxyReadOp>(op, soid, m->ops));
 
   ObjectOperation obj_op;
   obj_op.dup(prdop->ops);
@@ -2573,7 +2622,7 @@ void ReplicatedPG::do_proxy_write(OpRequestRef op, const hobject_t& missing_oid)
   unsigned flags = CEPH_OSD_FLAG_IGNORE_CACHE | CEPH_OSD_FLAG_IGNORE_OVERLAY;
   dout(10) << __func__ << " Start proxy write for " << *m << dendl;
 
-  ProxyWriteOpRef pwop(new ProxyWriteOp(op, soid, m->ops, m->get_reqid()));
+  ProxyWriteOpRef pwop(std::make_shared<ProxyWriteOp>(op, soid, m->ops, m->get_reqid()));
   pwop->ctx = new OpContext(op, m->get_reqid(), pwop->ops, this);
   pwop->mtime = m->get_mtime();
 
@@ -2767,8 +2816,7 @@ void ReplicatedPG::execute_ctx(OpContext *ctx)
 
   // this method must be idempotent since we may call it several times
   // before we finally apply the resulting transaction.
-  delete ctx->op_t;
-  ctx->op_t = pgbackend->get_transaction();
+  ctx->op_t.reset(pgbackend->get_transaction());
 
   if (op->may_write() || op->may_cache()) {
     // snap
@@ -2852,7 +2900,7 @@ void ReplicatedPG::execute_ctx(OpContext *ctx)
 
   if (result == -EAGAIN) {
     // clean up after the ctx
-    close_op_ctx(ctx, result);
+    close_op_ctx(ctx);
     return;
   }
 
@@ -2918,15 +2966,74 @@ void ReplicatedPG::execute_ctx(OpContext *ctx)
     }
   }
 
+  // no need to capture PG ref, repop cancel will handle that
+  // Can capture the ctx by pointer, it's owned by the repop
+  ctx->register_on_applied(
+    [m, ctx, this](){
+      if (m && m->wants_ack() && !ctx->sent_ack && !ctx->sent_disk) {
+	// send ack
+	MOSDOpReply *reply = ctx->reply;
+	if (reply)
+	  ctx->reply = NULL;
+	else {
+	  reply = new MOSDOpReply(m, 0, get_osdmap()->get_epoch(), 0, true);
+	  reply->set_reply_versions(ctx->at_version,
+				    ctx->user_at_version);
+	}
+	reply->add_flags(CEPH_OSD_FLAG_ACK);
+	dout(10) << " sending ack: " << *m << " " << reply << dendl;
+	osd->send_message_osd_client(reply, m->get_connection());
+	ctx->sent_ack = true;
+      }
+
+      // note the write is now readable (for rlatency calc).  note
+      // that this will only be defined if the write is readable
+      // _prior_ to being committed; it will not get set with
+      // writeahead journaling, for instance.
+      if (ctx->readable_stamp == utime_t())
+	ctx->readable_stamp = ceph_clock_now(cct);
+    });
+  ctx->register_on_commit(
+    [m, ctx, this](){
+      if (ctx->op)
+	log_op_stats(
+	  ctx);
+
+      if (m && m->wants_ondisk() && !ctx->sent_disk) {
+	// send commit.
+	MOSDOpReply *reply = ctx->reply;
+	if (reply)
+	  ctx->reply = NULL;
+	else {
+	  reply = new MOSDOpReply(m, 0, get_osdmap()->get_epoch(), 0, true);
+	  reply->set_reply_versions(ctx->at_version,
+				    ctx->user_at_version);
+	}
+	reply->add_flags(CEPH_OSD_FLAG_ACK | CEPH_OSD_FLAG_ONDISK);
+	dout(10) << " sending commit on " << *m << " " << reply << dendl;
+	osd->send_message_osd_client(reply, m->get_connection());
+	ctx->sent_disk = true;
+	ctx->op->mark_commit_sent();
+      }
+    });
+  ctx->register_on_success(
+    [ctx, this]() {
+      do_osd_op_effects(
+	ctx,
+	ctx->op ? ctx->op->get_req()->get_connection() :
+	ConnectionRef());
+    });
+  ctx->register_on_finish(
+    [ctx, this]() {
+      delete ctx;
+    });
+
   // issue replica writes
   ceph_tid_t rep_tid = osd->get_tid();
-  RepGather *repop = new_repop(ctx, obc, rep_tid);  // new repop claims our obc, src_obc refs
-  // note: repop now owns ctx AND ctx->op
-
-  repop->src_obc.swap(src_obc); // and src_obc.
 
-  issue_repop(repop);
+  RepGather *repop = new_repop(ctx, obc, rep_tid);
 
+  issue_repop(repop, ctx);
   eval_repop(repop);
   repop->put();
 }
@@ -2935,14 +3042,14 @@ void ReplicatedPG::reply_ctx(OpContext *ctx, int r)
 {
   if (ctx->op)
     osd->reply_op_error(ctx->op, r);
-  close_op_ctx(ctx, r);
+  close_op_ctx(ctx);
 }
 
 void ReplicatedPG::reply_ctx(OpContext *ctx, int r, eversion_t v, version_t uv)
 {
   if (ctx->op)
     osd->reply_op_error(ctx->op, r, v, uv);
-  close_op_ctx(ctx, r);
+  close_op_ctx(ctx);
 }
 
 void ReplicatedPG::log_op_stats(OpContext *ctx)
@@ -3074,7 +3181,7 @@ void ReplicatedPG::do_scan(
 		<< ratio << ", which exceeds " << full_ratio << dendl;
 	queue_peering_event(
 	  CephPeeringEvtRef(
-	    new CephPeeringEvt(
+	    std::make_shared<CephPeeringEvt>(
 	      get_osdmap()->get_epoch(),
 	      get_osdmap()->get_epoch(),
 	      BackfillTooFull())));
@@ -3152,7 +3259,7 @@ void ReplicatedPG::do_backfill(OpRequestRef op)
       osd->send_message_osd_cluster(reply, m->get_connection());
       queue_peering_event(
 	CephPeeringEvtRef(
-	  new CephPeeringEvt(
+	  std::make_shared<CephPeeringEvt>(
 	    get_osdmap()->get_epoch(),
 	    get_osdmap()->get_epoch(),
 	    RecoveryDone())));
@@ -3188,7 +3295,7 @@ void ReplicatedPG::do_backfill(OpRequestRef op)
   }
 }
 
-ReplicatedPG::RepGather *ReplicatedPG::trim_object(const hobject_t &coid)
+ReplicatedPG::OpContextUPtr ReplicatedPG::trim_object(const hobject_t &coid)
 {
   // load clone info
   bufferlist bl;
@@ -3199,28 +3306,12 @@ ReplicatedPG::RepGather *ReplicatedPG::trim_object(const hobject_t &coid)
   }
   assert(obc->ssc);
 
-  if (!obc->get_snaptrimmer_write()) {
-    dout(10) << __func__ << ": Unable to get a wlock on " << coid << dendl;
-    return NULL;
-  }
-
   hobject_t snapoid(
     coid.oid, coid.get_key(),
     obc->ssc->snapset.head_exists ? CEPH_NOSNAP:CEPH_SNAPDIR, coid.get_hash(),
     info.pgid.pool(), coid.get_namespace());
   ObjectContextRef snapset_obc = get_object_context(snapoid, false);
 
-  if (!snapset_obc->get_snaptrimmer_write()) {
-    dout(10) << __func__ << ": Unable to get a wlock on " << snapoid << dendl;
-    list<OpRequestRef> to_wake;
-    bool requeue_recovery = false;
-    bool requeue_snaptrimmer = false;
-    obc->put_write(&to_wake, &requeue_recovery, &requeue_snaptrimmer);
-    assert(to_wake.empty());
-    assert(!requeue_recovery);
-    return NULL;
-  }
-
   object_info_t &coi = obc->obs.oi;
   set<snapid_t> old_snaps(coi.snaps.begin(), coi.snaps.end());
   if (old_snaps.empty()) {
@@ -3255,13 +3346,28 @@ ReplicatedPG::RepGather *ReplicatedPG::trim_object(const hobject_t &coid)
     }
   }
 
-  RepGather *repop = simple_repop_create(obc);
-  OpContext *ctx = repop->ctx;
+  OpContextUPtr ctx = simple_opc_create(obc);
   ctx->snapset_obc = snapset_obc;
-  ctx->lock_to_release = OpContext::W_LOCK;
-  ctx->release_snapset_obc = true;
+
+  if (!ctx->lock_manager.get_snaptrimmer_write(
+	coid,
+	obc)) {
+    close_op_ctx(ctx.release());
+    dout(10) << __func__ << ": Unable to get a wlock on " << coid << dendl;
+    return NULL;
+  }
+
+  if (!ctx->lock_manager.get_snaptrimmer_write(
+	snapoid,
+	snapset_obc)) {
+    close_op_ctx(ctx.release());
+    dout(10) << __func__ << ": Unable to get a wlock on " << snapoid << dendl;
+    return NULL;
+  }
+
   ctx->at_version = get_next_version();
-  PGBackend::PGTransaction *t = ctx->op_t;
+
+  PGBackend::PGTransaction *t = ctx->op_t.get();
  
   if (new_snaps.empty()) {
     // remove clone
@@ -3343,7 +3449,7 @@ ReplicatedPG::RepGather *ReplicatedPG::trim_object(const hobject_t &coid)
     coi.version = ctx->at_version;
     bl.clear();
     ::encode(coi, bl);
-    setattr_maybe_cache(ctx->obc, ctx, t, OI_ATTR, bl);
+    setattr_maybe_cache(ctx->obc, ctx.get(), t, OI_ATTR, bl);
 
     ctx->log.push_back(
       pg_log_entry_t(
@@ -3427,7 +3533,7 @@ ReplicatedPG::RepGather *ReplicatedPG::trim_object(const hobject_t &coid)
     bl.clear();
     ::encode(ctx->snapset_obc->obs.oi, bl);
     attrs[OI_ATTR].claim(bl);
-    setattrs_maybe_cache(ctx->snapset_obc, ctx, t, attrs);
+    setattrs_maybe_cache(ctx->snapset_obc, ctx.get(), t, attrs);
 
     if (pool.info.require_rollback()) {
       set<string> changing;
@@ -3439,7 +3545,7 @@ ReplicatedPG::RepGather *ReplicatedPG::trim_object(const hobject_t &coid)
     }
   }
 
-  return repop;
+  return ctx;
 }
 
 void ReplicatedPG::snap_trimmer(epoch_t queued)
@@ -3932,7 +4038,7 @@ int ReplicatedPG::do_osd_ops(OpContext *ctx, vector<OSDOp>& ops)
 
   bool first_read = true;
 
-  PGBackend::PGTransaction* t = ctx->op_t;
+  PGBackend::PGTransaction* t = ctx->op_t.get();
 
   dout(10) << "do_osd_op " << soid << " " << ops << dendl;
 
@@ -4037,7 +4143,6 @@ int ReplicatedPG::do_osd_ops(OpContext *ctx, vector<OSDOp>& ops)
 	}
 
 	// read into a buffer
-	bufferlist bl;
 	bool async = false;
 	if (trimmed_read && op.extent.length == 0) {
 	  // read size was trimmed to zero and it is expected to do nothing
@@ -4337,7 +4442,7 @@ int ReplicatedPG::do_osd_ops(OpContext *ctx, vector<OSDOp>& ops)
       ++ctx->num_write;
       {
 	tracepoint(osd, do_osd_op_pre_try_flush, soid.oid.name.c_str(), soid.snap.val);
-	if (ctx->lock_to_release != OpContext::NONE) {
+	if (ctx->lock_type != ObjectContext::RWState::RWNONE) {
 	  dout(10) << "cache-try-flush without SKIPRWLOCKS flag set" << dendl;
 	  result = -EINVAL;
 	  break;
@@ -4356,7 +4461,7 @@ int ReplicatedPG::do_osd_ops(OpContext *ctx, vector<OSDOp>& ops)
 	  break;
 	}
 	if (oi.is_dirty()) {
-	  result = start_flush(ctx->op, ctx->obc, false, NULL, NULL);
+	  result = start_flush(ctx->op, ctx->obc, false, NULL, boost::none);
 	  if (result == -EINPROGRESS)
 	    result = -EAGAIN;
 	} else {
@@ -4369,7 +4474,7 @@ int ReplicatedPG::do_osd_ops(OpContext *ctx, vector<OSDOp>& ops)
       ++ctx->num_write;
       {
 	tracepoint(osd, do_osd_op_pre_cache_flush, soid.oid.name.c_str(), soid.snap.val);
-	if (ctx->lock_to_release == OpContext::NONE) {
+	if (ctx->lock_type == ObjectContext::RWState::RWNONE) {
 	  dout(10) << "cache-flush with SKIPRWLOCKS flag set" << dendl;
 	  result = -EINVAL;
 	  break;
@@ -4389,7 +4494,7 @@ int ReplicatedPG::do_osd_ops(OpContext *ctx, vector<OSDOp>& ops)
 	}
 	hobject_t missing;
 	if (oi.is_dirty()) {
-	  result = start_flush(ctx->op, ctx->obc, true, &missing, NULL);
+	  result = start_flush(ctx->op, ctx->obc, true, &missing, boost::none);
 	  if (result == -EINPROGRESS)
 	    result = -EAGAIN;
 	} else {
@@ -4497,21 +4602,23 @@ int ReplicatedPG::do_osd_ops(OpContext *ctx, vector<OSDOp>& ops)
 	name[op.xattr.name_len + 1] = 0;
 	
 	bufferlist xattr;
-	if (op.op == CEPH_OSD_OP_CMPXATTR)
-	  result = getattr_maybe_cache(
-	    ctx->obc,
-	    name,
-	    &xattr);
-	else
-	  result = getattr_maybe_cache(
-	    src_obc,
-	    name,
-	    &xattr);
-	if (result < 0 && result != -EEXIST && result != -ENODATA)
-	  break;
-	
-	ctx->delta_stats.num_rd++;
-	ctx->delta_stats.num_rd_kb += SHIFT_ROUND_UP(xattr.length(), 10);
+	if (obs.exists) {
+	  if (op.op == CEPH_OSD_OP_CMPXATTR)
+	    result = getattr_maybe_cache(
+		ctx->obc,
+		name,
+		&xattr);
+	  else
+	    result = getattr_maybe_cache(
+		src_obc,
+		name,
+		&xattr);
+	  if (result < 0 && result != -ENODATA)
+	    break;
+
+	  ctx->delta_stats.num_rd++;
+	  ctx->delta_stats.num_rd_kb += SHIFT_ROUND_UP(xattr.length(), 10);
+	}
 
 	switch (op.xattr.cmp_mode) {
 	case CEPH_OSD_CMPXATTR_MODE_STRING:
@@ -4757,10 +4864,6 @@ int ReplicatedPG::do_osd_ops(OpContext *ctx, vector<OSDOp>& ops)
       ++ctx->num_write;
       {
 	tracepoint(osd, do_osd_op_pre_setallochint, soid.oid.name.c_str(), soid.snap.val, op.alloc_hint.expected_object_size, op.alloc_hint.expected_write_size);
-        if (!(get_min_upacting_features() & CEPH_FEATURE_OSD_SET_ALLOC_HINT)) { 
-          result = -EOPNOTSUPP;
-          break;
-        }
 	if (maybe_create_new_object(ctx)) {
           ctx->mod_desc.create();
           t->touch(soid);
@@ -5144,7 +5247,7 @@ int ReplicatedPG::do_osd_ops(OpContext *ctx, vector<OSDOp>& ops)
             oi.watchers.erase(oi_iter);
 	    t->nop();  // update oi on disk
 	    ctx->watch_disconnects.push_back(
-	      OpContext::watch_disconnect_t(cookie, entity, false));
+	      watch_disconnect_t(cookie, entity, false));
 	  } else {
 	    dout(10) << " can't remove: no watch by " << entity << dendl;
 	  }
@@ -5850,7 +5953,7 @@ inline int ReplicatedPG::_delete_oid(OpContext *ctx, bool no_whiteout)
   ObjectState& obs = ctx->new_obs;
   object_info_t& oi = obs.oi;
   const hobject_t& soid = oi.soid;
-  PGBackend::PGTransaction* t = ctx->op_t;
+  PGBackend::PGTransaction* t = ctx->op_t.get();
 
   if (!obs.exists || (obs.oi.is_whiteout() && !no_whiteout))
     return -ENOENT;
@@ -5891,7 +5994,7 @@ inline int ReplicatedPG::_delete_oid(OpContext *ctx, bool no_whiteout)
        ++p) {
     dout(20) << __func__ << " will disconnect watcher " << p->first << dendl;
     ctx->watch_disconnects.push_back(
-      OpContext::watch_disconnect_t(p->first.first, p->first.second, true));
+      watch_disconnect_t(p->first.first, p->first.second, true));
   }
   oi.watchers.clear();
 
@@ -5924,7 +6027,7 @@ int ReplicatedPG::_rollback_to(OpContext *ctx, ceph_osd_op& op)
   ObjectState& obs = ctx->new_obs;
   object_info_t& oi = obs.oi;
   const hobject_t& soid = oi.soid;
-  PGBackend::PGTransaction* t = ctx->op_t;
+  PGBackend::PGTransaction* t = ctx->op_t.get();
   snapid_t snapid = (uint64_t)op.snap.snapid;
   hobject_t missing_oid;
 
@@ -6157,7 +6260,10 @@ void ReplicatedPG::make_writeable(OpContext *ctx)
       if (pool.info.require_rollback())
 	ctx->clone_obc->attr_cache = ctx->obc->attr_cache;
       snap_oi = &ctx->clone_obc->obs.oi;
-      bool got = ctx->clone_obc->get_write_greedy(ctx->op);
+      bool got = ctx->lock_manager.get_write_greedy(
+	coid,
+	ctx->clone_obc,
+	ctx->op);
       assert(got);
       dout(20) << " got greedy write on clone_obc " << *ctx->clone_obc << dendl;
     } else {
@@ -6171,9 +6277,8 @@ void ReplicatedPG::make_writeable(OpContext *ctx)
     // prepend transaction to op_t
     PGBackend::PGTransaction *t = pgbackend->get_transaction();
     _make_clone(ctx, t, ctx->clone_obc, soid, coid, snap_oi);
-    t->append(ctx->op_t);
-    delete ctx->op_t;
-    ctx->op_t = t;
+    t->append(ctx->op_t.get());
+    ctx->op_t.reset(t);
     
     ctx->delta_stats.num_objects++;
     if (snap_oi->is_dirty()) {
@@ -6257,30 +6362,37 @@ void ReplicatedPG::add_interval_usage(interval_set<uint64_t>& s, object_stat_sum
   }
 }
 
-void ReplicatedPG::do_osd_op_effects(OpContext *ctx, const ConnectionRef& conn)
+void ReplicatedPG::complete_disconnect_watches(
+  ObjectContextRef obc,
+  const list<watch_disconnect_t> &to_disconnect)
 {
-  entity_name_t entity = ctx->reqid.name;
-  dout(15) << "do_osd_op_effects " << entity << " con " << conn.get() << dendl;
-
-  // disconnects first
-  for (list<OpContext::watch_disconnect_t>::iterator i =
-	 ctx->watch_disconnects.begin();
-       i != ctx->watch_disconnects.end();
+  for (list<watch_disconnect_t>::const_iterator i =
+	 to_disconnect.begin();
+       i != to_disconnect.end();
        ++i) {
     pair<uint64_t, entity_name_t> watcher(i->cookie, i->name);
-    if (ctx->obc->watchers.count(watcher)) {
-      WatchRef watch = ctx->obc->watchers[watcher];
+    if (obc->watchers.count(watcher)) {
+      WatchRef watch = obc->watchers[watcher];
       dout(10) << "do_osd_op_effects disconnect watcher " << watcher << dendl;
-      ctx->obc->watchers.erase(watcher);
+      obc->watchers.erase(watcher);
       watch->remove(i->send_disconnect);
     } else {
       dout(10) << "do_osd_op_effects disconnect failed to find watcher "
 	       << watcher << dendl;
     }
   }
+}
+
+void ReplicatedPG::do_osd_op_effects(OpContext *ctx, const ConnectionRef& conn)
+{
+  entity_name_t entity = ctx->reqid.name;
+  dout(15) << "do_osd_op_effects " << entity << " con " << conn.get() << dendl;
+
+  // disconnects first
+  complete_disconnect_watches(ctx->obc, ctx->watch_disconnects);
+
+  assert(conn);
 
-  if (!conn)
-    return;
   boost::intrusive_ptr<OSD::Session> session((OSD::Session *)conn->get_priv());
   if (!session.get())
     return;
@@ -6360,7 +6472,7 @@ hobject_t ReplicatedPG::generate_temp_object()
 {
   ostringstream ss;
   ss << "temp_" << info.pgid << "_" << get_role() << "_" << osd->monc->get_global_id() << "_" << (++temp_seq);
-  hobject_t hoid = info.pgid.make_temp_object(ss.str());
+  hobject_t hoid = info.pgid.make_temp_hobject(ss.str());
   dout(20) << __func__ << " " << hoid << dendl;
   return hoid;
 }
@@ -6373,7 +6485,7 @@ hobject_t ReplicatedPG::get_temp_recovery_object(eversion_t version, snapid_t sn
      << "_" << info.history.same_interval_since
      << "_" << snap;
   // pgid + version + interval + snapid is unique, and short
-  hobject_t hoid = info.pgid.make_temp_object(ss.str());
+  hobject_t hoid = info.pgid.make_temp_hobject(ss.str());
   dout(20) << __func__ << " " << hoid << dendl;
   return hoid;
 }
@@ -6490,15 +6602,21 @@ void ReplicatedPG::finish_ctx(OpContext *ctx, int log_op_type, bool maintain_ssc
       if (!ctx->snapset_obc)
 	ctx->snapset_obc = get_object_context(snapoid, true);
       bool got = false;
-      if (ctx->lock_to_release == OpContext::W_LOCK) {
-	got = ctx->snapset_obc->get_write_greedy(ctx->op);
+      if (ctx->lock_type == ObjectContext::RWState::RWWRITE) {
+	got = ctx->lock_manager.get_write_greedy(
+	  snapoid,
+	  ctx->snapset_obc,
+	  ctx->op);
       } else {
-	assert(ctx->lock_to_release == OpContext::E_LOCK);
-	got = ctx->snapset_obc->get_excl(ctx->op);
+	assert(ctx->lock_type == ObjectContext::RWState::RWEXCL);
+	got = ctx->lock_manager.get_lock_type(
+	  ObjectContext::RWState::RWEXCL,
+	  snapoid,
+	  ctx->snapset_obc,
+	  ctx->op);
       }
       assert(got);
       dout(20) << " got greedy write on snapset_obc " << *ctx->snapset_obc << dendl;
-      ctx->release_snapset_obc = true;
       if (pool.info.require_rollback() && !ctx->snapset_obc->obs.exists) {
 	ctx->log.back().mod_desc.create();
       } else if (!pool.info.require_rollback()) {
@@ -6516,7 +6634,7 @@ void ReplicatedPG::finish_ctx(OpContext *ctx, int log_op_type, bool maintain_ssc
       ctx->op_t->touch(snapoid);
       attrs[OI_ATTR].claim(bv);
       attrs[SS_ATTR].claim(bss);
-      setattrs_maybe_cache(ctx->snapset_obc, ctx, ctx->op_t, attrs);
+      setattrs_maybe_cache(ctx->snapset_obc, ctx, ctx->op_t.get(), attrs);
       if (pool.info.require_rollback()) {
 	map<string, boost::optional<bufferlist> > to_set;
 	to_set[SS_ATTR];
@@ -6568,7 +6686,7 @@ void ReplicatedPG::finish_ctx(OpContext *ctx, int log_op_type, bool maintain_ssc
     } else {
       dout(10) << " no snapset (this is a clone)" << dendl;
     }
-    setattrs_maybe_cache(ctx->obc, ctx, ctx->op_t, attrs);
+    setattrs_maybe_cache(ctx->obc, ctx, ctx->op_t.get(), attrs);
 
     if (pool.info.require_rollback()) {
       set<string> changing;
@@ -6686,7 +6804,7 @@ void ReplicatedPG::complete_read_ctx(int result, OpContext *ctx)
   reply->set_result(result);
   reply->add_flags(CEPH_OSD_FLAG_ACK | CEPH_OSD_FLAG_ONDISK);
   osd->send_message_osd_client(reply, m->get_connection());
-  close_op_ctx(ctx, 0);
+  close_op_ctx(ctx);
 }
 
 // ========================================================================
@@ -6954,7 +7072,7 @@ void ReplicatedPG::start_copy(CopyCallback *cb, ObjectContextRef obc,
     cancel_copy(cop, false);
   }
 
-  CopyOpRef cop(new CopyOp(cb, obc, src, oloc, version, flags,
+  CopyOpRef cop(std::make_shared<CopyOp>(cb, obc, src, oloc, version, flags,
 			   mirror_snapset, src_obj_fadvise_flags,
 			   dest_obj_fadvise_flags));
   copy_ops[dest] = cop;
@@ -7100,12 +7218,12 @@ void ReplicatedPG::process_copy_chunk(hobject_t oid, ceph_tid_t tid, int r)
       dout(20) << __func__ << " using temp " << cop->results.temp_oid << dendl;
     }
     ObjectContextRef tempobc = get_object_context(cop->results.temp_oid, true);
-    RepGather *repop = simple_repop_create(tempobc);
+    OpContextUPtr ctx = simple_opc_create(tempobc);
     if (cop->temp_cursor.is_initial()) {
-      repop->ctx->new_temp_oid = cop->results.temp_oid;
+      ctx->new_temp_oid = cop->results.temp_oid;
     }
-    _write_copy_chunk(cop, repop->ctx->op_t);
-    simple_repop_submit(repop);
+    _write_copy_chunk(cop, ctx->op_t.get());
+    simple_opc_submit(std::move(ctx));
     dout(10) << __func__ << " fetching more" << dendl;
     _copy_some(cobc, cop);
     return;
@@ -7408,9 +7526,9 @@ void ReplicatedPG::finish_promote(int r, CopyResults *results,
     dout(10) << __func__ << " abort; will clean up partial work" << dendl;
     ObjectContextRef tempobc = get_object_context(results->temp_oid, false);
     assert(tempobc);
-    RepGather *repop = simple_repop_create(tempobc);
-    repop->ctx->op_t->remove(results->temp_oid);
-    simple_repop_submit(repop);
+    OpContextUPtr ctx = simple_opc_create(tempobc);
+    ctx->op_t->remove(results->temp_oid);
+    simple_opc_submit(std::move(ctx));
     results->started_temp_obj = false;
   }
 
@@ -7422,8 +7540,8 @@ void ReplicatedPG::finish_promote(int r, CopyResults *results,
     hobject_t head(soid.get_head());
     ObjectContextRef obc = get_object_context(head, false);
     assert(obc);
-    RepGather *repop = simple_repop_create(obc);
-    OpContext *tctx = repop->ctx;
+
+    OpContextUPtr tctx = simple_opc_create(obc);
     tctx->at_version = get_next_version();
     filter_snapc(tctx->new_snapset.snaps);
     vector<snapid_t> new_clones;
@@ -7438,15 +7556,16 @@ void ReplicatedPG::finish_promote(int r, CopyResults *results,
     tctx->new_snapset.clone_size.erase(soid.snap);
 
     // take RWWRITE lock for duration of our local write.  ignore starvation.
-    if (!obc->rwstate.take_write_lock()) {
+    if (!tctx->lock_manager.take_write_lock(
+	  head,
+	  obc)) {
       assert(0 == "problem!");
     }
-    tctx->lock_to_release = OpContext::W_LOCK;
     dout(20) << __func__ << " took lock on obc, " << obc->rwstate << dendl;
 
-    finish_ctx(tctx, pg_log_entry_t::PROMOTE);
+    finish_ctx(tctx.get(), pg_log_entry_t::PROMOTE);
 
-    simple_repop_submit(repop);
+    simple_opc_submit(std::move(tctx));
     return;
   }
 
@@ -7474,8 +7593,9 @@ void ReplicatedPG::finish_promote(int r, CopyResults *results,
     return;
   }
 
-  RepGather *repop = simple_repop_create(obc);
-  OpContext *tctx = repop->ctx;
+  osd->promote_finish(results->object_size);
+
+  OpContextUPtr tctx =  simple_opc_create(obc);
   tctx->at_version = get_next_version();
 
   ++tctx->delta_stats.num_objects;
@@ -7537,15 +7657,16 @@ void ReplicatedPG::finish_promote(int r, CopyResults *results,
   dout(20) << __func__ << " new_snapset " << tctx->new_snapset << dendl;
 
   // take RWWRITE lock for duration of our local write.  ignore starvation.
-  if (!obc->rwstate.take_write_lock()) {
+  if (!tctx->lock_manager.take_write_lock(
+	obc->obs.oi.soid,
+	obc)) {
     assert(0 == "problem!");
   }
-  tctx->lock_to_release = OpContext::W_LOCK;
   dout(20) << __func__ << " took lock on obc, " << obc->rwstate << dendl;
 
-  finish_ctx(tctx, pg_log_entry_t::PROMOTE);
+  finish_ctx(tctx.get(), pg_log_entry_t::PROMOTE);
 
-  simple_repop_submit(repop);
+  simple_opc_submit(std::move(tctx));
 
   osd->logger->inc(l_osd_tier_promote);
 
@@ -7649,7 +7770,7 @@ struct C_Flush : public Context {
 int ReplicatedPG::start_flush(
   OpRequestRef op, ObjectContextRef obc,
   bool blocking, hobject_t *pmissing,
-  Context *on_flush)
+  boost::optional<std::function<void()>> &&on_flush)
 {
   const object_info_t& oi = obc->obs.oi;
   const hobject_t& soid = oi.soid;
@@ -7807,11 +7928,11 @@ int ReplicatedPG::start_flush(
       NULL /* no callback, we'll rely on the ordering w.r.t the next op */);
   }
 
-  FlushOpRef fop(new FlushOp);
+  FlushOpRef fop(std::make_shared<FlushOp>());
   fop->obc = obc;
   fop->flushed_version = oi.user_version;
   fop->blocking = blocking;
-  fop->on_flush = on_flush;
+  fop->on_flush = std::move(on_flush);
   fop->op = op;
 
   ObjectOperation o;
@@ -7870,14 +7991,18 @@ void ReplicatedPG::finish_flush(hobject_t oid, ceph_tid_t tid, int r)
   if (r < 0 && !(r == -ENOENT && fop->removal)) {
     if (fop->op)
       osd->reply_op_error(fop->op, -EBUSY);
+    if (fop->blocking) {
+      obc->stop_block();
+      kick_object_context_blocked(obc);
+    }
+
     if (!fop->dup_ops.empty()) {
       dout(20) << __func__ << " requeueing dups" << dendl;
       requeue_ops(fop->dup_ops);
     }
     if (fop->on_flush) {
-      Context *on_flush = fop->on_flush;
-      fop->on_flush = NULL;
-      on_flush->complete(-EBUSY);
+      (*(fop->on_flush))();
+      fop->on_flush = boost::none;
     }
     flush_ops.erase(oid);
     return;
@@ -7913,9 +8038,8 @@ int ReplicatedPG::try_flush_mark_clean(FlushOpRef fop)
       requeue_ops(fop->dup_ops);
     }
     if (fop->on_flush) {
-      Context *on_flush = fop->on_flush;
-      fop->on_flush = NULL;
-      on_flush->complete(-EBUSY);
+      (*(fop->on_flush))();
+      fop->on_flush = boost::none;
     }
     flush_ops.erase(oid);
     if (fop->blocking)
@@ -7944,46 +8068,51 @@ int ReplicatedPG::try_flush_mark_clean(FlushOpRef fop)
       agent_maybe_evict(obc, true)) {
     osd->logger->inc(l_osd_tier_clean);
     if (fop->on_flush) {
-      Context *on_flush = fop->on_flush;
-      fop->on_flush = NULL;
-      on_flush->complete(0);
+      (*(fop->on_flush))();
+      fop->on_flush = boost::none;
     }
     flush_ops.erase(oid);
     return 0;
   }
 
+  dout(10) << __func__ << " clearing DIRTY flag for " << oid << dendl;
+  OpContextUPtr ctx = simple_opc_create(fop->obc);
+
   // successfully flushed; can we clear the dirty bit?
   // try to take the lock manually, since we don't
   // have a ctx yet.
-  if (obc->get_write(fop->op)) {
+  if (ctx->lock_manager.get_lock_type(
+	ObjectContext::RWState::RWWRITE,
+	oid,
+	obc,
+	fop->op)) {
     dout(20) << __func__ << " took write lock" << dendl;
   } else if (fop->op) {
     dout(10) << __func__ << " waiting on write lock" << dendl;
+    close_op_ctx(ctx.release());
     requeue_op(fop->op);
     requeue_ops(fop->dup_ops);
     return -EAGAIN;    // will retry
   } else {
     dout(10) << __func__ << " failed write lock, no op; failing" << dendl;
+    close_op_ctx(ctx.release());
     osd->logger->inc(l_osd_tier_try_flush_fail);
     cancel_flush(fop, false);
     return -ECANCELED;
   }
 
-  dout(10) << __func__ << " clearing DIRTY flag for " << oid << dendl;
-  RepGather *repop = simple_repop_create(fop->obc);
-  OpContext *ctx = repop->ctx;
-
-  ctx->on_finish = fop->on_flush;
-  fop->on_flush = NULL;
+  if (fop->on_flush) {
+    ctx->register_on_finish(*(fop->on_flush));
+    fop->on_flush = boost::none;
+  }
 
-  ctx->lock_to_release = OpContext::W_LOCK;  // we took it above
   ctx->at_version = get_next_version();
 
   ctx->new_obs = obc->obs;
   ctx->new_obs.oi.clear_flag(object_info_t::FLAG_DIRTY);
   --ctx->delta_stats.num_objects_dirty;
 
-  finish_ctx(ctx, pg_log_entry_t::CLEAN);
+  finish_ctx(ctx.get(), pg_log_entry_t::CLEAN);
 
   osd->logger->inc(l_osd_tier_clean);
 
@@ -7996,7 +8125,7 @@ int ReplicatedPG::try_flush_mark_clean(FlushOpRef fop)
     requeue_ops(ls);
   }
 
-  simple_repop_submit(repop);
+  simple_opc_submit(std::move(ctx));
 
   flush_ops.erase(oid);
 
@@ -8026,9 +8155,8 @@ void ReplicatedPG::cancel_flush(FlushOpRef fop, bool requeue)
     requeue_ops(fop->dup_ops);
   }
   if (fop->on_flush) {
-    Context *on_flush = fop->on_flush;
-    fop->on_flush = NULL;
-    on_flush->complete(-ECANCELED);
+    (*(fop->on_flush))();
+    fop->on_flush = boost::none;
   }
   flush_ops.erase(fop->obc->obs.oi.soid);
 }
@@ -8074,10 +8202,6 @@ void ReplicatedPG::repop_all_applied(RepGather *repop)
   repop->all_applied = true;
   if (!repop->rep_aborted) {
     eval_repop(repop);
-    if (repop->on_applied) {
-     repop->on_applied->complete(0);
-     repop->on_applied = NULL;
-    }
   }
 }
 
@@ -8140,8 +8264,8 @@ void ReplicatedPG::op_applied(const eversion_t &applied_version)
 void ReplicatedPG::eval_repop(RepGather *repop)
 {
   MOSDOp *m = NULL;
-  if (repop->ctx->op)
-    m = static_cast<MOSDOp *>(repop->ctx->op->get_req());
+  if (repop->op)
+    m = static_cast<MOSDOp *>(repop->op->get_req());
 
   if (m)
     dout(10) << "eval_repop " << *repop
@@ -8158,12 +8282,12 @@ void ReplicatedPG::eval_repop(RepGather *repop)
 
   // ondisk?
   if (repop->all_committed) {
-    if (repop->ctx->op && !repop->log_op_stat) {
-      log_op_stats(repop->ctx);
-      repop->log_op_stat = true;
+    dout(10) << " commit: " << *repop << dendl;
+    for (auto p = repop->on_committed.begin();
+	 p != repop->on_committed.end();
+	 repop->on_committed.erase(p++)) {
+      (*p)();
     }
-    publish_stats_to_osd();
-
     // send dup commits, in order
     if (waiting_for_ondisk.count(repop->v)) {
       assert(waiting_for_ondisk.begin()->first == repop->v);
@@ -8171,7 +8295,7 @@ void ReplicatedPG::eval_repop(RepGather *repop)
 	     waiting_for_ondisk[repop->v].begin();
 	   i != waiting_for_ondisk[repop->v].end();
 	   ++i) {
-	osd->reply_op_error(i->first, 0, repop->ctx->at_version,
+	osd->reply_op_error(i->first, 0, repop->v,
 			    i->second);
       }
       waiting_for_ondisk.erase(repop->v);
@@ -8183,26 +8307,16 @@ void ReplicatedPG::eval_repop(RepGather *repop)
       waiting_for_ack.erase(repop->v);
     }
 
-    if (m && m->wants_ondisk() && !repop->sent_disk) {
-      // send commit.
-      MOSDOpReply *reply = repop->ctx->reply;
-      if (reply)
-	repop->ctx->reply = NULL;
-      else {
-	reply = new MOSDOpReply(m, 0, get_osdmap()->get_epoch(), 0, true);
-	reply->set_reply_versions(repop->ctx->at_version,
-				  repop->ctx->user_at_version);
-      }
-      reply->add_flags(CEPH_OSD_FLAG_ACK | CEPH_OSD_FLAG_ONDISK);
-      dout(10) << " sending commit on " << *repop << " " << reply << dendl;
-      osd->send_message_osd_client(reply, m->get_connection());
-      repop->sent_disk = true;
-      repop->ctx->op->mark_commit_sent();
-    }
   }
 
   // applied?
   if (repop->all_applied) {
+    dout(10) << " applied: " << *repop << " " << dendl;
+    for (auto p = repop->on_applied.begin();
+	 p != repop->on_applied.end();
+	 repop->on_applied.erase(p++)) {
+      (*p)();
+    }
 
     // send dup acks, in order
     if (waiting_for_ack.count(repop->v)) {
@@ -8213,52 +8327,26 @@ void ReplicatedPG::eval_repop(RepGather *repop)
 	   ++i) {
 	MOSDOp *m = static_cast<MOSDOp*>(i->first->get_req());
 	MOSDOpReply *reply = new MOSDOpReply(m, 0, get_osdmap()->get_epoch(), 0, true);
-	reply->set_reply_versions(repop->ctx->at_version,
+	reply->set_reply_versions(repop->v,
 				  i->second);
 	reply->add_flags(CEPH_OSD_FLAG_ACK);
 	osd->send_message_osd_client(reply, m->get_connection());
       }
       waiting_for_ack.erase(repop->v);
     }
-
-    if (m && m->wants_ack() && !repop->sent_ack && !repop->sent_disk) {
-      // send ack
-      MOSDOpReply *reply = repop->ctx->reply;
-      if (reply)
-	repop->ctx->reply = NULL;
-      else {
-	reply = new MOSDOpReply(m, 0, get_osdmap()->get_epoch(), 0, true);
-	reply->set_reply_versions(repop->ctx->at_version,
-				  repop->ctx->user_at_version);
-      }
-      reply->add_flags(CEPH_OSD_FLAG_ACK);
-      dout(10) << " sending ack on " << *repop << " " << reply << dendl;
-      osd->send_message_osd_client(reply, m->get_connection());
-      repop->sent_ack = true;
-    }
-
-    // note the write is now readable (for rlatency calc).  note
-    // that this will only be defined if the write is readable
-    // _prior_ to being committed; it will not get set with
-    // writeahead journaling, for instance.
-    if (repop->ctx->readable_stamp == utime_t())
-      repop->ctx->readable_stamp = ceph_clock_now(cct);
   }
 
   // done.
   if (repop->all_applied && repop->all_committed) {
     repop->rep_done = true;
 
-    do_osd_op_effects(
-      repop->ctx,
-      repop->ctx->op ? repop->ctx->op->get_req()->get_connection() :
-      ConnectionRef());
-
+    publish_stats_to_osd();
     calc_min_last_complete_ondisk();
 
-    // kick snap_trimmer if necessary
-    if (repop->queue_snap_trimmer) {
-      queue_snap_trim();
+    for (auto p = repop->on_success.begin();
+	 p != repop->on_success.end();
+	 repop->on_success.erase(p++)) {
+      (*p)();
     }
 
     dout(10) << " removing " << *repop << dendl;
@@ -8274,9 +8362,8 @@ void ReplicatedPG::eval_repop(RepGather *repop)
   }
 }
 
-void ReplicatedPG::issue_repop(RepGather *repop)
+void ReplicatedPG::issue_repop(RepGather *repop, OpContext *ctx)
 {
-  OpContext *ctx = repop->ctx;
   const hobject_t& soid = ctx->obs->oi.soid;
   if (ctx->op &&
     ((static_cast<MOSDOp *>(
@@ -8302,22 +8389,22 @@ void ReplicatedPG::issue_repop(RepGather *repop)
     }
   }
 
-  repop->obc->ondisk_write_lock();
-  if (repop->ctx->clone_obc)
-    repop->ctx->clone_obc->ondisk_write_lock();
+  ctx->obc->ondisk_write_lock();
+  if (ctx->clone_obc)
+    ctx->clone_obc->ondisk_write_lock();
 
   bool unlock_snapset_obc = false;
-  if (repop->ctx->snapset_obc && repop->ctx->snapset_obc->obs.oi.soid !=
-      repop->obc->obs.oi.soid) {
-    repop->ctx->snapset_obc->ondisk_write_lock();
+  if (ctx->snapset_obc && ctx->snapset_obc->obs.oi.soid !=
+      ctx->obc->obs.oi.soid) {
+    ctx->snapset_obc->ondisk_write_lock();
     unlock_snapset_obc = true;
   }
 
-  repop->ctx->apply_pending_attrs();
+  ctx->apply_pending_attrs();
 
   if (pool.info.require_rollback()) {
-    for (vector<pg_log_entry_t>::iterator i = repop->ctx->log.begin();
-	 i != repop->ctx->log.end();
+    for (vector<pg_log_entry_t>::iterator i = ctx->log.begin();
+	 i != ctx->log.end();
 	 ++i) {
       assert(i->mod_desc.can_rollback());
       assert(!i->mod_desc.empty());
@@ -8327,35 +8414,55 @@ void ReplicatedPG::issue_repop(RepGather *repop)
   Context *on_all_commit = new C_OSD_RepopCommit(this, repop);
   Context *on_all_applied = new C_OSD_RepopApplied(this, repop);
   Context *onapplied_sync = new C_OSD_OndiskWriteUnlock(
-    repop->obc,
-    repop->ctx->clone_obc,
-    unlock_snapset_obc ? repop->ctx->snapset_obc : ObjectContextRef());
+    ctx->obc,
+    ctx->clone_obc,
+    unlock_snapset_obc ? ctx->snapset_obc : ObjectContextRef());
   pgbackend->submit_transaction(
     soid,
-    repop->ctx->at_version,
-    repop->ctx->op_t,
+    ctx->at_version,
+    std::move(ctx->op_t),
     pg_trim_to,
     min_last_complete_ondisk,
-    repop->ctx->log,
-    repop->ctx->updated_hset_history,
+    ctx->log,
+    ctx->updated_hset_history,
     onapplied_sync,
     on_all_applied,
     on_all_commit,
     repop->rep_tid,
-    repop->ctx->reqid,
-    repop->ctx->op);
-  repop->ctx->op_t = NULL;
+    ctx->reqid,
+    ctx->op);
 }
 
-ReplicatedPG::RepGather *ReplicatedPG::new_repop(OpContext *ctx, ObjectContextRef obc,
-						 ceph_tid_t rep_tid)
+ReplicatedPG::RepGather *ReplicatedPG::new_repop(
+  OpContext *ctx, ObjectContextRef obc,
+  ceph_tid_t rep_tid)
 {
   if (ctx->op)
     dout(10) << "new_repop rep_tid " << rep_tid << " on " << *ctx->op->get_req() << dendl;
   else
     dout(10) << "new_repop rep_tid " << rep_tid << " (no op)" << dendl;
 
-  RepGather *repop = new RepGather(ctx, obc, rep_tid, info.last_complete);
+  RepGather *repop = new RepGather(ctx, rep_tid, info.last_complete);
+
+  repop->start = ceph_clock_now(cct);
+
+  repop_queue.push_back(&repop->queue_item);
+  repop->get();
+
+  osd->logger->inc(l_osd_op_wip);
+
+  return repop;
+}
+
+ReplicatedPG::RepGather *ReplicatedPG::new_repop(
+  ObcLockManager &&manager,
+  boost::optional<std::function<void(void)> > &&on_complete)
+{
+  RepGather *repop = new RepGather(
+    std::move(manager),
+    std::move(on_complete),
+    osd->get_tid(),
+    info.last_complete);
 
   repop->start = ceph_clock_now(cct);
 
@@ -8370,40 +8477,158 @@ ReplicatedPG::RepGather *ReplicatedPG::new_repop(OpContext *ctx, ObjectContextRe
 void ReplicatedPG::remove_repop(RepGather *repop)
 {
   dout(20) << __func__ << " " << *repop << dendl;
-  if (repop->ctx->obc)
-    dout(20) << " obc " << *repop->ctx->obc << dendl;
-  if (repop->ctx->clone_obc)
-    dout(20) << " clone_obc " << *repop->ctx->clone_obc << dendl;
-  if (repop->ctx->snapset_obc)
-    dout(20) << " snapset_obc " << *repop->ctx->snapset_obc << dendl;
-  release_op_ctx_locks(repop->ctx);
-  repop->ctx->finish(0);  // FIXME: return value here is sloppy
+
+  for (auto p = repop->on_finish.begin();
+       p != repop->on_finish.end();
+       repop->on_finish.erase(p++)) {
+    (*p)();
+  }
+
+  release_object_locks(
+    repop->lock_manager);
   repop->put();
 
   osd->logger->dec(l_osd_op_wip);
 }
 
-ReplicatedPG::RepGather *ReplicatedPG::simple_repop_create(ObjectContextRef obc)
+ReplicatedPG::OpContextUPtr ReplicatedPG::simple_opc_create(ObjectContextRef obc)
 {
   dout(20) << __func__ << " " << obc->obs.oi.soid << dendl;
   vector<OSDOp> ops;
   ceph_tid_t rep_tid = osd->get_tid();
   osd_reqid_t reqid(osd->get_cluster_msgr_name(), 0, rep_tid);
-  OpContext *ctx = new OpContext(OpRequestRef(), reqid, ops, obc, this);
-  ctx->op_t = pgbackend->get_transaction();
+  OpContextUPtr ctx(new OpContext(OpRequestRef(), reqid, ops, obc, this));
+  ctx->op_t.reset(pgbackend->get_transaction());
   ctx->mtime = ceph_clock_now(g_ceph_context);
-  RepGather *repop = new_repop(ctx, obc, rep_tid);
-  return repop;
+  return ctx;
 }
 
-void ReplicatedPG::simple_repop_submit(RepGather *repop)
+void ReplicatedPG::simple_opc_submit(OpContextUPtr ctx)
 {
+  RepGather *repop = new_repop(ctx.get(), ctx->obc, ctx->reqid.tid);
   dout(20) << __func__ << " " << repop << dendl;
-  issue_repop(repop);
+  issue_repop(repop, ctx.get());
   eval_repop(repop);
   repop->put();
 }
 
+
+void ReplicatedPG::submit_log_entries(
+  const list<pg_log_entry_t> &entries,
+  ObcLockManager &&manager,
+  boost::optional<std::function<void(void)> > &&on_complete)
+{
+  dout(10) << __func__ << entries << dendl;
+  assert(is_primary());
+
+  ObjectStore::Transaction t;
+
+  eversion_t old_last_update = info.last_update;
+  merge_new_log_entries(entries, t);
+
+  boost::intrusive_ptr<RepGather> repop;
+  set<pg_shard_t> waiting_on;
+  if (get_osdmap()->test_flag(CEPH_OSDMAP_REQUIRE_JEWEL)) {
+    repop = new_repop(
+      std::move(manager),
+      std::move(on_complete));
+  }
+  for (set<pg_shard_t>::const_iterator i = actingbackfill.begin();
+       i != actingbackfill.end();
+       ++i) {
+    pg_shard_t peer(*i);
+    if (peer == pg_whoami) continue;
+    assert(peer_missing.count(peer));
+    assert(peer_info.count(peer));
+    if (get_osdmap()->test_flag(CEPH_OSDMAP_REQUIRE_JEWEL)) {
+      assert(repop);
+      MOSDPGUpdateLogMissing *m = new MOSDPGUpdateLogMissing(
+	entries,
+	spg_t(info.pgid.pgid, i->shard),
+	pg_whoami.shard,
+	get_osdmap()->get_epoch(),
+	repop->rep_tid);
+      osd->send_message_osd_cluster(
+	peer.osd, m, get_osdmap()->get_epoch());
+      waiting_on.insert(peer);
+    } else {
+      MOSDPGLog *m = new MOSDPGLog(
+	peer.shard, pg_whoami.shard,
+	info.last_update.epoch,
+	info);
+      m->log.log = entries;
+      m->log.tail = old_last_update;
+      m->log.head = info.last_update;
+      osd->send_message_osd_cluster(
+	peer.osd, m, get_osdmap()->get_epoch());
+    }
+  }
+  if (get_osdmap()->test_flag(CEPH_OSDMAP_REQUIRE_JEWEL)) {
+    ceph_tid_t rep_tid = repop->rep_tid;
+    waiting_on.insert(pg_whoami);
+    log_entry_update_waiting_on.insert(
+      make_pair(
+	rep_tid,
+	LogUpdateCtx{std::move(repop), std::move(waiting_on)}
+	));
+    struct OnComplete : public Context {
+      ReplicatedPGRef pg;
+      ceph_tid_t rep_tid;
+      epoch_t epoch;
+      OnComplete(
+	ReplicatedPGRef pg,
+	ceph_tid_t rep_tid,
+	epoch_t epoch)
+	: pg(pg), rep_tid(rep_tid), epoch(epoch) {}
+      void finish(int) override {
+	pg->lock();
+	if (!pg->pg_has_reset_since(epoch)) {
+	  auto it = pg->log_entry_update_waiting_on.find(rep_tid);
+	  assert(it != pg->log_entry_update_waiting_on.end());
+	  auto it2 = it->second.waiting_on.find(pg->pg_whoami);
+	  assert(it2 != it->second.waiting_on.end());
+	  it->second.waiting_on.erase(it2);
+	  if (it->second.waiting_on.empty()) {
+	    pg->repop_all_applied(it->second.repop.get());
+	    pg->repop_all_committed(it->second.repop.get());
+	    pg->log_entry_update_waiting_on.erase(it);
+	  }
+	}
+	pg->unlock();
+      }
+    };
+    t.register_on_complete(
+      new OnComplete{this, rep_tid, get_osdmap()->get_epoch()});
+  } else {
+    if (on_complete) {
+      struct OnComplete : public Context {
+	ReplicatedPGRef pg;
+	std::function<void(void)> on_complete;
+	epoch_t epoch;
+	OnComplete(
+	  ReplicatedPGRef pg,
+	  std::function<void(void)> &&on_complete,
+	  epoch_t epoch)
+	  : pg(pg),
+	    on_complete(std::move(on_complete)),
+	    epoch(epoch) {}
+	void finish(int) override {
+	  pg->lock();
+	  if (!pg->pg_has_reset_since(epoch))
+	    on_complete();
+	  pg->unlock();
+	}
+      };
+      t.register_on_complete(
+	new OnComplete{
+	  this, std::move(*on_complete), get_osdmap()->get_epoch()
+	  });
+    }
+  }
+  int r = osd->store->queue_transaction(osr.get(), std::move(t), NULL);
+  assert(r == 0);
+}
+
 // -------------------------------------------------------
 
 void ReplicatedPG::get_watchers(list<obj_watch_item_t> &pg_watchers)
@@ -8525,30 +8750,34 @@ void ReplicatedPG::handle_watch_timeout(WatchRef watch)
     return;
   }
 
-  RepGather *repop = simple_repop_create(obc);
-  OpContext *ctx = repop->ctx;
+  OpContextUPtr ctx = simple_opc_create(obc);
   ctx->at_version = get_next_version();
 
   object_info_t& oi = ctx->new_obs.oi;
   oi.watchers.erase(make_pair(watch->get_cookie(),
 			      watch->get_entity()));
 
-  ctx->watch_disconnects.push_back(
-    OpContext::watch_disconnect_t(watch->get_cookie(), watch->get_entity(), true));
+  list<watch_disconnect_t> watch_disconnects = {
+    watch_disconnect_t(watch->get_cookie(), watch->get_entity(), true)
+  };
+  ctx->register_on_success(
+    [this, obc, watch_disconnects]() {
+      complete_disconnect_watches(obc, watch_disconnects);
+    });
 
 
-  PGBackend::PGTransaction *t = ctx->op_t;
+  PGBackend::PGTransaction *t = ctx->op_t.get();
   ctx->log.push_back(pg_log_entry_t(pg_log_entry_t::MODIFY, obc->obs.oi.soid,
 				    ctx->at_version,
 				    oi.version,
 				    0,
 				    osd_reqid_t(), ctx->mtime));
 
-  oi.prior_version = repop->obc->obs.oi.version;
+  oi.prior_version = obc->obs.oi.version;
   oi.version = ctx->at_version;
   bufferlist bl;
   ::encode(oi, bl);
-  setattr_maybe_cache(obc, repop->ctx, t, OI_ATTR, bl);
+  setattr_maybe_cache(obc, ctx.get(), t, OI_ATTR, bl);
 
   if (pool.info.require_rollback()) {
     map<string, boost::optional<bufferlist> > to_set;
@@ -8558,13 +8787,12 @@ void ReplicatedPG::handle_watch_timeout(WatchRef watch)
     ctx->log.back().mod_desc.mark_unrollbackable();
   }
 
-  // no ctx->delta_stats
-
-  // obc ref swallowed by repop!
-  simple_repop_submit(repop);
 
   // apply new object state.
   ctx->obc->obs = ctx->new_obs;
+
+  // no ctx->delta_stats
+  simple_opc_submit(std::move(ctx));
 }
 
 ObjectContextRef ReplicatedPG::create_object_context(const object_info_t& oi,
@@ -9367,18 +9595,81 @@ ObjectContextRef ReplicatedPG::mark_object_lost(ObjectStore::Transaction *t,
   return obc;
 }
 
-struct C_PG_MarkUnfoundLost : public Context {
-  ReplicatedPGRef pg;
-  list<ObjectContextRef> obcs;
-  explicit C_PG_MarkUnfoundLost(ReplicatedPG *p) : pg(p) {}
-  void finish(int r) {
-    pg->_finish_mark_all_unfound_lost(obcs);
+void ReplicatedPG::do_update_log_missing(OpRequestRef &op)
+{
+  MOSDPGUpdateLogMissing *m = static_cast<MOSDPGUpdateLogMissing*>(
+    op->get_req());
+  assert(m->get_type() == MSG_OSD_PG_UPDATE_LOG_MISSING);
+  ObjectStore::Transaction t;
+  append_log_entries_update_missing(m->entries, t);
+  // TODO FIX
+
+  Context *c = new FunctionContext(
+      [=](int) {
+	MOSDPGUpdateLogMissing *msg =
+	  static_cast<MOSDPGUpdateLogMissing*>(
+	    op->get_req());
+	MOSDPGUpdateLogMissingReply *reply =
+	  new MOSDPGUpdateLogMissingReply(
+	    spg_t(info.pgid.pgid, primary_shard().shard),
+	    pg_whoami.shard,
+	    msg->get_epoch(),
+	    msg->get_tid());
+	reply->set_priority(CEPH_MSG_PRIO_HIGH);
+	msg->get_connection()->send_message(reply);
+      });
+
+  /* Hack to work around the fact that ReplicatedBackend sends
+   * ack+commit if commit happens first */
+  if (pool.info.ec_pool()) {
+    t.register_on_complete(c);
+  } else {
+    t.register_on_commit(c);
   }
-};
+  int tr = osd->store->queue_transaction(
+    osr.get(),
+    std::move(t),
+    nullptr);
+  assert(tr == 0);
+}
+
+void ReplicatedPG::do_update_log_missing_reply(OpRequestRef &op)
+{
+  MOSDPGUpdateLogMissingReply *m =
+    static_cast<MOSDPGUpdateLogMissingReply*>(
+    op->get_req());
+  dout(20) << __func__ << " got reply from "
+	   << m->get_from() << dendl;
+
+  auto it = log_entry_update_waiting_on.find(m->get_tid());
+  if (it != log_entry_update_waiting_on.end()) {
+    if (it->second.waiting_on.count(m->get_from())) {
+      it->second.waiting_on.erase(m->get_from());
+    } else {
+      osd->clog->error()
+	<< info.pgid << " got reply "
+	<< *m << " from shard we are not waiting for "
+	<< m->get_from();
+    }
+
+    if (it->second.waiting_on.empty()) {
+      repop_all_applied(it->second.repop.get());
+      repop_all_committed(it->second.repop.get());
+      log_entry_update_waiting_on.erase(it);
+    }
+  } else {
+    osd->clog->error()
+      << info.pgid << " got reply "
+      << *m << " on unknown tid " << m->get_tid();
+  }
+}
 
 /* Mark all unfound objects as lost.
  */
-void ReplicatedPG::mark_all_unfound_lost(int what)
+void ReplicatedPG::mark_all_unfound_lost(
+  int what,
+  ConnectionRef con,
+  ceph_tid_t tid)
 {
   dout(3) << __func__ << " " << pg_log_entry_t::get_op_name(what) << dendl;
 
@@ -9386,16 +9677,18 @@ void ReplicatedPG::mark_all_unfound_lost(int what)
   pg_log.get_log().print(*_dout);
   *_dout << dendl;
 
-  ObjectStore::Transaction t;
-  C_PG_MarkUnfoundLost *c = new C_PG_MarkUnfoundLost(this);
+  list<pg_log_entry_t> log_entries;
 
   utime_t mtime = ceph_clock_now(cct);
-  info.last_update.epoch = get_osdmap()->get_epoch();
-  const pg_missing_t &missing = pg_log.get_missing();
   map<hobject_t, pg_missing_t::item, hobject_t::ComparatorWithDefault>::const_iterator m =
     missing_loc.get_needs_recovery().begin();
   map<hobject_t, pg_missing_t::item, hobject_t::ComparatorWithDefault>::const_iterator mend =
     missing_loc.get_needs_recovery().end();
+
+  ObcLockManager manager;
+  eversion_t v = info.last_update;
+  v.epoch = get_osdmap()->get_epoch();
+  unsigned num_unfound = missing_loc.num_unfound();
   while (m != mend) {
     const hobject_t &oid(m->first);
     if (!missing_loc.is_unfound(oid)) {
@@ -9409,47 +9702,43 @@ void ReplicatedPG::mark_all_unfound_lost(int what)
 
     switch (what) {
     case pg_log_entry_t::LOST_MARK:
-      obc = mark_object_lost(&t, oid, m->second.need, mtime, pg_log_entry_t::LOST_MARK);
-      pg_log.missing_got(m++);
       assert(0 == "actually, not implemented yet!");
-      // we need to be careful about how this is handled on the replica!
       break;
 
     case pg_log_entry_t::LOST_REVERT:
       prev = pick_newest_available(oid);
       if (prev > eversion_t()) {
 	// log it
-	++info.last_update.version;
+	++v.version;
 	pg_log_entry_t e(
-	  pg_log_entry_t::LOST_REVERT, oid, info.last_update,
+	  pg_log_entry_t::LOST_REVERT, oid, v,
 	  m->second.need, 0, osd_reqid_t(), mtime);
 	e.reverting_to = prev;
-	pg_log.add(e);
+	e.mod_desc.mark_unrollbackable();
+	log_entries.push_back(e);
 	dout(10) << e << dendl;
 
 	// we are now missing the new version; recovery code will sort it out.
 	++m;
-	pg_log.revise_need(oid, info.last_update);
-	missing_loc.revise_need(oid, info.last_update);
 	break;
       }
-      /** fall-thru **/
 
     case pg_log_entry_t::LOST_DELETE:
       {
-	// log it
-      	++info.last_update.version;
-	pg_log_entry_t e(pg_log_entry_t::LOST_DELETE, oid, info.last_update, m->second.need,
+	++v.version;
+	pg_log_entry_t e(pg_log_entry_t::LOST_DELETE, oid, v, m->second.need,
 		     0, osd_reqid_t(), mtime);
-	pg_log.add(e);
+	if (get_osdmap()->test_flag(CEPH_OSDMAP_REQUIRE_JEWEL)) {
+	  if (pool.info.require_rollback()) {
+	    e.mod_desc.try_rmobject(v.version);
+	  } else {
+	    e.mod_desc.mark_unrollbackable();
+	  }
+	} // otherwise, just do what we used to do
 	dout(10) << e << dendl;
+	log_entries.push_back(e);
 
-	t.remove(
-	  coll,
-	  ghobject_t(oid, ghobject_t::NO_GEN, pg_whoami.shard));
-	pg_log.missing_add_event(e);
 	++m;
-	missing_loc.recovered(oid);
       }
       break;
 
@@ -9457,47 +9746,51 @@ void ReplicatedPG::mark_all_unfound_lost(int what)
       assert(0);
     }
 
-    if (obc)
-      c->obcs.push_back(obc);
+    if (obc) {
+      bool got = manager.get_lock_type(
+	ObjectContext::RWState::RWEXCL,
+	oid,
+	obc,
+	OpRequestRef());
+      if (!got) {
+	assert(0 == "Couldn't lock unfound object?");
+      }
+    }
   }
 
-  dout(30) << __func__ << ": log after:\n";
-  pg_log.get_log().print(*_dout);
-  *_dout << dendl;
-
   info.stats.stats_invalid = true;
 
-  if (missing.num_missing() == 0) {
-    // advance last_complete since nothing else is missing!
-    info.last_complete = info.last_update;
-  }
-
-  dirty_info = true;
-  write_if_dirty(t);
-
-  
-  osd->store->queue_transaction(osr.get(), std::move(t), c, NULL, 
-                            new C_OSD_OndiskWriteUnlockList(&c->obcs));
-	      
-  // Send out the PG log to all replicas
-  // So that they know what is lost
-  share_pg_log();
-
-  // queue ourselves so that we push the (now-lost) object_infos to replicas.
-  osd->queue_for_recovery(this);
-}
-
-void ReplicatedPG::_finish_mark_all_unfound_lost(list<ObjectContextRef>& obcs)
-{
-  lock();
-  dout(10) << "_finish_mark_all_unfound_lost " << dendl;
-
-  if (!deleting)
-    requeue_ops(waiting_for_all_missing);
-  waiting_for_all_missing.clear();
-
-  obcs.clear();
-  unlock();
+  struct OnComplete {
+    ReplicatedPG *pg;
+    std::function<void(void)> on_complete;
+    void operator()() {
+      pg->requeue_ops(pg->waiting_for_all_missing);
+      pg->waiting_for_all_missing.clear();
+      pg->osd->queue_for_recovery(pg);
+    }
+  };
+  submit_log_entries(
+    log_entries,
+    std::move(manager),
+    boost::optional<std::function<void(void)> >(
+      [=]() {
+	requeue_ops(waiting_for_all_missing);
+	waiting_for_all_missing.clear();
+	osd->queue_for_recovery(this);
+
+	stringstream ss;
+	ss << "pg has " << num_unfound
+	   << " objects unfound and apparently lost marking";
+	string rs = ss.str();
+	dout(0) << "do_command r=" << 0 << " " << rs << dendl;
+	osd->clog->info() << rs << "\n";
+	if (con) {
+	  MCommandReply *reply = new MCommandReply(0, rs);
+	  reply->set_tid(tid);
+	  con->send_message(reply);
+	}
+      }
+      ));
 }
 
 void ReplicatedPG::_split_into(pg_t child_pgid, PG *child, unsigned split_bits)
@@ -9519,16 +9812,15 @@ void ReplicatedPG::apply_and_flush_repops(bool requeue)
     repop_queue.pop_front();
     dout(10) << " canceling repop tid " << repop->rep_tid << dendl;
     repop->rep_aborted = true;
-    if (repop->on_applied) {
-      delete repop->on_applied;
-      repop->on_applied = NULL;
-    }
+    repop->on_applied.clear();
+    repop->on_committed.clear();
+    repop->on_success.clear();
 
     if (requeue) {
-      if (repop->ctx->op) {
-	dout(10) << " requeuing " << *repop->ctx->op->get_req() << dendl;
-	rq.push_back(repop->ctx->op);
-	repop->ctx->op = OpRequestRef();
+      if (repop->op) {
+	dout(10) << " requeuing " << *repop->op->get_req() << dendl;
+	rq.push_back(repop->op);
+	repop->op = OpRequestRef();
       }
 
       // also requeue any dups, interleaved into position
@@ -9651,7 +9943,7 @@ void ReplicatedPG::on_activate()
     dout(10) << "activate not all replicas are up-to-date, queueing recovery" << dendl;
     queue_peering_event(
       CephPeeringEvtRef(
-	new CephPeeringEvt(
+	std::make_shared<CephPeeringEvt>(
 	  get_osdmap()->get_epoch(),
 	  get_osdmap()->get_epoch(),
 	  DoRecovery())));
@@ -9659,7 +9951,7 @@ void ReplicatedPG::on_activate()
     dout(10) << "activate queueing backfill" << dendl;
     queue_peering_event(
       CephPeeringEvtRef(
-	new CephPeeringEvt(
+	std::make_shared<CephPeeringEvt>(
 	  get_osdmap()->get_epoch(),
 	  get_osdmap()->get_epoch(),
 	  RequestBackfill())));
@@ -9667,7 +9959,7 @@ void ReplicatedPG::on_activate()
     dout(10) << "activate all replicas clean, no recovery" << dendl;
     queue_peering_event(
       CephPeeringEvtRef(
-	new CephPeeringEvt(
+	std::make_shared<CephPeeringEvt>(
 	  get_osdmap()->get_epoch(),
 	  get_osdmap()->get_epoch(),
 	  AllReplicasRecovered())));
@@ -9722,8 +10014,6 @@ void ReplicatedPG::on_change(ObjectStore::Transaction *t)
   // requeues waiting_for_active
   scrub_clear_state();
 
-  context_registry_on_change();
-
   cancel_copy_ops(is_primary());
   cancel_flush_ops(is_primary());
   cancel_proxy_ops(is_primary());
@@ -9773,7 +10063,7 @@ void ReplicatedPG::on_change(ObjectStore::Transaction *t)
          in_progress_async_reads.begin();
        i != in_progress_async_reads.end();
        in_progress_async_reads.erase(i++)) {
-    close_op_ctx(i->second, -ECANCELED);
+    close_op_ctx(i->second);
     if (is_primary())
       requeue_op(i->first);
   }
@@ -9782,7 +10072,12 @@ void ReplicatedPG::on_change(ObjectStore::Transaction *t)
   // any dups
   apply_and_flush_repops(is_primary());
 
+  // do this *after* apply_and_flush_repops so that we catch any newly
+  // registered watches.
+  context_registry_on_change();
+
   pgbackend->on_change_cleanup(t);
+  scrubber.cleanup_store(t);
   pgbackend->on_change();
 
   // clear snap_trimmer state
@@ -10019,7 +10314,7 @@ bool ReplicatedPG::start_recovery_ops(
 	backfill_reserving = true;
 	queue_peering_event(
 	  CephPeeringEvtRef(
-	    new CephPeeringEvt(
+	    std::make_shared<CephPeeringEvt>(
 	      get_osdmap()->get_epoch(),
 	      get_osdmap()->get_epoch(),
 	      RequestBackfill())));
@@ -10072,7 +10367,7 @@ bool ReplicatedPG::start_recovery_ops(
       dout(10) << "recovery done, queuing backfill" << dendl;
       queue_peering_event(
         CephPeeringEvtRef(
-          new CephPeeringEvt(
+          std::make_shared<CephPeeringEvt>(
             get_osdmap()->get_epoch(),
             get_osdmap()->get_epoch(),
             RequestBackfill())));
@@ -10080,7 +10375,7 @@ bool ReplicatedPG::start_recovery_ops(
       dout(10) << "recovery done, no backfill" << dendl;
       queue_peering_event(
         CephPeeringEvtRef(
-          new CephPeeringEvt(
+          std::make_shared<CephPeeringEvt>(
             get_osdmap()->get_epoch(),
             get_osdmap()->get_epoch(),
             AllReplicasRecovered())));
@@ -10090,7 +10385,7 @@ bool ReplicatedPG::start_recovery_ops(
     dout(10) << "recovery done, backfill done" << dendl;
     queue_peering_event(
       CephPeeringEvtRef(
-        new CephPeeringEvt(
+        std::make_shared<CephPeeringEvt>(
           get_osdmap()->get_epoch(),
           get_osdmap()->get_epoch(),
           Backfilled())));
@@ -11113,15 +11408,14 @@ void ReplicatedPG::hit_set_remove_all()
     ObjectContextRef obc = get_object_context(oid, false);
     assert(obc);
 
-    RepGather *repop = simple_repop_create(obc);
-    OpContext *ctx = repop->ctx;
+    OpContextUPtr ctx = simple_opc_create(obc);
     ctx->at_version = get_next_version();
     ctx->updated_hset_history = info.hit_set;
     utime_t now = ceph_clock_now(cct);
     ctx->mtime = now;
-    hit_set_trim(repop, 0);
-    apply_ctx_stats(ctx);
-    simple_repop_submit(repop);
+    hit_set_trim(ctx, 0);
+    apply_ctx_stats(ctx.get());
+    simple_opc_submit(std::move(ctx));
   }
 
   info.hit_set = pg_hit_set_history_t();
@@ -11201,15 +11495,6 @@ bool ReplicatedPG::hit_set_apply_log()
   return true;
 }
 
-struct C_HitSetFlushing : public Context {
-  ReplicatedPGRef pg;
-  time_t hit_set_name;
-  C_HitSetFlushing(ReplicatedPG *p, time_t n) : pg(p), hit_set_name(n) { }
-  void finish(int r) {
-    pg->hit_set_flushing.erase(hit_set_name);
-  }
-};
-
 void ReplicatedPG::hit_set_persist()
 {
   dout(10) << __func__  << dendl;
@@ -11217,7 +11502,6 @@ void ReplicatedPG::hit_set_persist()
   unsigned max = pool.info.hit_set_count;
 
   utime_t now = ceph_clock_now(cct);
-  RepGather *repop;
   hobject_t oid;
   time_t flush_time = 0;
 
@@ -11286,10 +11570,15 @@ void ReplicatedPG::hit_set_persist()
   flush_time = new_hset.begin;
 
   ObjectContextRef obc = get_object_context(oid, true);
-  repop = simple_repop_create(obc);
-  if (flush_time != 0)
-    repop->on_applied = new C_HitSetFlushing(this, flush_time);
-  OpContext *ctx = repop->ctx;
+  OpContextUPtr ctx = simple_opc_create(obc);
+  if (flush_time != 0) {
+    ReplicatedPGRef pg(this);
+    ctx->register_on_applied(
+      [pg, flush_time]() {
+	pg->hit_set_flushing.erase(flush_time);
+      });
+  }
+
   ctx->at_version = get_next_version();
   ctx->updated_hset_history = info.hit_set;
   pg_hit_set_history_t &updated_hit_set_hist = *(ctx->updated_hset_history);
@@ -11326,7 +11615,7 @@ void ReplicatedPG::hit_set_persist()
   map <string, bufferlist> attrs;
   attrs[OI_ATTR].claim(boi);
   attrs[SS_ATTR].claim(bss);
-  setattrs_maybe_cache(ctx->obc, ctx, ctx->op_t, attrs);
+  setattrs_maybe_cache(ctx->obc, ctx.get(), ctx->op_t.get(), attrs);
   ctx->log.push_back(
     pg_log_entry_t(
       pg_log_entry_t::MODIFY,
@@ -11343,17 +11632,17 @@ void ReplicatedPG::hit_set_persist()
     ctx->log.back().mod_desc.mark_unrollbackable();
   }
 
-  hit_set_trim(repop, max);
+  hit_set_trim(ctx, max);
 
-  apply_ctx_stats(ctx);
-  simple_repop_submit(repop);
+  apply_ctx_stats(ctx.get());
+  simple_opc_submit(std::move(ctx));
 }
 
-void ReplicatedPG::hit_set_trim(RepGather *repop, unsigned max)
+void ReplicatedPG::hit_set_trim(OpContextUPtr &ctx, unsigned max)
 {
-  assert(repop->ctx->updated_hset_history);
+  assert(ctx->updated_hset_history);
   pg_hit_set_history_t &updated_hit_set_hist =
-    *(repop->ctx->updated_hset_history);
+    *(ctx->updated_hset_history);
   for (unsigned num = updated_hit_set_hist.history.size(); num > max; --num) {
     list<pg_hit_set_info_t>::iterator p = updated_hit_set_hist.history.begin();
     assert(p != updated_hit_set_hist.history.end());
@@ -11362,34 +11651,34 @@ void ReplicatedPG::hit_set_trim(RepGather *repop, unsigned max)
     assert(!is_degraded_or_backfilling_object(oid));
 
     dout(20) << __func__ << " removing " << oid << dendl;
-    ++repop->ctx->at_version.version;
-    repop->ctx->log.push_back(
+    ++ctx->at_version.version;
+    ctx->log.push_back(
         pg_log_entry_t(pg_log_entry_t::DELETE,
 		       oid,
-		       repop->ctx->at_version,
+		       ctx->at_version,
 		       p->version,
 		       0,
 		       osd_reqid_t(),
-		       repop->ctx->mtime));
+		       ctx->mtime));
     if (pool.info.require_rollback()) {
-      if (repop->ctx->log.back().mod_desc.rmobject(
-	  repop->ctx->at_version.version)) {
-	repop->ctx->op_t->stash(oid, repop->ctx->at_version.version);
+      if (ctx->log.back().mod_desc.rmobject(
+	  ctx->at_version.version)) {
+	ctx->op_t->stash(oid, ctx->at_version.version);
       } else {
-	repop->ctx->op_t->remove(oid);
+	ctx->op_t->remove(oid);
       }
     } else {
-      repop->ctx->op_t->remove(oid);
-      repop->ctx->log.back().mod_desc.mark_unrollbackable();
+      ctx->op_t->remove(oid);
+      ctx->log.back().mod_desc.mark_unrollbackable();
     }
     updated_hit_set_hist.history.pop_front();
 
     ObjectContextRef obc = get_object_context(oid, false);
     assert(obc);
-    --repop->ctx->delta_stats.num_objects;
-    --repop->ctx->delta_stats.num_objects_hit_set_archive;
-    repop->ctx->delta_stats.num_bytes -= obc->obs.oi.size;
-    repop->ctx->delta_stats.num_bytes_hit_set_archive -= obc->obs.oi.size;
+    --ctx->delta_stats.num_objects;
+    --ctx->delta_stats.num_objects_hit_set_archive;
+    ctx->delta_stats.num_bytes -= obc->obs.oi.size;
+    ctx->delta_stats.num_bytes_hit_set_archive -= obc->obs.oi.size;
   }
 }
 
@@ -11665,17 +11954,6 @@ void ReplicatedPG::agent_load_hit_sets()
   }
 }
 
-struct C_AgentFlushStartStop : public Context {
-  ReplicatedPGRef pg;
-  hobject_t oid;
-  C_AgentFlushStartStop(ReplicatedPG *p, hobject_t o) : pg(p), oid(o) {
-    pg->osd->agent_start_op(oid);
-  }
-  void finish(int r) {
-    pg->osd->agent_finish_op(oid);
-  }
-};
-
 bool ReplicatedPG::agent_maybe_flush(ObjectContextRef& obc)
 {
   if (!obc->obs.oi.is_dirty()) {
@@ -11717,12 +11995,18 @@ bool ReplicatedPG::agent_maybe_flush(ObjectContextRef& obc)
   // FIXME: flush anything dirty, regardless of what distribution of
   // ages we expect.
 
-  Context *on_flush = new C_AgentFlushStartStop(this, obc->obs.oi.soid);
+  hobject_t oid = obc->obs.oi.soid;
+  osd->agent_start_op(oid);
+  // no need to capture a pg ref, can't outlive fop or ctx
+  std::function<void()> on_flush = [this, oid]() {
+    osd->agent_finish_op(oid);
+  };
+
   int result = start_flush(
     OpRequestRef(), obc, false, NULL,
     on_flush);
   if (result != -EINPROGRESS) {
-    on_flush->complete(result);
+    on_flush();
     dout(10) << __func__ << " start_flush() failed " << obc->obs.oi
       << " with " << result << dendl;
     osd->logger->inc(l_osd_agent_skip);
@@ -11733,16 +12017,6 @@ bool ReplicatedPG::agent_maybe_flush(ObjectContextRef& obc)
   return true;
 }
 
-struct C_AgentEvictStartStop : public Context {
-  ReplicatedPGRef pg;
-  explicit C_AgentEvictStartStop(ReplicatedPG *p) : pg(p) {
-    pg->osd->agent_start_evict_op();
-  }
-  void finish(int r) {
-    pg->osd->agent_finish_evict_op();
-  }
-};
-
 bool ReplicatedPG::agent_maybe_evict(ObjectContextRef& obc, bool after_flush)
 {
   const hobject_t& soid = obc->obs.oi.soid;
@@ -11811,20 +12085,28 @@ bool ReplicatedPG::agent_maybe_evict(ObjectContextRef& obc, bool after_flush)
       return false;
   }
 
-  if (!obc->get_write(OpRequestRef())) {
+  dout(10) << __func__ << " evicting " << obc->obs.oi << dendl;
+  OpContextUPtr ctx = simple_opc_create(obc);
+
+  if (!ctx->lock_manager.get_lock_type(
+	ObjectContext::RWState::RWWRITE,
+	obc->obs.oi.soid,
+	obc,
+	OpRequestRef())) {
+    close_op_ctx(ctx.release());
     dout(20) << __func__ << " skip (cannot get lock) " << obc->obs.oi << dendl;
     return false;
   }
 
-  dout(10) << __func__ << " evicting " << obc->obs.oi << dendl;
-  RepGather *repop = simple_repop_create(obc);
-  OpContext *ctx = repop->ctx;
-  Context *on_evict = new C_AgentEvictStartStop(this);
-  ctx->on_finish = on_evict;
-  ctx->lock_to_release = OpContext::W_LOCK;
+  osd->agent_start_evict_op();
+  ctx->register_on_finish(
+    [this]() {
+      osd->agent_finish_evict_op();
+    });
+
   ctx->at_version = get_next_version();
   assert(ctx->new_obs.exists);
-  int r = _delete_oid(ctx, true);
+  int r = _delete_oid(ctx.get(), true);
   if (obc->obs.oi.is_omap())
     ctx->delta_stats.num_objects_omap--;
   ctx->delta_stats.num_evict++;
@@ -11832,8 +12114,8 @@ bool ReplicatedPG::agent_maybe_evict(ObjectContextRef& obc, bool after_flush)
   if (obc->obs.oi.is_dirty())
     --ctx->delta_stats.num_objects_dirty;
   assert(r == 0);
-  finish_ctx(ctx, pg_log_entry_t::DELETE, false);
-  simple_repop_submit(repop);
+  finish_ctx(ctx.get(), pg_log_entry_t::DELETE, false);
+  simple_opc_submit(std::move(ctx));
   osd->logger->inc(l_osd_tier_evict);
   osd->logger->inc(l_osd_agent_evict);
   return true;
@@ -12137,22 +12419,6 @@ bool ReplicatedPG::_range_available_for_scrub(
   return true;
 }
 
-struct C_ScrubDigestUpdated : public Context {
-  ReplicatedPGRef pg;
-  explicit C_ScrubDigestUpdated(ReplicatedPG *pg) : pg(pg) {}
-  void finish(int r) {
-    pg->_scrub_digest_updated();
-  }
-};
-
-void ReplicatedPG::_scrub_digest_updated()
-{
-  dout(20) << __func__ << dendl;
-  if (--scrubber.num_digest_updates_pending == 0) {
-    requeue_scrub();
-  }
-}
-
 static bool doing_clones(const boost::optional<SnapSet> &snapset,
 			 const vector<snapid_t>::reverse_iterator &curclone) {
     return snapset && curclone != snapset.get().clones.rend();
@@ -12183,7 +12449,8 @@ unsigned ReplicatedPG::process_clones_to(const boost::optional<hobject_t> &head,
   const char *mode,
   bool allow_incomplete_clones,
   boost::optional<snapid_t> target,
-  vector<snapid_t>::reverse_iterator *curclone)
+  vector<snapid_t>::reverse_iterator *curclone,
+  inconsistent_snapset_wrapper &e)
 {
   assert(head);
   assert(snapset);
@@ -12200,6 +12467,7 @@ unsigned ReplicatedPG::process_clones_to(const boost::optional<hobject_t> &head,
       clog->error() << mode << " " << pgid << " " << head.get()
 			 << " expected clone " << next_clone;
       ++scrubber.shallow_errors;
+      e.set_clone_missing(next_clone.snap);
     }
     // Clones are descending
     ++(*curclone);
@@ -12249,12 +12517,14 @@ void ReplicatedPG::_scrub(
   boost::optional<SnapSet> snapset; // If initialized so will head (above)
   vector<snapid_t>::reverse_iterator curclone; // Defined only if snapset initialized
   unsigned missing = 0;
+  inconsistent_snapset_wrapper snap_error;
 
   bufferlist last_data;
 
   for (map<hobject_t,ScrubMap::object, hobject_t::BitwiseComparator>::reverse_iterator
        p = scrubmap.objects.rbegin(); p != scrubmap.objects.rend(); ++p) {
     const hobject_t& soid = p->first;
+    snap_error = inconsistent_snapset_wrapper{soid};
     object_stat_sum_t stat;
     boost::optional<object_info_t> oi;
 
@@ -12275,6 +12545,7 @@ void ReplicatedPG::_scrub(
       osd->clog->error() << mode << " " << info.pgid << " " << soid
 			<< " no '" << OI_ATTR << "' attr";
       ++scrubber.shallow_errors;
+      snap_error.set_ss_attr_missing();
     } else {
       bufferlist bv;
       bv.push_back(p->second.attrs[OI_ATTR]);
@@ -12286,6 +12557,7 @@ void ReplicatedPG::_scrub(
 	osd->clog->error() << mode << " " << info.pgid << " " << soid
 		<< " can't decode '" << OI_ATTR << "' attr " << e.what();
 	++scrubber.shallow_errors;
+	snap_error.set_ss_attr_corrupted();
       }
     }
 
@@ -12297,6 +12569,7 @@ void ReplicatedPG::_scrub(
 			   << oi->size << ") adjusted for ondisk to ("
 			   << pgbackend->be_get_ondisk_size(oi->size)
 			   << ")";
+	snap_error.set_size_mismatch();
 	++scrubber.shallow_errors;
       }
 
@@ -12339,7 +12612,8 @@ void ReplicatedPG::_scrub(
       // Log any clones we were expecting to be there up to target
       // This will set missing, but will be a no-op if snap.soid == *curclone.
       missing += process_clones_to(head, snapset, osd->clog, info.pgid, mode,
-		        pool.info.allow_incomplete_clones(), target, &curclone);
+		        pool.info.allow_incomplete_clones(), target, &curclone,
+			snap_error);
     }
     bool expected;
     // Check doing_clones() again in case we ran process_clones_to()
@@ -12360,11 +12634,14 @@ void ReplicatedPG::_scrub(
       if (head && !snapset) {
 	osd->clog->info() << mode << " " << info.pgid << " " << soid
 			  << " clone ignored due to missing snapset";
+	scrubber.store->add_snap_error(pool.id, snap_error);
 	continue;
       }
       osd->clog->error() << mode << " " << info.pgid << " " << soid
 			   << " is an unexpected clone";
       ++scrubber.shallow_errors;
+      snap_error.set_headless();
+      scrubber.store->add_snap_error(pool.id, snap_error);
       continue;
     }
 
@@ -12374,11 +12651,13 @@ void ReplicatedPG::_scrub(
       if (missing) {
 	log_missing(missing, head, osd->clog, info.pgid, __func__, mode,
 		    pool.info.allow_incomplete_clones());
+	scrubber.store->add_snap_error(pool.id, snap_error);
       }
 
       // Set this as a new head object
       head = soid;
       missing = 0;
+      snap_error = inconsistent_snapset_wrapper{head.get()};
 
       dout(20) << __func__ << " " << mode << " new head " << head << dendl;
 
@@ -12387,6 +12666,7 @@ void ReplicatedPG::_scrub(
 			  << " no '" << SS_ATTR << "' attr";
         ++scrubber.shallow_errors;
 	snapset = boost::none;
+	snap_error.set_ss_attr_missing();
       } else {
 	bufferlist bl;
 	bl.push_back(p->second.attrs[SS_ATTR]);
@@ -12399,6 +12679,7 @@ void ReplicatedPG::_scrub(
           osd->clog->error() << mode << " " << info.pgid << " " << soid
 		<< " can't decode '" << SS_ATTR << "' attr " << e.what();
 	  ++scrubber.shallow_errors;
+	  snap_error.set_ss_attr_corrupted();
         }
       }
 
@@ -12412,6 +12693,7 @@ void ReplicatedPG::_scrub(
 	    osd->clog->error() << mode << " " << info.pgid << " " << soid
 			       << " snaps.seq not set";
 	    ++scrubber.shallow_errors;
+	    snap_error.set_snapset_mismatch();
           }
 	}
 
@@ -12419,11 +12701,13 @@ void ReplicatedPG::_scrub(
 	  osd->clog->error() << mode << " " << info.pgid << " " << soid
 			  << " snapset.head_exists=false, but head exists";
 	  ++scrubber.shallow_errors;
+	  snap_error.set_head_mismatch();
 	}
 	if (soid.is_snapdir() && snapset->head_exists) {
 	  osd->clog->error() << mode << " " << info.pgid << " " << soid
 			  << " snapset.head_exists=true, but snapdir exists";
 	  ++scrubber.shallow_errors;
+	  snap_error.set_head_mismatch();
 	}
       }
     } else {
@@ -12438,19 +12722,22 @@ void ReplicatedPG::_scrub(
 	osd->clog->error() << mode << " " << info.pgid << " " << soid
 			   << " is missing in clone_size";
 	++scrubber.shallow_errors;
+	snap_error.set_size_mismatch();
       } else {
         if (oi && oi->size != snapset->clone_size[soid.snap]) {
 	  osd->clog->error() << mode << " " << info.pgid << " " << soid
 			     << " size " << oi->size << " != clone_size "
 			     << snapset->clone_size[*curclone];
 	  ++scrubber.shallow_errors;
+	  snap_error.set_size_mismatch();
         }
 
         if (snapset->clone_overlap.count(soid.snap) == 0) {
 	  osd->clog->error() << mode << " " << info.pgid << " " << soid
 			     << " is missing in clone_overlap";
 	  ++scrubber.shallow_errors;
-        } else {
+	  snap_error.set_size_mismatch();
+	} else {
 	  // This checking is based on get_clone_bytes().  The first 2 asserts
 	  // can't happen because we know we have a clone_size and
 	  // a clone_overlap.  Now we check that the interval_set won't
@@ -12472,6 +12759,7 @@ void ReplicatedPG::_scrub(
 	    osd->clog->error() << mode << " " << info.pgid << " " << soid
 			       << " bad interval_set in clone_overlap";
 	    ++scrubber.shallow_errors;
+	    snap_error.set_size_mismatch();
 	  } else {
             stat.num_bytes += snapset->get_clone_bytes(soid.snap);
 	  }
@@ -12490,14 +12778,15 @@ void ReplicatedPG::_scrub(
 	     << " No more objects while processing " << head.get() << dendl;
 
     missing += process_clones_to(head, snapset, osd->clog, info.pgid, mode,
-		      pool.info.allow_incomplete_clones(), all_clones, &curclone);
-
+		      pool.info.allow_incomplete_clones(), all_clones, &curclone,
+		      snap_error);
   }
   // There could be missing found by the test above or even
   // before dropping out of the loop for the last head.
   if (missing) {
     log_missing(missing, head, osd->clog, info.pgid, __func__,
 		mode, pool.info.allow_incomplete_clones());
+    scrubber.store->add_snap_error(pool.id, snap_error);
   }
 
   for (map<hobject_t,pair<uint32_t,uint32_t>, hobject_t::BitwiseComparator>::const_iterator p =
@@ -12509,15 +12798,22 @@ void ReplicatedPG::_scrub(
     dout(10) << __func__ << " recording digests for " << p->first << dendl;
     ObjectContextRef obc = get_object_context(p->first, false);
     assert(obc);
-    RepGather *repop = simple_repop_create(obc);
-    OpContext *ctx = repop->ctx;
+    OpContextUPtr ctx = simple_opc_create(obc);
     ctx->at_version = get_next_version();
     ctx->mtime = utime_t();      // do not update mtime
     ctx->new_obs.oi.set_data_digest(p->second.first);
     ctx->new_obs.oi.set_omap_digest(p->second.second);
-    finish_ctx(ctx, pg_log_entry_t::MODIFY, true, true);
-    ctx->on_finish = new C_ScrubDigestUpdated(this);
-    simple_repop_submit(repop);
+    finish_ctx(ctx.get(), pg_log_entry_t::MODIFY, true, true);
+
+    ctx->register_on_success(
+      [this]() {
+	dout(20) << "updating scrub digest" << dendl;
+	if (--scrubber.num_digest_updates_pending == 0) {
+	  requeue_scrub();
+	}
+      });
+
+    simple_opc_submit(std::move(ctx));
     ++scrubber.num_digest_updates_pending;
   }
 
@@ -12600,10 +12896,7 @@ void ReplicatedPG::_scrub_finish()
 
 ReplicatedPG::SnapTrimmer::~SnapTrimmer()
 {
-  while (!repops.empty()) {
-    (*repops.begin())->put();
-    repops.erase(repops.begin());
-  }
+  in_flight.clear();
 }
 
 void ReplicatedPG::SnapTrimmer::log_enter(const char *state_name)
@@ -12672,36 +12965,19 @@ ReplicatedPG::TrimmingObjects::TrimmingObjects(my_context ctx)
 void ReplicatedPG::TrimmingObjects::exit()
 {
   context< SnapTrimmer >().log_exit(state_name, enter_time);
-  // Clean up repops in case of reset
-  set<RepGather *> &repops = context<SnapTrimmer>().repops;
-  for (set<RepGather *>::iterator i = repops.begin();
-       i != repops.end();
-       repops.erase(i++)) {
-    (*i)->put();
-  }
+  context<SnapTrimmer>().in_flight.clear();
 }
 
 boost::statechart::result ReplicatedPG::TrimmingObjects::react(const SnapTrim&)
 {
   dout(10) << "TrimmingObjects react" << dendl;
-  ReplicatedPG *pg = context< SnapTrimmer >().pg;
+  ReplicatedPGRef pg = context< SnapTrimmer >().pg;
   snapid_t snap_to_trim = context<SnapTrimmer>().snap_to_trim;
-  set<RepGather *> &repops = context<SnapTrimmer>().repops;
+  auto &in_flight = context<SnapTrimmer>().in_flight;
 
   dout(10) << "TrimmingObjects: trimming snap " << snap_to_trim << dendl;
 
-  for (set<RepGather *>::iterator i = repops.begin();
-       i != repops.end(); 
-       ) {
-    if ((*i)->all_applied && (*i)->all_committed) {
-      (*i)->put();
-      repops.erase(i++);
-    } else {
-      ++i;
-    }
-  }
-
-  while (repops.size() < g_conf->osd_pg_max_concurrent_snap_trims) {
+  while (in_flight.size() < g_conf->osd_pg_max_concurrent_snap_trims) {
     // Get next
     hobject_t old_pos = pos;
     int r = pg->snap_mapper.get_next_object_to_trim(snap_to_trim, &pos);
@@ -12716,20 +12992,25 @@ boost::statechart::result ReplicatedPG::TrimmingObjects::react(const SnapTrim&)
     }
 
     dout(10) << "TrimmingObjects react trimming " << pos << dendl;
-    RepGather *repop = pg->trim_object(pos);
-    if (!repop) {
+    OpContextUPtr ctx = pg->trim_object(pos);
+    if (!ctx) {
       dout(10) << __func__ << " could not get write lock on obj "
 	       << pos << dendl;
       pos = old_pos;
       return discard_event();
     }
-    assert(repop);
-    repop->queue_snap_trimmer = true;
+    assert(ctx);
+    hobject_t to_remove = pos;
+    ctx->register_on_success(
+      [pg, to_remove, &in_flight]() {
+	in_flight.erase(to_remove);
+	pg->queue_snap_trim();
+      });
 
-    pg->apply_ctx_stats(repop->ctx);
+    pg->apply_ctx_stats(ctx.get());
 
-    repops.insert(repop->get());
-    pg->simple_repop_submit(repop);
+    in_flight.insert(pos);
+    pg->simple_opc_submit(std::move(ctx));
   }
   return discard_event();
 }
@@ -12745,30 +13026,16 @@ ReplicatedPG::WaitingOnReplicas::WaitingOnReplicas(my_context ctx)
 void ReplicatedPG::WaitingOnReplicas::exit()
 {
   context< SnapTrimmer >().log_exit(state_name, enter_time);
-
-  // Clean up repops in case of reset
-  set<RepGather *> &repops = context<SnapTrimmer>().repops;
-  for (set<RepGather *>::iterator i = repops.begin();
-       i != repops.end();
-       repops.erase(i++)) {
-    (*i)->put();
-  }
+  context<SnapTrimmer>().in_flight.clear();
 }
 
 boost::statechart::result ReplicatedPG::WaitingOnReplicas::react(const SnapTrim&)
 {
-  // Have all the repops applied?
+  // Have all the trims finished?
   dout(10) << "Waiting on Replicas react" << dendl;
   ReplicatedPG *pg = context< SnapTrimmer >().pg;
-  set<RepGather *> &repops = context<SnapTrimmer>().repops;
-  for (set<RepGather *>::iterator i = repops.begin();
-       i != repops.end();
-       repops.erase(i++)) {
-    if (!(*i)->all_applied || !(*i)->all_committed) {
-      return discard_event();
-    } else {
-      (*i)->put();
-    }
+  if (!context<SnapTrimmer>().in_flight.empty()) {
+    return discard_event();
   }
 
   snapid_t &sn = context<SnapTrimmer>().snap_to_trim;
diff --git a/src/osd/ReplicatedPG.h b/src/osd/ReplicatedPG.h
index 0ee87a7..5384f2d 100644
--- a/src/osd/ReplicatedPG.h
+++ b/src/osd/ReplicatedPG.h
@@ -59,6 +59,8 @@ void put_with_id(ReplicatedPG *pg, uint64_t id);
   typedef boost::intrusive_ptr<ReplicatedPG> ReplicatedPGRef;
 #endif
 
+struct inconsistent_snapset_wrapper;
+
 class ReplicatedPG : public PG, public PGBackend::Listener {
   friend class OSD;
   friend class Watch;
@@ -167,7 +169,7 @@ public:
       results.mirror_snapset = mirror_snapset;
     }
   };
-  typedef boost::shared_ptr<CopyOp> CopyOpRef;
+  typedef ceph::shared_ptr<CopyOp> CopyOpRef;
 
   /**
    * The CopyCallback class defines an interface for completions to the
@@ -212,7 +214,7 @@ public:
 	user_version(0), data_offset(0),
 	canceled(false) { }
   };
-  typedef boost::shared_ptr<ProxyReadOp> ProxyReadOpRef;
+  typedef ceph::shared_ptr<ProxyReadOp> ProxyReadOpRef;
 
   struct ProxyWriteOp {
     OpContext *ctx;
@@ -234,7 +236,7 @@ public:
 	sent_ack(false), canceled(false),
         reqid(_reqid) { }
   };
-  typedef boost::shared_ptr<ProxyWriteOp> ProxyWriteOpRef;
+  typedef ceph::shared_ptr<ProxyWriteOp> ProxyWriteOpRef;
 
   struct FlushOp {
     ObjectContextRef obc;       ///< obc we are flushing
@@ -245,15 +247,14 @@ public:
     int rval;                   ///< copy-from result
     bool blocking;              ///< whether we are blocking updates
     bool removal;               ///< we are removing the backend object
-    Context *on_flush;          ///< callback, may be null
+    boost::optional<std::function<void()>> on_flush; ///< callback, may be null
 
     FlushOp()
       : flushed_version(0), objecter_tid(0), rval(0),
-	blocking(false), removal(false),
-	on_flush(NULL) {}
+	blocking(false), removal(false) {}
     ~FlushOp() { assert(!on_flush); }
   };
-  typedef boost::shared_ptr<FlushOp> FlushOpRef;
+  typedef ceph::shared_ptr<FlushOp> FlushOpRef;
 
   boost::scoped_ptr<PGBackend> pgbackend;
   PGBackend *get_pgbackend() {
@@ -382,18 +383,19 @@ public:
     map<string, bufferlist> &attrs) {
     return get_object_context(hoid, true, &attrs);
   }
+
   void log_operation(
     const vector<pg_log_entry_t> &logv,
     boost::optional<pg_hit_set_history_t> &hset_history,
     const eversion_t &trim_to,
     const eversion_t &trim_rollback_to,
     bool transaction_applied,
-    ObjectStore::Transaction *t) {
+    ObjectStore::Transaction &t) {
     if (hset_history) {
       info.hit_set = *hset_history;
       dirty_info = true;
     }
-    append_log(logv, trim_to, trim_rollback_to, *t, transaction_applied);
+    append_log(logv, trim_to, trim_rollback_to, t, transaction_applied);
   }
 
   void op_applied(
@@ -449,11 +451,6 @@ public:
     return get_sort_bitwise();
   }
 
-  bool transaction_use_tbl() {
-    uint64_t min_features = get_min_upacting_features();
-    return !(min_features & CEPH_FEATURE_OSD_TRANSACTION_MAY_LAYOUT);
-  }
-
   void send_message_osd_cluster(
     int peer, Message *m, epoch_t from_epoch);
   void send_message_osd_cluster(
@@ -471,6 +468,17 @@ public:
 
   LogClientTemp clog_error() { return osd->clog->error(); }
 
+  struct watch_disconnect_t {
+    uint64_t cookie;
+    entity_name_t name;
+    bool send_disconnect;
+    watch_disconnect_t(uint64_t c, entity_name_t n, bool sd)
+      : cookie(c), name(n), send_disconnect(sd) {}
+  };
+  void complete_disconnect_watches(
+    ObjectContextRef obc,
+    const list<watch_disconnect_t> &to_disconnect);
+
   /*
    * Capture all object state associated with an in-progress read or write.
    */
@@ -496,13 +504,6 @@ public:
 
     // side effects
     list<pair<watch_info_t,bool> > watch_connects; ///< new watch + will_ping flag
-    struct watch_disconnect_t {
-      uint64_t cookie;
-      entity_name_t name;
-      bool send_disconnect;
-      watch_disconnect_t(uint64_t c, entity_name_t n, bool sd)
-	: cookie(c), name(n), send_disconnect(sd) {}
-    };
     list<watch_disconnect_t> watch_disconnects; ///< old watch + send_discon
     list<notify_info_t> notifies;
     struct NotifyAck {
@@ -526,7 +527,7 @@ public:
 
     int current_osd_subop_num;
 
-    PGBackend::PGTransaction *op_t;
+    PGBackend::PGTransactionUPtr op_t;
     vector<pg_log_entry_t> log;
     boost::optional<pg_hit_set_history_t> updated_hset_history;
 
@@ -555,6 +556,31 @@ public:
     // pending xattr updates
     map<ObjectContextRef,
 	map<string, boost::optional<bufferlist> > > pending_attrs;
+
+    list<std::function<void()>> on_applied;
+    list<std::function<void()>> on_committed;
+    list<std::function<void()>> on_finish;
+    list<std::function<void()>> on_success;
+    template <typename F>
+    void register_on_finish(F &&f) {
+      on_finish.emplace_back(std::move(f));
+    }
+    template <typename F>
+    void register_on_success(F &&f) {
+      on_finish.emplace_back(std::move(f));
+    }
+    template <typename F>
+    void register_on_applied(F &&f) {
+      on_applied.emplace_back(std::move(f));
+    }
+    template <typename F>
+    void register_on_commit(F &&f) {
+      on_committed.emplace_back(std::move(f));
+    }
+
+    bool sent_ack;
+    bool sent_disk;
+
     void apply_pending_attrs() {
       for (map<ObjectContextRef,
 	     map<string, boost::optional<bufferlist> > >::iterator i =
@@ -592,15 +618,12 @@ public:
 
     ObjectModDesc mod_desc;
 
-    enum { W_LOCK, R_LOCK, E_LOCK, NONE } lock_to_release;
-
-    Context *on_finish;
+    ObjectContext::RWState::State lock_type;
+    ObcLockManager lock_manager;
 
     OpContext(const OpContext& other);
     const OpContext& operator=(const OpContext& other);
 
-    bool release_snapset_obc;
-
     OpContext(OpRequestRef _op, osd_reqid_t _reqid, vector<OSDOp>& _ops,
 	      ObjectContextRef& obc,
 	      ReplicatedPG *_pg) :
@@ -612,17 +635,15 @@ public:
       ignore_cache(false), ignore_log_op_stats(false),
       bytes_written(0), bytes_read(0), user_at_version(0),
       current_osd_subop_num(0),
-      op_t(NULL),
       obc(obc),
       data_off(0), reply(NULL), pg(_pg),
       num_read(0),
       num_write(0),
       copy_cb(NULL),
+      sent_ack(false), sent_disk(false),
       async_read_result(0),
       inflightreads(0),
-      lock_to_release(NONE),
-      on_finish(NULL),
-      release_snapset_obc(false) {
+      lock_type(ObjectContext::RWState::RWNONE) {
       if (obc->ssc) {
 	new_snapset = obc->ssc->snapset;
 	snapset = &obc->ssc->snapset;
@@ -635,16 +656,13 @@ public:
       ignore_cache(false), ignore_log_op_stats(false),
       bytes_written(0), bytes_read(0), user_at_version(0),
       current_osd_subop_num(0),
-      op_t(NULL),
       data_off(0), reply(NULL), pg(_pg),
       num_read(0),
       num_write(0),
       copy_cb(NULL),
       async_read_result(0),
       inflightreads(0),
-      lock_to_release(NONE),
-      on_finish(NULL),
-      release_snapset_obc(false) { }
+      lock_type(ObjectContext::RWState::RWNONE) {}
     void reset_obs(ObjectContextRef obc) {
       new_obs = ObjectState(obc->obs.oi, obc->obs.exists);
       if (obc->ssc) {
@@ -654,7 +672,6 @@ public:
     }
     ~OpContext() {
       assert(!op_t);
-      assert(lock_to_release == NONE);
       if (reply)
 	reply->put();
       for (list<pair<boost::tuple<uint64_t, uint64_t, unsigned>,
@@ -664,15 +681,9 @@ public:
 	   pending_async_reads.erase(i++)) {
 	delete i->second.second;
       }
-      assert(on_finish == NULL);
-    }
-    void finish(int r) {
-      if (on_finish) {
-	on_finish->complete(r);
-	on_finish = NULL;
-      }
     }
   };
+  using OpContextUPtr = std::unique_ptr<OpContext>;
   friend struct OpContext;
 
   /*
@@ -680,48 +691,63 @@ public:
    */
   class RepGather {
   public:
+    hobject_t hoid;
+    OpRequestRef op;
     xlist<RepGather*>::item queue_item;
     int nref;
 
     eversion_t v;
 
-    OpContext *ctx;
-    ObjectContextRef obc;
-    map<hobject_t,ObjectContextRef, hobject_t::BitwiseComparator> src_obc;
-
     ceph_tid_t rep_tid;
 
     bool rep_aborted, rep_done;
 
     bool all_applied;
     bool all_committed;
-    bool sent_ack;
-    //bool sent_nvram;
-    bool sent_disk;
     
     utime_t   start;
     
     eversion_t          pg_local_last_complete;
 
-    bool queue_snap_trimmer;
+    ObcLockManager lock_manager;
 
-    Context *on_applied;
-    bool log_op_stat;
+    list<std::function<void()>> on_applied;
+    list<std::function<void()>> on_committed;
+    list<std::function<void()>> on_success;
+    list<std::function<void()>> on_finish;
     
-    RepGather(OpContext *c, ObjectContextRef pi, ceph_tid_t rt,
+    RepGather(OpContext *c, ceph_tid_t rt,
 	      eversion_t lc) :
+      hoid(c->obc->obs.oi.soid),
+      op(c->op),
       queue_item(this),
       nref(1),
-      ctx(c), obc(pi),
       rep_tid(rt), 
       rep_aborted(false), rep_done(false),
-      all_applied(false), all_committed(false), sent_ack(false),
-      //sent_nvram(false),
-      sent_disk(false),
+      all_applied(false), all_committed(false),
+      pg_local_last_complete(lc),
+      lock_manager(std::move(c->lock_manager)),
+      on_applied(std::move(c->on_applied)),
+      on_committed(std::move(c->on_committed)),
+      on_success(std::move(c->on_success)),
+      on_finish(std::move(c->on_finish)) {}
+
+    RepGather(
+      ObcLockManager &&manager,
+      boost::optional<std::function<void(void)> > &&on_complete,
+      ceph_tid_t rt,
+      eversion_t lc) :
+      queue_item(this),
+      nref(1),
+      rep_tid(rt),
+      rep_aborted(false), rep_done(false),
+      all_applied(false), all_committed(false),
       pg_local_last_complete(lc),
-      queue_snap_trimmer(false),
-      on_applied(NULL),
-      log_op_stat(false) { }
+      lock_manager(std::move(manager)) {
+      if (on_complete) {
+	on_success.push_back(std::move(*on_complete));
+      }
+    }
 
     RepGather *get() {
       nref++;
@@ -730,8 +756,7 @@ public:
     void put() {
       assert(nref > 0);
       if (--nref == 0) {
-	delete ctx; // must already be unlocked
-	assert(on_applied == NULL);
+	assert(on_applied.empty());
 	delete this;
 	//generic_dout(0) << "deleting " << this << dendl;
       }
@@ -753,33 +778,35 @@ protected:
      * this (read or write) if we get the first we will be guaranteed
      * to get the second.
      */
-    ObjectContext::RWState::State type = ObjectContext::RWState::RWNONE;
     if (write_ordered && ctx->op->may_read()) {
-      type = ObjectContext::RWState::RWEXCL;
-      ctx->lock_to_release = OpContext::E_LOCK;
+      ctx->lock_type = ObjectContext::RWState::RWEXCL;
     } else if (write_ordered) {
-      type = ObjectContext::RWState::RWWRITE;
-      ctx->lock_to_release = OpContext::W_LOCK;
+      ctx->lock_type = ObjectContext::RWState::RWWRITE;
     } else {
       assert(ctx->op->may_read());
-      type = ObjectContext::RWState::RWREAD;
-      ctx->lock_to_release = OpContext::R_LOCK;
+      ctx->lock_type = ObjectContext::RWState::RWREAD;
     }
 
     if (ctx->snapset_obc) {
       assert(!ctx->obc->obs.exists);
-      if (ctx->snapset_obc->get_lock_type(ctx->op, type)) {
-	ctx->release_snapset_obc = true;
-      } else {
-	ctx->lock_to_release = OpContext::NONE;
+      if (!ctx->lock_manager.get_lock_type(
+	    ctx->lock_type,
+	    ctx->snapset_obc->obs.oi.soid,
+	    ctx->snapset_obc,
+	    ctx->op)) {
+	ctx->lock_type = ObjectContext::RWState::RWNONE;
 	return false;
       }
     }
-    if (ctx->obc->get_lock_type(ctx->op, type)) {
+    if (ctx->lock_manager.get_lock_type(
+	  ctx->lock_type,
+	  ctx->obc->obs.oi.soid,
+	  ctx->obc,
+	  ctx->op)) {
       return true;
     } else {
       assert(!ctx->snapset_obc);
-      ctx->lock_to_release = OpContext::NONE;
+      ctx->lock_type = ObjectContext::RWState::RWNONE;
       return false;
     }
   }
@@ -789,97 +816,50 @@ protected:
    *
    * @param ctx [in] ctx to clean up
    */
-  void close_op_ctx(OpContext *ctx, int r) {
-    release_op_ctx_locks(ctx);
-    delete ctx->op_t;
-    ctx->op_t = NULL;
-    ctx->finish(r);
+  void close_op_ctx(OpContext *ctx) {
+    release_object_locks(ctx->lock_manager);
+    ctx->op_t.reset();
+    for (auto p = ctx->on_finish.begin();
+	 p != ctx->on_finish.end();
+	 ctx->on_finish.erase(p++)) {
+      (*p)();
+    }
     delete ctx;
   }
 
   /**
-   * Releases ctx locks
+   * Releases locks
    *
-   * @param ctx [in] ctx to clean up
+   * @param manager [in] manager with locks to release
    */
-  void release_op_ctx_locks(OpContext *ctx) {
-    list<OpRequestRef> to_req;
+  void release_object_locks(
+    ObcLockManager &lock_manager) {
+    list<pair<hobject_t, list<OpRequestRef> > > to_req;
     bool requeue_recovery = false;
-    bool requeue_recovery_clone = false;
-    bool requeue_recovery_snapset = false;
-    bool requeue_snaptrimmer = false;
-    bool requeue_snaptrimmer_clone = false;
-    bool requeue_snaptrimmer_snapset = false;
-    switch (ctx->lock_to_release) {
-    case OpContext::W_LOCK:
-      if (ctx->snapset_obc && ctx->release_snapset_obc) {
-	ctx->snapset_obc->put_write(
-	  &to_req,
-	  &requeue_recovery_snapset,
-	  &requeue_snaptrimmer_snapset);
-	ctx->release_snapset_obc = false;
-      }
-      ctx->obc->put_write(
-	&to_req,
-	&requeue_recovery,
-	&requeue_snaptrimmer);
-      if (ctx->clone_obc)
-	ctx->clone_obc->put_write(
-	  &to_req,
-	  &requeue_recovery_clone,
-	  &requeue_snaptrimmer_clone);
-      break;
-    case OpContext::E_LOCK:
-      if (ctx->snapset_obc && ctx->release_snapset_obc) {
-	ctx->snapset_obc->put_excl(
-	  &to_req,
-	  &requeue_recovery_snapset,
-	  &requeue_snaptrimmer_snapset);
-	ctx->release_snapset_obc = false;
-      }
-      ctx->obc->put_excl(
-	&to_req,
-	&requeue_recovery,
-	&requeue_snaptrimmer);
-      if (ctx->clone_obc)
-	ctx->clone_obc->put_write(
-	  &to_req,
-	  &requeue_recovery_clone,
-	  &requeue_snaptrimmer_clone);
-      break;
-    case OpContext::R_LOCK:
-      if (ctx->snapset_obc && ctx->release_snapset_obc) {
-	ctx->snapset_obc->put_read(&to_req);
-	ctx->release_snapset_obc = false;
-      }
-      ctx->obc->put_read(&to_req);
-      break;
-    case OpContext::NONE:
-      break;
-    default:
-      assert(0);
-    };
-    assert(ctx->release_snapset_obc == false);
-    ctx->lock_to_release = OpContext::NONE;
-    if (requeue_recovery || requeue_recovery_clone || requeue_recovery_snapset)
+    bool requeue_snaptrim = false;
+    lock_manager.put_locks(
+      &to_req,
+      &requeue_recovery,
+      &requeue_snaptrim);
+    if (requeue_recovery)
       osd->recovery_wq.queue(this);
-    if (requeue_snaptrimmer ||
-	requeue_snaptrimmer_clone ||
-	requeue_snaptrimmer_snapset)
+    if (requeue_snaptrim)
       queue_snap_trim();
 
     if (!to_req.empty()) {
-      assert(ctx->obc);
       // requeue at front of scrub blocking queue if we are blocked by scrub
-      if (scrubber.write_blocked_by_scrub(ctx->obc->obs.oi.soid.get_head(),
-					  get_sort_bitwise())) {
-	waiting_for_active.splice(
-	  waiting_for_active.begin(),
-	  to_req,
-	  to_req.begin(),
-	  to_req.end());
-      } else {
-	requeue_ops(to_req);
+      for (auto &&p: to_req) {
+	if (scrubber.write_blocked_by_scrub(
+	      p.first.get_head(),
+	      get_sort_bitwise())) {
+	  waiting_for_active.splice(
+	    waiting_for_active.begin(),
+	    p.second,
+	    p.second.begin(),
+	    p.second.end());
+	} else {
+	  requeue_ops(p.second);
+	}
       }
     }
   }
@@ -893,12 +873,33 @@ protected:
   void repop_all_applied(RepGather *repop);
   void repop_all_committed(RepGather *repop);
   void eval_repop(RepGather*);
-  void issue_repop(RepGather *repop);
-  RepGather *new_repop(OpContext *ctx, ObjectContextRef obc, ceph_tid_t rep_tid);
+  void issue_repop(RepGather *repop, OpContext *ctx);
+  RepGather *new_repop(
+    OpContext *ctx,
+    ObjectContextRef obc,
+    ceph_tid_t rep_tid);
+  RepGather *new_repop(
+    ObcLockManager &&manager,
+    boost::optional<std::function<void(void)> > &&on_complete);
   void remove_repop(RepGather *repop);
 
-  RepGather *simple_repop_create(ObjectContextRef obc);
-  void simple_repop_submit(RepGather *repop);
+  OpContextUPtr simple_opc_create(ObjectContextRef obc);
+  void simple_opc_submit(OpContextUPtr ctx);
+
+  /**
+   * Merge entries atomically into all actingbackfill osds
+   * adjusting missing and recovery state as necessary
+   */
+  void submit_log_entries(
+    const list<pg_log_entry_t> &entries,
+    ObcLockManager &&manager,
+    boost::optional<std::function<void(void)> > &&on_complete);
+  struct LogUpdateCtx {
+    boost::intrusive_ptr<RepGather> repop;
+    set<pg_shard_t> waiting_on;
+  };
+  map<ceph_tid_t, LogUpdateCtx> log_entry_update_waiting_on;
+
 
   // hot/cold tracking
   HitSetRef hit_set;        ///< currently accumulating HitSet
@@ -911,7 +912,7 @@ protected:
   void hit_set_create();    ///< create a new HitSet
   void hit_set_persist();   ///< persist hit info
   bool hit_set_apply_log(); ///< apply log entries to update in-memory HitSet
-  void hit_set_trim(RepGather *repop, unsigned max); ///< discard old HitSets
+  void hit_set_trim(OpContextUPtr &ctx, unsigned max); ///< discard old HitSets
   void hit_set_in_memory_trim(uint32_t max_in_memory); ///< discard old in memory HitSets
   void hit_set_remove_all();
 
@@ -1395,7 +1396,7 @@ protected:
   int start_flush(
     OpRequestRef op, ObjectContextRef obc,
     bool blocking, hobject_t *pmissing,
-    Context *on_flush);
+    boost::optional<std::function<void()>> &&on_flush);
   void finish_flush(hobject_t oid, ceph_tid_t tid, int r);
   int try_flush_mark_clean(FlushOpRef fop);
   void cancel_flush(FlushOpRef fop, bool requeue);
@@ -1412,7 +1413,6 @@ protected:
   virtual void _scrub(
     ScrubMap &map,
     const std::map<hobject_t, pair<uint32_t, uint32_t>, hobject_t::BitwiseComparator> &missing_digest);
-  void _scrub_digest_updated();
   virtual void _scrub_clear_state();
   virtual void _scrub_finish();
   object_stat_collection_t scrub_cstat;
@@ -1456,8 +1456,13 @@ public:
 	       const PGPool &_pool, spg_t p);
   ~ReplicatedPG() {}
 
-  int do_command(cmdmap_t cmdmap, ostream& ss, bufferlist& idata,
-		 bufferlist& odata);
+  int do_command(
+    cmdmap_t cmdmap,
+    ostream& ss,
+    bufferlist& idata,
+    bufferlist& odata,
+    ConnectionRef conn,
+    ceph_tid_t tid) override;
 
   void do_request(
     OpRequestRef& op,
@@ -1472,7 +1477,7 @@ public:
     ThreadPool::TPHandle &handle);
   void do_backfill(OpRequestRef op);
 
-  RepGather *trim_object(const hobject_t &coid);
+  OpContextUPtr trim_object(const hobject_t &coid);
   void snap_trimmer(epoch_t e);
   int do_osd_ops(OpContext *ctx, vector<OSDOp>& ops);
 
@@ -1483,6 +1488,7 @@ public:
 
   void do_osd_op_effects(OpContext *ctx, const ConnectionRef& conn);
 private:
+  int do_scrub_ls(MOSDOp *op, OSDOp *osd_op);
   hobject_t earliest_backfill() const;
   bool check_src_targ(const hobject_t& soid, const hobject_t& toid) const;
 
@@ -1509,7 +1515,8 @@ private:
     const char *mode,
     bool allow_incomplete_clones,
     boost::optional<snapid_t> target,
-    vector<snapid_t>::reverse_iterator *curclone);
+    vector<snapid_t>::reverse_iterator *curclone,
+    inconsistent_snapset_wrapper &snap_error);
 
 public:
   coll_t get_coll() {
@@ -1540,7 +1547,7 @@ private:
   };
   struct SnapTrimmer : public boost::statechart::state_machine< SnapTrimmer, NotTrimming > {
     ReplicatedPG *pg;
-    set<RepGather *> repops;
+    set<hobject_t, hobject_t::BitwiseComparator> in_flight;
     snapid_t snap_to_trim;
     bool need_share_pg_info;
     explicit SnapTrimmer(ReplicatedPG *pg) : pg(pg), need_share_pg_info(false) {}
@@ -1611,12 +1618,20 @@ public:
   void wait_for_blocked_object(const hobject_t& soid, OpRequestRef op);
   void kick_object_context_blocked(ObjectContextRef obc);
 
-  void mark_all_unfound_lost(int what);
+  void mark_all_unfound_lost(
+    int what,
+    ConnectionRef con,
+    ceph_tid_t tid);
   eversion_t pick_newest_available(const hobject_t& oid);
   ObjectContextRef mark_object_lost(ObjectStore::Transaction *t,
 				  const hobject_t& oid, eversion_t version,
 				  utime_t mtime, int what);
-  void _finish_mark_all_unfound_lost(list<ObjectContextRef>& obcs);
+
+  void do_update_log_missing(
+    OpRequestRef &op);
+
+  void do_update_log_missing_reply(
+    OpRequestRef &op);
 
   void on_role_change();
   void on_pool_change();
@@ -1665,10 +1680,6 @@ inline ostream& operator<<(ostream& out, ReplicatedPG::RepGather& repop)
       << " rep_tid=" << repop.rep_tid 
       << " committed?=" << repop.all_committed
       << " applied?=" << repop.all_applied;
-  if (repop.ctx->lock_to_release != ReplicatedPG::OpContext::NONE)
-    out << " lock=" << (int)repop.ctx->lock_to_release;
-  if (repop.ctx->op)
-    out << " op=" << *(repop.ctx->op->get_req());
   out << ")";
   return out;
 }
diff --git a/src/osd/ScrubStore.cc b/src/osd/ScrubStore.cc
new file mode 100644
index 0000000..08dcae8
--- /dev/null
+++ b/src/osd/ScrubStore.cc
@@ -0,0 +1,195 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- 
+// vim: ts=8 sw=2 smarttab
+
+#include "ScrubStore.h"
+#include "osd_types.h"
+#include "common/scrub_types.h"
+#include "include/rados/rados_types.hpp"
+
+namespace {
+ghobject_t make_scrub_object(const spg_t& pgid)
+{
+  ostringstream ss;
+  ss << "scrub_" << pgid;
+  return pgid.make_temp_ghobject(ss.str());
+}
+
+string first_object_key(int64_t pool)
+{
+  auto hoid = hobject_t(object_t(),
+			"",
+			0,
+			0x00000000,
+			pool,
+			"");
+  hoid.build_hash_cache();
+  return "SCRUB_OBJ_" + hoid.to_str();
+}
+
+// the object_key should be unique across pools
+string to_object_key(int64_t pool, const librados::object_id_t& oid)
+{
+  auto hoid = hobject_t(object_t(oid.name),
+			oid.locator, // key
+			oid.snap,
+			0,		// hash
+			pool,
+			oid.nspace);
+  hoid.build_hash_cache();
+  return "SCRUB_OBJ_" + hoid.to_str();
+}
+
+string last_object_key(int64_t pool)
+{
+  auto hoid = hobject_t(object_t(),
+			"",
+			0,
+			0xffffffff,
+			pool,
+			"");
+  hoid.build_hash_cache();
+  return "SCRUB_OBJ_" + hoid.to_str();
+}
+
+string first_snap_key(int64_t pool)
+{
+  // scrub object is per spg_t object, so we can misuse the hash (pg.seed) for
+  // the representing the minimal and maximum keys. and this relies on how
+  // hobject_t::to_str() works: hex(pool).hex(revhash).
+  auto hoid = hobject_t(object_t(),
+			"",
+			0,
+			0x00000000,
+			pool,
+			"");
+  hoid.build_hash_cache();
+  return "SCRUB_SS_" + hoid.to_str();
+}
+
+string to_snap_key(int64_t pool, const librados::object_id_t& oid)
+{
+  auto hoid = hobject_t(object_t(oid.name),
+			oid.locator, // key
+			oid.snap,
+			0x77777777, // hash
+			pool,
+			oid.nspace);
+  hoid.build_hash_cache();
+  return "SCRUB_SS_" + hoid.to_str();
+}
+
+string last_snap_key(int64_t pool)
+{
+  auto hoid = hobject_t(object_t(),
+			"",
+			0,
+			0xffffffff,
+			pool,
+			"");
+  hoid.build_hash_cache();
+  return "SCRUB_SS_" + hoid.to_str();
+}
+}
+
+namespace Scrub {
+
+Store*
+Store::create(ObjectStore* store,
+	      ObjectStore::Transaction* t,
+	      const spg_t& pgid,
+	      const coll_t& coll)
+{
+  assert(store);
+  assert(t);
+  ghobject_t oid = make_scrub_object(pgid);
+  t->touch(coll, oid);
+  return new Store{coll, oid, store};
+}
+
+Store::Store(const coll_t& coll, const ghobject_t& oid, ObjectStore* store)
+  : coll(coll),
+    hoid(oid),
+    driver(store, coll, hoid),
+    backend(&driver)
+{}
+
+Store::~Store()
+{
+  assert(results.empty());
+}
+
+void Store::add_object_error(int64_t pool, const inconsistent_obj_wrapper& e)
+{
+  bufferlist bl;
+  e.encode(bl);
+  results[to_object_key(pool, e.object)] = bl;
+}
+
+void Store::add_snap_error(int64_t pool, const inconsistent_snapset_wrapper& e)
+{
+  bufferlist bl;
+  e.encode(bl);
+  results[to_snap_key(pool, e.object)] = bl;
+}
+
+bool Store::empty() const
+{
+  return results.empty();
+}
+
+void Store::flush(ObjectStore::Transaction* t)
+{
+  if (t) {
+    OSDriver::OSTransaction txn = driver.get_transaction(t);
+    backend.set_keys(results, &txn);
+  }
+  results.clear();
+}
+
+void Store::cleanup(ObjectStore::Transaction* t)
+{
+  t->remove(coll, hoid);
+}
+
+std::vector<bufferlist>
+Store::get_snap_errors(ObjectStore* store,
+		       int64_t pool,
+		       const librados::object_id_t& start,
+		       uint64_t max_return)
+{
+  const string begin = (start.name.empty() ?
+			first_snap_key(pool) : to_snap_key(pool, start));
+  const string end = last_snap_key(pool);
+  return get_errors(store, begin, end, max_return);     
+}
+
+std::vector<bufferlist>
+Store::get_object_errors(ObjectStore* store,
+			 int64_t pool,
+			 const librados::object_id_t& start,
+			 uint64_t max_return)
+{
+  const string begin = (start.name.empty() ?
+			first_object_key(pool) : to_object_key(pool, start));
+  const string end = last_object_key(pool);
+  return get_errors(store, begin, end, max_return);
+}
+
+std::vector<bufferlist>
+Store::get_errors(ObjectStore* store,
+		  const string& begin,
+		  const string& end,
+		  uint64_t max_return)
+{
+  vector<bufferlist> errors;
+  auto next = std::make_pair(begin, bufferlist{});
+  while (max_return && !backend.get_next(next.first, &next)) {
+    if (next.first >= end)
+      break;
+    errors.push_back(next.second);
+    max_return--;
+  }
+  return errors;
+}
+
+} // namespace Scrub
diff --git a/src/osd/ScrubStore.h b/src/osd/ScrubStore.h
new file mode 100644
index 0000000..39c7da6
--- /dev/null
+++ b/src/osd/ScrubStore.h
@@ -0,0 +1,55 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+
+#ifndef CEPH_SCRUB_RESULT_H
+#define CEPH_SCRUB_RESULT_H
+
+#include "SnapMapper.h"		// for OSDriver
+#include "common/map_cacher.hpp"
+
+namespace librados {
+  struct object_id_t;
+}
+
+struct inconsistent_obj_wrapper;
+struct inconsistent_snapset_wrapper;
+
+namespace Scrub {
+
+class Store {
+public:
+  ~Store();
+  static Store* create(ObjectStore* store,
+		       ObjectStore::Transaction* t,
+		       const spg_t& pgid,
+		       const coll_t& coll);
+  void add_object_error(int64_t pool, const inconsistent_obj_wrapper& e);
+  void add_snap_error(int64_t pool, const inconsistent_snapset_wrapper& e);
+  bool empty() const;
+  void flush(ObjectStore::Transaction *);
+  void cleanup(ObjectStore::Transaction *);
+  std::vector<bufferlist> get_snap_errors(ObjectStore* store,
+					  int64_t pool,
+					  const librados::object_id_t& start,
+					  uint64_t max_return);
+  std::vector<bufferlist> get_object_errors(ObjectStore* store,
+					    int64_t pool,
+					    const librados::object_id_t& start,
+					    uint64_t max_return);
+private:
+  Store(const coll_t& coll, const ghobject_t& oid, ObjectStore* store);
+  std::vector<bufferlist> get_errors(ObjectStore* store,
+				     const string& start, const string& end,
+				     uint64_t max_return);
+private:
+  const coll_t coll;
+  const ghobject_t hoid;
+  // a temp object holding mappings from seq-id to inconsistencies found in
+  // scrubbing
+  OSDriver driver;
+  MapCacher::MapCacher<std::string, bufferlist> backend;
+  map<string, bufferlist> results;
+};
+}
+
+#endif // CEPH_SCRUB_RESULT_H
diff --git a/src/osd/osd_types.cc b/src/osd/osd_types.cc
index 2d874e5..96e6795 100644
--- a/src/osd/osd_types.cc
+++ b/src/osd/osd_types.cc
@@ -121,22 +121,6 @@ string ceph_osd_op_flag_string(unsigned flags)
   return string("-");
 }
 
-const char *num_char_map = "0123456789abcdef";
-template<typename T, const int base>
-static inline
-char* ritoa(T u, char *buf) {
-  if (u < base) {
-    *--buf = num_char_map[u];
-    return buf;
-  }
- 
-  while (u) {
-    *--buf = num_char_map[u % base]; 
-    u /= base;
-  }
-  return buf;
-}
-
 void pg_shard_t::encode(bufferlist &bl) const
 {
   ENCODE_START(1, 1, bl);
@@ -463,7 +447,7 @@ char *spg_t::calc_name(char *buf, const char *suffix_backwords) const
     *--buf = *suffix_backwords++;
 
   if (!is_no_shard()) {
-    buf = ritoa<int8_t, 10>(shard.id, buf);
+    buf = ritoa<uint8_t, 10>((uint8_t)shard.id, buf);
     *--buf = 's';
   }
 
@@ -667,6 +651,7 @@ bool coll_t::parse(const std::string& s)
 
 void coll_t::encode(bufferlist& bl) const
 {
+  // when changing this, remember to update encoded_size() too.
   if (is_temp()) {
     // can't express this as v2...
     __u8 struct_v = 3;
@@ -682,6 +667,33 @@ void coll_t::encode(bufferlist& bl) const
   }
 }
 
+size_t coll_t::encoded_size() const
+{
+  size_t r = sizeof(__u8);
+  if (is_temp()) {
+    // v3
+    r += sizeof(__u32);
+    if (_str) {
+      r += strlen(_str);
+    }
+  } else {
+      // v2
+      // 1. type
+      r += sizeof(__u8);
+      // 2. pgid
+      //  - encoding header
+      r += sizeof(ceph_le32) + 2 * sizeof(__u8);
+      // - pg_t
+      r += sizeof(__u8) + sizeof(uint64_t) + 2 * sizeof(uint32_t);
+      // - shard_id_t
+      r += sizeof(int8_t);
+      // 3. snapid_t
+      r += sizeof(uint64_t);
+  }
+
+  return r;
+}
+
 void coll_t::decode(bufferlist::iterator& bl)
 {
   __u8 struct_v;
@@ -876,6 +888,10 @@ int pg_string_state(const std::string& state)
     type = PG_STATE_RECOVERY_WAIT;
   else if (state == "undersized")
     type = PG_STATE_UNDERSIZED;
+  else if (state == "activating")
+    type = PG_STATE_ACTIVATING;
+  else if (state == "peered")
+    type = PG_STATE_PEERED;
   else
     type = -1;
   return type;
@@ -884,9 +900,12 @@ int pg_string_state(const std::string& state)
 // -- eversion_t --
 string eversion_t::get_key_name() const
 {
-  char key[40];
-  snprintf(
-    key, sizeof(key), "%010u.%020llu", epoch, (long long unsigned)version);
+  char key[32];
+  // Below is equivalent of sprintf("%010u.%020llu");
+  key[31] = 0;
+  ritoa<uint64_t, 10, 20>(version, key + 31);
+  key[10] = '.';
+  ritoa<uint32_t, 10, 10>(epoch, key + 10);
   return string(key);
 }
 
@@ -1105,8 +1124,8 @@ void pg_pool_t::dump(Formatter *f) const
   f->dump_int("min_size", get_min_size());
   f->dump_int("crush_ruleset", get_crush_ruleset());
   f->dump_int("object_hash", get_object_hash());
-  f->dump_int("pg_num", get_pg_num());
-  f->dump_int("pg_placement_num", get_pgp_num());
+  f->dump_unsigned("pg_num", get_pg_num());
+  f->dump_unsigned("pg_placement_num", get_pgp_num());
   f->dump_unsigned("crash_replay_interval", get_crash_replay_interval());
   f->dump_stream("last_change") << get_last_change();
   f->dump_stream("last_force_op_resend") << get_last_force_op_resend();
@@ -1122,11 +1141,11 @@ void pg_pool_t::dump(Formatter *f) const
   }
   f->close_section();
   f->dump_stream("removed_snaps") << removed_snaps;
-  f->dump_int("quota_max_bytes", quota_max_bytes);
-  f->dump_int("quota_max_objects", quota_max_objects);
+  f->dump_unsigned("quota_max_bytes", quota_max_bytes);
+  f->dump_unsigned("quota_max_objects", quota_max_objects);
   f->open_array_section("tiers");
   for (set<uint64_t>::const_iterator p = tiers.begin(); p != tiers.end(); ++p)
-    f->dump_int("pool_id", *p);
+    f->dump_unsigned("pool_id", *p);
   f->close_section();
   f->dump_int("tier_of", tier_of);
   f->dump_int("read_tier", read_tier);
@@ -2518,6 +2537,7 @@ bool operator==(const pg_stat_t& l, const pg_stat_t& r)
     l.last_fresh == r.last_fresh &&
     l.last_change == r.last_change &&
     l.last_active == r.last_active &&
+    l.last_peered == r.last_peered &&
     l.last_clean == r.last_clean &&
     l.last_unstale == r.last_unstale &&
     l.last_undegraded == r.last_undegraded &&
@@ -2542,6 +2562,7 @@ bool operator==(const pg_stat_t& l, const pg_stat_t& r)
     l.mapping_epoch == r.mapping_epoch &&
     l.blocked_by == r.blocked_by &&
     l.last_became_active == r.last_became_active &&
+    l.last_became_peered == r.last_became_peered &&
     l.dirty_stats_invalid == r.dirty_stats_invalid &&
     l.omap_stats_invalid == r.omap_stats_invalid &&
     l.hitset_stats_invalid == r.hitset_stats_invalid &&
@@ -3169,20 +3190,14 @@ ostream& operator<<(ostream& out, const pg_interval_t& i)
 // -- pg_query_t --
 
 void pg_query_t::encode(bufferlist &bl, uint64_t features) const {
-  if (features & CEPH_FEATURE_QUERY_T) {
-    ENCODE_START(3, 2, bl);
-    ::encode(type, bl);
-    ::encode(since, bl);
-    history.encode(bl);
-    ::encode(epoch_sent, bl);
-    ::encode(to, bl);
-    ::encode(from, bl);
-    ENCODE_FINISH(bl);
-  } else {
-    ::encode(type, bl);
-    ::encode(since, bl);
-    history.encode(bl);
-  }
+  ENCODE_START(3, 2, bl);
+  ::encode(type, bl);
+  ::encode(since, bl);
+  history.encode(bl);
+  ::encode(epoch_sent, bl);
+  ::encode(to, bl);
+  ::encode(from, bl);
+  ENCODE_FINISH(bl);
 }
 
 void pg_query_t::decode(bufferlist::iterator &bl) {
@@ -3272,6 +3287,12 @@ void ObjectModDesc::visit(Visitor *visitor) const
 	visitor->update_snaps(snaps);
 	break;
       }
+      case TRY_DELETE: {
+	version_t old_version;
+	::decode(old_version, bp);
+	visitor->try_rmobject(old_version);
+	break;
+      }
       default:
 	assert(0 == "Invalid rollback code");
       }
@@ -4041,28 +4062,6 @@ void object_copy_data_t::decode_classic(bufferlist::iterator& bl)
 
 void object_copy_data_t::encode(bufferlist& bl, uint64_t features) const
 {
-  if ((features & CEPH_FEATURE_OSD_OBJECT_DIGEST) == 0) {
-    ENCODE_START(4, 1, bl);
-    ::encode(size, bl);
-    ::encode(mtime, bl);
-    ::encode((__u32)0, bl);  // was category; no longer used
-    ::encode(attrs, bl);
-    ::encode(data, bl);
-    if (omap_data.length())
-      bl.append(omap_data);
-    else
-      ::encode((__u32)0, bl);
-    ::encode(cursor, bl);
-    ::encode(omap_header, bl);
-    ::encode(snaps, bl);
-    ::encode(snap_seq, bl);
-    ::encode(flags, bl);
-    ::encode(data_digest, bl);
-    ::encode(omap_digest, bl);
-    ENCODE_FINISH(bl);
-    return;
-  }
-
   ENCODE_START(7, 5, bl);
   ::encode(size, bl);
   ::encode(mtime, bl);
@@ -5498,6 +5497,8 @@ ostream& operator<<(ostream& out, const OSDOp& op)
     case CEPH_OSD_OP_PG_HITSET_GET:
       out << " " << utime_t(op.op.hit_set_get.stamp);
       break;
+    case CEPH_OSD_OP_SCRUBLS:
+      break;
     }
   } else if (ceph_osd_op_type_multi(op.op.op)) {
     switch (op.op.op) {
diff --git a/src/osd/osd_types.h b/src/osd/osd_types.h
index 84770d3..adfe50f 100644
--- a/src/osd/osd_types.h
+++ b/src/osd/osd_types.h
@@ -277,7 +277,7 @@ enum {
 
 // pg stuff
 
-#define OSD_SUPERBLOCK_POBJECT ghobject_t(hobject_t(sobject_t(object_t("osd_superblock"), 0)))
+#define OSD_SUPERBLOCK_GOBJECT ghobject_t(hobject_t(sobject_t(object_t("osd_superblock"), 0)))
 
 // placement seed (a hash value)
 typedef uint32_t ps_t;
@@ -497,11 +497,20 @@ struct spg_t {
     DECODE_FINISH(bl);
   }
 
-  hobject_t make_temp_object(const string& name) {
+  hobject_t make_temp_hobject(const string& name) const {
     return hobject_t(object_t(name), "", CEPH_NOSNAP,
 		     pgid.ps(),
 		     hobject_t::POOL_TEMP_START - pgid.pool(), "");
   }
+
+  ghobject_t make_temp_ghobject(const string& name) const {
+    return ghobject_t(
+      hobject_t(object_t(name), "", CEPH_NOSNAP,
+		pgid.ps(),
+		hobject_t::POOL_TEMP_START - pgid.pool(), ""),
+      ghobject_t::NO_GEN,
+      shard);
+  }
 };
 WRITE_CLASS_ENCODER(spg_t)
 WRITE_EQ_OPERATORS_2(spg_t, pgid, shard)
@@ -624,6 +633,7 @@ public:
 
   void encode(bufferlist& bl) const;
   void decode(bufferlist::iterator& bl);
+  size_t encoded_size() const;
 
   inline bool operator==(const coll_t& rhs) const {
     // only compare type if meta
@@ -1766,7 +1776,7 @@ struct pg_stat_t {
   utime_t last_fresh;   // last reported
   utime_t last_change;  // new state != previous state
   utime_t last_active;  // state & PG_STATE_ACTIVE
-  utime_t last_peered;  // state & PG_STATE_ACTIVE || state & PG_STATE_ACTIVE
+  utime_t last_peered;  // state & PG_STATE_ACTIVE || state & PG_STATE_PEERED
   utime_t last_clean;   // state & PG_STATE_CLEAN
   utime_t last_unstale; // (state & PG_STATE_STALE) == 0
   utime_t last_undegraded; // (state & PG_STATE_DEGRADED) == 0
@@ -2360,6 +2370,15 @@ public:
     virtual void append(uint64_t old_offset) {}
     virtual void setattrs(map<string, boost::optional<bufferlist> > &attrs) {}
     virtual void rmobject(version_t old_version) {}
+    /**
+     * Used to support the unfound_lost_delete log event: if the stashed
+     * version exists, we unstash it, otherwise, we do nothing.  This way
+     * each replica rolls back to whatever state it had prior to the attempt
+     * at mark unfound lost delete
+     */
+    virtual void try_rmobject(version_t old_version) {
+      rmobject(old_version);
+    }
     virtual void create() {}
     virtual void update_snaps(set<snapid_t> &old_snaps) {}
     virtual ~Visitor() {}
@@ -2371,7 +2390,8 @@ public:
     SETATTRS = 2,
     DELETE = 3,
     CREATE = 4,
-    UPDATE_SNAPS = 5
+    UPDATE_SNAPS = 5,
+    TRY_DELETE = 6
   };
   ObjectModDesc() : can_local_rollback(true), rollback_info_completed(false) {}
   void claim(ObjectModDesc &other) {
@@ -2431,6 +2451,16 @@ public:
     rollback_info_completed = true;
     return true;
   }
+  bool try_rmobject(version_t deletion_version) {
+    if (!can_local_rollback || rollback_info_completed)
+      return false;
+    ENCODE_START(1, 1, bl);
+    append_id(TRY_DELETE);
+    ::encode(deletion_version, bl);
+    ENCODE_FINISH(bl);
+    rollback_info_completed = true;
+    return true;
+  }
   void create() {
     if (!can_local_rollback || rollback_info_completed)
       return;
@@ -3655,6 +3685,22 @@ public:
       *requeue_snaptrimmer = true;
     }
   }
+  void put_lock_type(
+    ObjectContext::RWState::State type,
+    list<OpRequestRef> *to_wake,
+    bool *requeue_recovery,
+    bool *requeue_snaptrimmer) {
+    switch (type) {
+    case ObjectContext::RWState::RWWRITE:
+      return put_write(to_wake, requeue_recovery, requeue_snaptrimmer);
+    case ObjectContext::RWState::RWREAD:
+      return put_read(to_wake);
+    case ObjectContext::RWState::RWEXCL:
+      return put_excl(to_wake, requeue_recovery, requeue_snaptrimmer);
+    default:
+      assert(0 == "invalid lock type");
+    }
+  }
   bool is_request_pending() {
     return (rwstate.count > 0);
   }
@@ -3750,6 +3796,104 @@ inline ostream& operator<<(ostream& out, const ObjectContext& obc)
 
 ostream& operator<<(ostream& out, const object_info_t& oi);
 
+class ObcLockManager {
+  struct ObjectLockState {
+    ObjectContextRef obc;
+    ObjectContext::RWState::State type;
+    ObjectLockState(
+      ObjectContextRef obc,
+      ObjectContext::RWState::State type)
+      : obc(obc), type(type) {}
+  };
+  map<hobject_t, ObjectLockState, hobject_t::BitwiseComparator> locks;
+public:
+  ObcLockManager() = default;
+  ObcLockManager(ObcLockManager &&) = default;
+  ObcLockManager(const ObcLockManager &) = delete;
+  bool empty() const {
+    return locks.empty();
+  }
+  bool get_lock_type(
+    ObjectContext::RWState::State type,
+    const hobject_t &hoid,
+    ObjectContextRef obc,
+    OpRequestRef op) {
+    assert(locks.find(hoid) == locks.end());
+    if (obc->get_lock_type(op, type)) {
+      locks.insert(make_pair(hoid, ObjectLockState(obc, type)));
+      return true;
+    } else {
+      return false;
+    }
+  }
+  /// Get write lock, ignore starvation
+  bool take_write_lock(
+    const hobject_t &hoid,
+    ObjectContextRef obc) {
+    assert(locks.find(hoid) == locks.end());
+    if (obc->rwstate.take_write_lock()) {
+      locks.insert(
+	make_pair(
+	  hoid, ObjectLockState(obc, ObjectContext::RWState::RWWRITE)));
+      return true;
+    } else {
+      return false;
+    }
+  }
+  /// Get write lock for snap trim
+  bool get_snaptrimmer_write(
+    const hobject_t &hoid,
+    ObjectContextRef obc) {
+    assert(locks.find(hoid) == locks.end());
+    if (obc->get_snaptrimmer_write()) {
+      locks.insert(
+	make_pair(
+	  hoid, ObjectLockState(obc, ObjectContext::RWState::RWWRITE)));
+      return true;
+    } else {
+      return false;
+    }
+  }
+  /// Get write lock greedy
+  bool get_write_greedy(
+    const hobject_t &hoid,
+    ObjectContextRef obc,
+    OpRequestRef op) {
+    assert(locks.find(hoid) == locks.end());
+    if (obc->get_write_greedy(op)) {
+      locks.insert(
+	make_pair(
+	  hoid, ObjectLockState(obc, ObjectContext::RWState::RWWRITE)));
+      return true;
+    } else {
+      return false;
+    }
+  }
+  void put_locks(
+    list<pair<hobject_t, list<OpRequestRef> > > *to_requeue,
+    bool *requeue_recovery,
+    bool *requeue_snaptrimmer) {
+    for (auto p: locks) {
+      list<OpRequestRef> _to_requeue;
+      p.second.obc->put_lock_type(
+	p.second.type,
+	&_to_requeue,
+	requeue_recovery,
+	requeue_snaptrimmer);
+      if (to_requeue) {
+	to_requeue->push_back(
+	  make_pair(
+	    p.second.obc->obs.oi.soid,
+	    std::move(_to_requeue)));
+      }
+    }
+    locks.clear();
+  }
+  ~ObcLockManager() {
+    assert(locks.empty());
+  }
+};
+
 
 
 // Object recovery
@@ -4162,4 +4306,29 @@ enum scrub_error_type {
   DEEP_ERROR,
   SHALLOW_ERROR
 };
+
+// PromoteCounter
+
+struct PromoteCounter {
+  atomic64_t attempts, objects, bytes;
+
+  void attempt() {
+    attempts.inc();
+  }
+
+  void finish(uint64_t size) {
+    objects.inc();
+    bytes.add(size);
+  }
+
+  void sample_and_attenuate(uint64_t *a, uint64_t *o, uint64_t *b) {
+    *a = attempts.read();
+    *o = objects.read();
+    *b = bytes.read();
+    attempts.set(*a / 2);
+    objects.set(*o / 2);
+    bytes.set(*b / 2);
+  }
+};
+
 #endif
diff --git a/src/osdc/Filer.cc b/src/osdc/Filer.cc
index bf5f23c..f64a122 100644
--- a/src/osdc/Filer.cc
+++ b/src/osdc/Filer.cc
@@ -67,7 +67,7 @@ public:
 };
 
 int Filer::probe(inodeno_t ino,
-		 ceph_file_layout *layout,
+		 file_layout_t *layout,
 		 snapid_t snapid,
 		 uint64_t start_from,
 		 uint64_t *end, // LB, when !fwd
@@ -90,7 +90,7 @@ int Filer::probe(inodeno_t ino,
 }
 
 int Filer::probe(inodeno_t ino,
-		 ceph_file_layout *layout,
+		 file_layout_t *layout,
 		 snapid_t snapid,
 		 uint64_t start_from,
 		 uint64_t *end, // LB, when !fwd
@@ -111,12 +111,11 @@ int Filer::probe(inodeno_t ino,
   return probe_impl(probe, layout, start_from, end);
 }
 
-int Filer::probe_impl(Probe* probe, ceph_file_layout *layout,
+int Filer::probe_impl(Probe* probe, file_layout_t *layout,
 		      uint64_t start_from, uint64_t *end) // LB, when !fwd
 {
   // period (bytes before we jump unto a new set of object(s))
-  uint64_t period = (uint64_t)layout->fl_stripe_count *
-    (uint64_t)layout->fl_object_size;
+  uint64_t period = layout->get_period();
 
   // start with 1+ periods.
   probe->probing_len = period;
@@ -268,8 +267,7 @@ bool Filer::_probed(Probe *probe, const object_t& oid, uint64_t size,
     // keep probing!
     ldout(cct, 10) << "_probed probing further" << dendl;
 
-    uint64_t period = (uint64_t)probe->layout.fl_stripe_count *
-      (uint64_t)probe->layout.fl_object_size;
+    uint64_t period = probe->layout.get_period();
     if (probe->fwd) {
       probe->probing_off += probe->probing_len;
       assert(probe->probing_off % period == 0);
@@ -303,14 +301,14 @@ struct PurgeRange {
   typedef std::lock_guard<std::mutex> lock_guard;
   typedef std::unique_lock<std::mutex> unique_lock;
   inodeno_t ino;
-  ceph_file_layout layout;
+  file_layout_t layout;
   SnapContext snapc;
   uint64_t first, num;
   ceph::real_time mtime;
   int flags;
   Context *oncommit;
   int uncommitted;
-  PurgeRange(inodeno_t i, ceph_file_layout& l, const SnapContext& sc,
+  PurgeRange(inodeno_t i, file_layout_t& l, const SnapContext& sc,
 	     uint64_t fo, uint64_t no, ceph::real_time t, int fl,
 	     Context *fin)
     : ino(i), layout(l), snapc(sc), first(fo), num(no), mtime(t), flags(fl),
@@ -318,7 +316,7 @@ struct PurgeRange {
 };
 
 int Filer::purge_range(inodeno_t ino,
-		       ceph_file_layout *layout,
+		       file_layout_t *layout,
 		       const SnapContext& snapc,
 		       uint64_t first_obj, uint64_t num_obj,
 		       ceph::real_time mtime,
diff --git a/src/osdc/Filer.h b/src/osdc/Filer.h
index 0c7b862..96c11b8 100644
--- a/src/osdc/Filer.h
+++ b/src/osdc/Filer.h
@@ -56,7 +56,7 @@ class Filer {
     typedef std::lock_guard<std::mutex> lock_guard;
     typedef std::unique_lock<std::mutex> unique_lock;
     inodeno_t ino;
-    ceph_file_layout layout;
+    file_layout_t layout;
     snapid_t snapid;
 
     uint64_t *psize;
@@ -80,7 +80,7 @@ class Filer {
     int err;
     bool found_size;
 
-    Probe(inodeno_t i, ceph_file_layout &l, snapid_t sn,
+    Probe(inodeno_t i, file_layout_t &l, snapid_t sn,
 	  uint64_t f, uint64_t *e, ceph::real_time *m, int fl, bool fw,
 	  Context *c) :
       ino(i), layout(l), snapid(sn),
@@ -88,7 +88,7 @@ class Filer {
       probing_off(f), probing_len(0),
       err(0), found_size(false) {}
 
-    Probe(inodeno_t i, ceph_file_layout &l, snapid_t sn,
+    Probe(inodeno_t i, file_layout_t &l, snapid_t sn,
 	  uint64_t f, uint64_t *e, utime_t *m, int fl, bool fw,
 	  Context *c) :
       ino(i), layout(l), snapid(sn),
@@ -118,7 +118,7 @@ class Filer {
   /*** async file interface.  scatter/gather as needed. ***/
 
   int read(inodeno_t ino,
-	   ceph_file_layout *layout,
+	   file_layout_t *layout,
 	   snapid_t snap,
 	   uint64_t offset,
 	   uint64_t len,
@@ -134,7 +134,7 @@ class Filer {
   }
 
   int read_trunc(inodeno_t ino,
-		 ceph_file_layout *layout,
+		 file_layout_t *layout,
 		 snapid_t snap,
 		 uint64_t offset,
 		 uint64_t len,
@@ -154,7 +154,7 @@ class Filer {
   }
 
   int write(inodeno_t ino,
-	    ceph_file_layout *layout,
+	    file_layout_t *layout,
 	    const SnapContext& snapc,
 	    uint64_t offset,
 	    uint64_t len,
@@ -172,7 +172,7 @@ class Filer {
   }
 
   int write_trunc(inodeno_t ino,
-		  ceph_file_layout *layout,
+		  file_layout_t *layout,
 		  const SnapContext& snapc,
 		  uint64_t offset,
 		  uint64_t len,
@@ -193,7 +193,7 @@ class Filer {
   }
 
   int truncate(inodeno_t ino,
-	       ceph_file_layout *layout,
+	       file_layout_t *layout,
 	       const SnapContext& snapc,
 	       uint64_t offset,
 	       uint64_t len,
@@ -232,7 +232,7 @@ class Filer {
   }
 
   int zero(inodeno_t ino,
-	   ceph_file_layout *layout,
+	   file_layout_t *layout,
 	   const SnapContext& snapc,
 	   uint64_t offset,
 	   uint64_t len,
@@ -244,7 +244,7 @@ class Filer {
     vector<ObjectExtent> extents;
     Striper::file_to_extents(cct, ino, layout, offset, len, 0, extents);
     if (extents.size() == 1) {
-      if (extents[0].offset == 0 && extents[0].length == layout->fl_object_size
+      if (extents[0].offset == 0 && extents[0].length == layout->object_size
 	  && (!keep_first || extents[0].objectno != 0))
 	objecter->remove(extents[0].oid, extents[0].oloc,
 			 snapc, mtime, flags, onack, oncommit);
@@ -258,7 +258,7 @@ class Filer {
       for (vector<ObjectExtent>::iterator p = extents.begin();
 	   p != extents.end();
 	   ++p) {
-	if (p->offset == 0 && p->length == layout->fl_object_size &&
+	if (p->offset == 0 && p->length == layout->object_size &&
 	    (!keep_first || p->objectno != 0))
 	  objecter->remove(p->oid, p->oloc,
 			   snapc, mtime, flags,
@@ -277,7 +277,7 @@ class Filer {
   }
 
   int zero(inodeno_t ino,
-	   ceph_file_layout *layout,
+	   file_layout_t *layout,
 	   const SnapContext& snapc,
 	   uint64_t offset,
 	   uint64_t len,
@@ -294,7 +294,7 @@ class Filer {
   }
   // purge range of ino.### objects
   int purge_range(inodeno_t ino,
-		  ceph_file_layout *layout,
+		  file_layout_t *layout,
 		  const SnapContext& snapc,
 		  uint64_t first_obj, uint64_t num_obj,
 		  ceph::real_time mtime,
@@ -307,7 +307,7 @@ class Filer {
    *  and whether we stop when we find data, or hole.
    */
   int probe(inodeno_t ino,
-	    ceph_file_layout *layout,
+	    file_layout_t *layout,
 	    snapid_t snapid,
 	    uint64_t start_from,
 	    uint64_t *end,
@@ -317,7 +317,7 @@ class Filer {
 	    Context *onfinish);
 
   int probe(inodeno_t ino,
-	    ceph_file_layout *layout,
+	    file_layout_t *layout,
 	    snapid_t snapid,
 	    uint64_t start_from,
 	    uint64_t *end,
@@ -329,7 +329,7 @@ class Filer {
   }
 
   int probe(inodeno_t ino,
-	    ceph_file_layout *layout,
+	    file_layout_t *layout,
 	    snapid_t snapid,
 	    uint64_t start_from,
 	    uint64_t *end,
@@ -339,7 +339,7 @@ class Filer {
 	    Context *onfinish);
 
 private:
-  int probe_impl(Probe* probe, ceph_file_layout *layout,
+  int probe_impl(Probe* probe, file_layout_t *layout,
 		 uint64_t start_from, uint64_t *end);
 };
 
diff --git a/src/osdc/Journaler.cc b/src/osdc/Journaler.cc
index 487bb60..fb38a08 100644
--- a/src/osdc/Journaler.cc
+++ b/src/osdc/Journaler.cc
@@ -45,7 +45,7 @@ void Journaler::set_writeable()
   readonly = false;
 }
 
-void Journaler::create(ceph_file_layout *l, stream_format_t const sf)
+void Journaler::create(file_layout_t *l, stream_format_t const sf)
 {
   lock_guard lk(lock);
 
@@ -58,24 +58,23 @@ void Journaler::create(ceph_file_layout *l, stream_format_t const sf)
 
   prezeroing_pos = prezero_pos = write_pos = flush_pos = safe_pos =
     read_pos = requested_pos = received_pos =
-    expire_pos = trimming_pos = trimmed_pos =
-    (uint64_t)layout.fl_stripe_count * layout.fl_object_size;
+    expire_pos = trimming_pos = trimmed_pos = layout.get_period();
 
   ldout(cct, 1) << "created blank journal at inode 0x" << std::hex << ino
 		<< std::dec << ", format=" << stream_format << dendl;
 }
 
-void Journaler::set_layout(ceph_file_layout const *l)
+void Journaler::set_layout(file_layout_t const *l)
 {
     lock_guard lk(lock);
     _set_layout(l);
 }
 
-void Journaler::_set_layout(ceph_file_layout const *l)
+void Journaler::_set_layout(file_layout_t const *l)
 {
   layout = *l;
 
-  assert(layout.fl_pg_pool == pg_pool);
+  assert(layout.pool_id == pg_pool);
   last_written.layout = layout;
   last_committed.layout = layout;
 
@@ -84,7 +83,7 @@ void Journaler::_set_layout(ceph_file_layout const *l)
   uint64_t periods = cct->_conf->journaler_prefetch_periods;
   if (periods < 2)
     periods = 2;  // we need at least 2 periods to make progress.
-  fetch_len = layout.fl_stripe_count * layout.fl_object_size * periods;
+  fetch_len = layout.get_period() * periods;
 }
 
 
@@ -536,9 +535,8 @@ uint64_t Journaler::append_entry(bufferlist& bl)
 
   if (!cct->_conf->journaler_allow_split_entries) {
     // will we span a stripe boundary?
-    int p = layout.fl_stripe_unit;
-    if (write_pos / p != (write_pos + (int64_t)(bl.length() +
-						sizeof(s))) / p) {
+    int p = layout.stripe_unit;
+    if (write_pos / p != (write_pos + (int64_t)(bl.length() + sizeof(s))) / p) {
       // yes.
       // move write_pos forward.
       int64_t owp = write_pos;
diff --git a/src/osdc/Journaler.h b/src/osdc/Journaler.h
index da397f6..c37cfce 100644
--- a/src/osdc/Journaler.h
+++ b/src/osdc/Journaler.h
@@ -130,14 +130,14 @@ public:
     uint64_t unused_field;
     uint64_t write_pos;
     string magic;
-    ceph_file_layout layout; //< The mapping from byte stream offsets
+    file_layout_t layout; //< The mapping from byte stream offsets
 			     //  to RADOS objects
     stream_format_t stream_format; //< The encoding of LogEvents
 				   //  within the journal byte stream
 
     Header(const char *m="") :
       trimmed_pos(0), expire_pos(0), unused_field(0), write_pos(0), magic(m),
-      stream_format(-1) {memset(&layout, 0, sizeof(layout));
+      stream_format(-1) {
     }
 
     void encode(bufferlist &bl) const {
@@ -147,7 +147,7 @@ public:
       ::encode(expire_pos, bl);
       ::encode(unused_field, bl);
       ::encode(write_pos, bl);
-      ::encode(layout, bl);
+      ::encode(layout, bl, 0);  // encode in legacy format
       ::encode(stream_format, bl);
       ENCODE_FINISH(bl);
     }
@@ -175,16 +175,7 @@ public:
 	f->dump_unsigned("expire_pos", expire_pos);
 	f->dump_unsigned("trimmed_pos", trimmed_pos);
 	f->dump_unsigned("stream_format", stream_format);
-	f->open_object_section("layout");
-	{
-	  f->dump_unsigned("stripe_unit", layout.fl_stripe_unit);
-	  f->dump_unsigned("stripe_count", layout.fl_stripe_count);
-	  f->dump_unsigned("object_size", layout.fl_object_size);
-	  f->dump_unsigned("cas_hash", layout.fl_cas_hash);
-	  f->dump_unsigned("object_stripe_unit", layout.fl_object_stripe_unit);
-	  f->dump_unsigned("pg_pool", layout.fl_pg_pool);
-	}
-	f->close_section(); // layout
+	f->dump_object("layout", layout);
       }
       f->close_section(); // journal_header
     }
@@ -223,7 +214,7 @@ private:
   inodeno_t ino;
   int64_t pg_pool;
   bool readonly;
-  ceph_file_layout layout;
+  file_layout_t layout;
   uint32_t stream_format;
   JournalStream journal_stream;
 
@@ -281,7 +272,7 @@ private:
   friend class C_WriteHead;
 
   void _reread_head(Context *onfinish);
-  void _set_layout(ceph_file_layout const *l);
+  void _set_layout(file_layout_t const *l);
   list<Context*> waitfor_recover;
   void _read_head(Context *on_finish, bufferlist *bl);
   void _finish_read_head(int r, bufferlist& bl);
@@ -416,7 +407,6 @@ public:
     expire_pos(0), trimming_pos(0), trimmed_pos(0), readable(false),
     write_iohint(0), stopping(false)
   {
-    memset(&layout, 0, sizeof(layout));
   }
 
   /* reset
@@ -452,7 +442,7 @@ public:
   // Asynchronous operations
   // =======================
   void erase(Context *completion);
-  void create(ceph_file_layout *layout, stream_format_t const sf);
+  void create(file_layout_t *layout, stream_format_t const sf);
   void recover(Context *onfinish);
   void reread_head(Context *onfinish);
   void reread_head_and_probe(Context *onfinish);
@@ -463,7 +453,7 @@ public:
 
   // Synchronous setters
   // ===================
-  void set_layout(ceph_file_layout const *l);
+  void set_layout(file_layout_t const *l);
   void set_readonly();
   void set_writeable();
   void set_write_pos(int64_t p) {
@@ -513,9 +503,9 @@ public:
   // ===================
   // TODO: need some locks on reads for true safety
   uint64_t get_layout_period() const {
-    return (uint64_t)layout.fl_stripe_count * (uint64_t)layout.fl_object_size;
+    return layout.get_period();
   }
-  ceph_file_layout& get_layout() { return layout; }
+  file_layout_t& get_layout() { return layout; }
   bool is_active() { return state == STATE_ACTIVE; }
   int get_error() { return error; }
   bool is_readonly() { return readonly; }
diff --git a/src/osdc/ObjectCacher.h b/src/osdc/ObjectCacher.h
index b2ec73d..b95c3ba 100644
--- a/src/osdc/ObjectCacher.h
+++ b/src/osdc/ObjectCacher.h
@@ -63,7 +63,6 @@ class ObjectCacher {
   struct OSDRead {
     vector<ObjectExtent> extents;
     snapid_t snap;
-    map<object_t, bufferlist*> read_data;  // bits of data as they come back
     bufferlist *bl;
     int fadvise_flags;
     OSDRead(snapid_t s, bufferlist *b, int f)
@@ -742,7 +741,7 @@ public:
   // file functions
 
   /*** async+caching (non-blocking) file interface ***/
-  int file_is_cached(ObjectSet *oset, ceph_file_layout *layout,
+  int file_is_cached(ObjectSet *oset, file_layout_t *layout,
 		     snapid_t snapid, loff_t offset, uint64_t len) {
     vector<ObjectExtent> extents;
     Striper::file_to_extents(cct, oset->ino, layout, offset, len,
@@ -750,7 +749,7 @@ public:
     return is_cached(oset, extents, snapid);
   }
 
-  int file_read(ObjectSet *oset, ceph_file_layout *layout, snapid_t snapid,
+  int file_read(ObjectSet *oset, file_layout_t *layout, snapid_t snapid,
 		loff_t offset, uint64_t len, bufferlist *bl, int flags,
 		Context *onfinish) {
     OSDRead *rd = prepare_read(snapid, bl, flags);
@@ -759,7 +758,7 @@ public:
     return readx(rd, oset, onfinish);
   }
 
-  int file_write(ObjectSet *oset, ceph_file_layout *layout,
+  int file_write(ObjectSet *oset, file_layout_t *layout,
 		 const SnapContext& snapc, loff_t offset, uint64_t len,
 		 bufferlist& bl, ceph::real_time mtime, int flags) {
     OSDWrite *wr = prepare_write(snapc, bl, mtime, flags, 0);
@@ -768,7 +767,7 @@ public:
     return writex(wr, oset, NULL);
   }
 
-  bool file_flush(ObjectSet *oset, ceph_file_layout *layout,
+  bool file_flush(ObjectSet *oset, file_layout_t *layout,
 		  const SnapContext& snapc, loff_t offset, uint64_t len,
 		  Context *onfinish) {
     vector<ObjectExtent> extents;
diff --git a/src/osdc/Objecter.cc b/src/osdc/Objecter.cc
index 9ace054..56b91e5 100644
--- a/src/osdc/Objecter.cc
+++ b/src/osdc/Objecter.cc
@@ -46,7 +46,7 @@
 
 #include "common/config.h"
 #include "common/perf_counters.h"
-#include "common/Finisher.h"
+#include "common/scrub_types.h"
 #include "include/str_list.h"
 #include "common/errno.h"
 
@@ -466,13 +466,6 @@ void Objecter::shutdown()
     tick_event = 0;
   }
 
-  if (m_request_state_hook) {
-    AdminSocket* admin_socket = cct->get_admin_socket();
-    admin_socket->unregister_command("objecter_requests");
-    delete m_request_state_hook;
-    m_request_state_hook = NULL;
-  }
-
   if (logger) {
     cct->get_perfcounters_collection()->remove(logger);
     delete logger;
@@ -481,6 +474,16 @@ void Objecter::shutdown()
 
   // Let go of Objecter write lock so timer thread can shutdown
   wl.unlock();
+
+  // Outside of lock to avoid cycle WRT calls to RequestStateHook
+  // This is safe because we guarantee no concurrent calls to
+  // shutdown() with the ::initialized check at start.
+  if (m_request_state_hook) {
+    AdminSocket* admin_socket = cct->get_admin_socket();
+    admin_socket->unregister_command("objecter_requests");
+    delete m_request_state_hook;
+    m_request_state_hook = NULL;
+  }
 }
 
 void Objecter::_send_linger(LingerOp *info,
@@ -594,7 +597,6 @@ struct C_DoWatchError : public Context {
 
     info->finished_async();
     info->put();
-    objecter->_linger_callback_finish();
   }
 };
 
@@ -619,7 +621,6 @@ void Objecter::_linger_reconnect(LingerOp *info, int r)
       info->last_error = r;
       if (info->watch_context) {
 	finisher->queue(new C_DoWatchError(this, info, r));
-	_linger_callback_queue();
       }
     }
     wl.unlock();
@@ -684,7 +685,6 @@ void Objecter::_linger_ping(LingerOp *info, int r, mono_time sent,
       info->last_error = r;
       if (info->watch_context) {
 	finisher->queue(new C_DoWatchError(this, info, r));
-	_linger_callback_queue();
       }
     }
   } else {
@@ -867,7 +867,6 @@ void Objecter::handle_watch_notify(MWatchNotify *m)
       info->last_error = -ENOTCONN;
       if (info->watch_context) {
 	finisher->queue(new C_DoWatchError(this, info, -ENOTCONN));
-	_linger_callback_queue();
       }
     }
   } else if (!info->is_watch) {
@@ -888,7 +887,6 @@ void Objecter::handle_watch_notify(MWatchNotify *m)
     }
   } else {
     finisher->queue(new C_DoWatchNotify(this, info, m));
-    _linger_callback_queue();
   }
 }
 
@@ -922,7 +920,6 @@ void Objecter::_do_watch_notify(LingerOp *info, MWatchNotify *m)
   info->finished_async();
   info->put();
   m->put();
-  _linger_callback_finish();
 }
 
 bool Objecter::ms_dispatch(Message *m)
@@ -2006,7 +2003,7 @@ void Objecter::tick()
 
   // look for laggy requests
   auto cutoff = ceph::mono_clock::now();
-  cutoff -= osd_timeout;  // timeout
+  cutoff -= ceph::make_timespan(cct->_conf->objecter_timeout);  // timeout
 
   unsigned laggy_ops = 0;
 
@@ -4864,7 +4861,8 @@ void Objecter::enumerate_objects(
     const hobject_t &start,
     const hobject_t &end,
     const uint32_t max,
-    std::list<librados::ListObjectImpl> *result,
+    const bufferlist &filter_bl,
+    std::list<librados::ListObjectImpl> *result, 
     hobject_t *next,
     Context *on_finish)
 {
@@ -4912,11 +4910,8 @@ void Objecter::enumerate_objects(
   C_EnumerateReply *on_ack = new C_EnumerateReply(
       this, next, result, end, pool_id, on_finish);
 
-  // Construct pgls operation
-  bufferlist filter; // FIXME pass in?
-
   ObjectOperation op;
-  op.pg_nls(max, filter, start, 0);
+  op.pg_nls(max, filter_bl, start, 0);
 
   // Issue.  See you later in _enumerate_reply
   object_locator_t oloc(pool_id, ns);
@@ -5013,3 +5008,94 @@ void Objecter::_enumerate_reply(
   return;
 }
 
+namespace {
+  using namespace librados;
+
+  template <typename T>
+  void do_decode(std::vector<T>& items, std::vector<bufferlist>& bls)
+  {
+    for (auto bl : bls) {
+      auto p = bl.begin();
+      T t;
+      decode(t, p);
+      items.push_back(t);
+    }
+  }
+
+  struct C_ObjectOperation_scrub_ls : public Context {
+    bufferlist bl;
+    uint32_t *interval;
+    std::vector<inconsistent_obj_t> *objects = nullptr;
+    std::vector<inconsistent_snapset_t> *snapsets = nullptr;
+    int *rval;
+
+    C_ObjectOperation_scrub_ls(uint32_t *interval,
+			       std::vector<inconsistent_obj_t> *objects,
+			       int *rval)
+      : interval(interval), objects(objects), rval(rval) {}
+    C_ObjectOperation_scrub_ls(uint32_t *interval,
+			       std::vector<inconsistent_snapset_t> *snapsets,
+			       int *rval)
+      : interval(interval), snapsets(snapsets), rval(rval) {}
+    void finish(int r) override {
+      if (r < 0 && r != -EAGAIN)
+	return;
+      try {
+	decode();
+      } catch (buffer::error&) {
+	if (rval)
+	  *rval = -EIO;
+      }
+    }
+  private:
+    void decode() {
+      scrub_ls_result_t result;
+      auto p = bl.begin();
+      result.decode(p);
+      *interval = result.interval;
+      if (objects) {
+	do_decode(*objects, result.vals);
+      } else {
+	do_decode(*snapsets, result.vals);
+      }
+    }
+  };
+
+  template <typename T>
+  void do_scrub_ls(::ObjectOperation *op,
+		   const scrub_ls_arg_t& arg,
+		   std::vector<T> *items,
+		   uint32_t *interval,
+		   int *rval)
+  {
+    OSDOp& osd_op = op->add_op(CEPH_OSD_OP_SCRUBLS);
+    op->flags |= CEPH_OSD_FLAG_PGOP;
+    assert(interval);
+    arg.encode(osd_op.indata);
+    unsigned p = op->ops.size() - 1;
+    auto *h = new C_ObjectOperation_scrub_ls{interval, items, rval};
+    op->out_handler[p] = h;
+    op->out_bl[p] = &h->bl;
+    op->out_rval[p] = rval;
+  }
+}
+
+void ::ObjectOperation::scrub_ls(const librados::object_id_t& start_after,
+				 uint64_t max_to_get,
+				 std::vector<librados::inconsistent_obj_t> *objects,
+				 uint32_t *interval,
+				 int *rval)
+{
+  scrub_ls_arg_t arg = {*interval, 0, start_after, max_to_get};
+  do_scrub_ls(this, arg, objects, interval, rval);
+}
+
+void ::ObjectOperation::scrub_ls(const librados::object_id_t& start_after,
+				 uint64_t max_to_get,
+				 std::vector<librados::inconsistent_snapset_t> *snapsets,
+				 uint32_t *interval,
+				 int *rval)
+{
+  scrub_ls_arg_t arg = {*interval, 1, start_after, max_to_get};
+  do_scrub_ls(this, arg, snapsets, interval, rval);
+}
diff --git a/src/osdc/Objecter.h b/src/osdc/Objecter.h
index 8e156a0..05b29bb 100644
--- a/src/osdc/Objecter.h
+++ b/src/osdc/Objecter.h
@@ -33,6 +33,7 @@
 #include "common/admin_socket.h"
 #include "common/ceph_time.h"
 #include "common/ceph_timer.h"
+#include "common/Finisher.h"
 #include "common/shunique_lock.h"
 
 #include "messages/MOSDOp.h"
@@ -193,7 +194,7 @@ struct ObjectOperation {
     osd_op.op.pgls.start_epoch = start_epoch;
     ::encode(cookie, osd_op.indata);
   }
-  void add_pgls_filter(int op, uint64_t count, bufferlist& filter,
+  void add_pgls_filter(int op, uint64_t count, const bufferlist& filter,
 		       collection_list_handle_t cookie, epoch_t start_epoch) {
     OSDOp& osd_op = add_op(op);
     osd_op.op.pgls.count = count;
@@ -225,7 +226,7 @@ struct ObjectOperation {
     flags |= CEPH_OSD_FLAG_PGOP;
   }
 
-  void pg_nls(uint64_t count, bufferlist& filter,
+  void pg_nls(uint64_t count, const bufferlist& filter,
 	      collection_list_handle_t cookie, epoch_t start_epoch) {
     if (filter.length() == 0)
       add_pgls(CEPH_OSD_OP_PGNLS, count, cookie, start_epoch);
@@ -235,6 +236,17 @@ struct ObjectOperation {
     flags |= CEPH_OSD_FLAG_PGOP;
   }
 
+  void scrub_ls(const librados::object_id_t& start_after,
+		uint64_t max_to_get,
+		std::vector<librados::inconsistent_obj_t> *objects,
+		uint32_t *interval,
+		int *rval);
+  void scrub_ls(const librados::object_id_t& start_after,
+		uint64_t max_to_get,
+		std::vector<librados::inconsistent_snapset_t> *objects,
+		uint32_t *interval,
+		int *rval);
+
   void create(bool excl) {
     OSDOp& o = add_op(CEPH_OSD_OP_CREATE);
     o.op.flags = (excl ? CEPH_OSD_OP_FLAG_EXCL : 0);
@@ -245,10 +257,11 @@ struct ObjectOperation {
     uint64_t *psize;
     ceph::real_time *pmtime;
     time_t *ptime;
+    struct timespec *pts;
     int *prval;
-    C_ObjectOperation_stat(uint64_t *ps, ceph::real_time *pm, time_t *pt,
+    C_ObjectOperation_stat(uint64_t *ps, ceph::real_time *pm, time_t *pt, struct timespec *_pts,
 			   int *prval)
-      : psize(ps), pmtime(pm), ptime(pt), prval(prval) {}
+      : psize(ps), pmtime(pm), ptime(pt), pts(_pts), prval(prval) {}
     void finish(int r) {
       if (r >= 0) {
 	bufferlist::iterator p = bl.begin();
@@ -263,6 +276,8 @@ struct ObjectOperation {
 	    *pmtime = mtime;
 	  if (ptime)
 	    *ptime = ceph::real_clock::to_time_t(mtime);
+	  if (pts)
+	    *pts = ceph::real_clock::to_timespec(mtime);
 	} catch (buffer::error& e) {
 	  if (prval)
 	    *prval = -EIO;
@@ -273,7 +288,7 @@ struct ObjectOperation {
   void stat(uint64_t *psize, ceph::real_time *pmtime, int *prval) {
     add_op(CEPH_OSD_OP_STAT);
     unsigned p = ops.size() - 1;
-    C_ObjectOperation_stat *h = new C_ObjectOperation_stat(psize, pmtime, NULL,
+    C_ObjectOperation_stat *h = new C_ObjectOperation_stat(psize, pmtime, NULL, NULL,
 							   prval);
     out_bl[p] = &h->bl;
     out_handler[p] = h;
@@ -282,13 +297,21 @@ struct ObjectOperation {
   void stat(uint64_t *psize, time_t *ptime, int *prval) {
     add_op(CEPH_OSD_OP_STAT);
     unsigned p = ops.size() - 1;
-    C_ObjectOperation_stat *h = new C_ObjectOperation_stat(psize, NULL, ptime,
+    C_ObjectOperation_stat *h = new C_ObjectOperation_stat(psize, NULL, ptime, NULL,
+							   prval);
+    out_bl[p] = &h->bl;
+    out_handler[p] = h;
+    out_rval[p] = prval;
+  }
+  void stat(uint64_t *psize, struct timespec *pts, int *prval) {
+    add_op(CEPH_OSD_OP_STAT);
+    unsigned p = ops.size() - 1;
+    C_ObjectOperation_stat *h = new C_ObjectOperation_stat(psize, NULL, NULL, pts,
 							   prval);
     out_bl[p] = &h->bl;
     out_handler[p] = h;
     out_rval[p] = prval;
   }
-
   // object data
   void read(uint64_t off, uint64_t len, bufferlist *pbl, int *prval,
 	    Context* ctx) {
@@ -1793,11 +1816,6 @@ public:
   map<uint64_t, LingerOp*> linger_ops;
   // we use this just to confirm a cookie is valid before dereferencing the ptr
   set<LingerOp*> linger_ops_set;
-  int num_linger_callbacks;
-  std::mutex linger_callback_lock;
-  typedef std::unique_lock<std::mutex> unique_linger_cb_lock;
-  typedef std::lock_guard<std::mutex> linger_cb_lock_guard;
-  std::condition_variable linger_callback_cond;
 
   map<ceph_tid_t,PoolStatOp*> poolstat_ops;
   map<ceph_tid_t,StatfsOp*> statfs_ops;
@@ -1866,23 +1884,10 @@ public:
 		    uint32_t register_gen);
   int _normalize_watch_error(int r);
 
-  void _linger_callback_queue() {
-    linger_cb_lock_guard l(linger_callback_lock);
-    ++num_linger_callbacks;
-  }
-  void _linger_callback_finish() {
-    linger_cb_lock_guard l(linger_callback_lock);
-    if (--num_linger_callbacks == 0)
-      linger_callback_cond.notify_all();
-    assert(num_linger_callbacks >= 0);
-  }
   friend class C_DoWatchError;
 public:
-  void linger_callback_flush() {
-    unique_linger_cb_lock l(linger_callback_lock);
-    linger_callback_cond.wait(l, [this]() {
-	return num_linger_callbacks <= 0;
-      });
+  void linger_callback_flush(Context *ctx) {
+    finisher->queue(ctx);
   }
 
 private:
@@ -1958,7 +1963,7 @@ private:
     keep_balanced_budget(false), honor_osdmap_full(true),
     last_seen_osdmap_version(0), last_seen_pgmap_version(0),
     logger(NULL), tick_event(0), m_request_state_hook(NULL),
-    num_linger_callbacks(0), num_homeless_ops(0),
+    num_homeless_ops(0),
     homeless_session(new OSDSession(cct, -1)),
     mon_timeout(ceph::make_timespan(mon_timeout)),
     osd_timeout(ceph::make_timespan(osd_timeout)),
@@ -2625,6 +2630,7 @@ public:
     const hobject_t &start,
     const hobject_t &end,
     const uint32_t max,
+    const bufferlist &filter_bl,
     std::list<librados::ListObjectImpl> *result, 
     hobject_t *next,
     Context *on_finish);
diff --git a/src/osdc/Striper.cc b/src/osdc/Striper.cc
index 4395106..851f067 100644
--- a/src/osdc/Striper.cc
+++ b/src/osdc/Striper.cc
@@ -27,7 +27,7 @@
 
 
 void Striper::file_to_extents(CephContext *cct, const char *object_format,
-			      const ceph_file_layout *layout,
+			      const file_layout_t *layout,
 			      uint64_t offset, uint64_t len,
 			      uint64_t trunc_size,
 			      vector<ObjectExtent>& extents,
@@ -41,7 +41,7 @@ void Striper::file_to_extents(CephContext *cct, const char *object_format,
 
 void Striper::file_to_extents(
   CephContext *cct, const char *object_format,
-  const ceph_file_layout *layout,
+  const file_layout_t *layout,
   uint64_t offset, uint64_t len,
   uint64_t trunc_size,
   map<object_t,vector<ObjectExtent> >& object_extents,
@@ -58,9 +58,9 @@ void Striper::file_to_extents(
    * buffer.. hence ObjectExtent.buffer_extents
    */
 
-  __u32 object_size = layout->fl_object_size;
-  __u32 su = layout->fl_stripe_unit;
-  __u32 stripe_count = layout->fl_stripe_count;
+  __u32 object_size = layout->object_size;
+  __u32 su = layout->stripe_unit;
+  __u32 stripe_count = layout->stripe_count;
   assert(object_size >= su);
   if (stripe_count == 1) {
     ldout(cct, 20) << " sc is one, reset su to os" << dendl;
@@ -161,16 +161,16 @@ void Striper::assimilate_extents(
   }
 }
 
-void Striper::extent_to_file(CephContext *cct, ceph_file_layout *layout,
+void Striper::extent_to_file(CephContext *cct, file_layout_t *layout,
 			   uint64_t objectno, uint64_t off, uint64_t len,
 			   vector<pair<uint64_t, uint64_t> >& extents)
 {
   ldout(cct, 10) << "extent_to_file " << objectno << " " << off << "~"
 		 << len << dendl;
 
-  __u32 object_size = layout->fl_object_size;
-  __u32 su = layout->fl_stripe_unit;
-  __u32 stripe_count = layout->fl_stripe_count;
+  __u32 object_size = layout->object_size;
+  __u32 su = layout->stripe_unit;
+  __u32 stripe_count = layout->stripe_count;
   assert(object_size >= su);
   uint64_t stripes_per_object = object_size / su;
   ldout(cct, 20) << " stripes_per_object " << stripes_per_object << dendl;
@@ -199,16 +199,16 @@ void Striper::extent_to_file(CephContext *cct, ceph_file_layout *layout,
 }
 
 uint64_t Striper::object_truncate_size(CephContext *cct,
-				       const ceph_file_layout *layout,
+				       const file_layout_t *layout,
 				       uint64_t objectno, uint64_t trunc_size)
 {
   uint64_t obj_trunc_size;
   if (trunc_size == 0 || trunc_size == (uint64_t)-1) {
     obj_trunc_size = trunc_size;
   } else {
-    __u32 object_size = layout->fl_object_size;
-    __u32 su = layout->fl_stripe_unit;
-    __u32 stripe_count = layout->fl_stripe_count;
+    __u32 object_size = layout->object_size;
+    __u32 su = layout->stripe_unit;
+    __u32 stripe_count = layout->stripe_count;
     assert(object_size >= su);
     uint64_t stripes_per_object = object_size / su;
 
@@ -237,12 +237,13 @@ uint64_t Striper::object_truncate_size(CephContext *cct,
 		 << trunc_size << "->" << obj_trunc_size << dendl;
   return obj_trunc_size;
 }
-uint64_t Striper::get_num_objects(const ceph_file_layout& layout,
+
+uint64_t Striper::get_num_objects(const file_layout_t& layout,
 				  uint64_t size)
 {
-  __u32 object_size = layout.fl_object_size;
-  __u32 stripe_unit = layout.fl_stripe_unit;
-  __u32 stripe_count = layout.fl_stripe_count;
+  __u32 object_size = layout.object_size;
+  __u32 stripe_unit = layout.stripe_unit;
+  __u32 stripe_count = layout.stripe_count;
   uint64_t period = (uint64_t)stripe_count * object_size;
   uint64_t num_periods = (size + period - 1) / period;
   uint64_t remainder_bytes = size % period;
@@ -270,6 +271,7 @@ void Striper::StripedReadResult::add_partial_result(
     size_t actual = MIN(bl.length(), p->second);
     bl.splice(0, actual, &r.first);
     r.second = p->second;
+    total_intended_len += r.second;
   }
 }
 
@@ -297,6 +299,7 @@ void Striper::StripedReadResult::add_partial_sparse_result(
 	ldout(cct, 20) << "  s at end" << dendl;
 	pair<bufferlist, uint64_t>& r = partial[tofs];
 	r.second = tlen;
+	total_intended_len += r.second;
 	break;
       }
 
@@ -315,6 +318,7 @@ void Striper::StripedReadResult::add_partial_sparse_result(
 	size_t gap = MIN(s->first - bl_off, tlen);
 	ldout(cct, 20) << "  s gap " << gap << ", skipping" << dendl;
 	r.second = gap;
+	total_intended_len += r.second;
 	bl_off += gap;
 	tofs += gap;
 	tlen -= gap;
@@ -332,6 +336,7 @@ void Striper::StripedReadResult::add_partial_sparse_result(
 	pair<bufferlist, uint64_t>& r = partial[tofs];
 	bl.splice(0, actual, &r.first);
 	r.second = actual;
+	total_intended_len += r.second;
 	bl_off += actual;
 	tofs += actual;
 	tlen -= actual;
@@ -369,7 +374,9 @@ void Striper::StripedReadResult::assemble_result(CephContext *cct,
     size_t len = p->second.first.length();
     if (len < p->second.second) {
       if (zero_tail || bl.length()) {
-	bl.append_zero(p->second.second - len);
+        bufferptr bp(p->second.second - len);
+        bp.zero();
+        bl.push_front(std::move(bp));
 	bl.claim_prepend(p->second.first);
       } else {
 	bl.claim_prepend(p->second.first);
@@ -382,3 +389,38 @@ void Striper::StripedReadResult::assemble_result(CephContext *cct,
   partial.clear();
 }
 
+void Striper::StripedReadResult::assemble_result(CephContext *cct, char *buffer, size_t length)
+{
+
+  assert(buffer && length == total_intended_len);
+
+  map<uint64_t,pair<bufferlist,uint64_t> >::reverse_iterator p = partial.rbegin();
+  if (p == partial.rend())
+    return;
+
+  uint64_t curr = length;
+  uint64_t end = p->first + p->second.second;
+  while (p != partial.rend()) {
+    // sanity check
+    ldout(cct, 0) << "assemble_result(" << this << ") " << p->first << "~" << p->second.second
+		   << " " << p->second.first.length() << " bytes"
+		   << dendl;
+    assert(p->first == end - p->second.second);
+    end = p->first;
+
+    size_t len = p->second.first.length();
+    assert(curr >= p->second.second);
+    curr -= p->second.second;
+    if (len < p->second.second) {
+      if (len)
+	p->second.first.copy(0, len, buffer + curr);
+      memset(buffer + curr + len, 0, p->second.second - len);
+    } else {
+      p->second.first.copy(0, len, buffer + curr);
+    }
+    ++p;
+  }
+  partial.clear();
+  assert(curr == 0);
+}
+
diff --git a/src/osdc/Striper.h b/src/osdc/Striper.h
index 228045a..6d110e9 100644
--- a/src/osdc/Striper.h
+++ b/src/osdc/Striper.h
@@ -29,21 +29,21 @@ class CephContext;
      * ranges in objects on (primary) osds)
      */
     static void file_to_extents(CephContext *cct, const char *object_format,
-				const ceph_file_layout *layout,
+				const file_layout_t *layout,
 				uint64_t offset, uint64_t len,
 				uint64_t trunc_size,
 				map<object_t, vector<ObjectExtent> >& extents,
 				uint64_t buffer_offset=0);
 
     static void file_to_extents(CephContext *cct, const char *object_format,
-				const ceph_file_layout *layout,
+				const file_layout_t *layout,
 				uint64_t offset, uint64_t len,
 				uint64_t trunc_size,
 				vector<ObjectExtent>& extents,
 				uint64_t buffer_offset=0);
 
     static void file_to_extents(CephContext *cct, inodeno_t ino,
-				const ceph_file_layout *layout,
+				const file_layout_t *layout,
 				uint64_t offset, uint64_t len,
 				uint64_t trunc_size,
 				vector<ObjectExtent>& extents) {
@@ -61,15 +61,15 @@ class CephContext;
     /**
      * reverse map an object extent to file extents
      */
-    static void extent_to_file(CephContext *cct, ceph_file_layout *layout,
+    static void extent_to_file(CephContext *cct, file_layout_t *layout,
 			       uint64_t objectno, uint64_t off, uint64_t len,
 			       vector<pair<uint64_t, uint64_t> >& extents);
 
     static uint64_t object_truncate_size(
-      CephContext *cct, const ceph_file_layout *layout,
+      CephContext *cct, const file_layout_t *layout,
       uint64_t objectno, uint64_t trunc_size);
 
-    static uint64_t get_num_objects(const ceph_file_layout& layout,
+    static uint64_t get_num_objects(const file_layout_t& layout,
 				    uint64_t size);
     /*
      * helper to assemble a striped result
@@ -77,6 +77,7 @@ class CephContext;
     class StripedReadResult {
       // offset -> (data, intended length)
       map<uint64_t, pair<bufferlist, uint64_t> > partial;
+      uint64_t total_intended_len = 0; //sum of partial.second.second
 
     public:
       void add_partial_result(
@@ -97,6 +98,12 @@ class CephContext;
 	const vector<pair<uint64_t,uint64_t> >& buffer_extents);
 
       void assemble_result(CephContext *cct, bufferlist& bl, bool zero_tail);
+
+      /**
+       * @buffer copy read data into buffer
+       * @len the length of buffer
+       */
+      void assemble_result(CephContext *cct, char *buffer, size_t len);
     };
 
   };
diff --git a/src/pybind/Makefile.am b/src/pybind/Makefile.am
index fd23fcb..8f0a5bd 100644
--- a/src/pybind/Makefile.am
+++ b/src/pybind/Makefile.am
@@ -1,51 +1,23 @@
-EXTRA_DIST += $(srcdir)/pybind/setup.py $(srcdir)/pybind/rbd.pyx
 
 if ENABLE_CLIENT
-if WITH_RADOS
-if WITH_RBD
 if WITH_CYTHON
 
 PY_DISTUTILS = \
 	CPPFLAGS="-iquote \${abs_srcdir}/include ${AM_CPPFLAGS} ${CPPFLAGS}" \
-	CFLAGS="-iquote \${abs_srcdir}/include ${AM_CFLAGS} ${CFLAGS}" \
-	LDFLAGS="-L\${abs_builddir}/.libs $(subst -pie,,${AM_LDFLAGS}) ${LDFLAGS}" \
+	CFLAGS="-iquote \${abs_srcdir}/include ${AM_CFLAGS} ${PYTHON_CFLAGS}" \
+	LDFLAGS="-L\${abs_builddir}/.libs $(subst -pie,,${AM_LDFLAGS}) ${PYTHON_LDFLAGS}" \
 	CYTHON_BUILD_DIR="$(shell readlink -f $(builddir))/build" \
 	${PYTHON} ./setup.py
 
-pybind-all: librbd.la ${srcdir}/ceph_ver.h
-	cd $(srcdir)/pybind; $(PY_DISTUTILS) build \
-	--build-base $(shell readlink -f $(builddir))/build \
-	--verbose
-
-pybind-clean: ${srcdir}/ceph_ver.h
-	cd $(srcdir)/pybind; $(PY_DISTUTILS) clean \
-	--build-base $(shell readlink -f $(builddir))/build \
-	--verbose
-
-pybind-install-exec: ${srcdir}/ceph_ver.h
-	if test "$(DESTDIR)" ; then \
-		if lsb_release -si | grep --quiet 'Ubuntu\|Debian\|Devuan' ; then \
-			options=--install-layout=deb ; \
-		else \
-			options=--prefix=/usr ; \
-		fi ; \
-		root="--root=$(DESTDIR)" ; \
-	else \
-		options=--prefix=$(prefix) ; \
-	fi ; \
-	cd $(srcdir)/pybind; $(PY_DISTUTILS) build \
-	--build-base $(shell readlink -f $(builddir))/build \
-	install \
-	$$options $$root \
-	--single-version-externally-managed \
-	--record /dev/null \
-	--verbose
-
-LOCAL_ALL += pybind-all
-LOCAL_CLEAN += pybind-clean
-LOCAL_INSTALLEXEC += pybind-install-exec
+if WITH_RADOS
+include pybind/rados/Makefile.am
+if WITH_RBD
+include pybind/rbd/Makefile.am
+endif # WITH_RBD
+if WITH_CEPHFS
+include pybind/cephfs/Makefile.am
+endif # WITH_CEPHFS
+endif # WITH_RADOS
 
-endif
-endif
-endif
-endif
+endif # WITH_CYTHON
+endif # ENABLE_CLIENT
diff --git a/src/pybind/ceph_argparse.py b/src/pybind/ceph_argparse.py
index 9a83057..7d5f4cf 100644
--- a/src/pybind/ceph_argparse.py
+++ b/src/pybind/ceph_argparse.py
@@ -10,6 +10,7 @@ Copyright (C) 2013 Inktank Storage, Inc.
 LGPL2.  See file COPYING.
 """
 import copy
+import errno
 import json
 import os
 import pprint
@@ -17,6 +18,7 @@ import re
 import socket
 import stat
 import sys
+import threading
 import types
 import uuid
 
@@ -1089,6 +1091,63 @@ def find_cmd_target(childargs):
     return 'mon', ''
 
 
+class RadosThread(threading.Thread):
+    def __init__(self, target, *args, **kwargs):
+        self.args = args
+        self.kwargs = kwargs
+        self.target = target
+	self.exception = None
+        threading.Thread.__init__(self)
+
+    def run(self):
+        try:
+		self.retval = self.target(*self.args, **self.kwargs)
+	except Exception as e:
+		self.exception = e
+
+
+# time in seconds between each call to t.join() for child thread
+POLL_TIME_INCR = 0.5
+
+
+def run_in_thread(target, *args, **kwargs):
+    interrupt = False
+    timeout = kwargs.pop('timeout', 0)
+    countdown = timeout
+    t = RadosThread(target, *args, **kwargs)
+
+    # allow the main thread to exit (presumably, avoid a join() on this
+    # subthread) before this thread terminates.  This allows SIGINT
+    # exit of a blocked call.  See below.
+    t.daemon = True
+
+    t.start()
+    try:
+        # poll for thread exit
+        while t.is_alive():
+            t.join(POLL_TIME_INCR)
+            if timeout and t.is_alive():
+                countdown = countdown - POLL_TIME_INCR
+                if countdown <= 0:
+                    raise KeyboardInterrupt
+
+        t.join()        # in case t exits before reaching the join() above
+    except KeyboardInterrupt:
+        # ..but allow SIGINT to terminate the waiting.  Note: this
+        # relies on the Linux kernel behavior of delivering the signal
+        # to the main thread in preference to any subthread (all that's
+        # strictly guaranteed is that *some* thread that has the signal
+        # unblocked will receive it).  But there doesn't seem to be
+        # any interface to create t with SIGINT blocked.
+        interrupt = True
+
+    if interrupt:
+        t.retval = -errno.EINTR
+    if t.exception:
+        raise t.exception
+    return t.retval
+
+
 def send_command(cluster, target=('mon', ''), cmd=None, inbuf='', timeout=0,
                  verbose=False):
     """
@@ -1110,8 +1169,8 @@ def send_command(cluster, target=('mon', ''), cmd=None, inbuf='', timeout=0,
             if verbose:
                 print >> sys.stderr, 'submit {0} to osd.{1}'.\
                     format(cmd, osdid)
-            ret, outbuf, outs = \
-                cluster.osd_command(osdid, cmd, inbuf, timeout)
+            ret, outbuf, outs = run_in_thread(
+                cluster.osd_command, osdid, cmd, inbuf, timeout)
 
         elif target[0] == 'pg':
             pgid = target[1]
@@ -1126,17 +1185,19 @@ def send_command(cluster, target=('mon', ''), cmd=None, inbuf='', timeout=0,
             if verbose:
                 print >> sys.stderr, 'submit {0} for pgid {1}'.\
                     format(cmd, pgid)
-            ret, outbuf, outs = \
-                cluster.pg_command(pgid, cmd, inbuf, timeout)
+            ret, outbuf, outs = run_in_thread(
+                cluster.pg_command, pgid, cmd, inbuf, timeout)
 
         elif target[0] == 'mon':
             if verbose:
                 print >> sys.stderr, '{0} to {1}'.\
                     format(cmd, target[0])
             if target[1] == '':
-                ret, outbuf, outs = cluster.mon_command(cmd, inbuf, timeout)
+                ret, outbuf, outs = run_in_thread(
+                    cluster.mon_command, cmd, inbuf, timeout)
             else:
-                ret, outbuf, outs = cluster.mon_command(cmd, inbuf, timeout, target[1])
+                ret, outbuf, outs = run_in_thread(
+                    cluster.mon_command, cmd, inbuf, timeout, target[1])
         elif target[0] == 'mds':
             mds_spec = target[1]
 
diff --git a/src/pybind/ceph_volume_client.py b/src/pybind/ceph_volume_client.py
index 2e284b2..8add311 100644
--- a/src/pybind/ceph_volume_client.py
+++ b/src/pybind/ceph_volume_client.py
@@ -15,13 +15,6 @@ import rados
 import cephfs
 from ceph_argparse import json_command
 
-# Generate missing lib errors at load time, rather than the
-# first time someone tries to use the FS
-try:
-    cephfs.load_libcephfs()
-except EnvironmentError as e:
-    raise ImportError(e.__str__())
-
 
 class RadosError(Exception):
     """
diff --git a/src/pybind/cephfs.py b/src/pybind/cephfs.py
deleted file mode 100644
index 71c0d40..0000000
--- a/src/pybind/cephfs.py
+++ /dev/null
@@ -1,590 +0,0 @@
-"""
-This module is a thin wrapper around libcephfs.
-"""
-from ctypes import CDLL, c_char_p, c_size_t, c_void_p, c_int, c_long, c_uint, c_ulong, \
-    c_ushort, create_string_buffer, byref, Structure, pointer, c_char, POINTER, \
-    c_uint8, c_int64
-from ctypes.util import find_library
-from collections import namedtuple
-import errno
-import os
-
-
-class Error(Exception):
-    pass
-
-
-class PermissionError(Error):
-    pass
-
-
-class ObjectNotFound(Error):
-    pass
-
-
-class NoData(Error):
-    pass
-
-
-class ObjectExists(Error):
-    pass
-
-
-class IOError(Error):
-    pass
-
-
-class NoSpace(Error):
-    pass
-
-
-class InvalidValue(Error):
-    pass
-
-
-class OperationNotSupported(Error):
-    pass
-
-
-class IncompleteWriteError(Error):
-    pass
-
-
-class LibCephFSStateError(Error):
-    pass
-
-
-def make_ex(ret, msg):
-    """
-    Translate a libcephfs return code into an exception.
-
-    :param ret: the return code
-    :type ret: int
-    :param msg: the error message to use
-    :type msg: str
-    :returns: a subclass of :class:`Error`
-    """
-
-    errors = {
-        errno.EPERM     : PermissionError,
-        errno.ENOENT    : ObjectNotFound,
-        errno.EIO       : IOError,
-        errno.ENOSPC    : NoSpace,
-        errno.EEXIST    : ObjectExists,
-        errno.ENODATA   : NoData,
-        errno.EINVAL    : InvalidValue,
-        errno.EOPNOTSUPP: OperationNotSupported,
-        }
-    ret = abs(ret)
-    if ret in errors:
-        return errors[ret](msg)
-    else:
-        return Error(msg + (": error code %d" % ret))
-
-
-class cephfs_statvfs(Structure):
-    _fields_ = [("f_bsize", c_ulong),
-                ("f_frsize", c_ulong),
-                ("f_blocks", c_ulong),
-                ("f_bfree", c_ulong),
-                ("f_bavail", c_ulong),
-                ("f_files", c_ulong),
-                ("f_ffree", c_ulong),
-                ("f_favail", c_ulong),
-                ("f_fsid", c_ulong),
-                ("f_flag", c_ulong),
-                ("f_namemax", c_ulong),
-                ("f_padding", c_ulong*32)]
-
-
-class cephfs_dirent(Structure):
-    _fields_ = [("d_ino", c_long),
-                ("d_off", c_ulong),
-                ("d_reclen", c_ushort),
-                ("d_type", c_uint8),
-                ("d_name", c_char*256)]
-
-# struct timespec {
-#   long int tv_sec;
-#   long int tv_nsec;
-# }
-class cephfs_timespec(Structure):
-    _fields_ = [('tv_sec', c_long),
-                ('tv_nsec', c_long)]
-
-
-# struct stat {
-#   unsigned long st_dev;
-#   unsigned long st_ino;
-#   unsigned long st_nlink;
-#   unsigned int st_mode;
-#   unsigned int st_uid;
-#   unsigned int st_gid;
-#   int __pad0;
-#   unsigned long st_rdev;
-#   long int st_size;
-#   long int st_blksize;
-#   long int st_blocks;
-#   struct timespec st_atim;
-#   struct timespec st_mtim;
-#   struct timespec st_ctim;
-#   long int __unused[3];
-# };
-class cephfs_stat(Structure):
-    _fields_ = [('st_dev', c_ulong),            # ID of device containing file
-                ('st_ino', c_ulong),            # inode number
-                ('st_nlink', c_ulong),          # number of hard links
-                ('st_mode', c_uint),            # protection
-                ('st_uid', c_uint),             # user ID of owner
-                ('st_gid', c_uint),             # group ID of owner
-                ('__pad0', c_int),
-                ('st_rdev', c_ulong),           # device ID (if special file)
-                ('st_size', c_long),            # total size, in bytes
-                ('st_blksize', c_long),         # blocksize for file system I/O
-                ('st_blocks', c_long),          # num of 512B blocks allocated
-                ('st_atime', cephfs_timespec),  # time of last access
-                ('st_mtime', cephfs_timespec),  # time of last modification
-                ('st_ctime', cephfs_timespec),  # time of last status change
-                ('__unused1', c_long),
-                ('__unused2', c_long),
-                ('__unused3', c_long)]
-
-
-class DirEntry(namedtuple('DirEntry',
-               ['d_ino', 'd_off', 'd_reclen', 'd_type', 'd_name'])):
-    DT_DIR = 0x4
-    DT_REG = 0xA
-    DT_LNK = 0xC
-    def is_dir(self):
-        return self.d_type == self.DT_DIR
-
-    def is_symbol_file(self):
-        return self.d_type == self.DT_LNK
-
-    def is_file(self):
-        return self.d_type == self.DT_REG
-
-StatResult = namedtuple('StatResult',
-                        ["st_dev", "st_ino", "st_mode", "st_nlink", "st_uid",
-                         "st_gid", "st_rdev", "st_size", "st_blksize",
-                         "st_blocks", "st_atime", "st_mtime", "st_ctime"])
-
-def load_libcephfs():
-    """
-    Load the libcephfs shared library.
-    """
-    libcephfs_path = find_library('cephfs')
-    if libcephfs_path:
-        return CDLL(libcephfs_path)
-
-    # try harder, find_library() doesn't search LD_LIBRARY_PATH
-    # in addition, it doesn't seem work on centos 6.4 (see e46d2ca067b5)
-    try:
-        return CDLL('libcephfs.so.1')
-    except OSError as e:
-        raise EnvironmentError("Unable to load libcephfs: %s" % e)
-
-
-class LibCephFS(object):
-    """libcephfs python wrapper"""
-    def require_state(self, *args):
-        for a in args:
-            if self.state == a:
-                return
-        raise LibCephFSStateError("You cannot perform that operation on a "
-                                  "CephFS object in state %s." % (self.state))
-
-    def __init__(self, conf=None, conffile=None, auth_id=None, rados_inst=None):
-        self.libcephfs = load_libcephfs()
-        self.cluster = c_void_p()
-
-        self.state = "uninitialized"
-        if rados_inst is not None:
-            if auth_id is not None or conffile is not None or conf is not None:
-                raise InvalidValue("May not pass RADOS instance as well as other configuration")
-
-            return self.create_with_rados(rados_inst)
-        else:
-            return self.create(conf, conffile, auth_id)
-
-    def create_with_rados(self, rados_inst):
-        ret = self.libcephfs.ceph_create_from_rados(
-                byref(self.cluster),
-                rados_inst.cluster)
-        if ret != 0:
-            raise Error("libcephfs_initialize failed with error code: %d" % ret)
-        self.state = "configuring"
-
-    def create(self, conf=None, conffile=None, auth_id=None, rados_inst=None):
-        if conffile is not None and not isinstance(conffile, basestring):
-            raise TypeError('conffile must be a string or None')
-
-        if auth_id is not None and not isinstance(auth_id, basestring):
-            raise TypeError('auth_id must be a string or None')
-
-        ret = self.libcephfs.ceph_create(byref(self.cluster),
-                c_char_p(auth_id) if auth_id else c_char_p(0))
-        if ret != 0:
-            raise Error("libcephfs_initialize failed with error code: %d" % ret)
-        self.state = "configuring"
-        if conffile is not None:
-            # read the default conf file when '' is given
-            if conffile == '':
-                conffile = None
-            self.conf_read_file(conffile)
-        if conf is not None:
-            for key, value in conf.iteritems():
-                self.conf_set(key, value)
-
-    def conf_read_file(self, conffile=None):
-        if conffile is not None and not isinstance(conffile, basestring):
-            raise TypeError('conffile param must be a string')
-        ret = self.libcephfs.ceph_conf_read_file(self.cluster, c_char_p(conffile))
-        if ret != 0:
-            raise make_ex(ret, "error calling conf_read_file")
-
-    def conf_parse_argv(self, argv):
-        self.require_state("configuring")
-        c_argv = (c_char_p * len(argv))(*argv)
-        ret = self.libcephfs.ceph_conf_parse_argv(self.cluster, len(argv),
-                                                  c_argv)
-        if ret != 0:
-            raise make_ex(ret, "error calling conf_parse_argv")
-
-    def shutdown(self):
-        """
-        Unmount and destroy the ceph mount handle.
-        """
-        if self.state != "shutdown":
-            self.libcephfs.ceph_shutdown(self.cluster)
-            self.state = "shutdown"
-
-    def __enter__(self):
-        self.mount()
-        return self
-
-    def __exit__(self, type_, value, traceback):
-        self.shutdown()
-        return False
-
-    def __del__(self):
-        self.shutdown()
-
-    def version(self):
-        """
-        Get the version number of the ``libcephfs`` C library.
-
-        :returns: a tuple of ``(major, minor, extra)`` components of the
-                  libcephfs version
-        """
-        major = c_int(0)
-        minor = c_int(0)
-        extra = c_int(0)
-        self.libcephfs.ceph_version(byref(major), byref(minor), byref(extra))
-        return (major.value, minor.value, extra.value)
-
-    def conf_get(self, option):
-        self.require_state("configuring", "initialized", "mounted")
-        if not isinstance(option, basestring):
-            raise TypeError('option must be a string')
-        length = 20
-        while True:
-            ret_buf = create_string_buffer(length)
-            ret = self.libcephfs.ceph_conf_get(self.cluster, option,
-                                               ret_buf, c_size_t(length))
-            if ret == 0:
-                return ret_buf.value
-            elif ret == -errno.ENAMETOOLONG:
-                length = length * 2
-            elif ret == -errno.ENOENT:
-                return None
-            else:
-                raise make_ex(ret, "error calling conf_get")
-
-    def conf_set(self, option, val):
-        self.require_state("configuring", "initialized", "mounted")
-        if not isinstance(option, basestring):
-            raise TypeError('option must be a string')
-        if not isinstance(val, basestring):
-            raise TypeError('val must be a string')
-        ret = self.libcephfs.ceph_conf_set(self.cluster, c_char_p(option),
-                                           c_char_p(val))
-        if ret != 0:
-            raise make_ex(ret, "error calling conf_set")
-
-    def init(self):
-        self.require_state("configuring")
-        ret = self.libcephfs.ceph_init(self.cluster)
-        if ret != 0:
-            raise make_ex(ret, "error calling ceph_init")
-        self.state = "initialized"
-
-    def mount(self):
-        if self.state == "configuring":
-            self.init()
-        self.require_state("initialized")
-        ret = self.libcephfs.ceph_mount(self.cluster, "/")
-        if ret != 0:
-            raise make_ex(ret, "error calling ceph_mount")
-        self.state = "mounted"
-
-    def statfs(self, path):
-        if not isinstance(path, basestring):
-            raise TypeError('path must be a string')
-        self.require_state("mounted")
-        statbuf = cephfs_statvfs()
-        ret = self.libcephfs.ceph_statfs(self.cluster, c_char_p(path), byref(statbuf))
-        if ret < 0:
-            raise make_ex(ret, "statfs failed: %s" % path)
-        return {'f_bsize': statbuf.f_bsize,
-                'f_frsize': statbuf.f_frsize,
-                'f_blocks': statbuf.f_blocks,
-                'f_bfree': statbuf.f_bfree,
-                'f_bavail': statbuf.f_bavail,
-                'f_files': statbuf.f_files,
-                'f_ffree': statbuf.f_ffree,
-                'f_favail': statbuf.f_favail,
-                'f_fsid': statbuf.f_fsid,
-                'f_flag': statbuf.f_flag,
-                'f_namemax': statbuf.f_namemax}
-
-    def sync_fs(self):
-        self.require_state("mounted")
-        ret = self.libcephfs.ceph_sync_fs(self.cluster)
-        if ret < 0:
-            raise make_ex(ret, "sync_fs failed")
-
-    def getcwd(self):
-        self.require_state("mounted")
-        self.libcephfs.ceph_getcwd.restype = c_char_p
-        return self.libcephfs.ceph_getcwd(self.cluster)
-
-    def chdir(self, path):
-        self.require_state("mounted")
-        ret = self.libcephfs.ceph_chdir(self.cluster, c_char_p(path))
-        if ret < 0:
-            raise make_ex(ret, "chdir failed")
-
-    def opendir(self, path):
-        self.require_state("mounted")
-        if not isinstance(path, basestring):
-            raise TypeError('path must be a string')
-        dir_handler = c_void_p()
-        ret = self.libcephfs.ceph_opendir(self.cluster, c_char_p(path),
-                                          pointer(dir_handler));
-        if ret < 0:
-            raise make_ex(ret, "opendir failed")
-        return dir_handler
-
-    def readdir(self, dir_handler):
-        self.require_state("mounted")
-        self.libcephfs.ceph_readdir.restype = POINTER(cephfs_dirent)
-        while True:
-            dirent = self.libcephfs.ceph_readdir(self.cluster, dir_handler)
-            if not dirent:
-                return None
-
-            return DirEntry(d_ino=dirent.contents.d_ino,
-                            d_off=dirent.contents.d_off,
-                            d_reclen=dirent.contents.d_reclen,
-                            d_type=dirent.contents.d_type,
-                            d_name=dirent.contents.d_name)
-
-    def closedir(self, dir_handler):
-        self.require_state("mounted")
-        ret = self.libcephfs.ceph_closedir(self.cluster, dir_handler)
-        if ret < 0:
-            raise make_ex(ret, "closedir failed")
-
-    def mkdir(self, path, mode):
-        self.require_state("mounted")
-        if not isinstance(path, basestring):
-            raise TypeError('path must be a string')
-        ret = self.libcephfs.ceph_mkdir(self.cluster, c_char_p(path), c_int(mode))
-        if ret < 0:
-            raise make_ex(ret, "error in mkdir '%s'" % path)
-
-    def mkdirs(self, path, mode):
-        self.require_state("mounted")
-        if not isinstance(path, basestring):
-            raise TypeError('path must be a string')
-        if not isinstance(mode, basestring):
-            raise TypeError('mode must be an int')
-        ret = self.libcephfs.ceph_mkdir(self.cluster, c_char_p(path), c_int(mode))
-        if ret < 0:
-            raise make_ex(ret, "error in mkdirs '%s'" % path)
-
-    def rmdir(self, path):
-        self.require_state("mounted")
-        if not isinstance(path, basestring):
-            raise TypeError('path must be a string')
-        ret = self.libcephfs.ceph_rmdir(self.cluster, c_char_p(path))
-        if ret < 0:
-            raise make_ex(ret, "error in rmdir '%s'" % path)
-
-    def open(self, path, flags, mode=0):
-        self.require_state("mounted")
-        if not isinstance(path, basestring):
-            raise TypeError('path must be a string')
-        if not isinstance(flags, basestring):
-            raise TypeError('flags must be a string')
-        if not isinstance(mode, int):
-            raise TypeError('mode must be an int')
-        cephfs_flags = 0
-        if flags == '':
-            cephfs_flags = os.O_RDONLY
-        else:
-            for c in flags:
-                if c == 'r':
-                    cephfs_flags |= os.O_RDONLY
-                elif c == 'w':
-                    cephfs_flags |= os.O_WRONLY | os.O_TRUNC | os.O_CREAT
-                elif c == '+':
-                    cephfs_flags |= os.O_RDWR
-                else:
-                    raise OperationNotSupported(
-                        "open flags doesn't support %s" % c)
-
-        ret = self.libcephfs.ceph_open(self.cluster, c_char_p(path),
-                                       c_int(cephfs_flags), c_int(mode))
-        if ret < 0:
-            raise make_ex(ret, "error in open '%s'" % path)
-        return ret
-
-    def close(self, fd):
-        self.require_state("mounted")
-        ret = self.libcephfs.ceph_close(self.cluster, c_int(fd))
-        if ret < 0:
-            raise make_ex(ret, "error in close")
-
-    def read(self, fd, offset, l):
-        self.require_state("mounted")
-        if not isinstance(offset, int):
-            raise TypeError('path must be an int')
-        if not isinstance(l, int):
-            raise TypeError('path must be an int')
-
-        buf = create_string_buffer(l)
-        ret = self.libcephfs.ceph_read(self.cluster, c_int(fd),
-                                       buf, c_int64(l), c_int64(offset))
-        if ret < 0:
-            raise make_ex(ret, "error in close")
-        return buf.value
-
-    def write(self, fd, buf, offset):
-        self.require_state("mounted")
-        if not isinstance(buf, basestring):
-            raise TypeError('buf must be a string')
-        if not isinstance(offset, int):
-            raise TypeError('offset must be an int')
-
-        ret = self.libcephfs.ceph_write(self.cluster, c_int(fd),
-                                        c_char_p(buf), c_int64(len(buf)),
-                                        c_int64(offset))
-        if ret < 0:
-            raise make_ex(ret, "error in close")
-        return ret
-
-    def getxattr(self, path, name):
-        if not isinstance(path, basestring):
-            raise TypeError('path must be a string')
-        if not isinstance(name, basestring):
-            raise TypeError('name must be a string')
-
-        self.require_state("mounted")
-        l = 255
-        buf = create_string_buffer(l)
-        actual_l = self.libcephfs.ceph_getxattr(self.cluster, path, name, buf, c_int(l))
-        if actual_l > l:
-            buf = create_string_buffer(actual_)
-            self.libcephfs.ceph_getxattr(path, name, new_buf, actual_l)
-        return buf.value
-
-    def setxattr(self, path, name, value, flags):
-        if not isinstance(path, basestring):
-            raise TypeError('path must be a string')
-        if not isinstance(name, basestring):
-            raise TypeError('name must be a string')
-        if not isinstance(value, basestring):
-            raise TypeError('value must be a string')
-        self.require_state("mounted")
-        ret = self.libcephfs.ceph_setxattr(self.cluster, c_char_p(path),
-                                           c_char_p(name), c_char_p(value),
-                                           c_size_t(len(value)), c_int(flags))
-        if ret < 0:
-            raise make_ex(ret, "error in setxattr")
-
-    def stat(self, path):
-        self.require_state("mounted")
-        if not isinstance(path, basestring):
-            raise TypeError('path must be a string')
-        statbuf = cephfs_stat()
-        ret = self.libcephfs.ceph_stat(self.cluster, c_char_p(path),
-                                       byref(statbuf))
-        if ret < 0:
-            raise make_ex(ret, "error in stat: %s" % path)
-        return StatResult(st_dev=statbuf.st_dev, st_ino=statbuf.st_ino,
-                          st_mode=statbuf.st_mode, st_nlink=statbuf.st_nlink,
-                          st_uid=statbuf.st_uid, st_gid=statbuf.st_gid,
-                          st_rdev=statbuf.st_rdev, st_size=statbuf.st_size,
-                          st_blksize=statbuf.st_blksize,
-                          st_blocks=statbuf.st_blocks,
-                          st_atime=statbuf.st_atime, st_mtime=statbuf.st_mtime,
-                          st_ctime=statbuf.st_ctime)
-
-    def symlink(self, existing, newname):
-        if not isinstance(existing, str):
-            raise TypeError('existing must be a string')
-        if not isinstance(newname, str):
-            raise TypeError('newname must be a string')
-        self.require_state("mounted")
-        ret = self.libcephfs.ceph_symlink(
-            self.cluster,
-            c_char_p(existing),
-            c_char_p(newname))
-        if ret < 0:
-            raise make_ex(ret, "error in symlink")
-
-    def unlink(self, path):
-        self.require_state("mounted")
-        ret = self.libcephfs.ceph_unlink(
-            self.cluster,
-            c_char_p(path))
-        if ret < 0:
-            raise make_ex(ret, "error in unlink: %s" % path)
-
-    def rename(self, src, dst):
-        self.require_state("mounted")
-        if not isinstance(src, basestring) or not isinstance(dst, basestring):
-            raise TypeError('source and destination must be a string')
-        ret = self.libcephfs.ceph_rename(self.cluster, c_char_p(src), c_char_p(dst))
-        if ret < 0:
-            raise make_ex(ret, "error in rename '%s' to '%s'" % (src, dst))
-
-    def mds_command(self, mds_spec, args, input_data):
-        """
-        :return 3-tuple of output status int, output status string, output data
-        """
-
-        cmdarr = (c_char_p * len(args))(*args)
-
-        outbufp = pointer(pointer(c_char()))
-        outbuflen = c_long()
-        outsp = pointer(pointer(c_char()))
-        outslen = c_long()
-
-        ret = self.libcephfs.ceph_mds_command(self.cluster, c_char_p(mds_spec),
-                                              cmdarr, len(args),
-                                              c_char_p(input_data),
-                                              len(input_data), outbufp,
-                                              byref(outbuflen), outsp,
-                                              byref(outslen))
-
-        my_outbuf = outbufp.contents[:(outbuflen.value)]
-        my_outs = outsp.contents[:(outslen.value)]
-        if outbuflen.value:
-            self.libcephfs.ceph_buffer_free(outbufp.contents)
-        if outslen.value:
-            self.libcephfs.ceph_buffer_free(outsp.contents)
-
-        return (ret, my_outbuf, my_outs)
diff --git a/src/pybind/cephfs/Makefile.am b/src/pybind/cephfs/Makefile.am
new file mode 100644
index 0000000..577431f
--- /dev/null
+++ b/src/pybind/cephfs/Makefile.am
@@ -0,0 +1,34 @@
+EXTRA_DIST += $(srcdir)/pybind/cephfs/setup.py $(srcdir)/pybind/cephfs/cephfs.pyx
+
+cephfs-pybind-all: libcephfs.la ${srcdir}/ceph_ver.h
+	cd $(srcdir)/pybind/cephfs; $(PY_DISTUTILS) build \
+	--build-base $(shell readlink -f $(builddir))/build \
+	--verbose
+
+cephfs-pybind-clean: ${srcdir}/ceph_ver.h
+	cd $(srcdir)/pybind/cephfs; $(PY_DISTUTILS) clean \
+	--build-base $(shell readlink -f $(builddir))/build \
+	--verbose
+
+cephfs-pybind-install-exec: ${srcdir}/ceph_ver.h
+	if test "$(DESTDIR)" ; then \
+		if lsb_release -si | grep --quiet 'Ubuntu\|Debian\|Devuan' ; then \
+			options=--install-layout=deb ; \
+		else \
+			options=--prefix=/usr ; \
+		fi ; \
+		root="--root=$(DESTDIR)" ; \
+	else \
+		options=--prefix=$(prefix) ; \
+	fi ; \
+	cd $(srcdir)/pybind/cephfs; $(PY_DISTUTILS) build \
+	--build-base $(shell readlink -f $(builddir))/build \
+	install \
+	$$options $$root \
+	--single-version-externally-managed \
+	--record /dev/null \
+	--verbose
+
+LOCAL_ALL += cephfs-pybind-all
+LOCAL_CLEAN += cephfs-pybind-clean
+LOCAL_INSTALLEXEC += cephfs-pybind-install-exec
diff --git a/src/pybind/cephfs/cephfs.pyx b/src/pybind/cephfs/cephfs.pyx
new file mode 100644
index 0000000..7121636
--- /dev/null
+++ b/src/pybind/cephfs/cephfs.pyx
@@ -0,0 +1,848 @@
+"""
+This module is a thin wrapper around libcephfs.
+"""
+
+from cpython cimport PyObject, ref, exc
+from libc cimport errno
+from libc.stdint cimport *
+from libc.stdlib cimport malloc, realloc, free
+
+cimport rados
+
+from collections import namedtuple
+from datetime import datetime
+import errno
+import os
+import sys
+
+# Are we running Python 2.x
+_python2 = sys.hexversion < 0x03000000
+
+if _python2:
+    str_type = basestring
+else:
+    str_type = str
+
+
+cdef extern from "Python.h":
+    # These are in cpython/string.pxd, but use "object" types instead of
+    # PyObject*, which invokes assumptions in cpython that we need to
+    # legitimately break to implement zero-copy string buffers in Image.read().
+    # This is valid use of the Python API and documented as a special case.
+    PyObject *PyBytes_FromStringAndSize(char *v, Py_ssize_t len) except NULL
+    char* PyBytes_AsString(PyObject *string) except NULL
+    int _PyBytes_Resize(PyObject **string, Py_ssize_t newsize) except -1
+    void PyEval_InitThreads()
+
+
+cdef extern from "sys/statvfs.h":
+    cdef struct statvfs:
+        unsigned long int f_bsize
+        unsigned long int f_frsize
+        unsigned long int f_blocks
+        unsigned long int f_bfree
+        unsigned long int f_bavail
+        unsigned long int f_files
+        unsigned long int f_ffree
+        unsigned long int f_favail
+        unsigned long int f_fsid
+        unsigned long int f_flag
+        unsigned long int f_namemax
+        unsigned long int f_padding[32]
+
+
+cdef extern from "dirent.h":
+    cdef struct dirent:
+        long int d_ino
+        unsigned long int d_off
+        unsigned short int d_reclen
+        unsigned char d_type
+        char d_name[256]
+
+
+cdef extern from "time.h":
+    ctypedef long int time_t
+
+
+cdef extern from "sys/types.h":
+    ctypedef unsigned long mode_t
+
+
+cdef extern from "sys/stat.h":
+    cdef struct stat:
+        unsigned long st_dev
+        unsigned long st_ino
+        unsigned long st_nlink
+        unsigned int st_mode
+        unsigned int st_uid
+        unsigned int st_gid
+        int __pad0
+        unsigned long st_rdev
+        long int st_size
+        long int st_blksize
+        long int st_blocks
+        time_t st_atime
+        time_t st_mtime
+        time_t st_ctime
+
+
+cdef extern from "cephfs/libcephfs.h" nogil:
+    cdef struct ceph_mount_info:
+        pass
+
+    cdef struct ceph_dir_result:
+        pass
+
+    ctypedef void* rados_t
+
+    const char *ceph_version(int *major, int *minor, int *patch)
+
+    int ceph_create(ceph_mount_info **cmount, const char * const id)
+    int ceph_create_from_rados(ceph_mount_info **cmount, rados_t cluster)
+    int ceph_init(ceph_mount_info *cmount)
+    void ceph_shutdown(ceph_mount_info *cmount)
+
+    int ceph_conf_read_file(ceph_mount_info *cmount, const char *path_list)
+    int ceph_conf_parse_argv(ceph_mount_info *cmount, int argc, const char **argv)
+    int ceph_conf_get(ceph_mount_info *cmount, const char *option, char *buf, size_t len)
+    int ceph_conf_set(ceph_mount_info *cmount, const char *option, const char *value)
+
+    int ceph_mount(ceph_mount_info *cmount, const char *root)
+    int ceph_stat(ceph_mount_info *cmount, const char *path, stat *stbuf)
+    int ceph_statfs(ceph_mount_info *cmount, const char *path, statvfs *stbuf)
+
+    int ceph_mds_command(ceph_mount_info *cmount, const char *mds_spec, const char **cmd, size_t cmdlen,
+                         const char *inbuf, size_t inbuflen, char **outbuf, size_t *outbuflen,
+                         char **outs, size_t *outslen)
+    int ceph_rename(ceph_mount_info *cmount, const char *from_, const char *to)
+    int ceph_unlink(ceph_mount_info *cmount, const char *path)
+    int ceph_symlink(ceph_mount_info *cmount, const char *existing, const char *newname)
+    int ceph_setxattr(ceph_mount_info *cmount, const char *path, const char *name,
+                      const void *value, size_t size, int flags)
+    int ceph_getxattr(ceph_mount_info *cmount, const char *path, const char *name,
+                      void *value, size_t size)
+    int ceph_write(ceph_mount_info *cmount, int fd, const char *buf, int64_t size, int64_t offset)
+    int ceph_read(ceph_mount_info *cmount, int fd, char *buf, int64_t size, int64_t offset)
+    int ceph_close(ceph_mount_info *cmount, int fd)
+    int ceph_open(ceph_mount_info *cmount, const char *path, int flags, mode_t mode)
+    int ceph_mkdir(ceph_mount_info *cmount, const char *path, mode_t mode)
+    int ceph_mkdirs(ceph_mount_info *cmount, const char *path, mode_t mode)
+    int ceph_closedir(ceph_mount_info *cmount, ceph_dir_result *dirp)
+    int ceph_opendir(ceph_mount_info *cmount, const char *name, ceph_dir_result **dirpp)
+    int ceph_chdir(ceph_mount_info *cmount, const char *path)
+    dirent * ceph_readdir(ceph_mount_info *cmount, ceph_dir_result *dirp)
+    int ceph_rmdir(ceph_mount_info *cmount, const char *path)
+    const char* ceph_getcwd(ceph_mount_info *cmount)
+    int ceph_sync_fs(ceph_mount_info *cmount)
+    int ceph_conf_parse_argv(ceph_mount_info *cmount, int argc, const char **argv)
+    void ceph_buffer_free(char *buf)
+
+
+
+class Error(Exception):
+    pass
+
+
+class PermissionError(Error):
+    pass
+
+
+class ObjectNotFound(Error):
+    pass
+
+
+class NoData(Error):
+    pass
+
+
+class ObjectExists(Error):
+    pass
+
+
+class IOError(Error):
+    pass
+
+
+class NoSpace(Error):
+    pass
+
+
+class InvalidValue(Error):
+    pass
+
+
+class OperationNotSupported(Error):
+    pass
+
+
+class IncompleteWriteError(Error):
+    pass
+
+
+class LibCephFSStateError(Error):
+    pass
+
+
+cdef errno_to_exception =  {
+    errno.EPERM     : PermissionError,
+    errno.ENOENT    : ObjectNotFound,
+    errno.EIO       : IOError,
+    errno.ENOSPC    : NoSpace,
+    errno.EEXIST    : ObjectExists,
+    errno.ENODATA   : NoData,
+    errno.EINVAL    : InvalidValue,
+    errno.EOPNOTSUPP: OperationNotSupported,
+}
+
+
+cdef make_ex(ret, msg):
+    """
+    Translate a librados return code into an exception.
+
+    :param ret: the return code
+    :type ret: int
+    :param msg: the error message to use
+    :type msg: str
+    :returns: a subclass of :class:`Error`
+    """
+    ret = abs(ret)
+    if ret in errno_to_exception:
+        return errno_to_exception[ret](msg)
+    else:
+        return Error(msg + (": error code %d" % ret))
+
+
+class DirEntry(namedtuple('DirEntry',
+               ['d_ino', 'd_off', 'd_reclen', 'd_type', 'd_name'])):
+    DT_DIR = 0x4
+    DT_REG = 0xA
+    DT_LNK = 0xC
+    def is_dir(self):
+        return self.d_type == self.DT_DIR
+
+    def is_symbol_file(self):
+        return self.d_type == self.DT_LNK
+
+    def is_file(self):
+        return self.d_type == self.DT_REG
+
+StatResult = namedtuple('StatResult',
+                        ["st_dev", "st_ino", "st_mode", "st_nlink", "st_uid",
+                         "st_gid", "st_rdev", "st_size", "st_blksize",
+                         "st_blocks", "st_atime", "st_mtime", "st_ctime"])
+
+cdef class DirResult(object):
+    cdef ceph_dir_result *handler
+
+
+def cstr(val, name, encoding="utf-8", opt=False):
+    """
+    Create a byte string from a Python string
+
+    :param basestring val: Python string
+    :param str name: Name of the string parameter, for exceptions
+    :param str encoding: Encoding to use
+    :param bool opt: If True, None is allowed
+    :rtype: bytes
+    :raises: :class:`InvalidArgument`
+    """
+    if opt and val is None:
+        return None
+    if isinstance(val, bytes):
+        return val
+    elif isinstance(val, unicode):
+        return val.encode(encoding)
+    else:
+        raise TypeError('%s must be a string' % name)
+
+
+def cstr_list(list_str, name, encoding="utf-8"):
+    return [cstr(s, name) for s in list_str]
+
+
+def decode_cstr(val, encoding="utf-8"):
+    """
+    Decode a byte string into a Python string.
+
+    :param bytes val: byte string
+    :rtype: unicode or None
+    """
+    if val is None:
+        return None
+
+    return val.decode(encoding)
+
+
+cdef char* opt_str(s) except? NULL:
+    if s is None:
+        return NULL
+    return s
+
+
+cdef char ** to_bytes_array(list_bytes):
+    cdef char **ret = <char **>malloc(len(list_bytes) * sizeof(char *))
+    if ret == NULL:
+        raise MemoryError("malloc failed")
+    for i in xrange(len(list_bytes)):
+        ret[i] = <char *>list_bytes[i]
+    return ret
+
+
+cdef void* realloc_chk(void* ptr, size_t size) except NULL:
+    cdef void *ret = realloc(ptr, size)
+    if ret == NULL:
+        raise MemoryError("realloc failed")
+    return ret
+
+
+cdef class LibCephFS(object):
+    """libcephfs python wrapper"""
+
+    cdef public object state
+    cdef ceph_mount_info *cluster
+
+    def require_state(self, *args):
+        if self.state in args:
+            return
+        raise LibCephFSStateError("You cannot perform that operation on a "
+                                  "CephFS object in state %s." % (self.state))
+
+    def __cinit__(self, conf=None, conffile=None, auth_id=None, rados_inst=None):
+        PyEval_InitThreads()
+        self.state = "uninitialized"
+        if rados_inst is not None:
+            if auth_id is not None or conffile is not None or conf is not None:
+                raise InvalidValue("May not pass RADOS instance as well as other configuration")
+
+            self.create_with_rados(rados_inst)
+        else:
+            self.create(conf, conffile, auth_id)
+
+    def create_with_rados(self, rados.Rados rados_inst):
+        cdef int ret
+        with nogil:
+            ret = ceph_create_from_rados(&self.cluster, rados_inst.cluster)
+        if ret != 0:
+            raise Error("libcephfs_initialize failed with error code: %d" % ret)
+        self.state = "configuring"
+
+    def create(self, conf=None, conffile=None, auth_id=None):
+        if conf is not None and not isinstance(conf, dict):
+            raise TypeError("conf must be dict or None")
+        cstr(conffile, 'configfile', opt=True)
+        auth_id = cstr(auth_id, 'configfile', opt=True)
+
+        cdef:
+            char* _auth_id = opt_str(auth_id)
+            int ret
+
+        with nogil:
+            ret = ceph_create(&self.cluster, <const char*>_auth_id)
+        if ret != 0:
+            raise Error("libcephfs_initialize failed with error code: %d" % ret)
+
+        self.state = "configuring"
+        if conffile is not None:
+            # read the default conf file when '' is given
+            if conffile == '':
+                conffile = None
+            self.conf_read_file(conffile)
+        if conf is not None:
+            for key, value in conf.iteritems():
+                self.conf_set(key, value)
+
+    def conf_read_file(self, conffile=None):
+        conffile = cstr(conffile, 'conffile', opt=True)
+        cdef:
+            char *_conffile = opt_str(conffile)
+        with nogil:
+            ret = ceph_conf_read_file(self.cluster, <const char*>_conffile)
+        if ret != 0:
+            raise make_ex(ret, "error calling conf_read_file")
+
+    def conf_parse_argv(self, argv):
+        self.require_state("configuring")
+        cargv = cstr_list(argv, 'argv')
+        cdef:
+            int _argc = len(argv)
+            char **_argv = to_bytes_array(cargv)
+
+        try:
+            with nogil:
+                ret = ceph_conf_parse_argv(self.cluster, _argc,
+                                           <const char **>_argv)
+            if ret != 0:
+                raise make_ex(ret, "error calling conf_parse_argv")
+        finally:
+            free(_argv)
+
+    def shutdown(self):
+        """
+        Unmount and destroy the ceph mount handle.
+        """
+        if self.state in ["initialized", "mounted"]:
+            with nogil:
+                ceph_shutdown(self.cluster)
+            self.state = "shutdown"
+
+    def __enter__(self):
+        self.mount()
+        return self
+
+    def __exit__(self, type_, value, traceback):
+        self.shutdown()
+        return False
+
+    def __dealloc__(self):
+        self.shutdown()
+
+    def version(self):
+        """
+        Get the version number of the ``libcephfs`` C library.
+
+        :returns: a tuple of ``(major, minor, extra)`` components of the
+                  libcephfs version
+        """
+        cdef:
+            int major = 0
+            int minor = 0
+            int extra = 0
+        with nogil:
+            ceph_version(&major, &minor, &extra)
+        return (major, minor, extra)
+
+    def conf_get(self, option):
+        self.require_state("configuring", "initialized", "mounted")
+
+        option = cstr(option, 'option')
+        cdef:
+            char *_option = option
+            size_t length = 20
+            char *ret_buf = NULL
+
+        try:
+            while True:
+                ret_buf = <char *>realloc_chk(ret_buf, length)
+                with nogil:
+                    ret = ceph_conf_get(self.cluster, _option, ret_buf, length)
+                if (ret == 0):
+                    return decode_cstr(ret_buf)
+                elif (ret == -errno.ENAMETOOLONG):
+                    length = length * 2
+                elif (ret == -errno.ENOENT):
+                    return None
+                else:
+                    raise make_ex(ret, "error calling conf_get")
+        finally:
+            free(ret_buf)
+
+    def conf_set(self, option, val):
+        self.require_state("configuring", "initialized", "mounted")
+
+        option = cstr(option, 'option')
+        val = cstr(val, 'val')
+        cdef:
+            char *_option = option
+            char *_val = val
+
+        with nogil:
+            ret = ceph_conf_set(self.cluster, _option, _val)
+        if (ret != 0):
+            raise make_ex(ret, "error calling conf_set")
+
+    def init(self):
+        self.require_state("configuring")
+        with nogil:
+            ret = ceph_init(self.cluster)
+        if ret != 0:
+            raise make_ex(ret, "error calling ceph_init")
+        self.state = "initialized"
+
+    def mount(self):
+        if self.state == "configuring":
+            self.init()
+        self.require_state("initialized")
+        with nogil:
+            ret = ceph_mount(self.cluster, "/")
+        if ret != 0:
+            raise make_ex(ret, "error calling ceph_mount")
+        self.state = "mounted"
+
+    def statfs(self, path):
+        self.require_state("mounted")
+        path = cstr(path, 'path')
+        cdef:
+            char* _path = path
+            statvfs statbuf
+
+        with nogil:
+            ret = ceph_statfs(self.cluster, _path, &statbuf)
+        if ret < 0:
+            raise make_ex(ret, "statfs failed: %s" % path)
+        return {'f_bsize': statbuf.f_bsize,
+                'f_frsize': statbuf.f_frsize,
+                'f_blocks': statbuf.f_blocks,
+                'f_bfree': statbuf.f_bfree,
+                'f_bavail': statbuf.f_bavail,
+                'f_files': statbuf.f_files,
+                'f_ffree': statbuf.f_ffree,
+                'f_favail': statbuf.f_favail,
+                'f_fsid': statbuf.f_fsid,
+                'f_flag': statbuf.f_flag,
+                'f_namemax': statbuf.f_namemax}
+
+    def sync_fs(self):
+        self.require_state("mounted")
+        with nogil:
+            ret = ceph_sync_fs(self.cluster)
+        if ret < 0:
+            raise make_ex(ret, "sync_fs failed")
+
+    def getcwd(self):
+        self.require_state("mounted")
+        with nogil:
+            ret = ceph_getcwd(self.cluster)
+        return ret
+
+    def chdir(self, path):
+        self.require_state("mounted")
+
+        path = cstr(path, 'path')
+        cdef char* _path = path
+        with nogil:
+            ret = ceph_chdir(self.cluster, _path)
+        if ret < 0:
+            raise make_ex(ret, "chdir failed")
+
+    def opendir(self, path):
+        self.require_state("mounted")
+
+        path = cstr(path, 'path')
+        cdef:
+            char* _path = path
+            ceph_dir_result *dir_handler
+        with nogil:
+            ret = ceph_opendir(self.cluster, _path, &dir_handler);
+        if ret < 0:
+            raise make_ex(ret, "opendir failed")
+        d = DirResult()
+        d.handler = dir_handler
+        return d
+
+    def readdir(self, DirResult dir_handler):
+        self.require_state("mounted")
+
+        cdef ceph_dir_result *_dir_handler = dir_handler.handler
+        with nogil:
+            dirent = ceph_readdir(self.cluster, _dir_handler)
+        if not dirent:
+            return None
+
+        return DirEntry(d_ino=dirent.d_ino,
+                        d_off=dirent.d_off,
+                        d_reclen=dirent.d_reclen,
+                        d_type=dirent.d_type,
+                        d_name=dirent.d_name)
+
+    def closedir(self, DirResult dir_handler):
+        self.require_state("mounted")
+        cdef:
+            ceph_dir_result *_dir_handler = dir_handler.handler
+
+        with nogil:
+            ret = ceph_closedir(self.cluster, _dir_handler)
+        if ret < 0:
+            raise make_ex(ret, "closedir failed")
+
+    def mkdir(self, path, mode):
+        self.require_state("mounted")
+        path = cstr(path, 'path')
+        if not isinstance(mode, int):
+            raise TypeError('mode must be an int')
+        cdef:
+            char* _path = path
+            int _mode = mode
+        with nogil:
+            ret = ceph_mkdir(self.cluster, _path, _mode)
+        if ret < 0:
+            raise make_ex(ret, "error in mkdir '%s'" % path)
+
+    def mkdirs(self, path, mode):
+        self.require_state("mounted")
+        path = cstr(path, 'path')
+        if not isinstance(mode, int):
+            raise TypeError('mode must be an int')
+        cdef:
+            char* _path = path
+            int _mode = mode
+
+        with nogil:
+            ret = ceph_mkdirs(self.cluster, _path, _mode)
+        if ret < 0:
+            raise make_ex(ret, "error in mkdirs '%s'" % path)
+
+    def rmdir(self, path):
+        self.require_state("mounted")
+        path = cstr(path, 'path')
+        cdef char* _path = path
+        ret = ceph_rmdir(self.cluster, _path)
+        if ret < 0:
+            raise make_ex(ret, "error in rmdir '%s'" % path)
+
+    def open(self, path, flags, mode=0):
+        self.require_state("mounted")
+
+        path = cstr(path, 'path')
+        flags = cstr(flags, 'flags')
+        if not isinstance(mode, int):
+            raise TypeError('mode must be an int')
+        cephfs_flags = 0
+        if flags == '':
+            cephfs_flags = os.O_RDONLY
+        else:
+            for c in flags:
+                if c == 'r':
+                    cephfs_flags |= os.O_RDONLY
+                elif c == 'w':
+                    cephfs_flags |= os.O_WRONLY | os.O_TRUNC | os.O_CREAT
+                elif c == '+':
+                    cephfs_flags |= os.O_RDWR
+                else:
+                    raise OperationNotSupported(
+                        "open flags doesn't support %s" % c)
+
+        cdef:
+            char* _path = path
+            int _flags = cephfs_flags
+            int _mode = mode
+
+        with nogil:
+            ret = ceph_open(self.cluster, _path, _flags, _mode)
+        if ret < 0:
+            raise make_ex(ret, "error in open '%s'" % path)
+        return ret
+
+    def close(self, fd):
+        self.require_state("mounted")
+        if not isinstance(fd, int):
+            raise TypeError('fd must be an int')
+        cdef int _fd = fd
+        with nogil:
+            ret = ceph_close(self.cluster, _fd)
+        if ret < 0:
+            raise make_ex(ret, "error in close")
+
+    def read(self, fd, offset, l):
+        self.require_state("mounted")
+        if not isinstance(offset, int):
+            raise TypeError('offset must be an int')
+        if not isinstance(l, int):
+            raise TypeError('l must be an int')
+        if not isinstance(fd, int):
+            raise TypeError('fd must be an int')
+        cdef:
+            int _fd = fd
+            int64_t _offset = offset
+            int64_t _length = l
+
+            char *ret_buf
+            PyObject* ret_s = NULL
+
+        ret_s = PyBytes_FromStringAndSize(NULL, _length)
+        try:
+            ret_buf = PyBytes_AsString(ret_s)
+            with nogil:
+                ret = ceph_read(self.cluster, _fd, ret_buf, _length, _offset)
+            if ret < 0:
+                raise make_ex(ret, "error in read")
+
+            if ret != _length:
+                _PyBytes_Resize(&ret_s, ret)
+
+            return <object>ret_s
+        finally:
+            # We DECREF unconditionally: the cast to object above will have
+            # INCREFed if necessary. This also takes care of exceptions,
+            # including if _PyString_Resize fails (that will free the string
+            # itself and set ret_s to NULL, hence XDECREF).
+            ref.Py_XDECREF(ret_s)
+
+    def write(self, fd, buf, offset):
+        self.require_state("mounted")
+        if not isinstance(fd, int):
+            raise TypeError('fd must be an int')
+        if not isinstance(buf, bytes):
+            raise TypeError('buf must be a bytes')
+        if not isinstance(offset, int):
+            raise TypeError('offset must be an int')
+
+        cdef:
+            int _fd = fd
+            char *_data = buf
+            int64_t _offset = offset
+
+            size_t length = len(buf)
+
+        with nogil:
+            ret = ceph_write(self.cluster, _fd, _data, length, _offset)
+        if ret < 0:
+            raise make_ex(ret, "error in write")
+        return ret
+
+    def getxattr(self, path, name):
+        self.require_state("mounted")
+
+        path = cstr(path, 'path')
+        name = cstr(name, 'name')
+
+        cdef:
+            char* _path = path
+            char* _name = name
+
+            size_t ret_length = 255
+            char *ret_buf = NULL
+
+        try:
+            ret_buf = <char *>realloc_chk(ret_buf, ret_length)
+            with nogil:
+                ret = ceph_getxattr(self.cluster, _path, _name, ret_buf,
+                                    ret_length)
+
+            if ret < 0:
+                raise make_ex(ret, "error in getxattr")
+
+            if ret > ret_length:
+                ret_buf = <char *>realloc_chk(ret_buf, ret)
+                with nogil:
+                    ret = ceph_getxattr(self.cluster, _path, _name, ret_buf,
+                                        ret)
+                if ret < 0:
+                    raise make_ex(ret, "error in getxattr")
+
+            return ret_buf[:ret]
+        finally:
+            free(ret_buf)
+
+    def setxattr(self, path, name, value, flags):
+        self.require_state("mounted")
+
+        name = cstr(name, 'name')
+        path = cstr(path, 'path')
+        if not isinstance(flags, int):
+            raise TypeError('flags must be a int')
+        if not isinstance(value, bytes):
+            raise TypeError('value must be a bytes')
+
+        cdef:
+            char *_path = path
+            char *_name = name
+            char *_value = value
+            size_t _value_len = len(value)
+            int _flags = flags
+
+        with nogil:
+            ret = ceph_setxattr(self.cluster, _path, _name,
+                                _value, _value_len, _flags)
+        if ret < 0:
+            raise make_ex(ret, "error in setxattr")
+
+    def stat(self, path):
+        self.require_state("mounted")
+        path = cstr(path, 'path')
+
+        cdef:
+            char* _path = path
+            stat statbuf
+
+        with nogil:
+            ret = ceph_stat(self.cluster, _path, &statbuf)
+        if ret < 0:
+            raise make_ex(ret, "error in stat: %s" % path)
+        return StatResult(st_dev=statbuf.st_dev, st_ino=statbuf.st_ino,
+                          st_mode=statbuf.st_mode, st_nlink=statbuf.st_nlink,
+                          st_uid=statbuf.st_uid, st_gid=statbuf.st_gid,
+                          st_rdev=statbuf.st_rdev, st_size=statbuf.st_size,
+                          st_blksize=statbuf.st_blksize,
+                          st_blocks=statbuf.st_blocks,
+                          st_atime=datetime.fromtimestamp(statbuf.st_atime),
+                          st_mtime=datetime.fromtimestamp(statbuf.st_mtime),
+                          st_ctime=datetime.fromtimestamp(statbuf.st_ctime))
+
+    def symlink(self, existing, newname):
+        self.require_state("mounted")
+        existing = cstr(existing, 'existing')
+        newname = cstr(newname, 'newname')
+        cdef:
+            char* _existing = existing
+            char* _newname = newname
+
+        with nogil:
+            ret = ceph_symlink(self.cluster, _existing, _newname)
+        if ret < 0:
+            raise make_ex(ret, "error in symlink")
+
+    def unlink(self, path):
+        self.require_state("mounted")
+        path = cstr(path, 'path')
+        cdef char* _path = path
+        with nogil:
+            ret = ceph_unlink(self.cluster, _path)
+        if ret < 0:
+            raise make_ex(ret, "error in unlink: %s" % path)
+
+    def rename(self, src, dst):
+        self.require_state("mounted")
+
+        src = cstr(src, 'source')
+        dst = cstr(dst, 'destination')
+
+        cdef:
+            char* _src = src
+            char* _dst = dst
+
+        with nogil:
+            ret = ceph_rename(self.cluster, _src, _dst)
+        if ret < 0:
+            raise make_ex(ret, "error in rename '%s' to '%s'" % (src, dst))
+
+    def mds_command(self, mds_spec, args, input_data):
+        """
+        :return 3-tuple of output status int, output status string, output data
+        """
+        mds_spec = cstr(mds_spec, 'mds_spec')
+        args = cstr_list(args, 'args')
+        input_data = cstr(input_data, 'input_data')
+
+        cdef:
+            char *_mds_spec = opt_str(mds_spec)
+            char **_cmd = to_bytes_array(args)
+            size_t _cmdlen = len(args)
+
+            char *_inbuf = input_data
+            size_t _inbuf_len = len(input_data)
+
+            char *_outbuf
+            size_t _outbuf_len
+            char *_outs
+            size_t _outs_len
+
+        try:
+            with nogil:
+                ret = ceph_mds_command(self.cluster, _mds_spec,
+                                       <const char **>_cmd, _cmdlen,
+                                       <const char*>_inbuf, _inbuf_len,
+                                       &_outbuf, &_outbuf_len,
+                                       &_outs, &_outs_len)
+            if ret == 0:
+                my_outs = decode_cstr(_outs[:_outs_len])
+                my_outbuf = _outbuf[:_outbuf_len]
+                if _outs_len:
+                    ceph_buffer_free(_outs)
+                if _outbuf_len:
+                    ceph_buffer_free(_outbuf)
+                return (ret, my_outbuf, my_outs)
+            else:
+                return (ret, b"", "")
+        finally:
+            free(_cmd)
+
diff --git a/src/pybind/setup.py b/src/pybind/cephfs/setup.py
similarity index 80%
copy from src/pybind/setup.py
copy to src/pybind/cephfs/setup.py
index 1eda454..cf29229 100755
--- a/src/pybind/setup.py
+++ b/src/pybind/cephfs/setup.py
@@ -33,18 +33,20 @@ if (len(sys.argv) >= 2 and
         return x
 
 setup(
-    name = 'rbd',
+    name = 'cephfs',
     version = get_version(),
-    description = "Python libraries for the Ceph librbd library",
+    description = "Python libraries for the Ceph libcephfs library",
     long_description = (
         "This package contains Python libraries for interacting with Ceph's "
-        "RBD block device library."),
+        "cephfs library."),
     ext_modules = cythonize([
-        Extension("rbd",
-            ["rbd.pyx"],
-            libraries=["rbd"]
+        Extension("cephfs",
+            ["cephfs.pyx"],
+            libraries=["cephfs"]
             )
-    ], build_dir=os.environ.get("CYTHON_BUILD_DIR", None)),
+    ], build_dir=os.environ.get("CYTHON_BUILD_DIR", None), include_path=[
+        os.path.join(os.path.dirname(__file__), "..", "rados")]
+    ),
     cmdclass={
         "egg_info": EggInfoCommand,
     },
diff --git a/src/pybind/rados.py b/src/pybind/rados.py
deleted file mode 100644
index a599346..0000000
--- a/src/pybind/rados.py
+++ /dev/null
@@ -1,2467 +0,0 @@
-"""
-This module is a thin wrapper around librados.
-
-Copyright 2011, Hannu Valtonen <hannu.valtonen at ormod.com>
-"""
-from ctypes import CDLL, c_char_p, c_size_t, c_void_p, c_char, c_int, c_long, \
-    c_ulong, create_string_buffer, byref, Structure, c_uint64, c_ubyte, \
-    pointer, CFUNCTYPE, c_int64, c_uint32, c_uint8
-from ctypes.util import find_library
-import ctypes
-import errno
-import threading
-import time
-import sys
-
-from collections import Iterator
-from datetime import datetime
-from functools import wraps
-from itertools import chain
-
-ANONYMOUS_AUID = 0xffffffffffffffff
-ADMIN_AUID = 0
-LIBRADOS_ALL_NSPACES = '\001'
-
-LIBRADOS_OP_FLAG_FADVISE_RANDOM = 0x4
-LIBRADOS_OP_FLAG_FADVISE_SEQUENTIAL = 0x8
-LIBRADOS_OP_FLAG_FADVISE_WILLNEED = 0x10
-LIBRADOS_OP_FLAG_FADVISE_DONTNEED = 0x20
-LIBRADOS_OP_FLAG_FADVISE_NOCACHE = 0x40
-LIBRADOS_SNAP_HEAD = -2
-
-
-# Are we running Python 2.x
-_python2 = sys.hexversion < 0x03000000
-
-
-if _python2:
-    str_type = basestring
-else:
-    str_type = str
-
-
-class Error(Exception):
-    """ `Error` class, derived from `Exception` """
-    pass
-
-
-class InterruptedOrTimeoutError(Error):
-    """ `InterruptedOrTimeoutError` class, derived from `Error` """
-    pass
-
-
-class PermissionError(Error):
-    """ `PermissionError` class, derived from `Error` """
-    pass
-
-class PermissionDeniedError(Error):
-    """ deal with EACCES related. """
-    pass
-
-class ObjectNotFound(Error):
-    """ `ObjectNotFound` class, derived from `Error` """
-    pass
-
-
-class NoData(Error):
-    """ `NoData` class, derived from `Error` """
-    pass
-
-
-class ObjectExists(Error):
-    """ `ObjectExists` class, derived from `Error` """
-    pass
-
-
-class ObjectBusy(Error):
-    """ `ObjectBusy` class, derived from `Error` """
-    pass
-
-
-class IOError(Error):
-    """ `IOError` class, derived from `Error` """
-    pass
-
-
-class NoSpace(Error):
-    """ `NoSpace` class, derived from `Error` """
-    pass
-
-
-class IncompleteWriteError(Error):
-    """ `IncompleteWriteError` class, derived from `Error` """
-    pass
-
-
-class RadosStateError(Error):
-    """ `RadosStateError` class, derived from `Error` """
-    pass
-
-
-class IoctxStateError(Error):
-    """ `IoctxStateError` class, derived from `Error` """
-    pass
-
-
-class ObjectStateError(Error):
-    """ `ObjectStateError` class, derived from `Error` """
-    pass
-
-
-class LogicError(Error):
-    """ `` class, derived from `Error` """
-    pass
-
-
-class TimedOut(Error):
-    """ `TimedOut` class, derived from `Error` """
-    pass
-
-
-def make_ex(ret, msg):
-    """
-    Translate a librados return code into an exception.
-
-    :param ret: the return code
-    :type ret: int
-    :param msg: the error message to use
-    :type msg: str
-    :returns: a subclass of :class:`Error`
-    """
-
-    errors = {
-        errno.EPERM     : PermissionError,
-        errno.ENOENT    : ObjectNotFound,
-        errno.EIO       : IOError,
-        errno.ENOSPC    : NoSpace,
-        errno.EEXIST    : ObjectExists,
-        errno.EBUSY     : ObjectBusy,
-        errno.ENODATA   : NoData,
-        errno.EINTR     : InterruptedOrTimeoutError,
-        errno.ETIMEDOUT : TimedOut,
-        errno.EACCES    : PermissionDeniedError
-        }
-    ret = abs(ret)
-    if ret in errors:
-        return errors[ret](msg)
-    else:
-        return Error(msg + (": errno %s" % errno.errorcode[ret]))
-
-
-class rados_pool_stat_t(Structure):
-    """ Usage information for a pool """
-    _fields_ = [("num_bytes", c_uint64),
-                ("num_kb", c_uint64),
-                ("num_objects", c_uint64),
-                ("num_object_clones", c_uint64),
-                ("num_object_copies", c_uint64),
-                ("num_objects_missing_on_primary", c_uint64),
-                ("num_objects_unfound", c_uint64),
-                ("num_objects_degraded", c_uint64),
-                ("num_rd", c_uint64),
-                ("num_rd_kb", c_uint64),
-                ("num_wr", c_uint64),
-                ("num_wr_kb", c_uint64)]
-
-
-class rados_cluster_stat_t(Structure):
-    """ Cluster-wide usage information """
-    _fields_ = [("kb", c_uint64),
-                ("kb_used", c_uint64),
-                ("kb_avail", c_uint64),
-                ("num_objects", c_uint64)]
-
-
-class timeval(Structure):
-    _fields_ = [("tv_sec", c_long), ("tv_usec", c_long)]
-
-
-class Version(object):
-    """ Version information """
-    def __init__(self, major, minor, extra):
-        self.major = major
-        self.minor = minor
-        self.extra = extra
-
-    def __str__(self):
-        return "%d.%d.%d" % (self.major, self.minor, self.extra)
-
-
-class RadosThread(threading.Thread):
-    def __init__(self, target, args=None):
-        self.args = args
-        self.target = target
-        threading.Thread.__init__(self)
-
-    def run(self):
-        self.retval = self.target(*self.args)
-
-# time in seconds between each call to t.join() for child thread
-POLL_TIME_INCR = 0.5
-
-
-def run_in_thread(target, args, timeout=0):
-    interrupt = False
-
-    countdown = timeout
-    t = RadosThread(target, args)
-
-    # allow the main thread to exit (presumably, avoid a join() on this
-    # subthread) before this thread terminates.  This allows SIGINT
-    # exit of a blocked call.  See below.
-    t.daemon = True
-
-    t.start()
-    try:
-        # poll for thread exit
-        while t.is_alive():
-            t.join(POLL_TIME_INCR)
-            if timeout and t.is_alive():
-                countdown = countdown - POLL_TIME_INCR
-                if countdown <= 0:
-                    raise KeyboardInterrupt
-
-        t.join()        # in case t exits before reaching the join() above
-    except KeyboardInterrupt:
-        # ..but allow SIGINT to terminate the waiting.  Note: this
-        # relies on the Linux kernel behavior of delivering the signal
-        # to the main thread in preference to any subthread (all that's
-        # strictly guaranteed is that *some* thread that has the signal
-        # unblocked will receive it).  But there doesn't seem to be
-        # any interface to create t with SIGINT blocked.
-        interrupt = True
-
-    if interrupt:
-        t.retval = -errno.EINTR
-    return t.retval
-
-
-# helper to specify an optional argument, where in addition to `cls`, `None`
-# is also acceptable
-def opt(cls):
-    return (cls, None)
-
-
-# validate argument types of an instance method
-# kwargs is an un-ordered dict, so use args instead
-def requires(*types):
-    def is_type_of(v, t):
-        if t is None:
-            return v is None
-        else:
-            return isinstance(v, t)
-
-    def check_type(val, arg_name, arg_type):
-        if isinstance(arg_type, tuple):
-            if any(is_type_of(val, t) for t in arg_type):
-                return
-            type_names = ' or '.join('None' if t is None else t.__name__
-                                     for t in arg_type)
-            raise TypeError('%s must be %s' % (arg_name, type_names))
-        else:
-            if is_type_of(val, arg_type):
-                return
-            assert(arg_type is not None)
-            raise TypeError('%s must be %s' % (arg_name, arg_type.__name__))
-
-    def wrapper(f):
-        @wraps(f)
-        def validate_func(*args, **kwargs):
-            # ignore the `self` arg
-            pos_args = zip(args[1:], types)
-            named_args = ((kwargs[name], (name, spec)) for name, spec in types
-                          if name in kwargs)
-            for arg_val, (arg_name, arg_type) in chain(pos_args, named_args):
-                check_type(arg_val, arg_name, arg_type)
-            return f(*args, **kwargs)
-        return validate_func
-    return wrapper
-
-
-def cstr(val, encoding="utf-8"):
-    """
-    Create a C-style string from a Python string
-
-    :param str val: Python string
-    :param encoding: Encoding to use
-    :rtype: c_char_p
-    """
-    if val is None:
-        return c_char_p(None)
-
-    if _python2 and isinstance(val, str):
-        # Don't encode str on Python 2, as it's already an 8-bit string
-        return c_char_p(val)
-    else:
-        return c_char_p(val.encode(encoding))
-
-
-def decode_cstr(addr, size=-1, encoding="utf-8"):
-    """
-    Decode a C-style string into a Python string.
-
-    Return None if a the C string is a NULL pointer.
-
-    :param c_char_p addr: C-style string
-    :param int: String size (assume NUL-terminated if size is -1)
-    :param encoding: Encoding to use
-    :rtype: str or None
-    """
-    if not addr:
-        # NULL pointer
-        return None
-
-    return ctypes.string_at(addr, size).decode(encoding)
-
-
-class Rados(object):
-    """librados python wrapper"""
-    def require_state(self, *args):
-        """
-        Checks if the Rados object is in a special state
-
-        :raises: RadosStateError
-        """
-        if self.state in args:
-            return
-        raise RadosStateError("You cannot perform that operation on a \
-Rados object in state %s." % self.state)
-
-    @requires(('rados_id', opt(str_type)), ('name', opt(str_type)), ('clustername', opt(str_type)),
-              ('conffile', opt(str_type)))
-    def __init__(self, rados_id=None, name=None, clustername=None,
-                 conf_defaults=None, conffile=None, conf=None, flags=0):
-        library_path = find_library('rados')
-        # maybe find_library can not find it correctly on all platforms,
-        # so fall back to librados.so.2 in such case.
-        self.librados = CDLL(library_path if library_path is not None else 'librados.so.2')
-
-        self.parsed_args = []
-        self.conf_defaults = conf_defaults
-        self.conffile = conffile
-        self.cluster = c_void_p()
-        self.rados_id = rados_id
-        if rados_id and name:
-            raise Error("Rados(): can't supply both rados_id and name")
-        elif rados_id:
-            name = 'client.' + rados_id
-        elif name is None:
-            name = 'client.admin'
-        if clustername is None:
-            clustername = 'ceph'
-        ret = run_in_thread(self.librados.rados_create2,
-                            (byref(self.cluster), cstr(clustername),
-                            cstr(name), c_uint64(flags)))
-
-        if ret != 0:
-            raise Error("rados_initialize failed with error code: %d" % ret)
-        self.state = "configuring"
-        # order is important: conf_defaults, then conffile, then conf
-        if conf_defaults:
-            for key, value in conf_defaults.items():
-                self.conf_set(key, value)
-        if conffile is not None:
-            # read the default conf file when '' is given
-            if conffile == '':
-                conffile = None
-            self.conf_read_file(conffile)
-        if conf:
-            for key, value in conf.items():
-                self.conf_set(key, value)
-
-    def shutdown(self):
-        """
-        Disconnects from the cluster.  Call this explicitly when a
-        Rados.connect()ed object is no longer used.
-        """
-        if hasattr(self, "state") and self.state != "shutdown":
-            run_in_thread(self.librados.rados_shutdown, (self.cluster,))
-            self.state = "shutdown"
-
-    def __enter__(self):
-        self.connect()
-        return self
-
-    def __exit__(self, type_, value, traceback):
-        self.shutdown()
-        return False
-
-    def version(self):
-        """
-        Get the version number of the ``librados`` C library.
-
-        :returns: a tuple of ``(major, minor, extra)`` components of the
-                  librados version
-        """
-        major = c_int(0)
-        minor = c_int(0)
-        extra = c_int(0)
-        run_in_thread(self.librados.rados_version,
-                      (byref(major), byref(minor), byref(extra)))
-        return Version(major.value, minor.value, extra.value)
-
-
-    @requires(('path', opt(str_type)))
-    def conf_read_file(self, path=None):
-        """
-        Configure the cluster handle using a Ceph config file.
-
-        :param path: path to the config file
-        :type path: str
-        """
-        self.require_state("configuring", "connected")
-        ret = run_in_thread(self.librados.rados_conf_read_file,
-                            (self.cluster, cstr(path)))
-        if (ret != 0):
-            raise make_ex(ret, "error calling conf_read_file")
-
-    def conf_parse_argv(self, args):
-        """
-        Parse known arguments from args, and remove; returned
-        args contain only those unknown to ceph
-        """
-        self.require_state("configuring", "connected")
-        if not args:
-            return
-        # create instances of arrays of c_char_p's, both len(args) long
-        # cretargs will always be a subset of cargs (perhaps identical)
-        cargs = (c_char_p * len(args))(*map(cstr, args))
-        cretargs = (c_char_p * len(args))()
-        ret = run_in_thread(self.librados.rados_conf_parse_argv_remainder,
-                            (self.cluster, len(args), cargs, cretargs))
-        if ret:
-            raise make_ex(ret, "error calling conf_parse_argv_remainder")
-
-        # cretargs was allocated with fixed length; collapse return
-        # list to eliminate any missing args
-        retargs = [a.decode('utf-8') for a in cretargs if a is not None]
-        self.parsed_args = args
-        return retargs
-
-    def conf_parse_env(self, var='CEPH_ARGS'):
-        """
-        Parse known arguments from an environment variable, normally
-        CEPH_ARGS.
-        """
-        self.require_state("configuring", "connected")
-        if not var:
-            return
-        ret = run_in_thread(self.librados.rados_conf_parse_env,
-                            (self.cluster, cstr(var)))
-        if (ret != 0):
-            raise make_ex(ret, "error calling conf_parse_env")
-
-    @requires(('option', str_type))
-    def conf_get(self, option):
-        """
-        Get the value of a configuration option
-
-        :param option: which option to read
-        :type option: str
-
-        :returns: str - value of the option or None
-        :raises: :class:`TypeError`
-        """
-        self.require_state("configuring", "connected")
-        length = 20
-        while True:
-            ret_buf = create_string_buffer(length)
-            ret = run_in_thread(self.librados.rados_conf_get,
-                                (self.cluster, cstr(option), ret_buf,
-                                c_size_t(length)))
-            if (ret == 0):
-                return decode_cstr(ret_buf)
-            elif (ret == -errno.ENAMETOOLONG):
-                length = length * 2
-            elif (ret == -errno.ENOENT):
-                return None
-            else:
-                raise make_ex(ret, "error calling conf_get")
-
-    @requires(('option', str_type), ('val', str_type))
-    def conf_set(self, option, val):
-        """
-        Set the value of a configuration option
-
-        :param option: which option to set
-        :type option: str
-        :param option: value of the option
-        :type option: str
-
-        :raises: :class:`TypeError`, :class:`ObjectNotFound`
-        """
-        self.require_state("configuring", "connected")
-        ret = run_in_thread(self.librados.rados_conf_set,
-                            (self.cluster, cstr(option), cstr(val)))
-        if (ret != 0):
-            raise make_ex(ret, "error calling conf_set")
-
-    def ping_monitor(self, mon_id):
-        """
-        Ping a monitor to assess liveness
-
-        May be used as a simply way to assess liveness, or to obtain
-        information about the monitor in a simple way even in the
-        absence of quorum.
-
-        :param mon_id: the ID portion of the monitor's name (i.e., mon.<ID>)
-        :type mon_id: str
-        :returns: the string reply from the monitor
-        """
-
-        self.require_state("configuring", "connected")
-
-        outstrp = pointer(pointer(c_char()))
-        outstrlen = c_long()
-
-        ret = run_in_thread(self.librados.rados_ping_monitor,
-                            (self.cluster, cstr(mon_id),
-                             outstrp, byref(outstrlen)))
-
-        my_outstr = outstrp.contents[:(outstrlen.value)]
-        if outstrlen.value:
-            run_in_thread(self.librados.rados_buffer_free, (outstrp.contents,))
-
-        if ret != 0:
-            raise make_ex(ret, "error calling ping_monitor")
-        return decode_cstr(my_outstr)
-
-    def connect(self, timeout=0):
-        """
-        Connect to the cluster.  Use shutdown() to release resources.
-        """
-        self.require_state("configuring")
-        ret = run_in_thread(self.librados.rados_connect, (self.cluster,),
-                            timeout)
-        if (ret != 0):
-            raise make_ex(ret, "error connecting to the cluster")
-        self.state = "connected"
-
-    def get_cluster_stats(self):
-        """
-        Read usage info about the cluster
-
-        This tells you total space, space used, space available, and number
-        of objects. These are not updated immediately when data is written,
-        they are eventually consistent.
-
-        :returns: dict - contains the following keys:
-
-            - ``kb`` (int) - total space
-
-            - ``kb_used`` (int) - space used
-
-            - ``kb_avail`` (int) - free space available
-
-            - ``num_objects`` (int) - number of objects
-
-        """
-        stats = rados_cluster_stat_t()
-        ret = run_in_thread(self.librados.rados_cluster_stat,
-                            (self.cluster, byref(stats)))
-        if ret < 0:
-            raise make_ex(
-                ret, "Rados.get_cluster_stats(%s): get_stats failed" % self.rados_id)
-        return {'kb': stats.kb,
-                'kb_used': stats.kb_used,
-                'kb_avail': stats.kb_avail,
-                'num_objects': stats.num_objects}
-
-    @requires(('pool_name', str_type))
-    def pool_exists(self, pool_name):
-        """
-        Checks if a given pool exists.
-
-        :param pool_name: name of the pool to check
-        :type pool_name: str
-
-        :raises: :class:`TypeError`, :class:`Error`
-        :returns: bool - whether the pool exists, false otherwise.
-        """
-        self.require_state("connected")
-        ret = run_in_thread(self.librados.rados_pool_lookup,
-                            (self.cluster, cstr(pool_name)))
-        if (ret >= 0):
-            return True
-        elif (ret == -errno.ENOENT):
-            return False
-        else:
-            raise make_ex(ret, "error looking up pool '%s'" % pool_name)
-
-    @requires(('pool_name', str_type))
-    def pool_lookup(self, pool_name):
-        """
-        Returns a pool's ID based on its name.
-
-        :param pool_name: name of the pool to look up
-        :type pool_name: str
-
-        :raises: :class:`TypeError`, :class:`Error`
-        :returns: int - pool ID, or None if it doesn't exist
-        """
-        self.require_state("connected")
-        ret = run_in_thread(self.librados.rados_pool_lookup,
-                            (self.cluster, cstr(pool_name)))
-        if (ret >= 0):
-            return int(ret)
-        elif (ret == -errno.ENOENT):
-            return None
-        else:
-            raise make_ex(ret, "error looking up pool '%s'" % pool_name)
-
-    @requires(('pool_id', int))
-    def pool_reverse_lookup(self, pool_id):
-        """
-        Returns a pool's name based on its ID.
-
-        :param pool_id: ID of the pool to look up
-        :type pool_id: int
-
-        :raises: :class:`TypeError`, :class:`Error`
-        :returns: string - pool name, or None if it doesn't exist
-        """
-        self.require_state("connected")
-        size = c_size_t(512)
-        while True:
-            c_name = create_string_buffer(size.value)
-            ret = run_in_thread(self.librados.rados_pool_reverse_lookup,
-                                (self.cluster, c_int64(pool_id), byref(c_name), size))
-            if ret > size.value:
-                size = c_size_t(ret)
-            elif ret == -errno.ENOENT:
-                return None
-            elif ret < 0:
-                raise make_ex(ret, "error reverse looking up pool '%s'" % pool_id)
-            else:
-                return decode_cstr(c_name.value)
-                break
-
-    @requires(('pool_name', str_type), ('auid', opt(int)), ('crush_rule', opt(int)))
-    def create_pool(self, pool_name, auid=None, crush_rule=None):
-        """
-        Create a pool:
-        - with default settings: if auid=None and crush_rule=None
-        - owned by a specific auid: auid given and crush_rule=None
-        - with a specific CRUSH rule: if auid=None and crush_rule given
-        - with a specific CRUSH rule and auid: if auid and crush_rule given
-
-        :param pool_name: name of the pool to create
-        :type pool_name: str
-        :param auid: the id of the owner of the new pool
-        :type auid: int
-        :param crush_rule: rule to use for placement in the new pool
-        :type crush_rule: int
-
-        :raises: :class:`TypeError`, :class:`Error`
-        """
-        self.require_state("connected")
-        if auid is None:
-            if crush_rule is None:
-                ret = run_in_thread(self.librados.rados_pool_create,
-                                    (self.cluster, cstr(pool_name)))
-            else:
-                ret = run_in_thread(self.librados.
-                                    rados_pool_create_with_crush_rule,
-                                    (self.cluster, cstr(pool_name),
-                                     c_ubyte(crush_rule)))
-
-        elif crush_rule is None:
-            ret = run_in_thread(self.librados.rados_pool_create_with_auid,
-                                (self.cluster, cstr(pool_name),
-                                 c_uint64(auid)))
-        else:
-            ret = run_in_thread(self.librados.rados_pool_create_with_all,
-                                (self.cluster, cstr(pool_name),
-                                 c_uint64(auid), c_ubyte(crush_rule)))
-        if ret < 0:
-            raise make_ex(ret, "error creating pool '%s'" % pool_name)
-
-    @requires(('pool_id', int))
-    def get_pool_base_tier(self, pool_id):
-        """
-        Get base pool
-
-        :returns: base pool, or pool_id if tiering is not configured for the pool
-        """
-        self.require_state("connected")
-        base_tier = c_int64(0)
-        ret = run_in_thread(self.librados.rados_pool_get_base_tier,
-                            (self.cluster, c_int64(pool_id), byref(base_tier)))
-        if ret < 0:
-            raise make_ex(ret, "get_pool_base_tier(%d)" % pool_id)
-        return base_tier.value
-
-    @requires(('pool_name', str_type))
-    def delete_pool(self, pool_name):
-        """
-        Delete a pool and all data inside it.
-
-        The pool is removed from the cluster immediately,
-        but the actual data is deleted in the background.
-
-        :param pool_name: name of the pool to delete
-        :type pool_name: str
-
-        :raises: :class:`TypeError`, :class:`Error`
-        """
-        self.require_state("connected")
-        ret = run_in_thread(self.librados.rados_pool_delete,
-                            (self.cluster, cstr(pool_name)))
-        if ret < 0:
-            raise make_ex(ret, "error deleting pool '%s'" % pool_name)
-
-    def list_pools(self):
-        """
-        Gets a list of pool names.
-
-        :returns: list - of pool names.
-        """
-        self.require_state("connected")
-        size = c_size_t(512)
-        while True:
-            c_names = create_string_buffer(size.value)
-            ret = run_in_thread(self.librados.rados_pool_list,
-                                (self.cluster, byref(c_names), size))
-            if ret > size.value:
-                size = c_size_t(ret)
-            else:
-                break
-
-        return [decode_cstr(name) for name in c_names.raw.split(b'\0') if len(name) > 0]
-
-    def get_fsid(self):
-        """
-        Get the fsid of the cluster as a hexadecimal string.
-
-        :raises: :class:`Error`
-        :returns: str - cluster fsid
-        """
-        self.require_state("connected")
-        buf_len = 37
-        fsid = create_string_buffer(buf_len)
-        ret = run_in_thread(self.librados.rados_cluster_fsid,
-                            (self.cluster, byref(fsid), c_size_t(buf_len)))
-        if ret < 0:
-            raise make_ex(ret, "error getting cluster fsid")
-        return fsid.value
-
-    @requires(('ioctx_name', str_type))
-    def open_ioctx(self, ioctx_name):
-        """
-        Create an io context
-
-        The io context allows you to perform operations within a particular
-        pool.
-
-        :param ioctx_name: name of the pool
-        :type ioctx_name: str
-
-        :raises: :class:`TypeError`, :class:`Error`
-        :returns: Ioctx - Rados Ioctx object
-        """
-        self.require_state("connected")
-        ioctx = c_void_p()
-        ret = run_in_thread(self.librados.rados_ioctx_create,
-                            (self.cluster, cstr(ioctx_name), byref(ioctx)))
-        if ret < 0:
-            raise make_ex(ret, "error opening pool '%s'" % ioctx_name)
-        return Ioctx(ioctx_name, self.librados, ioctx)
-
-    def mon_command(self, cmd, inbuf, timeout=0, target=None):
-        """
-        mon_command[_target](cmd, inbuf, outbuf, outbuflen, outs, outslen)
-        returns (int ret, string outbuf, string outs)
-        """
-        self.require_state("connected")
-        outbufp = pointer(pointer(c_char()))
-        outbuflen = c_long()
-        outsp = pointer(pointer(c_char()))
-        outslen = c_long()
-        cmdarr = (c_char_p * len(cmd))(*map(cstr, cmd))
-
-        if target:
-            ret = run_in_thread(self.librados.rados_mon_command_target,
-                                (self.cluster, cstr(target), cmdarr,
-                                 len(cmd), c_char_p(inbuf), len(inbuf),
-                                 outbufp, byref(outbuflen), outsp,
-                                 byref(outslen)), timeout)
-        else:
-            ret = run_in_thread(self.librados.rados_mon_command,
-                                (self.cluster, cmdarr, len(cmd),
-                                 c_char_p(inbuf), len(inbuf),
-                                 outbufp, byref(outbuflen), outsp, byref(outslen)),
-                                timeout)
-
-        # copy returned memory (ctypes makes a copy, not a reference)
-        my_outbuf = outbufp.contents[:(outbuflen.value)]
-        my_outs = decode_cstr(outsp.contents, outslen.value)
-
-        # free callee's allocations
-        if outbuflen.value:
-            run_in_thread(self.librados.rados_buffer_free, (outbufp.contents,))
-        if outslen.value:
-            run_in_thread(self.librados.rados_buffer_free, (outsp.contents,))
-
-        return (ret, my_outbuf, my_outs)
-
-    def osd_command(self, osdid, cmd, inbuf, timeout=0):
-        """
-        osd_command(osdid, cmd, inbuf, outbuf, outbuflen, outs, outslen)
-        returns (int ret, string outbuf, string outs)
-        """
-        self.require_state("connected")
-        outbufp = pointer(pointer(c_char()))
-        outbuflen = c_long()
-        outsp = pointer(pointer(c_char()))
-        outslen = c_long()
-        cmdarr = (c_char_p * len(cmd))(*map(cstr, cmd))
-        ret = run_in_thread(self.librados.rados_osd_command,
-                            (self.cluster, osdid, cmdarr, len(cmd),
-                             c_char_p(inbuf), len(inbuf),
-                             outbufp, byref(outbuflen), outsp, byref(outslen)),
-                            timeout)
-
-        # copy returned memory (ctypes makes a copy, not a reference)
-        my_outbuf = outbufp.contents[:(outbuflen.value)]
-        my_outs = decode_cstr(outsp.contents, outslen.value)
-
-        # free callee's allocations
-        if outbuflen.value:
-            run_in_thread(self.librados.rados_buffer_free, (outbufp.contents,))
-        if outslen.value:
-            run_in_thread(self.librados.rados_buffer_free, (outsp.contents,))
-
-        return (ret, my_outbuf, my_outs)
-
-    def pg_command(self, pgid, cmd, inbuf, timeout=0):
-        """
-        pg_command(pgid, cmd, inbuf, outbuf, outbuflen, outs, outslen)
-        returns (int ret, string outbuf, string outs)
-        """
-        self.require_state("connected")
-        outbufp = pointer(pointer(c_char()))
-        outbuflen = c_long()
-        outsp = pointer(pointer(c_char()))
-        outslen = c_long()
-        cmdarr = (c_char_p * len(cmd))(*map(cstr, cmd))
-        ret = run_in_thread(self.librados.rados_pg_command,
-                            (self.cluster, cstr(pgid), cmdarr, len(cmd),
-                             c_char_p(inbuf), len(inbuf),
-                             outbufp, byref(outbuflen), outsp, byref(outslen)),
-                            timeout)
-
-        # copy returned memory (ctypes makes a copy, not a reference)
-        my_outbuf = outbufp.contents[:(outbuflen.value)]
-        my_outs = decode_cstr(outsp.contents, outslen.value)
-
-        # free callee's allocations
-        if outbuflen.value:
-            run_in_thread(self.librados.rados_buffer_free, (outbufp.contents,))
-        if outslen.value:
-            run_in_thread(self.librados.rados_buffer_free, (outsp.contents,))
-
-        return (ret, my_outbuf, my_outs)
-
-    def wait_for_latest_osdmap(self):
-        self.require_state("connected")
-        return run_in_thread(self.librados.rados_wait_for_latest_osdmap, (self.cluster,))
-
-    def blacklist_add(self, client_address, expire_seconds=0):
-        """
-        Blacklist a client from the OSDs
-
-        :param client_address: client address
-        :type client_address: str
-        :param expire_seconds: number of seconds to blacklist
-        :type expire_seconds: int
-
-        :raises: :class:`Error`
-        """
-        self.require_state("connected")
-        ret = run_in_thread(self.librados.rados_blacklist_add,
-                            (self.cluster, cstr(client_address),
-                             c_uint32(expire_seconds)))
-        if ret < 0:
-            raise make_ex(ret, "error blacklisting client '%s'" % client_address)
-
-
-class OmapIterator(Iterator):
-    """Omap iterator"""
-    def __init__(self, ioctx, ctx):
-        self.ioctx = ioctx
-        self.ctx = ctx
-
-    def __iter__(self):
-        return self
-
-    def next(self):
-        return self.__next__()
-
-    def __next__(self):
-        """
-        Get the next key-value pair in the object
-        :returns: next rados.OmapItem
-        """
-        key_ = c_char_p(0)
-        val_ = c_char_p(0)
-        len_ = c_int(0)
-        ret = run_in_thread(self.ioctx.librados.rados_omap_get_next,
-                      (self.ctx, byref(key_), byref(val_), byref(len_)))
-        if (ret != 0):
-            raise make_ex(ret, "error iterating over the omap")
-        if key_.value is None:
-            raise StopIteration()
-        key = decode_cstr(key_)
-        val = None
-        if val_.value is not None:
-            val = ctypes.string_at(val_, len_)
-        return (key, val)
-
-    def __del__(self):
-        run_in_thread(self.ioctx.librados.rados_omap_get_end, (self.ctx,))
-
-
-class ObjectIterator(Iterator):
-    """rados.Ioctx Object iterator"""
-    def __init__(self, ioctx):
-        self.ioctx = ioctx
-        self.ctx = c_void_p()
-        ret = run_in_thread(self.ioctx.librados.rados_nobjects_list_open,
-                            (self.ioctx.io, byref(self.ctx)))
-        if ret < 0:
-            raise make_ex(ret, "error iterating over the objects in ioctx '%s'"
-                          % self.ioctx.name)
-
-    def __iter__(self):
-        return self
-
-    def next(self):
-        return self.__next__()
-
-    def __next__(self):
-        """
-        Get the next object name and locator in the pool
-
-        :raises: StopIteration
-        :returns: next rados.Ioctx Object
-        """
-        key_ = c_char_p()
-        locator_ = c_char_p()
-        nspace_ = c_char_p()
-        ret = run_in_thread(self.ioctx.librados.rados_nobjects_list_next,
-                            (self.ctx, byref(key_), byref(locator_), byref(nspace_)))
-        if ret < 0:
-            raise StopIteration()
-
-        key = decode_cstr(key_)
-        locator = decode_cstr(locator_)
-        nspace = decode_cstr(nspace_)
-        return Object(self.ioctx, key, locator, nspace)
-
-    def __del__(self):
-        run_in_thread(self.ioctx.librados.rados_nobjects_list_close, (self.ctx,))
-
-
-class XattrIterator(Iterator):
-    """Extended attribute iterator"""
-    def __init__(self, ioctx, it, oid):
-        self.ioctx = ioctx
-        self.it = it
-        self.oid = oid
-
-    def __iter__(self):
-        return self
-
-    def next(self):
-        return self.__next__()
-
-    def __next__(self):
-        """
-        Get the next xattr on the object
-
-        :raises: StopIteration
-        :returns: pair - of name and value of the next Xattr
-        """
-        name_ = c_char_p(0)
-        val_ = c_char_p(0)
-        len_ = c_int(0)
-        ret = run_in_thread(self.ioctx.librados.rados_getxattrs_next,
-                            (self.it, byref(name_), byref(val_), byref(len_)))
-        if (ret != 0):
-            raise make_ex(ret, "error iterating over the extended attributes \
-in '%s'" % self.oid)
-        if name_.value is None:
-            raise StopIteration()
-        name = decode_cstr(name_)
-        val = ctypes.string_at(val_, len_)
-        return (name, val)
-
-    def __del__(self):
-        run_in_thread(self.ioctx.librados.rados_getxattrs_end, (self.it,))
-
-
-class SnapIterator(Iterator):
-    """Snapshot iterator"""
-    def __init__(self, ioctx):
-        self.ioctx = ioctx
-        # We don't know how big a buffer we need until we've called the
-        # function. So use the exponential doubling strategy.
-        num_snaps = 10
-        while True:
-            self.snaps = (ctypes.c_uint64 * num_snaps)()
-            ret = run_in_thread(self.ioctx.librados.rados_ioctx_snap_list,
-                                (self.ioctx.io, self.snaps, c_int(num_snaps)))
-            if (ret >= 0):
-                self.max_snap = ret
-                break
-            elif (ret != -errno.ERANGE):
-                raise make_ex(ret, "error calling rados_snap_list for \
-ioctx '%s'" % self.ioctx.name)
-            num_snaps = num_snaps * 2
-        self.cur_snap = 0
-
-    def __iter__(self):
-        return self
-
-    def next(self):
-        return self.__next__()
-
-    def __next__(self):
-        """
-        Get the next Snapshot
-
-        :raises: :class:`Error`, StopIteration
-        :returns: Snap - next snapshot
-        """
-        if (self.cur_snap >= self.max_snap):
-            raise StopIteration
-        snap_id = self.snaps[self.cur_snap]
-        name_len = 10
-        while True:
-            name = create_string_buffer(name_len)
-            ret = run_in_thread(self.ioctx.librados.rados_ioctx_snap_get_name,
-                                (self.ioctx.io, c_uint64(snap_id), byref(name),
-                                 c_int(name_len)))
-            if (ret == 0):
-                name_len = ret
-                break
-            elif (ret != -errno.ERANGE):
-                raise make_ex(ret, "rados_snap_get_name error")
-            name_len = name_len * 2
-        snap = Snap(self.ioctx, decode_cstr(name), snap_id)
-        self.cur_snap = self.cur_snap + 1
-        return snap
-
-
-class Snap(object):
-    """Snapshot object"""
-    def __init__(self, ioctx, name, snap_id):
-        self.ioctx = ioctx
-        self.name = name
-        self.snap_id = snap_id
-
-    def __str__(self):
-        return "rados.Snap(ioctx=%s,name=%s,snap_id=%d)" \
-            % (str(self.ioctx), self.name, self.snap_id)
-
-    def get_timestamp(self):
-        """
-        Find when a snapshot in the current pool occurred
-
-        :raises: :class:`Error`
-        :returns: datetime - the data and time the snapshot was created
-        """
-        snap_time = c_long(0)
-        ret = run_in_thread(self.ioctx.librados.rados_ioctx_snap_get_stamp,
-                            (self.ioctx.io, self.snap_id, byref(snap_time)))
-        if (ret != 0):
-            raise make_ex(ret, "rados_ioctx_snap_get_stamp error")
-        return datetime.fromtimestamp(snap_time.value)
-
-
-class Completion(object):
-    """completion object"""
-    def __init__(self, ioctx, rados_comp, oncomplete, onsafe,
-                 complete_cb, safe_cb):
-        self.rados_comp = rados_comp
-        self.oncomplete = oncomplete
-        self.onsafe = onsafe
-        self.ioctx = ioctx
-        self.complete_cb = complete_cb
-        self.safe_cb = safe_cb
-
-    def is_safe(self):
-        """
-        Is an asynchronous operation safe?
-
-        This does not imply that the safe callback has finished.
-
-        :returns: True if the operation is safe
-        """
-        return run_in_thread(self.ioctx.librados.rados_aio_is_safe,
-                             (self.rados_comp,)) == 1
-
-    def is_complete(self):
-        """
-        Has an asynchronous operation completed?
-
-        This does not imply that the safe callback has finished.
-
-        :returns: True if the operation is completed
-        """
-        return run_in_thread(self.ioctx.librados.rados_aio_is_complete,
-                             (self.rados_comp,)) == 1
-
-    def wait_for_safe(self):
-        """
-        Wait for an asynchronous operation to be marked safe
-
-        This does not imply that the safe callback has finished.
-        """
-        run_in_thread(self.ioctx.librados.rados_aio_wait_for_safe,
-                      (self.rados_comp,))
-
-    def wait_for_complete(self):
-        """
-        Wait for an asynchronous operation to complete
-
-        This does not imply that the complete callback has finished.
-        """
-        run_in_thread(self.ioctx.librados.rados_aio_wait_for_complete,
-                      (self.rados_comp,))
-
-    def wait_for_safe_and_cb(self):
-        """
-        Wait for an asynchronous operation to be marked safe and for
-        the safe callback to have returned
-        """
-        run_in_thread(self.ioctx.librados.rados_aio_wait_for_safe_and_cb,
-                      (self.rados_comp,))
-
-    def wait_for_complete_and_cb(self):
-        """
-        Wait for an asynchronous operation to complete and for the
-        complete callback to have returned
-
-        :returns:  whether the operation is completed
-        """
-        return run_in_thread(
-            self.ioctx.librados.rados_aio_wait_for_complete_and_cb,
-            (self.rados_comp,)
-        )
-
-    def get_return_value(self):
-        """
-        Get the return value of an asychronous operation
-
-        The return value is set when the operation is complete or safe,
-        whichever comes first.
-
-        :returns: int - return value of the operation
-        """
-        return run_in_thread(self.ioctx.librados.rados_aio_get_return_value,
-                             (self.rados_comp,))
-
-    def __del__(self):
-        """
-        Release a completion
-
-        Call this when you no longer need the completion. It may not be
-        freed immediately if the operation is not acked and committed.
-        """
-        run_in_thread(self.ioctx.librados.rados_aio_release,
-                      (self.rados_comp,))
-
-
-class WriteOpCtx(object):
-    """write operation context manager"""
-    def __init__(self, ioctx):
-        self.ioctx = ioctx
-
-    def __enter__(self):
-        self.ioctx.librados.rados_create_write_op.restype = c_void_p
-        ret = run_in_thread(self.ioctx.librados.rados_create_write_op, (None,))
-        self.write_op = ret
-        return ret
-
-    def __exit__(self, type, msg, traceback):
-        self.ioctx.librados.rados_release_write_op.argtypes = [c_void_p]
-        run_in_thread(self.ioctx.librados.rados_release_write_op, (c_void_p(self.write_op),))
-
-
-class ReadOpCtx(object):
-    """read operation context manager"""
-    def __init__(self, ioctx):
-        self.ioctx = ioctx
-
-    def __enter__(self):
-        self.ioctx.librados.rados_create_read_op.restype = c_void_p
-        ret = run_in_thread(self.ioctx.librados.rados_create_read_op, (None,))
-        self.read_op = ret
-        return ret
-
-    def __exit__(self, type, msg, traceback):
-        self.ioctx.librados.rados_release_read_op.argtypes = [c_void_p]
-        run_in_thread(self.ioctx.librados.rados_release_read_op, (c_void_p(self.read_op),))
-
-
-RADOS_CB = CFUNCTYPE(c_int, c_void_p, c_void_p)
-
-
-class Ioctx(object):
-    """rados.Ioctx object"""
-    def __init__(self, name, librados, io):
-        self.name = name
-        self.librados = librados
-        self.io = io
-        self.state = "open"
-        self.locator_key = ""
-        self.nspace = ""
-        self.safe_cbs = {}
-        self.complete_cbs = {}
-        self.lock = threading.Lock()
-
-    def __enter__(self):
-        return self
-
-    def __exit__(self, type_, value, traceback):
-        self.close()
-        return False
-
-    def __del__(self):
-        self.close()
-
-    def __aio_safe_cb(self, completion, _):
-        """
-        Callback to onsafe() for asynchronous operations
-        """
-        cb = None
-        with self.lock:
-            cb = self.safe_cbs[completion]
-            del self.safe_cbs[completion]
-        cb.onsafe(cb)
-        return 0
-
-    def __aio_complete_cb(self, completion, _):
-        """
-        Callback to oncomplete() for asynchronous operations
-        """
-        cb = None
-        with self.lock:
-            cb = self.complete_cbs[completion]
-            del self.complete_cbs[completion]
-        cb.oncomplete(cb)
-        return 0
-
-    def __get_completion(self, oncomplete, onsafe):
-        """
-        Constructs a completion to use with asynchronous operations
-
-        :param oncomplete: what to do when the write is safe and complete in memory
-            on all replicas
-        :type oncomplete: completion
-        :param onsafe:  what to do when the write is safe and complete on storage
-            on all replicas
-        :type onsafe: completion
-
-        :raises: :class:`Error`
-        :returns: completion object
-        """
-        completion = c_void_p(0)
-        complete_cb = None
-        safe_cb = None
-        if oncomplete:
-            complete_cb = RADOS_CB(self.__aio_complete_cb)
-        if onsafe:
-            safe_cb = RADOS_CB(self.__aio_safe_cb)
-        ret = run_in_thread(self.librados.rados_aio_create_completion,
-                            (c_void_p(0), complete_cb, safe_cb,
-                             byref(completion)))
-        if ret < 0:
-            raise make_ex(ret, "error getting a completion")
-        with self.lock:
-            completion_obj = Completion(self, completion, oncomplete, onsafe,
-                                        complete_cb, safe_cb)
-            if oncomplete:
-                self.complete_cbs[completion.value] = completion_obj
-            if onsafe:
-                self.safe_cbs[completion.value] = completion_obj
-        return completion_obj
-
-    def aio_write(self, object_name, to_write, offset=0,
-                  oncomplete=None, onsafe=None):
-        """
-        Write data to an object asynchronously
-
-        Queues the write and returns.
-
-        :param object_name: name of the object
-        :type object_name: str
-        :param to_write: data to write
-        :type to_write: str
-        :param offset: byte offset in the object to begin writing at
-        :type offset: int
-        :param oncomplete: what to do when the write is safe and complete in memory
-            on all replicas
-        :type oncomplete: completion
-        :param onsafe:  what to do when the write is safe and complete on storage
-            on all replicas
-        :type onsafe: completion
-
-        :raises: :class:`Error`
-        :returns: completion object
-        """
-        completion = self.__get_completion(oncomplete, onsafe)
-        ret = run_in_thread(self.librados.rados_aio_write,
-                            (self.io, cstr(object_name),
-                             completion.rados_comp, c_char_p(to_write),
-                             c_size_t(len(to_write)), c_uint64(offset)))
-        if ret < 0:
-            raise make_ex(ret, "error writing object %s" % object_name)
-        return completion
-
-    def aio_write_full(self, object_name, to_write,
-                       oncomplete=None, onsafe=None):
-        """
-        Asychronously write an entire object
-
-        The object is filled with the provided data. If the object exists,
-        it is atomically truncated and then written.
-        Queues the write and returns.
-
-        :param object_name: name of the object
-        :type object_name: str
-        :param to_write: data to write
-        :type to_write: str
-        :param oncomplete: what to do when the write is safe and complete in memory
-            on all replicas
-        :type oncomplete: completion
-        :param onsafe:  what to do when the write is safe and complete on storage
-            on all replicas
-        :type onsafe: completion
-
-        :raises: :class:`Error`
-        :returns: completion object
-        """
-        completion = self.__get_completion(oncomplete, onsafe)
-        ret = run_in_thread(self.librados.rados_aio_write_full,
-                            (self.io, cstr(object_name),
-                             completion.rados_comp, c_char_p(to_write),
-                             c_size_t(len(to_write))))
-        if ret < 0:
-            raise make_ex(ret, "error writing object %s" % object_name)
-        return completion
-
-    def aio_append(self, object_name, to_append, oncomplete=None, onsafe=None):
-        """
-        Asychronously append data to an object
-
-        Queues the write and returns.
-
-        :param object_name: name of the object
-        :type object_name: str
-        :param to_append: data to append
-        :type to_append: str
-        :param offset: byte offset in the object to begin writing at
-        :type offset: int
-        :param oncomplete: what to do when the write is safe and complete in memory
-            on all replicas
-        :type oncomplete: completion
-        :param onsafe:  what to do when the write is safe and complete on storage
-            on all replicas
-        :type onsafe: completion
-
-        :raises: :class:`Error`
-        :returns: completion object
-        """
-        completion = self.__get_completion(oncomplete, onsafe)
-        ret = run_in_thread(self.librados.rados_aio_append,
-                            (self.io, cstr(object_name),
-                             completion.rados_comp, c_char_p(to_append),
-                             c_size_t(len(to_append))))
-        if ret < 0:
-            raise make_ex(ret, "error appending to object %s" % object_name)
-        return completion
-
-    def aio_flush(self):
-        """
-        Block until all pending writes in an io context are safe
-
-        :raises: :class:`Error`
-        """
-        ret = run_in_thread(self.librados.rados_aio_flush, (self.io,))
-        if ret < 0:
-            raise make_ex(ret, "error flushing")
-
-    def aio_read(self, object_name, length, offset, oncomplete):
-        """
-        Asychronously read data from an object
-
-        oncomplete will be called with the returned read value as
-        well as the completion:
-
-        oncomplete(completion, data_read)
-
-        :param object_name: name of the object to read from
-        :type object_name: str
-        :param length: the number of bytes to read
-        :type length: int
-        :param offset: byte offset in the object to begin reading from
-        :type offset: int
-        :param oncomplete: what to do when the read is complete
-        :type oncomplete: completion
-
-        :raises: :class:`Error`
-        :returns: completion object
-        """
-        buf = create_string_buffer(length)
-
-        def oncomplete_(completion_v):
-            return_value = completion_v.get_return_value()
-            return oncomplete(completion_v,
-                              ctypes.string_at(buf, return_value) if return_value >= 0 else None)
-
-        completion = self.__get_completion(oncomplete_, None)
-        ret = run_in_thread(self.librados.rados_aio_read,
-                            (self.io, cstr(object_name),
-                             completion.rados_comp, buf, c_size_t(length),
-                             c_uint64(offset)))
-        if ret < 0:
-            raise make_ex(ret, "error reading %s" % object_name)
-        return completion
-
-    def aio_remove(self, object_name, oncomplete=None, onsafe=None):
-        """
-        Asychronously remove an object
-
-        :param object_name: name of the object to remove
-        :type object_name: str
-        :param oncomplete: what to do when the remove is safe and complete in memory
-            on all replicas
-        :type oncomplete: completion
-        :param onsafe:  what to do when the remove is safe and complete on storage
-            on all replicas
-        :type onsafe: completion
-
-        :raises: :class:`Error`
-        :returns: completion object
-        """
-        completion = self.__get_completion(oncomplete, onsafe)
-        ret = run_in_thread(self.librados.rados_aio_remove,
-                            (self.io, cstr(object_name),
-                             completion.rados_comp))
-        if ret < 0:
-            raise make_ex(ret, "error removing %s" % object_name)
-        return completion
-
-    def require_ioctx_open(self):
-        """
-        Checks if the rados.Ioctx object state is 'open'
-
-        :raises: IoctxStateError
-        """
-        if self.state != "open":
-            raise IoctxStateError("The pool is %s" % self.state)
-
-    def change_auid(self, auid):
-        """
-        Attempt to change an io context's associated auid "owner."
-
-        Requires that you have write permission on both the current and new
-        auid.
-
-        :raises: :class:`Error`
-        """
-        self.require_ioctx_open()
-        ret = run_in_thread(self.librados.rados_ioctx_pool_set_auid,
-                            (self.io, ctypes.c_uint64(auid)))
-        if ret < 0:
-            raise make_ex(ret, "error changing auid of '%s' to %d"
-                          % (self.name, auid))
-
-    @requires(('loc_key', str_type))
-    def set_locator_key(self, loc_key):
-        """
-        Set the key for mapping objects to pgs within an io context.
-
-        The key is used instead of the object name to determine which
-        placement groups an object is put in. This affects all subsequent
-        operations of the io context - until a different locator key is
-        set, all objects in this io context will be placed in the same pg.
-
-        :param loc_key: the key to use as the object locator, or NULL to discard
-            any previously set key
-        :type loc_key: str
-
-        :raises: :class:`TypeError`
-        """
-        self.require_ioctx_open()
-        run_in_thread(self.librados.rados_ioctx_locator_set_key,
-                      (self.io, cstr(loc_key)))
-        self.locator_key = loc_key
-
-    def get_locator_key(self):
-        """
-        Get the locator_key of context
-
-        :returns: locator_key
-        """
-        return self.locator_key
-
-    @requires(('snap_id', int))
-    def set_read(self, snap_id):
-        """
-        Set the snapshot for reading objects.
-
-        To stop to read from snapshot, use set_read(LIBRADOS_SNAP_HEAD)
-
-        :param snap_id: the snapshot Id
-        :type snap_id: int
-
-        :raises: :class:`TypeError`
-        """
-        self.require_ioctx_open()
-        run_in_thread(self.librados.rados_ioctx_snap_set_read,
-                      (self.io, c_uint64(snap_id)))
-
-    @requires(('nspace', str_type))
-    def set_namespace(self, nspace):
-        """
-        Set the namespace for objects within an io context.
-
-        The namespace in addition to the object name fully identifies
-        an object. This affects all subsequent operations of the io context
-        - until a different namespace is set, all objects in this io context
-        will be placed in the same namespace.
-
-        :param nspace: the namespace to use, or None/"" for the default namespace
-        :type nspace: str
-
-        :raises: :class:`TypeError`
-        """
-        self.require_ioctx_open()
-        if nspace is None:
-            nspace = ""
-        run_in_thread(self.librados.rados_ioctx_set_namespace,
-                      (self.io, cstr(nspace)))
-        self.nspace = nspace
-
-    def get_namespace(self):
-        """
-        Get the namespace of context
-
-        :returns: namespace
-        """
-        return self.nspace
-
-    def close(self):
-        """
-        Close a rados.Ioctx object.
-
-        This just tells librados that you no longer need to use the io context.
-        It may not be freed immediately if there are pending asynchronous
-        requests on it, but you should not use an io context again after
-        calling this function on it.
-        """
-        if self.state == "open":
-            self.require_ioctx_open()
-            run_in_thread(self.librados.rados_ioctx_destroy, (self.io,))
-            self.state = "closed"
-
-
-    @requires(('key', str_type), ('data', bytes))
-    def write(self, key, data, offset=0):
-        """
-        Write data to an object synchronously
-
-        :param key: name of the object
-        :type key: str
-        :param data: data to write
-        :type data: bytes
-        :param offset: byte offset in the object to begin writing at
-        :type offset: int
-
-        :raises: :class:`TypeError`
-        :raises: :class:`LogicError`
-        :returns: int - 0 on success
-        """
-        self.require_ioctx_open()
-        length = len(data)
-        ret = run_in_thread(self.librados.rados_write,
-                            (self.io, cstr(key), c_char_p(data),
-                             c_size_t(length), c_uint64(offset)))
-        if ret == 0:
-            return ret
-        elif ret < 0:
-            raise make_ex(ret, "Ioctx.write(%s): failed to write %s"
-                          % (self.name, key))
-        else:
-            raise LogicError("Ioctx.write(%s): rados_write \
-returned %d, but should return zero on success." % (self.name, ret))
-
-    @requires(('key', str_type), ('data', bytes))
-    def write_full(self, key, data):
-        """
-        Write an entire object synchronously.
-
-        The object is filled with the provided data. If the object exists,
-        it is atomically truncated and then written.
-
-        :param key: name of the object
-        :type key: str
-        :param data: data to write
-        :type data: bytes
-
-        :raises: :class:`TypeError`
-        :raises: :class:`Error`
-        :returns: int - 0 on success
-        """
-        self.require_ioctx_open()
-        length = len(data)
-        ret = run_in_thread(self.librados.rados_write_full,
-                            (self.io, cstr(key), c_char_p(data),
-                             c_size_t(length)))
-        if ret == 0:
-            return ret
-        elif ret < 0:
-            raise make_ex(ret, "Ioctx.write_full(%s): failed to write %s"
-                          % (self.name, key))
-        else:
-            raise LogicError("Ioctx.write_full(%s): rados_write_full \
-returned %d, but should return zero on success." % (self.name, ret))
-
-    @requires(('key', str_type), ('data', bytes))
-    def append(self, key, data):
-        """
-        Append data to an object synchronously
-
-        :param key: name of the object
-        :type key: str
-        :param data: data to write
-        :type data: bytes
-
-        :raises: :class:`TypeError`
-        :raises: :class:`LogicError`
-        :returns: int - 0 on success
-        """
-        self.require_ioctx_open()
-        length = len(data)
-        ret = run_in_thread(self.librados.rados_append,
-                            (self.io, cstr(key), c_char_p(data),
-                             c_size_t(length)))
-        if ret == 0:
-            return ret
-        elif ret < 0:
-            raise make_ex(ret, "Ioctx.append(%s): failed to append %s"
-                          % (self.name, key))
-        else:
-            raise LogicError("Ioctx.append(%s): rados_append \
-returned %d, but should return zero on success." % (self.name, ret))
-
-    @requires(('key', str_type))
-    def read(self, key, length=8192, offset=0):
-        """
-        Read data from an object synchronously
-
-        :param key: name of the object
-        :type key: str
-        :param length: the number of bytes to read (default=8192)
-        :type length: int
-        :param offset: byte offset in the object to begin reading at
-        :type offset: int
-
-        :raises: :class:`TypeError`
-        :raises: :class:`Error`
-        :returns: str - data read from object
-        """
-        self.require_ioctx_open()
-        ret_buf = create_string_buffer(length)
-        ret = run_in_thread(self.librados.rados_read,
-                            (self.io, cstr(key), ret_buf, c_size_t(length),
-                             c_uint64(offset)))
-        if ret < 0:
-            raise make_ex(ret, "Ioctx.read(%s): failed to read %s" % (self.name, key))
-        return ctypes.string_at(ret_buf, ret)
-
-    @requires(('key', str_type), ('cls', str_type), ('method', str_type), ('data', bytes))
-    def execute(self, key, cls, method, data, length=8192):
-        """
-        Execute an OSD class method on an object.
-
-        :param key: name of the object
-        :type key: str
-        :param cls: name of the object class
-        :type cls: str
-        :param method: name of the method
-        :type method: str
-        :param data: input data
-        :type data: bytes
-        :param length: size of output buffer in bytes (default=8291)
-        :type length: int
-
-        :raises: :class:`TypeError`
-        :raises: :class:`Error`
-        :returns: (ret, method output)
-        """
-        self.require_ioctx_open()
-        ret_buf = create_string_buffer(length)
-        ret = run_in_thread(self.librados.rados_exec,
-                (self.io, cstr(key), cstr(cls), cstr(method),
-                    c_char_p(data), c_size_t(len(data)), ret_buf,
-                    c_size_t(length)))
-        if ret < 0:
-            raise make_ex(ret, "Ioctx.exec(%s): failed to exec %s:%s on %s" %
-                    (self.name, cls, method, key))
-        return ret, ctypes.string_at(ret_buf, min(ret, length))
-
-    def get_stats(self):
-        """
-        Get pool usage statistics
-
-        :returns: dict - contains the following keys:
-
-            - ``num_bytes`` (int) - size of pool in bytes
-
-            - ``num_kb`` (int) - size of pool in kbytes
-
-            - ``num_objects`` (int) - number of objects in the pool
-
-            - ``num_object_clones`` (int) - number of object clones
-
-            - ``num_object_copies`` (int) - number of object copies
-
-            - ``num_objects_missing_on_primary`` (int) - number of objets
-                missing on primary
-
-            - ``num_objects_unfound`` (int) - number of unfound objects
-
-            - ``num_objects_degraded`` (int) - number of degraded objects
-
-            - ``num_rd`` (int) - bytes read
-
-            - ``num_rd_kb`` (int) - kbytes read
-
-            - ``num_wr`` (int) - bytes written
-
-            - ``num_wr_kb`` (int) - kbytes written
-        """
-        self.require_ioctx_open()
-        stats = rados_pool_stat_t()
-        ret = run_in_thread(self.librados.rados_ioctx_pool_stat,
-                            (self.io, byref(stats)))
-        if ret < 0:
-            raise make_ex(ret, "Ioctx.get_stats(%s): get_stats failed" % self.name)
-        return {'num_bytes': stats.num_bytes,
-                'num_kb': stats.num_kb,
-                'num_objects': stats.num_objects,
-                'num_object_clones': stats.num_object_clones,
-                'num_object_copies': stats.num_object_copies,
-                "num_objects_missing_on_primary": stats.num_objects_missing_on_primary,
-                "num_objects_unfound": stats.num_objects_unfound,
-                "num_objects_degraded": stats.num_objects_degraded,
-                "num_rd": stats.num_rd,
-                "num_rd_kb": stats.num_rd_kb,
-                "num_wr": stats.num_wr,
-                "num_wr_kb": stats.num_wr_kb}
-
-    @requires(('key', str_type))
-    def remove_object(self, key):
-        """
-        Delete an object
-
-        This does not delete any snapshots of the object.
-
-        :param key: the name of the object to delete
-        :type key: str
-
-        :raises: :class:`TypeError`
-        :raises: :class:`Error`
-        :returns: bool - True on success
-        """
-        self.require_ioctx_open()
-        ret = run_in_thread(self.librados.rados_remove,
-                            (self.io, cstr(key)))
-        if ret < 0:
-            raise make_ex(ret, "Failed to remove '%s'" % key)
-        return True
-
-    @requires(('key', str_type))
-    def trunc(self, key, size):
-        """
-        Resize an object
-
-        If this enlarges the object, the new area is logically filled with
-        zeroes. If this shrinks the object, the excess data is removed.
-
-        :param key: the name of the object to resize
-        :type key: str
-        :param size: the new size of the object in bytes
-        :type size: int
-
-        :raises: :class:`TypeError`
-        :raises: :class:`Error`
-        :returns: int - 0 on success, otherwise raises error
-        """
-
-        self.require_ioctx_open()
-        ret = run_in_thread(self.librados.rados_trunc,
-                            (self.io, cstr(key), c_uint64(size)))
-        if ret < 0:
-            raise make_ex(ret, "Ioctx.trunc(%s): failed to truncate %s" % (self.name, key))
-        return ret
-
-    @requires(('key', str_type))
-    def stat(self, key):
-        """
-        Get object stats (size/mtime)
-
-        :param key: the name of the object to get stats from
-        :type key: str
-
-        :raises: :class:`TypeError`
-        :raises: :class:`Error`
-        :returns: (size,timestamp)
-        """
-        self.require_ioctx_open()
-        psize = c_uint64()
-        pmtime = c_uint64()
-
-        ret = run_in_thread(self.librados.rados_stat,
-                            (self.io, cstr(key), pointer(psize),
-                             pointer(pmtime)))
-        if ret < 0:
-            raise make_ex(ret, "Failed to stat %r" % key)
-        return psize.value, time.localtime(pmtime.value)
-
-    @requires(('key', str_type), ('xattr_name', str_type))
-    def get_xattr(self, key, xattr_name):
-        """
-        Get the value of an extended attribute on an object.
-
-        :param key: the name of the object to get xattr from
-        :type key: str
-        :param xattr_name: which extended attribute to read
-        :type xattr_name: str
-
-        :raises: :class:`TypeError`
-        :raises: :class:`Error`
-        :returns: str - value of the xattr
-        """
-        self.require_ioctx_open()
-        ret_length = 4096
-        while ret_length < 4096 * 1024 * 1024:
-            ret_buf = create_string_buffer(ret_length)
-            ret = run_in_thread(self.librados.rados_getxattr,
-                                (self.io, cstr(key), cstr(xattr_name),
-                                 ret_buf, c_size_t(ret_length)))
-            if (ret == -errno.ERANGE):
-                ret_length *= 2
-            elif ret < 0:
-                raise make_ex(ret, "Failed to get xattr %r" % xattr_name)
-            else:
-                break
-        return ctypes.string_at(ret_buf, ret)
-
-    @requires(('oid', str_type))
-    def get_xattrs(self, oid):
-        """
-        Start iterating over xattrs on an object.
-
-        :param oid: the name of the object to get xattrs from
-        :type oid: str
-
-        :raises: :class:`TypeError`
-        :raises: :class:`Error`
-        :returns: XattrIterator
-        """
-        self.require_ioctx_open()
-        it = c_void_p(0)
-        ret = run_in_thread(self.librados.rados_getxattrs,
-                            (self.io, cstr(oid), byref(it)))
-        if ret != 0:
-            raise make_ex(ret, "Failed to get rados xattrs for object %r" % oid)
-        return XattrIterator(self, it, oid)
-
-    @requires(('key', str_type), ('xattr_name', str_type), ('xattr_value', bytes))
-    def set_xattr(self, key, xattr_name, xattr_value):
-        """
-        Set an extended attribute on an object.
-
-        :param key: the name of the object to set xattr to
-        :type key: str
-        :param xattr_name: which extended attribute to set
-        :type xattr_name: str
-        :param xattr_value: the value of the  extended attribute
-        :type xattr_value: bytes
-
-        :raises: :class:`TypeError`
-        :raises: :class:`Error`
-        :returns: bool - True on success, otherwise raise an error
-        """
-        self.require_ioctx_open()
-        ret = run_in_thread(self.librados.rados_setxattr,
-                            (self.io, cstr(key), cstr(xattr_name),
-                             c_char_p(xattr_value), c_size_t(len(xattr_value))))
-        if ret < 0:
-            raise make_ex(ret, "Failed to set xattr %r" % xattr_name)
-        return True
-
-    @requires(('key', str_type), ('xattr_name', str_type))
-    def rm_xattr(self, key, xattr_name):
-        """
-        Removes an extended attribute on from an object.
-
-        :param key: the name of the object to remove xattr from
-        :type key: str
-        :param xattr_name: which extended attribute to remove
-        :type xattr_name: str
-
-        :raises: :class:`TypeError`
-        :raises: :class:`Error`
-        :returns: bool - True on success, otherwise raise an error
-        """
-        self.require_ioctx_open()
-        ret = run_in_thread(self.librados.rados_rmxattr,
-                            (self.io, cstr(key), cstr(xattr_name)))
-        if ret < 0:
-            raise make_ex(ret, "Failed to delete key %r xattr %r" %
-                          (key, xattr_name))
-        return True
-
-    def list_objects(self):
-        """
-        Get ObjectIterator on rados.Ioctx object.
-
-        :returns: ObjectIterator
-        """
-        self.require_ioctx_open()
-        return ObjectIterator(self)
-
-    def list_snaps(self):
-        """
-        Get SnapIterator on rados.Ioctx object.
-
-        :returns: SnapIterator
-        """
-        self.require_ioctx_open()
-        return SnapIterator(self)
-
-    @requires(('snap_name', str_type))
-    def create_snap(self, snap_name):
-        """
-        Create a pool-wide snapshot
-
-        :param snap_name: the name of the snapshot
-        :type snap_name: str
-
-        :raises: :class:`TypeError`
-        :raises: :class:`Error`
-        """
-        self.require_ioctx_open()
-        ret = run_in_thread(self.librados.rados_ioctx_snap_create,
-                            (self.io, cstr(snap_name)))
-        if (ret != 0):
-            raise make_ex(ret, "Failed to create snap %s" % snap_name)
-
-    @requires(('snap_name', str_type))
-    def remove_snap(self, snap_name):
-        """
-        Removes a pool-wide snapshot
-
-        :param snap_name: the name of the snapshot
-        :type snap_name: str
-
-        :raises: :class:`TypeError`
-        :raises: :class:`Error`
-        """
-        self.require_ioctx_open()
-        ret = run_in_thread(self.librados.rados_ioctx_snap_remove,
-                            (self.io, cstr(snap_name)))
-        if (ret != 0):
-            raise make_ex(ret, "Failed to remove snap %s" % snap_name)
-
-    @requires(('snap_name', str_type))
-    def lookup_snap(self, snap_name):
-        """
-        Get the id of a pool snapshot
-
-        :param snap_name: the name of the snapshot to lookop
-        :type snap_name: str
-
-        :raises: :class:`TypeError`
-        :raises: :class:`Error`
-        :returns: Snap - on success
-        """
-        self.require_ioctx_open()
-        snap_id = c_uint64()
-        ret = run_in_thread(self.librados.rados_ioctx_snap_lookup,
-                            (self.io, cstr(snap_name), byref(snap_id)))
-        if (ret != 0):
-            raise make_ex(ret, "Failed to lookup snap %s" % snap_name)
-        return Snap(self, snap_name, snap_id)
-
-    @requires(('oid', str_type), ('snap_name', str_type))
-    def snap_rollback(self, oid, snap_name):
-        """
-        Rollback an object to a snapshot
-
-        :param oid: the name of the object
-        :type oid: str
-        :param snap_name: the name of the snapshot
-        :type snap_name: str
-
-        :raises: :class:`TypeError`
-        :raises: :class:`Error`
-        """
-        self.require_ioctx_open()
-        ret = run_in_thread(self.librados.rados_ioctx_snap_rollback,
-                            (self.io, cstr(oid), cstr(snap_name)))
-        if (ret != 0):
-            raise make_ex(ret, "Failed to rollback %s" % oid)
-
-    def get_last_version(self):
-        """
-        Return the version of the last object read or written to.
-
-        This exposes the internal version number of the last object read or
-        written via this io context
-
-        :returns: version of the last object used
-        """
-        self.require_ioctx_open()
-        return run_in_thread(self.librados.rados_get_last_version, (self.io,))
-
-    def create_write_op(self):
-        """
-        create write operation object.
-        need call release_write_op after use
-        """
-        self.librados.rados_create_write_op.restype = c_void_p
-        return run_in_thread(self.librados.rados_create_write_op, (None,))
-
-    def create_read_op(self):
-        """
-        create read operation object.
-        need call release_read_op after use
-        """
-        self.librados.rados_create_read_op.restype = c_void_p
-        return run_in_thread(self.librados.rados_create_read_op, (None,))
-
-    def release_write_op(self, write_op):
-        """
-        release memory alloc by create_write_op
-        """
-        self.librados.rados_release_write_op.argtypes = [c_void_p]
-        run_in_thread(self.librados.rados_release_write_op, (c_void_p(write_op),))
-
-    def release_read_op(self, read_op):
-        """
-        release memory alloc by create_read_op
-        :para read_op: read_op object
-        :type: int
-        """
-        self.librados.rados_release_read_op.argtypes = [c_void_p]
-        run_in_thread(self.librados.rados_release_read_op, (c_void_p(read_op),))
-
-    @requires(('write_op', int), ('keys', tuple), ('values', tuple))
-    def set_omap(self, write_op, keys, values):
-        """
-        set keys values to write_op
-        :para write_op: write_operation object
-        :type write_op: int
-        :para keys: a tuple of keys
-        :type keys: tuple
-        :para values: a tuple of values
-        :type values: tuple
-        """
-        if len(keys) != len(values):
-            raise Error("Rados(): keys and values must have the same number of items")
-        key_num = len(keys)
-        key_array_type = c_char_p*key_num
-        key_array = key_array_type()
-        key_array[:] = [cstr(key) for key in keys]
-
-        value_array_type = c_char_p*key_num
-        value_array = value_array_type()
-        value_array[:] = values
-
-        lens_array_type = c_size_t*key_num
-        lens_array = lens_array_type()
-        for index, value in enumerate(values):
-            lens_array[index] = c_size_t(len(value))
-
-        run_in_thread(self.librados.rados_write_op_omap_set,
-                      (c_void_p(write_op), byref(key_array), byref(value_array),
-                       byref(lens_array), c_int(key_num),))
-
-    @requires(('write_op', int), ('oid', str_type), ('mtime', opt(int)), ('flags', opt(int)))
-    def operate_write_op(self, write_op, oid, mtime=0, flags=0):
-        """
-        excute the real write operation
-        :para write_op: write operation object
-        :type write_op: int
-        :para oid: object name
-        :type oid: str
-        :para mtime: the time to set the mtime to, 0 for the current time
-        :type mtime: int
-        :para flags: flags to apply to the entire operation
-        :type flags: int
-        """
-        run_in_thread(self.librados.rados_write_op_operate,
-                      (c_void_p(write_op), self.io, cstr(oid),
-                       c_long(mtime), c_int(flags),))
-
-    @requires(('read_op', int), ('oid', str_type), ('flag', opt(int)))
-    def operate_read_op(self, read_op, oid, flag=0):
-        """
-        excute the real read operation
-        :para read_op: read operation object
-        :type read_op: int
-        :para oid: object name
-        :type oid: str
-        :para flag: flags to apply to the entire operation
-        :type flag: int
-        """
-        run_in_thread(self.librados.rados_read_op_operate,
-                      (c_void_p(read_op), self.io, cstr(oid), c_int(flag),))
-
-    @requires(('read_op', int), ('start_after', str_type), ('filter_prefix', str_type), ('max_return', int))
-    def get_omap_vals(self, read_op, start_after, filter_prefix, max_return):
-        """
-        get the omap values
-        :para read_op: read operation object
-        :type read_op: int
-        :para start_after: list keys starting after start_after
-        :type start_after: str
-        :para filter_prefix: list only keys beginning with filter_prefix
-        :type filter_prefix: str
-        :para max_return: list no more than max_return key/value pairs
-        :type max_return: int
-        :returns: an iterator over the the requested omap values, return value from this action
-        """
-        prval = c_int()
-        iter_addr = c_void_p()
-        run_in_thread(self.librados.rados_read_op_omap_get_vals,
-                      (c_void_p(read_op), cstr(start_after),
-                       cstr(filter_prefix), c_int(max_return),
-                       byref(iter_addr), pointer(prval)))
-        return OmapIterator(self, iter_addr), prval.value
-
-    @requires(('read_op', int), ('start_after', str_type), ('max_return', int))
-    def get_omap_keys(self, read_op, start_after, max_return):
-        """
-        get the omap keys
-        :para read_op: read operation object
-        :type read_op: int
-        :para start_after: list keys starting after start_after
-        :type start_after: str
-        :para max_return: list no more than max_return key/value pairs
-        :type max_return: int
-        :returns: an iterator over the the requested omap values, return value from this action
-        """
-        prval = c_int()
-        iter_addr = c_void_p()
-        run_in_thread(self.librados.rados_read_op_omap_get_keys,
-                      (c_void_p(read_op), cstr(start_after),
-                       c_int(max_return), byref(iter_addr), pointer(prval)))
-        return OmapIterator(self, iter_addr), prval.value
-
-    @requires(('read_op', int), ('keys', tuple))
-    def get_omap_vals_by_keys(self, read_op, keys):
-        """
-        get the omap values by keys
-        :para read_op: read operation object
-        :type read_op: int
-        :para keys: input key tuple
-        :type keys: tuple
-        :returns: an iterator over the the requested omap values, return value from this action
-        """
-        prval = c_int()
-        iter_addr = c_void_p()
-        key_num = len(keys)
-        key_array_type = c_char_p*key_num
-        key_array = key_array_type()
-        key_array[:] = [cstr(key) for key in keys]
-        run_in_thread(self.librados.rados_read_op_omap_get_vals_by_keys,
-                      (c_void_p(read_op), byref(key_array), c_int(key_num),
-                       byref(iter_addr), pointer(prval)))
-        return OmapIterator(self, iter_addr), prval.value
-
-    @requires(('write_op', int), ('keys', tuple))
-    def remove_omap_keys(self, write_op, keys):
-        """
-        remove omap keys specifiled
-        :para write_op: write operation object
-        :type write_op: int
-        :para keys: input key tuple
-        :type keys: tuple
-        """
-        key_num = len(keys)
-        key_array_type = c_char_p*key_num
-        key_array = key_array_type()
-        key_array[:] = [cstr(key) for key in keys]
-        run_in_thread(self.librados.rados_write_op_omap_rm_keys,
-                      (c_void_p(write_op), byref(key_array), c_int(key_num)))
-
-    @requires(('write_op', int))
-    def clear_omap(self, write_op):
-        """
-        Remove all key/value pairs from an object
-        :para write_op: write operation object
-        :type write_op: int
-        """
-        run_in_thread(self.librados.rados_write_op_omap_clear,
-                      (c_void_p(write_op),))
-
-    @requires(('key', str_type), ('name', str_type), ('cookie', str_type), ('desc', str_type),
-              ('duration', opt(int)), ('flags', int))
-    def lock_exclusive(self, key, name, cookie, desc="", duration=None, flags=0):
-
-        """
-        Take an exclusive lock on an object
-
-        :param key: name of the object
-        :type key: str
-        :param name: name of the lock
-        :type name: str
-        :param cookie: cookie of the lock
-        :type cookie: str
-        :param desc: description of the lock
-        :type desc: str
-        :param duration: duration of the lock in seconds
-        :type duration: int
-        :param flags: flags
-        :type flags: int
-
-        :raises: :class:`TypeError`
-        :raises: :class:`Error`
-        """
-        self.require_ioctx_open()
-
-        ret = run_in_thread(self.librados.rados_lock_exclusive,
-                            (self.io, cstr(key), cstr(name), cstr(cookie),
-                             cstr(desc),
-                             timeval(duration, None) if duration is None else None,
-                             c_uint8(flags)))
-        if ret < 0:
-            raise make_ex(ret, "Ioctx.rados_lock_exclusive(%s): failed to set lock %s on %s" % (self.name, name, key))
-
-    @requires(('key', str_type), ('name', str_type), ('cookie', str_type), ('tag', str_type),
-              ('desc', str_type), ('duration', opt(int)), ('flags', int))
-    def lock_shared(self, key, name, cookie, tag, desc="", duration=None, flags=0):
-
-        """
-        Take a shared lock on an object
-
-        :param key: name of the object
-        :type key: str
-        :param name: name of the lock
-        :type name: str
-        :param cookie: cookie of the lock
-        :type cookie: str
-        :param tag: tag of the lock
-        :type tag: str
-        :param desc: description of the lock
-        :type desc: str
-        :param duration: duration of the lock in seconds
-        :type duration: int
-        :param flags: flags
-        :type flags: int
-
-        :raises: :class:`TypeError`
-        :raises: :class:`Error`
-        """
-        self.require_ioctx_open()
-
-        ret = run_in_thread(self.librados.rados_lock_shared,
-                            (self.io, cstr(key), cstr(name), cstr(cookie),
-                             cstr(tag), cstr(desc),
-                             timeval(duration, None) if duration is None else None,
-                             c_uint8(flags)))
-        if ret < 0:
-            raise make_ex(ret, "Ioctx.rados_lock_exclusive(%s): failed to set lock %s on %s" % (self.name, name, key))
-
-    @requires(('key', str_type), ('name', str_type), ('cookie', str_type))
-    def unlock(self, key, name, cookie):
-
-        """
-        Release a shared or exclusive lock on an object
-
-        :param key: name of the object
-        :type key: str
-        :param name: name of the lock
-        :type name: str
-        :param cookie: cookie of the lock
-        :type cookie: str
-
-        :raises: :class:`TypeError`
-        :raises: :class:`Error`
-        """
-        self.require_ioctx_open()
-
-        ret = run_in_thread(self.librados.rados_unlock,
-                            (self.io, cstr(key), cstr(name), cstr(cookie)))
-        if ret < 0:
-            raise make_ex(ret, "Ioctx.rados_lock_exclusive(%s): failed to set lock %s on %s" % (self.name, name, key))
-
-
-def set_object_locator(func):
-    def retfunc(self, *args, **kwargs):
-        if self.locator_key is not None:
-            old_locator = self.ioctx.get_locator_key()
-            self.ioctx.set_locator_key(self.locator_key)
-            retval = func(self, *args, **kwargs)
-            self.ioctx.set_locator_key(old_locator)
-            return retval
-        else:
-            return func(self, *args, **kwargs)
-    return retfunc
-
-
-def set_object_namespace(func):
-    def retfunc(self, *args, **kwargs):
-        if self.nspace is None:
-            raise LogicError("Namespace not set properly in context")
-        old_nspace = self.ioctx.get_namespace()
-        self.ioctx.set_namespace(self.nspace)
-        retval = func(self, *args, **kwargs)
-        self.ioctx.set_namespace(old_nspace)
-        return retval
-    return retfunc
-
-
-class Object(object):
-    """Rados object wrapper, makes the object look like a file"""
-    def __init__(self, ioctx, key, locator_key=None, nspace=None):
-        self.key = key
-        self.ioctx = ioctx
-        self.offset = 0
-        self.state = "exists"
-        self.locator_key = locator_key
-        self.nspace = "" if nspace is None else nspace
-
-    def __str__(self):
-        return "rados.Object(ioctx=%s,key=%s,nspace=%s,locator=%s)" % \
-            (str(self.ioctx), self.key, "--default--"
-             if self.nspace is "" else self.nspace, self.locator_key)
-
-    def require_object_exists(self):
-        if self.state != "exists":
-            raise ObjectStateError("The object is %s" % self.state)
-
-    @set_object_locator
-    @set_object_namespace
-    def read(self, length=1024 * 1024):
-        self.require_object_exists()
-        ret = self.ioctx.read(self.key, length, self.offset)
-        self.offset += len(ret)
-        return ret
-
-    @set_object_locator
-    @set_object_namespace
-    def write(self, string_to_write):
-        self.require_object_exists()
-        ret = self.ioctx.write(self.key, string_to_write, self.offset)
-        if ret == 0:
-            self.offset += len(string_to_write)
-        return ret
-
-    @set_object_locator
-    @set_object_namespace
-    def remove(self):
-        self.require_object_exists()
-        self.ioctx.remove_object(self.key)
-        self.state = "removed"
-
-    @set_object_locator
-    @set_object_namespace
-    def stat(self):
-        self.require_object_exists()
-        return self.ioctx.stat(self.key)
-
-    def seek(self, position):
-        self.require_object_exists()
-        self.offset = position
-
-    @set_object_locator
-    @set_object_namespace
-    def get_xattr(self, xattr_name):
-        self.require_object_exists()
-        return self.ioctx.get_xattr(self.key, xattr_name)
-
-    @set_object_locator
-    @set_object_namespace
-    def get_xattrs(self):
-        self.require_object_exists()
-        return self.ioctx.get_xattrs(self.key)
-
-    @set_object_locator
-    @set_object_namespace
-    def set_xattr(self, xattr_name, xattr_value):
-        self.require_object_exists()
-        return self.ioctx.set_xattr(self.key, xattr_name, xattr_value)
-
-    @set_object_locator
-    @set_object_namespace
-    def rm_xattr(self, xattr_name):
-        self.require_object_exists()
-        return self.ioctx.rm_xattr(self.key, xattr_name)
-
-MONITOR_LEVELS = [
-    "debug",
-    "info",
-    "warn", "warning",
-    "err", "error",
-    "sec",
-    ]
-
-
-class MonitorLog(object):
-    """
-    For watching cluster log messages.  Instantiate an object and keep
-    it around while callback is periodically called.  Construct with
-    'level' to monitor 'level' messages (one of MONITOR_LEVELS).
-    arg will be passed to the callback.
-
-    callback will be called with:
-        arg (given to __init__)
-        line (the full line, including timestamp, who, level, msg)
-        who (which entity issued the log message)
-        timestamp_sec (sec of a struct timespec)
-        timestamp_nsec (sec of a struct timespec)
-        seq (sequence number)
-        level (string representing the level of the log message)
-        msg (the message itself)
-    callback's return value is ignored
-    """
-
-    def monitor_log_callback(self, arg, line, who, sec, nsec, seq, level, msg):
-        """
-        Local callback wrapper, in case we decide to do something
-        """
-        self.callback(arg, line, who, sec, nsec, seq, level, msg)
-        return 0
-
-    def __init__(self, cluster, level, callback, arg):
-        if level not in MONITOR_LEVELS:
-            raise LogicError("invalid monitor level " + level)
-        if not callable(callback):
-            raise LogicError("callback must be a callable function")
-        self.level = level
-        self.callback = callback
-        self.arg = arg
-        callback_factory = CFUNCTYPE(c_int,     # return type (really void)
-                                     c_void_p,  # arg
-                                     c_char_p,  # line
-                                     c_char_p,  # who
-                                     c_uint64,  # timestamp_sec
-                                     c_uint64,  # timestamp_nsec
-                                     c_ulong,   # seq
-                                     c_char_p,  # level
-                                     c_char_p)  # msg
-        self.internal_callback = callback_factory(self.monitor_log_callback)
-
-        r = run_in_thread(cluster.librados.rados_monitor_log,
-                          (cluster.cluster, level, self.internal_callback, arg))
-        if r:
-            raise make_ex(r, 'error calling rados_monitor_log')
diff --git a/src/pybind/rados/Makefile.am b/src/pybind/rados/Makefile.am
new file mode 100644
index 0000000..ad555c3
--- /dev/null
+++ b/src/pybind/rados/Makefile.am
@@ -0,0 +1,35 @@
+EXTRA_DIST += $(srcdir)/pybind/rados/setup.py $(srcdir)/pybind/rados/rados.pyx $(srcdir)/pybind/rados/rados.pxd
+
+rados-pybind-all: librados.la ${srcdir}/ceph_ver.h
+	cd $(srcdir)/pybind/rados; $(PY_DISTUTILS) build \
+	--build-base $(shell readlink -f $(builddir))/build \
+	--verbose
+
+rados-pybind-clean: ${srcdir}/ceph_ver.h
+	cd $(srcdir)/pybind/rados; $(PY_DISTUTILS) clean \
+	--build-base $(shell readlink -f $(builddir))/build \
+	--verbose
+
+rados-pybind-install-exec: ${srcdir}/ceph_ver.h
+	if test "$(DESTDIR)" ; then \
+		if lsb_release -si | grep --quiet 'Ubuntu\|Debian\|Devuan' ; then \
+			options=--install-layout=deb ; \
+		else \
+			options=--prefix=/usr ; \
+		fi ; \
+		root="--root=$(DESTDIR)" ; \
+	else \
+		options=--prefix=$(prefix) ; \
+	fi ; \
+	cd $(srcdir)/pybind/rados; $(PY_DISTUTILS) build \
+	--build-base $(shell readlink -f $(builddir))/build \
+	install \
+	$$options $$root \
+	--single-version-externally-managed \
+	--record /dev/null \
+	--verbose
+
+LOCAL_ALL += rados-pybind-all
+LOCAL_CLEAN += rados-pybind-clean
+LOCAL_INSTALLEXEC += rados-pybind-install-exec
+
diff --git a/src/pybind/rados/rados.pxd b/src/pybind/rados/rados.pxd
new file mode 100644
index 0000000..619543d
--- /dev/null
+++ b/src/pybind/rados/rados.pxd
@@ -0,0 +1,38 @@
+# cython: embedsignature=True
+#
+# Shared object for librbdpy
+#
+# Copyright 2016 Mehdi Abaakouk <sileht at redhat.com>
+
+
+cdef extern from "rados/librados.h" nogil:
+    ctypedef void* rados_t
+    ctypedef void* rados_config_t
+    ctypedef void* rados_ioctx_t
+
+
+cdef class Rados(object):
+    cdef:
+        rados_t cluster
+        public object state
+        public object monitor_callback
+        public object parsed_args
+        public object conf_defaults
+        public object conffile
+        public object rados_id
+
+
+cdef class Ioctx(object):
+    cdef:
+        rados_ioctx_t io
+        public char *name
+        public object state
+        public object locator_key
+        public object nspace
+
+        # TODO(sileht): we need to track leaving completion objects
+        # I guess we can do that in a lighter ways, but keep code simple
+        # as before for now
+        public object safe_completions
+        public object complete_completions
+        public object lock
diff --git a/src/pybind/rados/rados.pyx b/src/pybind/rados/rados.pyx
new file mode 100644
index 0000000..86a4cb8
--- /dev/null
+++ b/src/pybind/rados/rados.pyx
@@ -0,0 +1,3223 @@
+# cython: embedsignature=True
+"""
+This module is a thin wrapper around librados.
+
+Error codes from librados are turned into exceptions that subclass
+:class:`Error`. Almost all methods may raise :class:`Error(the base class of all rados exceptions), :class:`PermissionError`
+(the base class of all rados exceptions), :class:`PermissionError`
+and :class:`IOError`, in addition to those documented for the
+method.
+"""
+# Copyright 2011 Josh Durgin
+# Copyright 2011, Hannu Valtonen <hannu.valtonen at ormod.com>
+# Copyright 2015 Hector Martin <marcan at marcan.st>
+# Copyright 2016 Mehdi Abaakouk <sileht at redhat.com>
+
+from cpython cimport PyObject, ref
+from libc cimport errno
+from libc.stdint cimport *
+from libc.stdlib cimport malloc, realloc, free
+
+import sys
+import threading
+import time
+
+from datetime import datetime
+from functools import partial, wraps
+from itertools import chain
+
+# Are we running Python 2.x
+_python2 = sys.hexversion < 0x03000000
+
+if _python2:
+    str_type = basestring
+else:
+    str_type = str
+
+
+cdef extern from "Python.h":
+    # These are in cpython/string.pxd, but use "object" types instead of
+    # PyObject*, which invokes assumptions in cpython that we need to
+    # legitimately break to implement zero-copy string buffers in Ioctx.read().
+    # This is valid use of the Python API and documented as a special case.
+    PyObject *PyBytes_FromStringAndSize(char *v, Py_ssize_t len) except NULL
+    char* PyBytes_AsString(PyObject *string) except NULL
+    int _PyBytes_Resize(PyObject **string, Py_ssize_t newsize) except -1
+    void PyEval_InitThreads()
+
+
+cdef extern from "time.h":
+    ctypedef long int time_t
+    ctypedef long int suseconds_t
+
+
+cdef extern from "sys/time.h":
+    cdef struct timeval:
+        time_t tv_sec
+        suseconds_t tv_usec
+
+
+cdef extern from "rados/rados_types.h" nogil:
+    cdef char* _LIBRADOS_ALL_NSPACES "LIBRADOS_ALL_NSPACES"
+
+
+cdef extern from "rados/librados.h" nogil:
+    enum:
+        _LIBRADOS_OP_FLAG_EXCL "LIBRADOS_OP_FLAG_EXCL"
+        _LIBRADOS_OP_FLAG_FAILOK "LIBRADOS_OP_FLAG_FAILOK"
+        _LIBRADOS_OP_FLAG_FADVISE_RANDOM "LIBRADOS_OP_FLAG_FADVISE_RANDOM"
+        _LIBRADOS_OP_FLAG_FADVISE_SEQUENTIAL "LIBRADOS_OP_FLAG_FADVISE_SEQUENTIAL"
+        _LIBRADOS_OP_FLAG_FADVISE_WILLNEED "LIBRADOS_OP_FLAG_FADVISE_WILLNEED"
+        _LIBRADOS_OP_FLAG_FADVISE_DONTNEED "LIBRADOS_OP_FLAG_FADVISE_DONTNEED"
+        _LIBRADOS_OP_FLAG_FADVISE_NOCACHE "LIBRADOS_OP_FLAG_FADVISE_NOCACHE"
+
+
+    enum:
+        _LIBRADOS_OPERATION_NOFLAG "LIBRADOS_OPERATION_NOFLAG"
+        _LIBRADOS_OPERATION_BALANCE_READS "LIBRADOS_OPERATION_BALANCE_READS"
+        _LIBRADOS_OPERATION_LOCALIZE_READS "LIBRADOS_OPERATION_LOCALIZE_READS"
+        _LIBRADOS_OPERATION_ORDER_READS_WRITES "LIBRADOS_OPERATION_ORDER_READS_WRITES"
+        _LIBRADOS_OPERATION_IGNORE_CACHE "LIBRADOS_OPERATION_IGNORE_CACHE"
+        _LIBRADOS_OPERATION_SKIPRWLOCKS "LIBRADOS_OPERATION_SKIPRWLOCKS"
+        _LIBRADOS_OPERATION_IGNORE_OVERLAY "LIBRADOS_OPERATION_IGNORE_OVERLAY"
+
+    cdef uint64_t _LIBRADOS_SNAP_HEAD "LIBRADOS_SNAP_HEAD"
+
+    ctypedef void* rados_t
+    ctypedef void* rados_config_t
+    ctypedef void* rados_ioctx_t
+    ctypedef void* rados_xattrs_iter_t
+    ctypedef void* rados_omap_iter_t
+    ctypedef void* rados_list_ctx_t
+    ctypedef uint64_t rados_snap_t
+    ctypedef void *rados_write_op_t
+    ctypedef void *rados_read_op_t
+    ctypedef void *rados_completion_t
+    ctypedef void (*rados_callback_t)(rados_completion_t cb, void *arg)
+    ctypedef void (*rados_log_callback_t)(void *arg, const char *line, const char *who,
+                                          uint64_t sec, uint64_t nsec, uint64_t seq, const char *level, const char *msg)
+
+
+    cdef struct rados_cluster_stat_t:
+        uint64_t kb
+        uint64_t kb_used
+        uint64_t kb_avail
+        uint64_t num_objects
+
+    cdef struct rados_pool_stat_t:
+        uint64_t num_bytes
+        uint64_t num_kb
+        uint64_t num_objects
+        uint64_t num_object_clones
+        uint64_t num_object_copies
+        uint64_t num_objects_missing_on_primary
+        uint64_t num_objects_unfound
+        uint64_t num_objects_degraded
+        uint64_t num_rd
+        uint64_t num_rd_kb
+        uint64_t num_wr
+        uint64_t num_wr_kb
+
+    void rados_buffer_free(char *buf)
+
+    void rados_version(int *major, int *minor, int *extra)
+    int rados_create2(rados_t *pcluster, const char *const clustername,
+                      const char * const name, uint64_t flags)
+    int rados_connect(rados_t cluster)
+    void rados_shutdown(rados_t cluster)
+    int rados_conf_read_file(rados_t cluster, const char *path)
+    int rados_conf_parse_argv_remainder(rados_t cluster, int argc, const char **argv, const char **remargv)
+    int rados_conf_parse_env(rados_t cluster, const char *var)
+    int rados_conf_set(rados_t cluster, char *option, const char *value)
+    int rados_conf_get(rados_t cluster, char *option, char *buf, size_t len)
+
+    int rados_ioctx_pool_stat(rados_ioctx_t io, rados_pool_stat_t *stats)
+    int64_t rados_pool_lookup(rados_t cluster, const char *pool_name)
+    int rados_pool_reverse_lookup(rados_t cluster, int64_t id, char *buf, size_t maxlen)
+    int rados_pool_create(rados_t cluster, const char *pool_name)
+    int rados_pool_create_with_auid(rados_t cluster, const char *pool_name, uint64_t auid)
+    int rados_pool_create_with_crush_rule(rados_t cluster, const char *pool_name, uint8_t crush_rule_num)
+    int rados_pool_create_with_all(rados_t cluster, const char *pool_name, uint64_t auid, uint8_t crush_rule_num)
+    int rados_pool_get_base_tier(rados_t cluster, int64_t pool, int64_t *base_tier)
+    int rados_pool_list(rados_t cluster, char *buf, size_t len)
+    int rados_pool_delete(rados_t cluster, const char *pool_name)
+    int rados_inconsistent_pg_list(rados_t cluster, int64_t pool, char *buf, size_t len)
+
+    int rados_cluster_stat(rados_t cluster, rados_cluster_stat_t *result)
+    int rados_cluster_fsid(rados_t cluster, char *buf, size_t len)
+    int rados_blacklist_add(rados_t cluster, char *client_address, uint32_t expire_seconds)
+
+    int rados_ping_monitor(rados_t cluster, const char *mon_id, char **outstr, size_t *outstrlen)
+    int rados_mon_command(rados_t cluster, const char **cmd, size_t cmdlen,
+                          const char *inbuf, size_t inbuflen,
+                          char **outbuf, size_t *outbuflen,
+                          char **outs, size_t *outslen)
+    int rados_mon_command_target(rados_t cluster, const char *name, const char **cmd, size_t cmdlen,
+                                 const char *inbuf, size_t inbuflen,
+                                 char **outbuf, size_t *outbuflen,
+                                 char **outs, size_t *outslen)
+    int rados_osd_command(rados_t cluster, int osdid, const char **cmd, size_t cmdlen,
+                          const char *inbuf, size_t inbuflen,
+                          char **outbuf, size_t *outbuflen,
+                          char **outs, size_t *outslen)
+    int rados_pg_command(rados_t cluster, const char *pgstr, const char **cmd, size_t cmdlen,
+                         const char *inbuf, size_t inbuflen,
+                         char **outbuf, size_t *outbuflen,
+                         char **outs, size_t *outslen)
+    int rados_monitor_log(rados_t cluster, const char *level, rados_log_callback_t cb, void *arg)
+
+    int rados_wait_for_latest_osdmap(rados_t cluster)
+
+    int rados_ioctx_create(rados_t cluster, const char *pool_name, rados_ioctx_t *ioctx)
+    void rados_ioctx_destroy(rados_ioctx_t io)
+    int rados_ioctx_pool_set_auid(rados_ioctx_t io, uint64_t auid)
+    void rados_ioctx_locator_set_key(rados_ioctx_t io, const char *key)
+    void rados_ioctx_set_namespace(rados_ioctx_t io, const char * nspace)
+
+    uint64_t rados_get_last_version(rados_ioctx_t io)
+    int rados_stat(rados_ioctx_t io, const char *o, uint64_t *psize, time_t *pmtime)
+    int rados_write(rados_ioctx_t io, const char *oid, const char *buf, size_t len, uint64_t off)
+    int rados_write_full(rados_ioctx_t io, const char *oid, const char *buf, size_t len)
+    int rados_append(rados_ioctx_t io, const char *oid, const char *buf, size_t len)
+    int rados_read(rados_ioctx_t io, const char *oid, char *buf, size_t len, uint64_t off)
+    int rados_remove(rados_ioctx_t io, const char *oid)
+    int rados_trunc(rados_ioctx_t io, const char *oid, uint64_t size)
+    int rados_getxattr(rados_ioctx_t io, const char *o, const char *name, char *buf, size_t len)
+    int rados_setxattr(rados_ioctx_t io, const char *o, const char *name, const char *buf, size_t len)
+    int rados_rmxattr(rados_ioctx_t io, const char *o, const char *name)
+    int rados_getxattrs(rados_ioctx_t io, const char *oid, rados_xattrs_iter_t *iter)
+    int rados_getxattrs_next(rados_xattrs_iter_t iter, const char **name, const char **val, size_t *len)
+    void rados_getxattrs_end(rados_xattrs_iter_t iter)
+
+    int rados_nobjects_list_open(rados_ioctx_t io, rados_list_ctx_t *ctx)
+    int rados_nobjects_list_next(rados_list_ctx_t ctx, const char **entry, const char **key, const char **nspace)
+    void rados_nobjects_list_close(rados_list_ctx_t ctx)
+
+    int rados_ioctx_snap_rollback(rados_ioctx_t io, const char * oid, const char * snapname)
+    int rados_ioctx_snap_create(rados_ioctx_t io, const char * snapname)
+    int rados_ioctx_snap_remove(rados_ioctx_t io, const char * snapname)
+    int rados_ioctx_snap_lookup(rados_ioctx_t io, const char * name, rados_snap_t * id)
+    int rados_ioctx_snap_get_name(rados_ioctx_t io, rados_snap_t id, char * name, int maxlen)
+    void rados_ioctx_snap_set_read(rados_ioctx_t io, rados_snap_t snap)
+    int rados_ioctx_snap_list(rados_ioctx_t io, rados_snap_t * snaps, int maxlen)
+    int rados_ioctx_snap_get_stamp(rados_ioctx_t io, rados_snap_t id, time_t * t)
+
+    int rados_lock_exclusive(rados_ioctx_t io, const char * oid, const char * name,
+                             const char * cookie, const char * desc,
+                             timeval * duration, uint8_t flags)
+    int rados_lock_shared(rados_ioctx_t io, const char * o, const char * name,
+                          const char * cookie, const char * tag, const char * desc,
+                          timeval * duration, uint8_t flags)
+    int rados_unlock(rados_ioctx_t io, const char * o, const char * name, const char * cookie)
+
+    rados_write_op_t rados_create_write_op()
+    void rados_release_write_op(rados_write_op_t write_op)
+
+    rados_read_op_t rados_create_read_op()
+    void rados_release_read_op(rados_read_op_t read_op)
+
+    int rados_aio_create_completion(void * cb_arg, rados_callback_t cb_complete, rados_callback_t cb_safe, rados_completion_t * pc)
+    void rados_aio_release(rados_completion_t c)
+    int rados_aio_write(rados_ioctx_t io, const char * oid, rados_completion_t completion, const char * buf, size_t len, uint64_t off)
+    int rados_aio_append(rados_ioctx_t io, const char * oid, rados_completion_t completion, const char * buf, size_t len)
+    int rados_aio_write_full(rados_ioctx_t io, const char * oid, rados_completion_t completion, const char * buf, size_t len)
+    int rados_aio_remove(rados_ioctx_t io, const char * oid, rados_completion_t completion)
+    int rados_aio_read(rados_ioctx_t io, const char * oid, rados_completion_t completion, char * buf, size_t len, uint64_t off)
+    int rados_aio_flush(rados_ioctx_t io)
+
+    int rados_aio_get_return_value(rados_completion_t c)
+    int rados_aio_wait_for_complete_and_cb(rados_completion_t c)
+    int rados_aio_wait_for_safe_and_cb(rados_completion_t c)
+    int rados_aio_wait_for_complete(rados_completion_t c)
+    int rados_aio_wait_for_safe(rados_completion_t c)
+    int rados_aio_is_complete(rados_completion_t c)
+    int rados_aio_is_safe(rados_completion_t c)
+
+    int rados_exec(rados_ioctx_t io, const char * oid, const char * cls, const char * method,
+                   const char * in_buf, size_t in_len, char * buf, size_t out_len)
+
+    int rados_write_op_operate(rados_write_op_t write_op, rados_ioctx_t io, const char * oid, time_t * mtime, int flags)
+    void rados_write_op_omap_set(rados_write_op_t write_op, const char * const* keys, const char * const* vals, const size_t * lens, size_t num)
+    void rados_write_op_omap_rm_keys(rados_write_op_t write_op, const char * const* keys, size_t keys_len)
+    void rados_write_op_omap_clear(rados_write_op_t write_op)
+    void rados_read_op_omap_get_vals(rados_read_op_t read_op, const char * start_after, const char * filter_prefix, uint64_t max_return, rados_omap_iter_t * iter, int * prval)
+    void rados_read_op_omap_get_keys(rados_read_op_t read_op, const char * start_after, uint64_t max_return, rados_omap_iter_t * iter, int * prval)
+    void rados_read_op_omap_get_vals_by_keys(rados_read_op_t read_op, const char * const* keys, size_t keys_len, rados_omap_iter_t * iter, int * prval)
+    int rados_read_op_operate(rados_read_op_t read_op, rados_ioctx_t io, const char * oid, int flags)
+    int rados_omap_get_next(rados_omap_iter_t iter, const char * const* key, const char * const* val, size_t * len)
+    void rados_omap_get_end(rados_omap_iter_t iter)
+
+
+LIBRADOS_OP_FLAG_EXCL = _LIBRADOS_OP_FLAG_EXCL
+LIBRADOS_OP_FLAG_FAILOK = _LIBRADOS_OP_FLAG_FAILOK
+LIBRADOS_OP_FLAG_FADVISE_RANDOM = _LIBRADOS_OP_FLAG_FADVISE_RANDOM
+LIBRADOS_OP_FLAG_FADVISE_SEQUENTIAL = _LIBRADOS_OP_FLAG_FADVISE_SEQUENTIAL
+LIBRADOS_OP_FLAG_FADVISE_WILLNEED = _LIBRADOS_OP_FLAG_FADVISE_WILLNEED
+LIBRADOS_OP_FLAG_FADVISE_DONTNEED = _LIBRADOS_OP_FLAG_FADVISE_DONTNEED
+LIBRADOS_OP_FLAG_FADVISE_NOCACHE = _LIBRADOS_OP_FLAG_FADVISE_NOCACHE
+
+LIBRADOS_SNAP_HEAD = _LIBRADOS_SNAP_HEAD
+
+LIBRADOS_OPERATION_NOFLAG = _LIBRADOS_OPERATION_NOFLAG
+LIBRADOS_OPERATION_BALANCE_READS = _LIBRADOS_OPERATION_BALANCE_READS
+LIBRADOS_OPERATION_LOCALIZE_READS = _LIBRADOS_OPERATION_LOCALIZE_READS
+LIBRADOS_OPERATION_ORDER_READS_WRITES = _LIBRADOS_OPERATION_ORDER_READS_WRITES
+LIBRADOS_OPERATION_IGNORE_CACHE = _LIBRADOS_OPERATION_IGNORE_CACHE
+LIBRADOS_OPERATION_SKIPRWLOCKS = _LIBRADOS_OPERATION_SKIPRWLOCKS
+LIBRADOS_OPERATION_IGNORE_OVERLAY = _LIBRADOS_OPERATION_IGNORE_OVERLAY
+
+LIBRADOS_ALL_NSPACES = _LIBRADOS_ALL_NSPACES.decode('utf-8')
+
+ANONYMOUS_AUID = 0xffffffffffffffff
+ADMIN_AUID = 0
+
+class Error(Exception):
+    """ `Error` class, derived from `Exception` """
+
+
+class InvalidArgument(Error):
+    pass
+
+
+class InterruptedOrTimeoutError(Error):
+    """ `InterruptedOrTimeoutError` class, derived from `Error` """
+    pass
+
+
+class PermissionError(Error):
+    """ `PermissionError` class, derived from `Error` """
+    pass
+
+class PermissionDeniedError(Error):
+    """ deal with EACCES related. """
+    pass
+
+class ObjectNotFound(Error):
+    """ `ObjectNotFound` class, derived from `Error` """
+    pass
+
+
+class NoData(Error):
+    """ `NoData` class, derived from `Error` """
+    pass
+
+
+class ObjectExists(Error):
+    """ `ObjectExists` class, derived from `Error` """
+    pass
+
+
+class ObjectBusy(Error):
+    """ `ObjectBusy` class, derived from `Error` """
+    pass
+
+
+class IOError(Error):
+    """ `IOError` class, derived from `Error` """
+    pass
+
+
+class NoSpace(Error):
+    """ `NoSpace` class, derived from `Error` """
+    pass
+
+
+class IncompleteWriteError(Error):
+    """ `IncompleteWriteError` class, derived from `Error` """
+    pass
+
+
+class RadosStateError(Error):
+    """ `RadosStateError` class, derived from `Error` """
+    pass
+
+
+class IoctxStateError(Error):
+    """ `IoctxStateError` class, derived from `Error` """
+    pass
+
+class ObjectStateError(Error):
+    """ `ObjectStateError` class, derived from `Error` """
+    pass
+
+
+class LogicError(Error):
+    """ `` class, derived from `Error` """
+    pass
+
+
+class TimedOut(Error):
+    """ `TimedOut` class, derived from `Error` """
+    pass
+
+
+
+cdef errno_to_exception = {
+    errno.EPERM     : PermissionError,
+    errno.ENOENT    : ObjectNotFound,
+    errno.EIO       : IOError,
+    errno.ENOSPC    : NoSpace,
+    errno.EEXIST    : ObjectExists,
+    errno.EBUSY     : ObjectBusy,
+    errno.ENODATA   : NoData,
+    errno.EINTR     : InterruptedOrTimeoutError,
+    errno.ETIMEDOUT : TimedOut,
+    errno.EACCES    : PermissionDeniedError
+}
+
+
+cdef make_ex(ret, msg):
+    """
+    Translate a librados return code into an exception.
+
+    :param ret: the return code
+    :type ret: int
+    :param msg: the error message to use
+    :type msg: str
+    :returns: a subclass of :class:`Error`
+    """
+    ret = abs(ret)
+    if ret in errno_to_exception:
+        return errno_to_exception[ret](msg)
+    else:
+        return Error(msg + (": error code %d" % ret))
+
+
+# helper to specify an optional argument, where in addition to `cls`, `None`
+# is also acceptable
+def opt(cls):
+    return (cls, None)
+
+
+# validate argument types of an instance method
+# kwargs is an un-ordered dict, so use args instead
+def requires(*types):
+    def is_type_of(v, t):
+        if t is None:
+            return v is None
+        else:
+            return isinstance(v, t)
+
+    def check_type(val, arg_name, arg_type):
+        if isinstance(arg_type, tuple):
+            if any(is_type_of(val, t) for t in arg_type):
+                return
+            type_names = ' or '.join('None' if t is None else t.__name__
+                                     for t in arg_type)
+            raise TypeError('%s must be %s' % (arg_name, type_names))
+        else:
+            if is_type_of(val, arg_type):
+                return
+            assert(arg_type is not None)
+            raise TypeError('%s must be %s' % (arg_name, arg_type.__name__))
+
+    def wrapper(f):
+        # FIXME(sileht): this stop with
+        # AttributeError: 'method_descriptor' object has no attribute '__module__'
+        # @wraps(f)
+        def validate_func(*args, **kwargs):
+            # ignore the `self` arg
+            pos_args = zip(args[1:], types)
+            named_args = ((kwargs[name], (name, spec)) for name, spec in types
+                          if name in kwargs)
+            for arg_val, (arg_name, arg_type) in chain(pos_args, named_args):
+                check_type(arg_val, arg_name, arg_type)
+            return f(*args, **kwargs)
+        return validate_func
+    return wrapper
+
+
+def cstr(val, name, encoding="utf-8", opt=False):
+    """
+    Create a byte string from a Python string
+
+    :param basestring val: Python string
+    :param str name: Name of the string parameter, for exceptions
+    :param str encoding: Encoding to use
+    :param bool opt: If True, None is allowed
+    :rtype: bytes
+    :raises: :class:`InvalidArgument`
+    """
+    if opt and val is None:
+        return None
+    if isinstance(val, bytes):
+        return val
+    elif isinstance(val, unicode):
+        return val.encode(encoding)
+    else:
+        raise TypeError('%s must be a string' % name)
+
+
+def cstr_list(list_str, name, encoding="utf-8"):
+    return [cstr(s, name) for s in list_str]
+
+
+def decode_cstr(val, encoding="utf-8"):
+    """
+    Decode a byte string into a Python string.
+
+    :param bytes val: byte string
+    :rtype: unicode or None
+    """
+    if val is None:
+        return None
+
+    return val.decode(encoding)
+
+
+cdef char* opt_str(s) except? NULL:
+    if s is None:
+        return NULL
+    return s
+
+
+cdef void* realloc_chk(void* ptr, size_t size) except NULL:
+    cdef void *ret = realloc(ptr, size)
+    if ret == NULL:
+        raise MemoryError("realloc failed")
+    return ret
+
+
+cdef size_t * to_csize_t_array(list_int):
+    cdef size_t *ret = <size_t *>malloc(len(list_int) * sizeof(size_t))
+    if ret == NULL:
+        raise MemoryError("malloc failed")
+    for i in xrange(len(list_int)):
+        ret[i] = <size_t>list_int[i]
+    return ret
+
+
+cdef char ** to_bytes_array(list_bytes):
+    cdef char **ret = <char **>malloc(len(list_bytes) * sizeof(char *))
+    if ret == NULL:
+        raise MemoryError("malloc failed")
+    for i in xrange(len(list_bytes)):
+        ret[i] = <char *>list_bytes[i]
+    return ret
+
+
+
+cdef int __monitor_callback(void *arg, const char *line, const char *who,
+                             uint64_t sec, uint64_t nsec, uint64_t seq,
+                             const char *level, const char *msg) with gil:
+    cdef object cb_info = <object>arg
+    cb_info[0](cb_info[1], line, who, sec, nsec, seq, level, msg)
+    return 0
+
+
+class Version(object):
+    """ Version information """
+    def __init__(self, major, minor, extra):
+        self.major = major
+        self.minor = minor
+        self.extra = extra
+
+    def __str__(self):
+        return "%d.%d.%d" % (self.major, self.minor, self.extra)
+
+
+cdef class Rados(object):
+    """This class wraps librados functions"""
+    # NOTE(sileht): attributes declared in .pyd
+
+    def __init__(self, *args, **kwargs):
+        PyEval_InitThreads()
+        self.__setup(*args, **kwargs)
+
+    @requires(('rados_id', opt(str_type)), ('name', opt(str_type)), ('clustername', opt(str_type)),
+              ('conffile', opt(str_type)))
+    def __setup(self, rados_id=None, name=None, clustername=None,
+                conf_defaults=None, conffile=None, conf=None, flags=0):
+        self.monitor_callback = None
+        self.parsed_args = []
+        self.conf_defaults = conf_defaults
+        self.conffile = conffile
+        self.rados_id = rados_id
+
+        if rados_id and name:
+            raise Error("Rados(): can't supply both rados_id and name")
+        elif rados_id:
+            name = 'client.' + rados_id
+        elif name is None:
+            name = 'client.admin'
+        if clustername is None:
+            clustername = ''
+
+        name = cstr(name, 'name')
+        clustername = cstr(clustername, 'clustername')
+        cdef:
+            char *_name = name
+            char *_clustername = clustername
+            int _flags = flags
+            int ret
+
+        with nogil:
+            ret = rados_create2(&self.cluster, _clustername, _name, _flags)
+        if ret != 0:
+            raise Error("rados_initialize failed with error code: %d" % ret)
+
+        self.state = "configuring"
+        # order is important: conf_defaults, then conffile, then conf
+        if conf_defaults:
+            for key, value in conf_defaults.items():
+                self.conf_set(key, value)
+        if conffile is not None:
+            # read the default conf file when '' is given
+            if conffile == '':
+                conffile = None
+            self.conf_read_file(conffile)
+        if conf:
+            for key, value in conf.items():
+                self.conf_set(key, value)
+
+    def require_state(self, *args):
+        """
+        Checks if the Rados object is in a special state
+
+        :raises: RadosStateError
+        """
+        if self.state in args:
+            return
+        raise RadosStateError("You cannot perform that operation on a \
+Rados object in state %s." % self.state)
+
+    def shutdown(self):
+        """
+        Disconnects from the cluster.  Call this explicitly when a
+        Rados.connect()ed object is no longer used.
+        """
+        if self.state != "shutdown":
+            with nogil:
+                rados_shutdown(self.cluster)
+            self.state = "shutdown"
+
+    def __enter__(self):
+        self.connect()
+        return self
+
+    def __exit__(self, type_, value, traceback):
+        self.shutdown()
+        return False
+
+    def version(self):
+        """
+        Get the version number of the ``librados`` C library.
+
+        :returns: a tuple of ``(major, minor, extra)`` components of the
+                  librados version
+        """
+        cdef int major = 0
+        cdef int minor = 0
+        cdef int extra = 0
+        with nogil:
+            rados_version(&major, &minor, &extra)
+        return Version(major, minor, extra)
+
+    @requires(('path', opt(str_type)))
+    def conf_read_file(self, path=None):
+        """
+        Configure the cluster handle using a Ceph config file.
+
+        :param path: path to the config file
+        :type path: str
+        """
+        self.require_state("configuring", "connected")
+        path = cstr(path, 'path', opt=True)
+        cdef:
+            char *_path = opt_str(path)
+        with nogil:
+            ret = rados_conf_read_file(self.cluster, _path)
+        if (ret != 0):
+            raise make_ex(ret, "error calling conf_read_file")
+
+    def conf_parse_argv(self, args):
+        """
+        Parse known arguments from args, and remove; returned
+        args contain only those unknown to ceph
+        """
+        self.require_state("configuring", "connected")
+        if not args:
+            return
+
+        cargs = cstr_list(args, 'args')
+        cdef:
+            int _argc = len(args)
+            char **_argv = to_bytes_array(cargs)
+            char **_remargv = NULL
+
+        try:
+            _remargv = <char **>malloc(_argc * sizeof(char *))
+            with nogil:
+                ret = rados_conf_parse_argv_remainder(self.cluster, _argc,
+                                                      <const char**>_argv,
+                                                      <const char**>_remargv)
+            if ret:
+                raise make_ex(ret, "error calling conf_parse_argv_remainder")
+
+            # _remargv was allocated with fixed argc; collapse return
+            # list to eliminate any missing args
+            retargs = [decode_cstr(a) for a in _remargv[:_argc]
+                       if a != NULL]
+            self.parsed_args = args
+            return retargs
+        finally:
+            free(_argv)
+            free(_remargv)
+
+    def conf_parse_env(self, var='CEPH_ARGS'):
+        """
+        Parse known arguments from an environment variable, normally
+        CEPH_ARGS.
+        """
+        self.require_state("configuring", "connected")
+        if not var:
+            return
+
+        var = cstr(var, 'var')
+        cdef:
+            char *_var = var
+        with nogil:
+            ret = rados_conf_parse_env(self.cluster, _var)
+        if (ret != 0):
+            raise make_ex(ret, "error calling conf_parse_env")
+
+    @requires(('option', str_type))
+    def conf_get(self, option):
+        """
+        Get the value of a configuration option
+
+        :param option: which option to read
+        :type option: str
+
+        :returns: str - value of the option or None
+        :raises: :class:`TypeError`
+        """
+        self.require_state("configuring", "connected")
+        option = cstr(option, 'option')
+        cdef:
+            char *_option = option
+            size_t length = 20
+            char *ret_buf = NULL
+
+        try:
+            while True:
+                ret_buf = <char *>realloc_chk(ret_buf, length)
+                with nogil:
+                    ret = rados_conf_get(self.cluster, _option, ret_buf, length)
+                if (ret == 0):
+                    return decode_cstr(ret_buf)
+                elif (ret == -errno.ENAMETOOLONG):
+                    length = length * 2
+                elif (ret == -errno.ENOENT):
+                    return None
+                else:
+                    raise make_ex(ret, "error calling conf_get")
+        finally:
+            free(ret_buf)
+
+    @requires(('option', str_type), ('val', str_type))
+    def conf_set(self, option, val):
+        """
+        Set the value of a configuration option
+
+        :param option: which option to set
+        :type option: str
+        :param option: value of the option
+        :type option: str
+
+        :raises: :class:`TypeError`, :class:`ObjectNotFound`
+        """
+        self.require_state("configuring", "connected")
+        option = cstr(option, 'option')
+        val = cstr(val, 'val')
+        cdef:
+            char *_option = option
+            char *_val = val
+
+        with nogil:
+            ret = rados_conf_set(self.cluster, _option, _val)
+        if (ret != 0):
+            raise make_ex(ret, "error calling conf_set")
+
+    def ping_monitor(self, mon_id):
+        """
+        Ping a monitor to assess liveness
+
+        May be used as a simply way to assess liveness, or to obtain
+        information about the monitor in a simple way even in the
+        absence of quorum.
+
+        :param mon_id: the ID portion of the monitor's name (i.e., mon.<ID>)
+        :type mon_id: str
+        :returns: the string reply from the monitor
+        """
+
+        self.require_state("configuring", "connected")
+
+        mon_id = cstr(mon_id, 'mon_id')
+        cdef:
+            char *_mon_id = mon_id
+            size_t outstrlen
+            char *outstr
+
+        with nogil:
+            ret = rados_ping_monitor(self.cluster, _mon_id, &outstr, &outstrlen)
+
+        if ret != 0:
+            raise make_ex(ret, "error calling ping_monitor")
+
+        if outstrlen:
+            my_outstr = outstr[:outstrlen]
+            rados_buffer_free(outstr)
+            return decode_cstr(my_outstr)
+
+    def connect(self, timeout=0):
+        """
+        Connect to the cluster.  Use shutdown() to release resources.
+        """
+        self.require_state("configuring")
+        # NOTE(sileht): timeout was supported by old python API,
+        # but this is not something available in C API, so ignore
+        # for now and remove it later
+        with nogil:
+            ret = rados_connect(self.cluster)
+        if (ret != 0):
+            raise make_ex(ret, "error connecting to the cluster")
+        self.state = "connected"
+
+    def get_cluster_stats(self):
+        """
+        Read usage info about the cluster
+
+        This tells you total space, space used, space available, and number
+        of objects. These are not updated immediately when data is written,
+        they are eventually consistent.
+
+        :returns: dict - contains the following keys:
+
+            - ``kb`` (int) - total space
+
+            - ``kb_used`` (int) - space used
+
+            - ``kb_avail`` (int) - free space available
+
+            - ``num_objects`` (int) - number of objects
+
+        """
+        cdef:
+            rados_cluster_stat_t stats
+
+        with nogil:
+            ret = rados_cluster_stat(self.cluster, &stats)
+
+        if ret < 0:
+            raise make_ex(
+                ret, "Rados.get_cluster_stats(%s): get_stats failed" % self.rados_id)
+        return {'kb': stats.kb,
+                'kb_used': stats.kb_used,
+                'kb_avail': stats.kb_avail,
+                'num_objects': stats.num_objects}
+
+    @requires(('pool_name', str_type))
+    def pool_exists(self, pool_name):
+        """
+        Checks if a given pool exists.
+
+        :param pool_name: name of the pool to check
+        :type pool_name: str
+
+        :raises: :class:`TypeError`, :class:`Error`
+        :returns: bool - whether the pool exists, false otherwise.
+        """
+        self.require_state("connected")
+
+        pool_name = cstr(pool_name, 'pool_name')
+        cdef:
+            char *_pool_name = pool_name
+
+        with nogil:
+            ret = rados_pool_lookup(self.cluster, _pool_name)
+        if (ret >= 0):
+            return True
+        elif (ret == -errno.ENOENT):
+            return False
+        else:
+            raise make_ex(ret, "error looking up pool '%s'" % pool_name)
+
+    @requires(('pool_name', str_type))
+    def pool_lookup(self, pool_name):
+        """
+        Returns a pool's ID based on its name.
+
+        :param pool_name: name of the pool to look up
+        :type pool_name: str
+
+        :raises: :class:`TypeError`, :class:`Error`
+        :returns: int - pool ID, or None if it doesn't exist
+        """
+        self.require_state("connected")
+        pool_name = cstr(pool_name, 'pool_name')
+        cdef:
+            char *_pool_name = pool_name
+
+        with nogil:
+            ret = rados_pool_lookup(self.cluster, _pool_name)
+        if (ret >= 0):
+            return int(ret)
+        elif (ret == -errno.ENOENT):
+            return None
+        else:
+            raise make_ex(ret, "error looking up pool '%s'" % pool_name)
+
+    @requires(('pool_id', int))
+    def pool_reverse_lookup(self, pool_id):
+        """
+        Returns a pool's name based on its ID.
+
+        :param pool_id: ID of the pool to look up
+        :type pool_id: int
+
+        :raises: :class:`TypeError`, :class:`Error`
+        :returns: string - pool name, or None if it doesn't exist
+        """
+        self.require_state("connected")
+        cdef:
+            int64_t _pool_id = pool_id
+            size_t size = 512
+            char *name = NULL
+
+        try:
+            while True:
+                name = <char *>realloc_chk(name, size)
+                with nogil:
+                    ret = rados_pool_reverse_lookup(self.cluster, _pool_id, name, size)
+                if ret >= 0:
+                    break
+                elif ret != -errno.ERANGE and size <= 4096:
+                    size *= 2
+                elif ret == -errno.ENOENT:
+                    return None
+                elif ret < 0:
+                    raise make_ex(ret, "error reverse looking up pool '%s'" % pool_id)
+
+            return decode_cstr(name)
+
+        finally:
+            free(name)
+
+    @requires(('pool_name', str_type), ('auid', opt(int)), ('crush_rule', opt(int)))
+    def create_pool(self, pool_name, auid=None, crush_rule=None):
+        """
+        Create a pool:
+        - with default settings: if auid=None and crush_rule=None
+        - owned by a specific auid: auid given and crush_rule=None
+        - with a specific CRUSH rule: if auid=None and crush_rule given
+        - with a specific CRUSH rule and auid: if auid and crush_rule given
+
+        :param pool_name: name of the pool to create
+        :type pool_name: str
+        :param auid: the id of the owner of the new pool
+        :type auid: int
+        :param crush_rule: rule to use for placement in the new pool
+        :type crush_rule: int
+
+        :raises: :class:`TypeError`, :class:`Error`
+        """
+        self.require_state("connected")
+
+        pool_name = cstr(pool_name, 'pool_name')
+        cdef:
+            char *_pool_name = pool_name
+            uint8_t _crush_rule
+            uint64_t _auid
+
+        if auid is None and crush_rule is None:
+            with nogil:
+                ret = rados_pool_create(self.cluster, _pool_name)
+        elif auid is None:
+            _crush_rule = crush_rule
+            with nogil:
+                ret = rados_pool_create_with_crush_rule(self.cluster, _pool_name, _crush_rule)
+        elif crush_rule is None:
+            _auid = auid
+            with nogil:
+                ret = rados_pool_create_with_auid(self.cluster, _pool_name, _auid)
+        else:
+            _auid = auid
+            _crush_rule = crush_rule
+            with nogil:
+                ret = rados_pool_create_with_all(self.cluster, _pool_name, _auid, _crush_rule)
+        if ret < 0:
+            raise make_ex(ret, "error creating pool '%s'" % pool_name)
+
+    @requires(('pool_id', int))
+    def get_pool_base_tier(self, pool_id):
+        """
+        Get base pool
+
+        :returns: base pool, or pool_id if tiering is not configured for the pool
+        """
+        self.require_state("connected")
+        cdef:
+            int64_t base_tier = 0
+            int64_t _pool_id = pool_id
+
+        with nogil:
+            ret = rados_pool_get_base_tier(self.cluster, _pool_id, &base_tier)
+        if ret < 0:
+            raise make_ex(ret, "get_pool_base_tier(%d)" % pool_id)
+        return int(base_tier)
+
+    @requires(('pool_name', str_type))
+    def delete_pool(self, pool_name):
+        """
+        Delete a pool and all data inside it.
+
+        The pool is removed from the cluster immediately,
+        but the actual data is deleted in the background.
+
+        :param pool_name: name of the pool to delete
+        :type pool_name: str
+
+        :raises: :class:`TypeError`, :class:`Error`
+        """
+        self.require_state("connected")
+
+        pool_name = cstr(pool_name, 'pool_name')
+        cdef:
+            char *_pool_name = pool_name
+
+        with nogil:
+            ret = rados_pool_delete(self.cluster, _pool_name)
+        if ret < 0:
+            raise make_ex(ret, "error deleting pool '%s'" % pool_name)
+
+    @requires(('pool_id', int))
+    def get_inconsistent_pgs(self, pool_id):
+        """
+        List inconsistent placement groups in the given pool
+
+        :param pool_id: ID of the pool in which PGs are listed
+        :type pool_id: int
+        :returns: list - inconsistent placement groups
+        """
+        self.require_state("connected")
+        cdef:
+            int64_t pool = pool_id
+            size_t size = 512
+            char *pgs = NULL
+
+        try:
+            while True:
+                pgs = <char *>realloc_chk(pgs, size);
+                with nogil:
+                    ret = rados_inconsistent_pg_list(self.cluster, pool,
+                                                     pgs, size)
+                if ret > size:
+                    size *= 2
+                elif ret >= 0:
+                    break
+                else:
+                    raise make_ex(ret, "error calling inconsistent_pg_list")
+            return [pg for pg in decode_cstr(pgs[:ret]).split('\0') if pg]
+        finally:
+            free(pgs)
+
+    def list_pools(self):
+        """
+        Gets a list of pool names.
+
+        :returns: list - of pool names.
+        """
+        self.require_state("connected")
+        cdef:
+            size_t size = 512
+            char *c_names = NULL
+
+        try:
+            while True:
+                c_names = <char *>realloc_chk(c_names, size)
+                with nogil:
+                    ret = rados_pool_list(self.cluster, c_names, size)
+                if ret > size:
+                    size *= 2
+                elif ret >= 0:
+                    break
+            return [name for name in decode_cstr(c_names[:ret]).split('\0')
+                    if name]
+        finally:
+            free(c_names)
+
+    def get_fsid(self):
+        """
+        Get the fsid of the cluster as a hexadecimal string.
+
+        :raises: :class:`Error`
+        :returns: str - cluster fsid
+        """
+        self.require_state("connected")
+        cdef:
+            char *ret_buf
+            size_t buf_len = 37
+            PyObject* ret_s = NULL
+
+        ret_s = PyBytes_FromStringAndSize(NULL, buf_len)
+        try:
+            ret_buf = PyBytes_AsString(ret_s)
+            with nogil:
+                ret = rados_cluster_fsid(self.cluster, ret_buf, buf_len)
+            if ret < 0:
+                raise make_ex(ret, "error getting cluster fsid")
+            if ret != buf_len:
+                _PyBytes_Resize(&ret_s, ret)
+            return <object>ret_s
+        finally:
+            # We DECREF unconditionally: the cast to object above will have
+            # INCREFed if necessary. This also takes care of exceptions,
+            # including if _PyString_Resize fails (that will free the string
+            # itself and set ret_s to NULL, hence XDECREF).
+            ref.Py_XDECREF(ret_s)
+
+    @requires(('ioctx_name', str_type))
+    def open_ioctx(self, ioctx_name):
+        """
+        Create an io context
+
+        The io context allows you to perform operations within a particular
+        pool.
+
+        :param ioctx_name: name of the pool
+        :type ioctx_name: str
+
+        :raises: :class:`TypeError`, :class:`Error`
+        :returns: Ioctx - Rados Ioctx object
+        """
+        self.require_state("connected")
+        ioctx_name = cstr(ioctx_name, 'ioctx_name')
+        cdef:
+            rados_ioctx_t ioctx
+            char *_ioctx_name = ioctx_name
+        with nogil:
+            ret = rados_ioctx_create(self.cluster, _ioctx_name, &ioctx)
+        if ret < 0:
+            raise make_ex(ret, "error opening pool '%s'" % ioctx_name)
+        io = Ioctx(ioctx_name)
+        io.io = ioctx
+        return io
+
+    def mon_command(self, cmd, inbuf, timeout=0, target=None):
+        """
+        mon_command[_target](cmd, inbuf, outbuf, outbuflen, outs, outslen)
+        returns (int ret, string outbuf, string outs)
+        """
+        # NOTE(sileht): timeout is ignored because C API doesn't provide
+        # timeout argument, but we keep it for backward compat with old python binding
+
+        self.require_state("connected")
+        cmd = cstr_list(cmd, 'c')
+
+        if isinstance(target, int):
+        # NOTE(sileht): looks weird but test_monmap_dump pass int
+            target = str(target)
+
+        target = cstr(target, 'target', opt=True)
+        inbuf = cstr(inbuf, 'inbuf')
+
+        cdef:
+            char *_target = opt_str(target)
+            char **_cmd = to_bytes_array(cmd)
+            size_t _cmdlen = len(cmd)
+
+            char *_inbuf = inbuf
+            size_t _inbuf_len = len(inbuf)
+
+            char *_outbuf
+            size_t _outbuf_len
+            char *_outs
+            size_t _outs_len
+
+        try:
+            if target:
+                with nogil:
+                    ret = rados_mon_command_target(self.cluster, _target,
+                                                <const char **>_cmd, _cmdlen,
+                                                <const char*>_inbuf, _inbuf_len,
+                                                &_outbuf, &_outbuf_len,
+                                                &_outs, &_outs_len)
+            else:
+                with nogil:
+                    ret = rados_mon_command(self.cluster,
+                                            <const char **>_cmd, _cmdlen,
+                                            <const char*>_inbuf, _inbuf_len,
+                                            &_outbuf, &_outbuf_len,
+                                            &_outs, &_outs_len)
+
+            my_outs = decode_cstr(_outs[:_outs_len])
+            my_outbuf = _outbuf[:_outbuf_len]
+            if _outs_len:
+                rados_buffer_free(_outs)
+            if _outbuf_len:
+                rados_buffer_free(_outbuf)
+            return (ret, my_outbuf, my_outs)
+        finally:
+            free(_cmd)
+
+    def osd_command(self, osdid, cmd, inbuf, timeout=0):
+        """
+        osd_command(osdid, cmd, inbuf, outbuf, outbuflen, outs, outslen)
+        returns (int ret, string outbuf, string outs)
+        """
+        # NOTE(sileht): timeout is ignored because C API doesn't provide
+        # timeout argument, but we keep it for backward compat with old python binding
+        self.require_state("connected")
+
+        cmd = cstr_list(cmd, 'cmd')
+        inbuf = cstr(inbuf, 'inbuf')
+
+        cdef:
+            int _osdid = osdid
+            char **_cmd = to_bytes_array(cmd)
+            size_t _cmdlen = len(cmd)
+
+            char *_inbuf = inbuf
+            size_t _inbuf_len = len(inbuf)
+
+            char *_outbuf
+            size_t _outbuf_len
+            char *_outs
+            size_t _outs_len
+
+        try:
+            with nogil:
+                ret = rados_osd_command(self.cluster, _osdid,
+                                        <const char **>_cmd, _cmdlen,
+                                        <const char*>_inbuf, _inbuf_len,
+                                        &_outbuf, &_outbuf_len,
+                                        &_outs, &_outs_len)
+
+            my_outs = decode_cstr(_outs[:_outs_len])
+            my_outbuf = _outbuf[:_outbuf_len]
+            if _outs_len:
+                rados_buffer_free(_outs)
+            if _outbuf_len:
+                rados_buffer_free(_outbuf)
+            return (ret, my_outbuf, my_outs)
+        finally:
+            free(_cmd)
+
+    def pg_command(self, pgid, cmd, inbuf, timeout=0):
+        """
+        pg_command(pgid, cmd, inbuf, outbuf, outbuflen, outs, outslen)
+        returns (int ret, string outbuf, string outs)
+        """
+        # NOTE(sileht): timeout is ignored because C API doesn't provide
+        # timeout argument, but we keep it for backward compat with old python binding
+        self.require_state("connected")
+
+        pgid = cstr(pgid, 'pgid')
+        cmd = cstr_list(cmd, 'cmd')
+        inbuf = cstr(inbuf, 'inbuf')
+
+        cdef:
+            char *_pgid = pgid
+            char **_cmd = to_bytes_array(cmd)
+            size_t _cmdlen = len(cmd)
+
+            char *_inbuf = inbuf
+            size_t _inbuf_len = len(inbuf)
+
+            char *_outbuf
+            size_t _outbuf_len
+            char *_outs
+            size_t _outs_len
+
+        try:
+            with nogil:
+                ret = rados_pg_command(self.cluster, _pgid,
+                                       <const char **>_cmd, _cmdlen,
+                                       <const char *>_inbuf, _inbuf_len,
+                                       &_outbuf, &_outbuf_len,
+                                       &_outs, &_outs_len)
+
+            my_outs = decode_cstr(_outs[:_outs_len])
+            my_outbuf = _outbuf[:_outbuf_len]
+            if _outs_len:
+                rados_buffer_free(_outs)
+            if _outbuf_len:
+                rados_buffer_free(_outbuf)
+            return (ret, my_outbuf, my_outs)
+        finally:
+            free(_cmd)
+
+    def wait_for_latest_osdmap(self):
+        self.require_state("connected")
+        with nogil:
+            ret = rados_wait_for_latest_osdmap(self.cluster)
+        return ret
+
+    def blacklist_add(self, client_address, expire_seconds=0):
+        """
+        Blacklist a client from the OSDs
+
+        :param client_address: client address
+        :type client_address: str
+        :param expire_seconds: number of seconds to blacklist
+        :type expire_seconds: int
+
+        :raises: :class:`Error`
+        """
+        self.require_state("connected")
+        client_address =  cstr(client_address, 'client_address')
+        cdef:
+            uint32_t _expire_seconds = expire_seconds
+            char *_client_address = client_address
+
+        with nogil:
+            ret = rados_blacklist_add(self.cluster, _client_address, _expire_seconds)
+        if ret < 0:
+            raise make_ex(ret, "error blacklisting client '%s'" % client_address)
+
+    def monitor_log(self, level, callback, arg):
+        if level not in MONITOR_LEVELS:
+            raise LogicError("invalid monitor level " + level)
+        if callback is not None and not callable(callback):
+            raise LogicError("callback must be a callable function or None")
+
+        level = cstr(level, 'level')
+        cdef char *_level = level
+
+        if callback is None:
+            with nogil:
+                r = rados_monitor_log(self.cluster, <const char*>_level, NULL, NULL)
+            self.monitor_callback = None
+            return
+
+        cb = (callback, arg)
+        cdef PyObject* _arg = <PyObject*>cb
+        with nogil:
+            r = rados_monitor_log(self.cluster, <const char*>_level,
+                                  <rados_log_callback_t>&__monitor_callback, _arg)
+
+        if r:
+            raise make_ex(r, 'error calling rados_monitor_log')
+        # NOTE(sileht): Prevents the callback method from being garbage collected
+        self.monitor_callback = cb
+
+
+cdef class OmapIterator(object):
+    """Omap iterator"""
+
+    cdef public Ioctx ioctx
+    cdef rados_omap_iter_t ctx
+
+    def __cinit__(self, Ioctx ioctx):
+        self.ioctx = ioctx
+
+    def __iter__(self):
+        return self
+
+    def __next__(self):
+        """
+        Get the next key-value pair in the object
+        :returns: next rados.OmapItem
+        """
+        cdef:
+            char *key_ = NULL
+            char *val_ = NULL
+            size_t len_
+
+        with nogil:
+            ret = rados_omap_get_next(self.ctx, &key_, &val_, &len_)
+
+        if (ret != 0):
+            raise make_ex(ret, "error iterating over the omap")
+        if key_ == NULL:
+            raise StopIteration()
+        key = decode_cstr(key_)
+        val = None
+        if val_ != NULL:
+            val = val_[:len_]
+        return (key, val)
+
+    def __dealloc__(self):
+        with nogil:
+            rados_omap_get_end(self.ctx)
+
+
+cdef class ObjectIterator(object):
+    """rados.Ioctx Object iterator"""
+
+    cdef rados_list_ctx_t ctx
+
+    cdef public object ioctx
+
+    def __cinit__(self, Ioctx ioctx):
+        self.ioctx = ioctx
+
+        with nogil:
+            ret = rados_nobjects_list_open(ioctx.io, &self.ctx)
+        if ret < 0:
+            raise make_ex(ret, "error iterating over the objects in ioctx '%s'"
+                          % self.ioctx.name)
+
+    def __iter__(self):
+        return self
+
+    def __next__(self):
+        """
+        Get the next object name and locator in the pool
+
+        :raises: StopIteration
+        :returns: next rados.Ioctx Object
+        """
+        cdef:
+            const char *key_ = NULL
+            const char *locator_ = NULL
+            const char *nspace_ = NULL
+
+        with nogil:
+            ret = rados_nobjects_list_next(self.ctx, &key_, &locator_, &nspace_)
+
+        if ret < 0:
+            raise StopIteration()
+
+        key = decode_cstr(key_)
+        locator = decode_cstr(locator_) if locator_ != NULL else None
+        nspace = decode_cstr(nspace_) if nspace_ != NULL else None
+        return Object(self.ioctx, key, locator, nspace)
+
+    def __dealloc__(self):
+        with nogil:
+            rados_nobjects_list_close(self.ctx)
+
+
+cdef class XattrIterator(object):
+    """Extended attribute iterator"""
+
+    cdef rados_xattrs_iter_t it
+    cdef char* _oid
+
+    cdef public Ioctx ioctx
+    cdef public object oid
+
+    def __cinit__(self, Ioctx ioctx, oid):
+        self.ioctx = ioctx
+        self.oid = cstr(oid, 'oid')
+        self._oid = self.oid
+
+        with nogil:
+            ret = rados_getxattrs(ioctx.io,  self._oid, &self.it)
+        if ret != 0:
+            raise make_ex(ret, "Failed to get rados xattrs for object %r" % oid)
+
+    def __iter__(self):
+        return self
+
+    def __next__(self):
+        """
+        Get the next xattr on the object
+
+        :raises: StopIteration
+        :returns: pair - of name and value of the next Xattr
+        """
+        cdef:
+            const char *name_ = NULL
+            const char *val_ = NULL
+            size_t len_ = 0
+
+        with nogil:
+            ret = rados_getxattrs_next(self.it, &name_, &val_, &len_)
+        if (ret != 0):
+            raise make_ex(ret, "error iterating over the extended attributes \
+in '%s'" % self.oid)
+        if name_ == NULL:
+            raise StopIteration()
+        name = decode_cstr(name_)
+        val = val_[:len_]
+        return (name, val)
+
+    def __dealloc__(self):
+        with nogil:
+            rados_getxattrs_end(self.it)
+
+
+cdef class SnapIterator(object):
+    """Snapshot iterator"""
+
+    cdef public Ioctx ioctx
+
+    cdef rados_snap_t *snaps
+    cdef int max_snap
+    cdef int cur_snap
+
+    def __cinit__(self, Ioctx ioctx):
+        self.ioctx = ioctx
+        # We don't know how big a buffer we need until we've called the
+        # function. So use the exponential doubling strategy.
+        cdef int num_snaps = 10
+        while True:
+            self.snaps = <rados_snap_t*>realloc_chk(self.snaps,
+                                                    num_snaps *
+                                                    sizeof(rados_snap_t))
+
+            with nogil:
+                ret = rados_ioctx_snap_list(ioctx.io, self.snaps, num_snaps)
+            if (ret >= 0):
+                self.max_snap = ret
+                break
+            elif (ret != -errno.ERANGE):
+                raise make_ex(ret, "error calling rados_snap_list for \
+ioctx '%s'" % self.ioctx.name)
+            num_snaps = num_snaps * 2
+        self.cur_snap = 0
+
+    def __iter__(self):
+        return self
+
+    def __next__(self):
+        """
+        Get the next Snapshot
+
+        :raises: :class:`Error`, StopIteration
+        :returns: Snap - next snapshot
+        """
+        if (self.cur_snap >= self.max_snap):
+            raise StopIteration
+
+        cdef:
+            rados_snap_t snap_id = self.snaps[self.cur_snap]
+            int name_len = 10
+            char *name = NULL
+
+        try:
+            while True:
+                name = <char *>realloc_chk(name, name_len)
+                with nogil:
+                    ret = rados_ioctx_snap_get_name(self.ioctx.io, snap_id, name, name_len)
+                if (ret == 0):
+                    break
+                elif (ret != -errno.ERANGE):
+                    raise make_ex(ret, "rados_snap_get_name error")
+                else:
+                    name_len = name_len * 2
+
+            snap = Snap(self.ioctx, decode_cstr(name[:name_len]).rstrip('\0'), snap_id)
+            self.cur_snap = self.cur_snap + 1
+            return snap
+        finally:
+            free(name)
+
+
+cdef class Snap(object):
+    """Snapshot object"""
+    cdef public Ioctx ioctx
+    cdef public object name
+
+    # NOTE(sileht): old API was storing the ctypes object
+    # instead of the value ....
+    cdef public rados_snap_t snap_id
+
+    def __cinit__(self, Ioctx ioctx, object name, rados_snap_t snap_id):
+        self.ioctx = ioctx
+        self.name = name
+        self.snap_id = snap_id
+
+    def __str__(self):
+        return "rados.Snap(ioctx=%s,name=%s,snap_id=%d)" \
+            % (str(self.ioctx), self.name, self.snap_id)
+
+    def get_timestamp(self):
+        """
+        Find when a snapshot in the current pool occurred
+
+        :raises: :class:`Error`
+        :returns: datetime - the data and time the snapshot was created
+        """
+        cdef time_t snap_time
+
+        with nogil:
+            ret = rados_ioctx_snap_get_stamp(self.ioctx.io, self.snap_id, &snap_time)
+        if (ret != 0):
+            raise make_ex(ret, "rados_ioctx_snap_get_stamp error")
+        return datetime.fromtimestamp(snap_time)
+
+
+cdef class Completion(object):
+    """completion object"""
+
+    cdef public:
+         Ioctx ioctx
+         object oncomplete
+         object onsafe
+
+    cdef:
+         rados_callback_t complete_cb
+         rados_callback_t safe_cb
+         rados_completion_t rados_comp
+         PyObject* buf
+
+    def __cinit__(self, Ioctx ioctx, object oncomplete, object onsafe):
+        self.oncomplete = oncomplete
+        self.onsafe = onsafe
+        self.ioctx = ioctx
+
+    def is_safe(self):
+        """
+        Is an asynchronous operation safe?
+
+        This does not imply that the safe callback has finished.
+
+        :returns: True if the operation is safe
+        """
+        with nogil:
+            ret = rados_aio_is_safe(self.rados_comp)
+        return ret == 1
+
+    def is_complete(self):
+        """
+        Has an asynchronous operation completed?
+
+        This does not imply that the safe callback has finished.
+
+        :returns: True if the operation is completed
+        """
+        with nogil:
+            ret = rados_aio_is_complete(self.rados_comp)
+        return ret == 1
+
+    def wait_for_safe(self):
+        """
+        Wait for an asynchronous operation to be marked safe
+
+        This does not imply that the safe callback has finished.
+        """
+        with nogil:
+            rados_aio_wait_for_safe(self.rados_comp)
+
+    def wait_for_complete(self):
+        """
+        Wait for an asynchronous operation to complete
+
+        This does not imply that the complete callback has finished.
+        """
+        with nogil:
+            rados_aio_wait_for_complete(self.rados_comp)
+
+    def wait_for_safe_and_cb(self):
+        """
+        Wait for an asynchronous operation to be marked safe and for
+        the safe callback to have returned
+        """
+        with nogil:
+            rados_aio_wait_for_safe_and_cb(self.rados_comp)
+
+    def wait_for_complete_and_cb(self):
+        """
+        Wait for an asynchronous operation to complete and for the
+        complete callback to have returned
+
+        :returns:  whether the operation is completed
+        """
+        with nogil:
+            ret = rados_aio_wait_for_complete_and_cb(self.rados_comp)
+        return ret
+
+    def get_return_value(self):
+        """
+        Get the return value of an asychronous operation
+
+        The return value is set when the operation is complete or safe,
+        whichever comes first.
+
+        :returns: int - return value of the operation
+        """
+        with nogil:
+            ret = rados_aio_get_return_value(self.rados_comp)
+        return ret
+
+    def __dealloc__(self):
+        """
+        Release a completion
+
+        Call this when you no longer need the completion. It may not be
+        freed immediately if the operation is not acked and committed.
+        """
+        ref.Py_XDECREF(self.buf)
+        self.buf = NULL
+        if self.rados_comp != NULL:
+            with nogil:
+                rados_aio_release(self.rados_comp)
+                self.rados_comp = NULL
+
+    def _complete(self):
+        self.oncomplete(self)
+        with self.ioctx.lock:
+            if self.oncomplete:
+                self.ioctx.complete_completions.remove(self)
+
+    def _safe(self):
+        self.onsafe(self)
+        with self.ioctx.lock:
+            if self.onsafe:
+                self.ioctx.safe_completions.remove(self)
+
+    def _cleanup(self):
+        with self.ioctx.lock:
+            if self.oncomplete:
+                self.ioctx.complete_completions.remove(self)
+            if self.onsafe:
+                self.ioctx.safe_completions.remove(self)
+
+
+class OpCtx(object):
+    def __enter__(self):
+        return self.create()
+
+    def __exit__(self, type, msg, traceback):
+        self.release()
+
+
+cdef class WriteOp(object):
+    cdef rados_write_op_t write_op
+
+    def create(self):
+        with nogil:
+            self.write_op = rados_create_write_op()
+        return self
+
+    def release(self):
+        with nogil:
+            rados_release_write_op(self.write_op)
+
+
+class WriteOpCtx(WriteOp, OpCtx):
+    """write operation context manager"""
+
+
+cdef class ReadOp(object):
+    cdef rados_read_op_t read_op
+
+    def create(self):
+        with nogil:
+            self.read_op = rados_create_read_op()
+        return self
+
+    def release(self):
+        with nogil:
+            rados_release_read_op(self.read_op)
+
+
+class ReadOpCtx(ReadOp, OpCtx):
+    """read operation context manager"""
+
+
+cdef int __aio_safe_cb(rados_completion_t completion, void *args) with gil:
+    """
+    Callback to onsafe() for asynchronous operations
+    """
+    cdef object cb = <object>args
+    cb._safe()
+    return 0
+
+
+cdef int __aio_complete_cb(rados_completion_t completion, void *args) with gil:
+    """
+    Callback to oncomplete() for asynchronous operations
+    """
+    cdef object cb = <object>args
+    cb._complete()
+    return 0
+
+
+cdef class Ioctx(object):
+    """rados.Ioctx object"""
+    # NOTE(sileht): attributes declared in .pyd
+
+    def __init__(self, name):
+        self.name = name
+        self.state = "open"
+
+        self.locator_key = ""
+        self.nspace = ""
+        self.lock = threading.Lock()
+        self.safe_completions = []
+        self.complete_completions = []
+
+    def __enter__(self):
+        return self
+
+    def __exit__(self, type_, value, traceback):
+        self.close()
+        return False
+
+    def __del__(self):
+        self.close()
+
+    def __track_completion(self, completion_obj):
+        if completion_obj.oncomplete:
+            with self.lock:
+                self.complete_completions.append(completion_obj)
+        if completion_obj.onsafe:
+            with self.lock:
+                self.safe_completions.append(completion_obj)
+
+    def __get_completion(self, oncomplete, onsafe):
+        """
+        Constructs a completion to use with asynchronous operations
+
+        :param oncomplete: what to do when the write is safe and complete in memory
+            on all replicas
+        :type oncomplete: completion
+        :param onsafe:  what to do when the write is safe and complete on storage
+            on all replicas
+        :type onsafe: completion
+
+        :raises: :class:`Error`
+        :returns: completion object
+        """
+
+        completion_obj = Completion(self, oncomplete, onsafe)
+
+        cdef:
+            rados_callback_t complete_cb = NULL
+            rados_callback_t safe_cb = NULL
+            rados_completion_t completion
+            PyObject* p_completion_obj= <PyObject*>completion_obj
+
+        if oncomplete:
+            complete_cb = <rados_callback_t>&__aio_complete_cb
+        if onsafe:
+            safe_cb = <rados_callback_t>&__aio_safe_cb
+
+        with nogil:
+            ret = rados_aio_create_completion(p_completion_obj, complete_cb, safe_cb,
+                                              &completion)
+        if ret < 0:
+            raise make_ex(ret, "error getting a completion")
+
+        completion_obj.rados_comp = completion
+        return completion_obj
+
+    def aio_write(self, object_name, to_write, offset=0,
+                  oncomplete=None, onsafe=None):
+        """
+        Write data to an object asynchronously
+
+        Queues the write and returns.
+
+        :param object_name: name of the object
+        :type object_name: str
+        :param to_write: data to write
+        :type to_write: bytes
+        :param offset: byte offset in the object to begin writing at
+        :type offset: int
+        :param oncomplete: what to do when the write is safe and complete in memory
+            on all replicas
+        :type oncomplete: completion
+        :param onsafe:  what to do when the write is safe and complete on storage
+            on all replicas
+        :type onsafe: completion
+
+        :raises: :class:`Error`
+        :returns: completion object
+        """
+
+        object_name = cstr(object_name, 'object_name')
+
+        cdef:
+            Completion completion
+            char* _object_name = object_name
+            char* _to_write = to_write
+            size_t size = len(to_write)
+            uint64_t _offset = offset
+
+        completion = self.__get_completion(oncomplete, onsafe)
+        self.__track_completion(completion)
+        with nogil:
+            ret = rados_aio_write(self.io, _object_name, completion.rados_comp,
+                                _to_write, size, _offset)
+        if ret < 0:
+            completion._cleanup()
+            raise make_ex(ret, "error writing object %s" % object_name)
+        return completion
+
+    def aio_write_full(self, object_name, to_write,
+                       oncomplete=None, onsafe=None):
+        """
+        Asychronously write an entire object
+
+        The object is filled with the provided data. If the object exists,
+        it is atomically truncated and then written.
+        Queues the write and returns.
+
+        :param object_name: name of the object
+        :type object_name: str
+        :param to_write: data to write
+        :type to_write: str
+        :param oncomplete: what to do when the write is safe and complete in memory
+            on all replicas
+        :type oncomplete: completion
+        :param onsafe:  what to do when the write is safe and complete on storage
+            on all replicas
+        :type onsafe: completion
+
+        :raises: :class:`Error`
+        :returns: completion object
+        """
+
+        object_name = cstr(object_name, 'object_name')
+
+        cdef:
+            Completion completion
+            char* _object_name = object_name
+            char* _to_write = to_write
+            size_t size = len(to_write)
+
+        completion = self.__get_completion(oncomplete, onsafe)
+        self.__track_completion(completion)
+        with nogil:
+            ret = rados_aio_write_full(self.io, _object_name,
+                                    completion.rados_comp,
+                                    _to_write, size)
+        if ret < 0:
+            completion._cleanup()
+            raise make_ex(ret, "error writing object %s" % object_name)
+        return completion
+
+    def aio_append(self, object_name, to_append, oncomplete=None, onsafe=None):
+        """
+        Asychronously append data to an object
+
+        Queues the write and returns.
+
+        :param object_name: name of the object
+        :type object_name: str
+        :param to_append: data to append
+        :type to_append: str
+        :param offset: byte offset in the object to begin writing at
+        :type offset: int
+        :param oncomplete: what to do when the write is safe and complete in memory
+            on all replicas
+        :type oncomplete: completion
+        :param onsafe:  what to do when the write is safe and complete on storage
+            on all replicas
+        :type onsafe: completion
+
+        :raises: :class:`Error`
+        :returns: completion object
+        """
+        object_name = cstr(object_name, 'object_name')
+
+        cdef:
+            Completion completion
+            char* _object_name = object_name
+            char* _to_append = to_append
+            size_t size = len(to_append)
+
+        completion = self.__get_completion(oncomplete, onsafe)
+        self.__track_completion(completion)
+        with nogil:
+            ret = rados_aio_append(self.io, _object_name,
+                                completion.rados_comp,
+                                _to_append, size)
+        if ret < 0:
+            completion._cleanup()
+            raise make_ex(ret, "error appending object %s" % object_name)
+        return completion
+
+    def aio_flush(self):
+        """
+        Block until all pending writes in an io context are safe
+
+        :raises: :class:`Error`
+        """
+        with nogil:
+            ret = rados_aio_flush(self.io)
+        if ret < 0:
+            raise make_ex(ret, "error flushing")
+
+    def aio_read(self, object_name, length, offset, oncomplete):
+        """
+        Asychronously read data from an object
+
+        oncomplete will be called with the returned read value as
+        well as the completion:
+
+        oncomplete(completion, data_read)
+
+        :param object_name: name of the object to read from
+        :type object_name: str
+        :param length: the number of bytes to read
+        :type length: int
+        :param offset: byte offset in the object to begin reading from
+        :type offset: int
+        :param oncomplete: what to do when the read is complete
+        :type oncomplete: completion
+
+        :raises: :class:`Error`
+        :returns: completion object
+        """
+
+        object_name = cstr(object_name, 'object_name')
+
+        cdef:
+            Completion completion
+            char* _object_name = object_name
+            uint64_t _offset = offset
+
+            char *ref_buf
+            size_t _length = length
+
+        def oncomplete_(completion_v):
+            cdef Completion _completion_v = completion_v
+            return_value = _completion_v.get_return_value()
+            if return_value > 0 and return_value != length:
+                _PyBytes_Resize(&_completion_v.buf, return_value)
+            return oncomplete(_completion_v, <object>_completion_v.buf if return_value >= 0 else None)
+
+        completion = self.__get_completion(oncomplete_, None)
+        completion.buf = PyBytes_FromStringAndSize(NULL, length)
+        ret_buf = PyBytes_AsString(completion.buf)
+        self.__track_completion(completion)
+        with nogil:
+            ret = rados_aio_read(self.io, _object_name, completion.rados_comp,
+                                ret_buf, _length, _offset)
+        if ret < 0:
+            completion._cleanup()
+            raise make_ex(ret, "error reading %s" % object_name)
+        return completion
+
+    def aio_remove(self, object_name, oncomplete=None, onsafe=None):
+        """
+        Asychronously remove an object
+
+        :param object_name: name of the object to remove
+        :type object_name: str
+        :param oncomplete: what to do when the remove is safe and complete in memory
+            on all replicas
+        :type oncomplete: completion
+        :param onsafe:  what to do when the remove is safe and complete on storage
+            on all replicas
+        :type onsafe: completion
+
+        :raises: :class:`Error`
+        :returns: completion object
+        """
+        object_name = cstr(object_name, 'object_name')
+
+        cdef:
+            Completion completion
+            char* _object_name = object_name
+
+        completion = self.__get_completion(oncomplete, onsafe)
+        self.__track_completion(completion)
+        with nogil:
+            ret = rados_aio_remove(self.io, _object_name,
+                                completion.rados_comp)
+        if ret < 0:
+            completion._cleanup()
+            raise make_ex(ret, "error removing %s" % object_name)
+        return completion
+
+    def require_ioctx_open(self):
+        """
+        Checks if the rados.Ioctx object state is 'open'
+
+        :raises: IoctxStateError
+        """
+        if self.state != b"open":
+            raise IoctxStateError("The pool is %s" % self.state)
+
+    def change_auid(self, auid):
+        """
+        Attempt to change an io context's associated auid "owner."
+
+        Requires that you have write permission on both the current and new
+        auid.
+
+        :raises: :class:`Error`
+        """
+        self.require_ioctx_open()
+
+        cdef:
+            uint64_t _auid = auid
+
+        with nogil:
+            ret = rados_ioctx_pool_set_auid(self.io, _auid)
+        if ret < 0:
+            raise make_ex(ret, "error changing auid of '%s' to %d"
+                          % (self.name, auid))
+
+    @requires(('loc_key', str_type))
+    def set_locator_key(self, loc_key):
+        """
+        Set the key for mapping objects to pgs within an io context.
+
+        The key is used instead of the object name to determine which
+        placement groups an object is put in. This affects all subsequent
+        operations of the io context - until a different locator key is
+        set, all objects in this io context will be placed in the same pg.
+
+        :param loc_key: the key to use as the object locator, or NULL to discard
+            any previously set key
+        :type loc_key: str
+
+        :raises: :class:`TypeError`
+        """
+        self.require_ioctx_open()
+        cloc_key = cstr(loc_key, 'loc_key')
+        cdef char *_loc_key = cloc_key
+        with nogil:
+            rados_ioctx_locator_set_key(self.io, _loc_key)
+        self.locator_key = loc_key
+
+    def get_locator_key(self):
+        """
+        Get the locator_key of context
+
+        :returns: locator_key
+        """
+        return self.locator_key
+
+    @requires(('snap_id', long))
+    def set_read(self, snap_id):
+        """
+        Set the snapshot for reading objects.
+
+        To stop to read from snapshot, use set_read(LIBRADOS_SNAP_HEAD)
+
+        :param snap_id: the snapshot Id
+        :type snap_id: int
+
+        :raises: :class:`TypeError`
+        """
+        self.require_ioctx_open()
+        cdef rados_snap_t _snap_id = snap_id
+        with nogil:
+            rados_ioctx_snap_set_read(self.io, _snap_id)
+
+    @requires(('nspace', str_type))
+    def set_namespace(self, nspace):
+        """
+        Set the namespace for objects within an io context.
+
+        The namespace in addition to the object name fully identifies
+        an object. This affects all subsequent operations of the io context
+        - until a different namespace is set, all objects in this io context
+        will be placed in the same namespace.
+
+        :param nspace: the namespace to use, or None/"" for the default namespace
+        :type nspace: str
+
+        :raises: :class:`TypeError`
+        """
+        self.require_ioctx_open()
+        if nspace is None:
+            nspace = ""
+        cnspace = cstr(nspace, 'nspace')
+        cdef char *_nspace = cnspace
+        with nogil:
+            rados_ioctx_set_namespace(self.io, _nspace)
+        self.nspace = nspace
+
+    def get_namespace(self):
+        """
+        Get the namespace of context
+
+        :returns: namespace
+        """
+        return self.nspace
+
+    def close(self):
+        """
+        Close a rados.Ioctx object.
+
+        This just tells librados that you no longer need to use the io context.
+        It may not be freed immediately if there are pending asynchronous
+        requests on it, but you should not use an io context again after
+        calling this function on it.
+        """
+        if self.state == "open":
+            self.require_ioctx_open()
+            with nogil:
+                rados_ioctx_destroy(self.io)
+            self.state = "closed"
+
+
+    @requires(('key', str_type), ('data', bytes))
+    def write(self, key, data, offset=0):
+        """
+        Write data to an object synchronously
+
+        :param key: name of the object
+        :type key: str
+        :param data: data to write
+        :type data: bytes
+        :param offset: byte offset in the object to begin writing at
+        :type offset: int
+
+        :raises: :class:`TypeError`
+        :raises: :class:`LogicError`
+        :returns: int - 0 on success
+        """
+        self.require_ioctx_open()
+
+        key = cstr(key, 'key')
+        cdef:
+            char *_key = key
+            char *_data = data
+            size_t length = len(data)
+            uint64_t _offset = offset
+
+        with nogil:
+            ret = rados_write(self.io, _key, _data, length, _offset)
+        if ret == 0:
+            return ret
+        elif ret < 0:
+            raise make_ex(ret, "Ioctx.write(%s): failed to write %s"
+                          % (self.name, key))
+        else:
+            raise LogicError("Ioctx.write(%s): rados_write \
+returned %d, but should return zero on success." % (self.name, ret))
+
+    @requires(('key', str_type), ('data', bytes))
+    def write_full(self, key, data):
+        """
+        Write an entire object synchronously.
+
+        The object is filled with the provided data. If the object exists,
+        it is atomically truncated and then written.
+
+        :param key: name of the object
+        :type key: str
+        :param data: data to write
+        :type data: bytes
+
+        :raises: :class:`TypeError`
+        :raises: :class:`Error`
+        :returns: int - 0 on success
+        """
+        self.require_ioctx_open()
+        key = cstr(key, 'key')
+        cdef:
+            char *_key = key
+            char *_data = data
+            size_t length = len(data)
+
+        with nogil:
+            ret = rados_write_full(self.io, _key, _data, length)
+        if ret == 0:
+            return ret
+        elif ret < 0:
+            raise make_ex(ret, "Ioctx.write_full(%s): failed to write %s"
+                          % (self.name, key))
+        else:
+            raise LogicError("Ioctx.write_full(%s): rados_write_full \
+returned %d, but should return zero on success." % (self.name, ret))
+
+    @requires(('key', str_type), ('data', bytes))
+    def append(self, key, data):
+        """
+        Append data to an object synchronously
+
+        :param key: name of the object
+        :type key: str
+        :param data: data to write
+        :type data: bytes
+
+        :raises: :class:`TypeError`
+        :raises: :class:`LogicError`
+        :returns: int - 0 on success
+        """
+        self.require_ioctx_open()
+        key = cstr(key, 'key')
+        cdef:
+            char *_key = key
+            char *_data = data
+            size_t length = len(data)
+
+        with nogil:
+            ret = rados_append(self.io, _key, _data, length)
+        if ret == 0:
+            return ret
+        elif ret < 0:
+            raise make_ex(ret, "Ioctx.append(%s): failed to append %s"
+                          % (self.name, key))
+        else:
+            raise LogicError("Ioctx.append(%s): rados_append \
+returned %d, but should return zero on success." % (self.name, ret))
+
+    @requires(('key', str_type))
+    def read(self, key, length=8192, offset=0):
+        """
+        Read data from an object synchronously
+
+        :param key: name of the object
+        :type key: str
+        :param length: the number of bytes to read (default=8192)
+        :type length: int
+        :param offset: byte offset in the object to begin reading at
+        :type offset: int
+
+        :raises: :class:`TypeError`
+        :raises: :class:`Error`
+        :returns: str - data read from object
+        """
+        self.require_ioctx_open()
+        key = cstr(key, 'key')
+        cdef:
+            char *_key = key
+            char *ret_buf
+            uint64_t _offset = offset
+            size_t _length = length
+            PyObject* ret_s = NULL
+
+        ret_s = PyBytes_FromStringAndSize(NULL, length)
+        try:
+            ret_buf = PyBytes_AsString(ret_s)
+            with nogil:
+                ret = rados_read(self.io, _key, ret_buf, _length, _offset)
+            if ret < 0:
+                raise make_ex(ret, "Ioctx.read(%s): failed to read %s" % (self.name, key))
+
+            if ret != length:
+                _PyBytes_Resize(&ret_s, ret)
+
+            return <object>ret_s
+        finally:
+            # We DECREF unconditionally: the cast to object above will have
+            # INCREFed if necessary. This also takes care of exceptions,
+            # including if _PyString_Resize fails (that will free the string
+            # itself and set ret_s to NULL, hence XDECREF).
+            ref.Py_XDECREF(ret_s)
+
+    @requires(('key', str_type), ('cls', str_type), ('method', str_type), ('data', bytes))
+    def execute(self, key, cls, method, data, length=8192):
+        """
+        Execute an OSD class method on an object.
+
+        :param key: name of the object
+        :type key: str
+        :param cls: name of the object class
+        :type cls: str
+        :param method: name of the method
+        :type method: str
+        :param data: input data
+        :type data: bytes
+        :param length: size of output buffer in bytes (default=8291)
+        :type length: int
+
+        :raises: :class:`TypeError`
+        :raises: :class:`Error`
+        :returns: (ret, method output)
+        """
+        self.require_ioctx_open()
+
+        key = cstr(key, 'key')
+        cls = cstr(cls, 'cls')
+        method = cstr(method, 'method')
+        cdef:
+            char *_key = key
+            char *_cls = cls
+            char *_method = method
+            char *_data = data
+            size_t _data_len = len(data)
+
+            char *ref_buf
+            size_t _length = length
+            PyObject* ret_s = NULL
+
+        ret_s = PyBytes_FromStringAndSize(NULL, length)
+        try:
+            ret_buf = PyBytes_AsString(ret_s)
+            with nogil:
+                ret = rados_exec(self.io, _key, _cls, _method, _data,
+                                 _data_len, ret_buf, _length)
+            if ret < 0:
+                raise make_ex(ret, "Ioctx.read(%s): failed to read %s" % (self.name, key))
+
+            if ret != length:
+                _PyBytes_Resize(&ret_s, ret)
+
+            return ret, <object>ret_s
+        finally:
+            # We DECREF unconditionally: the cast to object above will have
+            # INCREFed if necessary. This also takes care of exceptions,
+            # including if _PyString_Resize fails (that will free the string
+            # itself and set ret_s to NULL, hence XDECREF).
+            ref.Py_XDECREF(ret_s)
+
+    def get_stats(self):
+        """
+        Get pool usage statistics
+
+        :returns: dict - contains the following keys:
+
+            - ``num_bytes`` (int) - size of pool in bytes
+
+            - ``num_kb`` (int) - size of pool in kbytes
+
+            - ``num_objects`` (int) - number of objects in the pool
+
+            - ``num_object_clones`` (int) - number of object clones
+
+            - ``num_object_copies`` (int) - number of object copies
+
+            - ``num_objects_missing_on_primary`` (int) - number of objets
+                missing on primary
+
+            - ``num_objects_unfound`` (int) - number of unfound objects
+
+            - ``num_objects_degraded`` (int) - number of degraded objects
+
+            - ``num_rd`` (int) - bytes read
+
+            - ``num_rd_kb`` (int) - kbytes read
+
+            - ``num_wr`` (int) - bytes written
+
+            - ``num_wr_kb`` (int) - kbytes written
+        """
+        self.require_ioctx_open()
+        cdef rados_pool_stat_t stats
+        with nogil:
+            ret = rados_ioctx_pool_stat(self.io, &stats)
+        if ret < 0:
+            raise make_ex(ret, "Ioctx.get_stats(%s): get_stats failed" % self.name)
+        return {'num_bytes': stats.num_bytes,
+                'num_kb': stats.num_kb,
+                'num_objects': stats.num_objects,
+                'num_object_clones': stats.num_object_clones,
+                'num_object_copies': stats.num_object_copies,
+                "num_objects_missing_on_primary": stats.num_objects_missing_on_primary,
+                "num_objects_unfound": stats.num_objects_unfound,
+                "num_objects_degraded": stats.num_objects_degraded,
+                "num_rd": stats.num_rd,
+                "num_rd_kb": stats.num_rd_kb,
+                "num_wr": stats.num_wr,
+                "num_wr_kb": stats.num_wr_kb}
+
+    @requires(('key', str_type))
+    def remove_object(self, key):
+        """
+        Delete an object
+
+        This does not delete any snapshots of the object.
+
+        :param key: the name of the object to delete
+        :type key: str
+
+        :raises: :class:`TypeError`
+        :raises: :class:`Error`
+        :returns: bool - True on success
+        """
+        self.require_ioctx_open()
+        key = cstr(key, 'key')
+        cdef:
+            char *_key = key
+
+        with nogil:
+            ret = rados_remove(self.io, _key)
+        if ret < 0:
+            raise make_ex(ret, "Failed to remove '%s'" % key)
+        return True
+
+    @requires(('key', str_type))
+    def trunc(self, key, size):
+        """
+        Resize an object
+
+        If this enlarges the object, the new area is logically filled with
+        zeroes. If this shrinks the object, the excess data is removed.
+
+        :param key: the name of the object to resize
+        :type key: str
+        :param size: the new size of the object in bytes
+        :type size: int
+
+        :raises: :class:`TypeError`
+        :raises: :class:`Error`
+        :returns: int - 0 on success, otherwise raises error
+        """
+
+        self.require_ioctx_open()
+        key = cstr(key, 'key')
+        cdef:
+            char *_key = key
+            uint64_t _size = size
+
+        with nogil:
+            ret = rados_trunc(self.io, _key, _size)
+        if ret < 0:
+            raise make_ex(ret, "Ioctx.trunc(%s): failed to truncate %s" % (self.name, key))
+        return ret
+
+    @requires(('key', str_type))
+    def stat(self, key):
+        """
+        Get object stats (size/mtime)
+
+        :param key: the name of the object to get stats from
+        :type key: str
+
+        :raises: :class:`TypeError`
+        :raises: :class:`Error`
+        :returns: (size,timestamp)
+        """
+        self.require_ioctx_open()
+
+        key = cstr(key, 'key')
+        cdef:
+            char *_key = key
+            uint64_t psize
+            time_t pmtime
+
+        with nogil:
+            ret = rados_stat(self.io, _key, &psize, &pmtime)
+        if ret < 0:
+            raise make_ex(ret, "Failed to stat %r" % key)
+        return psize, time.localtime(pmtime)
+
+    @requires(('key', str_type), ('xattr_name', str_type))
+    def get_xattr(self, key, xattr_name):
+        """
+        Get the value of an extended attribute on an object.
+
+        :param key: the name of the object to get xattr from
+        :type key: str
+        :param xattr_name: which extended attribute to read
+        :type xattr_name: str
+
+        :raises: :class:`TypeError`
+        :raises: :class:`Error`
+        :returns: str - value of the xattr
+        """
+        self.require_ioctx_open()
+
+        key = cstr(key, 'key')
+        xattr_name = cstr(xattr_name, 'xattr_name')
+        cdef:
+            char *_key = key
+            char *_xattr_name = xattr_name
+            size_t ret_length = 4096
+            char *ret_buf = NULL
+
+        try:
+            while ret_length < 4096 * 1024 * 1024:
+                ret_buf = <char *>realloc_chk(ret_buf, ret_length)
+                with nogil:
+                    ret = rados_getxattr(self.io, _key, _xattr_name, ret_buf, ret_length)
+                if (ret == -errno.ERANGE):
+                    ret_length *= 2
+                elif ret < 0:
+                    raise make_ex(ret, "Failed to get xattr %r" % xattr_name)
+                else:
+                    break
+            return ret_buf[:ret]
+        finally:
+            free(ret_buf)
+
+    @requires(('oid', str_type))
+    def get_xattrs(self, oid):
+        """
+        Start iterating over xattrs on an object.
+
+        :param oid: the name of the object to get xattrs from
+        :type oid: str
+
+        :raises: :class:`TypeError`
+        :raises: :class:`Error`
+        :returns: XattrIterator
+        """
+        self.require_ioctx_open()
+        return XattrIterator(self, oid)
+
+    @requires(('key', str_type), ('xattr_name', str_type), ('xattr_value', bytes))
+    def set_xattr(self, key, xattr_name, xattr_value):
+        """
+        Set an extended attribute on an object.
+
+        :param key: the name of the object to set xattr to
+        :type key: str
+        :param xattr_name: which extended attribute to set
+        :type xattr_name: str
+        :param xattr_value: the value of the  extended attribute
+        :type xattr_value: bytes
+
+        :raises: :class:`TypeError`
+        :raises: :class:`Error`
+        :returns: bool - True on success, otherwise raise an error
+        """
+        self.require_ioctx_open()
+
+        key = cstr(key, 'key')
+        xattr_name = cstr(xattr_name, 'xattr_name')
+        cdef:
+            char *_key = key
+            char *_xattr_name = xattr_name
+            char *_xattr_value = xattr_value
+            size_t _xattr_value_len = len(xattr_value)
+
+        with nogil:
+            ret = rados_setxattr(self.io, _key, _xattr_name,
+                                 _xattr_value, _xattr_value_len)
+        if ret < 0:
+            raise make_ex(ret, "Failed to set xattr %r" % xattr_name)
+        return True
+
+    @requires(('key', str_type), ('xattr_name', str_type))
+    def rm_xattr(self, key, xattr_name):
+        """
+        Removes an extended attribute on from an object.
+
+        :param key: the name of the object to remove xattr from
+        :type key: str
+        :param xattr_name: which extended attribute to remove
+        :type xattr_name: str
+
+        :raises: :class:`TypeError`
+        :raises: :class:`Error`
+        :returns: bool - True on success, otherwise raise an error
+        """
+        self.require_ioctx_open()
+
+        key = cstr(key, 'key')
+        xattr_name = cstr(xattr_name, 'xattr_name')
+        cdef:
+            char *_key = key
+            char *_xattr_name = xattr_name
+
+        with nogil:
+            ret = rados_rmxattr(self.io, _key, _xattr_name)
+        if ret < 0:
+            raise make_ex(ret, "Failed to delete key %r xattr %r" %
+                          (key, xattr_name))
+        return True
+
+    def list_objects(self):
+        """
+        Get ObjectIterator on rados.Ioctx object.
+
+        :returns: ObjectIterator
+        """
+        self.require_ioctx_open()
+        return ObjectIterator(self)
+
+    def list_snaps(self):
+        """
+        Get SnapIterator on rados.Ioctx object.
+
+        :returns: SnapIterator
+        """
+        self.require_ioctx_open()
+        return SnapIterator(self)
+
+    @requires(('snap_name', str_type))
+    def create_snap(self, snap_name):
+        """
+        Create a pool-wide snapshot
+
+        :param snap_name: the name of the snapshot
+        :type snap_name: str
+
+        :raises: :class:`TypeError`
+        :raises: :class:`Error`
+        """
+        self.require_ioctx_open()
+        snap_name = cstr(snap_name, 'snap_name')
+        cdef char *_snap_name = snap_name
+
+        with nogil:
+            ret = rados_ioctx_snap_create(self.io, _snap_name)
+        if (ret != 0):
+            raise make_ex(ret, "Failed to create snap %s" % snap_name)
+
+    @requires(('snap_name', str_type))
+    def remove_snap(self, snap_name):
+        """
+        Removes a pool-wide snapshot
+
+        :param snap_name: the name of the snapshot
+        :type snap_name: str
+
+        :raises: :class:`TypeError`
+        :raises: :class:`Error`
+        """
+        self.require_ioctx_open()
+        snap_name = cstr(snap_name, 'snap_name')
+        cdef char *_snap_name = snap_name
+
+        with nogil:
+            ret = rados_ioctx_snap_remove(self.io, _snap_name)
+        if (ret != 0):
+            raise make_ex(ret, "Failed to remove snap %s" % snap_name)
+
+    @requires(('snap_name', str_type))
+    def lookup_snap(self, snap_name):
+        """
+        Get the id of a pool snapshot
+
+        :param snap_name: the name of the snapshot to lookop
+        :type snap_name: str
+
+        :raises: :class:`TypeError`
+        :raises: :class:`Error`
+        :returns: Snap - on success
+        """
+        self.require_ioctx_open()
+        csnap_name = cstr(snap_name, 'snap_name')
+        cdef:
+            char *_snap_name = csnap_name
+            rados_snap_t snap_id
+
+        with nogil:
+            ret = rados_ioctx_snap_lookup(self.io, _snap_name, &snap_id)
+        if (ret != 0):
+            raise make_ex(ret, "Failed to lookup snap %s" % snap_name)
+        return Snap(self, snap_name, int(snap_id))
+
+    @requires(('oid', str_type), ('snap_name', str_type))
+    def snap_rollback(self, oid, snap_name):
+        """
+        Rollback an object to a snapshot
+
+        :param oid: the name of the object
+        :type oid: str
+        :param snap_name: the name of the snapshot
+        :type snap_name: str
+
+        :raises: :class:`TypeError`
+        :raises: :class:`Error`
+        """
+        self.require_ioctx_open()
+        oid = cstr(oid, 'oid')
+        snap_name = cstr(snap_name, 'snap_name')
+        cdef:
+            char *_snap_name = snap_name
+            char *_oid = oid
+
+        with nogil:
+            ret = rados_ioctx_snap_rollback(self.io, _oid, _snap_name)
+        if (ret != 0):
+            raise make_ex(ret, "Failed to rollback %s" % oid)
+
+    def get_last_version(self):
+        """
+        Return the version of the last object read or written to.
+
+        This exposes the internal version number of the last object read or
+        written via this io context
+
+        :returns: version of the last object used
+        """
+        self.require_ioctx_open()
+        with nogil:
+            ret = rados_get_last_version(self.io)
+        return int(ret)
+
+    def create_write_op(self):
+        """
+        create write operation object.
+        need call release_write_op after use
+        """
+        return WriteOp().create()
+
+    def create_read_op(self):
+        """
+        create read operation object.
+        need call release_read_op after use
+        """
+        return ReadOp().create()
+
+    def release_write_op(self, write_op):
+        """
+        release memory alloc by create_write_op
+        """
+        write_op.release()
+
+    def release_read_op(self, read_op):
+        """
+        release memory alloc by create_read_op
+        :para read_op: read_op object
+        :type: int
+        """
+        read_op.release()
+
+    @requires(('write_op', WriteOp), ('keys', tuple), ('values', tuple))
+    def set_omap(self, write_op, keys, values):
+        """
+        set keys values to write_op
+        :para write_op: write_operation object
+        :type write_op: WriteOp
+        :para keys: a tuple of keys
+        :type keys: tuple
+        :para values: a tuple of values
+        :type values: tuple
+        """
+
+        if len(keys) != len(values):
+            raise Error("Rados(): keys and values must have the same number of items")
+
+        keys = cstr_list(keys, 'keys')
+        cdef:
+            WriteOp _write_op = write_op
+            size_t key_num = len(keys)
+            char **_keys = to_bytes_array(keys)
+            char **_values = to_bytes_array(values)
+            size_t *_lens = to_csize_t_array([len(v) for v in values])
+
+        try:
+            with nogil:
+                rados_write_op_omap_set(_write_op.write_op,
+                                        <const char**>_keys,
+                                        <const char**>_values,
+                                        <const size_t*>_lens, key_num)
+        finally:
+            free(_keys)
+            free(_values)
+            free(_lens)
+
+    @requires(('write_op', WriteOp), ('oid', str_type), ('mtime', opt(int)), ('flags', opt(int)))
+    def operate_write_op(self, write_op, oid, mtime=0, flags=LIBRADOS_OPERATION_NOFLAG):
+        """
+        excute the real write operation
+        :para write_op: write operation object
+        :type write_op: WriteOp
+        :para oid: object name
+        :type oid: str
+        :para mtime: the time to set the mtime to, 0 for the current time
+        :type mtime: int
+        :para flags: flags to apply to the entire operation
+        :type flags: int
+        """
+
+        oid = cstr(oid, 'oid')
+        cdef:
+            WriteOp _write_op = write_op
+            char *_oid = oid
+            time_t _mtime = mtime
+            int _flags = flags
+
+        with nogil:
+            rados_write_op_operate(_write_op.write_op, self.io, _oid, &_mtime, _flags)
+
+    @requires(('read_op', ReadOp), ('oid', str_type), ('flag', opt(int)))
+    def operate_read_op(self, read_op, oid, flag=LIBRADOS_OPERATION_NOFLAG):
+        """
+        excute the real read operation
+        :para read_op: read operation object
+        :type read_op: ReadOp
+        :para oid: object name
+        :type oid: str
+        :para flag: flags to apply to the entire operation
+        :type flag: int
+        """
+        oid = cstr(oid, 'oid')
+        cdef:
+            ReadOp _read_op = read_op
+            char *_oid = oid
+            int _flag = flag
+
+        with nogil:
+            rados_read_op_operate(_read_op.read_op, self.io, _oid, _flag)
+
+    @requires(('read_op', ReadOp), ('start_after', str_type), ('filter_prefix', str_type), ('max_return', int))
+    def get_omap_vals(self, read_op, start_after, filter_prefix, max_return):
+        """
+        get the omap values
+        :para read_op: read operation object
+        :type read_op: ReadOp
+        :para start_after: list keys starting after start_after
+        :type start_after: str
+        :para filter_prefix: list only keys beginning with filter_prefix
+        :type filter_prefix: str
+        :para max_return: list no more than max_return key/value pairs
+        :type max_return: int
+        :returns: an iterator over the the requested omap values, return value from this action
+        """
+
+        start_after = cstr(start_after, 'start_after') if start_after else None
+        filter_prefix = cstr(filter_prefix, 'filter_prefix') if filter_prefix else None
+        cdef:
+            char *_start_after = opt_str(start_after)
+            char *_filter_prefix = opt_str(filter_prefix)
+            ReadOp _read_op = read_op
+            rados_omap_iter_t iter_addr = NULL
+            int _max_return = max_return
+            int prval = 0
+
+        with nogil:
+            rados_read_op_omap_get_vals(_read_op.read_op, _start_after, _filter_prefix,
+                                        _max_return, &iter_addr,  &prval)
+        it = OmapIterator(self)
+        it.ctx = iter_addr
+        return it, int(prval)
+
+    @requires(('read_op', ReadOp), ('start_after', str_type), ('max_return', int))
+    def get_omap_keys(self, read_op, start_after, max_return):
+        """
+        get the omap keys
+        :para read_op: read operation object
+        :type read_op: ReadOp
+        :para start_after: list keys starting after start_after
+        :type start_after: str
+        :para max_return: list no more than max_return key/value pairs
+        :type max_return: int
+        :returns: an iterator over the the requested omap values, return value from this action
+        """
+        start_after = cstr(start_after, 'start_after') if start_after else None
+        cdef:
+            char *_start_after = opt_str(start_after)
+            ReadOp _read_op = read_op
+            rados_omap_iter_t iter_addr = NULL
+            int _max_return = max_return
+            int prval
+
+        with nogil:
+            rados_read_op_omap_get_keys(_read_op.read_op, _start_after,
+                                        _max_return, &iter_addr,  &prval)
+        it = OmapIterator(self)
+        it.ctx = iter_addr
+        return it, int(prval)
+
+    @requires(('read_op', ReadOp), ('keys', tuple))
+    def get_omap_vals_by_keys(self, read_op, keys):
+        """
+        get the omap values by keys
+        :para read_op: read operation object
+        :type read_op: ReadOp
+        :para keys: input key tuple
+        :type keys: tuple
+        :returns: an iterator over the the requested omap values, return value from this action
+        """
+        keys = cstr_list(keys, 'keys')
+        cdef:
+            ReadOp _read_op = read_op
+            rados_omap_iter_t iter_addr
+            char **_keys = to_bytes_array(keys)
+            size_t key_num = len(keys)
+            int prval
+
+        try:
+            with nogil:
+                rados_read_op_omap_get_vals_by_keys(_read_op.read_op,
+                                                    <const char**>_keys,
+                                                    key_num, &iter_addr,  &prval)
+            it = OmapIterator(self)
+            it.ctx = iter_addr
+            return it, int(prval)
+        finally:
+            free(_keys)
+
+    @requires(('write_op', WriteOp), ('keys', tuple))
+    def remove_omap_keys(self, write_op, keys):
+        """
+        remove omap keys specifiled
+        :para write_op: write operation object
+        :type write_op: WriteOp
+        :para keys: input key tuple
+        :type keys: tuple
+        """
+
+        keys = cstr_list(keys, 'keys')
+        cdef:
+            WriteOp _write_op = write_op
+            size_t key_num = len(keys)
+            char **_keys = to_bytes_array(keys)
+
+        try:
+            with nogil:
+                rados_write_op_omap_rm_keys(_write_op.write_op, <const char**>_keys, key_num)
+        finally:
+            free(_keys)
+
+    @requires(('write_op', WriteOp))
+    def clear_omap(self, write_op):
+        """
+        Remove all key/value pairs from an object
+        :para write_op: write operation object
+        :type write_op: WriteOp
+        """
+
+        cdef:
+            WriteOp _write_op = write_op
+
+        with nogil:
+            rados_write_op_omap_clear(_write_op.write_op)
+
+    @requires(('key', str_type), ('name', str_type), ('cookie', str_type), ('desc', str_type),
+              ('duration', opt(int)), ('flags', int))
+    def lock_exclusive(self, key, name, cookie, desc="", duration=None, flags=0):
+
+        """
+        Take an exclusive lock on an object
+
+        :param key: name of the object
+        :type key: str
+        :param name: name of the lock
+        :type name: str
+        :param cookie: cookie of the lock
+        :type cookie: str
+        :param desc: description of the lock
+        :type desc: str
+        :param duration: duration of the lock in seconds
+        :type duration: int
+        :param flags: flags
+        :type flags: int
+
+        :raises: :class:`TypeError`
+        :raises: :class:`Error`
+        """
+        self.require_ioctx_open()
+
+        key = cstr(key, 'key')
+        name = cstr(name, 'name')
+        cookie = cstr(cookie, 'cookie')
+        desc = cstr(desc, 'desc')
+
+        cdef:
+            char* _key = key
+            char* _name = name
+            char* _cookie = cookie
+            char* _desc = desc
+            uint8_t _flags = flags
+            timeval _duration
+
+        if duration is None:
+            with nogil:
+                ret = rados_lock_exclusive(self.io, _key, _name, _cookie, _desc,
+                                           NULL, _flags)
+        else:
+            _duration.tv_sec = duration
+            with nogil:
+                ret = rados_lock_exclusive(self.io, _key, _name, _cookie, _desc,
+                                           &_duration, _flags)
+
+        if ret < 0:
+            raise make_ex(ret, "Ioctx.rados_lock_exclusive(%s): failed to set lock %s on %s" % (self.name, name, key))
+
+    @requires(('key', str_type), ('name', str_type), ('cookie', str_type), ('tag', str_type),
+              ('desc', str_type), ('duration', opt(int)), ('flags', int))
+    def lock_shared(self, key, name, cookie, tag, desc="", duration=None, flags=0):
+
+        """
+        Take a shared lock on an object
+
+        :param key: name of the object
+        :type key: str
+        :param name: name of the lock
+        :type name: str
+        :param cookie: cookie of the lock
+        :type cookie: str
+        :param tag: tag of the lock
+        :type tag: str
+        :param desc: description of the lock
+        :type desc: str
+        :param duration: duration of the lock in seconds
+        :type duration: int
+        :param flags: flags
+        :type flags: int
+
+        :raises: :class:`TypeError`
+        :raises: :class:`Error`
+        """
+        self.require_ioctx_open()
+
+        key = cstr(key, 'key')
+        tag = cstr(tag, 'tag')
+        name = cstr(name, 'name')
+        cookie = cstr(cookie, 'cookie')
+        desc = cstr(desc, 'desc')
+
+        cdef:
+            char* _key = key
+            char* _tag = tag
+            char* _name = name
+            char* _cookie = cookie
+            char* _desc = desc
+            uint8_t _flags = flags
+            timeval _duration
+
+        if duration is None:
+            with nogil:
+                ret = rados_lock_shared(self.io, _key, _name, _cookie, _tag, _desc,
+                                        NULL, _flags)
+        else:
+            _duration.tv_sec = duration
+            with nogil:
+                ret = rados_lock_shared(self.io, _key, _name, _cookie, _tag, _desc,
+                                        &_duration, _flags)
+        if ret < 0:
+            raise make_ex(ret, "Ioctx.rados_lock_exclusive(%s): failed to set lock %s on %s" % (self.name, name, key))
+
+    @requires(('key', str_type), ('name', str_type), ('cookie', str_type))
+    def unlock(self, key, name, cookie):
+
+        """
+        Release a shared or exclusive lock on an object
+
+        :param key: name of the object
+        :type key: str
+        :param name: name of the lock
+        :type name: str
+        :param cookie: cookie of the lock
+        :type cookie: str
+
+        :raises: :class:`TypeError`
+        :raises: :class:`Error`
+        """
+        self.require_ioctx_open()
+
+        key = cstr(key, 'key')
+        name = cstr(name, 'name')
+        cookie = cstr(cookie, 'cookie')
+
+        cdef:
+            char* _key = key
+            char* _name = name
+            char* _cookie = cookie
+
+        with nogil:
+            ret = rados_unlock(self.io, _key, _name, _cookie)
+        if ret < 0:
+            raise make_ex(ret, "Ioctx.rados_lock_exclusive(%s): failed to set lock %s on %s" % (self.name, name, key))
+
+
+def set_object_locator(func):
+    def retfunc(self, *args, **kwargs):
+        if self.locator_key is not None:
+            old_locator = self.ioctx.get_locator_key()
+            self.ioctx.set_locator_key(self.locator_key)
+            retval = func(self, *args, **kwargs)
+            self.ioctx.set_locator_key(old_locator)
+            return retval
+        else:
+            return func(self, *args, **kwargs)
+    return retfunc
+
+
+def set_object_namespace(func):
+    def retfunc(self, *args, **kwargs):
+        if self.nspace is None:
+            raise LogicError("Namespace not set properly in context")
+        old_nspace = self.ioctx.get_namespace()
+        self.ioctx.set_namespace(self.nspace)
+        retval = func(self, *args, **kwargs)
+        self.ioctx.set_namespace(old_nspace)
+        return retval
+    return retfunc
+
+
+class Object(object):
+    """Rados object wrapper, makes the object look like a file"""
+    def __init__(self, ioctx, key, locator_key=None, nspace=None):
+        self.key = key
+        self.ioctx = ioctx
+        self.offset = 0
+        self.state = "exists"
+        self.locator_key = locator_key
+        self.nspace = "" if nspace is None else nspace
+
+    def __str__(self):
+        return "rados.Object(ioctx=%s,key=%s,nspace=%s,locator=%s)" % \
+            (str(self.ioctx), self.key, "--default--"
+             if self.nspace is "" else self.nspace, self.locator_key)
+
+    def require_object_exists(self):
+        if self.state != "exists":
+            raise ObjectStateError("The object is %s" % self.state)
+
+    @set_object_locator
+    @set_object_namespace
+    def read(self, length=1024 * 1024):
+        self.require_object_exists()
+        ret = self.ioctx.read(self.key, length, self.offset)
+        self.offset += len(ret)
+        return ret
+
+    @set_object_locator
+    @set_object_namespace
+    def write(self, string_to_write):
+        self.require_object_exists()
+        ret = self.ioctx.write(self.key, string_to_write, self.offset)
+        if ret == 0:
+            self.offset += len(string_to_write)
+        return ret
+
+    @set_object_locator
+    @set_object_namespace
+    def remove(self):
+        self.require_object_exists()
+        self.ioctx.remove_object(self.key)
+        self.state = "removed"
+
+    @set_object_locator
+    @set_object_namespace
+    def stat(self):
+        self.require_object_exists()
+        return self.ioctx.stat(self.key)
+
+    def seek(self, position):
+        self.require_object_exists()
+        self.offset = position
+
+    @set_object_locator
+    @set_object_namespace
+    def get_xattr(self, xattr_name):
+        self.require_object_exists()
+        return self.ioctx.get_xattr(self.key, xattr_name)
+
+    @set_object_locator
+    @set_object_namespace
+    def get_xattrs(self):
+        self.require_object_exists()
+        return self.ioctx.get_xattrs(self.key)
+
+    @set_object_locator
+    @set_object_namespace
+    def set_xattr(self, xattr_name, xattr_value):
+        self.require_object_exists()
+        return self.ioctx.set_xattr(self.key, xattr_name, xattr_value)
+
+    @set_object_locator
+    @set_object_namespace
+    def rm_xattr(self, xattr_name):
+        self.require_object_exists()
+        return self.ioctx.rm_xattr(self.key, xattr_name)
+
+MONITOR_LEVELS = [
+    "debug",
+    "info",
+    "warn", "warning",
+    "err", "error",
+    "sec",
+    ]
+
+
+class MonitorLog(object):
+    # NOTE(sileht): Keep this class for backward compat
+    # method moved to Rados.monitor_log()
+    """
+    For watching cluster log messages.  Instantiate an object and keep
+    it around while callback is periodically called.  Construct with
+    'level' to monitor 'level' messages (one of MONITOR_LEVELS).
+    arg will be passed to the callback.
+
+    callback will be called with:
+        arg (given to __init__)
+        line (the full line, including timestamp, who, level, msg)
+        who (which entity issued the log message)
+        timestamp_sec (sec of a struct timespec)
+        timestamp_nsec (sec of a struct timespec)
+        seq (sequence number)
+        level (string representing the level of the log message)
+        msg (the message itself)
+    callback's return value is ignored
+    """
+    def __init__(self, cluster, level, callback, arg):
+        self.level = level
+        self.callback = callback
+        self.arg = arg
+        self.cluster = cluster
+        self.cluster.monitor_log(level, callback, arg)
+
diff --git a/src/pybind/setup.py b/src/pybind/rados/setup.py
similarity index 87%
copy from src/pybind/setup.py
copy to src/pybind/rados/setup.py
index 1eda454..6a7b9bd 100755
--- a/src/pybind/setup.py
+++ b/src/pybind/rados/setup.py
@@ -33,16 +33,16 @@ if (len(sys.argv) >= 2 and
         return x
 
 setup(
-    name = 'rbd',
+    name = 'rados',
     version = get_version(),
-    description = "Python libraries for the Ceph librbd library",
+    description = "Python libraries for the Ceph librados library",
     long_description = (
         "This package contains Python libraries for interacting with Ceph's "
-        "RBD block device library."),
+        "rados library."),
     ext_modules = cythonize([
-        Extension("rbd",
-            ["rbd.pyx"],
-            libraries=["rbd"]
+        Extension("rados",
+            ["rados.pyx"],
+            libraries=["rados"]
             )
     ], build_dir=os.environ.get("CYTHON_BUILD_DIR", None)),
     cmdclass={
diff --git a/src/pybind/rbd/Makefile.am b/src/pybind/rbd/Makefile.am
new file mode 100644
index 0000000..affd2de
--- /dev/null
+++ b/src/pybind/rbd/Makefile.am
@@ -0,0 +1,34 @@
+EXTRA_DIST += $(srcdir)/pybind/rbd/setup.py $(srcdir)/pybind/rbd/rbd.pyx
+
+rbd-pybind-all: librbd.la ${srcdir}/ceph_ver.h
+	cd $(srcdir)/pybind/rbd; $(PY_DISTUTILS) build \
+	--build-base $(shell readlink -f $(builddir))/build \
+	--verbose
+
+rbd-pybind-clean: ${srcdir}/ceph_ver.h
+	cd $(srcdir)/pybind/rbd; $(PY_DISTUTILS) clean \
+	--build-base $(shell readlink -f $(builddir))/build \
+	--verbose
+
+rbd-pybind-install-exec: ${srcdir}/ceph_ver.h
+	if test "$(DESTDIR)" ; then \
+		if lsb_release -si | grep --quiet 'Ubuntu\|Debian\|Devuan' ; then \
+			options=--install-layout=deb ; \
+		else \
+			options=--prefix=/usr ; \
+		fi ; \
+		root="--root=$(DESTDIR)" ; \
+	else \
+		options=--prefix=$(prefix) ; \
+	fi ; \
+	cd $(srcdir)/pybind/rbd; $(PY_DISTUTILS) build \
+	--build-base $(shell readlink -f $(builddir))/build \
+	install \
+	$$options $$root \
+	--single-version-externally-managed \
+	--record /dev/null \
+	--verbose
+
+LOCAL_ALL += rbd-pybind-all
+LOCAL_CLEAN += rbd-pybind-clean
+LOCAL_INSTALLEXEC += rbd-pybind-install-exec
diff --git a/src/pybind/rbd.pyx b/src/pybind/rbd/rbd.pyx
similarity index 99%
rename from src/pybind/rbd.pyx
rename to src/pybind/rbd/rbd.pyx
index a03d975..23a9895 100644
--- a/src/pybind/rbd.pyx
+++ b/src/pybind/rbd/rbd.pyx
@@ -21,6 +21,9 @@ from libc.stdlib cimport realloc, free
 
 from collections import Iterable
 
+cimport rados
+
+
 cdef extern from "Python.h":
     # These are in cpython/string.pxd, but use "object" types instead of
     # PyObject*, which invokes assumptions in cpython that we need to
@@ -296,8 +299,9 @@ cdef make_ex(ret, msg):
     else:
         return Error(msg + (": error code %d" % ret))
 
-cdef rados_ioctx_t convert_ioctx(ioctx) except? NULL:
-    return <rados_ioctx_t><uintptr_t>ioctx.io.value
+
+cdef rados_ioctx_t convert_ioctx(rados.Ioctx ioctx) except? NULL:
+    return <rados_ioctx_t>ioctx.io
 
 cdef int no_op_progress_callback(uint64_t offset, uint64_t total, void* ptr):
     return 0
@@ -650,14 +654,14 @@ cdef class Image(object):
         After this is called, this object should not be used.
         """
         if not self.closed:
+            self.closed = True
             with nogil:
                 ret = rbd_close(self.image)
             if ret < 0:
                 raise make_ex(ret, 'error while closing image %s' % (
                               self.name,))
-            self.closed = True
 
-    def __del__(self):
+    def __dealloc__(self):
         self.close()
 
     def __repr__(self):
@@ -1436,7 +1440,7 @@ cdef class SnapIterator(object):
                 'name' : decode_cstr(self.snaps[i].name),
                 }
 
-    def __del__(self):
+    def __dealloc__(self):
         if self.snaps:
             rbd_snap_list_end(self.snaps)
             free(self.snaps)
diff --git a/src/pybind/setup.py b/src/pybind/rbd/setup.py
similarity index 91%
rename from src/pybind/setup.py
rename to src/pybind/rbd/setup.py
index 1eda454..ec2f3a2 100755
--- a/src/pybind/setup.py
+++ b/src/pybind/rbd/setup.py
@@ -44,7 +44,9 @@ setup(
             ["rbd.pyx"],
             libraries=["rbd"]
             )
-    ], build_dir=os.environ.get("CYTHON_BUILD_DIR", None)),
+    ], build_dir=os.environ.get("CYTHON_BUILD_DIR", None), include_path=[
+        os.path.join(os.path.dirname(__file__), "..", "rados")]
+    ),
     cmdclass={
         "egg_info": EggInfoCommand,
     },
diff --git a/src/rbd_replay/BufferReader.cc b/src/rbd_replay/BufferReader.cc
index a93302a..ad78b99 100644
--- a/src/rbd_replay/BufferReader.cc
+++ b/src/rbd_replay/BufferReader.cc
@@ -16,9 +16,9 @@ BufferReader::BufferReader(int fd, size_t min_bytes, size_t max_bytes)
 int BufferReader::fetch(bufferlist::iterator **it) {
   if (m_bl_it.get_remaining() < m_min_bytes) {
     ssize_t bytes_to_read = ROUND_UP_TO(m_max_bytes - m_bl_it.get_remaining(),
-                                        CEPH_BUFFER_APPEND_SIZE);
+                                        CEPH_PAGE_SIZE);
     while (!m_eof_reached && bytes_to_read > 0) {
-      int r = m_bl.read_fd(m_fd, CEPH_BUFFER_APPEND_SIZE);
+      int r = m_bl.read_fd(m_fd, CEPH_PAGE_SIZE);
       if (r < 0) {
         return r;
       }
diff --git a/src/rgw/Makefile.am b/src/rgw/Makefile.am
index 0fcc93d..c96e8c5 100644
--- a/src/rgw/Makefile.am
+++ b/src/rgw/Makefile.am
@@ -7,70 +7,123 @@ DENCODER_SOURCES += \
 	rgw/rgw_basic_types.cc \
 	rgw/rgw_common.cc \
 	rgw/rgw_env.cc \
-	rgw/rgw_json_enc.cc
+	rgw/rgw_json_enc.cc \
+	rgw/rgw_keystone.cc
+
+DENCODER_DEPS += -lcurl -lexpat \
+	libcls_version_client.la \
+	libcls_log_client.la \
+	libcls_refcount_client.la \
+	libcls_user_client.la \
+	libcls_timeindex_client.la \
+	libcls_statelog_client.la
 
 if WITH_RADOS
 if WITH_RADOSGW
 
-librgw_la_SOURCES =  \
-	rgw/librgw.cc \
+librgw_la_SOURCES = \
 	rgw/rgw_acl.cc \
 	rgw/rgw_acl_s3.cc \
 	rgw/rgw_acl_swift.cc \
-	rgw/rgw_client_io.cc \
-	rgw/rgw_fcgi.cc \
-	rgw/rgw_xml.cc \
-	rgw/rgw_usage.cc \
-	rgw/rgw_json_enc.cc \
-	rgw/rgw_xml_enc.cc \
-	rgw/rgw_user.cc \
-	rgw/rgw_bucket.cc\
+	rgw/rgw_coroutine.cc \
+	rgw/rgw_cr_rados.cc \
 	rgw/rgw_tools.cc \
-	rgw/rgw_rados.cc \
-	rgw/rgw_http_client.cc \
-	rgw/rgw_rest_client.cc \
-	rgw/rgw_rest_conn.cc \
-	rgw/rgw_op.cc \
 	rgw/rgw_basic_types.cc \
-	rgw/rgw_common.cc \
+	rgw/rgw_bucket.cc \
 	rgw/rgw_cache.cc \
+	rgw/rgw_client_io.cc \
+	rgw/rgw_common.cc \
+	rgw/rgw_cors.cc \
+	rgw/rgw_cors_s3.cc \
+	rgw/rgw_dencoder.cc \
+	rgw/rgw_env.cc \
+	rgw/rgw_fcgi.cc \
 	rgw/rgw_formats.cc \
+	rgw/rgw_frontend.cc \
+	rgw/rgw_gc.cc \
+	rgw/rgw_http_client.cc \
+	rgw/rgw_json_enc.cc \
+	rgw/rgw_keystone.cc \
+	rgw/rgw_loadgen.cc \
 	rgw/rgw_log.cc \
+	rgw/rgw_metadata.cc \
 	rgw/rgw_multi.cc \
-	rgw/rgw_policy_s3.cc \
-	rgw/rgw_gc.cc \
 	rgw/rgw_multi_del.cc \
-	rgw/rgw_env.cc \
-	rgw/rgw_cors.cc \
-	rgw/rgw_cors_s3.cc \
 	rgw/rgw_auth_s3.cc \
-	rgw/rgw_metadata.cc \
-	rgw/rgw_replica_log.cc \
-	rgw/rgw_keystone.cc \
-	rgw/rgw_quota.cc \
-	rgw/rgw_dencoder.cc \
+	rgw/rgw_period_history.cc \
+	rgw/rgw_period_puller.cc \
+	rgw/rgw_period_pusher.cc \
+	rgw/rgw_realm_reloader.cc \
+	rgw/rgw_realm_watcher.cc \
+	rgw/rgw_sync.cc \
+	rgw/rgw_data_sync.cc \
 	rgw/rgw_object_expirer_core.cc \
+	rgw/rgw_op.cc \
+	rgw/rgw_os_lib.cc \
+	rgw/rgw_policy_s3.cc \
+	rgw/rgw_process.cc \
+	rgw/rgw_quota.cc \
+	rgw/rgw_rados.cc \
+	rgw/rgw_replica_log.cc \
+	rgw/rgw_request.cc \
+	rgw/rgw_resolve.cc \
+	rgw/rgw_rest_bucket.cc \
+	rgw/rgw_rest.cc \
+	rgw/rgw_rest_client.cc \
+	rgw/rgw_rest_config.cc \
+	rgw/rgw_rest_conn.cc \
+	rgw/rgw_rest_log.cc \
+	rgw/rgw_rest_metadata.cc \
+	rgw/rgw_rest_opstate.cc \
+	rgw/rgw_rest_realm.cc \
+	rgw/rgw_rest_replica_log.cc \
+	rgw/rgw_rest_s3.cc \
+	rgw/rgw_rest_swift.cc \
+	rgw/rgw_rest_usage.cc \
+	rgw/rgw_rest_user.cc \
+	rgw/rgw_swift_auth.cc \
+	rgw/rgw_swift.cc \
+	rgw/rgw_usage.cc \
+	rgw/rgw_user.cc \
+	rgw/rgw_file.cc \
+	rgw/librgw.cc \
+	rgw/rgw_xml.cc \
+	rgw/rgw_xml_enc.cc \
 	rgw/rgw_website.cc
-librgw_la_CXXFLAGS = -Woverloaded-virtual ${AM_CXXFLAGS}
-noinst_LTLIBRARIES += librgw.la
+
+if WITH_OPENLDAP
+librgw_la_SOURCES += rgw/rgw_ldap.cc
+endif
+
+librgw_la_CXXFLAGS = -Woverloaded-virtual -fPIC -I$(srcdir)/xxHash \
+	${AM_CXXFLAGS}
+# noinst_LTLIBRARIES += librgw.la
 
 LIBRGW_DEPS += \
 	$(LIBRADOS) \
 	libcls_rgw_client.la \
-	libcls_log_client.a \
-	libcls_statelog_client.a \
-	libcls_timeindex_client.a \
-	libcls_user_client.a \
-	libcls_replica_log_client.a \
+	libcls_log_client.la \
+	libcls_statelog_client.la \
+	libcls_timeindex_client.la \
+	libcls_user_client.la \
+	libcls_replica_log_client.la \
 	libcls_lock_client.la \
 	libcls_refcount_client.la \
-	libcls_version_client.a \
+	libcls_version_client.la \
 	-lcurl \
 	-lexpat \
 	-lm \
 	-lfcgi \
 	-ldl
 
+librgw_la_LIBADD = $(LIBRGW_DEPS) \
+	$(PTHREAD_LIBS) $(RESOLV_LIBS) libglobal.la \
+	$(EXTRALIBS)
+
+librgw_la_LDFLAGS = ${AM_LDFLAGS} -version-info 2:0:0
+
+lib_LTLIBRARIES += librgw.la
+
 CIVETWEB_INCLUDE = --include $(srcdir)/civetweb/include/civetweb_conf.h
 
 libcivetweb_la_SOURCES =  \
@@ -78,38 +131,35 @@ libcivetweb_la_SOURCES =  \
 	rgw/rgw_civetweb_log.cc \
 	civetweb/src/civetweb.c
 
-libcivetweb_la_CXXFLAGS = ${CIVETWEB_INCLUDE} -Woverloaded-virtual ${AM_CXXFLAGS}
-libcivetweb_la_CFLAGS = -I$(srcdir)/civetweb/include ${CIVETWEB_INCLUDE}
+libcivetweb_la_CXXFLAGS = ${CIVETWEB_INCLUDE} -fPIC -Woverloaded-virtual \
+	${AM_CXXFLAGS}
+libcivetweb_la_CFLAGS = -I$(srcdir)/civetweb/include ${CIVETWEB_INCLUDE} -fPIC -DNO_SSL_DL
+LIBCIVETWEB_DEPS += -lssl -lcrypto
 
 noinst_LTLIBRARIES += libcivetweb.la
 
 radosgw_SOURCES = \
-	rgw/rgw_resolve.cc \
-	rgw/rgw_rest.cc \
-	rgw/rgw_rest_swift.cc \
-	rgw/rgw_rest_s3.cc \
-	rgw/rgw_rest_usage.cc \
-	rgw/rgw_rest_user.cc \
-	rgw/rgw_rest_bucket.cc \
-	rgw/rgw_rest_metadata.cc \
-	rgw/rgw_replica_log.cc \
-	rgw/rgw_rest_log.cc \
-	rgw/rgw_rest_opstate.cc \
-	rgw/rgw_rest_replica_log.cc \
-	rgw/rgw_rest_config.cc \
-	rgw/rgw_http_client.cc \
-	rgw/rgw_swift.cc \
-	rgw/rgw_swift_auth.cc \
-	rgw/rgw_loadgen.cc \
+	rgw/rgw_fcgi_process.cc \
+	rgw/rgw_loadgen_process.cc \
+	rgw/rgw_civetweb.cc \
+	rgw/rgw_civetweb_frontend.cc \
+	rgw/rgw_civetweb_log.cc \
+	civetweb/src/civetweb.c \
 	rgw/rgw_main.cc
-radosgw_CFLAGS = -I$(srcdir)/civetweb/include
-radosgw_LDADD = $(LIBRGW) $(LIBCIVETWEB) $(LIBRGW_DEPS) $(RESOLV_LIBS) $(CEPH_GLOBAL)
+
+radosgw_CFLAGS = -I$(srcdir)/civetweb/include -fPIC -I$(srcdir)/xxHash
+radosgw_LDADD = $(LIBRGW) $(LIBCIVETWEB) $(LIBCIVETWEB_DEPS) $(LIBRGW_DEPS) $(RESOLV_LIBS) \
+	$(CEPH_GLOBAL)
 bin_PROGRAMS += radosgw
 
 radosgw_admin_SOURCES = rgw/rgw_admin.cc rgw/rgw_orphan.cc
 radosgw_admin_LDADD = $(LIBRGW) $(LIBRGW_DEPS) $(CEPH_GLOBAL)
 bin_PROGRAMS += radosgw-admin
 
+radosgw_token_SOURCES = rgw/rgw_token.cc
+radosgw_token_LDADD = $(LIBRGW) $(LIBRGW_DEPS) $(CEPH_GLOBAL)
+bin_PROGRAMS += radosgw-token
+
 radosgw_object_expirer_SOURCES = rgw/rgw_object_expirer.cc
 radosgw_object_expirer_LDADD = $(LIBRGW) $(LIBRGW_DEPS) $(CEPH_GLOBAL)
 bin_PROGRAMS += radosgw-object-expirer
@@ -130,9 +180,14 @@ noinst_HEADERS += \
 	rgw/rgw_acl.h \
 	rgw/rgw_acl_s3.h \
 	rgw/rgw_acl_swift.h \
+	rgw/rgw_b64.h \
 	rgw/rgw_client_io.h \
+	rgw/rgw_coroutine.h \
+	rgw/rgw_cr_rados.h \
+	rgw/rgw_cr_rest.h \
 	rgw/rgw_fcgi.h \
 	rgw/rgw_xml.h \
+	rgw/rgw_token.h \
 	rgw/rgw_basic_types.h \
 	rgw/rgw_cache.h \
 	rgw/rgw_common.h \
@@ -140,17 +195,26 @@ noinst_HEADERS += \
 	rgw/rgw_cors_s3.h \
 	rgw/rgw_cors_swift.h \
 	rgw/rgw_string.h \
+	rgw/rgw_file.h \
 	rgw/rgw_formats.h \
 	rgw/rgw_http_errors.h \
+	rgw/rgw_ldap.h \
+	rgw/rgw_lib.h \
+	rgw/rgw_lib_frontend.h \
 	rgw/rgw_log.h \
 	rgw/rgw_loadgen.h \
+	rgw/rgw_process.h \
+	rgw/rgw_request.h \
+	rgw/rgw_frontend.h \
 	rgw/rgw_multi.h \
 	rgw/rgw_policy_s3.h \
 	rgw/rgw_gc.h \
 	rgw/rgw_metadata.h \
+	rgw/rgw_meta_sync_status.h \
 	rgw/rgw_multi_del.h \
 	rgw/rgw_object_expirer_core.h \
 	rgw/rgw_op.h \
+	rgw/rgw_os_lib.h \
 	rgw/rgw_orphan.h \
 	rgw/rgw_http_client.h \
 	rgw/rgw_swift.h \
@@ -175,11 +239,21 @@ noinst_HEADERS += \
 	rgw/rgw_rest_opstate.h \
 	rgw/rgw_rest_replica_log.h \
 	rgw/rgw_rest_config.h \
+	rgw/rgw_rest_realm.h \
+	rgw/rgw_sync.h \
+	rgw/rgw_data_sync.h \
 	rgw/rgw_usage.h \
 	rgw/rgw_user.h \
 	rgw/rgw_bucket.h \
 	rgw/rgw_keystone.h \
+	rgw/rgw_period_history.h \
+	rgw/rgw_period_pusher.h \
+	rgw/rgw_period_puller.h \
+	rgw/rgw_realm_reloader.h \
+	rgw/rgw_realm_watcher.h \
 	rgw/rgw_civetweb.h \
+	rgw/rgw_boost_asio_coroutine.h \
+	rgw/rgw_boost_asio_yield.h \
 	rgw/rgw_civetweb_log.h \
 	rgw/rgw_website.h \
 	rgw/rgw_rest_s3website.h \
diff --git a/src/rgw/librgw.cc b/src/rgw/librgw.cc
index f9b39ae..220d024 100644
--- a/src/rgw/librgw.cc
+++ b/src/rgw/librgw.cc
@@ -11,125 +11,605 @@
  * Foundation.  See file COPYING.
  *
  */
+#include <sys/types.h>
+#include <string.h>
 
 #include "include/types.h"
 #include "include/rados/librgw.h"
 #include "rgw/rgw_acl_s3.h"
 #include "rgw_acl.h"
+
+#include "include/str_list.h"
+#include "global/global_init.h"
+#include "common/config.h"
+#include "common/errno.h"
+#include "common/Timer.h"
+#include "common/Throttle.h"
+#include "common/WorkQueue.h"
 #include "common/ceph_argparse.h"
 #include "common/ceph_context.h"
 #include "common/common_init.h"
 #include "common/dout.h"
 
+#include "rgw_rados.h"
+#include "rgw_resolve.h"
+#include "rgw_op.h"
+#include "rgw_rest.h"
+#include "rgw_frontend.h"
+#include "rgw_request.h"
+#include "rgw_process.h"
+#include "rgw_rest_user.h"
+#include "rgw_rest_s3.h"
+#include "rgw_os_lib.h"
+#include "rgw_auth_s3.h"
+#include "rgw_lib.h"
+#include "rgw_lib_frontend.h"
+
 #include <errno.h>
-#include <sstream>
+#include <chrono>
+#include <thread>
+#include <string>
 #include <string.h>
+#include <mutex>
 
 #define dout_subsys ceph_subsys_rgw
 
-int librgw_create(librgw_t *rgw, const char * const id)
-{
-  CephInitParameters iparams(CEPH_ENTITY_TYPE_CLIENT);
-  if (id) {
-    iparams.name.set(CEPH_ENTITY_TYPE_CLIENT, id);
-  }
-  CephContext *cct = common_preinit(iparams, CODE_ENVIRONMENT_LIBRARY, 0,
-				    "rgw_data");
-  cct->_conf->set_val("log_to_stderr", "false"); // quiet by default
-  cct->_conf->set_val("err_to_stderr", "true"); // quiet by default
-  cct->_conf->parse_env(); // environment variables override
-  cct->_conf->apply_changes(NULL);
-
-  common_init_finish(cct);
-  *rgw = cct;
-  return 0;
-}
+bool global_stop = false;
 
-int librgw_acl_bin2xml(librgw_t rgw, const char *bin, int bin_len, char **xml)
-{
-  try {
-    // convert to bufferlist
-    bufferlist bl;
-    bl.append(bin, bin_len);
-
-    // convert to RGWAccessControlPolicy
-    RGWAccessControlPolicy_S3 acl((CephContext *)rgw);
-    bufferlist::iterator bli(bl.begin());
-    acl.decode(bli);
-
-    // convert to XML stringstream
-    stringstream ss;
-    acl.to_xml(ss);
-
-    // convert to XML C string
-    *xml = strdup(ss.str().c_str());
-    if (!*xml)
-      return -ENOBUFS;
-    return 0;
-  }
-  catch (const std::exception &e) {
-    lderr(rgw) << "librgw_acl_bin2xml: caught exception " << e.what() << dendl;
-    return -2000;
+namespace rgw {
+
+  using std::string;
+
+  static std::mutex librgw_mtx;
+
+  RGWLib rgwlib;
+
+  class C_InitTimeout : public Context {
+  public:
+    C_InitTimeout() {}
+    void finish(int r) {
+      derr << "Initialization timeout, failed to initialize" << dendl;
+      exit(1);
+    }
+  };
+
+  void RGWLibProcess::checkpoint()
+  {
+    m_tp.drain(&req_wq);
   }
-  catch (...) {
-    lderr(rgw) << "librgw_acl_bin2xml: caught unknown exception " << dendl;
-    return -2000;
+
+  void RGWLibProcess::run()
+  {
+    while (! shutdown) {
+      lsubdout(cct, rgw, 5) << "RGWLibProcess GC" << dendl;
+      unique_lock uniq(mtx);
+    restart:
+      int cur_gen = gen;
+      for (auto iter = mounted_fs.begin(); iter != mounted_fs.end();
+	   ++iter) {
+	RGWLibFS* fs = iter->first->ref();
+	uniq.unlock();
+	fs->gc();
+	fs->rele();
+	uniq.lock();
+	if (cur_gen != gen)
+	  goto restart; /* invalidated */
+      }
+      uniq.unlock();
+      std::this_thread::sleep_for(std::chrono::seconds(120));
+    }
   }
-}
 
-void librgw_free_xml(librgw_t rgw, char *xml)
-{
-  free(xml);
-}
+  void RGWLibProcess::handle_request(RGWRequest* r)
+  {
+    /*
+     * invariant: valid requests are derived from RGWLibRequst
+     */
+    RGWLibRequest* req = static_cast<RGWLibRequest*>(r);
 
-int librgw_acl_xml2bin(librgw_t rgw, const char *xml, char **bin, int *bin_len)
-{
-  char *bin_ = NULL;
-  try {
-    RGWACLXMLParser_S3 parser((CephContext *)rgw);
-    if (!parser.init()) {
-      return -1000;
+    // XXX move RGWLibIO and timing setup into process_request
+
+#if 0 /* XXX */
+    utime_t tm = ceph_clock_now(NULL);
+#endif
+
+    RGWLibIO io_ctx;
+
+    int ret = process_request(req, &io_ctx);
+    if (ret < 0) {
+      /* we don't really care about return code */
+      dout(20) << "process_request() returned " << ret << dendl;
+
+    }
+    delete req;
+  } /* handle_request */
+
+  int RGWLibProcess::process_request(RGWLibRequest* req)
+  {
+    // XXX move RGWLibIO and timing setup into process_request
+
+#if 0 /* XXX */
+    utime_t tm = ceph_clock_now(NULL);
+#endif
+
+    RGWLibIO io_ctx;
+
+    int ret = process_request(req, &io_ctx);
+    if (ret < 0) {
+      /* we don't really care about return code */
+      dout(20) << "process_request() returned " << ret << dendl;
+    }
+    return ret;
+  } /* process_request */
+
+  static inline void abort_req(struct req_state *s, RGWOp *op, int err_no)
+  {
+    if (!s)
+      return;
+
+    /* XXX the dump_errno and dump_bucket_from_state behaviors in
+     * the abort_early (rgw_rest.cc) might be valuable, but aren't
+     * safe to call presently as they return HTTP data */
+
+    perfcounter->inc(l_rgw_failed_req);
+  } /* abort_req */
+
+  int RGWLibProcess::process_request(RGWLibRequest* req, RGWLibIO* io)
+  {
+    int ret = 0;
+    bool should_log = true; // XXX
+
+    dout(1) << "====== " << __func__
+	    << " starting new request req=" << hex << req << dec
+	    << " ======" << dendl;
+
+    /*
+     * invariant: valid requests are derived from RGWOp--well-formed
+     * requests should have assigned RGWRequest::op in their descendant
+     * constructor--if not, the compiler can find it, at the cost of
+     * a runtime check
+     */
+    RGWOp *op = (req->op) ? req->op : dynamic_cast<RGWOp*>(req);
+    if (! op) {
+      dout(1) << "failed to derive cognate RGWOp (invalid op?)" << dendl;
+      return -EINVAL;
+    }
+
+    io->init(req->cct);
+
+    perfcounter->inc(l_rgw_req);
+
+    RGWEnv& rgw_env = io->get_env();
+
+    /* XXX
+     * until major refactoring of req_state and req_info, we need
+     * to build their RGWEnv boilerplate from the RGWLibRequest,
+     * pre-staging any strings (HTTP_HOST) that provoke a crash when
+     * not found
+     */
+
+    /* XXX for now, use "";  could be a legit hostname, or, in future,
+     * perhaps a tenant (Yehuda) */
+    rgw_env.set("HTTP_HOST", "");
+
+    /* XXX and -then- bloat up req_state with string copies from it */
+    struct req_state rstate(req->cct, &rgw_env, req->get_user());
+    struct req_state *s = &rstate;
+
+    // XXX fix this
+    s->cio = io;
+
+    RGWObjectCtx rados_ctx(store, s); // XXX holds std::map
+
+    /* XXX and -then- stash req_state pointers everywhere they are needed */
+    ret = req->init(rgw_env, &rados_ctx, io, s);
+    if (ret < 0) {
+      dout(10) << "failed to initialize request" << dendl;
+      abort_req(s, op, ret);
+      goto done;
+    }
+
+    /* req is-a RGWOp, currently initialized separately */
+    ret = req->op_init();
+    if (ret < 0) {
+      dout(10) << "failed to initialize RGWOp" << dendl;
+      abort_req(s, op, ret);
+      goto done;
+    }
+
+    /* XXX authorize does less here then in the REST path, e.g.,
+     * the user's info is cached, but still incomplete */
+    req->log(s, "authorizing");
+    ret = req->authorize();
+    if (ret < 0) {
+      dout(10) << "failed to authorize request" << dendl;
+      abort_req(s, op, ret);
+      goto done;
+    }
+
+    req->log(s, "reading op permissions");
+    ret = req->read_permissions(op);
+    if (ret < 0) {
+      abort_req(s, op, ret);
+      goto done;
     }
-    if (!parser.parse(xml, strlen(xml), true)) {
+
+    req->log(s, "init op");
+    ret = op->init_processing();
+    if (ret < 0) {
+      abort_req(s, op, ret);
+      goto done;
+    }
+
+    req->log(s, "verifying op mask");
+    ret = op->verify_op_mask();
+    if (ret < 0) {
+      abort_req(s, op, ret);
+      goto done;
+    }
+
+    req->log(s, "verifying op permissions");
+    ret = op->verify_permission();
+    if (ret < 0) {
+      if (s->system_request) {
+	dout(2) << "overriding permissions due to system operation" << dendl;
+      } else {
+	abort_req(s, op, ret);
+	goto done;
+      }
+    }
+
+    req->log(s, "verifying op params");
+    ret = op->verify_params();
+    if (ret < 0) {
+      abort_req(s, op, ret);
+      goto done;
+    }
+
+    req->log(s, "executing");
+    op->pre_exec();
+    op->execute();
+    op->complete();
+
+  done:
+    int r = io->complete_request();
+    if (r < 0) {
+      dout(0) << "ERROR: io->complete_request() returned " << r << dendl;
+    }
+    if (should_log) {
+      rgw_log_op(store, s, (op ? op->name() : "unknown"), olog);
+    }
+
+    int http_ret = s->err.http_ret;
+
+    req->log_format(s, "http status=%d", http_ret);
+
+    dout(1) << "====== " << __func__
+	    << " req done req=" << hex << req << dec << " http_status="
+	    << http_ret
+	    << " ======" << dendl;
+
+    return (ret < 0 ? ret : s->err.ret);
+  } /* process_request */
+
+  int RGWLibProcess::start_request(RGWLibContinuedReq* req)
+  {
+
+    dout(1) << "====== " << __func__
+	    << " starting new continued request req=" << hex << req << dec
+	    << " ======" << dendl;
+
+    /*
+     * invariant: valid requests are derived from RGWOp--well-formed
+     * requests should have assigned RGWRequest::op in their descendant
+     * constructor--if not, the compiler can find it, at the cost of
+     * a runtime check
+     */
+    RGWOp *op = (req->op) ? req->op : dynamic_cast<RGWOp*>(req);
+    if (! op) {
+      dout(1) << "failed to derive cognate RGWOp (invalid op?)" << dendl;
       return -EINVAL;
     }
-    RGWAccessControlPolicy_S3 *policy =
-      (RGWAccessControlPolicy_S3 *)parser.find_first("AccessControlPolicy");
-    if (!policy) {
-      return -1001;
+
+    struct req_state* s = req->get_state();
+
+    /* req is-a RGWOp, currently initialized separately */
+    int ret = req->op_init();
+    if (ret < 0) {
+      dout(10) << "failed to initialize RGWOp" << dendl;
+      abort_req(s, op, ret);
+      goto done;
+    }
+
+    /* XXX authorize does less here then in the REST path, e.g.,
+     * the user's info is cached, but still incomplete */
+    req->log(s, "authorizing");
+    ret = req->authorize();
+    if (ret < 0) {
+      dout(10) << "failed to authorize request" << dendl;
+      abort_req(s, op, ret);
+      goto done;
+    }
+
+    req->log(s, "reading op permissions");
+    ret = req->read_permissions(op);
+    if (ret < 0) {
+      abort_req(s, op, ret);
+      goto done;
+    }
+
+    req->log(s, "init op");
+    ret = op->init_processing();
+    if (ret < 0) {
+      abort_req(s, op, ret);
+      goto done;
+    }
+
+    req->log(s, "verifying op mask");
+    ret = op->verify_op_mask();
+    if (ret < 0) {
+      abort_req(s, op, ret);
+      goto done;
     }
-    bufferlist bl;
-    policy->encode(bl);
 
-    bin_ = (char*)malloc(bl.length());
-    if (!bin_) {
-      return -ENOBUFS;
+    req->log(s, "verifying op permissions");
+    ret = op->verify_permission();
+    if (ret < 0) {
+      if (s->system_request) {
+	dout(2) << "overriding permissions due to system operation" << dendl;
+      } else {
+	abort_req(s, op, ret);
+	goto done;
+      }
+    }
+
+    req->log(s, "verifying op params");
+    ret = op->verify_params();
+    if (ret < 0) {
+      abort_req(s, op, ret);
+      goto done;
+    }
+
+    op->pre_exec();
+    req->exec_start();
+
+  done:
+    return (ret < 0 ? ret : s->err.ret);
+  }
+
+  int RGWLibProcess::finish_request(RGWLibContinuedReq* req)
+  {
+    RGWOp *op = (req->op) ? req->op : dynamic_cast<RGWOp*>(req);
+    if (! op) {
+      dout(1) << "failed to derive cognate RGWOp (invalid op?)" << dendl;
+      return -EINVAL;
     }
-    int bin_len_ = bl.length();
-    bl.copy(0, bin_len_, bin_);
 
-    *bin = bin_;
-    *bin_len = bin_len_;
+    int ret = req->exec_finish();
+    int op_ret = op->get_ret();
+
+    dout(1) << "====== " << __func__
+	    << " finishing continued request req=" << hex << req << dec
+	    << " op status=" << op_ret
+	    << " ======" << dendl;
+
+    return ret;
+  }
+
+  int RGWLibFrontend::init()
+  {
+    pprocess = new RGWLibProcess(g_ceph_context, &env,
+				 g_conf->rgw_thread_pool_size, conf);
     return 0;
   }
-  catch (const std::exception &e) {
-    lderr(rgw) << "librgw_acl_bin2xml: caught exception " << e.what() << dendl;
+
+  int RGWLib::init()
+  {
+    vector<const char*> args;
+    return init(args);
   }
-  catch (...) {
-    lderr(rgw) << "librgw_acl_bin2xml: caught unknown exception " << dendl;
+
+  int RGWLib::init(vector<const char*>& args)
+  {
+    int r = 0;
+
+    /* alternative default for module */
+    vector<const char *> def_args;
+    def_args.push_back("--debug-rgw=1/5");
+    def_args.push_back("--keyring=$rgw_data/keyring");
+    def_args.push_back("--log-file=/var/log/radosgw/$cluster-$name.log");
+
+    global_init(&def_args, args,
+		CEPH_ENTITY_TYPE_CLIENT,
+		CODE_ENVIRONMENT_DAEMON,
+		CINIT_FLAG_UNPRIVILEGED_DAEMON_DEFAULTS);
+
+    Mutex mutex("main");
+    SafeTimer init_timer(g_ceph_context, mutex);
+    init_timer.init();
+    mutex.Lock();
+    init_timer.add_event_after(g_conf->rgw_init_timeout, new C_InitTimeout);
+    mutex.Unlock();
+
+    common_init_finish(g_ceph_context);
+
+    rgw_tools_init(g_ceph_context);
+
+    rgw_init_resolver();
+
+    store = RGWStoreManager::get_storage(g_ceph_context,
+					 g_conf->rgw_enable_gc_threads,
+					 g_conf->rgw_enable_quota_threads,
+					 g_conf->rgw_run_sync_thread);
+
+    if (!store) {
+      mutex.Lock();
+      init_timer.cancel_all_events();
+      init_timer.shutdown();
+      mutex.Unlock();
+
+      derr << "Couldn't init storage provider (RADOS)" << dendl;
+      return -EIO;
+    }
+
+    r = rgw_perf_start(g_ceph_context);
+
+    rgw_rest_init(g_ceph_context, store, store->get_zonegroup());
+
+    mutex.Lock();
+    init_timer.cancel_all_events();
+    init_timer.shutdown();
+    mutex.Unlock();
+
+    if (r)
+      return -EIO;
+
+    const string& ldap_uri = store->ctx()->_conf->rgw_ldap_uri;
+    const string& ldap_binddn = store->ctx()->_conf->rgw_ldap_binddn;
+    const string& ldap_searchdn = store->ctx()->_conf->rgw_ldap_searchdn;
+    const string& ldap_dnattr =
+      store->ctx()->_conf->rgw_ldap_dnattr;
+
+    ldh = new rgw::LDAPHelper(ldap_uri, ldap_binddn, ldap_searchdn,
+			      ldap_dnattr);
+    ldh->init();
+    ldh->bind();
+
+    rgw_user_init(store);
+    rgw_bucket_init(store->meta_mgr);
+    rgw_log_usage_init(g_ceph_context, store);
+
+    // XXX ex-RGWRESTMgr_lib, mgr->set_logging(true)
+
+    if (!g_conf->rgw_ops_log_socket_path.empty()) {
+      olog = new OpsLogSocket(g_ceph_context, g_conf->rgw_ops_log_data_backlog);
+      olog->init(g_conf->rgw_ops_log_socket_path);
+    }
+
+    int port = 80;
+    RGWProcessEnv env = { store, &rest, olog, port };
+
+    fec = new RGWFrontendConfig("rgwlib");
+    fe = new RGWLibFrontend(env, fec);
+
+    fe->init();
+    if (r < 0) {
+      derr << "ERROR: failed initializing frontend" << dendl;
+      return r;
+    }
+
+    fe->run();
+
+    return 0;
+  } /* RGWLib::init() */
+
+  int RGWLib::stop()
+  {
+    derr << "shutting down" << dendl;
+
+    fe->stop();
+
+    fe->join();
+
+    delete fe;
+    delete fec;
+    delete ldh;
+
+    rgw_log_usage_finalize();
+
+    delete olog;
+
+    RGWStoreManager::close_storage(store);
+
+    rgw_tools_cleanup();
+    rgw_shutdown_resolver();
+
+    rgw_perf_stop(g_ceph_context);
+
+    dout(1) << "final shutdown" << dendl;
+    g_ceph_context->put();
+
+    ceph::crypto::shutdown();
+
+    return 0;
+  } /* RGWLib::stop() */
+
+  int RGWLibIO::set_uid(RGWRados *store, const rgw_user& uid)
+  {
+    int ret = rgw_get_user_info_by_uid(store, uid, user_info, NULL);
+    if (ret < 0) {
+      derr << "ERROR: failed reading user info: uid=" << uid << " ret="
+	   << ret << dendl;
+    }
+    return ret;
   }
-  if (!bin_)
-    free(bin_);
-  bin_ = NULL;
-  return -2000;
-}
 
-void librgw_free_bin(librgw_t rgw, char *bin)
+  int RGWLibRequest::read_permissions(RGWOp* op) {
+    int ret =
+      rgw_build_bucket_policies(rgwlib.get_store(), get_state());
+    if (ret < 0) {
+      ldout(get_state()->cct, 10) << "read_permissions on "
+				  << get_state()->bucket << ":"
+				  << get_state()->object
+				  << " only_bucket=" << only_bucket()
+				  << " ret=" << ret << dendl;
+      if (ret == -ENODATA)
+	ret = -EACCES;
+    }
+    return ret;
+  } /* RGWLibRequest::read_permissions */
+
+  int RGWHandler_Lib::authorize()
+  {
+    /* TODO: handle
+     *  1. subusers
+     *  2. anonymous access
+     *  3. system access
+     *  4. ?
+     *
+     *  Much or all of this depends on handling the cached authorization
+     *  correctly (e.g., dealing with keystone) at mount time.
+     */
+    s->perm_mask = RGW_PERM_FULL_CONTROL;
+
+    // populate the owner info
+    s->owner.set_id(s->user->user_id);
+    s->owner.set_name(s->user->display_name);
+
+    return 0;
+  } /* RGWHandler_Lib::authorize */
+
+} /* namespace rgw */
+
+extern "C" {
+
+int librgw_create(librgw_t* rgw, int argc, char **argv)
 {
-  free(bin);
+  using namespace rgw;
+
+  int rc = -EINVAL;
+
+  if (! g_ceph_context) {
+    std::lock_guard<std::mutex> lg(librgw_mtx);
+    if (! g_ceph_context) {
+      vector<const char*> args;
+      argv_to_vec(argc, const_cast<const char**>(argv), args);
+      rc = rgwlib.init(args);
+    }
+  }
+
+  *rgw = g_ceph_context->get();
+
+  return rc;
 }
 
 void librgw_shutdown(librgw_t rgw)
 {
-  rgw->put();
+  using namespace rgw;
+
+  CephContext* cct = static_cast<CephContext*>(rgw);
+  rgwlib.stop();
+  cct->put();
 }
+
+} /* extern "C" */
diff --git a/src/rgw/rgw_acl.cc b/src/rgw/rgw_acl.cc
index 8c0066e..ef2cb31 100644
--- a/src/rgw/rgw_acl.cc
+++ b/src/rgw/rgw_acl.cc
@@ -13,8 +13,6 @@
 #include "rgw_acl.h"
 #include "rgw_user.h"
 
-#include "rgw_acl_s3.h" // required for backward compatibility
-
 #define dout_subsys ceph_subsys_rgw
 
 using namespace std;
diff --git a/src/rgw/rgw_admin.cc b/src/rgw/rgw_admin.cc
index 115dc0a..0bb5570 100644
--- a/src/rgw/rgw_admin.cc
+++ b/src/rgw/rgw_admin.cc
@@ -6,8 +6,6 @@
 #include <sstream>
 #include <string>
 
-using namespace std;
-
 #include "auth/Crypto.h"
 
 #include "common/armor.h"
@@ -28,11 +26,17 @@ using namespace std;
 #include "rgw_rados.h"
 #include "rgw_acl.h"
 #include "rgw_acl_s3.h"
-#include "rgw_log.h"
+
 #include "rgw_formats.h"
 #include "rgw_usage.h"
 #include "rgw_replica_log.h"
 #include "rgw_orphan.h"
+#include "rgw_sync.h"
+#include "rgw_data_sync.h"
+#include "rgw_rest_conn.h"
+#include "rgw_realm_watcher.h"
+
+using namespace std;
 
 #define dout_subsys ceph_subsys_rgw
 
@@ -69,16 +73,43 @@ void _usage()
   cout << "  object rm                  remove object\n";
   cout << "  object unlink              unlink object from bucket index\n";
   cout << "  objects expire             run expired objects cleanup\n";
+  cout << "  period prepare             prepare a new period\n";
+  cout << "  period delete              delete a period\n";
+  cout << "  period get                 get period info\n";
+  cout << "  period get-current         get current period info\n";
+  cout << "  period pull                pull a period\n";
+  cout << "  period push                push a period\n";
+  cout << "  period list                list all periods\n";
+  cout << "  period update              update the staging period\n";
+  cout << "  period commit              commit the staging period\n";
   cout << "  quota set                  set quota params\n";
   cout << "  quota enable               enable quota\n";
   cout << "  quota disable              disable quota\n";
-  cout << "  region get                 show region info\n";
-  cout << "  regions list               list all regions set on this cluster\n";
-  cout << "  region set                 set region info (requires infile)\n";
-  cout << "  region default             set default region\n";
-  cout << "  region-map get             show region-map\n";
-  cout << "  region-map set             set region-map (requires infile)\n";
+  cout << "  realm create               create a new realm\n";
+  cout << "  realm delete               delete a realm\n";
+  cout << "  realm get                  show realm info\n";
+  cout << "  realm get-default          get default realm name\n";
+  cout << "  realm list                 list realms\n";
+  cout << "  realm list-periods         list all realm periods\n";
+  cout << "  realm remove               remove a zonegroup from the realm\n";
+  cout << "  realm rename               rename a realm\n";
+  cout << "  realm set                  set realm info (requires infile)\n";
+  cout << "  realm default              set realm as default\n";
+  cout << "  realm pull                 pull a realm and its current period\n";
+  cout << "  zonegroup add              add a zone to a zonegroup\n";
+  cout << "  zonegroup create           create a new zone group info\n";
+  cout << "  zonegroup default          set default zone group\n";
+  cout << "  zonegroup delete           delete a zone group info\n";
+  cout << "  zonegroup get              show zone group info\n";
+  cout << "  zonegroup modify           set/clear zonegroup master status\n";
+  cout << "  zonegroup set              set zone group info (requires infile)\n";
+  cout << "  zonegroup rename           rename a zone group\n";
+  cout << "  zonegroup list             list all zone groups set on this cluster\n";
+  cout << "  zonegroup-map get          show zonegroup-map\n";
+  cout << "  zonegroup-map set          set zonegroup-map (requires infile)\n";
+  cout << "  zone create                create a new zone\n";
   cout << "  zone get                   show zone cluster params\n";
+  cout << "  zone modify                set/clear zone master status\n";
   cout << "  zone set                   set zone cluster params (requires infile)\n";
   cout << "  zone list                  list all zones set on this cluster\n";
   cout << "  pool add                   add an existing pool for data placement\n";
@@ -105,10 +136,12 @@ void _usage()
   cout << "  mdlog list                 list metadata log\n";
   cout << "  mdlog trim                 trim metadata log (use start-date, end-date or\n";
   cout << "                             start-marker, end-marker)\n";
+  cout << "  mdlog status               read metadata log status\n";
   cout << "  bilog list                 list bucket index log\n";
   cout << "  bilog trim                 trim bucket index log (use start-marker, end-marker)\n";
   cout << "  datalog list               list data log\n";
   cout << "  datalog trim               trim data log\n";
+  cout << "  datalog status             read data log status\n";
   cout << "  opstate list               list stateful operations entries (use client_id,\n";
   cout << "                             op_id, object)\n";
   cout << "  opstate set                set state on an entry (use client_id, op_id, object, state)\n";
@@ -120,6 +153,7 @@ void _usage()
   cout << "  orphans find               init and run search for leaked rados objects\n";
   cout << "  orphans finish             clean up search for leaked rados objects\n";
   cout << "options:\n";
+  cout << "   --tenant=<tenant>         tenant name\n";
   cout << "   --uid=<id>                user id\n";
   cout << "   --subuser=<name>          subuser name\n";
   cout << "   --access-key=<key>        S3 access key\n";
@@ -148,8 +182,23 @@ void _usage()
   cout << "                               replica mdlog get/delete\n";
   cout << "                               replica datalog get/delete\n";
   cout << "   --metadata-key=<key>      key to retrieve metadata from with metadata get\n";
-  cout << "   --rgw-region=<region>     region in which radosgw is running\n";
+  cout << "   --remote=<remote>         remote to pull period\n";
+  cout << "   --parent=<id>             parent period id\n";
+  cout << "   --period=<id>             period id\n";
+  cout << "   --epoch=<number>          period epoch\n";
+  cout << "   --commit                  commit the period during 'period update'\n";
+  cout << "   --master                  set as master\n";
+  cout << "   --master-url              master url\n";
+  cout << "   --master-zonegroup=<id>   master zonegroup id\n";
+  cout << "   --master-zone=<id>        master zone id\n";
+  cout << "   --rgw-realm=<realm>       realm name\n";
+  cout << "   --realm-id=<realm id>     realm id\n";
+  cout << "   --realm-new-name=<realm new name> realm new name\n";
+  cout << "   --rgw-zonegroup=<zonegroup>   zonegroup name\n";
   cout << "   --rgw-zone=<zone>         zone in which radosgw is running\n";
+  cout << "   --zone-new-name=<zone>    zone new name\n";
+  cout << "   --default                 set entity (realm, zonegroup, zone) as default\n";
+  cout << "   --endpoints=<list>        zone endpoints\n";
   cout << "   --fix                     besides checking bucket index, will also fix it\n";
   cout << "   --check-objects           bucket check: rebuilds bucket index according to\n";
   cout << "                             actual objects state\n";
@@ -167,14 +216,14 @@ void _usage()
   cout << "   --show-log-sum=<flag>     enable/disable dump of log summation on log show\n";
   cout << "   --skip-zero-entries       log show only dumps entries that don't have zero value\n";
   cout << "                             in one of the numeric field\n";
-  cout << "   --infile                  specify a file to read in when setting data\n";
+  cout << "   --infile=<file>           specify a file to read in when setting data\n";
   cout << "   --state=<state string>    specify a state for the opstate set command\n";
   cout << "   --replica-log-type        replica log type (metadata, data, bucket), required for\n";
   cout << "                             replica log operations\n";
   cout << "   --categories=<list>       comma separated list of categories, used in usage show\n";
   cout << "   --caps=<caps>             list of caps (e.g., \"usage=read, write; user=read\"\n";
   cout << "   --yes-i-really-mean-it    required for certain operations\n";
-  cout << "   --reset-regions           reset regionmap when regionmap update";
+  cout << "   --reset-regions           reset regionmap when regionmap update\n";
   cout << "\n";
   cout << "<date> := \"YYYY-MM-DD[ hh:mm:ss]\"\n";
   cout << "\nQuota options:\n";
@@ -195,12 +244,6 @@ int usage()
   return 1;
 }
 
-void usage_exit()
-{
-  _usage();
-  exit(1);
-}
-
 enum {
   OPT_NO_CMD = 0,
   OPT_USER_CREATE,
@@ -221,6 +264,9 @@ enum {
   OPT_BUCKET_UNLINK,
   OPT_BUCKET_STATS,
   OPT_BUCKET_CHECK,
+  OPT_BUCKET_SYNC_STATUS,
+  OPT_BUCKET_SYNC_INIT,
+  OPT_BUCKET_SYNC_RUN,
   OPT_BUCKET_RM,
   OPT_BUCKET_REWRITE,
   OPT_POLICY,
@@ -249,27 +295,47 @@ enum {
   OPT_GC_PROCESS,
   OPT_ORPHANS_FIND,
   OPT_ORPHANS_FINISH,
-  OPT_REGION_GET,
-  OPT_REGION_LIST,
-  OPT_REGION_SET,
-  OPT_REGION_DEFAULT,
-  OPT_REGIONMAP_GET,
-  OPT_REGIONMAP_SET,
-  OPT_REGIONMAP_UPDATE,
+  OPT_ZONEGROUP_ADD,
+  OPT_ZONEGROUP_CREATE,
+  OPT_ZONEGROUP_DEFAULT,
+  OPT_ZONEGROUP_DELETE,
+  OPT_ZONEGROUP_GET,
+  OPT_ZONEGROUP_MODIFY,
+  OPT_ZONEGROUP_SET,
+  OPT_ZONEGROUP_LIST,
+  OPT_ZONEGROUP_RENAME ,  
+  OPT_ZONEGROUPMAP_GET,
+  OPT_ZONEGROUPMAP_SET,
+  OPT_ZONEGROUPMAP_UPDATE,
+  OPT_ZONE_CREATE,  
+  OPT_ZONE_DELETE,
   OPT_ZONE_GET,
+  OPT_ZONE_MODIFY,
   OPT_ZONE_SET,
   OPT_ZONE_LIST,
+  OPT_ZONE_RENAME,
+  OPT_ZONE_DEFAULT,
   OPT_CAPS_ADD,
   OPT_CAPS_RM,
   OPT_METADATA_GET,
   OPT_METADATA_PUT,
   OPT_METADATA_RM,
   OPT_METADATA_LIST,
+  OPT_METADATA_SYNC_STATUS,
+  OPT_METADATA_SYNC_INIT,
+  OPT_METADATA_SYNC_RUN,
   OPT_MDLOG_LIST,
   OPT_MDLOG_TRIM,
+  OPT_MDLOG_FETCH,
+  OPT_MDLOG_STATUS,
+  OPT_SYNC_ERROR_LIST,
   OPT_BILOG_LIST,
   OPT_BILOG_TRIM,
+  OPT_DATA_SYNC_STATUS,
+  OPT_DATA_SYNC_INIT,
+  OPT_DATA_SYNC_RUN,
   OPT_DATALOG_LIST,
+  OPT_DATALOG_STATUS,
   OPT_DATALOG_TRIM,
   OPT_OPSTATE_LIST,
   OPT_OPSTATE_SET,
@@ -278,9 +344,30 @@ enum {
   OPT_REPLICALOG_GET,
   OPT_REPLICALOG_UPDATE,
   OPT_REPLICALOG_DELETE,
+  OPT_REALM_CREATE,
+  OPT_REALM_DELETE,
+  OPT_REALM_GET,
+  OPT_REALM_GET_DEFAULT,
+  OPT_REALM_LIST,
+  OPT_REALM_LIST_PERIODS,
+  OPT_REALM_REMOVE,
+  OPT_REALM_RENAME,
+  OPT_REALM_SET,
+  OPT_REALM_DEFAULT,
+  OPT_REALM_PULL,
+  OPT_PERIOD_PREPARE,
+  OPT_PERIOD_DELETE,
+  OPT_PERIOD_GET,
+  OPT_PERIOD_GET_CURRENT,
+  OPT_PERIOD_PULL,
+  OPT_PERIOD_PUSH,
+  OPT_PERIOD_LIST,
+  OPT_PERIOD_UPDATE,
+  OPT_PERIOD_COMMIT,
+  OPT_SYNC_STATUS,
 };
 
-static int get_cmd(const char *cmd, const char *prev_cmd, bool *need_more)
+static int get_cmd(const char *cmd, const char *prev_cmd, const char *prev_prev_cmd, bool *need_more)
 {
   *need_more = false;
   // NOTE: please keep the checks in alphabetical order !!!
@@ -289,7 +376,9 @@ static int get_cmd(const char *cmd, const char *prev_cmd, bool *need_more)
       strcmp(cmd, "bucket") == 0 ||
       strcmp(cmd, "buckets") == 0 ||
       strcmp(cmd, "caps") == 0 ||
+      strcmp(cmd, "data") == 0 ||
       strcmp(cmd, "datalog") == 0 ||
+      strcmp(cmd, "error") == 0 ||
       strcmp(cmd, "gc") == 0 || 
       strcmp(cmd, "key") == 0 ||
       strcmp(cmd, "log") == 0 ||
@@ -300,19 +389,26 @@ static int get_cmd(const char *cmd, const char *prev_cmd, bool *need_more)
       strcmp(cmd, "olh") == 0 ||
       strcmp(cmd, "opstate") == 0 ||
       strcmp(cmd, "orphans") == 0 || 
+      strcmp(cmd, "period") == 0 ||
       strcmp(cmd, "pool") == 0 ||
       strcmp(cmd, "pools") == 0 ||
       strcmp(cmd, "quota") == 0 ||
+      strcmp(cmd, "realm") == 0 ||
       strcmp(cmd, "region") == 0 ||
-      strcmp(cmd, "regions") == 0 ||
       strcmp(cmd, "region-map") == 0 ||
       strcmp(cmd, "regionmap") == 0 ||
       strcmp(cmd, "replicalog") == 0 ||
       strcmp(cmd, "subuser") == 0 ||
+      strcmp(cmd, "sync") == 0 ||
       strcmp(cmd, "temp") == 0 ||
       strcmp(cmd, "usage") == 0 ||
       strcmp(cmd, "user") == 0 ||
-      strcmp(cmd, "zone") == 0) {
+      strcmp(cmd, "zone") == 0 ||
+      strcmp(cmd, "zonegroup") == 0 ||
+      strcmp(cmd, "zonegroups") == 0 ||
+      strcmp(cmd, "zonegroup-map") == 0 ||
+      strcmp(cmd, "zonegroupmap") == 0 )
+{
     *need_more = true;
     return 0;
   }
@@ -370,6 +466,18 @@ static int get_cmd(const char *cmd, const char *prev_cmd, bool *need_more)
       return OPT_BUCKET_REWRITE;
     if (strcmp(cmd, "check") == 0)
       return OPT_BUCKET_CHECK;
+    if (strcmp(cmd, "sync") == 0) {
+      *need_more = true;
+      return 0;
+    }
+  } else if ((prev_prev_cmd && strcmp(prev_prev_cmd, "bucket") == 0) &&
+	     (strcmp(prev_cmd, "sync") == 0)) {
+    if (strcmp(cmd, "status") == 0)
+      return OPT_BUCKET_SYNC_STATUS;
+    if (strcmp(cmd, "init") == 0)
+      return OPT_BUCKET_SYNC_INIT;
+    if (strcmp(cmd, "run") == 0)
+      return OPT_BUCKET_SYNC_RUN;
   } else if (strcmp(prev_cmd, "log") == 0) {
     if (strcmp(cmd, "list") == 0)
       return OPT_LOG_LIST;
@@ -421,15 +529,68 @@ static int get_cmd(const char *cmd, const char *prev_cmd, bool *need_more)
       return OPT_BI_PUT;
     if (strcmp(cmd, "list") == 0)
       return OPT_BI_LIST;
-  } else if (strcmp(prev_cmd, "region") == 0) {
+  } else if (strcmp(prev_cmd, "period") == 0) {
+    if (strcmp(cmd, "prepare") == 0)
+      return OPT_PERIOD_PREPARE;
+    if (strcmp(cmd, "delete") == 0)
+      return OPT_PERIOD_DELETE;
+    if (strcmp(cmd, "get") == 0)
+      return OPT_PERIOD_GET;
+    if (strcmp(cmd, "get-current") == 0)
+      return OPT_PERIOD_GET_CURRENT;
+    if (strcmp(cmd, "pull") == 0)
+      return OPT_PERIOD_PULL;
+    if (strcmp(cmd, "push") == 0)
+      return OPT_PERIOD_PUSH;
+    if (strcmp(cmd, "list") == 0)
+      return OPT_PERIOD_LIST;
+    if (strcmp(cmd, "update") == 0)
+      return OPT_PERIOD_UPDATE;
+    if (strcmp(cmd, "commit") == 0)
+      return OPT_PERIOD_COMMIT;
+  } else if (strcmp(prev_cmd, "realm") == 0) {
+    if (strcmp(cmd, "create") == 0)
+      return OPT_REALM_CREATE;
+    if (strcmp(cmd, "delete") == 0)
+      return OPT_REALM_DELETE;
     if (strcmp(cmd, "get") == 0)
-      return OPT_REGION_GET;
+      return OPT_REALM_GET;
+    if (strcmp(cmd, "get-default") == 0)
+      return OPT_REALM_GET_DEFAULT;
     if (strcmp(cmd, "list") == 0)
-      return OPT_REGION_LIST;
+      return OPT_REALM_LIST;
+    if (strcmp(cmd, "list-periods") == 0)
+      return OPT_REALM_LIST_PERIODS;
+    if (strcmp(cmd, "remove") == 0)
+      return OPT_REALM_REMOVE;
+    if (strcmp(cmd, "rename") == 0)
+      return OPT_REALM_RENAME;
     if (strcmp(cmd, "set") == 0)
-      return OPT_REGION_SET;
+      return OPT_REALM_SET;
+    if (strcmp(cmd, "default") == 0)
+      return OPT_REALM_DEFAULT;
+    if (strcmp(cmd, "pull") == 0)
+      return OPT_REALM_PULL;
+  } else if (strcmp(prev_cmd, "zonegroup") == 0 ||
+	     strcmp(prev_cmd, "region") == 0) {
+    if (strcmp(cmd, "add") == 0)
+      return OPT_ZONEGROUP_ADD;
+    if (strcmp(cmd, "create")== 0)
+      return OPT_ZONEGROUP_CREATE;
     if (strcmp(cmd, "default") == 0)
-      return OPT_REGION_DEFAULT;
+      return OPT_ZONEGROUP_DEFAULT;
+    if (strcmp(cmd, "delete") == 0)
+      return OPT_ZONEGROUP_DELETE;
+    if (strcmp(cmd, "get") == 0)
+      return OPT_ZONEGROUP_GET;
+    if (strcmp(cmd, "modify") == 0)
+      return OPT_ZONEGROUP_MODIFY;
+    if (strcmp(cmd, "list") == 0)
+      return OPT_ZONEGROUP_LIST;
+    if (strcmp(cmd, "set") == 0)
+      return OPT_ZONEGROUP_SET;
+    if (strcmp(cmd, "rename") == 0)
+      return OPT_ZONEGROUP_RENAME;
   } else if (strcmp(prev_cmd, "quota") == 0) {
     if (strcmp(cmd, "set") == 0)
       return OPT_QUOTA_SET;
@@ -437,24 +598,37 @@ static int get_cmd(const char *cmd, const char *prev_cmd, bool *need_more)
       return OPT_QUOTA_ENABLE;
     if (strcmp(cmd, "disable") == 0)
       return OPT_QUOTA_DISABLE;
-  } else if (strcmp(prev_cmd, "regions") == 0) {
+  } else if (strcmp(prev_cmd, "zonegroups") == 0 ||
+	     strcmp(prev_cmd, "regions") == 0) {
     if (strcmp(cmd, "list") == 0)
-      return OPT_REGION_LIST;
-  } else if (strcmp(prev_cmd, "region-map") == 0 ||
+      return OPT_ZONEGROUP_LIST;
+  } else if (strcmp(prev_cmd, "zonegroup-map") == 0 ||
+             strcmp(prev_cmd, "zonegroupmap") == 0 ||
+	     strcmp(prev_cmd, "region-map") == 0 ||
              strcmp(prev_cmd, "regionmap") == 0) {
     if (strcmp(cmd, "get") == 0)
-      return OPT_REGIONMAP_GET;
+      return OPT_ZONEGROUPMAP_GET;
     if (strcmp(cmd, "set") == 0)
-      return OPT_REGIONMAP_SET;
+      return OPT_ZONEGROUPMAP_SET;
     if (strcmp(cmd, "update") == 0)
-      return OPT_REGIONMAP_UPDATE;
+      return OPT_ZONEGROUPMAP_UPDATE;
   } else if (strcmp(prev_cmd, "zone") == 0) {
+    if (strcmp(cmd, "delete") == 0)
+      return OPT_ZONE_DELETE;
+    if (strcmp(cmd, "create") == 0)
+      return OPT_ZONE_CREATE;
     if (strcmp(cmd, "get") == 0)
       return OPT_ZONE_GET;
     if (strcmp(cmd, "set") == 0)
       return OPT_ZONE_SET;
     if (strcmp(cmd, "list") == 0)
       return OPT_ZONE_LIST;
+    if (strcmp(cmd, "modify") == 0)
+      return OPT_ZONE_MODIFY;
+    if (strcmp(cmd, "rename") == 0)
+      return OPT_ZONE_RENAME;
+    if (strcmp(cmd, "default") == 0)
+      return OPT_ZONE_DEFAULT;
   } else if (strcmp(prev_cmd, "zones") == 0) {
     if (strcmp(cmd, "list") == 0)
       return OPT_ZONE_LIST;
@@ -477,21 +651,56 @@ static int get_cmd(const char *cmd, const char *prev_cmd, bool *need_more)
       return OPT_METADATA_RM;
     if (strcmp(cmd, "list") == 0)
       return OPT_METADATA_LIST;
+    if (strcmp(cmd, "sync") == 0) {
+      *need_more = true;
+      return 0;
+    }
+  } else if ((prev_prev_cmd && strcmp(prev_prev_cmd, "metadata") == 0) &&
+	     (strcmp(prev_cmd, "sync") == 0)) {
+    if (strcmp(cmd, "status") == 0)
+      return OPT_METADATA_SYNC_STATUS;
+    if (strcmp(cmd, "init") == 0)
+      return OPT_METADATA_SYNC_INIT;
+    if (strcmp(cmd, "run") == 0)
+      return OPT_METADATA_SYNC_RUN;
+  } else if ((prev_prev_cmd && strcmp(prev_prev_cmd, "sync") == 0) &&
+	     (strcmp(prev_cmd, "error") == 0)) {
+    if (strcmp(cmd, "list") == 0)
+      return OPT_SYNC_ERROR_LIST;
   } else if (strcmp(prev_cmd, "mdlog") == 0) {
     if (strcmp(cmd, "list") == 0)
       return OPT_MDLOG_LIST;
     if (strcmp(cmd, "trim") == 0)
       return OPT_MDLOG_TRIM;
+    if (strcmp(cmd, "fetch") == 0)
+      return OPT_MDLOG_FETCH;
+    if (strcmp(cmd, "status") == 0)
+      return OPT_MDLOG_STATUS;
   } else if (strcmp(prev_cmd, "bilog") == 0) {
     if (strcmp(cmd, "list") == 0)
       return OPT_BILOG_LIST;
     if (strcmp(cmd, "trim") == 0)
       return OPT_BILOG_TRIM;
+  } else if (strcmp(prev_cmd, "data") == 0) {
+    if (strcmp(cmd, "sync") == 0) {
+      *need_more = true;
+      return 0;
+    }
   } else if (strcmp(prev_cmd, "datalog") == 0) {
     if (strcmp(cmd, "list") == 0)
       return OPT_DATALOG_LIST;
     if (strcmp(cmd, "trim") == 0)
       return OPT_DATALOG_TRIM;
+    if (strcmp(cmd, "status") == 0)
+      return OPT_DATALOG_STATUS;
+  } else if ((prev_prev_cmd && strcmp(prev_prev_cmd, "data") == 0) &&
+	     (strcmp(prev_cmd, "sync") == 0)) {
+    if (strcmp(cmd, "status") == 0)
+      return OPT_DATA_SYNC_STATUS;
+    if (strcmp(cmd, "init") == 0)
+      return OPT_DATA_SYNC_INIT;
+    if (strcmp(cmd, "run") == 0)
+      return OPT_DATA_SYNC_RUN;
   } else if (strcmp(prev_cmd, "opstate") == 0) {
     if (strcmp(cmd, "list") == 0)
       return OPT_OPSTATE_LIST;
@@ -508,6 +717,9 @@ static int get_cmd(const char *cmd, const char *prev_cmd, bool *need_more)
       return OPT_REPLICALOG_UPDATE;
     if (strcmp(cmd, "delete") == 0)
       return OPT_REPLICALOG_DELETE;
+  } else if (strcmp(prev_cmd, "sync") == 0) {
+    if (strcmp(cmd, "status") == 0)
+      return OPT_SYNC_STATUS;
   }
 
   return -EINVAL;
@@ -592,10 +804,10 @@ static void dump_bucket_usage(map<RGWObjCategory, RGWStorageStats>& stats, Forma
   formatter->close_section();
 }
 
-int bucket_stats(rgw_bucket& bucket, Formatter *formatter)
+int bucket_stats(rgw_bucket& bucket, int shard_id, Formatter *formatter)
 {
   RGWBucketInfo bucket_info;
-  time_t mtime;
+  real_time mtime;
   RGWObjectCtx obj_ctx(store);
   int r = store->get_bucket_info(obj_ctx, bucket.tenant, bucket.name, bucket_info, &mtime);
   if (r < 0)
@@ -604,7 +816,7 @@ int bucket_stats(rgw_bucket& bucket, Formatter *formatter)
   map<RGWObjCategory, RGWStorageStats> stats;
   string bucket_ver, master_ver;
   string max_marker;
-  int ret = store->get_bucket_stats(bucket, &bucket_ver, &master_ver, stats, &max_marker);
+  int ret = store->get_bucket_stats(bucket, shard_id, &bucket_ver, &master_ver, stats, &max_marker);
   if (ret < 0) {
     cerr << "error getting bucket stats ret=" << ret << std::endl;
     return ret;
@@ -617,7 +829,7 @@ int bucket_stats(rgw_bucket& bucket, Formatter *formatter)
   formatter->dump_string("id", bucket.bucket_id);
   formatter->dump_string("marker", bucket.marker);
   ::encode_json("owner", bucket_info.owner, formatter);
-  formatter->dump_int("mtime", mtime);
+  formatter->dump_int("mtime", utime_t(mtime));
   formatter->dump_string("ver", bucket_ver);
   formatter->dump_string("master_ver", master_ver);
   formatter->dump_string("max_marker", max_marker);
@@ -831,7 +1043,7 @@ int set_bucket_quota(RGWRados *store, int opt_cmd,
 
   set_quota_info(bucket_info.quota, opt_cmd, max_size, max_objects, have_max_size, have_max_objects);
 
-   r = store->put_bucket_instance_info(bucket_info, false, 0, &attrs);
+   r = store->put_bucket_instance_info(bucket_info, false, real_time(), &attrs);
   if (r < 0) {
     cerr << "ERROR: failed writing bucket instance info: " << cpp_strerror(-r) << std::endl;
     return -r;
@@ -989,9 +1201,6 @@ int check_obj_tail_locator_underscore(RGWBucketInfo& bucket_info, rgw_obj& obj,
   f->dump_string("instance", key.instance);
   f->close_section();
 
-  string oid;
-  string locator;
-
   bool needs_fixing;
   string status;
 
@@ -1041,7 +1250,7 @@ int do_check_object_locator(const string& tenant_name, const string& bucket_name
   map<string, bool> common_prefixes;
   string ns;
 
-  RGWRados::Bucket target(store, bucket);
+  RGWRados::Bucket target(store, bucket_info);
   RGWRados::Bucket::List list_op(&target);
 
   string marker;
@@ -1063,7 +1272,6 @@ int do_check_object_locator(const string& tenant_name, const string& bucket_name
 
     count += result.size();
 
-    list<rgw_obj> objs;
     for (vector<RGWObjEnt>::iterator iter = result.begin(); iter != result.end(); ++iter) {
       rgw_obj_key key = iter->key;
       rgw_obj obj(bucket, key);
@@ -1086,111 +1294,751 @@ int do_check_object_locator(const string& tenant_name, const string& bucket_name
   return 0;
 }
 
-int main(int argc, char **argv) 
+#define MAX_REST_RESPONSE (128 * 1024) // we expect a very small response
+static int send_to_remote_gateway(const string& remote, req_info& info,
+                                  bufferlist& in_data, JSONParser& parser)
 {
-  vector<const char*> args;
-  argv_to_vec(argc, (const char **)argv, args);
-  env_to_vec(args);
+  bufferlist response;
+  RGWRESTConn *conn;
+  if (remote.empty()) {
+    if (!store->rest_master_conn) {
+      cerr << "Invalid rest master connection" << std::endl;
+      return -EINVAL;
+    }
+    conn = store->rest_master_conn;
+  } else {
+    auto iter = store->zonegroup_conn_map.find(remote);
+    if (iter == store->zonegroup_conn_map.end()) {
+      cerr << "could not find connection to: " << remote << std::endl;
+      return -ENOENT;
+    }
+    conn = iter->second;
+  }
+  rgw_user user;
+  int ret = conn->forward(user, info, NULL, MAX_REST_RESPONSE, &in_data, &response);
+  if (ret < 0) {
+    return ret;
+  }
+  ret = parser.parse(response.c_str(), response.length());
+  if (ret < 0) {
+    cerr << "failed to parse response" << std::endl;
+    return ret;
+  }
+  return 0;
+}
 
-  global_init(NULL, args, CEPH_ENTITY_TYPE_CLIENT, CODE_ENVIRONMENT_UTILITY, 0);
-  common_init_finish(g_ceph_context);
+static int send_to_url(const string& url, RGWAccessKey& key, req_info& info,
+                       bufferlist& in_data, JSONParser& parser)
+{
+  list<pair<string, string> > params;
+  RGWRESTSimpleRequest req(g_ceph_context, url, NULL, &params);
 
-  rgw_user user_id;
-  string tenant;
-  std::string access_key, secret_key, user_email, display_name;
-  std::string bucket_name, pool_name, object;
-  std::string date, subuser, access, format;
-  std::string start_date, end_date;
-  std::string key_type_str;
-  int key_type = KEY_TYPE_UNDEFINED;
-  rgw_bucket bucket;
-  uint32_t perm_mask = 0;
-  RGWUserInfo info;
-  int opt_cmd = OPT_NO_CMD;
-  bool need_more;
-  int gen_access_key = 0;
-  int gen_secret_key = 0;
-  bool set_perm = false;
-  bool set_temp_url_key = false;
-  map<int, string> temp_url_keys;
-  string bucket_id;
-  Formatter *formatter = NULL;
-  int purge_data = false;
+  bufferlist response;
+  int ret = req.forward_request(key, info, MAX_REST_RESPONSE, &in_data, &response);
+  if (ret < 0) {
+    return ret;
+  }
+  ret = parser.parse(response.c_str(), response.length());
+  if (ret < 0) {
+    cout << "failed to parse response" << std::endl;
+    return ret;
+  }
+  return 0;
+}
+
+static int send_to_remote_or_url(const string& remote, const string& url,
+                                 const string& access, const string& secret,
+                                 req_info& info, bufferlist& in_data,
+                                 JSONParser& parser)
+{
+  if (url.empty()) {
+    return send_to_remote_gateway(remote, info, in_data, parser);
+  }
+
+  if (access.empty() || secret.empty()) {
+    cerr << "An --access-key and --secret must be provided with --url." << std::endl;
+    return -EINVAL;
+  }
+  RGWAccessKey key;
+  key.id = access;
+  key.key = secret;
+  return send_to_url(url, key, info, in_data, parser);
+}
+
+static int commit_period(RGWRealm& realm, RGWPeriod& period,
+                         const string& remote, const string& url,
+                         const string& access, const string& secret)
+{
+  const string& master_zone = period.get_master_zone();
+  if (master_zone.empty()) {
+    cerr << "cannot commit period: period does not have a master zone of a master zonegroup" << std::endl;
+    return -EINVAL;
+  }
+  // are we the period's master zone?
+  if (store->get_zone_params().get_id() == master_zone) {
+    // read the current period
+    RGWPeriod current_period;
+    int ret = current_period.init(g_ceph_context, store, realm.get_id());
+    if (ret < 0) {
+      cerr << "Error initializing current period: "
+          << cpp_strerror(-ret) << std::endl;
+      return ret;
+    }
+    // the master zone can commit locally
+    ret = period.commit(realm, current_period);
+    if (ret < 0) {
+      cerr << "failed to commit period: " << cpp_strerror(-ret) << std::endl;
+    }
+    return ret;
+  }
+
+  // push period to the master with an empty period id
+  period.set_id("");
+
+  RGWEnv env;
+  req_info info(g_ceph_context, &env);
+  info.method = "POST";
+  info.request_uri = "/admin/realm/period";
+
+  // json format into a bufferlist
+  JSONFormatter jf(false);
+  encode_json("period", period, &jf);
+  bufferlist bl;
+  jf.flush(bl);
+
+  JSONParser p;
+  int ret = send_to_remote_or_url(remote, url, access, secret, info, bl, p);
+  if (ret < 0) {
+    cerr << "request failed: " << cpp_strerror(-ret) << std::endl;
+    return ret;
+  }
+
+  // decode the response and store it back
+  try {
+    decode_json_obj(period, &p);
+  } catch (JSONDecoder::err& e) {
+    cout << "failed to decode JSON input: " << e.message << std::endl;
+    return -EINVAL;
+  }
+  if (period.get_id().empty()) {
+    cerr << "Period commit got back an empty period id" << std::endl;
+    return -EINVAL;
+  }
+  // the master zone gave us back the period that it committed, so it's
+  // safe to save it as our latest epoch
+  ret = period.store_info(false);
+  if (ret < 0) {
+    cerr << "Error storing committed period " << period.get_id() << ": "
+        << cpp_strerror(ret) << std::endl;
+    return ret;
+  }
+  ret = period.set_latest_epoch(period.get_epoch());
+  if (ret < 0) {
+    cerr << "Error updating period epoch: " << cpp_strerror(ret) << std::endl;
+    return ret;
+  }
+  ret = period.reflect();
+  if (ret < 0) {
+    cerr << "Error updating local objects: " << cpp_strerror(ret) << std::endl;
+    return ret;
+  }
+  realm.notify_new_period(period);
+  return ret;
+}
+
+static int update_period(const string& realm_id, const string& realm_name,
+                         const string& period_id, const string& period_epoch,
+                         bool commit, const string& remote, const string& url,
+                         const string& access, const string& secret,
+                         Formatter *formatter)
+{
+  RGWRealm realm(realm_id, realm_name);
+  int ret = realm.init(g_ceph_context, store);
+  if (ret < 0 ) {
+    cerr << "Error initializing realm " << cpp_strerror(-ret) << std::endl;
+    return ret;
+  }
+  epoch_t epoch = 0;
+  if (!period_epoch.empty()) {
+    epoch = atoi(period_epoch.c_str());
+  }
+  RGWPeriod period(period_id, epoch);
+  ret = period.init(g_ceph_context, store, realm.get_id());
+  if (ret < 0) {
+    cerr << "period init failed: " << cpp_strerror(-ret) << std::endl;
+    return ret;
+  }
+  period.fork();
+  ret = period.update();
+  if(ret < 0) {
+    cerr << "failed to update period: " << cpp_strerror(-ret) << std::endl;
+    return ret;
+  }
+  ret = period.store_info(false);
+  if (ret < 0) {
+    cerr << "failed to store period: " << cpp_strerror(-ret) << std::endl;
+    return ret;
+  }
+  if (commit) {
+    ret = commit_period(realm, period, remote, url, access, secret);
+    if (ret < 0) {
+      cerr << "failed to commit period: " << cpp_strerror(-ret) << std::endl;
+      return ret;
+    }
+  }
+  encode_json("period", period, formatter);
+  formatter->flush(cout);
+  cout << std::endl;
+  return 0;
+}
+
+static int init_bucket_for_sync(const string& tenant, const string& bucket_name, string& bucket_id)
+{
   RGWBucketInfo bucket_info;
-  int pretty_format = false;
-  int show_log_entries = true;
-  int show_log_sum = true;
-  int skip_zero_entries = false;  // log show
-  int purge_keys = false;
-  int yes_i_really_mean_it = false;
-  int delete_child_objects = false;
-  int fix = false;
-  int remove_bad = false;
-  int check_head_obj_locator = false;
-  int max_buckets = -1;
-  map<string, bool> categories;
-  string caps;
-  int check_objects = false;
-  RGWUserAdminOpState user_op;
-  RGWBucketAdminOpState bucket_op;
-  string infile;
-  string metadata_key;
-  RGWObjVersionTracker objv_tracker;
-  string marker;
-  string start_marker;
-  string end_marker;
-  int max_entries = -1;
-  int system = false;
-  bool system_specified = false;
-  int shard_id = -1;
-  bool specified_shard_id = false;
-  string daemon_id;
-  bool specified_daemon_id = false;
-  string client_id;
-  string op_id;
-  string state_str;
-  string replica_log_type_str;
-  ReplicaLogType replica_log_type = ReplicaLog_Invalid;
-  string op_mask_str;
-  string quota_scope;
-  string object_version;
+  rgw_bucket bucket;
 
-  int64_t max_objects = -1;
-  int64_t max_size = -1;
-  bool have_max_objects = false;
-  bool have_max_size = false;
-  int include_all = false;
+  int ret = init_bucket(tenant, bucket_name, bucket_id, bucket_info, bucket);
+  if (ret == -ENOENT) {
+    if (bucket_id.empty()) {
+      cerr << "ERROR: bucket id specified" << std::endl;
+      return EINVAL;
+    }
+  } else {
+    bucket_id = bucket.bucket_id;
+  }
+  if (ret < 0) {
+    cerr << "ERROR: could not init bucket: " << cpp_strerror(-ret) << std::endl;
+    return -ret;
+  }
 
-  int sync_stats = false;
-  int reset_regions = false;
+  return 0;
+}
 
-  uint64_t min_rewrite_size = 4 * 1024 * 1024;
-  uint64_t max_rewrite_size = ULLONG_MAX;
-  uint64_t min_rewrite_stripe_size = 0;
+static int do_period_pull(const string& remote, const string& url, const string& access_key, const string& secret_key,
+                          const string& realm_id, const string& realm_name, const string& period_id, const string& period_epoch,
+                          RGWPeriod *period)
+{
+  RGWEnv env;
+  req_info info(g_ceph_context, &env);
+  info.method = "GET";
+  info.request_uri = "/admin/realm/period";
+
+  map<string, string> &params = info.args.get_params();
+  if (!realm_id.empty())
+    params["realm_id"] = realm_id;
+  if (!realm_name.empty())
+    params["realm_name"] = realm_name;
+  if (!period_id.empty())
+    params["period_id"] = period_id;
+  if (!period_epoch.empty())
+    params["epoch"] = period_epoch;
 
-  BIIndexType bi_index_type = PlainIdx;
+  bufferlist bl;
+  JSONParser p;
+  int ret = send_to_remote_or_url(remote, url, access_key, secret_key,
+                                  info, bl, p);
+  if (ret < 0) {
+    cerr << "request failed: " << cpp_strerror(-ret) << std::endl;
+    return ret;
+  }
+  ret = period->init(g_ceph_context, store, false);
+  if (ret < 0) {
+    cerr << "faile to init period " << cpp_strerror(-ret) << std::endl;
+    return ret;
+  }
+  try {
+    decode_json_obj(*period, &p);
+  } catch (JSONDecoder::err& e) {
+    cout << "failed to decode JSON input: " << e.message << std::endl;
+    return -EINVAL;
+  }
+  ret = period->store_info(false);
+  if (ret < 0) {
+    cerr << "Error storing period " << period->get_id() << ": " << cpp_strerror(ret) << std::endl;
+  }
 
-  string job_id;
-  int num_shards = 0;
-  int max_concurrent_ios = 32;
-  uint64_t orphan_stale_secs = (24 * 3600);
+  return 0;
+}
 
-  std::string val;
-  std::ostringstream errs;
-  string err;
-  long long tmp = 0;
+static int read_current_period_id(RGWRados* store, const std::string& realm_id,
+                                  const std::string& realm_name,
+                                  std::string* period_id)
+{
+  RGWRealm realm(realm_id, realm_name);
+  int ret = realm.init(g_ceph_context, store);
+  if (ret < 0) {
+    std::cerr << "failed to read realm: " << cpp_strerror(-ret) << std::endl;
+    return ret;
+  }
+  *period_id = realm.get_current_period();
+  return 0;
+}
 
-  for (std::vector<const char*>::iterator i = args.begin(); i != args.end(); ) {
-    if (ceph_argparse_double_dash(args, i)) {
-      break;
-    } else if (ceph_argparse_flag(args, i, "-h", "--help", (char*)NULL)) {
-      usage();
-      return 0;
-    } else if (ceph_argparse_witharg(args, i, &val, "-i", "--uid", (char*)NULL)) {
-      user_id.from_str(val);
-    } else if (ceph_argparse_witharg(args, i, &val, "--tenant", (char*)NULL)) {
-      tenant = val;
-    } else if (ceph_argparse_witharg(args, i, &val, "--access-key", (char*)NULL)) {
+void flush_ss(stringstream& ss, list<string>& l)
+{
+  if (!ss.str().empty()) {
+    l.push_back(ss.str());
+  }
+  ss.str("");
+}
+
+stringstream& push_ss(stringstream& ss, list<string>& l, int tab = 0)
+{
+  flush_ss(ss, l);
+  if (tab > 0) {
+    ss << setw(tab) << "" << setw(1);
+  }
+  return ss;
+}
+
+static void get_md_sync_status(list<string>& status)
+{
+  RGWMetaSyncStatusManager sync(store, store->get_async_rados());
+
+  int ret = sync.init();
+  if (ret < 0) {
+    status.push_back(string("failed to retrieve sync info: sync.init() failed: ") + cpp_strerror(-ret));
+    return;
+  }
+
+  ret = sync.read_sync_status();
+  if (ret < 0) {
+    status.push_back(string("failed to read sync status: ") + cpp_strerror(-ret));
+    return;
+  }
+
+  const rgw_meta_sync_status& sync_status = sync.get_sync_status();
+
+  string status_str;
+  switch (sync_status.sync_info.state) {
+    case rgw_meta_sync_info::StateInit:
+      status_str = "init";
+      break;
+    case rgw_meta_sync_info::StateBuildingFullSyncMaps:
+      status_str = "preparing for full sync";
+      break;
+    case rgw_meta_sync_info::StateSync:
+      status_str = "syncing";
+      break;
+    default:
+      status_str = "unknown";
+  }
+
+  status.push_back(status_str);
+  
+  uint64_t full_total = 0;
+  uint64_t full_complete = 0;
+
+  int num_full = 0;
+  int num_inc = 0;
+  int total_shards = 0;
+
+  for (auto marker_iter : sync_status.sync_markers) {
+    full_total += marker_iter.second.total_entries;
+    total_shards++;
+    if (marker_iter.second.state == rgw_meta_sync_marker::SyncState::FullSync) {
+      num_full++;
+      full_complete += marker_iter.second.pos;
+    } else {
+      full_complete += marker_iter.second.total_entries;
+    }
+    if (marker_iter.second.state == rgw_meta_sync_marker::SyncState::IncrementalSync) {
+      num_inc++;
+    }
+  }
+
+  stringstream ss;
+  push_ss(ss, status) << "full sync: " << num_full << "/" << total_shards << " shards";
+
+  if (num_full > 0) {
+    push_ss(ss, status) << "full sync: " << full_total - full_complete << " entries to sync";
+  }
+
+  push_ss(ss, status) << "incremental sync: " << num_inc << "/" << total_shards << " shards";
+
+  rgw_mdlog_info log_info;
+  ret = sync.read_log_info(&log_info);
+  if (ret < 0) {
+    status.push_back(string("failed to fetch local sync status: ") + cpp_strerror(-ret));
+    return;
+  }
+
+  map<int, RGWMetadataLogInfo> master_shards_info;
+  string master_period;
+
+  ret = sync.read_master_log_shards_info(&master_period, &master_shards_info);
+  if (ret < 0) {
+    status.push_back(string("failed to fetch master sync status: ") + cpp_strerror(-ret));
+    return;
+  }
+
+  map<int, string> shards_behind;
+
+  if (sync_status.sync_info.period != master_period) {
+    status.push_back(string("master is on a different period: master_period=" + master_period + " local_period=" + sync_status.sync_info.period));
+  } else {
+    for (auto local_iter : sync_status.sync_markers) {
+      int shard_id = local_iter.first;
+      auto iter = master_shards_info.find(shard_id);
+
+      if (iter == master_shards_info.end()) {
+        /* huh? */
+        derr << "ERROR: could not find remote sync shard status for shard_id=" << shard_id << dendl;
+        continue;
+      }
+      auto master_marker = iter->second.marker;
+      if (master_marker > local_iter.second.marker) {
+        shards_behind[shard_id] = local_iter.second.marker;
+      }
+    }
+  }
+
+  int total_behind = shards_behind.size() + (sync_status.sync_info.num_shards - num_inc);
+  if (total_behind == 0) {
+    status.push_back("metadata is caught up with master");
+  } else {
+    push_ss(ss, status) << "metadata is behind on " << total_behind << " shards";
+
+    map<int, rgw_mdlog_shard_data> master_pos;
+    ret = sync.read_master_log_shards_next(sync_status.sync_info.period, shards_behind, &master_pos);
+    if (ret < 0) {
+      derr << "ERROR: failed to fetch master next positions (" << cpp_strerror(-ret) << ")" << dendl;
+    } else {
+      ceph::real_time oldest;
+      for (auto iter : master_pos) {
+        rgw_mdlog_shard_data& shard_data = iter.second;
+
+        if (!shard_data.entries.empty()) {
+          rgw_mdlog_entry& entry = shard_data.entries.front();
+          if (ceph::real_clock::is_zero(oldest)) {
+            oldest = entry.timestamp;
+          } else if (!ceph::real_clock::is_zero(entry.timestamp) && entry.timestamp < oldest) {
+            oldest = entry.timestamp;
+          }
+        }
+      }
+
+      if (!ceph::real_clock::is_zero(oldest)) {
+        push_ss(ss, status) << "oldest incremental change not applied: " << oldest;
+      }
+    }
+  }
+
+  flush_ss(ss, status);
+}
+
+static void get_data_sync_status(const string& source_zone, list<string>& status, int tab)
+{
+  RGWDataSyncStatusManager sync(store, store->get_async_rados(), source_zone);
+
+  stringstream ss;
+
+  int ret = sync.init();
+  if (ret < 0) {
+    push_ss(ss, status, tab) << string("failed to retrieve sync info: ") + cpp_strerror(-ret);
+    flush_ss(ss, status);
+    return;
+  }
+
+  ret = sync.read_sync_status();
+  if (ret < 0) {
+    push_ss(ss, status, tab) << string("failed read sync status: ") + cpp_strerror(-ret);
+    return;
+  }
+
+  const rgw_data_sync_status& sync_status = sync.get_sync_status();
+
+  string status_str;
+  switch (sync_status.sync_info.state) {
+    case rgw_data_sync_info::StateInit:
+      status_str = "init";
+      break;
+    case rgw_data_sync_info::StateBuildingFullSyncMaps:
+      status_str = "preparing for full sync";
+      break;
+    case rgw_data_sync_info::StateSync:
+      status_str = "syncing";
+      break;
+    default:
+      status_str = "unknown";
+  }
+
+  push_ss(ss, status, tab) << status_str;
+  
+  uint64_t full_total = 0;
+  uint64_t full_complete = 0;
+
+  int num_full = 0;
+  int num_inc = 0;
+  int total_shards = 0;
+
+  for (auto marker_iter : sync_status.sync_markers) {
+    full_total += marker_iter.second.total_entries;
+    total_shards++;
+    if (marker_iter.second.state == rgw_data_sync_marker::SyncState::FullSync) {
+      num_full++;
+      full_complete += marker_iter.second.pos;
+    } else {
+      full_complete += marker_iter.second.total_entries;
+    }
+    if (marker_iter.second.state == rgw_data_sync_marker::SyncState::IncrementalSync) {
+      num_inc++;
+    }
+  }
+
+  push_ss(ss, status, tab) << "full sync: " << num_full << "/" << total_shards << " shards";
+
+  if (num_full > 0) {
+    push_ss(ss, status, tab) << "full sync: " << full_total - full_complete << " buckets to sync";
+  }
+
+  push_ss(ss, status, tab) << "incremental sync: " << num_inc << "/" << total_shards << " shards";
+
+  rgw_datalog_info log_info;
+  ret = sync.read_log_info(&log_info);
+  if (ret < 0) {
+    push_ss(ss, status, tab) << string("failed to fetch local sync status: ") + cpp_strerror(-ret);
+    return;
+  }
+
+
+  map<int, RGWDataChangesLogInfo> source_shards_info;
+
+  ret = sync.read_source_log_shards_info(&source_shards_info);
+  if (ret < 0) {
+    push_ss(ss, status, tab) << string("failed to fetch source sync status: ") + cpp_strerror(-ret);
+    return;
+  }
+
+  map<int, string> shards_behind;
+
+  for (auto local_iter : sync_status.sync_markers) {
+    int shard_id = local_iter.first;
+    auto iter = source_shards_info.find(shard_id);
+
+    if (iter == source_shards_info.end()) {
+      /* huh? */
+      derr << "ERROR: could not find remote sync shard status for shard_id=" << shard_id << dendl;
+      continue;
+    }
+    auto master_marker = iter->second.marker;
+    if (master_marker > local_iter.second.marker) {
+      shards_behind[shard_id] = local_iter.second.marker;
+    }
+  }
+
+  int total_behind = shards_behind.size() + (sync_status.sync_info.num_shards - num_inc);
+  if (total_behind == 0) {
+    push_ss(ss, status, tab) << "data is caught up with source";
+  } else {
+    push_ss(ss, status, tab) << "data is behind on " << total_behind << " shards";
+
+    map<int, rgw_datalog_shard_data> master_pos;
+    ret = sync.read_source_log_shards_next(shards_behind, &master_pos);
+    if (ret < 0) {
+      derr << "ERROR: failed to fetch next positions (" << cpp_strerror(-ret) << ")" << dendl;
+    } else {
+      ceph::real_time oldest;
+      for (auto iter : master_pos) {
+        rgw_datalog_shard_data& shard_data = iter.second;
+
+        if (!shard_data.entries.empty()) {
+          rgw_datalog_entry& entry = shard_data.entries.front();
+          if (ceph::real_clock::is_zero(oldest)) {
+            oldest = entry.timestamp;
+          } else if (!ceph::real_clock::is_zero(entry.timestamp) && entry.timestamp < oldest) {
+            oldest = entry.timestamp;
+          }
+        }
+      }
+
+      if (!ceph::real_clock::is_zero(oldest)) {
+        push_ss(ss, status, tab) << "oldest incremental change not applied: " << oldest;
+      }
+    }
+  }
+
+  flush_ss(ss, status);
+}
+
+static void tab_dump(const string& header, int width, const list<string>& entries)
+{
+  string s = header;
+
+  for (auto e : entries) {
+    cout << std::setw(width) << s << std::setw(1) << " " << e << std::endl;
+    s.clear();
+  }
+}
+
+
+static void sync_status(Formatter *formatter)
+{
+  RGWRealm& realm = store->realm;
+  RGWZoneGroup& zonegroup = store->get_zonegroup();
+  RGWZone& zone = store->get_zone();
+
+  int width = 15;
+
+  cout << std::setw(width) << "realm" << std::setw(1) << " " << realm.get_id() << " (" << realm.get_name() << ")" << std::endl;
+  cout << std::setw(width) << "zonegroup" << std::setw(1) << " " << zonegroup.get_id() << " (" << zonegroup.get_name() << ")" << std::endl;
+  cout << std::setw(width) << "zone" << std::setw(1) << " " << zone.id << " (" << zone.name << ")" << std::endl;
+
+  list<string> md_status;
+
+  if (zone.id == zonegroup.master_zone) {
+    md_status.push_back("no sync (zone is master)");
+  } else {
+    get_md_sync_status(md_status);
+  }
+
+  tab_dump("metadata sync", width, md_status);
+
+  list<string> data_status;
+
+  for (auto iter : store->zone_conn_map) {
+    const string& source_id = iter.first;
+    string zone_name;
+    string source_str = "source: ";
+    string s = source_str + source_id;
+    auto siter = store->zone_name_by_id.find(source_id);
+    if (siter != store->zone_name_by_id.end()) {
+      s += string(" (") + siter->second + ")";
+    }
+    data_status.push_back(s);
+    get_data_sync_status(source_id, data_status, source_str.size());
+  }
+
+  tab_dump("data sync", width, data_status);
+}
+
+int main(int argc, char **argv) 
+{
+  vector<const char*> args;
+  argv_to_vec(argc, (const char **)argv, args);
+  env_to_vec(args);
+
+  global_init(NULL, args, CEPH_ENTITY_TYPE_CLIENT, CODE_ENVIRONMENT_UTILITY, 0);
+  common_init_finish(g_ceph_context);
+
+  rgw_user user_id;
+  string tenant;
+  std::string access_key, secret_key, user_email, display_name;
+  std::string bucket_name, pool_name, object;
+  std::string date, subuser, access, format;
+  std::string start_date, end_date;
+  std::string key_type_str;
+  std::string period_id, period_epoch, remote, url, parent_period;
+  std::string master_zonegroup, master_zone;
+  std::string realm_name, realm_id, realm_new_name;
+  std::string zone_name, zone_id, zone_new_name;
+  std::string zonegroup_name, zonegroup_id, zonegroup_new_name;
+  std::string api_name;
+  list<string> endpoints;
+  std::string master_url;
+  int is_master_int;
+  int set_default = 0;
+  bool is_master = false;
+  bool is_master_set = false;
+  int read_only_int;
+  bool read_only = false;
+  int is_read_only_set = false;
+  int commit = false;
+  int staging = false;
+  int key_type = KEY_TYPE_UNDEFINED;
+  rgw_bucket bucket;
+  uint32_t perm_mask = 0;
+  RGWUserInfo info;
+  int opt_cmd = OPT_NO_CMD;
+  bool need_more;
+  int gen_access_key = 0;
+  int gen_secret_key = 0;
+  bool set_perm = false;
+  bool set_temp_url_key = false;
+  map<int, string> temp_url_keys;
+  string bucket_id;
+  Formatter *formatter = NULL;
+  int purge_data = false;
+  RGWBucketInfo bucket_info;
+  int pretty_format = false;
+  int show_log_entries = true;
+  int show_log_sum = true;
+  int skip_zero_entries = false;  // log show
+  int purge_keys = false;
+  int yes_i_really_mean_it = false;
+  int delete_child_objects = false;
+  int fix = false;
+  int remove_bad = false;
+  int check_head_obj_locator = false;
+  int max_buckets = -1;
+  map<string, bool> categories;
+  string caps;
+  int check_objects = false;
+  RGWUserAdminOpState user_op;
+  RGWBucketAdminOpState bucket_op;
+  string infile;
+  string metadata_key;
+  RGWObjVersionTracker objv_tracker;
+  string marker;
+  string start_marker;
+  string end_marker;
+  int max_entries = -1;
+  int system = false;
+  bool system_specified = false;
+  int shard_id = -1;
+  bool specified_shard_id = false;
+  string daemon_id;
+  bool specified_daemon_id = false;
+  string client_id;
+  string op_id;
+  string state_str;
+  string replica_log_type_str;
+  ReplicaLogType replica_log_type = ReplicaLog_Invalid;
+  string op_mask_str;
+  string quota_scope;
+  string object_version;
+
+  int64_t max_objects = -1;
+  int64_t max_size = -1;
+  bool have_max_objects = false;
+  bool have_max_size = false;
+  int include_all = false;
+
+  int sync_stats = false;
+  int reset_regions = false;
+
+  int extra_info = false;
+
+  uint64_t min_rewrite_size = 4 * 1024 * 1024;
+  uint64_t max_rewrite_size = ULLONG_MAX;
+  uint64_t min_rewrite_stripe_size = 0;
+
+  BIIndexType bi_index_type = PlainIdx;
+
+  string job_id;
+  int num_shards = 0;
+  int max_concurrent_ios = 32;
+  uint64_t orphan_stale_secs = (24 * 3600);
+
+  std::string val;
+  std::ostringstream errs;
+  string err;
+  long long tmp = 0;
+
+  string source_zone_name;
+  string source_zone; /* zone id */
+
+  for (std::vector<const char*>::iterator i = args.begin(); i != args.end(); ) {
+    if (ceph_argparse_double_dash(args, i)) {
+      break;
+    } else if (ceph_argparse_flag(args, i, "-h", "--help", (char*)NULL)) {
+      usage();
+      return 0;
+    } else if (ceph_argparse_witharg(args, i, &val, "-i", "--uid", (char*)NULL)) {
+      user_id.from_str(val);
+    } else if (ceph_argparse_witharg(args, i, &val, "--tenant", (char*)NULL)) {
+      tenant = val;
+    } else if (ceph_argparse_witharg(args, i, &val, "--access-key", (char*)NULL)) {
       access_key = val;
     } else if (ceph_argparse_witharg(args, i, &val, "--subuser", (char*)NULL)) {
       subuser = val;
@@ -1240,6 +2088,10 @@ int main(int argc, char **argv)
       // do nothing
     } else if (ceph_argparse_binary_flag(args, i, &system, NULL, "--system", (char*)NULL)) {
       system_specified = true;
+    } else if (ceph_argparse_binary_flag(args, i, &staging, NULL, "--staging", (char*)NULL)) {
+      // do nothing
+    } else if (ceph_argparse_binary_flag(args, i, &commit, NULL, "--commit", (char*)NULL)) {
+      // do nothing
     } else if (ceph_argparse_witharg(args, i, &tmp, errs, "-a", "--auth-uid", (char*)NULL)) {
       if (!errs.str().empty()) {
 	cerr << errs.str() << std::endl;
@@ -1363,6 +2215,9 @@ int main(int argc, char **argv)
      // do nothing
     } else if (ceph_argparse_binary_flag(args, i, &reset_regions, NULL, "--reset-regions", (char*)NULL)) {
      // do nothing
+    } else if (ceph_argparse_binary_flag(args, i, &extra_info, NULL, "--extra-info", (char*)NULL)) {
+     // do nothing
+    } else if (ceph_argparse_binary_flag(args, i, &reset_regions, NULL, "--reset-regions", (char*)NULL)) {
     } else if (ceph_argparse_witharg(args, i, &val, "--caps", (char*)NULL)) {
       caps = val;
     } else if (ceph_argparse_witharg(args, i, &val, "-i", "--infile", (char*)NULL)) {
@@ -1391,6 +2246,49 @@ int main(int argc, char **argv)
         cerr << "ERROR: invalid bucket index entry type" << std::endl;
         return EINVAL;
       }
+    } else if (ceph_argparse_witharg(args, i, &val, "--parent", (char*)NULL)) {
+      parent_period = val;
+    } else if (ceph_argparse_binary_flag(args, i, &is_master_int, NULL, "--master", (char*)NULL)) {
+      is_master = (bool)is_master_int;
+      is_master_set = true;
+    } else if (ceph_argparse_binary_flag(args, i, &set_default, NULL, "--default", (char*)NULL)) {
+      /* do nothing */
+    } else if (ceph_argparse_binary_flag(args, i, &read_only_int, NULL, "--read-only", (char*)NULL)) {
+      read_only = (bool)read_only_int;
+      is_read_only_set = true;
+    } else if (ceph_argparse_witharg(args, i, &val, "--master-url", (char*)NULL)) {
+      master_url = val;
+    } else if (ceph_argparse_witharg(args, i, &val, "--master-zonegroup", (char*)NULL)) {
+      master_zonegroup = val;
+    } else if (ceph_argparse_witharg(args, i, &val, "--master-zone", (char*)NULL)) {
+      master_zone = val;
+    } else if (ceph_argparse_witharg(args, i, &val, "--period", (char*)NULL)) {
+      period_id = val;
+    } else if (ceph_argparse_witharg(args, i, &val, "--epoch", (char*)NULL)) {
+      period_epoch = val;
+    } else if (ceph_argparse_witharg(args, i, &val, "--remote", (char*)NULL)) {
+      remote = val;
+    } else if (ceph_argparse_witharg(args, i, &val, "--url", (char*)NULL)) {
+      url = val;
+    } else if (ceph_argparse_witharg(args, i, &val, "--realm-id", (char*)NULL)) {
+      realm_id = val;
+    } else if (ceph_argparse_witharg(args, i, &val, "--realm-new-name", (char*)NULL)) {
+      realm_new_name = val;
+    } else if (ceph_argparse_witharg(args, i, &val, "--zonegroup-id", (char*)NULL)) {
+      zonegroup_id = val;
+    } else if (ceph_argparse_witharg(args, i, &val, "--zonegroup-new-name", (char*)NULL)) {
+      zonegroup_new_name = val;
+    } else if (ceph_argparse_witharg(args, i, &val, "--api-name", (char*)NULL)) {
+      api_name = val;
+    } else if (ceph_argparse_witharg(args, i, &val, "--zone-id", (char*)NULL)) {
+      zone_id = val;
+    } else if (ceph_argparse_witharg(args, i, &val, "--zone-new-name", (char*)NULL)) {
+      zone_new_name = val;
+    } else if (ceph_argparse_witharg(args, i, &val, "--endpoints", (char*)NULL)) {
+      list<string>::iterator iter;
+      get_str_list(val, endpoints);
+    } else if (ceph_argparse_witharg(args, i, &val, "--source-zone", (char*)NULL)) {
+      source_zone_name = val;
     } else if (strncmp(*i, "-", 1) == 0) {
       cerr << "ERROR: invalid flag " << *i << std::endl;
       return EINVAL;
@@ -1413,9 +2311,10 @@ int main(int argc, char **argv)
   }
   else {
     const char *prev_cmd = NULL;
+    const char *prev_prev_cmd = NULL;
     std::vector<const char*>::iterator i ;
     for (i = args.begin(); i != args.end(); ++i) {
-      opt_cmd = get_cmd(*i, prev_cmd, &need_more);
+      opt_cmd = get_cmd(*i, prev_cmd, prev_prev_cmd, &need_more);
       if (opt_cmd < 0) {
 	cerr << "unrecognized arg " << *i << std::endl;
 	return usage();
@@ -1424,6 +2323,7 @@ int main(int argc, char **argv)
 	++i;
 	break;
       }
+      prev_prev_cmd = prev_cmd;
       prev_cmd = *i;
     }
 
@@ -1470,229 +2370,1125 @@ int main(int argc, char **argv)
     return usage();
   }
 
-  RGWStreamFlusher f(formatter, cout);
+  realm_name = g_conf->rgw_realm;
+  zone_name = g_conf->rgw_zone;
+  zonegroup_name = g_conf->rgw_zonegroup;
 
-  bool raw_storage_op = (opt_cmd == OPT_REGION_GET || opt_cmd == OPT_REGION_LIST ||
-                         opt_cmd == OPT_REGION_SET || opt_cmd == OPT_REGION_DEFAULT ||
-                         opt_cmd == OPT_REGIONMAP_GET || opt_cmd == OPT_REGIONMAP_SET ||
-                         opt_cmd == OPT_REGIONMAP_UPDATE ||
-                         opt_cmd == OPT_ZONE_GET || opt_cmd == OPT_ZONE_SET ||
-                         opt_cmd == OPT_ZONE_LIST);
+  RGWStreamFlusher f(formatter, cout);
 
+  bool raw_storage_op = (opt_cmd == OPT_ZONEGROUP_ADD || opt_cmd == OPT_ZONEGROUP_CREATE || opt_cmd == OPT_ZONEGROUP_DELETE ||
+			 opt_cmd == OPT_ZONEGROUP_GET || opt_cmd == OPT_ZONEGROUP_LIST ||  
+                         opt_cmd == OPT_ZONEGROUP_SET || opt_cmd == OPT_ZONEGROUP_DEFAULT ||
+			 opt_cmd == OPT_ZONEGROUP_RENAME || opt_cmd == OPT_ZONEGROUP_MODIFY ||
+                         opt_cmd == OPT_ZONEGROUPMAP_GET || opt_cmd == OPT_ZONEGROUPMAP_SET ||
+                         opt_cmd == OPT_ZONEGROUPMAP_UPDATE ||
+			 opt_cmd == OPT_ZONE_CREATE || opt_cmd == OPT_ZONE_DELETE ||
+                         opt_cmd == OPT_ZONE_GET || opt_cmd == OPT_ZONE_SET || opt_cmd == OPT_ZONE_RENAME ||
+                         opt_cmd == OPT_ZONE_LIST || opt_cmd == OPT_ZONE_MODIFY || opt_cmd == OPT_ZONE_DEFAULT ||
+			 opt_cmd == OPT_REALM_CREATE || opt_cmd == OPT_PERIOD_PREPARE ||
+			 opt_cmd == OPT_PERIOD_DELETE || opt_cmd == OPT_PERIOD_GET ||
+			 opt_cmd == OPT_PERIOD_GET_CURRENT || opt_cmd == OPT_PERIOD_LIST ||
+			 (opt_cmd == OPT_PERIOD_UPDATE && !commit) ||
+			 opt_cmd == OPT_REALM_DELETE || opt_cmd == OPT_REALM_GET || opt_cmd == OPT_REALM_LIST ||
+			 opt_cmd == OPT_REALM_LIST_PERIODS ||
+			 opt_cmd == OPT_REALM_GET_DEFAULT || opt_cmd == OPT_REALM_REMOVE ||
+			 opt_cmd == OPT_REALM_RENAME || opt_cmd == OPT_REALM_SET ||
+			 opt_cmd == OPT_REALM_DEFAULT || opt_cmd == OPT_REALM_PULL);
 
   if (raw_storage_op) {
     store = RGWStoreManager::get_raw_storage(g_ceph_context);
   } else {
-    store = RGWStoreManager::get_storage(g_ceph_context, false, false);
+    store = RGWStoreManager::get_storage(g_ceph_context, false, false, false);
   }
   if (!store) {
     cerr << "couldn't init storage provider" << std::endl;
     return 5; //EIO
   }
 
+  if (!source_zone_name.empty()) {
+    if (!store->find_zone_id_by_name(source_zone_name, &source_zone)) {
+      cerr << "WARNING: cannot find source zone id for name=" << source_zone_name << std::endl;
+      source_zone = source_zone_name;
+    }
+  }
+
   rgw_user_init(store);
   rgw_bucket_init(store->meta_mgr);
 
   StoreDestructor store_destructor(store);
 
   if (raw_storage_op) {
-    if (opt_cmd == OPT_REGION_GET) {
-      RGWRegion region;
-      int ret = region.init(g_ceph_context, store);
-      if (ret < 0) {
-        cerr << "failed to init region: " << cpp_strerror(-ret) << std::endl;
-	return -ret;
-      }
-
-      encode_json("region", region, formatter);
-      formatter->flush(cout);
-      cout << std::endl;
-    }
-    if (opt_cmd == OPT_REGION_LIST) {
-      RGWRegion region;
-      int ret = region.init(g_ceph_context, store, false);
-      if (ret < 0) {
-	cerr << "failed to init region: " << cpp_strerror(-ret) << std::endl;
-	return -ret;
+    switch (opt_cmd) {
+    case OPT_PERIOD_PREPARE:
+      {
+	RGWRealm realm(realm_id, realm_name);
+	int ret = realm.init(g_ceph_context, store);
+	if (ret < 0) {
+	  cerr << "could not init realm " << ": " << cpp_strerror(-ret) << std::endl;
+	  return ret;
+	}
+	RGWPeriod period;
+	ret = period.init(g_ceph_context, store, realm.get_id(), realm.get_name(), false);
+	if (ret < 0) {
+	  cerr << "failed to init period " << ": " << cpp_strerror(-ret) << std::endl;
+	  return ret;
+	}
+	ret = period.create();
+	if (ret < 0) {
+	  cerr << "ERROR: couldn't create period " << ": " << cpp_strerror(-ret) << std::endl;
+	  return ret;
+	}
+	encode_json("period", period, formatter);
+	formatter->flush(cout);
       }
+      break;
+    case OPT_PERIOD_DELETE:
+      {
+	if (period_id.empty()) {
+	  cerr << "missing realm name or id" << std::endl;
+	  return -EINVAL;
+	}
+	RGWPeriod period(period_id);
+	int ret = period.init(g_ceph_context, store);
+	if (ret < 0) {
+	  cerr << "period.init failed: " << cpp_strerror(-ret) << std::endl;
+	  return -ret;
+	}
+	ret = period.delete_obj();
+	if (ret < 0) {
+	  cerr << "ERROR: couldn't delete period: " << cpp_strerror(-ret) << std::endl;
+	  return ret;
+	}
 
-      list<string> regions;
-      ret = store->list_regions(regions);
-      if (ret < 0) {
-        cerr << "failed to list regions: " << cpp_strerror(-ret) << std::endl;
-	return -ret;
       }
-      RGWDefaultRegionInfo default_region;
-      ret = region.read_default(default_region);
-      if (ret < 0 && ret != -ENOENT) {
-	cerr << "could not determine default region: " << cpp_strerror(-ret) << std::endl;
+      break;
+    case OPT_PERIOD_GET:
+      {
+	epoch_t epoch = 0;
+	if (!period_epoch.empty()) {
+	  epoch = atoi(period_epoch.c_str());
+	}
+        if (staging) {
+          RGWRealm realm(realm_id, realm_name);
+          int ret = realm.init(g_ceph_context, store);
+          if (ret < 0 ) {
+            cerr << "Error initializing realm " << cpp_strerror(-ret) << std::endl;
+            return ret;
+          }
+          realm_id = realm.get_id();
+          realm_name = realm.get_name();
+          period_id = RGWPeriod::get_staging_id(realm_id);
+          epoch = 1;
+        }
+	RGWPeriod period(period_id, epoch);
+	int ret = period.init(g_ceph_context, store, realm_id, realm_name);
+	if (ret < 0) {
+	  cerr << "period init failed: " << cpp_strerror(-ret) << std::endl;
+	  return -ret;
+	}
+	encode_json("period", period, formatter);
+	formatter->flush(cout);
+	cout << std::endl;
       }
-      formatter->open_object_section("regions_list");
-      encode_json("default_info", default_region, formatter);
-      encode_json("regions", regions, formatter);
-      formatter->close_section();
-      formatter->flush(cout);
-      cout << std::endl;
-    }
-    if (opt_cmd == OPT_REGION_SET) {
-      RGWRegion region;
-      int ret = region.init(g_ceph_context, store, false);
-      if (ret < 0) {
-	cerr << "failed to init region: " << cpp_strerror(-ret) << std::endl;
-	return -ret;
+      break;
+    case OPT_PERIOD_GET_CURRENT:
+      {
+        int ret = read_current_period_id(store, realm_id, realm_name, &period_id);
+	if (ret < 0) {
+	  return ret;
+	}
+	formatter->open_object_section("period_get_current");
+	encode_json("current_period", period_id, formatter);
+	formatter->close_section();
+	formatter->flush(cout);
       }
-      ret = read_decode_json(infile, region);
-      if (ret < 0) {
-        return 1;
+      break;
+    case OPT_PERIOD_LIST:
+      {
+	list<string> periods;
+	int ret = store->list_periods(periods);
+	if (ret < 0) {
+	  cerr << "failed to list periods: " << cpp_strerror(-ret) << std::endl;
+	  return -ret;
+	}
+	formatter->open_object_section("periods_list");
+	encode_json("periods", periods, formatter);
+	formatter->close_section();
+	formatter->flush(cout);
+	cout << std::endl;
+      }
+      break;
+    case OPT_PERIOD_UPDATE:
+      {
+        int ret = update_period(realm_id, realm_name, period_id, period_epoch,
+                                commit, remote, url, access_key, secret_key,
+                                formatter);
+	if (ret < 0) {
+          cerr << "period update failed: " << cpp_strerror(-ret) << std::endl;
+	  return ret;
+	}
       }
+      break;
+    case OPT_REALM_CREATE:
+      {
+	if (realm_name.empty()) {
+	  cerr << "missing realm name" << std::endl;
+	  return -EINVAL;
+	}
 
-      ret = region.store_info(false);
-      if (ret < 0) {
-        cerr << "ERROR: couldn't store zone info: " << cpp_strerror(-ret) << std::endl;
-        return 1;
+	RGWRealm realm(realm_name, g_ceph_context, store);
+	int ret = realm.create();
+	if (ret < 0) {
+	  cerr << "ERROR: couldn't create realm " << realm_name << ": " << cpp_strerror(-ret) << std::endl;
+	  return ret;
+	}
+
+        if (set_default) {
+          ret = realm.set_as_default();
+          if (ret < 0) {
+            cerr << "failed to set realm " << realm_name << " as default: " << cpp_strerror(-ret) << std::endl;
+          }
+        }
+
+	encode_json("realm", realm, formatter);
+	formatter->flush(cout);
+	cout << std::endl;
       }
+      break;
+    case OPT_REALM_DELETE:
+      {
+	RGWRealm realm(realm_id, realm_name);
+	if (realm_name.empty() && realm_id.empty()) {
+	  cerr << "missing realm name or id" << std::endl;
+	  return -EINVAL;
+	}
+	int ret = realm.init(g_ceph_context, store);
+	if (ret < 0) {
+	  cerr << "realm.init failed: " << cpp_strerror(-ret) << std::endl;
+	  return -ret;
+	}
+	ret = realm.delete_obj();
+	if (ret < 0) {
+	  cerr << "ERROR: couldn't : " << cpp_strerror(-ret) << std::endl;
+	  return ret;
+	}
 
-      encode_json("region", region, formatter);
-      formatter->flush(cout);
-    }
-    if (opt_cmd == OPT_REGION_DEFAULT) {
-      RGWRegion region;
-      int ret = region.init(g_ceph_context, store);
-      if (ret < 0) {
-	cerr << "failed to init region: " << cpp_strerror(-ret) << std::endl;
-	return -ret;
       }
+      break;
+    case OPT_REALM_GET:
+      {
+	RGWRealm realm(realm_id, realm_name);
+	int ret = realm.init(g_ceph_context, store);
+	if (ret < 0) {
+	  if (ret == -ENOENT && realm_name.empty() && realm_id.empty()) {
+	    cerr << "missing realm name or id, or default realm not found" << std::endl;
+	  } else {
+	    cerr << "realm.init failed: " << cpp_strerror(-ret) << std::endl;
+          }
+	  return -ret;
+	}
+	encode_json("realm", realm, formatter);
+	formatter->flush(cout);
+	cout << std::endl;
+      }
+      break;
+    case OPT_REALM_GET_DEFAULT:
+      {
+	RGWRealm realm(g_ceph_context, store);
+	string default_id;
+	int ret = realm.read_default_id(default_id);
+	if (ret == -ENOENT) {
+	  cout << "No default realm is set" << std::endl;
+	  return ret;
+	} else if (ret < 0) {
+	  cerr << "Error reading default realm:" << cpp_strerror(-ret) << std::endl;
+	  return ret;
+	}
+	cout << "default realm: " << default_id << std::endl;
+      }
+      break;
+    case OPT_REALM_LIST:
+      {
+	RGWRealm realm(g_ceph_context, store);
+	string default_id;
+	int ret = realm.read_default_id(default_id);
+	if (ret < 0 && ret != -ENOENT) {
+	  cerr << "could not determine default realm: " << cpp_strerror(-ret) << std::endl;
+	}
+	list<string> realms;
+	ret = store->list_realms(realms);
+	if (ret < 0) {
+	  cerr << "failed to list realmss: " << cpp_strerror(-ret) << std::endl;
+	  return -ret;
+	}
+	formatter->open_object_section("realmss_list");
+	encode_json("default_info", default_id, formatter);
+	encode_json("realms", realms, formatter);
+	formatter->close_section();
+	formatter->flush(cout);
+	cout << std::endl;
+      }
+      break;
+    case OPT_REALM_LIST_PERIODS:
+      {
+        int ret = read_current_period_id(store, realm_id, realm_name, &period_id);
+	if (ret < 0) {
+	  return -ret;
+	}
+	list<string> periods;
+	ret = store->list_periods(period_id, periods);
+	if (ret < 0) {
+	  cerr << "list periods failed: " << cpp_strerror(-ret) << std::endl;
+	  return -ret;
+	}	
+	formatter->open_object_section("realm_periods_list");
+	encode_json("current_period", period_id, formatter);
+	encode_json("periods", periods, formatter);
+	formatter->close_section();
+	formatter->flush(cout);
+	cout << std::endl;
+      }
+      break;
 
-      ret = region.set_as_default();
-      if (ret < 0) {
-	cerr << "failed to set region as default: " << cpp_strerror(-ret) << std::endl;
-	return -ret;
+    case OPT_REALM_RENAME:
+      {
+	RGWRealm realm(realm_id, realm_name);
+	if (realm_new_name.empty()) {
+	  cerr << "missing realm new name" << std::endl;
+	  return -EINVAL;
+	}
+	if (realm_name.empty() && realm_id.empty()) {
+	  cerr << "missing realm name or id" << std::endl;
+	  return -EINVAL;
+	}
+	int ret = realm.init(g_ceph_context, store);
+	if (ret < 0) {
+	  cerr << "realm.init failed: " << cpp_strerror(-ret) << std::endl;
+	  return -ret;
+	}
+	ret = realm.rename(realm_new_name);
+	if (ret < 0) {
+	  cerr << "realm.rename failed: " << cpp_strerror(-ret) << std::endl;
+	  return -ret;
+	}
       }
-    }
+      break;
+    case OPT_REALM_SET:
+      {
+	if (realm_id.empty() && realm_name.empty()) {
+	  cerr << "no realm name or id provided" << std::endl;
+	  return -EINVAL;
+	}
+        if (infile.empty()) {
+	  cerr << "no realm input file provided" << std::endl;
+	  return -EINVAL;
+        }
+	RGWRealm realm(realm_id, realm_name);
+	int ret = realm.init(g_ceph_context, store, false);
+	if (ret < 0) {
+	  cerr << "failed to init realm: " << cpp_strerror(-ret) << std::endl;
+	  return -ret;
+	}
+	ret = read_decode_json(infile, realm);
+	if (ret < 0) {
+	  return 1;
+	}
+	ret = realm.update();
+	if (ret < 0) {
+	  cerr << "ERROR: couldn't store realm info: " << cpp_strerror(-ret) << std::endl;
+	  return 1;
+	}
 
-    if (opt_cmd == OPT_REGIONMAP_GET) {
-      RGWRegionMap regionmap;
-      int ret = regionmap.read(g_ceph_context, store);
-      if (ret < 0) {
-	cerr << "failed to read region map: " << cpp_strerror(-ret) << std::endl;
-	return -ret;
+        if (set_default) {
+          ret = realm.set_as_default();
+          if (ret < 0) {
+            cerr << "failed to set realm " << realm_name << " as default: " << cpp_strerror(-ret) << std::endl;
+          }
+        }
+	encode_json("realm", realm, formatter);
+	formatter->flush(cout);
       }
-      encode_json("region-map", regionmap, formatter);
-      formatter->flush(cout);
-    }
+      break;
 
-    if (opt_cmd == OPT_REGIONMAP_SET) {
-      RGWRegionMap regionmap;
-      int ret = read_decode_json(infile, regionmap);
-      if (ret < 0) {
-        return 1;
+    case OPT_REALM_DEFAULT:
+      {
+	RGWRealm realm(realm_id, realm_name);
+	int ret = realm.init(g_ceph_context, store);
+	if (ret < 0) {
+	  cerr << "failed to init realm: " << cpp_strerror(-ret) << std::endl;
+	  return -ret;
+	}
+	ret = realm.set_as_default();
+	if (ret < 0) {
+	  cerr << "failed to set realm as default: " << cpp_strerror(-ret) << std::endl;
+	  return -ret;
+	}
       }
+      break;
+    case OPT_REALM_PULL:
+      {
+        RGWEnv env;
+        req_info info(g_ceph_context, &env);
+        info.method = "GET";
+        info.request_uri = "/admin/realm";
+
+        map<string, string> &params = info.args.get_params();
+        if (!realm_id.empty())
+          params["id"] = realm_id;
+        if (!realm_name.empty())
+          params["name"] = realm_name;
+
+        bufferlist bl;
+        JSONParser p;
+        int ret = send_to_remote_or_url(remote, url, access_key, secret_key,
+                                        info, bl, p);
+        if (ret < 0) {
+          cerr << "request failed: " << cpp_strerror(-ret) << std::endl;
+          return ret;
+        }
+        RGWRealm realm;
+        realm.init(g_ceph_context, store, false);
+        try {
+          decode_json_obj(realm, &p);
+        } catch (JSONDecoder::err& e) {
+          cerr << "failed to decode JSON response: " << e.message << std::endl;
+          return -EINVAL;
+        }
+        RGWPeriod period;
+        auto& current_period = realm.get_current_period();
+        if (!current_period.empty()) {
+          // pull the latest epoch of the realm's current period
+          ret = do_period_pull(remote, url, access_key, secret_key,
+                               realm_id, realm_name, current_period, "",
+                               &period);
+          if (ret < 0) {
+            cerr << "could not fetch period " << current_period << std::endl;
+            return -ret;
+          }
+        }
+        ret = realm.create(false);
+        if (ret < 0 && ret != -EEXIST) {
+          cerr << "Error storing realm " << realm.get_id() << ": "
+            << cpp_strerror(ret) << std::endl;
+          return ret;
+        } else if (ret ==-EEXIST) {
+	  ret = realm.update();
+	  if (ret < 0) {
+	    cerr << "Error storing realm " << realm.get_id() << ": "
+		 << cpp_strerror(ret) << std::endl;
+	  }
+	}
 
-      ret = regionmap.store(g_ceph_context, store);
-      if (ret < 0) {
-        cerr << "ERROR: couldn't store region map info: " << cpp_strerror(-ret) << std::endl;
-        return 1;
+        if (set_default) {
+          ret = realm.set_as_default();
+          if (ret < 0) {
+            cerr << "failed to set realm " << realm_name << " as default: " << cpp_strerror(-ret) << std::endl;
+          }
+        }
+
+        encode_json("realm", realm, formatter);
+        formatter->flush(cout);
+        cout << std::endl;
       }
+      return 0;
 
-      encode_json("region-map", regionmap, formatter);
-      formatter->flush(cout);
-    }
+    case OPT_ZONEGROUP_ADD:
+      {
+	if (zonegroup_id.empty() && zonegroup_name.empty()) {
+	  cerr << "no zonegroup name or id provided" << std::endl;
+	  return -EINVAL;
+	}
 
-    if (opt_cmd == OPT_REGIONMAP_UPDATE) {
-      RGWRegionMap regionmap;
-      int ret = regionmap.read(g_ceph_context, store);
-      if (ret < 0 && ret != -ENOENT) {
-	cerr << "failed to read region map: " << cpp_strerror(-ret) << std::endl;
-	return -ret;
+	RGWZoneGroup zonegroup(zonegroup_id,zonegroup_name);
+	int ret = zonegroup.init(g_ceph_context, store);
+	if (ret < 0) {
+	  cerr << "failed to initialize zonegroup " << zonegroup_name << " id " << zonegroup_id << " :"
+	       << cpp_strerror(-ret) << std::endl;
+	  return ret;
+	}
+	RGWZoneParams zone(zone_id, zone_name);
+	ret = zone.init(g_ceph_context, store);
+	if (ret < 0) {
+	  cerr << "unable to initialize zone: " << cpp_strerror(-ret) << std::endl;
+	  return -ret;
+	}
+        ret = zonegroup.add_zone(zone,
+                                 (is_master_set ? &is_master : NULL),
+                                 (is_read_only_set ? &read_only : NULL),
+                                 endpoints);
+	if (ret < 0) {
+	  cerr << "failed to add zone " << zone_name << " to zonegroup " << zonegroup.get_name() << ": "
+	       << cpp_strerror(-ret) << std::endl;
+	  return ret;
+	}
       }
+      break;
+    case OPT_ZONEGROUP_CREATE:
+      {
+	if (zonegroup_name.empty()) {
+	  cerr << "Missing zonegroup name" << std::endl;
+	  return -EINVAL;
+	}
+	RGWRealm realm(realm_id, realm_name);
+	int ret = realm.init(g_ceph_context, store);
+	if (ret < 0) {
+	  cerr << "failed to init realm: " << cpp_strerror(-ret) << std::endl;
+	  return -ret;
+	}
 
-      RGWRegion region;
-      ret = region.init(g_ceph_context, store, false);
-      if (ret < 0) {
-	cerr << "failed to init region: " << cpp_strerror(-ret) << std::endl;
-	return -ret;
+	RGWZoneGroup zonegroup(zonegroup_name, is_master, g_ceph_context, store, realm.get_id(), endpoints);
+        zonegroup.api_name = (api_name.empty() ? zonegroup_name : api_name);
+	ret = zonegroup.create();
+	if (ret < 0) {
+	  cerr << "failed to create zonegroup " << zonegroup_name << ": " << cpp_strerror(-ret) << std::endl;
+	  return -ret;
+	}
+
+        if (set_default) {
+          ret = zonegroup.set_as_default();
+          if (ret < 0) {
+            cerr << "failed to set zonegroup " << zonegroup_name << " as default: " << cpp_strerror(-ret) << std::endl;
+          }
+        }
+
+	encode_json("zonegroup", zonegroup, formatter);
+	formatter->flush(cout);
+	cout << std::endl;
+      }
+      break;
+    case OPT_ZONEGROUP_DEFAULT:
+      {
+	if (zonegroup_id.empty() && zonegroup_name.empty()) {
+	  cerr << "no zonegroup name or id provided" << std::endl;
+	  return -EINVAL;
+	}
+
+	RGWZoneGroup zonegroup(zonegroup_id, zonegroup_name);
+	int ret = zonegroup.init(g_ceph_context, store);
+	if (ret < 0) {
+	  cerr << "failed to init zonegroup: " << cpp_strerror(-ret) << std::endl;
+	  return -ret;
+	}
+
+	ret = zonegroup.set_as_default();
+	if (ret < 0) {
+	  cerr << "failed to set zonegroup as default: " << cpp_strerror(-ret) << std::endl;
+	  return -ret;
+	}
+      }
+      break;
+    case OPT_ZONEGROUP_DELETE:
+      {
+	if (zonegroup_id.empty() && zonegroup_name.empty()) {
+	  cerr << "no zonegroup name or id provided" << std::endl;
+	  return -EINVAL;
+	}
+	RGWZoneGroup zonegroup(zonegroup_id, zonegroup_name);
+	int ret = zonegroup.init(g_ceph_context, store);
+	if (ret < 0) {
+	  cerr << "failed to init zonegroup: " << cpp_strerror(-ret) << std::endl;
+	  return -ret;
+	}
+	ret = zonegroup.delete_obj();
+	if (ret < 0) {
+	  cerr << "ERROR: couldn't delete zonegroup: " << cpp_strerror(-ret) << std::endl;
+	  return ret;
+	}
       }
+      break;
+    case OPT_ZONEGROUP_GET:
+      {
+	RGWZoneGroup zonegroup(zonegroup_id, zonegroup_name);
+	int ret = zonegroup.init(g_ceph_context, store);
+	if (ret < 0) {
+	  cerr << "failed to init zonegroup: " << cpp_strerror(-ret) << std::endl;
+	  return -ret;
+	}
 
-      list<string> regions;
-      ret = store->list_regions(regions);
-      if (ret < 0) {
-        cerr << "failed to list regions: " << cpp_strerror(-ret) << std::endl;
-	return -ret;
+	encode_json("zonegroup", zonegroup, formatter);
+	formatter->flush(cout);
+	cout << std::endl;
       }
+      break;
+    case OPT_ZONEGROUP_LIST:
+      {
+	RGWZoneGroup zonegroup;
+	int ret = zonegroup.init(g_ceph_context, store, false);
+	if (ret < 0) {
+	  cerr << "failed to init zonegroup: " << cpp_strerror(-ret) << std::endl;
+	  return -ret;
+	}
 
-      if (reset_regions) {
-        regionmap.regions.clear();
+	list<string> zonegroups;
+	ret = store->list_zonegroups(zonegroups);
+	if (ret < 0) {
+	  cerr << "failed to list zonegroups: " << cpp_strerror(-ret) << std::endl;
+	  return -ret;
+	}
+	string default_zonegroup;
+	ret = zonegroup.read_default_id(default_zonegroup);
+	cout << "read_default_id : " << ret << std::endl;
+	if (ret < 0 && ret != -ENOENT) {
+	  cerr << "could not determine default zonegroup: " << cpp_strerror(-ret) << std::endl;
+	}
+	formatter->open_object_section("zonegroups_list");
+	encode_json("default_info", default_zonegroup, formatter);
+	encode_json("zonegroups", zonegroups, formatter);
+	formatter->close_section();
+	formatter->flush(cout);
+	cout << std::endl;
       }
+      break;
+    case OPT_ZONEGROUP_MODIFY:
+      {
+	RGWRealm realm(realm_id, realm_name);
+	int ret = realm.init(g_ceph_context, store);
+	if (ret < 0) {
+	  cerr << "failed to init realm: " << cpp_strerror(-ret) << std::endl;
+	  return -ret;
+	}
 
-      for (list<string>::iterator iter = regions.begin(); iter != regions.end(); ++iter) {
-        ret = region.read_info(*iter);
-        if (ret < 0) {
-        cerr << "failed to read region info (name=" << *iter << "): " << cpp_strerror(-ret) << std::endl;
-	return -ret;
+	RGWZoneGroup zonegroup(zonegroup_id, zonegroup_name);
+	ret = zonegroup.init(g_ceph_context, store);
+	if (ret < 0) {
+	  cerr << "failed to init zonegroup: " << cpp_strerror(-ret) << std::endl;
+	  return -ret;
+	}
+
+        bool need_update = false;
+
+        if (!master_zone.empty()) {
+          zonegroup.master_zone = master_zone;
+          need_update = true;
+        }
+
+	if (is_master_set) {
+	  zonegroup.update_master(is_master);
+          need_update = true;
+        }
+
+        if (!endpoints.empty()) {
+          zonegroup.endpoints = endpoints;
+          need_update = true;
+        }
+
+        if (!api_name.empty()) {
+          zonegroup.api_name = api_name;
+          need_update = true;
+        }
+
+        if (need_update) {
+          zonegroup.post_process_params();
+	  ret = zonegroup.update();
+	  if (ret < 0) {
+	    cerr << "failed to update zonegroup: " << cpp_strerror(-ret) << std::endl;
+	    return -ret;
+	  }
+	}
+
+        if (set_default) {
+          ret = zonegroup.set_as_default();
+          if (ret < 0) {
+            cerr << "failed to set zonegroup " << zonegroup_name << " as default: " << cpp_strerror(-ret) << std::endl;
+          }
         }
-        regionmap.update(region);
       }
+      break;
+    case OPT_ZONEGROUP_SET:
+      {
+	RGWRealm realm(realm_id, realm_name);
+	int ret = realm.init(g_ceph_context, store);
+	if (ret < 0) {
+	  cerr << "failed to init realm: " << cpp_strerror(-ret) << std::endl;
+	  return -ret;
+	}
 
-      ret = regionmap.store(g_ceph_context, store);
-      if (ret < 0) {
-        cerr << "ERROR: couldn't store region map info: " << cpp_strerror(-ret) << std::endl;
-        return 1;
+	RGWZoneGroup zonegroup;
+	ret = zonegroup.init(g_ceph_context, store, false);
+	if (ret < 0) {
+	  cerr << "failed to init zonegroup: " << cpp_strerror(-ret) << std::endl;
+	  return -ret;
+	}
+	ret = read_decode_json(infile, zonegroup);
+	if (ret < 0) {
+	  return 1;
+	}
+	if (zonegroup.realm_id.empty()) {
+	  zonegroup.realm_id = realm.get_id();
+	}
+	ret = zonegroup.create();
+	if (ret < 0 && ret != -EEXIST) {
+	  cerr << "ERROR: couldn't create zonegroup info: " << cpp_strerror(-ret) << std::endl;
+	  return 1;
+	} else if (ret == -EEXIST) {
+	  ret = zonegroup.update();
+	  if (ret < 0) {
+	    cerr << "ERROR: couldn't store zonegroup info: " << cpp_strerror(-ret) << std::endl;
+	    return 1;
+	  }
+	}
+
+        if (set_default) {
+          ret = zonegroup.set_as_default();
+          if (ret < 0) {
+            cerr << "failed to set zonegroup " << zonegroup_name << " as default: " << cpp_strerror(-ret) << std::endl;
+          }
+        }
+
+	encode_json("zonegroup", zonegroup, formatter);
+	formatter->flush(cout);
+      }
+      break;
+    case OPT_ZONEGROUP_RENAME:
+      {
+	if (zonegroup_new_name.empty()) {
+	  cerr << " missing zonegroup new name" << std::endl;
+	  return -EINVAL;
+	}
+	if (zonegroup_id.empty() && zonegroup_name.empty()) {
+	  cerr << "no zonegroup name or id provided" << std::endl;
+	  return -EINVAL;
+	}
+	RGWZoneGroup zonegroup(zonegroup_id, zonegroup_name);
+	int ret = zonegroup.init(g_ceph_context, store);
+	if (ret < 0) {
+	  cerr << "failed to init zonegroup: " << cpp_strerror(-ret) << std::endl;
+	  return -ret;
+	}
+	ret = zonegroup.rename(zonegroup_new_name);
+	if (ret < 0) {
+	  cerr << "failed to rename zonegroup: " << cpp_strerror(-ret) << std::endl;
+	  return -ret;
+	}
       }
+      break;
+    case OPT_ZONEGROUPMAP_GET:
+      {
+	RGWZoneGroupMap zonegroupmap;
 
-      encode_json("region-map", regionmap, formatter);
-      formatter->flush(cout);
-    }
+	int ret = zonegroupmap.read(g_ceph_context, store);
+	if (ret < 0 && ret != -ENOENT) {
+	  cerr << "failed to read zonegroupmap info: " << cpp_strerror(ret);
+	  return ret;
+	}
+		
+	encode_json("zonegroup-map", zonegroupmap, formatter);
+	formatter->flush(cout);
+      }
+      break;
+    case OPT_ZONEGROUPMAP_SET:
+      {
+	RGWZoneGroupMap zonegroupmap;
+	int ret = read_decode_json(infile, zonegroupmap);
+	if (ret < 0) {
+	  cerr << "ERROR: failed to read map json: " << cpp_strerror(-ret) << std::endl;
+	  return ret;
+	}
 
-    if (opt_cmd == OPT_ZONE_GET) {
-      RGWRegion region;
-      int ret = region.init(g_ceph_context, store);
-      if (ret < 0) {
-        cerr << "WARNING: failed to initialize region" << std::endl;
+	RGWPeriod period;
+	ret = period.init(g_ceph_context, store);
+	if (ret < 0) {
+	  cerr << "ERROR: failed to read current period info: " << cpp_strerror(-ret) << std::endl;
+	  return ret;
+	}
+
+	period.fork();
+	period.update(zonegroupmap);
+	period.store_info(false);
+
+	encode_json("zonegroup-map", zonegroupmap, formatter);
+	formatter->flush(cout);
       }
-      RGWZoneParams zone;
-      ret = zone.init(g_ceph_context, store, region);
-      if (ret < 0) {
-	cerr << "unable to initialize zone: " << cpp_strerror(-ret) << std::endl;
-	return -ret;
+      break;
+    case OPT_ZONEGROUPMAP_UPDATE:
+      {
+	RGWZoneGroupMap zonegroupmap;
+	int ret = zonegroupmap.read(g_ceph_context, store);
+	if (ret < 0 && ret != -ENOENT) {
+	  cerr << "failed to read zonegroup map: " << cpp_strerror(-ret) << std::endl;
+	  return -ret;
+	}
+
+	if (reset_regions) {
+          zonegroupmap.zonegroups.clear();
+        }
+
+	list<string> realms;
+	ret = store->list_realms(realms);
+	if (ret < 0) {
+	  cerr << "failed to list realms: " << cpp_strerror(-ret) << std::endl;
+	  return -ret;
+	}
+
+	for (list<string>::iterator iter = realms.begin(); iter != realms.end(); ++iter)
+	{
+	  RGWRealm realm("", *iter);
+	  ret = realm.init(g_ceph_context, store);
+	  if (ret < 0) {
+	    cerr << "failed to init realm: " << cpp_strerror(-ret) << std::endl;
+	    return -ret;
+	  }
+	}
+
+	encode_json("zonegroup-map", zonegroupmap, formatter);
+	formatter->flush(cout);
       }
-      encode_json("zone", zone, formatter);
-      formatter->flush(cout);
-    }
+      break;
+    case OPT_ZONE_CREATE:
+      {
+        if (zone_name.empty()) {
+	  cerr << "zone name not provided" << std::endl;
+	  return -EINVAL;
+        }
+	int ret;
+	RGWZoneGroup zonegroup(zonegroup_id, zonegroup_name);
+	/* if the user didn't provide zonegroup info , create stand alone zone */
+	if (!zonegroup_id.empty() || !zonegroup_name.empty()) {
+	  ret = zonegroup.init(g_ceph_context, store);
+	  if (ret < 0) {
+	    cerr << "unable to initialize zonegroup " << zonegroup_name << ": " << cpp_strerror(-ret) << std::endl;
+	    return ret;
+	  }
+	  if (realm_id.empty() && realm_name.empty()) {
+	    realm_id = zonegroup.realm_id;
+	  }
+	}
 
-    if (opt_cmd == OPT_ZONE_SET) {
-      RGWRegion region;
-      int ret = region.init(g_ceph_context, store);
-      if (ret < 0) {
-        cerr << "WARNING: failed to initialize region" << std::endl;
+	RGWZoneParams zone(zone_name);
+	ret = zone.init(g_ceph_context, store, false);
+	if (ret < 0) {
+	  cerr << "unable to initialize zone: " << cpp_strerror(-ret) << std::endl;
+	  return -ret;
+	}
+
+        zone.system_key.id = access_key;
+        zone.system_key.key = secret_key;
+	zone.realm_id = realm_id;
+
+	ret = zone.create();
+	if (ret < 0) {
+	  cerr << "failed to create zone " << zone_name << ": " << cpp_strerror(-ret) << std::endl;
+	  return ret;
+	}
+
+	if (!zonegroup_id.empty() || !zonegroup_name.empty()) {
+	  RGWRealm realm(realm_id, realm_name);
+	  ret = realm.init(g_ceph_context, store);
+	  if (ret < 0) {
+	    cerr << "ERROR: couldn't init realm:" << cpp_strerror(-ret) << std::endl;
+	    return ret;
+	  }
+	  ret = zonegroup.add_zone(zone,
+                                   (is_master_set ? &is_master : NULL),
+                                   (is_read_only_set ? &read_only : NULL),
+                                   endpoints);
+	  if (ret < 0) {
+	    cerr << "failed to add zone " << zone_name << " to zonegroup " << zonegroup.get_name()
+		 << ": " << cpp_strerror(-ret) << std::endl;
+	    return ret;
+	  }
+	}
+
+        if (set_default) {
+          ret = zone.set_as_default();
+          if (ret < 0) {
+            cerr << "failed to set zone " << zone_name << " as default: " << cpp_strerror(-ret) << std::endl;
+          }
+        }
+
+	encode_json("zone", zone, formatter);
+	formatter->flush(cout);
+	cout << std::endl;
       }
-      RGWZoneParams zone;
-      zone.init_default(store);
-      ret = read_decode_json(infile, zone);
-      if (ret < 0) {
-        return 1;
+      break;
+    case OPT_ZONE_DEFAULT:
+      {
+	RGWZoneGroup zonegroup(zonegroup_id,zonegroup_name);
+	int ret = zonegroup.init(g_ceph_context, store);
+	if (ret < 0) {
+	  cerr << "WARNING: failed to initialize zonegroup " << zonegroup_name << std::endl;
+	}
+	if (zone_id.empty() && zone_name.empty()) {
+	  cerr << "no zone name or id provided" << std::endl;
+	  return -EINVAL;
+	}
+	RGWZoneParams zone(zone_id, zone_name);
+	ret = zone.init(g_ceph_context, store);
+	if (ret < 0) {
+	  cerr << "unable to initialize zone: " << cpp_strerror(-ret) << std::endl;
+	  return -ret;
+	}
+	ret = zone.set_as_default();
+	if (ret < 0) {
+	  cerr << "failed to set zone as default: " << cpp_strerror(-ret) << std::endl;
+	  return -ret;
+	}
       }
+      break;
+    case OPT_ZONE_DELETE:
+      {
+	if (zone_id.empty() && zone_name.empty()) {
+	  cerr << "no zone name or id provided" << std::endl;
+	  return -EINVAL;
+	}
+	RGWZoneParams zone(zone_id, zone_name);
+	int ret = zone.init(g_ceph_context, store);
+	if (ret < 0) {
+	  cerr << "unable to initialize zone: " << cpp_strerror(-ret) << std::endl;
+	  return -ret;
+	}
 
-      ret = zone.store_info(g_ceph_context, store, region);
-      if (ret < 0) {
-        cerr << "ERROR: couldn't store zone info: " << cpp_strerror(-ret) << std::endl;
-        return 1;
+        list<string> zonegroups;
+	ret = store->list_zonegroups(zonegroups);
+	if (ret < 0) {
+	  cerr << "failed to list zonegroups: " << cpp_strerror(-ret) << std::endl;
+	  return -ret;
+	}
+
+        for (list<string>::iterator iter = zonegroups.begin(); iter != zonegroups.end(); ++iter) {
+          RGWZoneGroup zonegroup(string(), *iter);
+          int ret = zonegroup.init(g_ceph_context, store);
+          if (ret < 0) {
+            cerr << "WARNING: failed to initialize zonegroup " << zonegroup_name << std::endl;
+            continue;
+          }
+          ret = zonegroup.remove_zone(zone);
+          if (ret < 0 && ret != -ENOENT) {
+            cerr << "failed to remove zone " << zone_name << " from zonegroup " << zonegroup.get_name() << ": "
+              << cpp_strerror(-ret) << std::endl;
+          }
+        }
+
+	ret = zone.delete_obj();
+	if (ret < 0) {
+	  cerr << "failed to delete zone " << zone_name << ": " << cpp_strerror(-ret) << std::endl;
+	  return ret;
+	}
+      }
+      break;
+    case OPT_ZONE_GET:
+      {
+	RGWZoneParams zone(zone_id, zone_name);
+	int ret = zone.init(g_ceph_context, store);
+	if (ret < 0) {
+	  cerr << "unable to initialize zone: " << cpp_strerror(-ret) << std::endl;
+	  return -ret;
+	}
+	encode_json("zone", zone, formatter);
+	formatter->flush(cout);
       }
+      break;
+    case OPT_ZONE_SET:
+      {
+	RGWZoneParams zone(zone_name);
+	int ret = zone.init(g_ceph_context, store, false);
+	if (ret < 0) {
+	  return -ret;
+	}
 
-      encode_json("zone", zone, formatter);
-      formatter->flush(cout);
-    }
-    if (opt_cmd == OPT_ZONE_LIST) {
-      list<string> zones;
-      int ret = store->list_zones(zones);
-      if (ret < 0) {
-        cerr << "failed to list zones: " << cpp_strerror(-ret) << std::endl;
-	return -ret;
+        ret = zone.read();
+        if (ret < 0 && ret != -ENOENT) {
+	  cerr << "zone.read() returned ret=" << ret << std::endl;
+          return -ret;
+        }
+
+        string orig_id = zone.get_id();
+
+	ret = read_decode_json(infile, zone);
+	if (ret < 0) {
+	  return 1;
+	}
+
+	if(zone.realm_id.empty()) {
+	  RGWRealm realm(realm_id, realm_name);
+	  int ret = realm.init(g_ceph_context, store);
+	  if (ret < 0) {
+	    cerr << "failed to init realm: " << cpp_strerror(-ret) << std::endl;
+	    return -ret;
+	  }
+	  zone.realm_id = realm.get_id();
+	}
+
+        if (zone.get_name().empty()) {
+          zone.set_name(zone_name);
+          if (zone.get_name().empty()) {
+            cerr << "no zone name specified" << std::endl;
+            return EINVAL;
+          }
+        }
+
+	if(zone.get_name() != zone_name) {
+	  cerr << "Error: zone name" << zone_name << " is different than the zone name " << zone.get_name() << " in the provided json " << std::endl;
+	  return -EINVAL;
+	}
+
+        zone_name = zone.get_name();
+
+        if (zone.get_id().empty()) {
+          zone.set_id(orig_id);
+        }
+
+	if (zone.get_id().empty()) {
+	  cerr << "no zone name id the json provided, assuming old format" << std::endl;
+	  if (zone_name.empty()) {
+	    cerr << "missing zone name"  << std::endl;
+	    return EINVAL;
+	  }
+	  zone.set_name(zone_name);
+	  zone.set_id(zone_name);
+	}
+
+	cerr << "zone id " << zone.get_id();
+	ret = zone.fix_pool_names();
+	if (ret < 0) {
+	  cerr << "ERROR: couldn't fix zone: " << cpp_strerror(-ret) << std::endl;
+	  return ret;
+	}
+	ret = zone.write(false);
+	if (ret < 0) {
+	  cerr << "ERROR: couldn't create zone: " << cpp_strerror(-ret) << std::endl;
+	  return 1;
+	}
+
+        if (set_default) {
+          ret = zone.set_as_default();
+          if (ret < 0) {
+            cerr << "failed to set zone " << zone_name << " as default: " << cpp_strerror(-ret) << std::endl;
+          }
+        }
+
+	encode_json("zone", zone, formatter);
+	formatter->flush(cout);
       }
-      formatter->open_object_section("zones_list");
-      encode_json("zones", zones, formatter);
-      formatter->close_section();
-      formatter->flush(cout);
-      cout << std::endl;
+      break;
+    case OPT_ZONE_LIST:
+      {
+	list<string> zones;
+	int ret = store->list_zones(zones);
+	if (ret < 0) {
+	  cerr << "failed to list zones: " << cpp_strerror(-ret) << std::endl;
+	  return -ret;
+	}
+
+	RGWZoneParams zone;
+	ret = zone.init(g_ceph_context, store, false);
+	if (ret < 0) {
+	  cerr << "failed to init zone: " << cpp_strerror(-ret) << std::endl;
+	  return -ret;
+	}
+	string default_zone;
+	ret = zone.read_default_id(default_zone);
+	if (ret < 0 && ret != -ENOENT) {
+	  cerr << "could not determine default zone: " << cpp_strerror(-ret) << std::endl;
+	}
+	formatter->open_object_section("zones_list");
+	encode_json("default_info", default_zone, formatter);
+	encode_json("zones", zones, formatter);
+	formatter->close_section();
+	formatter->flush(cout);
+	cout << std::endl;
+      }
+      break;
+    case OPT_ZONE_MODIFY:
+      {
+	RGWZoneParams zone(zone_id, zone_name);
+	int ret = zone.init(g_ceph_context, store);
+        if (ret < 0) {
+	  cerr << "failed to init zone: " << cpp_strerror(-ret) << std::endl;
+	  return -ret;
+	}
+
+        bool need_zone_update = false;
+        if (!access_key.empty()) {
+          zone.system_key.id = access_key;
+          need_zone_update = true;
+        }
+
+        if (!secret_key.empty()) {
+          zone.system_key.key = secret_key;
+          need_zone_update = true;
+        }
+
+        if (need_zone_update) {
+          ret = zone.update();
+          if (ret < 0) {
+            cerr << "failed to save zone info: " << cpp_strerror(-ret) << std::endl;
+            return -ret;
+          }
+        }
+
+	RGWRealm realm(realm_id, realm_name);
+	ret = realm.init(g_ceph_context, store);
+	if (ret < 0) {
+	  cerr << "failed to init realm: " << cpp_strerror(-ret) << std::endl;
+	  return -ret;
+	}
+
+	RGWZoneGroup zonegroup(zonegroup_id, zonegroup_name);
+	ret = zonegroup.init(g_ceph_context, store);
+	if (ret < 0) {
+	  cerr << "failed to init zonegroup: " << cpp_strerror(-ret) << std::endl;
+	  return -ret;
+	}
+
+        ret = zonegroup.add_zone(zone,
+                                 (is_master_set ? &is_master : NULL),
+                                 (is_read_only_set ? &read_only : NULL),
+                                 endpoints);
+	if (ret < 0) {
+	  cerr << "failed to update zonegroup: " << cpp_strerror(-ret) << std::endl;
+	  return -ret;
+	}
+
+	ret = zonegroup.update();
+	if (ret < 0) {
+	  cerr << "failed to update zonegroup: " << cpp_strerror(-ret) << std::endl;
+	  return -ret;
+	}
+
+        if (set_default) {
+          ret = zone.set_as_default();
+          if (ret < 0) {
+            cerr << "failed to set zone " << zone_name << " as default: " << cpp_strerror(-ret) << std::endl;
+          }
+        }
+      }
+      break;
+    case OPT_ZONE_RENAME:
+      {
+	if (zone_new_name.empty()) {
+	  cerr << " missing zone new name" << std::endl;
+	  return -EINVAL;
+	}
+	if (zone_id.empty() && zone_name.empty()) {
+	  cerr << "no zonegroup name or id provided" << std::endl;
+	  return -EINVAL;
+	}
+	RGWZoneParams zone(zone_id,zone_name);
+	int ret = zone.init(g_ceph_context, store);
+	if (ret < 0) {
+	  cerr << "unable to initialize zone: " << cpp_strerror(-ret) << std::endl;
+	  return -ret;
+	}
+	ret = zone.rename(zone_new_name);
+	if (ret < 0) {
+	  cerr << "failed to rename zone " << zone_name << " to " << zone_new_name << ": " << cpp_strerror(-ret)
+	       << std::endl;
+	  return ret;
+	}
+	RGWZoneGroup zonegroup(zonegroup_id, zonegroup_name);
+	ret = zonegroup.init(g_ceph_context, store);
+	if (ret < 0) {
+	  cerr << "WARNING: failed to initialize zonegroup " << zonegroup_name << std::endl;
+	} else {
+	  ret = zonegroup.rename_zone(zone);
+	  if (ret < 0 && ret ) {
+	    cerr << "Error in zonegroup rename for " << zone_name << ": " << cpp_strerror(-ret) << std::endl;
+	    return ret;
+	  }
+	}
+      }
+      break;
     }
     return 0;
   }
@@ -1866,7 +3662,7 @@ int main(int argc, char **argv)
   case OPT_CAPS_RM:
     ret = user.caps.remove(user_op, &err_msg);
     if (ret < 0) {
-      cerr << "could not add remove caps: " << err_msg << std::endl;
+      cerr << "could not remove caps: " << err_msg << std::endl;
       return -ret;
     }
 
@@ -1885,8 +3681,114 @@ int main(int argc, char **argv)
       cerr << "could not remove key: " << err_msg << std::endl;
       return -ret;
     }
-
     break;
+  case OPT_PERIOD_PUSH:
+    {
+      RGWEnv env;
+      req_info info(g_ceph_context, &env);
+      info.method = "POST";
+      info.request_uri = "/admin/realm/period";
+
+      map<string, string> &params = info.args.get_params();
+      if (!realm_id.empty())
+        params["realm_id"] = realm_id;
+      if (!realm_name.empty())
+        params["realm_name"] = realm_name;
+      if (!period_id.empty())
+        params["period_id"] = period_id;
+      if (!period_epoch.empty())
+        params["epoch"] = period_epoch;
+
+      // load the period
+      RGWPeriod period(period_id);
+      int ret = period.init(g_ceph_context, store);
+      if (ret < 0) {
+        cerr << "period init failed: " << cpp_strerror(-ret) << std::endl;
+        return ret;
+      }
+      // json format into a bufferlist
+      JSONFormatter jf(false);
+      encode_json("period", period, &jf);
+      bufferlist bl;
+      jf.flush(bl);
+
+      JSONParser p;
+      ret = send_to_remote_gateway(url, info, bl, p);
+      if (ret < 0) {
+        cerr << "request failed: " << cpp_strerror(-ret) << std::endl;
+        return ret;
+      }
+    }
+    return 0;
+  case OPT_PERIOD_PULL:
+    {
+      if (remote.empty() && url.empty() ) {
+	/* use realm master zonegroup as remote */
+	RGWRealm realm(realm_id, realm_name);
+	int ret = realm.init(g_ceph_context, store);
+	if (ret < 0) {
+	  cerr << "failed to init realm: " << cpp_strerror(-ret) << std::endl;
+	  return ret;
+	}
+	RGWPeriod current_period(realm.get_current_period());
+	ret = current_period.init(g_ceph_context, store);
+	if (ret < 0) {
+	  cerr << "failed to init current period: " << cpp_strerror(-ret) << std::endl;
+	  return ret;
+	}
+	remote = current_period.get_master_zonegroup();
+      }
+      RGWPeriod period;
+      int ret = do_period_pull(remote, url, access_key, secret_key,
+                               realm_id, realm_name, period_id, period_epoch,
+                               &period);
+      if (ret < 0) {
+        cerr << "period pull failed: " << cpp_strerror(-ret) << std::endl;
+      }
+
+      encode_json("period", period, formatter);
+      formatter->flush(cout);
+      cout << std::endl;
+    }
+    return 0;
+  case OPT_PERIOD_UPDATE:
+    {
+      int ret = update_period(realm_id, realm_name, period_id, period_epoch,
+                              commit, remote, url, access_key, secret_key,
+                              formatter);
+      if (ret < 0) {
+        cerr << "period update failed: " << cpp_strerror(-ret) << std::endl;
+        return ret;
+      }
+    }
+    return 0;
+  case OPT_PERIOD_COMMIT:
+    {
+      // read realm and staging period
+      RGWRealm realm(realm_id, realm_name);
+      int ret = realm.init(g_ceph_context, store);
+      if (ret < 0) {
+        cerr << "Error initializing realm: " << cpp_strerror(-ret) << std::endl;
+        return ret;
+      }
+      RGWPeriod period(RGWPeriod::get_staging_id(realm.get_id()), 1);
+      ret = period.init(g_ceph_context, store, realm.get_id());
+      if (ret < 0) {
+        cerr << "period init failed: " << cpp_strerror(-ret) << std::endl;
+        return ret;
+      }
+      ret = commit_period(realm, period, remote, url, access_key, secret_key);
+      if (ret < 0) {
+        cerr << "failed to commit period: " << cpp_strerror(-ret) << std::endl;
+        return ret;
+      }
+
+      encode_json("period", period, formatter);
+      formatter->flush(cout);
+      cout << std::endl;
+    }
+    return 0;
+
   default:
     output_user_info = false;
   }
@@ -1902,9 +3804,18 @@ int main(int argc, char **argv)
   }
 
   if (opt_cmd == OPT_POLICY) {
-    int ret = RGWBucketAdminOp::get_policy(store, bucket_op, cout);
-    if (ret >= 0) {
-      cout << std::endl;
+    if (format == "xml") {
+      int ret = RGWBucketAdminOp::dump_s3_policy(store, bucket_op, cout);
+      if (ret < 0) {
+        cerr << "ERROR: failed to get policy: " << cpp_strerror(-ret) << std::endl;
+        return -ret;
+      }
+    } else {
+      int ret = RGWBucketAdminOp::get_policy(store, bucket_op, f);
+      if (ret < 0) {
+        cerr << "ERROR: failed to get policy: " << cpp_strerror(-ret) << std::endl;
+        return -ret;
+      }
     }
   }
 
@@ -1930,7 +3841,7 @@ int main(int argc, char **argv)
       map<string, bool> common_prefixes;
       string ns;
 
-      RGWRados::Bucket target(store, bucket);
+      RGWRados::Bucket target(store, bucket_info);
       RGWRados::Bucket::List list_op(&target);
 
       list_op.params.prefix = prefix;
@@ -2263,7 +4174,7 @@ next:
 
     RGWObjState *state;
 
-    int ret = store->get_obj_state(&rctx, obj, &state, NULL, false); /* don't follow olh */
+    int ret = store->get_obj_state(&rctx, obj, &state, false); /* don't follow olh */
     if (ret < 0) {
       return ret;
     }
@@ -2468,7 +4379,7 @@ next:
     formatter->open_array_section("objects");
     while (is_truncated) {
       map<string, RGWObjEnt> result;
-      int r = store->cls_bucket_list(bucket, marker, prefix, 1000, true,
+      int r = store->cls_bucket_list(bucket, RGW_NO_SHARD, marker, prefix, 1000, true,
                                      result, &is_truncated, &marker,
                                      bucket_object_check_filter);
 
@@ -2488,7 +4399,7 @@ next:
         formatter->dump_string("name", key.name);
         formatter->dump_string("instance", key.instance);
         formatter->dump_int("size", entry.size);
-        utime_t ut(entry.mtime, 0);
+        utime_t ut(entry.mtime);
         ut.gmtime(formatter->dump_stream("mtime"));
 
         if ((entry.size < min_rewrite_size) ||
@@ -2826,15 +4737,23 @@ next:
 
     int i = (specified_shard_id ? shard_id : 0);
 
+    if (period_id.empty()) {
+      int ret = read_current_period_id(store, realm_id, realm_name, &period_id);
+      if (ret < 0) {
+        return -ret;
+      }
+      std::cerr << "No --period given, using current period="
+          << period_id << std::endl;
+    }
+    RGWMetadataLog *meta_log = store->meta_mgr->get_log(period_id);
+
     formatter->open_array_section("entries");
     for (; i < g_ceph_context->_conf->rgw_md_log_max_shards; i++) {
-      RGWMetadataLog *meta_log = store->meta_mgr->get_log();
       void *handle;
       list<cls_log_entry> entries;
 
 
-      meta_log->init_list_entries(i, start_time, end_time, marker, &handle);
-
+      meta_log->init_list_entries(i, start_time.to_real_time(), end_time.to_real_time(), marker, &handle); 
       bool truncated;
       do {
 	  int ret = meta_log->list_entries(handle, 1000, entries, NULL, &truncated);
@@ -2861,6 +4780,36 @@ next:
     formatter->flush(cout);
   }
 
+  if (opt_cmd == OPT_MDLOG_STATUS) {
+    int i = (specified_shard_id ? shard_id : 0);
+
+    if (period_id.empty()) {
+      int ret = read_current_period_id(store, realm_id, realm_name, &period_id);
+      if (ret < 0) {
+        return ret;
+      }
+      std::cerr << "No --period given, using current period="
+          << period_id << std::endl;
+    }
+    RGWMetadataLog *meta_log = store->meta_mgr->get_log(period_id);
+
+    formatter->open_array_section("entries");
+
+    for (; i < g_ceph_context->_conf->rgw_md_log_max_shards; i++) {
+      RGWMetadataLogInfo info;
+      meta_log->get_info(i, &info);
+
+      ::encode_json("info", info, formatter);
+
+      if (specified_shard_id)
+        break;
+    }
+  
+
+    formatter->close_section();
+    formatter->flush(cout);
+  }
+
   if (opt_cmd == OPT_MDLOG_TRIM) {
     utime_t start_time, end_time;
 
@@ -2877,15 +4826,269 @@ next:
     if (ret < 0)
       return -ret;
 
-    RGWMetadataLog *meta_log = store->meta_mgr->get_log();
+    if (period_id.empty()) {
+      std::cerr << "missing --period argument" << std::endl;
+      return EINVAL;
+    }
+    RGWMetadataLog *meta_log = store->meta_mgr->get_log(period_id);
 
-    ret = meta_log->trim(shard_id, start_time, end_time, start_marker, end_marker);
+    ret = meta_log->trim(shard_id, start_time.to_real_time(), end_time.to_real_time(), start_marker, end_marker);
     if (ret < 0) {
       cerr << "ERROR: meta_log->trim(): " << cpp_strerror(-ret) << std::endl;
       return -ret;
     }
   }
-  
+
+  if (opt_cmd == OPT_SYNC_STATUS) {
+    sync_status(formatter);
+  }
+
+  if (opt_cmd == OPT_METADATA_SYNC_STATUS) {
+    RGWMetaSyncStatusManager sync(store, store->get_async_rados());
+
+    int ret = sync.init();
+    if (ret < 0) {
+      cerr << "ERROR: sync.init() returned ret=" << ret << std::endl;
+      return -ret;
+    }
+
+    ret = sync.read_sync_status();
+    if (ret < 0) {
+      cerr << "ERROR: sync.read_sync_status() returned ret=" << ret << std::endl;
+      return -ret;
+    }
+
+    const rgw_meta_sync_status& sync_status = sync.get_sync_status();
+
+    formatter->open_object_section("summary");
+    encode_json("sync_status", sync_status, formatter);
+
+    uint64_t full_total = 0;
+    uint64_t full_complete = 0;
+
+    for (auto marker_iter : sync_status.sync_markers) {
+      full_total += marker_iter.second.total_entries;
+      if (marker_iter.second.state == rgw_meta_sync_marker::SyncState::FullSync) {
+        full_complete += marker_iter.second.pos;
+      } else {
+        full_complete += marker_iter.second.total_entries;
+      }
+    }
+
+    formatter->open_object_section("full_sync");
+    encode_json("total", full_total, formatter);
+    encode_json("complete", full_complete, formatter);
+    formatter->close_section();
+    formatter->close_section();
+
+    formatter->flush(cout);
+
+  }
+
+  if (opt_cmd == OPT_METADATA_SYNC_INIT) {
+    RGWMetaSyncStatusManager sync(store, store->get_async_rados());
+
+    int ret = sync.init();
+    if (ret < 0) {
+      cerr << "ERROR: sync.init() returned ret=" << ret << std::endl;
+      return -ret;
+    }
+    ret = sync.init_sync_status();
+    if (ret < 0) {
+      cerr << "ERROR: sync.get_sync_status() returned ret=" << ret << std::endl;
+      return -ret;
+    }
+  }
+
+
+  if (opt_cmd == OPT_METADATA_SYNC_RUN) {
+    RGWMetaSyncStatusManager sync(store, store->get_async_rados());
+
+    int ret = sync.init();
+    if (ret < 0) {
+      cerr << "ERROR: sync.init() returned ret=" << ret << std::endl;
+      return -ret;
+    }
+
+    ret = sync.run();
+    if (ret < 0) {
+      cerr << "ERROR: sync.run() returned ret=" << ret << std::endl;
+      return -ret;
+    }
+  }
+
+  if (opt_cmd == OPT_DATA_SYNC_STATUS) {
+    if (source_zone.empty()) {
+      cerr << "ERROR: source zone not specified" << std::endl;
+      return EINVAL;
+    }
+    RGWDataSyncStatusManager sync(store, store->get_async_rados(), source_zone);
+
+    int ret = sync.init();
+    if (ret < 0) {
+      cerr << "ERROR: sync.init() returned ret=" << ret << std::endl;
+      return -ret;
+    }
+
+    ret = sync.read_sync_status();
+    if (ret < 0) {
+      cerr << "ERROR: sync.read_sync_status() returned ret=" << ret << std::endl;
+      return -ret;
+    }
+
+    rgw_data_sync_status& sync_status = sync.get_sync_status();
+
+    formatter->open_object_section("summary");
+    encode_json("sync_status", sync_status, formatter);
+
+    uint64_t full_total = 0;
+    uint64_t full_complete = 0;
+
+    for (auto marker_iter : sync_status.sync_markers) {
+      full_total += marker_iter.second.total_entries;
+      if (marker_iter.second.state == rgw_meta_sync_marker::SyncState::FullSync) {
+        full_complete += marker_iter.second.pos;
+      } else {
+        full_complete += marker_iter.second.total_entries;
+      }
+    }
+
+    formatter->open_object_section("full_sync");
+    encode_json("total", full_total, formatter);
+    encode_json("complete", full_complete, formatter);
+    formatter->close_section();
+    formatter->close_section();
+
+    formatter->flush(cout);
+  }
+
+  if (opt_cmd == OPT_DATA_SYNC_INIT) {
+    if (source_zone.empty()) {
+      cerr << "ERROR: source zone not specified" << std::endl;
+      return EINVAL;
+    }
+    RGWDataSyncStatusManager sync(store, store->get_async_rados(), source_zone);
+
+    int ret = sync.init();
+    if (ret < 0) {
+      cerr << "ERROR: sync.init() returned ret=" << ret << std::endl;
+      return -ret;
+    }
+
+    ret = sync.init_sync_status();
+    if (ret < 0) {
+      cerr << "ERROR: sync.get_sync_status() returned ret=" << ret << std::endl;
+      return -ret;
+    }
+  }
+
+  if (opt_cmd == OPT_DATA_SYNC_RUN) {
+    if (source_zone.empty()) {
+      cerr << "ERROR: source zone not specified" << std::endl;
+      return EINVAL;
+    }
+    RGWDataSyncStatusManager sync(store, store->get_async_rados(), source_zone);
+
+    int ret = sync.init();
+    if (ret < 0) {
+      cerr << "ERROR: sync.init() returned ret=" << ret << std::endl;
+      return -ret;
+    }
+
+    ret = sync.run();
+    if (ret < 0) {
+      cerr << "ERROR: sync.run() returned ret=" << ret << std::endl;
+      return -ret;
+    }
+  }
+
+  if (opt_cmd == OPT_BUCKET_SYNC_INIT) {
+    if (source_zone.empty()) {
+      cerr << "ERROR: source zone not specified" << std::endl;
+      return EINVAL;
+    }
+    if (bucket_name.empty()) {
+      cerr << "ERROR: bucket not specified" << std::endl;
+      return EINVAL;
+    }
+    int ret = init_bucket_for_sync(tenant, bucket_name, bucket_id);
+    if (ret < 0) {
+      return -ret;
+    }
+    RGWBucketSyncStatusManager sync(store, source_zone, bucket_name, bucket_id);
+
+    ret = sync.init();
+    if (ret < 0) {
+      cerr << "ERROR: sync.init() returned ret=" << ret << std::endl;
+      return -ret;
+    }
+    ret = sync.init_sync_status();
+    if (ret < 0) {
+      cerr << "ERROR: sync.get_sync_status() returned ret=" << ret << std::endl;
+      return -ret;
+    }
+  }
+
+  if (opt_cmd == OPT_BUCKET_SYNC_STATUS) {
+    if (source_zone.empty()) {
+      cerr << "ERROR: source zone not specified" << std::endl;
+      return EINVAL;
+    }
+    if (bucket_name.empty()) {
+      cerr << "ERROR: bucket not specified" << std::endl;
+      return EINVAL;
+    }
+    int ret = init_bucket_for_sync(tenant, bucket_name, bucket_id);
+    if (ret < 0) {
+      return -ret;
+    }
+    RGWBucketSyncStatusManager sync(store, source_zone, bucket_name, bucket_id);
+
+    ret = sync.init();
+    if (ret < 0) {
+      cerr << "ERROR: sync.init() returned ret=" << ret << std::endl;
+      return -ret;
+    }
+    ret = sync.read_sync_status();
+    if (ret < 0) {
+      cerr << "ERROR: sync.read_sync_status() returned ret=" << ret << std::endl;
+      return -ret;
+    }
+
+    map<int, rgw_bucket_shard_sync_info>& sync_status = sync.get_sync_status();
+
+    encode_json("sync_status", sync_status, formatter);
+    formatter->flush(cout);
+  }
+
+ if (opt_cmd == OPT_BUCKET_SYNC_RUN) {
+    if (source_zone.empty()) {
+      cerr << "ERROR: source zone not specified" << std::endl;
+      return EINVAL;
+    }
+    if (bucket_name.empty()) {
+      cerr << "ERROR: bucket not specified" << std::endl;
+      return EINVAL;
+    }
+    int ret = init_bucket_for_sync(tenant, bucket_name, bucket_id);
+    if (ret < 0) {
+      return -ret;
+    }
+    RGWBucketSyncStatusManager sync(store, source_zone, bucket_name, bucket_id);
+
+    ret = sync.init();
+    if (ret < 0) {
+      cerr << "ERROR: sync.init() returned ret=" << ret << std::endl;
+      return -ret;
+    }
+
+    ret = sync.run();
+    if (ret < 0) {
+      cerr << "ERROR: sync.run() returned ret=" << ret << std::endl;
+      return -ret;
+    }
+  }
+
   if (opt_cmd == OPT_BILOG_LIST) {
     if (bucket_name.empty()) {
       cerr << "ERROR: bucket not specified" << std::endl;
@@ -2926,6 +5129,83 @@ next:
     formatter->flush(cout);
   }
 
+  if (opt_cmd == OPT_SYNC_ERROR_LIST) {
+    if (max_entries < 0) {
+      max_entries = 1000;
+    }
+
+    bool truncated;
+    utime_t start_time, end_time;
+
+    int ret = parse_date_str(start_date, start_time);
+    if (ret < 0)
+      return -ret;
+
+    ret = parse_date_str(end_date, end_time);
+    if (ret < 0)
+      return -ret;
+
+    if (shard_id < 0) {
+      shard_id = 0;
+    }
+
+    formatter->open_array_section("entries");
+
+    for (; shard_id < ERROR_LOGGER_SHARDS; ++shard_id) {
+      formatter->open_object_section("shard");
+      encode_json("shard_id", shard_id, formatter);
+      formatter->open_array_section("entries");
+
+      int count = 0;
+      string oid = RGWSyncErrorLogger::get_shard_oid(RGW_SYNC_ERROR_LOG_SHARD_PREFIX, shard_id);
+
+      do {
+        list<cls_log_entry> entries;
+        ret = store->time_log_list(oid, start_time.to_real_time(), end_time.to_real_time(),
+                                   max_entries - count, entries, marker, &marker, &truncated);
+        if (ret == -ENOENT) {
+          break;
+        }
+        if (ret < 0) {
+          cerr << "ERROR: store->time_log_list(): " << cpp_strerror(-ret) << std::endl;
+          return -ret;
+        }
+
+        count += entries.size();
+
+        for (auto& cls_entry : entries) {
+          rgw_sync_error_info log_entry;
+
+          auto iter = cls_entry.data.begin();
+          try {
+            ::decode(log_entry, iter);
+          } catch (buffer::error& err) {
+            cerr << "ERROR: failed to decode log entry" << std::endl;
+            continue;
+          }
+          formatter->open_object_section("entry");
+          encode_json("id", cls_entry.id, formatter);
+          encode_json("section", cls_entry.section, formatter);
+          encode_json("name", cls_entry.name, formatter);
+          encode_json("timestamp", cls_entry.timestamp, formatter);
+          encode_json("info", log_entry, formatter);
+          formatter->close_section();
+          formatter->flush(cout);
+        }
+      } while (truncated && count < max_entries);
+
+      formatter->close_section();
+      formatter->close_section();
+
+      if (specified_shard_id) {
+        break;
+      }
+    }
+
+    formatter->close_section();
+    formatter->flush(cout);
+  }
+
   if (opt_cmd == OPT_BILOG_TRIM) {
     if (bucket_name.empty()) {
       cerr << "ERROR: bucket not specified" << std::endl;
@@ -2965,8 +5245,8 @@ next:
     RGWDataChangesLog::LogMarker marker;
 
     do {
-      list<rgw_data_change> entries;
-      ret = log->list_entries(start_time, end_time, max_entries - count, entries, marker, &truncated);
+      list<rgw_data_change_log_entry> entries;
+      ret = log->list_entries(start_time.to_real_time(), end_time.to_real_time(), max_entries - count, entries, marker, &truncated);
       if (ret < 0) {
         cerr << "ERROR: list_bi_log_entries(): " << cpp_strerror(-ret) << std::endl;
         return -ret;
@@ -2974,9 +5254,13 @@ next:
 
       count += entries.size();
 
-      for (list<rgw_data_change>::iterator iter = entries.begin(); iter != entries.end(); ++iter) {
-        rgw_data_change& entry = *iter;
-        encode_json("entry", entry, formatter);
+      for (list<rgw_data_change_log_entry>::iterator iter = entries.begin(); iter != entries.end(); ++iter) {
+        rgw_data_change_log_entry& entry = *iter;
+        if (!extra_info) {
+          encode_json("entry", entry.entry, formatter);
+        } else {
+          encode_json("entry", entry, formatter);
+        }
       }
       formatter->flush(cout);
     } while (truncated && count < max_entries);
@@ -2985,6 +5269,27 @@ next:
     formatter->flush(cout);
   }
   
+  if (opt_cmd == OPT_DATALOG_STATUS) {
+    RGWDataChangesLog *log = store->data_log;
+    int i = (specified_shard_id ? shard_id : 0);
+
+    formatter->open_array_section("entries");
+    for (; i < g_ceph_context->_conf->rgw_data_log_num_shards; i++) {
+      list<cls_log_entry> entries;
+
+      RGWDataChangesLogInfo info;
+      log->get_info(i, &info);
+
+      ::encode_json("info", info, formatter);
+
+      if (specified_shard_id)
+        break;
+    }
+
+    formatter->close_section();
+    formatter->flush(cout);
+  }
+  
   if (opt_cmd == OPT_DATALOG_TRIM) {
     utime_t start_time, end_time;
 
@@ -2997,7 +5302,7 @@ next:
       return -ret;
 
     RGWDataChangesLog *log = store->data_log;
-    ret = log->trim_entries(start_time, end_time, start_marker, end_marker);
+    ret = log->trim_entries(start_time.to_real_time(), end_time.to_real_time(), start_marker, end_marker);
     if (ret < 0) {
       cerr << "ERROR: trim_entries(): " << cpp_strerror(-ret) << std::endl;
       return -ret;
diff --git a/src/rgw/rgw_auth_s3.cc b/src/rgw/rgw_auth_s3.cc
index b372630..aba0655 100644
--- a/src/rgw/rgw_auth_s3.cc
+++ b/src/rgw/rgw_auth_s3.cc
@@ -2,7 +2,10 @@
 // vim: ts=8 sw=2 smarttab
 
 #include "common/armor.h"
+#include "common/utf8.h"
 #include "rgw_common.h"
+#include "rgw_client_io.h"
+#include "rgw_rest.h"
 
 #define dout_subsys ceph_subsys_rgw
 
@@ -26,6 +29,8 @@ static const char *signed_subresources[] = {
   "torrent",
   "uploadId",
   "uploads",
+  "start-date",
+  "end-date",
   "versionId",
   "versioning",
   "versions",
@@ -147,6 +152,11 @@ int rgw_get_s3_header_digest(const string& auth_hdr, const string& key, string&
   return 0;
 }
 
+void rgw_hash_s3_string_sha256(const char *data, int len, string& dest)
+{
+  calc_hash_sha256(data, len, dest);
+}
+
 static inline bool is_base64_for_content_md5(unsigned char c) {
   return (isalnum(c) || isspace(c) || (c == '+') || (c == '/') || (c == '='));
 }
@@ -214,3 +224,193 @@ bool rgw_create_s3_canonical_header(req_info& info, utime_t *header_time, string
 
   return true;
 }
+
+/*
+ * assemble canonical request for signature version 4
+ */
+void rgw_assemble_s3_v4_canonical_request(const char *method, const char *canonical_uri, const char *canonical_qs,
+                                          const char *canonical_hdrs, const char *signed_hdrs, const char *request_payload_hash,
+                                          string& dest_str)
+{
+  string dest;
+
+  if (method)
+    dest = method;
+  dest.append("\n");
+
+  if (canonical_uri) {
+    dest.append(canonical_uri);
+  }
+  dest.append("\n");
+
+  if (canonical_qs) {
+    dest.append(canonical_qs);
+  }
+  dest.append("\n");
+
+  if (canonical_hdrs)
+    dest.append(canonical_hdrs);
+  dest.append("\n");
+
+  if (signed_hdrs)
+    dest.append(signed_hdrs);
+  dest.append("\n");
+
+  if (request_payload_hash)
+    dest.append(request_payload_hash);
+
+  dest_str = dest;
+}
+
+/*
+ * create canonical request for signature version 4
+ */
+void rgw_create_s3_v4_canonical_request(struct req_state *s, const string& canonical_uri, const string& canonical_qs,
+                                        const string& canonical_hdrs, const string& signed_hdrs, const string& request_payload,
+                                        bool unsigned_payload, string& canonical_req, string& canonical_req_hash)
+{
+  string request_payload_hash;
+
+  if (unsigned_payload) {
+    request_payload_hash = "UNSIGNED-PAYLOAD";
+  } else {
+    if (s->aws4_auth_needs_complete) {
+      request_payload_hash = STREAM_IO(s)->grab_aws4_sha256_hash();
+    } else {
+      rgw_hash_s3_string_sha256(request_payload.c_str(), request_payload.size(), request_payload_hash);
+    }
+  }
+
+  s->aws4_auth->payload_hash = request_payload_hash;
+
+  ldout(s->cct, 10) << "payload request hash = " << request_payload_hash << dendl;
+
+  rgw_assemble_s3_v4_canonical_request(s->info.method, canonical_uri.c_str(),
+      canonical_qs.c_str(), canonical_hdrs.c_str(), signed_hdrs.c_str(),
+      request_payload_hash.c_str(), canonical_req);
+
+  rgw_hash_s3_string_sha256(canonical_req.c_str(), canonical_req.size(), canonical_req_hash);
+
+  ldout(s->cct, 10) << "canonical request = " << canonical_req << dendl;
+  ldout(s->cct, 10) << "canonical request hash = " << canonical_req_hash << dendl;
+}
+
+/*
+ * assemble string to sign for signature version 4
+ */
+void rgw_assemble_s3_v4_string_to_sign(const char *algorithm, const char *request_date,
+                                       const char *credential_scope, const char *hashed_qr, string& dest_str)
+{
+  string dest;
+
+  if (algorithm)
+    dest = algorithm;
+  dest.append("\n");
+
+  if (request_date)
+    dest.append(request_date);
+  dest.append("\n");
+
+  if (credential_scope)
+    dest.append(credential_scope);
+  dest.append("\n");
+
+  if (hashed_qr)
+    dest.append(hashed_qr);
+
+  dest_str = dest;
+}
+
+/*
+ * create string to sign for signature version 4
+ */
+void rgw_create_s3_v4_string_to_sign(CephContext *cct, const string& algorithm, const string& request_date,
+                                     const string& credential_scope, const string& hashed_qr,
+                                     string& string_to_sign) {
+
+  rgw_assemble_s3_v4_string_to_sign(algorithm.c_str(), request_date.c_str(),
+      credential_scope.c_str(), hashed_qr.c_str(), string_to_sign);
+
+  ldout(cct, 10) << "string to sign = " << string_to_sign << dendl;
+}
+
+/*
+ * calculate the AWS signature version 4
+ */
+int rgw_calculate_s3_v4_aws_signature(struct req_state *s,
+    const string& access_key_id, const string &date, const string& region,
+    const string& service, const string& string_to_sign, string& signature) {
+
+  map<string, RGWAccessKey>::iterator iter = s->user->access_keys.find(access_key_id);
+  if (iter == s->user->access_keys.end()) {
+    ldout(s->cct, 10) << "ERROR: access key not encoded in user info" << dendl;
+    return -EPERM;
+  }
+
+  RGWAccessKey& k = iter->second;
+
+  string secret_key = "AWS4" + k.key;
+
+  char secret_k[secret_key.size() * MAX_UTF8_SZ];
+
+  size_t n = 0;
+
+  for (size_t i = 0; i < secret_key.size(); i++) {
+    n += encode_utf8(secret_key[i], (unsigned char *) (secret_k + n));
+  }
+
+  string secret_key_utf8_k(secret_k, n);
+
+  /* date */
+
+  char date_k[CEPH_CRYPTO_HMACSHA256_DIGESTSIZE];
+  calc_hmac_sha256(secret_key_utf8_k.c_str(), secret_key_utf8_k.size(),
+      date.c_str(), date.size(), date_k);
+
+  char aux[CEPH_CRYPTO_HMACSHA256_DIGESTSIZE * 2 + 1];
+  buf_to_hex((unsigned char *) date_k, CEPH_CRYPTO_HMACSHA256_DIGESTSIZE, aux);
+
+  ldout(s->cct, 10) << "date_k        = " << string(aux) << dendl;
+
+  /* region */
+
+  char region_k[CEPH_CRYPTO_HMACSHA256_DIGESTSIZE];
+  calc_hmac_sha256(date_k, CEPH_CRYPTO_HMACSHA256_DIGESTSIZE, region.c_str(), region.size(), region_k);
+
+  buf_to_hex((unsigned char *) region_k, CEPH_CRYPTO_HMACSHA256_DIGESTSIZE, aux);
+
+  ldout(s->cct, 10) << "region_k      = " << string(aux) << dendl;
+
+  /* service */
+
+  char service_k[CEPH_CRYPTO_HMACSHA256_DIGESTSIZE];
+  calc_hmac_sha256(region_k, CEPH_CRYPTO_HMACSHA256_DIGESTSIZE, service.c_str(), service.size(), service_k);
+
+  buf_to_hex((unsigned char *) service_k, CEPH_CRYPTO_HMACSHA256_DIGESTSIZE, aux);
+
+  ldout(s->cct, 10) << "service_k     = " << string(aux) << dendl;
+
+  /* aws4_request */
+
+  char signing_k[CEPH_CRYPTO_HMACSHA256_DIGESTSIZE];
+  calc_hmac_sha256(service_k, CEPH_CRYPTO_HMACSHA256_DIGESTSIZE, "aws4_request", 12, signing_k);
+
+  buf_to_hex((unsigned char *) signing_k, CEPH_CRYPTO_HMACSHA256_DIGESTSIZE, aux);
+
+  ldout(s->cct, 10) << "signing_k     = " << string(aux) << dendl;
+
+  /* new signature */
+
+  char signature_k[CEPH_CRYPTO_HMACSHA256_DIGESTSIZE];
+  calc_hmac_sha256(signing_k, CEPH_CRYPTO_HMACSHA256_DIGESTSIZE, string_to_sign.c_str(), string_to_sign.size(), signature_k);
+
+  buf_to_hex((unsigned char *) signature_k, CEPH_CRYPTO_HMACSHA256_DIGESTSIZE, aux);
+
+  ldout(s->cct, 10) << "signature_k   = " << string(aux) << dendl;
+
+  signature = string(aux);
+
+  ldout(s->cct, 10) << "new signature = " << signature << dendl;
+
+  return 0;
+}
diff --git a/src/rgw/rgw_auth_s3.h b/src/rgw/rgw_auth_s3.h
index 3a7da09..4e8dd1c 100644
--- a/src/rgw/rgw_auth_s3.h
+++ b/src/rgw/rgw_auth_s3.h
@@ -7,12 +7,31 @@
 
 #include "rgw_common.h"
 
-void rgw_create_s3_canonical_header(const char *method, const char *content_md5, const char *content_type, const char *date,
-                            map<string, string>& meta_map, const char *request_uri, map<string, string>& sub_resources,
-                            string& dest_str);
-bool rgw_create_s3_canonical_header(req_info& info, utime_t *header_time, string& dest, bool qsr);
+void rgw_create_s3_canonical_header(const char *method,
+				    const char *content_md5,
+				    const char *content_type, const char *date,
+				    map<string, string>& meta_map,
+				    const char *request_uri,
+				    map<string, string>& sub_resources,
+				    string& dest_str);
+bool rgw_create_s3_canonical_header(req_info& info, utime_t *header_time,
+				    string& dest, bool qsr);
+int rgw_get_s3_header_digest(const string& auth_hdr, const string& key,
+			     string& dest);
 int rgw_get_s3_header_digest(const string& auth_hdr, const string& key, string& dest);
 
-
+void rgw_hash_s3_string_sha256(const char *data, int len, string& dest);
+void rgw_create_s3_v4_canonical_request(struct req_state *s, const string& canonical_uri,
+                                        const string& canonical_qs, const string& canonical_hdrs,
+                                        const string& signed_hdrs, const string& request_payload,
+                                        bool unsigned_payload,
+                                        string& canonical_req, string& canonical_req_hash);
+void rgw_create_s3_v4_string_to_sign(CephContext *cct, const string& algorithm,
+                                     const string& request_date, const string& credential_scope,
+                                     const string& hashed_qr, string& string_to_sign);
+int rgw_calculate_s3_v4_aws_signature(struct req_state *s, const string& access_key_id,
+                                      const string &date, const string& region,
+                                      const string& service, const string& string_to_sign,
+                                      string& signature);
 
 #endif
diff --git a/src/rgw/rgw_b64.h b/src/rgw/rgw_b64.h
new file mode 100644
index 0000000..8a9e8ad
--- /dev/null
+++ b/src/rgw/rgw_b64.h
@@ -0,0 +1,87 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+
+#ifndef RGW_B64_H
+#define RGW_B64_H
+
+#include <boost/utility/string_ref.hpp>
+#include <boost/archive/iterators/base64_from_binary.hpp>
+#include <boost/archive/iterators/binary_from_base64.hpp>
+#include <boost/archive/iterators/insert_linebreaks.hpp>
+#include <boost/archive/iterators/transform_width.hpp>
+#include <boost/archive/iterators/remove_whitespace.hpp>
+#include <limits>
+
+namespace rgw {
+
+  /*
+   * A header-only Base64 encoder built on boost::archive.  The
+   * formula is based on a class poposed for inclusion in boost in
+   * 2011 by Denis Shevchenko (abandoned), updated slightly
+   * (e.g., uses boost::string_ref).
+   *
+   * Also, wrap_width added as template argument, based on
+   * feedback from Marcus.
+   */
+
+  template<int wrap_width = std::numeric_limits<int>::max()>
+  inline std::string to_base64(boost::string_ref sref)
+  {
+    using namespace boost::archive::iterators;
+    std::string ostr;
+    
+    // output must be =padded modulo 3
+    auto psize = sref.size();
+    while ((psize % 3) != 0) {
+      ++psize;
+    }
+
+    /* RFC 2045 requires linebreaks to be present in the output
+     * sequence every at-most 76 characters (MIME-compliance),
+     * but we could likely omit it. */
+    typedef
+      insert_linebreaks<
+        base64_from_binary<
+          transform_width<
+	    boost::string_ref::const_iterator
+            ,6,8>
+          >
+          ,wrap_width
+        > b64_iter;
+
+    std::string outstr(b64_iter(sref.data()),
+		       b64_iter(sref.data() + sref.size()));
+
+    // pad ostr with '=' to a length that is a multiple of 3
+    for (size_t ix = 0; ix < (psize-sref.size()); ++ix)
+      outstr.push_back('=');
+
+    return std::move(outstr);
+  }
+
+  inline std::string from_base64(boost::string_ref sref)
+  {
+    using namespace boost::archive::iterators;
+
+    /* MIME-compliant input will have line-breaks, so we have to
+     * filter WS */
+    typedef
+      transform_width<
+      binary_from_base64<
+	remove_whitespace<
+	  boost::string_ref::const_iterator>>
+      ,8,6
+      > b64_iter;
+
+    while (sref.back() == '=')
+      sref.remove_suffix(1);
+
+    std::string outstr(b64_iter(sref.data()),
+		      b64_iter(sref.data() + sref.size()));
+
+    return std::move(outstr);
+  }
+
+} /* namespace */
+
+#endif /* RGW_B64_H */
diff --git a/src/rgw/rgw_basic_types.h b/src/rgw/rgw_basic_types.h
index 8538af6..00ad16e 100644
--- a/src/rgw/rgw_basic_types.h
+++ b/src/rgw/rgw_basic_types.h
@@ -41,7 +41,7 @@ struct rgw_user {
     id.clear();
   }
 
-  bool empty() {
+  bool empty() const {
     return id.empty();
   }
 
diff --git a/src/rgw/rgw_boost_asio_coroutine.h b/src/rgw/rgw_boost_asio_coroutine.h
new file mode 100644
index 0000000..2dd911e
--- /dev/null
+++ b/src/rgw/rgw_boost_asio_coroutine.h
@@ -0,0 +1,67 @@
+//
+// copy of needed class and macors from coroutine.hpp
+//
+// Copyright (c) 2003-2013 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#ifndef RGW_BOOST_ASIO_COROUTINE_H
+#define RGW_BOOST_ASIO_COROUTINE_H
+
+#ifndef HAVE_BOOST_ASIO_COROUTINE
+
+namespace boost {
+namespace asio {
+namespace detail {
+
+class coroutine_ref;
+
+} // namespace detail
+
+class coroutine
+{
+public:
+  /// Constructs a coroutine in its initial state.
+  coroutine() : value_(0) {}
+
+  /// Returns true if the coroutine is the child of a fork.
+  bool is_child() const { return value_ < 0; }
+
+  /// Returns true if the coroutine is the parent of a fork.
+  bool is_parent() const { return !is_child(); }
+
+  /// Returns true if the coroutine has reached its terminal state.
+  bool is_complete() const { return value_ == -1; }
+
+private:
+  friend class detail::coroutine_ref;
+  int value_;
+};
+
+
+namespace detail {
+
+class coroutine_ref
+{
+public:
+  coroutine_ref(coroutine& c) : value_(c.value_), modified_(false) {}
+  coroutine_ref(coroutine* c) : value_(c->value_), modified_(false) {}
+  ~coroutine_ref() { if (!modified_) value_ = -1; }
+  operator int() const { return value_; }
+  int& operator=(int v) { modified_ = true; return value_ = v; }
+private:
+  void operator=(const coroutine_ref&);
+  int& value_;
+  bool modified_;
+};
+
+} // namespace detail
+} // namespace asio
+} // namespace boost
+
+#endif // HAVE_BOOST_ASIO_COROUTINE
+
+#endif // RGW_BOOST_ASIO_COROUTINE_H
+
diff --git a/src/rgw/rgw_boost_asio_yield.h b/src/rgw/rgw_boost_asio_yield.h
new file mode 100644
index 0000000..aeb9321
--- /dev/null
+++ b/src/rgw/rgw_boost_asio_yield.h
@@ -0,0 +1,78 @@
+//
+// copy of needed macors from yield.hpp
+//
+// Copyright (c) 2003-2013 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#ifndef RGW_BOOST_ASIO_YIELD_H
+#define RGW_BOOST_ASIO_YIELD_H
+
+#ifdef HAVE_BOOST_ASIO_COROUTINE
+#include <boost/asio/yield.hpp>
+#else
+#define BOOST_ASIO_CORO_REENTER(c) \
+  switch (::boost::asio::detail::coroutine_ref _coro_value = c) \
+    case -1: if (_coro_value) \
+    { \
+      goto terminate_coroutine; \
+      terminate_coroutine: \
+      _coro_value = -1; \
+      goto bail_out_of_coroutine; \
+      bail_out_of_coroutine: \
+      break; \
+    } \
+    else case 0:
+
+#define BOOST_ASIO_CORO_YIELD_IMPL(n) \
+  for (_coro_value = (n);;) \
+    if (_coro_value == 0) \
+    { \
+      case (n): ; \
+      break; \
+    } \
+    else \
+      switch (_coro_value ? 0 : 1) \
+        for (;;) \
+          case -1: if (_coro_value) \
+            goto terminate_coroutine; \
+          else for (;;) \
+            case 1: if (_coro_value) \
+              goto bail_out_of_coroutine; \
+            else case 0:
+
+#define BOOST_ASIO_CORO_FORK_IMPL(n) \
+  for (_coro_value = -(n);; _coro_value = (n)) \
+    if (_coro_value == (n)) \
+    { \
+      case -(n): ; \
+      break; \
+    } \
+    else
+
+#if defined(_MSC_VER)
+# define BOOST_ASIO_CORO_YIELD BOOST_ASIO_CORO_YIELD_IMPL(__COUNTER__ + 1)
+# define BOOST_ASIO_CORO_FORK BOOST_ASIO_CORO_FORK_IMPL(__COUNTER__ + 1)
+#else // defined(_MSC_VER)
+# define BOOST_ASIO_CORO_YIELD BOOST_ASIO_CORO_YIELD_IMPL(__LINE__)
+# define BOOST_ASIO_CORO_FORK BOOST_ASIO_CORO_FORK_IMPL(__LINE__)
+#endif // defined(_MSC_VER)
+
+#ifndef reenter
+# define reenter(c) BOOST_ASIO_CORO_REENTER(c)
+#endif
+
+#ifndef yield
+# define yield BOOST_ASIO_CORO_YIELD
+#endif
+
+#ifndef fork
+# define fork BOOST_ASIO_CORO_FORK
+#endif
+
+#endif // HAVE_BOOST_ASIO_COROUTINE
+
+#endif // RGW_BOOST_ASIO_YIELD_H
+
diff --git a/src/rgw/rgw_bucket.cc b/src/rgw/rgw_bucket.cc
index 3e4e854..685968c 100644
--- a/src/rgw/rgw_bucket.cc
+++ b/src/rgw/rgw_bucket.cc
@@ -102,14 +102,15 @@ int rgw_read_user_buckets(RGWRados * store,
                           const string& end_marker,
                           uint64_t max,
                           bool need_stats,
-                          uint64_t default_amount)
+			  bool *is_truncated,
+			  uint64_t default_amount)
 {
   int ret;
   buckets.clear();
   string buckets_obj_id;
   rgw_get_buckets_obj(user_id, buckets_obj_id);
   bufferlist bl;
-  rgw_obj obj(store->zone.user_uid_pool, buckets_obj_id);
+  rgw_obj obj(store->get_zone_params().user_uid_pool, buckets_obj_id);
   bufferlist header;
   list<cls_user_bucket_entry> entries;
 
@@ -153,7 +154,7 @@ int rgw_bucket_sync_user_stats(RGWRados *store, const rgw_user& user_id, rgw_buc
 {
   string buckets_obj_id;
   rgw_get_buckets_obj(user_id, buckets_obj_id);
-  rgw_obj obj(store->zone.user_uid_pool, buckets_obj_id);
+  rgw_obj obj(store->get_zone_params().user_uid_pool, buckets_obj_id);
 
   return store->cls_user_sync_bucket_stats(obj, bucket);
 }
@@ -177,7 +178,7 @@ int rgw_bucket_sync_user_stats(RGWRados *store, const string& tenant_name, const
   return 0;
 }
 
-int rgw_link_bucket(RGWRados *store, const rgw_user& user_id, rgw_bucket& bucket, time_t creation_time, bool update_entrypoint)
+int rgw_link_bucket(RGWRados *store, const rgw_user& user_id, rgw_bucket& bucket, real_time creation_time, bool update_entrypoint)
 {
   int ret;
   string& tenant_name = bucket.tenant;
@@ -190,8 +191,8 @@ int rgw_link_bucket(RGWRados *store, const rgw_user& user_id, rgw_bucket& bucket
 
   bucket.convert(&new_bucket.bucket);
   new_bucket.size = 0;
-  if (!creation_time)
-    time(&new_bucket.creation_time);
+  if (real_clock::is_zero(creation_time))
+    new_bucket.creation_time = real_clock::now();
   else
     new_bucket.creation_time = creation_time;
 
@@ -202,16 +203,13 @@ int rgw_link_bucket(RGWRados *store, const rgw_user& user_id, rgw_bucket& bucket
     ret = store->get_bucket_entrypoint_info(obj_ctx, tenant_name, bucket_name, ep, &ot, NULL, &attrs);
     if (ret < 0 && ret != -ENOENT) {
       ldout(store->ctx(), 0) << "ERROR: store->get_bucket_entrypoint_info() returned " << ret << dendl;
-    } else if (ret >= 0 && ep.linked && ep.owner != user_id) {
-      ldout(store->ctx(), 0) << "can't link bucket, already linked to a different user: " << ep.owner << dendl;
-      return -EINVAL;
     }
   }
 
   string buckets_obj_id;
   rgw_get_buckets_obj(user_id, buckets_obj_id);
 
-  rgw_obj obj(store->zone.user_uid_pool, buckets_obj_id);
+  rgw_obj obj(store->get_zone_params().user_uid_pool, buckets_obj_id);
   ret = store->cls_user_add_bucket(obj, new_bucket);
   if (ret < 0) {
     ldout(store->ctx(), 0) << "ERROR: error adding bucket to directory: "
@@ -224,7 +222,7 @@ int rgw_link_bucket(RGWRados *store, const rgw_user& user_id, rgw_bucket& bucket
 
   ep.linked = true;
   ep.owner = user_id;
-  ret = store->put_bucket_entrypoint_info(tenant_name, bucket_name, ep, false, ot, 0, &attrs);
+  ret = store->put_bucket_entrypoint_info(tenant_name, bucket_name, ep, false, ot, real_time(), &attrs);
   if (ret < 0)
     goto done_err;
 
@@ -248,7 +246,7 @@ int rgw_unlink_bucket(RGWRados *store, const rgw_user& user_id, const string& te
 
   cls_user_bucket bucket;
   bucket.name = bucket_name;
-  rgw_obj obj(store->zone.user_uid_pool, buckets_obj_id);
+  rgw_obj obj(store->get_zone_params().user_uid_pool, buckets_obj_id);
   ret = store->cls_user_remove_bucket(obj, bucket);
   if (ret < 0) {
     ldout(store->ctx(), 0) << "ERROR: error removing bucket from directory: "
@@ -277,7 +275,7 @@ int rgw_unlink_bucket(RGWRados *store, const rgw_user& user_id, const string& te
   }
 
   ep.linked = false;
-  ret = store->put_bucket_entrypoint_info(tenant_name, bucket_name, ep, false, ot, 0, &attrs);
+  ret = store->put_bucket_entrypoint_info(tenant_name, bucket_name, ep, false, ot, real_time(), &attrs);
   if (ret < 0)
     return ret;
 
@@ -286,13 +284,13 @@ int rgw_unlink_bucket(RGWRados *store, const rgw_user& user_id, const string& te
 
 int rgw_bucket_store_info(RGWRados *store, const string& bucket_name, bufferlist& bl, bool exclusive,
                           map<string, bufferlist> *pattrs, RGWObjVersionTracker *objv_tracker,
-                          time_t mtime) {
+                          real_time mtime) {
   return store->meta_mgr->put_entry(bucket_meta_handler, bucket_name, bl, exclusive, objv_tracker, mtime, pattrs);
 }
 
 int rgw_bucket_instance_store_info(RGWRados *store, string& entry, bufferlist& bl, bool exclusive,
                           map<string, bufferlist> *pattrs, RGWObjVersionTracker *objv_tracker,
-                          time_t mtime) {
+                          real_time mtime) {
   return store->meta_mgr->put_entry(bucket_instance_meta_handler, entry, bl, exclusive, objv_tracker, mtime, pattrs);
 }
 
@@ -328,7 +326,6 @@ int rgw_bucket_parse_bucket_instance(const string& bucket_instance, string *targ
 
 int rgw_bucket_set_attrs(RGWRados *store, RGWBucketInfo& bucket_info,
                          map<string, bufferlist>& attrs,
-                         map<string, bufferlist>* rmattrs,
                          RGWObjVersionTracker *objv_tracker)
 {
   rgw_bucket& bucket = bucket_info.bucket;
@@ -344,13 +341,16 @@ int rgw_bucket_set_attrs(RGWRados *store, RGWBucketInfo& bucket_info,
   }
   string oid;
   store->get_bucket_meta_oid(bucket, oid);
-  rgw_obj obj(store->zone.domain_root, oid);
+  rgw_obj obj(store->get_zone_params().domain_root, oid);
 
   string key;
   store->get_bucket_instance_entry(bucket, key); /* we want the bucket instance name without
 						    the oid prefix cruft */
-  return store->meta_mgr->set_attrs(bucket_instance_meta_handler, key,
-                                    obj, attrs, rmattrs, objv_tracker);
+  bufferlist bl;
+
+  ::encode(bucket_info, bl);
+
+  return rgw_bucket_instance_store_info(store, key, bl, false, &attrs, objv_tracker, real_time());
 }
 
 static void dump_mulipart_index_results(list<rgw_obj_key>& objs_to_unlink,
@@ -368,10 +368,12 @@ static void dump_mulipart_index_results(list<rgw_obj_key>& objs_to_unlink,
   f->close_section();
 }
 
-void check_bad_user_bucket_mapping(RGWRados *store, const rgw_user& user_id, bool fix)
+void check_bad_user_bucket_mapping(RGWRados *store, const rgw_user& user_id,
+				   bool fix)
 {
   RGWUserBuckets user_buckets;
   bool done;
+  bool is_truncated;
   string marker;
 
   CephContext *cct = store->ctx();
@@ -379,10 +381,12 @@ void check_bad_user_bucket_mapping(RGWRados *store, const rgw_user& user_id, boo
   size_t max_entries = cct->_conf->rgw_list_buckets_max_chunk;
 
   do {
-    int ret = rgw_read_user_buckets(store, user_id, user_buckets,
-                                    marker, string(), max_entries, false);
+    int ret = rgw_read_user_buckets(store, user_id, user_buckets, marker,
+				    string(), max_entries, false,
+				    &is_truncated);
     if (ret < 0) {
-      ldout(store->ctx(), 0) << "failed to read user buckets: " << cpp_strerror(-ret) << dendl;
+      ldout(store->ctx(), 0) << "failed to read user buckets: "
+			     << cpp_strerror(-ret) << dendl;
       return;
     }
 
@@ -396,7 +400,7 @@ void check_bad_user_bucket_mapping(RGWRados *store, const rgw_user& user_id, boo
       rgw_bucket& bucket = bucket_ent.bucket;
 
       RGWBucketInfo bucket_info;
-      time_t mtime;
+      real_time mtime;
       RGWObjectCtx obj_ctx(store);
       int r = store->get_bucket_info(obj_ctx, user_id.tenant, bucket.name, bucket_info, &mtime);
       if (r < 0) {
@@ -462,7 +466,7 @@ int rgw_remove_bucket(RGWRados *store, rgw_bucket& bucket, bool delete_children)
 
   string bucket_ver, master_ver;
 
-  ret = store->get_bucket_stats(bucket, &bucket_ver, &master_ver, stats, NULL);
+  ret = store->get_bucket_stats(bucket, RGW_NO_SHARD, &bucket_ver, &master_ver, stats, NULL);
   if (ret < 0)
     return ret;
 
@@ -473,7 +477,7 @@ int rgw_remove_bucket(RGWRados *store, rgw_bucket& bucket, bool delete_children)
     return ret;
 
 
-  RGWRados::Bucket target(store, bucket);
+  RGWRados::Bucket target(store, info);
   RGWRados::Bucket::List list_op(&target);
 
   list_op.params.list_versions = true;
@@ -499,6 +503,11 @@ int rgw_remove_bucket(RGWRados *store, rgw_bucket& bucket, bool delete_children)
     }
   }
 
+  ret = rgw_bucket_sync_user_stats(store, bucket.tenant, bucket.name);
+  if ( ret < 0) {
+     dout(1) << "WARNING: failed sync user stats before bucket delete. ret=" <<  ret << dendl;
+  }
+
   RGWObjVersionTracker objv_tracker;
 
   ret = store->delete_bucket(bucket, objv_tracker);
@@ -601,6 +610,8 @@ int RGWBucket::link(RGWBucketAdminOpState& op_state, std::string *err_msg)
     return r;
   }
 
+  rgw_user user_id = op_state.get_user_id();
+
   map<string, bufferlist>::iterator aiter = attrs.find(RGW_ATTR_ACL);
   if (aiter != attrs.end()) {
     bufferlist aclbl = aiter->second;
@@ -615,7 +626,7 @@ int RGWBucket::link(RGWBucketAdminOpState& op_state, std::string *err_msg)
       return -EIO;
     }
 
-    r = rgw_unlink_bucket(store, owner.get_id(), bucket.tenant, bucket.name);
+    r = rgw_unlink_bucket(store, owner.get_id(), bucket.tenant, bucket.name, false);
     if (r < 0) {
       set_err_msg(err_msg, "could not unlink policy from user " + owner.get_id().to_str());
       return r;
@@ -638,11 +649,22 @@ int RGWBucket::link(RGWBucketAdminOpState& op_state, std::string *err_msg)
     aclbl.clear();
     policy.encode(aclbl);
 
-    r = store->set_attr(NULL, obj, RGW_ATTR_ACL, aclbl, &objv_tracker);
+    r = store->system_obj_set_attr(NULL, obj, RGW_ATTR_ACL, aclbl, &objv_tracker);
     if (r < 0)
       return r;
 
-    r = rgw_link_bucket(store, user_info.user_id, bucket, 0);
+    RGWAccessControlPolicy policy_instance;
+    policy_instance.create_default(user_info.user_id, display_name);
+    aclbl.clear();
+    policy_instance.encode(aclbl);
+
+    string oid_bucket_instance = RGW_BUCKET_INSTANCE_MD_PREFIX + key;
+    rgw_bucket bucket_instance;
+    bucket_instance.name = oid_bucket_instance;
+    rgw_obj obj_bucket_instance(bucket_instance, no_oid);
+    r = store->system_obj_set_attr(NULL, obj_bucket_instance, RGW_ATTR_ACL, aclbl, &objv_tracker);
+
+    r = rgw_link_bucket(store, user_info.user_id, bucket, real_time());
     if (r < 0)
       return r;
   }
@@ -751,7 +773,15 @@ int RGWBucket::check_bad_index_multipart(RGWBucketAdminOpState& op_state,
   map<string, bool> meta_objs;
   map<rgw_obj_key, string> all_objs;
 
-  RGWRados::Bucket target(store, bucket);
+  RGWBucketInfo bucket_info;
+  RGWObjectCtx obj_ctx(store);
+  int r = store->get_bucket_instance_info(obj_ctx, bucket, bucket_info, nullptr, nullptr);
+  if (r < 0) {
+    ldout(store->ctx(), 0) << "ERROR: " << __func__ << "(): get_bucket_instance_info(bucket=" << bucket << ") returned r=" << r << dendl;
+    return r;
+  }
+
+  RGWRados::Bucket target(store, bucket_info);
   RGWRados::Bucket::List list_op(&target);
 
   list_op.params.list_versions = true;
@@ -847,7 +877,7 @@ int RGWBucket::check_object_index(RGWBucketAdminOpState& op_state,
   while (is_truncated) {
     map<string, RGWObjEnt> result;
 
-    int r = store->cls_bucket_list(bucket, marker, prefix, 1000, true,
+    int r = store->cls_bucket_list(bucket, RGW_NO_SHARD, marker, prefix, 1000, true,
                                    result, &is_truncated, &marker,
                                    bucket_object_check_filter);
     if (r == -ENOENT) {
@@ -903,7 +933,19 @@ int RGWBucket::policy_bl_to_stream(bufferlist& bl, ostream& o)
   return 0;
 }
 
-int RGWBucket::get_policy(RGWBucketAdminOpState& op_state, ostream& o)
+static int policy_decode(RGWRados *store, bufferlist& bl, RGWAccessControlPolicy& policy)
+{
+  bufferlist::iterator iter = bl.begin();
+  try {
+    policy.decode(iter);
+  } catch (buffer::error& err) {
+    ldout(store->ctx(), 0) << "ERROR: caught buffer::error, could not decode policy" << dendl;
+    return -EIO;
+  }
+  return 0;
+}
+
+int RGWBucket::get_policy(RGWBucketAdminOpState& op_state, RGWAccessControlPolicy& policy)
 {
   std::string object_name = op_state.get_object_name();
   rgw_bucket bucket = op_state.get_bucket();
@@ -927,7 +969,7 @@ int RGWBucket::get_policy(RGWBucketAdminOpState& op_state, ostream& o)
     if (ret < 0)
       return ret;
 
-    return policy_bl_to_stream(bl, o);
+    return policy_decode(store, bl, policy);
   }
 
   map<string, bufferlist>::iterator aiter = attrs.find(RGW_ATTR_ACL);
@@ -935,12 +977,12 @@ int RGWBucket::get_policy(RGWBucketAdminOpState& op_state, ostream& o)
     return -ENOENT;
   }
 
-  return policy_bl_to_stream(aiter->second, o);
+  return policy_decode(store, aiter->second, policy);
 }
 
 
 int RGWBucketAdminOp::get_policy(RGWRados *store, RGWBucketAdminOpState& op_state,
-                  ostream& os)
+                  RGWAccessControlPolicy& policy)
 {
   RGWBucket bucket;
 
@@ -948,7 +990,7 @@ int RGWBucketAdminOp::get_policy(RGWRados *store, RGWBucketAdminOpState& op_stat
   if (ret < 0)
     return ret;
 
-  ret = bucket.get_policy(op_state, os);
+  ret = bucket.get_policy(op_state, policy);
   if (ret < 0)
     return ret;
 
@@ -961,9 +1003,9 @@ int RGWBucketAdminOp::get_policy(RGWRados *store, RGWBucketAdminOpState& op_stat
 int RGWBucketAdminOp::get_policy(RGWRados *store, RGWBucketAdminOpState& op_state,
                   RGWFormatterFlusher& flusher)
 {
-  std::ostringstream policy_stream;
+  RGWAccessControlPolicy policy(store->ctx());
 
-  int ret = get_policy(store, op_state, policy_stream);
+  int ret = get_policy(store, op_state, policy);
   if (ret < 0)
     return ret;
 
@@ -971,13 +1013,29 @@ int RGWBucketAdminOp::get_policy(RGWRados *store, RGWBucketAdminOpState& op_stat
 
   flusher.start(0);
 
-  formatter->dump_string("policy", policy_stream.str());
+  formatter->open_object_section("policy");
+  policy.dump(formatter);
+  formatter->close_section();
 
   flusher.flush();
 
   return 0;
 }
 
+int RGWBucketAdminOp::dump_s3_policy(RGWRados *store, RGWBucketAdminOpState& op_state,
+                  ostream& os)
+{
+  RGWAccessControlPolicy_S3 policy(store->ctx());
+
+  int ret = get_policy(store, op_state, policy);
+  if (ret < 0)
+    return ret;
+
+  policy.to_xml(os);
+
+  return 0;
+}
+
 int RGWBucketAdminOp::unlink(RGWRados *store, RGWBucketAdminOpState& op_state)
 {
   RGWBucket bucket;
@@ -1071,7 +1129,7 @@ static int bucket_stats(RGWRados *store, const std::string& tenant_name, std::st
   rgw_bucket bucket;
   map<RGWObjCategory, RGWStorageStats> stats;
 
-  time_t mtime;
+  real_time mtime;
   RGWObjectCtx obj_ctx(store);
   int r = store->get_bucket_info(obj_ctx, tenant_name, bucket_name, bucket_info, &mtime);
   if (r < 0)
@@ -1081,13 +1139,13 @@ static int bucket_stats(RGWRados *store, const std::string& tenant_name, std::st
 
   string bucket_ver, master_ver;
   string max_marker;
-  int ret = store->get_bucket_stats(bucket, &bucket_ver, &master_ver, stats, &max_marker);
+  int ret = store->get_bucket_stats(bucket, RGW_NO_SHARD, &bucket_ver, &master_ver, stats, &max_marker);
   if (ret < 0) {
     cerr << "error getting bucket stats ret=" << ret << std::endl;
     return ret;
   }
 
-  utime_t ut(mtime, 0);
+  utime_t ut(mtime);
 
   formatter->open_object_section("stats");
   formatter->dump_string("bucket", bucket.name);
@@ -1137,10 +1195,12 @@ int RGWBucketAdminOp::info(RGWRados *store, RGWBucketAdminOpState& op_state,
     RGWUserBuckets buckets;
     string marker;
     bool done;
+    bool is_truncated;
 
     do {
-      ret = rgw_read_user_buckets(store, user_id, buckets,
-                                  marker, string(), max_entries, false);
+      ret = rgw_read_user_buckets(store, op_state.get_user_id(), buckets,
+				  marker, string(), max_entries, false,
+				  &is_truncated);
       if (ret < 0)
         return ret;
 
@@ -1199,9 +1259,39 @@ void rgw_data_change::dump(Formatter *f) const
   }
   encode_json("entity_type", type, f);
   encode_json("key", key, f);
-  encode_json("timestamp", timestamp, f);
+  utime_t ut(timestamp);
+  encode_json("timestamp", ut, f);
+}
+
+void rgw_data_change::decode_json(JSONObj *obj) {
+  string s;
+  JSONDecoder::decode_json("entity_type", s, obj);
+  if (s == "bucket") {
+    entity_type = ENTITY_TYPE_BUCKET;
+  } else {
+    entity_type = ENTITY_TYPE_UNKNOWN;
+  }
+  JSONDecoder::decode_json("key", key, obj);
+  utime_t ut;
+  JSONDecoder::decode_json("timestamp", ut, obj);
+  timestamp = ut.to_real_time();
 }
 
+void rgw_data_change_log_entry::dump(Formatter *f) const
+{
+  encode_json("log_id", log_id, f);
+  utime_t ut(log_timestamp);
+  encode_json("log_timestamp", ut, f);
+  encode_json("entry", entry, f);
+}
+
+void rgw_data_change_log_entry::decode_json(JSONObj *obj) {
+  JSONDecoder::decode_json("log_id", log_id, obj);
+  utime_t ut;
+  JSONDecoder::decode_json("log_timestamp", ut, obj);
+  log_timestamp = ut.to_real_time();
+  JSONDecoder::decode_json("entry", entry, obj);
+}
 
 int RGWDataChangesLog::choose_oid(const rgw_bucket_shard& bs) {
     const string& name = bs.bucket.name;
@@ -1227,7 +1317,7 @@ int RGWDataChangesLog::renew_entries()
 
   map<rgw_bucket_shard, bool>::iterator iter;
   string section;
-  utime_t ut = ceph_clock_now(cct);
+  real_time ut = real_clock::now();
   for (iter = entries.begin(); iter != entries.end(); ++iter) {
     const rgw_bucket_shard& bs = iter->first;
     const rgw_bucket& bucket = bs.bucket;
@@ -1259,9 +1349,9 @@ int RGWDataChangesLog::renew_entries()
   for (miter = m.begin(); miter != m.end(); ++miter) {
     list<cls_log_entry>& entries = miter->second.second;
 
-    utime_t now = ceph_clock_now(cct);
+    real_time now = real_clock::now();
 
-    int ret = store->time_log_add(oids[miter->first], entries);
+    int ret = store->time_log_add(oids[miter->first], entries, NULL);
     if (ret < 0) {
       /* we don't really need to have a special handling for failed cases here,
        * as this is just an optimization. */
@@ -1269,8 +1359,8 @@ int RGWDataChangesLog::renew_entries()
       return ret;
     }
 
-    utime_t expiration = now;
-    expiration += utime_t(cct->_conf->rgw_data_log_window, 0);
+    real_time expiration = now;
+    expiration += make_timespan(cct->_conf->rgw_data_log_window);
 
     list<rgw_bucket_shard>& buckets = miter->second.first;
     list<rgw_bucket_shard>::iterator liter;
@@ -1297,7 +1387,7 @@ void RGWDataChangesLog::register_renew(rgw_bucket_shard& bs)
   cur_cycle[bs] = true;
 }
 
-void RGWDataChangesLog::update_renewed(rgw_bucket_shard& bs, utime_t& expiration)
+void RGWDataChangesLog::update_renewed(rgw_bucket_shard& bs, real_time& expiration)
 {
   Mutex::Locker l(lock);
   ChangeStatusPtr status;
@@ -1307,12 +1397,21 @@ void RGWDataChangesLog::update_renewed(rgw_bucket_shard& bs, utime_t& expiration
   status->cur_expiration = expiration;
 }
 
+int RGWDataChangesLog::get_log_shard_id(rgw_bucket& bucket, int shard_id) {
+  rgw_bucket_shard bs(bucket, shard_id);
+
+  return choose_oid(bs);
+}
+
 int RGWDataChangesLog::add_entry(rgw_bucket& bucket, int shard_id) {
   if (!store->need_to_log_data())
     return 0;
 
   rgw_bucket_shard bs(bucket, shard_id);
 
+  int index = choose_oid(bs);
+  mark_modified(index, bs);
+
   lock.Lock();
 
   ChangeStatusPtr status;
@@ -1320,7 +1419,7 @@ int RGWDataChangesLog::add_entry(rgw_bucket& bucket, int shard_id) {
 
   lock.Unlock();
 
-  utime_t now = ceph_clock_now(cct);
+  real_time now = real_clock::now();
 
   status->lock->Lock();
 
@@ -1355,8 +1454,8 @@ int RGWDataChangesLog::add_entry(rgw_bucket& bucket, int shard_id) {
   status->cond = new RefCountedCond;
   status->pending = true;
 
-  string& oid = oids[choose_oid(bs)];
-  utime_t expiration;
+  string& oid = oids[index];
+  real_time expiration;
 
   int ret;
 
@@ -1364,7 +1463,7 @@ int RGWDataChangesLog::add_entry(rgw_bucket& bucket, int shard_id) {
     status->cur_sent = now;
 
     expiration = now;
-    expiration += utime_t(cct->_conf->rgw_data_log_window, 0);
+    expiration += ceph::make_timespan(cct->_conf->rgw_data_log_window);
 
     status->lock->Unlock();
   
@@ -1385,17 +1484,17 @@ int RGWDataChangesLog::add_entry(rgw_bucket& bucket, int shard_id) {
 
     ret = store->time_log_add(oid, now, section, change.key, bl);
 
-    now = ceph_clock_now(cct);
+    now = real_clock::now();
 
     status->lock->Lock();
 
-  } while (!ret && ceph_clock_now(cct) > expiration);
+  } while (!ret && real_clock::now() > expiration);
 
   cond = status->cond;
 
   status->pending = false;
   status->cur_expiration = status->cur_sent; /* time of when operation started, not completed */
-  status->cur_expiration += utime_t(cct->_conf->rgw_data_log_window, 0);
+  status->cur_expiration += make_timespan(cct->_conf->rgw_data_log_window);
   status->cond = NULL;
   status->lock->Unlock();
 
@@ -1405,8 +1504,8 @@ int RGWDataChangesLog::add_entry(rgw_bucket& bucket, int shard_id) {
   return ret;
 }
 
-int RGWDataChangesLog::list_entries(int shard, utime_t& start_time, utime_t& end_time, int max_entries,
-				    list<rgw_data_change>& entries,
+int RGWDataChangesLog::list_entries(int shard, const real_time& start_time, const real_time& end_time, int max_entries,
+				    list<rgw_data_change_log_entry>& entries,
 				    const string& marker,
 				    string *out_marker,
 				    bool *truncated) {
@@ -1421,22 +1520,25 @@ int RGWDataChangesLog::list_entries(int shard, utime_t& start_time, utime_t& end
 
   list<cls_log_entry>::iterator iter;
   for (iter = log_entries.begin(); iter != log_entries.end(); ++iter) {
-    rgw_data_change entry;
+    rgw_data_change_log_entry log_entry;
+    log_entry.log_id = iter->id;
+    real_time rt = iter->timestamp.to_real_time();
+    log_entry.log_timestamp = rt;
     bufferlist::iterator liter = iter->data.begin();
     try {
-      ::decode(entry, liter);
+      ::decode(log_entry.entry, liter);
     } catch (buffer::error& err) {
       lderr(cct) << "ERROR: failed to decode data changes log entry" << dendl;
       return -EIO;
     }
-    entries.push_back(entry);
+    entries.push_back(log_entry);
   }
 
   return 0;
 }
 
-int RGWDataChangesLog::list_entries(utime_t& start_time, utime_t& end_time, int max_entries,
-             list<rgw_data_change>& entries, LogMarker& marker, bool *ptruncated) {
+int RGWDataChangesLog::list_entries(const real_time& start_time, const real_time& end_time, int max_entries,
+             list<rgw_data_change_log_entry>& entries, LogMarker& marker, bool *ptruncated) {
   bool truncated;
   entries.clear();
 
@@ -1475,12 +1577,12 @@ int RGWDataChangesLog::get_info(int shard_id, RGWDataChangesLogInfo *info)
     return ret;
 
   info->marker = header.max_marker;
-  info->last_update = header.max_time;
+  info->last_update = header.max_time.to_real_time();
 
   return 0;
 }
 
-int RGWDataChangesLog::trim_entries(int shard_id, const utime_t& start_time, const utime_t& end_time,
+int RGWDataChangesLog::trim_entries(int shard_id, const real_time& start_time, const real_time& end_time,
                                     const string& start_marker, const string& end_marker)
 {
   int ret;
@@ -1496,7 +1598,7 @@ int RGWDataChangesLog::trim_entries(int shard_id, const utime_t& start_time, con
   return ret;
 }
 
-int RGWDataChangesLog::trim_entries(const utime_t& start_time, const utime_t& end_time,
+int RGWDataChangesLog::trim_entries(const real_time& start_time, const real_time& end_time,
                                     const string& start_marker, const string& end_marker)
 {
   for (int shard = 0; shard < num_shards; shard++) {
@@ -1550,46 +1652,43 @@ void RGWDataChangesLog::ChangesRenewThread::stop()
   cond.Signal();
 }
 
-struct RGWBucketCompleteInfo {
-  RGWBucketInfo info;
-  map<string, bufferlist> attrs;
-
- void dump(Formatter *f) const {
-    encode_json("bucket_info", info, f);
-    encode_json("attrs", attrs, f);
-  }
-
-  void decode_json(JSONObj *obj) {
-    JSONDecoder::decode_json("bucket_info", info, obj);
-    JSONDecoder::decode_json("attrs", attrs, obj);
+void RGWDataChangesLog::mark_modified(int shard_id, rgw_bucket_shard& bs)
+{
+  string key = bs.bucket.name + ":" + bs.bucket.bucket_id;
+  char buf[16];
+  snprintf(buf, sizeof(buf), ":%d", bs.shard_id);
+  key.append(buf);
+  modified_lock.get_read();
+  map<int, set<string> >::iterator iter = modified_shards.find(shard_id);
+  if (iter != modified_shards.end()) {
+    set<string>& keys = iter->second;
+    if (keys.find(key) != keys.end()) {
+      modified_lock.unlock();
+      return;
+    }
   }
-};
+  modified_lock.unlock();
 
-class RGWBucketEntryMetadataObject : public RGWMetadataObject {
-  RGWBucketEntryPoint ep;
-public:
-  RGWBucketEntryMetadataObject(RGWBucketEntryPoint& _ep, obj_version& v, time_t m) : ep(_ep) {
-    objv = v;
-    mtime = m;
-  }
+  RWLock::WLocker wl(modified_lock);
+  modified_shards[shard_id].insert(key);
+}
 
-  void dump(Formatter *f) const {
-    ep.dump(f);
-  }
-};
+void RGWDataChangesLog::read_clear_modified(map<int, set<string> > &modified)
+{
+  RWLock::WLocker wl(modified_lock);
+  modified.swap(modified_shards);
+  modified_shards.clear();
+}
 
-class RGWBucketInstanceMetadataObject : public RGWMetadataObject {
-  RGWBucketCompleteInfo info;
-public:
-  RGWBucketInstanceMetadataObject(RGWBucketCompleteInfo& i, obj_version& v, time_t m) : info(i) {
-    objv = v;
-    mtime = m;
-  }
+void RGWBucketCompleteInfo::dump(Formatter *f) const {
+  encode_json("bucket_info", info, f);
+  encode_json("attrs", attrs, f);
+}
 
-  void dump(Formatter *f) const {
-    info.dump(f);
-  }
-};
+void RGWBucketCompleteInfo::decode_json(JSONObj *obj) {
+  JSONDecoder::decode_json("bucket_info", info, obj);
+  JSONDecoder::decode_json("attrs", attrs, obj);
+}
 
 class RGWBucketMetadataHandler : public RGWMetadataHandler {
 
@@ -1600,7 +1699,7 @@ public:
     RGWObjVersionTracker ot;
     RGWBucketEntryPoint be;
 
-    time_t mtime;
+    real_time mtime;
     map<string, bufferlist> attrs;
     RGWObjectCtx obj_ctx(store);
 
@@ -1618,7 +1717,7 @@ public:
   }
 
   int put(RGWRados *store, string& entry, RGWObjVersionTracker& objv_tracker,
-          time_t mtime, JSONObj *obj, sync_type_t sync_type) {
+          real_time mtime, JSONObj *obj, sync_type_t sync_type) {
     RGWBucketEntryPoint be, old_be;
     try {
       decode_json_obj(be, obj);
@@ -1626,7 +1725,7 @@ public:
       return -EINVAL;
     }
 
-    time_t orig_mtime;
+    real_time orig_mtime;
     map<string, bufferlist> attrs;
 
     RGWObjVersionTracker old_ot;
@@ -1696,7 +1795,7 @@ public:
 
   void get_pool_and_oid(RGWRados *store, const string& key, rgw_bucket& bucket, string& oid) {
     oid = key;
-    bucket = store->zone.domain_root;
+    bucket = store->get_zone_params().domain_root;
   }
 
   int list_keys_init(RGWRados *store, void **phandle)
@@ -1721,7 +1820,7 @@ public:
 
     list<string> unfiltered_keys;
 
-    int ret = store->list_raw_objects(store->zone.domain_root, no_filter,
+    int ret = store->list_raw_objects(store->get_zone_params().domain_root, no_filter,
                                       max, info->ctx, unfiltered_keys, truncated);
     if (ret < 0 && ret != -ENOENT)
       return ret;
@@ -1758,7 +1857,7 @@ public:
   int get(RGWRados *store, string& oid, RGWMetadataObject **obj) {
     RGWBucketCompleteInfo bci;
 
-    time_t mtime;
+    real_time mtime;
     RGWObjectCtx obj_ctx(store);
 
     int ret = store->get_bucket_instance_info(obj_ctx, oid, bci.info, &mtime, &bci.attrs);
@@ -1773,7 +1872,7 @@ public:
   }
 
   int put(RGWRados *store, string& entry, RGWObjVersionTracker& objv_tracker,
-          time_t mtime, JSONObj *obj, sync_type_t sync_type) {
+          real_time mtime, JSONObj *obj, sync_type_t sync_type) {
     RGWBucketCompleteInfo bci, old_bci;
     try {
       decode_json_obj(bci, obj);
@@ -1781,7 +1880,7 @@ public:
       return -EINVAL;
     }
 
-    time_t orig_mtime;
+    real_time orig_mtime;
     RGWObjectCtx obj_ctx(store);
 
     int ret = store->get_bucket_instance_info(obj_ctx, entry, old_bci.info,
@@ -1797,18 +1896,21 @@ public:
       parse_bucket(entry, tenant_name, bucket_name);
 
       rgw_bucket bucket;
+      RGWZonePlacementInfo rule_info;
       ret = store->set_bucket_location_by_rule(bci.info.placement_rule,
-                                           tenant_name, bucket_name, bucket);
+                                           tenant_name, bucket_name, bucket, &rule_info);
       if (ret < 0) {
         ldout(store->ctx(), 0) << "ERROR: select_bucket_placement() returned " << ret << dendl;
         return ret;
       }
       bci.info.bucket.data_pool = bucket.data_pool;
       bci.info.bucket.index_pool = bucket.index_pool;
+      bci.info.index_type = rule_info.index_type;
     } else {
       /* existing bucket, keep its placement pools */
       bci.info.bucket.data_pool = old_bci.info.bucket.data_pool;
       bci.info.bucket.index_pool = old_bci.info.bucket.index_pool;
+      bci.info.index_type = old_bci.info.index_type;
     }
 
     // are we actually going to perform this put, or is it too old?
@@ -1854,7 +1956,7 @@ public:
 
   void get_pool_and_oid(RGWRados *store, const string& key, rgw_bucket& bucket, string& oid) {
     oid = RGW_BUCKET_INSTANCE_MD_PREFIX + key;
-    bucket = store->zone.domain_root;
+    bucket = store->get_zone_params().domain_root;
   }
 
   int list_keys_init(RGWRados *store, void **phandle)
@@ -1879,7 +1981,7 @@ public:
 
     list<string> unfiltered_keys;
 
-    int ret = store->list_raw_objects(store->zone.domain_root, no_filter,
+    int ret = store->list_raw_objects(store->get_zone_params().domain_root, no_filter,
                                       max, info->ctx, unfiltered_keys, truncated);
     if (ret < 0 && ret != -ENOENT)
       return ret;
diff --git a/src/rgw/rgw_bucket.h b/src/rgw/rgw_bucket.h
index 61f5c62..8a2c28c 100644
--- a/src/rgw/rgw_bucket.h
+++ b/src/rgw/rgw_bucket.h
@@ -17,6 +17,7 @@
 
 #include "common/Formatter.h"
 #include "common/lru_map.h"
+#include "common/ceph_time.h"
 #include "rgw_formats.h"
 
 
@@ -27,10 +28,10 @@ extern void rgw_get_buckets_obj(const rgw_user& user_id, string& buckets_obj_id)
 
 extern int rgw_bucket_store_info(RGWRados *store, const string& bucket_name, bufferlist& bl, bool exclusive,
                                  map<string, bufferlist> *pattrs, RGWObjVersionTracker *objv_tracker,
-                                 time_t mtime);
+                                 real_time mtime);
 extern int rgw_bucket_instance_store_info(RGWRados *store, string& oid, bufferlist& bl, bool exclusive,
                                  map<string, bufferlist> *pattrs, RGWObjVersionTracker *objv_tracker,
-                                 time_t mtime);
+                                 real_time mtime);
 
 extern int rgw_bucket_parse_bucket_instance(const string& bucket_instance, string *target_bucket_instance, int *shard_id);
 
@@ -53,6 +54,47 @@ extern void rgw_parse_url_bucket(const string& bucket,
                                  const string& auth_tenant,
                                  string &tenant_name, string &bucket_name);
 
+struct RGWBucketCompleteInfo {
+  RGWBucketInfo info;
+  map<string, bufferlist> attrs;
+
+  void dump(Formatter *f) const;
+  void decode_json(JSONObj *obj);
+};
+
+class RGWBucketEntryMetadataObject : public RGWMetadataObject {
+  RGWBucketEntryPoint ep;
+public:
+  RGWBucketEntryMetadataObject(RGWBucketEntryPoint& _ep, obj_version& v, real_time m) : ep(_ep) {
+    objv = v;
+    mtime = m;
+  }
+
+  void dump(Formatter *f) const {
+    ep.dump(f);
+  }
+};
+
+class RGWBucketInstanceMetadataObject : public RGWMetadataObject {
+  RGWBucketCompleteInfo info;
+public:
+  RGWBucketInstanceMetadataObject() {}
+  RGWBucketInstanceMetadataObject(RGWBucketCompleteInfo& i, obj_version& v, real_time m) : info(i) {
+    objv = v;
+    mtime = m;
+  }
+
+  void dump(Formatter *f) const {
+    info.dump(f);
+  }
+
+  void decode_json(JSONObj *obj) {
+    info.decode_json(obj);
+  }
+
+  RGWBucketInfo& get_bucket_info() { return info.info; }
+};
+
 /**
  * Store a list of the user's buckets, with associated functinos.
  */
@@ -123,9 +165,10 @@ extern int rgw_read_user_buckets(RGWRados *store,
                                  const string& end_marker,
                                  uint64_t max,
                                  bool need_stats,
+				 bool* is_truncated,
                                  uint64_t default_amount = 1000);
 
-extern int rgw_link_bucket(RGWRados *store, const rgw_user& user_id, rgw_bucket& bucket, time_t creation_time, bool update_entrypoint = true);
+extern int rgw_link_bucket(RGWRados *store, const rgw_user& user_id, rgw_bucket& bucket, real_time creation_time, bool update_entrypoint = true);
 extern int rgw_unlink_bucket(RGWRados *store, const rgw_user& user_id,
                              const string& tenant_name, const string& bucket_name, bool update_entrypoint = true);
 
@@ -134,7 +177,6 @@ extern int rgw_remove_bucket(RGWRados *store, rgw_bucket& bucket, bool delete_ch
 
 extern int rgw_bucket_set_attrs(RGWRados *store, RGWBucketInfo& bucket_info,
                                 map<string, bufferlist>& attrs,
-                                map<string, bufferlist>* rmattrs,
                                 RGWObjVersionTracker *objv_tracker);
 
 extern void check_bad_user_bucket_mapping(RGWRados *store, const rgw_user& user_id, bool fix);
@@ -239,7 +281,7 @@ public:
 
   int remove_object(RGWBucketAdminOpState& op_state, std::string *err_msg = NULL);
   int policy_bl_to_stream(bufferlist& bl, ostream& o);
-  int get_policy(RGWBucketAdminOpState& op_state, ostream& o);
+  int get_policy(RGWBucketAdminOpState& op_state, RGWAccessControlPolicy& policy);
 
   void clear_failure() { failure = false; }
 };
@@ -250,9 +292,10 @@ public:
   static int get_policy(RGWRados *store, RGWBucketAdminOpState& op_state,
                   RGWFormatterFlusher& flusher);
   static int get_policy(RGWRados *store, RGWBucketAdminOpState& op_state,
+                  RGWAccessControlPolicy& policy);
+  static int dump_s3_policy(RGWRados *store, RGWBucketAdminOpState& op_state,
                   ostream& os);
 
-
   static int unlink(RGWRados *store, RGWBucketAdminOpState& op_state);
   static int link(RGWRados *store, RGWBucketAdminOpState& op_state, string *err_msg = NULL);
 
@@ -266,13 +309,14 @@ public:
 
 
 enum DataLogEntityType {
+  ENTITY_TYPE_UNKNOWN = 0,
   ENTITY_TYPE_BUCKET = 1,
 };
 
 struct rgw_data_change {
   DataLogEntityType entity_type;
   string key;
-  utime_t timestamp;
+  real_time timestamp;
 
   void encode(bufferlist& bl) const {
     ENCODE_START(1, 1, bl);
@@ -294,12 +338,39 @@ struct rgw_data_change {
   }
 
   void dump(Formatter *f) const;
+  void decode_json(JSONObj *obj);
 };
 WRITE_CLASS_ENCODER(rgw_data_change)
 
+struct rgw_data_change_log_entry {
+  string log_id;
+  real_time log_timestamp;
+  rgw_data_change entry;
+
+  void encode(bufferlist& bl) const {
+    ENCODE_START(1, 1, bl);
+    ::encode(log_id, bl);
+    ::encode(log_timestamp, bl);
+    ::encode(entry, bl);
+    ENCODE_FINISH(bl);
+  }
+
+  void decode(bufferlist::iterator& bl) {
+     DECODE_START(1, bl);
+     ::decode(log_id, bl);
+     ::decode(log_timestamp, bl);
+     ::decode(entry, bl);
+     DECODE_FINISH(bl);
+  }
+
+  void dump(Formatter *f) const;
+  void decode_json(JSONObj *obj);
+};
+WRITE_CLASS_ENCODER(rgw_data_change_log_entry)
+
 struct RGWDataChangesLogInfo {
   string marker;
-  utime_t last_update;
+  real_time last_update;
 
   void dump(Formatter *f) const;
   void decode_json(JSONObj *obj);
@@ -313,12 +384,14 @@ class RGWDataChangesLog {
   string *oids;
 
   Mutex lock;
+  RWLock modified_lock;
+  map<int, set<string> > modified_shards;
 
   atomic_t down_flag;
 
   struct ChangeStatus {
-    utime_t cur_expiration;
-    utime_t cur_sent;
+    real_time cur_expiration;
+    real_time cur_sent;
     bool pending;
     RefCountedCond *cond;
     Mutex *lock;
@@ -340,7 +413,7 @@ class RGWDataChangesLog {
 
   void _get_change(const rgw_bucket_shard& bs, ChangeStatusPtr& status);
   void register_renew(rgw_bucket_shard& bs);
-  void update_renewed(rgw_bucket_shard& bs, utime_t& expiration);
+  void update_renewed(rgw_bucket_shard& bs, real_time& expiration);
 
   class ChangesRenewThread : public Thread {
     CephContext *cct;
@@ -349,7 +422,7 @@ class RGWDataChangesLog {
     Cond cond;
 
   public:
-    ChangesRenewThread(CephContext *_cct, RGWDataChangesLog *_log) : cct(_cct), log(_log), lock("ChangesRenewThread") {}
+    ChangesRenewThread(CephContext *_cct, RGWDataChangesLog *_log) : cct(_cct), log(_log), lock("ChangesRenewThread::lock") {}
     void *entry();
     void stop();
   };
@@ -358,7 +431,8 @@ class RGWDataChangesLog {
 
 public:
 
-  RGWDataChangesLog(CephContext *_cct, RGWRados *_store) : cct(_cct), store(_store), lock("RGWDataChangesLog"),
+  RGWDataChangesLog(CephContext *_cct, RGWRados *_store) : cct(_cct), store(_store),
+                                                           lock("RGWDataChangesLog::lock"), modified_lock("RGWDataChangesLog::modified_lock"),
                                                            changes(cct->_conf->rgw_data_log_changes_size) {
     num_shards = cct->_conf->rgw_data_log_num_shards;
 
@@ -384,22 +458,23 @@ public:
 
   int choose_oid(const rgw_bucket_shard& bs);
   int add_entry(rgw_bucket& bucket, int shard_id);
+  int get_log_shard_id(rgw_bucket& bucket, int shard_id);
   int renew_entries();
-  int list_entries(int shard, utime_t& start_time, utime_t& end_time, int max_entries,
-		   list<rgw_data_change>& entries,
+  int list_entries(int shard, const real_time& start_time, const real_time& end_time, int max_entries,
+		   list<rgw_data_change_log_entry>& entries,
 		   const string& marker,
 		   string *out_marker,
 		   bool *truncated);
-  int trim_entries(int shard_id, const utime_t& start_time, const utime_t& end_time,
+  int trim_entries(int shard_id, const real_time& start_time, const real_time& end_time,
                    const string& start_marker, const string& end_marker);
-  int trim_entries(const utime_t& start_time, const utime_t& end_time,
+  int trim_entries(const real_time& start_time, const real_time& end_time,
                    const string& start_marker, const string& end_marker);
   int get_info(int shard_id, RGWDataChangesLogInfo *info);
-  int lock_exclusive(int shard_id, utime_t& duration, string& zone_id, string& owner_id) {
-    return store->lock_exclusive(store->zone.log_pool, oids[shard_id], duration, zone_id, owner_id);
+  int lock_exclusive(int shard_id, timespan duration, string& zone_id, string& owner_id) {
+    return store->lock_exclusive(store->get_zone_params().log_pool, oids[shard_id], duration, zone_id, owner_id);
   }
   int unlock(int shard_id, string& zone_id, string& owner_id) {
-    return store->unlock(store->zone.log_pool, oids[shard_id], zone_id, owner_id);
+    return store->unlock(store->get_zone_params().log_pool, oids[shard_id], zone_id, owner_id);
   }
   struct LogMarker {
     int shard;
@@ -407,8 +482,11 @@ public:
 
     LogMarker() : shard(0) {}
   };
-  int list_entries(utime_t& start_time, utime_t& end_time, int max_entries,
-               list<rgw_data_change>& entries, LogMarker& marker, bool *ptruncated);
+  int list_entries(const real_time& start_time, const real_time& end_time, int max_entries,
+               list<rgw_data_change_log_entry>& entries, LogMarker& marker, bool *ptruncated);
+
+  void mark_modified(int shard_id, rgw_bucket_shard& bs);
+  void read_clear_modified(map<int, set<string> > &modified);
 
   bool going_down();
 };
diff --git a/src/rgw/rgw_cache.cc b/src/rgw/rgw_cache.cc
index 03c3b05..cdd470c 100644
--- a/src/rgw/rgw_cache.cc
+++ b/src/rgw/rgw_cache.cc
@@ -52,7 +52,7 @@ int ObjectCache::get(string& name, ObjectCacheInfo& info, uint32_t mask, rgw_cac
     if(perfcounter) perfcounter->inc(l_rgw_cache_miss);
     return -ENOENT;
   }
-  ldout(cct, 10) << "cache get: name=" << name << " : hit" << dendl;
+  ldout(cct, 10) << "cache get: name=" << name << " : hit (requested=" << mask << ", cached=" << src.flags << ")" << dendl;
 
   info = src;
   if (cache_info) {
@@ -119,7 +119,7 @@ void ObjectCache::put(string& name, ObjectCacheInfo& info, rgw_cache_entry_info
     return;
   }
 
-  ldout(cct, 10) << "cache put: name=" << name << dendl;
+  ldout(cct, 10) << "cache put: name=" << name << " info.flags=" << info.flags << dendl;
   map<string, ObjectCacheEntry>::iterator iter = cache_map.find(name);
   if (iter == cache_map.end()) {
     ObjectCacheEntry entry;
diff --git a/src/rgw/rgw_cache.h b/src/rgw/rgw_cache.h
index 5ebb48c..5fc3226 100644
--- a/src/rgw/rgw_cache.h
+++ b/src/rgw/rgw_cache.h
@@ -27,23 +27,20 @@ enum {
 
 struct ObjectMetaInfo {
   uint64_t size;
-  time_t mtime;
+  real_time mtime;
 
-  ObjectMetaInfo() : size(0), mtime(0) {}
+  ObjectMetaInfo() : size(0) {}
 
   void encode(bufferlist& bl) const {
     ENCODE_START(2, 2, bl);
     ::encode(size, bl);
-    utime_t t(mtime, 0);
-    ::encode(t, bl);
+    ::encode(mtime, bl);
     ENCODE_FINISH(bl);
   }
   void decode(bufferlist::iterator& bl) {
     DECODE_START_LEGACY_COMPAT_LEN(2, 2, 2, bl);
     ::decode(size, bl);
-    utime_t t;
-    ::decode(t, bl);
-    mtime = t.sec();
+    ::decode(mtime, bl);
     DECODE_FINISH(bl);
   }
   void dump(Formatter *f) const;
@@ -227,25 +224,24 @@ public:
     cache.chain_cache(cc);
   }
 
-  int set_attr(void *ctx, rgw_obj& obj, const char *name, bufferlist& bl, RGWObjVersionTracker *objv_tracker);
-  int set_attrs(void *ctx, rgw_obj& obj, 
+  int system_obj_set_attrs(void *ctx, rgw_obj& obj, 
                 map<string, bufferlist>& attrs,
                 map<string, bufferlist>* rmattrs,
                 RGWObjVersionTracker *objv_tracker);
-  int put_system_obj_impl(rgw_obj& obj, uint64_t size, time_t *mtime,
+  int put_system_obj_impl(rgw_obj& obj, uint64_t size, real_time *mtime,
               map<std::string, bufferlist>& attrs, int flags,
               bufferlist& data,
               RGWObjVersionTracker *objv_tracker,
-              time_t set_mtime);
-  int put_obj_data(void *ctx, rgw_obj& obj, const char *data,
-              off_t ofs, size_t len, bool exclusive);
+              real_time set_mtime);
+  int put_system_obj_data(void *ctx, rgw_obj& obj, bufferlist& bl, off_t ofs, bool exclusive);
 
   int get_system_obj(RGWObjectCtx& obj_ctx, RGWRados::SystemObject::Read::GetObjState& read_state,
                      RGWObjVersionTracker *objv_tracker, rgw_obj& obj,
                      bufferlist& bl, off_t ofs, off_t end,
+                     map<string, bufferlist> *attrs,
                      rgw_cache_entry_info *cache_info);
 
-  int raw_obj_stat(rgw_obj& obj, uint64_t *psize, time_t *pmtime, uint64_t *epoch, map<string, bufferlist> *attrs,
+  int raw_obj_stat(rgw_obj& obj, uint64_t *psize, real_time *pmtime, uint64_t *epoch, map<string, bufferlist> *attrs,
                    bufferlist *first_chunk, RGWObjVersionTracker *objv_tracker);
 
   int delete_system_obj(rgw_obj& obj, RGWObjVersionTracker *objv_tracker);
@@ -262,7 +258,7 @@ void RGWCache<T>::normalize_bucket_and_obj(rgw_bucket& src_bucket, const string&
     dst_bucket = src_bucket;
     dst_obj = src_obj;
   } else {
-    dst_bucket = T::zone.domain_root;
+    dst_bucket = T::get_zone_params().domain_root;
     dst_obj = src_bucket.name;
   }
 }
@@ -273,8 +269,6 @@ int RGWCache<T>::delete_system_obj(rgw_obj& obj, RGWObjVersionTracker *objv_trac
   rgw_bucket bucket;
   string oid;
   normalize_bucket_and_obj(obj.bucket, obj.get_object(), bucket, oid);
-  if (bucket.name[0] != '.')
-    return T::delete_system_obj(obj, objv_tracker);
 
   string name = normal_name(obj);
   cache.remove(name);
@@ -289,13 +283,14 @@ template <class T>
 int RGWCache<T>::get_system_obj(RGWObjectCtx& obj_ctx, RGWRados::SystemObject::Read::GetObjState& read_state,
                      RGWObjVersionTracker *objv_tracker, rgw_obj& obj,
                      bufferlist& obl, off_t ofs, off_t end,
+                     map<string, bufferlist> *attrs,
                      rgw_cache_entry_info *cache_info)
 {
   rgw_bucket bucket;
   string oid;
   normalize_bucket_and_obj(obj.bucket, obj.get_object(), bucket, oid);
-  if (bucket.name[0] != '.' || ofs != 0)
-    return T::get_system_obj(obj_ctx, read_state, objv_tracker, obj, obl, ofs, end, cache_info);
+  if (ofs != 0)
+    return T::get_system_obj(obj_ctx, read_state, objv_tracker, obj, obl, ofs, end, attrs, cache_info);
 
   string name = normal_name(obj.bucket, oid);
 
@@ -304,6 +299,8 @@ int RGWCache<T>::get_system_obj(RGWObjectCtx& obj_ctx, RGWRados::SystemObject::R
   uint32_t flags = CACHE_FLAG_DATA;
   if (objv_tracker)
     flags |= CACHE_FLAG_OBJV;
+  if (attrs)
+    flags |= CACHE_FLAG_XATTRS;
   
   if (cache.get(name, info, flags, cache_info) == 0) {
     if (info.status < 0)
@@ -318,9 +315,11 @@ int RGWCache<T>::get_system_obj(RGWObjectCtx& obj_ctx, RGWRados::SystemObject::R
     i.copy_all(obl);
     if (objv_tracker)
       objv_tracker->read_version = info.version;
+    if (attrs)
+      *attrs = info.xattrs;
     return bl.length();
   }
-  int r = T::get_system_obj(obj_ctx, read_state, objv_tracker, obj, obl, ofs, end, cache_info);
+  int r = T::get_system_obj(obj_ctx, read_state, objv_tracker, obj, obl, ofs, end, attrs, cache_info);
   if (r < 0) {
     if (r == -ENOENT) { // only update ENOENT, we'd rather retry other errors
       info.status = r;
@@ -344,46 +343,15 @@ int RGWCache<T>::get_system_obj(RGWObjectCtx& obj_ctx, RGWRados::SystemObject::R
   if (objv_tracker) {
     info.version = objv_tracker->read_version;
   }
+  if (attrs) {
+    info.xattrs = *attrs;
+  }
   cache.put(name, info, cache_info);
   return r;
 }
 
 template <class T>
-int RGWCache<T>::set_attr(void *ctx, rgw_obj& obj, const char *attr_name, bufferlist& bl, RGWObjVersionTracker *objv_tracker)
-{
-  rgw_bucket bucket;
-  string oid;
-  normalize_bucket_and_obj(obj.bucket, obj.get_object(), bucket, oid);
-  ObjectCacheInfo info;
-  bool cacheable = false;
-  if (bucket.name[0] == '.') {
-    cacheable = true;
-    info.xattrs[attr_name] = bl;
-    info.status = 0;
-    info.flags = CACHE_FLAG_MODIFY_XATTRS;
-    if (objv_tracker) {
-      info.version = objv_tracker->write_version;
-      info.flags |= CACHE_FLAG_OBJV;
-    }
-  }
-  int ret = T::set_attr(ctx, obj, attr_name, bl, objv_tracker);
-  if (cacheable) {
-    string name = normal_name(bucket, oid);
-    if (ret >= 0) {
-      cache.put(name, info, NULL);
-      int r = distribute_cache(name, obj, info, UPDATE_OBJ);
-      if (r < 0)
-        mydout(0) << "ERROR: failed to distribute cache for " << obj << dendl;
-    } else {
-     cache.remove(name);
-    }
-  }
-
-  return ret;
-}
-
-template <class T>
-int RGWCache<T>::set_attrs(void *ctx, rgw_obj& obj, 
+int RGWCache<T>::system_obj_set_attrs(void *ctx, rgw_obj& obj, 
                            map<string, bufferlist>& attrs,
                            map<string, bufferlist>* rmattrs,
                            RGWObjVersionTracker *objv_tracker) 
@@ -392,96 +360,86 @@ int RGWCache<T>::set_attrs(void *ctx, rgw_obj& obj,
   string oid;
   normalize_bucket_and_obj(obj.bucket, obj.get_object(), bucket, oid);
   ObjectCacheInfo info;
-  bool cacheable = false;
-  if (bucket.name[0] == '.') {
-    cacheable = true;
-    info.xattrs = attrs;
-    if (rmattrs)
-      info.rm_xattrs = *rmattrs;
-    info.status = 0;
-    info.flags = CACHE_FLAG_MODIFY_XATTRS;
-    if (objv_tracker) {
-      info.version = objv_tracker->write_version;
-      info.flags |= CACHE_FLAG_OBJV;
-    }
+  info.xattrs = attrs;
+  if (rmattrs)
+    info.rm_xattrs = *rmattrs;
+  info.status = 0;
+  info.flags = CACHE_FLAG_MODIFY_XATTRS;
+  if (objv_tracker) {
+    info.version = objv_tracker->write_version;
+    info.flags |= CACHE_FLAG_OBJV;
   }
-  int ret = T::set_attrs(ctx, obj, attrs, rmattrs, objv_tracker);
-  if (cacheable) {
-    string name = normal_name(bucket, oid);
-    if (ret >= 0) {
-      cache.put(name, info, NULL);
-      int r = distribute_cache(name, obj, info, UPDATE_OBJ);
-      if (r < 0)
-        mydout(0) << "ERROR: failed to distribute cache for " << obj << dendl;
-    } else {
-     cache.remove(name);
-    }
+  int ret = T::system_obj_set_attrs(ctx, obj, attrs, rmattrs, objv_tracker);
+  string name = normal_name(bucket, oid);
+  if (ret >= 0) {
+    cache.put(name, info, NULL);
+    int r = distribute_cache(name, obj, info, UPDATE_OBJ);
+    if (r < 0)
+      mydout(0) << "ERROR: failed to distribute cache for " << obj << dendl;
+  } else {
+   cache.remove(name);
   }
 
   return ret;
 }
 
 template <class T>
-int RGWCache<T>::put_system_obj_impl(rgw_obj& obj, uint64_t size, time_t *mtime,
+int RGWCache<T>::put_system_obj_impl(rgw_obj& obj, uint64_t size, real_time *mtime,
               map<std::string, bufferlist>& attrs, int flags,
               bufferlist& data,
               RGWObjVersionTracker *objv_tracker,
-              time_t set_mtime)
+              real_time set_mtime)
 {
   rgw_bucket bucket;
   string oid;
   normalize_bucket_and_obj(obj.bucket, obj.get_object(), bucket, oid);
   ObjectCacheInfo info;
-  bool cacheable = false;
-  if (bucket.name[0] == '.') {
-    cacheable = true;
-    info.xattrs = attrs;
-    info.status = 0;
-    info.flags = CACHE_FLAG_XATTRS;
-    info.data = data;
-    info.flags |= CACHE_FLAG_DATA;
-    if (objv_tracker) {
-      info.version = objv_tracker->write_version;
-      info.flags |= CACHE_FLAG_OBJV;
-    }
+  info.xattrs = attrs;
+  info.status = 0;
+  info.flags = CACHE_FLAG_XATTRS;
+  info.data = data;
+  info.flags |= CACHE_FLAG_DATA | CACHE_FLAG_META;
+  if (objv_tracker) {
+    info.version = objv_tracker->write_version;
+    info.flags |= CACHE_FLAG_OBJV;
   }
-  int ret = T::put_system_obj_impl(obj, size, mtime, attrs, flags, data,
-                                   objv_tracker, set_mtime);
-  if (cacheable) {
-    string name = normal_name(bucket, oid);
-    if (ret >= 0) {
-      cache.put(name, info, NULL);
-      int r = distribute_cache(name, obj, info, UPDATE_OBJ);
-      if (r < 0)
-        mydout(0) << "ERROR: failed to distribute cache for " << obj << dendl;
-    } else {
-     cache.remove(name);
-    }
+  ceph::real_time result_mtime;
+  int ret = T::put_system_obj_impl(obj, size, &result_mtime, attrs, flags, data,
+				   objv_tracker, set_mtime);
+  if (mtime) {
+    *mtime = result_mtime;
+  }
+  info.meta.mtime = result_mtime;
+  info.meta.size = size;
+  string name = normal_name(bucket, oid);
+  if (ret >= 0) {
+    cache.put(name, info, NULL);
+    int r = distribute_cache(name, obj, info, UPDATE_OBJ);
+    if (r < 0)
+      mydout(0) << "ERROR: failed to distribute cache for " << obj << dendl;
+  } else {
+   cache.remove(name);
   }
 
   return ret;
 }
 
 template <class T>
-int RGWCache<T>::put_obj_data(void *ctx, rgw_obj& obj, const char *data,
-              off_t ofs, size_t len, bool exclusive)
+int RGWCache<T>::put_system_obj_data(void *ctx, rgw_obj& obj, bufferlist& data, off_t ofs, bool exclusive)
 {
   rgw_bucket bucket;
   string oid;
   normalize_bucket_and_obj(obj.bucket, obj.get_object(), bucket, oid);
   ObjectCacheInfo info;
   bool cacheable = false;
-  if ((bucket.name[0] == '.') && ((ofs == 0) || (ofs == -1))) {
+  if ((ofs == 0) || (ofs == -1)) {
     cacheable = true;
-    bufferptr p(len);
-    memcpy(p.c_str(), data, len);
-    bufferlist& bl = info.data;
-    bl.append(p);
-    info.meta.size = bl.length();
+    info.data = data;
+    info.meta.size = data.length();
     info.status = 0;
     info.flags = CACHE_FLAG_DATA;
   }
-  int ret = T::put_obj_data(ctx, obj, data, ofs, len, exclusive);
+  int ret = T::put_system_obj_data(ctx, obj, data, ofs, exclusive);
   if (cacheable) {
     string name = normal_name(bucket, oid);
     if (ret >= 0) {
@@ -498,20 +456,18 @@ int RGWCache<T>::put_obj_data(void *ctx, rgw_obj& obj, const char *data,
 }
 
 template <class T>
-int RGWCache<T>::raw_obj_stat(rgw_obj& obj, uint64_t *psize, time_t *pmtime,
+int RGWCache<T>::raw_obj_stat(rgw_obj& obj, uint64_t *psize, real_time *pmtime,
                           uint64_t *pepoch, map<string, bufferlist> *attrs,
                           bufferlist *first_chunk, RGWObjVersionTracker *objv_tracker)
 {
   rgw_bucket bucket;
   string oid;
   normalize_bucket_and_obj(obj.bucket, obj.get_object(), bucket, oid);
-  if (bucket.name[0] != '.')
-    return T::raw_obj_stat(obj, psize, pmtime, pepoch, attrs, first_chunk, objv_tracker);
 
   string name = normal_name(bucket, oid);
 
   uint64_t size;
-  time_t mtime;
+  real_time mtime;
   uint64_t epoch;
 
   ObjectCacheInfo info;
diff --git a/src/rgw/rgw_civetweb.cc b/src/rgw/rgw_civetweb.cc
index 4919377..8f755d8 100644
--- a/src/rgw/rgw_civetweb.cc
+++ b/src/rgw/rgw_civetweb.cc
@@ -27,9 +27,10 @@ int RGWMongoose::write_data(const char *buf, int len)
   return r;
 }
 
-RGWMongoose::RGWMongoose(mg_connection *_conn, int _port) : conn(_conn), port(_port), status_num(0), header_done(false),
-                                                 sent_header(false), has_content_length(false),
-                                                 explicit_keepalive(false), explicit_conn_close(false)
+RGWMongoose::RGWMongoose(mg_connection *_conn, int _port)
+  : conn(_conn), port(_port), status_num(0), header_done(false),
+    sent_header(false), has_content_length(false),
+    explicit_keepalive(false), explicit_conn_close(false)
 {
 }
 
@@ -60,8 +61,8 @@ int RGWMongoose::complete_request()
         print("Transfer-Enconding: %s\r\n", "chunked");
         data.append("0\r\n\r\n", sizeof("0\r\n\r\n")-1);
       } else {
-        int r = send_content_length(data.length());
-        if (r < 0)
+	int r = send_content_length(data.length());
+	if (r < 0)
 	  return r;
       }
     }
@@ -114,11 +115,11 @@ void RGWMongoose::init_env(CephContext *cct)
       char c = *src;
       switch (c) {
        case '-':
-         c = '_';
-         break;
-       default:
-         c = toupper(c);
-         break;
+	 c = '_';
+	 break;
+      default:
+	c = toupper(c);
+	break;
       }
       *dest = c;
     }
@@ -182,7 +183,8 @@ static void dump_date_header(bufferlist &out)
   if (tmp == NULL)
     return;
 
-  if (strftime(timestr, sizeof(timestr), "Date: %a, %d %b %Y %H:%M:%S %Z\r\n", tmp))
+  if (strftime(timestr, sizeof(timestr),
+	       "Date: %a, %d %b %Y %H:%M:%S %Z\r\n", tmp))
     out.append(timestr);
 }
 
diff --git a/src/rgw/rgw_civetweb.h b/src/rgw/rgw_civetweb.h
index bf7d64a..6745081 100644
--- a/src/rgw/rgw_civetweb.h
+++ b/src/rgw/rgw_civetweb.h
@@ -10,8 +10,7 @@
 
 struct mg_connection;
 
-
-class RGWMongoose : public RGWClientIO
+class RGWMongoose : public RGWStreamIO
 {
   mg_connection *conn;
 
@@ -43,5 +42,4 @@ public:
   void flush();
 };
 
-
 #endif
diff --git a/src/rgw/rgw_civetweb_frontend.cc b/src/rgw/rgw_civetweb_frontend.cc
new file mode 100644
index 0000000..557bb5b
--- /dev/null
+++ b/src/rgw/rgw_civetweb_frontend.cc
@@ -0,0 +1,78 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+
+#include "rgw_frontend.h"
+
+#define dout_subsys ceph_subsys_rgw
+
+static int civetweb_callback(struct mg_connection* conn) {
+  struct mg_request_info* req_info = mg_get_request_info(conn);
+  RGWMongooseEnv* pe = static_cast<RGWMongooseEnv *>(req_info->user_data);
+  RGWRados* store = pe->store;
+  RGWREST* rest = pe->rest;
+  OpsLogSocket* olog = pe->olog;
+
+  RGWRequest req(store->get_new_req_id());
+  RGWMongoose client_io(conn, pe->port);
+
+  {
+    // hold a read lock over access to pe->store for reconfiguration
+    RWLock::RLocker lock(pe->mutex);
+
+    int ret = process_request(pe->store, rest, &req, &client_io, olog);
+    if (ret < 0) {
+      /* we don't really care about return code */
+      dout(20) << "process_request() returned " << ret << dendl;
+    }
+  }
+
+// Mark as processed
+  return 1;
+}
+
+int RGWMongooseFrontend::run() {
+  char thread_pool_buf[32];
+  snprintf(thread_pool_buf, sizeof(thread_pool_buf), "%d",
+	   (int)g_conf->rgw_thread_pool_size);
+  string port_str;
+  map<string, string> conf_map = conf->get_config_map();
+  conf->get_val("port", "80", &port_str);
+  conf_map.erase("port");
+  conf_map["listening_ports"] = port_str;
+  set_conf_default(conf_map, "enable_keep_alive", "yes");
+  set_conf_default(conf_map, "num_threads", thread_pool_buf);
+  set_conf_default(conf_map, "decode_url", "no");
+
+  // Set run_as_user. This will cause civetweb to invoke setuid() and setgid()
+  // based on pw_uid and pw_gid obtained from pw_name.
+  string uid_string = g_ceph_context->get_set_uid_string();
+  if (!uid_string.empty()) {
+    conf_map.erase("run_as_user");
+    conf_map["run_as_user"] = uid_string;
+  }
+
+  const char *options[conf_map.size() * 2 + 1];
+  int i = 0;
+  for (map<string, string>::iterator iter = conf_map.begin();
+       iter != conf_map.end(); ++iter) {
+    options[i] = iter->first.c_str();
+    options[i + 1] = iter->second.c_str();
+    dout(20)<< "civetweb config: " << options[i] << ": "
+	    << (options[i + 1] ? options[i + 1] : "<null>") << dendl;
+    i += 2;
+  }
+  options[i] = NULL;
+
+  struct mg_callbacks cb;
+  memset((void *)&cb, 0, sizeof(cb));
+  cb.begin_request = civetweb_callback;
+  cb.log_message = rgw_civetweb_log_callback;
+  cb.log_access = rgw_civetweb_log_access_callback;
+  ctx = mg_start(&cb, &env, (const char **)&options);
+
+  if (!ctx) {
+    return -EIO;
+  }
+
+  return 0;
+} /* RGWMongooseFrontend::run */
diff --git a/src/rgw/rgw_client_io.cc b/src/rgw/rgw_client_io.cc
index b6ef745..b326a61 100644
--- a/src/rgw/rgw_client_io.cc
+++ b/src/rgw/rgw_client_io.cc
@@ -22,8 +22,7 @@ void RGWClientIO::init(CephContext *cct) {
   }
 }
 
-
-int RGWClientIO::print(const char *format, ...)
+int RGWStreamIO::print(const char *format, ...)
 {
 #define LARGE_ENOUGH 128
   int size = LARGE_ENOUGH;
@@ -49,7 +48,7 @@ int RGWClientIO::print(const char *format, ...)
   /* not reachable */
 }
 
-int RGWClientIO::write(const char *buf, int len)
+int RGWStreamIO::write(const char *buf, int len)
 {
   if (len == 0) {
     return 0;
@@ -59,7 +58,7 @@ int RGWClientIO::write(const char *buf, int len)
   if (ret < 0)
     return ret;
 
-  if (account)
+  if (account())
     bytes_sent += ret;
 
   if (ret < len) {
@@ -70,8 +69,7 @@ int RGWClientIO::write(const char *buf, int len)
   return 0;
 }
 
-
-int RGWClientIO::read(char *buf, int max, int *actual)
+int RGWStreamIO::read(char *buf, int max, int *actual, bool hash /* = false */)
 {
   int ret = read_data(buf, max);
   if (ret < 0)
@@ -81,6 +79,17 @@ int RGWClientIO::read(char *buf, int max, int *actual)
 
   bytes_received += *actual;
 
+  if (hash) {
+    if (!sha256_hash) {
+      sha256_hash = calc_hash_sha256_open_stream();
+    }
+    calc_hash_sha256_update_stream(sha256_hash, buf, *actual);
+  }
+
   return 0;
 }
 
+string RGWStreamIO::grab_aws4_sha256_hash()
+{
+  return calc_hash_sha256_close_stream(&sha256_hash);
+}
diff --git a/src/rgw/rgw_client_io.h b/src/rgw/rgw_client_io.h
index ac610c6..09cf332 100644
--- a/src/rgw/rgw_client_io.h
+++ b/src/rgw/rgw_client_io.h
@@ -13,56 +13,74 @@
 #include "rgw_common.h"
 
 class RGWClientIO {
-  bool account;
-
-  size_t bytes_sent;
-  size_t bytes_received;
+  bool _account;
 
 protected:
   RGWEnv env;
 
   virtual void init_env(CephContext *cct) = 0;
 
+public:
+  virtual ~RGWClientIO() {}
+  RGWClientIO() : _account(false) {}
+
+  void init(CephContext *cct);
+  RGWEnv& get_env() { return env; }
+
+  bool account() { return _account; }
+  void set_account(bool _accnt) {
+    _account = _accnt;
+  }
+
+  virtual int complete_request() = 0; /* XXX signature likely changing */
+
+  virtual uint64_t get_bytes_sent() { return 0; }
+  virtual uint64_t get_bytes_received() { return 0; }
+}; /* RGWClient IO */
+
+/* HTTP IO */
+class RGWStreamIO : public RGWClientIO {
+
+  size_t bytes_sent;
+  size_t bytes_received;
+
+  SHA256 *sha256_hash;
+
+protected:
   virtual int write_data(const char *buf, int len) = 0;
   virtual int read_data(char *buf, int max) = 0;
 
 public:
-  virtual ~RGWClientIO() {}
-  RGWClientIO() : account(false), bytes_sent(0), bytes_received(0) {}
+  virtual ~RGWStreamIO() {}
+  RGWStreamIO() : bytes_sent(0), bytes_received(0), sha256_hash(nullptr) {}
 
-  void init(CephContext *cct);
   int print(const char *format, ...);
   int write(const char *buf, int len);
   virtual void flush() = 0;
-  int read(char *buf, int max, int *actual);
+  int read(char *buf, int max, int *actual, bool hash = false);
+
+  string grab_aws4_sha256_hash();
 
   virtual int send_status(int status, const char *status_name) = 0;
   virtual int send_100_continue() = 0;
   virtual int complete_header() = 0;
-  virtual int complete_request() = 0;
   virtual int send_content_length(uint64_t len) = 0;
 
-  RGWEnv& get_env() { return env; }
-
-  void set_account(bool _account) {
-    account = _account;
-  }
-
   uint64_t get_bytes_sent() { return bytes_sent; }
   uint64_t get_bytes_received() { return bytes_received; }
-};
+}; /* RGWStreamIO */
 
 
 class RGWClientIOStreamBuf : public std::streambuf {
 protected:
-  RGWClientIO &cio;
+  RGWStreamIO &sio;
   std::size_t const window_size;
   std::size_t const putback_size;
   std::vector<char> buffer;
 
 public:
-  RGWClientIOStreamBuf(RGWClientIO &c, std::size_t ws, std::size_t ps = 1)
-    : cio(c),
+  RGWClientIOStreamBuf(RGWStreamIO &s, std::size_t ws, std::size_t ps = 1)
+    : sio(s),
       window_size(ws),
       putback_size(ps),
       buffer(ws + ps)
@@ -89,7 +107,7 @@ public:
     }
 
     int read_len;
-    int ret = cio.read(base, window_size, &read_len);
+    int ret = sio.read(base, window_size, &read_len);
     if (ret < 0 || 0 == read_len) {
       return traits_type::eof();
     }
@@ -100,17 +118,16 @@ public:
   }
 };
 
-
 class RGWClientIOStream : private RGWClientIOStreamBuf, public std::istream {
 /* Inheritance from RGWClientIOStreamBuf is a kind of shadow, undirect
  * form of composition here. We cannot do that explicitly because istream
  * ctor is being called prior to construction of any member of this class. */
 
 public:
-  explicit RGWClientIOStream(RGWClientIO &c)
-    : RGWClientIOStreamBuf(c, 1, 2),
+  explicit RGWClientIOStream(RGWStreamIO &s)
+    : RGWClientIOStreamBuf(s, 1, 2),
       istream(static_cast<RGWClientIOStreamBuf *>(this)) {
   }
 };
 
-#endif
+#endif /* CEPH_RGW_CLIENT_IO_H */
diff --git a/src/rgw/rgw_common.cc b/src/rgw/rgw_common.cc
index 80b6c1b..d597339 100644
--- a/src/rgw/rgw_common.cc
+++ b/src/rgw/rgw_common.cc
@@ -97,11 +97,48 @@ is_err() const
   return !(http_ret >= 200 && http_ret <= 399);
 }
 
+static bool starts_with(const string& s, const string& prefix) {
+  if (s.size() < prefix.size()) {
+    return false;
+  }
+  for (unsigned int i = 0; i < prefix.size(); ++i) {
+    if (prefix[i] != s[i]) {
+      return false;
+    }
+  }
+  return true;
+}
+
+// The requestURI transferred from the frontend can be abs_path or absoluteURI
+// If it is absoluteURI, we should adjust it to abs_path for the following 
+// S3 authorization and some other processes depending on the requestURI
+// The absoluteURI can start with "http://", "https://", "ws://" or "wss://"
+static string get_abs_path(const string& request_uri) {
+  const static string ABS_PREFIXS[] = {"http://", "https://", "ws://", "wss://"};
+  bool isAbs = false;
+  for (int i = 0; i < 4; ++i) {
+    if (starts_with(request_uri, ABS_PREFIXS[i])) {
+      isAbs = true;
+      break;
+    } 
+  }
+  if (!isAbs) {  // it is not a valid absolute uri
+    return request_uri;
+  }
+  size_t beg_pos = request_uri.find("://") + 3;
+  size_t len = request_uri.size();
+  beg_pos = request_uri.find('/', beg_pos);
+  if (beg_pos == string::npos) return request_uri;
+  return request_uri.substr(beg_pos, len - beg_pos);
+}
 
 req_info::req_info(CephContext *cct, class RGWEnv *e) : env(e) {
   method = env->get("REQUEST_METHOD", "");
   script_uri = env->get("SCRIPT_URI", cct->_conf->rgw_script_uri.c_str());
   request_uri = env->get("REQUEST_URI", cct->_conf->rgw_request_uri.c_str());
+  if (request_uri[0] != '/') {
+    request_uri = get_abs_path(request_uri);
+  }
   int pos = request_uri.find('?');
   if (pos >= 0) {
     request_params = request_uri.substr(pos + 1);
@@ -144,9 +181,9 @@ void req_info::rebuild_from(req_info& src)
 }
 
 
-req_state::req_state(CephContext *_cct, class RGWEnv *e) : cct(_cct), cio(NULL), op(OP_UNKNOWN),
-							   has_acl_header(false),
-                                                           os_auth_token(NULL), info(_cct, e)
+req_state::req_state(CephContext* _cct, RGWEnv* e, RGWUserInfo* u)
+  : cct(_cct), cio(NULL), op(OP_UNKNOWN), user(u), has_acl_header(false),
+    os_auth_token(NULL), info(_cct, e)
 {
   enable_ops_log = e->conf->enable_ops_log;
   enable_usage_log = e->conf->enable_usage_log;
@@ -157,6 +194,7 @@ req_state::req_state(CephContext *_cct, class RGWEnv *e) : cct(_cct), cio(NULL),
   bucket_acl = NULL;
   object_acl = NULL;
   expect_cont = false;
+  aws4_auth_needs_complete = false;
 
   header_ended = false;
   obj_size = 0;
@@ -167,6 +205,7 @@ req_state::req_state(CephContext *_cct, class RGWEnv *e) : cct(_cct), cio(NULL),
   os_auth_token = NULL;
   time = ceph_clock_now(cct);
   perm_mask = 0;
+  bucket_instance_shard_id = -1;
   content_length = 0;
   bucket_exists = false;
   has_bad_meta = false;
@@ -174,6 +213,8 @@ req_state::req_state(CephContext *_cct, class RGWEnv *e) : cct(_cct), cio(NULL),
   http_auth = NULL;
   local_source = false;
 
+  aws4_auth = NULL;
+
   obj_ctx = NULL;
 }
 
@@ -181,6 +222,7 @@ req_state::~req_state() {
   delete formatter;
   delete bucket_acl;
   delete object_acl;
+  delete aws4_auth;
 }
 
 struct str_len {
@@ -346,10 +388,22 @@ bool parse_rfc2616(const char *s, struct tm *t)
   return parse_rfc850(s, t) || parse_asctime(s, t) || parse_rfc1123(s, t) || parse_rfc1123_alt(s,t);
 }
 
-bool parse_iso8601(const char *s, struct tm *t)
+bool parse_iso8601(const char *s, struct tm *t, uint32_t *pns, bool extended_format)
 {
   memset(t, 0, sizeof(*t));
-  const char *p = strptime(s, "%Y-%m-%dT%T", t);
+  const char *p;
+
+  if (!s)
+    s = "";
+
+  if (extended_format) {
+    p = strptime(s, "%Y-%m-%dT%T", t);
+    if (!p) {
+      p = strptime(s, "%Y-%m-%d %T", t);
+    }
+  } else {
+    p = strptime(s, "%Y%m%dT%H%M%S", t);
+  }
   if (!p) {
     dout(0) << "parse_iso8601 failed" << dendl;
     return false;
@@ -366,10 +420,33 @@ bool parse_iso8601(const char *s, struct tm *t)
     return false;
 
   uint32_t ms;
-  int r = stringtoul(str.substr(1, len - 2), &ms);
+  string nsstr = str.substr(1,  len - 2);
+  int r = stringtoul(nsstr, &ms);
   if (r < 0)
     return false;
 
+  if (!pns) {
+    return true;
+  }
+
+  if (nsstr.size() > 9) {
+    nsstr = nsstr.substr(0, 9);
+  }
+
+  uint64_t mul_table[] = { 0,
+    100000000LL,
+    10000000LL,
+    1000000LL,
+    100000LL,
+    10000LL,
+    1000LL,
+    100LL,
+    10LL,
+    1 };
+
+
+  *pns = ms * mul_table[nsstr.size()];
+
   return true;
 }
 
@@ -395,14 +472,17 @@ int parse_key_value(string& in_str, string& key, string& val)
   return parse_key_value(in_str, "=", key,val);
 }
 
-int parse_time(const char *time_str, time_t *time)
+int parse_time(const char *time_str, real_time *time)
 {
   struct tm tm;
+  uint32_t ns = 0;
 
-  if (!parse_rfc2616(time_str, &tm))
+  if (!parse_rfc2616(time_str, &tm) && !parse_iso8601(time_str, &tm, &ns)) {
     return -EINVAL;
+  }
 
-  *time = timegm(&tm);
+  time_t sec = timegm(&tm);
+  *time = utime_t(sec, ns).to_real_time();
 
   return 0;
 }
@@ -419,6 +499,69 @@ void calc_hmac_sha1(const char *key, int key_len,
   hmac.Final((unsigned char *)dest);
 }
 
+/*
+ * calculate the sha256 value of a given msg and key
+ */
+void calc_hmac_sha256(const char *key, int key_len,
+                      const char *msg, int msg_len, char *dest)
+{
+  char hash_sha256[CEPH_CRYPTO_HMACSHA256_DIGESTSIZE];
+
+  HMACSHA256 hmac((const unsigned char *)key, key_len);
+  hmac.Update((const unsigned char *)msg, msg_len);
+  hmac.Final((unsigned char *)hash_sha256);
+
+  memcpy(dest, hash_sha256, CEPH_CRYPTO_HMACSHA256_DIGESTSIZE);
+}
+
+/*
+ * calculate the sha256 hash value of a given msg
+ */
+void calc_hash_sha256(const char *msg, int len, string& dest)
+{
+  char hash_sha256[CEPH_CRYPTO_HMACSHA256_DIGESTSIZE];
+
+  SHA256 hash;
+  hash.Update((const unsigned char *)msg, len);
+  hash.Final((unsigned char *)hash_sha256);
+
+  char hex_str[(CEPH_CRYPTO_SHA256_DIGESTSIZE * 2) + 1];
+  buf_to_hex((unsigned char *)hash_sha256, CEPH_CRYPTO_SHA256_DIGESTSIZE, hex_str);
+
+  dest = std::string(hex_str);
+}
+
+using ceph::crypto::SHA256;
+
+SHA256* calc_hash_sha256_open_stream()
+{
+  return new SHA256;
+}
+
+void calc_hash_sha256_update_stream(SHA256 *hash, const char *msg, int len)
+{
+  hash->Update((const unsigned char *)msg, len);
+}
+
+string calc_hash_sha256_close_stream(SHA256 **phash)
+{
+  SHA256 *hash = *phash;
+  if (!hash) {
+    hash = calc_hash_sha256_open_stream();
+  }
+  char hash_sha256[CEPH_CRYPTO_HMACSHA256_DIGESTSIZE];
+
+  hash->Final((unsigned char *)hash_sha256);
+
+  char hex_str[(CEPH_CRYPTO_SHA256_DIGESTSIZE * 2) + 1];
+  buf_to_hex((unsigned char *)hash_sha256, CEPH_CRYPTO_SHA256_DIGESTSIZE, hex_str);
+
+  delete hash;
+  *phash = NULL;
+  
+  return std::string(hex_str);
+}
+
 int gen_rand_base64(CephContext *cct, char *dest, int size) /* size should be the required string size + 1 */
 {
   char buf[size];
@@ -577,7 +720,6 @@ int RGWHTTPArgs::parse()
 {
   int pos = 0;
   bool end = false;
-  bool admin_subresource_added = false; 
   if (str[pos] == '?') pos++;
 
   while (!end) {
@@ -595,50 +737,7 @@ int RGWHTTPArgs::parse()
       string& name = nv.get_name();
       string& val = nv.get_val();
 
-      if (name.compare(0, sizeof(RGW_SYS_PARAM_PREFIX) - 1, RGW_SYS_PARAM_PREFIX) == 0) {
-        sys_val_map[name] = val;
-      } else {
-        val_map[name] = val;
-      }
-
-      if ((name.compare("acl") == 0) ||
-          (name.compare("cors") == 0) ||
-          (name.compare("location") == 0) ||
-          (name.compare("logging") == 0) ||
-          (name.compare("delete") == 0) ||
-          (name.compare("uploads") == 0) ||
-          (name.compare("partNumber") == 0) ||
-          (name.compare("uploadId") == 0) ||
-          (name.compare("versionId") == 0) ||
-          (name.compare("versions") == 0) ||
-          (name.compare("versioning") == 0) ||
-          (name.compare("website") == 0) ||
-          (name.compare("requestPayment") == 0) ||
-          (name.compare("torrent") == 0)) {
-        sub_resources[name] = val;
-      } else if (name[0] == 'r') { // root of all evil
-        if ((name.compare("response-content-type") == 0) ||
-           (name.compare("response-content-language") == 0) ||
-           (name.compare("response-expires") == 0) ||
-           (name.compare("response-cache-control") == 0) ||
-           (name.compare("response-content-disposition") == 0) ||
-           (name.compare("response-content-encoding") == 0)) {
-          sub_resources[name] = val;
-          has_resp_modifier = true;
-        }
-      } else if  ((name.compare("subuser") == 0) ||
-          (name.compare("key") == 0) ||
-          (name.compare("caps") == 0) ||
-          (name.compare("index") == 0) ||
-          (name.compare("policy") == 0) ||
-          (name.compare("quota") == 0) ||
-          (name.compare("object") == 0)) {
-
-        if (!admin_subresource_added) {
-          sub_resources[name] = "";
-          admin_subresource_added = true;
-        }
-      }
+      append(name, val);
     }
 
     pos = fpos + 1;  
@@ -647,6 +746,57 @@ int RGWHTTPArgs::parse()
   return 0;
 }
 
+void RGWHTTPArgs::append(const string& name, const string& val)
+{
+  if (name.compare(0, sizeof(RGW_SYS_PARAM_PREFIX) - 1, RGW_SYS_PARAM_PREFIX) == 0) {
+    sys_val_map[name] = val;
+  } else {
+    val_map[name] = val;
+  }
+
+  if ((name.compare("acl") == 0) ||
+      (name.compare("cors") == 0) ||
+      (name.compare("location") == 0) ||
+      (name.compare("logging") == 0) ||
+      (name.compare("usage") == 0) ||
+      (name.compare("delete") == 0) ||
+      (name.compare("uploads") == 0) ||
+      (name.compare("partNumber") == 0) ||
+      (name.compare("uploadId") == 0) ||
+      (name.compare("versionId") == 0) ||
+      (name.compare("start-date") == 0) ||
+      (name.compare("end-date") == 0) ||
+      (name.compare("versions") == 0) ||
+      (name.compare("versioning") == 0) ||
+      (name.compare("website") == 0) ||
+      (name.compare("requestPayment") == 0) ||
+      (name.compare("torrent") == 0)) {
+    sub_resources[name] = val;
+  } else if (name[0] == 'r') { // root of all evil
+    if ((name.compare("response-content-type") == 0) ||
+        (name.compare("response-content-language") == 0) ||
+        (name.compare("response-expires") == 0) ||
+        (name.compare("response-cache-control") == 0) ||
+        (name.compare("response-content-disposition") == 0) ||
+        (name.compare("response-content-encoding") == 0)) {
+      sub_resources[name] = val;
+      has_resp_modifier = true;
+    }
+  } else if  ((name.compare("subuser") == 0) ||
+              (name.compare("key") == 0) ||
+              (name.compare("caps") == 0) ||
+              (name.compare("index") == 0) ||
+              (name.compare("policy") == 0) ||
+              (name.compare("quota") == 0) ||
+              (name.compare("object") == 0)) {
+
+    if (!admin_subresource_added) {
+      sub_resources[name] = "";
+      admin_subresource_added = true;
+    }
+  }
+}
+
 string& RGWHTTPArgs::get(const string& name, bool *exists)
 {
   map<string, string>::iterator iter;
@@ -659,13 +809,6 @@ string& RGWHTTPArgs::get(const string& name, bool *exists)
   return empty_str;
 }
 
-string& RGWHTTPArgs::get(const char *name, bool *exists)
-{
-  string s(name);
-  return get(s, exists);
-}
-
-
 int RGWHTTPArgs::get_bool(const string& name, bool *val, bool *exists)
 {
   map<string, string>::iterator iter;
@@ -704,12 +847,24 @@ void RGWHTTPArgs::get_bool(const char *name, bool *val, bool def_val)
   }
 }
 
+string RGWHTTPArgs::sys_get(const string& name, bool * const exists)
+{
+  const auto iter = sys_val_map.find(name);
+  const bool e = (iter != val_map.end());
+
+  if (exists) {
+    *exists = e;
+  }
+
+  return e ? iter->second : string();
+}
+
 bool verify_requester_payer_permission(struct req_state *s)
 {
   if (!s->bucket_info.requester_pays)
     return true;
 
-  if (s->bucket_info.owner == s->user.user_id)
+  if (s->bucket_info.owner == s->user->user_id)
     return true;
 
   const char *request_payer = s->info.env->get("HTTP_X_AMZ_REQUEST_PAYER");
@@ -741,7 +896,7 @@ bool verify_bucket_permission(struct req_state * const s,
   if (!verify_requester_payer_permission(s))
     return false;
 
-  return bucket_acl->verify_permission(s->user.user_id, perm, perm);
+  return bucket_acl->verify_permission(s->user->user_id, perm, perm);
 }
 
 bool verify_bucket_permission(struct req_state * const s, const int perm)
@@ -754,9 +909,6 @@ static inline bool check_deferred_bucket_acl(struct req_state * const s,
                                              const uint8_t deferred_check,
                                              const int perm)
 {
-  if (!verify_requester_payer_permission(s))
-    return false;
-
   return (s->defer_to_bucket_acls == deferred_check \
               && verify_bucket_permission(s, bucket_acl, perm));
 }
@@ -766,6 +918,9 @@ bool verify_object_permission(struct req_state * const s,
                               RGWAccessControlPolicy * const object_acl,
                               const int perm)
 {
+  if (!verify_requester_payer_permission(s))
+    return false;
+
   if (check_deferred_bucket_acl(s, bucket_acl, RGW_DEFER_TO_BUCKET_ACLS_RECURSE, perm) ||
       check_deferred_bucket_acl(s, bucket_acl, RGW_DEFER_TO_BUCKET_ACLS_FULL_CONTROL, RGW_PERM_FULL_CONTROL)) {
     return true;
@@ -774,7 +929,8 @@ bool verify_object_permission(struct req_state * const s,
   if (!object_acl)
     return false;
 
-  bool ret = object_acl->verify_permission(s->user.user_id, s->perm_mask, perm);
+  bool ret = object_acl->verify_permission(s->user->user_id, s->perm_mask,
+					  perm);
   if (ret)
     return true;
 
@@ -794,7 +950,8 @@ bool verify_object_permission(struct req_state * const s,
     return false;
   /* we already verified the user mask above, so we pass swift_perm as the mask here,
      otherwise the mask might not cover the swift permissions bits */
-  return bucket_acl->verify_permission(s->user.user_id, swift_perm, swift_perm);
+  return bucket_acl->verify_permission(s->user->user_id, swift_perm,
+				      swift_perm);
 }
 
 bool verify_object_permission(struct req_state *s, int perm)
@@ -868,7 +1025,7 @@ bool url_decode(const string& src_str, string& dest_str, bool in_query)
   return true;
 }
 
-static void escape_char(char c, string& dst)
+void rgw_uri_escape_char(char c, string& dst)
 {
   char buf[16];
   snprintf(buf, sizeof(buf), "%%%.2X", (int)(unsigned char)c);
@@ -912,7 +1069,7 @@ void url_encode(const string& src, string& dst)
   const char *p = src.c_str();
   for (unsigned i = 0; i < src.size(); i++, p++) {
     if (char_needs_url_encoding(*p)) {
-      escape_char(*p, dst);
+      rgw_uri_escape_char(*p, dst);
       continue;
     }
 
diff --git a/src/rgw/rgw_common.h b/src/rgw/rgw_common.h
index 85405de..90d2ae5 100644
--- a/src/rgw/rgw_common.h
+++ b/src/rgw/rgw_common.h
@@ -17,6 +17,7 @@
 #define CEPH_RGW_COMMON_H
 
 #include "common/ceph_crypto.h"
+
 #include "common/debug.h"
 #include "common/perf_counters.h"
 
@@ -81,6 +82,9 @@ using ceph::crypto::MD5;
  * user through custom HTTP header named X-Static-Large-Object. */
 #define RGW_ATTR_SLO_UINDICATOR RGW_ATTR_META_PREFIX "static-large-object"
 
+#define RGW_ATTR_PG_VER 	RGW_ATTR_PREFIX "pg_ver"
+#define RGW_ATTR_SOURCE_ZONE    RGW_ATTR_PREFIX "source_zone"
+
 #define RGW_ATTR_TEMPURL_KEY1   RGW_ATTR_META_PREFIX "temp-url-key"
 #define RGW_ATTR_TEMPURL_KEY2   RGW_ATTR_META_PREFIX "temp-url-key-2"
 
@@ -172,6 +176,7 @@ using ceph::crypto::MD5;
 #define ERR_INVALID_TENANT_NAME  2037
 #define ERR_WEBSITE_REDIRECT     2038
 #define ERR_NO_SUCH_WEBSITE_CONFIGURATION 2039
+#define ERR_AMZ_CONTENT_SHA256_MISMATCH 2040
 #define ERR_USER_SUSPENDED       2100
 #define ERR_INTERNAL_ERROR       2200
 #define ERR_NOT_IMPLEMENTED      2201
@@ -275,10 +280,10 @@ class RGWHTTPArgs
   map<string, string> val_map;
   map<string, string> sys_val_map;
   map<string, string> sub_resources;
-
   bool has_resp_modifier;
+  bool admin_subresource_added;
  public:
-  RGWHTTPArgs() : has_resp_modifier(false) {}
+  RGWHTTPArgs() : has_resp_modifier(false), admin_subresource_added(false) {}
 
   /** Set the arguments; as received */
   void set(string s) {
@@ -289,13 +294,16 @@ class RGWHTTPArgs
   }
   /** parse the received arguments */
   int parse();
+  void append(const string& name, const string& val);
   /** Get the value for a specific argument parameter */
   string& get(const string& name, bool *exists = NULL);
-  string& get(const char *name, bool *exists = NULL);
   int get_bool(const string& name, bool *val, bool *exists);
   int get_bool(const char *name, bool *val, bool *exists);
   void get_bool(const char *name, bool *val, bool def_val);
 
+  /** Get the value for specific system argument parameter */
+  string sys_get(const string& name, bool *exists = nullptr);
+
   /** see if a parameter is contained in this RGWHTTPArgs */
   bool exists(const char *name) {
     map<string, string>::iterator iter = val_map.find(name);
@@ -371,6 +379,49 @@ enum http_op {
   OP_UNKNOWN,
 };
 
+enum RGWOpType {
+  RGW_OP_UNKNOWN = 0,
+  RGW_OP_GET_OBJ,
+  RGW_OP_LIST_BUCKETS,
+  RGW_OP_STAT_ACCOUNT,
+  RGW_OP_LIST_BUCKET,
+  RGW_OP_GET_BUCKET_LOGGING,
+  RGW_OP_GET_BUCKET_VERSIONING,
+  RGW_OP_SET_BUCKET_VERSIONING,
+  RGW_OP_GET_BUCKET_WEBSITE,
+  RGW_OP_SET_BUCKET_WEBSITE,
+  RGW_OP_STAT_BUCKET,
+  RGW_OP_CREATE_BUCKET,
+  RGW_OP_DELETE_BUCKET,
+  RGW_OP_PUT_OBJ,
+  RGW_OP_STAT_OBJ,
+  RGW_OP_POST_OBJ,
+  RGW_OP_PUT_METADATA_ACCOUNT,
+  RGW_OP_PUT_METADATA_BUCKET,
+  RGW_OP_PUT_METADATA_OBJECT,
+  RGW_OP_SET_TEMPURL,
+  RGW_OP_DELETE_OBJ,
+  RGW_OP_COPY_OBJ,
+  RGW_OP_GET_ACLS,
+  RGW_OP_PUT_ACLS,
+  RGW_OP_GET_CORS,
+  RGW_OP_PUT_CORS,
+  RGW_OP_DELETE_CORS,
+  RGW_OP_OPTIONS_CORS,
+  RGW_OP_GET_REQUEST_PAYMENT,
+  RGW_OP_SET_REQUEST_PAYMENT,
+  RGW_OP_INIT_MULTIPART,
+  RGW_OP_COMPLETE_MULTIPART,
+  RGW_OP_ABORT_MULTIPART,
+  RGW_OP_LIST_MULTIPART,
+  RGW_OP_LIST_BUCKET_MULTIPARTS,
+  RGW_OP_DELETE_MULTI_OBJ,
+  RGW_OP_BULK_DELETE,
+
+  /* rgw specific */
+  RGW_OP_ADMIN_SET_METADATA
+};
+
 class RGWAccessControlPolicy;
 class JSONObj;
 
@@ -380,6 +431,9 @@ struct RGWAccessKey {
   string subuser;
 
   RGWAccessKey() {}
+  RGWAccessKey(std::string _id, std::string _key)
+    : id(std::move(_id)), key(std::move(_key)) {}
+
   void encode(bufferlist& bl) const {
     ENCODE_START(2, 2, bl);
     ::encode(id, bl);
@@ -489,6 +543,13 @@ struct RGWUserInfo
 
   RGWUserInfo() : auid(0), suspended(0), max_buckets(RGW_DEFAULT_MAX_BUCKETS), op_mask(RGW_OP_TYPE_ALL), system(0) {}
 
+  RGWAccessKey* get_key0() {
+    if (access_keys.empty())
+      return nullptr;
+    else
+      return &(access_keys.begin()->second);
+  }
+
   void encode(bufferlist& bl) const {
      ENCODE_START(17, 9, bl);
      ::encode(auid, bl);
@@ -627,9 +688,11 @@ struct rgw_bucket {
 					 data_extra_pool(b.data_extra_pool),
 					 index_pool(b.index_pool), marker(b.marker),
 					 bucket_id(b.bucket_id) {}
-  // cppcheck-suppress noExplicitConstructor
+  rgw_bucket(const string& s) : name(s) {
+    data_pool = index_pool = s;
+    marker = "";
+  }
   rgw_bucket(const char *n) : name(n) {
-    assert(*n == '.'); // only rgw private buckets should be initialized without pool
     data_pool = index_pool = n;
     marker = "";
   }
@@ -788,6 +851,11 @@ enum RGWBucketFlags {
   BUCKET_VERSIONS_SUSPENDED = 0x4,
 };
 
+enum RGWBucketIndexType {
+  RGWBIType_Normal = 0,
+  RGWBIType_Indexless = 1,
+};
+
 struct RGWBucketInfo
 {
   enum BIShardsHashType {
@@ -797,8 +865,8 @@ struct RGWBucketInfo
   rgw_bucket bucket;
   rgw_user owner;
   uint32_t flags;
-  string region;
-  time_t creation_time;
+  string zonegroup;
+  ceph::real_time creation_time;
   string placement_rule;
   bool has_instance_obj;
   RGWObjVersionTracker objv_tracker; /* we don't need to serialize this, for runtime tracking */
@@ -822,13 +890,19 @@ struct RGWBucketInfo
   bool has_website;
   RGWBucketWebsiteConf website_conf;
 
+  RGWBucketIndexType index_type;
+
+  bool swift_versioning;
+  string swift_ver_location;
+
+
   void encode(bufferlist& bl) const {
-     ENCODE_START(14, 4, bl);
+     ENCODE_START(17, 4, bl);
      ::encode(bucket, bl);
      ::encode(owner.id, bl);
      ::encode(flags, bl);
-     ::encode(region, bl);
-     uint64_t ct = (uint64_t)creation_time;
+     ::encode(zonegroup, bl);
+     uint64_t ct = real_clock::to_time_t(creation_time);
      ::encode(ct, bl);
      ::encode(placement_rule, bl);
      ::encode(has_instance_obj, bl);
@@ -841,10 +915,16 @@ struct RGWBucketInfo
      if (has_website) {
        ::encode(website_conf, bl);
      }
+     ::encode((uint32_t)index_type, bl);
+     ::encode(swift_versioning, bl);
+     if (swift_versioning) {
+       ::encode(swift_ver_location, bl);
+     }
+     ::encode(creation_time, bl);
      ENCODE_FINISH(bl);
   }
   void decode(bufferlist::iterator& bl) {
-    DECODE_START_LEGACY_COMPAT_LEN_32(14, 4, 4, bl);
+    DECODE_START_LEGACY_COMPAT_LEN_32(17, 4, 4, bl);
      ::decode(bucket, bl);
      if (struct_v >= 2) {
        string s;
@@ -854,11 +934,12 @@ struct RGWBucketInfo
      if (struct_v >= 3)
        ::decode(flags, bl);
      if (struct_v >= 5)
-       ::decode(region, bl);
+       ::decode(zonegroup, bl);
      if (struct_v >= 6) {
        uint64_t ct;
        ::decode(ct, bl);
-       creation_time = (time_t)ct;
+       if (struct_v < 17)
+	 creation_time = ceph::real_clock::from_time_t((time_t)ct);
      }
      if (struct_v >= 7)
        ::decode(placement_rule, bl);
@@ -882,6 +963,24 @@ struct RGWBucketInfo
          website_conf = RGWBucketWebsiteConf();
        }
      }
+     if (struct_v >= 15) {
+       uint32_t it;
+       ::decode(it, bl);
+       index_type = (RGWBucketIndexType)it;
+     } else {
+       index_type = RGWBIType_Normal;
+     }
+     swift_versioning = false;
+     swift_ver_location.clear();
+     if (struct_v >= 16) {
+       ::decode(swift_versioning, bl);
+       if (swift_versioning) {
+         ::decode(swift_ver_location, bl);
+       }
+     }
+     if (struct_v >= 17) {
+       ::decode(creation_time, bl);
+     }
      DECODE_FINISH(bl);
   }
   void dump(Formatter *f) const;
@@ -893,8 +992,10 @@ struct RGWBucketInfo
   int versioning_status() { return flags & (BUCKET_VERSIONED | BUCKET_VERSIONS_SUSPENDED); }
   bool versioning_enabled() { return versioning_status() == BUCKET_VERSIONED; }
 
-  RGWBucketInfo() : flags(0), creation_time(0), has_instance_obj(false), num_shards(0), bucket_index_shard_hash_type(MOD), requester_pays(false),
-                    has_website(false) {}
+  bool has_swift_versioning() { return swift_versioning; }
+
+  RGWBucketInfo() : flags(0), has_instance_obj(false), num_shards(0), bucket_index_shard_hash_type(MOD), requester_pays(false),
+                    has_website(false), swift_versioning(false) {}
 };
 WRITE_CLASS_ENCODER(RGWBucketInfo)
 
@@ -902,27 +1003,28 @@ struct RGWBucketEntryPoint
 {
   rgw_bucket bucket;
   rgw_user owner;
-  time_t creation_time;
+  ceph::real_time creation_time;
   bool linked;
 
   bool has_bucket_info;
   RGWBucketInfo old_bucket_info;
 
-  RGWBucketEntryPoint() : creation_time(0), linked(false), has_bucket_info(false) {}
+  RGWBucketEntryPoint() : linked(false), has_bucket_info(false) {}
 
   void encode(bufferlist& bl) const {
-    ENCODE_START(9, 8, bl);
+    ENCODE_START(10, 8, bl);
     ::encode(bucket, bl);
     ::encode(owner.id, bl);
     ::encode(linked, bl);
-    uint64_t ctime = (uint64_t)creation_time;
+    uint64_t ctime = (uint64_t)real_clock::to_time_t(creation_time);
     ::encode(ctime, bl);
     ::encode(owner, bl);
+    ::encode(creation_time, bl);
     ENCODE_FINISH(bl);
   }
   void decode(bufferlist::iterator& bl) {
     bufferlist::iterator orig_iter = bl;
-    DECODE_START_LEGACY_COMPAT_LEN_32(9, 4, 4, bl);
+    DECODE_START_LEGACY_COMPAT_LEN_32(10, 4, 4, bl);
     if (struct_v < 8) {
       /* ouch, old entry, contains the bucket info itself */
       old_bucket_info.decode(orig_iter);
@@ -935,10 +1037,15 @@ struct RGWBucketEntryPoint
     ::decode(linked, bl);
     uint64_t ctime;
     ::decode(ctime, bl);
-    creation_time = (uint64_t)ctime;
+    if (struct_v < 10) {
+      creation_time = real_clock::from_time_t((time_t)ctime);
+    }
     if (struct_v >= 9) {
       ::decode(owner, bl);
     }
+    if (struct_v >= 10) {
+      ::decode(creation_time, bl);
+    }
     DECODE_FINISH(bl);
   }
 
@@ -1062,90 +1169,123 @@ inline ostream& operator<<(ostream& out, const rgw_obj_key &o) {
   }
 }
 
+struct rgw_aws4_auth {
+  string date;
+  string expires;
+  string credential;
+  string signedheaders;
+  string signed_hdrs;
+  string access_key_id;
+  string credential_scope;
+  string canonical_uri;
+  string canonical_qs;
+  string canonical_hdrs;
+  string signature;
+  string new_signature;
+  string payload_hash;
+};
+
 struct req_init_state {
   /* Keeps [[tenant]:]bucket until we parse the token. */
   string url_bucket;
   string src_bucket;
 };
 
+/* XXX why don't RGWRequest (or descendants) hold this state? */
+class RGWRequest;
+
 /** Store all the state necessary to complete and respond to an HTTP request*/
 struct req_state {
-   CephContext *cct;
-   RGWClientIO *cio;
-   http_op op;
-   bool content_started;
-   int format;
-   ceph::Formatter *formatter;
-   string decoded_uri;
-   string relative_uri;
-   const char *length;
-   int64_t content_length;
-   map<string, string> generic_attrs;
-   struct rgw_err err;
-   bool expect_cont;
-   bool header_ended;
-   uint64_t obj_size;
-   bool enable_ops_log;
-   bool enable_usage_log;
-   uint8_t defer_to_bucket_acls;
-   uint32_t perm_mask;
-   utime_t header_time;
-
-   /* Set once when url_bucket is parsed and not violated thereafter. */
-   string bucket_tenant;
-   string bucket_name;
-
-   rgw_bucket bucket;
-   rgw_obj_key object;
-   string src_tenant_name;
-   string src_bucket_name;
-   rgw_obj_key src_object;
-   ACLOwner bucket_owner;
-   ACLOwner owner;
-
-   string region_endpoint;
-   string bucket_instance_id;
-
-   string redirect;
-
-   RGWBucketInfo bucket_info;
-   map<string, bufferlist> bucket_attrs;
-   bool bucket_exists;
-
-   bool has_bad_meta;
-
-   RGWUserInfo user; 
-   RGWAccessControlPolicy *bucket_acl;
-   RGWAccessControlPolicy *object_acl;
-
-   bool system_request;
-
-   string canned_acl;
-   bool has_acl_header;
-   const char *http_auth;
-   bool local_source; /* source is local */
-
-   int prot_flags;
-
-   const char *os_auth_token;
-   string swift_user;
-   string swift_groups;
-
-   utime_t time;
-
-   void *obj_ctx;
-
-   string dialect;
-
-   string req_id;
-
-   string trans_id;
-
-   req_info info;
-   req_init_state init_state;
-
-   req_state(CephContext *_cct, class RGWEnv *e);
-   ~req_state();
+  CephContext *cct;
+  RGWClientIO *cio;
+  RGWRequest *req; /// XXX: re-remove??
+  http_op op;
+  RGWOpType op_type;
+  bool content_started;
+  int format;
+  ceph::Formatter *formatter;
+  string decoded_uri;
+  string relative_uri;
+  const char *length;
+  int64_t content_length;
+  map<string, string> generic_attrs;
+  struct rgw_err err;
+  bool expect_cont;
+  bool header_ended;
+  uint64_t obj_size;
+  bool enable_ops_log;
+  bool enable_usage_log;
+  uint8_t defer_to_bucket_acls;
+  uint32_t perm_mask;
+  utime_t header_time;
+
+  /* Set once when url_bucket is parsed and not violated thereafter. */
+  string account_name;
+
+  string bucket_tenant;
+  string bucket_name;
+
+  rgw_bucket bucket;
+  rgw_obj_key object;
+  string src_tenant_name;
+  string src_bucket_name;
+  rgw_obj_key src_object;
+  ACLOwner bucket_owner;
+  ACLOwner owner;
+
+  string zonegroup_name;
+  string zonegroup_endpoint;
+  string bucket_instance_id;
+  int bucket_instance_shard_id;
+
+  string redirect;
+
+  RGWBucketInfo bucket_info;
+  map<string, bufferlist> bucket_attrs;
+  bool bucket_exists;
+
+  bool has_bad_meta;
+
+  RGWUserInfo *user;
+
+  RGWAccessControlPolicy *bucket_acl;
+  RGWAccessControlPolicy *object_acl;
+
+  bool system_request;
+
+  /* aws4 auth support */
+  bool aws4_auth_needs_complete;
+  rgw_aws4_auth *aws4_auth;
+
+  string canned_acl;
+  bool has_acl_header;
+  const char *http_auth;
+  bool local_source; /* source is local */
+
+  int prot_flags;
+
+  const char *os_auth_token;
+  string swift_user;
+  string swift_groups;
+  /* Content-Disposition override for TempURL of Swift API. */
+  struct {
+    string override;
+    string fallback;
+  } content_disp;
+
+  string host_id;
+
+  req_info info;
+  req_init_state init_state;
+
+  utime_t time;
+  void *obj_ctx;
+  string dialect;
+  string req_id;
+  string trans_id;
+
+  req_state(CephContext* _cct, RGWEnv* e, RGWUserInfo* u);
+  ~req_state();
 };
 
 /** Store basic data on an object */
@@ -1155,7 +1295,7 @@ struct RGWObjEnt {
   rgw_user owner;
   std::string owner_display_name;
   uint64_t size;
-  utime_t mtime;
+  ceph::real_time mtime;
   string etag;
   string content_type;
   string tag;
@@ -1182,10 +1322,10 @@ struct RGWBucketEnt {
   rgw_bucket bucket;
   size_t size;
   size_t size_rounded;
-  time_t creation_time;
+  real_time creation_time;
   uint64_t count;
 
-  RGWBucketEnt() : size(0), size_rounded(0), creation_time(0), count(0) {}
+  RGWBucketEnt() : size(0), size_rounded(0), count(0) {}
 
   explicit RGWBucketEnt(const cls_user_bucket_entry& e) : bucket(e.bucket),
 		  					  size(e.size), 
@@ -1202,9 +1342,9 @@ struct RGWBucketEnt {
   }
 
   void encode(bufferlist& bl) const {
-    ENCODE_START(5, 5, bl);
+    ENCODE_START(6, 5, bl);
     uint64_t s = size;
-    __u32 mt = creation_time;
+    __u32 mt = ceph::real_clock::to_time_t(creation_time);
     string empty_str;  // originally had the bucket name here, but we encode bucket later
     ::encode(empty_str, bl);
     ::encode(s, bl);
@@ -1213,10 +1353,11 @@ struct RGWBucketEnt {
     ::encode(bucket, bl);
     s = size_rounded;
     ::encode(s, bl);
+    ::encode(creation_time, bl);
     ENCODE_FINISH(bl);
   }
   void decode(bufferlist::iterator& bl) {
-    DECODE_START_LEGACY_COMPAT_LEN(5, 5, 5, bl);
+    DECODE_START_LEGACY_COMPAT_LEN(6, 5, 5, bl);
     __u32 mt;
     uint64_t s;
     string empty_str;  // backward compatibility
@@ -1224,7 +1365,9 @@ struct RGWBucketEnt {
     ::decode(s, bl);
     ::decode(mt, bl);
     size = s;
-    creation_time = mt;
+    if (struct_v < 6) {
+      creation_time = ceph::real_clock::from_time_t(mt);
+    }
     if (struct_v >= 2)
       ::decode(count, bl);
     if (struct_v >= 3)
@@ -1232,6 +1375,8 @@ struct RGWBucketEnt {
     if (struct_v >= 4)
       ::decode(s, bl);
     size_rounded = s;
+    if (struct_v >= 6)
+      ::decode(creation_time, bl);
     DECODE_FINISH(bl);
   }
   void dump(Formatter *f) const;
@@ -1687,9 +1832,9 @@ extern void parse_csv_string(const string& ival, vector<string>& ovals);
 extern int parse_key_value(string& in_str, string& key, string& val);
 extern int parse_key_value(string& in_str, const char *delim, string& key, string& val);
 /** time parsing */
-extern int parse_time(const char *time_str, time_t *time);
+extern int parse_time(const char *time_str, real_time *time);
 extern bool parse_rfc2616(const char *s, struct tm *t);
-extern bool parse_iso8601(const char *s, struct tm *t);
+extern bool parse_iso8601(const char *s, struct tm *t, uint32_t *pns = NULL, bool extended_format = true);
 extern string rgw_trim_whitespace(const string& src);
 extern string rgw_trim_quotes(const string& val);
 
@@ -1707,12 +1852,22 @@ extern bool verify_object_permission(struct req_state *s,
 extern bool verify_object_permission(struct req_state *s, int perm);
 /** Convert an input URL into a sane object name
  * by converting %-escaped strings into characters, etc*/
+extern void rgw_uri_escape_char(char c, string& dst);
 extern bool url_decode(const string& src_str, string& dest_str, bool in_query = false);
 extern void url_encode(const string& src, string& dst);
 
+/* destination should be CEPH_CRYPTO_HMACSHA1_DIGESTSIZE bytes long */
 extern void calc_hmac_sha1(const char *key, int key_len,
                           const char *msg, int msg_len, char *dest);
-/* destination should be CEPH_CRYPTO_HMACSHA1_DIGESTSIZE bytes long */
+/* destination should be CEPH_CRYPTO_HMACSHA256_DIGESTSIZE bytes long */
+extern void calc_hmac_sha256(const char *key, int key_len, const char *msg, int msg_len, char *dest);
+extern void calc_hash_sha256(const char *msg, int len, string& dest);
+extern void calc_hash_sha256(const string& msg, string& dest);
+
+using ceph::crypto::SHA256;
+extern SHA256* calc_hash_sha256_open_stream();
+extern void    calc_hash_sha256_update_stream(SHA256 *hash, const char *msg, int len);
+extern string  calc_hash_sha256_close_stream(SHA256 **hash);
 
 extern int rgw_parse_op_type_list(const string& str, uint32_t *perm);
 
diff --git a/src/rgw/rgw_coroutine.cc b/src/rgw/rgw_coroutine.cc
new file mode 100644
index 0000000..ef28ae2
--- /dev/null
+++ b/src/rgw/rgw_coroutine.cc
@@ -0,0 +1,856 @@
+
+
+#include "common/ceph_json.h"
+
+#include "rgw_coroutine.h"
+#include "rgw_boost_asio_yield.h"
+
+
+#define dout_subsys ceph_subsys_rgw
+
+
+RGWCompletionManager::RGWCompletionManager(CephContext *_cct) : cct(_cct), lock("RGWCompletionManager::lock"),
+                                            timer(cct, lock)
+{
+  timer.init();
+}
+
+RGWCompletionManager::~RGWCompletionManager()
+{
+  Mutex::Locker l(lock);
+  timer.cancel_all_events();
+  timer.shutdown();
+}
+
+void RGWCompletionManager::complete(RGWAioCompletionNotifier *cn, void *user_info)
+{
+  Mutex::Locker l(lock);
+  _complete(cn, user_info);
+}
+
+void RGWCompletionManager::register_completion_notifier(RGWAioCompletionNotifier *cn)
+{
+  Mutex::Locker l(lock);
+  if (cn) {
+    cns.insert(cn);
+    cn->get();
+  }
+}
+
+void RGWCompletionManager::unregister_completion_notifier(RGWAioCompletionNotifier *cn)
+{
+  Mutex::Locker l(lock);
+  if (cn) {
+    cns.erase(cn);
+    cn->put();
+  }
+}
+
+void RGWCompletionManager::_complete(RGWAioCompletionNotifier *cn, void *user_info)
+{
+  if (cn) {
+    cns.erase(cn);
+    cn->put();
+  }
+  complete_reqs.push_back(user_info);
+  cond.Signal();
+}
+
+int RGWCompletionManager::get_next(void **user_info)
+{
+  Mutex::Locker l(lock);
+  while (complete_reqs.empty()) {
+    cond.Wait(lock);
+    if (going_down.read() != 0) {
+      return -ECANCELED;
+    }
+  }
+  *user_info = complete_reqs.front();
+  complete_reqs.pop_front();
+  return 0;
+}
+
+bool RGWCompletionManager::try_get_next(void **user_info)
+{
+  Mutex::Locker l(lock);
+  if (complete_reqs.empty()) {
+    return false;
+  }
+  *user_info = complete_reqs.front();
+  complete_reqs.pop_front();
+  return true;
+}
+
+void RGWCompletionManager::go_down()
+{
+  Mutex::Locker l(lock);
+  for (auto cn : cns) {
+    cn->unregister();
+  }
+  going_down.set(1);
+  cond.Signal();
+}
+
+void RGWCompletionManager::wait_interval(void *opaque, const utime_t& interval, void *user_info)
+{
+  Mutex::Locker l(lock);
+  assert(waiters.find(opaque) == waiters.end());
+  waiters[opaque] = user_info;
+  timer.add_event_after(interval, new WaitContext(this, opaque));
+}
+
+void RGWCompletionManager::wakeup(void *opaque)
+{
+  Mutex::Locker l(lock);
+  _wakeup(opaque);
+}
+
+void RGWCompletionManager::_wakeup(void *opaque)
+{
+  map<void *, void *>::iterator iter = waiters.find(opaque);
+  if (iter != waiters.end()) {
+    void *user_id = iter->second;
+    waiters.erase(iter);
+    _complete(NULL, user_id);
+  }
+}
+
+RGWCoroutine::~RGWCoroutine() {
+  for (auto stack : spawned.entries) {
+    stack->put();
+  }
+}
+
+void RGWCoroutine::set_io_blocked(bool flag) {
+  stack->set_io_blocked(flag);
+}
+
+void RGWCoroutine::set_sleeping(bool flag) {
+  stack->set_sleeping(flag);
+}
+
+int RGWCoroutine::io_block(int ret) {
+  set_io_blocked(true);
+  return ret;
+}
+
+void RGWCoroutine::StatusItem::dump(Formatter *f) const {
+  ::encode_json("timestamp", timestamp, f);
+  ::encode_json("status", status, f);
+}
+
+stringstream& RGWCoroutine::Status::set_status()
+{
+  RWLock::WLocker l(lock);
+  string s = status.str();
+  status.str(string());
+  if (!timestamp.is_zero()) {
+    history.push_back(StatusItem(timestamp, s));
+  }
+  if (history.size() > (size_t)max_history) {
+    history.pop_front();
+  }
+  timestamp = ceph_clock_now(cct);
+
+  return status;
+}
+
+RGWCoroutinesStack::RGWCoroutinesStack(CephContext *_cct, RGWCoroutinesManager *_ops_mgr, RGWCoroutine *start) : cct(_cct), ops_mgr(_ops_mgr),
+                                                                                                         done_flag(false), error_flag(false), blocked_flag(false),
+                                                                                                         sleep_flag(false), interval_wait_flag(false), is_scheduled(false), is_waiting_for_child(false),
+													 retcode(0), run_count(0),
+													 env(NULL), parent(NULL)
+{
+  if (start) {
+    ops.push_back(start);
+  }
+  pos = ops.begin();
+}
+
+RGWCoroutinesStack::~RGWCoroutinesStack()
+{
+  for (auto op : ops) {
+    op->put();
+  }
+
+  for (auto stack : spawned.entries) {
+    stack->put();
+  }
+}
+
+int RGWCoroutinesStack::operate(RGWCoroutinesEnv *_env)
+{
+  env = _env;
+  RGWCoroutine *op = *pos;
+  op->stack = this;
+  ldout(cct, 20) << *op << ": operate()" << dendl;
+  int r = op->operate();
+  if (r < 0) {
+    ldout(cct, 20) << *op << ": operate() returned r=" << r << dendl;
+  }
+
+  error_flag = op->is_error();
+
+  if (op->is_done()) {
+    int op_retcode = r;
+    r = unwind(op_retcode);
+    op->put();
+    done_flag = (pos == ops.end());
+    if (done_flag) {
+      retcode = op_retcode;
+    }
+    return r;
+  }
+
+  /* should r ever be negative at this point? */
+  assert(r >= 0);
+
+  return 0;
+}
+
+string RGWCoroutinesStack::error_str()
+{
+  if (pos != ops.end()) {
+    return (*pos)->error_str();
+  }
+  return string();
+}
+
+void RGWCoroutinesStack::call(RGWCoroutine *next_op) {
+  if (!next_op) {
+    return;
+  }
+  ops.push_back(next_op);
+  if (pos != ops.end()) {
+    ++pos;
+  } else {
+    pos = ops.begin();
+  }
+}
+
+RGWCoroutinesStack *RGWCoroutinesStack::spawn(RGWCoroutine *source_op, RGWCoroutine *op, bool wait)
+{
+  if (!op) {
+    return NULL;
+  }
+
+  rgw_spawned_stacks *s = (source_op ? &source_op->spawned : &spawned);
+
+  RGWCoroutinesStack *stack = env->manager->allocate_stack();
+  s->add_pending(stack);
+  stack->parent = this;
+
+  stack->get(); /* we'll need to collect the stack */
+  stack->call(op);
+
+  env->manager->schedule(env, stack);
+
+  if (wait) {
+    set_blocked_by(stack);
+  }
+
+  return stack;
+}
+
+RGWCoroutinesStack *RGWCoroutinesStack::spawn(RGWCoroutine *op, bool wait)
+{
+  return spawn(NULL, op, wait);
+}
+
+int RGWCoroutinesStack::wait(const utime_t& interval)
+{
+  RGWCompletionManager *completion_mgr = env->manager->get_completion_mgr();
+  completion_mgr->wait_interval((void *)this, interval, (void *)this);
+  set_io_blocked(true);
+  set_interval_wait(true);
+  return 0;
+}
+
+void RGWCoroutinesStack::wakeup()
+{
+  RGWCompletionManager *completion_mgr = env->manager->get_completion_mgr();
+  completion_mgr->wakeup((void *)this);
+}
+
+int RGWCoroutinesStack::unwind(int retcode)
+{
+  rgw_spawned_stacks *src_spawned = &(*pos)->spawned;
+
+  if (pos == ops.begin()) {
+    spawned.inherit(src_spawned);
+    ops.clear();
+    pos = ops.end();
+    return retcode;
+  }
+
+  --pos;
+  ops.pop_back();
+  RGWCoroutine *op = *pos;
+  op->set_retcode(retcode);
+  op->spawned.inherit(src_spawned);
+  return 0;
+}
+
+
+bool RGWCoroutinesStack::collect(RGWCoroutine *op, int *ret) /* returns true if needs to be called again */
+{
+  rgw_spawned_stacks *s = (op ? &op->spawned : &spawned);
+  *ret = 0;
+  vector<RGWCoroutinesStack *> new_list;
+
+  for (vector<RGWCoroutinesStack *>::iterator iter = s->entries.begin(); iter != s->entries.end(); ++iter) {
+    RGWCoroutinesStack *stack = *iter;
+    if (!stack->is_done()) {
+      new_list.push_back(stack);
+      ldout(cct, 20) << "collect(): s=" << (void *)this << " stack=" << (void *)stack << " is still running" << dendl;
+      continue;
+    }
+    int r = stack->get_ret_status();
+    if (r < 0) {
+      *ret = r;
+    }
+
+    ldout(cct, 20) << "collect(): s=" << (void *)this << " stack=" << (void *)stack << " is complete" << dendl;
+    stack->put();
+  }
+
+  s->entries.swap(new_list);
+  return false;
+}
+
+bool RGWCoroutinesStack::collect_next(RGWCoroutine *op, int *ret, RGWCoroutinesStack **collected_stack) /* returns true if found a stack to collect */
+{
+  rgw_spawned_stacks *s = (op ? &op->spawned : &spawned);
+  *ret = 0;
+
+  if (collected_stack) {
+    *collected_stack = NULL;
+  }
+
+  for (vector<RGWCoroutinesStack *>::iterator iter = s->entries.begin(); iter != s->entries.end(); ++iter) {
+    RGWCoroutinesStack *stack = *iter;
+    if (!stack->is_done()) {
+      continue;
+    }
+    int r = stack->get_ret_status();
+    if (r < 0) {
+      *ret = r;
+    }
+
+    if (collected_stack) {
+      *collected_stack = stack;
+    }
+    stack->put();
+
+    s->entries.erase(iter);
+    return true;
+  }
+
+  return false;
+}
+
+bool RGWCoroutinesStack::collect(int *ret) /* returns true if needs to be called again */
+{
+  return collect(NULL, ret);
+}
+
+static void _aio_completion_notifier_cb(librados::completion_t cb, void *arg);
+
+static void _aio_completion_notifier_cb(librados::completion_t cb, void *arg)
+{
+  ((RGWAioCompletionNotifier *)arg)->cb();
+}
+
+RGWAioCompletionNotifier::RGWAioCompletionNotifier(RGWCompletionManager *_mgr, void *_user_data) : completion_mgr(_mgr),
+                                                                         user_data(_user_data), lock("RGWAioCompletionNotifier"), registered(true) {
+  c = librados::Rados::aio_create_completion((void *)this, _aio_completion_notifier_cb, NULL);
+}
+
+RGWAioCompletionNotifier *RGWCoroutinesStack::create_completion_notifier()
+{
+  return ops_mgr->create_completion_notifier(this);
+}
+
+RGWCompletionManager *RGWCoroutinesStack::get_completion_mgr()
+{
+  return ops_mgr->get_completion_mgr();
+}
+
+bool RGWCoroutinesStack::unblock_stack(RGWCoroutinesStack **s)
+{
+  if (blocking_stacks.empty()) {
+    return false;
+  }
+
+  set<RGWCoroutinesStack *>::iterator iter = blocking_stacks.begin();
+  *s = *iter;
+  blocking_stacks.erase(iter);
+  (*s)->blocked_by_stack.erase(this);
+
+  return true;
+}
+
+void RGWCoroutinesManager::report_error(RGWCoroutinesStack *op)
+{
+  if (!op) {
+    return;
+  }
+  string err = op->error_str();
+  if (err.empty()) {
+    return;
+  }
+  lderr(cct) << "ERROR: failed operation: " << op->error_str() << dendl;
+}
+
+void RGWCoroutinesStack::dump(Formatter *f) const {
+  stringstream ss;
+  ss << (void *)this;
+  ::encode_json("stack", ss.str(), f);
+  ::encode_json("run_count", run_count, f);
+  f->open_array_section("ops");
+  for (auto& i : ops) {
+    encode_json("op", *i, f);
+  }
+  f->close_section();
+}
+
+void RGWCoroutinesManager::handle_unblocked_stack(set<RGWCoroutinesStack *>& context_stacks, list<RGWCoroutinesStack *>& scheduled_stacks, RGWCoroutinesStack *stack, int *blocked_count)
+{
+  RWLock::WLocker wl(lock);
+  --(*blocked_count);
+  stack->set_io_blocked(false);
+  stack->set_interval_wait(false);
+  if (!stack->is_done()) {
+    scheduled_stacks.push_back(stack);
+  } else {
+    RWLock::WLocker wl(lock);
+    context_stacks.erase(stack);
+    stack->put();
+  }
+}
+
+void RGWCoroutinesManager::schedule(RGWCoroutinesEnv *env, RGWCoroutinesStack *stack)
+{
+  assert(lock.is_wlocked());
+  env->scheduled_stacks->push_back(stack);
+  set<RGWCoroutinesStack *>& context_stacks = run_contexts[env->run_context];
+  context_stacks.insert(stack);
+}
+
+int RGWCoroutinesManager::run(list<RGWCoroutinesStack *>& stacks)
+{
+  int ret = 0;
+  int blocked_count = 0;
+  int interval_wait_count = 0;
+  RGWCoroutinesEnv env;
+
+  uint64_t run_context = run_context_count.inc();
+
+  lock.get_write();
+  set<RGWCoroutinesStack *>& context_stacks = run_contexts[run_context];
+  list<RGWCoroutinesStack *> scheduled_stacks;
+  for (auto& st : stacks) {
+    context_stacks.insert(st);
+    scheduled_stacks.push_back(st);
+  }
+  lock.unlock();
+
+  env.run_context = run_context;
+  env.manager = this;
+  env.scheduled_stacks = &scheduled_stacks;
+
+  for (list<RGWCoroutinesStack *>::iterator iter = scheduled_stacks.begin(); iter != scheduled_stacks.end() && !going_down.read();) {
+    lock.get_write();
+
+    RGWCoroutinesStack *stack = *iter;
+    env.stack = stack;
+
+    ret = stack->operate(&env);
+    stack->set_is_scheduled(false);
+    if (ret < 0) {
+      ldout(cct, 20) << "stack->operate() returned ret=" << ret << dendl;
+    }
+
+    if (stack->is_error()) {
+      report_error(stack);
+    }
+
+    bool op_not_blocked = false;
+
+    if (stack->is_io_blocked()) {
+      ldout(cct, 20) << __func__ << ":" << " stack=" << (void *)stack << " is io blocked" << dendl;
+      if (stack->is_interval_waiting()) {
+        interval_wait_count++;
+      }
+      blocked_count++;
+    } else if (stack->is_blocked()) {
+      /* do nothing, we'll re-add the stack when the blocking stack is done,
+       * or when we're awaken
+       */
+      ldout(cct, 20) << __func__ << ":" << " stack=" << (void *)stack << " is_blocked_by_stack()=" << stack->is_blocked_by_stack()
+	             << " is_sleeping=" << stack->is_sleeping() << " waiting_for_child()=" << stack->waiting_for_child() << dendl;
+    } else if (stack->is_done()) {
+      ldout(cct, 20) << __func__ << ":" << " stack=" << (void *)stack << " is done" << dendl;
+      RGWCoroutinesStack *s;
+      while (stack->unblock_stack(&s)) {
+	if (!s->is_blocked_by_stack() && !s->is_done()) {
+	  if (s->is_io_blocked()) {
+            if (stack->is_interval_waiting()) {
+              interval_wait_count++;
+            }
+	    blocked_count++;
+	  } else {
+	    s->schedule();
+	  }
+	}
+      }
+      if (stack->parent && stack->parent->waiting_for_child()) {
+        stack->parent->set_wait_for_child(false);
+        stack->parent->schedule();
+      }
+      context_stacks.erase(stack);
+      stack->put();
+      stack = NULL;
+    } else {
+      op_not_blocked = true;
+      stack->run_count++;
+      stack->schedule();
+    }
+
+    if (!op_not_blocked && stack) {
+      stack->run_count = 0;
+    }
+
+    lock.unlock();
+
+    RGWCoroutinesStack *blocked_stack;
+    while (completion_mgr->try_get_next((void **)&blocked_stack)) {
+      handle_unblocked_stack(context_stacks, scheduled_stacks, blocked_stack, &blocked_count);
+    }
+
+    /*
+     * only account blocked operations that are not in interval_wait, these are stacks that
+     * were put on a wait without any real IO operations. While we mark these as io_blocked,
+     * these aren't really waiting for IOs
+     */
+    while (blocked_count - interval_wait_count >= ops_window) {
+      ret = completion_mgr->get_next((void **)&blocked_stack);
+      if (ret < 0) {
+       ldout(cct, 0) << "ERROR: failed to clone shard, completion_mgr.get_next() returned ret=" << ret << dendl;
+      }
+      handle_unblocked_stack(context_stacks, scheduled_stacks, blocked_stack, &blocked_count);
+    }
+
+    ++iter;
+    scheduled_stacks.pop_front();
+
+
+    while (scheduled_stacks.empty() && blocked_count > 0) {
+      ret = completion_mgr->get_next((void **)&blocked_stack);
+      if (ret < 0) {
+	ldout(cct, 0) << "ERROR: failed to clone shard, completion_mgr.get_next() returned ret=" << ret << dendl;
+      }
+      if (going_down.read() > 0) {
+	ldout(cct, 5) << __func__ << "(): was stopped, exiting" << dendl;
+	ret = -ECANCELED;
+        break;
+      }
+      handle_unblocked_stack(context_stacks, scheduled_stacks, blocked_stack, &blocked_count);
+      iter = scheduled_stacks.begin();
+    }
+    if (ret == -ECANCELED) {
+      break;
+    }
+
+    if (iter == scheduled_stacks.end()) {
+      iter = scheduled_stacks.begin();
+    }
+
+    ret = 0;
+  }
+
+  lock.get_write();
+  for (auto stack : context_stacks) {
+    ldout(cct, 20) << "clearing stack on run() exit: stack=" << (void *)stack << " nref=" << stack->get_nref() << dendl;
+    stack->put();
+  }
+  run_contexts.erase(run_context);
+  lock.unlock();
+
+  return ret;
+}
+
+int RGWCoroutinesManager::run(RGWCoroutine *op)
+{
+  if (!op) {
+    return 0;
+  }
+  list<RGWCoroutinesStack *> stacks;
+  RGWCoroutinesStack *stack = allocate_stack();
+  op->get();
+  stack->call(op);
+
+  stack->schedule(&stacks);
+
+  int r = run(stacks);
+  if (r < 0) {
+    ldout(cct, 20) << "run(stacks) returned r=" << r << dendl;
+  } else {
+    r = op->get_ret_status();
+  }
+  op->put();
+
+  return r;
+}
+
+RGWAioCompletionNotifier *RGWCoroutinesManager::create_completion_notifier(RGWCoroutinesStack *stack)
+{
+  RGWAioCompletionNotifier *cn = new RGWAioCompletionNotifier(completion_mgr, (void *)stack);
+  completion_mgr->register_completion_notifier(cn);
+  return cn;
+}
+
+void RGWCoroutinesManager::dump(Formatter *f) const {
+  RWLock::RLocker rl(lock);
+
+  f->open_array_section("run_contexts");
+  for (auto& i : run_contexts) {
+    f->open_object_section("context");
+    ::encode_json("id", i.first, f);
+    f->open_array_section("entries");
+    for (auto& s : i.second) {
+      ::encode_json("entry", *s, f);
+    }
+    f->close_section();
+    f->close_section();
+  }
+  f->close_section();
+}
+
+RGWCoroutinesStack *RGWCoroutinesManager::allocate_stack() {
+  return new RGWCoroutinesStack(cct, this);
+}
+
+string RGWCoroutinesManager::get_id()
+{
+  if (!id.empty()) {
+    return id;
+  }
+  stringstream ss;
+  ss << (void *)this;
+  return ss.str();
+}
+
+void RGWCoroutinesManagerRegistry::add(RGWCoroutinesManager *mgr)
+{
+  RWLock::WLocker wl(lock);
+  if (managers.find(mgr) == managers.end()) {
+    managers.insert(mgr);
+    get();
+  }
+}
+
+void RGWCoroutinesManagerRegistry::remove(RGWCoroutinesManager *mgr)
+{
+  RWLock::WLocker wl(lock);
+  if (managers.find(mgr) != managers.end()) {
+    managers.erase(mgr);
+    put();
+  }
+}
+
+RGWCoroutinesManagerRegistry::~RGWCoroutinesManagerRegistry()
+{
+  AdminSocket *admin_socket = cct->get_admin_socket();
+  if (!admin_command.empty()) {
+    admin_socket->unregister_command(admin_command);
+  }
+}
+
+int RGWCoroutinesManagerRegistry::hook_to_admin_command(const string& command)
+{
+  AdminSocket *admin_socket = cct->get_admin_socket();
+  if (!admin_command.empty()) {
+    admin_socket->unregister_command(admin_command);
+  }
+  admin_command = command;
+  int r = admin_socket->register_command(admin_command, admin_command, this,
+				     "dump current coroutines stack state");
+  if (r < 0) {
+    lderr(cct) << "ERROR: fail to register admin socket command (r=" << r << ")" << dendl;
+    return r;
+  }
+  return 0;
+}
+
+bool RGWCoroutinesManagerRegistry::call(std::string command, cmdmap_t& cmdmap, std::string format,
+	    bufferlist& out) {
+  RWLock::RLocker rl(lock);
+  stringstream ss;
+  JSONFormatter f;
+  ::encode_json("cr_managers", *this, &f);
+  f.flush(ss);
+  out.append(ss);
+  return true;
+}
+
+void RGWCoroutinesManagerRegistry::dump(Formatter *f) const {
+  f->open_array_section("coroutine_managers");
+  for (auto m : managers) {
+    ::encode_json("entry", *m, f);
+  }
+  f->close_section();
+}
+
+void RGWCoroutine::call(RGWCoroutine *op)
+{
+  stack->call(op);
+}
+
+RGWCoroutinesStack *RGWCoroutine::spawn(RGWCoroutine *op, bool wait)
+{
+  return stack->spawn(this, op, wait);
+}
+
+bool RGWCoroutine::collect(int *ret) /* returns true if needs to be called again */
+{
+  return stack->collect(this, ret);
+}
+
+bool RGWCoroutine::collect_next(int *ret, RGWCoroutinesStack **collected_stack) /* returns true if found a stack to collect */
+{
+  return stack->collect_next(this, ret, collected_stack);
+}
+
+int RGWCoroutine::wait(const utime_t& interval)
+{
+  return stack->wait(interval);
+}
+
+void RGWCoroutine::wait_for_child()
+{
+  /* should only wait for child if there is a child that is not done yet, and no complete children */
+  if (spawned.entries.empty()) {
+    return;
+  }
+  for (vector<RGWCoroutinesStack *>::iterator iter = spawned.entries.begin(); iter != spawned.entries.end(); ++iter) {
+    if ((*iter)->is_done()) {
+      return;
+    }
+  }
+  stack->set_wait_for_child(true);
+}
+
+string RGWCoroutine::to_str() const
+{
+  return typeid(*this).name();
+}
+
+ostream& operator<<(ostream& out, const RGWCoroutine& cr)
+{
+  out << "cr:s=" << (void *)cr.get_stack() << ":op=" << (void *)&cr << ":" << typeid(cr).name();
+  return out;
+}
+
+bool RGWCoroutine::drain_children(int num_cr_left)
+{
+  bool done = false;
+  reenter(&drain_cr) {
+    while (num_spawned() > (size_t)num_cr_left) {
+      yield wait_for_child();
+      int ret;
+      while (collect(&ret)) {
+        if (ret < 0) {
+          ldout(cct, 10) << "collect() returned ret=" << ret << dendl;
+          /* we should have reported this error */
+          log_error() << "ERROR: collect() returned error (ret=" << ret << ")";
+        }
+      }
+    }
+    done = true;
+  }
+  return done;
+}
+
+void RGWCoroutine::wakeup()
+{
+  stack->wakeup();
+}
+
+void RGWCoroutine::dump(Formatter *f) const {
+  if (!description.str().empty()) {
+    encode_json("description", description.str(), f);
+  }
+  encode_json("type", to_str(), f);
+  if (!spawned.entries.empty()) {
+    f->open_array_section("spawned");
+    for (auto& i : spawned.entries) {
+      char buf[32];
+      snprintf(buf, sizeof(buf), "%p", (void *)i);
+      encode_json("stack", string(buf), f);
+    }
+    f->close_section();
+  }
+  if (!status.history.empty()) {
+    encode_json("history", status.history, f);
+  }
+
+  if (!status.status.str().empty()) {
+    f->open_object_section("status");
+    encode_json("status", status.status.str(), f);
+    encode_json("timestamp", status.timestamp, f);
+    f->close_section();
+  }
+}
+
+int RGWSimpleCoroutine::operate()
+{
+  int ret = 0;
+  reenter(this) {
+    yield return state_init();
+    yield return state_send_request();
+    yield return state_request_complete();
+    yield return state_all_complete();
+    drain_all();
+    return set_state(RGWCoroutine_Done, ret);
+  }
+  return 0;
+}
+
+int RGWSimpleCoroutine::state_init()
+{
+  int ret = init();
+  if (ret < 0) {
+    return set_state(RGWCoroutine_Error, ret);
+  }
+  return 0;
+}
+
+int RGWSimpleCoroutine::state_send_request()
+{
+  int ret = send_request();
+  if (ret < 0) {
+    return set_state(RGWCoroutine_Error, ret);
+  }
+  return io_block(0);
+}
+
+int RGWSimpleCoroutine::state_request_complete()
+{
+  int ret = request_complete();
+  if (ret < 0) {
+    return set_state(RGWCoroutine_Error, ret);
+  }
+  return 0;
+}
+
+int RGWSimpleCoroutine::state_all_complete()
+{
+  int ret = finish();
+  if (ret < 0) {
+    return set_state(RGWCoroutine_Error, ret);
+  }
+  return 0;
+}
+
+
diff --git a/src/rgw/rgw_coroutine.h b/src/rgw/rgw_coroutine.h
new file mode 100644
index 0000000..0912857
--- /dev/null
+++ b/src/rgw/rgw_coroutine.h
@@ -0,0 +1,582 @@
+#ifndef CEPH_RGW_COROUTINE_H
+#define CEPH_RGW_COROUTINE_H
+
+#ifdef _ASSERT_H
+#define NEED_ASSERT_H
+#pragma push_macro("_ASSERT_H")
+#endif
+
+#include <boost/asio.hpp>
+
+#ifdef NEED_ASSERT_H
+#pragma pop_macro("_ASSERT_H")
+#endif
+
+#include "include/utime.h"
+#include "common/RefCountedObj.h"
+#include "common/debug.h"
+#include "common/Timer.h"
+#include "common/admin_socket.h"
+
+#include "rgw_common.h"
+#include "rgw_boost_asio_coroutine.h"
+
+#define RGW_ASYNC_OPS_MGR_WINDOW 100
+
+class RGWCoroutinesStack;
+class RGWCoroutinesManager;
+class RGWAioCompletionNotifier;
+
+class RGWCompletionManager : public RefCountedObject {
+  CephContext *cct;
+  list<void *> complete_reqs;
+  set<RGWAioCompletionNotifier *> cns;
+
+  Mutex lock;
+  Cond cond;
+
+  SafeTimer timer;
+
+  atomic_t going_down;
+
+  map<void *, void *> waiters;
+
+  class WaitContext : public Context {
+    RGWCompletionManager *manager;
+    void *opaque;
+  public:
+    WaitContext(RGWCompletionManager *_cm, void *_opaque) : manager(_cm), opaque(_opaque) {}
+    void finish(int r) {
+      manager->_wakeup(opaque);
+    }
+  };
+
+  friend class WaitContext;
+
+protected:
+  void _wakeup(void *opaque);
+  void _complete(RGWAioCompletionNotifier *cn, void *user_info);
+public:
+  RGWCompletionManager(CephContext *_cct);
+  ~RGWCompletionManager();
+
+  void complete(RGWAioCompletionNotifier *cn, void *user_info);
+  int get_next(void **user_info);
+  bool try_get_next(void **user_info);
+
+  void go_down();
+
+  /*
+   * wait for interval length to complete user_info
+   */
+  void wait_interval(void *opaque, const utime_t& interval, void *user_info);
+  void wakeup(void *opaque);
+
+  void register_completion_notifier(RGWAioCompletionNotifier *cn);
+  void unregister_completion_notifier(RGWAioCompletionNotifier *cn);
+};
+
+/* a single use librados aio completion notifier that hooks into the RGWCompletionManager */
+class RGWAioCompletionNotifier : public RefCountedObject {
+  librados::AioCompletion *c;
+  RGWCompletionManager *completion_mgr;
+  void *user_data;
+  Mutex lock;
+  bool registered;
+
+public:
+  RGWAioCompletionNotifier(RGWCompletionManager *_mgr, void *_user_data);
+  ~RGWAioCompletionNotifier() {
+    c->release();
+    lock.Lock();
+    bool need_unregister = registered;
+    if (registered) {
+      completion_mgr->get();
+    }
+    registered = false;
+    lock.Unlock();
+    if (need_unregister) {
+      completion_mgr->unregister_completion_notifier(this);
+      completion_mgr->put();
+    }
+  }
+
+  librados::AioCompletion *completion() {
+    return c;
+  }
+
+  void unregister() {
+    Mutex::Locker l(lock);
+    if (!registered) {
+      return;
+    }
+    registered = false;
+  }
+
+  void cb() {
+    lock.Lock();
+    if (!registered) {
+      lock.Unlock();
+      put();
+      return;
+    }
+    completion_mgr->get();
+    registered = false;
+    lock.Unlock();
+    completion_mgr->complete(this, user_data);
+    completion_mgr->put();
+    put();
+  }
+};
+
+struct RGWCoroutinesEnv {
+  uint64_t run_context;
+  RGWCoroutinesManager *manager;
+  list<RGWCoroutinesStack *> *scheduled_stacks;
+  RGWCoroutinesStack *stack;
+
+  RGWCoroutinesEnv() : run_context(0), manager(NULL), scheduled_stacks(NULL), stack(NULL) {}
+};
+
+enum RGWCoroutineState {
+  RGWCoroutine_Error = -2,
+  RGWCoroutine_Done  = -1,
+  RGWCoroutine_Run   =  0,
+};
+
+struct rgw_spawned_stacks {
+  vector<RGWCoroutinesStack *> entries;
+
+  rgw_spawned_stacks() {}
+
+  void add_pending(RGWCoroutinesStack *s) {
+    entries.push_back(s);
+  }
+
+  void inherit(rgw_spawned_stacks *source) {
+    for (vector<RGWCoroutinesStack *>::iterator iter = source->entries.begin();
+         iter != source->entries.end(); ++iter) {
+      add_pending(*iter);
+    }
+    source->entries.clear();
+  }
+};
+
+
+
+class RGWCoroutine : public RefCountedObject, public boost::asio::coroutine {
+  friend class RGWCoroutinesStack;
+
+  struct StatusItem {
+    utime_t timestamp;
+    string status;
+
+    StatusItem(utime_t& t, const string& s) : timestamp(t), status(s) {}
+
+    void dump(Formatter *f) const;
+  };
+
+#define MAX_COROUTINE_HISTORY 10
+
+  struct Status {
+    CephContext *cct;
+    RWLock lock;
+    int max_history;
+
+    utime_t timestamp;
+    stringstream status;
+
+    Status(CephContext *_cct) : cct(_cct), lock("RGWCoroutine::Status::lock"), max_history(MAX_COROUTINE_HISTORY) {}
+
+    deque<StatusItem> history;
+
+    stringstream& set_status();
+  } status;
+
+  stringstream description;
+
+protected:
+  bool _yield_ret;
+  boost::asio::coroutine drain_cr;
+
+  CephContext *cct;
+
+  RGWCoroutinesStack *stack;
+  int retcode;
+  int state;
+
+  rgw_spawned_stacks spawned;
+
+  stringstream error_stream;
+
+  int set_state(int s, int ret = 0) {
+    state = s;
+    return ret;
+  }
+  int set_cr_error(int ret) {
+    state = RGWCoroutine_Error;
+    return ret;
+  }
+  int set_cr_done() {
+    state = RGWCoroutine_Done;
+    return 0;
+  }
+  void set_io_blocked(bool flag);
+  int io_block(int ret = 0);
+
+  void reset_description() {
+    description.str(string());
+  }
+
+  stringstream& set_description() {
+    return description;
+  }
+  stringstream& set_status() {
+    return status.set_status();
+  }
+
+  stringstream& set_status(const string& s) {
+    stringstream& status = set_status();
+    status << s;
+    return status;
+  }
+
+public:
+  RGWCoroutine(CephContext *_cct) : status(_cct), _yield_ret(false), cct(_cct), stack(NULL), retcode(0), state(RGWCoroutine_Run) {}
+  virtual ~RGWCoroutine();
+
+  virtual int operate() = 0;
+
+  bool is_done() { return (state == RGWCoroutine_Done || state == RGWCoroutine_Error); }
+  bool is_error() { return (state == RGWCoroutine_Error); }
+
+  stringstream& log_error() { return error_stream; }
+  string error_str() {
+    return error_stream.str();
+  }
+
+  void set_retcode(int r) {
+    retcode = r;
+  }
+
+  int get_ret_status() {
+    return retcode;
+  }
+
+  void call(RGWCoroutine *op); /* call at the same stack we're in */
+  RGWCoroutinesStack *spawn(RGWCoroutine *op, bool wait); /* execute on a different stack */
+  bool collect(int *ret); /* returns true if needs to be called again */
+  bool collect_next(int *ret, RGWCoroutinesStack **collected_stack = NULL); /* returns true if found a stack to collect */
+
+  int wait(const utime_t& interval);
+  bool drain_children(int num_cr_left); /* returns true if needed to be called again */
+  void wakeup();
+  void set_sleeping(bool flag); /* put in sleep, or wakeup from sleep */
+
+  size_t num_spawned() {
+    return spawned.entries.size();
+  }
+
+  void wait_for_child();
+
+  virtual string to_str() const;
+
+  RGWCoroutinesStack *get_stack() const {
+    return stack;
+  }
+
+  void dump(Formatter *f) const;
+};
+
+ostream& operator<<(ostream& out, const RGWCoroutine& cr);
+
+#define yield_until_true(x)     \
+do {                            \
+  do {                          \
+    yield _yield_ret = x;       \
+  } while (!_yield_ret);        \
+  _yield_ret = false;           \
+} while (0)
+
+#define drain_all() \
+  drain_cr = boost::asio::coroutine(); \
+  yield_until_true(drain_children(0))
+
+#define drain_all_but(n) \
+  drain_cr = boost::asio::coroutine(); \
+  yield_until_true(drain_children(n))
+
+template <class T>
+class RGWConsumerCR : public RGWCoroutine {
+  list<T> product;
+
+public:
+  RGWConsumerCR(CephContext *_cct) : RGWCoroutine(_cct) {}
+
+  bool has_product() {
+    return !product.empty();
+  }
+
+  void wait_for_product() {
+    if (!has_product()) {
+      set_sleeping(true);
+    }
+  }
+
+  bool consume(T *p) {
+    if (product.empty()) {
+      return false;
+    }
+    *p = product.front();
+    product.pop_front();
+    return true;
+  }
+
+  void receive(const T& p, bool wakeup = true);
+  void receive(list<T>& l, bool wakeup = true);
+};
+
+class RGWCoroutinesStack : public RefCountedObject {
+  friend class RGWCoroutine;
+  friend class RGWCoroutinesManager;
+
+  CephContext *cct;
+
+  RGWCoroutinesManager *ops_mgr;
+
+  list<RGWCoroutine *> ops;
+  list<RGWCoroutine *>::iterator pos;
+
+  rgw_spawned_stacks spawned;
+
+  set<RGWCoroutinesStack *> blocked_by_stack;
+  set<RGWCoroutinesStack *> blocking_stacks;
+
+  bool done_flag;
+  bool error_flag;
+  bool blocked_flag;
+  bool sleep_flag;
+  bool interval_wait_flag;
+
+  bool is_scheduled;
+
+  bool is_waiting_for_child;
+
+  int retcode;
+
+  uint64_t run_count;
+
+protected:
+  RGWCoroutinesEnv *env;
+  RGWCoroutinesStack *parent;
+
+  RGWCoroutinesStack *spawn(RGWCoroutine *source_op, RGWCoroutine *next_op, bool wait);
+  bool collect(RGWCoroutine *op, int *ret); /* returns true if needs to be called again */
+  bool collect_next(RGWCoroutine *op, int *ret, RGWCoroutinesStack **collected_stack); /* returns true if found a stack to collect */
+public:
+  RGWCoroutinesStack(CephContext *_cct, RGWCoroutinesManager *_ops_mgr, RGWCoroutine *start = NULL);
+  ~RGWCoroutinesStack();
+
+  int operate(RGWCoroutinesEnv *env);
+
+  bool is_done() {
+    return done_flag;
+  }
+  bool is_error() {
+    return error_flag;
+  }
+  bool is_blocked_by_stack() {
+    return !blocked_by_stack.empty();
+  }
+  void set_io_blocked(bool flag) {
+    blocked_flag = flag;
+  }
+  bool is_io_blocked() {
+    return blocked_flag;
+  }
+  void set_interval_wait(bool flag) {
+    interval_wait_flag = flag;
+  }
+  bool is_interval_waiting() {
+    return interval_wait_flag;
+  }
+  void set_sleeping(bool flag) {
+    bool wakeup = sleep_flag & !flag;
+    sleep_flag = flag;
+    if (wakeup) {
+      schedule();
+    }
+  }
+  bool is_sleeping() {
+    return sleep_flag;
+  }
+  void set_is_scheduled(bool flag) {
+    is_scheduled = flag;
+  }
+
+  bool is_blocked() {
+    return is_blocked_by_stack() || is_sleeping() ||
+          is_io_blocked() || waiting_for_child() ;
+  }
+
+  void schedule(list<RGWCoroutinesStack *> *stacks = NULL) {
+    if (!stacks) {
+      stacks = env->scheduled_stacks;
+    }
+    if (!is_scheduled) {
+      stacks->push_back(this);
+      is_scheduled = true;
+    }
+  }
+
+  int get_ret_status() {
+    return retcode;
+  }
+
+  string error_str();
+
+  void call(RGWCoroutine *next_op);
+  RGWCoroutinesStack *spawn(RGWCoroutine *next_op, bool wait);
+  int unwind(int retcode);
+
+  int wait(const utime_t& interval);
+  void wakeup();
+
+  bool collect(int *ret); /* returns true if needs to be called again */
+
+  RGWAioCompletionNotifier *create_completion_notifier();
+  RGWCompletionManager *get_completion_mgr();
+
+  void set_blocked_by(RGWCoroutinesStack *s) {
+    blocked_by_stack.insert(s);
+    s->blocking_stacks.insert(this);
+  }
+
+  void set_wait_for_child(bool flag) {
+    is_waiting_for_child = flag;
+  }
+
+  bool waiting_for_child() {
+    return is_waiting_for_child;
+  }
+
+  bool unblock_stack(RGWCoroutinesStack **s);
+
+  RGWCoroutinesEnv *get_env() { return env; }
+
+  void dump(Formatter *f) const;
+};
+
+template <class T>
+void RGWConsumerCR<T>::receive(list<T>& l, bool wakeup)
+{
+  product.splice(product.end(), l);
+  if (wakeup) {
+    set_sleeping(false);
+  }
+}
+
+
+template <class T>
+void RGWConsumerCR<T>::receive(const T& p, bool wakeup)
+{
+  product.push_back(p);
+  if (wakeup) {
+    set_sleeping(false);
+  }
+}
+
+class RGWCoroutinesManagerRegistry : public RefCountedObject, public AdminSocketHook {
+  CephContext *cct;
+
+  set<RGWCoroutinesManager *> managers;
+  RWLock lock;
+
+  string admin_command;
+
+public:
+  RGWCoroutinesManagerRegistry(CephContext *_cct) : cct(_cct), lock("RGWCoroutinesRegistry::lock") {}
+  ~RGWCoroutinesManagerRegistry();
+
+  void add(RGWCoroutinesManager *mgr);
+  void remove(RGWCoroutinesManager *mgr);
+
+  int hook_to_admin_command(const string& command);
+  bool call(std::string command, cmdmap_t& cmdmap, std::string format,
+	    bufferlist& out);
+    
+  void dump(Formatter *f) const;
+};
+
+class RGWCoroutinesManager {
+  CephContext *cct;
+  atomic_t going_down;
+
+  atomic64_t run_context_count;
+  map<uint64_t, set<RGWCoroutinesStack *> > run_contexts;
+
+  RWLock lock;
+
+  void handle_unblocked_stack(set<RGWCoroutinesStack *>& context_stacks, list<RGWCoroutinesStack *>& scheduled_stacks, RGWCoroutinesStack *stack, int *waiting_count);
+protected:
+  RGWCompletionManager *completion_mgr;
+  RGWCoroutinesManagerRegistry *cr_registry;
+
+  int ops_window;
+
+  string id;
+
+  void put_completion_notifier(RGWAioCompletionNotifier *cn);
+public:
+  RGWCoroutinesManager(CephContext *_cct, RGWCoroutinesManagerRegistry *_cr_registry) : cct(_cct), lock("RGWCoroutinesManager::lock"),
+                                                                                        cr_registry(_cr_registry), ops_window(RGW_ASYNC_OPS_MGR_WINDOW) {
+    completion_mgr = new RGWCompletionManager(cct);
+    if (cr_registry) {
+      cr_registry->add(this);
+    }
+  }
+  virtual ~RGWCoroutinesManager() {
+    completion_mgr->put();
+    if (cr_registry) {
+      cr_registry->remove(this);
+    }
+  }
+
+  int run(list<RGWCoroutinesStack *>& ops);
+  int run(RGWCoroutine *op);
+  void stop() {
+    going_down.set(1);
+    completion_mgr->go_down();
+  }
+
+  virtual void report_error(RGWCoroutinesStack *op);
+
+  RGWAioCompletionNotifier *create_completion_notifier(RGWCoroutinesStack *stack);
+  RGWCompletionManager *get_completion_mgr() { return completion_mgr; }
+
+  void schedule(RGWCoroutinesEnv *env, RGWCoroutinesStack *stack);
+  RGWCoroutinesStack *allocate_stack();
+
+  virtual string get_id();
+  void dump(Formatter *f) const;
+};
+
+class RGWSimpleCoroutine : public RGWCoroutine {
+  int operate();
+
+  int state_init();
+  int state_send_request();
+  int state_request_complete();
+  int state_all_complete();
+
+public:
+  RGWSimpleCoroutine(CephContext *_cct) : RGWCoroutine(_cct) {}
+
+  virtual int init() { return 0; }
+  virtual int send_request() = 0;
+  virtual int request_complete() = 0;
+  virtual int finish() { return 0; }
+
+};
+
+#endif
diff --git a/src/rgw/rgw_cr_rados.cc b/src/rgw/rgw_cr_rados.cc
new file mode 100644
index 0000000..ee32052
--- /dev/null
+++ b/src/rgw/rgw_cr_rados.cc
@@ -0,0 +1,655 @@
+#include "rgw_rados.h"
+#include "rgw_coroutine.h"
+#include "rgw_boost_asio_yield.h"
+#include "rgw_cr_rados.h"
+
+#include "cls/lock/cls_lock_client.h"
+
+#define dout_subsys ceph_subsys_rgw
+
+bool RGWAsyncRadosProcessor::RGWWQ::_enqueue(RGWAsyncRadosRequest *req) {
+  if (processor->is_going_down()) {
+    return false;
+  }
+  req->get();
+  processor->m_req_queue.push_back(req);
+  dout(20) << "enqueued request req=" << hex << req << dec << dendl;
+  _dump_queue();
+  return true;
+}
+
+bool RGWAsyncRadosProcessor::RGWWQ::_empty() {
+  return processor->m_req_queue.empty();
+}
+
+RGWAsyncRadosRequest *RGWAsyncRadosProcessor::RGWWQ::_dequeue() {
+  if (processor->m_req_queue.empty())
+    return NULL;
+  RGWAsyncRadosRequest *req = processor->m_req_queue.front();
+  processor->m_req_queue.pop_front();
+  dout(20) << "dequeued request req=" << hex << req << dec << dendl;
+  _dump_queue();
+  return req;
+}
+
+void RGWAsyncRadosProcessor::RGWWQ::_process(RGWAsyncRadosRequest *req, ThreadPool::TPHandle& handle) {
+  processor->handle_request(req);
+  processor->req_throttle.put(1);
+}
+
+void RGWAsyncRadosProcessor::RGWWQ::_dump_queue() {
+  if (!g_conf->subsys.should_gather(ceph_subsys_rgw, 20)) {
+    return;
+  }
+  deque<RGWAsyncRadosRequest *>::iterator iter;
+  if (processor->m_req_queue.empty()) {
+    dout(20) << "RGWWQ: empty" << dendl;
+    return;
+  }
+  dout(20) << "RGWWQ:" << dendl;
+  for (iter = processor->m_req_queue.begin(); iter != processor->m_req_queue.end(); ++iter) {
+    dout(20) << "req: " << hex << *iter << dec << dendl;
+  }
+}
+
+RGWAsyncRadosProcessor::RGWAsyncRadosProcessor(RGWRados *_store, int num_threads)
+  : store(_store), m_tp(store->ctx(), "RGWAsyncRadosProcessor::m_tp", "rados_async", num_threads),
+    req_throttle(store->ctx(), "rgw_async_rados_ops", num_threads * 2),
+    req_wq(this, g_conf->rgw_op_thread_timeout,
+    g_conf->rgw_op_thread_suicide_timeout, &m_tp) {
+}
+
+void RGWAsyncRadosProcessor::start() {
+  m_tp.start();
+}
+
+void RGWAsyncRadosProcessor::stop() {
+  going_down.set(1);
+  m_tp.drain(&req_wq);
+  m_tp.stop();
+  for (auto iter = m_req_queue.begin(); iter != m_req_queue.end(); ++iter) {
+    (*iter)->put();
+  }
+}
+
+void RGWAsyncRadosProcessor::handle_request(RGWAsyncRadosRequest *req) {
+  req->send_request();
+  req->put();
+}
+
+void RGWAsyncRadosProcessor::queue(RGWAsyncRadosRequest *req) {
+  req_throttle.get(1);
+  req_wq.queue(req);
+}
+
+int RGWAsyncGetSystemObj::_send_request()
+{
+  return store->get_system_obj(*obj_ctx, read_state, objv_tracker, obj, *pbl, ofs, end, pattrs, NULL);
+}
+
+RGWAsyncGetSystemObj::RGWAsyncGetSystemObj(RGWCoroutine *caller, RGWAioCompletionNotifier *cn, RGWRados *_store, RGWObjectCtx *_obj_ctx,
+                       RGWObjVersionTracker *_objv_tracker, rgw_obj& _obj,
+                       bufferlist *_pbl, off_t _ofs, off_t _end) : RGWAsyncRadosRequest(caller, cn), store(_store), obj_ctx(_obj_ctx),
+                                                                   objv_tracker(_objv_tracker), obj(_obj), pbl(_pbl), pattrs(NULL),
+                                                                  ofs(_ofs), end(_end)
+{
+}
+
+int RGWSimpleRadosReadAttrsCR::send_request()
+{
+  rgw_obj obj = rgw_obj(pool, oid);
+  req = new RGWAsyncGetSystemObj(this, stack->create_completion_notifier(),
+			         store, &obj_ctx, NULL,
+				 obj,
+				 &bl, 0, -1);
+  if (pattrs) {
+    req->set_read_attrs(pattrs);
+  }
+  async_rados->queue(req);
+  return 0;
+}
+
+int RGWSimpleRadosReadAttrsCR::request_complete()
+{
+  return req->get_ret_status();
+}
+
+int RGWAsyncPutSystemObj::_send_request()
+{
+  return store->put_system_obj_data(NULL, obj, bl, -1, exclusive);
+}
+
+RGWAsyncPutSystemObj::RGWAsyncPutSystemObj(RGWCoroutine *caller, RGWAioCompletionNotifier *cn, RGWRados *_store,
+                     rgw_obj& _obj, bool _exclusive,
+                     bufferlist& _bl) : RGWAsyncRadosRequest(caller, cn), store(_store),
+                                                       obj(_obj), exclusive(_exclusive),
+                                                       bl(_bl)
+{
+}
+
+int RGWAsyncPutSystemObjAttrs::_send_request()
+{
+  return store->system_obj_set_attrs(NULL, obj, *attrs, NULL, objv_tracker);
+}
+
+RGWAsyncPutSystemObjAttrs::RGWAsyncPutSystemObjAttrs(RGWCoroutine *caller, RGWAioCompletionNotifier *cn, RGWRados *_store,
+                     RGWObjVersionTracker *_objv_tracker, rgw_obj& _obj,
+                     map<string, bufferlist> *_attrs) : RGWAsyncRadosRequest(caller, cn), store(_store),
+                                                       objv_tracker(_objv_tracker), obj(_obj),
+                                                       attrs(_attrs)
+{
+}
+
+
+RGWOmapAppend::RGWOmapAppend(RGWAsyncRadosProcessor *_async_rados, RGWRados *_store, rgw_bucket& _pool, const string& _oid)
+                      : RGWConsumerCR<string>(_store->ctx()), async_rados(_async_rados),
+                        store(_store), pool(_pool), oid(_oid), going_down(false), num_pending_entries(0), total_entries(0)
+{
+}
+
+int RGWAsyncLockSystemObj::_send_request()
+{
+  librados::IoCtx ioctx;
+  librados::Rados *rados = store->get_rados_handle();
+  int r = rados->ioctx_create(obj.bucket.name.c_str(), ioctx); /* system object only! */
+  if (r < 0) {
+    lderr(store->ctx()) << "ERROR: failed to open pool (" << obj.bucket.name << ") ret=" << r << dendl;
+    return r;
+  }
+
+  rados::cls::lock::Lock l(lock_name);
+  utime_t duration(duration_secs, 0);
+  l.set_duration(duration);
+  l.set_cookie(cookie);
+  l.set_renew(true);
+
+  return l.lock_exclusive(&ioctx, obj.get_object());
+}
+
+RGWAsyncLockSystemObj::RGWAsyncLockSystemObj(RGWCoroutine *caller, RGWAioCompletionNotifier *cn, RGWRados *_store,
+                      RGWObjVersionTracker *_objv_tracker, rgw_obj& _obj,
+                       const string& _name, const string& _cookie, uint32_t _duration_secs) : RGWAsyncRadosRequest(caller, cn), store(_store),
+                                                              obj(_obj),
+                                                              lock_name(_name),
+                                                              cookie(_cookie),
+                                                              duration_secs(_duration_secs)
+{
+}
+
+int RGWAsyncUnlockSystemObj::_send_request()
+{
+  librados::IoCtx ioctx;
+  librados::Rados *rados = store->get_rados_handle();
+  int r = rados->ioctx_create(obj.bucket.name.c_str(), ioctx); /* system object only! */
+  if (r < 0) {
+    lderr(store->ctx()) << "ERROR: failed to open pool (" << obj.bucket.name << ") ret=" << r << dendl;
+    return r;
+  }
+
+  rados::cls::lock::Lock l(lock_name);
+
+  l.set_cookie(cookie);
+
+  return l.unlock(&ioctx, obj.get_object());
+}
+
+RGWAsyncUnlockSystemObj::RGWAsyncUnlockSystemObj(RGWCoroutine *caller, RGWAioCompletionNotifier *cn, RGWRados *_store,
+                                                 RGWObjVersionTracker *_objv_tracker, rgw_obj& _obj,
+                                                 const string& _name, const string& _cookie) : RGWAsyncRadosRequest(caller, cn), store(_store),
+  obj(_obj),
+  lock_name(_name), cookie(_cookie)
+{
+}
+
+
+RGWRadosSetOmapKeysCR::RGWRadosSetOmapKeysCR(RGWRados *_store,
+                      rgw_bucket& _pool, const string& _oid,
+                      map<string, bufferlist>& _entries) : RGWSimpleCoroutine(_store->ctx()),
+                                                store(_store),
+                                                entries(_entries),
+                                                pool(_pool), oid(_oid), cn(NULL)
+{
+  stringstream& s = set_description();
+  s << "set omap keys dest=" << pool.name << "/" << oid << " keys=[" << s.str() << "]";
+  for (auto i = entries.begin(); i != entries.end(); ++i) {
+    if (i != entries.begin()) {
+      s << ", ";
+    }
+    s << i->first;
+  }
+  s << "]";
+}
+
+RGWRadosSetOmapKeysCR::~RGWRadosSetOmapKeysCR()
+{
+  if (cn) {
+    cn->put();
+  }
+}
+
+int RGWRadosSetOmapKeysCR::send_request()
+{
+  librados::IoCtx ioctx;
+  librados::Rados *rados = store->get_rados_handle();
+  int r = rados->ioctx_create(pool.name.c_str(), ioctx); /* system object only! */
+  if (r < 0) {
+    lderr(store->ctx()) << "ERROR: failed to open pool (" << pool.name << ") ret=" << r << dendl;
+    return r;
+  }
+
+  set_status() << "sending request";
+
+  librados::ObjectWriteOperation op;
+  op.omap_set(entries);
+
+  cn = stack->create_completion_notifier();
+  cn->get();
+  return ioctx.aio_operate(oid, cn->completion(), &op);
+}
+
+int RGWRadosSetOmapKeysCR::request_complete()
+{
+  int r = cn->completion()->get_return_value();
+
+  set_status() << "request complete; ret=" << r;
+
+  return r;
+}
+
+RGWRadosGetOmapKeysCR::RGWRadosGetOmapKeysCR(RGWRados *_store,
+                      const rgw_bucket& _pool, const string& _oid,
+                      const string& _marker,
+                      map<string, bufferlist> *_entries, int _max_entries) : RGWSimpleCoroutine(_store->ctx()),
+                                                store(_store),
+                                                marker(_marker),
+                                                entries(_entries), max_entries(_max_entries), rval(0),
+                                                pool(_pool), oid(_oid), cn(NULL)
+{
+  set_description() << "set omap keys dest=" << pool.name << "/" << oid << " marker=" << marker;
+}
+
+RGWRadosGetOmapKeysCR::~RGWRadosGetOmapKeysCR()
+{
+}
+
+int RGWRadosGetOmapKeysCR::send_request() {
+  librados::Rados *rados = store->get_rados_handle();
+  int r = rados->ioctx_create(pool.name.c_str(), ioctx); /* system object only! */
+  if (r < 0) {
+    lderr(store->ctx()) << "ERROR: failed to open pool (" << pool.name << ") ret=" << r << dendl;
+    return r;
+  }
+
+  set_status() << "send request";
+
+  librados::ObjectReadOperation op;
+  op.omap_get_vals(marker, max_entries, entries, &rval);
+
+  cn = stack->create_completion_notifier();
+  return ioctx.aio_operate(oid, cn->completion(), &op, NULL);
+}
+
+RGWSimpleRadosLockCR::RGWSimpleRadosLockCR(RGWAsyncRadosProcessor *_async_rados, RGWRados *_store,
+                      const rgw_bucket& _pool, const string& _oid, const string& _lock_name,
+                      const string& _cookie,
+                      uint32_t _duration) : RGWSimpleCoroutine(_store->ctx()),
+                                                async_rados(_async_rados),
+                                                store(_store),
+                                                lock_name(_lock_name),
+                                                cookie(_cookie),
+                                                duration(_duration),
+                                                pool(_pool), oid(_oid),
+                                                req(NULL)
+{
+  stringstream s;
+  s << "rados lock dest=" << pool << "/" << oid << " lock=" << lock_name << " cookie=" << cookie << " duration=" << duration;
+}
+
+RGWSimpleRadosLockCR::~RGWSimpleRadosLockCR()
+{
+  if (req) {
+    req->finish();
+  }
+}
+
+int RGWSimpleRadosLockCR::send_request()
+{
+  set_status() << "sending request";
+  rgw_obj obj = rgw_obj(pool, oid);
+  req = new RGWAsyncLockSystemObj(this, stack->create_completion_notifier(),
+                                 store, NULL, obj, lock_name, cookie, duration);
+  async_rados->queue(req);
+  return 0;
+}
+
+int RGWSimpleRadosLockCR::request_complete()
+{
+  set_status() << "request complete; ret=" << req->get_ret_status();
+  return req->get_ret_status();
+}
+
+RGWSimpleRadosUnlockCR::RGWSimpleRadosUnlockCR(RGWAsyncRadosProcessor *_async_rados, RGWRados *_store,
+                      const rgw_bucket& _pool, const string& _oid, const string& _lock_name,
+                      const string& _cookie) : RGWSimpleCoroutine(_store->ctx()),
+                                                async_rados(_async_rados),
+                                                store(_store),
+                                                lock_name(_lock_name),
+                                                cookie(_cookie),
+                                                pool(_pool), oid(_oid),
+                                                req(NULL)
+{
+  set_description() << "rados unlock dest=" << pool << "/" << oid << " lock=" << lock_name << " cookie=" << cookie;
+}
+
+RGWSimpleRadosUnlockCR::~RGWSimpleRadosUnlockCR()
+{
+  if (req) {
+    req->finish();
+  }
+}
+
+int RGWSimpleRadosUnlockCR::send_request()
+{
+  set_status() << "sending request";
+
+  rgw_obj obj = rgw_obj(pool, oid);
+  req = new RGWAsyncUnlockSystemObj(this, stack->create_completion_notifier(),
+                                 store, NULL, obj, lock_name, cookie);
+  async_rados->queue(req);
+  return 0;
+}
+
+int RGWSimpleRadosUnlockCR::request_complete()
+{
+  set_status() << "request complete; ret=" << req->get_ret_status();
+  return req->get_ret_status();
+}
+
+
+#define OMAP_APPEND_MAX_ENTRIES 100
+int RGWOmapAppend::operate() {
+  reenter(this) {
+    for (;;) {
+      if (!has_product() && going_down) {
+        set_status() << "going down";
+        break;
+      }
+      set_status() << "waiting for product";
+      yield wait_for_product();
+      yield {
+        string entry;
+        while (consume(&entry)) {
+          set_status() << "adding entry: " << entry;
+          entries[entry] = bufferlist();
+          if (entries.size() >= OMAP_APPEND_MAX_ENTRIES) {
+            break;
+          }
+        }
+        if (entries.size() >= OMAP_APPEND_MAX_ENTRIES || going_down) {
+          set_status() << "flushing to omap";
+          call(new RGWRadosSetOmapKeysCR(store, pool, oid, entries));
+          entries.clear();
+        }
+      }
+      if (get_ret_status() < 0) {
+        ldout(cct, 0) << "ERROR: failed to store entries in omap" << dendl;
+        return set_state(RGWCoroutine_Error);
+      }
+    }
+    /* done with coroutine */
+    return set_state(RGWCoroutine_Done);
+  }
+  return 0;
+}
+
+void RGWOmapAppend::flush_pending() {
+  receive(pending_entries);
+  num_pending_entries = 0;
+}
+
+bool RGWOmapAppend::append(const string& s) {
+  if (is_done()) {
+    return false;
+  }
+  ++total_entries;
+  pending_entries.push_back(s);
+  if (++num_pending_entries >= OMAP_APPEND_MAX_ENTRIES) {
+    flush_pending();
+  }
+  return true;
+}
+
+bool RGWOmapAppend::finish() {
+  going_down = true;
+  flush_pending();
+  set_sleeping(false);
+  return (!is_done());
+}
+
+int RGWAsyncGetBucketInstanceInfo::_send_request()
+{
+  string id = bucket_name + ":" + bucket_id;
+  RGWObjectCtx obj_ctx(store);
+
+  int r = store->get_bucket_instance_info(obj_ctx, id, *bucket_info, NULL, NULL);
+  if (r < 0) {
+    ldout(store->ctx(), 0) << "ERROR: failed to get bucket instance info for bucket id=" << id << dendl;
+    return r;
+  }
+
+  return 0;
+}
+
+int RGWAsyncFetchRemoteObj::_send_request()
+{
+  RGWObjectCtx obj_ctx(store);
+
+  string user_id;
+  char buf[16];
+  snprintf(buf, sizeof(buf), ".%lld", (long long)store->instance_id());
+  string client_id = store->zone_id() + buf;
+  string op_id = store->unique_id(store->get_new_req_id());
+  map<string, bufferlist> attrs;
+
+  rgw_obj src_obj(bucket_info.bucket, key.name);
+  src_obj.set_instance(key.instance);
+
+  rgw_obj dest_obj(src_obj);
+
+  int r = store->fetch_remote_obj(obj_ctx,
+                       user_id,
+                       client_id,
+                       op_id,
+                       NULL, /* req_info */
+                       source_zone,
+                       dest_obj,
+                       src_obj,
+                       bucket_info, /* dest */
+                       bucket_info, /* source */
+                       NULL, /* real_time* src_mtime, */
+                       NULL, /* real_time* mtime, */
+                       NULL, /* const real_time* mod_ptr, */
+                       NULL, /* const real_time* unmod_ptr, */
+                       false, /* high precision time */
+                       NULL, /* const char *if_match, */
+                       NULL, /* const char *if_nomatch, */
+                       RGWRados::ATTRSMOD_NONE,
+                       copy_if_newer,
+                       attrs,
+                       RGW_OBJ_CATEGORY_MAIN,
+                       versioned_epoch,
+                       real_time(), /* delete_at */
+                       &key.instance, /* string *version_id, */
+                       NULL, /* string *ptag, */
+                       NULL, /* string *petag, */
+                       NULL, /* struct rgw_err *err, */
+                       NULL, /* void (*progress_cb)(off_t, void *), */
+                       NULL); /* void *progress_data*); */
+
+  if (r < 0) {
+    ldout(store->ctx(), 0) << "store->fetch_remote_obj() returned r=" << r << dendl;
+  }
+  return r;
+}
+
+
+int RGWAsyncRemoveObj::_send_request()
+{
+  RGWObjectCtx obj_ctx(store);
+
+  rgw_obj obj(bucket_info.bucket, key.name);
+  obj.set_instance(key.instance);
+
+  ldout(store->ctx(), 0) << __func__ << "(): deleting obj=" << obj << dendl;
+
+  obj_ctx.set_atomic(obj);
+
+  RGWObjState *state;
+
+  int ret = store->get_obj_state(&obj_ctx, obj, &state);
+  if (ret < 0) {
+    ldout(store->ctx(), 20) << __func__ << "(): get_obj_state() obj=" << obj << " returned ret=" << ret << dendl;
+    return ret;
+  }
+
+  /* has there been any racing object write? */
+  if (del_if_older && (state->mtime > timestamp)) {
+    ldout(store->ctx(), 20) << __func__ << "(): skipping object removal obj=" << obj << " (obj mtime=" << state->mtime << ", request timestamp=" << timestamp << ")" << dendl;
+    return 0;
+  }
+
+  RGWAccessControlPolicy policy;
+
+  /* decode policy */
+  map<string, bufferlist>::iterator iter = state->attrset.find(RGW_ATTR_ACL);
+  if (iter != state->attrset.end()) {
+    bufferlist::iterator bliter = iter->second.begin();
+    try {
+      policy.decode(bliter);
+    } catch (buffer::error& err) {
+      ldout(store->ctx(), 0) << "ERROR: could not decode policy, caught buffer::error" << dendl;
+      return -EIO;
+    }
+  }
+
+  RGWRados::Object del_target(store, bucket_info, obj_ctx, obj);
+  RGWRados::Object::Delete del_op(&del_target);
+
+  del_op.params.bucket_owner = bucket_info.owner;
+  del_op.params.obj_owner = policy.get_owner();
+  if (del_if_older) {
+    del_op.params.unmod_since = timestamp;
+  }
+  if (versioned) {
+    del_op.params.versioning_status = BUCKET_VERSIONED;
+  }
+  del_op.params.olh_epoch = versioned_epoch;
+  del_op.params.marker_version_id = marker_version_id;
+  del_op.params.obj_owner.set_id(owner);
+  del_op.params.obj_owner.set_name(owner_display_name);
+  del_op.params.mtime = timestamp;
+  del_op.params.high_precision_time = true;
+
+  ret = del_op.delete_obj();
+  if (ret < 0) {
+    ldout(store->ctx(), 20) << __func__ << "(): delete_obj() obj=" << obj << " returned ret=" << ret << dendl;
+  }
+  return ret;
+}
+
+int RGWContinuousLeaseCR::operate()
+{
+  if (aborted) {
+    caller->set_sleeping(false);
+    return set_cr_done();
+  }
+  reenter(this) {
+    while (!going_down.read()) {
+      yield call(new RGWSimpleRadosLockCR(async_rados, store, pool, oid, lock_name, cookie, interval));
+
+      caller->set_sleeping(false); /* will only be relevant when we return, that's why we can do it early */
+      if (retcode < 0) {
+        set_locked(false);
+        ldout(store->ctx(), 20) << *this << ": couldn't lock " << pool.name << ":" << oid << ":" << lock_name << ": retcode=" << retcode << dendl;
+        return set_state(RGWCoroutine_Error, retcode);
+      }
+      set_locked(true);
+      yield wait(utime_t(interval / 2, 0));
+    }
+    set_locked(false); /* moot at this point anyway */
+    yield call(new RGWSimpleRadosUnlockCR(async_rados, store, pool, oid, lock_name, cookie));
+    return set_state(RGWCoroutine_Done);
+  }
+  return 0;
+}
+
+RGWRadosTimelogAddCR::RGWRadosTimelogAddCR(RGWRados *_store, const string& _oid,
+                      const cls_log_entry& entry) : RGWSimpleCoroutine(_store->ctx()),
+                                                store(_store),
+                                                oid(_oid), cn(NULL)
+{
+  stringstream& s = set_description();
+  s << "timelog add entry oid=" <<  oid << "entry={id=" << entry.id << ", section=" << entry.section << ", name=" << entry.name << "}";
+  entries.push_back(entry);
+}
+
+RGWRadosTimelogAddCR::~RGWRadosTimelogAddCR()
+{
+  if (cn) {
+    cn->put();
+  }
+}
+
+int RGWRadosTimelogAddCR::send_request()
+{
+  set_status() << "sending request";
+
+  cn = stack->create_completion_notifier();
+  cn->get();
+  return store->time_log_add(oid, entries, cn->completion(), true);
+}
+
+int RGWRadosTimelogAddCR::request_complete()
+{
+  int r = cn->completion()->get_return_value();
+
+  set_status() << "request complete; ret=" << r;
+
+  return r;
+}
+
+int RGWAsyncStatObj::_send_request()
+{
+  return store->raw_obj_stat(obj, psize, pmtime, pepoch,
+                             nullptr, nullptr, objv_tracker);
+}
+
+RGWStatObjCR::RGWStatObjCR(RGWAsyncRadosProcessor *async_rados, RGWRados *store,
+                           const rgw_obj& obj, uint64_t *psize,
+                           real_time* pmtime, uint64_t *pepoch,
+                           RGWObjVersionTracker *objv_tracker)
+  : RGWSimpleCoroutine(store->ctx()), store(store), async_rados(async_rados),
+    obj(obj), psize(psize), pmtime(pmtime), pepoch(pepoch),
+    objv_tracker(objv_tracker)
+{
+}
+
+RGWStatObjCR::~RGWStatObjCR()
+{
+  if (req) {
+    req->finish();
+  }
+}
+
+int RGWStatObjCR::send_request()
+{
+  req = new RGWAsyncStatObj(this, stack->create_completion_notifier(),
+                            store, obj, psize, pmtime, pepoch, objv_tracker);
+  async_rados->queue(req);
+  return 0;
+}
+
+int RGWStatObjCR::request_complete()
+{
+  return req->get_ret_status();
+}
diff --git a/src/rgw/rgw_cr_rados.h b/src/rgw/rgw_cr_rados.h
new file mode 100644
index 0000000..f320076
--- /dev/null
+++ b/src/rgw/rgw_cr_rados.h
@@ -0,0 +1,940 @@
+#ifndef CEPH_RGW_CR_RADOS_H
+#define CEPH_RGW_CR_RADOS_H
+
+#include "rgw_coroutine.h"
+#include "common/WorkQueue.h"
+#include "common/Throttle.h"
+
+class RGWAsyncRadosRequest : public RefCountedObject {
+  RGWCoroutine *caller;
+  RGWAioCompletionNotifier *notifier;
+
+  void *user_info;
+  int retcode;
+
+  bool done;
+
+  Mutex lock;
+
+protected:
+  virtual int _send_request() = 0;
+public:
+  RGWAsyncRadosRequest(RGWCoroutine *_caller, RGWAioCompletionNotifier *_cn) : caller(_caller), notifier(_cn),
+                                                                               done(false), lock("RGWAsyncRadosRequest::lock") {
+    caller->get();
+  }
+  virtual ~RGWAsyncRadosRequest() {
+    caller->put();
+  }
+
+  void send_request() {
+    retcode = _send_request();
+    {
+      Mutex::Locker l(lock);
+      if (!done) {
+        notifier->cb();
+      }
+    }
+  }
+
+  int get_ret_status() { return retcode; }
+
+  void finish() {
+    {
+      Mutex::Locker l(lock);
+      done = true;
+    }
+    put();
+  }
+};
+
+
+class RGWAsyncRadosProcessor {
+  deque<RGWAsyncRadosRequest *> m_req_queue;
+  atomic_t going_down;
+protected:
+  RGWRados *store;
+  ThreadPool m_tp;
+  Throttle req_throttle;
+
+  struct RGWWQ : public ThreadPool::WorkQueue<RGWAsyncRadosRequest> {
+    RGWAsyncRadosProcessor *processor;
+    RGWWQ(RGWAsyncRadosProcessor *p, time_t timeout, time_t suicide_timeout, ThreadPool *tp)
+      : ThreadPool::WorkQueue<RGWAsyncRadosRequest>("RGWWQ", timeout, suicide_timeout, tp), processor(p) {}
+
+    bool _enqueue(RGWAsyncRadosRequest *req);
+    void _dequeue(RGWAsyncRadosRequest *req) {
+      assert(0);
+    }
+    bool _empty();
+    RGWAsyncRadosRequest *_dequeue();
+    using ThreadPool::WorkQueue<RGWAsyncRadosRequest>::_process;
+    void _process(RGWAsyncRadosRequest *req, ThreadPool::TPHandle& handle);
+    void _dump_queue();
+    void _clear() {
+      assert(processor->m_req_queue.empty());
+    }
+  } req_wq;
+
+public:
+  RGWAsyncRadosProcessor(RGWRados *_store, int num_threads);
+  ~RGWAsyncRadosProcessor() {}
+  void start();
+  void stop();
+  void handle_request(RGWAsyncRadosRequest *req);
+  void queue(RGWAsyncRadosRequest *req);
+
+  bool is_going_down() {
+    return (going_down.read() != 0);
+  }
+};
+
+
+class RGWAsyncGetSystemObj : public RGWAsyncRadosRequest {
+  RGWRados *store;
+  RGWObjectCtx *obj_ctx;
+  RGWRados::SystemObject::Read::GetObjState read_state;
+  RGWObjVersionTracker *objv_tracker;
+  rgw_obj obj;
+  bufferlist *pbl;
+  map<string, bufferlist> *pattrs;
+  off_t ofs;
+  off_t end;
+protected:
+  int _send_request();
+public:
+  RGWAsyncGetSystemObj(RGWCoroutine *caller, RGWAioCompletionNotifier *cn, RGWRados *_store, RGWObjectCtx *_obj_ctx,
+                       RGWObjVersionTracker *_objv_tracker, rgw_obj& _obj,
+                       bufferlist *_pbl, off_t _ofs, off_t _end);
+  void set_read_attrs(map<string, bufferlist> *_pattrs) { pattrs = _pattrs; }
+};
+
+class RGWAsyncPutSystemObj : public RGWAsyncRadosRequest {
+  RGWRados *store;
+  rgw_obj obj;
+  bool exclusive;
+  bufferlist bl;
+
+protected:
+  int _send_request();
+public:
+  RGWAsyncPutSystemObj(RGWCoroutine *caller, RGWAioCompletionNotifier *cn, RGWRados *_store,
+                       rgw_obj& _obj, bool _exclusive,
+                       bufferlist& _bl);
+};
+
+class RGWAsyncPutSystemObjAttrs : public RGWAsyncRadosRequest {
+  RGWRados *store;
+  RGWObjVersionTracker *objv_tracker;
+  rgw_obj obj;
+  map<string, bufferlist> *attrs;
+
+protected:
+  int _send_request();
+public:
+  RGWAsyncPutSystemObjAttrs(RGWCoroutine *caller, RGWAioCompletionNotifier *cn, RGWRados *_store,
+                       RGWObjVersionTracker *_objv_tracker, rgw_obj& _obj,
+                       map<string, bufferlist> *_attrs);
+};
+
+class RGWAsyncLockSystemObj : public RGWAsyncRadosRequest {
+  RGWRados *store;
+  rgw_obj obj;
+  string lock_name;
+  string cookie;
+  uint32_t duration_secs;
+
+protected:
+  int _send_request();
+public:
+  RGWAsyncLockSystemObj(RGWCoroutine *caller, RGWAioCompletionNotifier *cn, RGWRados *_store,
+                        RGWObjVersionTracker *_objv_tracker, rgw_obj& _obj,
+		        const string& _name, const string& _cookie, uint32_t _duration_secs);
+};
+
+class RGWAsyncUnlockSystemObj : public RGWAsyncRadosRequest {
+  RGWRados *store;
+  rgw_obj obj;
+  string lock_name;
+  string cookie;
+
+protected:
+  int _send_request();
+public:
+  RGWAsyncUnlockSystemObj(RGWCoroutine *caller, RGWAioCompletionNotifier *cn, RGWRados *_store,
+                        RGWObjVersionTracker *_objv_tracker, rgw_obj& _obj,
+		        const string& _name, const string& _cookie);
+};
+
+
+template <class T>
+class RGWSimpleRadosReadCR : public RGWSimpleCoroutine {
+  RGWAsyncRadosProcessor *async_rados;
+  RGWRados *store;
+  RGWObjectCtx& obj_ctx;
+  bufferlist bl;
+
+  rgw_bucket pool;
+  string oid;
+
+  map<string, bufferlist> *pattrs;
+
+  T *result;
+
+  RGWAsyncGetSystemObj *req;
+
+public:
+  RGWSimpleRadosReadCR(RGWAsyncRadosProcessor *_async_rados, RGWRados *_store,
+		      RGWObjectCtx& _obj_ctx,
+		      const rgw_bucket& _pool, const string& _oid,
+		      T *_result) : RGWSimpleCoroutine(_store->ctx()),
+                                                async_rados(_async_rados), store(_store),
+                                                obj_ctx(_obj_ctx),
+						pool(_pool), oid(_oid),
+                                                pattrs(NULL),
+						result(_result),
+                                                req(NULL) { }
+                                                         
+  ~RGWSimpleRadosReadCR() {
+    if (req) {
+      req->finish();
+    }
+  }
+
+  int send_request();
+  int request_complete();
+
+  virtual int handle_data(T& data) {
+    return 0;
+  }
+};
+
+template <class T>
+int RGWSimpleRadosReadCR<T>::send_request()
+{
+  rgw_obj obj = rgw_obj(pool, oid);
+  req = new RGWAsyncGetSystemObj(this, stack->create_completion_notifier(),
+			         store, &obj_ctx, NULL,
+				 obj,
+				 &bl, 0, -1);
+  if (pattrs) {
+    req->set_read_attrs(pattrs);
+  }
+  async_rados->queue(req);
+  return 0;
+}
+
+template <class T>
+int RGWSimpleRadosReadCR<T>::request_complete()
+{
+  int ret = req->get_ret_status();
+  retcode = ret;
+  if (ret != -ENOENT) {
+    if (ret < 0) {
+      return ret;
+    }
+    bufferlist::iterator iter = bl.begin();
+    try {
+      ::decode(*result, iter);
+    } catch (buffer::error& err) {
+      return -EIO;
+    }
+  } else {
+    *result = T();
+  }
+
+  return handle_data(*result);
+}
+
+class RGWSimpleRadosReadAttrsCR : public RGWSimpleCoroutine {
+  RGWAsyncRadosProcessor *async_rados;
+  RGWRados *store;
+  RGWObjectCtx& obj_ctx;
+  bufferlist bl;
+
+  rgw_bucket pool;
+  string oid;
+
+  map<string, bufferlist> *pattrs;
+
+  RGWAsyncGetSystemObj *req;
+
+public:
+  RGWSimpleRadosReadAttrsCR(RGWAsyncRadosProcessor *_async_rados, RGWRados *_store,
+		      RGWObjectCtx& _obj_ctx,
+		      rgw_bucket& _pool, const string& _oid,
+		      map<string, bufferlist> *_pattrs) : RGWSimpleCoroutine(_store->ctx()),
+                                                async_rados(_async_rados), store(_store),
+                                                obj_ctx(_obj_ctx),
+						pool(_pool), oid(_oid),
+                                                pattrs(_pattrs),
+                                                req(NULL) { }
+                                                         
+  ~RGWSimpleRadosReadAttrsCR() {
+    if (req) {
+      req->finish();
+    }
+  }
+
+  int send_request();
+  int request_complete();
+};
+
+template <class T>
+class RGWSimpleRadosWriteCR : public RGWSimpleCoroutine {
+  RGWAsyncRadosProcessor *async_rados;
+  RGWRados *store;
+  bufferlist bl;
+
+  rgw_bucket pool;
+  string oid;
+
+  RGWAsyncPutSystemObj *req;
+
+public:
+  RGWSimpleRadosWriteCR(RGWAsyncRadosProcessor *_async_rados, RGWRados *_store,
+		      const rgw_bucket& _pool, const string& _oid,
+		      const T& _data) : RGWSimpleCoroutine(_store->ctx()),
+                                                async_rados(_async_rados),
+						store(_store),
+						pool(_pool), oid(_oid),
+                                                req(NULL) {
+    ::encode(_data, bl);
+  }
+
+  ~RGWSimpleRadosWriteCR() {
+    if (req) {
+      req->finish();
+    }
+  }
+
+  int send_request() {
+    rgw_obj obj = rgw_obj(pool, oid);
+    req = new RGWAsyncPutSystemObj(this, stack->create_completion_notifier(),
+			           store, obj, false, bl);
+    async_rados->queue(req);
+    return 0;
+  }
+
+  int request_complete() {
+    return req->get_ret_status();
+  }
+};
+
+class RGWSimpleRadosWriteAttrsCR : public RGWSimpleCoroutine {
+  RGWAsyncRadosProcessor *async_rados;
+  RGWRados *store;
+
+  rgw_bucket pool;
+  string oid;
+
+  map<string, bufferlist> attrs;
+
+  RGWAsyncPutSystemObjAttrs *req;
+
+public:
+  RGWSimpleRadosWriteAttrsCR(RGWAsyncRadosProcessor *_async_rados, RGWRados *_store,
+		      rgw_bucket& _pool, const string& _oid,
+		      map<string, bufferlist>& _attrs) : RGWSimpleCoroutine(_store->ctx()),
+                                                async_rados(_async_rados),
+						store(_store),
+						pool(_pool), oid(_oid),
+                                                attrs(_attrs), req(NULL) {
+  }
+
+  ~RGWSimpleRadosWriteAttrsCR() {
+    if (req) {
+      req->finish();
+    }
+  }
+
+  int send_request() {
+    rgw_obj obj = rgw_obj(pool, oid);
+    req = new RGWAsyncPutSystemObjAttrs(this, stack->create_completion_notifier(),
+			           store, NULL, obj, &attrs);
+    async_rados->queue(req);
+    return 0;
+  }
+
+  int request_complete() {
+    return req->get_ret_status();
+  }
+};
+
+class RGWRadosSetOmapKeysCR : public RGWSimpleCoroutine {
+  RGWRados *store;
+  map<string, bufferlist> entries;
+
+  rgw_bucket pool;
+  string oid;
+
+  RGWAioCompletionNotifier *cn;
+
+public:
+  RGWRadosSetOmapKeysCR(RGWRados *_store,
+		      rgw_bucket& _pool, const string& _oid,
+		      map<string, bufferlist>& _entries);
+  ~RGWRadosSetOmapKeysCR();
+
+  int send_request();
+  int request_complete();
+};
+
+class RGWRadosGetOmapKeysCR : public RGWSimpleCoroutine {
+  RGWRados *store;
+
+  string marker;
+  map<string, bufferlist> *entries;
+  int max_entries;
+
+  int rval;
+  librados::IoCtx ioctx;
+
+  rgw_bucket pool;
+  string oid;
+
+  RGWAioCompletionNotifier *cn;
+
+public:
+  RGWRadosGetOmapKeysCR(RGWRados *_store,
+		      const rgw_bucket& _pool, const string& _oid,
+		      const string& _marker,
+		      map<string, bufferlist> *_entries, int _max_entries);
+  ~RGWRadosGetOmapKeysCR();
+
+  int send_request();
+
+  int request_complete() {
+    return rval;
+  }
+};
+
+class RGWSimpleRadosLockCR : public RGWSimpleCoroutine {
+  RGWAsyncRadosProcessor *async_rados;
+  RGWRados *store;
+  string lock_name;
+  string cookie;
+  uint32_t duration;
+
+  rgw_bucket pool;
+  string oid;
+
+  RGWAsyncLockSystemObj *req;
+
+public:
+  RGWSimpleRadosLockCR(RGWAsyncRadosProcessor *_async_rados, RGWRados *_store,
+		      const rgw_bucket& _pool, const string& _oid, const string& _lock_name,
+		      const string& _cookie,
+		      uint32_t _duration);
+  ~RGWSimpleRadosLockCR();
+
+  int send_request();
+  int request_complete();
+};
+
+class RGWSimpleRadosUnlockCR : public RGWSimpleCoroutine {
+  RGWAsyncRadosProcessor *async_rados;
+  RGWRados *store;
+  string lock_name;
+  string cookie;
+
+  rgw_bucket pool;
+  string oid;
+
+  RGWAsyncUnlockSystemObj *req;
+
+public:
+  RGWSimpleRadosUnlockCR(RGWAsyncRadosProcessor *_async_rados, RGWRados *_store,
+		      const rgw_bucket& _pool, const string& _oid, const string& _lock_name,
+		      const string& _cookie);
+  ~RGWSimpleRadosUnlockCR();
+
+  int send_request();
+  int request_complete();
+};
+
+class RGWOmapAppend : public RGWConsumerCR<string> {
+  RGWAsyncRadosProcessor *async_rados;
+  RGWRados *store;
+
+  rgw_bucket pool;
+  string oid;
+
+  bool going_down;
+
+  int num_pending_entries;
+  list<string> pending_entries;
+
+  map<string, bufferlist> entries;
+
+  uint64_t total_entries;
+public:
+  RGWOmapAppend(RGWAsyncRadosProcessor *_async_rados, RGWRados *_store, rgw_bucket& _pool, const string& _oid);
+  int operate();
+  void flush_pending();
+  bool append(const string& s);
+  bool finish();
+
+  uint64_t get_total_entries() {
+    return total_entries;
+  }
+};
+
+class RGWAsyncWait : public RGWAsyncRadosRequest {
+  CephContext *cct;
+  Mutex *lock;
+  Cond *cond;
+  utime_t interval;
+protected:
+  int _send_request() {
+    Mutex::Locker l(*lock);
+    return cond->WaitInterval(cct, *lock, interval);
+  }
+public:
+  RGWAsyncWait(RGWCoroutine *caller, RGWAioCompletionNotifier *cn, CephContext *_cct,
+               Mutex *_lock, Cond *_cond, int _secs) : RGWAsyncRadosRequest(caller, cn),
+                                       cct(_cct),
+                                       lock(_lock), cond(_cond), interval(_secs, 0) {}
+
+  void wakeup() {
+    Mutex::Locker l(*lock);
+    cond->Signal();
+  }
+};
+
+class RGWWaitCR : public RGWSimpleCoroutine {
+  CephContext *cct;
+  RGWAsyncRadosProcessor *async_rados;
+  Mutex *lock;
+  Cond *cond;
+  int secs;
+
+  RGWAsyncWait *req;
+
+public:
+  RGWWaitCR(RGWAsyncRadosProcessor *_async_rados, CephContext *_cct,
+	    Mutex *_lock, Cond *_cond,
+            int _secs) : RGWSimpleCoroutine(cct), cct(_cct),
+                         async_rados(_async_rados), lock(_lock), cond(_cond), secs(_secs), req(NULL) {
+  }
+
+  ~RGWWaitCR() {
+    wakeup();
+    if (req) {
+      req->finish();
+    }
+  }
+
+  int send_request() {
+    req = new RGWAsyncWait(this, stack->create_completion_notifier(), cct,  lock, cond, secs);
+    async_rados->queue(req);
+    return 0;
+  }
+
+  int request_complete() {
+    return req->get_ret_status();
+  }
+
+  void wakeup() {
+    req->wakeup();
+  }
+};
+
+class RGWShardedOmapCRManager {
+  RGWAsyncRadosProcessor *async_rados;
+  RGWRados *store;
+  RGWCoroutine *op;
+
+  int num_shards;
+
+  vector<RGWOmapAppend *> shards;
+public:
+  RGWShardedOmapCRManager(RGWAsyncRadosProcessor *_async_rados, RGWRados *_store, RGWCoroutine *_op, int _num_shards, rgw_bucket& pool, const string& oid_prefix)
+                      : async_rados(_async_rados),
+		        store(_store), op(_op), num_shards(_num_shards) {
+    shards.reserve(num_shards);
+    for (int i = 0; i < num_shards; ++i) {
+      char buf[oid_prefix.size() + 16];
+      snprintf(buf, sizeof(buf), "%s.%d", oid_prefix.c_str(), i);
+      RGWOmapAppend *shard = new RGWOmapAppend(async_rados, store, pool, buf);
+      shard->get();
+      shards.push_back(shard);
+      op->spawn(shard, false);
+    }
+  }
+
+  ~RGWShardedOmapCRManager() {
+    for (auto shard : shards) {
+      shard->put();
+    }
+  }
+
+  bool append(const string& entry, int shard_id) {
+    return shards[shard_id]->append(entry);
+  }
+  bool finish() {
+    bool success = true;
+    for (vector<RGWOmapAppend *>::iterator iter = shards.begin(); iter != shards.end(); ++iter) {
+      success &= ((*iter)->finish() && (!(*iter)->is_error()));
+    }
+    return success;
+  }
+
+  uint64_t get_total_entries(int shard_id) {
+    return shards[shard_id]->get_total_entries();
+  }
+};
+
+class RGWAsyncGetBucketInstanceInfo : public RGWAsyncRadosRequest {
+  RGWRados *store;
+  string bucket_name;
+  string bucket_id;
+  RGWBucketInfo *bucket_info;
+
+protected:
+  int _send_request();
+public:
+  RGWAsyncGetBucketInstanceInfo(RGWCoroutine *caller, RGWAioCompletionNotifier *cn, RGWRados *_store,
+		        const string& _bucket_name, const string& _bucket_id,
+                        RGWBucketInfo *_bucket_info) : RGWAsyncRadosRequest(caller, cn), store(_store),
+                                                       bucket_name(_bucket_name), bucket_id(_bucket_id),
+                                                       bucket_info(_bucket_info) {}
+};
+
+class RGWGetBucketInstanceInfoCR : public RGWSimpleCoroutine {
+  RGWAsyncRadosProcessor *async_rados;
+  RGWRados *store;
+  string bucket_name;
+  string bucket_id;
+  RGWBucketInfo *bucket_info;
+
+  RGWAsyncGetBucketInstanceInfo *req;
+  
+public:
+  RGWGetBucketInstanceInfoCR(RGWAsyncRadosProcessor *_async_rados, RGWRados *_store,
+		        const string& _bucket_name, const string& _bucket_id,
+                        RGWBucketInfo *_bucket_info) : RGWSimpleCoroutine(_store->ctx()), async_rados(_async_rados), store(_store),
+                                                       bucket_name(_bucket_name), bucket_id(_bucket_id),
+                                                       bucket_info(_bucket_info), req(NULL) {}
+  ~RGWGetBucketInstanceInfoCR() {
+    if (req) {
+      req->finish();
+    }
+  }
+
+  int send_request() {
+    req = new RGWAsyncGetBucketInstanceInfo(this, stack->create_completion_notifier(), store, bucket_name, bucket_id, bucket_info);
+    async_rados->queue(req);
+    return 0;
+  }
+  int request_complete() {
+    return req->get_ret_status();
+  }
+};
+
+class RGWAsyncFetchRemoteObj : public RGWAsyncRadosRequest {
+  RGWRados *store;
+  string source_zone;
+
+  RGWBucketInfo bucket_info;
+
+  rgw_obj_key key;
+  uint64_t versioned_epoch;
+
+  real_time src_mtime;
+
+  bool copy_if_newer;
+
+protected:
+  int _send_request();
+public:
+  RGWAsyncFetchRemoteObj(RGWCoroutine *caller, RGWAioCompletionNotifier *cn, RGWRados *_store,
+                         const string& _source_zone,
+                         RGWBucketInfo& _bucket_info,
+                         const rgw_obj_key& _key,
+                         uint64_t _versioned_epoch,
+                         bool _if_newer) : RGWAsyncRadosRequest(caller, cn), store(_store),
+                                                      source_zone(_source_zone),
+                                                      bucket_info(_bucket_info),
+                                                      key(_key),
+                                                      versioned_epoch(_versioned_epoch),
+                                                      copy_if_newer(_if_newer) {}
+};
+
+class RGWFetchRemoteObjCR : public RGWSimpleCoroutine {
+  CephContext *cct;
+  RGWAsyncRadosProcessor *async_rados;
+  RGWRados *store;
+  string source_zone;
+
+  RGWBucketInfo bucket_info;
+
+  rgw_obj_key key;
+  uint64_t versioned_epoch;
+
+  real_time src_mtime;
+
+  bool copy_if_newer;
+
+  RGWAsyncFetchRemoteObj *req;
+
+public:
+  RGWFetchRemoteObjCR(RGWAsyncRadosProcessor *_async_rados, RGWRados *_store,
+                      const string& _source_zone,
+                      RGWBucketInfo& _bucket_info,
+                      const rgw_obj_key& _key,
+                      uint64_t _versioned_epoch,
+                      bool _if_newer) : RGWSimpleCoroutine(_store->ctx()), cct(_store->ctx()),
+                                       async_rados(_async_rados), store(_store),
+                                       source_zone(_source_zone),
+                                       bucket_info(_bucket_info),
+                                       key(_key),
+                                       versioned_epoch(_versioned_epoch),
+                                       copy_if_newer(_if_newer), req(NULL) {}
+
+
+  ~RGWFetchRemoteObjCR() {
+    if (req) {
+      req->finish();
+    }
+  }
+
+  int send_request() {
+    req = new RGWAsyncFetchRemoteObj(this, stack->create_completion_notifier(), store, source_zone, bucket_info,
+                                     key, versioned_epoch, copy_if_newer);
+    async_rados->queue(req);
+    return 0;
+  }
+
+  int request_complete() {
+    return req->get_ret_status();
+  }
+};
+
+class RGWAsyncRemoveObj : public RGWAsyncRadosRequest {
+  RGWRados *store;
+  string source_zone;
+
+  RGWBucketInfo bucket_info;
+
+  rgw_obj_key key;
+  string owner;
+  string owner_display_name;
+  bool versioned;
+  uint64_t versioned_epoch;
+  string marker_version_id;
+
+  bool del_if_older;
+  ceph::real_time timestamp;
+
+protected:
+  int _send_request();
+public:
+  RGWAsyncRemoveObj(RGWCoroutine *caller, RGWAioCompletionNotifier *cn, RGWRados *_store,
+                         const string& _source_zone,
+                         RGWBucketInfo& _bucket_info,
+                         const rgw_obj_key& _key,
+                         const string& _owner,
+                         const string& _owner_display_name,
+                         bool _versioned,
+                         uint64_t _versioned_epoch,
+                         bool _delete_marker,
+                         bool _if_older,
+                         real_time& _timestamp) : RGWAsyncRadosRequest(caller, cn), store(_store),
+                                                      source_zone(_source_zone),
+                                                      bucket_info(_bucket_info),
+                                                      key(_key),
+                                                      owner(_owner),
+                                                      owner_display_name(_owner_display_name),
+                                                      versioned(_versioned),
+                                                      versioned_epoch(_versioned_epoch),
+                                                      del_if_older(_if_older),
+                                                      timestamp(_timestamp) {
+    if (_delete_marker) {
+      marker_version_id = key.instance;
+    }
+  }
+};
+
+class RGWRemoveObjCR : public RGWSimpleCoroutine {
+  CephContext *cct;
+  RGWAsyncRadosProcessor *async_rados;
+  RGWRados *store;
+  string source_zone;
+
+  RGWBucketInfo bucket_info;
+
+  rgw_obj_key key;
+  bool versioned;
+  uint64_t versioned_epoch;
+  bool delete_marker;
+  string owner;
+  string owner_display_name;
+
+  bool del_if_older;
+  real_time timestamp;
+
+  RGWAsyncRemoveObj *req;
+
+public:
+  RGWRemoveObjCR(RGWAsyncRadosProcessor *_async_rados, RGWRados *_store,
+                      const string& _source_zone,
+                      RGWBucketInfo& _bucket_info,
+                      const rgw_obj_key& _key,
+                      bool _versioned,
+                      uint64_t _versioned_epoch,
+                      string *_owner,
+                      string *_owner_display_name,
+                      bool _delete_marker,
+                      real_time *_timestamp) : RGWSimpleCoroutine(_store->ctx()), cct(_store->ctx()),
+                                       async_rados(_async_rados), store(_store),
+                                       source_zone(_source_zone),
+                                       bucket_info(_bucket_info),
+                                       key(_key),
+                                       versioned(_versioned),
+                                       versioned_epoch(_versioned_epoch),
+                                       delete_marker(_delete_marker), req(NULL) {
+    del_if_older = (_timestamp != NULL);
+    if (_timestamp) {
+      timestamp = *_timestamp;
+    }
+
+    if (_owner) {
+      owner = *_owner;
+    }
+
+    if (_owner_display_name) {
+      owner_display_name = *_owner_display_name;
+    }
+  }
+
+  ~RGWRemoveObjCR() {
+    if (req) {
+      req->finish();
+    }
+  }
+
+  int send_request() {
+    req = new RGWAsyncRemoveObj(this, stack->create_completion_notifier(), store, source_zone, bucket_info,
+                                key, owner, owner_display_name, versioned, versioned_epoch,
+                                delete_marker, del_if_older, timestamp);
+    async_rados->queue(req);
+    return 0;
+  }
+
+  int request_complete() {
+    return req->get_ret_status();
+  }
+};
+
+class RGWContinuousLeaseCR : public RGWCoroutine {
+  RGWAsyncRadosProcessor *async_rados;
+  RGWRados *store;
+
+  const rgw_bucket& pool;
+  string oid;
+
+  string lock_name;
+  string cookie;
+
+  int interval;
+
+  Mutex lock;
+  atomic_t going_down;
+  bool locked;
+
+  RGWCoroutine *caller;
+
+  bool aborted;
+
+public:
+  RGWContinuousLeaseCR(RGWAsyncRadosProcessor *_async_rados, RGWRados *_store,
+                       const rgw_bucket& _pool, const string& _oid,
+                       const string& _lock_name, int _interval, RGWCoroutine *_caller) : RGWCoroutine(_store->ctx()), async_rados(_async_rados), store(_store),
+                                        pool(_pool), oid(_oid), lock_name(_lock_name), interval(_interval),
+                                        lock("RGWContimuousLeaseCR"), locked(false), caller(_caller), aborted(false) {
+#define COOKIE_LEN 16
+    char buf[COOKIE_LEN + 1];
+
+    gen_rand_alphanumeric(cct, buf, sizeof(buf) - 1);
+    cookie = buf;
+  }
+
+  int operate();
+
+  bool is_locked() {
+    Mutex::Locker l(lock);
+    return locked;
+  }
+
+  void set_locked(bool status) {
+    Mutex::Locker l(lock);
+    locked = status;
+  }
+
+  void go_down() {
+    going_down.set(1);
+    wakeup();
+  }
+
+  void abort() {
+    aborted = true;
+  }
+};
+
+class RGWRadosTimelogAddCR : public RGWSimpleCoroutine {
+  RGWRados *store;
+  list<cls_log_entry> entries;
+
+  string oid;
+
+  RGWAioCompletionNotifier *cn;
+
+public:
+  RGWRadosTimelogAddCR(RGWRados *_store, const string& _oid,
+		        const cls_log_entry& entry);
+  ~RGWRadosTimelogAddCR();
+
+  int send_request();
+  int request_complete();
+};
+
+class RGWAsyncStatObj : public RGWAsyncRadosRequest {
+  RGWRados *store;
+  rgw_obj obj;
+  uint64_t *psize;
+  real_time *pmtime;
+  uint64_t *pepoch;
+  RGWObjVersionTracker *objv_tracker;
+protected:
+  int _send_request() override;
+public:
+  RGWAsyncStatObj(RGWCoroutine *caller, RGWAioCompletionNotifier *cn, RGWRados *store,
+                  const rgw_obj& obj, uint64_t *psize = nullptr,
+                  real_time *pmtime = nullptr, uint64_t *pepoch = nullptr,
+                  RGWObjVersionTracker *objv_tracker = nullptr)
+	  : RGWAsyncRadosRequest(caller, cn), store(store), obj(obj), psize(psize),
+	  pmtime(pmtime), pepoch(pepoch), objv_tracker(objv_tracker) {}
+};
+
+class RGWStatObjCR : public RGWSimpleCoroutine {
+  RGWRados *store;
+  RGWAsyncRadosProcessor *async_rados;
+  rgw_obj obj;
+  uint64_t *psize;
+  real_time *pmtime;
+  uint64_t *pepoch;
+  RGWObjVersionTracker *objv_tracker;
+  RGWAsyncStatObj *req = nullptr;
+ public:
+  RGWStatObjCR(RGWAsyncRadosProcessor *async_rados, RGWRados *store,
+	  const rgw_obj& obj, uint64_t *psize = nullptr,
+	  real_time* pmtime = nullptr, uint64_t *pepoch = nullptr,
+	  RGWObjVersionTracker *objv_tracker = nullptr);
+  ~RGWStatObjCR();
+
+  int send_request() override;
+  int request_complete() override;
+};
+
+#endif
diff --git a/src/rgw/rgw_cr_rest.h b/src/rgw/rgw_cr_rest.h
new file mode 100644
index 0000000..88a051a
--- /dev/null
+++ b/src/rgw/rgw_cr_rest.h
@@ -0,0 +1,118 @@
+#ifndef CEPH_RGW_CR_REST_H
+#define CEPH_RGW_CR_REST_H
+
+#include <boost/intrusive_ptr.hpp>
+#include "include/assert.h" // boost header clobbers our assert.h
+
+#include "rgw_coroutine.h"
+#include "rgw_rest_conn.h"
+
+template <class T>
+class RGWReadRESTResourceCR : public RGWSimpleCoroutine {
+  RGWRESTConn *conn;
+  RGWHTTPManager *http_manager;
+  string path;
+  param_list_t params;
+  T *result;
+
+  boost::intrusive_ptr<RGWRESTReadResource> http_op;
+
+public:
+  RGWReadRESTResourceCR(CephContext *_cct, RGWRESTConn *_conn,
+                        RGWHTTPManager *_http_manager, const string& _path,
+                        rgw_http_param_pair *params, T *_result)
+    : RGWSimpleCoroutine(_cct), conn(_conn), http_manager(_http_manager),
+      path(_path), params(make_param_list(params)), result(_result)
+  {}
+
+  int send_request() {
+    auto op = boost::intrusive_ptr<RGWRESTReadResource>(
+        new RGWRESTReadResource(conn, path, params, NULL, http_manager));
+
+    op->set_user_info((void *)stack);
+
+    int ret = op->aio_read();
+    if (ret < 0) {
+      log_error() << "failed to send http operation: " << op->to_str()
+          << " ret=" << ret << std::endl;
+      return ret;
+    }
+    std::swap(http_op, op); // store reference in http_op on success
+    return 0;
+  }
+
+  int request_complete() {
+    int ret = http_op->wait(result);
+    auto op = std::move(http_op); // release ref on return
+    if (ret < 0) {
+      error_stream << "http operation failed: " << op->to_str()
+          << " status=" << op->get_http_status() << std::endl;
+      return ret;
+    }
+    return 0;
+  }
+};
+
+template <class S, class T>
+class RGWPostRESTResourceCR : public RGWSimpleCoroutine {
+  RGWRESTConn *conn;
+  RGWHTTPManager *http_manager;
+  string path;
+  param_list_t params;
+  T *result;
+  S input;
+
+  boost::intrusive_ptr<RGWRESTPostResource> http_op;
+
+public:
+  RGWPostRESTResourceCR(CephContext *_cct, RGWRESTConn *_conn,
+                        RGWHTTPManager *_http_manager, const string& _path,
+                        rgw_http_param_pair *_params, S& _input, T *_result)
+    : RGWSimpleCoroutine(_cct), conn(_conn), http_manager(_http_manager),
+      path(_path), params(make_param_list(_params)), result(_result),
+      input(_input)
+  {}
+
+  int send_request() {
+    auto op = boost::intrusive_ptr<RGWRESTPostResource>(
+        new RGWRESTPostResource(conn, path, params, NULL, http_manager));
+
+    op->set_user_info((void *)stack);
+
+    JSONFormatter jf;
+    encode_json("data", input, &jf);
+    std::stringstream ss;
+    jf.flush(ss);
+    bufferlist bl;
+    bl.append(ss.str());
+
+    int ret = op->aio_send(bl);
+    if (ret < 0) {
+      lsubdout(cct, rgw, 0) << "ERROR: failed to send post request" << dendl;
+      return ret;
+    }
+    std::swap(http_op, op); // store reference in http_op on success
+    return 0;
+  }
+
+  int request_complete() {
+    int ret;
+    if (result) {
+      ret = http_op->wait(result);
+    } else {
+      bufferlist bl;
+      ret = http_op->wait_bl(&bl);
+    }
+    auto op = std::move(http_op); // release ref on return
+    if (ret < 0) {
+      error_stream << "http operation failed: " << op->to_str()
+          << " status=" << op->get_http_status() << std::endl;
+      lsubdout(cct, rgw, 0) << "ERROR: failed to wait for op, ret=" << ret
+          << ": " << op->to_str() << dendl;
+      return ret;
+    }
+    return 0;
+  }
+};
+
+#endif
diff --git a/src/rgw/rgw_data_sync.cc b/src/rgw/rgw_data_sync.cc
new file mode 100644
index 0000000..3aa0f48
--- /dev/null
+++ b/src/rgw/rgw_data_sync.cc
@@ -0,0 +1,2557 @@
+#include "common/ceph_json.h"
+#include "common/RWLock.h"
+#include "common/RefCountedObj.h"
+#include "common/WorkQueue.h"
+#include "common/Throttle.h"
+#include "common/errno.h"
+
+#include "rgw_common.h"
+#include "rgw_rados.h"
+#include "rgw_sync.h"
+#include "rgw_data_sync.h"
+#include "rgw_rest_conn.h"
+#include "rgw_cr_rados.h"
+#include "rgw_cr_rest.h"
+#include "rgw_http_client.h"
+#include "rgw_bucket.h"
+#include "rgw_metadata.h"
+#include "rgw_boost_asio_yield.h"
+
+#include "cls/lock/cls_lock_client.h"
+
+#define dout_subsys ceph_subsys_rgw
+
+static string datalog_sync_status_oid_prefix = "datalog.sync-status";
+static string datalog_sync_status_shard_prefix = "datalog.sync-status.shard";
+static string datalog_sync_full_sync_index_prefix = "data.full-sync.index";
+static string bucket_status_oid_prefix = "bucket.sync-status";
+
+void rgw_datalog_info::decode_json(JSONObj *obj) {
+  JSONDecoder::decode_json("num_objects", num_shards, obj);
+}
+
+void rgw_datalog_entry::decode_json(JSONObj *obj) {
+  JSONDecoder::decode_json("key", key, obj);
+  utime_t ut;
+  JSONDecoder::decode_json("timestamp", ut, obj);
+  timestamp = ut.to_real_time();
+}
+
+void rgw_datalog_shard_data::decode_json(JSONObj *obj) {
+  JSONDecoder::decode_json("marker", marker, obj);
+  JSONDecoder::decode_json("truncated", truncated, obj);
+  JSONDecoder::decode_json("entries", entries, obj);
+};
+
+class RGWReadDataSyncStatusCoroutine : public RGWSimpleRadosReadCR<rgw_data_sync_info> {
+  RGWDataSyncEnv *sync_env;
+
+  RGWObjectCtx& obj_ctx;
+
+  rgw_data_sync_status *sync_status;
+
+public:
+  RGWReadDataSyncStatusCoroutine(RGWDataSyncEnv *_sync_env, RGWObjectCtx& _obj_ctx,
+		      rgw_data_sync_status *_status) : RGWSimpleRadosReadCR(_sync_env->async_rados, _sync_env->store, _obj_ctx,
+									    _sync_env->store->get_zone_params().log_pool,
+									    RGWDataSyncStatusManager::sync_status_oid(_sync_env->source_zone),
+									    &_status->sync_info),
+                                                                            sync_env(_sync_env),
+                                                                            obj_ctx(_obj_ctx),
+									    sync_status(_status) {}
+
+  int handle_data(rgw_data_sync_info& data);
+};
+
+int RGWReadDataSyncStatusCoroutine::handle_data(rgw_data_sync_info& data)
+{
+  if (retcode == -ENOENT) {
+    return retcode;
+  }
+
+  map<uint32_t, rgw_data_sync_marker>& markers = sync_status->sync_markers;
+  RGWRados *store = sync_env->store;
+  for (int i = 0; i < (int)data.num_shards; i++) {
+    spawn(new RGWSimpleRadosReadCR<rgw_data_sync_marker>(sync_env->async_rados, store, obj_ctx, store->get_zone_params().log_pool,
+                                                    RGWDataSyncStatusManager::shard_obj_name(sync_env->source_zone, i), &markers[i]), true);
+  }
+  return 0;
+}
+
+class RGWReadRemoteDataLogShardInfoCR : public RGWCoroutine {
+  RGWDataSyncEnv *sync_env;
+
+  RGWRESTReadResource *http_op;
+
+  int shard_id;
+  RGWDataChangesLogInfo *shard_info;
+
+public:
+  RGWReadRemoteDataLogShardInfoCR(RGWDataSyncEnv *_sync_env,
+                                                      int _shard_id, RGWDataChangesLogInfo *_shard_info) : RGWCoroutine(_sync_env->cct),
+                                                      sync_env(_sync_env),
+                                                      http_op(NULL),
+                                                      shard_id(_shard_id),
+                                                      shard_info(_shard_info) {
+  }
+
+  ~RGWReadRemoteDataLogShardInfoCR() {
+    if (http_op) {
+      http_op->put();
+    }
+  }
+
+  int operate() {
+    reenter(this) {
+      yield {
+	char buf[16];
+	snprintf(buf, sizeof(buf), "%d", shard_id);
+        rgw_http_param_pair pairs[] = { { "type" , "data" },
+	                                { "id", buf },
+					{ "info" , NULL },
+	                                { NULL, NULL } };
+
+        string p = "/admin/log/";
+
+        http_op = new RGWRESTReadResource(sync_env->conn, p, pairs, NULL, sync_env->http_manager);
+
+        http_op->set_user_info((void *)stack);
+
+        int ret = http_op->aio_read();
+        if (ret < 0) {
+          ldout(sync_env->cct, 0) << "ERROR: failed to read from " << p << dendl;
+          log_error() << "failed to send http operation: " << http_op->to_str() << " ret=" << ret << std::endl;
+          return set_cr_error(ret);
+        }
+
+        return io_block(0);
+      }
+      yield {
+        int ret = http_op->wait(shard_info);
+        if (ret < 0) {
+          return set_cr_error(ret);
+        }
+        return set_cr_done();
+      }
+    }
+    return 0;
+  }
+};
+
+struct read_remote_data_log_response {
+  string marker;
+  bool truncated;
+  list<rgw_data_change_log_entry> entries;
+
+  read_remote_data_log_response() : truncated(false) {}
+
+  void decode_json(JSONObj *obj) {
+    JSONDecoder::decode_json("marker", marker, obj);
+    JSONDecoder::decode_json("truncated", truncated, obj);
+    JSONDecoder::decode_json("entries", entries, obj);
+  };
+};
+
+class RGWReadRemoteDataLogShardCR : public RGWCoroutine {
+  RGWDataSyncEnv *sync_env;
+
+  RGWRESTReadResource *http_op;
+
+  int shard_id;
+  string *pmarker;
+  list<rgw_data_change_log_entry> *entries;
+  bool *truncated;
+
+  read_remote_data_log_response response;
+
+public:
+  RGWReadRemoteDataLogShardCR(RGWDataSyncEnv *_sync_env,
+                              int _shard_id, string *_pmarker, list<rgw_data_change_log_entry> *_entries, bool *_truncated) : RGWCoroutine(_sync_env->cct),
+                                                      sync_env(_sync_env),
+                                                      http_op(NULL),
+                                                      shard_id(_shard_id),
+                                                      pmarker(_pmarker),
+                                                      entries(_entries),
+                                                      truncated(_truncated) {
+    if (http_op) {
+      http_op->put();
+    }
+  }
+
+  int operate() {
+    reenter(this) {
+      yield {
+	char buf[16];
+	snprintf(buf, sizeof(buf), "%d", shard_id);
+        rgw_http_param_pair pairs[] = { { "type" , "data" },
+	                                { "id", buf },
+	                                { "marker", pmarker->c_str() },
+	                                { "extra-info", "true" },
+	                                { NULL, NULL } };
+
+        string p = "/admin/log/";
+
+        http_op = new RGWRESTReadResource(sync_env->conn, p, pairs, NULL, sync_env->http_manager);
+
+        http_op->set_user_info((void *)stack);
+
+        int ret = http_op->aio_read();
+        if (ret < 0) {
+          ldout(sync_env->cct, 0) << "ERROR: failed to read from " << p << dendl;
+          log_error() << "failed to send http operation: " << http_op->to_str() << " ret=" << ret << std::endl;
+          return set_cr_error(ret);
+        }
+
+        return io_block(0);
+      }
+      yield {
+        int ret = http_op->wait(&response);
+        if (ret < 0) {
+          return set_cr_error(ret);
+        }
+        entries->clear();
+        entries->swap(response.entries);
+        *pmarker = response.marker;
+        *truncated = response.truncated;
+        return set_cr_done();
+      }
+    }
+    return 0;
+  }
+};
+
+class RGWReadRemoteDataLogInfoCR : public RGWShardCollectCR {
+  RGWDataSyncEnv *sync_env;
+
+  int num_shards;
+  map<int, RGWDataChangesLogInfo> *datalog_info;
+
+  int shard_id;
+#define READ_DATALOG_MAX_CONCURRENT 10
+
+public:
+  RGWReadRemoteDataLogInfoCR(RGWDataSyncEnv *_sync_env,
+                     int _num_shards,
+                     map<int, RGWDataChangesLogInfo> *_datalog_info) : RGWShardCollectCR(_sync_env->cct, READ_DATALOG_MAX_CONCURRENT),
+                                                                 sync_env(_sync_env), num_shards(_num_shards),
+                                                                 datalog_info(_datalog_info), shard_id(0) {}
+  bool spawn_next();
+};
+
+bool RGWReadRemoteDataLogInfoCR::spawn_next() {
+  if (shard_id >= num_shards) {
+    return false;
+  }
+  spawn(new RGWReadRemoteDataLogShardInfoCR(sync_env, shard_id, &(*datalog_info)[shard_id]), false);
+  shard_id++;
+  return true;
+}
+
+class RGWListRemoteDataLogShardCR : public RGWSimpleCoroutine {
+  RGWDataSyncEnv *sync_env;
+  RGWRESTReadResource *http_op;
+
+  int shard_id;
+  string marker;
+  uint32_t max_entries;
+  rgw_datalog_shard_data *result;
+
+public:
+  RGWListRemoteDataLogShardCR(RGWDataSyncEnv *env, int _shard_id,
+                              const string& _marker, uint32_t _max_entries,
+                              rgw_datalog_shard_data *_result)
+    : RGWSimpleCoroutine(env->store->ctx()), sync_env(env), http_op(NULL),
+      shard_id(_shard_id), marker(_marker), max_entries(_max_entries), result(_result) {}
+
+  int send_request() {
+    RGWRESTConn *conn = sync_env->conn;
+    RGWRados *store = sync_env->store;
+
+    char buf[32];
+    snprintf(buf, sizeof(buf), "%d", shard_id);
+
+    char max_entries_buf[32];
+    snprintf(max_entries_buf, sizeof(max_entries_buf), "%d", (int)max_entries);
+
+    const char *marker_key = (marker.empty() ? "" : "marker");
+
+    rgw_http_param_pair pairs[] = { { "type", "data" },
+      { "id", buf },
+      { "max-entries", max_entries_buf },
+      { marker_key, marker.c_str() },
+      { NULL, NULL } };
+
+    string p = "/admin/log/";
+
+    http_op = new RGWRESTReadResource(conn, p, pairs, NULL, sync_env->http_manager);
+    http_op->set_user_info((void *)stack);
+
+    int ret = http_op->aio_read();
+    if (ret < 0) {
+      ldout(store->ctx(), 0) << "ERROR: failed to read from " << p << dendl;
+      log_error() << "failed to send http operation: " << http_op->to_str() << " ret=" << ret << std::endl;
+      http_op->put();
+      return ret;
+    }
+
+    return 0;
+  }
+
+  int request_complete() {
+    int ret = http_op->wait(result);
+    if (ret < 0 && ret != -ENOENT) {
+      ldout(sync_env->store->ctx(), 0) << "ERROR: failed to list remote datalog shard, ret=" << ret << dendl;
+      return ret;
+    }
+    return 0;
+  }
+};
+
+class RGWListRemoteDataLogCR : public RGWShardCollectCR {
+  RGWDataSyncEnv *sync_env;
+
+  map<int, string> shards;
+  int max_entries_per_shard;
+  map<int, rgw_datalog_shard_data> *result;
+
+  map<int, string>::iterator iter;
+#define READ_DATALOG_MAX_CONCURRENT 10
+
+public:
+  RGWListRemoteDataLogCR(RGWDataSyncEnv *_sync_env,
+                     map<int, string>& _shards,
+                     int _max_entries_per_shard,
+                     map<int, rgw_datalog_shard_data> *_result) : RGWShardCollectCR(_sync_env->cct, READ_DATALOG_MAX_CONCURRENT),
+                                                                 sync_env(_sync_env), max_entries_per_shard(_max_entries_per_shard),
+                                                                 result(_result) {
+    shards.swap(_shards);
+    iter = shards.begin();
+  }
+  bool spawn_next();
+};
+
+bool RGWListRemoteDataLogCR::spawn_next() {
+  if (iter == shards.end()) {
+    return false;
+  }
+
+  spawn(new RGWListRemoteDataLogShardCR(sync_env, iter->first, iter->second, max_entries_per_shard, &(*result)[iter->first]), false);
+  ++iter;
+  return true;
+}
+
+class RGWInitDataSyncStatusCoroutine : public RGWCoroutine {
+  RGWDataSyncEnv *sync_env;
+
+  RGWRados *store;
+  RGWObjectCtx& obj_ctx;
+
+  string sync_status_oid;
+
+  string lock_name;
+  string cookie;
+  rgw_data_sync_info status;
+  map<int, RGWDataChangesLogInfo> shards_info;
+public:
+  RGWInitDataSyncStatusCoroutine(RGWDataSyncEnv *_sync_env,
+		      RGWObjectCtx& _obj_ctx, uint32_t _num_shards) : RGWCoroutine(_sync_env->cct),
+                                                sync_env(_sync_env), store(sync_env->store),
+                                                obj_ctx(_obj_ctx) {
+    lock_name = "sync_lock";
+    status.num_shards = _num_shards;
+
+#define COOKIE_LEN 16
+    char buf[COOKIE_LEN + 1];
+
+    gen_rand_alphanumeric(cct, buf, sizeof(buf) - 1);
+    string cookie = buf;
+
+    sync_status_oid = RGWDataSyncStatusManager::sync_status_oid(sync_env->source_zone);
+  }
+
+  int operate() {
+    int ret;
+    reenter(this) {
+      yield {
+	uint32_t lock_duration = 30;
+	call(new RGWSimpleRadosLockCR(sync_env->async_rados, store, store->get_zone_params().log_pool, sync_status_oid,
+			             lock_name, cookie, lock_duration));
+	if (retcode < 0) {
+	  ldout(cct, 0) << "ERROR: failed to take a lock on " << sync_status_oid << dendl;
+	  return set_cr_error(retcode);
+	}
+      }
+      yield {
+        call(new RGWSimpleRadosWriteCR<rgw_data_sync_info>(sync_env->async_rados, store, store->get_zone_params().log_pool,
+				 sync_status_oid, status));
+      }
+      yield { /* take lock again, we just recreated the object */
+	uint32_t lock_duration = 30;
+	call(new RGWSimpleRadosLockCR(sync_env->async_rados, store, store->get_zone_params().log_pool, sync_status_oid,
+			             lock_name, cookie, lock_duration));
+	if (retcode < 0) {
+	  ldout(cct, 0) << "ERROR: failed to take a lock on " << sync_status_oid << dendl;
+	  return set_cr_error(retcode);
+	}
+      }
+      /* fetch current position in logs */
+      yield {
+        RGWRESTConn *conn = store->get_zone_conn_by_id(sync_env->source_zone);
+        if (!conn) {
+          ldout(cct, 0) << "ERROR: connection to zone " << sync_env->source_zone << " does not exist!" << dendl;
+          return set_cr_error(-EIO);
+        }
+        for (int i = 0; i < (int)status.num_shards; i++) {
+          spawn(new RGWReadRemoteDataLogShardInfoCR(sync_env, i, &shards_info[i]), true);
+	}
+      }
+      while (collect(&ret)) {
+	if (ret < 0) {
+	  return set_state(RGWCoroutine_Error);
+	}
+        yield;
+      }
+      yield {
+        for (int i = 0; i < (int)status.num_shards; i++) {
+	  rgw_data_sync_marker marker;
+          RGWDataChangesLogInfo& info = shards_info[i];
+	  marker.next_step_marker = info.marker;
+	  marker.timestamp = info.last_update;
+          spawn(new RGWSimpleRadosWriteCR<rgw_data_sync_marker>(sync_env->async_rados, store, store->get_zone_params().log_pool,
+				                          RGWDataSyncStatusManager::shard_obj_name(sync_env->source_zone, i), marker), true);
+        }
+      }
+      yield {
+	status.state = rgw_data_sync_info::StateBuildingFullSyncMaps;
+        call(new RGWSimpleRadosWriteCR<rgw_data_sync_info>(sync_env->async_rados, store, store->get_zone_params().log_pool,
+				 sync_status_oid, status));
+      }
+      yield { /* unlock */
+	call(new RGWSimpleRadosUnlockCR(sync_env->async_rados, store, store->get_zone_params().log_pool, sync_status_oid,
+			             lock_name, cookie));
+      }
+      while (collect(&ret)) {
+	if (ret < 0) {
+	  return set_state(RGWCoroutine_Error);
+	}
+        yield;
+      }
+      drain_all();
+      return set_cr_done();
+    }
+    return 0;
+  }
+};
+
+int RGWRemoteDataLog::read_log_info(rgw_datalog_info *log_info)
+{
+  rgw_http_param_pair pairs[] = { { "type", "data" },
+                                  { NULL, NULL } };
+
+  int ret = sync_env.conn->get_json_resource("/admin/log", pairs, *log_info);
+  if (ret < 0) {
+    ldout(store->ctx(), 0) << "ERROR: failed to fetch datalog info" << dendl;
+    return ret;
+  }
+
+  ldout(store->ctx(), 20) << "remote datalog, num_shards=" << log_info->num_shards << dendl;
+
+  return 0;
+}
+
+int RGWRemoteDataLog::read_source_log_shards_info(map<int, RGWDataChangesLogInfo> *shards_info)
+{
+  rgw_datalog_info log_info;
+  int ret = read_log_info(&log_info);
+  if (ret < 0) {
+    return ret;
+  }
+
+  return run(new RGWReadRemoteDataLogInfoCR(&sync_env, log_info.num_shards, shards_info));
+}
+
+int RGWRemoteDataLog::read_source_log_shards_next(map<int, string> shard_markers, map<int, rgw_datalog_shard_data> *result)
+{
+  if (store->is_meta_master()) {
+    return 0;
+  }
+
+  return run(new RGWListRemoteDataLogCR(&sync_env, shard_markers, 1, result));
+}
+
+int RGWRemoteDataLog::init(const string& _source_zone, RGWRESTConn *_conn, RGWSyncErrorLogger *_error_logger)
+{
+  if (initialized) {
+    return 0;
+  }
+
+  sync_env.init(store->ctx(), store, _conn, async_rados, &http_manager, _error_logger, _source_zone);
+
+  int ret = http_manager.set_threaded();
+  if (ret < 0) {
+    ldout(store->ctx(), 0) << "failed in http_manager.set_threaded() ret=" << ret << dendl;
+    return ret;
+  }
+
+  initialized = true;
+
+  return 0;
+}
+
+void RGWRemoteDataLog::finish()
+{
+  stop();
+}
+
+int RGWRemoteDataLog::get_shard_info(int shard_id)
+{
+  char buf[32];
+  snprintf(buf, sizeof(buf), "%d", shard_id);
+
+  rgw_http_param_pair pairs[] = { { "type", "data" },
+                                  { "id", buf },
+                                  { "info", NULL },
+                                  { NULL, NULL } };
+
+  RGWDataChangesLogInfo info;
+  int ret = sync_env.conn->get_json_resource("/admin/log", pairs, info);
+  if (ret < 0) {
+    ldout(store->ctx(), 0) << "ERROR: failed to fetch datalog info" << dendl;
+    return ret;
+  }
+
+  ldout(store->ctx(), 20) << "remote datalog, shard_id=" << shard_id << " marker=" << info.marker << dendl;
+
+  return 0;
+}
+
+int RGWRemoteDataLog::read_sync_status(rgw_data_sync_status *sync_status)
+{
+  RGWObjectCtx obj_ctx(store, NULL);
+  int r = run(new RGWReadDataSyncStatusCoroutine(&sync_env, obj_ctx, sync_status));
+  if (r == -ENOENT) {
+    r = 0;
+  }
+  return r;
+}
+
+int RGWRemoteDataLog::init_sync_status(int num_shards)
+{
+  RGWObjectCtx obj_ctx(store, NULL);
+  return run(new RGWInitDataSyncStatusCoroutine(&sync_env, obj_ctx, num_shards));
+}
+
+static string full_data_sync_index_shard_oid(const string& source_zone, int shard_id)
+{
+  char buf[datalog_sync_full_sync_index_prefix.size() + 1 + source_zone.size() + 1 + 16];
+  snprintf(buf, sizeof(buf), "%s.%s.%d", datalog_sync_full_sync_index_prefix.c_str(), source_zone.c_str(), shard_id);
+  return string(buf);
+}
+
+struct bucket_instance_meta_info {
+  string key;
+  obj_version ver;
+  time_t mtime;
+  RGWBucketInstanceMetadataObject data;
+
+  bucket_instance_meta_info() : mtime(0) {}
+
+  void decode_json(JSONObj *obj) {
+    JSONDecoder::decode_json("key", key, obj);
+    JSONDecoder::decode_json("ver", ver, obj);
+    JSONDecoder::decode_json("mtime", mtime, obj);
+    JSONDecoder::decode_json("data", data, obj);
+  }
+};
+
+class RGWListBucketIndexesCR : public RGWCoroutine {
+  RGWDataSyncEnv *sync_env;
+
+  RGWRados *store;
+
+  rgw_data_sync_status *sync_status;
+  int num_shards;
+
+  int req_ret;
+  int ret;
+
+  list<string> result;
+  list<string>::iterator iter;
+
+  RGWShardedOmapCRManager *entries_index;
+
+  string oid_prefix;
+
+  string path;
+  bucket_instance_meta_info meta_info;
+  string key;
+  string s;
+  int i;
+
+  bool failed;
+
+public:
+  RGWListBucketIndexesCR(RGWDataSyncEnv *_sync_env,
+                         rgw_data_sync_status *_sync_status) : RGWCoroutine(_sync_env->cct), sync_env(_sync_env),
+                                                      store(sync_env->store), sync_status(_sync_status),
+						      req_ret(0), ret(0), entries_index(NULL), i(0), failed(false) {
+    oid_prefix = datalog_sync_full_sync_index_prefix + "." + sync_env->source_zone; 
+    path = "/admin/metadata/bucket.instance";
+    num_shards = sync_status->sync_info.num_shards;
+  }
+  ~RGWListBucketIndexesCR() {
+    delete entries_index;
+  }
+
+  int operate() {
+    reenter(this) {
+      entries_index = new RGWShardedOmapCRManager(sync_env->async_rados, store, this, num_shards,
+						  store->get_zone_params().log_pool,
+                                                  oid_prefix);
+      yield {
+        string entrypoint = string("/admin/metadata/bucket.instance");
+        /* FIXME: need a better scaling solution here, requires streaming output */
+        call(new RGWReadRESTResourceCR<list<string> >(store->ctx(), sync_env->conn, sync_env->http_manager,
+                                                      entrypoint, NULL, &result));
+      }
+      if (get_ret_status() < 0) {
+        ldout(sync_env->cct, 0) << "ERROR: failed to fetch metadata for section bucket.index" << dendl;
+        return set_state(RGWCoroutine_Error);
+      }
+      for (iter = result.begin(); iter != result.end(); ++iter) {
+        ldout(sync_env->cct, 20) << "list metadata: section=bucket.index key=" << *iter << dendl;
+
+        key = *iter;
+
+        yield {
+          rgw_http_param_pair pairs[] = { { "key", key.c_str() },
+                                          { NULL, NULL } };
+
+          call(new RGWReadRESTResourceCR<bucket_instance_meta_info>(store->ctx(), sync_env->conn, sync_env->http_manager, path, pairs, &meta_info));
+        }
+
+        num_shards = meta_info.data.get_bucket_info().num_shards;
+        if (num_shards > 0) {
+          for (i = 0; i < num_shards; i++) {
+            char buf[16];
+            snprintf(buf, sizeof(buf), ":%d", i);
+            s = key + buf;
+            yield entries_index->append(s, store->data_log->get_log_shard_id(meta_info.data.get_bucket_info().bucket, i));
+          }
+        } else {
+          yield entries_index->append(key, store->data_log->get_log_shard_id(meta_info.data.get_bucket_info().bucket, -1));
+        }
+      }
+      yield {
+        if (!entries_index->finish()) {
+          failed = true;
+        }
+      }
+      if (!failed) {
+        for (map<uint32_t, rgw_data_sync_marker>::iterator iter = sync_status->sync_markers.begin(); iter != sync_status->sync_markers.end(); ++iter) {
+          int shard_id = (int)iter->first;
+          rgw_data_sync_marker& marker = iter->second;
+          marker.total_entries = entries_index->get_total_entries(shard_id);
+          spawn(new RGWSimpleRadosWriteCR<rgw_data_sync_marker>(sync_env->async_rados, store, store->get_zone_params().log_pool,
+                                                                RGWDataSyncStatusManager::shard_obj_name(sync_env->source_zone, shard_id), marker), true);
+        }
+      } else {
+          yield call(sync_env->error_logger->log_error_cr(sync_env->conn->get_remote_id(), "data.init", "",
+                                                          EIO, string("failed to build bucket instances map")));
+      }
+      while (collect(&ret)) {
+	if (ret < 0) {
+          yield call(sync_env->error_logger->log_error_cr(sync_env->conn->get_remote_id(), "data.init", "",
+                                                          -ret, string("failed to store sync status: ") + cpp_strerror(-ret)));
+	  req_ret = ret;
+	}
+        yield;
+      }
+      drain_all();
+      if (req_ret < 0) {
+        yield return set_cr_error(req_ret);
+      }
+      yield return set_cr_done();
+    }
+    return 0;
+  }
+};
+
+#define DATA_SYNC_UPDATE_MARKER_WINDOW 1
+
+class RGWDataSyncShardMarkerTrack : public RGWSyncShardMarkerTrack<string, string> {
+  RGWDataSyncEnv *sync_env;
+
+  string marker_oid;
+  rgw_data_sync_marker sync_marker;
+
+  map<string, string> key_to_marker;
+  map<string, string> marker_to_key;
+
+  void handle_finish(const string& marker) {
+    map<string, string>::iterator iter = marker_to_key.find(marker);
+    if (iter == marker_to_key.end()) {
+      return;
+    }
+    key_to_marker.erase(iter->second);
+    reset_need_retry(iter->second);
+    marker_to_key.erase(iter);
+  }
+
+public:
+  RGWDataSyncShardMarkerTrack(RGWDataSyncEnv *_sync_env,
+                         const string& _marker_oid,
+                         const rgw_data_sync_marker& _marker) : RGWSyncShardMarkerTrack(DATA_SYNC_UPDATE_MARKER_WINDOW),
+                                                                sync_env(_sync_env),
+                                                                marker_oid(_marker_oid),
+                                                                sync_marker(_marker) {}
+
+  RGWCoroutine *store_marker(const string& new_marker, uint64_t index_pos, const real_time& timestamp) {
+    sync_marker.marker = new_marker;
+    sync_marker.pos = index_pos;
+
+    ldout(sync_env->cct, 20) << __func__ << "(): updating marker marker_oid=" << marker_oid << " marker=" << new_marker << dendl;
+    RGWRados *store = sync_env->store;
+
+    return new RGWSimpleRadosWriteCR<rgw_data_sync_marker>(sync_env->async_rados, store, store->get_zone_params().log_pool,
+				 marker_oid, sync_marker);
+  }
+
+  /*
+   * create index from key -> marker, and from marker -> key
+   * this is useful so that we can insure that we only have one
+   * entry for any key that is used. This is needed when doing
+   * incremenatl sync of data, and we don't want to run multiple
+   * concurrent sync operations for the same bucket shard 
+   */
+  bool index_key_to_marker(const string& key, const string& marker) {
+    if (key_to_marker.find(key) != key_to_marker.end()) {
+      set_need_retry(key);
+      return false;
+    }
+    key_to_marker[key] = marker;
+    marker_to_key[marker] = key;
+    return true;
+  }
+};
+
+class RGWRunBucketSyncCoroutine : public RGWCoroutine {
+  RGWDataSyncEnv *sync_env;
+  string bucket_name;
+  string bucket_id;
+  RGWBucketInfo bucket_info;
+  int shard_id;
+  rgw_bucket_shard_sync_info sync_status;
+  RGWMetaSyncEnv meta_sync_env;
+
+public:
+  RGWRunBucketSyncCoroutine(RGWDataSyncEnv *_sync_env,
+                            const string& _bucket_name, const string _bucket_id, int _shard_id) : RGWCoroutine(_sync_env->cct),
+                                                                            sync_env(_sync_env),
+                                                                            bucket_name(_bucket_name),
+									    bucket_id(_bucket_id), shard_id(_shard_id) {}
+
+  int operate();
+};
+
+static int parse_bucket_shard(CephContext *cct, const string& raw_key, string *bucket_name, string *bucket_instance, int *shard_id)
+{
+  ssize_t pos = raw_key.find(':');
+  *bucket_name = raw_key.substr(0, pos);
+  *bucket_instance = raw_key.substr(pos + 1);
+  pos = bucket_instance->find(':');
+  *shard_id = -1;
+  if (pos >= 0) {
+    string err;
+    string s = bucket_instance->substr(pos + 1);
+    *shard_id = strict_strtol(s.c_str(), 10, &err);
+    if (!err.empty()) {
+      ldout(cct, 0) << "ERROR: failed to parse bucket instance key: " << *bucket_instance << dendl;
+      return -EINVAL;
+    }
+
+    *bucket_instance = bucket_instance->substr(0, pos);
+  }
+  return 0;
+}
+
+class RGWDataSyncSingleEntryCR : public RGWCoroutine {
+  RGWDataSyncEnv *sync_env;
+
+  string raw_key;
+  string entry_marker;
+
+  string bucket_name;
+  string bucket_instance;
+
+  int sync_status;
+
+  bufferlist md_bl;
+
+  RGWDataSyncShardMarkerTrack *marker_tracker;
+
+public:
+  RGWDataSyncSingleEntryCR(RGWDataSyncEnv *_sync_env,
+		           const string& _raw_key, const string& _entry_marker, RGWDataSyncShardMarkerTrack *_marker_tracker) : RGWCoroutine(_sync_env->cct),
+                                                      sync_env(_sync_env),
+						      raw_key(_raw_key), entry_marker(_entry_marker),
+                                                      sync_status(0),
+                                                      marker_tracker(_marker_tracker) {
+    set_description() << "data sync single entry (source_zone=" << sync_env->source_zone << ") key=" <<_raw_key << " entry=" << entry_marker;
+  }
+
+  int operate() {
+    reenter(this) {
+      do {
+        yield {
+          int shard_id;
+          int ret = parse_bucket_shard(sync_env->cct, raw_key, &bucket_name, &bucket_instance, &shard_id);
+          if (ret < 0) {
+            return set_cr_error(-EIO);
+          }
+          marker_tracker->reset_need_retry(raw_key);
+          call(new RGWRunBucketSyncCoroutine(sync_env, bucket_name, bucket_instance, shard_id));
+        }
+      } while (marker_tracker->need_retry(raw_key));
+
+      sync_status = retcode;
+
+      if (sync_status < 0) {
+        yield call(sync_env->error_logger->log_error_cr(sync_env->conn->get_remote_id(), "data", bucket_name + ":" + bucket_instance,
+                                                        -sync_status, string("failed to sync bucket instance: ") + cpp_strerror(-sync_status)));
+      }
+      /* FIXME: what do do in case of error */
+      if (!entry_marker.empty()) {
+        /* update marker */
+        yield call(marker_tracker->finish(entry_marker));
+      }
+      if (sync_status == 0) {
+        sync_status = retcode;
+      }
+      if (sync_status < 0) {
+        return set_cr_error(sync_status);
+      }
+      return set_cr_done();
+    }
+    return 0;
+  }
+};
+
+#define BUCKET_SHARD_SYNC_SPAWN_WINDOW 20
+
+class RGWDataSyncShardCR : public RGWCoroutine {
+  RGWDataSyncEnv *sync_env;
+
+  rgw_bucket pool;
+
+  uint32_t shard_id;
+  rgw_data_sync_marker sync_marker;
+
+  map<string, bufferlist> entries;
+  map<string, bufferlist>::iterator iter;
+
+  string oid;
+
+  RGWDataSyncShardMarkerTrack *marker_tracker;
+
+  list<rgw_data_change_log_entry> log_entries;
+  list<rgw_data_change_log_entry>::iterator log_iter;
+  bool truncated;
+
+  RGWDataChangesLogInfo shard_info;
+  string datalog_marker;
+
+  Mutex inc_lock;
+  Cond inc_cond;
+
+  boost::asio::coroutine incremental_cr;
+  boost::asio::coroutine full_cr;
+
+
+  set<string> modified_shards;
+  set<string> current_modified;
+
+  set<string>::iterator modified_iter;
+
+  int total_entries;
+
+  int spawn_window;
+
+  bool *reset_backoff;
+
+  set<string> spawned_keys;
+
+  RGWContinuousLeaseCR *lease_cr;
+  string status_oid;
+public:
+  RGWDataSyncShardCR(RGWDataSyncEnv *_sync_env,
+                     rgw_bucket& _pool,
+		     uint32_t _shard_id, rgw_data_sync_marker& _marker, bool *_reset_backoff) : RGWCoroutine(_sync_env->cct),
+                                                      sync_env(_sync_env),
+						      pool(_pool),
+						      shard_id(_shard_id),
+						      sync_marker(_marker),
+                                                      marker_tracker(NULL), truncated(false), inc_lock("RGWDataSyncShardCR::inc_lock"),
+                                                      total_entries(0), spawn_window(BUCKET_SHARD_SYNC_SPAWN_WINDOW), reset_backoff(NULL),
+                                                      lease_cr(NULL) {
+    set_description() << "data sync shard source_zone=" << sync_env->source_zone << " shard_id=" << shard_id;
+    status_oid = RGWDataSyncStatusManager::shard_obj_name(sync_env->source_zone, shard_id);
+  }
+
+  ~RGWDataSyncShardCR() {
+    delete marker_tracker;
+    if (lease_cr) {
+      lease_cr->abort();
+      lease_cr->put();
+    }
+  }
+
+  void append_modified_shards(set<string>& keys) {
+    Mutex::Locker l(inc_lock);
+    modified_shards.insert(keys.begin(), keys.end());
+  }
+
+  void set_marker_tracker(RGWDataSyncShardMarkerTrack *mt) {
+    delete marker_tracker;
+    marker_tracker = mt;
+  }
+
+  int operate() {
+    int r;
+    while (true) {
+      switch (sync_marker.state) {
+      case rgw_data_sync_marker::FullSync:
+        r = full_sync();
+        if (r < 0) {
+          ldout(cct, 10) << "sync: full_sync: shard_id=" << shard_id << " r=" << r << dendl;
+          return set_cr_error(r);
+        }
+        return 0;
+      case rgw_data_sync_marker::IncrementalSync:
+        r  = incremental_sync();
+        if (r < 0) {
+          ldout(cct, 10) << "sync: incremental_sync: shard_id=" << shard_id << " r=" << r << dendl;
+          return set_cr_error(r);
+        }
+        return 0;
+      default:
+        return set_cr_error(-EIO);
+      }
+    }
+    return 0;
+  }
+
+  void init_lease_cr() {
+    set_status("acquiring sync lock");
+    uint32_t lock_duration = cct->_conf->rgw_sync_lease_period;
+    string lock_name = "sync_lock";
+    if (lease_cr) {
+      lease_cr->abort();
+      lease_cr->put();
+    }
+    RGWRados *store = sync_env->store;
+    lease_cr = new RGWContinuousLeaseCR(sync_env->async_rados, store, store->get_zone_params().log_pool, status_oid,
+                                        lock_name, lock_duration, this);
+    lease_cr->get();
+    spawn(lease_cr, false);
+  }
+
+  int full_sync() {
+#define OMAP_GET_MAX_ENTRIES 100
+    int max_entries = OMAP_GET_MAX_ENTRIES;
+    reenter(&full_cr) {
+      yield init_lease_cr();
+      while (!lease_cr->is_locked()) {
+        if (lease_cr->is_done()) {
+          ldout(cct, 0) << "ERROR: lease cr failed, done early " << dendl;
+          set_status("lease lock failed, early abort");
+          return set_cr_error(lease_cr->get_ret_status());
+        }
+        set_sleeping(true);
+        yield;
+      }
+      oid = full_data_sync_index_shard_oid(sync_env->source_zone, shard_id);
+      set_marker_tracker(new RGWDataSyncShardMarkerTrack(sync_env, status_oid, sync_marker));
+      total_entries = sync_marker.pos;
+      do {
+        yield call(new RGWRadosGetOmapKeysCR(sync_env->store, pool, oid, sync_marker.marker, &entries, max_entries));
+        if (retcode < 0) {
+          ldout(sync_env->cct, 0) << "ERROR: " << __func__ << "(): RGWRadosGetOmapKeysCR() returned ret=" << retcode << dendl;
+          lease_cr->go_down();
+          drain_all();
+          return set_cr_error(retcode);
+        }
+        iter = entries.begin();
+        for (; iter != entries.end(); ++iter) {
+          ldout(sync_env->cct, 20) << __func__ << ": full sync: " << iter->first << dendl;
+          total_entries++;
+          if (!marker_tracker->start(iter->first, total_entries, real_time())) {
+            ldout(sync_env->cct, 0) << "ERROR: cannot start syncing " << iter->first << ". Duplicate entry?" << dendl;
+          } else {
+            // fetch remote and write locally
+            yield spawn(new RGWDataSyncSingleEntryCR(sync_env, iter->first, iter->first, marker_tracker), false);
+            if (retcode < 0) {
+              lease_cr->go_down();
+              drain_all();
+              return set_cr_error(retcode);
+            }
+          }
+          sync_marker.marker = iter->first;
+        }
+      } while ((int)entries.size() == max_entries);
+
+      lease_cr->go_down();
+      drain_all();
+
+      yield {
+        /* update marker to reflect we're done with full sync */
+        sync_marker.state = rgw_data_sync_marker::IncrementalSync;
+        sync_marker.marker = sync_marker.next_step_marker;
+        sync_marker.next_step_marker.clear();
+        RGWRados *store = sync_env->store;
+        call(new RGWSimpleRadosWriteCR<rgw_data_sync_marker>(sync_env->async_rados, store, store->get_zone_params().log_pool,
+                                                             status_oid, sync_marker));
+      }
+      if (retcode < 0) {
+        ldout(sync_env->cct, 0) << "ERROR: failed to set sync marker: retcode=" << retcode << dendl;
+        lease_cr->go_down();
+        return set_cr_error(retcode);
+      }
+    }
+    return 0;
+  }
+
+  int incremental_sync() {
+    reenter(&incremental_cr) {
+      yield init_lease_cr();
+      while (!lease_cr->is_locked()) {
+        if (lease_cr->is_done()) {
+          ldout(cct, 0) << "ERROR: lease cr failed, done early " << dendl;
+          set_status("lease lock failed, early abort");
+          return set_cr_error(lease_cr->get_ret_status());
+        }
+        set_sleeping(true);
+        yield;
+      }
+      set_status("lease acquired");
+      set_marker_tracker(new RGWDataSyncShardMarkerTrack(sync_env, status_oid, sync_marker));
+      do {
+        current_modified.clear();
+        inc_lock.Lock();
+        current_modified.swap(modified_shards);
+        inc_lock.Unlock();
+
+        /* process out of band updates */
+        for (modified_iter = current_modified.begin(); modified_iter != current_modified.end(); ++modified_iter) {
+          yield {
+            ldout(sync_env->cct, 20) << __func__ << "(): async update notification: " << *modified_iter << dendl;
+            spawn(new RGWDataSyncSingleEntryCR(sync_env, *modified_iter, string(), marker_tracker), false);
+          }
+        }
+
+        yield call(new RGWReadRemoteDataLogShardInfoCR(sync_env, shard_id, &shard_info));
+        if (retcode < 0) {
+          ldout(sync_env->cct, 0) << "ERROR: failed to fetch remote data log info: ret=" << retcode << dendl;
+          lease_cr->go_down();
+          drain_all();
+          return set_cr_error(retcode);
+        }
+        datalog_marker = shard_info.marker;
+#define INCREMENTAL_MAX_ENTRIES 100
+	ldout(sync_env->cct, 20) << __func__ << ":" << __LINE__ << ": shard_id=" << shard_id << " datalog_marker=" << datalog_marker << " sync_marker.marker=" << sync_marker.marker << dendl;
+	if (datalog_marker > sync_marker.marker) {
+          spawned_keys.clear();
+          yield call(new RGWReadRemoteDataLogShardCR(sync_env, shard_id, &sync_marker.marker, &log_entries, &truncated));
+          if (retcode < 0) {
+            ldout(sync_env->cct, 0) << "ERROR: failed to read remote data log info: ret=" << retcode << dendl;
+            lease_cr->go_down();
+            drain_all();
+            return set_cr_error(retcode);
+          }
+          for (log_iter = log_entries.begin(); log_iter != log_entries.end(); ++log_iter) {
+            ldout(sync_env->cct, 20) << __func__ << ":" << __LINE__ << ": shard_id=" << shard_id << " log_entry: " << log_iter->log_id << ":" << log_iter->log_timestamp << ":" << log_iter->entry.key << dendl;
+            if (!marker_tracker->index_key_to_marker(log_iter->entry.key, log_iter->log_id)) {
+              ldout(sync_env->cct, 20) << __func__ << ": skipping sync of entry: " << log_iter->log_id << ":" << log_iter->entry.key << " sync already in progress for bucket shard" << dendl;
+              marker_tracker->try_update_high_marker(log_iter->log_id, 0, log_iter->log_timestamp);
+              continue;
+            }
+            if (!marker_tracker->start(log_iter->log_id, 0, log_iter->log_timestamp)) {
+              ldout(sync_env->cct, 0) << "ERROR: cannot start syncing " << log_iter->log_id << ". Duplicate entry?" << dendl;
+            } else {
+              /*
+               * don't spawn the same key more than once. We can do that as long as we don't yield
+               */
+              if (spawned_keys.find(log_iter->entry.key) == spawned_keys.end()) {
+                spawned_keys.insert(log_iter->entry.key);
+                spawn(new RGWDataSyncSingleEntryCR(sync_env, log_iter->entry.key, log_iter->log_id, marker_tracker), false);
+                if (retcode < 0) {
+                  lease_cr->go_down();
+                  drain_all();
+                  return set_cr_error(retcode);
+                }
+              }
+            }
+	  }
+          while ((int)num_spawned() > spawn_window) {
+            set_status() << "num_spawned() > spawn_window";
+            yield wait_for_child();
+            int ret;
+            while (collect(&ret)) {
+              if (ret < 0) {
+                ldout(sync_env->cct, 0) << "ERROR: a sync operation returned error" << dendl;
+                /* we have reported this error */
+              }
+              /* not waiting for child here */
+            }
+          }
+	}
+	ldout(sync_env->cct, 20) << __func__ << ":" << __LINE__ << ": shard_id=" << shard_id << " datalog_marker=" << datalog_marker << " sync_marker.marker=" << sync_marker.marker << dendl;
+	if (datalog_marker == sync_marker.marker) {
+#define INCREMENTAL_INTERVAL 20
+	  yield wait(utime_t(INCREMENTAL_INTERVAL, 0));
+	}
+      } while (true);
+    }
+    return 0;
+  }
+};
+
+class RGWDataSyncShardControlCR : public RGWBackoffControlCR {
+  RGWDataSyncEnv *sync_env;
+
+  rgw_bucket pool;
+
+  uint32_t shard_id;
+  rgw_data_sync_marker sync_marker;
+
+public:
+  RGWDataSyncShardControlCR(RGWDataSyncEnv *_sync_env, rgw_bucket& _pool,
+		     uint32_t _shard_id, rgw_data_sync_marker& _marker) : RGWBackoffControlCR(_sync_env->cct, false),
+                                                      sync_env(_sync_env),
+						      pool(_pool),
+						      shard_id(_shard_id),
+						      sync_marker(_marker) {
+  }
+
+  RGWCoroutine *alloc_cr() {
+    return new RGWDataSyncShardCR(sync_env, pool, shard_id, sync_marker, backoff_ptr());
+  }
+
+  RGWCoroutine *alloc_finisher_cr() {
+    RGWRados *store = sync_env->store;
+    RGWObjectCtx obj_ctx(store, NULL);
+    return new RGWSimpleRadosReadCR<rgw_data_sync_marker>(sync_env->async_rados, store, obj_ctx, store->get_zone_params().log_pool,
+                                                    RGWDataSyncStatusManager::shard_obj_name(sync_env->source_zone, shard_id), &sync_marker);
+  }
+
+  void append_modified_shards(set<string>& keys) {
+    Mutex::Locker l(cr_lock());
+
+    RGWDataSyncShardCR *cr = static_cast<RGWDataSyncShardCR *>(get_cr());
+    if (!cr) {
+      return;
+    }
+
+    cr->append_modified_shards(keys);
+  }
+};
+
+class RGWDataSyncCR : public RGWCoroutine {
+  RGWDataSyncEnv *sync_env;
+  uint32_t num_shards;
+
+  RGWObjectCtx obj_ctx;
+
+  rgw_data_sync_status sync_status;
+
+  RGWDataSyncShardMarkerTrack *marker_tracker;
+
+  Mutex shard_crs_lock;
+  map<int, RGWDataSyncShardControlCR *> shard_crs;
+
+  bool *reset_backoff;
+
+public:
+  RGWDataSyncCR(RGWDataSyncEnv *_sync_env, uint32_t _num_shards, bool *_reset_backoff) : RGWCoroutine(_sync_env->cct),
+                                                      sync_env(_sync_env),
+                                                      num_shards(_num_shards),
+                                                      obj_ctx(sync_env->store),
+                                                      marker_tracker(NULL),
+                                                      shard_crs_lock("RGWDataSyncCR::shard_crs_lock"),
+                                                      reset_backoff(_reset_backoff) {
+  }
+
+  ~RGWDataSyncCR() {
+    for (auto iter : shard_crs) {
+      iter.second->put();
+    }
+  }
+
+  int operate() {
+    reenter(this) {
+
+      /* read sync status */
+      yield call(new RGWReadDataSyncStatusCoroutine(sync_env, obj_ctx, &sync_status));
+
+      if (retcode == -ENOENT) {
+        sync_status.sync_info.num_shards = num_shards;
+      } else if (retcode < 0 && retcode != -ENOENT) {
+        ldout(sync_env->cct, 0) << "ERROR: failed to fetch sync status, retcode=" << retcode << dendl;
+        return set_cr_error(retcode);
+      }
+
+      /* state: init status */
+      if ((rgw_data_sync_info::SyncState)sync_status.sync_info.state == rgw_data_sync_info::StateInit) {
+        ldout(sync_env->cct, 20) << __func__ << "(): init" << dendl;
+        yield call(new RGWInitDataSyncStatusCoroutine(sync_env, obj_ctx, sync_status.sync_info.num_shards));
+        if (retcode < 0) {
+          ldout(sync_env->cct, 0) << "ERROR: failed to init sync, retcode=" << retcode << dendl;
+          return set_cr_error(retcode);
+        }
+        sync_status.sync_info.num_shards = num_shards;
+        sync_status.sync_info.state = rgw_data_sync_info::StateBuildingFullSyncMaps;
+        /* update new state */
+        yield call(set_sync_info_cr());
+
+        if (retcode < 0) {
+          ldout(sync_env->cct, 0) << "ERROR: failed to write sync status, retcode=" << retcode << dendl;
+          return set_cr_error(retcode);
+        }
+
+        *reset_backoff = true;
+      }
+
+      if  ((rgw_data_sync_info::SyncState)sync_status.sync_info.state == rgw_data_sync_info::StateBuildingFullSyncMaps) {
+        /* state: building full sync maps */
+        ldout(sync_env->cct, 20) << __func__ << "(): building full sync maps" << dendl;
+        yield call(new RGWListBucketIndexesCR(sync_env, &sync_status));
+        sync_status.sync_info.state = rgw_data_sync_info::StateSync;
+
+        /* update new state */
+        yield call(set_sync_info_cr());
+        if (retcode < 0) {
+          ldout(sync_env->cct, 0) << "ERROR: failed to write sync status, retcode=" << retcode << dendl;
+          return set_cr_error(retcode);
+        }
+
+        *reset_backoff = true;
+      }
+
+      yield {
+        if  ((rgw_data_sync_info::SyncState)sync_status.sync_info.state == rgw_data_sync_info::StateSync) {
+          case rgw_data_sync_info::StateSync:
+            for (map<uint32_t, rgw_data_sync_marker>::iterator iter = sync_status.sync_markers.begin();
+                 iter != sync_status.sync_markers.end(); ++iter) {
+              RGWDataSyncShardControlCR *cr = new RGWDataSyncShardControlCR(sync_env, sync_env->store->get_zone_params().log_pool,
+                                                        iter->first, iter->second);
+              cr->get();
+              shard_crs_lock.Lock();
+              shard_crs[iter->first] = cr;
+              shard_crs_lock.Unlock();
+              spawn(cr, true);
+            }
+        }
+      }
+
+      return set_cr_done();
+    }
+    return 0;
+  }
+
+  RGWCoroutine *set_sync_info_cr() {
+    RGWRados *store = sync_env->store;
+    return new RGWSimpleRadosWriteCR<rgw_data_sync_info>(sync_env->async_rados, store, store->get_zone_params().log_pool,
+                                                         RGWDataSyncStatusManager::sync_status_oid(sync_env->source_zone),
+                                                         sync_status.sync_info);
+  }
+
+  void wakeup(int shard_id, set<string>& keys) {
+    Mutex::Locker l(shard_crs_lock);
+    map<int, RGWDataSyncShardControlCR *>::iterator iter = shard_crs.find(shard_id);
+    if (iter == shard_crs.end()) {
+      return;
+    }
+    iter->second->append_modified_shards(keys);
+    iter->second->wakeup();
+  }
+};
+
+class RGWDataSyncControlCR : public RGWBackoffControlCR
+{
+  RGWDataSyncEnv *sync_env;
+  uint32_t num_shards;
+
+public:
+  RGWDataSyncControlCR(RGWDataSyncEnv *_sync_env, uint32_t _num_shards) : RGWBackoffControlCR(_sync_env->cct, true),
+                                                      sync_env(_sync_env), num_shards(_num_shards) {
+  }
+
+  RGWCoroutine *alloc_cr() {
+    return new RGWDataSyncCR(sync_env, num_shards, backoff_ptr());
+  }
+
+  void wakeup(int shard_id, set<string>& keys) {
+    Mutex& m = cr_lock();
+
+    m.Lock();
+    RGWDataSyncCR *cr = static_cast<RGWDataSyncCR *>(get_cr());
+    if (!cr) {
+      m.Unlock();
+      return;
+    }
+
+    cr->get();
+    m.Unlock();
+
+    if (cr) {
+      cr->wakeup(shard_id, keys);
+    }
+
+    cr->put();
+  }
+};
+
+void RGWRemoteDataLog::wakeup(int shard_id, set<string>& keys) {
+  RWLock::RLocker rl(lock);
+  if (!data_sync_cr) {
+    return;
+  }
+  data_sync_cr->wakeup(shard_id, keys);
+}
+
+int RGWRemoteDataLog::run_sync(int num_shards, rgw_data_sync_status& sync_status)
+{
+  RGWObjectCtx obj_ctx(store, NULL);
+
+  int r = run(new RGWReadDataSyncStatusCoroutine(&sync_env, obj_ctx, &sync_status));
+  if (r < 0 && r != -ENOENT) {
+    ldout(store->ctx(), 0) << "ERROR: failed to read sync status from source_zone=" << sync_env.source_zone << " r=" << r << dendl;
+    return r;
+  }
+  
+  lock.get_write();
+  data_sync_cr = new RGWDataSyncControlCR(&sync_env, num_shards);
+  lock.unlock();
+  r = run(data_sync_cr);
+  if (r < 0) {
+    ldout(store->ctx(), 0) << "ERROR: failed to run sync" << dendl;
+    return r;
+  }
+
+  lock.get_write();
+  data_sync_cr = NULL;
+  lock.unlock();
+
+  return 0;
+}
+
+int RGWDataSyncStatusManager::init()
+{
+  conn = store->get_zone_conn_by_id(source_zone);
+  if (!conn) {
+    ldout(store->ctx(), 0) << "connection object to zone " << source_zone << " does not exist" << dendl;
+    return -EINVAL;
+  }
+
+  const char *log_pool = store->get_zone_params().log_pool.name.c_str();
+  librados::Rados *rados = store->get_rados_handle();
+  int r = rados->ioctx_create(log_pool, ioctx);
+  if (r < 0) {
+    lderr(store->ctx()) << "ERROR: failed to open log pool (" << store->get_zone_params().log_pool.name << " ret=" << r << dendl;
+    return r;
+  }
+
+  source_status_obj = rgw_obj(store->get_zone_params().log_pool, RGWDataSyncStatusManager::sync_status_oid(source_zone));
+
+  error_logger = new RGWSyncErrorLogger(store, RGW_SYNC_ERROR_LOG_SHARD_PREFIX, ERROR_LOGGER_SHARDS);
+
+  r = source_log.init(source_zone, conn, error_logger);
+  if (r < 0) {
+    lderr(store->ctx()) << "ERROR: failed to init remote log, r=" << r << dendl;
+    return r;
+  }
+
+  rgw_datalog_info datalog_info;
+  r = source_log.read_log_info(&datalog_info);
+  if (r < 0) {
+    ldout(store->ctx(), 5) << "ERROR: master.read_log_info() returned r=" << r << dendl;
+    return r;
+  }
+
+  num_shards = datalog_info.num_shards;
+
+  for (int i = 0; i < num_shards; i++) {
+    shard_objs[i] = rgw_obj(store->get_zone_params().log_pool, shard_obj_name(source_zone, i));
+  }
+
+  return 0;
+}
+
+string RGWDataSyncStatusManager::sync_status_oid(const string& source_zone)
+{
+  char buf[datalog_sync_status_oid_prefix.size() + source_zone.size() + 16];
+  snprintf(buf, sizeof(buf), "%s.%s", datalog_sync_status_oid_prefix.c_str(), source_zone.c_str());
+
+  return string(buf);
+}
+
+string RGWDataSyncStatusManager::shard_obj_name(const string& source_zone, int shard_id)
+{
+  char buf[datalog_sync_status_shard_prefix.size() + source_zone.size() + 16];
+  snprintf(buf, sizeof(buf), "%s.%s.%d", datalog_sync_status_shard_prefix.c_str(), source_zone.c_str(), shard_id);
+
+  return string(buf);
+}
+
+int RGWRemoteBucketLog::init(const string& _source_zone, RGWRESTConn *_conn, const string& _bucket_name,
+                             const string& _bucket_id, int _shard_id, RGWSyncErrorLogger *_error_logger)
+{
+  conn = _conn;
+  source_zone = _source_zone;
+  bucket_name = _bucket_name;
+  bucket_id = _bucket_id;
+  shard_id = _shard_id;
+
+  sync_env.init(store->ctx(), store, conn, async_rados, http_manager, _error_logger, source_zone);
+
+  return 0;
+}
+
+struct bucket_index_marker_info {
+  string bucket_ver;
+  string master_ver;
+  string max_marker;
+
+  void decode_json(JSONObj *obj) {
+    JSONDecoder::decode_json("bucket_ver", bucket_ver, obj);
+    JSONDecoder::decode_json("master_ver", master_ver, obj);
+    JSONDecoder::decode_json("max_marker", max_marker, obj);
+  }
+};
+
+class RGWReadRemoteBucketIndexLogInfoCR : public RGWCoroutine {
+  RGWDataSyncEnv *sync_env;
+
+  string bucket_name;
+  string bucket_id;
+  int shard_id;
+
+  string instance_key;
+
+  bucket_index_marker_info *info;
+
+public:
+  RGWReadRemoteBucketIndexLogInfoCR(RGWDataSyncEnv *_sync_env,
+                                  const string& _bucket_name, const string& _bucket_id, int _shard_id,
+                                  bucket_index_marker_info *_info) : RGWCoroutine(_sync_env->cct), sync_env(_sync_env),
+                                                      bucket_name(_bucket_name), bucket_id(_bucket_id), shard_id(_shard_id),
+                                                      info(_info) {
+    instance_key = bucket_name + ":" + bucket_id;
+    if (shard_id >= 0) {
+      char buf[16];
+      snprintf(buf, sizeof(buf), ":%d", shard_id);
+      instance_key.append(buf);
+    }
+  }
+
+  int operate() {
+    reenter(this) {
+      yield {
+        rgw_http_param_pair pairs[] = { { "type" , "bucket-index" },
+	                                { "bucket-instance", instance_key.c_str() },
+					{ "info" , NULL },
+	                                { NULL, NULL } };
+
+        string p = "/admin/log/";
+        call(new RGWReadRESTResourceCR<bucket_index_marker_info>(sync_env->cct, sync_env->conn, sync_env->http_manager, p, pairs, info));
+      }
+      if (retcode < 0) {
+        return set_cr_error(retcode);
+      }
+      return set_cr_done();
+    }
+    return 0;
+  }
+};
+
+class RGWInitBucketShardSyncStatusCoroutine : public RGWCoroutine {
+  RGWDataSyncEnv *sync_env;
+  RGWRados *store;
+
+  string bucket_name;
+  string bucket_id;
+  int shard_id;
+
+  string sync_status_oid;
+
+  string lock_name;
+  string cookie;
+  rgw_bucket_shard_sync_info status;
+
+  bucket_index_marker_info info;
+public:
+  RGWInitBucketShardSyncStatusCoroutine(RGWDataSyncEnv *_sync_env,
+                      const string& _bucket_name, const string& _bucket_id, int _shard_id) : RGWCoroutine(_sync_env->cct), sync_env(_sync_env),
+                                                                                             bucket_name(_bucket_name), bucket_id(_bucket_id), shard_id(_shard_id) {
+    store = sync_env->store;
+    lock_name = "sync_lock";
+
+#define COOKIE_LEN 16
+    char buf[COOKIE_LEN + 1];
+
+    gen_rand_alphanumeric(cct, buf, sizeof(buf) - 1);
+    string cookie = buf;
+
+    sync_status_oid = RGWBucketSyncStatusManager::status_oid(sync_env->source_zone, bucket_name, bucket_id, shard_id);
+  }
+
+  int operate() {
+    reenter(this) {
+      yield {
+	uint32_t lock_duration = 30;
+	call(new RGWSimpleRadosLockCR(sync_env->async_rados, store, store->get_zone_params().log_pool, sync_status_oid,
+			             lock_name, cookie, lock_duration));
+	if (retcode < 0) {
+	  ldout(cct, 0) << "ERROR: failed to take a lock on " << sync_status_oid << dendl;
+	  return set_cr_error(retcode);
+	}
+      }
+      yield call(new RGWSimpleRadosWriteCR<rgw_bucket_shard_sync_info>(sync_env->async_rados, store, store->get_zone_params().log_pool,
+				 sync_status_oid, status));
+      yield { /* take lock again, we just recreated the object */
+	uint32_t lock_duration = 30;
+	call(new RGWSimpleRadosLockCR(sync_env->async_rados, store, store->get_zone_params().log_pool, sync_status_oid,
+			             lock_name, cookie, lock_duration));
+	if (retcode < 0) {
+	  ldout(cct, 0) << "ERROR: failed to take a lock on " << sync_status_oid << dendl;
+	  return set_cr_error(retcode);
+	}
+      }
+      /* fetch current position in logs */
+      yield call(new RGWReadRemoteBucketIndexLogInfoCR(sync_env, bucket_name, bucket_id, shard_id, &info));
+      if (retcode < 0 && retcode != -ENOENT) {
+        ldout(cct, 0) << "ERROR: failed to fetch bucket index status" << dendl;
+        return set_cr_error(retcode);
+      }
+      yield {
+	status.state = rgw_bucket_shard_sync_info::StateFullSync;
+        status.inc_marker.position = info.max_marker;
+        map<string, bufferlist> attrs;
+        status.encode_all_attrs(attrs);
+        call(new RGWSimpleRadosWriteAttrsCR(sync_env->async_rados, store, store->get_zone_params().log_pool,
+                                            sync_status_oid, attrs));
+      }
+      yield { /* unlock */
+	call(new RGWSimpleRadosUnlockCR(sync_env->async_rados, store, store->get_zone_params().log_pool, sync_status_oid,
+			             lock_name, cookie));
+      }
+      return set_cr_done();
+    }
+    return 0;
+  }
+};
+
+RGWCoroutine *RGWRemoteBucketLog::init_sync_status_cr()
+{
+  return new RGWInitBucketShardSyncStatusCoroutine(&sync_env,
+                                                   bucket_name, bucket_id, shard_id);
+}
+
+template <class T>
+static void decode_attr(CephContext *cct, map<string, bufferlist>& attrs, const string& attr_name, T *val)
+{
+  map<string, bufferlist>::iterator iter = attrs.find(attr_name);
+  if (iter == attrs.end()) {
+    *val = T();
+    return;
+  }
+
+  bufferlist::iterator biter = iter->second.begin();
+  try {
+    ::decode(*val, biter);
+  } catch (buffer::error& err) {
+    ldout(cct, 0) << "ERROR: failed to decode attribute: " << attr_name << dendl;
+  }
+}
+
+void rgw_bucket_shard_sync_info::decode_from_attrs(CephContext *cct, map<string, bufferlist>& attrs)
+{
+  decode_attr(cct, attrs, "state", &state);
+  decode_attr(cct, attrs, "full_marker", &full_marker);
+  decode_attr(cct, attrs, "inc_marker", &inc_marker);
+}
+
+void rgw_bucket_shard_sync_info::encode_all_attrs(map<string, bufferlist>& attrs)
+{
+  encode_state_attr(attrs);
+  full_marker.encode_attr(attrs);
+  inc_marker.encode_attr(attrs);
+}
+
+void rgw_bucket_shard_sync_info::encode_state_attr(map<string, bufferlist>& attrs)
+{
+  ::encode(state, attrs["state"]);
+}
+
+void rgw_bucket_shard_full_sync_marker::encode_attr(map<string, bufferlist>& attrs)
+{
+  ::encode(*this, attrs["full_marker"]);
+}
+
+void rgw_bucket_shard_inc_sync_marker::encode_attr(map<string, bufferlist>& attrs)
+{
+  ::encode(*this, attrs["inc_marker"]);
+}
+
+class RGWReadBucketSyncStatusCoroutine : public RGWCoroutine {
+  RGWDataSyncEnv *sync_env;
+  RGWObjectCtx obj_ctx;
+  string oid;
+  rgw_bucket_shard_sync_info *status;
+
+  map<string, bufferlist> attrs;
+public:
+  RGWReadBucketSyncStatusCoroutine(RGWDataSyncEnv *_sync_env,
+                      const string& _bucket_name, const string _bucket_id, int _shard_id,
+		      rgw_bucket_shard_sync_info *_status) : RGWCoroutine(_sync_env->cct),
+                                                            sync_env(_sync_env),
+                                                            obj_ctx(sync_env->store),
+                                                            oid(RGWBucketSyncStatusManager::status_oid(sync_env->source_zone, _bucket_name, _bucket_id, _shard_id)),
+                                                            status(_status) {}
+  int operate();
+};
+
+int RGWReadBucketSyncStatusCoroutine::operate()
+{
+  reenter(this) {
+    yield call(new RGWSimpleRadosReadAttrsCR(sync_env->async_rados, sync_env->store, obj_ctx,
+                                                   sync_env->store->get_zone_params().log_pool,
+                                                   oid,
+                                                   &attrs));
+    if (retcode == -ENOENT) {
+      *status = rgw_bucket_shard_sync_info();
+      return set_cr_done();
+    }
+    if (retcode < 0) {
+      ldout(sync_env->cct, 0) << "ERROR: failed to call fetch bucket shard info oid=" << oid << " ret=" << retcode << dendl;
+      return set_cr_error(retcode);
+    }
+    status->decode_from_attrs(sync_env->cct, attrs);
+    return set_cr_done();
+  }
+  return 0;
+}
+RGWCoroutine *RGWRemoteBucketLog::read_sync_status_cr(rgw_bucket_shard_sync_info *sync_status)
+{
+  return new RGWReadBucketSyncStatusCoroutine(&sync_env, bucket_name, bucket_id, shard_id, sync_status);
+}
+
+RGWBucketSyncStatusManager::~RGWBucketSyncStatusManager() {
+  for (map<int, RGWRemoteBucketLog *>::iterator iter = source_logs.begin(); iter != source_logs.end(); ++iter) {
+    delete iter->second;
+  }
+  delete error_logger;
+}
+
+
+struct bucket_entry_owner {
+  string id;
+  string display_name;
+
+  bucket_entry_owner() {}
+  bucket_entry_owner(const string& _id, const string& _display_name) : id(_id), display_name(_display_name) {}
+
+  void decode_json(JSONObj *obj) {
+    JSONDecoder::decode_json("ID", id, obj);
+    JSONDecoder::decode_json("DisplayName", display_name, obj);
+  }
+};
+
+struct bucket_list_entry {
+  bool delete_marker;
+  rgw_obj_key key;
+  bool is_latest;
+  real_time mtime;
+  string etag;
+  uint64_t size;
+  string storage_class;
+  bucket_entry_owner owner;
+  uint64_t versioned_epoch;
+  string rgw_tag;
+
+  bucket_list_entry() : delete_marker(false), is_latest(false), size(0), versioned_epoch(0) {}
+
+  void decode_json(JSONObj *obj) {
+    JSONDecoder::decode_json("IsDeleteMarker", delete_marker, obj);
+    JSONDecoder::decode_json("Key", key.name, obj);
+    JSONDecoder::decode_json("VersionId", key.instance, obj);
+    JSONDecoder::decode_json("IsLatest", is_latest, obj);
+    string mtime_str;
+    JSONDecoder::decode_json("RgwxMtime", mtime_str, obj);
+
+    struct tm t;
+    uint32_t nsec;
+    if (parse_iso8601(mtime_str.c_str(), &t, &nsec)) {
+      ceph_timespec ts;
+      ts.tv_sec = (uint64_t)timegm(&t);
+      ts.tv_nsec = nsec;
+      mtime = real_clock::from_ceph_timespec(ts);
+    }
+    JSONDecoder::decode_json("ETag", etag, obj);
+    JSONDecoder::decode_json("Size", size, obj);
+    JSONDecoder::decode_json("StorageClass", storage_class, obj);
+    JSONDecoder::decode_json("Owner", owner, obj);
+    JSONDecoder::decode_json("VersionedEpoch", versioned_epoch, obj);
+    JSONDecoder::decode_json("RgwxTag", rgw_tag, obj);
+  }
+};
+
+struct bucket_list_result {
+  string name;
+  string prefix;
+  string key_marker;
+  string version_id_marker;
+  int max_keys;
+  bool is_truncated;
+  list<bucket_list_entry> entries;
+
+  bucket_list_result() : max_keys(0), is_truncated(false) {}
+
+  void decode_json(JSONObj *obj) {
+    JSONDecoder::decode_json("Name", name, obj);
+    JSONDecoder::decode_json("Prefix", prefix, obj);
+    JSONDecoder::decode_json("KeyMarker", key_marker, obj);
+    JSONDecoder::decode_json("VersionIdMarker", version_id_marker, obj);
+    JSONDecoder::decode_json("MaxKeys", max_keys, obj);
+    JSONDecoder::decode_json("IsTruncated", is_truncated, obj);
+    JSONDecoder::decode_json("Entries", entries, obj);
+  }
+};
+
+class RGWListBucketShardCR: public RGWCoroutine {
+  RGWDataSyncEnv *sync_env;
+
+  string bucket_name;
+  string bucket_id;
+  int shard_id;
+
+  string instance_key;
+  rgw_obj_key marker_position;
+
+  bucket_list_result *result;
+
+public:
+  RGWListBucketShardCR(RGWDataSyncEnv *_sync_env,
+                                  const string& _bucket_name, const string& _bucket_id, int _shard_id,
+                                  rgw_obj_key& _marker_position,
+                                  bucket_list_result *_result) : RGWCoroutine(_sync_env->cct), sync_env(_sync_env),
+                                                      bucket_name(_bucket_name), bucket_id(_bucket_id), shard_id(_shard_id),
+                                                      marker_position(_marker_position),
+                                                      result(_result) {
+    instance_key = bucket_name + ":" + bucket_id;
+    if (shard_id >= 0) {
+      char buf[16];
+      snprintf(buf, sizeof(buf), ":%d", shard_id);
+      instance_key.append(buf);
+    }
+  }
+
+  int operate() {
+    reenter(this) {
+      yield {
+        rgw_http_param_pair pairs[] = { { "rgwx-bucket-instance", instance_key.c_str() },
+					{ "versions" , NULL },
+					{ "format" , "json" },
+					{ "objs-container" , "true" },
+					{ "key-marker" , marker_position.name.c_str() },
+					{ "version-id-marker" , marker_position.instance.c_str() },
+	                                { NULL, NULL } };
+
+        string p = string("/") + bucket_name;
+        call(new RGWReadRESTResourceCR<bucket_list_result>(sync_env->cct, sync_env->conn, sync_env->http_manager, p, pairs, result));
+      }
+      if (retcode < 0) {
+        return set_cr_error(retcode);
+      }
+      return set_cr_done();
+    }
+    return 0;
+  }
+};
+
+class RGWListBucketIndexLogCR: public RGWCoroutine {
+  RGWDataSyncEnv *sync_env;
+
+  string bucket_name;
+  string bucket_id;
+  int shard_id;
+
+  string instance_key;
+  string marker;
+
+  list<rgw_bi_log_entry> *result;
+
+public:
+  RGWListBucketIndexLogCR(RGWDataSyncEnv *_sync_env,
+                          const string& _bucket_name, const string& _bucket_id, int _shard_id,
+                          string& _marker,
+                          list<rgw_bi_log_entry> *_result) : RGWCoroutine(_sync_env->cct), sync_env(_sync_env),
+                                                      bucket_name(_bucket_name), bucket_id(_bucket_id), shard_id(_shard_id),
+                                                      marker(_marker),
+                                                      result(_result) {
+    instance_key = bucket_name + ":" + bucket_id;
+    if (shard_id >= 0) {
+      char buf[16];
+      snprintf(buf, sizeof(buf), ":%d", shard_id);
+      instance_key.append(buf);
+    }
+  }
+
+  int operate() {
+    reenter(this) {
+      yield {
+        rgw_http_param_pair pairs[] = { { "bucket-instance", instance_key.c_str() },
+					{ "format" , "json" },
+					{ "marker" , marker.c_str() },
+					{ "type", "bucket-index" },
+	                                { NULL, NULL } };
+
+        call(new RGWReadRESTResourceCR<list<rgw_bi_log_entry> >(sync_env->cct, sync_env->conn, sync_env->http_manager, "/admin/log", pairs, result));
+      }
+      if (retcode < 0) {
+        return set_cr_error(retcode);
+      }
+      return set_cr_done();
+    }
+    return 0;
+  }
+};
+
+#define BUCKET_SYNC_UPDATE_MARKER_WINDOW 10
+
+class RGWBucketFullSyncShardMarkerTrack : public RGWSyncShardMarkerTrack<rgw_obj_key, rgw_obj_key> {
+  RGWDataSyncEnv *sync_env;
+
+  string marker_oid;
+  rgw_bucket_shard_full_sync_marker sync_marker;
+
+public:
+  RGWBucketFullSyncShardMarkerTrack(RGWDataSyncEnv *_sync_env,
+                         const string& _marker_oid,
+                         const rgw_bucket_shard_full_sync_marker& _marker) : RGWSyncShardMarkerTrack(BUCKET_SYNC_UPDATE_MARKER_WINDOW),
+                                                                sync_env(_sync_env),
+                                                                marker_oid(_marker_oid),
+                                                                sync_marker(_marker) {}
+
+  RGWCoroutine *store_marker(const rgw_obj_key& new_marker, uint64_t index_pos, const real_time& timestamp) {
+    sync_marker.position = new_marker;
+    sync_marker.count = index_pos;
+
+    map<string, bufferlist> attrs;
+    sync_marker.encode_attr(attrs);
+
+    RGWRados *store = sync_env->store;
+
+    ldout(sync_env->cct, 20) << __func__ << "(): updating marker marker_oid=" << marker_oid << " marker=" << new_marker << dendl;
+    return new RGWSimpleRadosWriteAttrsCR(sync_env->async_rados, store, store->get_zone_params().log_pool,
+				 marker_oid, attrs);
+  }
+};
+
+class RGWBucketIncSyncShardMarkerTrack : public RGWSyncShardMarkerTrack<string, rgw_obj_key> {
+  RGWDataSyncEnv *sync_env;
+
+  string marker_oid;
+  rgw_bucket_shard_inc_sync_marker sync_marker;
+
+  map<rgw_obj_key, pair<RGWModifyOp, string> > key_to_marker;
+  map<string, rgw_obj_key> marker_to_key;
+
+  void handle_finish(const string& marker) {
+    map<string, rgw_obj_key>::iterator iter = marker_to_key.find(marker);
+    if (iter == marker_to_key.end()) {
+      return;
+    }
+    key_to_marker.erase(iter->second);
+    reset_need_retry(iter->second);
+    marker_to_key.erase(iter);
+  }
+
+public:
+  RGWBucketIncSyncShardMarkerTrack(RGWDataSyncEnv *_sync_env,
+                         const string& _marker_oid,
+                         const rgw_bucket_shard_inc_sync_marker& _marker) : RGWSyncShardMarkerTrack(BUCKET_SYNC_UPDATE_MARKER_WINDOW),
+                                                                sync_env(_sync_env),
+                                                                marker_oid(_marker_oid),
+                                                                sync_marker(_marker) {}
+
+  RGWCoroutine *store_marker(const string& new_marker, uint64_t index_pos, const real_time& timestamp) {
+    sync_marker.position = new_marker;
+
+    map<string, bufferlist> attrs;
+    sync_marker.encode_attr(attrs);
+
+    RGWRados *store = sync_env->store;
+
+    ldout(sync_env->cct, 20) << __func__ << "(): updating marker marker_oid=" << marker_oid << " marker=" << new_marker << dendl;
+    return new RGWSimpleRadosWriteAttrsCR(sync_env->async_rados, store, store->get_zone_params().log_pool,
+				 marker_oid, attrs);
+  }
+
+  /*
+   * create index from key -> <op, marker>, and from marker -> key
+   * this is useful so that we can insure that we only have one
+   * entry for any key that is used. This is needed when doing
+   * incremenatl sync of data, and we don't want to run multiple
+   * concurrent sync operations for the same bucket shard 
+   * Also, we should make sure that we don't run concurrent operations on the same key with
+   * different ops.
+   */
+  bool index_key_to_marker(const rgw_obj_key& key, RGWModifyOp op, const string& marker) {
+    if (key_to_marker.find(key) != key_to_marker.end()) {
+      set_need_retry(key);
+      return false;
+    }
+    key_to_marker[key] = make_pair<>(op, marker);
+    marker_to_key[marker] = key;
+    return true;
+  }
+
+  bool can_do_op(const rgw_obj_key& key, RGWModifyOp op) {
+    auto i = key_to_marker.find(key);
+    if (i == key_to_marker.end()) {
+      return true;
+    }
+
+    return (i->second.first == op);
+  }
+};
+
+template <class T, class K>
+class RGWBucketSyncSingleEntryCR : public RGWCoroutine {
+  RGWDataSyncEnv *sync_env;
+
+  RGWBucketInfo *bucket_info;
+  int shard_id;
+
+  rgw_obj_key key;
+  bool versioned;
+  uint64_t versioned_epoch;
+  bucket_entry_owner owner;
+  real_time timestamp;
+  RGWModifyOp op;
+  RGWPendingState op_state;
+
+  T entry_marker;
+  RGWSyncShardMarkerTrack<T, K> *marker_tracker;
+
+  int sync_status;
+
+  stringstream error_ss;
+
+
+public:
+  RGWBucketSyncSingleEntryCR(RGWDataSyncEnv *_sync_env,
+                             RGWBucketInfo *_bucket_info, int _shard_id,
+                             const rgw_obj_key& _key, bool _versioned, uint64_t _versioned_epoch,
+                             real_time& _timestamp,
+                             const bucket_entry_owner& _owner,
+                             RGWModifyOp _op, RGWPendingState _op_state,
+		             const T& _entry_marker, RGWSyncShardMarkerTrack<T, K> *_marker_tracker) : RGWCoroutine(_sync_env->cct),
+						      sync_env(_sync_env),
+                                                      bucket_info(_bucket_info), shard_id(_shard_id),
+                                                      key(_key), versioned(_versioned), versioned_epoch(_versioned_epoch),
+                                                      owner(_owner),
+                                                      timestamp(_timestamp), op(_op),
+                                                      op_state(_op_state),
+                                                      entry_marker(_entry_marker),
+                                                      marker_tracker(_marker_tracker),
+                                                      sync_status(0) {
+    set_description() << "bucket sync single entry (source_zone=" << sync_env->source_zone << ") b=" << bucket_info->bucket << ":" << shard_id <<"/" << key << "[" << versioned_epoch << "] log_entry=" << entry_marker << " op=" << (int)op << " op_state=" << (int)op_state;
+    ldout(sync_env->cct, 20) << "bucket sync single entry (source_zone=" << sync_env->source_zone << ") b=" << bucket_info->bucket << ":" << shard_id <<"/" << key << "[" << versioned_epoch << "] log_entry=" << entry_marker << " op=" << (int)op << " op_state=" << (int)op_state << dendl;
+    set_status("init");
+  }
+
+  int operate() {
+    reenter(this) {
+      /* skip entries that are not complete */
+      if (op_state != CLS_RGW_STATE_COMPLETE) {
+        goto done;
+      }
+      do {
+        yield {
+          marker_tracker->reset_need_retry(key);
+          if (key.name.empty()) {
+            /* shouldn't happen */
+            set_status("skipping empty entry");
+            ldout(sync_env->cct, 0) << "ERROR: " << __func__ << "(): entry with empty obj name, skipping" << dendl;
+            goto done;
+          }
+          if (op == CLS_RGW_OP_ADD ||
+              op == CLS_RGW_OP_LINK_OLH) {
+            if (op == CLS_RGW_OP_ADD && !key.instance.empty() && key.instance != "null") {
+              set_status("skipping entry");
+              ldout(sync_env->cct, 10) << "bucket skipping sync obj: " << sync_env->source_zone << "/" << bucket_info->bucket << "/" << key << "[" << versioned_epoch << "]: versioned object will be synced on link_olh" << dendl;
+              goto done;
+
+            }
+            set_status("syncing obj");
+            ldout(sync_env->cct, 5) << "bucket sync: sync obj: " << sync_env->source_zone << "/" << bucket_info->bucket << "/" << key << "[" << versioned_epoch << "]" << dendl;
+            call(new RGWFetchRemoteObjCR(sync_env->async_rados, sync_env->store, sync_env->source_zone, *bucket_info,
+                                         key, versioned_epoch,
+                                         true));
+          } else if (op == CLS_RGW_OP_DEL || op == CLS_RGW_OP_UNLINK_INSTANCE) {
+            set_status("removing obj");
+            if (op == CLS_RGW_OP_UNLINK_INSTANCE) {
+              versioned = true;
+            }
+            call(new RGWRemoveObjCR(sync_env->async_rados, sync_env->store, sync_env->source_zone, *bucket_info, key, versioned, versioned_epoch, NULL, NULL, false, &timestamp));
+          } else if (op == CLS_RGW_OP_LINK_OLH_DM) {
+            set_status("creating delete marker");
+            ldout(sync_env->cct, 10) << "creating delete marker: obj: " << sync_env->source_zone << "/" << bucket_info->bucket << "/" << key << "[" << versioned_epoch << "]" << dendl;
+            call(new RGWRemoveObjCR(sync_env->async_rados, sync_env->store, sync_env->source_zone, *bucket_info, key, versioned, versioned_epoch, &owner.id, &owner.display_name, true, &timestamp));
+          }
+        }
+      } while (marker_tracker->need_retry(key));
+      if (retcode < 0 && retcode != -ENOENT) {
+        set_status() << "failed to sync obj; retcode=" << retcode;
+        rgw_bucket& bucket = bucket_info->bucket;
+        ldout(sync_env->cct, 0) << "ERROR: failed to sync object: " << bucket.name << ":" << bucket.bucket_id << ":" << shard_id << "/" << key.name << dendl;
+        error_ss << bucket.name << ":" << bucket.bucket_id << ":" << shard_id << "/" << key.name;
+        sync_status = retcode;
+      }
+      if (!error_ss.str().empty()) {
+        yield call(sync_env->error_logger->log_error_cr(sync_env->conn->get_remote_id(), "data", error_ss.str(), retcode, "failed to sync object"));
+      }
+done:
+      /* update marker */
+      set_status() << "calling marker_tracker->finish(" << entry_marker << ")";
+      yield call(marker_tracker->finish(entry_marker));
+      if (sync_status == 0) {
+        sync_status = retcode;
+      }
+      if (sync_status < 0) {
+        return set_cr_error(sync_status);
+      }
+      return set_cr_done();
+    }
+    return 0;
+  }
+};
+
+#define BUCKET_SYNC_SPAWN_WINDOW 20
+
+class RGWBucketShardFullSyncCR : public RGWCoroutine {
+  RGWDataSyncEnv *sync_env;
+  string bucket_name;
+  string bucket_id;
+  int shard_id;
+  RGWBucketInfo *bucket_info;
+  bucket_list_result list_result;
+  list<bucket_list_entry>::iterator entries_iter;
+  rgw_bucket_shard_full_sync_marker full_marker;
+  RGWBucketFullSyncShardMarkerTrack *marker_tracker;
+  int spawn_window;
+  rgw_obj_key list_marker;
+  bucket_list_entry *entry;
+  RGWModifyOp op;
+
+  int total_entries;
+
+  RGWContinuousLeaseCR *lease_cr;
+
+  string status_oid;
+public:
+  RGWBucketShardFullSyncCR(RGWDataSyncEnv *_sync_env,
+                           const string& _bucket_name, const string _bucket_id, int _shard_id,
+                           RGWBucketInfo *_bucket_info,  rgw_bucket_shard_full_sync_marker& _full_marker) : RGWCoroutine(_sync_env->cct),
+									    sync_env(_sync_env),
+                                                                            bucket_name(_bucket_name),
+									    bucket_id(_bucket_id), shard_id(_shard_id),
+                                                                            bucket_info(_bucket_info),
+                                                                            full_marker(_full_marker), marker_tracker(NULL),
+                                                                            spawn_window(BUCKET_SYNC_SPAWN_WINDOW), entry(NULL),
+                                                                            op(CLS_RGW_OP_ADD),
+                                                                            total_entries(0), lease_cr(NULL) {
+    status_oid = RGWBucketSyncStatusManager::status_oid(sync_env->source_zone, bucket_name, bucket_id, shard_id);
+  }
+
+  ~RGWBucketShardFullSyncCR() {
+    delete marker_tracker;
+    if (lease_cr) {
+      lease_cr->abort();
+      lease_cr->put();
+    }
+  }
+  int operate();
+};
+
+int RGWBucketShardFullSyncCR::operate()
+{
+  int ret;
+  reenter(this) {
+    yield {
+      set_status("acquiring sync lock");
+      uint32_t lock_duration = cct->_conf->rgw_sync_lease_period;
+      string lock_name = "sync_lock";
+      RGWRados *store = sync_env->store;
+      lease_cr = new RGWContinuousLeaseCR(sync_env->async_rados, store, store->get_zone_params().log_pool, status_oid,
+                                          lock_name, lock_duration, this);
+      lease_cr->get();
+      spawn(lease_cr, false);
+    }
+    while (!lease_cr->is_locked()) {
+      if (lease_cr->is_done()) {
+        ldout(cct, 0) << "ERROR: lease cr failed, done early " << dendl;
+        set_status("lease lock failed, early abort");
+        return set_cr_error(lease_cr->get_ret_status());
+      }
+      set_sleeping(true);
+      yield;
+    }
+    set_status("lock acquired");
+    list_marker = full_marker.position;
+    marker_tracker = new RGWBucketFullSyncShardMarkerTrack(sync_env, status_oid, full_marker);
+
+    total_entries = full_marker.count;
+    do {
+      set_status("listing remote bucket");
+      ldout(sync_env->cct, 20) << __func__ << "(): listing bucket for full sync" << dendl;
+      yield call(new RGWListBucketShardCR(sync_env, bucket_name, bucket_id, shard_id,
+                                          list_marker, &list_result));
+      if (retcode < 0 && retcode != -ENOENT) {
+        set_status("failed bucket listing, going down");
+        yield lease_cr->go_down();
+        drain_all();
+        return set_cr_error(retcode);
+      }
+      entries_iter = list_result.entries.begin();
+      for (; entries_iter != list_result.entries.end(); ++entries_iter) {
+        ldout(sync_env->cct, 20) << "[full sync] syncing object: " << bucket_name << ":" << bucket_id << ":" << shard_id << "/" << entries_iter->key << dendl;
+        entry = &(*entries_iter);
+        total_entries++;
+        list_marker = entries_iter->key;
+        if (!marker_tracker->start(entry->key, total_entries, real_time())) {
+          ldout(sync_env->cct, 0) << "ERROR: cannot start syncing " << entry->key << ". Duplicate entry?" << dendl;
+        } else {
+          op = (entry->key.instance.empty() || entry->key.instance == "null" ? CLS_RGW_OP_ADD : CLS_RGW_OP_LINK_OLH);
+
+          yield {
+            spawn(new RGWBucketSyncSingleEntryCR<rgw_obj_key, rgw_obj_key>(sync_env, bucket_info, shard_id,
+                                                                           entry->key,
+                                                                           false, /* versioned, only matters for object removal */
+                                                                           entry->versioned_epoch, entry->mtime,
+                                                                           entry->owner, op, CLS_RGW_STATE_COMPLETE, entry->key, marker_tracker), false);
+          }
+        }
+        while ((int)num_spawned() > spawn_window) {
+          yield wait_for_child();
+          while (collect(&ret)) {
+            if (ret < 0) {
+              ldout(sync_env->cct, 0) << "ERROR: a sync operation returned error" << dendl;
+              /* we have reported this error */
+            }
+          }
+        }
+      }
+    } while (list_result.is_truncated);
+    set_status("done iterating over all objects");
+    /* wait for all operations to complete */
+    drain_all_but(1); /* still need to hold lease cr */
+    /* update sync state to incremental */
+    yield {
+      rgw_bucket_shard_sync_info sync_status;
+      sync_status.state = rgw_bucket_shard_sync_info::StateIncrementalSync;
+      map<string, bufferlist> attrs;
+      sync_status.encode_state_attr(attrs);
+      string oid = RGWBucketSyncStatusManager::status_oid(sync_env->source_zone, bucket_name, bucket_id, shard_id);
+      RGWRados *store = sync_env->store;
+      call(new RGWSimpleRadosWriteAttrsCR(sync_env->async_rados, store, store->get_zone_params().log_pool,
+                                          oid, attrs));
+    }
+    yield lease_cr->go_down();
+    drain_all();
+    if (retcode < 0) {
+      ldout(sync_env->cct, 0) << "ERROR: failed to set sync state on bucket " << bucket_name << ":" << bucket_id << ":" << shard_id
+        << " retcode=" << retcode << dendl;
+      return set_cr_error(retcode);
+    }
+    return set_cr_done();
+  }
+  return 0;
+}
+
+class RGWBucketShardIncrementalSyncCR : public RGWCoroutine {
+  RGWDataSyncEnv *sync_env;
+  string bucket_name;
+  string bucket_id;
+  int shard_id;
+  RGWBucketInfo *bucket_info;
+  list<rgw_bi_log_entry> list_result;
+  list<rgw_bi_log_entry>::iterator entries_iter;
+  rgw_bucket_shard_inc_sync_marker inc_marker;
+  rgw_obj_key key;
+  rgw_bi_log_entry *entry;
+  RGWBucketIncSyncShardMarkerTrack *marker_tracker;
+  int spawn_window;
+  bool updated_status;
+  RGWContinuousLeaseCR *lease_cr;
+  string status_oid;
+
+  string name;
+  string instance;
+  string ns;
+
+
+
+public:
+  RGWBucketShardIncrementalSyncCR(RGWDataSyncEnv *_sync_env,
+                           const string& _bucket_name, const string _bucket_id, int _shard_id,
+                           RGWBucketInfo *_bucket_info, rgw_bucket_shard_inc_sync_marker& _inc_marker) : RGWCoroutine(_sync_env->cct),
+                                                                            sync_env(_sync_env),
+                                                                            bucket_name(_bucket_name),
+									    bucket_id(_bucket_id), shard_id(_shard_id),
+                                                                            bucket_info(_bucket_info),
+                                                                            inc_marker(_inc_marker), entry(NULL), marker_tracker(NULL),
+                                                                            spawn_window(BUCKET_SYNC_SPAWN_WINDOW), updated_status(false),
+                                                                            lease_cr(NULL) {
+    status_oid = RGWBucketSyncStatusManager::status_oid(sync_env->source_zone, bucket_name, bucket_id, shard_id);
+    set_description() << "bucket shard incremental sync bucket=" << _bucket_name << ":" << _bucket_id << ":" << _shard_id;
+    set_status("init");
+  }
+
+  ~RGWBucketShardIncrementalSyncCR() {
+    if (lease_cr) {
+      lease_cr->abort();
+      lease_cr->put();
+    }
+    delete marker_tracker;
+  }
+  int operate();
+};
+
+int RGWBucketShardIncrementalSyncCR::operate()
+{
+  int ret;
+  reenter(this) {
+    yield {
+      set_status("acquiring sync lock");
+      uint32_t lock_duration = cct->_conf->rgw_sync_lease_period;
+      string lock_name = "sync_lock";
+      RGWRados *store = sync_env->store;
+      lease_cr = new RGWContinuousLeaseCR(sync_env->async_rados, store, store->get_zone_params().log_pool, status_oid,
+                                          lock_name, lock_duration, this);
+      lease_cr->get();
+      spawn(lease_cr, false);
+    }
+    while (!lease_cr->is_locked()) {
+      if (lease_cr->is_done()) {
+        ldout(cct, 0) << "ERROR: lease cr failed, done early " << dendl;
+        set_status("lease lock failed, early abort");
+        return set_cr_error(lease_cr->get_ret_status());
+      }
+      set_sleeping(true);
+      yield;
+    }
+    marker_tracker = new RGWBucketIncSyncShardMarkerTrack(sync_env,
+                                                          status_oid,
+                                                          inc_marker);
+    do {
+      ldout(sync_env->cct, 20) << __func__ << "(): listing bilog for incremental sync" << dendl;
+      set_status() << "listing bilog; position=" << inc_marker.position;
+      yield call(new RGWListBucketIndexLogCR(sync_env, bucket_name, bucket_id, shard_id,
+                                         inc_marker.position, &list_result));
+      if (retcode < 0 && retcode != -ENOENT) {
+        /* wait for all operations to complete */
+        lease_cr->go_down();
+        drain_all();
+        return set_cr_error(retcode);
+      }
+      entries_iter = list_result.begin();
+      for (; entries_iter != list_result.end(); ++entries_iter) {
+        entry = &(*entries_iter);
+        inc_marker.position = entry->id;
+
+        if (!rgw_obj::parse_raw_oid(entries_iter->object, &name, &instance, &ns)) {
+          set_status() << "parse_raw_oid() on " << entries_iter->object << " returned false, skipping entry";
+          ldout(sync_env->cct, 20) << "parse_raw_oid() on " << entries_iter->object << " returned false, skipping entry" << dendl;
+          continue;
+        }
+
+        ldout(sync_env->cct, 20) << "parsed entry: iter->object=" << entries_iter->object << " iter->instance=" << entries_iter->instance << " name=" << name << " instance=" << instance << " ns=" << ns << dendl;
+
+        if (!ns.empty()) {
+          set_status() << "skipping entry in namespace: " << entries_iter->object;
+          ldout(sync_env->cct, 20) << "skipping entry in namespace: " << entries_iter->object << dendl;
+          continue;
+        }
+
+        key = rgw_obj_key(name, entries_iter->instance);
+        set_status() << "got entry.id=" << entry->id << " key=" << key << " op=" << (int)entry->op;
+        if (entry->op == CLS_RGW_OP_CANCEL) {
+          set_status() << "canceled operation, skipping";
+          ldout(sync_env->cct, 20) << "[inc sync] skipping object: " << bucket_name << ":" << bucket_id << ":" << shard_id << "/" << key << ": canceled operation" << dendl;
+          continue;
+        }
+        if (entry->state != CLS_RGW_STATE_COMPLETE) {
+          set_status() << "non-complete operation, skipping";
+          ldout(sync_env->cct, 20) << "[inc sync] skipping object: " << bucket_name << ":" << bucket_id << ":" << shard_id << "/" << key << ": non-complete operation" << dendl;
+          continue;
+        }
+        ldout(sync_env->cct, 20) << "[inc sync] syncing object: " << bucket_name << ":" << bucket_id << ":" << shard_id << "/" << key << dendl;
+        updated_status = false;
+        while (!marker_tracker->can_do_op(key, entry->op)) {
+          if (!updated_status) {
+            set_status() << "can't do op, conflicting inflight operation";
+            updated_status = true;
+          }
+          ldout(sync_env->cct, 5) << *this << ": [inc sync] can't do op on key=" << key << " need to wait for conflicting operation to complete" << dendl;
+          yield wait_for_child();
+          
+        }
+        if (!marker_tracker->index_key_to_marker(key, entry->op, entry->id)) {
+          set_status() << "can't do op, sync already in progress for object";
+          ldout(sync_env->cct, 20) << __func__ << ": skipping sync of entry: " << entry->id << ":" << key << " sync already in progress for object" << dendl;
+          marker_tracker->try_update_high_marker(entry->id, 0, entries_iter->timestamp);
+          continue;
+        }
+        // yield {
+          set_status() << "start object sync";
+          if (!marker_tracker->start(entry->id, 0, entries_iter->timestamp)) {
+            ldout(sync_env->cct, 0) << "ERROR: cannot start syncing " << entry->id << ". Duplicate entry?" << dendl;
+          } else {
+            uint64_t versioned_epoch = 0;
+            bucket_entry_owner owner(entry->owner, entry->owner_display_name);
+            if (entry->ver.pool < 0) {
+              versioned_epoch = entry->ver.epoch;
+            }
+ldout(sync_env->cct, 0) << __FILE__ << ":" << __LINE__ << " entry->timestamp=" << entry->timestamp << dendl;
+            spawn(new RGWBucketSyncSingleEntryCR<string, rgw_obj_key>(sync_env, bucket_info, shard_id,
+                                                         key, entry->is_versioned(), versioned_epoch, entry->timestamp, owner, entry->op,
+                                                         entry->state, entry->id, marker_tracker), false);
+          }
+        // }
+        while ((int)num_spawned() > spawn_window) {
+          set_status() << "num_spawned() > spawn_window";
+          yield wait_for_child();
+          while (collect(&ret)) {
+            if (ret < 0) {
+              ldout(sync_env->cct, 0) << "ERROR: a sync operation returned error" << dendl;
+              /* we have reported this error */
+            }
+            /* not waiting for child here */
+          }
+        }
+      }
+    } while (!list_result.empty());
+
+    lease_cr->go_down();
+    /* wait for all operations to complete */
+    drain_all();
+    return set_cr_done();
+  }
+  return 0;
+}
+
+int RGWRunBucketSyncCoroutine::operate()
+{
+  reenter(this) {
+    yield call(new RGWReadBucketSyncStatusCoroutine(sync_env, bucket_name, bucket_id, shard_id, &sync_status));
+    if (retcode < 0 && retcode != -ENOENT) {
+      ldout(sync_env->cct, 0) << "ERROR: failed to read sync status for bucket=" << bucket_name << " bucket_id=" << bucket_id << " shard_id=" << shard_id << dendl;
+      return set_cr_error(retcode);
+    }
+
+    ldout(sync_env->cct, 20) << __func__ << "(): sync status for bucket " << bucket_name << ":" << bucket_id << ":" << shard_id << ": " << sync_status.state << dendl;
+
+    yield call(new RGWGetBucketInstanceInfoCR(sync_env->async_rados, sync_env->store, bucket_name, bucket_id, &bucket_info));
+    if (retcode == -ENOENT) {
+      /* bucket instance info has not been synced in yet, fetch it now */
+      yield {
+        ldout(sync_env->cct, 10) << "no local info for bucket " << bucket_name << ":" << bucket_id << ": fetching metadata" << dendl;
+        string raw_key = string("bucket.instance:") + bucket_name + ":" + bucket_id;
+
+        meta_sync_env.init(cct, sync_env->store, sync_env->store->rest_master_conn, sync_env->async_rados, sync_env->http_manager, sync_env->error_logger);
+
+        call(new RGWMetaSyncSingleEntryCR(&meta_sync_env, raw_key,
+                                          string() /* no marker */,
+                                          MDLOG_STATUS_COMPLETE,
+                                          NULL /* no marker tracker */));
+      }
+      if (retcode < 0) {
+        ldout(sync_env->cct, 0) << "ERROR: failed to fetch bucket instance info for " << bucket_name << ":" << bucket_id << dendl;
+        return set_cr_error(retcode);
+      }
+
+      yield call(new RGWGetBucketInstanceInfoCR(sync_env->async_rados, sync_env->store, bucket_name, bucket_id, &bucket_info));
+    }
+    if (retcode < 0) {
+      ldout(sync_env->cct, 0) << "ERROR: failed to retrieve bucket info for bucket=" << bucket_name << " bucket_id=" << bucket_id << dendl;
+      return set_cr_error(retcode);
+    }
+
+    yield {
+      if ((rgw_bucket_shard_sync_info::SyncState)sync_status.state == rgw_bucket_shard_sync_info::StateInit) {
+        call(new RGWInitBucketShardSyncStatusCoroutine(sync_env, bucket_name, bucket_id, shard_id));
+        sync_status.state = rgw_bucket_shard_sync_info::StateFullSync;
+      }
+    }
+
+    if (retcode < 0) {
+      ldout(sync_env->cct, 0) << "ERROR: init sync on " << bucket_name << " bucket_id=" << bucket_id << " shard_id=" << shard_id << " failed, retcode=" << retcode << dendl;
+      return set_cr_error(retcode);
+    }
+    yield {
+      if ((rgw_bucket_shard_sync_info::SyncState)sync_status.state == rgw_bucket_shard_sync_info::StateFullSync) {
+        call(new RGWBucketShardFullSyncCR(sync_env, bucket_name, bucket_id, shard_id,
+                                          &bucket_info, sync_status.full_marker));
+        sync_status.state = rgw_bucket_shard_sync_info::StateIncrementalSync;
+      }
+    }
+    if (retcode < 0) {
+      ldout(sync_env->cct, 0) << "ERROR: full sync on " << bucket_name << " bucket_id=" << bucket_id << " shard_id=" << shard_id << " failed, retcode=" << retcode << dendl;
+      return set_cr_error(retcode);
+    }
+
+    yield {
+      if ((rgw_bucket_shard_sync_info::SyncState)sync_status.state == rgw_bucket_shard_sync_info::StateIncrementalSync) {
+        call(new RGWBucketShardIncrementalSyncCR(sync_env, bucket_name, bucket_id, shard_id,
+                                                 &bucket_info, sync_status.inc_marker));
+      }
+    }
+    if (retcode < 0) {
+      ldout(sync_env->cct, 0) << "ERROR: incremental sync on " << bucket_name << " bucket_id=" << bucket_id << " shard_id=" << shard_id << " failed, retcode=" << retcode << dendl;
+      return set_cr_error(retcode);
+    }
+
+    return set_cr_done();
+  }
+
+  return 0;
+}
+
+RGWCoroutine *RGWRemoteBucketLog::run_sync_cr()
+{
+  return new RGWRunBucketSyncCoroutine(&sync_env, bucket_name, bucket_id, shard_id);
+}
+
+int RGWBucketSyncStatusManager::init()
+{
+  conn = store->get_zone_conn_by_id(source_zone);
+  if (!conn) {
+    ldout(store->ctx(), 0) << "connection object to zone " << source_zone << " does not exist" << dendl;
+    return -EINVAL;
+  }
+
+  async_rados = new RGWAsyncRadosProcessor(store, store->ctx()->_conf->rgw_num_async_rados_threads);
+  async_rados->start();
+
+  int ret = http_manager.set_threaded();
+  if (ret < 0) {
+    ldout(store->ctx(), 0) << "failed in http_manager.set_threaded() ret=" << ret << dendl;
+    return ret;
+  }
+
+
+  string key = bucket_name + ":" + bucket_id;
+
+  rgw_http_param_pair pairs[] = { { "key", key.c_str() },
+                                  { NULL, NULL } };
+
+  string path = string("/admin/metadata/bucket.instance");
+
+  bucket_instance_meta_info result;
+  ret = cr_mgr.run(new RGWReadRESTResourceCR<bucket_instance_meta_info>(store->ctx(), conn, &http_manager, path, pairs, &result));
+  if (ret < 0) {
+    ldout(store->ctx(), 0) << "ERROR: failed to fetch bucket metadata info from zone=" << source_zone << " path=" << path << " key=" << key << " ret=" << ret << dendl;
+    return ret;
+  }
+
+  RGWBucketInfo& bi = result.data.get_bucket_info();
+  num_shards = bi.num_shards;
+
+  error_logger = new RGWSyncErrorLogger(store, RGW_SYNC_ERROR_LOG_SHARD_PREFIX, ERROR_LOGGER_SHARDS);
+
+  int effective_num_shards = (num_shards ? num_shards : 1);
+
+  for (int i = 0; i < effective_num_shards; i++) {
+    RGWRemoteBucketLog *l = new RGWRemoteBucketLog(store, this, async_rados, &http_manager);
+    ret = l->init(source_zone, conn, bucket_name, bucket_id, (num_shards ? i : -1), error_logger);
+    if (ret < 0) {
+      ldout(store->ctx(), 0) << "ERROR: failed to initialize RGWRemoteBucketLog object" << dendl;
+      return ret;
+    }
+    source_logs[i] = l;
+  }
+
+  return 0;
+}
+
+int RGWBucketSyncStatusManager::init_sync_status()
+{
+  list<RGWCoroutinesStack *> stacks;
+
+  for (map<int, RGWRemoteBucketLog *>::iterator iter = source_logs.begin(); iter != source_logs.end(); ++iter) {
+    RGWCoroutinesStack *stack = new RGWCoroutinesStack(store->ctx(), &cr_mgr);
+    RGWRemoteBucketLog *l = iter->second;
+    stack->call(l->init_sync_status_cr());
+
+    stacks.push_back(stack);
+  }
+
+  return cr_mgr.run(stacks);
+}
+
+int RGWBucketSyncStatusManager::read_sync_status()
+{
+  list<RGWCoroutinesStack *> stacks;
+
+  for (map<int, RGWRemoteBucketLog *>::iterator iter = source_logs.begin(); iter != source_logs.end(); ++iter) {
+    RGWCoroutinesStack *stack = new RGWCoroutinesStack(store->ctx(), &cr_mgr);
+    RGWRemoteBucketLog *l = iter->second;
+    stack->call(l->read_sync_status_cr(&sync_status[iter->first]));
+
+    stacks.push_back(stack);
+  }
+
+  int ret = cr_mgr.run(stacks);
+  if (ret < 0) {
+    ldout(store->ctx(), 0) << "ERROR: failed to read sync status for " << bucket_name << ":" << bucket_id << dendl;
+    return ret;
+  }
+
+  return 0;
+}
+
+int RGWBucketSyncStatusManager::run()
+{
+  list<RGWCoroutinesStack *> stacks;
+
+  for (map<int, RGWRemoteBucketLog *>::iterator iter = source_logs.begin(); iter != source_logs.end(); ++iter) {
+    RGWCoroutinesStack *stack = new RGWCoroutinesStack(store->ctx(), &cr_mgr);
+    RGWRemoteBucketLog *l = iter->second;
+    stack->call(l->run_sync_cr());
+
+    stacks.push_back(stack);
+  }
+
+  int ret = cr_mgr.run(stacks);
+  if (ret < 0) {
+    ldout(store->ctx(), 0) << "ERROR: failed to read sync status for " << bucket_name << ":" << bucket_id << dendl;
+    return ret;
+  }
+
+  return 0;
+}
+
+string RGWBucketSyncStatusManager::status_oid(const string& source_zone, const string& bucket_name, const string& bucket_id, int shard_id)
+{
+  string oid = bucket_status_oid_prefix + "." + source_zone + ":" + bucket_name + ":" + bucket_id;
+  if (shard_id >= 0) {
+    char buf[16];
+    snprintf(buf, sizeof(buf), ":%d", shard_id);
+    oid.append(buf);
+  }
+  return oid;
+}
+
diff --git a/src/rgw/rgw_data_sync.h b/src/rgw/rgw_data_sync.h
new file mode 100644
index 0000000..a2b2451
--- /dev/null
+++ b/src/rgw/rgw_data_sync.h
@@ -0,0 +1,478 @@
+#ifndef CEPH_RGW_DATA_SYNC_H
+#define CEPH_RGW_DATA_SYNC_H
+
+#include "rgw_coroutine.h"
+#include "rgw_http_client.h"
+#include "rgw_bucket.h"
+
+#include "common/RWLock.h"
+
+
+struct rgw_datalog_info {
+  uint32_t num_shards;
+
+  rgw_datalog_info() : num_shards(0) {}
+
+  void decode_json(JSONObj *obj);
+};
+
+struct rgw_data_sync_info {
+  enum SyncState {
+    StateInit = 0,
+    StateBuildingFullSyncMaps = 1,
+    StateSync = 2,
+  };
+
+  uint16_t state;
+  uint32_t num_shards;
+
+  void encode(bufferlist& bl) const {
+    ENCODE_START(1, 1, bl);
+    ::encode(state, bl);
+    ::encode(num_shards, bl);
+    ENCODE_FINISH(bl);
+  }
+
+  void decode(bufferlist::iterator& bl) {
+     DECODE_START(1, bl);
+     ::decode(state, bl);
+     ::decode(num_shards, bl);
+     DECODE_FINISH(bl);
+  }
+
+  void dump(Formatter *f) const {
+    string s;
+    switch ((SyncState)state) {
+      case StateInit:
+	s = "init";
+	break;
+      case StateBuildingFullSyncMaps:
+	s = "building-full-sync-maps";
+	break;
+      case StateSync:
+	s = "sync";
+	break;
+      default:
+	s = "unknown";
+	break;
+    }
+    encode_json("status", s, f);
+    encode_json("num_shards", num_shards, f);
+  }
+
+  rgw_data_sync_info() : state((int)StateInit), num_shards(0) {}
+};
+WRITE_CLASS_ENCODER(rgw_data_sync_info)
+
+struct rgw_data_sync_marker {
+  enum SyncState {
+    FullSync = 0,
+    IncrementalSync = 1,
+  };
+  uint16_t state;
+  string marker;
+  string next_step_marker;
+  uint64_t total_entries;
+  uint64_t pos;
+  real_time timestamp;
+
+  rgw_data_sync_marker() : state(FullSync), total_entries(0), pos(0) {}
+
+  void encode(bufferlist& bl) const {
+    ENCODE_START(1, 1, bl);
+    ::encode(state, bl);
+    ::encode(marker, bl);
+    ::encode(next_step_marker, bl);
+    ::encode(total_entries, bl);
+    ::encode(pos, bl);
+    ::encode(timestamp, bl);
+    ENCODE_FINISH(bl);
+  }
+
+  void decode(bufferlist::iterator& bl) {
+     DECODE_START(1, bl);
+    ::decode(state, bl);
+    ::decode(marker, bl);
+    ::decode(next_step_marker, bl);
+    ::decode(total_entries, bl);
+    ::decode(pos, bl);
+    ::decode(timestamp, bl);
+     DECODE_FINISH(bl);
+  }
+
+  void dump(Formatter *f) const {
+    encode_json("state", (int)state, f);
+    encode_json("marker", marker, f);
+    encode_json("next_step_marker", next_step_marker, f);
+    encode_json("total_entries", total_entries, f);
+    encode_json("pos", pos, f);
+    encode_json("timestamp", utime_t(timestamp), f);
+  }
+};
+WRITE_CLASS_ENCODER(rgw_data_sync_marker)
+
+struct rgw_data_sync_status {
+  rgw_data_sync_info sync_info;
+  map<uint32_t, rgw_data_sync_marker> sync_markers;
+
+  rgw_data_sync_status() {}
+
+  void encode(bufferlist& bl) const {
+    ENCODE_START(1, 1, bl);
+    ::encode(sync_info, bl);
+    /* sync markers are encoded separately */
+    ENCODE_FINISH(bl);
+  }
+
+  void decode(bufferlist::iterator& bl) {
+     DECODE_START(1, bl);
+    ::decode(sync_info, bl);
+    /* sync markers are decoded separately */
+     DECODE_FINISH(bl);
+  }
+
+  void dump(Formatter *f) const {
+    encode_json("info", sync_info, f);
+    encode_json("markers", sync_markers, f);
+  }
+};
+WRITE_CLASS_ENCODER(rgw_data_sync_status)
+
+struct rgw_datalog_entry {
+  string key;
+  ceph::real_time timestamp;
+
+  void decode_json(JSONObj *obj);
+};
+
+struct rgw_datalog_shard_data {
+  string marker;
+  bool truncated;
+  vector<rgw_datalog_entry> entries;
+
+  void decode_json(JSONObj *obj);
+};
+
+class RGWAsyncRadosProcessor;
+class RGWDataSyncStatusManager;
+class RGWDataSyncControlCR;
+
+struct RGWDataSyncEnv {
+  CephContext *cct;
+  RGWRados *store;
+  RGWRESTConn *conn;
+  RGWAsyncRadosProcessor *async_rados;
+  RGWHTTPManager *http_manager;
+  RGWSyncErrorLogger *error_logger;
+  string source_zone;
+
+  RGWDataSyncEnv() : cct(NULL), store(NULL), conn(NULL), async_rados(NULL), http_manager(NULL), error_logger(NULL) {}
+
+  void init(CephContext *_cct, RGWRados *_store, RGWRESTConn *_conn,
+            RGWAsyncRadosProcessor *_async_rados, RGWHTTPManager *_http_manager,
+            RGWSyncErrorLogger *_error_logger, const string& _source_zone) {
+    cct = _cct;
+    store = _store;
+    conn = _conn;
+    async_rados = _async_rados;
+    http_manager = _http_manager;
+    error_logger = _error_logger;
+    source_zone = _source_zone;
+  }
+
+  string shard_obj_name(int shard_id);
+  string status_oid();
+};
+
+class RGWRemoteDataLog : public RGWCoroutinesManager {
+  RGWRados *store;
+  RGWAsyncRadosProcessor *async_rados;
+  RGWHTTPManager http_manager;
+
+  RGWDataSyncEnv sync_env;
+
+  RWLock lock;
+  RGWDataSyncControlCR *data_sync_cr;
+
+  bool initialized;
+
+public:
+  RGWRemoteDataLog(RGWRados *_store, RGWAsyncRadosProcessor *async_rados)
+    : RGWCoroutinesManager(_store->ctx(), _store->get_cr_registry()),
+      store(_store), async_rados(async_rados),
+      http_manager(store->ctx(), completion_mgr),
+      lock("RGWRemoteDataLog::lock"), data_sync_cr(NULL),
+      initialized(false) {}
+  int init(const string& _source_zone, RGWRESTConn *_conn, RGWSyncErrorLogger *_error_logger);
+  void finish();
+
+  int read_log_info(rgw_datalog_info *log_info);
+  int read_source_log_shards_info(map<int, RGWDataChangesLogInfo> *shards_info);
+  int read_source_log_shards_next(map<int, string> shard_markers, map<int, rgw_datalog_shard_data> *result);
+  int get_shard_info(int shard_id);
+  int read_sync_status(rgw_data_sync_status *sync_status);
+  int init_sync_status(int num_shards);
+  int run_sync(int num_shards, rgw_data_sync_status& sync_status);
+
+  void wakeup(int shard_id, set<string>& keys);
+};
+
+class RGWDataSyncStatusManager {
+  RGWRados *store;
+  librados::IoCtx ioctx;
+
+  string source_zone;
+  RGWRESTConn *conn;
+  RGWSyncErrorLogger *error_logger;
+
+  RGWRemoteDataLog source_log;
+
+  string source_status_oid;
+  string source_shard_status_oid_prefix;
+  rgw_obj source_status_obj;
+
+  rgw_data_sync_status sync_status;
+  map<int, rgw_obj> shard_objs;
+
+  int num_shards;
+
+public:
+  RGWDataSyncStatusManager(RGWRados *_store, RGWAsyncRadosProcessor *async_rados,
+                           const string& _source_zone)
+    : store(_store), source_zone(_source_zone), conn(NULL), error_logger(NULL),
+      source_log(store, async_rados), num_shards(0) {}
+  ~RGWDataSyncStatusManager() {
+    delete error_logger;
+  }
+  int init();
+
+  rgw_data_sync_status& get_sync_status() { return sync_status; }
+
+  static string shard_obj_name(const string& source_zone, int shard_id);
+  static string sync_status_oid(const string& source_zone);
+
+  int read_sync_status() { return source_log.read_sync_status(&sync_status); }
+  int init_sync_status() { return source_log.init_sync_status(num_shards); }
+
+  int read_log_info(rgw_datalog_info *log_info) {
+    return source_log.read_log_info(log_info);
+  }
+  int read_source_log_shards_info(map<int, RGWDataChangesLogInfo> *shards_info) {
+    return source_log.read_source_log_shards_info(shards_info);
+  }
+  int read_source_log_shards_next(map<int, string> shard_markers, map<int, rgw_datalog_shard_data> *result) {
+    return source_log.read_source_log_shards_next(shard_markers, result);
+  }
+
+  int run() { return source_log.run_sync(num_shards, sync_status); }
+
+  void wakeup(int shard_id, set<string>& keys) { return source_log.wakeup(shard_id, keys); }
+  void stop() {
+    source_log.finish();
+  }
+};
+
+class RGWBucketSyncStatusManager;
+class RGWBucketSyncCR;
+
+struct rgw_bucket_shard_full_sync_marker {
+  rgw_obj_key position;
+  uint64_t count;
+
+  rgw_bucket_shard_full_sync_marker() : count(0) {}
+
+  void encode_attr(map<string, bufferlist>& attrs);
+
+  void encode(bufferlist& bl) const {
+    ENCODE_START(1, 1, bl);
+    ::encode(position, bl);
+    ::encode(count, bl);
+    ENCODE_FINISH(bl);
+  }
+
+  void decode(bufferlist::iterator& bl) {
+     DECODE_START(1, bl);
+    ::decode(position, bl);
+    ::decode(count, bl);
+     DECODE_FINISH(bl);
+  }
+
+  void dump(Formatter *f) const {
+    encode_json("position", position, f);
+    encode_json("count", count, f);
+  }
+};
+WRITE_CLASS_ENCODER(rgw_bucket_shard_full_sync_marker)
+
+struct rgw_bucket_shard_inc_sync_marker {
+  string position;
+
+  rgw_bucket_shard_inc_sync_marker() {}
+
+  void encode_attr(map<string, bufferlist>& attrs);
+
+  void encode(bufferlist& bl) const {
+    ENCODE_START(1, 1, bl);
+    ::encode(position, bl);
+    ENCODE_FINISH(bl);
+  }
+
+  void decode(bufferlist::iterator& bl) {
+     DECODE_START(1, bl);
+    ::decode(position, bl);
+     DECODE_FINISH(bl);
+  }
+
+  void dump(Formatter *f) const {
+    encode_json("position", position, f);
+  }
+
+  bool operator<(const rgw_bucket_shard_inc_sync_marker& m) const {
+    return (position < m.position);
+  }
+};
+WRITE_CLASS_ENCODER(rgw_bucket_shard_inc_sync_marker)
+
+struct rgw_bucket_shard_sync_info {
+  enum SyncState {
+    StateInit = 0,
+    StateFullSync = 1,
+    StateIncrementalSync = 2,
+  };
+
+  uint16_t state;
+  rgw_bucket_shard_full_sync_marker full_marker;
+  rgw_bucket_shard_inc_sync_marker inc_marker;
+
+  void decode_from_attrs(CephContext *cct, map<string, bufferlist>& attrs);
+  void encode_all_attrs(map<string, bufferlist>& attrs);
+  void encode_state_attr(map<string, bufferlist>& attrs);
+
+  void encode(bufferlist& bl) const {
+    ENCODE_START(1, 1, bl);
+    ::encode(state, bl);
+    ::encode(full_marker, bl);
+    ::encode(inc_marker, bl);
+    ENCODE_FINISH(bl);
+  }
+
+  void decode(bufferlist::iterator& bl) {
+     DECODE_START(1, bl);
+     ::decode(state, bl);
+     ::decode(full_marker, bl);
+     ::decode(inc_marker, bl);
+     DECODE_FINISH(bl);
+  }
+
+  void dump(Formatter *f) const {
+    string s;
+    switch ((SyncState)state) {
+      case StateInit:
+	s = "init";
+	break;
+      case StateFullSync:
+	s = "full-sync";
+	break;
+      case StateIncrementalSync:
+	s = "incremental-sync";
+	break;
+      default:
+	s = "unknown";
+	break;
+    }
+    encode_json("status", s, f);
+    encode_json("full_marker", full_marker, f);
+    encode_json("inc_marker", inc_marker, f);
+  }
+
+  rgw_bucket_shard_sync_info() : state((int)StateInit) {}
+
+};
+WRITE_CLASS_ENCODER(rgw_bucket_shard_sync_info)
+
+
+class RGWRemoteBucketLog : public RGWCoroutinesManager {
+  RGWRados *store;
+  RGWRESTConn *conn;
+  string source_zone;
+  string bucket_name;
+  string bucket_id;
+  int shard_id;
+
+  RGWBucketSyncStatusManager *status_manager;
+  RGWAsyncRadosProcessor *async_rados;
+  RGWHTTPManager *http_manager;
+
+  RGWDataSyncEnv sync_env;
+
+  RGWBucketSyncCR *sync_cr;
+
+public:
+  RGWRemoteBucketLog(RGWRados *_store, RGWBucketSyncStatusManager *_sm,
+                     RGWAsyncRadosProcessor *_async_rados, RGWHTTPManager *_http_manager) : RGWCoroutinesManager(_store->ctx(), _store->get_cr_registry()), store(_store),
+                                       conn(NULL), shard_id(0),
+                                       status_manager(_sm), async_rados(_async_rados), http_manager(_http_manager),
+                                       sync_cr(NULL) {}
+
+  int init(const string& _source_zone, RGWRESTConn *_conn, const string& _bucket_name, const string& _bucket_id, int _shard_id, RGWSyncErrorLogger *_error_logger);
+  void finish();
+
+  RGWCoroutine *read_sync_status_cr(rgw_bucket_shard_sync_info *sync_status);
+  RGWCoroutine *init_sync_status_cr();
+  RGWCoroutine *run_sync_cr();
+
+  void wakeup();
+};
+
+class RGWBucketSyncStatusManager {
+  RGWRados *store;
+  librados::IoCtx ioctx;
+
+  RGWCoroutinesManager cr_mgr;
+
+  RGWAsyncRadosProcessor *async_rados;
+  RGWHTTPManager http_manager;
+
+  string source_zone;
+  RGWRESTConn *conn;
+  RGWSyncErrorLogger *error_logger;
+
+  string bucket_name;
+  string bucket_id;
+
+  map<int, RGWRemoteBucketLog *> source_logs;
+
+  string source_status_oid;
+  string source_shard_status_oid_prefix;
+  rgw_obj source_status_obj;
+
+  map<int, rgw_bucket_shard_sync_info> sync_status;
+  rgw_obj status_obj;
+
+  int num_shards;
+
+public:
+  RGWBucketSyncStatusManager(RGWRados *_store, const string& _source_zone,
+                             const string& _bucket_name, const string& _bucket_id) : store(_store),
+                                                                                     cr_mgr(_store->ctx(), _store->get_cr_registry()),
+                                                                                     async_rados(NULL),
+                                                                                     http_manager(store->ctx(), cr_mgr.get_completion_mgr()),
+                                                                                     source_zone(_source_zone),
+                                                                                     conn(NULL), error_logger(NULL),
+                                                                                     bucket_name(_bucket_name), bucket_id(_bucket_id),
+                                                                                     num_shards(0) {}
+  ~RGWBucketSyncStatusManager();
+
+  int init();
+
+  map<int, rgw_bucket_shard_sync_info>& get_sync_status() { return sync_status; }
+  int init_sync_status();
+
+  static string status_oid(const string& source_zone, const string& bucket_name, const string& bucket_id, int shard_id);
+
+  int read_sync_status();
+  int run();
+};
+
+
+#endif
diff --git a/src/rgw/rgw_dencoder.cc b/src/rgw/rgw_dencoder.cc
index 36fd0cc..0b4fdf5 100644
--- a/src/rgw/rgw_dencoder.cc
+++ b/src/rgw/rgw_dencoder.cc
@@ -419,11 +419,11 @@ void RGWBucketInfo::generate_test_instances(list<RGWBucketInfo*>& o)
   o.push_back(new RGWBucketInfo);
 }
 
-void RGWRegion::generate_test_instances(list<RGWRegion*>& o)
+void RGWZoneGroup::generate_test_instances(list<RGWZoneGroup*>& o)
 {
-  RGWRegion *r = new RGWRegion;
+  RGWZoneGroup *r = new RGWZoneGroup;
   o.push_back(r);
-  o.push_back(new RGWRegion);
+  o.push_back(new RGWZoneGroup);
 }
 
 void RGWZone::generate_test_instances(list<RGWZone*> &o)
diff --git a/src/rgw/rgw_fcgi.h b/src/rgw/rgw_fcgi.h
index 92171f4..d83e03f 100644
--- a/src/rgw/rgw_fcgi.h
+++ b/src/rgw/rgw_fcgi.h
@@ -4,13 +4,18 @@
 #ifndef CEPH_RGW_FCGI_H
 #define CEPH_RGW_FCGI_H
 
-#include "rgw_client_io.h"
+#include "acconfig.h"
+#ifdef FASTCGI_INCLUDE_DIR
+# include "fastcgi/fcgiapp.h"
+#else
+# include "fcgiapp.h"
+#endif
 
+#include "rgw_client_io.h"
 
 struct FCGX_Request;
 
-
-class RGWFCGX : public RGWClientIO
+class RGWFCGX : public RGWStreamIO
 {
   FCGX_Request *fcgx;
 
@@ -31,5 +36,4 @@ public:
   void flush();
 };
 
-
 #endif
diff --git a/src/rgw/rgw_fcgi_process.cc b/src/rgw/rgw_fcgi_process.cc
new file mode 100644
index 0000000..fd6cae6
--- /dev/null
+++ b/src/rgw/rgw_fcgi_process.cc
@@ -0,0 +1,128 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+
+#include "common/errno.h"
+#include "common/Throttle.h"
+#include "common/WorkQueue.h"
+
+#include "rgw_rados.h"
+#include "rgw_rest.h"
+#include "rgw_frontend.h"
+#include "rgw_request.h"
+#include "rgw_process.h"
+#include "rgw_loadgen.h"
+#include "rgw_client_io.h"
+
+#define dout_subsys ceph_subsys_rgw
+
+void RGWFCGXProcess::run()
+{
+  string socket_path;
+  string socket_port;
+  string socket_host;
+
+  conf->get_val("socket_path", "", &socket_path);
+  conf->get_val("socket_port", g_conf->rgw_port, &socket_port);
+  conf->get_val("socket_host", g_conf->rgw_host, &socket_host);
+
+  if (socket_path.empty() && socket_port.empty() && socket_host.empty()) {
+    socket_path = g_conf->rgw_socket_path;
+    if (socket_path.empty()) {
+      dout(0) << "ERROR: no socket server point defined, cannot "
+	"start fcgi frontend" << dendl;
+      return;
+    }
+  }
+
+  if (!socket_path.empty()) {
+    string path_str = socket_path;
+
+    /* this is necessary, as FCGX_OpenSocket might not return an
+	 * error, but rather ungracefully exit */
+    int fd = open(path_str.c_str(), O_CREAT, 0644);
+    if (fd < 0) {
+      int err = errno;
+      /* ENXIO is actually expected, we'll get that if we try to open
+	   * a unix domain socket */
+      if (err != ENXIO) {
+		  dout(0) << "ERROR: cannot create socket: path=" << path_str
+				  << " error=" << cpp_strerror(err) << dendl;
+		  return;
+      }
+    } else {
+		close(fd);
+    }
+
+    const char *path = path_str.c_str();
+    sock_fd = FCGX_OpenSocket(path, SOCKET_BACKLOG);
+    if (sock_fd < 0) {
+      dout(0) << "ERROR: FCGX_OpenSocket (" << path << ") returned "
+	      << sock_fd << dendl;
+      return;
+    }
+    if (chmod(path, 0777) < 0) {
+      dout(0) << "WARNING: couldn't set permissions on unix domain socket"
+	      << dendl;
+    }
+  } else if (!socket_port.empty()) {
+    string bind = socket_host + ":" + socket_port;
+    sock_fd = FCGX_OpenSocket(bind.c_str(), SOCKET_BACKLOG);
+    if (sock_fd < 0) {
+      dout(0) << "ERROR: FCGX_OpenSocket (" << bind.c_str() << ") returned "
+	      << sock_fd << dendl;
+      return;
+    }
+  }
+
+  m_tp.start();
+
+  FCGX_Request fcgx_reqs[max_connections];
+
+  QueueRing<FCGX_Request*> qr(max_connections);
+  for (int i = 0; i < max_connections; i++) {
+    FCGX_Request* fcgx = &fcgx_reqs[i];
+    FCGX_InitRequest(fcgx, sock_fd, 0);
+    qr.enqueue(fcgx);
+  }
+
+  for (;;) {
+    RGWFCGXRequest* req = new RGWFCGXRequest(store->get_new_req_id(), &qr);
+    dout(10) << "allocated request req=" << hex << req << dec << dendl;
+    req_throttle.get(1);
+    int ret = FCGX_Accept_r(req->fcgx);
+    if (ret < 0) {
+      delete req;
+      dout(0) << "ERROR: FCGX_Accept_r returned " << ret << dendl;
+      req_throttle.put(1);
+      break;
+    }
+    req_wq.queue(req);
+  }
+
+  m_tp.drain(&req_wq);
+  m_tp.stop();
+
+  dout(20) << "cleaning up fcgx connections" << dendl;
+
+  for (int i = 0; i < max_connections; i++) {
+    FCGX_Finish_r(&fcgx_reqs[i]);
+  }
+} /* RGWFCGXProcess::run */
+
+void RGWFCGXProcess::handle_request(RGWRequest* r)
+{
+  RGWFCGXRequest* req = static_cast<RGWFCGXRequest*>(r);
+  FCGX_Request* fcgx = req->fcgx;
+  RGWFCGX client_io(fcgx);
+
+ 
+  int ret = process_request(store, rest, req, &client_io, olog);
+  if (ret < 0) {
+    /* we don't really care about return code */
+    dout(20) << "process_request() returned " << ret << dendl;
+  }
+
+  FCGX_Finish_r(fcgx);
+
+  delete req;
+} /* RGWFCGXProcess::handle_request */
diff --git a/src/rgw/rgw_file.cc b/src/rgw/rgw_file.cc
new file mode 100644
index 0000000..53f764f
--- /dev/null
+++ b/src/rgw/rgw_file.cc
@@ -0,0 +1,1221 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+
+#include "include/rados/rgw_file.h"
+
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include "rgw_lib.h"
+#include "rgw_rados.h"
+#include "rgw_resolve.h"
+#include "rgw_op.h"
+#include "rgw_rest.h"
+#include "rgw_acl.h"
+#include "rgw_acl_s3.h"
+#include "rgw_frontend.h"
+#include "rgw_request.h"
+#include "rgw_process.h"
+#include "rgw_rest_user.h"
+#include "rgw_rest_s3.h"
+#include "rgw_os_lib.h"
+#include "rgw_auth_s3.h"
+#include "rgw_user.h"
+#include "rgw_bucket.h"
+
+#include "rgw_file.h"
+#include "rgw_lib_frontend.h"
+
+#define dout_subsys ceph_subsys_rgw
+
+using namespace rgw;
+
+namespace rgw {
+
+  extern RGWLib rgwlib;
+
+  const string RGWFileHandle::root_name = "/";
+
+  atomic<uint32_t> RGWLibFS::fs_inst;
+
+  LookupFHResult RGWLibFS::stat_bucket(RGWFileHandle* parent,
+				       const char *path, uint32_t flags)
+  {
+    LookupFHResult fhr{nullptr, 0};
+    std::string bucket_name{path};
+    RGWStatBucketRequest req(cct, get_user(), bucket_name);
+
+    int rc = rgwlib.get_fe()->execute_req(&req);
+    if ((rc == 0) &&
+	(req.get_ret() == 0) &&
+	(req.matched())) {
+      fhr = lookup_fh(parent, path,
+		      RGWFileHandle::FLAG_CREATE|
+		      RGWFileHandle::FLAG_BUCKET);
+      if (get<0>(fhr)) {
+	RGWFileHandle* rgw_fh = get<0>(fhr);
+	rgw_fh->set_times(req.get_ctime());
+      }
+    }
+    return fhr;
+  }
+
+  LookupFHResult RGWLibFS::stat_leaf(RGWFileHandle* parent,
+				     const char *path,
+				     uint32_t flags)
+  {
+    /* find either-of <object_name>, <object_name/>, only one of
+     * which should exist;  atomicity? */
+    using std::get;
+
+    LookupFHResult fhr{nullptr, 0};
+#if 0
+    RGWFileHandle::directory* d = parent->get_directory();
+    if (! d->name_cache.empty()) {
+      RGWFileHandle::dirent_string name{path};
+      const auto& diter = d->name_cache.find(name);
+      if (diter != d->name_cache.end()) {
+	fhr = lookup_fh(parent, path,
+			RGWFileHandle::FLAG_CREATE|
+			((diter->second == RGW_FS_TYPE_DIRECTORY) ?
+			  RGWFileHandle::FLAG_DIRECTORY :
+			  RGWFileHandle::FLAG_NONE));
+	if (get<0>(fhr))
+	  return fhr;
+      }
+    }
+#endif
+    std::string object_name{path};
+    for (auto ix : { 0, 1 }) {
+      switch (ix) {
+      case 0:
+      {
+	std::string obj_name{parent->relative_object_name()};
+	if ((obj_name.length() > 0) &&
+	    (obj_name.back() != '/'))
+	  obj_name += "/";
+	obj_name += path;
+	RGWStatObjRequest req(cct, get_user(),
+			      parent->bucket_name(), obj_name,
+			      RGWStatObjRequest::FLAG_NONE);
+	int rc = rgwlib.get_fe()->execute_req(&req);
+	if ((rc == 0) &&
+	    (req.get_ret() == 0)) {
+	  fhr = lookup_fh(parent, path, RGWFileHandle::FLAG_CREATE);
+	  if (get<0>(fhr)) {
+	    RGWFileHandle* rgw_fh = get<0>(fhr);
+	    rgw_fh->set_size(req.get_size());
+	    rgw_fh->set_mtime(real_clock::to_timespec(req.get_mtime()));
+	  }
+	  goto done;
+	}
+      }
+      break;
+      case 1:
+      {
+	RGWStatLeafRequest req(cct, get_user(), parent, object_name);
+	int rc = rgwlib.get_fe()->execute_req(&req);
+	if ((rc == 0) &&
+	    (req.get_ret() == 0)) {
+	  if (req.matched) {
+	    fhr = lookup_fh(parent, path,
+			    RGWFileHandle::FLAG_CREATE|
+			    ((req.is_dir) ?
+			      RGWFileHandle::FLAG_DIRECTORY :
+			      RGWFileHandle::FLAG_NONE));
+	    /* XXX we don't have an object--in general, there need not
+	     * be one (just a path segment in some other object).  In
+	     * actual leaf an object exists, but we'd need another round
+	     * trip to get attrs */
+	    if (get<0>(fhr)) {
+	      /* for now use the parent object's mtime */
+	      RGWFileHandle* rgw_fh = get<0>(fhr);
+	      rgw_fh->set_mtime(parent->get_mtime());
+	    }
+	  }
+	}
+      }
+      break;
+      default:
+	/* not reached */
+	break;
+      }
+    }
+  done:
+    return fhr;
+  } /* RGWLibFS::stat_leaf */
+
+  int RGWLibFS::unlink(RGWFileHandle* parent, const char *name)
+  {
+    int rc = 0;
+
+    /* atomicity */
+    LookupFHResult fhr = lookup_fh(parent, name, RGWFileHandle::FLAG_LOCK);
+    RGWFileHandle* rgw_fh = get<0>(fhr);
+
+    if (parent->is_root()) {
+      /* XXXX remove uri and deal with bucket and object names */
+      string uri = "/";
+      uri += name;
+      RGWDeleteBucketRequest req(cct, get_user(), uri);
+      rc = rgwlib.get_fe()->execute_req(&req);
+      if (! rc) {
+	rc = req.get_ret();
+      }
+    } else {
+      /*
+       * leaf object
+       */
+      if (! rgw_fh) {
+	/* XXX for now, peform a hard lookup to deduce the type of
+	 * object to be deleted ("foo" vs. "foo/")--also, ensures
+	 * atomicity at this endpoint */
+	struct rgw_file_handle *fh;
+	rc = rgw_lookup(get_fs(), parent->get_fh(), name, &fh,
+			RGW_LOOKUP_FLAG_NONE);
+	if (!! rc)
+	  return rc;
+
+	/* rgw_fh ref+ */
+	rgw_fh = get_rgwfh(fh);
+	rgw_fh->mtx.lock();
+      }
+
+      std::string oname = rgw_fh->relative_object_name();
+      if (rgw_fh->is_dir())
+	oname += "/";
+      RGWDeleteObjRequest req(cct, get_user(), parent->bucket_name(),
+			      oname);
+      rc = rgwlib.get_fe()->execute_req(&req);
+      if (! rc) {
+	rc = req.get_ret();
+      }
+    }
+
+    rgw_fh->flags |= RGWFileHandle::FLAG_DELETED;
+    fh_cache.remove(rgw_fh->fh.fh_hk.object, rgw_fh, cohort::lru::FLAG_NONE);
+    rgw_fh->mtx.unlock();
+    unref(rgw_fh);
+
+    return rc;
+  } /* RGWLibFS::unlink */
+
+  int RGWLibFS::rename(RGWFileHandle* src_fh, RGWFileHandle* dst_fh,
+		       const char *_src_name, const char *_dst_name)
+
+  {
+    /* XXX initial implementation: try-copy, and delete if copy
+     * succeeds */
+    int rc = -EINVAL;
+
+    std::string src_name{_src_name};
+    std::string dst_name{_dst_name};
+
+    /* atomicity */
+    LookupFHResult fhr = lookup_fh(src_fh, _src_name, RGWFileHandle::FLAG_LOCK);
+    RGWFileHandle* rgw_fh = get<0>(fhr);
+
+    for (int ix : {0, 1}) {
+      switch (ix) {
+      case 0:
+      {
+	RGWCopyObjRequest req(cct, get_user(), src_fh, dst_fh, src_name,
+			      dst_name);
+	int rc = rgwlib.get_fe()->execute_req(&req);
+	if ((rc != 0) ||
+	    ((rc = req.get_ret()) != 0)) {
+	  goto out;
+	}
+      }
+      break;
+      case 1:
+      {
+	RGWDeleteObjRequest req(cct, get_user(), src_fh->bucket_name(),
+				src_name);
+	rc = rgwlib.get_fe()->execute_req(&req);
+	if (! rc) {
+	  rc = req.get_ret();
+	  goto out;
+	}
+      }
+      break;
+      default:
+	abort();
+      } /* switch */
+    } /* ix */
+  out:
+    if (rgw_fh) {
+      rgw_fh->flags |= RGWFileHandle::FLAG_DELETED;
+      fh_cache.remove(rgw_fh->fh.fh_hk.object, rgw_fh, cohort::lru::FLAG_NONE);
+      rgw_fh->mtx.unlock();
+      unref(rgw_fh);
+    }
+    return rc;
+  } /* RGWLibFS::rename */
+
+  int RGWLibFS::getattr(RGWFileHandle* rgw_fh, struct stat* st)
+  {
+    switch(rgw_fh->fh.fh_type) {
+    case RGW_FS_TYPE_FILE:
+      break;
+    case RGW_FS_TYPE_DIRECTORY:
+    default:
+      break;
+    };
+
+    return rgw_fh->stat(st);
+  } /* RGWLibFS::getattr */
+
+  void RGWLibFS::close()
+  {
+    state.flags |= FLAG_CLOSED;
+
+    class ObjUnref
+    {
+      RGWLibFS* fs;
+    public:
+      ObjUnref(RGWLibFS* fs) : fs(fs) {}
+      void operator()(RGWFileHandle* fh) const {
+	lsubdout(fs->get_context(), rgw, 5)
+	  << __func__
+	  << fh->name
+	  << " before ObjUnref refs=" << fh->get_refcnt()
+	  << dendl;
+	fs->fh_lru.unref(fh, cohort::lru::FLAG_NONE);
+      }
+    };
+
+    /* force cache drain, forces objects to evict */
+    fh_cache.drain(ObjUnref(this),
+		  RGWFileHandle::FHCache::FLAG_LOCK);
+    rgwlib.get_fe()->get_process()->unregister_fs(this);
+    rele();
+  } /* RGWLibFS::close */
+
+  void RGWLibFS::gc()
+  {
+    using std::get;
+    using directory = RGWFileHandle::directory;
+
+    static constexpr uint32_t max_ev = 24;
+    static constexpr uint16_t expire_s = 300; /* 5m */
+
+    struct timespec now;
+    event_vector ve;
+    bool stop = false;
+    std::deque<event> &events = state.events;
+    (void) clock_gettime(CLOCK_MONOTONIC_COARSE, &now);
+
+    do {
+      {
+	lock_guard guard(state.mtx); /* LOCKED */
+	uint32_t _max_ev =
+	  (events.size() < 500) ? max_ev : (events.size() / 4);
+	for (uint32_t ix = 0; (ix < _max_ev) && (events.size() > 0); ++ix) {
+	  event& ev = events.front();
+	  if (ev.ts.tv_sec < (now.tv_sec + expire_s)) {
+	    stop = true;
+	    break;
+	  }
+	  ve.push_back(ev);
+	  events.pop_front();
+	}
+      } /* anon */
+      /* !LOCKED */
+      for (auto& ev : ve) {
+	if (likely(ev.t == event::type::READDIR)) {
+	  RGWFileHandle* rgw_fh = lookup_handle(ev.fhk.fh_hk);
+	  if (rgw_fh) {
+	    RGWFileHandle::directory* d;
+	    if (unlikely(! rgw_fh->is_dir())) {
+	      lsubdout(get_context(), rgw, 0)
+		<< __func__
+		<< " BUG non-directory found with READDIR event "
+		<< "(" << rgw_fh->bucket_name() << ","
+		<< rgw_fh->object_name() << ")"
+		<< dendl;
+	      goto rele;
+	    }
+	    /* clear state */
+	    d = get<directory>(&rgw_fh->variant_type);
+	    if (d) {
+	      lock_guard guard(rgw_fh->mtx);
+	      d->clear_state();
+	    }
+	  rele:
+	    unref(rgw_fh);
+	  } /* rgw_fh */
+	} /* event::type::READDIR */
+      } /* ev */
+    } while (! stop);
+  } /* RGWLibFS::gc */
+
+  bool RGWFileHandle::reclaim() {
+    fs->fh_cache.remove(fh.fh_hk.object, this, cohort::lru::FLAG_NONE);
+    return true;
+  } /* RGWFileHandle::reclaim */
+
+  int RGWFileHandle::readdir(rgw_readdir_cb rcb, void *cb_arg, uint64_t *offset,
+			     bool *eof, uint32_t flags)
+  {
+    using event = RGWLibFS::event;
+    int rc = 0;
+    struct timespec now;
+    CephContext* cct = fs->get_context();
+    directory* d = get_directory(); /* already type-checked */
+
+    (void) clock_gettime(CLOCK_MONOTONIC_COARSE, &now); /* !LOCKED */
+
+    if (flags & RGW_READDIR_FLAG_DOTDOT) {
+      /* send '.' and '..' with their NFS-defined offsets */
+      rcb(".", cb_arg, 1);
+      rcb("..", cb_arg, 2);
+    }
+
+    if (is_root()) {
+      RGWListBucketsRequest req(cct, fs->get_user(), this, rcb, cb_arg,
+				offset);
+      rc = rgwlib.get_fe()->execute_req(&req);
+      if (! rc) {
+	set_nlink(2 + d->name_cache.size());
+	state.atime = now;
+	*eof = req.eof();
+	event ev(event::type::READDIR, get_key(), state.atime);
+	fs->state.push_event(ev);
+      }
+    } else {
+      rgw_obj_key marker{"", ""};
+      RGWReaddirRequest req(cct, fs->get_user(), this, rcb, cb_arg, offset);
+      rc = rgwlib.get_fe()->execute_req(&req);
+      if (! rc) {
+	state.atime = now;
+	set_nlink(2 + d->name_cache.size());
+	*eof = req.eof();
+	event ev(event::type::READDIR, get_key(), state.atime);
+	fs->state.push_event(ev);
+      }
+    }
+    return rc;
+  } /* RGWFileHandle::readdir */
+
+  int RGWFileHandle::write(uint64_t off, size_t len, size_t *bytes_written,
+			   void *buffer)
+  {
+    using std::get;
+    lock_guard guard(mtx);
+
+    int rc = 0;
+
+    file* f = get<file>(&variant_type);
+    if (! f)
+      return -EISDIR;
+
+    if (! f->write_req) {
+      /* start */
+      std::string object_name = relative_object_name();
+      f->write_req =
+	new RGWWriteRequest(fs->get_context(), fs->get_user(), this,
+			    bucket_name(), object_name);
+      rc = rgwlib.get_fe()->start_req(f->write_req);
+    }
+
+    buffer::list bl;
+    /* XXXX */
+#if 0
+    bl.push_back(
+      buffer::create_static(len, static_cast<char*>(buffer)));
+#else
+    bl.push_back(
+      buffer::copy(static_cast<char*>(buffer), len));
+#endif
+
+    f->write_req->put_data(off, bl);
+    rc = f->write_req->exec_continue();
+
+    size_t min_size = off + len;
+    if (min_size > get_size())
+      set_size(min_size);
+
+    *bytes_written = (rc == 0) ? len : 0;
+    return rc;
+  } /* RGWFileHandle::write */
+
+  int RGWFileHandle::close()
+  {
+    lock_guard guard(mtx);
+
+    int rc = 0;
+    file* f = get<file>(&variant_type);
+    if (f && (f->write_req)) {
+      rc = rgwlib.get_fe()->finish_req(f->write_req);
+      if (! rc) {
+	rc = f->write_req->get_ret();
+      }
+      delete f->write_req;
+      f->write_req = nullptr;
+    }
+
+    flags &= ~FLAG_OPEN;
+    return rc;
+  } /* RGWFileHandle::close */
+
+  RGWFileHandle::file::~file()
+  {
+    delete write_req;
+  }
+
+  int RGWWriteRequest::exec_start() {
+    struct req_state* s = get_state();
+
+    /* not obviously supportable */
+    assert(! dlo_manifest);
+    assert(! slo_info);
+
+    perfcounter->inc(l_rgw_put);
+    op_ret = -EINVAL;
+
+    if (s->object.empty()) {
+      ldout(s->cct, 0) << __func__ << " called on empty object" << dendl;
+      goto done;
+    }
+
+    op_ret = get_params();
+    if (op_ret < 0)
+      goto done;
+
+    op_ret = get_system_versioning_params(s, &olh_epoch, &version_id);
+    if (op_ret < 0) {
+      goto done;
+    }
+
+    /* user-supplied MD5 check skipped (not supplied) */
+    /* early quota check skipped--we don't have size yet */
+    /* skipping user-supplied etag--we might have one in future, but
+     * like data it and other attrs would arrive after open */
+    processor = select_processor(*static_cast<RGWObjectCtx *>(s->obj_ctx),
+				 &multipart);
+    op_ret = processor->prepare(get_store(), NULL);
+
+  done:
+    return op_ret;
+  } /* exec_start */
+
+  int RGWWriteRequest::exec_continue()
+  {
+    struct req_state* s = get_state();
+    op_ret = 0;
+
+#if 0 // TODO: check offsets
+    if (next_off != last_off)
+      return -EIO;
+#endif
+    size_t len = data.length();
+    if (! len)
+      return 0;
+
+    /* XXX we are currently synchronous--supplied data buffers cannot
+     * be used after the caller returns  */
+    bool need_to_wait = true;
+    bufferlist orig_data;
+
+    if (need_to_wait) {
+      orig_data = data;
+    }
+
+    op_ret = put_data_and_throttle(processor, data, ofs,
+				   (true /* md5 */ ? &hash : NULL),
+				   need_to_wait);
+    if (op_ret < 0) {
+      if (!need_to_wait || op_ret != -EEXIST) {
+	ldout(s->cct, 20) << "processor->thottle_data() returned ret="
+			  << op_ret << dendl;
+	goto done;
+      }
+
+      ldout(s->cct, 5) << "NOTICE: processor->throttle_data() returned -EEXIST, need to restart write" << dendl;
+
+      /* restore original data */
+      data.swap(orig_data);
+
+      /* restart processing with different oid suffix */
+      dispose_processor(processor);
+      processor = select_processor(*static_cast<RGWObjectCtx *>(s->obj_ctx),
+				   &multipart);
+
+      string oid_rand;
+      char buf[33];
+      gen_rand_alphanumeric(get_store()->ctx(), buf, sizeof(buf) - 1);
+      oid_rand.append(buf);
+
+      op_ret = processor->prepare(get_store(), &oid_rand);
+      if (op_ret < 0) {
+	ldout(s->cct, 0) << "ERROR: processor->prepare() returned "
+			 << op_ret << dendl;
+	goto done;
+      }
+
+      op_ret = put_data_and_throttle(processor, data, ofs, NULL, false);
+      if (op_ret < 0) {
+	goto done;
+      }
+    }
+    bytes_written += len;
+
+  done:
+    return op_ret;
+  } /* exec_continue */
+
+  int RGWWriteRequest::exec_finish()
+  {
+    bufferlist bl, aclbl;
+    map<string, bufferlist> attrs;
+    map<string, string>::iterator iter;
+    char calc_md5[CEPH_CRYPTO_MD5_DIGESTSIZE * 2 + 1];
+    unsigned char m[CEPH_CRYPTO_MD5_DIGESTSIZE];
+    struct req_state* s = get_state();
+
+    s->obj_size = ofs; // XXX check ofs
+    perfcounter->inc(l_rgw_put_b, s->obj_size);
+
+    op_ret = get_store()->check_quota(s->bucket_owner.get_id(), s->bucket,
+				      user_quota, bucket_quota, s->obj_size);
+    if (op_ret < 0) {
+      goto done;
+    }
+
+    processor->complete_hash(&hash);
+    hash.Final(m);
+
+    buf_to_hex(m, CEPH_CRYPTO_MD5_DIGESTSIZE, calc_md5);
+    etag = calc_md5;
+
+    policy.encode(aclbl);
+    attrs[RGW_ATTR_ACL] = aclbl;
+
+    bl.append(etag.c_str(), etag.size() + 1);
+    attrs[RGW_ATTR_ETAG] = bl;
+
+    for (iter = s->generic_attrs.begin(); iter != s->generic_attrs.end();
+	 ++iter) {
+      bufferlist& attrbl = attrs[iter->first];
+      const string& val = iter->second;
+      attrbl.append(val.c_str(), val.size() + 1);
+    }
+
+    rgw_get_request_metadata(s->cct, s->info, attrs);
+    encode_delete_at_attr(delete_at, attrs);
+
+    /* Add a custom metadata to expose the information whether an object
+     * is an SLO or not. Appending the attribute must be performed AFTER
+     * processing any input from user in order to prohibit overwriting. */
+    if (unlikely(!! slo_info)) {
+      bufferlist slo_userindicator_bl;
+      ::encode("True", slo_userindicator_bl);
+      attrs[RGW_ATTR_SLO_UINDICATOR] = slo_userindicator_bl;
+    }
+
+    op_ret = processor->complete(etag, &mtime, real_time(), attrs, delete_at, if_match,
+				 if_nomatch);
+    if (! op_ret) {
+      /* update stats */
+      rgw_fh->set_mtime(real_clock::to_timespec(mtime));
+      rgw_fh->set_size(bytes_written);
+    }
+
+  done:
+    dispose_processor(processor);
+    perfcounter->tinc(l_rgw_put_lat,
+		      (ceph_clock_now(s->cct) - s->time));
+    return op_ret;
+  } /* exec_finish */
+
+} /* namespace rgw */
+
+/* librgw */
+extern "C" {
+
+/*
+ attach rgw namespace
+*/
+  int rgw_mount(librgw_t rgw, const char *uid, const char *acc_key,
+		const char *sec_key, struct rgw_fs **rgw_fs,
+		uint32_t flags)
+{
+  int rc = 0;
+
+  /* stash access data for "mount" */
+  RGWLibFS* new_fs = new RGWLibFS(static_cast<CephContext*>(rgw), uid, acc_key,
+				  sec_key);
+  assert(new_fs);
+
+  rc = new_fs->authorize(rgwlib.get_store());
+  if (rc != 0) {
+    delete new_fs;
+    return -EINVAL;
+  }
+
+  /* register fs for shared gc */
+  rgwlib.get_fe()->get_process()->register_fs(new_fs);
+
+  struct rgw_fs *fs = new_fs->get_fs();
+  fs->rgw = rgw;
+
+  /* XXX we no longer assume "/" is unique, but we aren't tracking the
+   * roots atm */
+
+  *rgw_fs = fs;
+
+  return 0;
+}
+
+/*
+ detach rgw namespace
+*/
+int rgw_umount(struct rgw_fs *rgw_fs, uint32_t flags)
+{
+  RGWLibFS *fs = static_cast<RGWLibFS*>(rgw_fs->fs_private);
+  fs->close();
+  fs->rele();
+  return 0;
+}
+
+/*
+  get filesystem attributes
+*/
+int rgw_statfs(struct rgw_fs *rgw_fs,
+	       struct rgw_file_handle *parent_fh,
+	       struct rgw_statvfs *vfs_st, uint32_t flags)
+{
+  RGWLibFS *fs = static_cast<RGWLibFS*>(rgw_fs->fs_private);
+
+  /* XXX for now, just publish a huge capacity and
+   * limited utiliztion */
+  vfs_st->f_bsize = 1024*1024 /* 1M */;
+  vfs_st->f_frsize = 1024;    /* minimal allocation unit (who cares) */
+  vfs_st->f_blocks = UINT64_MAX;
+  vfs_st->f_bfree = UINT64_MAX;
+  vfs_st->f_bavail = UINT64_MAX;
+  vfs_st->f_files = 1024; /* object count, do we have an est? */
+  vfs_st->f_ffree = UINT64_MAX;
+  vfs_st->f_fsid[0] = fs->get_inst();
+  vfs_st->f_fsid[1] = fs->get_inst();
+  vfs_st->f_flag = 0;
+  vfs_st->f_namemax = 4096;
+  return 0;
+}
+
+/*
+  generic create -- create an empty regular file
+*/
+int rgw_create(struct rgw_fs *rgw_fs,
+	       struct rgw_file_handle *parent_fh,
+	       const char *name, mode_t mode, struct stat *st,
+	       struct rgw_file_handle **fh, uint32_t flags)
+{
+  RGWLibFS *fs = static_cast<RGWLibFS*>(rgw_fs->fs_private);
+  CephContext* cct = static_cast<CephContext*>(rgw_fs->rgw);
+
+  RGWFileHandle* parent = get_rgwfh(parent_fh);
+  if ((! parent) ||
+      (parent->is_root()) ||
+      (parent->is_file())) {
+    /* bad parent */
+    return -EINVAL;
+  }
+
+  using std::get;
+
+  rgw_file_handle *lfh;
+  int rc = rgw_lookup(rgw_fs, parent_fh, name, &lfh,
+		      RGW_LOOKUP_FLAG_NONE);
+  if (! rc) {
+    /* conflict! */
+    rc = rgw_fh_rele(rgw_fs, lfh, RGW_FH_RELE_FLAG_NONE);
+    return -EEXIST;
+  } else {
+    /* expand and check name */
+    std::string obj_name{parent->relative_object_name()};
+    if ((obj_name.size() > 0) &&
+	(obj_name.back() != '/'))
+      obj_name += "/";
+    obj_name += name;
+    if (! valid_s3_object_name(obj_name)) {
+      return -EINVAL;
+    } else {
+      /* create it */
+      buffer::list bl;
+      RGWPutObjRequest req(cct, fs->get_user(), parent->bucket_name(),
+			   obj_name, bl);
+      rc = rgwlib.get_fe()->execute_req(&req);
+      int rc2 = req.get_ret();
+
+      if ((rc == 0) &&
+	  (rc2 == 0)) {
+	/* XXX atomicity */
+	LookupFHResult fhr = fs->lookup_fh(parent, name,
+					   RGWFileHandle::FLAG_CREATE);
+	RGWFileHandle* rgw_fh = get<0>(fhr);
+	if (rgw_fh) {
+	  if (get<1>(fhr) & RGWFileHandle::FLAG_CREATE) {
+	    /* fill in stat data */
+	    rgw_fh->set_times(real_clock::now());
+	    rgw_fh->open_for_create(); // XXX needed?
+	  }
+	  (void) rgw_fh->stat(st);
+	  struct rgw_file_handle *rfh = rgw_fh->get_fh();
+	  *fh = rfh;
+	} else
+	  rc = -EIO;
+      }
+    }
+  }
+
+  return rc;
+}
+
+/*
+  create a new directory
+*/
+int rgw_mkdir(struct rgw_fs *rgw_fs,
+	      struct rgw_file_handle *parent_fh,
+	      const char *name, mode_t mode, struct stat *st,
+	      struct rgw_file_handle **fh, uint32_t flags)
+{
+  int rc, rc2;
+
+  RGWLibFS *fs = static_cast<RGWLibFS*>(rgw_fs->fs_private);
+  CephContext* cct = static_cast<CephContext*>(rgw_fs->rgw);
+
+  RGWFileHandle* parent = get_rgwfh(parent_fh);
+  if (! parent) {
+    /* bad parent */
+    return -EINVAL;
+  }
+
+  LookupFHResult fhr;
+  RGWFileHandle* rgw_fh = nullptr;
+
+  if (parent->is_root()) {
+    /* bucket */
+    string bname{name};
+    /* enforce S3 name restrictions */
+    rc = valid_s3_bucket_name(bname, false /* relaxed */);
+    if (rc != 0)
+      return -EINVAL;
+    string uri = "/" + bname; /* XXX get rid of URI some day soon */
+    RGWCreateBucketRequest req(cct, fs->get_user(), uri);
+    rc = rgwlib.get_fe()->execute_req(&req);
+    rc2 = req.get_ret();
+  } else {
+    /* create an object representing the directory */
+    buffer::list bl;
+    string dir_name = /* XXX get rid of this some day soon, too */
+      parent->relative_object_name();
+    /* creating objects w/leading '/' makes a mess */
+    if ((dir_name.size() > 0) &&
+	(dir_name.back() != '/'))
+      dir_name += "/";
+    dir_name += name;
+    dir_name += "/";
+    RGWPutObjRequest req(cct, fs->get_user(), parent->bucket_name(),
+			 dir_name, bl);
+    rc = rgwlib.get_fe()->execute_req(&req);
+    rc2 = req.get_ret();
+  }
+
+  if ((rc == 0) &&
+      (rc2 == 0)) {
+    fhr = fs->lookup_fh(parent, name,
+			RGWFileHandle::FLAG_CREATE|
+			RGWFileHandle::FLAG_DIRECTORY);
+    rgw_fh = get<0>(fhr);
+    if (rgw_fh) {
+      /* XXX unify timestamps */
+      rgw_fh->set_times(real_clock::now());
+      rgw_fh->stat(st);
+      struct rgw_file_handle *rfh = rgw_fh->get_fh();
+      *fh = rfh;
+    } else
+      rc = -EIO;
+  }
+
+  return rc;
+}
+
+/*
+  rename object
+*/
+int rgw_rename(struct rgw_fs *rgw_fs,
+	       struct rgw_file_handle *src, const char* src_name,
+	       struct rgw_file_handle *dst, const char* dst_name,
+	       uint32_t flags)
+{
+  RGWLibFS *fs = static_cast<RGWLibFS*>(rgw_fs->fs_private);
+
+  RGWFileHandle* src_fh = get_rgwfh(src);
+  RGWFileHandle* dst_fh = get_rgwfh(dst);
+
+  return fs->rename(src_fh, dst_fh, src_name, dst_name);
+}
+
+/*
+  remove file or directory
+*/
+int rgw_unlink(struct rgw_fs *rgw_fs, struct rgw_file_handle *parent_fh,
+	       const char *name, uint32_t flags)
+{
+  RGWLibFS *fs = static_cast<RGWLibFS*>(rgw_fs->fs_private);
+  RGWFileHandle* parent = get_rgwfh(parent_fh);
+
+  return fs->unlink(parent, name);
+}
+
+/*
+  lookup object by name (POSIX style)
+*/
+int rgw_lookup(struct rgw_fs *rgw_fs,
+	      struct rgw_file_handle *parent_fh, const char* path,
+	      struct rgw_file_handle **fh, uint32_t flags)
+{
+  //CephContext* cct = static_cast<CephContext*>(rgw_fs->rgw);
+  RGWLibFS *fs = static_cast<RGWLibFS*>(rgw_fs->fs_private);
+
+  RGWFileHandle* parent = get_rgwfh(parent_fh);
+  if ((! parent) ||
+      (! parent->is_dir())) {
+    /* bad parent */
+    return -EINVAL;
+  }
+
+  RGWFileHandle* rgw_fh;
+  LookupFHResult fhr;
+
+  if (parent->is_root()) {
+    /* special: lookup on root itself */
+    if (strcmp(path, "/") == 0) {
+      rgw_fh = fs->ref(parent);
+    } else {
+      fhr = fs->stat_bucket(parent, path, RGWFileHandle::FLAG_NONE);
+      rgw_fh = get<0>(fhr);
+      if (! rgw_fh)
+	return -ENOENT;
+    }
+  } else {
+    fhr = fs->stat_leaf(parent, path, RGWFileHandle::FLAG_NONE);
+    if (! get<0>(fhr)) {
+      if (! (flags & RGW_LOOKUP_FLAG_CREATE))
+	return -ENOENT;
+      else
+	fhr = fs->lookup_fh(parent, path, RGWFileHandle::FLAG_CREATE);
+    }
+    rgw_fh = get<0>(fhr);
+  } /* !root */
+
+  struct rgw_file_handle *rfh = rgw_fh->get_fh();
+  *fh = rfh;
+
+  return 0;
+} /* rgw_lookup */
+
+/*
+  lookup object by handle (NFS style)
+*/
+int rgw_lookup_handle(struct rgw_fs *rgw_fs, struct rgw_fh_hk *fh_hk,
+		      struct rgw_file_handle **fh, uint32_t flags)
+{
+  RGWLibFS *fs = static_cast<RGWLibFS*>(rgw_fs->fs_private);
+
+  RGWFileHandle* rgw_fh = fs->lookup_handle(*fh_hk);
+  if (! rgw_fh) {
+    /* not found */
+    return -ENOENT;
+  }
+
+  struct rgw_file_handle *rfh = rgw_fh->get_fh();
+  *fh = rfh;
+
+  return 0;
+}
+
+/*
+ * release file handle
+ */
+int rgw_fh_rele(struct rgw_fs *rgw_fs, struct rgw_file_handle *fh,
+		uint32_t flags)
+{
+  RGWLibFS *fs = static_cast<RGWLibFS*>(rgw_fs->fs_private);
+  RGWFileHandle* rgw_fh = get_rgwfh(fh);
+  fs->unref(rgw_fh);
+
+  return 0;
+}
+
+/*
+   get unix attributes for object
+*/
+int rgw_getattr(struct rgw_fs *rgw_fs,
+		struct rgw_file_handle *fh, struct stat *st, uint32_t flags)
+{
+  RGWLibFS *fs = static_cast<RGWLibFS*>(rgw_fs->fs_private);
+  RGWFileHandle* rgw_fh = get_rgwfh(fh);
+
+  return -(fs->getattr(rgw_fh, st));
+}
+
+/*
+  set unix attributes for object
+*/
+int rgw_setattr(struct rgw_fs *rgw_fs,
+		struct rgw_file_handle *fh, struct stat *st,
+		uint32_t mask, uint32_t flags)
+{
+  /* XXX no-op */
+  return 0;
+}
+
+/*
+   truncate file
+*/
+int rgw_truncate(struct rgw_fs *rgw_fs,
+		 struct rgw_file_handle *fh, uint64_t size, uint32_t flags)
+{
+  return 0;
+}
+
+/*
+   open file
+*/
+int rgw_open(struct rgw_fs *rgw_fs,
+	     struct rgw_file_handle *fh, uint32_t flags)
+{
+  RGWFileHandle* rgw_fh = get_rgwfh(fh);
+
+  /* XXX 
+   * need to track specific opens--at least read opens and
+   * a write open;  we need to know when a write open is returned,
+   * that closes a write transaction
+   *
+   * for now, we will support single-open only, it's preferable to
+   * anything we can otherwise do without access to the NFS state
+   */
+  if (! rgw_fh->is_file())
+    return -EISDIR;
+
+  // convert flags
+  uint32_t oflags = 0;
+  return rgw_fh->open(oflags);
+}
+
+/*
+   close file
+*/
+int rgw_close(struct rgw_fs *rgw_fs,
+	      struct rgw_file_handle *fh, uint32_t flags)
+{
+  RGWLibFS *fs = static_cast<RGWLibFS*>(rgw_fs->fs_private);
+  RGWFileHandle* rgw_fh = get_rgwfh(fh);
+  int rc = rgw_fh->close(/* XXX */);
+
+  if (flags & RGW_CLOSE_FLAG_RELE)
+    fs->unref(rgw_fh);
+
+  return rc;
+}
+
+int rgw_readdir(struct rgw_fs *rgw_fs,
+		struct rgw_file_handle *parent_fh, uint64_t *offset,
+		rgw_readdir_cb rcb, void *cb_arg, bool *eof,
+		uint32_t flags)
+{
+  RGWFileHandle* parent = get_rgwfh(parent_fh);
+  if (! parent) {
+    /* bad parent */
+    return -EINVAL;
+  }
+  int rc = parent->readdir(rcb, cb_arg, offset, eof, flags);
+  return -rc;
+}
+
+/*
+   read data from file
+*/
+int rgw_read(struct rgw_fs *rgw_fs,
+	     struct rgw_file_handle *fh, uint64_t offset,
+	     size_t length, size_t *bytes_read, void *buffer,
+	     uint32_t flags)
+{
+  CephContext* cct = static_cast<CephContext*>(rgw_fs->rgw);
+  RGWLibFS *fs = static_cast<RGWLibFS*>(rgw_fs->fs_private);
+  RGWFileHandle* rgw_fh = get_rgwfh(fh);
+
+  if (! rgw_fh->is_file())
+    return -EINVAL;
+
+  RGWReadRequest req(cct, fs->get_user(), rgw_fh, offset, length, buffer);
+
+  int rc = rgwlib.get_fe()->execute_req(&req);
+  if ((rc == 0) &&
+      (req.get_ret() == 0)) {
+    *bytes_read = req.nread;
+  }
+
+  return rc;
+}
+
+/*
+   write data to file
+*/
+int rgw_write(struct rgw_fs *rgw_fs,
+	      struct rgw_file_handle *fh, uint64_t offset,
+	      size_t length, size_t *bytes_written, void *buffer,
+	      uint32_t flags)
+{
+  RGWFileHandle* rgw_fh = get_rgwfh(fh);
+  int rc;
+
+  *bytes_written = 0;
+
+  if (! rgw_fh->is_file())
+    return -EISDIR;
+
+  if (! rgw_fh->is_open())
+    return -EPERM;
+
+  std::cout << __func__ << " before write of "
+	    << length << " bytes at offset " << offset
+	    << std::endl;
+
+  rc = rgw_fh->write(offset, length, bytes_written, buffer);
+
+  std::cout << __func__ << " after write of "
+	    << length << " bytes at offset " << offset
+	    << " wrote " << *bytes_written
+	    << " rc " << rc
+	    << std::endl;
+
+  return rc;
+}
+
+/*
+   read data from file (vector)
+*/
+class RGWReadV
+{
+  buffer::list bl;
+  struct rgw_vio* vio;
+
+public:
+  RGWReadV(buffer::list& _bl, rgw_vio* _vio) : vio(_vio) {
+    bl.claim(_bl);
+  }
+
+  struct rgw_vio* get_vio() { return vio; }
+
+  const std::list<buffer::ptr>& buffers() { return bl.buffers(); }
+
+  unsigned /* XXX */ length() { return bl.length(); }
+
+};
+
+void rgw_readv_rele(struct rgw_uio *uio, uint32_t flags)
+{
+  RGWReadV* rdv = static_cast<RGWReadV*>(uio->uio_p1);
+  rdv->~RGWReadV();
+  ::operator delete(rdv);
+}
+
+int rgw_readv(struct rgw_fs *rgw_fs,
+	      struct rgw_file_handle *fh, rgw_uio *uio, uint32_t flags)
+{
+#if 0 /* XXX */
+  CephContext* cct = static_cast<CephContext*>(rgw_fs->rgw);
+  RGWLibFS *fs = static_cast<RGWLibFS*>(rgw_fs->fs_private);
+  RGWFileHandle* rgw_fh = get_rgwfh(fh);
+
+  if (! rgw_fh->is_file())
+    return -EINVAL;
+
+  int rc = 0;
+
+  buffer::list bl;
+  RGWGetObjRequest req(cct, fs->get_user(), rgw_fh->bucket_name(),
+		      rgw_fh->object_name(), uio->uio_offset, uio->uio_resid,
+		      bl);
+  req.do_hexdump = false;
+
+  rc = rgwlib.get_fe()->execute_req(&req);
+
+  if (! rc) {
+    RGWReadV* rdv = static_cast<RGWReadV*>(
+      ::operator new(sizeof(RGWReadV) +
+		    (bl.buffers().size() * sizeof(struct rgw_vio))));
+
+    (void) new (rdv)
+      RGWReadV(bl, reinterpret_cast<rgw_vio*>(rdv+sizeof(RGWReadV)));
+
+    uio->uio_p1 = rdv;
+    uio->uio_cnt = rdv->buffers().size();
+    uio->uio_resid = rdv->length();
+    uio->uio_vio = rdv->get_vio();
+    uio->uio_rele = rgw_readv_rele;
+
+    int ix = 0;
+    auto& buffers = rdv->buffers();
+    for (auto& bp : buffers) {
+      rgw_vio *vio = &(uio->uio_vio[ix]);
+      vio->vio_base = const_cast<char*>(bp.c_str());
+      vio->vio_len = bp.length();
+      vio->vio_u1 = nullptr;
+      vio->vio_p1 = nullptr;
+      ++ix;
+    }
+  }
+
+  return rc;
+#else
+  return 0;
+#endif
+}
+
+/*
+   write data to file (vector)
+*/
+  int rgw_writev(struct rgw_fs *rgw_fs, struct rgw_file_handle *fh,
+		 rgw_uio *uio, uint32_t flags)
+{
+  CephContext* cct = static_cast<CephContext*>(rgw_fs->rgw);
+  RGWLibFS *fs = static_cast<RGWLibFS*>(rgw_fs->fs_private);
+  RGWFileHandle* rgw_fh = get_rgwfh(fh);
+
+  if (! rgw_fh->is_file())
+    return -EINVAL;
+
+  buffer::list bl;
+  for (unsigned int ix = 0; ix < uio->uio_cnt; ++ix) {
+    rgw_vio *vio = &(uio->uio_vio[ix]);
+    bl.push_back(
+      buffer::create_static(vio->vio_len,
+			    static_cast<char*>(vio->vio_base)));
+  }
+
+  std::string oname = rgw_fh->relative_object_name();
+  RGWPutObjRequest req(cct, fs->get_user(), rgw_fh->bucket_name(),
+		       oname, bl);
+
+  int rc = rgwlib.get_fe()->execute_req(&req);
+
+  /* XXX update size (in request) */
+
+  return rc;
+}
+
+/*
+   sync written data
+*/
+int rgw_fsync(struct rgw_fs *rgw_fs, struct rgw_file_handle *handle,
+	      uint32_t flags)
+{
+  return 0;
+}
+
+} /* extern "C" */
diff --git a/src/rgw/rgw_file.h b/src/rgw/rgw_file.h
new file mode 100644
index 0000000..a6e06de
--- /dev/null
+++ b/src/rgw/rgw_file.h
@@ -0,0 +1,1924 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+
+#ifndef RGW_FILE_H
+#define RGW_FILE_H
+
+#include "include/rados/rgw_file.h"
+
+/* internal header */
+#include <string.h>
+#include <sys/stat.h>
+#include <stdint.h>
+
+#include <atomic>
+#include <chrono>
+#include <thread>
+#include <mutex>
+#include <vector>
+#include <deque>
+#include <algorithm>
+#include <functional>
+#include <boost/intrusive_ptr.hpp>
+#include <boost/range/adaptor/reversed.hpp>
+#include <boost/container/flat_map.hpp>
+#include <boost/variant.hpp>
+#include <boost/utility/string_ref.hpp>
+#include "xxhash.h"
+#include "include/buffer.h"
+#include "common/sstring.hh"
+#include "common/cohort_lru.h"
+#include "rgw_common.h"
+#include "rgw_user.h"
+#include "rgw_lib.h"
+#include "rgw_ldap.h"
+#include "rgw_token.h"
+
+
+/* XXX
+ * ASSERT_H somehow not defined after all the above (which bring
+ * in common/debug.h [e.g., dout])
+ */
+#include "include/assert.h"
+
+
+#define RGW_RWXMODE  (S_IRWXU | S_IRWXG | S_IRWXO)
+
+#define RGW_RWMODE (RGW_RWXMODE &			\
+		      ~(S_IXUSR | S_IXGRP | S_IXOTH))
+
+
+namespace rgw {
+
+  template <typename T>
+  static inline void ignore(T &&) {}
+
+
+  namespace bi = boost::intrusive;
+
+  class RGWLibFS;
+  class RGWFileHandle;
+  class RGWWriteRequest;
+
+  /*
+   * XXX
+   * The current 64-bit, non-cryptographic hash used here is intended
+   * for prototyping only.
+   *
+   * However, the invariant being prototyped is that objects be
+   * identifiable by their hash components alone.  We believe this can
+   * be legitimately implemented using 128-hash values for bucket and
+   * object components, together with a cluster-resident cryptographic
+   * key.  Since an MD5 or SHA-1 key is 128 bits and the (fast),
+   * non-cryptographic CityHash128 hash algorithm takes a 128-bit seed,
+   * speculatively we could use that for the final hash computations.
+   */
+  struct fh_key
+  {
+    rgw_fh_hk fh_hk;
+
+    static constexpr uint64_t seed = 8675309;
+
+    fh_key() {}
+
+    fh_key(const rgw_fh_hk& _hk)
+      : fh_hk(_hk) {
+      // nothing
+    }
+
+    fh_key(const uint64_t bk, const uint64_t ok) {
+      fh_hk.bucket = bk;
+      fh_hk.object = ok;
+    }
+
+    fh_key(const uint64_t bk, const char *_o) {
+      fh_hk.bucket = bk;
+      fh_hk.object = XXH64(_o, ::strlen(_o), seed);
+    }
+    
+    fh_key(const std::string& _b, const std::string& _o) {
+      fh_hk.bucket = XXH64(_b.c_str(), _o.length(), seed);
+      fh_hk.object = XXH64(_o.c_str(), _o.length(), seed);
+    }
+  }; /* fh_key */
+
+  inline bool operator<(const fh_key& lhs, const fh_key& rhs)
+  {
+    return ((lhs.fh_hk.bucket < rhs.fh_hk.bucket) ||
+	    ((lhs.fh_hk.bucket == rhs.fh_hk.bucket) &&
+	      (lhs.fh_hk.object < rhs.fh_hk.object)));
+  }
+
+  inline bool operator>(const fh_key& lhs, const fh_key& rhs)
+  {
+    return (rhs < lhs);
+  }
+
+  inline bool operator==(const fh_key& lhs, const fh_key& rhs)
+  {
+    return ((lhs.fh_hk.bucket == rhs.fh_hk.bucket) &&
+	    (lhs.fh_hk.object == rhs.fh_hk.object));
+  }
+
+  inline bool operator!=(const fh_key& lhs, const fh_key& rhs)
+  {
+    return !(lhs == rhs);
+  }
+
+  inline bool operator<=(const fh_key& lhs, const fh_key& rhs)
+  {
+    return (lhs < rhs) || (lhs == rhs);
+  }
+
+  using boost::variant;
+  using boost::container::flat_map;
+
+  class RGWFileHandle : public cohort::lru::Object
+  {
+    struct rgw_file_handle fh;
+    std::mutex mtx;
+    RGWLibFS* fs;
+    RGWFileHandle* bucket;
+    RGWFileHandle* parent;
+    /* const */ std::string name; /* XXX file or bucket name */
+    /* const */ fh_key fhk;
+
+    using lock_guard = std::lock_guard<std::mutex>;
+    using unique_lock = std::unique_lock<std::mutex>;
+
+    /* median file name length (HPC) has been found to be 16,
+     * w/90% of file names <= 31 (Yifan Wang, CMU) */
+    using dirent_string = basic_sstring<char, uint16_t, 32>;
+
+    using marker_cache_t = flat_map<uint64_t, dirent_string>;
+    using name_cache_t = flat_map<dirent_string, uint8_t>;
+
+    struct state {
+      uint64_t dev;
+      size_t size;
+      uint64_t nlink;
+      struct timespec ctime;
+      struct timespec mtime;
+      struct timespec atime;
+      state() : dev(0), size(0), nlink(1), ctime{0,0}, mtime{0,0}, atime{0,0} {}
+    } state;
+
+    struct file {
+      RGWWriteRequest* write_req;
+      file() : write_req(nullptr) {}
+      ~file();
+    };
+
+    struct directory {
+
+      static constexpr uint32_t FLAG_NONE =     0x0000;
+      static constexpr uint32_t FLAG_CACHED =   0x0001;
+      static constexpr uint32_t FLAG_OVERFLOW = 0x0002;
+
+      uint32_t flags;
+      marker_cache_t marker_cache;
+      name_cache_t name_cache;
+
+      directory() : flags(FLAG_NONE) {}
+
+      void clear_state() {
+	marker_cache.clear();
+	name_cache.clear();
+      }
+
+      void set_overflow() {
+	clear_state();
+	flags |= FLAG_OVERFLOW;
+      }
+    };
+
+    boost::variant<file, directory> variant_type;
+
+    uint16_t depth;
+    uint32_t flags;
+
+  public:
+    const static std::string root_name;
+
+    static constexpr uint16_t MAX_DEPTH = 256;
+
+    static constexpr uint32_t FLAG_NONE =    0x0000;
+    static constexpr uint32_t FLAG_OPEN =    0x0001;
+    static constexpr uint32_t FLAG_ROOT =    0x0002;
+    static constexpr uint32_t FLAG_CREATE =  0x0004;
+    static constexpr uint32_t FLAG_CREATING =  0x0008;
+    static constexpr uint32_t FLAG_DIRECTORY = 0x0010;
+    static constexpr uint32_t FLAG_BUCKET = 0x0020;
+    static constexpr uint32_t FLAG_LOCK =   0x0040;
+    static constexpr uint32_t FLAG_DELETED = 0x0080;
+
+    friend class RGWLibFS;
+
+  private:
+    RGWFileHandle(RGWLibFS* _fs, uint32_t fs_inst)
+      : fs(_fs), bucket(nullptr), parent(nullptr), variant_type{directory()},
+	depth(0), flags(FLAG_ROOT)
+      {
+	/* root */
+	fh.fh_type = RGW_FS_TYPE_DIRECTORY;
+	variant_type = directory();
+	/* stat */
+	state.dev = fs_inst;
+	/* pointer to self */
+	fh.fh_private = this;
+      }
+    
+    void init_rootfs(std::string& fsid, const std::string& object_name) {
+      /* fh_key */
+      fh.fh_hk.bucket = XXH64(fsid.c_str(), fsid.length(), fh_key::seed);
+      fh.fh_hk.object = XXH64(object_name.c_str(), object_name.length(),
+			      fh_key::seed);
+      fhk = fh.fh_hk;
+      name = object_name;
+    }
+
+  public:
+    RGWFileHandle(RGWLibFS* fs, uint32_t fs_inst, RGWFileHandle* _parent,
+		  const fh_key& _fhk, std::string& _name, uint32_t _flags)
+      : fs(fs), bucket(nullptr), parent(_parent), name(std::move(_name)),
+	fhk(_fhk), flags(_flags) {
+
+      if (parent->is_root()) {
+	fh.fh_type = RGW_FS_TYPE_DIRECTORY;
+	variant_type = directory();
+	flags |= FLAG_BUCKET;
+      } else {
+	bucket = (parent->flags & FLAG_BUCKET) ? parent
+	  : parent->bucket;
+	if (flags & FLAG_DIRECTORY) {
+	  fh.fh_type = RGW_FS_TYPE_DIRECTORY;
+	  variant_type = directory();
+	} else {
+	  fh.fh_type = RGW_FS_TYPE_FILE;
+	  variant_type = file();
+	}
+      }
+
+      depth = parent->depth + 1;
+
+      /* save constant fhk */
+      fh.fh_hk = fhk.fh_hk; /* XXX redundant in fh_hk */
+
+      /* pointer to self */
+      fh.fh_private = this;
+    }
+
+    const fh_key& get_key() const {
+      return fhk;
+    }
+
+    directory* get_directory() {
+      return get<directory>(&variant_type);
+    }
+
+    size_t get_size() const { return state.size; }
+
+    const char* stype() {
+      return is_dir() ? "DIR" : "FILE";
+    }
+
+    uint16_t get_depth() const { return depth; }
+
+    struct rgw_file_handle* get_fh() { return &fh; }
+
+    RGWLibFS* get_fs() { return fs; }
+
+    RGWFileHandle* get_parent() { return parent; }
+
+    struct timespec get_mtime() const { return state.mtime; }
+
+    int stat(struct stat *st) {
+      /* partial Unix attrs */
+      memset(st, 0, sizeof(struct stat));
+      st->st_dev = state.dev;
+      st->st_ino = fh.fh_hk.object; // XXX
+
+      st->st_uid = 0; // XXX
+      st->st_gid = 0; // XXX
+
+      st->st_atim = state.atime;
+      st->st_mtim = state.mtime;
+      st->st_ctim = state.ctime;
+
+      switch (fh.fh_type) {
+      case RGW_FS_TYPE_DIRECTORY:
+	st->st_mode = RGW_RWXMODE|S_IFDIR;
+	st->st_nlink = 3;
+	break;
+      case RGW_FS_TYPE_FILE:
+	st->st_mode = RGW_RWMODE|S_IFREG;
+	st->st_nlink = 1;
+	st->st_blksize = 4096;
+	st->st_size = state.size;
+	st->st_blocks = (state.size) / 512;
+      default:
+	break;
+      }
+
+      return 0;
+    }
+
+    const std::string& bucket_name() const {
+      if (is_root())
+	return root_name;
+      if (flags & FLAG_BUCKET)
+	return name;
+      return bucket->object_name();
+    }
+
+    const std::string& object_name() const { return name; }
+
+    std::string full_object_name(bool omit_bucket = false) {
+      std::string path;
+      std::vector<const std::string*> segments;
+      int reserve = 0;
+      RGWFileHandle* tfh = this;
+      while (tfh && !tfh->is_root() && !(tfh->is_bucket() && omit_bucket)) {
+	segments.push_back(&tfh->object_name());
+	reserve += (1 + tfh->object_name().length());
+	tfh = tfh->parent;
+      }
+      bool first = true;
+      path.reserve(reserve);
+      for (auto& s : boost::adaptors::reverse(segments)) {
+	if (! first)
+	  path += "/";
+	else {
+	  if (!omit_bucket && (path.front() != '/')) // pretty-print
+	    path += "/";
+	  first = false;
+	}
+	path += *s;
+      }
+      return path;
+    }
+
+    inline std::string relative_object_name() {
+      return full_object_name(true /* omit_bucket */);
+    }
+
+    inline std::string format_child_name(const std::string& cbasename) {
+      std::string child_name{relative_object_name()};
+      if ((child_name.size() > 0) &&
+	  (child_name.back() != '/'))
+	child_name += "/";
+      child_name += cbasename;
+      return child_name;
+    }
+
+    inline std::string make_key_name(const char *name) {
+      std::string key_name{full_object_name()};
+      if (key_name.length() > 0)
+	key_name += "/";
+      key_name += name;
+      return key_name;
+    }
+
+    fh_key make_fhk(const std::string& name) {
+      if (depth <= 1)
+	return fh_key(fhk.fh_hk.object, name.c_str());
+      else {
+	std::string key_name = make_key_name(name.c_str());
+	return fh_key(fhk.fh_hk.object, key_name.c_str());
+      }
+    }
+
+    void add_marker(uint64_t off, const boost::string_ref& marker,
+		    uint8_t obj_type) {
+      using std::get;
+      directory* d = get<directory>(&variant_type);
+      if (d) {
+	unique_lock guard(mtx);
+	// XXXX check for failure (dup key)
+	d->marker_cache.insert(
+	  marker_cache_t::value_type(off, marker.data()));
+	/* 90% of directories hold <= 32 entries (Yifan Wang, CMU),
+	 * but go big */
+	if (d->name_cache.size() < 128) {
+	  d->name_cache.insert(
+	    name_cache_t::value_type(marker.data(), obj_type));
+	} else {
+	  d->set_overflow(); // too many
+	}
+      }
+    }
+
+    /* XXX */
+    std::string find_marker(uint64_t off) { // XXX copy
+      using std::get;
+      directory* d = get<directory>(&variant_type);
+      if (d) {
+	const auto& iter = d->marker_cache.find(off);
+	if (iter != d->marker_cache.end())
+	  return iter->second;
+      }
+      return "";
+    }
+    
+    bool is_open() const { return flags & FLAG_OPEN; }
+    bool is_root() const { return flags & FLAG_ROOT; }
+    bool is_bucket() const { return flags & FLAG_BUCKET; }
+    bool is_object() const { return !is_bucket(); }
+    bool is_file() const { return (fh.fh_type == RGW_FS_TYPE_FILE); }
+    bool is_dir() const { return (fh.fh_type == RGW_FS_TYPE_DIRECTORY); }
+    bool creating() const { return flags & FLAG_CREATING; }
+
+    uint32_t open(uint32_t gsh_flags) {
+      lock_guard guard(mtx);
+      if (! (flags & FLAG_OPEN)) {
+	flags |= FLAG_OPEN;
+	return 0;
+      }
+      return EPERM;
+    }
+
+    int readdir(rgw_readdir_cb rcb, void *cb_arg, uint64_t *offset, bool *eof,
+		uint32_t flags);
+    int write(uint64_t off, size_t len, size_t *nbytes, void *buffer);
+    int write_finish();
+    int close();
+
+    void open_for_create() {
+      lock_guard guard(mtx);
+      flags |= FLAG_CREATING;
+    }
+
+    void clear_creating() {
+      lock_guard guard(mtx);
+      flags &= ~FLAG_CREATING;
+    }
+
+    void set_nlink(const uint64_t n) {
+      state.nlink = n;
+    }
+
+    void set_size(const size_t size) {
+      state.size = size;
+    }
+
+    void set_times(real_time t) {
+      state.ctime = real_clock::to_timespec(t);
+      state.mtime = state.ctime;
+      state.atime = state.ctime;
+    }
+
+    void set_ctime(const struct timespec &ts) {
+      state.ctime = ts;
+    }
+
+    void set_mtime(const struct timespec &ts) {
+      state.mtime = ts;
+    }
+
+    void set_atime(const struct timespec &ts) {
+      state.atime = ts;
+    }
+
+    virtual bool reclaim();
+
+    typedef cohort::lru::LRU<std::mutex> FhLRU;
+
+    struct FhLT
+    {
+      // for internal ordering
+      bool operator()(const RGWFileHandle& lhs, const RGWFileHandle& rhs) const
+	{ return (lhs.get_key() < rhs.get_key()); }
+
+      // for external search by fh_key
+      bool operator()(const fh_key& k, const RGWFileHandle& fh) const
+	{ return k < fh.get_key(); }
+
+      bool operator()(const RGWFileHandle& fh, const fh_key& k) const
+	{ return fh.get_key() < k; }
+    };
+
+    struct FhEQ
+    {
+      bool operator()(const RGWFileHandle& lhs, const RGWFileHandle& rhs) const
+	{ return (lhs.get_key() == rhs.get_key()); }
+
+      bool operator()(const fh_key& k, const RGWFileHandle& fh) const
+	{ return k == fh.get_key(); }
+
+      bool operator()(const RGWFileHandle& fh, const fh_key& k) const
+	{ return fh.get_key() == k; }
+    };
+
+    typedef bi::link_mode<bi::safe_link> link_mode; /* XXX normal */
+#if defined(FHCACHE_AVL)
+    typedef bi::avl_set_member_hook<link_mode> tree_hook_type;
+#else
+    /* RBT */
+    typedef bi::set_member_hook<link_mode> tree_hook_type;
+#endif
+    tree_hook_type fh_hook;
+
+    typedef bi::member_hook<
+      RGWFileHandle, tree_hook_type, &RGWFileHandle::fh_hook> FhHook;
+
+#if defined(FHCACHE_AVL)
+    typedef bi::avltree<RGWFileHandle, bi::compare<FhLT>, FhHook> FHTree;
+#else
+    typedef bi::rbtree<RGWFileHandle, bi::compare<FhLT>, FhHook> FhTree;
+#endif
+    typedef cohort::lru::TreeX<RGWFileHandle, FhTree, FhLT, FhEQ, fh_key,
+			       std::mutex> FHCache;
+
+    virtual ~RGWFileHandle() {}
+
+    class Factory : public cohort::lru::ObjectFactory
+    {
+    public:
+      RGWLibFS* fs;
+      uint32_t fs_inst;
+      RGWFileHandle* parent;
+      const fh_key& fhk;
+      std::string& name;
+      uint32_t flags;
+
+      Factory() = delete;
+
+      Factory(RGWLibFS* fs, uint32_t fs_inst, RGWFileHandle* parent,
+	      const fh_key& fhk, std::string& name, uint32_t flags)
+	: fs(fs), fs_inst(fs_inst), parent(parent), fhk(fhk), name(name),
+	  flags(flags) {}
+
+      void recycle (cohort::lru::Object* o) {
+	/* re-use an existing object */
+	o->~Object(); // call lru::Object virtual dtor
+	// placement new!
+	new (o) RGWFileHandle(fs, fs_inst, parent, fhk, name, flags);
+      }
+
+      cohort::lru::Object* alloc() {
+	return new RGWFileHandle(fs, fs_inst, parent, fhk, name, flags);
+      }
+    }; /* Factory */
+
+  }; /* RGWFileHandle */
+
+  static inline RGWFileHandle* get_rgwfh(struct rgw_file_handle* fh) {
+    return static_cast<RGWFileHandle*>(fh->fh_private);
+  }
+
+  typedef std::tuple<RGWFileHandle*, uint32_t> LookupFHResult;
+
+  class RGWLibFS
+  {
+    CephContext* cct;
+    struct rgw_fs fs;
+    RGWFileHandle root_fh;
+
+    mutable std::atomic<uint64_t> refcnt;
+
+    RGWFileHandle::FHCache fh_cache;
+    RGWFileHandle::FhLRU fh_lru;
+    
+    std::string uid; // should match user.user_id, iiuc
+
+    RGWUserInfo user;
+    RGWAccessKey key; // XXXX acc_key
+
+    static atomic<uint32_t> fs_inst;
+    std::string fsid;
+
+    using lock_guard = std::lock_guard<std::mutex>;
+    using unique_lock = std::unique_lock<std::mutex>;
+
+    struct event
+    {
+      enum class type : uint8_t { READDIR } ;
+      type t;
+      const fh_key fhk;
+      struct timespec ts;
+      event(type t, const fh_key& k, const struct timespec& ts)
+	: t(t), fhk(k), ts(ts) {}
+    };
+
+    using event_vector = /* boost::small_vector<event, 16> */
+      std::vector<event>;
+
+    struct state {
+      std::mutex mtx;
+      std::atomic<uint32_t> flags;
+      std::deque<event> events;
+      state() : flags(0) {}
+      void push_event(const event& ev) {
+	lock_guard guard(mtx);
+	events.push_back(ev);
+      }
+    } state;
+
+    friend class RGWFileHandle;
+
+  public:
+
+    static constexpr uint32_t FLAG_NONE =      0x0000;
+    static constexpr uint32_t FLAG_CLOSED =    0x0001;
+
+    RGWLibFS(CephContext* _cct, const char *_uid, const char *_user_id,
+	    const char* _key)
+      : cct(_cct), root_fh(this, get_inst()), refcnt(1),
+	fh_cache(cct->_conf->rgw_nfs_fhcache_partitions,
+		 cct->_conf->rgw_nfs_fhcache_size),
+	fh_lru(cct->_conf->rgw_nfs_lru_lanes,
+	       cct->_conf->rgw_nfs_lru_lane_hiwat),
+	uid(_uid), key(_user_id, _key) {
+
+      /* no bucket may be named rgw_fs_inst-(.*) */
+      fsid = RGWFileHandle::root_name + "rgw_fs_inst-" +
+	std::to_string(++(fs_inst));
+
+      root_fh.init_rootfs(fsid /* bucket */, RGWFileHandle::root_name);
+
+      /* pointer to self */
+      fs.fs_private = this;
+
+      /* expose public root fh */
+      fs.root_fh = root_fh.get_fh();
+    }
+
+    friend void intrusive_ptr_add_ref(const RGWLibFS* fs) {
+      fs->refcnt.fetch_add(1, std::memory_order_relaxed);
+    }
+
+    friend void intrusive_ptr_release(const RGWLibFS* fs) {
+      if (fs->refcnt.fetch_sub(1, std::memory_order_release) == 0) {
+	std::atomic_thread_fence(std::memory_order_acquire);
+	delete fs;
+      }
+    }
+
+    RGWLibFS* ref() {
+      intrusive_ptr_add_ref(this);
+      return this;
+    }
+
+    inline void rele() {
+      intrusive_ptr_release(this);
+    }
+
+    int authorize(RGWRados* store) {
+      int ret = rgw_get_user_info_by_access_key(store, key.id, user);
+      if (ret == 0) {
+	RGWAccessKey* key0 = user.get_key0();
+	if (!key0 ||
+	    (key0->key != key.key))
+	  return -EINVAL;
+	if (user.suspended)
+	  return -ERR_USER_SUSPENDED;
+      } else {
+	/* try external authenticators (ldap for now) */
+	rgw::LDAPHelper* ldh = rgwlib.get_ldh(); /* !nullptr */
+	RGWToken token{from_base64(key.id)};
+	if (token.valid() && (ldh->auth(token.id, token.key) == 0)) {
+	  /* try to store user if it doesn't already exist */
+	  if (rgw_get_user_info_by_uid(store, token.id, user) < 0) {
+	    int ret = rgw_store_user_info(store, user, NULL, NULL, real_time(),
+					  true);
+	    if (ret < 0) {
+	      lsubdout(get_context(), rgw, 10)
+		<< "NOTICE: failed to store new user's info: ret=" << ret
+		<< dendl;
+	    }
+	  }
+	} /* auth success */
+      }
+      return ret;
+    } /* authorize */
+
+    /* find or create an RGWFileHandle */
+    LookupFHResult lookup_fh(RGWFileHandle* parent, const char *name,
+			     const uint32_t cflags = RGWFileHandle::FLAG_NONE) {
+      using std::get;
+
+      LookupFHResult fhr { nullptr, RGWFileHandle::FLAG_NONE };
+
+      /* mount is stale? */
+      if (state.flags & FLAG_CLOSED)
+	return fhr;
+
+      RGWFileHandle::FHCache::Latch lat;
+      memset(&lat, 0, sizeof(lat)); // XXXX testing
+
+      std::string obj_name{name};
+      std::string key_name{parent->make_key_name(name)};
+
+      fh_key fhk = parent->make_fhk(key_name);
+
+    retry:
+      RGWFileHandle* fh =
+	fh_cache.find_latch(fhk.fh_hk.object /* partition selector*/,
+			    fhk /* key */, lat /* serializer */,
+			    RGWFileHandle::FHCache::FLAG_LOCK);
+      /* LATCHED */
+      if (fh) {
+	fh->mtx.lock(); // XXX !RAII because may-return-LOCKED
+	if (fh->flags & RGWFileHandle::FLAG_DELETED) {
+	  /* for now, delay briefly and retry */
+	  lat.lock->unlock();
+	  fh->mtx.unlock();
+	  std::this_thread::sleep_for(std::chrono::milliseconds(20));
+	  goto retry; /* !LATCHED */
+	}
+	/* need initial ref from LRU (fast path) */
+	if (! fh_lru.ref(fh, cohort::lru::FLAG_INITIAL)) {
+	  lat.lock->unlock();
+	  fh->mtx.unlock();
+	  goto retry; /* !LATCHED */
+	}
+	/* LATCHED, LOCKED */
+	if (! (fh->flags & RGWFileHandle::FLAG_LOCK))
+	  fh->mtx.unlock(); /* ! LOCKED */
+      } else {
+	/* make or re-use handle */
+	RGWFileHandle::Factory prototype(this, get_inst(), parent, fhk,
+					 obj_name, cflags);
+	fh = static_cast<RGWFileHandle*>(
+	  fh_lru.insert(&prototype,
+			cohort::lru::Edge::MRU,
+			cohort::lru::FLAG_INITIAL));
+	if (fh) {
+	  fh_cache.insert_latched(fh, lat, RGWFileHandle::FHCache::FLAG_UNLOCK);
+	  get<1>(fhr) |= RGWFileHandle::FLAG_CREATE;
+	  if (fh->flags & RGWFileHandle::FLAG_LOCK)
+	    fh->mtx.lock();
+	  goto out; /* !LATCHED */
+	} else {
+	  lat.lock->unlock();
+	  goto retry; /* !LATCHED */
+	}
+      }
+      lat.lock->unlock(); /* !LATCHED */
+    out:
+      get<0>(fhr) = fh;
+      return fhr;
+    }
+
+    inline void unref(RGWFileHandle* fh) {
+      (void) fh_lru.unref(fh, cohort::lru::FLAG_NONE);
+    }
+
+    inline RGWFileHandle* ref(RGWFileHandle* fh) {
+      fh_lru.ref(fh, cohort::lru::FLAG_NONE);
+      return fh;
+    }
+
+    int getattr(RGWFileHandle* rgw_fh, struct stat* st);
+
+    LookupFHResult stat_bucket(RGWFileHandle* parent,
+			       const char *path, uint32_t flags);
+
+    LookupFHResult stat_leaf(RGWFileHandle* parent, const char *path,
+			     uint32_t flags);
+
+    int rename(RGWFileHandle* old_fh, RGWFileHandle* new_fh,
+	       const char *old_name, const char *new_name);
+
+    int unlink(RGWFileHandle* parent, const char *name);
+
+    /* find existing RGWFileHandle */
+    RGWFileHandle* lookup_handle(struct rgw_fh_hk fh_hk) {
+
+      if (state.flags & FLAG_CLOSED)
+	return nullptr;
+
+      RGWFileHandle::FHCache::Latch lat;
+      fh_key fhk(fh_hk);
+
+    retry:
+      RGWFileHandle* fh =
+	fh_cache.find_latch(fhk.fh_hk.object /* partition selector*/,
+			    fhk /* key */, lat /* serializer */,
+			    RGWFileHandle::FHCache::FLAG_LOCK);
+      /* LATCHED */
+      if (! fh) {
+	lsubdout(get_context(), rgw, 0)
+	  << __func__ << " handle lookup failed <"
+	  << fhk.fh_hk.bucket << "," << fhk.fh_hk.object << ">"
+	  << "(need persistent handles)"
+	  << dendl;
+	goto out;
+      }
+      fh->mtx.lock();
+      if (fh->flags & RGWFileHandle::FLAG_DELETED) {
+	/* for now, delay briefly and retry */
+	lat.lock->unlock();
+	fh->mtx.unlock();
+	std::this_thread::sleep_for(std::chrono::milliseconds(20));
+	goto retry; /* !LATCHED */
+      }
+      if (! fh_lru.ref(fh, cohort::lru::FLAG_INITIAL)) {
+	lat.lock->unlock();
+	fh->mtx.unlock();
+	goto retry; /* !LATCHED */
+      }
+      /* LATCHED */
+    out:
+      lat.lock->unlock(); /* !LATCHED */
+      return fh;
+    }
+
+    CephContext* get_context() {
+      return cct;
+    }
+
+    struct rgw_fs* get_fs() { return &fs; }
+
+    uint32_t get_inst() { return fs_inst; }
+
+    RGWUserInfo* get_user() { return &user; }
+
+    void close();
+    void gc();
+  }; /* RGWLibFS */
+
+static inline std::string make_uri(const std::string& bucket_name,
+				   const std::string& object_name) {
+  std::string uri("/");
+  uri.reserve(bucket_name.length() + object_name.length() + 2);
+  uri += bucket_name;
+  uri += "/";
+  uri += object_name;
+  return uri;
+}
+
+/*
+  read directory content (buckets)
+*/
+
+class RGWListBucketsRequest : public RGWLibRequest,
+			      public RGWListBuckets /* RGWOp */
+{
+public:
+  RGWFileHandle* rgw_fh;
+  uint64_t* offset;
+  void* cb_arg;
+  rgw_readdir_cb rcb;
+  size_t ix;
+
+  RGWListBucketsRequest(CephContext* _cct, RGWUserInfo *_user,
+			RGWFileHandle* _rgw_fh, rgw_readdir_cb _rcb,
+			void* _cb_arg, uint64_t* _offset)
+    : RGWLibRequest(_cct, _user), rgw_fh(_rgw_fh), offset(_offset),
+      cb_arg(_cb_arg), rcb(_rcb), ix(0) {
+    const std::string& sm = rgw_fh->find_marker(*offset);
+    if (sm.size() > 0) {
+      RGWListBuckets::marker =
+	rgw_fh->relative_object_name();
+      if (marker.back() != '/')
+	marker += "/";
+      marker += sm;
+    }
+    op = this;
+  }
+
+  virtual bool only_bucket() { return false; }
+
+  virtual int op_init() {
+    // assign store, s, and dialect_handler
+    RGWObjectCtx* rados_ctx
+      = static_cast<RGWObjectCtx*>(get_state()->obj_ctx);
+    // framework promises to call op_init after parent init
+    assert(rados_ctx);
+    RGWOp::init(rados_ctx->store, get_state(), this);
+    op = this; // assign self as op: REQUIRED
+    return 0;
+  }
+
+  virtual int header_init() {
+    struct req_state* s = get_state();
+    s->info.method = "GET";
+    s->op = OP_GET;
+
+    /* XXX derp derp derp */
+    s->relative_uri = "/";
+    s->info.request_uri = "/"; // XXX
+    s->info.effective_uri = "/";
+    s->info.request_params = "";
+    s->info.domain = ""; /* XXX ? */
+
+    // woo
+    s->user = user;
+
+    return 0;
+  }
+
+  int get_params() {
+    limit = -1; /* no limit */
+    return 0;
+  }
+
+  virtual void send_response_begin(bool has_buckets) {
+    sent_data = true;
+  }
+
+  virtual void send_response_data(RGWUserBuckets& buckets) {
+    if (!sent_data)
+      return;
+    map<string, RGWBucketEnt>& m = buckets.get_buckets();
+    for (const auto& iter : m) {
+      boost::string_ref marker{iter.first};
+      const RGWBucketEnt& ent = iter.second;
+      /* call me maybe */
+      this->operator()(ent.bucket.name, marker);
+      ++ix;
+    }
+  } /* send_response_data */
+
+  virtual void send_response_end() {
+    // do nothing
+  }
+
+  int operator()(const boost::string_ref& name, const boost::string_ref& marker) {
+    uint64_t off = XXH64(name.data(), name.length(), fh_key::seed);
+    *offset = off;
+    /* update traversal cache */
+    rgw_fh->add_marker(off, marker, RGW_FS_TYPE_DIRECTORY);
+    rcb(name.data(), cb_arg, off);
+    return 0;
+  }
+
+  bool eof() {
+    lsubdout(cct, rgw, 15) << "READDIR offset: " << *offset
+			   << " is_truncated: " << is_truncated
+			   << dendl;
+    return !is_truncated;
+  }
+
+}; /* RGWListBucketsRequest */
+
+/*
+  read directory content (bucket objects)
+*/
+
+  class RGWReaddirRequest : public RGWLibRequest,
+			    public RGWListBucket /* RGWOp */
+{
+public:
+  RGWFileHandle* rgw_fh;
+  uint64_t* offset;
+  void* cb_arg;
+  rgw_readdir_cb rcb;
+  size_t ix;
+
+  RGWReaddirRequest(CephContext* _cct, RGWUserInfo *_user,
+		    RGWFileHandle* _rgw_fh, rgw_readdir_cb _rcb,
+		    void* _cb_arg, uint64_t* _offset)
+    : RGWLibRequest(_cct, _user), rgw_fh(_rgw_fh), offset(_offset),
+      cb_arg(_cb_arg), rcb(_rcb), ix(0) {
+    const std::string& sm{rgw_fh->find_marker(*offset)};
+    if (sm.size() > 0) {
+      RGWListBucket::marker = {rgw_fh->relative_object_name(), ""};
+      if (marker.name.back() != '/')
+	marker.name += "/";
+      marker.name += sm;
+    }
+    default_max = 1000; // XXX was being omitted
+    op = this;
+  }
+
+  virtual bool only_bucket() { return false; }
+
+  virtual int op_init() {
+    // assign store, s, and dialect_handler
+    RGWObjectCtx* rados_ctx
+      = static_cast<RGWObjectCtx*>(get_state()->obj_ctx);
+    // framework promises to call op_init after parent init
+    assert(rados_ctx);
+    RGWOp::init(rados_ctx->store, get_state(), this);
+    op = this; // assign self as op: REQUIRED
+    return 0;
+  }
+
+  virtual int header_init() {
+    struct req_state* s = get_state();
+    s->info.method = "GET";
+    s->op = OP_GET;
+
+    /* XXX derp derp derp */
+    std::string uri = "/" + rgw_fh->bucket_name() + "/";
+    s->relative_uri = uri;
+    s->info.request_uri = uri; // XXX
+    s->info.effective_uri = uri;
+    s->info.request_params = "";
+    s->info.domain = ""; /* XXX ? */
+
+    // woo
+    s->user = user;
+
+    prefix = rgw_fh->relative_object_name();
+    if (prefix.length() > 0)
+      prefix += "/";
+    delimiter = '/';
+
+    return 0;
+  }
+
+  int operator()(const boost::string_ref name, const boost::string_ref marker,
+		uint8_t type) {
+
+    assert(name.length() > 0); // XXX
+
+    /* hash offset of name in parent (short name) for NFS readdir cookie */
+    uint64_t off = XXH64(name.data(), name.length(), fh_key::seed);
+    *offset = off;
+    /* update traversal cache */
+    rgw_fh->add_marker(off, marker, type);
+    rcb(name.data(), cb_arg, off); // XXX has to be legit C-style string
+    return 0;
+  }
+
+  virtual int get_params() {
+    max = default_max;
+    return 0;
+  }
+
+  virtual void send_response() {
+    struct req_state* s = get_state();
+    for (const auto& iter : objs) {
+
+      boost::string_ref sref {iter.key.name};
+
+      lsubdout(cct, rgw, 15) << "readdir objects prefix: " << prefix
+			     << " obj: " << sref << dendl;
+
+      size_t last_del = sref.find_last_of('/');
+      if (last_del != string::npos)
+	sref.remove_prefix(last_del+1);
+
+      /* leaf directory? */
+      if (sref.empty())
+	continue;
+
+      lsubdout(cct, rgw, 15) << "RGWReaddirRequest "
+			     << __func__ << " "
+			     << "list uri=" << s->relative_uri << " "
+			     << " prefix=" << prefix << " "
+			     << " obj path=" << iter.key.name
+			     << " (" << sref << ")" << ""
+			     << dendl;
+
+      /* call me maybe */
+      this->operator()(sref, sref, RGW_FS_TYPE_FILE);
+      ++ix;
+    }
+    for (auto& iter : common_prefixes) {
+
+      lsubdout(cct, rgw, 15) << "readdir common prefixes prefix: " << prefix
+			     << " iter first: " << iter.first
+			     << " iter second: " << iter.second
+			     << dendl;
+
+      /* XXX aieee--I have seen this case! */
+      if (iter.first == "/")
+	continue;
+
+      /* it's safest to modify the element in place--a suffix-modifying
+       * string_ref operation is problematic since ULP rgw_file callers
+       * will ultimately need a c-string */
+      if (iter.first.back() == '/')
+	const_cast<std::string&>(iter.first).pop_back();
+
+      boost::string_ref sref{iter.first};
+
+      size_t last_del = sref.find_last_of('/');
+      if (last_del != string::npos)
+	sref.remove_prefix(last_del+1);
+
+      lsubdout(cct, rgw, 15) << "RGWReaddirRequest "
+			     << __func__ << " "
+			     << "list uri=" << s->relative_uri << " "
+			     << " prefix=" << prefix << " "
+			     << " cpref=" << sref
+			     << dendl;
+
+      this->operator()(sref, sref, RGW_FS_TYPE_DIRECTORY);
+      ++ix;
+    }
+  }
+
+  virtual void send_versioned_response() {
+    send_response();
+  }
+
+  bool eof() {
+    lsubdout(cct, rgw, 15) << "READDIR offset: " << *offset
+			   << " next marker: " << next_marker
+			   << " is_truncated: " << is_truncated
+			   << dendl;
+    return !is_truncated;
+  }
+
+}; /* RGWReaddirRequest */
+
+/*
+  create bucket
+*/
+
+class RGWCreateBucketRequest : public RGWLibRequest,
+			       public RGWCreateBucket /* RGWOp */
+{
+public:
+  std::string& uri;
+
+  RGWCreateBucketRequest(CephContext* _cct, RGWUserInfo *_user,
+			std::string& _uri)
+    : RGWLibRequest(_cct, _user), uri(_uri) {
+    op = this;
+  }
+
+  virtual bool only_bucket() { return false; }
+
+  virtual int read_permissions(RGWOp* op_obj) {
+    /* we ARE a 'create bucket' request (cf. rgw_rest.cc, ll. 1305-6) */
+    return 0;
+  }
+
+  virtual int op_init() {
+    // assign store, s, and dialect_handler
+    RGWObjectCtx* rados_ctx
+      = static_cast<RGWObjectCtx*>(get_state()->obj_ctx);
+    // framework promises to call op_init after parent init
+    assert(rados_ctx);
+    RGWOp::init(rados_ctx->store, get_state(), this);
+    op = this; // assign self as op: REQUIRED
+    return 0;
+  }
+
+  virtual int header_init() {
+
+    struct req_state* s = get_state();
+    s->info.method = "PUT";
+    s->op = OP_PUT;
+
+    /* XXX derp derp derp */
+    s->relative_uri = uri;
+    s->info.request_uri = uri; // XXX
+    s->info.effective_uri = uri;
+    s->info.request_params = "";
+    s->info.domain = ""; /* XXX ? */
+
+    // woo
+    s->user = user;
+
+    return 0;
+  }
+
+  virtual int get_params() {
+    struct req_state* s = get_state();
+    RGWAccessControlPolicy_S3 s3policy(s->cct);
+    /* we don't have (any) headers, so just create canned ACLs */
+    int ret = s3policy.create_canned(s->owner, s->bucket_owner, s->canned_acl);
+    policy = s3policy;
+    return ret;
+  }
+
+  virtual void send_response() {
+    /* TODO: something (maybe) */
+  }
+}; /* RGWCreateBucketRequest */
+
+/*
+  delete bucket
+*/
+
+class RGWDeleteBucketRequest : public RGWLibRequest,
+			       public RGWDeleteBucket /* RGWOp */
+{
+public:
+  std::string& uri;
+
+  RGWDeleteBucketRequest(CephContext* _cct, RGWUserInfo *_user,
+			std::string& _uri)
+    : RGWLibRequest(_cct, _user), uri(_uri) {
+    op = this;
+  }
+
+  virtual bool only_bucket() { return true; }
+
+  virtual int op_init() {
+    // assign store, s, and dialect_handler
+    RGWObjectCtx* rados_ctx
+      = static_cast<RGWObjectCtx*>(get_state()->obj_ctx);
+    // framework promises to call op_init after parent init
+    assert(rados_ctx);
+    RGWOp::init(rados_ctx->store, get_state(), this);
+    op = this; // assign self as op: REQUIRED
+    return 0;
+  }
+
+  virtual int header_init() {
+
+    struct req_state* s = get_state();
+    s->info.method = "DELETE";
+    s->op = OP_DELETE;
+
+    /* XXX derp derp derp */
+    s->relative_uri = uri;
+    s->info.request_uri = uri; // XXX
+    s->info.effective_uri = uri;
+    s->info.request_params = "";
+    s->info.domain = ""; /* XXX ? */
+
+    // woo
+    s->user = user;
+
+    return 0;
+  }
+
+  virtual void send_response() {}
+
+}; /* RGWDeleteBucketRequest */
+
+/*
+  put object
+*/
+class RGWPutObjRequest : public RGWLibRequest,
+			 public RGWPutObj /* RGWOp */
+{
+public:
+  const std::string& bucket_name;
+  const std::string& obj_name;
+  buffer::list& bl; /* XXX */
+  size_t bytes_written;
+
+  RGWPutObjRequest(CephContext* _cct, RGWUserInfo *_user,
+		  const std::string& _bname, const std::string& _oname,
+		  buffer::list& _bl)
+    : RGWLibRequest(_cct, _user), bucket_name(_bname), obj_name(_oname),
+      bl(_bl), bytes_written(0) {
+    op = this;
+  }
+
+  virtual bool only_bucket() { return true; }
+
+  virtual int op_init() {
+    // assign store, s, and dialect_handler
+    RGWObjectCtx* rados_ctx
+      = static_cast<RGWObjectCtx*>(get_state()->obj_ctx);
+    // framework promises to call op_init after parent init
+    assert(rados_ctx);
+    RGWOp::init(rados_ctx->store, get_state(), this);
+    op = this; // assign self as op: REQUIRED
+
+    if (! valid_s3_object_name(obj_name))
+      return -ERR_INVALID_OBJECT_NAME;
+
+    return 0;
+  }
+
+  virtual int header_init() {
+
+    struct req_state* s = get_state();
+    s->info.method = "PUT";
+    s->op = OP_PUT;
+
+    /* XXX derp derp derp */
+    std::string uri = make_uri(bucket_name, obj_name);
+    s->relative_uri = uri;
+    s->info.request_uri = uri; // XXX
+    s->info.effective_uri = uri;
+    s->info.request_params = "";
+    s->info.domain = ""; /* XXX ? */
+
+    /* XXX required in RGWOp::execute() */
+    s->content_length = bl.length();
+
+    // woo
+    s->user = user;
+
+    return 0;
+  }
+
+  virtual int get_params() {
+    struct req_state* s = get_state();
+    RGWAccessControlPolicy_S3 s3policy(s->cct);
+    /* we don't have (any) headers, so just create canned ACLs */
+    int ret = s3policy.create_canned(s->owner, s->bucket_owner, s->canned_acl);
+    policy = s3policy;
+    return ret;
+  }
+
+  virtual int get_data(buffer::list& _bl) {
+    /* XXX for now, use sharing semantics */
+    _bl.claim(bl);
+    uint32_t len = _bl.length();
+    bytes_written += len;
+    return len;
+  }
+
+  virtual void send_response() {}
+
+  virtual int verify_params() {
+    if (bl.length() > cct->_conf->rgw_max_put_size)
+      return -ERR_TOO_LARGE;
+    return 0;
+  }
+
+}; /* RGWPutObjRequest */
+
+/*
+  get object
+*/
+
+class RGWReadRequest : public RGWLibRequest,
+		       public RGWGetObj /* RGWOp */
+{
+public:
+  RGWFileHandle* rgw_fh;
+  void *ulp_buffer;
+  size_t nread;
+  size_t read_resid; /* initialize to len, <= sizeof(ulp_buffer) */
+  bool do_hexdump = false;
+
+  RGWReadRequest(CephContext* _cct, RGWUserInfo *_user,
+		 RGWFileHandle* _rgw_fh, uint64_t off, uint64_t len,
+		 void *_ulp_buffer)
+    : RGWLibRequest(_cct, _user), rgw_fh(_rgw_fh), ulp_buffer(_ulp_buffer),
+      nread(0), read_resid(len) {
+    op = this;
+
+    /* fixup RGWGetObj (already know range parameters) */
+    RGWGetObj::range_parsed = true;
+    RGWGetObj::get_data = true; // XXX
+    RGWGetObj::partial_content = true;
+    RGWGetObj::ofs = off;
+    RGWGetObj::end = off + len;
+  }
+
+  virtual bool only_bucket() { return false; }
+
+  virtual int op_init() {
+    // assign store, s, and dialect_handler
+    RGWObjectCtx* rados_ctx
+      = static_cast<RGWObjectCtx*>(get_state()->obj_ctx);
+    // framework promises to call op_init after parent init
+    assert(rados_ctx);
+    RGWOp::init(rados_ctx->store, get_state(), this);
+    op = this; // assign self as op: REQUIRED
+    return 0;
+  }
+
+  virtual int header_init() {
+
+    struct req_state* s = get_state();
+    s->info.method = "GET";
+    s->op = OP_GET;
+
+    /* XXX derp derp derp */
+    s->relative_uri = make_uri(rgw_fh->bucket_name(),
+			       rgw_fh->relative_object_name());
+    s->info.request_uri = s->relative_uri; // XXX
+    s->info.effective_uri = s->relative_uri;
+    s->info.request_params = "";
+    s->info.domain = ""; /* XXX ? */
+
+    // woo
+    s->user = user;
+
+    return 0;
+  }
+
+  virtual int get_params() {
+    return 0;
+  }
+
+  virtual int send_response_data(ceph::buffer::list& bl, off_t bl_off,
+				off_t bl_len) {
+    size_t bytes;
+    for (auto& bp : bl.buffers()) {
+      /* if for some reason bl_off indicates the start-of-data is not at
+       * the current buffer::ptr, skip it and account */
+      if (bl_off > bp.length()) {
+	bl_off -= bp.length();
+	continue;
+      }
+      /* read no more than read_resid */
+      bytes = std::min(read_resid, size_t(bp.length()-bl_off));
+      memcpy(static_cast<char*>(ulp_buffer)+nread, bp.c_str()+bl_off, bytes);
+      read_resid -= bytes; /* reduce read_resid by bytes read */
+      nread += bytes;
+      bl_off = 0;
+      /* stop if we have no residual ulp_buffer */
+      if (! read_resid)
+	break;
+    }
+    return 0;
+  }
+
+  virtual int send_response_data_error() {
+    /* S3 implementation just sends nothing--there is no side effect
+     * to simulate here */
+    return 0;
+  }
+
+}; /* RGWReadRequest */
+
+/*
+  delete object
+*/
+
+class RGWDeleteObjRequest : public RGWLibRequest,
+			    public RGWDeleteObj /* RGWOp */
+{
+public:
+  const std::string& bucket_name;
+  const std::string& obj_name;
+
+  RGWDeleteObjRequest(CephContext* _cct, RGWUserInfo *_user,
+		      const std::string& _bname, const std::string& _oname)
+    : RGWLibRequest(_cct, _user), bucket_name(_bname), obj_name(_oname) {
+    op = this;
+  }
+
+  virtual bool only_bucket() { return true; }
+
+  virtual int op_init() {
+    // assign store, s, and dialect_handler
+    RGWObjectCtx* rados_ctx
+      = static_cast<RGWObjectCtx*>(get_state()->obj_ctx);
+    // framework promises to call op_init after parent init
+    assert(rados_ctx);
+    RGWOp::init(rados_ctx->store, get_state(), this);
+    op = this; // assign self as op: REQUIRED
+    return 0;
+  }
+
+  virtual int header_init() {
+
+    struct req_state* s = get_state();
+    s->info.method = "DELETE";
+    s->op = OP_DELETE;
+
+    /* XXX derp derp derp */
+    std::string uri = make_uri(bucket_name, obj_name);
+    s->relative_uri = uri;
+    s->info.request_uri = uri; // XXX
+    s->info.effective_uri = uri;
+    s->info.request_params = "";
+    s->info.domain = ""; /* XXX ? */
+
+    // woo
+    s->user = user;
+
+    return 0;
+  }
+
+  virtual void send_response() {}
+
+}; /* RGWDeleteObjRequest */
+
+class RGWStatObjRequest : public RGWLibRequest,
+			  public RGWGetObj /* RGWOp */
+{
+public:
+  const std::string& bucket_name;
+  const std::string& obj_name;
+  uint64_t _size;
+  uint32_t flags;
+
+  static constexpr uint32_t FLAG_NONE = 0x000;
+
+  RGWStatObjRequest(CephContext* _cct, RGWUserInfo *_user,
+		    const std::string& _bname, const std::string& _oname,
+		    uint32_t _flags)
+    : RGWLibRequest(_cct, _user), bucket_name(_bname), obj_name(_oname),
+      _size(0), flags(_flags) {
+    op = this;
+
+    /* fixup RGWGetObj (already know range parameters) */
+    RGWGetObj::range_parsed = true;
+    RGWGetObj::get_data = false; // XXX
+    RGWGetObj::partial_content = true;
+    RGWGetObj::ofs = 0;
+    RGWGetObj::end = UINT64_MAX;
+  }
+
+  virtual const string name() { return "stat_obj"; }
+  virtual RGWOpType get_type() { return RGW_OP_STAT_OBJ; }
+
+  real_time get_mtime() const {
+    return lastmod;
+  }
+
+  /* attributes */
+  uint64_t get_size() { return _size; }
+  real_time ctime() { return mod_time; } // XXX
+  real_time mtime() { return mod_time; }
+  map<string, bufferlist>& get_attrs() { return attrs; }
+
+  virtual bool only_bucket() { return false; }
+
+  virtual int op_init() {
+    // assign store, s, and dialect_handler
+    RGWObjectCtx* rados_ctx
+      = static_cast<RGWObjectCtx*>(get_state()->obj_ctx);
+    // framework promises to call op_init after parent init
+    assert(rados_ctx);
+    RGWOp::init(rados_ctx->store, get_state(), this);
+    op = this; // assign self as op: REQUIRED
+    return 0;
+  }
+
+  virtual int header_init() {
+
+    struct req_state* s = get_state();
+    s->info.method = "GET";
+    s->op = OP_GET;
+
+    /* XXX derp derp derp */
+    s->relative_uri = make_uri(bucket_name, obj_name);
+    s->info.request_uri = s->relative_uri; // XXX
+    s->info.effective_uri = s->relative_uri;
+    s->info.request_params = "";
+    s->info.domain = ""; /* XXX ? */
+
+    // woo
+    s->user = user;
+
+    return 0;
+  }
+
+  virtual int get_params() {
+    return 0;
+  }
+
+  virtual int send_response_data(ceph::buffer::list& _bl, off_t s_off,
+				off_t e_off) {
+    /* NOP */
+    return 0;
+  }
+
+  virtual int send_response_data_error() {
+    /* NOP */
+    return 0;
+  }
+
+  virtual void execute() {
+    RGWGetObj::execute();
+    _size = get_state()->obj_size;
+  }
+
+}; /* RGWStatObjRequest */
+
+class RGWStatBucketRequest : public RGWLibRequest,
+			     public RGWStatBucket /* RGWOp */
+{
+public:
+  std::string uri;
+
+  RGWStatBucketRequest(CephContext* _cct, RGWUserInfo *_user,
+		       const std::string& _path)
+    : RGWLibRequest(_cct, _user) {
+    uri = "/" + _path;
+    op = this;
+  }
+
+  virtual bool only_bucket() { return false; }
+
+  virtual int op_init() {
+    // assign store, s, and dialect_handler
+    RGWObjectCtx* rados_ctx
+      = static_cast<RGWObjectCtx*>(get_state()->obj_ctx);
+    // framework promises to call op_init after parent init
+    assert(rados_ctx);
+    RGWOp::init(rados_ctx->store, get_state(), this);
+    op = this; // assign self as op: REQUIRED
+    return 0;
+  }
+
+  virtual int header_init() {
+
+    struct req_state* s = get_state();
+    s->info.method = "GET";
+    s->op = OP_GET;
+
+    /* XXX derp derp derp */
+    s->relative_uri = uri;
+    s->info.request_uri = uri; // XXX
+    s->info.effective_uri = uri;
+    s->info.request_params = "";
+    s->info.domain = ""; /* XXX ? */
+
+    // woo
+    s->user = user;
+
+    return 0;
+  }
+
+  real_time get_ctime() const {
+    return bucket.creation_time;
+  }
+
+  virtual int get_params() {
+    return 0;
+  }
+
+  virtual void send_response() {
+    bucket.creation_time = get_state()->bucket_info.creation_time;
+  }
+
+  bool matched() {
+    return (bucket.bucket.name.length() > 0);
+  }
+
+}; /* RGWStatBucketRequest */
+
+class RGWStatLeafRequest : public RGWLibRequest,
+			   public RGWListBucket /* RGWOp */
+{
+public:
+  RGWFileHandle* rgw_fh;
+  std::string path;
+  bool matched;
+  bool is_dir;
+
+  RGWStatLeafRequest(CephContext* _cct, RGWUserInfo *_user,
+		     RGWFileHandle* _rgw_fh, const std::string& _path)
+    : RGWLibRequest(_cct, _user), rgw_fh(_rgw_fh), path(_path),
+      matched(false), is_dir(false) {
+    default_max = 1000; // logical max {"foo", "foo/"}
+    op = this;
+  }
+
+  virtual bool only_bucket() { return false; }
+
+  virtual int op_init() {
+    // assign store, s, and dialect_handler
+    RGWObjectCtx* rados_ctx
+      = static_cast<RGWObjectCtx*>(get_state()->obj_ctx);
+    // framework promises to call op_init after parent init
+    assert(rados_ctx);
+    RGWOp::init(rados_ctx->store, get_state(), this);
+    op = this; // assign self as op: REQUIRED
+    return 0;
+  }
+
+  virtual int header_init() {
+
+    struct req_state* s = get_state();
+    s->info.method = "GET";
+    s->op = OP_GET;
+
+    /* XXX derp derp derp */
+    std::string uri = "/" + rgw_fh->bucket_name() + "/";
+    s->relative_uri = uri;
+    s->info.request_uri = uri; // XXX
+    s->info.effective_uri = uri;
+    s->info.request_params = "";
+    s->info.domain = ""; /* XXX ? */
+
+    // woo
+    s->user = user;
+
+    prefix = rgw_fh->relative_object_name();
+    if (prefix.length() > 0)
+      prefix += "/";
+    prefix += path;
+    delimiter = '/';
+
+    return 0;
+  }
+
+  virtual int get_params() {
+    max = default_max;
+    return 0;
+  }
+
+  virtual void send_response() {
+    struct req_state* s = get_state();
+    // try objects
+    for (const auto& iter : objs) {
+      auto& name = iter.key.name;
+      lsubdout(cct, rgw, 15) << "RGWStatLeafRequest "
+			     << __func__ << " "
+			     << "list uri=" << s->relative_uri << " "
+			     << " prefix=" << prefix << " "
+			     << " obj path=" << name << ""
+			     << dendl;
+      /* XXX is there a missing match-dir case (trailing '/')? */
+      matched = true;
+      return;
+    }
+    // try prefixes
+    for (auto& iter : common_prefixes) {
+      auto& name = iter.first;
+      lsubdout(cct, rgw, 15) << "RGWStatLeafRequest "
+			     << __func__ << " "
+			     << "list uri=" << s->relative_uri << " "
+			     << " prefix=" << prefix << " "
+			     << " pref path=" << name << " (not chomped)"
+			     << dendl;
+      matched = true;
+      is_dir = true;
+      break;
+    }
+  }
+
+  virtual void send_versioned_response() {
+    send_response();
+  }
+}; /* RGWStatLeafRequest */
+
+/*
+  put object
+*/
+
+class RGWWriteRequest : public RGWLibContinuedReq,
+			public RGWPutObj /* RGWOp */
+{
+public:
+  const std::string& bucket_name;
+  const std::string& obj_name;
+  RGWFileHandle* rgw_fh;
+  RGWPutObjProcessor *processor;
+  buffer::list data;
+  MD5 hash;
+  off_t last_off;
+  off_t next_off;
+  size_t bytes_written;
+  bool multipart;
+
+  RGWWriteRequest(CephContext* _cct, RGWUserInfo *_user, RGWFileHandle* _fh,
+		  const std::string& _bname, const std::string& _oname)
+    : RGWLibContinuedReq(_cct, _user), bucket_name(_bname), obj_name(_oname),
+      rgw_fh(_fh), processor(nullptr), last_off(0), next_off(0),
+      bytes_written(0), multipart(false) {
+
+    int ret = header_init();
+    if (ret == 0) {
+      ret = init_from_header(get_state());
+    }
+    op = this;
+  }
+
+  virtual bool only_bucket() { return true; }
+
+  virtual int op_init() {
+    // assign store, s, and dialect_handler
+    RGWObjectCtx* rados_ctx
+      = static_cast<RGWObjectCtx*>(get_state()->obj_ctx);
+    // framework promises to call op_init after parent init
+    assert(rados_ctx);
+    RGWOp::init(rados_ctx->store, get_state(), this);
+    op = this; // assign self as op: REQUIRED
+    return 0;
+  }
+
+  virtual int header_init() {
+
+    struct req_state* s = get_state();
+    s->info.method = "PUT";
+    s->op = OP_PUT;
+
+    /* XXX derp derp derp */
+    std::string uri = make_uri(bucket_name, obj_name);
+    s->relative_uri = uri;
+    s->info.request_uri = uri; // XXX
+    s->info.effective_uri = uri;
+    s->info.request_params = "";
+    s->info.domain = ""; /* XXX ? */
+
+    // woo
+    s->user = user;
+
+    return 0;
+  }
+
+  virtual RGWPutObjProcessor *select_processor(RGWObjectCtx& obj_ctx,
+					       bool *is_multipart) {
+    struct req_state* s = get_state();
+    uint64_t part_size = s->cct->_conf->rgw_obj_stripe_size;
+    RGWPutObjProcessor_Atomic *processor =
+      new RGWPutObjProcessor_Atomic(obj_ctx, s->bucket_info, s->bucket,
+				    s->object.name, part_size, s->req_id,
+				    s->bucket_info.versioning_enabled());
+    processor->set_olh_epoch(olh_epoch);
+    processor->set_version_id(version_id);
+    return processor;
+  }
+
+  virtual int get_params() {
+    struct req_state* s = get_state();
+    RGWAccessControlPolicy_S3 s3policy(s->cct);
+    /* we don't have (any) headers, so just create canned ACLs */
+    int ret = s3policy.create_canned(s->owner, s->bucket_owner, s->canned_acl);
+    policy = s3policy;
+    return ret;
+  }
+
+  virtual int get_data(buffer::list& _bl) {
+    /* XXX for now, use sharing semantics */
+    uint32_t len = data.length();
+    _bl.claim(data);
+    bytes_written += len;
+    return len;
+  }
+
+  void put_data(off_t off, buffer::list& _bl) {
+    ofs = off;
+    data.claim(_bl);
+  }
+
+  virtual int exec_start();
+  virtual int exec_continue();
+  virtual int exec_finish();
+
+  virtual void send_response() {}
+
+  virtual int verify_params() {
+    return 0;
+  }
+}; /* RGWWriteRequest */
+
+/*
+  copy object
+*/
+class RGWCopyObjRequest : public RGWLibRequest,
+			  public RGWCopyObj /* RGWOp */
+{
+public:
+  RGWFileHandle* src_parent;
+  RGWFileHandle* dst_parent;
+  const std::string& src_name;
+  const std::string& dst_name;
+
+  RGWCopyObjRequest(CephContext* _cct, RGWUserInfo *_user,
+		    RGWFileHandle* _src_parent, RGWFileHandle* _dst_parent,
+		    const std::string& _src_name, const std::string& _dst_name)
+    : RGWLibRequest(_cct, _user), src_parent(_src_parent),
+      dst_parent(_dst_parent), src_name(_src_name), dst_name(_dst_name) {
+    op = this;
+  }
+
+  virtual bool only_bucket() { return true; }
+
+  virtual int op_init() {
+    // assign store, s, and dialect_handler
+    RGWObjectCtx* rados_ctx
+      = static_cast<RGWObjectCtx*>(get_state()->obj_ctx);
+    // framework promises to call op_init after parent init
+    assert(rados_ctx);
+    RGWOp::init(rados_ctx->store, get_state(), this);
+    op = this; // assign self as op: REQUIRED
+
+    return 0;
+  }
+
+  virtual int header_init() {
+
+    struct req_state* s = get_state();
+    s->info.method = "PUT"; // XXX check
+    s->op = OP_PUT;
+
+    src_bucket_name = src_parent->bucket_name();
+    // need s->src_bucket_name?
+    src_object.name = src_parent->format_child_name(src_name);
+    // need s->src_object?
+
+    dest_bucket_name = dst_parent->bucket_name();
+    // need s->bucket.name?
+    dest_object = dst_parent->format_child_name(dst_name);
+    // need s->object_name?
+
+    if (! valid_s3_object_name(dest_object))
+      return -ERR_INVALID_OBJECT_NAME;
+
+#if 0 /* XXX needed? */
+    s->relative_uri = uri;
+    s->info.request_uri = uri; // XXX
+    s->info.effective_uri = uri;
+    s->info.request_params = "";
+    s->info.domain = ""; /* XXX ? */
+#endif
+
+    // woo
+    s->user = user;
+
+    return 0;
+  }
+
+  virtual int get_params() {
+    struct req_state* s = get_state();
+    RGWAccessControlPolicy_S3 s3policy(s->cct);
+    /* we don't have (any) headers, so just create canned ACLs */
+    int ret = s3policy.create_canned(s->owner, s->bucket_owner, s->canned_acl);
+    dest_policy = s3policy;
+    return ret;
+  }
+
+  virtual void send_response() {}
+  virtual void send_partial_response(off_t ofs) {}
+
+}; /* RGWCopyObjRequest */
+
+
+} /* namespace rgw */
+
+#endif /* RGW_FILE_H */
diff --git a/src/rgw/rgw_frontend.cc b/src/rgw/rgw_frontend.cc
new file mode 100644
index 0000000..24e186e
--- /dev/null
+++ b/src/rgw/rgw_frontend.cc
@@ -0,0 +1,86 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+
+#include <signal.h>
+
+#include "rgw_frontend.h"
+#include "include/str_list.h"
+
+#include "include/assert.h"
+
+
+#define dout_subsys ceph_subsys_rgw
+
+int RGWFrontendConfig::parse_config(const string& config,
+				    map<string, string>& config_map)
+{
+  list<string> config_list;
+  get_str_list(config, " ", config_list);
+
+  list<string>::iterator iter;
+  for (iter = config_list.begin(); iter != config_list.end(); ++iter) {
+    string& entry = *iter;
+    string key;
+    string val;
+
+    if (framework.empty()) {
+      framework = entry;
+      dout(0) << "framework: " << framework << dendl;
+      continue;
+    }
+
+    ssize_t pos = entry.find('=');
+    if (pos < 0) {
+      dout(0) << "framework conf key: " << entry << dendl;
+      config_map[entry] = "";
+      continue;
+    }
+
+    int ret = parse_key_value(entry, key, val);
+    if (ret < 0) {
+      cerr << "ERROR: can't parse " << entry << std::endl;
+      return ret;
+    }
+
+    dout(0) << "framework conf key: " << key << ", val: " << val << dendl;
+    config_map[key] = val;
+  }
+
+  return 0;
+}
+
+bool RGWFrontendConfig::get_val(const string& key, const string& def_val,
+				string *out)
+{
+ map<string, string>::iterator iter = config_map.find(key);
+ if (iter == config_map.end()) {
+   *out = def_val;
+   return false;
+ }
+
+ *out = iter->second;
+ return true;
+}
+
+bool RGWFrontendConfig::get_val(const string& key, int def_val, int *out)
+{
+  string str;
+  bool found = get_val(key, "", &str);
+  if (!found) {
+    *out = def_val;
+    return false;
+  }
+  string err;
+  *out = strict_strtol(str.c_str(), 10, &err);
+  if (!err.empty()) {
+    cerr << "error parsing int: " << str << ": " << err << std::endl;
+    return -EINVAL;
+  }
+  return 0;
+}
+
+void RGWProcessFrontend::stop()
+{
+  pprocess->close_fd();
+  thread->kill(SIGUSR1);
+}
diff --git a/src/rgw/rgw_frontend.h b/src/rgw/rgw_frontend.h
new file mode 100644
index 0000000..928a03b
--- /dev/null
+++ b/src/rgw/rgw_frontend.h
@@ -0,0 +1,224 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+
+#ifndef RGW_FRONTEND_H
+#define RGW_FRONTEND_H
+
+#include "rgw_request.h"
+#include "rgw_process.h"
+#include "rgw_realm_reloader.h"
+
+#include "rgw_civetweb.h"
+#include "rgw_civetweb_log.h"
+#include "civetweb/civetweb.h"
+
+#define dout_subsys ceph_subsys_rgw
+
+class RGWFrontendConfig {
+  string config;
+  map<string, string> config_map;
+  int parse_config(const string& config, map<string, string>& config_map);
+  string framework;
+public:
+  RGWFrontendConfig(const string& _conf) : config(_conf) {}
+  int init() {
+    int ret = parse_config(config, config_map);
+    if (ret < 0)
+      return ret;
+    return 0;
+  }
+  bool get_val(const string& key, const string& def_val, string *out);
+  bool get_val(const string& key, int def_val, int *out);
+
+  map<string, string>& get_config_map() { return config_map; }
+
+  string get_framework() { return framework; }
+};
+
+class RGWFrontend {
+public:
+  virtual ~RGWFrontend() {}
+
+  virtual int init() = 0;
+
+  virtual int run() = 0;
+  virtual void stop() = 0;
+  virtual void join() = 0;
+
+  virtual void pause_for_new_config() = 0;
+  virtual void unpause_with_new_config(RGWRados *store) = 0;
+};
+
+struct RGWMongooseEnv : public RGWProcessEnv {
+  // every request holds a read lock, so we need to prioritize write locks to
+  // avoid starving pause_for_new_config()
+  static constexpr bool prioritize_write = true;
+  RWLock mutex;
+  RGWMongooseEnv(const RGWProcessEnv &env)
+    : RGWProcessEnv(env),
+      mutex("RGWMongooseFrontend", false, true, prioritize_write) {}
+};
+
+class RGWMongooseFrontend : public RGWFrontend {
+  RGWFrontendConfig* conf;
+  struct mg_context* ctx;
+  RGWMongooseEnv env;
+
+  void set_conf_default(map<string, string>& m, const string& key,
+			const string& def_val) {
+    if (m.find(key) == m.end()) {
+      m[key] = def_val;
+    }
+  }
+
+public:
+  RGWMongooseFrontend(RGWProcessEnv& pe, RGWFrontendConfig* _conf)
+    : conf(_conf), ctx(nullptr), env(pe) {
+  }
+
+  int init() {
+    return 0;
+  }
+
+  int run();
+
+  void stop() {
+    if (ctx) {
+      mg_stop(ctx);
+    }
+  }
+
+  void join() {
+  }
+
+  void pause_for_new_config() override {
+    // block callbacks until unpause
+    env.mutex.get_write();
+  }
+
+  void unpause_with_new_config(RGWRados *store) override {
+    env.store = store;
+    // unpause callbacks
+    env.mutex.put_write();
+  }
+}; /* RGWMongooseFrontend */
+
+class RGWProcessFrontend : public RGWFrontend {
+protected:
+  RGWFrontendConfig* conf;
+  RGWProcess* pprocess;
+  RGWProcessEnv env;
+  RGWProcessControlThread* thread;
+
+public:
+  RGWProcessFrontend(RGWProcessEnv& pe, RGWFrontendConfig* _conf)
+    : conf(_conf), pprocess(nullptr), env(pe), thread(nullptr) {
+  }
+
+  ~RGWProcessFrontend() {
+    delete thread;
+    delete pprocess;
+  }
+
+  int run() {
+    assert(pprocess); /* should have initialized by init() */
+    thread = new RGWProcessControlThread(pprocess);
+    thread->create("rgw_frontend");
+    return 0;
+  }
+
+  void stop();
+
+  void join() {
+    thread->join();
+  }
+
+  void pause_for_new_config() override {
+    pprocess->pause();
+  }
+
+  void unpause_with_new_config(RGWRados *store) override {
+    env.store = store;
+    pprocess->unpause_with_new_config(store);
+  }
+}; /* RGWProcessFrontend */
+
+class RGWFCGXFrontend : public RGWProcessFrontend {
+public:
+  RGWFCGXFrontend(RGWProcessEnv& pe, RGWFrontendConfig* _conf)
+    : RGWProcessFrontend(pe, _conf) {}
+
+  int init() {
+    pprocess = new RGWFCGXProcess(g_ceph_context, &env,
+				  g_conf->rgw_thread_pool_size, conf);
+    return 0;
+  }
+}; /* RGWFCGXFrontend */
+
+class RGWLoadGenFrontend : public RGWProcessFrontend {
+public:
+  RGWLoadGenFrontend(RGWProcessEnv& pe, RGWFrontendConfig *_conf)
+    : RGWProcessFrontend(pe, _conf) {}
+
+  int init() {
+    int num_threads;
+    conf->get_val("num_threads", g_conf->rgw_thread_pool_size, &num_threads);
+    RGWLoadGenProcess *pp = new RGWLoadGenProcess(g_ceph_context, &env,
+						  num_threads, conf);
+
+    pprocess = pp;
+
+    string uid_str;
+    conf->get_val("uid", "", &uid_str);
+    if (uid_str.empty()) {
+      derr << "ERROR: uid param must be specified for loadgen frontend"
+	   << dendl;
+      return EINVAL;
+    }
+
+    rgw_user uid(uid_str);
+
+    RGWUserInfo user_info;
+    int ret = rgw_get_user_info_by_uid(env.store, uid, user_info, NULL);
+    if (ret < 0) {
+      derr << "ERROR: failed reading user info: uid=" << uid << " ret="
+	   << ret << dendl;
+      return ret;
+    }
+
+    map<string, RGWAccessKey>::iterator aiter = user_info.access_keys.begin();
+    if (aiter == user_info.access_keys.end()) {
+      derr << "ERROR: user has no S3 access keys set" << dendl;
+      return -EINVAL;
+    }
+
+    pp->set_access_key(aiter->second);
+
+    return 0;
+  }
+}; /* RGWLoadGenFrontend */
+
+// FrontendPauser implementation for RGWRealmReloader
+class RGWFrontendPauser : public RGWRealmReloader::Pauser {
+  std::list<RGWFrontend*> &frontends;
+  RGWRealmReloader::Pauser* pauser;
+ public:
+  RGWFrontendPauser(std::list<RGWFrontend*> &frontends,
+                    RGWRealmReloader::Pauser* pauser = nullptr)
+    : frontends(frontends), pauser(pauser) {}
+
+  void pause() override {
+    for (auto frontend : frontends)
+      frontend->pause_for_new_config();
+    if (pauser)
+      pauser->pause();
+  }
+  void resume(RGWRados *store) {
+    for (auto frontend : frontends)
+      frontend->unpause_with_new_config(store);
+    if (pauser)
+      pauser->resume(store);
+  }
+};
+
+#endif /* RGW_FRONTEND_H */
diff --git a/src/rgw/rgw_http_client.cc b/src/rgw/rgw_http_client.cc
index 4fedff9..b15ab66 100644
--- a/src/rgw/rgw_http_client.cc
+++ b/src/rgw/rgw_http_client.cc
@@ -7,6 +7,10 @@
 
 #include "rgw_common.h"
 #include "rgw_http_client.h"
+#include "rgw_http_errors.h"
+#include "common/RefCountedObj.h"
+
+#include "rgw_coroutine.h"
 
 #define dout_subsys ceph_subsys_rgw
 
@@ -82,6 +86,9 @@ int RGWHTTPClient::process(const char *method, const char *url)
 
   char error_buf[CURL_ERROR_SIZE];
 
+  last_method = (method ? method : "");
+  last_url = (url ? url : "");
+
   curl_handle = curl_easy_init();
 
   dout(20) << "sending request to " << url << dendl;
@@ -106,63 +113,110 @@ int RGWHTTPClient::process(const char *method, const char *url)
   if (has_send_len) {
     curl_easy_setopt(curl_handle, CURLOPT_INFILESIZE, (void *)send_len); 
   }
+  if (!verify_ssl) {
+    curl_easy_setopt(curl_handle, CURLOPT_SSL_VERIFYPEER, 0L);
+    curl_easy_setopt(curl_handle, CURLOPT_SSL_VERIFYHOST, 0L);
+    dout(20) << "ssl verification is set to off" << dendl;
+  }
+
   CURLcode status = curl_easy_perform(curl_handle);
   if (status) {
     dout(0) << "curl_easy_perform returned error: " << error_buf << dendl;
     ret = -EINVAL;
   }
+  curl_easy_getinfo(curl_handle, CURLINFO_RESPONSE_CODE, &http_status);
   curl_easy_cleanup(curl_handle);
   curl_slist_free_all(h);
 
   return ret;
 }
 
-struct multi_req_data {
+struct rgw_http_req_data : public RefCountedObject {
   CURL *easy_handle;
-  CURLM *multi_handle;
   curl_slist *h;
+  uint64_t id;
+  int ret;
+  atomic_t done;
+  RGWHTTPClient *client;
+  RGWHTTPManager *mgr;
+  char error_buf[CURL_ERROR_SIZE];
 
-  multi_req_data() : easy_handle(NULL), multi_handle(NULL), h(NULL) {}
-  ~multi_req_data() {
-    if (multi_handle)
-      curl_multi_cleanup(multi_handle);
+  Mutex lock;
+  Cond cond;
+
+  rgw_http_req_data() : easy_handle(NULL), h(NULL), id(-1), ret(0), client(NULL),
+                        mgr(NULL), lock("rgw_http_req_data::lock") {
+    memset(error_buf, 0, sizeof(error_buf));
+  }
+
+  int wait() {
+    Mutex::Locker l(lock);
+    cond.Wait(lock);
+    return ret;
+  }
 
+  void finish(int r) {
+    Mutex::Locker l(lock);
+    ret = r;
+    cond.Signal();
+    done.set(1);
     if (easy_handle)
       curl_easy_cleanup(easy_handle);
 
     if (h)
       curl_slist_free_all(h);
+
+    easy_handle = NULL;
+    h = NULL;
+  }
+
+  bool is_done() {
+    return done.read() != 0;
+  }
+
+  int get_retcode() {
+    Mutex::Locker l(lock);
+    return ret;
   }
 };
 
-int RGWHTTPClient::init_async(const char *method, const char *url, void **handle)
+string RGWHTTPClient::to_str()
 {
-  CURL *easy_handle;
-  CURLM *multi_handle;
-  multi_req_data *req_data = new multi_req_data;
-  *handle = (void *)req_data;
+  string method_str = (last_method.empty() ? "<no-method>" : last_method);
+  string url_str = (last_url.empty() ? "<no-url>" : last_url);
+  return method_str + " " + url_str;
+}
 
-  char error_buf[CURL_ERROR_SIZE];
+int RGWHTTPClient::get_req_retcode()
+{
+  if (!req_data) {
+    return -EINVAL;
+  }
+
+  return req_data->get_retcode();
+}
+
+int RGWHTTPClient::init_request(const char *method, const char *url, rgw_http_req_data *_req_data)
+{
+  assert(!req_data);
+  _req_data->get();
+  req_data = _req_data;
+
+  CURL *easy_handle;
 
-  multi_handle = curl_multi_init();
   easy_handle = curl_easy_init();
 
-  req_data->multi_handle = multi_handle;
   req_data->easy_handle = easy_handle;
 
-  CURLMcode mstatus = curl_multi_add_handle(multi_handle, easy_handle);
-  if (mstatus) {
-    dout(0) << "ERROR: failed on curl_multi_add_handle, status=" << mstatus << dendl;
-    delete req_data;
-    return -EIO;
-  }
-
   dout(20) << "sending request to " << url << dendl;
 
   curl_slist *h = headers_to_slist(headers);
 
   req_data->h = h;
 
+  last_method = (method ? method : "");
+  last_url = (url ? url : "");
+
   curl_easy_setopt(easy_handle, CURLOPT_CUSTOMREQUEST, method);
   curl_easy_setopt(easy_handle, CURLOPT_URL, url);
   curl_easy_setopt(easy_handle, CURLOPT_NOPROGRESS, 1L);
@@ -171,7 +225,7 @@ int RGWHTTPClient::init_async(const char *method, const char *url, void **handle
   curl_easy_setopt(easy_handle, CURLOPT_WRITEHEADER, (void *)this);
   curl_easy_setopt(easy_handle, CURLOPT_WRITEFUNCTION, receive_http_data);
   curl_easy_setopt(easy_handle, CURLOPT_WRITEDATA, (void *)this);
-  curl_easy_setopt(easy_handle, CURLOPT_ERRORBUFFER, (void *)error_buf);
+  curl_easy_setopt(easy_handle, CURLOPT_ERRORBUFFER, (void *)req_data->error_buf);
   if (h) {
     curl_easy_setopt(easy_handle, CURLOPT_HTTPHEADER, (void *)h);
   }
@@ -181,26 +235,60 @@ int RGWHTTPClient::init_async(const char *method, const char *url, void **handle
   if (has_send_len) {
     curl_easy_setopt(easy_handle, CURLOPT_INFILESIZE, (void *)send_len); 
   }
+  curl_easy_setopt(easy_handle, CURLOPT_PRIVATE, (void *)req_data);
 
   return 0;
 }
 
+int RGWHTTPClient::wait()
+{
+  if (!req_data->is_done()) {
+    return req_data->wait();
+  }
+
+  return req_data->ret;
+}
+
+RGWHTTPClient::~RGWHTTPClient()
+{
+  if (req_data) {
+    req_data->put();
+  }
+}
+
+
 #if HAVE_CURL_MULTI_WAIT
 
-static int do_curl_wait(CephContext *cct, CURLM *handle)
+static int do_curl_wait(CephContext *cct, CURLM *handle, int signal_fd)
 {
   int num_fds;
-  int ret = curl_multi_wait(handle, NULL, 0, cct->_conf->rgw_curl_wait_timeout_ms, &num_fds);
+  struct curl_waitfd wait_fd;
+
+  wait_fd.fd = signal_fd;
+  wait_fd.events = CURL_WAIT_POLLIN;
+  wait_fd.revents = 0;
+
+  int ret = curl_multi_wait(handle, &wait_fd, 1, cct->_conf->rgw_curl_wait_timeout_ms, &num_fds);
   if (ret) {
     dout(0) << "ERROR: curl_multi_wait() returned " << ret << dendl;
     return -EIO;
   }
+
+  if (wait_fd.revents > 0) {
+    uint32_t buf;
+    ret = read(signal_fd, (void *)&buf, sizeof(buf));
+    if (ret < 0) {
+      ret = -errno;
+      dout(0) << "ERROR: " << __func__ << "(): read() returned " << ret << dendl;
+      return ret;
+    }
+  }
   return 0;
 }
 
 #else
 
-static int do_curl_wait(CephContext *cct, CURLM *handle)
+static int do_curl_wait(CephContext *cct, CURLM *handle, int signal_fd)
 {
   fd_set fdread;
   fd_set fdwrite;
@@ -214,10 +302,14 @@ static int do_curl_wait(CephContext *cct, CURLM *handle)
   /* get file descriptors from the transfers */ 
   int ret = curl_multi_fdset(handle, &fdread, &fdwrite, &fdexcep, &maxfd);
   if (ret) {
-    dout(0) << "ERROR: curl_multi_fdset returned " << ret << dendl;
+    generic_dout(0) << "ERROR: curl_multi_fdset returned " << ret << dendl;
     return -EIO;
   }
 
+  if (signal_fd >= maxfd) {
+    maxfd = signal_fd + 1;
+  }
+
   /* forcing a strict timeout, as the returned fdsets might not reference all fds we wait on */
   uint64_t to = cct->_conf->rgw_curl_wait_timeout_ms;
 #define RGW_CURL_TIMEOUT 1000
@@ -234,43 +326,197 @@ static int do_curl_wait(CephContext *cct, CURLM *handle)
     return ret;
   }
 
+  if (signal_fd > 0 && FD_ISSET(signal_fd, &fdread)) {
+    uint32_t buf;
+    ret = read(signal_fd, (void *)&buf, sizeof(buf));
+    if (ret < 0) {
+      ret = -errno;
+      dout(0) << "ERROR: " << __func__ << "(): read() returned " << ret << dendl;
+      return ret;
+    }
+  }
+
   return 0;
 }
 
 #endif
 
-int RGWHTTPClient::process_request(void *handle, bool wait_for_data, bool *done)
+void *RGWHTTPManager::ReqsThread::entry()
+{
+  manager->reqs_thread_entry();
+  return NULL;
+}
+
+RGWHTTPManager::RGWHTTPManager(CephContext *_cct, RGWCompletionManager *_cm) : cct(_cct),
+                                                    completion_mgr(_cm), is_threaded(false),
+                                                    reqs_lock("RGWHTTPManager::reqs_lock"), num_reqs(0), max_threaded_req(0),
+                                                    reqs_thread(NULL)
+{
+  multi_handle = (void *)curl_multi_init();
+  thread_pipe[0] = -1;
+  thread_pipe[1] = -1;
+}
+
+RGWHTTPManager::~RGWHTTPManager() {
+  stop();
+  if (multi_handle)
+    curl_multi_cleanup((CURLM *)multi_handle);
+}
+
+void RGWHTTPManager::register_request(rgw_http_req_data *req_data)
+{
+  RWLock::WLocker rl(reqs_lock);
+  req_data->id = num_reqs;
+  reqs[num_reqs] = req_data;
+  num_reqs++;
+  ldout(cct, 20) << __func__ << " mgr=" << this << " req_data->id=" << req_data->id << ", easy_handle=" << req_data->easy_handle << dendl;
+}
+
+void RGWHTTPManager::complete_request(rgw_http_req_data *req_data)
 {
-  multi_req_data *req_data = static_cast<multi_req_data *>(handle);
+  RWLock::WLocker rl(reqs_lock);
+  _complete_request(req_data);
+}
+
+void RGWHTTPManager::_complete_request(rgw_http_req_data *req_data)
+{
+  map<uint64_t, rgw_http_req_data *>::iterator iter = reqs.find(req_data->id);
+  if (iter != reqs.end()) {
+    reqs.erase(iter);
+  }
+  if (completion_mgr) {
+    completion_mgr->complete(NULL, req_data->client->get_user_info());
+  }
+  req_data->put();
+}
+
+void RGWHTTPManager::finish_request(rgw_http_req_data *req_data, int ret)
+{
+  req_data->finish(ret);
+  complete_request(req_data);
+}
+
+void RGWHTTPManager::_finish_request(rgw_http_req_data *req_data, int ret)
+{
+  req_data->finish(ret);
+  _complete_request(req_data);
+}
+
+int RGWHTTPManager::link_request(rgw_http_req_data *req_data)
+{
+  ldout(cct, 20) << __func__ << " req_data=" << req_data << " req_data->id=" << req_data->id << ", easy_handle=" << req_data->easy_handle << dendl;
+  CURLMcode mstatus = curl_multi_add_handle((CURLM *)multi_handle, req_data->easy_handle);
+  if (mstatus) {
+    dout(0) << "ERROR: failed on curl_multi_add_handle, status=" << mstatus << dendl;
+    return -EIO;
+  }
+  return 0;
+}
+
+void RGWHTTPManager::link_pending_requests()
+{
+  reqs_lock.get_read();
+  if (max_threaded_req == num_reqs) {
+    reqs_lock.unlock();
+    return;
+  }
+  reqs_lock.unlock();
+
+  RWLock::WLocker wl(reqs_lock);
+
+  map<uint64_t, rgw_http_req_data *>::iterator iter = reqs.find(max_threaded_req);
+
+  list<std::pair<rgw_http_req_data *, int> > remove_reqs;
+
+  for (; iter != reqs.end(); ++iter) {
+    rgw_http_req_data *req_data = iter->second;
+    int r = link_request(req_data);
+    if (r < 0) {
+      ldout(cct, 0) << "ERROR: failed to link http request" << dendl;
+      remove_reqs.push_back(std::make_pair(iter->second, r));
+    } else {
+      max_threaded_req = iter->first + 1;
+    }
+  }
+
+  for (auto piter : remove_reqs) {
+    rgw_http_req_data *req_data = piter.first;
+    int r = piter.second;
+
+    _finish_request(req_data, r);
+  }
+}
+
+int RGWHTTPManager::add_request(RGWHTTPClient *client, const char *method, const char *url)
+{
+  rgw_http_req_data *req_data = new rgw_http_req_data;
+
+  int ret = client->init_request(method, url, req_data);
+  if (ret < 0) {
+    req_data->put();
+    return ret;
+  }
+
+  req_data->mgr = this;
+  req_data->client = client;
+
+  register_request(req_data);
+
+  if (!is_threaded) {
+    ret = link_request(req_data);
+    return ret;
+  }
+  ret = signal_thread();
+  if (ret < 0) {
+    finish_request(req_data, ret);
+  }
+
+  return ret;
+}
+
+int RGWHTTPManager::process_requests(bool wait_for_data, bool *done)
+{
+  assert(!is_threaded);
+
   int still_running;
   int mstatus;
 
   do {
     if (wait_for_data) {
-      int ret = do_curl_wait(cct, req_data->multi_handle);
+      int ret = do_curl_wait(cct, (CURLM *)multi_handle, -1);
       if (ret < 0) {
         return ret;
       }
     }
 
-    mstatus = curl_multi_perform(req_data->multi_handle, &still_running);
-    dout(20) << "curl_multi_perform returned: " << mstatus << dendl;
+    mstatus = curl_multi_perform((CURLM *)multi_handle, &still_running);
     switch (mstatus) {
       case CURLM_OK:
       case CURLM_CALL_MULTI_PERFORM:
         break;
       default:
+        dout(20) << "curl_multi_perform returned: " << mstatus << dendl;
         return -EINVAL;
     }
     int msgs_left;
     CURLMsg *msg;
-    while ((msg = curl_multi_info_read(req_data->multi_handle, &msgs_left))) {
+    while ((msg = curl_multi_info_read((CURLM *)multi_handle, &msgs_left))) {
       if (msg->msg == CURLMSG_DONE) {
-        switch (msg->data.result) {
+	CURL *e = msg->easy_handle;
+	rgw_http_req_data *req_data;
+	curl_easy_getinfo(e, CURLINFO_PRIVATE, (void **)&req_data);
+
+	long http_status;
+	curl_easy_getinfo(e, CURLINFO_RESPONSE_CODE, (void **)&http_status);
+
+	int status = rgw_http_error_to_errno(http_status);
+	int result = msg->data.result;
+	finish_request(req_data, status);
+        switch (result) {
           case CURLE_OK:
             break;
           default:
-            dout(20) << "ERROR: msg->data.result=" << msg->data.result << dendl;
+            dout(20) << "ERROR: msg->data.result=" << result << dendl;
             return -EIO;
         }
       }
@@ -282,15 +528,122 @@ int RGWHTTPClient::process_request(void *handle, bool wait_for_data, bool *done)
   return 0;
 }
 
-int RGWHTTPClient::complete_request(void *handle)
+int RGWHTTPManager::complete_requests()
 {
   bool done;
   int ret;
   do {
-    ret = process_request(handle, true, &done);
+    ret = process_requests(true, &done);
   } while (!done && !ret);
-  multi_req_data *req_data = static_cast<multi_req_data *>(handle);
-  delete req_data;
 
   return ret;
 }
+
+int RGWHTTPManager::set_threaded()
+{
+  is_threaded = true;
+  reqs_thread = new ReqsThread(this);
+  reqs_thread->create("http_manager");
+
+  int r = pipe(thread_pipe);
+  if (r < 0) {
+    r = -errno;
+    ldout(cct, 0) << "ERROR: pipe() returned errno=" << r << dendl;
+    return r;
+  }
+  return 0;
+}
+
+void RGWHTTPManager::stop()
+{
+  if (is_threaded) {
+    going_down.set(1);
+    signal_thread();
+    reqs_thread->join();
+    delete reqs_thread;
+  }
+}
+
+int RGWHTTPManager::signal_thread()
+{
+  uint32_t buf = 0;
+  int ret = write(thread_pipe[1], (void *)&buf, sizeof(buf));
+  if (ret < 0) {
+    ret = -errno;
+    ldout(cct, 0) << "ERROR: " << __func__ << ": write() returned ret=" << ret << dendl;
+    return ret;
+  }
+  return 0;
+}
+
+void *RGWHTTPManager::reqs_thread_entry()
+{
+  int still_running;
+  int mstatus;
+
+  ldout(cct, 20) << __func__ << ": start" << dendl;
+
+  while (!going_down.read()) {
+    int ret = do_curl_wait(cct, (CURLM *)multi_handle, thread_pipe[0]);
+    if (ret < 0) {
+      dout(0) << "ERROR: do_curl_wait() returned: " << ret << dendl;
+      return NULL;
+    }
+
+    link_pending_requests();
+
+    mstatus = curl_multi_perform((CURLM *)multi_handle, &still_running);
+    switch (mstatus) {
+      case CURLM_OK:
+      case CURLM_CALL_MULTI_PERFORM:
+        break;
+      default:
+        dout(10) << "curl_multi_perform returned: " << mstatus << dendl;
+	break;
+    }
+    int msgs_left;
+    CURLMsg *msg;
+    while ((msg = curl_multi_info_read((CURLM *)multi_handle, &msgs_left))) {
+      if (msg->msg == CURLMSG_DONE) {
+	int result = msg->data.result;
+	CURL *e = msg->easy_handle;
+	rgw_http_req_data *req_data;
+	curl_easy_getinfo(e, CURLINFO_PRIVATE, (void **)&req_data);
+	curl_multi_remove_handle((CURLM *)multi_handle, e);
+
+	long http_status;
+	curl_easy_getinfo(e, CURLINFO_RESPONSE_CODE, (void **)&http_status);
+
+	int status = rgw_http_error_to_errno(http_status);
+        if (result != CURLE_OK && http_status == 0) {
+          status = -EAGAIN;
+        }
+        int id = req_data->id;
+	finish_request(req_data, status);
+        switch (result) {
+          case CURLE_OK:
+            break;
+          default:
+            dout(20) << "ERROR: msg->data.result=" << result << " req_data->id=" << id << " http_status=" << http_status << dendl;
+	    break;
+        }
+      }
+    }
+  }
+
+  RWLock::WLocker rl(reqs_lock);
+  auto all_reqs = std::move(reqs);
+  for (auto iter : all_reqs) {
+    _finish_request(iter.second, -ECANCELED);
+  }
+
+  reqs.clear();
+
+  if (completion_mgr) {
+    completion_mgr->go_down();
+  }
+  
+  return 0;
+}
+
+
diff --git a/src/rgw/rgw_http_client.h b/src/rgw/rgw_http_client.h
index 705b848..d2105cb 100644
--- a/src/rgw/rgw_http_client.h
+++ b/src/rgw/rgw_http_client.h
@@ -4,21 +4,59 @@
 #ifndef CEPH_RGW_HTTP_CLIENT_H
 #define CEPH_RGW_HTTP_CLIENT_H
 
+#include "common/RWLock.h"
+#include "common/Cond.h"
+#include "include/atomic.h"
 #include "rgw_common.h"
 
+struct rgw_http_req_data;
+
 class RGWHTTPClient
 {
+  friend class RGWHTTPManager;
+
   bufferlist send_bl;
   bufferlist::iterator send_iter;
   size_t send_len;
   bool has_send_len;
+  long http_status;
+
+  rgw_http_req_data *req_data;
+
+  void *user_info;
+
+  string last_method;
+  string last_url;
+  bool verify_ssl; // Do not validate self signed certificates, default to false
+
 protected:
   CephContext *cct;
 
   list<pair<string, string> > headers;
+  int init_request(const char *method, const char *url, rgw_http_req_data *req_data);
 public:
-  virtual ~RGWHTTPClient() {}
-  explicit RGWHTTPClient(CephContext *_cct): send_len (0), has_send_len(false), cct(_cct) {}
+
+  static const long HTTP_STATUS_NOSTATUS     = 0;
+  static const long HTTP_STATUS_UNAUTHORIZED = 401;
+
+  virtual ~RGWHTTPClient();
+  explicit RGWHTTPClient(CephContext *_cct)
+    : send_len(0),
+      has_send_len(false),
+      http_status(HTTP_STATUS_NOSTATUS),
+      req_data(nullptr),
+      user_info(nullptr),
+      verify_ssl(true),
+      cct(_cct) {
+  }
+
+  void set_user_info(void *info) {
+    user_info = info;
+  }
+
+  void *get_user_info() {
+    return user_info;
+  }
 
   void append_header(const string& name, const string& val) {
     headers.push_back(pair<string, string>(name, val));
@@ -33,12 +71,78 @@ public:
     has_send_len = true;
   }
 
+
+  long get_http_status() const {
+    return http_status;
+  }
+
+  void set_verify_ssl(bool flag) {
+    verify_ssl = flag;
+  }
+
   int process(const char *method, const char *url);
   int process(const char *url) { return process("GET", url); }
 
-  int init_async(const char *method, const char *url, void **handle);
-  int process_request(void *handle, bool wait_for_data, bool *done);
-  int complete_request(void *handle);
+  int wait();
+  rgw_http_req_data *get_req_data() { return req_data; }
+
+  string to_str();
+
+  int get_req_retcode();
+};
+
+class RGWCompletionManager;
+
+class RGWHTTPManager {
+  CephContext *cct;
+  RGWCompletionManager *completion_mgr;
+  void *multi_handle;
+  bool is_threaded;
+  atomic_t going_down;
+
+  RWLock reqs_lock;
+  map<uint64_t, rgw_http_req_data *> reqs;
+  map<uint64_t, rgw_http_req_data *> complete_reqs;
+  int64_t num_reqs;
+  int64_t max_threaded_req;
+  int thread_pipe[2];
+
+  void register_request(rgw_http_req_data *req_data);
+  void complete_request(rgw_http_req_data *req_data);
+  void _complete_request(rgw_http_req_data *req_data);
+  void finish_request(rgw_http_req_data *req_data, int r);
+  void _finish_request(rgw_http_req_data *req_data, int r);
+  int link_request(rgw_http_req_data *req_data);
+
+  void link_pending_requests();
+
+  class ReqsThread : public Thread {
+    RGWHTTPManager *manager;
+
+  public:
+    ReqsThread(RGWHTTPManager *_m) : manager(_m) {}
+    void *entry();
+  };
+
+  ReqsThread *reqs_thread;
+
+  void *reqs_thread_entry();
+
+  int signal_thread();
+
+public:
+  RGWHTTPManager(CephContext *_cct, RGWCompletionManager *completion_mgr = NULL);
+  ~RGWHTTPManager();
+
+  int set_threaded();
+  void stop();
+
+  int add_request(RGWHTTPClient *client, const char *method, const char *url);
+
+  /* only for non threaded case */
+  int process_requests(bool wait_for_data, bool *done);
+
+  int complete_requests();
 };
 
 #endif
diff --git a/src/rgw/rgw_http_errors.h b/src/rgw/rgw_http_errors.h
index 8ff290d..04500ee 100644
--- a/src/rgw/rgw_http_errors.h
+++ b/src/rgw/rgw_http_errors.h
@@ -36,6 +36,7 @@ const static struct rgw_http_errors RGW_HTTP_ERRORS[] = {
     { ERR_TOO_SMALL, 400, "EntityTooSmall" },
     { ERR_TOO_MANY_BUCKETS, 400, "TooManyBuckets" },
     { ERR_MALFORMED_XML, 400, "MalformedXML" },
+    { ERR_AMZ_CONTENT_SHA256_MISMATCH, 400, "XAmzContentSHA256Mismatch" },
     { ERR_LENGTH_REQUIRED, 411, "MissingContentLength" },
     { EACCES, 403, "AccessDenied" },
     { EPERM, 403, "AccessDenied" },
@@ -142,6 +143,8 @@ static inline int rgw_http_error_to_errno(int http_err)
   if (http_err >= 200 && http_err <= 299)
     return 0;
   switch (http_err) {
+    case 304:
+      return -ERR_NOT_MODIFIED;
     case 400:
       return -EINVAL;
     case 401:
diff --git a/src/rgw/rgw_json_enc.cc b/src/rgw/rgw_json_enc.cc
index 3e6a031..cd4a0f5 100644
--- a/src/rgw/rgw_json_enc.cc
+++ b/src/rgw/rgw_json_enc.cc
@@ -11,10 +11,13 @@
 #include "rgw_keystone.h"
 #include "rgw_basic_types.h"
 #include "rgw_op.h"
+#include "rgw_sync.h"
 
 #include "common/ceph_json.h"
 #include "common/Formatter.h"
 
+#define dout_subsys ceph_subsys_rgw
+
 void encode_json(const char *name, const obj_version& v, Formatter *f)
 {
   f->open_object_section(name);
@@ -42,7 +45,8 @@ void RGWOLHInfo::dump(Formatter *f) const
 
 void RGWOLHPendingInfo::dump(Formatter *f) const
 {
-  encode_json("time", time, f);
+  utime_t ut(time);
+  encode_json("time", ut, f);
 }
 
 void RGWObjManifestPart::dump(Formatter *f) const
@@ -185,7 +189,7 @@ void RGWAccessControlPolicy::dump(Formatter *f) const
 void ObjectMetaInfo::dump(Formatter *f) const
 {
   encode_json("size", size, f);
-  encode_json("mtime", mtime, f);
+  encode_json("mtime", utime_t(mtime), f);
 }
 
 void ObjectCacheInfo::dump(Formatter *f) const
@@ -517,7 +521,8 @@ void RGWBucketEntryPoint::dump(Formatter *f) const
 {
   encode_json("bucket", bucket, f);
   encode_json("owner", owner, f);
-  encode_json("creation_time", creation_time, f);
+  utime_t ut(creation_time);
+  encode_json("creation_time", ut, f);
   encode_json("linked", linked, f);
   encode_json("has_bucket_info", has_bucket_info, f);
   if (has_bucket_info) {
@@ -528,7 +533,8 @@ void RGWBucketEntryPoint::dump(Formatter *f) const
 void RGWBucketEntryPoint::decode_json(JSONObj *obj) {
   JSONDecoder::decode_json("bucket", bucket, obj);
   JSONDecoder::decode_json("owner", owner, obj);
-  JSONDecoder::decode_json("creation_time", creation_time, obj);
+  utime_t ut(creation_time);
+  JSONDecoder::decode_json("creation_time", ut, obj);
   JSONDecoder::decode_json("linked", linked, obj);
   JSONDecoder::decode_json("has_bucket_info", has_bucket_info, obj);
   if (has_bucket_info) {
@@ -620,10 +626,11 @@ void RGWBucketWebsiteConf::decode_json(JSONObj *obj) {
 void RGWBucketInfo::dump(Formatter *f) const
 {
   encode_json("bucket", bucket, f);
-  encode_json("creation_time", creation_time, f);
+  utime_t ut(creation_time);
+  encode_json("creation_time", ut, f);
   encode_json("owner", owner.to_str(), f);
   encode_json("flags", flags, f);
-  encode_json("region", region, f);
+  encode_json("zonegroup", zonegroup, f);
   encode_json("placement_rule", placement_rule, f);
   encode_json("has_instance_obj", has_instance_obj, f);
   encode_json("quota", quota, f);
@@ -634,14 +641,21 @@ void RGWBucketInfo::dump(Formatter *f) const
   if (has_website) {
     encode_json("website_conf", website_conf, f);
   }
+  encode_json("swift_versioning", swift_versioning, f);
+  encode_json("swift_ver_location", swift_ver_location, f);
 }
 
 void RGWBucketInfo::decode_json(JSONObj *obj) {
   JSONDecoder::decode_json("bucket", bucket, obj);
-  JSONDecoder::decode_json("creation_time", creation_time, obj);
+  utime_t ut(creation_time);
+  JSONDecoder::decode_json("creation_time", ut, obj);
   JSONDecoder::decode_json("owner", owner, obj);
   JSONDecoder::decode_json("flags", flags, obj);
-  JSONDecoder::decode_json("region", region, obj);
+  JSONDecoder::decode_json("zonegroup", zonegroup, obj);
+  /* backward compatability with region */
+  if (zonegroup.empty()) {
+    JSONDecoder::decode_json("region", zonegroup, obj);
+  }
   JSONDecoder::decode_json("placement_rule", placement_rule, obj);
   JSONDecoder::decode_json("has_instance_obj", has_instance_obj, obj);
   JSONDecoder::decode_json("quota", quota, obj);
@@ -654,6 +668,14 @@ void RGWBucketInfo::decode_json(JSONObj *obj) {
   if (has_website) {
     JSONDecoder::decode_json("website_conf", website_conf, obj);
   }
+  JSONDecoder::decode_json("swift_versioning", swift_versioning, obj);
+  JSONDecoder::decode_json("swift_ver_location", swift_ver_location, obj);
+}
+
+void rgw_obj_key::dump(Formatter *f) const
+{
+  encode_json("name", name, f);
+  encode_json("instance", instance, f);
 }
 
 void RGWObjEnt::dump(Formatter *f) const
@@ -664,7 +686,8 @@ void RGWObjEnt::dump(Formatter *f) const
   encode_json("owner", owner.to_str(), f);
   encode_json("owner_display_name", owner_display_name, f);
   encode_json("size", size, f);
-  encode_json("mtime", mtime, f);
+  utime_t ut(mtime);
+  encode_json("mtime", ut, f);
   encode_json("etag", etag, f);
   encode_json("content_type", content_type, f);
   encode_json("tag", tag, f);
@@ -676,7 +699,8 @@ void RGWBucketEnt::dump(Formatter *f) const
   encode_json("bucket", bucket, f);
   encode_json("size", size, f);
   encode_json("size_rounded", size_rounded, f);
-  encode_json("mtime", creation_time, f); /* mtime / creation time discrepency needed for backward compatibility */
+  utime_t ut(creation_time);
+  encode_json("mtime", ut, f); /* mtime / creation time discrepency needed for backward compatibility */
   encode_json("count", count, f);
 }
 
@@ -685,7 +709,8 @@ void RGWUploadPartInfo::dump(Formatter *f) const
   encode_json("num", num, f);
   encode_json("size", size, f);
   encode_json("etag", etag, f);
-  encode_json("modified", modified, f);
+  utime_t ut(modified);
+  encode_json("modified", ut, f);
 }
 
 void rgw_obj::dump(Formatter *f) const
@@ -698,8 +723,75 @@ void rgw_obj::dump(Formatter *f) const
   encode_json("orig_obj", orig_obj, f);
 }
 
+void RGWDefaultSystemMetaObjInfo::dump(Formatter *f) const {
+  encode_json("default_id", default_id, f);
+}
+
+void RGWDefaultSystemMetaObjInfo::decode_json(JSONObj *obj) {
+  JSONDecoder::decode_json("default_id", default_id, obj);
+}
+
+void RGWNameToId::dump(Formatter *f) const {
+  encode_json("obj_id", obj_id, f);
+}
+
+void RGWNameToId::decode_json(JSONObj *obj) {
+  JSONDecoder::decode_json("obj_id", obj_id, obj);
+}
+
+void RGWSystemMetaObj::dump(Formatter *f) const
+{
+  encode_json("id", id , f);
+  encode_json("name", name , f);
+}
+
+void RGWSystemMetaObj::decode_json(JSONObj *obj)
+{
+  JSONDecoder::decode_json("id", id, obj);
+  JSONDecoder::decode_json("name", name, obj);
+}
+
+void RGWPeriodLatestEpochInfo::dump(Formatter *f) const {
+  encode_json("latest_epoch", epoch, f);
+}
+
+void RGWPeriodLatestEpochInfo::decode_json(JSONObj *obj) {
+  JSONDecoder::decode_json("latest_epoch", epoch, obj);
+}
+
+void RGWPeriod::dump(Formatter *f) const
+{
+  encode_json("id", id, f);
+  encode_json("epoch", epoch , f);
+  encode_json("predecessor_uuid", predecessor_uuid, f);
+  encode_json("sync_status", sync_status, f);
+  encode_json("period_map", period_map, f);
+  encode_json("master_zonegroup", master_zonegroup, f);
+  encode_json("master_zone", master_zone, f);
+  encode_json("period_config", period_config, f);
+  encode_json("realm_id", realm_id, f);
+  encode_json("realm_name", realm_name, f);
+  encode_json("realm_epoch", realm_epoch, f);
+}
+
+void RGWPeriod::decode_json(JSONObj *obj)
+{
+  JSONDecoder::decode_json("id", id, obj);
+  JSONDecoder::decode_json("epoch", epoch, obj);
+  JSONDecoder::decode_json("predecessor_uuid", predecessor_uuid, obj);
+  JSONDecoder::decode_json("sync_status", sync_status, obj);
+  JSONDecoder::decode_json("period_map", period_map, obj);
+  JSONDecoder::decode_json("master_zonegroup", master_zonegroup, obj);
+  JSONDecoder::decode_json("master_zone", master_zone, obj);
+  JSONDecoder::decode_json("period_config", period_config, obj);
+  JSONDecoder::decode_json("realm_id", realm_id, obj);
+  JSONDecoder::decode_json("realm_name", realm_name, obj);
+  JSONDecoder::decode_json("realm_epoch", realm_epoch, obj);
+}
+
 void RGWZoneParams::dump(Formatter *f) const
 {
+  RGWSystemMetaObj::dump(f);
   encode_json("domain_root", domain_root.data_pool, f);
   encode_json("control_pool", control_pool.data_pool, f);
   encode_json("gc_pool", gc_pool.data_pool, f);
@@ -712,15 +804,14 @@ void RGWZoneParams::dump(Formatter *f) const
   encode_json("user_uid_pool", user_uid_pool.data_pool, f);
   encode_json_plain("system_key", system_key, f);
   encode_json("placement_pools", placement_pools, f);
+  encode_json("metadata_heap", metadata_heap.data_pool, f);
+  encode_json("realm_id", realm_id, f);
 }
 
 static void decode_json(const char *field, rgw_bucket& bucket, JSONObj *obj)
 {
   string pool;
   JSONDecoder::decode_json(field, pool, obj);
-  if (pool[0] != '.') {
-    pool = string(".") + pool;
-  }
   bucket = rgw_bucket(pool.c_str());
 }
 
@@ -729,6 +820,7 @@ void RGWZonePlacementInfo::dump(Formatter *f) const
   encode_json("index_pool", index_pool, f);
   encode_json("data_pool", data_pool, f);
   encode_json("data_extra_pool", data_extra_pool, f);
+  encode_json("index_type", (uint32_t)index_type, f);
 }
 
 void RGWZonePlacementInfo::decode_json(JSONObj *obj)
@@ -736,10 +828,14 @@ void RGWZonePlacementInfo::decode_json(JSONObj *obj)
   JSONDecoder::decode_json("index_pool", index_pool, obj);
   JSONDecoder::decode_json("data_pool", data_pool, obj);
   JSONDecoder::decode_json("data_extra_pool", data_extra_pool, obj);
+  uint32_t it;
+  JSONDecoder::decode_json("index_type", it, obj);
+  index_type = (RGWBucketIndexType)it;
 }
 
 void RGWZoneParams::decode_json(JSONObj *obj)
 {
+  RGWSystemMetaObj::decode_json(obj);
   ::decode_json("domain_root", domain_root, obj);
   ::decode_json("control_pool", control_pool, obj);
   ::decode_json("gc_pool", gc_pool, obj);
@@ -748,45 +844,55 @@ void RGWZoneParams::decode_json(JSONObj *obj)
   ::decode_json("usage_log_pool", usage_log_pool, obj);
   ::decode_json("user_keys_pool", user_keys_pool, obj);
   ::decode_json("user_email_pool", user_email_pool, obj);
-  ::decode_json("user_uid_pool", user_uid_pool, obj);
   ::decode_json("user_swift_pool", user_swift_pool, obj);
+  ::decode_json("user_uid_pool", user_uid_pool, obj);
   JSONDecoder::decode_json("system_key", system_key, obj);
   JSONDecoder::decode_json("placement_pools", placement_pools, obj);
+  ::decode_json("metadata_heap", metadata_heap, obj);
+  JSONDecoder::decode_json("realm_id", realm_id, obj);
+
 }
 
 void RGWZone::dump(Formatter *f) const
 {
+  encode_json("id", id, f);
   encode_json("name", name, f);
   encode_json("endpoints", endpoints, f);
   encode_json("log_meta", log_meta, f);
   encode_json("log_data", log_data, f);
   encode_json("bucket_index_max_shards", bucket_index_max_shards, f);
+  encode_json("read_only", read_only, f);
 }
 
 void RGWZone::decode_json(JSONObj *obj)
 {
+  JSONDecoder::decode_json("id", id, obj);
   JSONDecoder::decode_json("name", name, obj);
+  if (id.empty()) {
+    id = name;
+  }
   JSONDecoder::decode_json("endpoints", endpoints, obj);
   JSONDecoder::decode_json("log_meta", log_meta, obj);
   JSONDecoder::decode_json("log_data", log_data, obj);
   JSONDecoder::decode_json("bucket_index_max_shards", bucket_index_max_shards, obj);
+  JSONDecoder::decode_json("read_only", read_only, obj);
 }
 
-void RGWRegionPlacementTarget::dump(Formatter *f) const
+void RGWZoneGroupPlacementTarget::dump(Formatter *f) const
 {
   encode_json("name", name, f);
   encode_json("tags", tags, f);
 }
 
-void RGWRegionPlacementTarget::decode_json(JSONObj *obj)
+void RGWZoneGroupPlacementTarget::decode_json(JSONObj *obj)
 {
   JSONDecoder::decode_json("name", name, obj);
   JSONDecoder::decode_json("tags", tags, obj);
 }
 
-void RGWRegion::dump(Formatter *f) const
+void RGWZoneGroup::dump(Formatter *f) const
 {
-  encode_json("name", name, f);
+  RGWSystemMetaObj::dump(f);
   encode_json("api_name", api_name, f);
   encode_json("is_master", is_master, f);
   encode_json("endpoints", endpoints, f);
@@ -796,26 +902,32 @@ void RGWRegion::dump(Formatter *f) const
   encode_json_map("zones", zones, f); /* more friendly representation */
   encode_json_map("placement_targets", placement_targets, f); /* more friendly representation */
   encode_json("default_placement", default_placement, f);
+  encode_json("realm_id", realm_id, f);
 }
 
 static void decode_zones(map<string, RGWZone>& zones, JSONObj *o)
 {
   RGWZone z;
   z.decode_json(o);
-  zones[z.name] = z;
+  zones[z.id] = z;
 }
 
-static void decode_placement_targets(map<string, RGWRegionPlacementTarget>& targets, JSONObj *o)
+static void decode_placement_targets(map<string, RGWZoneGroupPlacementTarget>& targets, JSONObj *o)
 {
-  RGWRegionPlacementTarget t;
+  RGWZoneGroupPlacementTarget t;
   t.decode_json(o);
   targets[t.name] = t;
 }
 
 
-void RGWRegion::decode_json(JSONObj *obj)
+void RGWZoneGroup::decode_json(JSONObj *obj)
 {
-  JSONDecoder::decode_json("name", name, obj);
+  RGWSystemMetaObj::decode_json(obj);
+  if (id.empty()) {
+    derr << "old format " << dendl;
+    JSONDecoder::decode_json("name", name, obj);
+    id = name;
+  }
   JSONDecoder::decode_json("api_name", api_name, obj);
   JSONDecoder::decode_json("is_master", is_master, obj);
   JSONDecoder::decode_json("endpoints", endpoints, obj);
@@ -825,8 +937,51 @@ void RGWRegion::decode_json(JSONObj *obj)
   JSONDecoder::decode_json("zones", zones, decode_zones, obj);
   JSONDecoder::decode_json("placement_targets", placement_targets, decode_placement_targets, obj);
   JSONDecoder::decode_json("default_placement", default_placement, obj);
+  JSONDecoder::decode_json("realm_id", realm_id, obj);
+}
+
+
+void RGWPeriodMap::dump(Formatter *f) const
+{
+  encode_json("id", id, f);
+  encode_json_map("zonegroups", zonegroups, f);
+  encode_json("short_zone_ids", short_zone_ids, f);
+}
+
+static void decode_zonegroups(map<string, RGWZoneGroup>& zonegroups, JSONObj *o)
+{
+  RGWZoneGroup zg;
+  zg.decode_json(o);
+  zonegroups[zg.get_id()] = zg;
+}
+
+void RGWPeriodMap::decode_json(JSONObj *obj)
+{
+  JSONDecoder::decode_json("id", id, obj);
+  JSONDecoder::decode_json("zonegroups", zonegroups, decode_zonegroups, obj);
+  /* backward compatability with region */
+  if (zonegroups.empty()) {
+    JSONDecoder::decode_json("regions", zonegroups, obj);
+  }
+  /* backward compatability with region */
+  if (master_zonegroup.empty()) {
+    JSONDecoder::decode_json("master_region", master_zonegroup, obj);
+  }
+  JSONDecoder::decode_json("short_zone_ids", short_zone_ids, obj);
+}
+
+
+void RGWPeriodConfig::dump(Formatter *f) const
+{
+  encode_json("bucket_quota", bucket_quota, f);
+  encode_json("user_quota", user_quota, f);
 }
 
+void RGWPeriodConfig::decode_json(JSONObj *obj)
+{
+  JSONDecoder::decode_json("bucket_quota", bucket_quota, obj);
+  JSONDecoder::decode_json("user_quota", user_quota, obj);
+}
 
 void RGWRegionMap::dump(Formatter *f) const
 {
@@ -840,60 +995,77 @@ void RGWRegionMap::decode_json(JSONObj *obj)
 {
   JSONDecoder::decode_json("regions", regions, obj);
   JSONDecoder::decode_json("master_region", master_region, obj);
+  JSONDecoder::decode_json("bucket_quota", bucket_quota, obj);
+  JSONDecoder::decode_json("user_quota", user_quota, obj);
+}
+
+void RGWZoneGroupMap::dump(Formatter *f) const
+{
+  encode_json("zonegroups", zonegroups, f);
+  encode_json("master_zonegroup", master_zonegroup, f);
+  encode_json("bucket_quota", bucket_quota, f);
+  encode_json("user_quota", user_quota, f);
+}
+
+void RGWZoneGroupMap::decode_json(JSONObj *obj)
+{
+  JSONDecoder::decode_json("zonegroups", zonegroups, obj);
+  /* backward compatability with region */
+  if (zonegroups.empty()) {
+    JSONDecoder::decode_json("regions", zonegroups, obj);
+  }
+  JSONDecoder::decode_json("master_zonegroup", master_zonegroup, obj);
+  /* backward compatability with region */
+  if (master_zonegroup.empty()) {
+    JSONDecoder::decode_json("master_region", master_zonegroup, obj);
+  }
+
+  JSONDecoder::decode_json("bucket_quota", bucket_quota, obj);
   JSONDecoder::decode_json("user_quota", user_quota, obj);
 }
 
 void RGWMetadataLogInfo::dump(Formatter *f) const
 {
   encode_json("marker", marker, f);
-  encode_json("last_update", last_update, f);
+  utime_t ut(last_update);
+  encode_json("last_update", ut, f);
 }
 
 void RGWMetadataLogInfo::decode_json(JSONObj *obj)
 {
   JSONDecoder::decode_json("marker", marker, obj);
-  JSONDecoder::decode_json("last_update", last_update, obj);
+  utime_t ut(last_update);
+  JSONDecoder::decode_json("last_update", ut, obj);
 }
 
 void RGWDataChangesLogInfo::dump(Formatter *f) const
 {
   encode_json("marker", marker, f);
-  encode_json("last_update", last_update, f);
+  utime_t ut(last_update);
+  encode_json("last_update", ut, f);
 }
 
 void RGWDataChangesLogInfo::decode_json(JSONObj *obj)
 {
   JSONDecoder::decode_json("marker", marker, obj);
-  JSONDecoder::decode_json("last_update", last_update, obj);
+  utime_t ut(last_update);
+  JSONDecoder::decode_json("last_update", ut, obj);
 }
 
-void KeystoneToken::Metadata::decode_json(JSONObj *obj)
-{
-  JSONDecoder::decode_json("is_admin", is_admin, obj);
-}
 
-void KeystoneToken::Service::Endpoint::decode_json(JSONObj *obj)
+void RGWRealm::dump(Formatter *f) const
 {
-  JSONDecoder::decode_json("id", id, obj);
-  JSONDecoder::decode_json("adminURL", admin_url, obj);
-  JSONDecoder::decode_json("publicURL", public_url, obj);
-  JSONDecoder::decode_json("internalURL", internal_url, obj);
-  JSONDecoder::decode_json("region", region, obj);
+  RGWSystemMetaObj::dump(f);
+  encode_json("current_period", current_period, f);
+  encode_json("epoch", epoch, f);
 }
 
-void KeystoneToken::Service::decode_json(JSONObj *obj)
-{
-  JSONDecoder::decode_json("type", type, obj, true);
-  JSONDecoder::decode_json("name", name, obj, true);
-  JSONDecoder::decode_json("endpoints", endpoints, obj);
-}
 
-void KeystoneToken::Token::Tenant::decode_json(JSONObj *obj)
+void RGWRealm::decode_json(JSONObj *obj)
 {
-  JSONDecoder::decode_json("id", id, obj, true);
-  JSONDecoder::decode_json("name", name, obj, true);
-  JSONDecoder::decode_json("description", description, obj);
-  JSONDecoder::decode_json("enabled", enabled, obj);
+  RGWSystemMetaObj::decode_json(obj);
+  JSONDecoder::decode_json("current_period", current_period, obj);
+  JSONDecoder::decode_json("epoch", epoch, obj);
 }
 
 void KeystoneToken::Token::decode_json(JSONObj *obj)
@@ -902,7 +1074,7 @@ void KeystoneToken::Token::decode_json(JSONObj *obj)
   struct tm t;
 
   JSONDecoder::decode_json("id", id, obj, true);
-  JSONDecoder::decode_json("tenant", tenant, obj, true);
+  JSONDecoder::decode_json("tenant", tenant_v2, obj, true);
   JSONDecoder::decode_json("expires", expires_iso8601, obj, true);
 
   if (parse_iso8601(expires_iso8601.c_str(), &t)) {
@@ -913,26 +1085,84 @@ void KeystoneToken::Token::decode_json(JSONObj *obj)
   }
 }
 
-void KeystoneToken::User::Role::decode_json(JSONObj *obj)
+void KeystoneToken::Role::decode_json(JSONObj *obj)
 {
   JSONDecoder::decode_json("id", id, obj);
-  JSONDecoder::decode_json("name", name, obj);
+  JSONDecoder::decode_json("name", name, obj, true);
+}
+
+void KeystoneToken::Domain::decode_json(JSONObj *obj)
+{
+  JSONDecoder::decode_json("id", id, obj, true);
+  JSONDecoder::decode_json("name", name, obj, true);
+}
+
+void KeystoneToken::Project::decode_json(JSONObj *obj)
+{
+  JSONDecoder::decode_json("id", id, obj, true);
+  JSONDecoder::decode_json("name", name, obj, true);
+  JSONDecoder::decode_json("domain", domain, obj);
 }
 
 void KeystoneToken::User::decode_json(JSONObj *obj)
 {
   JSONDecoder::decode_json("id", id, obj, true);
-  JSONDecoder::decode_json("name", name, obj);
-  JSONDecoder::decode_json("username", user_name, obj, true);
-  JSONDecoder::decode_json("roles", roles, obj);
+  JSONDecoder::decode_json("name", name, obj, true);
+  JSONDecoder::decode_json("domain", domain, obj);
+  JSONDecoder::decode_json("roles", roles_v2, obj);
 }
 
-void KeystoneToken::decode_json(JSONObj *access_obj)
+void KeystoneToken::decode_json(JSONObj *root_obj)
 {
-  JSONDecoder::decode_json("metadata", metadata, access_obj);
-  JSONDecoder::decode_json("token", token, access_obj, true);
-  JSONDecoder::decode_json("user", user, access_obj, true);
-  JSONDecoder::decode_json("serviceCatalog", service_catalog, access_obj);
+  JSONDecoder::decode_json("user", user, root_obj, true);
+
+  const auto version = KeystoneService::get_api_version();
+
+  if (version == KeystoneApiVersion::VER_3) {
+    string expires_iso8601;
+    if (JSONDecoder::decode_json("expires_at", expires_iso8601, root_obj)) {
+      /* VER_3 */
+      /* Presence of "expires_at" suggests we are dealing with OpenStack
+       * Identity API v3 (aka Keystone API v3) token. */
+      struct tm t;
+
+      if (parse_iso8601(expires_iso8601.c_str(), &t)) {
+        token.expires = timegm(&t);
+      } else {
+        token.expires = 0;
+        throw JSONDecoder::err("Failed to parse ISO8601 expiration date"
+                               "from Keystone response.");
+      }
+      JSONDecoder::decode_json("roles", roles, root_obj, true);
+      JSONDecoder::decode_json("project", project, root_obj, true);
+    } else {
+      /* fallback: VER_2 */
+      JSONDecoder::decode_json("token", token, root_obj, true);
+      roles = user.roles_v2;
+      project = token.tenant_v2;
+    }
+  } else if (version == KeystoneApiVersion::VER_2) {
+    if (JSONDecoder::decode_json("token", token, root_obj)) {
+      /* VER_2 */
+      roles = user.roles_v2;
+      project = token.tenant_v2;
+    } else {
+      /* fallback: VER_3 */
+      string expires_iso8601;
+      JSONDecoder::decode_json("expires_at", expires_iso8601, root_obj, true);
+
+      struct tm t;
+      if (parse_iso8601(expires_iso8601.c_str(), &t)) {
+        token.expires = timegm(&t);
+      } else {
+        token.expires = 0;
+        throw JSONDecoder::err("Failed to parse ISO8601 expiration date"
+                               "from Keystone response.");
+      }
+      JSONDecoder::decode_json("roles", roles, root_obj, true);
+      JSONDecoder::decode_json("project", project, root_obj, true);
+    }
+  }
 }
 
 void rgw_slo_entry::decode_json(JSONObj *obj)
@@ -941,3 +1171,130 @@ void rgw_slo_entry::decode_json(JSONObj *obj)
   JSONDecoder::decode_json("etag", etag, obj);
   JSONDecoder::decode_json("size_bytes", size_bytes, obj);
 };
+
+void rgw_meta_sync_info::decode_json(JSONObj *obj)
+{
+  string s;
+  JSONDecoder::decode_json("status", s, obj);
+  if (s == "init") {
+    state = StateInit;
+  } else if (s == "building-full-sync-maps") {
+    state = StateBuildingFullSyncMaps;
+  } else if (s == "sync") {
+    state = StateSync;
+  }    
+  JSONDecoder::decode_json("num_shards", num_shards, obj);
+  JSONDecoder::decode_json("period", period, obj);
+  JSONDecoder::decode_json("realm_epoch", realm_epoch, obj);
+}
+
+void rgw_meta_sync_info::dump(Formatter *f) const
+{
+  string s;
+  switch ((SyncState)state) {
+  case StateInit:
+    s = "init";
+    break;
+  case StateBuildingFullSyncMaps:
+    s = "building-full-sync-maps";
+    break;
+  case StateSync:
+    s = "sync";
+    break;
+  default:
+    s = "unknown";
+    break;
+  }
+  encode_json("status", s, f);
+  encode_json("num_shards", num_shards, f);
+  encode_json("period", period, f);
+  encode_json("realm_epoch", realm_epoch, f);
+}
+
+void rgw_meta_sync_marker::decode_json(JSONObj *obj)
+{
+  int s;
+  JSONDecoder::decode_json("state", s, obj);
+  state = s;
+  JSONDecoder::decode_json("marker", marker, obj);
+  JSONDecoder::decode_json("next_step_marker", next_step_marker, obj);
+  JSONDecoder::decode_json("total_entries", total_entries, obj);
+  JSONDecoder::decode_json("pos", pos, obj);
+  utime_t ut;
+  JSONDecoder::decode_json("timestamp", ut, obj);
+  timestamp = ut.to_real_time();
+}
+
+void rgw_meta_sync_marker::dump(Formatter *f) const
+{
+  encode_json("state", (int)state, f);
+  encode_json("marker", marker, f);
+  encode_json("next_step_marker", next_step_marker, f);
+  encode_json("total_entries", total_entries, f);
+  encode_json("pos", pos, f);
+  encode_json("timestamp", utime_t(timestamp), f);
+}
+
+void rgw_meta_sync_status::decode_json(JSONObj *obj)
+{
+  JSONDecoder::decode_json("info", sync_info, obj);
+  JSONDecoder::decode_json("markers", sync_markers, obj);
+}
+
+void rgw_meta_sync_status::dump(Formatter *f) const {
+  encode_json("info", sync_info, f);
+  encode_json("markers", sync_markers, f);
+}
+
+void rgw_sync_error_info::dump(Formatter *f) const {
+  encode_json("source_zone", source_zone, f);
+  encode_json("error_code", error_code, f);
+  encode_json("message", message, f);
+}
+
+void KeystoneAdminTokenRequestVer2::dump(Formatter * const f) const
+{
+  f->open_object_section("token_request");
+    f->open_object_section("auth");
+      f->open_object_section("passwordCredentials");
+        encode_json("username", cct->_conf->rgw_keystone_admin_user, f);
+        encode_json("password", cct->_conf->rgw_keystone_admin_password, f);
+      f->close_section();
+      encode_json("tenantName", cct->_conf->rgw_keystone_admin_tenant, f);
+    f->close_section();
+  f->close_section();
+}
+
+void KeystoneAdminTokenRequestVer3::dump(Formatter * const f) const
+{
+  f->open_object_section("token_request");
+    f->open_object_section("auth");
+      f->open_object_section("identity");
+        f->open_array_section("methods");
+          f->dump_string("", "password");
+        f->close_section();
+        f->open_object_section("password");
+          f->open_object_section("user");
+            f->open_object_section("domain");
+              encode_json("name", cct->_conf->rgw_keystone_admin_domain, f);
+            f->close_section();
+            encode_json("name", cct->_conf->rgw_keystone_admin_user, f);
+            encode_json("password", cct->_conf->rgw_keystone_admin_password, f);
+          f->close_section();
+        f->close_section();
+      f->close_section();
+      f->open_object_section("scope");
+        f->open_object_section("project");
+          if (!cct->_conf->rgw_keystone_admin_project.empty()) {
+            encode_json("name", cct->_conf->rgw_keystone_admin_project, f);
+          } else {
+            encode_json("name", cct->_conf->rgw_keystone_admin_tenant, f);
+          }
+          f->open_object_section("domain");
+            encode_json("name", cct->_conf->rgw_keystone_admin_domain, f);
+          f->close_section();
+        f->close_section();
+      f->close_section();
+    f->close_section();
+  f->close_section();
+}
diff --git a/src/rgw/rgw_keystone.cc b/src/rgw/rgw_keystone.cc
index 7c5d206..ae390fe 100644
--- a/src/rgw/rgw_keystone.cc
+++ b/src/rgw/rgw_keystone.cc
@@ -11,10 +11,146 @@
 
 #include "rgw_common.h"
 #include "rgw_keystone.h"
+#include "common/ceph_crypto_cms.h"
+#include "common/armor.h"
 
 #define dout_subsys ceph_subsys_rgw
 
-bool KeystoneToken::User::has_role(const string& r) {
+int rgw_open_cms_envelope(CephContext * const cct, string& src, string& dst)
+{
+#define BEGIN_CMS "-----BEGIN CMS-----"
+#define END_CMS "-----END CMS-----"
+
+  int start = src.find(BEGIN_CMS);
+  if (start < 0) {
+    ldout(cct, 0) << "failed to find " << BEGIN_CMS << " in response" << dendl;
+    return -EINVAL;
+  }
+  start += sizeof(BEGIN_CMS) - 1;
+
+  int end = src.find(END_CMS);
+  if (end < 0) {
+    ldout(cct, 0) << "failed to find " << END_CMS << " in response" << dendl;
+    return -EINVAL;
+  }
+
+  string s = src.substr(start, end - start);
+
+  int pos = 0;
+
+  do {
+    int next = s.find('\n', pos);
+    if (next < 0) {
+      dst.append(s.substr(pos));
+      break;
+    } else {
+      dst.append(s.substr(pos, next - pos));
+    }
+    pos = next + 1;
+  } while (pos < (int)s.size());
+
+  return 0;
+}
+
+int rgw_decode_b64_cms(CephContext * const cct,
+                       const string& signed_b64,
+                       bufferlist& bl)
+{
+  bufferptr signed_ber(signed_b64.size() * 2);
+  char *dest = signed_ber.c_str();
+  const char *src = signed_b64.c_str();
+  size_t len = signed_b64.size();
+  char buf[len + 1];
+  buf[len] = '\0';
+
+  for (size_t i = 0; i < len; i++, src++) {
+    if (*src != '-') {
+      buf[i] = *src;
+    } else {
+      buf[i] = '/';
+    }
+  }
+
+  int ret = ceph_unarmor(dest, dest + signed_ber.length(), buf,
+                         buf + signed_b64.size());
+  if (ret < 0) {
+    ldout(cct, 0) << "ceph_unarmor() failed, ret=" << ret << dendl;
+    return ret;
+  }
+
+  bufferlist signed_ber_bl;
+  signed_ber_bl.append(signed_ber);
+
+  ret = ceph_decode_cms(cct, signed_ber_bl, bl);
+  if (ret < 0) {
+    ldout(cct, 0) << "ceph_decode_cms returned " << ret << dendl;
+    return ret;
+  }
+
+  return 0;
+}
+
+#define PKI_ANS1_PREFIX "MII"
+
+bool rgw_is_pki_token(const string& token)
+{
+  return token.compare(0, sizeof(PKI_ANS1_PREFIX) - 1, PKI_ANS1_PREFIX) == 0;
+}
+
+void rgw_get_token_id(const string& token, string& token_id)
+{
+  if (!rgw_is_pki_token(token)) {
+    token_id = token;
+    return;
+  }
+
+  unsigned char m[CEPH_CRYPTO_MD5_DIGESTSIZE];
+
+  MD5 hash;
+  hash.Update((const byte *)token.c_str(), token.size());
+  hash.Final(m);
+
+  char calc_md5[CEPH_CRYPTO_MD5_DIGESTSIZE * 2 + 1];
+  buf_to_hex(m, CEPH_CRYPTO_MD5_DIGESTSIZE, calc_md5);
+  token_id = calc_md5;
+}
+
+bool rgw_decode_pki_token(CephContext * const cct,
+                          const string& token,
+                          bufferlist& bl)
+{
+  if (!rgw_is_pki_token(token)) {
+    return false;
+  }
+
+  int ret = rgw_decode_b64_cms(cct, token, bl);
+  if (ret < 0) {
+    return false;
+  }
+
+  ldout(cct, 20) << "successfully decoded pki token" << dendl;
+
+  return true;
+}
+
+
+KeystoneApiVersion KeystoneService::get_api_version()
+{
+  const int keystone_version = g_ceph_context->_conf->rgw_keystone_api_version;
+
+  if (keystone_version == 3) {
+    return KeystoneApiVersion::VER_3;
+  } else if (keystone_version == 2) {
+    return KeystoneApiVersion::VER_2;
+  } else {
+    dout(0) << "ERROR: wrong Keystone API version: " << keystone_version
+            << "; falling back to v2" <<  dendl;
+    return KeystoneApiVersion::VER_2;
+  }
+}
+
+bool KeystoneToken::has_role(const string& r)
+{
   list<Role>::iterator iter;
   for (iter = roles.begin(); iter != roles.end(); ++iter) {
       if (fnmatch(r.c_str(), ((*iter).name.c_str()), 0) == 0) {
@@ -24,7 +160,9 @@ bool KeystoneToken::User::has_role(const string& r) {
   return false;
 }
 
-int KeystoneToken::parse(CephContext *cct, bufferlist& bl)
+int KeystoneToken::parse(CephContext * const cct,
+                         const string& token_str,
+                         bufferlist& bl)
 {
   JSONParser parser;
   if (!parser.parse(bl.c_str(), bl.length())) {
@@ -33,7 +171,28 @@ int KeystoneToken::parse(CephContext *cct, bufferlist& bl)
   }
 
   try {
-    JSONDecoder::decode_json("access", *this, &parser);
+    const auto version = KeystoneService::get_api_version();
+
+    if (version == KeystoneApiVersion::VER_2) {
+      if (!JSONDecoder::decode_json("access", *this, &parser)) {
+        /* Token structure doesn't follow Identity API v2, so the token
+         * must be in v3. Otherwise we can assume it's wrongly formatted. */
+        JSONDecoder::decode_json("token", *this, &parser, true);
+        token.id = token_str;
+      }
+    } else if (version == KeystoneApiVersion::VER_3) {
+      if (!JSONDecoder::decode_json("token", *this, &parser)) {
+        /* If the token cannot be parsed according to V3, try V2. */
+        JSONDecoder::decode_json("access", *this, &parser, true);
+      } else {
+        /* v3 suceeded. We have to fill token.id from external input as it
+         * isn't a part of the JSON response anymore. It has been moved
+         * to X-Subject-Token HTTP header instead. */
+        token.id = token_str;
+      }
+    } else {
+      return -ENOTSUP;
+    }
   } catch (JSONDecoder::err& err) {
     ldout(cct, 0) << "Keystone token parse error: " << err.message << dendl;
     return -EINVAL;
@@ -72,7 +231,15 @@ bool RGWKeystoneTokenCache::find(const string& token_id, KeystoneToken& token)
   return true;
 }
 
-void RGWKeystoneTokenCache::add(const string& token_id, KeystoneToken& token)
+bool RGWKeystoneTokenCache::find_admin(KeystoneToken& token)
+{
+  Mutex::Locker l(lock);
+
+  return find(admin_token_id, token);
+}
+
+void RGWKeystoneTokenCache::add(const string& token_id,
+                                const KeystoneToken& token)
 {
   lock.Lock();
   map<string, token_entry>::iterator iter = tokens.find(token_id);
@@ -97,6 +264,14 @@ void RGWKeystoneTokenCache::add(const string& token_id, KeystoneToken& token)
   lock.Unlock();
 }
 
+void RGWKeystoneTokenCache::add_admin(const KeystoneToken& token)
+{
+  Mutex::Locker l(lock);
+
+  rgw_get_token_id(token.token.id, admin_token_id);
+  add(admin_token_id, token);
+}
+
 void RGWKeystoneTokenCache::invalidate(const string& token_id)
 {
   Mutex::Locker l(lock);
diff --git a/src/rgw/rgw_keystone.h b/src/rgw/rgw_keystone.h
index a9600ac..ffbae90 100644
--- a/src/rgw/rgw_keystone.h
+++ b/src/rgw/rgw_keystone.h
@@ -6,90 +6,102 @@
 
 #include "rgw_common.h"
 
+int rgw_open_cms_envelope(CephContext *cct, string& src, string& dst);
+int rgw_decode_b64_cms(CephContext *cct,
+                       const string& signed_b64,
+                       bufferlist& bl);
+bool rgw_is_pki_token(const string& token);
+void rgw_get_token_id(const string& token, string& token_id);
+bool rgw_decode_pki_token(CephContext *cct,
+                          const string& token,
+                          bufferlist& bl);
+
+enum class KeystoneApiVersion {
+  VER_2,
+  VER_3
+};
+
+class KeystoneService {
+public:
+  static KeystoneApiVersion get_api_version();
+};
+
 class KeystoneToken {
 public:
-  class Metadata {
+  class Domain {
   public:
-    Metadata() : is_admin(false) { }
-    bool is_admin;
+    string id;
+    string name;
     void decode_json(JSONObj *obj);
   };
-
-  class Service {
+  class Project {
   public:
-    class Endpoint {
-    public:
-      string id;
-      string admin_url;
-      string public_url;
-      string internal_url;
-      string region;
-      void decode_json(JSONObj *obj);
-    };
-    string type;
+    Domain domain;
+    string id;
     string name;
-    list<Endpoint> endpoints;
     void decode_json(JSONObj *obj);
   };
 
   class Token {
   public:
     Token() : expires(0) { }
-    class Tenant {
-    public:
-      Tenant() : enabled(false) { }
-      string id;
-      string name;
-      string description;
-      bool enabled;
-      void decode_json(JSONObj *obj);
-    };
     string id;
     time_t expires;
-    Tenant tenant;
+    Project tenant_v2;
+    void decode_json(JSONObj *obj);
+  };
+
+  class Role {
+  public:
+    string id;
+    string name;
     void decode_json(JSONObj *obj);
   };
 
   class User {
   public:
-    class Role {
-    public:
-      string id;
-      string name;
-      void decode_json(JSONObj *obj);
-    };
     string id;
     string name;
-    string user_name;
-    list<Role> roles;
+    Domain domain;
+    list<Role> roles_v2;
     void decode_json(JSONObj *obj);
-    bool has_role(const string& r);
   };
 
-  Metadata metadata;
-  list<Service> service_catalog;
   Token token;
+  Project project;
   User user;
+  list<Role> roles;
 
 public:
-  int parse(CephContext *cct, bufferlist& bl);
-
+  // FIXME: default ctor needs to be eradicated here
+  KeystoneToken() = default;
+  time_t get_expires() { return token.expires; }
+  string get_domain_id() {return project.domain.id;};
+  string get_domain_name()  {return project.domain.name;};
+  string get_project_id() {return project.id;};
+  string get_project_name() {return project.name;};
+  string get_user_id() {return user.id;};
+  string get_user_name() {return user.name;};
+  bool has_role(const string& r);
   bool expired() {
     uint64_t now = ceph_clock_now(NULL).sec();
-    return (now >= (uint64_t)token.expires);
+    return (now >= (uint64_t)get_expires());
   }
-
+  int parse(CephContext *cct,
+            const string& token_str,
+            bufferlist& bl /* in */);
   void decode_json(JSONObj *access_obj);
 };
 
-struct token_entry {
-  KeystoneToken token;
-  list<string>::iterator lru_iter;
-};
-
 class RGWKeystoneTokenCache {
+  struct token_entry {
+    KeystoneToken token;
+    list<string>::iterator lru_iter;
+  };
+
   CephContext *cct;
 
+  string admin_token_id;
   map<string, token_entry> tokens;
   list<string> tokens_lru;
 
@@ -98,12 +110,43 @@ class RGWKeystoneTokenCache {
   size_t max;
 
 public:
-  RGWKeystoneTokenCache(CephContext *_cct, int _max) : cct(_cct), lock("RGWKeystoneTokenCache"), max(_max) {}
+  RGWKeystoneTokenCache(CephContext *_cct, int _max)
+    : cct(_cct),
+      lock("RGWKeystoneTokenCache", true /* recursive */),
+      max(_max) {
+  }
 
   bool find(const string& token_id, KeystoneToken& token);
-  void add(const string& token_id, KeystoneToken& token);
+  bool find_admin(KeystoneToken& token);
+  void add(const string& token_id, const KeystoneToken& token);
+  void add_admin(const KeystoneToken& token);
   void invalidate(const string& token_id);
 };
 
+class KeystoneAdminTokenRequest {
+public:
+  virtual ~KeystoneAdminTokenRequest() = default;
+  virtual void dump(Formatter *f) const = 0;
+};
+
+class KeystoneAdminTokenRequestVer2 : public KeystoneAdminTokenRequest {
+  CephContext *cct;
+
+public:
+  KeystoneAdminTokenRequestVer2(CephContext * const _cct)
+    : cct(_cct) {
+  }
+  void dump(Formatter *f) const;
+};
+
+class KeystoneAdminTokenRequestVer3 : public KeystoneAdminTokenRequest {
+  CephContext *cct;
+
+public:
+  KeystoneAdminTokenRequestVer3(CephContext * const _cct)
+    : cct(_cct) {
+  }
+  void dump(Formatter *f) const;
+};
 
 #endif
diff --git a/src/rgw/rgw_ldap.cc b/src/rgw/rgw_ldap.cc
new file mode 100644
index 0000000..ac420e3
--- /dev/null
+++ b/src/rgw/rgw_ldap.cc
@@ -0,0 +1,4 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+
+#include "rgw_ldap.h"
diff --git a/src/rgw/rgw_ldap.h b/src/rgw/rgw_ldap.h
new file mode 100644
index 0000000..46b05ff
--- /dev/null
+++ b/src/rgw/rgw_ldap.h
@@ -0,0 +1,121 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+
+#ifndef RGW_LDAP_H
+#define RGW_LDAP_H
+
+#define LDAP_DEPRECATED 1
+#include "ldap.h"
+
+#include <stdint.h>
+#include <tuple>
+#include <vector>
+#include <string>
+#include <iostream>
+
+namespace rgw {
+
+#if defined(HAVE_OPENLDAP)
+
+  class LDAPHelper
+  {
+    std::string uri;
+    std::string binddn;
+    std::string searchdn;
+    std::string dnattr;
+    LDAP *ldap;
+
+  public:
+    LDAPHelper(std::string _uri, std::string _binddn, std::string _searchdn,
+	      std::string _dnattr)
+      : uri(std::move(_uri)), binddn(std::move(_binddn)), searchdn(_searchdn),
+	dnattr(_dnattr), ldap(nullptr) {
+      // nothing
+    }
+
+    int init() {
+      int ret;
+      ret = ldap_initialize(&ldap, uri.c_str());
+      return (ret == LDAP_SUCCESS) ? ret : -EINVAL;
+    }
+
+    int bind() {
+      int ret;
+      ret = ldap_simple_bind_s(ldap, nullptr, nullptr);
+      return (ret == LDAP_SUCCESS) ? ret : -EINVAL;
+    }
+
+    int simple_bind(const char *dn, const std::string& pwd) {
+      LDAP* tldap;
+      int ret = ldap_initialize(&tldap, uri.c_str());
+      ret = ldap_simple_bind_s(tldap, dn, pwd.c_str());
+      if (ret == LDAP_SUCCESS) {
+	ldap_unbind(tldap);
+      }
+      return ret; // OpenLDAP client error space
+    }
+
+    int auth(const std::string uid, const std::string pwd) {
+      int ret;
+      std::string filter;
+      filter = "(";
+      filter += dnattr;
+      filter += "=";
+      filter += uid;
+      filter += ")";
+      char *attrs[] = { const_cast<char*>(dnattr.c_str()), nullptr };
+      LDAPMessage *answer = nullptr, *entry = nullptr;
+      ret = ldap_search_s(ldap, searchdn.c_str(), LDAP_SCOPE_SUBTREE,
+			  filter.c_str(), attrs, 0, &answer);
+      if (ret == LDAP_SUCCESS) {
+	entry = ldap_first_entry(ldap, answer);
+	if (entry) {
+	  char *dn = ldap_get_dn(ldap, entry);
+	  ret = simple_bind(dn, pwd);
+	  ldap_memfree(dn);
+	} else {
+	  ret = LDAP_NO_SUCH_ATTRIBUTE; // fixup result
+	}
+	ldap_msgfree(answer);
+      }
+      return (ret == LDAP_SUCCESS) ? ret : -EACCES;
+    }
+
+    ~LDAPHelper() {
+      if (ldap)
+	ldap_unbind(ldap);
+    }
+
+  }; /* LDAPHelper */
+
+#else
+
+  class LDAPHelper
+  {
+  public:
+    LDAPHelper(std::string _uri, std::string _binddn, std::string _searchdn,
+	      std::string _dnattr)
+      {}
+
+    int init() {
+      return -ENOTSUP;
+    }
+
+    int bind() {
+      return -ENOTSUP;
+    }
+
+    int auth(const std::string uid, const std::string pwd) {
+      return -EACCES;
+    }
+
+    ~LDAPHelper() {}
+
+  }; /* LDAPHelper */
+
+
+#endif /* HAVE_OPENLDAP */
+
+} /* namespace rgw */
+
+#endif /* RGW_LDAP_H */
diff --git a/src/rgw/rgw_lib.h b/src/rgw/rgw_lib.h
new file mode 100644
index 0000000..f418a6d
--- /dev/null
+++ b/src/rgw/rgw_lib.h
@@ -0,0 +1,203 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+#ifndef RGW_LIB_H
+#define RGW_LIB_H
+
+#include <mutex>
+#include "include/unordered_map.h"
+#include "rgw_common.h"
+#include "rgw_client_io.h"
+#include "rgw_rest.h"
+#include "rgw_request.h"
+#include "rgw_frontend.h"
+#include "rgw_process.h"
+#include "rgw_rest_s3.h" // RGW_Auth_S3
+#include "rgw_ldap.h"
+#include "include/assert.h"
+
+class OpsLogSocket;
+
+namespace rgw {
+
+  class RGWLibFrontendConfig;
+  class RGWLibFrontend;
+
+  class RGWLib {
+    RGWFrontendConfig* fec;
+    RGWLibFrontend* fe;
+    OpsLogSocket* olog;
+    rgw::LDAPHelper* ldh;
+    RGWREST rest; // XXX needed for RGWProcessEnv
+    RGWRados* store;
+
+  public:
+    RGWLib() : fec(nullptr), fe(nullptr), olog(nullptr), store(nullptr)
+      {}
+    ~RGWLib() {}
+
+    RGWRados* get_store() { return store; }
+
+    RGWLibFrontend* get_fe() { return fe; }
+
+    rgw::LDAPHelper* get_ldh() { return ldh; }
+
+    int init();
+    int init(vector<const char *>& args);
+    int stop();
+  };
+
+  extern RGWLib rgwlib;
+
+/* request interface */
+
+  class RGWLibIO : public RGWClientIO
+  {
+    RGWUserInfo user_info;
+  public:
+    RGWLibIO() {
+      get_env().set("HTTP_HOST", "");
+    }
+    RGWLibIO(const RGWUserInfo &_user_info)
+      : user_info(_user_info) {}
+
+    virtual void init_env(CephContext *cct) {}
+
+    const RGWUserInfo& get_user() {
+      return user_info;
+    }
+
+    int set_uid(RGWRados* store, const rgw_user& uid);
+
+    int write_data(const char *buf, int len);
+    int read_data(char *buf, int len);
+    int send_status(int status, const char *status_name);
+    int send_100_continue();
+    int complete_header();
+    int send_content_length(uint64_t len);
+
+    int complete_request() { /* XXX */
+      return 0;
+    };
+
+  }; /* RGWLibIO */
+
+/* XXX */
+  class RGWRESTMgr_Lib : public RGWRESTMgr {
+  public:
+    RGWRESTMgr_Lib() {}
+    virtual ~RGWRESTMgr_Lib() {}
+  }; /* RGWRESTMgr_Lib */
+
+/* XXX */
+  class RGWHandler_Lib : public RGWHandler {
+    friend class RGWRESTMgr_Lib;
+  public:
+
+    virtual int authorize();
+
+    RGWHandler_Lib() {}
+    virtual ~RGWHandler_Lib() {}
+    static int init_from_header(struct req_state *s);
+  }; /* RGWHandler_Lib */
+
+  class RGWLibRequest : public RGWRequest,
+			public RGWHandler_Lib {
+  public:
+    CephContext* cct;
+    RGWUserInfo* user;
+
+    /* unambiguiously return req_state */
+    inline struct req_state* get_state() { return this->RGWRequest::s; }
+
+    RGWLibRequest(CephContext* _cct, RGWUserInfo* _user)
+      :  RGWRequest(0), cct(_cct), user(_user)
+      {}
+
+    RGWUserInfo* get_user() { return user; }
+
+  virtual int postauth_init() { return 0; }
+
+    /* descendant equivalent of *REST*::init_from_header(...):
+     * prepare request for execute()--should mean, fixup URI-alikes
+     * and any other expected stat vars in local req_state, for
+     * now */
+    virtual int header_init() = 0;
+
+    /* descendant initializer responsible to call RGWOp::init()--which
+     * descendants are required to inherit */
+    virtual int op_init() = 0;
+
+    using RGWHandler::init;
+
+    int init(const RGWEnv& rgw_env, RGWObjectCtx* rados_ctx,
+	     RGWLibIO* io, struct req_state* _s) {
+
+      RGWRequest::init_state(_s);
+      RGWHandler::init(rados_ctx->store, _s, io);
+
+      /* fixup _s->req */
+      _s->req = this;
+
+      log_init();
+
+      get_state()->obj_ctx = rados_ctx;
+      get_state()->req_id = store->unique_id(id);
+      get_state()->trans_id = store->unique_trans_id(id);
+
+      log_format(_s, "initializing for trans_id = %s",
+		 get_state()->trans_id.c_str());
+
+      int ret = header_init();
+      if (ret == 0) {
+	ret = init_from_header(_s);
+      }
+      return ret;
+    }
+
+    virtual bool only_bucket() = 0;
+
+    virtual int read_permissions(RGWOp *op);
+
+  }; /* RGWLibRequest */
+
+  class RGWLibContinuedReq : public RGWLibRequest {
+    RGWLibIO io_ctx;
+    struct req_state rstate;
+    RGWObjectCtx rados_ctx;
+  public:
+
+    RGWLibContinuedReq(CephContext* _cct, RGWUserInfo* _user)
+      :  RGWLibRequest(_cct, _user), io_ctx(),
+	 rstate(_cct, &io_ctx.get_env(), _user), rados_ctx(rgwlib.get_store(),
+							   &rstate)
+      {
+	io_ctx.init(_cct);
+
+	RGWRequest::init_state(&rstate);
+	RGWHandler::init(rados_ctx.store, &rstate, &io_ctx);
+
+	/* fixup _s->req */
+	get_state()->req = this;
+
+	log_init();
+
+	get_state()->obj_ctx = &rados_ctx;
+	get_state()->req_id = store->unique_id(id);
+	get_state()->trans_id = store->unique_trans_id(id);
+
+	log_format(get_state(), "initializing for trans_id = %s",
+		   get_state()->trans_id.c_str());
+      }
+
+    inline RGWRados* get_store() { return store; }
+
+    virtual int execute() final { abort(); }
+    virtual int exec_start() = 0;
+    virtual int exec_continue() = 0;
+    virtual int exec_finish() = 0;
+
+  }; /* RGWLibContinuedReq */
+
+} /* namespace rgw */
+
+#endif /* RGW_LIB_H */
diff --git a/src/rgw/rgw_lib_frontend.h b/src/rgw/rgw_lib_frontend.h
new file mode 100644
index 0000000..9f407f1
--- /dev/null
+++ b/src/rgw/rgw_lib_frontend.h
@@ -0,0 +1,103 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+
+#ifndef RGW_LIB_FRONTEND_H
+#define RGW_LIB_FRONTEND_H
+
+#include <boost/container/flat_map.hpp>
+
+#include <boost/container/flat_map.hpp>
+
+#include "rgw_lib.h"
+#include "rgw_file.h"
+
+namespace rgw {
+
+  class RGWLibProcess : public RGWProcess {
+    RGWAccessKey access_key;
+    std::mutex mtx;
+    int gen;
+    bool shutdown;
+
+    typedef flat_map<RGWLibFS*, RGWLibFS*> FSMAP;
+    FSMAP mounted_fs;
+
+    using lock_guard = std::lock_guard<std::mutex>;
+    using unique_lock = std::unique_lock<std::mutex>;
+
+  public:
+    RGWLibProcess(CephContext* cct, RGWProcessEnv* pe, int num_threads,
+		  RGWFrontendConfig* _conf) :
+      RGWProcess(cct, pe, num_threads, _conf), gen(0), shutdown(false) {}
+
+    void run();
+    void checkpoint();
+
+    void register_fs(RGWLibFS* fs) {
+      lock_guard guard(mtx);
+      mounted_fs.insert(FSMAP::value_type(fs, fs));
+      ++gen;
+    }
+
+    void unregister_fs(RGWLibFS* fs) {
+      lock_guard guard(mtx);
+      FSMAP::iterator it = mounted_fs.find(fs);
+      if (it != mounted_fs.end()) {
+	mounted_fs.erase(it);
+	++gen;
+      }
+    }
+
+    void enqueue_req(RGWLibRequest* req) {
+
+      lsubdout(g_ceph_context, rgw, 10)
+	<< __func__ << " enqueue request req="
+	<< hex << req << dec << dendl;
+
+      req_throttle.get(1);
+      req_wq.queue(req);
+    } /* enqueue_req */
+
+    /* "regular" requests */
+    void handle_request(RGWRequest* req); // async handler, deletes req
+    int process_request(RGWLibRequest* req);
+    int process_request(RGWLibRequest* req, RGWLibIO* io);
+    void set_access_key(RGWAccessKey& key) { access_key = key; }
+
+    /* requests w/continue semantics */
+    int start_request(RGWLibContinuedReq* req);
+    int finish_request(RGWLibContinuedReq* req);
+  }; /* RGWLibProcess */
+
+  class RGWLibFrontend : public RGWProcessFrontend {
+  public:
+    RGWLibFrontend(RGWProcessEnv& pe, RGWFrontendConfig *_conf)
+      : RGWProcessFrontend(pe, _conf) {}
+		
+    int init();
+
+    RGWLibProcess* get_process() {
+      return static_cast<RGWLibProcess*>(pprocess);
+    }
+
+    inline void enqueue_req(RGWLibRequest* req) {
+      static_cast<RGWLibProcess*>(pprocess)->enqueue_req(req); // async
+    }
+
+    inline int execute_req(RGWLibRequest* req) {
+      return static_cast<RGWLibProcess*>(pprocess)->process_request(req); // !async
+    }
+
+    inline int start_req(RGWLibContinuedReq* req) {
+      return static_cast<RGWLibProcess*>(pprocess)->start_request(req);
+    }
+
+    inline int finish_req(RGWLibContinuedReq* req) {
+      return static_cast<RGWLibProcess*>(pprocess)->finish_request(req);
+    }
+
+  }; /* RGWLibFrontend */
+
+} /* namespace rgw */
+
+#endif /* RGW_LIB_FRONTEND_H */
diff --git a/src/rgw/rgw_loadgen.h b/src/rgw/rgw_loadgen.h
index 8751315..01b2161 100644
--- a/src/rgw/rgw_loadgen.h
+++ b/src/rgw/rgw_loadgen.h
@@ -24,7 +24,9 @@ struct RGWLoadGenRequestEnv {
   int sign(RGWAccessKey& access_key);
 };
 
-class RGWLoadGenIO : public RGWClientIO
+/* XXX does RGWLoadGenIO actually want to perform stream/HTTP I/O,
+ * or (e.g) are these NOOPs? */
+class RGWLoadGenIO : public RGWStreamIO
 {
   uint64_t left_to_read;
   RGWLoadGenRequestEnv *req;
@@ -44,5 +46,4 @@ public:
   void flush();
 };
 
-
 #endif
diff --git a/src/rgw/rgw_loadgen_process.cc b/src/rgw/rgw_loadgen_process.cc
new file mode 100644
index 0000000..0e4aeb2
--- /dev/null
+++ b/src/rgw/rgw_loadgen_process.cc
@@ -0,0 +1,144 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+
+#include "common/errno.h"
+#include "common/Throttle.h"
+#include "common/WorkQueue.h"
+
+#include "rgw_rados.h"
+#include "rgw_rest.h"
+#include "rgw_frontend.h"
+#include "rgw_request.h"
+#include "rgw_process.h"
+#include "rgw_loadgen.h"
+#include "rgw_client_io.h"
+
+#define dout_subsys ceph_subsys_rgw
+
+extern void signal_shutdown();
+
+void RGWLoadGenProcess::checkpoint()
+{
+  m_tp.drain(&req_wq);
+}
+
+void RGWLoadGenProcess::run()
+{
+  m_tp.start(); /* start thread pool */
+
+  int i;
+
+  int num_objs;
+
+  conf->get_val("num_objs", 1000, &num_objs);
+
+  int num_buckets;
+  conf->get_val("num_buckets", 1, &num_buckets);
+
+  vector<string> buckets(num_buckets);
+
+  atomic_t failed;
+
+  for (i = 0; i < num_buckets; i++) {
+    buckets[i] = "/loadgen";
+    string& bucket = buckets[i];
+    append_rand_alpha(NULL, bucket, bucket, 16);
+
+    /* first create a bucket */
+    gen_request("PUT", bucket, 0, &failed);
+    checkpoint();
+  }
+
+  string *objs = new string[num_objs];
+
+  if (failed.read()) {
+    derr << "ERROR: bucket creation failed" << dendl;
+    goto done;
+  }
+
+  for (i = 0; i < num_objs; i++) {
+    char buf[16 + 1];
+    gen_rand_alphanumeric(NULL, buf, sizeof(buf));
+    buf[16] = '\0';
+    objs[i] = buckets[i % num_buckets] + "/" + buf;
+  }
+
+  for (i = 0; i < num_objs; i++) {
+    gen_request("PUT", objs[i], 4096, &failed);
+  }
+
+  checkpoint();
+
+  if (failed.read()) {
+    derr << "ERROR: bucket creation failed" << dendl;
+    goto done;
+  }
+
+  for (i = 0; i < num_objs; i++) {
+    gen_request("GET", objs[i], 4096, NULL);
+  }
+
+  checkpoint();
+
+  for (i = 0; i < num_objs; i++) {
+    gen_request("DELETE", objs[i], 0, NULL);
+  }
+
+  checkpoint();
+
+  for (i = 0; i < num_buckets; i++) {
+    gen_request("DELETE", buckets[i], 0, NULL);
+  }
+
+done:
+  checkpoint();
+
+  m_tp.stop();
+
+  delete[] objs;
+
+  signal_shutdown();
+} /* RGWLoadGenProcess::run() */
+
+void RGWLoadGenProcess::gen_request(const string& method,
+				    const string& resource,
+				    int content_length, atomic_t* fail_flag)
+{
+  RGWLoadGenRequest* req =
+    new RGWLoadGenRequest(store->get_new_req_id(), method, resource,
+			  content_length, fail_flag);
+  dout(10) << "allocated request req=" << hex << req << dec << dendl;
+  req_throttle.get(1);
+  req_wq.queue(req);
+} /* RGWLoadGenProcess::gen_request */
+
+void RGWLoadGenProcess::handle_request(RGWRequest* r)
+{
+  RGWLoadGenRequest* req = static_cast<RGWLoadGenRequest*>(r);
+
+  RGWLoadGenRequestEnv env;
+
+  utime_t tm = ceph_clock_now(NULL);
+
+  env.port = 80;
+  env.content_length = req->content_length;
+  env.content_type = "binary/octet-stream";
+  env.request_method = req->method;
+  env.uri = req->resource;
+  env.set_date(tm);
+  env.sign(access_key);
+
+  RGWLoadGenIO client_io(&env);
+
+  int ret = process_request(store, rest, req, &client_io, olog);
+  if (ret < 0) {
+    /* we don't really care about return code */
+    dout(20) << "process_request() returned " << ret << dendl;
+
+    if (req->fail_flag) {
+      req->fail_flag->inc();
+    }
+  }
+
+  delete req;
+} /* RGWLoadGenProcess::handle_request */
diff --git a/src/rgw/rgw_log.cc b/src/rgw/rgw_log.cc
index c600386..3bef606 100644
--- a/src/rgw/rgw_log.cc
+++ b/src/rgw/rgw_log.cc
@@ -23,7 +23,8 @@ static void set_param_str(struct req_state *s, const char *name, string& str)
 }
 
 string render_log_object_name(const string& format,
-			      struct tm *dt, string& bucket_id, const string& bucket_name)
+			      struct tm *dt, string& bucket_id,
+			      const string& bucket_name)
 {
   string o;
   for (unsigned i=0; i<format.size(); i++) {
@@ -126,14 +127,16 @@ public:
     round_timestamp = ts.round_to_hour();
   }
 
-  void insert(utime_t& timestamp, rgw_usage_log_entry& entry) {
+  void insert_user(utime_t& timestamp, const rgw_user& user, rgw_usage_log_entry& entry) {
     lock.Lock();
     if (timestamp.sec() > round_timestamp + 3600)
       recalc_round_timestamp(timestamp);
     entry.epoch = round_timestamp.sec();
     bool account;
-    rgw_user_bucket ub(entry.owner, entry.bucket);
-    usage_map[ub].insert(round_timestamp, entry, &account);
+    string u = user.to_str();
+    rgw_user_bucket ub(u, entry.bucket);
+    real_time rt = round_timestamp.to_real_time();
+    usage_map[ub].insert(rt, entry, &account);
     if (account)
       num_entries++;
     bool need_flush = (num_entries > cct->_conf->rgw_usage_log_flush_threshold);
@@ -144,6 +147,14 @@ public:
     }
   }
 
+  void insert(utime_t& timestamp, rgw_usage_log_entry& entry) {
+    if (entry.payer.empty()) {
+      insert_user(timestamp, entry.owner, entry);
+    } else {
+      insert_user(timestamp, entry.payer, entry);
+    }
+  }
+
   void flush() {
     map<rgw_user_bucket, RGWUsageBatch> old_map;
     lock.Lock();
@@ -177,14 +188,28 @@ static void log_usage(struct req_state *s, const string& op_name)
     return;
 
   rgw_user user;
+  rgw_user payer;
+  string bucket_name;
+
+  bucket_name = s->bucket_name;
 
-  if (!s->bucket_name.empty())
+  if (!bucket_name.empty()) {
     user = s->bucket_owner.get_id();
-  else
-    user = s->user.user_id;
+    if (s->bucket_info.requester_pays) {
+      payer = s->user->user_id;
+    }
+  } else {
+      user = s->user->user_id;
+  }
 
-  string id = user.to_str();
-  rgw_usage_log_entry entry(id, s->bucket.name);
+  bool error = s->err.is_err();
+  if (error && s->err.http_ret == 404) {
+    bucket_name = "-"; /* bucket not found, use the invalid '-' as bucket name */
+  }
+
+  string u = user.to_str();
+  string p = payer.to_str();
+  rgw_usage_log_entry entry(u, p, bucket_name);
 
   uint64_t bytes_sent = s->cio->get_bytes_sent();
   uint64_t bytes_received = s->cio->get_bytes_received();
@@ -192,7 +217,7 @@ static void log_usage(struct req_state *s, const string& op_name)
   rgw_usage_data data(bytes_sent, bytes_received);
 
   data.ops = 1;
-  if (!s->err.is_err())
+  if (!error)
     data.successful_ops = 1;
 
   entry.add(op_name, data);
@@ -305,20 +330,20 @@ int rgw_log_op(RGWRados *store, struct req_state *s, const string& op_name, OpsL
   entry.obj_size = s->obj_size;
 
   if (s->cct->_conf->rgw_remote_addr_param.length())
-    set_param_str(s, s->cct->_conf->rgw_remote_addr_param.c_str(), entry.remote_addr);
+    set_param_str(s, s->cct->_conf->rgw_remote_addr_param.c_str(),
+		  entry.remote_addr);
   else
-    set_param_str(s, "REMOTE_ADDR", entry.remote_addr);    
+    set_param_str(s, "REMOTE_ADDR", entry.remote_addr);
   set_param_str(s, "HTTP_USER_AGENT", entry.user_agent);
   set_param_str(s, "HTTP_REFERRER", entry.referrer);
   set_param_str(s, "REQUEST_URI", entry.uri);
   set_param_str(s, "REQUEST_METHOD", entry.op);
 
-  entry.user = s->user.user_id.to_str();
+  entry.user = s->user->user_id.to_str();
   if (s->object_acl)
     entry.object_owner = s->object_acl->get_owner().get_id();
   entry.bucket_owner = s->bucket_owner.get_id();
 
-
   uint64_t bytes_sent = s->cio->get_bytes_sent();
   uint64_t bytes_received = s->cio->get_bytes_received();
 
@@ -352,11 +377,11 @@ int rgw_log_op(RGWRados *store, struct req_state *s, const string& op_name, OpsL
     string oid = render_log_object_name(s->cct->_conf->rgw_log_object_name, &bdt,
 				        s->bucket.bucket_id, entry.bucket);
 
-    rgw_obj obj(store->zone.log_pool, oid);
+    rgw_obj obj(store->get_zone_params().log_pool, oid);
 
     ret = store->append_async(obj, bl.length(), bl);
     if (ret == -ENOENT) {
-      ret = store->create_pool(store->zone.log_pool);
+      ret = store->create_pool(store->get_zone_params().log_pool);
       if (ret < 0)
         goto done;
       // retry
diff --git a/src/rgw/rgw_main.cc b/src/rgw/rgw_main.cc
index 09b2e99..b5adf5e 100644
--- a/src/rgw/rgw_main.cc
+++ b/src/rgw/rgw_main.cc
@@ -13,32 +13,24 @@
 
 #include <curl/curl.h>
 
-#include "acconfig.h"
-#ifdef FASTCGI_INCLUDE_DIR
-# include "fastcgi/fcgiapp.h"
-#else
-# include "fcgiapp.h"
-#endif
+#include <boost/intrusive_ptr.hpp>
 
-#include "rgw_fcgi.h"
+#include "acconfig.h"
 
 #include "common/ceph_argparse.h"
 #include "global/global_init.h"
 #include "global/signal_handler.h"
 #include "common/config.h"
 #include "common/errno.h"
-#include "common/WorkQueue.h"
 #include "common/Timer.h"
-#include "common/Throttle.h"
-#include "common/QueueRing.h"
 #include "common/safe_io.h"
 #include "include/compat.h"
 #include "include/str_list.h"
 #include "rgw_common.h"
 #include "rgw_rados.h"
-#include "rgw_acl.h"
 #include "rgw_user.h"
-#include "rgw_op.h"
+#include "rgw_period_pusher.h"
+#include "rgw_realm_reloader.h"
 #include "rgw_rest.h"
 #include "rgw_rest_s3.h"
 #include "rgw_rest_swift.h"
@@ -52,22 +44,20 @@
 #include "rgw_replica_log.h"
 #include "rgw_rest_replica_log.h"
 #include "rgw_rest_config.h"
+#include "rgw_rest_realm.h"
 #include "rgw_swift_auth.h"
 #include "rgw_swift.h"
 #include "rgw_log.h"
 #include "rgw_tools.h"
 #include "rgw_resolve.h"
-#include "rgw_loadgen.h"
-#include "rgw_civetweb.h"
-#include "rgw_civetweb_log.h"
 
-#include "civetweb/civetweb.h"
+#include "rgw_request.h"
+#include "rgw_process.h"
+#include "rgw_frontend.h"
 
 #include <map>
 #include <string>
 #include <vector>
-#include <iostream>
-#include <sstream>
 
 #include "include/types.h"
 #include "common/BackTrace.h"
@@ -83,409 +73,15 @@ class RGWProcess;
 static int signal_fd[2] = {0, 0};
 static atomic_t disable_signal_fd;
 
-static void signal_shutdown();
-
-
-#define SOCKET_BACKLOG 1024
-
-struct RGWRequest
-{
-  uint64_t id;
-  struct req_state *s;
-  string req_str;
-  RGWOp *op;
-  utime_t ts;
-
-  explicit RGWRequest(uint64_t id) : id(id), s(NULL), op(NULL) {
-  }
-
-  virtual ~RGWRequest() {}
-
-  void init_state(req_state *_s) {
-    s = _s;
-  }
-
-  void log_format(struct req_state *s, const char *fmt, ...)
-  {
-#define LARGE_SIZE 1024
-    char buf[LARGE_SIZE];
-    va_list ap;
-
-    va_start(ap, fmt);
-    vsnprintf(buf, sizeof(buf), fmt, ap);
-    va_end(ap);
-
-    log(s, buf);
-  }
-
-  void log_init() {
-    ts = ceph_clock_now(g_ceph_context);
-  }
-
-  void log(struct req_state *s, const char *msg) {
-    if (s->info.method && req_str.size() == 0) {
-      req_str = s->info.method;
-      req_str.append(" ");
-      req_str.append(s->info.request_uri);
-    }
-    utime_t t = ceph_clock_now(g_ceph_context) - ts;
-    dout(2) << "req " << id << ":" << t << ":" << s->dialect << ":" << req_str << ":" << (op ? op->name() : "") << ":" << msg << dendl;
-  }
-};
-
-class RGWFrontendConfig {
-  string config;
-  map<string, string> config_map;
-  int parse_config(const string& config, map<string, string>& config_map);
-  string framework;
-public:
-  explicit RGWFrontendConfig(const string& _conf) : config(_conf) {}
-  int init() {
-    int ret = parse_config(config, config_map);
-    if (ret < 0)
-      return ret;
-    return 0;
-  }
-  bool get_val(const string& key, const string& def_val, string *out);
-  bool get_val(const string& key, int def_val, int *out);
-
-  map<string, string>& get_config_map() { return config_map; }
-
-  string get_framework() { return framework; }
-};
-
-
-struct RGWFCGXRequest : public RGWRequest {
-  FCGX_Request *fcgx;
-  QueueRing<FCGX_Request *> *qr;
-
-  RGWFCGXRequest(uint64_t req_id, QueueRing<FCGX_Request *> *_qr) : RGWRequest(req_id), qr(_qr) {
-    qr->dequeue(&fcgx);
-  }
-
-  ~RGWFCGXRequest() {
-    FCGX_Finish_r(fcgx);
-    qr->enqueue(fcgx);
-  }
-};
-
-struct RGWProcessEnv {
-  RGWRados *store;
-  RGWREST *rest;
-  OpsLogSocket *olog;
-  int port;
-};
-
-class RGWProcess {
-  deque<RGWRequest *> m_req_queue;
-protected:
-  RGWRados *store;
-  OpsLogSocket *olog;
-  ThreadPool m_tp;
-  Throttle req_throttle;
-  RGWREST *rest;
-  RGWFrontendConfig *conf;
-  int sock_fd;
-
-  struct RGWWQ : public ThreadPool::WorkQueue<RGWRequest> {
-    RGWProcess *process;
-    RGWWQ(RGWProcess *p, time_t timeout, time_t suicide_timeout, ThreadPool *tp)
-      : ThreadPool::WorkQueue<RGWRequest>("RGWWQ", timeout, suicide_timeout, tp), process(p) {}
-
-    bool _enqueue(RGWRequest *req) {
-      process->m_req_queue.push_back(req);
-      perfcounter->inc(l_rgw_qlen);
-      dout(20) << "enqueued request req=" << hex << req << dec << dendl;
-      _dump_queue();
-      return true;
-    }
-    void _dequeue(RGWRequest *req) {
-      assert(0);
-    }
-    bool _empty() {
-      return process->m_req_queue.empty();
-    }
-    RGWRequest *_dequeue() {
-      if (process->m_req_queue.empty())
-	return NULL;
-      RGWRequest *req = process->m_req_queue.front();
-      process->m_req_queue.pop_front();
-      dout(20) << "dequeued request req=" << hex << req << dec << dendl;
-      _dump_queue();
-      perfcounter->inc(l_rgw_qlen, -1);
-      return req;
-    }
-    void _process(RGWRequest *req, ThreadPool::TPHandle &) override {
-      perfcounter->inc(l_rgw_qactive);
-      process->handle_request(req);
-      process->req_throttle.put(1);
-      perfcounter->inc(l_rgw_qactive, -1);
-    }
-    void _dump_queue() {
-      if (!g_conf->subsys.should_gather(ceph_subsys_rgw, 20)) {
-        return;
-      }
-      deque<RGWRequest *>::iterator iter;
-      if (process->m_req_queue.empty()) {
-        dout(20) << "RGWWQ: empty" << dendl;
-        return;
-      }
-      dout(20) << "RGWWQ:" << dendl;
-      for (iter = process->m_req_queue.begin(); iter != process->m_req_queue.end(); ++iter) {
-        dout(20) << "req: " << hex << *iter << dec << dendl;
-      }
-    }
-    void _clear() {
-      assert(process->m_req_queue.empty());
-    }
-  } req_wq;
-
-public:
-  RGWProcess(CephContext *cct, RGWProcessEnv *pe, int num_threads, RGWFrontendConfig *_conf)
-    : store(pe->store), olog(pe->olog), m_tp(cct, "RGWProcess::m_tp", "tp_rgw_process", num_threads),
-      req_throttle(cct, "rgw_ops", num_threads * 2),
-      rest(pe->rest),
-      conf(_conf),
-      sock_fd(-1),
-      req_wq(this, g_conf->rgw_op_thread_timeout,
-	     g_conf->rgw_op_thread_suicide_timeout, &m_tp) {}
-  virtual ~RGWProcess() {}
-  virtual void run() = 0;
-  virtual void handle_request(RGWRequest *req) = 0;
-
-  void close_fd() {
-    if (sock_fd >= 0) {
-      ::close(sock_fd);
-      sock_fd = -1;
-    }
-  }
-};
-
-
-class RGWFCGXProcess : public RGWProcess {
-  int max_connections;
-public:
-  RGWFCGXProcess(CephContext *cct, RGWProcessEnv *pe, int num_threads, RGWFrontendConfig *_conf) :
-    RGWProcess(cct, pe, num_threads, _conf),
-    max_connections(num_threads + (num_threads >> 3)) /* have a bit more connections than threads so that requests
-                                                       are still accepted even if we're still processing older requests */
-    {}
-  void run();
-  void handle_request(RGWRequest *req);
-};
-
-void RGWFCGXProcess::run()
-{
-  string socket_path;
-  string socket_port;
-  string socket_host;
-
-  conf->get_val("socket_path", "", &socket_path);
-  conf->get_val("socket_port", g_conf->rgw_port, &socket_port);
-  conf->get_val("socket_host", g_conf->rgw_host, &socket_host);
-
-  if (socket_path.empty() && socket_port.empty() && socket_host.empty()) {
-    socket_path = g_conf->rgw_socket_path;
-    if (socket_path.empty()) {
-      dout(0) << "ERROR: no socket server point defined, cannot start fcgi frontend" << dendl;
-      return;
-    }
-  }
-
-  if (!socket_path.empty()) {
-    string path_str = socket_path;
-
-    /* this is necessary, as FCGX_OpenSocket might not return an error, but rather ungracefully exit */
-    int fd = open(path_str.c_str(), O_CREAT, 0644);
-    if (fd < 0) {
-      int err = errno;
-      /* ENXIO is actually expected, we'll get that if we try to open a unix domain socket */
-      if (err != ENXIO) {
-        dout(0) << "ERROR: cannot create socket: path=" << path_str << " error=" << cpp_strerror(err) << dendl;
-        return;
-      }
-    } else {
-      close(fd);
-    }
-
-    const char *path = path_str.c_str();
-    sock_fd = FCGX_OpenSocket(path, SOCKET_BACKLOG);
-    if (sock_fd < 0) {
-      dout(0) << "ERROR: FCGX_OpenSocket (" << path << ") returned " << sock_fd << dendl;
-      return;
-    }
-    if (chmod(path, 0777) < 0) {
-      dout(0) << "WARNING: couldn't set permissions on unix domain socket" << dendl;
-    }
-  } else if (!socket_port.empty()) {
-    string bind = socket_host + ":" + socket_port;
-    sock_fd = FCGX_OpenSocket(bind.c_str(), SOCKET_BACKLOG);
-    if (sock_fd < 0) {
-      dout(0) << "ERROR: FCGX_OpenSocket (" << bind.c_str() << ") returned " << sock_fd << dendl;
-      return;
-    }
-  }
-
-  m_tp.start();
-
-  FCGX_Request fcgx_reqs[max_connections];
-
-  QueueRing<FCGX_Request *> qr(max_connections);
-  for (int i = 0; i < max_connections; i++) {
-    FCGX_Request *fcgx = &fcgx_reqs[i];
-    FCGX_InitRequest(fcgx, sock_fd, 0);
-    qr.enqueue(fcgx);
-  }
-
-  for (;;) {
-    RGWFCGXRequest *req = new RGWFCGXRequest(store->get_new_req_id(), &qr);
-    dout(10) << "allocated request req=" << hex << req << dec << dendl;
-    req_throttle.get(1);
-    int ret = FCGX_Accept_r(req->fcgx);
-    if (ret < 0) {
-      delete req;
-      dout(0) << "ERROR: FCGX_Accept_r returned " << ret << dendl;
-      req_throttle.put(1);
-      break;
-    }
-
-    req_wq.queue(req);
-  }
-
-  m_tp.drain(&req_wq);
-  m_tp.stop();
-
-  dout(20) << "cleaning up fcgx connections" << dendl;
-
-  for (int i = 0; i < max_connections; i++) {
-    FCGX_Finish_r(&fcgx_reqs[i]);
-  }
-}
-
-struct RGWLoadGenRequest : public RGWRequest {
-  string method;
-  string resource;
-  int content_length;
-  atomic_t *fail_flag;
-
-
-  RGWLoadGenRequest(uint64_t req_id, const string& _m, const  string& _r, int _cl,
-                    atomic_t *ff) : RGWRequest(req_id), method(_m), resource(_r), content_length(_cl), fail_flag(ff) {}
-};
-
-class RGWLoadGenProcess : public RGWProcess {
-  RGWAccessKey access_key;
-public:
-  RGWLoadGenProcess(CephContext *cct, RGWProcessEnv *pe, int num_threads, RGWFrontendConfig *_conf) :
-    RGWProcess(cct, pe, num_threads, _conf) {}
-  void run();
-  void checkpoint();
-  void handle_request(RGWRequest *req);
-  void gen_request(const string& method, const string& resource, int content_length, atomic_t *fail_flag);
-
-  void set_access_key(RGWAccessKey& key) { access_key = key; }
-};
-
-void RGWLoadGenProcess::checkpoint()
-{
-  m_tp.drain(&req_wq);
-}
-
-void RGWLoadGenProcess::run()
-{
-  m_tp.start(); /* start thread pool */
-
-  int i;
-
-  int num_objs;
-
-  conf->get_val("num_objs", 1000, &num_objs);
-
-  int num_buckets;
-  conf->get_val("num_buckets", 1, &num_buckets);
-
-  vector<string> buckets(num_buckets);
-
-  atomic_t failed;
-
-  for (i = 0; i < num_buckets; i++) {
-    buckets[i] = "/loadgen";
-    string& bucket = buckets[i];
-    append_rand_alpha(NULL, bucket, bucket, 16);
-
-    /* first create a bucket */
-    gen_request("PUT", bucket, 0, &failed);
-    checkpoint();
-  }
-
-  string *objs = new string[num_objs];
-
-  if (failed.read()) {
-    derr << "ERROR: bucket creation failed" << dendl;
-    goto done;
-  }
-
-  for (i = 0; i < num_objs; i++) {
-    char buf[16 + 1];
-    gen_rand_alphanumeric(NULL, buf, sizeof(buf));
-    buf[16] = '\0';
-    objs[i] = buckets[i % num_buckets] + "/" + buf;
-  }
-
-  for (i = 0; i < num_objs; i++) {
-    gen_request("PUT", objs[i], 4096, &failed);
-  }
-
-  checkpoint();
-
-  if (failed.read()) {
-    derr << "ERROR: bucket creation failed" << dendl;
-    goto done;
-  }
-
-  for (i = 0; i < num_objs; i++) {
-    gen_request("GET", objs[i], 4096, NULL);
-  }
-
-  checkpoint();
-
-  for (i = 0; i < num_objs; i++) {
-    gen_request("DELETE", objs[i], 0, NULL);
-  }
-
-  checkpoint();
-
-  for (i = 0; i < num_buckets; i++) {
-    gen_request("DELETE", buckets[i], 0, NULL);
-  }
-
-done:
-  checkpoint();
-
-  m_tp.stop();
-
-  delete[] objs;
-
-  signal_shutdown();
-}
-
-void RGWLoadGenProcess::gen_request(const string& method, const string& resource, int content_length, atomic_t *fail_flag)
-{
-  RGWLoadGenRequest *req = new RGWLoadGenRequest(store->get_new_req_id(), method, resource,
-						 content_length, fail_flag);
-  dout(10) << "allocated request req=" << hex << req << dec << dendl;
-  req_throttle.get(1);
-  req_wq.queue(req);
-}
-
-static void signal_shutdown()
+void signal_shutdown()
 {
   if (!disable_signal_fd.read()) {
     int val = 0;
     int ret = write(signal_fd[0], (char *)&val, sizeof(val));
     if (ret < 0) {
       int err = -errno;
-      derr << "ERROR: " << __func__ << ": write() returned " << cpp_strerror(-err) << dendl;
+      derr << "ERROR: " << __func__ << ": write() returned "
+	   << cpp_strerror(-err) << dendl;
     }
   }
 }
@@ -535,245 +131,6 @@ static void godown_alarm(int signum)
   _exit(0);
 }
 
-static int process_request(RGWRados *store, RGWREST *rest, RGWRequest *req, RGWClientIO *client_io, OpsLogSocket *olog)
-{
-  int ret = 0;
-
-  client_io->init(g_ceph_context);
-
-  req->log_init();
-
-  dout(1) << "====== starting new request req=" << hex << req << dec << " =====" << dendl;
-  perfcounter->inc(l_rgw_req);
-
-  RGWEnv& rgw_env = client_io->get_env();
-
-  struct req_state rstate(g_ceph_context, &rgw_env);
-
-  struct req_state *s = &rstate;
-
-  RGWObjectCtx rados_ctx(store, s);
-  s->obj_ctx = &rados_ctx;
-
-  s->req_id = store->unique_id(req->id);
-  s->trans_id = store->unique_trans_id(req->id);
-
-  req->log_format(s, "initializing for trans_id = %s", s->trans_id.c_str());
-
-  RGWOp *op = NULL;
-  int init_error = 0;
-  bool should_log = false;
-  RGWRESTMgr *mgr;
-  RGWHandler *handler = rest->get_handler(store, s, client_io, &mgr, &init_error);
-  if (init_error != 0) {
-    abort_early(s, NULL, init_error, NULL);
-    goto done;
-  }
-  dout(10) << "handler=" << typeid(*handler).name() << dendl;
-
-  should_log = mgr->get_logging();
-
-  req->log_format(s, "getting op %d", s->op);
-  op = handler->get_op(store);
-  if (!op) {
-    abort_early(s, NULL, -ERR_METHOD_NOT_ALLOWED, handler);
-    goto done;
-  }
-  req->op = op;
-  dout(10) << "op=" << typeid(*op).name() << dendl;
-
-  req->log(s, "authorizing");
-  ret = handler->authorize();
-  if (ret < 0) {
-    dout(10) << "failed to authorize request" << dendl;
-    abort_early(s, NULL, ret, handler);
-    goto done;
-  }
-
-  req->log(s, "normalizing buckets and tenants");
-  ret = handler->postauth_init();
-  if (ret < 0) {
-    dout(10) << "failed to run post-auth init" << dendl;
-    abort_early(s, op, ret, handler);
-    goto done;
-  }
-
-  if (s->user.suspended) {
-    dout(10) << "user is suspended, uid=" << s->user.user_id << dendl;
-    abort_early(s, op, -ERR_USER_SUSPENDED, handler);
-    goto done;
-  }
-
-  req->log(s, "init permissions");
-  ret = handler->init_permissions(op);
-  if (ret < 0) {
-    abort_early(s, op, ret, handler);
-    goto done;
-  }
-
-  /**
-   * Only some accesses support website mode, and website mode does NOT apply
-   * if you are using the REST endpoint either (ergo, no authenticated access)
-   */
-  req->log(s, "recalculating target");
-  ret = handler->retarget(op, &op);
-  if (ret < 0) {
-    abort_early(s, op, ret, handler);
-    goto done;
-  }
-  req->op = op;
-
-  req->log(s, "reading permissions");
-  ret = handler->read_permissions(op);
-  if (ret < 0) {
-    abort_early(s, op, ret, handler);
-    goto done;
-  }
-
-  req->log(s, "init op");
-  ret = op->init_processing();
-  if (ret < 0) {
-    abort_early(s, op, ret, handler);
-    goto done;
-  }
-
-  req->log(s, "verifying op mask");
-  ret = op->verify_op_mask();
-  if (ret < 0) {
-    abort_early(s, op, ret, handler);
-    goto done;
-  }
-
-  req->log(s, "verifying op permissions");
-  ret = op->verify_permission();
-  if (ret < 0) {
-    if (s->system_request) {
-      dout(2) << "overriding permissions due to system operation" << dendl;
-    } else {
-      abort_early(s, op, ret, handler);
-      goto done;
-    }
-  }
-
-  req->log(s, "verifying op params");
-  ret = op->verify_params();
-  if (ret < 0) {
-    abort_early(s, op, ret, handler);
-    goto done;
-  }
-
-  req->log(s, "pre-executing");
-  op->pre_exec();
-
-  req->log(s, "executing");
-  op->execute();
-
-  req->log(s, "completing");
-  op->complete();
-done:
-  int r = client_io->complete_request();
-  if (r < 0) {
-    dout(0) << "ERROR: client_io->complete_request() returned " << r << dendl;
-  }
-  if (should_log) {
-    rgw_log_op(store, s, (op ? op->name() : "unknown"), olog);
-  }
-
-  int http_ret = s->err.http_ret;
-
-  int op_ret = 0;
-  if (op) {
-    op_ret = op->get_ret();
-  }
-
-  req->log_format(s, "op status=%d", op_ret);
-  req->log_format(s, "http status=%d", http_ret);
-
-  if (handler)
-    handler->put_op(op);
-  rest->put_handler(handler);
-
-  dout(1) << "====== req done req=" << hex << req << dec
-	  << " op status=" << op_ret
-	  << " http_status=" << http_ret
-	  << " ======"
-	  << dendl;
-
-  return (ret < 0 ? ret : s->err.ret);
-}
-
-void RGWFCGXProcess::handle_request(RGWRequest *r)
-{
-  RGWFCGXRequest *req = static_cast<RGWFCGXRequest *>(r);
-  FCGX_Request *fcgx = req->fcgx;
-  RGWFCGX client_io(fcgx);
-
- 
-  int ret = process_request(store, rest, req, &client_io, olog);
-  if (ret < 0) {
-    /* we don't really care about return code */
-    dout(20) << "process_request() returned " << ret << dendl;
-  }
-
-  FCGX_Finish_r(fcgx);
-
-  delete req;
-}
-
-void RGWLoadGenProcess::handle_request(RGWRequest *r)
-{
-  RGWLoadGenRequest *req = static_cast<RGWLoadGenRequest *>(r);
-
-  RGWLoadGenRequestEnv env;
-
-  utime_t tm = ceph_clock_now(NULL);
-
-  env.port = 80;
-  env.content_length = req->content_length;
-  env.content_type = "binary/octet-stream";
-  env.request_method = req->method;
-  env.uri = req->resource;
-  env.set_date(tm);
-  env.sign(access_key);
-
-  RGWLoadGenIO client_io(&env);
-
-  int ret = process_request(store, rest, req, &client_io, olog);
-  if (ret < 0) {
-    /* we don't really care about return code */
-    dout(20) << "process_request() returned " << ret << dendl;
-
-    if (req->fail_flag) {
-      req->fail_flag->inc();
-    }
-  }
-
-  delete req;
-}
-
-
-static int civetweb_callback(struct mg_connection *conn) {
-  struct mg_request_info *req_info = mg_get_request_info(conn);
-  RGWProcessEnv *pe = static_cast<RGWProcessEnv *>(req_info->user_data);
-  RGWRados *store = pe->store;
-  RGWREST *rest = pe->rest;
-  OpsLogSocket *olog = pe->olog;
-
-  RGWRequest *req = new RGWRequest(store->get_new_req_id());
-  RGWMongoose client_io(conn, pe->port);
-
-  int ret = process_request(store, rest, req, &client_io, olog);
-  if (ret < 0) {
-    /* we don't really care about return code */
-    dout(20) << "process_request() returned " << ret << dendl;
-  }
-
-  delete req;
-
-// Mark as processed
-  return 1;
-}
-
 #ifdef HAVE_CURL_MULTI_WAIT
 static void check_curl()
 {
@@ -817,243 +174,8 @@ static RGWRESTMgr *set_logging(RGWRESTMgr *mgr)
   return mgr;
 }
 
-
-int RGWFrontendConfig::parse_config(const string& config, map<string, string>& config_map)
-{
-  list<string> config_list;
-  get_str_list(config, " ", config_list);
-
-  list<string>::iterator iter;
-  for (iter = config_list.begin(); iter != config_list.end(); ++iter) {
-    string& entry = *iter;
-    string key;
-    string val;
-
-    if (framework.empty()) {
-      framework = entry;
-      dout(0) << "framework: " << framework << dendl;
-      continue;
-    }
-
-    ssize_t pos = entry.find('=');
-    if (pos < 0) {
-      dout(0) << "framework conf key: " << entry << dendl;
-      config_map[entry] = "";
-      continue;
-    }
-
-    int ret = parse_key_value(entry, key, val);
-    if (ret < 0) {
-      cerr << "ERROR: can't parse " << entry << std::endl;
-      return ret;
-    }
-
-    dout(0) << "framework conf key: " << key << ", val: " << val << dendl;
-    config_map[key] = val;
-  }
-
-  return 0;
-}
-
-
-bool RGWFrontendConfig::get_val(const string& key, const string& def_val, string *out)
-{
- map<string, string>::iterator iter = config_map.find(key);
- if (iter == config_map.end()) {
-   *out = def_val;
-   return false;
- }
-
- *out = iter->second;
- return true;
-}
-
-
-bool RGWFrontendConfig::get_val(const string& key, int def_val, int *out)
-{
-  string str;
-  bool found = get_val(key, "", &str);
-  if (!found) {
-    *out = def_val;
-    return false;
-  }
-  string err;
-  *out = strict_strtol(str.c_str(), 10, &err);
-  if (!err.empty()) {
-    cerr << "error parsing int: " << str << ": " << err << std::endl;
-    return -EINVAL;
-  }
-  return 0;
-}
-
-class RGWFrontend {
-public:
-  virtual ~RGWFrontend() {}
-
-  virtual int init() = 0;
-
-  virtual int run() = 0;
-  virtual void stop() = 0;
-  virtual void join() = 0;
-};
-
-class RGWProcessControlThread : public Thread {
-  RGWProcess *pprocess;
-public:
-  explicit RGWProcessControlThread(RGWProcess *_pprocess) : pprocess(_pprocess) {}
-
-  void *entry() {
-    pprocess->run();
-    return NULL;
-  }
-};
-
-class RGWProcessFrontend : public RGWFrontend {
-protected:
-  RGWFrontendConfig *conf;
-  RGWProcess *pprocess;
-  RGWProcessEnv env;
-  RGWProcessControlThread *thread;
-
-public:
-  RGWProcessFrontend(RGWProcessEnv& pe, RGWFrontendConfig *_conf) : conf(_conf), pprocess(NULL), env(pe), thread(NULL) {
-  }
-
-  ~RGWProcessFrontend() {
-    delete thread;
-    delete pprocess;
-  }
-
-  int run() {
-    assert(pprocess); /* should have initialized by init() */
-    thread = new RGWProcessControlThread(pprocess);
-    thread->create("rgw_frontend");
-    return 0;
-  }
-
-  void stop() {
-    pprocess->close_fd();
-    thread->kill(SIGUSR1);
-  }
-
-  void join() {
-    thread->join();
-  }
-};
-
-class RGWFCGXFrontend : public RGWProcessFrontend {
-public:
-  RGWFCGXFrontend(RGWProcessEnv& pe, RGWFrontendConfig *_conf) : RGWProcessFrontend(pe, _conf) {}
-
-  int init() {
-    pprocess = new RGWFCGXProcess(g_ceph_context, &env, g_conf->rgw_thread_pool_size, conf);
-    return 0;
-  }
-};
-
-class RGWLoadGenFrontend : public RGWProcessFrontend {
-public:
-  RGWLoadGenFrontend(RGWProcessEnv& pe, RGWFrontendConfig *_conf) : RGWProcessFrontend(pe, _conf) {}
-
-  int init() {
-    int num_threads;
-    conf->get_val("num_threads", g_conf->rgw_thread_pool_size, &num_threads);
-    RGWLoadGenProcess *pp = new RGWLoadGenProcess(g_ceph_context, &env, num_threads, conf);
-
-    pprocess = pp;
-
-    string uid_str;
-    conf->get_val("uid", "", &uid_str);
-    if (uid_str.empty()) {
-      derr << "ERROR: uid param must be specified for loadgen frontend" << dendl;
-      return EINVAL;
-    }
-
-    rgw_user uid(uid_str);
-
-    RGWUserInfo user_info;
-    int ret = rgw_get_user_info_by_uid(env.store, uid, user_info, NULL);
-    if (ret < 0) {
-      derr << "ERROR: failed reading user info: uid=" << uid << " ret=" << ret << dendl;
-      return ret;
-    }
-
-    map<string, RGWAccessKey>::iterator aiter = user_info.access_keys.begin();
-    if (aiter == user_info.access_keys.end()) {
-      derr << "ERROR: user has no S3 access keys set" << dendl;
-      return -EINVAL;
-    }
-
-    pp->set_access_key(aiter->second);
-
-    return 0;
-  }
-};
-
-class RGWMongooseFrontend : public RGWFrontend {
-  RGWFrontendConfig *conf;
-  struct mg_context *ctx;
-  RGWProcessEnv env;
-
-  void set_conf_default(map<string, string>& m, const string& key, const string& def_val) {
-    if (m.find(key) == m.end()) {
-      m[key] = def_val;
-    }
-  }
-
-public:
-  RGWMongooseFrontend(RGWProcessEnv& pe, RGWFrontendConfig *_conf) : conf(_conf), ctx(NULL), env(pe) {
-  }
-
-  int init() {
-    return 0;
-  }
-
-  int run() {
-    char thread_pool_buf[32];
-    snprintf(thread_pool_buf, sizeof(thread_pool_buf), "%d", (int)g_conf->rgw_thread_pool_size);
-    string port_str;
-    map<string, string> conf_map = conf->get_config_map();
-    conf->get_val("port", "80", &port_str);
-    conf_map.erase("port");
-    conf_map["listening_ports"] = port_str;
-    set_conf_default(conf_map, "enable_keep_alive", "yes");
-    set_conf_default(conf_map, "num_threads", thread_pool_buf);
-    set_conf_default(conf_map, "decode_url", "no");
-
-    const char *options[conf_map.size() * 2 + 1];
-    int i = 0;
-    for (map<string, string>::iterator iter = conf_map.begin(); iter != conf_map.end(); ++iter) {
-      options[i] = iter->first.c_str();
-      options[i + 1] = iter->second.c_str();
-      dout(20)<< "civetweb config: " << options[i] << ": " << (options[i + 1] ? options[i + 1] : "<null>") << dendl;
-      i += 2;
-    }
-    options[i] = NULL;
-
-    struct mg_callbacks cb;
-    memset((void *)&cb, 0, sizeof(cb));
-    cb.begin_request = civetweb_callback;
-    cb.log_message = rgw_civetweb_log_callback;
-    cb.log_access = rgw_civetweb_log_access_callback;
-    ctx = mg_start(&cb, &env, (const char **)&options);
-
-    if (!ctx) {
-      return -EIO;
-    }
-
-    return 0;
-  }
-
-  void stop() {
-    if (ctx) {
-      mg_stop(ctx);
-    }
-  }
-
-  void join() {
-  }
-};
+void intrusive_ptr_add_ref(CephContext* cct) { cct->get(); }
+void intrusive_ptr_release(CephContext* cct) { cct->put(); }
 
 /*
  * start up the RADOS connection and then handle HTTP messages as they come in
@@ -1078,8 +200,53 @@ int main(int argc, const char **argv)
   vector<const char*> args;
   argv_to_vec(argc, argv, args);
   env_to_vec(args);
+
+  // First, let's determine which frontends are configured.
+  int flags = CINIT_FLAG_UNPRIVILEGED_DAEMON_DEFAULTS;
+  global_pre_init(&def_args, args, CEPH_ENTITY_TYPE_CLIENT, CODE_ENVIRONMENT_DAEMON,
+		  flags);
+
+  list<string> frontends;
+  get_str_list(g_conf->rgw_frontends, ",", frontends);
+  multimap<string, RGWFrontendConfig *> fe_map;
+  list<RGWFrontendConfig *> configs;
+  if (frontends.empty()) {
+    frontends.push_back("fastcgi");
+  }
+  for (list<string>::iterator iter = frontends.begin(); iter != frontends.end(); ++iter) {
+    string& f = *iter;
+
+    if (f.find("civetweb") != string::npos) {
+      // If civetweb is configured as a frontend, prevent global_init() from
+      // dropping permissions by setting the appropriate flag.
+      flags |= CINIT_FLAG_DEFER_DROP_PRIVILEGES;
+      if (f.find("port") != string::npos) {
+	// check for the most common ws problems
+	if ((f.find("port=") == string::npos) ||
+	    (f.find("port= ") != string::npos)) {
+	  derr << "WARNING: civetweb frontend config found unexpected spacing around 'port' (ensure civetweb port parameter has the form 'port=80' with no spaces before or after '=')" << dendl;
+	}
+      }
+    }
+
+    RGWFrontendConfig *config = new RGWFrontendConfig(f);
+    int r = config->init();
+    if (r < 0) {
+      cerr << "ERROR: failed to init config: " << f << std::endl;
+      return EINVAL;
+    }
+
+    configs.push_back(config);
+
+    string framework = config->get_framework();
+    fe_map.insert(pair<string, RGWFrontendConfig*>(framework, config));
+  }
+
+  // Now that we've determined which frontend(s) to use, continue with global
+  // initialization. Passing false as the final argument ensures that
+  // global_pre_init() is not invoked twice.
   global_init(&def_args, args, CEPH_ENTITY_TYPE_CLIENT, CODE_ENVIRONMENT_DAEMON,
-	      CINIT_FLAG_UNPRIVILEGED_DAEMON_DEFAULTS, "rgw_data");
+	      flags, "rgw_data", false);
 
   for (std::vector<const char*>::iterator i = args.begin(); i != args.end(); ++i) {
     if (ceph_argparse_flag(args, i, "-h", "--help", (char*)NULL)) {
@@ -1105,6 +272,9 @@ int main(int argc, const char **argv)
 
   common_init_finish(g_ceph_context);
 
+  // claim the reference and release it after subsequent destructors have fired
+  boost::intrusive_ptr<CephContext> cct(g_ceph_context, false);
+
   rgw_tools_init(g_ceph_context);
 
   rgw_init_resolver();
@@ -1115,7 +285,8 @@ int main(int argc, const char **argv)
 
   int r = 0;
   RGWRados *store = RGWStoreManager::get_storage(g_ceph_context,
-      g_conf->rgw_enable_gc_threads, g_conf->rgw_enable_quota_threads);
+      g_conf->rgw_enable_gc_threads, g_conf->rgw_enable_quota_threads,
+      g_conf->rgw_run_sync_thread);
   if (!store) {
     mutex.Lock();
     init_timer.cancel_all_events();
@@ -1127,7 +298,7 @@ int main(int argc, const char **argv)
   }
   r = rgw_perf_start(g_ceph_context);
 
-  rgw_rest_init(g_ceph_context, store->region);
+  rgw_rest_init(g_ceph_context, store, store->get_zonegroup());
 
   mutex.Lock();
   init_timer.cancel_all_events();
@@ -1161,11 +332,13 @@ int main(int argc, const char **argv)
   if (apis_map.count("swift") > 0) {
     do_swift = true;
     swift_init(g_ceph_context);
-    rest.register_resource(g_conf->rgw_swift_url_prefix, set_logging(new RGWRESTMgr_SWIFT));
+    rest.register_resource(g_conf->rgw_swift_url_prefix,
+			   set_logging(new RGWRESTMgr_SWIFT));
   }
 
   if (apis_map.count("swift_auth") > 0)
-    rest.register_resource(g_conf->rgw_swift_auth_entry, set_logging(new RGWRESTMgr_SWIFT_Auth));
+    rest.register_resource(g_conf->rgw_swift_auth_entry,
+			   set_logging(new RGWRESTMgr_SWIFT_Auth));
 
   if (apis_map.count("admin") > 0) {
     RGWRESTMgr_Admin *admin_resource = new RGWRESTMgr_Admin;
@@ -1179,6 +352,7 @@ int main(int argc, const char **argv)
     admin_resource->register_resource("opstate", new RGWRESTMgr_Opstate);
     admin_resource->register_resource("replica_log", new RGWRESTMgr_ReplicaLog);
     admin_resource->register_resource("config", new RGWRESTMgr_Config);
+    admin_resource->register_resource("realm", new RGWRESTMgr_Realm);
     rest.register_resource(g_conf->rgw_admin_entry, admin_resource);
   }
 
@@ -1202,43 +376,10 @@ int main(int argc, const char **argv)
   register_async_signal_handler(SIGUSR1, handle_sigterm);
   sighandler_alrm = signal(SIGALRM, godown_alarm);
 
-  list<string> frontends;
-  get_str_list(g_conf->rgw_frontends, ",", frontends);
-
-  multimap<string, RGWFrontendConfig *> fe_map;
-  list<RGWFrontendConfig *> configs;
-  if (frontends.empty()) {
-    frontends.push_back("fastcgi");
-  }
-  for (list<string>::iterator iter = frontends.begin(); iter != frontends.end(); ++iter) {
-    string& f = *iter;
-
-    if (f.find("civetweb") != string::npos) {
-      if (f.find("port") != string::npos) {
-	// check for the most common ws problems
-	if ((f.find("port=") == string::npos) ||
-	    (f.find("port= ") != string::npos)) {
-	  derr << "WARNING: civetweb frontend config found unexpected spacing around 'port' (ensure civetweb port parameter has the form 'port=80' with no spaces before or after '=')" << dendl;
-	}
-      }
-    }
-
-    RGWFrontendConfig *config = new RGWFrontendConfig(f);
-    int r = config->init();
-    if (r < 0) {
-      cerr << "ERROR: failed to init config: " << f << std::endl;
-      return EINVAL;
-    }
-
-    configs.push_back(config);
-
-    string framework = config->get_framework();
-    fe_map.insert(pair<string, RGWFrontendConfig*>(framework, config));
-  }
-
   list<RGWFrontend *> fes;
 
-  for (multimap<string, RGWFrontendConfig *>::iterator fiter = fe_map.begin(); fiter != fe_map.end(); ++fiter) {
+  for (multimap<string, RGWFrontendConfig *>::iterator fiter = fe_map.begin();
+       fiter != fe_map.end(); ++fiter) {
     RGWFrontendConfig *config = fiter->second;
     string framework = config->get_framework();
     RGWFrontend *fe;
@@ -1270,27 +411,43 @@ int main(int argc, const char **argv)
       derr << "ERROR: failed initializing frontend" << dendl;
       return -r;
     }
-    fe->run();
+    r = fe->run();
+    if (r < 0) {
+      derr << "ERROR: failed run" << dendl;
+      return -r;
+    }
 
     fes.push_back(fe);
   }
 
+  // add a watcher to respond to realm configuration changes
+  RGWPeriodPusher pusher(store);
+  RGWFrontendPauser pauser(fes, &pusher);
+  RGWRealmReloader reloader(store, &pauser);
+
+  RGWRealmWatcher realm_watcher(g_ceph_context, store->realm);
+  realm_watcher.add_watcher(RGWRealmNotify::Reload, reloader);
+  realm_watcher.add_watcher(RGWRealmNotify::ZonesNeedPeriod, pusher);
+
   wait_shutdown();
 
   derr << "shutting down" << dendl;
 
-  for (list<RGWFrontend *>::iterator liter = fes.begin(); liter != fes.end(); ++liter) {
+  for (list<RGWFrontend *>::iterator liter = fes.begin(); liter != fes.end();
+       ++liter) {
     RGWFrontend *fe = *liter;
     fe->stop();
   }
 
-  for (list<RGWFrontend *>::iterator liter = fes.begin(); liter != fes.end(); ++liter) {
+  for (list<RGWFrontend *>::iterator liter = fes.begin(); liter != fes.end();
+       ++liter) {
     RGWFrontend *fe = *liter;
     fe->join();
     delete fe;
   }
 
-  for (list<RGWFrontendConfig *>::iterator liter = configs.begin(); liter != configs.end(); ++liter) {
+  for (list<RGWFrontendConfig *>::iterator liter = configs.begin();
+       liter != configs.end(); ++liter) {
     RGWFrontendConfig *fec = *liter;
     delete fec;
   }
@@ -1318,10 +475,8 @@ int main(int argc, const char **argv)
   rgw_perf_stop(g_ceph_context);
 
   dout(1) << "final shutdown" << dendl;
-  g_ceph_context->put();
 
   signal_fd_finalize();
 
   return 0;
 }
-
diff --git a/src/rgw/rgw_meta_sync_status.h b/src/rgw/rgw_meta_sync_status.h
new file mode 100644
index 0000000..e913e8f
--- /dev/null
+++ b/src/rgw/rgw_meta_sync_status.h
@@ -0,0 +1,113 @@
+#ifndef RGW_META_SYNC_STATUS_H
+#define RGW_META_SYNC_STATUS_H
+
+#include <string>
+
+#include "common/ceph_time.h"
+
+struct rgw_meta_sync_info {
+  enum SyncState {
+    StateInit = 0,
+    StateBuildingFullSyncMaps = 1,
+    StateSync = 2,
+  };
+
+  uint16_t state;
+  uint32_t num_shards;
+  std::string period; //< period id of current metadata log
+  epoch_t realm_epoch = 0; //< realm epoch of period
+
+  void encode(bufferlist& bl) const {
+    ENCODE_START(2, 1, bl);
+    ::encode(state, bl);
+    ::encode(num_shards, bl);
+    ::encode(period, bl);
+    ::encode(realm_epoch, bl);
+    ENCODE_FINISH(bl);
+  }
+
+  void decode(bufferlist::iterator& bl) {
+    DECODE_START(1, bl);
+    ::decode(state, bl);
+    ::decode(num_shards, bl);
+    if (struct_v >= 2) {
+      ::decode(period, bl);
+      ::decode(realm_epoch, bl);
+    }
+    DECODE_FINISH(bl);
+  }
+
+  void decode_json(JSONObj *obj);
+  void dump(Formatter *f) const;
+
+  rgw_meta_sync_info() : state((int)StateInit), num_shards(0) {}
+};
+WRITE_CLASS_ENCODER(rgw_meta_sync_info)
+
+struct rgw_meta_sync_marker {
+  enum SyncState {
+    FullSync = 0,
+    IncrementalSync = 1,
+  };
+  uint16_t state;
+  string marker;
+  string next_step_marker;
+  uint64_t total_entries;
+  uint64_t pos;
+  real_time timestamp;
+
+  rgw_meta_sync_marker() : state(FullSync), total_entries(0), pos(0) {}
+
+  void encode(bufferlist& bl) const {
+    ENCODE_START(1, 1, bl);
+    ::encode(state, bl);
+    ::encode(marker, bl);
+    ::encode(next_step_marker, bl);
+    ::encode(total_entries, bl);
+    ::encode(pos, bl);
+    ::encode(timestamp, bl);
+    ENCODE_FINISH(bl);
+  }
+
+  void decode(bufferlist::iterator& bl) {
+    DECODE_START(1, bl);
+    ::decode(state, bl);
+    ::decode(marker, bl);
+    ::decode(next_step_marker, bl);
+    ::decode(total_entries, bl);
+    ::decode(pos, bl);
+    ::decode(timestamp, bl);
+    DECODE_FINISH(bl);
+  }
+
+  void decode_json(JSONObj *obj);
+  void dump(Formatter *f) const;
+};
+WRITE_CLASS_ENCODER(rgw_meta_sync_marker)
+
+struct rgw_meta_sync_status {
+  rgw_meta_sync_info sync_info;
+  map<uint32_t, rgw_meta_sync_marker> sync_markers;
+
+  rgw_meta_sync_status() {}
+
+  void encode(bufferlist& bl) const {
+    ENCODE_START(1, 1, bl);
+    ::encode(sync_info, bl);
+    ::encode(sync_markers, bl);
+    ENCODE_FINISH(bl);
+  }
+
+  void decode(bufferlist::iterator& bl) {
+     DECODE_START(1, bl);
+    ::decode(sync_info, bl);
+    ::decode(sync_markers, bl);
+     DECODE_FINISH(bl);
+  }
+
+  void dump(Formatter *f) const;
+  void decode_json(JSONObj *obj);
+};
+WRITE_CLASS_ENCODER(rgw_meta_sync_status)
+
+#endif
diff --git a/src/rgw/rgw_metadata.cc b/src/rgw/rgw_metadata.cc
index 783cc61..3160ce0 100644
--- a/src/rgw/rgw_metadata.cc
+++ b/src/rgw/rgw_metadata.cc
@@ -1,81 +1,96 @@
 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
 // vim: ts=8 sw=2 smarttab
 
+#include <boost/intrusive_ptr.hpp>
 #include "common/ceph_json.h"
 #include "rgw_metadata.h"
+#include "rgw_coroutine.h"
 #include "cls/version/cls_version_types.h"
 
 #include "rgw_rados.h"
 #include "rgw_tools.h"
 
+#include "rgw_cr_rados.h"
+#include "rgw_boost_asio_yield.h"
+
 #define dout_subsys ceph_subsys_rgw
 
-struct LogStatusDump {
-  RGWMDLogStatus status;
-
-  explicit LogStatusDump(RGWMDLogStatus _status) : status(_status) {}
-  void dump(Formatter *f) const {
-    string s;
-    switch (status) {
-      case MDLOG_STATUS_WRITE:
-        s = "write";
-        break;
-      case MDLOG_STATUS_SETATTRS:
-        s = "set_attrs";
-        break;
-      case MDLOG_STATUS_REMOVE:
-        s = "remove";
-        break;
-      case MDLOG_STATUS_COMPLETE:
-        s = "complete";
-        break;
-      case MDLOG_STATUS_ABORT:
-        s = "abort";
-        break;
-      default:
-        s = "unknown";
-        break;
-    }
-    encode_json("status", s, f);
+void LogStatusDump::dump(Formatter *f) const {
+  string s;
+  switch (status) {
+    case MDLOG_STATUS_WRITE:
+      s = "write";
+      break;
+    case MDLOG_STATUS_SETATTRS:
+      s = "set_attrs";
+      break;
+    case MDLOG_STATUS_REMOVE:
+      s = "remove";
+      break;
+    case MDLOG_STATUS_COMPLETE:
+      s = "complete";
+      break;
+    case MDLOG_STATUS_ABORT:
+      s = "abort";
+      break;
+    default:
+      s = "unknown";
+      break;
   }
-};
+  encode_json("status", s, f);
+}
 
-struct RGWMetadataLogData {
-  obj_version read_version;
-  obj_version write_version;
-  RGWMDLogStatus status;
-  
-  RGWMetadataLogData() : status(MDLOG_STATUS_UNKNOWN) {}
+void RGWMetadataLogData::encode(bufferlist& bl) const {
+  ENCODE_START(1, 1, bl);
+  ::encode(read_version, bl);
+  ::encode(write_version, bl);
+  uint32_t s = (uint32_t)status;
+  ::encode(s, bl);
+  ENCODE_FINISH(bl);
+}
 
-  void encode(bufferlist& bl) const {
-    ENCODE_START(1, 1, bl);
-    ::encode(read_version, bl);
-    ::encode(write_version, bl);
-    uint32_t s = (uint32_t)status;
-    ::encode(s, bl);
-    ENCODE_FINISH(bl);
-  }
+void RGWMetadataLogData::decode(bufferlist::iterator& bl) {
+   DECODE_START(1, bl);
+   ::decode(read_version, bl);
+   ::decode(write_version, bl);
+   uint32_t s;
+   ::decode(s, bl);
+   status = (RGWMDLogStatus)s;
+   DECODE_FINISH(bl);
+}
 
-  void decode(bufferlist::iterator& bl) {
-     DECODE_START(1, bl);
-     ::decode(read_version, bl);
-     ::decode(write_version, bl);
-     uint32_t s;
-     ::decode(s, bl);
-     status = (RGWMDLogStatus)s;
-     DECODE_FINISH(bl);
-  }
+void RGWMetadataLogData::dump(Formatter *f) const {
+  encode_json("read_version", read_version, f);
+  encode_json("write_version", write_version, f);
+  encode_json("status", LogStatusDump(status), f);
+}
 
-  void dump(Formatter *f) const {
-    encode_json("read_version", read_version, f);
-    encode_json("write_version", write_version, f);
-    encode_json("status", LogStatusDump(status), f);
+void decode_json_obj(RGWMDLogStatus& status, JSONObj *obj) {
+  string s;
+  JSONDecoder::decode_json("status", s, obj);
+  if (s == "complete") {
+    status = MDLOG_STATUS_COMPLETE;
+  } else if (s == "write") {
+    status = MDLOG_STATUS_WRITE;
+  } else if (s == "remove") {
+    status = MDLOG_STATUS_REMOVE;
+  } else if (s == "set_attrs") {
+    status = MDLOG_STATUS_SETATTRS;
+  } else if (s == "abort") {
+    status = MDLOG_STATUS_ABORT;
+  } else {
+    status = MDLOG_STATUS_UNKNOWN;
   }
-};
-WRITE_CLASS_ENCODER(RGWMetadataLogData)
+}
 
+void RGWMetadataLogData::decode_json(JSONObj *obj) {
+  JSONDecoder::decode_json("read_version", read_version, obj);
+  JSONDecoder::decode_json("write_version", write_version, obj);
+  JSONDecoder::decode_json("status", status, obj);
+}
 
-int RGWMetadataLog::add_entry(RGWRados *store, RGWMetadataHandler *handler, const string& section, const string& key, bufferlist& bl) {
+
+int RGWMetadataLog::add_entry(RGWMetadataHandler *handler, const string& section, const string& key, bufferlist& bl) {
   if (!store->need_to_log_metadata())
     return 0;
 
@@ -84,12 +99,23 @@ int RGWMetadataLog::add_entry(RGWRados *store, RGWMetadataHandler *handler, cons
   string hash_key;
   handler->get_hash_key(section, key, hash_key);
 
-  store->shard_name(prefix, cct->_conf->rgw_md_log_max_shards, hash_key, oid);
-  utime_t now = ceph_clock_now(cct);
+  int shard_id;
+  store->shard_name(prefix, cct->_conf->rgw_md_log_max_shards, hash_key, oid, &shard_id);
+  mark_modified(shard_id);
+  real_time now = real_clock::now();
   return store->time_log_add(oid, now, section, key, bl);
 }
 
-void RGWMetadataLog::init_list_entries(int shard_id, utime_t& from_time, utime_t& end_time, 
+int RGWMetadataLog::store_entries_in_shard(list<cls_log_entry>& entries, int shard_id, librados::AioCompletion *completion)
+{
+  string oid;
+
+  mark_modified(shard_id);
+  store->shard_name(prefix, shard_id, oid);
+  return store->time_log_add(oid, entries, completion, false);
+}
+
+void RGWMetadataLog::init_list_entries(int shard_id, const real_time& from_time, const real_time& end_time, 
                                        string& marker, void **handle)
 {
   LogListCtx *ctx = new LogListCtx();
@@ -145,12 +171,79 @@ int RGWMetadataLog::get_info(int shard_id, RGWMetadataLogInfo *info)
     return ret;
 
   info->marker = header.max_marker;
-  info->last_update = header.max_time;
+  info->last_update = header.max_time.to_real_time();
+
+  return 0;
+}
+
+static void _mdlog_info_completion(librados::completion_t cb, void *arg);
+
+class RGWMetadataLogInfoCompletion : public RefCountedObject {
+  RGWMetadataLogInfo *pinfo;
+  RGWCompletionManager *completion_manager;
+  void *user_info;
+  int *pret;
+  cls_log_header header;
+  librados::IoCtx io_ctx;
+  librados::AioCompletion *completion;
+
+public:
+  RGWMetadataLogInfoCompletion(RGWMetadataLogInfo *_pinfo, RGWCompletionManager *_cm, void *_uinfo, int *_pret) :
+                                               pinfo(_pinfo), completion_manager(_cm), user_info(_uinfo), pret(_pret) {
+    completion = librados::Rados::aio_create_completion((void *)this, _mdlog_info_completion, NULL);
+  }
+
+  ~RGWMetadataLogInfoCompletion() {
+    completion->release();
+  }
+
+  void finish(librados::completion_t cb) {
+    *pret = completion->get_return_value();
+    if (*pret >= 0) {
+      pinfo->marker = header.max_marker;
+      pinfo->last_update = header.max_time.to_real_time();
+    }
+    completion_manager->complete(NULL, user_info);
+    put();
+  }
+
+  librados::IoCtx& get_io_ctx() { return io_ctx; }
+
+  cls_log_header *get_header() {
+    return &header;
+  }
+
+  librados::AioCompletion *get_completion() {
+    return completion;
+  }
+};
+
+static void _mdlog_info_completion(librados::completion_t cb, void *arg)
+{
+  RGWMetadataLogInfoCompletion *infoc = (RGWMetadataLogInfoCompletion *)arg;
+  infoc->finish(cb);
+}
+
+int RGWMetadataLog::get_info_async(int shard_id, RGWMetadataLogInfo *info, RGWCompletionManager *completion_manager, void *user_info, int *pret)
+{
+  string oid;
+  get_shard_oid(shard_id, oid);
+
+  RGWMetadataLogInfoCompletion *req_completion = new RGWMetadataLogInfoCompletion(info, completion_manager, user_info, pret);
+
+  req_completion->get();
+
+  int ret = store->time_log_info_async(req_completion->get_io_ctx(), oid, req_completion->get_header(), req_completion->get_completion());
+  if (ret < 0) {
+    return ret;
+  }
+
+  req_completion->put();
 
   return 0;
 }
 
-int RGWMetadataLog::trim(int shard_id, const utime_t& from_time, const utime_t& end_time,
+int RGWMetadataLog::trim(int shard_id, const real_time& from_time, const real_time& end_time,
                          const string& start_marker, const string& end_marker)
 {
   string oid;
@@ -166,18 +259,38 @@ int RGWMetadataLog::trim(int shard_id, const utime_t& from_time, const utime_t&
   return ret;
 }
   
-int RGWMetadataLog::lock_exclusive(int shard_id, utime_t& duration, string& zone_id, string& owner_id) {
+int RGWMetadataLog::lock_exclusive(int shard_id, timespan duration, string& zone_id, string& owner_id) {
   string oid;
   get_shard_oid(shard_id, oid);
 
-  return store->lock_exclusive(store->zone.log_pool, oid, duration, zone_id, owner_id);
+  return store->lock_exclusive(store->get_zone_params().log_pool, oid, duration, zone_id, owner_id);
 }
 
 int RGWMetadataLog::unlock(int shard_id, string& zone_id, string& owner_id) {
   string oid;
   get_shard_oid(shard_id, oid);
 
-  return store->unlock(store->zone.log_pool, oid, zone_id, owner_id);
+  return store->unlock(store->get_zone_params().log_pool, oid, zone_id, owner_id);
+}
+
+void RGWMetadataLog::mark_modified(int shard_id)
+{
+  lock.get_read();
+  if (modified_shards.find(shard_id) != modified_shards.end()) {
+    lock.unlock();
+    return;
+  }
+  lock.unlock();
+
+  RWLock::WLocker wl(lock);
+  modified_shards.insert(shard_id);
+}
+
+void RGWMetadataLog::read_clear_modified(set<int> &modified)
+{
+  RWLock::WLocker wl(lock);
+  modified.swap(modified_shards);
+  modified_shards.clear();
 }
 
 obj_version& RGWMetadataObject::get_version()
@@ -198,7 +311,7 @@ public:
 
   virtual int get(RGWRados *store, string& entry, RGWMetadataObject **obj) { return -ENOTSUP; }
   virtual int put(RGWRados *store, string& entry, RGWObjVersionTracker& objv_tracker,
-                  time_t mtime, JSONObj *obj, sync_type_t sync_type) { return -ENOTSUP; }
+                  real_time mtime, JSONObj *obj, sync_type_t sync_type) { return -ENOTSUP; }
 
   virtual void get_pool_and_oid(RGWRados *store, const string& key, rgw_bucket& bucket, string& oid) {}
 
@@ -232,9 +345,9 @@ public:
 
 static RGWMetadataTopHandler md_top_handler;
 
-RGWMetadataManager::RGWMetadataManager(CephContext *_cct, RGWRados *_store) : cct(_cct), store(_store)
+RGWMetadataManager::RGWMetadataManager(CephContext *_cct, RGWRados *_store)
+  : cct(_cct), store(_store)
 {
-  md_log = new RGWMetadataLog(_cct, _store);
 }
 
 RGWMetadataManager::~RGWMetadataManager()
@@ -246,7 +359,140 @@ RGWMetadataManager::~RGWMetadataManager()
   }
 
   handlers.clear();
-  delete md_log;
+}
+
+namespace {
+
+class FindAnyShardCR : public RGWCoroutine {
+  RGWRados *const store;
+  const RGWMetadataLog& mdlog;
+  const int num_shards;
+  int ret = 0;
+ public:
+  FindAnyShardCR(RGWRados *store, const RGWMetadataLog& mdlog, int num_shards)
+    : RGWCoroutine(store->ctx()), store(store), mdlog(mdlog),
+      num_shards(num_shards) {}
+
+  int operate() {
+    reenter(this) {
+      // send stat requests for each shard in parallel
+      yield {
+        auto async_rados = store->get_async_rados();
+        auto& pool = store->get_zone_params().log_pool;
+        auto oid = std::string{};
+
+        for (int i = 0; i < num_shards; i++) {
+          mdlog.get_shard_oid(i, oid);
+          auto obj = rgw_obj{pool, oid};
+          spawn(new RGWStatObjCR(async_rados, store, obj), true);
+        }
+      }
+      drain_all();
+      // if any shards were found, return success
+      while (collect_next(&ret)) {
+        if (ret == 0) {
+          // TODO: cancel instead of waiting for the rest
+          return set_cr_done();
+        }
+        ret = 0; // collect_next() won't modify &ret unless it's a failure
+      }
+      // no shards found
+      set_retcode(-ENOENT);
+      return set_cr_error(-ENOENT);
+    }
+    return 0;
+  }
+};
+
+// return true if any log shards exist for the given period
+int find_shards_for_period(RGWRados *store, const std::string& period_id)
+{
+  auto cct = store->ctx();
+  RGWMetadataLog mdlog(cct, store, period_id);
+  auto num_shards = cct->_conf->rgw_md_log_max_shards;
+
+  using FindAnyShardCRRef = boost::intrusive_ptr<FindAnyShardCR>;
+  auto cr = FindAnyShardCRRef{new FindAnyShardCR(store, mdlog, num_shards)};
+
+  RGWCoroutinesManager mgr(cct, nullptr);
+  int r = mgr.run(cr.get());
+  if (r < 0) {
+    return r;
+  }
+  return cr->get_ret_status();
+}
+
+RGWPeriodHistory::Cursor find_oldest_log_period(RGWRados *store)
+{
+  // search backwards through the period history for the first period with no
+  // log shard objects, and return its successor (some shards may be missing
+  // if they contain no metadata yet, so we need to check all shards)
+  auto cursor = store->period_history->get_current();
+  auto oldest_log = cursor;
+
+  while (cursor) {
+    // search for an existing log shard object for this period
+    int r = find_shards_for_period(store, cursor.get_period().get_id());
+    if (r == -ENOENT) {
+      ldout(store->ctx(), 10) << "find_oldest_log_period found no log shards "
+          "for period " << cursor.get_period().get_id() << "; returning "
+          "period " << oldest_log.get_period().get_id() << dendl;
+      return oldest_log;
+    }
+    if (r < 0) {
+      return RGWPeriodHistory::Cursor{r};
+    }
+    oldest_log = cursor;
+
+    // advance to the period's predecessor
+    if (!cursor.has_prev()) {
+      auto& predecessor = cursor.get_period().get_predecessor();
+      if (predecessor.empty()) {
+        // this is the first period, so our logs must start here
+        ldout(store->ctx(), 10) << "find_oldest_log_period returning first "
+            "period " << cursor.get_period().get_id() << dendl;
+        return cursor;
+      }
+      // pull the predecessor and add it to our history
+      RGWPeriod period;
+      int r = store->period_puller->pull(predecessor, period);
+      if (r < 0) {
+        return RGWPeriodHistory::Cursor{r};
+      }
+      auto prev = store->period_history->insert(std::move(period));
+      if (!prev) {
+        return prev;
+      }
+      ldout(store->ctx(), 10) << "find_oldest_log_period advancing to "
+          "predecessor period " << predecessor << dendl;
+      assert(cursor.has_prev());
+    }
+    cursor.prev();
+  }
+  ldout(store->ctx(), 10) << "find_oldest_log_period returning empty cursor" << dendl;
+  return cursor;
+}
+
+} // anonymous namespace
+
+int RGWMetadataManager::init(const std::string& current_period)
+{
+  if (store->is_meta_master()) {
+    // find our oldest log so we can tell other zones where to start their sync
+    oldest_log_period = find_oldest_log_period(store);
+  }
+  // open a log for the current period
+  current_log = get_log(current_period);
+  return 0;
+}
+
+RGWMetadataLog* RGWMetadataManager::get_log(const std::string& period)
+{
+  // construct the period's log in place if it doesn't exist
+  auto insert = md_logs.emplace(std::piecewise_construct,
+                                std::forward_as_tuple(period),
+                                std::forward_as_tuple(cct, store, period));
+  return &insert.first->second;
 }
 
 int RGWMetadataManager::register_handler(RGWMetadataHandler *handler)
@@ -261,7 +507,7 @@ int RGWMetadataManager::register_handler(RGWMetadataHandler *handler)
   return 0;
 }
 
-RGWMetadataHandler *RGWMetadataManager::get_handler(const char *type)
+RGWMetadataHandler *RGWMetadataManager::get_handler(const string& type)
 {
   map<string, RGWMetadataHandler *>::iterator iter = handlers.find(type);
   if (iter == handlers.end())
@@ -321,9 +567,10 @@ int RGWMetadataManager::get(string& metadata_key, Formatter *f)
   f->open_object_section("metadata_info");
   encode_json("key", metadata_key, f);
   encode_json("ver", obj->get_version(), f);
-  time_t mtime = obj->get_mtime();
-  if (mtime > 0) {
-    encode_json("mtime", mtime, f);
+  real_time mtime = obj->get_mtime();
+  if (!real_clock::is_zero(mtime)) {
+    utime_t ut(mtime);
+    encode_json("mtime", ut, f);
   }
   encode_json("data", *obj, f);
   f->close_section();
@@ -353,7 +600,7 @@ int RGWMetadataManager::put(string& metadata_key, bufferlist& bl,
 
   obj_version *objv = &objv_tracker.write_version;
 
-  time_t mtime = 0;
+  utime_t mtime;
 
   try {
     JSONDecoder::decode_json("key", metadata_key, &parser);
@@ -368,7 +615,7 @@ int RGWMetadataManager::put(string& metadata_key, bufferlist& bl,
     return -EINVAL;
   }
 
-  ret = handler->put(store, entry, objv_tracker, mtime, jo, sync_type);
+  ret = handler->put(store, entry, objv_tracker, mtime.to_real_time(), jo, sync_type);
   if (existing_version) {
     *existing_version = objv_tracker.read_version;
   }
@@ -400,7 +647,7 @@ int RGWMetadataManager::remove(string& metadata_key)
   return handler->remove(store, entry, objv_tracker);
 }
 
-int RGWMetadataManager::lock_exclusive(string& metadata_key, utime_t duration, string& owner_id) {
+int RGWMetadataManager::lock_exclusive(string& metadata_key, timespan duration, string& owner_id) {
   RGWMetadataHandler *handler;
   string entry;
   string zone_id;
@@ -492,7 +739,7 @@ void RGWMetadataManager::dump_log_entry(cls_log_entry& entry, Formatter *f)
   f->dump_string("id", entry.id);
   f->dump_string("section", entry.section);
   f->dump_string("name", entry.name);
-  entry.timestamp.gmtime(f->dump_stream("timestamp"));
+  entry.timestamp.gmtime_nsec(f->dump_stream("timestamp"));
 
   try {
     RGWMetadataLogData log_data;
@@ -536,7 +783,8 @@ int RGWMetadataManager::pre_modify(RGWMetadataHandler *handler, string& section,
   bufferlist logbl;
   ::encode(log_data, logbl);
 
-  int ret = md_log->add_entry(store, handler, section, key, logbl);
+  assert(current_log); // must have called init()
+  int ret = current_log->add_entry(handler, section, key, logbl);
   if (ret < 0)
     return ret;
 
@@ -554,7 +802,8 @@ int RGWMetadataManager::post_modify(RGWMetadataHandler *handler, const string& s
   bufferlist logbl;
   ::encode(log_data, logbl);
 
-  int r = md_log->add_entry(store, handler, section, key, logbl);
+  assert(current_log); // must have called init()
+  int r = current_log->add_entry(handler, section, key, logbl);
   if (ret < 0)
     return ret;
 
@@ -564,8 +813,58 @@ int RGWMetadataManager::post_modify(RGWMetadataHandler *handler, const string& s
   return 0;
 }
 
+string RGWMetadataManager::heap_oid(RGWMetadataHandler *handler, const string& key, const obj_version& objv)
+{
+  char buf[objv.tag.size() + 32];
+  snprintf(buf, sizeof(buf), "%s:%lld", objv.tag.c_str(), (long long)objv.ver);
+  return string(".meta:") + handler->get_type() + ":" + key + ":" + buf;
+}
+
+int RGWMetadataManager::store_in_heap(RGWMetadataHandler *handler, const string& key, bufferlist& bl,
+                                      RGWObjVersionTracker *objv_tracker, real_time mtime,
+				      map<string, bufferlist> *pattrs)
+{
+  if (!objv_tracker) {
+    return -EINVAL;
+  }
+
+  rgw_bucket heap_pool(store->get_zone_params().metadata_heap);
+
+  RGWObjVersionTracker otracker;
+  otracker.write_version = objv_tracker->write_version;
+  string oid = heap_oid(handler, key, objv_tracker->write_version);
+  int ret = rgw_put_system_obj(store, heap_pool, oid,
+                               bl.c_str(), bl.length(), false,
+                               &otracker, mtime, pattrs);
+  if (ret < 0) {
+    ldout(store->ctx(), 0) << "ERROR: rgw_put_system_obj() oid=" << oid << ") returned ret=" << ret << dendl;
+    return ret;
+  }
+
+  return 0;
+}
+
+int RGWMetadataManager::remove_from_heap(RGWMetadataHandler *handler, const string& key, RGWObjVersionTracker *objv_tracker)
+{
+  if (!objv_tracker) {
+    return -EINVAL;
+  }
+
+  rgw_bucket heap_pool(store->get_zone_params().metadata_heap);
+
+  string oid = heap_oid(handler, key, objv_tracker->write_version);
+  rgw_obj obj(heap_pool, oid);
+  int ret = store->delete_system_obj(obj);
+  if (ret < 0) {
+    ldout(store->ctx(), 0) << "ERROR: store->delete_system_obj()=" << oid << ") returned ret=" << ret << dendl;
+    return ret;
+  }
+
+  return 0;
+}
+
 int RGWMetadataManager::put_entry(RGWMetadataHandler *handler, const string& key, bufferlist& bl, bool exclusive,
-                                  RGWObjVersionTracker *objv_tracker, time_t mtime, map<string, bufferlist> *pattrs)
+                                  RGWObjVersionTracker *objv_tracker, real_time mtime, map<string, bufferlist> *pattrs)
 {
   string section;
   RGWMetadataLogData log_data;
@@ -578,9 +877,22 @@ int RGWMetadataManager::put_entry(RGWMetadataHandler *handler, const string& key
 
   handler->get_pool_and_oid(store, key, bucket, oid);
 
+  ret = store_in_heap(handler, key, bl, objv_tracker, mtime, pattrs);
+  if (ret < 0) {
+    ldout(store->ctx(), 0) << "ERROR: " << __func__ << ": store_in_heap() key=" << key << " returned ret=" << ret << dendl;
+    goto done;
+  }
+
   ret = rgw_put_system_obj(store, bucket, oid,
                            bl.c_str(), bl.length(), exclusive,
                            objv_tracker, mtime, pattrs);
+  if (ret < 0) {
+    int r = remove_from_heap(handler, key, objv_tracker);
+    if (r < 0) {
+      ldout(store->ctx(), 0) << "ERROR: " << __func__ << ": remove_from_heap() key=" << key << " returned ret=" << r << dendl;
+    }
+  }
+done:
   /* cascading ret into post_modify() */
 
   ret = post_modify(handler, section, key, log_data, objv_tracker, ret);
@@ -615,23 +927,15 @@ int RGWMetadataManager::remove_entry(RGWMetadataHandler *handler, string& key, R
   return 0;
 }
 
-int RGWMetadataManager::set_attrs(RGWMetadataHandler *handler, string& key,
-                                  rgw_obj& obj, map<string, bufferlist>& attrs,
-                                  map<string, bufferlist>* rmattrs,
-                                  RGWObjVersionTracker *objv_tracker)
+int RGWMetadataManager::get_log_shard_id(const string& section,
+                                         const string& key, int *shard_id)
 {
-  string section;
-  RGWMetadataLogData log_data;
-  int ret = pre_modify(handler, section, key, log_data, objv_tracker, MDLOG_STATUS_SETATTRS);
-  if (ret < 0)
-    return ret;
-
-  ret = store->set_attrs(NULL, obj, attrs, rmattrs, objv_tracker);
-  /* cascading ret into post_modify() */
-
-  ret = post_modify(handler, section, key, log_data, objv_tracker, ret);
-  if (ret < 0)
-    return ret;
-
+  RGWMetadataHandler *handler = get_handler(section);
+  if (!handler) {
+    return -EINVAL;
+  }
+  string hash_key;
+  handler->get_hash_key(section, key, hash_key);
+  *shard_id = store->key_to_shard_id(hash_key, cct->_conf->rgw_md_log_max_shards);
   return 0;
 }
diff --git a/src/rgw/rgw_metadata.h b/src/rgw/rgw_metadata.h
index bb77e65..7cd51e0 100644
--- a/src/rgw/rgw_metadata.h
+++ b/src/rgw/rgw_metadata.h
@@ -8,8 +8,11 @@
 
 #include "include/types.h"
 #include "rgw_common.h"
+#include "rgw_period_history.h"
 #include "cls/version/cls_version_types.h"
 #include "cls/log/cls_log_types.h"
+#include "common/RWLock.h"
+#include "common/ceph_time.h"
 
 
 class RGWRados;
@@ -31,13 +34,13 @@ enum RGWMDLogStatus {
 class RGWMetadataObject {
 protected:
   obj_version objv;
-  time_t mtime;
+  ceph::real_time mtime;
   
 public:
-  RGWMetadataObject() : mtime(0) {}
+  RGWMetadataObject() {}
   virtual ~RGWMetadataObject() {}
   obj_version& get_version();
-  time_t get_mtime() { return mtime; }
+  real_time get_mtime() { return mtime; }
 
   virtual void dump(Formatter *f) const = 0;
 };
@@ -70,7 +73,7 @@ public:
 
   virtual int get(RGWRados *store, string& entry, RGWMetadataObject **obj) = 0;
   virtual int put(RGWRados *store, string& entry, RGWObjVersionTracker& objv_tracker,
-                  time_t mtime, JSONObj *obj, sync_type_t type) = 0;
+                  real_time mtime, JSONObj *obj, sync_type_t type) = 0;
   virtual int remove(RGWRados *store, string& entry, RGWObjVersionTracker& objv_tracker) = 0;
 
   virtual int list_keys_init(RGWRados *store, void **phandle) = 0;
@@ -90,8 +93,8 @@ protected:
    *
    * @return true if the update should proceed, false otherwise.
    */
-  bool check_versions(const obj_version& ondisk, const time_t& ondisk_time,
-                      const obj_version& incoming, const time_t& incoming_time,
+  bool check_versions(const obj_version& ondisk, const real_time& ondisk_time,
+                      const obj_version& incoming, const real_time& incoming_time,
                       sync_type_t sync_mode) {
     switch (sync_mode) {
     case APPLY_UPDATES:
@@ -129,33 +132,49 @@ protected:
 
 struct RGWMetadataLogInfo {
   string marker;
-  utime_t last_update;
+  real_time last_update;
 
   void dump(Formatter *f) const;
   void decode_json(JSONObj *obj);
 };
 
+class RGWCompletionManager;
+
 class RGWMetadataLog {
   CephContext *cct;
   RGWRados *store;
-  string prefix;
+  const string prefix;
+
+  static std::string make_prefix(const std::string& period) {
+    if (period.empty())
+      return META_LOG_OBJ_PREFIX;
+    return META_LOG_OBJ_PREFIX + period + ".";
+  }
+
+  RWLock lock;
+  set<int> modified_shards;
+
+  void mark_modified(int shard_id);
+public:
+  RGWMetadataLog(CephContext *_cct, RGWRados *_store, const std::string& period)
+    : cct(_cct), store(_store),
+      prefix(make_prefix(period)),
+      lock("RGWMetaLog::lock") {}
 
-  void get_shard_oid(int id, string& oid) {
+  void get_shard_oid(int id, string& oid) const {
     char buf[16];
     snprintf(buf, sizeof(buf), "%d", id);
     oid = prefix + buf;
   }
 
-public:
-  RGWMetadataLog(CephContext *_cct, RGWRados *_store) : cct(_cct), store(_store), prefix(META_LOG_OBJ_PREFIX) {}
-
-  int add_entry(RGWRados *store, RGWMetadataHandler *handler, const string& section, const string& key, bufferlist& bl);
+  int add_entry(RGWMetadataHandler *handler, const string& section, const string& key, bufferlist& bl);
+  int store_entries_in_shard(list<cls_log_entry>& entries, int shard_id, librados::AioCompletion *completion);
 
   struct LogListCtx {
     int cur_shard;
     string marker;
-    utime_t from_time;
-    utime_t end_time;
+    real_time from_time;
+    real_time end_time;
 
     string cur_oid;
 
@@ -164,7 +183,7 @@ public:
     LogListCtx() : cur_shard(0), done(false) {}
   };
 
-  void init_list_entries(int shard_id, utime_t& from_time, utime_t& end_time, string& marker, void **handle);
+  void init_list_entries(int shard_id, const real_time& from_time, const real_time& end_time, string& marker, void **handle);
   void complete_list_entries(void *handle);
   int list_entries(void *handle,
                    int max_entries,
@@ -172,19 +191,49 @@ public:
 		   string *out_marker,
 		   bool *truncated);
 
-  int trim(int shard_id, const utime_t& from_time, const utime_t& end_time, const string& start_marker, const string& end_marker);
+  int trim(int shard_id, const real_time& from_time, const real_time& end_time, const string& start_marker, const string& end_marker);
   int get_info(int shard_id, RGWMetadataLogInfo *info);
-  int lock_exclusive(int shard_id, utime_t& duration, string&zone_id, string& owner_id);
+  int get_info_async(int shard_id, RGWMetadataLogInfo *info, RGWCompletionManager *completion_manager, void *user_info, int *pret);
+  int lock_exclusive(int shard_id, timespan duration, string&zone_id, string& owner_id);
   int unlock(int shard_id, string& zone_id, string& owner_id);
+
+  int update_shards(list<int>& shards);
+
+  void read_clear_modified(set<int> &modified);
+};
+
+struct LogStatusDump {
+  RGWMDLogStatus status;
+
+  explicit LogStatusDump(RGWMDLogStatus _status) : status(_status) {}
+  void dump(Formatter *f) const;
 };
 
-struct RGWMetadataLogData;
+struct RGWMetadataLogData {
+  obj_version read_version;
+  obj_version write_version;
+  RGWMDLogStatus status;
+  
+  RGWMetadataLogData() : status(MDLOG_STATUS_UNKNOWN) {}
+
+  void encode(bufferlist& bl) const;
+  void decode(bufferlist::iterator& bl);
+  void dump(Formatter *f) const;
+  void decode_json(JSONObj *obj);
+};
+WRITE_CLASS_ENCODER(RGWMetadataLogData)
 
 class RGWMetadataManager {
   map<string, RGWMetadataHandler *> handlers;
   CephContext *cct;
   RGWRados *store;
-  RGWMetadataLog *md_log;
+
+  // maintain a separate metadata log for each period
+  std::map<std::string, RGWMetadataLog> md_logs;
+  // use the current period's log for mutating operations
+  RGWMetadataLog* current_log = nullptr;
+  // oldest log's position in the period history
+  RGWPeriodHistory::Cursor oldest_log_period;
 
   void parse_metadata_key(const string& metadata_key, string& type, string& entry);
 
@@ -195,23 +244,31 @@ class RGWMetadataManager {
   int post_modify(RGWMetadataHandler *handler, const string& section, const string& key, RGWMetadataLogData& log_data,
                  RGWObjVersionTracker *objv_tracker, int ret);
 
+  string heap_oid(RGWMetadataHandler *handler, const string& key, const obj_version& objv);
+  int store_in_heap(RGWMetadataHandler *handler, const string& key, bufferlist& bl,
+                    RGWObjVersionTracker *objv_tracker, real_time mtime,
+                    map<string, bufferlist> *pattrs);
+  int remove_from_heap(RGWMetadataHandler *handler, const string& key, RGWObjVersionTracker *objv_tracker);
 public:
   RGWMetadataManager(CephContext *_cct, RGWRados *_store);
   ~RGWMetadataManager();
 
+  int init(const std::string& current_period);
+
+  RGWPeriodHistory::Cursor get_oldest_log_period() const {
+    return oldest_log_period;
+  }
+
+  /// find or create the metadata log for the given period
+  RGWMetadataLog* get_log(const std::string& period);
+
   int register_handler(RGWMetadataHandler *handler);
 
-  RGWMetadataHandler *get_handler(const char *type);
+  RGWMetadataHandler *get_handler(const string& type);
 
   int put_entry(RGWMetadataHandler *handler, const string& key, bufferlist& bl, bool exclusive,
-                RGWObjVersionTracker *objv_tracker, time_t mtime, map<string, bufferlist> *pattrs = NULL);
+                RGWObjVersionTracker *objv_tracker, real_time mtime, map<string, bufferlist> *pattrs = NULL);
   int remove_entry(RGWMetadataHandler *handler, string& key, RGWObjVersionTracker *objv_tracker);
-  int set_attr(RGWMetadataHandler *handler, string& key, rgw_obj& obj, string& attr, bufferlist& bl,
-               RGWObjVersionTracker *objv_tracker);
-  int set_attrs(RGWMetadataHandler *handler, string& key,
-                rgw_obj& obj, map<string, bufferlist>& attrs,
-                map<string, bufferlist>* rmattrs,
-                RGWObjVersionTracker *objv_tracker);
   int get(string& metadata_key, Formatter *f);
   int put(string& metadata_key, bufferlist& bl,
           RGWMetadataHandler::sync_type_t sync_mode,
@@ -225,10 +282,10 @@ public:
   void dump_log_entry(cls_log_entry& entry, Formatter *f);
 
   void get_sections(list<string>& sections);
-  int lock_exclusive(string& metadata_key, utime_t duration, string& owner_id);
+  int lock_exclusive(string& metadata_key, timespan duration, string& owner_id);
   int unlock(string& metadata_key, string& owner_id);
 
-  RGWMetadataLog *get_log() { return md_log; }
+  int get_log_shard_id(const string& section, const string& key, int *shard_id);
 };
 
 #endif
diff --git a/src/rgw/rgw_object_expirer.cc b/src/rgw/rgw_object_expirer.cc
index a53e1a7..f044db7 100644
--- a/src/rgw/rgw_object_expirer.cc
+++ b/src/rgw/rgw_object_expirer.cc
@@ -78,7 +78,7 @@ int main(const int argc, const char **argv)
 
   common_init_finish(g_ceph_context);
 
-  store = RGWStoreManager::get_storage(g_ceph_context, false, false);
+  store = RGWStoreManager::get_storage(g_ceph_context, false, false, false);
   if (!store) {
     std::cerr << "couldn't init storage provider" << std::endl;
     return EIO;
diff --git a/src/rgw/rgw_object_expirer_core.cc b/src/rgw/rgw_object_expirer_core.cc
index 56bb59f..a06e267 100644
--- a/src/rgw/rgw_object_expirer_core.cc
+++ b/src/rgw/rgw_object_expirer_core.cc
@@ -129,7 +129,10 @@ void RGWObjectExpirer::trim_chunk(const string& shard,
 {
   ldout(store->ctx(), 20) << "trying to trim removal hints to  " << to << dendl;
 
-  int ret = store->objexp_hint_trim(shard, from, to);
+  real_time rt_from = from.to_real_time();
+  real_time rt_to = to.to_real_time();
+
+  int ret = store->objexp_hint_trim(shard, rt_from, rt_to);
   if (ret < 0) {
     ldout(store->ctx(), 0) << "ERROR during trim: " << ret << dendl;
   }
@@ -163,8 +166,11 @@ void RGWObjectExpirer::process_single_shard(const string& shard,
     return;
   }
   do {
+    real_time rt_last = last_run.to_real_time();
+    real_time rt_start = round_start.to_real_time();
+
     list<cls_timeindex_entry> entries;
-    ret = store->objexp_hint_list(shard, last_run, round_start,
+    ret = store->objexp_hint_list(shard, rt_last, rt_start,
                                       num_entries, marker, entries,
                                       &out_marker, &truncated);
     if (ret < 0) {
diff --git a/src/rgw/rgw_op.cc b/src/rgw/rgw_op.cc
index 8475f48..2702111 100644
--- a/src/rgw/rgw_op.cc
+++ b/src/rgw/rgw_op.cc
@@ -25,9 +25,12 @@
 #include "rgw_multi_del.h"
 #include "rgw_cors.h"
 #include "rgw_cors_s3.h"
-
+#include "rgw_rest_conn.h"
+#include "rgw_rest_s3.h"
 #include "rgw_client_io.h"
 
+#include "include/assert.h"
+
 #define dout_subsys ceph_subsys_rgw
 
 using namespace std;
@@ -36,6 +39,8 @@ using ceph::crypto::MD5;
 static string mp_ns = RGW_OBJ_NS_MULTIPART;
 static string shadow_ns = RGW_OBJ_NS_SHADOW;
 
+static int forward_request_to_master(struct req_state *s, obj_version *objv, RGWRados *store, bufferlist& in_data, JSONParser *jp);
+
 #define MULTIPART_UPLOAD_ID_PREFIX_LEGACY "2/"
 #define MULTIPART_UPLOAD_ID_PREFIX "2~" // must contain a unique char that may not come up in gen_rand_alpha()
 
@@ -119,57 +124,6 @@ done:
   return r;
 }
 
-static void format_xattr(std::string &xattr)
-{
-  /* If the extended attribute is not valid UTF-8, we encode it using quoted-printable
-   * encoding.
-   */
-  if ((check_utf8(xattr.c_str(), xattr.length()) != 0) ||
-      (check_for_control_characters(xattr.c_str(), xattr.length()) != 0)) {
-    static const char MIME_PREFIX_STR[] = "=?UTF-8?Q?";
-    static const int MIME_PREFIX_LEN = sizeof(MIME_PREFIX_STR) - 1;
-    static const char MIME_SUFFIX_STR[] = "?=";
-    static const int MIME_SUFFIX_LEN = sizeof(MIME_SUFFIX_STR) - 1;
-    int mlen = mime_encode_as_qp(xattr.c_str(), NULL, 0);
-    char *mime = new char[MIME_PREFIX_LEN + mlen + MIME_SUFFIX_LEN + 1];
-    strcpy(mime, MIME_PREFIX_STR);
-    mime_encode_as_qp(xattr.c_str(), mime + MIME_PREFIX_LEN, mlen);
-    strcpy(mime + MIME_PREFIX_LEN + (mlen - 1), MIME_SUFFIX_STR);
-    xattr.assign(mime);
-    delete [] mime;
-  }
-}
-
-/**
- * Get the HTTP request metadata out of the req_state as a
- * map(<attr_name, attr_contents>, where attr_name is RGW_ATTR_PREFIX.HTTP_NAME)
- * s: The request state
- * attrs: will be filled up with attrs mapped as <attr_name, attr_contents>
- *
- */
-static void rgw_get_request_metadata(CephContext *cct,
-                                     struct req_info& info,
-                                     map<string, bufferlist>& attrs,
-                                     const bool allow_empty_attrs = true)
-{
-  map<string, string>::iterator iter;
-  for (iter = info.x_meta_map.begin(); iter != info.x_meta_map.end(); ++iter) {
-    const string &name(iter->first);
-    string &xattr(iter->second);
-
-    if (allow_empty_attrs || !xattr.empty()) {
-      ldout(cct, 10) << "x>> " << name << ":" << xattr << dendl;
-      format_xattr(xattr);
-      string attr_name(RGW_ATTR_PREFIX);
-      attr_name.append(name);
-      map<string, bufferlist>::value_type v(attr_name, bufferlist());
-      std::pair < map<string, bufferlist>::iterator, bool > rval(attrs.insert(v));
-      bufferlist& bl(rval.first->second);
-      bl.append(xattr.c_str(), xattr.size() + 1);
-    }
-  }
-}
-
 static int decode_policy(CephContext *cct, bufferlist& bl, RGWAccessControlPolicy *policy)
 {
   bufferlist::iterator iter = bl.begin();
@@ -181,7 +135,7 @@ static int decode_policy(CephContext *cct, bufferlist& bl, RGWAccessControlPolic
   }
   if (cct->_conf->subsys.should_gather(ceph_subsys_rgw, 15)) {
     RGWAccessControlPolicy_S3 *s3policy = static_cast<RGWAccessControlPolicy_S3 *>(policy);
-    ldout(cct, 15) << "Read AccessControlPolicy";
+    ldout(cct, 15) << __func__ << " Read AccessControlPolicy";
     s3policy->to_xml(*_dout);
     *_dout << dendl;
   }
@@ -322,8 +276,9 @@ static int read_policy(RGWRados *store, struct req_state *s,
     if (ret < 0)
       return ret;
     rgw_user& owner = bucket_policy.get_owner().get_id();
-    if (!s->system_request && owner.compare(s->user.user_id) != 0 &&
-        !bucket_policy.verify_permission(s->user.user_id, s->perm_mask, RGW_PERM_READ))
+    if (!s->system_request && owner.compare(s->user->user_id) != 0 &&
+        !bucket_policy.verify_permission(s->user->user_id, s->perm_mask,
+					RGW_PERM_READ))
       ret = -EACCES;
     else
       ret = -ENOENT;
@@ -341,7 +296,7 @@ static int read_policy(RGWRados *store, struct req_state *s,
  * only_bucket: If true, reads the bucket ACL rather than the object ACL.
  * Returns: 0 on success, -ERR# otherwise.
  */
-static int rgw_build_bucket_policies(RGWRados *store, struct req_state *s)
+int rgw_build_bucket_policies(RGWRados* store, struct req_state* s)
 {
   int ret = 0;
   rgw_obj_key obj;
@@ -350,8 +305,7 @@ static int rgw_build_bucket_policies(RGWRados *store, struct req_state *s)
 
   string bi = s->info.args.get(RGW_SYS_PARAM_PREFIX "bucket-instance");
   if (!bi.empty()) {
-    int shard_id;
-    ret = rgw_bucket_parse_bucket_instance(bi, &s->bucket_instance_id, &shard_id);
+    ret = rgw_bucket_parse_bucket_instance(bi, &s->bucket_instance_id, &s->bucket_instance_shard_id);
     if (ret < 0) {
       return ret;
     }
@@ -369,11 +323,14 @@ static int rgw_build_bucket_policies(RGWRados *store, struct req_state *s)
   if (!s->src_bucket_name.empty()) {
     RGWBucketInfo source_info;
 
-    ret = store->get_bucket_info(obj_ctx,
-        s->src_tenant_name, s->src_bucket_name, source_info, NULL);
+    if (s->bucket_instance_id.empty()) {
+      ret = store->get_bucket_info(obj_ctx, s->src_tenant_name, s->src_bucket_name, source_info, NULL);
+    } else {
+      ret = store->get_bucket_instance_info(obj_ctx, s->bucket_instance_id, source_info, NULL, NULL);
+    }
     if (ret == 0) {
-      string& region = source_info.region;
-      s->local_source = store->region.equals(region);
+      string& zonegroup = source_info.zonegroup;
+      s->local_source = store->get_zonegroup().equals(zonegroup);
     }
   }
 
@@ -399,23 +356,30 @@ static int rgw_build_bucket_policies(RGWRados *store, struct req_state *s)
       rgw_obj_key no_obj;
       ret = read_policy(store, s, s->bucket_info, s->bucket_attrs, s->bucket_acl, s->bucket, no_obj);
     } else {
-      s->bucket_acl->create_default(s->user.user_id, s->user.display_name);
+      s->bucket_acl->create_default(s->user->user_id, s->user->display_name);
       ret = -ERR_NO_SUCH_BUCKET;
     }
 
     s->bucket_owner = s->bucket_acl->get_owner();
 
-    string& region = s->bucket_info.region;
-    map<string, RGWRegion>::iterator dest_region = store->region_map.regions.find(region);
-    if (dest_region != store->region_map.regions.end() && !dest_region->second.endpoints.empty()) {
-      s->region_endpoint = dest_region->second.endpoints.front();
+    RGWZoneGroup zonegroup;
+    int r = store->get_zonegroup(s->bucket_info.zonegroup, zonegroup);
+    if (!r) {
+      if (!zonegroup.endpoints.empty()) {
+	s->zonegroup_endpoint = zonegroup.endpoints.front();
+      }
+      s->zonegroup_name = zonegroup.get_name();
     }
-    if (s->bucket_exists && !store->region.equals(region)) {
-      ldout(s->cct, 0) << "NOTICE: request for data in a different region (" << region << " != " << store->region.name << ")" << dendl;
+    if (r < 0 && ret == 0) {
+      ret = r;
+    }
+
+    if (s->bucket_exists && !store->get_zonegroup().equals(s->bucket_info.zonegroup)) {
+      ldout(s->cct, 0) << "NOTICE: request for data in a different zonegroup (" << s->bucket_info.zonegroup << " != " << store->get_zonegroup().get_id() << ")" << dendl;
       /* we now need to make sure that the operation actually requires copy source, that is
        * it's a copy operation
        */
-      if (store->region.is_master && s->op == OP_DELETE && s->system_request) {
+      if (store->get_zonegroup().is_master && s->op == OP_DELETE && s->system_request) {
         /*If the operation is delete and if this is the master, don't redirect*/
       } else if (!s->local_source ||
           (s->op != OP_PUT && s->op != OP_COPY) ||
@@ -481,20 +445,45 @@ int RGWOp::verify_op_mask()
 {
   uint32_t required_mask = op_mask();
 
-  ldout(s->cct, 20) << "required_mask= " << required_mask << " user.op_mask=" << s->user.op_mask << dendl;
+  ldout(s->cct, 20) << "required_mask= " << required_mask
+		    << " user.op_mask=" << s->user->op_mask << dendl;
 
-  if ((s->user.op_mask & required_mask) != required_mask) {
+  if ((s->user->op_mask & required_mask) != required_mask) {
     return -EPERM;
   }
 
-  if (!s->system_request && (required_mask & RGW_OP_TYPE_MODIFY) && !store->zone.is_master)  {
-    ldout(s->cct, 5) << "NOTICE: modify request to a non-master zone by a non-system user, permission denied"  << dendl;
+  if (!s->system_request && (required_mask & RGW_OP_TYPE_MODIFY) && store->get_zone().is_read_only()) {
+    ldout(s->cct, 5) << "NOTICE: modify request to a read-only zone by a non-system user, permission denied"  << dendl;
     return -EPERM;
   }
 
   return 0;
 }
 
+int RGWOp::do_aws4_auth_completion()
+{
+  int ret;
+
+  if (s->aws4_auth_needs_complete) {
+    /* complete */
+    ret = RGW_Auth_S3::authorize_aws4_auth_complete(store, s);
+    s->aws4_auth_needs_complete = false;
+    if (ret) {
+      return ret;
+    }
+    /* verify signature */
+    if (s->aws4_auth->signature != s->aws4_auth->new_signature) {
+      ret = -ERR_SIGNATURE_NO_MATCH;
+      ldout(s->cct, 20) << "delayed aws4 auth failed" << dendl;
+      return ret;
+    }
+    /* authorization ok */
+    dout(10) << "v4 auth ok" << dendl;
+  }
+
+  return 0;
+}
+
 int RGWOp::init_quota()
 {
   /* no quota enforcement for system requests */
@@ -502,7 +491,7 @@ int RGWOp::init_quota()
     return 0;
 
   /* init quota related stuff */
-  if (!(s->user.op_mask & RGW_OP_TYPE_MODIFY)) {
+  if (!(s->user->op_mask & RGW_OP_TYPE_MODIFY)) {
     return 0;
   }
 
@@ -514,8 +503,8 @@ int RGWOp::init_quota()
   RGWUserInfo owner_info;
   RGWUserInfo *uinfo;
 
-  if (s->user.user_id == s->bucket_owner.get_id()) {
-    uinfo = &s->user;
+  if (s->user->user_id == s->bucket_owner.get_id()) {
+    uinfo = s->user;
   } else {
     int r = rgw_get_user_info_by_uid(store, s->bucket_info.owner, owner_info);
     if (r < 0)
@@ -528,13 +517,13 @@ int RGWOp::init_quota()
   } else if (uinfo->bucket_quota.enabled) {
     bucket_quota = uinfo->bucket_quota;
   } else {
-    bucket_quota = store->region_map.bucket_quota;
+    bucket_quota = store->get_bucket_quota();
   }
 
   if (uinfo->user_quota.enabled) {
     user_quota = uinfo->user_quota;
   } else {
-    user_quota = store->region_map.user_quota;
+    user_quota = store->get_user_quota();
   }
 
   return 0;
@@ -745,11 +734,12 @@ static int iterate_user_manifest_parts(CephContext * const cct,
                                        RGWRados * const store,
                                        const off_t ofs,
                                        const off_t end,
-                                       rgw_bucket& bucket,
+                                       RGWBucketInfo *pbucket_info,
                                        const string& obj_prefix,
                                        RGWAccessControlPolicy * const bucket_policy,
                                        uint64_t * const ptotal_len,
                                        uint64_t * const pobj_size,
+                                       string * const pobj_sum,
                                        int (*cb)(rgw_bucket& bucket,
                                                  const RGWObjEnt& ent,
                                                  RGWAccessControlPolicy * const bucket_policy,
@@ -758,6 +748,7 @@ static int iterate_user_manifest_parts(CephContext * const cct,
                                                  void *param),
                                        void * const cb_param)
 {
+  rgw_bucket& bucket = pbucket_info->bucket;
   uint64_t obj_ofs = 0, len_count = 0;
   bool found_start = false, found_end = false, handled_end = false;
   string delim;
@@ -766,22 +757,21 @@ static int iterate_user_manifest_parts(CephContext * const cct,
 
   utime_t start_time = ceph_clock_now(cct);
 
-  RGWRados::Bucket target(store, bucket);
+  RGWRados::Bucket target(store, *pbucket_info);
   RGWRados::Bucket::List list_op(&target);
 
   list_op.params.prefix = obj_prefix;
   list_op.params.delim = delim;
 
+  MD5 etag_sum;
   do {
 #define MAX_LIST_OBJS 100
     int r = list_op.list_objects(MAX_LIST_OBJS, &objs, NULL, &is_truncated);
-    if (r < 0)
+    if (r < 0) {
       return r;
+    }
 
-    vector<RGWObjEnt>::iterator viter;
-
-    for (viter = objs.begin(); viter != objs.end(); ++viter) {
-      RGWObjEnt& ent = *viter;
+    for (RGWObjEnt& ent : objs) {
       uint64_t cur_total_len = obj_ofs;
       uint64_t start_ofs = 0, end_ofs = ent.size;
 
@@ -791,6 +781,10 @@ static int iterate_user_manifest_parts(CephContext * const cct,
       }
 
       obj_ofs += ent.size;
+      if (pobj_sum) {
+        etag_sum.Update((const byte *)ent.etag.c_str(),
+                        ent.etag.length());
+      }
 
       if (!found_end && obj_ofs > (uint64_t)end) {
 	end_ofs = end - cur_total_len + 1;
@@ -822,6 +816,9 @@ static int iterate_user_manifest_parts(CephContext * const cct,
   if (pobj_size) {
     *pobj_size = obj_ofs;
   }
+  if (pobj_sum) {
+    complete_etag(etag_sum, pobj_sum);
+  }
 
   return 0;
 }
@@ -850,14 +847,11 @@ static int iterate_slo_parts(CephContext *cct,
                              void *cb_param)
 {
   bool found_start = false, found_end = false;
-  string delim;
-  vector<RGWObjEnt> objs;
 
   if (slo_parts.empty()) {
     return 0;
   }
 
-
   utime_t start_time = ceph_clock_now(cct);
 
   map<uint64_t, rgw_slo_part>::iterator iter = slo_parts.upper_bound(ofs);
@@ -939,18 +933,22 @@ int RGWGetObj::handle_user_manifest(const char *prefix)
 
   RGWAccessControlPolicy _bucket_policy(s->cct);
   RGWAccessControlPolicy *bucket_policy;
+  RGWBucketInfo bucket_info;
+  RGWBucketInfo *pbucket_info;
 
   if (bucket_name.compare(s->bucket.name) != 0) {
-    RGWBucketInfo bucket_info;
     map<string, bufferlist> bucket_attrs;
     RGWObjectCtx obj_ctx(store);
-    int r = store->get_bucket_info(obj_ctx, s->user.user_id.tenant, bucket_name,
-                                   bucket_info, NULL, &bucket_attrs);
+    int r = store->get_bucket_info(obj_ctx, s->user->user_id.tenant,
+				  bucket_name, bucket_info, NULL,
+				  &bucket_attrs);
     if (r < 0) {
-      ldout(s->cct, 0) << "could not get bucket info for bucket=" << bucket_name << dendl;
+      ldout(s->cct, 0) << "could not get bucket info for bucket="
+		       << bucket_name << dendl;
       return r;
     }
     bucket = bucket_info.bucket;
+    pbucket_info = &bucket_info;
     rgw_obj_key no_obj;
     bucket_policy = &_bucket_policy;
     r = read_policy(store, s, bucket_info, bucket_attrs, bucket_policy, bucket, no_obj);
@@ -960,13 +958,18 @@ int RGWGetObj::handle_user_manifest(const char *prefix)
     }
   } else {
     bucket = s->bucket;
+    pbucket_info = &s->bucket_info;
     bucket_policy = s->bucket_acl;
   }
 
-  /* dry run to find out total length */
+  /* dry run to find out:
+   * - total length (of the parts we are going to send to client),
+   * - overall DLO's content size,
+   * - md5 sum of overall DLO's content (for etag of Swift API). */
   int r = iterate_user_manifest_parts(s->cct, store, ofs, end,
-        bucket, obj_prefix, bucket_policy, &total_len, &s->obj_size,
-        NULL, NULL);
+        pbucket_info, obj_prefix, bucket_policy,
+        &total_len, &s->obj_size, &lo_etag,
+        nullptr /* cb */, nullptr /* cb arg */);
   if (r < 0) {
     return r;
   }
@@ -978,7 +981,8 @@ int RGWGetObj::handle_user_manifest(const char *prefix)
   }
 
   r = iterate_user_manifest_parts(s->cct, store, ofs, end,
-        bucket, obj_prefix, bucket_policy, NULL, NULL,
+        pbucket_info, obj_prefix, bucket_policy,
+        nullptr, nullptr, nullptr,
         get_obj_user_manifest_iterate_cb, (void *)this);
   if (r < 0) {
     return r;
@@ -1005,13 +1009,15 @@ int RGWGetObj::handle_slo_manifest(bufferlist& bl)
 
   map<uint64_t, rgw_slo_part> slo_parts;
 
+  MD5 etag_sum;
   total_len = 0;
 
-  for (vector<rgw_slo_entry>::iterator iter = slo_info.entries.begin(); iter != slo_info.entries.end(); ++iter) {
-    string& path = iter->path;
-    int pos = path.find('/', 1); /* skip first / */
-    if (pos < 0)
+  for (const auto& entry : slo_info.entries) {
+    const string& path = entry.path;
+    const size_t pos = path.find('/', 1); /* skip first / */
+    if (pos == string::npos) {
       return -EINVAL;
+    }
 
     string bucket_name = path.substr(1, pos - 1);
     string obj_name = path.substr(pos + 1);
@@ -1020,7 +1026,7 @@ int RGWGetObj::handle_slo_manifest(bufferlist& bl)
     RGWAccessControlPolicy *bucket_policy;
 
     if (bucket_name.compare(s->bucket.name) != 0) {
-      map<string, RGWAccessControlPolicy *>::iterator piter = policies.find(bucket_name);
+      const auto& piter = policies.find(bucket_name);
       if (piter != policies.end()) {
         bucket_policy = piter->second;
         bucket = buckets[bucket_name];
@@ -1031,18 +1037,22 @@ int RGWGetObj::handle_slo_manifest(bufferlist& bl)
         RGWBucketInfo bucket_info;
         map<string, bufferlist> bucket_attrs;
         RGWObjectCtx obj_ctx(store);
-        int r = store->get_bucket_info(obj_ctx, s->user.user_id.tenant,
-              bucket_name, bucket_info, NULL, &bucket_attrs);
+        int r = store->get_bucket_info(obj_ctx, s->user->user_id.tenant,
+                                       bucket_name, bucket_info, nullptr,
+                                       &bucket_attrs);
         if (r < 0) {
-          ldout(s->cct, 0) << "could not get bucket info for bucket=" << bucket_name << dendl;
+          ldout(s->cct, 0) << "could not get bucket info for bucket="
+			   << bucket_name << dendl;
           return r;
         }
         bucket = bucket_info.bucket;
         rgw_obj_key no_obj;
         bucket_policy = &_bucket_policy;
-        r = read_policy(store, s, bucket_info, bucket_attrs, bucket_policy, bucket, no_obj);
+        r = read_policy(store, s, bucket_info, bucket_attrs, bucket_policy,
+                        bucket, no_obj);
         if (r < 0) {
-          ldout(s->cct, 0) << "failed to read bucket policy for bucket " << bucket << dendl;
+          ldout(s->cct, 0) << "failed to read bucket policy for bucket "
+                           << bucket << dendl;
           return r;
         }
         buckets[bucket_name] = bucket;
@@ -1057,8 +1067,8 @@ int RGWGetObj::handle_slo_manifest(bufferlist& bl)
     part.bucket_policy = bucket_policy;
     part.bucket = bucket;
     part.obj_name = obj_name;
-    part.size = iter->size_bytes;
-    part.etag = iter->etag;
+    part.size = entry.size_bytes;
+    part.etag = entry.etag;
     ldout(s->cct, 20) << "slo_part: ofs=" << ofs
                       << " bucket=" << part.bucket
                       << " obj=" << part.obj_name
@@ -1066,10 +1076,15 @@ int RGWGetObj::handle_slo_manifest(bufferlist& bl)
                       << " etag=" << part.etag
                       << dendl;
 
+    etag_sum.Update((const byte *)entry.etag.c_str(),
+                    entry.etag.length());
+
     slo_parts[total_len] = part;
     total_len += part.size;
   }
 
+  complete_etag(etag_sum, &lo_etag);
+
   s->obj_size = slo_info.total_size;
   ldout(s->cct, 20) << "s->obj_size=" << s->obj_size << dendl;
 
@@ -1188,6 +1203,9 @@ void RGWGetObj::execute()
 
   read_op.conds.mod_ptr = mod_ptr;
   read_op.conds.unmod_ptr = unmod_ptr;
+  read_op.conds.high_precision_time = s->system_request; /* system request need to use high precision time */
+  read_op.conds.mod_zone_id = mod_zone_id;
+  read_op.conds.mod_pg_ver = mod_pg_ver;
   read_op.conds.if_match = if_match;
   read_op.conds.if_nomatch = if_nomatch;
   read_op.params.attrs = &attrs;
@@ -1233,6 +1251,10 @@ void RGWGetObj::execute()
 
   start = ofs;
 
+  /* STAT ops don't need data, and do no i/o */
+  if (get_type() == RGW_OP_STAT_OBJ)
+    return;
+
   if (!get_data || ofs > end)
     goto done_err;
 
@@ -1286,6 +1308,13 @@ int RGWListBuckets::verify_permission()
   return 0;
 }
 
+int RGWGetUsage::verify_permission()
+{
+  if (!rgw_user_is_authenticated(*s->user))
+    return -EACCES;
+  return 0;
+}
+
 void RGWListBuckets::execute()
 {
   bool done;
@@ -1300,7 +1329,7 @@ void RGWListBuckets::execute()
   }
 
   if (supports_account_metadata()) {
-    op_ret = rgw_get_user_attrs_by_uid(store, s->user.user_id, attrs);
+    op_ret = rgw_get_user_attrs_by_uid(store, s->user->user_id, attrs);
     if (op_ret < 0) {
       goto send_end;
     }
@@ -1315,14 +1344,15 @@ void RGWListBuckets::execute()
       read_count = max_buckets;
     }
 
-    op_ret = rgw_read_user_buckets(store, s->user.user_id, buckets,
-				   marker, end_marker, read_count,
-				   should_get_stats(), 0);
-
+    op_ret = rgw_read_user_buckets(store, s->user->user_id, buckets,
+                                   marker, end_marker, read_count,
+                                   should_get_stats(), &is_truncated,
+                                   get_default_max());
     if (op_ret < 0) {
       /* hmm.. something wrong here.. the user was authenticated, so it
          should exist */
-      ldout(s->cct, 10) << "WARNING: failed on rgw_get_user_buckets uid=" << s->user.user_id << dendl;
+      ldout(s->cct, 10) << "WARNING: failed on rgw_get_user_buckets uid="
+			<< s->user->user_id << dendl;
       break;
     }
     map<string, RGWBucketEnt>& m = buckets.get_buckets();
@@ -1360,6 +1390,66 @@ send_end:
   send_response_end();
 }
 
+void RGWGetUsage::execute()
+{
+  uint64_t start_epoch = 0;
+  uint64_t end_epoch = (uint64_t)-1;
+  op_ret = get_params();
+  if (op_ret < 0)
+    return;
+    
+  if (!start_date.empty()) {
+    op_ret = utime_t::parse_date(start_date, &start_epoch, NULL);
+    if (op_ret < 0) {
+      ldout(store->ctx(), 0) << "ERROR: failed to parse start date" << dendl;
+      return;
+    }
+  }
+    
+  if (!end_date.empty()) {
+    op_ret = utime_t::parse_date(end_date, &end_epoch, NULL);
+    if (op_ret < 0) {
+      ldout(store->ctx(), 0) << "ERROR: failed to parse end date" << dendl;
+      return;
+    }
+  }
+     
+  uint32_t max_entries = 1000;
+
+  bool is_truncated = true;
+
+  RGWUsageIter usage_iter;
+  
+  while (is_truncated) {
+    op_ret = store->read_usage(s->user->user_id, start_epoch, end_epoch, max_entries,
+                                &is_truncated, usage_iter, usage);
+
+    if (op_ret == -ENOENT) {
+      op_ret = 0;
+      is_truncated = false;
+    }
+
+    if (op_ret < 0) {
+      return;
+    }    
+  }
+
+  op_ret = rgw_user_sync_all_stats(store, s->user->user_id);
+  if (op_ret < 0) {
+    ldout(store->ctx(), 0) << "ERROR: failed to sync user stats: " << dendl;
+    return ;
+  }
+  
+  string user_str = s->user->user_id.to_str();
+  op_ret = store->cls_user_get_header(user_str, &header);
+  if (op_ret < 0) {
+    ldout(store->ctx(), 0) << "ERROR: can't read user header: "  << dendl;
+    return ;
+  }
+  
+  return;
+}
+
 int RGWStatAccount::verify_permission()
 {
   return 0;
@@ -1369,17 +1459,19 @@ void RGWStatAccount::execute()
 {
   string marker;
   bool done;
+  bool is_truncated;
   uint64_t max_buckets = s->cct->_conf->rgw_list_buckets_max_chunk;
 
   do {
     RGWUserBuckets buckets;
 
-    op_ret = rgw_read_user_buckets(store, s->user.user_id, buckets,
-				   marker, string(), max_buckets, false);
+    op_ret = rgw_read_user_buckets(store, s->user->user_id, buckets, marker,
+				   string(), max_buckets, true, &is_truncated);
     if (op_ret < 0) {
       /* hmm.. something wrong here.. the user was authenticated, so it
          should exist */
-      ldout(s->cct, 10) << "WARNING: failed on rgw_get_user_buckets uid=" << s->user.user_id << dendl;
+      ldout(s->cct, 10) << "WARNING: failed on rgw_get_user_buckets uid="
+			<< s->user->user_id << dendl;
       break;
     } else {
       map<string, RGWBucketEnt>& m = buckets.get_buckets();
@@ -1401,7 +1493,7 @@ void RGWStatAccount::execute()
 
 int RGWGetBucketVersioning::verify_permission()
 {
-  if (s->user.user_id.compare(s->bucket_owner.get_id()) != 0)
+  if (s->user->user_id.compare(s->bucket_owner.get_id()) != 0)
     return -EACCES;
 
   return 0;
@@ -1420,7 +1512,7 @@ void RGWGetBucketVersioning::execute()
 
 int RGWSetBucketVersioning::verify_permission()
 {
-  if (s->user.user_id.compare(s->bucket_owner.get_id()) != 0)
+  if (s->user->user_id.compare(s->bucket_owner.get_id()) != 0)
     return -EACCES;
 
   return 0;
@@ -1433,7 +1525,18 @@ void RGWSetBucketVersioning::pre_exec()
 
 void RGWSetBucketVersioning::execute()
 {
+  if (!store->is_meta_master()) {
+    bufferlist in_data;
+    JSONParser jp;
+    op_ret = forward_request_to_master(s, NULL, store, in_data, &jp);
+    if (op_ret < 0) {
+      ldout(s->cct, 20) << __func__ << "forward_request_to_master returned ret=" << op_ret << dendl;
+    }
+    return;
+  }
+  
   op_ret = get_params();
+
   if (op_ret < 0)
     return;
 
@@ -1444,7 +1547,7 @@ void RGWSetBucketVersioning::execute()
     s->bucket_info.flags |= (BUCKET_VERSIONED | BUCKET_VERSIONS_SUSPENDED);
   }
 
-  op_ret = store->put_bucket_instance_info(s->bucket_info, false, 0,
+  op_ret = store->put_bucket_instance_info(s->bucket_info, false, real_time(),
 					  &s->bucket_attrs);
   if (op_ret < 0) {
     ldout(s->cct, 0) << "NOTICE: put_bucket_info on bucket=" << s->bucket.name
@@ -1455,7 +1558,7 @@ void RGWSetBucketVersioning::execute()
 
 int RGWGetBucketWebsite::verify_permission()
 {
-  if (s->user.user_id.compare(s->bucket_owner.get_id()) != 0)
+  if (s->user->user_id.compare(s->bucket_owner.get_id()) != 0)
     return -EACCES;
 
   return 0;
@@ -1475,7 +1578,7 @@ void RGWGetBucketWebsite::execute()
 
 int RGWSetBucketWebsite::verify_permission()
 {
-  if (s->user.user_id.compare(s->bucket_owner.get_id()) != 0)
+  if (s->user->user_id.compare(s->bucket_owner.get_id()) != 0)
     return -EACCES;
 
   return 0;
@@ -1496,7 +1599,7 @@ void RGWSetBucketWebsite::execute()
   s->bucket_info.has_website = true;
   s->bucket_info.website_conf = website_conf;
 
-  op_ret = store->put_bucket_instance_info(s->bucket_info, false, 0, &s->bucket_attrs);
+  op_ret = store->put_bucket_instance_info(s->bucket_info, false, real_time(), &s->bucket_attrs);
   if (op_ret < 0) {
     ldout(s->cct, 0) << "NOTICE: put_bucket_info on bucket=" << s->bucket.name << " returned err=" << op_ret << dendl;
     return;
@@ -1505,7 +1608,7 @@ void RGWSetBucketWebsite::execute()
 
 int RGWDeleteBucketWebsite::verify_permission()
 {
-  if (s->user.user_id.compare(s->bucket_owner.get_id()) != 0)
+  if (s->user->user_id.compare(s->bucket_owner.get_id()) != 0)
     return -EACCES;
 
   return 0;
@@ -1521,7 +1624,7 @@ void RGWDeleteBucketWebsite::execute()
   s->bucket_info.has_website = false;
   s->bucket_info.website_conf = RGWBucketWebsiteConf();
 
-  op_ret = store->put_bucket_instance_info(s->bucket_info, false, 0, &s->bucket_attrs);
+  op_ret = store->put_bucket_instance_info(s->bucket_info, false, real_time(), &s->bucket_attrs);
   if (op_ret < 0) {
     ldout(s->cct, 0) << "NOTICE: put_bucket_info on bucket=" << s->bucket.name << " returned err=" << op_ret << dendl;
     return;
@@ -1543,6 +1646,11 @@ void RGWStatBucket::pre_exec()
 
 void RGWStatBucket::execute()
 {
+  if (!s->bucket_exists) {
+    op_ret = -ERR_NO_SUCH_BUCKET;
+    return;
+  }
+
   RGWUserBuckets buckets;
   bucket.bucket = s->bucket;
   buckets.add(bucket);
@@ -1595,6 +1703,11 @@ void RGWListBucket::pre_exec()
 
 void RGWListBucket::execute()
 {
+  if (!s->bucket_exists) {
+    op_ret = -ERR_NO_SUCH_BUCKET;
+    return;
+  }
+
   op_ret = get_params();
   if (op_ret < 0)
     return;
@@ -1609,7 +1722,10 @@ void RGWListBucket::execute()
     }
   }
 
-  RGWRados::Bucket target(store, s->bucket);
+  RGWRados::Bucket target(store, s->bucket_info);
+  if (shard_id >= 0) {
+    target.set_shard_id(shard_id);
+  }
   RGWRados::Bucket::List list_op(&target);
 
   list_op.params.prefix = prefix;
@@ -1626,7 +1742,7 @@ void RGWListBucket::execute()
 
 int RGWGetBucketLogging::verify_permission()
 {
-  if (s->user.user_id.compare(s->bucket_owner.get_id()) != 0)
+  if (s->user->user_id.compare(s->bucket_owner.get_id()) != 0)
     return -EACCES;
 
   return 0;
@@ -1634,7 +1750,7 @@ int RGWGetBucketLogging::verify_permission()
 
 int RGWGetBucketLocation::verify_permission()
 {
-  if (s->user.user_id.compare(s->bucket_owner.get_id()) != 0)
+  if (s->user->user_id.compare(s->bucket_owner.get_id()) != 0)
     return -EACCES;
 
   return 0;
@@ -1642,25 +1758,29 @@ int RGWGetBucketLocation::verify_permission()
 
 int RGWCreateBucket::verify_permission()
 {
-  if (!rgw_user_is_authenticated(s->user))
+  if (!rgw_user_is_authenticated(*(s->user)))
     return -EACCES;
 
-  if (s->user.user_id.tenant != s->bucket_tenant) {
-    ldout(s->cct, 10) << "user cannot create a bucket in a different tenant (user_id.tenant=" << s->user.user_id.tenant << " requested=" << s->bucket_tenant << ")" << dendl;
+  if (s->user->user_id.tenant != s->bucket_tenant) {
+    ldout(s->cct, 10)
+      << "user cannot create a bucket in a different tenant (user_id.tenant="
+      << s->user->user_id.tenant << " requested=" << s->bucket_tenant << ")"
+      << dendl;
     return -EACCES;
   }
 
-  if (s->user.max_buckets) {
+  if (s->user->max_buckets) {
     RGWUserBuckets buckets;
     string marker;
-    op_ret = rgw_read_user_buckets(store, s->user.user_id, buckets,
-				   marker, string(), s->user.max_buckets,
-				   false);
+    bool is_truncated;
+    op_ret = rgw_read_user_buckets(store, s->user->user_id, buckets,
+				   marker, string(), s->user->max_buckets,
+				   false, &is_truncated);
     if (op_ret < 0)
       return op_ret;
 
     map<string, RGWBucketEnt>& m = buckets.get_buckets();
-    if (m.size() >= s->user.max_buckets) {
+    if (m.size() >= s->user->max_buckets) {
       return -ERR_TOO_MANY_BUCKETS;
     }
   }
@@ -1668,23 +1788,27 @@ int RGWCreateBucket::verify_permission()
   return 0;
 }
 
-static int forward_request_to_master(struct req_state *s, obj_version *objv, RGWRados *store, bufferlist& in_data, JSONParser *jp)
+static int forward_request_to_master(struct req_state *s, obj_version *objv,
+				    RGWRados *store, bufferlist& in_data,
+				    JSONParser *jp)
 {
   if (!store->rest_master_conn) {
     ldout(s->cct, 0) << "rest connection is invalid" << dendl;
     return -EINVAL;
   }
-  ldout(s->cct, 0) << "sending create_bucket request to master region" << dendl;
+  ldout(s->cct, 0) << "sending create_bucket request to master zonegroup" << dendl;
   bufferlist response;
-  string uid_str = s->user.user_id.to_str();
+  string uid_str = s->user->user_id.to_str();
 #define MAX_REST_RESPONSE (128 * 1024) // we expect a very small response
-  int ret = store->rest_master_conn->forward(uid_str, s->info, objv, MAX_REST_RESPONSE, &in_data, &response);
+  int ret = store->rest_master_conn->forward(uid_str, s->info, objv,
+					    MAX_REST_RESPONSE, &in_data,
+					    &response);
   if (ret < 0)
     return ret;
 
   ldout(s->cct, 20) << "response: " << response.c_str() << dendl;
-  if (!jp->parse(response.c_str(), response.length())) {
-    ldout(s->cct, 0) << "failed parsing response from master region" << dendl;
+  if (jp && !jp->parse(response.c_str(), response.length())) {
+    ldout(s->cct, 0) << "failed parsing response from master zonegroup" << dendl;
     return -EINVAL;
   }
 
@@ -1696,6 +1820,62 @@ void RGWCreateBucket::pre_exec()
   rgw_bucket_object_pre_exec(s);
 }
 
+static void prepare_add_del_attrs(const map<string, bufferlist>& orig_attrs,
+                                  map<string, bufferlist>& out_attrs,
+                                  map<string, bufferlist>& out_rmattrs)
+{
+  for (const auto kv : orig_attrs) {
+    const string& name = kv.first;
+
+    /* Check if the attr is user-defined metadata item. */
+    if (name.compare(0, sizeof(RGW_ATTR_META_PREFIX) - 1,
+                     RGW_ATTR_META_PREFIX) == 0) {
+      /* For the objects all existing meta attrs have to be removed. */
+      out_rmattrs[name] = kv.second;
+    } else if (out_attrs.find(name) == std::end(out_attrs)) {
+      out_attrs[name] = kv.second;
+    }
+  }
+}
+
+static void prepare_add_del_attrs(const map<string, bufferlist>& orig_attrs,
+                                  const set<string>& rmattr_names,
+                                  map<string, bufferlist>& out_attrs)
+{
+  for (const auto kv : orig_attrs) {
+    const string& name = kv.first;
+
+    /* Check if the attr is user-defined metadata item. */
+    if (name.compare(0, strlen(RGW_ATTR_META_PREFIX),
+                     RGW_ATTR_META_PREFIX) == 0) {
+      /* For the buckets all existing meta attrs are preserved,
+         except those that are listed in rmattr_names. */
+      if (rmattr_names.find(name) != std::end(rmattr_names)) {
+        const auto aiter = out_attrs.find(name);
+
+        if (aiter != std::end(out_attrs)) {
+          out_attrs.erase(aiter);
+        }
+      }
+    } else if (out_attrs.find(name) == std::end(out_attrs)) {
+      out_attrs[name] = kv.second;
+    }
+  }
+}
+
+
+static void populate_with_generic_attrs(const req_state * const s,
+                                        map<string, bufferlist>& out_attrs)
+{
+  for (auto kv : s->generic_attrs) {
+    bufferlist& attrbl = out_attrs[kv.first];
+    const string& val = kv.second;
+    attrbl.clear();
+    attrbl.append(val.c_str(), val.size() + 1);
+  }
+}
+
+
 void RGWCreateBucket::execute()
 {
   RGWAccessControlPolicy old_policy(s->cct);
@@ -1705,21 +1885,22 @@ void RGWCreateBucket::execute()
   bool existed;
   string bucket_name;
   rgw_make_bucket_entry_name(s->bucket_tenant, s->bucket_name, bucket_name);
-  rgw_obj obj(store->zone.domain_root, bucket_name);
+  rgw_obj obj(store->get_zone_params().domain_root, bucket_name);
   obj_version objv, *pobjv = NULL;
 
   op_ret = get_params();
   if (op_ret < 0)
     return;
 
-  if (!store->region.is_master &&
-      store->region.api_name != location_constraint) {
-    ldout(s->cct, 0) << "location constraint (" << location_constraint << ") doesn't match region" << " (" << store->region.api_name << ")" << dendl;
+  if (!store->get_zonegroup().is_master &&
+      store->get_zonegroup().api_name != location_constraint) {
+    ldout(s->cct, 0) << "location constraint (" << location_constraint << ") doesn't match zonegroup" << " (" << store->get_zonegroup().api_name << ")" << dendl;
     op_ret = -EINVAL;
     return;
   }
 
-  /* we need to make sure we read bucket info, it's not read before for this specific request */
+  /* we need to make sure we read bucket info, it's not read before for this
+   * specific request */
   RGWObjectCtx& obj_ctx = *static_cast<RGWObjectCtx *>(s->obj_ctx);
   op_ret = store->get_bucket_info(obj_ctx, s->bucket_tenant, s->bucket_name,
 				  s->bucket_info, NULL, &s->bucket_attrs);
@@ -1727,13 +1908,13 @@ void RGWCreateBucket::execute()
     return;
   s->bucket_exists = (op_ret != -ENOENT);
 
-  s->bucket_owner.set_id(s->user.user_id);
-  s->bucket_owner.set_name(s->user.display_name);
+  s->bucket_owner.set_id(s->user->user_id);
+  s->bucket_owner.set_name(s->user->display_name);
   if (s->bucket_exists) {
-    int r = get_policy_from_attr(s->cct, store, s->obj_ctx, s->bucket_info, s->bucket_attrs,
-                                 &old_policy, obj);
+    int r = get_policy_from_attr(s->cct, store, s->obj_ctx, s->bucket_info,
+				s->bucket_attrs, &old_policy, obj);
     if (r >= 0)  {
-      if (old_policy.get_owner().get_id().compare(s->user.user_id) != 0) {
+      if (old_policy.get_owner().get_id().compare(s->user->user_id) != 0) {
         op_ret = -EEXIST;
         return;
       }
@@ -1742,9 +1923,9 @@ void RGWCreateBucket::execute()
 
   RGWBucketInfo master_info;
   rgw_bucket *pmaster_bucket;
-  time_t creation_time;
+  real_time creation_time;
 
-  if (!store->region.is_master) {
+  if (!store->is_meta_master()) {
     JSONParser jp;
     op_ret = forward_request_to_master(s, NULL, store, in_data, &jp);
     if (op_ret < 0)
@@ -1760,35 +1941,39 @@ void RGWCreateBucket::execute()
     pobjv = &objv;
   } else {
     pmaster_bucket = NULL;
-    creation_time = 0;
   }
 
-  string region_name;
+  string zonegroup_id;
 
   if (s->system_request) {
-    region_name = s->info.args.get(RGW_SYS_PARAM_PREFIX "region");
-    if (region_name.empty()) {
-      region_name = store->region.name;
+    zonegroup_id = s->info.args.get(RGW_SYS_PARAM_PREFIX "zonegroup");
+    if (zonegroup_id.empty()) {
+      zonegroup_id = store->get_zonegroup().get_id();
     }
   } else {
-    region_name = store->region.name;
+    zonegroup_id = store->get_zonegroup().get_id();
   }
 
   if (s->bucket_exists) {
     string selected_placement_rule;
     rgw_bucket bucket;
-    op_ret = store->select_bucket_placement(s->user, region_name,
+    op_ret = store->select_bucket_placement(*(s->user), zonegroup_id,
 					    placement_rule,
 					    s->bucket_tenant, s->bucket_name,
-					    bucket, &selected_placement_rule);
+					    bucket, &selected_placement_rule, nullptr);
     if (selected_placement_rule != s->bucket_info.placement_rule) {
       op_ret = -EEXIST;
       return;
     }
   }
 
-  policy.encode(aclbl);
+  if (need_metadata_upload()) {
+    rgw_get_request_metadata(s->cct, s->info, attrs, false);
+    prepare_add_del_attrs(s->bucket_attrs, rmattr_names, attrs);
+    populate_with_generic_attrs(s, attrs);
+  }
 
+  policy.encode(aclbl);
   attrs[RGW_ATTR_ACL] = aclbl;
 
   if (has_cors) {
@@ -1797,11 +1982,12 @@ void RGWCreateBucket::execute()
   }
   s->bucket.tenant = s->bucket_tenant; /* ignored if bucket exists */
   s->bucket.name = s->bucket_name;
-  op_ret = store->create_bucket(s->user, s->bucket, region_name, placement_rule,
+  op_ret = store->create_bucket(*(s->user), s->bucket, zonegroup_id, placement_rule,
+                                swift_ver_location,
 				attrs, info, pobjv, &ep_objv, creation_time,
 				pmaster_bucket, true);
-  /* continue if EEXIST and create_bucket will fail below.  this way we can recover
-   * from a partial create by retrying it. */
+  /* continue if EEXIST and create_bucket will fail below.  this way we can
+   * recover from a partial create by retrying it. */
   ldout(s->cct, 20) << "rgw_create_bucket returned ret=" << op_ret << " bucket=" << s->bucket << dendl;
 
   if (op_ret && op_ret != -EEXIST)
@@ -1816,18 +2002,18 @@ void RGWCreateBucket::execute()
      * If all is ok then update the user's list of buckets.
      * Otherwise inform client about a name conflict.
      */
-    if (info.owner.compare(s->user.user_id) != 0) {
+    if (info.owner.compare(s->user->user_id) != 0) {
       op_ret = -EEXIST;
       return;
     }
     s->bucket = info.bucket;
   }
 
-  op_ret = rgw_link_bucket(store, s->user.user_id, s->bucket,
+  op_ret = rgw_link_bucket(store, s->user->user_id, s->bucket,
 			   info.creation_time, false);
   if (op_ret && !existed && op_ret != -EEXIST) {
     /* if it exists (or previously existed), don't remove it! */
-    op_ret = rgw_unlink_bucket(store, s->user.user_id, s->bucket.tenant,
+    op_ret = rgw_unlink_bucket(store, s->user->user_id, s->bucket.tenant,
 			       s->bucket.name);
     if (op_ret < 0) {
       ldout(s->cct, 0) << "WARNING: failed to unlink bucket: ret=" << op_ret
@@ -1836,6 +2022,46 @@ void RGWCreateBucket::execute()
   } else if (op_ret == -EEXIST || (op_ret == 0 && existed)) {
     op_ret = -ERR_BUCKET_EXISTS;
   }
+
+  if (need_metadata_upload() && existed) {
+    /* OK, it looks we lost race with another request. As it's required to
+     * handle metadata fusion and upload, the whole operation becomes very
+     * similar in nature to PutMetadataBucket. However, as the attrs may
+     * changed in the meantime, we have to refresh. */
+    short tries = 0;
+    do {
+      RGWObjectCtx& obj_ctx = *static_cast<RGWObjectCtx *>(s->obj_ctx);
+      RGWBucketInfo binfo;
+      map<string, bufferlist> battrs;
+
+      op_ret = store->get_bucket_info(obj_ctx, s->bucket_tenant, s->bucket_name,
+                                      binfo, nullptr, &battrs);
+      if (op_ret < 0) {
+        return;
+      } else if (binfo.owner.compare(s->user->user_id) != 0) {
+        /* New bucket doesn't belong to the account we're operating on. */
+        op_ret = -EEXIST;
+        return;
+      } else {
+        s->bucket_info = binfo;
+        s->bucket_attrs = battrs;
+      }
+
+      attrs.clear();
+
+      rgw_get_request_metadata(s->cct, s->info, attrs, false);
+      prepare_add_del_attrs(s->bucket_attrs, rmattr_names, attrs);
+      populate_with_generic_attrs(s, attrs);
+
+      op_ret = rgw_bucket_set_attrs(store, s->bucket_info, attrs,
+                                    &s->bucket_info.objv_tracker);
+    } while (op_ret == -ECANCELED && tries++ < 20);
+
+    /* Restore the proper return code. */
+    if (op_ret >= 0) {
+      op_ret = -ERR_BUCKET_EXISTS;
+    }
+  }
 }
 
 int RGWDeleteBucket::verify_permission()
@@ -1858,6 +2084,11 @@ void RGWDeleteBucket::execute()
   if (s->bucket_name.empty())
     return;
 
+  if (!s->bucket_exists) {
+    ldout(s->cct, 0) << "ERROR: bucket " << s->bucket_name << " not found" << dendl;
+    op_ret = -ERR_NO_SUCH_BUCKET;
+    return;
+  }
   RGWObjVersionTracker ot;
   ot.read_version = s->bucket_info.ep_objv;
 
@@ -1878,9 +2109,14 @@ void RGWDeleteBucket::execute()
     }
   }
 
+  op_ret = rgw_bucket_sync_user_stats(store, s->user->user_id, s->bucket);
+  if ( op_ret < 0) {
+     ldout(s->cct, 1) << "WARNING: failed to sync user stats before bucket delete: op_ret= " << op_ret << dendl;
+  }
+
   op_ret = store->delete_bucket(s->bucket, ot);
   if (op_ret == 0) {
-    op_ret = rgw_unlink_bucket(store, s->user.user_id, s->bucket.tenant,
+    op_ret = rgw_unlink_bucket(store, s->user->user_id, s->bucket.tenant,
 			       s->bucket.name, false);
     if (op_ret < 0) {
       ldout(s->cct, 0) << "WARNING: failed to unlink bucket: ret=" << op_ret
@@ -1892,11 +2128,10 @@ void RGWDeleteBucket::execute()
     return;
   }
 
-  if (!store->region.is_master) {
+  if (!store->is_meta_master()) {
     bufferlist in_data;
-    JSONParser jp;
     op_ret = forward_request_to_master(s, &ot.read_version, store, in_data,
-				       &jp);
+				       NULL);
     if (op_ret < 0) {
       if (op_ret == -ENOENT) {
         /* adjust error, we want to return with NoSuchBucket and not
@@ -1926,8 +2161,8 @@ class RGWPutObjProcessor_Multipart : public RGWPutObjProcessor_Atomic
 
 protected:
   int prepare(RGWRados *store, string *oid_rand);
-  int do_complete(string& etag, time_t *mtime, time_t set_mtime,
-                  map<string, bufferlist>& attrs, time_t delete_at,
+  int do_complete(string& etag, real_time *mtime, real_time set_mtime,
+                  map<string, bufferlist>& attrs, real_time delete_at,
                   const char *if_match = NULL, const char *if_nomatch = NULL);
 
 public:
@@ -2000,8 +2235,8 @@ static bool is_v2_upload_id(const string& upload_id)
          (strncmp(uid, MULTIPART_UPLOAD_ID_PREFIX_LEGACY, sizeof(MULTIPART_UPLOAD_ID_PREFIX_LEGACY) - 1) == 0);
 }
 
-int RGWPutObjProcessor_Multipart::do_complete(string& etag, time_t *mtime, time_t set_mtime,
-                                              map<string, bufferlist>& attrs, time_t delete_at,
+int RGWPutObjProcessor_Multipart::do_complete(string& etag, real_time *mtime, real_time set_mtime,
+                                              map<string, bufferlist>& attrs, real_time delete_at,
                                               const char *if_match, const char *if_nomatch)
 {
   complete_writing_data();
@@ -2039,7 +2274,7 @@ int RGWPutObjProcessor_Multipart::do_complete(string& etag, time_t *mtime, time_
   info.num = atoi(part_num.c_str());
   info.etag = etag;
   info.size = s->obj_size;
-  info.modified = ceph_clock_now(store->ctx());
+  info.modified = real_clock::now();
   info.manifest = manifest;
   ::encode(info, bl);
 
@@ -2088,91 +2323,6 @@ void RGWPutObj::pre_exec()
   rgw_bucket_object_pre_exec(s);
 }
 
-static int put_data_and_throttle(RGWPutObjProcessor *processor, bufferlist& data, off_t ofs,
-                                 MD5 *hash, bool need_to_wait)
-{
-  bool again;
-
-  do {
-    void *handle;
-
-    int ret = processor->handle_data(data, ofs, hash, &handle, &again);
-    if (ret < 0)
-      return ret;
-
-    ret = processor->throttle_data(handle, need_to_wait);
-    if (ret < 0)
-      return ret;
-
-    need_to_wait = false; /* the need to wait only applies to the first iteration */
-  } while (again);
-
-  return 0;
-}
-
-static int get_system_versioning_params(req_state *s, uint64_t *olh_epoch, string *version_id)
-{
-  if (!s->system_request) {
-    return 0;
-  }
-
-  if (olh_epoch) {
-    string epoch_str = s->info.args.get(RGW_SYS_PARAM_PREFIX "versioned-epoch");
-    if (!epoch_str.empty()) {
-      string err;
-      *olh_epoch = strict_strtol(epoch_str.c_str(), 10, &err);
-      if (!err.empty()) {
-        ldout(s->cct, 0) << "failed to parse versioned-epoch param" << dendl;
-        return -EINVAL;
-      }
-    }
-  }
-
-  if (version_id) {
-    *version_id = s->info.args.get(RGW_SYS_PARAM_PREFIX "version-id");
-  }
-
-  return 0;
-}
-
-static void encode_delete_at_attr(time_t delete_at, map<string, bufferlist>& attrs)
-{
-  if (delete_at == 0) {
-    return;
-  }
-
-  bufferlist delatbl;
-  ::encode(utime_t(delete_at, 0), delatbl);
-  attrs[RGW_ATTR_DELETE_AT] = delatbl;
-}
-
-static int encode_dlo_manifest_attr(const char * const dlo_manifest,
-                                    map<string, bufferlist>& attrs)
-{
-  string dm = dlo_manifest;
-
-  if (dm.find('/') == string::npos) {
-    return -EINVAL;
-  }
-
-  bufferlist manifest_bl;
-  manifest_bl.append(dlo_manifest, strlen(dlo_manifest) + 1);
-  attrs[RGW_ATTR_USER_MANIFEST] = manifest_bl;
-
-  return 0;
-}
-
-static void complete_etag(MD5& hash, string *etag)
-{
-  char etag_buf[CEPH_CRYPTO_MD5_DIGESTSIZE];
-  char etag_buf_str[CEPH_CRYPTO_MD5_DIGESTSIZE * 2 + 16];
-
-  hash.Final((byte *)etag_buf);
-  buf_to_hex((const unsigned char *)etag_buf, CEPH_CRYPTO_MD5_DIGESTSIZE, etag_buf_str);
-
-  *etag = etag_buf_str;
-}
-
 void RGWPutObj::execute()
 {
   RGWPutObjProcessor *processor = NULL;
@@ -2196,6 +2346,11 @@ void RGWPutObj::execute()
     goto done;
   }
 
+  if (!s->bucket_exists) {
+    op_ret = -ERR_NO_SUCH_BUCKET;
+    return;
+  }
+
   op_ret = get_params();
   if (op_ret < 0) {
     ldout(s->cct, 20) << "get_params() returned ret=" << op_ret << dendl;
@@ -2318,11 +2473,35 @@ void RGWPutObj::execute()
 
   perfcounter->inc(l_rgw_put_b, s->obj_size);
 
+  if (s->aws4_auth_needs_complete) {
+
+    /* complete aws4 auth */
+
+    op_ret = RGW_Auth_S3::authorize_aws4_auth_complete(store, s);
+    if (op_ret) {
+      goto done;
+    }
+
+    s->aws4_auth_needs_complete = false;
+
+    /* verify signature */
+
+    if (s->aws4_auth->signature != s->aws4_auth->new_signature) {
+      op_ret = -ERR_SIGNATURE_NO_MATCH;
+      ldout(s->cct, 20) << "delayed aws4 auth failed" << dendl;
+      goto done;
+    }
+
+    /* authorization ok */
+
+    dout(10) << "v4 auth ok" << dendl;
+
+  }
+
   op_ret = store->check_quota(s->bucket_owner.get_id(), s->bucket,
-			      user_quota, bucket_quota, s->obj_size);
+                              user_quota, bucket_quota, s->obj_size);
   if (op_ret < 0) {
-    ldout(s->cct, 20) << "second check_quota() returned ret=" << op_ret
-		      << dendl;
+    ldout(s->cct, 20) << "second check_quota() returned op_ret=" << op_ret << dendl;
     goto done;
   }
 
@@ -2389,7 +2568,7 @@ void RGWPutObj::execute()
     attrs[RGW_ATTR_SLO_UINDICATOR] = slo_userindicator_bl;
   }
 
-  op_ret = processor->complete(etag, &mtime, 0, attrs, delete_at, if_match,
+  op_ret = processor->complete(etag, &mtime, real_time(), attrs, delete_at, if_match,
 			       if_nomatch);
 
 done:
@@ -2511,73 +2690,16 @@ void RGWPostObj::execute()
     attrs[RGW_ATTR_CONTENT_TYPE] = ct_bl;
   }
 
-  op_ret = processor->complete(etag, NULL, 0, attrs, delete_at);
+  op_ret = processor->complete(etag, NULL, real_time(), attrs, delete_at);
 
 done:
   dispose_processor(processor);
 }
 
-
-static void populate_with_generic_attrs(const req_state * const s,
-                                        map<string, bufferlist>& out_attrs)
-{
-  map<string, string>::const_iterator giter;
-
-  for (giter = s->generic_attrs.begin(); giter != s->generic_attrs.end(); ++giter) {
-    bufferlist& attrbl = out_attrs[giter->first];
-    const string& val = giter->second;
-    attrbl.clear();
-    attrbl.append(val.c_str(), val.size() + 1);
-  }
-}
-
-static void prepare_add_del_attrs(const map<string, bufferlist>& orig_attrs,
-                                  map<string, bufferlist>& out_attrs,
-                                  map<string, bufferlist>& out_rmattrs)
-{
-  map<string, bufferlist>::const_iterator iter;
-
-  for (iter = orig_attrs.begin(); iter != orig_attrs.end(); ++iter) {
-    const string& name = iter->first;
-    /* check if the attr is user-defined metadata item */
-    if (name.compare(0, sizeof(RGW_ATTR_META_PREFIX) - 1, RGW_ATTR_META_PREFIX) == 0) {
-      /* for the objects all existing meta attrs have to be removed */
-      out_rmattrs[name] = iter->second;
-    } else if (out_attrs.find(name) == out_attrs.end()) {
-      out_attrs[name] = iter->second;
-    }
-  }
-}
-
-static void prepare_add_del_attrs(const map<string, bufferlist>& orig_attrs,
-                                  const set<string>& rmattr_names,
-                                  map<string, bufferlist>& out_attrs,
-                                  map<string, bufferlist>& out_rmattrs)
-{
-  map<string, bufferlist>::const_iterator iter;
-
-  for (iter = orig_attrs.begin(); iter != orig_attrs.end(); ++iter) {
-    const string& name = iter->first;
-    /* check if the attr is user-defined metadata item */
-    if (name.compare(0, strlen(RGW_ATTR_META_PREFIX), RGW_ATTR_META_PREFIX) == 0) {
-      /* for the buckets all existing meta attrs are preserved,
-         except those that are listed in rmattr_names. */
-      if (rmattr_names.find(name) != rmattr_names.end()) {
-        map<string, bufferlist>::iterator aiter = out_attrs.find(name);
-        if (aiter != out_attrs.end()) {
-          out_attrs.erase(aiter);
-        }
-        out_rmattrs[name] = iter->second;
-      }
-    } else if (out_attrs.find(name) == out_attrs.end()) {
-      out_attrs[name] = iter->second;
-    }
-  }
-}
-
-int RGWPutMetadataAccount::handle_temp_url_update(const map<int, string>& temp_url_keys) {
+int RGWPutMetadataAccount::handle_temp_url_update(
+  const map<int, string>& temp_url_keys) {
   RGWUserAdminOpState user_op;
-  user_op.set_user_id(s->user.user_id);
+  user_op.set_user_id(s->user->user_id);
 
   map<int, string>::const_iterator iter;
   for (iter = temp_url_keys.begin(); iter != temp_url_keys.end(); ++iter) {
@@ -2604,7 +2726,7 @@ int RGWPutMetadataAccount::handle_temp_url_update(const map<int, string>& temp_u
 
 int RGWPutMetadataAccount::verify_permission()
 {
-  if (!rgw_user_is_authenticated(s->user)) {
+  if (!rgw_user_is_authenticated(*(s->user))) {
     return -EACCES;
   }
   // if ((s->perm_mask & RGW_PERM_WRITE) == 0) {
@@ -2655,8 +2777,8 @@ void RGWPutMetadataAccount::execute()
   }
 
   rgw_get_request_metadata(s->cct, s->info, attrs, false);
-  rgw_get_user_attrs_by_uid(store, s->user.user_id, orig_attrs, &acct_op_tracker);
-  prepare_add_del_attrs(orig_attrs, rmattr_names, attrs, rmattrs);
+  RGWUserInfo orig_uinfo;
+  rgw_get_user_info_by_uid(store, s->user->user_id, orig_uinfo, &acct_op_tracker);
   populate_with_generic_attrs(s, attrs);
 
   /* Handle the TempURL-related stuff. */
@@ -2670,8 +2792,8 @@ void RGWPutMetadataAccount::execute()
   }
 
   /* XXX tenant needed? */
-  op_ret = rgw_store_user_attrs(store, s->user.user_id.id, attrs, &rmattrs,
-				&acct_op_tracker);
+  op_ret = rgw_store_user_info(store, *(s->user), &orig_uinfo,
+                               &acct_op_tracker, real_time(), false, &attrs);
   if (op_ret < 0) {
     return;
   }
@@ -2700,7 +2822,7 @@ void RGWPutMetadataBucket::pre_exec()
 
 void RGWPutMetadataBucket::execute()
 {
-  map<string, bufferlist> attrs, orig_attrs, rmattrs;
+  map<string, bufferlist> attrs, orig_attrs;
 
   op_ret = get_params();
   if (op_ret < 0) {
@@ -2716,7 +2838,7 @@ void RGWPutMetadataBucket::execute()
   }
 
   orig_attrs = s->bucket_attrs;
-  prepare_add_del_attrs(orig_attrs, rmattr_names, attrs, rmattrs);
+  prepare_add_del_attrs(orig_attrs, rmattr_names, attrs);
   populate_with_generic_attrs(s, attrs);
 
   if (has_policy) {
@@ -2731,8 +2853,10 @@ void RGWPutMetadataBucket::execute()
     attrs[RGW_ATTR_CORS] = bl;
   }
 
-  op_ret = rgw_bucket_set_attrs(store, s->bucket_info, attrs, &rmattrs,
-				&s->bucket_info.objv_tracker);
+  s->bucket_info.swift_ver_location = swift_ver_location;
+  s->bucket_info.swift_versioning = (!swift_ver_location.empty());
+
+  op_ret = rgw_bucket_set_attrs(store, s->bucket_info, attrs, &s->bucket_info.objv_tracker);
 }
 
 int RGWPutMetadataObject::verify_permission()
@@ -2788,7 +2912,7 @@ void RGWPutMetadataObject::execute()
     }
   }
 
-  op_ret = store->set_attrs(s->obj_ctx, obj, attrs, &rmattrs, NULL);
+  op_ret = store->set_attrs(s->obj_ctx, obj, attrs, &rmattrs);
 }
 
 int RGWDeleteObj::handle_slo_manifest(bufferlist& bl)
@@ -2861,15 +2985,20 @@ void RGWDeleteObj::pre_exec()
 
 void RGWDeleteObj::execute()
 {
-  op_ret = -EINVAL;
-  rgw_obj obj(s->bucket, s->object);
-  map<string, bufferlist> attrs;
+  if (!s->bucket_exists) {
+    op_ret = -ERR_NO_SUCH_BUCKET;
+    return;
+  }
 
   op_ret = get_params();
   if (op_ret < 0) {
     return;
   }
 
+  rgw_obj obj(s->bucket, s->object);
+  map<string, bufferlist> attrs;
+
+
   if (!s->object.empty()) {
     if (need_object_expiration() || multipart_delete) {
       /* check if obj exists, read orig attrs */
@@ -2910,6 +3039,8 @@ void RGWDeleteObj::execute()
     del_op.params.bucket_owner = s->bucket_owner.get_id();
     del_op.params.versioning_status = s->bucket_info.versioning_status();
     del_op.params.obj_owner = s->owner;
+    del_op.params.unmod_since = unmod_since;
+    del_op.params.high_precision_time = s->system_request; /* system request uses high precision time */
 
     op_ret = del_op.delete_obj();
     if (op_ret >= 0) {
@@ -2923,6 +3054,12 @@ void RGWDeleteObj::execute()
       op_ret = -ENOENT;
       return;
     }
+
+    if (op_ret == -ERR_PRECONDITION_FAILED && no_precondition_error) {
+      op_ret = 0;
+    }
+  } else {
+    op_ret = -EINVAL;
   }
 }
 
@@ -2986,10 +3123,18 @@ int RGWCopyObj::verify_permission()
 
   RGWObjectCtx& obj_ctx = *static_cast<RGWObjectCtx *>(s->obj_ctx);
 
-  op_ret = store->get_bucket_info(obj_ctx, src_tenant_name, src_bucket_name,
-				  src_bucket_info, NULL, &src_attrs);
-  if (op_ret < 0)
+  if (s->bucket_instance_id.empty()) {
+    op_ret = store->get_bucket_info(obj_ctx, src_tenant_name, src_bucket_name, src_bucket_info, NULL, &src_attrs);
+  } else {
+    /* will only happen in intra region sync where the source and dest bucket is the same */
+    op_ret = store->get_bucket_instance_info(obj_ctx, s->bucket_instance_id, src_bucket_info, NULL, &src_attrs);
+  }
+  if (op_ret < 0) {
+    if (op_ret == -ENOENT) {
+      op_ret = -ERR_NO_SUCH_BUCKET;
+    }
     return op_ret;
+  }
 
   src_bucket = src_bucket_info.bucket;
 
@@ -3006,21 +3151,27 @@ int RGWCopyObj::verify_permission()
       return op_ret;
 
     if (!s->system_request && /* system request overrides permission checks */
-        !src_policy.verify_permission(s->user.user_id, s->perm_mask, RGW_PERM_READ))
+        !src_policy.verify_permission(s->user->user_id, s->perm_mask,
+				      RGW_PERM_READ))
       return -EACCES;
   }
 
   RGWAccessControlPolicy dest_bucket_policy(s->cct);
   map<string, bufferlist> dest_attrs;
 
-  if (src_bucket_name.compare(dest_bucket_name) == 0) { /* will only happen if s->local_source */
+  if (src_bucket_name.compare(dest_bucket_name) == 0) { /* will only happen if s->local_source
+                                                           or intra region sync */
     dest_bucket_info = src_bucket_info;
     dest_attrs = src_attrs;
   } else {
     op_ret = store->get_bucket_info(obj_ctx, dest_tenant_name, dest_bucket_name,
 				    dest_bucket_info, NULL, &dest_attrs);
-    if (op_ret < 0)
+    if (op_ret < 0) {
+      if (op_ret == -ENOENT) {
+        op_ret = -ERR_NO_SUCH_BUCKET;
+      }
       return op_ret;
+    }
   }
 
   dest_bucket = dest_bucket_info.bucket;
@@ -3037,7 +3188,8 @@ int RGWCopyObj::verify_permission()
     return op_ret;
 
   if (!s->system_request && /* system request overrides permission checks */
-      !dest_bucket_policy.verify_permission(s->user.user_id, s->perm_mask, RGW_PERM_WRITE))
+      !dest_bucket_policy.verify_permission(s->user->user_id, s->perm_mask,
+					    RGW_PERM_WRITE))
     return -EACCES;
 
   op_ret = init_dest_policy();
@@ -3120,8 +3272,10 @@ void RGWCopyObj::execute()
 
   encode_delete_at_attr(delete_at, attrs);
 
+  bool high_precision_time = (s->system_request);
+
   op_ret = store->copy_obj(obj_ctx,
-			   s->user.user_id,
+			   s->user->user_id,
 			   client_id,
 			   op_id,
 			   &s->info,
@@ -3134,9 +3288,11 @@ void RGWCopyObj::execute()
 			   &mtime,
 			   mod_ptr,
 			   unmod_ptr,
+                           high_precision_time,
 			   if_match,
 			   if_nomatch,
 			   attrs_mod,
+                           copy_if_newer,
 			   attrs, RGW_OBJ_CATEGORY_MAIN,
 			   olh_epoch,
 			   delete_at,
@@ -3268,8 +3424,6 @@ void RGWPutACLs::execute()
     *_dout << dendl;
   }
 
-  RGWObjVersionTracker *ptracker = (!s->object.empty() ? NULL : &s->bucket_info.objv_tracker);
-
   new_policy.encode(bl);
   obj = rgw_obj(s->bucket, s->object);
   map<string, bufferlist> attrs;
@@ -3280,20 +3434,19 @@ void RGWPutACLs::execute()
     op_ret = get_obj_attrs(store, s, obj, attrs);
     if (op_ret < 0)
       return;
-  }
   
-  attrs[RGW_ATTR_ACL] = bl;
-
-  if (!s->object.empty()) {
-    op_ret = store->set_attrs(s->obj_ctx, obj, attrs, NULL, ptracker);
+    attrs[RGW_ATTR_ACL] = bl;
+    op_ret = store->set_attrs(s->obj_ctx, obj, attrs, NULL);
   } else {
-    op_ret = rgw_bucket_set_attrs(store, s->bucket_info, attrs, NULL, ptracker);
+    attrs = s->bucket_attrs;
+    attrs[RGW_ATTR_ACL] = bl;
+    op_ret = rgw_bucket_set_attrs(store, s->bucket_info, attrs, &s->bucket_info.objv_tracker);
   }
 }
 
 int RGWGetCORS::verify_permission()
 {
-  if (s->user.user_id.compare(s->bucket_owner.get_id()) != 0)
+  if (s->user->user_id.compare(s->bucket_owner.get_id()) != 0)
     return -EACCES;
 
   return 0;
@@ -3314,7 +3467,7 @@ void RGWGetCORS::execute()
 
 int RGWPutCORS::verify_permission()
 {
-  if (s->user.user_id.compare(s->bucket_owner.get_id()) != 0)
+  if (s->user->user_id.compare(s->bucket_owner.get_id()) != 0)
     return -EACCES;
 
   return 0;
@@ -3328,23 +3481,21 @@ void RGWPutCORS::execute()
   if (op_ret < 0)
     return;
 
-  RGWObjVersionTracker *ptracker = (!s->object.empty() ? NULL : &s->bucket_info.objv_tracker);
-
   bool is_object_op = (!s->object.empty());
   if (is_object_op) {
     store->get_bucket_instance_obj(s->bucket, obj);
     store->set_atomic(s->obj_ctx, obj);
-    op_ret = store->set_attr(s->obj_ctx, obj, RGW_ATTR_CORS, cors_bl, ptracker);
+    op_ret = store->set_attr(s->obj_ctx, obj, RGW_ATTR_CORS, cors_bl);
   } else {
-    map<string, bufferlist> attrs;
+    map<string, bufferlist> attrs = s->bucket_attrs;
     attrs[RGW_ATTR_CORS] = cors_bl;
-    op_ret = rgw_bucket_set_attrs(store, s->bucket_info, attrs, NULL, ptracker);
+    op_ret = rgw_bucket_set_attrs(store, s->bucket_info, attrs, &s->bucket_info.objv_tracker);
   }
 }
 
 int RGWDeleteCORS::verify_permission()
 {
-  if (s->user.user_id.compare(s->bucket_owner.get_id()) != 0)
+  if (s->user->user_id.compare(s->bucket_owner.get_id()) != 0)
     return -EACCES;
 
   return 0;
@@ -3369,7 +3520,6 @@ void RGWDeleteCORS::execute()
   map<string, bufferlist>::iterator iter;
 
   bool is_object_op = (!s->object.empty());
-  RGWObjVersionTracker *ptracker = NULL;
 
 
   if (is_object_op) {
@@ -3378,8 +3528,7 @@ void RGWDeleteCORS::execute()
     if (op_ret < 0)
       return;
   } else {
-    ptracker = (!s->object.empty() ? NULL : &s->bucket_info.objv_tracker);
-    op_ret = get_system_obj_attrs(store, s, obj, orig_attrs, NULL, ptracker);
+    op_ret = get_system_obj_attrs(store, s, obj, orig_attrs, NULL, &s->bucket_info.objv_tracker);
     if (op_ret < 0)
       return;
   }
@@ -3395,10 +3544,9 @@ void RGWDeleteCORS::execute()
     }
   }
   if (is_object_op) {
-    op_ret = store->set_attrs(s->obj_ctx, obj, attrs, &rmattrs, ptracker);
+    op_ret = store->set_attrs(s->obj_ctx, obj, attrs, &rmattrs);
   } else {
-    op_ret = rgw_bucket_set_attrs(store, s->bucket_info, attrs, &rmattrs,
-				  ptracker);
+    op_ret = rgw_bucket_set_attrs(store, s->bucket_info, attrs, &s->bucket_info.objv_tracker);
   }
 }
 
@@ -3472,7 +3620,7 @@ void RGWGetRequestPayment::execute()
 
 int RGWSetRequestPayment::verify_permission()
 {
-  if (s->user.user_id.compare(s->bucket_owner.get_id()) != 0)
+  if (s->user->user_id.compare(s->bucket_owner.get_id()) != 0)
     return -EACCES;
 
   return 0;
@@ -3491,7 +3639,7 @@ void RGWSetRequestPayment::execute()
     return;
 
   s->bucket_info.requester_pays = requester_pays;
-  op_ret = store->put_bucket_instance_info(s->bucket_info, false, 0,
+  op_ret = store->put_bucket_instance_info(s->bucket_info, false, real_time(),
 					   &s->bucket_attrs);
   if (op_ret < 0) {
     ldout(s->cct, 0) << "NOTICE: put_bucket_info on bucket=" << s->bucket.name
@@ -4083,7 +4231,7 @@ void RGWListBucketMultiparts::execute()
   }
   marker_meta = marker.get_meta();
 
-  RGWRados::Bucket target(store, s->bucket);
+  RGWRados::Bucket target(store, s->bucket_info);
   RGWRados::Bucket::List list_op(&target);
 
   list_op.params.prefix = prefix;
@@ -4245,8 +4393,8 @@ bool RGWBulkDelete::Deleter::delete_single(const acct_path_t& path)
 
   RGWBucketInfo binfo;
   map<string, bufferlist> battrs;
-  int ret = store->get_bucket_info(obj_ctx, s->user.user_id.tenant,
-				   path.bucket_name, binfo, NULL, &battrs);
+  int ret = store->get_bucket_info(obj_ctx, s->user->user_id.tenant,
+				  path.bucket_name, binfo, NULL, &battrs);
   if (ret < 0) {
     goto binfo_fail;
   }
@@ -4294,11 +4442,10 @@ bool RGWBulkDelete::Deleter::delete_single(const acct_path_t& path)
       goto delop_fail;
     }
 
-    if (!store->region.is_master) {
+    if (!store->get_zonegroup().is_master) {
       bufferlist in_data;
-      JSONParser jp;
       ret = forward_request_to_master(s, &ot.read_version, store, in_data,
-				      &jp);
+				      NULL);
       if (ret < 0) {
         if (ret == -ENOENT) {
           /* adjust error, we want to return with NoSuchBucket and not
@@ -4429,7 +4576,9 @@ int RGWHandler::do_read_permissions(RGWOp *op, bool only_bucket)
   int ret = rgw_build_object_policies(store, s, op->prefetch_data());
 
   if (ret < 0) {
-    ldout(s->cct, 10) << "read_permissions on " << s->bucket << ":" << s->object << " ret=" << ret << dendl;
+    ldout(s->cct, 10) << "read_permissions on " << s->bucket << ":"
+		      << s->object << " only_bucket=" << only_bucket
+		      << " ret=" << ret << dendl;
     if (ret == -ENODATA)
       ret = -EACCES;
   }
@@ -4437,47 +4586,6 @@ int RGWHandler::do_read_permissions(RGWOp *op, bool only_bucket)
   return ret;
 }
 
-
-RGWOp *RGWHandler::get_op(RGWRados *store)
-{
-  RGWOp *op;
-  switch (s->op) {
-   case OP_GET:
-     op = op_get();
-     break;
-   case OP_PUT:
-     op = op_put();
-     break;
-   case OP_DELETE:
-     op = op_delete();
-     break;
-   case OP_HEAD:
-     op = op_head();
-     break;
-   case OP_POST:
-     op = op_post();
-     break;
-   case OP_COPY:
-     op = op_copy();
-     break;
-   case OP_OPTIONS:
-     op = op_options();
-     break;
-   default:
-     return NULL;
-  }
-
-  if (op) {
-    op->init(store, s, this);
-  }
-  return op;
-}
-
-void RGWHandler::put_op(RGWOp *op)
-{
-  delete op;
-}
-
 int RGWOp::error_handler(int err_no, string *error_content) {
   return dialect_handler->error_handler(err_no, error_content);
 }
diff --git a/src/rgw/rgw_op.h b/src/rgw/rgw_op.h
index 254fbd4..e3ecd60 100644
--- a/src/rgw/rgw_op.h
+++ b/src/rgw/rgw_op.h
@@ -18,6 +18,13 @@
 #include <set>
 #include <map>
 
+#include "common/armor.h"
+#include "common/mime.h"
+#include "common/utf8.h"
+#include "common/ceph_json.h"
+#include "common/utf8.h"
+#include "common/ceph_time.h"
+
 #include "rgw_common.h"
 #include "rgw_rados.h"
 #include "rgw_user.h"
@@ -26,50 +33,13 @@
 #include "rgw_cors.h"
 #include "rgw_quota.h"
 
+#include "include/assert.h"
+
 using namespace std;
 
 struct req_state;
 class RGWHandler;
 
-enum RGWOpType {
-  RGW_OP_UNKNOWN = 0,
-  RGW_OP_GET_OBJ,
-  RGW_OP_LIST_BUCKETS,
-  RGW_OP_STAT_ACCOUNT,
-  RGW_OP_LIST_BUCKET,
-  RGW_OP_GET_BUCKET_LOGGING,
-  RGW_OP_GET_BUCKET_VERSIONING,
-  RGW_OP_SET_BUCKET_VERSIONING,
-  RGW_OP_GET_BUCKET_WEBSITE,
-  RGW_OP_SET_BUCKET_WEBSITE,
-  RGW_OP_STAT_BUCKET,
-  RGW_OP_CREATE_BUCKET,
-  RGW_OP_DELETE_BUCKET,
-  RGW_OP_PUT_OBJ,
-  RGW_OP_POST_OBJ,
-  RGW_OP_PUT_METADATA_ACCOUNT,
-  RGW_OP_PUT_METADATA_BUCKET,
-  RGW_OP_PUT_METADATA_OBJECT,
-  RGW_OP_SET_TEMPURL,
-  RGW_OP_DELETE_OBJ,
-  RGW_OP_COPY_OBJ,
-  RGW_OP_GET_ACLS,
-  RGW_OP_PUT_ACLS,
-  RGW_OP_GET_CORS,
-  RGW_OP_PUT_CORS,
-  RGW_OP_DELETE_CORS,
-  RGW_OP_OPTIONS_CORS,
-  RGW_OP_GET_REQUEST_PAYMENT,
-  RGW_OP_SET_REQUEST_PAYMENT,
-  RGW_OP_INIT_MULTIPART,
-  RGW_OP_COMPLETE_MULTIPART,
-  RGW_OP_ABORT_MULTIPART,
-  RGW_OP_LIST_MULTIPART,
-  RGW_OP_LIST_BUCKET_MULTIPARTS,
-  RGW_OP_DELETE_MULTI_OBJ,
-  RGW_OP_BULK_DELETE
-};
-
 /**
  * Provide the base class for all ops.
  */
@@ -84,10 +54,13 @@ protected:
   RGWQuotaInfo user_quota;
   int op_ret;
 
+  int do_aws4_auth_completion();
+
   virtual int init_quota();
 public:
-RGWOp() : s(NULL), dialect_handler(NULL), store(NULL), cors_exist(false),
-    op_ret(0) {}
+RGWOp() : s(nullptr), dialect_handler(nullptr), store(nullptr),
+    cors_exist(false), op_ret(0) {}
+
   virtual ~RGWOp() {}
 
   int get_ret() const { return op_ret; }
@@ -133,15 +106,17 @@ protected:
   const char *if_unmod;
   const char *if_match;
   const char *if_nomatch;
+  uint32_t mod_zone_id;
+  uint64_t mod_pg_ver;
   off_t ofs;
   uint64_t total_len;
   off_t start;
   off_t end;
-  time_t mod_time;
-  time_t lastmod;
-  time_t unmod_time;
-  time_t *mod_ptr;
-  time_t *unmod_ptr;
+  ceph::real_time mod_time;
+  ceph::real_time lastmod;
+  ceph::real_time unmod_time;
+  ceph::real_time *mod_ptr;
+  ceph::real_time *unmod_ptr;
   map<string, bufferlist> attrs;
   bool get_data;
   bool partial_content;
@@ -150,6 +125,7 @@ protected:
   rgw_obj obj;
   utime_t gc_invalidate_time;
   bool is_slo;
+  string lo_etag;
 
   int init_common();
 public:
@@ -159,13 +135,12 @@ public:
     if_unmod = NULL;
     if_match = NULL;
     if_nomatch = NULL;
+    mod_zone_id = 0;
+    mod_pg_ver = 0;
     start = 0;
     ofs = 0;
     total_len = 0;
     end = -1;
-    mod_time = 0;
-    lastmod = 0;
-    unmod_time = 0;
     mod_ptr = NULL;
     unmod_ptr = NULL;
     get_data = false;
@@ -308,6 +283,11 @@ protected:
   uint64_t buckets_size;
   uint64_t buckets_size_rounded;
   map<string, bufferlist> attrs;
+  bool is_truncated;
+
+  virtual uint64_t get_default_max() const {
+    return 1000;
+  }
 
 public:
   RGWListBuckets() : sent_data(false) {
@@ -335,6 +315,33 @@ public:
   virtual uint32_t op_mask() { return RGW_OP_TYPE_READ; }
 };
 
+class RGWGetUsage : public RGWOp {
+protected:
+  bool sent_data;
+  string start_date;
+  string end_date;
+  int show_log_entries;
+  int show_log_sum;
+  map<string, bool> categories;
+  map<rgw_user_bucket, rgw_usage_log_entry> usage;
+  map<string, rgw_usage_log_entry> summary_map;
+  cls_user_header header;
+public:
+  RGWGetUsage() : sent_data(false), show_log_entries(true), show_log_sum(true){
+  }
+
+  int verify_permission();
+  void execute();
+
+  virtual int get_params() = 0;
+  virtual void send_response() {}
+
+  virtual bool should_get_stats() { return false; }
+
+  virtual const string name() { return "get_usage"; }
+  virtual uint32_t op_mask() { return RGW_OP_TYPE_READ; }
+};
+
 class RGWStatAccount : public RGWOp {
 protected:
   uint32_t buckets_count;
@@ -377,11 +384,13 @@ protected:
   int default_max;
   bool is_truncated;
 
+  int shard_id;
+
   int parse_max_keys();
 
 public:
   RGWListBucket() : list_versions(false), max(0),
-                    default_max(0), is_truncated(false) {}
+                    default_max(0), is_truncated(false), shard_id(-1) {}
   int verify_permission();
   void pre_exec();
   void execute();
@@ -526,9 +535,13 @@ protected:
   obj_version ep_objv;
   bool has_cors;
   RGWCORSConfiguration cors_config;
+  string swift_ver_location;
+  set<string> rmattr_names;
 
   bufferlist in_data;
 
+  virtual bool need_metadata_upload() const { return false; }
+
 public:
   RGWCreateBucket() : has_cors(false) {}
 
@@ -635,11 +648,11 @@ protected:
   const char *dlo_manifest;
   RGWSLOInfo *slo_info;
 
-  time_t mtime;
+  ceph::real_time mtime;
   uint64_t olh_epoch;
   string version_id;
 
-  time_t delete_at;
+  ceph::real_time delete_at;
 
 public:
   RGWPutObj() : ofs(0),
@@ -650,9 +663,7 @@ public:
                 chunked_upload(0),
                 dlo_manifest(NULL),
                 slo_info(NULL),
-                mtime(0),
-                olh_epoch(0),
-                delete_at(0) {}
+                olh_epoch(0) {}
 
   ~RGWPutObj() {
     delete slo_info;
@@ -663,7 +674,7 @@ public:
     policy.set_ctx(s->cct);
   }
 
-  RGWPutObjProcessor *select_processor(RGWObjectCtx& obj_ctx, bool *is_multipart);
+  virtual RGWPutObjProcessor *select_processor(RGWObjectCtx& obj_ctx, bool *is_multipart);
   void dispose_processor(RGWPutObjProcessor *processor);
 
   int verify_permission();
@@ -695,12 +706,12 @@ protected:
   string content_type;
   RGWAccessControlPolicy policy;
   map<string, bufferlist> attrs;
-  time_t delete_at;
+  ceph::real_time delete_at;
 
 public:
   RGWPostObj() : min_len(0), max_len(LLONG_MAX), len(0), ofs(0),
 		 supplied_md5_b64(NULL), supplied_etag(NULL),
-		 data_pending(false), delete_at(0) {}
+		 data_pending(false) {}
 
   virtual void init(RGWRados *store, struct req_state *s, RGWHandler *h) {
     RGWOp::init(store, s, h);
@@ -756,6 +767,7 @@ protected:
   RGWAccessControlPolicy policy;
   RGWCORSConfiguration cors_config;
   string placement_rule;
+  string swift_ver_location;
 
 public:
   RGWPutMetadataBucket()
@@ -781,13 +793,12 @@ class RGWPutMetadataObject : public RGWOp {
 protected:
   RGWAccessControlPolicy policy;
   string placement_rule;
-  time_t delete_at;
+  ceph::real_time delete_at;
   const char *dlo_manifest;
 
 public:
   RGWPutMetadataObject()
-    : delete_at(0),
-      dlo_manifest(NULL)
+    : dlo_manifest(NULL)
   {}
 
   virtual void init(RGWRados *store, struct req_state *s, RGWHandler *h) {
@@ -811,12 +822,15 @@ protected:
   bool delete_marker;
   bool multipart_delete;
   string version_id;
+  ceph::real_time unmod_since; /* if unmodified since */
+  bool no_precondition_error;
   std::unique_ptr<RGWBulkDelete::Deleter> deleter;
 
 public:
   RGWDeleteObj()
     : delete_marker(false),
       multipart_delete(false),
+      no_precondition_error(false),
       deleter(nullptr) {
   }
 
@@ -825,7 +839,7 @@ public:
   void execute();
   int handle_slo_manifest(bufferlist& bl);
 
-  virtual int get_params() { return 0; };
+  virtual int get_params() { return 0; }
   virtual void send_response() = 0;
   virtual const string name() { return "delete_obj"; }
   virtual RGWOpType get_type() { return RGW_OP_DELETE_OBJ; }
@@ -843,10 +857,10 @@ protected:
   off_t ofs;
   off_t len;
   off_t end;
-  time_t mod_time;
-  time_t unmod_time;
-  time_t *mod_ptr;
-  time_t *unmod_ptr;
+  ceph::real_time mod_time;
+  ceph::real_time unmod_time;
+  ceph::real_time *mod_ptr;
+  ceph::real_time *unmod_ptr;
   map<string, bufferlist> attrs;
   string src_tenant_name, src_bucket_name;
   rgw_bucket src_bucket;
@@ -854,8 +868,8 @@ protected:
   string dest_tenant_name, dest_bucket_name;
   rgw_bucket dest_bucket;
   string dest_object;
-  time_t src_mtime;
-  time_t mtime;
+  ceph::real_time src_mtime;
+  ceph::real_time mtime;
   RGWRados::AttrsMod attrs_mod;
   RGWBucketInfo src_bucket_info;
   RGWBucketInfo dest_bucket_info;
@@ -869,7 +883,8 @@ protected:
   string version_id;
   uint64_t olh_epoch;
 
-  time_t delete_at;
+  ceph::real_time delete_at;
+  bool copy_if_newer;
 
   int init_common();
 
@@ -882,16 +897,12 @@ public:
     ofs = 0;
     len = 0;
     end = -1;
-    mod_time = 0;
-    unmod_time = 0;
     mod_ptr = NULL;
     unmod_ptr = NULL;
-    src_mtime = 0;
-    mtime = 0;
     attrs_mod = RGWRados::ATTRSMOD_NONE;
     last_ofs = 0;
     olh_epoch = 0;
-    delete_at = 0;
+    copy_if_newer = false;
   }
 
   static bool parse_copy_location(const string& src,
@@ -1297,7 +1308,6 @@ public:
   virtual uint32_t op_mask() { return RGW_OP_TYPE_DELETE; }
 };
 
-
 class RGWHandler {
 protected:
   RGWRados *store;
@@ -1306,31 +1316,171 @@ protected:
   int do_init_permissions();
   int do_read_permissions(RGWOp *op, bool only_bucket);
 
-  virtual RGWOp *op_get() { return NULL; }
-  virtual RGWOp *op_put() { return NULL; }
-  virtual RGWOp *op_delete() { return NULL; }
-  virtual RGWOp *op_head() { return NULL; }
-  virtual RGWOp *op_post() { return NULL; }
-  virtual RGWOp *op_copy() { return NULL; }
-  virtual RGWOp *op_options() { return NULL; }
 public:
   RGWHandler() : store(NULL), s(NULL) {}
   virtual ~RGWHandler();
-  virtual int init(RGWRados *store, struct req_state *_s, RGWClientIO *cio);
 
-  virtual RGWOp *get_op(RGWRados *store);
-  virtual void put_op(RGWOp *op);
+  virtual int init(RGWRados* store, struct req_state* _s, RGWClientIO* cio);
+
   virtual int init_permissions(RGWOp *op) {
     return 0;
   }
+
   virtual int retarget(RGWOp *op, RGWOp **new_op) {
     *new_op = op;
     return 0;
   }
+
   virtual int read_permissions(RGWOp *op) = 0;
   virtual int authorize() = 0;
   virtual int postauth_init() = 0;
   virtual int error_handler(int err_no, string *error_content);
 };
 
-#endif
+extern int rgw_build_bucket_policies(RGWRados* store, struct req_state* s);
+
+static inline int put_data_and_throttle(RGWPutObjProcessor *processor,
+					bufferlist& data, off_t ofs,
+					MD5 *hash, bool need_to_wait)
+{
+  bool again;
+
+  do {
+    void *handle;
+
+    int ret = processor->handle_data(data, ofs, hash, &handle, &again);
+    if (ret < 0)
+      return ret;
+
+    ret = processor->throttle_data(handle, need_to_wait);
+    if (ret < 0)
+      return ret;
+
+    need_to_wait = false; /* the need to wait only applies to the first
+			   * iteration */
+  } while (again);
+
+  return 0;
+} /* put_data_and_throttle */
+
+static inline int get_system_versioning_params(req_state *s,
+					      uint64_t *olh_epoch,
+					      string *version_id)
+{
+  if (!s->system_request) {
+    return 0;
+  }
+
+  if (olh_epoch) {
+    string epoch_str = s->info.args.get(RGW_SYS_PARAM_PREFIX "versioned-epoch");
+    if (!epoch_str.empty()) {
+      string err;
+      *olh_epoch = strict_strtol(epoch_str.c_str(), 10, &err);
+      if (!err.empty()) {
+        lsubdout(s->cct, rgw, 0) << "failed to parse versioned-epoch param"
+				 << dendl;
+        return -EINVAL;
+      }
+    }
+  }
+
+  if (version_id) {
+    *version_id = s->info.args.get(RGW_SYS_PARAM_PREFIX "version-id");
+  }
+
+  return 0;
+} /* get_system_versioning_params */
+
+static inline void format_xattr(std::string &xattr)
+{
+  /* If the extended attribute is not valid UTF-8, we encode it using
+   * quoted-printable encoding.
+   */
+  if ((check_utf8(xattr.c_str(), xattr.length()) != 0) ||
+      (check_for_control_characters(xattr.c_str(), xattr.length()) != 0)) {
+    static const char MIME_PREFIX_STR[] = "=?UTF-8?Q?";
+    static const int MIME_PREFIX_LEN = sizeof(MIME_PREFIX_STR) - 1;
+    static const char MIME_SUFFIX_STR[] = "?=";
+    static const int MIME_SUFFIX_LEN = sizeof(MIME_SUFFIX_STR) - 1;
+    int mlen = mime_encode_as_qp(xattr.c_str(), NULL, 0);
+    char *mime = new char[MIME_PREFIX_LEN + mlen + MIME_SUFFIX_LEN + 1];
+    strcpy(mime, MIME_PREFIX_STR);
+    mime_encode_as_qp(xattr.c_str(), mime + MIME_PREFIX_LEN, mlen);
+    strcpy(mime + MIME_PREFIX_LEN + (mlen - 1), MIME_SUFFIX_STR);
+    xattr.assign(mime);
+    delete [] mime;
+  }
+} /* format_xattr */
+
+/**
+ * Get the HTTP request metadata out of the req_state as a
+ * map(<attr_name, attr_contents>, where attr_name is RGW_ATTR_PREFIX.HTTP_NAME)
+ * s: The request state
+ * attrs: will be filled up with attrs mapped as <attr_name, attr_contents>
+ *
+ */
+static inline void rgw_get_request_metadata(CephContext *cct,
+					    struct req_info& info,
+					    map<string, bufferlist>& attrs,
+					    const bool allow_empty_attrs = true)
+{
+  map<string, string>::iterator iter;
+  for (iter = info.x_meta_map.begin(); iter != info.x_meta_map.end(); ++iter) {
+    const string &name(iter->first);
+    string &xattr(iter->second);
+
+    if (allow_empty_attrs || !xattr.empty()) {
+      lsubdout(cct, rgw, 10) << "x>> " << name << ":" << xattr << dendl;
+      format_xattr(xattr);
+      string attr_name(RGW_ATTR_PREFIX);
+      attr_name.append(name);
+      map<string, bufferlist>::value_type v(attr_name, bufferlist());
+      std::pair < map<string, bufferlist>::iterator, bool >
+	rval(attrs.insert(v));
+      bufferlist& bl(rval.first->second);
+      bl.append(xattr.c_str(), xattr.size() + 1);
+    }
+  }
+} /* rgw_get_request_metadata */
+
+static inline void encode_delete_at_attr(ceph::real_time delete_at,
+					map<string, bufferlist>& attrs)
+{
+  if (real_clock::is_zero(delete_at)) {
+    return;
+  }
+
+  bufferlist delatbl;
+  ::encode(delete_at, delatbl);
+  attrs[RGW_ATTR_DELETE_AT] = delatbl;
+} /* encode_delete_at_attr */
+
+static inline int encode_dlo_manifest_attr(const char * const dlo_manifest,
+					  map<string, bufferlist>& attrs)
+{
+  string dm = dlo_manifest;
+
+  if (dm.find('/') == string::npos) {
+    return -EINVAL;
+  }
+
+  bufferlist manifest_bl;
+  manifest_bl.append(dlo_manifest, strlen(dlo_manifest) + 1);
+  attrs[RGW_ATTR_USER_MANIFEST] = manifest_bl;
+
+  return 0;
+} /* encode_dlo_manifest_attr */
+
+static inline void complete_etag(MD5& hash, string *etag)
+{
+  char etag_buf[CEPH_CRYPTO_MD5_DIGESTSIZE];
+  char etag_buf_str[CEPH_CRYPTO_MD5_DIGESTSIZE * 2 + 16];
+
+  hash.Final((byte *)etag_buf);
+  buf_to_hex((const unsigned char *)etag_buf, CEPH_CRYPTO_MD5_DIGESTSIZE,
+	    etag_buf_str);
+
+  *etag = etag_buf_str;
+} /* complete_etag */
+
+#endif /* CEPH_RGW_OP_H */
diff --git a/src/rgw/rgw_orphan.cc b/src/rgw/rgw_orphan.cc
index f59e1f7..52dc8d7 100644
--- a/src/rgw/rgw_orphan.cc
+++ b/src/rgw/rgw_orphan.cc
@@ -454,7 +454,7 @@ int RGWOrphanSearch::build_linked_oids_for_bucket(const string& bucket_instance_
     return ret;
   }
 
-  RGWRados::Bucket target(store, bucket_info.bucket);
+  RGWRados::Bucket target(store, bucket_info);
   RGWRados::Bucket::List list_op(&target);
 
   string marker;
@@ -578,7 +578,11 @@ int RGWOrphanSearch::build_linked_oids_index()
     return ret;
   }
 
-  save_state();
+  ret = save_state();
+  if (ret < 0) {
+    cerr << __func__ << ": ERROR: failed to write state ret=" << ret << std::endl;
+    return ret;
+  }
 
   return 0;
 }
diff --git a/src/rgw/rgw_os_lib.cc b/src/rgw/rgw_os_lib.cc
new file mode 100644
index 0000000..e43bf41
--- /dev/null
+++ b/src/rgw/rgw_os_lib.cc
@@ -0,0 +1,62 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+
+#include "rgw_rest.h"
+#include "rgw_rest_s3.h"
+#include "rgw_rest_user.h"
+#include "rgw_os_lib.h"
+#include "rgw_file.h"
+#include "rgw_lib_frontend.h"
+
+namespace rgw {
+
+/* static */
+  int RGWHandler_Lib::init_from_header(struct req_state *s)
+  {
+    string req;
+    string first;
+
+    const char *req_name = s->relative_uri.c_str();
+    const char *p;
+
+    /* skip request_params parsing, rgw_file should not be
+     * seeing any */
+    if (*req_name == '?') {
+      p = req_name;
+    } else {
+      p = s->info.request_params.c_str();
+    }
+
+    s->info.args.set(p);
+    s->info.args.parse();
+
+    if (*req_name != '/')
+      return 0;
+
+    req_name++;
+
+    if (!*req_name)
+      return 0;
+
+    req = req_name;
+    int pos = req.find('/');
+    if (pos >= 0) {
+      first = req.substr(0, pos);
+    } else {
+      first = req;
+    }
+
+    if (s->bucket_name.empty()) {
+      s->bucket_name = std::move(first);
+      if (pos >= 0) {
+	// XXX ugh, another copy
+	string encoded_obj_str = req.substr(pos+1);
+	s->object = rgw_obj_key(encoded_obj_str, s->info.args.get("versionId"));
+      }
+    } else {
+      s->object = rgw_obj_key(req_name, s->info.args.get("versionId"));
+    }
+    return 0;
+  } /* init_from_header */
+
+} /* namespace rgw */
diff --git a/src/rgw/rgw_os_lib.h b/src/rgw/rgw_os_lib.h
new file mode 100644
index 0000000..78071b7
--- /dev/null
+++ b/src/rgw/rgw_os_lib.h
@@ -0,0 +1,12 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+
+#ifndef RGW_OS_LIB_H
+#define RGW_OS_LIB_H
+
+#include <functional>
+#include "rgw_common.h"
+#include "rgw_lib.h"
+
+
+#endif /* RGW_OS_LIB_H */
diff --git a/src/rgw/rgw_period_history.cc b/src/rgw/rgw_period_history.cc
new file mode 100644
index 0000000..2992623
--- /dev/null
+++ b/src/rgw/rgw_period_history.cc
@@ -0,0 +1,340 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+
+#include "rgw_period_history.h"
+#include "rgw_rados.h"
+
+#define dout_subsys ceph_subsys_rgw
+
+#undef dout_prefix
+#define dout_prefix (*_dout << "rgw period history: ")
+
+/// an ordered history of consecutive periods
+class RGWPeriodHistory::History : public bi::avl_set_base_hook<> {
+ public:
+  std::deque<RGWPeriod> periods;
+
+  epoch_t get_oldest_epoch() const {
+    return periods.front().get_realm_epoch();
+  }
+  epoch_t get_newest_epoch() const {
+    return periods.back().get_realm_epoch();
+  }
+  bool contains(epoch_t epoch) const {
+    return get_oldest_epoch() <= epoch && epoch <= get_newest_epoch();
+  }
+  RGWPeriod& get(epoch_t epoch) {
+    return periods[epoch - get_oldest_epoch()];
+  }
+  const RGWPeriod& get(epoch_t epoch) const {
+    return periods[epoch - get_oldest_epoch()];
+  }
+  const std::string& get_predecessor_id() const {
+    return periods.front().get_predecessor();
+  }
+};
+
+/// value comparison for avl_set
+bool operator<(const RGWPeriodHistory::History& lhs,
+               const RGWPeriodHistory::History& rhs)
+{
+  return lhs.get_newest_epoch() < rhs.get_newest_epoch();
+}
+
+/// key-value comparison for avl_set
+struct NewestEpochLess {
+  bool operator()(const RGWPeriodHistory::History& value, epoch_t key) const {
+    return value.get_newest_epoch() < key;
+  }
+};
+
+
+using Cursor = RGWPeriodHistory::Cursor;
+
+const RGWPeriod& Cursor::get_period() const
+{
+  std::lock_guard<std::mutex> lock(*mutex);
+  return history->get(epoch);
+}
+bool Cursor::has_prev() const
+{
+  std::lock_guard<std::mutex> lock(*mutex);
+  return epoch > history->get_oldest_epoch();
+}
+bool Cursor::has_next() const
+{
+  std::lock_guard<std::mutex> lock(*mutex);
+  return epoch < history->get_newest_epoch();
+}
+
+
+class RGWPeriodHistory::Impl final {
+ public:
+  Impl(CephContext* cct, Puller* puller, const RGWPeriod& current_period);
+  ~Impl();
+
+  Cursor get_current() const { return current_cursor; }
+  Cursor attach(RGWPeriod&& period);
+  Cursor insert(RGWPeriod&& period);
+  Cursor lookup(epoch_t realm_epoch);
+
+ private:
+  /// an intrusive set of histories, ordered by their newest epoch. although
+  /// the newest epoch of each history is mutable, the ordering cannot change
+  /// because we prevent the histories from overlapping
+  using Set = bi::avl_set<RGWPeriodHistory::History>;
+
+  /// insert the given period into the period history, creating new unconnected
+  /// histories or merging existing histories as necessary. expects the caller
+  /// to hold a lock on mutex. returns a valid cursor regardless of whether it
+  /// ends up in current_history, though cursors in other histories are only
+  /// valid within the context of the lock
+  Cursor insert_locked(RGWPeriod&& period);
+
+  /// merge the periods from the src history onto the end of the dst history,
+  /// and return an iterator to the merged history
+  Set::iterator merge(Set::iterator dst, Set::iterator src);
+
+  /// construct a Cursor object using Cursor's private constuctor
+  Cursor make_cursor(Set::const_iterator history, epoch_t epoch);
+
+  CephContext *const cct;
+  Puller *const puller; //< interface for pulling missing periods
+  Cursor current_cursor; //< Cursor to realm's current period
+
+  mutable std::mutex mutex; //< protects the histories
+
+  /// set of disjoint histories that are missing intermediate periods needed to
+  /// connect them together
+  Set histories;
+
+  /// iterator to the history that contains the realm's current period
+  Set::const_iterator current_history;
+};
+
+RGWPeriodHistory::Impl::Impl(CephContext* cct, Puller* puller,
+                             const RGWPeriod& current_period)
+  : cct(cct), puller(puller)
+{
+  if (!current_period.get_id().empty()) {
+    // copy the current period into a new history
+    auto history = new History;
+    history->periods.push_back(current_period);
+
+    // insert as our current history
+    current_history = histories.insert(*history).first;
+
+    // get a cursor to the current period
+    current_cursor = make_cursor(current_history, current_period.get_realm_epoch());
+  }
+}
+
+RGWPeriodHistory::Impl::~Impl()
+{
+  // clear the histories and delete each entry
+  histories.clear_and_dispose(std::default_delete<History>{});
+}
+
+Cursor RGWPeriodHistory::Impl::attach(RGWPeriod&& period)
+{
+  if (current_history == histories.end()) {
+    return Cursor{-EINVAL};
+  }
+
+  const auto epoch = period.get_realm_epoch();
+
+  std::string predecessor_id;
+  for (;;) {
+    {
+      // hold the lock over insert, and while accessing the unsafe cursor
+      std::lock_guard<std::mutex> lock(mutex);
+
+      auto cursor = insert_locked(std::move(period));
+      if (!cursor) {
+        return cursor;
+      }
+      if (current_history->contains(epoch)) {
+        break; // the history is complete
+      }
+
+      // take the predecessor id of the most recent history
+      if (cursor.get_epoch() > current_cursor.get_epoch()) {
+        predecessor_id = cursor.history->get_predecessor_id();
+      } else {
+        predecessor_id = current_history->get_predecessor_id();
+      }
+    }
+
+    if (predecessor_id.empty()) {
+      lderr(cct) << "reached a period with an empty predecessor id" << dendl;
+      return Cursor{-EINVAL};
+    }
+
+    // pull the period outside of the lock
+    int r = puller->pull(predecessor_id, period);
+    if (r < 0) {
+      return Cursor{r};
+    }
+  }
+
+  // return a cursor to the requested period
+  return make_cursor(current_history, epoch);
+}
+
+Cursor RGWPeriodHistory::Impl::insert(RGWPeriod&& period)
+{
+  if (current_history == histories.end()) {
+    return Cursor{-EINVAL};
+  }
+
+  std::lock_guard<std::mutex> lock(mutex);
+
+  auto cursor = insert_locked(std::move(period));
+
+  if (cursor.get_error()) {
+    return cursor;
+  }
+  // we can only provide cursors that are safe to use outside of the mutex if
+  // they're within the current_history, because other histories can disappear
+  // in a merge. see merge() for the special handling of current_history
+  if (cursor.history == &*current_history) {
+    return cursor;
+  }
+  return Cursor{};
+}
+
+Cursor RGWPeriodHistory::Impl::lookup(epoch_t realm_epoch)
+{
+  if (current_history != histories.end() &&
+      current_history->contains(realm_epoch)) {
+    return make_cursor(current_history, realm_epoch);
+  }
+  return Cursor{};
+}
+
+Cursor RGWPeriodHistory::Impl::insert_locked(RGWPeriod&& period)
+{
+  auto epoch = period.get_realm_epoch();
+
+  // find the first history whose newest epoch comes at or after this period
+  auto i = histories.lower_bound(epoch, NewestEpochLess{});
+
+  if (i == histories.end()) {
+    // epoch is past the end of our newest history
+    auto last = --Set::iterator{i}; // last = i - 1
+
+    if (epoch == last->get_newest_epoch() + 1) {
+      // insert at the back of the last history
+      last->periods.emplace_back(std::move(period));
+      return make_cursor(last, epoch);
+    }
+
+    // create a new history for this period
+    auto history = new History;
+    history->periods.emplace_back(std::move(period));
+    histories.insert(last, *history);
+
+    i = Set::s_iterator_to(*history);
+    return make_cursor(i, epoch);
+  }
+
+  if (i->contains(epoch)) {
+    // already resident in this history
+    auto& existing = i->get(epoch);
+    // verify that the period ids match; otherwise we've forked the history
+    if (period.get_id() != existing.get_id()) {
+      lderr(cct) << "Got two different periods, " << period.get_id()
+          << " and " << existing.get_id() << ", with the same realm epoch "
+          << epoch << "! This indicates a fork in the period history." << dendl;
+      return Cursor{-EEXIST};
+    }
+    // update the existing period if we got a newer period epoch
+    if (period.get_epoch() > existing.get_epoch()) {
+      existing = std::move(period);
+    }
+    return make_cursor(i, epoch);
+  }
+
+  if (epoch + 1 == i->get_oldest_epoch()) {
+    // insert at the front of this history
+    i->periods.emplace_front(std::move(period));
+
+    // try to merge with the previous history
+    if (i != histories.begin()) {
+      auto prev = --Set::iterator{i};
+      if (epoch == prev->get_newest_epoch() + 1) {
+        i = merge(prev, i);
+      }
+    }
+    return make_cursor(i, epoch);
+  }
+
+  if (i != histories.begin()) {
+    auto prev = --Set::iterator{i};
+    if (epoch == prev->get_newest_epoch() + 1) {
+      // insert at the back of the previous history
+      prev->periods.emplace_back(std::move(period));
+      return make_cursor(prev, epoch);
+    }
+  }
+
+  // create a new history for this period
+  auto history = new History;
+  history->periods.emplace_back(std::move(period));
+  histories.insert(i, *history);
+
+  i = Set::s_iterator_to(*history);
+  return make_cursor(i, epoch);
+}
+
+RGWPeriodHistory::Impl::Set::iterator
+RGWPeriodHistory::Impl::merge(Set::iterator dst, Set::iterator src)
+{
+  assert(dst->get_newest_epoch() + 1 == src->get_oldest_epoch());
+
+  // always merge into current_history
+  if (src == current_history) {
+    // move the periods from dst onto the front of src
+    src->periods.insert(src->periods.begin(),
+                        std::make_move_iterator(dst->periods.begin()),
+                        std::make_move_iterator(dst->periods.end()));
+    histories.erase_and_dispose(dst, std::default_delete<History>{});
+    return src;
+  }
+
+  // move the periods from src onto the end of dst
+  dst->periods.insert(dst->periods.end(),
+                      std::make_move_iterator(src->periods.begin()),
+                      std::make_move_iterator(src->periods.end()));
+  histories.erase_and_dispose(src, std::default_delete<History>{});
+  return dst;
+}
+
+Cursor RGWPeriodHistory::Impl::make_cursor(Set::const_iterator history,
+                                           epoch_t epoch) {
+  return Cursor{&*history, &mutex, epoch};
+}
+
+
+RGWPeriodHistory::RGWPeriodHistory(CephContext* cct, Puller* puller,
+                                   const RGWPeriod& current_period)
+  : impl(new Impl(cct, puller, current_period)) {}
+
+RGWPeriodHistory::~RGWPeriodHistory() = default;
+
+Cursor RGWPeriodHistory::get_current() const
+{
+  return impl->get_current();
+}
+Cursor RGWPeriodHistory::attach(RGWPeriod&& period)
+{
+  return impl->attach(std::move(period));
+}
+Cursor RGWPeriodHistory::insert(RGWPeriod&& period)
+{
+  return impl->insert(std::move(period));
+}
+Cursor RGWPeriodHistory::lookup(epoch_t realm_epoch)
+{
+  return impl->lookup(realm_epoch);
+}
diff --git a/src/rgw/rgw_period_history.h b/src/rgw/rgw_period_history.h
new file mode 100644
index 0000000..9541493
--- /dev/null
+++ b/src/rgw/rgw_period_history.h
@@ -0,0 +1,111 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+
+#ifndef RGW_PERIOD_HISTORY_H
+#define RGW_PERIOD_HISTORY_H
+
+#include <deque>
+#include <mutex>
+#include <system_error>
+#include <boost/intrusive/avl_set.hpp>
+#include "include/assert.h"
+#include "include/types.h"
+
+namespace bi = boost::intrusive;
+
+class RGWPeriod;
+
+/**
+ * RGWPeriodHistory tracks the relative history of all inserted periods,
+ * coordinates the pulling of missing intermediate periods, and provides a
+ * Cursor object for traversing through the connected history.
+ */
+class RGWPeriodHistory final {
+ private:
+  /// an ordered history of consecutive periods
+  class History;
+
+  // comparisons for avl_set ordering
+  friend bool operator<(const History& lhs, const History& rhs);
+  friend struct NewestEpochLess;
+
+  class Impl;
+  std::unique_ptr<Impl> impl;
+
+ public:
+  /**
+   * Puller is a synchronous interface for pulling periods from the master
+   * zone. The abstraction exists mainly to support unit testing.
+   */
+  class Puller {
+   public:
+    virtual ~Puller() = default;
+
+    virtual int pull(const std::string& period_id, RGWPeriod& period) = 0;
+  };
+
+  RGWPeriodHistory(CephContext* cct, Puller* puller,
+                   const RGWPeriod& current_period);
+  ~RGWPeriodHistory();
+
+  /**
+   * Cursor tracks a position in the period history and allows forward and
+   * backward traversal. Only periods that are fully connected to the
+   * current_period are reachable via a Cursor, because other histories are
+   * temporary and can be merged away. Cursors to periods in disjoint
+   * histories, as provided by insert() or lookup(), are therefore invalid and
+   * their operator bool() will return false.
+   */
+  class Cursor final {
+   public:
+    Cursor() = default;
+    explicit Cursor(int error) : error(error) {}
+
+    int get_error() const { return error; }
+
+    /// return false for a default-constructed or error Cursor
+    operator bool() const { return history != nullptr; }
+
+    epoch_t get_epoch() const { return epoch; }
+    const RGWPeriod& get_period() const;
+
+    bool has_prev() const;
+    bool has_next() const;
+
+    void prev() { epoch--; }
+    void next() { epoch++; }
+
+   private:
+    // private constructors for RGWPeriodHistory
+    friend class RGWPeriodHistory::Impl;
+
+    Cursor(const History* history, std::mutex* mutex, epoch_t epoch)
+      : history(history), mutex(mutex), epoch(epoch) {}
+
+    int error{0};
+    const History* history{nullptr};
+    std::mutex* mutex{nullptr};
+    epoch_t epoch{0}; //< realm epoch of cursor position
+  };
+
+  /// return a cursor to the current period
+  Cursor get_current() const;
+
+  /// build up a connected period history that covers the span between
+  /// current_period and the given period, reading predecessor periods or
+  /// fetching them from the master as necessary. returns a cursor at the
+  /// given period that can be used to traverse the current_history
+  Cursor attach(RGWPeriod&& period);
+
+  /// insert the given period into an existing history, or create a new
+  /// unconnected history. similar to attach(), but it doesn't try to fetch
+  /// missing periods. returns a cursor to the inserted period iff it's in
+  /// the current_history
+  Cursor insert(RGWPeriod&& period);
+
+  /// search for a period by realm epoch, returning a valid Cursor iff it's in
+  /// the current_history
+  Cursor lookup(epoch_t realm_epoch);
+};
+
+#endif // RGW_PERIOD_HISTORY_H
diff --git a/src/rgw/rgw_period_puller.cc b/src/rgw/rgw_period_puller.cc
new file mode 100644
index 0000000..a35591c
--- /dev/null
+++ b/src/rgw/rgw_period_puller.cc
@@ -0,0 +1,97 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+
+#include "rgw_rados.h"
+#include "rgw_rest_conn.h"
+#include "common/ceph_json.h"
+#include "common/errno.h"
+
+#define dout_subsys ceph_subsys_rgw
+
+#undef dout_prefix
+#define dout_prefix (*_dout << "rgw period puller: ")
+
+namespace {
+
+// pull the given period over the connection
+int pull_period(RGWRESTConn* conn, const std::string& period_id,
+                const std::string& realm_id, RGWPeriod& period)
+{
+  rgw_user user;
+  RGWEnv env;
+  req_info info(conn->get_ctx(), &env);
+  info.method = "GET";
+  info.request_uri = "/admin/realm/period";
+
+  auto& params = info.args.get_params();
+  params["realm_id"] = realm_id;
+  params["period_id"] = period_id;
+
+  bufferlist data;
+#define MAX_REST_RESPONSE (128 * 1024)
+  int r = conn->forward(user, info, nullptr, MAX_REST_RESPONSE, nullptr, &data);
+  if (r < 0) {
+    return r;
+  }
+
+  JSONParser parser;
+  r = parser.parse(data.c_str(), data.length());
+  if (r < 0) {
+    lderr(conn->get_ctx()) << "request failed: " << cpp_strerror(-r) << dendl;
+    return r;
+  }
+
+  try {
+    decode_json_obj(period, &parser);
+  } catch (JSONDecoder::err& e) {
+    lderr(conn->get_ctx()) << "failed to decode JSON input: "
+        << e.message << dendl;
+    return -EINVAL;
+  }
+  return 0;
+}
+
+} // anonymous namespace
+
+int RGWPeriodPuller::pull(const std::string& period_id, RGWPeriod& period)
+{
+  // try to read the period from rados
+  period.set_id(period_id);
+  int r = period.init(store->ctx(), store);
+  if (r < 0) {
+    ldout(store->ctx(), 14) << "pulling period " << period_id
+        << " from master" << dendl;
+    // request the period from the master zone
+    r = pull_period(store->rest_master_conn, period_id,
+                    store->realm.get_id(), period);
+    if (r < 0) {
+      lderr(store->ctx()) << "failed to pull period " << period_id << dendl;
+      return r;
+    }
+    // write the period to rados
+    r = period.store_info(true);
+    if (r == -EEXIST) {
+      r = 0;
+    } else if (r < 0) {
+      lderr(store->ctx()) << "failed to store period " << period_id << dendl;
+      return r;
+    }
+    // XXX: if this is a newer epoch, we should overwrite the existing
+    // latest_epoch. but there's no way to do that atomically
+    bool exclusive = true;
+    r = period.set_latest_epoch(period.get_epoch(), exclusive);
+    if (r == -EEXIST) {
+      r = 0;
+    } else if (r < 0) {
+      lderr(store->ctx()) << "failed to update latest_epoch for period "
+          << period_id << dendl;
+      return r;
+    }
+    ldout(store->ctx(), 14) << "period " << period_id
+        << " pulled and written to local storage" << dendl;
+  } else {
+    ldout(store->ctx(), 14) << "found period " << period_id
+        << " in local storage" << dendl;
+  }
+  return 0;
+}
diff --git a/src/rgw/rgw_period_puller.h b/src/rgw/rgw_period_puller.h
new file mode 100644
index 0000000..1cb8998
--- /dev/null
+++ b/src/rgw/rgw_period_puller.h
@@ -0,0 +1,20 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+
+#ifndef CEPH_RGW_PERIOD_PULLER_H
+#define CEPH_RGW_PERIOD_PULLER_H
+
+#include "rgw_period_history.h"
+
+class RGWRados;
+class RGWPeriod;
+
+class RGWPeriodPuller : public RGWPeriodHistory::Puller {
+  RGWRados *const store;
+ public:
+  RGWPeriodPuller(RGWRados* store) : store(store) {}
+
+  int pull(const std::string& period_id, RGWPeriod& period) override;
+};
+
+#endif // CEPH_RGW_PERIOD_PULLER_H
diff --git a/src/rgw/rgw_period_pusher.cc b/src/rgw/rgw_period_pusher.cc
new file mode 100644
index 0000000..10bf86e
--- /dev/null
+++ b/src/rgw/rgw_period_pusher.cc
@@ -0,0 +1,301 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+
+#include <map>
+#include <thread>
+
+#include "rgw_period_pusher.h"
+#include "rgw_cr_rest.h"
+#include "common/errno.h"
+
+#include "rgw_boost_asio_yield.h"
+
+#define dout_subsys ceph_subsys_rgw
+
+#undef dout_prefix
+#define dout_prefix (*_dout << "rgw period pusher: ")
+
+/// A coroutine to post the period over the given connection.
+using PushCR = RGWPostRESTResourceCR<RGWPeriod, int>;
+
+/// A coroutine that calls PushCR, and retries with backoff until success.
+class PushAndRetryCR : public RGWCoroutine {
+  const std::string& zone;
+  RGWRESTConn *const conn;
+  RGWHTTPManager *const http;
+  RGWPeriod& period;
+  const std::string epoch; //< epoch string for params
+  double timeout; //< current interval between retries
+  const double timeout_max; //< maximum interval between retries
+  uint32_t counter; //< number of failures since backoff increased
+
+ public:
+  PushAndRetryCR(CephContext* cct, const std::string& zone, RGWRESTConn* conn,
+                 RGWHTTPManager* http, RGWPeriod& period)
+    : RGWCoroutine(cct), zone(zone), conn(conn), http(http), period(period),
+      epoch(std::to_string(period.get_epoch())),
+      timeout(cct->_conf->rgw_period_push_interval),
+      timeout_max(cct->_conf->rgw_period_push_interval_max),
+      counter(0)
+  {}
+
+  int operate() override;
+};
+
+int PushAndRetryCR::operate()
+{
+  reenter(this) {
+    for (;;) {
+      yield {
+        ldout(cct, 10) << "pushing period " << period.get_id()
+            << " to " << zone << dendl;
+        // initialize the http params
+        rgw_http_param_pair params[] = {
+          { "period", period.get_id().c_str() },
+          { "epoch", epoch.c_str() },
+          { nullptr, nullptr }
+        };
+        call(new PushCR(cct, conn, http, "/admin/realm/period",
+                        params, period, nullptr));
+      }
+
+      // stop on success
+      if (get_ret_status() == 0) {
+        ldout(cct, 10) << "push to " << zone << " succeeded" << dendl;
+        return set_cr_done();
+      }
+
+      // try each endpoint in the connection before waiting
+      if (++counter < conn->get_endpoint_count())
+        continue;
+      counter = 0;
+
+      // wait with exponential backoff up to timeout_max
+      yield {
+        utime_t dur;
+        dur.set_from_double(timeout);
+
+        ldout(cct, 10) << "waiting " << dur << "s for retry.." << dendl;
+        wait(dur);
+
+        timeout *= 2;
+        if (timeout > timeout_max)
+          timeout = timeout_max;
+      }
+    }
+  }
+  return 0;
+}
+
+/**
+ * PushAllCR is a coroutine that sends the period over all of the given
+ * connections, retrying until they are all marked as completed.
+ */
+class PushAllCR : public RGWCoroutine {
+  RGWHTTPManager *const http;
+  RGWPeriod period; //< period object to push
+  std::map<std::string, RGWRESTConn> conns; //< zones that need the period
+
+ public:
+  PushAllCR(CephContext* cct, RGWHTTPManager* http, RGWPeriod&& period,
+            std::map<std::string, RGWRESTConn>&& conns)
+    : RGWCoroutine(cct), http(http),
+      period(std::move(period)),
+      conns(std::move(conns))
+  {}
+
+  int operate() override;
+};
+
+int PushAllCR::operate()
+{
+  reenter(this) {
+    // spawn a coroutine to push the period over each connection
+    yield {
+      ldout(cct, 4) << "sending " << conns.size() << " periods" << dendl;
+      for (auto& c : conns)
+        spawn(new PushAndRetryCR(cct, c.first, &c.second, http, period), false);
+    }
+    // wait for all to complete
+    drain_all();
+    return set_cr_done();
+  }
+  return 0;
+}
+
+/// A background thread to run the PushAllCR coroutine and exit.
+class RGWPeriodPusher::CRThread {
+  RGWCoroutinesManager coroutines;
+  RGWHTTPManager http;
+  boost::intrusive_ptr<PushAllCR> push_all;
+  std::thread thread;
+
+ public:
+  CRThread(CephContext* cct, RGWPeriod&& period,
+           std::map<std::string, RGWRESTConn>&& conns)
+    : coroutines(cct, NULL),
+      http(cct, coroutines.get_completion_mgr()),
+      push_all(new PushAllCR(cct, &http, std::move(period), std::move(conns))),
+      thread([this] { coroutines.run(push_all.get()); })
+  {
+    http.set_threaded();
+  }
+  ~CRThread()
+  {
+    push_all.reset();
+    coroutines.stop();
+    if (thread.joinable())
+      thread.join();
+  }
+};
+
+
+RGWPeriodPusher::RGWPeriodPusher(RGWRados* store)
+  : cct(store->ctx()), store(store)
+{
+  const auto& realm = store->realm;
+  auto& realm_id = realm.get_id();
+  if (realm_id.empty()) // no realm configuration
+    return;
+
+  // always send out the current period on startup
+  RGWPeriod period;
+  int r = period.init(cct, store, realm_id, realm.get_name());
+  if (r < 0) {
+    lderr(cct) << "failed to load period for realm " << realm_id << dendl;
+    return;
+  }
+
+  std::lock_guard<std::mutex> lock(mutex);
+  handle_notify(std::move(period));
+}
+
+// destructor is here because CRThread is incomplete in the header
+RGWPeriodPusher::~RGWPeriodPusher() = default;
+
+void RGWPeriodPusher::handle_notify(RGWRealmNotify type,
+                                    bufferlist::iterator& p)
+{
+  // decode the period
+  RGWZonesNeedPeriod info;
+  try {
+    ::decode(info, p);
+  } catch (buffer::error& e) {
+    lderr(cct) << "Failed to decode the period: " << e.what() << dendl;
+    return;
+  }
+
+  std::lock_guard<std::mutex> lock(mutex);
+
+  // we can't process this notification without access to our current realm
+  // configuration. queue it until resume()
+  if (store == nullptr) {
+    pending_periods.emplace_back(std::move(info));
+    return;
+  }
+
+  handle_notify(std::move(info));
+}
+
+// expects the caller to hold a lock on mutex
+void RGWPeriodPusher::handle_notify(RGWZonesNeedPeriod&& period)
+{
+  if (period.get_realm_epoch() < realm_epoch) {
+    ldout(cct, 10) << "period's realm epoch " << period.get_realm_epoch()
+        << " is not newer than current realm epoch " << realm_epoch
+        << ", discarding update" << dendl;
+    return;
+  }
+  if (period.get_realm_epoch() == realm_epoch &&
+      period.get_epoch() <= period_epoch) {
+    ldout(cct, 10) << "period epoch " << period.get_epoch() << " is not newer "
+        "than current epoch " << period_epoch << ", discarding update" << dendl;
+    return;
+  }
+
+  // find our zonegroup in the new period
+  auto& zonegroups = period.get_map().zonegroups;
+  auto i = zonegroups.find(store->get_zonegroup().get_id());
+  if (i == zonegroups.end()) {
+    lderr(cct) << "The new period does not contain my zonegroup!" << dendl;
+    return;
+  }
+  auto& my_zonegroup = i->second;
+
+  // if we're not a master zone, we're not responsible for pushing any updates
+  if (my_zonegroup.master_zone != store->get_zone_params().get_id())
+    return;
+
+  // construct a map of the zones that need this period. the map uses the same
+  // keys/ordering as the zone[group] map, so we can use a hint for insertions
+  std::map<std::string, RGWRESTConn> conns;
+  auto hint = conns.end();
+
+  // are we the master zonegroup in this period?
+  if (period.get_map().master_zonegroup == store->get_zonegroup().get_id()) {
+    // update other zonegroup endpoints
+    for (auto& zg : zonegroups) {
+      auto& zonegroup = zg.second;
+      if (zonegroup.get_id() == store->get_zonegroup().get_id())
+        continue;
+      if (zonegroup.endpoints.empty())
+        continue;
+
+      hint = conns.emplace_hint(
+          hint, std::piecewise_construct,
+          std::forward_as_tuple(zonegroup.get_id()),
+          std::forward_as_tuple(cct, store, zonegroup.get_id(), zonegroup.endpoints));
+    }
+  }
+
+  // update other zone endpoints
+  for (auto& z : my_zonegroup.zones) {
+    auto& zone = z.second;
+    if (zone.id == store->get_zone_params().get_id())
+      continue;
+    if (zone.endpoints.empty())
+      continue;
+
+    hint = conns.emplace_hint(
+        hint, std::piecewise_construct,
+        std::forward_as_tuple(zone.id),
+        std::forward_as_tuple(cct, store, zone.id, zone.endpoints));
+  }
+
+  if (conns.empty()) {
+    ldout(cct, 4) << "No zones to update" << dendl;
+    return;
+  }
+
+  realm_epoch = period.get_realm_epoch();
+  period_epoch = period.get_epoch();
+
+  ldout(cct, 4) << "Zone master pushing period " << period.get_id()
+      << " epoch " << period_epoch << " to "
+      << conns.size() << " other zones" << dendl;
+
+  // spawn a new coroutine thread, destroying the previous one
+  cr_thread.reset(new CRThread(cct, std::move(period), std::move(conns)));
+}
+
+void RGWPeriodPusher::pause()
+{
+  ldout(cct, 4) << "paused for realm update" << dendl;
+  std::lock_guard<std::mutex> lock(mutex);
+  store = nullptr;
+}
+
+void RGWPeriodPusher::resume(RGWRados* store)
+{
+  std::lock_guard<std::mutex> lock(mutex);
+  this->store = store;
+
+  ldout(cct, 4) << "resume with " << pending_periods.size()
+      << " periods pending" << dendl;
+
+  // process notification queue
+  for (auto& info : pending_periods) {
+    handle_notify(std::move(info));
+  }
+  pending_periods.clear();
+}
diff --git a/src/rgw/rgw_period_pusher.h b/src/rgw/rgw_period_pusher.h
new file mode 100644
index 0000000..ccba897
--- /dev/null
+++ b/src/rgw/rgw_period_pusher.h
@@ -0,0 +1,56 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+
+#ifndef RGW_PERIOD_PUSHER_H
+#define RGW_PERIOD_PUSHER_H
+
+#include <memory>
+#include <mutex>
+#include <vector>
+
+#include "rgw_realm_reloader.h"
+
+class RGWRados;
+class RGWPeriod;
+
+// RGWRealmNotify payload for push coordination
+using RGWZonesNeedPeriod = RGWPeriod;
+
+/**
+ * RGWPeriodPusher coordinates with other nodes via the realm watcher to manage
+ * the responsibility for pushing period updates to other zones or zonegroups.
+ */
+class RGWPeriodPusher final : public RGWRealmWatcher::Watcher,
+                              public RGWRealmReloader::Pauser {
+ public:
+  RGWPeriodPusher(RGWRados* store);
+  ~RGWPeriodPusher();
+
+  /// respond to realm notifications by pushing new periods to other zones
+  void handle_notify(RGWRealmNotify type, bufferlist::iterator& p) override;
+
+  /// avoid accessing RGWRados while dynamic reconfiguration is in progress.
+  /// notifications will be enqueued until resume()
+  void pause() override;
+
+  /// continue processing notifications with a new RGWRados instance
+  void resume(RGWRados* store) override;
+
+ private:
+  void handle_notify(RGWZonesNeedPeriod&& period);
+
+  CephContext *const cct;
+  RGWRados* store;
+
+  std::mutex mutex;
+  epoch_t realm_epoch{0}; //< the current realm epoch being sent
+  epoch_t period_epoch{0}; //< the current period epoch being sent
+
+  /// while paused for reconfiguration, we need to queue up notifications
+  std::vector<RGWZonesNeedPeriod> pending_periods;
+
+  class CRThread; //< contains thread, coroutine manager, http manager
+  std::unique_ptr<CRThread> cr_thread; //< thread to run the push coroutines
+};
+
+#endif // RGW_PERIOD_PUSHER_H
diff --git a/src/rgw/rgw_process.cc b/src/rgw/rgw_process.cc
new file mode 100644
index 0000000..6a92c49
--- /dev/null
+++ b/src/rgw/rgw_process.cc
@@ -0,0 +1,206 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+
+#include "common/errno.h"
+#include "common/Throttle.h"
+#include "common/WorkQueue.h"
+
+#include "rgw_rados.h"
+#include "rgw_rest.h"
+#include "rgw_frontend.h"
+#include "rgw_request.h"
+#include "rgw_process.h"
+#include "rgw_loadgen.h"
+#include "rgw_client_io.h"
+
+#define dout_subsys ceph_subsys_rgw
+
+void RGWProcess::RGWWQ::_dump_queue()
+{
+  if (!g_conf->subsys.should_gather(ceph_subsys_rgw, 20)) {
+    return;
+  }
+  deque<RGWRequest *>::iterator iter;
+  if (process->m_req_queue.empty()) {
+    dout(20) << "RGWWQ: empty" << dendl;
+    return;
+  }
+  dout(20) << "RGWWQ:" << dendl;
+  for (iter = process->m_req_queue.begin();
+       iter != process->m_req_queue.end(); ++iter) {
+    dout(20) << "req: " << hex << *iter << dec << dendl;
+  }
+} /* RGWProcess::RGWWQ::_dump_queue */
+
+int process_request(RGWRados* store, RGWREST* rest, RGWRequest* req,
+		    RGWStreamIO* client_io, OpsLogSocket* olog)
+{
+  int ret = 0;
+
+  client_io->init(g_ceph_context);
+
+  req->log_init();
+
+  dout(1) << "====== starting new request req=" << hex << req << dec
+	  << " =====" << dendl;
+  perfcounter->inc(l_rgw_req);
+
+  RGWEnv& rgw_env = client_io->get_env();
+
+  RGWUserInfo userinfo;
+
+  struct req_state rstate(g_ceph_context, &rgw_env, &userinfo);
+  struct req_state *s = &rstate;
+
+  RGWObjectCtx rados_ctx(store, s);
+  s->obj_ctx = &rados_ctx;
+
+  s->req_id = store->unique_id(req->id);
+  s->trans_id = store->unique_trans_id(req->id);
+  s->host_id = store->host_id;
+
+  req->log_format(s, "initializing for trans_id = %s", s->trans_id.c_str());
+
+  RGWOp* op = NULL;
+  int init_error = 0;
+  bool should_log = false;
+  RGWRESTMgr *mgr;
+  RGWHandler_REST *handler = rest->get_handler(store, s, client_io, &mgr,
+					      &init_error);
+  if (init_error != 0) {
+    abort_early(s, NULL, init_error, NULL);
+    goto done;
+  }
+  dout(10) << "handler=" << typeid(*handler).name() << dendl;
+
+  should_log = mgr->get_logging();
+
+  req->log_format(s, "getting op %d", s->op);
+  op = handler->get_op(store);
+  if (!op) {
+    abort_early(s, NULL, -ERR_METHOD_NOT_ALLOWED, handler);
+    goto done;
+  }
+  req->op = op;
+  dout(10) << "op=" << typeid(*op).name() << dendl;
+
+  s->op_type = op->get_type();
+
+  req->log(s, "authorizing");
+  ret = handler->authorize();
+  if (ret < 0) {
+    dout(10) << "failed to authorize request" << dendl;
+    abort_early(s, NULL, ret, handler);
+    goto done;
+  }
+
+  req->log(s, "normalizing buckets and tenants");
+  ret = handler->postauth_init();
+  if (ret < 0) {
+    dout(10) << "failed to run post-auth init" << dendl;
+    abort_early(s, op, ret, handler);
+    goto done;
+  }
+
+  if (s->user->suspended) {
+    dout(10) << "user is suspended, uid=" << s->user->user_id << dendl;
+    abort_early(s, op, -ERR_USER_SUSPENDED, handler);
+    goto done;
+  }
+
+  req->log(s, "init permissions");
+  ret = handler->init_permissions(op);
+  if (ret < 0) {
+    abort_early(s, op, ret, handler);
+    goto done;
+  }
+
+  /**
+   * Only some accesses support website mode, and website mode does NOT apply
+   * if you are using the REST endpoint either (ergo, no authenticated access)
+   */
+  req->log(s, "recalculating target");
+  ret = handler->retarget(op, &op);
+  if (ret < 0) {
+    abort_early(s, op, ret, handler);
+    goto done;
+  }
+  req->op = op;
+
+  req->log(s, "reading permissions");
+  ret = handler->read_permissions(op);
+  if (ret < 0) {
+    abort_early(s, op, ret, handler);
+    goto done;
+  }
+
+  req->log(s, "init op");
+  ret = op->init_processing();
+  if (ret < 0) {
+    abort_early(s, op, ret, handler);
+    goto done;
+  }
+
+  req->log(s, "verifying op mask");
+  ret = op->verify_op_mask();
+  if (ret < 0) {
+    abort_early(s, op, ret, handler);
+    goto done;
+  }
+
+  req->log(s, "verifying op permissions");
+  ret = op->verify_permission();
+  if (ret < 0) {
+    if (s->system_request) {
+      dout(2) << "overriding permissions due to system operation" << dendl;
+    } else {
+      abort_early(s, op, ret, handler);
+      goto done;
+    }
+  }
+
+  req->log(s, "verifying op params");
+  ret = op->verify_params();
+  if (ret < 0) {
+    abort_early(s, op, ret, handler);
+    goto done;
+  }
+
+  req->log(s, "pre-executing");
+  op->pre_exec();
+
+  req->log(s, "executing");
+  op->execute();
+
+  req->log(s, "completing");
+  op->complete();
+done:
+  int r = client_io->complete_request();
+  if (r < 0) {
+    dout(0) << "ERROR: client_io->complete_request() returned " << r << dendl;
+  }
+  if (should_log) {
+    rgw_log_op(store, s, (op ? op->name() : "unknown"), olog);
+  }
+
+  int http_ret = s->err.http_ret;
+  int op_ret = 0;
+  if (op) {
+    op_ret = op->get_ret();
+  }
+
+  req->log_format(s, "op status=%d", op_ret);
+  req->log_format(s, "http status=%d", http_ret);
+
+  if (handler)
+    handler->put_op(op);
+  rest->put_handler(handler);
+
+  dout(1) << "====== req done req=" << hex << req << dec
+	  << " op status=" << op_ret
+	  << " http_status=" << http_ret
+	  << " ======"
+	  << dendl;
+
+  return (ret < 0 ? ret : s->err.ret);
+} /* process_request */
diff --git a/src/rgw/rgw_process.h b/src/rgw/rgw_process.h
new file mode 100644
index 0000000..faf942c
--- /dev/null
+++ b/src/rgw/rgw_process.h
@@ -0,0 +1,181 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+
+#ifndef RGW_PROCESS_H
+#define RGW_PROCESS_H
+
+#include "rgw_common.h"
+#include "rgw_rados.h"
+#include "rgw_acl.h"
+#include "rgw_user.h"
+#include "rgw_op.h"
+#include "rgw_rest.h"
+
+#include "include/assert.h"
+
+#include "common/WorkQueue.h"
+#include "common/Throttle.h"
+
+#if !defined(dout_subsys)
+#define dout_subsys ceph_subsys_rgw
+#define def_dout_subsys
+#endif
+
+#define SOCKET_BACKLOG 1024
+
+extern void signal_shutdown();
+
+struct RGWProcessEnv {
+  RGWRados *store;
+  RGWREST *rest;
+  OpsLogSocket *olog;
+  int port;
+};
+
+class RGWFrontendConfig;
+
+class RGWProcess {
+  deque<RGWRequest*> m_req_queue;
+protected:
+  CephContext *cct;
+  RGWRados* store;
+  OpsLogSocket* olog;
+  ThreadPool m_tp;
+  Throttle req_throttle;
+  RGWREST* rest;
+  RGWFrontendConfig* conf;
+  int sock_fd;
+
+  struct RGWWQ : public ThreadPool::WorkQueue<RGWRequest> {
+    RGWProcess* process;
+    RGWWQ(RGWProcess* p, time_t timeout, time_t suicide_timeout, ThreadPool* tp)
+      : ThreadPool::WorkQueue<RGWRequest>("RGWWQ", timeout, suicide_timeout,
+					  tp), process(p) {}
+
+    bool _enqueue(RGWRequest* req) {
+      process->m_req_queue.push_back(req);
+      perfcounter->inc(l_rgw_qlen);
+      dout(20) << "enqueued request req=" << hex << req << dec << dendl;
+      _dump_queue();
+      return true;
+    }
+
+    void _dequeue(RGWRequest* req) {
+      assert(0);
+    }
+
+    bool _empty() {
+      return process->m_req_queue.empty();
+    }
+
+    RGWRequest* _dequeue() {
+      if (process->m_req_queue.empty())
+	return NULL;
+      RGWRequest *req = process->m_req_queue.front();
+      process->m_req_queue.pop_front();
+      dout(20) << "dequeued request req=" << hex << req << dec << dendl;
+      _dump_queue();
+      perfcounter->inc(l_rgw_qlen, -1);
+      return req;
+    }
+
+    using ThreadPool::WorkQueue<RGWRequest>::_process;
+
+    void _process(RGWRequest *req, ThreadPool::TPHandle &) override  {
+      perfcounter->inc(l_rgw_qactive);
+      process->handle_request(req);
+      process->req_throttle.put(1);
+      perfcounter->inc(l_rgw_qactive, -1);
+    }
+
+    void _dump_queue();
+
+    void _clear() {
+      assert(process->m_req_queue.empty());
+    }
+  } req_wq;
+
+public:
+  RGWProcess(CephContext* cct, RGWProcessEnv* pe, int num_threads,
+	    RGWFrontendConfig* _conf)
+    : cct(cct), store(pe->store), olog(pe->olog),
+      m_tp(cct, "RGWProcess::m_tp", "tp_rgw_process", num_threads),
+      req_throttle(cct, "rgw_ops", num_threads * 2),
+      rest(pe->rest), conf(_conf), sock_fd(-1),
+      req_wq(this, g_conf->rgw_op_thread_timeout,
+	     g_conf->rgw_op_thread_suicide_timeout, &m_tp) {}
+  
+  virtual ~RGWProcess() {}
+
+  virtual void run() = 0;
+  virtual void handle_request(RGWRequest *req) = 0;
+
+  void pause() {
+    m_tp.pause();
+  }
+
+  void unpause_with_new_config(RGWRados *store) {
+    this->store = store;
+    m_tp.unpause();
+  }
+
+  void close_fd() {
+    if (sock_fd >= 0) {
+      ::close(sock_fd);
+      sock_fd = -1;
+    }
+  }
+}; /* RGWProcess */
+
+class RGWFCGXProcess : public RGWProcess {
+	int max_connections;
+public:
+
+  /* have a bit more connections than threads so that requests are
+   * still accepted even if we're still processing older requests */
+  RGWFCGXProcess(CephContext* cct, RGWProcessEnv* pe, int num_threads,
+		 RGWFrontendConfig* _conf)
+    : RGWProcess(cct, pe, num_threads, _conf),
+      max_connections(num_threads + (num_threads >> 3))
+    {}
+
+  void run();
+  void handle_request(RGWRequest* req);
+};
+
+class RGWProcessControlThread : public Thread {
+  RGWProcess *pprocess;
+public:
+  RGWProcessControlThread(RGWProcess *_pprocess) : pprocess(_pprocess) {}
+
+  void *entry() {
+    pprocess->run();
+    return NULL;
+  }
+};
+
+class RGWLoadGenProcess : public RGWProcess {
+  RGWAccessKey access_key;
+public:
+  RGWLoadGenProcess(CephContext* cct, RGWProcessEnv* pe, int num_threads,
+		  RGWFrontendConfig* _conf) :
+  RGWProcess(cct, pe, num_threads, _conf) {}
+  void run();
+  void checkpoint();
+  void handle_request(RGWRequest* req);
+  void gen_request(const string& method, const string& resource,
+		  int content_length, atomic_t* fail_flag);
+
+  void set_access_key(RGWAccessKey& key) { access_key = key; }
+};
+
+/* process stream request */
+int process_request(RGWRados* store, RGWREST* rest, RGWRequest* req,
+		    RGWStreamIO* client_io, OpsLogSocket* olog);
+
+#if defined(def_dout_subsys)
+#undef def_dout_subsys
+#undef dout_subsys
+#endif
+
+#endif /* RGW_PROCESS_H */
diff --git a/src/rgw/rgw_quota.cc b/src/rgw/rgw_quota.cc
index c6c62e7..0ea17d5 100644
--- a/src/rgw/rgw_quota.cc
+++ b/src/rgw/rgw_quota.cc
@@ -258,7 +258,7 @@ int BucketAsyncRefreshHandler::init_fetch()
 {
   ldout(store->ctx(), 20) << "initiating async quota refresh for bucket=" << bucket << dendl;
 
-  int r = store->get_bucket_stats_async(bucket, this);
+  int r = store->get_bucket_stats_async(bucket, RGW_NO_SHARD, this);
   if (r < 0) {
     ldout(store->ctx(), 0) << "could not get bucket info for bucket=" << bucket.name << dendl;
 
@@ -322,7 +322,7 @@ int RGWBucketStatsCache::fetch_stats_from_storage(const rgw_user& user, rgw_buck
   string master_ver;
 
   map<RGWObjCategory, RGWStorageStats> bucket_stats;
-  int r = store->get_bucket_stats(bucket, &bucket_ver, &master_ver, bucket_stats, NULL);
+  int r = store->get_bucket_stats(bucket, RGW_NO_SHARD, &bucket_ver, &master_ver, bucket_stats, NULL);
   if (r < 0) {
     ldout(store->ctx(), 0) << "could not get bucket info for bucket=" << bucket.name << dendl;
     return r;
@@ -453,7 +453,7 @@ class RGWUserStatsCache : public RGWQuotaCache<rgw_user> {
       do {
         int ret = stats->sync_all_users();
         if (ret < 0) {
-          ldout(cct, 0) << "ERROR: sync_all_users() returned ret=" << ret << dendl;
+          ldout(cct, 5) << "ERROR: sync_all_users() returned ret=" << ret << dendl;
         }
 
         lock.Lock();
@@ -590,10 +590,11 @@ int RGWUserStatsCache::sync_user(const rgw_user& user)
     return 0;
   }
 
-  utime_t when_need_full_sync = header.last_stats_sync;
-  when_need_full_sync += store->ctx()->_conf->rgw_user_quota_sync_wait_time;
+  real_time when_need_full_sync = header.last_stats_sync;
+  when_need_full_sync += make_timespan(store->ctx()->_conf->rgw_user_quota_sync_wait_time);
   
   // check if enough time passed since last full sync
+  /* FIXME: missing check? */
 
   ret = rgw_user_sync_all_stats(store, user);
   if (ret < 0) {
@@ -611,7 +612,7 @@ int RGWUserStatsCache::sync_all_users()
 
   int ret = store->meta_mgr->list_keys_init(key, &handle);
   if (ret < 0) {
-    ldout(store->ctx(), 0) << "ERROR: can't get key: ret=" << ret << dendl;
+    ldout(store->ctx(), 10) << "ERROR: can't get key: ret=" << ret << dendl;
     return ret;
   }
 
diff --git a/src/rgw/rgw_rados.cc b/src/rgw/rgw_rados.cc
index a75b69e..7177788 100644
--- a/src/rgw/rgw_rados.cc
+++ b/src/rgw/rgw_rados.cc
@@ -1,3 +1,4 @@
+
 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
 // vim: ts=8 sw=2 smarttab
 
@@ -19,6 +20,9 @@
 #include "rgw_acl_s3.h" /* for dumping s3policy in debug log */
 #include "rgw_metadata.h"
 #include "rgw_bucket.h"
+#include "rgw_rest_conn.h"
+#include "rgw_cr_rados.h"
+#include "rgw_cr_rest.h"
 
 #include "cls/rgw/cls_rgw_ops.h"
 #include "cls/rgw/cls_rgw_types.h"
@@ -33,6 +37,8 @@
 
 #include "rgw_tools.h"
 
+#include "rgw_coroutine.h"
+
 #include "common/Clock.h"
 
 #include "include/rados/librados.hpp"
@@ -49,6 +55,9 @@ using namespace librados;
 
 #include "rgw_gc.h"
 #include "rgw_object_expirer_core.h"
+#include "rgw_sync.h"
+#include "rgw_data_sync.h"
+#include "rgw_realm_watcher.h"
 
 #define dout_subsys ceph_subsys_rgw
 
@@ -63,23 +72,35 @@ static string notify_oid_prefix = "notify";
 static string *notify_oids = NULL;
 static string shadow_ns = "shadow";
 static string dir_oid_prefix = ".dir.";
-static string default_storage_pool = ".rgw.buckets";
-static string default_storage_extra_pool = ".rgw.buckets.extra";
+static string default_storage_pool_suffix = "rgw.buckets.data";
+static string default_bucket_index_pool_suffix = "rgw.buckets.index";
+static string default_storage_extra_pool_suffix = "rgw.buckets.non-ec";
 static string avail_pools = ".pools.avail";
 
 static string zone_info_oid_prefix = "zone_info.";
+static string zone_names_oid_prefix = "zone_names.";
 static string region_info_oid_prefix = "region_info.";
-
+static string zone_group_info_oid_prefix = "zonegroup_info.";
+static string realm_names_oid_prefix = "realms_names.";
+static string realm_info_oid_prefix = "realms.";
 static string default_region_info_oid = "default.region";
+static string default_zone_group_info_oid = "default.zonegroup";
+static string period_info_oid_prefix = "periods.";
+static string period_latest_epoch_info_oid = ".latest_epoch";
 static string region_map_oid = "region_map";
+static string zonegroup_map_oid = "zonegroup_map";
 static string log_lock_name = "rgw_log_lock";
-
+static string default_realm_info_oid = "default.realm";
+const string default_zonegroup_name = "default";
+const string default_zone_name = "default";
+static string zonegroup_names_oid_prefix = "zonegroups_names.";
 static RGWObjCategory main_category = RGW_OBJ_CATEGORY_MAIN;
-
 #define RGW_USAGE_OBJ_PREFIX "usage."
-
-#define RGW_DEFAULT_ZONE_ROOT_POOL ".rgw.root"
-#define RGW_DEFAULT_REGION_ROOT_POOL ".rgw.root"
+#define FIRST_EPOCH 1
+static string RGW_DEFAULT_ZONE_ROOT_POOL = "rgw.root";
+static string RGW_DEFAULT_ZONEGROUP_ROOT_POOL = "rgw.root";
+static string RGW_DEFAULT_REALM_ROOT_POOL = "rgw.root";
+static string RGW_DEFAULT_PERIOD_ROOT_POOL = "rgw.root";
 
 #define RGW_STATELOG_OBJ_PREFIX "statelog."
 
@@ -87,442 +108,1653 @@ static RGWObjCategory main_category = RGW_OBJ_CATEGORY_MAIN;
 
 struct bucket_info_entry {
   RGWBucketInfo info;
-  time_t mtime;
+  real_time mtime;
   map<string, bufferlist> attrs;
 };
 
 static RGWChainedCacheImpl<bucket_info_entry> binfo_cache;
 
-void RGWDefaultRegionInfo::dump(Formatter *f) const {
-  encode_json("default_region", default_region, f);
+void RGWDefaultZoneGroupInfo::dump(Formatter *f) const {
+  encode_json("default_zonegroup", default_zonegroup, f);
 }
 
-void RGWDefaultRegionInfo::decode_json(JSONObj *obj) {
-  JSONDecoder::decode_json("default_region", default_region, obj);
+void RGWDefaultZoneGroupInfo::decode_json(JSONObj *obj) {
+
+  JSONDecoder::decode_json("default_zonegroup", default_zonegroup, obj);
+  /* backward compatability with region */
+  if (default_zonegroup.empty()) {
+    JSONDecoder::decode_json("default_region", default_zonegroup, obj);
+  }
 }
 
-int RGWRegion::get_pool_name(CephContext *cct, string *pool_name)
+const string& RGWZoneGroup::get_pool_name(CephContext *cct_)
 {
-  *pool_name = cct->_conf->rgw_region_root_pool;
-  if (pool_name->empty()) {
-    *pool_name = RGW_DEFAULT_REGION_ROOT_POOL;
-  } else if ((*pool_name)[0] != '.') {
-    derr << "ERROR: region root pool name must start with a period" << dendl;
-    return -EINVAL;
+  if (cct_->_conf->rgw_zonegroup_root_pool.empty()) {
+    return RGW_DEFAULT_ZONEGROUP_ROOT_POOL;
   }
-  return 0;
+
+  return cct_->_conf->rgw_zonegroup_root_pool;
 }
 
-int RGWRegion::read_default(RGWDefaultRegionInfo& default_info)
+int RGWZoneGroup::create_default(bool old_format)
 {
-  string pool_name;
+  name = default_zonegroup_name;
+  is_master = true;
 
-  int ret = get_pool_name(cct, &pool_name);
-  if (ret < 0) {
-    return ret;
+  RGWZoneGroupPlacementTarget placement_target;
+  placement_target.name = "default-placement";
+  placement_targets[placement_target.name] = placement_target;
+  default_placement = "default-placement";
+
+  RGWZoneParams zone_params(default_zone_name);
+
+  int r = zone_params.init(cct, store, false);
+  if (r < 0) {
+    ldout(cct, 0) << "create_default: error initializing zone params: " << cpp_strerror(-r) << dendl;
+    return r;
   }
 
-  string oid = cct->_conf->rgw_default_region_info_oid;
-  if (oid.empty()) {
-    oid = default_region_info_oid;
+  r = zone_params.create_default();
+  if (r < 0 && r != -EEXIST) {
+    ldout(cct, 0) << "create_default: error in create_default  zone params: " << cpp_strerror(-r) << dendl;
+    return r;
+  } else if (r == -EEXIST) {
+    ldout(cct, 10) << "zone_params::create_default() returned -EEXIST, we raced with another default zone_params creation" << dendl;
+    zone_params.clear_id();
+    r = zone_params.init(cct, store);
+    if (r < 0) {
+      ldout(cct, 0) << "create_default: error in init existing zone params: " << cpp_strerror(-r) << dendl;
+      return r;
+    }
+    ldout(cct, 20) << "zone_params::create_default() " << zone_params.get_name() << " id " << zone_params.get_id()
+		   << dendl;
+  }
+  
+  RGWZone& default_zone = zones[zone_params.get_id()];
+  default_zone.name = zone_params.get_name();
+  default_zone.id = zone_params.get_id();
+  master_zone = default_zone.id;
+  
+  r = create();
+  if (r < 0 && r != -EEXIST) {
+    ldout(cct, 0) << "error storing zone group info: " << cpp_strerror(-r) << dendl;
+    return r;
   }
 
-  rgw_bucket pool(pool_name.c_str());
-  bufferlist bl;
-  RGWObjectCtx obj_ctx(store);
-  ret = rgw_get_system_obj(store, obj_ctx, pool, oid, bl, NULL, NULL);
-  if (ret < 0)
-    return ret;
+  if (r == -EEXIST) {
+    ldout(cct, 10) << "create_default() returned -EEXIST, we raced with another zonegroup creation" << dendl;
+    id.clear();
+    r = init(cct, store);
+    if (r < 0) {
+      return r;
+    }
+  }
 
-  try {
-    bufferlist::iterator iter = bl.begin();
-    ::decode(default_info, iter);
-  } catch (buffer::error& err) {
-    derr << "error decoding data from " << pool << ":" << oid << dendl;
-    return -EIO;
+  if (old_format) {
+    name = id;
   }
 
-  name = default_info.default_region;
+  post_process_params();
 
   return 0;
 }
 
-int RGWRegion::set_as_default()
+const string RGWZoneGroup::get_default_oid(bool old_region_format)
 {
-  string pool_name;
-  int ret = get_pool_name(cct, &pool_name);
-  if (ret < 0)
-    return ret;
-
-  string oid = cct->_conf->rgw_default_region_info_oid;
-  if (oid.empty()) {
-    oid = default_region_info_oid;
+  if (old_region_format) {
+    if (cct->_conf->rgw_default_region_info_oid.empty()) {
+      return default_region_info_oid;
+    }
+    return cct->_conf->rgw_default_region_info_oid;
   }
 
-  rgw_bucket pool(pool_name.c_str());
-  bufferlist bl;
-
-  RGWDefaultRegionInfo default_info;
-  default_info.default_region = name;
+  string default_oid = cct->_conf->rgw_default_zonegroup_info_oid;
 
-  ::encode(default_info, bl);
+  if (cct->_conf->rgw_default_zonegroup_info_oid.empty()) {
+    default_oid = default_zone_group_info_oid;
+  }
 
-  ret = rgw_put_system_obj(store, pool, oid, bl.c_str(), bl.length(), false, NULL, 0, NULL);
-  if (ret < 0)
-    return ret;
+  default_oid += "." + realm_id;
 
-  return 0;
+  return default_oid;
 }
 
-int RGWRegion::init(CephContext *_cct, RGWRados *_store, bool setup_region)
+const string& RGWZoneGroup::get_info_oid_prefix(bool old_region_format)
 {
-  cct = _cct;
-  store = _store;
-
-  if (!setup_region)
-    return 0;
-
-  string region_name = cct->_conf->rgw_region;
-
-  if (region_name.empty()) {
-    RGWDefaultRegionInfo default_info;
-    int r = read_default(default_info);
-    if (r == -ENOENT) {
-      r = create_default();
-      if (r == -EEXIST) { /* we may have raced with another region creation,
-                             make sure we can read the region info and continue
-                             as usual to make sure region creation is complete */
-        ldout(cct, 0) << "create_default() returned -EEXIST, we raced with another region creation" << dendl;
-        r = read_info(name);
-      }
-      if (r < 0)
-        return r;
-      r = set_as_default(); /* set this as default even if we weren't the creators */
-      if (r < 0)
-        return r;
-      /*Re attempt to read region info from newly created default region */
-      r = read_default(default_info);
-      if (r < 0)
-	return r;
-    } else if (r < 0) {
-      lderr(cct) << "failed reading default region info: " << cpp_strerror(-r) << dendl;
-      return r;
-    }
-    region_name = default_info.default_region;
+  if (old_region_format) {
+    return region_info_oid_prefix;
   }
-
-  return read_info(region_name);
+  return zone_group_info_oid_prefix;
 }
 
-int RGWRegion::read_info(const string& region_name)
+const string& RGWZoneGroup::get_names_oid_prefix()
 {
-  string pool_name;
-  int ret = get_pool_name(cct, &pool_name);
-  if (ret < 0)
-    return ret;
+  return zonegroup_names_oid_prefix;
+}
 
-  rgw_bucket pool(pool_name.c_str());
-  bufferlist bl;
+const string& RGWZoneGroup::get_predefined_name(CephContext *cct) {
+  return cct->_conf->rgw_zonegroup;
+}
 
-  name = region_name;
+int RGWZoneGroup::equals(const string& other_zonegroup) const
+{
+  if (is_master && other_zonegroup.empty())
+    return true;
 
-  string oid = region_info_oid_prefix + name;
+  return (id  == other_zonegroup);
+}
 
-  RGWObjectCtx obj_ctx(store);
-  ret = rgw_get_system_obj(store, obj_ctx, pool, oid, bl, NULL, NULL);
-  if (ret < 0) {
-    lderr(cct) << "failed reading region info from " << pool << ":" << oid << ": " << cpp_strerror(-ret) << dendl;
-    return ret;
+int RGWZoneGroup::add_zone(const RGWZoneParams& zone_params, bool *is_master, bool *read_only, const list<string>& endpoints)
+{
+  if (is_master && *is_master) {
+    if (!master_zone.empty() && master_zone != zone_params.get_id()) {
+      ldout(cct, 0) << "NOTICE: overriding master zone: " << master_zone  << dendl;
+    }
+    master_zone = zone_params.get_id();
+  } else if (master_zone == zone_params.get_id()) {
+    master_zone ="";
   }
 
-  try {
-    bufferlist::iterator iter = bl.begin();
-    ::decode(*this, iter);
-  } catch (buffer::error& err) {
-    ldout(cct, 0) << "ERROR: failed to decode region from " << pool << ":" << oid << dendl;
-    return -EIO;
+  RGWZone& zone = zones[zone_params.get_id()];
+  zone.name = zone_params.get_name();
+  zone.id = zone_params.get_id();
+  if (!endpoints.empty()) {
+    zone.endpoints = endpoints;
+  }
+  if (read_only) {
+    zone.read_only = *read_only;
   }
 
-  return 0;
+  post_process_params();
+
+  return update();
 }
 
-int RGWRegion::create_default()
-{
-  name = "default";
-  string zone_name = "default";
 
-  is_master = true;
+int RGWZoneGroup::rename_zone(const RGWZoneParams& zone_params)
+{ 
+  RGWZone& zone = zones[zone_params.get_id()];
+  zone.name = zone_params.get_name();
+  
+  return update();
+}
 
-  RGWRegionPlacementTarget placement_target;
-  placement_target.name = "default-placement";
-  placement_targets[placement_target.name] = placement_target;
-  default_placement = "default-placement";
+void RGWZoneGroup::post_process_params()
+{
+  bool log_data = zones.size() > 1;
 
-  RGWZone& default_zone = zones[zone_name];
-  default_zone.name = zone_name;
+  if (master_zone.empty()) {
+    map<string, RGWZone>::iterator iter = zones.begin();
+    if (iter != zones.end()) {
+      master_zone = iter->first;
+    }
+  }
+  
+  for (map<string, RGWZone>::iterator iter = zones.begin(); iter != zones.end(); ++iter) {
+    RGWZone& zone = iter->second;
+    zone.log_data = log_data;
+    zone.log_meta = (is_master && zone.id == master_zone);
 
-  RGWZoneParams zone_params;
-  zone_params.name = zone_name;
-  zone_params.init_default(store);
+    RGWZoneParams zone_params(zone.id, zone.name);
+    int ret = zone_params.init(cct, store);
+    if (ret < 0) {
+      ldout(cct, 0) << "WARNING: could not read zone params for zone id=" << zone.id << " name=" << zone.name << dendl;
+      continue;
+    }
 
-  int r = zone_params.store_info(cct, store, *this);
-  if (r < 0) {
-    derr << "error storing zone params: " << cpp_strerror(-r) << dendl;
-    return r;
+    for (map<string, RGWZonePlacementInfo>::iterator iter = zone_params.placement_pools.begin(); 
+         iter != zone_params.placement_pools.end(); ++iter) {
+      const string& placement_name = iter->first;
+      if (placement_targets.find(placement_name) == placement_targets.end()) {
+        RGWZoneGroupPlacementTarget placement_target;
+        placement_target.name = placement_name;
+        placement_targets[placement_name] = placement_target;
+      }
+    }
   }
 
-  r = store_info(true);
-  if (r < 0) {
-    derr << "error storing region info: " << cpp_strerror(-r) << dendl;
-    return r;
+  if (default_placement.empty() && !placement_targets.empty()) {
+    default_placement = placement_targets.begin()->first;
   }
-
-  return 0;
 }
 
-int RGWRegion::store_info(bool exclusive)
+int RGWZoneGroup::remove_zone(const RGWZoneParams& zone_params)
 {
-  string pool_name;
-  int ret = get_pool_name(cct, &pool_name);
-  if (ret < 0)
-    return ret;
-
-  rgw_bucket pool(pool_name.c_str());
-
-  string oid = region_info_oid_prefix + name;
+  map<string, RGWZone>::iterator iter = zones.find(zone_params.get_id());
 
-  bufferlist bl;
-  ::encode(*this, bl);
-  ret = rgw_put_system_obj(store, pool, oid, bl.c_str(), bl.length(), exclusive, NULL, 0, NULL);
+  if (iter == zones.end()) {
+    ldout(cct, 0) << "zone " << zone_params.get_name() << " " << zone_params.get_id() << "is not a part of zonegroup "<< name << dendl;
+    return -ENOENT;
+  }
 
-  return ret;
-}
+  zones.erase(iter);
 
-int RGWRegion::equals(const string& other_region)
-{
-  if (is_master && other_region.empty())
-    return true;
+  post_process_params();
 
-  return (name == other_region);
+  return update();
 }
 
-void RGWZoneParams::init_default(RGWRados *store)
+int RGWZoneGroup::read_default_id(string& default_id, bool old_format)
 {
-  domain_root = ".rgw";
-  control_pool = ".rgw.control";
-  gc_pool = ".rgw.gc";
-  log_pool = ".log";
-  intent_log_pool = ".intent-log";
-  usage_log_pool = ".usage";
-  user_keys_pool = ".users";
-  user_email_pool = ".users.email";
-  user_swift_pool = ".users.swift";
-  user_uid_pool = ".users.uid";
-
-  /* check for old pools config */
-  rgw_obj obj(domain_root, avail_pools);
-  int r =  store->raw_obj_stat(obj, NULL, NULL, NULL, NULL, NULL, NULL);
-  if (r < 0) {
-    ldout(store->ctx(), 0) << "couldn't find old data placement pools config, setting up new ones for the zone" << dendl;
-    /* a new system, let's set new placement info */
-    RGWZonePlacementInfo default_placement;
-    default_placement.index_pool = ".rgw.buckets.index";
-    default_placement.data_pool = ".rgw.buckets";
-    default_placement.data_extra_pool = ".rgw.buckets.extra";
-    placement_pools["default-placement"] = default_placement;
+  if (realm_id.empty()) {
+    /* try using default realm */
+    RGWRealm realm;
+    int ret = realm.init(cct, store);
+    if (ret < 0) {
+      ldout(cct, 10) << "could not read realm id: " << cpp_strerror(-ret) << dendl;
+      return -ENOENT;
+    }
+    realm_id = realm.get_id();
   }
+
+  return RGWSystemMetaObj::read_default_id(default_id, old_format);
 }
 
-int RGWZoneParams::get_pool_name(CephContext *cct, string *pool_name)
+int RGWZoneGroup::set_as_default()
 {
-  *pool_name = cct->_conf->rgw_zone_root_pool;
-  if (pool_name->empty()) {
-    *pool_name = RGW_DEFAULT_ZONE_ROOT_POOL;
-  } else if ((*pool_name)[0] != '.') {
-    derr << "ERROR: zone root pool name must start with a period" << dendl;
-    return -EINVAL;
+  if (realm_id.empty()) {
+    /* try using default realm */
+    RGWRealm realm;
+    int ret = realm.init(cct, store);
+    if (ret < 0) {
+      ldout(cct, 10) << "could not read realm id: " << cpp_strerror(-ret) << dendl;
+      return -EINVAL;
+    }
+    realm_id = realm.get_id();
   }
 
-  return 0;
+  return RGWSystemMetaObj::set_as_default();
 }
 
-void RGWZoneParams::init_name(CephContext *cct, RGWRegion& region)
+int RGWSystemMetaObj::init(CephContext *_cct, RGWRados *_store, bool setup_obj, bool old_format)
 {
-  name = cct->_conf->rgw_zone;
+  cct = _cct;
+  store = _store;
 
-  if (name.empty()) {
-    name = region.master_zone;
+  if (!setup_obj)
+    return 0;
+
+  if (old_format && id.empty()) {
+    id = name;
+  }
 
+  if (id.empty()) {
+    int r;
     if (name.empty()) {
-      name = "default";
+      name = get_predefined_name(cct);
+    }
+    if (name.empty()) {
+      r = use_default(old_format);
+      if (r < 0) {
+	return r;
+      }
+    } else if (!old_format) {
+      r = read_id(name, id);
+      if (r < 0) {
+	ldout(cct, 0) << "error in read_id for id " << id << " : " << cpp_strerror(-r) << dendl;
+	return r;
+      }
     }
   }
+
+  return read_info(id, old_format);
 }
 
-int RGWZoneParams::init(CephContext *cct, RGWRados *store, RGWRegion& region)
+int RGWSystemMetaObj::read_default(RGWDefaultSystemMetaObjInfo& default_info, const string& oid)
 {
-  init_name(cct, region);
-
-  string pool_name;
-  int ret = get_pool_name(cct, &pool_name);
-  if (ret < 0)
-    return ret;
+  string pool_name = get_pool_name(cct);
 
   rgw_bucket pool(pool_name.c_str());
   bufferlist bl;
-
-  string oid = zone_info_oid_prefix + name;
   RGWObjectCtx obj_ctx(store);
-  ret = rgw_get_system_obj(store, obj_ctx, pool, oid, bl, NULL, NULL);
+  int ret = rgw_get_system_obj(store, obj_ctx, pool, oid, bl, NULL, NULL);
   if (ret < 0)
     return ret;
 
   try {
     bufferlist::iterator iter = bl.begin();
-    ::decode(*this, iter);
+    ::decode(default_info, iter);
   } catch (buffer::error& err) {
-    ldout(cct, 0) << "ERROR: failed to decode zone info from " << pool << ":" << oid << dendl;
+    ldout(cct, 0) << "error decoding data from " << pool << ":" << oid << dendl;
     return -EIO;
   }
 
-  is_master = (name == region.master_zone) || (region.master_zone.empty() && name == "default");
-
-  ldout(cct, 2) << "zone " << name << " is " << (is_master ? "" : "NOT ") << "master" << dendl;
-
   return 0;
 }
 
-int RGWZoneParams::store_info(CephContext *cct, RGWRados *store, RGWRegion& region)
+int RGWSystemMetaObj::read_default_id(string& default_id, bool old_format)
 {
-  init_name(cct, region);
+  RGWDefaultSystemMetaObjInfo default_info;
 
-  string pool_name;
-  int ret = get_pool_name(cct, &pool_name);
-  if (ret < 0)
+  int ret = read_default(default_info, get_default_oid(old_format));
+  if (ret < 0) {
     return ret;
+  }
 
-  rgw_bucket pool(pool_name.c_str());
-  string oid = zone_info_oid_prefix + name;
-
-  bufferlist bl;
-  ::encode(*this, bl);
-  ret = rgw_put_system_obj(store, pool, oid, bl.c_str(), bl.length(), false, NULL, 0, NULL);
+  default_id = default_info.default_id;
 
-  return ret;
+  return 0;
 }
 
-void RGWRegionMap::encode(bufferlist& bl) const {
-  ENCODE_START(3, 1, bl);
-  ::encode(regions, bl);
-  ::encode(master_region, bl);
-  ::encode(bucket_quota, bl);
-  ::encode(user_quota, bl);
-  ENCODE_FINISH(bl);
+int RGWSystemMetaObj::use_default(bool old_format)
+{
+  return read_default_id(id, old_format);
 }
 
-void RGWRegionMap::decode(bufferlist::iterator& bl) {
-  DECODE_START(3, bl);
-  ::decode(regions, bl);
-  ::decode(master_region, bl);
+int RGWSystemMetaObj::set_as_default()
+{
+  string pool_name = get_pool_name(cct);
+  string oid  = get_default_oid();
 
-  if (struct_v >= 2)
-    ::decode(bucket_quota, bl);
-  if (struct_v >= 3)
-    ::decode(user_quota, bl);
-  DECODE_FINISH(bl);
+  rgw_bucket pool(pool_name.c_str());
+  bufferlist bl;
 
-  regions_by_api.clear();
-  for (map<string, RGWRegion>::iterator iter = regions.begin();
-       iter != regions.end(); ++iter) {
-    RGWRegion& region = iter->second;
-    regions_by_api[region.api_name] = region;
-    if (region.is_master) {
-      master_region = region.name;
-    }
-  }
-}
+  RGWDefaultSystemMetaObjInfo default_info;
+  default_info.default_id = id;
 
-void RGWRegionMap::get_params(CephContext *cct, string& pool_name, string& oid)
-{
-  pool_name = cct->_conf->rgw_zone_root_pool;
-  if (pool_name.empty()) {
-    pool_name = RGW_DEFAULT_ZONE_ROOT_POOL;
-  }
-  oid = region_map_oid;
-}
+  ::encode(default_info, bl);
 
-int RGWRegionMap::read(CephContext *cct, RGWRados *store)
-{
-  string pool_name, oid;
+  int ret = rgw_put_system_obj(store, pool, oid, bl.c_str(), bl.length(), false, NULL, real_time(), NULL);
+  if (ret < 0)
+    return ret;
 
-  get_params(cct, pool_name, oid);
+  return 0;
+}
 
+int RGWSystemMetaObj::read_id(const string& obj_name, string& object_id)
+{
+  string pool_name = get_pool_name(cct);
   rgw_bucket pool(pool_name.c_str());
-
   bufferlist bl;
+
+  string oid = get_names_oid_prefix() + obj_name;
+
   RGWObjectCtx obj_ctx(store);
   int ret = rgw_get_system_obj(store, obj_ctx, pool, oid, bl, NULL, NULL);
-  if (ret < 0)
+  if (ret < 0) {
     return ret;
+  }
 
-
-  Mutex::Locker l(lock);
+  RGWNameToId nameToId;
   try {
     bufferlist::iterator iter = bl.begin();
-    ::decode(*this, iter);
+    ::decode(nameToId, iter);
   } catch (buffer::error& err) {
-    ldout(cct, 0) << "ERROR: failed to decode region map info from " << pool << ":" << oid << dendl;
+    ldout(cct, 0) << "ERROR: failed to decode obj from " << pool << ":" << oid << dendl;
     return -EIO;
   }
-
+  object_id = nameToId.obj_id;
   return 0;
 }
 
-int RGWRegionMap::store(CephContext *cct, RGWRados *store)
+int RGWSystemMetaObj::delete_obj(bool old_format)
 {
-  string pool_name, oid;
-
-  get_params(cct, pool_name, oid);
-
+  string pool_name = get_pool_name(cct);
   rgw_bucket pool(pool_name.c_str());
 
-  Mutex::Locker l(lock);
+  /* check to see if obj is the default */
+  RGWDefaultSystemMetaObjInfo default_info;
+  int ret = read_default(default_info, get_default_oid(old_format));
+  if (ret < 0 && ret != -ENOENT)
+    return ret;
+  if (default_info.default_id == id || (old_format && default_info.default_id == name)) {
+    string oid = get_default_oid(old_format);
+    rgw_obj default_named_obj(pool, oid);
+    ret = store->delete_system_obj(default_named_obj);
+    if (ret < 0) {
+      ldout(cct, 0) << "Error delete default obj name  " << name << ": " << cpp_strerror(-ret) << dendl;
+      return ret;
+    }
+  }
+  if (!old_format) {
+    string oid  = get_names_oid_prefix() + name;
+    rgw_obj object_name(pool, oid);
+    ret = store->delete_system_obj(object_name);
+    if (ret < 0) {
+      ldout(cct, 0) << "Error delete obj name  " << name << ": " << cpp_strerror(-ret) << dendl;
+      return ret;
+    }
+  }
 
-  bufferlist bl;
-  ::encode(*this, bl);
-  int ret = rgw_put_system_obj(store, pool, oid, bl.c_str(), bl.length(), false, NULL, 0, NULL);
+  string oid = get_info_oid_prefix(old_format);
+  if (old_format) {
+    oid += name;
+  } else {
+    oid += id;
+  }
+
+  rgw_obj object_id(pool, oid);
+  ret = store->delete_system_obj(object_id);
+  if (ret < 0) {
+    ldout(cct, 0) << "Error delete object id " << id << ": " << cpp_strerror(-ret) << dendl;
+  }
 
   return ret;
 }
 
-int RGWRegionMap::update(RGWRegion& region)
+int RGWSystemMetaObj::store_name(bool exclusive)
 {
-  Mutex::Locker l(lock);
+  string pool_name = get_pool_name(cct);
 
-  if (region.is_master && !region.equals(master_region)) {
-    derr << "cannot update region map, master_region conflict" << dendl;
-    return -EINVAL;
-  }
-  map<string, RGWRegion>::iterator iter = regions.find(region.name);
-  if (iter != regions.end()) {
-    RGWRegion& old_region = iter->second;
-    if (!old_region.api_name.empty()) {
-      regions_by_api.erase(old_region.api_name);
-    }
-  }
-  regions[region.name] = region;
+  rgw_bucket pool(pool_name.c_str());
+  string oid = get_names_oid_prefix() + name;
 
-  if (!region.api_name.empty()) {
-    regions_by_api[region.api_name] = region;
-  }
+  RGWNameToId nameToId;
+  nameToId.obj_id = id;
 
-  if (region.is_master) {
-    master_region = region.name;
-  }
-  return 0;
+  bufferlist bl;
+  ::encode(nameToId, bl);
+  return  rgw_put_system_obj(store, pool, oid, bl.c_str(), bl.length(), exclusive, NULL, real_time(), NULL);
 }
 
-void RGWObjVersionTracker::prepare_op_for_read(ObjectReadOperation *op)
+int RGWSystemMetaObj::rename(const string& new_name)
+{
+  string new_id;
+  int ret = read_id(new_name, new_id);
+  if (!ret) {
+    return -EEXIST;
+  }
+  if (ret < 0 && ret != -ENOENT) {
+    ldout(cct, 0) << "Error read_id " << new_name << ": " << cpp_strerror(-ret) << dendl;
+    return ret;
+  }
+  string old_name = name;
+  name = new_name;
+  ret = update();
+  if (ret < 0) {
+    ldout(cct, 0) << "Error storing new obj info " << new_name << ": " << cpp_strerror(-ret) << dendl;
+    return ret;
+  }
+  ret = store_name(true);
+  if (ret < 0) {
+    ldout(cct, 0) << "Error storing new name " << new_name << ": " << cpp_strerror(-ret) << dendl;
+    return ret;
+  }
+  /* delete old name */
+  string pool_name = get_pool_name(cct);
+  rgw_bucket pool(pool_name.c_str());
+  string oid = get_names_oid_prefix() + old_name;
+  rgw_obj old_name_obj(pool, oid);
+  ret = store->delete_system_obj(old_name_obj);
+  if (ret < 0) {
+    ldout(cct, 0) << "Error delete old obj name  " << old_name << ": " << cpp_strerror(-ret) << dendl;
+    return ret;
+  }
+
+  return ret;
+}
+
+int RGWSystemMetaObj::read_info(const string& obj_id, bool old_format)
+{
+  string pool_name = get_pool_name(cct);
+
+  rgw_bucket pool(pool_name.c_str());
+  bufferlist bl;
+
+  string oid = get_info_oid_prefix(old_format) + obj_id;
+
+  RGWObjectCtx obj_ctx(store);
+  int ret = rgw_get_system_obj(store, obj_ctx, pool, oid, bl, NULL, NULL);
+  if (ret < 0) {
+    ldout(cct, 0) << "failed reading obj info from " << pool << ":" << oid << ": " << cpp_strerror(-ret) << dendl;
+    return ret;
+  }
+
+  try {
+    bufferlist::iterator iter = bl.begin();
+    ::decode(*this, iter);
+  } catch (buffer::error& err) {
+    ldout(cct, 0) << "ERROR: failed to decode obj from " << pool << ":" << oid << dendl;
+    return -EIO;
+  }
+
+  return 0;
+}
+
+int RGWSystemMetaObj::read()
+{
+  int ret = read_id(name, id);
+  if (ret < 0) {
+    return ret;
+  }
+
+  return read_info(id);
+}
+
+int RGWSystemMetaObj::create(bool exclusive)
+{
+  int ret;
+  
+  /* check to see the name is not used */
+  ret = read_id(name, id);
+  if (exclusive && ret == 0) {
+    ldout(cct, 10) << "ERROR: name " << name << " already in use for obj id " << id << dendl;
+    return -EEXIST;
+  } else if ( ret < 0 && ret != -ENOENT) {
+    ldout(cct, 0) << "failed reading obj id  " << id << ": " << cpp_strerror(-ret) << dendl;
+    return ret;
+  }
+
+  if (id.empty()) {
+    /* create unique id */
+    uuid_d new_uuid;
+    char uuid_str[37];
+    new_uuid.generate_random();
+    new_uuid.print(uuid_str);
+    id = uuid_str;
+  }
+
+  ret = store_info(exclusive);
+  if (ret < 0) {
+    ldout(cct, 0) << "ERROR:  storing info for " << id << ": " << cpp_strerror(-ret) << dendl;
+    return ret;
+  }
+
+  return store_name(exclusive);
+}
+
+int RGWSystemMetaObj::store_info(bool exclusive)
+{
+  string pool_name = get_pool_name(cct);
+
+  rgw_bucket pool(pool_name.c_str());
+
+  string oid = get_info_oid_prefix() + id;
+
+  bufferlist bl;
+  ::encode(*this, bl);
+  return  rgw_put_system_obj(store, pool, oid, bl.c_str(), bl.length(), exclusive, NULL, real_time(), NULL);
+}
+
+int RGWSystemMetaObj::write(bool exclusive)
+{
+  int ret = store_info(exclusive);
+  if (ret < 0) {
+    ldout(cct, 20) << __func__ << "(): store_info() returned ret=" << ret << dendl;
+    return ret;
+  }
+  ret = store_name(exclusive);
+  if (ret < 0) {
+    ldout(cct, 20) << __func__ << "(): store_name() returned ret=" << ret << dendl;
+    return ret;
+  }
+  return 0;
+}
+
+
+const string& RGWRealm::get_predefined_name(CephContext *cct) {
+  return cct->_conf->rgw_realm;
+}
+
+int RGWRealm::create(bool exclusive)
+{
+  list<string> realms;
+  int ret = store->list_realms(realms);
+  if (ret < 0 && ret != -ENOENT) {
+    ldout(cct, 0) << "ERROR: listing realms, ret=" << ret << dendl;
+    return ret;
+  }
+
+  bool first_realm = realms.empty();
+
+  ret = RGWSystemMetaObj::create(exclusive);
+  if (ret < 0) {
+    ldout(cct, 0) << "ERROR creating new realm object " << name << ": " << cpp_strerror(-ret) << dendl;
+    return ret;
+  }
+  // create the control object for watch/notify
+  ret = create_control();
+  if (ret < 0) {
+    ldout(cct, 0) << "ERROR creating control for new realm " << name << ": " << cpp_strerror(-ret) << dendl;
+    return ret;
+  }
+  RGWPeriod period;
+  if (current_period.empty()) {
+    /* create new period for the realm */
+    ret = period.init(cct, store, id, name, false);
+    if (ret < 0 ) {
+      return ret;
+    }
+    ret = period.create(true);
+    if (ret < 0) {
+      ldout(cct, 0) << "ERROR: creating new period for realm " << name << ": " << cpp_strerror(-ret) << dendl;
+      return ret;
+    }
+  } else {
+    period = RGWPeriod(current_period, 0);
+    int ret = period.init(cct, store, id, name);
+    if (ret < 0) {
+      ldout(cct, 0) << "ERROR: failed to init period " << current_period << dendl;
+      return ret;
+    }
+  }
+  ret = set_current_period(period);
+  if (ret < 0) {
+    ldout(cct, 0) << "ERROR: failed set current period " << current_period << dendl;
+    return ret;
+  }
+
+  if (first_realm) { /* this is racy, but it's fine */
+    ret = set_as_default();
+    if (ret < 0) {
+      ldout(cct, 0) << "WARNING: failed to set realm as default realm, ret=" << ret << dendl;
+    }
+  }
+
+  return 0;
+}
+
+int RGWRealm::delete_obj()
+{
+  int ret = RGWSystemMetaObj::delete_obj();
+  if (ret < 0) {
+    return ret;
+  }
+  return delete_control();
+}
+
+int RGWRealm::create_control()
+{
+  auto pool_name = get_pool_name(cct);
+  auto pool = rgw_bucket{pool_name.c_str()};
+  auto oid = get_control_oid();
+  return rgw_put_system_obj(store, pool, oid, nullptr, 0, true,
+                            nullptr, real_time(), nullptr);
+}
+
+int RGWRealm::delete_control()
+{
+  auto pool_name = get_pool_name(cct);
+  auto pool = rgw_bucket{pool_name.c_str()};
+  auto obj = rgw_obj{pool, get_control_oid()};
+  return store->delete_system_obj(obj);
+}
+
+const string& RGWRealm::get_pool_name(CephContext *cct)
+{
+  if (cct->_conf->rgw_realm_root_pool.empty()) {
+    return RGW_DEFAULT_REALM_ROOT_POOL;
+  }
+  return cct->_conf->rgw_realm_root_pool;
+}
+
+const string RGWRealm::get_default_oid(bool old_format)
+{
+  if (cct->_conf->rgw_default_realm_info_oid.empty()) {
+    return default_realm_info_oid;
+  }
+  return cct->_conf->rgw_default_realm_info_oid;
+}
+
+const string& RGWRealm::get_names_oid_prefix()
+{
+  return realm_names_oid_prefix;
+}
+
+const string& RGWRealm::get_info_oid_prefix(bool old_format)
+{
+  return realm_info_oid_prefix;
+}
+
+int RGWRealm::set_current_period(RGWPeriod& period)
+{
+  // update realm epoch to match the period's
+  if (epoch > period.get_realm_epoch()) {
+    ldout(cct, 0) << "ERROR: set_current_period with old realm epoch "
+        << period.get_realm_epoch() << ", current epoch=" << epoch << dendl;
+    return -EINVAL;
+  }
+  if (epoch == period.get_realm_epoch() && current_period != period.get_id()) {
+    ldout(cct, 0) << "ERROR: set_current_period with same realm epoch "
+        << period.get_realm_epoch() << ", but different period id "
+        << period.get_id() << " != " << current_period << dendl;
+    return -EINVAL;
+  }
+
+  epoch = period.get_realm_epoch();
+  current_period = period.get_id();
+
+  int ret = update();
+  if (ret < 0) {
+    ldout(cct, 0) << "ERROR: period update: " << cpp_strerror(-ret) << dendl;
+    return ret;
+  }
+
+  ret = period.reflect();
+  if (ret < 0) {
+    ldout(cct, 0) << "ERROR: period.reflect(): " << cpp_strerror(-ret) << dendl;
+    return ret;
+  }
+
+  return 0;
+}
+
+string RGWRealm::get_control_oid()
+{
+  return get_info_oid_prefix() + id + ".control";
+}
+
+int RGWRealm::notify_zone(bufferlist& bl)
+{
+  // open a context on the realm's pool
+  auto pool = get_pool_name(cct);
+  librados::IoCtx ctx;
+  int r = store->get_rados_handle()->ioctx_create(pool.c_str(), ctx);
+  if (r < 0) {
+    ldout(cct, 0) << "Failed to open pool " << pool << dendl;
+    return r;
+  }
+  // send a notify on the realm object
+  r = ctx.notify2(get_control_oid(), bl, 0, nullptr);
+  if (r < 0) {
+    ldout(cct, 0) << "Realm notify failed with " << r << dendl;
+    return r;
+  }
+  return 0;
+}
+
+int RGWRealm::notify_new_period(const RGWPeriod& period)
+{
+  bufferlist bl;
+  // push the period to dependent zonegroups/zones
+  ::encode(RGWRealmNotify::ZonesNeedPeriod, bl);
+  ::encode(period, bl);
+  // reload the gateway with the new period
+  ::encode(RGWRealmNotify::Reload, bl);
+
+  return notify_zone(bl);
+}
+
+int RGWPeriod::init(CephContext *_cct, RGWRados *_store, const string& period_realm_id,
+		    const string& period_realm_name, bool setup_obj)
+{
+  cct = _cct;
+  store = _store;
+  realm_id = period_realm_id;
+  realm_name = period_realm_name;
+
+  if (!setup_obj)
+    return 0;
+
+  return init(_cct, _store, setup_obj);
+}
+
+
+int RGWPeriod::init(CephContext *_cct, RGWRados *_store, bool setup_obj)
+{
+  cct = _cct;
+  store = _store;
+
+  if (!setup_obj)
+    return 0;
+
+  if (id.empty()) {
+    RGWRealm realm(realm_id, realm_name);
+    int ret = realm.init(cct, store);
+    if (ret < 0) {
+      ldout(cct, 0) << "RGWPeriod::init failed to init realm " << realm_name  << " id " << realm_id << " : " <<
+	cpp_strerror(-ret) << dendl;
+      return ret;
+    }
+    id = realm.get_current_period();
+    realm_id = realm.get_id();
+  }
+
+  if (!epoch) {
+    int ret = use_latest_epoch();
+    if (ret < 0) {
+      ldout(cct, 0) << "failed to use_latest_epoch period id " << id << " realm " << realm_name  << " id " << realm_id
+	   << " : " << cpp_strerror(-ret) << dendl;
+      return ret;
+    }
+  }
+
+  return read_info();
+}
+
+
+int RGWPeriod::get_zonegroup(RGWZoneGroup& zonegroup, const string& zonegroup_id) {
+  map<string, RGWZoneGroup>::const_iterator iter = period_map.zonegroups.find(zonegroup_id);
+  if (iter != period_map.zonegroups.end()) {
+    zonegroup = iter->second;
+    return 0;
+  }
+
+  return -ENOENT;
+}
+
+bool RGWPeriod::is_single_zonegroup(CephContext *cct, RGWRados *store)
+{
+  return (period_map.zonegroups.size() == 1);
+}
+
+const string& RGWPeriod::get_latest_epoch_oid()
+{
+  if (cct->_conf->rgw_period_latest_epoch_info_oid.empty()) {
+    return period_latest_epoch_info_oid;
+  }
+  return cct->_conf->rgw_period_latest_epoch_info_oid;
+}
+
+const string& RGWPeriod::get_info_oid_prefix()
+{
+  return period_info_oid_prefix;
+}
+
+const string RGWPeriod::get_period_oid_prefix()
+{
+  return get_info_oid_prefix() + id;
+}
+
+const string RGWPeriod::get_period_oid()
+{
+  std::ostringstream oss;
+  oss << get_period_oid_prefix();
+  // skip the epoch for the staging period
+  if (id != get_staging_id(realm_id))
+    oss << "." << epoch;
+  return oss.str();
+}
+
+int RGWPeriod::read_latest_epoch(RGWPeriodLatestEpochInfo& info)
+{
+  string pool_name = get_pool_name(cct);
+  string oid = get_period_oid_prefix() + get_latest_epoch_oid();
+
+  rgw_bucket pool(pool_name.c_str());
+  bufferlist bl;
+  RGWObjectCtx obj_ctx(store);
+  int ret = rgw_get_system_obj(store, obj_ctx, pool, oid, bl, NULL, NULL);
+  if (ret < 0) {
+    ldout(cct, 0) << "error read_lastest_epoch " << pool << ":" << oid << dendl;
+    return ret;
+  }
+  try {
+    bufferlist::iterator iter = bl.begin();
+    ::decode(info, iter);
+  } catch (buffer::error& err) {
+    ldout(cct, 0) << "error decoding data from " << pool << ":" << oid << dendl;
+    return -EIO;
+  }
+
+  return 0;
+}
+
+int RGWPeriod::get_latest_epoch(epoch_t& latest_epoch)
+{
+  RGWPeriodLatestEpochInfo info;
+
+  int ret = read_latest_epoch(info);
+  if (ret < 0) {
+    return ret;
+  }
+
+  latest_epoch = info.epoch;
+
+  return 0;
+}
+
+int RGWPeriod::use_latest_epoch()
+{
+  RGWPeriodLatestEpochInfo info;
+  int ret = read_latest_epoch(info);
+  if (ret < 0) {
+    return ret;
+  }
+
+  epoch = info.epoch;
+
+  return 0;
+}
+
+int RGWPeriod::set_latest_epoch(epoch_t epoch, bool exclusive)
+{
+  string pool_name = get_pool_name(cct);
+  string oid = get_period_oid_prefix() + get_latest_epoch_oid();
+
+  rgw_bucket pool(pool_name.c_str());
+  bufferlist bl;
+
+  RGWPeriodLatestEpochInfo info;
+  info.epoch = epoch;
+
+  ::encode(info, bl);
+
+  return rgw_put_system_obj(store, pool, oid, bl.c_str(), bl.length(),
+                            exclusive, NULL, real_time(), NULL);
+}
+
+int RGWPeriod::delete_obj()
+{
+  string pool_name = get_pool_name(cct);
+  rgw_bucket pool(pool_name.c_str());
+
+  rgw_obj object_id(pool, get_period_oid());
+  int ret = store->delete_system_obj(object_id);
+  if (ret < 0) {
+    ldout(cct, 0) << "Error delete object id " << id << ": " << cpp_strerror(-ret) << dendl;
+  }
+
+  return ret;
+}
+
+int RGWPeriod::read_info()
+{
+  string pool_name = get_pool_name(cct);
+
+  rgw_bucket pool(pool_name.c_str());
+  bufferlist bl;
+
+  RGWObjectCtx obj_ctx(store);
+  int ret = rgw_get_system_obj(store, obj_ctx, pool, get_period_oid(), bl, NULL, NULL);
+  if (ret < 0) {
+    ldout(cct, 0) << "failed reading obj info from " << pool << ":" << get_period_oid() << ": " << cpp_strerror(-ret) << dendl;
+    return ret;
+  }
+
+  try {
+    bufferlist::iterator iter = bl.begin();
+    ::decode(*this, iter);
+  } catch (buffer::error& err) {
+    ldout(cct, 0) << "ERROR: failed to decode obj from " << pool << ":" << get_period_oid() << dendl;
+    return -EIO;
+  }
+
+  return 0;
+}
+
+int RGWPeriod::create(bool exclusive)
+{
+  int ret;
+  
+  /* create unique id */
+  uuid_d new_uuid;
+  char uuid_str[37];
+  new_uuid.generate_random();
+  new_uuid.print(uuid_str);
+  id = uuid_str;
+
+  epoch = FIRST_EPOCH;
+
+  period_map.id = id;
+  
+  ret = store_info(exclusive);
+  if (ret < 0) {
+    ldout(cct, 0) << "ERROR:  storing info for " << id << ": " << cpp_strerror(-ret) << dendl;
+  }
+
+  ret = set_latest_epoch(epoch);
+  if (ret < 0) {
+    ldout(cct, 0) << "ERROR: setting latest epoch " << id << ": " << cpp_strerror(-ret) << dendl;
+  }
+
+  return ret;
+}
+
+int RGWPeriod::store_info(bool exclusive)
+{
+  epoch_t latest_epoch = FIRST_EPOCH - 1;
+  int ret = get_latest_epoch(latest_epoch);
+  if (ret < 0 && ret != -ENOENT) {
+    ldout(cct, 0) << "ERROR: RGWPeriod::get_latest_epoch() returned " << cpp_strerror(-ret) << dendl;
+    return ret;
+  }
+  string pool_name = get_pool_name(cct);
+
+  rgw_bucket pool(pool_name.c_str());
+
+  string oid = get_period_oid();
+  bufferlist bl;
+  ::encode(*this, bl);
+  ret = rgw_put_system_obj(store, pool, oid, bl.c_str(), bl.length(), exclusive, NULL, real_time(), NULL);
+  if (ret < 0) {
+    ldout(cct, 0) << "ERROR: rgw_put_system_obj(" << pool << ":" << oid << "): " << cpp_strerror(-ret) << dendl;
+    return ret;
+  }
+  if (latest_epoch < epoch) {
+    ret = set_latest_epoch(epoch);
+    if (ret < 0) {
+      ldout(cct, 0) << "ERROR: RGWPeriod::set_latest_epoch() returned " << cpp_strerror(-ret) << dendl;
+      return ret;
+    }
+  }
+  return 0;
+}
+
+const string& RGWPeriod::get_pool_name(CephContext *cct)
+{
+  if (cct->_conf->rgw_period_root_pool.empty()) {
+    return RGW_DEFAULT_PERIOD_ROOT_POOL;
+  }
+  return cct->_conf->rgw_period_root_pool;
+}
+
+int RGWPeriod::use_next_epoch()
+{
+  epoch_t latest_epoch;
+  int ret = get_latest_epoch(latest_epoch);
+  if (ret < 0) {
+    return ret;
+  }
+  epoch = latest_epoch + 1;
+  ret = read_info();
+  if (ret < 0 && ret != -ENOENT) {
+    return ret;
+  }
+  if (ret == -ENOENT) {
+    ret = create();
+    if (ret < 0) {
+      ldout(cct, 0) << "Error creating new epoch " << epoch << dendl;
+      return ret;
+    }
+  }
+  return 0;
+}
+
+int RGWPeriod::add_zonegroup(const RGWZoneGroup& zonegroup)
+{
+  if (zonegroup.realm_id != realm_id) {
+    return 0;
+  }
+  int ret = period_map.update(zonegroup);
+  if (ret < 0) {
+    ldout(cct, 0) << "ERROR: updating period map: " << cpp_strerror(-ret) << dendl;
+    return ret;
+  }
+
+  return store_info(false);
+}
+
+int RGWPeriod::update()
+{
+  ldout(cct, 20) << __func__ << " realm " << realm_id << " period " << get_id() << dendl;
+  list<string> zonegroups;
+  int ret = store->list_zonegroups(zonegroups);
+  if (ret < 0) {
+    ldout(cct, 0) << "ERROR: failed to list zonegroups: " << cpp_strerror(-ret) << dendl;
+    return ret;
+  }
+
+  for (auto& iter : zonegroups) {
+    RGWZoneGroup zg(string(), iter);
+    ret = zg.init(cct, store);
+    if (ret < 0) {
+      ldout(cct, 0) << "WARNING: zg.init() failed: " << cpp_strerror(-ret) << dendl;
+      continue;
+    }
+
+    if (zg.realm_id != realm_id) {
+      ldout(cct, 20) << "skipping zonegroup " << zg.get_name() << " zone realm id " << zg.realm_id << ", not on our realm " << realm_id << dendl;
+      continue;
+    }
+    
+    if (zg.is_master_zonegroup()) {
+      master_zonegroup = zg.get_id();
+      master_zone = zg.master_zone;
+    }
+
+    int ret = period_map.update(zg);
+    if (ret < 0) {
+      ldout(cct, 0) << "ERROR: updating period map: " << cpp_strerror(-ret) << dendl;
+      return ret;
+    }
+  }
+
+  return 0;
+}
+
+int RGWPeriod::reflect()
+{
+  for (auto& iter : period_map.zonegroups) {
+    RGWZoneGroup& zg = iter.second;
+    zg.reinit_instance(cct, store);
+    int r = zg.write(false);
+    if (r < 0) {
+      ldout(cct, 0) << "ERROR: failed to store zonegroup info for zonegroup=" << iter.first << ": " << cpp_strerror(-r) << dendl;
+      return r;
+    }
+  }
+  return 0;
+}
+
+void RGWPeriod::fork()
+{
+  ldout(cct, 20) << __func__ << " realm " << realm_id << " period " << id << dendl;
+  predecessor_uuid = id;
+  id = get_staging_id(realm_id);
+  period_map.reset();
+  realm_epoch++;
+}
+
+void RGWPeriod::update(const RGWZoneGroupMap& map)
+{
+  ldout(cct, 20) << __func__ << " realm " << realm_id << " period " << id << dendl;
+  for (std::map<string, RGWZoneGroup>::const_iterator iter = map.zonegroups.begin();
+       iter != map.zonegroups.end(); iter++) {
+    period_map.zonegroups_by_api[iter->second.api_name] = iter->second;
+    period_map.zonegroups[iter->second.get_name()] = iter->second;
+  }
+
+  period_config.bucket_quota = map.bucket_quota;
+  period_config.user_quota = map.user_quota;
+  period_map.master_zonegroup = map.master_zonegroup;
+}
+
+int RGWPeriod::update_sync_status()
+{
+  // must be new period's master zone to write sync status
+  if (master_zone != store->get_zone_params().get_id()) {
+    ldout(cct, 0) << "my zone " << store->get_zone_params().get_id()
+        << " is not period's master zone " << master_zone << dendl;
+    return -EINVAL;
+  }
+
+  auto mdlog = store->meta_mgr->get_log(get_id());
+  const auto num_shards = cct->_conf->rgw_md_log_max_shards;
+
+  std::vector<std::string> markers;
+  markers.reserve(num_shards);
+
+  // gather the markers for each shard
+  // TODO: use coroutines to read them in parallel
+  for (int i = 0; i < num_shards; i++) {
+    RGWMetadataLogInfo info;
+    int r = mdlog->get_info(i, &info);
+    if (r < 0) {
+      ldout(cct, 0) << "period failed to get metadata log info for shard " << i
+          << ": " << cpp_strerror(-r) << dendl;
+      return r;
+    }
+    ldout(cct, 15) << "got shard " << i << " marker " << info.marker << dendl;
+    markers.emplace_back(std::move(info.marker));
+  }
+
+  std::swap(sync_status, markers);
+  return 0;
+}
+
+int RGWPeriod::commit(RGWRealm& realm, const RGWPeriod& current_period)
+{
+  ldout(cct, 20) << __func__ << " realm " << realm.get_id() << " period " << current_period.get_id() << dendl;
+  // gateway must be in the master zone to commit
+  if (master_zone != store->get_zone_params().get_id()) {
+    ldout(cct, 0) << "period commit on zone " << store->get_zone_params().get_id()
+        << ", not period's master zone " << master_zone << dendl;
+    return -EINVAL;
+  }
+  // period predecessor must match current period
+  if (predecessor_uuid != current_period.get_id()) {
+    ldout(cct, 0) << "period predecessor " << predecessor_uuid
+        << " does not match current period " << current_period.get_id()
+        << dendl;
+    return -EINVAL;
+  }
+  // realm epoch must be 1 greater than current period
+  if (realm_epoch != current_period.get_realm_epoch() + 1) {
+    ldout(cct, 0) << "period's realm epoch " << realm_epoch
+        << " does not come directly after current realm epoch "
+        << current_period.get_realm_epoch() << dendl;
+    return -EINVAL;
+  }
+  // did the master zone change?
+  if (master_zone != current_period.get_master_zone()) {
+    // store the current metadata sync status in the period
+    int r = update_sync_status();
+    if (r < 0) {
+      ldout(cct, 0) << "failed to update metadata sync status: "
+          << cpp_strerror(-r) << dendl;
+      return r;
+    }
+    // create an object with a new period id
+    r = create(true);
+    if (r < 0) {
+      ldout(cct, 0) << "failed to create new period: " << cpp_strerror(-r) << dendl;
+      return r;
+    }
+    // set as current period
+    r = realm.set_current_period(*this);
+    if (r < 0) {
+      ldout(cct, 0) << "failed to update realm's current period: "
+          << cpp_strerror(-r) << dendl;
+      return r;
+    }
+    ldout(cct, 4) << "Promoted to master zone and committed new period "
+        << id << dendl;
+    realm.notify_new_period(*this);
+    return 0;
+  }
+  // period must be based on current epoch
+  if (epoch != current_period.get_epoch()) {
+    ldout(cct, 0) << "period epoch " << epoch << " does not match "
+        "predecessor epoch " << current_period.get_epoch() << dendl;
+    return -EINVAL;
+  }
+  // set period as next epoch
+  set_id(current_period.get_id());
+  set_epoch(current_period.get_epoch() + 1);
+  set_predecessor(current_period.get_predecessor());
+  realm_epoch = current_period.get_realm_epoch();
+  // write the period to rados
+  int r = store_info(false);
+  if (r < 0) {
+    ldout(cct, 0) << "failed to store period: " << cpp_strerror(-r) << dendl;
+    return r;
+  }
+  // set as latest epoch
+  r = set_latest_epoch(epoch);
+  if (r < 0) {
+    ldout(cct, 0) << "failed to set latest epoch: " << cpp_strerror(-r) << dendl;
+    return r;
+  }
+  r = reflect();
+  if (r < 0) {
+    ldout(cct, 0) << "failed to update local objects: " << cpp_strerror(-r) << dendl;
+    return r;
+  }
+  ldout(cct, 4) << "Committed new epoch " << epoch
+      << " for period " << id << dendl;
+  realm.notify_new_period(*this);
+  return 0;
+}
+
+int RGWZoneParams::create_default(bool old_format)
+{
+  name = default_zone_name;
+
+  int r = create();
+  if (r < 0) {
+    return r;
+  }
+
+  if (old_format) {
+    name = id;
+  }
+
+  return r;
+}
+
+
+int get_zones_pool_names_set(CephContext* cct,
+			     RGWRados* store,
+			     const list<string>& zones,
+			     const string& my_zone_id,
+			     set<string>& pool_names)
+{
+  for(auto const& iter : zones) {
+    RGWZoneParams zone(iter);
+    int r = zone.init(cct, store);
+    if (r < 0) {
+      ldout(cct, 0) << "Error: init zone " << iter << ":" << cpp_strerror(-r) << dendl;
+      return r;
+    }
+    if (zone.get_id() != my_zone_id) {
+      pool_names.insert(zone.domain_root.name);
+      pool_names.insert(zone.metadata_heap.name);
+      pool_names.insert(zone.control_pool.name);
+      pool_names.insert(zone.gc_pool.name);
+      pool_names.insert(zone.log_pool.name);
+      pool_names.insert(zone.intent_log_pool.name);
+      pool_names.insert(zone.usage_log_pool.name);
+      pool_names.insert(zone.user_keys_pool.name);
+      pool_names.insert(zone.user_email_pool.name);
+      pool_names.insert(zone.user_swift_pool.name);
+      pool_names.insert(zone.user_uid_pool.name);
+      for(auto& iter : zone.placement_pools) {
+	pool_names.insert(iter.second.index_pool);
+	pool_names.insert(iter.second.data_pool);
+	pool_names.insert(iter.second.data_extra_pool);
+      }
+    }
+  }
+  return 0;
+}
+
+string fix_zone_pool_name(set<string> pool_names,
+			  const string& default_prefix,
+			  const string& default_suffix,
+			  const string& suggested_name)
+{
+  string prefix = default_prefix;
+  string suffix = default_suffix;
+
+  if (!suggested_name.empty()) {
+    prefix = suggested_name.substr(0,suggested_name.find("."));
+    suffix = suggested_name.substr(prefix.length(), suggested_name.length() - 1);
+  }
+
+  string name = prefix + suffix;
+  
+  if (pool_names.find(name) == pool_names.end()) {
+    return name;
+  } else {
+    while(true) {
+      name =  prefix + "_" + std::to_string(std::rand()) + suffix;
+      if (pool_names.find(name) == pool_names.end()) {
+	return name;
+      }
+    }
+  }  
+}
+
+int RGWZoneParams::fix_pool_names()
+{
+
+  list<string> zones;
+  int r = store->list_zones(zones);
+  if (r < 0) {
+    ldout(cct, 10) << "WARNING: store->list_zones() returned r=" << r << dendl;
+  }
+
+  set<string> pool_names;
+  r = get_zones_pool_names_set(cct, store, zones, id, pool_names);
+  if (r < 0) {
+    ldout(cct, 0) << "Error: get_zones_pool_names" << r << dendl;
+    return r;
+  }
+
+  domain_root = fix_zone_pool_name(pool_names, name, ".rgw.data.root", domain_root.name);
+  metadata_heap = fix_zone_pool_name(pool_names, name, ".rgw.meta", metadata_heap.name);
+  control_pool = fix_zone_pool_name(pool_names, name, ".rgw.control", control_pool.name);
+  gc_pool = fix_zone_pool_name(pool_names, name ,".rgw.gc", gc_pool.name);
+  log_pool = fix_zone_pool_name(pool_names, name, ".rgw.log", log_pool.name);
+  intent_log_pool = fix_zone_pool_name(pool_names, name, ".rgw.intent-log", intent_log_pool.name);
+  usage_log_pool = fix_zone_pool_name(pool_names, name, ".rgw.usage", usage_log_pool.name);
+  user_keys_pool = fix_zone_pool_name(pool_names, name, ".rgw.users.keys", user_keys_pool.name);
+  user_email_pool = fix_zone_pool_name(pool_names, name, ".rgw.users.email", user_email_pool.name);
+  user_swift_pool = fix_zone_pool_name(pool_names, name, ".rgw.users.swift", user_swift_pool.name);
+  user_uid_pool = fix_zone_pool_name(pool_names, name, ".rgw.users.uid", user_uid_pool.name);
+
+  for(auto& iter : placement_pools) {
+    iter.second.index_pool = fix_zone_pool_name(pool_names, name, "." + default_bucket_index_pool_suffix,
+						iter.second.index_pool);
+    iter.second.data_pool = fix_zone_pool_name(pool_names, name, "." + default_storage_pool_suffix,
+					       iter.second.data_pool);
+    iter.second.data_extra_pool= fix_zone_pool_name(pool_names, name, "." + default_storage_extra_pool_suffix,
+						    iter.second.data_extra_pool);
+  }
+
+  return 0;
+}
+
+int RGWZoneParams::create(bool exclusive)
+{
+  list<string> zones;
+  int r = store->list_zones(zones);
+  if (r < 0) {
+    ldout(cct, 10) << "WARNING: store->list_zones() returned r=" << r << dendl;
+  }
+
+  /* check for old pools config */
+  rgw_obj obj(domain_root, avail_pools);
+  r = store->raw_obj_stat(obj, NULL, NULL, NULL, NULL, NULL, NULL);
+  if (r < 0) {
+    ldout(store->ctx(), 10) << "couldn't find old data placement pools config, setting up new ones for the zone" << dendl;
+    /* a new system, let's set new placement info */
+    RGWZonePlacementInfo default_placement;
+    default_placement.index_pool = name + "." + default_bucket_index_pool_suffix;
+    default_placement.data_pool =  name + "." + default_storage_pool_suffix;
+    default_placement.data_extra_pool = name + "." + default_storage_extra_pool_suffix;
+    placement_pools["default-placement"] = default_placement;
+  }
+
+  r = fix_pool_names();
+  if (r < 0) {
+    ldout(cct, 0) << "ERROR: fix_pool_names returned r=" << r << dendl;
+    return r;
+  }
+
+  r = RGWSystemMetaObj::create(exclusive);
+  if (r < 0) {
+    ldout(cct, 0) << "RGWZoneParams::create(): error creating default zone params: " << cpp_strerror(-r) << dendl;
+    return r;
+  }
+
+  if (zones.empty()) { /* first zone? maybe, it's a racy check */
+    r = set_as_default();
+    if (r < 0) {
+      ldout(cct, 10) << "WARNING: failed to set zone as default, r=" << r << dendl;
+    }
+  }
+
+  return 0;
+}
+
+const string& RGWZoneParams::get_pool_name(CephContext *cct)
+{
+  if (cct->_conf->rgw_zone_root_pool.empty()) {
+    return RGW_DEFAULT_ZONE_ROOT_POOL;
+  }
+
+  return cct->_conf->rgw_zone_root_pool;
+}
+
+const string RGWZoneParams::get_default_oid(bool old_format)
+{
+  if (old_format) {
+    return cct->_conf->rgw_default_zone_info_oid;
+  }
+
+  return cct->_conf->rgw_default_zone_info_oid + "." + realm_id;
+}
+
+const string& RGWZoneParams::get_names_oid_prefix()
+{
+  return zone_names_oid_prefix;
+}
+
+const string& RGWZoneParams::get_info_oid_prefix(bool old_format)
+{
+  return zone_info_oid_prefix;
+}
+
+const string& RGWZoneParams::get_predefined_name(CephContext *cct) {
+  return cct->_conf->rgw_zone;
+}
+
+int RGWZoneParams::init(CephContext *cct, RGWRados *store, bool setup_obj, bool old_format)
+{
+  if (name.empty()) {
+    name = cct->_conf->rgw_zone;
+  }
+
+  int ret = RGWSystemMetaObj::init(cct, store, setup_obj, old_format);
+  if (ret < 0) {
+    return ret;
+  }
+
+  return ret;
+}
+
+int RGWZoneParams::read_default_id(string& default_id, bool old_format)
+{
+  if (realm_id.empty()) {
+    /* try using default realm */
+    RGWRealm realm;
+    int ret = realm.init(cct, store);
+    if (ret < 0) {
+      ldout(cct, 10) << "could not read realm id: " << cpp_strerror(-ret) << dendl;
+      return -ENOENT;
+    }
+    realm_id = realm.get_id();
+  }
+
+  return RGWSystemMetaObj::read_default_id(default_id, old_format);
+}
+
+
+int RGWZoneParams::set_as_default()
+{
+  if (realm_id.empty()) {
+    /* try using default realm */
+    RGWRealm realm;
+    int ret = realm.init(cct, store);
+    if (ret < 0) {
+      ldout(cct, 10) << "could not read realm id: " << cpp_strerror(-ret) << dendl;
+      return -EINVAL;
+    }
+    realm_id = realm.get_id();
+  }
+
+  return RGWSystemMetaObj::set_as_default();
+}
+
+void RGWPeriodMap::encode(bufferlist& bl) const {
+  ENCODE_START(2, 1, bl);
+  ::encode(id, bl);
+  ::encode(zonegroups, bl);
+  ::encode(master_zonegroup, bl);
+  ::encode(short_zone_ids, bl);
+  ENCODE_FINISH(bl);
+}
+
+void RGWPeriodMap::decode(bufferlist::iterator& bl) {
+  DECODE_START(2, bl);
+  ::decode(id, bl);
+  ::decode(zonegroups, bl);
+  ::decode(master_zonegroup, bl);
+  if (struct_v >= 2) {
+    ::decode(short_zone_ids, bl);
+  }
+  DECODE_FINISH(bl);
+
+  zonegroups_by_api.clear();
+  for (map<string, RGWZoneGroup>::iterator iter = zonegroups.begin();
+       iter != zonegroups.end(); ++iter) {
+    RGWZoneGroup& zonegroup = iter->second;
+    zonegroups_by_api[zonegroup.api_name] = zonegroup;
+    if (zonegroup.is_master) {
+      master_zonegroup = zonegroup.get_id();
+    }
+  }
+}
+
+int RGWPeriodMap::update(const RGWZoneGroup& zonegroup)
+{
+  if (zonegroup.is_master && (!master_zonegroup.empty() && zonegroup.get_id() != master_zonegroup)) {
+    return -EINVAL;
+  }
+  map<string, RGWZoneGroup>::iterator iter = zonegroups.find(zonegroup.get_id());
+  if (iter != zonegroups.end()) {
+    RGWZoneGroup& old_zonegroup = iter->second;
+    if (!old_zonegroup.api_name.empty()) {
+      zonegroups_by_api.erase(old_zonegroup.api_name);
+    }
+  }
+  zonegroups[zonegroup.get_id()] = zonegroup;
+
+  if (!zonegroup.api_name.empty()) {
+    zonegroups_by_api[zonegroup.api_name] = zonegroup;
+  }
+
+  if (zonegroup.is_master) {
+    master_zonegroup = zonegroup.get_id();
+  } else if (master_zonegroup == zonegroup.get_id()) {
+    master_zonegroup = "";
+  }
+
+  for (auto iter : zonegroups) {
+    for (auto i : iter.second.zones) {
+      string& zone_id = i.second.id;
+      if (short_zone_ids.find(zone_id) == short_zone_ids.end()) {
+        uint32_t short_id;
+
+        unsigned char md5[CEPH_CRYPTO_MD5_DIGESTSIZE];
+        MD5 hash;
+        hash.Update((const byte *)zone_id.c_str(), zone_id.size());
+        hash.Final(md5);
+        memcpy((char *)&short_id, md5, sizeof(short_id));
+
+        if (short_id == 0) {
+          ++short_id;
+        }
+
+        short_zone_ids[i.second.id] = short_id;
+      }
+    }
+  }
+
+  return 0;
+}
+
+uint32_t RGWPeriodMap::get_zone_short_id(const string& zone_id) const
+{
+  auto i = short_zone_ids.find(zone_id);
+  if (i == short_zone_ids.end()) {
+    return 0;
+  }
+  return i->second;
+}
+
+int RGWZoneGroupMap::read(CephContext *cct, RGWRados *store)
+{
+
+  RGWPeriod period;
+  int ret = period.init(cct, store);
+  if (ret < 0) {
+    cerr << "failed to read current period info: " << cpp_strerror(ret);
+    return ret;
+  }
+	
+  bucket_quota = period.get_config().bucket_quota;
+  user_quota = period.get_config().user_quota;
+  zonegroups = period.get_map().zonegroups;
+  zonegroups_by_api = period.get_map().zonegroups_by_api;
+  master_zonegroup = period.get_map().master_zonegroup;
+
+  return 0;
+}
+
+void RGWRegionMap::encode(bufferlist& bl) const {
+  ENCODE_START( 3, 1, bl);
+  ::encode(regions, bl);
+  ::encode(master_region, bl);
+  ::encode(bucket_quota, bl);
+  ::encode(user_quota, bl);
+  ENCODE_FINISH(bl);
+}
+
+void RGWRegionMap::decode(bufferlist::iterator& bl) {
+  DECODE_START(3, bl);
+  ::decode(regions, bl);
+  ::decode(master_region, bl);
+  if (struct_v >= 2)
+    ::decode(bucket_quota, bl);
+  if (struct_v >= 3)
+    ::decode(user_quota, bl);
+  DECODE_FINISH(bl);
+}
+
+void RGWZoneGroupMap::encode(bufferlist& bl) const {
+  ENCODE_START( 3, 1, bl);
+  ::encode(zonegroups, bl);
+  ::encode(master_zonegroup, bl);
+  ::encode(bucket_quota, bl);
+  ::encode(user_quota, bl);
+  ENCODE_FINISH(bl);
+}
+
+void RGWZoneGroupMap::decode(bufferlist::iterator& bl) {
+  DECODE_START(3, bl);
+  ::decode(zonegroups, bl);
+  ::decode(master_zonegroup, bl);
+  if (struct_v >= 2)
+    ::decode(bucket_quota, bl);
+  if (struct_v >= 3)
+    ::decode(user_quota, bl);
+  DECODE_FINISH(bl);
+
+  zonegroups_by_api.clear();
+  for (map<string, RGWZoneGroup>::iterator iter = zonegroups.begin();
+       iter != zonegroups.end(); ++iter) {
+    RGWZoneGroup& zonegroup = iter->second;
+    zonegroups_by_api[zonegroup.api_name] = zonegroup;
+    if (zonegroup.is_master) {
+      master_zonegroup = zonegroup.get_name();
+    }
+  }
+}
+
+void RGWObjVersionTracker::prepare_op_for_read(ObjectReadOperation *op)
 {
   obj_version *check_objv = version_for_check();
 
@@ -636,7 +1868,7 @@ void RGWObjManifest::obj_iterator::operator++()
     stripe_size = 0;
   }
 
-  dout(0) << "RGWObjManifest::operator++(): result: ofs=" << ofs << " stripe_ofs=" << stripe_ofs << " part_ofs=" << part_ofs << " rule->part_size=" << rule->part_size << dendl;
+  dout(20) << "RGWObjManifest::operator++(): result: ofs=" << ofs << " stripe_ofs=" << stripe_ofs << " part_ofs=" << part_ofs << " rule->part_size=" << rule->part_size << dendl;
   update_location();
 }
 
@@ -891,15 +2123,15 @@ void RGWObjVersionTracker::generate_new_write_ver(CephContext *cct)
   append_rand_alpha(cct, write_version.tag, write_version.tag, TAG_LEN);
 }
 
-int RGWPutObjProcessor::complete(string& etag, time_t *mtime, time_t set_mtime,
-                                 map<string, bufferlist>& attrs, time_t delete_at,
+int RGWPutObjProcessor::complete(string& etag, real_time *mtime, real_time set_mtime,
+                                 map<string, bufferlist>& attrs, real_time delete_at,
                                  const char *if_match, const char * if_nomatch)
 {
   int r = do_complete(etag, mtime, set_mtime, attrs, delete_at, if_match, if_nomatch);
   if (r < 0)
     return r;
 
-  is_complete = true;
+  is_complete = !canceled;
   return 0;
 }
 
@@ -1180,7 +2412,13 @@ int RGWPutObjProcessor_Atomic::complete_parts()
 int RGWPutObjProcessor_Atomic::complete_writing_data()
 {
   if (!data_ofs && !immutable_head()) {
-    first_chunk.claim(pending_data_bl);
+    /* only claim if pending_data_bl() is not empty. This is needed because we might be called twice
+     * (e.g., when a retry due to race happens). So a second call to first_chunk.claim() would
+     * clobber first_chunk
+     */
+    if (pending_data_bl.length() > 0) {
+      first_chunk.claim(pending_data_bl);
+    }
     obj_len = (uint64_t)first_chunk.length();
   }
   if (pending_data_bl.length()) {
@@ -1208,8 +2446,8 @@ int RGWPutObjProcessor_Atomic::complete_writing_data()
   return 0;
 }
 
-int RGWPutObjProcessor_Atomic::do_complete(string& etag, time_t *mtime, time_t set_mtime,
-                                           map<string, bufferlist>& attrs, time_t delete_at,
+int RGWPutObjProcessor_Atomic::do_complete(string& etag, real_time *mtime, real_time set_mtime,
+                                           map<string, bufferlist>& attrs, real_time delete_at,
                                            const char *if_match,
                                            const char *if_nomatch) {
   int r = complete_writing_data();
@@ -1242,6 +2480,8 @@ int RGWPutObjProcessor_Atomic::do_complete(string& etag, time_t *mtime, time_t s
     return r;
   }
 
+  canceled = obj_op.meta.canceled;
+
   return 0;
 }
 
@@ -1306,90 +2546,454 @@ class RGWWatcher : public librados::WatchCtx2 {
       }
   };
 public:
-  RGWWatcher(RGWRados *r, int i, const string& o) : rados(r), index(i), oid(o), watch_handle(0) {}
-  void handle_notify(uint64_t notify_id,
-		     uint64_t cookie,
-		     uint64_t notifier_id,
-		     bufferlist& bl) {
-    ldout(rados->ctx(), 10) << "RGWWatcher::handle_notify() "
-			    << " notify_id " << notify_id
-			    << " cookie " << cookie
-			    << " notifier " << notifier_id
-			    << " bl.length()=" << bl.length() << dendl;
-    rados->watch_cb(notify_id, cookie, notifier_id, bl);
+  RGWWatcher(RGWRados *r, int i, const string& o) : rados(r), index(i), oid(o), watch_handle(0) {}
+  void handle_notify(uint64_t notify_id,
+		     uint64_t cookie,
+		     uint64_t notifier_id,
+		     bufferlist& bl) {
+    ldout(rados->ctx(), 10) << "RGWWatcher::handle_notify() "
+			    << " notify_id " << notify_id
+			    << " cookie " << cookie
+			    << " notifier " << notifier_id
+			    << " bl.length()=" << bl.length() << dendl;
+    rados->watch_cb(notify_id, cookie, notifier_id, bl);
+
+    bufferlist reply_bl; // empty reply payload
+    rados->control_pool_ctx.notify_ack(oid, notify_id, cookie, reply_bl);
+  }
+  void handle_error(uint64_t cookie, int err) {
+    lderr(rados->ctx()) << "RGWWatcher::handle_error cookie " << cookie
+			<< " err " << cpp_strerror(err) << dendl;
+    rados->remove_watcher(index);
+    rados->schedule_context(new C_ReinitWatch(this));
+  }
+
+  void reinit() {
+    int ret = unregister_watch();
+    if (ret < 0) {
+      ldout(rados->ctx(), 0) << "ERROR: unregister_watch() returned ret=" << ret << dendl;
+      return;
+    }
+    ret = register_watch();
+    if (ret < 0) {
+      ldout(rados->ctx(), 0) << "ERROR: register_watch() returned ret=" << ret << dendl;
+      return;
+    }
+  }
+
+  int unregister_watch() {
+    int r = rados->unwatch(watch_handle);
+    if (r < 0) {
+      return r;
+    }
+    rados->remove_watcher(index);
+    return 0;
+  }
+
+  int register_watch() {
+    int r = rados->watch(oid, &watch_handle, this);
+    if (r < 0) {
+      return r;
+    }
+    rados->add_watcher(index);
+    return 0;
+  }
+};
+
+RGWObjState *RGWObjectCtx::get_state(rgw_obj& obj) {
+  RGWObjState *result;
+  map<rgw_obj, RGWObjState>::iterator iter;
+  lock.get_read();
+  if (!obj.get_object().empty()) {
+    iter = objs_state.find(obj);
+    if (iter != objs_state.end()) {
+      result = &iter->second;
+      lock.unlock();
+    } else {
+      lock.unlock();
+      lock.get_write();
+      result = &objs_state[obj];
+      lock.unlock();
+    }
+    return result;
+  } else {
+    rgw_obj new_obj(store->get_zone_params().domain_root, obj.bucket.name);
+    iter = objs_state.find(new_obj);
+    if (iter != objs_state.end()) {
+      result = &iter->second;
+      lock.unlock();
+    } else {
+      lock.unlock();
+      lock.get_write();
+      result = &objs_state[new_obj];
+      lock.unlock();
+    }
+    return result;
+  }
+}
+
+void RGWObjectCtx::invalidate(rgw_obj& obj)
+{
+  RWLock::WLocker wl(lock);
+  objs_state.erase(obj);
+}
+
+void RGWObjectCtx::set_atomic(rgw_obj& obj) {
+  RWLock::WLocker wl(lock);
+  if (!obj.get_object().empty()) {
+    objs_state[obj].is_atomic = true;
+  } else {
+    rgw_obj new_obj(store->get_zone_params().domain_root, obj.bucket.name);
+    objs_state[new_obj].is_atomic = true;
+  }
+}
+
+void RGWObjectCtx::set_prefetch_data(rgw_obj& obj) {
+  RWLock::WLocker wl(lock);
+  if (!obj.get_object().empty()) {
+    objs_state[obj].prefetch_data = true;
+  } else {
+    rgw_obj new_obj(store->get_zone_params().domain_root, obj.bucket.name);
+    objs_state[new_obj].prefetch_data = true;
+  }
+}
+
+class RGWMetaNotifierManager : public RGWCoroutinesManager {
+  RGWRados *store;
+  RGWHTTPManager http_manager;
+
+public:
+  RGWMetaNotifierManager(RGWRados *_store) : RGWCoroutinesManager(_store->ctx(), _store->get_cr_registry()), store(_store),
+                                             http_manager(store->ctx(), completion_mgr) {
+    http_manager.set_threaded();
+  }
+
+  int notify_all(map<string, RGWRESTConn *>& conn_map, set<int>& shards) {
+    rgw_http_param_pair pairs[] = { { "type", "metadata" },
+                                    { "notify", NULL },
+                                    { NULL, NULL } };
+
+    list<RGWCoroutinesStack *> stacks;
+    for (map<string, RGWRESTConn *>::iterator iter = conn_map.begin(); iter != conn_map.end(); ++iter) {
+      RGWRESTConn *conn = iter->second;
+      RGWCoroutinesStack *stack = new RGWCoroutinesStack(store->ctx(), this);
+      stack->call(new RGWPostRESTResourceCR<set<int>, int>(store->ctx(), conn, &http_manager, "/admin/log", pairs, shards, NULL));
+
+      stacks.push_back(stack);
+    }
+    return run(stacks);
+  }
+};
+
+class RGWDataNotifierManager : public RGWCoroutinesManager {
+  RGWRados *store;
+  RGWHTTPManager http_manager;
+
+public:
+  RGWDataNotifierManager(RGWRados *_store) : RGWCoroutinesManager(_store->ctx(), _store->get_cr_registry()), store(_store),
+                                             http_manager(store->ctx(), completion_mgr) {
+    http_manager.set_threaded();
+  }
+
+  int notify_all(map<string, RGWRESTConn *>& conn_map, map<int, set<string> >& shards) {
+    rgw_http_param_pair pairs[] = { { "type", "data" },
+                                    { "notify", NULL },
+                                    { "source-zone", store->get_zone_params().get_id().c_str() },
+                                    { NULL, NULL } };
+
+    list<RGWCoroutinesStack *> stacks;
+    for (map<string, RGWRESTConn *>::iterator iter = conn_map.begin(); iter != conn_map.end(); ++iter) {
+      RGWRESTConn *conn = iter->second;
+      RGWCoroutinesStack *stack = new RGWCoroutinesStack(store->ctx(), this);
+      stack->call(new RGWPostRESTResourceCR<map<int, set<string> >, int>(store->ctx(), conn, &http_manager, "/admin/log", pairs, shards, NULL));
+
+      stacks.push_back(stack);
+    }
+    return run(stacks);
+  }
+};
+
+class RGWRadosThread {
+  class Worker : public Thread {
+    CephContext *cct;
+    RGWRadosThread *processor;
+    Mutex lock;
+    Cond cond;
+
+  public:
+    Worker(CephContext *_cct, RGWRadosThread *_p) : cct(_cct), processor(_p), lock("RGWRadosThread::Worker") {}
+    void *entry();
+    void stop() {
+      Mutex::Locker l(lock);
+      cond.Signal();
+    }
+  };
+
+  Worker *worker;
+
+protected:
+  CephContext *cct;
+  RGWRados *store;
+
+  atomic_t down_flag;
+
+  virtual uint64_t interval_msec() = 0;
+  virtual void stop_process() {}
+public:
+  RGWRadosThread(RGWRados *_store) : worker(NULL), cct(_store->ctx()), store(_store) {}
+  virtual ~RGWRadosThread() {
+    stop();
+  }
+
+  virtual int init() { return 0; }
+  virtual int process() = 0;
+
+  bool going_down() { return down_flag.read() != 0; }
+  void start();
+  void stop();
+};
+
+void RGWRadosThread::start()
+{
+  worker = new Worker(cct, this);
+  worker->create("radosgw");
+}
+
+void RGWRadosThread::stop()
+{
+  down_flag.set(1);
+  stop_process();
+  if (worker) {
+    worker->stop();
+    worker->join();
+  }
+  delete worker;
+  worker = NULL;
+}
+
+void *RGWRadosThread::Worker::entry() {
+  uint64_t msec = processor->interval_msec();
+  utime_t interval = utime_t(msec / 1000, (msec % 1000) * 1000000);
+
+  do {
+    utime_t start = ceph_clock_now(cct);
+    int r = processor->process();
+    if (r < 0) {
+      dout(0) << "ERROR: processor->process() returned error r=" << r << dendl;
+    }
+
+    if (processor->going_down())
+      break;
+
+    utime_t end = ceph_clock_now(cct);
+    end -= start;
+
+    uint64_t cur_msec = processor->interval_msec();
+    if (cur_msec != msec) { /* was it reconfigured? */
+      msec = cur_msec;
+      interval = utime_t(msec / 1000, (msec % 1000) * 1000000);
+    }
+
+    if (cur_msec > 0) {
+      if (interval <= end)
+        continue; // next round
+
+      utime_t wait_time = interval;
+      wait_time -= end;
+
+      lock.Lock();
+      cond.WaitInterval(cct, lock, wait_time);
+      lock.Unlock();
+    } else {
+      lock.Lock();
+      cond.Wait(lock);
+      lock.Unlock();
+    }
+  } while (!processor->going_down());
+
+  return NULL;
+}
+
+class RGWMetaNotifier : public RGWRadosThread {
+  RGWMetaNotifierManager notify_mgr;
+  RGWMetadataLog *const log;
+
+  uint64_t interval_msec() {
+    return cct->_conf->rgw_md_notify_interval_msec;
+  }
+public:
+  RGWMetaNotifier(RGWRados *_store, RGWMetadataLog* log)
+    : RGWRadosThread(_store), notify_mgr(_store), log(log) {}
+
+  int process();
+};
+
+int RGWMetaNotifier::process()
+{
+  set<int> shards;
+
+  log->read_clear_modified(shards);
+
+  if (shards.empty()) {
+    return 0;
+  }
+
+  for (set<int>::iterator iter = shards.begin(); iter != shards.end(); ++iter) {
+    ldout(cct, 20) << __func__ << "(): notifying mdlog change, shard_id=" << *iter << dendl;
+  }
+
+  notify_mgr.notify_all(store->zone_conn_map, shards);
+
+  return 0;
+}
+
+class RGWDataNotifier : public RGWRadosThread {
+  RGWDataNotifierManager notify_mgr;
+
+  uint64_t interval_msec() {
+    return cct->_conf->rgw_md_notify_interval_msec;
+  }
+public:
+  RGWDataNotifier(RGWRados *_store) : RGWRadosThread(_store), notify_mgr(_store) {}
+
+  int process();
+};
+
+int RGWDataNotifier::process()
+{
+  if (!store->data_log) {
+    return 0;
+  }
+
+  map<int, set<string> > shards;
+
+  store->data_log->read_clear_modified(shards);
+
+  if (shards.empty()) {
+    return 0;
+  }
+
+  for (map<int, set<string> >::iterator iter = shards.begin(); iter != shards.end(); ++iter) {
+    ldout(cct, 20) << __func__ << "(): notifying datalog change, shard_id=" << iter->first << ": " << iter->second << dendl;
+  }
+
+  notify_mgr.notify_all(store->zone_conn_map, shards);
+
+  return 0;
+}
+
+class RGWSyncProcessorThread : public RGWRadosThread {
+public:
+  RGWSyncProcessorThread(RGWRados *_store) : RGWRadosThread(_store) {}
+  virtual ~RGWSyncProcessorThread() {}
+  virtual int init() = 0 ;
+  virtual int process() = 0;
+};
 
-    bufferlist reply_bl; // empty reply payload
-    rados->control_pool_ctx.notify_ack(oid, notify_id, cookie, reply_bl);
+class RGWMetaSyncProcessorThread : public RGWSyncProcessorThread
+{
+  RGWMetaSyncStatusManager sync;
+
+  uint64_t interval_msec() {
+    return 0; /* no interval associated, it'll run once until stopped */
   }
-  void handle_error(uint64_t cookie, int err) {
-    lderr(rados->ctx()) << "RGWWatcher::handle_error cookie " << cookie
-			<< " err " << cpp_strerror(err) << dendl;
-    rados->remove_watcher(index);
-    rados->schedule_context(new C_ReinitWatch(this));
+  void stop_process() {
+    sync.stop();
   }
+public:
+  RGWMetaSyncProcessorThread(RGWRados *_store, RGWAsyncRadosProcessor *async_rados)
+    : RGWSyncProcessorThread(_store), sync(_store, async_rados) {}
 
-  void reinit() {
-    int ret = unregister_watch();
-    if (ret < 0) {
-      ldout(rados->ctx(), 0) << "ERROR: unregister_watch() returned ret=" << ret << dendl;
-      return;
+  void wakeup_sync_shards(set<int>& shard_ids) {
+    for (set<int>::iterator iter = shard_ids.begin(); iter != shard_ids.end(); ++iter) {
+      sync.wakeup(*iter);
     }
-    ret = register_watch();
+  }
+
+  int init() {
+    int ret = sync.init();
     if (ret < 0) {
-      ldout(rados->ctx(), 0) << "ERROR: register_watch() returned ret=" << ret << dendl;
-      return;
+      ldout(store->ctx(), 0) << "ERROR: sync.init() returned " << ret << dendl;
+      return ret;
     }
+    return 0;
   }
 
-  int unregister_watch() {
-    int r = rados->unwatch(watch_handle);
-    if (r < 0) {
-      return r;
+  int process() {
+    sync.run();
+    return 0;
+  }
+};
+
+class RGWDataSyncProcessorThread : public RGWSyncProcessorThread
+{
+  RGWDataSyncStatusManager sync;
+  bool initialized;
+
+  uint64_t interval_msec() {
+    if (initialized) {
+      return 0; /* no interval associated, it'll run once until stopped */
+    } else {
+#define DATA_SYNC_INIT_WAIT_SEC 20
+      return DATA_SYNC_INIT_WAIT_SEC * 1000;
     }
-    rados->remove_watcher(index);
+  }
+  void stop_process() {
+    sync.stop();
+  }
+public:
+  RGWDataSyncProcessorThread(RGWRados *_store, RGWAsyncRadosProcessor *async_rados,
+                             const string& _source_zone)
+    : RGWSyncProcessorThread(_store), sync(_store, async_rados, _source_zone),
+      initialized(false) {}
+
+  void wakeup_sync_shards(map<int, set<string> >& shard_ids) {
+    for (map<int, set<string> >::iterator iter = shard_ids.begin(); iter != shard_ids.end(); ++iter) {
+      sync.wakeup(iter->first, iter->second);
+    }
+  }
+
+
+  int init() {
     return 0;
   }
 
-  int register_watch() {
-    int r = rados->watch(oid, &watch_handle, this);
-    if (r < 0) {
-      return r;
+  int process() {
+    while (!going_down()) {
+      int ret = sync.init();
+      if (ret >= 0) {
+        initialized = true;
+        break;
+      }
+      /* we'll be back! */
+      return 0;
     }
-    rados->add_watcher(index);
+    sync.run();
     return 0;
   }
 };
 
-RGWObjState *RGWObjectCtx::get_state(rgw_obj& obj) {
-  if (!obj.get_object().empty()) {
-    return &objs_state[obj];
-  } else {
-    rgw_obj new_obj(store->zone.domain_root, obj.bucket.name);
-    return &objs_state[new_obj];
+void RGWRados::wakeup_meta_sync_shards(set<int>& shard_ids)
+{
+  Mutex::Locker l(meta_sync_thread_lock);
+  if (meta_sync_processor_thread) {
+    meta_sync_processor_thread->wakeup_sync_shards(shard_ids);
   }
 }
 
-void RGWObjectCtx::invalidate(rgw_obj& obj)
+void RGWRados::wakeup_data_sync_shards(const string& source_zone, map<int, set<string> >& shard_ids)
 {
-  objs_state.erase(obj);
-}
-
-void RGWObjectCtx::set_atomic(rgw_obj& obj) {
-  if (!obj.get_object().empty()) {
-    objs_state[obj].is_atomic = true;
-  } else {
-    rgw_obj new_obj(store->zone.domain_root, obj.bucket.name);
-    objs_state[new_obj].is_atomic = true;
+  ldout(ctx(), 20) << __func__ << ": source_zone=" << source_zone << ", shard_ids=" << shard_ids << dendl;
+  Mutex::Locker l(data_sync_thread_lock);
+  map<string, RGWDataSyncProcessorThread *>::iterator iter = data_sync_processor_threads.find(source_zone);
+  if (iter == data_sync_processor_threads.end()) {
+    ldout(ctx(), 10) << __func__ << ": couldn't find sync thread for zone " << source_zone << ", skipping async data sync processing" << dendl;
+    return;
   }
-}
 
-void RGWObjectCtx::set_prefetch_data(rgw_obj& obj) {
-  if (!obj.get_object().empty()) {
-    objs_state[obj].prefetch_data = true;
-  } else {
-    rgw_obj new_obj(store->zone.domain_root, obj.bucket.name);
-    objs_state[new_obj].prefetch_data = true;
-  }
+  RGWDataSyncProcessorThread *thread = iter->second;
+  assert(thread);
+  thread->wakeup_sync_shards(shard_ids);
 }
 
 int RGWRados::get_required_alignment(rgw_bucket& bucket, uint64_t *alignment)
@@ -1452,6 +3056,29 @@ int RGWRados::get_max_chunk_size(rgw_bucket& bucket, uint64_t *max_chunk_size)
 
 void RGWRados::finalize()
 {
+  if (run_sync_thread) {
+    Mutex::Locker l(meta_sync_thread_lock);
+    meta_sync_processor_thread->stop();
+
+    Mutex::Locker dl(data_sync_thread_lock);
+    for (auto iter : data_sync_processor_threads) {
+      RGWDataSyncProcessorThread *thread = iter.second;
+      thread->stop();
+    }
+  }
+  if (async_rados) {
+    async_rados->stop();
+  }
+  if (run_sync_thread) {
+    delete meta_sync_processor_thread;
+    meta_sync_processor_thread = NULL;
+    Mutex::Locker dl(data_sync_thread_lock);
+    for (auto iter : data_sync_processor_threads) {
+      RGWDataSyncProcessorThread *thread = iter.second;
+      delete thread;
+    }
+    data_sync_processor_threads.clear();
+  }
   if (finisher) {
     finisher->stop();
   }
@@ -1465,8 +3092,19 @@ void RGWRados::finalize()
      */
     delete finisher;
   }
+  if (meta_notifier) {
+    meta_notifier->stop();
+    delete meta_notifier;
+  }
+  if (data_notifier) {
+    data_notifier->stop();
+    delete data_notifier;
+  }
   delete meta_mgr;
   delete data_log;
+  if (async_rados) {
+    delete async_rados;
+  }
   if (use_gc_thread) {
     gc->stop_processor();
     obj_expirer->stop_processor();
@@ -1485,11 +3123,14 @@ void RGWRados::finalize()
     delete conn;
   }
 
-  for (iter = region_conn_map.begin(); iter != region_conn_map.end(); ++iter) {
+  for (iter = zonegroup_conn_map.begin(); iter != zonegroup_conn_map.end(); ++iter) {
     RGWRESTConn *conn = iter->second;
     delete conn;
   }
   RGWQuotaHandler::free_handler(quota_handler);
+  if (cr_registry) {
+    cr_registry->put();
+  }
 }
 
 /** 
@@ -1527,6 +3168,12 @@ int RGWRados::init_rados()
     }
   }
 
+  cr_registry = new RGWCoroutinesManagerRegistry(cct);
+  ret =  cr_registry->hook_to_admin_command("cr dump");
+  if (ret < 0) {
+    goto fail;
+  }
+
   meta_mgr = new RGWMetadataManager(cct, this);
   data_log = new RGWDataChangesLog(cct, this);
 
@@ -1550,20 +3197,330 @@ fail:
 
 /**
  * Add new connection to connections map
- * @param region_conn_map map which new connection will be added to 
- * @param region region which new connection will connect to
+ * @param zonegroup_conn_map map which new connection will be added to
+ * @param zonegroup zonegroup which new connection will connect to
  * @param new_connection pointer to new connection instance
  */
-static void add_new_connection_to_map(map<string, RGWRESTConn *> &region_conn_map, RGWRegion &region, RGWRESTConn *new_connection) 
+static void add_new_connection_to_map(map<string, RGWRESTConn *> &zonegroup_conn_map,
+				      const RGWZoneGroup &zonegroup, RGWRESTConn *new_connection)
 {
   // Delete if connection is already exists
-  map<string, RGWRESTConn *>::iterator iterRegion = region_conn_map.find(region.name);
-  if (iterRegion != region_conn_map.end()) {
-    delete iterRegion->second;
+  map<string, RGWRESTConn *>::iterator iterZoneGroup = zonegroup_conn_map.find(zonegroup.get_id());
+  if (iterZoneGroup != zonegroup_conn_map.end()) {
+    delete iterZoneGroup->second;
   }
     
   // Add new connection to connections map
-  region_conn_map[region.name] = new_connection;
+  zonegroup_conn_map[zonegroup.get_id()] = new_connection;
+}
+
+int RGWRados::convert_regionmap()
+{
+  RGWZoneGroupMap zonegroupmap;
+
+  string pool_name = cct->_conf->rgw_zone_root_pool;
+  if (pool_name.empty()) {
+    pool_name = RGW_DEFAULT_ZONE_ROOT_POOL;
+  }
+  string oid = region_map_oid; 
+
+  rgw_bucket pool(pool_name.c_str());
+  bufferlist bl;
+  RGWObjectCtx obj_ctx(this);
+  int ret = rgw_get_system_obj(this, obj_ctx, pool, oid, bl, NULL, NULL);
+  if (ret < 0 && ret != -ENOENT) {
+    return ret;
+  } else if (ret == -ENOENT) {
+    return 0;
+  }
+
+  try {
+    bufferlist::iterator iter = bl.begin();
+    ::decode(zonegroupmap, iter);
+  } catch (buffer::error& err) {
+    ldout(cct, 0) << "error decoding regionmap from " << pool << ":" << oid << dendl;
+    return -EIO;
+  }
+  
+  for (map<string, RGWZoneGroup>::iterator iter = zonegroupmap.zonegroups.begin();
+       iter != zonegroupmap.zonegroups.end(); ++iter) {
+    RGWZoneGroup& zonegroup = iter->second;
+    ret = zonegroup.init(cct, this, false);
+    ret = zonegroup.update();
+    if (ret < 0 && ret != -ENOENT) {
+      ldout(cct, 0) << "Error could not update zonegroup " << zonegroup.get_name() << ": " <<
+	cpp_strerror(-ret) << dendl;
+      return ret;
+    } else if (ret == -ENOENT) {
+      ret = zonegroup.create();
+      if (ret < 0) {
+	ldout(cct, 0) << "Error could not create " << zonegroup.get_name() << ": " <<
+	  cpp_strerror(-ret) << dendl;
+	return ret;
+      }
+    }
+  }
+
+  current_period.set_user_quota(zonegroupmap.user_quota);
+  current_period.set_bucket_quota(zonegroupmap.bucket_quota);
+
+  return 0;
+}
+
+/** 
+ * Replace all region configuration with zonegroup for
+ * backward compatability
+ * Returns 0 on success, -ERR# on failure.
+ */
+int RGWRados::replace_region_with_zonegroup()
+{
+  if (!cct->_conf->rgw_region.empty() && cct->_conf->rgw_zonegroup.empty()) {
+    int ret = cct->_conf->set_val("rgw_zonegroup", cct->_conf->rgw_region, true, false);
+    if (ret < 0) {
+      ldout(cct, 0) << "failed to set rgw_zonegroup to " << cct->_conf->rgw_region << dendl;
+      return ret;
+    }
+  }
+
+  /* copy default region */
+  /* convert default region to default zonegroup */
+  string default_oid = cct->_conf->rgw_default_region_info_oid;
+  if (default_oid.empty()) {
+    default_oid = default_region_info_oid;
+  }
+
+  string default_region;
+  RGWZoneGroup default_zonegroup;
+  int ret = default_zonegroup.init(cct, this, false, true);
+  if (ret < 0) {
+    ldout(cct, 0) << "failed init default region: ret "<< ret << " " << cpp_strerror(-ret) << dendl;
+    return ret;
+  }    
+  ret  = default_zonegroup.read_default_id(default_region, true);
+  if (ret < 0 && ret != -ENOENT) {
+    ldout(cct, 0) << "failed reading old default region: ret "<< ret << " " << cpp_strerror(-ret) << dendl;
+    return ret;
+  }
+
+  /* convert regions to zonegroups */
+  list<string> regions;
+  ret = list_regions(regions);
+  if (ret < 0 && ret != -ENOENT) {
+    ldout(cct, 0) << "failed to list regions: ret "<< ret << " " << cpp_strerror(-ret) << dendl;
+    return ret;
+  } else if (ret == -ENOENT || regions.empty()) {
+    return 0;
+  }
+
+  string master_region, master_zone;
+  for (list<string>::iterator iter = regions.begin(); iter != regions.end(); ++iter) {
+    if (*iter != default_zonegroup_name){
+      RGWZoneGroup region(*iter);
+      int ret = region.init(cct, this, true, true);
+      if (ret < 0) {
+	  ldout(cct, 0) << "failed init region "<< *iter << ": " << cpp_strerror(-ret) << dendl;
+	  return ret;
+      }
+      if (region.is_master) {
+	master_region = region.get_id();
+	master_zone = region.master_zone;
+      }
+    }
+  }
+
+  /* create realm if there is none.
+     The realm name will be the region and zone concatenated
+     realm id will be mds of its name */
+  if (realm.get_id().empty() && !master_region.empty() && !master_zone.empty()) {
+    string new_realm_name = master_region + "." + master_zone;
+    unsigned char md5[CEPH_CRYPTO_MD5_DIGESTSIZE];
+    char md5_str[CEPH_CRYPTO_MD5_DIGESTSIZE * 2 + 1];
+    MD5 hash;
+    hash.Update((const byte *)new_realm_name.c_str(), new_realm_name.length());
+    hash.Final(md5);
+    buf_to_hex(md5, CEPH_CRYPTO_MD5_DIGESTSIZE, md5_str);
+    string new_realm_id(md5_str);
+    RGWRealm new_realm(new_realm_id,new_realm_name);
+    ret = new_realm.init(cct, this, false);
+    if (ret < 0) {
+      ldout(cct, 0) << "Error initing new realm: " << cpp_strerror(-ret)  << dendl;
+      return ret;
+    }
+    ret = new_realm.create();
+    if (ret < 0 && ret != -EEXIST) {
+      ldout(cct, 0) << "Error creating new realm: " << cpp_strerror(-ret)  << dendl;
+      return ret;
+    }
+    ret = new_realm.set_as_default();
+    if (ret < 0) {
+      ldout(cct, 0) << "Error setting realm as default: " << cpp_strerror(-ret)  << dendl;
+      return ret;
+    }
+    ret = realm.init(cct, this);
+    if (ret < 0) {
+      ldout(cct, 0) << "Error initing realm: " << cpp_strerror(-ret)  << dendl;
+      return ret;
+    }
+    ret = current_period.init(cct, this, realm.get_id(), realm.get_name());
+    if (ret < 0) {
+      ldout(cct, 0) << "Error initing current period: " << cpp_strerror(-ret)  << dendl;
+      return ret;
+    }
+  }
+
+  list<string>::iterator iter;
+  /* create zonegroups */
+  for (iter = regions.begin(); iter != regions.end(); ++iter)
+  {
+    /* read region info default has no data */
+    if (*iter != default_zonegroup_name){
+      RGWZoneGroup zonegroup(*iter);
+      int ret = zonegroup.init(cct, this, true, true);
+      if (ret < 0) {
+	ldout(cct, 0) << "failed init zonegroup: ret "<< ret << " " << cpp_strerror(-ret) << dendl;
+	return ret;
+      }
+      zonegroup.realm_id = realm.get_id();
+      ret = zonegroup.update();
+      if (ret < 0 && ret != -EEXIST) {
+	ldout(cct, 0) << "failed to update zonegroup " << *iter << ": ret "<< ret << " " << cpp_strerror(-ret)
+		   << dendl;
+	return ret;
+      }
+      ret = zonegroup.update_name();
+      if (ret < 0 && ret != -EEXIST) {
+	ldout(cct, 0) << "failed to update_name for zonegroup " << *iter << ": ret "<< ret << " " << cpp_strerror(-ret)
+		   << dendl;
+	return ret;
+      }
+      if (zonegroup.get_name() == default_region) {
+	ret = zonegroup.set_as_default();
+	if (ret < 0) {
+	  ldout(cct, 0) << "failed to set_as_default " << *iter << ": ret "<< ret << " " << cpp_strerror(-ret)
+		     << dendl;
+	  return ret;
+	}
+      }
+      for (map<string, RGWZone>::const_iterator iter = zonegroup.zones.begin(); iter != zonegroup.zones.end();
+	   iter ++) {
+	RGWZoneParams zoneparams(iter->first, iter->first);
+	ret = zoneparams.init(cct, this);
+	if (ret < 0) {
+	  ldout(cct, 0) << "failed to init zoneparams  " << iter->first <<  ": " << cpp_strerror(-ret) << dendl;
+	  return ret;
+	}
+	zonegroup.realm_id = realm.get_id();
+	ret = zoneparams.update();
+	if (ret < 0 && ret != -EEXIST) {
+	  ldout(cct, 0) << "failed to update zoneparams " << iter->first <<  ": " << cpp_strerror(-ret) << dendl;
+	  return ret;
+	}
+	ret = zoneparams.update_name();
+	if (ret < 0 && ret != -EEXIST) {
+	  ldout(cct, 0) << "failed to init zoneparams " << iter->first <<  ": " << cpp_strerror(-ret) << dendl;
+	  return ret;
+	}
+      }
+
+      if (!current_period.get_id().empty()) {
+	ret = current_period.add_zonegroup(zonegroup);
+	if (ret < 0) {
+	  ldout(cct, 0) << "failed to add zonegroup to current_period: " << cpp_strerror(-ret) << dendl;
+	  return ret;
+	}
+	ret = current_period.update();
+	if (ret < 0) {
+	  ldout(cct, 0) << "failed to update current_period: " << cpp_strerror(-ret) << dendl;
+	  return ret;
+	}
+      }
+
+      ret = zonegroup.delete_obj(true);
+      if (ret < 0 && ret != -ENOENT) {
+	ldout(cct, 0) << "failed to delete region " << *iter << ": ret "<< ret << " " << cpp_strerror(-ret)
+		   << dendl;
+	return ret;
+      }
+    }
+  }
+
+  return 0;
+}
+
+int RGWRados::init_zg_from_period(bool *initialized)
+{
+  *initialized = false;
+
+  if (current_period.get_id().empty()) {
+    return 0;
+  }
+
+  int ret = zonegroup.init(cct, this);
+  ldout(cct, 20) << "period zonegroup init ret " << ret << dendl;
+  if (ret == -ENOENT) {
+    return 0;
+  }
+  if (ret < 0) {
+    ldout(cct, 0) << "failed reading zonegroup info: " << " " << cpp_strerror(-ret) << dendl;
+    return ret;
+  }
+  ldout(cct, 20) << "period zonegroup name " << zonegroup.get_name() << dendl;
+
+  map<string, RGWZoneGroup>::const_iterator iter =
+    current_period.get_map().zonegroups.find(zonegroup.get_id());
+
+  if (iter != current_period.get_map().zonegroups.end()) {
+    ldout(cct, 20) << "using current period zonegroup " << zonegroup.get_name() << dendl;
+    zonegroup = iter->second;
+    ret = zone_params.init(cct, this);
+    if (ret < 0 && ret != -ENOENT) {
+      ldout(cct, 0) << "failed reading zone params info: " << " " << cpp_strerror(-ret) << dendl;
+      return ret;
+    }
+  }
+  for (iter = current_period.get_map().zonegroups.begin();
+       iter != current_period.get_map().zonegroups.end(); ++iter){
+    const RGWZoneGroup& zg = iter->second;
+    add_new_connection_to_map(zonegroup_conn_map, zg, new RGWRESTConn(cct, this, zg.get_id(), zg.endpoints));
+    if (!current_period.get_master_zonegroup().empty() &&
+        zg.get_id() == current_period.get_master_zonegroup()) {
+      rest_master_conn = new RGWRESTConn(cct, this, zg.get_id(), zg.endpoints);
+    }
+  }
+
+  *initialized = true;
+
+  return 0;
+}
+
+int RGWRados::init_zg_from_local(bool *creating_defaults)
+{
+  int ret = zonegroup.init(cct, this);
+  if ( (ret < 0 && ret != -ENOENT) || (ret == -ENOENT && !cct->_conf->rgw_zonegroup.empty())) {
+    ldout(cct, 0) << "failed reading zonegroup info: ret "<< ret << " " << cpp_strerror(-ret) << dendl;
+    return ret;
+  } else if (ret == -ENOENT) {
+    *creating_defaults = true;
+    ldout(cct, 10) << "Creating default zonegroup " << dendl;
+    ret = zonegroup.create_default();
+    if (ret < 0) {
+      ldout(cct, 0) << "failure in zonegroup create_default: ret "<< ret << " " << cpp_strerror(-ret)
+        << dendl;
+      return ret;
+    }
+    ret = zonegroup.init(cct, this);
+    if (ret < 0) {
+      ldout(cct, 0) << "failure in zonegroup create_default: ret "<< ret << " " << cpp_strerror(-ret)
+        << dendl;
+      return ret;
+    }
+  }
+  ldout(cct, 20) << "zonegroup " << zonegroup.get_name() << dendl;
+  if (zonegroup.is_master) {
+    rest_master_conn = new RGWRESTConn(cct, this, zonegroup.get_id(), zonegroup.endpoints);
+  }
+
+  return 0;
 }
 
 /** 
@@ -1572,66 +3529,116 @@ static void add_new_connection_to_map(map<string, RGWRESTConn *> &region_conn_ma
  */
 int RGWRados::init_complete()
 {
-  int ret;
+  int ret = realm.init(cct, this);
+  if (ret < 0 && ret != -ENOENT) {
+    ldout(cct, 0) << "failed reading realm info: ret "<< ret << " " << cpp_strerror(-ret) << dendl;
+    return ret;
+  } else if (ret != -ENOENT) {
+    ldout(cct, 20) << "realm  " << realm.get_name() << " " << realm.get_id() << dendl;
+    ret = current_period.init(cct, this, realm.get_id(), realm.get_name());
+    if (ret < 0 && ret != -ENOENT) {
+      ldout(cct, 0) << "failed reading current period info: " << " " << cpp_strerror(-ret) << dendl;
+      return ret;
+    }
+    ldout(cct, 20) << "current period " << current_period.get_id() << dendl;  
+  }
 
-  ret = region.init(cct, this);
-  if (ret < 0)
+  ret = replace_region_with_zonegroup();
+  if (ret < 0) {
+    lderr(cct) << "failed converting region to zonegroup : ret "<< ret << " " << cpp_strerror(-ret) << dendl;
     return ret;
+  }
 
-  ret = zone.init(cct, this, region);
-  if (ret < 0)
+  ret = convert_regionmap();
+  if (ret < 0) {
+    lderr(cct) << "failed converting regionmap: " << cpp_strerror(-ret) << dendl;
     return ret;
+  }
 
-  init_unique_trans_id_deps();
+  bool zg_initialized = false;
 
-  ret = region_map.read(cct, this);
-  if (ret < 0) {
-    if (ret != -ENOENT) {
-      ldout(cct, 0) << "WARNING: cannot read region map" << dendl;
+  if (!current_period.get_id().empty()) {
+    ret = init_zg_from_period(&zg_initialized);
+    if (ret < 0) {
+      return ret;
+    }
+  }
+
+  bool creating_defaults = false;
+  bool using_local = (!zg_initialized);
+  if (using_local) {
+    ldout(cct, 10) << " cannot find current period zonegroup using local zonegroup" << dendl;
+    ret = init_zg_from_local(&creating_defaults);
+    if (ret < 0) {
+      return ret;
+    }
+  }
+
+  ldout(cct, 10) << "Cannot find current period zone using local zone" << dendl;
+  if (creating_defaults && cct->_conf->rgw_zone.empty()) {
+    ldout(cct, 10) << " Using default name "<< default_zone_name << dendl;
+    zone_params.set_name(default_zone_name);
+  }
+
+  ret = zone_params.init(cct, this);
+  if (ret < 0 && ret != -ENOENT) {
+    lderr(cct) << "failed reading zone info: ret "<< ret << " " << cpp_strerror(-ret) << dendl;
+    return ret;
+  }
+  map<string, RGWZone>::iterator zone_iter = get_zonegroup().zones.find(zone_params.get_id());
+  if (zone_iter == get_zonegroup().zones.end()) {
+    if (using_local) {
+      lderr(cct) << "Cannot find zone id=" << zone_params.get_id() << " (name=" << zone_params.get_name() << ")" << dendl;
+      return -EINVAL;
     }
-    ret = region_map.update(region);
+    ldout(cct, 0) << "Cannot find zone id=" << zone_params.get_id() << " (name=" << zone_params.get_name() << "), switching to local zonegroup configuration" << dendl;
+    ret = init_zg_from_local(&creating_defaults);
     if (ret < 0) {
-      ldout(cct, 0) << "ERROR: failed to update regionmap with local region info" << dendl;
-      return -EIO;
+      return ret;
     }
+    zone_iter = get_zonegroup().zones.find(zone_params.get_id());
+  }
+  if (zone_iter != get_zonegroup().zones.end()) {
+    zone_public_config = zone_iter->second;
+    ldout(cct, 20) << "zone " << zone_params.get_name() << dendl;
   } else {
-    string master_region = region_map.master_region;
-    if (master_region.empty()) {
-      lderr(cct) << "ERROR: region map does not specify master region" << dendl;
-      return -EINVAL;
-    }
-    map<string, RGWRegion>::iterator iter = region_map.regions.find(master_region);
-    if (iter == region_map.regions.end()) {
-      lderr(cct) << "ERROR: bad region map: inconsistent master region" << dendl;
-      return -EINVAL;
-    }
-    RGWRegion& region = iter->second;
-    rest_master_conn = new RGWRESTConn(cct, this, region.endpoints);
-
-    for (iter = region_map.regions.begin(); iter != region_map.regions.end(); ++iter) {
-      RGWRegion& region = iter->second;
-      add_new_connection_to_map(region_conn_map, region, new RGWRESTConn(cct, this, region.endpoints));
-    }
+    lderr(cct) << "Cannot find zone id=" << zone_params.get_id() << " (name=" << zone_params.get_name() << ")" << dendl;
+    return -EINVAL;
   }
 
+  zone_short_id = current_period.get_map().get_zone_short_id(zone_params.get_id());
+
+  init_unique_trans_id_deps();
+
   finisher = new Finisher(cct);
   finisher->start();
 
+  period_puller.reset(new RGWPeriodPuller(this));
+  period_history.reset(new RGWPeriodHistory(cct, period_puller.get(),
+                                            current_period));
+
   if (need_watch_notify()) {
     ret = init_watch();
     if (ret < 0) {
-      lderr(cct) << "ERROR: failed to initialize watch" << dendl;
+      lderr(cct) << "ERROR: failed to initialize watch: " << cpp_strerror(-ret) << dendl;
       return ret;
     }
   }
 
   map<string, RGWZone>::iterator ziter;
-  for (ziter = region.zones.begin(); ziter != region.zones.end(); ++ziter) {
-    const string& name = ziter->first;
+  for (ziter = get_zonegroup().zones.begin(); ziter != get_zonegroup().zones.end(); ++ziter) {
+    const string& id = ziter->first;
     RGWZone& z = ziter->second;
-    if (name != zone.name) {
-      ldout(cct, 20) << "generating connection object for zone " << name << dendl;
-      zone_conn_map[name] = new RGWRESTConn(cct, this, z.endpoints);
+    zone_id_by_name[z.name] = id;
+    zone_name_by_id[id] = z.name;
+    if (id != zone_id()) {
+      if (!z.endpoints.empty()) {
+        ldout(cct, 20) << "generating connection object for zone " << z.name << " id " << z.id << dendl;
+        RGWRESTConn *conn = new RGWRESTConn(cct, this, z.id, z.endpoints);
+        zone_conn_map[id] = conn;
+      } else {
+        ldout(cct, 0) << "WARNING: can't generate connection for zone " << z.id << " id " << z.name << ": no endpoints defined" << dendl;
+      }
     } else {
       zone_public_config = z;
     }
@@ -1661,10 +3668,58 @@ int RGWRados::init_complete()
     obj_expirer->start_processor();
   }
 
+  /* not point of running sync thread if there is a single zone or
+     we don't have a master zone configured or there is no rest_master_conn */
+  if (get_zonegroup().zones.size() < 2 || get_zonegroup().master_zone.empty() || !rest_master_conn) {
+    run_sync_thread = false;
+  }
+
+  async_rados = new RGWAsyncRadosProcessor(this, cct->_conf->rgw_num_async_rados_threads);
+  async_rados->start();
+
+  ret = meta_mgr->init(current_period.get_id());
+  if (ret < 0) {
+    lderr(cct) << "ERROR: failed to initialize metadata log: "
+        << cpp_strerror(-ret) << dendl;
+    return ret;
+  }
+
+  if (is_meta_master()) {
+    auto md_log = meta_mgr->get_log(current_period.get_id());
+    meta_notifier = new RGWMetaNotifier(this, md_log);
+    meta_notifier->start();
+  }
+
+  if (run_sync_thread) {
+    Mutex::Locker l(meta_sync_thread_lock);
+    meta_sync_processor_thread = new RGWMetaSyncProcessorThread(this, async_rados);
+    ret = meta_sync_processor_thread->init();
+    if (ret < 0) {
+      ldout(cct, 0) << "ERROR: failed to initialize" << dendl;
+      return ret;
+    }
+    meta_sync_processor_thread->start();
+
+    Mutex::Locker dl(data_sync_thread_lock);
+    for (map<string, RGWRESTConn *>::iterator iter = zone_conn_map.begin(); iter != zone_conn_map.end(); ++iter) {
+      ldout(cct, 5) << "starting data sync thread for zone " << iter->first << dendl;
+      RGWDataSyncProcessorThread *thread = new RGWDataSyncProcessorThread(this, async_rados, iter->first);
+      ret = thread->init();
+      if (ret < 0) {
+        ldout(cct, 0) << "ERROR: failed to initialize" << dendl;
+        return ret;
+      }
+      thread->start();
+      data_sync_processor_threads[iter->first] = thread;
+    }
+  }
+  data_notifier = new RGWDataNotifier(this);
+  data_notifier->start();
+
   quota_handler = RGWQuotaHandler::generate_handler(this, quota_threads);
 
   bucket_index_max_shards = (cct->_conf->rgw_override_bucket_index_max_shards ? cct->_conf->rgw_override_bucket_index_max_shards :
-                             zone_public_config.bucket_index_max_shards);
+                             get_zone().bucket_index_max_shards);
   if (bucket_index_max_shards > MAX_BUCKET_INDEX_SHARDS_PRIME) {
     bucket_index_max_shards = MAX_BUCKET_INDEX_SHARDS_PRIME;
     ldout(cct, 1) << __func__ << " bucket index max shards is too large, reset to value: "
@@ -1710,7 +3765,7 @@ void RGWRados::schedule_context(Context *c) {
   finisher->queue(c);
 }
 
-int RGWRados::list_raw_prefixed_objs(string pool_name, const string& prefix, list<string>& result)
+int RGWRados::list_raw_prefixed_objs(const string& pool_name, const string& prefix, list<string>& result)
 {
   rgw_bucket pool(pool_name.c_str());
   bool is_truncated;
@@ -1735,22 +3790,69 @@ int RGWRados::list_raw_prefixed_objs(string pool_name, const string& prefix, lis
 
 int RGWRados::list_regions(list<string>& regions)
 {
-  string pool_name;
-  int ret = RGWRegion::get_pool_name(cct, &pool_name);
-  if (ret < 0)
-    return ret;
+  RGWZoneGroup zonegroup;
+
+  return list_raw_prefixed_objs(zonegroup.get_pool_name(cct), region_info_oid_prefix, regions);
+}
 
-  return list_raw_prefixed_objs(pool_name, region_info_oid_prefix, regions);
+int RGWRados::list_zonegroups(list<string>& zonegroups)
+{
+  RGWZoneGroup zonegroup;
+
+  return list_raw_prefixed_objs(zonegroup.get_pool_name(cct), zonegroup_names_oid_prefix, zonegroups);
 }
 
 int RGWRados::list_zones(list<string>& zones)
 {
-  string pool_name;
-  int ret = RGWZoneParams::get_pool_name(cct, &pool_name);
-  if (ret < 0)
+  RGWZoneParams zoneparams;
+  string pool_name = zoneparams.get_pool_name(cct);
+
+  return list_raw_prefixed_objs(pool_name, zone_names_oid_prefix, zones);
+}
+
+int RGWRados::list_realms(list<string>& realms)
+{
+  RGWRealm realm(cct, this);
+  string pool_name = realm.get_pool_name(cct);
+  return list_raw_prefixed_objs(pool_name, realm_names_oid_prefix, realms);
+}
+
+int RGWRados::list_periods(list<string>& periods)
+{
+  RGWPeriod period;
+  list<string> raw_periods;
+  int ret = list_raw_prefixed_objs(period.get_pool_name(cct), period.get_info_oid_prefix(), raw_periods);
+  if (ret < 0) {
     return ret;
+  }
+  for(list<string>::iterator iter = raw_periods.begin(); iter != raw_periods.end(); iter++) {
+    size_t pos = iter->find(".");
+    if ( pos != std::string::npos) {
+      periods.push_back(iter->substr(0, pos));
+    } else {
+      periods.push_back(*iter);
+    }
+  }
+  periods.unique();
+  return 0;
+}
 
-  return list_raw_prefixed_objs(pool_name, zone_info_oid_prefix, zones);
+
+int RGWRados::list_periods(const string& current_period, list<string>& periods)
+{
+  int ret = 0;
+  string period_id = current_period;
+  while(!period_id.empty()) {
+    RGWPeriod period(period_id);
+    ret = period.init(cct, this);
+    if (ret < 0) {
+      return ret;
+    }
+    periods.push_back(period.get_id());
+    period_id = period.get_predecessor();
+  }
+  
+  return ret;
 }
 
 /**
@@ -1759,7 +3861,7 @@ int RGWRados::list_zones(list<string>& zones)
  */
 int RGWRados::open_root_pool_ctx()
 {
-  const string& pool = zone.domain_root.name;
+  const string& pool = get_zone_params().domain_root.name;
   const char *pool_str = pool.c_str();
   librados::Rados *rad = get_rados_handle();
   int r = rad->ioctx_create(pool_str, root_pool_ctx);
@@ -1778,7 +3880,7 @@ int RGWRados::open_root_pool_ctx()
 
 int RGWRados::open_gc_pool_ctx()
 {
-  const char *gc_pool = zone.gc_pool.name.c_str();
+  const char *gc_pool = get_zone_params().gc_pool.name.c_str();
   librados::Rados *rad = get_rados_handle();
   int r = rad->ioctx_create(gc_pool, gc_pool_ctx);
   if (r == -ENOENT) {
@@ -1796,7 +3898,7 @@ int RGWRados::open_gc_pool_ctx()
 
 int RGWRados::open_objexp_pool_ctx()
 {
-  const char * const pool_name = zone.log_pool.name.c_str();
+  const char * const pool_name = get_zone_params().log_pool.name.c_str();
   librados::Rados * const rad = get_rados_handle();
   int r = rad->ioctx_create(pool_name, objexp_pool_ctx);
   if (r == -ENOENT) {
@@ -1815,9 +3917,11 @@ int RGWRados::open_objexp_pool_ctx()
 
 int RGWRados::init_watch()
 {
-  const char *control_pool = zone.control_pool.name.c_str();
+  const char *control_pool = get_zone_params().control_pool.name.c_str();
+
   librados::Rados *rad = rados[0];
   int r = rad->ioctx_create(control_pool, control_pool_ctx);
+
   if (r == -ENOENT) {
     r = rad->pool_create(control_pool);
     if (r == -EEXIST)
@@ -1879,7 +3983,7 @@ void RGWRados::pick_control_oid(const string& key, string& notify_oid)
   notify_oid.append(buf);
 }
 
-int RGWRados::open_bucket_pool_ctx(const string& pool, librados::IoCtx&  io_ctx)
+int RGWRados::open_pool_ctx(const string& pool, librados::IoCtx&  io_ctx)
 {
   librados::Rados *rad = get_rados_handle();
   int r = rad->ioctx_create(pool.c_str(), io_ctx);
@@ -1900,7 +4004,7 @@ int RGWRados::open_bucket_pool_ctx(const string& pool, librados::IoCtx&  io_ctx)
 
 int RGWRados::open_bucket_data_ctx(rgw_bucket& bucket, librados::IoCtx& data_ctx)
 {
-  int r = open_bucket_pool_ctx(bucket.data_pool, data_ctx);
+  int r = open_pool_ctx(bucket.data_pool, data_ctx);
   if (r < 0)
     return r;
 
@@ -1910,7 +4014,7 @@ int RGWRados::open_bucket_data_ctx(rgw_bucket& bucket, librados::IoCtx& data_ctx
 int RGWRados::open_bucket_data_extra_ctx(rgw_bucket& bucket, librados::IoCtx& data_ctx)
 {
   string& pool = (!bucket.data_extra_pool.empty() ? bucket.data_extra_pool : bucket.data_pool);
-  int r = open_bucket_pool_ctx(pool, data_ctx);
+  int r = open_pool_ctx(pool, data_ctx);
   if (r < 0)
     return r;
 
@@ -1928,7 +4032,7 @@ void RGWRados::build_bucket_index_marker(const string& shard_id_str, const strin
 
 int RGWRados::open_bucket_index_ctx(rgw_bucket& bucket, librados::IoCtx& index_ctx)
 {
-  int r = open_bucket_pool_ctx(bucket.index_pool, index_ctx);
+  int r = open_pool_ctx(bucket.index_pool, index_ctx);
   if (r < 0)
     return r;
 
@@ -1982,7 +4086,7 @@ struct log_list_state {
 int RGWRados::log_list_init(const string& prefix, RGWAccessHandle *handle)
 {
   log_list_state *state = new log_list_state;
-  const char *log_pool = zone.log_pool.name.c_str();
+  const char *log_pool = get_zone_params().log_pool.name.c_str();
   librados::Rados *rad = get_rados_handle();
   int r = rad->ioctx_create(log_pool, state->io_ctx);
   if (r < 0) {
@@ -2018,7 +4122,7 @@ int RGWRados::log_list_next(RGWAccessHandle handle, string *name)
 int RGWRados::log_remove(const string& name)
 {
   librados::IoCtx io_ctx;
-  const char *log_pool = zone.log_pool.name.c_str();
+  const char *log_pool = get_zone_params().log_pool.name.c_str();
   librados::Rados *rad = get_rados_handle();
   int r = rad->ioctx_create(log_pool, io_ctx);
   if (r < 0)
@@ -2039,7 +4143,7 @@ struct log_show_state {
 int RGWRados::log_show_init(const string& name, RGWAccessHandle *handle)
 {
   log_show_state *state = new log_show_state;
-  const char *log_pool = zone.log_pool.name.c_str();
+  const char *log_pool = get_zone_params().log_pool.name.c_str();
   librados::Rados *rad = get_rados_handle();
   int r = rad->ioctx_create(log_pool, state->io_ctx);
   if (r < 0) {
@@ -2153,8 +4257,7 @@ int RGWRados::log_usage(map<rgw_user_bucket, RGWUsageBatch>& usage_info)
     last_user = ub.user;
     vector<rgw_usage_log_entry>& v = log_objs[hash].entries;
 
-    map<utime_t, rgw_usage_log_entry>::iterator miter;
-    for (miter = info.m.begin(); miter != info.m.end(); ++miter) {
+    for (auto miter = info.m.begin(); miter != info.m.end(); ++miter) {
       v.push_back(miter->second);
     }
   }
@@ -2236,10 +4339,21 @@ next:
   return 0;
 }
 
-void RGWRados::shard_name(const string& prefix, unsigned max_shards, const string& key, string& name)
+#define MAX_SHARDS_PRIME 7877
+
+int RGWRados::key_to_shard_id(const string& key, int max_shards)
+{
+  uint32_t val = ceph_str_hash_linux(key.c_str(), key.size()) % MAX_SHARDS_PRIME;
+  return val % max_shards;
+}
+
+void RGWRados::shard_name(const string& prefix, unsigned max_shards, const string& key, string& name, int *shard_id)
 {
   uint32_t val = ceph_str_hash_linux(key.c_str(), key.size());
   char buf[16];
+  if (shard_id) {
+    *shard_id = val % max_shards;
+  }
   snprintf(buf, sizeof(buf), "%u", (unsigned)(val % max_shards));
   name = prefix + buf;
 }
@@ -2253,16 +4367,22 @@ void RGWRados::shard_name(const string& prefix, unsigned max_shards, const strin
   name = prefix + buf;
 }
 
-void RGWRados::time_log_prepare_entry(cls_log_entry& entry, const utime_t& ut, const string& section, const string& key, bufferlist& bl)
+void RGWRados::shard_name(const string& prefix, unsigned shard_id, string& name)
 {
-  cls_log_add_prepare_entry(entry, ut, section, key, bl);
+  char buf[16];
+  snprintf(buf, sizeof(buf), "%u", shard_id);
+  name = prefix + buf;
+
 }
 
-int RGWRados::time_log_add(const string& oid, const utime_t& ut, const string& section, const string& key, bufferlist& bl)
+void RGWRados::time_log_prepare_entry(cls_log_entry& entry, const real_time& ut, const string& section, const string& key, bufferlist& bl)
 {
-  librados::IoCtx io_ctx;
+  cls_log_add_prepare_entry(entry, utime_t(ut), section, key, bl);
+}
 
-  const char *log_pool = zone.log_pool.name.c_str();
+int RGWRados::time_log_add_init(librados::IoCtx& io_ctx)
+{
+  const char *log_pool = get_zone_params().log_pool.name.c_str();
   librados::Rados *rad = get_rados_handle();
   int r = rad->ioctx_create(log_pool, io_ctx);
   if (r == -ENOENT) {
@@ -2277,40 +4397,49 @@ int RGWRados::time_log_add(const string& oid, const utime_t& ut, const string& s
   if (r < 0)
     return r;
 
+  return 0;
+
+}
+
+int RGWRados::time_log_add(const string& oid, const real_time& ut, const string& section, const string& key, bufferlist& bl)
+{
+  librados::IoCtx io_ctx;
+
+  int r = time_log_add_init(io_ctx);
+  if (r < 0) {
+    return r;
+  }
+
   ObjectWriteOperation op;
-  cls_log_add(op, ut, section, key, bl);
+  utime_t t(ut);
+  cls_log_add(op, t, section, key, bl);
 
   r = io_ctx.operate(oid, &op);
   return r;
 }
 
-int RGWRados::time_log_add(const string& oid, list<cls_log_entry>& entries)
+int RGWRados::time_log_add(const string& oid, list<cls_log_entry>& entries,
+			   librados::AioCompletion *completion, bool monotonic_inc)
 {
   librados::IoCtx io_ctx;
 
-  const char *log_pool = zone.log_pool.name.c_str();
-  librados::Rados *rad = get_rados_handle();
-  int r = rad->ioctx_create(log_pool, io_ctx);
-  if (r == -ENOENT) {
-    rgw_bucket pool(log_pool);
-    r = create_pool(pool);
-    if (r < 0)
-      return r;
- 
-    // retry
-    r = rad->ioctx_create(log_pool, io_ctx);
-  }
-  if (r < 0)
+  int r = time_log_add_init(io_ctx);
+  if (r < 0) {
     return r;
+  }
 
   ObjectWriteOperation op;
-  cls_log_add(op, entries);
+  cls_log_add(op, entries, monotonic_inc);
 
-  r = io_ctx.operate(oid, &op);
+  if (!completion) {
+    r = io_ctx.operate(oid, &op);
+  } else {
+    r = io_ctx.aio_operate(oid, completion, &op);
+  }
   return r;
 }
 
-int RGWRados::time_log_list(const string& oid, utime_t& start_time, utime_t& end_time,
+int RGWRados::time_log_list(const string& oid, const real_time& start_time, const real_time& end_time,
                             int max_entries, list<cls_log_entry>& entries,
 			    const string& marker,
 			    string *out_marker,
@@ -2318,14 +4447,17 @@ int RGWRados::time_log_list(const string& oid, utime_t& start_time, utime_t& end
 {
   librados::IoCtx io_ctx;
 
-  const char *log_pool = zone.log_pool.name.c_str();
+  const char *log_pool = get_zone_params().log_pool.name.c_str();
   librados::Rados *rad = get_rados_handle();
   int r = rad->ioctx_create(log_pool, io_ctx);
   if (r < 0)
     return r;
   librados::ObjectReadOperation op;
 
-  cls_log_list(op, start_time, end_time, marker, max_entries, entries,
+  utime_t st(start_time);
+  utime_t et(end_time);
+
+  cls_log_list(op, st, et, marker, max_entries, entries,
 	       out_marker, truncated);
 
   bufferlist obl;
@@ -2341,7 +4473,7 @@ int RGWRados::time_log_info(const string& oid, cls_log_header *header)
 {
   librados::IoCtx io_ctx;
 
-  const char *log_pool = zone.log_pool.name.c_str();
+  const char *log_pool = get_zone_params().log_pool.name.c_str();
   librados::Rados *rad = get_rados_handle();
   int r = rad->ioctx_create(log_pool, io_ctx);
   if (r < 0)
@@ -2359,18 +4491,40 @@ int RGWRados::time_log_info(const string& oid, cls_log_header *header)
   return 0;
 }
 
-int RGWRados::time_log_trim(const string& oid, const utime_t& start_time, const utime_t& end_time,
+int RGWRados::time_log_info_async(librados::IoCtx& io_ctx, const string& oid, cls_log_header *header, librados::AioCompletion *completion)
+{
+  const char *log_pool = get_zone_params().log_pool.name.c_str();
+  librados::Rados *rad = get_rados_handle();
+  int r = rad->ioctx_create(log_pool, io_ctx);
+  if (r < 0)
+    return r;
+
+  librados::ObjectReadOperation op;
+
+  cls_log_info(op, header);
+
+  int ret = io_ctx.aio_operate(oid, completion, &op, NULL);
+  if (ret < 0)
+    return ret;
+
+  return 0;
+}
+
+int RGWRados::time_log_trim(const string& oid, const real_time& start_time, const real_time& end_time,
 			    const string& from_marker, const string& to_marker)
 {
   librados::IoCtx io_ctx;
 
-  const char *log_pool = zone.log_pool.name.c_str();
+  const char *log_pool = get_zone_params().log_pool.name.c_str();
   librados::Rados *rad = get_rados_handle();
   int r = rad->ioctx_create(log_pool, io_ctx);
   if (r < 0)
     return r;
 
-  return cls_log_trim(io_ctx, oid, start_time, end_time, from_marker, to_marker);
+  utime_t st(start_time);
+  utime_t et(end_time);
+
+  return cls_log_trim(io_ctx, oid, st, et, from_marker, to_marker);
 }
 
 string RGWRados::objexp_hint_get_shardname(int shard_num)
@@ -2382,7 +4536,7 @@ string RGWRados::objexp_hint_get_shardname(int shard_num)
   return objname + buf;
 }
 
-#define MAX_PBJEXP_SHARDS_PRIME 7877
+#define MAX_OBJEXP_SHARDS_PRIME 7877
 
 int RGWRados::objexp_key_shard(const rgw_obj_key& key)
 {
@@ -2390,7 +4544,7 @@ int RGWRados::objexp_key_shard(const rgw_obj_key& key)
   int num_shards = cct->_conf->rgw_objexp_hints_num_shards;
   uint32_t sid = ceph_str_hash_linux(obj_key.c_str(), obj_key.size());
   uint32_t sid2 = sid ^ ((sid & 0xFF) << 24);
-  sid = sid2 % MAX_BUCKET_INDEX_SHARDS_PRIME % num_shards;
+  sid = sid2 % MAX_OBJEXP_SHARDS_PRIME % num_shards;
   return sid % num_shards;
 }
 
@@ -2403,7 +4557,7 @@ static string objexp_hint_get_keyext(const string& tenant_name,
       ":" + obj_key.name + ":" + obj_key.instance;
 }
 
-int RGWRados::objexp_hint_add(const utime_t& delete_at,
+int RGWRados::objexp_hint_add(const ceph::real_time& delete_at,
                               const string& tenant_name,
                               const string& bucket_name,
                               const string& bucket_id,
@@ -2420,7 +4574,7 @@ int RGWRados::objexp_hint_add(const utime_t& delete_at,
   bufferlist hebl;
   ::encode(he, hebl);
   ObjectWriteOperation op;
-  cls_timeindex_add(op, delete_at, keyext, hebl);
+  cls_timeindex_add(op, utime_t(delete_at), keyext, hebl);
 
   string shard_name = objexp_hint_get_shardname(objexp_key_shard(obj_key));
   return objexp_pool_ctx.operate(shard_name, &op);
@@ -2433,8 +4587,8 @@ void  RGWRados::objexp_get_shard(int shard_num,
 }
 
 int RGWRados::objexp_hint_list(const string& oid,
-                               const utime_t& start_time,
-                               const utime_t& end_time,
+                               const ceph::real_time& start_time,
+                               const ceph::real_time& end_time,
                                const int max_entries,
                                const string& marker,
                                list<cls_timeindex_entry>& entries, /* out */
@@ -2442,7 +4596,7 @@ int RGWRados::objexp_hint_list(const string& oid,
                                bool *truncated)                    /* out */
 {
   librados::ObjectReadOperation op;
-  cls_timeindex_list(op, start_time, end_time, marker, max_entries, entries,
+  cls_timeindex_list(op, utime_t(start_time), utime_t(end_time), marker, max_entries, entries,
 	       out_marker, truncated);
 
   bufferlist obl;
@@ -2473,12 +4627,12 @@ int RGWRados::objexp_hint_parse(cls_timeindex_entry &ti_entry,  /* in */
 }
 
 int RGWRados::objexp_hint_trim(const string& oid,
-                               const utime_t& start_time,
-                               const utime_t& end_time,
+                               const ceph::real_time& start_time,
+                               const ceph::real_time& end_time,
                                const string& from_marker,
                                const string& to_marker)
 {
-  int ret = cls_timeindex_trim(objexp_pool_ctx, oid, start_time, end_time,
+  int ret = cls_timeindex_trim(objexp_pool_ctx, oid, utime_t(start_time), utime_t(end_time),
           from_marker, to_marker);
   if ((ret < 0 ) && (ret != -ENOENT)) {
     return ret;
@@ -2487,7 +4641,7 @@ int RGWRados::objexp_hint_trim(const string& oid,
   return 0;
 }
 
-int RGWRados::lock_exclusive(rgw_bucket& pool, const string& oid, utime_t& duration, 
+int RGWRados::lock_exclusive(rgw_bucket& pool, const string& oid, timespan& duration, 
                              string& zone_id, string& owner_id) {
   librados::IoCtx io_ctx;
 
@@ -2497,9 +4651,11 @@ int RGWRados::lock_exclusive(rgw_bucket& pool, const string& oid, utime_t& durat
   int r = rad->ioctx_create(pool_name, io_ctx);
   if (r < 0)
     return r;
+  uint64_t msec = std::chrono::duration_cast<std::chrono::milliseconds>(duration).count();
+  utime_t ut(msec / 1000, msec % 1000);
   
   rados::cls::lock::Lock l(log_lock_name);
-  l.set_duration(duration);
+  l.set_duration(ut);
   l.set_cookie(owner_id);
   l.set_tag(zone_id);
   l.set_renew(true);
@@ -2554,13 +4710,14 @@ int rgw_policy_from_attrset(CephContext *cct, map<string, bufferlist>& attrset,
   }
   if (cct->_conf->subsys.should_gather(ceph_subsys_rgw, 15)) {
     RGWAccessControlPolicy_S3 *s3policy = static_cast<RGWAccessControlPolicy_S3 *>(policy);
-    ldout(cct, 15) << "Read AccessControlPolicy";
+    ldout(cct, 15) << __func__ << " Read AccessControlPolicy";
     s3policy->to_xml(*_dout);
     *_dout << dendl;
   }
   return 0;
 }
 
+
 /** 
  * get listing of the objects in a bucket.
  * bucket: bucket to list contents of
@@ -2582,13 +4739,11 @@ int RGWRados::Bucket::List::list_objects(int max, vector<RGWObjEnt> *result,
   RGWRados *store = target->get_store();
   CephContext *cct = store->ctx();
   rgw_bucket& bucket = target->get_bucket();
+  int shard_id = target->get_shard_id();
 
   int count = 0;
   bool truncated = true;
 
-  if (store->bucket_is_system(bucket)) {
-    return -EINVAL;
-  }
   result->clear();
 
   rgw_obj marker_obj, end_marker_obj, prefix_obj;
@@ -2644,7 +4799,7 @@ int RGWRados::Bucket::List::list_objects(int max, vector<RGWObjEnt> *result,
       ldout(cct, 20) << "setting cur_marker=" << cur_marker.name << "[" << cur_marker.instance << "]" << dendl;
     }
     std::map<string, RGWObjEnt> ent_map;
-    int r = store->cls_bucket_list(bucket, cur_marker, cur_prefix, max + 1 - count, params.list_versions, ent_map,
+    int r = store->cls_bucket_list(bucket, shard_id, cur_marker, cur_prefix, max + 1 - count, params.list_versions, ent_map,
                             &truncated, &cur_marker);
     if (r < 0)
       return r;
@@ -2795,30 +4950,33 @@ int RGWRados::init_bucket_index(rgw_bucket& bucket, int num_shards)
  * returns 0 on success, -ERR# otherwise.
  */
 int RGWRados::create_bucket(RGWUserInfo& owner, rgw_bucket& bucket,
-                            const string& region_name,
+                            const string& zonegroup_id,
                             const string& placement_rule,
+                            const string& swift_ver_location,
 			    map<std::string, bufferlist>& attrs,
                             RGWBucketInfo& info,
                             obj_version *pobjv,
                             obj_version *pep_objv,
-                            time_t creation_time,
+                            real_time creation_time,
                             rgw_bucket *pmaster_bucket,
 			    bool exclusive)
 {
 #define MAX_CREATE_RETRIES 20 /* need to bound retries */
-  string selected_placement_rule;
+  string selected_placement_rule_name;
+  RGWZonePlacementInfo rule_info;
+
   for (int i = 0; i < MAX_CREATE_RETRIES; i++) {
     int ret = 0;
-    ret = select_bucket_placement(owner, region_name, placement_rule,
+    ret = select_bucket_placement(owner, zonegroup_id, placement_rule,
                                   bucket.tenant, bucket.name, bucket,
-                                  &selected_placement_rule);
+                                  &selected_placement_rule_name, &rule_info);
     if (ret < 0)
       return ret;
     bufferlist bl;
     uint32_t nop = 0;
     ::encode(nop, bl);
 
-    const string& pool = zone.domain_root.name;
+    const string& pool = get_zone_params().domain_root.name;
     const char *pool_str = pool.c_str();
     librados::IoCtx id_io_ctx;
     librados::Rados *rad = get_rados_handle();
@@ -2829,8 +4987,8 @@ int RGWRados::create_bucket(RGWUserInfo& owner, rgw_bucket& bucket,
     if (!pmaster_bucket) {
       uint64_t iid = instance_id();
       uint64_t bid = next_bucket_id();
-      char buf[zone.name.size() + 48];
-      snprintf(buf, sizeof(buf), "%s.%llu.%llu", zone.name.c_str(), (long long)iid, (long long)bid);
+      char buf[get_zone_params().get_id().size() + 48];
+      snprintf(buf, sizeof(buf), "%s.%llu.%llu", get_zone_params().get_id().c_str(), (long long)iid, (long long)bid);
       bucket.marker = buf;
       bucket.bucket_id = bucket.marker;
     } else {
@@ -2852,16 +5010,19 @@ int RGWRados::create_bucket(RGWUserInfo& owner, rgw_bucket& bucket,
 
     info.bucket = bucket;
     info.owner = owner.user_id;
-    info.region = region_name;
-    info.placement_rule = selected_placement_rule;
+    info.zonegroup = zonegroup_id;
+    info.placement_rule = selected_placement_rule_name;
+    info.index_type = rule_info.index_type;
+    info.swift_ver_location = swift_ver_location;
+    info.swift_versioning = (!swift_ver_location.empty());
     info.num_shards = bucket_index_max_shards;
     info.bucket_index_shard_hash_type = RGWBucketInfo::MOD;
     info.requester_pays = false;
-    if (!creation_time)
-      time(&info.creation_time);
+    if (real_clock::is_zero(creation_time))
+      creation_time = ceph::real_clock::now(cct);
     else
       info.creation_time = creation_time;
-    ret = put_linked_bucket_info(info, exclusive, 0, pep_objv, &attrs, true);
+    ret = put_linked_bucket_info(info, exclusive, ceph::real_time(), pep_objv, &attrs, true);
     if (ret == -EEXIST) {
        /* we need to reread the info and return it, caller will have a use for it */
       RGWObjVersionTracker instance_ver = info.objv_tracker;
@@ -2908,24 +5069,26 @@ int RGWRados::create_bucket(RGWUserInfo& owner, rgw_bucket& bucket,
   return -ENOENT;
 }
 
-int RGWRados::select_new_bucket_location(RGWUserInfo& user_info, const string& region_name, const string& request_rule,
-                                         const string& tenant_name, const string& bucket_name, rgw_bucket& bucket, string *pselected_rule)
+int RGWRados::select_new_bucket_location(RGWUserInfo& user_info, const string& zonegroup_id, const string& request_rule,
+                                         const string& tenant_name, const string& bucket_name, rgw_bucket& bucket, string *pselected_rule_name,
+                                         RGWZonePlacementInfo *rule_info)
+
 {
-  /* first check that rule exists within the specific region */
-  map<string, RGWRegion>::iterator riter = region_map.regions.find(region_name);
-  if (riter == region_map.regions.end()) {
-    ldout(cct, 0) << "could not find region " << region_name << " in region map" << dendl;
-    return -EINVAL;
+  /* first check that rule exists within the specific zonegroup */
+  RGWZoneGroup zonegroup;
+  int ret = get_zonegroup(zonegroup_id, zonegroup);
+  if (ret < 0) {
+    ldout(cct, 0) << "could not find zonegroup " << zonegroup_id << " in current period" << dendl;
+    return ret;
   }
-  /* now check that tag exists within region */
-  RGWRegion& region = riter->second;
 
-  /* find placement rule. Hierarchy: request rule > user default rule > region default rule */
+  /* now check that tag exists within zonegroup */
+  /* find placement rule. Hierarchy: request rule > user default rule > zonegroup default rule */
   string rule = request_rule;
   if (rule.empty()) {
     rule = user_info.default_placement;
     if (rule.empty())
-      rule = region.default_placement;
+      rule = zonegroup.default_placement;
   }
 
   if (rule.empty()) {
@@ -2933,28 +5096,27 @@ int RGWRados::select_new_bucket_location(RGWUserInfo& user_info, const string& r
     return -EIO;
   }
 
-  if (!rule.empty()) {
-    map<string, RGWRegionPlacementTarget>::iterator titer = region.placement_targets.find(rule);
-    if (titer == region.placement_targets.end()) {
-      ldout(cct, 0) << "could not find placement rule " << rule << " within region " << dendl;
-      return -EINVAL;
-    }
+  map<string, RGWZoneGroupPlacementTarget>::iterator titer = zonegroup.placement_targets.find(rule);
+  if (titer == zonegroup.placement_targets.end()) {
+    ldout(cct, 0) << "could not find placement rule " << rule << " within zonegroup " << dendl;
+    return -EINVAL;
+  }
 
-    /* now check tag for the rule, whether user is permitted to use rule */
-    RGWRegionPlacementTarget& target_rule = titer->second;
-    if (!target_rule.user_permitted(user_info.placement_tags)) {
-      ldout(cct, 0) << "user not permitted to use placement rule" << dendl;
-      return -EPERM;
-    }
+  /* now check tag for the rule, whether user is permitted to use rule */
+  RGWZoneGroupPlacementTarget& target_rule = titer->second;
+  if (!target_rule.user_permitted(user_info.placement_tags)) {
+    ldout(cct, 0) << "user not permitted to use placement rule" << dendl;
+    return -EPERM;
   }
 
-  if (pselected_rule)
-    *pselected_rule = rule;
-  
-  return set_bucket_location_by_rule(rule, tenant_name, bucket_name, bucket);
+  if (pselected_rule_name)
+    *pselected_rule_name = rule;
+
+  return set_bucket_location_by_rule(rule, tenant_name, bucket_name, bucket, rule_info);
 }
 
-int RGWRados::set_bucket_location_by_rule(const string& location_rule, const string& tenant_name, const string& bucket_name, rgw_bucket& bucket)
+int RGWRados::set_bucket_location_by_rule(const string& location_rule, const string& tenant_name, const string& bucket_name, rgw_bucket& bucket,
+                                         RGWZonePlacementInfo *rule_info)
 {
   bucket.tenant = tenant_name;
   bucket.name = bucket_name;
@@ -2963,7 +5125,7 @@ int RGWRados::set_bucket_location_by_rule(const string& location_rule, const str
     /* we can only reach here if we're trying to set a bucket location from a bucket
      * created on a different zone, using a legacy / default pool configuration
      */
-    return select_legacy_bucket_placement(tenant_name, bucket_name, bucket);
+    return select_legacy_bucket_placement(tenant_name, bucket_name, bucket, rule_info);
   }
 
   /*
@@ -2971,12 +5133,12 @@ int RGWRados::set_bucket_location_by_rule(const string& location_rule, const str
    * checking it for the local zone, because that's where this bucket object is going to
    * reside.
    */
-  map<string, RGWZonePlacementInfo>::iterator piter = zone.placement_pools.find(location_rule);
-  if (piter == zone.placement_pools.end()) {
+  map<string, RGWZonePlacementInfo>::iterator piter = get_zone_params().placement_pools.find(location_rule);
+  if (piter == get_zone_params().placement_pools.end()) {
     /* couldn't find, means we cannot really place data for this bucket in this zone */
-    if (region.equals(region_name)) {
+    if (get_zonegroup().equals(zonegroup_id)) {
       /* that's a configuration error, zone should have that rule, as we're within the requested
-       * region */
+       * zonegroup */
       return -EINVAL;
     } else {
       /* oh, well, data is not going to be placed here, bucket object is just a placeholder */
@@ -2990,35 +5152,41 @@ int RGWRados::set_bucket_location_by_rule(const string& location_rule, const str
   bucket.data_extra_pool = placement_info.data_extra_pool;
   bucket.index_pool = placement_info.index_pool;
 
+  if (rule_info) {
+    *rule_info = placement_info;
+  }
+
   return 0;
 }
 
-int RGWRados::select_bucket_placement(RGWUserInfo& user_info, const string& region_name, const string& placement_rule,
+int RGWRados::select_bucket_placement(RGWUserInfo& user_info, const string& zonegroup_id, const string& placement_rule,
                                       const string& tenant_name, const string& bucket_name, rgw_bucket& bucket,
-                                      string *pselected_rule)
+                                      string *pselected_rule_name, RGWZonePlacementInfo *rule_info)
 {
-  if (!zone.placement_pools.empty()) {
-    return select_new_bucket_location(user_info, region_name, placement_rule,
-                                      tenant_name, bucket_name, bucket, pselected_rule);
+  if (!get_zone_params().placement_pools.empty()) {
+    return select_new_bucket_location(user_info, zonegroup_id, placement_rule,
+                                      tenant_name, bucket_name, bucket, pselected_rule_name, rule_info);
   }
 
-  if (pselected_rule)
-    pselected_rule->clear();
+  if (pselected_rule_name) {
+    pselected_rule_name->clear();
+  }
 
-  return select_legacy_bucket_placement(tenant_name, bucket_name, bucket);
+  return select_legacy_bucket_placement(tenant_name, bucket_name, bucket, rule_info);
 }
 
-int RGWRados::select_legacy_bucket_placement(const string& tenant_name, const string& bucket_name, rgw_bucket& bucket)
+int RGWRados::select_legacy_bucket_placement(const string& tenant_name, const string& bucket_name, rgw_bucket& bucket,
+                                             RGWZonePlacementInfo *rule_info)
 {
   bufferlist map_bl;
   map<string, bufferlist> m;
   string pool_name;
   bool write_map = false;
 
-  rgw_obj obj(zone.domain_root, avail_pools);
+  rgw_obj obj(get_zone_params().domain_root, avail_pools);
 
   RGWObjectCtx obj_ctx(this);
-  int ret = rgw_get_system_obj(this, obj_ctx, zone.domain_root, avail_pools, map_bl, NULL, NULL);
+  int ret = rgw_get_system_obj(this, obj_ctx, get_zone_params().domain_root, avail_pools, map_bl, NULL, NULL);
   if (ret < 0) {
     goto read_omap;
   }
@@ -3040,22 +5208,23 @@ read_omap:
 
   if (ret < 0 || m.empty()) {
     vector<string> names;
-    names.push_back(default_storage_pool);
+    string s = string("default.") + default_storage_pool_suffix;
+    names.push_back(s);
     vector<int> retcodes;
     bufferlist bl;
     ret = create_pools(names, retcodes);
     if (ret < 0)
       return ret;
-    ret = omap_set(obj, default_storage_pool, bl);
+    ret = omap_set(obj, s, bl);
     if (ret < 0)
       return ret;
-    m[default_storage_pool] = bl;
+    m[s] = bl;
   }
 
   if (write_map) {
     bufferlist new_bl;
     ::encode(m, new_bl);
-    ret = put_obj_data(NULL, obj, new_bl.c_str(), -1, new_bl.length(), false);
+    ret = put_system_obj_data(NULL, obj, new_bl, -1, false);
     if (ret < 0) {
       ldout(cct, 0) << "WARNING: could not save avail pools map info ret=" << ret << dendl;
     }
@@ -3082,22 +5251,26 @@ read_omap:
   bucket.data_pool = pool_name;
   bucket.index_pool = pool_name;
 
-  return 0;
+  rule_info->data_pool = pool_name;
+  rule_info->data_extra_pool = pool_name;
+  rule_info->index_pool = pool_name;
+  rule_info->index_type = RGWBIType_Normal;
 
+  return 0;
 }
 
 int RGWRados::update_placement_map()
 {
   bufferlist header;
   map<string, bufferlist> m;
-  rgw_obj obj(zone.domain_root, avail_pools);
+  rgw_obj obj(get_zone_params().domain_root, avail_pools);
   int ret = omap_get_all(obj, header, m);
   if (ret < 0)
     return ret;
 
   bufferlist new_bl;
   ::encode(m, new_bl);
-  ret = put_obj_data(NULL, obj, new_bl.c_str(), -1, new_bl.length(), false);
+  ret = put_system_obj_data(NULL, obj, new_bl, -1, false);
   if (ret < 0) {
     ldout(cct, 0) << "WARNING: could not save avail pools map info ret=" << ret << dendl;
   }
@@ -3112,7 +5285,7 @@ int RGWRados::add_bucket_placement(std::string& new_pool)
   if (ret < 0) // DNE, or something
     return ret;
 
-  rgw_obj obj(zone.domain_root, avail_pools);
+  rgw_obj obj(get_zone_params().domain_root, avail_pools);
   bufferlist empty_bl;
   ret = omap_set(obj, new_pool, empty_bl);
 
@@ -3124,7 +5297,7 @@ int RGWRados::add_bucket_placement(std::string& new_pool)
 
 int RGWRados::remove_bucket_placement(std::string& old_pool)
 {
-  rgw_obj obj(zone.domain_root, avail_pools);
+  rgw_obj obj(get_zone_params().domain_root, avail_pools);
   int ret = omap_del(obj, old_pool);
 
   // don't care about return value
@@ -3138,7 +5311,7 @@ int RGWRados::list_placement_set(set<string>& names)
   bufferlist header;
   map<string, bufferlist> m;
 
-  rgw_obj obj(zone.domain_root, avail_pools);
+  rgw_obj obj(get_zone_params().domain_root, avail_pools);
   int ret = omap_get_all(obj, header, m);
   if (ret < 0)
     return ret;
@@ -3209,18 +5382,13 @@ int RGWRados::get_obj_ioctx(const rgw_obj& obj, librados::IoCtx *ioctx)
   return 0;
 }
 
-int RGWRados::get_obj_ref(const rgw_obj& obj, rgw_rados_ref *ref, rgw_bucket *bucket, bool ref_system_obj)
+int RGWRados::get_obj_ref(const rgw_obj& obj, rgw_rados_ref *ref, rgw_bucket *bucket)
 {
   get_obj_bucket_and_oid_loc(obj, *bucket, ref->oid, ref->key);
 
   int r;
 
-  if (ref_system_obj && ref->oid.empty()) {
-    ref->oid = bucket->name;
-    *bucket = zone.domain_root;
-
-    r = open_bucket_data_ctx(*bucket, ref->ioctx);
-  } else if (!obj.is_in_extra_data()) {
+  if (!obj.is_in_extra_data()) {
     r = open_bucket_data_ctx(*bucket, ref->ioctx);
   } else {
     r = open_bucket_data_extra_ctx(*bucket, ref->ioctx);
@@ -3233,6 +5401,25 @@ int RGWRados::get_obj_ref(const rgw_obj& obj, rgw_rados_ref *ref, rgw_bucket *bu
   return 0;
 }
 
+int RGWRados::get_system_obj_ref(const rgw_obj& obj, rgw_rados_ref *ref, rgw_bucket *bucket)
+{
+  get_obj_bucket_and_oid_loc(obj, *bucket, ref->oid, ref->key);
+
+  int r;
+
+  if (ref->oid.empty()) {
+    ref->oid = bucket->name;
+    *bucket = get_zone_params().domain_root;
+  }
+  r = open_pool_ctx(bucket->name, ref->ioctx);
+  if (r < 0)
+    return r;
+
+  ref->ioctx.locator_set_key(ref->key);
+
+  return 0;
+}
+
 /*
  * fixes an issue where head objects were supposed to have a locator created, but ended
  * up without one
@@ -3261,13 +5448,13 @@ int RGWRados::fix_head_obj_locator(rgw_bucket& bucket, bool copy_obj, bool remov
   ioctx.locator_set_key(string()); /* override locator for this object, use empty locator */
 
   uint64_t size;
-  time_t mtime;
   bufferlist data;
 
+  struct timespec mtime_ts;
   map<string, bufferlist> attrs;
   librados::ObjectReadOperation op;
   op.getxattrs(&attrs, NULL);
-  op.stat(&size, &mtime, NULL);
+  op.stat2(&size, &mtime_ts, NULL);
 #define HEAD_SIZE 512 * 1024
   op.read(0, HEAD_SIZE, &data, NULL);
 
@@ -3290,7 +5477,7 @@ int RGWRados::fix_head_obj_locator(rgw_bucket& bucket, bool copy_obj, bool remov
   if (copy_obj) {
     librados::ObjectWriteOperation wop;
 
-    wop.mtime(&mtime);
+    wop.mtime2(&mtime_ts);
 
     map<string, bufferlist>::iterator iter;
     for (iter = attrs.begin(); iter != attrs.end(); ++iter) {
@@ -3327,7 +5514,8 @@ int RGWRados::move_rados_obj(librados::IoCtx& src_ioctx,
   uint64_t chunk_size = COPY_BUF_SIZE;
   uint64_t ofs = 0;
   int ret = 0;
-  time_t mtime = 0;
+  real_time mtime;
+  struct timespec mtime_ts;
   uint64_t size;
 
   if (src_oid == dst_oid && src_locator == dst_locator) {
@@ -3343,7 +5531,8 @@ int RGWRados::move_rados_obj(librados::IoCtx& src_ioctx,
     ObjectWriteOperation wop;
 
     if (ofs == 0) {
-      rop.stat(&size, &mtime, NULL);
+      rop.stat2(&size, &mtime_ts, NULL);
+      mtime = real_clock::from_timespec(mtime_ts);
     }
     rop.read(ofs, chunk_size, &data, NULL);
     ret = src_ioctx.operate(src_oid, &rop, NULL);
@@ -3357,7 +5546,8 @@ int RGWRados::move_rados_obj(librados::IoCtx& src_ioctx,
 
     if (ofs == 0) {
       wop.create(true); /* make it exclusive */
-      wop.mtime(&mtime);
+      wop.mtime2(&mtime_ts);
+      mtime = real_clock::from_timespec(mtime_ts);
     }
     wop.write(ofs, data);
     ret = dst_ioctx.operate(dst_oid, &wop);
@@ -3387,8 +5577,6 @@ done_err:
  */
 int RGWRados::fix_tail_obj_locator(rgw_bucket& bucket, rgw_obj_key& key, bool fix, bool *need_fix)
 {
-  string locator;
-
   rgw_obj obj(bucket, key);
 
   if (need_fix) {
@@ -3463,10 +5651,6 @@ int RGWRados::BucketShard::init(rgw_bucket& _bucket, rgw_obj& obj)
 {
   bucket = _bucket;
 
-  if (store->bucket_is_system(bucket)) {
-    return 0;
-  }
-
   int ret = store->open_bucket_index_shard(bucket, index_ctx, obj.get_hash_object(), &bucket_obj, &shard_id);
   if (ret < 0) {
     ldout(store->ctx(), 0) << "ERROR: open_bucket_index_shard() returned ret=" << ret << dendl;
@@ -3478,6 +5662,79 @@ int RGWRados::BucketShard::init(rgw_bucket& _bucket, rgw_obj& obj)
 }
 
 
+int RGWRados::swift_versioning_copy(RGWBucketInfo& bucket_info, RGWRados::Object *source, RGWObjState *state,
+                                    rgw_user& user)
+{
+  if (!bucket_info.has_swift_versioning() || bucket_info.swift_ver_location.empty()) {
+    return 0;
+  }
+
+  if (!state->exists) {
+    return 0;
+  }
+
+  string client_id;
+  string op_id;
+
+  rgw_obj& obj = source->get_obj();
+  const string& src_name = obj.get_object();
+  char buf[src_name.size() + 32];
+  struct timespec ts = ceph::real_clock::to_timespec(state->mtime);
+  snprintf(buf, sizeof(buf), "%03d%s/%lld.%06ld", (int)src_name.size(),
+           src_name.c_str(), (long long)ts.tv_sec, ts.tv_nsec / 1000);
+
+  RGWBucketInfo dest_bucket_info;
+
+  int r = get_bucket_info(source->get_ctx(), bucket_info.bucket.tenant, bucket_info.swift_ver_location, dest_bucket_info, NULL, NULL);
+  if (r < 0) {
+    ldout(cct, 10) << "failed to read dest bucket info: r=" << r << dendl;
+    return r;
+  }
+
+  if (dest_bucket_info.owner != bucket_info.owner) {
+    return -EPERM;
+  }
+
+  rgw_obj dest_obj(dest_bucket_info.bucket, buf);
+
+  string no_zone;
+
+  r = copy_obj(source->get_ctx(),
+               user,
+               client_id,
+               op_id,
+               NULL, /* req_info *info */
+               no_zone,
+               dest_obj,
+               obj,
+               dest_bucket_info,
+               bucket_info,
+               NULL, /* time_t *src_mtime */
+               NULL, /* time_t *mtime */
+               NULL, /* const time_t *mod_ptr */
+               NULL, /* const time_t *unmod_ptr */
+               false, /* bool high_precision_time */
+               NULL, /* const char *if_match */
+               NULL, /* const char *if_nomatch */
+               RGWRados::ATTRSMOD_NONE,
+               true, /* bool copy_if_newer */
+               state->attrset,
+               RGW_OBJ_CATEGORY_MAIN,
+               0, /* uint64_t olh_epoch */
+               real_time(), /* time_t delete_at */
+               NULL, /* string *version_id */
+               NULL, /* string *ptag */
+               NULL, /* string *petag */
+               NULL, /* struct rgw_err *err */
+               NULL, /* void (*progress_cb)(off_t, void *) */
+               NULL); /* void *progress_data */
+  if (r == -ECANCELED || r == -ENOENT) { /* has already been overwritten, meaning another rgw process already copied it out */
+    return 0;
+  }
+
+  return r;
+}
+
 /**
  * Write/overwrite an object to the bucket storage.
  * bucket: the bucket to store the object in
@@ -3504,6 +5761,12 @@ int RGWRados::Object::Write::write_meta(uint64_t size,
     return r;
 
   rgw_obj& obj = target->get_obj();
+
+  if (obj.get_object().empty()) {
+    ldout(store->ctx(), 0) << "ERROR: " << __func__ << "(): cannot write object with empty name" << dendl;
+    return -EIO;
+  }
+
   r = store->get_obj_ref(obj, &ref, &bucket);
   if (r < 0)
     return r;
@@ -3515,18 +5778,16 @@ int RGWRados::Object::Write::write_meta(uint64_t size,
   if (r < 0)
     return r;
 
-  utime_t ut;
-  if (meta.set_mtime) {
-    ut = utime_t(meta.set_mtime, 0);
-  } else {
-    ut = ceph_clock_now(0);
-    meta.set_mtime = ut.sec();
+  if (real_clock::is_zero(meta.set_mtime)) {
+    meta.set_mtime = real_clock::now();
   }
 
   if (state->is_olh) {
     op.setxattr(RGW_ATTR_OLH_ID_TAG, state->olh_tag);
   }
-  op.mtime(&meta.set_mtime);
+
+  struct timespec mtime_ts = real_clock::to_timespec(meta.set_mtime);
+  op.mtime2(&mtime_ts);
 
   if (meta.data) {
     /* if we want to overwrite the data, we also want to overwrite the
@@ -3574,6 +5835,15 @@ int RGWRados::Object::Write::write_meta(uint64_t size,
       acl_bl = bl;
     }
   }
+  if (attrs.find(RGW_ATTR_PG_VER) == attrs.end()) {
+    cls_rgw_obj_store_pg_ver(op, RGW_ATTR_PG_VER);
+  }
+
+  if (attrs.find(RGW_ATTR_SOURCE_ZONE) == attrs.end()) {
+    bufferlist bl;
+    ::encode(store->get_zone_short_id(), bl);
+    op.setxattr(RGW_ATTR_SOURCE_ZONE, bl);
+  }
 
   if (!op.size())
     return 0;
@@ -3591,13 +5861,20 @@ int RGWRados::Object::Write::write_meta(uint64_t size,
 
   bool versioned_op = (target->versioning_enabled() || is_olh || versioned_target);
 
-  RGWRados::Bucket bop(store, bucket);
+  RGWBucketInfo& bucket_info = target->get_bucket_info();
+
+  RGWRados::Bucket bop(store, bucket_info);
   RGWRados::Bucket::UpdateIndex index_op(&bop, obj, state);
 
   if (versioned_op) {
     index_op.set_bilog_flags(RGW_BILOG_FLAG_VERSIONED_OP);
   }
 
+  r = store->swift_versioning_copy(bucket_info, target, state, meta.owner);
+  if (r < 0) {
+    goto done_cancel;
+  }
+
   r = index_op.prepare(CLS_RGW_OP_ADD);
   if (r < 0)
     return r;
@@ -3618,7 +5895,7 @@ int RGWRados::Object::Write::write_meta(uint64_t size,
   }
 
   r = index_op.complete(poolid, epoch, size,
-                        ut, etag, content_type, &acl_bl,
+                        meta.set_mtime, etag, content_type, &acl_bl,
                         meta.category, meta.remove_objs);
   if (r < 0)
     goto done_cancel;
@@ -3632,23 +5909,24 @@ int RGWRados::Object::Write::write_meta(uint64_t size,
   state = NULL;
 
   if (versioned_op) {
-    r = store->set_olh(target->get_ctx(), target->get_bucket_info(), obj, false, NULL, meta.olh_epoch);
+    r = store->set_olh(target->get_ctx(), target->get_bucket_info(), obj, false, NULL, meta.olh_epoch, real_time(), false);
     if (r < 0) {
       return r;
     }
   }
 
-  if (meta.delete_at > 0) {
+  if (!real_clock::is_zero(meta.delete_at)) {
     rgw_obj_key obj_key;
     obj.get_index_key(&obj_key);
 
-    r = store->objexp_hint_add(utime_t(meta.delete_at, 0),
+    r = store->objexp_hint_add(meta.delete_at,
             bucket.tenant, bucket.name, bucket.bucket_id, obj_key);
     if (r < 0) {
       ldout(store->ctx(), 0) << "ERROR: objexp_hint_add() returned r=" << r << ", object will not get removed" << dendl;
       /* ignoring error, nothing we can do at this point */
     }
   }
+  meta.canceled = false;
 
   /* update quota cache */
   store->quota_handler->update_stats(meta.owner, bucket, (orig_exists ? 0 : 1), size, orig_size);
@@ -3661,6 +5939,8 @@ done_cancel:
     ldout(store->ctx(), 0) << "ERROR: index_op.cancel()() returned ret=" << ret << dendl;
   }
 
+  meta.canceled = true;
+
   /* we lost in a race. There are a few options:
    * - existing object was rewritten (ECANCELED)
    * - non existing object was created (EEXIST)
@@ -3699,15 +5979,15 @@ done_cancel:
 }
 
 /** Write/overwrite a system object. */
-int RGWRados::put_system_obj_impl(rgw_obj& obj, uint64_t size, time_t *mtime,
+int RGWRados::put_system_obj_impl(rgw_obj& obj, uint64_t size, real_time *mtime,
               map<std::string, bufferlist>& attrs, int flags,
               bufferlist& data,
               RGWObjVersionTracker *objv_tracker,
-              time_t set_mtime /* 0 for don't set */)
+              real_time set_mtime /* 0 for don't set */)
 {
   rgw_bucket bucket;
   rgw_rados_ref ref;
-  int r = get_obj_ref(obj, &ref, &bucket);
+  int r = get_system_obj_ref(obj, &ref, &bucket);
   if (r < 0)
     return r;
 
@@ -3717,21 +5997,22 @@ int RGWRados::put_system_obj_impl(rgw_obj& obj, uint64_t size, time_t *mtime,
     if (!(flags & PUT_OBJ_CREATE))
 	return -EINVAL;
     op.create(true); // exclusive create
+  } else {
+    op.remove();
+    op.set_op_flags2(LIBRADOS_OP_FLAG_FAILOK);
+    op.create(false);
   }
 
   if (objv_tracker) {
     objv_tracker->prepare_op_for_write(&op);
   }
 
-  utime_t ut;
-  if (set_mtime) {
-    ut = utime_t(set_mtime, 0);
-  } else {
-    ut = ceph_clock_now(0);
-    set_mtime = ut.sec();
+  if (real_clock::is_zero(set_mtime)) {
+    set_mtime = real_clock::now();
   }
 
-  op.mtime(&set_mtime);
+  struct timespec mtime_ts = real_clock::to_timespec(set_mtime);
+  op.mtime2(&mtime_ts);
   op.write_full(data);
 
   bufferlist acl_bl;
@@ -3762,6 +6043,33 @@ int RGWRados::put_system_obj_impl(rgw_obj& obj, uint64_t size, time_t *mtime,
   return 0;
 }
 
+int RGWRados::put_system_obj_data(void *ctx, rgw_obj& obj, bufferlist& bl,
+			       off_t ofs, bool exclusive)
+{
+  rgw_rados_ref ref;
+  rgw_bucket bucket;
+  int r = get_system_obj_ref(obj, &ref, &bucket);
+  if (r < 0) {
+    return r;
+  }
+
+  ObjectWriteOperation op;
+
+  if (exclusive)
+    op.create(true);
+
+  if (ofs == -1) {
+    op.write_full(bl);
+  } else {
+    op.write(ofs, bl);
+  }
+  r = ref.ioctx.operate(ref.oid, &op);
+  if (r < 0)
+    return r;
+
+  return 0;
+}
+
 /**
  * Write/overwrite an object to the bucket storage.
  * bucket: the bucket to store the object in
@@ -3844,7 +6152,9 @@ public:
                                                                        progress_cb(_progress_cb),
                                                                        progress_data(_progress_data) {}
   int handle_data(bufferlist& bl, off_t ofs, off_t len) {
-    progress_cb(ofs, progress_data);
+    if (progress_cb) {
+      progress_cb(ofs, progress_data);
+    }
 
     bool again;
 
@@ -3887,9 +6197,13 @@ public:
     processor->set_extra_data_len(len);
   }
 
-  int complete(string& etag, time_t *mtime, time_t set_mtime, map<string, bufferlist>& attrs, time_t delete_at) {
+  int complete(string& etag, real_time *mtime, real_time set_mtime, map<string, bufferlist>& attrs, real_time delete_at) {
     return processor->complete(etag, mtime, set_mtime, attrs, delete_at);
   }
+
+  bool is_canceled() {
+    return processor->is_canceled();
+  }
 };
 
 /*
@@ -3924,7 +6238,7 @@ int RGWRados::rewrite_obj(RGWBucketInfo& dest_bucket_info, rgw_obj& obj)
   int64_t ofs = 0;
   int64_t end = -1;
 
-  time_t mtime;
+  real_time mtime;
   uint64_t total_len;
   uint64_t obj_size;
   RGWObjectCtx rctx(this);
@@ -3937,21 +6251,87 @@ int RGWRados::rewrite_obj(RGWBucketInfo& dest_bucket_info, rgw_obj& obj)
   read_op.params.read_size = &total_len;
   read_op.params.obj_size = &obj_size;
 
-  int ret = read_op.prepare(&ofs, &end);
-  if (ret < 0)
-    return ret;
+  int ret = read_op.prepare(&ofs, &end);
+  if (ret < 0)
+    return ret;
+
+  attrset.erase(RGW_ATTR_ID_TAG);
+
+  uint64_t max_chunk_size;
+
+  ret = get_max_chunk_size(obj.bucket, &max_chunk_size);
+  if (ret < 0) {
+    ldout(cct, 0) << "ERROR: failed to get max_chunk_size() for bucket " << obj.bucket << dendl;
+    return ret;
+  }
+
+  return copy_obj_data(rctx, dest_bucket_info, read_op, end, obj, obj, max_chunk_size, NULL, mtime, attrset,
+                       RGW_OBJ_CATEGORY_MAIN, 0, real_time(), NULL, NULL, NULL, NULL);
+}
+
+struct obj_time_weight {
+  real_time mtime;
+  uint32_t zone_short_id;
+  uint64_t pg_ver;
+  bool high_precision;
+
+  obj_time_weight() : zone_short_id(0), pg_ver(0), high_precision(false) {}
+
+  bool compare_low_precision(const obj_time_weight& rhs) {
+    struct timespec l = ceph::real_clock::to_timespec(mtime);
+    struct timespec r = ceph::real_clock::to_timespec(rhs.mtime);
+    l.tv_nsec = 0;
+    r.tv_nsec = 0;
+    if (l > r) {
+      return false;
+    }
+    if (l < r) {
+      return true;
+    }
+    if (zone_short_id != rhs.zone_short_id) {
+      return (zone_short_id < rhs.zone_short_id);
+    }
+    return (pg_ver < rhs.pg_ver);
+
+  }
 
-  attrset.erase(RGW_ATTR_ID_TAG);
+  bool operator<(const obj_time_weight& rhs) {
+    if (!high_precision || !rhs.high_precision) {
+      return compare_low_precision(rhs);
+    }
+    if (mtime > rhs.mtime) {
+      return false;
+    }
+    if (mtime < rhs.mtime) {
+      return true;
+    }
+    if (zone_short_id != rhs.zone_short_id) {
+      return (zone_short_id < rhs.zone_short_id);
+    }
+    return (pg_ver < rhs.pg_ver);
+  }
 
-  uint64_t max_chunk_size;
+  void init(const real_time& _mtime, uint32_t _short_id, uint64_t _pg_ver) {
+    mtime = _mtime;
+    zone_short_id = _short_id;
+    pg_ver = _pg_ver;
+  }
 
-  ret = get_max_chunk_size(obj.bucket, &max_chunk_size);
-  if (ret < 0) {
-    ldout(cct, 0) << "ERROR: failed to get max_chunk_size() for bucket " << obj.bucket << dendl;
-    return ret;
+  void init(RGWObjState *state) {
+    mtime = state->mtime;
+    zone_short_id = state->zone_short_id;
+    pg_ver = state->pg_ver;
+  }
+};
+
+inline ostream& operator<<(ostream& out, const obj_time_weight &o) {
+  out << o.mtime;
+
+  if (o.zone_short_id != 0 || o.pg_ver != 0) {
+    out << "[zid=" << o.zone_short_id << ", pgv=" << o.pg_ver << "]";
   }
 
-  return copy_obj_data(rctx, dest_bucket_info, read_op, end, obj, obj, max_chunk_size, NULL, mtime, attrset, RGW_OBJ_CATEGORY_MAIN, 0, 0, NULL, NULL, NULL, NULL);
+  return out;
 }
 
 int RGWRados::fetch_remote_obj(RGWObjectCtx& obj_ctx,
@@ -3964,17 +6344,19 @@ int RGWRados::fetch_remote_obj(RGWObjectCtx& obj_ctx,
                rgw_obj& src_obj,
                RGWBucketInfo& dest_bucket_info,
                RGWBucketInfo& src_bucket_info,
-               time_t *src_mtime,
-               time_t *mtime,
-               const time_t *mod_ptr,
-               const time_t *unmod_ptr,
+               real_time *src_mtime,
+               real_time *mtime,
+               const real_time *mod_ptr,
+               const real_time *unmod_ptr,
+               bool high_precision_time,
                const char *if_match,
                const char *if_nomatch,
                AttrsMod attrs_mod,
+               bool copy_if_newer,
                map<string, bufferlist>& attrs,
                RGWObjCategory category,
                uint64_t olh_epoch,
-	       time_t delete_at,
+	       real_time delete_at,
                string *version_id,
                string *ptag,
                string *petag,
@@ -3982,16 +6364,24 @@ int RGWRados::fetch_remote_obj(RGWObjectCtx& obj_ctx,
                void (*progress_cb)(off_t, void *),
                void *progress_data)
 {
-  /* source is in a different region, copy from there */
+  /* source is in a different zonegroup, copy from there */
 
   RGWRESTStreamReadRequest *in_stream_req;
   string tag;
   map<string, bufferlist> src_attrs;
+  int i;
   append_rand_alpha(cct, tag, tag, 32);
+  obj_time_weight set_mtime_weight;
+  set_mtime_weight.high_precision = high_precision_time;
 
   RGWPutObjProcessor_Atomic processor(obj_ctx,
-                                      dest_bucket_info, dest_obj.bucket, dest_obj.get_object(),
+                                      dest_bucket_info, dest_obj.bucket, dest_obj.get_orig_obj(),
                                       cct->_conf->rgw_obj_stripe_size, tag, dest_bucket_info.versioning_enabled());
+  const string& instance = dest_obj.get_instance();
+  if (instance != "null") {
+    processor.set_version_id(dest_obj.get_instance());
+  }
+  processor.set_olh_epoch(olh_epoch);
   int ret = processor.prepare(this, NULL);
   if (ret < 0) {
     return ret;
@@ -3999,13 +6389,13 @@ int RGWRados::fetch_remote_obj(RGWObjectCtx& obj_ctx,
 
   RGWRESTConn *conn;
   if (source_zone.empty()) {
-    if (dest_bucket_info.region.empty()) {
-      /* source is in the master region */
+    if (dest_bucket_info.zonegroup.empty()) {
+      /* source is in the master zonegroup */
       conn = rest_master_conn;
     } else {
-      map<string, RGWRESTConn *>::iterator iter = region_conn_map.find(src_bucket_info.region);
-      if (iter == region_conn_map.end()) {
-        ldout(cct, 0) << "could not find region connection to region: " << source_zone << dendl;
+      map<string, RGWRESTConn *>::iterator iter = zonegroup_conn_map.find(src_bucket_info.zonegroup);
+      if (iter == zonegroup_conn_map.end()) {
+        ldout(cct, 0) << "could not find zonegroup connection to zonegroup: " << source_zone << dendl;
         return -ENOENT;
       }
       conn = iter->second;
@@ -4031,9 +6421,30 @@ int RGWRados::fetch_remote_obj(RGWObjectCtx& obj_ctx,
   RGWRadosPutObj cb(&processor, &opstate, progress_cb, progress_data);
   string etag;
   map<string, string> req_headers;
-  time_t set_mtime;
+  real_time set_mtime;
+
+  RGWObjState *dest_state = NULL;
+
+  const real_time *pmod = mod_ptr;
+
+  obj_time_weight dest_mtime_weight;
+
+  if (copy_if_newer) {
+    /* need to get mtime for destination */
+    ret = get_obj_state(&obj_ctx, dest_obj, &dest_state, NULL);
+    if (ret < 0)
+      return ret;
+
+    if (dest_state->exists) {
+      dest_mtime_weight.init(dest_state);
+      pmod = &dest_mtime_weight.mtime;
+    }
+  }
+
  
-  ret = conn->get_obj(user_id, info, src_obj, true, &cb, &in_stream_req);
+  ret = conn->get_obj(user_id, info, src_obj, pmod, unmod_ptr,
+                      dest_mtime_weight.zone_short_id, dest_mtime_weight.pg_ver,
+                      true, &cb, &in_stream_req);
   if (ret < 0) {
     goto set_err_state;
   }
@@ -4061,9 +6472,7 @@ int RGWRados::fetch_remote_obj(RGWObjectCtx& obj_ctx,
 	map<string, bufferlist>::iterator iter = src_attrs.find(RGW_ATTR_DELETE_AT);
 	if (iter != src_attrs.end()) {
 	  try {
-	    utime_t da;
-	    ::decode(da, iter->second);
-	    delete_at = (time_t)da.sec();
+	    ::decode(delete_at, iter->second);
 	  } catch (buffer::error& err) {
 	    ldout(cct, 0) << "ERROR: failed to decode delete_at field in intra zone copy" << dendl;
 	  }
@@ -4090,8 +6499,51 @@ int RGWRados::fetch_remote_obj(RGWObjectCtx& obj_ctx,
     attrs = src_attrs;
   }
 
-  ret = cb.complete(etag, mtime, set_mtime, attrs, delete_at);
-  if (ret < 0) {
+  if (copy_if_newer) {
+    uint64_t pg_ver = 0;
+    auto i = attrs.find(RGW_ATTR_PG_VER);
+    if (i != attrs.end() && i->second.length() > 0) {
+      bufferlist::iterator iter = i->second.begin();
+      try {
+        ::decode(pg_ver, iter);
+      } catch (buffer::error& err) {
+        ldout(ctx(), 0) << "ERROR: failed to decode pg ver attribute, ignoring" << dendl;
+        /* non critical error */
+      }
+    }
+    set_mtime_weight.init(set_mtime, get_zone_short_id(), pg_ver);
+  }
+
+#define MAX_COMPLETE_RETRY 100
+  for (i = 0; i < MAX_COMPLETE_RETRY; i++) {
+    ret = cb.complete(etag, mtime, set_mtime, attrs, delete_at);
+    if (ret < 0) {
+      goto set_err_state;
+    }
+    if (copy_if_newer && cb.is_canceled()) {
+      ldout(cct, 20) << "raced with another write of obj: " << dest_obj << dendl;
+      obj_ctx.invalidate(dest_obj); /* object was overwritten */
+      ret = get_obj_state(&obj_ctx, dest_obj, &dest_state, NULL);
+      if (ret < 0) {
+        ldout(cct, 0) << "ERROR: " << __func__ << ": get_err_state() returned ret=" << ret << dendl;
+        goto set_err_state;
+      }
+      dest_mtime_weight.init(dest_state);
+      dest_mtime_weight.high_precision = high_precision_time;
+      if (!dest_state->exists ||
+        dest_mtime_weight < set_mtime_weight) {
+        ldout(cct, 20) << "retrying writing object mtime=" << set_mtime << " dest_state->mtime=" << dest_state->mtime << " dest_state->exists=" << dest_state->exists << dendl;
+        continue;
+      } else {
+        ldout(cct, 20) << "not retrying writing object mtime=" << set_mtime << " dest_state->mtime=" << dest_state->mtime << " dest_state->exists=" << dest_state->exists << dendl;
+      }
+    }
+    break;
+  }
+
+  if (i == MAX_COMPLETE_RETRY) {
+    ldout(cct, 0) << "ERROR: retried object completion too many times, something is wrong!" << dendl;
+    ret = -EIO;
     goto set_err_state;
   }
 
@@ -4102,7 +6554,12 @@ int RGWRados::fetch_remote_obj(RGWObjectCtx& obj_ctx,
 
   return 0;
 set_err_state:
-  int r = opstate.set_state(RGWOpState::OPSTATE_ERROR);
+  RGWOpState::OpState state = RGWOpState::OPSTATE_ERROR;
+  if (copy_if_newer && ret == -ERR_NOT_MODIFIED) {
+    state = RGWOpState::OPSTATE_COMPLETE;
+    ret = 0;
+  }
+  int r = opstate.set_state(state);
   if (r < 0) {
     ldout(cct, 0) << "ERROR: failed to set opstate r=" << ret << dendl;
   }
@@ -4115,7 +6572,7 @@ int RGWRados::copy_obj_to_remote_dest(RGWObjState *astate,
                                       RGWRados::Object::Read& read_op,
                                       const rgw_user& user_id,
                                       rgw_obj& dest_obj,
-                                      time_t *mtime)
+                                      real_time *mtime)
 {
   string etag;
 
@@ -4163,17 +6620,19 @@ int RGWRados::copy_obj(RGWObjectCtx& obj_ctx,
                rgw_obj& src_obj,
                RGWBucketInfo& dest_bucket_info,
                RGWBucketInfo& src_bucket_info,
-               time_t *src_mtime,
-               time_t *mtime,
-               const time_t *mod_ptr,
-               const time_t *unmod_ptr,
+               real_time *src_mtime,
+               real_time *mtime,
+               const real_time *mod_ptr,
+               const real_time *unmod_ptr,
+               bool high_precision_time,
                const char *if_match,
                const char *if_nomatch,
                AttrsMod attrs_mod,
+               bool copy_if_newer,
                map<string, bufferlist>& attrs,
                RGWObjCategory category,
                uint64_t olh_epoch,
-	       time_t delete_at,
+	       real_time delete_at,
                string *version_id,
                string *ptag,
                string *petag,
@@ -4192,8 +6651,8 @@ int RGWRados::copy_obj(RGWObjectCtx& obj_ctx,
   append_rand_alpha(cct, dest_obj.get_object(), shadow_oid, 32);
   shadow_obj.init_ns(dest_obj.bucket, shadow_oid, shadow_ns);
 
-  remote_dest = !region.equals(dest_bucket_info.region);
-  remote_src = !region.equals(src_bucket_info.region);
+  remote_dest = !get_zonegroup().equals(dest_bucket_info.zonegroup);
+  remote_src = !get_zonegroup().equals(src_bucket_info.zonegroup);
 
   if (remote_src && remote_dest) {
     ldout(cct, 0) << "ERROR: can't copy object when both src and dest buckets are remote" << dendl;
@@ -4205,7 +6664,8 @@ int RGWRados::copy_obj(RGWObjectCtx& obj_ctx,
   if (remote_src || !source_zone.empty()) {
     return fetch_remote_obj(obj_ctx, user_id, client_id, op_id, info, source_zone,
                dest_obj, src_obj, dest_bucket_info, src_bucket_info, src_mtime, mtime, mod_ptr,
-               unmod_ptr, if_match, if_nomatch, attrs_mod, attrs, category,
+               unmod_ptr, high_precision_time,
+               if_match, if_nomatch, attrs_mod, copy_if_newer, attrs, category,
                olh_epoch, delete_at, version_id, ptag, petag, err, progress_cb, progress_data);
   }
 
@@ -4217,6 +6677,7 @@ int RGWRados::copy_obj(RGWObjectCtx& obj_ctx,
 
   read_op.conds.mod_ptr = mod_ptr;
   read_op.conds.unmod_ptr = unmod_ptr;
+  read_op.conds.high_precision_time = high_precision_time;
   read_op.conds.if_match = if_match;
   read_op.conds.if_nomatch = if_nomatch;
   read_op.params.attrs = &src_attrs;
@@ -4235,6 +6696,8 @@ int RGWRados::copy_obj(RGWObjectCtx& obj_ctx,
 
   set_copy_attrs(src_attrs, attrs, attrs_mod);
   attrs.erase(RGW_ATTR_ID_TAG);
+  attrs.erase(RGW_ATTR_PG_VER);
+  attrs.erase(RGW_ATTR_SOURCE_ZONE);
 
   RGWObjManifest manifest;
   RGWObjState *astate = NULL;
@@ -4246,7 +6709,7 @@ int RGWRados::copy_obj(RGWObjectCtx& obj_ctx,
   vector<rgw_obj> ref_objs;
 
   if (remote_dest) {
-    /* dest is in a different region, copy it there */
+    /* dest is in a different zonegroup, copy it there */
     return copy_obj_to_remote_dest(astate, attrs, read_op, user_id, dest_obj, mtime);
   }
   uint64_t max_chunk_size;
@@ -4285,7 +6748,7 @@ int RGWRados::copy_obj(RGWObjectCtx& obj_ctx,
 
   if (copy_data) { /* refcounting tail wouldn't work here, just copy the data */
     return copy_obj_data(obj_ctx, dest_bucket_info, read_op, end, dest_obj, src_obj,
-                         max_chunk_size, mtime, 0, attrs, category, olh_epoch, delete_at,
+                         max_chunk_size, mtime, real_time(), attrs, category, olh_epoch, delete_at,
                          version_id, ptag, petag, err);
   }
 
@@ -4416,12 +6879,12 @@ int RGWRados::copy_obj_data(RGWObjectCtx& obj_ctx,
                rgw_obj& dest_obj,
                rgw_obj& src_obj,
                uint64_t max_chunk_size,
-	       time_t *mtime,
-	       time_t set_mtime,
+	       real_time *mtime,
+	       real_time set_mtime,
                map<string, bufferlist>& attrs,
                RGWObjCategory category,
                uint64_t olh_epoch,
-	       time_t delete_at,
+	       real_time delete_at,
                string *version_id,
                string *ptag,
                string *petag,
@@ -4483,6 +6946,15 @@ int RGWRados::copy_obj_data(RGWObjectCtx& obj_ctx,
   return ret;
 }
 
+bool RGWRados::is_meta_master()
+{
+  if (!get_zonegroup().is_master) {
+    return false;
+  }
+
+  return (get_zonegroup().master_zone == zone_public_config.id);
+}
+
 /**
   * Check to see if the bucket metadata could be synced
   * bucket: the bucket to check
@@ -4490,18 +6962,18 @@ int RGWRados::copy_obj_data(RGWObjectCtx& obj_ctx,
   */
 bool RGWRados::is_syncing_bucket_meta(rgw_bucket& bucket)
 {
-  /* region is not master region */
-  if (!region.is_master) {
+  /* zonegroup is not master zonegroup */
+  if (!get_zonegroup().is_master) {
     return false;
   }
 
-  /* single region and a single zone */
-  if (region_map.regions.size() == 1 && region.zones.size() == 1) {
+  /* single zonegroup and a single zone */
+  if (current_period.is_single_zonegroup(cct, this) && get_zonegroup().zones.size() == 1) {
     return false;
   }
 
   /* zone is not master */
-  if (region.master_zone.compare(zone_name) != 0) {
+  if (get_zonegroup().master_zone.compare(zone_public_config.id) != 0) {
     return false;
   }
 
@@ -4528,7 +7000,7 @@ int RGWRados::delete_bucket(rgw_bucket& bucket, RGWObjVersionTracker& objv_track
 
   do {
 #define NUM_ENTRIES 1000
-    r = cls_bucket_list(bucket, marker, prefix, NUM_ENTRIES, true, ent_map,
+    r = cls_bucket_list(bucket, RGW_NO_SHARD, marker, prefix, NUM_ENTRIES, true, ent_map,
                         &is_truncated, &marker);
     if (r < 0)
       return r;
@@ -4549,7 +7021,7 @@ int RGWRados::delete_bucket(rgw_bucket& bucket, RGWObjVersionTracker& objv_track
   if (r < 0)
     return r;
 
-  /* if the bucked is not synced we can remove the meta file */
+  /* if the bucket is not synced we can remove the meta file */
   if (!is_syncing_bucket_meta(bucket)) {
     RGWObjVersionTracker objv_tracker;
     string entry;
@@ -4576,7 +7048,7 @@ int RGWRados::set_bucket_owner(rgw_bucket& bucket, ACLOwner& owner)
 
   info.owner = owner.get_id();
 
-  r = put_bucket_instance_info(info, false, 0, &attrs);
+  r = put_bucket_instance_info(info, false, real_time(), &attrs);
   if (r < 0) {
     ldout(cct, 0) << "NOTICE: put_bucket_info on bucket=" << bucket.name << " returned err=" << r << dendl;
     return r;
@@ -4614,7 +7086,7 @@ int RGWRados::set_buckets_enabled(vector<rgw_bucket>& buckets, bool enabled)
       info.flags |= BUCKET_SUSPENDED;
     }
 
-    r = put_bucket_instance_info(info, false, 0, &attrs);
+    r = put_bucket_instance_info(info, false, real_time(), &attrs);
     if (r < 0) {
       ldout(cct, 0) << "NOTICE: put_bucket_info on bucket=" << bucket.name << " returned err=" << r << ", skipping bucket" << dendl;
       ret = r;
@@ -4673,9 +7145,6 @@ int RGWRados::send_chain_to_gc(cls_rgw_obj_chain& chain, const string& tag, bool
 
 int RGWRados::open_bucket_index(rgw_bucket& bucket, librados::IoCtx& index_ctx, string& bucket_oid)
 {
-  if (bucket_is_system(bucket))
-    return -EINVAL;
-
   int r = open_bucket_index_ctx(bucket, index_ctx);
   if (r < 0)
     return r;
@@ -4693,9 +7162,6 @@ int RGWRados::open_bucket_index(rgw_bucket& bucket, librados::IoCtx& index_ctx,
 
 int RGWRados::open_bucket_index_base(rgw_bucket& bucket, librados::IoCtx& index_ctx,
     string& bucket_oid_base) {
-  if (bucket_is_system(bucket))
-    return -EINVAL;
-
   int r = open_bucket_index_ctx(bucket, index_ctx);
   if (r < 0)
     return r;
@@ -4871,6 +7337,11 @@ void RGWRados::cls_obj_check_prefix_exist(ObjectOperation& op, const string& pre
   cls_rgw_obj_check_attrs_prefix(op, prefix, fail_if_exist);
 }
 
+void RGWRados::cls_obj_check_mtime(ObjectOperation& op, const real_time& mtime, bool high_precision_time, RGWCheckMTimeType type)
+{
+  cls_rgw_obj_check_mtime(op, mtime, high_precision_time, type);
+}
+
 
 /**
  * Delete an object.
@@ -4910,9 +7381,14 @@ int RGWRados::Object::Delete::delete_obj()
 
       meta.owner = params.obj_owner.get_id().to_str();
       meta.owner_display_name = params.obj_owner.get_display_name();
-      meta.mtime = ceph_clock_now(store->ctx());
 
-      int r = store->set_olh(target->get_ctx(), target->get_bucket_info(), marker, true, &meta, params.olh_epoch);
+      if (real_clock::is_zero(params.mtime)) {
+        meta.mtime = real_clock::now();
+      } else {
+        meta.mtime = params.mtime;
+      }
+
+      int r = store->set_olh(target->get_ctx(), target->get_bucket_info(), marker, true, &meta, params.olh_epoch, params.unmod_since, params.high_precision_time);
       if (r < 0) {
         return r;
       }
@@ -4931,6 +7407,19 @@ int RGWRados::Object::Delete::delete_obj()
       result.version_id = instance;
     }
 
+    BucketShard *bs;
+    int r = target->get_bucket_shard(&bs);
+    if (r < 0) {
+      ldout(store->ctx(), 5) << "failed to get BucketShard object: r=" << r << dendl;
+      return r;
+    }
+
+    r = store->data_log->add_entry(bs->bucket, bs->shard_id);
+    if (r < 0) {
+      lderr(store->ctx()) << "ERROR: failed writing data log" << dendl;
+      return r;
+    }
+
     return 0;
   }
 
@@ -4946,11 +7435,29 @@ int RGWRados::Object::Delete::delete_obj()
   if (r < 0)
     return r;
 
+  ObjectWriteOperation op;
+
+  if (!real_clock::is_zero(params.unmod_since)) {
+    struct timespec ctime = ceph::real_clock::to_timespec(state->mtime);
+    struct timespec unmod = ceph::real_clock::to_timespec(params.unmod_since);
+    if (!params.high_precision_time) {
+      ctime.tv_nsec = 0;
+      unmod.tv_nsec = 0;
+    }
+
+    ldout(store->ctx(), 10) << "If-UnModified-Since: " << params.unmod_since << " Last-Modified: " << ctime << dendl;
+    if (ctime > unmod) {
+      return -ERR_PRECONDITION_FAILED;
+    }
+
+    /* only delete object if mtime is less than or equal to params.unmod_since */
+    store->cls_obj_check_mtime(op, params.unmod_since, params.high_precision_time, CLS_RGW_CHECK_TIME_MTIME_LE);
+  }
   uint64_t obj_size = state->size;
 
-  if (!params.expiration_time.is_zero()) {
+  if (!real_clock::is_zero(params.expiration_time)) {
     bufferlist bl;
-    utime_t delete_at;
+    real_time delete_at;
 
     if (state->get_attr(RGW_ATTR_DELETE_AT, bl)) {
       try {
@@ -4967,19 +7474,24 @@ int RGWRados::Object::Delete::delete_obj()
     }
   }
 
-  ObjectWriteOperation op;
-
   r = target->prepare_atomic_modification(op, false, NULL, NULL, NULL, true);
   if (r < 0)
     return r;
 
   bool ret_not_existed = (!state->exists);
 
-  RGWRados::Bucket bop(store, bucket);
+  RGWBucketInfo& bucket_info = target->get_bucket_info();
+
+  RGWRados::Bucket bop(store, bucket_info);
   RGWRados::Bucket::UpdateIndex index_op(&bop, obj, state);
 
   index_op.set_bilog_flags(params.bilog_flags);
 
+  r = store->swift_versioning_copy(bucket_info, target, state, params.bucket_owner);
+  if (r < 0) {
+    return r;
+  }
+
   r = index_op.prepare(CLS_RGW_OP_DEL);
   if (r < 0)
     return r;
@@ -4995,7 +7507,7 @@ int RGWRados::Object::Delete::delete_obj()
   bool removed = (r >= 0);
 
   int64_t poolid = ref.ioctx.get_id();
-  if (r >= 0 || r == -ENOENT) {
+  if (r >= 0) {
     r = index_op.complete_del(poolid, ref.ioctx.get_last_version(), params.remove_objs);
   } else {
     int ret = index_op.cancel();
@@ -5032,7 +7544,7 @@ int RGWRados::delete_obj(RGWObjectCtx& obj_ctx,
                          rgw_obj& obj,
                          int versioning_status,
                          uint16_t bilog_flags,
-                         const utime_t& expiration_time)
+                         const real_time& expiration_time)
 {
   RGWRados::Object del_target(this, bucket_info, obj_ctx, obj);
   RGWRados::Object::Delete del_op(&del_target);
@@ -5074,7 +7586,16 @@ int RGWRados::delete_obj_index(rgw_obj& obj)
   std::string oid, key;
   get_obj_bucket_and_oid_loc(obj, bucket, oid, key);
 
-  RGWRados::Bucket bop(this, bucket);
+  RGWObjectCtx obj_ctx(this);
+
+  RGWBucketInfo bucket_info;
+  int ret = get_bucket_instance_info(obj_ctx, bucket, bucket_info, NULL, NULL);
+  if (ret < 0) {
+    ldout(cct, 0) << "ERROR: " << __func__ << "() get_bucket_instance_info(bucket=" << bucket << ") returned ret=" << ret << dendl;
+    return ret;
+  }
+
+  RGWRados::Bucket bop(this, bucket_info);
   RGWRados::Bucket::UpdateIndex index_op(&bop, obj, NULL);
 
   int r = index_op.complete_del(-1 /* pool */, 0, NULL);
@@ -5127,7 +7648,7 @@ static bool has_olh_tag(map<string, bufferlist>& attrs)
 }
 
 int RGWRados::get_olh_target_state(RGWObjectCtx& obj_ctx, rgw_obj& obj, RGWObjState *olh_state,
-                                   RGWObjState **target_state, RGWObjVersionTracker *objv_tracker)
+                                   RGWObjState **target_state)
 {
   assert(olh_state->is_olh);
 
@@ -5136,7 +7657,7 @@ int RGWRados::get_olh_target_state(RGWObjectCtx& obj_ctx, rgw_obj& obj, RGWObjSt
   if (r < 0) {
     return r;
   }
-  r = get_obj_state(&obj_ctx, target, target_state, objv_tracker, false);
+  r = get_obj_state(&obj_ctx, target, target_state, false);
   if (r < 0) {
     return r;
   }
@@ -5144,7 +7665,52 @@ int RGWRados::get_olh_target_state(RGWObjectCtx& obj_ctx, rgw_obj& obj, RGWObjSt
   return 0;
 }
 
-int RGWRados::get_obj_state_impl(RGWObjectCtx *rctx, rgw_obj& obj, RGWObjState **state, RGWObjVersionTracker *objv_tracker, bool follow_olh)
+int RGWRados::get_system_obj_state_impl(RGWObjectCtx *rctx, rgw_obj& obj, RGWObjState **state, RGWObjVersionTracker *objv_tracker)
+{
+  RGWObjState *s = rctx->get_state(obj);
+  ldout(cct, 20) << "get_system_obj_state: rctx=" << (void *)rctx << " obj=" << obj << " state=" << (void *)s << " s->prefetch_data=" << s->prefetch_data << dendl;
+  *state = s;
+  if (s->has_attrs) {
+    return 0;
+  }
+
+  s->obj = obj;
+
+  int r = raw_obj_stat(obj, &s->size, &s->mtime, &s->epoch, &s->attrset, (s->prefetch_data ? &s->data : NULL), objv_tracker);
+  if (r == -ENOENT) {
+    s->exists = false;
+    s->has_attrs = true;
+    s->mtime = real_time();
+    return 0;
+  }
+  if (r < 0)
+    return r;
+
+  s->exists = true;
+  s->has_attrs = true;
+  s->obj_tag = s->attrset[RGW_ATTR_ID_TAG];
+
+  bufferlist manifest_bl = s->attrset[RGW_ATTR_MANIFEST];
+  if (s->obj_tag.length())
+    ldout(cct, 20) << "get_system_obj_state: setting s->obj_tag to " << string(s->obj_tag.c_str(), s->obj_tag.length()) << dendl;
+  else
+    ldout(cct, 20) << "get_system_obj_state: s->obj_tag was set empty" << dendl;
+
+  return 0;
+}
+
+int RGWRados::get_system_obj_state(RGWObjectCtx *rctx, rgw_obj& obj, RGWObjState **state, RGWObjVersionTracker *objv_tracker)
+{
+  int ret;
+
+  do {
+    ret = get_system_obj_state_impl(rctx, obj, state, objv_tracker);
+  } while (ret == -EAGAIN);
+
+  return ret;
+}
+
+int RGWRados::get_obj_state_impl(RGWObjectCtx *rctx, rgw_obj& obj, RGWObjState **state, bool follow_olh)
 {
   bool need_follow_olh = follow_olh && !obj.have_instance();
 
@@ -5153,18 +7719,18 @@ int RGWRados::get_obj_state_impl(RGWObjectCtx *rctx, rgw_obj& obj, RGWObjState *
   *state = s;
   if (s->has_attrs) {
     if (s->is_olh && need_follow_olh) {
-      return get_olh_target_state(*rctx, obj, s, state, objv_tracker);
+      return get_olh_target_state(*rctx, obj, s, state);
     }
     return 0;
   }
 
   s->obj = obj;
 
-  int r = raw_obj_stat(obj, &s->size, &s->mtime, &s->epoch, &s->attrset, (s->prefetch_data ? &s->data : NULL), objv_tracker);
+  int r = RGWRados::raw_obj_stat(obj, &s->size, &s->mtime, &s->epoch, &s->attrset, (s->prefetch_data ? &s->data : NULL), NULL);
   if (r == -ENOENT) {
     s->exists = false;
     s->has_attrs = true;
-    s->mtime = 0;
+    s->mtime = real_time();
     return 0;
   }
   if (r < 0)
@@ -5190,7 +7756,7 @@ int RGWRados::get_obj_state_impl(RGWObjectCtx *rctx, rgw_obj& obj, RGWObjState *
       s->has_manifest = true;
       s->size = s->manifest.get_obj_size();
     } catch (buffer::error& err) {
-      ldout(cct, 20) << "ERROR: couldn't decode manifest" << dendl;
+      ldout(cct, 0) << "ERROR: couldn't decode manifest" << dendl;
       return -EIO;
     }
     ldout(cct, 10) << "manifest: total_size = " << s->manifest.get_obj_size() << dendl;
@@ -5210,6 +7776,30 @@ int RGWRados::get_obj_state_impl(RGWObjectCtx *rctx, rgw_obj& obj, RGWObjState *
       s->fake_tag = true;
     }
   }
+  map<string, bufferlist>::iterator aiter = s->attrset.find(RGW_ATTR_PG_VER);
+  if (aiter != s->attrset.end()) {
+    bufferlist& pg_ver_bl = aiter->second;
+    if (pg_ver_bl.length()) {
+      bufferlist::iterator pgbl = pg_ver_bl.begin();
+      try {
+        ::decode(s->pg_ver, pgbl);
+      } catch (buffer::error& err) {
+        ldout(cct, 0) << "ERROR: couldn't decode pg ver attr for object " << s->obj << ", non-critical error, ignoring" << dendl;
+      }
+    }
+  }
+  aiter = s->attrset.find(RGW_ATTR_SOURCE_ZONE);
+  if (aiter != s->attrset.end()) {
+    bufferlist& zone_short_id_bl = aiter->second;
+    if (zone_short_id_bl.length()) {
+      bufferlist::iterator zbl = zone_short_id_bl.begin();
+      try {
+        ::decode(s->zone_short_id, zbl);
+      } catch (buffer::error& err) {
+        ldout(cct, 0) << "ERROR: couldn't decode zone short id attr for object " << s->obj << ", non-critical error, ignoring" << dendl;
+      }
+    }
+  }
   if (s->obj_tag.length())
     ldout(cct, 20) << "get_obj_state: setting s->obj_tag to " << string(s->obj_tag.c_str(), s->obj_tag.length()) << dendl;
   else
@@ -5229,19 +7819,19 @@ int RGWRados::get_obj_state_impl(RGWObjectCtx *rctx, rgw_obj& obj, RGWObjState *
     ldout(cct, 20) << __func__ << ": setting s->olh_tag to " << string(s->olh_tag.c_str(), s->olh_tag.length()) << dendl;
 
     if (need_follow_olh) {
-      return get_olh_target_state(*rctx, obj, s, state, objv_tracker);
+      return get_olh_target_state(*rctx, obj, s, state);
     }
   }
 
   return 0;
 }
 
-int RGWRados::get_obj_state(RGWObjectCtx *rctx, rgw_obj& obj, RGWObjState **state, RGWObjVersionTracker *objv_tracker, bool follow_olh)
+int RGWRados::get_obj_state(RGWObjectCtx *rctx, rgw_obj& obj, RGWObjState **state, bool follow_olh)
 {
   int ret;
 
   do {
-    ret = get_obj_state_impl(rctx, obj, state, objv_tracker, follow_olh);
+    ret = get_obj_state_impl(rctx, obj, state, follow_olh);
   } while (ret == -EAGAIN);
 
   return ret;
@@ -5273,7 +7863,7 @@ int RGWRados::Object::Stat::stat_async()
   if (s->has_attrs) {
     state.ret = 0;
     result.size = s->size;
-    result.mtime = s->mtime;
+    result.mtime = ceph::real_clock::to_timespec(s->mtime);
     result.attrs = s->attrset;
     result.has_manifest = s->has_manifest;
     result.manifest = s->manifest;
@@ -5291,13 +7881,15 @@ int RGWRados::Object::Stat::stat_async()
   }
 
   librados::ObjectReadOperation op;
-  op.stat(&result.size, &result.mtime, NULL);
+  op.stat2(&result.size, &result.mtime, NULL);
   op.getxattrs(&result.attrs, NULL);
   state.completion = librados::Rados::aio_create_completion(NULL, NULL, NULL);
   state.io_ctx.locator_set_key(loc);
   r = state.io_ctx.aio_operate(oid, state.completion, &op, NULL);
   if (r < 0) {
-    ldout(store->ctx(), 5) << __func__ << ": ERROR: aio_operate() returned ret=" << r << dendl;
+    ldout(store->ctx(), 5) << __func__
+						   << ": ERROR: aio_operate() returned ret=" << r
+						   << dendl;
     return r;
   }
 
@@ -5353,7 +7945,7 @@ int RGWRados::system_obj_get_attr(rgw_obj& obj, const char *name, bufferlist& de
 {
   rgw_rados_ref ref;
   rgw_bucket bucket;
-  int r = get_obj_ref(obj, &ref, &bucket, true);
+  int r = get_system_obj_ref(obj, &ref, &bucket);
   if (r < 0) {
     return r;
   }
@@ -5397,7 +7989,7 @@ int RGWRados::append_atomic_test(RGWObjectCtx *rctx, rgw_obj& obj,
 
 int RGWRados::Object::get_state(RGWObjState **pstate, bool follow_olh)
 {
-  return store->get_obj_state(&ctx, obj, pstate, NULL, follow_olh);
+  return store->get_obj_state(&ctx, obj, pstate, follow_olh);
 }
 
 void RGWRados::Object::invalidate_state()
@@ -5494,6 +8086,61 @@ int RGWRados::Object::prepare_atomic_modification(ObjectWriteOperation& op, bool
   return 0;
 }
 
+int RGWRados::system_obj_set_attr(void *ctx, rgw_obj& obj, const char *name, bufferlist& bl,
+				  RGWObjVersionTracker *objv_tracker)
+{
+  map<string, bufferlist> attrs;
+  attrs[name] = bl;
+  return system_obj_set_attrs(ctx, obj, attrs, NULL, objv_tracker);
+}
+
+int RGWRados::system_obj_set_attrs(void *ctx, rgw_obj& obj,
+                        map<string, bufferlist>& attrs,
+                        map<string, bufferlist>* rmattrs,
+                        RGWObjVersionTracker *objv_tracker)
+{
+  rgw_rados_ref ref;
+  rgw_bucket bucket;
+  int r = get_system_obj_ref(obj, &ref, &bucket);
+  if (r < 0) {
+    return r;
+  }
+  ObjectWriteOperation op;
+
+  if (objv_tracker) {
+    objv_tracker->prepare_op_for_write(&op);
+  }
+
+  map<string, bufferlist>::iterator iter;
+  if (rmattrs) {
+    for (iter = rmattrs->begin(); iter != rmattrs->end(); ++iter) {
+      const string& name = iter->first;
+      op.rmxattr(name.c_str());
+    }
+  }
+
+  for (iter = attrs.begin(); iter != attrs.end(); ++iter) {
+    const string& name = iter->first;
+    bufferlist& bl = iter->second;
+
+    if (!bl.length())
+      continue;
+
+    op.setxattr(name.c_str(), bl);
+  }
+
+  if (!op.size())
+    return 0;
+
+  bufferlist bl;
+
+  r = ref.ioctx.operate(ref.oid, &op);
+  if (r < 0)
+    return r;
+
+  return 0;
+}
+
 /**
  * Set an attr on an object.
  * bucket: name of the bucket holding the object
@@ -5502,21 +8149,20 @@ int RGWRados::Object::prepare_atomic_modification(ObjectWriteOperation& op, bool
  * bl: the contents of the attr
  * Returns: 0 on success, -ERR# otherwise.
  */
-int RGWRados::set_attr(void *ctx, rgw_obj& obj, const char *name, bufferlist& bl, RGWObjVersionTracker *objv_tracker)
+int RGWRados::set_attr(void *ctx, rgw_obj& obj, const char *name, bufferlist& bl)
 {
   map<string, bufferlist> attrs;
   attrs[name] = bl;
-  return set_attrs(ctx, obj, attrs, NULL, objv_tracker);
+  return set_attrs(ctx, obj, attrs, NULL);
 }
 
 int RGWRados::set_attrs(void *ctx, rgw_obj& obj,
                         map<string, bufferlist>& attrs,
-                        map<string, bufferlist>* rmattrs,
-                        RGWObjVersionTracker *objv_tracker)
+                        map<string, bufferlist>* rmattrs)
 {
   rgw_rados_ref ref;
   rgw_bucket bucket;
-  int r = get_obj_ref(obj, &ref, &bucket, true);
+  int r = get_obj_ref(obj, &ref, &bucket);
   if (r < 0) {
     return r;
   }
@@ -5529,10 +8175,6 @@ int RGWRados::set_attrs(void *ctx, rgw_obj& obj,
   if (r < 0)
     return r;
 
-  if (objv_tracker) {
-    objv_tracker->prepare_op_for_write(&op);
-  }
-
   map<string, bufferlist>::iterator iter;
   if (rmattrs) {
     for (iter = rmattrs->begin(); iter != rmattrs->end(); ++iter) {
@@ -5551,7 +8193,7 @@ int RGWRados::set_attrs(void *ctx, rgw_obj& obj,
     op.setxattr(name.c_str(), bl);
 
     if (name.compare(RGW_ATTR_DELETE_AT) == 0) {
-      utime_t ts;
+      real_time ts;
       try {
         ::decode(ts, bl);
 
@@ -5568,8 +8210,17 @@ int RGWRados::set_attrs(void *ctx, rgw_obj& obj,
   if (!op.size())
     return 0;
 
+  RGWObjectCtx obj_ctx(this);
+
+  RGWBucketInfo bucket_info;
+  int ret = get_bucket_instance_info(obj_ctx, bucket, bucket_info, NULL, NULL);
+  if (ret < 0) {
+    ldout(cct, 0) << "ERROR: " << __func__ << "() get_bucket_instance_info(bucket=" << bucket << ") returned ret=" << ret << dendl;
+    return ret;
+  }
+
   bufferlist bl;
-  RGWRados::Bucket bop(this, bucket);
+  RGWRados::Bucket bop(this, bucket_info);
   RGWRados::Bucket::UpdateIndex index_op(&bop, obj, state);
 
   if (state) {
@@ -5596,7 +8247,7 @@ int RGWRados::set_attrs(void *ctx, rgw_obj& obj,
       string content_type(content_type_bl.c_str(), content_type_bl.length());
       uint64_t epoch = ref.ioctx.get_last_version();
       int64_t poolid = ref.ioctx.get_id();
-      utime_t mtime = ceph_clock_now(cct);
+      real_time mtime = real_clock::now();
       r = index_op.complete(poolid, epoch, state->size,
                             mtime, etag, content_type, &acl_bl,
                             RGW_OBJ_CATEGORY_MAIN, NULL);
@@ -5688,18 +8339,25 @@ int RGWRados::Object::Read::prepare(int64_t *pofs, int64_t *pend)
 
   /* Convert all times go GMT to make them compatible */
   if (conds.mod_ptr || conds.unmod_ptr) {
-    time_t ctime = astate->mtime;
+    obj_time_weight src_weight;
+    src_weight.init(astate);
+    src_weight.high_precision = conds.high_precision_time;
+
+    obj_time_weight dest_weight;
+    dest_weight.high_precision = conds.high_precision_time;
 
     if (conds.mod_ptr) {
-      ldout(cct, 10) << "If-Modified-Since: " << *conds.mod_ptr << " Last-Modified: " << ctime << dendl;
-      if (ctime < *conds.mod_ptr) {
+      dest_weight.init(*conds.mod_ptr, conds.mod_zone_id, conds.mod_pg_ver);
+      ldout(cct, 10) << "If-Modified-Since: " << dest_weight << " Last-Modified: " << src_weight << dendl;
+      if (!(dest_weight < src_weight)) {
         return -ERR_NOT_MODIFIED;
       }
     }
 
     if (conds.unmod_ptr) {
-      ldout(cct, 10) << "If-UnModified-Since: " << *conds.unmod_ptr << " Last-Modified: " << ctime << dendl;
-      if (ctime > *conds.unmod_ptr) {
+      dest_weight.init(*conds.unmod_ptr, conds.mod_zone_id, conds.mod_pg_ver);
+      ldout(cct, 10) << "If-UnModified-Since: " << dest_weight << " Last-Modified: " << src_weight << dendl;
+      if (dest_weight < src_weight) {
         return -ERR_PRECONDITION_FAILED;
       }
     }
@@ -5765,20 +8423,20 @@ int RGWRados::Object::Read::prepare(int64_t *pofs, int64_t *pend)
 
 int RGWRados::SystemObject::get_state(RGWObjState **pstate, RGWObjVersionTracker *objv_tracker)
 {
-  return store->get_obj_state(&ctx, obj, pstate, objv_tracker, false);
+  return store->get_system_obj_state(&ctx, obj, pstate, objv_tracker);
 }
 
 int RGWRados::stat_system_obj(RGWObjectCtx& obj_ctx,
                               RGWRados::SystemObject::Read::GetObjState& state,
                               rgw_obj& obj,
                               map<string, bufferlist> *attrs,
-                              time_t *lastmod,
+                              real_time *lastmod,
                               uint64_t *obj_size,
                               RGWObjVersionTracker *objv_tracker)
 {
   RGWObjState *astate = NULL;
 
-  int r = get_obj_state(&obj_ctx, obj, &astate, objv_tracker);
+  int r = get_system_obj_state(&obj_ctx, obj, &astate, objv_tracker);
   if (r < 0)
     return r;
 
@@ -5815,6 +8473,9 @@ int RGWRados::SystemObject::Read::stat(RGWObjVersionTracker *objv_tracker)
 
 int RGWRados::Bucket::UpdateIndex::prepare(RGWModifyOp op)
 {
+  if (blind) {
+    return 0;
+  }
   RGWRados *store = target->get_store();
   BucketShard *bs;
   int ret = get_bucket_shard(&bs);
@@ -5823,12 +8484,6 @@ int RGWRados::Bucket::UpdateIndex::prepare(RGWModifyOp op)
     return ret;
   }
 
-  ret = store->data_log->add_entry(bs->bucket, bs->shard_id);
-  if (ret < 0) {
-    lderr(store->ctx()) << "ERROR: failed writing data log" << dendl;
-    return ret;
-  }
-
   if (obj_state && obj_state->write_tag.length()) {
     optag = string(obj_state->write_tag.c_str(), obj_state->write_tag.length());
   } else {
@@ -5842,9 +8497,12 @@ int RGWRados::Bucket::UpdateIndex::prepare(RGWModifyOp op)
 }
 
 int RGWRados::Bucket::UpdateIndex::complete(int64_t poolid, uint64_t epoch, uint64_t size,
-                                    utime_t& ut, string& etag, string& content_type, bufferlist *acl_bl, RGWObjCategory category,
+                                    ceph::real_time& ut, string& etag, string& content_type, bufferlist *acl_bl, RGWObjCategory category,
                                     list<rgw_obj_key> *remove_objs)
 {
+  if (blind) {
+    return 0;
+  }
   RGWRados *store = target->get_store();
   BucketShard *bs;
   int ret = get_bucket_shard(&bs);
@@ -5871,12 +8529,20 @@ int RGWRados::Bucket::UpdateIndex::complete(int64_t poolid, uint64_t epoch, uint
 
   ret = store->cls_obj_complete_add(*bs, optag, poolid, epoch, ent, category, remove_objs, bilog_flags);
 
+  int r = store->data_log->add_entry(bs->bucket, bs->shard_id);
+  if (r < 0) {
+    lderr(store->ctx()) << "ERROR: failed writing data log" << dendl;
+  }
+
   return ret;
 }
 
 int RGWRados::Bucket::UpdateIndex::complete_del(int64_t poolid, uint64_t epoch,
                                                 list<rgw_obj_key> *remove_objs)
 {
+  if (blind) {
+    return 0;
+  }
   RGWRados *store = target->get_store();
   BucketShard *bs;
   int ret = get_bucket_shard(&bs);
@@ -5884,12 +8550,23 @@ int RGWRados::Bucket::UpdateIndex::complete_del(int64_t poolid, uint64_t epoch,
     ldout(store->ctx(), 5) << "failed to get BucketShard object: ret=" << ret << dendl;
     return ret;
   }
-  return store->cls_obj_complete_del(*bs, optag, poolid, epoch, obj, remove_objs, bilog_flags);
+
+  ret = store->cls_obj_complete_del(*bs, optag, poolid, epoch, obj, remove_objs, bilog_flags);
+
+  int r = store->data_log->add_entry(bs->bucket, bs->shard_id);
+  if (r < 0) {
+    lderr(store->ctx()) << "ERROR: failed writing data log" << dendl;
+  }
+
+  return ret;
 }
 
 
 int RGWRados::Bucket::UpdateIndex::cancel()
 {
+  if (blind) {
+    return 0;
+  }
   RGWRados *store = target->get_store();
   BucketShard *bs;
   int ret = get_bucket_shard(&bs);
@@ -6020,6 +8697,7 @@ int RGWRados::SystemObject::Read::GetObjState::get_ioctx(RGWRados *store, rgw_ob
 int RGWRados::get_system_obj(RGWObjectCtx& obj_ctx, RGWRados::SystemObject::Read::GetObjState& read_state,
                              RGWObjVersionTracker *objv_tracker, rgw_obj& obj,
                              bufferlist& bl, off_t ofs, off_t end,
+                             map<string, bufferlist> *attrs,
                              rgw_cache_entry_info *cache_info)
 {
   rgw_bucket bucket;
@@ -6031,7 +8709,7 @@ int RGWRados::get_system_obj(RGWObjectCtx& obj_ctx, RGWRados::SystemObject::Read
 
   get_obj_bucket_and_oid_loc(obj, bucket, oid, key);
 
-  int r = get_obj_state(&obj_ctx, obj, &astate, NULL);
+  int r = get_system_obj_state(&obj_ctx, obj, &astate, NULL);
   if (r < 0)
     return r;
 
@@ -6047,6 +8725,10 @@ int RGWRados::get_system_obj(RGWObjectCtx& obj_ctx, RGWRados::SystemObject::Read
   ldout(cct, 20) << "rados->read ofs=" << ofs << " len=" << len << dendl;
   op.read(ofs, len, &bl, NULL);
 
+  if (attrs) {
+    op.getxattrs(attrs, NULL);
+  }
+
   librados::IoCtx *io_ctx;
   r = read_state.get_ioctx(this, obj, &io_ctx);
   if (r < 0) {
@@ -6078,7 +8760,7 @@ int RGWRados::SystemObject::Read::read(int64_t ofs, int64_t end, bufferlist& bl,
   RGWRados *store = source->get_store();
   rgw_obj& obj = source->get_obj();
 
-  return store->get_system_obj(source->get_ctx(), state, objv_tracker, obj, bl, ofs, end, read_params.cache_info);
+  return store->get_system_obj(source->get_ctx(), state, objv_tracker, obj, bl, ofs, end, read_params.attrs, read_params.cache_info);
 }
 
 int RGWRados::SystemObject::Read::get_attr(const char *name, bufferlist& dest)
@@ -6638,13 +9320,14 @@ int RGWRados::olh_init_modification_impl(RGWObjState& state, rgw_obj& olh_obj, s
 
   bufferlist bl;
   RGWOLHPendingInfo pending_info;
-  pending_info.time = ceph_clock_now(cct);
+  pending_info.time = real_clock::now();
   ::encode(pending_info, bl);
 
 #define OLH_PENDING_TAG_LEN 32
   /* tag will start with current time epoch, this so that entries are sorted by time */
   char buf[32];
-  snprintf(buf, sizeof(buf), "%016llx", (unsigned long long)pending_info.time.sec());
+  utime_t ut(pending_info.time);
+  snprintf(buf, sizeof(buf), "%016llx", (unsigned long long)ut.sec());
   *op_tag = buf;
 
   string s;
@@ -6686,7 +9369,8 @@ int RGWRados::olh_init_modification(RGWObjState& state, rgw_obj& obj, string *op
 int RGWRados::bucket_index_link_olh(RGWObjState& olh_state, rgw_obj& obj_instance, bool delete_marker,
                                     const string& op_tag,
                                     struct rgw_bucket_dir_entry_meta *meta,
-                                    uint64_t olh_epoch)
+                                    uint64_t olh_epoch,
+                                    real_time unmod_since, bool high_precision_time)
 {
   rgw_rados_ref ref;
   rgw_bucket bucket;
@@ -6704,7 +9388,8 @@ int RGWRados::bucket_index_link_olh(RGWObjState& olh_state, rgw_obj& obj_instanc
 
   cls_rgw_obj_key key(obj_instance.get_index_key_name(), obj_instance.get_instance());
   ret = cls_rgw_bucket_link_olh(bs.index_ctx, bs.bucket_obj, key, olh_state.olh_tag, delete_marker, op_tag, meta, olh_epoch,
-                                zone_public_config.log_data);
+                                unmod_since, high_precision_time,
+                                get_zone().log_data);
   if (ret < 0) {
     return ret;
   }
@@ -6735,7 +9420,7 @@ int RGWRados::bucket_index_unlink_instance(rgw_obj& obj_instance, const string&
   }
 
   cls_rgw_obj_key key(obj_instance.get_index_key_name(), obj_instance.get_instance());
-  ret = cls_rgw_bucket_unlink_instance(bs.index_ctx, bs.bucket_obj, key, op_tag, olh_epoch, zone_public_config.log_data);
+  ret = cls_rgw_bucket_unlink_instance(bs.index_ctx, bs.bucket_obj, key, op_tag, olh_epoch, get_zone().log_data);
   if (ret < 0) {
     return ret;
   }
@@ -6985,7 +9670,7 @@ int RGWRados::update_olh(RGWObjectCtx& obj_ctx, RGWObjState *state, RGWBucketInf
 }
 
 int RGWRados::set_olh(RGWObjectCtx& obj_ctx, RGWBucketInfo& bucket_info, rgw_obj& target_obj, bool delete_marker, rgw_bucket_dir_entry_meta *meta,
-                      uint64_t olh_epoch)
+                      uint64_t olh_epoch, real_time unmod_since, bool high_precision_time)
 {
   string op_tag;
 
@@ -7003,7 +9688,7 @@ int RGWRados::set_olh(RGWObjectCtx& obj_ctx, RGWBucketInfo& bucket_info, rgw_obj
       obj_ctx.invalidate(olh_obj);
     }
 
-    ret = get_obj_state(&obj_ctx, olh_obj, &state, NULL, false); /* don't follow olh */
+    ret = get_obj_state(&obj_ctx, olh_obj, &state, false); /* don't follow olh */
     if (ret < 0) {
       return ret;
     }
@@ -7016,7 +9701,7 @@ int RGWRados::set_olh(RGWObjectCtx& obj_ctx, RGWBucketInfo& bucket_info, rgw_obj
       }
       return ret;
     }
-    ret = bucket_index_link_olh(*state, target_obj, delete_marker, op_tag, meta, olh_epoch);
+    ret = bucket_index_link_olh(*state, target_obj, delete_marker, op_tag, meta, olh_epoch, unmod_since, high_precision_time);
     if (ret < 0) {
       ldout(cct, 20) << "bucket_index_link_olh() target_obj=" << target_obj << " delete_marker=" << (int)delete_marker << " returned " << ret << dendl;
       if (ret == -ECANCELED) {
@@ -7062,7 +9747,7 @@ int RGWRados::unlink_obj_instance(RGWObjectCtx& obj_ctx, RGWBucketInfo& bucket_i
       obj_ctx.invalidate(olh_obj);
     }
 
-    ret = get_obj_state(&obj_ctx, olh_obj, &state, NULL, false); /* don't follow olh */
+    ret = get_obj_state(&obj_ctx, olh_obj, &state, false); /* don't follow olh */
     if (ret < 0)
       return ret;
 
@@ -7165,7 +9850,7 @@ void RGWRados::check_pending_olh_entries(map<string, bufferlist>& pending_entrie
 {
   map<string, bufferlist>::iterator iter = pending_entries.begin();
 
-  utime_t now = ceph_clock_now(cct);
+  real_time now = real_clock::now();
 
   while (iter != pending_entries.end()) {
     bufferlist::iterator biter = iter->second.begin();
@@ -7181,7 +9866,7 @@ void RGWRados::check_pending_olh_entries(map<string, bufferlist>& pending_entrie
 
     map<string, bufferlist>::iterator cur_iter = iter;
     ++iter;
-    if (now - pending_info.time >= cct->_conf->rgw_olh_pending_timeout_sec) {
+    if (now - pending_info.time >= make_timespan(cct->_conf->rgw_olh_pending_timeout_sec)) {
       (*rm_pending_entries)[cur_iter->first] = cur_iter->second;
       pending_entries.erase(cur_iter);
     } else {
@@ -7275,7 +9960,7 @@ int RGWRados::follow_olh(RGWObjectCtx& obj_ctx, RGWObjState *state, rgw_obj& olh
   return 0;
 }
 
-int RGWRados::raw_obj_stat(rgw_obj& obj, uint64_t *psize, time_t *pmtime, uint64_t *epoch,
+int RGWRados::raw_obj_stat(rgw_obj& obj, uint64_t *psize, real_time *pmtime, uint64_t *epoch,
                            map<string, bufferlist> *attrs, bufferlist *first_chunk,
                            RGWObjVersionTracker *objv_tracker)
 {
@@ -7288,7 +9973,7 @@ int RGWRados::raw_obj_stat(rgw_obj& obj, uint64_t *psize, time_t *pmtime, uint64
 
   map<string, bufferlist> unfiltered_attrset;
   uint64_t size = 0;
-  time_t mtime = 0;
+  struct timespec mtime_ts;
 
   ObjectReadOperation op;
   if (objv_tracker) {
@@ -7298,7 +9983,7 @@ int RGWRados::raw_obj_stat(rgw_obj& obj, uint64_t *psize, time_t *pmtime, uint64
     op.getxattrs(&unfiltered_attrset, NULL);
   }
   if (psize || pmtime) {
-    op.stat(&size, &mtime, NULL);
+    op.stat2(&size, &mtime_ts, NULL);
   }
   if (first_chunk) {
     op.read(0, cct->_conf->rgw_max_chunk_size, first_chunk, NULL);
@@ -7316,7 +10001,7 @@ int RGWRados::raw_obj_stat(rgw_obj& obj, uint64_t *psize, time_t *pmtime, uint64
   if (psize)
     *psize = size;
   if (pmtime)
-    *pmtime = mtime;
+    *pmtime = ceph::real_clock::from_timespec(mtime_ts);
   if (attrs) {
     filter_attrset(unfiltered_attrset, RGW_ATTR_PREFIX, attrs);
   }
@@ -7324,12 +10009,12 @@ int RGWRados::raw_obj_stat(rgw_obj& obj, uint64_t *psize, time_t *pmtime, uint64
   return 0;
 }
 
-int RGWRados::get_bucket_stats(rgw_bucket& bucket, string *bucket_ver, string *master_ver,
+int RGWRados::get_bucket_stats(rgw_bucket& bucket, int shard_id, string *bucket_ver, string *master_ver,
     map<RGWObjCategory, RGWStorageStats>& stats, string *max_marker)
 {
   map<string, rgw_bucket_dir_header> headers;
   map<int, string> bucket_instance_ids;
-  int r = cls_bucket_head(bucket, headers, &bucket_instance_ids);
+  int r = cls_bucket_head(bucket, shard_id, headers, &bucket_instance_ids);
   if (r < 0)
     return r;
 
@@ -7340,6 +10025,7 @@ int RGWRados::get_bucket_stats(rgw_bucket& bucket, string *bucket_ver, string *m
   BucketIndexShardsManager ver_mgr;
   BucketIndexShardsManager master_ver_mgr;
   BucketIndexShardsManager marker_mgr;
+  string shard_marker;
   char buf[64];
   for(; iter != headers.end(); ++iter, ++viter) {
     accumulate_raw_stats(iter->second, stats);
@@ -7347,11 +10033,17 @@ int RGWRados::get_bucket_stats(rgw_bucket& bucket, string *bucket_ver, string *m
     ver_mgr.add(viter->first, string(buf));
     snprintf(buf, sizeof(buf), "%lu", (unsigned long)iter->second.master_ver);
     master_ver_mgr.add(viter->first, string(buf));
-    marker_mgr.add(viter->first, iter->second.max_marker);
+    if (shard_id >= 0) {
+      *max_marker = iter->second.max_marker;
+    } else {
+      marker_mgr.add(viter->first, iter->second.max_marker);
+    }
   }
   ver_mgr.to_string(bucket_ver);
   master_ver_mgr.to_string(master_ver);
-  marker_mgr.to_string(max_marker);
+  if (shard_id < 0) {
+    marker_mgr.to_string(max_marker);
+  }
   return 0;
 }
 
@@ -7394,7 +10086,7 @@ public:
   }
 };
 
-int RGWRados::get_bucket_stats_async(rgw_bucket& bucket, RGWGetBucketStats_CB *ctx)
+int RGWRados::get_bucket_stats_async(rgw_bucket& bucket, int shard_id, RGWGetBucketStats_CB *ctx)
 {
   RGWBucketInfo binfo;
   RGWObjectCtx obj_ctx(this);
@@ -7406,7 +10098,7 @@ int RGWRados::get_bucket_stats_async(rgw_bucket& bucket, RGWGetBucketStats_CB *c
   int num_aio = 0;
   RGWGetBucketStatsContext *get_ctx = new RGWGetBucketStatsContext(ctx, binfo.num_shards);
   assert(get_ctx);
-  r = cls_bucket_head_async(bucket, get_ctx, &num_aio);
+  r = cls_bucket_head_async(bucket, shard_id, get_ctx, &num_aio);
   get_ctx->put();
   if (r < 0) {
     ctx->put();
@@ -7492,16 +10184,16 @@ void RGWRados::get_bucket_meta_oid(rgw_bucket& bucket, string& oid)
 void RGWRados::get_bucket_instance_obj(rgw_bucket& bucket, rgw_obj& obj)
 {
   if (!bucket.oid.empty()) {
-    obj.init(zone.domain_root, bucket.oid);
+    obj.init(get_zone_params().domain_root, bucket.oid);
   } else {
     string oid;
     get_bucket_meta_oid(bucket, oid);
-    obj.init(zone.domain_root, oid);
+    obj.init(get_zone_params().domain_root, oid);
   }
 }
 
 int RGWRados::get_bucket_instance_info(RGWObjectCtx& obj_ctx, const string& meta_key, RGWBucketInfo& info,
-                                       time_t *pmtime, map<string, bufferlist> *pattrs)
+                                       real_time *pmtime, map<string, bufferlist> *pattrs)
 {
   int pos = meta_key.find(':');
   if (pos < 0) {
@@ -7513,7 +10205,7 @@ int RGWRados::get_bucket_instance_info(RGWObjectCtx& obj_ctx, const string& meta
 }
 
 int RGWRados::get_bucket_instance_info(RGWObjectCtx& obj_ctx, rgw_bucket& bucket, RGWBucketInfo& info,
-                                       time_t *pmtime, map<string, bufferlist> *pattrs)
+                                       real_time *pmtime, map<string, bufferlist> *pattrs)
 {
   string oid;
   if (bucket.oid.empty()) {
@@ -7526,14 +10218,14 @@ int RGWRados::get_bucket_instance_info(RGWObjectCtx& obj_ctx, rgw_bucket& bucket
 }
 
 int RGWRados::get_bucket_instance_from_oid(RGWObjectCtx& obj_ctx, string& oid, RGWBucketInfo& info,
-                                           time_t *pmtime, map<string, bufferlist> *pattrs,
+                                           real_time *pmtime, map<string, bufferlist> *pattrs,
                                            rgw_cache_entry_info *cache_info)
 {
-  ldout(cct, 20) << "reading from " << zone.domain_root << ":" << oid << dendl;
+  ldout(cct, 20) << "reading from " << get_zone_params().domain_root << ":" << oid << dendl;
 
   bufferlist epbl;
 
-  int ret = rgw_get_system_obj(this, obj_ctx, zone.domain_root, oid, epbl, &info.objv_tracker, pmtime, pattrs, cache_info);
+  int ret = rgw_get_system_obj(this, obj_ctx, get_zone_params().domain_root, oid, epbl, &info.objv_tracker, pmtime, pattrs, cache_info);
   if (ret < 0) {
     return ret;
   }
@@ -7554,7 +10246,7 @@ int RGWRados::get_bucket_entrypoint_info(RGWObjectCtx& obj_ctx,
                                          const string& bucket_name,
                                          RGWBucketEntryPoint& entry_point,
                                          RGWObjVersionTracker *objv_tracker,
-                                         time_t *pmtime,
+                                         real_time *pmtime,
                                          map<string, bufferlist> *pattrs,
                                          rgw_cache_entry_info *cache_info)
 {
@@ -7562,7 +10254,7 @@ int RGWRados::get_bucket_entrypoint_info(RGWObjectCtx& obj_ctx,
   string bucket_entry;
 
   rgw_make_bucket_entry_name(tenant_name, bucket_name, bucket_entry);
-  int ret = rgw_get_system_obj(this, obj_ctx, zone.domain_root, bucket_entry, bl, objv_tracker, pmtime, pattrs, cache_info);
+  int ret = rgw_get_system_obj(this, obj_ctx, get_zone_params().domain_root, bucket_entry, bl, objv_tracker, pmtime, pattrs, cache_info);
   if (ret < 0) {
     return ret;
   }
@@ -7582,7 +10274,7 @@ int RGWRados::convert_old_bucket_info(RGWObjectCtx& obj_ctx,
                                       const string& bucket_name)
 {
   RGWBucketEntryPoint entry_point;
-  time_t ep_mtime;
+  real_time ep_mtime;
   RGWObjVersionTracker ot;
   map<string, bufferlist> attrs;
   RGWBucketInfo info;
@@ -7616,7 +10308,7 @@ int RGWRados::convert_old_bucket_info(RGWObjectCtx& obj_ctx,
 
 int RGWRados::get_bucket_info(RGWObjectCtx& obj_ctx,
                               const string& tenant, const string& bucket_name, RGWBucketInfo& info,
-                              time_t *pmtime, map<string, bufferlist> *pattrs)
+                              real_time *pmtime, map<string, bufferlist> *pattrs)
 {
   bucket_info_entry e;
   string bucket_entry;
@@ -7634,7 +10326,7 @@ int RGWRados::get_bucket_info(RGWObjectCtx& obj_ctx,
   bufferlist bl;
 
   RGWBucketEntryPoint entry_point;
-  time_t ep_mtime;
+  real_time ep_mtime;
   RGWObjVersionTracker ot;
   rgw_cache_entry_info entry_cache_info;
   int ret = get_bucket_entrypoint_info(obj_ctx, tenant, bucket_name, entry_point, &ot, &ep_mtime, pattrs, &entry_cache_info);
@@ -7663,8 +10355,6 @@ int RGWRados::get_bucket_info(RGWObjectCtx& obj_ctx,
 
   ldout(cct, 20) << "rgw_get_bucket_info: bucket instance: " << entry_point.bucket << dendl;
 
-  if (pattrs)
-    pattrs->clear();
 
   /* read bucket instance info */
 
@@ -7702,7 +10392,7 @@ int RGWRados::get_bucket_info(RGWObjectCtx& obj_ctx,
 }
 
 int RGWRados::put_bucket_entrypoint_info(const string& tenant_name, const string& bucket_name, RGWBucketEntryPoint& entry_point,
-                                         bool exclusive, RGWObjVersionTracker& objv_tracker, time_t mtime,
+                                         bool exclusive, RGWObjVersionTracker& objv_tracker, real_time mtime,
                                          map<string, bufferlist> *pattrs)
 {
   bufferlist epbl;
@@ -7713,7 +10403,7 @@ int RGWRados::put_bucket_entrypoint_info(const string& tenant_name, const string
 }
 
 int RGWRados::put_bucket_instance_info(RGWBucketInfo& info, bool exclusive,
-                              time_t mtime, map<string, bufferlist> *pattrs)
+                              real_time mtime, map<string, bufferlist> *pattrs)
 {
   info.has_instance_obj = true;
   bufferlist bl;
@@ -7722,10 +10412,22 @@ int RGWRados::put_bucket_instance_info(RGWBucketInfo& info, bool exclusive,
 
   string key;
   get_bucket_instance_entry(info.bucket, key); /* when we go through meta api, we don't use oid directly */
-  return rgw_bucket_instance_store_info(this, key, bl, exclusive, pattrs, &info.objv_tracker, mtime);
+  int ret = rgw_bucket_instance_store_info(this, key, bl, exclusive, pattrs, &info.objv_tracker, mtime);
+  if (ret == -EEXIST) {
+    /* well, if it's exclusive we shouldn't overwrite it, because we might race with another
+     * bucket operation on this specific bucket (e.g., being synced from the master), but
+     * since bucket instace meta object is unique for this specific bucket instace, we don't
+     * need to return an error.
+     * A scenario where we'd get -EEXIST here, is in a multi-zone config, we're not on the
+     * master, creating a bucket, sending bucket creation to the master, we create the bucket
+     * locally, while in the sync thread we sync the new bucket.
+     */
+    ret = 0;
+  }
+  return ret;
 }
 
-int RGWRados::put_linked_bucket_info(RGWBucketInfo& info, bool exclusive, time_t mtime, obj_version *pep_objv,
+int RGWRados::put_linked_bucket_info(RGWBucketInfo& info, bool exclusive, real_time mtime, obj_version *pep_objv,
                                      map<string, bufferlist> *pattrs, bool create_entry_point)
 {
   bufferlist bl;
@@ -7841,7 +10543,7 @@ int RGWRados::update_containers_stats(map<string, RGWBucketEnt>& m)
     rgw_bucket& bucket = ent.bucket;
 
     map<string, rgw_bucket_dir_header> headers;
-    int r = cls_bucket_head(bucket, headers);
+    int r = cls_bucket_head(bucket, RGW_NO_SHARD, headers);
     if (r < 0)
       return r;
 
@@ -8006,7 +10708,6 @@ int RGWRados::list_bi_log_entries(rgw_bucket& bucket, int shard_id, string& mark
   if (r < 0)
     return r;
 
-  vector<string> shard_ids_str;
   map<int, list<rgw_bi_log_entry>::iterator> vcurrents;
   map<int, list<rgw_bi_log_entry>::iterator> vends;
   if (truncated) {
@@ -8225,7 +10926,7 @@ int RGWRados::cls_obj_prepare_op(BucketShard& bs, RGWModifyOp op, string& tag,
 {
   ObjectWriteOperation o;
   cls_rgw_obj_key key(obj.get_index_key_name(), obj.get_instance());
-  cls_rgw_bucket_prepare_op(o, op, tag, key, obj.get_loc(), zone_public_config.log_data, bilog_flags);
+  cls_rgw_bucket_prepare_op(o, op, tag, key, obj.get_loc(), get_zone().log_data, bilog_flags);
   int r = bs.index_ctx.operate(bs.bucket_obj, &o);
   return r;
 }
@@ -8251,7 +10952,7 @@ int RGWRados::cls_obj_complete_op(BucketShard& bs, RGWModifyOp op, string& tag,
   rgw_bucket_dir_entry_meta dir_meta;
   dir_meta.size = ent.size;
   dir_meta.accounted_size = ent.size;
-  dir_meta.mtime = utime_t(ent.mtime, 0);
+  dir_meta.mtime = ent.mtime;
   dir_meta.etag = ent.etag;
   dir_meta.owner = ent.owner.to_str();
   dir_meta.owner_display_name = ent.owner_display_name;
@@ -8263,7 +10964,7 @@ int RGWRados::cls_obj_complete_op(BucketShard& bs, RGWModifyOp op, string& tag,
   ver.epoch = epoch;
   cls_rgw_obj_key key(ent.key.name, ent.key.instance);
   cls_rgw_bucket_complete_op(o, op, tag, ver, key, dir_meta, pro,
-                             zone_public_config.log_data, bilog_flags);
+                             get_zone().log_data, bilog_flags);
 
   AioCompletion *c = librados::Rados::aio_create_completion(NULL, NULL, NULL);
   int ret = bs.index_ctx.aio_operate(bs.bucket_obj, c, &o);
@@ -8308,7 +11009,7 @@ int RGWRados::cls_obj_set_bucket_tag_timeout(rgw_bucket& bucket, uint64_t timeou
   return CLSRGWIssueSetTagTimeout(index_ctx, bucket_objs, cct->_conf->rgw_bucket_index_max_aio, timeout)();
 }
 
-int RGWRados::cls_bucket_list(rgw_bucket& bucket, rgw_obj_key& start, const string& prefix,
+int RGWRados::cls_bucket_list(rgw_bucket& bucket, int shard_id, rgw_obj_key& start, const string& prefix,
 		              uint32_t num_entries, bool list_versions, map<string, RGWObjEnt>& m,
 			      bool *is_truncated, rgw_obj_key *last_entry,
 			      bool (*force_check_filter)(const string&  name))
@@ -8320,7 +11021,7 @@ int RGWRados::cls_bucket_list(rgw_bucket& bucket, rgw_obj_key& start, const stri
   // value - list result for the corresponding oid (shard), it is filled by the AIO callback
   map<int, string> oids;
   map<int, struct rgw_cls_list_ret> list_results;
-  int r = open_bucket_index(bucket, index_ctx, oids);
+  int r = open_bucket_index(bucket, index_ctx, oids, shard_id);
   if (r < 0)
     return r;
 
@@ -8356,6 +11057,7 @@ int RGWRados::cls_bucket_list(rgw_bucket& bucket, rgw_obj_key& start, const stri
   map<string, bufferlist> updates;
   uint32_t count = 0;
   while (count < num_entries && !candidates.empty()) {
+    r = 0;
     // Select the next one
     int pos = candidates.begin()->second;
     const string& name = vcurrents[pos]->first;
@@ -8427,7 +11129,7 @@ int RGWRados::cls_obj_usage_log_add(const string& oid, rgw_usage_log_info& info)
 {
   librados::IoCtx io_ctx;
 
-  const char *usage_log_pool = zone.usage_log_pool.name.c_str();
+  const char *usage_log_pool = get_zone_params().usage_log_pool.name.c_str();
   librados::Rados *rad = get_rados_handle();
   int r = rad->ioctx_create(usage_log_pool, io_ctx);
   if (r == -ENOENT) {
@@ -8456,7 +11158,7 @@ int RGWRados::cls_obj_usage_log_read(string& oid, string& user, uint64_t start_e
 
   *is_truncated = false;
 
-  const char *usage_log_pool = zone.usage_log_pool.name.c_str();
+  const char *usage_log_pool = get_zone_params().usage_log_pool.name.c_str();
   librados::Rados *rad = get_rados_handle();
   int r = rad->ioctx_create(usage_log_pool, io_ctx);
   if (r < 0)
@@ -8472,7 +11174,7 @@ int RGWRados::cls_obj_usage_log_trim(string& oid, string& user, uint64_t start_e
 {
   librados::IoCtx io_ctx;
 
-  const char *usage_log_pool = zone.usage_log_pool.name.c_str();
+  const char *usage_log_pool = get_zone_params().usage_log_pool.name.c_str();
   librados::Rados *rad = get_rados_handle();
   int r = rad->ioctx_create(usage_log_pool, io_ctx);
   if (r < 0)
@@ -8564,7 +11266,7 @@ int RGWRados::check_disk_state(librados::IoCtx io_ctx,
   ACLOwner owner;
 
   object.size = astate->size;
-  object.mtime = utime_t(astate->mtime, 0);
+  object.mtime = astate->mtime;
 
   map<string, bufferlist>::iterator iter = astate->attrset.find(RGW_ATTR_ETAG);
   if (iter != astate->attrset.end()) {
@@ -8607,7 +11309,7 @@ int RGWRados::check_disk_state(librados::IoCtx io_ctx,
   list_state.ver.pool = io_ctx.get_id();
   list_state.ver.epoch = astate->epoch;
   list_state.meta.size = object.size;
-  list_state.meta.mtime.set_from_double(double(object.mtime));
+  list_state.meta.mtime = object.mtime;
   list_state.meta.category = main_category;
   list_state.meta.etag = etag;
   list_state.meta.content_type = content_type;
@@ -8621,12 +11323,12 @@ int RGWRados::check_disk_state(librados::IoCtx io_ctx,
   return 0;
 }
 
-int RGWRados::cls_bucket_head(rgw_bucket& bucket, map<string, struct rgw_bucket_dir_header>& headers, map<int, string> *bucket_instance_ids)
+int RGWRados::cls_bucket_head(rgw_bucket& bucket, int shard_id, map<string, struct rgw_bucket_dir_header>& headers, map<int, string> *bucket_instance_ids)
 {
   librados::IoCtx index_ctx;
   map<int, string> oids;
   map<int, struct rgw_cls_list_ret> list_results;
-  int r = open_bucket_index(bucket, index_ctx, oids, list_results, -1, bucket_instance_ids);
+  int r = open_bucket_index(bucket, index_ctx, oids, list_results, shard_id, bucket_instance_ids);
   if (r < 0)
     return r;
 
@@ -8641,11 +11343,11 @@ int RGWRados::cls_bucket_head(rgw_bucket& bucket, map<string, struct rgw_bucket_
   return 0;
 }
 
-int RGWRados::cls_bucket_head_async(rgw_bucket& bucket, RGWGetDirHeader_CB *ctx, int *num_aio)
+int RGWRados::cls_bucket_head_async(rgw_bucket& bucket, int shard_id, RGWGetDirHeader_CB *ctx, int *num_aio)
 {
   librados::IoCtx index_ctx;
   map<int, string> bucket_objs;
-  int r = open_bucket_index(bucket, index_ctx, bucket_objs);
+  int r = open_bucket_index(bucket, index_ctx, bucket_objs, shard_id);
   if (r < 0)
     return r;
 
@@ -8666,7 +11368,7 @@ int RGWRados::cls_user_get_header(const string& user_id, cls_user_header *header
 {
   string buckets_obj_id;
   rgw_get_buckets_obj(user_id, buckets_obj_id);
-  rgw_obj obj(zone.user_uid_pool, buckets_obj_id);
+  rgw_obj obj(get_zone_params().user_uid_pool, buckets_obj_id);
 
   rgw_rados_ref ref;
   rgw_bucket bucket;
@@ -8692,7 +11394,7 @@ int RGWRados::cls_user_get_header_async(const string& user_id, RGWGetUserHeader_
 {
   string buckets_obj_id;
   rgw_get_buckets_obj(user_id, buckets_obj_id);
-  rgw_obj obj(zone.user_uid_pool, buckets_obj_id);
+  rgw_obj obj(get_zone_params().user_uid_pool, buckets_obj_id);
 
   rgw_rados_ref ref;
   rgw_bucket bucket;
@@ -8711,7 +11413,7 @@ int RGWRados::cls_user_get_header_async(const string& user_id, RGWGetUserHeader_
 int RGWRados::cls_user_sync_bucket_stats(rgw_obj& user_obj, rgw_bucket& bucket)
 {
   map<string, struct rgw_bucket_dir_header> headers;
-  int r = cls_bucket_head(bucket, headers);
+  int r = cls_bucket_head(bucket, RGW_NO_SHARD, headers);
   if (r < 0) {
     ldout(cct, 20) << "cls_bucket_header() returned " << r << dendl;
     return r;
@@ -8757,7 +11459,7 @@ int RGWRados::update_user_bucket_stats(const string& user_id, rgw_bucket& bucket
 
   string buckets_obj_id;
   rgw_get_buckets_obj(user_id, buckets_obj_id);
-  rgw_obj obj(zone.user_uid_pool, buckets_obj_id);
+  rgw_obj obj(get_zone_params().user_uid_pool, buckets_obj_id);
 
   int r = cls_user_update_buckets(obj, entries, false);
   if (r < 0) {
@@ -8819,7 +11521,7 @@ int RGWRados::complete_sync_user_stats(const rgw_user& user_id)
 {
   string buckets_obj_id;
   rgw_get_buckets_obj(user_id, buckets_obj_id);
-  rgw_obj obj(zone.user_uid_pool, buckets_obj_id);
+  rgw_obj obj(get_zone_params().user_uid_pool, buckets_obj_id);
   return cls_user_complete_stats_sync(obj);
 }
 
@@ -9112,7 +11814,7 @@ void RGWStateLog::dump_entry(const cls_statelog_entry& entry, Formatter *f)
   f->dump_string("client_id", entry.client_id);
   f->dump_string("op_id", entry.op_id);
   f->dump_string("object", entry.object);
-  entry.timestamp.gmtime(f->dump_stream("timestamp"));
+  entry.timestamp.gmtime_nsec(f->dump_stream("timestamp"));
   if (!dump_entry_internal(entry, f)) {
     f->dump_int("state", entry.state);
   }
@@ -9193,17 +11895,17 @@ RGWOpStateSingleOp::RGWOpStateSingleOp(RGWRados *store, const string& cid, const
 }
 
 int RGWOpStateSingleOp::set_state(RGWOpState::OpState state) {
-  last_update = ceph_clock_now(cct);
+  last_update = real_clock::now();
   cur_state = state;
   return os.set_state(client_id, op_id, object, state);
 }
 
 int RGWOpStateSingleOp::renew_state() {
-  utime_t now = ceph_clock_now(cct);
+  real_time now = real_clock::now();
 
   int rate_limit_sec = cct->_conf->rgw_opstate_ratelimit_sec;
 
-  if (rate_limit_sec && now - last_update < rate_limit_sec) {
+  if (rate_limit_sec && now - last_update < make_timespan(rate_limit_sec)) {
     return 0;
   }
 
@@ -9223,7 +11925,7 @@ uint64_t RGWRados::next_bucket_id()
   return ++max_bucket_id;
 }
 
-RGWRados *RGWStoreManager::init_storage_provider(CephContext *cct, bool use_gc_thread, bool quota_threads)
+RGWRados *RGWStoreManager::init_storage_provider(CephContext *cct, bool use_gc_thread, bool quota_threads, bool run_sync_thread)
 {
   int use_cache = cct->_conf->rgw_cache_enabled;
   RGWRados *store = NULL;
@@ -9233,7 +11935,7 @@ RGWRados *RGWStoreManager::init_storage_provider(CephContext *cct, bool use_gc_t
     store = new RGWCache<RGWRados>; 
   }
 
-  if (store->initialize(cct, use_gc_thread, quota_threads) < 0) {
+  if (store->initialize(cct, use_gc_thread, quota_threads, run_sync_thread) < 0) {
     delete store;
     return NULL;
   }
diff --git a/src/rgw/rgw_rados.h b/src/rgw/rgw_rados.h
index cb3c880..b95c838 100644
--- a/src/rgw/rgw_rados.h
+++ b/src/rgw/rgw_rados.h
@@ -8,6 +8,7 @@
 #include "include/Context.h"
 #include "common/RefCountedObj.h"
 #include "common/RWLock.h"
+#include "common/ceph_time.h"
 #include "rgw_common.h"
 #include "cls/rgw/cls_rgw_types.h"
 #include "cls/version/cls_version_types.h"
@@ -16,13 +17,19 @@
 #include "cls/timeindex/cls_timeindex_types.h"
 #include "rgw_log.h"
 #include "rgw_metadata.h"
-#include "rgw_rest_conn.h"
+#include "rgw_meta_sync_status.h"
+#include "rgw_period_puller.h"
 
 class RGWWatcher;
 class SafeTimer;
 class ACLOwner;
 class RGWGC;
+class RGWMetaNotifier;
+class RGWDataNotifier;
 class RGWObjectExpirer;
+class RGWMetaSyncProcessorThread;
+class RGWDataSyncProcessorThread;
+class RGWRESTConn;
 
 /* flags for put_obj_meta() */
 #define PUT_OBJ_CREATE      0x01
@@ -34,6 +41,8 @@ class RGWObjectExpirer;
 
 #define RGW_BUCKET_INSTANCE_MD_PREFIX ".bucket.meta."
 
+#define RGW_NO_SHARD -1
+
 static inline void prepend_bucket_marker(rgw_bucket& bucket, const string& orig_oid, string& oid)
 {
   if (bucket.marker.empty() || orig_oid.empty()) {
@@ -51,7 +60,7 @@ static inline void get_obj_bucket_and_oid_loc(const rgw_obj& obj, rgw_bucket& bu
   prepend_bucket_marker(bucket, obj.get_object(), oid);
   const string& loc = obj.get_loc();
   if (!loc.empty()) {
-    prepend_bucket_marker(bucket, obj.get_loc(), locator); // XXX get_loc twice
+    prepend_bucket_marker(bucket, loc, locator);
   } else {
     locator.clear();
   }
@@ -84,7 +93,7 @@ struct RGWOLHInfo {
 WRITE_CLASS_ENCODER(RGWOLHInfo)
 
 struct RGWOLHPendingInfo {
-  utime_t time;
+  ceph::real_time time;
 
   RGWOLHPendingInfo() {}
 
@@ -105,9 +114,9 @@ struct RGWOLHPendingInfo {
 WRITE_CLASS_ENCODER(RGWOLHPendingInfo)
 
 struct RGWUsageBatch {
-  map<utime_t, rgw_usage_log_entry> m;
+  map<ceph::real_time, rgw_usage_log_entry> m;
 
-  void insert(utime_t& t, rgw_usage_log_entry& entry, bool *account) {
+  void insert(ceph::real_time& t, rgw_usage_log_entry& entry, bool *account) {
     bool exists = m.find(t) != m.end();
     *account = !exists;
     m[t].aggregate(entry);
@@ -571,7 +580,7 @@ struct RGWUploadPartInfo {
   uint32_t num;
   uint64_t size;
   string etag;
-  utime_t modified;
+  ceph::real_time modified;
   RGWObjManifest manifest;
 
   RGWUploadPartInfo() : num(0), size(0) {}
@@ -606,7 +615,7 @@ struct RGWObjState {
   bool has_attrs;
   bool exists;
   uint64_t size;
-  time_t mtime;
+  ceph::real_time mtime;
   uint64_t epoch;
   bufferlist obj_tag;
   string write_tag;
@@ -620,6 +629,8 @@ struct RGWObjState {
   bool keep_tail;
   bool is_olh;
   bufferlist olh_tag;
+  uint64_t pg_ver;
+  uint32_t zone_short_id;
 
   /* important! don't forget to update copy constructor */
 
@@ -627,8 +638,9 @@ struct RGWObjState {
 
   map<string, bufferlist> attrset;
   RGWObjState() : is_atomic(false), has_attrs(0), exists(false),
-                  size(0), mtime(0), epoch(0), fake_tag(false), has_manifest(false),
-                  has_data(false), prefetch_data(false), keep_tail(false), is_olh(false) {}
+                  size(0), epoch(0), fake_tag(false), has_manifest(false),
+                  has_data(false), prefetch_data(false), keep_tail(false), is_olh(false),
+                  pg_ver(0), zone_short_id(0) {}
   RGWObjState(const RGWObjState& rhs) : obj (rhs.obj) {
     is_atomic = rhs.is_atomic;
     has_attrs = rhs.has_attrs;
@@ -654,6 +666,7 @@ struct RGWObjState {
     keep_tail = rhs.keep_tail;
     is_olh = rhs.is_olh;
     objv_tracker = rhs.objv_tracker;
+    pg_ver = rhs.pg_ver;
   }
 
   bool get_attr(string name, bufferlist& dest) {
@@ -664,19 +677,6 @@ struct RGWObjState {
     }
     return false;
   }
-
-  void clear() {
-    has_attrs = false;
-    exists = false;
-    fake_tag = false;
-    epoch = 0;
-    size = 0;
-    mtime = 0;
-    obj_tag.clear();
-    shadow_obj.clear();
-    attrset.clear();
-    data.clear();
-  }
 };
 
 struct RGWPoolIterCtx {
@@ -691,29 +691,150 @@ struct RGWListRawObjsCtx {
   RGWListRawObjsCtx() : initialized(false) {}
 };
 
-struct RGWRegion;
+struct RGWDefaultSystemMetaObjInfo {
+  string default_id;
+
+  void encode(bufferlist& bl) const {
+    ENCODE_START(1, 1, bl);
+    ::encode(default_id, bl);
+    ENCODE_FINISH(bl);
+  }
+
+  void decode(bufferlist::iterator& bl) {
+    DECODE_START(1, bl);
+    ::decode(default_id, bl);
+    DECODE_FINISH(bl);
+  }
+
+  void dump(Formatter *f) const;
+  void decode_json(JSONObj *obj);
+};
+WRITE_CLASS_ENCODER(RGWDefaultSystemMetaObjInfo)
+
+struct RGWNameToId {
+  string obj_id;
+
+  void encode(bufferlist& bl) const {
+    ENCODE_START(1, 1, bl);
+    ::encode(obj_id, bl);
+    ENCODE_FINISH(bl);
+  }
+
+  void decode(bufferlist::iterator& bl) {
+    DECODE_START(1, bl);
+    ::decode(obj_id, bl);
+    DECODE_FINISH(bl);
+  }
+
+  void dump(Formatter *f) const;
+  void decode_json(JSONObj *obj);
+};
+WRITE_CLASS_ENCODER(RGWNameToId)
+
+class RGWSystemMetaObj {
+protected:
+  string id;
+  string name;
+
+  CephContext *cct;
+  RGWRados *store;
+
+  int store_name(bool exclusive);
+  int store_info(bool exclusive);
+  int read_info(const string& obj_id, bool old_format = false);
+  int read_id(const string& obj_name, string& obj_id);
+  int read_default(RGWDefaultSystemMetaObjInfo& default_info,
+		   const string& oid);
+  /* read and use default id */
+  int use_default(bool old_format = false);
+
+public:
+  RGWSystemMetaObj() {}
+  RGWSystemMetaObj(const string& _name): name(_name)  {}
+  RGWSystemMetaObj(const string& _id, const string& _name) : id(_id), name(_name) {}
+  RGWSystemMetaObj(CephContext *_cct, RGWRados *_store): cct(_cct), store(_store){}
+  RGWSystemMetaObj(const string& _name, CephContext *_cct, RGWRados *_store): name(_name), cct(_cct), store(_store){}
+  const string& get_name() const { return name; }
+  const string& get_id() const { return id; }
+
+  void set_name(const string& _name) { name = _name;}
+  void set_id(const string& _id) { id = _id;}
+  void clear_id() { id.clear(); }
 
+  virtual ~RGWSystemMetaObj() {}
+
+  virtual void encode(bufferlist& bl) const {
+    ENCODE_START(1, 1, bl);
+    ::encode(id, bl);
+    ::encode(name, bl);
+    ENCODE_FINISH(bl);
+  }
+
+  virtual void decode(bufferlist::iterator& bl) {
+    DECODE_START(1, bl);
+    ::decode(id, bl);
+    ::decode(name, bl);
+    DECODE_FINISH(bl);
+  }
+
+  void reinit_instance(CephContext *_cct, RGWRados *_store) {
+    cct = _cct;
+    store = _store;
+  }
+  int init(CephContext *_cct, RGWRados *_store, bool setup_obj = true, bool old_format = false);
+  virtual int read_default_id(string& default_id, bool old_format = false);
+  virtual int set_as_default();
+  int delete_default();
+  virtual int create(bool exclusive = true);
+  int delete_obj(bool old_format = false);
+  int rename(const string& new_name);
+  int update() { return store_info(false);}
+  int update_name() { return store_name(false);}
+  int read();
+  int write(bool exclusive);
+
+  virtual const string& get_pool_name(CephContext *cct) = 0;
+  virtual const string get_default_oid(bool old_format = false) = 0;
+  virtual const string& get_names_oid_prefix() = 0;
+  virtual const string& get_info_oid_prefix(bool old_format = false) = 0;
+  virtual const string& get_predefined_name(CephContext *cct) = 0;
+
+  void dump(Formatter *f) const;
+  void decode_json(JSONObj *obj);
+};
+WRITE_CLASS_ENCODER(RGWSystemMetaObj)
+
+struct RGWZoneGroup;
 
 struct RGWZonePlacementInfo {
   string index_pool;
   string data_pool;
   string data_extra_pool; /* if not set we should use data_pool */
+  RGWBucketIndexType index_type;
+
+  RGWZonePlacementInfo() : index_type(RGWBIType_Normal) {}
 
   void encode(bufferlist& bl) const {
-    ENCODE_START(4, 1, bl);
+    ENCODE_START(5, 1, bl);
     ::encode(index_pool, bl);
     ::encode(data_pool, bl);
     ::encode(data_extra_pool, bl);
+    ::encode((uint32_t)index_type, bl);
     ENCODE_FINISH(bl);
   }
 
   void decode(bufferlist::iterator& bl) {
-    DECODE_START(4, bl);
+    DECODE_START(5, bl);
     ::decode(index_pool, bl);
     ::decode(data_pool, bl);
     if (struct_v >= 4) {
       ::decode(data_extra_pool, bl);
     }
+    if (struct_v >= 5) {
+      uint32_t it;
+      ::decode(it, bl);
+      index_type = (RGWBucketIndexType)it;
+    }
     DECODE_FINISH(bl);
   }
   const string& get_data_extra_pool() {
@@ -727,8 +848,9 @@ struct RGWZonePlacementInfo {
 };
 WRITE_CLASS_ENCODER(RGWZonePlacementInfo)
 
-struct RGWZoneParams {
+struct RGWZoneParams : RGWSystemMetaObj {
   rgw_bucket domain_root;
+  rgw_bucket metadata_heap;
   rgw_bucket control_pool;
   rgw_bucket gc_pool;
   rgw_bucket log_pool;
@@ -740,23 +862,35 @@ struct RGWZoneParams {
   rgw_bucket user_swift_pool;
   rgw_bucket user_uid_pool;
 
-  string name;
-  bool is_master;
-
   RGWAccessKey system_key;
 
   map<string, RGWZonePlacementInfo> placement_pools;
 
-  RGWZoneParams() : is_master(false) {}
+  string realm_id;
+
+  RGWZoneParams() : RGWSystemMetaObj() {}
+  RGWZoneParams(const string& name) : RGWSystemMetaObj(name){}
+  RGWZoneParams(const string& id, const string& name) : RGWSystemMetaObj(id, name) {}
+  RGWZoneParams(const string& id, const string& name, const string& _realm_id)
+    : RGWSystemMetaObj(id, name), realm_id(_realm_id) {}
 
-  static int get_pool_name(CephContext *cct, string *pool_name);
-  void init_name(CephContext *cct, RGWRegion& region);
-  int init(CephContext *cct, RGWRados *store, RGWRegion& region);
-  void init_default(RGWRados *store);
-  int store_info(CephContext *cct, RGWRados *store, RGWRegion& region);
+  const string& get_pool_name(CephContext *cct);
+  const string get_default_oid(bool old_format = false);
+  const string& get_names_oid_prefix();
+  const string& get_info_oid_prefix(bool old_format = false);
+  const string& get_predefined_name(CephContext *cct);
 
+  int init(CephContext *_cct, RGWRados *_store, bool setup_obj = true,
+	   bool old_format = false);
+  using RGWSystemMetaObj::init;
+  int read_default_id(string& default_id, bool old_format = false);
+  int set_as_default();
+  int create_default(bool old_format = false);
+  int create(bool exclusive = true);
+  int fix_pool_names();
+  
   void encode(bufferlist& bl) const {
-    ENCODE_START(4, 1, bl);
+    ENCODE_START(6, 1, bl);
     ::encode(domain_root, bl);
     ::encode(control_pool, bl);
     ::encode(gc_pool, bl);
@@ -767,14 +901,16 @@ struct RGWZoneParams {
     ::encode(user_email_pool, bl);
     ::encode(user_swift_pool, bl);
     ::encode(user_uid_pool, bl);
-    ::encode(name, bl);
+    RGWSystemMetaObj::encode(bl);
     ::encode(system_key, bl);
     ::encode(placement_pools, bl);
+    ::encode(metadata_heap, bl);
+    ::encode(realm_id, bl);
     ENCODE_FINISH(bl);
   }
 
   void decode(bufferlist::iterator& bl) {
-     DECODE_START(4, bl);
+    DECODE_START(6, bl);
     ::decode(domain_root, bl);
     ::decode(control_pool, bl);
     ::decode(gc_pool, bl);
@@ -785,12 +921,21 @@ struct RGWZoneParams {
     ::decode(user_email_pool, bl);
     ::decode(user_swift_pool, bl);
     ::decode(user_uid_pool, bl);
-    if (struct_v >= 2)
+    if (struct_v >= 6) {
+      RGWSystemMetaObj::decode(bl);
+    } else if (struct_v >= 2) {
       ::decode(name, bl);
+      id = name;
+    }
     if (struct_v >= 3)
       ::decode(system_key, bl);
     if (struct_v >= 4)
       ::decode(placement_pools, bl);
+    if (struct_v >= 5)
+      ::decode(metadata_heap, bl);
+    if (struct_v >= 6) {
+      ::decode(realm_id, bl);
+    }
     DECODE_FINISH(bl);
   }
   void dump(Formatter *f) const;
@@ -800,10 +945,12 @@ struct RGWZoneParams {
 WRITE_CLASS_ENCODER(RGWZoneParams)
 
 struct RGWZone {
+  string id;
   string name;
   list<string> endpoints;
   bool log_meta;
   bool log_data;
+  bool read_only;
 
 /**
  * Represents the number of shards for the bucket index object, a value of zero
@@ -814,21 +961,26 @@ struct RGWZone {
  */
   uint32_t bucket_index_max_shards;
 
-  RGWZone() : log_meta(false), log_data(false), bucket_index_max_shards(0) {}
+  RGWZone() : log_meta(false), log_data(false), read_only(false), bucket_index_max_shards(0) {}
 
   void encode(bufferlist& bl) const {
-    ENCODE_START(3, 1, bl);
+    ENCODE_START(4, 1, bl);
     ::encode(name, bl);
     ::encode(endpoints, bl);
     ::encode(log_meta, bl);
     ::encode(log_data, bl);
     ::encode(bucket_index_max_shards, bl);
+    ::encode(id, bl);
+    ::encode(read_only, bl);
     ENCODE_FINISH(bl);
   }
 
   void decode(bufferlist::iterator& bl) {
-    DECODE_START(2, bl);
+    DECODE_START(4, bl);
     ::decode(name, bl);
+    if (struct_v < 4) {
+      id = name;
+    }
     ::decode(endpoints, bl);
     if (struct_v >= 2) {
       ::decode(log_meta, bl);
@@ -837,35 +989,41 @@ struct RGWZone {
     if (struct_v >= 3) {
       ::decode(bucket_index_max_shards, bl);
     }
+    if (struct_v >= 4) {
+      ::decode(id, bl);
+      ::decode(read_only, bl);
+    }
     DECODE_FINISH(bl);
   }
   void dump(Formatter *f) const;
   void decode_json(JSONObj *obj);
   static void generate_test_instances(list<RGWZone*>& o);
+
+  bool is_read_only() { return read_only; }
 };
 WRITE_CLASS_ENCODER(RGWZone)
 
-struct RGWDefaultRegionInfo {
-  string default_region;
+struct RGWDefaultZoneGroupInfo {
+  string default_zonegroup;
 
   void encode(bufferlist& bl) const {
     ENCODE_START(1, 1, bl);
-    ::encode(default_region, bl);
+    ::encode(default_zonegroup, bl);
     ENCODE_FINISH(bl);
   }
 
   void decode(bufferlist::iterator& bl) {
     DECODE_START(1, bl);
-    ::decode(default_region, bl);
+    ::decode(default_zonegroup, bl);
     DECODE_FINISH(bl);
   }
   void dump(Formatter *f) const;
   void decode_json(JSONObj *obj);
   //todo: implement ceph-dencoder
 };
-WRITE_CLASS_ENCODER(RGWDefaultRegionInfo)
+WRITE_CLASS_ENCODER(RGWDefaultZoneGroupInfo)
 
-struct RGWRegionPlacementTarget {
+struct RGWZoneGroupPlacementTarget {
   string name;
   list<string> tags;
 
@@ -900,11 +1058,10 @@ struct RGWRegionPlacementTarget {
   void dump(Formatter *f) const;
   void decode_json(JSONObj *obj);
 };
-WRITE_CLASS_ENCODER(RGWRegionPlacementTarget)
+WRITE_CLASS_ENCODER(RGWZoneGroupPlacementTarget)
 
 
-struct RGWRegion {
-  string name;
+struct RGWZoneGroup : public RGWSystemMetaObj {
   string api_name;
   list<string> endpoints;
   bool is_master;
@@ -912,7 +1069,7 @@ struct RGWRegion {
   string master_zone;
   map<string, RGWZone> zones;
 
-  map<string, RGWRegionPlacementTarget> placement_targets;
+  map<string, RGWZoneGroupPlacementTarget> placement_targets;
   string default_placement;
 
   list<string> hostnames;
@@ -934,13 +1091,25 @@ struct RGWRegion {
   map<string, list<string> > api_hostname_map;
   map<string, list<string> > api_endpoints_map;
 
-  CephContext *cct;
-  RGWRados *store;
+  string realm_id;
 
-  RGWRegion() : is_master(false), cct(NULL), store(NULL) {}
+  RGWZoneGroup(): is_master(false){}
+  RGWZoneGroup(const std::string &id, const std::string &name):RGWSystemMetaObj(id, name) {}
+  RGWZoneGroup(const std::string &_name):RGWSystemMetaObj(_name) {}
+  RGWZoneGroup(const std::string &_name, bool _is_master, CephContext *cct, RGWRados* store,
+	       const string& _realm_id, const list<string>& _endpoints)
+    : RGWSystemMetaObj(_name, cct , store), endpoints(_endpoints), is_master(_is_master),
+      realm_id(_realm_id) {}
+
+  bool is_master_zonegroup() const { return is_master;}
+  void update_master(bool _is_master) {
+    is_master = _is_master;
+    post_process_params();
+  }
+  void post_process_params();
 
   void encode(bufferlist& bl) const {
-    ENCODE_START(3, 1, bl);
+    ENCODE_START(4, 1, bl);
     ::encode(name, bl);
     ::encode(api_name, bl);
     ::encode(is_master, bl);
@@ -951,11 +1120,13 @@ struct RGWRegion {
     ::encode(default_placement, bl);
     ::encode(hostnames, bl);
     ::encode(hostnames_s3website, bl);
+    RGWSystemMetaObj::encode(bl);
+    ::encode(realm_id, bl);
     ENCODE_FINISH(bl);
   }
 
   void decode(bufferlist::iterator& bl) {
-    DECODE_START(3, bl);
+    DECODE_START(4, bl);
     ::decode(name, bl);
     ::decode(api_name, bl);
     ::decode(is_master, bl);
@@ -970,57 +1141,131 @@ struct RGWRegion {
     if (struct_v >= 3) {
       ::decode(hostnames_s3website, bl);
     }
+    if (struct_v >= 4) {
+      RGWSystemMetaObj::decode(bl);
+      ::decode(realm_id, bl);
+    } else {
+      id = name;
+    }
     DECODE_FINISH(bl);
   }
 
-  int init(CephContext *_cct, RGWRados *_store, bool setup_region = true);
-  int create_default();
-  int store_info(bool exclusive);
-  int read_info(const string& region_name);
-  int read_default(RGWDefaultRegionInfo& default_region);
+  int read_default_id(string& default_id, bool old_format = false);
   int set_as_default();
-  int equals(const string& other_region);
+  int create_default(bool old_format = false);
+  int equals(const string& other_zonegroup) const;
+  int add_zone(const RGWZoneParams& zone_params, bool *is_master, bool *read_only, const list<string>& endpoints);
+  int remove_zone(const RGWZoneParams& zone_params);
+  int rename_zone(const RGWZoneParams& zone_params);
+  const string& get_pool_name(CephContext *cct);
+  const string get_default_oid(bool old_region_format = false);
+  const string& get_info_oid_prefix(bool old_region_format = false);
+  const string& get_names_oid_prefix();
+  const string& get_predefined_name(CephContext *cct);
+
+  void dump(Formatter *f) const;
+  void decode_json(JSONObj *obj);
+  static void generate_test_instances(list<RGWZoneGroup*>& o);
+};
+WRITE_CLASS_ENCODER(RGWZoneGroup)
+
+struct RGWPeriodMap
+{
+  string id;
+  map<string, RGWZoneGroup> zonegroups;
+  map<string, RGWZoneGroup> zonegroups_by_api;
+  map<string, uint32_t> short_zone_ids;
+
+  string master_zonegroup;
+
+  void encode(bufferlist& bl) const;
+  void decode(bufferlist::iterator& bl);
+
+  int update(const RGWZoneGroup& zonegroup);
+
+  void dump(Formatter *f) const;
+  void decode_json(JSONObj *obj);
+
+  void reset() {
+    zonegroups.clear();
+    zonegroups_by_api.clear();
+  }
 
-  static int get_pool_name(CephContext *cct, string *pool_name);
+  uint32_t get_zone_short_id(const string& zone_id) const;
+};
+WRITE_CLASS_ENCODER(RGWPeriodMap)
+
+struct RGWPeriodConfig
+{
+  RGWQuotaInfo bucket_quota;
+  RGWQuotaInfo user_quota;
+
+  void encode(bufferlist& bl) const {
+    ENCODE_START(1, 1, bl);
+    ::encode(bucket_quota, bl);
+    ::encode(user_quota, bl);
+    ENCODE_FINISH(bl);
+  }
+
+  void decode(bufferlist::iterator& bl) {
+    DECODE_START(1, bl);
+    ::decode(bucket_quota, bl);
+    ::decode(user_quota, bl);
+    DECODE_FINISH(bl);
+  }
 
   void dump(Formatter *f) const;
   void decode_json(JSONObj *obj);
-  static void generate_test_instances(list<RGWRegion*>& o);
 };
-WRITE_CLASS_ENCODER(RGWRegion)
+WRITE_CLASS_ENCODER(RGWPeriodConfig)
 
+/* for backward comaptability */
 struct RGWRegionMap {
-  Mutex lock;
-  map<string, RGWRegion> regions;
-  map<string, RGWRegion> regions_by_api;
+
+  map<string, RGWZoneGroup> regions;
 
   string master_region;
 
   RGWQuotaInfo bucket_quota;
   RGWQuotaInfo user_quota;
 
-  RGWRegionMap() : lock("RGWRegionMap") {}
-
   void encode(bufferlist& bl) const;
   void decode(bufferlist::iterator& bl);
 
-  void get_params(CephContext *cct, string& pool_name, string& oid);
+  void dump(Formatter *f) const;
+  void decode_json(JSONObj *obj);
+};
+WRITE_CLASS_ENCODER(RGWRegionMap)
+
+struct RGWZoneGroupMap {
+
+  map<string, RGWZoneGroup> zonegroups;
+  map<string, RGWZoneGroup> zonegroups_by_api;
+
+  string master_zonegroup;
+
+  RGWQuotaInfo bucket_quota;
+  RGWQuotaInfo user_quota;
+
+  /* constract the map */
   int read(CephContext *cct, RGWRados *store);
-  int store(CephContext *cct, RGWRados *store);
 
-  int update(RGWRegion& region);
+  void encode(bufferlist& bl) const;
+  void decode(bufferlist::iterator& bl);
 
   void dump(Formatter *f) const;
   void decode_json(JSONObj *obj);
 };
-WRITE_CLASS_ENCODER(RGWRegionMap)
+WRITE_CLASS_ENCODER(RGWZoneGroupMap)
+
+class RGWRealm;
 
 struct objexp_hint_entry {
   string tenant;
   string bucket_name;
   string bucket_id;
   rgw_obj_key obj_key;
-  utime_t exp_time;
+  ceph::real_time exp_time;
 
   void encode(bufferlist& bl) const {
     ENCODE_START(2, 1, bl);
@@ -1049,8 +1294,226 @@ struct objexp_hint_entry {
 };
 WRITE_CLASS_ENCODER(objexp_hint_entry)
 
+class RGWPeriod;
+
+class RGWRealm : public RGWSystemMetaObj
+{
+  string current_period;
+  epoch_t epoch{0}; //< realm epoch, incremented for each new period
+
+  int create_control();
+  int delete_control();
+public:
+  RGWRealm() {}
+  RGWRealm(const string& _id, const string& _name = "") : RGWSystemMetaObj(_id, _name) {}
+  RGWRealm(CephContext *_cct, RGWRados *_store): RGWSystemMetaObj(_cct, _store) {}
+  RGWRealm(const string& _name, CephContext *_cct, RGWRados *_store): RGWSystemMetaObj(_name, _cct, _store){}
+
+  void encode(bufferlist& bl) const {
+    ENCODE_START(1, 1, bl);
+    RGWSystemMetaObj::encode(bl);
+    ::encode(current_period, bl);
+    ::encode(epoch, bl);
+    ENCODE_FINISH(bl);
+  }
+
+  void decode(bufferlist::iterator& bl) {
+    DECODE_START(1, bl);
+    RGWSystemMetaObj::decode(bl);
+    ::decode(current_period, bl);
+    ::decode(epoch, bl);
+    DECODE_FINISH(bl);
+  }
+
+  int create(bool exclusive = true);
+  int delete_obj();
+  const string& get_pool_name(CephContext *cct);
+  const string get_default_oid(bool old_format = false);
+  const string& get_names_oid_prefix();
+  const string& get_info_oid_prefix(bool old_format = false);
+  const string& get_predefined_name(CephContext *cct);
+
+  void dump(Formatter *f) const;
+  void decode_json(JSONObj *obj);
+
+  const string& get_current_period() const {
+    return current_period;
+  }
+  int set_current_period(RGWPeriod& period);
+
+  epoch_t get_epoch() const { return epoch; }
+
+  string get_control_oid();
+  /// send a notify on the realm control object
+  int notify_zone(bufferlist& bl);
+  /// notify the zone of a new period
+  int notify_new_period(const RGWPeriod& period);
+};
+WRITE_CLASS_ENCODER(RGWRealm)
+
+struct RGWPeriodLatestEpochInfo {
+  epoch_t epoch;
+
+  void encode(bufferlist& bl) const {
+    ENCODE_START(1, 1, bl);
+    ::encode(epoch, bl);
+    ENCODE_FINISH(bl);
+  }
+
+  void decode(bufferlist::iterator& bl) {
+    DECODE_START(1, bl);
+    ::decode(epoch, bl);
+    DECODE_FINISH(bl);
+  }
+
+  void dump(Formatter *f) const;
+  void decode_json(JSONObj *obj);
+};
+WRITE_CLASS_ENCODER(RGWPeriodLatestEpochInfo)
+
+class RGWPeriod
+{
+  string id;
+  epoch_t epoch;
+  string predecessor_uuid;
+  std::vector<std::string> sync_status;
+  RGWPeriodMap period_map;
+  RGWPeriodConfig period_config;
+  string master_zonegroup;
+  string master_zone;
+
+  string realm_id;
+  string realm_name;
+  epoch_t realm_epoch{1}; //< realm epoch when period was made current
+
+  CephContext *cct;
+  RGWRados *store;
+
+  int read_info();
+  int read_latest_epoch(RGWPeriodLatestEpochInfo& epoch_info);
+  int use_latest_epoch();
+  int use_current_period();
+
+  const string get_period_oid();
+  const string get_period_oid_prefix();
+
+  // gather the metadata sync status for each shard; only for use on master zone
+  int update_sync_status();
+
+public:
+  RGWPeriod() : epoch(0) {}
+
+  RGWPeriod(const string& period_id, epoch_t _epoch = 0)
+    : id(period_id), epoch(_epoch) {}
+
+  const string& get_id() const { return id; }
+  epoch_t get_epoch() const { return epoch; }
+  epoch_t get_realm_epoch() const { return realm_epoch; }
+  const string& get_predecessor() const { return predecessor_uuid; }
+  const string& get_master_zone() const { return master_zone; }
+  const string& get_master_zonegroup() const { return master_zonegroup; }
+  const string& get_realm() const { return realm_id; }
+  const RGWPeriodMap& get_map() const { return period_map; }
+  const RGWPeriodConfig& get_config() const { return period_config; }
+  const std::vector<std::string>& get_sync_status() const { return sync_status; }
+  const string& get_pool_name(CephContext *cct);
+  const string& get_latest_epoch_oid();
+  const string& get_info_oid_prefix();
+
+  void set_user_quota(RGWQuotaInfo& user_quota) {
+    period_config.user_quota = user_quota;
+  }
+
+  void set_bucket_quota(RGWQuotaInfo& bucket_quota) {
+    period_config.bucket_quota = bucket_quota;
+  }
+
+  void set_id(const string& id) {
+    this->id = id;
+    period_map.id = id;
+  }
+  void set_epoch(epoch_t epoch) { this->epoch = epoch; }
+  void set_realm_epoch(epoch_t epoch) { realm_epoch = epoch; }
+
+  void set_predecessor(const string& predecessor)
+  {
+    predecessor_uuid = predecessor;
+  }
+
+  void set_realm_id(const string& _realm_id) {
+    realm_id = _realm_id;
+  }
+
+  void update(const RGWZoneGroupMap& map);
+  int reflect();
+
+  int get_zonegroup(RGWZoneGroup& zonegroup,
+		    const string& zonegroup_id);
+
+  bool is_single_zonegroup(CephContext *cct, RGWRados *store);
+
+  int get_latest_epoch(epoch_t& epoch);
+  int set_latest_epoch(epoch_t epoch, bool exclusive = false);
+
+  int init(CephContext *_cct, RGWRados *_store, const string &period_realm_id, const string &period_realm_name = "",
+	   bool setup_obj = true);
+  int init(CephContext *_cct, RGWRados *_store, bool setup_obj = true);  
+  int use_next_epoch();
+
+  int create(bool exclusive = true);
+  int delete_obj();
+  int store_info(bool exclusive);
+  int add_zonegroup(const RGWZoneGroup& zonegroup);
+
+  void fork();
+  int update();
+
+  // commit a staging period; only for use on master zone
+  int commit(RGWRealm& realm, const RGWPeriod &current_period);
+
+  void encode(bufferlist& bl) const {
+    ENCODE_START(1, 1, bl);
+    ::encode(id, bl);
+    ::encode(epoch, bl);
+    ::encode(realm_epoch, bl);
+    ::encode(predecessor_uuid, bl);
+    ::encode(sync_status, bl);
+    ::encode(period_map, bl);
+    ::encode(master_zone, bl);
+    ::encode(master_zonegroup, bl);
+    ::encode(period_config, bl);
+    ::encode(realm_id, bl);
+    ::encode(realm_name, bl);
+    ENCODE_FINISH(bl);
+  }
+
+  void decode(bufferlist::iterator& bl) {
+    DECODE_START(1, bl);
+    ::decode(id, bl);
+    ::decode(epoch, bl);
+    ::decode(realm_epoch, bl);
+    ::decode(predecessor_uuid, bl);
+    ::decode(sync_status, bl);
+    ::decode(period_map, bl);
+    ::decode(master_zone, bl);
+    ::decode(master_zonegroup, bl);
+    ::decode(period_config, bl);
+    ::decode(realm_id, bl);
+    ::decode(realm_name, bl);
+    DECODE_FINISH(bl);
+  }
+  void dump(Formatter *f) const;
+  void decode_json(JSONObj *obj);
+
+  static string get_staging_id(const string& realm_id) {
+    return realm_id + ":staging";
+  }
+};
+WRITE_CLASS_ENCODER(RGWPeriod)
+
 class RGWDataChangesLog;
 class RGWReplicaLogger;
+class RGWCoroutinesManagerRegistry;
   
 class RGWStateLog {
   RGWRados *store;
@@ -1147,7 +1610,7 @@ class RGWOpStateSingleOp
   CephContext *cct;
 
   RGWOpState::OpState cur_state;
-  utime_t last_update;
+  ceph::real_time last_update;
 
 public:
   RGWOpStateSingleOp(RGWRados *store, const string& cid, const string& oid, const string& obj);
@@ -1211,10 +1674,11 @@ public:
 struct RGWObjectCtx {
   RGWRados *store;
   map<rgw_obj, RGWObjState> objs_state;
+  RWLock lock;
   void *user_ctx;
 
-  explicit RGWObjectCtx(RGWRados *_store) : store(_store), user_ctx(NULL) { }
-  RGWObjectCtx(RGWRados *_store, void *_user_ctx) : store(_store), user_ctx(_user_ctx) { }
+  explicit RGWObjectCtx(RGWRados *_store) : store(_store), lock("RGWObjectCtx"), user_ctx(NULL) { }
+  RGWObjectCtx(RGWRados *_store, void *_user_ctx) : store(_store), lock("RGWObjectCtx"), user_ctx(_user_ctx) { }
 
   RGWObjState *get_state(rgw_obj& obj);
   void set_atomic(rgw_obj& obj);
@@ -1223,11 +1687,16 @@ struct RGWObjectCtx {
 };
 
 class Finisher;
+class RGWAsyncRadosProcessor;
 
 class RGWRados
 {
   friend class RGWGC;
+  friend class RGWMetaNotifier;
+  friend class RGWDataNotifier;
   friend class RGWObjectExpirer;
+  friend class RGWMetaSyncProcessorThread;
+  friend class RGWDataSyncProcessorThread;
   friend class RGWStateLog;
   friend class RGWReplicaLogger;
 
@@ -1236,7 +1705,7 @@ class RGWRados
   int open_gc_pool_ctx();
   int open_objexp_pool_ctx();
 
-  int open_bucket_pool_ctx(const string& pool, librados::IoCtx&  io_ctx);
+  int open_pool_ctx(const string& pool, librados::IoCtx&  io_ctx);
   int open_bucket_index_ctx(rgw_bucket& bucket, librados::IoCtx&  index_ctx);
   int open_bucket_data_ctx(rgw_bucket& bucket, librados::IoCtx&  io_ctx);
   int open_bucket_data_extra_ctx(rgw_bucket& bucket, librados::IoCtx&  io_ctx);
@@ -1274,6 +1743,17 @@ class RGWRados
   RGWObjectExpirer *obj_expirer;
   bool use_gc_thread;
   bool quota_threads;
+  bool run_sync_thread;
+
+  RGWAsyncRadosProcessor* async_rados;
+
+  RGWMetaNotifier *meta_notifier;
+  RGWDataNotifier *data_notifier;
+  RGWMetaSyncProcessorThread *meta_sync_processor_thread;
+  map<string, RGWDataSyncProcessorThread *> data_sync_processor_threads;
+
+  Mutex meta_sync_thread_lock;
+  Mutex data_sync_thread_lock;
 
   int num_watchers;
   RGWWatcher **watchers;
@@ -1290,12 +1770,14 @@ class RGWRados
   uint32_t bucket_index_max_shards;
 
   int get_obj_ioctx(const rgw_obj& obj, librados::IoCtx *ioctx);
-  int get_obj_ref(const rgw_obj& obj, rgw_rados_ref *ref, rgw_bucket *bucket, bool ref_system_obj = false);
+  int get_obj_ref(const rgw_obj& obj, rgw_rados_ref *ref, rgw_bucket *bucket);
+  int get_system_obj_ref(const rgw_obj& obj, rgw_rados_ref *ref, rgw_bucket *bucket);
   uint64_t max_bucket_id;
 
   int get_olh_target_state(RGWObjectCtx& rctx, rgw_obj& obj, RGWObjState *olh_state,
-                           RGWObjState **target_state, RGWObjVersionTracker *objv_tracker);
-  int get_obj_state_impl(RGWObjectCtx *rctx, rgw_obj& obj, RGWObjState **state, RGWObjVersionTracker *objv_tracker, bool follow_olh);
+                           RGWObjState **target_state);
+  int get_system_obj_state_impl(RGWObjectCtx *rctx, rgw_obj& obj, RGWObjState **state, RGWObjVersionTracker *objv_tracker);
+  int get_obj_state_impl(RGWObjectCtx *rctx, rgw_obj& obj, RGWObjState **state, bool follow_olh);
   int append_atomic_test(RGWObjectCtx *rctx, rgw_obj& obj,
                          librados::ObjectOperation& op, RGWObjState **state);
 
@@ -1304,6 +1786,7 @@ class RGWRados
 
   void remove_rgw_head_obj(librados::ObjectWriteOperation& op);
   void cls_obj_check_prefix_exist(librados::ObjectOperation& op, const string& prefix, bool fail_if_exist);
+  void cls_obj_check_mtime(librados::ObjectOperation& op, const real_time& mtime, bool high_precision_time, RGWCheckMTimeType type);
 protected:
   CephContext *cct;
 
@@ -1318,17 +1801,28 @@ protected:
 
   bool pools_initialized;
 
-  string region_name;
+  string zonegroup_id;
   string zone_name;
   string trans_id_suffix;
 
   RGWQuotaHandler *quota_handler;
 
   Finisher *finisher;
+  
+  RGWCoroutinesManagerRegistry *cr_registry;
+
+  RGWZoneGroup zonegroup;
+  RGWZone zone_public_config; /* external zone params, e.g., entrypoints, log flags, etc. */  
+  RGWZoneParams zone_params; /* internal zone params, e.g., rados pools */
+  uint32_t zone_short_id;
 
+  RGWPeriod current_period;
 public:
   RGWRados() : max_req_id(0), lock("rados_timer_lock"), watchers_lock("watchers_lock"), timer(NULL),
                gc(NULL), obj_expirer(NULL), use_gc_thread(false), quota_threads(false),
+               run_sync_thread(false), async_rados(nullptr), meta_notifier(NULL),
+               data_notifier(NULL), meta_sync_processor_thread(NULL),
+               meta_sync_thread_lock("meta_sync_thread_lock"), data_sync_thread_lock("data_sync_thread_lock"),
                num_watchers(0), watchers(NULL),
                watch_initialized(false),
                bucket_id_lock("rados_bucket_id"),
@@ -1339,6 +1833,8 @@ public:
                pools_initialized(false),
                quota_handler(NULL),
                finisher(NULL),
+               cr_registry(NULL),
+               zone_short_id(0),
                rest_master_conn(NULL),
                meta_mgr(NULL), data_log(NULL) {}
 
@@ -1350,23 +1846,97 @@ public:
     cct = _cct;
   }
 
-  void set_region(const string& name) {
-    region_name = name;
+  /**
+   * AmazonS3 errors contain a HostId string, but is an opaque base64 blob; we
+   * try to be more transparent. This has a wrapper so we can update it when zonegroup/zone are changed.
+   */
+  void init_host_id() {
+    /* uint64_t needs 16, two '-' separators and a trailing null */
+    const string& zone_name = get_zone().name;
+    const string& zonegroup_name = zonegroup.get_name();
+    char charbuf[16 + zone_name.size() + zonegroup_name.size() + 2 + 1];
+    snprintf(charbuf, sizeof(charbuf), "%llx-%s-%s", (unsigned long long)instance_id(), zone_name.c_str(), zonegroup_name.c_str());
+    string s(charbuf);
+    host_id = s;
   }
 
-  void set_zone(const string& name) {
-    zone_name = name;
-  }
+  string host_id;
+
+  RGWRealm realm;
 
-  RGWRegion region;
-  RGWZoneParams zone; /* internal zone params, e.g., rados pools */
-  RGWZone zone_public_config; /* external zone params, e.g., entrypoints, log flags, etc. */
-  RGWRegionMap region_map;
   RGWRESTConn *rest_master_conn;
   map<string, RGWRESTConn *> zone_conn_map;
-  map<string, RGWRESTConn *> region_conn_map;
+  map<string, RGWRESTConn *> zonegroup_conn_map;
+
+  map<string, string> zone_id_by_name;
+  map<string, string> zone_name_by_id;
+
+  RGWRESTConn *get_zone_conn_by_id(const string& id) {
+    auto citer = zone_conn_map.find(id);
+    if (citer == zone_conn_map.end()) {
+      return NULL;
+    }
+
+    return citer->second;
+  }
+
+  RGWRESTConn *get_zone_conn_by_name(const string& name) {
+    auto i = zone_id_by_name.find(name);
+    if (i == zone_id_by_name.end()) {
+      return NULL;
+    }
+
+    return get_zone_conn_by_id(i->second);
+  }
+
+  bool find_zone_id_by_name(const string& name, string *id) {
+    auto i = zone_id_by_name.find(name);
+    if (i == zone_id_by_name.end()) {
+      return false;
+    }
+    *id = i->second; 
+    return true;
+  }
+
+  int get_zonegroup(const string& id, RGWZoneGroup& zonegroup) {
+    int ret = 0;
+    if (id == get_zonegroup().get_id()) {
+      zonegroup = get_zonegroup();
+    } else if (!current_period.get_id().empty()) {
+      ret = current_period.get_zonegroup(zonegroup, zonegroup_id);
+    }
+    return ret;
+  }
+
+  RGWZoneParams& get_zone_params() { return zone_params; }
+  RGWZoneGroup& get_zonegroup() {
+    return zonegroup;
+  }
+  RGWZone& get_zone() {
+    return zone_public_config;
+  }
+
+  uint32_t get_zone_short_id() const {
+    return zone_short_id;
+  }
 
-  RGWZoneParams& get_zone_params() { return zone; }
+  const RGWQuotaInfo& get_bucket_quota() {
+    return current_period.get_config().bucket_quota;
+  }
+
+  const RGWQuotaInfo& get_user_quota() {
+    return current_period.get_config().user_quota;
+  }
+
+  const string& get_current_period_id() {
+    return current_period.get_id();
+  }
+  // pulls missing periods for period_history
+  std::unique_ptr<RGWPeriodPuller> period_puller;
+  // maintains a connected history of periods
+  std::unique_ptr<RGWPeriodHistory> period_history;
+
+  RGWAsyncRadosProcessor* get_async_rados() const { return async_rados; };
 
   RGWMetadataManager *meta_mgr;
 
@@ -1391,23 +1961,31 @@ public:
                        RGWListRawObjsCtx& ctx, list<string>& oids,
                        bool *is_truncated);
 
-  int list_raw_prefixed_objs(string pool_name, const string& prefix, list<string>& result);
+  int list_raw_prefixed_objs(const string& pool_name, const string& prefix, list<string>& result);
+  int list_zonegroups(list<string>& zonegroups);
   int list_regions(list<string>& regions);
   int list_zones(list<string>& zones);
-
+  int list_realms(list<string>& realms);
+  int list_periods(list<string>& periods);
+  int list_periods(const string& current_period, list<string>& periods);
   void tick();
 
   CephContext *ctx() { return cct; }
   /** do all necessary setup of the storage device */
-  int initialize(CephContext *_cct, bool _use_gc_thread, bool _quota_threads) {
+  int initialize(CephContext *_cct, bool _use_gc_thread, bool _quota_threads, bool _run_sync_thread) {
     set_context(_cct);
     use_gc_thread = _use_gc_thread;
     quota_threads = _quota_threads;
+    run_sync_thread = _run_sync_thread;
     return initialize();
   }
   /** Initialize the RADOS instance and prepare to do other ops */
   virtual int init_rados();
+  int init_zg_from_period(bool *initialized);
+  int init_zg_from_local(bool *creating_defaults);
   int init_complete();
+  int replace_region_with_zonegroup();
+  int convert_regionmap();
   virtual int initialize();
   virtual void finalize();
 
@@ -1445,20 +2023,25 @@ public:
    * returns 0 on success, -ERR# otherwise.
    */
   virtual int init_bucket_index(rgw_bucket& bucket, int num_shards);
-  int select_bucket_placement(RGWUserInfo& user_info, const string& region_name, const string& rule,
-                              const string& tenant_name, const string& bucket_name, rgw_bucket& bucket, string *pselected_rule);
-  int select_legacy_bucket_placement(const string& tenant_name, const string& bucket_name, rgw_bucket& bucket);
-  int select_new_bucket_location(RGWUserInfo& user_info, const string& region_name, const string& rule,
-                                 const string& tenant_name, const string& bucket_name, rgw_bucket& bucket, string *pselected_rule);
-  int set_bucket_location_by_rule(const string& location_rule, const string& tenant_name, const string& bucket_name, rgw_bucket& bucket);
+  int select_bucket_placement(RGWUserInfo& user_info, const string& zonegroup_id, const string& rule,
+                              const string& tenant_name, const string& bucket_name, rgw_bucket& bucket, string *pselected_rule_name,
+                              RGWZonePlacementInfo *rule_info);
+  int select_legacy_bucket_placement(const string& tenant_name, const string& bucket_name, rgw_bucket& bucket,
+                                     RGWZonePlacementInfo *rule_info);
+  int select_new_bucket_location(RGWUserInfo& user_info, const string& zonegroup_id, const string& rule,
+                                 const string& tenant_name, const string& bucket_name, rgw_bucket& bucket, string *pselected_rule_name,
+                                 RGWZonePlacementInfo *rule_info);
+  int set_bucket_location_by_rule(const string& location_rule, const string& tenant_name, const string& bucket_name, rgw_bucket& bucket,
+                                  RGWZonePlacementInfo *rule_info);
   virtual int create_bucket(RGWUserInfo& owner, rgw_bucket& bucket,
-                            const string& region_name,
+                            const string& zonegroup_id,
                             const string& placement_rule,
+                            const string& swift_ver_location,
                             map<std::string,bufferlist>& attrs,
                             RGWBucketInfo& bucket_info,
                             obj_version *pobjv,
                             obj_version *pep_objv,
-                            time_t creation_time,
+                            ceph::real_time creation_time,
                             rgw_bucket *master_bucket,
                             bool exclusive = true);
   virtual int add_bucket_placement(std::string& new_pool);
@@ -1466,6 +2049,8 @@ public:
   virtual int list_placement_set(set<string>& names);
   virtual int create_pools(vector<string>& names, vector<int>& retcodes);
 
+  RGWCoroutinesManagerRegistry *get_cr_registry() { return cr_registry; }
+
   class SystemObject {
     RGWRados *store;
     RGWObjectCtx& ctx;
@@ -1497,7 +2082,7 @@ public:
       } state;
       
       struct StatParams {
-        time_t *lastmod;
+        ceph::real_time *lastmod;
         uint64_t *obj_size;
         map<string, bufferlist> *attrs;
         struct rgw_err *perr;
@@ -1507,6 +2092,9 @@ public:
 
       struct ReadParams {
         rgw_cache_entry_info *cache_info;
+        map<string, bufferlist> *attrs;
+
+        ReadParams() : attrs(NULL) {}
       } read_params;
 
       explicit Read(RGWRados::SystemObject *_source) : source(_source) {}
@@ -1590,17 +2178,21 @@ public:
       } state;
       
       struct ConditionParams {
-        const time_t *mod_ptr;
-        const time_t *unmod_ptr;
+        const ceph::real_time *mod_ptr;
+        const ceph::real_time *unmod_ptr;
+        bool high_precision_time;
+        uint32_t mod_zone_id;
+        uint64_t mod_pg_ver;
         const char *if_match;
         const char *if_nomatch;
         
         ConditionParams() : 
-                 mod_ptr(NULL), unmod_ptr(NULL), if_match(NULL), if_nomatch(NULL) {}
+                 mod_ptr(NULL), unmod_ptr(NULL), high_precision_time(false), mod_zone_id(0), mod_pg_ver(0),
+                 if_match(NULL), if_nomatch(NULL) {}
       } conds;
 
       struct Params {
-        time_t *lastmod;
+        ceph::real_time *lastmod;
         uint64_t *read_size;
         uint64_t *obj_size;
         map<string, bufferlist> *attrs;
@@ -1621,24 +2213,25 @@ public:
       RGWRados::Object *target;
       
       struct MetaParams {
-        time_t *mtime;
+        ceph::real_time *mtime;
         map<std::string, bufferlist>* rmattrs;
         const bufferlist *data;
         RGWObjManifest *manifest;
         const string *ptag;
         list<rgw_obj_key> *remove_objs;
-        time_t set_mtime;
+        ceph::real_time set_mtime;
         rgw_user owner;
         RGWObjCategory category;
         int flags;
         const char *if_match;
         const char *if_nomatch;
         uint64_t olh_epoch;
-	time_t delete_at;
+        ceph::real_time delete_at;
+        bool canceled;
 
         MetaParams() : mtime(NULL), rmattrs(NULL), data(NULL), manifest(NULL), ptag(NULL),
-                 remove_objs(NULL), set_mtime(0), category(RGW_OBJ_CATEGORY_MAIN), flags(0),
-                 if_match(NULL), if_nomatch(NULL), olh_epoch(0), delete_at(0) {}
+                 remove_objs(NULL), category(RGW_OBJ_CATEGORY_MAIN), flags(0),
+                 if_match(NULL), if_nomatch(NULL), olh_epoch(0), canceled(false) {}
       } meta;
 
       explicit Write(RGWRados::Object *_target) : target(_target) {}
@@ -1658,9 +2251,12 @@ public:
         string marker_version_id;
         uint32_t bilog_flags;
         list<rgw_obj_key> *remove_objs;
-        utime_t expiration_time;
+        ceph::real_time expiration_time;
+        ceph::real_time unmod_since;
+        ceph::real_time mtime; /* for setting delete marker mtime */
+        bool high_precision_time;
 
-        DeleteParams() : versioning_status(0), olh_epoch(0), bilog_flags(0), remove_objs(NULL) {}
+        DeleteParams() : versioning_status(0), olh_epoch(0), bilog_flags(0), remove_objs(NULL), high_precision_time(false) {}
       } params;
 
       struct DeleteResult {
@@ -1683,10 +2279,10 @@ public:
         RGWObjManifest manifest;
         bool has_manifest;
         uint64_t size;
-        time_t mtime;
+	struct timespec mtime;
         map<string, bufferlist> attrs;
 
-        Result() : has_manifest(false), size(0), mtime(0) {}
+        Result() : has_manifest(false), size(0) {}
       } result;
 
       struct State {
@@ -1710,13 +2306,21 @@ public:
 
   class Bucket {
     RGWRados *store;
+    RGWBucketInfo bucket_info;
     rgw_bucket& bucket;
+    int shard_id;
 
   public:
-    Bucket(RGWRados *_store, rgw_bucket& _bucket) : store(_store), bucket(_bucket) {}
-
+    Bucket(RGWRados *_store, RGWBucketInfo& _bucket_info) : store(_store), bucket_info(_bucket_info), bucket(bucket_info.bucket),
+                                                            shard_id(RGW_NO_SHARD) {}
     RGWRados *get_store() { return store; }
     rgw_bucket& get_bucket() { return bucket; }
+    RGWBucketInfo& get_bucket_info() { return bucket_info; }
+
+    int get_shard_id() { return shard_id; }
+    void set_shard_id(int id) {
+      shard_id = id;
+    }
 
     class UpdateIndex {
       RGWRados::Bucket *target;
@@ -1726,10 +2330,13 @@ public:
       uint16_t bilog_flags;
       BucketShard bs;
       bool bs_initialized;
+      bool blind;
     public:
 
       UpdateIndex(RGWRados::Bucket *_target, rgw_obj& _obj, RGWObjState *_state) : target(_target), obj(_obj), obj_state(_state), bilog_flags(0),
-                                                                                   bs(target->get_store()), bs_initialized(false) {}
+                                                                                   bs(target->get_store()), bs_initialized(false) {
+                                                                                     blind = (target->get_bucket_info().index_type == RGWBIType_Indexless);
+                                                                                   }
 
       int get_bucket_shard(BucketShard **pbs) {
         if (!bs_initialized) {
@@ -1749,7 +2356,7 @@ public:
 
       int prepare(RGWModifyOp);
       int complete(int64_t poolid, uint64_t epoch, uint64_t size,
-                   utime_t& ut, string& etag, string& content_type,
+                   ceph::real_time& ut, string& etag, string& content_type,
                    bufferlist *acl_bl, RGWObjCategory category,
 		   list<rgw_obj_key> *remove_objs);
       int complete_del(int64_t poolid, uint64_t epoch,
@@ -1785,20 +2392,22 @@ public:
   };
 
   /** Write/overwrite an object to the bucket storage. */
-  virtual int put_system_obj_impl(rgw_obj& obj, uint64_t size, time_t *mtime,
+  virtual int put_system_obj_impl(rgw_obj& obj, uint64_t size, ceph::real_time *mtime,
               map<std::string, bufferlist>& attrs, int flags,
               bufferlist& data,
               RGWObjVersionTracker *objv_tracker,
-              time_t set_mtime /* 0 for don't set */);
+              ceph::real_time set_mtime /* 0 for don't set */);
 
+  virtual int put_system_obj_data(void *ctx, rgw_obj& obj, bufferlist& bl,
+              off_t ofs, bool exclusive);
   virtual int put_obj_data(void *ctx, rgw_obj& obj, const char *data,
               off_t ofs, size_t len, bool exclusive);
   virtual int aio_put_obj_data(void *ctx, rgw_obj& obj, bufferlist& bl,
                                off_t ofs, bool exclusive, void **handle);
 
   int put_system_obj(void *ctx, rgw_obj& obj, const char *data, size_t len, bool exclusive,
-              time_t *mtime, map<std::string, bufferlist>& attrs, RGWObjVersionTracker *objv_tracker,
-              time_t set_mtime) {
+              ceph::real_time *mtime, map<std::string, bufferlist>& attrs, RGWObjVersionTracker *objv_tracker,
+              ceph::real_time set_mtime) {
     bufferlist bl;
     bl.append(data, len);
     int flags = PUT_OBJ_CREATE;
@@ -1827,29 +2436,33 @@ public:
                        rgw_obj& src_obj,
                        RGWBucketInfo& dest_bucket_info,
                        RGWBucketInfo& src_bucket_info,
-                       time_t *src_mtime,
-                       time_t *mtime,
-                       const time_t *mod_ptr,
-                       const time_t *unmod_ptr,
+                       ceph::real_time *src_mtime,
+                       ceph::real_time *mtime,
+                       const ceph::real_time *mod_ptr,
+                       const ceph::real_time *unmod_ptr,
+                       bool high_precision_time,
                        const char *if_match,
                        const char *if_nomatch,
                        AttrsMod attrs_mod,
+                       bool copy_if_newer,
                        map<string, bufferlist>& attrs,
                        RGWObjCategory category,
                        uint64_t olh_epoch,
-		       time_t delete_at,
+		       ceph::real_time delete_at,
                        string *version_id,
                        string *ptag,
                        string *petag,
                        struct rgw_err *err,
                        void (*progress_cb)(off_t, void *),
                        void *progress_data);
+  int swift_versioning_copy(RGWBucketInfo& bucket_info, RGWRados::Object *source, RGWObjState *state,
+                            rgw_user& user);
   int copy_obj_to_remote_dest(RGWObjState *astate,
                               map<string, bufferlist>& src_attrs,
                               RGWRados::Object::Read& read_op,
                               const rgw_user& user_id,
                               rgw_obj& dest_obj,
-                              time_t *mtime);
+                              ceph::real_time *mtime);
   /**
    * Copy an object.
    * dest_obj: the object to copy into
@@ -1875,17 +2488,19 @@ public:
                rgw_obj& src_obj,
                RGWBucketInfo& dest_bucket_info,
                RGWBucketInfo& src_bucket_info,
-               time_t *src_mtime,
-               time_t *mtime,
-               const time_t *mod_ptr,
-               const time_t *unmod_ptr,
+               ceph::real_time *src_mtime,
+               ceph::real_time *mtime,
+               const ceph::real_time *mod_ptr,
+               const ceph::real_time *unmod_ptr,
+               bool high_precision_time,
                const char *if_match,
                const char *if_nomatch,
                AttrsMod attrs_mod,
+               bool copy_if_newer,
                map<std::string, bufferlist>& attrs,
                RGWObjCategory category,
                uint64_t olh_epoch,
-	       time_t delete_at,
+	       ceph::real_time delete_at,
                string *version_id,
                string *ptag,
                string *petag,
@@ -1899,12 +2514,12 @@ public:
                rgw_obj& dest_obj,
                rgw_obj& src_obj,
                uint64_t max_chunk_size,
-	       time_t *mtime,
-	       time_t set_mtime,
+	       ceph::real_time *mtime,
+	       ceph::real_time set_mtime,
                map<string, bufferlist>& attrs,
                RGWObjCategory category,
                uint64_t olh_epoch,
-	       time_t delete_at,
+	       ceph::real_time delete_at,
                string *version_id,
                string *ptag,
                string *petag,
@@ -1917,11 +2532,15 @@ public:
    */
   virtual int delete_bucket(rgw_bucket& bucket, RGWObjVersionTracker& objv_tracker);
 
+  bool is_meta_master();
+
   /**
    * Check to see if the bucket metadata is synced
    */
   bool is_syncing_bucket_meta(rgw_bucket& bucket);
-  
+  void wakeup_meta_sync_shards(set<int>& shard_ids);
+  void wakeup_data_sync_shards(const string& source_zone, map<int, set<string> >& shard_ids);
+
   int set_bucket_owner(rgw_bucket& bucket, ACLOwner& owner);
   int set_buckets_enabled(std::vector<rgw_bucket>& buckets, bool enabled);
   int bucket_suspended(rgw_bucket& bucket, bool *suspended);
@@ -1932,7 +2551,7 @@ public:
                          rgw_obj& src_obj,
                          int versioning_status,
                          uint16_t bilog_flags = 0,
-                         const utime_t& expiration_time = utime_t());
+                         const ceph::real_time& expiration_time = ceph::real_time());
 
   /* Delete a system object */
   virtual int delete_system_obj(rgw_obj& src_obj, RGWObjVersionTracker *objv_tracker = NULL);
@@ -1950,6 +2569,13 @@ public:
    */
   virtual int system_obj_get_attr(rgw_obj& obj, const char *name, bufferlist& dest);
 
+  int system_obj_set_attr(void *ctx, rgw_obj& obj, const char *name, bufferlist& bl,
+                          RGWObjVersionTracker *objv_tracker);
+  virtual int system_obj_set_attrs(void *ctx, rgw_obj& obj,
+                                   map<string, bufferlist>& attrs,
+                                   map<string, bufferlist>* rmattrs,
+                                   RGWObjVersionTracker *objv_tracker);
+
   /**
    * Set an attr on an object.
    * bucket: name of the bucket holding the object
@@ -1958,30 +2584,30 @@ public:
    * bl: the contents of the attr
    * Returns: 0 on success, -ERR# otherwise.
    */
-  virtual int set_attr(void *ctx, rgw_obj& obj, const char *name, bufferlist& bl,
-                       RGWObjVersionTracker *objv_tracker);
+  int set_attr(void *ctx, rgw_obj& obj, const char *name, bufferlist& bl);
 
-  virtual int set_attrs(void *ctx, rgw_obj& obj,
+  int set_attrs(void *ctx, rgw_obj& obj,
                         map<string, bufferlist>& attrs,
-                        map<string, bufferlist>* rmattrs,
-                        RGWObjVersionTracker *objv_tracker);
+                        map<string, bufferlist>* rmattrs);
 
-  int get_obj_state(RGWObjectCtx *rctx, rgw_obj& obj, RGWObjState **state, RGWObjVersionTracker *objv_tracker, bool follow_olh);
-  int get_obj_state(RGWObjectCtx *rctx, rgw_obj& obj, RGWObjState **state, RGWObjVersionTracker *objv_tracker) {
-    return get_obj_state(rctx, obj, state, objv_tracker, true);
+  int get_system_obj_state(RGWObjectCtx *rctx, rgw_obj& obj, RGWObjState **state, RGWObjVersionTracker *objv_tracker);
+  int get_obj_state(RGWObjectCtx *rctx, rgw_obj& obj, RGWObjState **state, bool follow_olh);
+  int get_obj_state(RGWObjectCtx *rctx, rgw_obj& obj, RGWObjState **state) {
+    return get_obj_state(rctx, obj, state, true);
   }
 
   virtual int stat_system_obj(RGWObjectCtx& obj_ctx,
                               RGWRados::SystemObject::Read::GetObjState& state,
                               rgw_obj& obj,
                               map<string, bufferlist> *attrs,
-                              time_t *lastmod,
+                              ceph::real_time *lastmod,
                               uint64_t *obj_size,
                               RGWObjVersionTracker *objv_tracker);
 
   virtual int get_system_obj(RGWObjectCtx& obj_ctx, RGWRados::SystemObject::Read::GetObjState& read_state,
                              RGWObjVersionTracker *objv_tracker, rgw_obj& obj,
                              bufferlist& bl, off_t ofs, off_t end,
+                             map<string, bufferlist> *attrs,
                              rgw_cache_entry_info *cache_info);
 
   virtual void register_chained_cache(RGWChainedCache *cache) {}
@@ -2006,7 +2632,7 @@ public:
    * a simple object read without keeping state
    */
 
-  virtual int raw_obj_stat(rgw_obj& obj, uint64_t *psize, time_t *pmtime, uint64_t *epoch,
+  virtual int raw_obj_stat(rgw_obj& obj, uint64_t *psize, ceph::real_time *pmtime, uint64_t *epoch,
                        map<string, bufferlist> *attrs, bufferlist *first_chunk,
                        RGWObjVersionTracker *objv_tracker);
 
@@ -2018,7 +2644,8 @@ public:
   int olh_init_modification_impl(RGWObjState& state, rgw_obj& olh_obj, string *op_tag);
   int bucket_index_link_olh(RGWObjState& olh_state, rgw_obj& obj_instance, bool delete_marker,
                             const string& op_tag, struct rgw_bucket_dir_entry_meta *meta,
-                            uint64_t olh_epoch);
+                            uint64_t olh_epoch,
+                            ceph::real_time unmod_since, bool high_precision_time);
   int bucket_index_unlink_instance(rgw_obj& obj_instance, const string& op_tag, uint64_t olh_epoch);
   int bucket_index_read_olh_log(RGWObjState& state, rgw_obj& obj_instance, uint64_t ver_marker,
                                 map<uint64_t, vector<rgw_bucket_olh_log_entry> > *log, bool *is_truncated);
@@ -2029,7 +2656,7 @@ public:
                     uint64_t *plast_ver);
   int update_olh(RGWObjectCtx& obj_ctx, RGWObjState *state, RGWBucketInfo& bucket_info, rgw_obj& obj);
   int set_olh(RGWObjectCtx& obj_ctx, RGWBucketInfo& bucket_info, rgw_obj& target_obj, bool delete_marker, rgw_bucket_dir_entry_meta *meta,
-              uint64_t olh_epoch);
+              uint64_t olh_epoch, ceph::real_time unmod_since, bool high_precision_time);
   int unlink_obj_instance(RGWObjectCtx& obj_ctx, RGWBucketInfo& bucket_info, rgw_obj& target_obj,
                           uint64_t olh_epoch);
 
@@ -2074,9 +2701,9 @@ public:
   }
 
   int decode_policy(bufferlist& bl, ACLOwner *owner);
-  int get_bucket_stats(rgw_bucket& bucket, string *bucket_ver, string *master_ver,
+  int get_bucket_stats(rgw_bucket& bucket, int shard_id, string *bucket_ver, string *master_ver,
       map<RGWObjCategory, RGWStorageStats>& stats, string *max_marker);
-  int get_bucket_stats_async(rgw_bucket& bucket, RGWGetBucketStats_CB *cb);
+  int get_bucket_stats_async(rgw_bucket& bucket, int shard_id, RGWGetBucketStats_CB *cb);
   int get_user_stats(const rgw_user& user, RGWStorageStats& stats);
   int get_user_stats_async(const rgw_user& user, RGWGetUserStats_CB *cb);
   void get_bucket_instance_obj(rgw_bucket& bucket, rgw_obj& obj);
@@ -2084,15 +2711,15 @@ public:
   void get_bucket_meta_oid(rgw_bucket& bucket, string& oid);
 
   int put_bucket_entrypoint_info(const string& tenant_name, const string& bucket_name, RGWBucketEntryPoint& entry_point,
-                                 bool exclusive, RGWObjVersionTracker& objv_tracker, time_t mtime,
+                                 bool exclusive, RGWObjVersionTracker& objv_tracker, ceph::real_time mtime,
                                  map<string, bufferlist> *pattrs);
-  int put_bucket_instance_info(RGWBucketInfo& info, bool exclusive, time_t mtime, map<string, bufferlist> *pattrs);
+  int put_bucket_instance_info(RGWBucketInfo& info, bool exclusive, ceph::real_time mtime, map<string, bufferlist> *pattrs);
   int get_bucket_entrypoint_info(RGWObjectCtx& obj_ctx, const string& tenant_name, const string& bucket_name,
                                  RGWBucketEntryPoint& entry_point, RGWObjVersionTracker *objv_tracker,
-                                 time_t *pmtime, map<string, bufferlist> *pattrs, rgw_cache_entry_info *cache_info = NULL);
-  int get_bucket_instance_info(RGWObjectCtx& obj_ctx, const string& meta_key, RGWBucketInfo& info, time_t *pmtime, map<string, bufferlist> *pattrs);
-  int get_bucket_instance_info(RGWObjectCtx& obj_ctx, rgw_bucket& bucket, RGWBucketInfo& info, time_t *pmtime, map<string, bufferlist> *pattrs);
-  int get_bucket_instance_from_oid(RGWObjectCtx& obj_ctx, string& oid, RGWBucketInfo& info, time_t *pmtime, map<string, bufferlist> *pattrs,
+                                 ceph::real_time *pmtime, map<string, bufferlist> *pattrs, rgw_cache_entry_info *cache_info = NULL);
+  int get_bucket_instance_info(RGWObjectCtx& obj_ctx, const string& meta_key, RGWBucketInfo& info, ceph::real_time *pmtime, map<string, bufferlist> *pattrs);
+  int get_bucket_instance_info(RGWObjectCtx& obj_ctx, rgw_bucket& bucket, RGWBucketInfo& info, ceph::real_time *pmtime, map<string, bufferlist> *pattrs);
+  int get_bucket_instance_from_oid(RGWObjectCtx& obj_ctx, string& oid, RGWBucketInfo& info, ceph::real_time *pmtime, map<string, bufferlist> *pattrs,
                                    rgw_cache_entry_info *cache_info = NULL);
 
   int convert_old_bucket_info(RGWObjectCtx& obj_ctx, const string& tenant_name, const string& bucket_name);
@@ -2100,8 +2727,8 @@ public:
   virtual int get_bucket_info(RGWObjectCtx& obj_ctx,
                               const string& tenant_name, const string& bucket_name,
                               RGWBucketInfo& info,
-                              time_t *pmtime, map<string, bufferlist> *pattrs = NULL);
-  virtual int put_linked_bucket_info(RGWBucketInfo& info, bool exclusive, time_t mtime, obj_version *pep_objv,
+                              ceph::real_time *pmtime, map<string, bufferlist> *pattrs = NULL);
+  virtual int put_linked_bucket_info(RGWBucketInfo& info, bool exclusive, ceph::real_time mtime, obj_version *pep_objv,
                                      map<string, bufferlist> *pattrs, bool create_entry_point);
 
   int cls_rgw_init_index(librados::IoCtx& io_ctx, librados::ObjectWriteOperation& op, string& oid);
@@ -2114,12 +2741,12 @@ public:
                            list<rgw_obj_key> *remove_objs, uint16_t bilog_flags);
   int cls_obj_complete_cancel(BucketShard& bs, string& tag, rgw_obj& obj, uint16_t bilog_flags);
   int cls_obj_set_bucket_tag_timeout(rgw_bucket& bucket, uint64_t timeout);
-  int cls_bucket_list(rgw_bucket& bucket, rgw_obj_key& start, const string& prefix,
+  int cls_bucket_list(rgw_bucket& bucket, int shard_id, rgw_obj_key& start, const string& prefix,
                       uint32_t num_entries, bool list_versions, map<string, RGWObjEnt>& m,
                       bool *is_truncated, rgw_obj_key *last_entry,
                       bool (*force_check_filter)(const string&  name) = NULL);
-  int cls_bucket_head(rgw_bucket& bucket, map<string, struct rgw_bucket_dir_header>& headers, map<int, string> *bucket_instance_ids = NULL);
-  int cls_bucket_head_async(rgw_bucket& bucket, RGWGetDirHeader_CB *ctx, int *num_aio);
+  int cls_bucket_head(rgw_bucket& bucket, int shard_id, map<string, struct rgw_bucket_dir_header>& headers, map<int, string> *bucket_instance_ids = NULL);
+  int cls_bucket_head_async(rgw_bucket& bucket, int shard_id, RGWGetDirHeader_CB *ctx, int *num_aio);
   int list_bi_log_entries(rgw_bucket& bucket, int shard_id, string& marker, uint32_t max, std::list<rgw_bi_log_entry>& result, bool *truncated);
   int trim_bi_log_entries(rgw_bucket& bucket, int shard_id, string& marker, string& end_marker);
 
@@ -2134,30 +2761,35 @@ public:
                              string& read_iter, map<rgw_user_bucket, rgw_usage_log_entry>& usage, bool *is_truncated);
   int cls_obj_usage_log_trim(string& oid, string& user, uint64_t start_epoch, uint64_t end_epoch);
 
-  void shard_name(const string& prefix, unsigned max_shards, const string& key, string& name);
+  int key_to_shard_id(const string& key, int max_shards);
+  void shard_name(const string& prefix, unsigned max_shards, const string& key, string& name, int *shard_id);
   void shard_name(const string& prefix, unsigned max_shards, const string& section, const string& key, string& name);
-  void time_log_prepare_entry(cls_log_entry& entry, const utime_t& ut, const string& section, const string& key, bufferlist& bl);
-  int time_log_add(const string& oid, list<cls_log_entry>& entries);
-  int time_log_add(const string& oid, const utime_t& ut, const string& section, const string& key, bufferlist& bl);
-  int time_log_list(const string& oid, utime_t& start_time, utime_t& end_time,
+  void shard_name(const string& prefix, unsigned shard_id, string& name);
+  void time_log_prepare_entry(cls_log_entry& entry, const ceph::real_time& ut, const string& section, const string& key, bufferlist& bl);
+  int time_log_add_init(librados::IoCtx& io_ctx);
+  int time_log_add(const string& oid, list<cls_log_entry>& entries,
+		   librados::AioCompletion *completion, bool monotonic_inc = true);
+  int time_log_add(const string& oid, const ceph::real_time& ut, const string& section, const string& key, bufferlist& bl);
+  int time_log_list(const string& oid, const ceph::real_time& start_time, const ceph::real_time& end_time,
                     int max_entries, list<cls_log_entry>& entries,
 		    const string& marker, string *out_marker, bool *truncated);
   int time_log_info(const string& oid, cls_log_header *header);
-  int time_log_trim(const string& oid, const utime_t& start_time, const utime_t& end_time,
+  int time_log_info_async(librados::IoCtx& io_ctx, const string& oid, cls_log_header *header, librados::AioCompletion *completion);
+  int time_log_trim(const string& oid, const ceph::real_time& start_time, const ceph::real_time& end_time,
                     const string& from_marker, const string& to_marker);
 
   string objexp_hint_get_shardname(int shard_num);
   int objexp_key_shard(const rgw_obj_key& key);
   void objexp_get_shard(int shard_num,
                         string& shard);                       /* out */
-  int objexp_hint_add(const utime_t& delete_at,
+  int objexp_hint_add(const ceph::real_time& delete_at,
                       const string& tenant_name,
                       const string& bucket_name,
                       const string& bucket_id,
                       const rgw_obj_key& obj_key);
   int objexp_hint_list(const string& oid,
-                       const utime_t& start_time,
-                       const utime_t& end_time,
+                       const ceph::real_time& start_time,
+                       const ceph::real_time& end_time,
                        const int max_entries,
                        const string& marker,
                        list<cls_timeindex_entry>& entries, /* out */
@@ -2166,12 +2798,12 @@ public:
   int objexp_hint_parse(cls_timeindex_entry &ti_entry,
                         objexp_hint_entry& hint_entry);    /* out */
   int objexp_hint_trim(const string& oid,
-                       const utime_t& start_time,
-                       const utime_t& end_time,
+                       const ceph::real_time& start_time,
+                       const ceph::real_time& end_time,
                        const string& from_marker = std::string(),
                        const string& to_marker   = std::string());
 
-  int lock_exclusive(rgw_bucket& pool, const string& oid, utime_t& duration, string& zone_id, string& owner_id);
+  int lock_exclusive(rgw_bucket& pool, const string& oid, ceph::timespan& duration, string& zone_id, string& owner_id);
   int unlock(rgw_bucket& pool, const string& oid, string& zone_id, string& owner_id);
 
   void update_gc_chain(rgw_obj& head_obj, RGWObjManifest& manifest, cls_rgw_obj_chain *chain);
@@ -2218,10 +2850,14 @@ public:
   int check_quota(const rgw_user& bucket_owner, rgw_bucket& bucket,
                   RGWQuotaInfo& user_quota, RGWQuotaInfo& bucket_quota, uint64_t obj_size);
 
+  uint64_t instance_id();
+  const string& zone_id() {
+    return get_zone_params().get_id();
+  }
   string unique_id(uint64_t unique_num) {
     char buf[32];
     snprintf(buf, sizeof(buf), ".%llu.%llu", (unsigned long long)instance_id(), (unsigned long long)unique_num);
-    string s = zone.name + buf;
+    string s = get_zone_params().get_id() + buf;
     return s;
   }
 
@@ -2229,7 +2865,7 @@ public:
     char buf[16 + 2 + 1]; /* uint64_t needs 16, 2 hyphens add further 2 */
 
     snprintf(buf, sizeof(buf), "-%llx-", (unsigned long long)instance_id());
-    url_encode(string(buf) + zone.name, trans_id_suffix);
+    url_encode(string(buf) + get_zone_params().get_name(), trans_id_suffix);
   }
 
   /* In order to preserve compability with Swift API, transaction ID
@@ -2255,15 +2891,15 @@ public:
   }
 
   void get_log_pool_name(string& name) {
-    name = zone.log_pool.name;
+    name = get_zone_params().log_pool.name;
   }
 
   bool need_to_log_data() {
-    return zone_public_config.log_data;
+    return get_zone().log_data;
   }
 
   bool need_to_log_metadata() {
-    return zone_public_config.log_meta;
+    return get_zone().log_meta;
   }
 
   librados::Rados* get_rados_handle();
@@ -2315,10 +2951,6 @@ public:
                        RGWObjEnt& object,
                        bufferlist& suggested_updates);
 
-  bool bucket_is_system(rgw_bucket& bucket) {
-    return (bucket.name[0] == '.');
-  }
-
   /**
    * Init pool iteration
    * bucket: pool name in a bucket object
@@ -2338,22 +2970,21 @@ public:
   int pool_iterate(RGWPoolIterCtx& ctx, uint32_t num, vector<RGWObjEnt>& objs,
                    bool *is_truncated, RGWAccessListFilter *filter);
 
-  uint64_t instance_id();
   uint64_t next_bucket_id();
 };
 
 class RGWStoreManager {
 public:
   RGWStoreManager() {}
-  static RGWRados *get_storage(CephContext *cct, bool use_gc_thread, bool quota_threads) {
-    RGWRados *store = init_storage_provider(cct, use_gc_thread, quota_threads);
+  static RGWRados *get_storage(CephContext *cct, bool use_gc_thread, bool quota_threads, bool run_sync_thread) {
+    RGWRados *store = init_storage_provider(cct, use_gc_thread, quota_threads, run_sync_thread);
     return store;
   }
   static RGWRados *get_raw_storage(CephContext *cct) {
     RGWRados *store = init_raw_storage_provider(cct);
     return store;
   }
-  static RGWRados *init_storage_provider(CephContext *cct, bool use_gc_thread, bool quota_threads);
+  static RGWRados *init_storage_provider(CephContext *cct, bool use_gc_thread, bool quota_threads, bool run_sync_thread);
   static RGWRados *init_raw_storage_provider(CephContext *cct);
   static void close_storage(RGWRados *store);
 
@@ -2405,7 +3036,7 @@ public:
     RWLock::WLocker wl(lock);
     entries.clear();
   }
-};
+}; /* RGWChainedCacheImpl */
 
 class RGWPutObjProcessor
 {
@@ -2414,13 +3045,14 @@ protected:
   RGWObjectCtx& obj_ctx;
   bool is_complete;
   RGWBucketInfo bucket_info;
+  bool canceled;
 
-  virtual int do_complete(string& etag, time_t *mtime, time_t set_mtime,
-                          map<string, bufferlist>& attrs, time_t delete_at,
+  virtual int do_complete(string& etag, ceph::real_time *mtime, ceph::real_time set_mtime,
+                          map<string, bufferlist>& attrs, ceph::real_time delete_at,
                           const char *if_match = NULL, const char *if_nomatch = NULL) = 0;
 
 public:
-  RGWPutObjProcessor(RGWObjectCtx& _obj_ctx, RGWBucketInfo& _bi) : store(NULL), obj_ctx(_obj_ctx), is_complete(false), bucket_info(_bi) {}
+  RGWPutObjProcessor(RGWObjectCtx& _obj_ctx, RGWBucketInfo& _bi) : store(NULL), obj_ctx(_obj_ctx), is_complete(false), bucket_info(_bi), canceled(false) {}
   virtual ~RGWPutObjProcessor() {}
   virtual int prepare(RGWRados *_store, string *oid_rand) {
     store = _store;
@@ -2431,12 +3063,14 @@ public:
   virtual void complete_hash(MD5 *hash) {
     assert(0);
   }
-  virtual int complete(string& etag, time_t *mtime, time_t set_mtime,
-                       map<string, bufferlist>& attrs, time_t delete_at,
+  virtual int complete(string& etag, ceph::real_time *mtime, ceph::real_time set_mtime,
+                       map<string, bufferlist>& attrs, ceph::real_time delete_at,
                        const char *if_match = NULL, const char *if_nomatch = NULL);
 
   CephContext *ctx();
-};
+
+  bool is_canceled() { return canceled; }
+}; /* RGWPutObjProcessor */
 
 struct put_obj_aio_info {
   void *handle;
@@ -2470,7 +3104,7 @@ public:
 
   RGWPutObjProcessor_Aio(RGWObjectCtx& obj_ctx, RGWBucketInfo& bucket_info) : RGWPutObjProcessor(obj_ctx, bucket_info), max_chunks(RGW_MAX_PENDING_CHUNKS), obj_len(0) {}
   virtual ~RGWPutObjProcessor_Aio();
-};
+}; /* RGWPutObjProcessor_Aio */
 
 class RGWPutObjProcessor_Atomic : public RGWPutObjProcessor_Aio
 {
@@ -2502,8 +3136,8 @@ protected:
   RGWObjManifest::generator manifest_gen;
 
   int write_data(bufferlist& bl, off_t ofs, void **phandle, bool exclusive);
-  virtual int do_complete(string& etag, time_t *mtime, time_t set_mtime,
-                          map<string, bufferlist>& attrs, time_t delete_at,
+  virtual int do_complete(string& etag, ceph::real_time *mtime, ceph::real_time set_mtime,
+                          map<string, bufferlist>& attrs, ceph::real_time delete_at,
                           const char *if_match = NULL, const char *if_nomatch = NULL);
 
   int prepare_next_part(off_t ofs);
@@ -2545,6 +3179,6 @@ public:
   void set_version_id(const string& vid) {
     version_id = vid;
   }
-};
+}; /* RGWPutObjProcessor_Atomic */
 
 #endif
diff --git a/src/rgw/rgw_realm_reloader.cc b/src/rgw/rgw_realm_reloader.cc
new file mode 100644
index 0000000..a0c31fe
--- /dev/null
+++ b/src/rgw/rgw_realm_reloader.cc
@@ -0,0 +1,157 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+
+#include "rgw_realm_reloader.h"
+#include "rgw_rados.h"
+
+#include "rgw_bucket.h"
+#include "rgw_log.h"
+#include "rgw_rest.h"
+#include "rgw_user.h"
+
+#define dout_subsys ceph_subsys_rgw
+
+#undef dout_prefix
+#define dout_prefix (*_dout << "rgw realm reloader: ")
+
+
+// safe callbacks from SafeTimer are unneccessary. reload() can take a long
+// time, so we don't want to hold the mutex and block handle_notify() for the
+// duration
+static constexpr bool USE_SAFE_TIMER_CALLBACKS = false;
+
+
+RGWRealmReloader::RGWRealmReloader(RGWRados*& store, Pauser* frontends)
+  : store(store),
+    frontends(frontends),
+    timer(store->ctx(), mutex, USE_SAFE_TIMER_CALLBACKS),
+    mutex("RGWRealmReloader"),
+    reload_scheduled(nullptr)
+{
+  timer.init();
+}
+
+RGWRealmReloader::~RGWRealmReloader()
+{
+  Mutex::Locker lock(mutex);
+  timer.shutdown();
+}
+
+class RGWRealmReloader::C_Reload : public Context {
+  RGWRealmReloader* reloader;
+ public:
+  C_Reload(RGWRealmReloader* reloader) : reloader(reloader) {}
+  void finish(int r) { reloader->reload(); }
+};
+
+void RGWRealmReloader::handle_notify(RGWRealmNotify type,
+                                     bufferlist::iterator& p)
+{
+  if (!store) {
+    /* we're in the middle of reload */
+    return;
+  }
+
+  CephContext *const cct = store->ctx();
+
+  Mutex::Locker lock(mutex);
+  if (reload_scheduled) {
+    ldout(cct, 4) << "Notification on realm, reconfiguration "
+        "already scheduled" << dendl;
+    return;
+  }
+
+  reload_scheduled = new C_Reload(this);
+  cond.SignalOne(); // wake reload() if it blocked on a bad configuration
+
+  // schedule reload() with a delay so we can batch up changes
+  auto delay = cct->_conf->rgw_realm_reconfigure_delay;
+  timer.add_event_after(delay, reload_scheduled);
+
+  ldout(cct, 4) << "Notification on realm, reconfiguration scheduled in "
+      << delay << 's' << dendl;
+}
+
+void RGWRealmReloader::reload()
+{
+  CephContext *const cct = store->ctx();
+  ldout(cct, 1) << "Pausing frontends for realm update..." << dendl;
+
+  frontends->pause();
+
+  ldout(cct, 1) << "Frontends paused" << dendl;
+  // destroy the existing store
+  RGWStoreManager::close_storage(store);
+  store = nullptr;
+
+  ldout(cct, 1) << "Store closed" << dendl;
+  {
+    // allow a new notify to reschedule us. it's important that we do this
+    // before we start loading the new realm, or we could miss some updates
+    Mutex::Locker lock(mutex);
+    reload_scheduled = nullptr;
+  }
+
+  while (!store) {
+    // recreate and initialize a new store
+    store = RGWStoreManager::get_storage(cct,
+                                         cct->_conf->rgw_enable_gc_threads,
+                                         cct->_conf->rgw_enable_quota_threads,
+                                         cct->_conf->rgw_run_sync_thread);
+
+    ldout(cct, 1) << "Creating new store" << dendl;
+
+    RGWRados* store_cleanup = nullptr;
+    {
+      Mutex::Locker lock(mutex);
+
+      // failure to recreate RGWRados is not a recoverable error, but we
+      // don't want to assert or abort the entire cluster.  instead, just
+      // sleep until we get another notification, and retry until we get
+      // a working configuration
+      if (store == nullptr) {
+        lderr(cct) << "Failed to reinitialize RGWRados after a realm "
+            "configuration update. Waiting for a new update." << dendl;
+
+        // sleep until another event is scheduled
+        while (!reload_scheduled)
+          cond.Wait(mutex);
+
+        ldout(cct, 1) << "Woke up with a new configuration, retrying "
+            "RGWRados initialization." << dendl;
+      }
+
+      if (reload_scheduled) {
+        // cancel the event; we'll handle it now
+        timer.cancel_event(reload_scheduled);
+        reload_scheduled = nullptr;
+
+        // if we successfully created a store, clean it up outside of the lock,
+        // then continue to loop and recreate another
+        std::swap(store, store_cleanup);
+      }
+    }
+
+    if (store_cleanup) {
+      ldout(cct, 4) << "Got another notification, restarting RGWRados "
+          "initialization." << dendl;
+
+      RGWStoreManager::close_storage(store_cleanup);
+    }
+  }
+
+  ldout(cct, 1) << "Finishing initialization of new store" << dendl;
+  // finish initializing the new store
+  ldout(cct, 1) << " - REST subsystem init" << dendl;
+  rgw_rest_init(cct, store, store->get_zonegroup());
+  ldout(cct, 1) << " - user subsystem init" << dendl;
+  rgw_user_init(store);
+  ldout(cct, 1) << " - user subsystem init" << dendl;
+  rgw_bucket_init(store->meta_mgr);
+  ldout(cct, 1) << " - usage subsystem init" << dendl;
+  rgw_log_usage_init(cct, store);
+
+  ldout(cct, 1) << "Resuming frontends with new realm configuration." << dendl;
+
+  frontends->resume(store);
+}
diff --git a/src/rgw/rgw_realm_reloader.h b/src/rgw/rgw_realm_reloader.h
new file mode 100644
index 0000000..3e60cd4
--- /dev/null
+++ b/src/rgw/rgw_realm_reloader.h
@@ -0,0 +1,62 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+
+#ifndef RGW_REALM_RELOADER_H
+#define RGW_REALM_RELOADER_H
+
+#include "rgw_realm_watcher.h"
+#include "common/Cond.h"
+
+class RGWRados;
+
+/**
+ * RGWRealmReloader responds to notifications by recreating RGWRados with the
+ * updated realm configuration.
+ */
+class RGWRealmReloader : public RGWRealmWatcher::Watcher {
+ public:
+  /**
+   * Pauser is an interface to pause/resume frontends. Frontend cooperation
+   * is required to ensure that they stop issuing requests on the old
+   * RGWRados instance, and restart with the updated configuration.
+   *
+   * This abstraction avoids a depency on class RGWFrontend, which is only
+   * defined in rgw_main.cc
+   */
+  class Pauser {
+   public:
+    virtual ~Pauser() = default;
+
+    /// pause all frontends while realm reconfiguration is in progress
+    virtual void pause() = 0;
+    /// resume all frontends with the given RGWRados instance
+    virtual void resume(RGWRados* store) = 0;
+  };
+
+  RGWRealmReloader(RGWRados*& store, Pauser* frontends);
+  ~RGWRealmReloader();
+
+  /// respond to realm notifications by scheduling a reload()
+  void handle_notify(RGWRealmNotify type, bufferlist::iterator& p) override;
+
+ private:
+  /// pause frontends and replace the RGWRados instance
+  void reload();
+
+  class C_Reload; //< Context that calls reload()
+
+  /// main()'s RGWRados pointer as a reference, modified by reload()
+  RGWRados*& store;
+  Pauser *const frontends;
+
+  /// reload() takes a significant amount of time, so we don't want to run
+  /// it in the handle_notify() thread. we choose a timer thread because we
+  /// also want to add a delay (see rgw_realm_reconfigure_delay) so that we
+  /// can batch up notifications within that window
+  SafeTimer timer;
+  Mutex mutex; //< protects access to timer and reload_scheduled
+  Cond cond; //< to signal reload() after an invalid realm config
+  C_Reload* reload_scheduled; //< reload() context if scheduled
+};
+
+#endif // RGW_REALM_RELOADER_H
diff --git a/src/rgw/rgw_realm_watcher.cc b/src/rgw/rgw_realm_watcher.cc
new file mode 100644
index 0000000..6e47c48
--- /dev/null
+++ b/src/rgw/rgw_realm_watcher.cc
@@ -0,0 +1,141 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+
+#include "common/errno.h"
+
+#include "rgw_realm_watcher.h"
+#include "rgw_rados.h"
+
+#define dout_subsys ceph_subsys_rgw
+
+#undef dout_prefix
+#define dout_prefix (*_dout << "rgw realm watcher: ")
+
+
+RGWRealmWatcher::RGWRealmWatcher(CephContext* cct, RGWRealm& realm)
+  : cct(cct)
+{
+  // no default realm, nothing to watch
+  if (realm.get_id().empty()) {
+    ldout(cct, 4) << "No realm, disabling dynamic reconfiguration." << dendl;
+    return;
+  }
+
+  // establish the watch on RGWRealm
+  int r = watch_start(realm);
+  if (r < 0) {
+    lderr(cct) << "Failed to establish a watch on RGWRealm, "
+        "disabling dynamic reconfiguration." << dendl;
+    return;
+  }
+}
+
+RGWRealmWatcher::~RGWRealmWatcher()
+{
+  watch_stop();
+}
+
+void RGWRealmWatcher::add_watcher(RGWRealmNotify type, Watcher& watcher)
+{
+  watchers.emplace(type, watcher);
+}
+
+void RGWRealmWatcher::handle_notify(uint64_t notify_id, uint64_t cookie,
+                                    uint64_t notifier_id, bufferlist& bl)
+{
+  if (cookie != watch_handle)
+    return;
+
+  // send an empty notify ack
+  bufferlist reply;
+  pool_ctx.notify_ack(watch_oid, notify_id, cookie, reply);
+
+  try {
+    auto p = bl.begin();
+    while (!p.end()) {
+      RGWRealmNotify notify;
+      ::decode(notify, p);
+      auto watcher = watchers.find(notify);
+      if (watcher == watchers.end()) {
+        lderr(cct) << "Failed to find a watcher for notify type "
+            << static_cast<int>(notify) << dendl;
+        break;
+      }
+      watcher->second.handle_notify(notify, p);
+    }
+  } catch (const buffer::error &e) {
+    lderr(cct) << "Failed to decode realm notifications." << dendl;
+  }
+}
+
+void RGWRealmWatcher::handle_error(uint64_t cookie, int err)
+{
+  if (cookie != watch_handle)
+    return;
+
+  if (err == -ENOTCONN) {
+    ldout(cct, 4) << "Disconnected watch on " << watch_oid << dendl;
+    watch_restart();
+  }
+}
+
+int RGWRealmWatcher::watch_start(RGWRealm& realm)
+{
+  // initialize a Rados client
+  int r = rados.init_with_context(cct);
+  if (r < 0) {
+    lderr(cct) << "Rados client initialization failed with "
+        << cpp_strerror(-r) << dendl;
+    return r;
+  }
+  r = rados.connect();
+  if (r < 0) {
+    lderr(cct) << "Rados client connection failed with "
+        << cpp_strerror(-r) << dendl;
+    return r;
+  }
+
+  // open an IoCtx for the realm's pool
+  auto pool = realm.get_pool_name(cct);
+  r = rados.ioctx_create(pool.c_str(), pool_ctx);
+  if (r < 0) {
+    lderr(cct) << "Failed to open pool " << pool
+        << " with " << cpp_strerror(-r) << dendl;
+    rados.shutdown();
+    return r;
+  }
+
+  // register a watch on the realm's control object
+  auto oid = realm.get_control_oid();
+  r = pool_ctx.watch2(oid, &watch_handle, this);
+  if (r < 0) {
+    lderr(cct) << "Failed to watch " << oid
+        << " with " << cpp_strerror(-r) << dendl;
+    pool_ctx.close();
+    rados.shutdown();
+    return r;
+  }
+
+  ldout(cct, 10) << "Watching " << oid << dendl;
+  std::swap(watch_oid, oid);
+  return 0;
+}
+
+int RGWRealmWatcher::watch_restart()
+{
+  assert(!watch_oid.empty());
+  int r = pool_ctx.watch2(watch_oid, &watch_handle, this);
+  if (r < 0)
+    lderr(cct) << "Failed to restart watch on " << watch_oid
+        << " with " << cpp_strerror(-r) << dendl;
+  return r;
+}
+
+void RGWRealmWatcher::watch_stop()
+{
+  if (!watch_oid.empty()) {
+    pool_ctx.unwatch2(watch_handle);
+    pool_ctx.close();
+    watch_oid.clear();
+  }
+}
diff --git a/src/rgw/rgw_realm_watcher.h b/src/rgw/rgw_realm_watcher.h
new file mode 100644
index 0000000..b43501e
--- /dev/null
+++ b/src/rgw/rgw_realm_watcher.h
@@ -0,0 +1,69 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+
+#ifndef RGW_REALM_WATCHER_H
+#define RGW_REALM_WATCHER_H
+
+#include "include/rados/librados.hpp"
+#include "include/assert.h"
+#include "common/Timer.h"
+#include "common/Cond.h"
+
+class RGWRados;
+class RGWRealm;
+
+enum class RGWRealmNotify {
+  Reload,
+  ZonesNeedPeriod,
+};
+WRITE_RAW_ENCODER(RGWRealmNotify);
+
+/**
+ * RGWRealmWatcher establishes a watch on the current RGWRealm's control object,
+ * and forwards notifications to registered observers.
+ */
+class RGWRealmWatcher : public librados::WatchCtx2 {
+ public:
+  /**
+   * Watcher is an interface that allows the RGWRealmWatcher to pass
+   * notifications on to other interested objects.
+   */
+  class Watcher {
+   public:
+    virtual ~Watcher() = default;
+
+    virtual void handle_notify(RGWRealmNotify type,
+                               bufferlist::iterator& p) = 0;
+  };
+
+  RGWRealmWatcher(CephContext* cct, RGWRealm& realm);
+  ~RGWRealmWatcher();
+
+  /// register a watcher for the given notification type
+  void add_watcher(RGWRealmNotify type, Watcher& watcher);
+
+  /// respond to realm notifications by calling the appropriate watcher
+  void handle_notify(uint64_t notify_id, uint64_t cookie,
+                     uint64_t notifier_id, bufferlist& bl) override;
+
+  /// reestablish the watch if it gets disconnected
+  void handle_error(uint64_t cookie, int err) override;
+
+ private:
+  CephContext *const cct;
+
+  /// keep a separate Rados client whose lifetime is independent of RGWRados
+  /// so that we don't miss notifications during realm reconfiguration
+  librados::Rados rados;
+  librados::IoCtx pool_ctx;
+  uint64_t watch_handle;
+  std::string watch_oid;
+
+  int watch_start(RGWRealm& realm);
+  int watch_restart();
+  void watch_stop();
+
+  std::map<RGWRealmNotify, Watcher&> watchers;
+};
+
+#endif // RGW_REALM_WATCHER_H
diff --git a/src/rgw/rgw_request.cc b/src/rgw/rgw_request.cc
new file mode 100644
index 0000000..ed5335f
--- /dev/null
+++ b/src/rgw/rgw_request.cc
@@ -0,0 +1,37 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+
+#include "rgw_op.h"
+#include "rgw_request.h"
+
+#define dout_subsys ceph_subsys_rgw
+
+/* XXX */
+void RGWRequest::log_format(struct req_state *s, const char *fmt, ...)
+{
+#define LARGE_SIZE 1024
+  char buf[LARGE_SIZE];
+  va_list ap;
+
+  va_start(ap, fmt);
+  vsnprintf(buf, sizeof(buf), fmt, ap);
+  va_end(ap);
+
+  log(s, buf);
+} /* RGWRequest::log_format */
+
+void RGWRequest::log_init() {
+  ts = ceph_clock_now(g_ceph_context);
+}
+
+void RGWRequest::log(struct req_state *s, const char *msg) {
+  if (s->info.method && req_str.size() == 0) {
+    req_str = s->info.method;
+    req_str.append(" ");
+    req_str.append(s->info.request_uri);
+  }
+  utime_t t = ceph_clock_now(g_ceph_context) - ts;
+  dout(2) << "req " << id << ":" << t << ":" << s->dialect << ":"
+	  << req_str << ":" << (op ? op->name() : "") << ":" << msg
+	  << dendl;
+}
diff --git a/src/rgw/rgw_request.h b/src/rgw/rgw_request.h
new file mode 100644
index 0000000..29060d0
--- /dev/null
+++ b/src/rgw/rgw_request.h
@@ -0,0 +1,64 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+
+#ifndef RGW_REQUEST_H
+#define RGW_REQUEST_H
+
+#include "rgw_common.h"
+#include "rgw_rados.h"
+#include "rgw_acl.h"
+#include "rgw_user.h"
+#include "rgw_op.h"
+#include "rgw_fcgi.h"
+
+#include "common/QueueRing.h"
+
+struct RGWRequest
+{
+  uint64_t id;
+  struct req_state *s;
+  string req_str;
+  RGWOp *op;
+  utime_t ts;
+
+  explicit RGWRequest(uint64_t id) : id(id), s(NULL), op(NULL) {}
+
+  virtual ~RGWRequest() {}
+
+  void init_state(req_state *_s) {
+    s = _s;
+  }
+
+  void log_format(struct req_state *s, const char *fmt, ...);
+  void log_init();
+  void log(struct req_state *s, const char *msg);
+}; /* RGWRequest */
+
+struct RGWFCGXRequest : public RGWRequest {
+  FCGX_Request *fcgx;
+  QueueRing<FCGX_Request *> *qr;
+
+  RGWFCGXRequest(uint64_t req_id, QueueRing<FCGX_Request *> *_qr)
+	  : RGWRequest(req_id), qr(_qr) {
+    qr->dequeue(&fcgx);
+  }
+
+  ~RGWFCGXRequest() {
+    FCGX_Finish_r(fcgx);
+    qr->enqueue(fcgx);
+  }
+};
+
+struct RGWLoadGenRequest : public RGWRequest {
+	string method;
+	string resource;
+	int content_length;
+	atomic_t* fail_flag;
+
+RGWLoadGenRequest(uint64_t req_id, const string& _m, const  string& _r, int _cl,
+		atomic_t *ff)
+	: RGWRequest(req_id), method(_m), resource(_r), content_length(_cl),
+		fail_flag(ff) {}
+};
+
+#endif /* RGW_REQUEST_H */
diff --git a/src/rgw/rgw_rest.cc b/src/rgw/rgw_rest.cc
index 0097295..b60999f 100644
--- a/src/rgw/rgw_rest.cc
+++ b/src/rgw/rgw_rest.cc
@@ -18,6 +18,7 @@
 #include "rgw_swift_auth.h"
 #include "rgw_cors_s3.h"
 #include "rgw_http_errors.h"
+#include "rgw_lib.h"
 
 #include "rgw_client_io.h"
 #include "rgw_resolve.h"
@@ -172,8 +173,10 @@ string camelcase_dash_http_attr(const string& orig)
 static set<string> hostnames_set;
 static set<string> hostnames_s3website_set;
 
-void rgw_rest_init(CephContext *cct, RGWRegion& region)
+void rgw_rest_init(CephContext *cct, RGWRados *store, RGWZoneGroup& zone_group)
 {
+  store->init_host_id();
+
   for (const auto& rgw2http : base_rgw_to_http_attrs)  {
     rgw_to_http_attrs[rgw2http.rgw_attr] = rgw2http.http_attr;
   }
@@ -205,7 +208,7 @@ void rgw_rest_init(CephContext *cct, RGWRegion& region)
   if (!cct->_conf->rgw_dns_name.empty()) {
     hostnames_set.insert(cct->_conf->rgw_dns_name);
   }
-  hostnames_set.insert(region.hostnames.begin(),  region.hostnames.end());
+  hostnames_set.insert(zone_group.hostnames.begin(),  zone_group.hostnames.end());
   string s;
   ldout(cct, 20) << "RGW hostnames: " << std::accumulate(hostnames_set.begin(), hostnames_set.end(), s) << dendl;
   /* TODO: We should have a sanity check that no hostname matches the end of
@@ -221,7 +224,7 @@ void rgw_rest_init(CephContext *cct, RGWRegion& region)
   if (!cct->_conf->rgw_dns_s3website_name.empty()) {
     hostnames_s3website_set.insert(cct->_conf->rgw_dns_s3website_name);
   }
-  hostnames_s3website_set.insert(region.hostnames_s3website.begin(), region.hostnames_s3website.end());
+  hostnames_s3website_set.insert(zone_group.hostnames_s3website.begin(), zone_group.hostnames_s3website.end());
   s.clear();
   ldout(cct, 20) << "RGW S3website hostnames: " << std::accumulate(hostnames_s3website_set.begin(), hostnames_s3website_set.end(), s) << dendl;
   /* TODO: we should repeat the hostnames_set sanity check here
@@ -261,7 +264,7 @@ static bool rgw_find_host_in_domains(const string& host, string *domain, string
       subdomain->clear();
     } else {
       if (host[pos - 1] != '.') {
-        continue;
+	continue;
       }
 
       *domain = host.substr(pos);
@@ -272,12 +275,14 @@ static bool rgw_find_host_in_domains(const string& host, string *domain, string
   return false;
 }
 
-static void dump_status(struct req_state *s, int status, const char *status_name)
+static void dump_status(struct req_state *s, int status,
+			const char *status_name)
 {
   s->formatter->set_status(status, status_name);
-  int r = s->cio->send_status(status, status_name);
+  int r = STREAM_IO(s)->send_status(status, status_name);
   if (r < 0) {
-    ldout(s->cct, 0) << "ERROR: s->cio->send_status() returned err=" << r << dendl;
+    ldout(s->cct, 0) << "ERROR: s->cio->send_status() returned err=" << r
+		     << dendl;
   }
 }
 
@@ -288,7 +293,7 @@ void rgw_flush_formatter_and_reset(struct req_state *s, Formatter *formatter)
   formatter->flush(oss);
   std::string outs(oss.str());
   if (!outs.empty() && s->op != OP_HEAD) {
-    s->cio->write(outs.c_str(), outs.size());
+    STREAM_IO(s)->write(outs.c_str(), outs.size());
   }
 
   s->formatter->reset();
@@ -300,7 +305,7 @@ void rgw_flush_formatter(struct req_state *s, Formatter *formatter)
   formatter->flush(oss);
   std::string outs(oss.str());
   if (!outs.empty() && s->op != OP_HEAD) {
-    s->cio->write(outs.c_str(), outs.size());
+    STREAM_IO(s)->write(outs.c_str(), outs.size());
   }
 }
 
@@ -314,7 +319,8 @@ void set_req_state_err(struct rgw_err& err,     /* out */
     err_no = -err_no;
   err.ret = -err_no;
   if (prot_flags & RGW_REST_SWIFT) {
-    r = search_err(err_no, RGW_HTTP_SWIFT_ERRORS, ARRAY_LEN(RGW_HTTP_SWIFT_ERRORS));
+    r = search_err(err_no, RGW_HTTP_SWIFT_ERRORS,
+		   ARRAY_LEN(RGW_HTTP_SWIFT_ERRORS));
     if (r) {
       err.http_ret = r->http_ret;
       err.s3_code = r->s3_code;
@@ -332,7 +338,8 @@ void set_req_state_err(struct rgw_err& err,     /* out */
     err.s3_code = r->s3_code;
     return;
   }
-  dout(0) << "WARNING: set_req_state_err err_no=" << err_no << " resorting to 500" << dendl;
+  dout(0) << "WARNING: set_req_state_err err_no=" << err_no
+	  << " resorting to 500" << dendl;
 
   err.http_ret = 500;
   err.s3_code = "UnknownError";
@@ -368,7 +375,7 @@ void dump_errno(struct req_state *s, int http_ret)
 
 void dump_string_header(struct req_state *s, const char *name, const char *val)
 {
-  int r = s->cio->print("%s: %s\r\n", name, val);
+  int r = STREAM_IO(s)->print("%s: %s\r\n", name, val);
   if (r < 0) {
     ldout(s->cct, 0) << "ERROR: s->cio->print() returned err=" << r << dendl;
   }
@@ -376,12 +383,12 @@ void dump_string_header(struct req_state *s, const char *name, const char *val)
 
 void dump_content_length(struct req_state *s, uint64_t len)
 {
-  int r = s->cio->send_content_length(len);
+  int r = STREAM_IO(s)->send_content_length(len);
   if (r < 0) {
     ldout(s->cct, 0) << "ERROR: s->cio->send_content_length() returned err="
                      << r << dendl;
   }
-  r = s->cio->print("Accept-Ranges: bytes\r\n");
+  r = STREAM_IO(s)->print("Accept-Ranges: bytes\r\n");
   if (r < 0) {
     ldout(s->cct, 0) << "ERROR: s->cio->print() returned err=" << r << dendl;
   }
@@ -395,11 +402,10 @@ void dump_etag(struct req_state * const s, const char * const etag)
 
   int r;
   if (s->prot_flags & RGW_REST_SWIFT) {
-    r = s->cio->print("etag: %s\r\n", etag);
+    r = STREAM_IO(s)->print("etag: %s\r\n", etag);
   } else {
-    r = s->cio->print("ETag: \"%s\"\r\n", etag);
+    r = STREAM_IO(s)->print("ETag: \"%s\"\r\n", etag);
   }
-
   if (r < 0) {
     ldout(s->cct, 0) << "ERROR: s->cio->print() returned err=" << r << dendl;
   }
@@ -408,7 +414,7 @@ void dump_etag(struct req_state * const s, const char * const etag)
 void dump_pair(struct req_state *s, const char *key, const char *value)
 {
   if ( (strlen(key) > 0) && (strlen(value) > 0))
-    s->cio->print("%s: %s\r\n", key, value);
+    STREAM_IO(s)->print("%s: %s\r\n", key, value);
 }
 
 void dump_bucket_from_state(struct req_state *s)
@@ -423,7 +429,7 @@ void dump_bucket_from_state(struct req_state *s)
       } else {
         url_encode(s->bucket_name, b);
       }
-      s->cio->print("Bucket: %s\r\n", b.c_str());
+      STREAM_IO(s)->print("Bucket: %s\r\n", b.c_str());
     }
   }
 }
@@ -444,13 +450,13 @@ void dump_uri_from_state(struct req_state *s)
       location += s->bucket_name;
       location += "/";
       if (!s->object.empty()) {
-        location += s->object.name;
-        s->cio->print("Location: %s\r\n", location.c_str());
+	location += s->object.name;
+	STREAM_IO(s)->print("Location: %s\r\n", location.c_str());
       }
     }
   }
   else {
-    s->cio->print("Location: \"%s\"\r\n", s->info.request_uri.c_str());
+    STREAM_IO(s)->print("Location: \"%s\"\r\n", s->info.request_uri.c_str());
   }
 }
 
@@ -459,58 +465,69 @@ void dump_redirect(struct req_state *s, const string& redirect)
   if (redirect.empty())
     return;
 
-  s->cio->print("Location: %s\r\n", redirect.c_str());
+  STREAM_IO(s)->print("Location: %s\r\n", redirect.c_str());
 }
 
-void dump_time_header(struct req_state *s, const char *name, time_t t)
+void dump_time_header(struct req_state *s, const char *name, real_time t)
 {
+  utime_t ut(t);
+  time_t secs = (time_t)ut.sec();
 
   char timestr[TIME_BUF_SIZE];
   struct tm result;
-  struct tm *tmp = gmtime_r(&t, &result);
+  struct tm *tmp = gmtime_r(&secs, &result);
   if (tmp == NULL)
     return;
 
   if (strftime(timestr, sizeof(timestr), "%a, %d %b %Y %H:%M:%S %Z", tmp) == 0)
     return;
 
-  int r = s->cio->print("%s: %s\r\n", name, timestr);
+  int r = STREAM_IO(s)->print("%s: %s\r\n", name, timestr);
   if (r < 0) {
     ldout(s->cct, 0) << "ERROR: s->cio->print() returned err=" << r << dendl;
   }
 }
 
-void dump_last_modified(struct req_state *s, time_t t)
+void dump_last_modified(struct req_state *s, real_time t)
 {
   dump_time_header(s, "Last-Modified", t);
 }
 
-void dump_epoch_header(struct req_state *s, const char *name, time_t t)
+void dump_epoch_header(struct req_state *s, const char *name, real_time t)
 {
-  char buf[32];
-  snprintf(buf, sizeof(buf), "%lld", (long long)t);
+  utime_t ut(t);
+  char sec_buf[32], nsec_buf[32];
+  snprintf(sec_buf, sizeof(sec_buf), "%lld", (long long)ut.sec());
+  snprintf(nsec_buf, sizeof(nsec_buf), "%09lld", (long long)ut.nsec());
 
-  int r = s->cio->print("%s: %s\r\n", name, buf);
+  int r = STREAM_IO(s)->print("%s: %s.%s\r\n", name, sec_buf, nsec_buf);
   if (r < 0) {
     ldout(s->cct, 0) << "ERROR: s->cio->print() returned err=" << r << dendl;
   }
 }
 
-void dump_time(struct req_state *s, const char *name, time_t *t)
+void dump_time(struct req_state *s, const char *name, real_time *t)
 {
+  utime_t ut(*t);
+
   char buf[TIME_BUF_SIZE];
   struct tm result;
-  struct tm *tmp = gmtime_r(t, &result);
+  time_t epoch = ut.sec();
+  struct tm *tmp = gmtime_r(&epoch, &result);
   if (tmp == NULL)
     return;
 
-  if (strftime(buf, sizeof(buf), "%Y-%m-%dT%T.000Z", tmp) == 0)
+  if (strftime(buf, sizeof(buf), "%Y-%m-%dT%T", tmp) == 0)
     return;
 
-  s->formatter->dump_string(name, buf);
+  char buf2[TIME_BUF_SIZE];
+  snprintf(buf2, sizeof(buf2), "%s.%03dZ", buf, (int)(ut.usec() / 1000));
+
+  s->formatter->dump_string(name, buf2);
 }
 
-void dump_owner(struct req_state *s, rgw_user& id, string& name, const char *section)
+void dump_owner(struct req_state *s, rgw_user& id, string& name,
+		const char *section)
 {
   if (!section)
     section = "Owner";
@@ -520,19 +537,21 @@ void dump_owner(struct req_state *s, rgw_user& id, string& name, const char *sec
   s->formatter->close_section();
 }
 
-void dump_access_control(struct req_state *s, const char *origin, const char *meth,
-                         const char *hdr, const char *exp_hdr, uint32_t max_age) {
+void dump_access_control(struct req_state *s, const char *origin,
+			 const char *meth,
+			 const char *hdr, const char *exp_hdr,
+			 uint32_t max_age) {
   if (origin && (origin[0] != '\0')) {
-    s->cio->print("Access-Control-Allow-Origin: %s\r\n", origin);
+    STREAM_IO(s)->print("Access-Control-Allow-Origin: %s\r\n", origin);
     if (meth && (meth[0] != '\0'))
-      s->cio->print("Access-Control-Allow-Methods: %s\r\n", meth);
+      STREAM_IO(s)->print("Access-Control-Allow-Methods: %s\r\n", meth);
     if (hdr && (hdr[0] != '\0'))
-      s->cio->print("Access-Control-Allow-Headers: %s\r\n", hdr);
+      STREAM_IO(s)->print("Access-Control-Allow-Headers: %s\r\n", hdr);
     if (exp_hdr && (exp_hdr[0] != '\0')) {
-      s->cio->print("Access-Control-Expose-Headers: %s\r\n", exp_hdr);
+      STREAM_IO(s)->print("Access-Control-Expose-Headers: %s\r\n", exp_hdr);
     }
     if (max_age != CORS_MAX_AGE_INVALID) {
-      s->cio->print("Access-Control-Max-Age: %d\r\n", max_age);
+      STREAM_IO(s)->print("Access-Control-Max-Age: %d\r\n", max_age);
     }
   }
 }
@@ -548,7 +567,8 @@ void dump_access_control(req_state *s, RGWOp *op)
   if (!op->generate_cors_headers(origin, method, header, exp_header, &max_age))
     return;
 
-  dump_access_control(s, origin.c_str(), method.c_str(), header.c_str(), exp_header.c_str(), max_age);
+  dump_access_control(s, origin.c_str(), method.c_str(), header.c_str(),
+		      exp_header.c_str(), max_age);
 }
 
 void dump_start(struct req_state *s)
@@ -562,24 +582,25 @@ void dump_start(struct req_state *s)
 void dump_trans_id(req_state *s)
 {
   if (s->prot_flags & RGW_REST_SWIFT) {
-    s->cio->print("X-Trans-Id: %s\r\n", s->trans_id.c_str());
+    STREAM_IO(s)->print("X-Trans-Id: %s\r\n", s->trans_id.c_str());
   }
   else {
-    s->cio->print("x-amz-request-id: %s\r\n", s->trans_id.c_str());
+    STREAM_IO(s)->print("x-amz-request-id: %s\r\n", s->trans_id.c_str());
   }
 }
 
-void end_header(struct req_state *s, RGWOp *op, const char *content_type, const int64_t proposed_content_length,
-		bool force_content_type, bool force_no_error)
+void end_header(struct req_state* s, RGWOp* op, const char *content_type,
+		const int64_t proposed_content_length, bool force_content_type,
+		bool force_no_error)
 {
   string ctype;
 
   dump_trans_id(s);
 
   if ((!s->err.is_err()) &&
-      (s->bucket_info.owner != s->user.user_id) &&
+      (s->bucket_info.owner != s->user->user_id) &&
       (s->bucket_info.requester_pays)) {
-    s->cio->print("x-amz-request-charged: requester\r\n");
+    STREAM_IO(s)->print("x-amz-request-charged: requester\r\n");
   }
 
   if (op) {
@@ -592,7 +613,8 @@ void end_header(struct req_state *s, RGWOp *op, const char *content_type, const
 
   /* do not send content type if content length is zero
      and the content type was not set by the user */
-  if (force_content_type || (!content_type &&  s->formatter->get_len()  != 0) || s->err.is_err()){
+  if (force_content_type ||
+      (!content_type &&  s->formatter->get_len()  != 0) || s->err.is_err()){
     switch (s->format) {
     case RGW_FORMAT_XML:
       ctype = "application/xml";
@@ -624,7 +646,7 @@ void end_header(struct req_state *s, RGWOp *op, const char *content_type, const
       s->formatter->dump_string("BucketName", s->bucket_name);
     if (!s->trans_id.empty()) // TODO: connect to expose_bucket or another toggle
       s->formatter->dump_string("RequestId", s->trans_id);
-    s->formatter->dump_string("HostId", "FIXME-TODO-How-does-amazon-generate-HostId"); // TODO, FIXME
+    s->formatter->dump_string("HostId", s->host_id);
     if (s->format != RGW_FORMAT_HTML) {
       s->formatter->close_section();
     }
@@ -638,21 +660,24 @@ void end_header(struct req_state *s, RGWOp *op, const char *content_type, const
 
   int r;
   if (content_type) {
-      r = s->cio->print("Content-Type: %s\r\n", content_type);
+      r = STREAM_IO(s)->print("Content-Type: %s\r\n", content_type);
       if (r < 0) {
-	ldout(s->cct, 0) << "ERROR: s->cio->print() returned err=" << r << dendl;
+	ldout(s->cct, 0) << "ERROR: STREAM_IO(s)->print() returned err=" << r
+			 << dendl;
       }
   }
-  r = s->cio->complete_header();
+  r = STREAM_IO(s)->complete_header();
   if (r < 0) {
-    ldout(s->cct, 0) << "ERROR: s->cio->complete_header() returned err=" << r << dendl;
+    ldout(s->cct, 0) << "ERROR: STREAM_IO(s)->complete_header() returned err="
+		     << r << dendl;
   }
 
-  s->cio->set_account(true);
+  STREAM_IO(s)->set_account(true);
   rgw_flush_formatter_and_reset(s, s->formatter);
 }
 
-void abort_early(struct req_state *s, RGWOp *op, int err_no, RGWHandler* handler)
+void abort_early(struct req_state *s, RGWOp *op, int err_no,
+		 RGWHandler* handler)
 {
   string error_content("");
   if (!s->formatter) {
@@ -664,12 +689,14 @@ void abort_early(struct req_state *s, RGWOp *op, int err_no, RGWHandler* handler
   if (op != NULL) {
     int new_err_no;
     new_err_no = op->error_handler(err_no, &error_content);
-    ldout(s->cct, 20) << "op->ERRORHANDLER: err_no=" << err_no << " new_err_no=" << new_err_no << dendl;
+    ldout(s->cct, 20) << "op->ERRORHANDLER: err_no=" << err_no
+		      << " new_err_no=" << new_err_no << dendl;
     err_no = new_err_no;
   } else if (handler != NULL) {
     int new_err_no;
     new_err_no = handler->error_handler(err_no, &error_content);
-    ldout(s->cct, 20) << "handler->ERRORHANDLER: err_no=" << err_no << " new_err_no=" << new_err_no << dendl;
+    ldout(s->cct, 20) << "handler->ERRORHANDLER: err_no=" << err_no
+		      << " new_err_no=" << new_err_no << dendl;
     err_no = new_err_no;
   }
   set_req_state_err(s, err_no);
@@ -679,8 +706,8 @@ void abort_early(struct req_state *s, RGWOp *op, int err_no, RGWHandler* handler
     string dest_uri;
     if (!s->redirect.empty()) {
       dest_uri = s->redirect;
-    } else if (!s->region_endpoint.empty()) {
-      string dest_uri = s->region_endpoint;
+    } else if (!s->zonegroup_endpoint.empty()) {
+      string dest_uri = s->zonegroup_endpoint;
       /*
        * reqest_uri is always start with slash, so we need to remove
        * the unnecessary slash at the end of dest_uri.
@@ -698,17 +725,19 @@ void abort_early(struct req_state *s, RGWOp *op, int err_no, RGWHandler* handler
     }
   }
   if (!error_content.empty()) {
-    ldout(s->cct, 20) << "error_content is set, we need to serve it INSTEAD of firing the formatter" << dendl;
+    ldout(s->cct, 20) << "error_content is set, we need to serve it INSTEAD"
+      " of firing the formatter" << dendl;
     /*
      * FIXME we must add all error entries as headers here:
-     * when having a working errordoc, then the s3 error fields are rendered as HTTP headers, e.g.:
+     * when having a working errordoc, then the s3 error fields are
+     * rendered as HTTP headers, e.g.:
      *
      *   x-amz-error-code: NoSuchKey
      *   x-amz-error-message: The specified key does not exist.
      *   x-amz-error-detail-Key: foo
      */
     end_header(s, op, NULL, NO_CONTENT_LENGTH, false, true);
-    s->cio->write(error_content.c_str(), error_content.size());
+    STREAM_IO(s)->write(error_content.c_str(), error_content.size());
     s->formatter->reset();
   } else {
     end_header(s, op);
@@ -719,16 +748,19 @@ void abort_early(struct req_state *s, RGWOp *op, int err_no, RGWHandler* handler
 
 void dump_continue(struct req_state *s)
 {
-  s->cio->send_100_continue();
+  STREAM_IO(s)->send_100_continue();
 }
 
-void dump_range(struct req_state *s, uint64_t ofs, uint64_t end, uint64_t total)
+void dump_range(struct req_state *s, uint64_t ofs, uint64_t end,
+		uint64_t total)
 {
   char range_buf[128];
 
-  /* dumping range into temp buffer first, as libfcgi will fail to digest %lld */
-  snprintf(range_buf, sizeof(range_buf), "%lld-%lld/%lld", (long long)ofs, (long long)end, (long long)total);
-  int r = s->cio->print("Content-Range: bytes %s\r\n", range_buf);
+  /* dumping range into temp buffer first, as libfcgi will fail to digest
+   * %lld */
+  snprintf(range_buf, sizeof(range_buf), "%lld-%lld/%lld", (long long)ofs,
+	   (long long)end, (long long)total);
+  int r = STREAM_IO(s)->print("Content-Range: bytes %s\r\n", range_buf);
   if (r < 0) {
     ldout(s->cct, 0) << "ERROR: s->cio->print() returned err=" << r << dendl;
   }
@@ -742,10 +774,16 @@ int RGWGetObj_ObjStore::get_params()
   if_match = s->info.env->get("HTTP_IF_MATCH");
   if_nomatch = s->info.env->get("HTTP_IF_NONE_MATCH");
 
+  if (s->system_request) {
+    mod_zone_id = s->info.env->get_int("HTTP_DEST_ZONE_SHORT_ID", 0);
+    mod_pg_ver = s->info.env->get_int("HTTP_DEST_PG_VER", 0);
+  }
+
   return 0;
 }
 
-int RESTArgs::get_string(struct req_state *s, const string& name, const string& def_val, string *val, bool *existed)
+int RESTArgs::get_string(struct req_state *s, const string& name,
+			 const string& def_val, string *val, bool *existed)
 {
   bool exists;
   *val = s->info.args.get(name, &exists);
@@ -761,7 +799,8 @@ int RESTArgs::get_string(struct req_state *s, const string& name, const string&
   return 0;
 }
 
-int RESTArgs::get_uint64(struct req_state *s, const string& name, uint64_t def_val, uint64_t *val, bool *existed)
+int RESTArgs::get_uint64(struct req_state *s, const string& name,
+			 uint64_t def_val, uint64_t *val, bool *existed)
 {
   bool exists;
   string sval = s->info.args.get(name, &exists);
@@ -781,7 +820,8 @@ int RESTArgs::get_uint64(struct req_state *s, const string& name, uint64_t def_v
   return 0;
 }
 
-int RESTArgs::get_int64(struct req_state *s, const string& name, int64_t def_val, int64_t *val, bool *existed)
+int RESTArgs::get_int64(struct req_state *s, const string& name,
+			int64_t def_val, int64_t *val, bool *existed)
 {
   bool exists;
   string sval = s->info.args.get(name, &exists);
@@ -801,7 +841,8 @@ int RESTArgs::get_int64(struct req_state *s, const string& name, int64_t def_val
   return 0;
 }
 
-int RESTArgs::get_uint32(struct req_state *s, const string& name, uint32_t def_val, uint32_t *val, bool *existed)
+int RESTArgs::get_uint32(struct req_state *s, const string& name,
+			 uint32_t def_val, uint32_t *val, bool *existed)
 {
   bool exists;
   string sval = s->info.args.get(name, &exists);
@@ -821,7 +862,8 @@ int RESTArgs::get_uint32(struct req_state *s, const string& name, uint32_t def_v
   return 0;
 }
 
-int RESTArgs::get_int32(struct req_state *s, const string& name, int32_t def_val, int32_t *val, bool *existed)
+int RESTArgs::get_int32(struct req_state *s, const string& name,
+			int32_t def_val, int32_t *val, bool *existed)
 {
   bool exists;
   string sval = s->info.args.get(name, &exists);
@@ -841,7 +883,8 @@ int RESTArgs::get_int32(struct req_state *s, const string& name, int32_t def_val
   return 0;
 }
 
-int RESTArgs::get_time(struct req_state *s, const string& name, const utime_t& def_val, utime_t *val, bool *existed)
+int RESTArgs::get_time(struct req_state *s, const string& name,
+		       const utime_t& def_val, utime_t *val, bool *existed)
 {
   bool exists;
   string sval = s->info.args.get(name, &exists);
@@ -968,10 +1011,13 @@ int RGWPutObj_ObjStore::get_data(bufferlist& bl)
     bufferptr bp(cl);
 
     int read_len; /* cio->read() expects int * */
-    int r = s->cio->read(bp.c_str(), cl, &read_len);
-    len = read_len;
-    if (r < 0)
+    int r = STREAM_IO(s)->read(bp.c_str(), cl, &read_len,
+                               s->aws4_auth_needs_complete);
+    if (r < 0) {
       return r;
+    }
+
+    len = read_len;
     bl.append(bp, 0, len);
   }
 
@@ -1013,7 +1059,7 @@ int RGWPutACLs_ObjStore::get_params()
        return op_ret;
     }
     int read_len;
-    int r = s->cio->read(data, cl, &read_len);
+    int r = STREAM_IO(s)->read(data, cl, &read_len, s->aws4_auth_needs_complete);
     len = read_len;
     if (r < 0)
       return r;
@@ -1025,7 +1071,8 @@ int RGWPutACLs_ObjStore::get_params()
   return op_ret;
 }
 
-static int read_all_chunked_input(req_state *s, char **pdata, int *plen, int max_read)
+static int read_all_chunked_input(req_state *s, char **pdata, int *plen,
+				  int max_read)
 {
 #define READ_CHUNK 4096
 #define MAX_READ_CHUNK (128 * 1024)
@@ -1037,7 +1084,7 @@ static int read_all_chunked_input(req_state *s, char **pdata, int *plen, int max
 
   int read_len = 0, len = 0;
   do {
-    int r = s->cio->read(data + len, need_to_read, &read_len);
+    int r = STREAM_IO(s)->read(data + len, need_to_read, &read_len, s->aws4_auth_needs_complete);
     if (r < 0) {
       free(data);
       return r;
@@ -1050,15 +1097,15 @@ static int read_all_chunked_input(req_state *s, char **pdata, int *plen, int max
 	need_to_read *= 2;
 
       if (total > max_read) {
-        free(data);
-        return -ERANGE;
+	free(data);
+	return -ERANGE;
       }
       total += need_to_read;
 
       void *p = realloc(data, total + 1);
       if (!p) {
-        free(data);
-        return -ENOMEM;
+	free(data);
+	return -ENOMEM;
       }
       data = (char *)p;
     } else {
@@ -1074,7 +1121,8 @@ static int read_all_chunked_input(req_state *s, char **pdata, int *plen, int max
   return 0;
 }
 
-int rgw_rest_read_all_input(struct req_state *s, char **pdata, int *plen, int max_len)
+int rgw_rest_read_all_input(struct req_state *s, char **pdata, int *plen,
+			    int max_len)
 {
   size_t cl = 0;
   int len = 0;
@@ -1090,7 +1138,7 @@ int rgw_rest_read_all_input(struct req_state *s, char **pdata, int *plen, int ma
     if (!data) {
        return -ENOMEM;
     }
-    int ret = s->cio->read(data, cl, &len);
+    int ret = STREAM_IO(s)->read(data, cl, &len, s->aws4_auth_needs_complete);
     if (ret < 0) {
       free(data);
       return ret;
@@ -1112,7 +1160,6 @@ int rgw_rest_read_all_input(struct req_state *s, char **pdata, int *plen, int ma
   return 0;
 }
 
-
 int RGWCompleteMultipart_ObjStore::get_params()
 {
   upload_id = s->info.args.get("uploadId");
@@ -1196,7 +1243,7 @@ int RGWDeleteMultiObj_ObjStore::get_params()
       return op_ret;
     }
     int read_len;
-    op_ret = s->cio->read(data, cl, &read_len);
+    op_ret = STREAM_IO(s)->read(data, cl, &read_len, s->aws4_auth_needs_complete);
     len = read_len;
     if (op_ret < 0)
       return op_ret;
@@ -1221,11 +1268,52 @@ void RGWRESTOp::send_response()
 
 int RGWRESTOp::verify_permission()
 {
-  return check_caps(s->user.caps);
+  return check_caps(s->user->caps);
 }
 
+RGWOp* RGWHandler_REST::get_op(RGWRados* store)
+{
+  RGWOp *op;
+  switch (s->op) {
+   case OP_GET:
+     op = op_get();
+     break;
+   case OP_PUT:
+     op = op_put();
+     break;
+   case OP_DELETE:
+     op = op_delete();
+     break;
+   case OP_HEAD:
+     op = op_head();
+     break;
+   case OP_POST:
+     op = op_post();
+     break;
+   case OP_COPY:
+     op = op_copy();
+     break;
+   case OP_OPTIONS:
+     op = op_options();
+     break;
+   default:
+     return NULL;
+  }
+
+  if (op) {
+    op->init(store, s, this);
+  }
+  return op;
+} /* get_op */
 
-int RGWHandler_ObjStore::allocate_formatter(struct req_state *s, int default_type, bool configurable)
+void RGWHandler_REST::put_op(RGWOp* op)
+{
+  delete op;
+} /* put_op */
+
+int RGWHandler_REST::allocate_formatter(struct req_state *s,
+					int default_type,
+					bool configurable)
 {
   s->format = default_type;
   if (configurable) {
@@ -1287,20 +1375,21 @@ int RGWHandler_ObjStore::allocate_formatter(struct req_state *s, int default_typ
   return 0;
 }
 
-int RGWHandler_ObjStore::validate_tenant_name(string const& t)
+int RGWHandler_REST::validate_tenant_name(string const& t)
 {
-  const char *p = t.c_str();
-  for (unsigned int i = 0; i < t.size(); i++) {
-    char ch = p[i];
-    if (!(isalnum(ch) || ch == '_'))
-      return -ERR_INVALID_TENANT_NAME;
-  }
-  return 0;
+  struct tench {
+    static bool is_good(char ch) {
+      return isalnum(ch) || ch == '_';
+    }
+  };
+  std::string::const_iterator it =
+    std::find_if_not(t.begin(), t.end(), tench::is_good);
+  return (it == t.end())? 0: -ERR_INVALID_TENANT_NAME;
 }
 
 // This function enforces Amazon's spec for bucket names.
 // (The requirements, not the recommendations.)
-int RGWHandler_ObjStore::validate_bucket_name(const string& bucket)
+int RGWHandler_REST::validate_bucket_name(const string& bucket)
 {
   int len = bucket.size();
   if (len < 3) {
@@ -1323,7 +1412,7 @@ int RGWHandler_ObjStore::validate_bucket_name(const string& bucket)
 // is at most 1024 bytes long."
 // However, we can still have control characters and other nasties in there.
 // Just as long as they're utf-8 nasties.
-int RGWHandler_ObjStore::validate_object_name(const string& object)
+int RGWHandler_REST::validate_object_name(const string& object)
 {
   int len = object.size();
   if (len > 1024) {
@@ -1360,7 +1449,7 @@ static http_op op_from_method(const char *method)
   return OP_UNKNOWN;
 }
 
-int RGWHandler_ObjStore::init_permissions(RGWOp *op)
+int RGWHandler_REST::init_permissions(RGWOp* op)
 {
   if (op->get_type() == RGW_OP_CREATE_BUCKET)
     return 0;
@@ -1368,7 +1457,7 @@ int RGWHandler_ObjStore::init_permissions(RGWOp *op)
   return do_init_permissions();
 }
 
-int RGWHandler_ObjStore::read_permissions(RGWOp *op_obj)
+int RGWHandler_REST::read_permissions(RGWOp* op_obj)
 {
   bool only_bucket;
 
@@ -1496,7 +1585,8 @@ static int64_t parse_content_length(const char *content_length)
 
   return len;
 }
-int RGWREST::preprocess(struct req_state *s, RGWClientIO *cio)
+
+int RGWREST::preprocess(struct req_state *s, RGWClientIO* cio)
 {
   req_info& info = s->info;
 
@@ -1529,27 +1619,37 @@ int RGWREST::preprocess(struct req_state *s, RGWClientIO *cio)
       << " in_hosted_domain_s3website=" << in_hosted_domain_s3website 
       << dendl;
 
-    if (g_conf->rgw_resolve_cname && !in_hosted_domain && !in_hosted_domain_s3website) {
+    if (g_conf->rgw_resolve_cname
+	&& !in_hosted_domain
+	&& !in_hosted_domain_s3website) {
       string cname;
       bool found;
       int r = rgw_resolver->resolve_cname(info.host, cname, &found);
       if (r < 0) {
-        ldout(s->cct, 0) << "WARNING: rgw_resolver->resolve_cname() returned r=" << r << dendl;
+	ldout(s->cct, 0)
+	  << "WARNING: rgw_resolver->resolve_cname() returned r=" << r
+	  << dendl;
       }
 
       if (found) {
-        ldout(s->cct, 5) << "resolved host cname " << info.host << " -> "
+	ldout(s->cct, 5) << "resolved host cname " << info.host << " -> "
 			 << cname << dendl;
-        in_hosted_domain = rgw_find_host_in_domains(cname, &domain, &subdomain, hostnames_set);
-
-        if (s3website_enabled && !in_hosted_domain_s3website) {
-            in_hosted_domain_s3website = rgw_find_host_in_domains(cname, &s3website_domain, &s3website_subdomain, hostnames_s3website_set);
-	    if (in_hosted_domain_s3website) {
-	      in_hosted_domain = true; // TODO: should hostnames be a strict superset of hostnames_s3website?
-	      domain = s3website_domain;
-	      subdomain = s3website_subdomain;
-	      s->prot_flags |= RGW_REST_WEBSITE;
-	    }
+	in_hosted_domain =
+	  rgw_find_host_in_domains(cname, &domain, &subdomain, hostnames_set);
+
+        if (s3website_enabled
+	    && !in_hosted_domain_s3website) {
+	  in_hosted_domain_s3website =
+	    rgw_find_host_in_domains(cname, &s3website_domain,
+				     &s3website_subdomain,
+				     hostnames_s3website_set);
+	  if (in_hosted_domain_s3website) {
+	    in_hosted_domain = true; // TODO: should hostnames be a
+				     // strict superset of hostnames_s3website?
+	    domain = s3website_domain;
+	    subdomain = s3website_subdomain;
+	    s->prot_flags |= RGW_REST_WEBSITE;
+	  }
         }
 
         ldout(s->cct, 20)
@@ -1592,7 +1692,7 @@ int RGWREST::preprocess(struct req_state *s, RGWClientIO *cio)
    * Ergo if we are in Authorizer role, we MUST look at HTTP_CONTENT_LENGTH
    * instead of CONTENT_LENGTH for the Content-Length.
    *
-   * There is one slight wrinkle in this, and that's older versions of 
+   * There is one slight wrinkle in this, and that's older versions of
    * nginx/lighttpd/apache setting BOTH headers. As a result, we have to check
    * both headers and can't always simply pick A or B.
    */
@@ -1601,7 +1701,8 @@ int RGWREST::preprocess(struct req_state *s, RGWClientIO *cio)
   if (!http_content_length != !content_length) {
     /* Easy case: one or the other is missing */
     s->length = (content_length ? content_length : http_content_length);
-  } else if (s->cct->_conf->rgw_content_length_compat && content_length && http_content_length) {
+  } else if (s->cct->_conf->rgw_content_length_compat &&
+	     content_length && http_content_length) {
     /* Hard case: Both are set, we have to disambiguate */
     int64_t content_length_i, http_content_length_i;
 
@@ -1624,14 +1725,14 @@ int RGWREST::preprocess(struct req_state *s, RGWClientIO *cio)
       }
     }
     s->length = content_length;
-    // End of: else if (s->cct->_conf->rgw_content_length_compat && content_length &&
+    // End of: else if (s->cct->_conf->rgw_content_length_compat &&
+    //   content_length &&
     // http_content_length)
   } else {
     /* no content length was defined */
     s->length = NULL;
   }
 
-
   if (s->length) {
     if (*s->length == '\0') {
       s->content_length = 0;
@@ -1639,8 +1740,8 @@ int RGWREST::preprocess(struct req_state *s, RGWClientIO *cio)
       string err;
       s->content_length = strict_strtoll(s->length, 10, &err);
       if (!err.empty()) {
-        ldout(s->cct, 10) << "bad content length, aborting" << dendl;
-        return -EINVAL;
+	ldout(s->cct, 10) << "bad content length, aborting" << dendl;
+	return -EINVAL;
       }
     }
   }
@@ -1651,7 +1752,8 @@ int RGWREST::preprocess(struct req_state *s, RGWClientIO *cio)
   }
 
   map<string, string>::iterator giter;
-  for (giter = generic_attrs_map.begin(); giter != generic_attrs_map.end(); ++giter) {
+  for (giter = generic_attrs_map.begin(); giter != generic_attrs_map.end();
+       ++giter) {
     const char *env = info.env->get(giter->first.c_str());
     if (env) {
       s->generic_attrs[giter->second] = env;
@@ -1671,12 +1773,13 @@ int RGWREST::preprocess(struct req_state *s, RGWClientIO *cio)
   return 0;
 }
 
-RGWHandler *RGWREST::get_handler(RGWRados *store, struct req_state *s, RGWClientIO *cio,
-				 RGWRESTMgr **pmgr, int *init_error)
+RGWHandler_REST* RGWREST::get_handler(RGWRados *store, struct req_state *s,
+				      RGWStreamIO *sio, RGWRESTMgr **pmgr,
+				      int *init_error)
 {
-  RGWHandler *handler;
+  RGWHandler_REST* handler;
 
-  *init_error = preprocess(s, cio);
+  *init_error = preprocess(s, sio);
   if (*init_error < 0)
     return NULL;
 
@@ -1694,12 +1797,11 @@ RGWHandler *RGWREST::get_handler(RGWRados *store, struct req_state *s, RGWClient
     *init_error = -ERR_METHOD_NOT_ALLOWED;
     return NULL;
   }
-  *init_error = handler->init(store, s, cio);
+  *init_error = handler->init(store, s, sio);
   if (*init_error < 0) {
     m->put_handler(handler);
     return NULL;
   }
 
   return handler;
-}
-
+} /* get stream handler */
diff --git a/src/rgw/rgw_rest.h b/src/rgw/rgw_rest.h
index 8f1c4ed..bb288ca 100644
--- a/src/rgw/rgw_rest.h
+++ b/src/rgw/rgw_rest.h
@@ -3,30 +3,40 @@
 
 #ifndef CEPH_RGW_REST_H
 #define CEPH_RGW_REST_H
+
 #define TIME_BUF_SIZE 128
 
 #include "common/ceph_json.h"
 #include "include/assert.h" /* needed because of common/ceph_json.h */
 #include "rgw_op.h"
 #include "rgw_formats.h"
-
+#include "rgw_client_io.h"
 
 extern std::map<std::string, std::string> rgw_to_http_attrs;
 
 extern string lowercase_dash_http_attr(const string& orig);
 
-extern void rgw_rest_init(CephContext *cct, RGWRegion& region);
+extern void rgw_rest_init(CephContext *cct, RGWRados *store, RGWZoneGroup& zone_group);
 
 extern void rgw_flush_formatter_and_reset(struct req_state *s,
 					 ceph::Formatter *formatter);
 
 extern void rgw_flush_formatter(struct req_state *s,
-                                         ceph::Formatter *formatter);
+				ceph::Formatter *formatter);
+
+extern int rgw_rest_read_all_input(struct req_state *s, char **data, int *plen,
+				   int max_len);
 
-extern int rgw_rest_read_all_input(struct req_state *s, char **data, int *plen, int max_len);
+/* type conversions to work around lack of req_state type
+ * hierarchy matching (e.g.) REST backends (may be replaced w/dynamic
+ * typed req_state) */
+static inline RGWStreamIO* STREAM_IO(struct req_state* s) {
+  return static_cast<RGWStreamIO*>(s->cio);
+}
 
 template <class T>
-int rgw_rest_get_json_input(CephContext *cct, req_state *s, T& out, int max_len, bool *empty)
+int rgw_rest_get_json_input(CephContext *cct, req_state *s, T& out,
+			    int max_len, bool *empty)
 {
   int rv, data_len;
   char *data;
@@ -97,20 +107,29 @@ int rgw_rest_get_json_input_keep_data(CephContext *cct, req_state *s, T& out, in
   return 0;
 }
 
-
 class RESTArgs {
 public:
-  static int get_string(struct req_state *s, const string& name, const string& def_val, string *val, bool *existed = NULL);
-  static int get_uint64(struct req_state *s, const string& name, uint64_t def_val, uint64_t *val, bool *existed = NULL);
-  static int get_int64(struct req_state *s, const string& name, int64_t def_val, int64_t *val, bool *existed = NULL);
-  static int get_uint32(struct req_state *s, const string& name, uint32_t def_val, uint32_t *val, bool *existed = NULL);
-  static int get_int32(struct req_state *s, const string& name, int32_t def_val, int32_t *val, bool *existed = NULL);
-  static int get_time(struct req_state *s, const string& name, const utime_t& def_val, utime_t *val, bool *existed = NULL);
-  static int get_epoch(struct req_state *s, const string& name, uint64_t def_val, uint64_t *epoch, bool *existed = NULL);
-  static int get_bool(struct req_state *s, const string& name, bool def_val, bool *val, bool *existed = NULL);
+  static int get_string(struct req_state *s, const string& name,
+			const string& def_val, string *val,
+			bool *existed = NULL);
+  static int get_uint64(struct req_state *s, const string& name,
+			uint64_t def_val, uint64_t *val, bool *existed = NULL);
+  static int get_int64(struct req_state *s, const string& name,
+		       int64_t def_val, int64_t *val, bool *existed = NULL);
+  static int get_uint32(struct req_state *s, const string& name,
+			uint32_t def_val, uint32_t *val, bool *existed = NULL);
+  static int get_int32(struct req_state *s, const string& name,
+		       int32_t def_val, int32_t *val, bool *existed = NULL);
+  static int get_time(struct req_state *s, const string& name,
+		      const utime_t& def_val, utime_t *val,
+		      bool *existed = NULL);
+  static int get_epoch(struct req_state *s, const string& name,
+		       uint64_t def_val, uint64_t *epoch,
+		       bool *existed = NULL);
+  static int get_bool(struct req_state *s, const string& name, bool def_val,
+		      bool *val, bool *existed = NULL);
 };
 
-
 class RGWRESTFlusher : public RGWFormatterFlusher {
   struct req_state *s;
   RGWOp *op;
@@ -118,7 +137,8 @@ protected:
   virtual void do_flush();
   virtual void do_start(int ret);
 public:
-  RGWRESTFlusher(struct req_state *_s, RGWOp *_op) : RGWFormatterFlusher(_s->formatter), s(_s), op(_op) {}
+  RGWRESTFlusher(struct req_state *_s, RGWOp *_op) :
+    RGWFormatterFlusher(_s->formatter), s(_s), op(_op) {}
   RGWRESTFlusher() : RGWFormatterFlusher(NULL), s(NULL), op(NULL) {}
 
   void init(struct req_state *_s, RGWOp *_op) {
@@ -128,7 +148,7 @@ public:
   }
 };
 
-class RGWClientIO;
+class RGWStreamIO;
 
 class RGWGetObj_ObjStore : public RGWGetObj
 {
@@ -151,6 +171,12 @@ public:
   ~RGWListBuckets_ObjStore() {}
 };
 
+class RGWGetUsage_ObjStore : public RGWGetUsage {
+public:
+  RGWGetUsage_ObjStore() {}
+  ~RGWGetUsage_ObjStore() {}
+};
+
 class RGWListBucket_ObjStore : public RGWListBucket {
 public:
   RGWListBucket_ObjStore() {}
@@ -189,7 +215,7 @@ public:
 
   virtual int verify_params();
   virtual int get_params();
-  int get_data(bufferlist& bl);
+  virtual int get_data(bufferlist& bl);
 };
 
 class RGWPostObj_ObjStore : public RGWPostObj
@@ -245,7 +271,7 @@ public:
   RGWPutACLs_ObjStore() {}
   ~RGWPutACLs_ObjStore() {}
 
-  int get_params();
+  virtual int get_params();
 };
 
 class RGWGetCORS_ObjStore : public RGWGetCORS {
@@ -283,7 +309,7 @@ public:
   RGWCompleteMultipart_ObjStore() {}
   ~RGWCompleteMultipart_ObjStore() {}
 
-  int get_params();
+  virtual int get_params();
 };
 
 class RGWAbortMultipart_ObjStore : public RGWAbortMultipart {
@@ -319,7 +345,7 @@ public:
   RGWDeleteMultiObj_ObjStore() {}
   ~RGWDeleteMultiObj_ObjStore() {}
 
-  int get_params();
+  virtual int get_params();
 };
 
 class RGWRESTOp : public RGWOp {
@@ -328,16 +354,18 @@ protected:
   RGWRESTFlusher flusher;
 public:
   RGWRESTOp() : http_ret(0) {}
-  virtual void init(RGWRados *store, struct req_state *s, RGWHandler *dialect_handler) {
+  virtual void init(RGWRados *store, struct req_state *s,
+		    RGWHandler *dialect_handler) {
     RGWOp::init(store, s, dialect_handler);
     flusher.init(s, this);
   }
   virtual void send_response();
-  virtual int check_caps(RGWUserCaps& caps) { return -EPERM; } /* should to be implemented! */
+  virtual int check_caps(RGWUserCaps& caps)
+    { return -EPERM; } /* should to be implemented! */
   virtual int verify_permission();
 };
 
-class RGWHandler_ObjStore : public RGWHandler {
+class RGWHandler_REST : public RGWHandler {
 protected:
   virtual bool is_obj_update_op() { return false; }
   virtual RGWOp *op_get() { return NULL; }
@@ -352,13 +380,19 @@ protected:
   virtual int validate_bucket_name(const string& bucket);
   virtual int validate_object_name(const string& object);
 
-  static int allocate_formatter(struct req_state *s, int default_formatter, bool configurable);
+  static int allocate_formatter(struct req_state *s, int default_formatter,
+				bool configurable);
 public:
-  RGWHandler_ObjStore() {}
-  virtual ~RGWHandler_ObjStore() {}
-  int init_permissions(RGWOp *op);
-  int read_permissions(RGWOp *op);
-  virtual int retarget(RGWOp *op, RGWOp **new_op) {
+  RGWHandler_REST() {}
+  virtual ~RGWHandler_REST() {}
+
+  int init_permissions(RGWOp* op);
+  int read_permissions(RGWOp* op);
+
+  virtual RGWOp* get_op(RGWRados* store);
+  virtual void put_op(RGWOp* op);
+
+  virtual int retarget(RGWOp* op, RGWOp** new_op) {
     *new_op = op;
     return 0;
   }
@@ -367,9 +401,9 @@ public:
   // virtual int postauth_init(struct req_init_state *t) = 0;
 };
 
-class RGWHandler_ObjStore_SWIFT;
+class RGWHandler_REST_SWIFT;
 class RGWHandler_SWIFT_Auth;
-class RGWHandler_ObjStore_S3;
+class RGWHandler_REST_S3;
 
 
 class RGWRESTMgr {
@@ -386,27 +420,37 @@ public:
   void register_resource(string resource, RGWRESTMgr *mgr);
   void register_default_mgr(RGWRESTMgr *mgr);
 
-  virtual RGWRESTMgr *get_resource_mgr(struct req_state *s, const string& uri, string *out_uri);
-  virtual RGWHandler *get_handler(struct req_state *s) { return NULL; }
-  virtual void put_handler(RGWHandler *handler) { delete handler; }
+  virtual RGWRESTMgr *get_resource_mgr(struct req_state *s, const string& uri,
+				       string *out_uri);
+  virtual RGWHandler_REST *get_handler(struct req_state *s) { return NULL; }
+  virtual void put_handler(RGWHandler_REST *handler) { delete handler; }
 
   void set_logging(bool _should_log) { should_log = _should_log; }
   bool get_logging() { return should_log; }
 };
 
+class RGWLibIO;
+
 class RGWREST {
   RGWRESTMgr mgr;
 
-  static int preprocess(struct req_state *s, RGWClientIO *cio);
+  static int preprocess(struct req_state *s, RGWClientIO *sio);
 public:
   RGWREST() {}
-  RGWHandler *get_handler(RGWRados *store, struct req_state *s, RGWClientIO *cio,
-			  RGWRESTMgr **pmgr, int *init_error);
-  void put_handler(RGWHandler *handler) {
+  RGWHandler_REST *get_handler(RGWRados *store, struct req_state *s,
+			      RGWStreamIO *sio,
+			      RGWRESTMgr **pmgr, int *init_error);
+#if 0
+  RGWHandler *get_handler(RGWRados *store, struct req_state *s,
+			  RGWLibIO *io, RGWRESTMgr **pmgr,
+			  int *init_error);
+#endif
+  void put_handler(RGWHandler_REST *handler) {
     mgr.put_handler(handler);
   }
 
-  void register_resource(string resource, RGWRESTMgr *m, bool register_empty = false) {
+  void register_resource(string resource, RGWRESTMgr *m,
+			 bool register_empty = false) {
     if (!register_empty && resource.empty())
       return;
 
@@ -417,7 +461,7 @@ public:
   }
 };
 
-static const int64_t NO_CONTENT_LENGTH = -1;
+static constexpr int64_t NO_CONTENT_LENGTH = -1;
 
 extern void set_req_state_err(struct rgw_err &err, int err_no, int prot_flags);
 extern void set_req_state_err(struct req_state *s, int err_no);
@@ -426,33 +470,39 @@ extern void dump_errno(const struct rgw_err &err, string& out);
 extern void dump_errno(struct req_state *s);
 extern void dump_errno(struct req_state *s, int http_ret);
 extern void end_header(struct req_state *s,
-                       RGWOp *op = NULL,
-                       const char *content_type = NULL,
-                       const int64_t proposed_content_length = NO_CONTENT_LENGTH,
+                       RGWOp* op = nullptr,
+                       const char *content_type = nullptr,
+                       const int64_t proposed_content_length =
+		       NO_CONTENT_LENGTH,
 		       bool force_content_type = false,
 		       bool force_no_error = false);
 extern void dump_start(struct req_state *s);
 extern void list_all_buckets_start(struct req_state *s);
-extern void dump_owner(struct req_state *s, rgw_user& id, string& name, const char *section = NULL);
-extern void dump_string_header(struct req_state *s, const char *name, const char *val);
+extern void dump_owner(struct req_state *s, rgw_user& id, string& name,
+		       const char *section = NULL);
+extern void dump_string_header(struct req_state *s, const char *name,
+			       const char *val);
 extern void dump_content_length(struct req_state *s, uint64_t len);
 extern void dump_etag(struct req_state *s, const char *etag);
-extern void dump_epoch_header(struct req_state *s, const char *name, time_t t);
-extern void dump_time_header(struct req_state *s, const char *name, time_t t);
-extern void dump_last_modified(struct req_state *s, time_t t);
-extern void abort_early(struct req_state *s, RGWOp *op, int err, RGWHandler* handler);
-extern void dump_range(struct req_state *s, uint64_t ofs, uint64_t end, uint64_t total_size);
+extern void dump_epoch_header(struct req_state *s, const char *name, real_time t);
+extern void dump_time_header(struct req_state *s, const char *name, real_time t);
+extern void dump_last_modified(struct req_state *s, real_time t);
+extern void abort_early(struct req_state* s, RGWOp* op, int err,
+			RGWHandler* handler);
+extern void dump_range(struct req_state* s, uint64_t ofs, uint64_t end,
+		       uint64_t total_size);
 extern void dump_continue(struct req_state *s);
 extern void list_all_buckets_end(struct req_state *s);
-extern void dump_time(struct req_state *s, const char *name, time_t *t);
+extern void dump_time(struct req_state *s, const char *name, real_time *t);
 extern void dump_bucket_from_state(struct req_state *s);
 extern void dump_uri_from_state(struct req_state *s);
 extern void dump_redirect(struct req_state *s, const string& redirect);
 extern void dump_pair(struct req_state *s, const char *key, const char *value);
 extern bool is_valid_url(const char *url);
-extern void dump_access_control(struct req_state *s, const char *origin, const char *meth,
-                         const char *hdr, const char *exp_hdr, uint32_t max_age);
+extern void dump_access_control(struct req_state *s, const char *origin,
+				const char *meth,
+				const char *hdr, const char *exp_hdr,
+				uint32_t max_age);
 extern void dump_access_control(req_state *s, RGWOp *op);
 
-
-#endif
+#endif /* CEPH_RGW_REST_H */
diff --git a/src/rgw/rgw_rest_bucket.h b/src/rgw/rgw_rest_bucket.h
index 542bec6..227ef91 100644
--- a/src/rgw/rgw_rest_bucket.h
+++ b/src/rgw/rgw_rest_bucket.h
@@ -28,7 +28,7 @@ public:
   RGWRESTMgr_Bucket() {}
   virtual ~RGWRESTMgr_Bucket() {}
 
-  RGWHandler *get_handler(struct req_state *s) {
+  RGWHandler_REST* get_handler(struct req_state *s) {
     return new RGWHandler_Bucket;
   }
 };
diff --git a/src/rgw/rgw_rest_client.cc b/src/rgw/rgw_rest_client.cc
index 4ca88ab..718dffb 100644
--- a/src/rgw/rgw_rest_client.cc
+++ b/src/rgw/rgw_rest_client.cc
@@ -10,9 +10,19 @@
 #include "common/ceph_crypto_cms.h"
 #include "common/armor.h"
 #include "common/strtol.h"
+#include "include/str_list.h"
 
 #define dout_subsys ceph_subsys_rgw
 
+int RGWRESTSimpleRequest::get_status()
+{
+  int retcode = get_req_retcode();
+  if (retcode < 0) {
+    return retcode;
+  }
+  return status;
+}
+
 int RGWRESTSimpleRequest::receive_header(void *ptr, size_t len)
 {
   char line[len + 1];
@@ -152,11 +162,15 @@ void RGWRESTSimpleRequest::append_param(string& dest, const string& name, const
   } else {
     dest.append("&");
   }
-  dest.append(name);
+  string url_name;
+  url_encode(name, url_name);
+  dest.append(url_name);
 
   if (!val.empty()) {
+    string url_val;
+    url_encode(val, url_val);
     dest.append("=");
-    dest.append(val);
+    dest.append(url_val);
   }
 }
 
@@ -176,9 +190,11 @@ int RGWRESTSimpleRequest::sign_request(RGWAccessKey& key, RGWEnv& env, req_info&
 {
   map<string, string, ltstr_nocase>& m = env.get_map();
 
-  map<string, string>::iterator i;
-  for (i = m.begin(); i != m.end(); ++i) {
-    ldout(cct, 0) << "> " << i->first << " -> " << i->second << dendl;
+  if (cct->_conf->subsys.should_gather(ceph_subsys_rgw, 20)) {
+    map<string, string>::iterator i;
+    for (i = m.begin(); i != m.end(); ++i) {
+      ldout(cct, 20) << "> " << i->first << " -> " << i->second << dendl;
+    }
   }
 
   string canonical_header;
@@ -233,8 +249,7 @@ int RGWRESTSimpleRequest::forward_request(RGWAccessKey& key, req_info& info, siz
   }
 
   string params_str;
-  map<string, string>& args = new_info.args.get_params();
-  get_params_str(args, params_str);
+  get_params_str(info.args.get_params(), params_str);
 
   string new_url = url;
   string& resource = new_info.request_uri;
@@ -307,7 +322,7 @@ int RGWRESTStreamWriteRequest::add_output_data(bufferlist& bl)
   lock.Unlock();
 
   bool done;
-  return process_request(handle, false, &done);
+  return http_manager.process_requests(false, &done);
 }
 
 static void grants_by_type_add_one_grant(map<int, string>& grants_by_type, int perm, ACLGrant& grant)
@@ -455,7 +470,7 @@ int RGWRESTStreamWriteRequest::put_obj_init(RGWAccessKey& key, rgw_obj& obj, uin
 
   set_send_length(obj_size);
 
-  int r = init_async(new_info.method, new_url.c_str(), &handle);
+  int r = http_manager.add_request(this, new_info.method, new_url.c_str());
   if (r < 0)
     return r;
 
@@ -518,34 +533,69 @@ void set_str_from_headers(map<string, string>& out_headers, const string& header
   }
 }
 
-int RGWRESTStreamWriteRequest::complete(string& etag, time_t *mtime)
+static int parse_rgwx_mtime(CephContext *cct, const string& s, ceph::real_time *rt)
+{
+  string err;
+  vector<string> vec;
+
+  get_str_vec(s, ".", vec);
+
+  if (vec.empty()) {
+    return -EINVAL;
+  }
+
+  long secs = strict_strtol(vec[0].c_str(), 10, &err);
+  long nsecs = 0;
+  if (!err.empty()) {
+    ldout(cct, 0) << "ERROR: failed converting mtime (" << s << ") to real_time " << dendl;
+    return -EINVAL;
+  }
+
+  if (vec.size() > 1) {
+    nsecs = strict_strtol(vec[1].c_str(), 10, &err);
+    if (!err.empty()) {
+      ldout(cct, 0) << "ERROR: failed converting mtime (" << s << ") to real_time " << dendl;
+      return -EINVAL;
+    }
+  }
+
+  *rt = utime_t(secs, nsecs).to_real_time();
+
+  return 0;
+}
+
+int RGWRESTStreamWriteRequest::complete(string& etag, real_time *mtime)
 {
-  int ret = complete_request(handle);
+  int ret = http_manager.complete_requests();
   if (ret < 0)
     return ret;
 
   set_str_from_headers(out_headers, "ETAG", etag);
+
   if (mtime) {
     string mtime_str;
     set_str_from_headers(out_headers, "RGWX_MTIME", mtime_str);
-    string err;
-    long t = strict_strtol(mtime_str.c_str(), 10, &err);
-    if (!err.empty()) {
-      ldout(cct, 0) << "ERROR: failed converting mtime (" << mtime_str << ") to int " << dendl;
-      return -EINVAL;
+
+    ret = parse_rgwx_mtime(cct, mtime_str, mtime);
+    if (ret < 0) {
+      return ret;
     }
-    *mtime = (time_t)t;
   }
-
   return status;
 }
 
-int RGWRESTStreamReadRequest::get_obj(RGWAccessKey& key, map<string, string>& extra_headers, rgw_obj& obj)
+int RGWRESTStreamRWRequest::get_obj(RGWAccessKey& key, map<string, string>& extra_headers, rgw_obj& obj)
 {
   string urlsafe_bucket, urlsafe_object;
   url_encode(obj.bucket.name, urlsafe_bucket);
-  url_encode(obj.get_object(), urlsafe_object);
+  url_encode(obj.get_orig_obj(), urlsafe_object);
   string resource = urlsafe_bucket + "/" + urlsafe_object;
+
+  return get_resource(key, extra_headers, resource);
+}
+
+int RGWRESTStreamRWRequest::get_resource(RGWAccessKey& key, map<string, string>& extra_headers, const string& resource, RGWHTTPManager *mgr)
+{
   string new_url = url;
   if (new_url[new_url.size() - 1] != '/')
     new_url.append("/");
@@ -560,7 +610,19 @@ int RGWRESTStreamReadRequest::get_obj(RGWAccessKey& key, map<string, string>& ex
   map<string, string>& args = new_info.args.get_params();
   get_params_str(args, params_str);
 
-  new_url.append(resource + params_str);
+  /* merge params with extra args so that we can sign correctly */
+  for (list<pair<string, string> >::iterator iter = params.begin(); iter != params.end(); ++iter) {
+    new_info.args.append(iter->first, iter->second);
+  }
+
+  string new_resource;
+  if (resource[0] == '/') {
+    new_resource = resource.substr(1);
+  } else {
+    new_resource = resource;
+  }
+
+  new_url.append(new_resource + params_str);
 
   new_env.set("HTTP_DATE", date_str.c_str());
 
@@ -569,10 +631,10 @@ int RGWRESTStreamReadRequest::get_obj(RGWAccessKey& key, map<string, string>& ex
     new_env.set(iter->first.c_str(), iter->second.c_str());
   }
 
-  new_info.method = "GET";
+  new_info.method = method;
 
   new_info.script_uri = "/";
-  new_info.script_uri.append(resource);
+  new_info.script_uri.append(new_resource);
   new_info.request_uri = new_info.script_uri;
 
   new_info.init_meta_info(NULL);
@@ -589,27 +651,33 @@ int RGWRESTStreamReadRequest::get_obj(RGWAccessKey& key, map<string, string>& ex
     headers.push_back(pair<string, string>(iter->first, iter->second));
   }
 
-  int r = process(new_info.method, new_url.c_str());
+  RGWHTTPManager *pmanager = &http_manager;
+  if (mgr) {
+    pmanager = mgr;
+  }
+
+  int r = pmanager->add_request(this, new_info.method, new_url.c_str());
   if (r < 0)
     return r;
 
+  if (!mgr) {
+    r = pmanager->complete_requests();
+    if (r < 0)
+      return r;
+  }
+
   return 0;
 }
 
-int RGWRESTStreamReadRequest::complete(string& etag, time_t *mtime, map<string, string>& attrs)
+int RGWRESTStreamRWRequest::complete(string& etag, real_time *mtime, map<string, string>& attrs)
 {
   set_str_from_headers(out_headers, "ETAG", etag);
   if (mtime) {
     string mtime_str;
     set_str_from_headers(out_headers, "RGWX_MTIME", mtime_str);
-    if (!mtime_str.empty()) {
-      string err;
-      long t = strict_strtol(mtime_str.c_str(), 10, &err);
-      if (!err.empty()) {
-        ldout(cct, 0) << "ERROR: failed converting mtime (" << mtime_str << ") to int " << dendl;
-        return -EINVAL;
-      }
-      *mtime = (time_t)t;
+    int ret = parse_rgwx_mtime(cct, mtime_str, mtime);
+    if (ret < 0) {
+      return ret;
     }
   }
 
@@ -637,7 +705,7 @@ int RGWRESTStreamReadRequest::complete(string& etag, time_t *mtime, map<string,
   return status;
 }
 
-int RGWRESTStreamReadRequest::handle_header(const string& name, const string& val)
+int RGWRESTStreamRWRequest::handle_header(const string& name, const string& val)
 {
   if (name == "RGWX_EMBEDDED_METADATA_LEN") {
     string err;
@@ -652,7 +720,7 @@ int RGWRESTStreamReadRequest::handle_header(const string& name, const string& va
   return 0;
 }
 
-int RGWRESTStreamReadRequest::receive_data(void *ptr, size_t len)
+int RGWRESTStreamRWRequest::receive_data(void *ptr, size_t len)
 {
   bufferptr bp((const char *)ptr, len);
   bufferlist bl;
@@ -664,9 +732,27 @@ int RGWRESTStreamReadRequest::receive_data(void *ptr, size_t len)
   return len;
 }
 
-int RGWRESTStreamReadRequest::send_data(void *ptr, size_t len)
+int RGWRESTStreamRWRequest::send_data(void *ptr, size_t len)
 {
-  /* not sending any data */
-  return 0;
+  if (outbl.length() == 0) {
+    return 0;
+  }
+
+  uint64_t send_size = min(len, (size_t)(outbl.length() - write_ofs));
+  if (send_size > 0) {
+    memcpy(ptr, outbl.c_str() + write_ofs, send_size);
+    write_ofs += send_size;
+  }
+  return send_size;
 }
 
+class StreamIntoBufferlist : public RGWGetDataCB {
+  bufferlist& bl;
+public:
+  StreamIntoBufferlist(bufferlist& _bl) : bl(_bl) {}
+  int handle_data(bufferlist& inbl, off_t bl_ofs, off_t bl_len) {
+    bl.claim_append(inbl);
+    return bl_len;
+  }
+};
+
diff --git a/src/rgw/rgw_rest_client.h b/src/rgw/rgw_rest_client.h
index ccbb01c..82f3c3c 100644
--- a/src/rgw/rgw_rest_client.h
+++ b/src/rgw/rgw_rest_client.h
@@ -31,13 +31,20 @@ protected:
 
   int sign_request(RGWAccessKey& key, RGWEnv& env, req_info& info);
 public:
-  RGWRESTSimpleRequest(CephContext *_cct, string& _url, list<pair<string, string> > *_headers,
+  RGWRESTSimpleRequest(CephContext *_cct, const string& _url, list<pair<string, string> > *_headers,
                 list<pair<string, string> > *_params) : RGWHTTPClient(_cct), http_status(0), status(0),
                 url(_url), send_iter(NULL),
                 max_response(0) {
+    set_headers(_headers);
+    set_params(_params);
+  }
+
+  void set_headers(list<pair<string, string> > *_headers) {
     if (_headers)
       headers = *_headers;
+  }
 
+  void set_params(list<pair<string, string> > *_params) {
     if (_params)
       params = *_params;
   }
@@ -52,50 +59,70 @@ public:
   int forward_request(RGWAccessKey& key, req_info& info, size_t max_response, bufferlist *inbl, bufferlist *outbl);
 
   map<string, string>& get_out_headers() { return out_headers; }
+
+  int get_http_status() { return http_status; }
+  int get_status();
 };
 
 
 class RGWRESTStreamWriteRequest : public RGWRESTSimpleRequest {
   Mutex lock;
   list<bufferlist> pending_send;
-  void *handle;
   RGWGetDataCB *cb;
+  RGWHTTPManager http_manager;
 public:
   int add_output_data(bufferlist& bl);
   int send_data(void *ptr, size_t len);
 
-  RGWRESTStreamWriteRequest(CephContext *_cct, string& _url, list<pair<string, string> > *_headers,
+  RGWRESTStreamWriteRequest(CephContext *_cct, const string& _url, list<pair<string, string> > *_headers,
                 list<pair<string, string> > *_params) : RGWRESTSimpleRequest(_cct, _url, _headers, _params),
-                lock("RGWRESTStreamWriteRequest"), handle(NULL), cb(NULL) {}
+                lock("RGWRESTStreamWriteRequest"), cb(NULL), http_manager(_cct) {}
   ~RGWRESTStreamWriteRequest();
   int put_obj_init(RGWAccessKey& key, rgw_obj& obj, uint64_t obj_size, map<string, bufferlist>& attrs);
-  int complete(string& etag, time_t *mtime);
+  int complete(string& etag, real_time *mtime);
 
   RGWGetDataCB *get_out_cb() { return cb; }
 };
 
-class RGWRESTStreamReadRequest : public RGWRESTSimpleRequest {
+class RGWRESTStreamRWRequest : public RGWRESTSimpleRequest {
   Mutex lock;
   RGWGetDataCB *cb;
+  bufferlist outbl;
   bufferlist in_data;
   size_t chunk_ofs;
   size_t ofs;
+  RGWHTTPManager http_manager;
+  const char *method;
+  uint64_t write_ofs;
 protected:
   int handle_header(const string& name, const string& val);
 public:
   int send_data(void *ptr, size_t len);
   int receive_data(void *ptr, size_t len);
 
-  RGWRESTStreamReadRequest(CephContext *_cct, string& _url, RGWGetDataCB *_cb, list<pair<string, string> > *_headers,
+  RGWRESTStreamRWRequest(CephContext *_cct, const char *_method, const string& _url, RGWGetDataCB *_cb,
+	        list<pair<string, string> > *_headers,
                 list<pair<string, string> > *_params) : RGWRESTSimpleRequest(_cct, _url, _headers, _params),
                 lock("RGWRESTStreamReadRequest"), cb(_cb),
-                chunk_ofs(0), ofs(0) {}
-  ~RGWRESTStreamReadRequest() {}
+                chunk_ofs(0), ofs(0), http_manager(_cct), method(_method), write_ofs(0) {
+  }
+  virtual ~RGWRESTStreamRWRequest() {}
   int get_obj(RGWAccessKey& key, map<string, string>& extra_headers, rgw_obj& obj);
-  int complete(string& etag, time_t *mtime, map<string, string>& attrs);
+  int get_resource(RGWAccessKey& key, map<string, string>& extra_headers, const string& resource, RGWHTTPManager *mgr = NULL);
+  int complete(string& etag, real_time *mtime, map<string, string>& attrs);
+
+  void set_outbl(bufferlist& _outbl) {
+    outbl.swap(_outbl);
+  }
 
   void set_in_cb(RGWGetDataCB *_cb) { cb = _cb; }
 };
 
+class RGWRESTStreamReadRequest : public RGWRESTStreamRWRequest {
+public:
+  RGWRESTStreamReadRequest(CephContext *_cct, const string& _url, RGWGetDataCB *_cb, list<pair<string, string> > *_headers,
+                list<pair<string, string> > *_params) : RGWRESTStreamRWRequest(_cct, "GET", _url, _cb, _headers, _params) {}
+};
+
 #endif
 
diff --git a/src/rgw/rgw_rest_config.cc b/src/rgw/rgw_rest_config.cc
index 27cc989..2c0f5e4 100644
--- a/src/rgw/rgw_rest_config.cc
+++ b/src/rgw/rgw_rest_config.cc
@@ -20,28 +20,45 @@
 #include "rgw_rest_config.h"
 #include "rgw_client_io.h"
 #include "common/errno.h"
+#include "include/assert.h"
 
 #define dout_subsys ceph_subsys_rgw
 
-void RGWOp_RegionMap_Get::execute() {
-  http_ret = regionmap.read(g_ceph_context, store);
+void RGWOp_ZoneGroupMap_Get::execute() {
+  http_ret = zonegroup_map.read(g_ceph_context, store);
   if (http_ret < 0) {
-    dout(5) << "failed to read region map" << dendl;
+    dout(5) << "failed to read zone_group map" << dendl;
   }
 }
 
-void RGWOp_RegionMap_Get::send_response() {
+void RGWOp_ZoneGroupMap_Get::send_response() {
   set_req_state_err(s, http_ret);
   dump_errno(s);
   end_header(s);
 
   if (http_ret < 0)
     return;
-  
-  encode_json("region-map", regionmap, s->formatter);
-  flusher.flush(); 
+
+  if (old_format) {
+    RGWRegionMap region_map;
+    region_map.regions = zonegroup_map.zonegroups;
+    region_map.master_region = zonegroup_map.master_zonegroup;
+    region_map.bucket_quota = zonegroup_map.bucket_quota;
+    region_map.user_quota = zonegroup_map.user_quota;    
+    encode_json("region-map", region_map, s->formatter);
+  } else {
+    encode_json("zonegroup-map", zonegroup_map, s->formatter);
+  }
+  flusher.flush();
 }
 
 RGWOp* RGWHandler_Config::op_get() {
-  return new RGWOp_RegionMap_Get;
+  bool exists;
+  string type = s->info.args.get("type", &exists);
+
+  if (type.compare("zonegroup-map") == 0) {
+    return new RGWOp_ZoneGroupMap_Get(false);
+  } else {
+    return new RGWOp_ZoneGroupMap_Get(true);
+  }
 }
diff --git a/src/rgw/rgw_rest_config.h b/src/rgw/rgw_rest_config.h
index 2e0408a..fe7f027 100644
--- a/src/rgw/rgw_rest_config.h
+++ b/src/rgw/rgw_rest_config.h
@@ -11,14 +11,16 @@
  * Foundation. See file COPYING.
  *
  */
-#ifndef CEPH_RGW_REST_CONFIG_H
-#define CEPH_RGW_REST_CONFIG_H
 
-class RGWOp_RegionMap_Get : public RGWRESTOp {
-  RGWRegionMap regionmap;
+#ifndef RGW_REST_CONFIG_H
+#define RGW_REST_CONFIG_H
+
+class RGWOp_ZoneGroupMap_Get : public RGWRESTOp {
+  RGWZoneGroupMap zonegroup_map;
+  bool old_format;
 public:
-  RGWOp_RegionMap_Get() {}
-  ~RGWOp_RegionMap_Get() {}
+  RGWOp_ZoneGroupMap_Get(bool _old_format):old_format(_old_format) {}
+  ~RGWOp_ZoneGroupMap_Get() {}
 
   int verify_permission() {
     return 0; 
@@ -26,7 +28,11 @@ public:
   void execute();
   virtual void send_response();
   virtual const string name() {
-    return "get_region_map";
+    if (old_format) {
+      return "get_region_map";
+    } else {
+      return "get_zonegroup_map";
+    }
   }
 };
 
@@ -42,14 +48,15 @@ public:
   virtual ~RGWHandler_Config() {}
 };
 
+
 class RGWRESTMgr_Config : public RGWRESTMgr {
 public:
   RGWRESTMgr_Config() {}
   virtual ~RGWRESTMgr_Config() {}
 
-  virtual RGWHandler *get_handler(struct req_state *s){
+  virtual RGWHandler_REST* get_handler(struct req_state *s){
     return new RGWHandler_Config;
   }
 };
 
-#endif
+#endif /* RGW_REST_CONFIG_H */
diff --git a/src/rgw/rgw_rest_conn.cc b/src/rgw/rgw_rest_conn.cc
index e278ad2..f45e94a 100644
--- a/src/rgw/rgw_rest_conn.cc
+++ b/src/rgw/rgw_rest_conn.cc
@@ -6,15 +6,15 @@
 
 #define dout_subsys ceph_subsys_rgw
 
-RGWRESTConn::RGWRESTConn(CephContext *_cct, RGWRados *store, list<string>& remote_endpoints) : cct(_cct)
+RGWRESTConn::RGWRESTConn(CephContext *_cct, RGWRados *store,
+                         const string& _remote_id,
+                         const list<string>& remote_endpoints)
+  : cct(_cct),
+    endpoints(remote_endpoints.begin(), remote_endpoints.end()),
+    remote_id(_remote_id)
 {
-  list<string>::iterator iter;
-  int i;
-  for (i = 0, iter = remote_endpoints.begin(); iter != remote_endpoints.end(); ++iter, ++i) {
-    endpoints[i] = *iter;
-  }
-  key = store->zone.system_key;
-  region = store->region.name;
+  key = store->get_zone_params().system_key;
+  self_zone_group = store->get_zonegroup().get_id();
 }
 
 int RGWRESTConn::get_url(string& endpoint)
@@ -30,6 +30,20 @@ int RGWRESTConn::get_url(string& endpoint)
   return 0;
 }
 
+string RGWRESTConn::get_url()
+{
+  string endpoint;
+  if (endpoints.empty()) {
+    ldout(cct, 0) << "WARNING: endpoints not configured for upstream zone" << dendl; /* we'll catch this later */
+    return endpoint;
+  }
+
+  int i = counter.inc();
+  endpoint = endpoints[i % endpoints.size()];
+
+  return endpoint;
+}
+
 int RGWRESTConn::forward(const rgw_user& uid, req_info& info, obj_version *objv, size_t max_response, bufferlist *inbl, bufferlist *outbl)
 {
   string url;
@@ -37,14 +51,15 @@ int RGWRESTConn::forward(const rgw_user& uid, req_info& info, obj_version *objv,
   if (ret < 0)
     return ret;
   string uid_str = uid.to_str();
-  list<pair<string, string> > params;
-  params.push_back(pair<string, string>(RGW_SYS_PARAM_PREFIX "uid", uid_str));
-  params.push_back(pair<string, string>(RGW_SYS_PARAM_PREFIX "region", region));
+  param_list_t params;
+  if (!uid.empty())
+    params.push_back(param_pair_t(RGW_SYS_PARAM_PREFIX "uid", uid_str));
+  params.push_back(param_pair_t(RGW_SYS_PARAM_PREFIX "region", self_zone_group));
   if (objv) {
-    params.push_back(pair<string, string>(RGW_SYS_PARAM_PREFIX "tag", objv->tag));
+    params.push_back(param_pair_t(RGW_SYS_PARAM_PREFIX "tag", objv->tag));
     char buf[16];
     snprintf(buf, sizeof(buf), "%lld", (long long)objv->ver);
-    params.push_back(pair<string, string>(RGW_SYS_PARAM_PREFIX "ver", buf));
+    params.push_back(param_pair_t(RGW_SYS_PARAM_PREFIX "ver", buf));
   }
   RGWRESTSimpleRequest req(cct, url, NULL, &params);
   return req.forward_request(key, info, max_response, inbl, outbl);
@@ -65,14 +80,14 @@ int RGWRESTConn::put_obj_init(const rgw_user& uid, rgw_obj& obj, uint64_t obj_si
     return ret;
 
   string uid_str = uid.to_str();
-  list<pair<string, string> > params;
-  params.push_back(pair<string, string>(RGW_SYS_PARAM_PREFIX "uid", uid_str));
-  params.push_back(pair<string, string>(RGW_SYS_PARAM_PREFIX "region", region));
+  param_list_t params;
+  params.push_back(param_pair_t(RGW_SYS_PARAM_PREFIX "uid", uid_str));
+  params.push_back(param_pair_t(RGW_SYS_PARAM_PREFIX "region", self_zone_group));
   *req = new RGWRESTStreamWriteRequest(cct, url, NULL, &params);
   return (*req)->put_obj_init(key, obj, obj_size, attrs);
 }
 
-int RGWRESTConn::complete_request(RGWRESTStreamWriteRequest *req, string& etag, time_t *mtime)
+int RGWRESTConn::complete_request(RGWRESTStreamWriteRequest *req, string& etag, real_time *mtime)
 {
   int ret = req->complete(etag, mtime);
   delete req;
@@ -80,20 +95,47 @@ int RGWRESTConn::complete_request(RGWRESTStreamWriteRequest *req, string& etag,
   return ret;
 }
 
-int RGWRESTConn::get_obj(const rgw_user& uid, req_info *info /* optional */, rgw_obj& obj, bool prepend_metadata,
-                                 RGWGetDataCB *cb, RGWRESTStreamReadRequest **req)
+static void set_date_header(const real_time *t, map<string, string>& headers, const string& header_name)
+{
+  if (!t) {
+    return;
+  }
+  stringstream s;
+  utime_t tm = utime_t(*t);
+  tm.gmtime_nsec(s);
+  headers[header_name] = s.str();
+}
+
+template <class T>
+static void set_header(T val, map<string, string>& headers, const string& header_name)
+{
+  stringstream s;
+  s << val;
+  headers[header_name] = s.str();
+}
+
+
+int RGWRESTConn::get_obj(const rgw_user& uid, req_info *info /* optional */, rgw_obj& obj,
+                         const real_time *mod_ptr, const real_time *unmod_ptr,
+                         uint32_t mod_zone_id, uint64_t mod_pg_ver,
+                         bool prepend_metadata, RGWGetDataCB *cb, RGWRESTStreamReadRequest **req)
 {
   string url;
   int ret = get_url(url);
   if (ret < 0)
     return ret;
 
-  string uid_str = uid.to_str();
-  list<pair<string, string> > params;
-  params.push_back(pair<string, string>(RGW_SYS_PARAM_PREFIX "uid", uid_str));
-  params.push_back(pair<string, string>(RGW_SYS_PARAM_PREFIX "region", region));
+  param_list_t params;
+  if (!uid.empty()) {
+    params.push_back(param_pair_t(RGW_SYS_PARAM_PREFIX "uid", uid.to_str()));
+  }
+  params.push_back(param_pair_t(RGW_SYS_PARAM_PREFIX "region", self_zone_group));
   if (prepend_metadata) {
-    params.push_back(pair<string, string>(RGW_SYS_PARAM_PREFIX "prepend-metadata", region));
+    params.push_back(param_pair_t(RGW_SYS_PARAM_PREFIX "prepend-metadata", self_zone_group));
+  }
+  if (!obj.get_instance().empty()) {
+    const string& instance = obj.get_instance();
+    params.push_back(param_pair_t("versionId", instance));
   }
   *req = new RGWRESTStreamReadRequest(cct, url, cb, NULL, &params);
   map<string, string> extra_headers;
@@ -111,10 +153,20 @@ int RGWRESTConn::get_obj(const rgw_user& uid, req_info *info /* optional */, rgw
       extra_headers[iter->first] = iter->second;
     }
   }
+
+  set_date_header(mod_ptr, extra_headers, "HTTP_IF_MODIFIED_SINCE");
+  set_date_header(unmod_ptr, extra_headers, "HTTP_IF_UNMODIFIED_SINCE");
+  if (mod_zone_id != 0) {
+    set_header(mod_zone_id, extra_headers, "HTTP_DEST_ZONE_SHORT_ID");
+  }
+  if (mod_pg_ver != 0) {
+    set_header(mod_pg_ver, extra_headers, "HTTP_DEST_PG_VER");
+  }
+
   return (*req)->get_obj(key, extra_headers, obj);
 }
 
-int RGWRESTConn::complete_request(RGWRESTStreamReadRequest *req, string& etag, time_t *mtime, map<string, string>& attrs)
+int RGWRESTConn::complete_request(RGWRESTStreamReadRequest *req, string& etag, real_time *mtime, map<string, string>& attrs)
 {
   int ret = req->complete(etag, mtime, attrs);
   delete req;
@@ -122,4 +174,164 @@ int RGWRESTConn::complete_request(RGWRESTStreamReadRequest *req, string& etag, t
   return ret;
 }
 
+int RGWRESTConn::get_resource(const string& resource,
+		     param_list_t *extra_params,
+		     map<string, string> *extra_headers,
+		     bufferlist& bl,
+		     RGWHTTPManager *mgr)
+{
+  string url;
+  int ret = get_url(url);
+  if (ret < 0)
+    return ret;
+
+  param_list_t params;
+
+  if (extra_params) {
+    params.insert(params.end(), extra_params->begin(), extra_params->end());
+  }
+
+  params.push_back(param_pair_t(RGW_SYS_PARAM_PREFIX "zonegroup", self_zone_group));
+
+  RGWStreamIntoBufferlist cb(bl);
+
+  RGWRESTStreamReadRequest req(cct, url, &cb, NULL, &params);
+
+  map<string, string> headers;
+  if (extra_headers) {
+    headers.insert(extra_params->begin(), extra_params->end());
+  }
+
+  ret = req.get_resource(key, headers, resource, mgr);
+  if (ret < 0) {
+    ldout(cct, 5) << __func__ << ": get_resource() resource=" << resource << " returned ret=" << ret << dendl;
+    return ret;
+  }
+
+  string etag;
+  map<string, string> attrs;
+  return req.complete(etag, NULL, attrs);
+}
+
+RGWRESTReadResource::RGWRESTReadResource(RGWRESTConn *_conn,
+                                         const string& _resource,
+		                         const rgw_http_param_pair *pp,
+                                         param_list_t *extra_headers,
+                                         RGWHTTPManager *_mgr)
+  : cct(_conn->get_ctx()), conn(_conn), resource(_resource),
+    params(make_param_list(pp)), cb(bl), mgr(_mgr),
+    req(cct, conn->get_url(), &cb, NULL, NULL)
+{
+  init_common(extra_headers);
+}
+
+RGWRESTReadResource::RGWRESTReadResource(RGWRESTConn *_conn,
+                                         const string& _resource,
+		                         param_list_t& _params,
+                                         param_list_t *extra_headers,
+                                         RGWHTTPManager *_mgr)
+  : cct(_conn->get_ctx()), conn(_conn), resource(_resource), params(_params),
+    cb(bl), mgr(_mgr), req(cct, conn->get_url(), &cb, NULL, NULL)
+{
+  init_common(extra_headers);
+}
+
+void RGWRESTReadResource::init_common(param_list_t *extra_headers)
+{
+  params.push_back(param_pair_t(RGW_SYS_PARAM_PREFIX "zonegroup", conn->get_self_zonegroup()));
+
+  if (extra_headers) {
+    headers.insert(extra_headers->begin(), extra_headers->end());
+  }
+
+  req.set_params(&params);
+}
+
+int RGWRESTReadResource::read()
+{
+  int ret = req.get_resource(conn->get_key(), headers, resource, mgr);
+  if (ret < 0) {
+    ldout(cct, 5) << __func__ << ": get_resource() resource=" << resource << " returned ret=" << ret << dendl;
+    return ret;
+  }
+
+  string etag;
+  map<string, string> attrs;
+  return req.complete(etag, NULL, attrs);
+}
+
+int RGWRESTReadResource::aio_read()
+{
+  get();
+  int ret = req.get_resource(conn->get_key(), headers, resource, mgr);
+  if (ret < 0) {
+    put();
+    ldout(cct, 5) << __func__ << ": get_resource() resource=" << resource << " returned ret=" << ret << dendl;
+    return ret;
+  }
+
+  return 0;
+}
+
+RGWRESTPostResource::RGWRESTPostResource(RGWRESTConn *_conn,
+                                         const string& _resource,
+		                         const rgw_http_param_pair *pp,
+                                         param_list_t *extra_headers,
+                                         RGWHTTPManager *_mgr)
+  : cct(_conn->get_ctx()), conn(_conn), resource(_resource),
+    params(make_param_list(pp)), cb(bl), mgr(_mgr),
+    req(cct, "POST", conn->get_url(), &cb, NULL, NULL)
+{
+  init_common(extra_headers);
+}
+
+RGWRESTPostResource::RGWRESTPostResource(RGWRESTConn *_conn,
+                                         const string& _resource,
+		                         param_list_t& params,
+                                         param_list_t *extra_headers,
+                                         RGWHTTPManager *_mgr)
+  : cct(_conn->get_ctx()), conn(_conn), resource(_resource), params(params),
+    cb(bl), mgr(_mgr), req(cct, "POST", conn->get_url(), &cb, NULL, NULL)
+{
+  init_common(extra_headers);
+}
+
+void RGWRESTPostResource::init_common(param_list_t *extra_headers)
+{
+  params.push_back(param_pair_t(RGW_SYS_PARAM_PREFIX "zonegroup", conn->get_self_zonegroup()));
+
+  if (extra_headers) {
+    headers.insert(extra_headers->begin(), extra_headers->end());
+  }
+
+  req.set_params(&params);
+}
+
+int RGWRESTPostResource::send(bufferlist& outbl)
+{
+  req.set_outbl(outbl);
+  int ret = req.get_resource(conn->get_key(), headers, resource, mgr);
+  if (ret < 0) {
+    ldout(cct, 5) << __func__ << ": get_resource() resource=" << resource << " returned ret=" << ret << dendl;
+    return ret;
+  }
+
+  string etag;
+  map<string, string> attrs;
+  return req.complete(etag, NULL, attrs);
+}
+
+int RGWRESTPostResource::aio_send(bufferlist& outbl)
+{
+  req.set_outbl(outbl);
+  get();
+  int ret = req.get_resource(conn->get_key(), headers, resource, mgr);
+  if (ret < 0) {
+    put();
+    ldout(cct, 5) << __func__ << ": get_resource() resource=" << resource << " returned ret=" << ret << dendl;
+    return ret;
+  }
+
+  return 0;
+}
 
diff --git a/src/rgw/rgw_rest_conn.h b/src/rgw/rgw_rest_conn.h
index d7620da..ef33b1f 100644
--- a/src/rgw/rgw_rest_conn.h
+++ b/src/rgw/rgw_rest_conn.h
@@ -4,23 +4,83 @@
 #ifndef CEPH_RGW_REST_CONN_H
 #define CEPH_RGW_REST_CONN_H
 
+#include "rgw_rados.h"
 #include "rgw_rest_client.h"
+#include "common/ceph_json.h"
+#include "common/RefCountedObj.h"
+
 
 class CephContext;
 class RGWRados;
 class RGWGetObjData;
 
+template <class T>
+static int parse_decode_json(CephContext *cct, T& t, bufferlist& bl)
+{
+  JSONParser p;
+  int ret = p.parse(bl.c_str(), bl.length());
+  if (ret < 0) {
+    return ret;
+  }
+
+  try {
+    decode_json_obj(t, &p);
+  } catch (JSONDecoder::err& e) {
+    return -EINVAL;
+  }
+  return 0;
+}
+
+struct rgw_http_param_pair {
+  const char *key;
+  const char *val;
+};
+
+using param_pair_t = pair<string, string>;
+// TODO: consider vector instead of list
+using param_list_t = std::list<param_pair_t>;
+
+// copy a null-terminated rgw_http_param_pair list into a list of string pairs
+inline param_list_t make_param_list(const rgw_http_param_pair* pp)
+{
+  param_list_t params;
+  while (pp && pp->key) {
+    string k = pp->key;
+    string v = (pp->val ? pp->val : "");
+    params.emplace_back(make_pair(std::move(k), std::move(v)));
+    ++pp;
+  }
+  return params;
+}
+
 class RGWRESTConn
 {
   CephContext *cct;
-  map<int, string> endpoints;
+  vector<string> endpoints;
   RGWAccessKey key;
-  string region;
+  string self_zone_group;
+  string remote_id;
   atomic_t counter;
+
 public:
 
-  RGWRESTConn(CephContext *_cct, RGWRados *store, list<string>& endpoints);
+  RGWRESTConn(CephContext *_cct, RGWRados *store, const string& _remote_id, const list<string>& endpoints);
   int get_url(string& endpoint);
+  string get_url();
+  const string& get_self_zonegroup() {
+    return self_zone_group;
+  }
+  const string& get_remote_id() {
+    return remote_id;
+  }
+  RGWAccessKey& get_key() {
+    return key;
+  }
+
+  CephContext *get_ctx() {
+    return cct;
+  }
+  size_t get_endpoint_count() const { return endpoints.size(); }
 
   /* sync request */
   int forward(const rgw_user& uid, req_info& info, obj_version *objv, size_t max_response, bufferlist *inbl, bufferlist *outbl);
@@ -28,10 +88,271 @@ public:
   /* async request */
   int put_obj_init(const rgw_user& uid, rgw_obj& obj, uint64_t obj_size,
                    map<string, bufferlist>& attrs, RGWRESTStreamWriteRequest **req);
-  int complete_request(RGWRESTStreamWriteRequest *req, string& etag, time_t *mtime);
+  int complete_request(RGWRESTStreamWriteRequest *req, string& etag, ceph::real_time *mtime);
+
+  int get_obj(const rgw_user& uid, req_info *info /* optional */, rgw_obj& obj,
+              const ceph::real_time *mod_ptr, const ceph::real_time *unmod_ptr,
+              uint32_t mod_zone_id, uint64_t mod_pg_ver,
+              bool prepend_metadata, RGWGetDataCB *cb, RGWRESTStreamReadRequest **req);
+  int complete_request(RGWRESTStreamReadRequest *req, string& etag, ceph::real_time *mtime, map<string, string>& attrs);
+
+  int get_resource(const string& resource,
+                   param_list_t *extra_params,
+                   map<string, string>* extra_headers,
+                   bufferlist& bl, RGWHTTPManager *mgr = NULL);
+
+  template <class T>
+  int get_json_resource(const string& resource, param_list_t *params, T& t);
+  template <class T>
+  int get_json_resource(const string& resource, const rgw_http_param_pair *pp, T& t);
+};
+
+
+template<class T>
+int RGWRESTConn::get_json_resource(const string& resource, param_list_t *params, T& t)
+{
+  bufferlist bl;
+  int ret = get_resource(resource, params, NULL, bl);
+  if (ret < 0) {
+    return ret;
+  }
+
+  ret = parse_decode_json(cct, t, bl);
+  if (ret < 0) {
+    return ret;
+  }
+
+  return 0;
+}
+
+template<class T>
+int RGWRESTConn::get_json_resource(const string& resource,  const rgw_http_param_pair *pp, T& t)
+{
+  param_list_t params = make_param_list(pp);
+  return get_json_resource(resource, &params, t);
+}
+
+class RGWStreamIntoBufferlist : public RGWGetDataCB {
+  bufferlist& bl;
+public:
+  RGWStreamIntoBufferlist(bufferlist& _bl) : bl(_bl) {}
+  int handle_data(bufferlist& inbl, off_t bl_ofs, off_t bl_len) {
+    bl.claim_append(inbl);
+    return bl_len;
+  }
+};
+
+class RGWRESTReadResource : public RefCountedObject {
+  CephContext *cct;
+  RGWRESTConn *conn;
+  string resource;
+  param_list_t params;
+  map<string, string> headers;
+  bufferlist bl;
+  RGWStreamIntoBufferlist cb;
+
+  RGWHTTPManager *mgr;
+  RGWRESTStreamReadRequest req;
+
+  void init_common(param_list_t *extra_headers);
+
+public:
+  RGWRESTReadResource(RGWRESTConn *_conn,
+		      const string& _resource,
+		      const rgw_http_param_pair *pp,
+		      param_list_t *extra_headers,
+		      RGWHTTPManager *_mgr);
+
+  RGWRESTReadResource(RGWRESTConn *_conn,
+		      const string& _resource,
+		      param_list_t& _params,
+		      param_list_t *extra_headers,
+		      RGWHTTPManager *_mgr);
+
+  void set_user_info(void *user_info) {
+    req.set_user_info(user_info);
+  }
+  void *get_user_info() {
+    return req.get_user_info();
+  }
+
+  template <class T>
+  int decode_resource(T *dest);
+
+  int read();
+
+  int aio_read();
 
-  int get_obj(const rgw_user& uid, req_info *info /* optional */, rgw_obj& obj, bool prepend_metadata, RGWGetDataCB *cb, RGWRESTStreamReadRequest **req);
-  int complete_request(RGWRESTStreamReadRequest *req, string& etag, time_t *mtime, map<string, string>& attrs);
+  string to_str() {
+    return req.to_str();
+  }
+
+  int get_http_status() {
+    return req.get_http_status();
+  }
+
+  int wait_bl(bufferlist *pbl) {
+    int ret = req.wait();
+    put();
+    if (ret < 0) {
+      return ret;
+    }
+
+    if (req.get_status() < 0) {
+      return req.get_status();
+    }
+    *pbl = bl;
+    return 0;
+  }
+
+  template <class T>
+  int wait(T *dest);
+
+  template <class T>
+  int fetch(T *dest);
+};
+
+
+template <class T>
+int RGWRESTReadResource::decode_resource(T *dest)
+{
+  int ret = req.get_status();
+  if (ret < 0) {
+    return ret;
+  }
+  ret = parse_decode_json(cct, *dest, bl);
+  if (ret < 0) {
+    return ret;
+  }
+  return 0;
+}
+
+template <class T>
+int RGWRESTReadResource::fetch(T *dest)
+{
+  int ret = read();
+  if (ret < 0) {
+    return ret;
+  }
+
+  ret = decode_resource(dest);
+  if (ret < 0) {
+    return ret;
+  }
+  return 0;
+}
+
+template <class T>
+int RGWRESTReadResource::wait(T *dest)
+{
+  int ret = req.wait();
+  put();
+  if (ret < 0) {
+    return ret;
+  }
+
+  ret = decode_resource(dest);
+  if (ret < 0) {
+    return ret;
+  }
+  return 0;
+}
+
+class RGWRESTPostResource : public RefCountedObject {
+  CephContext *cct;
+  RGWRESTConn *conn;
+  string resource;
+  param_list_t params;
+  map<string, string> headers;
+  bufferlist bl;
+  RGWStreamIntoBufferlist cb;
+
+  RGWHTTPManager *mgr;
+  RGWRESTStreamRWRequest req;
+
+  void init_common(param_list_t *extra_headers);
+
+public:
+  RGWRESTPostResource(RGWRESTConn *_conn,
+		      const string& _resource,
+		      const rgw_http_param_pair *pp,
+		      param_list_t *extra_headers,
+		      RGWHTTPManager *_mgr);
+
+  RGWRESTPostResource(RGWRESTConn *_conn,
+		      const string& _resource,
+		      param_list_t& params,
+		      param_list_t *extra_headers,
+		      RGWHTTPManager *_mgr);
+
+  void set_user_info(void *user_info) {
+    req.set_user_info(user_info);
+  }
+  void *get_user_info() {
+    return req.get_user_info();
+  }
+
+  template <class T>
+  int decode_resource(T *dest);
+
+  int send(bufferlist& bl);
+
+  int aio_send(bufferlist& bl);
+
+  string to_str() {
+    return req.to_str();
+  }
+
+  int get_http_status() {
+    return req.get_http_status();
+  }
+
+  int wait_bl(bufferlist *pbl) {
+    int ret = req.wait();
+    put();
+    if (ret < 0) {
+      return ret;
+    }
+
+    if (req.get_status() < 0) {
+      return req.get_status();
+    }
+    *pbl = bl;
+    return 0;
+  }
+
+  template <class T>
+  int wait(T *dest);
 };
 
+template <class T>
+int RGWRESTPostResource::decode_resource(T *dest)
+{
+  int ret = req.get_status();
+  if (ret < 0) {
+    return ret;
+  }
+  ret = parse_decode_json(cct, *dest, bl);
+  if (ret < 0) {
+    return ret;
+  }
+  return 0;
+}
+
+template <class T>
+int RGWRESTPostResource::wait(T *dest)
+{
+  int ret = req.wait();
+  put();
+  if (ret < 0) {
+    return ret;
+  }
+
+  ret = decode_resource(dest);
+  if (ret < 0) {
+    return ret;
+  }
+  return 0;
+}
+
 #endif
diff --git a/src/rgw/rgw_rest_log.cc b/src/rgw/rgw_rest_log.cc
index 2ba2ee7..854da2e 100644
--- a/src/rgw/rgw_rest_log.cc
+++ b/src/rgw/rgw_rest_log.cc
@@ -19,11 +19,12 @@
 #include "rgw_rest_log.h"
 #include "rgw_client_io.h"
 #include "common/errno.h"
+#include "include/assert.h"
 
 #define LOG_CLASS_LIST_MAX_ENTRIES (1000)
 #define dout_subsys ceph_subsys_rgw
 
-static int parse_date_str(string& in, utime_t& out) {
+static int parse_date_str(string& in, real_time& out) {
   uint64_t epoch = 0;
   uint64_t nsec = 0;
 
@@ -33,19 +34,20 @@ static int parse_date_str(string& in, utime_t& out) {
       return -EINVAL;
     }
   }
-  out = utime_t(epoch, nsec);
+  out = utime_t(epoch, nsec).to_real_time();
   return 0;
 }
 
 void RGWOp_MDLog_List::execute() {
+  string   period = s->info.args.get("period");
   string   shard = s->info.args.get("id");
   string   max_entries_str = s->info.args.get("max-entries");
   string   st = s->info.args.get("start-time"),
            et = s->info.args.get("end-time"),
            marker = s->info.args.get("marker"),
            err;
-  utime_t  ut_st, 
-           ut_et;
+  real_time  ut_st, 
+             ut_et;
   void    *handle;
   unsigned shard_id, max_entries = LOG_CLASS_LIST_MAX_ENTRIES;
 
@@ -74,14 +76,24 @@ void RGWOp_MDLog_List::execute() {
       return;
     }
   } 
-  
-  RGWMetadataLog *meta_log = store->meta_mgr->get_log();
 
-  meta_log->init_list_entries(shard_id, ut_st, ut_et, marker, &handle);
+  if (period.empty()) {
+    ldout(s->cct, 5) << "Missing period id trying to use current" << dendl;
+    period = store->get_current_period_id();
+    if (period.empty()) {
+      ldout(s->cct, 5) << "Missing period id" << dendl;
+      http_ret = -EINVAL;
+      return;
+    }
+  }
+
+  RGWMetadataLog meta_log{s->cct, store, period};
+
+  meta_log.init_list_entries(shard_id, ut_st, ut_et, marker, &handle);
 
   do {
-    http_ret = meta_log->list_entries(handle, max_entries, entries,
-				      &last_marker, &truncated);
+    http_ret = meta_log.list_entries(handle, max_entries, entries,
+				     &last_marker, &truncated);
     if (http_ret < 0) 
       break;
 
@@ -89,7 +101,7 @@ void RGWOp_MDLog_List::execute() {
       max_entries -= entries.size();
   } while (truncated && (max_entries > 0));
 
-  meta_log->complete_list_entries(handle);
+  meta_log.complete_list_entries(handle);
 }
 
 void RGWOp_MDLog_List::send_response() {
@@ -119,7 +131,8 @@ void RGWOp_MDLog_List::send_response() {
 
 void RGWOp_MDLog_Info::execute() {
   num_objects = s->cct->_conf->rgw_md_log_max_shards;
-  http_ret = 0;
+  period = store->meta_mgr->get_oldest_log_period();
+  http_ret = period.get_error();
 }
 
 void RGWOp_MDLog_Info::send_response() {
@@ -127,13 +140,18 @@ void RGWOp_MDLog_Info::send_response() {
   dump_errno(s);
   end_header(s);
 
-  s->formatter->open_object_section("num_objects");
+  s->formatter->open_object_section("mdlog");
   s->formatter->dump_unsigned("num_objects", num_objects);
+  if (period) {
+    s->formatter->dump_string("period", period.get_period().get_id());
+    s->formatter->dump_unsigned("realm_epoch", period.get_epoch());
+  }
   s->formatter->close_section();
   flusher.flush();
 }
 
 void RGWOp_MDLog_ShardInfo::execute() {
+  string period = s->info.args.get("period");
   string shard = s->info.args.get("id");
   string err;
 
@@ -144,9 +162,14 @@ void RGWOp_MDLog_ShardInfo::execute() {
     return;
   }
 
-  RGWMetadataLog *meta_log = store->meta_mgr->get_log();
+  if (period.empty()) {
+    ldout(s->cct, 5) << "Missing period id" << dendl;
+    http_ret = -EINVAL;
+    return;
+  }
+  RGWMetadataLog meta_log{s->cct, store, period};
 
-  http_ret = meta_log->get_info(shard_id, &info);
+  http_ret = meta_log.get_info(shard_id, &info);
 }
 
 void RGWOp_MDLog_ShardInfo::send_response() {
@@ -163,10 +186,11 @@ void RGWOp_MDLog_Delete::execute() {
            et = s->info.args.get("end-time"),
            start_marker = s->info.args.get("start-marker"),
            end_marker = s->info.args.get("end-marker"),
+           period = s->info.args.get("period"),
            shard = s->info.args.get("id"),
            err;
-  utime_t  ut_st, 
-           ut_et;
+  real_time  ut_st, 
+             ut_et;
   unsigned shard_id;
 
   http_ret = 0;
@@ -191,23 +215,36 @@ void RGWOp_MDLog_Delete::execute() {
     http_ret = -EINVAL;
     return;
   }
-  RGWMetadataLog *meta_log = store->meta_mgr->get_log();
 
-  http_ret = meta_log->trim(shard_id, ut_st, ut_et, start_marker, end_marker);
+  if (period.empty()) {
+    ldout(s->cct, 5) << "Missing period id" << dendl;
+    http_ret = -EINVAL;
+    return;
+  }
+  RGWMetadataLog meta_log{s->cct, store, period};
+
+  http_ret = meta_log.trim(shard_id, ut_st, ut_et, start_marker, end_marker);
 }
 
 void RGWOp_MDLog_Lock::execute() {
-  string shard_id_str, duration_str, locker_id, zone_id;
+  string period, shard_id_str, duration_str, locker_id, zone_id;
   unsigned shard_id;
 
   http_ret = 0;
 
+  period       = s->info.args.get("period");
   shard_id_str = s->info.args.get("id");
   duration_str = s->info.args.get("length");
   locker_id    = s->info.args.get("locker-id");
   zone_id      = s->info.args.get("zone-id");
 
-  if (shard_id_str.empty() ||
+  if (period.empty()) {
+    ldout(s->cct, 5) << "Missing period id trying to use current" << dendl;
+    period = store->get_current_period_id();
+  }
+
+  if (period.empty() ||
+      shard_id_str.empty() ||
       (duration_str.empty()) ||
       locker_id.empty() ||
       zone_id.empty()) {
@@ -224,7 +261,7 @@ void RGWOp_MDLog_Lock::execute() {
     return;
   }
 
-  RGWMetadataLog *meta_log = store->meta_mgr->get_log();
+  RGWMetadataLog meta_log{s->cct, store, period};
   unsigned dur;
   dur = (unsigned)strict_strtol(duration_str.c_str(), 10, &err);
   if (!err.empty() || dur <= 0) {
@@ -232,23 +269,30 @@ void RGWOp_MDLog_Lock::execute() {
     http_ret = -EINVAL;
     return;
   }
-  utime_t time(dur, 0);
-  http_ret = meta_log->lock_exclusive(shard_id, time, zone_id, locker_id);
+  http_ret = meta_log.lock_exclusive(shard_id, make_timespan(dur), zone_id,
+				     locker_id);
   if (http_ret == -EBUSY)
     http_ret = -ERR_LOCKED;
 }
 
 void RGWOp_MDLog_Unlock::execute() {
-  string shard_id_str, locker_id, zone_id;
+  string period, shard_id_str, locker_id, zone_id;
   unsigned shard_id;
 
   http_ret = 0;
 
+  period       = s->info.args.get("period");
   shard_id_str = s->info.args.get("id");
   locker_id    = s->info.args.get("locker-id");
   zone_id      = s->info.args.get("zone-id");
 
-  if (shard_id_str.empty() ||
+  if (period.empty()) {
+    ldout(s->cct, 5) << "Missing period id trying to use current" << dendl;
+    period = store->get_current_period_id();
+  }
+
+  if (period.empty() ||
+      shard_id_str.empty() ||
       locker_id.empty() ||
       zone_id.empty()) {
     dout(5) << "Error invalid parameter list" << dendl;
@@ -264,8 +308,49 @@ void RGWOp_MDLog_Unlock::execute() {
     return;
   }
 
-  RGWMetadataLog *meta_log = store->meta_mgr->get_log();
-  http_ret = meta_log->unlock(shard_id, zone_id, locker_id);
+  RGWMetadataLog meta_log{s->cct, store, period};
+  http_ret = meta_log.unlock(shard_id, zone_id, locker_id);
+}
+
+void RGWOp_MDLog_Notify::execute() {
+  char *data;
+  int len = 0;
+#define LARGE_ENOUGH_BUF (128 * 1024)
+  int r = rgw_rest_read_all_input(s, &data, &len, LARGE_ENOUGH_BUF);
+  if (r < 0) {
+    http_ret = r;
+    return;
+  }
+
+  ldout(s->cct, 20) << __func__ << "(): read data: " << string(data, len) << dendl;
+
+  JSONParser p;
+  r = p.parse(data, len);
+  free(data);
+  if (r < 0) {
+    ldout(s->cct, 0) << "ERROR: failed to parse JSON" << dendl;
+    http_ret = r;
+    return;
+  }
+
+  set<int> updated_shards;
+  try {
+    decode_json_obj(updated_shards, &p);
+  } catch (JSONDecoder::err& err) {
+    ldout(s->cct, 0) << "ERROR: failed to decode JSON" << dendl;
+    http_ret = -EINVAL;
+    return;
+  }
+
+  if (store->ctx()->_conf->subsys.should_gather(ceph_subsys_rgw, 20)) {
+    for (set<int>::iterator iter = updated_shards.begin(); iter != updated_shards.end(); ++iter) {
+      ldout(s->cct, 20) << __func__ << "(): updated shard=" << *iter << dendl;
+    }
+  }
+
+  store->wakeup_meta_sync_shards(updated_shards);
+
+  http_ret = 0;
 }
 
 void RGWOp_BILog_List::execute() {
@@ -378,6 +463,12 @@ void RGWOp_BILog_Info::execute() {
     return;
   }
 
+  int shard_id;
+  http_ret = rgw_bucket_parse_bucket_instance(bucket_instance, &bucket_instance, &shard_id);
+  if (http_ret < 0) {
+    return;
+  }
+
   if (!bucket_instance.empty()) {
     http_ret = store->get_bucket_instance_info(obj_ctx, bucket_instance, bucket_info, NULL, NULL);
     if (http_ret < 0) {
@@ -392,7 +483,7 @@ void RGWOp_BILog_Info::execute() {
     }
   }
   map<RGWObjCategory, RGWStorageStats> stats;
-  int ret =  store->get_bucket_stats(bucket_info.bucket, &bucket_ver, &master_ver, stats, &max_marker);
+  int ret =  store->get_bucket_stats(bucket_info.bucket, shard_id, &bucket_ver, &master_ver, stats, &max_marker);
   if (ret < 0 && ret != -ENOENT) {
     http_ret = ret;
     return;
@@ -469,10 +560,12 @@ void RGWOp_DATALog_List::execute() {
            max_entries_str = s->info.args.get("max-entries"),
            marker = s->info.args.get("marker"),
            err;
-  utime_t  ut_st, 
-           ut_et;
+  real_time  ut_st, 
+             ut_et;
   unsigned shard_id, max_entries = LOG_CLASS_LIST_MAX_ENTRIES;
 
+  s->info.args.get_bool("extra-info", &extra_info, false);
+
   shard_id = (unsigned)strict_strtol(shard.c_str(), 10, &err);
   if (!err.empty()) {
     dout(5) << "Error parsing shard_id " << shard << dendl;
@@ -526,10 +619,14 @@ void RGWOp_DATALog_List::send_response() {
   s->formatter->dump_bool("truncated", truncated);
   {
     s->formatter->open_array_section("entries");
-    for (list<rgw_data_change>::iterator iter = entries.begin();
+    for (list<rgw_data_change_log_entry>::iterator iter = entries.begin();
 	 iter != entries.end(); ++iter) {
-      rgw_data_change& entry = *iter;
-      encode_json("entry", entry, s->formatter);
+      rgw_data_change_log_entry& entry = *iter;
+      if (!extra_info) {
+        encode_json("entry", entry.entry, s->formatter);
+      } else {
+        encode_json("entry", entry, s->formatter);
+      }
       flusher.flush();
     }
     s->formatter->close_section();
@@ -613,8 +710,7 @@ void RGWOp_DATALog_Lock::execute() {
     http_ret = -EINVAL;
     return;
   }
-  utime_t time(dur, 0);
-  http_ret = store->data_log->lock_exclusive(shard_id, time, zone_id, locker_id);
+  http_ret = store->data_log->lock_exclusive(shard_id, make_timespan(dur), zone_id, locker_id);
   if (http_ret == -EBUSY)
     http_ret = -ERR_LOCKED;
 }
@@ -648,6 +744,52 @@ void RGWOp_DATALog_Unlock::execute() {
   http_ret = store->data_log->unlock(shard_id, zone_id, locker_id);
 }
 
+void RGWOp_DATALog_Notify::execute() {
+  string  source_zone = s->info.args.get("source-zone");
+  char *data;
+  int len = 0;
+#define LARGE_ENOUGH_BUF (128 * 1024)
+  int r = rgw_rest_read_all_input(s, &data, &len, LARGE_ENOUGH_BUF);
+  if (r < 0) {
+    http_ret = r;
+    return;
+  }
+
+  ldout(s->cct, 20) << __func__ << "(): read data: " << string(data, len) << dendl;
+
+  JSONParser p;
+  r = p.parse(data, len);
+  free(data);
+  if (r < 0) {
+    ldout(s->cct, 0) << "ERROR: failed to parse JSON" << dendl;
+    http_ret = r;
+    return;
+  }
+
+  map<int, set<string> > updated_shards;
+  try {
+    decode_json_obj(updated_shards, &p);
+  } catch (JSONDecoder::err& err) {
+    ldout(s->cct, 0) << "ERROR: failed to decode JSON" << dendl;
+    http_ret = -EINVAL;
+    return;
+  }
+
+  if (store->ctx()->_conf->subsys.should_gather(ceph_subsys_rgw, 20)) {
+    for (map<int, set<string> >::iterator iter = updated_shards.begin(); iter != updated_shards.end(); ++iter) {
+      ldout(s->cct, 20) << __func__ << "(): updated shard=" << iter->first << dendl;
+      set<string>& keys = iter->second;
+      for (set<string>::iterator kiter = keys.begin(); kiter != keys.end(); ++kiter) {
+      ldout(s->cct, 20) << __func__ << "(): modified key=" << *kiter << dendl;
+      }
+    }
+  }
+
+  store->wakeup_data_sync_shards(source_zone, updated_shards);
+
+  http_ret = 0;
+}
+
 void RGWOp_DATALog_Delete::execute() {
   string   st = s->info.args.get("start-time"),
            et = s->info.args.get("end-time"),
@@ -655,8 +797,8 @@ void RGWOp_DATALog_Delete::execute() {
            end_marker = s->info.args.get("end-marker"),
            shard = s->info.args.get("id"),
            err;
-  utime_t  ut_st, 
-           ut_et;
+  real_time  ut_st, 
+             ut_et;
   unsigned shard_id;
 
   http_ret = 0;
@@ -753,11 +895,15 @@ RGWOp *RGWHandler_Log::op_post() {
       return new RGWOp_MDLog_Lock;
     else if (s->info.args.exists("unlock"))
       return new RGWOp_MDLog_Unlock;
+    else if (s->info.args.exists("notify"))
+      return new RGWOp_MDLog_Notify;	    
   } else if (type.compare("data") == 0) {
     if (s->info.args.exists("lock"))
       return new RGWOp_DATALog_Lock;
     else if (s->info.args.exists("unlock"))
       return new RGWOp_DATALog_Unlock;
+    else if (s->info.args.exists("notify"))
+      return new RGWOp_DATALog_Notify;	    
   }
   return NULL;
 }
diff --git a/src/rgw/rgw_rest_log.h b/src/rgw/rgw_rest_log.h
index d6873bd..c5e94f6 100644
--- a/src/rgw/rgw_rest_log.h
+++ b/src/rgw/rgw_rest_log.h
@@ -11,8 +11,9 @@
  * Foundation. See file COPYING.
  *
  */
-#ifndef CEPH_RGW_REST_LOG_H
-#define CEPH_RGW_REST_LOG_H
+
+#ifndef RGW_REST_LOG_H
+#define RGW_REST_LOG_H
 
 #include "rgw_metadata.h"
 
@@ -26,7 +27,7 @@ public:
     return caps.check_cap("bilog", RGW_CAP_READ);
   }
   int verify_permission() {
-    return check_caps(s->user.caps);
+    return check_caps(s->user->caps);
   }
   virtual void send_response();
   virtual void send_response(list<rgw_bi_log_entry>& entries, string& marker);
@@ -49,7 +50,7 @@ public:
     return caps.check_cap("bilog", RGW_CAP_READ);
   }
   int verify_permission() {
-    return check_caps(s->user.caps);
+    return check_caps(s->user->caps);
   }
   virtual void send_response();
   void execute();
@@ -84,7 +85,7 @@ public:
     return caps.check_cap("mdlog", RGW_CAP_READ);
   }
   int verify_permission() {
-    return check_caps(s->user.caps);
+    return check_caps(s->user->caps);
   }
   void execute();
   virtual void send_response();
@@ -95,6 +96,7 @@ public:
 
 class RGWOp_MDLog_Info : public RGWRESTOp {
   unsigned num_objects;
+  RGWPeriodHistory::Cursor period;
 public:
   RGWOp_MDLog_Info() : num_objects(0) {}
   ~RGWOp_MDLog_Info() {}
@@ -103,7 +105,7 @@ public:
     return caps.check_cap("mdlog", RGW_CAP_READ);
   }
   int verify_permission() {
-    return check_caps(s->user.caps);
+    return check_caps(s->user->caps);
   }
   void execute();
   virtual void send_response();
@@ -122,7 +124,7 @@ public:
     return caps.check_cap("mdlog", RGW_CAP_READ);
   }
   int verify_permission() {
-    return check_caps(s->user.caps);
+    return check_caps(s->user->caps);
   }
   void execute();
   virtual void send_response();
@@ -159,6 +161,20 @@ public:
   }
 };
 
+class RGWOp_MDLog_Notify : public RGWRESTOp {
+public:
+  RGWOp_MDLog_Notify() {}
+  ~RGWOp_MDLog_Notify() {}
+
+  int check_caps(RGWUserCaps& caps) {
+    return caps.check_cap("mdlog", RGW_CAP_WRITE);
+  }
+  void execute();
+  virtual const string name() {
+    return "mdlog_notify";
+  }
+};
+
 class RGWOp_MDLog_Delete : public RGWRESTOp {
 public:
   RGWOp_MDLog_Delete() {}
@@ -174,18 +190,19 @@ public:
 };
 
 class RGWOp_DATALog_List : public RGWRESTOp {
-  list<rgw_data_change> entries;
+  list<rgw_data_change_log_entry> entries;
   string last_marker;
   bool truncated;
+  bool extra_info;
 public:
-  RGWOp_DATALog_List() : truncated(false) {}
+  RGWOp_DATALog_List() : truncated(false), extra_info(false) {}
   ~RGWOp_DATALog_List() {}
 
   int check_caps(RGWUserCaps& caps) {
     return caps.check_cap("datalog", RGW_CAP_READ);
   }
   int verify_permission() {
-    return check_caps(s->user.caps);
+    return check_caps(s->user->caps);
   }
   void execute();
   virtual void send_response();
@@ -204,7 +221,7 @@ public:
     return caps.check_cap("datalog", RGW_CAP_READ);
   }
   int verify_permission() {
-    return check_caps(s->user.caps);
+    return check_caps(s->user->caps);
   }
   void execute();
   virtual void send_response();
@@ -223,7 +240,7 @@ public:
     return caps.check_cap("datalog", RGW_CAP_READ);
   }
   int verify_permission() {
-    return check_caps(s->user.caps);
+    return check_caps(s->user->caps);
   }
   void execute();
   virtual void send_response();
@@ -260,6 +277,20 @@ public:
   }
 };
 
+class RGWOp_DATALog_Notify : public RGWRESTOp {
+public:
+  RGWOp_DATALog_Notify() {}
+  ~RGWOp_DATALog_Notify() {}
+
+  int check_caps(RGWUserCaps& caps) {
+    return caps.check_cap("datalog", RGW_CAP_WRITE);
+  }
+  void execute();
+  virtual const string name() {
+    return "datalog_notify";
+  }
+};
+
 class RGWOp_DATALog_Delete : public RGWRESTOp {
 public:
   RGWOp_DATALog_Delete() {}
@@ -293,10 +324,9 @@ public:
   RGWRESTMgr_Log() {}
   virtual ~RGWRESTMgr_Log() {}
 
-  virtual RGWHandler *get_handler(struct req_state *s){
+  virtual RGWHandler_REST* get_handler(struct req_state *s){
     return new RGWHandler_Log;
   }
 };
 
-#endif
-
+#endif /* RGW_REST_LOG_H */
diff --git a/src/rgw/rgw_rest_metadata.cc b/src/rgw/rgw_rest_metadata.cc
index f97fdb4..8f02b0f 100644
--- a/src/rgw/rgw_rest_metadata.cc
+++ b/src/rgw/rgw_rest_metadata.cc
@@ -1,4 +1,4 @@
-// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- 
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
 // vim: ts=8 sw=2 smarttab
 /*
  * Ceph - scalable distributed file system
@@ -20,6 +20,7 @@
 #include "rgw_client_io.h"
 #include "common/errno.h"
 #include "common/strtol.h"
+#include "include/assert.h"
 
 #define dout_subsys ceph_subsys_rgw
 
@@ -32,8 +33,8 @@ static inline void frame_metadata_key(req_state *s, string& out) {
   string key = s->info.args.get("key", &exists);
 
   string section;
-  if (!s->bucket_name.empty()) {
-    section = s->bucket_name;
+  if (!s->init_state.url_bucket.empty()) {
+    section = s->init_state.url_bucket;
   } else {
     section = key;
     key.clear();
@@ -87,11 +88,13 @@ void RGWOp_Metadata_List::execute() {
     list<string> keys;
     http_ret = store->meta_mgr->list_keys_next(handle, max, keys, &truncated);
     if (http_ret < 0) {
-      dout(5) << "ERROR: lists_keys_next(): " << cpp_strerror(http_ret) << dendl;
+      dout(5) << "ERROR: lists_keys_next(): " << cpp_strerror(http_ret)
+	      << dendl;
       return;
     }
 
-    for (list<string>::iterator iter = keys.begin(); iter != keys.end(); ++iter) {
+    for (list<string>::iterator iter = keys.begin(); iter != keys.end();
+	 ++iter) {
       s->formatter->dump_string("key", *iter);
     }
 
@@ -116,7 +119,7 @@ int RGWOp_Metadata_Put::get_data(bufferlist& bl) {
     if (!data) {
        return -ENOMEM;
     }
-    int r = s->cio->read(data, cl, &read_len);
+    int r = STREAM_IO(s)->read(data, cl, &read_len);
     if (cl != (size_t)read_len) {
       dout(10) << "cio->read incomplete" << dendl;
     }
@@ -126,7 +129,7 @@ int RGWOp_Metadata_Put::get_data(bufferlist& bl) {
     }
     bl.append(data, read_len);
   } else {
-    int chunk_size = CEPH_PAGE_SIZE; 
+    int chunk_size = CEPH_PAGE_SIZE;
     const char *enc = s->info.env->get("HTTP_TRANSFER_ENCODING");
     if (!enc || strcmp(enc, "chunked")) {
       return -ERR_LENGTH_REQUIRED;
@@ -136,10 +139,10 @@ int RGWOp_Metadata_Put::get_data(bufferlist& bl) {
       return -ENOMEM;
     }
     do {
-      int r = s->cio->read(data, chunk_size, &read_len);
+      int r = STREAM_IO(s)->read(data, chunk_size, &read_len);
       if (r < 0) {
-        free(data);
-        return r;
+	free(data);
+	return r;
       }
       bl.append(data, read_len);
     } while (read_len == chunk_size);
@@ -157,23 +160,31 @@ void RGWOp_Metadata_Put::execute() {
   if (http_ret < 0) {
     return;
   }
+
+  if (s->aws4_auth_needs_complete) {
+    http_ret = do_aws4_auth_completion();
+    if (http_ret < 0) {
+      return;
+    }
+  }
   
   frame_metadata_key(s, metadata_key);
-  
+
   RGWMetadataHandler::sync_type_t sync_type = RGWMetadataHandler::APPLY_ALWAYS;
 
   bool mode_exists = false;
   string mode_string = s->info.args.get("update-type", &mode_exists);
   if (mode_exists) {
     bool parsed = RGWMetadataHandler::string_to_sync_type(mode_string,
-                                                          sync_type);
+							  sync_type);
     if (!parsed) {
       http_ret = -EINVAL;
       return;
     }
   }
 
-  http_ret = store->meta_mgr->put(metadata_key, bl, sync_type, &ondisk_version);
+  http_ret = store->meta_mgr->put(metadata_key, bl, sync_type,
+				  &ondisk_version);
   if (http_ret < 0) {
     dout(5) << "ERROR: can't put key: " << cpp_strerror(http_ret) << dendl;
     return;
@@ -222,7 +233,7 @@ void RGWOp_Metadata_Lock::execute() {
   duration_str = s->info.args.get("length");
   lock_id      = s->info.args.get("lock_id");
 
-  if ((!s->info.args.exists("key")) || 
+  if ((!s->info.args.exists("key")) ||
       (duration_str.empty()) ||
       lock_id.empty()) {
     dout(5) << "Error invalid parameter list" << dendl;
@@ -239,8 +250,7 @@ void RGWOp_Metadata_Lock::execute() {
     http_ret = -EINVAL;
     return;
   }
-  utime_t time(dur, 0);
-  http_ret = store->meta_mgr->lock_exclusive(metadata_key, time, lock_id);
+  http_ret = store->meta_mgr->lock_exclusive(metadata_key, make_timespan(dur), lock_id);
   if (http_ret == -EBUSY)
     http_ret = -ERR_LOCKED;
 }
@@ -255,7 +265,7 @@ void RGWOp_Metadata_Unlock::execute() {
 
   lock_id = s->info.args.get("lock_id");
 
-  if ((!s->info.args.exists("key")) || 
+  if ((!s->info.args.exists("key")) ||
       lock_id.empty()) {
     dout(5) << "Error invalid parameter list" << dendl;
     http_ret = -EINVAL;
@@ -288,4 +298,3 @@ RGWOp *RGWHandler_Metadata::op_post() {
 
   return NULL;
 }
-
diff --git a/src/rgw/rgw_rest_metadata.h b/src/rgw/rgw_rest_metadata.h
index 7f3cf1f..2511b9b 100644
--- a/src/rgw/rgw_rest_metadata.h
+++ b/src/rgw/rgw_rest_metadata.h
@@ -11,8 +11,9 @@
  * Foundation. See file COPYING.
  *
  */
-#ifndef CEPH_RGW_REST_METADATA_H
-#define CEPH_RGW_REST_METADATA_H
+
+#ifndef RGW_REST_METADATA_H
+#define RGW_REST_METADATA_H
 
 class RGWOp_Metadata_List : public RGWRESTOp {
 public:
@@ -52,6 +53,7 @@ public:
   void execute();
   void send_response();
   virtual const string name() { return "set_metadata"; }
+  RGWOpType get_type() { return RGW_OP_ADMIN_SET_METADATA; }
 };
 
 class RGWOp_Metadata_Delete : public RGWRESTOp {
@@ -114,10 +116,9 @@ public:
   RGWRESTMgr_Metadata() {}
   virtual ~RGWRESTMgr_Metadata() {}
 
-  virtual RGWHandler *get_handler(struct req_state *s){
+  virtual RGWHandler_REST* get_handler(struct req_state *s){
     return new RGWHandler_Metadata;
   }
 };
 
-
-#endif
+#endif /* RGW_REST_METADATA_H */
diff --git a/src/rgw/rgw_rest_opstate.cc b/src/rgw/rgw_rest_opstate.cc
index 2b215a7..02bdf17 100644
--- a/src/rgw/rgw_rest_opstate.cc
+++ b/src/rgw/rgw_rest_opstate.cc
@@ -19,6 +19,7 @@
 #include "rgw_rest_opstate.h"
 #include "rgw_client_io.h"
 #include "common/errno.h"
+#include "include/assert.h"
 
 #define OPSTATE_LIST_MAX_ENTRIES 1000
 #define dout_subsys ceph_subsys_rgw
diff --git a/src/rgw/rgw_rest_opstate.h b/src/rgw/rgw_rest_opstate.h
index de13dde..1a8076c 100644
--- a/src/rgw/rgw_rest_opstate.h
+++ b/src/rgw/rgw_rest_opstate.h
@@ -11,8 +11,9 @@
  * Foundation. See file COPYING.
  *
  */
-#ifndef CEPH_RGW_REST_OPSTATE_H
-#define CEPH_RGW_REST_OPSTATE_H
+
+#ifndef RGW_REST_OPSTATE_H
+#define RGW_REST_OPSTATE_H
 
 class RGWOp_Opstate_List : public RGWRESTOp {
   bool sent_header;
@@ -24,7 +25,7 @@ public:
     return caps.check_cap("opstate", RGW_CAP_READ);
   }
   int verify_permission() {
-    return check_caps(s->user.caps);
+    return check_caps(s->user->caps);
   }
   void execute();
   virtual void send_response();
@@ -100,10 +101,9 @@ public:
   RGWRESTMgr_Opstate() {}
   virtual ~RGWRESTMgr_Opstate() {}
 
-  virtual RGWHandler *get_handler(struct req_state *s){
+  virtual RGWHandler_REST* get_handler(struct req_state *s){
     return new RGWHandler_Opstate;
   }
 };
 
-#endif /*!CEPH_RGW_REST_OPSTATE_H*/
-
+#endif /*!RGW_REST_OPSTATE_H*/
diff --git a/src/rgw/rgw_rest_realm.cc b/src/rgw/rgw_rest_realm.cc
new file mode 100644
index 0000000..488c0cc
--- /dev/null
+++ b/src/rgw/rgw_rest_realm.cc
@@ -0,0 +1,280 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+
+#include "common/errno.h"
+#include "rgw_rest_realm.h"
+#include "rgw_rest_s3.h"
+#include "rgw_rest_config.h"
+
+#include "include/assert.h"
+
+#define dout_subsys ceph_subsys_rgw
+
+// reject 'period push' if we would have to fetch too many intermediate periods
+static const uint32_t PERIOD_HISTORY_FETCH_MAX = 64;
+
+// base period op, shared between Get and Post
+class RGWOp_Period_Base : public RGWRESTOp {
+ protected:
+  RGWPeriod period;
+ public:
+  int verify_permission() override { return 0; }
+  void send_response() override;
+};
+
+// reply with the period object on success
+void RGWOp_Period_Base::send_response()
+{
+  set_req_state_err(s, http_ret);
+  dump_errno(s);
+  end_header(s);
+
+  if (http_ret < 0)
+    return;
+
+  encode_json("period", period, s->formatter);
+  flusher.flush();
+}
+
+// GET /admin/realm/period
+class RGWOp_Period_Get : public RGWOp_Period_Base {
+ public:
+  void execute() override;
+  const string name() override { return "get_period"; }
+};
+
+void RGWOp_Period_Get::execute()
+{
+  string realm_id, realm_name, period_id;
+  epoch_t epoch = 0;
+  RESTArgs::get_string(s, "realm_id", realm_id, &realm_id);
+  RESTArgs::get_string(s, "realm_name", realm_name, &realm_name);
+  RESTArgs::get_string(s, "period_id", period_id, &period_id);
+  RESTArgs::get_uint32(s, "epoch", 0, &epoch);
+
+  period.set_id(period_id);
+  period.set_epoch(epoch);
+
+  http_ret = period.init(store->ctx(), store, realm_id, realm_name);
+  if (http_ret < 0)
+    ldout(store->ctx(), 5) << "failed to read period" << dendl;
+}
+
+// POST /admin/realm/period
+class RGWOp_Period_Post : public RGWOp_Period_Base {
+ public:
+  void execute() override;
+  const string name() override { return "post_period"; }
+};
+
+void RGWOp_Period_Post::execute()
+{
+  auto cct = store->ctx();
+
+  // initialize the period without reading from rados
+  period.init(cct, store, false);
+
+  // decode the period from input
+#define PERIOD_MAX_LEN 4096
+  bool empty;
+  http_ret = rgw_rest_get_json_input(cct, s, period, PERIOD_MAX_LEN, &empty);
+  if (http_ret < 0) {
+    lderr(cct) << "failed to decode period" << dendl;
+    return;
+  }
+
+  // require period.realm_id to match our realm
+  if (period.get_realm() != store->realm.get_id()) {
+    lderr(cct) << "period with realm id " << period.get_realm()
+        << " doesn't match current realm " << store->realm.get_id() << dendl;
+    http_ret = -EINVAL;
+    return;
+  }
+
+  // load the realm and current period from rados; there may be a more recent
+  // period that we haven't restarted with yet. we also don't want to modify
+  // the objects in use by RGWRados
+  RGWRealm realm(period.get_realm());
+  http_ret = realm.init(cct, store);
+  if (http_ret < 0) {
+    lderr(cct) << "failed to read current realm: "
+        << cpp_strerror(-http_ret) << dendl;
+    return;
+  }
+
+  RGWPeriod current_period;
+  http_ret = current_period.init(cct, store, realm.get_id());
+  if (http_ret < 0) {
+    lderr(cct) << "failed to read current period: "
+        << cpp_strerror(-http_ret) << dendl;
+    return;
+  }
+
+  // if period id is empty, handle as 'period commit'
+  if (period.get_id().empty()) {
+    http_ret = period.commit(realm, current_period);
+    if (http_ret < 0) {
+      lderr(cct) << "master zone failed to commit period" << dendl;
+    }
+    return;
+  }
+
+  // if it's not period commit, nobody is allowed to push to the master zone
+  if (period.get_master_zone() == store->get_zone_params().get_id()) {
+    ldout(cct, 10) << "master zone rejecting period id="
+        << period.get_id() << " epoch=" << period.get_epoch() << dendl;
+    http_ret = -EINVAL; // XXX: error code
+    return;
+  }
+
+  // write the period to rados
+  http_ret = period.store_info(false);
+  if (http_ret < 0) {
+    lderr(cct) << "failed to store period " << period.get_id() << dendl;
+    return;
+  }
+
+  // decide whether we can set_current_period() or set_latest_epoch()
+  if (period.get_id() != current_period.get_id()) {
+    auto current_epoch = current_period.get_realm_epoch();
+    // discard periods in the past
+    if (period.get_realm_epoch() < current_epoch) {
+      ldout(cct, 10) << "discarding period " << period.get_id()
+          << " with realm epoch " << period.get_realm_epoch()
+          << " older than current epoch " << current_epoch << dendl;
+      // return success to ack that we have this period
+      return;
+    }
+    // discard periods too far in the future
+    if (period.get_realm_epoch() > current_epoch + PERIOD_HISTORY_FETCH_MAX) {
+      lderr(cct) << "discarding period " << period.get_id()
+          << " with realm epoch " << period.get_realm_epoch() << " too far in "
+          "the future from current epoch " << current_epoch << dendl;
+      http_ret = -ENOENT; // XXX: error code
+      return;
+    }
+    // attach a copy of the period into the period history
+    auto cursor = store->period_history->attach(RGWPeriod{period});
+    if (!cursor) {
+      // we're missing some history between the new period and current_period
+      http_ret = cursor.get_error();
+      lderr(cct) << "failed to collect the periods between current period "
+          << current_period.get_id() << " (realm epoch " << current_epoch
+          << ") and the new period " << period.get_id()
+          << " (realm epoch " << period.get_realm_epoch()
+          << "): " << cpp_strerror(-http_ret) << dendl;
+      return;
+    }
+    if (cursor.has_next()) {
+      // don't switch if we have a newer period in our history
+      ldout(cct, 4) << "attached period " << period.get_id()
+          << " to history, but the history contains newer periods" << dendl;
+      return;
+    }
+    // set as current period
+    http_ret = realm.set_current_period(period);
+    if (http_ret < 0) {
+      lderr(cct) << "failed to update realm's current period" << dendl;
+      return;
+    }
+    ldout(cct, 4) << "period " << period.get_id()
+        << " is newer than current period " << current_period.get_id()
+        << ", updating realm's current period and notifying zone" << dendl;
+    realm.notify_new_period(period);
+    return;
+  }
+
+  if (period.get_epoch() <= current_period.get_epoch()) {
+    lderr(cct) << "period epoch " << period.get_epoch() << " is not newer "
+        "than current epoch " << current_period.get_epoch()
+        << ", discarding update" << dendl;
+    return;
+  }
+  // set as latest epoch
+  http_ret = period.set_latest_epoch(period.get_epoch());
+  if (http_ret < 0) {
+    lderr(cct) << "failed to set latest epoch" << dendl;
+    return;
+  }
+  // reflect the period into our local objects
+  http_ret  = period.reflect();
+  if (http_ret  < 0) {
+    lderr(cct) << "failed to update local objects: "
+        << cpp_strerror(-http_ret) << dendl;
+    return;
+  }
+  ldout(cct, 4) << "period epoch " << period.get_epoch()
+      << " is newer than current epoch " << current_period.get_epoch()
+      << ", updating period's latest epoch and notifying zone" << dendl;
+  realm.notify_new_period(period);
+  // update the period history
+  store->period_history->insert(RGWPeriod{period});
+}
+
+class RGWHandler_Period : public RGWHandler_Auth_S3 {
+ protected:
+  RGWOp *op_get() override { return new RGWOp_Period_Get; }
+  RGWOp *op_post() override { return new RGWOp_Period_Post; }
+};
+
+class RGWRESTMgr_Period : public RGWRESTMgr {
+ public:
+  RGWHandler_REST* get_handler(struct req_state*) override {
+    return new RGWHandler_Period;
+  }
+};
+
+
+// GET /admin/realm
+class RGWOp_Realm_Get : public RGWRESTOp {
+  std::unique_ptr<RGWRealm> realm;
+public:
+  int verify_permission() override { return 0; }
+  void execute() override;
+  void send_response() override;
+  const string name() { return "get_realm"; }
+};
+
+void RGWOp_Realm_Get::execute()
+{
+  string id;
+  RESTArgs::get_string(s, "id", id, &id);
+  string name;
+  RESTArgs::get_string(s, "name", name, &name);
+
+  // read realm
+  realm.reset(new RGWRealm(id, name));
+  http_ret = realm->init(g_ceph_context, store);
+  if (http_ret < 0)
+    lderr(store->ctx()) << "failed to read realm id=" << id
+        << " name=" << name << dendl;
+}
+
+void RGWOp_Realm_Get::send_response()
+{
+  set_req_state_err(s, http_ret);
+  dump_errno(s);
+  end_header(s);
+
+  if (http_ret < 0)
+    return;
+
+  encode_json("realm", *realm, s->formatter);
+  flusher.flush();
+}
+
+class RGWHandler_Realm : public RGWHandler_Auth_S3 {
+protected:
+  RGWOp *op_get() { return new RGWOp_Realm_Get; }
+};
+
+RGWRESTMgr_Realm::RGWRESTMgr_Realm()
+{
+  // add the /admin/realm/period resource
+  register_resource("period", new RGWRESTMgr_Period);
+}
+
+RGWHandler_REST* RGWRESTMgr_Realm::get_handler(struct req_state*)
+{
+  return new RGWHandler_Realm;
+}
diff --git a/src/rgw/rgw_rest_realm.h b/src/rgw/rgw_rest_realm.h
new file mode 100644
index 0000000..cb61594
--- /dev/null
+++ b/src/rgw/rgw_rest_realm.h
@@ -0,0 +1,16 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+
+#ifndef CEPH_RGW_REST_REALM_H
+#define CEPH_RGW_REST_REALM_H
+
+#include "rgw_rest.h"
+
+class RGWRESTMgr_Realm : public RGWRESTMgr {
+public:
+  RGWRESTMgr_Realm();
+
+  RGWHandler_REST* get_handler(struct req_state*) override;
+};
+
+#endif
diff --git a/src/rgw/rgw_rest_replica_log.cc b/src/rgw/rgw_rest_replica_log.cc
index 74b4549..4768284 100644
--- a/src/rgw/rgw_rest_replica_log.cc
+++ b/src/rgw/rgw_rest_replica_log.cc
@@ -22,6 +22,7 @@
 #include "rgw_rest_replica_log.h"
 #include "rgw_client_io.h"
 #include "common/errno.h"
+#include "include/assert.h"
 
 #define dout_subsys ceph_subsys_rgw
 #define REPLICA_INPUT_MAX_LEN (512*1024)
@@ -37,7 +38,6 @@ static int parse_to_utime(string& in, utime_t& out) {
   return 0;
 }
 
-
 void RGWOp_OBJLog_SetBounds::execute() {
   string id_str = s->info.args.get("id"),
          marker = s->info.args.get("marker"),
@@ -148,7 +148,7 @@ void RGWOp_OBJLog_DeleteBounds::execute() {
 
 static int bucket_instance_to_bucket(RGWRados *store, const string& bucket_instance, rgw_bucket& bucket) {
   RGWBucketInfo bucket_info;
-  time_t mtime;
+  real_time mtime;
   
   RGWObjectCtx obj_ctx(store);
   int r = store->get_bucket_instance_info(obj_ctx, bucket_instance, bucket_info, &mtime, NULL);
diff --git a/src/rgw/rgw_rest_replica_log.h b/src/rgw/rgw_rest_replica_log.h
index c879150..76ccc3f 100644
--- a/src/rgw/rgw_rest_replica_log.h
+++ b/src/rgw/rgw_rest_replica_log.h
@@ -11,8 +11,9 @@
  * Foundation. See file COPYING.
  *
  */
-#ifndef CEPH_RGW_REST_REPLICA_LOG_H
-#define CEPH_RGW_REST_REPLICA_LOG_H
+
+#ifndef RGW_REST_REPLICA_LOG_H
+#define RGW_REST_REPLICA_LOG_H
 
 class RGWOp_OBJLog_GetBounds : public RGWRESTOp {
   string prefix;
@@ -28,7 +29,7 @@ public:
     return caps.check_cap(obj_type.c_str(), RGW_CAP_READ);
   }
   int verify_permission() {
-    return check_caps(s->user.caps);
+    return check_caps(s->user->caps);
   }
   void execute();
   virtual void send_response();
@@ -90,7 +91,7 @@ public:
     return caps.check_cap("bilog", RGW_CAP_READ);
   }
   int verify_permission() {
-    return check_caps(s->user.caps);
+    return check_caps(s->user->caps);
   }
   void execute();
   virtual void send_response();
@@ -146,9 +147,9 @@ public:
   RGWRESTMgr_ReplicaLog() {}
   virtual ~RGWRESTMgr_ReplicaLog() {}
 
-  virtual RGWHandler *get_handler(struct req_state *s){
+  virtual RGWHandler_REST* get_handler(struct req_state *s){
     return new RGWHandler_ReplicaLog;
   }
 };
 
-#endif /*!CEPH_RGW_REST_REPLICA_LOG_H*/
+#endif /*!RGW_REST_REPLICA_LOG_H*/
diff --git a/src/rgw/rgw_rest_s3.cc b/src/rgw/rgw_rest_s3.cc
index 9572193..9c525d1 100644
--- a/src/rgw/rgw_rest_s3.cc
+++ b/src/rgw/rgw_rest_s3.cc
@@ -27,10 +27,17 @@
 
 #include <typeinfo> // for 'typeid'
 
+#include "rgw_ldap.h"
+#include "rgw_token.h"
+#include "include/assert.h"
+
 #define dout_subsys ceph_subsys_rgw
 
+using namespace rgw;
 using namespace ceph::crypto;
 
+using std::get;
+
 void list_all_buckets_start(struct req_state *s)
 {
   s->formatter->open_array_section_in_ns("ListAllMyBucketsResult",
@@ -105,7 +112,30 @@ int RGWGetObj_ObjStore_S3::send_response_data_error()
   return send_response_data(bl, 0 , 0);
 }
 
-int RGWGetObj_ObjStore_S3::send_response_data(bufferlist& bl, off_t bl_ofs, off_t bl_len)
+template <class T>
+int decode_attr_bl_single_value(map<string, bufferlist>& attrs, const char *attr_name, T *result, T def_val)
+{
+  map<string, bufferlist>::iterator iter = attrs.find(attr_name);
+  if (iter == attrs.end()) {
+    *result = def_val;
+    return 0;
+  }
+  bufferlist& bl = iter->second;
+  if (bl.length() == 0) {
+    *result = def_val;
+    return 0;
+  }
+  bufferlist::iterator bliter = bl.begin();
+  try {
+    ::decode(*result, bliter);
+  } catch (buffer::error& err) {
+    return -EIO;
+  }
+  return 0;
+}
+
+int RGWGetObj_ObjStore_S3::send_response_data(bufferlist& bl, off_t bl_ofs,
+					      off_t bl_len)
 {
   const char *content_type = NULL;
   string content_type_str;
@@ -129,30 +159,55 @@ int RGWGetObj_ObjStore_S3::send_response_data(bufferlist& bl, off_t bl_ofs, off_
     JSONFormatter jf;
     jf.open_object_section("obj_metadata");
     encode_json("attrs", attrs, &jf);
-    encode_json("mtime", lastmod, &jf);
+    utime_t ut(lastmod);
+    encode_json("mtime", ut, &jf);
     jf.close_section();
     stringstream ss;
     jf.flush(ss);
     metadata_bl.append(ss.str());
-    s->cio->print("Rgwx-Embedded-Metadata-Len: %lld\r\n", (long long)metadata_bl.length());
+    STREAM_IO(s)->print("Rgwx-Embedded-Metadata-Len: %lld\r\n",
+			(long long)metadata_bl.length());
     total_len += metadata_bl.length();
   }
 
-  if (s->system_request && lastmod) {
+  if (s->system_request && !real_clock::is_zero(lastmod)) {
     /* we end up dumping mtime in two different methods, a bit redundant */
     dump_epoch_header(s, "Rgwx-Mtime", lastmod);
+    uint64_t pg_ver = 0;
+    int r = decode_attr_bl_single_value(attrs, RGW_ATTR_PG_VER, &pg_ver, (uint64_t)0);
+    if (r < 0) {
+      ldout(s->cct, 0) << "ERROR: failed to decode pg ver attr, ignoring" << dendl;
+    }
+    STREAM_IO(s)->print("Rgwx-Obj-PG-Ver: %lld\r\n", (long long)pg_ver);
+
+    uint32_t source_zone_short_id = 0;
+    r = decode_attr_bl_single_value(attrs, RGW_ATTR_SOURCE_ZONE, &source_zone_short_id, (uint32_t)0);
+    if (r < 0) {
+      ldout(s->cct, 0) << "ERROR: failed to decode pg ver attr, ignoring" << dendl;
+    }
+    if (source_zone_short_id != 0) {
+      STREAM_IO(s)->print("Rgwx-Source-Zone-Short-Id: %lld\r\n", (long long)source_zone_short_id);
+    }
   }
 
   dump_content_length(s, total_len);
   dump_last_modified(s, lastmod);
 
   if (! op_ret) {
-    map<string, bufferlist>::iterator iter = attrs.find(RGW_ATTR_ETAG);
-    if (iter != attrs.end()) {
-      bufferlist& bl = iter->second;
-      if (bl.length()) {
-        char *etag = bl.c_str();
-        dump_etag(s, etag);
+    if (! lo_etag.empty()) {
+      /* Handle etag of Swift API's large objects (DLO/SLO). It's entirerly
+       * legit to perform GET on them through S3 API. In such situation,
+       * a client should receive the composited content with corresponding
+       * etag value. */
+      dump_etag(s, lo_etag.c_str());
+    } else {
+      auto iter = attrs.find(RGW_ATTR_ETAG);
+      if (iter != attrs.end()) {
+        bufferlist& bl = iter->second;
+        if (bl.length()) {
+	  const char * etag = bl.c_str();
+	  dump_etag(s, etag);
+        }
       }
     }
 
@@ -169,9 +224,8 @@ int RGWGetObj_ObjStore_S3::send_response_data(bufferlist& bl, off_t bl_ofs, off_
       }
     }
 
-    for (iter = attrs.begin(); iter != attrs.end(); ++iter) {
+    for (auto iter = attrs.begin(); iter != attrs.end(); ++iter) {
       const char *name = iter->first.c_str();
-
       map<string, string>::iterator aiter = rgw_to_http_attrs.find(name);
       if (aiter != rgw_to_http_attrs.end()) {
         if (response_attrs.count(aiter->second) == 0) {
@@ -183,22 +237,24 @@ int RGWGetObj_ObjStore_S3::send_response_data(bufferlist& bl, off_t bl_ofs, off_
         if (!content_type) {
           content_type = iter->second.c_str();
         }
-      } else if (strncmp(name, RGW_ATTR_META_PREFIX, sizeof(RGW_ATTR_META_PREFIX)-1) == 0) {
+      } else if (strncmp(name, RGW_ATTR_META_PREFIX,
+			 sizeof(RGW_ATTR_META_PREFIX)-1) == 0) {
         /* User custom metadata. */
         name += sizeof(RGW_ATTR_PREFIX) - 1;
-        s->cio->print("%s: %s\r\n", name, iter->second.c_str());
+        STREAM_IO(s)->print("%s: %s\r\n", name, iter->second.c_str());
       }
     }
   }
 
 done:
-  set_req_state_err(s, (partial_content && !op_ret) ? STATUS_PARTIAL_CONTENT :
-		    op_ret);
-
+  set_req_state_err(s, (partial_content && !op_ret) ? STATUS_PARTIAL_CONTENT
+		    : op_ret);
   dump_errno(s);
 
-  for (riter = response_attrs.begin(); riter != response_attrs.end(); ++riter) {
-    s->cio->print("%s: %s\r\n", riter->first.c_str(), riter->second.c_str());
+  for (riter = response_attrs.begin(); riter != response_attrs.end();
+       ++riter) {
+    STREAM_IO(s)->print("%s: %s\r\n", riter->first.c_str(),
+			riter->second.c_str());
   }
 
   if (!content_type)
@@ -207,13 +263,13 @@ done:
   end_header(s, this, content_type);
 
   if (metadata_bl.length()) {
-    s->cio->write(metadata_bl.c_str(), metadata_bl.length());
+    STREAM_IO(s)->write(metadata_bl.c_str(), metadata_bl.length());
   }
   sent_header = true;
 
 send_data:
   if (get_data && !op_ret) {
-    int r = s->cio->write(bl.c_str() + bl_ofs, bl_len);
+    int r = STREAM_IO(s)->write(bl.c_str() + bl_ofs, bl_len);
     if (r < 0)
       return r;
   }
@@ -231,7 +287,7 @@ void RGWListBuckets_ObjStore_S3::send_response_begin(bool has_buckets)
 
   if (! op_ret) {
     list_all_buckets_start(s);
-    dump_owner(s, s->user.user_id, s->user.display_name);
+    dump_owner(s, s->user->user_id, s->user->display_name);
     s->formatter->open_array_section("Buckets");
     sent_data = true;
   }
@@ -261,6 +317,115 @@ void RGWListBuckets_ObjStore_S3::send_response_end()
   }
 }
 
+int RGWGetUsage_ObjStore_S3::get_params()
+{
+  start_date = s->info.args.get("start-date");
+  end_date = s->info.args.get("end-date"); 
+  return 0;
+}
+
+static void dump_usage_categories_info(Formatter *formatter, const rgw_usage_log_entry& entry, map<string, bool> *categories)
+{
+  formatter->open_array_section("categories");
+  map<string, rgw_usage_data>::const_iterator uiter;
+  for (uiter = entry.usage_map.begin(); uiter != entry.usage_map.end(); ++uiter) {
+    if (categories && !categories->empty() && !categories->count(uiter->first))
+      continue;
+    const rgw_usage_data& usage = uiter->second;
+    formatter->open_object_section("Entry");
+    formatter->dump_string("Category", uiter->first);
+    formatter->dump_int("BytesSent", usage.bytes_sent);
+    formatter->dump_int("BytesReceived", usage.bytes_received);
+    formatter->dump_int("Ops", usage.ops);
+    formatter->dump_int("SuccessfulOps", usage.successful_ops);
+    formatter->close_section(); // Entry
+  }
+  formatter->close_section(); // Category
+}
+
+void RGWGetUsage_ObjStore_S3::send_response()
+{
+  if (op_ret < 0)
+    set_req_state_err(s, op_ret);
+  dump_errno(s);
+
+  end_header(s, this, "application/xml");
+  dump_start(s);
+  if (op_ret < 0)
+    return;
+
+  Formatter *formatter = s->formatter;
+  string last_owner;
+  bool user_section_open = false;
+  
+  formatter->open_object_section("Usage");
+  if (show_log_entries) {
+    formatter->open_array_section("Entries");
+  }
+  map<rgw_user_bucket, rgw_usage_log_entry>::iterator iter;
+  for (iter = usage.begin(); iter != usage.end(); ++iter) {
+    const rgw_user_bucket& ub = iter->first;
+    const rgw_usage_log_entry& entry = iter->second;
+
+    if (show_log_entries) {
+      if (ub.user.compare(last_owner) != 0) {
+        if (user_section_open) {
+          formatter->close_section();
+          formatter->close_section();
+        }
+        formatter->open_object_section("User");
+        formatter->dump_string("Owner", ub.user);
+        formatter->open_array_section("Buckets");
+        user_section_open = true;
+        last_owner = ub.user;
+      }
+      formatter->open_object_section("Bucket");
+      formatter->dump_string("Bucket", ub.bucket);
+      utime_t ut(entry.epoch, 0);
+      ut.gmtime(formatter->dump_stream("Time"));
+      formatter->dump_int("Epoch", entry.epoch);
+      dump_usage_categories_info(formatter, entry, &categories);
+      formatter->close_section(); // bucket
+    }
+
+    summary_map[ub.user].aggregate(entry, &categories);
+  }
+
+  if (show_log_entries) {
+     if (user_section_open) {
+       formatter->close_section(); // buckets
+       formatter->close_section(); //user
+     }
+     formatter->close_section(); // entries
+   }
+  
+   if (show_log_sum) {
+     formatter->open_array_section("Summary");
+     map<string, rgw_usage_log_entry>::iterator siter;
+     for (siter = summary_map.begin(); siter != summary_map.end(); ++siter) {
+       const rgw_usage_log_entry& entry = siter->second;
+       formatter->open_object_section("User");
+       formatter->dump_string("User", siter->first);
+       dump_usage_categories_info(formatter, entry, &categories);
+       rgw_usage_data total_usage;
+       entry.sum(total_usage, categories);
+       formatter->open_object_section("Total");
+       formatter->dump_int("BytesSent", total_usage.bytes_sent);
+       formatter->dump_int("BytesReceived", total_usage.bytes_received);
+       formatter->dump_int("Ops", total_usage.ops);
+       formatter->dump_int("SuccessfulOps", total_usage.successful_ops);
+       formatter->close_section(); // total 
+       formatter->close_section(); // user
+     } 
+     formatter->dump_int("TotalBytes", header.stats.total_bytes);
+     formatter->dump_int("TotalBytesRounded", header.stats.total_bytes_rounded);
+     formatter->dump_int("TotalEntries", header.stats.total_entries);
+     formatter->close_section(); // summary
+   }
+   formatter->close_section(); // usage
+   rgw_flush_formatter_and_reset(s, s->formatter);
+}
+
 int RGWListBucket_ObjStore_S3::get_params()
 {
   list_versions = s->info.args.exists("versions");
@@ -278,6 +443,20 @@ int RGWListBucket_ObjStore_S3::get_params()
   }
   delimiter = s->info.args.get("delimiter");
   encoding_type = s->info.args.get("encoding-type");
+  if (s->system_request) {
+    s->info.args.get_bool("objs-container", &objs_container, false);
+    const char *shard_id_str = s->info.env->get("HTTP_RGWX_SHARD_ID");
+    if (shard_id_str) {
+      string err;
+      shard_id = strict_strtol(shard_id_str, 10, &err);
+      if (!err.empty()) {
+        ldout(s->cct, 5) << "bad shard id specified: " << shard_id_str << dendl;
+        return -EINVAL;
+      }
+    } else {
+      shard_id = s->bucket_instance_shard_id;
+    }
+  }
   return 0;
 }
 
@@ -296,49 +475,67 @@ void RGWListBucket_ObjStore_S3::send_versioned_response()
   if (!delimiter.empty())
     s->formatter->dump_string("Delimiter", delimiter);
 
-  s->formatter->dump_string("IsTruncated", (max && is_truncated ? "true" : "false"));
+  s->formatter->dump_string("IsTruncated", (max && is_truncated ? "true"
+					    : "false"));
 
   bool encode_key = false;
   if (strcasecmp(encoding_type.c_str(), "url") == 0)
     encode_key = true;
 
   if (op_ret >= 0) {
+    if (objs_container) {
+      s->formatter->open_array_section("Entries");
+    }
+
     vector<RGWObjEnt>::iterator iter;
     for (iter = objs.begin(); iter != objs.end(); ++iter) {
-      time_t mtime = iter->mtime.sec();
-      const char *section_name = (iter->is_delete_marker() ? "DeleteMarker" : "Version");
-      s->formatter->open_array_section(section_name);
+      const char *section_name = (iter->is_delete_marker() ? "DeleteMarker"
+				  : "Version");
+      s->formatter->open_object_section(section_name);
+      if (objs_container) {
+        s->formatter->dump_bool("IsDeleteMarker", iter->is_delete_marker());
+      }
       if (encode_key) {
-        string key_name;
-        url_encode(iter->key.name, key_name);
-        s->formatter->dump_string("Key", key_name);
+	string key_name;
+	url_encode(iter->key.name, key_name);
+	s->formatter->dump_string("Key", key_name);
       } else {
-        s->formatter->dump_string("Key", iter->key.name);
+	s->formatter->dump_string("Key", iter->key.name);
       }
       string version_id = iter->key.instance;
       if (version_id.empty()) {
-        version_id = "null";
+	version_id = "null";
       }
-      if (s->system_request && iter->versioned_epoch > 0) {
-        s->formatter->dump_int("VersionedEpoch", iter->versioned_epoch);
+      if (s->system_request) {
+        if (iter->versioned_epoch > 0) {
+          s->formatter->dump_int("VersionedEpoch", iter->versioned_epoch);
+        }
+        s->formatter->dump_string("RgwxTag", iter->tag);
+        utime_t ut(iter->mtime);
+        ut.gmtime_nsec(s->formatter->dump_stream("RgwxMtime"));
       }
       s->formatter->dump_string("VersionId", version_id);
       s->formatter->dump_bool("IsLatest", iter->is_current());
-      dump_time(s, "LastModified", &mtime);
+      dump_time(s, "LastModified", &iter->mtime);
       if (!iter->is_delete_marker()) {
-        s->formatter->dump_format("ETag", "\"%s\"", iter->etag.c_str());
-        s->formatter->dump_int("Size", iter->size);
-        s->formatter->dump_string("StorageClass", "STANDARD");
+	s->formatter->dump_format("ETag", "\"%s\"", iter->etag.c_str());
+	s->formatter->dump_int("Size", iter->size);
+	s->formatter->dump_string("StorageClass", "STANDARD");
       }
       dump_owner(s, iter->owner, iter->owner_display_name);
       s->formatter->close_section();
     }
+    if (objs_container) {
+      s->formatter->close_section();
+    }
+
     if (!common_prefixes.empty()) {
       map<string, bool>::iterator pref_iter;
-      for (pref_iter = common_prefixes.begin(); pref_iter != common_prefixes.end(); ++pref_iter) {
-        s->formatter->open_array_section("CommonPrefixes");
-        s->formatter->dump_string("Prefix", pref_iter->first);
-        s->formatter->close_section();
+      for (pref_iter = common_prefixes.begin();
+	   pref_iter != common_prefixes.end(); ++pref_iter) {
+	s->formatter->open_array_section("CommonPrefixes");
+	s->formatter->dump_string("Prefix", pref_iter->first);
+	s->formatter->close_section();
       }
     }
   }
@@ -375,7 +572,8 @@ void RGWListBucket_ObjStore_S3::send_response()
   if (!delimiter.empty())
     s->formatter->dump_string("Delimiter", delimiter);
 
-  s->formatter->dump_string("IsTruncated", (max && is_truncated ? "true" : "false"));
+  s->formatter->dump_string("IsTruncated", (max && is_truncated ? "true"
+					    : "false"));
 
   bool encode_key = false;
   if (strcasecmp(encoding_type.c_str(), "url") == 0)
@@ -386,26 +584,29 @@ void RGWListBucket_ObjStore_S3::send_response()
     for (iter = objs.begin(); iter != objs.end(); ++iter) {
       s->formatter->open_array_section("Contents");
       if (encode_key) {
-        string key_name;
-        url_encode(iter->key.name, key_name);
-        s->formatter->dump_string("Key", key_name);
+	string key_name;
+	url_encode(iter->key.name, key_name);
+	s->formatter->dump_string("Key", key_name);
       } else {
-        s->formatter->dump_string("Key", iter->key.name);
+	s->formatter->dump_string("Key", iter->key.name);
       }
-      time_t mtime = iter->mtime.sec();
-      dump_time(s, "LastModified", &mtime);
+      dump_time(s, "LastModified", &iter->mtime);
       s->formatter->dump_format("ETag", "\"%s\"", iter->etag.c_str());
       s->formatter->dump_int("Size", iter->size);
       s->formatter->dump_string("StorageClass", "STANDARD");
       dump_owner(s, iter->owner, iter->owner_display_name);
+      if (s->system_request) {
+        s->formatter->dump_string("RgwxTag", iter->tag);
+      }
       s->formatter->close_section();
     }
     if (!common_prefixes.empty()) {
       map<string, bool>::iterator pref_iter;
-      for (pref_iter = common_prefixes.begin(); pref_iter != common_prefixes.end(); ++pref_iter) {
-        s->formatter->open_array_section("CommonPrefixes");
-        s->formatter->dump_string("Prefix", pref_iter->first);
-        s->formatter->close_section();
+      for (pref_iter = common_prefixes.begin();
+	   pref_iter != common_prefixes.end(); ++pref_iter) {
+	s->formatter->open_array_section("CommonPrefixes");
+	s->formatter->dump_string("Prefix", pref_iter->first);
+	s->formatter->close_section();
       }
     }
   }
@@ -431,15 +632,15 @@ void RGWGetBucketLocation_ObjStore_S3::send_response()
   end_header(s, this);
   dump_start(s);
 
-  string region = s->bucket_info.region;
+  RGWZoneGroup zonegroup;
   string api_name;
 
-  map<string, RGWRegion>::iterator iter = store->region_map.regions.find(region);
-  if (iter != store->region_map.regions.end()) {
-    api_name = iter->second.api_name;
+  int ret = store->get_zonegroup(s->bucket_info.zonegroup, zonegroup);
+  if (ret >= 0) {
+    api_name = zonegroup.api_name;
   } else  {
-    if (region != "default") {
-      api_name = region;
+    if (s->bucket_info.zonegroup != "default") {
+      api_name = s->bucket_info.zonegroup;
     }
   }
 
@@ -504,11 +705,19 @@ int RGWSetBucketVersioning_ObjStore_S3::get_params()
 
   char *data;
   int len = 0;
-  int r = rgw_rest_read_all_input(s, &data, &len, GET_BUCKET_VERSIONING_BUF_MAX);
+  int r =
+    rgw_rest_read_all_input(s, &data, &len, GET_BUCKET_VERSIONING_BUF_MAX);
   if (r < 0) {
     return r;
   }
 
+  if (s->aws4_auth_needs_complete) {
+    int ret_auth = do_aws4_auth_completion();
+    if (ret_auth < 0) {
+      return ret_auth;
+    }
+  }
+
   RGWSetBucketVersioningParser parser;
 
   if (!parser.init()) {
@@ -541,7 +750,7 @@ void RGWSetBucketVersioning_ObjStore_S3::send_response()
 
 int RGWSetBucketWebsite_ObjStore_S3::get_params()
 {
-#define GET_BUCKET_WEBSITE_BUF_MAX (128 * 1024)
+  static constexpr uint32_t GET_BUCKET_WEBSITE_BUF_MAX = (128 * 1024);
 
   char *data;
   int len = 0;
@@ -616,9 +825,9 @@ static void dump_bucket_metadata(struct req_state *s, RGWBucketEnt& bucket)
 {
   char buf[32];
   snprintf(buf, sizeof(buf), "%lld", (long long)bucket.count);
-  s->cio->print("X-RGW-Object-Count: %s\r\n", buf);
+  STREAM_IO(s)->print("X-RGW-Object-Count: %s\r\n", buf);
   snprintf(buf, sizeof(buf), "%lld", (long long)bucket.size);
-  s->cio->print("X-RGW-Bytes-Used: %s\r\n", buf);
+  STREAM_IO(s)->print("X-RGW-Bytes-Used: %s\r\n", buf);
 }
 
 void RGWStatBucket_ObjStore_S3::send_response()
@@ -634,7 +843,9 @@ void RGWStatBucket_ObjStore_S3::send_response()
   dump_start(s);
 }
 
-static int create_s3_policy(struct req_state *s, RGWRados *store, RGWAccessControlPolicy_S3& s3policy, ACLOwner& owner)
+static int create_s3_policy(struct req_state *s, RGWRados *store,
+			    RGWAccessControlPolicy_S3& s3policy,
+			    ACLOwner& owner)
 {
   if (s->has_acl_header) {
     if (!s->canned_acl.empty())
@@ -680,7 +891,7 @@ public:
   RGWCreateBucketParser() {}
   ~RGWCreateBucketParser() {}
 
-  bool get_location_constraint(string& region) {
+  bool get_location_constraint(string& zone_group) {
     XMLObj *config = find_first("CreateBucketConfiguration");
     if (!config)
       return false;
@@ -689,7 +900,7 @@ public:
     if (!constraint)
       return false;
 
-    region = constraint->get_data();
+    zone_group = constraint->get_data();
 
     return true;
   }
@@ -712,6 +923,13 @@ int RGWCreateBucket_ObjStore_S3::get_params()
   if ((op_ret < 0) && (op_ret != -ERR_LENGTH_REQUIRED))
     return op_ret;
 
+  if (s->aws4_auth_needs_complete) {
+    int ret_auth = do_aws4_auth_completion();
+    if (ret_auth < 0) {
+      return ret_auth;
+    }
+  }
+  
   bufferptr in_ptr(data, len);
   in_data.append(in_ptr);
 
@@ -738,7 +956,8 @@ int RGWCreateBucket_ObjStore_S3::get_params()
       return -EINVAL;
     }
 
-    ldout(s->cct, 10) << "create bucket location constraint: " << location_constraint << dendl;
+    ldout(s->cct, 10) << "create bucket location constraint: "
+		      << location_constraint << dendl;
   }
 
   int pos = location_constraint.find(':');
@@ -812,6 +1031,20 @@ int RGWPutObj_ObjStore_S3::get_params()
   return RGWPutObj_ObjStore::get_params();
 }
 
+int RGWPutObj_ObjStore_S3::get_data(bufferlist& bl)
+{
+  int ret = RGWPutObj_ObjStore::get_data(bl);
+  if (ret < 0)
+    s->aws4_auth_needs_complete = false;
+  if ((ret == 0) && s->aws4_auth_needs_complete) {
+    int ret_auth = do_aws4_auth_completion();
+    if (ret_auth < 0) {
+      return ret_auth;
+    }
+  }
+  return ret;
+}
+
 static int get_success_retcode(int code)
 {
   switch (code) {
@@ -836,7 +1069,7 @@ void RGWPutObj_ObjStore_S3::send_response()
     dump_etag(s, etag.c_str());
     dump_content_length(s, 0);
   }
-  if (s->system_request && mtime) {
+  if (s->system_request && !real_clock::is_zero(mtime)) {
     dump_epoch_header(s, "Rgwx-Mtime", mtime);
   }
   dump_errno(s);
@@ -846,7 +1079,8 @@ void RGWPutObj_ObjStore_S3::send_response()
 /*
  * parses params in the format: 'first; param1=foo; param2=bar'
  */
-static void parse_params(const string& params_str, string& first, map<string, string>& params)
+static void parse_params(const string& params_str, string& first,
+			 map<string, string>& params)
 {
   int pos = params_str.find(';');
   if (pos < 0) {
@@ -878,7 +1112,8 @@ static void parse_params(const string& params_str, string& first, map<string, st
   }
 }
 
-static int parse_part_field(const string& line, string& field_name, struct post_part_field& field)
+static int parse_part_field(const string& line, string& field_name,
+			    struct post_part_field& field)
 {
   int pos = line.find(':');
   if (pos < 0)
@@ -902,8 +1137,9 @@ bool is_crlf(const char *s)
  * find the index of the boundary, if exists, or optionally the next end of line
  * also returns how many bytes to skip
  */
-static int index_of(bufferlist& bl, int max_len, const string& str, bool check_crlf,
-                    bool *reached_boundary, int *skip)
+static int index_of(bufferlist& bl, int max_len, const string& str,
+		    bool check_crlf,
+		    bool *reached_boundary, int *skip)
 {
   *reached_boundary = false;
   *skip = 0;
@@ -923,13 +1159,13 @@ static int index_of(bufferlist& bl, int max_len, const string& str, bool check_c
   int i;
   for (i = 0; i < max_len; i++, buf++) {
     if (check_crlf &&
-        i >= 1 &&
-        is_crlf(buf - 1)) {
-        return i + 1; // skip the crlf
+	i >= 1 &&
+	is_crlf(buf - 1)) {
+      return i + 1; // skip the crlf
     }
     if ((i < max_len - (int)str.size() + 1) &&
-        (buf[0] == s[0] && buf[1] == s[1]) &&
-        (strncmp(buf, s, str.size()) == 0)) {
+	(buf[0] == s[0] && buf[1] == s[1]) &&
+	(strncmp(buf, s, str.size()) == 0)) {
       *reached_boundary = true;
       *skip = str.size();
 
@@ -937,9 +1173,9 @@ static int index_of(bufferlist& bl, int max_len, const string& str, bool check_c
        * if exists
        */
       if ((i >= 2) &&
-        is_crlf(buf - 2)) {
-        i -= 2;
-        *skip += 2;
+	  is_crlf(buf - 2)) {
+	i -= 2;
+	*skip += 2;
       }
       return i;
     }
@@ -948,8 +1184,10 @@ static int index_of(bufferlist& bl, int max_len, const string& str, bool check_c
   return -1;
 }
 
-int RGWPostObj_ObjStore_S3::read_with_boundary(bufferlist& bl, uint64_t max, bool check_crlf,
-                                               bool *reached_boundary, bool *done)
+int RGWPostObj_ObjStore_S3::read_with_boundary(bufferlist& bl, uint64_t max,
+					       bool check_crlf,
+					       bool *reached_boundary,
+					       bool *done)
 {
   uint64_t cl = max + 2 + boundary.size();
 
@@ -959,14 +1197,15 @@ int RGWPostObj_ObjStore_S3::read_with_boundary(bufferlist& bl, uint64_t max, boo
     bufferptr bp(need_to_read);
 
     int read_len;
-    s->cio->read(bp.c_str(), need_to_read, &read_len);
+    STREAM_IO(s)->read(bp.c_str(), need_to_read, &read_len);
 
     in_data.append(bp, 0, read_len);
   }
 
   *done = false;
   int skip;
-  int index = index_of(in_data, cl, boundary, check_crlf, reached_boundary, &skip);
+  int index = index_of(in_data, cl, boundary, check_crlf, reached_boundary,
+		       &skip);
   if (index >= 0)
     max = index;
 
@@ -987,7 +1226,7 @@ int RGWPostObj_ObjStore_S3::read_with_boundary(bufferlist& bl, uint64_t max, boo
       int need = skip + 2 - left;
       bufferptr boundary_bp(need);
       int actual;
-      s->cio->read(boundary_bp.c_str(), need, &actual);
+      STREAM_IO(s)->read(boundary_bp.c_str(), need, &actual);
       in_data.append(boundary_bp);
     }
     max += skip; // skip boundary for next time
@@ -996,9 +1235,9 @@ int RGWPostObj_ObjStore_S3::read_with_boundary(bufferlist& bl, uint64_t max, boo
       if (is_crlf(data + max)) {
 	max += 2;
       } else {
-        if (*(data + max) == '-' &&
-            *(data + max + 1) == '-') {
-          *done = true;
+	if (*(data + max) == '-' &&
+	    *(data + max + 1) == '-') {
+	  *done = true;
 	  max += 2;
 	}
       }
@@ -1025,7 +1264,7 @@ int RGWPostObj_ObjStore_S3::read_data(bufferlist& bl, uint64_t max,
 
 
 int RGWPostObj_ObjStore_S3::read_form_part_header(struct post_form_part *part,
-                                              bool *done)
+						  bool *done)
 {
   bufferlist bl;
   bool reached_boundary;
@@ -1079,7 +1318,8 @@ int RGWPostObj_ObjStore_S3::read_form_part_header(struct post_form_part *part,
 
 bool RGWPostObj_ObjStore_S3::part_str(const string& name, string *val)
 {
-  map<string, struct post_form_part, ltstr_nocase>::iterator iter = parts.find(name);
+  map<string, struct post_form_part, ltstr_nocase>::iterator iter
+    = parts.find(name);
   if (iter == parts.end())
     return false;
 
@@ -1091,7 +1331,8 @@ bool RGWPostObj_ObjStore_S3::part_str(const string& name, string *val)
 
 bool RGWPostObj_ObjStore_S3::part_bl(const string& name, bufferlist *pbl)
 {
-  map<string, struct post_form_part, ltstr_nocase>::iterator iter = parts.find(name);
+  map<string, struct post_form_part, ltstr_nocase>::iterator iter =
+    parts.find(name);
   if (iter == parts.end())
     return false;
 
@@ -1137,15 +1378,18 @@ int RGWPostObj_ObjStore_S3::get_params()
   }
 
   if (s->cct->_conf->subsys.should_gather(ceph_subsys_rgw, 20)) {
-    ldout(s->cct, 20) << "request content_type_str=" << req_content_type_str << dendl;
+    ldout(s->cct, 20) << "request content_type_str="
+		      << req_content_type_str << dendl;
     ldout(s->cct, 20) << "request content_type params:" << dendl;
     map<string, string>::iterator iter;
     for (iter = params.begin(); iter != params.end(); ++iter) {
-      ldout(s->cct, 20) << " " << iter->first << " -> " << iter->second << dendl;
+      ldout(s->cct, 20) << " " << iter->first << " -> " << iter->second
+			<< dendl;
     }
   }
 
-  ldout(s->cct, 20) << "adding bucket to policy env: " << s->bucket.name << dendl;
+  ldout(s->cct, 20) << "adding bucket to policy env: " << s->bucket.name
+		    << dendl;
   env.add_var("bucket", s->bucket.name);
 
   map<string, string>::iterator iter = params.find("boundary");
@@ -1164,18 +1408,20 @@ int RGWPostObj_ObjStore_S3::get_params()
     int r = read_form_part_header(&part, &done);
     if (r < 0)
       return r;
-    
+
     if (s->cct->_conf->subsys.should_gather(ceph_subsys_rgw, 20)) {
       map<string, struct post_part_field, ltstr_nocase>::iterator piter;
       for (piter = part.fields.begin(); piter != part.fields.end(); ++piter) {
-        ldout(s->cct, 20) << "read part header: name=" << part.name << " content_type=" << part.content_type << dendl;
-        ldout(s->cct, 20) << "name=" << piter->first << dendl;
-        ldout(s->cct, 20) << "val=" << piter->second.val << dendl;
-        ldout(s->cct, 20) << "params:" << dendl;
-        map<string, string>& params = piter->second.params;
-        for (iter = params.begin(); iter != params.end(); ++iter) {
-          ldout(s->cct, 20) << " " << iter->first << " -> " << iter->second << dendl;
-        }
+	ldout(s->cct, 20) << "read part header: name=" << part.name
+			  << " content_type=" << part.content_type << dendl;
+	ldout(s->cct, 20) << "name=" << piter->first << dendl;
+	ldout(s->cct, 20) << "val=" << piter->second.val << dendl;
+	ldout(s->cct, 20) << "params:" << dendl;
+	map<string, string>& params = piter->second.params;
+	for (iter = params.begin(); iter != params.end(); ++iter) {
+	  ldout(s->cct, 20) << " " << iter->first << " -> " << iter->second
+			    << dendl;
+	}
       }
     }
 
@@ -1188,7 +1434,7 @@ int RGWPostObj_ObjStore_S3::get_params()
       struct post_part_field& field = part.fields["Content-Disposition"];
       map<string, string>::iterator iter = field.params.find("filename");
       if (iter != field.params.end()) {
-        filename = iter->second;
+	filename = iter->second;
       }
       parts[part.name] = part;
       data_pending = true;
@@ -1227,10 +1473,12 @@ int RGWPostObj_ObjStore_S3::get_params()
   part_str("Content-Type", &content_type);
   env.add_var("Content-Type", content_type);
 
-  map<string, struct post_form_part, ltstr_nocase>::iterator piter = parts.upper_bound(RGW_AMZ_META_PREFIX);
+  map<string, struct post_form_part, ltstr_nocase>::iterator piter =
+    parts.upper_bound(RGW_AMZ_META_PREFIX);
   for (; piter != parts.end(); ++piter) {
     string n = piter->first;
-    if (strncasecmp(n.c_str(), RGW_AMZ_META_PREFIX, sizeof(RGW_AMZ_META_PREFIX) - 1) != 0)
+    if (strncasecmp(n.c_str(), RGW_AMZ_META_PREFIX,
+		    sizeof(RGW_AMZ_META_PREFIX) - 1) != 0)
       break;
 
     string attr_name = RGW_ATTR_PREFIX;
@@ -1295,40 +1543,76 @@ int RGWPostObj_ObjStore_S3::get_policy()
 
     op_ret = rgw_get_user_info_by_access_key(store, s3_access_key, user_info);
     if (op_ret < 0) {
-      // Try keystone authentication as well
-      int keystone_result = -EINVAL;
-      if (!store->ctx()->_conf->rgw_s3_auth_use_keystone ||
-	  store->ctx()->_conf->rgw_keystone_url.empty()) {
-        return -EACCES;
-      }
-      dout(20) << "s3 keystone: trying keystone auth" << dendl;
-
-      RGW_Auth_S3_Keystone_ValidateToken keystone_validator(store->ctx());
-      keystone_result = keystone_validator.validate_s3token(s3_access_key,string(encoded_policy.c_str(),encoded_policy.length()),received_signature_str);
-
-      if (keystone_result < 0) {
-        ldout(s->cct, 0) << "User lookup failed!" << dendl;
-        err_msg = "Bad access key / signature";
-        return -EACCES;
-      }
-
-      user_info.user_id = keystone_validator.response.token.tenant.id;
-      user_info.display_name = keystone_validator.response.token.tenant.name;
+        // try external authenticators
+      if (store->ctx()->_conf->rgw_s3_auth_use_keystone &&
+	  store->ctx()->_conf->rgw_keystone_url.empty())
+      {
+	// keystone
+	int external_auth_result = -EINVAL;
+	dout(20) << "s3 keystone: trying keystone auth" << dendl;
+
+	RGW_Auth_S3_Keystone_ValidateToken keystone_validator(store->ctx());
+	external_auth_result =
+	  keystone_validator.validate_s3token(s3_access_key,
+					      string(encoded_policy.c_str(),
+						    encoded_policy.length()),
+					      received_signature_str);
+
+	if (external_auth_result < 0) {
+	  ldout(s->cct, 0) << "User lookup failed!" << dendl;
+	  err_msg = "Bad access key / signature";
+	  return -EACCES;
+	}
 
-      rgw_user uid(keystone_validator.response.token.tenant.id);
-      /* try to store user if it not already exists */
-      if (rgw_get_user_info_by_uid(store, uid, user_info) < 0) {
-        int ret = rgw_store_user_info(store, user_info, NULL, NULL, 0, true);
-        if (ret < 0) {
-          dout(10) << "NOTICE: failed to store new user's info: ret=" << ret << dendl;
-        }
+	string project_id = keystone_validator.response.get_project_id();
+	rgw_user uid(project_id);
+
+	user_info.user_id = project_id;
+	user_info.display_name = keystone_validator.response.get_project_name();
+
+	/* try to store user if it not already exists */
+	if (rgw_get_user_info_by_uid(store, uid, user_info) < 0) {
+	  int ret = rgw_store_user_info(store, user_info, NULL, NULL, real_time(), true);
+	  if (ret < 0) {
+	    ldout(store->ctx(), 10)
+	      << "NOTICE: failed to store new user's info: ret="
+	      << ret << dendl;
+	  }
+	  s->perm_mask = RGW_PERM_FULL_CONTROL;
+	}
+      } else if (store->ctx()->_conf->rgw_s3_auth_use_ldap &&
+		store->ctx()->_conf->rgw_ldap_uri.empty()) {
+	RGWToken token{from_base64(s3_access_key)};
+	rgw::LDAPHelper *ldh = RGW_Auth_S3::get_ldap_ctx(store);
+	if ((! token.valid()) || ldh->auth(token.id, token.key) != 0)
+	  return -EACCES;
+
+	/* ok, succeeded */
+	user_info.user_id = token.id;
+	user_info.display_name = token.id; // cn?
+
+	/* create local account, if none exists */
+	if (rgw_get_user_info_by_uid(store, user_info.user_id,
+					user_info) < 0) {
+	  int ret = rgw_store_user_info(store, user_info, nullptr, nullptr,
+					real_time(), true);
+	  if (ret < 0) {
+	    ldout(store->ctx(), 10)
+	      << "NOTICE: failed to store new user's info: ret=" << ret
+	      << dendl;
+	  }
+	}
 
-        s->perm_mask = RGW_PERM_FULL_CONTROL;
+	/* set request perms */
+	s->perm_mask = RGW_PERM_FULL_CONTROL;
+      } else {
+	return -EACCES;
       }
     } else {
       map<string, RGWAccessKey> access_keys  = user_info.access_keys;
 
-      map<string, RGWAccessKey>::const_iterator iter = access_keys.find(s3_access_key);
+      map<string, RGWAccessKey>::const_iterator iter =
+	access_keys.find(s3_access_key);
       // We know the key must exist, since the user was returned by
       // rgw_get_user_info_by_access_key, but it doesn't hurt to check!
       if (iter == access_keys.end()) {
@@ -1340,17 +1624,24 @@ int RGWPostObj_ObjStore_S3::get_policy()
 
       char expected_signature_char[CEPH_CRYPTO_HMACSHA1_DIGESTSIZE];
 
-      calc_hmac_sha1(s3_secret_key.c_str(), s3_secret_key.size(), encoded_policy.c_str(), encoded_policy.length(), expected_signature_char);
+      calc_hmac_sha1(s3_secret_key.c_str(), s3_secret_key.size(),
+		     encoded_policy.c_str(), encoded_policy.length(),
+		     expected_signature_char);
       bufferlist expected_signature_hmac_raw;
       bufferlist expected_signature_hmac_encoded;
-      expected_signature_hmac_raw.append(expected_signature_char, CEPH_CRYPTO_HMACSHA1_DIGESTSIZE);
-      expected_signature_hmac_raw.encode_base64(expected_signature_hmac_encoded);
+      expected_signature_hmac_raw.append(expected_signature_char,
+					 CEPH_CRYPTO_HMACSHA1_DIGESTSIZE);
+      expected_signature_hmac_raw.encode_base64(
+	expected_signature_hmac_encoded);
       expected_signature_hmac_encoded.append((char)0); /* null terminate */
 
-      if (received_signature_str.compare(expected_signature_hmac_encoded.c_str()) != 0) {
+      if (received_signature_str.compare(
+	    expected_signature_hmac_encoded.c_str()) != 0) {
 	ldout(s->cct, 0) << "Signature verification failed!" << dendl;
-	ldout(s->cct, 0) << "received: " << received_signature_str.c_str() << dendl;
-	ldout(s->cct, 0) << "expected: " << expected_signature_hmac_encoded.c_str() << dendl;
+	ldout(s->cct, 0) << "received: " << received_signature_str.c_str()
+			 << dendl;
+	ldout(s->cct, 0) << "expected: "
+			 << expected_signature_hmac_encoded.c_str() << dendl;
 	err_msg = "Bad access key / signature";
 	return -EACCES;
       }
@@ -1392,7 +1683,8 @@ int RGWPostObj_ObjStore_S3::get_policy()
       return r;
     }
 
-    s->user = user_info;
+    // deep copy
+    *(s->user) = user_info;
     s->owner.set_id(user_info.user_id);
     s->owner.set_name(user_info.display_name);
   } else {
@@ -1422,7 +1714,7 @@ int RGWPostObj_ObjStore_S3::complete_get_params()
     int r = read_form_part_header(&part, &done);
     if (r < 0)
       return r;
-    
+
     bufferlist part_data;
     bool boundary;
     uint64_t chunk_size = s->cct->_conf->rgw_max_chunk_size;
@@ -1453,7 +1745,7 @@ int RGWPostObj_ObjStore_S3::get_data(bufferlist& bl)
     if (!done) {  /* reached end of data, let's drain the rest of the params */
       r = complete_get_params();
       if (r < 0)
-        return r;
+	return r;
     }
   }
 
@@ -1541,7 +1833,9 @@ done:
   if (op_ret == STATUS_CREATED) {
     s->formatter->open_object_section("PostResponse");
     if (g_conf->rgw_dns_name.length())
-      s->formatter->dump_format("Location", "%s/%s", s->info.script_uri.c_str(), s->object.name.c_str());
+      s->formatter->dump_format("Location", "%s/%s",
+				s->info.script_uri.c_str(),
+				s->object.name.c_str());
     if (!s->bucket_tenant.empty())
       s->formatter->dump_string("Tenant", s->bucket_tenant);
     s->formatter->dump_string("Bucket", s->bucket_name);
@@ -1561,6 +1855,29 @@ done:
   rgw_flush_formatter_and_reset(s, s->formatter);
 }
 
+int RGWDeleteObj_ObjStore_S3::get_params()
+{
+  const char *if_unmod = s->info.env->get("HTTP_X_AMZ_DELETE_IF_UNMODIFIED_SINCE");
+
+  if (s->system_request) {
+    s->info.args.get_bool(RGW_SYS_PARAM_PREFIX "no-precondition-error", &no_precondition_error, false);
+  }
+
+  if (if_unmod) {
+    string if_unmod_str(if_unmod);
+    string if_unmod_decoded;
+    url_decode(if_unmod_str, if_unmod_decoded);
+    uint64_t epoch;
+    uint64_t nsec;
+    if (utime_t::parse_date(if_unmod_decoded, &epoch, &nsec) < 0) {
+      ldout(s->cct, 10) << "failed to parse time: " << if_unmod_decoded << dendl;
+      return -EINVAL;
+    }
+    unmod_since = utime_t(epoch, nsec).to_real_time();
+  }
+
+  return 0;
+}
 
 void RGWDeleteObj_ObjStore_S3::send_response()
 {
@@ -1615,13 +1932,18 @@ int RGWCopyObj_ObjStore_S3::get_params()
 
   if (s->system_request) {
     source_zone = s->info.args.get(RGW_SYS_PARAM_PREFIX "source-zone");
+    s->info.args.get_bool(RGW_SYS_PARAM_PREFIX "copy-if-newer", &copy_if_newer, false);
     if (!source_zone.empty()) {
       client_id = s->info.args.get(RGW_SYS_PARAM_PREFIX "client-id");
       op_id = s->info.args.get(RGW_SYS_PARAM_PREFIX "op-id");
 
       if (client_id.empty() || op_id.empty()) {
-        ldout(s->cct, 0) << RGW_SYS_PARAM_PREFIX "client-id or " RGW_SYS_PARAM_PREFIX "op-id were not provided, required for intra-region copy" << dendl;
-        return -EINVAL;
+	ldout(s->cct, 0) <<
+	  RGW_SYS_PARAM_PREFIX "client-id or "
+	  RGW_SYS_PARAM_PREFIX "op-id were not provided, "
+	  "required for intra-region copy"
+			 << dendl;
+	return -EINVAL;
       }
     }
   }
@@ -1633,7 +1955,7 @@ int RGWCopyObj_ObjStore_S3::get_params()
     } else if (strcasecmp(md_directive, "REPLACE") == 0) {
       attrs_mod = RGWRados::ATTRSMOD_REPLACE;
     } else if (!source_zone.empty()) {
-      attrs_mod = RGWRados::ATTRSMOD_NONE; // default for intra-region copy
+      attrs_mod = RGWRados::ATTRSMOD_NONE; // default for intra-zone_group copy
     } else {
       ldout(s->cct, 0) << "invalid metadata directive" << dendl;
       return -EINVAL;
@@ -1647,7 +1969,8 @@ int RGWCopyObj_ObjStore_S3::get_params()
       src_object.instance.empty() &&
       (attrs_mod != RGWRados::ATTRSMOD_REPLACE)) {
     /* can only copy object into itself if replacing attrs */
-    ldout(s->cct, 0) << "can't copy object into itself if not replacing attrs" << dendl;
+    ldout(s->cct, 0) << "can't copy object into itself if not replacing attrs"
+		     << dendl;
     return -ERR_INVALID_REQUEST;
   }
   return 0;
@@ -1697,10 +2020,26 @@ void RGWGetACLs_ObjStore_S3::send_response()
   end_header(s, this, "application/xml");
   dump_start(s);
   rgw_flush_formatter(s, s->formatter);
-  s->cio->write(acls.c_str(), acls.size());
+  STREAM_IO(s)->write(acls.c_str(), acls.size());
 }
 
-int RGWPutACLs_ObjStore_S3::get_policy_from_state(RGWRados *store, struct req_state *s, stringstream& ss)
+int RGWPutACLs_ObjStore_S3::get_params()
+{
+  int ret =  RGWPutACLs_ObjStore::get_params();
+  if (ret < 0)
+    s->aws4_auth_needs_complete = false;
+  if (s->aws4_auth_needs_complete) {
+    int ret_auth = do_aws4_auth_completion();
+    if (ret_auth < 0) {
+      return ret_auth;
+    }
+  }
+  return ret;
+}
+
+int RGWPutACLs_ObjStore_S3::get_policy_from_state(RGWRados *store,
+						  struct req_state *s,
+						  stringstream& ss)
 {
   RGWAccessControlPolicy_S3 s3policy(s->cct);
 
@@ -1741,12 +2080,13 @@ void RGWGetCORS_ObjStore_S3::send_response()
   dump_start(s);
   if (! op_ret) {
     string cors;
-    RGWCORSConfiguration_S3 *s3cors = static_cast<RGWCORSConfiguration_S3 *>(&bucket_cors);
+    RGWCORSConfiguration_S3 *s3cors =
+      static_cast<RGWCORSConfiguration_S3 *>(&bucket_cors);
     stringstream ss;
 
     s3cors->to_xml(ss);
     cors = ss.str();
-    s->cio->write(cors.c_str(), cors.size());
+    STREAM_IO(s)->write(cors.c_str(), cors.size());
   }
 }
 
@@ -1768,7 +2108,7 @@ int RGWPutCORS_ObjStore_S3::get_params()
        goto done_err;
     }
     int read_len;
-    r = s->cio->read(data, cl, &read_len);
+    r = STREAM_IO(s)->read(data, cl, &read_len, s->aws4_auth_needs_complete);
     len = read_len;
     if (r < 0)
       goto done_err;
@@ -1777,6 +2117,13 @@ int RGWPutCORS_ObjStore_S3::get_params()
     len = 0;
   }
 
+  if (s->aws4_auth_needs_complete) {
+    int ret_auth = do_aws4_auth_completion();
+    if (ret_auth < 0) {
+      return ret_auth;
+    }
+  }
+
   if (!parser.init()) {
     r = -EINVAL;
     goto done_err;
@@ -1786,7 +2133,9 @@ int RGWPutCORS_ObjStore_S3::get_params()
     r = -EINVAL;
     goto done_err;
   }
-  cors_config = static_cast<RGWCORSConfiguration_S3 *>(parser.find_first("CORSConfiguration"));
+  cors_config =
+    static_cast<RGWCORSConfiguration_S3 *>(parser.find_first(
+					     "CORSConfiguration"));
   if (!cors_config) {
     r = -EINVAL;
     goto done_err;
@@ -1845,7 +2194,8 @@ void RGWOptionsCORS_ObjStore_S3::send_response()
   get_response_params(hdrs, exp_hdrs, &max_age);
 
   dump_errno(s);
-  dump_access_control(s, origin, req_meth, hdrs.c_str(), exp_hdrs.c_str(), max_age); 
+  dump_access_control(s, origin, req_meth, hdrs.c_str(), exp_hdrs.c_str(),
+		      max_age);
   end_header(s, NULL);
 }
 
@@ -1968,6 +2318,22 @@ void RGWInitMultipart_ObjStore_S3::send_response()
   }
 }
 
+int RGWCompleteMultipart_ObjStore_S3::get_params()
+{
+  int ret = RGWCompleteMultipart_ObjStore::get_params();
+  if (ret < 0) {
+    return ret;
+  }
+
+  if (s->aws4_auth_needs_complete) {
+    int ret_auth = do_aws4_auth_completion();
+    if (ret_auth < 0) {
+      return ret_auth;
+    }
+  }
+  return 0;
+}
+
 void RGWCompleteMultipart_ObjStore_S3::send_response()
 {
   if (op_ret)
@@ -2049,16 +2415,9 @@ void RGWListMultipart_ObjStore_S3::send_response()
     for (; iter != parts.end(); ++iter) {
       RGWUploadPartInfo& info = iter->second;
 
-      time_t sec = info.modified.sec();
-      struct tm tmp;
-      gmtime_r(&sec, &tmp);
-      char buf[TIME_BUF_SIZE];
-
       s->formatter->open_object_section("Part");
 
-      if (strftime(buf, sizeof(buf), "%Y-%m-%dT%T.000Z", &tmp) > 0) {
-        s->formatter->dump_string("LastModified", buf);
-      }
+      dump_time(s, "LastModified", &info.modified);
 
       s->formatter->dump_unsigned("PartNumber", info.num);
       s->formatter->dump_string("ETag", info.etag);
@@ -2111,18 +2470,18 @@ void RGWListBucketMultiparts_ObjStore_S3::send_response()
       s->formatter->open_array_section("Upload");
       s->formatter->dump_string("Key", mp.get_key());
       s->formatter->dump_string("UploadId", mp.get_upload_id());
-      dump_owner(s, s->user.user_id, s->user.display_name, "Initiator");
-      dump_owner(s, s->user.user_id, s->user.display_name);
+      dump_owner(s, s->user->user_id, s->user->display_name, "Initiator");
+      dump_owner(s, s->user->user_id, s->user->display_name);
       s->formatter->dump_string("StorageClass", "STANDARD");
-      time_t mtime = iter->obj.mtime.sec();
-      dump_time(s, "Initiated", &mtime);
+      dump_time(s, "Initiated", &iter->obj.mtime);
       s->formatter->close_section();
     }
     if (!common_prefixes.empty()) {
       s->formatter->open_array_section("CommonPrefixes");
       map<string, bool>::iterator pref_iter;
-      for (pref_iter = common_prefixes.begin(); pref_iter != common_prefixes.end(); ++pref_iter) {
-        s->formatter->dump_string("CommonPrefixes.Prefix", pref_iter->first);
+      for (pref_iter = common_prefixes.begin();
+	   pref_iter != common_prefixes.end(); ++pref_iter) {
+	s->formatter->dump_string("CommonPrefixes.Prefix", pref_iter->first);
       }
       s->formatter->close_section();
     }
@@ -2131,6 +2490,22 @@ void RGWListBucketMultiparts_ObjStore_S3::send_response()
   rgw_flush_formatter_and_reset(s, s->formatter);
 }
 
+int RGWDeleteMultiObj_ObjStore_S3::get_params()
+{
+  int ret = RGWDeleteMultiObj_ObjStore::get_params();
+  if (ret < 0) {
+    return ret;
+  }
+
+  if (s->aws4_auth_needs_complete) {
+    int ret_auth = do_aws4_auth_completion();
+    if (ret_auth < 0) {
+      return ret_auth;
+    }
+  }
+  return 0;
+}
+
 void RGWDeleteMultiObj_ObjStore_S3::send_status()
 {
   if (! status_dumped) {
@@ -2151,24 +2526,25 @@ void RGWDeleteMultiObj_ObjStore_S3::begin_response()
   dump_start(s);
   end_header(s, this, "application/xml");
   s->formatter->open_object_section_in_ns("DeleteResult",
-                                            "http://s3.amazonaws.com/doc/2006-03-01/");
+					  "http://s3.amazonaws.com/doc/2006-03-01/");
 
   rgw_flush_formatter(s, s->formatter);
 }
 
-void RGWDeleteMultiObj_ObjStore_S3::send_partial_response(rgw_obj_key& key, bool delete_marker,
-                                                          const string& marker_version_id, int ret)
+void RGWDeleteMultiObj_ObjStore_S3::send_partial_response(rgw_obj_key& key,
+							  bool delete_marker,
+							  const string& marker_version_id, int ret)
 {
   if (!key.empty()) {
     if (op_ret == 0 && !quiet) {
       s->formatter->open_object_section("Deleted");
       s->formatter->dump_string("Key", key.name);
       if (!key.instance.empty()) {
-        s->formatter->dump_string("VersionId", key.instance);
+	s->formatter->dump_string("VersionId", key.instance);
       }
       if (delete_marker) {
-        s->formatter->dump_bool("DeleteMarker", true);
-        s->formatter->dump_string("DeleteMarkerVersionId", marker_version_id);
+	s->formatter->dump_bool("DeleteMarker", true);
+	s->formatter->dump_string("DeleteMarkerVersionId", marker_version_id);
       }
       s->formatter->close_section();
     } else if (op_ret < 0) {
@@ -2198,17 +2574,21 @@ void RGWDeleteMultiObj_ObjStore_S3::end_response()
   rgw_flush_formatter_and_reset(s, s->formatter);
 }
 
-RGWOp *RGWHandler_ObjStore_Service_S3::op_get()
+RGWOp *RGWHandler_REST_Service_S3::op_get()
 {
-  return new RGWListBuckets_ObjStore_S3;
+  if (is_usage_op()) {
+    return new RGWGetUsage_ObjStore_S3;
+  } else {
+    return new RGWListBuckets_ObjStore_S3;
+  }
 }
 
-RGWOp *RGWHandler_ObjStore_Service_S3::op_head()
+RGWOp *RGWHandler_REST_Service_S3::op_head()
 {
   return new RGWListBuckets_ObjStore_S3;
 }
 
-RGWOp *RGWHandler_ObjStore_Bucket_S3::get_obj_op(bool get_data)
+RGWOp *RGWHandler_REST_Bucket_S3::get_obj_op(bool get_data)
 {
   // Non-website mode
   if (get_data)
@@ -2217,7 +2597,7 @@ RGWOp *RGWHandler_ObjStore_Bucket_S3::get_obj_op(bool get_data)
     return new RGWStatBucket_ObjStore_S3;
 }
 
-RGWOp *RGWHandler_ObjStore_Bucket_S3::op_get()
+RGWOp *RGWHandler_REST_Bucket_S3::op_get()
 {
   if (s->info.args.sub_resource_exists("logging"))
     return new RGWGetBucketLogging_ObjStore_S3;
@@ -2247,7 +2627,7 @@ RGWOp *RGWHandler_ObjStore_Bucket_S3::op_get()
   return get_obj_op(true);
 }
 
-RGWOp *RGWHandler_ObjStore_Bucket_S3::op_head()
+RGWOp *RGWHandler_REST_Bucket_S3::op_head()
 {
   if (is_acl_op()) {
     return new RGWGetACLs_ObjStore_S3;
@@ -2257,7 +2637,7 @@ RGWOp *RGWHandler_ObjStore_Bucket_S3::op_head()
   return get_obj_op(false);
 }
 
-RGWOp *RGWHandler_ObjStore_Bucket_S3::op_put()
+RGWOp *RGWHandler_REST_Bucket_S3::op_put()
 {
   if (s->info.args.sub_resource_exists("logging"))
     return NULL;
@@ -2279,7 +2659,7 @@ RGWOp *RGWHandler_ObjStore_Bucket_S3::op_put()
   return new RGWCreateBucket_ObjStore_S3;
 }
 
-RGWOp *RGWHandler_ObjStore_Bucket_S3::op_delete()
+RGWOp *RGWHandler_REST_Bucket_S3::op_delete()
 {
   if (is_cors_op()) {
     return new RGWDeleteCORS_ObjStore_S3;
@@ -2295,7 +2675,7 @@ RGWOp *RGWHandler_ObjStore_Bucket_S3::op_delete()
   return new RGWDeleteBucket_ObjStore_S3;
 }
 
-RGWOp *RGWHandler_ObjStore_Bucket_S3::op_post()
+RGWOp *RGWHandler_REST_Bucket_S3::op_post()
 {
   if ( s->info.request_params == "delete" ) {
     return new RGWDeleteMultiObj_ObjStore_S3;
@@ -2304,12 +2684,12 @@ RGWOp *RGWHandler_ObjStore_Bucket_S3::op_post()
   return new RGWPostObj_ObjStore_S3;
 }
 
-RGWOp *RGWHandler_ObjStore_Bucket_S3::op_options()
+RGWOp *RGWHandler_REST_Bucket_S3::op_options()
 {
   return new RGWOptionsCORS_ObjStore_S3;
 }
 
-RGWOp *RGWHandler_ObjStore_Obj_S3::get_obj_op(bool get_data)
+RGWOp *RGWHandler_REST_Obj_S3::get_obj_op(bool get_data)
 {
   if (is_acl_op()) {
     return new RGWGetACLs_ObjStore_S3;
@@ -2319,7 +2699,7 @@ RGWOp *RGWHandler_ObjStore_Obj_S3::get_obj_op(bool get_data)
   return get_obj_op;
 }
 
-RGWOp *RGWHandler_ObjStore_Obj_S3::op_get()
+RGWOp *RGWHandler_REST_Obj_S3::op_get()
 {
   if (is_acl_op()) {
     return new RGWGetACLs_ObjStore_S3;
@@ -2329,7 +2709,7 @@ RGWOp *RGWHandler_ObjStore_Obj_S3::op_get()
   return get_obj_op(true);
 }
 
-RGWOp *RGWHandler_ObjStore_Obj_S3::op_head()
+RGWOp *RGWHandler_REST_Obj_S3::op_head()
 {
   if (is_acl_op()) {
     return new RGWGetACLs_ObjStore_S3;
@@ -2339,7 +2719,7 @@ RGWOp *RGWHandler_ObjStore_Obj_S3::op_head()
   return get_obj_op(false);
 }
 
-RGWOp *RGWHandler_ObjStore_Obj_S3::op_put()
+RGWOp *RGWHandler_REST_Obj_S3::op_put()
 {
   if (is_acl_op()) {
     return new RGWPutACLs_ObjStore_S3;
@@ -2350,7 +2730,7 @@ RGWOp *RGWHandler_ObjStore_Obj_S3::op_put()
     return new RGWCopyObj_ObjStore_S3;
 }
 
-RGWOp *RGWHandler_ObjStore_Obj_S3::op_delete()
+RGWOp *RGWHandler_REST_Obj_S3::op_delete()
 {
   string upload_id = s->info.args.get("uploadId");
 
@@ -2360,7 +2740,7 @@ RGWOp *RGWHandler_ObjStore_Obj_S3::op_delete()
     return new RGWAbortMultipart_ObjStore_S3;
 }
 
-RGWOp *RGWHandler_ObjStore_Obj_S3::op_post()
+RGWOp *RGWHandler_REST_Obj_S3::op_post()
 {
   if (s->info.args.exists("uploadId"))
     return new RGWCompleteMultipart_ObjStore_S3;
@@ -2371,12 +2751,14 @@ RGWOp *RGWHandler_ObjStore_Obj_S3::op_post()
   return NULL;
 }
 
-RGWOp *RGWHandler_ObjStore_Obj_S3::op_options()
+RGWOp *RGWHandler_REST_Obj_S3::op_options()
 {
   return new RGWOptionsCORS_ObjStore_S3;
 }
 
-int RGWHandler_ObjStore_S3::init_from_header(struct req_state *s, int default_formatter, bool configurable_format)
+int RGWHandler_REST_S3::init_from_header(struct req_state* s,
+					int default_formatter,
+					bool configurable_format)
 {
   string req;
   string first;
@@ -2427,7 +2809,6 @@ int RGWHandler_ObjStore_S3::init_from_header(struct req_state *s, int default_fo
   if (s->init_state.url_bucket.empty()) {
     // Save bucket to tide us over until token is parsed.
     s->init_state.url_bucket = first;
-
     if (pos >= 0) {
       string encoded_obj_str = req.substr(pos+1);
       s->object = rgw_obj_key(encoded_obj_str, s->info.args.get("versionId"));
@@ -2438,12 +2819,13 @@ int RGWHandler_ObjStore_S3::init_from_header(struct req_state *s, int default_fo
   return 0;
 }
 
-int RGWHandler_ObjStore_S3::postauth_init()
+int RGWHandler_REST_S3::postauth_init()
 {
   struct req_init_state *t = &s->init_state;
   bool relaxed_names = s->cct->_conf->rgw_relaxed_s3_bucket_names;
 
-  rgw_parse_url_bucket(t->url_bucket, s->user.user_id.tenant, s->bucket_tenant, s->bucket_name);
+  rgw_parse_url_bucket(t->url_bucket, s->user->user_id.tenant,
+		      s->bucket_tenant, s->bucket_name);
 
   dout(10) << "s->object=" << (!s->object.empty() ? s->object : rgw_obj_key("<NULL>"))
            << " s->bucket=" << rgw_make_bucket_entry_name(s->bucket_tenant, s->bucket_name) << dendl;
@@ -2452,88 +2834,47 @@ int RGWHandler_ObjStore_S3::postauth_init()
   ret = validate_tenant_name(s->bucket_tenant);
   if (ret)
     return ret;
-  ret = validate_bucket_name(s->bucket_name, relaxed_names);
-  if (ret)
-    return ret;
-  ret = validate_object_name(s->object.name);
-  if (ret)
-    return ret;
+  if (!s->bucket_name.empty()) {
+    ret = valid_s3_bucket_name(s->bucket_name, relaxed_names);
+    if (ret)
+      return ret;
+    ret = validate_object_name(s->object.name);
+    if (ret)
+      return ret;
+  }
 
   if (!t->src_bucket.empty()) {
-    rgw_parse_url_bucket(t->src_bucket, s->user.user_id.tenant, s->src_tenant_name, s->src_bucket_name);
+    rgw_parse_url_bucket(t->src_bucket, s->user->user_id.tenant,
+			s->src_tenant_name, s->src_bucket_name);
     ret = validate_tenant_name(s->src_tenant_name);
     if (ret)
       return ret;
-    ret = validate_bucket_name(s->src_bucket_name, relaxed_names);
+    ret = valid_s3_bucket_name(s->src_bucket_name, relaxed_names);
     if (ret)
       return ret;
   }
   return 0;
 }
 
-static bool looks_like_ip_address(const char *bucket)
-{
-  int num_periods = 0;
-  bool expect_period = false;
-  for (const char *b = bucket; *b; ++b) {
-    if (*b == '.') {
-      if (!expect_period)
-	return false;
-      ++num_periods;
-      if (num_periods > 3)
-	return false;
-      expect_period = false;
-    }
-    else if (isdigit(*b)) {
-      expect_period = true;
-    }
-    else {
-      return false;
-    }
-  }
-  return (num_periods == 3);
-}
-
-int RGWHandler_ObjStore_S3::validate_bucket_name(const string& bucket, bool relaxed_names)
-{
-  int ret = RGWHandler_ObjStore::validate_bucket_name(bucket);
-  if (ret < 0)
-    return ret;
-
-  if (bucket.size() == 0)
-    return 0;
-
-  // bucket names must start with a number, letter, or underscore
-  if (!(isalpha(bucket[0]) || isdigit(bucket[0]))) {
-    if (!relaxed_names)
-      return -ERR_INVALID_BUCKET_NAME;
-    else if (!(bucket[0] == '_' || bucket[0] == '.' || bucket[0] == '-'))
-      return -ERR_INVALID_BUCKET_NAME;
-  } 
-
-  for (const char *s = bucket.c_str(); *s; ++s) {
-    char c = *s;
-    if (isdigit(c) || (c == '.'))
-      continue;
-    if (isalpha(c))
-      continue;
-    if ((c == '-') || (c == '_'))
-      continue;
-    // Invalid character
-    return -ERR_INVALID_BUCKET_NAME;
-  }
-
-  if (looks_like_ip_address(bucket.c_str()))
-    return -ERR_INVALID_BUCKET_NAME;
-
-  return 0;
-}
-
-int RGWHandler_ObjStore_S3::init(RGWRados *store, struct req_state *s, RGWClientIO *cio)
+int RGWHandler_REST_S3::init(RGWRados *store, struct req_state *s,
+			    RGWClientIO *cio)
 {
   int ret;
 
   s->dialect = "s3";
+  
+  ret = validate_tenant_name(s->bucket_tenant);
+  if (ret)
+    return ret;
+  bool relaxed_names = s->cct->_conf->rgw_relaxed_s3_bucket_names;
+  if (!s->bucket_name.empty()) {
+    ret = valid_s3_bucket_name(s->bucket_name, relaxed_names);
+    if (ret)
+      return ret;
+    ret = validate_object_name(s->object.name);
+    if (ret)
+      return ret;
+  }
 
   const char *cacl = s->info.env->get("HTTP_X_AMZ_ACL");
   if (cacl)
@@ -2543,26 +2884,54 @@ int RGWHandler_ObjStore_S3::init(RGWRados *store, struct req_state *s, RGWClient
 
   const char *copy_source = s->info.env->get("HTTP_X_AMZ_COPY_SOURCE");
   if (copy_source) {
-    ret = RGWCopyObj::parse_copy_location(copy_source, s->init_state.src_bucket, s->src_object);
+    ret = RGWCopyObj::parse_copy_location(copy_source,
+					  s->init_state.src_bucket,
+					  s->src_object);
     if (!ret) {
       ldout(s->cct, 0) << "failed to parse copy location" << dendl;
       return -EINVAL; // XXX why not -ERR_INVALID_BUCKET_NAME or -ERR_BAD_URL?
     }
   }
 
-  return RGWHandler_ObjStore::init(store, s, cio);
+  return RGWHandler_REST::init(store, s, cio);
 }
 
+/* RGW_Auth_S3 static members */
+std::mutex RGW_Auth_S3::mtx;
+rgw::LDAPHelper* RGW_Auth_S3::ldh;
+
+/* static */
+void RGW_Auth_S3::init_impl(RGWRados* store)
+{
+  const string& ldap_uri = store->ctx()->_conf->rgw_ldap_uri;
+  const string& ldap_binddn = store->ctx()->_conf->rgw_ldap_binddn;
+  const string& ldap_searchdn = store->ctx()->_conf->rgw_ldap_searchdn;
+  const string& ldap_dnattr =
+    store->ctx()->_conf->rgw_ldap_dnattr;
+
+  ldh = new rgw::LDAPHelper(ldap_uri, ldap_binddn, ldap_searchdn,
+			    ldap_dnattr);
+
+  ldh->init();
+  ldh->bind();
+}
 
 /*
  * Try to validate S3 auth against keystone s3token interface
  */
-int RGW_Auth_S3_Keystone_ValidateToken::validate_s3token(const string& auth_id, const string& auth_token, const string& auth_sign) {
+int RGW_Auth_S3_Keystone_ValidateToken::validate_s3token(
+  const string& auth_id, const string& auth_token, const string& auth_sign) {
   /* prepare keystone url */
   string keystone_url = cct->_conf->rgw_keystone_url;
-  if (keystone_url[keystone_url.size() - 1] != '/')
+  if (keystone_url[keystone_url.size() - 1] != '/') {
     keystone_url.append("/");
-  keystone_url.append("v2.0/s3tokens");
+  }
+
+  if (KeystoneService::get_api_version() == KeystoneApiVersion::VER_3) {
+    keystone_url.append("v3/s3tokens");
+  } else {
+    keystone_url.append("v2.0/s3tokens");
+  }
 
   /* get authentication token for Keystone. */
   string admin_token_id;
@@ -2576,6 +2945,9 @@ int RGW_Auth_S3_Keystone_ValidateToken::validate_s3token(const string& auth_id,
   append_header("X-Auth-Token", admin_token_id);
   append_header("Content-Type", "application/json");
 
+  /* check if we want to verify keystone's ssl certs */
+  set_verify_ssl(cct->_conf->rgw_keystone_verify_ssl);
+
   /* encode token */
   bufferlist token_buff;
   bufferlist token_encoded;
@@ -2600,12 +2972,18 @@ int RGW_Auth_S3_Keystone_ValidateToken::validate_s3token(const string& auth_id,
   /* send request */
   int ret = process("POST", keystone_url.c_str());
   if (ret < 0) {
-    dout(2) << "s3 keystone: token validation ERROR: " << rx_buffer.c_str() << dendl;
+    dout(2) << "s3 keystone: token validation ERROR: " << rx_buffer.c_str()
+            << dendl;
     return -EPERM;
   }
 
+  /* if the supplied signature is wrong, we will get 401 from Keystone */
+  if (get_http_status() == HTTP_STATUS_UNAUTHORIZED) {
+    return -ERR_SIGNATURE_NO_MATCH;
+  }
+
   /* now parse response */
-  if (response.parse(cct, rx_buffer) < 0) {
+  if (response.parse(cct, string(), rx_buffer) < 0) {
     dout(2) << "s3 keystone: token parsing failed" << dendl;
     return -EPERM;
   }
@@ -2614,42 +2992,43 @@ int RGW_Auth_S3_Keystone_ValidateToken::validate_s3token(const string& auth_id,
   bool found = false;
   list<string>::iterator iter;
   for (iter = roles_list.begin(); iter != roles_list.end(); ++iter) {
-    if ((found=response.user.has_role(*iter))==true)
+    if ((found=response.has_role(*iter))==true)
       break;
   }
 
   if (!found) {
-    ldout(cct, 5) << "s3 keystone: user does not hold a matching role; required roles: " << cct->_conf->rgw_keystone_accepted_roles << dendl;
-    return -EPERM;
+    ldout(cct, 5) << "s3 keystone: user does not hold a matching role;"
+                     " required roles: "
+                  << cct->_conf->rgw_keystone_accepted_roles << dendl;
+    return -ERR_INVALID_ACCESS_KEY;
   }
 
   /* everything seems fine, continue with this user */
-  ldout(cct, 5) << "s3 keystone: validated token: " << response.token.tenant.name << ":" << response.user.name << " expires: " << response.token.expires << dendl;
+  ldout(cct, 5) << "s3 keystone: validated token: " << response.get_project_name()
+                << ":" << response.get_user_name()
+                << " expires: " << response.get_expires() << dendl;
   return 0;
 }
 
 static void init_anon_user(struct req_state *s)
 {
-  rgw_get_anon_user(s->user);
+  rgw_get_anon_user(*(s->user));
   s->perm_mask = RGW_PERM_FULL_CONTROL;
 }
 
 /*
  * verify that a signed request comes from the keyholder
  * by checking the signature against our locally-computed version
+ *
+ * it tries AWS v4 before AWS v2
  */
 int RGW_Auth_S3::authorize(RGWRados *store, struct req_state *s)
 {
-  bool qsr = false;
-  string auth_id;
-  string auth_sign;
-
-  time_t now;
-  time(&now);
 
   /* neither keystone and rados enabled; warn and exit! */
-  if (!store->ctx()->_conf->rgw_s3_auth_use_rados
-      && !store->ctx()->_conf->rgw_s3_auth_use_keystone) {
+  if (!store->ctx()->_conf->rgw_s3_auth_use_rados &&
+      !store->ctx()->_conf->rgw_s3_auth_use_keystone &&
+      !store->ctx()->_conf->rgw_s3_auth_use_ldap) {
     dout(0) << "WARNING: no authorization backend enabled! Users will never authenticate." << dendl;
     return -EPERM;
   }
@@ -2660,35 +3039,611 @@ int RGW_Auth_S3::authorize(RGWRados *store, struct req_state *s)
   }
 
   if (!s->http_auth || !(*s->http_auth)) {
-    auth_id = s->info.args.get("AWSAccessKeyId");
+
+    /* AWS4 */
+
+    string algorithm = s->info.args.get("X-Amz-Algorithm");
+    if (algorithm.size()) {
+      if (algorithm != "AWS4-HMAC-SHA256") {
+        return -EPERM;
+      }
+      return authorize_v4(store, s);
+    }
+
+    /* AWS2 */
+
+    string auth_id = s->info.args.get("AWSAccessKeyId");
     if (auth_id.size()) {
-      auth_sign = s->info.args.get("Signature");
+      return authorize_v2(store, s);
+    }
+
+    /* anonymous access */
+
+    init_anon_user(s);
+    return 0;
+
+  } else {
 
-      string date = s->info.args.get("Expires");
-      time_t exp = atoll(date.c_str());
-      if (now >= exp)
+    /* AWS4 */
+
+    if (!strncmp(s->http_auth, "AWS4-HMAC-SHA256", 16)) {
+      return authorize_v4(store, s);
+    }
+
+    /* AWS2 */
+
+    if (!strncmp(s->http_auth, "AWS ", 4)) {
+      return authorize_v2(store, s);
+    }
+
+  }
+
+  return -EINVAL;
+}
+
+int RGW_Auth_S3::authorize_aws4_auth_complete(RGWRados *store, struct req_state *s)
+{
+  return authorize_v4_complete(store, s, "", false);
+}
+
+int RGW_Auth_S3::authorize_v4_complete(RGWRados *store, struct req_state *s, const string& request_payload, bool unsigned_payload)
+{
+  size_t pos;
+
+  /* craft canonical request */
+
+  string canonical_req;
+  string canonical_req_hash;
+
+  rgw_create_s3_v4_canonical_request(s, s->aws4_auth->canonical_uri, s->aws4_auth->canonical_qs,
+      s->aws4_auth->canonical_hdrs, s->aws4_auth->signed_hdrs, request_payload, unsigned_payload,
+      canonical_req, canonical_req_hash);
+
+  /* Validate x-amz-sha256 */
+
+  if (s->aws4_auth_needs_complete) {
+    const char *expected_request_payload_hash = s->info.env->get("HTTP_X_AMZ_CONTENT_SHA256");
+    if (expected_request_payload_hash &&
+	s->aws4_auth->payload_hash.compare(expected_request_payload_hash) != 0) {
+      ldout(s->cct, 10) << "ERROR: x-amz-content-sha256 does not match" << dendl;
+      return -ERR_AMZ_CONTENT_SHA256_MISMATCH;
+    }
+  }
+
+  /*
+   * create a string to sign
+   *
+   * http://docs.aws.amazon.com/general/latest/gr/sigv4-create-string-to-sign.html
+   */
+
+  string string_to_sign;
+
+  rgw_create_s3_v4_string_to_sign(s->cct, "AWS4-HMAC-SHA256", s->aws4_auth->date, s->aws4_auth->credential_scope,
+      canonical_req_hash, string_to_sign);
+
+  /*
+   * calculate the AWS signature
+   *
+   * http://docs.aws.amazon.com/general/latest/gr/sigv4-calculate-signature.html
+   */
+
+  string cs_aux = s->aws4_auth->credential_scope;
+
+  string date_cs = cs_aux;
+  pos = date_cs.find("/");
+  date_cs = date_cs.substr(0, pos);
+  cs_aux = cs_aux.substr(pos + 1, cs_aux.length());
+
+  string region_cs = cs_aux;
+  pos = region_cs.find("/");
+  region_cs = region_cs.substr(0, pos);
+  cs_aux = cs_aux.substr(pos + 1, cs_aux.length());
+
+  string service_cs = cs_aux;
+  pos = service_cs.find("/");
+  service_cs = service_cs.substr(0, pos);
+
+  int err = rgw_calculate_s3_v4_aws_signature(s, s->aws4_auth->access_key_id, date_cs,
+      region_cs, service_cs, string_to_sign, s->aws4_auth->new_signature);
+
+  ldout(s->cct, 10) << "----------------------------- Verifying signatures" << dendl;
+  ldout(s->cct, 10) << "Signature     = " << s->aws4_auth->signature << dendl;
+  ldout(s->cct, 10) << "New Signature = " << s->aws4_auth->new_signature << dendl;
+  ldout(s->cct, 10) << "-----------------------------" << dendl;
+
+  if (err) {
+    return err;
+  }
+
+  return 0;
+
+}
+
+static inline bool is_base64_for_content_md5(unsigned char c) {
+  return (isalnum(c) || isspace(c) || (c == '+') || (c == '/') || (c == '='));
+}
+
+static bool char_needs_aws4_escaping(char c)
+{
+  if ((c >= 'a' && c <= 'z') ||
+      (c >= 'A' && c <= 'Z') ||
+      (c >= '0' && c <= '9')) {
+    return false;
+  }
+
+  switch (c) {
+    case '-':
+    case '_':
+    case '.':
+    case '~':
+      return false;
+  }
+  return true;
+}
+
+static void aws4_uri_encode(const string& src, string& dst)
+{
+  const char *p = src.c_str();
+  for (unsigned i = 0; i < src.size(); i++, p++) {
+    if (char_needs_aws4_escaping(*p)) {
+      rgw_uri_escape_char(*p, dst);
+      continue;
+    }
+
+    dst.append(p, 1);
+  }
+}
+
+/*
+ * handle v4 signatures (rados auth only)
+ */
+int RGW_Auth_S3::authorize_v4(RGWRados *store, struct req_state *s)
+{
+  string::size_type pos;
+  bool using_qs;
+
+  time_t now, now_req=0;
+  time(&now);
+
+  /* v4 requires rados auth */
+  if (!store->ctx()->_conf->rgw_s3_auth_use_rados) {
+    return -EPERM;
+  }
+
+  string algorithm = "AWS4-HMAC-SHA256";
+
+  s->aws4_auth = new rgw_aws4_auth;
+
+  if ((!s->http_auth) || !(*s->http_auth)) {
+
+    /* auth ships with req params ... */
+
+    /* look for required params */
+
+    using_qs = true;
+    s->aws4_auth->credential = s->info.args.get("X-Amz-Credential");
+    if (s->aws4_auth->credential.size() == 0) {
+      return -EPERM;
+    }
+
+    s->aws4_auth->date = s->info.args.get("X-Amz-Date");
+    struct tm date_t;
+    if (!parse_iso8601(s->aws4_auth->date.c_str(), &date_t, NULL, false))
+      return -EPERM;
+
+    s->aws4_auth->expires = s->info.args.get("X-Amz-Expires");
+    if (s->aws4_auth->expires.size() != 0) {
+      /* X-Amz-Expires provides the time period, in seconds, for which
+         the generated presigned URL is valid. The minimum value
+         you can set is 1, and the maximum is 604800 (seven days) */
+      time_t exp = atoll(s->aws4_auth->expires.c_str());
+      if ((exp < 1) || (exp > 604800)) {
+        dout(10) << "NOTICE: exp out of range, exp = " << exp << dendl;
+        return -EPERM;
+      }
+      /* handle expiration in epoch time */
+      now_req = mktime(&date_t);
+      if (now >= now_req + exp) {
+        dout(10) << "NOTICE: now = " << now << ", now_req = " << now_req << ", exp = " << exp << dendl;
         return -EPERM;
+      }
+    }
 
-      qsr = true;
-    } else {
-      /* anonymous access */
-      init_anon_user(s);
-      return 0;
+    if ( (now_req < now - RGW_AUTH_GRACE_MINS * 60) ||
+         (now_req > now + RGW_AUTH_GRACE_MINS * 60) ) {
+      dout(10) << "NOTICE: request time skew too big." << dendl;
+      dout(10) << "now_req = " << now_req << " now = " << now << "; now - RGW_AUTH_GRACE_MINS=" << now - RGW_AUTH_GRACE_MINS * 60 << "; now + RGW_AUTH_GRACE_MINS=" << now + RGW_AUTH_GRACE_MINS * 60 << dendl;
+      return -ERR_REQUEST_TIME_SKEWED;
+    }
+
+    s->aws4_auth->signedheaders = s->info.args.get("X-Amz-SignedHeaders");
+    if (s->aws4_auth->signedheaders.size() == 0) {
+      return -EPERM;
+    }
+
+    s->aws4_auth->signature = s->info.args.get("X-Amz-Signature");
+    if (s->aws4_auth->signature.size() == 0) {
+      return -EPERM;
     }
+
   } else {
-    if (strncmp(s->http_auth, "AWS ", 4))
+
+    /* auth ships in headers ... */
+
+    /* ------------------------- handle Credential header */
+
+    using_qs = false;
+    s->aws4_auth->credential = s->http_auth;
+
+    s->aws4_auth->credential = s->aws4_auth->credential.substr(17, s->aws4_auth->credential.length());
+
+    pos = s->aws4_auth->credential.find("Credential");
+    if (pos == std::string::npos) {
+      return -EINVAL;
+    }
+
+    s->aws4_auth->credential = s->aws4_auth->credential.substr(pos, s->aws4_auth->credential.find(","));
+
+    s->aws4_auth->credential = s->aws4_auth->credential.substr(pos + 1, s->aws4_auth->credential.length());
+
+    pos = s->aws4_auth->credential.find("=");
+
+    s->aws4_auth->credential = s->aws4_auth->credential.substr(pos + 1, s->aws4_auth->credential.length());
+
+    /* ------------------------- handle SignedHeaders header */
+
+    s->aws4_auth->signedheaders = s->http_auth;
+
+    s->aws4_auth->signedheaders = s->aws4_auth->signedheaders.substr(17, s->aws4_auth->signedheaders.length());
+
+    pos = s->aws4_auth->signedheaders.find("SignedHeaders");
+    if (pos == std::string::npos) {
+      return -EINVAL;
+    }
+
+    s->aws4_auth->signedheaders = s->aws4_auth->signedheaders.substr(pos, s->aws4_auth->signedheaders.length());
+
+    pos = s->aws4_auth->signedheaders.find(",");
+    if (pos == std::string::npos) {
+      return -EINVAL;
+    }
+
+    s->aws4_auth->signedheaders = s->aws4_auth->signedheaders.substr(0, pos);
+
+    pos = s->aws4_auth->signedheaders.find("=");
+    if (pos == std::string::npos) {
+      return -EINVAL;
+    }
+
+    s->aws4_auth->signedheaders = s->aws4_auth->signedheaders.substr(pos + 1, s->aws4_auth->signedheaders.length());
+
+    /* host;user-agent;x-amz-content-sha256;x-amz-date */
+    dout(10) << "v4 signedheaders format = " << s->aws4_auth->signedheaders << dendl;
+
+    /* ------------------------- handle Signature header */
+
+    s->aws4_auth->signature = s->http_auth;
+
+    s->aws4_auth->signature = s->aws4_auth->signature.substr(17, s->aws4_auth->signature.length());
+
+    pos = s->aws4_auth->signature.find("Signature");
+    if (pos == std::string::npos) {
       return -EINVAL;
+    }
+
+    s->aws4_auth->signature = s->aws4_auth->signature.substr(pos, s->aws4_auth->signature.length());
+
+    pos = s->aws4_auth->signature.find("=");
+    if (pos == std::string::npos) {
+      return -EINVAL;
+    }
+
+    s->aws4_auth->signature = s->aws4_auth->signature.substr(pos + 1, s->aws4_auth->signature.length());
+
+    /* sig hex str */
+    dout(10) << "v4 signature format = " << s->aws4_auth->signature << dendl;
+
+    /* ------------------------- handle x-amz-date header */
+
+    /* grab date */
+
+    const char *d = s->info.env->get("HTTP_X_AMZ_DATE");
+    struct tm t;
+    if (!parse_iso8601(d, &t, NULL, false)) {
+      dout(10) << "error reading date via http_x_amz_date" << dendl;
+      return -EACCES;
+    }
+    s->aws4_auth->date = d;
+  }
+
+  /* AKIAIVKTAZLOCF43WNQD/AAAAMMDD/region/host/aws4_request */
+  dout(10) << "v4 credential format = " << s->aws4_auth->credential << dendl;
+
+  if (std::count(s->aws4_auth->credential.begin(), s->aws4_auth->credential.end(), '/') != 4) {
+    return -EINVAL;
+  }
+
+  /* credential must end with 'aws4_request' */
+  if (s->aws4_auth->credential.find("aws4_request") == std::string::npos) {
+    return -EINVAL;
+  }
+
+  /* grab access key id */
+
+  pos = s->aws4_auth->credential.find("/");
+  s->aws4_auth->access_key_id = s->aws4_auth->credential.substr(0, pos);
+
+  dout(10) << "access key id = " << s->aws4_auth->access_key_id << dendl;
+
+  /* grab credential scope */
+
+  s->aws4_auth->credential_scope = s->aws4_auth->credential.substr(pos + 1, s->aws4_auth->credential.length());
+
+  dout(10) << "credential scope = " << s->aws4_auth->credential_scope << dendl;
+
+  /* grab user information */
+
+  if (rgw_get_user_info_by_access_key(store, s->aws4_auth->access_key_id, *s->user) < 0) {
+    dout(10) << "error reading user info, uid=" << s->aws4_auth->access_key_id
+              << " can't authenticate" << dendl;
+    return -ERR_INVALID_ACCESS_KEY;
+  }
+
+  /*
+   * create a canonical request
+   *
+   * http://docs.aws.amazon.com/general/latest/gr/sigv4-create-canonical-request.html
+   */
+
+  /* craft canonical uri */
+
+  /* here code should normalize via rfc3986 but S3 does **NOT** do path normalization
+   * that SigV4 typically does. this code follows the same approach that boto library
+   * see auth.py:canonical_uri(...) */
+
+  s->aws4_auth->canonical_uri = s->info.request_uri;
+
+  if (s->aws4_auth->canonical_uri.empty()) {
+    s->aws4_auth->canonical_uri = "/";
+  }
+
+  /* craft canonical query string */
+
+  s->aws4_auth->canonical_qs = s->info.request_params;
+
+  if (!s->aws4_auth->canonical_qs.empty()) {
+
+    /* handle case when query string exists. Step 3 in
+     * http://docs.aws.amazon.com/general/latest/gr/sigv4-create-canonical-request.html */
+
+    map<string, string> canonical_qs_map;
+    istringstream cqs(s->aws4_auth->canonical_qs);
+    string keyval;
+
+    while (getline(cqs, keyval, '&')) {
+      string key, val;
+      istringstream kv(keyval);
+      getline(kv, key, '=');
+      getline(kv, val, '=');
+      if (!using_qs || key != "X-Amz-Signature") {
+        string encoded_key;
+        string encoded_val;
+        if (key != "X-Amz-Credential") {
+          aws4_uri_encode(key, encoded_key);
+          aws4_uri_encode(val, encoded_val);
+        } else {
+          encoded_key = key;
+          encoded_val = val;
+        }
+        canonical_qs_map[encoded_key] = encoded_val;
+      }
+    }
+
+    s->aws4_auth->canonical_qs = "";
+
+    map<string, string>::iterator last = canonical_qs_map.end();
+    --last;
+
+    for (map<string, string>::iterator it = canonical_qs_map.begin();
+        it != canonical_qs_map.end(); ++it) {
+      s->aws4_auth->canonical_qs.append(it->first + "=" + it->second);
+      if (it != last) {
+        s->aws4_auth->canonical_qs.append("&");
+      }
+    }
+
+  }
+
+  /* craft canonical headers */
+
+  map<string, string> canonical_hdrs_map;
+  istringstream sh(s->aws4_auth->signedheaders);
+  string token;
+  string port = s->info.env->get("SERVER_PORT");
+
+  while (getline(sh, token, ';')) {
+    string token_env = "HTTP_" + token;
+    transform(token_env.begin(), token_env.end(), token_env.begin(), ::toupper);
+    replace(token_env.begin(), token_env.end(), '-', '_');
+    if (token_env == "HTTP_CONTENT_LENGTH") {
+      token_env = "CONTENT_LENGTH";
+    }
+    if (token_env == "HTTP_CONTENT_TYPE") {
+      token_env = "CONTENT_TYPE";
+    }
+    const char *t = s->info.env->get(token_env.c_str());
+    if (!t) {
+      dout(10) << "warning env var not available" << dendl;
+      continue;
+    }
+    if (token_env == "HTTP_CONTENT_MD5") {
+      for (const char *p = t; *p; p++) {
+	if (!is_base64_for_content_md5(*p)) {
+	  dout(0) << "NOTICE: bad content-md5 provided (not base64), aborting request p=" << *p << " " << (int)*p << dendl;
+	  return -EPERM;
+	}
+      }
+    }
+    string token_value = string(t);
+    if (using_qs && (token == "host"))
+      token_value = token_value + ":" + port;
+    canonical_hdrs_map[token] = rgw_trim_whitespace(token_value);
+  }
+
+  for (map<string, string>::iterator it = canonical_hdrs_map.begin();
+      it != canonical_hdrs_map.end(); ++it) {
+    s->aws4_auth->canonical_hdrs.append(it->first + ":" + it->second + "\n");
+  }
+
+  dout(10) << "canonical headers format = " << s->aws4_auth->canonical_hdrs << dendl;
+
+  /* craft signed headers */
+
+  s->aws4_auth->signed_hdrs = s->aws4_auth->signedheaders;
+
+  /* handle request payload */
+
+  /* from rfc2616 - 4.3 Message Body
+   *
+   * "The presence of a message-body in a request is signaled by the inclusion of a
+   *  Content-Length or Transfer-Encoding header field in the request's message-headers."
+   */
+
+  s->aws4_auth->payload_hash = "";
+
+  string request_payload;
+
+  bool unsigned_payload = false;
+  if (using_qs) {
+    unsigned_payload = true;
+  }
+
+  if (using_qs || ((s->content_length == 0) && s->info.env->get("HTTP_TRANSFER_ENCODING") == NULL)) {
+
+    /* requests lacking of body are authenticated now */
+
+    /* complete aws4 auth */
+
+    int err = authorize_v4_complete(store, s, request_payload, unsigned_payload);
+    if (err) {
+      return err;
+    }
+
+    /* verify signature */
+
+    if (s->aws4_auth->signature != s->aws4_auth->new_signature) {
+      return -ERR_SIGNATURE_NO_MATCH;
+    }
+
+    /* authorization ok */
+
+    dout(10) << "v4 auth ok" << dendl;
+
+    /* aws4 auth completed */
+
+    s->aws4_auth_needs_complete = false;
+
+  } else {
+
+    /* aws4 auth not completed... delay aws4 auth */
+
+    dout(10) << "body content detected... delaying v4 auth" << dendl;
+
+    switch (s->op_type)
+    {
+      case RGW_OP_CREATE_BUCKET:
+      case RGW_OP_PUT_OBJ:
+      case RGW_OP_PUT_ACLS:
+      case RGW_OP_PUT_CORS:
+      case RGW_OP_COMPLETE_MULTIPART:
+      case RGW_OP_SET_BUCKET_VERSIONING:
+      case RGW_OP_DELETE_MULTI_OBJ:
+      case RGW_OP_ADMIN_SET_METADATA:
+        break;
+      default:
+        dout(10) << "ERROR: AWS4 completion for this operation NOT IMPLEMENTED" << dendl;
+        return -ERR_NOT_IMPLEMENTED;
+    }
+
+    s->aws4_auth_needs_complete = true;
+
+  }
+
+  map<string, RGWAccessKey>::iterator iter = s->user->access_keys.find(s->aws4_auth->access_key_id);
+  if (iter == s->user->access_keys.end()) {
+    dout(0) << "ERROR: access key not encoded in user info" << dendl;
+    return -EPERM;
+  }
+
+  RGWAccessKey& k = iter->second;
+
+  if (!k.subuser.empty()) {
+    map<string, RGWSubUser>::iterator uiter = s->user->subusers.find(k.subuser);
+    if (uiter == s->user->subusers.end()) {
+      dout(0) << "NOTICE: could not find subuser: " << k.subuser << dendl;
+      return -EPERM;
+    }
+    RGWSubUser& subuser = uiter->second;
+    s->perm_mask = subuser.perm_mask;
+  } else {
+    s->perm_mask = RGW_PERM_FULL_CONTROL;
+  }
+
+  if (s->user->system) {
+    s->system_request = true;
+    dout(20) << "system request" << dendl;
+    s->info.args.set_system();
+    string euid = s->info.args.get(RGW_SYS_PARAM_PREFIX "uid");
+    rgw_user effective_uid(euid);
+    RGWUserInfo effective_user;
+    if (!effective_uid.empty()) {
+      int ret = rgw_get_user_info_by_uid(store, effective_uid, effective_user);
+      if (ret < 0) {
+        ldout(s->cct, 0) << "User lookup failed!" << dendl;
+        return -ENOENT;
+      }
+      *(s->user) = effective_user;
+    }
+  }
+
+  // populate the owner info
+  s->owner.set_id(s->user->user_id);
+  s->owner.set_name(s->user->display_name);
+
+  return 0;
+}
+
+/*
+ * handle v2 signatures
+ */
+int RGW_Auth_S3::authorize_v2(RGWRados *store, struct req_state *s)
+{
+  bool qsr = false;
+  string auth_id;
+  string auth_sign;
+
+  time_t now;
+  time(&now);
+
+  if (!s->http_auth || !(*s->http_auth)) {
+    auth_id = s->info.args.get("AWSAccessKeyId");
+    auth_sign = s->info.args.get("Signature");
+    string date = s->info.args.get("Expires");
+    time_t exp = atoll(date.c_str());
+    if (now >= exp)
+      return -EPERM;
+    qsr = true;
+  } else {
     string auth_str(s->http_auth + 4);
     int pos = auth_str.rfind(':');
     if (pos < 0)
       return -EINVAL;
-
     auth_id = auth_str.substr(0, pos);
     auth_sign = auth_str.substr(pos + 1);
   }
 
   /* try keystone auth first */
-  int keystone_result = -EINVAL;
+  int external_auth_result = -ERR_INVALID_ACCESS_KEY;;
   if (store->ctx()->_conf->rgw_s3_auth_use_keystone
       && !store->ctx()->_conf->rgw_keystone_url.empty()) {
     dout(20) << "s3 keystone: trying keystone auth" << dendl;
@@ -2696,31 +3651,44 @@ int RGW_Auth_S3::authorize(RGWRados *store, struct req_state *s)
     RGW_Auth_S3_Keystone_ValidateToken keystone_validator(store->ctx());
     string token;
 
-    if (!rgw_create_s3_canonical_header(s->info, &s->header_time, token, qsr)) {
-        dout(10) << "failed to create auth header\n" << token << dendl;
+    if (!rgw_create_s3_canonical_header(s->info,
+                                        &s->header_time, token, qsr)) {
+      dout(10) << "failed to create auth header\n" << token << dendl;
+      external_auth_result = -EPERM;
     } else {
-      keystone_result = keystone_validator.validate_s3token(auth_id, token, auth_sign);
-      if (keystone_result == 0) {
+      external_auth_result = keystone_validator.validate_s3token(auth_id, token,
+							    auth_sign);
+      if (external_auth_result == 0) {
 	// Check for time skew first
 	time_t req_sec = s->header_time.sec();
 
 	if ((req_sec < now - RGW_AUTH_GRACE_MINS * 60 ||
 	     req_sec > now + RGW_AUTH_GRACE_MINS * 60) && !qsr) {
-	  dout(10) << "req_sec=" << req_sec << " now=" << now << "; now - RGW_AUTH_GRACE_MINS=" << now - RGW_AUTH_GRACE_MINS * 60 << "; now + RGW_AUTH_GRACE_MINS=" << now + RGW_AUTH_GRACE_MINS * 60 << dendl;
-	  dout(0) << "NOTICE: request time skew too big now=" << utime_t(now, 0) << " req_time=" << s->header_time << dendl;
+	  ldout(s->cct, 10) << "req_sec=" << req_sec << " now=" << now
+                            << "; now - RGW_AUTH_GRACE_MINS="
+                            << now - RGW_AUTH_GRACE_MINS * 60
+                            << "; now + RGW_AUTH_GRACE_MINS="
+                            << now + RGW_AUTH_GRACE_MINS * 60
+                            << dendl;
+
+	  ldout(s->cct, 0)  << "NOTICE: request time skew too big now="
+                            << utime_t(now, 0)
+                            << " req_time=" << s->header_time
+                            << dendl;
 	  return -ERR_REQUEST_TIME_SKEWED;
 	}
 
+        string project_id = keystone_validator.response.get_project_id();
+        s->user->user_id = project_id;
+        s->user->display_name = keystone_validator.response.get_project_name(); // wow.
 
-	s->user.user_id = keystone_validator.response.token.tenant.id;
-        s->user.display_name = keystone_validator.response.token.tenant.name; // wow.
-
-        rgw_user uid(keystone_validator.response.token.tenant.id);
+        rgw_user uid(project_id);
         /* try to store user if it not already exists */
-        if (rgw_get_user_info_by_uid(store, uid, s->user) < 0) {
-          int ret = rgw_store_user_info(store, s->user, NULL, NULL, 0, true);
+        if (rgw_get_user_info_by_uid(store, uid, *(s->user)) < 0) {
+          int ret = rgw_store_user_info(store, *(s->user), NULL, NULL, real_time(), true);
           if (ret < 0)
-            dout(10) << "NOTICE: failed to store new user's info: ret=" << ret << dendl;
+            dout(10) << "NOTICE: failed to store new user's info: ret="
+		     << ret << dendl;
         }
 
         s->perm_mask = RGW_PERM_FULL_CONTROL;
@@ -2728,23 +3696,55 @@ int RGW_Auth_S3::authorize(RGWRados *store, struct req_state *s)
     }
   }
 
+  if ((external_auth_result < 0) &&
+      (store->ctx()->_conf->rgw_s3_auth_use_ldap) &&
+      (! store->ctx()->_conf->rgw_ldap_uri.empty())) {
+
+    RGW_Auth_S3::init(store);
+
+    RGWToken token{from_base64(auth_id)};
+    if ((! token.valid()) || ldh->auth(token.id, token.key) != 0)
+      external_auth_result = -EACCES;
+    else {
+      /* ok, succeeded */
+      external_auth_result = 0;
+
+      /* create local account, if none exists */
+      s->user->user_id = token.id;
+      s->user->display_name = token.id; // cn?
+      int ret = rgw_get_user_info_by_uid(store, s->user->user_id, *(s->user));
+      if (ret < 0) {
+	ret = rgw_store_user_info(store, *(s->user), nullptr, nullptr,
+				  real_time(), true);
+	if (ret < 0) {
+	  dout(10) << "NOTICE: failed to store new user's info: ret=" << ret
+		   << dendl;
+	}
+      }
+
+      /* set request perms */
+      s->perm_mask = RGW_PERM_FULL_CONTROL;
+    } /* success */
+  } /* ldap */
+
   /* keystone failed (or not enabled); check if we want to use rados backend */
   if (!store->ctx()->_conf->rgw_s3_auth_use_rados
-      && keystone_result < 0)
-    return keystone_result;
+      && external_auth_result < 0)
+    return external_auth_result;
 
   /* now try rados backend, but only if keystone did not succeed */
-  if (keystone_result < 0) {
+  if (external_auth_result < 0) {
     /* get the user info */
-    if (rgw_get_user_info_by_access_key(store, auth_id, s->user) < 0) {
-      dout(5) << "error reading user info, uid=" << auth_id << " can't authenticate" << dendl;
-      return -ERR_INVALID_ACCESS_KEY;
+    if (rgw_get_user_info_by_access_key(store, auth_id, *(s->user)) < 0) {
+      dout(5) << "error reading user info, uid=" << auth_id
+              << " can't authenticate" << dendl;
+      return external_auth_result;
     }
 
     /* now verify signature */
-
     string auth_hdr;
-    if (!rgw_create_s3_canonical_header(s->info, &s->header_time, auth_hdr, qsr)) {
+    if (!rgw_create_s3_canonical_header(s->info, &s->header_time, auth_hdr,
+					qsr)) {
       dout(10) << "failed to create auth header\n" << auth_hdr << dendl;
       return -EPERM;
     }
@@ -2753,23 +3753,30 @@ int RGW_Auth_S3::authorize(RGWRados *store, struct req_state *s)
     time_t req_sec = s->header_time.sec();
     if ((req_sec < now - RGW_AUTH_GRACE_MINS * 60 ||
         req_sec > now + RGW_AUTH_GRACE_MINS * 60) && !qsr) {
-      dout(10) << "req_sec=" << req_sec << " now=" << now << "; now - RGW_AUTH_GRACE_MINS=" << now - RGW_AUTH_GRACE_MINS * 60 << "; now + RGW_AUTH_GRACE_MINS=" << now + RGW_AUTH_GRACE_MINS * 60 << dendl;
-      dout(0) << "NOTICE: request time skew too big now=" << utime_t(now, 0) << " req_time=" << s->header_time << dendl;
+      dout(10) << "req_sec=" << req_sec << " now=" << now
+               << "; now - RGW_AUTH_GRACE_MINS=" << now - RGW_AUTH_GRACE_MINS * 60
+               << "; now + RGW_AUTH_GRACE_MINS=" << now + RGW_AUTH_GRACE_MINS * 60
+               << dendl;
+      dout(0)  << "NOTICE: request time skew too big now=" << utime_t(now, 0)
+               << " req_time=" << s->header_time
+               << dendl;
       return -ERR_REQUEST_TIME_SKEWED;
     }
 
-    map<string, RGWAccessKey>::iterator iter = s->user.access_keys.find(auth_id);
-    if (iter == s->user.access_keys.end()) {
+    map<string, RGWAccessKey>::iterator iter =
+      s->user->access_keys.find(auth_id);
+    if (iter == s->user->access_keys.end()) {
       dout(0) << "ERROR: access key not encoded in user info" << dendl;
       return -EPERM;
     }
     RGWAccessKey& k = iter->second;
 
     if (!k.subuser.empty()) {
-      map<string, RGWSubUser>::iterator uiter = s->user.subusers.find(k.subuser);
-      if (uiter == s->user.subusers.end()) {
-        dout(0) << "NOTICE: could not find subuser: " << k.subuser << dendl;
-        return -EPERM;
+      map<string, RGWSubUser>::iterator uiter =
+	s->user->subusers.find(k.subuser);
+      if (uiter == s->user->subusers.end()) {
+	dout(0) << "NOTICE: could not find subuser: " << k.subuser << dendl;
+	return -EPERM;
       }
       RGWSubUser& subuser = uiter->second;
       s->perm_mask = subuser.perm_mask;
@@ -2790,7 +3797,7 @@ int RGW_Auth_S3::authorize(RGWRados *store, struct req_state *s)
       return -ERR_SIGNATURE_NO_MATCH;
     }
 
-    if (s->user.system) {
+    if (s->user->system) {
       s->system_request = true;
       dout(20) << "system request" << dendl;
       s->info.args.set_system();
@@ -2803,60 +3810,66 @@ int RGW_Auth_S3::authorize(RGWRados *store, struct req_state *s)
           ldout(s->cct, 0) << "User lookup failed!" << dendl;
           return -ENOENT;
         }
-        s->user = effective_user;
+        *(s->user) = effective_user;
       }
     }
 
-  } /* if keystone_result < 0 */
+  } /* if external_auth_result < 0 */
 
   // populate the owner info
-  s->owner.set_id(s->user.user_id);
-  s->owner.set_name(s->user.display_name);
+  s->owner.set_id(s->user->user_id);
+  s->owner.set_name(s->user->display_name);
 
   return  0;
 }
 
-int RGWHandler_Auth_S3::init(RGWRados *store, struct req_state *state, RGWClientIO *cio)
+int RGWHandler_Auth_S3::init(RGWRados *store, struct req_state *state,
+			     RGWClientIO *cio)
 {
-  int ret = RGWHandler_ObjStore_S3::init_from_header(state, RGW_FORMAT_JSON, true);
+  int ret = RGWHandler_REST_S3::init_from_header(state, RGW_FORMAT_JSON,
+						     true);
   if (ret < 0)
     return ret;
 
-  return RGWHandler_ObjStore::init(store, state, cio);
+  return RGWHandler_REST::init(store, state, cio);
 }
 
-RGWHandler *RGWRESTMgr_S3::get_handler(struct req_state *s)
+RGWHandler_REST* RGWRESTMgr_S3::get_handler(struct req_state *s)
 {
   bool is_s3website = enable_s3website && (s->prot_flags & RGW_REST_WEBSITE);
-  int ret = RGWHandler_ObjStore_S3::init_from_header(s, is_s3website ? RGW_FORMAT_HTML : RGW_FORMAT_XML, false);
+  int ret =
+    RGWHandler_REST_S3::init_from_header(s,
+					is_s3website ? RGW_FORMAT_HTML :
+					RGW_FORMAT_XML, true);
   if (ret < 0)
     return NULL;
 
-  RGWHandler* handler;
+  RGWHandler_REST* handler;
   // TODO: Make this more readable
   if (is_s3website) {
     if (s->init_state.url_bucket.empty()) {
-      handler = new RGWHandler_ObjStore_Service_S3Website;
+      handler = new RGWHandler_REST_Service_S3Website;
     } else if (s->object.empty()) {
-      handler = new RGWHandler_ObjStore_Bucket_S3Website;
+      handler = new RGWHandler_REST_Bucket_S3Website;
     } else {
-      handler = new RGWHandler_ObjStore_Obj_S3Website;
+      handler = new RGWHandler_REST_Obj_S3Website;
     }
   } else {
     if (s->init_state.url_bucket.empty()) {
-      handler = new RGWHandler_ObjStore_Service_S3;
+      handler = new RGWHandler_REST_Service_S3;
     } else if (s->object.empty()) {
-      handler = new RGWHandler_ObjStore_Bucket_S3;
+      handler = new RGWHandler_REST_Bucket_S3;
     } else {
-      handler = new RGWHandler_ObjStore_Obj_S3;
+      handler = new RGWHandler_REST_Obj_S3;
     }
   }
 
-  ldout(s->cct, 20) << __func__ << " handler=" << typeid(*handler).name() << dendl;
+  ldout(s->cct, 20) << __func__ << " handler=" << typeid(*handler).name()
+		    << dendl;
   return handler;
 }
 
-int RGWHandler_ObjStore_S3Website::retarget(RGWOp *op, RGWOp **new_op) {
+int RGWHandler_REST_S3Website::retarget(RGWOp* op, RGWOp** new_op) {
   *new_op = op;
   ldout(s->cct, 10) << __func__ << "Starting retarget" << dendl;
 
@@ -2864,7 +3877,9 @@ int RGWHandler_ObjStore_S3Website::retarget(RGWOp *op, RGWOp **new_op) {
     return 0;
 
   RGWObjectCtx& obj_ctx = *static_cast<RGWObjectCtx *>(s->obj_ctx);
-  int ret = store->get_bucket_info(obj_ctx, s->bucket_tenant, s->bucket_name, s->bucket_info, NULL, &s->bucket_attrs);
+  int ret = store->get_bucket_info(obj_ctx, s->bucket_tenant,
+				  s->bucket_name, s->bucket_info, NULL,
+				  &s->bucket_attrs);
   if (ret < 0) {
       // TODO-FUTURE: if the bucket does not exist, maybe expose it here?
       return -ERR_NO_SUCH_BUCKET;
@@ -2876,26 +3891,32 @@ int RGWHandler_ObjStore_S3Website::retarget(RGWOp *op, RGWOp **new_op) {
 
   rgw_obj_key new_obj;
   s->bucket_info.website_conf.get_effective_key(s->object.name, &new_obj.name);
-  ldout(s->cct, 10) << "retarget get_effective_key " << s->object << " -> " << new_obj << dendl;
+  ldout(s->cct, 10) << "retarget get_effective_key " << s->object << " -> "
+		    << new_obj << dendl;
 
   RGWBWRoutingRule rrule;
-  bool should_redirect = s->bucket_info.website_conf.should_redirect(new_obj.name, 0, &rrule);
+  bool should_redirect =
+    s->bucket_info.website_conf.should_redirect(new_obj.name, 0, &rrule);
 
   if (should_redirect) {
     const string& hostname = s->info.env->get("HTTP_HOST", "");
-    const string& protocol = (s->info.env->get("SERVER_PORT_SECURE") ? "https" : "http");
+    const string& protocol =
+      (s->info.env->get("SERVER_PORT_SECURE") ? "https" : "http");
     int redirect_code = 0;
-    rrule.apply_rule(protocol, hostname, s->object.name, &s->redirect, &redirect_code);
+    rrule.apply_rule(protocol, hostname, s->object.name, &s->redirect,
+		    &redirect_code);
     // APply a custom HTTP response code
     if (redirect_code > 0)
       s->err.http_ret = redirect_code; // Apply a custom HTTP response code
-    ldout(s->cct, 10) << "retarget redirect code=" << redirect_code << " proto+host:" << protocol << "://" << hostname << " -> " << s->redirect << dendl;
+    ldout(s->cct, 10) << "retarget redirect code=" << redirect_code
+		      << " proto+host:" << protocol << "://" << hostname
+		      << " -> " << s->redirect << dendl;
     return -ERR_WEBSITE_REDIRECT;
   }
 
   /*
-   * FIXME: if s->object != new_obj, drop op and create a new op to handle operation. Or
-   * remove this comment if it's not applicable anymore
+   * FIXME: if s->object != new_obj, drop op and create a new op to handle
+   * operation. Or remove this comment if it's not applicable anymore
    */
 
   s->object = new_obj;
@@ -2903,52 +3924,57 @@ int RGWHandler_ObjStore_S3Website::retarget(RGWOp *op, RGWOp **new_op) {
   return 0;
 }
 
-RGWOp *RGWHandler_ObjStore_S3Website::op_get()
+RGWOp* RGWHandler_REST_S3Website::op_get()
 {
   return get_obj_op(true);
 }
 
-RGWOp *RGWHandler_ObjStore_S3Website::op_head()
+RGWOp* RGWHandler_REST_S3Website::op_head()
 {
   return get_obj_op(false);
 }
 
-int RGWHandler_ObjStore_S3Website::get_errordoc(const string errordoc_key, string *error_content) {
-    ldout(s->cct, 20) << "TODO Serve Custom error page here if bucket has <Error>" << dendl;
-    *error_content = errordoc_key;
-    // 1. Check if errordoc exists
-    // 2. Check if errordoc is public
-    // 3. Fetch errordoc content
-    /*
-     * FIXME maybe:  need to make sure all of the fields for conditional requests are cleared
-     */
-    RGWGetObj_ObjStore_S3Website *getop = new RGWGetObj_ObjStore_S3Website(true);
-    getop->set_get_data(true);
-    getop->init(store, s, this);
-
-    RGWGetObj_CB cb(getop);
-    rgw_obj obj(s->bucket, errordoc_key);
-    RGWObjectCtx rctx(store);
-    //RGWRados::Object op_target(store, s->bucket_info, *static_cast<RGWObjectCtx *>(s->obj_ctx), obj);
-    RGWRados::Object op_target(store, s->bucket_info, rctx, obj);
-    RGWRados::Object::Read read_op(&op_target);
-
-    int ret;
-    int64_t ofs = 0; 
-    int64_t end = -1;
-    ret = read_op.prepare(&ofs, &end);
-    if (ret < 0) {
-      goto done;
-    }
+int RGWHandler_REST_S3Website::get_errordoc(const string& errordoc_key,
+					    std::string* error_content) {
+  ldout(s->cct, 20) << "TODO Serve Custom error page here if bucket has "
+    "<Error>" << dendl;
+  *error_content = errordoc_key;
+  // 1. Check if errordoc exists
+  // 2. Check if errordoc is public
+  // 3. Fetch errordoc content
+  /*
+   * FIXME maybe:  need to make sure all of the fields for conditional
+   * requests are cleared
+   */
+  RGWGetObj_ObjStore_S3Website* getop =
+    new RGWGetObj_ObjStore_S3Website(true);
+  getop->set_get_data(true);
+  getop->init(store, s, this);
+
+  RGWGetObj_CB cb(getop);
+  rgw_obj obj(s->bucket, errordoc_key);
+  RGWObjectCtx rctx(store);
+  //RGWRados::Object op_target(store, s->bucket_info, *static_cast<RGWObjectCtx *>(s->obj_ctx), obj);
+  RGWRados::Object op_target(store, s->bucket_info, rctx, obj);
+  RGWRados::Object::Read read_op(&op_target);
 
-    ret = read_op.iterate(ofs, end, &cb); // FIXME: need to know the final size?
+  int ret;
+  int64_t ofs = 0; 
+  int64_t end = -1;
+  ret = read_op.prepare(&ofs, &end);
+  if (ret < 0) {
+    goto done;
+  }
+
+  ret = read_op.iterate(ofs, end, &cb); // FIXME: need to know the final size?
 done:
-    delete getop;
-    return ret;
+  delete getop;
+  return ret;
 }
   
-int RGWHandler_ObjStore_S3Website::error_handler(int err_no, string *error_content) {
-  const struct rgw_http_errors *r;
+int RGWHandler_REST_S3Website::error_handler(int err_no,
+					    string* error_content) {
+  const struct rgw_http_errors* r;
   int http_error_code = -1;
   r = search_err(err_no, RGW_HTTP_ERRORS, ARRAY_LEN(RGW_HTTP_ERRORS));
   if (r) {
@@ -2956,20 +3982,27 @@ int RGWHandler_ObjStore_S3Website::error_handler(int err_no, string *error_conte
   }
 
   RGWBWRoutingRule rrule;
-  bool should_redirect = s->bucket_info.website_conf.should_redirect(s->object.name, http_error_code, &rrule);
+  bool should_redirect =
+    s->bucket_info.website_conf.should_redirect(s->object.name, http_error_code,
+						&rrule);
 
   if (should_redirect) {
     const string& hostname = s->info.env->get("HTTP_HOST", "");
-    const string& protocol = (s->info.env->get("SERVER_PORT_SECURE") ? "https" : "http");
+    const string& protocol =
+      (s->info.env->get("SERVER_PORT_SECURE") ? "https" : "http");
     int redirect_code = 0;
-    rrule.apply_rule(protocol, hostname, s->object.name, &s->redirect, &redirect_code);
-    // APply a custom HTTP response code
+    rrule.apply_rule(protocol, hostname, s->object.name, &s->redirect,
+		    &redirect_code);
+    // Apply a custom HTTP response code
     if (redirect_code > 0)
       s->err.http_ret = redirect_code; // Apply a custom HTTP response code
-    ldout(s->cct, 10) << "error handler redirect code=" << redirect_code << " proto+host:" << protocol << "://" << hostname << " -> " << s->redirect << dendl;
+    ldout(s->cct, 10) << "error handler redirect code=" << redirect_code
+		      << " proto+host:" << protocol << "://" << hostname
+		      << " -> " << s->redirect << dendl;
     return -ERR_WEBSITE_REDIRECT;
   } else if (!s->bucket_info.website_conf.error_doc.empty()) {
-    RGWHandler_ObjStore_S3Website::get_errordoc(s->bucket_info.website_conf.error_doc, error_content);
+    RGWHandler_REST_S3Website::get_errordoc(
+      s->bucket_info.website_conf.error_doc, error_content);
   } else {
     ldout(s->cct, 20) << "No special error handling today!" << dendl;
   }
@@ -2977,35 +4010,35 @@ int RGWHandler_ObjStore_S3Website::error_handler(int err_no, string *error_conte
   return err_no;
 }
 
-RGWOp *RGWHandler_ObjStore_Obj_S3Website::get_obj_op(bool get_data)
+RGWOp* RGWHandler_REST_Obj_S3Website::get_obj_op(bool get_data)
 {
   /** If we are in website mode, then it is explicitly impossible to run GET or
    * HEAD on the actual directory. We must convert the request to run on the
    * suffix object instead!
    */
-  RGWGetObj_ObjStore_S3Website *op = new RGWGetObj_ObjStore_S3Website;
+  RGWGetObj_ObjStore_S3Website* op = new RGWGetObj_ObjStore_S3Website;
   op->set_get_data(get_data);
   return op;
 }
 
-RGWOp *RGWHandler_ObjStore_Bucket_S3Website::get_obj_op(bool get_data)
+RGWOp* RGWHandler_REST_Bucket_S3Website::get_obj_op(bool get_data)
 {
   /** If we are in website mode, then it is explicitly impossible to run GET or
    * HEAD on the actual directory. We must convert the request to run on the
    * suffix object instead!
    */
-  RGWGetObj_ObjStore_S3Website *op = new RGWGetObj_ObjStore_S3Website;
+  RGWGetObj_ObjStore_S3Website* op = new RGWGetObj_ObjStore_S3Website;
   op->set_get_data(get_data);
   return op;
 }
 
-RGWOp *RGWHandler_ObjStore_Service_S3Website::get_obj_op(bool get_data)
+RGWOp* RGWHandler_REST_Service_S3Website::get_obj_op(bool get_data)
 {
   /** If we are in website mode, then it is explicitly impossible to run GET or
    * HEAD on the actual directory. We must convert the request to run on the
    * suffix object instead!
    */
-  RGWGetObj_ObjStore_S3Website *op = new RGWGetObj_ObjStore_S3Website;
+  RGWGetObj_ObjStore_S3Website* op = new RGWGetObj_ObjStore_S3Website;
   op->set_get_data(get_data);
   return op;
 }
diff --git a/src/rgw/rgw_rest_s3.h b/src/rgw/rgw_rest_s3.h
index ada5562..9278964 100644
--- a/src/rgw/rgw_rest_s3.h
+++ b/src/rgw/rgw_rest_s3.h
@@ -2,14 +2,19 @@
 // vim: ts=8 sw=2 smarttab
 
 #ifndef CEPH_RGW_REST_S3_H
+
 #define CEPH_RGW_REST_S3_H
 #define TIME_BUF_SIZE 128
 
+#include <mutex>
+
 #include "rgw_op.h"
 #include "rgw_http_errors.h"
 #include "rgw_acl_s3.h"
 #include "rgw_policy_s3.h"
 #include "rgw_keystone.h"
+#include "rgw_rest_conn.h"
+#include "rgw_ldap.h"
 
 #define RGW_AUTH_GRACE_MINS 15
 
@@ -39,9 +44,19 @@ public:
   virtual void send_response_end();
 };
 
+class RGWGetUsage_ObjStore_S3 : public RGWGetUsage_ObjStore {
+public:
+  RGWGetUsage_ObjStore_S3() {}
+  ~RGWGetUsage_ObjStore_S3() {}
+
+  int get_params() ;
+  virtual void send_response();
+};
+
 class RGWListBucket_ObjStore_S3 : public RGWListBucket_ObjStore {
+  bool objs_container;
 public:
-  RGWListBucket_ObjStore_S3() {
+  RGWListBucket_ObjStore_S3() : objs_container(false) {
     default_max = 1000;
   }
   ~RGWListBucket_ObjStore_S3() {}
@@ -140,6 +155,7 @@ public:
   ~RGWPutObj_ObjStore_S3() {}
 
   int get_params();
+  int get_data(bufferlist& bl);
   void send_response();
 };
 
@@ -195,6 +211,7 @@ public:
   RGWDeleteObj_ObjStore_S3() {}
   ~RGWDeleteObj_ObjStore_S3() {}
 
+  int get_params();
   void send_response();
 };
 
@@ -225,6 +242,7 @@ public:
 
   int get_policy_from_state(RGWRados *store, struct req_state *s, stringstream& ss);
   void send_response();
+  int get_params();
 };
 
 class RGWGetCORS_ObjStore_S3 : public RGWGetCORS_ObjStore {
@@ -291,6 +309,7 @@ public:
   RGWCompleteMultipart_ObjStore_S3() {}
   ~RGWCompleteMultipart_ObjStore_S3() {}
 
+  int get_params();
   void send_response();
 };
 
@@ -325,6 +344,7 @@ public:
   RGWDeleteMultiObj_ObjStore_S3() {}
   ~RGWDeleteMultiObj_ObjStore_S3() {}
 
+  int get_params();
   void send_status();
   void begin_response();
   void send_partial_response(rgw_obj_key& key, bool delete_marker,
@@ -384,14 +404,40 @@ public:
 };
 
 class RGW_Auth_S3 {
+private:
+  static std::mutex mtx;
+  static rgw::LDAPHelper* ldh;
+
+  static int authorize_v2(RGWRados *store, struct req_state *s);
+  static int authorize_v4(RGWRados *store, struct req_state *s);
+  static int authorize_v4_complete(RGWRados *store, struct req_state *s,
+				  const string& request_payload,
+				  bool unsigned_payload);
 public:
   static int authorize(RGWRados *store, struct req_state *s);
+  static int authorize_aws4_auth_complete(RGWRados *store, struct req_state *s);
+
+  static inline void init(RGWRados* store) {
+    if (! ldh) {
+      std::lock_guard<std::mutex> lck(mtx);
+      if (! ldh) {
+	init_impl(store);
+      }
+    }
+  }
+
+  static inline rgw::LDAPHelper* get_ldap_ctx(RGWRados* store) {
+    init(store);
+    return ldh;
+  }
+
+  static void init_impl(RGWRados* store);
 };
 
-class RGWHandler_Auth_S3 : public RGWHandler_ObjStore {
+class RGWHandler_Auth_S3 : public RGWHandler_REST {
   friend class RGWRESTMgr_S3;
 public:
-  RGWHandler_Auth_S3() : RGWHandler_ObjStore() {}
+  RGWHandler_Auth_S3() : RGWHandler_REST() {}
   virtual ~RGWHandler_Auth_S3() {}
 
   virtual int validate_bucket_name(const string& bucket) {
@@ -407,17 +453,16 @@ public:
   int postauth_init() { return 0; }
 };
 
-class RGWHandler_ObjStore_S3 : public RGWHandler_ObjStore {
+class RGWHandler_REST_S3 : public RGWHandler_REST {
   friend class RGWRESTMgr_S3;
 public:
   static int init_from_header(struct req_state *s, int default_formatter, bool configurable_format);
 
-  RGWHandler_ObjStore_S3() : RGWHandler_ObjStore() {}
-  virtual ~RGWHandler_ObjStore_S3() {}
+  RGWHandler_REST_S3() : RGWHandler_REST() {}
+  virtual ~RGWHandler_REST_S3() {}
+
+  int get_errordoc(const string& errordoc_key, string* error_content);  
 
-  int validate_bucket_name(const string& bucket, bool relaxed_names);
-  using RGWHandler_ObjStore::validate_bucket_name;
-  
   virtual int init(RGWRados *store, struct req_state *s, RGWClientIO *cio);
   virtual int authorize() {
     return RGW_Auth_S3::authorize(store, s);
@@ -429,16 +474,19 @@ public:
   }
 };
 
-class RGWHandler_ObjStore_Service_S3 : public RGWHandler_ObjStore_S3 {
+class RGWHandler_REST_Service_S3 : public RGWHandler_REST_S3 {
 protected:
+    bool is_usage_op() {
+    return s->info.args.exists("usage");
+  }
   RGWOp *op_get();
   RGWOp *op_head();
 public:
-  RGWHandler_ObjStore_Service_S3() {}
-  virtual ~RGWHandler_ObjStore_Service_S3() {}
+  RGWHandler_REST_Service_S3() {}
+  virtual ~RGWHandler_REST_Service_S3() {}
 };
 
-class RGWHandler_ObjStore_Bucket_S3 : public RGWHandler_ObjStore_S3 {
+class RGWHandler_REST_Bucket_S3 : public RGWHandler_REST_S3 {
 protected:
   bool is_acl_op() {
     return s->info.args.exists("acl");
@@ -461,11 +509,11 @@ protected:
   RGWOp *op_post();
   RGWOp *op_options();
 public:
-  RGWHandler_ObjStore_Bucket_S3() {}
-  virtual ~RGWHandler_ObjStore_Bucket_S3() {}
+  RGWHandler_REST_Bucket_S3() {}
+  virtual ~RGWHandler_REST_Bucket_S3() {}
 };
 
-class RGWHandler_ObjStore_Obj_S3 : public RGWHandler_ObjStore_S3 {
+class RGWHandler_REST_Obj_S3 : public RGWHandler_REST_S3 {
 protected:
   bool is_acl_op() {
     return s->info.args.exists("acl");
@@ -485,20 +533,95 @@ protected:
   RGWOp *op_post();
   RGWOp *op_options();
 public:
-  RGWHandler_ObjStore_Obj_S3() {}
-  virtual ~RGWHandler_ObjStore_Obj_S3() {}
+  RGWHandler_REST_Obj_S3() {}
+  virtual ~RGWHandler_REST_Obj_S3() {}
 };
 
 class RGWRESTMgr_S3 : public RGWRESTMgr {
 private:
   bool enable_s3website;
 public:
-  explicit RGWRESTMgr_S3(bool enable_s3website) : enable_s3website(false) { this->enable_s3website = enable_s3website; }
+  explicit RGWRESTMgr_S3(bool _enable_s3website = false)
+    : enable_s3website(_enable_s3website)
+    {}
+
   virtual ~RGWRESTMgr_S3() {}
 
-  virtual RGWHandler *get_handler(struct req_state *s);
+  virtual RGWHandler_REST *get_handler(struct req_state *s);
 };
 
-class RGWHandler_ObjStore_Obj_S3Website;
+class RGWHandler_REST_Obj_S3Website;
+
+static inline bool looks_like_ip_address(const char *bucket)
+{
+  int num_periods = 0;
+  bool expect_period = false;
+  for (const char *b = bucket; *b; ++b) {
+    if (*b == '.') {
+      if (!expect_period)
+	return false;
+      ++num_periods;
+      if (num_periods > 3)
+	return false;
+      expect_period = false;
+    }
+    else if (isdigit(*b)) {
+      expect_period = true;
+    }
+    else {
+      return false;
+    }
+  }
+  return (num_periods == 3);
+}
+
+static inline bool valid_s3_object_name(const string& name) {
+  if (name.size() > 1024) {
+    return false;
+  }
+  if (check_utf8(name.c_str(), name.size())) {
+    return false;
+  }
+  return true;
+}
+
+static inline int valid_s3_bucket_name(const string& name, bool relaxed=false)
+{
+  // This function enforces Amazon's spec for bucket names.
+  // (The requirements, not the recommendations.)
+  int len = name.size();
+  if (len < 3) {
+    // Name too short
+    return -ERR_INVALID_BUCKET_NAME;
+  } else if (len > 255) {
+    // Name too long
+    return -ERR_INVALID_BUCKET_NAME;
+  }
+
+  // bucket names must start with a number, letter, or underscore
+  if (!(isalpha(name[0]) || isdigit(name[0]))) {
+    if (!relaxed)
+      return -ERR_INVALID_BUCKET_NAME;
+    else if (!(name[0] == '_' || name[0] == '.' || name[0] == '-'))
+      return -ERR_INVALID_BUCKET_NAME;
+  }
+
+  for (const char *s = name.c_str(); *s; ++s) {
+    char c = *s;
+    if (isdigit(c) || (c == '.'))
+      continue;
+    if (isalpha(c))
+      continue;
+    if ((c == '-') || (c == '_'))
+      continue;
+    // Invalid character
+    return -ERR_INVALID_BUCKET_NAME;
+  }
+
+  if (looks_like_ip_address(name.c_str()))
+    return -ERR_INVALID_BUCKET_NAME;
+
+  return 0;
+}
 
-#endif
+#endif /* CEPH_RGW_REST_S3_H */
diff --git a/src/rgw/rgw_rest_s3website.h b/src/rgw/rgw_rest_s3website.h
index d6cd7d8..b14942b 100644
--- a/src/rgw/rgw_rest_s3website.h
+++ b/src/rgw/rgw_rest_s3website.h
@@ -16,7 +16,7 @@
  
 #include "rgw_rest_s3.h"
 
-class RGWHandler_ObjStore_S3Website : public RGWHandler_ObjStore_S3 {
+class RGWHandler_REST_S3Website : public RGWHandler_REST_S3 {
 protected:
   int retarget(RGWOp *op, RGWOp **new_op);
   // TODO: this should be virtual I think, and ensure that it's always
@@ -32,38 +32,38 @@ protected:
   RGWOp *op_copy() { return NULL; }
   RGWOp *op_options() { return NULL; }
 
-  int get_errordoc(const string errordoc_key, string *error_content);
+  int get_errordoc(const string& errordoc_key, string *error_content);
 public:
-  RGWHandler_ObjStore_S3Website() : RGWHandler_ObjStore_S3() {}
-  virtual ~RGWHandler_ObjStore_S3Website() {}
+  RGWHandler_REST_S3Website() : RGWHandler_REST_S3() {}
+  virtual ~RGWHandler_REST_S3Website() {}
   virtual int error_handler(int err_no, string *error_content);
 };
 
-class RGWHandler_ObjStore_Service_S3Website : public RGWHandler_ObjStore_S3Website {
+class RGWHandler_REST_Service_S3Website : public RGWHandler_REST_S3Website {
 protected:
   virtual RGWOp *get_obj_op(bool get_data);
 public:
-  RGWHandler_ObjStore_Service_S3Website() {}
-  virtual ~RGWHandler_ObjStore_Service_S3Website() {}
+  RGWHandler_REST_Service_S3Website() {}
+  virtual ~RGWHandler_REST_Service_S3Website() {}
 };
 
-class RGWHandler_ObjStore_Obj_S3Website : public RGWHandler_ObjStore_S3Website {
+class RGWHandler_REST_Obj_S3Website : public RGWHandler_REST_S3Website {
 protected:
   virtual RGWOp *get_obj_op(bool get_data);
 public:
-  RGWHandler_ObjStore_Obj_S3Website() {}
-  virtual ~RGWHandler_ObjStore_Obj_S3Website() {}
+  RGWHandler_REST_Obj_S3Website() {}
+  virtual ~RGWHandler_REST_Obj_S3Website() {}
 };
 
 /* The cross-inheritance from Obj to Bucket is deliberate!
  * S3Websites do NOT support any bucket operations
  */
-class RGWHandler_ObjStore_Bucket_S3Website : public RGWHandler_ObjStore_S3Website {
+class RGWHandler_REST_Bucket_S3Website : public RGWHandler_REST_S3Website {
 protected:
   RGWOp *get_obj_op(bool get_data);
 public:
-  RGWHandler_ObjStore_Bucket_S3Website() {}
-  virtual ~RGWHandler_ObjStore_Bucket_S3Website() {}
+  RGWHandler_REST_Bucket_S3Website() {}
+  virtual ~RGWHandler_REST_Bucket_S3Website() {}
 };
 
 // TODO: do we actually need this?
diff --git a/src/rgw/rgw_rest_swift.cc b/src/rgw/rgw_rest_swift.cc
index 94d44d6..a9bf03e 100644
--- a/src/rgw/rgw_rest_swift.cc
+++ b/src/rgw/rgw_rest_swift.cc
@@ -1,8 +1,12 @@
 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
 // vim: ts=8 sw=2 smarttab
 
+#include "include/assert.h"
+
 #include "common/Formatter.h"
 #include "common/utf8.h"
+#include "common/ceph_json.h"
+
 #include "rgw_swift.h"
 #include "rgw_rest_swift.h"
 #include "rgw_acl_swift.h"
@@ -51,37 +55,39 @@ int RGWListBuckets_ObjStore_SWIFT::get_params()
 }
 
 static void dump_account_metadata(struct req_state * const s,
-                                  const uint32_t buckets_count,
-                                  const uint64_t buckets_object_count,
-                                  const uint64_t buckets_size,
-                                  const uint64_t buckets_size_rounded,
-                                  map<string, bufferlist>& attrs)
+				  const uint32_t buckets_count,
+				  const uint64_t buckets_object_count,
+				  const uint64_t buckets_size,
+				  const uint64_t buckets_size_rounded,
+				  map<string, bufferlist>& attrs)
 {
   char buf[32];
   utime_t now = ceph_clock_now(g_ceph_context);
   snprintf(buf, sizeof(buf), "%0.5f", (double)now);
   /* Adding X-Timestamp to keep align with Swift API */
-  s->cio->print("X-Timestamp: %s\r\n", buf);
+  STREAM_IO(s)->print("X-Timestamp: %s\r\n", buf);
   snprintf(buf, sizeof(buf), "%lld", (long long)buckets_count);
-  s->cio->print("X-Account-Container-Count: %s\r\n", buf);
+  STREAM_IO(s)->print("X-Account-Container-Count: %s\r\n", buf);
   snprintf(buf, sizeof(buf), "%lld", (long long)buckets_object_count);
-  s->cio->print("X-Account-Object-Count: %s\r\n", buf);
+  STREAM_IO(s)->print("X-Account-Object-Count: %s\r\n", buf);
   snprintf(buf, sizeof(buf), "%lld", (long long)buckets_size);
-  s->cio->print("X-Account-Bytes-Used: %s\r\n", buf);
+  STREAM_IO(s)->print("X-Account-Bytes-Used: %s\r\n", buf);
   snprintf(buf, sizeof(buf), "%lld", (long long)buckets_size_rounded);
-  s->cio->print("X-Account-Bytes-Used-Actual: %s\r\n", buf);
+  STREAM_IO(s)->print("X-Account-Bytes-Used-Actual: %s\r\n", buf);
 
   /* Dump TempURL-related stuff */
   if (s->perm_mask == RGW_PERM_FULL_CONTROL) {
     map<int, string>::iterator iter;
-    iter = s->user.temp_url_keys.find(0);
-    if (iter != s->user.temp_url_keys.end() && !iter->second.empty()) {
-      s->cio->print("X-Account-Meta-Temp-Url-Key: %s\r\n", iter->second.c_str());
+    iter = s->user->temp_url_keys.find(0);
+    if (iter != s->user->temp_url_keys.end() && !iter->second.empty()) {
+      STREAM_IO(s)->print("X-Account-Meta-Temp-Url-Key: %s\r\n",
+			  iter->second.c_str());
     }
 
-    iter = s->user.temp_url_keys.find(1);
-    if (iter != s->user.temp_url_keys.end() && !iter->second.empty()) {
-      s->cio->print("X-Account-Meta-Temp-Url-Key-2: %s\r\n", iter->second.c_str());
+    iter = s->user->temp_url_keys.find(1);
+    if (iter != s->user->temp_url_keys.end() && !iter->second.empty()) {
+      STREAM_IO(s)->print("X-Account-Meta-Temp-Url-Key-2: %s\r\n",
+			  iter->second.c_str());
     }
   }
 
@@ -93,9 +99,11 @@ static void dump_account_metadata(struct req_state * const s,
     map<string, string>::const_iterator geniter = rgw_to_http_attrs.find(name);
 
     if (geniter != rgw_to_http_attrs.end()) {
-      s->cio->print("%s: %s\r\n", geniter->second.c_str(), iter->second.c_str());
+      STREAM_IO(s)->print("%s: %s\r\n", geniter->second.c_str(),
+			  iter->second.c_str());
     } else if (strncmp(name, RGW_ATTR_META_PREFIX, PREFIX_LEN) == 0) {
-      s->cio->print("X-Account-Meta-%s: %s\r\n", name + PREFIX_LEN, iter->second.c_str());
+      STREAM_IO(s)->print("X-Account-Meta-%s: %s\r\n", name + PREFIX_LEN,
+			  iter->second.c_str());
     }
   }
 }
@@ -124,7 +132,7 @@ void RGWListBuckets_ObjStore_SWIFT::send_response_begin(bool has_buckets)
   if (! op_ret) {
     dump_start(s);
     s->formatter->open_array_section_with_attrs("account",
-            FormatterAttrs("name", s->user.display_name.c_str(), NULL));
+            FormatterAttrs("name", s->user->display_name.c_str(), NULL));
 
     sent_data = true;
   }
@@ -264,8 +272,7 @@ void RGWListBucket_ObjStore_SWIFT::send_response()
         }
         s->formatter->dump_string("content_type", single_content_type);
       }
-      time_t mtime = iter->mtime.sec();
-      dump_time(s, "last_modified", &mtime);
+      dump_time(s, "last_modified", &iter->mtime);
       s->formatter->close_section();
     }
 
@@ -319,27 +326,31 @@ static void dump_container_metadata(struct req_state *s, RGWBucketEnt& bucket)
 {
   char buf[32];
   /* Adding X-Timestamp to keep align with Swift API */
-  snprintf(buf, sizeof(buf), "%lld.00000", (long long)s->bucket_info.creation_time);
-  s->cio->print("X-Timestamp: %s\r\n", buf);
+  utime_t ut(s->bucket_info.creation_time);
+  snprintf(buf, sizeof(buf), "%lld.%05d",
+	   (long long)ut.sec(), (int)(ut.usec() / 10));
+  STREAM_IO(s)->print("X-Timestamp: %s\r\n", buf);
   snprintf(buf, sizeof(buf), "%lld", (long long)bucket.count);
-  s->cio->print("X-Container-Object-Count: %s\r\n", buf);
+  STREAM_IO(s)->print("X-Container-Object-Count: %s\r\n", buf);
   snprintf(buf, sizeof(buf), "%lld", (long long)bucket.size);
-  s->cio->print("X-Container-Bytes-Used: %s\r\n", buf);
+  STREAM_IO(s)->print("X-Container-Bytes-Used: %s\r\n", buf);
   snprintf(buf, sizeof(buf), "%lld", (long long)bucket.size_rounded);
-  s->cio->print("X-Container-Bytes-Used-Actual: %s\r\n", buf);
+  STREAM_IO(s)->print("X-Container-Bytes-Used-Actual: %s\r\n", buf);
 
   if (s->object.empty()) {
-    RGWAccessControlPolicy_SWIFT *swift_policy = static_cast<RGWAccessControlPolicy_SWIFT *>(s->bucket_acl);
+    RGWAccessControlPolicy_SWIFT *swift_policy
+      = static_cast<RGWAccessControlPolicy_SWIFT *>(s->bucket_acl);
     string read_acl, write_acl;
     swift_policy->to_str(read_acl, write_acl);
     if (read_acl.size()) {
-      s->cio->print("X-Container-Read: %s\r\n", read_acl.c_str());
+      STREAM_IO(s)->print("X-Container-Read: %s\r\n", read_acl.c_str());
     }
     if (write_acl.size()) {
-      s->cio->print("X-Container-Write: %s\r\n", write_acl.c_str());
+      STREAM_IO(s)->print("X-Container-Write: %s\r\n", write_acl.c_str());
     }
     if (!s->bucket_info.placement_rule.empty()) {
-      s->cio->print("X-Storage-Policy: %s\r\n", s->bucket_info.placement_rule.c_str());
+      STREAM_IO(s)->print("X-Storage-Policy: %s\r\n",
+			  s->bucket_info.placement_rule.c_str());
     }
 
     /* Dump user-defined metadata items and generic attrs. */
@@ -352,26 +363,36 @@ static void dump_container_metadata(struct req_state *s, RGWBucketEnt& bucket)
       map<string, string>::const_iterator geniter = rgw_to_http_attrs.find(name);
 
       if (geniter != rgw_to_http_attrs.end()) {
-        s->cio->print("%s: %s\r\n", geniter->second.c_str(), iter->second.c_str());
+        STREAM_IO(s)->print("%s: %s\r\n", geniter->second.c_str(),
+			    iter->second.c_str());
       } else if (strncmp(name, RGW_ATTR_META_PREFIX, PREFIX_LEN) == 0) {
-        s->cio->print("X-Container-Meta-%s: %s\r\n", name + PREFIX_LEN, iter->second.c_str());
+        STREAM_IO(s)->print("X-Container-Meta-%s: %s\r\n", name + PREFIX_LEN,
+			    iter->second.c_str());
       }
     }
   }
+
+  /* Dump container versioning info. */
+  if (!s->bucket_info.swift_ver_location.empty()) {
+    string encoded_loc;
+    url_encode(s->bucket_info.swift_ver_location, encoded_loc);
+    STREAM_IO(s)->print("X-Versions-Location: %s\r\n", encoded_loc.c_str());
+  }
+
 }
 
 void RGWStatAccount_ObjStore_SWIFT::execute()
 {
   RGWStatAccount_ObjStore::execute();
-
-  op_ret = rgw_get_user_attrs_by_uid(store, s->user.user_id, attrs);
+  op_ret = rgw_get_user_attrs_by_uid(store, s->user->user_id, attrs);
 }
 
 void RGWStatAccount_ObjStore_SWIFT::send_response()
 {
   if (op_ret >= 0) {
     op_ret = STATUS_NO_CONTENT;
-    dump_account_metadata(s, buckets_count, buckets_objcount, buckets_size, buckets_size_rounded, attrs);
+    dump_account_metadata(s, buckets_count, buckets_objcount, buckets_size,
+			  buckets_size_rounded, attrs);
   }
 
   set_req_state_err(s, op_ret);
@@ -414,7 +435,7 @@ static int get_swift_container_settings(req_state *s, RGWRados *store, RGWAccess
 
   if (read_attr || write_attr) {
     RGWAccessControlPolicy_SWIFT swift_policy(s->cct);
-    int r = swift_policy.create(store, s->user.user_id, s->user.display_name, read_list, write_list);
+    int r = swift_policy.create(store, s->user->user_id, s->user->display_name, read_list, write_list);
     if (r < 0)
       return r;
 
@@ -446,6 +467,42 @@ static int get_swift_container_settings(req_state *s, RGWRados *store, RGWAccess
   return 0;
 }
 
+#define ACCT_REMOVE_ATTR_PREFIX     "HTTP_X_REMOVE_ACCOUNT_META_"
+#define ACCT_PUT_ATTR_PREFIX        "HTTP_X_ACCOUNT_META_"
+#define CONT_REMOVE_ATTR_PREFIX     "HTTP_X_REMOVE_CONTAINER_META_"
+#define CONT_PUT_ATTR_PREFIX        "HTTP_X_CONTAINER_META_"
+
+static void get_rmattrs_from_headers(const req_state * const s,
+				     const char * const put_prefix,
+				     const char * const del_prefix,
+				     set<string>& rmattr_names)
+{
+  map<string, string, ltstr_nocase>& m = s->info.env->get_map();
+  map<string, string, ltstr_nocase>::const_iterator iter;
+  const size_t put_prefix_len = strlen(put_prefix);
+  const size_t del_prefix_len = strlen(del_prefix);
+
+  for (iter = m.begin(); iter != m.end(); ++iter) {
+    size_t prefix_len = 0;
+    const char * const p = iter->first.c_str();
+
+    if (strncasecmp(p, del_prefix, del_prefix_len) == 0) {
+      /* Explicitly requested removal. */
+      prefix_len = del_prefix_len;
+    } else if ((strncasecmp(p, put_prefix, put_prefix_len) == 0)
+	       && iter->second.empty()) {
+      /* Removal requested by putting an empty value. */
+      prefix_len = put_prefix_len;
+    }
+
+    if (prefix_len > 0) {
+      string name(RGW_ATTR_META_PREFIX);
+      name.append(lowercase_dash_http_attr(p + prefix_len));
+      rmattr_names.insert(name);
+    }
+  }
+}
+
 int RGWCreateBucket_ObjStore_SWIFT::get_params()
 {
   bool has_policy;
@@ -456,12 +513,18 @@ int RGWCreateBucket_ObjStore_SWIFT::get_params()
   }
 
   if (!has_policy) {
-    policy.create_default(s->user.user_id, s->user.display_name);
+    policy.create_default(s->user->user_id, s->user->display_name);
   }
 
-  location_constraint = store->region.api_name;
+  location_constraint = store->get_zonegroup().api_name;
+  get_rmattrs_from_headers(s, CONT_PUT_ATTR_PREFIX,
+                           CONT_REMOVE_ATTR_PREFIX, rmattr_names);
   placement_rule = s->info.env->get("HTTP_X_STORAGE_POLICY", "");
 
+  if (s->cct->_conf->rgw_swift_versioning_enabled) {
+    swift_ver_location = s->info.env->get("HTTP_X_VERSIONS_LOCATION", "");
+  }
+
   return 0;
 }
 
@@ -490,10 +553,10 @@ void RGWDeleteBucket_ObjStore_SWIFT::send_response()
   rgw_flush_formatter_and_reset(s, s->formatter);
 }
 
-static int get_delete_at_param(req_state *s, time_t *delete_at)
+static int get_delete_at_param(req_state *s, real_time *delete_at)
 {
   /* Handle Swift object expiration. */
-  utime_t delat_proposal;
+  real_time delat_proposal;
   string x_delete = s->info.env->get("HTTP_X_DELETE_AFTER", "");
 
   if (x_delete.empty()) {
@@ -501,7 +564,7 @@ static int get_delete_at_param(req_state *s, time_t *delete_at)
   } else {
     /* X-Delete-After HTTP is present. It means we need add its value
      * to the current time. */
-    delat_proposal = ceph_clock_now(g_ceph_context);
+    delat_proposal = real_clock::now();
   }
 
   if (x_delete.empty()) {
@@ -514,12 +577,12 @@ static int get_delete_at_param(req_state *s, time_t *delete_at)
     return -EINVAL;
   }
 
-  delat_proposal += utime_t(ts, 0);
-  if (delat_proposal < ceph_clock_now(g_ceph_context)) {
+  delat_proposal += make_timespan(ts);
+  if (delat_proposal < real_clock::now()) {
     return -EINVAL;
   }
 
-  *delete_at = delat_proposal.sec();
+  *delete_at = delat_proposal;
 
   return 0;
 }
@@ -548,16 +611,16 @@ int RGWPutObj_ObjStore_SWIFT::get_params()
     if (suffix) {
       suffix++;
       if (*suffix) {
-        string suffix_str(suffix);
+	string suffix_str(suffix);
 	const char *mime = rgw_find_mime_by_ext(suffix_str);
 	if (mime) {
-          s->generic_attrs[RGW_ATTR_CONTENT_TYPE] = mime;
+	  s->generic_attrs[RGW_ATTR_CONTENT_TYPE] = mime;
 	}
       }
     }
   }
 
-  policy.create_default(s->user.user_id, s->user.display_name);
+  policy.create_default(s->user->user_id, s->user->display_name);
 
   int r = get_delete_at_param(s, &delete_at);
   if (r < 0) {
@@ -590,11 +653,19 @@ int RGWPutObj_ObjStore_SWIFT::get_params()
       return -EINVAL;
     }
 
+    MD5 etag_sum;
     uint64_t total_size = 0;
-    for (vector<rgw_slo_entry>::iterator iter = slo_info->entries.begin(); iter != slo_info->entries.end(); ++iter) {
-      total_size += iter->size_bytes;
-      ldout(s->cct, 20) << "slo_part: " << iter->path << " size=" << iter->size_bytes << dendl;
+    for (const auto& entry : slo_info->entries) {
+      etag_sum.Update((const byte *)entry.etag.c_str(),
+                      entry.etag.length());
+      total_size += entry.size_bytes;
+
+      ldout(s->cct, 20) << "slo_part: " << entry.path
+                        << " size=" << entry.size_bytes
+                        << " etag=" << entry.etag
+                        << dendl;
     }
+    complete_etag(etag_sum, &lo_etag);
     slo_info->total_size = total_size;
 
     ofs = slo_info->raw_data_len;
@@ -605,9 +676,24 @@ int RGWPutObj_ObjStore_SWIFT::get_params()
 
 void RGWPutObj_ObjStore_SWIFT::send_response()
 {
-  if (! op_ret)
+  if (! op_ret) {
     op_ret = STATUS_CREATED;
-  dump_etag(s, etag.c_str());
+  }
+
+  if (!lo_etag.empty()) {
+    /* Static Large Object of Swift API has two etags represented by
+     * following members:
+     *  - etag - for the manifest itself (it will be stored in xattrs),
+     *  - lo_etag - for the content composited from SLO's segments.
+     *    The value is calculated basing on segments' etags.
+     * In response for PUT request we have to expose the second one.
+     * The first one may be obtained by GET with "multipart-manifest=get"
+     * in query string on a given SLO. */
+    dump_etag(s, ("\"" + lo_etag + "\"").c_str());
+  } else {
+    dump_etag(s, etag.c_str());
+  }
+
   dump_last_modified(s, mtime);
   set_req_state_err(s, op_ret);
   dump_errno(s);
@@ -615,49 +701,14 @@ void RGWPutObj_ObjStore_SWIFT::send_response()
   rgw_flush_formatter_and_reset(s, s->formatter);
 }
 
-#define ACCT_REMOVE_ATTR_PREFIX     "HTTP_X_REMOVE_ACCOUNT_META_"
-#define ACCT_PUT_ATTR_PREFIX        "HTTP_X_ACCOUNT_META_"
-#define CONT_REMOVE_ATTR_PREFIX     "HTTP_X_REMOVE_CONTAINER_META_"
-#define CONT_PUT_ATTR_PREFIX        "HTTP_X_CONTAINER_META_"
-
-static void get_rmattrs_from_headers(const req_state * const s,
-                                     const char * const put_prefix,
-                                     const char * const del_prefix,
-                                     set<string>& rmattr_names)
-{
-  map<string, string, ltstr_nocase>& m = s->info.env->get_map();
-  map<string, string, ltstr_nocase>::const_iterator iter;
-  const size_t put_prefix_len = strlen(put_prefix);
-  const size_t del_prefix_len = strlen(del_prefix);
-
-  for (iter = m.begin(); iter != m.end(); ++iter) {
-    size_t prefix_len = 0;
-    const char * const p = iter->first.c_str();
-
-    if (strncasecmp(p, del_prefix, del_prefix_len) == 0) {
-      /* Explicitly requested removal. */
-      prefix_len = del_prefix_len;
-    } else if ((strncasecmp(p, put_prefix, put_prefix_len) == 0)
-        && iter->second.empty()) {
-      /* Removal requested by putting an empty value. */
-      prefix_len = put_prefix_len;
-    }
-
-    if (prefix_len > 0) {
-      string name(RGW_ATTR_META_PREFIX);
-      name.append(lowercase_dash_http_attr(p + prefix_len));
-      rmattr_names.insert(name);
-    }
-  }
-}
-
 int RGWPutMetadataAccount_ObjStore_SWIFT::get_params()
 {
   if (s->has_bad_meta) {
     return -EINVAL;
   }
 
-  get_rmattrs_from_headers(s, ACCT_PUT_ATTR_PREFIX, ACCT_REMOVE_ATTR_PREFIX, rmattr_names);
+  get_rmattrs_from_headers(s, ACCT_PUT_ATTR_PREFIX, ACCT_REMOVE_ATTR_PREFIX,
+			   rmattr_names);
   return 0;
 }
 
@@ -678,13 +729,19 @@ int RGWPutMetadataBucket_ObjStore_SWIFT::get_params()
     return -EINVAL;
   }
 
-  int r = get_swift_container_settings(s, store, &policy, &has_policy, &cors_config, &has_cors);
+  int r = get_swift_container_settings(s, store, &policy, &has_policy,
+				       &cors_config, &has_cors);
   if (r < 0) {
     return r;
   }
 
-  get_rmattrs_from_headers(s, CONT_PUT_ATTR_PREFIX, CONT_REMOVE_ATTR_PREFIX, rmattr_names);
+  get_rmattrs_from_headers(s, CONT_PUT_ATTR_PREFIX, CONT_REMOVE_ATTR_PREFIX,
+			   rmattr_names);
   placement_rule = s->info.env->get("HTTP_X_STORAGE_POLICY", "");
+
+  if (s->cct->_conf->rgw_swift_versioning_enabled) {
+    swift_ver_location = s->info.env->get("HTTP_X_VERSIONS_LOCATION", "");
+  }
   return 0;
 }
 
@@ -807,9 +864,11 @@ void RGWDeleteObj_ObjStore_SWIFT::send_response()
 
   set_req_state_err(s, r);
   dump_errno(s);
-  end_header(s, this);
 
   if (multipart_delete) {
+    end_header(s, this /* RGWOp */, nullptr /* contype */,
+               NO_CONTENT_LENGTH);
+
     if (deleter) {
       bulkdelete_respond(deleter->get_num_deleted(),
                          deleter->get_num_unfound(),
@@ -829,6 +888,8 @@ void RGWDeleteObj_ObjStore_SWIFT::send_response()
 
       bulkdelete_respond(0, 0, { fail_desc }, s->prot_flags, *s->formatter);
     }
+  } else {
+    end_header(s, this);
   }
 
   rgw_flush_formatter_and_reset(s, s->formatter);
@@ -836,7 +897,7 @@ void RGWDeleteObj_ObjStore_SWIFT::send_response()
 }
 
 static void get_contype_from_attrs(map<string, bufferlist>& attrs,
-                                   string& content_type)
+				   string& content_type)
 {
   map<string, bufferlist>::iterator iter = attrs.find(RGW_ATTR_CONTENT_TYPE);
   if (iter != attrs.end()) {
@@ -845,43 +906,59 @@ static void get_contype_from_attrs(map<string, bufferlist>& attrs,
 }
 
 static void dump_object_metadata(struct req_state * const s,
-                                 map<string, bufferlist> attrs)
+				 map<string, bufferlist> attrs)
 {
   map<string, string> response_attrs;
-  map<string, string>::const_iterator riter;
-  map<string, bufferlist>::iterator iter;
 
-  for (iter = attrs.begin(); iter != attrs.end(); ++iter) {
-    const char *name = iter->first.c_str();
-    map<string, string>::const_iterator aiter = rgw_to_http_attrs.find(name);
+  for (auto kv : attrs) {
+    const char * name = kv.first.c_str();
+    const auto aiter = rgw_to_http_attrs.find(name);
 
-    if (aiter != rgw_to_http_attrs.end()) {
-      response_attrs[aiter->second] = iter->second.c_str();
-    } else if (strncmp(name, RGW_ATTR_META_PREFIX, sizeof(RGW_ATTR_META_PREFIX)-1) == 0) {
+    if (aiter != std::end(rgw_to_http_attrs)) {
+      response_attrs[aiter->second] = kv.second.c_str();
+    } else if (strncmp(name, RGW_ATTR_META_PREFIX,
+		       sizeof(RGW_ATTR_META_PREFIX)-1) == 0) {
       name += sizeof(RGW_ATTR_META_PREFIX) - 1;
-      s->cio->print("X-Object-Meta-%s: %s\r\n", name, iter->second.c_str());
+      STREAM_IO(s)->print("X-Object-Meta-%s: %s\r\n", name,
+                          kv.second.c_str());
+    }
+  }
+
+  /* Handle override and fallback for Content-Disposition HTTP header.
+   * At the moment this will be used only by TempURL of the Swift API. */
+  const auto cditer = rgw_to_http_attrs.find(RGW_ATTR_CONTENT_DISP);
+  if (cditer != std::end(rgw_to_http_attrs)) {
+    const auto& name = cditer->second;
+
+    if (!s->content_disp.override.empty()) {
+      response_attrs[name] = s->content_disp.override;
+    } else if (!s->content_disp.fallback.empty()
+        && response_attrs.find(name) == std::end(response_attrs)) {
+      response_attrs[name] = s->content_disp.fallback;
     }
   }
 
-  for (riter = response_attrs.begin(); riter != response_attrs.end(); ++riter) {
-    s->cio->print("%s: %s\r\n", riter->first.c_str(), riter->second.c_str());
+  for (const auto kv : response_attrs) {
+    STREAM_IO(s)->print("%s: %s\r\n", kv.first.c_str(), kv.second.c_str());
   }
 
-  iter = attrs.find(RGW_ATTR_DELETE_AT);
-  if (iter != attrs.end()) {
+  const auto iter = attrs.find(RGW_ATTR_DELETE_AT);
+  if (iter != std::end(attrs)) {
     utime_t delete_at;
     try {
       ::decode(delete_at, iter->second);
-      s->cio->print("X-Delete-At: %lu\r\n", delete_at.sec());
+      STREAM_IO(s)->print("X-Delete-At: %lu\r\n", delete_at.sec());
     } catch (buffer::error& err) {
-      dout(0) << "ERROR: cannot decode object's " RGW_ATTR_DELETE_AT " attr, ignoring" << dendl;
+      ldout(s->cct, 0) << "ERROR: cannot decode object's " RGW_ATTR_DELETE_AT
+                          " attr, ignoring"
+                       << dendl;
     }
   }
 }
 
 int RGWCopyObj_ObjStore_SWIFT::init_dest_policy()
 {
-  dest_policy.create_default(s->user.user_id, s->user.display_name);
+  dest_policy.create_default(s->user->user_id, s->user->display_name);
 
   return 0;
 }
@@ -944,12 +1021,13 @@ void RGWCopyObj_ObjStore_SWIFT::dump_copy_info()
   string objname, bucketname;
   url_encode(src_object.name, objname);
   url_encode(src_bucket.name, bucketname);
-  s->cio->print("X-Copied-From: %s/%s\r\n", bucketname.c_str(), objname.c_str());
+  STREAM_IO(s)->print("X-Copied-From: %s/%s\r\n", bucketname.c_str(),
+		      objname.c_str());
 
   /* Dump X-Copied-From-Account */
   string account_name;
-  url_encode(s->user.user_id.id, account_name); // XXX tenant
-  s->cio->print("X-Copied-From-Account: %s\r\n", account_name.c_str());
+  url_encode(s->user->user_id.id, account_name); // XXX tenant
+  STREAM_IO(s)->print("X-Copied-From-Account: %s\r\n", account_name.c_str());
 
   /* Dump X-Copied-From-Last-Modified. */
   dump_time_header(s, "X-Copied-From-Last-Modified", src_mtime);
@@ -968,7 +1046,8 @@ void RGWCopyObj_ObjStore_SWIFT::send_response()
     dump_copy_info();
     get_contype_from_attrs(attrs, content_type);
     dump_object_metadata(s, attrs);
-    end_header(s, this, !content_type.empty() ? content_type.c_str() : "binary/octet-stream");
+    end_header(s, this, !content_type.empty() ? content_type.c_str()
+	       : "binary/octet-stream");
   } else {
     s->formatter->close_section();
     rgw_flush_formatter(s, s->formatter);
@@ -989,7 +1068,9 @@ int RGWGetObj_ObjStore_SWIFT::send_response_data_error()
   return send_response_data(bl, 0, 0);
 }
 
-int RGWGetObj_ObjStore_SWIFT::send_response_data(bufferlist& bl, off_t bl_ofs, off_t bl_len)
+int RGWGetObj_ObjStore_SWIFT::send_response_data(bufferlist& bl,
+                                                 const off_t bl_ofs,
+                                                 const off_t bl_len)
 {
   string content_type;
 
@@ -997,8 +1078,8 @@ int RGWGetObj_ObjStore_SWIFT::send_response_data(bufferlist& bl, off_t bl_ofs, o
     goto send_data;
   }
 
-  set_req_state_err(s, (partial_content && !op_ret) ? STATUS_PARTIAL_CONTENT :
-		    op_ret);
+  set_req_state_err(s, (partial_content && !op_ret) ? STATUS_PARTIAL_CONTENT
+		    : op_ret);
   dump_errno(s);
   if (s->err.is_err()) {
     end_header(s, NULL);
@@ -1011,18 +1092,25 @@ int RGWGetObj_ObjStore_SWIFT::send_response_data(bufferlist& bl, off_t bl_ofs, o
 
   dump_content_length(s, total_len);
   dump_last_modified(s, lastmod);
-  s->cio->print("X-Timestamp: %lld.00000\r\n", (long long)lastmod);
+  {
+    utime_t ut(lastmod);
+    STREAM_IO(s)->print("X-Timestamp: %lld.%05d\r\n", (long long)ut.sec(), (int)(ut.usec() / 10));
+  }
   if (is_slo) {
-    s->cio->print("X-Static-Large-Object: True\r\n");
+    STREAM_IO(s)->print("X-Static-Large-Object: True\r\n");
   }
 
   if (! op_ret) {
-    map<string, bufferlist>::iterator iter = attrs.find(RGW_ATTR_ETAG);
-    if (iter != attrs.end()) {
-      bufferlist& bl = iter->second;
-      if (bl.length()) {
-        char *etag = bl.c_str();
-        dump_etag(s, etag);
+    if (!lo_etag.empty()) {
+      dump_etag(s, ("\"" + lo_etag + "\"").c_str());
+    } else {
+      auto iter = attrs.find(RGW_ATTR_ETAG);
+      if (iter != attrs.end()) {
+        bufferlist& bl = iter->second;
+        if (bl.length()) {
+          char *etag = bl.c_str();
+          dump_etag(s, etag);
+        }
       }
     }
 
@@ -1030,13 +1118,14 @@ int RGWGetObj_ObjStore_SWIFT::send_response_data(bufferlist& bl, off_t bl_ofs, o
     dump_object_metadata(s, attrs);
   }
 
-  end_header(s, this, !content_type.empty() ? content_type.c_str() : "binary/octet-stream");
+  end_header(s, this, !content_type.empty() ? content_type.c_str()
+	     : "binary/octet-stream");
 
   sent_header = true;
 
 send_data:
   if (get_data && !op_ret) {
-    int r = s->cio->write(bl.c_str() + bl_ofs, bl_len);
+    int r = STREAM_IO(s)->write(bl.c_str() + bl_ofs, bl_len);
     if (r < 0)
       return r;
   }
@@ -1062,16 +1151,18 @@ void RGWOptionsCORS_ObjStore_SWIFT::send_response()
   }
   get_response_params(hdrs, exp_hdrs, &max_age);
   dump_errno(s);
-  dump_access_control(s, origin, req_meth, hdrs.c_str(), exp_hdrs.c_str(), max_age);
+  dump_access_control(s, origin, req_meth, hdrs.c_str(), exp_hdrs.c_str(),
+		      max_age);
   end_header(s, NULL);
 }
 
-int RGWBulkDelete_ObjStore_SWIFT::get_data(list<RGWBulkDelete::acct_path_t>& items,
-                                           bool * const is_truncated)
+int RGWBulkDelete_ObjStore_SWIFT::get_data(
+  list<RGWBulkDelete::acct_path_t>& items, bool * const is_truncated)
 {
-  const size_t MAX_LINE_SIZE = 2048;
+  constexpr size_t MAX_LINE_SIZE = 2048;
 
-  RGWClientIOStreamBuf ciosb(*s->cio, (size_t)s->cct->_conf->rgw_max_chunk_size);
+  RGWClientIOStreamBuf ciosb(static_cast<RGWStreamIO&>(*(s->cio)),
+			     std::size_t(s->cct->_conf->rgw_max_chunk_size));
   istream cioin(&ciosb);
 
   char buf[MAX_LINE_SIZE];
@@ -1122,17 +1213,17 @@ void RGWBulkDelete_ObjStore_SWIFT::send_response()
   rgw_flush_formatter_and_reset(s, s->formatter);
 }
 
-RGWOp *RGWHandler_ObjStore_Service_SWIFT::op_get()
+RGWOp *RGWHandler_REST_Service_SWIFT::op_get()
 {
   return new RGWListBuckets_ObjStore_SWIFT;
 }
 
-RGWOp *RGWHandler_ObjStore_Service_SWIFT::op_head()
+RGWOp *RGWHandler_REST_Service_SWIFT::op_head()
 {
   return new RGWStatAccount_ObjStore_SWIFT;
 }
 
-RGWOp *RGWHandler_ObjStore_Service_SWIFT::op_post()
+RGWOp *RGWHandler_REST_Service_SWIFT::op_post()
 {
   if (s->info.args.exists("bulk-delete")) {
     return new RGWBulkDelete_ObjStore_SWIFT;
@@ -1140,7 +1231,7 @@ RGWOp *RGWHandler_ObjStore_Service_SWIFT::op_post()
   return new RGWPutMetadataAccount_ObjStore_SWIFT;
 }
 
-RGWOp *RGWHandler_ObjStore_Service_SWIFT::op_delete()
+RGWOp *RGWHandler_REST_Service_SWIFT::op_delete()
 {
   if (s->info.args.exists("bulk-delete")) {
     return new RGWBulkDelete_ObjStore_SWIFT;
@@ -1148,7 +1239,7 @@ RGWOp *RGWHandler_ObjStore_Service_SWIFT::op_delete()
   return NULL;
 }
 
-RGWOp *RGWHandler_ObjStore_Bucket_SWIFT::get_obj_op(bool get_data)
+RGWOp *RGWHandler_REST_Bucket_SWIFT::get_obj_op(bool get_data)
 {
   if (is_acl_op()) {
     return new RGWGetACLs_ObjStore_SWIFT;
@@ -1160,7 +1251,7 @@ RGWOp *RGWHandler_ObjStore_Bucket_SWIFT::get_obj_op(bool get_data)
     return new RGWStatBucket_ObjStore_SWIFT;
 }
 
-RGWOp *RGWHandler_ObjStore_Bucket_SWIFT::op_get()
+RGWOp *RGWHandler_REST_Bucket_SWIFT::op_get()
 {
   if (is_acl_op()) {
     return new RGWGetACLs_ObjStore_SWIFT;
@@ -1168,7 +1259,7 @@ RGWOp *RGWHandler_ObjStore_Bucket_SWIFT::op_get()
   return get_obj_op(true);
 }
 
-RGWOp *RGWHandler_ObjStore_Bucket_SWIFT::op_head()
+RGWOp *RGWHandler_REST_Bucket_SWIFT::op_head()
 {
   if (is_acl_op()) {
     return new RGWGetACLs_ObjStore_SWIFT;
@@ -1176,7 +1267,7 @@ RGWOp *RGWHandler_ObjStore_Bucket_SWIFT::op_head()
   return get_obj_op(false);
 }
 
-RGWOp *RGWHandler_ObjStore_Bucket_SWIFT::op_put()
+RGWOp *RGWHandler_REST_Bucket_SWIFT::op_put()
 {
   if (is_acl_op()) {
     return new RGWPutACLs_ObjStore_SWIFT;
@@ -1184,22 +1275,22 @@ RGWOp *RGWHandler_ObjStore_Bucket_SWIFT::op_put()
   return new RGWCreateBucket_ObjStore_SWIFT;
 }
 
-RGWOp *RGWHandler_ObjStore_Bucket_SWIFT::op_delete()
+RGWOp *RGWHandler_REST_Bucket_SWIFT::op_delete()
 {
   return new RGWDeleteBucket_ObjStore_SWIFT;
 }
 
-RGWOp *RGWHandler_ObjStore_Bucket_SWIFT::op_post()
+RGWOp *RGWHandler_REST_Bucket_SWIFT::op_post()
 {
   return new RGWPutMetadataBucket_ObjStore_SWIFT;
 }
 
-RGWOp *RGWHandler_ObjStore_Bucket_SWIFT::op_options()
+RGWOp *RGWHandler_REST_Bucket_SWIFT::op_options()
 {
   return new RGWOptionsCORS_ObjStore_SWIFT;
 }
 
-RGWOp *RGWHandler_ObjStore_Obj_SWIFT::get_obj_op(bool get_data)
+RGWOp *RGWHandler_REST_Obj_SWIFT::get_obj_op(bool get_data)
 {
   if (is_acl_op()) {
     return new RGWGetACLs_ObjStore_SWIFT;
@@ -1210,7 +1301,7 @@ RGWOp *RGWHandler_ObjStore_Obj_SWIFT::get_obj_op(bool get_data)
   return get_obj_op;
 }
 
-RGWOp *RGWHandler_ObjStore_Obj_SWIFT::op_get()
+RGWOp *RGWHandler_REST_Obj_SWIFT::op_get()
 {
   if (is_acl_op()) {
     return new RGWGetACLs_ObjStore_SWIFT;
@@ -1218,7 +1309,7 @@ RGWOp *RGWHandler_ObjStore_Obj_SWIFT::op_get()
   return get_obj_op(true);
 }
 
-RGWOp *RGWHandler_ObjStore_Obj_SWIFT::op_head()
+RGWOp *RGWHandler_REST_Obj_SWIFT::op_head()
 {
   if (is_acl_op()) {
     return new RGWGetACLs_ObjStore_SWIFT;
@@ -1226,7 +1317,7 @@ RGWOp *RGWHandler_ObjStore_Obj_SWIFT::op_head()
   return get_obj_op(false);
 }
 
-RGWOp *RGWHandler_ObjStore_Obj_SWIFT::op_put()
+RGWOp *RGWHandler_REST_Obj_SWIFT::op_put()
 {
   if (is_acl_op()) {
     return new RGWPutACLs_ObjStore_SWIFT;
@@ -1237,32 +1328,32 @@ RGWOp *RGWHandler_ObjStore_Obj_SWIFT::op_put()
     return new RGWCopyObj_ObjStore_SWIFT;
 }
 
-RGWOp *RGWHandler_ObjStore_Obj_SWIFT::op_delete()
+RGWOp *RGWHandler_REST_Obj_SWIFT::op_delete()
 {
   return new RGWDeleteObj_ObjStore_SWIFT;
 }
 
-RGWOp *RGWHandler_ObjStore_Obj_SWIFT::op_post()
+RGWOp *RGWHandler_REST_Obj_SWIFT::op_post()
 {
   return new RGWPutMetadataObject_ObjStore_SWIFT;
 }
 
-RGWOp *RGWHandler_ObjStore_Obj_SWIFT::op_copy()
+RGWOp *RGWHandler_REST_Obj_SWIFT::op_copy()
 {
   return new RGWCopyObj_ObjStore_SWIFT;
 }
 
-RGWOp *RGWHandler_ObjStore_Obj_SWIFT::op_options()
+RGWOp *RGWHandler_REST_Obj_SWIFT::op_options()
 {
   return new RGWOptionsCORS_ObjStore_SWIFT;
 }
 
-int RGWHandler_ObjStore_SWIFT::authorize()
+int RGWHandler_REST_SWIFT::authorize()
 {
   if ((!s->os_auth_token && s->info.args.get("temp_url_sig").empty()) ||
       (s->op == OP_OPTIONS)) {
     /* anonymous access */
-    rgw_get_anon_user(s->user);
+    rgw_get_anon_user(*(s->user));
     s->perm_mask = RGW_PERM_FULL_CONTROL;
     return 0;
   }
@@ -1271,19 +1362,41 @@ int RGWHandler_ObjStore_SWIFT::authorize()
   if (!authorized)
     return -EPERM;
 
+  if (s->user->system) {
+    s->system_request = true;
+    ldout(s->cct, 20) << "system request over Swift API" << dendl;
+
+    rgw_user euid(s->info.args.sys_get(RGW_SYS_PARAM_PREFIX "uid"));
+    if (!euid.empty()) {
+      RGWUserInfo einfo;
+
+      const int ret = rgw_get_user_info_by_uid(store, euid, einfo);
+      if (ret < 0) {
+        ldout(s->cct, 0) << "User lookup failed, euid=" << euid
+                         << " ret=" << ret << dendl;
+        return -ENOENT;
+      }
+
+      *(s->user) = einfo;
+    }
+  }
+
   return 0;
 }
 
-int RGWHandler_ObjStore_SWIFT::postauth_init()
+int RGWHandler_REST_SWIFT::postauth_init()
 {
-  struct req_init_state *t = &s->init_state;
+  struct req_init_state* t = &s->init_state;
 
   /* XXX Stub this until Swift Auth sets account into URL. */
-  s->bucket_tenant = s->user.user_id.tenant;
+  s->bucket_tenant = s->user->user_id.tenant;
   s->bucket_name = t->url_bucket;
 
-  dout(10) << "s->object=" << (!s->object.empty() ? s->object : rgw_obj_key("<NULL>"))
-           << " s->bucket=" << rgw_make_bucket_entry_name(s->bucket_tenant, s->bucket_name) << dendl;
+  dout(10) << "s->object=" <<
+    (!s->object.empty() ? s->object : rgw_obj_key("<NULL>"))
+           << " s->bucket="
+	   << rgw_make_bucket_entry_name(s->bucket_tenant, s->bucket_name)
+	   << dendl;
 
   int ret;
   ret = validate_tenant_name(s->bucket_tenant);
@@ -1301,7 +1414,7 @@ int RGWHandler_ObjStore_SWIFT::postauth_init()
      * We don't allow cross-tenant copy at present. It requires account
      * names in the URL for Swift.
      */
-    s->src_tenant_name = s->user.user_id.tenant;
+    s->src_tenant_name = s->user->user_id.tenant;
     s->src_bucket_name = t->src_bucket;
 
     ret = validate_bucket_name(s->src_bucket_name);
@@ -1317,9 +1430,9 @@ int RGWHandler_ObjStore_SWIFT::postauth_init()
   return 0;
 }
 
-int RGWHandler_ObjStore_SWIFT::validate_bucket_name(const string& bucket)
+int RGWHandler_REST_SWIFT::validate_bucket_name(const string& bucket)
 {
-  int ret = RGWHandler_ObjStore::validate_bucket_name(bucket);
+  int ret = RGWHandler_REST::validate_bucket_name(bucket);
   if (ret < 0)
     return ret;
 
@@ -1360,7 +1473,7 @@ static void next_tok(string& str, string& tok, char delim)
   }
 }
 
-int RGWHandler_ObjStore_SWIFT::init_from_header(struct req_state *s)
+int RGWHandler_REST_SWIFT::init_from_header(struct req_state *s)
 {
   string req;
   string first;
@@ -1414,7 +1527,8 @@ int RGWHandler_ObjStore_SWIFT::init_from_header(struct req_state *s)
 
   /* verify that the request_uri conforms with what's expected */
   char buf[g_conf->rgw_swift_url_prefix.length() + 16 + tenant_path.length()];
-  int blen = sprintf(buf, "/%s/v1%s", g_conf->rgw_swift_url_prefix.c_str(), tenant_path.c_str());
+  int blen = sprintf(buf, "/%s/v1%s",
+		    g_conf->rgw_swift_url_prefix.c_str(), tenant_path.c_str());
   if (s->decoded_uri[0] != '/' ||
     s->decoded_uri.compare(0, blen, buf) !=  0) {
     return -ENOENT;
@@ -1428,9 +1542,27 @@ int RGWHandler_ObjStore_SWIFT::init_from_header(struct req_state *s)
 
   next_tok(req, ver, '/');
 
-  string tenant;
-  if (!tenant_path.empty()) {
-    next_tok(req, tenant, '/');
+  if (!tenant_path.empty() || g_conf->rgw_swift_account_in_url) {
+    string account_name;
+    next_tok(req, account_name, '/');
+
+    /* Erase all pre-defined prefixes like "AUTH_" or "KEY_". */
+    const vector<string> skipped_prefixes = { "AUTH_", "KEY_" };
+
+    for (const auto pfx : skipped_prefixes) {
+      const size_t comp_len = min(account_name.length(), pfx.length());
+      if (account_name.compare(0, comp_len, pfx) == 0) {
+        /* Prefix is present. Drop it. */
+        account_name = account_name.substr(comp_len);
+        break;
+      }
+    }
+
+    if (account_name.empty()) {
+      return -ERR_PRECONDITION_FAILED;
+    } else {
+      s->account_name = account_name;
+    }
   }
 
   s->os_auth_token = s->info.env->get("HTTP_X_AUTH_TOKEN");
@@ -1446,14 +1578,16 @@ int RGWHandler_ObjStore_SWIFT::init_from_header(struct req_state *s)
   s->init_state.url_bucket = first;
 
   if (req.size()) {
-    s->object = rgw_obj_key(req, s->info.env->get("HTTP_X_OBJECT_VERSION_ID", "")); /* rgw swift extension */
+    s->object =
+      rgw_obj_key(req, s->info.env->get("HTTP_X_OBJECT_VERSION_ID", "")); /* rgw swift extension */
     s->info.effective_uri.append("/" + s->object.name);
   }
 
   return 0;
 }
 
-int RGWHandler_ObjStore_SWIFT::init(RGWRados *store, struct req_state *s, RGWClientIO *cio)
+int RGWHandler_REST_SWIFT::init(RGWRados* store, struct req_state* s,
+				RGWClientIO *cio)
 {
   struct req_init_state *t = &s->init_state;
 
@@ -1461,9 +1595,10 @@ int RGWHandler_ObjStore_SWIFT::init(RGWRados *store, struct req_state *s, RGWCli
 
   const char *copy_source = s->info.env->get("HTTP_X_COPY_FROM");
   if (copy_source) {
-    bool result = RGWCopyObj::parse_copy_location(copy_source, t->src_bucket, s->src_object);
+    bool result = RGWCopyObj::parse_copy_location(copy_source, t->src_bucket,
+						  s->src_object);
     if (!result)
-       return -ERR_BAD_URL;
+      return -ERR_BAD_URL;
   }
 
   if (s->op == OP_COPY) {
@@ -1473,7 +1608,9 @@ int RGWHandler_ObjStore_SWIFT::init(RGWRados *store, struct req_state *s, RGWCli
 
     string dest_bucket_name;
     rgw_obj_key dest_obj_key;
-    bool result = RGWCopyObj::parse_copy_location(req_dest, dest_bucket_name, dest_obj_key);
+    bool result =
+      RGWCopyObj::parse_copy_location(req_dest, dest_bucket_name,
+				      dest_obj_key);
     if (!result)
        return -ERR_BAD_URL;
 
@@ -1487,21 +1624,20 @@ int RGWHandler_ObjStore_SWIFT::init(RGWRados *store, struct req_state *s, RGWCli
     s->op = OP_PUT;
   }
 
-  return RGWHandler_ObjStore::init(store, s, cio);
+  return RGWHandler_REST::init(store, s, cio);
 }
 
-
-RGWHandler *RGWRESTMgr_SWIFT::get_handler(struct req_state *s)
+RGWHandler_REST* RGWRESTMgr_SWIFT::get_handler(struct req_state *s)
 {
-  int ret = RGWHandler_ObjStore_SWIFT::init_from_header(s);
+  int ret = RGWHandler_REST_SWIFT::init_from_header(s);
   if (ret < 0)
     return NULL;
 
   if (s->init_state.url_bucket.empty())
-    return new RGWHandler_ObjStore_Service_SWIFT;
+    return new RGWHandler_REST_Service_SWIFT;
 
   if (s->object.empty())
-    return new RGWHandler_ObjStore_Bucket_SWIFT;
+    return new RGWHandler_REST_Bucket_SWIFT;
 
-  return new RGWHandler_ObjStore_Obj_SWIFT;
+  return new RGWHandler_REST_Obj_SWIFT;
 }
diff --git a/src/rgw/rgw_rest_swift.h b/src/rgw/rgw_rest_swift.h
index 1d483b3..bbef15b 100644
--- a/src/rgw/rgw_rest_swift.h
+++ b/src/rgw/rgw_rest_swift.h
@@ -21,6 +21,10 @@ public:
 
 class RGWListBuckets_ObjStore_SWIFT : public RGWListBuckets_ObjStore {
   bool need_stats;
+
+  uint64_t get_default_max() const override {
+    return 0;
+  }
 public:
   RGWListBuckets_ObjStore_SWIFT() : need_stats(true) {}
   ~RGWListBuckets_ObjStore_SWIFT() {}
@@ -67,6 +71,8 @@ public:
 };
 
 class RGWCreateBucket_ObjStore_SWIFT : public RGWCreateBucket_ObjStore {
+protected:
+  bool need_metadata_upload() const override { return true; }
 public:
   RGWCreateBucket_ObjStore_SWIFT() {}
   ~RGWCreateBucket_ObjStore_SWIFT() {}
@@ -84,6 +90,7 @@ public:
 };
 
 class RGWPutObj_ObjStore_SWIFT : public RGWPutObj_ObjStore {
+  string lo_etag;
 public:
   RGWPutObj_ObjStore_SWIFT() {}
   ~RGWPutObj_ObjStore_SWIFT() {}
@@ -178,7 +185,7 @@ public:
   void send_response();
 };
 
-class RGWHandler_ObjStore_SWIFT : public RGWHandler_ObjStore {
+class RGWHandler_REST_SWIFT : public RGWHandler_REST {
   friend class RGWRESTMgr_SWIFT;
 protected:
   virtual bool is_acl_op() {
@@ -187,8 +194,8 @@ protected:
 
   static int init_from_header(struct req_state *s);
 public:
-  RGWHandler_ObjStore_SWIFT() {}
-  virtual ~RGWHandler_ObjStore_SWIFT() {}
+  RGWHandler_REST_SWIFT() {}
+  virtual ~RGWHandler_REST_SWIFT() {}
 
   int validate_bucket_name(const string& bucket);
 
@@ -200,18 +207,18 @@ public:
   void free_policy(RGWAccessControlPolicy *policy) { delete policy; }
 };
 
-class RGWHandler_ObjStore_Service_SWIFT : public RGWHandler_ObjStore_SWIFT {
+class RGWHandler_REST_Service_SWIFT : public RGWHandler_REST_SWIFT {
 protected:
   RGWOp *op_get();
   RGWOp *op_head();
   RGWOp *op_post();
   RGWOp *op_delete();
 public:
-  RGWHandler_ObjStore_Service_SWIFT() {}
-  virtual ~RGWHandler_ObjStore_Service_SWIFT() {}
+  RGWHandler_REST_Service_SWIFT() {}
+  virtual ~RGWHandler_REST_Service_SWIFT() {}
 };
 
-class RGWHandler_ObjStore_Bucket_SWIFT : public RGWHandler_ObjStore_SWIFT {
+class RGWHandler_REST_Bucket_SWIFT : public RGWHandler_REST_SWIFT {
 protected:
   bool is_obj_update_op() {
     return s->op == OP_POST;
@@ -225,11 +232,11 @@ protected:
   RGWOp *op_post();
   RGWOp *op_options();
 public:
-  RGWHandler_ObjStore_Bucket_SWIFT() {}
-  virtual ~RGWHandler_ObjStore_Bucket_SWIFT() {}
+  RGWHandler_REST_Bucket_SWIFT() {}
+  virtual ~RGWHandler_REST_Bucket_SWIFT() {}
 };
 
-class RGWHandler_ObjStore_Obj_SWIFT : public RGWHandler_ObjStore_SWIFT {
+class RGWHandler_REST_Obj_SWIFT : public RGWHandler_REST_SWIFT {
 protected:
   bool is_obj_update_op() {
     return s->op == OP_POST;
@@ -243,9 +250,10 @@ protected:
   RGWOp *op_post();
   RGWOp *op_copy();
   RGWOp *op_options();
+
 public:
-  RGWHandler_ObjStore_Obj_SWIFT() {}
-  virtual ~RGWHandler_ObjStore_Obj_SWIFT() {}
+  RGWHandler_REST_Obj_SWIFT() {}
+  virtual ~RGWHandler_REST_Obj_SWIFT() {}
 };
 
 class RGWRESTMgr_SWIFT : public RGWRESTMgr {
@@ -253,7 +261,7 @@ public:
   RGWRESTMgr_SWIFT() {}
   virtual ~RGWRESTMgr_SWIFT() {}
 
-  virtual RGWHandler *get_handler(struct req_state *s);
+  virtual RGWHandler_REST *get_handler(struct req_state *s);
 };
 
 #endif
diff --git a/src/rgw/rgw_rest_usage.h b/src/rgw/rgw_rest_usage.h
index 1851ddf..e096380 100644
--- a/src/rgw/rgw_rest_usage.h
+++ b/src/rgw/rgw_rest_usage.h
@@ -26,10 +26,9 @@ public:
   RGWRESTMgr_Usage() {}
   virtual ~RGWRESTMgr_Usage() {}
 
-  RGWHandler *get_handler(struct req_state *s) {
+  RGWHandler_REST* get_handler(struct req_state *s) {
     return new RGWHandler_Usage;
   }
 };
 
-
 #endif
diff --git a/src/rgw/rgw_rest_user.cc b/src/rgw/rgw_rest_user.cc
index 46132b0..587e6d0 100644
--- a/src/rgw/rgw_rest_user.cc
+++ b/src/rgw/rgw_rest_user.cc
@@ -8,6 +8,7 @@
 #include "rgw_rest_user.h"
 
 #include "include/str_list.h"
+#include "include/assert.h"
 
 #define dout_subsys ceph_subsys_rgw
 
@@ -92,7 +93,7 @@ void RGWOp_User_Create::execute()
   RESTArgs::get_bool(s, "system", false, &system);
   RESTArgs::get_bool(s, "exclusive", false, &exclusive);
 
-  if (!s->user.system && system) {
+  if (!s->user->system && system) {
     ldout(s->cct, 0) << "cannot set system flag by non-system user" << dendl;
     http_ret = -EINVAL;
     return;
@@ -192,7 +193,7 @@ void RGWOp_User_Modify::execute()
 
   RESTArgs::get_bool(s, "system", false, &system);
 
-  if (!s->user.system && system) {
+  if (!s->user->system && system) {
     ldout(s->cct, 0) << "cannot set system flag by non-system user" << dendl;
     http_ret = -EINVAL;
     return;
diff --git a/src/rgw/rgw_rest_user.h b/src/rgw/rgw_rest_user.h
index 4fe22f7..d3c399b 100644
--- a/src/rgw/rgw_rest_user.h
+++ b/src/rgw/rgw_rest_user.h
@@ -28,7 +28,7 @@ public:
   RGWRESTMgr_User() {}
   virtual ~RGWRESTMgr_User() {}
 
-  RGWHandler *get_handler(struct req_state *s) {
+  RGWHandler_REST *get_handler(struct req_state *s) {
     return new RGWHandler_User;
   }
 };
diff --git a/src/rgw/rgw_swift.cc b/src/rgw/rgw_swift.cc
index 76eda3c..0fdb310 100644
--- a/src/rgw/rgw_swift.cc
+++ b/src/rgw/rgw_swift.cc
@@ -15,9 +15,6 @@
 
 #include "include/str_list.h"
 
-#include "common/ceph_crypto_cms.h"
-#include "common/armor.h"
-
 #define dout_subsys ceph_subsys_rgw
 
 static list<string> roles_list;
@@ -65,7 +62,7 @@ int RGWValidateSwiftToken::receive_header(void *ptr, size_t len)
           l++;
  
         if (strcmp(tok, "HTTP") == 0) {
-          info->status = atoi(l);
+          ;
         } else if (strcasecmp(tok, "X-Auth-Groups") == 0) {
           info->auth_groups = l;
           char *s = strchr(l, ',');
@@ -111,8 +108,12 @@ class RGWPostHTTPData : public RGWHTTPClient {
   bufferlist *bl;
   std::string post_data;
   size_t post_data_index;
+  std::string subject_token;
 public:
   RGWPostHTTPData(CephContext *_cct, bufferlist *_bl) : RGWHTTPClient(_cct), bl(_bl), post_data_index(0) {}
+  RGWPostHTTPData(CephContext *_cct, bufferlist *_bl, bool verify_ssl) : RGWHTTPClient(_cct), bl(_bl), post_data_index(0){
+    set_verify_ssl(verify_ssl);
+  }
 
   void set_post_data(const std::string& _post_data) {
     this->post_data = _post_data;
@@ -134,106 +135,57 @@ public:
   }
 
   int receive_header(void *ptr, size_t len) {
-    return 0;
-  }
-};
+    char line[len + 1];
 
-typedef RGWPostHTTPData RGWGetKeystoneAdminToken;
-typedef RGWPostHTTPData RGWGetRevokedTokens;
+    char *s = (char *)ptr, *end = (char *)ptr + len;
+    char *p = line;
+    ldout(cct, 20) << "RGWPostHTTPData::receive_header parsing HTTP headers" << dendl;
 
-class RGWValidateKeystoneToken : public RGWHTTPClient {
-  bufferlist *bl;
-public:
-  RGWValidateKeystoneToken(CephContext *_cct, bufferlist *_bl) : RGWHTTPClient(_cct), bl(_bl) {}
+    while (s != end) {
+      if (*s == '\r') {
+        s++;
+        continue;
+      }
+      if (*s == '\n') {
+        *p = '\0';
+        ldout(cct, 20) << "RGWPostHTTPData::receive_header: line="
+                       << line << dendl;
+        // TODO: fill whatever data required here
+        char *l = line;
+        char *tok = strsep(&l, " \t:");
+        if (tok) {
+          while (l && *l == ' ') {
+            l++;
+          }
 
-  int receive_data(void *ptr, size_t len) {
-    bl->append((char *)ptr, len);
-    return 0;
-  }
-  int receive_header(void *ptr, size_t len) {
-    return 0;
-  }
-  int send_data(void *ptr, size_t len) {
+          if (strcasecmp(tok, "X-Subject-Token") == 0) {
+            subject_token = l;
+          }
+        }
+      }
+      if (s != end) {
+        *p++ = *s++;
+      }
+    }
     return 0;
   }
 
-};
-
-static RGWKeystoneTokenCache *keystone_token_cache = NULL;
-
-static int open_cms_envelope(CephContext *cct, string& src, string& dst)
-{
-#define BEGIN_CMS "-----BEGIN CMS-----"
-#define END_CMS "-----END CMS-----"
-
-  int start = src.find(BEGIN_CMS);
-  if (start < 0) {
-    ldout(cct, 0) << "failed to find " << BEGIN_CMS << " in response" << dendl;
-    return -EINVAL;
-  }
-  start += sizeof(BEGIN_CMS) - 1;
-
-  int end = src.find(END_CMS);
-  if (end < 0) {
-    ldout(cct, 0) << "failed to find " << END_CMS << " in response" << dendl;
-    return -EINVAL;
+  std::string get_subject_token() {
+    return subject_token;
   }
+};
 
-  string s = src.substr(start, end - start);
-
-  int pos = 0;
-
-  do {
-    int next = s.find('\n', pos);
-    if (next < 0) {
-      dst.append(s.substr(pos));
-      break;
-    } else {
-      dst.append(s.substr(pos, next - pos));
-    }
-    pos = next + 1;
-  } while (pos < (int)s.size());
-
-  return 0;
-}
-
-static int decode_b64_cms(CephContext *cct, const string& signed_b64, bufferlist& bl)
-{
-  bufferptr signed_ber(signed_b64.size() * 2);
-  char *dest = signed_ber.c_str();
-  const char *src = signed_b64.c_str();
-  size_t len = signed_b64.size();
-  char buf[len + 1];
-  buf[len] = '\0';
-  for (size_t i = 0; i < len; i++, src++) {
-    if (*src != '-')
-      buf[i] = *src;
-    else
-      buf[i] = '/';
-  }
-  int ret = ceph_unarmor(dest, dest + signed_ber.length(), buf, buf + signed_b64.size());
-  if (ret < 0) {
-    ldout(cct, 0) << "ceph_unarmor() failed, ret=" << ret << dendl;
-    return ret;
-  }
-
-  bufferlist signed_ber_bl;
-  signed_ber_bl.append(signed_ber);
-
-  ret = ceph_decode_cms(cct, signed_ber_bl, bl);
-  if (ret < 0) {
-    ldout(cct, 0) << "ceph_decode_cms returned " << ret << dendl;
-    return ret;
-  }
+typedef RGWPostHTTPData RGWValidateKeystoneToken;
+typedef RGWPostHTTPData RGWGetKeystoneAdminToken;
+typedef RGWPostHTTPData RGWGetRevokedTokens;
 
-  return 0;
-}
+static RGWKeystoneTokenCache *keystone_token_cache = NULL;
 
 int RGWSwift::get_keystone_url(CephContext * const cct,
                                std::string& url)
 {
   bufferlist bl;
-  RGWGetRevokedTokens req(cct, &bl);
+  RGWGetRevokedTokens req(cct, &bl, cct->_conf->rgw_keystone_verify_ssl);
 
   url = cct->_conf->rgw_keystone_url;
   if (url.empty()) {
@@ -260,38 +212,64 @@ int RGWSwift::get_keystone_admin_token(CephContext * const cct,
 {
   std::string token_url;
 
-  if (get_keystone_url(cct, token_url) < 0)
+  if (get_keystone_url(cct, token_url) < 0) {
     return -EINVAL;
-  if (cct->_conf->rgw_keystone_admin_token.empty()) {
+  }
+
+  if (!cct->_conf->rgw_keystone_admin_token.empty()) {
+    token = cct->_conf->rgw_keystone_admin_token;
+    return 0;
+  }
+
+  KeystoneToken t;
+
+  /* Try cache first. */
+  if (keystone_token_cache->find_admin(t)) {
+    ldout(cct, 20) << "found cached admin token" << dendl;
+    token = t.token.id;
+    return 0;
+  }
+
+  bufferlist token_bl;
+  RGWGetKeystoneAdminToken token_req(cct, &token_bl, cct->_conf->rgw_keystone_verify_ssl);
+  token_req.append_header("Content-Type", "application/json");
+  JSONFormatter jf;
+
+  const auto keystone_version = KeystoneService::get_api_version();
+  if (keystone_version == KeystoneApiVersion::VER_2) {
+    KeystoneAdminTokenRequestVer2 req_serializer(cct);
+    req_serializer.dump(&jf);
+
+    std::stringstream ss;
+    jf.flush(ss);
+    token_req.set_post_data(ss.str());
+    token_req.set_send_length(ss.str().length());
     token_url.append("v2.0/tokens");
-    KeystoneToken t;
-    bufferlist token_bl;
-    RGWGetKeystoneAdminToken token_req(cct, &token_bl);
-    token_req.append_header("Content-Type", "application/json");
-    JSONFormatter jf;
-    jf.open_object_section("token_request");
-    jf.open_object_section("auth");
-    jf.open_object_section("passwordCredentials");
-    encode_json("username", cct->_conf->rgw_keystone_admin_user, &jf);
-    encode_json("password", cct->_conf->rgw_keystone_admin_password, &jf);
-    jf.close_section();
-    encode_json("tenantName", cct->_conf->rgw_keystone_admin_tenant, &jf);
-    jf.close_section();
-    jf.close_section();
+
+  } else if (keystone_version == KeystoneApiVersion::VER_3) {
+    KeystoneAdminTokenRequestVer3 req_serializer(cct);
+    req_serializer.dump(&jf);
+
     std::stringstream ss;
     jf.flush(ss);
     token_req.set_post_data(ss.str());
     token_req.set_send_length(ss.str().length());
-    int ret = token_req.process("POST", token_url.c_str());
-    if (ret < 0)
-      return ret;
-    if (t.parse(cct, token_bl) != 0)
-      return -EINVAL;
-    token = t.token.id;
+    token_url.append("v3/auth/tokens");
   } else {
-    token = cct->_conf->rgw_keystone_admin_token;
+    return -ENOTSUP;
   }
-  return 0; 
+
+  const int ret = token_req.process("POST", token_url.c_str());
+  if (ret < 0) {
+    return ret;
+  }
+  if (t.parse(cct, token_req.get_subject_token(), token_bl) != 0) {
+    return -EINVAL;
+  }
+
+  keystone_token_cache->add_admin(t);
+  token = t.token.id;
+  return 0;
 }
 
 
@@ -303,16 +281,26 @@ int RGWSwift::check_revoked()
   bufferlist bl;
   RGWGetRevokedTokens req(cct, &bl);
 
-  if (get_keystone_admin_token(token) < 0)
+  if (get_keystone_admin_token(token) < 0) {
     return -EINVAL;
-  if (get_keystone_url(url) < 0)
+  }
+  if (get_keystone_url(url) < 0) {
     return -EINVAL;
-  url.append("v2.0/tokens/revoked");
+  }
   req.append_header("X-Auth-Token", token);
+
+  const auto keystone_version = KeystoneService::get_api_version();
+  if (keystone_version == KeystoneApiVersion::VER_2) {
+    url.append("v2.0/tokens/revoked");
+  } else if (keystone_version == KeystoneApiVersion::VER_3) {
+    url.append("v3/auth/tokens/OS-PKI/revoked");
+  }
+
   req.set_send_length(0);
   int ret = req.process(url.c_str());
-  if (ret < 0)
+  if (ret < 0) {
     return ret;
+  }
 
   bl.append((char)0); // NULL terminate for debug output
 
@@ -338,14 +326,14 @@ int RGWSwift::check_revoked()
   ldout(cct, 10) << "signed=" << signed_str << dendl;
 
   string signed_b64;
-  ret = open_cms_envelope(cct, signed_str, signed_b64);
+  ret = rgw_open_cms_envelope(cct, signed_str, signed_b64);
   if (ret < 0)
     return ret;
 
   ldout(cct, 10) << "content=" << signed_b64 << dendl;
   
   bufferlist json;
-  ret = decode_b64_cms(cct, signed_b64, json);
+  ret = rgw_decode_b64_cms(cct, signed_b64, json);
   if (ret < 0) {
     return ret;
   }
@@ -385,31 +373,37 @@ int RGWSwift::check_revoked()
 
 static void rgw_set_keystone_token_auth_info(KeystoneToken& token, struct rgw_swift_auth_info *info)
 {
-  info->user = token.token.tenant.id;
-  info->display_name = token.token.tenant.name;
-  info->status = 200;
+  info->user = token.get_project_id();
+  info->display_name = token.get_project_name();
 }
 
-int RGWSwift::parse_keystone_token_response(const string& token, bufferlist& bl, struct rgw_swift_auth_info *info, KeystoneToken& t)
+int RGWSwift::parse_keystone_token_response(const string& token,
+                                            bufferlist& bl,
+                                            struct rgw_swift_auth_info *info,
+                                            KeystoneToken& t)
 {
-  int ret = t.parse(cct, bl);
-  if (ret < 0)
+  int ret = t.parse(cct, token, bl);
+  if (ret < 0) {
     return ret;
+  }
 
   bool found = false;
   list<string>::iterator iter;
   for (iter = roles_list.begin(); iter != roles_list.end(); ++iter) {
     const string& role = *iter;
-    if ((found=t.user.has_role(role))==true)
+    if ((found=t.has_role(role))==true)
       break;
   }
 
   if (!found) {
-    ldout(cct, 0) << "user does not hold a matching role; required roles: " << g_conf->rgw_keystone_accepted_roles << dendl;
+    ldout(cct, 0) << "user does not hold a matching role; required roles: "
+                  << g_conf->rgw_keystone_accepted_roles << dendl;
     return -EPERM;
   }
 
-  ldout(cct, 0) << "validated token: " << t.token.tenant.name << ":" << t.user.name << " expires: " << t.token.expires << dendl;
+  ldout(cct, 0) << "validated token: " << t.get_project_name()
+                << ":" << t.get_user_name()
+                << " expires: " << t.get_expires() << dendl;
 
   rgw_set_keystone_token_auth_info(t, info);
 
@@ -418,77 +412,72 @@ int RGWSwift::parse_keystone_token_response(const string& token, bufferlist& bl,
 
 int RGWSwift::update_user_info(RGWRados *store, struct rgw_swift_auth_info *info, RGWUserInfo& user_info)
 {
-  if (rgw_get_user_info_by_uid(store, info->user, user_info) < 0) {
-    ldout(cct, 0) << "NOTICE: couldn't map swift user" << dendl;
-    user_info.user_id = info->user;
-    user_info.display_name = info->display_name;
-
-    int ret = rgw_store_user_info(store, user_info, NULL, NULL, 0, true);
-    if (ret < 0) {
-      ldout(cct, 0) << "ERROR: failed to store new user's info: ret=" << ret << dendl;
-      return ret;
+  ldout(cct, 20) << "updating user=" << info->user << dendl; // P3 XXX
+  /*
+   * Normally once someone parsed the token, the tenant and user are set
+   * in rgw_swift_auth_info. If .tenant is empty in it, the client has
+   * authenticated with the empty legacy tenant. But when we authenticate
+   * with Keystone, we have a special compatibility kludge. First, we try
+   * the same tenant as the user. If that user exists, we use it. This way,
+   * migrated OpenStack users can get their namespaced containers and
+   * nobody's the wiser. If that fails, we look up the user in the empty
+   * tenant. If neither is found, make one, and those migrating can
+   * set a special configurable rgw_keystone_implicit_tenants to create
+   * suitable tenantized users.
+   */
+  if (info->user.tenant.empty()) {
+    rgw_user uid;
+    uid.tenant = info->user.id;
+    uid.id = info->user.id;
+    if (rgw_get_user_info_by_uid(store, uid, user_info) < 0) {
+      uid.tenant.clear();
+      if (rgw_get_user_info_by_uid(store, uid, user_info) < 0) {
+        ldout(cct, 0) << "NOTICE: couldn't map swift user " << uid << dendl;
+        if (g_conf->rgw_keystone_implicit_tenants) {
+          uid.tenant = info->user.id;
+        }
+        user_info.user_id = uid;
+        user_info.display_name = info->display_name;
+        int ret = rgw_store_user_info(store, user_info, NULL, NULL, real_time(), true);
+        if (ret < 0) {
+          ldout(cct, 0) << "ERROR: failed to store new user info: user=" << user_info.user_id << " ret=" << ret << dendl;
+          return ret;
+        }
+      }
+    }
+  } else {
+    if (rgw_get_user_info_by_uid(store, info->user, user_info) < 0) {
+      ldout(cct, 0) << "NOTICE: couldn't map swift user " << info->user << dendl;
+      user_info.user_id = info->user;
+      user_info.display_name = info->display_name;
+      int ret = rgw_store_user_info(store, user_info, NULL, NULL, real_time(), true);
+      if (ret < 0) {
+        ldout(cct, 0) << "ERROR: failed to store new user info: user=" << user_info.user_id << " ret=" << ret << dendl;
+        return ret;
+      }
     }
   }
   return 0;
 }
 
-#define PKI_ANS1_PREFIX "MII"
-
-static bool is_pki_token(const string& token)
-{
-  return token.compare(0, sizeof(PKI_ANS1_PREFIX) - 1, PKI_ANS1_PREFIX) == 0;
-}
-
-static void get_token_id(const string& token, string& token_id)
-{
-  if (!is_pki_token(token)) {
-    token_id = token;
-    return;
-  }
-
-  unsigned char m[CEPH_CRYPTO_MD5_DIGESTSIZE];
-
-  MD5 hash;
-  hash.Update((const byte *)token.c_str(), token.size());
-  hash.Final(m);
-
-
-  char calc_md5[CEPH_CRYPTO_MD5_DIGESTSIZE * 2 + 1];
-  buf_to_hex(m, CEPH_CRYPTO_MD5_DIGESTSIZE, calc_md5);
-  token_id = calc_md5;
-}
-
-static bool decode_pki_token(CephContext *cct, const string& token, bufferlist& bl)
-{
-  if (!is_pki_token(token))
-    return false;
-
-  int ret = decode_b64_cms(cct, token, bl);
-  if (ret < 0)
-    return false;
-
-  ldout(cct, 20) << "successfully decoded pki token" << dendl;
-
-  return true;
-}
-
-int RGWSwift::validate_keystone_token(RGWRados *store, const string& token, struct rgw_swift_auth_info *info,
+int RGWSwift::validate_keystone_token(RGWRados *store, const string& token,
 				      RGWUserInfo& rgw_user)
 {
   KeystoneToken t;
+  struct rgw_swift_auth_info info;
 
   string token_id;
-  get_token_id(token, token_id);
+  rgw_get_token_id(token, token_id);
 
   ldout(cct, 20) << "token_id=" << token_id << dendl;
 
   /* check cache first */
   if (keystone_token_cache->find(token_id, t)) {
-    rgw_set_keystone_token_auth_info(t, info);
+    rgw_set_keystone_token_auth_info(t, &info);
 
-    ldout(cct, 20) << "cached token.tenant.id=" << t.token.tenant.id << dendl;
+    ldout(cct, 20) << "cached token.project.id=" << t.get_project_id() << dendl;
 
-    int ret = update_user_info(store, info, rgw_user);
+    int ret = update_user_info(store, &info, rgw_user);
     if (ret < 0)
       return ret;
 
@@ -498,11 +487,11 @@ int RGWSwift::validate_keystone_token(RGWRados *store, const string& token, stru
   bufferlist bl;
 
   /* check if that's a self signed token that we can decode */
-  if (!decode_pki_token(cct, token, bl)) {
+  if (!rgw_decode_pki_token(cct, token, bl)) {
 
     /* can't decode, just go to the keystone server for validation */
 
-    RGWValidateKeystoneToken validate(cct, &bl);
+    RGWValidateKeystoneToken validate(cct, &bl, cct->_conf->rgw_keystone_verify_ssl);
 
     string url = g_conf->rgw_keystone_url;
     if (url.empty()) {
@@ -517,11 +506,18 @@ int RGWSwift::validate_keystone_token(RGWRados *store, const string& token, stru
     if (get_keystone_url(url) < 0)
       return -EINVAL;
 
-    url.append("v2.0/tokens/");
-    url.append(token);
-
     validate.append_header("X-Auth-Token", admin_token);
 
+    const auto keystone_version = KeystoneService::get_api_version();
+    if (keystone_version == KeystoneApiVersion::VER_2) {
+      url.append("v2.0/tokens/");
+      url.append(token);
+    }
+    if (keystone_version == KeystoneApiVersion::VER_3) {
+      url.append("v3/auth/tokens");
+      validate.append_header("X-Subject-Token", token);
+    }
+
     validate.set_send_length(0);
 
     int ret = validate.process(url.c_str());
@@ -533,67 +529,133 @@ int RGWSwift::validate_keystone_token(RGWRados *store, const string& token, stru
 
   ldout(cct, 20) << "received response: " << bl.c_str() << dendl;
 
-  int ret = parse_keystone_token_response(token, bl, info, t);
+  int ret = parse_keystone_token_response(token, bl, &info, t);
   if (ret < 0)
     return ret;
 
   if (t.expired()) {
-    ldout(cct, 0) << "got expired token: " << t.token.tenant.name << ":" << t.user.name << " expired: " << t.token.expires << dendl;
+    ldout(cct, 0) << "got expired token: " << t.get_project_name()
+                  << ":" << t.get_user_name()
+                  << " expired: " << t.get_expires() << dendl;
     return -EPERM;
   }
 
   keystone_token_cache->add(token_id, t);
 
-  ret = update_user_info(store, info, rgw_user);
+  ret = update_user_info(store, &info, rgw_user);
   if (ret < 0)
     return ret;
 
   return 0;
 }
 
-int authenticate_temp_url(RGWRados *store, req_state *s)
+static void temp_url_make_content_disp(req_state * const s)
 {
+  bool inline_exists = false;
+  string filename = s->info.args.get("filename");
+
+  s->info.args.get("inline", &inline_exists);
+  if (inline_exists) {
+    s->content_disp.override = "inline";
+  } else if (!filename.empty()) {
+    string fenc;
+    url_encode(filename, fenc);
+    s->content_disp.override = "attachment; filename=\"" + fenc + "\"";
+  } else {
+    string fenc;
+    url_encode(s->object.name, fenc);
+    s->content_disp.fallback = "attachment; filename=\"" + fenc + "\"";
+  }
+}
+
+static string temp_url_gen_sig(const string& key,
+                               const string& method,
+                               const string& path,
+                               const string& expires)
+{
+  const string str = method + "\n" + expires + "\n" + path;
+  //dout(20) << "temp url signature (plain text): " << str << dendl;
+
+  /* unsigned */ char dest[CEPH_CRYPTO_HMACSHA1_DIGESTSIZE];
+  calc_hmac_sha1(key.c_str(), key.size(),
+                 str.c_str(), str.size(),
+                 dest);
+
+  char dest_str[CEPH_CRYPTO_HMACSHA1_DIGESTSIZE * 2 + 1];
+  buf_to_hex((const unsigned char *)dest, sizeof(dest), dest_str);
+
+  return dest_str;
+}
+
+int authenticate_temp_url(RGWRados * const store, req_state * const s)
+{
+  /* We cannot use req_state::bucket_name because it isn't available
+   * now. It will be initialized in RGWHandler_REST_SWIFT::postauth_init(). */
+  const string& bucket_name = s->init_state.url_bucket;
+
   /* temp url requires bucket and object specified in the requets */
-  if (s->bucket_name.empty())
+  if (bucket_name.empty()) {
     return -EPERM;
+  }
 
-  if (s->object.empty())
+  if (s->object.empty()) {
     return -EPERM;
+  }
 
-  string temp_url_sig = s->info.args.get("temp_url_sig");
-  if (temp_url_sig.empty())
+  const string temp_url_sig = s->info.args.get("temp_url_sig");
+  if (temp_url_sig.empty()) {
     return -EPERM;
+  }
 
-  string temp_url_expires = s->info.args.get("temp_url_expires");
-  if (temp_url_expires.empty())
+  const string temp_url_expires = s->info.args.get("temp_url_expires");
+  if (temp_url_expires.empty()) {
     return -EPERM;
+  }
 
-  /* need to get user info of bucket owner */
-  RGWBucketInfo bucket_info;
+  /* TempURL case is completely different than the Keystone auth - you may
+   * get account name only through extraction from URL. In turn, knowledge
+   * about account is neccessary to obtain its bucket tenant. Without that,
+   * the access would be limited to accounts with empty tenant. */
+  string bucket_tenant;
+  if (!s->account_name.empty()) {
+    RGWUserInfo uinfo;
 
+    if (rgw_get_user_info_by_uid(store, s->account_name, uinfo) < 0) {
+      return -EPERM;
+    }
+
+    bucket_tenant = uinfo.user_id.tenant;
+  }
+
+  /* Need to get user info of bucket owner. */
+  RGWBucketInfo bucket_info;
   int ret = store->get_bucket_info(*static_cast<RGWObjectCtx *>(s->obj_ctx),
-                                   s->bucket_tenant, s->bucket_name,
+                                   bucket_tenant, bucket_name,
                                    bucket_info, NULL);
-  if (ret < 0)
+  if (ret < 0) {
     return -EPERM;
+  }
 
-  dout(20) << "temp url user (bucket owner): " << bucket_info.owner << dendl;
-  if (rgw_get_user_info_by_uid(store, bucket_info.owner, s->user) < 0) {
+  ldout(s->cct, 20) << "temp url user (bucket owner): " << bucket_info.owner
+                    << dendl;
+  if (rgw_get_user_info_by_uid(store, bucket_info.owner, *(s->user)) < 0) {
     return -EPERM;
   }
 
-  if (s->user.temp_url_keys.empty()) {
+  if (s->user->temp_url_keys.empty()) {
     dout(5) << "user does not have temp url key set, aborting" << dendl;
     return -EPERM;
   }
 
-  if (!s->info.method)
+  if (!s->info.method) {
     return -EPERM;
+  }
 
-  utime_t now = ceph_clock_now(g_ceph_context);
+  const utime_t now = ceph_clock_now(g_ceph_context);
 
   string err;
-  uint64_t expiration = (uint64_t)strict_strtoll(temp_url_expires.c_str(), 10, &err);
+  uint64_t expiration = (uint64_t)strict_strtoll(temp_url_expires.c_str(),
+                                                 10, &err);
   if (!err.empty()) {
     dout(5) << "failed to parse temp_url_expires: " << err << dendl;
     return -EPERM;
@@ -603,32 +665,56 @@ int authenticate_temp_url(RGWRados *store, req_state *s)
     return -EPERM;
   }
 
-  /* strip the swift prefix from the uri */
-  int pos = g_conf->rgw_swift_url_prefix.find_last_not_of('/') + 1;
-  string object_path = s->info.request_uri.substr(pos + 1);
-  string str = string(s->info.method) + "\n" + temp_url_expires + "\n" + object_path;
+  /* We need to verify two paths because of compliance with Swift, Tempest
+   * and old versions of RadosGW. The second item will have the prefix
+   * of Swift API entry point removed. */
+  const size_t pos = g_conf->rgw_swift_url_prefix.find_last_not_of('/') + 1;
+  const vector<string> allowed_paths = {
+    s->info.request_uri,
+    s->info.request_uri.substr(pos + 1)
+  };
 
-  dout(20) << "temp url signature (plain text): " << str << dendl;
+  vector<string> allowed_methods;
+  if (strcmp("HEAD", s->info.method) == 0) {
+    /* HEAD requests are specially handled. */
+    allowed_methods = { s->info.method, "PUT", "GET" };
+  } else {
+    allowed_methods = { s->info.method };
+  }
 
-  map<int, string>::iterator iter;
-  for (iter = s->user.temp_url_keys.begin(); iter != s->user.temp_url_keys.end(); ++iter) {
-    string& temp_url_key = iter->second;
+  /* Need to try each combination of keys, allowed path and methods. */
+  for (const auto kv : s->user->temp_url_keys) {
+    const int temp_url_key_num = kv.first;
+    const string& temp_url_key = kv.second;
 
-    if (temp_url_key.empty())
+    if (temp_url_key.empty()) {
       continue;
+    }
 
-    char dest[CEPH_CRYPTO_HMACSHA1_DIGESTSIZE];
-    calc_hmac_sha1(temp_url_key.c_str(), temp_url_key.size(),
-                   str.c_str(), str.size(), dest);
-
-    char dest_str[CEPH_CRYPTO_HMACSHA1_DIGESTSIZE * 2 + 1];
-    buf_to_hex((const unsigned char *)dest, sizeof(dest), dest_str);
-    dout(20) << "temp url signature [" << iter->first << "] (calculated): " << dest_str << dendl;
-
-    if (dest_str != temp_url_sig) {
-      dout(5) << "temp url signature mismatch: " << dest_str << " != " << temp_url_sig << dendl;
-    } else {
-      return 0;
+    for (const auto path : allowed_paths) {
+      for (const auto method : allowed_methods) {
+        const string local_sig = temp_url_gen_sig(temp_url_key,
+                                                  method, path,
+                                                  temp_url_expires);
+
+        ldout(s->cct, 20) << "temp url signature [" << temp_url_key_num
+                          << "] (calculated): " << local_sig
+                          << dendl;
+
+        if (local_sig != temp_url_sig) {
+          ldout(s->cct,  5) << "temp url signature mismatch: " << local_sig
+                            << " != "
+                            << temp_url_sig
+                            << dendl;
+        } else {
+          temp_url_make_content_disp(s);
+          ldout(s->cct, 20) << "temp url signature match: " << local_sig
+                            << " content_disp override " << s->content_disp.override
+                            << " content_disp fallback " << s->content_disp.fallback
+                            << dendl;
+          return 0;
+        }
+      }
     }
   }
 
@@ -650,8 +736,8 @@ bool RGWSwift::verify_swift_token(RGWRados *store, req_state *s)
       subuser = s->swift_user.substr(pos + 1);
     }
     s->perm_mask = 0;
-    map<string, RGWSubUser>::iterator iter = s->user.subusers.find(subuser);
-    if (iter != s->user.subusers.end()) {
+    map<string, RGWSubUser>::iterator iter = s->user->subusers.find(subuser);
+    if (iter != s->user->subusers.end()) {
       RGWSubUser& subuser_ = iter->second;
       s->perm_mask = subuser_.perm_mask;
     }
@@ -665,30 +751,26 @@ bool RGWSwift::verify_swift_token(RGWRados *store, req_state *s)
 
 bool RGWSwift::do_verify_swift_token(RGWRados *store, req_state *s)
 {
-  if (!s->os_auth_token) {
+  if (s->info.args.exists("temp_url_sig") ||
+      s->info.args.exists("temp_url_expires")) {
     int ret = authenticate_temp_url(store, s);
     return (ret >= 0);
   }
 
   if (strncmp(s->os_auth_token, "AUTH_rgwtk", 10) == 0) {
-    int ret = rgw_swift_verify_signed_token(s->cct, store, s->os_auth_token, s->user, &s->swift_user);
-    if (ret < 0)
-      return false;
-
-    return  true;
+    int ret = rgw_swift_verify_signed_token(s->cct, store, s->os_auth_token,
+					    *(s->user), &s->swift_user);
+    return (ret >= 0);
   }
 
-  struct rgw_swift_auth_info info;
-
-  info.status = 401; // start with access denied, validate_token might change that
-
-  int ret;
-
   if (supports_keystone()) {
-    ret = validate_keystone_token(store, s->os_auth_token, &info, s->user);
+    int ret = validate_keystone_token(store, s->os_auth_token, *(s->user));
     return (ret >= 0);
   }
 
+  struct rgw_swift_auth_info info;
+  int ret;
+
   ret = validate_token(s->os_auth_token, &info);
   if (ret < 0)
     return false;
@@ -705,12 +787,12 @@ bool RGWSwift::do_verify_swift_token(RGWRados *store, req_state *s)
 
   ldout(cct, 10) << "swift user=" << s->swift_user << dendl;
 
-  if (rgw_get_user_info_by_swift(store, swift_user, s->user) < 0) {
+  if (rgw_get_user_info_by_swift(store, swift_user, *(s->user)) < 0) {
     ldout(cct, 0) << "NOTICE: couldn't map swift user" << dendl;
     return false;
   }
 
-  ldout(cct, 10) << "user_id=" << s->user.user_id << dendl;
+  ldout(cct, 10) << "user_id=" << s->user->user_id << dendl;
 
   return true;
 }
@@ -793,4 +875,3 @@ void RGWSwift::KeystoneRevokeThread::stop()
   Mutex::Locker l(lock);
   cond.Signal();
 }
-
diff --git a/src/rgw/rgw_swift.h b/src/rgw/rgw_swift.h
index ff449e9..d41d2ce 100644
--- a/src/rgw/rgw_swift.h
+++ b/src/rgw/rgw_swift.h
@@ -5,6 +5,8 @@
 #ifndef CEPH_RGW_SWIFT_H
 #define CEPH_RGW_SWIFT_H
 
+#include "include/assert.h"
+
 #include "rgw_common.h"
 #include "common/Cond.h"
 
@@ -12,13 +14,12 @@ class RGWRados;
 class KeystoneToken;
 
 struct rgw_swift_auth_info {
-  int status;
   string auth_groups;
   rgw_user user;
   string display_name;
   long long ttl;
 
-  rgw_swift_auth_info() : status(0), ttl(0) {}
+  rgw_swift_auth_info() : ttl(0) {}
 };
 
 class RGWSwift {
@@ -26,10 +27,12 @@ class RGWSwift {
   atomic_t down_flag;
 
   int validate_token(const char *token, struct rgw_swift_auth_info *info);
-  int validate_keystone_token(RGWRados *store, const string& token, struct rgw_swift_auth_info *info,
+  int validate_keystone_token(RGWRados *store, const string& token,
 			      RGWUserInfo& rgw_user);
 
-  int parse_keystone_token_response(const string& token, bufferlist& bl, struct rgw_swift_auth_info *info,
+  int parse_keystone_token_response(const string& token,
+                                    bufferlist& bl,
+                                    struct rgw_swift_auth_info *info,
 		                    KeystoneToken& t);
   int update_user_info(RGWRados *store, struct rgw_swift_auth_info *info, RGWUserInfo& user_info);
   int get_keystone_url(std::string& url);
diff --git a/src/rgw/rgw_swift_auth.cc b/src/rgw/rgw_swift_auth.cc
index 3e94e63..32234d7 100644
--- a/src/rgw/rgw_swift_auth.cc
+++ b/src/rgw/rgw_swift_auth.cc
@@ -17,7 +17,8 @@
 
 using namespace ceph::crypto;
 
-static int build_token(string& swift_user, string& key, uint64_t nonce, utime_t& expiration, bufferlist& bl)
+static int build_token(string& swift_user, string& key, uint64_t nonce,
+		       utime_t& expiration, bufferlist& bl)
 {
   ::encode(swift_user, bl);
   ::encode(nonce, bl);
@@ -43,7 +44,8 @@ static int build_token(string& swift_user, string& key, uint64_t nonce, utime_t&
 
 }
 
-static int encode_token(CephContext *cct, string& swift_user, string& key, bufferlist& bl)
+static int encode_token(CephContext *cct, string& swift_user, string& key,
+			bufferlist& bl)
 {
   uint64_t nonce;
 
@@ -59,7 +61,9 @@ static int encode_token(CephContext *cct, string& swift_user, string& key, buffe
   return ret;
 }
 
-int rgw_swift_verify_signed_token(CephContext *cct, RGWRados *store, const char *token, RGWUserInfo& info, string *pswift_user)
+int rgw_swift_verify_signed_token(CephContext *cct, RGWRados *store,
+				  const char *token, RGWUserInfo& info,
+				  string *pswift_user)
 {
   if (strncmp(token, "AUTH_rgwtk", 10) != 0)
     return -EINVAL;
@@ -68,7 +72,8 @@ int rgw_swift_verify_signed_token(CephContext *cct, RGWRados *store, const char
 
   int len = strlen(token);
   if (len & 1) {
-    dout(0) << "NOTICE: failed to verify token: invalid token length len=" << len << dendl;
+    dout(0) << "NOTICE: failed to verify token: invalid token length len="
+	    << len << dendl;
     return -EINVAL;
   }
 
@@ -96,7 +101,8 @@ int rgw_swift_verify_signed_token(CephContext *cct, RGWRados *store, const char
   }
   utime_t now = ceph_clock_now(cct);
   if (expiration < now) {
-    dout(0) << "NOTICE: old timed out token was used now=" << now << " token.expiration=" << expiration << dendl;
+    dout(0) << "NOTICE: old timed out token was used now=" << now
+	    << " token.expiration=" << expiration << dendl;
     return -EPERM;
   }
 
@@ -116,7 +122,8 @@ int rgw_swift_verify_signed_token(CephContext *cct, RGWRados *store, const char
     return ret;
 
   if (tok.length() != bl.length()) {
-    dout(0) << "NOTICE: tokens length mismatch: bl.length()=" << bl.length() << " tok.length()=" << tok.length() << dendl;
+    dout(0) << "NOTICE: tokens length mismatch: bl.length()=" << bl.length()
+	    << " tok.length()=" << tok.length() << dendl;
     return -EPERM;
   }
 
@@ -179,7 +186,6 @@ void RGW_SWIFT_Auth_Get::execute()
     }
   }
 
-
   if (!key || !user)
     goto done;
 
@@ -207,10 +213,13 @@ void RGW_SWIFT_Auth_Get::execute()
   if (!g_conf->rgw_swift_tenant_name.empty()) {
     tenant_path = "/AUTH_";
     tenant_path.append(g_conf->rgw_swift_tenant_name);
+  } else if (g_conf->rgw_swift_account_in_url) {
+    tenant_path = "/AUTH_";
+    tenant_path.append(user_str);
   }
 
-  s->cio->print("X-Storage-Url: %s/%s/v1%s\r\n", swift_url.c_str(),
-	        swift_prefix.c_str(), tenant_path.c_str());
+  STREAM_IO(s)->print("X-Storage-Url: %s/%s/v1%s\r\n", swift_url.c_str(),
+		swift_prefix.c_str(), tenant_path.c_str());
 
   if ((ret = encode_token(s->cct, swift_key->id, swift_key->key, bl)) < 0)
     goto done;
@@ -219,8 +228,8 @@ void RGW_SWIFT_Auth_Get::execute()
     char buf[bl.length() * 2 + 1];
     buf_to_hex((const unsigned char *)bl.c_str(), bl.length(), buf);
 
-    s->cio->print("X-Storage-Token: AUTH_rgwtk%s\r\n", buf);
-    s->cio->print("X-Auth-Token: AUTH_rgwtk%s\r\n", buf);
+    STREAM_IO(s)->print("X-Storage-Token: AUTH_rgwtk%s\r\n", buf);
+    STREAM_IO(s)->print("X-Auth-Token: AUTH_rgwtk%s\r\n", buf);
   }
 
   ret = STATUS_NO_CONTENT;
@@ -231,7 +240,8 @@ done:
   end_header(s);
 }
 
-int RGWHandler_SWIFT_Auth::init(RGWRados *store, struct req_state *state, RGWClientIO *cio)
+int RGWHandler_SWIFT_Auth::init(RGWRados *store, struct req_state *state,
+				RGWClientIO *cio)
 {
   state->dialect = "swift-auth";
   state->formatter = new JSONFormatter;
diff --git a/src/rgw/rgw_swift_auth.h b/src/rgw/rgw_swift_auth.h
index 6b19d04..be835fc 100644
--- a/src/rgw/rgw_swift_auth.h
+++ b/src/rgw/rgw_swift_auth.h
@@ -21,7 +21,7 @@ public:
   virtual const string name() { return "swift_auth_get"; }
 };
 
-class RGWHandler_SWIFT_Auth : public RGWHandler {
+class RGWHandler_SWIFT_Auth : public RGWHandler_REST {
 public:
   RGWHandler_SWIFT_Auth() {}
   ~RGWHandler_SWIFT_Auth() {}
@@ -44,7 +44,7 @@ public:
   virtual RGWRESTMgr *get_resource_mgr(struct req_state *s, const string& uri, string *out_uri) {
     return this;
   }
-  virtual RGWHandler *get_handler(struct req_state *s) {
+  virtual RGWHandler_REST* get_handler(struct req_state *s) {
     return new RGWHandler_SWIFT_Auth;
   }
 };
diff --git a/src/rgw/rgw_sync.cc b/src/rgw/rgw_sync.cc
new file mode 100644
index 0000000..bb3a1ac
--- /dev/null
+++ b/src/rgw/rgw_sync.cc
@@ -0,0 +1,2157 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+
+#include "common/ceph_json.h"
+#include "common/RWLock.h"
+#include "common/RefCountedObj.h"
+#include "common/WorkQueue.h"
+#include "common/Throttle.h"
+#include "common/admin_socket.h"
+#include "common/errno.h"
+
+#include "rgw_common.h"
+#include "rgw_rados.h"
+#include "rgw_sync.h"
+#include "rgw_metadata.h"
+#include "rgw_rest_conn.h"
+#include "rgw_tools.h"
+#include "rgw_cr_rados.h"
+#include "rgw_cr_rest.h"
+#include "rgw_http_client.h"
+#include "rgw_boost_asio_yield.h"
+
+#include "cls/lock/cls_lock_client.h"
+
+#define dout_subsys ceph_subsys_rgw
+
+#undef dout_prefix
+#define dout_prefix (*_dout << "rgw meta sync: ")
+
+static string mdlog_sync_status_oid = "mdlog.sync-status";
+static string mdlog_sync_status_shard_prefix = "mdlog.sync-status.shard";
+static string mdlog_sync_full_sync_index_prefix = "meta.full-sync.index";
+
+RGWSyncErrorLogger::RGWSyncErrorLogger(RGWRados *_store, const string oid_prefix, int _num_shards) : store(_store), num_shards(_num_shards) {
+  for (int i = 0; i < num_shards; i++) {
+    oids.push_back(get_shard_oid(oid_prefix, i));
+  }
+}
+string RGWSyncErrorLogger::get_shard_oid(const string& oid_prefix, int shard_id) {
+  char buf[oid_prefix.size() + 16];
+  snprintf(buf, sizeof(buf), "%s.%d", oid_prefix.c_str(), shard_id);
+  return string(buf);
+}
+
+RGWCoroutine *RGWSyncErrorLogger::log_error_cr(const string& source_zone, const string& section, const string& name, uint32_t error_code, const string& message) {
+  cls_log_entry entry;
+
+  rgw_sync_error_info info(source_zone, error_code, message);
+  bufferlist bl;
+  ::encode(info, bl);
+  store->time_log_prepare_entry(entry, real_clock::now(), section, name, bl);
+
+  uint32_t shard_id = counter.inc() % num_shards;
+
+
+  return new RGWRadosTimelogAddCR(store, oids[shard_id], entry);
+}
+
+void RGWSyncBackoff::update_wait_time()
+{
+  if (cur_wait == 0) {
+    cur_wait = 1;
+  } else {
+    cur_wait = (cur_wait << 1);
+  }
+  if (cur_wait >= max_secs) {
+    cur_wait = max_secs;
+  }
+}
+
+void RGWSyncBackoff::backoff_sleep()
+{
+  update_wait_time();
+  sleep(cur_wait);
+}
+
+void RGWSyncBackoff::backoff(RGWCoroutine *op)
+{
+  update_wait_time();
+  op->wait(utime_t(cur_wait, 0));
+}
+
+int RGWBackoffControlCR::operate() {
+  RGWCoroutine *finisher_cr;
+  reenter(this) {
+    while (true) {
+      yield {
+        Mutex::Locker l(lock);
+        cr = alloc_cr();
+        cr->get();
+        call(cr);
+      }
+      {
+        Mutex::Locker l(lock);
+        cr->put();
+        cr = NULL;
+      }
+      if (retcode < 0 && retcode != -EBUSY && retcode != -EAGAIN) {
+        ldout(cct, 0) << "ERROR: RGWBackoffControlCR called coroutine returned " << retcode << dendl;
+        if (exit_on_error) {
+          return set_cr_error(retcode);
+        }
+      }
+      if (reset_backoff) {
+        backoff.reset();
+      }
+      yield backoff.backoff(this);
+      finisher_cr = alloc_finisher_cr();
+      if (finisher_cr) {
+        yield call(finisher_cr);
+        if (retcode < 0) {
+          ldout(cct, 0) << "ERROR: call to finisher_cr() failed: retcode=" << retcode << dendl;
+          if (exit_on_error) {
+            return set_cr_error(retcode);
+          }
+        }
+      }
+    }
+  }
+  return 0;
+}
+
+void rgw_mdlog_info::decode_json(JSONObj *obj) {
+  JSONDecoder::decode_json("num_objects", num_shards, obj);
+  JSONDecoder::decode_json("period", period, obj);
+  JSONDecoder::decode_json("realm_epoch", realm_epoch, obj);
+}
+
+void rgw_mdlog_entry::decode_json(JSONObj *obj) {
+  JSONDecoder::decode_json("id", id, obj);
+  JSONDecoder::decode_json("section", section, obj);
+  JSONDecoder::decode_json("name", name, obj);
+  utime_t ut;
+  JSONDecoder::decode_json("timestamp", ut, obj);
+  timestamp = ut.to_real_time();
+  JSONDecoder::decode_json("data", log_data, obj);
+}
+
+void rgw_mdlog_shard_data::decode_json(JSONObj *obj) {
+  JSONDecoder::decode_json("marker", marker, obj);
+  JSONDecoder::decode_json("truncated", truncated, obj);
+  JSONDecoder::decode_json("entries", entries, obj);
+};
+
+int RGWShardCollectCR::operate() {
+  reenter(this) {
+    while (spawn_next()) {
+      current_running++;
+
+      while (current_running >= max_concurrent) {
+        int child_ret;
+        yield wait_for_child();
+        if (collect_next(&child_ret)) {
+          current_running--;
+          if (child_ret < 0 && child_ret != -ENOENT) {
+            ldout(cct, 10) << __func__ << ": failed to fetch log status, ret=" << child_ret << dendl;
+            status = child_ret;
+          }
+        }
+      }
+    }
+    while (current_running > 0) {
+      int child_ret;
+      yield wait_for_child();
+      if (collect_next(&child_ret)) {
+        current_running--;
+        if (child_ret < 0 && child_ret != -ENOENT) {
+          ldout(cct, 10) << __func__ << ": failed to fetch log status, ret=" << child_ret << dendl;
+          status = child_ret;
+        }
+      }
+    }
+    if (status < 0) {
+      return set_cr_error(status);
+    }
+    return set_cr_done();
+  }
+  return 0;
+}
+
+class RGWReadRemoteMDLogInfoCR : public RGWShardCollectCR {
+  RGWMetaSyncEnv *sync_env;
+
+  const std::string& period;
+  int num_shards;
+  map<int, RGWMetadataLogInfo> *mdlog_info;
+
+  int shard_id;
+#define READ_MDLOG_MAX_CONCURRENT 10
+
+public:
+  RGWReadRemoteMDLogInfoCR(RGWMetaSyncEnv *_sync_env,
+                     const std::string& period, int _num_shards,
+                     map<int, RGWMetadataLogInfo> *_mdlog_info) : RGWShardCollectCR(_sync_env->cct, READ_MDLOG_MAX_CONCURRENT),
+                                                                 sync_env(_sync_env),
+                                                                 period(period), num_shards(_num_shards),
+                                                                 mdlog_info(_mdlog_info), shard_id(0) {}
+  bool spawn_next();
+};
+
+class RGWListRemoteMDLogCR : public RGWShardCollectCR {
+  RGWMetaSyncEnv *sync_env;
+
+  const std::string& period;
+  map<int, string> shards;
+  int max_entries_per_shard;
+  map<int, rgw_mdlog_shard_data> *result;
+
+  map<int, string>::iterator iter;
+#define READ_MDLOG_MAX_CONCURRENT 10
+
+public:
+  RGWListRemoteMDLogCR(RGWMetaSyncEnv *_sync_env,
+                     const std::string& period, map<int, string>& _shards,
+                     int _max_entries_per_shard,
+                     map<int, rgw_mdlog_shard_data> *_result) : RGWShardCollectCR(_sync_env->cct, READ_MDLOG_MAX_CONCURRENT),
+                                                                 sync_env(_sync_env), period(period),
+                                                                 max_entries_per_shard(_max_entries_per_shard),
+                                                                 result(_result) {
+    shards.swap(_shards);
+    iter = shards.begin();
+  }
+  bool spawn_next();
+};
+
+RGWRemoteMetaLog::~RGWRemoteMetaLog()
+{
+  delete error_logger;
+}
+
+int RGWRemoteMetaLog::read_log_info(rgw_mdlog_info *log_info)
+{
+  rgw_http_param_pair pairs[] = { { "type", "metadata" },
+                                  { NULL, NULL } };
+
+  int ret = conn->get_json_resource("/admin/log", pairs, *log_info);
+  if (ret < 0) {
+    ldout(store->ctx(), 0) << "ERROR: failed to fetch mdlog info" << dendl;
+    return ret;
+  }
+
+  ldout(store->ctx(), 20) << "remote mdlog, num_shards=" << log_info->num_shards << dendl;
+
+  return 0;
+}
+
+int RGWRemoteMetaLog::read_master_log_shards_info(string *master_period, map<int, RGWMetadataLogInfo> *shards_info)
+{
+  if (store->is_meta_master()) {
+    return 0;
+  }
+
+  rgw_mdlog_info log_info;
+  int ret = read_log_info(&log_info);
+  if (ret < 0) {
+    return ret;
+  }
+
+  *master_period = log_info.period;
+
+  return run(new RGWReadRemoteMDLogInfoCR(&sync_env, log_info.period, log_info.num_shards, shards_info));
+}
+
+int RGWRemoteMetaLog::read_master_log_shards_next(const string& period, map<int, string> shard_markers, map<int, rgw_mdlog_shard_data> *result)
+{
+  if (store->is_meta_master()) {
+    return 0;
+  }
+
+  return run(new RGWListRemoteMDLogCR(&sync_env, period, shard_markers, 1, result));
+}
+
+int RGWRemoteMetaLog::init()
+{
+  conn = store->rest_master_conn;
+
+  int ret = http_manager.set_threaded();
+  if (ret < 0) {
+    ldout(store->ctx(), 0) << "failed in http_manager.set_threaded() ret=" << ret << dendl;
+    return ret;
+  }
+
+  error_logger = new RGWSyncErrorLogger(store, RGW_SYNC_ERROR_LOG_SHARD_PREFIX, ERROR_LOGGER_SHARDS);
+
+  init_sync_env(&sync_env);
+
+  return 0;
+}
+
+void RGWRemoteMetaLog::finish()
+{
+  going_down.set(1);
+  stop();
+}
+
+#define CLONE_MAX_ENTRIES 100
+
+int RGWMetaSyncStatusManager::init()
+{
+  if (store->is_meta_master()) {
+    return 0;
+  }
+
+  if (!store->rest_master_conn) {
+    lderr(store->ctx()) << "no REST connection to master zone" << dendl;
+    return -EIO;
+  }
+
+  const char *log_pool = store->get_zone_params().log_pool.name.c_str();
+  librados::Rados *rados = store->get_rados_handle();
+  int r = rados->ioctx_create(log_pool, ioctx);
+  if (r < 0) {
+    lderr(store->ctx()) << "ERROR: failed to open log pool (" << store->get_zone_params().log_pool.name << " ret=" << r << dendl;
+    return r;
+  }
+
+  r = master_log.init();
+  if (r < 0) {
+    lderr(store->ctx()) << "ERROR: failed to init remote log, r=" << r << dendl;
+    return r;
+  }
+
+  RGWMetaSyncEnv& sync_env = master_log.get_sync_env();
+
+  r = read_sync_status();
+  if (r < 0 && r != -ENOENT) {
+    lderr(store->ctx()) << "ERROR: failed to read sync status, r=" << r << dendl;
+    return r;
+  }
+
+  int num_shards = master_log.get_sync_status().sync_info.num_shards;
+
+  for (int i = 0; i < num_shards; i++) {
+    shard_objs[i] = rgw_obj(store->get_zone_params().log_pool, sync_env.shard_obj_name(i));
+  }
+
+  RWLock::WLocker wl(ts_to_shard_lock);
+  for (int i = 0; i < num_shards; i++) {
+    clone_markers.push_back(string());
+    utime_shard ut;
+    ut.shard_id = i;
+    ts_to_shard[ut] = i;
+  }
+
+  return 0;
+}
+
+void RGWMetaSyncEnv::init(CephContext *_cct, RGWRados *_store, RGWRESTConn *_conn,
+                          RGWAsyncRadosProcessor *_async_rados, RGWHTTPManager *_http_manager,
+                          RGWSyncErrorLogger *_error_logger) {
+  cct = _cct;
+  store = _store;
+  conn = _conn;
+  async_rados = _async_rados;
+  http_manager = _http_manager;
+  error_logger = _error_logger;
+}
+
+string RGWMetaSyncEnv::status_oid()
+{
+  return mdlog_sync_status_oid;
+}
+
+string RGWMetaSyncEnv::shard_obj_name(int shard_id)
+{
+  char buf[mdlog_sync_status_shard_prefix.size() + 16];
+  snprintf(buf, sizeof(buf), "%s.%d", mdlog_sync_status_shard_prefix.c_str(), shard_id);
+
+  return string(buf);
+}
+
+class RGWAsyncReadMDLogEntries : public RGWAsyncRadosRequest {
+  RGWRados *store;
+  RGWMetadataLog *mdlog;
+  int shard_id;
+  string *marker;
+  int max_entries;
+  list<cls_log_entry> *entries;
+  bool *truncated;
+
+protected:
+  int _send_request() {
+    real_time from_time;
+    real_time end_time;
+
+    void *handle;
+
+    mdlog->init_list_entries(shard_id, from_time, end_time, *marker, &handle);
+
+    int ret = mdlog->list_entries(handle, max_entries, *entries, marker, truncated);
+
+    mdlog->complete_list_entries(handle);
+
+    return ret;
+  }
+public:
+  RGWAsyncReadMDLogEntries(RGWCoroutine *caller, RGWAioCompletionNotifier *cn, RGWRados *_store,
+                           RGWMetadataLog* mdlog, int _shard_id,
+                           string* _marker, int _max_entries,
+                           list<cls_log_entry> *_entries, bool *_truncated)
+    : RGWAsyncRadosRequest(caller, cn), store(_store), mdlog(mdlog),
+      shard_id(_shard_id), marker(_marker), max_entries(_max_entries),
+      entries(_entries), truncated(_truncated) {}
+};
+
+class RGWReadMDLogEntriesCR : public RGWSimpleCoroutine {
+  RGWMetaSyncEnv *sync_env;
+  RGWMetadataLog *const mdlog;
+  int shard_id;
+  string marker;
+  string *pmarker;
+  int max_entries;
+  list<cls_log_entry> *entries;
+  bool *truncated;
+
+  RGWAsyncReadMDLogEntries *req;
+
+public:
+  RGWReadMDLogEntriesCR(RGWMetaSyncEnv *_sync_env, RGWMetadataLog* mdlog,
+                        int _shard_id, string*_marker, int _max_entries,
+                        list<cls_log_entry> *_entries, bool *_truncated)
+    : RGWSimpleCoroutine(_sync_env->cct), sync_env(_sync_env), mdlog(mdlog),
+      shard_id(_shard_id), pmarker(_marker), max_entries(_max_entries),
+      entries(_entries), truncated(_truncated) {}
+
+  ~RGWReadMDLogEntriesCR() {
+    if (req) {
+      req->finish();
+    }
+  }
+
+  int send_request() {
+    marker = *pmarker;
+    req = new RGWAsyncReadMDLogEntries(this, stack->create_completion_notifier(),
+                                       sync_env->store, mdlog, shard_id, &marker,
+                                       max_entries, entries, truncated);
+    sync_env->async_rados->queue(req);
+    return 0;
+  }
+
+  int request_complete() {
+    int ret = req->get_ret_status();
+    if (ret >= 0 && !entries->empty()) {
+     *pmarker = marker;
+    }
+    return req->get_ret_status();
+  }
+};
+
+
+class RGWReadRemoteMDLogShardInfoCR : public RGWCoroutine {
+  RGWMetaSyncEnv *env;
+  RGWRESTReadResource *http_op;
+
+  const std::string& period;
+  int shard_id;
+  RGWMetadataLogInfo *shard_info;
+
+public:
+  RGWReadRemoteMDLogShardInfoCR(RGWMetaSyncEnv *env, const std::string& period,
+                                int _shard_id, RGWMetadataLogInfo *_shard_info)
+    : RGWCoroutine(env->store->ctx()), env(env), http_op(NULL),
+      period(period), shard_id(_shard_id), shard_info(_shard_info) {}
+
+  int operate() {
+    auto store = env->store;
+    RGWRESTConn *conn = store->rest_master_conn;
+    reenter(this) {
+      yield {
+	char buf[16];
+	snprintf(buf, sizeof(buf), "%d", shard_id);
+        rgw_http_param_pair pairs[] = { { "type" , "metadata" },
+	                                { "id", buf },
+	                                { "period", period.c_str() },
+					{ "info" , NULL },
+	                                { NULL, NULL } };
+
+        string p = "/admin/log/";
+
+        http_op = new RGWRESTReadResource(conn, p, pairs, NULL,
+                                          env->http_manager);
+
+        http_op->set_user_info((void *)stack);
+
+        int ret = http_op->aio_read();
+        if (ret < 0) {
+          ldout(store->ctx(), 0) << "ERROR: failed to read from " << p << dendl;
+          log_error() << "failed to send http operation: " << http_op->to_str() << " ret=" << ret << std::endl;
+          http_op->put();
+          return set_cr_error(ret);
+        }
+
+        return io_block(0);
+      }
+      yield {
+        int ret = http_op->wait(shard_info);
+        if (ret < 0) {
+          return set_cr_error(ret);
+        }
+        return set_cr_done();
+      }
+    }
+    return 0;
+  }
+};
+
+class RGWListRemoteMDLogShardCR : public RGWSimpleCoroutine {
+  RGWMetaSyncEnv *sync_env;
+  RGWRESTReadResource *http_op;
+
+  const std::string& period;
+  int shard_id;
+  string marker;
+  uint32_t max_entries;
+  rgw_mdlog_shard_data *result;
+
+public:
+  RGWListRemoteMDLogShardCR(RGWMetaSyncEnv *env, const std::string& period,
+                            int _shard_id, const string& _marker, uint32_t _max_entries,
+                            rgw_mdlog_shard_data *_result)
+    : RGWSimpleCoroutine(env->store->ctx()), sync_env(env), http_op(NULL),
+      period(period), shard_id(_shard_id), marker(_marker), max_entries(_max_entries), result(_result) {}
+
+  int send_request() {
+    RGWRESTConn *conn = sync_env->conn;
+    RGWRados *store = sync_env->store;
+
+    char buf[32];
+    snprintf(buf, sizeof(buf), "%d", shard_id);
+
+    char max_entries_buf[32];
+    snprintf(max_entries_buf, sizeof(max_entries_buf), "%d", (int)max_entries);
+
+    const char *marker_key = (marker.empty() ? "" : "marker");
+
+    rgw_http_param_pair pairs[] = { { "type", "metadata" },
+      { "id", buf },
+      { "period", period.c_str() },
+      { "max-entries", max_entries_buf },
+      { marker_key, marker.c_str() },
+      { NULL, NULL } };
+
+    string p = "/admin/log/";
+
+    http_op = new RGWRESTReadResource(conn, p, pairs, NULL, sync_env->http_manager);
+    http_op->set_user_info((void *)stack);
+
+    int ret = http_op->aio_read();
+    if (ret < 0) {
+      ldout(store->ctx(), 0) << "ERROR: failed to read from " << p << dendl;
+      log_error() << "failed to send http operation: " << http_op->to_str() << " ret=" << ret << std::endl;
+      http_op->put();
+      return ret;
+    }
+
+    return 0;
+  }
+
+  int request_complete() {
+    int ret = http_op->wait(result);
+    if (ret < 0 && ret != -ENOENT) {
+      ldout(sync_env->store->ctx(), 0) << "ERROR: failed to list remote mdlog shard, ret=" << ret << dendl;
+      return ret;
+    }
+    return 0;
+  }
+};
+
+bool RGWReadRemoteMDLogInfoCR::spawn_next() {
+  if (shard_id >= num_shards) {
+    return false;
+  }
+  spawn(new RGWReadRemoteMDLogShardInfoCR(sync_env, period, shard_id, &(*mdlog_info)[shard_id]), false);
+  shard_id++;
+  return true;
+}
+
+bool RGWListRemoteMDLogCR::spawn_next() {
+  if (iter == shards.end()) {
+    return false;
+  }
+
+  spawn(new RGWListRemoteMDLogShardCR(sync_env, period, iter->first, iter->second, max_entries_per_shard, &(*result)[iter->first]), false);
+  ++iter;
+  return true;
+}
+
+class RGWInitSyncStatusCoroutine : public RGWCoroutine {
+  RGWMetaSyncEnv *sync_env;
+  RGWObjectCtx& obj_ctx;
+
+  rgw_meta_sync_info status;
+  vector<RGWMetadataLogInfo> shards_info;
+  RGWContinuousLeaseCR *lease_cr;
+public:
+  RGWInitSyncStatusCoroutine(RGWMetaSyncEnv *_sync_env,
+                             RGWObjectCtx& _obj_ctx,
+                             const rgw_meta_sync_info &status)
+    : RGWCoroutine(_sync_env->store->ctx()), sync_env(_sync_env),
+      obj_ctx(_obj_ctx), status(status), shards_info(status.num_shards),
+      lease_cr(NULL) {}
+
+  ~RGWInitSyncStatusCoroutine() {
+    if (lease_cr) {
+      lease_cr->abort();
+      lease_cr->put();
+    }
+  }
+
+  int operate() {
+    int ret;
+    reenter(this) {
+      yield {
+        set_status("acquiring sync lock");
+	uint32_t lock_duration = cct->_conf->rgw_sync_lease_period;
+        string lock_name = "sync_lock";
+        RGWRados *store = sync_env->store;
+	lease_cr = new RGWContinuousLeaseCR(sync_env->async_rados, store, store->get_zone_params().log_pool, sync_env->status_oid(),
+                                            lock_name, lock_duration, this);
+        lease_cr->get();
+        spawn(lease_cr, false);
+      }
+      while (!lease_cr->is_locked()) {
+        if (lease_cr->is_done()) {
+          ldout(cct, 0) << "ERROR: lease cr failed, done early " << dendl;
+          set_status("lease lock failed, early abort");
+          return set_cr_error(lease_cr->get_ret_status());
+        }
+        set_sleeping(true);
+        yield;
+      }
+      yield {
+        set_status("writing sync status");
+        RGWRados *store = sync_env->store;
+        call(new RGWSimpleRadosWriteCR<rgw_meta_sync_info>(sync_env->async_rados, store, store->get_zone_params().log_pool,
+				 sync_env->status_oid(), status));
+      }
+
+      if (retcode < 0) {
+        set_status("failed to write sync status");
+        ldout(cct, 0) << "ERROR: failed to write sync status, retcode=" << retcode << dendl;
+        yield lease_cr->go_down();
+        return set_cr_error(retcode);
+      }
+      /* fetch current position in logs */
+      set_status("fetching remote log position");
+      yield {
+        for (int i = 0; i < (int)status.num_shards; i++) {
+          spawn(new RGWReadRemoteMDLogShardInfoCR(sync_env, status.period, i,
+                                                  &shards_info[i]), false);
+	}
+      }
+
+      drain_all_but(1); /* the lease cr still needs to run */
+
+      yield {
+        set_status("updating sync status");
+        for (int i = 0; i < (int)status.num_shards; i++) {
+	  rgw_meta_sync_marker marker;
+          RGWMetadataLogInfo& info = shards_info[i];
+	  marker.next_step_marker = info.marker;
+	  marker.timestamp = info.last_update;
+          RGWRados *store = sync_env->store;
+          spawn(new RGWSimpleRadosWriteCR<rgw_meta_sync_marker>(sync_env->async_rados, store, store->get_zone_params().log_pool,
+				                          sync_env->shard_obj_name(i), marker), true);
+        }
+      }
+      yield {
+        set_status("changing sync state: build full sync maps");
+	status.state = rgw_meta_sync_info::StateBuildingFullSyncMaps;
+        RGWRados *store = sync_env->store;
+        call(new RGWSimpleRadosWriteCR<rgw_meta_sync_info>(sync_env->async_rados, store, store->get_zone_params().log_pool,
+				 sync_env->status_oid(), status));
+      }
+      set_status("drop lock lease");
+      yield lease_cr->go_down();
+      while (collect(&ret)) {
+	if (ret < 0) {
+	  return set_cr_error(ret);
+	}
+        yield;
+      }
+      drain_all();
+      return set_cr_done();
+    }
+    return 0;
+  }
+};
+
+class RGWReadSyncStatusCoroutine : public RGWSimpleRadosReadCR<rgw_meta_sync_info> {
+  RGWMetaSyncEnv *sync_env;
+  RGWObjectCtx& obj_ctx;
+
+  rgw_meta_sync_status *sync_status;
+
+public:
+  RGWReadSyncStatusCoroutine(RGWMetaSyncEnv *_sync_env,
+		      RGWObjectCtx& _obj_ctx,
+		      rgw_meta_sync_status *_status) : RGWSimpleRadosReadCR(_sync_env->async_rados, _sync_env->store, _obj_ctx,
+									    _sync_env->store->get_zone_params().log_pool,
+									    _sync_env->status_oid(),
+									    &_status->sync_info),
+                                                                            sync_env(_sync_env),
+                                                                            obj_ctx(_obj_ctx),
+									    sync_status(_status) {
+
+  }
+
+  int handle_data(rgw_meta_sync_info& data);
+};
+
+int RGWReadSyncStatusCoroutine::handle_data(rgw_meta_sync_info& data)
+{
+  if (retcode == -ENOENT) {
+    return retcode;
+  }
+
+  RGWRados *store = sync_env->store;
+  map<uint32_t, rgw_meta_sync_marker>& markers = sync_status->sync_markers;
+  for (int i = 0; i < (int)data.num_shards; i++) {
+    spawn(new RGWSimpleRadosReadCR<rgw_meta_sync_marker>(sync_env->async_rados, store, obj_ctx, store->get_zone_params().log_pool,
+				                    sync_env->shard_obj_name(i), &markers[i]), true);
+  }
+  return 0;
+}
+
+class RGWFetchAllMetaCR : public RGWCoroutine {
+  RGWMetaSyncEnv *sync_env;
+
+  int num_shards;
+
+
+  int ret_status;
+
+  list<string> sections;
+  list<string>::iterator sections_iter;
+  list<string> result;
+  list<string>::iterator iter;
+
+  RGWShardedOmapCRManager *entries_index;
+
+  RGWContinuousLeaseCR *lease_cr;
+  bool lost_lock;
+  bool failed;
+
+  map<uint32_t, rgw_meta_sync_marker>& markers;
+
+public:
+  RGWFetchAllMetaCR(RGWMetaSyncEnv *_sync_env, int _num_shards,
+                    map<uint32_t, rgw_meta_sync_marker>& _markers) : RGWCoroutine(_sync_env->cct), sync_env(_sync_env),
+						      num_shards(_num_shards),
+						      ret_status(0), entries_index(NULL), lease_cr(NULL), lost_lock(false), failed(false), markers(_markers) {
+  }
+
+  ~RGWFetchAllMetaCR() {
+    if (lease_cr) {
+      lease_cr->put();
+    }
+  }
+
+  void append_section_from_set(set<string>& all_sections, const string& name) {
+    set<string>::iterator iter = all_sections.find(name);
+    if (iter != all_sections.end()) {
+      sections.emplace_back(std::move(*iter));
+      all_sections.erase(iter);
+    }
+  }
+  /*
+   * meta sync should go in the following order: user, bucket.instance, bucket
+   * then whatever other sections exist (if any)
+   */
+  void rearrange_sections() {
+    set<string> all_sections;
+    std::move(sections.begin(), sections.end(),
+              std::inserter(all_sections, all_sections.end()));
+    sections.clear();
+
+    append_section_from_set(all_sections, "user");
+    append_section_from_set(all_sections, "bucket.instance");
+    append_section_from_set(all_sections, "bucket");
+
+    std::move(all_sections.begin(), all_sections.end(),
+              std::back_inserter(sections));
+  }
+
+  int operate() {
+    RGWRESTConn *conn = sync_env->conn;
+
+    reenter(this) {
+      yield {
+        set_status(string("acquiring lock (") + sync_env->status_oid() + ")");
+	uint32_t lock_duration = cct->_conf->rgw_sync_lease_period;
+        string lock_name = "sync_lock";
+	lease_cr = new RGWContinuousLeaseCR(sync_env->async_rados, sync_env->store, sync_env->store->get_zone_params().log_pool, sync_env->status_oid(),
+                                            lock_name, lock_duration, this);
+        lease_cr->get();
+        spawn(lease_cr, false);
+      }
+      while (!lease_cr->is_locked()) {
+        if (lease_cr->is_done()) {
+          ldout(cct, 0) << "ERROR: lease cr failed, done early " << dendl;
+          set_status("failed acquiring lock");
+          return set_cr_error(lease_cr->get_ret_status());
+        }
+        set_sleeping(true);
+        yield;
+      }
+      entries_index = new RGWShardedOmapCRManager(sync_env->async_rados, sync_env->store, this, num_shards,
+						  sync_env->store->get_zone_params().log_pool,
+                                                  mdlog_sync_full_sync_index_prefix);
+      yield {
+	call(new RGWReadRESTResourceCR<list<string> >(cct, conn, sync_env->http_manager,
+				       "/admin/metadata", NULL, &sections));
+      }
+      if (get_ret_status() < 0) {
+        ldout(cct, 0) << "ERROR: failed to fetch metadata sections" << dendl;
+        yield lease_cr->go_down();
+        drain_all();
+	return set_cr_error(get_ret_status());
+      }
+      rearrange_sections();
+      sections_iter = sections.begin();
+      for (; sections_iter != sections.end(); ++sections_iter) {
+        yield {
+	  string entrypoint = string("/admin/metadata/") + *sections_iter;
+          /* FIXME: need a better scaling solution here, requires streaming output */
+	  call(new RGWReadRESTResourceCR<list<string> >(cct, conn, sync_env->http_manager,
+				       entrypoint, NULL, &result));
+	}
+        if (get_ret_status() < 0) {
+          ldout(cct, 0) << "ERROR: failed to fetch metadata section: " << *sections_iter << dendl;
+          yield lease_cr->go_down();
+          drain_all();
+          return set_cr_error(get_ret_status());
+        }
+        iter = result.begin();
+        for (; iter != result.end(); ++iter) {
+          RGWRados *store;
+          int ret;
+          yield {
+            if (!lease_cr->is_locked()) {
+              lost_lock = true;
+              break;
+            }
+	    ldout(cct, 20) << "list metadata: section=" << *sections_iter << " key=" << *iter << dendl;
+	    string s = *sections_iter + ":" + *iter;
+            int shard_id;
+            store = sync_env->store;
+            ret = store->meta_mgr->get_log_shard_id(*sections_iter, *iter, &shard_id);
+            if (ret < 0) {
+              ldout(cct, 0) << "ERROR: could not determine shard id for " << *sections_iter << ":" << *iter << dendl;
+              ret_status = ret;
+              break;
+            }
+	    if (!entries_index->append(s, shard_id)) {
+              break;
+            }
+	  }
+	}
+      }
+      yield {
+        if (!entries_index->finish()) {
+          failed = true;
+        }
+      }
+      if (!failed) {
+        for (map<uint32_t, rgw_meta_sync_marker>::iterator iter = markers.begin(); iter != markers.end(); ++iter) {
+          int shard_id = (int)iter->first;
+          rgw_meta_sync_marker& marker = iter->second;
+          marker.total_entries = entries_index->get_total_entries(shard_id);
+          spawn(new RGWSimpleRadosWriteCR<rgw_meta_sync_marker>(sync_env->async_rados, sync_env->store, sync_env->store->get_zone_params().log_pool,
+                                                                sync_env->shard_obj_name(shard_id), marker), true);
+        }
+      }
+
+      drain_all_but(1); /* the lease cr still needs to run */
+
+      yield lease_cr->go_down();
+
+      int ret;
+      while (collect(&ret)) {
+	if (ret < 0) {
+	  return set_cr_error(ret);
+	}
+        yield;
+      }
+      drain_all();
+      if (failed) {
+        yield return set_cr_error(-EIO);
+      }
+      if (lost_lock) {
+        yield return set_cr_error(-EBUSY);
+      }
+
+      if (ret_status < 0) {
+        yield return set_cr_error(ret_status);
+      }
+
+      yield return set_cr_done();
+    }
+    return 0;
+  }
+};
+
+static string full_sync_index_shard_oid(int shard_id)
+{
+  char buf[mdlog_sync_full_sync_index_prefix.size() + 16];
+  snprintf(buf, sizeof(buf), "%s.%d", mdlog_sync_full_sync_index_prefix.c_str(), shard_id);
+  return string(buf);
+}
+
+class RGWReadRemoteMetadataCR : public RGWCoroutine {
+  RGWMetaSyncEnv *sync_env;
+
+  RGWRESTReadResource *http_op;
+
+  string section;
+  string key;
+
+  bufferlist *pbl;
+
+public:
+  RGWReadRemoteMetadataCR(RGWMetaSyncEnv *_sync_env,
+                                                      const string& _section, const string& _key, bufferlist *_pbl) : RGWCoroutine(_sync_env->cct), sync_env(_sync_env),
+                                                      http_op(NULL),
+                                                      section(_section),
+                                                      key(_key),
+						      pbl(_pbl) {
+  }
+
+  int operate() {
+    RGWRESTConn *conn = sync_env->conn;
+    reenter(this) {
+      yield {
+        rgw_http_param_pair pairs[] = { { "key" , key.c_str()},
+	                                { NULL, NULL } };
+
+        string p = string("/admin/metadata/") + section + "/" + key;
+
+        http_op = new RGWRESTReadResource(conn, p, pairs, NULL, sync_env->http_manager);
+
+        http_op->set_user_info((void *)stack);
+
+        int ret = http_op->aio_read();
+        if (ret < 0) {
+          ldout(sync_env->cct, 0) << "ERROR: failed to fetch mdlog data" << dendl;
+          log_error() << "failed to send http operation: " << http_op->to_str() << " ret=" << ret << std::endl;
+          http_op->put();
+          return set_cr_error(ret);
+        }
+
+        return io_block(0);
+      }
+      yield {
+        int ret = http_op->wait_bl(pbl);
+        if (ret < 0) {
+          return set_cr_error(ret);
+        }
+        return set_cr_done();
+      }
+    }
+    return 0;
+  }
+};
+
+class RGWAsyncMetaStoreEntry : public RGWAsyncRadosRequest {
+  RGWRados *store;
+  string raw_key;
+  bufferlist bl;
+protected:
+  int _send_request() {
+    int ret = store->meta_mgr->put(raw_key, bl, RGWMetadataHandler::APPLY_ALWAYS);
+    if (ret < 0) {
+      ldout(store->ctx(), 0) << "ERROR: can't store key: " << raw_key << " ret=" << ret << dendl;
+      return ret;
+    }
+    return 0;
+  }
+public:
+  RGWAsyncMetaStoreEntry(RGWCoroutine *caller, RGWAioCompletionNotifier *cn, RGWRados *_store,
+                       const string& _raw_key,
+                       bufferlist& _bl) : RGWAsyncRadosRequest(caller, cn), store(_store),
+                                          raw_key(_raw_key), bl(_bl) {}
+};
+
+
+class RGWMetaStoreEntryCR : public RGWSimpleCoroutine {
+  RGWMetaSyncEnv *sync_env;
+  string raw_key;
+  bufferlist bl;
+
+  RGWAsyncMetaStoreEntry *req;
+
+public:
+  RGWMetaStoreEntryCR(RGWMetaSyncEnv *_sync_env,
+                       const string& _raw_key,
+                       bufferlist& _bl) : RGWSimpleCoroutine(_sync_env->cct), sync_env(_sync_env),
+                                          raw_key(_raw_key), bl(_bl), req(NULL) {
+  }
+
+  ~RGWMetaStoreEntryCR() {
+    if (req) {
+      req->finish();
+    }
+  }
+
+  int send_request() {
+    req = new RGWAsyncMetaStoreEntry(this, stack->create_completion_notifier(),
+			           sync_env->store, raw_key, bl);
+    sync_env->async_rados->queue(req);
+    return 0;
+  }
+
+  int request_complete() {
+    return req->get_ret_status();
+  }
+};
+
+class RGWAsyncMetaRemoveEntry : public RGWAsyncRadosRequest {
+  RGWRados *store;
+  string raw_key;
+protected:
+  int _send_request() {
+    int ret = store->meta_mgr->remove(raw_key);
+    if (ret < 0) {
+      ldout(store->ctx(), 0) << "ERROR: can't remove key: " << raw_key << " ret=" << ret << dendl;
+      return ret;
+    }
+    return 0;
+  }
+public:
+  RGWAsyncMetaRemoveEntry(RGWCoroutine *caller, RGWAioCompletionNotifier *cn, RGWRados *_store,
+                       const string& _raw_key) : RGWAsyncRadosRequest(caller, cn), store(_store),
+                                          raw_key(_raw_key) {}
+};
+
+
+class RGWMetaRemoveEntryCR : public RGWSimpleCoroutine {
+  RGWMetaSyncEnv *sync_env;
+  string raw_key;
+
+  RGWAsyncMetaRemoveEntry *req;
+
+public:
+  RGWMetaRemoveEntryCR(RGWMetaSyncEnv *_sync_env,
+                       const string& _raw_key) : RGWSimpleCoroutine(_sync_env->cct), sync_env(_sync_env),
+                                          raw_key(_raw_key), req(NULL) {
+  }
+
+  ~RGWMetaRemoveEntryCR() {
+    if (req) {
+      req->finish();
+    }
+  }
+
+  int send_request() {
+    req = new RGWAsyncMetaRemoveEntry(this, stack->create_completion_notifier(),
+			           sync_env->store, raw_key);
+    sync_env->async_rados->queue(req);
+    return 0;
+  }
+
+  int request_complete() {
+    int r = req->get_ret_status();
+    if (r == -ENOENT) {
+      r = 0;
+    }
+    return r;
+  }
+};
+
+#define META_SYNC_UPDATE_MARKER_WINDOW 10
+
+class RGWMetaSyncShardMarkerTrack : public RGWSyncShardMarkerTrack<string, string> {
+  RGWMetaSyncEnv *sync_env;
+
+  string marker_oid;
+  rgw_meta_sync_marker sync_marker;
+
+
+public:
+  RGWMetaSyncShardMarkerTrack(RGWMetaSyncEnv *_sync_env,
+                         const string& _marker_oid,
+                         const rgw_meta_sync_marker& _marker) : RGWSyncShardMarkerTrack(META_SYNC_UPDATE_MARKER_WINDOW),
+                                                                sync_env(_sync_env),
+                                                                marker_oid(_marker_oid),
+                                                                sync_marker(_marker) {}
+
+  RGWCoroutine *store_marker(const string& new_marker, uint64_t index_pos, const real_time& timestamp) {
+    sync_marker.marker = new_marker;
+    if (index_pos > 0) {
+      sync_marker.pos = index_pos;
+    }
+
+    if (!real_clock::is_zero(timestamp)) {
+      sync_marker.timestamp = timestamp;
+    }
+
+    ldout(sync_env->cct, 20) << __func__ << "(): updating marker marker_oid=" << marker_oid << " marker=" << new_marker << dendl;
+    RGWRados *store = sync_env->store;
+    return new RGWSimpleRadosWriteCR<rgw_meta_sync_marker>(sync_env->async_rados, store, store->get_zone_params().log_pool,
+				 marker_oid, sync_marker);
+  }
+};
+
+int RGWMetaSyncSingleEntryCR::operate() {
+  reenter(this) {
+#define NUM_TRANSIENT_ERROR_RETRIES 10
+
+    if (op_status != MDLOG_STATUS_COMPLETE) {
+      ldout(sync_env->cct, 20) << "skipping pending operation" << dendl;
+      yield call(marker_tracker->finish(entry_marker));
+      if (retcode < 0) {
+        return set_cr_error(retcode);
+      }
+      return set_cr_done();
+    }
+    for (tries = 0; tries < NUM_TRANSIENT_ERROR_RETRIES; tries++) {
+      yield {
+        pos = raw_key.find(':');
+        section = raw_key.substr(0, pos);
+        key = raw_key.substr(pos + 1);
+        ldout(sync_env->cct, 20) << "fetching remote metadata: " << section << ":" << key << (tries == 0 ? "" : " (retry)") << dendl;
+        call(new RGWReadRemoteMetadataCR(sync_env, section, key, &md_bl));
+      }
+
+      sync_status = retcode;
+
+      if (sync_status == -ENOENT) {
+        /* FIXME: do we need to remove the entry from the local zone? */
+        break;
+      }
+
+      if ((sync_status == -EAGAIN || sync_status == -ECANCELED) && (tries < NUM_TRANSIENT_ERROR_RETRIES - 1)) {
+        ldout(sync_env->cct, 20) << *this << ": failed to fetch remote metadata: " << section << ":" << key << ", will retry" << dendl;
+        continue;
+      }
+
+      if (sync_status < 0) {
+        ldout(sync_env->cct, 10) << *this << ": failed to send read remote metadata entry: section=" << section << " key=" << key << " status=" << sync_status << dendl;
+        log_error() << "failed to send read remote metadata entry: section=" << section << " key=" << key << " status=" << sync_status << std::endl;
+        yield call(sync_env->error_logger->log_error_cr(sync_env->conn->get_remote_id(), section, key, -sync_status,
+                                                        string("failed to read remote metadata entry: ") + cpp_strerror(-sync_status)));
+        return set_cr_error(sync_status);
+      }
+
+      break;
+    }
+
+    retcode = 0;
+    for (tries = 0; tries < NUM_TRANSIENT_ERROR_RETRIES; tries++) {
+      if (sync_status != -ENOENT) {
+          yield call(new RGWMetaStoreEntryCR(sync_env, raw_key, md_bl));
+      } else {
+          yield call(new RGWMetaRemoveEntryCR(sync_env, raw_key));
+      }
+      if ((retcode == -EAGAIN || retcode == -ECANCELED) && (tries < NUM_TRANSIENT_ERROR_RETRIES - 1)) {
+        ldout(sync_env->cct, 20) << *this << ": failed to store metadata: " << section << ":" << key << ", got retcode=" << retcode << dendl;
+        continue;
+      }
+      break;
+    }
+
+    sync_status = retcode;
+
+    if (sync_status == 0 && marker_tracker) {
+      /* update marker */
+      yield call(marker_tracker->finish(entry_marker));
+      sync_status = retcode;
+    }
+    if (sync_status < 0) {
+      return set_cr_error(sync_status);
+    }
+    return set_cr_done();
+  }
+  return 0;
+}
+
+class RGWCloneMetaLogCoroutine : public RGWCoroutine {
+  RGWMetaSyncEnv *sync_env;
+  RGWMetadataLog *mdlog;
+
+  const std::string& period;
+  int shard_id;
+  string marker;
+  bool truncated = false;
+  string *new_marker;
+
+  int max_entries = CLONE_MAX_ENTRIES;
+
+  RGWRESTReadResource *http_op = nullptr;
+
+  int req_ret = 0;
+  RGWMetadataLogInfo shard_info;
+  rgw_mdlog_shard_data data;
+
+public:
+  RGWCloneMetaLogCoroutine(RGWMetaSyncEnv *_sync_env, RGWMetadataLog* mdlog,
+                           const std::string& period, int _id,
+                           const string& _marker, string *_new_marker)
+    : RGWCoroutine(_sync_env->cct), sync_env(_sync_env), mdlog(mdlog),
+      period(period), shard_id(_id), marker(_marker), new_marker(_new_marker) {
+    if (new_marker) {
+      *new_marker = marker;
+    }
+  }
+  ~RGWCloneMetaLogCoroutine() {
+    if (http_op) {
+      http_op->put();
+    }
+  }
+
+  int operate();
+
+  int state_init();
+  int state_read_shard_status();
+  int state_read_shard_status_complete();
+  int state_send_rest_request();
+  int state_receive_rest_response();
+  int state_store_mdlog_entries();
+  int state_store_mdlog_entries_complete();
+};
+
+class RGWMetaSyncShardCR : public RGWCoroutine {
+  RGWMetaSyncEnv *sync_env;
+
+  const rgw_bucket& pool;
+  const std::string& period; //< currently syncing period id
+  RGWMetadataLog* mdlog; //< log of syncing period
+  uint32_t shard_id;
+  rgw_meta_sync_marker& sync_marker;
+  string marker;
+  string max_marker;
+  const std::string& period_marker; //< max marker stored in next period
+
+  map<string, bufferlist> entries;
+  map<string, bufferlist>::iterator iter;
+
+  string oid;
+
+  RGWMetaSyncShardMarkerTrack *marker_tracker = nullptr;
+
+  list<cls_log_entry> log_entries;
+  list<cls_log_entry>::iterator log_iter;
+  bool truncated = false;
+
+  string mdlog_marker;
+  string raw_key;
+  rgw_mdlog_entry mdlog_entry;
+
+  Mutex inc_lock;
+  Cond inc_cond;
+
+  boost::asio::coroutine incremental_cr;
+  boost::asio::coroutine full_cr;
+
+  RGWContinuousLeaseCR *lease_cr = nullptr;
+  bool lost_lock = false;
+
+  bool *reset_backoff;
+
+  map<RGWCoroutinesStack *, string> stack_to_pos;
+  map<string, string> pos_to_prev;
+
+  bool can_adjust_marker = false;
+  bool done_with_period = false;
+
+  int total_entries = 0;
+
+public:
+  RGWMetaSyncShardCR(RGWMetaSyncEnv *_sync_env, const rgw_bucket& _pool,
+                     const std::string& period, RGWMetadataLog* mdlog,
+                     uint32_t _shard_id, rgw_meta_sync_marker& _marker,
+                     const std::string& period_marker, bool *_reset_backoff)
+    : RGWCoroutine(_sync_env->cct), sync_env(_sync_env), pool(_pool),
+      period(period), mdlog(mdlog), shard_id(_shard_id), sync_marker(_marker),
+      period_marker(period_marker), inc_lock("RGWMetaSyncShardCR::inc_lock"),
+      reset_backoff(_reset_backoff) {
+    *reset_backoff = false;
+  }
+
+  ~RGWMetaSyncShardCR() {
+    delete marker_tracker;
+    if (lease_cr) {
+      lease_cr->abort();
+      lease_cr->put();
+    }
+  }
+
+  void set_marker_tracker(RGWMetaSyncShardMarkerTrack *mt) {
+    delete marker_tracker;
+    marker_tracker = mt;
+  }
+
+  int operate() {
+    int r;
+    while (true) {
+      switch (sync_marker.state) {
+      case rgw_meta_sync_marker::FullSync:
+        r  = full_sync();
+        if (r < 0) {
+          ldout(sync_env->cct, 10) << "sync: full_sync: shard_id=" << shard_id << " r=" << r << dendl;
+          return set_cr_error(r);
+        }
+        return 0;
+      case rgw_meta_sync_marker::IncrementalSync:
+        r  = incremental_sync();
+        if (r < 0) {
+          ldout(sync_env->cct, 10) << "sync: incremental_sync: shard_id=" << shard_id << " r=" << r << dendl;
+          return set_cr_error(r);
+        }
+        return 0;
+      }
+    }
+    /* unreachable */
+    return 0;
+  }
+
+  void collect_children()
+  {
+    int child_ret;
+    RGWCoroutinesStack *child;
+    while (collect_next(&child_ret, &child)) {
+      map<RGWCoroutinesStack *, string>::iterator iter = stack_to_pos.find(child);
+      if (iter == stack_to_pos.end()) {
+        /* some other stack that we don't care about */
+        continue;
+      }
+
+      string& pos = iter->second;
+
+      if (child_ret < 0) {
+        ldout(sync_env->cct, 0) << *this << ": child operation stack=" << child << " entry=" << pos << " returned " << child_ret << dendl;
+      }
+
+      map<string, string>::iterator prev_iter = pos_to_prev.find(pos);
+      assert(prev_iter != pos_to_prev.end());
+
+      /*
+       * we should get -EAGAIN for transient errors, for which we want to retry, so we don't
+       * update the marker and abort. We'll get called again for these. Permanent errors will be
+       * handled by marking the entry at the error log shard, so that we retry on it separately
+       */
+      if (child_ret == -EAGAIN) {
+        can_adjust_marker = false;
+      }
+
+      if (pos_to_prev.size() == 1) {
+        if (can_adjust_marker) {
+          sync_marker.marker = pos;
+        }
+        pos_to_prev.erase(prev_iter);
+      } else {
+        assert(pos_to_prev.size() > 1);
+        pos_to_prev.erase(prev_iter);
+        prev_iter = pos_to_prev.begin();
+        if (can_adjust_marker) {
+          sync_marker.marker = prev_iter->second;
+        }
+      }
+
+      ldout(sync_env->cct, 0) << *this << ": adjusting marker pos=" << sync_marker.marker << dendl;
+      stack_to_pos.erase(iter);
+
+      child->put();
+    }
+  }
+
+  int full_sync() {
+#define OMAP_GET_MAX_ENTRIES 100
+    int max_entries = OMAP_GET_MAX_ENTRIES;
+    reenter(&full_cr) {
+      set_status("full_sync");
+      oid = full_sync_index_shard_oid(shard_id);
+      can_adjust_marker = true;
+      /* grab lock */
+      yield {
+	uint32_t lock_duration = cct->_conf->rgw_sync_lease_period;
+        string lock_name = "sync_lock";
+        if (lease_cr) {
+          lease_cr->put();
+        }
+        RGWRados *store = sync_env->store;
+	lease_cr = new RGWContinuousLeaseCR(sync_env->async_rados, store, pool,
+                                            sync_env->shard_obj_name(shard_id),
+                                            lock_name, lock_duration, this);
+        lease_cr->get();
+        spawn(lease_cr, false);
+        lost_lock = false;
+      }
+      while (!lease_cr->is_locked()) {
+        if (lease_cr->is_done()) {
+          ldout(cct, 0) << "ERROR: lease cr failed, done early " << dendl;
+          drain_all();
+          return lease_cr->get_ret_status();
+        }
+        set_sleeping(true);
+        yield;
+      }
+
+      /* lock succeeded, a retry now should avoid previous backoff status */
+      *reset_backoff = true;
+
+      /* prepare marker tracker */
+      set_marker_tracker(new RGWMetaSyncShardMarkerTrack(sync_env,
+                                                         sync_env->shard_obj_name(shard_id),
+                                                         sync_marker));
+
+      marker = sync_marker.marker;
+
+      total_entries = sync_marker.pos;
+
+      /* sync! */
+      do {
+        if (!lease_cr->is_locked()) {
+          lost_lock = true;
+          break;
+        }
+        yield call(new RGWRadosGetOmapKeysCR(sync_env->store, pool, oid, marker, &entries, max_entries));
+        if (retcode < 0) {
+          ldout(sync_env->cct, 0) << "ERROR: " << __func__ << "(): RGWRadosGetOmapKeysCR() returned ret=" << retcode << dendl;
+          yield lease_cr->go_down();
+          drain_all();
+          return retcode;
+        }
+        iter = entries.begin();
+        for (; iter != entries.end(); ++iter) {
+          ldout(sync_env->cct, 20) << __func__ << ": full sync: " << iter->first << dendl;
+          total_entries++;
+          if (!marker_tracker->start(iter->first, total_entries, real_time())) {
+            ldout(sync_env->cct, 0) << "ERROR: cannot start syncing " << iter->first << ". Duplicate entry?" << dendl;
+          } else {
+            // fetch remote and write locally
+            yield {
+              RGWCoroutinesStack *stack = spawn(new RGWMetaSyncSingleEntryCR(sync_env, iter->first, iter->first, MDLOG_STATUS_COMPLETE, marker_tracker), false);
+              stack->get();
+
+              stack_to_pos[stack] = iter->first;
+              pos_to_prev[iter->first] = marker;
+            }
+          }
+          marker = iter->first;
+        }
+        collect_children();
+      } while ((int)entries.size() == max_entries && can_adjust_marker);
+
+      while (num_spawned() > 1) {
+        yield wait_for_child();
+        collect_children();
+      }
+
+      if (!lost_lock) {
+        /* update marker to reflect we're done with full sync */
+        if (can_adjust_marker) yield {
+          sync_marker.state = rgw_meta_sync_marker::IncrementalSync;
+          sync_marker.marker = sync_marker.next_step_marker;
+          sync_marker.next_step_marker.clear();
+
+          RGWRados *store = sync_env->store;
+          ldout(sync_env->cct, 0) << *this << ": saving marker pos=" << sync_marker.marker << dendl;
+          using WriteMarkerCR = RGWSimpleRadosWriteCR<rgw_meta_sync_marker>;
+          call(new WriteMarkerCR(sync_env->async_rados, store, pool,
+                                 sync_env->shard_obj_name(shard_id),
+                                 sync_marker));
+        }
+        if (retcode < 0) {
+          ldout(sync_env->cct, 0) << "ERROR: failed to set sync marker: retcode=" << retcode << dendl;
+          return retcode;
+        }
+      }
+
+      /* 
+       * if we reached here, it means that lost_lock is true, otherwise the state
+       * change in the previous block will prevent us from reaching here
+       */
+
+      yield lease_cr->go_down();
+
+      lease_cr->put();
+      lease_cr = NULL;
+
+      drain_all();
+
+      if (!can_adjust_marker) {
+        return -EAGAIN;
+      }
+
+      if (lost_lock) {
+        return -EBUSY;
+      }
+    }
+    return 0;
+  }
+    
+
+  int incremental_sync() {
+    reenter(&incremental_cr) {
+      set_status("incremental_sync");
+      can_adjust_marker = true;
+      /* grab lock */
+      if (!lease_cr) { /* could have had  a lease_cr lock from previous state */
+        yield {
+          uint32_t lock_duration = cct->_conf->rgw_sync_lease_period;
+          string lock_name = "sync_lock";
+          RGWRados *store = sync_env->store;
+          lease_cr = new RGWContinuousLeaseCR(sync_env->async_rados, store, pool,
+                                              sync_env->shard_obj_name(shard_id),
+                                              lock_name, lock_duration, this);
+          lease_cr->get();
+          spawn(lease_cr, false);
+          lost_lock = false;
+        }
+        while (!lease_cr->is_locked()) {
+          if (lease_cr->is_done()) {
+            ldout(cct, 0) << "ERROR: lease cr failed, done early " << dendl;
+            drain_all();
+            return lease_cr->get_ret_status();
+          }
+          set_sleeping(true);
+          yield;
+        }
+      }
+      mdlog_marker = sync_marker.marker;
+      set_marker_tracker(new RGWMetaSyncShardMarkerTrack(sync_env,
+                                                         sync_env->shard_obj_name(shard_id),
+                                                         sync_marker));
+
+      /*
+       * mdlog_marker: the remote sync marker positiion
+       * sync_marker: the local sync marker position
+       * max_marker: the max mdlog position that we fetched
+       * marker: the current position we try to sync
+       * period_marker: the last marker before the next period begins (optional)
+       */
+      marker = max_marker = sync_marker.marker;
+      /* inc sync */
+      do {
+        if (!lease_cr->is_locked()) {
+          lost_lock = true;
+          break;
+        }
+#define INCREMENTAL_MAX_ENTRIES 100
+	ldout(sync_env->cct, 20) << __func__ << ":" << __LINE__ << ": shard_id=" << shard_id << " mdlog_marker=" << mdlog_marker << " sync_marker.marker=" << sync_marker.marker << " period_marker=" << period_marker << dendl;
+        if (!period_marker.empty() && period_marker <= marker) {
+          done_with_period = true;
+          break;
+        }
+	if (mdlog_marker <= max_marker) {
+	  /* we're at the tip, try to bring more entries */
+          ldout(sync_env->cct, 20) << __func__ << ":" << __LINE__ << ": shard_id=" << shard_id << " syncing mdlog for shard_id=" << shard_id << dendl;
+          yield call(new RGWCloneMetaLogCoroutine(sync_env, mdlog,
+                                                  period, shard_id,
+                                                  mdlog_marker, &mdlog_marker));
+	}
+        if (retcode < 0) {
+          ldout(sync_env->cct, 10) << *this << ": failed to fetch more log entries, retcode=" << retcode << dendl;
+          yield lease_cr->go_down();
+          drain_all();
+          return retcode;
+        }
+        *reset_backoff = true; /* if we got to this point, all systems function */
+	ldout(sync_env->cct, 20) << __func__ << ":" << __LINE__ << ": shard_id=" << shard_id << " mdlog_marker=" << mdlog_marker << " sync_marker.marker=" << sync_marker.marker << dendl;
+	if (mdlog_marker > max_marker) {
+          marker = max_marker;
+          yield call(new RGWReadMDLogEntriesCR(sync_env, mdlog, shard_id,
+                                               &max_marker, INCREMENTAL_MAX_ENTRIES,
+                                               &log_entries, &truncated));
+          for (log_iter = log_entries.begin(); log_iter != log_entries.end(); ++log_iter) {
+            if (!period_marker.empty() && period_marker < log_iter->id) {
+              done_with_period = true;
+              break;
+            }
+            if (!mdlog_entry.convert_from(*log_iter)) {
+              ldout(sync_env->cct, 0) << __func__ << ":" << __LINE__ << ": ERROR: failed to convert mdlog entry, shard_id=" << shard_id << " log_entry: " << log_iter->id << ":" << log_iter->section << ":" << log_iter->name << ":" << log_iter->timestamp << " ... skipping entry" << dendl;
+              continue;
+            }
+            ldout(sync_env->cct, 20) << __func__ << ":" << __LINE__ << ": shard_id=" << shard_id << " log_entry: " << log_iter->id << ":" << log_iter->section << ":" << log_iter->name << ":" << log_iter->timestamp << dendl;
+            if (!marker_tracker->start(log_iter->id, 0, log_iter->timestamp.to_real_time())) {
+              ldout(sync_env->cct, 0) << "ERROR: cannot start syncing " << log_iter->id << ". Duplicate entry?" << dendl;
+            } else {
+              raw_key = log_iter->section + ":" + log_iter->name;
+              yield {
+                RGWCoroutinesStack *stack = spawn(new RGWMetaSyncSingleEntryCR(sync_env, raw_key, log_iter->id, mdlog_entry.log_data.status, marker_tracker), false);
+                assert(stack);
+                stack->get();
+
+                stack_to_pos[stack] = log_iter->id;
+                pos_to_prev[log_iter->id] = marker;
+              }
+            }
+            marker = log_iter->id;
+          }
+        }
+        collect_children();
+	ldout(sync_env->cct, 20) << __func__ << ":" << __LINE__ << ": shard_id=" << shard_id << " mdlog_marker=" << mdlog_marker << " max_marker=" << max_marker << " sync_marker.marker=" << sync_marker.marker << " period_marker=" << period_marker << dendl;
+        if (done_with_period) {
+          // return control to RGWMetaSyncCR and advance to the next period
+          break;
+        }
+	if (mdlog_marker == max_marker && can_adjust_marker) {
+#define INCREMENTAL_INTERVAL 20
+	  yield wait(utime_t(INCREMENTAL_INTERVAL, 0));
+	}
+      } while (can_adjust_marker);
+
+      while (num_spawned() > 1) {
+        yield wait_for_child();
+        collect_children();
+      }
+
+      yield lease_cr->go_down();
+
+      drain_all();
+
+      if (lost_lock) {
+        return -EBUSY;
+      }
+
+      if (!can_adjust_marker) {
+        return -EAGAIN;
+      }
+    }
+    /* TODO */
+    return 0;
+  }
+};
+
+class RGWMetaSyncShardControlCR : public RGWBackoffControlCR
+{
+  RGWMetaSyncEnv *sync_env;
+
+  const rgw_bucket& pool;
+  const std::string& period;
+  RGWMetadataLog* mdlog;
+  uint32_t shard_id;
+  rgw_meta_sync_marker sync_marker;
+  const std::string period_marker;
+
+  RGWObjectCtx obj_ctx;
+
+public:
+  RGWMetaSyncShardControlCR(RGWMetaSyncEnv *_sync_env, const rgw_bucket& _pool,
+                            const std::string& period, RGWMetadataLog* mdlog,
+                            uint32_t _shard_id, const rgw_meta_sync_marker& _marker,
+                            std::string&& period_marker)
+    : RGWBackoffControlCR(_sync_env->cct, true), sync_env(_sync_env),
+      pool(_pool), period(period), mdlog(mdlog), shard_id(_shard_id),
+      sync_marker(_marker), period_marker(std::move(period_marker)),
+      obj_ctx(sync_env->store) {}
+
+  RGWCoroutine *alloc_cr() {
+    return new RGWMetaSyncShardCR(sync_env, pool, period, mdlog, shard_id,
+                                  sync_marker, period_marker, backoff_ptr());
+  }
+
+  RGWCoroutine *alloc_finisher_cr() {
+    RGWRados *store = sync_env->store;
+    return new RGWSimpleRadosReadCR<rgw_meta_sync_marker>(sync_env->async_rados, store, obj_ctx, pool,
+                                                               sync_env->shard_obj_name(shard_id), &sync_marker);
+  }
+};
+
+class RGWMetaSyncCR : public RGWCoroutine {
+  RGWMetaSyncEnv *sync_env;
+  const rgw_bucket& pool;
+  RGWPeriodHistory::Cursor cursor; //< sync position in period history
+  RGWPeriodHistory::Cursor next; //< next period in history
+  rgw_meta_sync_status sync_status;
+
+  std::mutex mutex; //< protect access to shard_crs
+
+  using ControlCRRef = boost::intrusive_ptr<RGWMetaSyncShardControlCR>;
+  map<int, ControlCRRef> shard_crs;
+
+public:
+  RGWMetaSyncCR(RGWMetaSyncEnv *_sync_env, RGWPeriodHistory::Cursor cursor,
+                const rgw_meta_sync_status& _sync_status)
+    : RGWCoroutine(_sync_env->cct), sync_env(_sync_env),
+      pool(sync_env->store->get_zone_params().log_pool),
+      cursor(cursor), sync_status(_sync_status) {}
+
+  int operate() {
+    int ret = 0;
+    reenter(this) {
+      // loop through one period at a time
+      for (;;) {
+        if (cursor == sync_env->store->period_history->get_current()) {
+          next = RGWPeriodHistory::Cursor{};
+          if (cursor) {
+            ldout(cct, 10) << "RGWMetaSyncCR on current period="
+                << cursor.get_period().get_id() << dendl;
+          } else {
+            ldout(cct, 10) << "RGWMetaSyncCR with no period" << dendl;
+          }
+        } else {
+          next = cursor;
+          next.next();
+          ldout(cct, 10) << "RGWMetaSyncCR on period="
+              << cursor.get_period().get_id() << ", next="
+              << next.get_period().get_id() << dendl;
+        }
+
+        yield {
+          // get the mdlog for the current period (may be empty)
+          auto& period_id = sync_status.sync_info.period;
+          auto mdlog = sync_env->store->meta_mgr->get_log(period_id);
+
+          // prevent wakeup() from accessing shard_crs while we're spawning them
+          std::lock_guard<std::mutex> lock(mutex);
+
+          // sync this period on each shard
+          for (const auto& m : sync_status.sync_markers) {
+            uint32_t shard_id = m.first;
+            auto& marker = m.second;
+
+            std::string period_marker;
+            if (next) {
+              // read the maximum marker from the next period's sync status
+              period_marker = next.get_period().get_sync_status()[shard_id];
+              if (period_marker.empty()) {
+                // no metadata changes have occurred on this shard, skip it
+                ldout(cct, 10) << "RGWMetaSyncCR: skipping shard " << shard_id
+                    << " with empty period marker" << dendl;
+                continue;
+              }
+            }
+
+            auto cr = new RGWMetaSyncShardControlCR(sync_env, pool, period_id,
+                                                    mdlog, shard_id, marker,
+                                                    std::move(period_marker));
+            shard_crs[shard_id] = cr;
+            spawn(cr, false);
+          }
+        }
+        // wait for each shard to complete
+        collect(&ret);
+        drain_all();
+        {
+          // drop shard cr refs under lock
+          std::lock_guard<std::mutex> lock(mutex);
+          shard_crs.clear();
+        }
+        if (ret < 0) {
+          return set_cr_error(ret);
+        }
+        // advance to the next period
+        assert(next);
+        cursor = next;
+
+        // write the updated sync info
+        sync_status.sync_info.period = cursor.get_period().get_id();
+        sync_status.sync_info.realm_epoch = cursor.get_epoch();
+        yield call(new RGWSimpleRadosWriteCR<rgw_meta_sync_info>(sync_env->async_rados,
+                                                                 sync_env->store, pool,
+                                                                 sync_env->status_oid(),
+                                                                 sync_status.sync_info));
+      }
+    }
+    return 0;
+  }
+
+  void wakeup(int shard_id) {
+    std::lock_guard<std::mutex> lock(mutex);
+    auto iter = shard_crs.find(shard_id);
+    if (iter == shard_crs.end()) {
+      return;
+    }
+    iter->second->wakeup();
+  }
+};
+
+void RGWRemoteMetaLog::init_sync_env(RGWMetaSyncEnv *env) {
+  env->cct = store->ctx();
+  env->store = store;
+  env->conn = conn;
+  env->async_rados = async_rados;
+  env->http_manager = &http_manager;
+  env->error_logger = error_logger;
+}
+
+int RGWRemoteMetaLog::read_sync_status()
+{
+  if (store->is_meta_master()) {
+    return 0;
+  }
+
+  RGWObjectCtx obj_ctx(store, NULL);
+  return run(new RGWReadSyncStatusCoroutine(&sync_env, obj_ctx, &sync_status));
+}
+
+int RGWRemoteMetaLog::init_sync_status()
+{
+  if (store->is_meta_master()) {
+    return 0;
+  }
+
+  auto& sync_info = sync_status.sync_info;
+  if (!sync_info.num_shards) {
+    rgw_mdlog_info mdlog_info;
+    int r = read_log_info(&mdlog_info);
+    if (r < 0) {
+      lderr(store->ctx()) << "ERROR: fail to fetch master log info (r=" << r << ")" << dendl;
+      return r;
+    }
+    sync_info.num_shards = mdlog_info.num_shards;
+    auto cursor = store->period_history->get_current();
+    if (cursor) {
+      sync_info.period = cursor.get_period().get_id();
+      sync_info.realm_epoch = cursor.get_epoch();
+    }
+  }
+
+  RGWObjectCtx obj_ctx(store, NULL);
+  return run(new RGWInitSyncStatusCoroutine(&sync_env, obj_ctx, sync_info));
+}
+
+int RGWRemoteMetaLog::store_sync_info()
+{
+  return run(new RGWSimpleRadosWriteCR<rgw_meta_sync_info>(async_rados, store, store->get_zone_params().log_pool,
+				 sync_env.status_oid(), sync_status.sync_info));
+}
+
+// return a cursor to the period at our sync position
+static RGWPeriodHistory::Cursor get_period_at(RGWRados* store,
+                                              const rgw_meta_sync_info& info)
+{
+  if (info.period.empty()) {
+    // return an empty cursor with error=0
+    return RGWPeriodHistory::Cursor{};
+  }
+
+  // look for an existing period in our history
+  auto cursor = store->period_history->lookup(info.realm_epoch);
+  if (cursor) {
+    // verify that the period ids match
+    auto& existing = cursor.get_period().get_id();
+    if (existing != info.period) {
+      lderr(store->ctx()) << "ERROR: sync status period=" << info.period
+          << " does not match period=" << existing
+          << " in history at realm epoch=" << info.realm_epoch << dendl;
+      return RGWPeriodHistory::Cursor{-EEXIST};
+    }
+    return cursor;
+  }
+
+  // read the period from rados or pull it from the master
+  RGWPeriod period;
+  int r = store->period_puller->pull(info.period, period);
+  if (r < 0) {
+    lderr(store->ctx()) << "ERROR: failed to read period id "
+        << info.period << ": " << cpp_strerror(r) << dendl;
+    return RGWPeriodHistory::Cursor{r};
+  }
+  // attach the period to our history
+  cursor = store->period_history->attach(std::move(period));
+  if (!cursor) {
+    r = cursor.get_error();
+    lderr(store->ctx()) << "ERROR: failed to read period history back to "
+        << info.period << ": " << cpp_strerror(r) << dendl;
+  }
+  return cursor;
+}
+
+int RGWRemoteMetaLog::run_sync()
+{
+  if (store->is_meta_master()) {
+    return 0;
+  }
+
+  RGWObjectCtx obj_ctx(store, NULL);
+
+  // get shard count and oldest log period from master
+  rgw_mdlog_info mdlog_info;
+  int r = read_log_info(&mdlog_info);
+  if (r < 0) {
+    lderr(store->ctx()) << "ERROR: fail to fetch master log info (r=" << r << ")" << dendl;
+    return r;
+  }
+
+  do {
+    r = run(new RGWReadSyncStatusCoroutine(&sync_env, obj_ctx, &sync_status));
+    if (r < 0 && r != -ENOENT) {
+      ldout(store->ctx(), 0) << "ERROR: failed to fetch sync status r=" << r << dendl;
+      return r;
+    }
+
+    if (!mdlog_info.period.empty()) {
+      // restart sync if the remote has a period, but:
+      // a) our status does not, or
+      // b) our sync period comes before the remote's oldest log period
+      if (sync_status.sync_info.period.empty() ||
+          sync_status.sync_info.realm_epoch < mdlog_info.realm_epoch) {
+        sync_status.sync_info.state = rgw_meta_sync_info::StateInit;
+      }
+    }
+
+    if (sync_status.sync_info.state == rgw_meta_sync_info::StateInit) {
+      ldout(store->ctx(), 20) << __func__ << "(): init" << dendl;
+      sync_status.sync_info.num_shards = mdlog_info.num_shards;
+      auto cursor = store->period_history->get_current();
+      if (cursor) {
+        // run full sync, then start incremental from the current period/epoch
+        sync_status.sync_info.period = cursor.get_period().get_id();
+        sync_status.sync_info.realm_epoch = cursor.get_epoch();
+      }
+      r = run(new RGWInitSyncStatusCoroutine(&sync_env, obj_ctx,
+                                             sync_status.sync_info));
+      if (r == -EBUSY) {
+        backoff.backoff_sleep();
+        continue;
+      }
+      backoff.reset();
+      if (r < 0) {
+        ldout(store->ctx(), 0) << "ERROR: failed to init sync status r=" << r << dendl;
+        return r;
+      }
+    }
+  } while (sync_status.sync_info.state == rgw_meta_sync_info::StateInit);
+
+  auto num_shards = sync_status.sync_info.num_shards;
+  if (num_shards != mdlog_info.num_shards) {
+    lderr(store->ctx()) << "ERROR: can't sync, mismatch between num shards, master num_shards=" << mdlog_info.num_shards << " local num_shards=" << num_shards << dendl;
+    return r;
+  }
+
+  RGWPeriodHistory::Cursor cursor;
+  do {
+    r = run(new RGWReadSyncStatusCoroutine(&sync_env, obj_ctx, &sync_status));
+    if (r < 0 && r != -ENOENT) {
+      ldout(store->ctx(), 0) << "ERROR: failed to fetch sync status r=" << r << dendl;
+      return r;
+    }
+
+    switch ((rgw_meta_sync_info::SyncState)sync_status.sync_info.state) {
+      case rgw_meta_sync_info::StateBuildingFullSyncMaps:
+        ldout(store->ctx(), 20) << __func__ << "(): building full sync maps" << dendl;
+        r = run(new RGWFetchAllMetaCR(&sync_env, num_shards, sync_status.sync_markers));
+        if (r == -EBUSY || r == -EAGAIN) {
+          backoff.backoff_sleep();
+          continue;
+        }
+        backoff.reset();
+        if (r < 0) {
+          ldout(store->ctx(), 0) << "ERROR: failed to fetch all metadata keys" << dendl;
+          return r;
+        }
+
+        sync_status.sync_info.state = rgw_meta_sync_info::StateSync;
+        r = store_sync_info();
+        if (r < 0) {
+          ldout(store->ctx(), 0) << "ERROR: failed to update sync status" << dendl;
+          return r;
+        }
+        /* fall through */
+      case rgw_meta_sync_info::StateSync:
+        ldout(store->ctx(), 20) << __func__ << "(): sync" << dendl;
+        // find our position in the period history (if any)
+        cursor = get_period_at(store, sync_status.sync_info);
+        r = cursor.get_error();
+        if (r < 0) {
+          return r;
+        }
+        meta_sync_cr = new RGWMetaSyncCR(&sync_env, cursor, sync_status);
+        r = run(meta_sync_cr);
+        if (r < 0) {
+          ldout(store->ctx(), 0) << "ERROR: failed to fetch all metadata keys" << dendl;
+          return r;
+        }
+        break;
+      default:
+        ldout(store->ctx(), 0) << "ERROR: bad sync state!" << dendl;
+        return -EIO;
+    }
+  } while (!going_down.read());
+
+  return 0;
+}
+
+void RGWRemoteMetaLog::wakeup(int shard_id)
+{
+  if (!meta_sync_cr) {
+    return;
+  }
+  meta_sync_cr->wakeup(shard_id);
+}
+
+int RGWCloneMetaLogCoroutine::operate()
+{
+  reenter(this) {
+    do {
+      yield {
+        ldout(cct, 20) << __func__ << ": shard_id=" << shard_id << ": init request" << dendl;
+        return state_init();
+      }
+      yield {
+        ldout(cct, 20) << __func__ << ": shard_id=" << shard_id << ": reading shard status" << dendl;
+        return state_read_shard_status();
+      }
+      yield {
+        ldout(cct, 20) << __func__ << ": shard_id=" << shard_id << ": reading shard status complete" << dendl;
+        return state_read_shard_status_complete();
+      }
+      yield {
+        ldout(cct, 20) << __func__ << ": shard_id=" << shard_id << ": sending rest request" << dendl;
+        return state_send_rest_request();
+      }
+      yield {
+        ldout(cct, 20) << __func__ << ": shard_id=" << shard_id << ": receiving rest response" << dendl;
+        return state_receive_rest_response();
+      }
+      yield {
+        ldout(cct, 20) << __func__ << ": shard_id=" << shard_id << ": storing mdlog entries" << dendl;
+        return state_store_mdlog_entries();
+      }
+    } while (truncated);
+    yield {
+      ldout(cct, 20) << __func__ << ": shard_id=" << shard_id << ": storing mdlog entries complete" << dendl;
+      return state_store_mdlog_entries_complete();
+    }
+  }
+
+  return 0;
+}
+
+int RGWCloneMetaLogCoroutine::state_init()
+{
+  data = rgw_mdlog_shard_data();
+
+  return 0;
+}
+
+int RGWCloneMetaLogCoroutine::state_read_shard_status()
+{
+  int ret = mdlog->get_info_async(shard_id, &shard_info, stack->get_completion_mgr(), (void *)stack, &req_ret);
+  if (ret < 0) {
+    ldout(cct, 0) << "ERROR: mdlog->get_info_async() returned ret=" << ret << dendl;
+    return set_cr_error(ret);
+  }
+
+  return io_block(0);
+}
+
+int RGWCloneMetaLogCoroutine::state_read_shard_status_complete()
+{
+  ldout(cct, 20) << "shard_id=" << shard_id << " marker=" << shard_info.marker << " last_update=" << shard_info.last_update << dendl;
+
+  marker = shard_info.marker;
+
+  return 0;
+}
+
+int RGWCloneMetaLogCoroutine::state_send_rest_request()
+{
+  RGWRESTConn *conn = sync_env->conn;
+
+  char buf[32];
+  snprintf(buf, sizeof(buf), "%d", shard_id);
+
+  char max_entries_buf[32];
+  snprintf(max_entries_buf, sizeof(max_entries_buf), "%d", max_entries);
+
+  const char *marker_key = (marker.empty() ? "" : "marker");
+
+  rgw_http_param_pair pairs[] = { { "type", "metadata" },
+                                  { "id", buf },
+                                  { "period", period.c_str() },
+                                  { "max-entries", max_entries_buf },
+                                  { marker_key, marker.c_str() },
+                                  { NULL, NULL } };
+
+  http_op = new RGWRESTReadResource(conn, "/admin/log", pairs, NULL, sync_env->http_manager);
+
+  http_op->set_user_info((void *)stack);
+
+  int ret = http_op->aio_read();
+  if (ret < 0) {
+    ldout(cct, 0) << "ERROR: failed to fetch mdlog data" << dendl;
+    log_error() << "failed to send http operation: " << http_op->to_str() << " ret=" << ret << std::endl;
+    http_op->put();
+    http_op = NULL;
+    return ret;
+  }
+
+  return io_block(0);
+}
+
+int RGWCloneMetaLogCoroutine::state_receive_rest_response()
+{
+  int ret = http_op->wait(&data);
+  if (ret < 0) {
+    error_stream << "http operation failed: " << http_op->to_str() << " status=" << http_op->get_http_status() << std::endl;
+    ldout(cct, 0) << "ERROR: failed to wait for op, ret=" << ret << dendl;
+    http_op->put();
+    http_op = NULL;
+    return set_cr_error(ret);
+  }
+  http_op->put();
+  http_op = NULL;
+
+  ldout(cct, 20) << "remote mdlog, shard_id=" << shard_id << " num of shard entries: " << data.entries.size() << dendl;
+
+  truncated = ((int)data.entries.size() == max_entries);
+
+  if (data.entries.empty()) {
+    if (new_marker) {
+      *new_marker = marker;
+    }
+    return set_cr_done();
+  }
+
+  if (new_marker) {
+    *new_marker = data.entries.back().id;
+  }
+
+  return 0;
+}
+
+
+int RGWCloneMetaLogCoroutine::state_store_mdlog_entries()
+{
+  list<cls_log_entry> dest_entries;
+
+  vector<rgw_mdlog_entry>::iterator iter;
+  for (iter = data.entries.begin(); iter != data.entries.end(); ++iter) {
+    rgw_mdlog_entry& entry = *iter;
+    ldout(cct, 20) << "entry: name=" << entry.name << dendl;
+
+    cls_log_entry dest_entry;
+    dest_entry.id = entry.id;
+    dest_entry.section = entry.section;
+    dest_entry.name = entry.name;
+    dest_entry.timestamp = utime_t(entry.timestamp);
+  
+    ::encode(entry.log_data, dest_entry.data);
+
+    dest_entries.push_back(dest_entry);
+
+    marker = entry.id;
+  }
+
+  RGWAioCompletionNotifier *cn = stack->create_completion_notifier();
+
+  int ret = mdlog->store_entries_in_shard(dest_entries, shard_id, cn->completion());
+  if (ret < 0) {
+    cn->put();
+    ldout(cct, 10) << "failed to store md log entries shard_id=" << shard_id << " ret=" << ret << dendl;
+    return set_cr_error(ret);
+  }
+  return io_block(0);
+}
+
+int RGWCloneMetaLogCoroutine::state_store_mdlog_entries_complete()
+{
+  return set_cr_done();
+}
+
+
diff --git a/src/rgw/rgw_sync.h b/src/rgw/rgw_sync.h
new file mode 100644
index 0000000..66c639c
--- /dev/null
+++ b/src/rgw/rgw_sync.h
@@ -0,0 +1,443 @@
+#ifndef CEPH_RGW_SYNC_H
+#define CEPH_RGW_SYNC_H
+
+#include "rgw_coroutine.h"
+#include "rgw_http_client.h"
+#include "rgw_meta_sync_status.h"
+
+#include "common/RWLock.h"
+
+#define ERROR_LOGGER_SHARDS 32
+#define RGW_SYNC_ERROR_LOG_SHARD_PREFIX "sync.error-log"
+
+struct rgw_mdlog_info {
+  uint32_t num_shards;
+  std::string period; //< period id of the master's oldest metadata log
+  epoch_t realm_epoch; //< realm epoch of oldest metadata log
+
+  rgw_mdlog_info() : num_shards(0), realm_epoch(0) {}
+
+  void decode_json(JSONObj *obj);
+};
+
+
+struct rgw_mdlog_entry {
+  string id;
+  string section;
+  string name;
+  ceph::real_time timestamp;
+  RGWMetadataLogData log_data;
+
+  void decode_json(JSONObj *obj);
+
+  bool convert_from(cls_log_entry& le) {
+    id = le.id;
+    section = le.section;
+    name = le.name;
+    timestamp = le.timestamp.to_real_time();
+    try {
+      bufferlist::iterator iter = le.data.begin();
+      ::decode(log_data, iter);
+    } catch (buffer::error& err) {
+      return false;
+    }
+    return true;
+  }
+};
+
+struct rgw_mdlog_shard_data {
+  string marker;
+  bool truncated;
+  vector<rgw_mdlog_entry> entries;
+
+  void decode_json(JSONObj *obj);
+};
+
+class RGWAsyncRadosProcessor;
+class RGWMetaSyncStatusManager;
+class RGWMetaSyncCR;
+class RGWRESTConn;
+
+class RGWSyncErrorLogger {
+  RGWRados *store;
+
+  vector<string> oids;
+  int num_shards;
+
+  atomic_t counter;
+public:
+  RGWSyncErrorLogger(RGWRados *_store, const string oid_prefix, int _num_shards);
+  RGWCoroutine *log_error_cr(const string& source_zone, const string& section, const string& name, uint32_t error_code, const string& message);
+
+  static string get_shard_oid(const string& oid_prefix, int shard_id);
+};
+
+struct rgw_sync_error_info {
+  string source_zone;
+  uint32_t error_code;
+  string message;
+
+  rgw_sync_error_info() : error_code(0) {}
+  rgw_sync_error_info(const string& _source_zone, uint32_t _error_code, const string& _message) : source_zone(_source_zone), error_code(_error_code), message(_message) {}
+
+  void encode(bufferlist& bl) const {
+    ENCODE_START(1, 1, bl);
+    ::encode(source_zone, bl);
+    ::encode(error_code, bl);
+    ::encode(message, bl);
+    ENCODE_FINISH(bl);
+  }
+
+  void decode(bufferlist::iterator& bl) {
+    DECODE_START(1, bl);
+    ::decode(source_zone, bl);
+    ::decode(error_code, bl);
+    ::decode(message, bl);
+    DECODE_FINISH(bl);
+  }
+
+  void dump(Formatter *f) const;
+};
+WRITE_CLASS_ENCODER(rgw_sync_error_info)
+
+#define DEFAULT_BACKOFF_MAX 30
+
+class RGWSyncBackoff {
+  int cur_wait;
+  int max_secs;
+
+  void update_wait_time();
+public:
+  RGWSyncBackoff(int _max_secs = DEFAULT_BACKOFF_MAX) : cur_wait(0), max_secs(_max_secs) {}
+
+  void backoff_sleep();
+  void reset() {
+    cur_wait = 0;
+  }
+
+  void backoff(RGWCoroutine *op);
+};
+
+class RGWBackoffControlCR : public RGWCoroutine
+{
+  RGWCoroutine *cr;
+  Mutex lock;
+
+  RGWSyncBackoff backoff;
+  bool reset_backoff;
+
+  bool exit_on_error;
+
+protected:
+  bool *backoff_ptr() {
+    return &reset_backoff;
+  }
+
+  Mutex& cr_lock() {
+    return lock;
+  }
+
+  RGWCoroutine *get_cr() {
+    return cr;
+  }
+
+public:
+  RGWBackoffControlCR(CephContext *_cct, bool _exit_on_error) : RGWCoroutine(_cct), cr(NULL), lock("RGWBackoffControlCR::lock"),
+                                                                reset_backoff(false), exit_on_error(_exit_on_error) {
+  }
+
+  virtual ~RGWBackoffControlCR() {
+    if (cr) {
+      cr->put();
+    }
+  }
+
+  virtual RGWCoroutine *alloc_cr() = 0;
+  virtual RGWCoroutine *alloc_finisher_cr() { return NULL; }
+
+  int operate();
+};
+
+struct RGWMetaSyncEnv {
+  CephContext *cct;
+  RGWRados *store;
+  RGWRESTConn *conn;
+  RGWAsyncRadosProcessor *async_rados;
+  RGWHTTPManager *http_manager;
+  RGWSyncErrorLogger *error_logger;
+
+  RGWMetaSyncEnv() : cct(NULL), store(NULL), conn(NULL), async_rados(NULL), http_manager(NULL), error_logger(NULL) {}
+
+  void init(CephContext *_cct, RGWRados *_store, RGWRESTConn *_conn,
+            RGWAsyncRadosProcessor *_async_rados, RGWHTTPManager *_http_manager,
+            RGWSyncErrorLogger *_error_logger);
+
+  string shard_obj_name(int shard_id);
+  string status_oid();
+};
+
+class RGWRemoteMetaLog : public RGWCoroutinesManager {
+  RGWRados *store;
+  RGWRESTConn *conn;
+  RGWAsyncRadosProcessor *async_rados;
+
+  RGWHTTPManager http_manager;
+  RGWMetaSyncStatusManager *status_manager;
+  RGWSyncErrorLogger *error_logger;
+
+  RGWMetaSyncCR *meta_sync_cr;
+
+  RGWSyncBackoff backoff;
+
+  RGWMetaSyncEnv sync_env;
+  rgw_meta_sync_status sync_status;
+
+  void init_sync_env(RGWMetaSyncEnv *env);
+  int store_sync_info();
+
+  atomic_t going_down;
+
+public:
+  RGWRemoteMetaLog(RGWRados *_store, RGWAsyncRadosProcessor *async_rados,
+                   RGWMetaSyncStatusManager *_sm)
+    : RGWCoroutinesManager(_store->ctx(), _store->get_cr_registry()),
+      store(_store), conn(NULL), async_rados(async_rados),
+      http_manager(store->ctx(), completion_mgr),
+      status_manager(_sm), error_logger(NULL), meta_sync_cr(NULL) {}
+
+  ~RGWRemoteMetaLog();
+
+  int init();
+  void finish();
+
+  int read_log_info(rgw_mdlog_info *log_info);
+  int read_master_log_shards_info(string *master_period, map<int, RGWMetadataLogInfo> *shards_info);
+  int read_master_log_shards_next(const string& period, map<int, string> shard_markers, map<int, rgw_mdlog_shard_data> *result);
+  int read_sync_status();
+  int init_sync_status();
+  int run_sync();
+
+  void wakeup(int shard_id);
+
+  RGWMetaSyncEnv& get_sync_env() {
+    return sync_env;
+  }
+  const rgw_meta_sync_status& get_sync_status() const { return sync_status; }
+};
+
+class RGWMetaSyncStatusManager {
+  RGWRados *store;
+  librados::IoCtx ioctx;
+
+  RGWRemoteMetaLog master_log;
+
+  map<int, rgw_obj> shard_objs;
+
+  struct utime_shard {
+    real_time ts;
+    int shard_id;
+
+    utime_shard() : shard_id(-1) {}
+
+    bool operator<(const utime_shard& rhs) const {
+      if (ts == rhs.ts) {
+	return shard_id < rhs.shard_id;
+      }
+      return ts < rhs.ts;
+    }
+  };
+
+  RWLock ts_to_shard_lock;
+  map<utime_shard, int> ts_to_shard;
+  vector<string> clone_markers;
+
+public:
+  RGWMetaSyncStatusManager(RGWRados *_store, RGWAsyncRadosProcessor *async_rados)
+    : store(_store), master_log(store, async_rados, this),
+      ts_to_shard_lock("ts_to_shard_lock") {}
+  int init();
+  void finish();
+
+  const rgw_meta_sync_status& get_sync_status() const {
+    return master_log.get_sync_status();
+  }
+
+  int read_sync_status() { return master_log.read_sync_status(); }
+  int init_sync_status() { return master_log.init_sync_status(); }
+  int read_log_info(rgw_mdlog_info *log_info) {
+    return master_log.read_log_info(log_info);
+  }
+  int read_master_log_shards_info(string *master_period, map<int, RGWMetadataLogInfo> *shards_info) {
+    return master_log.read_master_log_shards_info(master_period, shards_info);
+  }
+  int read_master_log_shards_next(const string& period, map<int, string> shard_markers, map<int, rgw_mdlog_shard_data> *result) {
+    return master_log.read_master_log_shards_next(period, shard_markers, result);
+  }
+
+  int run() { return master_log.run_sync(); }
+
+  void wakeup(int shard_id) { return master_log.wakeup(shard_id); }
+  void stop() {
+    master_log.finish();
+  }
+};
+
+template <class T, class K>
+class RGWSyncShardMarkerTrack {
+  struct marker_entry {
+    uint64_t pos;
+    real_time timestamp;
+
+    marker_entry() : pos(0) {}
+    marker_entry(uint64_t _p, const real_time& _ts) : pos(_p), timestamp(_ts) {}
+  };
+  typename std::map<T, marker_entry> pending;
+
+  T high_marker;
+  marker_entry high_entry;
+
+  int window_size;
+  int updates_since_flush;
+
+
+protected:
+  typename std::set<K> need_retry_set;
+
+  virtual RGWCoroutine *store_marker(const T& new_marker, uint64_t index_pos, const real_time& timestamp) = 0;
+  virtual void handle_finish(const T& marker) { }
+
+public:
+  RGWSyncShardMarkerTrack(int _window_size) : window_size(_window_size), updates_since_flush(0) {}
+  virtual ~RGWSyncShardMarkerTrack() {}
+
+  bool start(const T& pos, int index_pos, const real_time& timestamp) {
+    if (pending.find(pos) != pending.end()) {
+      return false;
+    }
+    pending[pos] = marker_entry(index_pos, timestamp);
+    return true;
+  }
+
+  void try_update_high_marker(const T& pos, int index_pos, const real_time& timestamp) {
+    if (!(pos <= high_marker)) {
+      high_marker = pos;
+      high_entry = marker_entry(index_pos, timestamp);
+    }
+  }
+
+  RGWCoroutine *finish(const T& pos) {
+    if (pending.empty()) {
+      /* can happen, due to a bug that ended up with multiple objects with the same name and version
+       * -- which can happen when versioning is enabled an the version is 'null'.
+       */
+      return NULL;
+    }
+
+    typename std::map<T, marker_entry>::iterator iter = pending.begin();
+
+    bool is_first = (pos == iter->first);
+
+    typename std::map<T, marker_entry>::iterator pos_iter = pending.find(pos);
+    if (pos_iter == pending.end()) {
+      /* see pending.empty() comment */
+      return NULL;
+    }
+
+    if (!(pos <= high_marker)) {
+      high_marker = pos;
+      high_entry = pos_iter->second;
+    }
+
+    pending.erase(pos);
+
+    handle_finish(pos);
+
+    updates_since_flush++;
+
+    if (is_first && (updates_since_flush >= window_size || pending.empty())) {
+      return update_marker(high_marker, high_entry);
+    }
+    return NULL;
+  }
+
+  RGWCoroutine *update_marker(const T& new_marker, marker_entry& entry) {
+    updates_since_flush = 0;
+    return store_marker(new_marker, entry.pos, entry.timestamp);
+  }
+
+  /*
+   * a key needs retry if it was processing when another marker that points
+   * to the same bucket shards arrives. Instead of processing it, we mark
+   * it as need_retry so that when we finish processing the original, we
+   * retry the processing on the same bucket shard, in case there are more
+   * entries to process. This closes a race that can happen.
+   */
+  bool need_retry(const K& key) {
+    return (need_retry_set.find(key) != need_retry_set.end());
+  }
+
+  void set_need_retry(const K& key) {
+    need_retry_set.insert(key);
+  }
+
+  void reset_need_retry(const K& key) {
+    need_retry_set.erase(key);
+  }
+};
+
+class RGWMetaSyncShardMarkerTrack;
+
+class RGWMetaSyncSingleEntryCR : public RGWCoroutine {
+  RGWMetaSyncEnv *sync_env;
+
+  string raw_key;
+  string entry_marker;
+  RGWMDLogStatus op_status;
+
+  ssize_t pos;
+  string section;
+  string key;
+
+  int sync_status;
+
+  bufferlist md_bl;
+
+  RGWMetaSyncShardMarkerTrack *marker_tracker;
+
+  int tries;
+
+public:
+  RGWMetaSyncSingleEntryCR(RGWMetaSyncEnv *_sync_env,
+		           const string& _raw_key, const string& _entry_marker,
+                           const RGWMDLogStatus& _op_status,
+                           RGWMetaSyncShardMarkerTrack *_marker_tracker) : RGWCoroutine(_sync_env->cct),
+                                                      sync_env(_sync_env),
+						      raw_key(_raw_key), entry_marker(_entry_marker),
+                                                      op_status(_op_status),
+                                                      pos(0), sync_status(0),
+                                                      marker_tracker(_marker_tracker), tries(0) {
+  }
+
+  int operate();
+};
+
+class RGWShardCollectCR : public RGWCoroutine {
+  CephContext *cct;
+
+  int cur_shard;
+  int current_running;
+  int max_concurrent;
+  int status;
+
+public:
+  RGWShardCollectCR(CephContext *_cct, int _max_concurrent) : RGWCoroutine(_cct),
+                                                             current_running(0),
+                                                             max_concurrent(_max_concurrent),
+                                                             status(0) {}
+
+  virtual bool spawn_next() = 0;
+  int operate();
+};
+
+
+#endif
diff --git a/src/rgw/rgw_token.cc b/src/rgw/rgw_token.cc
new file mode 100644
index 0000000..c4ae0f0
--- /dev/null
+++ b/src/rgw/rgw_token.cc
@@ -0,0 +1,135 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+/*
+ * Ceph - scalable distributed file system
+ *
+ * Copyright (C) 2016 Red Hat, Inc.
+ *
+ * This is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software
+ * Foundation.  See file COPYING.
+ *
+ */
+
+#include <errno.h>
+#include <iostream>
+#include <sstream>
+#include <string>
+
+#include "common/config.h"
+#include "common/ceph_argparse.h"
+#include "common/debug.h"
+#include "global/global_init.h"
+#include "include/assert.h"
+#include "include/str_list.h"
+
+#include "rgw_token.h"
+#include "rgw_b64.h"
+
+#define dout_subsys ceph_subsys_rgw
+
+namespace {
+
+  using namespace rgw;
+  using std::get;
+  using std::string;
+
+  RGWToken::token_type type{RGWToken::TOKEN_NONE};
+  string access_key{""};
+  string secret_key{""};
+
+  Formatter* formatter{nullptr};
+
+  bool verbose {false};
+  bool do_encode {false};
+  bool do_decode {false};
+
+}
+
+void usage()
+{
+  cout << "usage: radosgw-token --encode --ttype=<token type> [options...]" << std::endl;
+  cout << "\t(maybe exporting RGW_ACCESS_KEY_ID and RGW_SECRET_ACCESS_KEY)"    
+       << std::endl;
+  cout << "\t <token type> := ad | ldap" << std::endl;
+  cout << "\n";
+  generic_client_usage();
+}
+
+int main(int argc, char **argv)
+{
+  std::string val;
+  vector<const char*> args;
+  argv_to_vec(argc, (const char **)argv, args);
+  env_to_vec(args);
+
+  global_init(NULL, args, CEPH_ENTITY_TYPE_CLIENT, CODE_ENVIRONMENT_UTILITY, 0);
+  common_init_finish(g_ceph_context);
+
+  char *v{nullptr};
+  v = getenv("RGW_ACCESS_KEY_ID");
+  if (v) {
+    access_key = v;
+  }
+
+  v = getenv("RGW_SECRET_ACCESS_KEY");
+  if (v) {
+    secret_key = v;
+  }
+
+  for (auto arg_iter = args.begin(); arg_iter != args.end();) {
+    if (ceph_argparse_witharg(args, arg_iter, &val, "--access",
+			      (char*) nullptr)) {
+      access_key = val;
+    } else if (ceph_argparse_witharg(args, arg_iter, &val, "--secret",
+				     (char*) nullptr)) {
+      secret_key = val;
+    } else if (ceph_argparse_witharg(args, arg_iter, &val, "--ttype",
+				     (char*) nullptr)) {
+      for (const auto& ttype : {"ad", "ldap"}) {
+	if (boost::iequals(val, ttype)) {
+	  type = RGWToken::to_type(val);
+	  break;
+	}
+      }
+    } else if (ceph_argparse_flag(args, arg_iter, "--encode",
+					    (char*) nullptr)) {
+      do_encode = true;
+    } else if (ceph_argparse_flag(args, arg_iter, "--decode",
+					    (char*) nullptr)) {
+      do_decode = true;
+    } else if (ceph_argparse_flag(args, arg_iter, "--verbose",
+					    (char*) nullptr)) {
+      verbose = true;
+    } else {
+      ++arg_iter;
+    }
+  }
+
+  if ((! do_encode) ||
+      (type == RGWToken::TOKEN_NONE)) {
+    usage();
+    return -EINVAL;
+  }
+
+  formatter = new JSONFormatter(true /* pretty */);
+
+  RGWToken token(type, access_key, secret_key);
+  if (do_encode) {
+    token.encode_json(formatter);
+    std::ostringstream os;
+    formatter->flush(os);
+    string token_str = os.str();
+    if (verbose) {
+      std::cout << "expanded token: " << token_str << std::endl;
+      if (do_decode) {
+	RGWToken token2(token_str);
+	std::cout << "decoded expanded token: " << token2 << std::endl;
+      }
+    }
+    std::cout << to_base64(token_str) << std::endl;
+  }
+
+  return 0;
+}
diff --git a/src/rgw/rgw_token.h b/src/rgw/rgw_token.h
new file mode 100644
index 0000000..7dce9a9
--- /dev/null
+++ b/src/rgw/rgw_token.h
@@ -0,0 +1,169 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+/*
+ * Ceph - scalable distributed file system
+ *
+ * Copyright (C) 2016 Red Hat, Inc
+ *
+ * This is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software
+ * Foundation.  See file COPYING.
+ *
+ */
+
+#ifndef RGW_TOKEN_H
+#define RGW_TOKEN_H
+
+#include <stdint.h>
+#include <boost/algorithm/string.hpp>
+#include <sstream>
+
+#include "common/ceph_json.h"
+#include "common/Formatter.h"
+#include "rgw/rgw_b64.h"
+
+namespace rgw {
+
+  using std::string;
+
+  class RGWToken {
+  public:
+    static constexpr auto type_name = "RGW_TOKEN";
+
+    enum token_type : uint32_t {
+      TOKEN_NONE,
+	TOKEN_AD,
+	TOKEN_KEYSTONE,
+	TOKEN_LDAP,
+    };
+
+    static enum token_type to_type(const string& s) {
+      if (boost::iequals(s, "ad"))
+	return TOKEN_AD;
+      if (boost::iequals(s, "ldap"))
+	return TOKEN_LDAP;
+      if (boost::iequals(s, "keystone"))
+	return TOKEN_KEYSTONE;
+      return TOKEN_NONE;
+    }
+
+    static const char* from_type(enum token_type type) {
+      switch (type) {
+      case TOKEN_AD:
+	return "ad";
+	break;
+      case TOKEN_LDAP:
+	return "ldap";
+	break;
+      case TOKEN_KEYSTONE:
+	return "keystone";
+	break;
+      default:
+	return "none";
+      };
+      return "none";
+    }
+
+    token_type type;
+    string id;
+    string key;
+
+    virtual uint32_t version() const { return 1; };
+
+    bool valid() {
+      return ((type != TOKEN_NONE) &&
+	      (! id.empty()) &&
+	      (! key.empty()));
+    }
+
+    RGWToken()
+      : type(TOKEN_NONE) {};
+
+    RGWToken(enum token_type _type, const std::string& _id,
+	     const std::string& _key)
+      : type(_type), id(_id), key(_key) {};
+
+    RGWToken(const string& json) {
+      JSONParser p;
+      p.parse(json.c_str(), json.length());
+      JSONDecoder::decode_json(RGWToken::type_name, *this, &p);
+    }
+
+    void encode(bufferlist& bl) const {
+      uint32_t ver = version();
+      string typestr{from_type(type)};
+      ENCODE_START(1, 1, bl);
+      ::encode(type_name, bl);
+      ::encode(ver, bl);
+      ::encode(typestr, bl);
+      ::encode(id, bl);
+      ::encode(key, bl);
+      ENCODE_FINISH(bl);
+    }
+
+    void decode(bufferlist::iterator& bl) {
+      string name;
+      string typestr;
+      uint32_t version;
+      DECODE_START(1, bl);
+      ::decode(name, bl);
+      ::decode(version, bl);
+      ::decode(typestr, bl);
+      type = to_type(typestr.c_str());
+      ::decode(id, bl);
+      ::decode(key, bl);
+      DECODE_FINISH(bl);
+    }
+
+    void dump(Formatter* f) const {
+      ::encode_json("version", uint32_t(version()), f);
+      ::encode_json("type", from_type(type), f);
+      ::encode_json("id", id, f);
+      ::encode_json("key", key, f);
+    }
+
+    void encode_json(Formatter* f) {
+      RGWToken& token = *this;
+      f->open_object_section(type_name);
+      ::encode_json(type_name, token, f);
+      f->close_section();
+    }
+
+    void decode_json(JSONObj* obj) {
+      uint32_t version;
+      string type_name;
+      string typestr;
+      JSONDecoder::decode_json("version", version, obj);
+      JSONDecoder::decode_json("type", typestr, obj);
+      type = to_type(typestr.c_str());
+      JSONDecoder::decode_json("id", id, obj);
+      JSONDecoder::decode_json("key", key, obj);
+    }
+
+    std::string encode_json_base64(Formatter* f) {
+      encode_json(f);
+      std::ostringstream os;
+      f->flush(os);
+      return std::move(to_base64(std::move(os.str())));
+    }
+
+    friend inline ostream& operator<<(ostream& os, const RGWToken& token);
+
+    virtual ~RGWToken() {};
+  };
+  WRITE_CLASS_ENCODER(RGWToken)
+
+  inline ostream& operator<<(ostream& os, const RGWToken& token)
+  {
+    os << "<<RGWToken"
+       << " type=" << RGWToken::from_type(token.type)
+       << " id=" << token.id
+       << " key=" << token.key
+       << ">>";
+    return os;
+  }
+
+} /* namespace rgw */
+
+#endif /* RGW_TOKEN_H */
diff --git a/src/rgw/rgw_tools.cc b/src/rgw/rgw_tools.cc
index 0dfc3e6..e97b432 100644
--- a/src/rgw/rgw_tools.cc
+++ b/src/rgw/rgw_tools.cc
@@ -19,7 +19,7 @@
 static map<string, string> ext_mime_map;
 
 int rgw_put_system_obj(RGWRados *rgwstore, rgw_bucket& bucket, string& oid, const char *data, size_t size, bool exclusive,
-                       RGWObjVersionTracker *objv_tracker, time_t set_mtime, map<string, bufferlist> *pattrs)
+                       RGWObjVersionTracker *objv_tracker, real_time set_mtime, map<string, bufferlist> *pattrs)
 {
   map<string,bufferlist> no_attrs;
   if (!pattrs)
@@ -39,7 +39,7 @@ int rgw_put_system_obj(RGWRados *rgwstore, rgw_bucket& bucket, string& oid, cons
 }
 
 int rgw_get_system_obj(RGWRados *rgwstore, RGWObjectCtx& obj_ctx, rgw_bucket& bucket, const string& key, bufferlist& bl,
-                       RGWObjVersionTracker *objv_tracker, time_t *pmtime, map<string, bufferlist> *pattrs,
+                       RGWObjVersionTracker *objv_tracker, real_time *pmtime, map<string, bufferlist> *pattrs,
                        rgw_cache_entry_info *cache_info)
 {
   struct rgw_err err;
diff --git a/src/rgw/rgw_tools.h b/src/rgw/rgw_tools.h
index daffabe..f778b47 100644
--- a/src/rgw/rgw_tools.h
+++ b/src/rgw/rgw_tools.h
@@ -7,6 +7,7 @@
 #include <string>
 
 #include "include/types.h"
+#include "common/ceph_time.h"
 #include "rgw_common.h"
 
 class RGWRados;
@@ -16,9 +17,9 @@ struct RGWObjVersionTracker;
 struct obj_version;
 
 int rgw_put_system_obj(RGWRados *rgwstore, rgw_bucket& bucket, string& oid, const char *data, size_t size, bool exclusive,
-                       RGWObjVersionTracker *objv_tracker, time_t set_mtime, map<string, bufferlist> *pattrs = NULL);
+                       RGWObjVersionTracker *objv_tracker, real_time set_mtime, map<string, bufferlist> *pattrs = NULL);
 int rgw_get_system_obj(RGWRados *rgwstore, RGWObjectCtx& obj_ctx, rgw_bucket& bucket, const string& key, bufferlist& bl,
-                       RGWObjVersionTracker *objv_tracker, time_t *pmtime, map<string, bufferlist> *pattrs = NULL,
+                       RGWObjVersionTracker *objv_tracker, real_time *pmtime, map<string, bufferlist> *pattrs = NULL,
                        rgw_cache_entry_info *cache_info = NULL);
 
 int rgw_tools_init(CephContext *cct);
diff --git a/src/rgw/rgw_usage.cc b/src/rgw/rgw_usage.cc
index f8495c5..03a4ab4 100644
--- a/src/rgw/rgw_usage.cc
+++ b/src/rgw/rgw_usage.cc
@@ -78,7 +78,7 @@ int RGWUsage::show(RGWRados *store, rgw_user& uid, uint64_t start_epoch,
             formatter->close_section();
           }
           formatter->open_object_section("user");
-          formatter->dump_string("owner", ub.user);
+          formatter->dump_string("user", ub.user);
           formatter->open_array_section("buckets");
           user_section_open = true;
           last_owner = ub.user;
@@ -88,6 +88,12 @@ int RGWUsage::show(RGWRados *store, rgw_user& uid, uint64_t start_epoch,
         utime_t ut(entry.epoch, 0);
         ut.gmtime(formatter->dump_stream("time"));
         formatter->dump_int("epoch", entry.epoch);
+        string owner = entry.owner.to_str();
+        string payer = entry.payer.to_str();
+        formatter->dump_string("owner", owner);
+        if (!payer.empty() && payer != owner) {
+          formatter->dump_string("payer", payer);
+        }
         dump_usage_categories_info(formatter, entry, categories);
         formatter->close_section(); // bucket
         flusher.flush();
diff --git a/src/rgw/rgw_user.cc b/src/rgw/rgw_user.cc
index fb313d0..53f4a75 100644
--- a/src/rgw/rgw_user.cc
+++ b/src/rgw/rgw_user.cc
@@ -50,13 +50,14 @@ int rgw_user_sync_all_stats(RGWRados *store, const rgw_user& user_id)
   CephContext *cct = store->ctx();
   size_t max_entries = cct->_conf->rgw_list_buckets_max_chunk;
   bool done;
+  bool is_truncated;
   string marker;
   int ret;
 
   do {
     RGWUserBuckets user_buckets;
-    ret = rgw_read_user_buckets(store, user_id, user_buckets,
-                                marker, string(), max_entries, false);
+    ret = rgw_read_user_buckets(store, user_id, user_buckets, marker,
+				string(), max_entries, false, &is_truncated);
     if (ret < 0) {
       ldout(cct, 0) << "failed to read user buckets: ret=" << ret << dendl;
       return ret;
@@ -94,7 +95,7 @@ int rgw_store_user_info(RGWRados *store,
                         RGWUserInfo& info,
                         RGWUserInfo *old_info,
                         RGWObjVersionTracker *objv_tracker,
-                        time_t mtime,
+                        real_time mtime,
                         bool exclusive,
                         map<string, bufferlist> *pattrs)
 {
@@ -167,8 +168,8 @@ int rgw_store_user_info(RGWRados *store,
   if (!info.user_email.empty()) {
     if (!old_info ||
         old_info->user_email.compare(info.user_email) != 0) { /* only if new index changed */
-      ret = rgw_put_system_obj(store, store->zone.user_email_pool, info.user_email,
-                               link_bl.c_str(), link_bl.length(), exclusive, NULL, 0);
+      ret = rgw_put_system_obj(store, store->get_zone_params().user_email_pool, info.user_email,
+                               link_bl.c_str(), link_bl.length(), exclusive, NULL, real_time());
       if (ret < 0)
         return ret;
     }
@@ -181,9 +182,9 @@ int rgw_store_user_info(RGWRados *store,
       if (old_info && old_info->access_keys.count(iter->first) != 0)
 	continue;
 
-      ret = rgw_put_system_obj(store, store->zone.user_keys_pool, k.id,
+      ret = rgw_put_system_obj(store, store->get_zone_params().user_keys_pool, k.id,
                                link_bl.c_str(), link_bl.length(), exclusive,
-                               NULL, 0);
+                               NULL, real_time());
       if (ret < 0)
         return ret;
     }
@@ -195,9 +196,9 @@ int rgw_store_user_info(RGWRados *store,
     if (old_info && old_info->swift_keys.count(siter->first) != 0)
       continue;
 
-    ret = rgw_put_system_obj(store, store->zone.user_swift_pool, k.id,
+    ret = rgw_put_system_obj(store, store->get_zone_params().user_swift_pool, k.id,
                              link_bl.c_str(), link_bl.length(), exclusive,
-                             NULL, 0);
+                             NULL, real_time());
     if (ret < 0)
       return ret;
   }
@@ -205,28 +206,16 @@ int rgw_store_user_info(RGWRados *store,
   return ret;
 }
 
-int rgw_store_user_attrs(RGWRados *const store,
-                         string& user_id,
-                         map<string, bufferlist>& attrs,
-                         map<string, bufferlist>* const rmattrs,
-                         RGWObjVersionTracker * const objv_tracker)
-{
-  rgw_obj obj(store->zone.user_uid_pool, user_id);
-
-  return store->meta_mgr->set_attrs(user_meta_handler, user_id, obj,
-                                    attrs, rmattrs, objv_tracker);
-}
-
 struct user_info_entry {
   RGWUserInfo info;
   RGWObjVersionTracker objv_tracker;
-  time_t mtime;
+  real_time mtime;
 };
 
 static RGWChainedCacheImpl<user_info_entry> uinfo_cache;
 
 int rgw_get_user_info_from_index(RGWRados *store, string& key, rgw_bucket& bucket, RGWUserInfo& info,
-                                 RGWObjVersionTracker *objv_tracker, time_t *pmtime)
+                                 RGWObjVersionTracker *objv_tracker, real_time *pmtime)
 {
   user_info_entry e;
   if (uinfo_cache.find(key, &e)) {
@@ -279,10 +268,10 @@ int rgw_get_user_info_from_index(RGWRados *store, string& key, rgw_bucket& bucke
  * returns: 0 on success, -ERR# on failure (including nonexistence)
  */
 int rgw_get_user_info_by_uid(RGWRados *store,
-                             rgw_user& uid,
+                             const rgw_user& uid,
                              RGWUserInfo& info,
                              RGWObjVersionTracker *objv_tracker,
-                             time_t *pmtime,
+                             real_time *pmtime,
                              rgw_cache_entry_info *cache_info,
                              map<string, bufferlist> *pattrs)
 {
@@ -291,7 +280,7 @@ int rgw_get_user_info_by_uid(RGWRados *store,
 
   RGWObjectCtx obj_ctx(store);
   string oid = uid.to_str();
-  int ret = rgw_get_system_obj(store, obj_ctx, store->zone.user_uid_pool, oid, bl, objv_tracker, pmtime, pattrs, cache_info);
+  int ret = rgw_get_system_obj(store, obj_ctx, store->get_zone_params().user_uid_pool, oid, bl, objv_tracker, pmtime, pattrs, cache_info);
   if (ret < 0) {
     return ret;
   }
@@ -319,9 +308,9 @@ int rgw_get_user_info_by_uid(RGWRados *store,
  * returns: 0 on success, -ERR# on failure (including nonexistence)
  */
 int rgw_get_user_info_by_email(RGWRados *store, string& email, RGWUserInfo& info,
-                               RGWObjVersionTracker *objv_tracker, time_t *pmtime)
+                               RGWObjVersionTracker *objv_tracker, real_time *pmtime)
 {
-  return rgw_get_user_info_from_index(store, email, store->zone.user_email_pool, info, objv_tracker, pmtime);
+  return rgw_get_user_info_from_index(store, email, store->get_zone_params().user_email_pool, info, objv_tracker, pmtime);
 }
 
 /**
@@ -329,9 +318,9 @@ int rgw_get_user_info_by_email(RGWRados *store, string& email, RGWUserInfo& info
  * returns: 0 on success, -ERR# on failure (including nonexistence)
  */
 extern int rgw_get_user_info_by_swift(RGWRados *store, string& swift_name, RGWUserInfo& info,
-                                      RGWObjVersionTracker *objv_tracker, time_t *pmtime)
+                                      RGWObjVersionTracker *objv_tracker, real_time *pmtime)
 {
-  return rgw_get_user_info_from_index(store, swift_name, store->zone.user_swift_pool, info, objv_tracker, pmtime);
+  return rgw_get_user_info_from_index(store, swift_name, store->get_zone_params().user_swift_pool, info, objv_tracker, pmtime);
 }
 
 /**
@@ -339,9 +328,9 @@ extern int rgw_get_user_info_by_swift(RGWRados *store, string& swift_name, RGWUs
  * returns: 0 on success, -ERR# on failure (including nonexistence)
  */
 extern int rgw_get_user_info_by_access_key(RGWRados *store, string& access_key, RGWUserInfo& info,
-                                           RGWObjVersionTracker *objv_tracker, time_t *pmtime)
+                                           RGWObjVersionTracker *objv_tracker, real_time *pmtime)
 {
-  return rgw_get_user_info_from_index(store, access_key, store->zone.user_keys_pool, info, objv_tracker, pmtime);
+  return rgw_get_user_info_from_index(store, access_key, store->get_zone_params().user_keys_pool, info, objv_tracker, pmtime);
 }
 
 int rgw_get_user_attrs_by_uid(RGWRados *store,
@@ -350,7 +339,7 @@ int rgw_get_user_attrs_by_uid(RGWRados *store,
                               RGWObjVersionTracker *objv_tracker)
 {
   RGWObjectCtx obj_ctx(store);
-  rgw_obj obj(store->zone.user_uid_pool, user_id.to_str());
+  rgw_obj obj(store->get_zone_params().user_uid_pool, user_id.to_str());
   RGWRados::SystemObject src(store, obj_ctx, obj);
   RGWRados::SystemObject::Read rop(&src);
 
@@ -360,7 +349,7 @@ int rgw_get_user_attrs_by_uid(RGWRados *store,
 
 int rgw_remove_key_index(RGWRados *store, RGWAccessKey& access_key)
 {
-  rgw_obj obj(store->zone.user_keys_pool, access_key.id);
+  rgw_obj obj(store->get_zone_params().user_keys_pool, access_key.id);
   int ret = store->delete_system_obj(obj);
   return ret;
 }
@@ -383,14 +372,14 @@ int rgw_remove_uid_index(RGWRados *store, rgw_user& uid)
 
 int rgw_remove_email_index(RGWRados *store, string& email)
 {
-  rgw_obj obj(store->zone.user_email_pool, email);
+  rgw_obj obj(store->get_zone_params().user_email_pool, email);
   int ret = store->delete_system_obj(obj);
   return ret;
 }
 
 int rgw_remove_swift_name_index(RGWRados *store, string& swift_name)
 {
-  rgw_obj obj(store->zone.user_swift_pool, swift_name);
+  rgw_obj obj(store->get_zone_params().user_swift_pool, swift_name);
   int ret = store->delete_system_obj(obj);
   return ret;
 }
@@ -406,14 +395,15 @@ int rgw_delete_user(RGWRados *store, RGWUserInfo& info, RGWObjVersionTracker& ob
   vector<rgw_bucket> buckets_vec;
 
   bool done;
+  bool is_truncated;
   int ret;
   CephContext *cct = store->ctx();
   size_t max_buckets = cct->_conf->rgw_list_buckets_max_chunk;
 
   do {
     RGWUserBuckets user_buckets;
-    ret = rgw_read_user_buckets(store, info.user_id, user_buckets,
-                                marker, string(), max_buckets, false);
+    ret = rgw_read_user_buckets(store, info.user_id, user_buckets, marker,
+				string(), max_buckets, false, &is_truncated);
     if (ret < 0)
       return ret;
 
@@ -452,7 +442,7 @@ int rgw_delete_user(RGWRados *store, RGWUserInfo& info, RGWObjVersionTracker& ob
     }
   }
 
-  rgw_obj email_obj(store->zone.user_email_pool, info.user_email);
+  rgw_obj email_obj(store->get_zone_params().user_email_pool, info.user_email);
   ldout(store->ctx(), 10) << "removing email index: " << info.user_email << dendl;
   ret = store->delete_system_obj(email_obj);
   if (ret < 0 && ret != -ENOENT) {
@@ -462,7 +452,7 @@ int rgw_delete_user(RGWRados *store, RGWUserInfo& info, RGWObjVersionTracker& ob
 
   string buckets_obj_id;
   rgw_get_buckets_obj(info.user_id, buckets_obj_id);
-  rgw_obj uid_bucks(store->zone.user_uid_pool, buckets_obj_id);
+  rgw_obj uid_bucks(store->get_zone_params().user_uid_pool, buckets_obj_id);
   ldout(store->ctx(), 10) << "removing user buckets index" << dendl;
   ret = store->delete_system_obj(uid_bucks);
   if (ret < 0 && ret != -ENOENT) {
@@ -473,7 +463,7 @@ int rgw_delete_user(RGWRados *store, RGWUserInfo& info, RGWObjVersionTracker& ob
   string key;
   info.user_id.to_str(key);
   
-  rgw_obj uid_obj(store->zone.user_uid_pool, key);
+  rgw_obj uid_obj(store->get_zone_params().user_uid_pool, key);
   ldout(store->ctx(), 10) << "removing user index: " << info.user_id << dendl;
   ret = store->meta_mgr->remove_entry(user_meta_handler, key, &objv_tracker);
   if (ret < 0 && ret != -ENOENT && ret  != -ECANCELED) {
@@ -1813,7 +1803,7 @@ int RGWUser::update(RGWUserAdminOpState& op_state, std::string *err_msg)
   }
 
   if (is_populated()) {
-    ret = rgw_store_user_info(store, user_info, &old_info, &op_state.objv, 0, false);
+    ret = rgw_store_user_info(store, user_info, &old_info, &op_state.objv, real_time(), false);
     if (ret < 0) {
       set_err_msg(err_msg, "unable to store user info");
       return ret;
@@ -1825,7 +1815,7 @@ int RGWUser::update(RGWUserAdminOpState& op_state, std::string *err_msg)
       return ret;
     }
   } else {
-    ret = rgw_store_user_info(store, user_info, NULL, &op_state.objv, 0, false);
+    ret = rgw_store_user_info(store, user_info, NULL, &op_state.objv, real_time(), false);
     if (ret < 0) {
       set_err_msg(err_msg, "unable to store user info");
       return ret;
@@ -2023,13 +2013,14 @@ int RGWUser::execute_remove(RGWUserAdminOpState& op_state, std::string *err_msg)
   }
 
   bool done;
+  bool is_truncated;
   string marker;
   CephContext *cct = store->ctx();
   size_t max_buckets = cct->_conf->rgw_list_buckets_max_chunk;
   do {
     RGWUserBuckets buckets;
-    ret = rgw_read_user_buckets(store, uid, buckets,
-                                marker, string(), max_buckets, false);
+    ret = rgw_read_user_buckets(store, uid, buckets, marker, string(),
+				max_buckets, false, &is_truncated);
     if (ret < 0) {
       set_err_msg(err_msg, "unable to read user bucket info");
       return ret;
@@ -2174,12 +2165,13 @@ int RGWUser::execute_modify(RGWUserAdminOpState& op_state, std::string *err_msg)
     }
 
     bool done;
+    bool is_truncated;
     string marker;
     CephContext *cct = store->ctx();
     size_t max_buckets = cct->_conf->rgw_list_buckets_max_chunk;
     do {
-      ret = rgw_read_user_buckets(store, user_id, buckets,
-                                  marker, string(), max_buckets, false);
+      ret = rgw_read_user_buckets(store, user_id, buckets, marker, string(),
+				  max_buckets, false, &is_truncated);
       if (ret < 0) {
         set_err_msg(err_msg, "could not get buckets for uid:  " + user_id.to_str());
         return ret;
@@ -2577,7 +2569,7 @@ struct RGWUserCompleteInfo {
 class RGWUserMetadataObject : public RGWMetadataObject {
   RGWUserCompleteInfo uci;
 public:
-  RGWUserMetadataObject(const RGWUserCompleteInfo& _uci, obj_version& v, time_t m)
+  RGWUserMetadataObject(const RGWUserCompleteInfo& _uci, obj_version& v, real_time m)
       : uci(_uci) {
     objv = v;
     mtime = m;
@@ -2595,7 +2587,7 @@ public:
   int get(RGWRados *store, string& entry, RGWMetadataObject **obj) {
     RGWUserCompleteInfo uci;
     RGWObjVersionTracker objv_tracker;
-    time_t mtime;
+    real_time mtime;
 
     rgw_user uid(entry);
 
@@ -2612,7 +2604,7 @@ public:
   }
 
   int put(RGWRados *store, string& entry, RGWObjVersionTracker& objv_tracker,
-          time_t mtime, JSONObj *obj, sync_type_t sync_mode) {
+          real_time mtime, JSONObj *obj, sync_type_t sync_mode) {
     RGWUserCompleteInfo uci;
 
     try {
@@ -2629,7 +2621,7 @@ public:
     rgw_user uid(entry);
 
     RGWUserInfo old_info;
-    time_t orig_mtime;
+    real_time orig_mtime;
     int ret = rgw_get_user_info_by_uid(store, uid, old_info, &objv_tracker, &orig_mtime);
     if (ret < 0 && ret != -ENOENT)
       return ret;
@@ -2668,7 +2660,7 @@ public:
 
   void get_pool_and_oid(RGWRados *store, const string& key, rgw_bucket& bucket, string& oid) {
     oid = key;
-    bucket = store->zone.user_uid_pool;
+    bucket = store->get_zone_params().user_uid_pool;
   }
 
   int list_keys_init(RGWRados *store, void **phandle)
@@ -2693,7 +2685,7 @@ public:
 
     list<string> unfiltered_keys;
 
-    int ret = store->list_raw_objects(store->zone.user_uid_pool, no_filter,
+    int ret = store->list_raw_objects(store->get_zone_params().user_uid_pool, no_filter,
                                       max, info->ctx, unfiltered_keys, truncated);
     if (ret < 0 && ret != -ENOENT)
       return ret;		        
diff --git a/src/rgw/rgw_user.h b/src/rgw/rgw_user.h
index bff4a52..da40d85 100644
--- a/src/rgw/rgw_user.h
+++ b/src/rgw/rgw_user.h
@@ -63,29 +63,19 @@ extern int rgw_store_user_info(RGWRados *store,
                                RGWUserInfo& info,
                                RGWUserInfo *old_info,
                                RGWObjVersionTracker *objv_tracker,
-                               time_t mtime,
+                               real_time mtime,
                                bool exclusive,
                                map<string, bufferlist> *pattrs = NULL);
-/**
- * Save the custom user metadata given in @attrs and delete those in @rmattrs
- * for user specified in @user_id.
- * Returns: 0 on success, -ERR# on failure.
- */
-extern int rgw_store_user_attrs(RGWRados *store,
-                                string& user_id,
-                                map<string, bufferlist>& attrs,
-                                map<string, bufferlist>* rmattrs,
-                                RGWObjVersionTracker *objv_tracker);
 
 /**
  * Given an user_id, finds the user info associated with it.
  * returns: 0 on success, -ERR# on failure (including nonexistence)
  */
 extern int rgw_get_user_info_by_uid(RGWRados *store,
-                                    rgw_user& user_id,
+                                    const rgw_user& user_id,
                                     RGWUserInfo& info,
                                     RGWObjVersionTracker *objv_tracker = NULL,
-                                    time_t *pmtime                     = NULL,
+                                    real_time *pmtime                     = NULL,
                                     rgw_cache_entry_info *cache_info   = NULL,
                                     map<string, bufferlist> *pattrs    = NULL);
 /**
@@ -93,19 +83,19 @@ extern int rgw_get_user_info_by_uid(RGWRados *store,
  * returns: 0 on success, -ERR# on failure (including nonexistence)
  */
 extern int rgw_get_user_info_by_email(RGWRados *store, string& email, RGWUserInfo& info,
-                                      RGWObjVersionTracker *objv_tracker = NULL, time_t *pmtime = NULL);
+                                      RGWObjVersionTracker *objv_tracker = NULL, real_time *pmtime = NULL);
 /**
  * Given an swift username, finds the user info associated with it.
  * returns: 0 on success, -ERR# on failure (including nonexistence)
  */
 extern int rgw_get_user_info_by_swift(RGWRados *store, string& swift_name, RGWUserInfo& info,
-                                      RGWObjVersionTracker *objv_tracker = NULL, time_t *pmtime = NULL);
+                                      RGWObjVersionTracker *objv_tracker = NULL, real_time *pmtime = NULL);
 /**
  * Given an access key, finds the user info associated with it.
  * returns: 0 on success, -ERR# on failure (including nonexistence)
  */
 extern int rgw_get_user_info_by_access_key(RGWRados *store, string& access_key, RGWUserInfo& info,
-                                           RGWObjVersionTracker *objv_tracker = NULL, time_t *pmtime = NULL);
+                                           RGWObjVersionTracker *objv_tracker = NULL, real_time *pmtime = NULL);
 /**
  * Get all the custom metadata stored for user specified in @user_id
  * and put it into @attrs.
@@ -268,7 +258,13 @@ struct RGWUserAdminOpState {
 
     size_t pos = _subuser.find(":");
     if (pos != string::npos) {
-      user_id.from_str(_subuser.substr(0, pos));
+      rgw_user tmp_id;
+      tmp_id.from_str(_subuser.substr(0, pos));
+      if (tmp_id.tenant.empty()) {
+        user_id.id = tmp_id.id;
+      } else {
+        user_id = tmp_id;
+      }
       subuser = _subuser.substr(pos+1);
     } else {
       subuser = _subuser;
diff --git a/src/spdk/CONFIG b/src/spdk/CONFIG
index ddce2cf..7a1c320 100644
--- a/src/spdk/CONFIG
+++ b/src/spdk/CONFIG
@@ -49,3 +49,8 @@ CONFIG_NVME_IMPL?=nvme_impl.h
 # Header file to use for IOAT implementation specific functions.
 # Defaults to depending on DPDK.
 CONFIG_IOAT_IMPL?=ioat_impl.h
+
+# This item indicates using libpciaccess library or not. If enabled with y,
+# libpciaccess library is used to map pci devices; else DPDK library is used to
+# map pci devices.
+CONFIG_PCIACCESS?=y
diff --git a/src/spdk/include/spdk/assert.h b/src/spdk/include/spdk/assert.h
index 6a71022..80b65b0 100644
--- a/src/spdk/include/spdk/assert.h
+++ b/src/spdk/include/spdk/assert.h
@@ -34,6 +34,10 @@
 #ifndef SPDK_ASSERT_H
 #define SPDK_ASSERT_H
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 #include <assert.h>
 
 #define SPDK_CONCAT_(x, y) x##y
@@ -52,4 +56,8 @@
         typedef char SPDK_CONCAT(SPDK_STATIC_ASSERT_, __LINE__)[!!(cond) - 1]
 #endif
 
+#ifdef __cplusplus
+}
+#endif
+
 #endif /* SPDK_ASSERT_H */
diff --git a/src/spdk/include/spdk/barrier.h b/src/spdk/include/spdk/barrier.h
index 0295967..637c64d 100644
--- a/src/spdk/include/spdk/barrier.h
+++ b/src/spdk/include/spdk/barrier.h
@@ -34,7 +34,15 @@
 #ifndef SPDK_BARRIER_H
 #define SPDK_BARRIER_H
 
-#define wmb()	__asm volatile("sfence" ::: "memory")
-#define mb()	__asm volatile("mfence" ::: "memory")
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define spdk_wmb()	__asm volatile("sfence" ::: "memory")
+#define spdk_mb()	__asm volatile("mfence" ::: "memory")
+
+#ifdef __cplusplus
+}
+#endif
 
 #endif
diff --git a/src/spdk/include/spdk/file.h b/src/spdk/include/spdk/file.h
index e696da3..5cb1769 100644
--- a/src/spdk/include/spdk/file.h
+++ b/src/spdk/include/spdk/file.h
@@ -34,9 +34,17 @@
 #ifndef SPDK_FILE_H
 #define SPDK_FILE_H
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 #include <stdint.h>
 
-uint64_t file_get_size(int fd);
-uint32_t dev_get_blocklen(int fd);
+uint64_t spdk_file_get_size(int fd);
+uint32_t spdk_dev_get_blocklen(int fd);
+
+#ifdef __cplusplus
+}
+#endif
 
 #endif
diff --git a/src/spdk/include/spdk/ioat.h b/src/spdk/include/spdk/ioat.h
index 3eec6b1..d44bd25 100644
--- a/src/spdk/include/spdk/ioat.h
+++ b/src/spdk/include/spdk/ioat.h
@@ -35,69 +35,126 @@
  * This file defines the public interface to the I/OAT DMA engine driver.
  */
 
-#ifndef __IOAT_H__
-#define __IOAT_H__
+#ifndef SPDK_IOAT_H
+#define SPDK_IOAT_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
 
 #include <inttypes.h>
 #include <stdbool.h>
+#include "spdk/pci.h"
+
+#include "spdk/pci.h"
+
+/**
+ * Opaque handle for a single I/OAT channel returned by \ref spdk_ioat_probe().
+ */
+struct spdk_ioat_chan;
 
 /**
  * Signature for callback function invoked when a request is completed.
  */
-typedef void (*ioat_callback_t)(void *arg);
+typedef void (*spdk_ioat_req_cb)(void *arg);
+
+/**
+ * Callback for spdk_ioat_probe() enumeration.
+ *
+ * \return true to attach to this device.
+ */
+typedef bool (*spdk_ioat_probe_cb)(void *cb_ctx, struct spdk_pci_device *pci_dev);
 
 /**
- * Returns true if vendor_id and device_id match a known IOAT PCI device ID.
+ * Callback for spdk_ioat_probe() to report a device that has been attached to the userspace I/OAT driver.
  */
-bool ioat_pci_device_match_id(uint16_t vendor_id, uint16_t device_id);
+typedef void (*spdk_ioat_attach_cb)(void *cb_ctx, struct spdk_pci_device *pci_dev,
+				    struct spdk_ioat_chan *ioat);
 
 /**
- * Attach an I/OAT PCI device to the I/OAT userspace driver.
+ * \brief Enumerate the I/OAT devices attached to the system and attach the userspace I/OAT driver
+ * to them if desired.
+ *
+ * \param probe_cb will be called once per I/OAT device found in the system.
+ * \param attach_cb will be called for devices for which probe_cb returned true once the I/OAT
+ * controller has been attached to the userspace driver.
  *
- * To stop using the the device and release its associated resources,
- * call \ref ioat_detach with the ioat_channel instance returned by this function.
+ * If called more than once, only devices that are not already attached to the SPDK I/OAT driver
+ * will be reported.
+ *
+ * To stop using the the controller and release its associated resources,
+ * call \ref spdk_ioat_detach with the ioat_channel instance returned by this function.
  */
-struct ioat_channel *ioat_attach(void *device);
+int spdk_ioat_probe(void *cb_ctx, spdk_ioat_probe_cb probe_cb, spdk_ioat_attach_cb attach_cb);
 
 /**
- * Detaches specified device returned by \ref ioat_attach() from the I/OAT driver.
+ * Detaches specified device returned by \ref spdk_ioat_probe() from the I/OAT driver.
  */
-int ioat_detach(struct ioat_channel *ioat);
+int spdk_ioat_detach(struct spdk_ioat_chan *ioat);
 
 /**
  * Request a DMA engine channel for the calling thread.
  *
  * Must be called before submitting any requests from a thread.
  *
- * The \ref ioat_unregister_thread() function can be called to release the channel.
+ * The \ref spdk_ioat_unregister_thread() function can be called to release the channel.
  */
-int ioat_register_thread(void);
+int spdk_ioat_register_thread(void);
 
 /**
  * Unregister the current thread's I/OAT channel.
  *
- * This function can be called after \ref ioat_register_thread() to release the thread's
+ * This function can be called after \ref spdk_ioat_register_thread() to release the thread's
  * DMA engine channel for use by other threads.
  */
-void ioat_unregister_thread(void);
+void spdk_ioat_unregister_thread(void);
 
 /**
  * Submit a DMA engine memory copy request.
  *
  * Before submitting any requests on a thread, the thread must be registered
- * using the \ref ioat_register_thread() function.
+ * using the \ref spdk_ioat_register_thread() function.
  */
-int64_t ioat_submit_copy(void *cb_arg, ioat_callback_t cb_fn,
-			 void *dst, const void *src, uint64_t nbytes);
+int64_t spdk_ioat_submit_copy(void *cb_arg, spdk_ioat_req_cb cb_fn,
+			      void *dst, const void *src, uint64_t nbytes);
+
+/**
+ * Submit a DMA engine memory fill request.
+ *
+ * Before submitting any requests on a thread, the thread must be registered
+ * using the \ref spdk_ioat_register_thread() function.
+ */
+int64_t spdk_ioat_submit_fill(void *cb_arg, spdk_ioat_req_cb cb_fn,
+			      void *dst, uint64_t fill_pattern, uint64_t nbytes);
 
 /**
  * Check for completed requests on the current thread.
  *
  * Before submitting any requests on a thread, the thread must be registered
- * using the \ref ioat_register_thread() function.
+ * using the \ref spdk_ioat_register_thread() function.
  *
  * \returns 0 on success or negative if something went wrong.
  */
-int ioat_process_events(void);
+int spdk_ioat_process_events(void);
+
+/**
+ * DMA engine capability flags
+ */
+enum spdk_ioat_dma_capability_flags {
+	SPDK_IOAT_ENGINE_COPY_SUPPORTED	= 0x1, /**< The memory copy is supported */
+	SPDK_IOAT_ENGINE_FILL_SUPPORTED	= 0x2, /**< The memory fill is supported */
+};
+
+/**
+ * Get the DMA engine capabilities.
+ *
+ * Before submitting any requests on a thread, the thread must be registered
+ * using the \ref spdk_ioat_register_thread() function.
+ */
+uint32_t spdk_ioat_get_dma_capabilities(void);
+
+#ifdef __cplusplus
+}
+#endif
 
 #endif
diff --git a/src/spdk/include/spdk/ioat_spec.h b/src/spdk/include/spdk/ioat_spec.h
index bb65b5b..f8ed7a9 100644
--- a/src/spdk/include/spdk/ioat_spec.h
+++ b/src/spdk/include/spdk/ioat_spec.h
@@ -31,30 +31,41 @@
  *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-#ifndef __IOAT_SPEC_H__
-#define __IOAT_SPEC_H__
+#ifndef SPDK_IOAT_SPEC_H
+#define SPDK_IOAT_SPEC_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
 
 #include <inttypes.h>
 
 #include "spdk/assert.h"
 
-#define IOAT_INTRCTRL_MASTER_INT_EN	0x01
+#define SPDK_IOAT_INTRCTRL_MASTER_INT_EN	0x01
 
-#define IOAT_VER_3_0                0x30
-#define IOAT_VER_3_3                0x33
+#define SPDK_IOAT_VER_3_0                0x30
+#define SPDK_IOAT_VER_3_3                0x33
 
 /* DMA Channel Registers */
-#define IOAT_CHANCTRL_CHANNEL_PRIORITY_MASK	0xF000
-#define IOAT_CHANCTRL_COMPL_DCA_EN		0x0200
-#define IOAT_CHANCTRL_CHANNEL_IN_USE		0x0100
-#define IOAT_CHANCTRL_DESCRIPTOR_ADDR_SNOOP_CONTROL	0x0020
-#define IOAT_CHANCTRL_ERR_INT_EN		0x0010
-#define IOAT_CHANCTRL_ANY_ERR_ABORT_EN		0x0008
-#define IOAT_CHANCTRL_ERR_COMPLETION_EN		0x0004
-#define IOAT_CHANCTRL_INT_REARM			0x0001
+#define SPDK_IOAT_CHANCTRL_CHANNEL_PRIORITY_MASK	0xF000
+#define SPDK_IOAT_CHANCTRL_COMPL_DCA_EN		0x0200
+#define SPDK_IOAT_CHANCTRL_CHANNEL_IN_USE		0x0100
+#define SPDK_IOAT_CHANCTRL_DESCRIPTOR_ADDR_SNOOP_CONTROL	0x0020
+#define SPDK_IOAT_CHANCTRL_ERR_INT_EN		0x0010
+#define SPDK_IOAT_CHANCTRL_ANY_ERR_ABORT_EN		0x0008
+#define SPDK_IOAT_CHANCTRL_ERR_COMPLETION_EN		0x0004
+#define SPDK_IOAT_CHANCTRL_INT_REARM			0x0001
 
+/* DMA Channel Capabilities */
+#define	SPDK_IOAT_DMACAP_PB		(1 << 0)
+#define	SPDK_IOAT_DMACAP_DCA		(1 << 4)
+#define	SPDK_IOAT_DMACAP_BFILL		(1 << 6)
+#define	SPDK_IOAT_DMACAP_XOR		(1 << 8)
+#define	SPDK_IOAT_DMACAP_PQ		(1 << 9)
+#define	SPDK_IOAT_DMACAP_DMA_DIF	(1 << 10)
 
-struct ioat_registers {
+struct spdk_ioat_registers {
 	uint8_t		chancnt;
 	uint8_t		xfercap;
 	uint8_t		genctrl;
@@ -79,24 +90,24 @@ struct ioat_registers {
 	uint32_t	chanerrmask;	/* 0xAC */
 } __attribute__((packed));
 
-#define IOAT_CHANCMD_RESET		0x20
-#define IOAT_CHANCMD_SUSPEND		0x04
+#define SPDK_IOAT_CHANCMD_RESET			0x20
+#define SPDK_IOAT_CHANCMD_SUSPEND		0x04
 
-#define IOAT_CHANSTS_STATUS		0x7ULL
-#define IOAT_CHANSTS_ACTIVE		0x0
-#define IOAT_CHANSTS_IDLE		0x1
-#define IOAT_CHANSTS_SUSPENDED		0x2
-#define IOAT_CHANSTS_HALTED		0x3
-#define IOAT_CHANSTS_ARMED		0x4
+#define SPDK_IOAT_CHANSTS_STATUS		0x7ULL
+#define SPDK_IOAT_CHANSTS_ACTIVE		0x0
+#define SPDK_IOAT_CHANSTS_IDLE			0x1
+#define SPDK_IOAT_CHANSTS_SUSPENDED		0x2
+#define SPDK_IOAT_CHANSTS_HALTED		0x3
+#define SPDK_IOAT_CHANSTS_ARMED			0x4
 
-#define IOAT_CHANSTS_UNAFFILIATED_ERROR	0x8ULL
-#define IOAT_CHANSTS_SOFT_ERROR		0x10ULL
+#define SPDK_IOAT_CHANSTS_UNAFFILIATED_ERROR	0x8ULL
+#define SPDK_IOAT_CHANSTS_SOFT_ERROR		0x10ULL
 
-#define IOAT_CHANSTS_COMPLETED_DESCRIPTOR_MASK	(~0x3FULL)
+#define SPDK_IOAT_CHANSTS_COMPLETED_DESCRIPTOR_MASK	(~0x3FULL)
 
-#define IOAT_CHANCMP_ALIGN		8	/* CHANCMP address must be 64-bit aligned */
+#define SPDK_IOAT_CHANCMP_ALIGN			8	/* CHANCMP address must be 64-bit aligned */
 
-struct ioat_generic_hw_descriptor {
+struct spdk_ioat_generic_hw_desc {
 	uint32_t size;
 	union {
 		uint32_t control_raw;
@@ -122,7 +133,7 @@ struct ioat_generic_hw_descriptor {
 	uint64_t op_specific[4];
 };
 
-struct ioat_dma_hw_descriptor {
+struct spdk_ioat_dma_hw_desc {
 	uint32_t size;
 	union {
 		uint32_t control_raw;
@@ -139,7 +150,7 @@ struct ioat_dma_hw_descriptor {
 			uint32_t dest_dca: 1;
 			uint32_t hint: 1;
 			uint32_t reserved: 13;
-#define IOAT_OP_COPY 0x00
+#define SPDK_IOAT_OP_COPY 0x00
 			uint32_t op: 8;
 		} control;
 	} u;
@@ -152,7 +163,7 @@ struct ioat_dma_hw_descriptor {
 	uint64_t user2;
 };
 
-struct ioat_fill_hw_descriptor {
+struct spdk_ioat_fill_hw_desc {
 	uint32_t size;
 	union {
 		uint32_t control_raw;
@@ -166,7 +177,7 @@ struct ioat_fill_hw_descriptor {
 			uint32_t dest_page_break: 1;
 			uint32_t bundle: 1;
 			uint32_t reserved3: 15;
-#define IOAT_OP_FILL 0x01
+#define SPDK_IOAT_OP_FILL 0x01
 			uint32_t op: 8;
 		} control;
 	} u;
@@ -179,7 +190,7 @@ struct ioat_fill_hw_descriptor {
 	uint64_t user2;
 };
 
-struct ioat_xor_hw_descriptor {
+struct spdk_ioat_xor_hw_desc {
 	uint32_t size;
 	union {
 		uint32_t control_raw;
@@ -194,8 +205,8 @@ struct ioat_xor_hw_descriptor {
 			uint32_t dest_dca: 1;
 			uint32_t hint: 1;
 			uint32_t reserved: 13;
-#define IOAT_OP_XOR 0x87
-#define IOAT_OP_XOR_VAL 0x88
+#define SPDK_IOAT_OP_XOR 0x87
+#define SPDK_IOAT_OP_XOR_VAL 0x88
 			uint32_t op: 8;
 		} control;
 	} u;
@@ -208,7 +219,7 @@ struct ioat_xor_hw_descriptor {
 	uint64_t src_addr5;
 };
 
-struct ioat_xor_ext_hw_descriptor {
+struct spdk_ioat_xor_ext_hw_desc {
 	uint64_t src_addr6;
 	uint64_t src_addr7;
 	uint64_t src_addr8;
@@ -216,7 +227,7 @@ struct ioat_xor_ext_hw_descriptor {
 	uint64_t reserved[4];
 };
 
-struct ioat_pq_hw_descriptor {
+struct spdk_ioat_pq_hw_desc {
 	uint32_t size;
 	union {
 		uint32_t control_raw;
@@ -233,8 +244,8 @@ struct ioat_pq_hw_descriptor {
 			uint32_t p_disable: 1;
 			uint32_t q_disable: 1;
 			uint32_t reserved: 11;
-#define IOAT_OP_PQ 0x89
-#define IOAT_OP_PQ_VAL 0x8a
+#define SPDK_IOAT_OP_PQ 0x89
+#define SPDK_IOAT_OP_PQ_VAL 0x8a
 			uint32_t op: 8;
 		} control;
 	} u;
@@ -247,7 +258,7 @@ struct ioat_pq_hw_descriptor {
 	uint64_t q_addr;
 };
 
-struct ioat_pq_ext_hw_descriptor {
+struct spdk_ioat_pq_ext_hw_desc {
 	uint64_t src_addr4;
 	uint64_t src_addr5;
 	uint64_t src_addr6;
@@ -257,7 +268,7 @@ struct ioat_pq_ext_hw_descriptor {
 	uint64_t reserved[2];
 };
 
-struct ioat_pq_update_hw_descriptor {
+struct spdk_ioat_pq_update_hw_desc {
 	uint32_t size;
 	union {
 		uint32_t control_raw;
@@ -275,7 +286,7 @@ struct ioat_pq_update_hw_descriptor {
 			uint32_t q_disable: 1;
 			uint32_t reserved: 3;
 			uint32_t coef: 8;
-#define IOAT_OP_PQ_UP 0x8b
+#define SPDK_IOAT_OP_PQ_UP 0x8b
 			uint32_t op: 8;
 		} control;
 	} u;
@@ -288,21 +299,25 @@ struct ioat_pq_update_hw_descriptor {
 	uint64_t q_addr;
 };
 
-struct ioat_raw_hw_descriptor {
+struct spdk_ioat_raw_hw_desc {
 	uint64_t field[8];
 };
 
-union ioat_hw_descriptor {
-	struct ioat_raw_hw_descriptor raw;
-	struct ioat_generic_hw_descriptor generic;
-	struct ioat_dma_hw_descriptor dma;
-	struct ioat_fill_hw_descriptor fill;
-	struct ioat_xor_hw_descriptor xor;
-	struct ioat_xor_ext_hw_descriptor xor_ext;
-	struct ioat_pq_hw_descriptor pq;
-	struct ioat_pq_ext_hw_descriptor pq_ext;
-	struct ioat_pq_update_hw_descriptor pq_update;
+union spdk_ioat_hw_desc {
+	struct spdk_ioat_raw_hw_desc raw;
+	struct spdk_ioat_generic_hw_desc generic;
+	struct spdk_ioat_dma_hw_desc dma;
+	struct spdk_ioat_fill_hw_desc fill;
+	struct spdk_ioat_xor_hw_desc xor;
+	struct spdk_ioat_xor_ext_hw_desc xor_ext;
+	struct spdk_ioat_pq_hw_desc pq;
+	struct spdk_ioat_pq_ext_hw_desc pq_ext;
+	struct spdk_ioat_pq_update_hw_desc pq_update;
 };
-SPDK_STATIC_ASSERT(sizeof(union ioat_hw_descriptor) == 64, "incorrect ioat_hw_descriptor layout");
+SPDK_STATIC_ASSERT(sizeof(union spdk_ioat_hw_desc) == 64, "incorrect spdk_ioat_hw_desc layout");
+
+#ifdef __cplusplus
+}
+#endif
 
-#endif /* __IOAT_SPEC_H__ */
+#endif /* SPDK_IOAT_SPEC_H */
diff --git a/src/spdk/include/spdk/mmio.h b/src/spdk/include/spdk/mmio.h
index a9f3902..3674fde 100644
--- a/src/spdk/include/spdk/mmio.h
+++ b/src/spdk/include/spdk/mmio.h
@@ -34,6 +34,10 @@
 #ifndef SPDK_MMIO_H
 #define SPDK_MMIO_H
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 #include <inttypes.h>
 
 #ifdef __x86_64__
@@ -88,4 +92,8 @@ spdk_mmio_write_8(volatile uint64_t *addr, uint64_t val)
 	}
 }
 
+#ifdef __cplusplus
+}
+#endif
+
 #endif
diff --git a/src/spdk/include/spdk/nvme.h b/src/spdk/include/spdk/nvme.h
index 33dc547..d762203 100644
--- a/src/spdk/include/spdk/nvme.h
+++ b/src/spdk/include/spdk/nvme.h
@@ -34,47 +34,65 @@
 #ifndef SPDK_NVME_H
 #define SPDK_NVME_H
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 #include <stddef.h>
+#include "spdk/pci.h"
 #include "nvme_spec.h"
 
 /** \file
  *
  */
 
-#define NVME_DEFAULT_RETRY_COUNT	(4)
-extern int32_t		nvme_retry_count;
+#define SPDK_NVME_DEFAULT_RETRY_COUNT	(4)
+extern int32_t		spdk_nvme_retry_count;
+
 
-#ifdef __cplusplus
-extern "C" {
-#endif
 
-/** \brief Opaque handle to a controller. Obtained by calling nvme_attach(). */
-struct nvme_controller;
+/** \brief Opaque handle to a controller. Returned by \ref spdk_nvme_probe()'s attach_cb. */
+struct spdk_nvme_ctrlr;
 
 /**
- * \brief Attaches specified device to the NVMe driver.
+ * Callback for spdk_nvme_probe() enumeration.
  *
- * On success, the nvme_controller handle is valid for other nvme_ctrlr_* functions.
- * On failure, the return value will be NULL.
+ * \return true to attach to this device.
+ */
+typedef bool (*spdk_nvme_probe_cb)(void *cb_ctx, struct spdk_pci_device *pci_dev);
+
+/**
+ * Callback for spdk_nvme_probe() to report a device that has been attached to the userspace NVMe driver.
+ */
+typedef void (*spdk_nvme_attach_cb)(void *cb_ctx, struct spdk_pci_device *pci_dev,
+				    struct spdk_nvme_ctrlr *ctrlr);
+
+/**
+ * \brief Enumerate the NVMe devices attached to the system and attach the userspace NVMe driver
+ * to them if desired.
  *
- * This function should be called from a single thread while no other threads or drivers
- * are actively using the NVMe device.
+ * \param probe_cb will be called once per NVMe device found in the system.
+ * \param attach_cb will be called for devices for which probe_cb returned true once that NVMe
+ * controller has been attached to the userspace driver.
+ *
+ * If called more than once, only devices that are not already attached to the SPDK NVMe driver
+ * will be reported.
  *
  * To stop using the the controller and release its associated resources,
- * call \ref nvme_detach with the nvme_controller instance returned by this function.
+ * call \ref nvme_detach with the spdk_nvme_ctrlr instance returned by this function.
  */
-struct nvme_controller *nvme_attach(void *devhandle);
+int spdk_nvme_probe(void *cb_ctx, spdk_nvme_probe_cb probe_cb, spdk_nvme_attach_cb attach_cb);
 
 /**
- * \brief Detaches specified device returned by \ref nvme_attach() from the NVMe driver.
+ * \brief Detaches specified device returned by \ref nvme_probe()'s attach_cb from the NVMe driver.
  *
- * On success, the nvme_controller handle is no longer valid.
+ * On success, the spdk_nvme_ctrlr handle is no longer valid.
  *
  * This function should be called from a single thread while no other threads
  * are actively using the NVMe device.
  *
  */
-int nvme_detach(struct nvme_controller *ctrlr);
+int spdk_nvme_detach(struct spdk_nvme_ctrlr *ctrlr);
 
 /**
  * \brief Perform a full hardware reset of the NVMe controller.
@@ -82,90 +100,94 @@ int nvme_detach(struct nvme_controller *ctrlr);
  * This function should be called from a single thread while no other threads
  * are actively using the NVMe device.
  *
- * Any pointers returned from nvme_ctrlr_get_ns() and nvme_ns_get_data() may be invalidated
- * by calling this function.  The number of namespaces as returned by nvme_ctrlr_get_num_ns() may
+ * Any pointers returned from spdk_nvme_ctrlr_get_ns() and spdk_nvme_ns_get_data() may be invalidated
+ * by calling this function.  The number of namespaces as returned by spdk_nvme_ctrlr_get_num_ns() may
  * also change.
  */
-int nvme_ctrlr_reset(struct nvme_controller *ctrlr);
+int spdk_nvme_ctrlr_reset(struct spdk_nvme_ctrlr *ctrlr);
 
 /**
  * \brief Get the identify controller data as defined by the NVMe specification.
  *
- * This function is thread safe and can be called at any point after nvme_attach().
+ * This function is thread safe and can be called at any point while the controller is attached to
+ *  the SPDK NVMe driver.
  *
  */
-const struct nvme_controller_data *nvme_ctrlr_get_data(struct nvme_controller *ctrlr);
+const struct spdk_nvme_ctrlr_data *spdk_nvme_ctrlr_get_data(struct spdk_nvme_ctrlr *ctrlr);
 
 /**
  * \brief Get the number of namespaces for the given NVMe controller.
  *
- * This function is thread safe and can be called at any point after nvme_attach().
+ * This function is thread safe and can be called at any point while the controller is attached to
+ *  the SPDK NVMe driver.
  *
- * This is equivalent to calling nvme_ctrlr_get_data() to get the
- * nvme_controller_data and then reading the nn field.
+ * This is equivalent to calling spdk_nvme_ctrlr_get_data() to get the
+ * spdk_nvme_ctrlr_data and then reading the nn field.
  *
  */
-uint32_t nvme_ctrlr_get_num_ns(struct nvme_controller *ctrlr);
+uint32_t spdk_nvme_ctrlr_get_num_ns(struct spdk_nvme_ctrlr *ctrlr);
 
 /**
  * \brief Determine if a particular log page is supported by the given NVMe controller.
  *
- * This function is thread safe and can be called at any point after nvme_attach().
+ * This function is thread safe and can be called at any point while the controller is attached to
+ *  the SPDK NVMe driver.
  *
- * \sa nvme_ctrlr_cmd_get_log_page()
+ * \sa spdk_nvme_ctrlr_cmd_get_log_page()
  */
-bool nvme_ctrlr_is_log_page_supported(struct nvme_controller *ctrlr, uint8_t log_page);
+bool spdk_nvme_ctrlr_is_log_page_supported(struct spdk_nvme_ctrlr *ctrlr, uint8_t log_page);
 
 /**
  * \brief Determine if a particular feature is supported by the given NVMe controller.
  *
- * This function is thread safe and can be called at any point after nvme_attach().
+ * This function is thread safe and can be called at any point while the controller is attached to
+ *  the SPDK NVMe driver.
  *
- * \sa nvme_ctrlr_cmd_get_feature()
+ * \sa spdk_nvme_ctrlr_cmd_get_feature()
  */
-bool nvme_ctrlr_is_feature_supported(struct nvme_controller *ctrlr, uint8_t feature_code);
+bool spdk_nvme_ctrlr_is_feature_supported(struct spdk_nvme_ctrlr *ctrlr, uint8_t feature_code);
 
 /**
  * Signature for callback function invoked when a command is completed.
  *
- * The nvme_completion parameter contains the completion status.
+ * The spdk_nvme_cpl parameter contains the completion status.
  */
-typedef void (*nvme_cb_fn_t)(void *, const struct nvme_completion *);
+typedef void (*spdk_nvme_cmd_cb)(void *, const struct spdk_nvme_cpl *);
 
 /**
  * Signature for callback function invoked when an asynchronous error
  *  request command is completed.
  *
  * The aer_cb_arg parameter is set to the context specified by
- *  nvme_register_aer_callback().
- * The nvme_completion parameter contains the completion status of the
+ *  spdk_nvme_register_aer_callback().
+ * The spdk_nvme_cpl parameter contains the completion status of the
  *  asynchronous event request that was completed.
  */
-typedef void (*nvme_aer_cb_fn_t)(void *aer_cb_arg,
-				 const struct nvme_completion *);
+typedef void (*spdk_nvme_aer_cb)(void *aer_cb_arg,
+				 const struct spdk_nvme_cpl *);
 
-void nvme_ctrlr_register_aer_callback(struct nvme_controller *ctrlr,
-				      nvme_aer_cb_fn_t aer_cb_fn,
-				      void *aer_cb_arg);
+void spdk_nvme_ctrlr_register_aer_callback(struct spdk_nvme_ctrlr *ctrlr,
+		spdk_nvme_aer_cb aer_cb_fn,
+		void *aer_cb_arg);
 
 /**
  * \brief Send the given NVM I/O command to the NVMe controller.
  *
  * This is a low level interface for submitting I/O commands directly. Prefer
- * the nvme_ns_cmd_* functions instead. The validity of the command will
+ * the spdk_nvme_ns_cmd_* functions instead. The validity of the command will
  * not be checked!
  *
  * When constructing the nvme_command it is not necessary to fill out the PRP
  * list/SGL or the CID. The driver will handle both of those for you.
  *
  * This function is thread safe and can be called at any point after
- * nvme_register_io_thread().
+ * spdk_nvme_register_io_thread().
  *
  */
-int nvme_ctrlr_cmd_io_raw(struct nvme_controller *ctrlr,
-			  struct nvme_command *cmd,
-			  void *buf, uint32_t len,
-			  nvme_cb_fn_t cb_fn, void *cb_arg);
+int spdk_nvme_ctrlr_cmd_io_raw(struct spdk_nvme_ctrlr *ctrlr,
+			       struct spdk_nvme_cmd *cmd,
+			       void *buf, uint32_t len,
+			       spdk_nvme_cmd_cb cb_fn, void *cb_arg);
 
 /**
  * \brief Process any outstanding completions for I/O submitted on the current thread.
@@ -180,31 +202,33 @@ int nvme_ctrlr_cmd_io_raw(struct nvme_controller *ctrlr,
  *
  * \return Number of completions processed (may be 0) or negative on error.
  *
- * This function is thread safe and can be called at any point after nvme_attach().
+ * This function is thread safe and can be called at any point while the controller is attached to
+ *  the SPDK NVMe driver.
  *
  */
-int32_t nvme_ctrlr_process_io_completions(struct nvme_controller *ctrlr, uint32_t max_completions);
+int32_t spdk_nvme_ctrlr_process_io_completions(struct spdk_nvme_ctrlr *ctrlr,
+		uint32_t max_completions);
 
 /**
  * \brief Send the given admin command to the NVMe controller.
  *
  * This is a low level interface for submitting admin commands directly. Prefer
- * the nvme_ctrlr_cmd_* functions instead. The validity of the command will
+ * the spdk_nvme_ctrlr_cmd_* functions instead. The validity of the command will
  * not be checked!
  *
  * When constructing the nvme_command it is not necessary to fill out the PRP
  * list/SGL or the CID. The driver will handle both of those for you.
  *
- * This function is thread safe and can be called at any point after
- * \ref nvme_attach().
+ * This function is thread safe and can be called at any point while the controller is attached to
+ *  the SPDK NVMe driver.
  *
- * Call \ref nvme_ctrlr_process_admin_completions() to poll for completion
+ * Call \ref spdk_nvme_ctrlr_process_admin_completions() to poll for completion
  * of commands submitted through this function.
  */
-int nvme_ctrlr_cmd_admin_raw(struct nvme_controller *ctrlr,
-			     struct nvme_command *cmd,
-			     void *buf, uint32_t len,
-			     nvme_cb_fn_t cb_fn, void *cb_arg);
+int spdk_nvme_ctrlr_cmd_admin_raw(struct spdk_nvme_ctrlr *ctrlr,
+				  struct spdk_nvme_cmd *cmd,
+				  void *buf, uint32_t len,
+				  spdk_nvme_cmd_cb cb_fn, void *cb_arg);
 
 /**
  * \brief Process any outstanding completions for admin commands.
@@ -217,31 +241,32 @@ int nvme_ctrlr_cmd_admin_raw(struct nvme_controller *ctrlr,
  *
  * \return Number of completions processed (may be 0) or negative on error.
  *
- * This function is thread safe and can be called at any point after nvme_attach().
+ * This function is thread safe and can be called at any point while the controller is attached to
+ *  the SPDK NVMe driver.
  */
-int32_t nvme_ctrlr_process_admin_completions(struct nvme_controller *ctrlr);
+int32_t spdk_nvme_ctrlr_process_admin_completions(struct spdk_nvme_ctrlr *ctrlr);
 
 
-/** \brief Opaque handle to a namespace. Obtained by calling nvme_ctrlr_get_ns(). */
-struct nvme_namespace;
+/** \brief Opaque handle to a namespace. Obtained by calling spdk_nvme_ctrlr_get_ns(). */
+struct spdk_nvme_ns;
 
 /**
  * \brief Get a handle to a namespace for the given controller.
  *
  * Namespaces are numbered from 1 to the total number of namespaces. There will never
  * be any gaps in the numbering. The number of namespaces is obtained by calling
- * nvme_ctrlr_get_num_ns().
- *
- * This function is thread safe and can be called at any point after nvme_attach().
+ * spdk_nvme_ctrlr_get_num_ns().
  *
+ * This function is thread safe and can be called at any point while the controller is attached to
+ *  the SPDK NVMe driver.
  */
-struct nvme_namespace *nvme_ctrlr_get_ns(struct nvme_controller *ctrlr, uint32_t ns_id);
+struct spdk_nvme_ns *spdk_nvme_ctrlr_get_ns(struct spdk_nvme_ctrlr *ctrlr, uint32_t ns_id);
 
 /**
  * \brief Get a specific log page from the NVMe controller.
  *
  * \param log_page The log page identifier.
- * \param nsid Depending on the log page, this may be 0, a namespace identifier, or NVME_GLOBAL_NAMESPACE_TAG.
+ * \param nsid Depending on the log page, this may be 0, a namespace identifier, or SPDK_NVME_GLOBAL_NS_TAG.
  * \param payload The pointer to the payload buffer.
  * \param payload_size The size of payload buffer.
  * \param cb_fn Callback function to invoke when the log page has been retrieved.
@@ -249,17 +274,18 @@ struct nvme_namespace *nvme_ctrlr_get_ns(struct nvme_controller *ctrlr, uint32_t
  *
  * \return 0 if successfully submitted, ENOMEM if resources could not be allocated for this request
  *
- * This function is thread safe and can be called at any point after nvme_attach().
+ * This function is thread safe and can be called at any point while the controller is attached to
+ *  the SPDK NVMe driver.
  *
- * Call \ref nvme_ctrlr_process_admin_completions() to poll for completion
+ * Call \ref spdk_nvme_ctrlr_process_admin_completions() to poll for completion
  * of commands submitted through this function.
  *
- * \sa nvme_ctrlr_is_log_page_supported()
+ * \sa spdk_nvme_ctrlr_is_log_page_supported()
  */
-int nvme_ctrlr_cmd_get_log_page(struct nvme_controller *ctrlr,
-				uint8_t log_page, uint32_t nsid,
-				void *payload, uint32_t payload_size,
-				nvme_cb_fn_t cb_fn, void *cb_arg);
+int spdk_nvme_ctrlr_cmd_get_log_page(struct spdk_nvme_ctrlr *ctrlr,
+				     uint8_t log_page, uint32_t nsid,
+				     void *payload, uint32_t payload_size,
+				     spdk_nvme_cmd_cb cb_fn, void *cb_arg);
 
 /**
  * \brief Set specific feature for the given NVMe controller.
@@ -274,17 +300,18 @@ int nvme_ctrlr_cmd_get_log_page(struct nvme_controller *ctrlr,
  *
  * \return 0 if successfully submitted, ENOMEM if resources could not be allocated for this request
  *
- * This function is thread safe and can be called at any point after nvme_attach().
+ * This function is thread safe and can be called at any point while the controller is attached to
+ *  the SPDK NVMe driver.
  *
- * Call \ref nvme_ctrlr_process_admin_completions() to poll for completion
+ * Call \ref spdk_nvme_ctrlr_process_admin_completions() to poll for completion
  * of commands submitted through this function.
  *
- * \sa nvme_ctrlr_cmd_set_feature()
+ * \sa spdk_nvme_ctrlr_cmd_get_feature()
  */
-int nvme_ctrlr_cmd_set_feature(struct nvme_controller *ctrlr,
-			       uint8_t feature, uint32_t cdw11, uint32_t cdw12,
-			       void *payload, uint32_t payload_size,
-			       nvme_cb_fn_t cb_fn, void *cb_arg);
+int spdk_nvme_ctrlr_cmd_set_feature(struct spdk_nvme_ctrlr *ctrlr,
+				    uint8_t feature, uint32_t cdw11, uint32_t cdw12,
+				    void *payload, uint32_t payload_size,
+				    spdk_nvme_cmd_cb cb_fn, void *cb_arg);
 
 /**
  * \brief Get specific feature from given NVMe controller.
@@ -298,91 +325,93 @@ int nvme_ctrlr_cmd_set_feature(struct nvme_controller *ctrlr,
  *
  * \return 0 if successfully submitted, ENOMEM if resources could not be allocated for this request
  *
- * This function is thread safe and can be called at any point after nvme_attach().
+ * This function is thread safe and can be called at any point while the controller is attached to
+ *  the SPDK NVMe driver.
  *
- * Call \ref nvme_ctrlr_process_admin_completions() to poll for completion
+ * Call \ref spdk_nvme_ctrlr_process_admin_completions() to poll for completion
  * of commands submitted through this function.
  *
- * \sa nvme_ctrlr_cmd_get_feature()
+ * \sa spdk_nvme_ctrlr_cmd_set_feature()
  */
-int nvme_ctrlr_cmd_get_feature(struct nvme_controller *ctrlr,
-			       uint8_t feature, uint32_t cdw11,
-			       void *payload, uint32_t payload_size,
-			       nvme_cb_fn_t cb_fn, void *cb_arg);
+int spdk_nvme_ctrlr_cmd_get_feature(struct spdk_nvme_ctrlr *ctrlr,
+				    uint8_t feature, uint32_t cdw11,
+				    void *payload, uint32_t payload_size,
+				    spdk_nvme_cmd_cb cb_fn, void *cb_arg);
 
 /**
  * \brief Get the identify namespace data as defined by the NVMe specification.
  *
- * This function is thread safe and can be called at any point after nvme_attach().
- *
+ * This function is thread safe and can be called at any point while the controller is attached to
+ *  the SPDK NVMe driver.
  */
-const struct nvme_namespace_data *nvme_ns_get_data(struct nvme_namespace *ns);
+const struct spdk_nvme_ns_data *spdk_nvme_ns_get_data(struct spdk_nvme_ns *ns);
 
 /**
  * \brief Get the namespace id (index number) from the given namespace handle.
  *
- * This function is thread safe and can be called at any point after nvme_attach().
- *
+ * This function is thread safe and can be called at any point while the controller is attached to
+ *  the SPDK NVMe driver.
  */
-uint32_t nvme_ns_get_id(struct nvme_namespace *ns);
+uint32_t spdk_nvme_ns_get_id(struct spdk_nvme_ns *ns);
 
 /**
  * \brief Get the maximum transfer size, in bytes, for an I/O sent to the given namespace.
  *
- * This function is thread safe and can be called at any point after nvme_attach().
- *
+ * This function is thread safe and can be called at any point while the controller is attached to
+ *  the SPDK NVMe driver.
  */
-uint32_t nvme_ns_get_max_io_xfer_size(struct nvme_namespace *ns);
+uint32_t spdk_nvme_ns_get_max_io_xfer_size(struct spdk_nvme_ns *ns);
 
 /**
  * \brief Get the sector size, in bytes, of the given namespace.
  *
- * This function is thread safe and can be called at any point after nvme_attach().
- *
+ * This function is thread safe and can be called at any point while the controller is attached to
+ *  the SPDK NVMe driver.
  */
-uint32_t nvme_ns_get_sector_size(struct nvme_namespace *ns);
+uint32_t spdk_nvme_ns_get_sector_size(struct spdk_nvme_ns *ns);
 
 /**
  * \brief Get the number of sectors for the given namespace.
  *
- * This function is thread safe and can be called at any point after nvme_attach().
- *
+ * This function is thread safe and can be called at any point while the controller is attached to
+ *  the SPDK NVMe driver.
  */
-uint64_t nvme_ns_get_num_sectors(struct nvme_namespace *ns);
+uint64_t spdk_nvme_ns_get_num_sectors(struct spdk_nvme_ns *ns);
 
 /**
  * \brief Get the size, in bytes, of the given namespace.
  *
- * This function is thread safe and can be called at any point after nvme_attach().
- *
+ * This function is thread safe and can be called at any point while the controller is attached to
+ *  the SPDK NVMe driver.
  */
-uint64_t nvme_ns_get_size(struct nvme_namespace *ns);
+uint64_t spdk_nvme_ns_get_size(struct spdk_nvme_ns *ns);
 
 /**
  * \brief Namespace command support flags.
  */
-enum nvme_namespace_flags {
-	NVME_NS_DEALLOCATE_SUPPORTED	= 0x1, /**< The deallocate command is supported */
-	NVME_NS_FLUSH_SUPPORTED		= 0x2, /**< The flush command is supported */
-	NVME_NS_RESERVATION_SUPPORTED	= 0x4, /**< The reservation command is supported */
+enum spdk_nvme_ns_flags {
+	SPDK_NVME_NS_DEALLOCATE_SUPPORTED	= 0x1, /**< The deallocate command is supported */
+	SPDK_NVME_NS_FLUSH_SUPPORTED		= 0x2, /**< The flush command is supported */
+	SPDK_NVME_NS_RESERVATION_SUPPORTED	= 0x4, /**< The reservation command is supported */
+	SPDK_NVME_NS_WRITE_ZEROES_SUPPORTED	= 0x8, /**< The write zeroes command is supported */
 };
 
 /**
  * \brief Get the flags for the given namespace.
  *
- * See nvme_namespace_flags for the possible flags returned.
- *
- * This function is thread safe and can be called at any point after nvme_attach().
+ * See spdk_nvme_ns_flags for the possible flags returned.
  *
+ * This function is thread safe and can be called at any point while the controller is attached to
+ *  the SPDK NVMe driver.
  */
-uint32_t nvme_ns_get_flags(struct nvme_namespace *ns);
+uint32_t spdk_nvme_ns_get_flags(struct spdk_nvme_ns *ns);
 
 /**
  * Restart the SGL walk to the specified offset when the command has scattered payloads.
  *
  * The cb_arg parameter is the value passed to readv/writev.
  */
-typedef void (*nvme_req_reset_sgl_fn_t)(void *cb_arg, uint32_t offset);
+typedef void (*spdk_nvme_req_reset_sgl_cb)(void *cb_arg, uint32_t offset);
 
 /**
  * Fill out *address and *length with the current SGL entry and advance to the next
@@ -392,7 +421,7 @@ typedef void (*nvme_req_reset_sgl_fn_t)(void *cb_arg, uint32_t offset);
  * The address parameter contains the physical address of this segment.
  * The length parameter contains the length of this physical segment.
  */
-typedef int (*nvme_req_next_sge_fn_t)(void *cb_arg, uint64_t *address, uint32_t *length);
+typedef int (*spdk_nvme_req_next_sge_cb)(void *cb_arg, uint64_t *address, uint32_t *length);
 
 /**
  * \brief Submits a write I/O to the specified NVMe namespace.
@@ -403,18 +432,18 @@ typedef int (*nvme_req_next_sge_fn_t)(void *cb_arg, uint64_t *address, uint32_t
  * \param lba_count length (in sectors) for the write operation
  * \param cb_fn callback function to invoke when the I/O is completed
  * \param cb_arg argument to pass to the callback function
- * \param io_flags set flags, defined by the NVME_IO_FLAGS_* entries
+ * \param io_flags set flags, defined by the SPDK_NVME_IO_FLAGS_* entries
  * 			in spdk/nvme_spec.h, for this I/O.
  *
  * \return 0 if successfully submitted, ENOMEM if an nvme_request
  *	     structure cannot be allocated for the I/O request
  *
  * This function is thread safe and can be called at any point after
- * nvme_register_io_thread().
+ * spdk_nvme_register_io_thread().
  */
-int nvme_ns_cmd_write(struct nvme_namespace *ns, void *payload,
-		      uint64_t lba, uint32_t lba_count, nvme_cb_fn_t cb_fn,
-		      void *cb_arg, uint32_t io_flags);
+int spdk_nvme_ns_cmd_write(struct spdk_nvme_ns *ns, void *payload,
+			   uint64_t lba, uint32_t lba_count, spdk_nvme_cmd_cb cb_fn,
+			   void *cb_arg, uint32_t io_flags);
 
 /**
  * \brief Submits a write I/O to the specified NVMe namespace.
@@ -433,12 +462,33 @@ int nvme_ns_cmd_write(struct nvme_namespace *ns, void *payload,
  *	     structure cannot be allocated for the I/O request
  *
  * This function is thread safe and can be called at any point after
- * nvme_register_io_thread().
+ * spdk_nvme_register_io_thread().
  */
-int nvme_ns_cmd_writev(struct nvme_namespace *ns, uint64_t lba, uint32_t lba_count,
-		       nvme_cb_fn_t cb_fn, void *cb_arg, uint32_t io_flags,
-		       nvme_req_reset_sgl_fn_t reset_sgl_fn,
-		       nvme_req_next_sge_fn_t next_sge_fn);
+int spdk_nvme_ns_cmd_writev(struct spdk_nvme_ns *ns, uint64_t lba, uint32_t lba_count,
+			    spdk_nvme_cmd_cb cb_fn, void *cb_arg, uint32_t io_flags,
+			    spdk_nvme_req_reset_sgl_cb reset_sgl_fn,
+			    spdk_nvme_req_next_sge_cb next_sge_fn);
+
+/**
+ * \brief Submits a write zeroes I/O to the specified NVMe namespace.
+ *
+ * \param ns NVMe namespace to submit the write zeroes I/O
+ * \param lba starting LBA for this command
+ * \param lba_count length (in sectors) for the write zero operation
+ * \param cb_fn callback function to invoke when the I/O is completed
+ * \param cb_arg argument to pass to the callback function
+ * \param io_flags set flags, defined by the SPDK_NVME_IO_FLAGS_* entries
+ * 			in spdk/nvme_spec.h, for this I/O.
+ *
+ * \return 0 if successfully submitted, ENOMEM if an nvme_request
+ *	     structure cannot be allocated for the I/O request
+ *
+ * This function is thread safe and can be called at any point after
+ * spdk_nvme_register_io_thread().
+ */
+int spdk_nvme_ns_cmd_write_zeroes(struct spdk_nvme_ns *ns, uint64_t lba,
+				  uint32_t lba_count, spdk_nvme_cmd_cb cb_fn, void *cb_arg,
+				  uint32_t io_flags);
 
 /**
  * \brief Submits a read I/O to the specified NVMe namespace.
@@ -455,11 +505,11 @@ int nvme_ns_cmd_writev(struct nvme_namespace *ns, uint64_t lba, uint32_t lba_cou
  *	     structure cannot be allocated for the I/O request
  *
  * This function is thread safe and can be called at any point after
- * nvme_register_io_thread().
+ * spdk_nvme_register_io_thread().
  */
-int nvme_ns_cmd_read(struct nvme_namespace *ns, void *payload,
-		     uint64_t lba, uint32_t lba_count, nvme_cb_fn_t cb_fn,
-		     void *cb_arg, uint32_t io_flags);
+int spdk_nvme_ns_cmd_read(struct spdk_nvme_ns *ns, void *payload,
+			  uint64_t lba, uint32_t lba_count, spdk_nvme_cmd_cb cb_fn,
+			  void *cb_arg, uint32_t io_flags);
 
 /**
  * \brief Submits a read I/O to the specified NVMe namespace.
@@ -478,13 +528,12 @@ int nvme_ns_cmd_read(struct nvme_namespace *ns, void *payload,
  *	     structure cannot be allocated for the I/O request
  *
  * This function is thread safe and can be called at any point after
- * nvme_register_io_thread().
+ * spdk_nvme_register_io_thread().
  */
-int nvme_ns_cmd_readv(struct nvme_namespace *ns, uint64_t lba, uint32_t lba_count,
-		      nvme_cb_fn_t cb_fn, void *cb_arg, uint32_t io_flags,
-		      nvme_req_reset_sgl_fn_t reset_sgl_fn,
-		      nvme_req_next_sge_fn_t next_sge_fn);
-
+int spdk_nvme_ns_cmd_readv(struct spdk_nvme_ns *ns, uint64_t lba, uint32_t lba_count,
+			   spdk_nvme_cmd_cb cb_fn, void *cb_arg, uint32_t io_flags,
+			   spdk_nvme_req_reset_sgl_cb reset_sgl_fn,
+			   spdk_nvme_req_next_sge_cb next_sge_fn);
 
 /**
  * \brief Submits a deallocation request to the specified NVMe namespace.
@@ -493,7 +542,7 @@ int nvme_ns_cmd_readv(struct nvme_namespace *ns, uint64_t lba, uint32_t lba_coun
  * \param payload virtual address pointer to the list of LBA ranges to
  *                deallocate
  * \param num_ranges number of ranges in the list pointed to by payload; must be
- *                between 1 and \ref NVME_DATASET_MANAGEMENT_MAX_RANGES, inclusive.
+ *                between 1 and \ref SPDK_NVME_DATASET_MANAGEMENT_MAX_RANGES, inclusive.
  * \param cb_fn callback function to invoke when the I/O is completed
  * \param cb_arg argument to pass to the callback function
  *
@@ -501,11 +550,11 @@ int nvme_ns_cmd_readv(struct nvme_namespace *ns, uint64_t lba, uint32_t lba_coun
  *	     structure cannot be allocated for the I/O request
  *
  * This function is thread safe and can be called at any point after
- * nvme_register_io_thread().
+ * spdk_nvme_register_io_thread().
  */
-int nvme_ns_cmd_deallocate(struct nvme_namespace *ns, void *payload,
-			   uint16_t num_ranges, nvme_cb_fn_t cb_fn,
-			   void *cb_arg);
+int spdk_nvme_ns_cmd_deallocate(struct spdk_nvme_ns *ns, void *payload,
+				uint16_t num_ranges, spdk_nvme_cmd_cb cb_fn,
+				void *cb_arg);
 
 /**
  * \brief Submits a flush request to the specified NVMe namespace.
@@ -518,10 +567,9 @@ int nvme_ns_cmd_deallocate(struct nvme_namespace *ns, void *payload,
  *	     structure cannot be allocated for the I/O request
  *
  * This function is thread safe and can be called at any point after
- * nvme_register_io_thread().
+ * spdk_nvme_register_io_thread().
  */
-int nvme_ns_cmd_flush(struct nvme_namespace *ns, nvme_cb_fn_t cb_fn,
-		      void *cb_arg);
+int spdk_nvme_ns_cmd_flush(struct spdk_nvme_ns *ns, spdk_nvme_cmd_cb cb_fn, void *cb_arg);
 
 /**
  * \brief Submits a reservation register to the specified NVMe namespace.
@@ -538,14 +586,14 @@ int nvme_ns_cmd_flush(struct nvme_namespace *ns, nvme_cb_fn_t cb_fn,
  *	     structure cannot be allocated for the I/O request
  *
  * This function is thread safe and can be called at any point after
- * nvme_register_io_thread().
+ * spdk_nvme_register_io_thread().
  */
-int nvme_ns_cmd_reservation_register(struct nvme_namespace *ns,
-				     struct nvme_reservation_register_data *payload,
-				     bool ignore_key,
-				     enum nvme_reservation_register_action action,
-				     enum nvme_reservation_register_cptpl cptpl,
-				     nvme_cb_fn_t cb_fn, void *cb_arg);
+int spdk_nvme_ns_cmd_reservation_register(struct spdk_nvme_ns *ns,
+		struct spdk_nvme_reservation_register_data *payload,
+		bool ignore_key,
+		enum spdk_nvme_reservation_register_action action,
+		enum spdk_nvme_reservation_register_cptpl cptpl,
+		spdk_nvme_cmd_cb cb_fn, void *cb_arg);
 
 /**
  * \brief Submits a reservation release to the specified NVMe namespace.
@@ -562,14 +610,14 @@ int nvme_ns_cmd_reservation_register(struct nvme_namespace *ns,
  *	     structure cannot be allocated for the I/O request
  *
  * This function is thread safe and can be called at any point after
- * nvme_register_io_thread().
+ * spdk_nvme_register_io_thread().
  */
-int nvme_ns_cmd_reservation_release(struct nvme_namespace *ns,
-				    struct nvme_reservation_key_data *payload,
-				    bool ignore_key,
-				    enum nvme_reservation_release_action action,
-				    enum nvme_reservation_type type,
-				    nvme_cb_fn_t cb_fn, void *cb_arg);
+int spdk_nvme_ns_cmd_reservation_release(struct spdk_nvme_ns *ns,
+		struct spdk_nvme_reservation_key_data *payload,
+		bool ignore_key,
+		enum spdk_nvme_reservation_release_action action,
+		enum spdk_nvme_reservation_type type,
+		spdk_nvme_cmd_cb cb_fn, void *cb_arg);
 
 /**
  * \brief Submits a reservation acquire to the specified NVMe namespace.
@@ -586,14 +634,14 @@ int nvme_ns_cmd_reservation_release(struct nvme_namespace *ns,
  *	     structure cannot be allocated for the I/O request
  *
  * This function is thread safe and can be called at any point after
- * nvme_register_io_thread().
+ * spdk_nvme_register_io_thread().
  */
-int nvme_ns_cmd_reservation_acquire(struct nvme_namespace *ns,
-				    struct nvme_reservation_acquire_data *payload,
-				    bool ignore_key,
-				    enum nvme_reservation_acquire_action action,
-				    enum nvme_reservation_type type,
-				    nvme_cb_fn_t cb_fn, void *cb_arg);
+int spdk_nvme_ns_cmd_reservation_acquire(struct spdk_nvme_ns *ns,
+		struct spdk_nvme_reservation_acquire_data *payload,
+		bool ignore_key,
+		enum spdk_nvme_reservation_acquire_action action,
+		enum spdk_nvme_reservation_type type,
+		spdk_nvme_cmd_cb cb_fn, void *cb_arg);
 
 /**
  * \brief Submits a reservation report to the specified NVMe namespace.
@@ -608,10 +656,10 @@ int nvme_ns_cmd_reservation_acquire(struct nvme_namespace *ns,
  *	     structure cannot be allocated for the I/O request
  *
  * This function is thread safe and can be called at any point after
- * nvme_register_io_thread().
+ * spdk_nvme_register_io_thread().
  */
-int nvme_ns_cmd_reservation_report(struct nvme_namespace *ns, void *payload,
-				   uint32_t len, nvme_cb_fn_t cb_fn, void *cb_arg);
+int spdk_nvme_ns_cmd_reservation_report(struct spdk_nvme_ns *ns, void *payload,
+					uint32_t len, spdk_nvme_cmd_cb cb_fn, void *cb_arg);
 
 /**
  * \brief Get the size, in bytes, of an nvme_request.
@@ -622,10 +670,10 @@ int nvme_ns_cmd_reservation_report(struct nvme_namespace *ns, void *payload,
  * This function is thread safe and can be called at any time.
  *
  */
-size_t nvme_request_size(void);
+size_t spdk_nvme_request_size(void);
 
-int nvme_register_io_thread(void);
-void nvme_unregister_io_thread(void);
+int spdk_nvme_register_io_thread(void);
+void spdk_nvme_unregister_io_thread(void);
 
 #ifdef __cplusplus
 }
diff --git a/src/spdk/include/spdk/nvme_intel.h b/src/spdk/include/spdk/nvme_intel.h
index 421c458..bac0be2 100644
--- a/src/spdk/include/spdk/nvme_intel.h
+++ b/src/spdk/include/spdk/nvme_intel.h
@@ -34,6 +34,10 @@
 #ifndef SPDK_NVME_INTEL_H
 #define SPDK_NVME_INTEL_H
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 #include <stdint.h>
 #include <stddef.h>
 
@@ -43,51 +47,50 @@
  * \file
  *
  * reference:
- * http://www.intel.com/content/dam/www/public/us/en/documents/product-specifications/
- * ssd-dc-p3700-spec.pdf
+ * http://www.intel.com/content/dam/www/public/us/en/documents/product-specifications/ssd-dc-p3700-spec.pdf
  */
 
-enum nvme_intel_feature {
-	NVME_INTEL_FEAT_MAX_LBA				= 0xC1,
-	NVME_INTEL_FEAT_NATIVE_MAX_LBA			= 0xC2,
-	NVME_INTEL_FEAT_POWER_GOVERNOR_SETTING		= 0xC6,
-	NVME_INTEL_FEAT_SMBUS_ADDRESS			= 0xC8,
-	NVME_INTEL_FEAT_LED_PATTERN			= 0xC9,
-	NVME_INTEL_FEAT_RESET_TIMED_WORKLOAD_COUNTERS	= 0xD5,
-	NVME_INTEL_FEAT_LATENCY_TRACKING		= 0xE2,
+enum spdk_nvme_intel_feat {
+	SPDK_NVME_INTEL_FEAT_MAX_LBA				= 0xC1,
+	SPDK_NVME_INTEL_FEAT_NATIVE_MAX_LBA			= 0xC2,
+	SPDK_NVME_INTEL_FEAT_POWER_GOVERNOR_SETTING		= 0xC6,
+	SPDK_NVME_INTEL_FEAT_SMBUS_ADDRESS			= 0xC8,
+	SPDK_NVME_INTEL_FEAT_LED_PATTERN			= 0xC9,
+	SPDK_NVME_INTEL_FEAT_RESET_TIMED_WORKLOAD_COUNTERS	= 0xD5,
+	SPDK_NVME_INTEL_FEAT_LATENCY_TRACKING			= 0xE2,
 };
 
-enum nvme_intel_set_max_lba_command_status_code {
-	NVME_INTEL_EXCEEDS_AVAILABLE_CAPACITY		= 0xC0,
-	NVME_INTEL_SMALLER_THAN_MIN_LIMIT		= 0xC1,
-	NVME_INTEL_SMALLER_THAN_NS_REQUIREMENTS		= 0xC2,
+enum spdk_nvme_intel_set_max_lba_command_status_code {
+	SPDK_NVME_INTEL_EXCEEDS_AVAILABLE_CAPACITY		= 0xC0,
+	SPDK_NVME_INTEL_SMALLER_THAN_MIN_LIMIT			= 0xC1,
+	SPDK_NVME_INTEL_SMALLER_THAN_NS_REQUIREMENTS		= 0xC2,
 };
 
-enum nvme_intel_log_page {
-	NVME_INTEL_LOG_PAGE_DIRECTORY		= 0xC0,
-	NVME_INTEL_LOG_READ_CMD_LATENCY		= 0xC1,
-	NVME_INTEL_LOG_WRITE_CMD_LATENCY	= 0xC2,
-	NVME_INTEL_LOG_TEMPERATURE		= 0xC5,
-	NVME_INTEL_LOG_SMART			= 0xCA,
+enum spdk_nvme_intel_log_page {
+	SPDK_NVME_INTEL_LOG_PAGE_DIRECTORY			= 0xC0,
+	SPDK_NVME_INTEL_LOG_READ_CMD_LATENCY			= 0xC1,
+	SPDK_NVME_INTEL_LOG_WRITE_CMD_LATENCY			= 0xC2,
+	SPDK_NVME_INTEL_LOG_TEMPERATURE				= 0xC5,
+	SPDK_NVME_INTEL_LOG_SMART				= 0xCA,
 };
 
-enum nvme_intel_smart_attribute_code {
-	NVME_INTEL_SMART_PROGRAM_FAIL_COUNT			= 0xAB,
-	NVME_INTEL_SMART_ERASE_FAIL_COUNT			= 0xAC,
-	NVME_INTEL_SMART_WEAR_LEVELING_COUNT			= 0xAD,
-	NVME_INTEL_SMART_E2E_ERROR_COUNT			= 0xB8,
-	NVME_INTEL_SMART_CRC_ERROR_COUNT			= 0xC7,
-	NVME_INTEL_SMART_MEDIA_WEAR				= 0xE2,
-	NVME_INTEL_SMART_HOST_READ_PERCENTAGE			= 0xE3,
-	NVME_INTEL_SMART_TIMER					= 0xE4,
-	NVME_INTEL_SMART_THERMAL_THROTTLE_STATUS		= 0xEA,
-	NVME_INTEL_SMART_RETRY_BUFFER_OVERFLOW_COUNTER		= 0xF0,
-	NVME_INTEL_SMART_PLL_LOCK_LOSS_COUNT			= 0xF3,
-	NVME_INTEL_SMART_NAND_BYTES_WRITTEN			= 0xF4,
-	NVME_INTEL_SMART_HOST_BYTES_WRITTEN			= 0xF5,
+enum spdk_nvme_intel_smart_attribute_code {
+	SPDK_NVME_INTEL_SMART_PROGRAM_FAIL_COUNT		= 0xAB,
+	SPDK_NVME_INTEL_SMART_ERASE_FAIL_COUNT			= 0xAC,
+	SPDK_NVME_INTEL_SMART_WEAR_LEVELING_COUNT		= 0xAD,
+	SPDK_NVME_INTEL_SMART_E2E_ERROR_COUNT			= 0xB8,
+	SPDK_NVME_INTEL_SMART_CRC_ERROR_COUNT			= 0xC7,
+	SPDK_NVME_INTEL_SMART_MEDIA_WEAR			= 0xE2,
+	SPDK_NVME_INTEL_SMART_HOST_READ_PERCENTAGE		= 0xE3,
+	SPDK_NVME_INTEL_SMART_TIMER				= 0xE4,
+	SPDK_NVME_INTEL_SMART_THERMAL_THROTTLE_STATUS		= 0xEA,
+	SPDK_NVME_INTEL_SMART_RETRY_BUFFER_OVERFLOW_COUNTER	= 0xF0,
+	SPDK_NVME_INTEL_SMART_PLL_LOCK_LOSS_COUNT		= 0xF3,
+	SPDK_NVME_INTEL_SMART_NAND_BYTES_WRITTEN		= 0xF4,
+	SPDK_NVME_INTEL_SMART_HOST_BYTES_WRITTEN		= 0xF5,
 };
 
-struct nvme_intel_log_page_directory {
+struct spdk_nvme_intel_log_page_directory {
 	uint8_t		version[2];
 	uint8_t		reserved[384];
 	uint8_t		read_latency_log_len;
@@ -99,18 +102,18 @@ struct nvme_intel_log_page_directory {
 	uint8_t		smart_log_len;
 	uint8_t		reserved5[107];
 };
-SPDK_STATIC_ASSERT(sizeof(struct nvme_intel_log_page_directory) == 512, "Incorrect size");
+SPDK_STATIC_ASSERT(sizeof(struct spdk_nvme_intel_log_page_directory) == 512, "Incorrect size");
 
-struct nvme_intel_rw_latency_page {
+struct spdk_nvme_intel_rw_latency_page {
 	uint16_t		major_revison;
 	uint16_t		minor_revison;
 	uint32_t		buckets_32us[32];
 	uint32_t		buckets_1ms[31];
 	uint32_t		buckets_32ms[31];
 };
-SPDK_STATIC_ASSERT(sizeof(struct nvme_intel_rw_latency_page) == 380, "Incorrect size");
+SPDK_STATIC_ASSERT(sizeof(struct spdk_nvme_intel_rw_latency_page) == 380, "Incorrect size");
 
-struct nvme_intel_temperature_page {
+struct spdk_nvme_intel_temperature_page {
 	uint64_t		current_temperature;
 	uint64_t		shutdown_flag_last;
 	uint64_t		shutdown_flag_life;
@@ -122,9 +125,9 @@ struct nvme_intel_temperature_page {
 	uint64_t		specified_min_op_temperature;
 	uint64_t		estimated_offset;
 };
-SPDK_STATIC_ASSERT(sizeof(struct nvme_intel_temperature_page) == 112, "Incorrect size");
+SPDK_STATIC_ASSERT(sizeof(struct spdk_nvme_intel_temperature_page) == 112, "Incorrect size");
 
-struct nvme_intel_smart_attribute {
+struct spdk_nvme_intel_smart_attribute {
 	uint8_t			code;
 	uint8_t			reserved[2];
 	uint8_t			normalized_value;
@@ -133,12 +136,12 @@ struct nvme_intel_smart_attribute {
 	uint8_t			reserved3;
 };
 
-struct __attribute__((packed)) nvme_intel_smart_information_page {
-	struct nvme_intel_smart_attribute	nvme_intel_smart_attributes[13];
+struct __attribute__((packed)) spdk_nvme_intel_smart_information_page {
+	struct spdk_nvme_intel_smart_attribute	attributes[13];
 };
-SPDK_STATIC_ASSERT(sizeof(struct nvme_intel_smart_information_page) == 156, "Incorrect size");
+SPDK_STATIC_ASSERT(sizeof(struct spdk_nvme_intel_smart_information_page) == 156, "Incorrect size");
 
-union nvme_intel_power_governor_feature {
+union spdk_nvme_intel_feat_power_governor {
 	uint32_t	raw;
 	struct {
 		/** power governor setting : 00h = 25W 01h = 20W 02h = 10W */
@@ -146,9 +149,9 @@ union nvme_intel_power_governor_feature {
 		uint32_t reserved	: 24;
 	} bits;
 };
-SPDK_STATIC_ASSERT(sizeof(union nvme_intel_power_governor_feature) == 4, "Incorrect size");
+SPDK_STATIC_ASSERT(sizeof(union spdk_nvme_intel_feat_power_governor) == 4, "Incorrect size");
 
-union nvme_intel_smbus_address_feature {
+union spdk_nvme_intel_feat_smbus_address {
 	uint32_t	raw;
 	struct {
 		uint32_t reserved	: 1;
@@ -156,18 +159,18 @@ union nvme_intel_smbus_address_feature {
 		uint32_t reserved2	: 23;
 	} bits;
 };
-SPDK_STATIC_ASSERT(sizeof(union nvme_intel_smbus_address_feature) == 4, "Incorrect size");
+SPDK_STATIC_ASSERT(sizeof(union spdk_nvme_intel_feat_smbus_address) == 4, "Incorrect size");
 
-union nvme_intel_led_pattern_feature {
+union spdk_nvme_intel_feat_led_pattern {
 	uint32_t	raw;
 	struct {
 		uint32_t feature_options	: 24;
 		uint32_t value	: 8;
 	} bits;
 };
-SPDK_STATIC_ASSERT(sizeof(union nvme_intel_led_pattern_feature) == 4, "Incorrect size");
+SPDK_STATIC_ASSERT(sizeof(union spdk_nvme_intel_feat_led_pattern) == 4, "Incorrect size");
 
-union nvme_intel_reset_timed_workload_counters_feature {
+union spdk_nvme_intel_feat_reset_timed_workload_counters {
 	uint32_t	raw;
 	struct {
 		/**
@@ -178,10 +181,10 @@ union nvme_intel_reset_timed_workload_counters_feature {
 		uint32_t reserved	: 31;
 	} bits;
 };
-SPDK_STATIC_ASSERT(sizeof(union nvme_intel_reset_timed_workload_counters_feature) == 4,
+SPDK_STATIC_ASSERT(sizeof(union spdk_nvme_intel_feat_reset_timed_workload_counters) == 4,
 		   "Incorrect size");
 
-union nvme_intel_enable_latency_tracking_feature {
+union spdk_nvme_intel_feat_latency_tracking {
 	uint32_t	raw;
 	struct {
 		/**
@@ -192,5 +195,10 @@ union nvme_intel_enable_latency_tracking_feature {
 		uint32_t enable	: 32;
 	} bits;
 };
-SPDK_STATIC_ASSERT(sizeof(union nvme_intel_enable_latency_tracking_feature) == 4, "Incorrect size");
+SPDK_STATIC_ASSERT(sizeof(union spdk_nvme_intel_feat_latency_tracking) == 4, "Incorrect size");
+
+#ifdef __cplusplus
+}
+#endif
+
 #endif
diff --git a/src/spdk/include/spdk/nvme_spec.h b/src/spdk/include/spdk/nvme_spec.h
index 52f6304..aa8ab93 100644
--- a/src/spdk/include/spdk/nvme_spec.h
+++ b/src/spdk/include/spdk/nvme_spec.h
@@ -34,6 +34,10 @@
 #ifndef SPDK_NVME_SPEC_H
 #define SPDK_NVME_SPEC_H
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 #include <stdint.h>
 #include <stddef.h>
 
@@ -45,29 +49,20 @@
  */
 
 /**
- * PCI class code for NVMe devices.
- *
- * Base class code 01h: mass storage
- * Subclass code 08h: non-volatile memory
- * Programming interface 02h: NVM Express
- */
-#define NVME_CLASS_CODE 0x10802
-
-/**
  * Use to mark a command to apply to all namespaces, or to retrieve global
  *  log pages.
  */
-#define NVME_GLOBAL_NAMESPACE_TAG	((uint32_t)0xFFFFFFFF)
+#define SPDK_NVME_GLOBAL_NS_TAG		((uint32_t)0xFFFFFFFF)
 
-#define NVME_MAX_IO_QUEUES		(1 << 16)
+#define SPDK_NVME_MAX_IO_QUEUES		(1 << 16)
 
 /**
  * Indicates the maximum number of range sets that may be specified
  *  in the dataset mangement command.
  */
-#define NVME_DATASET_MANAGEMENT_MAX_RANGES	256
+#define SPDK_NVME_DATASET_MANAGEMENT_MAX_RANGES	256
 
-union nvme_cap_lo_register {
+union spdk_nvme_cap_lo_register {
 	uint32_t	raw;
 	struct {
 		/** maximum queue entries supported */
@@ -85,9 +80,9 @@ union nvme_cap_lo_register {
 		uint32_t to		: 8;
 	} bits;
 };
-SPDK_STATIC_ASSERT(sizeof(union nvme_cap_lo_register) == 4, "Incorrect size");
+SPDK_STATIC_ASSERT(sizeof(union spdk_nvme_cap_lo_register) == 4, "Incorrect size");
 
-union nvme_cap_hi_register {
+union spdk_nvme_cap_hi_register {
 	uint32_t	raw;
 	struct {
 		/** doorbell stride */
@@ -110,9 +105,9 @@ union nvme_cap_hi_register {
 		uint32_t reserved1	: 8;
 	} bits;
 };
-SPDK_STATIC_ASSERT(sizeof(union nvme_cap_hi_register) == 4, "Incorrect size");
+SPDK_STATIC_ASSERT(sizeof(union spdk_nvme_cap_hi_register) == 4, "Incorrect size");
 
-union nvme_cc_register {
+union spdk_nvme_cc_register {
 	uint32_t	raw;
 	struct {
 		/** enable */
@@ -141,14 +136,14 @@ union nvme_cc_register {
 		uint32_t reserved2	: 8;
 	} bits;
 };
-SPDK_STATIC_ASSERT(sizeof(union nvme_cc_register) == 4, "Incorrect size");
+SPDK_STATIC_ASSERT(sizeof(union spdk_nvme_cc_register) == 4, "Incorrect size");
 
-enum nvme_shn_value {
-	NVME_SHN_NORMAL		= 0x1,
-	NVME_SHN_ABRUPT		= 0x2,
+enum spdk_nvme_shn_value {
+	SPDK_NVME_SHN_NORMAL		= 0x1,
+	SPDK_NVME_SHN_ABRUPT		= 0x2,
 };
 
-union nvme_csts_register {
+union spdk_nvme_csts_register {
 	uint32_t	raw;
 	struct {
 		/** ready */
@@ -163,15 +158,15 @@ union nvme_csts_register {
 		uint32_t reserved1	: 28;
 	} bits;
 };
-SPDK_STATIC_ASSERT(sizeof(union nvme_csts_register) == 4, "Incorrect size");
+SPDK_STATIC_ASSERT(sizeof(union spdk_nvme_csts_register) == 4, "Incorrect size");
 
-enum nvme_shst_value {
-	NVME_SHST_NORMAL	= 0x0,
-	NVME_SHST_OCCURRING	= 0x1,
-	NVME_SHST_COMPLETE	= 0x2,
+enum spdk_nvme_shst_value {
+	SPDK_NVME_SHST_NORMAL		= 0x0,
+	SPDK_NVME_SHST_OCCURRING	= 0x1,
+	SPDK_NVME_SHST_COMPLETE		= 0x2,
 };
 
-union nvme_aqa_register {
+union spdk_nvme_aqa_register {
 	uint32_t	raw;
 	struct {
 		/** admin submission queue size */
@@ -185,30 +180,81 @@ union nvme_aqa_register {
 		uint32_t reserved2	: 4;
 	} bits;
 };
-SPDK_STATIC_ASSERT(sizeof(union nvme_aqa_register) == 4, "Incorrect size");
+SPDK_STATIC_ASSERT(sizeof(union spdk_nvme_aqa_register) == 4, "Incorrect size");
+
+union spdk_nvme_vs_register {
+	uint32_t	raw;
+	struct {
+		uint32_t reserved1	: 8;
+		/** indicates the minor version */
+		uint32_t mnr		: 8;
+		/** indicates the major version */
+		uint32_t mjr		: 16;
+	} bits;
+};
+SPDK_STATIC_ASSERT(sizeof(union spdk_nvme_vs_register) == 4, "Incorrect size");
 
-struct nvme_registers {
+union spdk_nvme_cmbloc_register {
+	uint32_t	raw;
+	struct {
+		/** indicator of BAR which contains controller memory buffer(CMB) */
+		uint32_t bir		: 3;
+		uint32_t reserved1	: 9;
+		/** offset of CMB in multiples of the size unit */
+		uint32_t ofst		: 20;
+	} bits;
+};
+SPDK_STATIC_ASSERT(sizeof(union spdk_nvme_cmbloc_register) == 4, "Incorrect size");
+
+union spdk_nvme_cmbsz_register {
+	uint32_t	raw;
+	struct {
+		/** support submission queues in CMB */
+		uint32_t sqs		: 1;
+		/** support completion queues in CMB */
+		uint32_t cqs		: 1;
+		/** support PRP and SGLs lists in CMB */
+		uint32_t lists		: 1;
+		/** support read data and metadata in CMB */
+		uint32_t rds		: 1;
+		/** support write data and metadata in CMB */
+		uint32_t wds		: 1;
+		uint32_t reserved1	: 3;
+		/** indicates the granularity of the size unit */
+		uint32_t szu		: 4;
+		/** size of CMB in multiples of the size unit */
+		uint32_t sz		: 20;
+	} bits;
+};
+SPDK_STATIC_ASSERT(sizeof(union spdk_nvme_cmbsz_register) == 4, "Incorrect size");
+
+struct spdk_nvme_registers {
 	/** controller capabilities */
-	union nvme_cap_lo_register	cap_lo;
-	union nvme_cap_hi_register	cap_hi;
+	union spdk_nvme_cap_lo_register	cap_lo;
+	union spdk_nvme_cap_hi_register	cap_hi;
 
-	uint32_t	vs;		/* version */
+	/** version of NVMe specification */
+	union spdk_nvme_vs_register vs;
 	uint32_t	intms;		/* interrupt mask set */
 	uint32_t	intmc;		/* interrupt mask clear */
 
 	/** controller configuration */
-	union nvme_cc_register	cc;
+	union spdk_nvme_cc_register	cc;
 
 	uint32_t	reserved1;
 	uint32_t	csts;		/* controller status */
 	uint32_t	nssr;		/* NVM subsystem reset */
 
 	/** admin queue attributes */
-	union nvme_aqa_register	aqa;
+	union spdk_nvme_aqa_register	aqa;
 
 	uint64_t	asq;		/* admin submission queue base addr */
 	uint64_t	acq;		/* admin completion queue base addr */
-	uint32_t	reserved3[0x3f2];
+	/** controller memory buffer location */
+	union spdk_nvme_cmbloc_register	cmbloc;
+	/** controller memory buffer size */
+	union spdk_nvme_cmbsz_register cmbsz;
+	uint32_t	reserved3[0x3f0];
 
 	struct {
 		uint32_t	sq_tdbl;	/* submission queue tail doorbell */
@@ -217,27 +263,34 @@ struct nvme_registers {
 };
 
 /* NVMe controller register space offsets */
-SPDK_STATIC_ASSERT(0x00 == offsetof(struct nvme_registers, cap_lo), "Incorrect register offset");
-SPDK_STATIC_ASSERT(0x08 == offsetof(struct nvme_registers, vs), "Incorrect register offset");
-SPDK_STATIC_ASSERT(0x0C == offsetof(struct nvme_registers, intms), "Incorrect register offset");
-SPDK_STATIC_ASSERT(0x10 == offsetof(struct nvme_registers, intmc), "Incorrect register offset");
-SPDK_STATIC_ASSERT(0x14 == offsetof(struct nvme_registers, cc), "Incorrect register offset");
-SPDK_STATIC_ASSERT(0x1C == offsetof(struct nvme_registers, csts), "Incorrect register offset");
-SPDK_STATIC_ASSERT(0x20 == offsetof(struct nvme_registers, nssr), "Incorrect register offset");
-SPDK_STATIC_ASSERT(0x24 == offsetof(struct nvme_registers, aqa), "Incorrect register offset");
-SPDK_STATIC_ASSERT(0x28 == offsetof(struct nvme_registers, asq), "Incorrect register offset");
-SPDK_STATIC_ASSERT(0x30 == offsetof(struct nvme_registers, acq), "Incorrect register offset");
-
-enum nvme_sgl_descriptor_type {
-	NVME_SGL_TYPE_DATA_BLOCK	= 0x0,
-	NVME_SGL_TYPE_BIT_BUCKET	= 0x1,
-	NVME_SGL_TYPE_SEGMENT		= 0x2,
-	NVME_SGL_TYPE_LAST_SEGMENT	= 0x3,
+SPDK_STATIC_ASSERT(0x00 == offsetof(struct spdk_nvme_registers, cap_lo),
+		   "Incorrect register offset");
+SPDK_STATIC_ASSERT(0x08 == offsetof(struct spdk_nvme_registers, vs), "Incorrect register offset");
+SPDK_STATIC_ASSERT(0x0C == offsetof(struct spdk_nvme_registers, intms),
+		   "Incorrect register offset");
+SPDK_STATIC_ASSERT(0x10 == offsetof(struct spdk_nvme_registers, intmc),
+		   "Incorrect register offset");
+SPDK_STATIC_ASSERT(0x14 == offsetof(struct spdk_nvme_registers, cc), "Incorrect register offset");
+SPDK_STATIC_ASSERT(0x1C == offsetof(struct spdk_nvme_registers, csts), "Incorrect register offset");
+SPDK_STATIC_ASSERT(0x20 == offsetof(struct spdk_nvme_registers, nssr), "Incorrect register offset");
+SPDK_STATIC_ASSERT(0x24 == offsetof(struct spdk_nvme_registers, aqa), "Incorrect register offset");
+SPDK_STATIC_ASSERT(0x28 == offsetof(struct spdk_nvme_registers, asq), "Incorrect register offset");
+SPDK_STATIC_ASSERT(0x30 == offsetof(struct spdk_nvme_registers, acq), "Incorrect register offset");
+SPDK_STATIC_ASSERT(0x38 == offsetof(struct spdk_nvme_registers, cmbloc),
+		   "Incorrect register offset");
+SPDK_STATIC_ASSERT(0x3C == offsetof(struct spdk_nvme_registers, cmbsz),
+		   "Incorrect register offset");
+
+enum spdk_nvme_sgl_descriptor_type {
+	SPDK_NVME_SGL_TYPE_DATA_BLOCK		= 0x0,
+	SPDK_NVME_SGL_TYPE_BIT_BUCKET		= 0x1,
+	SPDK_NVME_SGL_TYPE_SEGMENT		= 0x2,
+	SPDK_NVME_SGL_TYPE_LAST_SEGMENT		= 0x3,
 	/* 0x4 - 0xe reserved */
-	NVME_SGL_TYPE_VENDOR_SPECIFIC	= 0xf
+	SPDK_NVME_SGL_TYPE_VENDOR_SPECIFIC	= 0xf
 };
 
-struct __attribute__((packed)) nvme_sgl_descriptor {
+struct __attribute__((packed)) spdk_nvme_sgl_descriptor {
 	uint64_t address;
 	uint32_t length;
 	uint8_t reserved[3];
@@ -248,16 +301,16 @@ struct __attribute__((packed)) nvme_sgl_descriptor {
 	/** SGL descriptor type specific */
 	uint8_t type_specific : 4;
 };
-SPDK_STATIC_ASSERT(sizeof(struct nvme_sgl_descriptor) == 16, "Incorrect size");
+SPDK_STATIC_ASSERT(sizeof(struct spdk_nvme_sgl_descriptor) == 16, "Incorrect size");
 
-enum nvme_psdt_value {
-	NVME_PSDT_PRP			= 0x0,
-	NVME_PSDT_SGL_MPTR_CONTIG	= 0x1,
-	NVME_PSDT_SGL_MPTR_SGL		= 0x2,
-	NVME_PSDT_RESERVED		= 0x3
+enum spdk_nvme_psdt_value {
+	SPDK_NVME_PSDT_PRP		= 0x0,
+	SPDK_NVME_PSDT_SGL_MPTR_CONTIG	= 0x1,
+	SPDK_NVME_PSDT_SGL_MPTR_SGL	= 0x2,
+	SPDK_NVME_PSDT_RESERVED		= 0x3
 };
 
-struct nvme_command {
+struct spdk_nvme_cmd {
 	/* dword 0 */
 	uint16_t opc	:  8;	/* opcode */
 	uint16_t fuse	:  2;	/* fused operation */
@@ -282,7 +335,7 @@ struct nvme_command {
 			uint64_t prp2;		/* prp entry 2 */
 		} prp;
 
-		struct nvme_sgl_descriptor sgl1;
+		struct spdk_nvme_sgl_descriptor sgl1;
 	} dptr;
 
 	/* dword 10-15 */
@@ -293,9 +346,9 @@ struct nvme_command {
 	uint32_t cdw14;		/* command-specific */
 	uint32_t cdw15;		/* command-specific */
 };
-SPDK_STATIC_ASSERT(sizeof(struct nvme_command) == 64, "Incorrect size");
+SPDK_STATIC_ASSERT(sizeof(struct spdk_nvme_cmd) == 64, "Incorrect size");
 
-struct nvme_status {
+struct spdk_nvme_status {
 	uint16_t p	:  1;	/* phase tag */
 	uint16_t sc	:  8;	/* status code */
 	uint16_t sct	:  3;	/* status code type */
@@ -303,9 +356,12 @@ struct nvme_status {
 	uint16_t m	:  1;	/* more */
 	uint16_t dnr	:  1;	/* do not retry */
 };
-SPDK_STATIC_ASSERT(sizeof(struct nvme_status) == 2, "Incorrect size");
+SPDK_STATIC_ASSERT(sizeof(struct spdk_nvme_status) == 2, "Incorrect size");
 
-struct nvme_completion {
+/**
+ * Completion queue entry
+ */
+struct spdk_nvme_cpl {
 	/* dword 0 */
 	uint32_t		cdw0;	/* command-specific */
 
@@ -318,155 +374,170 @@ struct nvme_completion {
 
 	/* dword 3 */
 	uint16_t		cid;	/* command identifier */
-	struct nvme_status	status;
+	struct spdk_nvme_status	status;
 };
-SPDK_STATIC_ASSERT(sizeof(struct nvme_completion) == 16, "Incorrect size");
+SPDK_STATIC_ASSERT(sizeof(struct spdk_nvme_cpl) == 16, "Incorrect size");
 
-struct nvme_dsm_range {
+/**
+ * Dataset Management range
+ */
+struct spdk_nvme_dsm_range {
 	uint32_t attributes;
 	uint32_t length;
 	uint64_t starting_lba;
 };
-SPDK_STATIC_ASSERT(sizeof(struct nvme_dsm_range) == 16, "Incorrect size");
+SPDK_STATIC_ASSERT(sizeof(struct spdk_nvme_dsm_range) == 16, "Incorrect size");
 
-/* status code types */
-enum nvme_status_code_type {
-	NVME_SCT_GENERIC		= 0x0,
-	NVME_SCT_COMMAND_SPECIFIC	= 0x1,
-	NVME_SCT_MEDIA_ERROR		= 0x2,
+/**
+ * Status code types
+ */
+enum spdk_nvme_status_code_type {
+	SPDK_NVME_SCT_GENERIC		= 0x0,
+	SPDK_NVME_SCT_COMMAND_SPECIFIC	= 0x1,
+	SPDK_NVME_SCT_MEDIA_ERROR	= 0x2,
 	/* 0x3-0x6 - reserved */
-	NVME_SCT_VENDOR_SPECIFIC	= 0x7,
+	SPDK_NVME_SCT_VENDOR_SPECIFIC	= 0x7,
 };
 
-/* generic command status codes */
-enum nvme_generic_command_status_code {
-	NVME_SC_SUCCESS				= 0x00,
-	NVME_SC_INVALID_OPCODE			= 0x01,
-	NVME_SC_INVALID_FIELD			= 0x02,
-	NVME_SC_COMMAND_ID_CONFLICT		= 0x03,
-	NVME_SC_DATA_TRANSFER_ERROR		= 0x04,
-	NVME_SC_ABORTED_POWER_LOSS		= 0x05,
-	NVME_SC_INTERNAL_DEVICE_ERROR		= 0x06,
-	NVME_SC_ABORTED_BY_REQUEST		= 0x07,
-	NVME_SC_ABORTED_SQ_DELETION		= 0x08,
-	NVME_SC_ABORTED_FAILED_FUSED		= 0x09,
-	NVME_SC_ABORTED_MISSING_FUSED		= 0x0a,
-	NVME_SC_INVALID_NAMESPACE_OR_FORMAT	= 0x0b,
-	NVME_SC_COMMAND_SEQUENCE_ERROR		= 0x0c,
-
-	NVME_SC_LBA_OUT_OF_RANGE		= 0x80,
-	NVME_SC_CAPACITY_EXCEEDED		= 0x81,
-	NVME_SC_NAMESPACE_NOT_READY		= 0x82,
+/**
+ * Generic command status codes
+ */
+enum spdk_nvme_generic_command_status_code {
+	SPDK_NVME_SC_SUCCESS				= 0x00,
+	SPDK_NVME_SC_INVALID_OPCODE			= 0x01,
+	SPDK_NVME_SC_INVALID_FIELD			= 0x02,
+	SPDK_NVME_SC_COMMAND_ID_CONFLICT		= 0x03,
+	SPDK_NVME_SC_DATA_TRANSFER_ERROR		= 0x04,
+	SPDK_NVME_SC_ABORTED_POWER_LOSS			= 0x05,
+	SPDK_NVME_SC_INTERNAL_DEVICE_ERROR		= 0x06,
+	SPDK_NVME_SC_ABORTED_BY_REQUEST			= 0x07,
+	SPDK_NVME_SC_ABORTED_SQ_DELETION		= 0x08,
+	SPDK_NVME_SC_ABORTED_FAILED_FUSED		= 0x09,
+	SPDK_NVME_SC_ABORTED_MISSING_FUSED		= 0x0a,
+	SPDK_NVME_SC_INVALID_NAMESPACE_OR_FORMAT	= 0x0b,
+	SPDK_NVME_SC_COMMAND_SEQUENCE_ERROR		= 0x0c,
+
+	SPDK_NVME_SC_LBA_OUT_OF_RANGE			= 0x80,
+	SPDK_NVME_SC_CAPACITY_EXCEEDED			= 0x81,
+	SPDK_NVME_SC_NAMESPACE_NOT_READY		= 0x82,
 };
 
-/* command specific status codes */
-enum nvme_command_specific_status_code {
-	NVME_SC_COMPLETION_QUEUE_INVALID	= 0x00,
-	NVME_SC_INVALID_QUEUE_IDENTIFIER	= 0x01,
-	NVME_SC_MAXIMUM_QUEUE_SIZE_EXCEEDED	= 0x02,
-	NVME_SC_ABORT_COMMAND_LIMIT_EXCEEDED	= 0x03,
+/**
+ * Command specific status codes
+ */
+enum spdk_nvme_command_specific_status_code {
+	SPDK_NVME_SC_COMPLETION_QUEUE_INVALID		= 0x00,
+	SPDK_NVME_SC_INVALID_QUEUE_IDENTIFIER		= 0x01,
+	SPDK_NVME_SC_MAXIMUM_QUEUE_SIZE_EXCEEDED	= 0x02,
+	SPDK_NVME_SC_ABORT_COMMAND_LIMIT_EXCEEDED	= 0x03,
 	/* 0x04 - reserved */
-	NVME_SC_ASYNC_EVENT_REQUEST_LIMIT_EXCEEDED = 0x05,
-	NVME_SC_INVALID_FIRMWARE_SLOT		= 0x06,
-	NVME_SC_INVALID_FIRMWARE_IMAGE		= 0x07,
-	NVME_SC_INVALID_INTERRUPT_VECTOR	= 0x08,
-	NVME_SC_INVALID_LOG_PAGE		= 0x09,
-	NVME_SC_INVALID_FORMAT			= 0x0a,
-	NVME_SC_FIRMWARE_REQUIRES_RESET		= 0x0b,
-
-	NVME_SC_CONFLICTING_ATTRIBUTES		= 0x80,
-	NVME_SC_INVALID_PROTECTION_INFO		= 0x81,
-	NVME_SC_ATTEMPTED_WRITE_TO_RO_PAGE	= 0x82,
+	SPDK_NVME_SC_ASYNC_EVENT_REQUEST_LIMIT_EXCEEDED = 0x05,
+	SPDK_NVME_SC_INVALID_FIRMWARE_SLOT		= 0x06,
+	SPDK_NVME_SC_INVALID_FIRMWARE_IMAGE		= 0x07,
+	SPDK_NVME_SC_INVALID_INTERRUPT_VECTOR		= 0x08,
+	SPDK_NVME_SC_INVALID_LOG_PAGE			= 0x09,
+	SPDK_NVME_SC_INVALID_FORMAT			= 0x0a,
+	SPDK_NVME_SC_FIRMWARE_REQUIRES_RESET		= 0x0b,
+
+	SPDK_NVME_SC_CONFLICTING_ATTRIBUTES		= 0x80,
+	SPDK_NVME_SC_INVALID_PROTECTION_INFO		= 0x81,
+	SPDK_NVME_SC_ATTEMPTED_WRITE_TO_RO_PAGE		= 0x82,
 };
 
-/* media error status codes */
-enum nvme_media_error_status_code {
-	NVME_SC_WRITE_FAULTS			= 0x80,
-	NVME_SC_UNRECOVERED_READ_ERROR		= 0x81,
-	NVME_SC_GUARD_CHECK_ERROR		= 0x82,
-	NVME_SC_APPLICATION_TAG_CHECK_ERROR	= 0x83,
-	NVME_SC_REFERENCE_TAG_CHECK_ERROR	= 0x84,
-	NVME_SC_COMPARE_FAILURE			= 0x85,
-	NVME_SC_ACCESS_DENIED			= 0x86,
+/**
+ * Media error status codes
+ */
+enum spdk_nvme_media_error_status_code {
+	SPDK_NVME_SC_WRITE_FAULTS			= 0x80,
+	SPDK_NVME_SC_UNRECOVERED_READ_ERROR		= 0x81,
+	SPDK_NVME_SC_GUARD_CHECK_ERROR			= 0x82,
+	SPDK_NVME_SC_APPLICATION_TAG_CHECK_ERROR	= 0x83,
+	SPDK_NVME_SC_REFERENCE_TAG_CHECK_ERROR		= 0x84,
+	SPDK_NVME_SC_COMPARE_FAILURE			= 0x85,
+	SPDK_NVME_SC_ACCESS_DENIED			= 0x86,
 };
 
-/* admin opcodes */
-enum nvme_admin_opcode {
-	NVME_OPC_DELETE_IO_SQ			= 0x00,
-	NVME_OPC_CREATE_IO_SQ			= 0x01,
-	NVME_OPC_GET_LOG_PAGE			= 0x02,
+/**
+ * Admin opcodes
+ */
+enum spdk_nvme_admin_opcode {
+	SPDK_NVME_OPC_DELETE_IO_SQ			= 0x00,
+	SPDK_NVME_OPC_CREATE_IO_SQ			= 0x01,
+	SPDK_NVME_OPC_GET_LOG_PAGE			= 0x02,
 	/* 0x03 - reserved */
-	NVME_OPC_DELETE_IO_CQ			= 0x04,
-	NVME_OPC_CREATE_IO_CQ			= 0x05,
-	NVME_OPC_IDENTIFY			= 0x06,
+	SPDK_NVME_OPC_DELETE_IO_CQ			= 0x04,
+	SPDK_NVME_OPC_CREATE_IO_CQ			= 0x05,
+	SPDK_NVME_OPC_IDENTIFY				= 0x06,
 	/* 0x07 - reserved */
-	NVME_OPC_ABORT				= 0x08,
-	NVME_OPC_SET_FEATURES			= 0x09,
-	NVME_OPC_GET_FEATURES			= 0x0a,
+	SPDK_NVME_OPC_ABORT				= 0x08,
+	SPDK_NVME_OPC_SET_FEATURES			= 0x09,
+	SPDK_NVME_OPC_GET_FEATURES			= 0x0a,
 	/* 0x0b - reserved */
-	NVME_OPC_ASYNC_EVENT_REQUEST		= 0x0c,
-	NVME_OPC_NAMESPACE_MANAGEMENT		= 0x0d,
+	SPDK_NVME_OPC_ASYNC_EVENT_REQUEST		= 0x0c,
+	SPDK_NVME_OPC_NS_MANAGEMENT			= 0x0d,
 	/* 0x0e-0x0f - reserved */
-	NVME_OPC_FIRMWARE_COMMIT		= 0x10,
-	NVME_OPC_FIRMWARE_IMAGE_DOWNLOAD	= 0x11,
+	SPDK_NVME_OPC_FIRMWARE_COMMIT			= 0x10,
+	SPDK_NVME_OPC_FIRMWARE_IMAGE_DOWNLOAD		= 0x11,
 
-	NVME_OPC_NAMESPACE_ATTACHMENT		= 0x15,
+	SPDK_NVME_OPC_NS_ATTACHMENT			= 0x15,
 
-	NVME_OPC_FORMAT_NVM			= 0x80,
-	NVME_OPC_SECURITY_SEND			= 0x81,
-	NVME_OPC_SECURITY_RECEIVE		= 0x82,
+	SPDK_NVME_OPC_FORMAT_NVM			= 0x80,
+	SPDK_NVME_OPC_SECURITY_SEND			= 0x81,
+	SPDK_NVME_OPC_SECURITY_RECEIVE			= 0x82,
 };
 
-/* nvme nvm opcodes */
-enum nvme_nvm_opcode {
-	NVME_OPC_FLUSH				= 0x00,
-	NVME_OPC_WRITE				= 0x01,
-	NVME_OPC_READ				= 0x02,
+/**
+ * NVM command set opcodes
+ */
+enum spdk_nvme_nvm_opcode {
+	SPDK_NVME_OPC_FLUSH				= 0x00,
+	SPDK_NVME_OPC_WRITE				= 0x01,
+	SPDK_NVME_OPC_READ				= 0x02,
 	/* 0x03 - reserved */
-	NVME_OPC_WRITE_UNCORRECTABLE		= 0x04,
-	NVME_OPC_COMPARE			= 0x05,
+	SPDK_NVME_OPC_WRITE_UNCORRECTABLE		= 0x04,
+	SPDK_NVME_OPC_COMPARE				= 0x05,
 	/* 0x06-0x07 - reserved */
-	NVME_OPC_WRITE_ZEROES			= 0x08,
-	NVME_OPC_DATASET_MANAGEMENT		= 0x09,
+	SPDK_NVME_OPC_WRITE_ZEROES			= 0x08,
+	SPDK_NVME_OPC_DATASET_MANAGEMENT		= 0x09,
 
-	NVME_OPC_RESERVATION_REGISTER		= 0x0d,
-	NVME_OPC_RESERVATION_REPORT		= 0x0e,
+	SPDK_NVME_OPC_RESERVATION_REGISTER		= 0x0d,
+	SPDK_NVME_OPC_RESERVATION_REPORT		= 0x0e,
 
-	NVME_OPC_RESERVATION_ACQUIRE		= 0x11,
-	NVME_OPC_RESERVATION_RELEASE		= 0x15,
+	SPDK_NVME_OPC_RESERVATION_ACQUIRE		= 0x11,
+	SPDK_NVME_OPC_RESERVATION_RELEASE		= 0x15,
 };
 
-enum nvme_feature {
+enum spdk_nvme_feat {
 	/* 0x00 - reserved */
-	NVME_FEAT_ARBITRATION			= 0x01,
-	NVME_FEAT_POWER_MANAGEMENT		= 0x02,
-	NVME_FEAT_LBA_RANGE_TYPE		= 0x03,
-	NVME_FEAT_TEMPERATURE_THRESHOLD		= 0x04,
-	NVME_FEAT_ERROR_RECOVERY		= 0x05,
-	NVME_FEAT_VOLATILE_WRITE_CACHE		= 0x06,
-	NVME_FEAT_NUMBER_OF_QUEUES		= 0x07,
-	NVME_FEAT_INTERRUPT_COALESCING		= 0x08,
-	NVME_FEAT_INTERRUPT_VECTOR_CONFIGURATION = 0x09,
-	NVME_FEAT_WRITE_ATOMICITY		= 0x0A,
-	NVME_FEAT_ASYNC_EVENT_CONFIGURATION	= 0x0B,
-	NVME_FEAT_AUTONOMOUS_POWER_STATE_TRANSITION	= 0x0C,
-	NVME_FEAT_HOST_MEM_BUFFER		= 0x0D,
+	SPDK_NVME_FEAT_ARBITRATION				= 0x01,
+	SPDK_NVME_FEAT_POWER_MANAGEMENT				= 0x02,
+	SPDK_NVME_FEAT_LBA_RANGE_TYPE				= 0x03,
+	SPDK_NVME_FEAT_TEMPERATURE_THRESHOLD			= 0x04,
+	SPDK_NVME_FEAT_ERROR_RECOVERY				= 0x05,
+	SPDK_NVME_FEAT_VOLATILE_WRITE_CACHE			= 0x06,
+	SPDK_NVME_FEAT_NUMBER_OF_QUEUES				= 0x07,
+	SPDK_NVME_FEAT_INTERRUPT_COALESCING			= 0x08,
+	SPDK_NVME_FEAT_INTERRUPT_VECTOR_CONFIGURATION		= 0x09,
+	SPDK_NVME_FEAT_WRITE_ATOMICITY				= 0x0A,
+	SPDK_NVME_FEAT_ASYNC_EVENT_CONFIGURATION		= 0x0B,
+	SPDK_NVME_FEAT_AUTONOMOUS_POWER_STATE_TRANSITION	= 0x0C,
+	SPDK_NVME_FEAT_HOST_MEM_BUFFER				= 0x0D,
 	/* 0x0C-0x7F - reserved */
-	NVME_FEAT_SOFTWARE_PROGRESS_MARKER	= 0x80,
+	SPDK_NVME_FEAT_SOFTWARE_PROGRESS_MARKER			= 0x80,
 	/* 0x81-0xBF - command set specific */
-	NVME_FEAT_HOST_IDENTIFIER		= 0x81,
-	NVME_FEAT_HOST_RESERVE_MASK		= 0x82,
-	NVME_FEAT_HOST_RESERVE_PERSIST		= 0x83,
+	SPDK_NVME_FEAT_HOST_IDENTIFIER				= 0x81,
+	SPDK_NVME_FEAT_HOST_RESERVE_MASK			= 0x82,
+	SPDK_NVME_FEAT_HOST_RESERVE_PERSIST			= 0x83,
 	/* 0xC0-0xFF - vendor specific */
 };
 
-enum nvme_dsm_attribute {
-	NVME_DSM_ATTR_INTEGRAL_READ		= 0x1,
-	NVME_DSM_ATTR_INTEGRAL_WRITE		= 0x2,
-	NVME_DSM_ATTR_DEALLOCATE		= 0x4,
+enum spdk_nvme_dsm_attribute {
+	SPDK_NVME_DSM_ATTR_INTEGRAL_READ		= 0x1,
+	SPDK_NVME_DSM_ATTR_INTEGRAL_WRITE		= 0x2,
+	SPDK_NVME_DSM_ATTR_DEALLOCATE			= 0x4,
 };
 
-struct nvme_power_state {
+struct spdk_nvme_power_state {
 	uint16_t mp;				/* bits 15:00: maximum power */
 
 	uint8_t reserved1;
@@ -492,9 +563,9 @@ struct nvme_power_state {
 
 	uint8_t reserved7[16];
 };
-SPDK_STATIC_ASSERT(sizeof(struct nvme_power_state) == 32, "Incorrect size");
+SPDK_STATIC_ASSERT(sizeof(struct spdk_nvme_power_state) == 32, "Incorrect size");
 
-struct __attribute__((packed)) nvme_controller_data {
+struct __attribute__((packed)) spdk_nvme_ctrlr_data {
 	/* bytes 0-255: controller capabilities and features */
 
 	/** pci vendor id */
@@ -713,14 +784,14 @@ struct __attribute__((packed)) nvme_controller_data {
 	uint8_t			reserved5[1344];
 
 	/* bytes 2048-3071: power state descriptors */
-	struct nvme_power_state	psd[32];
+	struct spdk_nvme_power_state	psd[32];
 
 	/* bytes 3072-4095: vendor specific */
 	uint8_t			vs[1024];
 };
-SPDK_STATIC_ASSERT(sizeof(struct nvme_controller_data) == 4096, "Incorrect size");
+SPDK_STATIC_ASSERT(sizeof(struct spdk_nvme_ctrlr_data) == 4096, "Incorrect size");
 
-struct nvme_namespace_data {
+struct spdk_nvme_ns_data {
 	/** namespace size */
 	uint64_t		nsze;
 
@@ -877,53 +948,53 @@ struct nvme_namespace_data {
 
 	uint8_t			vendor_specific[3712];
 };
-SPDK_STATIC_ASSERT(sizeof(struct nvme_namespace_data) == 4096, "Incorrect size");
+SPDK_STATIC_ASSERT(sizeof(struct spdk_nvme_ns_data) == 4096, "Incorrect size");
 
 /**
  * Reservation Type Encoding
  */
-enum nvme_reservation_type {
+enum spdk_nvme_reservation_type {
 	/* 0x00 - reserved */
 
 	/* Write Exclusive Reservation */
-	NVME_RESERVE_WRITE_EXCLUSIVE	= 0x1,
+	SPDK_NVME_RESERVE_WRITE_EXCLUSIVE		= 0x1,
 
 	/* Exclusive Access Reservation */
-	NVME_RESERVE_EXCLUSIVE_ACCESS	= 0x2,
+	SPDK_NVME_RESERVE_EXCLUSIVE_ACCESS		= 0x2,
 
 	/* Write Exclusive - Registrants Only Reservation */
-	NVME_RESERVE_WRITE_EXCLUSIVE_REG_ONLY	= 0x3,
+	SPDK_NVME_RESERVE_WRITE_EXCLUSIVE_REG_ONLY	= 0x3,
 
 	/* Exclusive Access - Registrants Only Reservation */
-	NVME_RESERVE_EXCLUSIVE_ACCESS_REG_ONLY	= 0x4,
+	SPDK_NVME_RESERVE_EXCLUSIVE_ACCESS_REG_ONLY	= 0x4,
 
 	/* Write Exclusive - All Registrants Reservation */
-	NVME_RESERVE_WRITE_EXCLUSIVE_ALL_REGS	= 0x5,
+	SPDK_NVME_RESERVE_WRITE_EXCLUSIVE_ALL_REGS	= 0x5,
 
 	/* Exclusive Access - All Registrants Reservation */
-	NVME_RESERVE_EXCLUSIVE_ACCESS_ALL_REGS	= 0x6,
+	SPDK_NVME_RESERVE_EXCLUSIVE_ACCESS_ALL_REGS	= 0x6,
 
 	/* 0x7-0xFF - Reserved */
 };
 
-struct nvme_reservation_acquire_data {
+struct spdk_nvme_reservation_acquire_data {
 	/** current reservation key */
 	uint64_t		crkey;
 	/** preempt reservation key */
 	uint64_t		prkey;
 };
-SPDK_STATIC_ASSERT(sizeof(struct nvme_reservation_acquire_data) == 16, "Incorrect size");
+SPDK_STATIC_ASSERT(sizeof(struct spdk_nvme_reservation_acquire_data) == 16, "Incorrect size");
 
 /**
  * Reservation Acquire action
  */
-enum nvme_reservation_acquire_action {
-	NVME_RESERVE_ACQUIRE		= 0x0,
-	NVME_RESERVE_PREEMPT		= 0x1,
-	NVME_RESERVE_PREEMPT_ABORT	= 0x2,
+enum spdk_nvme_reservation_acquire_action {
+	SPDK_NVME_RESERVE_ACQUIRE		= 0x0,
+	SPDK_NVME_RESERVE_PREEMPT		= 0x1,
+	SPDK_NVME_RESERVE_PREEMPT_ABORT		= 0x2,
 };
 
-struct __attribute__((packed)) nvme_reservation_status_data {
+struct __attribute__((packed)) spdk_nvme_reservation_status_data {
 	/** reservation action generation counter */
 	uint32_t		generation;
 	/** reservation type */
@@ -935,9 +1006,9 @@ struct __attribute__((packed)) nvme_reservation_status_data {
 	uint8_t			ptpl_state;
 	uint8_t			reserved[14];
 };
-SPDK_STATIC_ASSERT(sizeof(struct nvme_reservation_status_data) == 24, "Incorrect size");
+SPDK_STATIC_ASSERT(sizeof(struct spdk_nvme_reservation_status_data) == 24, "Incorrect size");
 
-struct __attribute__((packed)) nvme_reservation_controller_data {
+struct __attribute__((packed)) spdk_nvme_reservation_ctrlr_data {
 	uint16_t		ctrlr_id;
 	/** reservation status */
 	struct {
@@ -950,74 +1021,74 @@ struct __attribute__((packed)) nvme_reservation_controller_data {
 	/** reservation key */
 	uint64_t		key;
 };
-SPDK_STATIC_ASSERT(sizeof(struct nvme_reservation_controller_data) == 24, "Incorrect size");
+SPDK_STATIC_ASSERT(sizeof(struct spdk_nvme_reservation_ctrlr_data) == 24, "Incorrect size");
 
 /**
  * Change persist through power loss state for
  *  Reservation Register command
  */
-enum nvme_reservation_register_cptpl {
-	NVME_RESERVE_PTPL_NO_CHANGES		= 0x0,
-	NVME_RESERVE_PTPL_CLEAR_POWER_ON	= 0x2,
-	NVME_RESERVE_PTPL_PERSIST_POWER_LOSS	= 0x3,
+enum spdk_nvme_reservation_register_cptpl {
+	SPDK_NVME_RESERVE_PTPL_NO_CHANGES		= 0x0,
+	SPDK_NVME_RESERVE_PTPL_CLEAR_POWER_ON		= 0x2,
+	SPDK_NVME_RESERVE_PTPL_PERSIST_POWER_LOSS	= 0x3,
 };
 
 /**
  * Registration action for Reservation Register command
  */
-enum nvme_reservation_register_action {
-	NVME_RESERVE_REGISTER_KEY	= 0x0,
-	NVME_RESERVE_UNREGISTER_KEY	= 0x1,
-	NVME_RESERVE_REPLACE_KEY	= 0x2,
+enum spdk_nvme_reservation_register_action {
+	SPDK_NVME_RESERVE_REGISTER_KEY		= 0x0,
+	SPDK_NVME_RESERVE_UNREGISTER_KEY	= 0x1,
+	SPDK_NVME_RESERVE_REPLACE_KEY		= 0x2,
 };
 
-struct nvme_reservation_register_data {
+struct spdk_nvme_reservation_register_data {
 	/** current reservation key */
 	uint64_t		crkey;
 	/** new reservation key */
 	uint64_t		nrkey;
 };
-SPDK_STATIC_ASSERT(sizeof(struct nvme_reservation_register_data) == 16, "Incorrect size");
+SPDK_STATIC_ASSERT(sizeof(struct spdk_nvme_reservation_register_data) == 16, "Incorrect size");
 
-struct nvme_reservation_key_data {
+struct spdk_nvme_reservation_key_data {
 	/** current reservation key */
 	uint64_t		crkey;
 };
-SPDK_STATIC_ASSERT(sizeof(struct nvme_reservation_key_data) == 8, "Incorrect size");
+SPDK_STATIC_ASSERT(sizeof(struct spdk_nvme_reservation_key_data) == 8, "Incorrect size");
 
 /**
  * Reservation Release action
  */
-enum nvme_reservation_release_action {
-	NVME_RESERVE_RELEASE		= 0x0,
-	NVME_RESERVE_CLEAR		= 0x1,
+enum spdk_nvme_reservation_release_action {
+	SPDK_NVME_RESERVE_RELEASE		= 0x0,
+	SPDK_NVME_RESERVE_CLEAR			= 0x1,
 };
 
 /**
- * Log page identifiers for NVME_OPC_GET_LOG_PAGE
+ * Log page identifiers for SPDK_NVME_OPC_GET_LOG_PAGE
  */
-enum nvme_log_page {
+enum spdk_nvme_log_page {
 	/* 0x00 - reserved */
 
-	/** Error information (mandatory) - \ref nvme_error_information_entry */
-	NVME_LOG_ERROR			= 0x01,
+	/** Error information (mandatory) - \ref spdk_nvme_error_information_entry */
+	SPDK_NVME_LOG_ERROR			= 0x01,
 
-	/** SMART / health information (mandatory) - \ref nvme_health_information_page */
-	NVME_LOG_HEALTH_INFORMATION	= 0x02,
+	/** SMART / health information (mandatory) - \ref spdk_nvme_health_information_page */
+	SPDK_NVME_LOG_HEALTH_INFORMATION	= 0x02,
 
-	/** Firmware slot information (mandatory) - \ref nvme_firmware_page */
-	NVME_LOG_FIRMWARE_SLOT		= 0x03,
+	/** Firmware slot information (mandatory) - \ref spdk_nvme_firmware_page */
+	SPDK_NVME_LOG_FIRMWARE_SLOT		= 0x03,
 
 	/** Changed namespace list (optional) */
-	NVME_LOG_CHANGED_NS_LIST	= 0x04,
+	SPDK_NVME_LOG_CHANGED_NS_LIST	= 0x04,
 
 	/** Command effects log (optional) */
-	NVME_LOG_COMMAND_EFFECTS_LOG	= 0x05,
+	SPDK_NVME_LOG_COMMAND_EFFECTS_LOG	= 0x05,
 
 	/* 0x06-0x7F - reserved */
 
 	/** Reservation notification (optional) */
-	NVME_LOG_RESERVATION_NOTIFICATION	= 0x80,
+	SPDK_NVME_LOG_RESERVATION_NOTIFICATION	= 0x80,
 
 	/* 0x81-0xBF - I/O command set specific */
 
@@ -1025,22 +1096,22 @@ enum nvme_log_page {
 };
 
 /**
- * Error information log page (\ref NVME_LOG_ERROR)
+ * Error information log page (\ref SPDK_NVME_LOG_ERROR)
  */
-struct nvme_error_information_entry {
+struct spdk_nvme_error_information_entry {
 	uint64_t		error_count;
 	uint16_t		sqid;
 	uint16_t		cid;
-	struct nvme_status	status;
+	struct spdk_nvme_status	status;
 	uint16_t		error_location;
 	uint64_t		lba;
 	uint32_t		nsid;
 	uint8_t			vendor_specific;
 	uint8_t			reserved[35];
 };
-SPDK_STATIC_ASSERT(sizeof(struct nvme_error_information_entry) == 64, "Incorrect size");
+SPDK_STATIC_ASSERT(sizeof(struct spdk_nvme_error_information_entry) == 64, "Incorrect size");
 
-union nvme_critical_warning_state {
+union spdk_nvme_critical_warning_state {
 	uint8_t		raw;
 
 	struct {
@@ -1052,13 +1123,13 @@ union nvme_critical_warning_state {
 		uint8_t	reserved		: 3;
 	} bits;
 };
-SPDK_STATIC_ASSERT(sizeof(union nvme_critical_warning_state) == 1, "Incorrect size");
+SPDK_STATIC_ASSERT(sizeof(union spdk_nvme_critical_warning_state) == 1, "Incorrect size");
 
 /**
- * SMART / health information page (\ref NVME_LOG_HEALTH_INFORMATION)
+ * SMART / health information page (\ref SPDK_NVME_LOG_HEALTH_INFORMATION)
  */
-struct __attribute__((packed)) nvme_health_information_page {
-	union nvme_critical_warning_state	critical_warning;
+struct __attribute__((packed)) spdk_nvme_health_information_page {
+	union spdk_nvme_critical_warning_state	critical_warning;
 
 	uint16_t		temperature;
 	uint8_t			available_spare;
@@ -1088,12 +1159,12 @@ struct __attribute__((packed)) nvme_health_information_page {
 
 	uint8_t			reserved2[320];
 };
-SPDK_STATIC_ASSERT(sizeof(struct nvme_health_information_page) == 512, "Incorrect size");
+SPDK_STATIC_ASSERT(sizeof(struct spdk_nvme_health_information_page) == 512, "Incorrect size");
 
 /**
- * Firmware slot information page (\ref NVME_LOG_FIRMWARE_SLOT)
+ * Firmware slot information page (\ref SPDK_NVME_LOG_FIRMWARE_SLOT)
  */
-struct nvme_firmware_page {
+struct spdk_nvme_firmware_page {
 	struct {
 		uint8_t	slot		: 3; /* slot for current FW */
 		uint8_t	reserved	: 5;
@@ -1103,12 +1174,42 @@ struct nvme_firmware_page {
 	uint64_t		revision[7]; /* revisions for 7 slots */
 	uint8_t			reserved2[448];
 };
-SPDK_STATIC_ASSERT(sizeof(struct nvme_firmware_page) == 512, "Incorrect size");
+SPDK_STATIC_ASSERT(sizeof(struct spdk_nvme_firmware_page) == 512, "Incorrect size");
+
+/**
+ * Namespace attachment Type Encoding
+ */
+enum spdk_nvme_ns_attach_type {
+	/* Controller attach */
+	SPDK_NVME_NS_CTRLR_ATTACH	= 0x0,
+
+	/* Controller detach */
+	SPDK_NVME_NS_CTRLR_DETACH	= 0x1,
+
+	/* 0x2-0xF - Reserved */
+};
 
-#define nvme_completion_is_error(cpl)					\
+/**
+ * Namespace management Type Encoding
+ */
+enum spdk_nvme_ns_management_type {
+	/* Create */
+	SPDK_NVME_NS_MANAGEMENT_CREATE	= 0x0,
+
+	/* Delete */
+	SPDK_NVME_NS_MANAGEMENT_DELETE	= 0x1,
+
+	/* 0x2-0xF - Reserved */
+};
+
+#define spdk_nvme_cpl_is_error(cpl)					\
 	((cpl)->status.sc != 0 || (cpl)->status.sct != 0)
 
-#define NVME_IO_FLAGS_FORCE_UNIT_ACCESS (1U << 30)
-#define NVME_IO_FLAGS_LIMITED_RETRY (1U << 31)
+#define SPDK_NVME_IO_FLAGS_FORCE_UNIT_ACCESS (1U << 30)
+#define SPDK_NVME_IO_FLAGS_LIMITED_RETRY (1U << 31)
+
+#ifdef __cplusplus
+}
+#endif
 
 #endif
diff --git a/src/spdk/include/spdk/pci.h b/src/spdk/include/spdk/pci.h
index 13401d9..7d71e79 100644
--- a/src/spdk/include/spdk/pci.h
+++ b/src/spdk/include/spdk/pci.h
@@ -34,22 +34,45 @@
 #ifndef SPDK_PCI_H
 #define SPDK_PCI_H
 
-#define spdk_pci_device_get_domain(dev)	(dev->domain)
-#define spdk_pci_device_get_bus(dev)	(dev->bus)
-#define spdk_pci_device_get_dev(dev)	(dev->dev)
-#define spdk_pci_device_get_func(dev)	(dev->func)
-#define spdk_pci_device_get_vendor_id(dev) (dev->vendor_id)
-#define spdk_pci_device_get_device_id(dev) (dev->device_id)
-
-#define PCI_CFG_SIZE		256
-#define PCI_EXT_CAP_ID_SN	0x03
-#define PCI_UIO_DRIVER		"uio_pci_generic"
-
-int pci_device_get_serial_number(struct pci_device *dev, char *sn, int len);
-int pci_device_has_non_uio_driver(struct pci_device *dev);
-int pci_device_unbind_kernel_driver(struct pci_device *dev);
-int pci_device_bind_uio_driver(struct pci_device *dev, char *driver_name);
-int pci_device_switch_to_uio_driver(struct pci_device *pci_dev);
-int pci_device_claim(struct pci_device *dev);
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <inttypes.h>
+#include <stddef.h>
+
+struct spdk_pci_device;
+
+int spdk_pci_enumerate(int (*enum_cb)(void *enum_ctx, struct spdk_pci_device *pci_dev),
+		       void *enum_ctx);
+
+uint16_t spdk_pci_device_get_domain(struct spdk_pci_device *dev);
+uint8_t spdk_pci_device_get_bus(struct spdk_pci_device *dev);
+uint8_t spdk_pci_device_get_dev(struct spdk_pci_device *dev);
+uint8_t spdk_pci_device_get_func(struct spdk_pci_device *dev);
+uint16_t spdk_pci_device_get_vendor_id(struct spdk_pci_device *dev);
+uint16_t spdk_pci_device_get_device_id(struct spdk_pci_device *dev);
+uint16_t spdk_pci_device_get_subvendor_id(struct spdk_pci_device *dev);
+uint16_t spdk_pci_device_get_subdevice_id(struct spdk_pci_device *dev);
+uint32_t spdk_pci_device_get_class(struct spdk_pci_device *dev);
+const char *spdk_pci_device_get_device_name(struct spdk_pci_device *dev);
+
+int spdk_pci_device_cfg_read8(struct spdk_pci_device *dev, uint8_t *value, uint32_t offset);
+int spdk_pci_device_cfg_write8(struct spdk_pci_device *dev, uint8_t value, uint32_t offset);
+int spdk_pci_device_cfg_read16(struct spdk_pci_device *dev, uint16_t *value, uint32_t offset);
+int spdk_pci_device_cfg_write16(struct spdk_pci_device *dev, uint16_t value, uint32_t offset);
+int spdk_pci_device_cfg_read32(struct spdk_pci_device *dev, uint32_t *value, uint32_t offset);
+int spdk_pci_device_cfg_write32(struct spdk_pci_device *dev, uint32_t value, uint32_t offset);
+
+int spdk_pci_device_get_serial_number(struct spdk_pci_device *dev, char *sn, size_t len);
+int spdk_pci_device_has_non_uio_driver(struct spdk_pci_device *dev);
+int spdk_pci_device_unbind_kernel_driver(struct spdk_pci_device *dev);
+int spdk_pci_device_bind_uio_driver(struct spdk_pci_device *dev);
+int spdk_pci_device_switch_to_uio_driver(struct spdk_pci_device *pci_dev);
+int spdk_pci_device_claim(struct spdk_pci_device *dev);
+
+#ifdef __cplusplus
+}
+#endif
 
 #endif
diff --git a/src/spdk/include/spdk/pci_ids.h b/src/spdk/include/spdk/pci_ids.h
index ab377fe..84edc5e 100644
--- a/src/spdk/include/spdk/pci_ids.h
+++ b/src/spdk/include/spdk/pci_ids.h
@@ -31,9 +31,28 @@
  *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-#ifndef __PCI_IDS_H__
-#define __PCI_IDS_H__
+#ifndef SPDK_PCI_IDS
+#define SPDK_PCI_IDS
 
-#define PCI_VENDOR_ID_INTEL	0x8086
+#ifdef __cplusplus
+extern "C" {
+#endif
 
-#endif /* __PCI_IDS_H__ */
+#include <stdint.h>
+
+#define SPDK_PCI_VID_INTEL		0x8086
+
+/**
+ * PCI class code for NVMe devices.
+ *
+ * Base class code 01h: mass storage
+ * Subclass code 08h: non-volatile memory
+ * Programming interface 02h: NVM Express
+ */
+#define SPDK_PCI_CLASS_NVME		0x010802
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* SPDK_PCI_IDS */
diff --git a/src/spdk/include/spdk/queue.h b/src/spdk/include/spdk/queue.h
index 2b27f55..d3d8615 100644
--- a/src/spdk/include/spdk/queue.h
+++ b/src/spdk/include/spdk/queue.h
@@ -34,6 +34,10 @@
 #ifndef SPDK_QUEUE_H
 #define SPDK_QUEUE_H
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 #include <sys/cdefs.h>
 #include <sys/queue.h>
 
@@ -46,4 +50,8 @@
 #include <spdk/queue_extras.h>
 #endif
 
+#ifdef __cplusplus
+}
+#endif
+
 #endif
diff --git a/src/spdk/include/spdk/string.h b/src/spdk/include/spdk/string.h
index d7e1226..f6261dc 100644
--- a/src/spdk/include/spdk/string.h
+++ b/src/spdk/include/spdk/string.h
@@ -34,6 +34,10 @@
 #ifndef SPDK_STRING_H
 #define SPDK_STRING_H
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 /**
  * sprintf with automatic buffer allocation.
  *
@@ -41,6 +45,10 @@
  * which should be passed to free() when no longer needed,
  * or NULL on failure.
  */
-char *sprintf_alloc(const char *format, ...) __attribute__((format(printf, 1, 2)));
+char *spdk_sprintf_alloc(const char *format, ...) __attribute__((format(printf, 1, 2)));
+
+#ifdef __cplusplus
+}
+#endif
 
 #endif
diff --git a/src/spdk/include/spdk/vtophys.h b/src/spdk/include/spdk/vtophys.h
index 4d6d57e..146d800 100644
--- a/src/spdk/include/spdk/vtophys.h
+++ b/src/spdk/include/spdk/vtophys.h
@@ -34,15 +34,15 @@
 #ifndef SPDK_VTOPHYS_H
 #define SPDK_VTOPHYS_H
 
-#include <stdint.h>
-
 #ifdef __cplusplus
 extern "C" {
 #endif
 
-#define VTOPHYS_ERROR	(0xFFFFFFFFFFFFFFFFULL)
+#include <stdint.h>
+
+#define SPDK_VTOPHYS_ERROR	(0xFFFFFFFFFFFFFFFFULL)
 
-uint64_t vtophys(void *buf);
+uint64_t spdk_vtophys(void *buf);
 
 #ifdef __cplusplus
 }
diff --git a/src/spdk/lib/ioat/ioat.c b/src/spdk/lib/ioat/ioat.c
index b90c90e..bbbf819 100644
--- a/src/spdk/lib/ioat/ioat.c
+++ b/src/spdk/lib/ioat/ioat.c
@@ -38,125 +38,62 @@
  *
  * Must hold g_ioat_driver.lock while manipulating this list.
  */
-static SLIST_HEAD(, ioat_channel) ioat_free_channels;
+static SLIST_HEAD(, spdk_ioat_chan) ioat_free_channels;
 
 /** IOAT channel assigned to this thread (or NULL if not assigned yet). */
-static __thread struct ioat_channel *ioat_thread_channel;
+static __thread struct spdk_ioat_chan *ioat_thread_channel;
 
 struct ioat_driver {
 	ioat_mutex_t	lock;
+	TAILQ_HEAD(, spdk_ioat_chan)	attached_chans;
 };
 
 static struct ioat_driver g_ioat_driver = {
 	.lock = IOAT_MUTEX_INITIALIZER,
+	.attached_chans = TAILQ_HEAD_INITIALIZER(g_ioat_driver.attached_chans),
 };
 
-struct pci_device_id {
-	uint16_t vendor;
-	uint16_t device;
-};
-
-static const struct pci_device_id ioat_pci_table[] = {
-	{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IOAT_SNB0},
-	{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IOAT_SNB1},
-	{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IOAT_SNB2},
-	{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IOAT_SNB3},
-	{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IOAT_SNB4},
-	{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IOAT_SNB5},
-	{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IOAT_SNB6},
-	{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IOAT_SNB7},
-	{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IOAT_IVB0},
-	{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IOAT_IVB1},
-	{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IOAT_IVB2},
-	{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IOAT_IVB3},
-	{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IOAT_IVB4},
-	{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IOAT_IVB5},
-	{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IOAT_IVB6},
-	{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IOAT_IVB7},
-	{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IOAT_HSW0},
-	{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IOAT_HSW1},
-	{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IOAT_HSW2},
-	{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IOAT_HSW3},
-	{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IOAT_HSW4},
-	{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IOAT_HSW5},
-	{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IOAT_HSW6},
-	{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IOAT_HSW7},
-	{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IOAT_BDX0},
-	{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IOAT_BDX1},
-	{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IOAT_BDX2},
-	{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IOAT_BDX3},
-	{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IOAT_BDX4},
-	{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IOAT_BDX5},
-	{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IOAT_BDX6},
-	{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IOAT_BDX7},
-	{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IOAT_BDX8},
-	{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IOAT_BDX9},
-	{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IOAT_BWD0},
-	{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IOAT_BWD1},
-	{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IOAT_BWD2},
-	{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IOAT_BWD3},
-	{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IOAT_BDXDE0},
-	{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IOAT_BDXDE1},
-	{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IOAT_BDXDE2},
-	{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IOAT_BDXDE3},
-};
-
-bool
-ioat_pci_device_match_id(uint16_t vendor_id, uint16_t device_id)
-{
-	size_t i;
-	const struct pci_device_id *ids;
-
-	for (i = 0; i < sizeof(ioat_pci_table) / sizeof(struct pci_device_id); i++) {
-		ids = &ioat_pci_table[i];
-		if (ids->device == device_id && ids->vendor == vendor_id) {
-			return true;
-		}
-	}
-	return false;
-}
-
 static uint64_t
-ioat_get_chansts(struct ioat_channel *ioat)
+ioat_get_chansts(struct spdk_ioat_chan *ioat)
 {
 	return spdk_mmio_read_8(&ioat->regs->chansts);
 }
 
 static void
-ioat_write_chancmp(struct ioat_channel *ioat, uint64_t addr)
+ioat_write_chancmp(struct spdk_ioat_chan *ioat, uint64_t addr)
 {
 	spdk_mmio_write_8(&ioat->regs->chancmp, addr);
 }
 
 static void
-ioat_write_chainaddr(struct ioat_channel *ioat, uint64_t addr)
+ioat_write_chainaddr(struct spdk_ioat_chan *ioat, uint64_t addr)
 {
 	spdk_mmio_write_8(&ioat->regs->chainaddr, addr);
 }
 
 static inline void
-ioat_suspend(struct ioat_channel *ioat)
+ioat_suspend(struct spdk_ioat_chan *ioat)
 {
-	ioat->regs->chancmd = IOAT_CHANCMD_SUSPEND;
+	ioat->regs->chancmd = SPDK_IOAT_CHANCMD_SUSPEND;
 }
 
 static inline void
-ioat_reset(struct ioat_channel *ioat)
+ioat_reset(struct spdk_ioat_chan *ioat)
 {
-	ioat->regs->chancmd = IOAT_CHANCMD_RESET;
+	ioat->regs->chancmd = SPDK_IOAT_CHANCMD_RESET;
 }
 
 static inline uint32_t
-ioat_reset_pending(struct ioat_channel *ioat)
+ioat_reset_pending(struct spdk_ioat_chan *ioat)
 {
 	uint8_t cmd;
 
 	cmd = ioat->regs->chancmd;
-	return (cmd & IOAT_CHANCMD_RESET) == IOAT_CHANCMD_RESET;
+	return (cmd & SPDK_IOAT_CHANCMD_RESET) == SPDK_IOAT_CHANCMD_RESET;
 }
 
 static int
-ioat_map_pci_bar(struct ioat_channel *ioat)
+ioat_map_pci_bar(struct spdk_ioat_chan *ioat)
 {
 	int regs_bar, rc;
 	void *addr;
@@ -169,13 +106,13 @@ ioat_map_pci_bar(struct ioat_channel *ioat)
 		return -1;
 	}
 
-	ioat->regs = (volatile struct ioat_registers *)addr;
+	ioat->regs = (volatile struct spdk_ioat_registers *)addr;
 
 	return 0;
 }
 
 static int
-ioat_unmap_pci_bar(struct ioat_channel *ioat)
+ioat_unmap_pci_bar(struct spdk_ioat_chan *ioat)
 {
 	int rc = 0;
 	void *addr = (void *)ioat->regs;
@@ -188,27 +125,27 @@ ioat_unmap_pci_bar(struct ioat_channel *ioat)
 
 
 static inline uint32_t
-ioat_get_active(struct ioat_channel *ioat)
+ioat_get_active(struct spdk_ioat_chan *ioat)
 {
 	return (ioat->head - ioat->tail) & ((1 << ioat->ring_size_order) - 1);
 }
 
 static inline uint32_t
-ioat_get_ring_space(struct ioat_channel *ioat)
+ioat_get_ring_space(struct spdk_ioat_chan *ioat)
 {
 	return (1 << ioat->ring_size_order) - ioat_get_active(ioat) - 1;
 }
 
 static uint32_t
-ioat_get_ring_index(struct ioat_channel *ioat, uint32_t index)
+ioat_get_ring_index(struct spdk_ioat_chan *ioat, uint32_t index)
 {
 	return index & ((1 << ioat->ring_size_order) - 1);
 }
 
 static void
-ioat_get_ring_entry(struct ioat_channel *ioat, uint32_t index,
+ioat_get_ring_entry(struct spdk_ioat_chan *ioat, uint32_t index,
 		    struct ioat_descriptor **desc,
-		    union ioat_hw_descriptor **hw_desc)
+		    union spdk_ioat_hw_desc **hw_desc)
 {
 	uint32_t i = ioat_get_ring_index(ioat, index);
 
@@ -217,29 +154,29 @@ ioat_get_ring_entry(struct ioat_channel *ioat, uint32_t index,
 }
 
 static uint64_t
-ioat_get_desc_phys_addr(struct ioat_channel *ioat, uint32_t index)
+ioat_get_desc_phys_addr(struct spdk_ioat_chan *ioat, uint32_t index)
 {
 	return ioat->hw_ring_phys_addr +
-	       ioat_get_ring_index(ioat, index) * sizeof(union ioat_hw_descriptor);
+	       ioat_get_ring_index(ioat, index) * sizeof(union spdk_ioat_hw_desc);
 }
 
 static void
-ioat_submit_single(struct ioat_channel *ioat)
+ioat_submit_single(struct spdk_ioat_chan *ioat)
 {
 	ioat->head++;
 }
 
 static void
-ioat_flush(struct ioat_channel *ioat)
+ioat_flush(struct spdk_ioat_chan *ioat)
 {
 	ioat->regs->dmacount = (uint16_t)ioat->head;
 }
 
 static struct ioat_descriptor *
-ioat_prep_null(struct ioat_channel *ioat)
+ioat_prep_null(struct spdk_ioat_chan *ioat)
 {
 	struct ioat_descriptor *desc;
-	union ioat_hw_descriptor *hw_desc;
+	union spdk_ioat_hw_desc *hw_desc;
 
 	if (ioat_get_ring_space(ioat) < 1) {
 		return NULL;
@@ -248,7 +185,7 @@ ioat_prep_null(struct ioat_channel *ioat)
 	ioat_get_ring_entry(ioat, ioat->head, &desc, &hw_desc);
 
 	hw_desc->dma.u.control_raw = 0;
-	hw_desc->dma.u.control.op = IOAT_OP_COPY;
+	hw_desc->dma.u.control.op = SPDK_IOAT_OP_COPY;
 	hw_desc->dma.u.control.null = 1;
 	hw_desc->dma.u.control.completion_update = 1;
 
@@ -265,11 +202,11 @@ ioat_prep_null(struct ioat_channel *ioat)
 }
 
 static struct ioat_descriptor *
-ioat_prep_copy(struct ioat_channel *ioat, uint64_t dst,
+ioat_prep_copy(struct spdk_ioat_chan *ioat, uint64_t dst,
 	       uint64_t src, uint32_t len)
 {
 	struct ioat_descriptor *desc;
-	union ioat_hw_descriptor *hw_desc;
+	union spdk_ioat_hw_desc *hw_desc;
 
 	ioat_assert(len <= ioat->max_xfer_size);
 
@@ -280,7 +217,7 @@ ioat_prep_copy(struct ioat_channel *ioat, uint64_t dst,
 	ioat_get_ring_entry(ioat, ioat->head, &desc, &hw_desc);
 
 	hw_desc->dma.u.control_raw = 0;
-	hw_desc->dma.u.control.op = IOAT_OP_COPY;
+	hw_desc->dma.u.control.op = SPDK_IOAT_OP_COPY;
 	hw_desc->dma.u.control.completion_update = 1;
 
 	hw_desc->dma.size = len;
@@ -295,7 +232,38 @@ ioat_prep_copy(struct ioat_channel *ioat, uint64_t dst,
 	return desc;
 }
 
-static int ioat_reset_hw(struct ioat_channel *ioat)
+static struct ioat_descriptor *
+ioat_prep_fill(struct spdk_ioat_chan *ioat, uint64_t dst,
+	       uint64_t fill_pattern, uint32_t len)
+{
+	struct ioat_descriptor *desc;
+	union spdk_ioat_hw_desc *hw_desc;
+
+	ioat_assert(len <= ioat->max_xfer_size);
+
+	if (ioat_get_ring_space(ioat) < 1) {
+		return NULL;
+	}
+
+	ioat_get_ring_entry(ioat, ioat->head, &desc, &hw_desc);
+
+	hw_desc->fill.u.control_raw = 0;
+	hw_desc->fill.u.control.op = SPDK_IOAT_OP_FILL;
+	hw_desc->fill.u.control.completion_update = 1;
+
+	hw_desc->fill.size = len;
+	hw_desc->fill.src_data = fill_pattern;
+	hw_desc->fill.dest_addr = dst;
+
+	desc->callback_fn = NULL;
+	desc->callback_arg = NULL;
+
+	ioat_submit_single(ioat);
+
+	return desc;
+}
+
+static int ioat_reset_hw(struct spdk_ioat_chan *ioat)
 {
 	int timeout;
 	uint64_t status;
@@ -340,7 +308,7 @@ static int ioat_reset_hw(struct ioat_channel *ioat)
 }
 
 static int
-ioat_process_channel_events(struct ioat_channel *ioat)
+ioat_process_channel_events(struct spdk_ioat_chan *ioat)
 {
 	struct ioat_descriptor *desc;
 	uint64_t status, completed_descriptor, hw_desc_phys_addr;
@@ -351,7 +319,7 @@ ioat_process_channel_events(struct ioat_channel *ioat)
 	}
 
 	status = *ioat->comp_update;
-	completed_descriptor = status & IOAT_CHANSTS_COMPLETED_DESCRIPTOR_MASK;
+	completed_descriptor = status & SPDK_IOAT_CHANSTS_COMPLETED_DESCRIPTOR_MASK;
 
 	if (is_ioat_halted(status)) {
 		ioat_printf(ioat, "%s: Channel halted (%x)\n", __func__, ioat->regs->chanerr);
@@ -379,7 +347,7 @@ ioat_process_channel_events(struct ioat_channel *ioat)
 }
 
 static int
-ioat_channel_destruct(struct ioat_channel *ioat)
+ioat_channel_destruct(struct spdk_ioat_chan *ioat)
 {
 	ioat_unmap_pci_bar(ioat);
 
@@ -400,7 +368,7 @@ ioat_channel_destruct(struct ioat_channel *ioat)
 }
 
 static int
-ioat_channel_start(struct ioat_channel *ioat)
+ioat_channel_start(struct spdk_ioat_chan *ioat)
 {
 	uint8_t xfercap, version;
 	uint64_t status;
@@ -413,12 +381,16 @@ ioat_channel_start(struct ioat_channel *ioat)
 	}
 
 	version = ioat->regs->cbver;
-	if (version < IOAT_VER_3_0) {
+	if (version < SPDK_IOAT_VER_3_0) {
 		ioat_printf(ioat, "%s: unsupported IOAT version %u.%u\n",
 			    __func__, version >> 4, version & 0xF);
 		return -1;
 	}
 
+	/* Always support DMA copy */
+	ioat->dma_capabilities = SPDK_IOAT_ENGINE_COPY_SUPPORTED;
+	if (ioat->regs->dmacapability & SPDK_IOAT_DMACAP_BFILL)
+		ioat->dma_capabilities |= SPDK_IOAT_ENGINE_FILL_SUPPORTED;
 	xfercap = ioat->regs->xfercap;
 
 	/* Only bits [4:0] are valid. */
@@ -434,7 +406,7 @@ ioat_channel_start(struct ioat_channel *ioat)
 		ioat->max_xfer_size = 1U << xfercap;
 	}
 
-	ioat->comp_update = ioat_zmalloc(NULL, sizeof(*ioat->comp_update), IOAT_CHANCMP_ALIGN,
+	ioat->comp_update = ioat_zmalloc(NULL, sizeof(*ioat->comp_update), SPDK_IOAT_CHANCMP_ALIGN,
 					 &comp_update_bus_addr);
 	if (ioat->comp_update == NULL) {
 		return -1;
@@ -449,7 +421,7 @@ ioat_channel_start(struct ioat_channel *ioat)
 		return -1;
 	}
 
-	ioat->hw_ring = ioat_zmalloc(NULL, num_descriptors * sizeof(union ioat_hw_descriptor), 64,
+	ioat->hw_ring = ioat_zmalloc(NULL, num_descriptors * sizeof(union spdk_ioat_hw_desc), 64,
 				     &ioat->hw_ring_phys_addr);
 	if (!ioat->hw_ring) {
 		return -1;
@@ -465,7 +437,7 @@ ioat_channel_start(struct ioat_channel *ioat)
 
 	ioat_reset_hw(ioat);
 
-	ioat->regs->chanctrl = IOAT_CHANCTRL_ANY_ERR_ABORT_EN;
+	ioat->regs->chanctrl = SPDK_IOAT_CHANCTRL_ANY_ERR_ABORT_EN;
 	ioat_write_chancmp(ioat, comp_update_bus_addr);
 	ioat_write_chainaddr(ioat, ioat->hw_ring_phys_addr);
 
@@ -491,14 +463,14 @@ ioat_channel_start(struct ioat_channel *ioat)
 	return 0;
 }
 
-struct ioat_channel *
+/* Caller must hold g_ioat_driver.lock */
+static struct spdk_ioat_chan *
 ioat_attach(void *device)
 {
-	struct ioat_driver	*driver = &g_ioat_driver;
-	struct ioat_channel 	*ioat;
+	struct spdk_ioat_chan 	*ioat;
 	uint32_t cmd_reg;
 
-	ioat = calloc(1, sizeof(struct ioat_channel));
+	ioat = calloc(1, sizeof(struct spdk_ioat_chan));
 	if (ioat == NULL) {
 		return NULL;
 	}
@@ -516,15 +488,76 @@ ioat_attach(void *device)
 		return NULL;
 	}
 
-	ioat_mutex_lock(&driver->lock);
 	SLIST_INSERT_HEAD(&ioat_free_channels, ioat, next);
-	ioat_mutex_unlock(&driver->lock);
 
 	return ioat;
 }
 
+struct ioat_enum_ctx {
+	spdk_ioat_probe_cb probe_cb;
+	spdk_ioat_attach_cb attach_cb;
+	void *cb_ctx;
+};
+
+/* This function must only be called while holding g_ioat_driver.lock */
+static int
+ioat_enum_cb(void *ctx, struct spdk_pci_device *pci_dev)
+{
+	struct ioat_enum_ctx *enum_ctx = ctx;
+	struct spdk_ioat_chan *ioat;
+
+	/* Verify that this device is not already attached */
+	TAILQ_FOREACH(ioat, &g_ioat_driver.attached_chans, tailq) {
+		/*
+		 * NOTE: This assumes that the PCI abstraction layer will use the same device handle
+		 *  across enumerations; we could compare by BDF instead if this is not true.
+		 */
+		if (pci_dev == ioat->device) {
+			return 0;
+		}
+	}
+
+	if (enum_ctx->probe_cb(enum_ctx->cb_ctx, pci_dev)) {
+		/*
+		 * Since I/OAT init is relatively quick, just perform the full init during probing.
+		 *  If this turns out to be a bottleneck later, this can be changed to work like
+		 *  NVMe with a list of devices to initialize in parallel.
+		 */
+		ioat = ioat_attach(pci_dev);
+		if (ioat == NULL) {
+			ioat_printf(NULL, "ioat_attach() failed\n");
+			return -1;
+		}
+
+		TAILQ_INSERT_TAIL(&g_ioat_driver.attached_chans, ioat, tailq);
+
+		enum_ctx->attach_cb(enum_ctx->cb_ctx, pci_dev, ioat);
+	}
+
+	return 0;
+}
+
 int
-ioat_detach(struct ioat_channel *ioat)
+spdk_ioat_probe(void *cb_ctx, spdk_ioat_probe_cb probe_cb, spdk_ioat_attach_cb attach_cb)
+{
+	int rc;
+	struct ioat_enum_ctx enum_ctx;
+
+	ioat_mutex_lock(&g_ioat_driver.lock);
+
+	enum_ctx.probe_cb = probe_cb;
+	enum_ctx.attach_cb = attach_cb;
+	enum_ctx.cb_ctx = cb_ctx;
+
+	rc = ioat_pci_enumerate(ioat_enum_cb, &enum_ctx);
+
+	ioat_mutex_unlock(&g_ioat_driver.lock);
+
+	return rc;
+}
+
+int
+spdk_ioat_detach(struct spdk_ioat_chan *ioat)
 {
 	struct ioat_driver	*driver = &g_ioat_driver;
 
@@ -532,7 +565,8 @@ ioat_detach(struct ioat_channel *ioat)
 	 * when calling ioat_detach().
 	 */
 	ioat_mutex_lock(&driver->lock);
-	SLIST_REMOVE(&ioat_free_channels, ioat, ioat_channel, next);
+	SLIST_REMOVE(&ioat_free_channels, ioat, spdk_ioat_chan, next);
+	TAILQ_REMOVE(&driver->attached_chans, ioat, tailq);
 	ioat_mutex_unlock(&driver->lock);
 
 	ioat_channel_destruct(ioat);
@@ -542,7 +576,7 @@ ioat_detach(struct ioat_channel *ioat)
 }
 
 int
-ioat_register_thread(void)
+spdk_ioat_register_thread(void)
 {
 	struct ioat_driver	*driver = &g_ioat_driver;
 
@@ -564,7 +598,7 @@ ioat_register_thread(void)
 }
 
 void
-ioat_unregister_thread(void)
+spdk_ioat_unregister_thread(void)
 {
 	struct ioat_driver	*driver = &g_ioat_driver;
 
@@ -586,10 +620,10 @@ ioat_unregister_thread(void)
 #define _2MB_OFFSET(ptr)	((ptr) &  (0x200000 - 1))
 
 int64_t
-ioat_submit_copy(void *cb_arg, ioat_callback_t cb_fn,
-		 void *dst, const void *src, uint64_t nbytes)
+spdk_ioat_submit_copy(void *cb_arg, spdk_ioat_req_cb cb_fn,
+		      void *dst, const void *src, uint64_t nbytes)
 {
-	struct ioat_channel	*ioat;
+	struct spdk_ioat_chan	*ioat;
 	struct ioat_descriptor	*last_desc;
 	uint64_t	remaining, op_size;
 	uint64_t	vdst, vsrc;
@@ -663,7 +697,78 @@ ioat_submit_copy(void *cb_arg, ioat_callback_t cb_fn,
 	return nbytes;
 }
 
-int ioat_process_events(void)
+int64_t
+spdk_ioat_submit_fill(void *cb_arg, spdk_ioat_req_cb cb_fn,
+		      void *dst, uint64_t fill_pattern, uint64_t nbytes)
+{
+	struct spdk_ioat_chan	*ioat;
+	struct ioat_descriptor	*last_desc = NULL;
+	uint64_t	remaining, op_size;
+	uint64_t	vdst;
+	uint32_t	orig_head;
+
+	ioat = ioat_thread_channel;
+	if (!ioat) {
+		return -1;
+	}
+
+	if (!(ioat->dma_capabilities & SPDK_IOAT_ENGINE_FILL_SUPPORTED)) {
+		ioat_printf(ioat, "Channel does not support memory fill\n");
+		return -1;
+	}
+
+	orig_head = ioat->head;
+
+	vdst = (uint64_t)dst;
+	remaining = nbytes;
+
+	while (remaining) {
+		op_size = remaining;
+		op_size = min(op_size, ioat->max_xfer_size);
+		remaining -= op_size;
+
+		last_desc = ioat_prep_fill(ioat,
+					   ioat_vtophys((void *)vdst),
+					   fill_pattern,
+					   op_size);
+
+		if (remaining == 0 || last_desc == NULL) {
+			break;
+		}
+
+		vdst += op_size;
+	}
+
+	if (last_desc) {
+		last_desc->callback_fn = cb_fn;
+		last_desc->callback_arg = cb_arg;
+	} else {
+		/*
+		 * Ran out of descriptors in the ring - reset head to leave things as they were
+		 * in case we managed to fill out any descriptors.
+		 */
+		ioat->head = orig_head;
+		return -1;
+	}
+
+	ioat_flush(ioat);
+	return nbytes;
+}
+
+uint32_t
+spdk_ioat_get_dma_capabilities(void)
+{
+	struct spdk_ioat_chan	*ioat;
+
+	ioat = ioat_thread_channel;
+	if (!ioat) {
+		return 0;
+	}
+	return ioat->dma_capabilities;
+}
+
+int
+spdk_ioat_process_events(void)
 {
 	if (!ioat_thread_channel) {
 		return -1;
diff --git a/src/spdk/lib/ioat/ioat_impl.h b/src/spdk/lib/ioat/ioat_impl.h
index 1224a27..d7b41a9 100644
--- a/src/spdk/lib/ioat/ioat_impl.h
+++ b/src/spdk/lib/ioat/ioat_impl.h
@@ -3,14 +3,24 @@
 
 #include <assert.h>
 #include <pthread.h>
-#include <pciaccess.h>
 #include <stdio.h>
-#include <rte_malloc.h>
+#include <stdbool.h>
 #include <rte_config.h>
+#include <rte_malloc.h>
 #include <rte_atomic.h>
 #include <rte_cycles.h>
 
+#include "spdk/pci.h"
 #include "spdk/vtophys.h"
+#include "spdk/pci.h"
+
+#include "ioat_pci.h"
+
+#ifdef USE_PCIACCESS
+#include <pciaccess.h>
+#else
+#include <rte_pci.h>
+#endif
 
 /**
  * \file
@@ -42,7 +52,7 @@ ioat_zmalloc(const char *tag, size_t size, unsigned align, uint64_t *phys_addr)
 /**
  * Return the physical address for the specified virtual address.
  */
-#define ioat_vtophys(buf)		vtophys(buf)
+#define ioat_vtophys(buf)		spdk_vtophys(buf)
 
 /**
  * Delay us.
@@ -63,8 +73,96 @@ ioat_zmalloc(const char *tag, size_t size, unsigned align, uint64_t *phys_addr)
 /**
  *
  */
-#define ioat_pcicfg_read32(handle, var, offset)  pci_device_cfg_read_u32(handle, var, offset)
-#define ioat_pcicfg_write32(handle, var, offset) pci_device_cfg_write_u32(handle, var, offset)
+#define ioat_pcicfg_read32(handle, var, offset)  spdk_pci_device_cfg_read32(handle, var, offset)
+#define ioat_pcicfg_write32(handle, var, offset) spdk_pci_device_cfg_write32(handle, var, offset)
+
+struct ioat_pci_enum_ctx {
+	int (*user_enum_cb)(void *enum_ctx, struct spdk_pci_device *pci_dev);
+	void *user_enum_ctx;
+};
+
+#ifdef USE_PCIACCESS
+
+static inline bool
+ioat_pci_device_match_id(uint16_t vendor_id, uint16_t device_id)
+{
+	if (vendor_id != SPDK_PCI_VID_INTEL) {
+		return false;
+	}
+
+	switch (device_id) {
+	case PCI_DEVICE_ID_INTEL_IOAT_SNB0:
+	case PCI_DEVICE_ID_INTEL_IOAT_SNB1:
+	case PCI_DEVICE_ID_INTEL_IOAT_SNB2:
+	case PCI_DEVICE_ID_INTEL_IOAT_SNB3:
+	case PCI_DEVICE_ID_INTEL_IOAT_SNB4:
+	case PCI_DEVICE_ID_INTEL_IOAT_SNB5:
+	case PCI_DEVICE_ID_INTEL_IOAT_SNB6:
+	case PCI_DEVICE_ID_INTEL_IOAT_SNB7:
+	case PCI_DEVICE_ID_INTEL_IOAT_IVB0:
+	case PCI_DEVICE_ID_INTEL_IOAT_IVB1:
+	case PCI_DEVICE_ID_INTEL_IOAT_IVB2:
+	case PCI_DEVICE_ID_INTEL_IOAT_IVB3:
+	case PCI_DEVICE_ID_INTEL_IOAT_IVB4:
+	case PCI_DEVICE_ID_INTEL_IOAT_IVB5:
+	case PCI_DEVICE_ID_INTEL_IOAT_IVB6:
+	case PCI_DEVICE_ID_INTEL_IOAT_IVB7:
+	case PCI_DEVICE_ID_INTEL_IOAT_HSW0:
+	case PCI_DEVICE_ID_INTEL_IOAT_HSW1:
+	case PCI_DEVICE_ID_INTEL_IOAT_HSW2:
+	case PCI_DEVICE_ID_INTEL_IOAT_HSW3:
+	case PCI_DEVICE_ID_INTEL_IOAT_HSW4:
+	case PCI_DEVICE_ID_INTEL_IOAT_HSW5:
+	case PCI_DEVICE_ID_INTEL_IOAT_HSW6:
+	case PCI_DEVICE_ID_INTEL_IOAT_HSW7:
+	case PCI_DEVICE_ID_INTEL_IOAT_BDX0:
+	case PCI_DEVICE_ID_INTEL_IOAT_BDX1:
+	case PCI_DEVICE_ID_INTEL_IOAT_BDX2:
+	case PCI_DEVICE_ID_INTEL_IOAT_BDX3:
+	case PCI_DEVICE_ID_INTEL_IOAT_BDX4:
+	case PCI_DEVICE_ID_INTEL_IOAT_BDX5:
+	case PCI_DEVICE_ID_INTEL_IOAT_BDX6:
+	case PCI_DEVICE_ID_INTEL_IOAT_BDX7:
+	case PCI_DEVICE_ID_INTEL_IOAT_BDX8:
+	case PCI_DEVICE_ID_INTEL_IOAT_BDX9:
+	case PCI_DEVICE_ID_INTEL_IOAT_BWD0:
+	case PCI_DEVICE_ID_INTEL_IOAT_BWD1:
+	case PCI_DEVICE_ID_INTEL_IOAT_BWD2:
+	case PCI_DEVICE_ID_INTEL_IOAT_BWD3:
+	case PCI_DEVICE_ID_INTEL_IOAT_BDXDE0:
+	case PCI_DEVICE_ID_INTEL_IOAT_BDXDE1:
+	case PCI_DEVICE_ID_INTEL_IOAT_BDXDE2:
+	case PCI_DEVICE_ID_INTEL_IOAT_BDXDE3:
+		return true;
+	}
+
+	return false;
+}
+
+static int
+ioat_pci_enum_cb(void *enum_ctx, struct spdk_pci_device *pci_dev)
+{
+	struct ioat_pci_enum_ctx *ctx = enum_ctx;
+	uint16_t vendor_id = spdk_pci_device_get_vendor_id(pci_dev);
+	uint16_t device_id = spdk_pci_device_get_device_id(pci_dev);
+
+	if (!ioat_pci_device_match_id(vendor_id, device_id)) {
+		return 0;
+	}
+
+	return ctx->user_enum_cb(ctx->user_enum_ctx, pci_dev);
+}
+
+static inline int
+ioat_pci_enumerate(int (*enum_cb)(void *enum_ctx, struct spdk_pci_device *pci_dev), void *enum_ctx)
+{
+	struct ioat_pci_enum_ctx ioat_enum_ctx;
+
+	ioat_enum_ctx.user_enum_cb = enum_cb;
+	ioat_enum_ctx.user_enum_ctx = enum_ctx;
+
+	return spdk_pci_enumerate(ioat_pci_enum_cb, &ioat_enum_ctx);
+}
 
 static inline int
 ioat_pcicfg_map_bar(void *devhandle, uint32_t bar, uint32_t read_only, void **mapped_addr)
@@ -84,6 +182,112 @@ ioat_pcicfg_unmap_bar(void *devhandle, uint32_t bar, void *addr)
 	return pci_device_unmap_range(dev, addr, dev->regions[bar].size);
 }
 
+#else /* !USE_PCIACCESS */
+
+static inline int
+ioat_pcicfg_map_bar(void *devhandle, uint32_t bar, uint32_t read_only, void **mapped_addr)
+{
+	struct rte_pci_device *dev = devhandle;
+
+	*mapped_addr = dev->mem_resource[bar].addr;
+	return 0;
+}
+
+/* TODO: avoid duplicating the device ID list */
+static struct rte_pci_id ioat_driver_id[] = {
+	{RTE_PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IOAT_SNB0)},
+	{RTE_PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IOAT_SNB1)},
+	{RTE_PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IOAT_SNB2)},
+	{RTE_PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IOAT_SNB3)},
+	{RTE_PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IOAT_SNB4)},
+	{RTE_PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IOAT_SNB5)},
+	{RTE_PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IOAT_SNB6)},
+	{RTE_PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IOAT_SNB7)},
+	{RTE_PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IOAT_SNB8)},
+	{RTE_PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IOAT_IVB0)},
+	{RTE_PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IOAT_IVB1)},
+	{RTE_PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IOAT_IVB2)},
+	{RTE_PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IOAT_IVB3)},
+	{RTE_PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IOAT_IVB4)},
+	{RTE_PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IOAT_IVB5)},
+	{RTE_PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IOAT_IVB6)},
+	{RTE_PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IOAT_IVB7)},
+	{RTE_PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IOAT_IVB8)},
+	{RTE_PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IOAT_IVB9)},
+	{RTE_PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IOAT_HSW0)},
+	{RTE_PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IOAT_HSW2)},
+	{RTE_PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IOAT_HSW3)},
+	{RTE_PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IOAT_HSW4)},
+	{RTE_PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IOAT_HSW5)},
+	{RTE_PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IOAT_HSW6)},
+	{RTE_PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IOAT_HSW7)},
+	{RTE_PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IOAT_HSW8)},
+	{RTE_PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IOAT_HSW9)},
+	{RTE_PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IOAT_BWD0)},
+	{RTE_PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IOAT_BWD1)},
+	{RTE_PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IOAT_BWD2)},
+	{RTE_PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IOAT_BWD3)},
+	{RTE_PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IOAT_BDXDE0)},
+	{RTE_PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IOAT_BDXDE1)},
+	{RTE_PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IOAT_BDXDE2)},
+	{RTE_PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IOAT_BDXDE3)},
+	{RTE_PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IOAT_BDX0)},
+	{RTE_PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IOAT_BDX1)},
+	{RTE_PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IOAT_BDX2)},
+	{RTE_PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IOAT_BDX3)},
+	{RTE_PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IOAT_BDX4)},
+	{RTE_PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IOAT_BDX5)},
+	{RTE_PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IOAT_BDX6)},
+	{RTE_PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IOAT_BDX7)},
+	{RTE_PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IOAT_BDX8)},
+	{RTE_PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IOAT_BDX9)},
+	{ .vendor_id = 0, /* sentinel */ },
+};
+
+/*
+ * TODO: eliminate this global if possible (does rte_pci_driver have a context field for this?)
+ *
+ * This should be protected by the ioat driver lock, since ioat_probe() holds the lock
+ *  the whole time, but we shouldn't have to depend on that.
+ */
+static struct ioat_pci_enum_ctx g_ioat_pci_enum_ctx;
+
+static int
+ioat_driver_init(struct rte_pci_driver *dr, struct rte_pci_device *rte_dev)
+{
+	/*
+	 * These are actually the same type internally.
+	 * TODO: refactor this so it's inside pci.c
+	 */
+	struct spdk_pci_device *pci_dev = (struct spdk_pci_device *)rte_dev;
+
+	return g_ioat_pci_enum_ctx.user_enum_cb(g_ioat_pci_enum_ctx.user_enum_ctx, pci_dev);
+}
+
+static struct rte_pci_driver ioat_rte_driver = {
+	.name = "ioat_driver",
+	.devinit = ioat_driver_init,
+	.id_table = ioat_driver_id,
+	.drv_flags = RTE_PCI_DRV_NEED_MAPPING,
+};
+
+static inline int
+ioat_pci_enumerate(int (*enum_cb)(void *enum_ctx, struct spdk_pci_device *pci_dev), void *enum_ctx)
+{
+	int rc;
+
+	g_ioat_pci_enum_ctx.user_enum_cb = enum_cb;
+	g_ioat_pci_enum_ctx.user_enum_ctx = enum_ctx;
+
+	rte_eal_pci_register(&ioat_rte_driver);
+	rc = rte_eal_pci_probe();
+	rte_eal_pci_unregister(&ioat_rte_driver);
+
+	return rc;
+}
+
+#endif /* !USE_PCIACCESS */
+
 typedef pthread_mutex_t ioat_mutex_t;
 
 #define ioat_mutex_lock pthread_mutex_lock
diff --git a/src/spdk/lib/ioat/ioat_internal.h b/src/spdk/lib/ioat/ioat_internal.h
index 030d278..9b23eef 100644
--- a/src/spdk/lib/ioat/ioat_internal.h
+++ b/src/spdk/lib/ioat/ioat_internal.h
@@ -50,18 +50,18 @@
 #define IOAT_DEFAULT_ORDER			15
 
 struct ioat_descriptor {
-	ioat_callback_t		callback_fn;
+	spdk_ioat_req_cb	callback_fn;
 	void			*callback_arg;
 };
 
 /* One of these per allocated PCI device. */
-struct ioat_channel {
-	SLIST_ENTRY(ioat_channel) next;
+struct spdk_ioat_chan {
+	SLIST_ENTRY(spdk_ioat_chan) next;
 
 	/* Opaque handle to upper layer */
 	void                *device;
 	uint64_t            max_xfer_size;
-	volatile struct ioat_registers *regs;
+	volatile struct spdk_ioat_registers *regs;
 
 	volatile uint64_t   *comp_update;
 
@@ -72,32 +72,36 @@ struct ioat_channel {
 	uint64_t            last_seen;
 
 	struct ioat_descriptor		*ring;
-	union ioat_hw_descriptor	*hw_ring;
+	union spdk_ioat_hw_desc		*hw_ring;
 	uint64_t			hw_ring_phys_addr;
+	uint32_t			dma_capabilities;
+
+	/* tailq entry for attached_chans */
+	TAILQ_ENTRY(spdk_ioat_chan)	tailq;
 };
 
 static inline uint32_t
 is_ioat_active(uint64_t status)
 {
-	return (status & IOAT_CHANSTS_STATUS) == IOAT_CHANSTS_ACTIVE;
+	return (status & SPDK_IOAT_CHANSTS_STATUS) == SPDK_IOAT_CHANSTS_ACTIVE;
 }
 
 static inline uint32_t
 is_ioat_idle(uint64_t status)
 {
-	return (status & IOAT_CHANSTS_STATUS) == IOAT_CHANSTS_IDLE;
+	return (status & SPDK_IOAT_CHANSTS_STATUS) == SPDK_IOAT_CHANSTS_IDLE;
 }
 
 static inline uint32_t
 is_ioat_halted(uint64_t status)
 {
-	return (status & IOAT_CHANSTS_STATUS) == IOAT_CHANSTS_HALTED;
+	return (status & SPDK_IOAT_CHANSTS_STATUS) == SPDK_IOAT_CHANSTS_HALTED;
 }
 
 static inline uint32_t
 is_ioat_suspended(uint64_t status)
 {
-	return (status & IOAT_CHANSTS_STATUS) == IOAT_CHANSTS_SUSPENDED;
+	return (status & SPDK_IOAT_CHANSTS_STATUS) == SPDK_IOAT_CHANSTS_SUSPENDED;
 }
 
 #endif /* __IOAT_INTERNAL_H__ */
diff --git a/src/spdk/lib/memory/vtophys.c b/src/spdk/lib/memory/vtophys.c
index 40972f7..5abab3c 100644
--- a/src/spdk/lib/memory/vtophys.c
+++ b/src/spdk/lib/memory/vtophys.c
@@ -69,7 +69,7 @@ struct map_2mb {
 };
 
 /* Second-level map table indexed by bits [21..29] of the virtual address.
- * Each entry contains the 2MB physical page frame number or VTOPHYS_ERROR for entries that haven't
+ * Each entry contains the 2MB physical page frame number or SPDK_VTOPHYS_ERROR for entries that haven't
  * been retrieved yet.
  */
 struct map_1gb {
@@ -109,7 +109,7 @@ vtophys_get_map(uint64_t vfn_2mb)
 		if (!map_1gb) {
 			map_1gb = malloc(sizeof(struct map_1gb));
 			if (map_1gb) {
-				/* initialize all entries to all 0xFF (VTOPHYS_ERROR) */
+				/* initialize all entries to all 0xFF (SPDK_VTOPHYS_ERROR) */
 				memset(map_1gb, 0xFF, sizeof(struct map_1gb));
 				vtophys_map_128tb.map[idx_128tb] = map_1gb;
 			}
@@ -157,7 +157,7 @@ vtophys_get_pfn_2mb(uint64_t vfn_2mb)
 }
 
 uint64_t
-vtophys(void *buf)
+spdk_vtophys(void *buf)
 {
 	struct map_2mb *map_2mb;
 	uint64_t vfn_2mb, pfn_2mb;
@@ -167,14 +167,14 @@ vtophys(void *buf)
 
 	map_2mb = vtophys_get_map(vfn_2mb);
 	if (!map_2mb) {
-		return VTOPHYS_ERROR;
+		return SPDK_VTOPHYS_ERROR;
 	}
 
 	pfn_2mb = map_2mb->pfn_2mb;
-	if (pfn_2mb == VTOPHYS_ERROR) {
+	if (pfn_2mb == SPDK_VTOPHYS_ERROR) {
 		pfn_2mb = vtophys_get_pfn_2mb(vfn_2mb);
-		if (pfn_2mb == VTOPHYS_ERROR) {
-			return VTOPHYS_ERROR;
+		if (pfn_2mb == SPDK_VTOPHYS_ERROR) {
+			return SPDK_VTOPHYS_ERROR;
 		}
 		map_2mb->pfn_2mb = pfn_2mb;
 	}
diff --git a/src/spdk/lib/nvme/Makefile b/src/spdk/lib/nvme/Makefile
index 18572c4..7924b6d 100644
--- a/src/spdk/lib/nvme/Makefile
+++ b/src/spdk/lib/nvme/Makefile
@@ -36,7 +36,7 @@ include $(SPDK_ROOT_DIR)/mk/spdk.common.mk
 
 CFLAGS += $(DPDK_INC) -include $(CONFIG_NVME_IMPL)
 
-C_SRCS = nvme_ctrlr_cmd.c nvme_ctrlr.c nvme_ns_cmd.c nvme_ns.c nvme_qpair.c nvme.c
+C_SRCS = nvme_ctrlr_cmd.c nvme_ctrlr.c nvme_ns_cmd.c nvme_ns.c nvme_qpair.c nvme.c nvme_intel.c
 
 LIB = libspdk_nvme.a
 
diff --git a/src/spdk/lib/nvme/nvme.c b/src/spdk/lib/nvme/nvme.c
index 072a1ed..9975824 100644
--- a/src/spdk/lib/nvme/nvme.c
+++ b/src/spdk/lib/nvme/nvme.c
@@ -39,10 +39,12 @@
 
 struct nvme_driver g_nvme_driver = {
 	.lock = NVME_MUTEX_INITIALIZER,
-	.max_io_queues = DEFAULT_MAX_IO_QUEUES
+	.max_io_queues = DEFAULT_MAX_IO_QUEUES,
+	.init_ctrlrs = TAILQ_HEAD_INITIALIZER(g_nvme_driver.init_ctrlrs),
+	.attached_ctrlrs = TAILQ_HEAD_INITIALIZER(g_nvme_driver.attached_ctrlrs),
 };
 
-int32_t		nvme_retry_count;
+int32_t		spdk_nvme_retry_count;
 __thread int	nvme_thread_ioq_index = -1;
 
 
@@ -52,26 +54,28 @@ __thread int	nvme_thread_ioq_index = -1;
 \msc
 
 	app [label="Application"], nvme [label="NVMe Driver"];
-	app=>nvme [label="nvme_attach(devhandle)"];
-	app<<nvme [label="nvme_controller ptr"];
-	app=>nvme [label="nvme_ctrlr_start(nvme_controller ptr)"];
+	app=>nvme [label="nvme_probe()"];
+	app<<nvme [label="probe_cb(pci_dev)"];
+	nvme=>nvme [label="nvme_attach(devhandle)"];
+	nvme=>nvme [label="nvme_ctrlr_start(nvme_controller ptr)"];
 	nvme=>nvme [label="identify controller"];
 	nvme=>nvme [label="create queue pairs"];
 	nvme=>nvme [label="identify namespace(s)"];
+	app<<nvme [label="attach_cb(pci_dev, nvme_controller)"];
 	app=>app [label="create block devices based on controller's namespaces"];
 
 \endmsc
 
  */
 
-struct nvme_controller *
+static struct spdk_nvme_ctrlr *
 nvme_attach(void *devhandle)
 {
-	struct nvme_controller	*ctrlr;
+	struct spdk_nvme_ctrlr	*ctrlr;
 	int			status;
 	uint64_t		phys_addr = 0;
 
-	ctrlr = nvme_malloc("nvme_ctrlr", sizeof(struct nvme_controller),
+	ctrlr = nvme_malloc("nvme_ctrlr", sizeof(struct spdk_nvme_ctrlr),
 			    64, &phys_addr);
 	if (ctrlr == NULL) {
 		nvme_printf(NULL, "could not allocate ctrlr\n");
@@ -84,25 +88,26 @@ nvme_attach(void *devhandle)
 		return NULL;
 	}
 
-	if (nvme_ctrlr_start(ctrlr) != 0) {
-		nvme_ctrlr_destruct(ctrlr);
-		nvme_free(ctrlr);
-		return NULL;
-	}
-
 	return ctrlr;
 }
 
 int
-nvme_detach(struct nvme_controller *ctrlr)
+spdk_nvme_detach(struct spdk_nvme_ctrlr *ctrlr)
 {
+	struct nvme_driver	*driver = &g_nvme_driver;
+
+	nvme_mutex_lock(&driver->lock);
+
 	nvme_ctrlr_destruct(ctrlr);
+	TAILQ_REMOVE(&g_nvme_driver.attached_ctrlrs, ctrlr, tailq);
 	nvme_free(ctrlr);
+
+	nvme_mutex_unlock(&driver->lock);
 	return 0;
 }
 
 void
-nvme_completion_poll_cb(void *arg, const struct nvme_completion *cpl)
+nvme_completion_poll_cb(void *arg, const struct spdk_nvme_cpl *cpl)
 {
 	struct nvme_completion_poll_status	*status = arg;
 
@@ -116,14 +121,14 @@ nvme_completion_poll_cb(void *arg, const struct nvme_completion *cpl)
 }
 
 size_t
-nvme_request_size(void)
+spdk_nvme_request_size(void)
 {
 	return sizeof(struct nvme_request);
 }
 
 struct nvme_request *
 nvme_allocate_request(const struct nvme_payload *payload, uint32_t payload_size,
-		      nvme_cb_fn_t cb_fn, void *cb_arg)
+		      spdk_nvme_cmd_cb cb_fn, void *cb_arg)
 {
 	struct nvme_request *req = NULL;
 
@@ -153,7 +158,8 @@ nvme_allocate_request(const struct nvme_payload *payload, uint32_t payload_size,
 }
 
 struct nvme_request *
-nvme_allocate_request_contig(void *buffer, uint32_t payload_size, nvme_cb_fn_t cb_fn, void *cb_arg)
+nvme_allocate_request_contig(void *buffer, uint32_t payload_size, spdk_nvme_cmd_cb cb_fn,
+			     void *cb_arg)
 {
 	struct nvme_payload payload;
 
@@ -164,7 +170,7 @@ nvme_allocate_request_contig(void *buffer, uint32_t payload_size, nvme_cb_fn_t c
 }
 
 struct nvme_request *
-nvme_allocate_request_null(nvme_cb_fn_t cb_fn, void *cb_arg)
+nvme_allocate_request_null(spdk_nvme_cmd_cb cb_fn, void *cb_arg)
 {
 	return nvme_allocate_request_contig(NULL, 0, cb_fn, cb_arg);
 }
@@ -224,7 +230,7 @@ nvme_free_ioq_index(void)
 }
 
 int
-nvme_register_io_thread(void)
+spdk_nvme_register_io_thread(void)
 {
 	int rc = 0;
 
@@ -242,8 +248,99 @@ nvme_register_io_thread(void)
 }
 
 void
-nvme_unregister_io_thread(void)
+spdk_nvme_unregister_io_thread(void)
 {
 	nvme_free_ioq_index();
 }
 
+struct nvme_enum_ctx {
+	spdk_nvme_probe_cb probe_cb;
+	void *cb_ctx;
+};
+
+/* This function must only be called while holding g_nvme_driver.lock */
+static int
+nvme_enum_cb(void *ctx, struct spdk_pci_device *pci_dev)
+{
+	struct nvme_enum_ctx *enum_ctx = ctx;
+	struct spdk_nvme_ctrlr *ctrlr;
+
+	/* Verify that this controller is not already attached */
+	TAILQ_FOREACH(ctrlr, &g_nvme_driver.attached_ctrlrs, tailq) {
+		/* NOTE: This assumes that the PCI abstraction layer will use the same device handle
+		 *  across enumerations; we could compare by BDF instead if this is not true.
+		 */
+		if (pci_dev == ctrlr->devhandle) {
+			return 0;
+		}
+	}
+
+	if (enum_ctx->probe_cb(enum_ctx->cb_ctx, pci_dev)) {
+		ctrlr = nvme_attach(pci_dev);
+		if (ctrlr == NULL) {
+			nvme_printf(NULL, "nvme_attach() failed\n");
+			return -1;
+		}
+
+		TAILQ_INSERT_TAIL(&g_nvme_driver.init_ctrlrs, ctrlr, tailq);
+	}
+
+	return 0;
+}
+
+int
+spdk_nvme_probe(void *cb_ctx, spdk_nvme_probe_cb probe_cb, spdk_nvme_attach_cb attach_cb)
+{
+	int rc, start_rc;
+	struct nvme_enum_ctx enum_ctx;
+	struct spdk_nvme_ctrlr *ctrlr;
+
+	nvme_mutex_lock(&g_nvme_driver.lock);
+
+	enum_ctx.probe_cb = probe_cb;
+	enum_ctx.cb_ctx = cb_ctx;
+
+	rc = nvme_pci_enumerate(nvme_enum_cb, &enum_ctx);
+	/*
+	 * Keep going even if one or more nvme_attach() calls failed,
+	 *  but maintain the value of rc to signal errors when we return.
+	 */
+
+	/* TODO: This could be reworked to start all the controllers in parallel. */
+	while (!TAILQ_EMPTY(&g_nvme_driver.init_ctrlrs)) {
+		/* Remove ctrlr from init_ctrlrs and attempt to start it */
+		ctrlr = TAILQ_FIRST(&g_nvme_driver.init_ctrlrs);
+		TAILQ_REMOVE(&g_nvme_driver.init_ctrlrs, ctrlr, tailq);
+
+		/*
+		 * Drop the driver lock while calling nvme_ctrlr_start() since it needs to acquire
+		 *  the driver lock internally.
+		 *
+		 * TODO: Rethink the locking - maybe reset should take the lock so that start() and
+		 *  the functions it calls (in particular nvme_ctrlr_set_num_qpairs())
+		 *  can assume it is held.
+		 */
+		nvme_mutex_unlock(&g_nvme_driver.lock);
+		start_rc = nvme_ctrlr_start(ctrlr);
+		nvme_mutex_lock(&g_nvme_driver.lock);
+
+		if (start_rc == 0) {
+			TAILQ_INSERT_TAIL(&g_nvme_driver.attached_ctrlrs, ctrlr, tailq);
+
+			/*
+			 * Unlock while calling attach_cb() so the user can call other functions
+			 *  that may take the driver lock, like nvme_detach().
+			 */
+			nvme_mutex_unlock(&g_nvme_driver.lock);
+			attach_cb(cb_ctx, ctrlr->devhandle, ctrlr);
+			nvme_mutex_lock(&g_nvme_driver.lock);
+		} else {
+			nvme_ctrlr_destruct(ctrlr);
+			nvme_free(ctrlr);
+			rc = -1;
+		}
+	}
+
+	nvme_mutex_unlock(&g_nvme_driver.lock);
+	return rc;
+}
diff --git a/src/spdk/lib/nvme/nvme_ctrlr.c b/src/spdk/lib/nvme/nvme_ctrlr.c
index 4920384..1afc937 100644
--- a/src/spdk/lib/nvme/nvme_ctrlr.c
+++ b/src/spdk/lib/nvme/nvme_ctrlr.c
@@ -32,46 +32,58 @@
  */
 
 #include "nvme_internal.h"
-#include "spdk/nvme_intel.h"
+#include "spdk/pci.h"
+
 /**
  * \file
  *
  */
 
-static int nvme_ctrlr_construct_and_submit_aer(struct nvme_controller *ctrlr,
+static int nvme_ctrlr_construct_and_submit_aer(struct spdk_nvme_ctrlr *ctrlr,
 		struct nvme_async_event_request *aer);
 
 static void
-nvme_ctrlr_construct_intel_support_log_page_list(struct nvme_controller *ctrlr,
-		struct nvme_intel_log_page_directory *log_page_directory)
+nvme_ctrlr_construct_intel_support_log_page_list(struct spdk_nvme_ctrlr *ctrlr,
+		struct spdk_nvme_intel_log_page_directory *log_page_directory)
 {
-	if (ctrlr->cdata.vid != PCI_VENDOR_ID_INTEL || log_page_directory == NULL)
+	struct spdk_pci_device *dev;
+	struct pci_id pci_id;
+
+	if (ctrlr->cdata.vid != SPDK_PCI_VID_INTEL || log_page_directory == NULL)
 		return;
 
-	ctrlr->log_page_supported[NVME_INTEL_LOG_PAGE_DIRECTORY] = true;
+	dev = ctrlr->devhandle;
+	pci_id.vendor_id = spdk_pci_device_get_vendor_id(dev);
+	pci_id.dev_id = spdk_pci_device_get_device_id(dev);
+	pci_id.sub_vendor_id = spdk_pci_device_get_subvendor_id(dev);
+	pci_id.sub_dev_id = spdk_pci_device_get_subdevice_id(dev);
 
-	if (log_page_directory->read_latency_log_len) {
-		ctrlr->log_page_supported[NVME_INTEL_LOG_READ_CMD_LATENCY] = true;
+	ctrlr->log_page_supported[SPDK_NVME_INTEL_LOG_PAGE_DIRECTORY] = true;
+
+	if (log_page_directory->read_latency_log_len ||
+	    nvme_intel_has_quirk(&pci_id, NVME_INTEL_QUIRK_READ_LATENCY)) {
+		ctrlr->log_page_supported[SPDK_NVME_INTEL_LOG_READ_CMD_LATENCY] = true;
 	}
-	if (log_page_directory->write_latency_log_len) {
-		ctrlr->log_page_supported[NVME_INTEL_LOG_WRITE_CMD_LATENCY] = true;
+	if (log_page_directory->write_latency_log_len ||
+	    nvme_intel_has_quirk(&pci_id, NVME_INTEL_QUIRK_WRITE_LATENCY)) {
+		ctrlr->log_page_supported[SPDK_NVME_INTEL_LOG_WRITE_CMD_LATENCY] = true;
 	}
 	if (log_page_directory->temperature_statistics_log_len) {
-		ctrlr->log_page_supported[NVME_INTEL_LOG_TEMPERATURE] = true;
+		ctrlr->log_page_supported[SPDK_NVME_INTEL_LOG_TEMPERATURE] = true;
 	}
 	if (log_page_directory->smart_log_len) {
-		ctrlr->log_page_supported[NVME_INTEL_LOG_SMART] = true;
+		ctrlr->log_page_supported[SPDK_NVME_INTEL_LOG_SMART] = true;
 	}
 }
 
-static int nvme_ctrlr_set_intel_support_log_pages(struct nvme_controller *ctrlr)
+static int nvme_ctrlr_set_intel_support_log_pages(struct spdk_nvme_ctrlr *ctrlr)
 {
 	uint64_t phys_addr = 0;
 	struct nvme_completion_poll_status	status;
-	struct nvme_intel_log_page_directory *log_page_directory;
+	struct spdk_nvme_intel_log_page_directory *log_page_directory;
 
 	log_page_directory = nvme_malloc("nvme_log_page_directory",
-					 sizeof(struct nvme_intel_log_page_directory),
+					 sizeof(struct spdk_nvme_intel_log_page_directory),
 					 64, &phys_addr);
 	if (log_page_directory == NULL) {
 		nvme_printf(NULL, "could not allocate log_page_directory\n");
@@ -79,14 +91,14 @@ static int nvme_ctrlr_set_intel_support_log_pages(struct nvme_controller *ctrlr)
 	}
 
 	status.done = false;
-	nvme_ctrlr_cmd_get_log_page(ctrlr, NVME_INTEL_LOG_PAGE_DIRECTORY, NVME_GLOBAL_NAMESPACE_TAG,
-				    log_page_directory, sizeof(struct nvme_intel_log_page_directory),
-				    nvme_completion_poll_cb,
-				    &status);
+	spdk_nvme_ctrlr_cmd_get_log_page(ctrlr, SPDK_NVME_INTEL_LOG_PAGE_DIRECTORY, SPDK_NVME_GLOBAL_NS_TAG,
+					 log_page_directory, sizeof(struct spdk_nvme_intel_log_page_directory),
+					 nvme_completion_poll_cb,
+					 &status);
 	while (status.done == false) {
 		nvme_qpair_process_completions(&ctrlr->adminq, 0);
 	}
-	if (nvme_completion_is_error(&status.cpl)) {
+	if (spdk_nvme_cpl_is_error(&status.cpl)) {
 		nvme_free(log_page_directory);
 		nvme_printf(ctrlr, "nvme_ctrlr_cmd_get_log_page failed!\n");
 		return ENXIO;
@@ -98,64 +110,64 @@ static int nvme_ctrlr_set_intel_support_log_pages(struct nvme_controller *ctrlr)
 }
 
 static void
-nvme_ctrlr_set_supported_log_pages(struct nvme_controller *ctrlr)
+nvme_ctrlr_set_supported_log_pages(struct spdk_nvme_ctrlr *ctrlr)
 {
 	memset(ctrlr->log_page_supported, 0, sizeof(ctrlr->log_page_supported));
 	/* Mandatory pages */
-	ctrlr->log_page_supported[NVME_LOG_ERROR] = true;
-	ctrlr->log_page_supported[NVME_LOG_HEALTH_INFORMATION] = true;
-	ctrlr->log_page_supported[NVME_LOG_FIRMWARE_SLOT] = true;
+	ctrlr->log_page_supported[SPDK_NVME_LOG_ERROR] = true;
+	ctrlr->log_page_supported[SPDK_NVME_LOG_HEALTH_INFORMATION] = true;
+	ctrlr->log_page_supported[SPDK_NVME_LOG_FIRMWARE_SLOT] = true;
 	if (ctrlr->cdata.lpa.celp) {
-		ctrlr->log_page_supported[NVME_LOG_COMMAND_EFFECTS_LOG] = true;
+		ctrlr->log_page_supported[SPDK_NVME_LOG_COMMAND_EFFECTS_LOG] = true;
 	}
-	if (ctrlr->cdata.vid == PCI_VENDOR_ID_INTEL) {
+	if (ctrlr->cdata.vid == SPDK_PCI_VID_INTEL) {
 		nvme_ctrlr_set_intel_support_log_pages(ctrlr);
 	}
 }
 
 static void
-nvme_ctrlr_set_intel_supported_features(struct nvme_controller *ctrlr)
+nvme_ctrlr_set_intel_supported_features(struct spdk_nvme_ctrlr *ctrlr)
 {
-	ctrlr->feature_supported[NVME_INTEL_FEAT_MAX_LBA] = true;
-	ctrlr->feature_supported[NVME_INTEL_FEAT_NATIVE_MAX_LBA] = true;
-	ctrlr->feature_supported[NVME_INTEL_FEAT_POWER_GOVERNOR_SETTING] = true;
-	ctrlr->feature_supported[NVME_INTEL_FEAT_SMBUS_ADDRESS] = true;
-	ctrlr->feature_supported[NVME_INTEL_FEAT_LED_PATTERN] = true;
-	ctrlr->feature_supported[NVME_INTEL_FEAT_RESET_TIMED_WORKLOAD_COUNTERS] = true;
-	ctrlr->feature_supported[NVME_INTEL_FEAT_LATENCY_TRACKING] = true;
+	ctrlr->feature_supported[SPDK_NVME_INTEL_FEAT_MAX_LBA] = true;
+	ctrlr->feature_supported[SPDK_NVME_INTEL_FEAT_NATIVE_MAX_LBA] = true;
+	ctrlr->feature_supported[SPDK_NVME_INTEL_FEAT_POWER_GOVERNOR_SETTING] = true;
+	ctrlr->feature_supported[SPDK_NVME_INTEL_FEAT_SMBUS_ADDRESS] = true;
+	ctrlr->feature_supported[SPDK_NVME_INTEL_FEAT_LED_PATTERN] = true;
+	ctrlr->feature_supported[SPDK_NVME_INTEL_FEAT_RESET_TIMED_WORKLOAD_COUNTERS] = true;
+	ctrlr->feature_supported[SPDK_NVME_INTEL_FEAT_LATENCY_TRACKING] = true;
 }
 
 static void
-nvme_ctrlr_set_supported_features(struct nvme_controller *ctrlr)
+nvme_ctrlr_set_supported_features(struct spdk_nvme_ctrlr *ctrlr)
 {
 	memset(ctrlr->feature_supported, 0, sizeof(ctrlr->feature_supported));
 	/* Mandatory features */
-	ctrlr->feature_supported[NVME_FEAT_ARBITRATION] = true;
-	ctrlr->feature_supported[NVME_FEAT_POWER_MANAGEMENT] = true;
-	ctrlr->feature_supported[NVME_FEAT_TEMPERATURE_THRESHOLD] = true;
-	ctrlr->feature_supported[NVME_FEAT_ERROR_RECOVERY] = true;
-	ctrlr->feature_supported[NVME_FEAT_NUMBER_OF_QUEUES] = true;
-	ctrlr->feature_supported[NVME_FEAT_INTERRUPT_COALESCING] = true;
-	ctrlr->feature_supported[NVME_FEAT_INTERRUPT_VECTOR_CONFIGURATION] = true;
-	ctrlr->feature_supported[NVME_FEAT_WRITE_ATOMICITY] = true;
-	ctrlr->feature_supported[NVME_FEAT_ASYNC_EVENT_CONFIGURATION] = true;
+	ctrlr->feature_supported[SPDK_NVME_FEAT_ARBITRATION] = true;
+	ctrlr->feature_supported[SPDK_NVME_FEAT_POWER_MANAGEMENT] = true;
+	ctrlr->feature_supported[SPDK_NVME_FEAT_TEMPERATURE_THRESHOLD] = true;
+	ctrlr->feature_supported[SPDK_NVME_FEAT_ERROR_RECOVERY] = true;
+	ctrlr->feature_supported[SPDK_NVME_FEAT_NUMBER_OF_QUEUES] = true;
+	ctrlr->feature_supported[SPDK_NVME_FEAT_INTERRUPT_COALESCING] = true;
+	ctrlr->feature_supported[SPDK_NVME_FEAT_INTERRUPT_VECTOR_CONFIGURATION] = true;
+	ctrlr->feature_supported[SPDK_NVME_FEAT_WRITE_ATOMICITY] = true;
+	ctrlr->feature_supported[SPDK_NVME_FEAT_ASYNC_EVENT_CONFIGURATION] = true;
 	/* Optional features */
 	if (ctrlr->cdata.vwc.present) {
-		ctrlr->feature_supported[NVME_FEAT_VOLATILE_WRITE_CACHE] = true;
+		ctrlr->feature_supported[SPDK_NVME_FEAT_VOLATILE_WRITE_CACHE] = true;
 	}
 	if (ctrlr->cdata.apsta.supported) {
-		ctrlr->feature_supported[NVME_FEAT_AUTONOMOUS_POWER_STATE_TRANSITION] = true;
+		ctrlr->feature_supported[SPDK_NVME_FEAT_AUTONOMOUS_POWER_STATE_TRANSITION] = true;
 	}
 	if (ctrlr->cdata.hmpre) {
-		ctrlr->feature_supported[NVME_FEAT_HOST_MEM_BUFFER] = true;
+		ctrlr->feature_supported[SPDK_NVME_FEAT_HOST_MEM_BUFFER] = true;
 	}
-	if (ctrlr->cdata.vid == PCI_VENDOR_ID_INTEL) {
+	if (ctrlr->cdata.vid == SPDK_PCI_VID_INTEL) {
 		nvme_ctrlr_set_intel_supported_features(ctrlr);
 	}
 }
 
 static int
-nvme_ctrlr_construct_admin_qpair(struct nvme_controller *ctrlr)
+nvme_ctrlr_construct_admin_qpair(struct spdk_nvme_ctrlr *ctrlr)
 {
 	return nvme_qpair_construct(&ctrlr->adminq,
 				    0, /* qpair ID */
@@ -165,10 +177,10 @@ nvme_ctrlr_construct_admin_qpair(struct nvme_controller *ctrlr)
 }
 
 static int
-nvme_ctrlr_construct_io_qpairs(struct nvme_controller *ctrlr)
+nvme_ctrlr_construct_io_qpairs(struct spdk_nvme_ctrlr *ctrlr)
 {
 	struct nvme_qpair		*qpair;
-	union nvme_cap_lo_register	cap_lo;
+	union spdk_nvme_cap_lo_register	cap_lo;
 	uint32_t			i, num_entries, num_trackers;
 	int				rc;
 
@@ -224,7 +236,7 @@ nvme_ctrlr_construct_io_qpairs(struct nvme_controller *ctrlr)
 }
 
 static void
-nvme_ctrlr_fail(struct nvme_controller *ctrlr)
+nvme_ctrlr_fail(struct spdk_nvme_ctrlr *ctrlr)
 {
 	uint32_t i;
 
@@ -236,11 +248,11 @@ nvme_ctrlr_fail(struct nvme_controller *ctrlr)
 }
 
 static int
-_nvme_ctrlr_wait_for_ready(struct nvme_controller *ctrlr, int desired_ready_value)
+_nvme_ctrlr_wait_for_ready(struct spdk_nvme_ctrlr *ctrlr, int desired_ready_value)
 {
 	int ms_waited, ready_timeout_in_ms;
-	union nvme_csts_register csts;
-	union nvme_cap_lo_register cap_lo;
+	union spdk_nvme_csts_register csts;
+	union spdk_nvme_cap_lo_register cap_lo;
 
 	/* Get ready timeout value from controller, in units of 500ms. */
 	cap_lo.raw = nvme_mmio_read_4(ctrlr, cap_lo.raw);
@@ -264,9 +276,9 @@ _nvme_ctrlr_wait_for_ready(struct nvme_controller *ctrlr, int desired_ready_valu
 }
 
 static int
-nvme_ctrlr_wait_for_ready(struct nvme_controller *ctrlr)
+nvme_ctrlr_wait_for_ready(struct spdk_nvme_ctrlr *ctrlr)
 {
-	union nvme_cc_register cc;
+	union spdk_nvme_cc_register cc;
 
 	cc.raw = nvme_mmio_read_4(ctrlr, cc.raw);
 
@@ -279,10 +291,10 @@ nvme_ctrlr_wait_for_ready(struct nvme_controller *ctrlr)
 }
 
 static void
-nvme_ctrlr_disable(struct nvme_controller *ctrlr)
+nvme_ctrlr_disable(struct spdk_nvme_ctrlr *ctrlr)
 {
-	union nvme_cc_register cc;
-	union nvme_csts_register csts;
+	union spdk_nvme_cc_register cc;
+	union spdk_nvme_csts_register csts;
 
 	cc.raw = nvme_mmio_read_4(ctrlr, cc.raw);
 	csts.raw = nvme_mmio_read_4(ctrlr, csts);
@@ -298,14 +310,14 @@ nvme_ctrlr_disable(struct nvme_controller *ctrlr)
 }
 
 static void
-nvme_ctrlr_shutdown(struct nvme_controller *ctrlr)
+nvme_ctrlr_shutdown(struct spdk_nvme_ctrlr *ctrlr)
 {
-	union nvme_cc_register		cc;
-	union nvme_csts_register	csts;
+	union spdk_nvme_cc_register	cc;
+	union spdk_nvme_csts_register	csts;
 	int				ms_waited = 0;
 
 	cc.raw = nvme_mmio_read_4(ctrlr, cc.raw);
-	cc.bits.shn = NVME_SHN_NORMAL;
+	cc.bits.shn = SPDK_NVME_SHN_NORMAL;
 	nvme_mmio_write_4(ctrlr, cc.raw, cc.raw);
 
 	csts.raw = nvme_mmio_read_4(ctrlr, csts);
@@ -315,22 +327,22 @@ nvme_ctrlr_shutdown(struct nvme_controller *ctrlr)
 	 *  5 seconds as a reasonable amount of time to
 	 *  wait before proceeding.
 	 */
-	while (csts.bits.shst != NVME_SHST_COMPLETE) {
+	while (csts.bits.shst != SPDK_NVME_SHST_COMPLETE) {
 		nvme_delay(1000);
 		csts.raw = nvme_mmio_read_4(ctrlr, csts);
 		if (ms_waited++ >= 5000)
 			break;
 	}
-	if (csts.bits.shst != NVME_SHST_COMPLETE)
+	if (csts.bits.shst != SPDK_NVME_SHST_COMPLETE)
 		nvme_printf(ctrlr, "did not shutdown within 5 seconds\n");
 }
 
 static int
-nvme_ctrlr_enable(struct nvme_controller *ctrlr)
+nvme_ctrlr_enable(struct spdk_nvme_ctrlr *ctrlr)
 {
-	union nvme_cc_register		cc;
-	union nvme_csts_register	csts;
-	union nvme_aqa_register		aqa;
+	union spdk_nvme_cc_register	cc;
+	union spdk_nvme_csts_register	csts;
+	union spdk_nvme_aqa_register	aqa;
 
 	cc.raw = nvme_mmio_read_4(ctrlr, cc.raw);
 	csts.raw = nvme_mmio_read_4(ctrlr, csts);
@@ -368,11 +380,11 @@ nvme_ctrlr_enable(struct nvme_controller *ctrlr)
 }
 
 static int
-nvme_ctrlr_hw_reset(struct nvme_controller *ctrlr)
+nvme_ctrlr_hw_reset(struct spdk_nvme_ctrlr *ctrlr)
 {
 	uint32_t i;
 	int rc;
-	union nvme_cc_register cc;
+	union spdk_nvme_cc_register cc;
 
 	cc.raw = nvme_mmio_read_4(ctrlr, cc.raw);
 	if (cc.bits.en) {
@@ -396,7 +408,7 @@ nvme_ctrlr_hw_reset(struct nvme_controller *ctrlr)
 }
 
 int
-nvme_ctrlr_reset(struct nvme_controller *ctrlr)
+spdk_nvme_ctrlr_reset(struct spdk_nvme_ctrlr *ctrlr)
 {
 	int rc;
 
@@ -429,7 +441,7 @@ nvme_ctrlr_reset(struct nvme_controller *ctrlr)
 }
 
 static int
-nvme_ctrlr_identify(struct nvme_controller *ctrlr)
+nvme_ctrlr_identify(struct spdk_nvme_ctrlr *ctrlr)
 {
 	struct nvme_completion_poll_status	status;
 
@@ -439,7 +451,7 @@ nvme_ctrlr_identify(struct nvme_controller *ctrlr)
 	while (status.done == false) {
 		nvme_qpair_process_completions(&ctrlr->adminq, 0);
 	}
-	if (nvme_completion_is_error(&status.cpl)) {
+	if (spdk_nvme_cpl_is_error(&status.cpl)) {
 		nvme_printf(ctrlr, "nvme_identify_controller failed!\n");
 		return ENXIO;
 	}
@@ -457,7 +469,7 @@ nvme_ctrlr_identify(struct nvme_controller *ctrlr)
 }
 
 static int
-nvme_ctrlr_set_num_qpairs(struct nvme_controller *ctrlr)
+nvme_ctrlr_set_num_qpairs(struct spdk_nvme_ctrlr *ctrlr)
 {
 	struct nvme_driver			*driver = &g_nvme_driver;
 	struct nvme_completion_poll_status	status;
@@ -475,7 +487,7 @@ nvme_ctrlr_set_num_qpairs(struct nvme_controller *ctrlr)
 	while (status.done == false) {
 		nvme_qpair_process_completions(&ctrlr->adminq, 0);
 	}
-	if (nvme_completion_is_error(&status.cpl)) {
+	if (spdk_nvme_cpl_is_error(&status.cpl)) {
 		nvme_printf(ctrlr, "nvme_set_num_queues failed!\n");
 		return ENXIO;
 	}
@@ -498,7 +510,7 @@ nvme_ctrlr_set_num_qpairs(struct nvme_controller *ctrlr)
 }
 
 static int
-nvme_ctrlr_create_qpairs(struct nvme_controller *ctrlr)
+nvme_ctrlr_create_qpairs(struct spdk_nvme_ctrlr *ctrlr)
 {
 	struct nvme_completion_poll_status	status;
 	struct nvme_qpair			*qpair;
@@ -518,7 +530,7 @@ nvme_ctrlr_create_qpairs(struct nvme_controller *ctrlr)
 		while (status.done == false) {
 			nvme_qpair_process_completions(&ctrlr->adminq, 0);
 		}
-		if (nvme_completion_is_error(&status.cpl)) {
+		if (spdk_nvme_cpl_is_error(&status.cpl)) {
 			nvme_printf(ctrlr, "nvme_create_io_cq failed!\n");
 			return ENXIO;
 		}
@@ -529,7 +541,7 @@ nvme_ctrlr_create_qpairs(struct nvme_controller *ctrlr)
 		while (status.done == false) {
 			nvme_qpair_process_completions(&ctrlr->adminq, 0);
 		}
-		if (nvme_completion_is_error(&status.cpl)) {
+		if (spdk_nvme_cpl_is_error(&status.cpl)) {
 			nvme_printf(ctrlr, "nvme_create_io_sq failed!\n");
 			return ENXIO;
 		}
@@ -541,7 +553,7 @@ nvme_ctrlr_create_qpairs(struct nvme_controller *ctrlr)
 }
 
 static void
-nvme_ctrlr_destruct_namespaces(struct nvme_controller *ctrlr)
+nvme_ctrlr_destruct_namespaces(struct spdk_nvme_ctrlr *ctrlr)
 {
 	if (ctrlr->ns) {
 		uint32_t i, num_ns = ctrlr->num_ns;
@@ -562,7 +574,7 @@ nvme_ctrlr_destruct_namespaces(struct nvme_controller *ctrlr)
 }
 
 static int
-nvme_ctrlr_construct_namespaces(struct nvme_controller *ctrlr)
+nvme_ctrlr_construct_namespaces(struct spdk_nvme_ctrlr *ctrlr)
 {
 	uint32_t i, nn = ctrlr->cdata.nn;
 	uint64_t phys_addr = 0;
@@ -578,13 +590,13 @@ nvme_ctrlr_construct_namespaces(struct nvme_controller *ctrlr)
 	if (nn != ctrlr->num_ns) {
 		nvme_ctrlr_destruct_namespaces(ctrlr);
 
-		ctrlr->ns = calloc(nn, sizeof(struct nvme_namespace));
+		ctrlr->ns = calloc(nn, sizeof(struct spdk_nvme_ns));
 		if (ctrlr->ns == NULL) {
 			goto fail;
 		}
 
 		ctrlr->nsdata = nvme_malloc("nvme_namespaces",
-					    nn * sizeof(struct nvme_namespace_data), 64,
+					    nn * sizeof(struct spdk_nvme_ns_data), 64,
 					    &phys_addr);
 		if (ctrlr->nsdata == NULL) {
 			goto fail;
@@ -594,7 +606,7 @@ nvme_ctrlr_construct_namespaces(struct nvme_controller *ctrlr)
 	}
 
 	for (i = 0; i < nn; i++) {
-		struct nvme_namespace	*ns = &ctrlr->ns[i];
+		struct spdk_nvme_ns	*ns = &ctrlr->ns[i];
 		uint32_t 		nsid = i + 1;
 
 		if (nvme_ns_construct(ns, nsid, ctrlr) != 0) {
@@ -610,12 +622,12 @@ fail:
 }
 
 static void
-nvme_ctrlr_async_event_cb(void *arg, const struct nvme_completion *cpl)
+nvme_ctrlr_async_event_cb(void *arg, const struct spdk_nvme_cpl *cpl)
 {
 	struct nvme_async_event_request	*aer = arg;
-	struct nvme_controller		*ctrlr = aer->ctrlr;
+	struct spdk_nvme_ctrlr		*ctrlr = aer->ctrlr;
 
-	if (cpl->status.sc == NVME_SC_ABORTED_SQ_DELETION) {
+	if (cpl->status.sc == SPDK_NVME_SC_ABORTED_SQ_DELETION) {
 		/*
 		 *  This is simulated when controller is being shut down, to
 		 *  effectively abort outstanding asynchronous event requests
@@ -643,7 +655,7 @@ nvme_ctrlr_async_event_cb(void *arg, const struct nvme_completion *cpl)
 }
 
 static int
-nvme_ctrlr_construct_and_submit_aer(struct nvme_controller *ctrlr,
+nvme_ctrlr_construct_and_submit_aer(struct spdk_nvme_ctrlr *ctrlr,
 				    struct nvme_async_event_request *aer)
 {
 	struct nvme_request *req;
@@ -660,16 +672,16 @@ nvme_ctrlr_construct_and_submit_aer(struct nvme_controller *ctrlr,
 	 *  nature never be timed out.
 	 */
 	req->timeout = false;
-	req->cmd.opc = NVME_OPC_ASYNC_EVENT_REQUEST;
+	req->cmd.opc = SPDK_NVME_OPC_ASYNC_EVENT_REQUEST;
 	nvme_ctrlr_submit_admin_request(ctrlr, req);
 
 	return 0;
 }
 
 static int
-nvme_ctrlr_configure_aer(struct nvme_controller *ctrlr)
+nvme_ctrlr_configure_aer(struct spdk_nvme_ctrlr *ctrlr)
 {
-	union nvme_critical_warning_state	state;
+	union spdk_nvme_critical_warning_state	state;
 	struct nvme_async_event_request		*aer;
 	uint32_t				i;
 	struct nvme_completion_poll_status	status;
@@ -683,7 +695,7 @@ nvme_ctrlr_configure_aer(struct nvme_controller *ctrlr)
 	while (status.done == false) {
 		nvme_qpair_process_completions(&ctrlr->adminq, 0);
 	}
-	if (nvme_completion_is_error(&status.cpl)) {
+	if (spdk_nvme_cpl_is_error(&status.cpl)) {
 		nvme_printf(ctrlr, "nvme_ctrlr_cmd_set_async_event_config failed!\n");
 		return ENXIO;
 	}
@@ -703,7 +715,7 @@ nvme_ctrlr_configure_aer(struct nvme_controller *ctrlr)
 }
 
 int
-nvme_ctrlr_start(struct nvme_controller *ctrlr)
+nvme_ctrlr_start(struct spdk_nvme_ctrlr *ctrlr)
 {
 	if (nvme_ctrlr_hw_reset(ctrlr) != 0) {
 		return -1;
@@ -739,13 +751,13 @@ nvme_ctrlr_start(struct nvme_controller *ctrlr)
 }
 
 static int
-nvme_ctrlr_allocate_bars(struct nvme_controller *ctrlr)
+nvme_ctrlr_allocate_bars(struct spdk_nvme_ctrlr *ctrlr)
 {
 	int rc;
 	void *addr;
 
 	rc = nvme_pcicfg_map_bar(ctrlr->devhandle, 0, 0 /* writable */, &addr);
-	ctrlr->regs = (volatile struct nvme_registers *)addr;
+	ctrlr->regs = (volatile struct spdk_nvme_registers *)addr;
 	if ((ctrlr->regs == NULL) || (rc != 0)) {
 		nvme_printf(ctrlr, "pci_device_map_range failed with error code %d\n", rc);
 		return -1;
@@ -755,7 +767,7 @@ nvme_ctrlr_allocate_bars(struct nvme_controller *ctrlr)
 }
 
 static int
-nvme_ctrlr_free_bars(struct nvme_controller *ctrlr)
+nvme_ctrlr_free_bars(struct spdk_nvme_ctrlr *ctrlr)
 {
 	int rc = 0;
 	void *addr = (void *)ctrlr->regs;
@@ -767,9 +779,9 @@ nvme_ctrlr_free_bars(struct nvme_controller *ctrlr)
 }
 
 int
-nvme_ctrlr_construct(struct nvme_controller *ctrlr, void *devhandle)
+nvme_ctrlr_construct(struct spdk_nvme_ctrlr *ctrlr, void *devhandle)
 {
-	union nvme_cap_hi_register	cap_hi;
+	union spdk_nvme_cap_hi_register	cap_hi;
 	uint32_t			cmd_reg;
 	int				status;
 	int				rc;
@@ -807,7 +819,7 @@ nvme_ctrlr_construct(struct nvme_controller *ctrlr, void *devhandle)
 }
 
 void
-nvme_ctrlr_destruct(struct nvme_controller *ctrlr)
+nvme_ctrlr_destruct(struct spdk_nvme_ctrlr *ctrlr)
 {
 	uint32_t	i;
 
@@ -829,14 +841,14 @@ nvme_ctrlr_destruct(struct nvme_controller *ctrlr)
 }
 
 void
-nvme_ctrlr_submit_admin_request(struct nvme_controller *ctrlr,
+nvme_ctrlr_submit_admin_request(struct spdk_nvme_ctrlr *ctrlr,
 				struct nvme_request *req)
 {
 	nvme_qpair_submit_request(&ctrlr->adminq, req);
 }
 
 void
-nvme_ctrlr_submit_io_request(struct nvme_controller *ctrlr,
+nvme_ctrlr_submit_io_request(struct spdk_nvme_ctrlr *ctrlr,
 			     struct nvme_request *req)
 {
 	struct nvme_qpair       *qpair;
@@ -848,14 +860,14 @@ nvme_ctrlr_submit_io_request(struct nvme_controller *ctrlr,
 }
 
 int32_t
-nvme_ctrlr_process_io_completions(struct nvme_controller *ctrlr, uint32_t max_completions)
+spdk_nvme_ctrlr_process_io_completions(struct spdk_nvme_ctrlr *ctrlr, uint32_t max_completions)
 {
 	nvme_assert(nvme_thread_ioq_index >= 0, ("no ioq_index assigned for thread\n"));
 	return nvme_qpair_process_completions(&ctrlr->ioq[nvme_thread_ioq_index], max_completions);
 }
 
 int32_t
-nvme_ctrlr_process_admin_completions(struct nvme_controller *ctrlr)
+spdk_nvme_ctrlr_process_admin_completions(struct spdk_nvme_ctrlr *ctrlr)
 {
 	int32_t num_completions;
 
@@ -866,21 +878,20 @@ nvme_ctrlr_process_admin_completions(struct nvme_controller *ctrlr)
 	return num_completions;
 }
 
-const struct nvme_controller_data *
-nvme_ctrlr_get_data(struct nvme_controller *ctrlr)
+const struct spdk_nvme_ctrlr_data *
+spdk_nvme_ctrlr_get_data(struct spdk_nvme_ctrlr *ctrlr)
 {
-
 	return &ctrlr->cdata;
 }
 
 uint32_t
-nvme_ctrlr_get_num_ns(struct nvme_controller *ctrlr)
+spdk_nvme_ctrlr_get_num_ns(struct spdk_nvme_ctrlr *ctrlr)
 {
 	return ctrlr->num_ns;
 }
 
-struct nvme_namespace *
-nvme_ctrlr_get_ns(struct nvme_controller *ctrlr, uint32_t ns_id)
+struct spdk_nvme_ns *
+spdk_nvme_ctrlr_get_ns(struct spdk_nvme_ctrlr *ctrlr, uint32_t ns_id)
 {
 	if (ns_id < 1 || ns_id > ctrlr->num_ns) {
 		return NULL;
@@ -890,16 +901,16 @@ nvme_ctrlr_get_ns(struct nvme_controller *ctrlr, uint32_t ns_id)
 }
 
 void
-nvme_ctrlr_register_aer_callback(struct nvme_controller *ctrlr,
-				 nvme_aer_cb_fn_t aer_cb_fn,
-				 void *aer_cb_arg)
+spdk_nvme_ctrlr_register_aer_callback(struct spdk_nvme_ctrlr *ctrlr,
+				      spdk_nvme_aer_cb aer_cb_fn,
+				      void *aer_cb_arg)
 {
 	ctrlr->aer_cb_fn = aer_cb_fn;
 	ctrlr->aer_cb_arg = aer_cb_arg;
 }
 
 bool
-nvme_ctrlr_is_log_page_supported(struct nvme_controller *ctrlr, uint8_t log_page)
+spdk_nvme_ctrlr_is_log_page_supported(struct spdk_nvme_ctrlr *ctrlr, uint8_t log_page)
 {
 	/* No bounds check necessary, since log_page is uint8_t and log_page_supported has 256 entries */
 	SPDK_STATIC_ASSERT(sizeof(ctrlr->log_page_supported) == 256, "log_page_supported size mismatch");
@@ -907,7 +918,7 @@ nvme_ctrlr_is_log_page_supported(struct nvme_controller *ctrlr, uint8_t log_page
 }
 
 bool
-nvme_ctrlr_is_feature_supported(struct nvme_controller *ctrlr, uint8_t feature_code)
+spdk_nvme_ctrlr_is_feature_supported(struct spdk_nvme_ctrlr *ctrlr, uint8_t feature_code)
 {
 	/* No bounds check necessary, since feature_code is uint8_t and feature_supported has 256 entries */
 	SPDK_STATIC_ASSERT(sizeof(ctrlr->feature_supported) == 256, "feature_supported size mismatch");
diff --git a/src/spdk/lib/nvme/nvme_ctrlr_cmd.c b/src/spdk/lib/nvme/nvme_ctrlr_cmd.c
index 564349c..f349ddd 100644
--- a/src/spdk/lib/nvme/nvme_ctrlr_cmd.c
+++ b/src/spdk/lib/nvme/nvme_ctrlr_cmd.c
@@ -34,10 +34,10 @@
 #include "nvme_internal.h"
 
 int
-nvme_ctrlr_cmd_io_raw(struct nvme_controller *ctrlr,
-		      struct nvme_command *cmd,
-		      void *buf, uint32_t len,
-		      nvme_cb_fn_t cb_fn, void *cb_arg)
+spdk_nvme_ctrlr_cmd_io_raw(struct spdk_nvme_ctrlr *ctrlr,
+			   struct spdk_nvme_cmd *cmd,
+			   void *buf, uint32_t len,
+			   spdk_nvme_cmd_cb cb_fn, void *cb_arg)
 {
 	struct nvme_request	*req;
 
@@ -54,10 +54,10 @@ nvme_ctrlr_cmd_io_raw(struct nvme_controller *ctrlr,
 }
 
 int
-nvme_ctrlr_cmd_admin_raw(struct nvme_controller *ctrlr,
-			 struct nvme_command *cmd,
-			 void *buf, uint32_t len,
-			 nvme_cb_fn_t cb_fn, void *cb_arg)
+spdk_nvme_ctrlr_cmd_admin_raw(struct spdk_nvme_ctrlr *ctrlr,
+			      struct spdk_nvme_cmd *cmd,
+			      void *buf, uint32_t len,
+			      spdk_nvme_cmd_cb cb_fn, void *cb_arg)
 {
 	struct nvme_request	*req;
 
@@ -77,18 +77,18 @@ nvme_ctrlr_cmd_admin_raw(struct nvme_controller *ctrlr,
 }
 
 void
-nvme_ctrlr_cmd_identify_controller(struct nvme_controller *ctrlr, void *payload,
-				   nvme_cb_fn_t cb_fn, void *cb_arg)
+nvme_ctrlr_cmd_identify_controller(struct spdk_nvme_ctrlr *ctrlr, void *payload,
+				   spdk_nvme_cmd_cb cb_fn, void *cb_arg)
 {
 	struct nvme_request *req;
-	struct nvme_command *cmd;
+	struct spdk_nvme_cmd *cmd;
 
 	req = nvme_allocate_request_contig(payload,
-					   sizeof(struct nvme_controller_data),
+					   sizeof(struct spdk_nvme_ctrlr_data),
 					   cb_fn, cb_arg);
 
 	cmd = &req->cmd;
-	cmd->opc = NVME_OPC_IDENTIFY;
+	cmd->opc = SPDK_NVME_OPC_IDENTIFY;
 
 	/*
 	 * TODO: create an identify command data structure, which
@@ -100,18 +100,18 @@ nvme_ctrlr_cmd_identify_controller(struct nvme_controller *ctrlr, void *payload,
 }
 
 void
-nvme_ctrlr_cmd_identify_namespace(struct nvme_controller *ctrlr, uint16_t nsid,
-				  void *payload, nvme_cb_fn_t cb_fn, void *cb_arg)
+nvme_ctrlr_cmd_identify_namespace(struct spdk_nvme_ctrlr *ctrlr, uint16_t nsid,
+				  void *payload, spdk_nvme_cmd_cb cb_fn, void *cb_arg)
 {
 	struct nvme_request *req;
-	struct nvme_command *cmd;
+	struct spdk_nvme_cmd *cmd;
 
 	req = nvme_allocate_request_contig(payload,
-					   sizeof(struct nvme_namespace_data),
+					   sizeof(struct spdk_nvme_ns_data),
 					   cb_fn, cb_arg);
 
 	cmd = &req->cmd;
-	cmd->opc = NVME_OPC_IDENTIFY;
+	cmd->opc = SPDK_NVME_OPC_IDENTIFY;
 
 	/*
 	 * TODO: create an identify command data structure
@@ -122,17 +122,17 @@ nvme_ctrlr_cmd_identify_namespace(struct nvme_controller *ctrlr, uint16_t nsid,
 }
 
 void
-nvme_ctrlr_cmd_create_io_cq(struct nvme_controller *ctrlr,
-			    struct nvme_qpair *io_que, nvme_cb_fn_t cb_fn,
+nvme_ctrlr_cmd_create_io_cq(struct spdk_nvme_ctrlr *ctrlr,
+			    struct nvme_qpair *io_que, spdk_nvme_cmd_cb cb_fn,
 			    void *cb_arg)
 {
 	struct nvme_request *req;
-	struct nvme_command *cmd;
+	struct spdk_nvme_cmd *cmd;
 
 	req = nvme_allocate_request_null(cb_fn, cb_arg);
 
 	cmd = &req->cmd;
-	cmd->opc = NVME_OPC_CREATE_IO_CQ;
+	cmd->opc = SPDK_NVME_OPC_CREATE_IO_CQ;
 
 	/*
 	 * TODO: create a create io completion queue command data
@@ -150,16 +150,16 @@ nvme_ctrlr_cmd_create_io_cq(struct nvme_controller *ctrlr,
 }
 
 void
-nvme_ctrlr_cmd_create_io_sq(struct nvme_controller *ctrlr,
-			    struct nvme_qpair *io_que, nvme_cb_fn_t cb_fn, void *cb_arg)
+nvme_ctrlr_cmd_create_io_sq(struct spdk_nvme_ctrlr *ctrlr,
+			    struct nvme_qpair *io_que, spdk_nvme_cmd_cb cb_fn, void *cb_arg)
 {
 	struct nvme_request *req;
-	struct nvme_command *cmd;
+	struct spdk_nvme_cmd *cmd;
 
 	req = nvme_allocate_request_null(cb_fn, cb_arg);
 
 	cmd = &req->cmd;
-	cmd->opc = NVME_OPC_CREATE_IO_SQ;
+	cmd->opc = SPDK_NVME_OPC_CREATE_IO_SQ;
 
 	/*
 	 * TODO: create a create io submission queue command data
@@ -174,12 +174,12 @@ nvme_ctrlr_cmd_create_io_sq(struct nvme_controller *ctrlr,
 }
 
 int
-nvme_ctrlr_cmd_set_feature(struct nvme_controller *ctrlr, uint8_t feature,
-			   uint32_t cdw11, uint32_t cdw12, void *payload, uint32_t payload_size,
-			   nvme_cb_fn_t cb_fn, void *cb_arg)
+spdk_nvme_ctrlr_cmd_set_feature(struct spdk_nvme_ctrlr *ctrlr, uint8_t feature,
+				uint32_t cdw11, uint32_t cdw12, void *payload, uint32_t payload_size,
+				spdk_nvme_cmd_cb cb_fn, void *cb_arg)
 {
 	struct nvme_request *req;
-	struct nvme_command *cmd;
+	struct spdk_nvme_cmd *cmd;
 
 	nvme_mutex_lock(&ctrlr->ctrlr_lock);
 	req = nvme_allocate_request_null(cb_fn, cb_arg);
@@ -189,7 +189,7 @@ nvme_ctrlr_cmd_set_feature(struct nvme_controller *ctrlr, uint8_t feature,
 	}
 
 	cmd = &req->cmd;
-	cmd->opc = NVME_OPC_SET_FEATURES;
+	cmd->opc = SPDK_NVME_OPC_SET_FEATURES;
 	cmd->cdw10 = feature;
 	cmd->cdw11 = cdw11;
 	cmd->cdw12 = cdw12;
@@ -201,12 +201,12 @@ nvme_ctrlr_cmd_set_feature(struct nvme_controller *ctrlr, uint8_t feature,
 }
 
 int
-nvme_ctrlr_cmd_get_feature(struct nvme_controller *ctrlr, uint8_t feature,
-			   uint32_t cdw11, void *payload, uint32_t payload_size,
-			   nvme_cb_fn_t cb_fn, void *cb_arg)
+spdk_nvme_ctrlr_cmd_get_feature(struct spdk_nvme_ctrlr *ctrlr, uint8_t feature,
+				uint32_t cdw11, void *payload, uint32_t payload_size,
+				spdk_nvme_cmd_cb cb_fn, void *cb_arg)
 {
 	struct nvme_request *req;
-	struct nvme_command *cmd;
+	struct spdk_nvme_cmd *cmd;
 
 	nvme_mutex_lock(&ctrlr->ctrlr_lock);
 	req = nvme_allocate_request_null(cb_fn, cb_arg);
@@ -216,7 +216,7 @@ nvme_ctrlr_cmd_get_feature(struct nvme_controller *ctrlr, uint8_t feature,
 	}
 
 	cmd = &req->cmd;
-	cmd->opc = NVME_OPC_GET_FEATURES;
+	cmd->opc = SPDK_NVME_OPC_GET_FEATURES;
 	cmd->cdw10 = feature;
 	cmd->cdw11 = cdw11;
 
@@ -227,36 +227,35 @@ nvme_ctrlr_cmd_get_feature(struct nvme_controller *ctrlr, uint8_t feature,
 }
 
 void
-nvme_ctrlr_cmd_set_num_queues(struct nvme_controller *ctrlr,
-			      uint32_t num_queues, nvme_cb_fn_t cb_fn, void *cb_arg)
+nvme_ctrlr_cmd_set_num_queues(struct spdk_nvme_ctrlr *ctrlr,
+			      uint32_t num_queues, spdk_nvme_cmd_cb cb_fn, void *cb_arg)
 {
 	uint32_t cdw11;
 
 	cdw11 = ((num_queues - 1) << 16) | (num_queues - 1);
-	nvme_ctrlr_cmd_set_feature(ctrlr, NVME_FEAT_NUMBER_OF_QUEUES, cdw11, 0,
-				   NULL, 0, cb_fn, cb_arg);
+	spdk_nvme_ctrlr_cmd_set_feature(ctrlr, SPDK_NVME_FEAT_NUMBER_OF_QUEUES, cdw11, 0,
+					NULL, 0, cb_fn, cb_arg);
 }
 
 void
-nvme_ctrlr_cmd_set_async_event_config(struct nvme_controller *ctrlr,
-				      union nvme_critical_warning_state state, nvme_cb_fn_t cb_fn,
+nvme_ctrlr_cmd_set_async_event_config(struct spdk_nvme_ctrlr *ctrlr,
+				      union spdk_nvme_critical_warning_state state, spdk_nvme_cmd_cb cb_fn,
 				      void *cb_arg)
 {
 	uint32_t cdw11;
 
 	cdw11 = state.raw;
-	nvme_ctrlr_cmd_set_feature(ctrlr,
-				   NVME_FEAT_ASYNC_EVENT_CONFIGURATION, cdw11, 0, NULL, 0, cb_fn,
-				   cb_arg);
+	spdk_nvme_ctrlr_cmd_set_feature(ctrlr, SPDK_NVME_FEAT_ASYNC_EVENT_CONFIGURATION, cdw11, 0, NULL, 0,
+					cb_fn, cb_arg);
 }
 
 int
-nvme_ctrlr_cmd_get_log_page(struct nvme_controller *ctrlr, uint8_t log_page,
-			    uint32_t nsid, void *payload, uint32_t payload_size, nvme_cb_fn_t cb_fn,
-			    void *cb_arg)
+spdk_nvme_ctrlr_cmd_get_log_page(struct spdk_nvme_ctrlr *ctrlr, uint8_t log_page,
+				 uint32_t nsid, void *payload, uint32_t payload_size, spdk_nvme_cmd_cb cb_fn,
+				 void *cb_arg)
 {
 	struct nvme_request *req;
-	struct nvme_command *cmd;
+	struct spdk_nvme_cmd *cmd;
 
 	nvme_mutex_lock(&ctrlr->ctrlr_lock);
 	req = nvme_allocate_request_contig(payload, payload_size, cb_fn, cb_arg);
@@ -266,7 +265,7 @@ nvme_ctrlr_cmd_get_log_page(struct nvme_controller *ctrlr, uint8_t log_page,
 	}
 
 	cmd = &req->cmd;
-	cmd->opc = NVME_OPC_GET_LOG_PAGE;
+	cmd->opc = SPDK_NVME_OPC_GET_LOG_PAGE;
 	cmd->nsid = nsid;
 	cmd->cdw10 = ((payload_size / sizeof(uint32_t)) - 1) << 16;
 	cmd->cdw10 |= log_page;
@@ -278,16 +277,16 @@ nvme_ctrlr_cmd_get_log_page(struct nvme_controller *ctrlr, uint8_t log_page,
 }
 
 void
-nvme_ctrlr_cmd_abort(struct nvme_controller *ctrlr, uint16_t cid,
-		     uint16_t sqid, nvme_cb_fn_t cb_fn, void *cb_arg)
+nvme_ctrlr_cmd_abort(struct spdk_nvme_ctrlr *ctrlr, uint16_t cid,
+		     uint16_t sqid, spdk_nvme_cmd_cb cb_fn, void *cb_arg)
 {
 	struct nvme_request *req;
-	struct nvme_command *cmd;
+	struct spdk_nvme_cmd *cmd;
 
 	req = nvme_allocate_request_null(cb_fn, cb_arg);
 
 	cmd = &req->cmd;
-	cmd->opc = NVME_OPC_ABORT;
+	cmd->opc = SPDK_NVME_OPC_ABORT;
 	cmd->cdw10 = (cid << 16) | sqid;
 
 	nvme_ctrlr_submit_admin_request(ctrlr, req);
diff --git a/src/spdk/lib/nvme/nvme_impl.h b/src/spdk/lib/nvme/nvme_impl.h
index 9c580c9..1b682b3 100644
--- a/src/spdk/lib/nvme/nvme_impl.h
+++ b/src/spdk/lib/nvme/nvme_impl.h
@@ -35,13 +35,24 @@
 #define __NVME_IMPL_H__
 
 #include "spdk/vtophys.h"
+#include "spdk/pci.h"
+#include "spdk/nvme_spec.h"
 #include <assert.h>
-#include <pciaccess.h>
-#include <rte_malloc.h>
 #include <rte_config.h>
+#include <rte_malloc.h>
 #include <rte_mempool.h>
 #include <rte_memcpy.h>
 
+#ifdef USE_PCIACCESS
+#include <pciaccess.h>
+#else
+#include <rte_pci.h>
+#endif
+
+#include "spdk/pci.h"
+#include "spdk/pci_ids.h"
+#include "spdk/nvme_spec.h"
+
 /**
  * \file
  *
@@ -98,8 +109,8 @@ nvme_malloc(const char *tag, size_t size, unsigned align, uint64_t *phys_addr)
 /**
  * Return the physical address for the specified virtual address.
  */
-#define nvme_vtophys(buf)		vtophys(buf)
-#define NVME_VTOPHYS_ERROR		VTOPHYS_ERROR
+#define nvme_vtophys(buf)		spdk_vtophys(buf)
+#define NVME_VTOPHYS_ERROR		SPDK_VTOPHYS_ERROR
 
 extern struct rte_mempool *request_mempool;
 
@@ -117,8 +128,38 @@ extern struct rte_mempool *request_mempool;
 /**
  *
  */
-#define nvme_pcicfg_read32(handle, var, offset)  pci_device_cfg_read_u32(handle, var, offset)
-#define nvme_pcicfg_write32(handle, var, offset) pci_device_cfg_write_u32(handle, var, offset)
+#define nvme_pcicfg_read32(handle, var, offset)  spdk_pci_device_cfg_read32(handle, var, offset)
+#define nvme_pcicfg_write32(handle, var, offset) spdk_pci_device_cfg_write32(handle, var, offset)
+
+struct nvme_pci_enum_ctx {
+	int (*user_enum_cb)(void *enum_ctx, struct spdk_pci_device *pci_dev);
+	void *user_enum_ctx;
+};
+
+#ifdef USE_PCIACCESS
+
+static int
+nvme_pci_enum_cb(void *enum_ctx, struct spdk_pci_device *pci_dev)
+{
+	struct nvme_pci_enum_ctx *ctx = enum_ctx;
+
+	if (spdk_pci_device_get_class(pci_dev) != SPDK_PCI_CLASS_NVME) {
+		return 0;
+	}
+
+	return ctx->user_enum_cb(ctx->user_enum_ctx, pci_dev);
+}
+
+static inline int
+nvme_pci_enumerate(int (*enum_cb)(void *enum_ctx, struct spdk_pci_device *pci_dev), void *enum_ctx)
+{
+	struct nvme_pci_enum_ctx nvme_enum_ctx;
+
+	nvme_enum_ctx.user_enum_cb = enum_cb;
+	nvme_enum_ctx.user_enum_ctx = enum_ctx;
+
+	return spdk_pci_enumerate(nvme_pci_enum_cb, &nvme_enum_ctx);
+}
 
 static inline int
 nvme_pcicfg_map_bar(void *devhandle, uint32_t bar, uint32_t read_only, void **mapped_addr)
@@ -138,6 +179,75 @@ nvme_pcicfg_unmap_bar(void *devhandle, uint32_t bar, void *addr)
 	return pci_device_unmap_range(dev, addr, dev->regions[bar].size);
 }
 
+#else /* !USE_PCIACCESS */
+
+static inline int
+nvme_pcicfg_map_bar(void *devhandle, uint32_t bar, uint32_t read_only, void **mapped_addr)
+{
+	struct rte_pci_device *dev = devhandle;
+
+	*mapped_addr = dev->mem_resource[bar].addr;
+	return 0;
+}
+
+static inline int
+nvme_pcicfg_unmap_bar(void *devhandle, uint32_t bar, void *addr)
+{
+	return 0;
+}
+
+/*
+ * TODO: once DPDK supports matching class code instead of device ID, switch to SPDK_PCI_CLASS_NVME
+ */
+static struct rte_pci_id nvme_pci_driver_id[] = {
+	{RTE_PCI_DEVICE(0x8086, 0x0953)},
+	{ .vendor_id = 0, /* sentinel */ },
+};
+
+/*
+ * TODO: eliminate this global if possible (does rte_pci_driver have a context field for this?)
+ *
+ * This should be protected by the NVMe driver lock, since nvme_probe() holds the lock
+ *  while calling nvme_pci_enumerate(), but we shouldn't have to depend on that.
+ */
+static struct nvme_pci_enum_ctx g_nvme_pci_enum_ctx;
+
+static int
+nvme_driver_init(struct rte_pci_driver *dr, struct rte_pci_device *rte_dev)
+{
+	/*
+	 * These are actually the same type internally.
+	 * TODO: refactor this so it's inside pci.c
+	 */
+	struct spdk_pci_device *pci_dev = (struct spdk_pci_device *)rte_dev;
+
+	return g_nvme_pci_enum_ctx.user_enum_cb(g_nvme_pci_enum_ctx.user_enum_ctx, pci_dev);
+}
+
+static struct rte_pci_driver nvme_rte_driver = {
+	.name = "nvme_driver",
+	.devinit = nvme_driver_init,
+	.id_table = nvme_pci_driver_id,
+	.drv_flags = RTE_PCI_DRV_NEED_MAPPING,
+};
+
+static inline int
+nvme_pci_enumerate(int (*enum_cb)(void *enum_ctx, struct spdk_pci_device *pci_dev), void *enum_ctx)
+{
+	int rc;
+
+	g_nvme_pci_enum_ctx.user_enum_cb = enum_cb;
+	g_nvme_pci_enum_ctx.user_enum_ctx = enum_ctx;
+
+	rte_eal_pci_register(&nvme_rte_driver);
+	rc = rte_eal_pci_probe();
+	rte_eal_pci_unregister(&nvme_rte_driver);
+
+	return rc;
+}
+
+#endif /* !USE_PCIACCESS */
+
 typedef pthread_mutex_t nvme_mutex_t;
 
 #define nvme_mutex_init(x) pthread_mutex_init((x), NULL)
@@ -166,6 +276,6 @@ nvme_mutex_init_recursive(nvme_mutex_t *mtx)
 /**
  * Copy a struct nvme_command from one memory location to another.
  */
-#define nvme_copy_command(dst, src)	rte_memcpy((dst), (src), sizeof(struct nvme_command))
+#define nvme_copy_command(dst, src)	rte_memcpy((dst), (src), sizeof(struct spdk_nvme_cmd))
 
 #endif /* __NVME_IMPL_H__ */
diff --git a/src/spdk/lib/nvme/nvme_internal.h b/src/spdk/lib/nvme/nvme_internal.h
index 338e531..4849afb 100644
--- a/src/spdk/lib/nvme/nvme_internal.h
+++ b/src/spdk/lib/nvme/nvme_internal.h
@@ -54,6 +54,19 @@
 #include "spdk/mmio.h"
 #include "spdk/pci_ids.h"
 #include "spdk/nvme_intel.h"
+#include "spdk/pci_ids.h"
+
+/*
+ * Some Intel devices support vendor-unique read latency log page even
+ * though the log page directory says otherwise.
+ */
+#define NVME_INTEL_QUIRK_READ_LATENCY 0x1
+
+/*
+ * Some Intel devices support vendor-unique write latency log page even
+ * though the log page directory says otherwise.
+ */
+#define NVME_INTEL_QUIRK_WRITE_LATENCY 0x2
 
 #define NVME_MAX_PRP_LIST_ENTRIES	(32)
 
@@ -129,8 +142,8 @@ struct __attribute__((packed)) nvme_payload {
 		 * Functions for retrieving physical addresses for scattered payloads.
 		 */
 		struct {
-			nvme_req_reset_sgl_fn_t reset_sgl_fn;
-			nvme_req_next_sge_fn_t next_sge_fn;
+			spdk_nvme_req_reset_sgl_cb reset_sgl_fn;
+			spdk_nvme_req_next_sge_cb next_sge_fn;
 		} sgl;
 	} u;
 
@@ -139,7 +152,7 @@ struct __attribute__((packed)) nvme_payload {
 };
 
 struct nvme_request {
-	struct nvme_command		cmd;
+	struct spdk_nvme_cmd		cmd;
 
 	/**
 	 * Data payload for this request's command.
@@ -162,7 +175,7 @@ struct nvme_request {
 	 */
 	uint32_t			payload_offset;
 
-	nvme_cb_fn_t			cb_fn;
+	spdk_nvme_cmd_cb		cb_fn;
 	void				*cb_arg;
 	STAILQ_ENTRY(nvme_request)	stailq;
 
@@ -199,18 +212,18 @@ struct nvme_request {
 	 *  to ensure that the parent request is also completed with error
 	 *  status once all child requests are completed.
 	 */
-	struct nvme_completion		parent_status;
+	struct spdk_nvme_cpl		parent_status;
 };
 
 struct nvme_completion_poll_status {
-	struct nvme_completion	cpl;
+	struct spdk_nvme_cpl	cpl;
 	bool			done;
 };
 
 struct nvme_async_event_request {
-	struct nvme_controller		*ctrlr;
+	struct spdk_nvme_ctrlr		*ctrlr;
 	struct nvme_request		*req;
-	struct nvme_completion		cpl;
+	struct spdk_nvme_cpl		cpl;
 };
 
 struct nvme_tracker {
@@ -230,12 +243,12 @@ struct nvme_qpair {
 	/**
 	 * Submission queue
 	 */
-	struct nvme_command		*cmd;
+	struct spdk_nvme_cmd		*cmd;
 
 	/**
 	 * Completion queue
 	 */
-	struct nvme_completion		*cpl;
+	struct spdk_nvme_cpl		*cpl;
 
 	LIST_HEAD(, nvme_tracker)	free_tr;
 	LIST_HEAD(, nvme_tracker)	outstanding_tr;
@@ -257,14 +270,14 @@ struct nvme_qpair {
 	/*
 	 * Fields below this point should not be touched on the normal I/O happy path.
 	 */
-	struct nvme_controller		*ctrlr;
+	struct spdk_nvme_ctrlr		*ctrlr;
 
 	uint64_t			cmd_bus_addr;
 	uint64_t			cpl_bus_addr;
 };
 
-struct nvme_namespace {
-	struct nvme_controller		*ctrlr;
+struct spdk_nvme_ns {
+	struct spdk_nvme_ctrlr		*ctrlr;
 	uint32_t			stripe_size;
 	uint32_t			sector_size;
 	uint32_t			sectors_per_max_io;
@@ -276,17 +289,17 @@ struct nvme_namespace {
 /*
  * One of these per allocated PCI device.
  */
-struct nvme_controller {
+struct spdk_nvme_ctrlr {
 	/* Hot data (accessed in I/O path) starts here. */
 
 	/** NVMe MMIO register space */
-	volatile struct nvme_registers	*regs;
+	volatile struct spdk_nvme_registers	*regs;
 
 	/** I/O queue pairs */
 	struct nvme_qpair		*ioq;
 
 	/** Array of namespaces indexed by nsid - 1 */
-	struct nvme_namespace		*ns;
+	struct spdk_nvme_ns		*ns;
 
 	uint32_t			num_ns;
 
@@ -296,6 +309,8 @@ struct nvme_controller {
 
 	/* Cold data (not accessed in normal I/O path) is after this point. */
 
+	TAILQ_ENTRY(spdk_nvme_ctrlr)	tailq;
+
 	/** All the log pages supported */
 	bool				log_page_supported[256];
 
@@ -303,7 +318,7 @@ struct nvme_controller {
 	bool				feature_supported[256];
 
 	/* Opaque handle to associated PCI device. */
-	void				*devhandle;
+	struct spdk_pci_device		*devhandle;
 
 	uint32_t			num_io_queues;
 
@@ -318,7 +333,7 @@ struct nvme_controller {
 
 	uint32_t			num_aers;
 	struct nvme_async_event_request	aer[NVME_MAX_ASYNC_EVENTS];
-	nvme_aer_cb_fn_t		aer_cb_fn;
+	spdk_nvme_aer_cb		aer_cb_fn;
 	void				*aer_cb_arg;
 
 	/** guards access to the controller itself, including admin queues */
@@ -330,14 +345,14 @@ struct nvme_controller {
 	/**
 	 * Identify Controller data.
 	 */
-	struct nvme_controller_data	cdata;
+	struct spdk_nvme_ctrlr_data	cdata;
 
 	/**
 	 * Array of Identify Namespace data.
 	 *
 	 * Stored separately from ns since nsdata should not normally be accessed during I/O.
 	 */
-	struct nvme_namespace_data	*nsdata;
+	struct spdk_nvme_ns_data	*nsdata;
 };
 
 extern __thread int nvme_thread_ioq_index;
@@ -347,6 +362,15 @@ struct nvme_driver {
 	uint16_t	*ioq_index_pool;
 	uint32_t	max_io_queues;
 	uint16_t	ioq_index_pool_next;
+	TAILQ_HEAD(, spdk_nvme_ctrlr)	init_ctrlrs;
+	TAILQ_HEAD(, spdk_nvme_ctrlr)	attached_ctrlrs;
+};
+
+struct pci_id {
+	uint16_t	vendor_id;
+	uint16_t	dev_id;
+	uint16_t	sub_vendor_id;
+	uint16_t	sub_dev_id;
 };
 
 extern struct nvme_driver g_nvme_driver;
@@ -383,44 +407,44 @@ nvme_align32pow2(uint32_t x)
 }
 
 /* Admin functions */
-void	nvme_ctrlr_cmd_identify_controller(struct nvme_controller *ctrlr,
+void	nvme_ctrlr_cmd_identify_controller(struct spdk_nvme_ctrlr *ctrlr,
 		void *payload,
-		nvme_cb_fn_t cb_fn, void *cb_arg);
-void	nvme_ctrlr_cmd_identify_namespace(struct nvme_controller *ctrlr,
+		spdk_nvme_cmd_cb cb_fn, void *cb_arg);
+void	nvme_ctrlr_cmd_identify_namespace(struct spdk_nvme_ctrlr *ctrlr,
 		uint16_t nsid, void *payload,
-		nvme_cb_fn_t cb_fn, void *cb_arg);
-void	nvme_ctrlr_cmd_create_io_cq(struct nvme_controller *ctrlr,
+		spdk_nvme_cmd_cb cb_fn, void *cb_arg);
+void	nvme_ctrlr_cmd_create_io_cq(struct spdk_nvme_ctrlr *ctrlr,
 				    struct nvme_qpair *io_que,
-				    nvme_cb_fn_t cb_fn, void *cb_arg);
-void	nvme_ctrlr_cmd_create_io_sq(struct nvme_controller *ctrlr,
+				    spdk_nvme_cmd_cb cb_fn, void *cb_arg);
+void	nvme_ctrlr_cmd_create_io_sq(struct spdk_nvme_ctrlr *ctrlr,
 				    struct nvme_qpair *io_que,
-				    nvme_cb_fn_t cb_fn, void *cb_arg);
-void	nvme_ctrlr_cmd_set_num_queues(struct nvme_controller *ctrlr,
-				      uint32_t num_queues, nvme_cb_fn_t cb_fn,
+				    spdk_nvme_cmd_cb cb_fn, void *cb_arg);
+void	nvme_ctrlr_cmd_set_num_queues(struct spdk_nvme_ctrlr *ctrlr,
+				      uint32_t num_queues, spdk_nvme_cmd_cb cb_fn,
 				      void *cb_arg);
-void	nvme_ctrlr_cmd_set_async_event_config(struct nvme_controller *ctrlr,
-		union nvme_critical_warning_state state,
-		nvme_cb_fn_t cb_fn, void *cb_arg);
-void	nvme_ctrlr_cmd_abort(struct nvme_controller *ctrlr, uint16_t cid,
-			     uint16_t sqid, nvme_cb_fn_t cb_fn, void *cb_arg);
+void	nvme_ctrlr_cmd_set_async_event_config(struct spdk_nvme_ctrlr *ctrlr,
+		union spdk_nvme_critical_warning_state state,
+		spdk_nvme_cmd_cb cb_fn, void *cb_arg);
+void	nvme_ctrlr_cmd_abort(struct spdk_nvme_ctrlr *ctrlr, uint16_t cid,
+			     uint16_t sqid, spdk_nvme_cmd_cb cb_fn, void *cb_arg);
 
-void	nvme_completion_poll_cb(void *arg, const struct nvme_completion *cpl);
+void	nvme_completion_poll_cb(void *arg, const struct spdk_nvme_cpl *cpl);
 
-int	nvme_ctrlr_construct(struct nvme_controller *ctrlr, void *devhandle);
-void	nvme_ctrlr_destruct(struct nvme_controller *ctrlr);
-int	nvme_ctrlr_start(struct nvme_controller *ctrlr);
+int	nvme_ctrlr_construct(struct spdk_nvme_ctrlr *ctrlr, void *devhandle);
+void	nvme_ctrlr_destruct(struct spdk_nvme_ctrlr *ctrlr);
+int	nvme_ctrlr_start(struct spdk_nvme_ctrlr *ctrlr);
 
-void	nvme_ctrlr_submit_admin_request(struct nvme_controller *ctrlr,
+void	nvme_ctrlr_submit_admin_request(struct spdk_nvme_ctrlr *ctrlr,
 					struct nvme_request *req);
-void	nvme_ctrlr_submit_io_request(struct nvme_controller *ctrlr,
+void	nvme_ctrlr_submit_io_request(struct spdk_nvme_ctrlr *ctrlr,
 				     struct nvme_request *req);
-void	nvme_ctrlr_post_failed_request(struct nvme_controller *ctrlr,
+void	nvme_ctrlr_post_failed_request(struct spdk_nvme_ctrlr *ctrlr,
 				       struct nvme_request *req);
 
 int	nvme_qpair_construct(struct nvme_qpair *qpair, uint16_t id,
 			     uint16_t num_entries,
 			     uint16_t num_trackers,
-			     struct nvme_controller *ctrlr);
+			     struct spdk_nvme_ctrlr *ctrlr);
 void	nvme_qpair_destroy(struct nvme_qpair *qpair);
 void	nvme_qpair_enable(struct nvme_qpair *qpair);
 void	nvme_qpair_disable(struct nvme_qpair *qpair);
@@ -430,15 +454,16 @@ void	nvme_qpair_submit_request(struct nvme_qpair *qpair,
 void	nvme_qpair_reset(struct nvme_qpair *qpair);
 void	nvme_qpair_fail(struct nvme_qpair *qpair);
 
-int	nvme_ns_construct(struct nvme_namespace *ns, uint16_t id,
-			  struct nvme_controller *ctrlr);
-void	nvme_ns_destruct(struct nvme_namespace *ns);
+int	nvme_ns_construct(struct spdk_nvme_ns *ns, uint16_t id,
+			  struct spdk_nvme_ctrlr *ctrlr);
+void	nvme_ns_destruct(struct spdk_nvme_ns *ns);
 
 struct nvme_request *nvme_allocate_request(const struct nvme_payload *payload,
-		uint32_t payload_size, nvme_cb_fn_t cb_fn, void *cb_arg);
-struct nvme_request *nvme_allocate_request_null(nvme_cb_fn_t cb_fn, void *cb_arg);
+		uint32_t payload_size, spdk_nvme_cmd_cb cb_fn, void *cb_arg);
+struct nvme_request *nvme_allocate_request_null(spdk_nvme_cmd_cb cb_fn, void *cb_arg);
 struct nvme_request *nvme_allocate_request_contig(void *buffer, uint32_t payload_size,
-		nvme_cb_fn_t cb_fn, void *cb_arg);
+		spdk_nvme_cmd_cb cb_fn, void *cb_arg);
 void	nvme_free_request(struct nvme_request *req);
+bool	nvme_intel_has_quirk(struct pci_id *id, uint64_t quirk);
 
 #endif /* __NVME_INTERNAL_H__ */
diff --git a/src/spdk/lib/nvme/nvme_ns.c b/src/spdk/lib/nvme/nvme_ns.c
index 6e2ff90..3c2a538 100644
--- a/src/spdk/lib/nvme/nvme_ns.c
+++ b/src/spdk/lib/nvme/nvme_ns.c
@@ -33,60 +33,60 @@
 
 #include "nvme_internal.h"
 
-static inline struct nvme_namespace_data *
-_nvme_ns_get_data(struct nvme_namespace *ns)
+static inline struct spdk_nvme_ns_data *
+_nvme_ns_get_data(struct spdk_nvme_ns *ns)
 {
 	return &ns->ctrlr->nsdata[ns->id - 1];
 }
 
 uint32_t
-nvme_ns_get_id(struct nvme_namespace *ns)
+spdk_nvme_ns_get_id(struct spdk_nvme_ns *ns)
 {
 	return ns->id;
 }
 
 uint32_t
-nvme_ns_get_max_io_xfer_size(struct nvme_namespace *ns)
+spdk_nvme_ns_get_max_io_xfer_size(struct spdk_nvme_ns *ns)
 {
 	return ns->ctrlr->max_xfer_size;
 }
 
 uint32_t
-nvme_ns_get_sector_size(struct nvme_namespace *ns)
+spdk_nvme_ns_get_sector_size(struct spdk_nvme_ns *ns)
 {
 	return ns->sector_size;
 }
 
 uint64_t
-nvme_ns_get_num_sectors(struct nvme_namespace *ns)
+spdk_nvme_ns_get_num_sectors(struct spdk_nvme_ns *ns)
 {
 	return _nvme_ns_get_data(ns)->nsze;
 }
 
 uint64_t
-nvme_ns_get_size(struct nvme_namespace *ns)
+spdk_nvme_ns_get_size(struct spdk_nvme_ns *ns)
 {
-	return nvme_ns_get_num_sectors(ns) * nvme_ns_get_sector_size(ns);
+	return spdk_nvme_ns_get_num_sectors(ns) * spdk_nvme_ns_get_sector_size(ns);
 }
 
 uint32_t
-nvme_ns_get_flags(struct nvme_namespace *ns)
+spdk_nvme_ns_get_flags(struct spdk_nvme_ns *ns)
 {
 	return ns->flags;
 }
 
-const struct nvme_namespace_data *
-nvme_ns_get_data(struct nvme_namespace *ns)
+const struct spdk_nvme_ns_data *
+spdk_nvme_ns_get_data(struct spdk_nvme_ns *ns)
 {
 	return _nvme_ns_get_data(ns);
 }
 
 int
-nvme_ns_construct(struct nvme_namespace *ns, uint16_t id,
-		  struct nvme_controller *ctrlr)
+nvme_ns_construct(struct spdk_nvme_ns *ns, uint16_t id,
+		  struct spdk_nvme_ctrlr *ctrlr)
 {
 	struct nvme_completion_poll_status	status;
-	struct nvme_namespace_data		*nsdata;
+	struct spdk_nvme_ns_data		*nsdata;
 	uint32_t				pci_devid;
 
 	nvme_assert(id > 0, ("invalid namespace id %d", id));
@@ -108,32 +108,36 @@ nvme_ns_construct(struct nvme_namespace *ns, uint16_t id,
 	while (status.done == false) {
 		nvme_qpair_process_completions(&ctrlr->adminq, 0);
 	}
-	if (nvme_completion_is_error(&status.cpl)) {
+	if (spdk_nvme_cpl_is_error(&status.cpl)) {
 		nvme_printf(ctrlr, "nvme_identify_namespace failed\n");
 		return ENXIO;
 	}
 
 	ns->sector_size = 1 << nsdata->lbaf[nsdata->flbas.format].lbads;
 
-	ns->sectors_per_max_io = nvme_ns_get_max_io_xfer_size(ns) / ns->sector_size;
+	ns->sectors_per_max_io = spdk_nvme_ns_get_max_io_xfer_size(ns) / ns->sector_size;
 	ns->sectors_per_stripe = ns->stripe_size / ns->sector_size;
 
 	if (ctrlr->cdata.oncs.dsm) {
-		ns->flags |= NVME_NS_DEALLOCATE_SUPPORTED;
+		ns->flags |= SPDK_NVME_NS_DEALLOCATE_SUPPORTED;
 	}
 
 	if (ctrlr->cdata.vwc.present) {
-		ns->flags |= NVME_NS_FLUSH_SUPPORTED;
+		ns->flags |= SPDK_NVME_NS_FLUSH_SUPPORTED;
+	}
+
+	if (ctrlr->cdata.oncs.write_zeroes) {
+		ns->flags |= SPDK_NVME_NS_WRITE_ZEROES_SUPPORTED;
 	}
 
 	if (nsdata->nsrescap.raw) {
-		ns->flags |= NVME_NS_RESERVATION_SUPPORTED;
+		ns->flags |= SPDK_NVME_NS_RESERVATION_SUPPORTED;
 	}
 
 	return 0;
 }
 
-void nvme_ns_destruct(struct nvme_namespace *ns)
+void nvme_ns_destruct(struct spdk_nvme_ns *ns)
 {
 
 }
diff --git a/src/spdk/lib/nvme/nvme_ns_cmd.c b/src/spdk/lib/nvme/nvme_ns_cmd.c
index 0ca5f60..bad9a80 100644
--- a/src/spdk/lib/nvme/nvme_ns_cmd.c
+++ b/src/spdk/lib/nvme/nvme_ns_cmd.c
@@ -38,13 +38,13 @@
  *
  */
 
-static struct nvme_request *_nvme_ns_cmd_rw(struct nvme_namespace *ns,
+static struct nvme_request *_nvme_ns_cmd_rw(struct spdk_nvme_ns *ns,
 		const struct nvme_payload *payload, uint64_t lba,
-		uint32_t lba_count, nvme_cb_fn_t cb_fn,
+		uint32_t lba_count, spdk_nvme_cmd_cb cb_fn,
 		void *cb_arg, uint32_t opc, uint32_t io_flags);
 
 static void
-nvme_cb_complete_child(void *child_arg, const struct nvme_completion *cpl)
+nvme_cb_complete_child(void *child_arg, const struct spdk_nvme_cpl *cpl)
 {
 	struct nvme_request *child = child_arg;
 	struct nvme_request *parent = child->parent;
@@ -52,7 +52,7 @@ nvme_cb_complete_child(void *child_arg, const struct nvme_completion *cpl)
 	parent->num_children--;
 	TAILQ_REMOVE(&parent->children, child, child_tailq);
 
-	if (nvme_completion_is_error(cpl)) {
+	if (spdk_nvme_cpl_is_error(cpl)) {
 		memcpy(&parent->parent_status, cpl, sizeof(*cpl));
 	}
 
@@ -76,7 +76,7 @@ nvme_request_add_child(struct nvme_request *parent, struct nvme_request *child)
 		 */
 		TAILQ_INIT(&parent->children);
 		parent->parent = NULL;
-		memset(&parent->parent_status, 0, sizeof(struct nvme_completion));
+		memset(&parent->parent_status, 0, sizeof(struct spdk_nvme_cpl));
 	}
 
 	parent->num_children++;
@@ -87,10 +87,10 @@ nvme_request_add_child(struct nvme_request *parent, struct nvme_request *child)
 }
 
 static struct nvme_request *
-_nvme_ns_cmd_split_request(struct nvme_namespace *ns,
+_nvme_ns_cmd_split_request(struct spdk_nvme_ns *ns,
 			   const struct nvme_payload *payload,
 			   uint64_t lba, uint32_t lba_count,
-			   nvme_cb_fn_t cb_fn, void *cb_arg, uint32_t opc,
+			   spdk_nvme_cmd_cb cb_fn, void *cb_arg, uint32_t opc,
 			   uint32_t io_flags, struct nvme_request *req,
 			   uint32_t sectors_per_max_io, uint32_t sector_mask)
 {
@@ -120,12 +120,12 @@ _nvme_ns_cmd_split_request(struct nvme_namespace *ns,
 }
 
 static struct nvme_request *
-_nvme_ns_cmd_rw(struct nvme_namespace *ns, const struct nvme_payload *payload,
-		uint64_t lba, uint32_t lba_count, nvme_cb_fn_t cb_fn, void *cb_arg, uint32_t opc,
+_nvme_ns_cmd_rw(struct spdk_nvme_ns *ns, const struct nvme_payload *payload,
+		uint64_t lba, uint32_t lba_count, spdk_nvme_cmd_cb cb_fn, void *cb_arg, uint32_t opc,
 		uint32_t io_flags)
 {
 	struct nvme_request	*req;
-	struct nvme_command	*cmd;
+	struct spdk_nvme_cmd	*cmd;
 	uint64_t		*tmp_lba;
 	uint32_t		sector_size;
 	uint32_t		sectors_per_max_io;
@@ -175,9 +175,9 @@ _nvme_ns_cmd_rw(struct nvme_namespace *ns, const struct nvme_payload *payload,
 }
 
 int
-nvme_ns_cmd_read(struct nvme_namespace *ns, void *buffer, uint64_t lba,
-		 uint32_t lba_count, nvme_cb_fn_t cb_fn, void *cb_arg,
-		 uint32_t io_flags)
+spdk_nvme_ns_cmd_read(struct spdk_nvme_ns *ns, void *buffer, uint64_t lba,
+		      uint32_t lba_count, spdk_nvme_cmd_cb cb_fn, void *cb_arg,
+		      uint32_t io_flags)
 {
 	struct nvme_request *req;
 	struct nvme_payload payload;
@@ -185,7 +185,7 @@ nvme_ns_cmd_read(struct nvme_namespace *ns, void *buffer, uint64_t lba,
 	payload.type = NVME_PAYLOAD_TYPE_CONTIG;
 	payload.u.contig = buffer;
 
-	req = _nvme_ns_cmd_rw(ns, &payload, lba, lba_count, cb_fn, cb_arg, NVME_OPC_READ, io_flags);
+	req = _nvme_ns_cmd_rw(ns, &payload, lba, lba_count, cb_fn, cb_arg, SPDK_NVME_OPC_READ, io_flags);
 	if (req != NULL) {
 		nvme_ctrlr_submit_io_request(ns->ctrlr, req);
 		return 0;
@@ -195,19 +195,22 @@ nvme_ns_cmd_read(struct nvme_namespace *ns, void *buffer, uint64_t lba,
 }
 
 int
-nvme_ns_cmd_readv(struct nvme_namespace *ns, uint64_t lba, uint32_t lba_count,
-		  nvme_cb_fn_t cb_fn, void *cb_arg, uint32_t io_flags,
-		  nvme_req_reset_sgl_fn_t reset_sgl_fn,
-		  nvme_req_next_sge_fn_t next_sge_fn)
+spdk_nvme_ns_cmd_readv(struct spdk_nvme_ns *ns, uint64_t lba, uint32_t lba_count,
+		       spdk_nvme_cmd_cb cb_fn, void *cb_arg, uint32_t io_flags,
+		       spdk_nvme_req_reset_sgl_cb reset_sgl_fn,
+		       spdk_nvme_req_next_sge_cb next_sge_fn)
 {
 	struct nvme_request *req;
 	struct nvme_payload payload;
 
+	if (reset_sgl_fn == NULL || next_sge_fn == NULL)
+		return EINVAL;
+
 	payload.type = NVME_PAYLOAD_TYPE_SGL;
 	payload.u.sgl.reset_sgl_fn = reset_sgl_fn;
 	payload.u.sgl.next_sge_fn = next_sge_fn;
 
-	req = _nvme_ns_cmd_rw(ns, &payload, lba, lba_count, cb_fn, cb_arg, NVME_OPC_READ, io_flags);
+	req = _nvme_ns_cmd_rw(ns, &payload, lba, lba_count, cb_fn, cb_arg, SPDK_NVME_OPC_READ, io_flags);
 	if (req != NULL) {
 		nvme_ctrlr_submit_io_request(ns->ctrlr, req);
 		return 0;
@@ -217,9 +220,9 @@ nvme_ns_cmd_readv(struct nvme_namespace *ns, uint64_t lba, uint32_t lba_count,
 }
 
 int
-nvme_ns_cmd_write(struct nvme_namespace *ns, void *buffer, uint64_t lba,
-		  uint32_t lba_count, nvme_cb_fn_t cb_fn, void *cb_arg,
-		  uint32_t io_flags)
+spdk_nvme_ns_cmd_write(struct spdk_nvme_ns *ns, void *buffer, uint64_t lba,
+		       uint32_t lba_count, spdk_nvme_cmd_cb cb_fn, void *cb_arg,
+		       uint32_t io_flags)
 {
 	struct nvme_request *req;
 	struct nvme_payload payload;
@@ -227,7 +230,7 @@ nvme_ns_cmd_write(struct nvme_namespace *ns, void *buffer, uint64_t lba,
 	payload.type = NVME_PAYLOAD_TYPE_CONTIG;
 	payload.u.contig = buffer;
 
-	req = _nvme_ns_cmd_rw(ns, &payload, lba, lba_count, cb_fn, cb_arg, NVME_OPC_WRITE, io_flags);
+	req = _nvme_ns_cmd_rw(ns, &payload, lba, lba_count, cb_fn, cb_arg, SPDK_NVME_OPC_WRITE, io_flags);
 	if (req != NULL) {
 		nvme_ctrlr_submit_io_request(ns->ctrlr, req);
 		return 0;
@@ -237,19 +240,22 @@ nvme_ns_cmd_write(struct nvme_namespace *ns, void *buffer, uint64_t lba,
 }
 
 int
-nvme_ns_cmd_writev(struct nvme_namespace *ns, uint64_t lba, uint32_t lba_count,
-		   nvme_cb_fn_t cb_fn, void *cb_arg, uint32_t io_flags,
-		   nvme_req_reset_sgl_fn_t reset_sgl_fn,
-		   nvme_req_next_sge_fn_t next_sge_fn)
+spdk_nvme_ns_cmd_writev(struct spdk_nvme_ns *ns, uint64_t lba, uint32_t lba_count,
+			spdk_nvme_cmd_cb cb_fn, void *cb_arg, uint32_t io_flags,
+			spdk_nvme_req_reset_sgl_cb reset_sgl_fn,
+			spdk_nvme_req_next_sge_cb next_sge_fn)
 {
 	struct nvme_request *req;
 	struct nvme_payload payload;
 
+	if (reset_sgl_fn == NULL || next_sge_fn == NULL)
+		return EINVAL;
+
 	payload.type = NVME_PAYLOAD_TYPE_SGL;
 	payload.u.sgl.reset_sgl_fn = reset_sgl_fn;
 	payload.u.sgl.next_sge_fn = next_sge_fn;
 
-	req = _nvme_ns_cmd_rw(ns, &payload, lba, lba_count, cb_fn, cb_arg, NVME_OPC_WRITE, io_flags);
+	req = _nvme_ns_cmd_rw(ns, &payload, lba, lba_count, cb_fn, cb_arg, SPDK_NVME_OPC_WRITE, io_flags);
 	if (req != NULL) {
 		nvme_ctrlr_submit_io_request(ns->ctrlr, req);
 		return 0;
@@ -259,30 +265,62 @@ nvme_ns_cmd_writev(struct nvme_namespace *ns, uint64_t lba, uint32_t lba_count,
 }
 
 int
-nvme_ns_cmd_deallocate(struct nvme_namespace *ns, void *payload,
-		       uint16_t num_ranges, nvme_cb_fn_t cb_fn, void *cb_arg)
+spdk_nvme_ns_cmd_write_zeroes(struct spdk_nvme_ns *ns, uint64_t lba,
+			      uint32_t lba_count, spdk_nvme_cmd_cb cb_fn, void *cb_arg,
+			      uint32_t io_flags)
+{
+	struct nvme_request	*req;
+	struct spdk_nvme_cmd	*cmd;
+	uint64_t		*tmp_lba;
+
+	if (lba_count == 0) {
+		return EINVAL;
+	}
+
+	req = nvme_allocate_request_null(cb_fn, cb_arg);
+	if (req == NULL) {
+		return ENOMEM;
+	}
+
+	cmd = &req->cmd;
+	cmd->opc = SPDK_NVME_OPC_WRITE_ZEROES;
+	cmd->nsid = ns->id;
+
+	tmp_lba = (uint64_t *)&cmd->cdw10;
+	*tmp_lba = lba;
+	cmd->cdw12 = lba_count - 1;
+	cmd->cdw12 |= io_flags;
+
+	nvme_ctrlr_submit_io_request(ns->ctrlr, req);
+
+	return 0;
+}
+
+int
+spdk_nvme_ns_cmd_deallocate(struct spdk_nvme_ns *ns, void *payload,
+			    uint16_t num_ranges, spdk_nvme_cmd_cb cb_fn, void *cb_arg)
 {
 	struct nvme_request	*req;
-	struct nvme_command	*cmd;
+	struct spdk_nvme_cmd	*cmd;
 
-	if (num_ranges == 0 || num_ranges > NVME_DATASET_MANAGEMENT_MAX_RANGES) {
+	if (num_ranges == 0 || num_ranges > SPDK_NVME_DATASET_MANAGEMENT_MAX_RANGES) {
 		return EINVAL;
 	}
 
 	req = nvme_allocate_request_contig(payload,
-					   num_ranges * sizeof(struct nvme_dsm_range),
+					   num_ranges * sizeof(struct spdk_nvme_dsm_range),
 					   cb_fn, cb_arg);
 	if (req == NULL) {
 		return ENOMEM;
 	}
 
 	cmd = &req->cmd;
-	cmd->opc = NVME_OPC_DATASET_MANAGEMENT;
+	cmd->opc = SPDK_NVME_OPC_DATASET_MANAGEMENT;
 	cmd->nsid = ns->id;
 
 	/* TODO: create a delete command data structure */
 	cmd->cdw10 = num_ranges - 1;
-	cmd->cdw11 = NVME_DSM_ATTR_DEALLOCATE;
+	cmd->cdw11 = SPDK_NVME_DSM_ATTR_DEALLOCATE;
 
 	nvme_ctrlr_submit_io_request(ns->ctrlr, req);
 
@@ -290,10 +328,10 @@ nvme_ns_cmd_deallocate(struct nvme_namespace *ns, void *payload,
 }
 
 int
-nvme_ns_cmd_flush(struct nvme_namespace *ns, nvme_cb_fn_t cb_fn, void *cb_arg)
+spdk_nvme_ns_cmd_flush(struct spdk_nvme_ns *ns, spdk_nvme_cmd_cb cb_fn, void *cb_arg)
 {
 	struct nvme_request	*req;
-	struct nvme_command	*cmd;
+	struct spdk_nvme_cmd	*cmd;
 
 	req = nvme_allocate_request_null(cb_fn, cb_arg);
 	if (req == NULL) {
@@ -301,7 +339,7 @@ nvme_ns_cmd_flush(struct nvme_namespace *ns, nvme_cb_fn_t cb_fn, void *cb_arg)
 	}
 
 	cmd = &req->cmd;
-	cmd->opc = NVME_OPC_FLUSH;
+	cmd->opc = SPDK_NVME_OPC_FLUSH;
 	cmd->nsid = ns->id;
 
 	nvme_ctrlr_submit_io_request(ns->ctrlr, req);
@@ -310,25 +348,25 @@ nvme_ns_cmd_flush(struct nvme_namespace *ns, nvme_cb_fn_t cb_fn, void *cb_arg)
 }
 
 int
-nvme_ns_cmd_reservation_register(struct nvme_namespace *ns,
-				 struct nvme_reservation_register_data *payload,
-				 bool ignore_key,
-				 enum nvme_reservation_register_action action,
-				 enum nvme_reservation_register_cptpl cptpl,
-				 nvme_cb_fn_t cb_fn, void *cb_arg)
+spdk_nvme_ns_cmd_reservation_register(struct spdk_nvme_ns *ns,
+				      struct spdk_nvme_reservation_register_data *payload,
+				      bool ignore_key,
+				      enum spdk_nvme_reservation_register_action action,
+				      enum spdk_nvme_reservation_register_cptpl cptpl,
+				      spdk_nvme_cmd_cb cb_fn, void *cb_arg)
 {
 	struct nvme_request	*req;
-	struct nvme_command	*cmd;
+	struct spdk_nvme_cmd	*cmd;
 
 	req = nvme_allocate_request_contig(payload,
-					   sizeof(struct nvme_reservation_register_data),
+					   sizeof(struct spdk_nvme_reservation_register_data),
 					   cb_fn, cb_arg);
 	if (req == NULL) {
 		return ENOMEM;
 	}
 
 	cmd = &req->cmd;
-	cmd->opc = NVME_OPC_RESERVATION_REGISTER;
+	cmd->opc = SPDK_NVME_OPC_RESERVATION_REGISTER;
 	cmd->nsid = ns->id;
 
 	/* Bits 0-2 */
@@ -344,24 +382,24 @@ nvme_ns_cmd_reservation_register(struct nvme_namespace *ns,
 }
 
 int
-nvme_ns_cmd_reservation_release(struct nvme_namespace *ns,
-				struct nvme_reservation_key_data *payload,
-				bool ignore_key,
-				enum nvme_reservation_release_action action,
-				enum nvme_reservation_type type,
-				nvme_cb_fn_t cb_fn, void *cb_arg)
+spdk_nvme_ns_cmd_reservation_release(struct spdk_nvme_ns *ns,
+				     struct spdk_nvme_reservation_key_data *payload,
+				     bool ignore_key,
+				     enum spdk_nvme_reservation_release_action action,
+				     enum spdk_nvme_reservation_type type,
+				     spdk_nvme_cmd_cb cb_fn, void *cb_arg)
 {
 	struct nvme_request	*req;
-	struct nvme_command	*cmd;
+	struct spdk_nvme_cmd	*cmd;
 
-	req = nvme_allocate_request_contig(payload, sizeof(struct nvme_reservation_key_data), cb_fn,
+	req = nvme_allocate_request_contig(payload, sizeof(struct spdk_nvme_reservation_key_data), cb_fn,
 					   cb_arg);
 	if (req == NULL) {
 		return ENOMEM;
 	}
 
 	cmd = &req->cmd;
-	cmd->opc = NVME_OPC_RESERVATION_RELEASE;
+	cmd->opc = SPDK_NVME_OPC_RESERVATION_RELEASE;
 	cmd->nsid = ns->id;
 
 	/* Bits 0-2 */
@@ -377,25 +415,25 @@ nvme_ns_cmd_reservation_release(struct nvme_namespace *ns,
 }
 
 int
-nvme_ns_cmd_reservation_acquire(struct nvme_namespace *ns,
-				struct nvme_reservation_acquire_data *payload,
-				bool ignore_key,
-				enum nvme_reservation_acquire_action action,
-				enum nvme_reservation_type type,
-				nvme_cb_fn_t cb_fn, void *cb_arg)
+spdk_nvme_ns_cmd_reservation_acquire(struct spdk_nvme_ns *ns,
+				     struct spdk_nvme_reservation_acquire_data *payload,
+				     bool ignore_key,
+				     enum spdk_nvme_reservation_acquire_action action,
+				     enum spdk_nvme_reservation_type type,
+				     spdk_nvme_cmd_cb cb_fn, void *cb_arg)
 {
 	struct nvme_request	*req;
-	struct nvme_command	*cmd;
+	struct spdk_nvme_cmd	*cmd;
 
 	req = nvme_allocate_request_contig(payload,
-					   sizeof(struct nvme_reservation_acquire_data),
+					   sizeof(struct spdk_nvme_reservation_acquire_data),
 					   cb_fn, cb_arg);
 	if (req == NULL) {
 		return ENOMEM;
 	}
 
 	cmd = &req->cmd;
-	cmd->opc = NVME_OPC_RESERVATION_ACQUIRE;
+	cmd->opc = SPDK_NVME_OPC_RESERVATION_ACQUIRE;
 	cmd->nsid = ns->id;
 
 	/* Bits 0-2 */
@@ -411,12 +449,12 @@ nvme_ns_cmd_reservation_acquire(struct nvme_namespace *ns,
 }
 
 int
-nvme_ns_cmd_reservation_report(struct nvme_namespace *ns, void *payload,
-			       uint32_t len, nvme_cb_fn_t cb_fn, void *cb_arg)
+spdk_nvme_ns_cmd_reservation_report(struct spdk_nvme_ns *ns, void *payload,
+				    uint32_t len, spdk_nvme_cmd_cb cb_fn, void *cb_arg)
 {
 	uint32_t		num_dwords;
 	struct nvme_request	*req;
-	struct nvme_command	*cmd;
+	struct spdk_nvme_cmd	*cmd;
 
 	if (len % 4)
 		return EINVAL;
@@ -428,7 +466,7 @@ nvme_ns_cmd_reservation_report(struct nvme_namespace *ns, void *payload,
 	}
 
 	cmd = &req->cmd;
-	cmd->opc = NVME_OPC_RESERVATION_REPORT;
+	cmd->opc = SPDK_NVME_OPC_RESERVATION_REPORT;
 	cmd->nsid = ns->id;
 
 	cmd->cdw10 = num_dwords;
diff --git a/src/spdk/lib/nvme/nvme_qpair.c b/src/spdk/lib/nvme/nvme_qpair.c
index b3e5586..06de6b1 100644
--- a/src/spdk/lib/nvme/nvme_qpair.c
+++ b/src/spdk/lib/nvme/nvme_qpair.c
@@ -54,38 +54,38 @@ struct nvme_string {
 };
 
 static const struct nvme_string admin_opcode[] = {
-	{ NVME_OPC_DELETE_IO_SQ, "DELETE IO SQ" },
-	{ NVME_OPC_CREATE_IO_SQ, "CREATE IO SQ" },
-	{ NVME_OPC_GET_LOG_PAGE, "GET LOG PAGE" },
-	{ NVME_OPC_DELETE_IO_CQ, "DELETE IO CQ" },
-	{ NVME_OPC_CREATE_IO_CQ, "CREATE IO CQ" },
-	{ NVME_OPC_IDENTIFY, "IDENTIFY" },
-	{ NVME_OPC_ABORT, "ABORT" },
-	{ NVME_OPC_SET_FEATURES, "SET FEATURES" },
-	{ NVME_OPC_GET_FEATURES, "GET FEATURES" },
-	{ NVME_OPC_ASYNC_EVENT_REQUEST, "ASYNC EVENT REQUEST" },
-	{ NVME_OPC_NAMESPACE_MANAGEMENT, "NAMESPACE MANAGEMENT" },
-	{ NVME_OPC_FIRMWARE_COMMIT, "FIRMWARE COMMIT" },
-	{ NVME_OPC_FIRMWARE_IMAGE_DOWNLOAD, "FIRMWARE IMAGE DOWNLOAD" },
-	{ NVME_OPC_NAMESPACE_ATTACHMENT, "NAMESPACE ATTACHMENT" },
-	{ NVME_OPC_FORMAT_NVM, "FORMAT NVM" },
-	{ NVME_OPC_SECURITY_SEND, "SECURITY SEND" },
-	{ NVME_OPC_SECURITY_RECEIVE, "SECURITY RECEIVE" },
+	{ SPDK_NVME_OPC_DELETE_IO_SQ, "DELETE IO SQ" },
+	{ SPDK_NVME_OPC_CREATE_IO_SQ, "CREATE IO SQ" },
+	{ SPDK_NVME_OPC_GET_LOG_PAGE, "GET LOG PAGE" },
+	{ SPDK_NVME_OPC_DELETE_IO_CQ, "DELETE IO CQ" },
+	{ SPDK_NVME_OPC_CREATE_IO_CQ, "CREATE IO CQ" },
+	{ SPDK_NVME_OPC_IDENTIFY, "IDENTIFY" },
+	{ SPDK_NVME_OPC_ABORT, "ABORT" },
+	{ SPDK_NVME_OPC_SET_FEATURES, "SET FEATURES" },
+	{ SPDK_NVME_OPC_GET_FEATURES, "GET FEATURES" },
+	{ SPDK_NVME_OPC_ASYNC_EVENT_REQUEST, "ASYNC EVENT REQUEST" },
+	{ SPDK_NVME_OPC_NS_MANAGEMENT, "NAMESPACE MANAGEMENT" },
+	{ SPDK_NVME_OPC_FIRMWARE_COMMIT, "FIRMWARE COMMIT" },
+	{ SPDK_NVME_OPC_FIRMWARE_IMAGE_DOWNLOAD, "FIRMWARE IMAGE DOWNLOAD" },
+	{ SPDK_NVME_OPC_NS_ATTACHMENT, "NAMESPACE ATTACHMENT" },
+	{ SPDK_NVME_OPC_FORMAT_NVM, "FORMAT NVM" },
+	{ SPDK_NVME_OPC_SECURITY_SEND, "SECURITY SEND" },
+	{ SPDK_NVME_OPC_SECURITY_RECEIVE, "SECURITY RECEIVE" },
 	{ 0xFFFF, "ADMIN COMMAND" }
 };
 
 static const struct nvme_string io_opcode[] = {
-	{ NVME_OPC_FLUSH, "FLUSH" },
-	{ NVME_OPC_WRITE, "WRITE" },
-	{ NVME_OPC_READ, "READ" },
-	{ NVME_OPC_WRITE_UNCORRECTABLE, "WRITE UNCORRECTABLE" },
-	{ NVME_OPC_COMPARE, "COMPARE" },
-	{ NVME_OPC_WRITE_ZEROES, "WRITE ZEROES" },
-	{ NVME_OPC_DATASET_MANAGEMENT, "DATASET MANAGEMENT" },
-	{ NVME_OPC_RESERVATION_REGISTER, "RESERVATION REGISTER" },
-	{ NVME_OPC_RESERVATION_REPORT, "RESERVATION REPORT" },
-	{ NVME_OPC_RESERVATION_ACQUIRE, "RESERVATION ACQUIRE" },
-	{ NVME_OPC_RESERVATION_RELEASE, "RESERVATION RELEASE" },
+	{ SPDK_NVME_OPC_FLUSH, "FLUSH" },
+	{ SPDK_NVME_OPC_WRITE, "WRITE" },
+	{ SPDK_NVME_OPC_READ, "READ" },
+	{ SPDK_NVME_OPC_WRITE_UNCORRECTABLE, "WRITE UNCORRECTABLE" },
+	{ SPDK_NVME_OPC_COMPARE, "COMPARE" },
+	{ SPDK_NVME_OPC_WRITE_ZEROES, "WRITE ZEROES" },
+	{ SPDK_NVME_OPC_DATASET_MANAGEMENT, "DATASET MANAGEMENT" },
+	{ SPDK_NVME_OPC_RESERVATION_REGISTER, "RESERVATION REGISTER" },
+	{ SPDK_NVME_OPC_RESERVATION_REPORT, "RESERVATION REPORT" },
+	{ SPDK_NVME_OPC_RESERVATION_ACQUIRE, "RESERVATION ACQUIRE" },
+	{ SPDK_NVME_OPC_RESERVATION_RELEASE, "RESERVATION RELEASE" },
 	{ 0xFFFF, "IO COMMAND" }
 };
 
@@ -107,7 +107,7 @@ nvme_get_string(const struct nvme_string *strings, uint16_t value)
 
 static void
 nvme_admin_qpair_print_command(struct nvme_qpair *qpair,
-			       struct nvme_command *cmd)
+			       struct spdk_nvme_cmd *cmd)
 {
 
 	nvme_printf(qpair->ctrlr, "%s (%02x) sqid:%d cid:%d nsid:%x "
@@ -118,14 +118,14 @@ nvme_admin_qpair_print_command(struct nvme_qpair *qpair,
 
 static void
 nvme_io_qpair_print_command(struct nvme_qpair *qpair,
-			    struct nvme_command *cmd)
+			    struct spdk_nvme_cmd *cmd)
 {
 
 	switch ((int)cmd->opc) {
-	case NVME_OPC_WRITE:
-	case NVME_OPC_READ:
-	case NVME_OPC_WRITE_UNCORRECTABLE:
-	case NVME_OPC_COMPARE:
+	case SPDK_NVME_OPC_WRITE:
+	case SPDK_NVME_OPC_READ:
+	case SPDK_NVME_OPC_WRITE_UNCORRECTABLE:
+	case SPDK_NVME_OPC_COMPARE:
 		nvme_printf(qpair->ctrlr, "%s sqid:%d cid:%d nsid:%d "
 			    "lba:%llu len:%d\n",
 			    nvme_get_string(io_opcode, cmd->opc), qpair->id, cmd->cid,
@@ -133,8 +133,8 @@ nvme_io_qpair_print_command(struct nvme_qpair *qpair,
 			    ((unsigned long long)cmd->cdw11 << 32) + cmd->cdw10,
 			    (cmd->cdw12 & 0xFFFF) + 1);
 		break;
-	case NVME_OPC_FLUSH:
-	case NVME_OPC_DATASET_MANAGEMENT:
+	case SPDK_NVME_OPC_FLUSH:
+	case SPDK_NVME_OPC_DATASET_MANAGEMENT:
 		nvme_printf(qpair->ctrlr, "%s sqid:%d cid:%d nsid:%d\n",
 			    nvme_get_string(io_opcode, cmd->opc), qpair->id, cmd->cid,
 			    cmd->nsid);
@@ -148,7 +148,7 @@ nvme_io_qpair_print_command(struct nvme_qpair *qpair,
 }
 
 static void
-nvme_qpair_print_command(struct nvme_qpair *qpair, struct nvme_command *cmd)
+nvme_qpair_print_command(struct nvme_qpair *qpair, struct spdk_nvme_cmd *cmd)
 {
 	nvme_assert(qpair != NULL, ("qpair can not be NULL"));
 	nvme_assert(cmd != NULL, ("cmd can not be NULL"));
@@ -161,51 +161,51 @@ nvme_qpair_print_command(struct nvme_qpair *qpair, struct nvme_command *cmd)
 }
 
 static const struct nvme_string generic_status[] = {
-	{ NVME_SC_SUCCESS, "SUCCESS" },
-	{ NVME_SC_INVALID_OPCODE, "INVALID OPCODE" },
-	{ NVME_SC_INVALID_FIELD, "INVALID_FIELD" },
-	{ NVME_SC_COMMAND_ID_CONFLICT, "COMMAND ID CONFLICT" },
-	{ NVME_SC_DATA_TRANSFER_ERROR, "DATA TRANSFER ERROR" },
-	{ NVME_SC_ABORTED_POWER_LOSS, "ABORTED - POWER LOSS" },
-	{ NVME_SC_INTERNAL_DEVICE_ERROR, "INTERNAL DEVICE ERROR" },
-	{ NVME_SC_ABORTED_BY_REQUEST, "ABORTED - BY REQUEST" },
-	{ NVME_SC_ABORTED_SQ_DELETION, "ABORTED - SQ DELETION" },
-	{ NVME_SC_ABORTED_FAILED_FUSED, "ABORTED - FAILED FUSED" },
-	{ NVME_SC_ABORTED_MISSING_FUSED, "ABORTED - MISSING FUSED" },
-	{ NVME_SC_INVALID_NAMESPACE_OR_FORMAT, "INVALID NAMESPACE OR FORMAT" },
-	{ NVME_SC_COMMAND_SEQUENCE_ERROR, "COMMAND SEQUENCE ERROR" },
-	{ NVME_SC_LBA_OUT_OF_RANGE, "LBA OUT OF RANGE" },
-	{ NVME_SC_CAPACITY_EXCEEDED, "CAPACITY EXCEEDED" },
-	{ NVME_SC_NAMESPACE_NOT_READY, "NAMESPACE NOT READY" },
+	{ SPDK_NVME_SC_SUCCESS, "SUCCESS" },
+	{ SPDK_NVME_SC_INVALID_OPCODE, "INVALID OPCODE" },
+	{ SPDK_NVME_SC_INVALID_FIELD, "INVALID_FIELD" },
+	{ SPDK_NVME_SC_COMMAND_ID_CONFLICT, "COMMAND ID CONFLICT" },
+	{ SPDK_NVME_SC_DATA_TRANSFER_ERROR, "DATA TRANSFER ERROR" },
+	{ SPDK_NVME_SC_ABORTED_POWER_LOSS, "ABORTED - POWER LOSS" },
+	{ SPDK_NVME_SC_INTERNAL_DEVICE_ERROR, "INTERNAL DEVICE ERROR" },
+	{ SPDK_NVME_SC_ABORTED_BY_REQUEST, "ABORTED - BY REQUEST" },
+	{ SPDK_NVME_SC_ABORTED_SQ_DELETION, "ABORTED - SQ DELETION" },
+	{ SPDK_NVME_SC_ABORTED_FAILED_FUSED, "ABORTED - FAILED FUSED" },
+	{ SPDK_NVME_SC_ABORTED_MISSING_FUSED, "ABORTED - MISSING FUSED" },
+	{ SPDK_NVME_SC_INVALID_NAMESPACE_OR_FORMAT, "INVALID NAMESPACE OR FORMAT" },
+	{ SPDK_NVME_SC_COMMAND_SEQUENCE_ERROR, "COMMAND SEQUENCE ERROR" },
+	{ SPDK_NVME_SC_LBA_OUT_OF_RANGE, "LBA OUT OF RANGE" },
+	{ SPDK_NVME_SC_CAPACITY_EXCEEDED, "CAPACITY EXCEEDED" },
+	{ SPDK_NVME_SC_NAMESPACE_NOT_READY, "NAMESPACE NOT READY" },
 	{ 0xFFFF, "GENERIC" }
 };
 
 static const struct nvme_string command_specific_status[] = {
-	{ NVME_SC_COMPLETION_QUEUE_INVALID, "INVALID COMPLETION QUEUE" },
-	{ NVME_SC_INVALID_QUEUE_IDENTIFIER, "INVALID QUEUE IDENTIFIER" },
-	{ NVME_SC_MAXIMUM_QUEUE_SIZE_EXCEEDED, "MAX QUEUE SIZE EXCEEDED" },
-	{ NVME_SC_ABORT_COMMAND_LIMIT_EXCEEDED, "ABORT CMD LIMIT EXCEEDED" },
-	{ NVME_SC_ASYNC_EVENT_REQUEST_LIMIT_EXCEEDED, "ASYNC LIMIT EXCEEDED" },
-	{ NVME_SC_INVALID_FIRMWARE_SLOT, "INVALID FIRMWARE SLOT" },
-	{ NVME_SC_INVALID_FIRMWARE_IMAGE, "INVALID FIRMWARE IMAGE" },
-	{ NVME_SC_INVALID_INTERRUPT_VECTOR, "INVALID INTERRUPT VECTOR" },
-	{ NVME_SC_INVALID_LOG_PAGE, "INVALID LOG PAGE" },
-	{ NVME_SC_INVALID_FORMAT, "INVALID FORMAT" },
-	{ NVME_SC_FIRMWARE_REQUIRES_RESET, "FIRMWARE REQUIRES RESET" },
-	{ NVME_SC_CONFLICTING_ATTRIBUTES, "CONFLICTING ATTRIBUTES" },
-	{ NVME_SC_INVALID_PROTECTION_INFO, "INVALID PROTECTION INFO" },
-	{ NVME_SC_ATTEMPTED_WRITE_TO_RO_PAGE, "WRITE TO RO PAGE" },
+	{ SPDK_NVME_SC_COMPLETION_QUEUE_INVALID, "INVALID COMPLETION QUEUE" },
+	{ SPDK_NVME_SC_INVALID_QUEUE_IDENTIFIER, "INVALID QUEUE IDENTIFIER" },
+	{ SPDK_NVME_SC_MAXIMUM_QUEUE_SIZE_EXCEEDED, "MAX QUEUE SIZE EXCEEDED" },
+	{ SPDK_NVME_SC_ABORT_COMMAND_LIMIT_EXCEEDED, "ABORT CMD LIMIT EXCEEDED" },
+	{ SPDK_NVME_SC_ASYNC_EVENT_REQUEST_LIMIT_EXCEEDED, "ASYNC LIMIT EXCEEDED" },
+	{ SPDK_NVME_SC_INVALID_FIRMWARE_SLOT, "INVALID FIRMWARE SLOT" },
+	{ SPDK_NVME_SC_INVALID_FIRMWARE_IMAGE, "INVALID FIRMWARE IMAGE" },
+	{ SPDK_NVME_SC_INVALID_INTERRUPT_VECTOR, "INVALID INTERRUPT VECTOR" },
+	{ SPDK_NVME_SC_INVALID_LOG_PAGE, "INVALID LOG PAGE" },
+	{ SPDK_NVME_SC_INVALID_FORMAT, "INVALID FORMAT" },
+	{ SPDK_NVME_SC_FIRMWARE_REQUIRES_RESET, "FIRMWARE REQUIRES RESET" },
+	{ SPDK_NVME_SC_CONFLICTING_ATTRIBUTES, "CONFLICTING ATTRIBUTES" },
+	{ SPDK_NVME_SC_INVALID_PROTECTION_INFO, "INVALID PROTECTION INFO" },
+	{ SPDK_NVME_SC_ATTEMPTED_WRITE_TO_RO_PAGE, "WRITE TO RO PAGE" },
 	{ 0xFFFF, "COMMAND SPECIFIC" }
 };
 
 static const struct nvme_string media_error_status[] = {
-	{ NVME_SC_WRITE_FAULTS, "WRITE FAULTS" },
-	{ NVME_SC_UNRECOVERED_READ_ERROR, "UNRECOVERED READ ERROR" },
-	{ NVME_SC_GUARD_CHECK_ERROR, "GUARD CHECK ERROR" },
-	{ NVME_SC_APPLICATION_TAG_CHECK_ERROR, "APPLICATION TAG CHECK ERROR" },
-	{ NVME_SC_REFERENCE_TAG_CHECK_ERROR, "REFERENCE TAG CHECK ERROR" },
-	{ NVME_SC_COMPARE_FAILURE, "COMPARE FAILURE" },
-	{ NVME_SC_ACCESS_DENIED, "ACCESS DENIED" },
+	{ SPDK_NVME_SC_WRITE_FAULTS, "WRITE FAULTS" },
+	{ SPDK_NVME_SC_UNRECOVERED_READ_ERROR, "UNRECOVERED READ ERROR" },
+	{ SPDK_NVME_SC_GUARD_CHECK_ERROR, "GUARD CHECK ERROR" },
+	{ SPDK_NVME_SC_APPLICATION_TAG_CHECK_ERROR, "APPLICATION TAG CHECK ERROR" },
+	{ SPDK_NVME_SC_REFERENCE_TAG_CHECK_ERROR, "REFERENCE TAG CHECK ERROR" },
+	{ SPDK_NVME_SC_COMPARE_FAILURE, "COMPARE FAILURE" },
+	{ SPDK_NVME_SC_ACCESS_DENIED, "ACCESS DENIED" },
 	{ 0xFFFF, "MEDIA ERROR" }
 };
 
@@ -215,16 +215,16 @@ get_status_string(uint16_t sct, uint16_t sc)
 	const struct nvme_string *entry;
 
 	switch (sct) {
-	case NVME_SCT_GENERIC:
+	case SPDK_NVME_SCT_GENERIC:
 		entry = generic_status;
 		break;
-	case NVME_SCT_COMMAND_SPECIFIC:
+	case SPDK_NVME_SCT_COMMAND_SPECIFIC:
 		entry = command_specific_status;
 		break;
-	case NVME_SCT_MEDIA_ERROR:
+	case SPDK_NVME_SCT_MEDIA_ERROR:
 		entry = media_error_status;
 		break;
-	case NVME_SCT_VENDOR_SPECIFIC:
+	case SPDK_NVME_SCT_VENDOR_SPECIFIC:
 		return "VENDOR SPECIFIC";
 	default:
 		return "RESERVED";
@@ -235,7 +235,7 @@ get_status_string(uint16_t sct, uint16_t sc)
 
 static void
 nvme_qpair_print_completion(struct nvme_qpair *qpair,
-			    struct nvme_completion *cpl)
+			    struct spdk_nvme_cpl *cpl)
 {
 	nvme_printf(qpair->ctrlr, "%s (%02x/%02x) sqid:%d cid:%d cdw0:%x sqhd:%04x p:%x m:%x dnr:%x\n",
 		    get_status_string(cpl->status.sct, cpl->status.sc),
@@ -244,7 +244,7 @@ nvme_qpair_print_completion(struct nvme_qpair *qpair,
 }
 
 static bool
-nvme_completion_is_retry(const struct nvme_completion *cpl)
+nvme_completion_is_retry(const struct spdk_nvme_cpl *cpl)
 {
 	/*
 	 * TODO: spec is not clear how commands that are aborted due
@@ -253,34 +253,34 @@ nvme_completion_is_retry(const struct nvme_completion *cpl)
 	 *  look at the DNR bit.
 	 */
 	switch ((int)cpl->status.sct) {
-	case NVME_SCT_GENERIC:
+	case SPDK_NVME_SCT_GENERIC:
 		switch ((int)cpl->status.sc) {
-		case NVME_SC_ABORTED_BY_REQUEST:
-		case NVME_SC_NAMESPACE_NOT_READY:
+		case SPDK_NVME_SC_ABORTED_BY_REQUEST:
+		case SPDK_NVME_SC_NAMESPACE_NOT_READY:
 			if (cpl->status.dnr) {
 				return false;
 			} else {
 				return true;
 			}
-		case NVME_SC_INVALID_OPCODE:
-		case NVME_SC_INVALID_FIELD:
-		case NVME_SC_COMMAND_ID_CONFLICT:
-		case NVME_SC_DATA_TRANSFER_ERROR:
-		case NVME_SC_ABORTED_POWER_LOSS:
-		case NVME_SC_INTERNAL_DEVICE_ERROR:
-		case NVME_SC_ABORTED_SQ_DELETION:
-		case NVME_SC_ABORTED_FAILED_FUSED:
-		case NVME_SC_ABORTED_MISSING_FUSED:
-		case NVME_SC_INVALID_NAMESPACE_OR_FORMAT:
-		case NVME_SC_COMMAND_SEQUENCE_ERROR:
-		case NVME_SC_LBA_OUT_OF_RANGE:
-		case NVME_SC_CAPACITY_EXCEEDED:
+		case SPDK_NVME_SC_INVALID_OPCODE:
+		case SPDK_NVME_SC_INVALID_FIELD:
+		case SPDK_NVME_SC_COMMAND_ID_CONFLICT:
+		case SPDK_NVME_SC_DATA_TRANSFER_ERROR:
+		case SPDK_NVME_SC_ABORTED_POWER_LOSS:
+		case SPDK_NVME_SC_INTERNAL_DEVICE_ERROR:
+		case SPDK_NVME_SC_ABORTED_SQ_DELETION:
+		case SPDK_NVME_SC_ABORTED_FAILED_FUSED:
+		case SPDK_NVME_SC_ABORTED_MISSING_FUSED:
+		case SPDK_NVME_SC_INVALID_NAMESPACE_OR_FORMAT:
+		case SPDK_NVME_SC_COMMAND_SEQUENCE_ERROR:
+		case SPDK_NVME_SC_LBA_OUT_OF_RANGE:
+		case SPDK_NVME_SC_CAPACITY_EXCEEDED:
 		default:
 			return false;
 		}
-	case NVME_SCT_COMMAND_SPECIFIC:
-	case NVME_SCT_MEDIA_ERROR:
-	case NVME_SCT_VENDOR_SPECIFIC:
+	case SPDK_NVME_SCT_COMMAND_SPECIFIC:
+	case SPDK_NVME_SCT_MEDIA_ERROR:
+	case SPDK_NVME_SCT_VENDOR_SPECIFIC:
 	default:
 		return false;
 	}
@@ -308,13 +308,13 @@ nvme_qpair_submit_tracker(struct nvme_qpair *qpair, struct nvme_tracker *tr)
 		qpair->sq_tail = 0;
 	}
 
-	wmb();
+	spdk_wmb();
 	spdk_mmio_write_4(qpair->sq_tdbl, qpair->sq_tail);
 }
 
 static void
 nvme_qpair_complete_tracker(struct nvme_qpair *qpair, struct nvme_tracker *tr,
-			    struct nvme_completion *cpl, bool print_on_error)
+			    struct spdk_nvme_cpl *cpl, bool print_on_error)
 {
 	struct nvme_request	*req;
 	bool			retry, error;
@@ -323,9 +323,9 @@ nvme_qpair_complete_tracker(struct nvme_qpair *qpair, struct nvme_tracker *tr,
 
 	nvme_assert(req != NULL, ("tr has NULL req\n"));
 
-	error = nvme_completion_is_error(cpl);
+	error = spdk_nvme_cpl_is_error(cpl);
 	retry = error && nvme_completion_is_retry(cpl) &&
-		req->retries < nvme_retry_count;
+		req->retries < spdk_nvme_retry_count;
 
 	if (error && print_on_error) {
 		nvme_qpair_print_command(qpair, &req->cmd);
@@ -369,7 +369,7 @@ nvme_qpair_manual_complete_tracker(struct nvme_qpair *qpair,
 				   struct nvme_tracker *tr, uint32_t sct, uint32_t sc, uint32_t dnr,
 				   bool print_on_error)
 {
-	struct nvme_completion	cpl;
+	struct spdk_nvme_cpl	cpl;
 
 	memset(&cpl, 0, sizeof(cpl));
 	cpl.sqid = qpair->id;
@@ -385,7 +385,7 @@ nvme_qpair_manual_complete_request(struct nvme_qpair *qpair,
 				   struct nvme_request *req, uint32_t sct, uint32_t sc,
 				   bool print_on_error)
 {
-	struct nvme_completion	cpl;
+	struct spdk_nvme_cpl	cpl;
 	bool			error;
 
 	memset(&cpl, 0, sizeof(cpl));
@@ -393,7 +393,7 @@ nvme_qpair_manual_complete_request(struct nvme_qpair *qpair,
 	cpl.status.sct = sct;
 	cpl.status.sc = sc;
 
-	error = nvme_completion_is_error(&cpl);
+	error = spdk_nvme_cpl_is_error(&cpl);
 
 	if (error && print_on_error) {
 		nvme_qpair_print_command(qpair, &req->cmd);
@@ -465,7 +465,7 @@ int32_t
 nvme_qpair_process_completions(struct nvme_qpair *qpair, uint32_t max_completions)
 {
 	struct nvme_tracker	*tr;
-	struct nvme_completion	*cpl;
+	struct spdk_nvme_cpl	*cpl;
 	uint32_t num_completions = 0;
 
 	if (!nvme_qpair_check_enabled(qpair)) {
@@ -509,20 +509,22 @@ nvme_qpair_process_completions(struct nvme_qpair *qpair, uint32_t max_completion
 			qpair->phase = !qpair->phase;
 		}
 
-		spdk_mmio_write_4(qpair->cq_hdbl, qpair->cq_head);
-
 		if (++num_completions == max_completions) {
 			break;
 		}
 	}
 
+	if (num_completions > 0) {
+		spdk_mmio_write_4(qpair->cq_hdbl, qpair->cq_head);
+	}
+
 	return num_completions;
 }
 
 int
 nvme_qpair_construct(struct nvme_qpair *qpair, uint16_t id,
 		     uint16_t num_entries, uint16_t num_trackers,
-		     struct nvme_controller *ctrlr)
+		     struct spdk_nvme_ctrlr *ctrlr)
 {
 	struct nvme_tracker	*tr;
 	uint16_t		i;
@@ -539,7 +541,7 @@ nvme_qpair_construct(struct nvme_qpair *qpair, uint16_t id,
 
 	/* cmd and cpl rings must be aligned on 4KB boundaries. */
 	qpair->cmd = nvme_malloc("qpair_cmd",
-				 qpair->num_entries * sizeof(struct nvme_command),
+				 qpair->num_entries * sizeof(struct spdk_nvme_cmd),
 				 0x1000,
 				 &qpair->cmd_bus_addr);
 	if (qpair->cmd == NULL) {
@@ -547,7 +549,7 @@ nvme_qpair_construct(struct nvme_qpair *qpair, uint16_t id,
 		goto fail;
 	}
 	qpair->cpl = nvme_malloc("qpair_cpl",
-				 qpair->num_entries * sizeof(struct nvme_completion),
+				 qpair->num_entries * sizeof(struct spdk_nvme_cpl),
 				 0x1000,
 				 &qpair->cpl_bus_addr);
 	if (qpair->cpl == NULL) {
@@ -597,9 +599,9 @@ nvme_admin_qpair_abort_aers(struct nvme_qpair *qpair)
 
 	tr = LIST_FIRST(&qpair->outstanding_tr);
 	while (tr != NULL) {
-		if (tr->req->cmd.opc == NVME_OPC_ASYNC_EVENT_REQUEST) {
+		if (tr->req->cmd.opc == SPDK_NVME_OPC_ASYNC_EVENT_REQUEST) {
 			nvme_qpair_manual_complete_tracker(qpair, tr,
-							   NVME_SCT_GENERIC, NVME_SC_ABORTED_SQ_DELETION, 0,
+							   SPDK_NVME_SCT_GENERIC, SPDK_NVME_SC_ABORTED_SQ_DELETION, 0,
 							   false);
 			tr = LIST_FIRST(&qpair->outstanding_tr);
 		} else {
@@ -656,16 +658,16 @@ _nvme_fail_request_bad_vtophys(struct nvme_qpair *qpair, struct nvme_tracker *tr
 	 * Bad vtophys translation, so abort this request and return
 	 *  immediately.
 	 */
-	nvme_qpair_manual_complete_tracker(qpair, tr, NVME_SCT_GENERIC,
-					   NVME_SC_INVALID_FIELD,
+	nvme_qpair_manual_complete_tracker(qpair, tr, SPDK_NVME_SCT_GENERIC,
+					   SPDK_NVME_SC_INVALID_FIELD,
 					   1 /* do not retry */, true);
 }
 
 static void
 _nvme_fail_request_ctrlr_failed(struct nvme_qpair *qpair, struct nvme_request *req)
 {
-	nvme_qpair_manual_complete_request(qpair, req, NVME_SCT_GENERIC,
-					   NVME_SC_ABORTED_BY_REQUEST, true);
+	nvme_qpair_manual_complete_request(qpair, req, SPDK_NVME_SCT_GENERIC,
+					   SPDK_NVME_SC_ABORTED_BY_REQUEST, true);
 }
 
 /**
@@ -692,7 +694,7 @@ _nvme_qpair_build_contig_request(struct nvme_qpair *qpair, struct nvme_request *
 		nseg += 1 + ((modulo + unaligned - 1) >> nvme_u32log2(PAGE_SIZE));
 	}
 
-	tr->req->cmd.psdt = NVME_PSDT_PRP;
+	tr->req->cmd.psdt = SPDK_NVME_PSDT_PRP;
 	tr->req->cmd.dptr.prp.prp1 = phys_addr;
 	if (nseg == 2) {
 		seg_addr = payload + PAGE_SIZE - unaligned;
@@ -758,7 +760,7 @@ _nvme_qpair_build_sgl_request(struct nvme_qpair *qpair, struct nvme_request *req
 		}
 
 		if (total_nseg == 0) {
-			req->cmd.psdt = NVME_PSDT_PRP;
+			req->cmd.psdt = SPDK_NVME_PSDT_PRP;
 			req->cmd.dptr.prp.prp1 = phys_addr;
 		}
 
@@ -888,9 +890,9 @@ nvme_qpair_reset(struct nvme_qpair *qpair)
 	qpair->phase = 1;
 
 	memset(qpair->cmd, 0,
-	       qpair->num_entries * sizeof(struct nvme_command));
+	       qpair->num_entries * sizeof(struct spdk_nvme_cmd));
 	memset(qpair->cpl, 0,
-	       qpair->num_entries * sizeof(struct nvme_completion));
+	       qpair->num_entries * sizeof(struct spdk_nvme_cpl));
 }
 
 static void
@@ -908,8 +910,8 @@ _nvme_admin_qpair_enable(struct nvme_qpair *qpair)
 	LIST_FOREACH_SAFE(tr, &qpair->outstanding_tr, list, tr_temp) {
 		nvme_printf(qpair->ctrlr,
 			    "aborting outstanding admin command\n");
-		nvme_qpair_manual_complete_tracker(qpair, tr, NVME_SCT_GENERIC,
-						   NVME_SC_ABORTED_BY_REQUEST, 1 /* do not retry */, true);
+		nvme_qpair_manual_complete_tracker(qpair, tr, SPDK_NVME_SCT_GENERIC,
+						   SPDK_NVME_SC_ABORTED_BY_REQUEST, 1 /* do not retry */, true);
 	}
 
 	qpair->is_enabled = true;
@@ -931,8 +933,8 @@ _nvme_io_qpair_enable(struct nvme_qpair *qpair)
 	 */
 	LIST_FOREACH_SAFE(tr, &qpair->outstanding_tr, list, tr_temp) {
 		nvme_printf(qpair->ctrlr, "aborting outstanding i/o\n");
-		nvme_qpair_manual_complete_tracker(qpair, tr, NVME_SCT_GENERIC,
-						   NVME_SC_ABORTED_BY_REQUEST, 0, true);
+		nvme_qpair_manual_complete_tracker(qpair, tr, SPDK_NVME_SCT_GENERIC,
+						   SPDK_NVME_SC_ABORTED_BY_REQUEST, 0, true);
 	}
 
 
@@ -992,8 +994,8 @@ nvme_qpair_fail(struct nvme_qpair *qpair)
 		req = STAILQ_FIRST(&qpair->queued_req);
 		STAILQ_REMOVE_HEAD(&qpair->queued_req, stailq);
 		nvme_printf(qpair->ctrlr, "failing queued i/o\n");
-		nvme_qpair_manual_complete_request(qpair, req, NVME_SCT_GENERIC,
-						   NVME_SC_ABORTED_BY_REQUEST, true);
+		nvme_qpair_manual_complete_request(qpair, req, SPDK_NVME_SCT_GENERIC,
+						   SPDK_NVME_SC_ABORTED_BY_REQUEST, true);
 	}
 
 	/* Manually abort each outstanding I/O. */
@@ -1004,8 +1006,8 @@ nvme_qpair_fail(struct nvme_qpair *qpair)
 		 *  do that for us.
 		 */
 		nvme_printf(qpair->ctrlr, "failing outstanding i/o\n");
-		nvme_qpair_manual_complete_tracker(qpair, tr, NVME_SCT_GENERIC,
-						   NVME_SC_ABORTED_BY_REQUEST, 1 /* do not retry */, true);
+		nvme_qpair_manual_complete_tracker(qpair, tr, SPDK_NVME_SCT_GENERIC,
+						   SPDK_NVME_SC_ABORTED_BY_REQUEST, 1 /* do not retry */, true);
 	}
 }
 
diff --git a/src/spdk/lib/util/file.c b/src/spdk/lib/util/file.c
index b002502..1a754c1 100644
--- a/src/spdk/lib/util/file.c
+++ b/src/spdk/lib/util/file.c
@@ -64,7 +64,7 @@ dev_get_size(int fd)
 }
 
 uint32_t
-dev_get_blocklen(int fd)
+spdk_dev_get_blocklen(int fd)
 {
 #if defined(DKIOCGETBLOCKSIZE) /* FreeBSD */
 	uint32_t blocklen;
@@ -85,7 +85,7 @@ dev_get_blocklen(int fd)
 }
 
 uint64_t
-file_get_size(int fd)
+spdk_file_get_size(int fd)
 {
 	struct stat st;
 
diff --git a/src/spdk/lib/util/pci.c b/src/spdk/lib/util/pci.c
index 6651ece..1a70d21 100644
--- a/src/spdk/lib/util/pci.c
+++ b/src/spdk/lib/util/pci.c
@@ -40,8 +40,18 @@
 #include <sys/mman.h>
 #include <sys/stat.h>
 #include <sys/types.h>
+#include <pthread.h>
+#include <stdbool.h>
 
+#ifdef USE_PCIACCESS
 #include <pciaccess.h>
+/* When using libpciaccess, struct spdk_pci_device * is actually struct pci_device * internally. */
+#define spdk_pci_device pci_device
+#else
+#include <rte_pci.h>
+/* When using DPDK PCI, struct spdk_pci_device * is actually struct rte_pci_device * internally. */
+#define spdk_pci_device rte_pci_device
+#endif
 
 #ifdef __FreeBSD__
 #include <sys/pciio.h>
@@ -51,16 +61,324 @@
 
 #define SYSFS_PCI_DEVICES	"/sys/bus/pci/devices"
 #define SYSFS_PCI_DRIVERS	"/sys/bus/pci/drivers"
+
+#ifndef PCI_PRI_FMT /* This is defined by rte_pci.h when USE_PCIACCESS is not set */
 #define PCI_PRI_FMT		"%04x:%02x:%02x.%1u"
+#endif
+
 #define SPDK_PCI_PATH_MAX	256
+#define PCI_CFG_SIZE		256
+#define PCI_EXT_CAP_ID_SN	0x03
+#define PCI_UIO_DRIVER		"uio_pci_generic"
+
+#ifdef USE_PCIACCESS
+
+/*
+ * libpciaccess wrapper functions
+ */
+
+static pthread_mutex_t g_pci_init_mutex = PTHREAD_MUTEX_INITIALIZER;
+static bool g_pci_initialized = false;
+
+static int
+spdk_pci_init(void)
+{
+	int rc;
+
+	pthread_mutex_lock(&g_pci_init_mutex);
+
+	if (!g_pci_initialized) {
+		rc = pci_system_init();
+		if (rc == 0) {
+			g_pci_initialized = true;
+		}
+	} else {
+		rc = 0;
+	}
+
+	pthread_mutex_unlock(&g_pci_init_mutex);
+
+	return rc;
+}
+
+uint16_t
+spdk_pci_device_get_domain(struct spdk_pci_device *dev)
+{
+	return dev->domain;
+}
+
+uint8_t
+spdk_pci_device_get_bus(struct spdk_pci_device *dev)
+{
+	return dev->bus;
+}
+
+
+uint8_t
+spdk_pci_device_get_dev(struct spdk_pci_device *dev)
+{
+	return dev->dev;
+}
+
+uint8_t
+spdk_pci_device_get_func(struct spdk_pci_device *dev)
+{
+	return dev->func;
+}
+
+uint16_t
+spdk_pci_device_get_vendor_id(struct spdk_pci_device *dev)
+{
+	return dev->vendor_id;
+}
+
+uint16_t
+spdk_pci_device_get_device_id(struct spdk_pci_device *dev)
+{
+	return dev->device_id;
+}
+
+uint16_t
+spdk_pci_device_get_subvendor_id(struct spdk_pci_device *dev)
+{
+	return dev->subvendor_id;
+}
+
+uint16_t
+spdk_pci_device_get_subdevice_id(struct spdk_pci_device *dev)
+{
+	return dev->subdevice_id;
+}
+
+uint32_t
+spdk_pci_device_get_class(struct spdk_pci_device *dev)
+{
+	return dev->device_class;
+}
+
+const char *
+spdk_pci_device_get_device_name(struct spdk_pci_device *dev)
+{
+	return pci_device_get_device_name(dev);
+}
+
+int
+spdk_pci_device_cfg_read8(struct spdk_pci_device *dev, uint8_t *value, uint32_t offset)
+{
+	return pci_device_cfg_read_u8(dev, value, offset);
+}
+
+int
+spdk_pci_device_cfg_write8(struct spdk_pci_device *dev, uint8_t value, uint32_t offset)
+{
+	return pci_device_cfg_write_u8(dev, value, offset);
+}
+
+int
+spdk_pci_device_cfg_read16(struct spdk_pci_device *dev, uint16_t *value, uint32_t offset)
+{
+	return pci_device_cfg_read_u16(dev, value, offset);
+}
+
+int
+spdk_pci_device_cfg_write16(struct spdk_pci_device *dev, uint16_t value, uint32_t offset)
+{
+	return pci_device_cfg_write_u16(dev, value, offset);
+}
+
+int
+spdk_pci_device_cfg_read32(struct spdk_pci_device *dev, uint32_t *value, uint32_t offset)
+{
+	return pci_device_cfg_read_u32(dev, value, offset);
+}
+
+int
+spdk_pci_device_cfg_write32(struct spdk_pci_device *dev, uint32_t value, uint32_t offset)
+{
+	return pci_device_cfg_write_u32(dev, value, offset);
+}
+
+int
+spdk_pci_enumerate(int (*enum_cb)(void *enum_ctx, struct spdk_pci_device *pci_dev), void *enum_ctx)
+{
+	struct pci_device_iterator *pci_dev_iter;
+	struct pci_device *pci_dev;
+	struct pci_slot_match match;
+	int rc;
+
+	rc = spdk_pci_init();
+	if (rc != 0) {
+		return rc;
+	}
+
+	match.domain = PCI_MATCH_ANY;
+	match.bus = PCI_MATCH_ANY;
+	match.dev = PCI_MATCH_ANY;
+	match.func = PCI_MATCH_ANY;
+
+	pci_dev_iter = pci_slot_match_iterator_create(&match);
+
+	rc = 0;
+	while ((pci_dev = pci_device_next(pci_dev_iter))) {
+		pci_device_probe(pci_dev);
+		if (enum_cb(enum_ctx, pci_dev)) {
+			rc = -1;
+		}
+	}
+
+	pci_iterator_destroy(pci_dev_iter);
+
+	return rc;
+}
+
+#else /* !USE_PCIACCESS */
+
+/*
+ * DPDK PCI wrapper functions
+ */
+
+static int
+pci_device_get_u32(struct spdk_pci_device *dev, const char *file, uint32_t *val)
+{
+	char filename[SPDK_PCI_PATH_MAX];
+	FILE *fd;
+	char buf[10];
+	char *end;
+
+	snprintf(filename, sizeof(filename),
+		 SYSFS_PCI_DEVICES "/" PCI_PRI_FMT "/%s",
+		 spdk_pci_device_get_domain(dev), spdk_pci_device_get_bus(dev),
+		 spdk_pci_device_get_dev(dev), spdk_pci_device_get_func(dev), file);
+
+	fd = fopen(filename, "r");
+	if (!fd) {
+		return -1;
+	}
+
+	if (fgets(buf, sizeof(buf), fd) == NULL) {
+		fclose(fd);
+		return -1;
+	}
+
+	*val = strtoul(buf, &end, 0);
+	if ((buf[0] == '\0') || (end == NULL) || (*end != '\n')) {
+		fclose(fd);
+		return -1;
+	}
+
+	fclose(fd);
+	return 0;
+
+}
+
+uint16_t
+spdk_pci_device_get_domain(struct spdk_pci_device *dev)
+{
+	return dev->addr.domain;
+}
+
+uint8_t
+spdk_pci_device_get_bus(struct spdk_pci_device *dev)
+{
+	return dev->addr.bus;
+}
+
+uint8_t
+spdk_pci_device_get_dev(struct spdk_pci_device *dev)
+{
+	return dev->addr.devid;
+}
+
+uint8_t
+spdk_pci_device_get_func(struct spdk_pci_device *dev)
+{
+	return dev->addr.function;
+}
+
+uint16_t
+spdk_pci_device_get_vendor_id(struct spdk_pci_device *dev)
+{
+	return dev->id.vendor_id;
+}
+
+uint16_t
+spdk_pci_device_get_device_id(struct spdk_pci_device *dev)
+{
+	return dev->id.device_id;
+}
+
+uint16_t
+spdk_pci_device_get_subvendor_id(struct spdk_pci_device *dev)
+{
+	return dev->id.subsystem_vendor_id;
+}
+
+uint16_t
+spdk_pci_device_get_subdevice_id(struct spdk_pci_device *dev)
+{
+	return dev->id.subsystem_device_id;
+}
+
+uint32_t
+spdk_pci_device_get_class(struct spdk_pci_device *dev)
+{
+	uint32_t class_code;
+
+	if (pci_device_get_u32(dev, "class", &class_code) < 0) {
+		return 0xFFFFFFFFu;
+	}
+
+	return class_code;
+}
+
+const char *
+spdk_pci_device_get_device_name(struct spdk_pci_device *dev)
+{
+	/* TODO */
+	return NULL;
+}
+
+int
+spdk_pci_device_cfg_read8(struct spdk_pci_device *dev, uint8_t *value, uint32_t offset)
+{
+	return rte_eal_pci_read_config(dev, value, 1, offset) == 1 ? 0 : -1;
+}
+
+int
+spdk_pci_device_cfg_write8(struct spdk_pci_device *dev, uint8_t value, uint32_t offset)
+{
+	return rte_eal_pci_write_config(dev, &value, 1, offset) == 1 ? 0 : -1;
+}
+
+int
+spdk_pci_device_cfg_read16(struct spdk_pci_device *dev, uint16_t *value, uint32_t offset)
+{
+	return rte_eal_pci_read_config(dev, value, 2, offset) == 2 ? 0 : -1;
+}
+
+int
+spdk_pci_device_cfg_write16(struct spdk_pci_device *dev, uint16_t value, uint32_t offset)
+{
+	return rte_eal_pci_write_config(dev, &value, 2, offset) == 2 ? 0 : -1;
+}
+
+int
+spdk_pci_device_cfg_read32(struct spdk_pci_device *dev, uint32_t *value, uint32_t offset)
+{
+	return rte_eal_pci_read_config(dev, value, 4, offset) == 4 ? 0 : -1;
+}
+
+int
+spdk_pci_device_cfg_write32(struct spdk_pci_device *dev, uint32_t value, uint32_t offset)
+{
+	return rte_eal_pci_write_config(dev, &value, 4, offset) == 4 ? 0 : -1;
+}
 
+#endif /* !USE_PCIACCESS */
 
-/* var should be the pointer */
-#define spdk_pcicfg_read32(handle, var, offset)  pci_device_cfg_read_u32(handle, var, offset)
-#define spdk_pcicfg_write32(handle, var, offset) pci_device_cfg_write_u32(handle, *var, offset)
 
 int
-pci_device_get_serial_number(struct pci_device *dev, char *sn, int len)
+spdk_pci_device_get_serial_number(struct spdk_pci_device *dev, char *sn, size_t len)
 {
 	int err;
 	uint32_t pos, header = 0;
@@ -69,7 +387,7 @@ pci_device_get_serial_number(struct pci_device *dev, char *sn, int len)
 	if (len < 17)
 		return -1;
 
-	err = spdk_pcicfg_read32(dev, &header, PCI_CFG_SIZE);
+	err = spdk_pci_device_cfg_read32(dev, &header, PCI_CFG_SIZE);
 	if (err || !header)
 		return -1;
 
@@ -80,8 +398,7 @@ pci_device_get_serial_number(struct pci_device *dev, char *sn, int len)
 				/*skip the header*/
 				pos += 4;
 				for (i = 0; i < 2; i++) {
-					err = spdk_pcicfg_read32(dev,
-								 &buf[i], pos + 4 * i);
+					err = spdk_pci_device_cfg_read32(dev, &buf[i], pos + 4 * i);
 					if (err)
 						return -1;
 				}
@@ -93,7 +410,7 @@ pci_device_get_serial_number(struct pci_device *dev, char *sn, int len)
 		/*0 if no other items exist*/
 		if (pos < PCI_CFG_SIZE)
 			return -1;
-		err = spdk_pcicfg_read32(dev, &header, pos);
+		err = spdk_pci_device_cfg_read32(dev, &header, pos);
 		if (err)
 			return -1;
 	}
@@ -102,7 +419,7 @@ pci_device_get_serial_number(struct pci_device *dev, char *sn, int len)
 
 #ifdef __linux__
 int
-pci_device_has_non_uio_driver(struct pci_device *dev)
+spdk_pci_device_has_non_uio_driver(struct spdk_pci_device *dev)
 {
 	char linkname[SPDK_PCI_PATH_MAX];
 	char driver[SPDK_PCI_PATH_MAX];
@@ -137,7 +454,7 @@ pci_device_has_non_uio_driver(struct pci_device *dev)
 
 #ifdef __FreeBSD__
 int
-pci_device_has_non_uio_driver(struct pci_device *dev)
+spdk_pci_device_has_non_uio_driver(struct spdk_pci_device *dev)
 {
 	struct pci_conf_io	configsel;
 	struct pci_match_conf	pattern;
@@ -189,7 +506,7 @@ pci_device_has_non_uio_driver(struct pci_device *dev)
 #endif
 
 int
-pci_device_unbind_kernel_driver(struct pci_device *dev)
+spdk_pci_device_unbind_kernel_driver(struct spdk_pci_device *dev)
 {
 	int n;
 	FILE *fd;
@@ -221,7 +538,7 @@ error:
 }
 
 static int
-check_modules(char *driver_name)
+check_modules(const char *driver_name)
 {
 	FILE *fd;
 	const char *proc_modules = "/proc/modules";
@@ -245,12 +562,13 @@ check_modules(char *driver_name)
 }
 
 int
-pci_device_bind_uio_driver(struct pci_device *dev, char *driver_name)
+spdk_pci_device_bind_uio_driver(struct spdk_pci_device *dev)
 {
 	int err, n;
 	FILE *fd;
 	char filename[SPDK_PCI_PATH_MAX];
 	char buf[256];
+	const char *driver_name = PCI_UIO_DRIVER;
 
 	err = check_modules(driver_name);
 	if (err < 0) {
@@ -282,9 +600,9 @@ error:
 }
 
 int
-pci_device_switch_to_uio_driver(struct pci_device *dev)
+spdk_pci_device_switch_to_uio_driver(struct spdk_pci_device *dev)
 {
-	if (pci_device_unbind_kernel_driver(dev)) {
+	if (spdk_pci_device_unbind_kernel_driver(dev)) {
 		fprintf(stderr, "Device %d:%d:%d unbind from "
 			"kernel driver failed\n",
 			spdk_pci_device_get_bus(dev),
@@ -292,7 +610,7 @@ pci_device_switch_to_uio_driver(struct pci_device *dev)
 			spdk_pci_device_get_func(dev));
 		return -1;
 	}
-	if (pci_device_bind_uio_driver(dev, PCI_UIO_DRIVER)) {
+	if (spdk_pci_device_bind_uio_driver(dev)) {
 		fprintf(stderr, "Device %d:%d:%d bind to "
 			"uio driver failed\n",
 			spdk_pci_device_get_bus(dev),
@@ -307,7 +625,7 @@ pci_device_switch_to_uio_driver(struct pci_device *dev)
 }
 
 int
-pci_device_claim(struct pci_device *dev)
+spdk_pci_device_claim(struct spdk_pci_device *dev)
 {
 	int dev_fd;
 	char shm_name[64];
diff --git a/src/spdk/lib/util/string.c b/src/spdk/lib/util/string.c
index 2ec50e8..de76048 100644
--- a/src/spdk/lib/util/string.c
+++ b/src/spdk/lib/util/string.c
@@ -38,7 +38,7 @@
 #include "spdk/string.h"
 
 char *
-sprintf_alloc(const char *format, ...)
+spdk_sprintf_alloc(const char *format, ...)
 {
 	va_list args;
 	char *buf;
diff --git a/src/spdk/mk/spdk.common.mk b/src/spdk/mk/spdk.common.mk
index 16ab059..cb5dc43 100644
--- a/src/spdk/mk/spdk.common.mk
+++ b/src/spdk/mk/spdk.common.mk
@@ -84,6 +84,12 @@ LDFLAGS += --coverage
 endif
 endif
 
+ifeq ($(CONFIG_PCIACCESS), y)
+PCIACCESS_LIB=-lpciaccess
+SPDK_PCIACCESS_CFLAGS=-DUSE_PCIACCESS
+COMMON_CFLAGS += $(SPDK_PCIACCESS_CFLAGS)
+endif
+
 CFLAGS   += $(COMMON_CFLAGS) -Wno-pointer-sign -std=gnu99
 
 MAKEFLAGS += --no-print-directory
diff --git a/src/stop.sh b/src/stop.sh
index ea5f273..795ac9a 100755
--- a/src/stop.sh
+++ b/src/stop.sh
@@ -1,4 +1,4 @@
-#!/bin/bash
+#!/bin/sh
 #
 # Copyright (C) 2013 Inktank <info at inktank.com>
 # Copyright (C) 2013 Cloudwatt <libre.licensing at cloudwatt.com>
@@ -33,7 +33,7 @@ do_killall() {
     $SUDO killall -u $MYNAME $1
 }
 
-usage="usage: $0 [all] [mon] [mds] [osd]\n"
+usage="usage: $0 [all] [mon] [mds] [osd] [rgw]\n"
 
 stop_all=1
 stop_mon=0
@@ -58,6 +58,10 @@ while [ $# -ge 1 ]; do
             stop_osd=1
             stop_all=0
             ;;
+        rgw | ceph-rgw )
+            stop_rgw=1
+            stop_all=0
+            ;;
         * )
             printf "$usage"
             exit
@@ -66,18 +70,21 @@ while [ $# -ge 1 ]; do
 done
 
 if [ $stop_all -eq 1 ]; then
-    while read DEV; do
-        # While it is currently possible to create an rbd image with
-        # whitespace chars in its name, krbd will refuse mapping such
-        # an image, so we can safely split on whitespace here.  (The
-        # same goes for whitespace chars in names of the pools that
-        # contain rbd images).
-        DEV="$(echo "${DEV}" | tr -s '[:space:]' | awk '{ print $5 }')"
-        sudo "${CEPH_BIN}"/rbd unmap "${DEV}"
-    done < <("${CEPH_BIN}"/rbd showmapped | tail -n +2)
+    if "${CEPH_BIN}"/rbd showmapped >/dev/null 2>&1; then
+        "${CEPH_BIN}"/rbd showmapped | tail -n +2 |
+        while read DEV; do
+            # While it is currently possible to create an rbd image with
+            # whitespace chars in its name, krbd will refuse mapping such
+            # an image, so we can safely split on whitespace here.  (The
+            # same goes for whitespace chars in names of the pools that
+            # contain rbd images).
+            DEV="$(echo "${DEV}" | tr -s '[:space:]' | awk '{ print $5 }')"
+            sudo "${CEPH_BIN}"/rbd unmap "${DEV}"
+        done
 
-    if [ -n "$("${CEPH_BIN}"/rbd showmapped)" ]; then
-        echo "WARNING: Some rbd images are still mapped!" >&2
+        if [ -n "$("${CEPH_BIN}"/rbd showmapped)" ]; then
+            echo "WARNING: Some rbd images are still mapped!" >&2
+        fi
     fi
 
     for p in ceph-mon ceph-mds ceph-osd radosgw lt-radosgw apache2 ; do
diff --git a/src/test/Makefile-client.am b/src/test/Makefile-client.am
index 4a60b47..b2ad5e8 100644
--- a/src/test/Makefile-client.am
+++ b/src/test/Makefile-client.am
@@ -3,6 +3,8 @@ ceph_dencoder_SOURCES = \
 	test/encoding/ceph_dencoder.cc \
 	$(DENCODER_SOURCES)
 ceph_dencoder_LDADD = \
+	$(LIBRGW) \
+	$(LIBRADOS) \
 	$(LIBRBD_TYPES) \
 	$(LIBOSD_TYPES) \
 	$(LIBOS_TYPES) \
@@ -152,23 +154,23 @@ ceph_test_cls_refcount_CXXFLAGS = $(UNITTEST_CXXFLAGS)
 bin_DEBUGPROGRAMS += ceph_test_cls_refcount
 
 ceph_test_cls_version_SOURCES = test/cls_version/test_cls_version.cc
-ceph_test_cls_version_LDADD = $(LIBRADOS) libcls_version_client.a $(UNITTEST_LDADD) $(RADOS_TEST_LDADD)
+ceph_test_cls_version_LDADD = $(LIBRADOS) libcls_version_client.la $(UNITTEST_LDADD) $(RADOS_TEST_LDADD)
 ceph_test_cls_version_CXXFLAGS = $(UNITTEST_CXXFLAGS)
 bin_DEBUGPROGRAMS += ceph_test_cls_version
 
 ceph_test_cls_log_SOURCES = test/cls_log/test_cls_log.cc
-ceph_test_cls_log_LDADD = $(LIBRADOS) libcls_log_client.a $(UNITTEST_LDADD) $(CEPH_GLOBAL) $(RADOS_TEST_LDADD)
+ceph_test_cls_log_LDADD = $(LIBRADOS) libcls_log_client.la $(UNITTEST_LDADD) $(CEPH_GLOBAL) $(RADOS_TEST_LDADD)
 ceph_test_cls_log_CXXFLAGS = $(UNITTEST_CXXFLAGS)
 bin_DEBUGPROGRAMS += ceph_test_cls_log
 
 ceph_test_cls_statelog_SOURCES = test/cls_statelog/test_cls_statelog.cc
-ceph_test_cls_statelog_LDADD = $(LIBRADOS) libcls_statelog_client.a $(UNITTEST_LDADD) $(CEPH_GLOBAL) $(RADOS_TEST_LDADD)
+ceph_test_cls_statelog_LDADD = $(LIBRADOS) libcls_statelog_client.la $(UNITTEST_LDADD) $(CEPH_GLOBAL) $(RADOS_TEST_LDADD)
 ceph_test_cls_statelog_CXXFLAGS = $(UNITTEST_CXXFLAGS)
 bin_DEBUGPROGRAMS += ceph_test_cls_statelog
 
 ceph_test_cls_replica_log_SOURCES = test/cls_replica_log/test_cls_replica_log.cc
 ceph_test_cls_replica_log_LDADD = \
-	$(LIBRADOS) libcls_replica_log_client.a \
+	$(LIBRADOS) libcls_replica_log_client.la \
 	$(UNITTEST_LDADD) $(CEPH_GLOBAL) $(RADOS_TEST_LDADD)
 ceph_test_cls_replica_log_CXXFLAGS = $(UNITTEST_CXXFLAGS)
 bin_DEBUGPROGRAMS += ceph_test_cls_replica_log
@@ -283,6 +285,11 @@ ceph_test_rados_api_lock_LDADD = $(LIBRADOS) $(UNITTEST_LDADD) $(RADOS_TEST_LDAD
 ceph_test_rados_api_lock_CXXFLAGS = $(UNITTEST_CXXFLAGS)
 bin_DEBUGPROGRAMS += ceph_test_rados_api_lock
 
+ceph_test_rados_api_tmap_migrate_SOURCES = test/librados/tmap_migrate.cc tools/cephfs/DataScan.cc tools/cephfs/MDSUtility.cc
+ceph_test_rados_api_tmap_migrate_LDADD = $(LIBRADOS) $(UNITTEST_LDADD) $(LIBMDS) libcls_cephfs_client.la  $(CEPH_GLOBAL) $(RADOS_TEST_LDADD)
+ceph_test_rados_api_tmap_migrate_CXXFLAGS = $(UNITTEST_CXXFLAGS)
+bin_DEBUGPROGRAMS += ceph_test_rados_api_tmap_migrate
+
 
 ceph_test_stress_watch_SOURCES = test/test_stress_watch.cc
 ceph_test_stress_watch_LDADD = \
@@ -354,6 +361,7 @@ librbd_test_la_SOURCES = \
 	test/librbd/test_librbd.cc \
 	test/librbd/test_ImageWatcher.cc \
 	test/librbd/test_internal.cc \
+	test/librbd/test_mirroring.cc \
 	test/librbd/test_ObjectMap.cc \
 	test/librbd/journal/test_Entries.cc \
 	test/librbd/journal/test_Replay.cc
@@ -423,6 +431,7 @@ noinst_HEADERS += \
 	test/librbd/mock/MockContextWQ.h \
 	test/librbd/mock/MockExclusiveLock.h \
 	test/librbd/mock/MockImageCtx.h \
+	test/librbd/mock/MockImageState.h \
 	test/librbd/mock/MockImageWatcher.h \
 	test/librbd/mock/MockJournal.h \
 	test/librbd/mock/MockObjectMap.h \
@@ -432,12 +441,29 @@ noinst_HEADERS += \
 
 librbd_mirror_test_la_SOURCES = \
 	test/rbd_mirror/test_ClusterWatcher.cc \
-	test/rbd_mirror/test_PoolWatcher.cc
+	test/rbd_mirror/test_PoolWatcher.cc \
+	test/rbd_mirror/test_ImageReplayer.cc \
+	test/rbd_mirror/test_ImageSync.cc \
+	test/rbd_mirror/test_fixture.cc
+
+noinst_HEADERS += \
+	test/rbd_mirror/test_fixture.h \
+	test/rbd_mirror/test_mock_fixture.h \
+	test/rbd_mirror/mock/MockJournaler.h
+
 librbd_mirror_test_la_CXXFLAGS = $(UNITTEST_CXXFLAGS)
 noinst_LTLIBRARIES += librbd_mirror_test.la
 
 unittest_rbd_mirror_SOURCES = \
-	test/rbd_mirror/test_main.cc
+	test/rbd_mirror/test_main.cc \
+	test/rbd_mirror/test_mock_fixture.cc \
+	test/rbd_mirror/test_mock_ImageSync.cc \
+	test/rbd_mirror/image_sync/test_mock_ImageCopyRequest.cc \
+	test/rbd_mirror/image_sync/test_mock_ObjectCopyRequest.cc \
+	test/rbd_mirror/image_sync/test_mock_SnapshotCopyRequest.cc \
+	test/rbd_mirror/image_sync/test_mock_SyncPointCreateRequest.cc \
+	test/rbd_mirror/image_sync/test_mock_SyncPointPruneRequest.cc \
+	test/rbd_mirror/mock/MockJournaler.cc
 unittest_rbd_mirror_CXXFLAGS = $(UNITTEST_CXXFLAGS)
 unittest_rbd_mirror_LDADD = \
 	librbd_mirror_test.la \
@@ -474,9 +500,26 @@ ceph_test_rbd_mirror_LDADD = \
 	$(CEPH_GLOBAL) $(RADOS_TEST_LDADD)
 bin_DEBUGPROGRAMS += ceph_test_rbd_mirror
 
+ceph_test_rbd_mirror_image_replay_SOURCES = \
+	test/rbd_mirror/image_replay.cc
+ceph_test_rbd_mirror_image_replay_LDADD = \
+	librbd_mirror_internal.la \
+	librbd_internal.la \
+	librbd_api.la \
+	$(LIBRBD_TYPES) \
+	libjournal.la \
+	$(LIBRADOS) $(LIBOSDC) \
+	librados_internal.la \
+	libcls_rbd_client.la \
+	libcls_lock_client.la \
+	libcls_journal_client.la \
+	$(CEPH_GLOBAL)
+bin_DEBUGPROGRAMS += ceph_test_rbd_mirror_image_replay
+
 if LINUX
 ceph_test_librbd_fsx_SOURCES = test/librbd/fsx.cc
 ceph_test_librbd_fsx_LDADD = \
+	libjournal.la libcls_journal_client.la \
 	$(LIBKRBD) $(LIBRBD) $(LIBRADOS) \
 	$(CRYPTO_LIBS) $(PTHREAD_LIBS)
 ceph_test_librbd_fsx_CXXFLAGS = $(UNITTEST_CXXFLAGS)
@@ -613,18 +656,6 @@ test_build_librgw_CXXFLAGS = $(AM_CXXFLAGS)
 bin_DEBUGPROGRAMS += test_build_librgw
 endif # WITH_BUILD_TESTS
 
-#unittest_librgw_link_SOURCES = test/librgw_link.cc
-#unittest_librgw_link_LDFLAGS = $(PTHREAD_CFLAGS) ${AM_LDFLAGS}
-#unittest_librgw_link_LDADD = $(LIBRGW) ${UNITTEST_LDADD}
-#unittest_librgw_link_CXXFLAGS = ${CRYPTO_CFLAGS} ${AM_CXXFLAGS} ${UNITTEST_CXXFLAGS}
-#check_TESTPROGRAMS += unittest_librgw_link
-
-#unittest_librgw_SOURCES = test/librgw.cc
-#unittest_librgw_LDFLAGS = -lrt $(PTHREAD_CFLAGS) -lcurl ${AM_LDFLAGS}
-#unittest_librgw_LDADD =  librgw.la $(LIBRADOS) ${UNITTEST_LDADD} -lexpat $(CEPH_GLOBAL)
-#unittest_librgw_CXXFLAGS = ${CRYPTO_CFLAGS} ${AM_CXXFLAGS} ${UNITTEST_CXXFLAGS}
-#check_TESTPROGRAMS += unittest_librgw
-
 ceph_test_cors_SOURCES = test/test_cors.cc
 ceph_test_cors_LDADD = \
 	$(LIBRADOS) $(LIBRGW) $(CEPH_GLOBAL) \
@@ -642,6 +673,13 @@ ceph_test_rgw_manifest_LDADD = \
 ceph_test_rgw_manifest_CXXFLAGS = $(UNITTEST_CXXFLAGS)
 bin_DEBUGPROGRAMS += ceph_test_rgw_manifest
 
+ceph_test_rgw_period_history_SOURCES = test/rgw/test_rgw_period_history.cc
+ceph_test_rgw_period_history_LDADD = \
+	$(LIBRADOS) $(LIBRGW) $(LIBRGW_DEPS) $(CEPH_GLOBAL) \
+	$(UNITTEST_LDADD) $(CRYPTO_LIBS) -lcurl -lexpat
+ceph_test_rgw_period_history_CXXFLAGS = $(UNITTEST_CXXFLAGS)
+bin_DEBUGPROGRAMS += ceph_test_rgw_period_history
+
 ceph_test_rgw_obj_SOURCES = test/rgw/test_rgw_obj.cc
 ceph_test_rgw_obj_LDADD = \
 	$(LIBRADOS) $(LIBRGW) $(LIBRGW_DEPS) $(CEPH_GLOBAL) \
@@ -653,23 +691,24 @@ bin_DEBUGPROGRAMS += ceph_test_rgw_obj
 
 ceph_test_cls_rgw_meta_SOURCES = test/test_rgw_admin_meta.cc
 ceph_test_cls_rgw_meta_LDADD = \
-	$(LIBRADOS) $(LIBRGW) $(CEPH_GLOBAL) \
+	$(LIBRGW) $(LIBRADOS) $(CEPH_GLOBAL) \
 	$(UNITTEST_LDADD) $(CRYPTO_LIBS) \
 	-lcurl -lexpat \
-	libcls_version_client.a libcls_log_client.a \
-	libcls_statelog_client.a libcls_refcount_client.la \
-	libcls_rgw_client.la libcls_user_client.a libcls_lock_client.la
+	libcls_timeindex_client.la \
+	libcls_version_client.la libcls_log_client.la \
+	libcls_statelog_client.la libcls_refcount_client.la \
+	libcls_rgw_client.la libcls_user_client.la libcls_lock_client.la
 ceph_test_cls_rgw_meta_CXXFLAGS = $(UNITTEST_CXXFLAGS)
 bin_DEBUGPROGRAMS += ceph_test_cls_rgw_meta
 
 ceph_test_cls_rgw_log_SOURCES = test/test_rgw_admin_log.cc
 ceph_test_cls_rgw_log_LDADD = \
-	$(LIBRADOS) $(LIBRGW) $(CEPH_GLOBAL) \
+	$(LIBRADOS) $(LIBRGW) $(LIBRGW_DEPS) $(CEPH_GLOBAL) \
 	$(UNITTEST_LDADD) $(CRYPTO_LIBS) \
 	-lcurl -lexpat \
-	libcls_version_client.a libcls_log_client.a \
-	libcls_statelog_client.a libcls_refcount_client.la \
-	libcls_rgw_client.la libcls_user_client.a libcls_lock_client.la
+	libcls_version_client.la libcls_log_client.la \
+	libcls_statelog_client.la libcls_refcount_client.la \
+	libcls_rgw_client.la libcls_user_client.la libcls_lock_client.la
 ceph_test_cls_rgw_log_CXXFLAGS = $(UNITTEST_CXXFLAGS)
 bin_DEBUGPROGRAMS += ceph_test_cls_rgw_log
 
@@ -678,9 +717,10 @@ ceph_test_cls_rgw_opstate_LDADD = \
 	$(LIBRADOS) $(LIBRGW) $(CEPH_GLOBAL) \
 	$(UNITTEST_LDADD) $(CRYPTO_LIBS) \
 	-lcurl -lexpat \
-	libcls_version_client.a libcls_log_client.a  libcls_timeindex_client.a \
-	libcls_statelog_client.a libcls_refcount_client.la \
-	libcls_rgw_client.la libcls_user_client.a libcls_lock_client.la \
+	libcls_version_client.la libcls_log_client.la \
+	libcls_timeindex_client.la \
+	libcls_statelog_client.la libcls_refcount_client.la \
+	libcls_rgw_client.la libcls_user_client.la libcls_lock_client.la \
 	$(LIBRADOS)
 ceph_test_cls_rgw_opstate_CXXFLAGS = $(UNITTEST_CXXFLAGS)
 bin_DEBUGPROGRAMS += ceph_test_cls_rgw_opstate
@@ -692,6 +732,51 @@ ceph_test_cls_rgw_LDADD = \
 ceph_test_cls_rgw_CXXFLAGS = $(UNITTEST_CXXFLAGS)
 bin_DEBUGPROGRAMS += ceph_test_cls_rgw
 
+# librgw/RGW-NFS
+librgw_file_SOURCES = test/librgw_file.cc
+librgw_file_CXXFLAGS = -I$(srcdir)/xxHash $(UNITTEST_CXXFLAGS)
+librgw_file_LDADD = $(UNITTEST_LDADD)  \
+	librgw.la librados.la $(PTHREAD_LIBS) $(CEPH_GLOBAL) $(EXTRALIBS) 
+bin_DEBUGPROGRAMS += librgw_file
+
+librgw_file_cd_SOURCES = test/librgw_file_cd.cc
+librgw_file_cd_CXXFLAGS = -I$(srcdir)/xxHash $(UNITTEST_CXXFLAGS)
+librgw_file_cd_LDADD = $(UNITTEST_LDADD) \
+	librgw.la librados.la $(PTHREAD_LIBS) $(CEPH_GLOBAL) $(EXTRALIBS)
+bin_DEBUGPROGRAMS += librgw_file_cd
+
+librgw_file_gp_SOURCES = test/librgw_file_gp.cc
+librgw_file_gp_CXXFLAGS = -I$(srcdir)/xxHash $(UNITTEST_CXXFLAGS)
+librgw_file_gp_LDADD = $(UNITTEST_LDADD) \
+	librgw.la librados.la $(PTHREAD_LIBS) $(CEPH_GLOBAL) $(EXTRALIBS)
+bin_DEBUGPROGRAMS += librgw_file_gp
+
+librgw_file_aw_SOURCES = test/librgw_file_aw.cc
+librgw_file_aw_CXXFLAGS = -I$(srcdir)/xxHash $(UNITTEST_CXXFLAGS)
+librgw_file_aw_LDADD = $(UNITTEST_LDADD) \
+	librgw.la librados.la $(PTHREAD_LIBS) $(CEPH_GLOBAL) $(EXTRALIBS)
+bin_DEBUGPROGRAMS += librgw_file_aw
+
+librgw_file_nfsns_SOURCES = test/librgw_file_nfsns.cc
+librgw_file_nfsns_CXXFLAGS = -I$(srcdir)/xxHash $(UNITTEST_CXXFLAGS)
+librgw_file_nfsns_LDADD = $(UNITTEST_LDADD) \
+	librgw.la librados.la $(PTHREAD_LIBS) $(CEPH_GLOBAL) $(EXTRALIBS)
+bin_DEBUGPROGRAMS += librgw_file_nfsns
+
+# 
+# test_rgw_token_SOURCES = test/test_rgw_token.cc
+# test_rgw_token_CXXFLAGS = $(UNITTEST_CXXFLAGS)
+# test_rgw_token_LDADD = $(UNITTEST_LDADD) \
+# 	librgw.la $(PTHREAD_LIBS) $(LIBOS) $(CEPH_GLOBAL) $(EXTRALIBS)
+# bin_DEBUGPROGRAMS += test_rgw_token
+
+# test_rgw_ldap_SOURCES = rgw/rgw_ldap.cc test/test_rgw_ldap.cc
+# test_rgw_ldap_CXXFLAGS = $(UNITTEST_CXXFLAGS)
+# test_rgw_ldap_LDADD = $(UNITTEST_LDADD) \
+# 	librados.la $(PTHREAD_LIBS) $(LIBOS) $(CEPH_GLOBAL) ${OPENLDAP_LIBS}
+# 	$(EXTRALIBS)
+# bin_DEBUGPROGRAMS += test_rgw_ldap
+
 endif # WITH_RADOSGW
 
 
diff --git a/src/test/Makefile.am b/src/test/Makefile.am
index ed6a80d..5e7fc85 100644
--- a/src/test/Makefile.am
+++ b/src/test/Makefile.am
@@ -70,6 +70,7 @@ check_SCRIPTS += \
 	test/cephtool-test-mon.sh \
 	test/cephtool-test-mds.sh \
 	test/cephtool-test-rados.sh \
+       test/test_pool_create.sh \
 	unittest_bufferlist.sh \
 	test/encoding/check-generated.sh \
 	test/mon/osd-pool-create.sh \
diff --git a/src/test/bufferlist.cc b/src/test/bufferlist.cc
index d98db9a..008b8cd 100644
--- a/src/test/bufferlist.cc
+++ b/src/test/bufferlist.cc
@@ -217,6 +217,27 @@ TEST(Buffer, constructors) {
     EXPECT_EQ(0, buffer::get_total_alloc());
 }
 
+void bench_buffer_alloc(int size, int num)
+{
+  utime_t start = ceph_clock_now(NULL);
+  for (int i=0; i<num; ++i) {
+    bufferptr p = buffer::create(size);
+    p.zero();
+  }
+  utime_t end = ceph_clock_now(NULL);
+  cout << num << " alloc of size " << size
+       << " in " << (end - start) << std::endl;
+}
+
+TEST(Buffer, BenchAlloc) {
+  bench_buffer_alloc(16384, 1000000);
+  bench_buffer_alloc(4096, 1000000);
+  bench_buffer_alloc(1024, 1000000);
+  bench_buffer_alloc(256, 1000000);
+  bench_buffer_alloc(32, 1000000);
+  bench_buffer_alloc(4, 1000000);
+}
+
 TEST(BufferRaw, ostream) {
   bufferptr ptr(1);
   std::ostringstream stream;
@@ -340,9 +361,9 @@ TEST_F(TestRawPipe, buffer_list_read_fd_zero_copy) {
   bl = bufferlist();
   EXPECT_EQ(0, bl.read_fd_zero_copy(fd, len));
   EXPECT_EQ(len, bl.length());
-  EXPECT_EQ(0u, bl.buffers().front().unused_tail_length());
-  EXPECT_EQ(1u, bl.buffers().size());
-  EXPECT_EQ(len, bl.buffers().front().raw_length());
+  EXPECT_EQ(0u, bl.front().unused_tail_length());
+  EXPECT_EQ(1u, bl.get_num_buffers());
+  EXPECT_EQ(len, bl.front().raw_length());
   EXPECT_EQ(0, memcmp(bl.c_str(), "ABC\n", len));
   EXPECT_TRUE(bl.can_zero_copy());
 }
@@ -457,7 +478,7 @@ TEST(BufferPtr, constructors) {
     bufferptr ptr(std::move(original));
     EXPECT_TRUE(ptr.have_raw());
     EXPECT_FALSE(original.have_raw());
-    EXPECT_EQ(str.compare(0, str.size(), ptr.c_str()), 0);
+    EXPECT_EQ(0, ::memcmp(str.c_str(), ptr.c_str(), len));
     EXPECT_EQ(1, ptr.raw_nref());
   }
 }
@@ -617,6 +638,17 @@ TEST(BufferPtr, is_n_page_sized) {
   }
 }
 
+TEST(BufferPtr, is_partial) {
+  bufferptr a;
+  EXPECT_FALSE(a.is_partial());
+  bufferptr b(10);
+  EXPECT_FALSE(b.is_partial());
+  bufferptr c(b, 1, 9);
+  EXPECT_TRUE(c.is_partial());
+  bufferptr d(b, 0, 9);
+  EXPECT_TRUE(d.is_partial());
+}
+
 TEST(BufferPtr, accessors) {
   unsigned len = 17;
   bufferptr ptr(len);
@@ -791,15 +823,17 @@ TEST(BufferPtr, append) {
 }
 
 TEST(BufferPtr, append_bench) {
-  for (int s=1; s<=8; s*=2) {
+  char src[1048576];
+  memset(src, 0, sizeof(src));
+  for (int s=4; s<=16384; s*=4) {
     utime_t start = ceph_clock_now(NULL);
     int buflen = 1048576;
-    int count = 1000;
+    int count = 4000;
     for (int i=0; i<count; ++i) {
       bufferptr bp(buflen);
       bp.set_length(0);
       for (int64_t j=0; j<buflen; j += s) {
-	bp.append((char *)&j, s);
+	bp.append(src, s);
       }
     }
     utime_t end = ceph_clock_now(NULL);
@@ -910,6 +944,18 @@ TEST(BufferListIterator, constructors) {
     j.advance(-1);
     EXPECT_EQ('X', *j);
   }
+
+  //
+  // const_iterator(const iterator& other)
+  //
+  {
+    bufferlist bl;
+    bl.append("ABC", 3);
+    bufferlist::iterator i(&bl);
+    bufferlist::const_iterator ci(i);
+    EXPECT_EQ(0u, ci.get_off());
+    EXPECT_EQ('A', *ci);
+  }
 }
 
 TEST(BufferListIterator, empty_create_append_copy) {
@@ -923,7 +969,7 @@ TEST(BufferListIterator, empty_create_append_copy) {
   ASSERT_TRUE(out.contents_equal(bl));
 }
 
-TEST(BufferListIterator, operator_equal) {
+TEST(BufferListIterator, operator_assign) {
   bufferlist bl;
   bl.append("ABC", 3);
   bufferlist::iterator i(&bl, 1);
@@ -1015,6 +1061,49 @@ TEST(BufferListIterator, operator_star) {
   }
 }
 
+TEST(BufferListIterator, operator_equal) {
+  bufferlist bl;
+  bl.append("ABC", 3);
+  {
+    bufferlist::iterator i(&bl);
+    bufferlist::iterator j(&bl);
+    EXPECT_EQ(i, j);
+  }
+  {
+    bufferlist::const_iterator ci = bl.begin();
+    bufferlist::iterator i = bl.begin();
+    EXPECT_EQ(i, ci);
+    EXPECT_EQ(ci, i);
+  }
+}
+
+TEST(BufferListIterator, operator_nequal) {
+  bufferlist bl;
+  bl.append("ABC", 3);
+  {
+    bufferlist::iterator i(&bl);
+    bufferlist::iterator j(&bl);
+    EXPECT_NE(++i, j);
+  }
+  {
+    bufferlist::const_iterator ci = bl.begin();
+    bufferlist::const_iterator cj = bl.begin();
+    ++ci;
+    EXPECT_NE(ci, cj);
+    bufferlist::iterator i = bl.begin();
+    EXPECT_NE(i, ci);
+    EXPECT_NE(ci, i);
+  }
+  {
+    // tests begin(), end(), operator++() also
+    string s("ABC");
+    int i = 0;
+    for (auto c : bl) {
+      EXPECT_EQ(s[i++], c);
+    }
+  }
+}
+
 TEST(BufferListIterator, operator_plus_plus) {
   bufferlist bl;
   {
@@ -1026,7 +1115,7 @@ TEST(BufferListIterator, operator_plus_plus) {
     bufferlist::iterator i(&bl);
     ++i;
     EXPECT_EQ('B', *i);
-  }  
+  }
 }
 
 TEST(BufferListIterator, get_current_ptr) {
@@ -1236,6 +1325,33 @@ TEST(BufferList, constructors) {
   }
 }
 
+void bench_bufferlist_alloc(int size, int num, int per)
+{
+  utime_t start = ceph_clock_now(NULL);
+  for (int i=0; i<num; ++i) {
+    bufferlist bl;
+    for (int j=0; j<per; ++j)
+      bl.append(buffer::create(size));
+  }
+  utime_t end = ceph_clock_now(NULL);
+  cout << num << " alloc of size " << size
+       << " in " << (end - start) << std::endl;
+}
+
+TEST(BufferList, BenchAlloc) {
+  bench_bufferlist_alloc(32768, 100000, 16);
+  bench_bufferlist_alloc(25000, 100000, 16);
+  bench_bufferlist_alloc(16384, 100000, 16);
+  bench_bufferlist_alloc(10000, 100000, 16);
+  bench_bufferlist_alloc(8192, 100000, 16);
+  bench_bufferlist_alloc(6000, 100000, 16);
+  bench_bufferlist_alloc(4096, 100000, 16);
+  bench_bufferlist_alloc(1024, 100000, 16);
+  bench_bufferlist_alloc(256, 100000, 16);
+  bench_bufferlist_alloc(32, 100000, 16);
+  bench_bufferlist_alloc(4, 100000, 16);
+}
+
 TEST(BufferList, operator_equal) {
   //
   // list& operator= (const list& other)
@@ -1269,9 +1385,9 @@ TEST(BufferList, operator_equal) {
 
 TEST(BufferList, buffers) {
   bufferlist bl;
-  ASSERT_EQ((unsigned)0, bl.buffers().size());
+  ASSERT_EQ((unsigned)0, bl.get_num_buffers());
   bl.append('A');
-  ASSERT_EQ((unsigned)1, bl.buffers().size());
+  ASSERT_EQ((unsigned)1, bl.get_num_buffers());
 }
 
 TEST(BufferList, get_contiguous) {
@@ -1285,13 +1401,13 @@ TEST(BufferList, get_contiguous) {
     bl.append(a);
     bl.append(b);
     bl.append(c);
-    ASSERT_EQ(3u, bl.buffers().size());
+    ASSERT_EQ(3u, bl.get_num_buffers());
     ASSERT_EQ(0, memcmp("bar", bl.get_contiguous(3, 3), 3));
     ASSERT_EQ(0, memcmp("456", bl.get_contiguous(12, 3), 3));
     ASSERT_EQ(0, memcmp("ABC", bl.get_contiguous(18, 3), 3));
-    ASSERT_EQ(3u, bl.buffers().size());
+    ASSERT_EQ(3u, bl.get_num_buffers());
     ASSERT_EQ(0, memcmp("789ABC", bl.get_contiguous(15, 6), 6));
-    ASSERT_EQ(2u, bl.buffers().size());
+    ASSERT_EQ(2u, bl.get_num_buffers());
   }
 
   {
@@ -1305,7 +1421,7 @@ TEST(BufferList, get_contiguous) {
     bl.append(c);
 
     ASSERT_EQ(0, memcmp("789ABCDEFGHI", bl.get_contiguous(15, 12), 12));
-    ASSERT_EQ(2u, bl.buffers().size());
+    ASSERT_EQ(2u, bl.get_num_buffers());
   }
 
   {
@@ -1319,7 +1435,7 @@ TEST(BufferList, get_contiguous) {
     bl.append(c);
 
     ASSERT_EQ(0, memcmp("z123456789AB", bl.get_contiguous(8, 12), 12));
-    ASSERT_EQ(1u, bl.buffers().size());
+    ASSERT_EQ(1u, bl.get_num_buffers());
   }
 }
 
@@ -1496,13 +1612,13 @@ TEST(BufferList, rebuild_aligned_size_and_memory) {
   EXPECT_FALSE(bl.is_aligned(SIMD_ALIGN));
   EXPECT_FALSE(bl.is_n_align_sized(BUFFER_SIZE));
   EXPECT_EQ(BUFFER_SIZE * 3, bl.length());
-  EXPECT_FALSE(bl.buffers().front().is_aligned(SIMD_ALIGN));
-  EXPECT_FALSE(bl.buffers().front().is_n_align_sized(BUFFER_SIZE));
-  EXPECT_EQ(5U, bl.buffers().size());
+  EXPECT_FALSE(bl.front().is_aligned(SIMD_ALIGN));
+  EXPECT_FALSE(bl.front().is_n_align_sized(BUFFER_SIZE));
+  EXPECT_EQ(5U, bl.get_num_buffers());
   bl.rebuild_aligned_size_and_memory(BUFFER_SIZE, SIMD_ALIGN);
   EXPECT_TRUE(bl.is_aligned(SIMD_ALIGN));
   EXPECT_TRUE(bl.is_n_align_sized(BUFFER_SIZE));
-  EXPECT_EQ(3U, bl.buffers().size());
+  EXPECT_EQ(3U, bl.get_num_buffers());
 }
 
 TEST(BufferList, is_zero) {
@@ -1528,7 +1644,7 @@ TEST(BufferList, clear) {
   bl.append_zero(len);
   bl.clear();
   EXPECT_EQ((unsigned)0, bl.length());
-  EXPECT_EQ((unsigned)0, bl.buffers().size());
+  EXPECT_EQ((unsigned)0, bl.get_num_buffers());
 }
 
 TEST(BufferList, push_front) {
@@ -1540,7 +1656,7 @@ TEST(BufferList, push_front) {
     bufferptr ptr;
     bl.push_front(ptr);
     EXPECT_EQ((unsigned)0, bl.length());
-    EXPECT_EQ((unsigned)0, bl.buffers().size());
+    EXPECT_EQ((unsigned)0, bl.get_num_buffers());
   }
   unsigned len = 17;
   {
@@ -1550,9 +1666,9 @@ TEST(BufferList, push_front) {
     ptr.c_str()[0] = 'B';
     bl.push_front(ptr);
     EXPECT_EQ((unsigned)(1 + len), bl.length());
-    EXPECT_EQ((unsigned)2, bl.buffers().size());
-    EXPECT_EQ('B', bl.buffers().front()[0]);
-    EXPECT_EQ(ptr.get_raw(), bl.buffers().front().get_raw());
+    EXPECT_EQ((unsigned)2, bl.get_num_buffers());
+    EXPECT_EQ('B', bl.front()[0]);
+    EXPECT_EQ(ptr.get_raw(), bl.front().get_raw());
   }
   //
   // void push_front(raw *r)
@@ -1564,9 +1680,9 @@ TEST(BufferList, push_front) {
     ptr.c_str()[0] = 'B';
     bl.push_front(ptr.get_raw());
     EXPECT_EQ((unsigned)(1 + len), bl.length());
-    EXPECT_EQ((unsigned)2, bl.buffers().size());
-    EXPECT_EQ('B', bl.buffers().front()[0]);
-    EXPECT_EQ(ptr.get_raw(), bl.buffers().front().get_raw());
+    EXPECT_EQ((unsigned)2, bl.get_num_buffers());
+    EXPECT_EQ('B', bl.front()[0]);
+    EXPECT_EQ(ptr.get_raw(), bl.front().get_raw());
   }
   //
   // void push_front(ptr&& bp)
@@ -1600,7 +1716,7 @@ TEST(BufferList, push_back) {
     bufferptr ptr;
     bl.push_back(ptr);
     EXPECT_EQ((unsigned)0, bl.length());
-    EXPECT_EQ((unsigned)0, bl.buffers().size());
+    EXPECT_EQ((unsigned)0, bl.get_num_buffers());
   }
   unsigned len = 17;
   {
@@ -1610,9 +1726,9 @@ TEST(BufferList, push_back) {
     ptr.c_str()[0] = 'B';
     bl.push_back(ptr);
     EXPECT_EQ((unsigned)(1 + len), bl.length());
-    EXPECT_EQ((unsigned)2, bl.buffers().size());
-    EXPECT_EQ('B', bl.buffers().back()[0]);
-    EXPECT_EQ(ptr.get_raw(), bl.buffers().back().get_raw());
+    EXPECT_EQ((unsigned)2, bl.get_num_buffers());
+    EXPECT_EQ('B', bl.back()[0]);
+    EXPECT_EQ(ptr.get_raw(), bl.back().get_raw());
   }
   //
   // void push_back(raw *r)
@@ -1624,9 +1740,9 @@ TEST(BufferList, push_back) {
     ptr.c_str()[0] = 'B';
     bl.push_back(ptr.get_raw());
     EXPECT_EQ((unsigned)(1 + len), bl.length());
-    EXPECT_EQ((unsigned)2, bl.buffers().size());
-    EXPECT_EQ('B', bl.buffers().back()[0]);
-    EXPECT_EQ(ptr.get_raw(), bl.buffers().back().get_raw());
+    EXPECT_EQ((unsigned)2, bl.get_num_buffers());
+    EXPECT_EQ('B', bl.back()[0]);
+    EXPECT_EQ(ptr.get_raw(), bl.back().get_raw());
   }
   //
   // void push_back(ptr&& bp)
@@ -1654,14 +1770,14 @@ TEST(BufferList, push_back) {
 TEST(BufferList, is_contiguous) {
   bufferlist bl;
   EXPECT_TRUE(bl.is_contiguous());
-  EXPECT_EQ((unsigned)0, bl.buffers().size());
+  EXPECT_EQ((unsigned)0, bl.get_num_buffers());
   bl.append('A');  
   EXPECT_TRUE(bl.is_contiguous());
-  EXPECT_EQ((unsigned)1, bl.buffers().size());
+  EXPECT_EQ((unsigned)1, bl.get_num_buffers());
   bufferptr ptr(1);
   bl.push_back(ptr);
   EXPECT_FALSE(bl.is_contiguous());
-  EXPECT_EQ((unsigned)2, bl.buffers().size());
+  EXPECT_EQ((unsigned)2, bl.get_num_buffers());
 }
 
 TEST(BufferList, rebuild) {
@@ -1683,11 +1799,11 @@ TEST(BufferList, rebuild) {
     const std::string str(CEPH_PAGE_SIZE, 'X');
     bl.append(str.c_str(), str.size());
     bl.append(str.c_str(), str.size());
-    EXPECT_EQ((unsigned)2, bl.buffers().size());
-    EXPECT_TRUE(bl.is_aligned(CEPH_BUFFER_APPEND_SIZE));
+    EXPECT_EQ((unsigned)2, bl.get_num_buffers());
+    //EXPECT_TRUE(bl.is_aligned(CEPH_BUFFER_APPEND_SIZE));
     bl.rebuild();
     EXPECT_TRUE(bl.is_page_aligned());
-    EXPECT_EQ((unsigned)1, bl.buffers().size());
+    EXPECT_EQ((unsigned)1, bl.get_num_buffers());
   }
   {
     bufferlist bl;
@@ -1713,11 +1829,11 @@ TEST(BufferList, rebuild_page_aligned) {
       ptr.set_length(CEPH_PAGE_SIZE);
       bl.append(ptr);
     }
-    EXPECT_EQ((unsigned)1, bl.buffers().size());
+    EXPECT_EQ((unsigned)1, bl.get_num_buffers());
     EXPECT_FALSE(bl.is_page_aligned());
     bl.rebuild_page_aligned();
     EXPECT_TRUE(bl.is_page_aligned());
-    EXPECT_EQ((unsigned)1, bl.buffers().size());
+    EXPECT_EQ((unsigned)1, bl.get_num_buffers());
   }
   {
     bufferlist bl;
@@ -1725,7 +1841,7 @@ TEST(BufferList, rebuild_page_aligned) {
     char *p = ptr.c_str();
     bl.append(ptr);
     bl.rebuild_page_aligned();
-    EXPECT_EQ(p, bl.buffers().front().c_str());
+    EXPECT_EQ(p, bl.front().c_str());
   }
   {
     bufferlist bl;
@@ -1769,12 +1885,12 @@ TEST(BufferList, rebuild_page_aligned) {
       EXPECT_TRUE(ptr.is_n_page_sized());
       bl.append(ptr);
     }
-    EXPECT_EQ((unsigned)6, bl.buffers().size());
+    EXPECT_EQ((unsigned)6, bl.get_num_buffers());
     EXPECT_TRUE((bl.length() & ~CEPH_PAGE_MASK) == 0);
     EXPECT_FALSE(bl.is_page_aligned());
     bl.rebuild_page_aligned();
     EXPECT_TRUE(bl.is_page_aligned());
-    EXPECT_EQ((unsigned)4, bl.buffers().size());
+    EXPECT_EQ((unsigned)4, bl.get_num_buffers());
   }
 }
 
@@ -1790,11 +1906,11 @@ TEST(BufferList, claim) {
     to.append(ptr);
   }
   EXPECT_EQ((unsigned)4, to.length());
-  EXPECT_EQ((unsigned)1, to.buffers().size());
+  EXPECT_EQ((unsigned)1, to.get_num_buffers());
   to.claim(from);
   EXPECT_EQ((unsigned)2, to.length());
-  EXPECT_EQ((unsigned)1, to.buffers().size());
-  EXPECT_EQ((unsigned)0, from.buffers().size());
+  EXPECT_EQ((unsigned)1, to.get_num_buffers());
+  EXPECT_EQ((unsigned)0, from.get_num_buffers());
   EXPECT_EQ((unsigned)0, from.length());
 }
 
@@ -1810,13 +1926,13 @@ TEST(BufferList, claim_append) {
     to.append(ptr);
   }
   EXPECT_EQ((unsigned)4, to.length());
-  EXPECT_EQ((unsigned)1, to.buffers().size());
+  EXPECT_EQ((unsigned)1, to.get_num_buffers());
   to.claim_append(from);
   EXPECT_EQ((unsigned)(4 + 2), to.length());
-  EXPECT_EQ((unsigned)4, to.buffers().front().length());
-  EXPECT_EQ((unsigned)2, to.buffers().back().length());
-  EXPECT_EQ((unsigned)2, to.buffers().size());
-  EXPECT_EQ((unsigned)0, from.buffers().size());
+  EXPECT_EQ((unsigned)4, to.front().length());
+  EXPECT_EQ((unsigned)2, to.back().length());
+  EXPECT_EQ((unsigned)2, to.get_num_buffers());
+  EXPECT_EQ((unsigned)0, from.get_num_buffers());
   EXPECT_EQ((unsigned)0, from.length());
 }
 
@@ -1832,13 +1948,13 @@ TEST(BufferList, claim_prepend) {
     to.append(ptr);
   }
   EXPECT_EQ((unsigned)4, to.length());
-  EXPECT_EQ((unsigned)1, to.buffers().size());
+  EXPECT_EQ((unsigned)1, to.get_num_buffers());
   to.claim_prepend(from);
   EXPECT_EQ((unsigned)(2 + 4), to.length());
-  EXPECT_EQ((unsigned)2, to.buffers().front().length());
-  EXPECT_EQ((unsigned)4, to.buffers().back().length());
-  EXPECT_EQ((unsigned)2, to.buffers().size());
-  EXPECT_EQ((unsigned)0, from.buffers().size());
+  EXPECT_EQ((unsigned)2, to.front().length());
+  EXPECT_EQ((unsigned)4, to.back().length());
+  EXPECT_EQ((unsigned)2, to.get_num_buffers());
+  EXPECT_EQ((unsigned)0, from.get_num_buffers());
   EXPECT_EQ((unsigned)0, from.length());
 }
 
@@ -1928,10 +2044,10 @@ TEST(BufferList, append) {
   //
   {
     bufferlist bl;
-    EXPECT_EQ((unsigned)0, bl.buffers().size());
+    EXPECT_EQ((unsigned)0, bl.get_num_buffers());
     bl.append('A');
-    EXPECT_EQ((unsigned)1, bl.buffers().size());
-    EXPECT_TRUE(bl.is_aligned(CEPH_BUFFER_APPEND_SIZE));
+    EXPECT_EQ((unsigned)1, bl.get_num_buffers());
+    //EXPECT_TRUE(bl.is_aligned(CEPH_BUFFER_APPEND_SIZE));
   }
   //
   // void append(const char *data, unsigned len);
@@ -1940,9 +2056,9 @@ TEST(BufferList, append) {
     bufferlist bl(CEPH_PAGE_SIZE);
     std::string str(CEPH_PAGE_SIZE * 2, 'X');
     bl.append(str.c_str(), str.size());
-    EXPECT_EQ((unsigned)2, bl.buffers().size());
-    EXPECT_EQ(CEPH_PAGE_SIZE, bl.buffers().front().length());
-    EXPECT_EQ(CEPH_PAGE_SIZE, bl.buffers().back().length());
+    EXPECT_EQ((unsigned)2, bl.get_num_buffers());
+    EXPECT_EQ(CEPH_PAGE_SIZE, bl.front().length());
+    EXPECT_EQ(CEPH_PAGE_SIZE, bl.back().length());
   }
   //
   // void append(const std::string& s);
@@ -1951,27 +2067,27 @@ TEST(BufferList, append) {
     bufferlist bl(CEPH_PAGE_SIZE);
     std::string str(CEPH_PAGE_SIZE * 2, 'X');
     bl.append(str);
-    EXPECT_EQ((unsigned)2, bl.buffers().size());
-    EXPECT_EQ(CEPH_PAGE_SIZE, bl.buffers().front().length());
-    EXPECT_EQ(CEPH_PAGE_SIZE, bl.buffers().back().length());
+    EXPECT_EQ((unsigned)2, bl.get_num_buffers());
+    EXPECT_EQ(CEPH_PAGE_SIZE, bl.front().length());
+    EXPECT_EQ(CEPH_PAGE_SIZE, bl.back().length());
   }
   //
   // void append(const ptr& bp);
   //
   {
     bufferlist bl;
-    EXPECT_EQ((unsigned)0, bl.buffers().size());
+    EXPECT_EQ((unsigned)0, bl.get_num_buffers());
     EXPECT_EQ((unsigned)0, bl.length());
     {
       bufferptr ptr;
       bl.append(ptr);
-      EXPECT_EQ((unsigned)0, bl.buffers().size());
+      EXPECT_EQ((unsigned)0, bl.get_num_buffers());
       EXPECT_EQ((unsigned)0, bl.length());
     }
     {
       bufferptr ptr(3);
       bl.append(ptr);
-      EXPECT_EQ((unsigned)1, bl.buffers().size());
+      EXPECT_EQ((unsigned)1, bl.get_num_buffers());
       EXPECT_EQ((unsigned)3, bl.length());
     }
   }
@@ -1981,27 +2097,27 @@ TEST(BufferList, append) {
   {
     bufferlist bl;
     bl.append('A');
-    bufferptr back(bl.buffers().back());
+    bufferptr back(bl.back());
     bufferptr in(back);
-    EXPECT_EQ((unsigned)1, bl.buffers().size());
+    EXPECT_EQ((unsigned)1, bl.get_num_buffers());
     EXPECT_EQ((unsigned)1, bl.length());
     EXPECT_DEATH(bl.append(in, (unsigned)100, (unsigned)100), "");
     EXPECT_LT((unsigned)0, in.unused_tail_length());
     in.append('B');
     bl.append(in, back.end(), 1);
-    EXPECT_EQ((unsigned)1, bl.buffers().size());
+    EXPECT_EQ((unsigned)1, bl.get_num_buffers());
     EXPECT_EQ((unsigned)2, bl.length());
     EXPECT_EQ('B', bl[1]);
   }
   {
     bufferlist bl;
-    EXPECT_EQ((unsigned)0, bl.buffers().size());
+    EXPECT_EQ((unsigned)0, bl.get_num_buffers());
     EXPECT_EQ((unsigned)0, bl.length());
     bufferptr ptr(2);
     ptr.set_length(0);
     ptr.append("AB", 2);
     bl.append(ptr, 1, 1);
-    EXPECT_EQ((unsigned)1, bl.buffers().size());
+    EXPECT_EQ((unsigned)1, bl.get_num_buffers());
     EXPECT_EQ((unsigned)1, bl.length());
   }
   //
@@ -2013,7 +2129,7 @@ TEST(BufferList, append) {
     bufferlist other;
     other.append('B');
     bl.append(other);
-    EXPECT_EQ((unsigned)2, bl.buffers().size());
+    EXPECT_EQ((unsigned)2, bl.get_num_buffers());
     EXPECT_EQ('B', bl[1]);
   }
   //
@@ -2053,10 +2169,10 @@ TEST(BufferList, append) {
 TEST(BufferList, append_zero) {
   bufferlist bl;
   bl.append('A');
-  EXPECT_EQ((unsigned)1, bl.buffers().size());
+  EXPECT_EQ((unsigned)1, bl.get_num_buffers());
   EXPECT_EQ((unsigned)1, bl.length());
   bl.append_zero(1);
-  EXPECT_EQ((unsigned)2, bl.buffers().size());
+  EXPECT_EQ((unsigned)2, bl.get_num_buffers());
   EXPECT_EQ((unsigned)2, bl.length());
   EXPECT_EQ('\0', bl[1]);
 }
@@ -2068,7 +2184,7 @@ TEST(BufferList, operator_brackets) {
   bufferlist other;
   other.append('B');
   bl.append(other);
-  EXPECT_EQ((unsigned)2, bl.buffers().size());
+  EXPECT_EQ((unsigned)2, bl.get_num_buffers());
   EXPECT_EQ('B', bl[1]);
 }
 
@@ -2079,7 +2195,7 @@ TEST(BufferList, c_str) {
   bufferlist other;
   other.append('B');
   bl.append(other);
-  EXPECT_EQ((unsigned)2, bl.buffers().size());
+  EXPECT_EQ((unsigned)2, bl.get_num_buffers());
   EXPECT_EQ(0, ::memcmp("AB", bl.c_str(), 2));
 }
 
@@ -2096,12 +2212,12 @@ TEST(BufferList, substr_of) {
     bufferptr ptr(s[i], strlen(s[i]));
     bl.push_back(ptr);
   }
-  EXPECT_EQ((unsigned)4, bl.buffers().size());
+  EXPECT_EQ((unsigned)4, bl.get_num_buffers());
 
   bufferlist other;
   other.append("TO BE CLEARED");
   other.substr_of(bl, 4, 4);
-  EXPECT_EQ((unsigned)2, other.buffers().size());
+  EXPECT_EQ((unsigned)2, other.get_num_buffers());
   EXPECT_EQ((unsigned)4, other.length());
   EXPECT_EQ(0, ::memcmp("EFGH", other.c_str(), 4));
 }
@@ -2119,13 +2235,13 @@ TEST(BufferList, splice) {
     bufferptr ptr(s[i], strlen(s[i]));
     bl.push_back(ptr);
   }
-  EXPECT_EQ((unsigned)4, bl.buffers().size());
+  EXPECT_EQ((unsigned)4, bl.get_num_buffers());
   bl.splice(0, 0);
 
   bufferlist other;
   other.append('X');
   bl.splice(4, 4, &other);
-  EXPECT_EQ((unsigned)3, other.buffers().size());
+  EXPECT_EQ((unsigned)3, other.get_num_buffers());
   EXPECT_EQ((unsigned)5, other.length());
   EXPECT_EQ(0, ::memcmp("XEFGH", other.c_str(), other.length()));
   EXPECT_EQ((unsigned)8, bl.length());
@@ -2219,7 +2335,7 @@ TEST(BufferList, read_fd) {
   EXPECT_EQ(-EBADF, bl.read_fd(fd, len));
   fd = ::open(FILENAME, O_RDONLY);
   EXPECT_EQ(len, (unsigned)bl.read_fd(fd, len));
-  EXPECT_EQ(CEPH_BUFFER_APPEND_SIZE - len, bl.buffers().front().unused_tail_length());
+  //EXPECT_EQ(CEPH_BUFFER_APPEND_SIZE - len, bl.front().unused_tail_length());
   EXPECT_EQ(len, bl.length());
   ::close(fd);
   ::unlink(FILENAME);
@@ -2256,6 +2372,24 @@ TEST(BufferList, write_fd) {
   ::unlink(FILENAME);
 }
 
+TEST(BufferList, write_fd_offset) {
+  ::unlink(FILENAME);
+  int fd = ::open(FILENAME, O_WRONLY|O_CREAT|O_TRUNC, 0600);
+  bufferlist bl;
+  for (unsigned i = 0; i < IOV_MAX * 2; i++) {
+    bufferptr ptr("A", 1);
+    bl.push_back(ptr);
+  }
+  uint64_t offset = 200;
+  EXPECT_EQ(0, bl.write_fd(fd, offset));
+  ::close(fd);
+  struct stat st;
+  memset(&st, 0, sizeof(st));
+  ::stat(FILENAME, &st);
+  EXPECT_EQ(IOV_MAX * 2 + offset, (unsigned)st.st_size);
+  ::unlink(FILENAME);
+}
+
 TEST(BufferList, crc32c) {
   bufferlist bl;
   __u32 crc = 0;
@@ -2698,6 +2832,15 @@ TEST(BufferList, InvalidateCrc) {
   EXPECT_NE(crc, bl.crc32c(0));
 }
 
+TEST(BufferList, TestIsProvidedBuffer) {
+  char buff[100];
+  bufferlist bl;
+  bl.push_back(buffer::create_static(100, buff));
+  ASSERT_TRUE(bl.is_provided_buffer(buff));
+  bl.append_zero(100);
+  ASSERT_FALSE(bl.is_provided_buffer(buff));
+}
+
 TEST(BufferHash, all) {
   {
     bufferlist bl;
diff --git a/src/test/centos-6/ceph.spec.in b/src/test/centos-6/ceph.spec.in
index 498eac4..b52d7e2 100644
--- a/src/test/centos-6/ceph.spec.in
+++ b/src/test/centos-6/ceph.spec.in
@@ -46,7 +46,8 @@ restorecon -R /etc/rc\.d/init\.d/ceph > /dev/null 2>&1; \
 restorecon -R /etc/rc\.d/init\.d/radosgw > /dev/null 2>&1; \
 restorecon -R /var/run/ceph > /dev/null 2>&1; \
 restorecon -R /var/lib/ceph > /dev/null 2>&1; \
-restorecon -R /var/log/ceph > /dev/null 2>&1;
+restorecon -R /var/log/ceph > /dev/null 2>&1; \
+restorecon -R /var/log/radosgw > /dev/null 2>&1;
 %endif
 
 %{!?_udevrulesdir: %global _udevrulesdir /lib/udev/rules.d}
@@ -108,11 +109,6 @@ BuildRequires:	boost-devel
 BuildRequires:  cmake
 BuildRequires:	cryptsetup
 BuildRequires:	fuse-devel
-%if 0%{?suse_version}
-BuildRequires:	python-Cython
-%else
-BuildRequires:	Cython
-%endif
 BuildRequires:	gdbm
 BuildRequires:	hdparm
 BuildRequires:	leveldb-devel > 1.2
@@ -155,15 +151,20 @@ BuildRequires:	libbz2-devel
 %if 0%{with tcmalloc}
 BuildRequires:	gperftools-devel
 %endif
+BuildRequires:  btrfsprogs
 BuildRequires:	mozilla-nss-devel
 BuildRequires:	keyutils-devel
 BuildRequires:	libatomic-ops-devel
+BuildRequires:  libopenssl-devel
 BuildRequires:  lsb-release
+BuildRequires:  openldap2-devel
+BuildRequires:	python-Cython
 %endif
 %if 0%{?fedora} || 0%{?rhel} 
 %if 0%{?_with_systemd}
 Requires:	systemd
 %endif
+BuildRequires:	btrfs-progs
 BuildRequires:	nss-devel
 BuildRequires:	keyutils-libs-devel
 BuildRequires:	libatomic_ops-devel
@@ -171,7 +172,10 @@ Requires(post):	chkconfig
 Requires(preun):	chkconfig
 Requires(preun):	initscripts
 BuildRequires:	gperftools-devel
+BuildRequires:  openldap-devel
+BuildRequires:  openssl-devel
 BuildRequires:  redhat-lsb-core
+BuildRequires:	Cython
 %endif
 # boost
 %if 0%{?fedora} || 0%{?rhel} 
@@ -208,6 +212,10 @@ BuildRequires:	python-sphinx10
 %if 0%{?fedora} || 0%{?suse_version} || 0%{?rhel} >= 7
 BuildRequires:	python-sphinx
 %endif
+#hardened-cc1
+%if 0%{?fedora} || 0%{?rhel}
+BuildRequires:  redhat-rpm-config
+%endif
 
 %description
 Ceph is a massively scalable, open-source, distributed storage system that runs
@@ -224,6 +232,7 @@ Requires:      ceph-common = %{epoch}:%{version}-%{release}
 Requires:      librbd1 = %{epoch}:%{version}-%{release}
 Requires:      librados2 = %{epoch}:%{version}-%{release}
 Requires:      libcephfs1 = %{epoch}:%{version}-%{release}
+Requires:      librgw2 = %{epoch}:%{version}-%{release}
 %if 0%{with selinux}
 Requires:      ceph-selinux = %{epoch}:%{version}-%{release}
 %endif
@@ -253,6 +262,7 @@ Summary:	Ceph Common
 Group:		System Environment/Base
 Requires:	librbd1 = %{epoch}:%{version}-%{release}
 Requires:	librados2 = %{epoch}:%{version}-%{release}
+Requires:	libcephfs1 = %{epoch}:%{version}-%{release}
 Requires:	python-rados = %{epoch}:%{version}-%{release}
 Requires:	python-rbd = %{epoch}:%{version}-%{release}
 Requires:	python-cephfs = %{epoch}:%{version}-%{release}
@@ -300,14 +310,12 @@ of cluster membership, configuration, and state.
 %package fuse
 Summary:	Ceph fuse-based client
 Group:		System Environment/Base
-Requires:	%{name}
 %description fuse
 FUSE based client for Ceph distributed network file system
 
 %package -n rbd-fuse
 Summary:	Ceph fuse-based client
 Group:		System Environment/Base
-Requires:	%{name}
 Requires:	librados2 = %{epoch}:%{version}-%{release}
 Requires:	librbd1 = %{epoch}:%{version}-%{release}
 %description -n rbd-fuse
@@ -316,7 +324,6 @@ FUSE based client to map Ceph rbd images to files
 %package -n rbd-mirror
 Summary:	Ceph daemon for mirroring RBD images
 Group:		System Environment/Base
-Requires:	%{name}
 Requires:	ceph-common = %{epoch}:%{version}-%{release}
 Requires:	librados2 = %{epoch}:%{version}-%{release}
 %description -n rbd-mirror
@@ -326,7 +333,6 @@ changes asynchronously.
 %package -n rbd-nbd
 Summary:	Ceph RBD client base on NBD
 Group:		System Environment/Base
-Requires:	%{name}
 Requires:	librados2 = %{epoch}:%{version}-%{release}
 Requires:	librbd1 = %{epoch}:%{version}-%{release}
 %description -n rbd-nbd
@@ -340,6 +346,7 @@ Requires:	ceph-common = %{epoch}:%{version}-%{release}
 Requires:	ceph-selinux = %{epoch}:%{version}-%{release}
 %endif
 Requires:	librados2 = %{epoch}:%{version}-%{release}
+Requires:	librgw2 = %{epoch}:%{version}-%{release}
 %if 0%{?rhel} || 0%{?fedora}
 Requires:	mailcap
 # python-flask for powerdns
@@ -350,16 +357,17 @@ Requires:	python-flask
 Requires:      python-Flask
 %endif
 %description radosgw
-This package is an S3 HTTP REST gateway for the RADOS object store. It
-is implemented as a FastCGI module using libfcgi, and can be used in
-conjunction with any FastCGI capable web server.
+RADOS is a distributed object store used by the Ceph distributed
+storage system.  This package provides a REST gateway to the
+object store that aims to implement a superset of Amazon's S3
+service as well as the OpenStack Object Storage ("Swift") API.
 
 %if %{with ocf}
 %package resource-agents
 Summary:	OCF-compliant resource agents for Ceph daemons
 Group:		System Environment/Base
 License:	LGPL-2.0
-Requires:	%{name} = %{epoch}:%{version}
+Requires:	ceph-base = %{epoch}:%{version}
 Requires:	resource-agents
 %description resource-agents
 Resource agents for monitoring and managing Ceph daemons
@@ -406,6 +414,24 @@ Obsoletes:	ceph-devel < %{epoch}:%{version}-%{release}
 This package contains libraries and headers needed to develop programs
 that use RADOS object store.
 
+%package -n librgw2
+Summary:	RADOS gateway client library
+Group:		System Environment/Libraries
+License:	LGPL-2.0
+Requires:	librados2 = %{epoch}:%{version}-%{release}
+%description -n librgw2
+This package provides a library implementation of the RADOS gateway
+(distributed object store with S3 and Swift personalities).
+
+%package -n librgw2-devel
+Summary:	RADOS gateway client library
+Group:		Development/Libraries
+License:	LGPL-2.0
+Requires:	librados2 = %{epoch}:%{version}-%{release}
+%description -n librgw2-devel
+This package contains libraries and headers needed to develop programs
+that use RADOS gateway client library.
+
 %package -n python-rados
 Summary:	Python libraries for the RADOS object store
 Group:		System Environment/Libraries
@@ -564,7 +590,7 @@ This package contains the Java libraries for the Ceph File System.
 %package selinux
 Summary:	SELinux support for Ceph MON, OSD and MDS
 Group:		System Environment/Base
-Requires:	%{name}
+Requires:	ceph-base = %{epoch}:%{version}-%{release}
 Requires:	policycoreutils, libselinux-utils
 Requires(post): selinux-policy-base >= %{_selinux_policy_version}, policycoreutils, gawk
 Requires(postun): policycoreutils
@@ -601,7 +627,6 @@ Summary:	Compatibility package for Ceph headers
 Group:		Development/Libraries
 License:	LGPL-2.0
 Obsoletes:	ceph-devel
-Requires:	%{name} = %{epoch}:%{version}-%{release}
 Requires:	librados2-devel = %{epoch}:%{version}-%{release}
 Requires:	libradosstriper1-devel = %{epoch}:%{version}-%{release}
 Requires:	librbd1-devel = %{epoch}:%{version}-%{release}
@@ -733,11 +758,13 @@ install -m 0644 -D etc/sysconfig/ceph $RPM_BUILD_ROOT%{_localstatedir}/adm/fillu
   install -m 0644 -D systemd/ceph-create-keys at .service $RPM_BUILD_ROOT%{_unitdir}/ceph-create-keys at .service
   install -m 0644 -D systemd/ceph-mds at .service $RPM_BUILD_ROOT%{_unitdir}/ceph-mds at .service
   install -m 0644 -D systemd/ceph-radosgw at .service $RPM_BUILD_ROOT%{_unitdir}/ceph-radosgw at .service
+  install -m 0644 -D systemd/ceph-rbd-mirror at .service $RPM_BUILD_ROOT%{_unitdir}/ceph-rbd-mirror at .service
   install -m 0644 -D systemd/ceph.target $RPM_BUILD_ROOT%{_unitdir}/ceph.target
   install -m 0644 -D systemd/ceph-osd.target $RPM_BUILD_ROOT%{_unitdir}/ceph-osd.target
   install -m 0644 -D systemd/ceph-mon.target $RPM_BUILD_ROOT%{_unitdir}/ceph-mon.target
   install -m 0644 -D systemd/ceph-mds.target $RPM_BUILD_ROOT%{_unitdir}/ceph-mds.target
   install -m 0644 -D systemd/ceph-radosgw.target $RPM_BUILD_ROOT%{_unitdir}/ceph-radosgw.target
+  install -m 0644 -D systemd/ceph-rbd-mirror.target $RPM_BUILD_ROOT%{_unitdir}/ceph-rbd-mirror.target
   install -m 0644 -D systemd/ceph-disk at .service $RPM_BUILD_ROOT%{_unitdir}/ceph-disk at .service
   install -m 0755 -D systemd/ceph $RPM_BUILD_ROOT%{_sbindir}/rcceph
 %else
@@ -942,6 +969,9 @@ rm -rf $RPM_BUILD_ROOT
 %{_bindir}/ceph-rbdnamer
 %{_bindir}/ceph-syn
 %{_bindir}/ceph-crush-location
+%{_bindir}/cephfs-data-scan
+%{_bindir}/cephfs-journal-tool
+%{_bindir}/cephfs-table-tool
 %{_bindir}/rados
 %{_bindir}/rbd
 %{_bindir}/rbd-replay
@@ -1018,9 +1048,6 @@ fi
 #################################################################################
 %files mds
 %{_bindir}/ceph-mds
-%{_bindir}/cephfs-journal-tool
-%{_bindir}/cephfs-table-tool
-%{_bindir}/cephfs-data-scan
 %{_mandir}/man8/ceph-mds.8*
 %if 0%{?_with_systemd}
 %{_unitdir}/ceph-mds at .service
@@ -1067,6 +1094,10 @@ fi
 %defattr(-,root,root,-)
 %{_bindir}/rbd-mirror
 %{_mandir}/man8/rbd-mirror.8*
+%if 0%{?_with_systemd}
+%{_unitdir}/ceph-rbd-mirror at .service
+%{_unitdir}/ceph-rbd-mirror.target
+%endif
 
 #################################################################################
 %files -n rbd-nbd
@@ -1079,6 +1110,7 @@ fi
 %defattr(-,root,root,-)
 %{_bindir}/radosgw
 %{_bindir}/radosgw-admin
+%{_bindir}/radosgw-token
 %{_bindir}/radosgw-object-expirer
 %{_mandir}/man8/radosgw.8*
 %{_mandir}/man8/radosgw-admin.8*
@@ -1161,12 +1193,27 @@ fi
 
 #################################################################################
 %if %{with ocf}
+
 %files resource-agents
 %defattr(0755,root,root,-)
-%dir /usr/lib/ocf
-%dir /usr/lib/ocf/resource.d
-%dir /usr/lib/ocf/resource.d/ceph
-/usr/lib/ocf/resource.d/%{name}/*
+# N.B. src/ocf/Makefile.am uses $(prefix)/lib
+%dir %{_prefix}/lib/ocf
+%dir %{_prefix}/lib/ocf/resource.d
+%dir %{_prefix}/lib/ocf/resource.d/ceph
+%if 0%{_with_systemd}
+%exclude %{_prefix}/lib/ocf/resource.d/ceph/ceph
+%exclude %{_prefix}/lib/ocf/resource.d/ceph/mds
+%exclude %{_prefix}/lib/ocf/resource.d/ceph/mon
+%exclude %{_prefix}/lib/ocf/resource.d/ceph/osd
+%endif
+%if ! 0%{_with_systemd}
+%{_prefix}/lib/ocf/resource.d/ceph/ceph
+%{_prefix}/lib/ocf/resource.d/ceph/mds
+%{_prefix}/lib/ocf/resource.d/ceph/mon
+%{_prefix}/lib/ocf/resource.d/ceph/osd
+%endif
+%{_prefix}/lib/ocf/resource.d/ceph/rbd
+
 %endif
 
 #################################################################################
@@ -1206,7 +1253,8 @@ fi
 #################################################################################
 %files -n python-rados
 %defattr(-,root,root,-)
-%{python_sitelib}/rados.py*
+%{python_sitearch}/rados.so
+%{python_sitearch}/rados-*.egg-info
 
 #################################################################################
 %files -n libradosstriper1
@@ -1256,6 +1304,25 @@ ln -sf %{_libdir}/librbd.so.1 /usr/lib64/qemu/librbd.so.1
 %endif
 
 #################################################################################
+%files -n librgw2
+%defattr(-,root,root,-)
+%{_libdir}/librgw.so.*
+
+%post -n librgw2
+/sbin/ldconfig
+
+%postun -n librgw2
+/sbin/ldconfig
+
+#################################################################################
+%files -n librgw2-devel
+%defattr(-,root,root,-)
+%dir %{_includedir}/rados
+%{_includedir}/rados/librgw.h
+%{_includedir}/rados/rgw_file.h
+%{_libdir}/librgw.so
+
+#################################################################################
 %files -n python-rbd
 %defattr(-,root,root,-)
 %{python_sitearch}/rbd.so
@@ -1282,7 +1349,8 @@ ln -sf %{_libdir}/librbd.so.1 /usr/lib64/qemu/librbd.so.1
 #################################################################################
 %files -n python-cephfs
 %defattr(-,root,root,-)
-%{python_sitelib}/cephfs.py*
+%{python_sitearch}/cephfs.so
+%{python_sitearch}/cephfs-*.egg-info
 %{python_sitelib}/ceph_volume_client.py*
 
 #################################################################################
@@ -1310,6 +1378,7 @@ ln -sf %{_libdir}/librbd.so.1 /usr/lib64/qemu/librbd.so.1
 %{_bindir}/ceph_smalliobenchfs
 %{_bindir}/ceph_smalliobenchrbd
 %{_bindir}/ceph_test_*
+%{_bindir}/librgw_file*
 %{_bindir}/ceph_tpbench
 %{_bindir}/ceph_xattr_bench
 %{_bindir}/ceph-coverage
diff --git a/src/test/centos-7/ceph.spec.in b/src/test/centos-7/ceph.spec.in
index 498eac4..b52d7e2 100644
--- a/src/test/centos-7/ceph.spec.in
+++ b/src/test/centos-7/ceph.spec.in
@@ -46,7 +46,8 @@ restorecon -R /etc/rc\.d/init\.d/ceph > /dev/null 2>&1; \
 restorecon -R /etc/rc\.d/init\.d/radosgw > /dev/null 2>&1; \
 restorecon -R /var/run/ceph > /dev/null 2>&1; \
 restorecon -R /var/lib/ceph > /dev/null 2>&1; \
-restorecon -R /var/log/ceph > /dev/null 2>&1;
+restorecon -R /var/log/ceph > /dev/null 2>&1; \
+restorecon -R /var/log/radosgw > /dev/null 2>&1;
 %endif
 
 %{!?_udevrulesdir: %global _udevrulesdir /lib/udev/rules.d}
@@ -108,11 +109,6 @@ BuildRequires:	boost-devel
 BuildRequires:  cmake
 BuildRequires:	cryptsetup
 BuildRequires:	fuse-devel
-%if 0%{?suse_version}
-BuildRequires:	python-Cython
-%else
-BuildRequires:	Cython
-%endif
 BuildRequires:	gdbm
 BuildRequires:	hdparm
 BuildRequires:	leveldb-devel > 1.2
@@ -155,15 +151,20 @@ BuildRequires:	libbz2-devel
 %if 0%{with tcmalloc}
 BuildRequires:	gperftools-devel
 %endif
+BuildRequires:  btrfsprogs
 BuildRequires:	mozilla-nss-devel
 BuildRequires:	keyutils-devel
 BuildRequires:	libatomic-ops-devel
+BuildRequires:  libopenssl-devel
 BuildRequires:  lsb-release
+BuildRequires:  openldap2-devel
+BuildRequires:	python-Cython
 %endif
 %if 0%{?fedora} || 0%{?rhel} 
 %if 0%{?_with_systemd}
 Requires:	systemd
 %endif
+BuildRequires:	btrfs-progs
 BuildRequires:	nss-devel
 BuildRequires:	keyutils-libs-devel
 BuildRequires:	libatomic_ops-devel
@@ -171,7 +172,10 @@ Requires(post):	chkconfig
 Requires(preun):	chkconfig
 Requires(preun):	initscripts
 BuildRequires:	gperftools-devel
+BuildRequires:  openldap-devel
+BuildRequires:  openssl-devel
 BuildRequires:  redhat-lsb-core
+BuildRequires:	Cython
 %endif
 # boost
 %if 0%{?fedora} || 0%{?rhel} 
@@ -208,6 +212,10 @@ BuildRequires:	python-sphinx10
 %if 0%{?fedora} || 0%{?suse_version} || 0%{?rhel} >= 7
 BuildRequires:	python-sphinx
 %endif
+#hardened-cc1
+%if 0%{?fedora} || 0%{?rhel}
+BuildRequires:  redhat-rpm-config
+%endif
 
 %description
 Ceph is a massively scalable, open-source, distributed storage system that runs
@@ -224,6 +232,7 @@ Requires:      ceph-common = %{epoch}:%{version}-%{release}
 Requires:      librbd1 = %{epoch}:%{version}-%{release}
 Requires:      librados2 = %{epoch}:%{version}-%{release}
 Requires:      libcephfs1 = %{epoch}:%{version}-%{release}
+Requires:      librgw2 = %{epoch}:%{version}-%{release}
 %if 0%{with selinux}
 Requires:      ceph-selinux = %{epoch}:%{version}-%{release}
 %endif
@@ -253,6 +262,7 @@ Summary:	Ceph Common
 Group:		System Environment/Base
 Requires:	librbd1 = %{epoch}:%{version}-%{release}
 Requires:	librados2 = %{epoch}:%{version}-%{release}
+Requires:	libcephfs1 = %{epoch}:%{version}-%{release}
 Requires:	python-rados = %{epoch}:%{version}-%{release}
 Requires:	python-rbd = %{epoch}:%{version}-%{release}
 Requires:	python-cephfs = %{epoch}:%{version}-%{release}
@@ -300,14 +310,12 @@ of cluster membership, configuration, and state.
 %package fuse
 Summary:	Ceph fuse-based client
 Group:		System Environment/Base
-Requires:	%{name}
 %description fuse
 FUSE based client for Ceph distributed network file system
 
 %package -n rbd-fuse
 Summary:	Ceph fuse-based client
 Group:		System Environment/Base
-Requires:	%{name}
 Requires:	librados2 = %{epoch}:%{version}-%{release}
 Requires:	librbd1 = %{epoch}:%{version}-%{release}
 %description -n rbd-fuse
@@ -316,7 +324,6 @@ FUSE based client to map Ceph rbd images to files
 %package -n rbd-mirror
 Summary:	Ceph daemon for mirroring RBD images
 Group:		System Environment/Base
-Requires:	%{name}
 Requires:	ceph-common = %{epoch}:%{version}-%{release}
 Requires:	librados2 = %{epoch}:%{version}-%{release}
 %description -n rbd-mirror
@@ -326,7 +333,6 @@ changes asynchronously.
 %package -n rbd-nbd
 Summary:	Ceph RBD client base on NBD
 Group:		System Environment/Base
-Requires:	%{name}
 Requires:	librados2 = %{epoch}:%{version}-%{release}
 Requires:	librbd1 = %{epoch}:%{version}-%{release}
 %description -n rbd-nbd
@@ -340,6 +346,7 @@ Requires:	ceph-common = %{epoch}:%{version}-%{release}
 Requires:	ceph-selinux = %{epoch}:%{version}-%{release}
 %endif
 Requires:	librados2 = %{epoch}:%{version}-%{release}
+Requires:	librgw2 = %{epoch}:%{version}-%{release}
 %if 0%{?rhel} || 0%{?fedora}
 Requires:	mailcap
 # python-flask for powerdns
@@ -350,16 +357,17 @@ Requires:	python-flask
 Requires:      python-Flask
 %endif
 %description radosgw
-This package is an S3 HTTP REST gateway for the RADOS object store. It
-is implemented as a FastCGI module using libfcgi, and can be used in
-conjunction with any FastCGI capable web server.
+RADOS is a distributed object store used by the Ceph distributed
+storage system.  This package provides a REST gateway to the
+object store that aims to implement a superset of Amazon's S3
+service as well as the OpenStack Object Storage ("Swift") API.
 
 %if %{with ocf}
 %package resource-agents
 Summary:	OCF-compliant resource agents for Ceph daemons
 Group:		System Environment/Base
 License:	LGPL-2.0
-Requires:	%{name} = %{epoch}:%{version}
+Requires:	ceph-base = %{epoch}:%{version}
 Requires:	resource-agents
 %description resource-agents
 Resource agents for monitoring and managing Ceph daemons
@@ -406,6 +414,24 @@ Obsoletes:	ceph-devel < %{epoch}:%{version}-%{release}
 This package contains libraries and headers needed to develop programs
 that use RADOS object store.
 
+%package -n librgw2
+Summary:	RADOS gateway client library
+Group:		System Environment/Libraries
+License:	LGPL-2.0
+Requires:	librados2 = %{epoch}:%{version}-%{release}
+%description -n librgw2
+This package provides a library implementation of the RADOS gateway
+(distributed object store with S3 and Swift personalities).
+
+%package -n librgw2-devel
+Summary:	RADOS gateway client library
+Group:		Development/Libraries
+License:	LGPL-2.0
+Requires:	librados2 = %{epoch}:%{version}-%{release}
+%description -n librgw2-devel
+This package contains libraries and headers needed to develop programs
+that use RADOS gateway client library.
+
 %package -n python-rados
 Summary:	Python libraries for the RADOS object store
 Group:		System Environment/Libraries
@@ -564,7 +590,7 @@ This package contains the Java libraries for the Ceph File System.
 %package selinux
 Summary:	SELinux support for Ceph MON, OSD and MDS
 Group:		System Environment/Base
-Requires:	%{name}
+Requires:	ceph-base = %{epoch}:%{version}-%{release}
 Requires:	policycoreutils, libselinux-utils
 Requires(post): selinux-policy-base >= %{_selinux_policy_version}, policycoreutils, gawk
 Requires(postun): policycoreutils
@@ -601,7 +627,6 @@ Summary:	Compatibility package for Ceph headers
 Group:		Development/Libraries
 License:	LGPL-2.0
 Obsoletes:	ceph-devel
-Requires:	%{name} = %{epoch}:%{version}-%{release}
 Requires:	librados2-devel = %{epoch}:%{version}-%{release}
 Requires:	libradosstriper1-devel = %{epoch}:%{version}-%{release}
 Requires:	librbd1-devel = %{epoch}:%{version}-%{release}
@@ -733,11 +758,13 @@ install -m 0644 -D etc/sysconfig/ceph $RPM_BUILD_ROOT%{_localstatedir}/adm/fillu
   install -m 0644 -D systemd/ceph-create-keys at .service $RPM_BUILD_ROOT%{_unitdir}/ceph-create-keys at .service
   install -m 0644 -D systemd/ceph-mds at .service $RPM_BUILD_ROOT%{_unitdir}/ceph-mds at .service
   install -m 0644 -D systemd/ceph-radosgw at .service $RPM_BUILD_ROOT%{_unitdir}/ceph-radosgw at .service
+  install -m 0644 -D systemd/ceph-rbd-mirror at .service $RPM_BUILD_ROOT%{_unitdir}/ceph-rbd-mirror at .service
   install -m 0644 -D systemd/ceph.target $RPM_BUILD_ROOT%{_unitdir}/ceph.target
   install -m 0644 -D systemd/ceph-osd.target $RPM_BUILD_ROOT%{_unitdir}/ceph-osd.target
   install -m 0644 -D systemd/ceph-mon.target $RPM_BUILD_ROOT%{_unitdir}/ceph-mon.target
   install -m 0644 -D systemd/ceph-mds.target $RPM_BUILD_ROOT%{_unitdir}/ceph-mds.target
   install -m 0644 -D systemd/ceph-radosgw.target $RPM_BUILD_ROOT%{_unitdir}/ceph-radosgw.target
+  install -m 0644 -D systemd/ceph-rbd-mirror.target $RPM_BUILD_ROOT%{_unitdir}/ceph-rbd-mirror.target
   install -m 0644 -D systemd/ceph-disk at .service $RPM_BUILD_ROOT%{_unitdir}/ceph-disk at .service
   install -m 0755 -D systemd/ceph $RPM_BUILD_ROOT%{_sbindir}/rcceph
 %else
@@ -942,6 +969,9 @@ rm -rf $RPM_BUILD_ROOT
 %{_bindir}/ceph-rbdnamer
 %{_bindir}/ceph-syn
 %{_bindir}/ceph-crush-location
+%{_bindir}/cephfs-data-scan
+%{_bindir}/cephfs-journal-tool
+%{_bindir}/cephfs-table-tool
 %{_bindir}/rados
 %{_bindir}/rbd
 %{_bindir}/rbd-replay
@@ -1018,9 +1048,6 @@ fi
 #################################################################################
 %files mds
 %{_bindir}/ceph-mds
-%{_bindir}/cephfs-journal-tool
-%{_bindir}/cephfs-table-tool
-%{_bindir}/cephfs-data-scan
 %{_mandir}/man8/ceph-mds.8*
 %if 0%{?_with_systemd}
 %{_unitdir}/ceph-mds at .service
@@ -1067,6 +1094,10 @@ fi
 %defattr(-,root,root,-)
 %{_bindir}/rbd-mirror
 %{_mandir}/man8/rbd-mirror.8*
+%if 0%{?_with_systemd}
+%{_unitdir}/ceph-rbd-mirror at .service
+%{_unitdir}/ceph-rbd-mirror.target
+%endif
 
 #################################################################################
 %files -n rbd-nbd
@@ -1079,6 +1110,7 @@ fi
 %defattr(-,root,root,-)
 %{_bindir}/radosgw
 %{_bindir}/radosgw-admin
+%{_bindir}/radosgw-token
 %{_bindir}/radosgw-object-expirer
 %{_mandir}/man8/radosgw.8*
 %{_mandir}/man8/radosgw-admin.8*
@@ -1161,12 +1193,27 @@ fi
 
 #################################################################################
 %if %{with ocf}
+
 %files resource-agents
 %defattr(0755,root,root,-)
-%dir /usr/lib/ocf
-%dir /usr/lib/ocf/resource.d
-%dir /usr/lib/ocf/resource.d/ceph
-/usr/lib/ocf/resource.d/%{name}/*
+# N.B. src/ocf/Makefile.am uses $(prefix)/lib
+%dir %{_prefix}/lib/ocf
+%dir %{_prefix}/lib/ocf/resource.d
+%dir %{_prefix}/lib/ocf/resource.d/ceph
+%if 0%{_with_systemd}
+%exclude %{_prefix}/lib/ocf/resource.d/ceph/ceph
+%exclude %{_prefix}/lib/ocf/resource.d/ceph/mds
+%exclude %{_prefix}/lib/ocf/resource.d/ceph/mon
+%exclude %{_prefix}/lib/ocf/resource.d/ceph/osd
+%endif
+%if ! 0%{_with_systemd}
+%{_prefix}/lib/ocf/resource.d/ceph/ceph
+%{_prefix}/lib/ocf/resource.d/ceph/mds
+%{_prefix}/lib/ocf/resource.d/ceph/mon
+%{_prefix}/lib/ocf/resource.d/ceph/osd
+%endif
+%{_prefix}/lib/ocf/resource.d/ceph/rbd
+
 %endif
 
 #################################################################################
@@ -1206,7 +1253,8 @@ fi
 #################################################################################
 %files -n python-rados
 %defattr(-,root,root,-)
-%{python_sitelib}/rados.py*
+%{python_sitearch}/rados.so
+%{python_sitearch}/rados-*.egg-info
 
 #################################################################################
 %files -n libradosstriper1
@@ -1256,6 +1304,25 @@ ln -sf %{_libdir}/librbd.so.1 /usr/lib64/qemu/librbd.so.1
 %endif
 
 #################################################################################
+%files -n librgw2
+%defattr(-,root,root,-)
+%{_libdir}/librgw.so.*
+
+%post -n librgw2
+/sbin/ldconfig
+
+%postun -n librgw2
+/sbin/ldconfig
+
+#################################################################################
+%files -n librgw2-devel
+%defattr(-,root,root,-)
+%dir %{_includedir}/rados
+%{_includedir}/rados/librgw.h
+%{_includedir}/rados/rgw_file.h
+%{_libdir}/librgw.so
+
+#################################################################################
 %files -n python-rbd
 %defattr(-,root,root,-)
 %{python_sitearch}/rbd.so
@@ -1282,7 +1349,8 @@ ln -sf %{_libdir}/librbd.so.1 /usr/lib64/qemu/librbd.so.1
 #################################################################################
 %files -n python-cephfs
 %defattr(-,root,root,-)
-%{python_sitelib}/cephfs.py*
+%{python_sitearch}/cephfs.so
+%{python_sitearch}/cephfs-*.egg-info
 %{python_sitelib}/ceph_volume_client.py*
 
 #################################################################################
@@ -1310,6 +1378,7 @@ ln -sf %{_libdir}/librbd.so.1 /usr/lib64/qemu/librbd.so.1
 %{_bindir}/ceph_smalliobenchfs
 %{_bindir}/ceph_smalliobenchrbd
 %{_bindir}/ceph_test_*
+%{_bindir}/librgw_file*
 %{_bindir}/ceph_tpbench
 %{_bindir}/ceph_xattr_bench
 %{_bindir}/ceph-coverage
diff --git a/src/test/ceph_crypto.cc b/src/test/ceph_crypto.cc
index 11d4101..893f332 100644
--- a/src/test/ceph_crypto.cc
+++ b/src/test/ceph_crypto.cc
@@ -9,8 +9,6 @@ public:
   }
 };
 
-::testing::Environment* const crypto_env = ::testing::AddGlobalTestEnvironment(new CryptoEnvironment);
-
 TEST(MD5, Simple) {
   ceph::crypto::MD5 h;
   h.Update((const byte*)"foo", 3);
diff --git a/src/test/ceph_objectstore_tool.py b/src/test/ceph_objectstore_tool.py
index 651326e..20a5d30 100755
--- a/src/test/ceph_objectstore_tool.py
+++ b/src/test/ceph_objectstore_tool.py
@@ -1857,11 +1857,27 @@ def main(argv):
         print "TEST FAILED WITH {errcount} ERRORS".format(errcount=ERRORS)
         return 1
 
+
+def remove_btrfs_subvolumes(path):
+    result = subprocess.Popen("stat -f -c '%%T' %s" % path, shell=True, stdout=subprocess.PIPE)
+    filesystem = result.stdout.readlines()[0]
+    if filesystem.rstrip('\n') == "btrfs":
+        result = subprocess.Popen("btrfs subvolume list %s" % path, shell=True, stdout=subprocess.PIPE)
+        for line in result.stdout.readlines():
+            subvolume=line.split()[8]
+            # extracting the relative volume name
+            m = re.search(".*(%s.*)" % path, subvolume)
+            if m:
+                found = m.group(1)
+                call("btrfs subvolume delete %s" % found, shell=True)
+
+
 if __name__ == "__main__":
     status = 1
     try:
         status = main(sys.argv[1:])
     finally:
         kill_daemons()
+        remove_btrfs_subvolumes(CEPH_DIR)
         call("/bin/rm -fr {dir}".format(dir=CEPH_DIR), shell=True)
     sys.exit(status)
diff --git a/src/test/cli/crushtool/arg-order-checks.t b/src/test/cli/crushtool/arg-order-checks.t
index 4d2ccae..8ee1934 100644
--- a/src/test/cli/crushtool/arg-order-checks.t
+++ b/src/test/cli/crushtool/arg-order-checks.t
@@ -4,7 +4,7 @@
   tunable straw_calc_version 1
 # build then reweight-item then tree
   $ map="$TESTDIR/foo"
-  $ crushtool --outfn "$map" --build --num_osds 25 node straw 5 rack straw 1 root straw 0 --reweight-item osd.2 99 -o "$map" --tree
+  $ crushtool --outfn "$map" --build --set-chooseleaf-vary-r 0 --num_osds 25 node straw 5 rack straw 1 root straw 0 --reweight-item osd.2 99 -o "$map" --tree
   crushtool reweighting item osd.2 to 99
   ID\tWEIGHT\tTYPE NAME (esc)
   -11\t123.00000\troot root (esc)
diff --git a/src/test/cli/crushtool/build.t b/src/test/cli/crushtool/build.t
index 0bf13e0..5fa4b50 100644
--- a/src/test/cli/crushtool/build.t
+++ b/src/test/cli/crushtool/build.t
@@ -31,6 +31,7 @@
   tunable choose_local_fallback_tries 0
   tunable choose_total_tries 50
   tunable chooseleaf_descend_once 1
+  tunable chooseleaf_vary_r 1
   
   # devices
   device 0 osd.0
diff --git a/src/test/cli/osdmaptool/create-print.t b/src/test/cli/osdmaptool/create-print.t
index 14bc447..3ec53ca 100644
--- a/src/test/cli/osdmaptool/create-print.t
+++ b/src/test/cli/osdmaptool/create-print.t
@@ -11,6 +11,7 @@
   tunable choose_local_fallback_tries 0
   tunable choose_total_tries 50
   tunable chooseleaf_descend_once 1
+  tunable chooseleaf_vary_r 1
   tunable straw_calc_version 1
   
   # devices
diff --git a/src/test/cli/osdmaptool/create-racks.t b/src/test/cli/osdmaptool/create-racks.t
index 696b085..eec4fe8 100644
--- a/src/test/cli/osdmaptool/create-racks.t
+++ b/src/test/cli/osdmaptool/create-racks.t
@@ -10,6 +10,7 @@
   tunable choose_local_fallback_tries 0
   tunable choose_total_tries 50
   tunable chooseleaf_descend_once 1
+  tunable chooseleaf_vary_r 1
   tunable straw_calc_version 1
   
   # devices
diff --git a/src/test/cli/radosgw-admin/help.t b/src/test/cli/radosgw-admin/help.t
index 260de6d..587317a 100644
--- a/src/test/cli/radosgw-admin/help.t
+++ b/src/test/cli/radosgw-admin/help.t
@@ -25,16 +25,43 @@
     object rm                  remove object
     object unlink              unlink object from bucket index
     objects expire             run expired objects cleanup
+    period prepare             prepare a new period
+    period delete              delete a period
+    period get                 get period info
+    period get-current         get current period info
+    period pull                pull a period
+    period push                push a period
+    period list                list all periods
+    period update              update the staging period
+    period commit              commit the staging period
     quota set                  set quota params
     quota enable               enable quota
     quota disable              disable quota
-    region get                 show region info
-    regions list               list all regions set on this cluster
-    region set                 set region info (requires infile)
-    region default             set default region
-    region-map get             show region-map
-    region-map set             set region-map (requires infile)
+    realm create               create a new realm
+    realm delete               delete a realm
+    realm get                  show realm info
+    realm get-default          get default realm name
+    realm list                 list realms
+    realm list-periods         list all realm periods
+    realm remove               remove a zonegroup from the realm
+    realm rename               rename a realm
+    realm set                  set realm info (requires infile)
+    realm default              set realm as default
+    realm pull                 pull a realm and its current period
+    zonegroup add              add a zone to a zonegroup
+    zonegroup create           create a new zone group info
+    zonegroup default          set default zone group
+    zonegroup delete           delete a zone group info
+    zonegroup get              show zone group info
+    zonegroup modify           set/clear zonegroup master status
+    zonegroup set              set zone group info (requires infile)
+    zonegroup rename           rename a zone group
+    zonegroup list             list all zone groups set on this cluster
+    zonegroup-map get          show zonegroup-map
+    zonegroup-map set          set zonegroup-map (requires infile)
+    zone create                create a new zone
     zone get                   show zone cluster params
+    zone modify                set/clear zone master status
     zone set                   set zone cluster params (requires infile)
     zone list                  list all zones set on this cluster
     pool add                   add an existing pool for data placement
@@ -61,10 +88,12 @@
     mdlog list                 list metadata log
     mdlog trim                 trim metadata log (use start-date, end-date or
                                start-marker, end-marker)
+    mdlog status               read metadata log status
     bilog list                 list bucket index log
     bilog trim                 trim bucket index log (use start-marker, end-marker)
     datalog list               list data log
     datalog trim               trim data log
+    datalog status             read data log status
     opstate list               list stateful operations entries (use client_id,
                                op_id, object)
     opstate set                set state on an entry (use client_id, op_id, object, state)
@@ -76,6 +105,7 @@
     orphans find               init and run search for leaked rados objects
     orphans finish             clean up search for leaked rados objects
   options:
+     --tenant=<tenant>         tenant name
      --uid=<id>                user id
      --subuser=<name>          subuser name
      --access-key=<key>        S3 access key
@@ -104,8 +134,23 @@
                                  replica mdlog get/delete
                                  replica datalog get/delete
      --metadata-key=<key>      key to retrieve metadata from with metadata get
-     --rgw-region=<region>     region in which radosgw is running
+     --remote=<remote>         remote to pull period
+     --parent=<id>             parent period id
+     --period=<id>             period id
+     --epoch=<number>          period epoch
+     --commit                  commit the period during 'period update'
+     --master                  set as master
+     --master-url              master url
+     --master-zonegroup=<id>   master zonegroup id
+     --master-zone=<id>        master zone id
+     --rgw-realm=<realm>       realm name
+     --realm-id=<realm id>     realm id
+     --realm-new-name=<realm new name> realm new name
+     --rgw-zonegroup=<zonegroup>   zonegroup name
      --rgw-zone=<zone>         zone in which radosgw is running
+     --zone-new-name=<zone>    zone new name
+     --default                 set entity (realm, zonegroup, zone) as default
+     --endpoints=<list>        zone endpoints
      --fix                     besides checking bucket index, will also fix it
      --check-objects           bucket check: rebuilds bucket index according to
                                actual objects state
@@ -123,7 +168,7 @@
      --show-log-sum=<flag>     enable/disable dump of log summation on log show
      --skip-zero-entries       log show only dumps entries that don't have zero value
                                in one of the numeric field
-     --infile                  specify a file to read in when setting data
+     --infile=<file>           specify a file to read in when setting data
      --state=<state string>    specify a state for the opstate set command
      --replica-log-type        replica log type (metadata, data, bucket), required for
                                replica log operations
@@ -131,6 +176,7 @@
      --caps=<caps>             list of caps (e.g., "usage=read, write; user=read"
      --yes-i-really-mean-it    required for certain operations
      --reset-regions           reset regionmap when regionmap update
+  
   <date> := "YYYY-MM-DD[ hh:mm:ss]"
   
   Quota options:
@@ -152,4 +198,3 @@
     --version         show version and quit
   
   [1]
- 
diff --git a/src/test/cli/rbd/help.t b/src/test/cli/rbd/help.t
index 6832012..e68f186 100644
--- a/src/test/cli/rbd/help.t
+++ b/src/test/cli/rbd/help.t
@@ -42,6 +42,11 @@
       lock remove (lock rm)       Release a lock on an image.
       map                         Map image to a block device using the kernel.
       merge-diff                  Merge two diff exports together.
+      mirror image demote         Demote an image to secondary for RBD mirroring.
+      mirror image disable        Disable RBD mirroring for an image.
+      mirror image enable         Enable RBD mirroring for an image.
+      mirror image promote        Promote an image to primary for RBD mirroring.
+      mirror image resync         Force resync to primary image for RBD mirroring.
       mirror pool disable         Disable RBD mirroring by default within a pool.
       mirror pool enable          Enable RBD mirroring by default within a pool.
       mirror pool info            Show information about the pool mirroring
@@ -149,8 +154,8 @@
     --order arg               object order [12 <= order <= 25]
     --object-size arg         object size in B/K/M [4K <= object size <= 32M]
     --image-feature arg       image features
-                              [layering(+), striping(+), exclusive-lock(*),
-                              object-map(*), fast-diff(*), deep-flatten,
+                              [layering(+), striping, exclusive-lock(+*),
+                              object-map(+*), fast-diff(+*), deep-flatten(+-),
                               journaling(*)]
     --image-shared            shared image
     --stripe-unit arg         stripe unit
@@ -161,6 +166,7 @@
   
   Image Features:
     (*) supports enabling/disabling on existing images
+    (-) supports disabling-only on existing images
     (+) enabled by default for new images if features not specified
   
   rbd help copy
@@ -192,8 +198,8 @@
     --order arg                  object order [12 <= order <= 25]
     --object-size arg            object size in B/K/M [4K <= object size <= 32M]
     --image-feature arg          image features
-                                 [layering(+), striping(+), exclusive-lock(*),
-                                 object-map(*), fast-diff(*), deep-flatten,
+                                 [layering(+), striping, exclusive-lock(+*),
+                                 object-map(+*), fast-diff(+*), deep-flatten(+-),
                                  journaling(*)]
     --image-shared               shared image
     --stripe-unit arg            stripe unit
@@ -205,6 +211,7 @@
   
   Image Features:
     (*) supports enabling/disabling on existing images
+    (-) supports disabling-only on existing images
     (+) enabled by default for new images if features not specified
   
   rbd help create
@@ -228,14 +235,14 @@
   Optional arguments
     -p [ --pool ] arg         pool name
     --image arg               image name
-    --image-format arg        image format [1 or 2]
+    --image-format arg        image format [1 (deprecated) or 2]
     --new-format              use image format 2
                               (deprecated)
     --order arg               object order [12 <= order <= 25]
     --object-size arg         object size in B/K/M [4K <= object size <= 32M]
     --image-feature arg       image features
-                              [layering(+), striping(+), exclusive-lock(*),
-                              object-map(*), fast-diff(*), deep-flatten,
+                              [layering(+), striping, exclusive-lock(+*),
+                              object-map(+*), fast-diff(+*), deep-flatten(+-),
                               journaling(*)]
     --image-shared            shared image
     --stripe-unit arg         stripe unit
@@ -247,6 +254,7 @@
   
   Image Features:
     (*) supports enabling/disabling on existing images
+    (-) supports disabling-only on existing images
     (+) enabled by default for new images if features not specified
   
   rbd help diff
@@ -473,14 +481,14 @@
     --path arg                import file (or '-' for stdin)
     --dest-pool arg           destination pool name
     --dest arg                destination image name
-    --image-format arg        image format [1 or 2]
+    --image-format arg        image format [1 (deprecated) or 2]
     --new-format              use image format 2
                               (deprecated)
     --order arg               object order [12 <= order <= 25]
     --object-size arg         object size in B/K/M [4K <= object size <= 32M]
     --image-feature arg       image features
-                              [layering(+), striping(+), exclusive-lock(*),
-                              object-map(*), fast-diff(*), deep-flatten,
+                              [layering(+), striping, exclusive-lock(+*),
+                              object-map(+*), fast-diff(+*), deep-flatten(+-),
                               journaling(*)]
     --image-shared            shared image
     --stripe-unit arg         stripe unit
@@ -494,6 +502,7 @@
   
   Image Features:
     (*) supports enabling/disabling on existing images
+    (-) supports disabling-only on existing images
     (+) enabled by default for new images if features not specified
   
   rbd help import-diff
@@ -742,6 +751,78 @@
     --path arg           path to merged diff (or '-' for stdout)
     --no-progress        disable progress output
   
+  rbd help mirror image demote
+  usage: rbd mirror image demote [--pool <pool>] [--image <image>] 
+                                 <image-spec> 
+  
+  Demote an image to secondary for RBD mirroring.
+  
+  Positional arguments
+    <image-spec>         image specification
+                         (example: [<pool-name>/]<image-name>)
+  
+  Optional arguments
+    -p [ --pool ] arg    pool name
+    --image arg          image name
+  
+  rbd help mirror image disable
+  usage: rbd mirror image disable [--force] [--pool <pool>] [--image <image>] 
+                                  <image-spec> 
+  
+  Disable RBD mirroring for an image.
+  
+  Positional arguments
+    <image-spec>         image specification
+                         (example: [<pool-name>/]<image-name>)
+  
+  Optional arguments
+    --force              disable even if not primary
+    -p [ --pool ] arg    pool name
+    --image arg          image name
+  
+  rbd help mirror image enable
+  usage: rbd mirror image enable [--pool <pool>] [--image <image>] 
+                                 <image-spec> 
+  
+  Enable RBD mirroring for an image.
+  
+  Positional arguments
+    <image-spec>         image specification
+                         (example: [<pool-name>/]<image-name>)
+  
+  Optional arguments
+    -p [ --pool ] arg    pool name
+    --image arg          image name
+  
+  rbd help mirror image promote
+  usage: rbd mirror image promote [--force] [--pool <pool>] [--image <image>] 
+                                  <image-spec> 
+  
+  Promote an image to primary for RBD mirroring.
+  
+  Positional arguments
+    <image-spec>         image specification
+                         (example: [<pool-name>/]<image-name>)
+  
+  Optional arguments
+    --force              promote even if not cleanly demoted by remote cluster
+    -p [ --pool ] arg    pool name
+    --image arg          image name
+  
+  rbd help mirror image resync
+  usage: rbd mirror image resync [--pool <pool>] [--image <image>] 
+                                 <image-spec> 
+  
+  Force resync to primary image for RBD mirroring.
+  
+  Positional arguments
+    <image-spec>         image specification
+                         (example: [<pool-name>/]<image-name>)
+  
+  Optional arguments
+    -p [ --pool ] arg    pool name
+    --image arg          image name
+  
   rbd help mirror pool disable
   usage: rbd mirror pool disable [--pool <pool>] 
                                  <pool-name> 
@@ -756,12 +837,13 @@
   
   rbd help mirror pool enable
   usage: rbd mirror pool enable [--pool <pool>] 
-                                <pool-name> 
+                                <pool-name> <mode> 
   
   Enable RBD mirroring by default within a pool.
   
   Positional arguments
     <pool-name>          pool name
+    <mode>               mirror mode [image or pool]
   
   Optional arguments
     -p [ --pool ] arg    pool name
@@ -785,44 +867,42 @@
   usage: rbd mirror pool peer add [--pool <pool>] 
                                   [--remote-client-name <remote-client-name>] 
                                   [--remote-cluster <remote-cluster>] 
-                                  [--remote-cluster-uuid <remote-cluster-uuid>] 
                                   <pool-name> <remote-cluster-spec> 
   
   Add a mirroring peer to a pool.
   
   Positional arguments
-    <pool-name>               pool name
-    <remote-cluster-spec>     remote cluster spec
-                              (example: [<client name>@]<cluster name>
+    <pool-name>              pool name
+    <remote-cluster-spec>    remote cluster spec
+                             (example: [<client name>@]<cluster name>
   
   Optional arguments
-    -p [ --pool ] arg         pool name
-    --remote-client-name arg  remote client name
-    --remote-cluster arg      remote cluster name
-    --remote-cluster-uuid arg remote cluster uuid
+    -p [ --pool ] arg        pool name
+    --remote-client-name arg remote client name
+    --remote-cluster arg     remote cluster name
   
   rbd help mirror pool peer remove
   usage: rbd mirror pool peer remove [--pool <pool>] 
-                                     <pool-name> <cluster-uuid> 
+                                     <pool-name> <uuid> 
   
   Remove a mirroring peer from a pool.
   
   Positional arguments
     <pool-name>          pool name
-    <cluster-uuid>       cluster UUID
+    <uuid>               peer uuid
   
   Optional arguments
     -p [ --pool ] arg    pool name
   
   rbd help mirror pool peer set
   usage: rbd mirror pool peer set [--pool <pool>] 
-                                  <pool-name> <cluster-uuid> <key> <value> 
+                                  <pool-name> <uuid> <key> <value> 
   
   Update mirroring peer settings.
   
   Positional arguments
     <pool-name>          pool name
-    <cluster-uuid>       cluster UUID
+    <uuid>               peer uuid
     <key>                peer parameter [client or cluster]
     <value>              new client or cluster name
   
diff --git a/src/test/cli/rbd/not-enough-args.t b/src/test/cli/rbd/not-enough-args.t
index 10283a3..72adf18 100644
--- a/src/test/cli/rbd/not-enough-args.t
+++ b/src/test/cli/rbd/not-enough-args.t
@@ -190,3 +190,27 @@
   $ rbd bench-write
   rbd: image name was not specified
   [22]
+  $ rbd mirror pool enable rbd
+  rbd: must specify 'image' or 'pool' mode.
+  [22]
+  $ rbd mirror pool peer add rbd
+  rbd: remote cluster was not specified
+  [22]
+  $ rbd mirror pool peer remove rbd
+  rbd: must specify peer uuid
+  [22]
+  $ rbd mirror image demote
+  rbd: image name was not specified
+  [22]
+  $ rbd mirror image disable
+  rbd: image name was not specified
+  [22]
+  $ rbd mirror image enable
+  rbd: image name was not specified
+  [22]
+  $ rbd mirror image promote
+  rbd: image name was not specified
+  [22]
+  $ rbd mirror image resync
+  rbd: image name was not specified
+  [22]
diff --git a/src/test/cls_journal/test_cls_journal.cc b/src/test/cls_journal/test_cls_journal.cc
index 3a26e8f..9c6000d 100644
--- a/src/test/cls_journal/test_cls_journal.cc
+++ b/src/test/cls_journal/test_cls_journal.cc
@@ -235,19 +235,20 @@ TEST_F(TestClsJournal, ClientRegisterDuplicate) {
   ASSERT_EQ(-EEXIST, client::client_register(ioctx, oid, "id1", bufferlist()));
 }
 
-TEST_F(TestClsJournal, ClientUpdate) {
+TEST_F(TestClsJournal, ClientUpdateData) {
   librados::IoCtx ioctx;
   ASSERT_EQ(0, _rados.ioctx_create(_pool_name.c_str(), ioctx));
 
   std::string oid = get_temp_image_name();
 
-  ASSERT_EQ(-ENOENT, client::client_update(ioctx, oid, "id1", bufferlist()));
+  ASSERT_EQ(-ENOENT, client::client_update_data(ioctx, oid, "id1",
+                                                bufferlist()));
 
   ASSERT_EQ(0, client::client_register(ioctx, oid, "id1", bufferlist()));
 
   bufferlist data;
   data.append(std::string('1', 128));
-  ASSERT_EQ(0, client::client_update(ioctx, oid, "id1", data));
+  ASSERT_EQ(0, client::client_update_data(ioctx, oid, "id1", data));
 
   Client client;
   ASSERT_EQ(0, client::get_client(ioctx, oid, "id1", &client));
@@ -255,6 +256,30 @@ TEST_F(TestClsJournal, ClientUpdate) {
   ASSERT_EQ(expected_client, client);
 }
 
+TEST_F(TestClsJournal, ClientUpdateState) {
+  librados::IoCtx ioctx;
+  ASSERT_EQ(0, _rados.ioctx_create(_pool_name.c_str(), ioctx));
+
+  std::string oid = get_temp_image_name();
+
+  ASSERT_EQ(-ENOENT, client::client_update_state(ioctx, oid, "id1",
+                                                 CLIENT_STATE_DISCONNECTED));
+
+  ASSERT_EQ(0, client::client_register(ioctx, oid, "id1", bufferlist()));
+
+  bufferlist data;
+  data.append(std::string('1', 128));
+  ASSERT_EQ(0, client::client_update_state(ioctx, oid, "id1",
+                                           CLIENT_STATE_DISCONNECTED));
+
+  Client client;
+  ASSERT_EQ(0, client::get_client(ioctx, oid, "id1", &client));
+  Client expected_client;
+  expected_client.id = "id1";
+  expected_client.state = CLIENT_STATE_DISCONNECTED;
+  ASSERT_EQ(expected_client, client);
+}
+
 TEST_F(TestClsJournal, ClientUnregister) {
   librados::IoCtx ioctx;
   ASSERT_EQ(0, _rados.ioctx_create(_pool_name.c_str(), ioctx));
@@ -293,7 +318,7 @@ TEST_F(TestClsJournal, ClientUnregisterPruneTags) {
   ASSERT_EQ(0, client::tag_create(ioctx, oid, 2, 1, bufferlist()));
 
   librados::ObjectWriteOperation op1;
-  client::client_commit(&op1, "id1", {1, {{2, 120}}});
+  client::client_commit(&op1, "id1", {{{1, 2, 120}}});
   ASSERT_EQ(0, ioctx.operate(oid, &op1));
 
   ASSERT_EQ(0, client::client_unregister(ioctx, oid, "id2"));
@@ -314,12 +339,12 @@ TEST_F(TestClsJournal, ClientCommit) {
   ASSERT_EQ(0, client::create(ioctx, oid, 2, 2, ioctx.get_id()));
   ASSERT_EQ(0, client::client_register(ioctx, oid, "id1", bufferlist()));
 
-  cls::journal::EntryPositions entry_positions;
-  entry_positions = {
-    cls::journal::EntryPosition(234, 120),
-    cls::journal::EntryPosition(235, 121)};
+  cls::journal::ObjectPositions object_positions;
+  object_positions = {
+    cls::journal::ObjectPosition(0, 234, 120),
+    cls::journal::ObjectPosition(3, 235, 121)};
   cls::journal::ObjectSetPosition object_set_position(
-    1, entry_positions);
+    object_positions);
 
   librados::ObjectWriteOperation op2;
   client::client_commit(&op2, "id1", object_set_position);
@@ -342,13 +367,13 @@ TEST_F(TestClsJournal, ClientCommitInvalid) {
   ASSERT_EQ(0, client::create(ioctx, oid, 2, 2, ioctx.get_id()));
   ASSERT_EQ(0, client::client_register(ioctx, oid, "id1", bufferlist()));
 
-  cls::journal::EntryPositions entry_positions;
-  entry_positions = {
-    cls::journal::EntryPosition(234, 120),
-    cls::journal::EntryPosition(234, 121),
-    cls::journal::EntryPosition(235, 121)};
+  cls::journal::ObjectPositions object_positions;
+  object_positions = {
+    cls::journal::ObjectPosition(0, 234, 120),
+    cls::journal::ObjectPosition(4, 234, 121),
+    cls::journal::ObjectPosition(5, 235, 121)};
   cls::journal::ObjectSetPosition object_set_position(
-    1, entry_positions);
+    object_positions);
 
   librados::ObjectWriteOperation op2;
   client::client_commit(&op2, "id1", object_set_position);
@@ -468,7 +493,7 @@ TEST_F(TestClsJournal, TagCreatePrunesTags) {
   ASSERT_EQ(0, client::tag_create(ioctx, oid, 2, 1, bufferlist()));
 
   librados::ObjectWriteOperation op1;
-  client::client_commit(&op1, "id1", {1, {{2, 120}}});
+  client::client_commit(&op1, "id1", {{{1, 2, 120}}});
   ASSERT_EQ(0, ioctx.operate(oid, &op1));
 
   ASSERT_EQ(0, client::tag_create(ioctx, oid, 3, 0, bufferlist()));
diff --git a/src/test/cls_rbd/test_cls_rbd.cc b/src/test/cls_rbd/test_cls_rbd.cc
index 218505d..cd8283e 100644
--- a/src/test/cls_rbd/test_cls_rbd.cc
+++ b/src/test/cls_rbd/test_cls_rbd.cc
@@ -1259,7 +1259,8 @@ TEST_F(TestClsRbd, set_features)
   ASSERT_EQ(0, _rados.ioctx_create(_pool_name.c_str(), ioctx));
 
   string oid = get_temp_image_name();
-  ASSERT_EQ(0, create_image(&ioctx, oid, 0, 22, 0, oid));
+  uint64_t base_features = RBD_FEATURE_LAYERING | RBD_FEATURE_DEEP_FLATTEN;
+  ASSERT_EQ(0, create_image(&ioctx, oid, 0, 22, base_features, oid));
 
   uint64_t features = RBD_FEATURES_MUTABLE;
   uint64_t mask = RBD_FEATURES_MUTABLE;
@@ -1268,7 +1269,7 @@ TEST_F(TestClsRbd, set_features)
   uint64_t actual_features;
   ASSERT_EQ(0, get_features(&ioctx, oid, CEPH_NOSNAP, &actual_features));
 
-  uint64_t expected_features = RBD_FEATURES_MUTABLE;
+  uint64_t expected_features = RBD_FEATURES_MUTABLE | base_features;
   ASSERT_EQ(expected_features, actual_features);
 
   features = 0;
@@ -1277,42 +1278,68 @@ TEST_F(TestClsRbd, set_features)
 
   ASSERT_EQ(0, get_features(&ioctx, oid, CEPH_NOSNAP, &actual_features));
 
-  expected_features = RBD_FEATURES_MUTABLE & ~RBD_FEATURE_OBJECT_MAP;
+  expected_features = (RBD_FEATURES_MUTABLE | base_features) &
+                      ~RBD_FEATURE_OBJECT_MAP;
   ASSERT_EQ(expected_features, actual_features);
 
-  mask = RBD_FEATURE_LAYERING;
-  ASSERT_EQ(-EINVAL, set_features(&ioctx, oid, features, mask));
+  ASSERT_EQ(0, set_features(&ioctx, oid, 0, RBD_FEATURE_DEEP_FLATTEN));
+  ASSERT_EQ(-EINVAL, set_features(&ioctx, oid, RBD_FEATURE_DEEP_FLATTEN,
+                                  RBD_FEATURE_DEEP_FLATTEN));
+
+  ASSERT_EQ(-EINVAL, set_features(&ioctx, oid, 0, RBD_FEATURE_LAYERING));
 }
 
 TEST_F(TestClsRbd, mirror) {
   librados::IoCtx ioctx;
   ASSERT_EQ(0, _rados.ioctx_create(_pool_name.c_str(), ioctx));
+  ioctx.remove(RBD_MIRRORING);
 
   std::vector<cls::rbd::MirrorPeer> peers;
   ASSERT_EQ(-ENOENT, mirror_peer_list(&ioctx, &peers));
 
+  std::string uuid;
+  ASSERT_EQ(-ENOENT, mirror_uuid_get(&ioctx, &uuid));
   ASSERT_EQ(-EINVAL, mirror_peer_add(&ioctx, "uuid1", "cluster1", "client"));
 
-  bool enabled;
-  ASSERT_EQ(0, mirror_is_enabled(&ioctx, &enabled));
-  ASSERT_FALSE(enabled);
-  ASSERT_EQ(0, mirror_set_enabled(&ioctx, true));
-  ASSERT_EQ(0, mirror_is_enabled(&ioctx, &enabled));
-  ASSERT_TRUE(enabled);
+  cls::rbd::MirrorMode mirror_mode;
+  ASSERT_EQ(0, mirror_mode_get(&ioctx, &mirror_mode));
+  ASSERT_EQ(cls::rbd::MIRROR_MODE_DISABLED, mirror_mode);
+
+  ASSERT_EQ(-EINVAL, mirror_mode_set(&ioctx, cls::rbd::MIRROR_MODE_IMAGE));
+  ASSERT_EQ(-EINVAL, mirror_uuid_set(&ioctx, ""));
+  ASSERT_EQ(0, mirror_uuid_set(&ioctx, "mirror-uuid"));
+  ASSERT_EQ(0, mirror_uuid_get(&ioctx, &uuid));
+  ASSERT_EQ("mirror-uuid", uuid);
+
+  ASSERT_EQ(0, mirror_mode_set(&ioctx, cls::rbd::MIRROR_MODE_IMAGE));
+  ASSERT_EQ(0, mirror_mode_get(&ioctx, &mirror_mode));
+  ASSERT_EQ(cls::rbd::MIRROR_MODE_IMAGE, mirror_mode);
+
+  ASSERT_EQ(-EINVAL, mirror_uuid_set(&ioctx, "new-mirror-uuid"));
 
+  ASSERT_EQ(0, mirror_mode_set(&ioctx, cls::rbd::MIRROR_MODE_POOL));
+  ASSERT_EQ(0, mirror_mode_get(&ioctx, &mirror_mode));
+  ASSERT_EQ(cls::rbd::MIRROR_MODE_POOL, mirror_mode);
+
+  ASSERT_EQ(-EINVAL, mirror_peer_add(&ioctx, "mirror-uuid", "cluster1", "client"));
   ASSERT_EQ(0, mirror_peer_add(&ioctx, "uuid1", "cluster1", "client"));
   ASSERT_EQ(0, mirror_peer_add(&ioctx, "uuid2", "cluster2", "admin"));
-  ASSERT_EQ(-EEXIST, mirror_peer_add(&ioctx, "uuid2", "cluster3", "foo"));
+  ASSERT_EQ(-ESTALE, mirror_peer_add(&ioctx, "uuid2", "cluster3", "foo"));
   ASSERT_EQ(-EEXIST, mirror_peer_add(&ioctx, "uuid3", "cluster1", "foo"));
-  ASSERT_EQ(0, mirror_peer_add(&ioctx, "uuid3", "cluster3", "admin"));
+  ASSERT_EQ(0, mirror_peer_add(&ioctx, "uuid3", "cluster3", "admin", 123));
+  ASSERT_EQ(-EEXIST, mirror_peer_add(&ioctx, "uuid4", "cluster3", "admin"));
+  ASSERT_EQ(-EEXIST, mirror_peer_add(&ioctx, "uuid4", "cluster3", "admin", 123));
+  ASSERT_EQ(0, mirror_peer_add(&ioctx, "uuid4", "cluster3", "admin", 234));
 
   ASSERT_EQ(0, mirror_peer_list(&ioctx, &peers));
   std::vector<cls::rbd::MirrorPeer> expected_peers = {
-    {"uuid1", "cluster1", "client"},
-    {"uuid2", "cluster2", "admin"},
-    {"uuid3", "cluster3", "admin"}};
+    {"uuid1", "cluster1", "client", -1},
+    {"uuid2", "cluster2", "admin", -1},
+    {"uuid3", "cluster3", "admin", 123},
+    {"uuid4", "cluster3", "admin", 234}};
   ASSERT_EQ(expected_peers, peers);
 
+  ASSERT_EQ(0, mirror_peer_remove(&ioctx, "uuid5"));
   ASSERT_EQ(0, mirror_peer_remove(&ioctx, "uuid4"));
   ASSERT_EQ(0, mirror_peer_remove(&ioctx, "uuid2"));
 
@@ -1324,10 +1351,10 @@ TEST_F(TestClsRbd, mirror) {
 
   ASSERT_EQ(0, mirror_peer_list(&ioctx, &peers));
   expected_peers = {
-    {"uuid1", "cluster1", "new client"},
-    {"uuid3", "new cluster", "admin"}};
+    {"uuid1", "cluster1", "new client", -1},
+    {"uuid3", "new cluster", "admin", 123}};
   ASSERT_EQ(expected_peers, peers);
-  ASSERT_EQ(-EBUSY, mirror_set_enabled(&ioctx, false));
+  ASSERT_EQ(-EBUSY, mirror_mode_set(&ioctx, cls::rbd::MIRROR_MODE_DISABLED));
 
   ASSERT_EQ(0, mirror_peer_remove(&ioctx, "uuid3"));
   ASSERT_EQ(0, mirror_peer_remove(&ioctx, "uuid1"));
@@ -1335,7 +1362,60 @@ TEST_F(TestClsRbd, mirror) {
   expected_peers = {};
   ASSERT_EQ(expected_peers, peers);
 
-  ASSERT_EQ(0, mirror_set_enabled(&ioctx, false));
-  ASSERT_EQ(0, mirror_is_enabled(&ioctx, &enabled));
-  ASSERT_FALSE(enabled);
+  ASSERT_EQ(0, mirror_mode_set(&ioctx, cls::rbd::MIRROR_MODE_DISABLED));
+  ASSERT_EQ(0, mirror_mode_get(&ioctx, &mirror_mode));
+  ASSERT_EQ(cls::rbd::MIRROR_MODE_DISABLED, mirror_mode);
+  ASSERT_EQ(-ENOENT, mirror_uuid_get(&ioctx, &uuid));
+}
+
+TEST_F(TestClsRbd, mirror_image) {
+  librados::IoCtx ioctx;
+  ASSERT_EQ(0, _rados.ioctx_create(_pool_name.c_str(), ioctx));
+  ioctx.remove(RBD_MIRRORING);
+
+  vector<string> image_ids;
+  ASSERT_EQ(-ENOENT, mirror_image_list(&ioctx, &image_ids));
+
+  cls::rbd::MirrorImage image1("uuid1", cls::rbd::MIRROR_IMAGE_STATE_ENABLED);
+  cls::rbd::MirrorImage image2("uuid2", cls::rbd::MIRROR_IMAGE_STATE_DISABLING);
+  cls::rbd::MirrorImage image3("uuid3", cls::rbd::MIRROR_IMAGE_STATE_ENABLED);
+
+  ASSERT_EQ(0, mirror_image_set(&ioctx, "image_id1", image1));
+  ASSERT_EQ(0, mirror_image_set(&ioctx, "image_id2", image2));
+  ASSERT_EQ(-EEXIST, mirror_image_set(&ioctx, "image_id1", image2));
+  ASSERT_EQ(-EEXIST, mirror_image_set(&ioctx, "image_id2", image3));
+  ASSERT_EQ(0, mirror_image_set(&ioctx, "image_id3", image3));
+
+  cls::rbd::MirrorImage read_image;
+  ASSERT_EQ(0, mirror_image_get(&ioctx, "image_id1", &read_image));
+  ASSERT_EQ(read_image, image1);
+  ASSERT_EQ(0, mirror_image_get(&ioctx, "image_id2", &read_image));
+  ASSERT_EQ(read_image, image2);
+  ASSERT_EQ(0, mirror_image_get(&ioctx, "image_id3", &read_image));
+  ASSERT_EQ(read_image, image3);
+
+  ASSERT_EQ(0, mirror_image_list(&ioctx, &image_ids));
+  vector<string> expected_image_ids = {
+    {"image_id1"}, {"image_id2"}, {"image_id3"}};
+  ASSERT_EQ(expected_image_ids, image_ids);
+
+  ASSERT_EQ(0, mirror_image_remove(&ioctx, "image_id2"));
+  ASSERT_EQ(-EBUSY, mirror_image_remove(&ioctx, "image_id1"));
+
+  ASSERT_EQ(0, mirror_image_list(&ioctx, &image_ids));
+  expected_image_ids = {{"image_id1"}, {"image_id3"}};
+  ASSERT_EQ(expected_image_ids, image_ids);
+
+  image1.state = cls::rbd::MIRROR_IMAGE_STATE_DISABLING;
+  image3.state = cls::rbd::MIRROR_IMAGE_STATE_DISABLING;
+  ASSERT_EQ(0, mirror_image_set(&ioctx, "image_id1", image1));
+  ASSERT_EQ(0, mirror_image_get(&ioctx, "image_id1", &read_image));
+  ASSERT_EQ(read_image, image1);
+  ASSERT_EQ(0, mirror_image_set(&ioctx, "image_id3", image3));
+  ASSERT_EQ(0, mirror_image_remove(&ioctx, "image_id1"));
+  ASSERT_EQ(0, mirror_image_remove(&ioctx, "image_id3"));
+
+  ASSERT_EQ(0, mirror_image_list(&ioctx, &image_ids));
+  expected_image_ids = {};
+  ASSERT_EQ(expected_image_ids, image_ids);
 }
diff --git a/src/test/common/Throttle.cc b/src/test/common/Throttle.cc
index bd30471..a200121 100644
--- a/src/test/common/Throttle.cc
+++ b/src/test/common/Throttle.cc
@@ -28,6 +28,13 @@
 #include "global/global_init.h"
 #include <gtest/gtest.h>
 
+#include <thread>
+#include <atomic>
+#include <chrono>
+#include <mutex>
+#include <list>
+#include <random>
+
 class ThrottleTest : public ::testing::Test {
 protected:
 
@@ -252,6 +259,159 @@ TEST_F(ThrottleTest, destructor) {
   }
 }
 
+std::pair<double, std::chrono::duration<double> > test_backoff(
+  double low_threshhold,
+  double high_threshhold,
+  double expected_throughput,
+  double high_multiple,
+  double max_multiple,
+  uint64_t max,
+  double put_delay_per_count,
+  unsigned getters,
+  unsigned putters)
+{
+  std::mutex l;
+  std::condition_variable c;
+  uint64_t total = 0;
+  std::list<uint64_t> in_queue;
+  bool stop = false;
+
+  auto wait_time = std::chrono::duration<double>(0);
+  uint64_t waits = 0;
+
+  uint64_t total_observed_total = 0;
+  uint64_t total_observations = 0;
+
+  BackoffThrottle throttle(5);
+  bool valid = throttle.set_params(
+    low_threshhold,
+    high_threshhold,
+    expected_throughput,
+    high_multiple,
+    max_multiple,
+    max,
+    0);
+  assert(valid);
+
+  auto getter = [&]() {
+    std::random_device rd;
+    std::mt19937 gen(rd());
+    std::uniform_int_distribution<> dis(0, 10);
+
+    std::unique_lock<std::mutex> g(l);
+    while (!stop) {
+      g.unlock();
+
+      uint64_t to_get = dis(gen);
+      auto waited = throttle.get(to_get);
+
+      g.lock();
+      wait_time += waited;
+      waits += to_get;
+      total += to_get;
+      in_queue.push_back(to_get);
+      c.notify_one();
+    }
+  };
+
+  auto putter = [&]() {
+    std::unique_lock<std::mutex> g(l);
+    while (!stop) {
+      while (in_queue.empty())
+	c.wait(g);
+
+      uint64_t c = in_queue.front();
+
+      total_observed_total += total;
+      total_observations++;
+      in_queue.pop_front();
+      assert(total <= max);
+
+      g.unlock();
+      std::this_thread::sleep_for(
+	c * std::chrono::duration<double>(put_delay_per_count*putters));
+      g.lock();
+
+      total -= c;
+      throttle.put(c);
+    }
+  };
+
+  vector<std::thread> gts(getters);
+  for (auto &&i: gts) i = std::thread(getter);
+
+  vector<std::thread> pts(putters);
+  for (auto &&i: pts) i = std::thread(putter);
+
+  std::this_thread::sleep_for(std::chrono::duration<double>(5));
+  {
+    std::unique_lock<std::mutex> g(l);
+    stop = true;
+  }
+  for (auto &&i: gts) i.join();
+  gts.clear();
+  for (auto &&i: pts) i.join();
+  pts.clear();
+
+  return make_pair(
+    ((double)total_observed_total)/((double)total_observations),
+    wait_time / waits);
+}
+
+TEST(BackoffThrottle, undersaturated)
+{
+  auto results = test_backoff(
+    0.4,
+    0.6,
+    1000,
+    2,
+    10,
+    100,
+    0.0001,
+    3,
+    6);
+  ASSERT_LT(results.first, 45);
+  ASSERT_GT(results.first, 35);
+  ASSERT_LT(results.second.count(), 0.0002);
+  ASSERT_GT(results.second.count(), 0.00005);
+}
+
+TEST(BackoffThrottle, balanced)
+{
+  auto results = test_backoff(
+    0.4,
+    0.6,
+    1000,
+    2,
+    10,
+    100,
+    0.001,
+    7,
+    2);
+  ASSERT_LT(results.first, 60);
+  ASSERT_GT(results.first, 40);
+  ASSERT_LT(results.second.count(), 0.002);
+  ASSERT_GT(results.second.count(), 0.0005);
+}
+
+TEST(BackoffThrottle, oversaturated)
+{
+  auto results = test_backoff(
+    0.4,
+    0.6,
+    10000000,
+    2,
+    10,
+    100,
+    0.001,
+    1,
+    3);
+  ASSERT_LT(results.first, 101);
+  ASSERT_GT(results.first, 85);
+  ASSERT_LT(results.second.count(), 0.002);
+  ASSERT_GT(results.second.count(), 0.0005);
+}
+
 int main(int argc, char **argv) {
   vector<const char*> args;
   argv_to_vec(argc, (const char **)argv, args);
diff --git a/src/test/common/test_bit_vector.cc b/src/test/common/test_bit_vector.cc
index c58583c..f5b0b26 100644
--- a/src/test/common/test_bit_vector.cc
+++ b/src/test/common/test_bit_vector.cc
@@ -88,21 +88,22 @@ TYPED_TEST(BitVectorTest, get_set) {
 TYPED_TEST(BitVectorTest, get_buffer_extents) {
   typename TestFixture::bit_vector_t bit_vector;
 
-  uint64_t element_count = 2 * CEPH_PAGE_SIZE + 51;
+  uint64_t element_count = 2 * bit_vector.BLOCK_SIZE + 51;
   uint64_t elements_per_byte = 8 / bit_vector.BIT_COUNT;
   bit_vector.resize(element_count * elements_per_byte);
 
-  uint64_t offset = (CEPH_PAGE_SIZE + 11) * elements_per_byte;
-  uint64_t length = (CEPH_PAGE_SIZE + 31) * elements_per_byte;
+  uint64_t offset = (bit_vector.BLOCK_SIZE + 11) * elements_per_byte;
+  uint64_t length = (bit_vector.BLOCK_SIZE + 31) * elements_per_byte;
   uint64_t byte_offset;
   uint64_t byte_length;
   bit_vector.get_data_extents(offset, length, &byte_offset, &byte_length);
-  ASSERT_EQ(CEPH_PAGE_SIZE, byte_offset);
-  ASSERT_EQ(CEPH_PAGE_SIZE + (element_count % CEPH_PAGE_SIZE), byte_length);
+  ASSERT_EQ(bit_vector.BLOCK_SIZE, byte_offset);
+  ASSERT_EQ(bit_vector.BLOCK_SIZE + (element_count % bit_vector.BLOCK_SIZE),
+            byte_length);
 
   bit_vector.get_data_extents(1, 1, &byte_offset, &byte_length);
   ASSERT_EQ(0U, byte_offset);
-  ASSERT_EQ(CEPH_PAGE_SIZE, byte_length);
+  ASSERT_EQ(bit_vector.BLOCK_SIZE, byte_length);
 }
 
 TYPED_TEST(BitVectorTest, get_header_length) {
@@ -155,11 +156,11 @@ TYPED_TEST(BitVectorTest, partial_decode_encode) {
 
   Extents extents = boost::assign::list_of(
     std::make_pair(0, 1))(
-    std::make_pair((CEPH_PAGE_SIZE * elements_per_byte) - 2, 4))(
-    std::make_pair((CEPH_PAGE_SIZE * elements_per_byte) + 2, 2))(
-    std::make_pair((2 * CEPH_PAGE_SIZE * elements_per_byte) - 2, 4))(
-    std::make_pair((2 * CEPH_PAGE_SIZE * elements_per_byte) + 2, 2))(
-    std::make_pair(2, 2 * CEPH_PAGE_SIZE));
+    std::make_pair((bit_vector.BLOCK_SIZE * elements_per_byte) - 2, 4))(
+    std::make_pair((bit_vector.BLOCK_SIZE * elements_per_byte) + 2, 2))(
+    std::make_pair((2 * bit_vector.BLOCK_SIZE * elements_per_byte) - 2, 4))(
+    std::make_pair((2 * bit_vector.BLOCK_SIZE * elements_per_byte) + 2, 2))(
+    std::make_pair(2, 2 * bit_vector.BLOCK_SIZE));
   for (Extents::iterator it = extents.begin(); it != extents.end(); ++it) {
     uint64_t element_offset = it->first;
     uint64_t element_length = it->second;
@@ -224,8 +225,8 @@ TYPED_TEST(BitVectorTest, data_crc) {
   typename TestFixture::bit_vector_t bit_vector2;
 
   uint64_t elements_per_byte = 8 / bit_vector1.BIT_COUNT;
-  bit_vector1.resize((CEPH_PAGE_SIZE + 1) * elements_per_byte);
-  bit_vector2.resize((CEPH_PAGE_SIZE + 1) * elements_per_byte);
+  bit_vector1.resize((bit_vector1.BLOCK_SIZE + 1) * elements_per_byte);
+  bit_vector2.resize((bit_vector2.BLOCK_SIZE + 1) * elements_per_byte);
 
   uint64_t byte_offset;
   uint64_t byte_length;
@@ -236,7 +237,7 @@ TYPED_TEST(BitVectorTest, data_crc) {
   bit_vector1.encode_data(data, byte_offset, byte_length);
 
   bufferlist::iterator data_it = data.begin();
-  bit_vector1.decode_data(data_it, byte_offset); 
+  bit_vector1.decode_data(data_it, byte_offset);
 
   bit_vector2[bit_vector2.size() - 1] = 1;
 
diff --git a/src/test/common/test_context.cc b/src/test/common/test_context.cc
index 921fc90..d976758 100644
--- a/src/test/common/test_context.cc
+++ b/src/test/common/test_context.cc
@@ -30,6 +30,8 @@ TEST(CephContext, do_command)
 {
   CephContext *cct = (new CephContext(CEPH_ENTITY_TYPE_CLIENT))->get();
 
+  cct->_conf->cluster = "ceph";
+
   string key("key");
   string value("value");
   cct->_conf->set_val(key.c_str(), value.c_str(), false);
@@ -57,6 +59,8 @@ TEST(CephContext, experimental_features)
 {
   CephContext *cct = (new CephContext(CEPH_ENTITY_TYPE_CLIENT))->get();
 
+  cct->_conf->cluster = "ceph";
+
   ASSERT_FALSE(cct->check_experimental_feature_enabled("foo"));
   ASSERT_FALSE(cct->check_experimental_feature_enabled("bar"));
   ASSERT_FALSE(cct->check_experimental_feature_enabled("baz"));
diff --git a/src/test/common/test_time.cc b/src/test/common/test_time.cc
index 2e6ad4b..a54fe90 100644
--- a/src/test/common/test_time.cc
+++ b/src/test/common/test_time.cc
@@ -122,7 +122,9 @@ static void system_clock_conversions() {
 
   ASSERT_EQ(Clock::to_double(brt), bd);
   // Fudge factor
-  ASSERT_LT(abs((Clock::from_double(bd) - brt).count()), 30);
+  ASSERT_LT((Clock::from_double(bd) >  brt ?
+	     Clock::from_double(bd) - brt :
+	     brt - Clock::from_double(bd)).count(), 30U);
 }
 
 TEST(RealClock, Sanity) {
diff --git a/src/test/common/test_weighted_priority_queue.cc b/src/test/common/test_weighted_priority_queue.cc
index d3ebc41..b851979 100644
--- a/src/test/common/test_weighted_priority_queue.cc
+++ b/src/test/common/test_weighted_priority_queue.cc
@@ -114,13 +114,6 @@ protected:
         // in the strict queue.
         LQ::reverse_iterator ri = strictq.rbegin();
         EXPECT_EQ(std::get<0>(r), ri->first);
-        // Check that if there are multiple classes in a priority
-        // that it is not dequeueing the same class each time.
-        LastKlass::iterator si = last_strict.find(std::get<0>(r));
-        if (strictq[std::get<0>(r)].size() > 1 && si != last_strict.end()) {
-	  EXPECT_NE(std::get<1>(r), si->second);
-	}
-        last_strict[std::get<0>(r)] = std::get<1>(r);
 
 	Item t = strictq[std::get<0>(r)][std::get<1>(r)].front().second;
         EXPECT_EQ(std::get<2>(r), std::get<2>(t));
@@ -132,14 +125,6 @@ protected:
 	  strictq.erase(std::get<0>(r));
 	}
       } else {
-        // Check that if there are multiple classes in a priority
-        // that it is not dequeueing the same class each time.
-        LastKlass::iterator si = last_norm.find(std::get<0>(r));
-        if (normq[std::get<0>(r)].size() > 1 && si != last_norm.end()) {
-	  EXPECT_NE(std::get<1>(r), si->second);
-	}
-        last_norm[std::get<0>(r)] = std::get<1>(r);
-
 	Item t = normq[std::get<0>(r)][std::get<1>(r)].front().second;
         EXPECT_EQ(std::get<2>(r), std::get<2>(t));
         normq[std::get<0>(r)][std::get<1>(r)].pop_front();
diff --git a/src/test/compressor/test_compression_plugin.cc b/src/test/compressor/test_compression_plugin.cc
index 6d81532..e898b80 100644
--- a/src/test/compressor/test_compression_plugin.cc
+++ b/src/test/compressor/test_compression_plugin.cc
@@ -52,8 +52,10 @@ int main(int argc, char **argv) {
   global_init(NULL, args, CEPH_ENTITY_TYPE_CLIENT, CODE_ENVIRONMENT_UTILITY, 0);
   common_init_finish(g_ceph_context);
 
-  system("mkdir -p .libs/compressor");
-  system("cp .libs/libceph_example.so* .libs/compressor/");
+  int r = system("mkdir -p .libs/compressor");
+  (void)r;
+  r = system("cp .libs/libceph_example.so* .libs/compressor/");
+  (void)r;
   g_conf->set_val("plugin_dir", ".libs", false, false);
 
   ::testing::InitGoogleTest(&argc, argv);
diff --git a/src/test/compressor/test_compression_plugin_snappy.cc b/src/test/compressor/test_compression_plugin_snappy.cc
index 495e641..2855f7a 100644
--- a/src/test/compressor/test_compression_plugin_snappy.cc
+++ b/src/test/compressor/test_compression_plugin_snappy.cc
@@ -38,8 +38,10 @@ int main(int argc, char **argv) {
   global_init(NULL, args, CEPH_ENTITY_TYPE_CLIENT, CODE_ENVIRONMENT_UTILITY, 0);
   common_init_finish(g_ceph_context);
 
-  system("mkdir -p .libs/compressor");
-  system("cp .libs/libceph_snappy.so* .libs/compressor/");
+  int r = system("mkdir -p .libs/compressor");
+  (void)r;
+  r = system("cp .libs/libceph_snappy.so* .libs/compressor/");
+  (void)r;
 
   g_conf->set_val("plugin_dir", ".libs", false, false);
 
diff --git a/src/test/compressor/test_compression_plugin_zlib.cc b/src/test/compressor/test_compression_plugin_zlib.cc
index 6cf1085..0e956a1 100644
--- a/src/test/compressor/test_compression_plugin_zlib.cc
+++ b/src/test/compressor/test_compression_plugin_zlib.cc
@@ -37,8 +37,10 @@ int main(int argc, char **argv) {
   global_init(NULL, args, CEPH_ENTITY_TYPE_CLIENT, CODE_ENVIRONMENT_UTILITY, 0);
   common_init_finish(g_ceph_context);
 
-  system("mkdir -p .libs/compressor");
-  system("cp .libs/libceph_zlib.so* .libs/compressor/");
+  int r = system("mkdir -p .libs/compressor");
+  (void)r;
+  r = system("cp .libs/libceph_zlib.so* .libs/compressor/");
+  (void)r;
 
   g_conf->set_val("plugin_dir", ".libs", false, false);
 
diff --git a/src/test/compressor/test_compression_zlib.cc b/src/test/compressor/test_compression_zlib.cc
index aba2f44..70df87f 100644
--- a/src/test/compressor/test_compression_zlib.cc
+++ b/src/test/compressor/test_compression_zlib.cc
@@ -27,7 +27,7 @@ TEST(CompressionZlib, compress_decompress)
 {
   CompressionZlib sp;
   EXPECT_EQ(sp.get_method_name(), "zlib");
-  char* test = "This is test text";
+  const char* test = "This is test text";
   int len = strlen(test);
   bufferlist in, out;
   in.append(test, len);
@@ -36,14 +36,16 @@ TEST(CompressionZlib, compress_decompress)
   bufferlist after;
   res = sp.decompress(out, after);
   EXPECT_EQ(res, 0);
-  EXPECT_STREQ(test, after.c_str());
+  bufferlist exp;
+  exp.append(test);
+  EXPECT_TRUE(exp.contents_equal(after));
 }
 
 TEST(CompressionZlib, compress_decompress_chunk)
 {
   CompressionZlib sp;
   EXPECT_EQ(sp.get_method_name(), "zlib");
-  char* test = "This is test text";
+  const char* test = "This is test text";
   buffer::ptr test2 ("1234567890", 10);
   int len = strlen(test);
   bufferlist in, out;
@@ -54,7 +56,9 @@ TEST(CompressionZlib, compress_decompress_chunk)
   bufferlist after;
   res = sp.decompress(out, after);
   EXPECT_EQ(res, 0);
-  EXPECT_STREQ("This is test text1234567890", after.c_str());
+  bufferlist exp;
+  exp.append("This is test text1234567890");
+  EXPECT_TRUE(exp.contents_equal(after));
 }
 
 int main(int argc, char **argv) {
diff --git a/src/test/confutils.cc b/src/test/confutils.cc
index 90e8372..f323c68 100644
--- a/src/test/confutils.cc
+++ b/src/test/confutils.cc
@@ -471,35 +471,33 @@ TEST(ConfUtils, EscapingFiles) {
 
 TEST(ConfUtils, Overrides) {
   md_config_t conf;
-  std::deque<std::string> err;
   std::ostringstream warn;
   std::string override_conf_1_f(next_tempfile(override_config_1));
 
   conf.name.set(CEPH_ENTITY_TYPE_MON, "0");
-  conf.parse_config_files(override_conf_1_f.c_str(), &err, &warn, 0);
-  ASSERT_EQ(err.size(), 0U);
+  conf.parse_config_files(override_conf_1_f.c_str(), &warn, 0);
+  ASSERT_EQ(conf.parse_errors.size(), 0U);
   ASSERT_EQ(conf.log_file, "global_log");
 
   conf.name.set(CEPH_ENTITY_TYPE_MDS, "a");
-  conf.parse_config_files(override_conf_1_f.c_str(), &err, &warn, 0);
-  ASSERT_EQ(err.size(), 0U);
+  conf.parse_config_files(override_conf_1_f.c_str(), &warn, 0);
+  ASSERT_EQ(conf.parse_errors.size(), 0U);
   ASSERT_EQ(conf.log_file, "mds_log");
 
   conf.name.set(CEPH_ENTITY_TYPE_OSD, "0");
-  conf.parse_config_files(override_conf_1_f.c_str(), &err, &warn, 0);
-  ASSERT_EQ(err.size(), 0U);
+  conf.parse_config_files(override_conf_1_f.c_str(), &warn, 0);
+  ASSERT_EQ(conf.parse_errors.size(), 0U);
   ASSERT_EQ(conf.log_file, "osd0_log");
 }
 
 TEST(ConfUtils, DupKey) {
   md_config_t conf;
-  std::deque<std::string> err;
   std::ostringstream warn;
   std::string dup_key_config_f(next_tempfile(dup_key_config_1));
 
   conf.name.set(CEPH_ENTITY_TYPE_MDS, "a");
-  conf.parse_config_files(dup_key_config_f.c_str(), &err, &warn, 0);
-  ASSERT_EQ(err.size(), 0U);
+  conf.parse_config_files(dup_key_config_f.c_str(), &warn, 0);
+  ASSERT_EQ(conf.parse_errors.size(), 0U);
   ASSERT_EQ(conf.log_file, string("3"));
 }
 
diff --git a/src/test/crypto.cc b/src/test/crypto.cc
index 17e90d0..25c01ba 100644
--- a/src/test/crypto.cc
+++ b/src/test/crypto.cc
@@ -17,8 +17,6 @@ public:
   }
 };
 
-::testing::Environment* const crypto_env = ::testing::AddGlobalTestEnvironment(new CryptoEnvironment);
-
 TEST(AES, ValidateSecret) {
   CryptoHandler *h = g_ceph_context->get_crypto_handler(CEPH_CRYPTO_AES);
   int l;
diff --git a/src/test/debian-jessie/Dockerfile.in b/src/test/debian-jessie/Dockerfile.in
index 59f9072..9735716 100644
--- a/src/test/debian-jessie/Dockerfile.in
+++ b/src/test/debian-jessie/Dockerfile.in
@@ -27,5 +27,5 @@ RUN apt-get update
 # build dependencies
 RUN cd /root ; ./install-deps.sh
 # development tools
-RUN apt-get install -y ccache valgrind gdb python-virtualenv gdisk kpartx hdparm jq xmlstarlet
+RUN apt-get install -y sudo ccache valgrind gdb python-virtualenv gdisk kpartx hdparm jq xmlstarlet
 RUN if test %%USER%% != root ; then useradd -M --uid %%user_id%% %%USER%% && echo '%%USER%% ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers ; fi
diff --git a/src/test/encoding/ceph_dencoder.cc b/src/test/encoding/ceph_dencoder.cc
index 119145a..dfe29f3 100644
--- a/src/test/encoding/ceph_dencoder.cc
+++ b/src/test/encoding/ceph_dencoder.cc
@@ -30,16 +30,18 @@
 #define TYPE_FEATUREFUL(t)
 #define TYPE_FEATUREFUL_STRAYDATA(t)
 #define TYPE_FEATUREFUL_NONDETERMINISTIC(t)
+#define TYPE_FEATUREFUL_NOCOPY(t)
 #define TYPE_NOCOPY(t)
 #define MESSAGE(t)
 #include "types.h"
 #undef TYPE
 #undef TYPE_STRAYDATA
 #undef TYPE_NONDETERMINISTIC
+#undef TYPE_NOCOPY
 #undef TYPE_FEATUREFUL
 #undef TYPE_FEATUREFUL_STRAYDATA
 #undef TYPE_FEATUREFUL_NONDETERMINISTIC
-#undef TYPE_NOCOPY
+#undef TYPE_FEATUREFUL_NOCOPY
 #undef MESSAGE
 
 #define MB(m) ((m) * 1024 * 1024)
@@ -180,9 +182,9 @@ public:
 };
 
 template<class T>
-class DencoderImplFeatureful : public DencoderBase<T> {
+class DencoderImplFeaturefulNoCopy : public DencoderBase<T> {
 public:
-  DencoderImplFeatureful(bool stray_ok, bool nondeterministic)
+  DencoderImplFeaturefulNoCopy(bool stray_ok, bool nondeterministic)
     : DencoderBase<T>(stray_ok, nondeterministic) {}
   virtual void encode(bufferlist& out, uint64_t features) {
     out.clear();
@@ -190,6 +192,23 @@ public:
   }
 };
 
+template<class T>
+class DencoderImplFeatureful : public DencoderImplFeaturefulNoCopy<T> {
+public:
+  DencoderImplFeatureful(bool stray_ok, bool nondeterministic)
+    : DencoderImplFeaturefulNoCopy<T>(stray_ok, nondeterministic) {}
+  void copy() {
+    T *n = new T;
+    *n = *this->m_object;
+    delete this->m_object;
+    this->m_object = n;
+  }
+  void copy_ctor() {
+    T *n = new T(*this->m_object);
+    delete this->m_object;
+    this->m_object = n;
+  }
+};
 
 template<class T>
 class MessageDencoderImpl : public Dencoder {
@@ -280,15 +299,18 @@ int main(int argc, const char **argv)
 #define TYPE_FEATUREFUL(t) dencoders[T_STRINGIFY(t)] = new DencoderImplFeatureful<t>(false, false);
 #define TYPE_FEATUREFUL_STRAYDATA(t) dencoders[T_STRINGIFY(t)] = new DencoderImplFeatureful<t>(true, false);
 #define TYPE_FEATUREFUL_NONDETERMINISTIC(t) dencoders[T_STRINGIFY(t)] = new DencoderImplFeatureful<t>(false, true);
+#define TYPE_FEATUREFUL_NOCOPY(t) dencoders[T_STRINGIFY(t)] = new DencoderImplFeaturefulNoCopy<t>(false, false);
 #define TYPE_NOCOPY(t) dencoders[T_STRINGIFY(t)] = new DencoderImplNoFeatureNoCopy<t>(false, false);
 #define MESSAGE(t) dencoders[T_STRINGIFY(t)] = new MessageDencoderImpl<t>;
 #include "types.h"
 #undef TYPE
 #undef TYPE_STRAYDATA
 #undef TYPE_NONDETERMINISTIC
+#undef TYPE_NOCOPY
 #undef TYPE_FEATUREFUL
 #undef TYPE_FEATUREFUL_STRAYDATA
 #undef TYPE_FEATUREFUL_NONDETERMINISTIC
+#undef TYPE_FEATUREFUL_NOCOPY
 #undef T_STR
 #undef T_STRINGIFY
 
diff --git a/src/test/encoding/types.h b/src/test/encoding/types.h
index 41796f4..382c0a3 100644
--- a/src/test/encoding/types.h
+++ b/src/test/encoding/types.h
@@ -166,8 +166,8 @@ TYPE(sr_t)
 TYPE(frag_info_t)
 TYPE(nest_info_t)
 TYPE(client_writeable_range_t)
-TYPE(inode_t)
-TYPE(old_inode_t)
+TYPE_FEATUREFUL(inode_t)
+TYPE_FEATUREFUL(old_inode_t)
 TYPE(fnode_t)
 TYPE(old_rstat_t)
 TYPE(session_info_t)
@@ -181,10 +181,12 @@ TYPE(cap_reconnect_t)
 TYPE(inode_backtrace_t)
 TYPE(inode_backpointer_t)
 TYPE(quota_info_t)
-TYPE(ceph_file_layout_wrapper)
+
+#include "include/fs_types.h"
+TYPE_FEATUREFUL(file_layout_t)
 
 #include "mds/CInode.h"
-TYPE(InodeStore)
+TYPE_FEATUREFUL(InodeStore)
 
 #include "mds/MDSMap.h"
 TYPE_FEATUREFUL(MDSMap)
@@ -200,43 +202,43 @@ TYPE(InoTable)
 TYPE_STRAYDATA(SnapServer)
 
 #include "mds/events/ECommitted.h"
-TYPE(ECommitted)
+TYPE_FEATUREFUL(ECommitted)
 #include "mds/events/EExport.h"
-TYPE(EExport)
+TYPE_FEATUREFUL(EExport)
 #include "mds/events/EFragment.h"
-TYPE(EFragment)
+TYPE_FEATUREFUL(EFragment)
 #include "mds/events/EImportFinish.h"
-TYPE(EImportFinish)
+TYPE_FEATUREFUL(EImportFinish)
 #include "mds/events/EImportStart.h"
-TYPE(EImportStart)
+TYPE_FEATUREFUL(EImportStart)
 #include "mds/events/EMetaBlob.h"
-TYPE_NOCOPY(EMetaBlob::fullbit)
+TYPE_FEATUREFUL_NOCOPY(EMetaBlob::fullbit)
 TYPE(EMetaBlob::remotebit)
 TYPE(EMetaBlob::nullbit)
-TYPE(EMetaBlob::dirlump)
-TYPE(EMetaBlob)
+TYPE_FEATUREFUL(EMetaBlob::dirlump)
+TYPE_FEATUREFUL(EMetaBlob)
 #include "mds/events/EOpen.h"
-TYPE(EOpen)
+TYPE_FEATUREFUL(EOpen)
 #include "mds/events/EResetJournal.h"
-TYPE(EResetJournal)
+TYPE_FEATUREFUL(EResetJournal)
 #include "mds/events/ESession.h"
-TYPE(ESession)
+TYPE_FEATUREFUL(ESession)
 #include "mds/events/ESessions.h"
-TYPE(ESessions)
+TYPE_FEATUREFUL(ESessions)
 #include "mds/events/ESlaveUpdate.h"
 TYPE(link_rollback)
 TYPE(rmdir_rollback)
 TYPE(rename_rollback::drec)
 TYPE(rename_rollback)
-TYPE(ESlaveUpdate)
+TYPE_FEATUREFUL(ESlaveUpdate)
 #include "mds/events/ESubtreeMap.h"
-TYPE(ESubtreeMap)
+TYPE_FEATUREFUL(ESubtreeMap)
 #include "mds/events/ETableClient.h"
-TYPE(ETableClient)
+TYPE_FEATUREFUL(ETableClient)
 #include "mds/events/ETableServer.h"
-TYPE(ETableServer)
+TYPE_FEATUREFUL(ETableServer)
 #include "mds/events/EUpdate.h"
-TYPE(EUpdate)
+TYPE_FEATUREFUL(EUpdate)
 
 #ifdef WITH_RBD
 #include "librbd/journal/Types.h"
@@ -258,7 +260,7 @@ TYPE(rbd_replay::action::ActionEntry);
 TYPE(RGWObjManifestPart)
 TYPE(RGWObjManifest)
 TYPE(RGWOLHInfo)
-TYPE(RGWRegion)
+TYPE(RGWZoneGroup)
 TYPE(RGWZone)
 TYPE(RGWZoneParams)     
    
@@ -330,7 +332,7 @@ TYPE(cls_user_get_header_ret)
 TYPE(cls_user_complete_stats_sync_op)
 
 #include "cls/journal/cls_journal_types.h"
-TYPE(cls::journal::EntryPosition)
+TYPE(cls::journal::ObjectPosition)
 TYPE(cls::journal::ObjectSetPosition)
 TYPE(cls::journal::Client)
 
@@ -354,6 +356,7 @@ TYPE(cls_rbd_snap)
 
 #include "cls/rbd/cls_rbd_types.h"
 TYPE(cls::rbd::MirrorPeer)
+TYPE(cls::rbd::MirrorImage)
 #endif
 
 #endif
diff --git a/src/test/erasure-code/ErasureCodeExample.h b/src/test/erasure-code/ErasureCodeExample.h
index dce35d1..2ab8de6 100644
--- a/src/test/erasure-code/ErasureCodeExample.h
+++ b/src/test/erasure-code/ErasureCodeExample.h
@@ -128,7 +128,7 @@ public:
     // populate the bufferlist with bufferptr pointing
     // to chunk boundaries
     //
-    const bufferptr ptr = out.buffers().front();
+    const bufferptr &ptr = out.front();
     for (set<int>::iterator j = want_to_encode.begin();
          j != want_to_encode.end();
          ++j) {
@@ -172,9 +172,9 @@ public:
 	// two recovers it.
 	//
         map<int, bufferlist>::const_iterator k = chunks.begin();
-        const char *a = k->second.buffers().front().c_str();
+        const char *a = k->second.front().c_str();
         ++k;
-        const char *b = k->second.buffers().front().c_str();
+        const char *b = k->second.front().c_str();
         bufferptr chunk(chunk_length);
 	char *c = chunk.c_str();
         for (unsigned j = 0; j < chunk_length; j++) {
diff --git a/src/test/erasure-code/TestErasureCode.cc b/src/test/erasure-code/TestErasureCode.cc
index 4140403..27023e1 100644
--- a/src/test/erasure-code/TestErasureCode.cc
+++ b/src/test/erasure-code/TestErasureCode.cc
@@ -141,10 +141,10 @@ TEST(ErasureCodeTest, encode_misaligned_non_contiguous)
   map<int, bufferlist> encoded;
 
   ASSERT_FALSE(in.is_contiguous());
-  ASSERT_TRUE(in.buffers().front().is_aligned(ErasureCode::SIMD_ALIGN));
-  ASSERT_FALSE(in.buffers().front().is_n_align_sized(chunk_size));
-  ASSERT_TRUE(in.buffers().back().is_aligned(ErasureCode::SIMD_ALIGN));
-  ASSERT_FALSE(in.buffers().back().is_n_align_sized(chunk_size));
+  ASSERT_TRUE(in.front().is_aligned(ErasureCode::SIMD_ALIGN));
+  ASSERT_FALSE(in.front().is_n_align_sized(chunk_size));
+  ASSERT_TRUE(in.back().is_aligned(ErasureCode::SIMD_ALIGN));
+  ASSERT_FALSE(in.back().is_n_align_sized(chunk_size));
   ASSERT_EQ(0, erasure_code.encode(want_to_encode, in, &encoded));
   for (unsigned int i = 0; i < erasure_code.get_chunk_count(); i++) {
     ASSERT_TRUE(encoded[i].is_aligned(ErasureCode::SIMD_ALIGN));
diff --git a/src/test/fedora-21/ceph.spec.in b/src/test/fedora-21/ceph.spec.in
index 498eac4..b52d7e2 100644
--- a/src/test/fedora-21/ceph.spec.in
+++ b/src/test/fedora-21/ceph.spec.in
@@ -46,7 +46,8 @@ restorecon -R /etc/rc\.d/init\.d/ceph > /dev/null 2>&1; \
 restorecon -R /etc/rc\.d/init\.d/radosgw > /dev/null 2>&1; \
 restorecon -R /var/run/ceph > /dev/null 2>&1; \
 restorecon -R /var/lib/ceph > /dev/null 2>&1; \
-restorecon -R /var/log/ceph > /dev/null 2>&1;
+restorecon -R /var/log/ceph > /dev/null 2>&1; \
+restorecon -R /var/log/radosgw > /dev/null 2>&1;
 %endif
 
 %{!?_udevrulesdir: %global _udevrulesdir /lib/udev/rules.d}
@@ -108,11 +109,6 @@ BuildRequires:	boost-devel
 BuildRequires:  cmake
 BuildRequires:	cryptsetup
 BuildRequires:	fuse-devel
-%if 0%{?suse_version}
-BuildRequires:	python-Cython
-%else
-BuildRequires:	Cython
-%endif
 BuildRequires:	gdbm
 BuildRequires:	hdparm
 BuildRequires:	leveldb-devel > 1.2
@@ -155,15 +151,20 @@ BuildRequires:	libbz2-devel
 %if 0%{with tcmalloc}
 BuildRequires:	gperftools-devel
 %endif
+BuildRequires:  btrfsprogs
 BuildRequires:	mozilla-nss-devel
 BuildRequires:	keyutils-devel
 BuildRequires:	libatomic-ops-devel
+BuildRequires:  libopenssl-devel
 BuildRequires:  lsb-release
+BuildRequires:  openldap2-devel
+BuildRequires:	python-Cython
 %endif
 %if 0%{?fedora} || 0%{?rhel} 
 %if 0%{?_with_systemd}
 Requires:	systemd
 %endif
+BuildRequires:	btrfs-progs
 BuildRequires:	nss-devel
 BuildRequires:	keyutils-libs-devel
 BuildRequires:	libatomic_ops-devel
@@ -171,7 +172,10 @@ Requires(post):	chkconfig
 Requires(preun):	chkconfig
 Requires(preun):	initscripts
 BuildRequires:	gperftools-devel
+BuildRequires:  openldap-devel
+BuildRequires:  openssl-devel
 BuildRequires:  redhat-lsb-core
+BuildRequires:	Cython
 %endif
 # boost
 %if 0%{?fedora} || 0%{?rhel} 
@@ -208,6 +212,10 @@ BuildRequires:	python-sphinx10
 %if 0%{?fedora} || 0%{?suse_version} || 0%{?rhel} >= 7
 BuildRequires:	python-sphinx
 %endif
+#hardened-cc1
+%if 0%{?fedora} || 0%{?rhel}
+BuildRequires:  redhat-rpm-config
+%endif
 
 %description
 Ceph is a massively scalable, open-source, distributed storage system that runs
@@ -224,6 +232,7 @@ Requires:      ceph-common = %{epoch}:%{version}-%{release}
 Requires:      librbd1 = %{epoch}:%{version}-%{release}
 Requires:      librados2 = %{epoch}:%{version}-%{release}
 Requires:      libcephfs1 = %{epoch}:%{version}-%{release}
+Requires:      librgw2 = %{epoch}:%{version}-%{release}
 %if 0%{with selinux}
 Requires:      ceph-selinux = %{epoch}:%{version}-%{release}
 %endif
@@ -253,6 +262,7 @@ Summary:	Ceph Common
 Group:		System Environment/Base
 Requires:	librbd1 = %{epoch}:%{version}-%{release}
 Requires:	librados2 = %{epoch}:%{version}-%{release}
+Requires:	libcephfs1 = %{epoch}:%{version}-%{release}
 Requires:	python-rados = %{epoch}:%{version}-%{release}
 Requires:	python-rbd = %{epoch}:%{version}-%{release}
 Requires:	python-cephfs = %{epoch}:%{version}-%{release}
@@ -300,14 +310,12 @@ of cluster membership, configuration, and state.
 %package fuse
 Summary:	Ceph fuse-based client
 Group:		System Environment/Base
-Requires:	%{name}
 %description fuse
 FUSE based client for Ceph distributed network file system
 
 %package -n rbd-fuse
 Summary:	Ceph fuse-based client
 Group:		System Environment/Base
-Requires:	%{name}
 Requires:	librados2 = %{epoch}:%{version}-%{release}
 Requires:	librbd1 = %{epoch}:%{version}-%{release}
 %description -n rbd-fuse
@@ -316,7 +324,6 @@ FUSE based client to map Ceph rbd images to files
 %package -n rbd-mirror
 Summary:	Ceph daemon for mirroring RBD images
 Group:		System Environment/Base
-Requires:	%{name}
 Requires:	ceph-common = %{epoch}:%{version}-%{release}
 Requires:	librados2 = %{epoch}:%{version}-%{release}
 %description -n rbd-mirror
@@ -326,7 +333,6 @@ changes asynchronously.
 %package -n rbd-nbd
 Summary:	Ceph RBD client base on NBD
 Group:		System Environment/Base
-Requires:	%{name}
 Requires:	librados2 = %{epoch}:%{version}-%{release}
 Requires:	librbd1 = %{epoch}:%{version}-%{release}
 %description -n rbd-nbd
@@ -340,6 +346,7 @@ Requires:	ceph-common = %{epoch}:%{version}-%{release}
 Requires:	ceph-selinux = %{epoch}:%{version}-%{release}
 %endif
 Requires:	librados2 = %{epoch}:%{version}-%{release}
+Requires:	librgw2 = %{epoch}:%{version}-%{release}
 %if 0%{?rhel} || 0%{?fedora}
 Requires:	mailcap
 # python-flask for powerdns
@@ -350,16 +357,17 @@ Requires:	python-flask
 Requires:      python-Flask
 %endif
 %description radosgw
-This package is an S3 HTTP REST gateway for the RADOS object store. It
-is implemented as a FastCGI module using libfcgi, and can be used in
-conjunction with any FastCGI capable web server.
+RADOS is a distributed object store used by the Ceph distributed
+storage system.  This package provides a REST gateway to the
+object store that aims to implement a superset of Amazon's S3
+service as well as the OpenStack Object Storage ("Swift") API.
 
 %if %{with ocf}
 %package resource-agents
 Summary:	OCF-compliant resource agents for Ceph daemons
 Group:		System Environment/Base
 License:	LGPL-2.0
-Requires:	%{name} = %{epoch}:%{version}
+Requires:	ceph-base = %{epoch}:%{version}
 Requires:	resource-agents
 %description resource-agents
 Resource agents for monitoring and managing Ceph daemons
@@ -406,6 +414,24 @@ Obsoletes:	ceph-devel < %{epoch}:%{version}-%{release}
 This package contains libraries and headers needed to develop programs
 that use RADOS object store.
 
+%package -n librgw2
+Summary:	RADOS gateway client library
+Group:		System Environment/Libraries
+License:	LGPL-2.0
+Requires:	librados2 = %{epoch}:%{version}-%{release}
+%description -n librgw2
+This package provides a library implementation of the RADOS gateway
+(distributed object store with S3 and Swift personalities).
+
+%package -n librgw2-devel
+Summary:	RADOS gateway client library
+Group:		Development/Libraries
+License:	LGPL-2.0
+Requires:	librados2 = %{epoch}:%{version}-%{release}
+%description -n librgw2-devel
+This package contains libraries and headers needed to develop programs
+that use RADOS gateway client library.
+
 %package -n python-rados
 Summary:	Python libraries for the RADOS object store
 Group:		System Environment/Libraries
@@ -564,7 +590,7 @@ This package contains the Java libraries for the Ceph File System.
 %package selinux
 Summary:	SELinux support for Ceph MON, OSD and MDS
 Group:		System Environment/Base
-Requires:	%{name}
+Requires:	ceph-base = %{epoch}:%{version}-%{release}
 Requires:	policycoreutils, libselinux-utils
 Requires(post): selinux-policy-base >= %{_selinux_policy_version}, policycoreutils, gawk
 Requires(postun): policycoreutils
@@ -601,7 +627,6 @@ Summary:	Compatibility package for Ceph headers
 Group:		Development/Libraries
 License:	LGPL-2.0
 Obsoletes:	ceph-devel
-Requires:	%{name} = %{epoch}:%{version}-%{release}
 Requires:	librados2-devel = %{epoch}:%{version}-%{release}
 Requires:	libradosstriper1-devel = %{epoch}:%{version}-%{release}
 Requires:	librbd1-devel = %{epoch}:%{version}-%{release}
@@ -733,11 +758,13 @@ install -m 0644 -D etc/sysconfig/ceph $RPM_BUILD_ROOT%{_localstatedir}/adm/fillu
   install -m 0644 -D systemd/ceph-create-keys at .service $RPM_BUILD_ROOT%{_unitdir}/ceph-create-keys at .service
   install -m 0644 -D systemd/ceph-mds at .service $RPM_BUILD_ROOT%{_unitdir}/ceph-mds at .service
   install -m 0644 -D systemd/ceph-radosgw at .service $RPM_BUILD_ROOT%{_unitdir}/ceph-radosgw at .service
+  install -m 0644 -D systemd/ceph-rbd-mirror at .service $RPM_BUILD_ROOT%{_unitdir}/ceph-rbd-mirror at .service
   install -m 0644 -D systemd/ceph.target $RPM_BUILD_ROOT%{_unitdir}/ceph.target
   install -m 0644 -D systemd/ceph-osd.target $RPM_BUILD_ROOT%{_unitdir}/ceph-osd.target
   install -m 0644 -D systemd/ceph-mon.target $RPM_BUILD_ROOT%{_unitdir}/ceph-mon.target
   install -m 0644 -D systemd/ceph-mds.target $RPM_BUILD_ROOT%{_unitdir}/ceph-mds.target
   install -m 0644 -D systemd/ceph-radosgw.target $RPM_BUILD_ROOT%{_unitdir}/ceph-radosgw.target
+  install -m 0644 -D systemd/ceph-rbd-mirror.target $RPM_BUILD_ROOT%{_unitdir}/ceph-rbd-mirror.target
   install -m 0644 -D systemd/ceph-disk at .service $RPM_BUILD_ROOT%{_unitdir}/ceph-disk at .service
   install -m 0755 -D systemd/ceph $RPM_BUILD_ROOT%{_sbindir}/rcceph
 %else
@@ -942,6 +969,9 @@ rm -rf $RPM_BUILD_ROOT
 %{_bindir}/ceph-rbdnamer
 %{_bindir}/ceph-syn
 %{_bindir}/ceph-crush-location
+%{_bindir}/cephfs-data-scan
+%{_bindir}/cephfs-journal-tool
+%{_bindir}/cephfs-table-tool
 %{_bindir}/rados
 %{_bindir}/rbd
 %{_bindir}/rbd-replay
@@ -1018,9 +1048,6 @@ fi
 #################################################################################
 %files mds
 %{_bindir}/ceph-mds
-%{_bindir}/cephfs-journal-tool
-%{_bindir}/cephfs-table-tool
-%{_bindir}/cephfs-data-scan
 %{_mandir}/man8/ceph-mds.8*
 %if 0%{?_with_systemd}
 %{_unitdir}/ceph-mds at .service
@@ -1067,6 +1094,10 @@ fi
 %defattr(-,root,root,-)
 %{_bindir}/rbd-mirror
 %{_mandir}/man8/rbd-mirror.8*
+%if 0%{?_with_systemd}
+%{_unitdir}/ceph-rbd-mirror at .service
+%{_unitdir}/ceph-rbd-mirror.target
+%endif
 
 #################################################################################
 %files -n rbd-nbd
@@ -1079,6 +1110,7 @@ fi
 %defattr(-,root,root,-)
 %{_bindir}/radosgw
 %{_bindir}/radosgw-admin
+%{_bindir}/radosgw-token
 %{_bindir}/radosgw-object-expirer
 %{_mandir}/man8/radosgw.8*
 %{_mandir}/man8/radosgw-admin.8*
@@ -1161,12 +1193,27 @@ fi
 
 #################################################################################
 %if %{with ocf}
+
 %files resource-agents
 %defattr(0755,root,root,-)
-%dir /usr/lib/ocf
-%dir /usr/lib/ocf/resource.d
-%dir /usr/lib/ocf/resource.d/ceph
-/usr/lib/ocf/resource.d/%{name}/*
+# N.B. src/ocf/Makefile.am uses $(prefix)/lib
+%dir %{_prefix}/lib/ocf
+%dir %{_prefix}/lib/ocf/resource.d
+%dir %{_prefix}/lib/ocf/resource.d/ceph
+%if 0%{_with_systemd}
+%exclude %{_prefix}/lib/ocf/resource.d/ceph/ceph
+%exclude %{_prefix}/lib/ocf/resource.d/ceph/mds
+%exclude %{_prefix}/lib/ocf/resource.d/ceph/mon
+%exclude %{_prefix}/lib/ocf/resource.d/ceph/osd
+%endif
+%if ! 0%{_with_systemd}
+%{_prefix}/lib/ocf/resource.d/ceph/ceph
+%{_prefix}/lib/ocf/resource.d/ceph/mds
+%{_prefix}/lib/ocf/resource.d/ceph/mon
+%{_prefix}/lib/ocf/resource.d/ceph/osd
+%endif
+%{_prefix}/lib/ocf/resource.d/ceph/rbd
+
 %endif
 
 #################################################################################
@@ -1206,7 +1253,8 @@ fi
 #################################################################################
 %files -n python-rados
 %defattr(-,root,root,-)
-%{python_sitelib}/rados.py*
+%{python_sitearch}/rados.so
+%{python_sitearch}/rados-*.egg-info
 
 #################################################################################
 %files -n libradosstriper1
@@ -1256,6 +1304,25 @@ ln -sf %{_libdir}/librbd.so.1 /usr/lib64/qemu/librbd.so.1
 %endif
 
 #################################################################################
+%files -n librgw2
+%defattr(-,root,root,-)
+%{_libdir}/librgw.so.*
+
+%post -n librgw2
+/sbin/ldconfig
+
+%postun -n librgw2
+/sbin/ldconfig
+
+#################################################################################
+%files -n librgw2-devel
+%defattr(-,root,root,-)
+%dir %{_includedir}/rados
+%{_includedir}/rados/librgw.h
+%{_includedir}/rados/rgw_file.h
+%{_libdir}/librgw.so
+
+#################################################################################
 %files -n python-rbd
 %defattr(-,root,root,-)
 %{python_sitearch}/rbd.so
@@ -1282,7 +1349,8 @@ ln -sf %{_libdir}/librbd.so.1 /usr/lib64/qemu/librbd.so.1
 #################################################################################
 %files -n python-cephfs
 %defattr(-,root,root,-)
-%{python_sitelib}/cephfs.py*
+%{python_sitearch}/cephfs.so
+%{python_sitearch}/cephfs-*.egg-info
 %{python_sitelib}/ceph_volume_client.py*
 
 #################################################################################
@@ -1310,6 +1378,7 @@ ln -sf %{_libdir}/librbd.so.1 /usr/lib64/qemu/librbd.so.1
 %{_bindir}/ceph_smalliobenchfs
 %{_bindir}/ceph_smalliobenchrbd
 %{_bindir}/ceph_test_*
+%{_bindir}/librgw_file*
 %{_bindir}/ceph_tpbench
 %{_bindir}/ceph_xattr_bench
 %{_bindir}/ceph-coverage
diff --git a/src/test/journal/RadosTestFixture.cc b/src/test/journal/RadosTestFixture.cc
index c965c52..6fa8759 100644
--- a/src/test/journal/RadosTestFixture.cc
+++ b/src/test/journal/RadosTestFixture.cc
@@ -4,6 +4,7 @@
 #include "test/journal/RadosTestFixture.h"
 #include "cls/journal/cls_journal_client.h"
 #include "include/stringify.h"
+#include "common/WorkQueue.h"
 
 RadosTestFixture::RadosTestFixture()
   : m_timer_lock("m_timer_lock"), m_timer(NULL), m_listener(this) {
@@ -12,10 +13,18 @@ RadosTestFixture::RadosTestFixture()
 void RadosTestFixture::SetUpTestCase() {
   _pool_name = get_temp_pool_name();
   ASSERT_EQ("", create_one_pool_pp(_pool_name, _rados));
+
+  CephContext* cct = reinterpret_cast<CephContext*>(_rados.cct());
+  _thread_pool = new ThreadPool(cct, "RadosTestFixture::_thread_pool",
+                                 "tp_test", 1);
+  _thread_pool->start();
 }
 
 void RadosTestFixture::TearDownTestCase() {
   ASSERT_EQ(0, destroy_one_pool_pp(_pool_name, _rados));
+
+  _thread_pool->stop();
+  delete _thread_pool;
 }
 
 std::string RadosTestFixture::get_temp_oid() {
@@ -25,8 +34,12 @@ std::string RadosTestFixture::get_temp_oid() {
 
 void RadosTestFixture::SetUp() {
   ASSERT_EQ(0, _rados.ioctx_create(_pool_name.c_str(), m_ioctx));
-  m_timer = new SafeTimer(reinterpret_cast<CephContext*>(m_ioctx.cct()),
-                          m_timer_lock, true);
+
+  CephContext* cct = reinterpret_cast<CephContext*>(m_ioctx.cct());
+  m_work_queue = new ContextWQ("RadosTestFixture::m_work_queue", 60,
+                               _thread_pool);
+
+  m_timer = new SafeTimer(cct, m_timer_lock, true);
   m_timer->init();
 }
 
@@ -36,6 +49,9 @@ void RadosTestFixture::TearDown() {
     m_timer->shutdown();
   }
   delete m_timer;
+
+  m_work_queue->drain();
+  delete m_work_queue;
 }
 
 int RadosTestFixture::create(const std::string &oid, uint8_t order,
@@ -43,6 +59,15 @@ int RadosTestFixture::create(const std::string &oid, uint8_t order,
   return cls::journal::client::create(m_ioctx, oid, order, splay_width, -1);
 }
 
+journal::JournalMetadataPtr RadosTestFixture::create_metadata(
+    const std::string &oid, const std::string &client_id,
+    double commit_internal) {
+  journal::JournalMetadataPtr metadata(new journal::JournalMetadata(
+    m_work_queue, m_timer, &m_timer_lock, m_ioctx, oid, client_id,
+    commit_internal));
+  return metadata;
+}
+
 int RadosTestFixture::append(const std::string &oid, const bufferlist &bl) {
   librados::ObjectWriteOperation op;
   op.append(bl);
@@ -93,3 +118,4 @@ bool RadosTestFixture::wait_for_update(journal::JournalMetadataPtr metadata) {
 std::string RadosTestFixture::_pool_name;
 librados::Rados RadosTestFixture::_rados;
 uint64_t RadosTestFixture::_oid_number = 0;
+ThreadPool *RadosTestFixture::_thread_pool = nullptr;
diff --git a/src/test/journal/RadosTestFixture.h b/src/test/journal/RadosTestFixture.h
index 3b05a70..3415b0b 100644
--- a/src/test/journal/RadosTestFixture.h
+++ b/src/test/journal/RadosTestFixture.h
@@ -8,6 +8,8 @@
 #include "cls/journal/cls_journal_types.h"
 #include "gtest/gtest.h"
 
+class ThreadPool;
+
 class RadosTestFixture : public ::testing::Test {
 public:
   static void SetUpTestCase();
@@ -19,11 +21,15 @@ public:
   virtual void SetUp();
   virtual void TearDown();
 
-  int create(const std::string &oid, uint8_t order, uint8_t splay_width);
+  int create(const std::string &oid, uint8_t order = 14,
+             uint8_t splay_width = 2);
+  journal::JournalMetadataPtr create_metadata(const std::string &oid,
+                                              const std::string &client_id = "client",
+                                              double commit_internal = 0.1);
   int append(const std::string &oid, const bufferlist &bl);
 
-  int client_register(const std::string &oid, const std::string &id,
-                      const std::string &description);
+  int client_register(const std::string &oid, const std::string &id = "client",
+                      const std::string &description = "");
   int client_commit(const std::string &oid, const std::string &id,
                     const cls::journal::ObjectSetPosition &commit_position);
 
@@ -52,9 +58,12 @@ public:
   static std::string _pool_name;
   static librados::Rados _rados;
   static uint64_t _oid_number;
+  static ThreadPool *_thread_pool;
 
   librados::IoCtx m_ioctx;
 
+  ContextWQ *m_work_queue;
+
   Mutex m_timer_lock;
   SafeTimer *m_timer;
 
diff --git a/src/test/journal/test_FutureImpl.cc b/src/test/journal/test_FutureImpl.cc
index 3a45a8d..51e19cf 100644
--- a/src/test/journal/test_FutureImpl.cc
+++ b/src/test/journal/test_FutureImpl.cc
@@ -3,21 +3,12 @@
 
 #include "journal/FutureImpl.h"
 #include "common/Cond.h"
-#include "common/Finisher.h"
 #include "common/Mutex.h"
 #include "gtest/gtest.h"
 #include "test/journal/RadosTestFixture.h"
 
 class TestFutureImpl : public RadosTestFixture {
 public:
-
-  TestFutureImpl() : m_finisher(NULL) {
-  }
-  ~TestFutureImpl() {
-    m_finisher->stop();
-    delete m_finisher;
-  }
-
   struct FlushHandler : public journal::FutureImpl::FlushHandler {
     uint64_t refs;
     uint64_t flushes;
@@ -34,18 +25,13 @@ public:
     }
   };
 
-  void SetUp() {
-    RadosTestFixture::SetUp();
-    m_finisher = new Finisher(reinterpret_cast<CephContext*>(m_ioctx.cct()));
-    m_finisher->start();
-  }
-
-  journal::FutureImplPtr create_future(uint64_t tag_tid, uint64_t entry_tid,
+  journal::FutureImplPtr create_future(journal::JournalMetadataPtr metadata,
+                                       uint64_t tag_tid, uint64_t entry_tid,
                                        uint64_t commit_tid,
                                        const journal::FutureImplPtr &prev =
                                          journal::FutureImplPtr()) {
-    journal::FutureImplPtr future(new journal::FutureImpl(*m_finisher,
-                                                          tag_tid, entry_tid,
+    journal::FutureImplPtr future(new journal::FutureImpl(metadata, tag_tid,
+                                                          entry_tid,
                                                           commit_tid));
     future->init(prev);
     return future;
@@ -54,26 +40,42 @@ public:
   void flush(const journal::FutureImplPtr &future) {
   }
 
-  Finisher *m_finisher;
-
   FlushHandler m_flush_handler;
 };
 
 TEST_F(TestFutureImpl, Getters) {
-  journal::FutureImplPtr future = create_future(234, 123, 456);
+  std::string oid = get_temp_oid();
+  ASSERT_EQ(0, create(oid));
+  ASSERT_EQ(0, client_register(oid));
+  journal::JournalMetadataPtr metadata = create_metadata(oid);
+  ASSERT_EQ(0, init_metadata(metadata));
+
+  journal::FutureImplPtr future = create_future(metadata, 234, 123, 456);
   ASSERT_EQ(234U, future->get_tag_tid());
   ASSERT_EQ(123U, future->get_entry_tid());
   ASSERT_EQ(456U, future->get_commit_tid());
 }
 
 TEST_F(TestFutureImpl, Attach) {
-  journal::FutureImplPtr future = create_future(234, 123, 456);
+  std::string oid = get_temp_oid();
+  ASSERT_EQ(0, create(oid));
+  ASSERT_EQ(0, client_register(oid));
+  journal::JournalMetadataPtr metadata = create_metadata(oid);
+  ASSERT_EQ(0, init_metadata(metadata));
+
+  journal::FutureImplPtr future = create_future(metadata, 234, 123, 456);
   ASSERT_FALSE(future->attach(&m_flush_handler));
   ASSERT_EQ(1U, m_flush_handler.refs);
 }
 
 TEST_F(TestFutureImpl, AttachWithPendingFlush) {
-  journal::FutureImplPtr future = create_future(234, 123, 456);
+  std::string oid = get_temp_oid();
+  ASSERT_EQ(0, create(oid));
+  ASSERT_EQ(0, client_register(oid));
+  journal::JournalMetadataPtr metadata = create_metadata(oid);
+  ASSERT_EQ(0, init_metadata(metadata));
+
+  journal::FutureImplPtr future = create_future(metadata, 234, 123, 456);
   future->flush(NULL);
 
   ASSERT_TRUE(future->attach(&m_flush_handler));
@@ -81,21 +83,39 @@ TEST_F(TestFutureImpl, AttachWithPendingFlush) {
 }
 
 TEST_F(TestFutureImpl, Detach) {
-  journal::FutureImplPtr future = create_future(234, 123, 456);
+  std::string oid = get_temp_oid();
+  ASSERT_EQ(0, create(oid));
+  ASSERT_EQ(0, client_register(oid));
+  journal::JournalMetadataPtr metadata = create_metadata(oid);
+  ASSERT_EQ(0, init_metadata(metadata));
+
+  journal::FutureImplPtr future = create_future(metadata, 234, 123, 456);
   ASSERT_FALSE(future->attach(&m_flush_handler));
   future->detach();
   ASSERT_EQ(0U, m_flush_handler.refs);
 }
 
 TEST_F(TestFutureImpl, DetachImplicit) {
-  journal::FutureImplPtr future = create_future(234, 123, 456);
+  std::string oid = get_temp_oid();
+  ASSERT_EQ(0, create(oid));
+  ASSERT_EQ(0, client_register(oid));
+  journal::JournalMetadataPtr metadata = create_metadata(oid);
+  ASSERT_EQ(0, init_metadata(metadata));
+
+  journal::FutureImplPtr future = create_future(metadata, 234, 123, 456);
   ASSERT_FALSE(future->attach(&m_flush_handler));
   future.reset();
   ASSERT_EQ(0U, m_flush_handler.refs);
 }
 
 TEST_F(TestFutureImpl, Flush) {
-  journal::FutureImplPtr future = create_future(234, 123, 456);
+  std::string oid = get_temp_oid();
+  ASSERT_EQ(0, create(oid));
+  ASSERT_EQ(0, client_register(oid));
+  journal::JournalMetadataPtr metadata = create_metadata(oid);
+  ASSERT_EQ(0, init_metadata(metadata));
+
+  journal::FutureImplPtr future = create_future(metadata, 234, 123, 456);
   ASSERT_FALSE(future->attach(&m_flush_handler));
 
   C_SaferCond cond;
@@ -107,7 +127,13 @@ TEST_F(TestFutureImpl, Flush) {
 }
 
 TEST_F(TestFutureImpl, FlushWithoutContext) {
-  journal::FutureImplPtr future = create_future(234, 123, 456);
+  std::string oid = get_temp_oid();
+  ASSERT_EQ(0, create(oid));
+  ASSERT_EQ(0, client_register(oid));
+  journal::JournalMetadataPtr metadata = create_metadata(oid);
+  ASSERT_EQ(0, init_metadata(metadata));
+
+  journal::FutureImplPtr future = create_future(metadata, 234, 123, 456);
   ASSERT_FALSE(future->attach(&m_flush_handler));
 
   future->flush(NULL);
@@ -118,9 +144,17 @@ TEST_F(TestFutureImpl, FlushWithoutContext) {
 }
 
 TEST_F(TestFutureImpl, FlushChain) {
-  journal::FutureImplPtr future1 = create_future(234, 123, 456);
-  journal::FutureImplPtr future2 = create_future(234, 124, 457, future1);
-  journal::FutureImplPtr future3 = create_future(235, 1, 458, future2);
+  std::string oid = get_temp_oid();
+  ASSERT_EQ(0, create(oid));
+  ASSERT_EQ(0, client_register(oid));
+  journal::JournalMetadataPtr metadata = create_metadata(oid);
+  ASSERT_EQ(0, init_metadata(metadata));
+
+  journal::FutureImplPtr future1 = create_future(metadata, 234, 123, 456);
+  journal::FutureImplPtr future2 = create_future(metadata, 234, 124, 457,
+                                                 future1);
+  journal::FutureImplPtr future3 = create_future(metadata, 235, 1, 458,
+                                                 future2);
   ASSERT_FALSE(future1->attach(&m_flush_handler));
   ASSERT_FALSE(future2->attach(&m_flush_handler));
   ASSERT_FALSE(future3->attach(&m_flush_handler));
@@ -144,8 +178,15 @@ TEST_F(TestFutureImpl, FlushChain) {
 }
 
 TEST_F(TestFutureImpl, FlushInProgress) {
-  journal::FutureImplPtr future1 = create_future(234, 123, 456);
-  journal::FutureImplPtr future2 = create_future(234, 124, 457, future1);
+  std::string oid = get_temp_oid();
+  ASSERT_EQ(0, create(oid));
+  ASSERT_EQ(0, client_register(oid));
+  journal::JournalMetadataPtr metadata = create_metadata(oid);
+  ASSERT_EQ(0, init_metadata(metadata));
+
+  journal::FutureImplPtr future1 = create_future(metadata, 234, 123, 456);
+  journal::FutureImplPtr future2 = create_future(metadata, 234, 124, 457,
+                                                 future1);
   ASSERT_FALSE(future1->attach(&m_flush_handler));
   ASSERT_FALSE(future2->attach(&m_flush_handler));
 
@@ -159,7 +200,13 @@ TEST_F(TestFutureImpl, FlushInProgress) {
 }
 
 TEST_F(TestFutureImpl, FlushAlreadyComplete) {
-  journal::FutureImplPtr future = create_future(234, 123, 456);
+  std::string oid = get_temp_oid();
+  ASSERT_EQ(0, create(oid));
+  ASSERT_EQ(0, client_register(oid));
+  journal::JournalMetadataPtr metadata = create_metadata(oid);
+  ASSERT_EQ(0, init_metadata(metadata));
+
+  journal::FutureImplPtr future = create_future(metadata, 234, 123, 456);
   future->safe(-EIO);
 
   C_SaferCond cond;
@@ -168,7 +215,13 @@ TEST_F(TestFutureImpl, FlushAlreadyComplete) {
 }
 
 TEST_F(TestFutureImpl, Wait) {
-  journal::FutureImplPtr future = create_future(234, 1, 456);
+  std::string oid = get_temp_oid();
+  ASSERT_EQ(0, create(oid));
+  ASSERT_EQ(0, client_register(oid));
+  journal::JournalMetadataPtr metadata = create_metadata(oid);
+  ASSERT_EQ(0, init_metadata(metadata));
+
+  journal::FutureImplPtr future = create_future(metadata, 234, 1, 456);
 
   C_SaferCond cond;
   future->wait(&cond);
@@ -177,7 +230,13 @@ TEST_F(TestFutureImpl, Wait) {
 }
 
 TEST_F(TestFutureImpl, WaitAlreadyComplete) {
-  journal::FutureImplPtr future = create_future(234, 1, 456);
+  std::string oid = get_temp_oid();
+  ASSERT_EQ(0, create(oid));
+  ASSERT_EQ(0, client_register(oid));
+  journal::JournalMetadataPtr metadata = create_metadata(oid);
+  ASSERT_EQ(0, init_metadata(metadata));
+
+  journal::FutureImplPtr future = create_future(metadata, 234, 1, 456);
   future->safe(-EEXIST);
 
   C_SaferCond cond;
@@ -186,8 +245,15 @@ TEST_F(TestFutureImpl, WaitAlreadyComplete) {
 }
 
 TEST_F(TestFutureImpl, SafePreservesError) {
-  journal::FutureImplPtr future1 = create_future(234, 123, 456);
-  journal::FutureImplPtr future2 = create_future(234, 124, 457, future1);
+  std::string oid = get_temp_oid();
+  ASSERT_EQ(0, create(oid));
+  ASSERT_EQ(0, client_register(oid));
+  journal::JournalMetadataPtr metadata = create_metadata(oid);
+  ASSERT_EQ(0, init_metadata(metadata));
+
+  journal::FutureImplPtr future1 = create_future(metadata, 234, 123, 456);
+  journal::FutureImplPtr future2 = create_future(metadata, 234, 124, 457,
+                                                 future1);
 
   future1->safe(-EIO);
   future2->safe(-EEXIST);
@@ -196,8 +262,15 @@ TEST_F(TestFutureImpl, SafePreservesError) {
 }
 
 TEST_F(TestFutureImpl, ConsistentPreservesError) {
-  journal::FutureImplPtr future1 = create_future(234, 123, 456);
-  journal::FutureImplPtr future2 = create_future(234, 124, 457, future1);
+  std::string oid = get_temp_oid();
+  ASSERT_EQ(0, create(oid));
+  ASSERT_EQ(0, client_register(oid));
+  journal::JournalMetadataPtr metadata = create_metadata(oid);
+  ASSERT_EQ(0, init_metadata(metadata));
+
+  journal::FutureImplPtr future1 = create_future(metadata, 234, 123, 456);
+  journal::FutureImplPtr future2 = create_future(metadata, 234, 124, 457,
+                                                 future1);
 
   future2->safe(-EEXIST);
   future1->safe(-EIO);
diff --git a/src/test/journal/test_JournalMetadata.cc b/src/test/journal/test_JournalMetadata.cc
index 1a97ae7..850263d 100644
--- a/src/test/journal/test_JournalMetadata.cc
+++ b/src/test/journal/test_JournalMetadata.cc
@@ -14,13 +14,16 @@ public:
          it != m_metadata_list.end(); ++it) {
       (*it)->remove_listener(&m_listener);
     }
+    m_metadata_list.clear();
+
     RadosTestFixture::TearDown();
   }
 
   journal::JournalMetadataPtr create_metadata(const std::string &oid,
-                                              const std::string &client_id) {
-    journal::JournalMetadataPtr metadata(new journal::JournalMetadata(
-      m_ioctx, oid, client_id, 0.1));
+                                              const std::string &client_id,
+                                              double commit_internal = 0.1) {
+    journal::JournalMetadataPtr metadata = RadosTestFixture::create_metadata(
+      oid, client_id, commit_internal);
     m_metadata_list.push_back(metadata);
     metadata->add_listener(&m_listener);
     return metadata;
@@ -50,36 +53,49 @@ TEST_F(TestJournalMetadata, ClientDNE) {
   ASSERT_EQ(-ENOENT, init_metadata(metadata2));
 }
 
-TEST_F(TestJournalMetadata, SetCommitPositions) {
+TEST_F(TestJournalMetadata, Committed) {
   std::string oid = get_temp_oid();
 
   ASSERT_EQ(0, create(oid, 14, 2));
   ASSERT_EQ(0, client_register(oid, "client1", ""));
 
-  journal::JournalMetadataPtr metadata1 = create_metadata(oid, "client1");
+  journal::JournalMetadataPtr metadata1 = create_metadata(oid, "client1", 600);
   ASSERT_EQ(0, init_metadata(metadata1));
 
   journal::JournalMetadataPtr metadata2 = create_metadata(oid, "client1");
   ASSERT_EQ(0, init_metadata(metadata2));
   ASSERT_TRUE(wait_for_update(metadata2));
 
-  journal::JournalMetadata::ObjectSetPosition commit_position;
+  journal::JournalMetadata::ObjectSetPosition expect_commit_position;
   journal::JournalMetadata::ObjectSetPosition read_commit_position;
   metadata1->get_commit_position(&read_commit_position);
-  ASSERT_EQ(commit_position, read_commit_position);
+  ASSERT_EQ(expect_commit_position, read_commit_position);
 
-  journal::JournalMetadata::EntryPositions entry_positions;
-  entry_positions = {
-    cls::journal::EntryPosition(123, 122)};
-  commit_position = journal::JournalMetadata::ObjectSetPosition(1, entry_positions);
+  uint64_t commit_tid1 = metadata1->allocate_commit_tid(0, 0, 0);
+  uint64_t commit_tid2 = metadata1->allocate_commit_tid(0, 1, 0);
+  uint64_t commit_tid3 = metadata1->allocate_commit_tid(1, 0, 1);
+  uint64_t commit_tid4 = metadata1->allocate_commit_tid(0, 0, 2);
 
-  C_SaferCond cond;
-  metadata1->set_commit_position(commit_position, &cond);
-  ASSERT_EQ(0, cond.wait());
-  ASSERT_TRUE(wait_for_update(metadata2));
+  // cannot commit until tid1 + 2 committed
+  metadata1->committed(commit_tid2, []() { return nullptr; });
+  metadata1->committed(commit_tid3, []() { return nullptr; });
+
+  C_SaferCond cond1;
+  metadata1->committed(commit_tid1, [&cond1]() { return &cond1; });
 
+  // given our 10 minute commit internal, this should override the
+  // in-flight commit
+  C_SaferCond cond2;
+  metadata1->committed(commit_tid4, [&cond2]() { return &cond2; });
+
+  ASSERT_EQ(-ESTALE, cond1.wait());
+  metadata1->flush_commit_position();
+  ASSERT_EQ(0, cond2.wait());
+
+  ASSERT_TRUE(wait_for_update(metadata2));
   metadata2->get_commit_position(&read_commit_position);
-  ASSERT_EQ(commit_position, read_commit_position);
+  expect_commit_position = {{{0, 0, 2}, {1, 0, 1}}};
+  ASSERT_EQ(expect_commit_position, read_commit_position);
 }
 
 TEST_F(TestJournalMetadata, UpdateActiveObject) {
diff --git a/src/test/journal/test_JournalPlayer.cc b/src/test/journal/test_JournalPlayer.cc
index 6636327..3f992cb 100644
--- a/src/test/journal/test_JournalPlayer.cc
+++ b/src/test/journal/test_JournalPlayer.cc
@@ -53,14 +53,6 @@ public:
     RadosTestFixture::TearDown();
   }
 
-  int create(const std::string &oid, uint8_t splay_width = 2) {
-    return RadosTestFixture::create(oid, 14, splay_width);
-  }
-
-  int client_register(const std::string &oid) {
-    return RadosTestFixture::client_register(oid, "client", "");
-  }
-
   int client_commit(const std::string &oid,
                     journal::JournalPlayer::ObjectSetPosition position) {
     return RadosTestFixture::client_commit(oid, "client", position);
@@ -72,12 +64,6 @@ public:
     return journal::Entry(tag_tid, entry_tid, payload_bl);
   }
 
-  journal::JournalMetadataPtr create_metadata(const std::string &oid) {
-    journal::JournalMetadataPtr metadata(new journal::JournalMetadata(
-      m_ioctx, oid, "client", 0.1));
-    return metadata;
-  }
-
   journal::JournalPlayer *create_player(const std::string &oid,
                                           const journal::JournalMetadataPtr &metadata) {
     journal::JournalPlayer *player(new journal::JournalPlayer(
@@ -143,10 +129,10 @@ public:
 TEST_F(TestJournalPlayer, Prefetch) {
   std::string oid = get_temp_oid();
 
-  journal::JournalPlayer::EntryPositions positions;
+  journal::JournalPlayer::ObjectPositions positions;
   positions = {
-    cls::journal::EntryPosition(234, 122) };
-  cls::journal::ObjectSetPosition commit_position(0, positions);
+    cls::journal::ObjectPosition(0, 234, 122) };
+  cls::journal::ObjectSetPosition commit_position(positions);
 
   ASSERT_EQ(0, create(oid));
   ASSERT_EQ(0, client_register(oid));
@@ -183,10 +169,11 @@ TEST_F(TestJournalPlayer, Prefetch) {
 TEST_F(TestJournalPlayer, PrefetchSkip) {
   std::string oid = get_temp_oid();
 
-  journal::JournalPlayer::EntryPositions positions;
+  journal::JournalPlayer::ObjectPositions positions;
   positions = {
-    cls::journal::EntryPosition(234, 125) };
-  cls::journal::ObjectSetPosition commit_position(0, positions);
+    cls::journal::ObjectPosition(0, 234, 125),
+    cls::journal::ObjectPosition(1, 234, 124) };
+  cls::journal::ObjectSetPosition commit_position(positions);
 
   ASSERT_EQ(0, create(oid));
   ASSERT_EQ(0, client_register(oid));
@@ -246,13 +233,14 @@ TEST_F(TestJournalPlayer, PrefetchWithoutCommit) {
 TEST_F(TestJournalPlayer, PrefetchMultipleTags) {
   std::string oid = get_temp_oid();
 
-  journal::JournalPlayer::EntryPositions positions;
+  journal::JournalPlayer::ObjectPositions positions;
   positions = {
-    cls::journal::EntryPosition(234, 122),
-    cls::journal::EntryPosition(345, 1)};
-  cls::journal::ObjectSetPosition commit_position(0, positions);
+    cls::journal::ObjectPosition(2, 234, 122),
+    cls::journal::ObjectPosition(1, 234, 121),
+    cls::journal::ObjectPosition(0, 234, 120)};
+  cls::journal::ObjectSetPosition commit_position(positions);
 
-  ASSERT_EQ(0, create(oid));
+  ASSERT_EQ(0, create(oid, 14, 3));
   ASSERT_EQ(0, client_register(oid));
   ASSERT_EQ(0, client_commit(oid, commit_position));
 
@@ -262,13 +250,11 @@ TEST_F(TestJournalPlayer, PrefetchMultipleTags) {
   journal::JournalPlayer *player = create_player(oid, metadata);
 
   ASSERT_EQ(0, write_entry(oid, 0, 234, 120));
-  ASSERT_EQ(0, write_entry(oid, 0, 345, 0));
   ASSERT_EQ(0, write_entry(oid, 1, 234, 121));
-  ASSERT_EQ(0, write_entry(oid, 1, 345, 1));
-  ASSERT_EQ(0, write_entry(oid, 0, 234, 122));
-  ASSERT_EQ(0, write_entry(oid, 1, 234, 123));
-  ASSERT_EQ(0, write_entry(oid, 0, 234, 124));
-  ASSERT_EQ(0, write_entry(oid, 0, 345, 2));
+  ASSERT_EQ(0, write_entry(oid, 2, 234, 122));
+  ASSERT_EQ(0, write_entry(oid, 0, 234, 123));
+  ASSERT_EQ(0, write_entry(oid, 1, 234, 124));
+  ASSERT_EQ(0, write_entry(oid, 0, 236, 0)); // new tag allocated
 
   player->prefetch();
 
@@ -279,8 +265,8 @@ TEST_F(TestJournalPlayer, PrefetchMultipleTags) {
   uint64_t last_tid;
   ASSERT_TRUE(metadata->get_last_allocated_entry_tid(234, &last_tid));
   ASSERT_EQ(124U, last_tid);
-  ASSERT_TRUE(metadata->get_last_allocated_entry_tid(345, &last_tid));
-  ASSERT_EQ(2U, last_tid);
+  ASSERT_TRUE(metadata->get_last_allocated_entry_tid(236, &last_tid));
+  ASSERT_EQ(0U, last_tid);
 }
 
 TEST_F(TestJournalPlayer, PrefetchCorruptSequence) {
@@ -298,28 +284,56 @@ TEST_F(TestJournalPlayer, PrefetchCorruptSequence) {
   journal::JournalPlayer *player = create_player(oid, metadata);
 
   ASSERT_EQ(0, write_entry(oid, 0, 234, 120));
-  ASSERT_EQ(0, write_entry(oid, 0, 345, 0));
   ASSERT_EQ(0, write_entry(oid, 1, 234, 121));
   ASSERT_EQ(0, write_entry(oid, 0, 234, 124));
 
   player->prefetch();
   Entries entries;
-  ASSERT_TRUE(wait_for_entries(player, 3, &entries));
+  ASSERT_TRUE(wait_for_entries(player, 2, &entries));
+
+  journal::Entry entry;
+  uint64_t commit_tid;
+  ASSERT_FALSE(player->try_pop_front(&entry, &commit_tid));
+  ASSERT_TRUE(wait_for_complete(player));
+  ASSERT_EQ(-ENOMSG, m_replay_hander.complete_result);
+}
+
+TEST_F(TestJournalPlayer, PrefetchUnexpectedTag) {
+  std::string oid = get_temp_oid();
+
+  cls::journal::ObjectSetPosition commit_position;
+
+  ASSERT_EQ(0, create(oid));
+  ASSERT_EQ(0, client_register(oid));
+  ASSERT_EQ(0, client_commit(oid, commit_position));
+
+  journal::JournalMetadataPtr metadata = create_metadata(oid);
+  ASSERT_EQ(0, init_metadata(metadata));
+
+  journal::JournalPlayer *player = create_player(oid, metadata);
+
+  ASSERT_EQ(0, write_entry(oid, 0, 234, 120));
+  ASSERT_EQ(0, write_entry(oid, 1, 235, 121));
+  ASSERT_EQ(0, write_entry(oid, 0, 234, 124));
+
+  player->prefetch();
+  Entries entries;
+  ASSERT_TRUE(wait_for_entries(player, 1, &entries));
 
   journal::Entry entry;
   uint64_t commit_tid;
   ASSERT_FALSE(player->try_pop_front(&entry, &commit_tid));
   ASSERT_TRUE(wait_for_complete(player));
-  ASSERT_NE(0, m_replay_hander.complete_result);
+  ASSERT_EQ(-ENOMSG, m_replay_hander.complete_result);
 }
 
 TEST_F(TestJournalPlayer, PrefetchAndWatch) {
   std::string oid = get_temp_oid();
 
-  journal::JournalPlayer::EntryPositions positions;
+  journal::JournalPlayer::ObjectPositions positions;
   positions = {
-    cls::journal::EntryPosition(234, 122)};
-  cls::journal::ObjectSetPosition commit_position(0, positions);
+    cls::journal::ObjectPosition(0, 234, 122)};
+  cls::journal::ObjectSetPosition commit_position(positions);
 
   ASSERT_EQ(0, create(oid));
   ASSERT_EQ(0, client_register(oid));
@@ -354,7 +368,7 @@ TEST_F(TestJournalPlayer, PrefetchSkippedObject) {
 
   cls::journal::ObjectSetPosition commit_position;
 
-  ASSERT_EQ(0, create(oid, 3));
+  ASSERT_EQ(0, create(oid, 14, 3));
   ASSERT_EQ(0, client_register(oid));
   ASSERT_EQ(0, client_commit(oid, commit_position));
 
diff --git a/src/test/journal/test_JournalRecorder.cc b/src/test/journal/test_JournalRecorder.cc
index 099c9a2..d384e7f 100644
--- a/src/test/journal/test_JournalRecorder.cc
+++ b/src/test/journal/test_JournalRecorder.cc
@@ -18,16 +18,6 @@ public:
     RadosTestFixture::TearDown();
   }
 
-  int client_register(const std::string &oid) {
-    return RadosTestFixture::client_register(oid, "client", "");
-  }
-
-  journal::JournalMetadataPtr create_metadata(const std::string &oid) {
-    journal::JournalMetadataPtr metadata(new journal::JournalMetadata(
-      m_ioctx, oid, "client", 0.1));
-    return metadata;
-  }
-
   journal::JournalRecorder *create_recorder(const std::string &oid,
                                             const journal::JournalMetadataPtr &metadata) {
     journal::JournalRecorder *recorder(new journal::JournalRecorder(
diff --git a/src/test/journal/test_JournalTrimmer.cc b/src/test/journal/test_JournalTrimmer.cc
index 896f80c..9a9291f 100644
--- a/src/test/journal/test_JournalTrimmer.cc
+++ b/src/test/journal/test_JournalTrimmer.cc
@@ -16,6 +16,8 @@ public:
          it != m_metadata_list.end(); ++it) {
       (*it)->remove_listener(&m_listener);
     }
+    m_metadata_list.clear();
+
     for (std::list<journal::JournalTrimmer*>::iterator it = m_trimmers.begin();
          it != m_trimmers.end(); ++it) {
       delete *it;
@@ -34,14 +36,9 @@ public:
     return r;
   }
 
-  using RadosTestFixture::client_register;
-  int client_register(const std::string &oid) {
-    return RadosTestFixture::client_register(oid, "client", "");
-  }
-
   journal::JournalMetadataPtr create_metadata(const std::string &oid) {
-    journal::JournalMetadataPtr metadata(new journal::JournalMetadata(
-      m_ioctx, oid, "client", 0.1));
+    journal::JournalMetadataPtr metadata = RadosTestFixture::create_metadata(
+      oid);
     m_metadata_list.push_back(metadata);
     metadata->add_listener(&m_listener);
     return metadata;
@@ -85,10 +82,10 @@ TEST_F(TestJournalTrimmer, Committed) {
   uint64_t commit_tid5;
   uint64_t commit_tid6;
   ASSERT_EQ(0, append_payload(metadata, oid, 0, "payload", &commit_tid1));
-  ASSERT_EQ(0, append_payload(metadata, oid, 2, "payload", &commit_tid2));
+  ASSERT_EQ(0, append_payload(metadata, oid, 4, "payload", &commit_tid2));
   ASSERT_EQ(0, append_payload(metadata, oid, 5, "payload", &commit_tid3));
   ASSERT_EQ(0, append_payload(metadata, oid, 0, "payload", &commit_tid4));
-  ASSERT_EQ(0, append_payload(metadata, oid, 2, "payload", &commit_tid5));
+  ASSERT_EQ(0, append_payload(metadata, oid, 4, "payload", &commit_tid5));
   ASSERT_EQ(0, append_payload(metadata, oid, 5, "payload", &commit_tid6));
 
   journal::JournalTrimmer *trimmer = create_trimmer(oid, metadata);
diff --git a/src/test/journal/test_Journaler.cc b/src/test/journal/test_Journaler.cc
index 1d45bdc..df029a5 100644
--- a/src/test/journal/test_Journaler.cc
+++ b/src/test/journal/test_Journaler.cc
@@ -20,7 +20,8 @@ public:
   virtual void SetUp() {
     RadosTestFixture::SetUp();
     m_journal_id = get_temp_journal_id();
-    m_journaler = new journal::Journaler(m_ioctx, m_journal_id, CLIENT_ID, 5);
+    m_journaler = new journal::Journaler(m_work_queue, m_timer, &m_timer_lock,
+                                         m_ioctx, m_journal_id, CLIENT_ID, 5);
   }
 
   virtual void TearDown() {
@@ -39,10 +40,31 @@ public:
   }
 
   int register_client(const std::string &client_id, const std::string &desc) {
-    journal::Journaler journaler(m_ioctx, m_journal_id, client_id, 5);
+    journal::Journaler journaler(m_work_queue, m_timer, &m_timer_lock,
+                                 m_ioctx, m_journal_id, client_id, 5);
     bufferlist data;
     data.append(desc);
-    return journaler.register_client(data);
+    C_SaferCond cond;
+    journaler.register_client(data, &cond);
+    return cond.wait();
+  }
+
+  int update_client(const std::string &client_id, const std::string &desc) {
+    journal::Journaler journaler(m_work_queue, m_timer, &m_timer_lock,
+                                 m_ioctx, m_journal_id, client_id, 5);
+    bufferlist data;
+    data.append(desc);
+    C_SaferCond cond;
+    journaler.update_client(data, &cond);
+    return cond.wait();
+  }
+
+  int unregister_client(const std::string &client_id) {
+    journal::Journaler journaler(m_work_queue, m_timer, &m_timer_lock,
+                                 m_ioctx, m_journal_id, client_id, 5);
+    C_SaferCond cond;
+    journaler.unregister_client(&cond);
+    return cond.wait();
   }
 
   static uint64_t _journal_id;
@@ -80,10 +102,36 @@ TEST_F(TestJournaler, InitDNE) {
 }
 
 TEST_F(TestJournaler, RegisterClientDuplicate) {
+  ASSERT_EQ(0, create_journal(12, 8));
   ASSERT_EQ(0, register_client(CLIENT_ID, "foo"));
   ASSERT_EQ(-EEXIST, register_client(CLIENT_ID, "foo2"));
 }
 
+TEST_F(TestJournaler, UpdateClient) {
+  ASSERT_EQ(0, create_journal(12, 8));
+  ASSERT_EQ(0, register_client(CLIENT_ID, "foo"));
+  ASSERT_EQ(0, update_client(CLIENT_ID, "foo2"));
+}
+
+TEST_F(TestJournaler, UpdateClientDNE) {
+  ASSERT_EQ(0, create_journal(12, 8));
+  ASSERT_EQ(-ENOENT, update_client(CLIENT_ID, "foo"));
+}
+
+TEST_F(TestJournaler, UnregisterClient) {
+  ASSERT_EQ(0, create_journal(12, 8));
+  ASSERT_EQ(0, register_client(CLIENT_ID, "foo"));
+  ASSERT_EQ(0, unregister_client(CLIENT_ID));
+  // Test it does not exist and can be registered again
+  ASSERT_EQ(-ENOENT, update_client(CLIENT_ID, "foo"));
+  ASSERT_EQ(0, register_client(CLIENT_ID, "foo"));
+}
+
+TEST_F(TestJournaler, UnregisterClientDNE) {
+  ASSERT_EQ(0, create_journal(12, 8));
+  ASSERT_EQ(-ENOENT, unregister_client(CLIENT_ID));
+}
+
 TEST_F(TestJournaler, AllocateTag) {
   ASSERT_EQ(0, create_journal(12, 8));
 
diff --git a/src/test/journal/test_ObjectPlayer.cc b/src/test/journal/test_ObjectPlayer.cc
index 86bf3ca..6103ee6 100644
--- a/src/test/journal/test_ObjectPlayer.cc
+++ b/src/test/journal/test_ObjectPlayer.cc
@@ -141,7 +141,7 @@ TEST_F(TestObjectPlayer, FetchCorrupt) {
 
   C_SaferCond cond;
   object->fetch(&cond);
-  ASSERT_EQ(-EINVAL, cond.wait());
+  ASSERT_EQ(-EBADMSG, cond.wait());
 
   journal::ObjectPlayer::Entries entries;
   object->get_entries(&entries);
@@ -267,7 +267,7 @@ TEST_F(TestObjectPlayer, Unwatch) {
   bool done = false;
   int rval = 0;
   C_SafeCond *ctx = new C_SafeCond(&mutex, &cond, &done, &rval);
-  object->watch(ctx, 0.1);
+  object->watch(ctx, 600);
 
   usleep(200000);
   ASSERT_FALSE(done);
diff --git a/src/test/journal/test_ObjectRecorder.cc b/src/test/journal/test_ObjectRecorder.cc
index 9d3d0e5..65d74b6 100644
--- a/src/test/journal/test_ObjectRecorder.cc
+++ b/src/test/journal/test_ObjectRecorder.cc
@@ -3,7 +3,6 @@
 
 #include "journal/ObjectRecorder.h"
 #include "common/Cond.h"
-#include "common/Finisher.h"
 #include "common/Mutex.h"
 #include "common/Timer.h"
 #include "gtest/gtest.h"
@@ -16,16 +15,10 @@ public:
   TestObjectRecorder()
     : m_flush_interval(std::numeric_limits<uint32_t>::max()),
       m_flush_bytes(std::numeric_limits<uint64_t>::max()),
-      m_flush_age(600),
-      m_finisher(NULL)
+      m_flush_age(600)
   {
   }
 
-  ~TestObjectRecorder() {
-    m_finisher->stop();
-    delete m_finisher;
-  }
-
   struct OverflowHandler : public journal::ObjectRecorder::OverflowHandler {
     Mutex lock;
     Cond cond;
@@ -52,14 +45,6 @@ public:
   double m_flush_age;
   OverflowHandler m_overflow_handler;
 
-  Finisher *m_finisher;
-
-  void SetUp() {
-    RadosTestFixture::SetUp();
-    m_finisher = new Finisher(reinterpret_cast<CephContext*>(m_ioctx.cct()));
-    m_finisher->start();
-  }
-
   void TearDown() {
     for (ObjectRecorders::iterator it = m_object_recorders.begin();
          it != m_object_recorders.end(); ++it) {
@@ -67,6 +52,8 @@ public:
       (*it)->flush(&cond);
       cond.wait();
     }
+    m_object_recorders.clear();
+
     RadosTestFixture::TearDown();
   }
 
@@ -80,10 +67,11 @@ public:
     m_flush_age = i;
   }
 
-  journal::AppendBuffer create_append_buffer(uint64_t tag_tid, uint64_t entry_tid,
+  journal::AppendBuffer create_append_buffer(journal::JournalMetadataPtr metadata,
+                                             uint64_t tag_tid, uint64_t entry_tid,
                                              const std::string &payload) {
-    journal::FutureImplPtr future(new journal::FutureImpl(*m_finisher,
-                                                          tag_tid, entry_tid, 456));
+    journal::FutureImplPtr future(new journal::FutureImpl(metadata, tag_tid,
+                                                          entry_tid, 456));
     future->init(journal::FutureImplPtr());
 
     bufferlist bl;
@@ -103,18 +91,24 @@ public:
 
 TEST_F(TestObjectRecorder, Append) {
   std::string oid = get_temp_oid();
+  ASSERT_EQ(0, create(oid));
+  ASSERT_EQ(0, client_register(oid));
+  journal::JournalMetadataPtr metadata = create_metadata(oid);
+  ASSERT_EQ(0, init_metadata(metadata));
 
   journal::ObjectRecorderPtr object = create_object(oid, 24);
 
-  journal::AppendBuffer append_buffer1 = create_append_buffer(234, 123,
-                                                             "payload");
+  journal::AppendBuffer append_buffer1 = create_append_buffer(metadata,
+                                                              234, 123,
+                                                              "payload");
   journal::AppendBuffers append_buffers;
   append_buffers = {append_buffer1};
   ASSERT_FALSE(object->append(append_buffers));
   ASSERT_EQ(1U, object->get_pending_appends());
 
-  journal::AppendBuffer append_buffer2 = create_append_buffer(234, 124,
-                                                             "payload");
+  journal::AppendBuffer append_buffer2 = create_append_buffer(metadata,
+                                                              234, 124,
+                                                              "payload");
   append_buffers = {append_buffer2};
   ASSERT_FALSE(object->append(append_buffers));
   ASSERT_EQ(2U, object->get_pending_appends());
@@ -127,19 +121,25 @@ TEST_F(TestObjectRecorder, Append) {
 
 TEST_F(TestObjectRecorder, AppendFlushByCount) {
   std::string oid = get_temp_oid();
+  ASSERT_EQ(0, create(oid));
+  ASSERT_EQ(0, client_register(oid));
+  journal::JournalMetadataPtr metadata = create_metadata(oid);
+  ASSERT_EQ(0, init_metadata(metadata));
 
   set_flush_interval(2);
   journal::ObjectRecorderPtr object = create_object(oid, 24);
 
-  journal::AppendBuffer append_buffer1 = create_append_buffer(234, 123,
-                                                             "payload");
+  journal::AppendBuffer append_buffer1 = create_append_buffer(metadata,
+                                                              234, 123,
+                                                              "payload");
   journal::AppendBuffers append_buffers;
   append_buffers = {append_buffer1};
   ASSERT_FALSE(object->append(append_buffers));
   ASSERT_EQ(1U, object->get_pending_appends());
 
-  journal::AppendBuffer append_buffer2 = create_append_buffer(234, 124,
-                                                             "payload");
+  journal::AppendBuffer append_buffer2 = create_append_buffer(metadata,
+                                                              234, 124,
+                                                              "payload");
   append_buffers = {append_buffer2};
   ASSERT_FALSE(object->append(append_buffers));
   ASSERT_EQ(0U, object->get_pending_appends());
@@ -151,19 +151,25 @@ TEST_F(TestObjectRecorder, AppendFlushByCount) {
 
 TEST_F(TestObjectRecorder, AppendFlushByBytes) {
   std::string oid = get_temp_oid();
+  ASSERT_EQ(0, create(oid));
+  ASSERT_EQ(0, client_register(oid));
+  journal::JournalMetadataPtr metadata = create_metadata(oid);
+  ASSERT_EQ(0, init_metadata(metadata));
 
   set_flush_bytes(10);
   journal::ObjectRecorderPtr object = create_object(oid, 24);
 
-  journal::AppendBuffer append_buffer1 = create_append_buffer(234, 123,
-                                                             "payload");
+  journal::AppendBuffer append_buffer1 = create_append_buffer(metadata,
+                                                              234, 123,
+                                                              "payload");
   journal::AppendBuffers append_buffers;
   append_buffers = {append_buffer1};
   ASSERT_FALSE(object->append(append_buffers));
   ASSERT_EQ(1U, object->get_pending_appends());
 
-  journal::AppendBuffer append_buffer2 = create_append_buffer(234, 124,
-                                                             "payload");
+  journal::AppendBuffer append_buffer2 = create_append_buffer(metadata,
+                                                              234, 124,
+                                                              "payload");
   append_buffers = {append_buffer2};
   ASSERT_FALSE(object->append(append_buffers));
   ASSERT_EQ(0U, object->get_pending_appends());
@@ -175,18 +181,24 @@ TEST_F(TestObjectRecorder, AppendFlushByBytes) {
 
 TEST_F(TestObjectRecorder, AppendFlushByAge) {
   std::string oid = get_temp_oid();
+  ASSERT_EQ(0, create(oid));
+  ASSERT_EQ(0, client_register(oid));
+  journal::JournalMetadataPtr metadata = create_metadata(oid);
+  ASSERT_EQ(0, init_metadata(metadata));
 
   set_flush_age(0.1);
   journal::ObjectRecorderPtr object = create_object(oid, 24);
 
-  journal::AppendBuffer append_buffer1 = create_append_buffer(234, 123,
-                                                             "payload");
+  journal::AppendBuffer append_buffer1 = create_append_buffer(metadata,
+                                                              234, 123,
+                                                              "payload");
   journal::AppendBuffers append_buffers;
   append_buffers = {append_buffer1};
   ASSERT_FALSE(object->append(append_buffers));
 
-  journal::AppendBuffer append_buffer2 = create_append_buffer(234, 124,
-                                                             "payload");
+  journal::AppendBuffer append_buffer2 = create_append_buffer(metadata,
+                                                              234, 124,
+                                                              "payload");
   append_buffers = {append_buffer2};
   ASSERT_FALSE(object->append(append_buffers));
 
@@ -198,17 +210,23 @@ TEST_F(TestObjectRecorder, AppendFlushByAge) {
 
 TEST_F(TestObjectRecorder, AppendFilledObject) {
   std::string oid = get_temp_oid();
+  ASSERT_EQ(0, create(oid));
+  ASSERT_EQ(0, client_register(oid));
+  journal::JournalMetadataPtr metadata = create_metadata(oid);
+  ASSERT_EQ(0, init_metadata(metadata));
 
   journal::ObjectRecorderPtr object = create_object(oid, 12);
 
   std::string payload(2048, '1');
-  journal::AppendBuffer append_buffer1 = create_append_buffer(234, 123,
+  journal::AppendBuffer append_buffer1 = create_append_buffer(metadata,
+                                                              234, 123,
                                                               payload);
   journal::AppendBuffers append_buffers;
   append_buffers = {append_buffer1};
   ASSERT_FALSE(object->append(append_buffers));
 
-  journal::AppendBuffer append_buffer2 = create_append_buffer(234, 124,
+  journal::AppendBuffer append_buffer2 = create_append_buffer(metadata,
+                                                              234, 124,
                                                               payload);
   append_buffers = {append_buffer2};
   ASSERT_TRUE(object->append(append_buffers));
@@ -221,11 +239,16 @@ TEST_F(TestObjectRecorder, AppendFilledObject) {
 
 TEST_F(TestObjectRecorder, Flush) {
   std::string oid = get_temp_oid();
+  ASSERT_EQ(0, create(oid));
+  ASSERT_EQ(0, client_register(oid));
+  journal::JournalMetadataPtr metadata = create_metadata(oid);
+  ASSERT_EQ(0, init_metadata(metadata));
 
   journal::ObjectRecorderPtr object = create_object(oid, 24);
 
-  journal::AppendBuffer append_buffer1 = create_append_buffer(234, 123,
-                                                             "payload");
+  journal::AppendBuffer append_buffer1 = create_append_buffer(metadata,
+                                                              234, 123,
+                                                              "payload");
   journal::AppendBuffers append_buffers;
   append_buffers = {append_buffer1};
   ASSERT_FALSE(object->append(append_buffers));
@@ -243,10 +266,15 @@ TEST_F(TestObjectRecorder, Flush) {
 
 TEST_F(TestObjectRecorder, FlushFuture) {
   std::string oid = get_temp_oid();
+  ASSERT_EQ(0, create(oid));
+  ASSERT_EQ(0, client_register(oid));
+  journal::JournalMetadataPtr metadata = create_metadata(oid);
+  ASSERT_EQ(0, init_metadata(metadata));
 
   journal::ObjectRecorderPtr object = create_object(oid, 24);
 
-  journal::AppendBuffer append_buffer = create_append_buffer(234, 123,
+  journal::AppendBuffer append_buffer = create_append_buffer(metadata,
+                                                             234, 123,
                                                              "payload");
   journal::AppendBuffers append_buffers;
   append_buffers = {append_buffer};
@@ -263,10 +291,15 @@ TEST_F(TestObjectRecorder, FlushFuture) {
 
 TEST_F(TestObjectRecorder, FlushDetachedFuture) {
   std::string oid = get_temp_oid();
+  ASSERT_EQ(0, create(oid));
+  ASSERT_EQ(0, client_register(oid));
+  journal::JournalMetadataPtr metadata = create_metadata(oid);
+  ASSERT_EQ(0, init_metadata(metadata));
 
   journal::ObjectRecorderPtr object = create_object(oid, 24);
 
-  journal::AppendBuffer append_buffer = create_append_buffer(234, 123,
+  journal::AppendBuffer append_buffer = create_append_buffer(metadata,
+                                                             234, 123,
                                                              "payload");
 
   journal::AppendBuffers append_buffers;
@@ -284,14 +317,20 @@ TEST_F(TestObjectRecorder, FlushDetachedFuture) {
 
 TEST_F(TestObjectRecorder, Overflow) {
   std::string oid = get_temp_oid();
+  ASSERT_EQ(0, create(oid));
+  ASSERT_EQ(0, client_register(oid));
+  journal::JournalMetadataPtr metadata = create_metadata(oid);
+  ASSERT_EQ(0, init_metadata(metadata));
 
   journal::ObjectRecorderPtr object1 = create_object(oid, 12);
   journal::ObjectRecorderPtr object2 = create_object(oid, 12);
 
   std::string payload(2048, '1');
-  journal::AppendBuffer append_buffer1 = create_append_buffer(234, 123,
+  journal::AppendBuffer append_buffer1 = create_append_buffer(metadata,
+                                                              234, 123,
                                                               payload);
-  journal::AppendBuffer append_buffer2 = create_append_buffer(234, 124,
+  journal::AppendBuffer append_buffer2 = create_append_buffer(metadata,
+                                                              234, 124,
                                                               payload);
   journal::AppendBuffers append_buffers;
   append_buffers = {append_buffer1, append_buffer2};
@@ -302,7 +341,8 @@ TEST_F(TestObjectRecorder, Overflow) {
   ASSERT_EQ(0, cond.wait());
   ASSERT_EQ(0U, object1->get_pending_appends());
 
-  journal::AppendBuffer append_buffer3 = create_append_buffer(456, 123,
+  journal::AppendBuffer append_buffer3 = create_append_buffer(metadata,
+                                                              456, 123,
                                                               payload);
   append_buffers = {append_buffer3};
 
diff --git a/src/test/libcephfs/test.cc b/src/test/libcephfs/test.cc
index 139c7f3..06061a6 100644
--- a/src/test/libcephfs/test.cc
+++ b/src/test/libcephfs/test.cc
@@ -81,20 +81,20 @@ TEST(LibCephFS, OpenReadWrite) {
   const char *out_buf = "hello world";
   size_t size = strlen(out_buf);
   char in_buf[100];
-  ASSERT_EQ(ceph_write(cmount, fd, out_buf, size, 0), size);
+  ASSERT_EQ(ceph_write(cmount, fd, out_buf, size, 0), (int)size);
   ASSERT_EQ(ceph_read(cmount, fd, in_buf, sizeof(in_buf), 0), -EBADF);
   ASSERT_EQ(0, ceph_close(cmount, fd));
 
   fd = ceph_open(cmount, c_path, O_RDONLY, 0);
   ASSERT_LT(0, fd);
   ASSERT_EQ(ceph_write(cmount, fd, out_buf, size, 0), -EBADF);
-  ASSERT_EQ(ceph_read(cmount, fd, in_buf, sizeof(in_buf), 0), size);
+  ASSERT_EQ(ceph_read(cmount, fd, in_buf, sizeof(in_buf), 0), (int)size);
   ASSERT_EQ(0, ceph_close(cmount, fd));
 
   fd = ceph_open(cmount, c_path, O_RDWR, 0);
   ASSERT_LT(0, fd);
-  ASSERT_EQ(ceph_write(cmount, fd, out_buf, size, 0), size);
-  ASSERT_EQ(ceph_read(cmount, fd, in_buf, sizeof(in_buf), 0), size);
+  ASSERT_EQ(ceph_write(cmount, fd, out_buf, size, 0), (int)size);
+  ASSERT_EQ(ceph_read(cmount, fd, in_buf, sizeof(in_buf), 0), (int)size);
   ASSERT_EQ(0, ceph_close(cmount, fd));
 
   ceph_shutdown(cmount);
@@ -356,7 +356,7 @@ TEST(LibCephFS, DirLs) {
       found.insert(name);
     }
   }
-  ASSERT_EQ(found.size(), r);
+  ASSERT_EQ(found.size(), (unsigned)r);
   free(getdents_entries);
 
   // test readdir_r
@@ -378,7 +378,7 @@ TEST(LibCephFS, DirLs) {
     ASSERT_EQ(len, 1);
     found.insert(rdent.d_name);
   }
-  ASSERT_EQ(found.size(), r);
+  ASSERT_EQ(found.size(), (unsigned)r);
 
   // test readdirplus
   ceph_rewinddir(cmount, ls_dir);
@@ -407,7 +407,7 @@ TEST(LibCephFS, DirLs) {
     ASSERT_EQ(st.st_ino, rdent.d_ino);
     //ASSERT_EQ(st.st_mode, (mode_t)0666);
   }
-  ASSERT_EQ(found.size(), r);
+  ASSERT_EQ(found.size(), (unsigned)r);
 
   ASSERT_EQ(ceph_closedir(cmount, ls_dir), 0);
 
@@ -1321,3 +1321,26 @@ TEST(LibCephFS, GetOsdAddr) {
 
   ceph_shutdown(cmount);
 }
+
+TEST(LibCephFS, OpenNoClose) {
+  struct ceph_mount_info *cmount;
+  ASSERT_EQ(ceph_create(&cmount, NULL), 0);
+  ASSERT_EQ(ceph_conf_read_file(cmount, NULL), 0);
+  ASSERT_EQ(0, ceph_conf_parse_env(cmount, NULL));
+  ASSERT_EQ(ceph_mount(cmount, "/"), 0);
+
+  pid_t mypid = getpid();
+  char str_buf[256];
+  sprintf(str_buf, "open_no_close_dir%d", mypid);
+  ASSERT_EQ(0, ceph_mkdirs(cmount, str_buf, 0777));
+
+  struct ceph_dir_result *ls_dir = NULL;
+  ASSERT_EQ(ceph_opendir(cmount, str_buf, &ls_dir), 0);
+
+  sprintf(str_buf, "open_no_close_file%d", mypid);
+  int fd = ceph_open(cmount, str_buf, O_RDONLY|O_CREAT, 0666);
+  ASSERT_LT(0, fd);
+
+  // shutdown should force close opened file/dir
+  ceph_shutdown(cmount);
+}
diff --git a/src/test/librados/list.cc b/src/test/librados/list.cc
index 39b02b5..b7f0253 100644
--- a/src/test/librados/list.cc
+++ b/src/test/librados/list.cc
@@ -693,7 +693,7 @@ TEST_F(LibRadosList, EnumerateObjects) {
     memset(results, 0, sizeof(rados_object_list_item) * 12);
     int r = rados_object_list(ioctx,
             c, rados_object_list_end(ioctx),
-            12, results, &c);
+            12, NULL, 0, results, &c);
     ASSERT_GE(r, 0);
     for (int i = 0; i < r; ++i) {
       std::string oid(results[i].oid, results[i].oid_length);
@@ -761,7 +761,7 @@ TEST_F(LibRadosList, EnumerateObjectsSplit) {
         memset(results, 0, sizeof(rados_object_list_item) * 12);
         int r = rados_object_list(ioctx,
                 c, shard_end,
-                12, results, &c);
+                12, NULL, 0, results, &c);
         ASSERT_GE(r, 0);
         for (int i = 0; i < r; ++i) {
           std::string oid(results[i].oid, results[i].oid_length);
@@ -806,7 +806,7 @@ TEST_F(LibRadosListPP, EnumerateObjectsPP) {
   while(!ioctx.object_list_is_end(c))
   {
     std::vector<ObjectItem> result;
-    int r = ioctx.object_list(c, end, 12, &result, &c);
+    int r = ioctx.object_list(c, end, 12, {}, &result, &c);
     ASSERT_GE(r, 0);
     ASSERT_EQ(r, (int)result.size());
     for (int i = 0; i < r; ++i) {
@@ -861,7 +861,7 @@ TEST_F(LibRadosListPP, EnumerateObjectsSplitPP) {
       while(c < shard_end)
       {
         std::vector<ObjectItem> result;
-        int r = ioctx.object_list(c, shard_end, 12, &result, &c);
+        int r = ioctx.object_list(c, shard_end, 12, {}, &result, &c);
         ASSERT_GE(r, 0);
 
         for (const auto & i : result) {
@@ -906,5 +906,53 @@ TEST_F(LibRadosListNP, ListObjectsError) {
   rados_shutdown(cluster);
 }
 
+TEST_F(LibRadosListPP, EnumerateObjectsFilterPP) {
+  char buf[128];
+  memset(buf, 0xcc, sizeof(buf));
+  bufferlist obj_content;
+  obj_content.append(buf, sizeof(buf));
+
+  std::string target_str = "content";
+
+  // Write xattr bare, no ::encod'ing
+  bufferlist target_val;
+  target_val.append(target_str);
+  bufferlist nontarget_val;
+  nontarget_val.append("rhubarb");
+
+  ASSERT_EQ(0, ioctx.write("has_xattr", obj_content, obj_content.length(), 0));
+  ASSERT_EQ(0, ioctx.write("has_wrong_xattr", obj_content, obj_content.length(), 0));
+  ASSERT_EQ(0, ioctx.write("no_xattr", obj_content, obj_content.length(), 0));
+
+  ASSERT_EQ(0, ioctx.setxattr("has_xattr", "theattr", target_val));
+  ASSERT_EQ(0, ioctx.setxattr("has_wrong_xattr", "theattr", nontarget_val));
+
+  bufferlist filter_bl;
+  std::string filter_name = "plain";
+  ::encode(filter_name, filter_bl);
+  ::encode("_theattr", filter_bl);
+  ::encode(target_str, filter_bl);
+
+  ObjectCursor c = ioctx.object_list_begin();
+  ObjectCursor end = ioctx.object_list_end();
+  bool foundit = false;
+  while(!ioctx.object_list_is_end(c))
+  {
+    std::vector<ObjectItem> result;
+    int r = ioctx.object_list(c, end, 12, filter_bl, &result, &c);
+    ASSERT_GE(r, 0);
+    ASSERT_EQ(r, (int)result.size());
+    for (int i = 0; i < r; ++i) {
+      auto oid = result[i].oid;
+      // We should only see the object that matches the filter
+      ASSERT_EQ(oid, "has_xattr");
+      // We should only see it once
+      ASSERT_FALSE(foundit);
+      foundit = true;
+    }
+  }
+  ASSERT_TRUE(foundit);
+}
+
 #pragma GCC diagnostic pop
 #pragma GCC diagnostic warning "-Wpragmas"
diff --git a/src/test/librados/misc.cc b/src/test/librados/misc.cc
index 0fb67e0..9cc7f22 100644
--- a/src/test/librados/misc.cc
+++ b/src/test/librados/misc.cc
@@ -38,6 +38,16 @@ TEST(LibRadosMiscVersion, VersionPP) {
   Rados::version(&major, &minor, &extra);
 }
 
+static void test_rados_log_cb(void *arg,
+                              const char *line,
+                              const char *who,
+                              uint64_t sec, uint64_t nsec,
+                              uint64_t seq, const char *level,
+                              const char *msg)
+{
+    std::cerr << "monitor log callback invoked" << std::endl;
+}
+
 TEST(LibRadosMiscConnectFailure, ConnectFailure) {
   rados_t cluster;
 
@@ -49,7 +59,10 @@ TEST(LibRadosMiscConnectFailure, ConnectFailure) {
   ASSERT_EQ(0, rados_conf_read_file(cluster, NULL));
   ASSERT_EQ(0, rados_conf_parse_env(cluster, NULL));
 
-  ASSERT_EQ(0, rados_conf_set(cluster, "client_mount_timeout", "0.000001"));
+  ASSERT_EQ(0, rados_conf_set(cluster, "client_mount_timeout", "0.000000001"));
+
+  ASSERT_EQ(-ENOTCONN, rados_monitor_log(cluster, "error",
+                                         test_rados_log_cb, NULL));
 
   ASSERT_NE(0, rados_connect(cluster));
   ASSERT_NE(0, rados_connect(cluster));
diff --git a/src/test/librados/stat.cc b/src/test/librados/stat.cc
index 5757b30..9641bb8 100644
--- a/src/test/librados/stat.cc
+++ b/src/test/librados/stat.cc
@@ -3,6 +3,8 @@
 #include "test/librados/test.h"
 #include "test/librados/TestCase.h"
 
+#include "common/ceph_time.h"
+
 #include <algorithm>
 #include <errno.h>
 #include "gtest/gtest.h"
@@ -38,6 +40,36 @@ TEST_F(LibRadosStatPP, StatPP) {
   ASSERT_EQ(-ENOENT, ioctx.stat("nonexistent", &size, &mtime));
 }
 
+TEST_F(LibRadosStatPP, Stat2Mtime2PP) {
+  char buf[128];
+  memset(buf, 0xcc, sizeof(buf));
+  bufferlist bl;
+  bl.append(buf, sizeof(buf));
+  librados::ObjectWriteOperation op;
+  struct timespec ts;
+  ts.tv_sec = 1457129052;
+  ts.tv_nsec = 123456789;
+  op.mtime2(&ts);
+  op.write(0, bl);
+  ASSERT_EQ(0, ioctx.operate("foo", &op));
+
+  /* XXX time comparison asserts could spuriously fail */
+
+  uint64_t size;
+  time_t mtime;
+  ASSERT_EQ(0, ioctx.stat("foo", &size, &mtime));
+  ASSERT_EQ(sizeof(buf), size);
+  ASSERT_EQ(mtime, ts.tv_sec);
+
+  struct timespec ts2;
+  ASSERT_EQ(0, ioctx.stat2("foo", &size, &ts2));
+  ASSERT_EQ(sizeof(buf), size);
+  ASSERT_EQ(ts2.tv_sec, ts.tv_sec);
+  ASSERT_EQ(ts2.tv_nsec, ts.tv_nsec);
+
+  ASSERT_EQ(-ENOENT, ioctx.stat2("nonexistent", &size, &ts2));
+}
+
 TEST_F(LibRadosStat, StatNS) {
   char buf[128];
   memset(buf, 0xcc, sizeof(buf));
diff --git a/src/test/librados/test.cc b/src/test/librados/test.cc
index 5f3ff2d..e09bee1 100644
--- a/src/test/librados/test.cc
+++ b/src/test/librados/test.cc
@@ -20,7 +20,7 @@
 
 using namespace librados;
 
-std::string get_temp_pool_name()
+std::string get_temp_pool_name(const std::string &prefix)
 {
   char hostname[80];
   char out[80];
@@ -30,9 +30,7 @@ std::string get_temp_pool_name()
   static int num = 1;
   sprintf(out, "%s-%d-%d", hostname, getpid(), num);
   num++;
-  std::string prefix("test-rados-api-");
-  prefix += out;
-  return prefix;
+  return prefix + out;
 }
 
 int wait_for_healthy(rados_t *cluster)
diff --git a/src/test/librados/test.h b/src/test/librados/test.h
index c5f948c..1d13d81 100644
--- a/src/test/librados/test.h
+++ b/src/test/librados/test.h
@@ -22,7 +22,7 @@
 #include <string>
 #include <unistd.h>
 
-std::string get_temp_pool_name();
+std::string get_temp_pool_name(const std::string &prefix = "test-rados-api-");
 
 std::string create_one_pool(const std::string &pool_name, rados_t *cluster,
     uint32_t pg_num=0);
diff --git a/src/test/librados/tier.cc b/src/test/librados/tier.cc
index 3c57c7f..38bace6 100755
--- a/src/test/librados/tier.cc
+++ b/src/test/librados/tier.cc
@@ -3762,6 +3762,143 @@ TEST_F(LibRadosTwoPoolsECPP, TryFlush) {
   }
 }
 
+TEST_F(LibRadosTwoPoolsECPP, FailedFlush) {
+  // configure cache
+  bufferlist inbl;
+  ASSERT_EQ(0, cluster.mon_command(
+    "{\"prefix\": \"osd tier add\", \"pool\": \"" + pool_name +
+    "\", \"tierpool\": \"" + cache_pool_name +
+    "\", \"force_nonempty\": \"--force-nonempty\" }",
+    inbl, NULL, NULL));
+  ASSERT_EQ(0, cluster.mon_command(
+    "{\"prefix\": \"osd tier set-overlay\", \"pool\": \"" + pool_name +
+    "\", \"overlaypool\": \"" + cache_pool_name + "\"}",
+    inbl, NULL, NULL));
+  ASSERT_EQ(0, cluster.mon_command(
+    "{\"prefix\": \"osd tier cache-mode\", \"pool\": \"" + cache_pool_name +
+    "\", \"mode\": \"writeback\"}",
+    inbl, NULL, NULL));
+
+  // wait for maps to settle
+  cluster.wait_for_latest_osdmap();
+
+  // create object
+  {
+    bufferlist bl;
+    bl.append("hi there");
+    ObjectWriteOperation op;
+    op.write_full(bl);
+    ASSERT_EQ(0, ioctx.operate("foo", &op));
+  }
+
+  // verify the object is present in the cache tier
+  {
+    NObjectIterator it = cache_ioctx.nobjects_begin();
+    ASSERT_TRUE(it != cache_ioctx.nobjects_end());
+    ASSERT_TRUE(it->get_oid() == string("foo"));
+    ++it;
+    ASSERT_TRUE(it == cache_ioctx.nobjects_end());
+  }
+
+  // verify the object is NOT present in the base tier
+  {
+    NObjectIterator it = ioctx.nobjects_begin();
+    ASSERT_TRUE(it == ioctx.nobjects_end());
+  }
+
+  // set omap
+  {
+    ObjectWriteOperation op;
+    std::map<std::string, bufferlist> omap;
+    omap["somekey"] = bufferlist();
+    op.omap_set(omap);
+    librados::AioCompletion *completion = cluster.aio_create_completion();
+    ASSERT_EQ(0, cache_ioctx.aio_operate("foo", completion, &op));
+    completion->wait_for_safe();
+    ASSERT_EQ(0, completion->get_return_value());
+    completion->release();
+  }
+
+  // flush
+  {
+    ObjectReadOperation op;
+    op.cache_flush();
+    librados::AioCompletion *completion = cluster.aio_create_completion();
+    ASSERT_EQ(0, cache_ioctx.aio_operate(
+      "foo", completion, &op,
+      librados::OPERATION_IGNORE_OVERLAY, NULL));
+    completion->wait_for_safe();
+    ASSERT_NE(0, completion->get_return_value());
+    completion->release();
+  }
+
+  // get omap
+  {
+    ObjectReadOperation op;
+    bufferlist bl;
+    int prval = 0;
+    std::set<std::string> keys;
+    keys.insert("somekey");
+    std::map<std::string, bufferlist> map;
+
+    op.omap_get_vals_by_keys(keys, &map, &prval);
+    librados::AioCompletion *completion = cluster.aio_create_completion();
+    ASSERT_EQ(0, cache_ioctx.aio_operate("foo", completion, &op, &bl));
+    sleep(5);
+    bool completed = completion->is_complete();
+    if( !completed ) {
+      cache_ioctx.aio_cancel(completion); 
+      std::cerr << "Most probably test case will hang here, please reset manually" << std::endl;
+      ASSERT_TRUE(completed); //in fact we are locked forever at test case shutdown unless fix for http://tracker.ceph.com/issues/14511 is applied. Seems there is no workaround for that
+    }
+    completion->release();
+  }
+  // verify still not in base tier
+  {
+    ASSERT_TRUE(ioctx.nobjects_begin() == ioctx.nobjects_end());
+  }
+  // erase it
+  {
+    ObjectWriteOperation op;
+    op.remove();
+    ASSERT_EQ(0, ioctx.operate("foo", &op));
+  }
+  // flush whiteout
+  {
+    ObjectReadOperation op;
+    op.cache_flush();
+    librados::AioCompletion *completion = cluster.aio_create_completion();
+    ASSERT_EQ(0, cache_ioctx.aio_operate(
+      "foo", completion, &op,
+      librados::OPERATION_IGNORE_OVERLAY, NULL));
+    completion->wait_for_safe();
+    ASSERT_EQ(0, completion->get_return_value());
+    completion->release();
+  }
+  // evict
+  {
+    ObjectReadOperation op;
+    op.cache_evict();
+    librados::AioCompletion *completion = cluster.aio_create_completion();
+    ASSERT_EQ(0, cache_ioctx.aio_operate(
+      "foo", completion, &op, librados::OPERATION_IGNORE_CACHE, NULL));
+    completion->wait_for_safe();
+    ASSERT_EQ(0, completion->get_return_value());
+    completion->release();
+  }
+
+  // verify no longer in cache tier
+  {
+    NObjectIterator it = cache_ioctx.nobjects_begin();
+    ASSERT_TRUE(it == cache_ioctx.nobjects_end());
+  }
+  // or base tier
+  {
+    NObjectIterator it = ioctx.nobjects_begin();
+    ASSERT_TRUE(it == ioctx.nobjects_end());
+  }
+}
+
 TEST_F(LibRadosTwoPoolsECPP, Flush) {
   // configure cache
   bufferlist inbl;
@@ -4500,6 +4637,122 @@ TEST_F(LibRadosTwoPoolsECPP, TryFlushReadRace) {
   test_lock.Unlock();
 }
 
+TEST_F(LibRadosTierECPP, CallForcesPromote) {
+  Rados cluster;
+  std::string pool_name = get_temp_pool_name();
+  std::string cache_pool_name = pool_name + "-cache";
+  ASSERT_EQ("", create_one_ec_pool_pp(pool_name, cluster));
+  ASSERT_EQ(0, cluster.pool_create(cache_pool_name.c_str()));
+  IoCtx cache_ioctx;
+  ASSERT_EQ(0, cluster.ioctx_create(cache_pool_name.c_str(), cache_ioctx));
+  IoCtx ioctx;
+  ASSERT_EQ(0, cluster.ioctx_create(pool_name.c_str(), ioctx));
+
+  // configure cache
+  bufferlist inbl;
+  ASSERT_EQ(0, cluster.mon_command(
+    "{\"prefix\": \"osd tier add\", \"pool\": \"" + pool_name +
+    "\", \"tierpool\": \"" + cache_pool_name + "\"}",
+    inbl, NULL, NULL));
+  ASSERT_EQ(0, cluster.mon_command(
+    "{\"prefix\": \"osd tier set-overlay\", \"pool\": \"" + pool_name +
+    "\", \"overlaypool\": \"" + cache_pool_name + "\"}",
+    inbl, NULL, NULL));
+  ASSERT_EQ(0, cluster.mon_command(
+    "{\"prefix\": \"osd tier cache-mode\", \"pool\": \"" + cache_pool_name +
+    "\", \"mode\": \"writeback\"}",
+    inbl, NULL, NULL));
+
+  // set things up such that the op would normally be proxied
+  ASSERT_EQ(0, cluster.mon_command(
+	      set_pool_str(cache_pool_name, "hit_set_count", 2),
+	      inbl, NULL, NULL));
+  ASSERT_EQ(0, cluster.mon_command(
+	      set_pool_str(cache_pool_name, "hit_set_period", 600),
+	      inbl, NULL, NULL));
+  ASSERT_EQ(0, cluster.mon_command(
+	      set_pool_str(cache_pool_name, "hit_set_type",
+			   "explicit_object"),
+	      inbl, NULL, NULL));
+  ASSERT_EQ(0, cluster.mon_command(
+	      set_pool_str(cache_pool_name, "min_read_recency_for_promote",
+			   "4"),
+	      inbl, NULL, NULL));
+
+  // wait for maps to settle
+  cluster.wait_for_latest_osdmap();
+
+  // create/dirty object
+  bufferlist bl;
+  bl.append("hi there");
+  {
+    ObjectWriteOperation op;
+    op.write_full(bl);
+    ASSERT_EQ(0, ioctx.operate("foo", &op));
+  }
+
+  // flush
+  {
+    ObjectReadOperation op;
+    op.cache_flush();
+    librados::AioCompletion *completion = cluster.aio_create_completion();
+    ASSERT_EQ(0, cache_ioctx.aio_operate(
+      "foo", completion, &op,
+      librados::OPERATION_IGNORE_OVERLAY, NULL));
+    completion->wait_for_safe();
+    ASSERT_EQ(0, completion->get_return_value());
+    completion->release();
+  }
+
+  // evict
+  {
+    ObjectReadOperation op;
+    op.cache_evict();
+    librados::AioCompletion *completion = cluster.aio_create_completion();
+    ASSERT_EQ(0, cache_ioctx.aio_operate("foo", completion, &op,
+					 librados::OPERATION_IGNORE_CACHE,
+					 NULL));
+    completion->wait_for_safe();
+    ASSERT_EQ(0, completion->get_return_value());
+    completion->release();
+  }
+
+  // call
+  {
+    ObjectReadOperation op;
+    bufferlist bl;
+    op.exec("rbd", "get_id", bl);
+    bufferlist out;
+    // should get EIO (not an rbd object), not -EOPNOTSUPP (we didn't promote)
+    ASSERT_EQ(-5, ioctx.operate("foo", &op, &out));
+  }
+
+  // make sure foo is back in the cache tier
+  {
+    NObjectIterator it = cache_ioctx.nobjects_begin();
+    ASSERT_TRUE(it != cache_ioctx.nobjects_end());
+    ASSERT_TRUE(it->get_oid() == string("foo"));
+    ++it;
+    ASSERT_TRUE(it == cache_ioctx.nobjects_end());
+  }
+
+  // tear down tiers
+  ASSERT_EQ(0, cluster.mon_command(
+    "{\"prefix\": \"osd tier remove-overlay\", \"pool\": \"" + pool_name +
+    "\"}",
+    inbl, NULL, NULL));
+  ASSERT_EQ(0, cluster.mon_command(
+    "{\"prefix\": \"osd tier remove\", \"pool\": \"" + pool_name +
+    "\", \"tierpool\": \"" + cache_pool_name + "\"}",
+    inbl, NULL, NULL));
+
+  // wait for maps to settle before next test
+  cluster.wait_for_latest_osdmap();
+
+  ASSERT_EQ(0, cluster.pool_delete(cache_pool_name.c_str()));
+  ASSERT_EQ(0, destroy_one_pool_pp(pool_name, cluster));
+}
+
 TEST_F(LibRadosTierECPP, HitSetNone) {
   {
     list< pair<time_t,time_t> > ls;
diff --git a/src/test/librados/tmap_migrate.cc b/src/test/librados/tmap_migrate.cc
new file mode 100644
index 0000000..98be69a
--- /dev/null
+++ b/src/test/librados/tmap_migrate.cc
@@ -0,0 +1,70 @@
+#include "include/rados/librados.h"
+#include "include/rados/librados.hpp"
+#include "test/librados/test.h"
+#include "test/librados/TestCase.h"
+#include "include/encoding.h"
+#include "tools/cephfs/DataScan.h"
+#include "global/global_init.h"
+
+#include <algorithm>
+#include <errno.h>
+#include "gtest/gtest.h"
+
+
+using namespace librados;
+
+typedef RadosTestPP TmapMigratePP;
+
+TEST_F(TmapMigratePP, DataScan) {
+  std::vector<const char *> args;
+  global_init(NULL, args, CEPH_ENTITY_TYPE_CLIENT, CODE_ENVIRONMENT_UTILITY, 0);
+  common_init_finish(g_ceph_context);
+
+  // DataScan isn't namespace-aware, so override RadosTestPP's default
+  // behaviour of putting everything into a namespace
+  ioctx.set_namespace("");
+
+  bufferlist header;
+  std::map<std::string, bufferlist> kvs;
+  bufferlist val;
+  val.append("custard");
+  kvs.insert({"rhubarb", val});
+
+  bufferlist tmap_trans;
+  ::encode(header, tmap_trans);
+  ::encode(kvs, tmap_trans);
+
+  // Create a TMAP object
+  ASSERT_EQ(0, ioctx.tmap_put("10000000000.00000000", tmap_trans));
+
+  // Create an OMAP object
+  std::map<std::string, bufferlist> omap_kvs;
+  bufferlist omap_val;
+  omap_val.append("waffles");
+  omap_kvs.insert({"tasty", omap_val});
+  ASSERT_EQ(0, ioctx.omap_set("10000000001.00000000", omap_kvs));
+
+  DataScan ds;
+  ASSERT_EQ(0, ds.init());
+  int r = ds.main({"tmap_upgrade", pool_name.c_str()});
+  ASSERT_EQ(r, 0);
+  ds.shutdown();
+
+  // Check that the TMAP object is now an omap object
+  std::map<std::string, bufferlist> read_vals;
+  ASSERT_EQ(0, ioctx.omap_get_vals("10000000000.00000000", "", 1, &read_vals));
+  ASSERT_EQ(read_vals.size(), 1u);
+  bufferlist tmap_expect_val;
+  tmap_expect_val.append("custard");
+  ASSERT_EQ(read_vals.at("rhubarb"), tmap_expect_val);
+
+
+  // Check that the OMAP object is still readable
+  read_vals.clear();
+  ASSERT_EQ(0, ioctx.omap_get_vals("10000000001.00000000", "", 1, &read_vals));
+  ASSERT_EQ(read_vals.size(), 1u);
+  bufferlist expect_omap_val;
+  expect_omap_val.append("waffles");
+  ASSERT_EQ(read_vals.at("tasty"), expect_omap_val);
+}
+
diff --git a/src/test/librados/watch_notify.cc b/src/test/librados/watch_notify.cc
index c191a38..dda8fec 100644
--- a/src/test/librados/watch_notify.cc
+++ b/src/test/librados/watch_notify.cc
@@ -247,6 +247,40 @@ TEST_F(LibRadosWatchNotify, Watch2Delete) {
   rados_unwatch2(ioctx, handle);
 }
 
+TEST_F(LibRadosWatchNotify, AioWatchDelete) {
+  notify_io = ioctx;
+  notify_oid = "foo";
+  notify_err = 0;
+  char buf[128];
+  memset(buf, 0xcc, sizeof(buf));
+  ASSERT_EQ(0, rados_write(ioctx, notify_oid, buf, sizeof(buf), 0));
+
+
+  rados_completion_t comp;
+  uint64_t handle;
+  ASSERT_EQ(0, rados_aio_create_completion(NULL, NULL, NULL, &comp));
+  rados_aio_watch(ioctx, notify_oid, comp, &handle,
+                  watch_notify2_test_cb, watch_notify2_test_errcb, NULL);
+  ASSERT_EQ(0, rados_aio_wait_for_complete(comp));
+  ASSERT_EQ(0, rados_aio_get_return_value(comp));
+  rados_aio_release(comp);
+  ASSERT_EQ(0, rados_remove(ioctx, notify_oid));
+  int left = 300;
+  std::cout << "waiting up to " << left << " for disconnect notification ..."
+	    << std::endl;
+  while (notify_err == 0 && --left) {
+    sleep(1);
+  }
+  ASSERT_TRUE(left > 0);
+  ASSERT_EQ(-ENOTCONN, notify_err);
+  ASSERT_EQ(-ENOTCONN, rados_watch_check(ioctx, handle));
+  ASSERT_EQ(0, rados_aio_create_completion(NULL, NULL, NULL, &comp));
+  rados_aio_unwatch(ioctx, handle, comp);
+  ASSERT_EQ(0, rados_aio_wait_for_complete(comp));
+  ASSERT_EQ(-ENOENT, rados_aio_get_return_value(comp));
+  rados_aio_release(comp);
+}
+
 TEST_F(LibRadosWatchNotify, Watch2Timeout) {
   notify_io = ioctx;
   notify_oid = "foo";
@@ -378,6 +412,60 @@ TEST_F(LibRadosWatchNotify, WatchNotify2) {
   rados_unwatch2(ioctx, handle);
 }
 
+TEST_F(LibRadosWatchNotify, AioWatchNotify2) {
+  notify_io = ioctx;
+  notify_oid = "foo";
+  notify_cookies.clear();
+  char buf[128];
+  memset(buf, 0xcc, sizeof(buf));
+  ASSERT_EQ(0, rados_write(ioctx, notify_oid, buf, sizeof(buf), 0));
+
+  rados_completion_t comp;
+  uint64_t handle;
+  ASSERT_EQ(0, rados_aio_create_completion(NULL, NULL, NULL, &comp));
+  rados_aio_watch(ioctx, notify_oid, comp, &handle,
+                  watch_notify2_test_cb, watch_notify2_test_errcb, NULL);
+  ASSERT_EQ(0, rados_aio_wait_for_complete(comp));
+  ASSERT_EQ(0, rados_aio_get_return_value(comp));
+  rados_aio_release(comp);
+
+  ASSERT_GT(rados_watch_check(ioctx, handle), 0);
+  char *reply_buf = 0;
+  size_t reply_buf_len;
+  ASSERT_EQ(0, rados_notify2(ioctx, notify_oid,
+			     "notify", 6, 300000,
+			     &reply_buf, &reply_buf_len));
+  bufferlist reply;
+  reply.append(reply_buf, reply_buf_len);
+  std::map<std::pair<uint64_t,uint64_t>, bufferlist> reply_map;
+  std::set<std::pair<uint64_t,uint64_t> > missed_map;
+  bufferlist::iterator reply_p = reply.begin();
+  ::decode(reply_map, reply_p);
+  ::decode(missed_map, reply_p);
+  ASSERT_EQ(1u, reply_map.size());
+  ASSERT_EQ(0u, missed_map.size());
+  ASSERT_EQ(1u, notify_cookies.size());
+  ASSERT_EQ(1u, notify_cookies.count(handle));
+  ASSERT_EQ(5u, reply_map.begin()->second.length());
+  ASSERT_EQ(0, strncmp("reply", reply_map.begin()->second.c_str(), 5));
+  ASSERT_GT(rados_watch_check(ioctx, handle), 0);
+  rados_buffer_free(reply_buf);
+
+  // try it on a non-existent object ... our buffer pointers
+  // should get zeroed.
+  ASSERT_EQ(-ENOENT, rados_notify2(ioctx, "doesnotexist",
+				   "notify", 6, 300000,
+				   &reply_buf, &reply_buf_len));
+  ASSERT_EQ((char*)0, reply_buf);
+  ASSERT_EQ(0u, reply_buf_len);
+
+  ASSERT_EQ(0, rados_aio_create_completion(NULL, NULL, NULL, &comp));
+  rados_aio_unwatch(ioctx, handle, comp);
+  ASSERT_EQ(0, rados_aio_wait_for_complete(comp));
+  ASSERT_EQ(0, rados_aio_get_return_value(comp));
+  rados_aio_release(comp);
+}
+
 TEST_F(LibRadosWatchNotify, AioNotify) {
   notify_io = ioctx;
   notify_oid = "foo";
@@ -464,6 +552,50 @@ TEST_P(LibRadosWatchNotifyPP, WatchNotify2) {
   ioctx.unwatch2(handle);
 }
 
+TEST_P(LibRadosWatchNotifyPP, AioWatchNotify2) {
+  notify_oid = "foo";
+  notify_ioctx = &ioctx;
+  notify_cookies.clear();
+  char buf[128];
+  memset(buf, 0xcc, sizeof(buf));
+  bufferlist bl1;
+  bl1.append(buf, sizeof(buf));
+  ASSERT_EQ(0, ioctx.write(notify_oid, bl1, sizeof(buf), 0));
+
+  uint64_t handle;
+  WatchNotifyTestCtx2 ctx;
+  librados::AioCompletion *comp = cluster.aio_create_completion();
+  ASSERT_EQ(0, ioctx.aio_watch(notify_oid, comp, &handle, &ctx));
+  ASSERT_EQ(0, comp->wait_for_complete());
+  ASSERT_EQ(0, comp->get_return_value());
+  comp->release();
+
+  ASSERT_GT(ioctx.watch_check(handle), 0);
+  std::list<obj_watch_t> watches;
+  ASSERT_EQ(0, ioctx.list_watchers(notify_oid, &watches));
+  ASSERT_EQ(watches.size(), 1u);
+  bufferlist bl2, bl_reply;
+  ASSERT_EQ(0, ioctx.notify2(notify_oid, bl2, 300000, &bl_reply));
+  bufferlist::iterator p = bl_reply.begin();
+  std::map<std::pair<uint64_t,uint64_t>,bufferlist> reply_map;
+  std::set<std::pair<uint64_t,uint64_t> > missed_map;
+  ::decode(reply_map, p);
+  ::decode(missed_map, p);
+  ASSERT_EQ(1u, notify_cookies.size());
+  ASSERT_EQ(1u, notify_cookies.count(handle));
+  ASSERT_EQ(1u, reply_map.size());
+  ASSERT_EQ(5u, reply_map.begin()->second.length());
+  ASSERT_EQ(0, strncmp("reply", reply_map.begin()->second.c_str(), 5));
+  ASSERT_EQ(0u, missed_map.size());
+  ASSERT_GT(ioctx.watch_check(handle), 0);
+
+  comp = cluster.aio_create_completion();
+  ioctx.aio_unwatch(handle, comp);
+  ASSERT_EQ(0, comp->wait_for_complete());
+  comp->release();
+}
+
+
 TEST_P(LibRadosWatchNotifyPP, AioNotify) {
   notify_oid = "foo";
   notify_ioctx = &ioctx;
@@ -593,7 +725,14 @@ TEST_F(LibRadosWatchNotify, WatchNotify2Timeout) {
   ASSERT_GT(rados_watch_check(ioctx, handle), 0);
 
   rados_unwatch2(ioctx, handle);
-  rados_watch_flush(cluster);
+
+  rados_completion_t comp;
+  ASSERT_EQ(0, rados_aio_create_completion(NULL, NULL, NULL, &comp));
+  rados_aio_watch_flush(cluster, comp);
+  ASSERT_EQ(0, rados_aio_wait_for_complete(comp));
+  ASSERT_EQ(0, rados_aio_get_return_value(comp));
+  rados_aio_release(comp);
+
 }
 
 TEST_P(LibRadosWatchNotifyPP, WatchNotify2Timeout) {
@@ -621,9 +760,14 @@ TEST_P(LibRadosWatchNotifyPP, WatchNotify2Timeout) {
   std::cout << " timed out" << std::endl;
   ASSERT_GT(ioctx.watch_check(handle), 0);
   ioctx.unwatch2(handle);
+
   std::cout << " flushing" << std::endl;
-  cluster.watch_flush();
+  librados::AioCompletion *comp = cluster.aio_create_completion();
+  cluster.aio_watch_flush(comp);
+  ASSERT_EQ(0, comp->wait_for_complete());
+  ASSERT_EQ(0, comp->get_return_value());
   std::cout << " flushed" << std::endl;
+  comp->release();
 }
 
 // --
diff --git a/src/test/librados_test_stub/LibradosTestStub.cc b/src/test/librados_test_stub/LibradosTestStub.cc
index 99a8f44..ad6b395 100644
--- a/src/test/librados_test_stub/LibradosTestStub.cc
+++ b/src/test/librados_test_stub/LibradosTestStub.cc
@@ -66,6 +66,16 @@ void do_out_buffer(string& outbl, char **outbuf, size_t *outbuflen) {
 
 } // anonymous namespace
 
+namespace librados {
+
+MockTestMemIoCtxImpl &get_mock_io_ctx(IoCtx &ioctx) {
+  MockTestMemIoCtxImpl **mock =
+    reinterpret_cast<MockTestMemIoCtxImpl **>(&ioctx);
+  return **mock;
+}
+
+}
+
 namespace librados_test_stub {
 
 TestRadosClientPtr *rados_client() {
@@ -153,12 +163,11 @@ extern "C" int rados_conf_read_file(rados_t cluster, const char *path) {
   librados::TestRadosClient *client =
     reinterpret_cast<librados::TestRadosClient*>(cluster);
   md_config_t *conf = client->cct()->_conf;
-  std::deque<std::string> parse_errors;
-  int ret = conf->parse_config_files(path, &parse_errors, NULL, 0);
+  int ret = conf->parse_config_files(path, NULL, 0);
   if (ret == 0) {
     conf->parse_env();
     conf->apply_changes(NULL);
-    complain_about_parse_errors(client->cct(), &parse_errors);
+    conf->complain_about_parse_errors(client->cct());
   } else if (ret == -EINVAL) {
     // ignore missing client config
     return 0;
@@ -404,6 +413,17 @@ int IoCtx::aio_remove(const std::string& oid, AioCompletion *c) {
   return ctx->aio_remove(oid, c->pc);
 }
 
+int IoCtx::aio_watch(const std::string& o, AioCompletion *c, uint64_t *handle,
+                     librados::WatchCtx2 *watch_ctx) {
+  TestIoCtxImpl *ctx = reinterpret_cast<TestIoCtxImpl*>(io_ctx_impl);
+  return ctx->aio_watch(o, c->pc, handle, watch_ctx);
+}
+
+int IoCtx::aio_unwatch(uint64_t handle, AioCompletion *c) {
+  TestIoCtxImpl *ctx = reinterpret_cast<TestIoCtxImpl*>(io_ctx_impl);
+  return ctx->aio_unwatch(handle, c->pc);
+}
+
 config_t IoCtx::cct() {
   TestIoCtxImpl *ctx = reinterpret_cast<TestIoCtxImpl*>(io_ctx_impl);
   return reinterpret_cast<config_t>(ctx->get_rados_client()->cct());
@@ -528,8 +548,7 @@ int IoCtx::read(const std::string& oid, bufferlist& bl, size_t len,
 int IoCtx::remove(const std::string& oid) {
   TestIoCtxImpl *ctx = reinterpret_cast<TestIoCtxImpl*>(io_ctx_impl);
   return ctx->execute_operation(
-    oid, boost::bind(&TestIoCtxImpl::remove, _1, _2));
-  return ctx->remove(oid);
+    oid, boost::bind(&TestIoCtxImpl::remove, _1, _2, ctx->get_snap_context()));
 }
 
 int IoCtx::selfmanaged_snap_create(uint64_t *snapid) {
@@ -571,6 +590,13 @@ int IoCtx::tmap_update(const std::string& oid, bufferlist& cmdbl) {
     oid, boost::bind(&TestIoCtxImpl::tmap_update, _1, _2, cmdbl));
 }
 
+int IoCtx::trunc(const std::string& oid, uint64_t off) {
+  TestIoCtxImpl *ctx = reinterpret_cast<TestIoCtxImpl*>(io_ctx_impl);
+  return ctx->execute_operation(
+    oid, boost::bind(&TestIoCtxImpl::truncate, _1, _2, off,
+                     ctx->get_snap_context()));
+}
+
 int IoCtx::unwatch2(uint64_t handle) {
   TestIoCtxImpl *ctx = reinterpret_cast<TestIoCtxImpl*>(io_ctx_impl);
   return ctx->unwatch(handle);
@@ -741,7 +767,7 @@ void ObjectWriteOperation::omap_set(const std::map<std::string, bufferlist> &map
 
 void ObjectWriteOperation::remove() {
   TestObjectOperationImpl *o = reinterpret_cast<TestObjectOperationImpl*>(impl);
-  o->ops.push_back(boost::bind(&TestIoCtxImpl::remove, _1, _2));
+  o->ops.push_back(boost::bind(&TestIoCtxImpl::remove, _1, _2, _4));
 }
 
 void ObjectWriteOperation::selfmanaged_snap_rollback(uint64_t snapid) {
@@ -811,6 +837,11 @@ AioCompletion *Rados::aio_create_completion(void *cb_arg,
   return new AioCompletion(c);
 }
 
+int Rados::aio_watch_flush(AioCompletion* c) {
+  TestRadosClient *impl = reinterpret_cast<TestRadosClient*>(client);
+  return impl->aio_watch_flush(c->pc);
+}
+
 int Rados::blacklist_add(const std::string& client_address,
 			 uint32_t expire_seconds) {
   TestRadosClient *impl = reinterpret_cast<TestRadosClient*>(client);
diff --git a/src/test/librados_test_stub/LibradosTestStub.h b/src/test/librados_test_stub/LibradosTestStub.h
index 9fed68d..4432ec3 100644
--- a/src/test/librados_test_stub/LibradosTestStub.h
+++ b/src/test/librados_test_stub/LibradosTestStub.h
@@ -7,7 +7,11 @@
 #include <boost/shared_ptr.hpp>
 
 namespace librados {
+class IoCtx;
 class TestRadosClient;
+class MockTestMemIoCtxImpl;
+
+MockTestMemIoCtxImpl &get_mock_io_ctx(IoCtx &ioctx);
 }
 
 namespace librados_test_stub {
diff --git a/src/test/librados_test_stub/MockTestMemIoCtxImpl.h b/src/test/librados_test_stub/MockTestMemIoCtxImpl.h
index c9da11b..40ccc8f 100644
--- a/src/test/librados_test_stub/MockTestMemIoCtxImpl.h
+++ b/src/test/librados_test_stub/MockTestMemIoCtxImpl.h
@@ -48,6 +48,11 @@ public:
                                   snapc);
   }
 
+  MOCK_METHOD2(list_snaps, int(const std::string& o, snap_set_t *out_snaps));
+  int do_list_snaps(const std::string& o, snap_set_t *out_snaps) {
+    return TestMemIoCtxImpl::list_snaps(o, out_snaps);
+  }
+
   MOCK_METHOD2(list_watchers, int(const std::string& o,
                                   std::list<obj_watch_t> *out_watchers));
   int do_list_watchers(const std::string& o,
@@ -64,9 +69,9 @@ public:
     return TestMemIoCtxImpl::read(oid, len, off, bl);
   }
 
-  MOCK_METHOD1(remove, int(const std::string& oid));
-  int do_remove(const std::string& oid) {
-    return TestMemIoCtxImpl::remove(oid);
+  MOCK_METHOD2(remove, int(const std::string& oid, const SnapContext &snapc));
+  int do_remove(const std::string& oid, const SnapContext &snapc) {
+    return TestMemIoCtxImpl::remove(oid, snapc);
   }
 
   MOCK_METHOD1(selfmanaged_snap_create, int(uint64_t *snap_id));
@@ -112,9 +117,10 @@ public:
     using namespace ::testing;
 
     ON_CALL(*this, exec(_, _, _, _, _, _, _)).WillByDefault(Invoke(this, &MockTestMemIoCtxImpl::do_exec));
+    ON_CALL(*this, list_snaps(_, _)).WillByDefault(Invoke(this, &MockTestMemIoCtxImpl::do_list_snaps));
     ON_CALL(*this, list_watchers(_, _)).WillByDefault(Invoke(this, &MockTestMemIoCtxImpl::do_list_watchers));
     ON_CALL(*this, read(_, _, _, _)).WillByDefault(Invoke(this, &MockTestMemIoCtxImpl::do_read));
-    ON_CALL(*this, remove(_)).WillByDefault(Invoke(this, &MockTestMemIoCtxImpl::do_remove));
+    ON_CALL(*this, remove(_, _)).WillByDefault(Invoke(this, &MockTestMemIoCtxImpl::do_remove));
     ON_CALL(*this, selfmanaged_snap_create(_)).WillByDefault(Invoke(this, &MockTestMemIoCtxImpl::do_selfmanaged_snap_create));
     ON_CALL(*this, selfmanaged_snap_remove(_)).WillByDefault(Invoke(this, &MockTestMemIoCtxImpl::do_selfmanaged_snap_remove));
     ON_CALL(*this, selfmanaged_snap_rollback(_, _)).WillByDefault(Invoke(this, &MockTestMemIoCtxImpl::do_selfmanaged_snap_rollback));
diff --git a/src/test/librados_test_stub/TestIoCtxImpl.cc b/src/test/librados_test_stub/TestIoCtxImpl.cc
index 4bde5c9..fcca3b3 100644
--- a/src/test/librados_test_stub/TestIoCtxImpl.cc
+++ b/src/test/librados_test_stub/TestIoCtxImpl.cc
@@ -125,6 +125,24 @@ int TestIoCtxImpl::aio_operate_read(const std::string& oid,
   return 0;
 }
 
+int TestIoCtxImpl::aio_watch(const std::string& o, AioCompletionImpl *c,
+                             uint64_t *handle, librados::WatchCtx2 *watch_ctx) {
+  m_pending_ops.inc();
+  c->get();
+  C_AioNotify *ctx = new C_AioNotify(this, c);
+  m_client->get_watch_notify().aio_watch(o, get_instance_id(), handle,
+                                         watch_ctx, ctx);
+  return 0;
+}
+
+int TestIoCtxImpl::aio_unwatch(uint64_t handle, AioCompletionImpl *c) {
+  m_pending_ops.inc();
+  c->get();
+  C_AioNotify *ctx = new C_AioNotify(this, c);
+  m_client->get_watch_notify().aio_unwatch(handle, ctx);
+  return 0;
+}
+
 int TestIoCtxImpl::exec(const std::string& oid, TestClassHandler *handler,
                         const char *cls, const char *method,
                         bufferlist& inbl, bufferlist* outbl,
diff --git a/src/test/librados_test_stub/TestIoCtxImpl.h b/src/test/librados_test_stub/TestIoCtxImpl.h
index c38e90e..b6d845d 100644
--- a/src/test/librados_test_stub/TestIoCtxImpl.h
+++ b/src/test/librados_test_stub/TestIoCtxImpl.h
@@ -81,7 +81,9 @@ public:
                                AioCompletionImpl *c, int flags,
                                bufferlist *pbl);
   virtual int aio_remove(const std::string& oid, AioCompletionImpl *c) = 0;
-
+  virtual int aio_watch(const std::string& o, AioCompletionImpl *c,
+                        uint64_t *handle, librados::WatchCtx2 *ctx);
+  virtual int aio_unwatch(uint64_t handle, AioCompletionImpl *c);
   virtual int append(const std::string& oid, const bufferlist &bl,
                      const SnapContext &snapc) = 0;
   virtual int assert_exists(const std::string &oid) = 0;
@@ -112,7 +114,7 @@ public:
                            bufferlist *pbl);
   virtual int read(const std::string& oid, size_t len, uint64_t off,
                    bufferlist *bl) = 0;
-  virtual int remove(const std::string& oid) = 0;
+  virtual int remove(const std::string& oid, const SnapContext &snapc) = 0;
   virtual int selfmanaged_snap_create(uint64_t *snapid) = 0;
   virtual int selfmanaged_snap_remove(uint64_t snapid) = 0;
   virtual int selfmanaged_snap_rollback(const std::string& oid,
diff --git a/src/test/librados_test_stub/TestMemIoCtxImpl.cc b/src/test/librados_test_stub/TestMemIoCtxImpl.cc
index 9b95c50..6c522e8 100644
--- a/src/test/librados_test_stub/TestMemIoCtxImpl.cc
+++ b/src/test/librados_test_stub/TestMemIoCtxImpl.cc
@@ -46,7 +46,8 @@ TestIoCtxImpl *TestMemIoCtxImpl::clone() {
 
 int TestMemIoCtxImpl::aio_remove(const std::string& oid, AioCompletionImpl *c) {
   m_client->add_aio_operation(oid, true,
-                              boost::bind(&TestMemIoCtxImpl::remove, this, oid),
+                              boost::bind(&TestMemIoCtxImpl::remove, this, oid,
+                                          get_snap_context()),
                               c);
   return 0;
 }
@@ -270,18 +271,17 @@ int TestMemIoCtxImpl::read(const std::string& oid, size_t len, uint64_t off,
   return len;
 }
 
-int TestMemIoCtxImpl::remove(const std::string& oid) {
+int TestMemIoCtxImpl::remove(const std::string& oid, const SnapContext &snapc) {
   if (get_snap_read() != CEPH_NOSNAP) {
     return -EROFS;
   }
 
   RWLock::WLocker l(m_pool->file_lock);
-  TestMemRadosClient::SharedFile file = get_file(oid, false,
-                                                 get_snap_context());
+  TestMemRadosClient::SharedFile file = get_file(oid, false, snapc);
   if (file == NULL) {
     return -ENOENT;
   }
-  file = get_file(oid, true, get_snap_context());
+  file = get_file(oid, true, snapc);
 
   RWLock::WLocker l2(file->lock);
   file->exists = false;
diff --git a/src/test/librados_test_stub/TestMemIoCtxImpl.h b/src/test/librados_test_stub/TestMemIoCtxImpl.h
index 6556c9c..ab04772 100644
--- a/src/test/librados_test_stub/TestMemIoCtxImpl.h
+++ b/src/test/librados_test_stub/TestMemIoCtxImpl.h
@@ -38,7 +38,7 @@ public:
                        bufferlist> &map);
   virtual int read(const std::string& oid, size_t len, uint64_t off,
                    bufferlist *bl);
-  virtual int remove(const std::string& oid);
+  virtual int remove(const std::string& oid, const SnapContext &snapc);
   virtual int selfmanaged_snap_create(uint64_t *snapid);
   virtual int selfmanaged_snap_remove(uint64_t snapid);
   virtual int selfmanaged_snap_rollback(const std::string& oid,
diff --git a/src/test/librados_test_stub/TestRadosClient.cc b/src/test/librados_test_stub/TestRadosClient.cc
index c72aa28..e2fe20b 100644
--- a/src/test/librados_test_stub/TestRadosClient.cc
+++ b/src/test/librados_test_stub/TestRadosClient.cc
@@ -187,15 +187,15 @@ void TestRadosClient::add_aio_operation(const std::string& oid,
 struct WaitForFlush {
   int flushed() {
     if (count.dec() == 0) {
-      if (c != NULL) {
-	finish_aio_completion(c, 0);
-      }
+      aio_finisher->queue(new FunctionContext(boost::bind(
+        &finish_aio_completion, c, 0)));
       delete this;
     }
     return 0;
   }
 
   atomic_t count;
+  Finisher *aio_finisher;
   AioCompletionImpl *c;
 };
 
@@ -211,16 +211,25 @@ void TestRadosClient::flush_aio_operations(AioCompletionImpl *c) {
 
   WaitForFlush *wait_for_flush = new WaitForFlush();
   wait_for_flush->count.set(m_finishers.size());
+  wait_for_flush->aio_finisher = m_aio_finisher;
   wait_for_flush->c = c;
 
   for (size_t i = 0; i < m_finishers.size(); ++i) {
     AioFunctionContext *ctx = new AioFunctionContext(
       boost::bind(&WaitForFlush::flushed, wait_for_flush),
-      m_aio_finisher, NULL);
+      nullptr, nullptr);
     m_finishers[i]->queue(ctx);
   }
 }
 
+int TestRadosClient::aio_watch_flush(AioCompletionImpl *c) {
+  c->get();
+  Context *ctx = new FunctionContext(boost::bind(
+    &TestRadosClient::finish_aio_completion, this, c, _1));
+  get_watch_notify().aio_flush(ctx);
+  return 0;
+}
+
 void TestRadosClient::finish_aio_completion(AioCompletionImpl *c, int r) {
   librados::finish_aio_completion(c, r);
 }
diff --git a/src/test/librados_test_stub/TestRadosClient.h b/src/test/librados_test_stub/TestRadosClient.h
index b1aa75d..a4fd00d 100644
--- a/src/test/librados_test_stub/TestRadosClient.h
+++ b/src/test/librados_test_stub/TestRadosClient.h
@@ -85,6 +85,7 @@ public:
   virtual int64_t pool_lookup(const std::string &name) = 0;
   virtual int pool_reverse_lookup(int64_t id, std::string *name) = 0;
 
+  virtual int aio_watch_flush(AioCompletionImpl *c);
   virtual int watch_flush() = 0;
 
   virtual int blacklist_add(const std::string& client_address,
diff --git a/src/test/librados_test_stub/TestWatchNotify.cc b/src/test/librados_test_stub/TestWatchNotify.cc
index 7bd2ef7..2aacd48 100644
--- a/src/test/librados_test_stub/TestWatchNotify.cc
+++ b/src/test/librados_test_stub/TestWatchNotify.cc
@@ -7,8 +7,18 @@
 #include <boost/bind.hpp>
 #include <boost/function.hpp>
 
+#define dout_subsys ceph_subsys_rados
+#undef dout_prefix
+#define dout_prefix *_dout << "TestWatchNotify::" << __func__ << ": "
+
 namespace librados {
 
+std::ostream& operator<<(std::ostream& out,
+			 const TestWatchNotify::WatcherID &watcher_id) {
+  out << "(" << watcher_id.first << "," << watcher_id.second << ")";
+  return out;
+}
+
 TestWatchNotify::TestWatchNotify(CephContext *cct, Finisher *finisher)
   : m_cct(cct), m_finisher(finisher), m_handle(), m_notify_id(),
     m_lock("librados::TestWatchNotify::m_lock"),
@@ -21,6 +31,8 @@ TestWatchNotify::~TestWatchNotify() {
 }
 
 void TestWatchNotify::flush() {
+  ldout(m_cct, 20) << "enter" << dendl;
+  // block until we know no additional async notify callbacks will occur
   Mutex::Locker locker(m_lock);
   while (m_pending_notifies > 0) {
     m_file_watcher_cond.Wait(m_lock);
@@ -46,6 +58,23 @@ int TestWatchNotify::list_watchers(const std::string& o,
   return 0;
 }
 
+void TestWatchNotify::aio_flush(Context *on_finish) {
+  m_finisher->queue(on_finish);
+}
+
+void TestWatchNotify::aio_watch(const std::string& o, uint64_t gid,
+                                uint64_t *handle,
+                                librados::WatchCtx2 *watch_ctx,
+                                Context *on_finish) {
+  int r = watch(o, gid, handle, nullptr, watch_ctx);
+  m_finisher->queue(on_finish, r);
+}
+
+void TestWatchNotify::aio_unwatch(uint64_t handle, Context *on_finish) {
+  unwatch(handle);
+  m_finisher->queue(on_finish);
+}
+
 void TestWatchNotify::aio_notify(const std::string& oid, bufferlist& bl,
                                  uint64_t timeout_ms, bufferlist *pbl,
                                  Context *on_notify) {
@@ -53,6 +82,8 @@ void TestWatchNotify::aio_notify(const std::string& oid, bufferlist& bl,
   ++m_pending_notifies;
   uint64_t notify_id = ++m_notify_id;
 
+  ldout(m_cct, 20) << "oid=" << oid << ": notify_id=" << notify_id << dendl;
+
   SharedWatcher watcher = get_watcher(oid);
 
   SharedNotifyHandle notify_handle(new NotifyHandle());
@@ -80,6 +111,8 @@ int TestWatchNotify::notify(const std::string& oid, bufferlist& bl,
 void TestWatchNotify::notify_ack(const std::string& o, uint64_t notify_id,
                                  uint64_t handle, uint64_t gid,
                                  bufferlist& bl) {
+  ldout(m_cct, 20) << "notify_id=" << notify_id << ", handle=" << handle
+		   << ", gid=" << gid << dendl;
   Mutex::Locker lock(m_lock);
   WatcherID watcher_id = std::make_pair(gid, handle);
   ack_notify(o, notify_id, watcher_id, bl);
@@ -100,10 +133,14 @@ int TestWatchNotify::watch(const std::string& o, uint64_t gid,
   watcher->watch_handles[watch_handle.handle] = watch_handle;
 
   *handle = watch_handle.handle;
+
+  ldout(m_cct, 20) << "oid=" << o << ", gid=" << gid << ": handle=" << *handle
+		   << dendl;
   return 0;
 }
 
 int TestWatchNotify::unwatch(uint64_t handle) {
+  ldout(m_cct, 20) << "handle=" << handle << dendl;
   Mutex::Locker locker(m_lock);
   for (FileWatchers::iterator it = m_file_watchers.begin();
        it != m_file_watchers.end(); ++it) {
@@ -133,12 +170,16 @@ TestWatchNotify::SharedWatcher TestWatchNotify::get_watcher(
 
 void TestWatchNotify::execute_notify(const std::string &oid,
                                      bufferlist &bl, uint64_t notify_id) {
+  ldout(m_cct, 20) << "oid=" << oid << ", notify_id=" << notify_id << dendl;
+
   Mutex::Locker lock(m_lock);
   SharedWatcher watcher = get_watcher(oid);
   WatchHandles &watch_handles = watcher->watch_handles;
 
   NotifyHandles::iterator n_it = watcher->notify_handles.find(notify_id);
   if (n_it == watcher->notify_handles.end()) {
+    ldout(m_cct, 1) << "oid=" << oid << ", notify_id=" << notify_id
+		    << ": not found" << dendl;
     return;
   }
 
@@ -176,17 +217,26 @@ void TestWatchNotify::execute_notify(const std::string &oid,
   }
 
   finish_notify(oid, notify_id);
+
+  if (--m_pending_notifies == 0) {
+    m_file_watcher_cond.Signal();
+  }
 }
 
 void TestWatchNotify::ack_notify(const std::string &oid,
                                  uint64_t notify_id,
                                  const WatcherID &watcher_id,
                                  const bufferlist &bl) {
+  ldout(m_cct, 20) << "oid=" << oid << ", notify_id=" << notify_id
+		   << ", WatcherID=" << watcher_id << dendl;
+
   assert(m_lock.is_locked());
   SharedWatcher watcher = get_watcher(oid);
 
   NotifyHandles::iterator it = watcher->notify_handles.find(notify_id);
   if (it == watcher->notify_handles.end()) {
+    ldout(m_cct, 1) << "oid=" << oid << ", notify_id=" << notify_id
+		    << ", WatcherID=" << watcher_id << ": not found" << dendl;
     return;
   }
 
@@ -200,19 +250,28 @@ void TestWatchNotify::ack_notify(const std::string &oid,
 
 void TestWatchNotify::finish_notify(const std::string &oid,
                                     uint64_t notify_id) {
+  ldout(m_cct, 20) << "oid=" << oid << ", notify_id=" << notify_id << dendl;
+
   assert(m_lock.is_locked());
   SharedWatcher watcher = get_watcher(oid);
 
   NotifyHandles::iterator it = watcher->notify_handles.find(notify_id);
   if (it == watcher->notify_handles.end()) {
+    ldout(m_cct, 1) << "oid=" << oid << ", notify_id=" << notify_id
+		    << ": not found" << dendl;
     return;
   }
 
   SharedNotifyHandle notify_handle = it->second;
   if (!notify_handle->pending_watcher_ids.empty()) {
+    ldout(m_cct, 10) << "oid=" << oid << ", notify_id=" << notify_id
+		     << ": pending watchers, returning" << dendl;
     return;
   }
 
+  ldout(m_cct, 20) << "oid=" << oid << ", notify_id=" << notify_id
+		   << ": completing" << dendl;
+
   if (notify_handle->pbl != NULL) {
     ::encode(notify_handle->notify_responses, *notify_handle->pbl);
     ::encode(notify_handle->pending_watcher_ids, *notify_handle->pbl);
@@ -226,10 +285,6 @@ void TestWatchNotify::finish_notify(const std::string &oid,
   if (watcher->watch_handles.empty() && watcher->notify_handles.empty()) {
     m_file_watchers.erase(oid);
   }
-
-  if (--m_pending_notifies == 0) {
-    m_file_watcher_cond.Signal();
-  }
 }
 
 } // namespace librados
diff --git a/src/test/librados_test_stub/TestWatchNotify.h b/src/test/librados_test_stub/TestWatchNotify.h
index a40f560..9cd5230 100644
--- a/src/test/librados_test_stub/TestWatchNotify.h
+++ b/src/test/librados_test_stub/TestWatchNotify.h
@@ -51,11 +51,17 @@ public:
   TestWatchNotify(CephContext *cct, Finisher *finisher);
   ~TestWatchNotify();
 
-  void flush();
   int list_watchers(const std::string& o,
                     std::list<obj_watch_t> *out_watchers);
+
+  void aio_flush(Context *on_finish);
+  void aio_watch(const std::string& o, uint64_t gid, uint64_t *handle,
+                 librados::WatchCtx2 *watch_ctx, Context *on_finish);
+  void aio_unwatch(uint64_t handle, Context *on_finish);
   void aio_notify(const std::string& oid, bufferlist& bl, uint64_t timeout_ms,
                   bufferlist *pbl, Context *on_notify);
+
+  void flush();
   int notify(const std::string& o, bufferlist& bl,
              uint64_t timeout_ms, bufferlist *pbl);
   void notify_ack(const std::string& o, uint64_t notify_id,
diff --git a/src/test/librbd/exclusive_lock/test_mock_AcquireRequest.cc b/src/test/librbd/exclusive_lock/test_mock_AcquireRequest.cc
index e899491..9d67982 100644
--- a/src/test/librbd/exclusive_lock/test_mock_AcquireRequest.cc
+++ b/src/test/librbd/exclusive_lock/test_mock_AcquireRequest.cc
@@ -17,6 +17,7 @@
 #include <list>
 
 // template definitions
+#include "librbd/Journal.cc"
 #include "librbd/exclusive_lock/AcquireRequest.cc"
 template class librbd::exclusive_lock::AcquireRequest<librbd::MockImageCtx>;
 
@@ -28,6 +29,7 @@ using ::testing::DoAll;
 using ::testing::InSequence;
 using ::testing::Return;
 using ::testing::SetArgPointee;
+using ::testing::StrEq;
 using ::testing::WithArg;
 
 static const std::string TEST_COOKIE("auto 123");
@@ -45,7 +47,7 @@ public:
 
   void expect_lock(MockImageCtx &mock_image_ctx, int r) {
     EXPECT_CALL(get_mock_io_ctx(mock_image_ctx.md_ctx),
-                exec(mock_image_ctx.header_oid, _, "lock", "lock", _, _, _))
+                exec(mock_image_ctx.header_oid, _, StrEq("lock"), StrEq("lock"), _, _, _))
                   .WillOnce(Return(r));
   }
 
@@ -79,6 +81,22 @@ public:
                   .WillOnce(CompleteContext(r, mock_image_ctx.image_ctx->op_work_queue));
   }
 
+  void expect_close_journal(MockImageCtx &mock_image_ctx,
+                            MockJournal &mock_journal) {
+    EXPECT_CALL(mock_journal, close(_))
+                  .WillOnce(CompleteContext(0, mock_image_ctx.image_ctx->op_work_queue));
+  }
+
+  void expect_is_journal_tag_owner(MockJournal &mock_journal, bool owner) {
+    EXPECT_CALL(mock_journal, is_tag_owner()).WillOnce(Return(owner));
+  }
+
+  void expect_allocate_journal_tag(MockImageCtx &mock_image_ctx,
+                                   MockJournal &mock_journal, int r) {
+    EXPECT_CALL(mock_journal, allocate_tag("", _))
+                  .WillOnce(WithArg<1>(CompleteContext(r, mock_image_ctx.image_ctx->op_work_queue)));
+  }
+
   void expect_get_lock_info(MockImageCtx &mock_image_ctx, int r,
                             const entity_name_t &locker_entity,
                             const std::string &locker_address,
@@ -86,8 +104,8 @@ public:
                             const std::string &lock_tag,
                             ClsLockType lock_type) {
     auto &expect = EXPECT_CALL(get_mock_io_ctx(mock_image_ctx.md_ctx),
-                               exec(mock_image_ctx.header_oid, _, "lock",
-                               "get_info", _, _, _));
+                               exec(mock_image_ctx.header_oid, _, StrEq("lock"),
+                               StrEq("get_info"), _, _, _));
     if (r < 0 && r != -ENOENT) {
       expect.WillOnce(Return(r));
     } else {
@@ -138,9 +156,14 @@ public:
 
   void expect_break_lock(MockImageCtx &mock_image_ctx, int r) {
     EXPECT_CALL(get_mock_io_ctx(mock_image_ctx.md_ctx),
-                exec(mock_image_ctx.header_oid, _, "lock", "break_lock", _, _, _))
+                exec(mock_image_ctx.header_oid, _, StrEq("lock"), StrEq("break_lock"), _, _, _))
                   .WillOnce(Return(r));
   }
+
+  void expect_flush_notifies(MockImageCtx &mock_image_ctx) {
+    EXPECT_CALL(*mock_image_ctx.image_watcher, flush(_))
+                  .WillOnce(CompleteContext(0, mock_image_ctx.image_ctx->op_work_queue));
+  }
 };
 
 TEST_F(TestMockExclusiveLockAcquireRequest, Success) {
@@ -153,6 +176,7 @@ TEST_F(TestMockExclusiveLockAcquireRequest, Success) {
   expect_op_work_queue(mock_image_ctx);
 
   InSequence seq;
+  expect_flush_notifies(mock_image_ctx);
   expect_lock(mock_image_ctx, 0);
 
   MockObjectMap mock_object_map;
@@ -164,6 +188,8 @@ TEST_F(TestMockExclusiveLockAcquireRequest, Success) {
   expect_test_features(mock_image_ctx, RBD_FEATURE_JOURNALING, true);
   expect_create_journal(mock_image_ctx, &mock_journal);
   expect_open_journal(mock_image_ctx, mock_journal, 0);
+  expect_is_journal_tag_owner(mock_journal, true);
+  expect_allocate_journal_tag(mock_image_ctx, mock_journal, 0);
 
   C_SaferCond acquire_ctx;
   C_SaferCond ctx;
@@ -185,6 +211,7 @@ TEST_F(TestMockExclusiveLockAcquireRequest, SuccessJournalDisabled) {
   expect_op_work_queue(mock_image_ctx);
 
   InSequence seq;
+  expect_flush_notifies(mock_image_ctx);
   expect_lock(mock_image_ctx, 0);
 
   MockObjectMap mock_object_map;
@@ -214,6 +241,7 @@ TEST_F(TestMockExclusiveLockAcquireRequest, SuccessObjectMapDisabled) {
   expect_op_work_queue(mock_image_ctx);
 
   InSequence seq;
+  expect_flush_notifies(mock_image_ctx);
   expect_lock(mock_image_ctx, 0);
 
   expect_test_features(mock_image_ctx, RBD_FEATURE_OBJECT_MAP, false);
@@ -222,6 +250,8 @@ TEST_F(TestMockExclusiveLockAcquireRequest, SuccessObjectMapDisabled) {
   expect_test_features(mock_image_ctx, RBD_FEATURE_JOURNALING, true);
   expect_create_journal(mock_image_ctx, &mock_journal);
   expect_open_journal(mock_image_ctx, mock_journal, 0);
+  expect_is_journal_tag_owner(mock_journal, true);
+  expect_allocate_journal_tag(mock_image_ctx, mock_journal, 0);
 
   C_SaferCond acquire_ctx;
   C_SaferCond ctx;
@@ -243,6 +273,7 @@ TEST_F(TestMockExclusiveLockAcquireRequest, JournalError) {
   expect_op_work_queue(mock_image_ctx);
 
   InSequence seq;
+  expect_flush_notifies(mock_image_ctx);
   expect_lock(mock_image_ctx, 0);
 
   MockObjectMap *mock_object_map = new MockObjectMap();
@@ -254,6 +285,7 @@ TEST_F(TestMockExclusiveLockAcquireRequest, JournalError) {
   expect_test_features(mock_image_ctx, RBD_FEATURE_JOURNALING, true);
   expect_create_journal(mock_image_ctx, mock_journal);
   expect_open_journal(mock_image_ctx, *mock_journal, -EINVAL);
+  expect_close_journal(mock_image_ctx, *mock_journal);
   expect_close_object_map(mock_image_ctx, *mock_object_map);
 
   C_SaferCond acquire_ctx;
@@ -265,6 +297,77 @@ TEST_F(TestMockExclusiveLockAcquireRequest, JournalError) {
   ASSERT_EQ(-EINVAL, ctx.wait());
 }
 
+TEST_F(TestMockExclusiveLockAcquireRequest, NotJournalTagOwner) {
+  REQUIRE_FEATURE(RBD_FEATURE_EXCLUSIVE_LOCK);
+
+  librbd::ImageCtx *ictx;
+  ASSERT_EQ(0, open_image(m_image_name, &ictx));
+
+  MockImageCtx mock_image_ctx(*ictx);
+  expect_op_work_queue(mock_image_ctx);
+
+  InSequence seq;
+  expect_flush_notifies(mock_image_ctx);
+  expect_lock(mock_image_ctx, 0);
+
+  MockObjectMap *mock_object_map = new MockObjectMap();
+  expect_test_features(mock_image_ctx, RBD_FEATURE_OBJECT_MAP, true);
+  expect_create_object_map(mock_image_ctx, mock_object_map);
+  expect_open_object_map(mock_image_ctx, *mock_object_map);
+
+  MockJournal *mock_journal = new MockJournal();
+  expect_test_features(mock_image_ctx, RBD_FEATURE_JOURNALING, true);
+  expect_create_journal(mock_image_ctx, mock_journal);
+  expect_open_journal(mock_image_ctx, *mock_journal, 0);
+  expect_is_journal_tag_owner(*mock_journal, false);
+  expect_close_journal(mock_image_ctx, *mock_journal);
+  expect_close_object_map(mock_image_ctx, *mock_object_map);
+
+  C_SaferCond acquire_ctx;
+  C_SaferCond ctx;
+  MockAcquireRequest *req = MockAcquireRequest::create(mock_image_ctx,
+                                                       TEST_COOKIE,
+                                                       &acquire_ctx, &ctx);
+  req->send();
+  ASSERT_EQ(-EPERM, ctx.wait());
+}
+
+TEST_F(TestMockExclusiveLockAcquireRequest, AllocateJournalTagError) {
+  REQUIRE_FEATURE(RBD_FEATURE_EXCLUSIVE_LOCK);
+
+  librbd::ImageCtx *ictx;
+  ASSERT_EQ(0, open_image(m_image_name, &ictx));
+
+  MockImageCtx mock_image_ctx(*ictx);
+  expect_op_work_queue(mock_image_ctx);
+
+  InSequence seq;
+  expect_flush_notifies(mock_image_ctx);
+  expect_lock(mock_image_ctx, 0);
+
+  MockObjectMap *mock_object_map = new MockObjectMap();
+  expect_test_features(mock_image_ctx, RBD_FEATURE_OBJECT_MAP, true);
+  expect_create_object_map(mock_image_ctx, mock_object_map);
+  expect_open_object_map(mock_image_ctx, *mock_object_map);
+
+  MockJournal *mock_journal = new MockJournal();
+  expect_test_features(mock_image_ctx, RBD_FEATURE_JOURNALING, true);
+  expect_create_journal(mock_image_ctx, mock_journal);
+  expect_open_journal(mock_image_ctx, *mock_journal, 0);
+  expect_is_journal_tag_owner(*mock_journal, true);
+  expect_allocate_journal_tag(mock_image_ctx, *mock_journal, -ESTALE);
+  expect_close_journal(mock_image_ctx, *mock_journal);
+  expect_close_object_map(mock_image_ctx, *mock_object_map);
+
+  C_SaferCond acquire_ctx;
+  C_SaferCond ctx;
+  MockAcquireRequest *req = MockAcquireRequest::create(mock_image_ctx,
+                                                       TEST_COOKIE,
+                                                       &acquire_ctx, &ctx);
+  req->send();
+  ASSERT_EQ(-ESTALE, ctx.wait());
+}
+
 TEST_F(TestMockExclusiveLockAcquireRequest, LockBusy) {
   REQUIRE_FEATURE(RBD_FEATURE_EXCLUSIVE_LOCK);
 
@@ -275,6 +378,7 @@ TEST_F(TestMockExclusiveLockAcquireRequest, LockBusy) {
   expect_op_work_queue(mock_image_ctx);
 
   InSequence seq;
+  expect_flush_notifies(mock_image_ctx);
   expect_lock(mock_image_ctx, -EBUSY);
   expect_get_lock_info(mock_image_ctx, 0, entity_name_t::CLIENT(1), "1.2.3.4",
                        "auto 123", MockExclusiveLock::WATCHER_LOCK_TAG,
@@ -302,6 +406,7 @@ TEST_F(TestMockExclusiveLockAcquireRequest, GetLockInfoError) {
   expect_op_work_queue(mock_image_ctx);
 
   InSequence seq;
+  expect_flush_notifies(mock_image_ctx);
   expect_lock(mock_image_ctx, -EBUSY);
   expect_get_lock_info(mock_image_ctx, -EINVAL, entity_name_t::CLIENT(1), "",
                        "", "", LOCK_EXCLUSIVE);
@@ -324,6 +429,7 @@ TEST_F(TestMockExclusiveLockAcquireRequest, GetLockInfoEmpty) {
   expect_op_work_queue(mock_image_ctx);
 
   InSequence seq;
+  expect_flush_notifies(mock_image_ctx);
   expect_lock(mock_image_ctx, -EBUSY);
   expect_get_lock_info(mock_image_ctx, -ENOENT, entity_name_t::CLIENT(1), "",
                        "", "", LOCK_EXCLUSIVE);
@@ -347,6 +453,7 @@ TEST_F(TestMockExclusiveLockAcquireRequest, GetLockInfoExternalTag) {
   expect_op_work_queue(mock_image_ctx);
 
   InSequence seq;
+  expect_flush_notifies(mock_image_ctx);
   expect_lock(mock_image_ctx, -EBUSY);
   expect_get_lock_info(mock_image_ctx, 0, entity_name_t::CLIENT(1), "1.2.3.4",
                        "auto 123", "external tag", LOCK_EXCLUSIVE);
@@ -369,6 +476,7 @@ TEST_F(TestMockExclusiveLockAcquireRequest, GetLockInfoShared) {
   expect_op_work_queue(mock_image_ctx);
 
   InSequence seq;
+  expect_flush_notifies(mock_image_ctx);
   expect_lock(mock_image_ctx, -EBUSY);
   expect_get_lock_info(mock_image_ctx, 0, entity_name_t::CLIENT(1), "1.2.3.4",
                        "auto 123", MockExclusiveLock::WATCHER_LOCK_TAG,
@@ -392,6 +500,7 @@ TEST_F(TestMockExclusiveLockAcquireRequest, GetLockInfoExternalCookie) {
   expect_op_work_queue(mock_image_ctx);
 
   InSequence seq;
+  expect_flush_notifies(mock_image_ctx);
   expect_lock(mock_image_ctx, -EBUSY);
   expect_get_lock_info(mock_image_ctx, 0, entity_name_t::CLIENT(1), "1.2.3.4",
                        "external cookie", MockExclusiveLock::WATCHER_LOCK_TAG,
@@ -415,6 +524,7 @@ TEST_F(TestMockExclusiveLockAcquireRequest, GetWatchersError) {
   expect_op_work_queue(mock_image_ctx);
 
   InSequence seq;
+  expect_flush_notifies(mock_image_ctx);
   expect_lock(mock_image_ctx, -EBUSY);
   expect_get_lock_info(mock_image_ctx, 0, entity_name_t::CLIENT(1), "1.2.3.4",
                        "auto 123", MockExclusiveLock::WATCHER_LOCK_TAG,
@@ -439,6 +549,7 @@ TEST_F(TestMockExclusiveLockAcquireRequest, GetWatchersAlive) {
   expect_op_work_queue(mock_image_ctx);
 
   InSequence seq;
+  expect_flush_notifies(mock_image_ctx);
   expect_lock(mock_image_ctx, -EBUSY);
   expect_get_lock_info(mock_image_ctx, 0, entity_name_t::CLIENT(1), "1.2.3.4",
                        "auto 123", MockExclusiveLock::WATCHER_LOCK_TAG,
@@ -464,6 +575,7 @@ TEST_F(TestMockExclusiveLockAcquireRequest, BlacklistDisabled) {
   mock_image_ctx.blacklist_on_break_lock = false;
 
   InSequence seq;
+  expect_flush_notifies(mock_image_ctx);
   expect_lock(mock_image_ctx, -EBUSY);
   expect_get_lock_info(mock_image_ctx, 0, entity_name_t::CLIENT(1), "1.2.3.4",
                        "auto 123", MockExclusiveLock::WATCHER_LOCK_TAG,
@@ -490,6 +602,7 @@ TEST_F(TestMockExclusiveLockAcquireRequest, BlacklistError) {
   expect_op_work_queue(mock_image_ctx);
 
   InSequence seq;
+  expect_flush_notifies(mock_image_ctx);
   expect_lock(mock_image_ctx, -EBUSY);
   expect_get_lock_info(mock_image_ctx, 0, entity_name_t::CLIENT(1), "1.2.3.4",
                        "auto 123", MockExclusiveLock::WATCHER_LOCK_TAG,
@@ -515,6 +628,7 @@ TEST_F(TestMockExclusiveLockAcquireRequest, BreakLockMissing) {
   expect_op_work_queue(mock_image_ctx);
 
   InSequence seq;
+  expect_flush_notifies(mock_image_ctx);
   expect_lock(mock_image_ctx, -EBUSY);
   expect_get_lock_info(mock_image_ctx, 0, entity_name_t::CLIENT(1), "1.2.3.4",
                        "auto 123", MockExclusiveLock::WATCHER_LOCK_TAG,
@@ -542,6 +656,7 @@ TEST_F(TestMockExclusiveLockAcquireRequest, BreakLockError) {
   expect_op_work_queue(mock_image_ctx);
 
   InSequence seq;
+  expect_flush_notifies(mock_image_ctx);
   expect_lock(mock_image_ctx, -EBUSY);
   expect_get_lock_info(mock_image_ctx, 0, entity_name_t::CLIENT(1), "1.2.3.4",
                        "auto 123", MockExclusiveLock::WATCHER_LOCK_TAG,
diff --git a/src/test/librbd/exclusive_lock/test_mock_ReleaseRequest.cc b/src/test/librbd/exclusive_lock/test_mock_ReleaseRequest.cc
index b32deee..eb42feb 100644
--- a/src/test/librbd/exclusive_lock/test_mock_ReleaseRequest.cc
+++ b/src/test/librbd/exclusive_lock/test_mock_ReleaseRequest.cc
@@ -22,6 +22,7 @@ namespace exclusive_lock {
 using ::testing::_;
 using ::testing::InSequence;
 using ::testing::Return;
+using ::testing::StrEq;
 
 static const std::string TEST_COOKIE("auto 123");
 
@@ -29,7 +30,22 @@ class TestMockExclusiveLockReleaseRequest : public TestMockFixture {
 public:
   typedef ReleaseRequest<MockImageCtx> MockReleaseRequest;
 
+  void expect_test_features(MockImageCtx &mock_image_ctx, uint64_t features,
+                            bool enabled) {
+    EXPECT_CALL(mock_image_ctx, test_features(features))
+                  .WillOnce(Return(enabled));
+  }
+
+  void expect_set_require_lock_on_read(MockImageCtx &mock_image_ctx) {
+    EXPECT_CALL(*mock_image_ctx.aio_work_queue, set_require_lock_on_read());
+  }
+
   void expect_block_writes(MockImageCtx &mock_image_ctx, int r) {
+    expect_test_features(mock_image_ctx, RBD_FEATURE_JOURNALING,
+                         ((mock_image_ctx.features & RBD_FEATURE_JOURNALING) != 0));
+    if ((mock_image_ctx.features & RBD_FEATURE_JOURNALING) != 0) {
+      expect_set_require_lock_on_read(mock_image_ctx);
+    }
     EXPECT_CALL(*mock_image_ctx.aio_work_queue, block_writes(_))
                   .WillOnce(CompleteContext(r, mock_image_ctx.image_ctx->op_work_queue));
   }
@@ -45,7 +61,7 @@ public:
 
   void expect_unlock(MockImageCtx &mock_image_ctx, int r) {
     EXPECT_CALL(get_mock_io_ctx(mock_image_ctx.md_ctx),
-                exec(mock_image_ctx.header_oid, _, "lock", "unlock", _, _, _))
+                exec(mock_image_ctx.header_oid, _, StrEq("lock"), StrEq("unlock"), _, _, _))
                   .WillOnce(Return(r));
   }
 
@@ -60,6 +76,11 @@ public:
     EXPECT_CALL(mock_object_map, close(_))
                   .WillOnce(CompleteContext(0, mock_image_ctx.image_ctx->op_work_queue));
   }
+
+  void expect_flush_notifies(MockImageCtx &mock_image_ctx) {
+    EXPECT_CALL(*mock_image_ctx.image_watcher, flush(_))
+                  .WillOnce(CompleteContext(0, mock_image_ctx.image_ctx->op_work_queue));
+  }
 };
 
 TEST_F(TestMockExclusiveLockReleaseRequest, Success) {
@@ -74,6 +95,7 @@ TEST_F(TestMockExclusiveLockReleaseRequest, Success) {
   InSequence seq;
   expect_block_writes(mock_image_ctx, 0);
   expect_cancel_op_requests(mock_image_ctx, 0);
+  expect_flush_notifies(mock_image_ctx);
 
   MockJournal *mock_journal = new MockJournal();
   mock_image_ctx.journal = mock_journal;
@@ -107,6 +129,7 @@ TEST_F(TestMockExclusiveLockReleaseRequest, SuccessJournalDisabled) {
 
   InSequence seq;
   expect_cancel_op_requests(mock_image_ctx, 0);
+  expect_flush_notifies(mock_image_ctx);
 
   MockObjectMap *mock_object_map = new MockObjectMap();
   mock_image_ctx.object_map = mock_object_map;
@@ -136,6 +159,7 @@ TEST_F(TestMockExclusiveLockReleaseRequest, SuccessObjectMapDisabled) {
 
   InSequence seq;
   expect_cancel_op_requests(mock_image_ctx, 0);
+  expect_flush_notifies(mock_image_ctx);
 
   expect_unlock(mock_image_ctx, 0);
 
@@ -182,6 +206,7 @@ TEST_F(TestMockExclusiveLockReleaseRequest, UnlockError) {
   InSequence seq;
   expect_block_writes(mock_image_ctx, 0);
   expect_cancel_op_requests(mock_image_ctx, 0);
+  expect_flush_notifies(mock_image_ctx);
 
   expect_unlock(mock_image_ctx, -EINVAL);
 
diff --git a/src/test/librbd/fsx.cc b/src/test/librbd/fsx.cc
index 55a2ba3..f0519ec 100644
--- a/src/test/librbd/fsx.cc
+++ b/src/test/librbd/fsx.cc
@@ -1,11 +1,12 @@
-// -*- mode:C; tab-width:8; c-basic-offset:8; indent-tabs-mode:t -*- 
+// -*- mode:C++; tab-width:8; c-basic-offset:8; indent-tabs-mode:t -*-
+// vim: ts=8 sw=8 smarttab
 /*
  *	Copyright (C) 1991, NeXT Computer, Inc.  All Rights Reserverd.
  *
  *	File:	fsx.cc
  *	Author:	Avadis Tevanian, Jr.
  *
- *	File system exerciser. 
+ *	File system exerciser.
  *
  *	Rewritten 8/98 by Conrad Minshall.
  *
@@ -43,10 +44,15 @@
 #include "include/intarith.h"
 #include "include/krbd.h"
 #include "include/rados/librados.h"
+#include "include/rados/librados.hpp"
 #include "include/rbd/librbd.h"
-
+#include "include/rbd/librbd.hpp"
+#include "common/Cond.h"
 #include "common/SubProcess.h"
 #include "common/safe_io.h"
+#include "journal/Journaler.h"
+#include "journal/ReplayEntry.h"
+#include "journal/ReplayHandler.h"
 
 #define NUMPRINTCOLUMNS 32	/* # columns of data to print on each line */
 
@@ -116,6 +122,7 @@ int			logcount = 0;	/* total ops */
 #undef PAGE_MASK
 #define PAGE_MASK       (PAGE_SIZE - 1)
 
+
 char	*original_buf;			/* a pointer to the original data */
 char	*good_buf;			/* a pointer to the correct data */
 char	*temp_buf;			/* a pointer to the current data */
@@ -130,8 +137,9 @@ unsigned long	simulatedopcount = 0;	/* -b flag */
 int	closeprob = 0;			/* -c flag */
 int	debug = 0;			/* -d flag */
 unsigned long	debugstart = 0;		/* -D flag */
-int	flush = 0;			/* -f flag */
+int	flush_enabled = 0;		/* -f flag */
 int	holebdy = 1;			/* -h flag */
+bool    journal_replay = false;         /* -j flah */
 int	do_fsync = 0;			/* -y flag */
 unsigned long	maxfilelen = 256 * 1024;	/* -l flag */
 int	sizechecks = 1;			/* -n flag disables them */
@@ -243,6 +251,234 @@ get_random(void)
 	return random_generator();
 }
 
+void replay_imagename(char *buf, size_t len, int clones);
+
+namespace {
+
+static const std::string JOURNAL_CLIENT_ID("fsx");
+
+struct ReplayHandler : public journal::ReplayHandler {
+        journal::Journaler *journaler;
+        journal::Journaler *replay_journaler;
+        Context *on_finish;
+
+        ReplayHandler(journal::Journaler *journaler,
+                      journal::Journaler *replay_journaler, Context *on_finish)
+                : journaler(journaler), replay_journaler(replay_journaler),
+                  on_finish(on_finish) {
+        }
+
+        virtual void get() {
+        }
+        virtual void put() {
+        }
+
+        virtual void handle_entries_available() {
+                while (true) {
+                        journal::ReplayEntry replay_entry;
+                        if (!journaler->try_pop_front(&replay_entry)) {
+                                return;
+                        }
+
+                        replay_journaler->append(0, replay_entry.get_data());
+                }
+        }
+
+        virtual void handle_complete(int r) {
+                on_finish->complete(r);
+        }
+};
+
+int get_image_id(librados::IoCtx &io_ctx, const char *image_name,
+                 std::string *image_id) {
+        librbd::RBD rbd;
+        librbd::Image image;
+        int r = rbd.open(io_ctx, image, image_name);
+        if (r < 0) {
+                simple_err("failed to open image", r);
+                return r;
+        }
+
+        rbd_image_info_t info;
+        r = image.stat(info, sizeof(info));
+        if (r < 0) {
+                simple_err("failed to stat image", r);
+                return r;
+        }
+
+        *image_id = std::string(&info.block_name_prefix[strlen(RBD_DATA_PREFIX)]);
+        return 0;
+}
+
+int register_journal(rados_ioctx_t ioctx, const char *image_name) {
+        librados::IoCtx io_ctx;
+        librados::IoCtx::from_rados_ioctx_t(ioctx, io_ctx);
+
+        std::string image_id;
+        int r = get_image_id(io_ctx, image_name, &image_id);
+        if (r < 0) {
+                return r;
+        }
+
+        journal::Journaler journaler(io_ctx, image_id, JOURNAL_CLIENT_ID, 0);
+        r = journaler.register_client(bufferlist());
+        if (r < 0) {
+                simple_err("failed to register journal client", r);
+                return r;
+        }
+        return 0;
+}
+
+int unregister_journal(rados_ioctx_t ioctx, const char *image_name) {
+        librados::IoCtx io_ctx;
+        librados::IoCtx::from_rados_ioctx_t(ioctx, io_ctx);
+
+        std::string image_id;
+        int r = get_image_id(io_ctx, image_name, &image_id);
+        if (r < 0) {
+                return r;
+        }
+
+        journal::Journaler journaler(io_ctx, image_id, JOURNAL_CLIENT_ID, 0);
+        r = journaler.unregister_client();
+        if (r < 0) {
+                simple_err("failed to unregister journal client", r);
+                return r;
+        }
+        return 0;
+}
+
+int create_replay_image(rados_ioctx_t ioctx, int order,
+                        uint64_t stripe_unit, int stripe_count,
+                        const char *replay_image_name,
+                        const char *last_replay_image_name) {
+        librados::IoCtx io_ctx;
+        librados::IoCtx::from_rados_ioctx_t(ioctx, io_ctx);
+
+        int r;
+        librbd::RBD rbd;
+        if (last_replay_image_name == nullptr) {
+                r = rbd.create2(io_ctx, replay_image_name, 0,
+                                RBD_FEATURES_ALL, &order);
+        } else {
+                r = rbd.clone2(io_ctx, last_replay_image_name, "snap",
+                               io_ctx, replay_image_name, RBD_FEATURES_ALL,
+                               &order, stripe_unit, stripe_count);
+        }
+
+        if (r < 0) {
+                simple_err("failed to create replay image", r);
+                return r;
+        }
+
+        return 0;
+}
+
+int replay_journal(rados_ioctx_t ioctx, const char *image_name,
+                   const char *replay_image_name) {
+        librados::IoCtx io_ctx;
+        librados::IoCtx::from_rados_ioctx_t(ioctx, io_ctx);
+
+        std::string image_id;
+        int r = get_image_id(io_ctx, image_name, &image_id);
+        if (r < 0) {
+                return r;
+        }
+
+        std::string replay_image_id;
+        r = get_image_id(io_ctx, replay_image_name, &replay_image_id);
+        if (r < 0) {
+                return r;
+        }
+
+        journal::Journaler journaler(io_ctx, image_id, JOURNAL_CLIENT_ID, 0);
+        C_SaferCond init_ctx;
+        journaler.init(&init_ctx);
+        r = init_ctx.wait();
+        if (r < 0) {
+                simple_err("failed to initialize journal", r);
+                return r;
+        }
+
+        journal::Journaler replay_journaler(io_ctx, replay_image_id, "", 0);
+        C_SaferCond replay_init_ctx;
+        replay_journaler.init(&replay_init_ctx);
+        r = replay_init_ctx.wait();
+        if (r < 0) {
+                simple_err("failed to initialize replay journal", r);
+                return r;
+        }
+
+        replay_journaler.start_append(0, 0, 0);
+
+        C_SaferCond replay_ctx;
+        ReplayHandler replay_handler(&journaler, &replay_journaler,
+                                     &replay_ctx);
+
+        // copy journal events from source image to replay image
+        journaler.start_replay(&replay_handler);
+        r = replay_ctx.wait();
+
+        journaler.stop_replay();
+
+        C_SaferCond stop_ctx;
+        replay_journaler.stop_append(&stop_ctx);
+        int stop_r = stop_ctx.wait();
+        if (r == 0 && stop_r < 0) {
+                r = stop_r;
+        }
+
+        if (r < 0) {
+                simple_err("failed to replay journal", r);
+                return r;
+        }
+
+        librbd::RBD rbd;
+        librbd::Image image;
+        r = rbd.open(io_ctx, image, replay_image_name);
+        if (r < 0) {
+                simple_err("failed to open replay image", r);
+                return r;
+        }
+
+        // perform an IO op to initiate the journal replay
+        bufferlist bl;
+        r = static_cast<ssize_t>(image.write(0, 0, bl));
+        if (r < 0) {
+                simple_err("failed to write to replay image", r);
+                return r;
+        }
+        return 0;
+}
+
+int finalize_journal(rados_ioctx_t ioctx, const char *imagename, int clones,
+                     int order, uint64_t stripe_unit, int stripe_count) {
+        char replayimagename[1024];
+        replay_imagename(replayimagename, sizeof(replayimagename), clones);
+
+        char lastreplayimagename[1024];
+        if (clones > 0) {
+                replay_imagename(lastreplayimagename,
+                                 sizeof(lastreplayimagename), clones - 1);
+        }
+
+        int ret = create_replay_image(ioctx, order, stripe_unit,
+                                      stripe_count, replayimagename,
+                                      clones > 0 ? lastreplayimagename :
+                                                   nullptr);
+        if (ret < 0) {
+                exit(EXIT_FAILURE);
+        }
+
+        ret = replay_journal(ioctx, imagename, replayimagename);
+        if (ret < 0) {
+                exit(EXIT_FAILURE);
+        }
+        return 0;
+}
+
+} // anonymous namespace
+
 /*
  * rbd
  */
@@ -809,7 +1045,7 @@ nbd_open(const char *name, struct rbd_ctx *ctx)
 
         r = process.spawn();
         if (r < 0) {
-		prt("nbd_open failed to run rbd-nbd error: %s\n", process.err());
+		prt("nbd_open failed to run rbd-nbd error: %s\n", process.err().c_str());
 		return r;
         }
 	r = safe_read(process.get_stdout(), dev, sizeof(dev));
@@ -823,7 +1059,7 @@ nbd_open(const char *name, struct rbd_ctx *ctx)
 	dev[r] = 0;
 	r = process.join();
 	if (r) {
-		prt("rbd-nbd failed with error: %s", process.err());
+		prt("rbd-nbd failed with error: %s", process.err().c_str());
 		return -EINVAL;
 	}
 
@@ -863,12 +1099,12 @@ nbd_close(struct rbd_ctx *ctx)
 
         r = process.spawn();
         if (r < 0) {
-		prt("nbd_close failed to run rbd-nbd error: %s\n", process.err());
+		prt("nbd_close failed to run rbd-nbd error: %s\n", process.err().c_str());
 		return r;
         }
 	r = process.join();
 	if (r) {
-		prt("rbd-nbd failed with error: %d", process.err());
+		prt("rbd-nbd failed with error: %d", process.err().c_str());
 		return -EINVAL;
 	}
 
@@ -1232,8 +1468,16 @@ create_image()
 		simple_err("Error creating ioctx", r);
 		goto failed_krbd;
 	}
-	if (clone_calls) {
-		r = rbd_create2(ioctx, iname, 0, RBD_FEATURE_LAYERING, &order);
+	if (clone_calls || journal_replay) {
+                uint64_t features = 0;
+                if (clone_calls) {
+                        features |= RBD_FEATURE_LAYERING;
+                }
+                if (journal_replay) {
+                        features |= (RBD_FEATURE_EXCLUSIVE_LOCK |
+                                     RBD_FEATURE_JOURNALING);
+                }
+		r = rbd_create2(ioctx, iname, 0, features, &order);
 	} else {
 		r = rbd_create(ioctx, iname, 0, &order);
 	}
@@ -1242,6 +1486,12 @@ create_image()
 		goto failed_open;
 	}
 
+        if (journal_replay) {
+                r = register_journal(ioctx, iname);
+                if (r < 0) {
+                        goto failed_open;
+                }
+        }
 	return 0;
 
  failed_open:
@@ -1411,7 +1661,7 @@ dowrite(unsigned offset, unsigned size)
 		report_failure(151);
 	}
 
-	if (flush)
+	if (flush_enabled)
 		doflush(offset, size);
 }
 
@@ -1515,9 +1765,17 @@ void clone_imagename(char *buf, size_t len, int clones)
 		snprintf(buf, len, "%s-clone%d", iname, clones);
 	else
 		strncpy(buf, iname, len);
+        buf[len - 1] = '\0';
 }
 
-void check_clone(int clonenum);
+void replay_imagename(char *buf, size_t len, int clones)
+{
+        clone_imagename(buf, len, clones);
+        strncat(buf, "-replay", len - strlen(buf));
+        buf[len - 1] = '\0';
+}
+
+void check_clone(int clonenum, bool replay_image);
 
 void
 do_clone()
@@ -1613,6 +1871,19 @@ do_clone()
 		exit(174);
 	}
 
+        if (journal_replay) {
+                ret = finalize_journal(ioctx, lastimagename, num_clones - 1,
+                                       order, stripe_unit, stripe_count);
+                if (ret < 0) {
+                        exit(EXIT_FAILURE);
+                }
+
+                ret = register_journal(ioctx, imagename);
+                if (ret < 0) {
+                        exit(EXIT_FAILURE);
+                }
+        }
+
 	/*
 	 * Open freshly made clone.
 	 */
@@ -1621,12 +1892,16 @@ do_clone()
 		exit(166);
 	}
 
-	if (num_clones > 1)
-		check_clone(num_clones - 2);
+	if (num_clones > 1) {
+                if (journal_replay) {
+		        check_clone(num_clones - 2, true);
+                }
+		check_clone(num_clones - 2, false);
+        }
 }
 
 void
-check_clone(int clonenum)
+check_clone(int clonenum, bool replay_image)
 {
 	char filename[128];
 	char imagename[128];
@@ -1635,7 +1910,12 @@ check_clone(int clonenum)
 	struct stat file_info;
 	char *good_buf, *temp_buf;
 
-	clone_imagename(imagename, sizeof(imagename), clonenum);
+        if (replay_image) {
+                replay_imagename(imagename, sizeof(imagename), clonenum);
+        } else {
+        	clone_imagename(imagename, sizeof(imagename), clonenum);
+        }
+
 	if ((ret = ops->open(imagename, &cur_ctx)) < 0) {
 		prterrcode("check_clone: ops->open", ret);
 		exit(167);
@@ -1687,7 +1967,9 @@ check_clone(int clonenum)
 	}
 	check_buffers(good_buf, temp_buf, 0, file_info.st_size);
 
-	unlink(filename);
+        if (!replay_image) {
+	        unlink(filename);
+        }
 
 	free(good_buf);
 	free(temp_buf);
@@ -1912,12 +2194,13 @@ void
 usage(void)
 {
 	fprintf(stdout, "usage: %s",
-		"fsx [-dfnqxyACFHKLORUWZ] [-b opnum] [-c Prob] [-h holebdy] [-l flen] [-m start:end] [-o oplen] [-p progressinterval] [-r readbdy] [-s style] [-t truncbdy] [-w writebdy] [-D startingop] [-N numops] [-P dirpath] [-S seed] pname iname\n\
+		"fsx [-dfjnqxyACFHKLORUWZ] [-b opnum] [-c Prob] [-h holebdy] [-l flen] [-m start:end] [-o oplen] [-p progressinterval] [-r readbdy] [-s style] [-t truncbdy] [-w writebdy] [-D startingop] [-N numops] [-P dirpath] [-S seed] pname iname\n\
 	-b opnum: beginning operation number (default 1)\n\
 	-c P: 1 in P chance of file close+open at each op (default infinity)\n\
 	-d: debug output for all operations\n\
 	-f: flush and invalidate cache after I/O\n\
 	-h holebdy: 4096 would make discards page aligned (default 1)\n\
+	-j: journal replay stress test\n\
 	-l flen: the upper bound on file size (default 262144)\n\
 	-m startop:endop: monitor (print debug output) specified byte range (default 0:infinity)\n\
 	-n: no verifications of file size\n\
@@ -2111,6 +2394,49 @@ test_fallocate()
 
 }
 
+void remove_image(rados_ioctx_t ioctx, char *imagename, bool remove_snap,
+                  bool unregister) {
+	rbd_image_t image;
+	char errmsg[128];
+        int ret;
+
+	if ((ret = rbd_open(ioctx, imagename, &image, NULL)) < 0) {
+		sprintf(errmsg, "rbd_open %s", imagename);
+		prterrcode(errmsg, ret);
+		report_failure(101);
+	}
+	if (remove_snap) {
+		if ((ret = rbd_snap_unprotect(image, "snap")) < 0) {
+			sprintf(errmsg, "rbd_snap_unprotect %s at snap",
+				imagename);
+			prterrcode(errmsg, ret);
+			report_failure(102);
+		}
+		if ((ret = rbd_snap_remove(image, "snap")) < 0) {
+			sprintf(errmsg, "rbd_snap_remove %s at snap",
+				imagename);
+			prterrcode(errmsg, ret);
+			report_failure(103);
+		}
+	}
+	if ((ret = rbd_close(image)) < 0) {
+		sprintf(errmsg, "rbd_close %s", imagename);
+		prterrcode(errmsg, ret);
+		report_failure(104);
+	}
+
+        if (unregister &&
+            (ret = unregister_journal(ioctx, imagename)) < 0) {
+                report_failure(105);
+        }
+
+	if ((ret = rbd_remove(ioctx, imagename)) < 0) {
+		sprintf(errmsg, "rbd_remove %s", imagename);
+		prterrcode(errmsg, ret);
+		report_failure(106);
+	}
+}
+
 int
 main(int argc, char **argv)
 {
@@ -2128,7 +2454,7 @@ main(int argc, char **argv)
 
 	setvbuf(stdout, (char *)0, _IOLBF, 0); /* line buffered stdout */
 
-	while ((ch = getopt(argc, argv, "b:c:dfh:l:m:no:p:qr:s:t:w:xyACD:FHKMLN:OP:RS:UWZ"))
+	while ((ch = getopt(argc, argv, "b:c:dfh:jl:m:no:p:qr:s:t:w:xyACD:FHKMLN:OP:RS:UWZ"))
 	       != EOF)
 		switch (ch) {
 		case 'b':
@@ -2153,13 +2479,16 @@ main(int argc, char **argv)
 			debug = 1;
 			break;
 		case 'f':
-			flush = 1;
+			flush_enabled = 1;
 			break;
 		case 'h':
 			holebdy = getnum(optarg, &endp);
 			if (holebdy <= 0)
 				usage();
 			break;
+                case 'j':
+                        journal_replay = true;
+                        break;
 		case 'l':
 			{
 				int _num = getnum(optarg, &endp);
@@ -2416,48 +2745,38 @@ main(int argc, char **argv)
 		report_failure(99);
 	}
 
-	if (num_clones > 0)
-		check_clone(num_clones - 1);
+        if (journal_replay) {
+                char imagename[1024];
+	        clone_imagename(imagename, sizeof(imagename), num_clones);
+                ret = finalize_journal(ioctx, imagename, num_clones, 0, 0, 0);
+                if (ret < 0) {
+                        report_failure(100);
+                }
+        }
+
+	if (num_clones > 0) {
+                if (journal_replay) {
+		        check_clone(num_clones - 1, true);
+                }
+		check_clone(num_clones - 1, false);
+        }
 
 	while (num_clones >= 0) {
-		static int first = 1;
-		rbd_image_t image;
-		char clonename[128];
-		char errmsg[128];
+		static bool remove_snap = false;
 
-		clone_imagename(clonename, 128, num_clones);
-		if ((ret = rbd_open(ioctx, clonename, &image, NULL)) < 0) {
-			sprintf(errmsg, "rbd_open %s", clonename);
-			prterrcode(errmsg, ret);
-			report_failure(101);
-		}
-		if (!first) {
-			if ((ret = rbd_snap_unprotect(image, "snap")) < 0) {
-				sprintf(errmsg, "rbd_snap_unprotect %s at snap",
-					clonename);
-				prterrcode(errmsg, ret);
-				report_failure(102);
-			}
-			if ((ret = rbd_snap_remove(image, "snap")) < 0) {
-				sprintf(errmsg, "rbd_snap_remove %s at snap",
-					clonename);
-				prterrcode(errmsg, ret);
-				report_failure(103);
-			}
-		}
-		if ((ret = rbd_close(image)) < 0) {
-			sprintf(errmsg, "rbd_close %s", clonename);
-			prterrcode(errmsg, ret);
-			report_failure(104);
-		}
+                if (journal_replay) {
+                        char replayimagename[1024];
+                        replay_imagename(replayimagename,
+                                         sizeof(replayimagename), num_clones);
+                        remove_image(ioctx, replayimagename, remove_snap,
+                                     false);
+                }
 
-		if ((ret = rbd_remove(ioctx, clonename)) < 0) {
-			sprintf(errmsg, "rbd_remove %s", clonename);
-			prterrcode(errmsg, ret);
-			report_failure(105);
-		}
+		char clonename[128];
+		clone_imagename(clonename, 128, num_clones);
+                remove_image(ioctx, clonename, remove_snap, journal_replay);
 
-		first = 0;
+                remove_snap = true;
 		num_clones--;
 	}
 
diff --git a/src/test/librbd/image/test_mock_RefreshRequest.cc b/src/test/librbd/image/test_mock_RefreshRequest.cc
index 6d8791f..e362986 100644
--- a/src/test/librbd/image/test_mock_RefreshRequest.cc
+++ b/src/test/librbd/image/test_mock_RefreshRequest.cc
@@ -8,6 +8,7 @@
 #include "test/librbd/mock/MockObjectMap.h"
 #include "test/librados_test_stub/MockTestMemIoCtxImpl.h"
 #include "test/librados_test_stub/MockTestMemRadosClient.h"
+#include "librbd/ImageState.h"
 #include "librbd/internal.h"
 #include "librbd/Operations.h"
 #include "librbd/image/RefreshRequest.h"
@@ -19,19 +20,29 @@
 #include <boost/scope_exit.hpp>
 
 namespace librbd {
+
+namespace {
+
+struct MockRefreshImageCtx : public MockImageCtx {
+  MockRefreshImageCtx(ImageCtx &image_ctx) : MockImageCtx(image_ctx) {
+  }
+};
+
+} // anonymous namespace
+
 namespace image {
 
 template <>
-struct RefreshParentRequest<MockImageCtx> {
+struct RefreshParentRequest<MockRefreshImageCtx> {
   static RefreshParentRequest* s_instance;
-  static RefreshParentRequest* create(MockImageCtx &mock_image_ctx,
+  static RefreshParentRequest* create(MockRefreshImageCtx &mock_image_ctx,
                                       const parent_info& parent_md,
                                       Context *on_finish) {
     assert(s_instance != nullptr);
     s_instance->on_finish = on_finish;
     return s_instance;
   }
-  static bool is_refresh_required(MockImageCtx &mock_image_ctx,
+  static bool is_refresh_required(MockRefreshImageCtx &mock_image_ctx,
                                   const parent_info& parent_md) {
     assert(s_instance != nullptr);
     return s_instance->is_refresh_required();
@@ -49,14 +60,14 @@ struct RefreshParentRequest<MockImageCtx> {
   MOCK_METHOD1(finalize, void(Context *));
 };
 
-RefreshParentRequest<MockImageCtx>* RefreshParentRequest<MockImageCtx>::s_instance = nullptr;
+RefreshParentRequest<MockRefreshImageCtx>* RefreshParentRequest<MockRefreshImageCtx>::s_instance = nullptr;
 
 } // namespace image
 } // namespace librbd
 
 // template definitions
 #include "librbd/image/RefreshRequest.cc"
-template class librbd::image::RefreshRequest<librbd::MockImageCtx>;
+template class librbd::image::RefreshRequest<librbd::MockRefreshImageCtx>;
 
 ACTION_P(TestFeatures, image_ctx) {
   return ((image_ctx->features & arg0) != 0);
@@ -76,13 +87,23 @@ using ::testing::DoAll;
 using ::testing::DoDefault;
 using ::testing::InSequence;
 using ::testing::Return;
+using ::testing::WithArg;
+using ::testing::StrEq;
 
 class TestMockImageRefreshRequest : public TestMockFixture {
 public:
-  typedef RefreshRequest<MockImageCtx> MockRefreshRequest;
-  typedef RefreshParentRequest<MockImageCtx> MockRefreshParentRequest;
+  typedef RefreshRequest<MockRefreshImageCtx> MockRefreshRequest;
+  typedef RefreshParentRequest<MockRefreshImageCtx> MockRefreshParentRequest;
 
-  void expect_v1_read_header(MockImageCtx &mock_image_ctx, int r) {
+  void expect_set_require_lock_on_read(MockRefreshImageCtx &mock_image_ctx) {
+    EXPECT_CALL(*mock_image_ctx.aio_work_queue, set_require_lock_on_read());
+  }
+
+  void expect_clear_require_lock_on_read(MockRefreshImageCtx &mock_image_ctx) {
+    EXPECT_CALL(*mock_image_ctx.aio_work_queue, clear_require_lock_on_read());
+  }
+
+  void expect_v1_read_header(MockRefreshImageCtx &mock_image_ctx, int r) {
     auto &expect = EXPECT_CALL(get_mock_io_ctx(mock_image_ctx.md_ctx),
                                read(mock_image_ctx.header_oid, _, _, _));
     if (r < 0) {
@@ -92,9 +113,9 @@ public:
     }
   }
 
-  void expect_v1_get_snapshots(MockImageCtx &mock_image_ctx, int r) {
+  void expect_v1_get_snapshots(MockRefreshImageCtx &mock_image_ctx, int r) {
     auto &expect = EXPECT_CALL(get_mock_io_ctx(mock_image_ctx.md_ctx),
-                               exec(mock_image_ctx.header_oid, _, "rbd", "snap_list", _, _, _));
+                               exec(mock_image_ctx.header_oid, _, StrEq("rbd"), StrEq("snap_list"), _, _, _));
     if (r < 0) {
       expect.WillOnce(Return(r));
     } else {
@@ -102,9 +123,9 @@ public:
     }
   }
 
-  void expect_v1_get_locks(MockImageCtx &mock_image_ctx, int r) {
+  void expect_v1_get_locks(MockRefreshImageCtx &mock_image_ctx, int r) {
     auto &expect = EXPECT_CALL(get_mock_io_ctx(mock_image_ctx.md_ctx),
-                               exec(mock_image_ctx.header_oid, _, "lock", "get_info", _, _, _));
+                               exec(mock_image_ctx.header_oid, _, StrEq("lock"), StrEq("get_info"), _, _, _));
     if (r < 0) {
       expect.WillOnce(Return(r));
     } else {
@@ -112,31 +133,31 @@ public:
     }
   }
 
-  void expect_get_mutable_metadata(MockImageCtx &mock_image_ctx, int r) {
+  void expect_get_mutable_metadata(MockRefreshImageCtx &mock_image_ctx, int r) {
     auto &expect = EXPECT_CALL(get_mock_io_ctx(mock_image_ctx.md_ctx),
-                               exec(mock_image_ctx.header_oid, _, "rbd", "get_size", _, _, _));
+                               exec(mock_image_ctx.header_oid, _, StrEq("rbd"), StrEq("get_size"), _, _, _));
     if (r < 0) {
       expect.WillOnce(Return(r));
     } else {
       expect.WillOnce(DoDefault());
       EXPECT_CALL(get_mock_io_ctx(mock_image_ctx.md_ctx),
-                  exec(mock_image_ctx.header_oid, _, "rbd", "get_features", _, _, _))
+                  exec(mock_image_ctx.header_oid, _, StrEq("rbd"), StrEq("get_features"), _, _, _))
                     .WillOnce(DoDefault());
       EXPECT_CALL(get_mock_io_ctx(mock_image_ctx.md_ctx),
-                  exec(mock_image_ctx.header_oid, _, "rbd", "get_snapcontext", _, _, _))
+                  exec(mock_image_ctx.header_oid, _, StrEq("rbd"), StrEq("get_snapcontext"), _, _, _))
                     .WillOnce(DoDefault());
       EXPECT_CALL(get_mock_io_ctx(mock_image_ctx.md_ctx),
-                  exec(mock_image_ctx.header_oid, _, "rbd", "get_parent", _, _, _))
+                  exec(mock_image_ctx.header_oid, _, StrEq("rbd"), StrEq("get_parent"), _, _, _))
                     .WillOnce(DoDefault());
       EXPECT_CALL(get_mock_io_ctx(mock_image_ctx.md_ctx),
-                  exec(mock_image_ctx.header_oid, _, "lock", "get_info", _, _, _))
+                  exec(mock_image_ctx.header_oid, _, StrEq("lock"), StrEq("get_info"), _, _, _))
                     .WillOnce(DoDefault());
     }
   }
 
-  void expect_get_flags(MockImageCtx &mock_image_ctx, int r) {
+  void expect_get_flags(MockRefreshImageCtx &mock_image_ctx, int r) {
     auto &expect = EXPECT_CALL(get_mock_io_ctx(mock_image_ctx.md_ctx),
-                               exec(mock_image_ctx.header_oid, _, "rbd", "get_flags", _, _, _));
+                               exec(mock_image_ctx.header_oid, _, StrEq("rbd"), StrEq("get_flags"), _, _, _));
     if (r < 0) {
       expect.WillOnce(Return(r));
     } else {
@@ -144,40 +165,40 @@ public:
     }
   }
 
-  void expect_get_snapshots(MockImageCtx &mock_image_ctx, int r) {
+  void expect_get_snapshots(MockRefreshImageCtx &mock_image_ctx, int r) {
     auto &expect = EXPECT_CALL(get_mock_io_ctx(mock_image_ctx.md_ctx),
-                               exec(mock_image_ctx.header_oid, _, "rbd", "get_snapshot_name", _, _, _));
+                               exec(mock_image_ctx.header_oid, _, StrEq("rbd"), StrEq("get_snapshot_name"), _, _, _));
     if (r < 0) {
       expect.WillOnce(Return(r));
     } else {
       expect.WillOnce(DoDefault());
       EXPECT_CALL(get_mock_io_ctx(mock_image_ctx.md_ctx),
-                  exec(mock_image_ctx.header_oid, _, "rbd", "get_size", _, _, _))
+                  exec(mock_image_ctx.header_oid, _, StrEq("rbd"), StrEq("get_size"), _, _, _))
                     .WillOnce(DoDefault());
       EXPECT_CALL(get_mock_io_ctx(mock_image_ctx.md_ctx),
-                  exec(mock_image_ctx.header_oid, _, "rbd", "get_parent", _, _, _))
+                  exec(mock_image_ctx.header_oid, _, StrEq("rbd"), StrEq("get_parent"), _, _, _))
                     .WillOnce(DoDefault());
       EXPECT_CALL(get_mock_io_ctx(mock_image_ctx.md_ctx),
-                  exec(mock_image_ctx.header_oid, _, "rbd", "get_protection_status", _, _, _))
+                  exec(mock_image_ctx.header_oid, _, StrEq("rbd"), StrEq("get_protection_status"), _, _, _))
                     .WillOnce(DoDefault());
     }
   }
 
-  void expect_add_snap(MockImageCtx &mock_image_ctx,
+  void expect_add_snap(MockRefreshImageCtx &mock_image_ctx,
                        const std::string &snap_name, uint64_t snap_id) {
     EXPECT_CALL(mock_image_ctx, add_snap(snap_name, snap_id, _, _, _, _));
   }
 
-  void expect_init_exclusive_lock(MockImageCtx &mock_image_ctx,
+  void expect_init_exclusive_lock(MockRefreshImageCtx &mock_image_ctx,
                                   MockExclusiveLock &mock_exclusive_lock,
                                   int r) {
     EXPECT_CALL(mock_image_ctx, create_exclusive_lock())
                   .WillOnce(Return(&mock_exclusive_lock));
-    EXPECT_CALL(mock_exclusive_lock, init(_))
-                  .WillOnce(CompleteContext(r, mock_image_ctx.image_ctx->op_work_queue));
+    EXPECT_CALL(mock_exclusive_lock, init(mock_image_ctx.features, _))
+                  .WillOnce(WithArg<1>(CompleteContext(r, mock_image_ctx.image_ctx->op_work_queue)));
   }
 
-  void expect_shut_down_exclusive_lock(MockImageCtx &mock_image_ctx,
+  void expect_shut_down_exclusive_lock(MockRefreshImageCtx &mock_image_ctx,
                                        MockExclusiveLock &mock_exclusive_lock,
                                        int r) {
     EXPECT_CALL(mock_exclusive_lock, shut_down(_))
@@ -185,11 +206,11 @@ public:
                                   CompleteContext(r, mock_image_ctx.image_ctx->op_work_queue)));
   }
 
-  void expect_init_layout(MockImageCtx &mock_image_ctx) {
+  void expect_init_layout(MockRefreshImageCtx &mock_image_ctx) {
     EXPECT_CALL(mock_image_ctx, init_layout());
   }
 
-  void expect_test_features(MockImageCtx &mock_image_ctx) {
+  void expect_test_features(MockRefreshImageCtx &mock_image_ctx) {
     EXPECT_CALL(mock_image_ctx, test_features(_, _))
                   .WillRepeatedly(TestFeatures(&mock_image_ctx));
   }
@@ -200,7 +221,7 @@ public:
                   .WillRepeatedly(Return(required));
   }
 
-  void expect_refresh_parent_send(MockImageCtx &mock_image_ctx,
+  void expect_refresh_parent_send(MockRefreshImageCtx &mock_image_ctx,
                                   MockRefreshParentRequest &mock_refresh_parent_request,
                                   int r) {
     EXPECT_CALL(mock_refresh_parent_request, send())
@@ -212,7 +233,7 @@ public:
     EXPECT_CALL(mock_refresh_parent_request, apply());
   }
 
-  void expect_refresh_parent_finalize(MockImageCtx &mock_image_ctx,
+  void expect_refresh_parent_finalize(MockRefreshImageCtx &mock_image_ctx,
                                       MockRefreshParentRequest &mock_refresh_parent_request,
                                       int r) {
     EXPECT_CALL(mock_refresh_parent_request, finalize(_))
@@ -224,7 +245,7 @@ public:
     EXPECT_CALL(mock_exclusive_lock, is_lock_owner()).WillOnce(Return(is_owner));
   }
 
-  void expect_open_journal(MockImageCtx &mock_image_ctx,
+  void expect_open_journal(MockRefreshImageCtx &mock_image_ctx,
                            MockJournal &mock_journal, int r) {
     EXPECT_CALL(mock_image_ctx, create_journal())
                   .WillOnce(Return(&mock_journal));
@@ -232,13 +253,13 @@ public:
                   .WillOnce(CompleteContext(r, mock_image_ctx.image_ctx->op_work_queue));
   }
 
-  void expect_close_journal(MockImageCtx &mock_image_ctx,
+  void expect_close_journal(MockRefreshImageCtx &mock_image_ctx,
                             MockJournal &mock_journal, int r) {
     EXPECT_CALL(mock_journal, close(_))
                   .WillOnce(CompleteContext(r, mock_image_ctx.image_ctx->op_work_queue));
   }
 
-  void expect_open_object_map(MockImageCtx &mock_image_ctx,
+  void expect_open_object_map(MockRefreshImageCtx &mock_image_ctx,
                               MockObjectMap &mock_object_map, int r) {
     EXPECT_CALL(mock_image_ctx, create_object_map(_))
                   .WillOnce(Return(&mock_object_map));
@@ -246,13 +267,13 @@ public:
                   .WillOnce(CompleteContext(r, mock_image_ctx.image_ctx->op_work_queue));
   }
 
-  void expect_close_object_map(MockImageCtx &mock_image_ctx,
+  void expect_close_object_map(MockRefreshImageCtx &mock_image_ctx,
                                MockObjectMap &mock_object_map, int r) {
     EXPECT_CALL(mock_object_map, close(_))
                   .WillOnce(CompleteContext(r, mock_image_ctx.image_ctx->op_work_queue));
   }
 
-  void expect_get_snap_id(MockImageCtx &mock_image_ctx,
+  void expect_get_snap_id(MockRefreshImageCtx &mock_image_ctx,
                           const std::string &snap_name, uint64_t snap_id) {
     EXPECT_CALL(mock_image_ctx, get_snap_id(snap_name)).WillOnce(Return(snap_id));
   }
@@ -264,7 +285,7 @@ TEST_F(TestMockImageRefreshRequest, SuccessV1) {
   librbd::ImageCtx *ictx;
   ASSERT_EQ(0, open_image(m_image_name, &ictx));
 
-  MockImageCtx mock_image_ctx(*ictx);
+  MockRefreshImageCtx mock_image_ctx(*ictx);
   expect_op_work_queue(mock_image_ctx);
   expect_test_features(mock_image_ctx);
 
@@ -287,8 +308,9 @@ TEST_F(TestMockImageRefreshRequest, SuccessSnapshotV1) {
   librbd::ImageCtx *ictx;
   ASSERT_EQ(0, open_image(m_image_name, &ictx));
   ASSERT_EQ(0, snap_create(*ictx, "snap"));
+  ASSERT_EQ(0, ictx->state->refresh());
 
-  MockImageCtx mock_image_ctx(*ictx);
+  MockRefreshImageCtx mock_image_ctx(*ictx);
   expect_op_work_queue(mock_image_ctx);
   expect_test_features(mock_image_ctx);
 
@@ -312,7 +334,7 @@ TEST_F(TestMockImageRefreshRequest, SuccessV2) {
   librbd::ImageCtx *ictx;
   ASSERT_EQ(0, open_image(m_image_name, &ictx));
 
-  MockImageCtx mock_image_ctx(*ictx);
+  MockRefreshImageCtx mock_image_ctx(*ictx);
   MockRefreshParentRequest mock_refresh_parent_request;
   MockExclusiveLock mock_exclusive_lock;
   expect_op_work_queue(mock_image_ctx);
@@ -340,7 +362,7 @@ TEST_F(TestMockImageRefreshRequest, SuccessSnapshotV2) {
   ASSERT_EQ(0, open_image(m_image_name, &ictx));
   ASSERT_EQ(0, snap_create(*ictx, "snap"));
 
-  MockImageCtx mock_image_ctx(*ictx);
+  MockRefreshImageCtx mock_image_ctx(*ictx);
   MockRefreshParentRequest mock_refresh_parent_request;
   MockExclusiveLock mock_exclusive_lock;
   expect_op_work_queue(mock_image_ctx);
@@ -372,7 +394,7 @@ TEST_F(TestMockImageRefreshRequest, SuccessSetSnapshotV2) {
   ASSERT_EQ(0, snap_create(*ictx, "snap"));
   ASSERT_EQ(0, librbd::snap_set(ictx, "snap"));
 
-  MockImageCtx mock_image_ctx(*ictx);
+  MockRefreshImageCtx mock_image_ctx(*ictx);
   MockRefreshParentRequest mock_refresh_parent_request;
   MockObjectMap mock_object_map;
   expect_op_work_queue(mock_image_ctx);
@@ -423,7 +445,7 @@ TEST_F(TestMockImageRefreshRequest, SuccessChild) {
 
   ASSERT_EQ(0, open_image(clone_name, &ictx2));
 
-  MockImageCtx mock_image_ctx(*ictx2);
+  MockRefreshImageCtx mock_image_ctx(*ictx2);
   MockRefreshParentRequest *mock_refresh_parent_request = new MockRefreshParentRequest();
   MockExclusiveLock mock_exclusive_lock;
   expect_op_work_queue(mock_image_ctx);
@@ -453,7 +475,7 @@ TEST_F(TestMockImageRefreshRequest, DisableExclusiveLock) {
   librbd::ImageCtx *ictx;
   ASSERT_EQ(0, open_image(m_image_name, &ictx));
 
-  MockImageCtx mock_image_ctx(*ictx);
+  MockRefreshImageCtx mock_image_ctx(*ictx);
   MockRefreshParentRequest mock_refresh_parent_request;
 
   MockExclusiveLock *mock_exclusive_lock = new MockExclusiveLock();
@@ -503,7 +525,7 @@ TEST_F(TestMockImageRefreshRequest, EnableJournalWithExclusiveLock) {
                                RBD_FEATURE_OBJECT_MAP |
                                RBD_FEATURE_FAST_DIFF, false));
 
-  MockImageCtx mock_image_ctx(*ictx);
+  MockRefreshImageCtx mock_image_ctx(*ictx);
   MockRefreshParentRequest mock_refresh_parent_request;
 
   MockExclusiveLock mock_exclusive_lock;
@@ -539,7 +561,7 @@ TEST_F(TestMockImageRefreshRequest, EnableJournalWithoutExclusiveLock) {
                                RBD_FEATURE_OBJECT_MAP |
                                RBD_FEATURE_FAST_DIFF, false));
 
-  MockImageCtx mock_image_ctx(*ictx);
+  MockRefreshImageCtx mock_image_ctx(*ictx);
   MockRefreshParentRequest mock_refresh_parent_request;
 
   MockExclusiveLock mock_exclusive_lock;
@@ -554,6 +576,7 @@ TEST_F(TestMockImageRefreshRequest, EnableJournalWithoutExclusiveLock) {
   expect_get_mutable_metadata(mock_image_ctx, 0);
   expect_get_flags(mock_image_ctx, 0);
   expect_refresh_parent_is_required(mock_refresh_parent_request, false);
+  expect_set_require_lock_on_read(mock_image_ctx);
 
   C_SaferCond ctx;
   MockRefreshRequest *req = new MockRefreshRequest(mock_image_ctx, &ctx);
@@ -568,7 +591,7 @@ TEST_F(TestMockImageRefreshRequest, DisableJournal) {
   librbd::ImageCtx *ictx;
   ASSERT_EQ(0, open_image(m_image_name, &ictx));
 
-  MockImageCtx mock_image_ctx(*ictx);
+  MockRefreshImageCtx mock_image_ctx(*ictx);
   MockRefreshParentRequest mock_refresh_parent_request;
 
   MockExclusiveLock mock_exclusive_lock;
@@ -592,6 +615,7 @@ TEST_F(TestMockImageRefreshRequest, DisableJournal) {
   expect_get_mutable_metadata(mock_image_ctx, 0);
   expect_get_flags(mock_image_ctx, 0);
   expect_refresh_parent_is_required(mock_refresh_parent_request, false);
+  expect_clear_require_lock_on_read(mock_image_ctx);
   expect_close_journal(mock_image_ctx, *mock_journal, 0);
 
   C_SaferCond ctx;
@@ -609,7 +633,7 @@ TEST_F(TestMockImageRefreshRequest, EnableObjectMapWithExclusiveLock) {
 
   ASSERT_EQ(0, update_features(ictx, RBD_FEATURE_JOURNALING, false));
 
-  MockImageCtx mock_image_ctx(*ictx);
+  MockRefreshImageCtx mock_image_ctx(*ictx);
   MockRefreshParentRequest mock_refresh_parent_request;
 
   MockExclusiveLock mock_exclusive_lock;
@@ -643,7 +667,7 @@ TEST_F(TestMockImageRefreshRequest, EnableObjectMapWithoutExclusiveLock) {
 
   ASSERT_EQ(0, update_features(ictx, RBD_FEATURE_JOURNALING, false));
 
-  MockImageCtx mock_image_ctx(*ictx);
+  MockRefreshImageCtx mock_image_ctx(*ictx);
   MockRefreshParentRequest mock_refresh_parent_request;
 
   MockExclusiveLock mock_exclusive_lock;
@@ -672,7 +696,7 @@ TEST_F(TestMockImageRefreshRequest, DisableObjectMap) {
   librbd::ImageCtx *ictx;
   ASSERT_EQ(0, open_image(m_image_name, &ictx));
 
-  MockImageCtx mock_image_ctx(*ictx);
+  MockRefreshImageCtx mock_image_ctx(*ictx);
   MockRefreshParentRequest mock_refresh_parent_request;
 
   MockExclusiveLock mock_exclusive_lock;
diff --git a/src/test/librbd/journal/test_Replay.cc b/src/test/librbd/journal/test_Replay.cc
index c144cbf..1f822d6 100644
--- a/src/test/librbd/journal/test_Replay.cc
+++ b/src/test/librbd/journal/test_Replay.cc
@@ -1,15 +1,21 @@
-// -*- mode:C; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
 // vim: ts=8 sw=2 smarttab
 
 #include "test/librbd/test_fixture.h"
 #include "test/librbd/test_support.h"
+#include "cls/journal/cls_journal_types.h"
+#include "cls/journal/cls_journal_client.h"
+#include "journal/Journaler.h"
 #include "librbd/AioCompletion.h"
 #include "librbd/AioImageRequest.h"
 #include "librbd/AioImageRequestWQ.h"
 #include "librbd/ExclusiveLock.h"
 #include "librbd/ImageCtx.h"
+#include "librbd/ImageState.h"
 #include "librbd/ImageWatcher.h"
+#include "librbd/internal.h"
 #include "librbd/Journal.h"
+#include "librbd/Operations.h"
 #include "librbd/journal/Types.h"
 
 void register_test_journal_replay() {
@@ -26,6 +32,61 @@ public:
     }
     return lock_ctx.wait();
   }
+
+  template<typename T>
+  void inject_into_journal(librbd::ImageCtx *ictx, T event) {
+
+    librbd::journal::EventEntry event_entry(event);
+    librbd::Journal<>::AioObjectRequests requests;
+    {
+      RWLock::RLocker owner_locker(ictx->owner_lock);
+      ictx->journal->append_io_event(NULL, std::move(event_entry), requests, 0,
+				     0, true);
+    }
+  }
+
+  void get_journal_commit_position(librbd::ImageCtx *ictx, int64_t *tag,
+                                   int64_t *entry)
+  {
+    const std::string client_id = "";
+    std::string journal_id = ictx->id;
+
+    C_SaferCond close_cond;
+    ictx->journal->close(&close_cond);
+    ASSERT_EQ(0, close_cond.wait());
+    delete ictx->journal;
+    ictx->journal = nullptr;
+
+    C_SaferCond cond;
+    uint64_t minimum_set;
+    uint64_t active_set;
+    std::set<cls::journal::Client> registered_clients;
+    std::string oid = ::journal::Journaler::header_oid(journal_id);
+    cls::journal::client::get_mutable_metadata(ictx->md_ctx, oid, &minimum_set,
+	&active_set, &registered_clients, &cond);
+    ASSERT_EQ(0, cond.wait());
+    std::set<cls::journal::Client>::const_iterator c;
+    for (c = registered_clients.begin(); c != registered_clients.end(); ++c) {
+      if (c->id == client_id) {
+	break;
+      }
+    }
+    if (c == registered_clients.end() ||
+        c->commit_position.object_positions.empty()) {
+      *tag = 0;
+      *entry = -1;
+    } else {
+      const cls::journal::ObjectPosition &object_position =
+        *c->commit_position.object_positions.begin();
+      *tag = object_position.tag_tid;
+      *entry = object_position.entry_tid;
+    }
+
+    C_SaferCond open_cond;
+    ictx->journal = new librbd::Journal<>(*ictx);
+    ictx->journal->open(&open_cond);
+    ASSERT_EQ(0, open_cond.wait());
+  }
 };
 
 TEST_F(TestJournalReplay, AioDiscardEvent) {
@@ -57,18 +118,17 @@ TEST_F(TestJournalReplay, AioDiscardEvent) {
   ASSERT_EQ(payload, read_payload);
   close_image(ictx);
 
-  // inject a discard operation into the journal
   ASSERT_EQ(0, open_image(m_image_name, &ictx));
   ASSERT_EQ(0, when_acquired_lock(ictx));
 
-  librbd::journal::EventEntry event_entry(
-    librbd::journal::AioDiscardEvent(0, payload.size()));
-  librbd::Journal<>::AioObjectRequests requests;
-  {
-    RWLock::RLocker owner_locker(ictx->owner_lock);
-    ictx->journal->append_io_event(NULL, std::move(event_entry), requests, 0, 0,
-                                   true);
-  }
+  // get current commit position
+  int64_t initial_tag;
+  int64_t initial_entry;
+  get_journal_commit_position(ictx, &initial_tag, &initial_entry);
+
+  // inject a discard operation into the journal
+  inject_into_journal(ictx,
+                      librbd::journal::AioDiscardEvent(0, payload.size()));
 
   // re-open the journal so that it replays the new entry
   ASSERT_EQ(0, open_image(m_image_name, &ictx));
@@ -80,27 +140,50 @@ TEST_F(TestJournalReplay, AioDiscardEvent) {
   ASSERT_EQ(0, aio_comp->wait_for_complete());
   aio_comp->release();
   ASSERT_EQ(std::string(read_payload.size(), '\0'), read_payload);
+
+  // check the commit position is properly updated
+  int64_t current_tag;
+  int64_t current_entry;
+  get_journal_commit_position(ictx, &current_tag, &current_entry);
+  ASSERT_EQ(initial_tag + 1, current_tag);
+  ASSERT_EQ(0, current_entry);
+
+  // replay several envents and check the commit position
+  inject_into_journal(ictx,
+                      librbd::journal::AioDiscardEvent(0, payload.size()));
+  inject_into_journal(ictx,
+                      librbd::journal::AioDiscardEvent(0, payload.size()));
+  ASSERT_EQ(0, open_image(m_image_name, &ictx));
+  ASSERT_EQ(0, when_acquired_lock(ictx));
+  get_journal_commit_position(ictx, &current_tag, &current_entry);
+  ASSERT_EQ(initial_tag + 2, current_tag);
+  ASSERT_EQ(1, current_entry);
+
+  // verify lock ordering constraints
+  aio_comp = new librbd::AioCompletion();
+  ictx->aio_work_queue->aio_discard(aio_comp, 0, read_payload.size());
+  ASSERT_EQ(0, aio_comp->wait_for_complete());
+  aio_comp->release();
 }
 
 TEST_F(TestJournalReplay, AioWriteEvent) {
   REQUIRE_FEATURE(RBD_FEATURE_JOURNALING);
 
-  // inject a write operation into the journal
   librbd::ImageCtx *ictx;
   ASSERT_EQ(0, open_image(m_image_name, &ictx));
   ASSERT_EQ(0, when_acquired_lock(ictx));
 
+  // get current commit position
+  int64_t initial_tag;
+  int64_t initial_entry;
+  get_journal_commit_position(ictx, &initial_tag, &initial_entry);
+
+  // inject a write operation into the journal
   std::string payload(4096, '1');
   bufferlist payload_bl;
   payload_bl.append(payload);
-  librbd::journal::EventEntry event_entry(
-    librbd::journal::AioWriteEvent(0, payload.size(), payload_bl));
-  librbd::Journal<>::AioObjectRequests requests;
-  {
-    RWLock::RLocker owner_locker(ictx->owner_lock);
-    ictx->journal->append_io_event(NULL, std::move(event_entry), requests, 0, 0,
-                                   true);
-  }
+  inject_into_journal(ictx,
+      librbd::journal::AioWriteEvent(0, payload.size(), payload_bl));
 
   // re-open the journal so that it replays the new entry
   ASSERT_EQ(0, open_image(m_image_name, &ictx));
@@ -113,25 +196,48 @@ TEST_F(TestJournalReplay, AioWriteEvent) {
   ASSERT_EQ(0, aio_comp->wait_for_complete());
   aio_comp->release();
   ASSERT_EQ(payload, read_payload);
+
+  // check the commit position is properly updated
+  int64_t current_tag;
+  int64_t current_entry;
+  get_journal_commit_position(ictx, &current_tag, &current_entry);
+  ASSERT_EQ(initial_tag + 1, current_tag);
+  ASSERT_EQ(0, current_entry);
+
+  // replay several events and check the commit position
+  inject_into_journal(ictx,
+      librbd::journal::AioWriteEvent(0, payload.size(), payload_bl));
+  inject_into_journal(ictx,
+      librbd::journal::AioWriteEvent(0, payload.size(), payload_bl));
+  ASSERT_EQ(0, open_image(m_image_name, &ictx));
+  ASSERT_EQ(0, when_acquired_lock(ictx));
+  get_journal_commit_position(ictx, &current_tag, &current_entry);
+  ASSERT_EQ(initial_tag + 2, current_tag);
+  ASSERT_EQ(1, current_entry);
+
+  // verify lock ordering constraints
+  aio_comp = new librbd::AioCompletion();
+  ictx->aio_work_queue->aio_write(aio_comp, 0, payload.size(), payload.c_str(),
+                                  0);
+  ASSERT_EQ(0, aio_comp->wait_for_complete());
+  aio_comp->release();
 }
 
 TEST_F(TestJournalReplay, AioFlushEvent) {
   REQUIRE_FEATURE(RBD_FEATURE_JOURNALING);
 
-  // inject a flush operation into the journal
   librbd::ImageCtx *ictx;
 
   ASSERT_EQ(0, open_image(m_image_name, &ictx));
   ASSERT_EQ(0, when_acquired_lock(ictx));
 
-  librbd::journal::AioFlushEvent aio_flush_event;
-  librbd::journal::EventEntry event_entry(aio_flush_event);
-  librbd::Journal<>::AioObjectRequests requests;
-  {
-    RWLock::RLocker owner_locker(ictx->owner_lock);
-    ictx->journal->append_io_event(NULL, std::move(event_entry), requests, 0, 0,
-                                   true);
-  }
+  // get current commit position
+  int64_t initial_tag;
+  int64_t initial_entry;
+  get_journal_commit_position(ictx, &initial_tag, &initial_entry);
+
+  // inject a flush operation into the journal
+  inject_into_journal(ictx, librbd::journal::AioFlushEvent());
 
   // start an AIO write op
   librbd::Journal<> *journal = ictx->journal;
@@ -161,5 +267,423 @@ TEST_F(TestJournalReplay, AioFlushEvent) {
   ASSERT_EQ(0, aio_comp->wait_for_complete());
   aio_comp->release();
   ASSERT_EQ(payload, read_payload);
+
+  // check the commit position is properly updated
+  int64_t current_tag;
+  int64_t current_entry;
+  get_journal_commit_position(ictx, &current_tag, &current_entry);
+  ASSERT_EQ(initial_tag + 1, current_tag);
+  ASSERT_EQ(0, current_entry);
+
+  // replay several events and check the commit position
+  inject_into_journal(ictx, librbd::journal::AioFlushEvent());
+  inject_into_journal(ictx, librbd::journal::AioFlushEvent());
+  ASSERT_EQ(0, open_image(m_image_name, &ictx));
+  ASSERT_EQ(0, when_acquired_lock(ictx));
+  get_journal_commit_position(ictx, &current_tag, &current_entry);
+  ASSERT_EQ(initial_tag + 2, current_tag);
+  ASSERT_EQ(1, current_entry);
+
+  // verify lock ordering constraints
+  aio_comp = new librbd::AioCompletion();
+  ictx->aio_work_queue->aio_flush(aio_comp);
+  ASSERT_EQ(0, aio_comp->wait_for_complete());
+  aio_comp->release();
+}
+
+TEST_F(TestJournalReplay, SnapCreate) {
+  REQUIRE_FEATURE(RBD_FEATURE_JOURNALING);
+
+  librbd::ImageCtx *ictx;
+
+  ASSERT_EQ(0, open_image(m_image_name, &ictx));
+  ASSERT_EQ(0, when_acquired_lock(ictx));
+
+  // get current commit position
+  int64_t initial_tag;
+  int64_t initial_entry;
+  get_journal_commit_position(ictx, &initial_tag, &initial_entry);
+
+  // inject snapshot ops into journal
+  inject_into_journal(ictx, librbd::journal::SnapCreateEvent(1, "snap"));
+  inject_into_journal(ictx, librbd::journal::OpFinishEvent(1, 0));
+
+  // replay journal
+  ASSERT_EQ(0, open_image(m_image_name, &ictx));
+  ASSERT_EQ(0, when_acquired_lock(ictx));
+
+  int64_t current_tag;
+  int64_t current_entry;
+  get_journal_commit_position(ictx, &current_tag, &current_entry);
+  ASSERT_EQ(initial_tag + 1, current_tag);
+  ASSERT_EQ(1, current_entry);
+
+  {
+    RWLock::RLocker snap_locker(ictx->snap_lock);
+    ASSERT_NE(CEPH_NOSNAP, ictx->get_snap_id("snap"));
+  }
+
+  // verify lock ordering constraints
+  ASSERT_EQ(0, ictx->operations->snap_create("snap2"));
+}
+
+TEST_F(TestJournalReplay, SnapProtect) {
+  REQUIRE_FEATURE(RBD_FEATURE_JOURNALING);
+
+  librbd::ImageCtx *ictx;
+
+  ASSERT_EQ(0, open_image(m_image_name, &ictx));
+  ASSERT_EQ(0, when_acquired_lock(ictx));
+
+  ASSERT_EQ(0, ictx->operations->snap_create("snap"));
+
+  // get current commit position
+  int64_t initial_tag;
+  int64_t initial_entry;
+  get_journal_commit_position(ictx, &initial_tag, &initial_entry);
+
+  // inject snapshot ops into journal
+  inject_into_journal(ictx, librbd::journal::SnapProtectEvent(1, "snap"));
+  inject_into_journal(ictx, librbd::journal::OpFinishEvent(1, 0));
+
+  // replay journal
+  ASSERT_EQ(0, open_image(m_image_name, &ictx));
+  ASSERT_EQ(0, when_acquired_lock(ictx));
+
+  int64_t current_tag;
+  int64_t current_entry;
+  get_journal_commit_position(ictx, &current_tag, &current_entry);
+  ASSERT_EQ(initial_tag, current_tag);
+  ASSERT_EQ(initial_entry + 2, current_entry);
+
+  bool is_protected;
+  ASSERT_EQ(0, librbd::snap_is_protected(ictx, "snap", &is_protected));
+  ASSERT_TRUE(is_protected);
+
+  // verify lock ordering constraints
+  ASSERT_EQ(0, ictx->operations->snap_create("snap2"));
+  ASSERT_EQ(0, ictx->operations->snap_protect("snap2"));
+}
+
+TEST_F(TestJournalReplay, SnapUnprotect) {
+  REQUIRE_FEATURE(RBD_FEATURE_JOURNALING);
+
+  librbd::ImageCtx *ictx;
+
+  ASSERT_EQ(0, open_image(m_image_name, &ictx));
+  ASSERT_EQ(0, when_acquired_lock(ictx));
+
+  ASSERT_EQ(0, ictx->operations->snap_create("snap"));
+  uint64_t snap_id;
+  {
+    RWLock::RLocker snap_locker(ictx->snap_lock);
+    snap_id = ictx->get_snap_id("snap");
+    ASSERT_NE(CEPH_NOSNAP, snap_id);
+  }
+  ASSERT_EQ(0, ictx->operations->snap_protect("snap"));
+
+  // get current commit position
+  int64_t initial_tag;
+  int64_t initial_entry;
+  get_journal_commit_position(ictx, &initial_tag, &initial_entry);
+
+  // inject snapshot ops into journal
+  inject_into_journal(ictx, librbd::journal::SnapUnprotectEvent(1, "snap"));
+  inject_into_journal(ictx, librbd::journal::OpFinishEvent(1, 0));
+
+  // replay journal
+  ASSERT_EQ(0, open_image(m_image_name, &ictx));
+  ASSERT_EQ(0, when_acquired_lock(ictx));
+
+  int64_t current_tag;
+  int64_t current_entry;
+  get_journal_commit_position(ictx, &current_tag, &current_entry);
+  ASSERT_EQ(initial_tag, current_tag);
+  ASSERT_EQ(initial_entry + 2, current_entry);
+
+  bool is_protected;
+  ASSERT_EQ(0, librbd::snap_is_protected(ictx, "snap", &is_protected));
+  ASSERT_FALSE(is_protected);
+
+  // verify lock ordering constraints
+  ASSERT_EQ(0, ictx->operations->snap_create("snap2"));
+  ASSERT_EQ(0, ictx->operations->snap_protect("snap2"));
+  ASSERT_EQ(0, ictx->operations->snap_unprotect("snap2"));
+}
+
+TEST_F(TestJournalReplay, SnapRename) {
+  REQUIRE_FEATURE(RBD_FEATURE_JOURNALING);
+
+  librbd::ImageCtx *ictx;
+
+  ASSERT_EQ(0, open_image(m_image_name, &ictx));
+  ASSERT_EQ(0, when_acquired_lock(ictx));
+
+  ASSERT_EQ(0, ictx->operations->snap_create("snap"));
+  uint64_t snap_id;
+  {
+    RWLock::RLocker snap_locker(ictx->snap_lock);
+    snap_id = ictx->get_snap_id("snap");
+    ASSERT_NE(CEPH_NOSNAP, snap_id);
+  }
+
+  // get current commit position
+  int64_t initial_tag;
+  int64_t initial_entry;
+  get_journal_commit_position(ictx, &initial_tag, &initial_entry);
+
+  // inject snapshot ops into journal
+  inject_into_journal(ictx, librbd::journal::SnapRenameEvent(1, snap_id, "snap2"));
+  inject_into_journal(ictx, librbd::journal::OpFinishEvent(1, 0));
+
+  // replay journal
+  ASSERT_EQ(0, open_image(m_image_name, &ictx));
+  ASSERT_EQ(0, when_acquired_lock(ictx));
+
+  int64_t current_tag;
+  int64_t current_entry;
+  get_journal_commit_position(ictx, &current_tag, &current_entry);
+  ASSERT_EQ(initial_tag, current_tag);
+  ASSERT_EQ(initial_entry + 2, current_entry);
+  ASSERT_EQ(0, ictx->state->refresh());
+
+  {
+    RWLock::RLocker snap_locker(ictx->snap_lock);
+    snap_id = ictx->get_snap_id("snap2");
+    ASSERT_NE(CEPH_NOSNAP, snap_id);
+  }
+
+  // verify lock ordering constraints
+  ASSERT_EQ(0, ictx->operations->snap_rename("snap2", "snap3"));
+}
+
+TEST_F(TestJournalReplay, SnapRollback) {
+  REQUIRE_FEATURE(RBD_FEATURE_JOURNALING);
+
+  librbd::ImageCtx *ictx;
+
+  ASSERT_EQ(0, open_image(m_image_name, &ictx));
+  ASSERT_EQ(0, when_acquired_lock(ictx));
+
+  ASSERT_EQ(0, ictx->operations->snap_create("snap"));
+
+  // get current commit position
+  int64_t initial_tag;
+  int64_t initial_entry;
+  get_journal_commit_position(ictx, &initial_tag, &initial_entry);
+
+  // inject snapshot ops into journal
+  inject_into_journal(ictx, librbd::journal::SnapRollbackEvent(1, "snap"));
+  inject_into_journal(ictx, librbd::journal::OpFinishEvent(1, 0));
+
+  // replay journal
+  ASSERT_EQ(0, open_image(m_image_name, &ictx));
+  ASSERT_EQ(0, when_acquired_lock(ictx));
+
+  int64_t current_tag;
+  int64_t current_entry;
+  get_journal_commit_position(ictx, &current_tag, &current_entry);
+  ASSERT_EQ(initial_tag, current_tag);
+  ASSERT_EQ(initial_entry + 2, current_entry);
+
+  // verify lock ordering constraints
+  librbd::NoOpProgressContext no_op_progress;
+  ASSERT_EQ(0, ictx->operations->snap_rollback("snap", no_op_progress));
+}
+
+TEST_F(TestJournalReplay, SnapRemove) {
+  REQUIRE_FEATURE(RBD_FEATURE_JOURNALING);
+
+  librbd::ImageCtx *ictx;
+
+  ASSERT_EQ(0, open_image(m_image_name, &ictx));
+  ASSERT_EQ(0, when_acquired_lock(ictx));
+
+  ASSERT_EQ(0, ictx->operations->snap_create("snap"));
+
+  // get current commit position
+  int64_t initial_tag;
+  int64_t initial_entry;
+  get_journal_commit_position(ictx, &initial_tag, &initial_entry);
+
+  // inject snapshot ops into journal
+  inject_into_journal(ictx, librbd::journal::SnapRemoveEvent(1, "snap"));
+  inject_into_journal(ictx, librbd::journal::OpFinishEvent(1, 0));
+
+  // replay journal
+  ASSERT_EQ(0, open_image(m_image_name, &ictx));
+  ASSERT_EQ(0, when_acquired_lock(ictx));
+
+  int64_t current_tag;
+  int64_t current_entry;
+  get_journal_commit_position(ictx, &current_tag, &current_entry);
+  ASSERT_EQ(initial_tag, current_tag);
+  ASSERT_EQ(initial_entry + 2, current_entry);
+
+  {
+    RWLock::RLocker snap_locker(ictx->snap_lock);
+    uint64_t snap_id = ictx->get_snap_id("snap");
+    ASSERT_EQ(CEPH_NOSNAP, snap_id);
+  }
+
+  // verify lock ordering constraints
+  ASSERT_EQ(0, ictx->operations->snap_create("snap"));
+  ASSERT_EQ(0, ictx->operations->snap_remove("snap"));
+}
+
+TEST_F(TestJournalReplay, Rename) {
+  REQUIRE_FEATURE(RBD_FEATURE_JOURNALING);
+
+  librbd::ImageCtx *ictx;
+
+  ASSERT_EQ(0, open_image(m_image_name, &ictx));
+  ASSERT_EQ(0, when_acquired_lock(ictx));
+
+  // get current commit position
+  int64_t initial_tag;
+  int64_t initial_entry;
+  get_journal_commit_position(ictx, &initial_tag, &initial_entry);
+
+  // inject snapshot ops into journal
+  std::string new_image_name(get_temp_image_name());
+  inject_into_journal(ictx, librbd::journal::RenameEvent(1, new_image_name));
+  inject_into_journal(ictx, librbd::journal::OpFinishEvent(1, 0));
+
+  // replay journal
+  ASSERT_EQ(0, open_image(m_image_name, &ictx));
+  ASSERT_EQ(0, when_acquired_lock(ictx));
+
+  int64_t current_tag;
+  int64_t current_entry;
+  get_journal_commit_position(ictx, &current_tag, &current_entry);
+  ASSERT_EQ(initial_tag + 1, current_tag);
+  ASSERT_EQ(1, current_entry);
+
+  // verify lock ordering constraints
+  librbd::RBD rbd;
+  ASSERT_EQ(0, rbd.rename(m_ioctx, new_image_name.c_str(), m_image_name.c_str()));
 }
 
+TEST_F(TestJournalReplay, Resize) {
+  REQUIRE_FEATURE(RBD_FEATURE_JOURNALING);
+
+  librbd::ImageCtx *ictx;
+
+  ASSERT_EQ(0, open_image(m_image_name, &ictx));
+  ASSERT_EQ(0, when_acquired_lock(ictx));
+
+  // get current commit position
+  int64_t initial_tag;
+  int64_t initial_entry;
+  get_journal_commit_position(ictx, &initial_tag, &initial_entry);
+
+  // inject snapshot ops into journal
+  inject_into_journal(ictx, librbd::journal::ResizeEvent(1, 16));
+  inject_into_journal(ictx, librbd::journal::OpFinishEvent(1, 0));
+
+  // replay journal
+  ASSERT_EQ(0, open_image(m_image_name, &ictx));
+  ASSERT_EQ(0, when_acquired_lock(ictx));
+
+  int64_t current_tag;
+  int64_t current_entry;
+  get_journal_commit_position(ictx, &current_tag, &current_entry);
+  ASSERT_EQ(initial_tag + 1, current_tag);
+  ASSERT_EQ(1, current_entry);
+
+  // verify lock ordering constraints
+  librbd::NoOpProgressContext no_op_progress;
+  ASSERT_EQ(0, ictx->operations->resize(0, no_op_progress));
+}
+
+TEST_F(TestJournalReplay, Flatten) {
+  REQUIRE_FEATURE(RBD_FEATURE_LAYERING | RBD_FEATURE_JOURNALING);
+
+  librbd::ImageCtx *ictx;
+  ASSERT_EQ(0, open_image(m_image_name, &ictx));
+  ASSERT_EQ(0, ictx->operations->snap_create("snap"));
+  ASSERT_EQ(0, ictx->operations->snap_protect("snap"));
+
+  std::string clone_name = get_temp_image_name();
+  int order = ictx->order;
+  ASSERT_EQ(0, librbd::clone(m_ioctx, m_image_name.c_str(), "snap", m_ioctx,
+			     clone_name.c_str(), ictx->features, &order, 0, 0));
+
+  librbd::ImageCtx *ictx2;
+  ASSERT_EQ(0, open_image(clone_name, &ictx2));
+  ASSERT_EQ(0, when_acquired_lock(ictx2));
+
+  // get current commit position
+  int64_t initial_tag;
+  int64_t initial_entry;
+  get_journal_commit_position(ictx2, &initial_tag, &initial_entry);
+
+  // inject snapshot ops into journal
+  inject_into_journal(ictx2, librbd::journal::FlattenEvent(1));
+  inject_into_journal(ictx2, librbd::journal::OpFinishEvent(1, 0));
+
+  // replay journal
+  ASSERT_EQ(0, open_image(clone_name, &ictx2));
+  ASSERT_EQ(0, when_acquired_lock(ictx2));
+
+  int64_t current_tag;
+  int64_t current_entry;
+  get_journal_commit_position(ictx2, &current_tag, &current_entry);
+  ASSERT_EQ(initial_tag + 1, current_tag);
+  ASSERT_EQ(1, current_entry);
+  ASSERT_EQ(0, ictx->operations->snap_unprotect("snap"));
+
+  // verify lock ordering constraints
+  librbd::NoOpProgressContext no_op;
+  ASSERT_EQ(-EINVAL, ictx2->operations->flatten(no_op));
+}
+
+TEST_F(TestJournalReplay, ObjectPosition) {
+  REQUIRE_FEATURE(RBD_FEATURE_JOURNALING);
+
+  librbd::ImageCtx *ictx;
+  ASSERT_EQ(0, open_image(m_image_name, &ictx));
+  ASSERT_EQ(0, when_acquired_lock(ictx));
+
+  // get current commit position
+  int64_t initial_tag;
+  int64_t initial_entry;
+  get_journal_commit_position(ictx, &initial_tag, &initial_entry);
+
+  std::string payload(4096, '1');
+  librbd::AioCompletion *aio_comp = new librbd::AioCompletion();
+  ictx->aio_work_queue->aio_write(aio_comp, 0, payload.size(), payload.c_str(),
+                                  0);
+  ASSERT_EQ(0, aio_comp->wait_for_complete());
+  aio_comp->release();
+
+  aio_comp = new librbd::AioCompletion();
+  ictx->aio_work_queue->aio_flush(aio_comp);
+  ASSERT_EQ(0, aio_comp->wait_for_complete());
+  aio_comp->release();
+
+  // check the commit position updated
+  int64_t current_tag;
+  int64_t current_entry;
+  get_journal_commit_position(ictx, &current_tag, &current_entry);
+  ASSERT_EQ(initial_tag + 1, current_tag);
+  ASSERT_EQ(1, current_entry);
+
+  // write again
+
+  aio_comp = new librbd::AioCompletion();
+  ictx->aio_work_queue->aio_write(aio_comp, 0, payload.size(), payload.c_str(),
+                                  0);
+  ASSERT_EQ(0, aio_comp->wait_for_complete());
+  aio_comp->release();
+
+  aio_comp = new librbd::AioCompletion();
+  ictx->aio_work_queue->aio_flush(aio_comp);
+  ASSERT_EQ(0, aio_comp->wait_for_complete());
+  aio_comp->release();
+
+  // check the commit position updated
+  get_journal_commit_position(ictx, &current_tag, &current_entry);
+  ASSERT_EQ(initial_tag + 1, current_tag);
+  ASSERT_EQ(3, current_entry);
+}
diff --git a/src/test/librbd/journal/test_mock_Replay.cc b/src/test/librbd/journal/test_mock_Replay.cc
index 5302b8f..2fc4344 100644
--- a/src/test/librbd/journal/test_mock_Replay.cc
+++ b/src/test/librbd/journal/test_mock_Replay.cc
@@ -13,27 +13,36 @@
 
 namespace librbd {
 
+namespace {
+
+struct MockReplayImageCtx : public MockImageCtx {
+  MockReplayImageCtx(ImageCtx &image_ctx) : MockImageCtx(image_ctx) {
+  }
+};
+
+} // anonymous namespace
+
 template <>
-struct AioImageRequest<MockImageCtx> {
+struct AioImageRequest<MockReplayImageCtx> {
   static AioImageRequest *s_instance;
 
   MOCK_METHOD5(aio_write, void(AioCompletion *c, uint64_t off, size_t len,
                                const char *buf, int op_flags));
-  static void aio_write(MockImageCtx *ictx, AioCompletion *c, uint64_t off,
+  static void aio_write(MockReplayImageCtx *ictx, AioCompletion *c, uint64_t off,
                         size_t len, const char *buf, int op_flags) {
     assert(s_instance != nullptr);
     s_instance->aio_write(c, off, len, buf, op_flags);
   }
 
   MOCK_METHOD3(aio_discard, void(AioCompletion *c, uint64_t off, uint64_t len));
-  static void aio_discard(MockImageCtx *ictx, AioCompletion *c, uint64_t off,
+  static void aio_discard(MockReplayImageCtx *ictx, AioCompletion *c, uint64_t off,
                           uint64_t len) {
     assert(s_instance != nullptr);
     s_instance->aio_discard(c, off, len);
   }
 
   MOCK_METHOD1(aio_flush, void(AioCompletion *c));
-  static void aio_flush(MockImageCtx *ictx, AioCompletion *c) {
+  static void aio_flush(MockReplayImageCtx *ictx, AioCompletion *c) {
     assert(s_instance != nullptr);
     s_instance->aio_flush(c);
   }
@@ -43,13 +52,13 @@ struct AioImageRequest<MockImageCtx> {
   }
 };
 
-AioImageRequest<MockImageCtx> *AioImageRequest<MockImageCtx>::s_instance = nullptr;
+AioImageRequest<MockReplayImageCtx> *AioImageRequest<MockReplayImageCtx>::s_instance = nullptr;
 
 }
 
 // template definitions
 #include "librbd/journal/Replay.cc"
-template class librbd::journal::Replay<librbd::MockImageCtx>;
+template class librbd::journal::Replay<librbd::MockReplayImageCtx>;
 
 using ::testing::_;
 using ::testing::DoAll;
@@ -62,6 +71,11 @@ MATCHER_P(CStrEq, str, "") {
   return (strncmp(arg, str, strlen(str)) == 0);
 }
 
+ACTION_P2(NotifyInvoke, lock, cond) {
+  Mutex::Locker locker(*lock);
+  cond->Signal();
+}
+
 ACTION_P2(CompleteAioCompletion, r, image_ctx) {
   CephContext *cct = image_ctx->cct;
   image_ctx->op_work_queue->queue(new FunctionContext([cct, arg0](int r) {
@@ -76,8 +90,11 @@ namespace journal {
 
 class TestMockJournalReplay : public TestMockFixture {
 public:
-  typedef AioImageRequest<MockImageCtx> MockAioImageRequest;
-  typedef Replay<MockImageCtx> MockJournalReplay;
+  typedef AioImageRequest<MockReplayImageCtx> MockAioImageRequest;
+  typedef Replay<MockReplayImageCtx> MockJournalReplay;
+
+  TestMockJournalReplay() : m_invoke_lock("m_invoke_lock") {
+  }
 
   void expect_aio_discard(MockAioImageRequest &mock_aio_image_request,
                           AioCompletion **aio_comp, uint64_t off,
@@ -92,7 +109,7 @@ public:
                   .WillOnce(SaveArg<0>(aio_comp));
   }
 
-  void expect_aio_flush(MockImageCtx &mock_image_ctx,
+  void expect_aio_flush(MockReplayImageCtx &mock_image_ctx,
                         MockAioImageRequest &mock_aio_image_request, int r) {
     EXPECT_CALL(mock_aio_image_request, aio_flush(_))
                   .WillOnce(CompleteAioCompletion(r, mock_image_ctx.image_ctx));
@@ -106,60 +123,79 @@ public:
                   .WillOnce(SaveArg<0>(aio_comp));
   }
 
-  void expect_flatten(MockImageCtx &mock_image_ctx, Context **on_finish) {
-    EXPECT_CALL(*mock_image_ctx.operations, flatten(_, _))
-                  .WillOnce(SaveArg<1>(on_finish));
+  void expect_flatten(MockReplayImageCtx &mock_image_ctx, Context **on_finish) {
+    EXPECT_CALL(*mock_image_ctx.operations, execute_flatten(_, _))
+                  .WillOnce(DoAll(SaveArg<1>(on_finish),
+                                  NotifyInvoke(&m_invoke_lock, &m_invoke_cond)));
   }
 
-  void expect_rename(MockImageCtx &mock_image_ctx, Context **on_finish,
+  void expect_rename(MockReplayImageCtx &mock_image_ctx, Context **on_finish,
                      const char *image_name) {
-    EXPECT_CALL(*mock_image_ctx.operations, rename(CStrEq(image_name), _))
-                  .WillOnce(SaveArg<1>(on_finish));
+    EXPECT_CALL(*mock_image_ctx.operations, execute_rename(CStrEq(image_name), _))
+                  .WillOnce(DoAll(SaveArg<1>(on_finish),
+                                  NotifyInvoke(&m_invoke_lock, &m_invoke_cond)));
   }
 
-  void expect_resize(MockImageCtx &mock_image_ctx, Context **on_finish,
+  void expect_resize(MockReplayImageCtx &mock_image_ctx, Context **on_finish,
                      uint64_t size, uint64_t op_tid) {
-    EXPECT_CALL(*mock_image_ctx.operations, resize(size, _, _, op_tid))
-                  .WillOnce(SaveArg<2>(on_finish));
+    EXPECT_CALL(*mock_image_ctx.operations, execute_resize(size, _, _, op_tid))
+                  .WillOnce(DoAll(SaveArg<2>(on_finish),
+                                  NotifyInvoke(&m_invoke_lock, &m_invoke_cond)));
   }
 
-  void expect_snap_create(MockImageCtx &mock_image_ctx,
+  void expect_snap_create(MockReplayImageCtx &mock_image_ctx,
                           Context **on_finish, const char *snap_name,
                           uint64_t op_tid) {
-    EXPECT_CALL(*mock_image_ctx.operations, snap_create(CStrEq(snap_name), _,
-                                                        op_tid))
-                  .WillOnce(SaveArg<1>(on_finish));
+    EXPECT_CALL(*mock_image_ctx.operations, execute_snap_create(CStrEq(snap_name), _,
+                                                                op_tid))
+                  .WillOnce(DoAll(SaveArg<1>(on_finish),
+                                  NotifyInvoke(&m_invoke_lock, &m_invoke_cond)));
   }
 
-  void expect_snap_remove(MockImageCtx &mock_image_ctx,
+  void expect_snap_remove(MockReplayImageCtx &mock_image_ctx,
                           Context **on_finish, const char *snap_name) {
-    EXPECT_CALL(*mock_image_ctx.operations, snap_remove(CStrEq(snap_name), _))
-                  .WillOnce(SaveArg<1>(on_finish));
+    EXPECT_CALL(*mock_image_ctx.operations, execute_snap_remove(CStrEq(snap_name), _))
+                  .WillOnce(DoAll(SaveArg<1>(on_finish),
+                                  NotifyInvoke(&m_invoke_lock, &m_invoke_cond)));
   }
 
-  void expect_snap_rename(MockImageCtx &mock_image_ctx,
+  void expect_snap_rename(MockReplayImageCtx &mock_image_ctx,
                           Context **on_finish, uint64_t snap_id,
                           const char *snap_name) {
-    EXPECT_CALL(*mock_image_ctx.operations, snap_rename(snap_id, CStrEq(snap_name), _))
-                  .WillOnce(SaveArg<2>(on_finish));
+    EXPECT_CALL(*mock_image_ctx.operations, execute_snap_rename(snap_id, CStrEq(snap_name), _))
+                  .WillOnce(DoAll(SaveArg<2>(on_finish),
+                                  NotifyInvoke(&m_invoke_lock, &m_invoke_cond)));
   }
 
-  void expect_snap_protect(MockImageCtx &mock_image_ctx,
+  void expect_snap_protect(MockReplayImageCtx &mock_image_ctx,
                            Context **on_finish, const char *snap_name) {
-    EXPECT_CALL(*mock_image_ctx.operations, snap_protect(CStrEq(snap_name), _))
-                  .WillOnce(SaveArg<1>(on_finish));
+    EXPECT_CALL(*mock_image_ctx.operations, execute_snap_protect(CStrEq(snap_name), _))
+                  .WillOnce(DoAll(SaveArg<1>(on_finish),
+                                  NotifyInvoke(&m_invoke_lock, &m_invoke_cond)));
   }
 
-  void expect_snap_unprotect(MockImageCtx &mock_image_ctx,
+  void expect_snap_unprotect(MockReplayImageCtx &mock_image_ctx,
                              Context **on_finish, const char *snap_name) {
-    EXPECT_CALL(*mock_image_ctx.operations, snap_unprotect(CStrEq(snap_name), _))
-                  .WillOnce(SaveArg<1>(on_finish));
+    EXPECT_CALL(*mock_image_ctx.operations, execute_snap_unprotect(CStrEq(snap_name), _))
+                  .WillOnce(DoAll(SaveArg<1>(on_finish),
+                                  NotifyInvoke(&m_invoke_lock, &m_invoke_cond)));
   }
 
-  void expect_snap_rollback(MockImageCtx &mock_image_ctx,
+  void expect_snap_rollback(MockReplayImageCtx &mock_image_ctx,
                             Context **on_finish, const char *snap_name) {
-    EXPECT_CALL(*mock_image_ctx.operations, snap_rollback(CStrEq(snap_name), _, _))
-                  .WillOnce(SaveArg<2>(on_finish));
+    EXPECT_CALL(*mock_image_ctx.operations, execute_snap_rollback(CStrEq(snap_name), _, _))
+                  .WillOnce(DoAll(SaveArg<2>(on_finish),
+                                  NotifyInvoke(&m_invoke_lock, &m_invoke_cond)));
+  }
+
+  void expect_refresh_image(MockReplayImageCtx &mock_image_ctx, bool required,
+                            int r) {
+    EXPECT_CALL(*mock_image_ctx.state, is_refresh_required())
+                  .WillOnce(Return(required));
+    if (required) {
+      EXPECT_CALL(*mock_image_ctx.state, refresh(_))
+                    .WillOnce(CompleteContext(r, mock_image_ctx.image_ctx->op_work_queue));
+    }
   }
 
   void when_process(MockJournalReplay &mock_journal_replay,
@@ -178,7 +214,7 @@ public:
     mock_journal_replay.process(it, on_ready, on_safe);
   }
 
-  void when_complete(MockImageCtx &mock_image_ctx, AioCompletion *aio_comp,
+  void when_complete(MockReplayImageCtx &mock_image_ctx, AioCompletion *aio_comp,
                      int r) {
     aio_comp->get();
     aio_comp->set_request_count(mock_image_ctx.cct, 1);
@@ -191,16 +227,35 @@ public:
     return ctx.wait();
   }
 
+  int when_shut_down(MockJournalReplay &mock_journal_replay, bool cancel_ops) {
+    C_SaferCond ctx;
+    mock_journal_replay.shut_down(cancel_ops, &ctx);
+    return ctx.wait();
+  }
+
   void when_replay_op_ready(MockJournalReplay &mock_journal_replay,
                             uint64_t op_tid, Context *on_resume) {
     mock_journal_replay.replay_op_ready(op_tid, on_resume);
   }
 
+  void wait_for_op_invoked(Context **on_finish, int r) {
+    {
+      Mutex::Locker locker(m_invoke_lock);
+      while (*on_finish == nullptr) {
+        m_invoke_cond.Wait(m_invoke_lock);
+      }
+    }
+    (*on_finish)->complete(r);
+  }
+
   bufferlist to_bl(const std::string &str) {
     bufferlist bl;
     bl.append(str);
     return bl;
   }
+
+  Mutex m_invoke_lock;
+  Cond m_invoke_cond;
 };
 
 TEST_F(TestMockJournalReplay, AioDiscard) {
@@ -209,7 +264,7 @@ TEST_F(TestMockJournalReplay, AioDiscard) {
   librbd::ImageCtx *ictx;
   ASSERT_EQ(0, open_image(m_image_name, &ictx));
 
-  MockImageCtx mock_image_ctx(*ictx);
+  MockReplayImageCtx mock_image_ctx(*ictx);
   MockJournalReplay mock_journal_replay(mock_image_ctx);
   MockAioImageRequest mock_aio_image_request;
   expect_op_work_queue(mock_image_ctx);
@@ -227,7 +282,7 @@ TEST_F(TestMockJournalReplay, AioDiscard) {
   ASSERT_EQ(0, on_ready.wait());
 
   expect_aio_flush(mock_image_ctx, mock_aio_image_request, 0);
-  ASSERT_EQ(0, when_flush(mock_journal_replay));
+  ASSERT_EQ(0, when_shut_down(mock_journal_replay, false));
   ASSERT_EQ(0, on_safe.wait());
 }
 
@@ -237,7 +292,7 @@ TEST_F(TestMockJournalReplay, AioWrite) {
   librbd::ImageCtx *ictx;
   ASSERT_EQ(0, open_image(m_image_name, &ictx));
 
-  MockImageCtx mock_image_ctx(*ictx);
+  MockReplayImageCtx mock_image_ctx(*ictx);
   MockJournalReplay mock_journal_replay(mock_image_ctx);
   MockAioImageRequest mock_aio_image_request;
   expect_op_work_queue(mock_image_ctx);
@@ -255,7 +310,7 @@ TEST_F(TestMockJournalReplay, AioWrite) {
   ASSERT_EQ(0, on_ready.wait());
 
   expect_aio_flush(mock_image_ctx, mock_aio_image_request, 0);
-  ASSERT_EQ(0, when_flush(mock_journal_replay));
+  ASSERT_EQ(0, when_shut_down(mock_journal_replay, false));
   ASSERT_EQ(0, on_safe.wait());
 }
 
@@ -265,7 +320,7 @@ TEST_F(TestMockJournalReplay, AioFlush) {
   librbd::ImageCtx *ictx;
   ASSERT_EQ(0, open_image(m_image_name, &ictx));
 
-  MockImageCtx mock_image_ctx(*ictx);
+  MockReplayImageCtx mock_image_ctx(*ictx);
   MockJournalReplay mock_journal_replay(mock_image_ctx);
   MockAioImageRequest mock_aio_image_request;
   expect_op_work_queue(mock_image_ctx);
@@ -281,7 +336,7 @@ TEST_F(TestMockJournalReplay, AioFlush) {
   when_complete(mock_image_ctx, aio_comp, 0);
   ASSERT_EQ(0, on_safe.wait());
 
-  ASSERT_EQ(0, when_flush(mock_journal_replay));
+  ASSERT_EQ(0, when_shut_down(mock_journal_replay, false));
   ASSERT_EQ(0, on_ready.wait());
 }
 
@@ -291,7 +346,7 @@ TEST_F(TestMockJournalReplay, IOError) {
   librbd::ImageCtx *ictx;
   ASSERT_EQ(0, open_image(m_image_name, &ictx));
 
-  MockImageCtx mock_image_ctx(*ictx);
+  MockReplayImageCtx mock_image_ctx(*ictx);
   MockJournalReplay mock_journal_replay(mock_image_ctx);
   MockAioImageRequest mock_aio_image_request;
   expect_op_work_queue(mock_image_ctx);
@@ -309,7 +364,7 @@ TEST_F(TestMockJournalReplay, IOError) {
   ASSERT_EQ(-EINVAL, on_safe.wait());
 
   expect_aio_flush(mock_image_ctx, mock_aio_image_request, 0);
-  ASSERT_EQ(0, when_flush(mock_journal_replay));
+  ASSERT_EQ(0, when_shut_down(mock_journal_replay, false));
   ASSERT_EQ(0, on_ready.wait());
 }
 
@@ -319,7 +374,7 @@ TEST_F(TestMockJournalReplay, SoftFlushIO) {
   librbd::ImageCtx *ictx;
   ASSERT_EQ(0, open_image(m_image_name, &ictx));
 
-  MockImageCtx mock_image_ctx(*ictx);
+  MockReplayImageCtx mock_image_ctx(*ictx);
   MockJournalReplay mock_journal_replay(mock_image_ctx);
   MockAioImageRequest mock_aio_image_request;
   expect_op_work_queue(mock_image_ctx);
@@ -338,9 +393,9 @@ TEST_F(TestMockJournalReplay, SoftFlushIO) {
     when_process(mock_journal_replay,
                  EventEntry{AioDiscardEvent(123, 456)},
                  &on_ready, &on_safes[i]);
+    when_complete(mock_image_ctx, aio_comp, 0);
     ASSERT_EQ(0, on_ready.wait());
 
-    when_complete(mock_image_ctx, aio_comp, 0);
     if (flush_comp != nullptr) {
       when_complete(mock_image_ctx, flush_comp, 0);
     }
@@ -349,7 +404,7 @@ TEST_F(TestMockJournalReplay, SoftFlushIO) {
     ASSERT_EQ(0, on_safe.wait());
   }
 
-  ASSERT_EQ(0, when_flush(mock_journal_replay));
+  ASSERT_EQ(0, when_shut_down(mock_journal_replay, false));
 }
 
 TEST_F(TestMockJournalReplay, PauseIO) {
@@ -358,7 +413,7 @@ TEST_F(TestMockJournalReplay, PauseIO) {
   librbd::ImageCtx *ictx;
   ASSERT_EQ(0, open_image(m_image_name, &ictx));
 
-  MockImageCtx mock_image_ctx(*ictx);
+  MockReplayImageCtx mock_image_ctx(*ictx);
   MockJournalReplay mock_journal_replay(mock_image_ctx);
   MockAioImageRequest mock_aio_image_request;
   expect_op_work_queue(mock_image_ctx);
@@ -378,54 +433,197 @@ TEST_F(TestMockJournalReplay, PauseIO) {
     when_process(mock_journal_replay,
                  EventEntry{AioWriteEvent(123, 456, to_bl("test"))},
                  &on_ready, &on_safes[i]);
+    when_complete(mock_image_ctx, aio_comp, 0);
     if (i < io_count - 1) {
       ASSERT_EQ(0, on_ready.wait());
-    }
-
-    when_complete(mock_image_ctx, aio_comp, 0);
-    if (i == io_count - 1) {
+    } else {
       for (auto flush_comp : flush_comps) {
         when_complete(mock_image_ctx, flush_comp, 0);
-        ASSERT_EQ(0, on_ready.wait());
       }
+      ASSERT_EQ(0, on_ready.wait());
     }
   }
   for (auto &on_safe : on_safes) {
     ASSERT_EQ(0, on_safe.wait());
   }
 
-  ASSERT_EQ(0, when_flush(mock_journal_replay));
+  ASSERT_EQ(0, when_shut_down(mock_journal_replay, false));
 }
 
-TEST_F(TestMockJournalReplay, MissingOpFinishEvent) {
+TEST_F(TestMockJournalReplay, Flush) {
   librbd::ImageCtx *ictx;
   ASSERT_EQ(0, open_image(m_image_name, &ictx));
 
-  MockImageCtx mock_image_ctx(*ictx);
+  MockReplayImageCtx mock_image_ctx(*ictx);
   MockJournalReplay mock_journal_replay(mock_image_ctx);
+  MockAioImageRequest mock_aio_image_request;
   expect_op_work_queue(mock_image_ctx);
 
   InSequence seq;
+  AioCompletion *aio_comp;
   C_SaferCond on_ready;
   C_SaferCond on_safe;
-  when_process(mock_journal_replay, EventEntry{SnapRemoveEvent(123, "snap")},
+  expect_aio_discard(mock_aio_image_request, &aio_comp, 123, 456);
+  when_process(mock_journal_replay,
+               EventEntry{AioDiscardEvent(123, 456)},
                &on_ready, &on_safe);
 
+  when_complete(mock_image_ctx, aio_comp, 0);
   ASSERT_EQ(0, on_ready.wait());
 
+  expect_aio_flush(mock_image_ctx, mock_aio_image_request, 0);
   ASSERT_EQ(0, when_flush(mock_journal_replay));
-  ASSERT_EQ(-ERESTART, on_safe.wait());
+  ASSERT_EQ(0, on_safe.wait());
 }
 
-TEST_F(TestMockJournalReplay, MissingCompleteOpFinishEvent) {
-  // TODO
+TEST_F(TestMockJournalReplay, OpFinishError) {
+  REQUIRE_FEATURE(RBD_FEATURE_JOURNALING);
+
+  librbd::ImageCtx *ictx;
+  ASSERT_EQ(0, open_image(m_image_name, &ictx));
+
+  MockReplayImageCtx mock_image_ctx(*ictx);
+  MockJournalReplay mock_journal_replay(mock_image_ctx);
+  expect_op_work_queue(mock_image_ctx);
+
+  InSequence seq;
+  C_SaferCond on_start_ready;
+  C_SaferCond on_start_safe;
+  when_process(mock_journal_replay, EventEntry{SnapRemoveEvent(123, "snap")},
+               &on_start_ready, &on_start_safe);
+  ASSERT_EQ(0, on_start_ready.wait());
+
+  C_SaferCond on_finish_ready;
+  C_SaferCond on_finish_safe;
+  when_process(mock_journal_replay, EventEntry{OpFinishEvent(123, -EIO)},
+               &on_finish_ready, &on_finish_safe);
+
+  ASSERT_EQ(-EIO, on_start_safe.wait());
+  ASSERT_EQ(-EIO, on_finish_safe.wait());
+  ASSERT_EQ(0, on_finish_ready.wait());
+}
+
+TEST_F(TestMockJournalReplay, BlockedOpFinishError) {
+  REQUIRE_FEATURE(RBD_FEATURE_JOURNALING);
+
+  librbd::ImageCtx *ictx;
+  ASSERT_EQ(0, open_image(m_image_name, &ictx));
+
+  MockReplayImageCtx mock_image_ctx(*ictx);
+  MockJournalReplay mock_journal_replay(mock_image_ctx);
+  expect_op_work_queue(mock_image_ctx);
+
+  InSequence seq;
+  Context *on_finish = nullptr;
+  expect_refresh_image(mock_image_ctx, false, 0);
+  expect_snap_create(mock_image_ctx, &on_finish, "snap", 123);
+
+  C_SaferCond on_start_ready;
+  C_SaferCond on_start_safe;
+  when_process(mock_journal_replay, EventEntry{SnapCreateEvent(123, "snap")},
+               &on_start_ready, &on_start_safe);
+
+  C_SaferCond on_resume;
+  when_replay_op_ready(mock_journal_replay, 123, &on_resume);
+  ASSERT_EQ(0, on_start_ready.wait());
+
+  C_SaferCond on_finish_ready;
+  C_SaferCond on_finish_safe;
+  when_process(mock_journal_replay, EventEntry{OpFinishEvent(123, -EBADMSG)},
+               &on_finish_ready, &on_finish_safe);
+
+  ASSERT_EQ(-EBADMSG, on_resume.wait());
+  wait_for_op_invoked(&on_finish, -ESTALE);
+
+  ASSERT_EQ(-ESTALE, on_start_safe.wait());
+  ASSERT_EQ(-ESTALE, on_finish_safe.wait());
+  ASSERT_EQ(0, on_finish_ready.wait());
+}
+
+TEST_F(TestMockJournalReplay, MissingOpFinishEvent) {
+  librbd::ImageCtx *ictx;
+  ASSERT_EQ(0, open_image(m_image_name, &ictx));
+
+  MockReplayImageCtx mock_image_ctx(*ictx);
+  MockJournalReplay mock_journal_replay(mock_image_ctx);
+  expect_op_work_queue(mock_image_ctx);
+
+  EXPECT_CALL(*mock_image_ctx.state, is_refresh_required())
+                .WillRepeatedly(Return(false));
+
+  InSequence seq;
+  Context *on_snap_create_finish = nullptr;
+  expect_snap_create(mock_image_ctx, &on_snap_create_finish, "snap", 123);
+
+  Context *on_snap_remove_finish = nullptr;
+  expect_snap_remove(mock_image_ctx, &on_snap_remove_finish, "snap");
+
+  C_SaferCond on_snap_remove_ready;
+  C_SaferCond on_snap_remove_safe;
+  when_process(mock_journal_replay, EventEntry{SnapRemoveEvent(122, "snap")},
+               &on_snap_remove_ready, &on_snap_remove_safe);
+  ASSERT_EQ(0, on_snap_remove_ready.wait());
+
+  C_SaferCond on_snap_create_ready;
+  C_SaferCond on_snap_create_safe;
+  when_process(mock_journal_replay, EventEntry{SnapCreateEvent(123, "snap")},
+               &on_snap_create_ready, &on_snap_create_safe);
+
+  C_SaferCond on_shut_down;
+  mock_journal_replay.shut_down(false, &on_shut_down);
+
+  wait_for_op_invoked(&on_snap_remove_finish, 0);
+  ASSERT_EQ(0, on_snap_remove_safe.wait());
+
+  C_SaferCond on_snap_create_resume;
+  when_replay_op_ready(mock_journal_replay, 123, &on_snap_create_resume);
+  ASSERT_EQ(0, on_snap_create_resume.wait());
+
+  wait_for_op_invoked(&on_snap_create_finish, 0);
+  ASSERT_EQ(0, on_snap_create_ready.wait());
+  ASSERT_EQ(0, on_snap_create_safe.wait());
+
+  ASSERT_EQ(0, on_shut_down.wait());
+}
+
+TEST_F(TestMockJournalReplay, MissingOpFinishEventCancelOps) {
+  librbd::ImageCtx *ictx;
+  ASSERT_EQ(0, open_image(m_image_name, &ictx));
+
+  MockReplayImageCtx mock_image_ctx(*ictx);
+  MockJournalReplay mock_journal_replay(mock_image_ctx);
+  expect_op_work_queue(mock_image_ctx);
+
+  InSequence seq;
+  Context *on_snap_create_finish = nullptr;
+  expect_refresh_image(mock_image_ctx, false, 0);
+  expect_snap_create(mock_image_ctx, &on_snap_create_finish, "snap", 123);
+
+  C_SaferCond on_snap_remove_ready;
+  C_SaferCond on_snap_remove_safe;
+  when_process(mock_journal_replay, EventEntry{SnapRemoveEvent(122, "snap")},
+               &on_snap_remove_ready, &on_snap_remove_safe);
+  ASSERT_EQ(0, on_snap_remove_ready.wait());
+
+  C_SaferCond on_snap_create_ready;
+  C_SaferCond on_snap_create_safe;
+  when_process(mock_journal_replay, EventEntry{SnapCreateEvent(123, "snap")},
+               &on_snap_create_ready, &on_snap_create_safe);
+
+  C_SaferCond on_resume;
+  when_replay_op_ready(mock_journal_replay, 123, &on_resume);
+  ASSERT_EQ(0, on_snap_create_ready.wait());
+
+  ASSERT_EQ(0, when_shut_down(mock_journal_replay, true));
+  ASSERT_EQ(-ERESTART, on_snap_remove_safe.wait());
+  ASSERT_EQ(-ERESTART, on_snap_create_safe.wait());
 }
 
 TEST_F(TestMockJournalReplay, UnknownOpFinishEvent) {
   librbd::ImageCtx *ictx;
   ASSERT_EQ(0, open_image(m_image_name, &ictx));
 
-  MockImageCtx mock_image_ctx(*ictx);
+  MockReplayImageCtx mock_image_ctx(*ictx);
   MockJournalReplay mock_journal_replay(mock_image_ctx);
   expect_op_work_queue(mock_image_ctx);
 
@@ -445,12 +643,13 @@ TEST_F(TestMockJournalReplay, OpEventError) {
   librbd::ImageCtx *ictx;
   ASSERT_EQ(0, open_image(m_image_name, &ictx));
 
-  MockImageCtx mock_image_ctx(*ictx);
+  MockReplayImageCtx mock_image_ctx(*ictx);
   MockJournalReplay mock_journal_replay(mock_image_ctx);
   expect_op_work_queue(mock_image_ctx);
 
   InSequence seq;
-  Context *on_finish;
+  Context *on_finish = nullptr;
+  expect_refresh_image(mock_image_ctx, false, 0);
   expect_snap_remove(mock_image_ctx, &on_finish, "snap");
 
   C_SaferCond on_start_ready;
@@ -464,7 +663,7 @@ TEST_F(TestMockJournalReplay, OpEventError) {
   when_process(mock_journal_replay, EventEntry{OpFinishEvent(123, 0)},
                &on_finish_ready, &on_finish_safe);
 
-  on_finish->complete(-EINVAL);
+  wait_for_op_invoked(&on_finish, -EINVAL);
   ASSERT_EQ(-EINVAL, on_start_safe.wait());
   ASSERT_EQ(0, on_finish_ready.wait());
   ASSERT_EQ(-EINVAL, on_finish_safe.wait());
@@ -476,12 +675,13 @@ TEST_F(TestMockJournalReplay, SnapCreateEvent) {
   librbd::ImageCtx *ictx;
   ASSERT_EQ(0, open_image(m_image_name, &ictx));
 
-  MockImageCtx mock_image_ctx(*ictx);
+  MockReplayImageCtx mock_image_ctx(*ictx);
   MockJournalReplay mock_journal_replay(mock_image_ctx);
   expect_op_work_queue(mock_image_ctx);
 
   InSequence seq;
-  Context *on_finish;
+  Context *on_finish = nullptr;
+  expect_refresh_image(mock_image_ctx, false, 0);
   expect_snap_create(mock_image_ctx, &on_finish, "snap", 123);
 
   C_SaferCond on_start_ready;
@@ -499,7 +699,40 @@ TEST_F(TestMockJournalReplay, SnapCreateEvent) {
                &on_finish_ready, &on_finish_safe);
 
   ASSERT_EQ(0, on_resume.wait());
-  on_finish->complete(0);
+  wait_for_op_invoked(&on_finish, 0);
+
+  ASSERT_EQ(0, on_start_safe.wait());
+  ASSERT_EQ(0, on_finish_ready.wait());
+  ASSERT_EQ(0, on_finish_safe.wait());
+}
+
+TEST_F(TestMockJournalReplay, SnapCreateEventExists) {
+  REQUIRE_FEATURE(RBD_FEATURE_JOURNALING);
+
+  librbd::ImageCtx *ictx;
+  ASSERT_EQ(0, open_image(m_image_name, &ictx));
+
+  MockReplayImageCtx mock_image_ctx(*ictx);
+  MockJournalReplay mock_journal_replay(mock_image_ctx);
+  expect_op_work_queue(mock_image_ctx);
+
+  InSequence seq;
+  Context *on_finish = nullptr;
+  expect_refresh_image(mock_image_ctx, false, 0);
+  expect_snap_create(mock_image_ctx, &on_finish, "snap", 123);
+
+  C_SaferCond on_start_ready;
+  C_SaferCond on_start_safe;
+  when_process(mock_journal_replay, EventEntry{SnapCreateEvent(123, "snap")},
+               &on_start_ready, &on_start_safe);
+
+  wait_for_op_invoked(&on_finish, -EEXIST);
+  ASSERT_EQ(0, on_start_ready.wait());
+
+  C_SaferCond on_finish_ready;
+  C_SaferCond on_finish_safe;
+  when_process(mock_journal_replay, EventEntry{OpFinishEvent(123, 0)},
+               &on_finish_ready, &on_finish_safe);
 
   ASSERT_EQ(0, on_start_safe.wait());
   ASSERT_EQ(0, on_finish_ready.wait());
@@ -512,12 +745,45 @@ TEST_F(TestMockJournalReplay, SnapRemoveEvent) {
   librbd::ImageCtx *ictx;
   ASSERT_EQ(0, open_image(m_image_name, &ictx));
 
-  MockImageCtx mock_image_ctx(*ictx);
+  MockReplayImageCtx mock_image_ctx(*ictx);
+  MockJournalReplay mock_journal_replay(mock_image_ctx);
+  expect_op_work_queue(mock_image_ctx);
+
+  InSequence seq;
+  Context *on_finish = nullptr;
+  expect_refresh_image(mock_image_ctx, false, 0);
+  expect_snap_remove(mock_image_ctx, &on_finish, "snap");
+
+  C_SaferCond on_start_ready;
+  C_SaferCond on_start_safe;
+  when_process(mock_journal_replay, EventEntry{SnapRemoveEvent(123, "snap")},
+               &on_start_ready, &on_start_safe);
+  ASSERT_EQ(0, on_start_ready.wait());
+
+  C_SaferCond on_finish_ready;
+  C_SaferCond on_finish_safe;
+  when_process(mock_journal_replay, EventEntry{OpFinishEvent(123, 0)},
+               &on_finish_ready, &on_finish_safe);
+
+  wait_for_op_invoked(&on_finish, 0);
+  ASSERT_EQ(0, on_start_safe.wait());
+  ASSERT_EQ(0, on_finish_ready.wait());
+  ASSERT_EQ(0, on_finish_safe.wait());
+}
+
+TEST_F(TestMockJournalReplay, SnapRemoveEventDNE) {
+  REQUIRE_FEATURE(RBD_FEATURE_JOURNALING);
+
+  librbd::ImageCtx *ictx;
+  ASSERT_EQ(0, open_image(m_image_name, &ictx));
+
+  MockReplayImageCtx mock_image_ctx(*ictx);
   MockJournalReplay mock_journal_replay(mock_image_ctx);
   expect_op_work_queue(mock_image_ctx);
 
   InSequence seq;
-  Context *on_finish;
+  Context *on_finish = nullptr;
+  expect_refresh_image(mock_image_ctx, false, 0);
   expect_snap_remove(mock_image_ctx, &on_finish, "snap");
 
   C_SaferCond on_start_ready;
@@ -531,7 +797,7 @@ TEST_F(TestMockJournalReplay, SnapRemoveEvent) {
   when_process(mock_journal_replay, EventEntry{OpFinishEvent(123, 0)},
                &on_finish_ready, &on_finish_safe);
 
-  on_finish->complete(0);
+  wait_for_op_invoked(&on_finish, -ENOENT);
   ASSERT_EQ(0, on_start_safe.wait());
   ASSERT_EQ(0, on_finish_ready.wait());
   ASSERT_EQ(0, on_finish_safe.wait());
@@ -543,12 +809,46 @@ TEST_F(TestMockJournalReplay, SnapRenameEvent) {
   librbd::ImageCtx *ictx;
   ASSERT_EQ(0, open_image(m_image_name, &ictx));
 
-  MockImageCtx mock_image_ctx(*ictx);
+  MockReplayImageCtx mock_image_ctx(*ictx);
+  MockJournalReplay mock_journal_replay(mock_image_ctx);
+  expect_op_work_queue(mock_image_ctx);
+
+  InSequence seq;
+  Context *on_finish = nullptr;
+  expect_refresh_image(mock_image_ctx, false, 0);
+  expect_snap_rename(mock_image_ctx, &on_finish, 234, "snap");
+
+  C_SaferCond on_start_ready;
+  C_SaferCond on_start_safe;
+  when_process(mock_journal_replay,
+               EventEntry{SnapRenameEvent(123, 234, "snap")},
+               &on_start_ready, &on_start_safe);
+  ASSERT_EQ(0, on_start_ready.wait());
+
+  C_SaferCond on_finish_ready;
+  C_SaferCond on_finish_safe;
+  when_process(mock_journal_replay, EventEntry{OpFinishEvent(123, 0)},
+               &on_finish_ready, &on_finish_safe);
+
+  wait_for_op_invoked(&on_finish, 0);
+  ASSERT_EQ(0, on_start_safe.wait());
+  ASSERT_EQ(0, on_finish_ready.wait());
+  ASSERT_EQ(0, on_finish_safe.wait());
+}
+
+TEST_F(TestMockJournalReplay, SnapRenameEventExists) {
+  REQUIRE_FEATURE(RBD_FEATURE_JOURNALING);
+
+  librbd::ImageCtx *ictx;
+  ASSERT_EQ(0, open_image(m_image_name, &ictx));
+
+  MockReplayImageCtx mock_image_ctx(*ictx);
   MockJournalReplay mock_journal_replay(mock_image_ctx);
   expect_op_work_queue(mock_image_ctx);
 
   InSequence seq;
-  Context *on_finish;
+  Context *on_finish = nullptr;
+  expect_refresh_image(mock_image_ctx, false, 0);
   expect_snap_rename(mock_image_ctx, &on_finish, 234, "snap");
 
   C_SaferCond on_start_ready;
@@ -563,7 +863,7 @@ TEST_F(TestMockJournalReplay, SnapRenameEvent) {
   when_process(mock_journal_replay, EventEntry{OpFinishEvent(123, 0)},
                &on_finish_ready, &on_finish_safe);
 
-  on_finish->complete(0);
+  wait_for_op_invoked(&on_finish, -EEXIST);
   ASSERT_EQ(0, on_start_safe.wait());
   ASSERT_EQ(0, on_finish_ready.wait());
   ASSERT_EQ(0, on_finish_safe.wait());
@@ -575,12 +875,45 @@ TEST_F(TestMockJournalReplay, SnapProtectEvent) {
   librbd::ImageCtx *ictx;
   ASSERT_EQ(0, open_image(m_image_name, &ictx));
 
-  MockImageCtx mock_image_ctx(*ictx);
+  MockReplayImageCtx mock_image_ctx(*ictx);
+  MockJournalReplay mock_journal_replay(mock_image_ctx);
+  expect_op_work_queue(mock_image_ctx);
+
+  InSequence seq;
+  Context *on_finish = nullptr;
+  expect_refresh_image(mock_image_ctx, false, 0);
+  expect_snap_protect(mock_image_ctx, &on_finish, "snap");
+
+  C_SaferCond on_start_ready;
+  C_SaferCond on_start_safe;
+  when_process(mock_journal_replay, EventEntry{SnapProtectEvent(123, "snap")},
+               &on_start_ready, &on_start_safe);
+  ASSERT_EQ(0, on_start_ready.wait());
+
+  C_SaferCond on_finish_ready;
+  C_SaferCond on_finish_safe;
+  when_process(mock_journal_replay, EventEntry{OpFinishEvent(123, 0)},
+               &on_finish_ready, &on_finish_safe);
+
+  wait_for_op_invoked(&on_finish, 0);
+  ASSERT_EQ(0, on_start_safe.wait());
+  ASSERT_EQ(0, on_finish_ready.wait());
+  ASSERT_EQ(0, on_finish_safe.wait());
+}
+
+TEST_F(TestMockJournalReplay, SnapProtectEventBusy) {
+  REQUIRE_FEATURE(RBD_FEATURE_JOURNALING);
+
+  librbd::ImageCtx *ictx;
+  ASSERT_EQ(0, open_image(m_image_name, &ictx));
+
+  MockReplayImageCtx mock_image_ctx(*ictx);
   MockJournalReplay mock_journal_replay(mock_image_ctx);
   expect_op_work_queue(mock_image_ctx);
 
   InSequence seq;
-  Context *on_finish;
+  Context *on_finish = nullptr;
+  expect_refresh_image(mock_image_ctx, false, 0);
   expect_snap_protect(mock_image_ctx, &on_finish, "snap");
 
   C_SaferCond on_start_ready;
@@ -594,7 +927,7 @@ TEST_F(TestMockJournalReplay, SnapProtectEvent) {
   when_process(mock_journal_replay, EventEntry{OpFinishEvent(123, 0)},
                &on_finish_ready, &on_finish_safe);
 
-  on_finish->complete(0);
+  wait_for_op_invoked(&on_finish, -EBUSY);
   ASSERT_EQ(0, on_start_safe.wait());
   ASSERT_EQ(0, on_finish_ready.wait());
   ASSERT_EQ(0, on_finish_safe.wait());
@@ -606,12 +939,13 @@ TEST_F(TestMockJournalReplay, SnapUnprotectEvent) {
   librbd::ImageCtx *ictx;
   ASSERT_EQ(0, open_image(m_image_name, &ictx));
 
-  MockImageCtx mock_image_ctx(*ictx);
+  MockReplayImageCtx mock_image_ctx(*ictx);
   MockJournalReplay mock_journal_replay(mock_image_ctx);
   expect_op_work_queue(mock_image_ctx);
 
   InSequence seq;
-  Context *on_finish;
+  Context *on_finish = nullptr;
+  expect_refresh_image(mock_image_ctx, false, 0);
   expect_snap_unprotect(mock_image_ctx, &on_finish, "snap");
 
   C_SaferCond on_start_ready;
@@ -625,7 +959,39 @@ TEST_F(TestMockJournalReplay, SnapUnprotectEvent) {
   when_process(mock_journal_replay, EventEntry{OpFinishEvent(123, 0)},
                &on_finish_ready, &on_finish_safe);
 
-  on_finish->complete(0);
+  wait_for_op_invoked(&on_finish, 0);
+  ASSERT_EQ(0, on_start_safe.wait());
+  ASSERT_EQ(0, on_finish_ready.wait());
+  ASSERT_EQ(0, on_finish_safe.wait());
+}
+
+TEST_F(TestMockJournalReplay, SnapUnprotectEventInvalid) {
+  REQUIRE_FEATURE(RBD_FEATURE_JOURNALING);
+
+  librbd::ImageCtx *ictx;
+  ASSERT_EQ(0, open_image(m_image_name, &ictx));
+
+  MockReplayImageCtx mock_image_ctx(*ictx);
+  MockJournalReplay mock_journal_replay(mock_image_ctx);
+  expect_op_work_queue(mock_image_ctx);
+
+  InSequence seq;
+  Context *on_finish = nullptr;
+  expect_refresh_image(mock_image_ctx, false, 0);
+  expect_snap_unprotect(mock_image_ctx, &on_finish, "snap");
+
+  C_SaferCond on_start_ready;
+  C_SaferCond on_start_safe;
+  when_process(mock_journal_replay, EventEntry{SnapUnprotectEvent(123, "snap")},
+               &on_start_ready, &on_start_safe);
+  ASSERT_EQ(0, on_start_ready.wait());
+
+  C_SaferCond on_finish_ready;
+  C_SaferCond on_finish_safe;
+  when_process(mock_journal_replay, EventEntry{OpFinishEvent(123, 0)},
+               &on_finish_ready, &on_finish_safe);
+
+  wait_for_op_invoked(&on_finish, -EINVAL);
   ASSERT_EQ(0, on_start_safe.wait());
   ASSERT_EQ(0, on_finish_ready.wait());
   ASSERT_EQ(0, on_finish_safe.wait());
@@ -637,12 +1003,13 @@ TEST_F(TestMockJournalReplay, SnapRollbackEvent) {
   librbd::ImageCtx *ictx;
   ASSERT_EQ(0, open_image(m_image_name, &ictx));
 
-  MockImageCtx mock_image_ctx(*ictx);
+  MockReplayImageCtx mock_image_ctx(*ictx);
   MockJournalReplay mock_journal_replay(mock_image_ctx);
   expect_op_work_queue(mock_image_ctx);
 
   InSequence seq;
-  Context *on_finish;
+  Context *on_finish = nullptr;
+  expect_refresh_image(mock_image_ctx, false, 0);
   expect_snap_rollback(mock_image_ctx, &on_finish, "snap");
 
   C_SaferCond on_start_ready;
@@ -656,7 +1023,7 @@ TEST_F(TestMockJournalReplay, SnapRollbackEvent) {
   when_process(mock_journal_replay, EventEntry{OpFinishEvent(123, 0)},
                &on_finish_ready, &on_finish_safe);
 
-  on_finish->complete(0);
+  wait_for_op_invoked(&on_finish, 0);
   ASSERT_EQ(0, on_start_safe.wait());
   ASSERT_EQ(0, on_finish_ready.wait());
   ASSERT_EQ(0, on_finish_safe.wait());
@@ -668,12 +1035,45 @@ TEST_F(TestMockJournalReplay, RenameEvent) {
   librbd::ImageCtx *ictx;
   ASSERT_EQ(0, open_image(m_image_name, &ictx));
 
-  MockImageCtx mock_image_ctx(*ictx);
+  MockReplayImageCtx mock_image_ctx(*ictx);
+  MockJournalReplay mock_journal_replay(mock_image_ctx);
+  expect_op_work_queue(mock_image_ctx);
+
+  InSequence seq;
+  Context *on_finish = nullptr;
+  expect_refresh_image(mock_image_ctx, false, 0);
+  expect_rename(mock_image_ctx, &on_finish, "image");
+
+  C_SaferCond on_start_ready;
+  C_SaferCond on_start_safe;
+  when_process(mock_journal_replay, EventEntry{RenameEvent(123, "image")},
+               &on_start_ready, &on_start_safe);
+  ASSERT_EQ(0, on_start_ready.wait());
+
+  C_SaferCond on_finish_ready;
+  C_SaferCond on_finish_safe;
+  when_process(mock_journal_replay, EventEntry{OpFinishEvent(123, 0)},
+               &on_finish_ready, &on_finish_safe);
+
+  wait_for_op_invoked(&on_finish, 0);
+  ASSERT_EQ(0, on_start_safe.wait());
+  ASSERT_EQ(0, on_finish_ready.wait());
+  ASSERT_EQ(0, on_finish_safe.wait());
+}
+
+TEST_F(TestMockJournalReplay, RenameEventExists) {
+  REQUIRE_FEATURE(RBD_FEATURE_JOURNALING);
+
+  librbd::ImageCtx *ictx;
+  ASSERT_EQ(0, open_image(m_image_name, &ictx));
+
+  MockReplayImageCtx mock_image_ctx(*ictx);
   MockJournalReplay mock_journal_replay(mock_image_ctx);
   expect_op_work_queue(mock_image_ctx);
 
   InSequence seq;
-  Context *on_finish;
+  Context *on_finish = nullptr;
+  expect_refresh_image(mock_image_ctx, false, 0);
   expect_rename(mock_image_ctx, &on_finish, "image");
 
   C_SaferCond on_start_ready;
@@ -687,7 +1087,7 @@ TEST_F(TestMockJournalReplay, RenameEvent) {
   when_process(mock_journal_replay, EventEntry{OpFinishEvent(123, 0)},
                &on_finish_ready, &on_finish_safe);
 
-  on_finish->complete(0);
+  wait_for_op_invoked(&on_finish, -EEXIST);
   ASSERT_EQ(0, on_start_safe.wait());
   ASSERT_EQ(0, on_finish_ready.wait());
   ASSERT_EQ(0, on_finish_safe.wait());
@@ -699,12 +1099,13 @@ TEST_F(TestMockJournalReplay, ResizeEvent) {
   librbd::ImageCtx *ictx;
   ASSERT_EQ(0, open_image(m_image_name, &ictx));
 
-  MockImageCtx mock_image_ctx(*ictx);
+  MockReplayImageCtx mock_image_ctx(*ictx);
   MockJournalReplay mock_journal_replay(mock_image_ctx);
   expect_op_work_queue(mock_image_ctx);
 
   InSequence seq;
-  Context *on_finish;
+  Context *on_finish = nullptr;
+  expect_refresh_image(mock_image_ctx, false, 0);
   expect_resize(mock_image_ctx, &on_finish, 234, 123);
 
   C_SaferCond on_start_ready;
@@ -722,7 +1123,7 @@ TEST_F(TestMockJournalReplay, ResizeEvent) {
                &on_finish_ready, &on_finish_safe);
 
   ASSERT_EQ(0, on_resume.wait());
-  on_finish->complete(0);
+  wait_for_op_invoked(&on_finish, 0);
 
   ASSERT_EQ(0, on_start_safe.wait());
   ASSERT_EQ(0, on_finish_ready.wait());
@@ -735,12 +1136,13 @@ TEST_F(TestMockJournalReplay, FlattenEvent) {
   librbd::ImageCtx *ictx;
   ASSERT_EQ(0, open_image(m_image_name, &ictx));
 
-  MockImageCtx mock_image_ctx(*ictx);
+  MockReplayImageCtx mock_image_ctx(*ictx);
   MockJournalReplay mock_journal_replay(mock_image_ctx);
   expect_op_work_queue(mock_image_ctx);
 
   InSequence seq;
-  Context *on_finish;
+  Context *on_finish = nullptr;
+  expect_refresh_image(mock_image_ctx, false, 0);
   expect_flatten(mock_image_ctx, &on_finish);
 
   C_SaferCond on_start_ready;
@@ -754,7 +1156,39 @@ TEST_F(TestMockJournalReplay, FlattenEvent) {
   when_process(mock_journal_replay, EventEntry{OpFinishEvent(123, 0)},
                &on_finish_ready, &on_finish_safe);
 
-  on_finish->complete(0);
+  wait_for_op_invoked(&on_finish, 0);
+  ASSERT_EQ(0, on_start_safe.wait());
+  ASSERT_EQ(0, on_finish_ready.wait());
+  ASSERT_EQ(0, on_finish_safe.wait());
+}
+
+TEST_F(TestMockJournalReplay, FlattenEventInvalid) {
+  REQUIRE_FEATURE(RBD_FEATURE_JOURNALING);
+
+  librbd::ImageCtx *ictx;
+  ASSERT_EQ(0, open_image(m_image_name, &ictx));
+
+  MockReplayImageCtx mock_image_ctx(*ictx);
+  MockJournalReplay mock_journal_replay(mock_image_ctx);
+  expect_op_work_queue(mock_image_ctx);
+
+  InSequence seq;
+  Context *on_finish = nullptr;
+  expect_refresh_image(mock_image_ctx, false, 0);
+  expect_flatten(mock_image_ctx, &on_finish);
+
+  C_SaferCond on_start_ready;
+  C_SaferCond on_start_safe;
+  when_process(mock_journal_replay, EventEntry{FlattenEvent(123)},
+               &on_start_ready, &on_start_safe);
+  ASSERT_EQ(0, on_start_ready.wait());
+
+  C_SaferCond on_finish_ready;
+  C_SaferCond on_finish_safe;
+  when_process(mock_journal_replay, EventEntry{OpFinishEvent(123, 0)},
+               &on_finish_ready, &on_finish_safe);
+
+  wait_for_op_invoked(&on_finish, -EINVAL);
   ASSERT_EQ(0, on_start_safe.wait());
   ASSERT_EQ(0, on_finish_ready.wait());
   ASSERT_EQ(0, on_finish_safe.wait());
@@ -766,7 +1200,7 @@ TEST_F(TestMockJournalReplay, UnknownEvent) {
   librbd::ImageCtx *ictx;
   ASSERT_EQ(0, open_image(m_image_name, &ictx));
 
-  MockImageCtx mock_image_ctx(*ictx);
+  MockReplayImageCtx mock_image_ctx(*ictx);
   MockJournalReplay mock_journal_replay(mock_image_ctx);
   expect_op_work_queue(mock_image_ctx);
 
@@ -786,5 +1220,42 @@ TEST_F(TestMockJournalReplay, UnknownEvent) {
   ASSERT_EQ(0, on_ready.wait());
 }
 
+TEST_F(TestMockJournalReplay, RefreshImageBeforeOpStart) {
+  REQUIRE_FEATURE(RBD_FEATURE_JOURNALING);
+
+  librbd::ImageCtx *ictx;
+  ASSERT_EQ(0, open_image(m_image_name, &ictx));
+
+  MockReplayImageCtx mock_image_ctx(*ictx);
+  MockJournalReplay mock_journal_replay(mock_image_ctx);
+  expect_op_work_queue(mock_image_ctx);
+
+  InSequence seq;
+  Context *on_finish = nullptr;
+  expect_refresh_image(mock_image_ctx, true, 0);
+  expect_resize(mock_image_ctx, &on_finish, 234, 123);
+
+  C_SaferCond on_start_ready;
+  C_SaferCond on_start_safe;
+  when_process(mock_journal_replay, EventEntry{ResizeEvent(123, 234)},
+               &on_start_ready, &on_start_safe);
+
+  C_SaferCond on_resume;
+  when_replay_op_ready(mock_journal_replay, 123, &on_resume);
+  ASSERT_EQ(0, on_start_ready.wait());
+
+  C_SaferCond on_finish_ready;
+  C_SaferCond on_finish_safe;
+  when_process(mock_journal_replay, EventEntry{OpFinishEvent(123, 0)},
+               &on_finish_ready, &on_finish_safe);
+
+  ASSERT_EQ(0, on_resume.wait());
+  wait_for_op_invoked(&on_finish, 0);
+
+  ASSERT_EQ(0, on_start_safe.wait());
+  ASSERT_EQ(0, on_finish_ready.wait());
+  ASSERT_EQ(0, on_finish_safe.wait());
+}
+
 } // namespace journal
 } // namespace librbd
diff --git a/src/test/librbd/mock/MockAioImageRequestWQ.h b/src/test/librbd/mock/MockAioImageRequestWQ.h
index c4dbd3b..77419c0 100644
--- a/src/test/librbd/mock/MockAioImageRequestWQ.h
+++ b/src/test/librbd/mock/MockAioImageRequestWQ.h
@@ -6,13 +6,18 @@
 
 #include "gmock/gmock.h"
 
+class Context;
+
 namespace librbd {
 
 struct MockAioImageRequestWQ {
   MOCK_METHOD1(block_writes, void(Context *));
   MOCK_METHOD0(unblock_writes, void());
 
-  MOCK_CONST_METHOD0(writes_empty, bool());
+  MOCK_METHOD0(set_require_lock_on_read, void());
+  MOCK_METHOD0(clear_require_lock_on_read, void());
+
+  MOCK_CONST_METHOD0(is_lock_request_needed, bool());
 };
 
 } // namespace librbd
diff --git a/src/test/librbd/mock/MockExclusiveLock.h b/src/test/librbd/mock/MockExclusiveLock.h
index 430dbc7..97f9da1 100644
--- a/src/test/librbd/mock/MockExclusiveLock.h
+++ b/src/test/librbd/mock/MockExclusiveLock.h
@@ -17,7 +17,7 @@ struct MockExclusiveLock {
 
   MOCK_METHOD1(assert_header_locked, void(librados::ObjectWriteOperation *));
 
-  MOCK_METHOD1(init, void(Context*));
+  MOCK_METHOD2(init, void(uint64_t features, Context*));
   MOCK_METHOD1(shut_down, void(Context*));
 };
 
diff --git a/src/test/librbd/mock/MockImageCtx.h b/src/test/librbd/mock/MockImageCtx.h
index 0c9b7a1..60d5fbb 100644
--- a/src/test/librbd/mock/MockImageCtx.h
+++ b/src/test/librbd/mock/MockImageCtx.h
@@ -7,6 +7,7 @@
 #include "test/librbd/mock/MockAioImageRequestWQ.h"
 #include "test/librbd/mock/MockContextWQ.h"
 #include "test/librbd/mock/MockExclusiveLock.h"
+#include "test/librbd/mock/MockImageState.h"
 #include "test/librbd/mock/MockImageWatcher.h"
 #include "test/librbd/mock/MockJournal.h"
 #include "test/librbd/mock/MockObjectMap.h"
@@ -59,6 +60,7 @@ struct MockImageCtx {
       aio_work_queue(new MockAioImageRequestWQ()),
       op_work_queue(new MockContextWQ()),
       parent(NULL), operations(new MockOperations()),
+      state(new MockImageState()),
       image_watcher(NULL), object_map(NULL),
       exclusive_lock(NULL), journal(NULL),
       concurrent_management_ops(image_ctx.concurrent_management_ops),
@@ -85,6 +87,7 @@ struct MockImageCtx {
     image_ctx->md_ctx.aio_flush();
     image_ctx->data_ctx.aio_flush();
     image_ctx->op_work_queue->drain();
+    delete state;
     delete operations;
     delete image_watcher;
     delete op_work_queue;
@@ -110,6 +113,7 @@ struct MockImageCtx {
   MOCK_CONST_METHOD1(get_object_name, std::string(uint64_t));
   MOCK_CONST_METHOD0(get_current_size, uint64_t());
   MOCK_CONST_METHOD1(get_image_size, uint64_t(librados::snap_t));
+  MOCK_CONST_METHOD1(get_object_count, uint64_t(librados::snap_t));
   MOCK_CONST_METHOD1(get_snap_id, librados::snap_t(std::string in_snap_name));
   MOCK_CONST_METHOD1(get_snap_info, const SnapInfo*(librados::snap_t));
   MOCK_CONST_METHOD2(get_parent_spec, int(librados::snap_t in_snap_id,
@@ -141,6 +145,9 @@ struct MockImageCtx {
   MOCK_METHOD1(create_object_map, MockObjectMap*(uint64_t));
   MOCK_METHOD0(create_journal, MockJournal*());
 
+  MOCK_METHOD0(notify_update, void());
+  MOCK_METHOD1(notify_update, void(Context *));
+
   ImageCtx *image_ctx;
   CephContext *cct;
 
@@ -183,7 +190,7 @@ struct MockImageCtx {
   std::string id;
   parent_info parent_md;
 
-  ceph_file_layout layout;
+  file_layout_t layout;
 
   xlist<operation::ResizeRequest<MockImageCtx>*> resize_reqs;
   xlist<AsyncRequest<MockImageCtx>*> async_requests;
@@ -197,6 +204,7 @@ struct MockImageCtx {
 
   MockImageCtx *parent;
   MockOperations *operations;
+  MockImageState *state;
 
   MockImageWatcher *image_watcher;
   MockObjectMap *object_map;
diff --git a/src/test/librbd/mock/MockImageState.h b/src/test/librbd/mock/MockImageState.h
new file mode 100644
index 0000000..6f75ecd
--- /dev/null
+++ b/src/test/librbd/mock/MockImageState.h
@@ -0,0 +1,20 @@
+// -*- mode:C; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+
+#ifndef CEPH_TEST_LIBRBD_MOCK_IMAGE_STATE_H
+#define CEPH_TEST_LIBRBD_MOCK_IMAGE_STATE_H
+
+#include <gmock/gmock.h>
+
+class Context;
+
+namespace librbd {
+
+struct MockImageState {
+  MOCK_CONST_METHOD0(is_refresh_required, bool());
+  MOCK_METHOD1(refresh, void(Context*));
+};
+
+} // namespace librbd
+
+#endif // CEPH_TEST_LIBRBD_MOCK_IMAGE_STATE_H
diff --git a/src/test/librbd/mock/MockImageWatcher.h b/src/test/librbd/mock/MockImageWatcher.h
index 20164ea..d1a7c64 100644
--- a/src/test/librbd/mock/MockImageWatcher.h
+++ b/src/test/librbd/mock/MockImageWatcher.h
@@ -6,10 +6,13 @@
 
 #include "gmock/gmock.h"
 
+class Context;
+
 namespace librbd {
 
 struct MockImageWatcher {
   MOCK_METHOD0(unregister_watch, void());
+  MOCK_METHOD1(flush, void(Context *));
 
   MOCK_CONST_METHOD0(get_watch_handle, uint64_t());
 
diff --git a/src/test/librbd/mock/MockJournal.h b/src/test/librbd/mock/MockJournal.h
index 9fe3518..1393399 100644
--- a/src/test/librbd/mock/MockJournal.h
+++ b/src/test/librbd/mock/MockJournal.h
@@ -16,6 +16,9 @@ struct MockJournal {
 
   MOCK_METHOD1(wait_for_journal_ready, void(Context *));
 
+  MOCK_CONST_METHOD0(is_tag_owner, bool());
+  MOCK_METHOD2(allocate_tag, void(const std::string &, Context *));
+
   MOCK_METHOD1(open, void(Context *));
   MOCK_METHOD1(close, void(Context *));
 
diff --git a/src/test/librbd/mock/MockObjectMap.h b/src/test/librbd/mock/MockObjectMap.h
index ae452a5..25d14ed 100644
--- a/src/test/librbd/mock/MockObjectMap.h
+++ b/src/test/librbd/mock/MockObjectMap.h
@@ -4,6 +4,7 @@
 #ifndef CEPH_TEST_LIBRBD_MOCK_OBJECT_MAP_H
 #define CEPH_TEST_LIBRBD_MOCK_OBJECT_MAP_H
 
+#include "common/RWLock.h"
 #include "gmock/gmock.h"
 
 namespace librbd {
@@ -16,7 +17,10 @@ struct MockObjectMap {
 
   MOCK_METHOD3(aio_resize, void(uint64_t new_size, uint8_t default_object_state,
                                 Context *on_finish));
-
+  MOCK_METHOD6(aio_update, void(uint64_t snap_id, uint64_t start_object_no,
+                                uint64_t end_object_no, uint8_t new_state,
+                                const boost::optional<uint8_t> &current_state,
+                                Context *on_finish));
   MOCK_METHOD2(snapshot_add, void(uint64_t snap_id, Context *on_finish));
   MOCK_METHOD2(snapshot_remove, void(uint64_t snap_id, Context *on_finish));
   MOCK_METHOD2(rollback, void(uint64_t snap_id, Context *on_finish));
diff --git a/src/test/librbd/mock/MockOperations.h b/src/test/librbd/mock/MockOperations.h
index c3bf9d9..6150125 100644
--- a/src/test/librbd/mock/MockOperations.h
+++ b/src/test/librbd/mock/MockOperations.h
@@ -12,22 +12,31 @@ class Context;
 namespace librbd {
 
 struct MockOperations {
-  MOCK_METHOD2(flatten, void(ProgressContext &prog_ctx, Context *on_finish));
-  MOCK_METHOD2(rebuild_object_map, void(ProgressContext &prog_ctx,
-                                        Context *on_finish));
-  MOCK_METHOD2(rename, void(const char *dstname, Context *on_finish));
-  MOCK_METHOD4(resize, void(uint64_t size, ProgressContext &prog_ctx,
-                            Context *on_finish, uint64_t journal_op_tid));
-  MOCK_METHOD3(snap_create, void(const char *snap_name, Context *on_finish,
-                                 uint64_t journal_op_tid));
+  MOCK_METHOD2(execute_flatten, void(ProgressContext &prog_ctx,
+                                     Context *on_finish));
+  MOCK_METHOD2(execute_rebuild_object_map, void(ProgressContext &prog_ctx,
+                                                Context *on_finish));
+  MOCK_METHOD2(execute_rename, void(const char *dstname, Context *on_finish));
+  MOCK_METHOD4(execute_resize, void(uint64_t size, ProgressContext &prog_ctx,
+                                    Context *on_finish,
+                                    uint64_t journal_op_tid));
+  MOCK_METHOD2(snap_create, void(const char *snap_name, Context *on_finish));
+  MOCK_METHOD3(execute_snap_create, void(const char *snap_name,
+                                         Context *on_finish,
+                                         uint64_t journal_op_tid));
   MOCK_METHOD2(snap_remove, void(const char *snap_name, Context *on_finish));
-  MOCK_METHOD3(snap_rename, void(uint64_t src_snap_id, const char *snap_name,
-                                 Context *on_finish));
-  MOCK_METHOD3(snap_rollback, void(const char *snap_name,
-                                   ProgressContext &prog_ctx,
-                                   Context *on_finish));
-  MOCK_METHOD2(snap_protect, void(const char *snap_name, Context *on_finish));
-  MOCK_METHOD2(snap_unprotect, void(const char *snap_name, Context *on_finish));
+  MOCK_METHOD2(execute_snap_remove, void(const char *snap_name,
+                                         Context *on_finish));
+  MOCK_METHOD3(execute_snap_rename, void(uint64_t src_snap_id,
+                                         const char *snap_name,
+                                         Context *on_finish));
+  MOCK_METHOD3(execute_snap_rollback, void(const char *snap_name,
+                                           ProgressContext &prog_ctx,
+                                           Context *on_finish));
+  MOCK_METHOD2(execute_snap_protect, void(const char *snap_name,
+                                          Context *on_finish));
+  MOCK_METHOD2(execute_snap_unprotect, void(const char *snap_name,
+                                            Context *on_finish));
 };
 
 } // namespace librbd
diff --git a/src/test/librbd/object_map/mock/MockInvalidateRequest.h b/src/test/librbd/object_map/mock/MockInvalidateRequest.h
index b7d02c6..b4fc78b 100644
--- a/src/test/librbd/object_map/mock/MockInvalidateRequest.h
+++ b/src/test/librbd/object_map/mock/MockInvalidateRequest.h
@@ -9,17 +9,17 @@
 namespace librbd {
 namespace object_map {
 
-template <>
-struct InvalidateRequest<MockImageCtx> {
-  static std::list<InvalidateRequest *> s_requests;
+template <typename I>
+struct MockInvalidateRequestBase {
+  static std::list<InvalidateRequest<I>*> s_requests;
   uint64_t snap_id;
   bool force;
   Context *on_finish;
 
-  static InvalidateRequest* create(MockImageCtx &image_ctx, uint64_t snap_id,
-                                   bool force, Context *on_finish) {
+  static InvalidateRequest<I>* create(I &image_ctx, uint64_t snap_id,
+                                      bool force, Context *on_finish) {
     assert(!s_requests.empty());
-    InvalidateRequest* req = s_requests.front();
+    InvalidateRequest<I>* req = s_requests.front();
     req->snap_id = snap_id;
     req->force = force;
     req->on_finish = on_finish;
@@ -27,16 +27,15 @@ struct InvalidateRequest<MockImageCtx> {
     return req;
   }
 
-  InvalidateRequest() {
-    s_requests.push_back(this);
+  MockInvalidateRequestBase() {
+    s_requests.push_back(static_cast<InvalidateRequest<I>*>(this));
   }
 
   MOCK_METHOD0(send, void());
 };
 
-typedef InvalidateRequest<MockImageCtx> MockInvalidateRequest;
-
-std::list<InvalidateRequest<MockImageCtx>*> InvalidateRequest<MockImageCtx>::s_requests;
+template <typename I>
+std::list<InvalidateRequest<I>*> MockInvalidateRequestBase<I>::s_requests;
 
 } // namespace object_map
 } // namespace librbd
diff --git a/src/test/librbd/object_map/test_mock_InvalidateRequest.cc b/src/test/librbd/object_map/test_mock_InvalidateRequest.cc
index 9f20a47..4f3831c 100644
--- a/src/test/librbd/object_map/test_mock_InvalidateRequest.cc
+++ b/src/test/librbd/object_map/test_mock_InvalidateRequest.cc
@@ -15,6 +15,7 @@ namespace object_map {
 using ::testing::_;
 using ::testing::DoDefault;
 using ::testing::Return;
+using ::testing::StrEq;
 
 class TestMockObjectMapInvalidateRequest : public TestMockFixture {
 public:
@@ -31,7 +32,7 @@ TEST_F(TestMockObjectMapInvalidateRequest, UpdatesInMemoryFlag) {
   AsyncRequest<> *request = new InvalidateRequest<>(*ictx, CEPH_NOSNAP, false, &cond_ctx);
 
   EXPECT_CALL(get_mock_io_ctx(ictx->md_ctx),
-              exec(ictx->header_oid, _, "rbd", "set_flags", _, _, _))
+              exec(ictx->header_oid, _, StrEq("rbd"), StrEq("set_flags"), _, _, _))
                 .Times(0);
 
   {
@@ -55,10 +56,10 @@ TEST_F(TestMockObjectMapInvalidateRequest, UpdatesHeadOnDiskFlag) {
   AsyncRequest<> *request = new InvalidateRequest<>(*ictx, CEPH_NOSNAP, false, &cond_ctx);
 
   EXPECT_CALL(get_mock_io_ctx(ictx->md_ctx),
-              exec(ictx->header_oid, _, "lock", "assert_locked", _, _, _))
+              exec(ictx->header_oid, _, StrEq("lock"), StrEq("assert_locked"), _, _, _))
                 .WillOnce(DoDefault());
   EXPECT_CALL(get_mock_io_ctx(ictx->md_ctx),
-              exec(ictx->header_oid, _, "rbd", "set_flags", _, _, _))
+              exec(ictx->header_oid, _, StrEq("rbd"), StrEq("set_flags"), _, _, _))
                 .WillOnce(DoDefault());
 
   {
@@ -85,10 +86,10 @@ TEST_F(TestMockObjectMapInvalidateRequest, UpdatesSnapOnDiskFlag) {
                                                 &cond_ctx);
 
   EXPECT_CALL(get_mock_io_ctx(ictx->md_ctx),
-              exec(ictx->header_oid, _, "lock", "assert_locked", _, _, _))
+              exec(ictx->header_oid, _, StrEq("lock"), StrEq("assert_locked"), _, _, _))
                 .Times(0);
   EXPECT_CALL(get_mock_io_ctx(ictx->md_ctx),
-              exec(ictx->header_oid, _, "rbd", "set_flags", _, _, _))
+              exec(ictx->header_oid, _, StrEq("rbd"), StrEq("set_flags"), _, _, _))
                 .WillOnce(DoDefault());
 
   {
@@ -109,7 +110,7 @@ TEST_F(TestMockObjectMapInvalidateRequest, SkipOnDiskUpdateWithoutLock) {
   AsyncRequest<> *request = new InvalidateRequest<>(*ictx, CEPH_NOSNAP, false, &cond_ctx);
 
   EXPECT_CALL(get_mock_io_ctx(ictx->md_ctx),
-              exec(ictx->header_oid, _, "rbd", "set_flags", _, _, _))
+              exec(ictx->header_oid, _, StrEq("rbd"), StrEq("set_flags"), _, _, _))
                 .Times(0);
 
   {
@@ -133,10 +134,10 @@ TEST_F(TestMockObjectMapInvalidateRequest, IgnoresOnDiskUpdateFailure) {
   AsyncRequest<> *request = new InvalidateRequest<>(*ictx, CEPH_NOSNAP, false, &cond_ctx);
 
   EXPECT_CALL(get_mock_io_ctx(ictx->md_ctx),
-              exec(ictx->header_oid, _, "lock", "assert_locked", _, _, _))
+              exec(ictx->header_oid, _, StrEq("lock"), StrEq("assert_locked"), _, _, _))
                 .WillOnce(DoDefault());
   EXPECT_CALL(get_mock_io_ctx(ictx->md_ctx),
-              exec(ictx->header_oid, _, "rbd", "set_flags", _, _, _))
+              exec(ictx->header_oid, _, StrEq("rbd"), StrEq("set_flags"), _, _, _))
                 .WillOnce(Return(-EINVAL));
 
   {
diff --git a/src/test/librbd/object_map/test_mock_LockRequest.cc b/src/test/librbd/object_map/test_mock_LockRequest.cc
index e7a62fd..0ee782b 100644
--- a/src/test/librbd/object_map/test_mock_LockRequest.cc
+++ b/src/test/librbd/object_map/test_mock_LockRequest.cc
@@ -19,6 +19,7 @@ using ::testing::_;
 using ::testing::DoAll;
 using ::testing::InSequence;
 using ::testing::Return;
+using ::testing::StrEq;
 using ::testing::WithArg;
 
 class TestMockObjectMapLockRequest : public TestMockFixture {
@@ -28,14 +29,14 @@ public:
   void expect_lock(MockImageCtx &mock_image_ctx, int r) {
     std::string oid(ObjectMap::object_map_name(mock_image_ctx.id, CEPH_NOSNAP));
     EXPECT_CALL(get_mock_io_ctx(mock_image_ctx.md_ctx),
-                exec(oid, _, "lock", "lock", _, _, _))
+                exec(oid, _, StrEq("lock"), StrEq("lock"), _, _, _))
                   .WillOnce(Return(r));
   }
 
   void expect_get_lock_info(MockImageCtx &mock_image_ctx, int r) {
     std::string oid(ObjectMap::object_map_name(mock_image_ctx.id, CEPH_NOSNAP));
     auto &expect = EXPECT_CALL(get_mock_io_ctx(mock_image_ctx.md_ctx),
-                               exec(oid, _, "lock", "get_info", _, _, _));
+                               exec(oid, _, StrEq("lock"), StrEq("get_info"), _, _, _));
     if (r < 0) {
       expect.WillOnce(Return(r));
     } else {
@@ -60,7 +61,7 @@ public:
   void expect_break_lock(MockImageCtx &mock_image_ctx, int r) {
     std::string oid(ObjectMap::object_map_name(mock_image_ctx.id, CEPH_NOSNAP));
     auto &expect = EXPECT_CALL(get_mock_io_ctx(mock_image_ctx.md_ctx),
-                               exec(oid, _, "lock", "break_lock", _, _, _));
+                               exec(oid, _, StrEq("lock"), StrEq("break_lock"), _, _, _));
     if (r < 0) {
       expect.WillOnce(Return(r));
     } else {
diff --git a/src/test/librbd/object_map/test_mock_RefreshRequest.cc b/src/test/librbd/object_map/test_mock_RefreshRequest.cc
index 2abfd8e..0dfbb4c 100644
--- a/src/test/librbd/object_map/test_mock_RefreshRequest.cc
+++ b/src/test/librbd/object_map/test_mock_RefreshRequest.cc
@@ -12,13 +12,23 @@
 #include "librbd/object_map/LockRequest.h"
 
 namespace librbd {
+
+namespace {
+
+struct MockObjectMapImageCtx : public MockImageCtx {
+  MockObjectMapImageCtx(ImageCtx &image_ctx) : MockImageCtx(image_ctx) {
+  }
+};
+
+} // anonymous namespace
+
 namespace object_map {
 
 template <>
-class LockRequest<MockImageCtx> {
+class LockRequest<MockObjectMapImageCtx> {
 public:
   static LockRequest *s_instance;
-  static LockRequest *create(MockImageCtx &image_ctx, Context *on_finish) {
+  static LockRequest *create(MockObjectMapImageCtx &image_ctx, Context *on_finish) {
     assert(s_instance != nullptr);
     s_instance->on_finish = on_finish;
     return s_instance;
@@ -33,7 +43,12 @@ public:
   MOCK_METHOD0(send, void());
 };
 
-LockRequest<MockImageCtx> *LockRequest<MockImageCtx>::s_instance = nullptr;
+template<>
+struct InvalidateRequest<MockObjectMapImageCtx> :
+    public MockInvalidateRequestBase<MockObjectMapImageCtx> {
+};
+
+LockRequest<MockObjectMapImageCtx> *LockRequest<MockObjectMapImageCtx>::s_instance = nullptr;
 
 } // namespace object_map
 } // namespace librbd
@@ -50,28 +65,30 @@ using ::testing::DoAll;
 using ::testing::DoDefault;
 using ::testing::InSequence;
 using ::testing::Return;
+using ::testing::StrEq;
 using ::testing::WithArg;
 
 class TestMockObjectMapRefreshRequest : public TestMockFixture {
 public:
   static const uint64_t TEST_SNAP_ID = 123;
 
-  typedef RefreshRequest<MockImageCtx> MockRefreshRequest;
-  typedef LockRequest<MockImageCtx> MockLockRequest;
+  typedef RefreshRequest<MockObjectMapImageCtx> MockRefreshRequest;
+  typedef LockRequest<MockObjectMapImageCtx> MockLockRequest;
+  typedef InvalidateRequest<MockObjectMapImageCtx> MockInvalidateRequest;
 
-  void expect_object_map_lock(MockImageCtx &mock_image_ctx,
+  void expect_object_map_lock(MockObjectMapImageCtx &mock_image_ctx,
                               MockLockRequest &mock_lock_request) {
     EXPECT_CALL(mock_lock_request, send())
                   .WillOnce(FinishRequest(&mock_lock_request, 0,
                                           &mock_image_ctx));
   }
 
-  void expect_object_map_load(MockImageCtx &mock_image_ctx,
+  void expect_object_map_load(MockObjectMapImageCtx &mock_image_ctx,
                               ceph::BitVector<2> *object_map, uint64_t snap_id,
                               int r) {
     std::string oid(ObjectMap::object_map_name(mock_image_ctx.id, snap_id));
     auto &expect = EXPECT_CALL(get_mock_io_ctx(mock_image_ctx.md_ctx),
-                               exec(oid, _, "rbd", "object_map_load", _, _, _));
+                               exec(oid, _, StrEq("rbd"), StrEq("object_map_load"), _, _, _));
     if (r < 0) {
       expect.WillOnce(Return(r));
     } else {
@@ -86,34 +103,34 @@ public:
     }
   }
 
-  void expect_get_image_size(MockImageCtx &mock_image_ctx, uint64_t snap_id,
+  void expect_get_image_size(MockObjectMapImageCtx &mock_image_ctx, uint64_t snap_id,
                              uint64_t size) {
     EXPECT_CALL(mock_image_ctx, get_image_size(snap_id))
                   .WillOnce(Return(size));
   }
 
-  void expect_invalidate_request(MockImageCtx &mock_image_ctx,
+  void expect_invalidate_request(MockObjectMapImageCtx &mock_image_ctx,
                                  MockInvalidateRequest &invalidate_request) {
     EXPECT_CALL(invalidate_request, send())
                   .WillOnce(FinishRequest(&invalidate_request, 0,
                                           &mock_image_ctx));
   }
 
-  void expect_truncate_request(MockImageCtx &mock_image_ctx) {
+  void expect_truncate_request(MockObjectMapImageCtx &mock_image_ctx) {
     std::string oid(ObjectMap::object_map_name(mock_image_ctx.id, TEST_SNAP_ID));
     EXPECT_CALL(get_mock_io_ctx(mock_image_ctx.md_ctx), truncate(oid, 0, _))
                   .WillOnce(Return(0));
   }
 
-  void expect_object_map_resize(MockImageCtx &mock_image_ctx,
+  void expect_object_map_resize(MockObjectMapImageCtx &mock_image_ctx,
                                 uint64_t num_objects, int r) {
     std::string oid(ObjectMap::object_map_name(mock_image_ctx.id, TEST_SNAP_ID));
     auto &expect = EXPECT_CALL(get_mock_io_ctx(mock_image_ctx.md_ctx),
-                               exec(oid, _, "rbd", "object_map_resize", _, _, _));
+                               exec(oid, _, StrEq("rbd"), StrEq("object_map_resize"), _, _, _));
     expect.WillOnce(Return(r));
   }
 
-  void init_object_map(MockImageCtx &mock_image_ctx,
+  void init_object_map(MockObjectMapImageCtx &mock_image_ctx,
                        ceph::BitVector<2> *object_map) {
     uint64_t num_objs = Striper::get_num_objects(
       mock_image_ctx.layout, mock_image_ctx.image_ctx->size);
@@ -128,7 +145,7 @@ TEST_F(TestMockObjectMapRefreshRequest, SuccessHead) {
   librbd::ImageCtx *ictx;
   ASSERT_EQ(0, open_image(m_image_name, &ictx));
 
-  MockImageCtx mock_image_ctx(*ictx);
+  MockObjectMapImageCtx mock_image_ctx(*ictx);
 
   ceph::BitVector<2> on_disk_object_map;
   init_object_map(mock_image_ctx, &on_disk_object_map);
@@ -156,7 +173,7 @@ TEST_F(TestMockObjectMapRefreshRequest, SuccessSnapshot) {
   librbd::ImageCtx *ictx;
   ASSERT_EQ(0, open_image(m_image_name, &ictx));
 
-  MockImageCtx mock_image_ctx(*ictx);
+  MockObjectMapImageCtx mock_image_ctx(*ictx);
 
   ceph::BitVector<2> on_disk_object_map;
   init_object_map(mock_image_ctx, &on_disk_object_map);
@@ -182,7 +199,7 @@ TEST_F(TestMockObjectMapRefreshRequest, LoadError) {
   librbd::ImageCtx *ictx;
   ASSERT_EQ(0, open_image(m_image_name, &ictx));
 
-  MockImageCtx mock_image_ctx(*ictx);
+  MockObjectMapImageCtx mock_image_ctx(*ictx);
 
   ceph::BitVector<2> on_disk_object_map;
   init_object_map(mock_image_ctx, &on_disk_object_map);
@@ -210,7 +227,7 @@ TEST_F(TestMockObjectMapRefreshRequest, LoadCorrupt) {
   librbd::ImageCtx *ictx;
   ASSERT_EQ(0, open_image(m_image_name, &ictx));
 
-  MockImageCtx mock_image_ctx(*ictx);
+  MockObjectMapImageCtx mock_image_ctx(*ictx);
 
   ceph::BitVector<2> on_disk_object_map;
   init_object_map(mock_image_ctx, &on_disk_object_map);
@@ -240,7 +257,7 @@ TEST_F(TestMockObjectMapRefreshRequest, TooSmall) {
   librbd::ImageCtx *ictx;
   ASSERT_EQ(0, open_image(m_image_name, &ictx));
 
-  MockImageCtx mock_image_ctx(*ictx);
+  MockObjectMapImageCtx mock_image_ctx(*ictx);
 
   ceph::BitVector<2> on_disk_object_map;
   init_object_map(mock_image_ctx, &on_disk_object_map);
@@ -271,7 +288,7 @@ TEST_F(TestMockObjectMapRefreshRequest, TooLarge) {
   librbd::ImageCtx *ictx;
   ASSERT_EQ(0, open_image(m_image_name, &ictx));
 
-  MockImageCtx mock_image_ctx(*ictx);
+  MockObjectMapImageCtx mock_image_ctx(*ictx);
 
   ceph::BitVector<2> on_disk_object_map;
   init_object_map(mock_image_ctx, &on_disk_object_map);
@@ -298,7 +315,7 @@ TEST_F(TestMockObjectMapRefreshRequest, ResizeError) {
   librbd::ImageCtx *ictx;
   ASSERT_EQ(0, open_image(m_image_name, &ictx));
 
-  MockImageCtx mock_image_ctx(*ictx);
+  MockObjectMapImageCtx mock_image_ctx(*ictx);
 
   ceph::BitVector<2> on_disk_object_map;
   init_object_map(mock_image_ctx, &on_disk_object_map);
diff --git a/src/test/librbd/object_map/test_mock_ResizeRequest.cc b/src/test/librbd/object_map/test_mock_ResizeRequest.cc
index f21d645..42007d3 100644
--- a/src/test/librbd/object_map/test_mock_ResizeRequest.cc
+++ b/src/test/librbd/object_map/test_mock_ResizeRequest.cc
@@ -17,6 +17,7 @@ namespace object_map {
 using ::testing::_;
 using ::testing::DoDefault;
 using ::testing::Return;
+using ::testing::StrEq;
 
 class TestMockObjectMapResizeRequest : public TestMockFixture {
 public:
@@ -24,26 +25,26 @@ public:
     std::string oid(ObjectMap::object_map_name(ictx->id, snap_id));
     if (snap_id == CEPH_NOSNAP) {
       EXPECT_CALL(get_mock_io_ctx(ictx->md_ctx),
-                  exec(oid, _, "lock", "assert_locked", _, _, _))
+                  exec(oid, _, StrEq("lock"), StrEq("assert_locked"), _, _, _))
                     .WillOnce(DoDefault());
     }
 
     if (r < 0) {
       EXPECT_CALL(get_mock_io_ctx(ictx->md_ctx),
-                  exec(oid, _, "rbd", "object_map_resize", _, _, _))
+                  exec(oid, _, StrEq("rbd"), StrEq("object_map_resize"), _, _, _))
                     .WillOnce(Return(r));
     } else {
       EXPECT_CALL(get_mock_io_ctx(ictx->md_ctx),
-                  exec(oid, _, "rbd", "object_map_resize", _, _, _))
+                  exec(oid, _, StrEq("rbd"), StrEq("object_map_resize"), _, _, _))
                     .WillOnce(DoDefault());
     }
   }
 
   void expect_invalidate(librbd::ImageCtx *ictx) {
     EXPECT_CALL(get_mock_io_ctx(ictx->md_ctx),
-                exec(ictx->header_oid, _, "lock", "assert_locked", _, _, _)).Times(0);
+                exec(ictx->header_oid, _, StrEq("lock"), StrEq("assert_locked"), _, _, _)).Times(0);
     EXPECT_CALL(get_mock_io_ctx(ictx->md_ctx),
-                exec(ictx->header_oid, _, "rbd", "set_flags", _, _, _))
+                exec(ictx->header_oid, _, StrEq("rbd"), StrEq("set_flags"), _, _, _))
                   .WillOnce(DoDefault());
   }
 };
diff --git a/src/test/librbd/object_map/test_mock_SnapshotCreateRequest.cc b/src/test/librbd/object_map/test_mock_SnapshotCreateRequest.cc
index e76c192..3dd6298 100644
--- a/src/test/librbd/object_map/test_mock_SnapshotCreateRequest.cc
+++ b/src/test/librbd/object_map/test_mock_SnapshotCreateRequest.cc
@@ -17,6 +17,7 @@ namespace object_map {
 using ::testing::_;
 using ::testing::DoDefault;
 using ::testing::Return;
+using ::testing::StrEq;
 
 class TestMockObjectMapSnapshotCreateRequest : public TestMockFixture {
 public:
@@ -57,21 +58,21 @@ public:
     std::string oid(ObjectMap::object_map_name(ictx->id, CEPH_NOSNAP));
     if (r < 0) {
       EXPECT_CALL(get_mock_io_ctx(ictx->md_ctx),
-                  exec(oid, _, "lock", "assert_locked", _, _, _))
+                  exec(oid, _, StrEq("lock"), StrEq("assert_locked"), _, _, _))
                     .WillOnce(Return(r));
     } else {
       EXPECT_CALL(get_mock_io_ctx(ictx->md_ctx),
-                  exec(oid, _, "lock", "assert_locked", _, _, _))
+                  exec(oid, _, StrEq("lock"), StrEq("assert_locked"), _, _, _))
                     .WillOnce(DoDefault());
       EXPECT_CALL(get_mock_io_ctx(ictx->md_ctx),
-                  exec(oid, _, "rbd", "object_map_snap_add", _, _, _))
+                  exec(oid, _, StrEq("rbd"), StrEq("object_map_snap_add"), _, _, _))
                     .WillOnce(DoDefault());
     }
   }
 
   void expect_invalidate(librbd::ImageCtx *ictx) {
     EXPECT_CALL(get_mock_io_ctx(ictx->md_ctx),
-                exec(ictx->header_oid, _, "rbd", "set_flags", _, _, _))
+                exec(ictx->header_oid, _, StrEq("rbd"), StrEq("set_flags"), _, _, _))
                   .WillOnce(DoDefault());
   }
 };
diff --git a/src/test/librbd/object_map/test_mock_SnapshotRemoveRequest.cc b/src/test/librbd/object_map/test_mock_SnapshotRemoveRequest.cc
index a29699e..c00a3e6 100644
--- a/src/test/librbd/object_map/test_mock_SnapshotRemoveRequest.cc
+++ b/src/test/librbd/object_map/test_mock_SnapshotRemoveRequest.cc
@@ -18,6 +18,7 @@ namespace object_map {
 using ::testing::_;
 using ::testing::DoDefault;
 using ::testing::Return;
+using ::testing::StrEq;
 
 class TestMockObjectMapSnapshotRemoveRequest : public TestMockFixture {
 public:
@@ -25,11 +26,11 @@ public:
     std::string snap_oid(ObjectMap::object_map_name(ictx->id, snap_id));
     if (r < 0) {
       EXPECT_CALL(get_mock_io_ctx(ictx->md_ctx),
-                  exec(snap_oid, _, "rbd", "object_map_load", _, _, _))
+                  exec(snap_oid, _, StrEq("rbd"), StrEq("object_map_load"), _, _, _))
                     .WillOnce(Return(r));
     } else {
       EXPECT_CALL(get_mock_io_ctx(ictx->md_ctx),
-                  exec(snap_oid, _, "rbd", "object_map_load", _, _, _))
+                  exec(snap_oid, _, StrEq("rbd"), StrEq("object_map_load"), _, _, _))
                     .WillOnce(DoDefault());
     }
   }
@@ -38,14 +39,14 @@ public:
     std::string oid(ObjectMap::object_map_name(ictx->id, CEPH_NOSNAP));
     if (r < 0) {
       EXPECT_CALL(get_mock_io_ctx(ictx->md_ctx),
-                  exec(oid, _, "lock", "assert_locked", _, _, _))
+                  exec(oid, _, StrEq("lock"), StrEq("assert_locked"), _, _, _))
                     .WillOnce(Return(r));
     } else {
       EXPECT_CALL(get_mock_io_ctx(ictx->md_ctx),
-                  exec(oid, _, "lock", "assert_locked", _, _, _))
+                  exec(oid, _, StrEq("lock"), StrEq("assert_locked"), _, _, _))
                     .WillOnce(DoDefault());
       EXPECT_CALL(get_mock_io_ctx(ictx->md_ctx),
-                  exec(oid, _, "rbd", "object_map_snap_remove", _, _, _))
+                  exec(oid, _, StrEq("rbd"), StrEq("object_map_snap_remove"), _, _, _))
                     .WillOnce(DoDefault());
     }
   }
@@ -53,20 +54,20 @@ public:
   void expect_remove_map(librbd::ImageCtx *ictx, uint64_t snap_id, int r) {
     std::string snap_oid(ObjectMap::object_map_name(ictx->id, snap_id));
     if (r < 0) {
-      EXPECT_CALL(get_mock_io_ctx(ictx->md_ctx), remove(snap_oid))
+      EXPECT_CALL(get_mock_io_ctx(ictx->md_ctx), remove(snap_oid, _))
                     .WillOnce(Return(r));
     } else {
-      EXPECT_CALL(get_mock_io_ctx(ictx->md_ctx), remove(snap_oid))
+      EXPECT_CALL(get_mock_io_ctx(ictx->md_ctx), remove(snap_oid, _))
                     .WillOnce(DoDefault());
     }
   }
 
   void expect_invalidate(librbd::ImageCtx *ictx) {
     EXPECT_CALL(get_mock_io_ctx(ictx->md_ctx),
-                exec(ictx->header_oid, _, "lock", "assert_locked", _, _, _))
+                exec(ictx->header_oid, _, StrEq("lock"), StrEq("assert_locked"), _, _, _))
                   .Times(0);
     EXPECT_CALL(get_mock_io_ctx(ictx->md_ctx),
-                exec(ictx->header_oid, _, "rbd", "set_flags", _, _, _))
+                exec(ictx->header_oid, _, StrEq("rbd"), StrEq("set_flags"), _, _, _))
                   .WillOnce(DoDefault());
   }
 };
diff --git a/src/test/librbd/object_map/test_mock_SnapshotRollbackRequest.cc b/src/test/librbd/object_map/test_mock_SnapshotRollbackRequest.cc
index 2465ffd..51fc932 100644
--- a/src/test/librbd/object_map/test_mock_SnapshotRollbackRequest.cc
+++ b/src/test/librbd/object_map/test_mock_SnapshotRollbackRequest.cc
@@ -17,6 +17,7 @@ namespace object_map {
 using ::testing::_;
 using ::testing::DoDefault;
 using ::testing::Return;
+using ::testing::StrEq;
 
 class TestMockObjectMapSnapshotRollbackRequest : public TestMockFixture {
 public:
@@ -35,7 +36,7 @@ public:
   void expect_write_map(librbd::ImageCtx *ictx, int r) {
     EXPECT_CALL(get_mock_io_ctx(ictx->md_ctx),
                 exec(ObjectMap::object_map_name(ictx->id, CEPH_NOSNAP), _,
-		     "lock", "assert_locked", _, _, _))
+		     StrEq("lock"), StrEq("assert_locked"), _, _, _))
                   .WillOnce(DoDefault());
     if (r < 0) {
       EXPECT_CALL(get_mock_io_ctx(ictx->md_ctx),
@@ -52,10 +53,10 @@ public:
 
   void expect_invalidate(librbd::ImageCtx *ictx, uint32_t times) {
     EXPECT_CALL(get_mock_io_ctx(ictx->md_ctx),
-                exec(ictx->header_oid, _, "lock", "assert_locked", _, _, _))
+                exec(ictx->header_oid, _, StrEq("lock"), StrEq("assert_locked"), _, _, _))
                   .Times(0);
     EXPECT_CALL(get_mock_io_ctx(ictx->md_ctx),
-                exec(ictx->header_oid, _, "rbd", "set_flags", _, _, _))
+                exec(ictx->header_oid, _, StrEq("rbd"), StrEq("set_flags"), _, _, _))
                   .Times(times)
                   .WillRepeatedly(DoDefault());
   }
diff --git a/src/test/librbd/object_map/test_mock_UnlockRequest.cc b/src/test/librbd/object_map/test_mock_UnlockRequest.cc
index 4cd2db4..7f834ca 100644
--- a/src/test/librbd/object_map/test_mock_UnlockRequest.cc
+++ b/src/test/librbd/object_map/test_mock_UnlockRequest.cc
@@ -18,6 +18,7 @@ namespace object_map {
 using ::testing::_;
 using ::testing::InSequence;
 using ::testing::Return;
+using ::testing::StrEq;
 
 class TestMockObjectMapUnlockRequest : public TestMockFixture {
 public:
@@ -26,7 +27,7 @@ public:
   void expect_unlock(MockImageCtx &mock_image_ctx, int r) {
     std::string oid(ObjectMap::object_map_name(mock_image_ctx.id, CEPH_NOSNAP));
     EXPECT_CALL(get_mock_io_ctx(mock_image_ctx.md_ctx),
-                exec(oid, _, "lock", "unlock", _, _, _))
+                exec(oid, _, StrEq("lock"), StrEq("unlock"), _, _, _))
                   .WillOnce(Return(r));
   }
 };
diff --git a/src/test/librbd/object_map/test_mock_UpdateRequest.cc b/src/test/librbd/object_map/test_mock_UpdateRequest.cc
index 0d7dffa..45879f2 100644
--- a/src/test/librbd/object_map/test_mock_UpdateRequest.cc
+++ b/src/test/librbd/object_map/test_mock_UpdateRequest.cc
@@ -18,6 +18,7 @@ namespace object_map {
 using ::testing::_;
 using ::testing::DoDefault;
 using ::testing::Return;
+using ::testing::StrEq;
 
 class TestMockObjectMapUpdateRequest : public TestMockFixture {
 public:
@@ -25,27 +26,27 @@ public:
     std::string oid(ObjectMap::object_map_name(ictx->id, snap_id));
     if (snap_id == CEPH_NOSNAP) {
       EXPECT_CALL(get_mock_io_ctx(ictx->md_ctx),
-                  exec(oid, _, "lock", "assert_locked", _, _, _))
+                  exec(oid, _, StrEq("lock"), StrEq("assert_locked"), _, _, _))
                     .WillOnce(DoDefault());
     }
 
     if (r < 0) {
       EXPECT_CALL(get_mock_io_ctx(ictx->md_ctx),
-                  exec(oid, _, "rbd", "object_map_update", _, _, _))
+                  exec(oid, _, StrEq("rbd"), StrEq("object_map_update"), _, _, _))
                     .WillOnce(Return(r));
     } else {
       EXPECT_CALL(get_mock_io_ctx(ictx->md_ctx),
-                  exec(oid, _, "rbd", "object_map_update", _, _, _))
+                  exec(oid, _, StrEq("rbd"), StrEq("object_map_update"), _, _, _))
                     .WillOnce(DoDefault());
     }
   }
 
   void expect_invalidate(librbd::ImageCtx *ictx) {
     EXPECT_CALL(get_mock_io_ctx(ictx->md_ctx),
-                exec(ictx->header_oid, _, "lock", "assert_locked", _, _, _))
+                exec(ictx->header_oid, _, StrEq("lock"), StrEq("assert_locked"), _, _, _))
                   .Times(0);
     EXPECT_CALL(get_mock_io_ctx(ictx->md_ctx),
-                exec(ictx->header_oid, _, "rbd", "set_flags", _, _, _))
+                exec(ictx->header_oid, _, StrEq("rbd"), StrEq("set_flags"), _, _, _))
                   .WillOnce(DoDefault());
   }
 };
diff --git a/src/test/librbd/operation/test_mock_ResizeRequest.cc b/src/test/librbd/operation/test_mock_ResizeRequest.cc
index dfe07bf..34b0deb 100644
--- a/src/test/librbd/operation/test_mock_ResizeRequest.cc
+++ b/src/test/librbd/operation/test_mock_ResizeRequest.cc
@@ -53,6 +53,7 @@ using ::testing::_;
 using ::testing::DoAll;
 using ::testing::InSequence;
 using ::testing::Return;
+using ::testing::StrEq;
 using ::testing::WithArg;
 
 class TestMockOperationResizeRequest : public TestMockFixture {
@@ -104,7 +105,7 @@ public:
         EXPECT_CALL(*mock_image_ctx.exclusive_lock, assert_header_locked(_));
       }
       EXPECT_CALL(get_mock_io_ctx(mock_image_ctx.md_ctx),
-                  exec(mock_image_ctx.header_oid, _, "rbd", "set_size", _, _, _))
+                  exec(mock_image_ctx.header_oid, _, StrEq("rbd"), StrEq("set_size"), _, _, _))
                     .WillOnce(Return(r));
     }
   }
diff --git a/src/test/librbd/operation/test_mock_SnapshotCreateRequest.cc b/src/test/librbd/operation/test_mock_SnapshotCreateRequest.cc
index 96fe0cd..8cc5fda 100644
--- a/src/test/librbd/operation/test_mock_SnapshotCreateRequest.cc
+++ b/src/test/librbd/operation/test_mock_SnapshotCreateRequest.cc
@@ -23,6 +23,7 @@ using ::testing::DoAll;
 using ::testing::DoDefault;
 using ::testing::Return;
 using ::testing::SetArgPointee;
+using ::testing::StrEq;
 using ::testing::WithArg;
 
 class TestMockOperationSnapshotCreateRequest : public TestMockFixture {
@@ -69,9 +70,9 @@ public:
     }
 
     auto &expect = EXPECT_CALL(get_mock_io_ctx(mock_image_ctx.md_ctx),
-                               exec(mock_image_ctx.header_oid, _, "rbd",
-                               mock_image_ctx.old_format ? "snap_add" :
-                                                           "snapshot_add",
+                               exec(mock_image_ctx.header_oid, _, StrEq("rbd"),
+                               StrEq(mock_image_ctx.old_format ? "snap_add" :
+                                                                 "snapshot_add"),
                                _, _, _));
     if (r == -ESTALE) {
       expect.WillOnce(Return(r)).WillOnce(DoDefault());
diff --git a/src/test/librbd/operation/test_mock_SnapshotProtectRequest.cc b/src/test/librbd/operation/test_mock_SnapshotProtectRequest.cc
index ab7a8e4..22c0293 100644
--- a/src/test/librbd/operation/test_mock_SnapshotProtectRequest.cc
+++ b/src/test/librbd/operation/test_mock_SnapshotProtectRequest.cc
@@ -23,6 +23,7 @@ using ::testing::DoAll;
 using ::testing::DoDefault;
 using ::testing::Return;
 using ::testing::SetArgPointee;
+using ::testing::StrEq;
 using ::testing::WithArg;
 
 class TestMockOperationSnapshotProtectRequest : public TestMockFixture {
@@ -46,8 +47,8 @@ public:
 
   void expect_set_protection_status(MockImageCtx &mock_image_ctx, int r) {
     auto &expect = EXPECT_CALL(get_mock_io_ctx(mock_image_ctx.md_ctx),
-                               exec(mock_image_ctx.header_oid, _, "rbd",
-                                    "set_protection_status", _, _, _));
+                               exec(mock_image_ctx.header_oid, _, StrEq("rbd"),
+                                    StrEq("set_protection_status"), _, _, _));
     if (r < 0) {
       expect.WillOnce(Return(r));
     } else {
diff --git a/src/test/librbd/operation/test_mock_SnapshotRemoveRequest.cc b/src/test/librbd/operation/test_mock_SnapshotRemoveRequest.cc
index fc1fe2a..4dcf3c8 100644
--- a/src/test/librbd/operation/test_mock_SnapshotRemoveRequest.cc
+++ b/src/test/librbd/operation/test_mock_SnapshotRemoveRequest.cc
@@ -23,6 +23,7 @@ using ::testing::DoAll;
 using ::testing::DoDefault;
 using ::testing::Return;
 using ::testing::SetArgPointee;
+using ::testing::StrEq;
 using ::testing::WithArg;
 
 class TestMockOperationSnapshotRemoveRequest : public TestMockFixture {
@@ -71,7 +72,7 @@ public:
   void expect_remove_child(MockImageCtx &mock_image_ctx, int r) {
     bool deep_flatten = mock_image_ctx.image_ctx->test_features(RBD_FEATURE_DEEP_FLATTEN);
     auto &expect = EXPECT_CALL(get_mock_io_ctx(mock_image_ctx.md_ctx),
-                               exec(RBD_CHILDREN, _, "rbd", "remove_child",_,
+                               exec(RBD_CHILDREN, _, StrEq("rbd"), StrEq("remove_child"), _,
                                     _, _));
     if (deep_flatten) {
       expect.Times(0);
@@ -93,9 +94,9 @@ public:
 
   void expect_snap_remove(MockImageCtx &mock_image_ctx, int r) {
     auto &expect = EXPECT_CALL(get_mock_io_ctx(mock_image_ctx.md_ctx),
-                               exec(mock_image_ctx.header_oid, _, "rbd",
-                               mock_image_ctx.old_format ? "snap_remove" :
-                                                           "snapshot_remove",
+                               exec(mock_image_ctx.header_oid, _, StrEq("rbd"),
+                               StrEq(mock_image_ctx.old_format ? "snap_remove" :
+                                                                  "snapshot_remove"),
                                 _, _, _));
     if (r < 0) {
       expect.WillOnce(Return(r));
diff --git a/src/test/librbd/operation/test_mock_SnapshotRollbackRequest.cc b/src/test/librbd/operation/test_mock_SnapshotRollbackRequest.cc
index dab3418..6173336 100644
--- a/src/test/librbd/operation/test_mock_SnapshotRollbackRequest.cc
+++ b/src/test/librbd/operation/test_mock_SnapshotRollbackRequest.cc
@@ -14,14 +14,24 @@
 #include "gtest/gtest.h"
 
 namespace librbd {
+
+namespace {
+
+struct MockOperationImageCtx : public MockImageCtx {
+  MockOperationImageCtx(ImageCtx &image_ctx) : MockImageCtx(image_ctx) {
+  }
+};
+
+} // anonymous namespace
+
 namespace operation {
 
 template <>
-struct ResizeRequest<MockImageCtx> {
+struct ResizeRequest<MockOperationImageCtx> {
   static ResizeRequest *s_instance;
   Context *on_finish = nullptr;
 
-  static ResizeRequest* create(MockImageCtx &image_ctx, Context *on_finish,
+  static ResizeRequest* create(MockOperationImageCtx &image_ctx, Context *on_finish,
                                uint64_t new_size, ProgressContext &prog_ctx,
                                uint64_t journal_op_tid, bool disable_journal) {
     assert(s_instance != nullptr);
@@ -38,14 +48,31 @@ struct ResizeRequest<MockImageCtx> {
   MOCK_METHOD0(send, void());
 };
 
-ResizeRequest<MockImageCtx> *ResizeRequest<MockImageCtx>::s_instance = nullptr;
+ResizeRequest<MockOperationImageCtx> *ResizeRequest<MockOperationImageCtx>::s_instance = nullptr;
 
 } // namespace operation
+
+template <>
+struct AsyncRequest<MockOperationImageCtx> : public AsyncRequest<MockImageCtx> {
+  MockOperationImageCtx &m_image_ctx;
+
+  AsyncRequest(MockOperationImageCtx &image_ctx, Context *on_finish)
+    : AsyncRequest<MockImageCtx>(image_ctx, on_finish), m_image_ctx(image_ctx) {
+  }
+};
+
 } // namespace librbd
 
 // template definitions
+#include "librbd/AsyncRequest.cc"
+#include "librbd/AsyncObjectThrottle.cc"
+#include "librbd/operation/Request.cc"
 #include "librbd/operation/SnapshotRollbackRequest.cc"
 
+template class librbd::AsyncRequest<librbd::MockImageCtx>;
+template class librbd::AsyncObjectThrottle<librbd::MockImageCtx>;
+template class librbd::operation::Request<librbd::MockImageCtx>;
+
 namespace librbd {
 namespace operation {
 
@@ -56,26 +83,26 @@ using ::testing::WithArg;
 
 class TestMockOperationSnapshotRollbackRequest : public TestMockFixture {
 public:
-  typedef SnapshotRollbackRequest<MockImageCtx> MockSnapshotRollbackRequest;
-  typedef ResizeRequest<MockImageCtx> MockResizeRequest;
+  typedef SnapshotRollbackRequest<MockOperationImageCtx> MockSnapshotRollbackRequest;
+  typedef ResizeRequest<MockOperationImageCtx> MockResizeRequest;
 
-  void expect_block_writes(MockImageCtx &mock_image_ctx, int r) {
+  void expect_block_writes(MockOperationImageCtx &mock_image_ctx, int r) {
     EXPECT_CALL(*mock_image_ctx.aio_work_queue, block_writes(_))
                   .WillOnce(CompleteContext(r, mock_image_ctx.image_ctx->op_work_queue));
   }
 
-  void expect_unblock_writes(MockImageCtx &mock_image_ctx) {
+  void expect_unblock_writes(MockOperationImageCtx &mock_image_ctx) {
     EXPECT_CALL(*mock_image_ctx.aio_work_queue, unblock_writes())
                   .Times(1);
   }
 
-  void expect_get_image_size(MockImageCtx &mock_image_ctx,
+  void expect_get_image_size(MockOperationImageCtx &mock_image_ctx,
                              uint64_t size) {
     EXPECT_CALL(mock_image_ctx, get_image_size(CEPH_NOSNAP))
                   .WillOnce(Return(size));
   }
 
-  void expect_resize(MockImageCtx &mock_image_ctx,
+  void expect_resize(MockOperationImageCtx &mock_image_ctx,
                      MockResizeRequest &mock_resize_request, int r) {
     expect_get_image_size(mock_image_ctx, 123);
     EXPECT_CALL(mock_resize_request, send())
@@ -83,7 +110,7 @@ public:
                                           &mock_image_ctx));
   }
 
-  void expect_rollback_object_map(MockImageCtx &mock_image_ctx,
+  void expect_rollback_object_map(MockOperationImageCtx &mock_image_ctx,
                                   MockObjectMap &mock_object_map) {
     if (mock_image_ctx.object_map != nullptr) {
       EXPECT_CALL(mock_object_map, rollback(_, _))
@@ -91,43 +118,43 @@ public:
     }
   }
 
-  void expect_get_object_name(MockImageCtx &mock_image_ctx,
+  void expect_get_object_name(MockOperationImageCtx &mock_image_ctx,
                               uint64_t object_num) {
     EXPECT_CALL(mock_image_ctx, get_object_name(object_num))
                   .WillOnce(Return("object-name-" + stringify(object_num)));
   }
 
-  void expect_get_current_size(MockImageCtx &mock_image_ctx, uint64_t size) {
+  void expect_get_current_size(MockOperationImageCtx &mock_image_ctx, uint64_t size) {
     EXPECT_CALL(mock_image_ctx, get_current_size())
                   .WillOnce(Return(size));
   }
 
-  void expect_rollback_snap_id(MockImageCtx &mock_image_ctx,
+  void expect_rollback_snap_id(MockOperationImageCtx &mock_image_ctx,
                                const std::string &oid, int r) {
     EXPECT_CALL(get_mock_io_ctx(mock_image_ctx.data_ctx),
                 selfmanaged_snap_rollback(oid, _))
                   .WillOnce(Return(r));
   }
 
-  void expect_rollback(MockImageCtx &mock_image_ctx, int r) {
+  void expect_rollback(MockOperationImageCtx &mock_image_ctx, int r) {
     expect_get_current_size(mock_image_ctx, 1);
     expect_get_object_name(mock_image_ctx, 0);
     expect_rollback_snap_id(mock_image_ctx, "object-name-0", r);
   }
 
-  void expect_create_object_map(MockImageCtx &mock_image_ctx,
+  void expect_create_object_map(MockOperationImageCtx &mock_image_ctx,
                                 MockObjectMap *mock_object_map) {
     EXPECT_CALL(mock_image_ctx, create_object_map(_))
                   .WillOnce(Return(mock_object_map));
   }
 
-  void expect_open_object_map(MockImageCtx &mock_image_ctx,
+  void expect_open_object_map(MockOperationImageCtx &mock_image_ctx,
                               MockObjectMap &mock_object_map) {
     EXPECT_CALL(mock_object_map, open(_))
                   .WillOnce(CompleteContext(0, mock_image_ctx.image_ctx->op_work_queue));
   }
 
-  void expect_refresh_object_map(MockImageCtx &mock_image_ctx,
+  void expect_refresh_object_map(MockOperationImageCtx &mock_image_ctx,
                                  MockObjectMap &mock_object_map) {
     if (mock_image_ctx.object_map != nullptr) {
       expect_create_object_map(mock_image_ctx, &mock_object_map);
@@ -135,14 +162,14 @@ public:
     }
   }
 
-  void expect_invalidate_cache(MockImageCtx &mock_image_ctx, int r) {
+  void expect_invalidate_cache(MockOperationImageCtx &mock_image_ctx, int r) {
     if (mock_image_ctx.object_cacher != nullptr) {
       EXPECT_CALL(mock_image_ctx, invalidate_cache(_))
                     .WillOnce(CompleteContext(r, NULL));
     }
   }
 
-  int when_snap_rollback(MockImageCtx &mock_image_ctx,
+  int when_snap_rollback(MockOperationImageCtx &mock_image_ctx,
                          const std::string &snap_name,
                          uint64_t snap_id, uint64_t snap_size) {
     C_SaferCond cond_ctx;
@@ -161,7 +188,7 @@ TEST_F(TestMockOperationSnapshotRollbackRequest, Success) {
   librbd::ImageCtx *ictx;
   ASSERT_EQ(0, open_image(m_image_name, &ictx));
 
-  MockImageCtx mock_image_ctx(*ictx);
+  MockOperationImageCtx mock_image_ctx(*ictx);
   MockExclusiveLock mock_exclusive_lock;
   MockJournal mock_journal;
   MockObjectMap *mock_object_map = new MockObjectMap();
@@ -187,7 +214,7 @@ TEST_F(TestMockOperationSnapshotRollbackRequest, BlockWritesError) {
   librbd::ImageCtx *ictx;
   ASSERT_EQ(0, open_image(m_image_name, &ictx));
 
-  MockImageCtx mock_image_ctx(*ictx);
+  MockOperationImageCtx mock_image_ctx(*ictx);
   MockExclusiveLock mock_exclusive_lock;
   MockJournal mock_journal;
   MockObjectMap mock_object_map;
@@ -207,7 +234,7 @@ TEST_F(TestMockOperationSnapshotRollbackRequest, SkipResize) {
   librbd::ImageCtx *ictx;
   ASSERT_EQ(0, open_image(m_image_name, &ictx));
 
-  MockImageCtx mock_image_ctx(*ictx);
+  MockOperationImageCtx mock_image_ctx(*ictx);
   MockExclusiveLock mock_exclusive_lock;
   MockJournal mock_journal;
   MockObjectMap *mock_object_map = new MockObjectMap();
@@ -232,7 +259,7 @@ TEST_F(TestMockOperationSnapshotRollbackRequest, ResizeError) {
   librbd::ImageCtx *ictx;
   ASSERT_EQ(0, open_image(m_image_name, &ictx));
 
-  MockImageCtx mock_image_ctx(*ictx);
+  MockOperationImageCtx mock_image_ctx(*ictx);
   MockExclusiveLock mock_exclusive_lock;
   MockJournal mock_journal;
   MockObjectMap mock_object_map;
@@ -254,7 +281,7 @@ TEST_F(TestMockOperationSnapshotRollbackRequest, RollbackObjectsError) {
   librbd::ImageCtx *ictx;
   ASSERT_EQ(0, open_image(m_image_name, &ictx));
 
-  MockImageCtx mock_image_ctx(*ictx);
+  MockOperationImageCtx mock_image_ctx(*ictx);
   MockExclusiveLock mock_exclusive_lock;
   MockJournal mock_journal;
   MockObjectMap mock_object_map;
@@ -278,7 +305,7 @@ TEST_F(TestMockOperationSnapshotRollbackRequest, InvalidateCacheError) {
   librbd::ImageCtx *ictx;
   ASSERT_EQ(0, open_image(m_image_name, &ictx));
 
-  MockImageCtx mock_image_ctx(*ictx);
+  MockOperationImageCtx mock_image_ctx(*ictx);
   MockExclusiveLock mock_exclusive_lock;
   MockJournal mock_journal;
   MockObjectMap *mock_object_map = new MockObjectMap();
diff --git a/src/test/librbd/operation/test_mock_SnapshotUnprotectRequest.cc b/src/test/librbd/operation/test_mock_SnapshotUnprotectRequest.cc
index 4d437d0..b312027 100644
--- a/src/test/librbd/operation/test_mock_SnapshotUnprotectRequest.cc
+++ b/src/test/librbd/operation/test_mock_SnapshotUnprotectRequest.cc
@@ -26,6 +26,7 @@ using ::testing::DoDefault;
 using ::testing::Return;
 using ::testing::SetArgReferee;
 using ::testing::SetArgPointee;
+using ::testing::StrEq;
 using ::testing::WithArg;
 
 class TestMockOperationSnapshotUnprotectRequest : public TestMockFixture {
@@ -54,8 +55,8 @@ public:
     ::encode(status, bl);
 
     auto &expect = EXPECT_CALL(get_mock_io_ctx(mock_image_ctx.md_ctx),
-                               exec(mock_image_ctx.header_oid, _, "rbd",
-                                    "set_protection_status", ContentsEqual(bl),
+                               exec(mock_image_ctx.header_oid, _, StrEq("rbd"),
+                                    StrEq("set_protection_status"), ContentsEqual(bl),
                                     _, _));
     if (r < 0) {
       expect.WillOnce(Return(r));
@@ -89,7 +90,7 @@ public:
     ::encode(children, bl);
 
     auto &expect = EXPECT_CALL(get_mock_io_ctx(mock_image_ctx.md_ctx),
-                               exec(RBD_CHILDREN, _, "rbd", "get_children", _,
+                               exec(RBD_CHILDREN, _, StrEq("rbd"), StrEq("get_children"), _,
                                _, _));
     if (r < 0) {
       expect.WillRepeatedly(Return(r));
diff --git a/src/test/librbd/test_ImageWatcher.cc b/src/test/librbd/test_ImageWatcher.cc
index 7ae6643..a698e33 100644
--- a/src/test/librbd/test_ImageWatcher.cc
+++ b/src/test/librbd/test_ImageWatcher.cc
@@ -257,7 +257,9 @@ struct FlattenTask {
 
   void operator()() {
     RWLock::RLocker l(ictx->owner_lock);
-    result = ictx->image_watcher->notify_flatten(0, *progress_context);
+    C_SaferCond ctx;
+    ictx->image_watcher->notify_flatten(0, *progress_context, &ctx);
+    result = ctx.wait();
   }
 };
 
@@ -271,7 +273,9 @@ struct ResizeTask {
 
   void operator()() {
     RWLock::RLocker l(ictx->owner_lock);
-    result = ictx->image_watcher->notify_resize(0, 0, *progress_context);
+    C_SaferCond ctx;
+    ictx->image_watcher->notify_resize(0, 0, *progress_context, &ctx);
+    result = ctx.wait();
   }
 };
 
@@ -285,7 +289,9 @@ struct RebuildObjectMapTask {
 
   void operator()() {
     RWLock::RLocker l(ictx->owner_lock);
-    result = ictx->image_watcher->notify_rebuild_object_map(0, *progress_context);
+    C_SaferCond ctx;
+    ictx->image_watcher->notify_rebuild_object_map(0, *progress_context, &ctx);
+    result = ctx.wait();
   }
 };
 
@@ -300,6 +306,10 @@ TEST_F(TestImageWatcher, NotifyRequestLock) {
   m_notify_acks = {{NOTIFY_OP_REQUEST_LOCK, {}}};
   ictx->image_watcher->notify_request_lock();
 
+  C_SaferCond ctx;
+  ictx->image_watcher->flush(&ctx);
+  ctx.wait();
+
   ASSERT_TRUE(wait_for_notifies(*ictx));
 
   NotifyOps expected_notify_ops;
@@ -352,7 +362,7 @@ TEST_F(TestImageWatcher, NotifyHeaderUpdate) {
   ASSERT_EQ(0, register_image_watch(*ictx));
 
   m_notify_acks = {{NOTIFY_OP_HEADER_UPDATE, {}}};
-  librbd::ImageWatcher::notify_header_update(m_ioctx, ictx->header_oid);
+  ictx->notify_update();
 
   ASSERT_TRUE(wait_for_notifies(*ictx));
 
@@ -477,7 +487,9 @@ TEST_F(TestImageWatcher, NotifySnapCreate) {
   m_notify_acks = {{NOTIFY_OP_SNAP_CREATE, create_response_message(0)}};
 
   RWLock::RLocker l(ictx->owner_lock);
-  ASSERT_EQ(0, ictx->image_watcher->notify_snap_create("snap"));
+  C_SaferCond notify_ctx;
+  ictx->image_watcher->notify_snap_create("snap", &notify_ctx);
+  ASSERT_EQ(0, notify_ctx.wait());
 
   NotifyOps expected_notify_ops;
   expected_notify_ops += NOTIFY_OP_SNAP_CREATE;
@@ -497,7 +509,9 @@ TEST_F(TestImageWatcher, NotifySnapCreateError) {
   m_notify_acks = {{NOTIFY_OP_SNAP_CREATE, create_response_message(-EEXIST)}};
 
   RWLock::RLocker l(ictx->owner_lock);
-  ASSERT_EQ(-EEXIST, ictx->image_watcher->notify_snap_create("snap"));
+  C_SaferCond notify_ctx;
+  ictx->image_watcher->notify_snap_create("snap", &notify_ctx);
+  ASSERT_EQ(-EEXIST, notify_ctx.wait());
 
   NotifyOps expected_notify_ops;
   expected_notify_ops += NOTIFY_OP_SNAP_CREATE;
@@ -517,7 +531,9 @@ TEST_F(TestImageWatcher, NotifySnapRename) {
   m_notify_acks = {{NOTIFY_OP_SNAP_RENAME, create_response_message(0)}};
 
   RWLock::RLocker l(ictx->owner_lock);
-  ASSERT_EQ(0, ictx->image_watcher->notify_snap_rename(1, "snap-rename"));
+  C_SaferCond notify_ctx;
+  ictx->image_watcher->notify_snap_rename(1, "snap-rename", &notify_ctx);
+  ASSERT_EQ(0, notify_ctx.wait());
 
   NotifyOps expected_notify_ops;
   expected_notify_ops += NOTIFY_OP_SNAP_RENAME;
@@ -537,7 +553,9 @@ TEST_F(TestImageWatcher, NotifySnapRenameError) {
   m_notify_acks = {{NOTIFY_OP_SNAP_RENAME, create_response_message(-EEXIST)}};
 
   RWLock::RLocker l(ictx->owner_lock);
-  ASSERT_EQ(-EEXIST, ictx->image_watcher->notify_snap_rename(1, "snap-rename"));
+  C_SaferCond notify_ctx;
+  ictx->image_watcher->notify_snap_rename(1, "snap-rename", &notify_ctx);
+  ASSERT_EQ(-EEXIST, notify_ctx.wait());
 
   NotifyOps expected_notify_ops;
   expected_notify_ops += NOTIFY_OP_SNAP_RENAME;
@@ -557,7 +575,9 @@ TEST_F(TestImageWatcher, NotifySnapRemove) {
   m_notify_acks = {{NOTIFY_OP_SNAP_REMOVE, create_response_message(0)}};
 
   RWLock::RLocker l(ictx->owner_lock);
-  ASSERT_EQ(0, ictx->image_watcher->notify_snap_remove("snap"));
+  C_SaferCond notify_ctx;
+  ictx->image_watcher->notify_snap_remove("snap", &notify_ctx);
+  ASSERT_EQ(0, notify_ctx.wait());
 
   NotifyOps expected_notify_ops;
   expected_notify_ops += NOTIFY_OP_SNAP_REMOVE;
@@ -577,7 +597,9 @@ TEST_F(TestImageWatcher, NotifySnapProtect) {
   m_notify_acks = {{NOTIFY_OP_SNAP_PROTECT, create_response_message(0)}};
 
   RWLock::RLocker l(ictx->owner_lock);
-  ASSERT_EQ(0, ictx->image_watcher->notify_snap_protect("snap"));
+  C_SaferCond notify_ctx;
+  ictx->image_watcher->notify_snap_protect("snap", &notify_ctx);
+  ASSERT_EQ(0, notify_ctx.wait());
 
   NotifyOps expected_notify_ops;
   expected_notify_ops += NOTIFY_OP_SNAP_PROTECT;
@@ -597,7 +619,9 @@ TEST_F(TestImageWatcher, NotifySnapUnprotect) {
   m_notify_acks = {{NOTIFY_OP_SNAP_UNPROTECT, create_response_message(0)}};
 
   RWLock::RLocker l(ictx->owner_lock);
-  ASSERT_EQ(0, ictx->image_watcher->notify_snap_unprotect("snap"));
+  C_SaferCond notify_ctx;
+  ictx->image_watcher->notify_snap_unprotect("snap", &notify_ctx);
+  ASSERT_EQ(0, notify_ctx.wait());
 
   NotifyOps expected_notify_ops;
   expected_notify_ops += NOTIFY_OP_SNAP_UNPROTECT;
@@ -617,7 +641,9 @@ TEST_F(TestImageWatcher, NotifyRename) {
   m_notify_acks = {{NOTIFY_OP_RENAME, create_response_message(0)}};
 
   RWLock::RLocker l(ictx->owner_lock);
-  ASSERT_EQ(0, ictx->image_watcher->notify_rename("new_name"));
+  C_SaferCond notify_ctx;
+  ictx->image_watcher->notify_rename("new_name", &notify_ctx);
+  ASSERT_EQ(0, notify_ctx.wait());
 
   NotifyOps expected_notify_ops;
   expected_notify_ops += NOTIFY_OP_RENAME;
@@ -716,6 +742,6 @@ TEST_F(TestImageWatcher, NotifyAsyncRequestTimedOut) {
   ASSERT_TRUE(wait_for_notifies(*ictx));
 
   ASSERT_TRUE(thread.timed_join(boost::posix_time::seconds(10)));
-  ASSERT_EQ(-ERESTART, flatten_task.result);
+  ASSERT_EQ(-ETIMEDOUT, flatten_task.result);
 }
 
diff --git a/src/test/librbd/test_fixture.cc b/src/test/librbd/test_fixture.cc
index 8ed4299..a521a79 100644
--- a/src/test/librbd/test_fixture.cc
+++ b/src/test/librbd/test_fixture.cc
@@ -24,7 +24,7 @@ TestFixture::TestFixture() : m_image_size(0) {
 }
 
 void TestFixture::SetUpTestCase() {
-  _pool_name = get_temp_pool_name();
+  _pool_name = get_temp_pool_name("test-librbd-");
   ASSERT_EQ("", create_one_pool_pp(_pool_name, _rados));
 }
 
diff --git a/src/test/librbd/test_internal.cc b/src/test/librbd/test_internal.cc
index 7c2f759..b5c6f6b 100644
--- a/src/test/librbd/test_internal.cc
+++ b/src/test/librbd/test_internal.cc
@@ -6,6 +6,7 @@
 #include "librbd/AioImageRequest.h"
 #include "librbd/AioImageRequestWQ.h"
 #include "librbd/ExclusiveLock.h"
+#include "librbd/ImageState.h"
 #include "librbd/ImageWatcher.h"
 #include "librbd/internal.h"
 #include "librbd/ObjectMap.h"
@@ -71,6 +72,20 @@ public:
   }
 };
 
+TEST_F(TestInternal, OpenByID) {
+   REQUIRE_FORMAT_V2();
+
+   librbd::ImageCtx *ictx;
+   ASSERT_EQ(0, open_image(m_image_name, &ictx));
+   std::string id = ictx->id;
+   close_image(ictx);
+
+   ictx = new librbd::ImageCtx("", id, nullptr, m_ioctx, true);
+   ASSERT_EQ(0, ictx->state->open());
+   ASSERT_EQ(ictx->name, m_image_name);
+   close_image(ictx);
+}
+
 TEST_F(TestInternal, IsExclusiveLockOwner) {
   REQUIRE_FEATURE(RBD_FEATURE_EXCLUSIVE_LOCK);
 
@@ -321,7 +336,7 @@ TEST_F(TestInternal, CancelAsyncResize) {
     size -= MIN(size, 1<<18);
     {
       RWLock::RLocker l(ictx->owner_lock);
-      ictx->operations->resize(size, prog_ctx, &ctx, 0);
+      ictx->operations->execute_resize(size, prog_ctx, &ctx, 0);
     }
 
     // try to interrupt the in-progress resize
@@ -369,7 +384,7 @@ TEST_F(TestInternal, MultipleResize) {
 
     RWLock::RLocker l(ictx->owner_lock);
     contexts.push_back(new C_SaferCond());
-    ictx->operations->resize(new_size, prog_ctx, contexts.back(), 0);
+    ictx->operations->execute_resize(new_size, prog_ctx, contexts.back(), 0);
   }
 
   for (uint32_t i = 0; i < contexts.size(); ++i) {
diff --git a/src/test/librbd/test_librbd.cc b/src/test/librbd/test_librbd.cc
index 38e8609..cd9decf 100644
--- a/src/test/librbd/test_librbd.cc
+++ b/src/test/librbd/test_librbd.cc
@@ -209,13 +209,13 @@ public:
     librados::Rados rados;
     std::string pool_name;
     if (unique) {
-      pool_name = get_temp_pool_name();
+      pool_name = get_temp_pool_name("test-librbd-");
       EXPECT_EQ("", create_one_pool_pp(pool_name, rados));
       _unique_pool_names.push_back(pool_name);
     } else if (m_pool_number < _pool_names.size()) {
       pool_name = _pool_names[m_pool_number];
     } else {
-      pool_name = get_temp_pool_name();
+      pool_name = get_temp_pool_name("test-librbd-");
       EXPECT_EQ("", create_one_pool_pp(pool_name, rados));
       _pool_names.push_back(pool_name);
     }
@@ -2939,6 +2939,52 @@ TEST_F(TestLibRBD, TestPendingAio)
   rados_ioctx_destroy(ioctx);
 }
 
+TEST_F(TestLibRBD, Flatten)
+{
+  REQUIRE_FEATURE(RBD_FEATURE_LAYERING);
+
+  librados::IoCtx ioctx;
+  ASSERT_EQ(0, _rados.ioctx_create(m_pool_name.c_str(), ioctx));
+
+  librbd::RBD rbd;
+  std::string parent_name = get_temp_image_name();
+  uint64_t size = 2 << 20;
+  int order = 0;
+  ASSERT_EQ(0, create_image_pp(rbd, ioctx, parent_name.c_str(), size, &order));
+
+  librbd::Image parent_image;
+  ASSERT_EQ(0, rbd.open(ioctx, parent_image, parent_name.c_str(), NULL));
+
+  bufferlist bl;
+  bl.append(std::string(4096, '1'));
+  ASSERT_EQ(bl.length(), parent_image.write(0, bl.length(), bl));
+
+  ASSERT_EQ(0, parent_image.snap_create("snap1"));
+  ASSERT_EQ(0, parent_image.snap_protect("snap1"));
+
+  uint64_t features;
+  ASSERT_EQ(0, parent_image.features(&features));
+
+  std::string clone_name = get_temp_image_name();
+  EXPECT_EQ(0, rbd.clone(ioctx, parent_name.c_str(), "snap1", ioctx,
+       clone_name.c_str(), features, &order));
+
+  librbd::Image clone_image;
+  ASSERT_EQ(0, rbd.open(ioctx, clone_image, clone_name.c_str(), NULL));
+  ASSERT_EQ(0, clone_image.flatten());
+
+  librbd::RBD::AioCompletion *read_comp =
+    new librbd::RBD::AioCompletion(NULL, NULL);
+  bufferlist read_bl;
+  clone_image.aio_read(0, bl.length(), read_bl, read_comp);
+  ASSERT_EQ(0, read_comp->wait_for_complete());
+  ASSERT_EQ(bl.length(), read_comp->get_return_value());
+  read_comp->release();
+  ASSERT_TRUE(bl.contents_equal(read_bl));
+
+  ASSERT_PASSED(validate_object_map, clone_image);
+}
+
 TEST_F(TestLibRBD, RebuildObjectMapViaLockOwner)
 {
   REQUIRE_FEATURE(RBD_FEATURE_EXCLUSIVE_LOCK | RBD_FEATURE_OBJECT_MAP);
@@ -3474,6 +3520,9 @@ TEST_F(TestLibRBD, UpdateFeatures)
     return;
   }
 
+  uint64_t features;
+  ASSERT_EQ(0, image.features(&features));
+
   // must provide a single feature
   ASSERT_EQ(-EINVAL, image.update_features(0, true));
 
@@ -3519,6 +3568,11 @@ TEST_F(TestLibRBD, UpdateFeatures)
   ASSERT_EQ(0U, flags);
 
   ASSERT_EQ(0, image.update_features(RBD_FEATURE_EXCLUSIVE_LOCK, false));
+
+  if ((features & RBD_FEATURE_DEEP_FLATTEN) != 0) {
+    ASSERT_EQ(0, image.update_features(RBD_FEATURE_DEEP_FLATTEN, false));
+  }
+  ASSERT_EQ(-EINVAL, image.update_features(RBD_FEATURE_DEEP_FLATTEN, true));
 }
 
 TEST_F(TestLibRBD, RebuildObjectMap)
@@ -3715,6 +3769,7 @@ TEST_F(TestLibRBD, ExclusiveLockTransition)
     comps.pop_front();
     ASSERT_EQ(0, comp->wait_for_complete());
     ASSERT_EQ(1, comp->is_complete());
+    comp->release();
   }
 
   librbd::Image image3;
@@ -3731,6 +3786,60 @@ TEST_F(TestLibRBD, ExclusiveLockTransition)
   ASSERT_PASSED(validate_object_map, image3);
 }
 
+TEST_F(TestLibRBD, ExclusiveLockReadTransition)
+{
+  REQUIRE_FEATURE(RBD_FEATURE_JOURNALING);
+
+  librados::IoCtx ioctx;
+  ASSERT_EQ(0, _rados.ioctx_create(m_pool_name.c_str(), ioctx));
+
+  librbd::RBD rbd;
+  std::string name = get_temp_image_name();
+
+  uint64_t size = 1 << 18;
+  int order = 12;
+  ASSERT_EQ(0, create_image_pp(rbd, ioctx, name.c_str(), size, &order));
+
+  librbd::Image image1;
+  ASSERT_EQ(0, rbd.open(ioctx, image1, name.c_str(), NULL));
+
+  bool lock_owner;
+  ASSERT_EQ(0, image1.is_exclusive_lock_owner(&lock_owner));
+  ASSERT_FALSE(lock_owner);
+
+  // journaling should force read ops to acquire the lock
+  bufferlist read_bl;
+  ASSERT_EQ(0, image1.read(0, 0, read_bl));
+
+  ASSERT_EQ(0, image1.is_exclusive_lock_owner(&lock_owner));
+  ASSERT_TRUE(lock_owner);
+
+  librbd::Image image2;
+  ASSERT_EQ(0, rbd.open(ioctx, image2, name.c_str(), NULL));
+
+  std::list<librbd::RBD::AioCompletion *> comps;
+  std::list<bufferlist> read_bls;
+  for (size_t object_no = 0; object_no < (size >> 12); ++object_no) {
+    librbd::RBD::AioCompletion *comp = new librbd::RBD::AioCompletion(NULL,
+                                                                      NULL);
+    comps.push_back(comp);
+    read_bls.emplace_back();
+    if (object_no % 2 == 0) {
+      ASSERT_EQ(0, image1.aio_read(object_no << order, 1 << order, read_bls.back(), comp));
+    } else {
+      ASSERT_EQ(0, image2.aio_read(object_no << order, 1 << order, read_bls.back(), comp));
+    }
+  }
+
+  while (!comps.empty()) {
+    librbd::RBD::AioCompletion *comp = comps.front();
+    comps.pop_front();
+    ASSERT_EQ(0, comp->wait_for_complete());
+    ASSERT_EQ(1, comp->is_complete());
+    comp->release();
+  }
+}
+
 TEST_F(TestLibRBD, CacheMayCopyOnWrite) {
   REQUIRE_FEATURE(RBD_FEATURE_LAYERING);
 
@@ -3981,11 +4090,18 @@ TEST_F(TestLibRBD, ImagePollIO)
 namespace librbd {
 
 static bool operator==(const mirror_peer_t &lhs, const mirror_peer_t &rhs) {
-  return (lhs.cluster_uuid == rhs.cluster_uuid &&
+  return (lhs.uuid == rhs.uuid &&
           lhs.cluster_name == rhs.cluster_name &&
           lhs.client_name == rhs.client_name);
 }
 
+static std::ostream& operator<<(std::ostream &os, const mirror_peer_t &peer) {
+  os << "uuid=" << peer.uuid << ", "
+     << "cluster=" << peer.cluster_name << ", "
+     << "client=" << peer.client_name;
+  return os;
+}
+
 } // namespace librbd
 
 TEST_F(TestLibRBD, Mirror) {
@@ -3999,43 +4115,101 @@ TEST_F(TestLibRBD, Mirror) {
   ASSERT_EQ(0, rbd.mirror_peer_list(ioctx, &peers));
   ASSERT_EQ(expected_peers, peers);
 
-  ASSERT_EQ(-EINVAL, rbd.mirror_peer_add(ioctx, "uuid1", "cluster1", "client"));
+  std::string uuid1;
+  ASSERT_EQ(-EINVAL, rbd.mirror_peer_add(ioctx, &uuid1, "cluster1", "client"));
 
-  bool enabled;
-  ASSERT_EQ(0, rbd.mirror_is_enabled(ioctx, &enabled));
-  ASSERT_FALSE(enabled);
-  ASSERT_EQ(0, rbd.mirror_set_enabled(ioctx, true));
-  ASSERT_EQ(0, rbd.mirror_is_enabled(ioctx, &enabled));
-  ASSERT_TRUE(enabled);
+  rbd_mirror_mode_t mirror_mode;
+  ASSERT_EQ(0, rbd.mirror_mode_get(ioctx, &mirror_mode));
+  ASSERT_EQ(RBD_MIRROR_MODE_DISABLED, mirror_mode);
 
-  ASSERT_EQ(0, rbd.mirror_peer_add(ioctx, "uuid1", "cluster1", "client"));
-  ASSERT_EQ(0, rbd.mirror_peer_add(ioctx, "uuid2", "cluster2", "admin"));
-  ASSERT_EQ(-EEXIST, rbd.mirror_peer_add(ioctx, "uuid2", "cluster3", "foo"));
-  ASSERT_EQ(-EEXIST, rbd.mirror_peer_add(ioctx, "uuid3", "cluster1", "foo"));
-  ASSERT_EQ(0, rbd.mirror_peer_add(ioctx, "uuid3", "cluster3", "admin"));
+  ASSERT_EQ(0, rbd.mirror_mode_set(ioctx, RBD_MIRROR_MODE_IMAGE));
+  ASSERT_EQ(0, rbd.mirror_mode_get(ioctx, &mirror_mode));
+  ASSERT_EQ(RBD_MIRROR_MODE_IMAGE, mirror_mode);
+
+  ASSERT_EQ(0, rbd.mirror_mode_set(ioctx, RBD_MIRROR_MODE_POOL));
+  ASSERT_EQ(0, rbd.mirror_mode_get(ioctx, &mirror_mode));
+  ASSERT_EQ(RBD_MIRROR_MODE_POOL, mirror_mode);
+
+  std::string uuid2;
+  std::string uuid3;
+  ASSERT_EQ(0, rbd.mirror_peer_add(ioctx, &uuid1, "cluster1", "client"));
+  ASSERT_EQ(0, rbd.mirror_peer_add(ioctx, &uuid2, "cluster2", "admin"));
+  ASSERT_EQ(-EEXIST, rbd.mirror_peer_add(ioctx, &uuid3, "cluster1", "foo"));
+  ASSERT_EQ(0, rbd.mirror_peer_add(ioctx, &uuid3, "cluster3", "admin"));
 
   ASSERT_EQ(0, rbd.mirror_peer_list(ioctx, &peers));
+  auto sort_peers = [](const librbd::mirror_peer_t &lhs,
+                         const librbd::mirror_peer_t &rhs) {
+      return lhs.uuid < rhs.uuid;
+    };
   expected_peers = {
-    {"uuid1", "cluster1", "client"},
-    {"uuid2", "cluster2", "admin"},
-    {"uuid3", "cluster3", "admin"}};
+    {uuid1, "cluster1", "client"},
+    {uuid2, "cluster2", "admin"},
+    {uuid3, "cluster3", "admin"}};
+  std::sort(expected_peers.begin(), expected_peers.end(), sort_peers);
   ASSERT_EQ(expected_peers, peers);
 
   ASSERT_EQ(0, rbd.mirror_peer_remove(ioctx, "uuid4"));
-  ASSERT_EQ(0, rbd.mirror_peer_remove(ioctx, "uuid2"));
+  ASSERT_EQ(0, rbd.mirror_peer_remove(ioctx, uuid2));
 
   ASSERT_EQ(-ENOENT, rbd.mirror_peer_set_client(ioctx, "uuid4", "new client"));
-  ASSERT_EQ(0, rbd.mirror_peer_set_client(ioctx, "uuid1", "new client"));
+  ASSERT_EQ(0, rbd.mirror_peer_set_client(ioctx, uuid1, "new client"));
 
   ASSERT_EQ(-ENOENT, rbd.mirror_peer_set_cluster(ioctx, "uuid4",
                                                  "new cluster"));
-  ASSERT_EQ(0, rbd.mirror_peer_set_cluster(ioctx, "uuid3", "new cluster"));
+  ASSERT_EQ(0, rbd.mirror_peer_set_cluster(ioctx, uuid3, "new cluster"));
 
   ASSERT_EQ(0, rbd.mirror_peer_list(ioctx, &peers));
   expected_peers = {
-    {"uuid1", "cluster1", "new client"},
-    {"uuid3", "new cluster", "admin"}};
+    {uuid1, "cluster1", "new client"},
+    {uuid3, "new cluster", "admin"}};
+  std::sort(expected_peers.begin(), expected_peers.end(), sort_peers);
   ASSERT_EQ(expected_peers, peers);
 
-  ASSERT_EQ(-EBUSY, rbd.mirror_set_enabled(ioctx, false));
+  ASSERT_EQ(-EBUSY, rbd.mirror_mode_set(ioctx, RBD_MIRROR_MODE_DISABLED));
+}
+
+TEST_F(TestLibRBD, FlushCacheWithCopyupOnExternalSnapshot) {
+  REQUIRE_FEATURE(RBD_FEATURE_LAYERING);
+
+  librados::IoCtx ioctx;
+  ASSERT_EQ(0, _rados.ioctx_create(m_pool_name.c_str(), ioctx));
+
+  librbd::RBD rbd;
+  librbd::Image image;
+  std::string name = get_temp_image_name();
+
+  uint64_t size = 1 << 18;
+  int order = 0;
+
+  ASSERT_EQ(0, create_image_pp(rbd, ioctx, name.c_str(), size, &order));
+  ASSERT_EQ(0, rbd.open(ioctx, image, name.c_str(), NULL));
+
+  bufferlist bl;
+  bl.append(std::string(size, '1'));
+  ASSERT_EQ((int)size, image.write(0, size, bl));
+  ASSERT_EQ(0, image.snap_create("one"));
+  ASSERT_EQ(0, image.snap_protect("one"));
+
+  std::string clone_name = this->get_temp_image_name();
+  ASSERT_EQ(0, rbd.clone(ioctx, name.c_str(), "one", ioctx, clone_name.c_str(),
+                         RBD_FEATURE_LAYERING, &order));
+  ASSERT_EQ(0, rbd.open(ioctx, image, clone_name.c_str(), NULL));
+
+  librbd::Image image2;
+  ASSERT_EQ(0, rbd.open(ioctx, image2, clone_name.c_str(), NULL));
+
+  // prepare CoW writeback that will be flushed on next op
+  bl.clear();
+  bl.append(std::string(1, '1'));
+  ASSERT_EQ(0, image.flush());
+  ASSERT_EQ(1, image.write(0, 1, bl));
+  ASSERT_EQ(0, image2.snap_create("snap1"));
+
+  librbd::RBD::AioCompletion *read_comp =
+    new librbd::RBD::AioCompletion(NULL, NULL);
+  bufferlist read_bl;
+  image.aio_read(0, 1024, read_bl, read_comp);
+  ASSERT_EQ(0, read_comp->wait_for_complete());
+  read_comp->release();
 }
diff --git a/src/test/librbd/test_main.cc b/src/test/librbd/test_main.cc
index 7451195..c3d7002 100644
--- a/src/test/librbd/test_main.cc
+++ b/src/test/librbd/test_main.cc
@@ -15,6 +15,7 @@ extern void register_test_internal();
 extern void register_test_journal_entries();
 extern void register_test_journal_replay();
 extern void register_test_object_map();
+extern void register_test_mirroring();
 #endif // TEST_LIBRBD_INTERNALS
 
 int main(int argc, char **argv)
@@ -26,6 +27,7 @@ int main(int argc, char **argv)
   register_test_journal_entries();
   register_test_journal_replay();
   register_test_object_map();
+  register_test_mirroring();
 #endif // TEST_LIBRBD_INTERNALS
 
   ::testing::InitGoogleTest(&argc, argv);
diff --git a/src/test/librbd/test_mirroring.cc b/src/test/librbd/test_mirroring.cc
new file mode 100644
index 0000000..6ba7eac
--- /dev/null
+++ b/src/test/librbd/test_mirroring.cc
@@ -0,0 +1,219 @@
+// -*- mode:C; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+/*
+ * Ceph - scalable distributed file system
+ *
+ * Copyright (C) 2016 SUSE LINUX GmbH
+ *
+ * This is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software
+ * Foundation.  See file COPYING.
+ *
+ */
+#include "test/librbd/test_fixture.h"
+#include "test/librbd/test_support.h"
+#include "librbd/AioCompletion.h"
+#include "librbd/AioImageRequest.h"
+#include "librbd/AioImageRequestWQ.h"
+#include "librbd/ExclusiveLock.h"
+#include "librbd/ImageState.h"
+#include "librbd/ImageWatcher.h"
+#include "librbd/internal.h"
+#include "librbd/ObjectMap.h"
+#include "librbd/Operations.h"
+#include <boost/scope_exit.hpp>
+#include <boost/assign/list_of.hpp>
+#include <utility>
+#include <vector>
+
+void register_test_mirroring() {
+}
+
+class TestMirroring : public TestFixture {
+public:
+
+  TestMirroring() {}
+
+
+  virtual void TearDown() {
+    unlock_image();
+
+    TestFixture::TearDown();
+  }
+
+  std::string image_name = "mirrorimg1";
+
+  void check_mirror_image_enable(uint64_t features,
+                                 int expected_r,
+                                 rbd_mirror_image_state_t mirror_state) {
+
+    ASSERT_EQ(0, m_rbd.mirror_mode_set(m_ioctx, RBD_MIRROR_MODE_DISABLED));
+
+    int order = 20;
+    ASSERT_EQ(0, m_rbd.create2(m_ioctx, image_name.c_str(), 4096, features, &order));
+    librbd::Image image;
+    ASSERT_EQ(0, m_rbd.open(m_ioctx, image, image_name.c_str()));
+
+    ASSERT_EQ(expected_r, image.mirror_image_enable());
+
+    librbd::mirror_image_info_t mirror_image;
+    ASSERT_EQ(0, image.mirror_image_get_info(&mirror_image, sizeof(mirror_image)));
+    ASSERT_EQ(mirror_state, mirror_image.state);
+
+    ASSERT_EQ(0, image.close());
+    ASSERT_EQ(0, m_rbd.remove(m_ioctx, image_name.c_str()));
+  }
+
+  void check_mirroring_on_create(uint64_t features,
+                                 rbd_mirror_mode_t mirror_mode,
+                                 rbd_mirror_image_state_t mirror_state) {
+
+    ASSERT_EQ(0, m_rbd.mirror_mode_set(m_ioctx, mirror_mode));
+
+    int order = 20;
+    ASSERT_EQ(0, m_rbd.create2(m_ioctx, image_name.c_str(), 4096, features, &order));
+    librbd::Image image;
+    ASSERT_EQ(0, m_rbd.open(m_ioctx, image, image_name.c_str()));
+
+    librbd::mirror_image_info_t mirror_image;
+    ASSERT_EQ(0, image.mirror_image_get_info(&mirror_image, sizeof(mirror_image)));
+    ASSERT_EQ(mirror_state, mirror_image.state);
+
+    ASSERT_EQ(0, image.close());
+    ASSERT_EQ(0, m_rbd.remove(m_ioctx, image_name.c_str()));
+  }
+
+  void check_mirroring_on_update_features(uint64_t init_features,
+                                 bool enable, bool enable_mirroring,
+                                 uint64_t features, int expected_r,
+                                 rbd_mirror_mode_t mirror_mode,
+                                 rbd_mirror_image_state_t mirror_state) {
+
+    ASSERT_EQ(0, m_rbd.mirror_mode_set(m_ioctx, mirror_mode));
+
+    int order = 20;
+    ASSERT_EQ(0, m_rbd.create2(m_ioctx, image_name.c_str(), 4096, init_features, &order));
+    librbd::Image image;
+    ASSERT_EQ(0, m_rbd.open(m_ioctx, image, image_name.c_str()));
+
+    if (enable_mirroring) {
+      ASSERT_EQ(0, image.mirror_image_enable());
+    }
+
+    ASSERT_EQ(expected_r, image.update_features(features, enable));
+
+    librbd::mirror_image_info_t mirror_image;
+    ASSERT_EQ(0, image.mirror_image_get_info(&mirror_image, sizeof(mirror_image)));
+    ASSERT_EQ(mirror_state, mirror_image.state);
+    ASSERT_EQ(0, image.close());
+    ASSERT_EQ(0, m_rbd.remove(m_ioctx, image_name.c_str()));
+  }
+
+};
+
+TEST_F(TestMirroring, EnableImageMirror) {
+  uint64_t features = 0;
+  features |= RBD_FEATURE_OBJECT_MAP;
+  features |= RBD_FEATURE_EXCLUSIVE_LOCK;
+  features |= RBD_FEATURE_JOURNALING;
+  check_mirror_image_enable(features, 0, RBD_MIRROR_IMAGE_ENABLED);
+}
+
+TEST_F(TestMirroring, EnableImageMirror_WithoutJournaling) {
+  uint64_t features = 0;
+  features |= RBD_FEATURE_OBJECT_MAP;
+  features |= RBD_FEATURE_EXCLUSIVE_LOCK;
+  check_mirror_image_enable(features, -EINVAL, RBD_MIRROR_IMAGE_DISABLED);
+}
+
+TEST_F(TestMirroring, CreateImage_In_MirrorModeDisabled) {
+  uint64_t features = 0;
+  features |= RBD_FEATURE_OBJECT_MAP;
+  features |= RBD_FEATURE_EXCLUSIVE_LOCK;
+  features |= RBD_FEATURE_JOURNALING;
+  check_mirroring_on_create(features, RBD_MIRROR_MODE_DISABLED,
+                            RBD_MIRROR_IMAGE_DISABLED);
+}
+
+TEST_F(TestMirroring, CreateImage_In_MirrorModeImage) {
+  uint64_t features = 0;
+  features |= RBD_FEATURE_OBJECT_MAP;
+  features |= RBD_FEATURE_EXCLUSIVE_LOCK;
+  features |= RBD_FEATURE_JOURNALING;
+  check_mirroring_on_create(features, RBD_MIRROR_MODE_IMAGE,
+                            RBD_MIRROR_IMAGE_DISABLED);
+}
+
+TEST_F(TestMirroring, CreateImage_In_MirrorModePool) {
+  uint64_t features = 0;
+  features |= RBD_FEATURE_OBJECT_MAP;
+  features |= RBD_FEATURE_EXCLUSIVE_LOCK;
+  features |= RBD_FEATURE_JOURNALING;
+  check_mirroring_on_create(features, RBD_MIRROR_MODE_POOL,
+                            RBD_MIRROR_IMAGE_ENABLED);
+}
+
+TEST_F(TestMirroring, CreateImage_In_MirrorModePool_WithoutJournaling) {
+  uint64_t features = 0;
+  features |= RBD_FEATURE_OBJECT_MAP;
+  features |= RBD_FEATURE_EXCLUSIVE_LOCK;
+  check_mirroring_on_create(features, RBD_MIRROR_MODE_POOL,
+                            RBD_MIRROR_IMAGE_DISABLED);
+}
+
+TEST_F(TestMirroring, CreateImage_In_MirrorModeImage_WithoutJournaling) {
+  uint64_t features = 0;
+  features |= RBD_FEATURE_OBJECT_MAP;
+  features |= RBD_FEATURE_EXCLUSIVE_LOCK;
+  check_mirroring_on_create(features, RBD_MIRROR_MODE_IMAGE,
+                            RBD_MIRROR_IMAGE_DISABLED);
+}
+
+TEST_F(TestMirroring, EnableJournaling_In_MirrorModeDisabled) {
+  uint64_t init_features = 0;
+  init_features |= RBD_FEATURE_OBJECT_MAP;
+  init_features |= RBD_FEATURE_EXCLUSIVE_LOCK;
+  uint64_t features = init_features | RBD_FEATURE_JOURNALING;
+  check_mirroring_on_update_features(init_features, true, false, features, 0,
+                      RBD_MIRROR_MODE_DISABLED, RBD_MIRROR_IMAGE_DISABLED);
+}
+
+TEST_F(TestMirroring, EnableJournaling_In_MirrorModeImage) {
+  uint64_t init_features = 0;
+  init_features |= RBD_FEATURE_OBJECT_MAP;
+  init_features |= RBD_FEATURE_EXCLUSIVE_LOCK;
+  uint64_t features = init_features | RBD_FEATURE_JOURNALING;
+  check_mirroring_on_update_features(init_features, true, false, features, 0,
+                      RBD_MIRROR_MODE_IMAGE, RBD_MIRROR_IMAGE_DISABLED);
+}
+
+TEST_F(TestMirroring, EnableJournaling_In_MirrorModePool) {
+  uint64_t init_features = 0;
+  init_features |= RBD_FEATURE_OBJECT_MAP;
+  init_features |= RBD_FEATURE_EXCLUSIVE_LOCK;
+  uint64_t features = init_features | RBD_FEATURE_JOURNALING;
+  check_mirroring_on_update_features(init_features, true, false, features, 0,
+                      RBD_MIRROR_MODE_POOL, RBD_MIRROR_IMAGE_ENABLED);
+}
+
+TEST_F(TestMirroring, DisableJournaling_In_MirrorModePool) {
+  uint64_t init_features = 0;
+  init_features |= RBD_FEATURE_OBJECT_MAP;
+  init_features |= RBD_FEATURE_EXCLUSIVE_LOCK;
+  init_features |= RBD_FEATURE_JOURNALING;
+  uint64_t features = RBD_FEATURE_JOURNALING;
+  check_mirroring_on_update_features(init_features, false, false, features, 0,
+                      RBD_MIRROR_MODE_POOL, RBD_MIRROR_IMAGE_DISABLED);
+}
+
+TEST_F(TestMirroring, DisableJournaling_In_MirrorModeImage) {
+  uint64_t init_features = 0;
+  init_features |= RBD_FEATURE_OBJECT_MAP;
+  init_features |= RBD_FEATURE_EXCLUSIVE_LOCK;
+  init_features |= RBD_FEATURE_JOURNALING;
+  uint64_t features = RBD_FEATURE_JOURNALING;
+  check_mirroring_on_update_features(init_features, false, true, features, -EINVAL,
+                      RBD_MIRROR_MODE_IMAGE, RBD_MIRROR_IMAGE_ENABLED);
+}
+
diff --git a/src/test/librbd/test_mock_ExclusiveLock.cc b/src/test/librbd/test_mock_ExclusiveLock.cc
index 6913d1d..7757675 100644
--- a/src/test/librbd/test_mock_ExclusiveLock.cc
+++ b/src/test/librbd/test_mock_ExclusiveLock.cc
@@ -12,15 +12,25 @@
 #include <list>
 
 namespace librbd {
+
+namespace {
+
+struct MockExclusiveLockImageCtx : public MockImageCtx {
+  MockExclusiveLockImageCtx(ImageCtx &image_ctx) : MockImageCtx(image_ctx) {
+  }
+};
+
+} // anonymous namespace
+
 namespace exclusive_lock {
 
 template<typename T>
 struct BaseRequest {
   static std::list<T *> s_requests;
-  Context *on_lock_unlock;
-  Context *on_finish;
+  Context *on_lock_unlock = nullptr;
+  Context *on_finish = nullptr;
 
-  static T* create(MockImageCtx &image_ctx, const std::string &cookie,
+  static T* create(MockExclusiveLockImageCtx &image_ctx, const std::string &cookie,
                    Context *on_lock_unlock, Context *on_finish) {
     assert(!s_requests.empty());
     T* req = s_requests.front();
@@ -39,12 +49,12 @@ template<typename T>
 std::list<T *> BaseRequest<T>::s_requests;
 
 template <>
-struct AcquireRequest<MockImageCtx> : public BaseRequest<AcquireRequest<MockImageCtx> > {
+struct AcquireRequest<MockExclusiveLockImageCtx> : public BaseRequest<AcquireRequest<MockExclusiveLockImageCtx> > {
   MOCK_METHOD0(send, void());
 };
 
 template <>
-struct ReleaseRequest<MockImageCtx> : public BaseRequest<ReleaseRequest<MockImageCtx> > {
+struct ReleaseRequest<MockExclusiveLockImageCtx> : public BaseRequest<ReleaseRequest<MockExclusiveLockImageCtx> > {
   MOCK_METHOD0(send, void());
 };
 
@@ -53,93 +63,119 @@ struct ReleaseRequest<MockImageCtx> : public BaseRequest<ReleaseRequest<MockImag
 
 // template definitions
 #include "librbd/ExclusiveLock.cc"
-template class librbd::ExclusiveLock<librbd::MockImageCtx>;
+template class librbd::ExclusiveLock<librbd::MockExclusiveLockImageCtx>;
+
+ACTION_P(FinishLockUnlock, request) {
+  if (request->on_lock_unlock != nullptr) {
+    request->on_lock_unlock->complete(0);
+  }
+}
 
 namespace librbd {
 
 using ::testing::_;
+using ::testing::DoAll;
 using ::testing::Invoke;
 using ::testing::InSequence;
 using ::testing::Return;
 
 class TestMockExclusiveLock : public TestMockFixture {
 public:
-  typedef ExclusiveLock<MockImageCtx> MockExclusiveLock;
-  typedef exclusive_lock::AcquireRequest<MockImageCtx> MockAcquireRequest;
-  typedef exclusive_lock::ReleaseRequest<MockImageCtx> MockReleaseRequest;
+  typedef ExclusiveLock<MockExclusiveLockImageCtx> MockExclusiveLock;
+  typedef exclusive_lock::AcquireRequest<MockExclusiveLockImageCtx> MockAcquireRequest;
+  typedef exclusive_lock::ReleaseRequest<MockExclusiveLockImageCtx> MockReleaseRequest;
 
-  void expect_get_watch_handle(MockImageCtx &mock_image_ctx) {
+  void expect_get_watch_handle(MockExclusiveLockImageCtx &mock_image_ctx) {
     EXPECT_CALL(*mock_image_ctx.image_watcher, get_watch_handle())
                   .WillRepeatedly(Return(1234567890));
   }
 
-  void expect_block_writes(MockImageCtx &mock_image_ctx) {
+  void expect_set_require_lock_on_read(MockExclusiveLockImageCtx &mock_image_ctx) {
+    EXPECT_CALL(*mock_image_ctx.aio_work_queue, set_require_lock_on_read());
+  }
+
+  void expect_clear_require_lock_on_read(MockExclusiveLockImageCtx &mock_image_ctx) {
+    EXPECT_CALL(*mock_image_ctx.aio_work_queue, clear_require_lock_on_read());
+  }
+
+  void expect_block_writes(MockExclusiveLockImageCtx &mock_image_ctx) {
     EXPECT_CALL(*mock_image_ctx.aio_work_queue, block_writes(_))
                   .WillOnce(CompleteContext(0, mock_image_ctx.image_ctx->op_work_queue));
+    if ((mock_image_ctx.features & RBD_FEATURE_JOURNALING) != 0) {
+      expect_set_require_lock_on_read(mock_image_ctx);
+    }
   }
 
-  void expect_unblock_writes(MockImageCtx &mock_image_ctx) {
+  void expect_unblock_writes(MockExclusiveLockImageCtx &mock_image_ctx) {
+    expect_clear_require_lock_on_read(mock_image_ctx);
     EXPECT_CALL(*mock_image_ctx.aio_work_queue, unblock_writes());
   }
 
-  void expect_acquire_lock(MockImageCtx &mock_image_ctx,
+  void expect_acquire_lock(MockExclusiveLockImageCtx &mock_image_ctx,
                            MockAcquireRequest &acquire_request, int r) {
     expect_get_watch_handle(mock_image_ctx);
     EXPECT_CALL(acquire_request, send())
-                  .WillOnce(FinishRequest(&acquire_request, r, &mock_image_ctx));
+                  .WillOnce(DoAll(FinishLockUnlock(&acquire_request),
+                                  FinishRequest(&acquire_request, r, &mock_image_ctx)));
     if (r == 0) {
       expect_notify_acquired_lock(mock_image_ctx);
       expect_unblock_writes(mock_image_ctx);
     }
   }
 
-  void expect_release_lock(MockImageCtx &mock_image_ctx,
+  void expect_release_lock(MockExclusiveLockImageCtx &mock_image_ctx,
                            MockReleaseRequest &release_request, int r,
                            bool shutting_down = false) {
     EXPECT_CALL(release_request, send())
-                  .WillOnce(FinishRequest(&release_request, r, &mock_image_ctx));
+                  .WillOnce(DoAll(FinishLockUnlock(&release_request),
+                                  FinishRequest(&release_request, r, &mock_image_ctx)));
     if (r == 0) {
       if (shutting_down) {
         expect_unblock_writes(mock_image_ctx);
       }
       expect_notify_released_lock(mock_image_ctx);
-      expect_writes_empty(mock_image_ctx);
+      expect_is_lock_request_needed(mock_image_ctx, false);
     }
   }
 
-  void expect_notify_request_lock(MockImageCtx &mock_image_ctx,
+  void expect_notify_request_lock(MockExclusiveLockImageCtx &mock_image_ctx,
                                   MockExclusiveLock &mock_exclusive_lock) {
     EXPECT_CALL(*mock_image_ctx.image_watcher, notify_request_lock())
                   .WillRepeatedly(Invoke(&mock_exclusive_lock,
                                          &MockExclusiveLock::handle_lock_released));
   }
 
-  void expect_notify_acquired_lock(MockImageCtx &mock_image_ctx) {
+  void expect_notify_acquired_lock(MockExclusiveLockImageCtx &mock_image_ctx) {
     EXPECT_CALL(*mock_image_ctx.image_watcher, notify_acquired_lock())
                   .Times(1);
   }
 
-  void expect_notify_released_lock(MockImageCtx &mock_image_ctx) {
+  void expect_notify_released_lock(MockExclusiveLockImageCtx &mock_image_ctx) {
     EXPECT_CALL(*mock_image_ctx.image_watcher, notify_released_lock())
                   .Times(1);
   }
 
-  void expect_writes_empty(MockImageCtx &mock_image_ctx) {
-    EXPECT_CALL(*mock_image_ctx.aio_work_queue, writes_empty())
-                  .WillRepeatedly(Return(true));
+  void expect_is_lock_request_needed(MockExclusiveLockImageCtx &mock_image_ctx, bool ret) {
+    EXPECT_CALL(*mock_image_ctx.aio_work_queue, is_lock_request_needed())
+                  .WillRepeatedly(Return(ret));
   }
 
-  int when_init(MockImageCtx &mock_image_ctx,
+  void expect_flush_notifies(MockExclusiveLockImageCtx &mock_image_ctx) {
+    EXPECT_CALL(*mock_image_ctx.image_watcher, flush(_))
+                  .WillOnce(CompleteContext(0, mock_image_ctx.image_ctx->op_work_queue));
+  }
+
+  int when_init(MockExclusiveLockImageCtx &mock_image_ctx,
                 MockExclusiveLock &exclusive_lock) {
     C_SaferCond ctx;
     {
       RWLock::WLocker owner_locker(mock_image_ctx.owner_lock);
-      exclusive_lock.init(&ctx);
+      exclusive_lock.init(mock_image_ctx.features, &ctx);
     }
     return ctx.wait();
   }
 
-  int when_try_lock(MockImageCtx &mock_image_ctx,
+  int when_try_lock(MockExclusiveLockImageCtx &mock_image_ctx,
                      MockExclusiveLock &exclusive_lock) {
     C_SaferCond ctx;
     {
@@ -148,7 +184,7 @@ public:
     }
     return ctx.wait();
   }
-  int when_request_lock(MockImageCtx &mock_image_ctx,
+  int when_request_lock(MockExclusiveLockImageCtx &mock_image_ctx,
                      MockExclusiveLock &exclusive_lock) {
     C_SaferCond ctx;
     {
@@ -157,7 +193,7 @@ public:
     }
     return ctx.wait();
   }
-  int when_release_lock(MockImageCtx &mock_image_ctx,
+  int when_release_lock(MockExclusiveLockImageCtx &mock_image_ctx,
                      MockExclusiveLock &exclusive_lock) {
     C_SaferCond ctx;
     {
@@ -166,7 +202,7 @@ public:
     }
     return ctx.wait();
   }
-  int when_shut_down(MockImageCtx &mock_image_ctx,
+  int when_shut_down(MockExclusiveLockImageCtx &mock_image_ctx,
                      MockExclusiveLock &exclusive_lock) {
     C_SaferCond ctx;
     {
@@ -176,7 +212,7 @@ public:
     return ctx.wait();
   }
 
-  bool is_lock_owner(MockImageCtx &mock_image_ctx,
+  bool is_lock_owner(MockExclusiveLockImageCtx &mock_image_ctx,
                      MockExclusiveLock &exclusive_lock) {
     RWLock::RLocker owner_locker(mock_image_ctx.owner_lock);
     return exclusive_lock.is_lock_owner();
@@ -189,7 +225,7 @@ TEST_F(TestMockExclusiveLock, StateTransitions) {
   librbd::ImageCtx *ictx;
   ASSERT_EQ(0, open_image(m_image_name, &ictx));
 
-  MockImageCtx mock_image_ctx(*ictx);
+  MockExclusiveLockImageCtx mock_image_ctx(*ictx);
   MockExclusiveLock exclusive_lock(mock_image_ctx);
   expect_op_work_queue(mock_image_ctx);
 
@@ -224,7 +260,7 @@ TEST_F(TestMockExclusiveLock, TryLockLockedState) {
   librbd::ImageCtx *ictx;
   ASSERT_EQ(0, open_image(m_image_name, &ictx));
 
-  MockImageCtx mock_image_ctx(*ictx);
+  MockExclusiveLockImageCtx mock_image_ctx(*ictx);
   MockExclusiveLock exclusive_lock(mock_image_ctx);
   expect_op_work_queue(mock_image_ctx);
 
@@ -248,7 +284,7 @@ TEST_F(TestMockExclusiveLock, TryLockAlreadyLocked) {
   librbd::ImageCtx *ictx;
   ASSERT_EQ(0, open_image(m_image_name, &ictx));
 
-  MockImageCtx mock_image_ctx(*ictx);
+  MockExclusiveLockImageCtx mock_image_ctx(*ictx);
   MockExclusiveLock exclusive_lock(mock_image_ctx);
   expect_op_work_queue(mock_image_ctx);
 
@@ -262,6 +298,7 @@ TEST_F(TestMockExclusiveLock, TryLockAlreadyLocked) {
   ASSERT_FALSE(is_lock_owner(mock_image_ctx, exclusive_lock));
 
   expect_unblock_writes(mock_image_ctx);
+  expect_flush_notifies(mock_image_ctx);
   ASSERT_EQ(0, when_shut_down(mock_image_ctx, exclusive_lock));
 }
 
@@ -271,7 +308,7 @@ TEST_F(TestMockExclusiveLock, TryLockBusy) {
   librbd::ImageCtx *ictx;
   ASSERT_EQ(0, open_image(m_image_name, &ictx));
 
-  MockImageCtx mock_image_ctx(*ictx);
+  MockExclusiveLockImageCtx mock_image_ctx(*ictx);
   MockExclusiveLock exclusive_lock(mock_image_ctx);
   expect_op_work_queue(mock_image_ctx);
 
@@ -285,6 +322,7 @@ TEST_F(TestMockExclusiveLock, TryLockBusy) {
   ASSERT_FALSE(is_lock_owner(mock_image_ctx, exclusive_lock));
 
   expect_unblock_writes(mock_image_ctx);
+  expect_flush_notifies(mock_image_ctx);
   ASSERT_EQ(0, when_shut_down(mock_image_ctx, exclusive_lock));
 }
 
@@ -294,7 +332,7 @@ TEST_F(TestMockExclusiveLock, TryLockError) {
   librbd::ImageCtx *ictx;
   ASSERT_EQ(0, open_image(m_image_name, &ictx));
 
-  MockImageCtx mock_image_ctx(*ictx);
+  MockExclusiveLockImageCtx mock_image_ctx(*ictx);
   MockExclusiveLock exclusive_lock(mock_image_ctx);
   expect_op_work_queue(mock_image_ctx);
 
@@ -309,6 +347,7 @@ TEST_F(TestMockExclusiveLock, TryLockError) {
   ASSERT_FALSE(is_lock_owner(mock_image_ctx, exclusive_lock));
 
   expect_unblock_writes(mock_image_ctx);
+  expect_flush_notifies(mock_image_ctx);
   ASSERT_EQ(0, when_shut_down(mock_image_ctx, exclusive_lock));
 }
 
@@ -318,7 +357,7 @@ TEST_F(TestMockExclusiveLock, RequestLockLockedState) {
   librbd::ImageCtx *ictx;
   ASSERT_EQ(0, open_image(m_image_name, &ictx));
 
-  MockImageCtx mock_image_ctx(*ictx);
+  MockExclusiveLockImageCtx mock_image_ctx(*ictx);
   MockExclusiveLock exclusive_lock(mock_image_ctx);
   expect_op_work_queue(mock_image_ctx);
 
@@ -343,7 +382,7 @@ TEST_F(TestMockExclusiveLock, RequestLockBlacklist) {
   librbd::ImageCtx *ictx;
   ASSERT_EQ(0, open_image(m_image_name, &ictx));
 
-  MockImageCtx mock_image_ctx(*ictx);
+  MockExclusiveLockImageCtx mock_image_ctx(*ictx);
   MockExclusiveLock exclusive_lock(mock_image_ctx);
   expect_op_work_queue(mock_image_ctx);
 
@@ -359,6 +398,7 @@ TEST_F(TestMockExclusiveLock, RequestLockBlacklist) {
   ASSERT_FALSE(is_lock_owner(mock_image_ctx, exclusive_lock));
 
   expect_unblock_writes(mock_image_ctx);
+  expect_flush_notifies(mock_image_ctx);
   ASSERT_EQ(0, when_shut_down(mock_image_ctx, exclusive_lock));
 }
 
@@ -368,7 +408,7 @@ TEST_F(TestMockExclusiveLock, RequestLockBusy) {
   librbd::ImageCtx *ictx;
   ASSERT_EQ(0, open_image(m_image_name, &ictx));
 
-  MockImageCtx mock_image_ctx(*ictx);
+  MockExclusiveLockImageCtx mock_image_ctx(*ictx);
   MockExclusiveLock exclusive_lock(mock_image_ctx);
   expect_op_work_queue(mock_image_ctx);
 
@@ -397,7 +437,7 @@ TEST_F(TestMockExclusiveLock, RequestLockError) {
   librbd::ImageCtx *ictx;
   ASSERT_EQ(0, open_image(m_image_name, &ictx));
 
-  MockImageCtx mock_image_ctx(*ictx);
+  MockExclusiveLockImageCtx mock_image_ctx(*ictx);
   MockExclusiveLock exclusive_lock(mock_image_ctx);
   expect_op_work_queue(mock_image_ctx);
 
@@ -426,7 +466,7 @@ TEST_F(TestMockExclusiveLock, ReleaseLockUnlockedState) {
   librbd::ImageCtx *ictx;
   ASSERT_EQ(0, open_image(m_image_name, &ictx));
 
-  MockImageCtx mock_image_ctx(*ictx);
+  MockExclusiveLockImageCtx mock_image_ctx(*ictx);
   MockExclusiveLock exclusive_lock(mock_image_ctx);
   expect_op_work_queue(mock_image_ctx);
 
@@ -437,6 +477,7 @@ TEST_F(TestMockExclusiveLock, ReleaseLockUnlockedState) {
   ASSERT_EQ(0, when_release_lock(mock_image_ctx, exclusive_lock));
 
   expect_unblock_writes(mock_image_ctx);
+  expect_flush_notifies(mock_image_ctx);
   ASSERT_EQ(0, when_shut_down(mock_image_ctx, exclusive_lock));
 }
 
@@ -446,7 +487,7 @@ TEST_F(TestMockExclusiveLock, ReleaseLockError) {
   librbd::ImageCtx *ictx;
   ASSERT_EQ(0, open_image(m_image_name, &ictx));
 
-  MockImageCtx mock_image_ctx(*ictx);
+  MockExclusiveLockImageCtx mock_image_ctx(*ictx);
   MockExclusiveLock exclusive_lock(mock_image_ctx);
   expect_op_work_queue(mock_image_ctx);
 
@@ -476,7 +517,7 @@ TEST_F(TestMockExclusiveLock, ConcurrentRequests) {
   librbd::ImageCtx *ictx;
   ASSERT_EQ(0, open_image(m_image_name, &ictx));
 
-  MockImageCtx mock_image_ctx(*ictx);
+  MockExclusiveLockImageCtx mock_image_ctx(*ictx);
   MockExclusiveLock exclusive_lock(mock_image_ctx);
   expect_op_work_queue(mock_image_ctx);
 
@@ -498,7 +539,7 @@ TEST_F(TestMockExclusiveLock, ConcurrentRequests) {
   EXPECT_CALL(release, send())
                 .WillOnce(Notify(&wait_for_send_ctx2));
   expect_notify_released_lock(mock_image_ctx);
-  expect_writes_empty(mock_image_ctx);
+  expect_is_lock_request_needed(mock_image_ctx, false);
 
   C_SaferCond try_request_ctx1;
   {
@@ -528,6 +569,7 @@ TEST_F(TestMockExclusiveLock, ConcurrentRequests) {
 
   // fail the try_lock
   ASSERT_EQ(0, wait_for_send_ctx1.wait());
+  try_lock_acquire.on_lock_unlock->complete(0);
   try_lock_acquire.on_finish->complete(-EINVAL);
   ASSERT_EQ(-EINVAL, try_request_ctx1.wait());
 
@@ -538,11 +580,12 @@ TEST_F(TestMockExclusiveLock, ConcurrentRequests) {
 
   // proceed with the release
   ASSERT_EQ(0, wait_for_send_ctx2.wait());
+  release.on_lock_unlock->complete(0);
   release.on_finish->complete(0);
   ASSERT_EQ(0, release_lock_ctx1.wait());
 
   expect_unblock_writes(mock_image_ctx);
-  expect_op_work_queue(mock_image_ctx);
+  expect_flush_notifies(mock_image_ctx);
   ASSERT_EQ(0, when_shut_down(mock_image_ctx, exclusive_lock));
 }
 
diff --git a/src/test/librbd/test_mock_Journal.cc b/src/test/librbd/test_mock_Journal.cc
index c849e60..050a4d0 100644
--- a/src/test/librbd/test_mock_Journal.cc
+++ b/src/test/librbd/test_mock_Journal.cc
@@ -7,6 +7,7 @@
 #include "common/Cond.h"
 #include "common/Mutex.h"
 #include "cls/journal/cls_journal_types.h"
+#include "journal/Journaler.h"
 #include "librbd/Journal.h"
 #include "librbd/Utils.h"
 #include "librbd/journal/Replay.h"
@@ -85,6 +86,12 @@ struct MockJournaler {
   MOCK_METHOD3(get_metadata, void(uint8_t *order, uint8_t *splay_width,
                                   int64_t *pool_id));
   MOCK_METHOD1(init, void(Context*));
+  MOCK_METHOD0(shut_down, void());
+  MOCK_METHOD1(flush_commit_position, void(Context*));
+
+  MOCK_METHOD2(get_cached_client, int(const std::string&, cls::journal::Client*));
+  MOCK_METHOD2(update_client, void(const bufferlist &, Context *));
+  MOCK_METHOD3(get_tags, void(uint64_t, journal::Journaler::Tags*, Context*));
 
   MOCK_METHOD1(start_replay, void(::journal::ReplayHandler *replay_handler));
   MOCK_METHOD1(try_pop_front, bool(MockReplayEntryProxy *replay_entry));
@@ -108,6 +115,13 @@ struct MockJournalerProxy {
     MockJournaler::get_instance().construct();
   }
 
+  template <typename IoCtxT>
+  MockJournalerProxy(ContextWQ *work_queue, SafeTimer *safe_timer,
+                     Mutex *timer_lock, IoCtxT &header_ioctx,
+                     const std::string &, const std::string &, double) {
+    MockJournaler::get_instance().construct();
+  }
+
   int exists(bool *header_exists) const {
     return -EINVAL;
   }
@@ -132,6 +146,26 @@ struct MockJournalerProxy {
   void init(Context *on_finish) {
     MockJournaler::get_instance().init(on_finish);
   }
+  void shut_down() {
+    MockJournaler::get_instance().shut_down();
+  }
+
+  int get_cached_client(const std::string& client_id,
+                        cls::journal::Client* client) {
+    return MockJournaler::get_instance().get_cached_client(client_id, client);
+  }
+  void update_client(const bufferlist &client_data, Context *on_finish) {
+    MockJournaler::get_instance().update_client(client_data, on_finish);
+  }
+
+  void get_tags(uint64_t tag_class, journal::Journaler::Tags *tags,
+                Context *on_finish) {
+    MockJournaler::get_instance().get_tags(tag_class, tags, on_finish);
+  }
+
+  void flush_commit_position(Context *on_finish) {
+    MockJournaler::get_instance().flush_commit_position(on_finish);
+  }
 
   void start_replay(::journal::ReplayHandler *replay_handler) {
     MockJournaler::get_instance().start_replay(replay_handler);
@@ -178,10 +212,20 @@ MockJournaler *MockJournaler::s_instance = nullptr;
 } // namespace journal
 
 namespace librbd {
+
+namespace {
+
+struct MockJournalImageCtx : public MockImageCtx {
+  MockJournalImageCtx(librbd::ImageCtx& image_ctx) : MockImageCtx(image_ctx) {
+  }
+};
+
+} // anonymous namespace
+
 namespace journal {
 
 template <>
-struct TypeTraits<MockImageCtx> {
+struct TypeTraits<MockJournalImageCtx> {
   typedef ::journal::MockJournalerProxy Journaler;
   typedef ::journal::MockFutureProxy  Future;
   typedef ::journal::MockReplayEntryProxy ReplayEntry;
@@ -198,20 +242,20 @@ struct MockReplay {
     s_instance = this;
   }
 
-  MOCK_METHOD1(flush, void(Context *));
+  MOCK_METHOD2(shut_down, void(bool cancel_ops, Context *));
   MOCK_METHOD3(process, void(bufferlist::iterator*, Context *, Context *));
   MOCK_METHOD2(replay_op_ready, void(uint64_t, Context *));
 };
 
 template <>
-class Replay<MockImageCtx> {
+class Replay<MockJournalImageCtx> {
 public:
-  static Replay *create(MockImageCtx &image_ctx) {
+  static Replay *create(MockJournalImageCtx &image_ctx) {
     return new Replay();
   }
 
-  void flush(Context *on_finish) {
-    MockReplay::get_instance().flush(on_finish);
+  void shut_down(bool cancel_ops, Context *on_finish) {
+    MockReplay::get_instance().shut_down(cancel_ops, on_finish);
   }
 
   void process(bufferlist::iterator *it, Context *on_ready,
@@ -231,7 +275,7 @@ MockReplay *MockReplay::s_instance = nullptr;
 
 // template definitions
 #include "librbd/Journal.cc"
-template class librbd::Journal<librbd::MockImageCtx>;
+template class librbd::Journal<librbd::MockJournalImageCtx>;
 
 using ::testing::_;
 using ::testing::DoAll;
@@ -255,7 +299,7 @@ namespace librbd {
 class TestMockJournal : public TestMockFixture {
 public:
   typedef journal::MockReplay MockJournalReplay;
-  typedef Journal<MockImageCtx> MockJournal;
+  typedef Journal<MockJournalImageCtx> MockJournal;
 
   typedef std::function<void(::journal::ReplayHandler*)> ReplayAction;
   typedef std::list<ReplayAction> ReplayActions;
@@ -293,10 +337,39 @@ public:
   void expect_init_journaler(::journal::MockJournaler &mock_journaler, int r) {
     EXPECT_CALL(mock_journaler, init(_))
                   .WillOnce(CompleteContext(r, NULL));
+  }
+
+  void expect_get_journaler_cached_client(::journal::MockJournaler &mock_journaler, int r) {
+
+    journal::ImageClientMeta image_client_meta;
+    image_client_meta.tag_class = 0;
+
+    journal::ClientData client_data;
+    client_data.client_meta = image_client_meta;
+
+    cls::journal::Client client;
+    ::encode(client_data, client.data);
 
+    EXPECT_CALL(mock_journaler, get_cached_client("", _))
+                  .WillOnce(DoAll(SetArgPointee<1>(client),
+                                  Return(r)));
   }
 
-  void expect_start_replay(MockImageCtx &mock_image_ctx,
+  void expect_get_journaler_tags(MockImageCtx &mock_image_ctx,
+                                 ::journal::MockJournaler &mock_journaler,
+                                 int r) {
+    journal::TagData tag_data;
+
+    bufferlist tag_data_bl;
+    ::encode(tag_data, tag_data_bl);
+
+    ::journal::Journaler::Tags tags = {{0, 0, {}}, {1, 0, tag_data_bl}};
+    EXPECT_CALL(mock_journaler, get_tags(0, _, _))
+                  .WillOnce(DoAll(SetArgPointee<1>(tags),
+                                  WithArg<2>(CompleteContext(r, mock_image_ctx.image_ctx->op_work_queue))));
+  }
+
+  void expect_start_replay(MockJournalImageCtx &mock_image_ctx,
                            ::journal::MockJournaler &mock_journaler,
                            const ReplayActions &actions) {
     EXPECT_CALL(mock_journaler, start_replay(_))
@@ -308,11 +381,12 @@ public:
     EXPECT_CALL(mock_journaler, stop_replay());
   }
 
-  void expect_flush_replay(MockImageCtx &mock_image_ctx,
-                           MockJournalReplay &mock_journal_replay, int r) {
-    EXPECT_CALL(mock_journal_replay, flush(_))
-                  .WillOnce(Invoke([this, &mock_image_ctx, r](Context *on_flush) {
-                    this->commit_replay(mock_image_ctx, on_flush, r);}));
+  void expect_shut_down_replay(MockJournalImageCtx &mock_image_ctx,
+                               MockJournalReplay &mock_journal_replay, int r,
+                               bool cancel_ops = false) {
+    EXPECT_CALL(mock_journal_replay, shut_down(cancel_ops, _))
+                  .WillOnce(WithArg<1>(Invoke([this, &mock_image_ctx, r](Context *on_flush) {
+                    this->commit_replay(mock_image_ctx, on_flush, r);})));
   }
 
   void expect_get_data(::journal::MockReplayEntry &mock_replay_entry) {
@@ -371,6 +445,11 @@ public:
     EXPECT_CALL(mock_future, is_valid()).WillOnce(Return(false));
   }
 
+  void expect_flush_commit_position(::journal::MockJournaler &mock_journaler) {
+    EXPECT_CALL(mock_journaler, flush_commit_position(_))
+                  .WillOnce(CompleteContext(0, NULL));
+  }
+
   int when_open(MockJournal &mock_journal) {
     C_SaferCond ctx;
     mock_journal.open(&ctx);
@@ -383,7 +462,7 @@ public:
     return ctx.wait();
   }
 
-  uint64_t when_append_io_event(MockImageCtx &mock_image_ctx,
+  uint64_t when_append_io_event(MockJournalImageCtx &mock_image_ctx,
                                 MockJournal &mock_journal,
                                 AioCompletion *aio_comp = nullptr) {
     RWLock::RLocker owner_locker(mock_image_ctx.owner_lock);
@@ -402,7 +481,8 @@ public:
     m_cond.Signal();
   }
 
-  void commit_replay(MockImageCtx &mock_image_ctx, Context *on_flush, int r) {
+  void commit_replay(MockJournalImageCtx &mock_image_ctx, Context *on_flush,
+                     int r) {
     Contexts commit_contexts;
     std::swap(commit_contexts, m_commit_contexts);
 
@@ -412,13 +492,16 @@ public:
     mock_image_ctx.image_ctx->op_work_queue->queue(on_flush, 0);
   }
 
-  void open_journal(MockImageCtx &mock_image_ctx, MockJournal &mock_journal,
+  void open_journal(MockJournalImageCtx &mock_image_ctx,
+                    MockJournal &mock_journal,
                     ::journal::MockJournaler &mock_journaler) {
     expect_op_work_queue(mock_image_ctx);
 
     InSequence seq;
     expect_construct_journaler(mock_journaler);
     expect_init_journaler(mock_journaler, 0);
+    expect_get_journaler_cached_client(mock_journaler, 0);
+    expect_get_journaler_tags(mock_image_ctx, mock_journaler, 0);
     expect_start_replay(
       mock_image_ctx, mock_journaler, {
         std::bind(&invoke_replay_complete, _1, 0)
@@ -426,7 +509,7 @@ public:
 
     MockJournalReplay mock_journal_replay;
     expect_stop_replay(mock_journaler);
-    expect_flush_replay(mock_image_ctx, mock_journal_replay, 0);
+    expect_shut_down_replay(mock_image_ctx, mock_journal_replay, 0);
     expect_committed(mock_journaler, 0);
     expect_start_append(mock_journaler);
     ASSERT_EQ(0, when_open(mock_journal));
@@ -453,7 +536,7 @@ TEST_F(TestMockJournal, StateTransitions) {
   librbd::ImageCtx *ictx;
   ASSERT_EQ(0, open_image(m_image_name, &ictx));
 
-  MockImageCtx mock_image_ctx(*ictx);
+  MockJournalImageCtx mock_image_ctx(*ictx);
   MockJournal mock_journal(mock_image_ctx);
   expect_op_work_queue(mock_image_ctx);
 
@@ -462,6 +545,8 @@ TEST_F(TestMockJournal, StateTransitions) {
   ::journal::MockJournaler mock_journaler;
   expect_construct_journaler(mock_journaler);
   expect_init_journaler(mock_journaler, 0);
+  expect_get_journaler_cached_client(mock_journaler, 0);
+  expect_get_journaler_tags(mock_image_ctx, mock_journaler, 0);
   expect_start_replay(
     mock_image_ctx, mock_journaler, {
       std::bind(&invoke_replay_ready, _1),
@@ -481,7 +566,7 @@ TEST_F(TestMockJournal, StateTransitions) {
   expect_try_pop_front(mock_journaler, false, mock_replay_entry);
 
   expect_stop_replay(mock_journaler);
-  expect_flush_replay(mock_image_ctx, mock_journal_replay, 0);
+  expect_shut_down_replay(mock_image_ctx, mock_journal_replay, 0);
   expect_committed(mock_journaler, 3);
 
   expect_start_append(mock_journaler);
@@ -498,7 +583,7 @@ TEST_F(TestMockJournal, InitError) {
   librbd::ImageCtx *ictx;
   ASSERT_EQ(0, open_image(m_image_name, &ictx));
 
-  MockImageCtx mock_image_ctx(*ictx);
+  MockJournalImageCtx mock_image_ctx(*ictx);
   MockJournal mock_journal(mock_image_ctx);
   expect_op_work_queue(mock_image_ctx);
 
@@ -510,13 +595,52 @@ TEST_F(TestMockJournal, InitError) {
   ASSERT_EQ(-EINVAL, when_open(mock_journal));
 }
 
+TEST_F(TestMockJournal, GetCachedClientError) {
+  REQUIRE_FEATURE(RBD_FEATURE_JOURNALING);
+
+  librbd::ImageCtx *ictx;
+  ASSERT_EQ(0, open_image(m_image_name, &ictx));
+
+  MockJournalImageCtx mock_image_ctx(*ictx);
+  MockJournal mock_journal(mock_image_ctx);
+  expect_op_work_queue(mock_image_ctx);
+
+  InSequence seq;
+
+  ::journal::MockJournaler mock_journaler;
+  expect_construct_journaler(mock_journaler);
+  expect_init_journaler(mock_journaler, 0);
+  expect_get_journaler_cached_client(mock_journaler, -ENOENT);
+  ASSERT_EQ(-ENOENT, when_open(mock_journal));
+}
+
+TEST_F(TestMockJournal, GetTagsError) {
+  REQUIRE_FEATURE(RBD_FEATURE_JOURNALING);
+
+  librbd::ImageCtx *ictx;
+  ASSERT_EQ(0, open_image(m_image_name, &ictx));
+
+  MockJournalImageCtx mock_image_ctx(*ictx);
+  MockJournal mock_journal(mock_image_ctx);
+  expect_op_work_queue(mock_image_ctx);
+
+  InSequence seq;
+
+  ::journal::MockJournaler mock_journaler;
+  expect_construct_journaler(mock_journaler);
+  expect_init_journaler(mock_journaler, 0);
+  expect_get_journaler_cached_client(mock_journaler, 0);
+  expect_get_journaler_tags(mock_image_ctx, mock_journaler, -EBADMSG);
+  ASSERT_EQ(-EBADMSG, when_open(mock_journal));
+}
+
 TEST_F(TestMockJournal, ReplayCompleteError) {
   REQUIRE_FEATURE(RBD_FEATURE_JOURNALING);
 
   librbd::ImageCtx *ictx;
   ASSERT_EQ(0, open_image(m_image_name, &ictx));
 
-  MockImageCtx mock_image_ctx(*ictx);
+  MockJournalImageCtx mock_image_ctx(*ictx);
   MockJournal mock_journal(mock_image_ctx);
   expect_op_work_queue(mock_image_ctx);
 
@@ -525,6 +649,8 @@ TEST_F(TestMockJournal, ReplayCompleteError) {
   ::journal::MockJournaler mock_journaler;
   expect_construct_journaler(mock_journaler);
   expect_init_journaler(mock_journaler, 0);
+  expect_get_journaler_cached_client(mock_journaler, 0);
+  expect_get_journaler_tags(mock_image_ctx, mock_journaler, 0);
   expect_start_replay(
     mock_image_ctx, mock_journaler, {
       std::bind(&invoke_replay_complete, _1, -EINVAL)
@@ -532,18 +658,20 @@ TEST_F(TestMockJournal, ReplayCompleteError) {
 
   MockJournalReplay mock_journal_replay;
   expect_stop_replay(mock_journaler);
-  expect_flush_replay(mock_image_ctx, mock_journal_replay, 0);
+  expect_shut_down_replay(mock_image_ctx, mock_journal_replay, 0, true);
 
   // replay failure should result in replay-restart
   expect_construct_journaler(mock_journaler);
   expect_init_journaler(mock_journaler, 0);
+  expect_get_journaler_cached_client(mock_journaler, 0);
+  expect_get_journaler_tags(mock_image_ctx, mock_journaler, 0);
   expect_start_replay(
     mock_image_ctx, mock_journaler, {
       std::bind(&invoke_replay_complete, _1, 0)
     });
 
   expect_stop_replay(mock_journaler);
-  expect_flush_replay(mock_image_ctx, mock_journal_replay, 0);
+  expect_shut_down_replay(mock_image_ctx, mock_journal_replay, 0);
   expect_start_append(mock_journaler);
   ASSERT_EQ(0, when_open(mock_journal));
 
@@ -557,7 +685,7 @@ TEST_F(TestMockJournal, FlushReplayError) {
   librbd::ImageCtx *ictx;
   ASSERT_EQ(0, open_image(m_image_name, &ictx));
 
-  MockImageCtx mock_image_ctx(*ictx);
+  MockJournalImageCtx mock_image_ctx(*ictx);
   MockJournal mock_journal(mock_image_ctx);
   expect_op_work_queue(mock_image_ctx);
 
@@ -566,6 +694,8 @@ TEST_F(TestMockJournal, FlushReplayError) {
   ::journal::MockJournaler mock_journaler;
   expect_construct_journaler(mock_journaler);
   expect_init_journaler(mock_journaler, 0);
+  expect_get_journaler_cached_client(mock_journaler, 0);
+  expect_get_journaler_tags(mock_image_ctx, mock_journaler, 0);
   expect_start_replay(
     mock_image_ctx, mock_journaler, {
       std::bind(&invoke_replay_ready, _1),
@@ -578,18 +708,20 @@ TEST_F(TestMockJournal, FlushReplayError) {
   expect_replay_process(mock_journal_replay);
   expect_try_pop_front(mock_journaler, false, mock_replay_entry);
   expect_stop_replay(mock_journaler);
-  expect_flush_replay(mock_image_ctx, mock_journal_replay, -EINVAL);
+  expect_shut_down_replay(mock_image_ctx, mock_journal_replay, -EINVAL);
 
   // replay flush failure should result in replay-restart
   expect_construct_journaler(mock_journaler);
   expect_init_journaler(mock_journaler, 0);
+  expect_get_journaler_cached_client(mock_journaler, 0);
+  expect_get_journaler_tags(mock_image_ctx, mock_journaler, 0);
   expect_start_replay(
     mock_image_ctx, mock_journaler, {
       std::bind(&invoke_replay_complete, _1, 0)
     });
 
   expect_stop_replay(mock_journaler);
-  expect_flush_replay(mock_image_ctx, mock_journal_replay, 0);
+  expect_shut_down_replay(mock_image_ctx, mock_journal_replay, 0);
   expect_start_append(mock_journaler);
   ASSERT_EQ(0, when_open(mock_journal));
 
@@ -603,7 +735,7 @@ TEST_F(TestMockJournal, StopError) {
   librbd::ImageCtx *ictx;
   ASSERT_EQ(0, open_image(m_image_name, &ictx));
 
-  MockImageCtx mock_image_ctx(*ictx);
+  MockJournalImageCtx mock_image_ctx(*ictx);
   MockJournal mock_journal(mock_image_ctx);
   expect_op_work_queue(mock_image_ctx);
 
@@ -612,6 +744,8 @@ TEST_F(TestMockJournal, StopError) {
   ::journal::MockJournaler mock_journaler;
   expect_construct_journaler(mock_journaler);
   expect_init_journaler(mock_journaler, 0);
+  expect_get_journaler_cached_client(mock_journaler, 0);
+  expect_get_journaler_tags(mock_image_ctx, mock_journaler, 0);
   expect_start_replay(
     mock_image_ctx, mock_journaler, {
       std::bind(&invoke_replay_complete, _1, 0)
@@ -619,7 +753,7 @@ TEST_F(TestMockJournal, StopError) {
 
   MockJournalReplay mock_journal_replay;
   expect_stop_replay(mock_journaler);
-  expect_flush_replay(mock_image_ctx, mock_journal_replay, 0);
+  expect_shut_down_replay(mock_image_ctx, mock_journal_replay, 0);
   expect_start_append(mock_journaler);
   ASSERT_EQ(0, when_open(mock_journal));
 
@@ -633,7 +767,7 @@ TEST_F(TestMockJournal, ReplayOnDiskPreFlushError) {
   librbd::ImageCtx *ictx;
   ASSERT_EQ(0, open_image(m_image_name, &ictx));
 
-  MockImageCtx mock_image_ctx(*ictx);
+  MockJournalImageCtx mock_image_ctx(*ictx);
   MockJournal mock_journal(mock_image_ctx);
   expect_op_work_queue(mock_image_ctx);
 
@@ -641,6 +775,8 @@ TEST_F(TestMockJournal, ReplayOnDiskPreFlushError) {
   ::journal::MockJournaler mock_journaler;
   expect_construct_journaler(mock_journaler);
   expect_init_journaler(mock_journaler, 0);
+  expect_get_journaler_cached_client(mock_journaler, 0);
+  expect_get_journaler_tags(mock_image_ctx, mock_journaler, 0);
 
   ::journal::ReplayHandler *replay_handler = nullptr;
   expect_start_replay(
@@ -660,18 +796,20 @@ TEST_F(TestMockJournal, ReplayOnDiskPreFlushError) {
 
   expect_try_pop_front(mock_journaler, false, mock_replay_entry);
   expect_stop_replay(mock_journaler);
-  expect_flush_replay(mock_image_ctx, mock_journal_replay, 0);
+  expect_shut_down_replay(mock_image_ctx, mock_journal_replay, 0, true);
 
   // replay write-to-disk failure should result in replay-restart
   expect_construct_journaler(mock_journaler);
   expect_init_journaler(mock_journaler, 0);
+  expect_get_journaler_cached_client(mock_journaler, 0);
+  expect_get_journaler_tags(mock_image_ctx, mock_journaler, 0);
   expect_start_replay(
     mock_image_ctx, mock_journaler, {
       std::bind(&invoke_replay_complete, _1, 0)
     });
 
   expect_stop_replay(mock_journaler);
-  expect_flush_replay(mock_image_ctx, mock_journal_replay, 0);
+  expect_shut_down_replay(mock_image_ctx, mock_journal_replay, 0);
   expect_start_append(mock_journaler);
 
   C_SaferCond ctx;
@@ -706,7 +844,7 @@ TEST_F(TestMockJournal, ReplayOnDiskPostFlushError) {
   librbd::ImageCtx *ictx;
   ASSERT_EQ(0, open_image(m_image_name, &ictx));
 
-  MockImageCtx mock_image_ctx(*ictx);
+  MockJournalImageCtx mock_image_ctx(*ictx);
   MockJournal mock_journal(mock_image_ctx);
   expect_op_work_queue(mock_image_ctx);
 
@@ -715,6 +853,8 @@ TEST_F(TestMockJournal, ReplayOnDiskPostFlushError) {
   ::journal::MockJournaler mock_journaler;
   expect_construct_journaler(mock_journaler);
   expect_init_journaler(mock_journaler, 0);
+  expect_get_journaler_cached_client(mock_journaler, 0);
+  expect_get_journaler_tags(mock_image_ctx, mock_journaler, 0);
   expect_start_replay(
     mock_image_ctx, mock_journaler, {
       std::bind(&invoke_replay_ready, _1),
@@ -729,20 +869,22 @@ TEST_F(TestMockJournal, ReplayOnDiskPostFlushError) {
   expect_stop_replay(mock_journaler);
 
   Context *on_flush = nullptr;
-  EXPECT_CALL(mock_journal_replay, flush(_))
-    .WillOnce(DoAll(SaveArg<0>(&on_flush),
+  EXPECT_CALL(mock_journal_replay, shut_down(false, _))
+    .WillOnce(DoAll(SaveArg<1>(&on_flush),
                     InvokeWithoutArgs(this, &TestMockJournal::wake_up)));
 
   // replay write-to-disk failure should result in replay-restart
   expect_construct_journaler(mock_journaler);
   expect_init_journaler(mock_journaler, 0);
+  expect_get_journaler_cached_client(mock_journaler, 0);
+  expect_get_journaler_tags(mock_image_ctx, mock_journaler, 0);
   expect_start_replay(
     mock_image_ctx, mock_journaler, {
       std::bind(&invoke_replay_complete, _1, 0)
     });
 
   expect_stop_replay(mock_journaler);
-  expect_flush_replay(mock_image_ctx, mock_journal_replay, 0);
+  expect_shut_down_replay(mock_image_ctx, mock_journal_replay, 0);
   expect_start_append(mock_journaler);
 
   C_SaferCond ctx;
@@ -780,7 +922,7 @@ TEST_F(TestMockJournal, EventAndIOCommitOrder) {
   librbd::ImageCtx *ictx;
   ASSERT_EQ(0, open_image(m_image_name, &ictx));
 
-  MockImageCtx mock_image_ctx(*ictx);
+  MockJournalImageCtx mock_image_ctx(*ictx);
   MockJournal mock_journal(mock_image_ctx);
   ::journal::MockJournaler mock_journaler;
   open_journal(mock_image_ctx, mock_journal, mock_journaler);
@@ -820,7 +962,7 @@ TEST_F(TestMockJournal, EventCommitError) {
   librbd::ImageCtx *ictx;
   ASSERT_EQ(0, open_image(m_image_name, &ictx));
 
-  MockImageCtx mock_image_ctx(*ictx);
+  MockJournalImageCtx mock_image_ctx(*ictx);
   MockJournal mock_journal(mock_image_ctx);
   ::journal::MockJournaler mock_journaler;
   open_journal(mock_image_ctx, mock_journal, mock_journaler);
@@ -857,7 +999,7 @@ TEST_F(TestMockJournal, EventCommitErrorWithPendingWriteback) {
   librbd::ImageCtx *ictx;
   ASSERT_EQ(0, open_image(m_image_name, &ictx));
 
-  MockImageCtx mock_image_ctx(*ictx);
+  MockJournalImageCtx mock_image_ctx(*ictx);
   MockJournal mock_journal(mock_image_ctx);
   ::journal::MockJournaler mock_journaler;
   open_journal(mock_image_ctx, mock_journal, mock_journaler);
@@ -895,7 +1037,7 @@ TEST_F(TestMockJournal, IOCommitError) {
   librbd::ImageCtx *ictx;
   ASSERT_EQ(0, open_image(m_image_name, &ictx));
 
-  MockImageCtx mock_image_ctx(*ictx);
+  MockJournalImageCtx mock_image_ctx(*ictx);
   MockJournal mock_journal(mock_image_ctx);
   ::journal::MockJournaler mock_journaler;
   open_journal(mock_image_ctx, mock_journal, mock_journaler);
@@ -914,4 +1056,24 @@ TEST_F(TestMockJournal, IOCommitError) {
   mock_journal.commit_io_event(1U, -EINVAL);
 }
 
+TEST_F(TestMockJournal, FlushCommitPosition) {
+  REQUIRE_FEATURE(RBD_FEATURE_JOURNALING);
+
+  librbd::ImageCtx *ictx;
+  ASSERT_EQ(0, open_image(m_image_name, &ictx));
+
+  MockJournalImageCtx mock_image_ctx(*ictx);
+  MockJournal mock_journal(mock_image_ctx);
+  ::journal::MockJournaler mock_journaler;
+  open_journal(mock_image_ctx, mock_journal, mock_journaler);
+  BOOST_SCOPE_EXIT_ALL(&) {
+    close_journal(mock_journal, mock_journaler);
+  };
+
+  expect_flush_commit_position(mock_journaler);
+  C_SaferCond ctx;
+  mock_journal.flush_commit_position(&ctx);
+  ASSERT_EQ(0, ctx.wait());
+}
+
 } // namespace librbd
diff --git a/src/test/librbd/test_mock_fixture.cc b/src/test/librbd/test_mock_fixture.cc
index f5a2394..4cc940c 100644
--- a/src/test/librbd/test_mock_fixture.cc
+++ b/src/test/librbd/test_mock_fixture.cc
@@ -9,15 +9,18 @@
 // template definitions
 #include "librbd/AsyncRequest.cc"
 #include "librbd/AsyncObjectThrottle.cc"
+#include "librbd/ExclusiveLock.cc"
 #include "librbd/operation/Request.cc"
 
 template class librbd::AsyncRequest<librbd::MockImageCtx>;
 template class librbd::AsyncObjectThrottle<librbd::MockImageCtx>;
+template class librbd::ExclusiveLock<librbd::MockImageCtx>;
 template class librbd::operation::Request<librbd::MockImageCtx>;
 
 using ::testing::_;
 using ::testing::DoDefault;
 using ::testing::Return;
+using ::testing::StrEq;
 using ::testing::WithArg;
 
 TestMockFixture::TestRadosClientPtr TestMockFixture::s_test_rados_client;
@@ -37,6 +40,8 @@ void TestMockFixture::SetUpTestCase() {
 void TestMockFixture::TearDownTestCase() {
   TestFixture::TearDownTestCase();
   librados_test_stub::set_rados_client(s_test_rados_client);
+  s_test_rados_client->put();
+  s_test_rados_client.reset();
 }
 
 void TestMockFixture::SetUp() {
@@ -53,7 +58,7 @@ void TestMockFixture::TearDown() {
 
 void TestMockFixture::expect_unlock_exclusive_lock(librbd::ImageCtx &ictx) {
   EXPECT_CALL(get_mock_io_ctx(ictx.md_ctx),
-              exec(_, _, "lock", "unlock", _, _, _))
+              exec(_, _, StrEq("lock"), StrEq("unlock"), _, _, _))
                 .WillRepeatedly(DoDefault());
 }
 
@@ -63,14 +68,6 @@ void TestMockFixture::expect_op_work_queue(librbd::MockImageCtx &mock_image_ctx)
                   mock_image_ctx.image_ctx->op_work_queue));
 }
 
-librados::MockTestMemIoCtxImpl &TestMockFixture::get_mock_io_ctx(
-    librados::IoCtx &ioctx) {
-  // TODO become friend of IoCtx so that we can cleanly extract io_ctx_impl
-  librados::MockTestMemIoCtxImpl **mock =
-    reinterpret_cast<librados::MockTestMemIoCtxImpl **>(&ioctx);
-  return **mock;
-}
-
 void TestMockFixture::initialize_features(librbd::ImageCtx *ictx,
                                           librbd::MockImageCtx &mock_image_ctx,
                                           librbd::MockExclusiveLock &mock_exclusive_lock,
diff --git a/src/test/librbd/test_mock_fixture.h b/src/test/librbd/test_mock_fixture.h
index ce3e6d5..bd5a2ac 100644
--- a/src/test/librbd/test_mock_fixture.h
+++ b/src/test/librbd/test_mock_fixture.h
@@ -6,6 +6,7 @@
 
 #include "test/librbd/test_fixture.h"
 #include "test/librbd/mock/MockImageCtx.h"
+#include "test/librados_test_stub/LibradosTestStub.h"
 #include "common/WorkQueue.h"
 #include <boost/shared_ptr.hpp>
 #include <gmock/gmock.h>
@@ -69,7 +70,6 @@ public:
   ::testing::NiceMock<librados::MockTestMemRadosClient> &get_mock_rados_client() {
     return *s_mock_rados_client;
   }
-  librados::MockTestMemIoCtxImpl &get_mock_io_ctx(librados::IoCtx &ioctx);
 
   void expect_op_work_queue(librbd::MockImageCtx &mock_image_ctx);
   void expect_unlock_exclusive_lock(librbd::ImageCtx &ictx);
diff --git a/src/test/librgw_file.cc b/src/test/librgw_file.cc
new file mode 100644
index 0000000..5ed0cb4
--- /dev/null
+++ b/src/test/librgw_file.cc
@@ -0,0 +1,292 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+/*
+ * Ceph - scalable distributed file system
+ *
+ * Copyright (C) 2015 Red Hat, Inc.
+ *
+ * This is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software
+ * Foundation.  See file COPYING.
+ *
+ */
+
+#include <stdint.h>
+#include <tuple>
+#include <iostream>
+
+#include "include/rados/librgw.h"
+#include "include/rados/rgw_file.h"
+
+#include "gtest/gtest.h"
+#include "common/ceph_argparse.h"
+#include "common/debug.h"
+#include "global/global_init.h"
+
+#define dout_subsys ceph_subsys_rgw
+
+namespace {
+  librgw_t rgw = nullptr;
+  string uid("testuser");
+  string access_key("");
+  string secret_key("");
+  struct rgw_fs *fs = nullptr;
+  typedef std::tuple<string, uint64_t, struct rgw_file_handle*> fid_type; //in c++2014 can alias...
+  typedef std::tuple<fid_type, std::vector<fid_type>> bucket_type;
+		     
+  std::vector<fid_type> fids1;
+  std::vector<bucket_type> bucket_matrix;
+
+  bool do_getattr = false;
+
+  struct {
+    int argc;
+    char **argv;
+  } saved_args;
+}
+
+TEST(LibRGW, INIT) {
+  int ret = librgw_create(&rgw, saved_args.argc, saved_args.argv);
+  ASSERT_EQ(ret, 0);
+  ASSERT_NE(rgw, nullptr);
+}
+
+TEST(LibRGW, MOUNT) {
+  int ret = rgw_mount(rgw, uid.c_str(), access_key.c_str(), secret_key.c_str(),
+		      &fs, RGW_MOUNT_FLAG_NONE);
+  ASSERT_EQ(ret, 0);
+  ASSERT_NE(fs, nullptr);
+}
+
+TEST(LibRGW, GETATTR_ROOT) {
+  if (do_getattr) {
+    using std::get;
+
+    if (! fs)
+      return;
+
+    struct stat st;
+    int ret = rgw_getattr(fs, fs->root_fh, &st, RGW_GETATTR_FLAG_NONE);
+    ASSERT_EQ(ret, 0);
+  }
+}
+
+extern "C" {
+  static bool r1_cb(const char* name, void *arg, uint64_t offset) {
+    // don't need arg--it would point to fids1
+    fids1.push_back(fid_type(name, offset, nullptr /* handle */));
+    return true; /* XXX ? */
+  }
+}
+
+TEST(LibRGW, LIST_BUCKETS) {
+  /* list buckets via readdir in fs root */
+  using std::get;
+
+  if (! fs)
+    return;
+
+  bool eof = false;
+  uint64_t offset = 0;
+  int ret = rgw_readdir(fs, fs->root_fh, &offset, r1_cb, &fids1, &eof,
+			RGW_READDIR_FLAG_NONE);
+  for (auto& fid : fids1) {
+    std::cout << "fname: " << get<0>(fid) << " fid: " << get<1>(fid)
+	      << std::endl;
+    /* push row for bucket into bucket_matrix */
+    bucket_matrix.push_back(bucket_type(fid, std::vector<fid_type>()));
+  }
+  ASSERT_EQ(ret, 0);
+}
+
+TEST(LibRGW, LOOKUP_BUCKETS) {
+  using std::get;
+
+  if (! fs)
+    return;
+
+  int ret = 0;
+  for (auto& fid_row : bucket_matrix) {
+    auto& fid = get<0>(fid_row);
+    // auto& obj_vector = get<1>(fid_row);
+    struct rgw_file_handle *rgw_fh = nullptr;
+    ret = rgw_lookup(fs, fs->root_fh, get<0>(fid).c_str(), &rgw_fh,
+		    0 /* flags */);
+    ASSERT_EQ(ret, 0);
+    get<2>(fid) = rgw_fh;
+    ASSERT_NE(get<2>(fid), nullptr);
+  }
+}
+
+TEST(LibRGW, GETATTR_BUCKETS) {
+  if (do_getattr) {
+    using std::get;
+
+    if (! fs)
+      return;
+
+    int ret = 0;
+    struct stat st;
+
+    for (auto& fid_row : bucket_matrix) {
+      auto& fid = get<0>(fid_row);
+      struct rgw_file_handle *rgw_fh = get<2>(fid);
+      ret = rgw_getattr(fs, rgw_fh, &st, RGW_GETATTR_FLAG_NONE);
+      ASSERT_EQ(ret, 0);
+    }
+  }
+}
+
+extern "C" {
+  static bool r2_cb(const char* name, void *arg, uint64_t offset) {
+    std::vector<fid_type>& obj_vector = *(static_cast<std::vector<fid_type>*>(arg));
+    obj_vector.push_back(fid_type(name, offset, nullptr));
+    return true; /* XXX ? */
+  }
+}
+
+TEST(LibRGW, LIST_OBJECTS) {
+  /* list objects via readdir, bucketwise */
+  using std::get;
+
+  if (! fs)
+    return;
+
+  for (auto& fid_row : bucket_matrix) {
+    auto& fid = get<0>(fid_row); // bucket
+    std::vector<fid_type>& obj_vector = get<1>(fid_row); // objects in bucket
+    struct rgw_file_handle *bucket_fh = get<2>(fid);
+
+    ldout(g_ceph_context, 0) << __func__ << " readdir on bucket " << get<0>(fid)
+			     << dendl;
+
+    bool eof = false;
+    uint64_t offset = 0;
+    int ret = rgw_readdir(fs, bucket_fh, &offset, r2_cb, &obj_vector, &eof,
+			  RGW_READDIR_FLAG_NONE);
+    for (auto& obj : obj_vector) {
+      std::cout << "fname: " << get<0>(obj) << " fid: " << get<1>(obj)
+		<< std::endl;
+    }
+    ASSERT_EQ(ret, 0);
+  }
+}
+
+extern bool global_stop;
+
+TEST(LibRGW, GETATTR_OBJECTS) {
+  if (do_getattr) {
+    using std::get;
+    struct stat st;
+    int ret;
+
+    global_stop = true;
+
+    for (auto& fid_row : bucket_matrix) {
+      auto& fid = get<0>(fid_row); // bucket
+      std::vector<fid_type>& obj_vector = get<1>(fid_row); // objects in bucket
+      struct rgw_file_handle *bucket_fh = get<2>(fid);
+
+      for (auto& obj : obj_vector) {
+	struct rgw_file_handle *obj_fh = nullptr;
+	std::string object_name = get<0>(obj);
+	ret = rgw_lookup(fs, bucket_fh, get<0>(obj).c_str(), &obj_fh,
+			0 /* flags */);
+	ASSERT_EQ(ret, 0);
+	get<2>(obj) = obj_fh; // stash obj_fh for cleanup
+	ASSERT_NE(get<2>(obj), nullptr);
+	ret = rgw_getattr(fs, obj_fh, &st,
+			  RGW_GETATTR_FLAG_NONE); // now, getattr
+	ASSERT_EQ(ret, 0);
+      }
+    }
+  }
+}
+
+TEST(LibRGW, CLEANUP) {
+  int ret = 0;
+  using std::get;
+
+  /* release file handles */
+  for (auto& fid_row : bucket_matrix) {
+    auto& bucket = get<0>(fid_row); // bucket
+    std::vector<fid_type>& obj_vector = get<1>(fid_row); // objects in bucket
+    for (auto& obj : obj_vector) {
+      struct rgw_file_handle *obj_fh = get<2>(obj);
+      if (obj_fh) {
+	ret = rgw_fh_rele(fs, obj_fh, 0 /* flags */);
+	ASSERT_EQ(ret, 0);
+      }
+    }
+    // now the bucket
+    struct rgw_file_handle *bucket_fh = get<2>(bucket);
+    if (bucket_fh) {
+      ret = rgw_fh_rele(fs, bucket_fh, 0 /* flags */);
+      ASSERT_EQ(ret, 0);
+    }
+  }
+}
+
+TEST(LibRGW, UMOUNT) {
+  if (! fs)
+    return;
+
+  int ret = rgw_umount(fs, RGW_UMOUNT_FLAG_NONE);
+  ASSERT_EQ(ret, 0);
+}
+
+TEST(LibRGW, SHUTDOWN) {
+  librgw_shutdown(rgw);
+}
+
+int main(int argc, char *argv[])
+{
+  char *v{nullptr};
+  string val;
+  vector<const char*> args;
+
+  argv_to_vec(argc, const_cast<const char**>(argv), args);
+  env_to_vec(args);
+
+  v = getenv("AWS_ACCESS_KEY_ID");
+  if (v) {
+    access_key = v;
+  }
+
+  v = getenv("AWS_SECRET_ACCESS_KEY");
+  if (v) {
+    secret_key = v;
+  }
+
+  for (auto arg_iter = args.begin(); arg_iter != args.end();) {
+    if (ceph_argparse_witharg(args, arg_iter, &val, "--access",
+			      (char*) nullptr)) {
+      access_key = val;
+    } else if (ceph_argparse_witharg(args, arg_iter, &val, "--secret",
+				     (char*) nullptr)) {
+      secret_key = val;
+    } else if (ceph_argparse_witharg(args, arg_iter, &val, "--uid",
+				     (char*) nullptr)) {
+      uid = val;
+    } else if (ceph_argparse_flag(args, arg_iter, "--getattr",
+					    (char*) nullptr)) {
+      do_getattr = true;
+    } else {
+      ++arg_iter;
+    }
+  }
+
+  /* dont accidentally run as anonymous */
+  if ((access_key == "") ||
+      (secret_key == "")) {
+    std::cout << argv[0] << " no AWS credentials, exiting" << std::endl;
+    return EPERM;
+  }
+
+  saved_args.argc = argc;
+  saved_args.argv = argv;
+
+  ::testing::InitGoogleTest(&argc, argv);
+  return RUN_ALL_TESTS();
+}
diff --git a/src/test/librgw_file_aw.cc b/src/test/librgw_file_aw.cc
new file mode 100644
index 0000000..2ae73b8
--- /dev/null
+++ b/src/test/librgw_file_aw.cc
@@ -0,0 +1,352 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+/*
+ * Ceph - scalable distributed file system
+ *
+ * Copyright (C) 2015 Red Hat, Inc.
+ *
+ * This is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software
+ * Foundation.  See file COPYING.
+ *
+ */
+
+#include <stdint.h>
+#include <tuple>
+#include <iostream>
+#include <vector>
+#include <map>
+#include <random>
+#include "xxhash.h"
+
+#include "include/rados/librgw.h"
+#include "include/rados/rgw_file.h"
+
+#include "gtest/gtest.h"
+#include "common/ceph_argparse.h"
+#include "common/debug.h"
+#include "global/global_init.h"
+
+#define dout_subsys ceph_subsys_rgw
+
+namespace {
+  librgw_t rgw = nullptr;
+  string uid("testuser");
+  string access_key("");
+  string secret_key("");
+  struct rgw_fs *fs = nullptr;
+
+  bool do_create = false;
+  bool do_delete = false;
+  bool do_verify = false;
+  bool do_hexdump = false;
+
+  string bucket_name = "sorry_dave";
+  string object_name = "jocaml";
+
+  struct rgw_file_handle *bucket_fh = nullptr;
+  struct rgw_file_handle *object_fh = nullptr;
+
+  typedef std::tuple<string,uint64_t, struct rgw_file_handle*> fid_type;
+  std::vector<fid_type> fids;
+
+  std::uniform_int_distribution<uint8_t> uint_dist;
+  std::mt19937 rng;
+
+  constexpr int iovcnt = 16;
+  constexpr int page_size = 65536;
+  constexpr int seed = 8675309;
+
+  struct ZPage
+  {
+    char data[page_size];
+    uint64_t cksum;
+  }; /* ZPage */
+  
+  struct ZPageSet
+  {
+    std::vector<ZPage*> pages;
+    struct iovec* iovs;
+
+    ZPageSet(int n) {
+      pages.reserve(n);
+      iovs = (struct iovec*) calloc(n, sizeof(struct iovec));
+      for (int page_ix = 0; page_ix < n; ++page_ix) {
+	ZPage* p = new ZPage();
+	for (int data_ix = 0; data_ix < page_size; ++data_ix) {
+	  p->data[data_ix] = uint_dist(rng);
+	} // data_ix
+	p->cksum = XXH64(p->data, page_size, seed);
+	pages.emplace_back(p);
+	// and iovs
+	struct iovec* iov = &iovs[page_ix];
+	iov->iov_base = p->data;
+	iov->iov_len = page_size;
+      } // page_ix
+    }
+
+    int size() { return pages.size(); }
+
+    struct iovec* get_iovs() { return iovs; }
+
+    bool operator==(const ZPageSet& rhs) {
+      int n = size();
+      for (int page_ix = 0; page_ix < n; ++page_ix) {
+	ZPage* p1 = pages[page_ix];
+	ZPage* p2 = rhs.pages[page_ix];
+	if (p1->cksum != p2->cksum)
+	  return false;
+      }
+      return true;
+    }
+
+    bool operator==(const rgw_uio* uio) {
+      uint64_t cksum;
+      int vix = 0, off = 0;
+      rgw_vio* vio = &uio->uio_vio[vix];
+      int vio_len = vio->vio_len;
+      char *data;
+
+      for (int ix = 0; ix < iovcnt; ++ix) {
+	ZPage* p1 = pages[ix];
+	data = static_cast<char*>(vio->vio_base) + off;
+	cksum = XXH64(data, page_size, seed);
+
+	if (p1->cksum != cksum) {
+	  int r = memcmp(data, p1->data, page_size);
+	  std::cout << "problem at ix " << ix << " r " << r<< std::endl;
+	  return false;
+	}
+
+	off += page_size;
+	if (off >= vio_len) {
+	  vio = &uio->uio_vio[++vix];
+	  vio_len = vio->vio_len;
+	  off = 0;
+	}
+      }
+      return true;
+    }
+    
+    void cksum() {
+      int n = size();
+      for (int page_ix = 0; page_ix < n; ++page_ix) {
+	ZPage* p = pages[page_ix];
+	p->cksum = XXH64(p->data, page_size, seed);
+      }
+    }
+
+    void reset_iovs() { // VOP_READ and VOP_WRITE update
+      int n = size();
+      for (int page_ix = 0; page_ix < n; ++page_ix) {
+	ZPage* p = pages[page_ix];
+	struct iovec* iov = &iovs[page_ix];
+	iov->iov_base = p->data;
+	iov->iov_len = page_size;
+      }
+    }
+
+    ~ZPageSet() {
+      for (unsigned int ix = 0; ix < pages.size(); ++ix)
+	delete pages[ix];
+      free(iovs);
+    }
+  }; /* ZPageSet */
+
+  ZPageSet zp_set1{iovcnt}; // 1M random data in 16 64K pages
+
+  struct {
+    int argc;
+    char **argv;
+  } saved_args;
+}
+
+TEST(LibRGW, INIT) {
+  int ret = librgw_create(&rgw, saved_args.argc, saved_args.argv);
+  ASSERT_EQ(ret, 0);
+  ASSERT_NE(rgw, nullptr);
+}
+
+TEST(LibRGW, MOUNT) {
+  int ret = rgw_mount(rgw, uid.c_str(), access_key.c_str(), secret_key.c_str(),
+		      &fs, RGW_MOUNT_FLAG_NONE);
+  ASSERT_EQ(ret, 0);
+  ASSERT_NE(fs, nullptr);
+}
+
+TEST(LibRGW, CREATE_BUCKET) {
+  if (do_create) {
+    struct stat st;
+    struct rgw_file_handle *fh;
+    int ret = rgw_mkdir(fs, fs->root_fh, bucket_name.c_str(), 755, &st, &fh,
+			RGW_MKDIR_FLAG_NONE);
+    ASSERT_EQ(ret, 0);
+  }
+}
+
+TEST(LibRGW, LOOKUP_BUCKET) {
+  int ret = rgw_lookup(fs, fs->root_fh, bucket_name.c_str(), &bucket_fh,
+		      RGW_LOOKUP_FLAG_NONE);
+  ASSERT_EQ(ret, 0);
+}
+
+TEST(LibRGW, LOOKUP_OBJECT) {
+  int ret = rgw_lookup(fs, bucket_fh, object_name.c_str(), &object_fh,
+		       RGW_LOOKUP_FLAG_CREATE);
+  ASSERT_EQ(ret, 0);
+}
+
+TEST(LibRGW, OPEN1) {
+  int ret = rgw_open(fs, object_fh, RGW_OPEN_FLAG_NONE);
+  ASSERT_EQ(ret, 0);
+}
+
+TEST(LibRGW, PUT_OBJECT) {
+  size_t nbytes;
+  struct iovec *iovs = zp_set1.get_iovs();
+  off_t offset = 0;
+  for (int ix : {0, 1}) {
+    struct iovec *iov = &iovs[ix];
+    // quick check
+    sprintf(static_cast<char*>(iov->iov_base), "::hi mom (%d)", ix);
+    iov->iov_len = 14;
+    int ret = rgw_write(fs, object_fh, offset, iov->iov_len, &nbytes,
+			iov->iov_base, RGW_WRITE_FLAG_NONE);
+    offset += iov->iov_len;
+    ASSERT_EQ(ret, 0);
+    ASSERT_EQ(nbytes, iov->iov_len);
+  }
+}
+
+TEST(LibRGW, CLOSE1) {
+  int ret = rgw_close(fs, object_fh, RGW_CLOSE_FLAG_NONE);
+  ASSERT_EQ(ret, 0);
+}
+
+TEST(LibRGW, OPEN2) {
+  int ret = rgw_open(fs, object_fh, RGW_OPEN_FLAG_NONE);
+  ASSERT_EQ(ret, 0);
+}
+
+TEST(LibRGW, GET_OBJECT) {
+  size_t nread;
+  off_t offset = 0;
+  struct iovec *iovs = zp_set1.get_iovs();
+  for (int ix : {2 , 3}) {
+    struct iovec *iov = &iovs[ix];
+    int ret = rgw_read(fs, object_fh, offset, iovs[ix-2].iov_len, &nread,
+		       iov->iov_base, RGW_READ_FLAG_NONE);
+    iov->iov_len = nread;
+    offset += iov->iov_len;
+    ASSERT_EQ(ret, 0);
+    ASSERT_EQ(nread, iovs[ix-2].iov_len);
+    std::cout << "read: " << static_cast<char*>(iov->iov_base) << std::endl;
+  }
+}
+
+TEST(LibRGW, CLOSE2) {
+  int ret = rgw_close(fs, object_fh, RGW_CLOSE_FLAG_NONE);
+  ASSERT_EQ(ret, 0);
+}
+
+TEST(LibRGW, STAT_OBJECT) {
+  struct stat st;
+  int ret = rgw_getattr(fs, object_fh, &st, RGW_GETATTR_FLAG_NONE);
+  ASSERT_EQ(ret, 0);
+  dout(15) << "rgw_getattr on " << object_name << " size = "
+	   << st.st_size << dendl;
+}
+
+TEST(LibRGW, DELETE_OBJECT) {
+  if (do_delete) {
+    int ret = rgw_unlink(fs, bucket_fh, object_name.c_str(),
+			 RGW_UNLINK_FLAG_NONE);
+    ASSERT_EQ(ret, 0);
+  }
+}
+
+TEST(LibRGW, CLEANUP) {
+  int ret;
+  if (object_fh) {
+    ret = rgw_fh_rele(fs, object_fh, RGW_FH_RELE_FLAG_NONE);
+    ASSERT_EQ(ret, 0);
+  }
+  ret = rgw_fh_rele(fs, bucket_fh, 0 /* flags */);
+  ASSERT_EQ(ret, 0);
+}
+
+TEST(LibRGW, UMOUNT) {
+  if (! fs)
+    return;
+
+  int ret = rgw_umount(fs, RGW_UMOUNT_FLAG_NONE);
+  ASSERT_EQ(ret, 0);
+}
+
+TEST(LibRGW, SHUTDOWN) {
+  librgw_shutdown(rgw);
+}
+
+int main(int argc, char *argv[])
+{
+  char *v{nullptr};
+  string val;
+  vector<const char*> args;
+
+  argv_to_vec(argc, const_cast<const char**>(argv), args);
+  env_to_vec(args);
+
+  v = getenv("AWS_ACCESS_KEY_ID");
+  if (v) {
+    access_key = v;
+  }
+
+  v = getenv("AWS_SECRET_ACCESS_KEY");
+  if (v) {
+    secret_key = v;
+  }
+
+  for (auto arg_iter = args.begin(); arg_iter != args.end();) {
+    if (ceph_argparse_witharg(args, arg_iter, &val, "--access",
+			      (char*) nullptr)) {
+      access_key = val;
+    } else if (ceph_argparse_witharg(args, arg_iter, &val, "--secret",
+				     (char*) nullptr)) {
+      secret_key = val;
+    } else if (ceph_argparse_witharg(args, arg_iter, &val, "--uid",
+				     (char*) nullptr)) {
+      uid = val;
+    } else if (ceph_argparse_witharg(args, arg_iter, &val, "--bn",
+				     (char*) nullptr)) {
+      bucket_name = val;
+    } else if (ceph_argparse_flag(args, arg_iter, "--verify",
+					    (char*) nullptr)) {
+      do_verify = true;
+    } else if (ceph_argparse_flag(args, arg_iter, "--create",
+					    (char*) nullptr)) {
+      do_create = true;
+    } else if (ceph_argparse_flag(args, arg_iter, "--delete",
+					    (char*) nullptr)) {
+      do_delete = true;
+    } else if (ceph_argparse_flag(args, arg_iter, "--hexdump",
+					    (char*) nullptr)) {
+      do_hexdump = true;
+    } else {
+      ++arg_iter;
+    }
+  }
+
+  /* dont accidentally run as anonymous */
+  if ((access_key == "") ||
+      (secret_key == "")) {
+    std::cout << argv[0] << " no AWS credentials, exiting" << std::endl;
+    return EPERM;
+  }
+
+  saved_args.argc = argc;
+  saved_args.argv = argv;
+
+  ::testing::InitGoogleTest(&argc, argv);
+  return RUN_ALL_TESTS();
+}
diff --git a/src/test/librgw_file_cd.cc b/src/test/librgw_file_cd.cc
new file mode 100644
index 0000000..4ec671f
--- /dev/null
+++ b/src/test/librgw_file_cd.cc
@@ -0,0 +1,182 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+/*
+ * Ceph - scalable distributed file system
+ *
+ * Copyright (C) 2015 Red Hat, Inc.
+ *
+ * This is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software
+ * Foundation.  See file COPYING.
+ *
+ */
+
+#include <stdint.h>
+#include <tuple>
+#include <iostream>
+
+#include "include/rados/librgw.h"
+#include "include/rados/rgw_file.h"
+
+#include "gtest/gtest.h"
+#include "common/ceph_argparse.h"
+#include "common/debug.h"
+#include "global/global_init.h"
+
+#define dout_subsys ceph_subsys_rgw
+
+namespace {
+  librgw_t rgw = nullptr;
+  string uid("testuser");
+  string access_key("");
+  string secret_key("");
+  struct rgw_fs *fs = nullptr;
+
+  bool do_create = false;
+  bool do_delete = false;
+  bool do_multi = false;
+  int multi_cnt = 10;
+
+  string bucket_name = "sorry_dave";
+
+  struct {
+    int argc;
+    char **argv;
+  } saved_args;
+}
+
+TEST(LibRGW, INIT) {
+  int ret = librgw_create(&rgw, saved_args.argc, saved_args.argv);
+  ASSERT_EQ(ret, 0);
+  ASSERT_NE(rgw, nullptr);
+}
+
+TEST(LibRGW, MOUNT) {
+  int ret = rgw_mount(rgw, uid.c_str(), access_key.c_str(), secret_key.c_str(),
+		      &fs, RGW_MOUNT_FLAG_NONE);
+  ASSERT_EQ(ret, 0);
+  ASSERT_NE(fs, nullptr);
+}
+
+TEST(LibRGW, CREATE_BUCKET) {
+  if (do_create) {
+    struct stat st;
+    struct rgw_file_handle *fh;
+    int ret = rgw_mkdir(fs, fs->root_fh, bucket_name.c_str(), 755, &st, &fh,
+			RGW_MKDIR_FLAG_NONE);
+    ASSERT_EQ(ret, 0);
+  }
+}
+
+TEST(LibRGW, DELETE_BUCKET) {
+  if (do_delete) {
+    int ret = rgw_unlink(fs, fs->root_fh, bucket_name.c_str(),
+			 RGW_UNLINK_FLAG_NONE);
+    ASSERT_EQ(ret, 0);
+  }
+}
+
+TEST(LibRGW, CREATE_BUCKET_MULTI) {
+  if (do_multi) {
+    int ret;
+    struct stat st;
+    struct rgw_file_handle *fh;
+    for (int ix = 0; ix < multi_cnt; ++ix) {
+      string bn = bucket_name;
+      bn += to_string(ix);
+      ret = rgw_mkdir(fs, fs->root_fh, bn.c_str(), 755, &st, &fh,
+		      RGW_MKDIR_FLAG_NONE);
+      ASSERT_EQ(ret, 0);
+      std::cout << "created: " << bn << std::endl;
+    }
+  }
+}
+
+TEST(LibRGW, DELETE_BUCKET_MULTI) {
+  if (do_multi) {
+    for (int ix = 0; ix < multi_cnt; ++ix) {
+      string bn = bucket_name;
+      bn += to_string(ix);
+      int ret = rgw_unlink(fs, fs->root_fh, bn.c_str(),
+			   RGW_UNLINK_FLAG_NONE);
+      ASSERT_EQ(ret, 0);
+    }
+  }
+}
+
+TEST(LibRGW, CLEANUP) {
+  // do nothing
+}
+
+TEST(LibRGW, UMOUNT) {
+  if (! fs)
+    return;
+
+  int ret = rgw_umount(fs, RGW_UMOUNT_FLAG_NONE);
+  ASSERT_EQ(ret, 0);
+}
+
+TEST(LibRGW, SHUTDOWN) {
+  librgw_shutdown(rgw);
+}
+
+int main(int argc, char *argv[])
+{
+  char *v{nullptr};
+  string val;
+  vector<const char*> args;
+
+  argv_to_vec(argc, const_cast<const char**>(argv), args);
+  env_to_vec(args);
+
+  v = getenv("AWS_ACCESS_KEY_ID");
+  if (v) {
+    access_key = v;
+  }
+
+  v = getenv("AWS_SECRET_ACCESS_KEY");
+  if (v) {
+    secret_key = v;
+  }
+
+  for (auto arg_iter = args.begin(); arg_iter != args.end();) {
+    if (ceph_argparse_witharg(args, arg_iter, &val, "--access",
+			      (char*) nullptr)) {
+      access_key = val;
+    } else if (ceph_argparse_witharg(args, arg_iter, &val, "--secret",
+				     (char*) nullptr)) {
+      secret_key = val;
+    } else if (ceph_argparse_witharg(args, arg_iter, &val, "--uid",
+				     (char*) nullptr)) {
+      uid = val;
+    } else if (ceph_argparse_witharg(args, arg_iter, &val, "--bn",
+				     (char*) nullptr)) {
+      bucket_name = val;
+    } else if (ceph_argparse_flag(args, arg_iter, "--create",
+					    (char*) nullptr)) {
+      do_create = true;
+    } else if (ceph_argparse_flag(args, arg_iter, "--delete",
+					    (char*) nullptr)) {
+      do_delete = true;
+    } else if (ceph_argparse_flag(args, arg_iter, "--multi",
+					    (char*) nullptr)) {
+      do_multi = true;
+    } else {
+      ++arg_iter;
+    }
+  }
+
+  /* dont accidentally run as anonymous */
+  if ((access_key == "") ||
+      (secret_key == "")) {
+    std::cout << argv[0] << " no AWS credentials, exiting" << std::endl;
+    return EPERM;
+  }
+
+  saved_args.argc = argc;
+  saved_args.argv = argv;
+
+  ::testing::InitGoogleTest(&argc, argv);
+  return RUN_ALL_TESTS();
+}
diff --git a/src/test/librgw_file_gp.cc b/src/test/librgw_file_gp.cc
new file mode 100644
index 0000000..ec70b5d
--- /dev/null
+++ b/src/test/librgw_file_gp.cc
@@ -0,0 +1,484 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+/*
+ * Ceph - scalable distributed file system
+ *
+ * Copyright (C) 2015 Red Hat, Inc.
+ *
+ * This is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software
+ * Foundation.  See file COPYING.
+ *
+ */
+
+#include <stdint.h>
+#include <tuple>
+#include <iostream>
+#include <vector>
+#include <map>
+#include <random>
+#include "xxhash.h"
+
+#include "include/rados/librgw.h"
+#include "include/rados/rgw_file.h"
+
+#include "gtest/gtest.h"
+#include "common/ceph_argparse.h"
+#include "common/debug.h"
+#include "global/global_init.h"
+
+#define dout_subsys ceph_subsys_rgw
+
+namespace {
+  librgw_t rgw = nullptr;
+  string uid("testuser");
+  string access_key("");
+  string secret_key("");
+  struct rgw_fs *fs = nullptr;
+
+  bool do_pre_list = false;
+  bool do_put = false;
+  bool do_bulk = false;
+  bool do_writev = false;
+  bool do_readv = false;
+  bool do_verify = false;
+  bool do_get = false;
+  bool do_delete = false;
+  bool do_stat = false; // stat objects (not buckets)
+  bool do_hexdump = false;
+
+  bool object_open = false;
+
+  string bucket_name = "sorry_dave";
+  string object_name = "jocaml";
+
+  struct rgw_file_handle *bucket_fh = nullptr;
+  struct rgw_file_handle *object_fh = nullptr;
+
+  typedef std::tuple<string,uint64_t, struct rgw_file_handle*> fid_type;
+  std::vector<fid_type> fids;
+
+  std::uniform_int_distribution<uint8_t> uint_dist;
+  std::mt19937 rng;
+
+  constexpr int iovcnt = 16;
+  constexpr int page_size = 65536;
+  constexpr int seed = 8675309;
+
+  struct ZPage
+  {
+    char data[page_size];
+    uint64_t cksum;
+  }; /* ZPage */
+  
+  struct ZPageSet
+  {
+    std::vector<ZPage*> pages;
+    struct iovec* iovs;
+
+    ZPageSet(int n) {
+      pages.reserve(n);
+      iovs = (struct iovec*) calloc(n, sizeof(struct iovec));
+      for (int page_ix = 0; page_ix < n; ++page_ix) {
+	ZPage* p = new ZPage();
+	for (int data_ix = 0; data_ix < page_size; ++data_ix) {
+	  p->data[data_ix] = uint_dist(rng);
+	} // data_ix
+	p->cksum = XXH64(p->data, page_size, seed);
+	pages.emplace_back(p);
+	// and iovs
+	struct iovec* iov = &iovs[page_ix];
+	iov->iov_base = p->data;
+	iov->iov_len = page_size;
+      } // page_ix
+    }
+
+    int size() { return pages.size(); }
+
+    struct iovec* get_iovs() { return iovs; }
+
+    bool operator==(const ZPageSet& rhs) {
+      int n = size();
+      for (int page_ix = 0; page_ix < n; ++page_ix) {
+	ZPage* p1 = pages[page_ix];
+	ZPage* p2 = rhs.pages[page_ix];
+	if (p1->cksum != p2->cksum)
+	  return false;
+      }
+      return true;
+    }
+
+    bool operator==(const rgw_uio* uio) {
+      uint64_t cksum;
+      int vix = 0, off = 0;
+      rgw_vio* vio = &uio->uio_vio[vix];
+      int vio_len = vio->vio_len;
+      char *data;
+
+      for (int ix = 0; ix < iovcnt; ++ix) {
+	ZPage* p1 = pages[ix];
+	data = static_cast<char*>(vio->vio_base) + off;
+	cksum = XXH64(data, page_size, seed);
+
+	if (p1->cksum != cksum) {
+	  int r = memcmp(data, p1->data, page_size);
+	  std::cout << "problem at ix " << ix << " r " << r<< std::endl;
+	  return false;
+	}
+
+	off += page_size;
+	if (off >= vio_len) {
+	  vio = &uio->uio_vio[++vix];
+	  vio_len = vio->vio_len;
+	  off = 0;
+	}
+      }
+      return true;
+    }
+    
+    void cksum() {
+      int n = size();
+      for (int page_ix = 0; page_ix < n; ++page_ix) {
+	ZPage* p = pages[page_ix];
+	p->cksum = XXH64(p->data, page_size, seed);
+      }
+    }
+
+    void reset_iovs() { // VOP_READ and VOP_WRITE update
+      int n = size();
+      for (int page_ix = 0; page_ix < n; ++page_ix) {
+	ZPage* p = pages[page_ix];
+	struct iovec* iov = &iovs[page_ix];
+	iov->iov_base = p->data;
+	iov->iov_len = page_size;
+      }
+    }
+
+    ~ZPageSet() {
+      for (unsigned int ix = 0; ix < pages.size(); ++ix)
+	delete pages[ix];
+      free(iovs);
+    }
+  }; /* ZPageSet */
+
+  rgw_uio uio[1];
+  ZPageSet zp_set1{iovcnt}; // 1M random data in 16 64K pages
+
+  struct {
+    int argc;
+    char **argv;
+  } saved_args;
+}
+
+TEST(LibRGW, INIT) {
+  int ret = librgw_create(&rgw, saved_args.argc, saved_args.argv);
+  ASSERT_EQ(ret, 0);
+  ASSERT_NE(rgw, nullptr);
+}
+
+TEST(LibRGW, MOUNT) {
+  int ret = rgw_mount(rgw, uid.c_str(), access_key.c_str(), secret_key.c_str(),
+		      &fs, RGW_MOUNT_FLAG_NONE);
+  ASSERT_EQ(ret, 0);
+  ASSERT_NE(fs, nullptr);
+}
+
+TEST(LibRGW, LOOKUP_BUCKET) {
+  int ret = rgw_lookup(fs, fs->root_fh, bucket_name.c_str(), &bucket_fh,
+		       RGW_LOOKUP_FLAG_NONE);
+  ASSERT_EQ(ret, 0);
+}
+
+extern "C" {
+  static bool r2_cb(const char* name, void *arg, uint64_t offset) {
+    // don't need arg--it would point to fids
+    fids.push_back(fid_type(name, offset, nullptr));
+    return true; /* XXX ? */
+  }
+}
+
+TEST(LibRGW, LIST_OBJECTS) {
+  if (do_pre_list) {
+    /* list objects via readdir, bucketwise */
+    using std::get;
+
+    ldout(g_ceph_context, 0) << __func__ << " readdir on bucket "
+			     << bucket_name << dendl;
+    bool eof = false;
+    uint64_t offset = 0;
+    int ret = rgw_readdir(fs, bucket_fh, &offset, r2_cb, &fids,
+			  &eof, RGW_READDIR_FLAG_NONE);
+    for (auto& fid : fids) {
+      std::cout << "fname: " << get<0>(fid) << " fid: " << get<1>(fid)
+		<< std::endl;
+    }
+    ASSERT_EQ(ret, 0);
+  }
+}
+
+TEST(LibRGW, LOOKUP_OBJECT) {
+  if (do_get || do_stat || do_put || do_bulk || do_readv || do_writev) {
+    int ret = rgw_lookup(fs, bucket_fh, object_name.c_str(), &object_fh,
+			RGW_LOOKUP_FLAG_CREATE);
+    ASSERT_EQ(ret, 0);
+  }
+}
+
+TEST(LibRGW, OBJ_OPEN) {
+  if (do_get || do_put || do_readv || do_writev) {
+    int ret = rgw_open(fs, object_fh, 0 /* flags */);
+    ASSERT_EQ(ret, 0);
+    object_open = true;
+  }
+}
+
+TEST(LibRGW, PUT_OBJECT) {
+  if (do_put) {
+    size_t nbytes;
+    string data = "hi mom"; // fix this
+    int ret = rgw_write(fs, object_fh, 0, data.length(), &nbytes,
+			(void*) data.c_str(), RGW_WRITE_FLAG_NONE);
+    ASSERT_EQ(ret, 0);
+    ASSERT_EQ(nbytes, data.length());
+  }
+}
+
+TEST(LibRGW, GET_OBJECT) {
+  if (do_get) {
+    char sbuf[512];
+    memset(sbuf, 0, 512);
+    size_t nread;
+    int ret = rgw_read(fs, object_fh, 0 /* off */, 512 /* len */, &nread, sbuf,
+		       RGW_READ_FLAG_NONE);
+    ASSERT_EQ(ret, 0);
+    buffer::list bl;
+    bl.push_back(buffer::create_static(nread, sbuf));
+    if (do_hexdump) {
+      dout(15) << "";
+      bl.hexdump(*_dout);
+      *_dout << dendl;
+    }
+  }
+}
+
+TEST(LibRGW, STAT_OBJECT) {
+  if (do_stat) {
+    struct stat st;
+    int ret = rgw_getattr(fs, object_fh, &st, RGW_GETATTR_FLAG_NONE);
+    ASSERT_EQ(ret, 0);
+    dout(15) << "rgw_getattr on " << object_name << " size = "
+	     << st.st_size << dendl;
+  }
+}
+
+TEST(LibRGW, WRITE_READ_VERIFY)
+{
+  if (do_bulk && do_put) {
+    ZPageSet zp_set1{iovcnt}; // 1M random data in 16 64K pages
+    struct iovec *iovs = zp_set1.get_iovs();
+
+    /* read after write POSIX-style */
+    size_t nbytes, off = 0;
+    for (int ix = 0; ix < 16; ++ix, off += page_size) {
+      struct iovec *iov = &iovs[ix];
+      int ret = rgw_write(fs, object_fh, off, page_size, &nbytes,
+			  iov->iov_base, RGW_WRITE_FLAG_NONE);
+      ASSERT_EQ(ret, 0);
+      ASSERT_EQ(nbytes, size_t(page_size));
+    }
+    zp_set1.reset_iovs();
+  }
+}
+
+/* "functions that call alloca are not inlined"
+ * --alexandre oliva
+ * http://gcc.gnu.org/ml/gcc-help/2004-04/msg00158.html
+ */
+#define alloca_uio()				\
+  do {\
+    int uiosz = sizeof(rgw_uio) + iovcnt*sizeof(rgw_vio);		\
+    uio = static_cast<rgw_uio*>(alloca(uiosz));				\
+    memset(uio, 0, uiosz);						\
+    uio->uio_vio = reinterpret_cast<rgw_vio*>(uio+sizeof(rgw_uio));	\
+  } while (0);								\
+
+TEST(LibRGW, WRITEV)
+{
+  if (do_writev) {
+    rgw_uio* uio;
+    struct iovec *iovs = zp_set1.get_iovs();
+    alloca_uio();
+    ASSERT_NE(uio, nullptr);
+
+    for (int ix = 0; ix < iovcnt; ++ix) {
+      struct iovec *iov = &iovs[ix];
+      rgw_vio *vio = &(uio->uio_vio[ix]);
+      vio->vio_base = iov->iov_base;
+      vio->vio_len = iov->iov_len;
+      vio->vio_u1 = iov; // private data
+    }
+    uio->uio_cnt = iovcnt;
+    uio->uio_offset = iovcnt * page_size;
+
+    int ret = rgw_writev(fs, object_fh, uio, RGW_WRITE_FLAG_NONE);
+    ASSERT_EQ(ret, 0);
+  }
+}
+
+TEST(LibRGW, READV)
+{
+  if (do_readv) {
+    memset(uio, 0, sizeof(rgw_uio));
+    uio->uio_offset = 0; // ok, it was already 0
+    uio->uio_resid = UINT64_MAX;
+    int ret = rgw_readv(fs, object_fh, uio, RGW_READ_FLAG_NONE);
+    ASSERT_EQ(ret, 0);
+    buffer::list bl;
+    for (unsigned int ix = 0; ix < uio->uio_cnt; ++ix) {
+      rgw_vio *vio = &(uio->uio_vio[ix]);
+      bl.push_back(
+	buffer::create_static(vio->vio_len,
+			      static_cast<char*>(vio->vio_base)));
+    }
+
+    /* length check */
+    ASSERT_EQ(uint32_t{bl.length()}, uint32_t{iovcnt*page_size});
+
+    if (do_hexdump) {
+      dout(15) << "";
+      bl.hexdump(*_dout);
+      *_dout << dendl;
+    }
+  }
+}
+
+TEST(LibRGW, READV_AFTER_WRITEV)
+{
+  /* checksum data */
+  if (do_readv && do_writev && do_verify) {
+    ASSERT_TRUE(zp_set1 == uio);
+  }
+}
+
+TEST(LibRGW, DELETE_OBJECT) {
+  if (do_delete) {
+    int ret = rgw_unlink(fs, bucket_fh, object_name.c_str(),
+			 RGW_UNLINK_FLAG_NONE);
+    ASSERT_EQ(ret, 0);
+  }
+}
+
+TEST(LibRGW, CLEANUP) {
+  if (do_readv) {
+    // release resources
+    ASSERT_NE(uio->uio_rele, nullptr);
+    if (uio->uio_rele) {
+      uio->uio_rele(uio, RGW_UIO_NONE);
+    }
+  }
+  int ret;
+  if (object_open) {
+    ret = rgw_close(fs, object_fh, RGW_CLOSE_FLAG_NONE);
+    ASSERT_EQ(ret, 0);
+  }
+  if (object_fh) {
+    ret = rgw_fh_rele(fs, object_fh, 0 /* flags */);
+    ASSERT_EQ(ret, 0);
+  }
+  ret = rgw_fh_rele(fs, bucket_fh, 0 /* flags */);
+  ASSERT_EQ(ret, 0);
+}
+
+TEST(LibRGW, UMOUNT) {
+  if (! fs)
+    return;
+
+  int ret = rgw_umount(fs, RGW_UMOUNT_FLAG_NONE);
+  ASSERT_EQ(ret, 0);
+}
+
+TEST(LibRGW, SHUTDOWN) {
+  librgw_shutdown(rgw);
+}
+
+int main(int argc, char *argv[])
+{
+  char *v{nullptr};
+  string val;
+  vector<const char*> args;
+
+  argv_to_vec(argc, const_cast<const char**>(argv), args);
+  env_to_vec(args);
+
+  v = getenv("AWS_ACCESS_KEY_ID");
+  if (v) {
+    access_key = v;
+  }
+
+  v = getenv("AWS_SECRET_ACCESS_KEY");
+  if (v) {
+    secret_key = v;
+  }
+
+  for (auto arg_iter = args.begin(); arg_iter != args.end();) {
+    if (ceph_argparse_witharg(args, arg_iter, &val, "--access",
+			      (char*) nullptr)) {
+      access_key = val;
+    } else if (ceph_argparse_witharg(args, arg_iter, &val, "--secret",
+				     (char*) nullptr)) {
+      secret_key = val;
+    } else if (ceph_argparse_witharg(args, arg_iter, &val, "--uid",
+				     (char*) nullptr)) {
+      uid = val;
+    } else if (ceph_argparse_witharg(args, arg_iter, &val, "--bn",
+				     (char*) nullptr)) {
+      bucket_name = val;
+    } else if (ceph_argparse_flag(args, arg_iter, "--get",
+					    (char*) nullptr)) {
+      do_get = true;
+    } else if (ceph_argparse_flag(args, arg_iter, "--stat",
+					    (char*) nullptr)) {
+      do_stat = true;
+    } else if (ceph_argparse_flag(args, arg_iter, "--put",
+					    (char*) nullptr)) {
+      do_put = true;
+    } else if (ceph_argparse_flag(args, arg_iter, "--bulk",
+					    (char*) nullptr)) {
+      do_bulk = true;
+    } else if (ceph_argparse_flag(args, arg_iter, "--writev",
+					    (char*) nullptr)) {
+      do_writev = true;
+    } else if (ceph_argparse_flag(args, arg_iter, "--readv",
+					    (char*) nullptr)) {
+      do_readv = true;
+    } else if (ceph_argparse_flag(args, arg_iter, "--verify",
+					    (char*) nullptr)) {
+      do_verify = true;
+    } else if (ceph_argparse_flag(args, arg_iter, "--delete",
+					    (char*) nullptr)) {
+      do_delete = true;
+    } else if (ceph_argparse_flag(args, arg_iter, "--prelist",
+					    (char*) nullptr)) {
+      do_pre_list = true;
+    } else if (ceph_argparse_flag(args, arg_iter, "--hexdump",
+					    (char*) nullptr)) {
+      do_hexdump = true;
+    } else {
+      ++arg_iter;
+    }
+  }
+
+  /* dont accidentally run as anonymous */
+  if ((access_key == "") ||
+      (secret_key == "")) {
+    std::cout << argv[0] << " no AWS credentials, exiting" << std::endl;
+    return EPERM;
+  }
+
+  saved_args.argc = argc;
+  saved_args.argv = argv;
+
+  ::testing::InitGoogleTest(&argc, argv);
+  return RUN_ALL_TESTS();
+}
diff --git a/src/test/librgw_file_nfsns.cc b/src/test/librgw_file_nfsns.cc
new file mode 100644
index 0000000..49f0ff5
--- /dev/null
+++ b/src/test/librgw_file_nfsns.cc
@@ -0,0 +1,1019 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+/*
+ * Ceph - scalable distributed file system
+ *
+ * Copyright (C) 2015 Red Hat, Inc.
+ *
+ * This is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software
+ * Foundation.  See file COPYING.
+ *
+ */
+
+#include <stdint.h>
+#include <tuple>
+#include <iostream>
+#include <fstream>
+#include <stack>
+
+#include "include/rados/librgw.h"
+#include "include/rados/rgw_file.h"
+#include "rgw/rgw_file.h"
+#include "rgw/rgw_lib_frontend.h" // direct requests
+
+#include "gtest/gtest.h"
+#include "common/ceph_argparse.h"
+#include "common/debug.h"
+#include "global/global_init.h"
+#include "include/assert.h"
+
+#define dout_subsys ceph_subsys_rgw
+
+namespace {
+
+  using namespace rgw;
+  using std::get;
+  using std::string;
+
+  librgw_t rgw_h = nullptr;
+  string uid("testuser");
+  string access_key("");
+  string secret_key("");
+  struct rgw_fs *fs = nullptr;
+  CephContext* cct = nullptr;
+
+  string bucket_name("nfsroot");
+  string dirs1_bucket_name("bdirs1");
+  string readf_name("toyland");
+  string readf_out_name("rgwlib_readf.out");
+  std::string writef_name{"bigbird"};
+
+  int n_dirs1_dirs = 3;
+  int n_dirs1_objs = 2;
+
+  class obj_rec
+  {
+  public:
+    string name;
+    struct rgw_file_handle* fh;
+    struct rgw_file_handle* parent_fh;
+    RGWFileHandle* rgw_fh; // alias into fh
+
+    struct state {
+      bool readdir;
+      state() : readdir(false) {}
+    } state;
+
+    obj_rec(string _name, struct rgw_file_handle* _fh,
+	    struct rgw_file_handle* _parent_fh, RGWFileHandle* _rgw_fh)
+      : name(std::move(_name)), fh(_fh), parent_fh(_parent_fh),
+	rgw_fh(_rgw_fh) {}
+
+    void sync() {
+      if (fh)
+	rgw_fh = get_rgwfh(fh);
+    }
+
+    friend ostream& operator<<(ostream& os, const obj_rec& rec);
+  };
+
+  ostream& operator<<(ostream& os, const obj_rec& rec)
+  {
+    RGWFileHandle* rgw_fh = rec.rgw_fh;
+    if (rgw_fh) {
+      const char* type = rgw_fh->is_dir() ? "DIR " : "FILE ";
+      os << rec.rgw_fh->full_object_name()
+	 << " (" << rec.rgw_fh->object_name() << "): "
+	 << type;
+    }
+    return os;
+  }
+  
+  std::stack<obj_rec> obj_stack;
+  std::deque<obj_rec> cleanup_queue;
+
+  typedef std::vector<obj_rec> obj_vec;
+  typedef std::tuple<obj_rec, obj_vec> dirs1_rec;
+  typedef std::vector<dirs1_rec> dirs1_vec;
+
+  dirs1_vec dirs_vec;
+
+  struct obj_rec_st
+  {
+    const obj_rec& obj;
+    const struct stat& st;
+
+    obj_rec_st(const obj_rec& _obj, const struct stat& _st)
+      : obj(_obj), st(_st) {}
+  };
+
+  ostream& operator<<(ostream& os, const obj_rec_st& rec)
+  {
+    RGWFileHandle* rgw_fh = rec.obj.rgw_fh;
+    if (rgw_fh) {
+      const char* type = rgw_fh->is_dir() ? "DIR " : "FILE ";
+      os << rgw_fh->full_object_name()
+	 << " (" << rgw_fh->object_name() << "): "
+	 << type;
+      const struct stat& st = rec.st;
+      switch(uint8_t(rgw_fh->is_dir())) {
+      case 1:
+	os << " mode: " << st.st_mode;
+	os << " nlinks: " << st.st_nlink;
+	break;
+      case 0:
+      default:
+	os << " mode: " << st.st_mode;
+	os << " size: " << st.st_size;
+	// xxx
+	break;
+      }
+    }
+    return os;
+  }
+
+  bool do_hier1 = false;
+  bool do_dirs1 = false;
+  bool do_readf = false;
+  bool do_writef = false;
+  bool do_marker1 = false;
+  bool do_create = false;
+  bool do_delete = false;
+  bool do_rename = false;
+  bool verbose = false;
+
+  string marker_dir("nfs_marker");
+  struct rgw_file_handle *bucket_fh = nullptr;
+  struct rgw_file_handle *marker_fh;
+  static constexpr int marker_nobjs = 2*1024;
+  std::deque<obj_rec> marker_objs;
+
+  using dirent_t = std::tuple<std::string, uint64_t>;
+  struct dirent_vec
+  {
+    std::vector<dirent_t> obj_names;
+    uint32_t count;
+    dirent_vec() : count(0) {}
+  };
+
+  obj_rec dirs1_b{dirs1_bucket_name, nullptr, nullptr, nullptr};
+
+  dirs1_vec renames_vec;
+
+  struct {
+    int argc;
+    char **argv;
+  } saved_args;
+}
+
+TEST(LibRGW, INIT) {
+  int ret = librgw_create(&rgw_h, saved_args.argc, saved_args.argv);
+  ASSERT_EQ(ret, 0);
+  ASSERT_NE(rgw_h, nullptr);
+}
+
+TEST(LibRGW, MOUNT) {
+  int ret = rgw_mount(rgw_h, uid.c_str(), access_key.c_str(),
+		      secret_key.c_str(), &fs, RGW_MOUNT_FLAG_NONE);
+  ASSERT_EQ(ret, 0);
+  ASSERT_NE(fs, nullptr);
+
+  cct = static_cast<RGWLibFS*>(fs->fs_private)->get_context();
+}
+
+TEST(LibRGW, SETUP_HIER1)
+{
+  if (do_hier1) {
+    (void) rgw_lookup(fs, fs->root_fh, bucket_name.c_str(), &bucket_fh,
+		      RGW_LOOKUP_FLAG_NONE);
+    if (! bucket_fh) {
+      if (do_create) {
+	struct stat st;
+	int rc = rgw_mkdir(fs, fs->root_fh, bucket_name.c_str(), 755, &st,
+			   &bucket_fh, RGW_MKDIR_FLAG_NONE);
+	ASSERT_EQ(rc, 0);
+      }
+    }
+
+    ASSERT_NE(bucket_fh, nullptr);
+
+    if (do_create) {
+      /* create objects directly */
+      std::vector<std::string> obj_names =
+	{"foo/bar/baz/quux",
+	 "foo/f1",
+	 "foo/f2",
+	 "foo/bar/f1",
+	 "foo/bar/d1/",
+	 "foo/bar/baz/hungry",
+	 "foo/bar/baz/hungry/",
+	 "foo/bar/baz/momma",
+	 "foo/bar/baz/bear/",
+	 "foo/bar/baz/sasquatch",
+	 "foo/bar/baz/sasquatch/",
+	 "foo/bar/baz/frobozz"};
+
+      buffer::list bl; // empty object
+      RGWLibFS *fs_private = static_cast<RGWLibFS*>(fs->fs_private);
+
+      for (const auto& obj_name : obj_names) {
+	if (verbose) {
+	  std::cout << "creating: " << bucket_name << ":" << obj_name
+		    << std::endl;
+	}
+	RGWPutObjRequest req(cct, fs_private->get_user(), bucket_name, obj_name,
+			    bl);
+	int rc = rgwlib.get_fe()->execute_req(&req);
+	int rc2 = req.get_ret();
+	ASSERT_EQ(rc, 0);
+	ASSERT_EQ(rc2, 0);
+      }
+    }
+  }
+}
+
+TEST(LibRGW, SETUP_DIRS1) {
+  if (do_dirs1) {
+    int rc;
+    struct stat st;
+
+    dirs1_b.parent_fh = fs->root_fh;
+
+    (void) rgw_lookup(fs, dirs1_b.parent_fh, dirs1_bucket_name.c_str(),
+		      &dirs1_b.fh, RGW_LOOKUP_FLAG_NONE);
+
+    if (! dirs1_b.fh) {
+      if (do_create) {
+	rc = rgw_mkdir(fs, dirs1_b.parent_fh, dirs1_b.name.c_str(), 755, &st,
+		       &dirs1_b.fh, RGW_MKDIR_FLAG_NONE);
+	ASSERT_EQ(rc, 0);
+      }
+    }
+    dirs1_b.sync();
+
+    /* make top-level dirs */
+    int d_ix;
+    obj_vec ovec;
+    for (d_ix = 0; d_ix < n_dirs1_dirs; ++d_ix) {
+      std::string dname{"dir_"};
+      dname += to_string(d_ix);
+      obj_rec dir{dname, nullptr, dirs1_b.fh, nullptr};
+      ovec.clear();
+
+      (void) rgw_lookup(fs, dir.parent_fh, dir.name.c_str(), &dir.fh,
+			RGW_LOOKUP_FLAG_NONE);
+      if (! dir.fh) {
+	if (do_create) {
+	  rc = rgw_mkdir(fs, dir.parent_fh, dir.name.c_str(), 755, &st,
+			 &dir.fh, RGW_MKDIR_FLAG_NONE);
+	  ASSERT_EQ(rc, 0);
+	}
+      }
+
+      ASSERT_NE(dir.fh, nullptr);
+      dir.sync();
+      ASSERT_NE(dir.rgw_fh, nullptr);
+      ASSERT_TRUE(dir.rgw_fh->is_dir());
+
+      int f_ix;
+      for (f_ix = 0; f_ix < n_dirs1_objs; ++f_ix) {
+	/* child dir */
+	std::string sdname{"sdir_"};
+	sdname += to_string(f_ix);
+	obj_rec sdir{sdname, nullptr, dir.fh, nullptr};
+
+	(void) rgw_lookup(fs, sdir.parent_fh, sdir.name.c_str(), &sdir.fh,
+			  RGW_LOOKUP_FLAG_NONE);
+
+	if (! sdir.fh) {
+	  if (do_create) {
+	    rc = rgw_mkdir(fs, sdir.parent_fh, sdir.name.c_str(), 755,
+			   &st, &sdir.fh, RGW_MKDIR_FLAG_NONE);
+	    ASSERT_EQ(rc, 0);
+	  }
+	}
+
+	ASSERT_NE(sdir.fh, nullptr); // suppress !lookup && !create case
+
+	sdir.sync();
+	ASSERT_TRUE(sdir.rgw_fh->is_dir());
+	ovec.push_back(sdir);
+
+	/* child file */
+	std::string sfname{"sfile_"};
+
+	sfname += to_string(f_ix);
+	obj_rec sf{sfname, nullptr, dir.fh, nullptr};
+
+	(void) rgw_lookup(fs, sf.parent_fh, sf.name.c_str(), &sf.fh,
+			  RGW_LOOKUP_FLAG_NONE);
+
+	if (! sf.fh) {
+	  if (do_create) {
+	    /* make a new file object (the hard way) */
+	    rc = rgw_lookup(fs, sf.parent_fh, sf.name.c_str(), &sf.fh,
+			    RGW_LOOKUP_FLAG_CREATE);
+	    ASSERT_EQ(rc, 0);
+	    sf.sync();
+	    ASSERT_TRUE(sf.rgw_fh->is_file());
+	    /* open handle */
+	    rc = rgw_open(fs, sf.fh, 0 /* flags */);
+	    ASSERT_EQ(rc, 0);
+	    ASSERT_TRUE(sf.rgw_fh->is_open());
+	    /* stage seq write */
+	    size_t nbytes;
+	    string data = "data for " + sf.name;
+	    rc = rgw_write(fs, sf.fh, 0, data.length(), &nbytes,
+			   (void*) data.c_str(), RGW_WRITE_FLAG_NONE);
+	    ASSERT_EQ(rc, 0);
+	    ASSERT_EQ(nbytes, data.length());
+	    /* commit write transaction */
+	    rc = rgw_close(fs, sf.fh, 0 /* flags */);
+	    ASSERT_EQ(rc, 0);
+	  }
+	} else {
+	  sf.sync();
+	  ASSERT_TRUE(sf.rgw_fh->is_file());
+	}
+	
+	if (sf.fh)
+	  ovec.push_back(sf);
+      }
+      dirs_vec.push_back(dirs1_rec{dir, ovec});
+    }
+  } /* dirs1 top-level !exist */
+}
+
+TEST(LibRGW, RGW_CREATE_DIRS1) {
+  /* verify rgw_create (create [empty] file objects the easy way) */
+  if (do_dirs1) {
+    if (do_create) {
+      int rc;
+      struct stat st;
+      for (auto& dirs_rec : dirs_vec) {
+	/* create 1 more file in each sdir */
+	obj_rec& dir = get<0>(dirs_rec);
+	std::string sfname{"sfile_" + to_string(n_dirs1_objs)};
+	obj_rec sf{sfname, nullptr, dir.fh, nullptr};
+	(void) rgw_lookup(fs, sf.parent_fh, sf.name.c_str(), &sf.fh,
+			  RGW_LOOKUP_FLAG_NONE);
+	if (! sf.fh) {
+	  rc = rgw_create(fs, sf.parent_fh, sf.name.c_str(), 644, &st, &sf.fh,
+			  RGW_CREATE_FLAG_NONE);
+	  ASSERT_EQ(rc, 0);
+	}
+	sf.sync();
+      }
+      n_dirs1_objs++;
+    }
+  }
+}
+
+TEST(LibRGW, RGW_SETUP_RENAME1) {
+  /* verify rgw_create (create [empty] file objects the easy way) */
+  if (do_rename) {
+    int rc;
+    struct stat st;
+    obj_vec ovec;
+    for (int b_ix : {0, 1}) {
+      std::string bname{"brename_" + to_string(b_ix)};
+      obj_rec brec{bname, nullptr, nullptr, nullptr};
+      (void) rgw_lookup(fs, fs->root_fh, brec.name.c_str(), &brec.fh,
+			RGW_LOOKUP_FLAG_NONE);
+      if (! brec.fh) {
+	if (do_create) {
+	  struct stat st;
+	  int rc = rgw_mkdir(fs, fs->root_fh, brec.name.c_str(), 755, &st,
+			     &brec.fh, RGW_MKDIR_FLAG_NONE);
+	  ASSERT_EQ(rc, 0);
+	}
+      }
+      ASSERT_NE(brec.fh, nullptr);
+      brec.sync();
+      for (int f_ix : {0, 1}) {
+	std::string rfname{"rfile_"};
+	rfname += to_string(f_ix);
+	obj_rec rf{rfname, nullptr, brec.fh, nullptr};
+	(void) rgw_lookup(fs, rf.parent_fh, rf.name.c_str(), &rf.fh,
+			  RGW_LOOKUP_FLAG_NONE);
+	if (! rf.fh) {
+	  rc = rgw_create(fs, rf.parent_fh, rf.name.c_str(), 644, &st, &rf.fh,
+			  RGW_CREATE_FLAG_NONE);
+	  ASSERT_EQ(rc, 0);
+	}
+	rf.sync();
+	ovec.push_back(rf);
+      }
+      renames_vec.push_back(dirs1_rec{brec, ovec});
+      ovec.clear();
+    } /* b_ix */
+  }
+}
+
+TEST(LibRGW, RGW_INTRABUCKET_RENAME1) {
+  /* rgw_rename a file within a bucket */
+  if (do_rename) {
+    int rc;
+    obj_rec& bdir0 = get<0>(renames_vec[0]);
+    obj_rec& src_obj = get<1>(renames_vec[0])[0];
+    std::string rfname{"rfile_r0"};
+    if (verbose) {
+      std::cout << "rename file " << src_obj.name << " to "
+		<< rfname << " (bucket " << bdir0.name << ")"
+		<< std::endl;
+    }
+    rc = rgw_rename(fs, bdir0.fh, src_obj.name.c_str(), bdir0.fh,
+		    rfname.c_str(), RGW_RENAME_FLAG_NONE);
+    ASSERT_EQ(rc, 0);
+  }
+}
+
+TEST(LibRGW, RGW_CROSSBUCKET_RENAME1) {
+  /* rgw_rename a file within a bucket */
+  if (do_rename) {
+    int rc;
+    obj_rec& bdir0 = get<0>(renames_vec[0]);
+    obj_rec& bdir1 = get<0>(renames_vec[1]);
+    obj_rec& src_obj = get<1>(renames_vec[0])[1];
+    std::string rfname{"rfile_rhilldog"};
+    if (verbose) {
+      std::cout << "rename file " << src_obj.name
+		<< " (bucket " << bdir0.name << ") to "
+		<< rfname << " (bucket " << bdir1.name << ")"
+		<< std::endl;
+    }
+    rc = rgw_rename(fs, bdir0.fh, src_obj.name.c_str(), bdir1.fh,
+		    rfname.c_str(), RGW_RENAME_FLAG_NONE);
+    ASSERT_EQ(rc, 0);
+  }
+}
+
+TEST(LibRGW, BAD_DELETES_DIRS1) {
+  if (do_dirs1) {
+    int rc;
+    if (do_delete) {
+      /* try to unlink a non-empty directory (bucket) */
+      rc = rgw_unlink(fs, dirs1_b.parent_fh, dirs1_b.name.c_str(),
+		      RGW_UNLINK_FLAG_NONE);
+      ASSERT_NE(rc, 0);
+    }
+    /* try to unlink a non-empty directory (non-bucket) */
+    obj_rec& sdir_0 = get<1>(dirs_vec[0])[0];    ASSERT_EQ(sdir_0.name, "sdir_0");
+    ASSERT_TRUE(sdir_0.rgw_fh->is_dir());
+    /* XXX we can't enforce this currently */
+#if 0
+    ASSERT_EQ(sdir_0.name, "sdir_0");
+    ASSERT_TRUE(sdir_0.rgw_fh->is_dir());
+    rc = rgw_unlink(fs, sdir_0.parent_fh, sdir_0.name.c_str(),
+		    RGW_UNLINK_FLAG_NONE);
+    ASSERT_NE(rc, 0);
+#endif
+  }
+}
+
+TEST(LibRGW, GETATTR_DIRS1)
+{
+  if (do_dirs1) {
+    int rc;
+    struct stat st;
+    for (auto& dirs_rec : dirs_vec) {
+      obj_rec& dir = get<0>(dirs_rec);
+      if (verbose) {
+	std::cout << "scanning objects in "
+		  << dir.rgw_fh->full_object_name()
+		  << std::endl;
+      }
+      for (auto& sobj : get<1>(dirs_rec)) {
+	rc = rgw_getattr(fs, sobj.fh, &st, RGW_GETATTR_FLAG_NONE);
+	ASSERT_EQ(rc, 0);
+	/* validate, pretty-print */
+	if (sobj.rgw_fh->object_name().find("sfile") != std::string::npos) {
+	  ASSERT_TRUE(sobj.rgw_fh->is_file());
+	  ASSERT_TRUE(S_ISREG(st.st_mode));
+	}
+	if (sobj.rgw_fh->object_name().find("sdir") != std::string::npos) {
+	  ASSERT_TRUE(sobj.rgw_fh->is_dir());
+	  ASSERT_TRUE(S_ISDIR(st.st_mode));
+	}
+	if (verbose) {
+	  obj_rec_st rec_st{sobj, st};
+	  std::cout << "\t"
+		    << rec_st
+		    << std::endl;
+	}
+      }
+    }
+  }
+}
+
+TEST(LibRGW, READ_DIRS1)
+{
+  if (do_dirs1) {
+    int rc;
+    char buf[256];
+    size_t nread;
+    for (auto& dirs_rec : dirs_vec) {
+      obj_rec& dir = get<0>(dirs_rec);
+      if (verbose) {
+	std::cout << "read back objects in "
+		  << dir.rgw_fh->full_object_name()
+		  << std::endl;
+      }
+      for (auto& sobj : get<1>(dirs_rec)) {
+	/* only the first 2 file objects have data */
+	if ((sobj.rgw_fh->object_name().find("sfile_0")
+	     != std::string::npos) ||
+	    (sobj.rgw_fh->object_name().find("sfile_1")
+	     != std::string::npos)) {
+	  ASSERT_TRUE(sobj.rgw_fh->is_file());
+	  ASSERT_EQ(sobj.rgw_fh->get_size(), 16UL);
+	  // do it
+	  memset(buf, 0, 256);
+	  rc = rgw_read(fs, sobj.fh, 0, 256, &nread, buf, RGW_READ_FLAG_NONE);
+	  ASSERT_EQ(rc, 0);
+	  if (verbose) {
+	    std::cout << "\tread back from " << sobj.name
+		      << " : \"" << buf << "\""
+		      << std::endl;
+	  }
+	}
+      }
+    }
+  }
+}
+
+TEST(LibRGW, READF_SETUP1)
+{
+  struct stat st;
+  if (do_dirs1) {
+    if (do_create) {
+      if ((! stat(readf_out_name.c_str(), &st)) &&
+	  (S_ISREG(st.st_mode)) &&
+	  (st.st_size == 6291456))
+	return;
+      ofstream of;
+      of.open(readf_out_name, ios::out|ios::app|ios::binary);
+      for (int ix1 = 0; ix1 < 6; ++ix1) {
+	for (int ix2 = 0; ix2 < 1024*1024; ++ix2) {
+	  of << ix1;
+	}
+      }
+    }
+  }
+}
+
+TEST(LibRGW, READF_DIRS1) {
+  if (do_dirs1) {
+    if (do_readf) {
+      obj_rec fobj{readf_name, nullptr, dirs1_b.fh, nullptr};
+
+      int rc = rgw_lookup(fs, dirs1_b.fh, fobj.name.c_str(), &fobj.fh,
+			  RGW_LOOKUP_FLAG_NONE);
+      ASSERT_EQ(rc, 0);
+      ASSERT_NE(fobj.fh, nullptr);
+      fobj.sync();
+
+      ofstream of;
+      of.open(readf_out_name, ios::out|ios::app|ios::binary);
+      int bufsz = 1024 * 1024 * sizeof(char);
+      char *buffer = (char*) malloc(bufsz);
+
+      uint64_t offset = 0;
+      uint64_t length = bufsz;
+      for (int ix = 0; ix < 6; ++ix) {
+	size_t nread = 0;
+	memset(buffer, 0, length); // XXX
+	rc = rgw_read(fs, fobj.fh, offset, length, &nread, buffer,
+		      RGW_READ_FLAG_NONE);
+	ASSERT_EQ(rc, 0);
+	ASSERT_EQ(nread, length);
+	of.write(buffer, length);
+	offset += nread;
+      }
+      of.close();
+      free(buffer);
+      rgw_fh_rele(fs, fobj.fh, 0 /* flags */);
+    }
+  }
+}
+
+TEST(LibRGW, WRITEF_DIRS1) {
+  if (do_dirs1) {
+    if (do_writef) {
+      int rc;
+      ifstream ifs;
+      ifs.open(readf_out_name, ios::out|ios::app|ios::binary);
+      ASSERT_TRUE(ifs.is_open());
+
+      obj_rec fobj{writef_name, nullptr, dirs1_b.fh, nullptr};
+
+      (void) rgw_lookup(fs, fobj.parent_fh, fobj.name.c_str(), &fobj.fh,
+			RGW_LOOKUP_FLAG_NONE);
+      if (! fobj.fh) {
+	if (do_create) {
+	  /* make a new file object (the hard way) */
+	  rc = rgw_lookup(fs, fobj.parent_fh, fobj.name.c_str(), &fobj.fh,
+			  RGW_LOOKUP_FLAG_CREATE);
+	  ASSERT_EQ(rc, 0);
+	}
+      }
+      ASSERT_NE(fobj.fh, nullptr);
+      fobj.sync();
+
+      /* begin write transaction */
+      rc = rgw_open(fs, fobj.fh, 0 /* flags */);
+      ASSERT_EQ(rc, 0);
+      ASSERT_TRUE(fobj.rgw_fh->is_open());
+
+      int bufsz = 1024 * 1024 * sizeof(char);
+      char *buffer = (char*) malloc(bufsz);
+
+      uint64_t offset = 0;
+      uint64_t length = bufsz;
+      for (int ix = 0; ix < 6; ++ix) {
+	ASSERT_TRUE(ifs.good());
+	ifs.read(buffer, bufsz);
+	size_t nwritten = 0;
+	string str;
+	str.assign(buffer, 4);
+	if (verbose) {
+	  std::cout << "read and writing " << length << " bytes"
+		    << " from " << readf_out_name
+		    << " at offset " << offset
+		    << " (" << str << "... [first 4 chars])"
+		    << std::endl;
+	}
+	char* leakbuf = (char*) malloc(bufsz);
+	memcpy(leakbuf, buffer, length);
+	rc = rgw_write(fs, fobj.fh, offset, length, &nwritten, leakbuf,
+		      RGW_WRITE_FLAG_NONE);
+	ASSERT_EQ(rc, 0);
+	ASSERT_EQ(nwritten, length);
+	offset += length;
+      }
+
+      /* commit write transaction */
+      rc = rgw_close(fs, fobj.fh, RGW_CLOSE_FLAG_NONE);
+      ASSERT_EQ(rc, 0);
+
+      ifs.close();
+      free(buffer);
+      rgw_fh_rele(fs, fobj.fh, 0 /* flags */);
+    }
+  }
+}
+
+TEST(LibRGW, RELEASE_DIRS1) {
+  if (do_dirs1) {
+    /* force release of handles for children of dirs1--force subsequent
+     * checks to reload them from the cluster.
+     *
+     * while doing this, verify handle cleanup and correct LRU state
+     * (not reachable)
+     */
+    int rc;
+    for (auto& dirs_rec : dirs_vec) {
+      for (auto& obj : get<1>(dirs_rec)) {
+	if (verbose) {
+	  std::cout << "release " << obj.name
+		    << " type: " << obj.rgw_fh->stype()
+		    << " refs: " << obj.rgw_fh->get_refcnt()
+		    << std::endl;
+	}
+	ASSERT_EQ(obj.rgw_fh->get_refcnt(), 2UL);
+	rc = rgw_fh_rele(fs, obj.fh, 0 /* flags */);
+	ASSERT_EQ(rc, 0);
+	ASSERT_EQ(obj.rgw_fh->get_refcnt(), 1UL);
+	/* try-discard handle */
+	/* clear obj_rec vec */
+      }
+    }
+  }
+}
+
+extern "C" {
+  static bool r1_cb(const char* name, void *arg, uint64_t offset) {
+    struct rgw_file_handle* parent_fh
+      = static_cast<struct rgw_file_handle*>(arg);
+    RGWFileHandle* rgw_fh = get_rgwfh(parent_fh);
+    lsubdout(cct, rgw, 10) << __func__
+			   << " bucket=" << rgw_fh->bucket_name()
+			   << " dir=" << rgw_fh->full_object_name()
+			   << " called back name=" << name
+			   << dendl;
+    string name_str{name};
+    if (! ((name_str == ".") ||
+	   (name_str == ".."))) {
+      obj_stack.push(
+	obj_rec{std::move(name_str), nullptr, parent_fh, nullptr});
+    }
+    return true; /* XXX */
+  }
+}
+
+TEST(LibRGW, HIER1) {
+  if (do_hier1) {
+    int rc;
+    obj_stack.push(
+      obj_rec{bucket_name, nullptr, nullptr, nullptr});
+    while (! obj_stack.empty()) {
+      auto& elt = obj_stack.top();
+      if (! elt.fh) {
+	struct rgw_file_handle* parent_fh = elt.parent_fh
+	  ? elt.parent_fh : fs->root_fh;
+	RGWFileHandle* pfh = get_rgwfh(parent_fh);
+	rgw::ignore(pfh);
+	lsubdout(cct, rgw, 10)
+	  << "rgw_lookup:"
+	  << " parent object_name()=" << pfh->object_name()
+	  << " parent full_object_name()=" << pfh->full_object_name()
+	  << " elt.name=" << elt.name
+	  << dendl;
+	rc = rgw_lookup(fs, parent_fh, elt.name.c_str(), &elt.fh,
+			RGW_LOOKUP_FLAG_NONE);
+	ASSERT_EQ(rc, 0);
+	// XXXX
+	RGWFileHandle* efh = get_rgwfh(elt.fh);
+	rgw::ignore(efh);
+	lsubdout(cct, rgw, 10)
+	  << "rgw_lookup result:"
+	  << " elt object_name()=" << efh->object_name()
+	  << " elt full_object_name()=" << efh->full_object_name()
+	  << " elt.name=" << elt.name
+	  << dendl;
+
+	ASSERT_NE(elt.fh, nullptr);
+	elt.rgw_fh = get_rgwfh(elt.fh);
+	elt.parent_fh = elt.rgw_fh->get_parent()->get_fh();
+	ASSERT_EQ(elt.parent_fh, parent_fh);
+	continue;
+      } else {
+	// we have a handle in some state in top position
+	switch(elt.fh->fh_type) {
+	case RGW_FS_TYPE_DIRECTORY:
+	  if (! elt.state.readdir) {
+	    // descending
+	    uint64_t offset = 0;
+	    bool eof; // XXX
+	    lsubdout(cct, rgw, 10)
+	      << "readdir in"
+	      << " bucket: " << elt.rgw_fh->bucket_name()
+	      << " object_name: " << elt.rgw_fh->object_name()
+	      << " full_name: " << elt.rgw_fh->full_object_name()
+	      << dendl;
+	    rc = rgw_readdir(fs, elt.fh, &offset, r1_cb, elt.fh, &eof,
+			    RGW_READDIR_FLAG_DOTDOT);
+	    elt.state.readdir = true;
+	    ASSERT_EQ(rc, 0);
+	    // ASSERT_TRUE(eof); // XXXX working incorrectly w/single readdir
+	  } else {
+	    // ascending
+	    std::cout << elt << std::endl;
+	    cleanup_queue.push_back(elt);
+	    obj_stack.pop();
+	  }
+	  break;
+	case RGW_FS_TYPE_FILE:
+	  // ascending
+	  std::cout << elt << std::endl;
+	  cleanup_queue.push_back(elt);
+	  obj_stack.pop();
+	  break;
+	default:
+	  abort();
+	};
+      }
+    }
+  }
+}
+
+TEST(LibRGW, MARKER1_SETUP_BUCKET) {
+  /* "large" directory enumeration test.  this one deals only with
+   * file objects */
+  if (do_marker1) {
+    struct stat st;
+    int ret;
+
+    if (do_create) {
+      ret = rgw_mkdir(fs, bucket_fh, marker_dir.c_str(), 755, &st, &marker_fh,
+		      RGW_MKDIR_FLAG_NONE);
+    } else {
+      ret = rgw_lookup(fs, bucket_fh, marker_dir.c_str(), &marker_fh,
+		       RGW_LOOKUP_FLAG_NONE);
+    }
+    ASSERT_EQ(ret, 0);
+  }
+}
+
+TEST(LibRGW, MARKER1_SETUP_OBJECTS)
+{
+  /* "large" directory enumeration test.  this one deals only with
+   * file objects */
+  if (do_marker1 && do_create) {
+    int ret;
+
+    for (int ix = 0; ix < marker_nobjs; ++ix) {
+      std::string object_name("f_");
+      object_name += to_string(ix);
+      obj_rec obj{object_name, nullptr, marker_fh, nullptr};
+      // lookup object--all operations are by handle
+      ret = rgw_lookup(fs, marker_fh, obj.name.c_str(), &obj.fh,
+		       RGW_LOOKUP_FLAG_CREATE);
+      ASSERT_EQ(ret, 0);
+      obj.rgw_fh = get_rgwfh(obj.fh);
+      // open object--open transaction
+      ret = rgw_open(fs, obj.fh, RGW_OPEN_FLAG_NONE);
+      ASSERT_EQ(ret, 0);
+      ASSERT_TRUE(obj.rgw_fh->is_open());
+      // unstable write data
+      size_t nbytes;
+      string data("data for ");
+      data += object_name;
+      int ret = rgw_write(fs, obj.fh, 0, data.length(), &nbytes,
+			  (void*) data.c_str(), RGW_WRITE_FLAG_NONE);
+      ASSERT_EQ(ret, 0);
+      ASSERT_EQ(nbytes, data.length());
+      // commit transaction (write on close)
+      ret = rgw_close(fs, obj.fh, 0 /* flags */);
+      ASSERT_EQ(ret, 0);
+      // save for cleanup
+      marker_objs.push_back(obj);
+    }
+  }
+}
+
+extern "C" {
+  static bool r2_cb(const char* name, void *arg, uint64_t offset) {
+    dirent_vec& dvec =
+      *(static_cast<dirent_vec*>(arg));
+    lsubdout(cct, rgw, 10) << __func__
+			   << " bucket=" << bucket_name
+			   << " dir=" << marker_dir
+			   << " iv count=" << dvec.count
+			   << " called back name=" << name
+			   << dendl;
+    string name_str{name};
+    if (! ((name_str == ".") ||
+	   (name_str == ".."))) {
+      dvec.obj_names.push_back(dirent_t{std::move(name_str), offset});
+    }
+    return true; /* XXX */
+  }
+}
+
+TEST(LibRGW, MARKER1_READDIR)
+{
+  if (do_marker1) {
+    using std::get;
+
+    dirent_vec dvec;
+    uint64_t offset = 0;
+    bool eof = false;
+
+    /* because RGWReaddirRequest::default_max is 1000 (XXX make
+     * configurable?) and marker_nobjs is 5*1024, the number
+     * of required rgw_readdir operations N should be
+     * marker_nobjs/1000 < N < marker_nobjs/1000+1, i.e., 6 when
+     * marker_nobjs==5*1024 */
+    uint32_t max_iterations = marker_nobjs/1000+1;
+
+    do {
+      ASSERT_TRUE(dvec.count <= max_iterations);
+      int ret = rgw_readdir(fs, marker_fh, &offset, r2_cb, &dvec, &eof,
+			    RGW_READDIR_FLAG_DOTDOT);
+      ASSERT_EQ(ret, 0);
+      ASSERT_EQ(offset, get<1>(dvec.obj_names.back())); // cookie check
+      ++dvec.count;
+    } while(!eof);
+    std::cout << "Read " << dvec.obj_names.size() << " objects in "
+	      << marker_dir.c_str() << std::endl;
+  }
+}
+
+TEST(LibRGW, MARKER1_OBJ_CLEANUP)
+{
+  int rc;
+  for (auto& obj : marker_objs) {
+    if (obj.fh) {
+      if (do_delete) {
+	if (verbose) {
+	  std::cout << "unlinking: " << bucket_name << ":" << obj.name
+		    << std::endl;
+	}
+	rc = rgw_unlink(fs, marker_fh, obj.name.c_str(), RGW_UNLINK_FLAG_NONE);
+      }
+      rc = rgw_fh_rele(fs, obj.fh, 0 /* flags */);
+      ASSERT_EQ(rc, 0);
+    }
+  }
+  marker_objs.clear();
+}
+
+TEST(LibRGW, CLEANUP) {
+  int rc;
+
+  if (do_marker1) {
+    cleanup_queue.push_back(
+      obj_rec{bucket_name, bucket_fh, fs->root_fh, get_rgwfh(fs->root_fh)});
+  }
+
+  for (auto& elt : cleanup_queue) {
+    if (elt.fh) {
+      rc = rgw_fh_rele(fs, elt.fh, 0 /* flags */);
+      ASSERT_EQ(rc, 0);
+    }
+  }
+  cleanup_queue.clear();
+}
+
+TEST(LibRGW, UMOUNT) {
+  if (! fs)
+    return;
+
+  int ret = rgw_umount(fs, RGW_UMOUNT_FLAG_NONE);
+  ASSERT_EQ(ret, 0);
+}
+
+TEST(LibRGW, SHUTDOWN) {
+  librgw_shutdown(rgw_h);
+}
+
+int main(int argc, char *argv[])
+{
+  char *v{nullptr};
+  string val;
+  vector<const char*> args;
+
+  argv_to_vec(argc, const_cast<const char**>(argv), args);
+  env_to_vec(args);
+
+  v = getenv("AWS_ACCESS_KEY_ID");
+  if (v) {
+    access_key = v;
+  }
+
+  v = getenv("AWS_SECRET_ACCESS_KEY");
+  if (v) {
+    secret_key = v;
+  }
+
+  for (auto arg_iter = args.begin(); arg_iter != args.end();) {
+    if (ceph_argparse_witharg(args, arg_iter, &val, "--access",
+			      (char*) nullptr)) {
+      access_key = val;
+    } else if (ceph_argparse_witharg(args, arg_iter, &val, "--secret",
+				     (char*) nullptr)) {
+      secret_key = val;
+    } else if (ceph_argparse_witharg(args, arg_iter, &val, "--uid",
+				     (char*) nullptr)) {
+      uid = val;
+    } else if (ceph_argparse_witharg(args, arg_iter, &val, "--bn",
+				     (char*) nullptr)) {
+      bucket_name = val;
+    } else if (ceph_argparse_flag(args, arg_iter, "--hier1",
+					    (char*) nullptr)) {
+      do_hier1 = true;
+    } else if (ceph_argparse_flag(args, arg_iter, "--dirs1",
+					    (char*) nullptr)) {
+      do_dirs1 = true;
+    } else if (ceph_argparse_flag(args, arg_iter, "--marker1",
+					    (char*) nullptr)) {
+      do_marker1 = true;
+    } else if (ceph_argparse_flag(args, arg_iter, "--create",
+					    (char*) nullptr)) {
+      do_create = true;
+    } else if (ceph_argparse_flag(args, arg_iter, "--delete",
+					    (char*) nullptr)) {
+      do_delete = true;
+    } else if (ceph_argparse_flag(args, arg_iter, "--rename",
+					    (char*) nullptr)) {
+      do_rename = true;
+    } else if (ceph_argparse_flag(args, arg_iter, "--readf",
+					    (char*) nullptr)) {
+      do_readf = true;
+    } else if (ceph_argparse_flag(args, arg_iter, "--writef",
+					    (char*) nullptr)) {
+      do_writef = true;
+    } else if (ceph_argparse_flag(args, arg_iter, "--verbose",
+					    (char*) nullptr)) {
+      verbose = true;
+    } else {
+      ++arg_iter;
+    }
+  }
+
+  /* dont accidentally run as anonymous */
+  if ((access_key == "") ||
+      (secret_key == "")) {
+    std::cout << argv[0] << " no AWS credentials, exiting" << std::endl;
+    return EPERM;
+  }
+
+  saved_args.argc = argc;
+  saved_args.argv = argv;
+
+  ::testing::InitGoogleTest(&argc, argv);
+  return RUN_ALL_TESTS();
+}
diff --git a/src/test/msgr/test_msgr.cc b/src/test/msgr/test_msgr.cc
index b195349..b41f260 100644
--- a/src/test/msgr/test_msgr.cc
+++ b/src/test/msgr/test_msgr.cc
@@ -1048,7 +1048,7 @@ TEST_P(MessengerTest, SyntheticStressTest) {
     test_msg.generate_connection();
   }
   gen_type rng(time(NULL));
-  for (int i = 0; i < 10000; ++i) {
+  for (int i = 0; i < 5000; ++i) {
     if (!(i % 10)) {
       cerr << "Op " << i << ": ";
       test_msg.print_internal_state();
diff --git a/src/test/objectstore/store_test.cc b/src/test/objectstore/store_test.cc
index 36cb2ae..e1f01cd 100644
--- a/src/test/objectstore/store_test.cc
+++ b/src/test/objectstore/store_test.cc
@@ -526,6 +526,17 @@ TEST_P(StoreTest, SimpleObjectTest) {
     ASSERT_TRUE(in.contents_equal(bl));
   }
   {
+    bufferlist bl;
+    bl.append("abcde01234012340123401234abcde01234012340123401234abcde01234012340123401234abcde01234012340123401234");
+
+    //test: offset=len=0 mean read all data
+    bufferlist in;
+    r = store->read(cid, hoid, 0, 0, in);
+    ASSERT_EQ((int)bl.length(), r);
+    in.hexdump(cout);
+    ASSERT_TRUE(in.contents_equal(bl));
+  }
+  {
     ObjectStore::Transaction t;
     t.remove(cid, hoid);
     t.remove_collection(cid);
@@ -1480,6 +1491,65 @@ TEST_P(StoreTest, SimpleObjectLongnameTest) {
   }
 }
 
+ghobject_t generate_long_name(unsigned i)
+{
+  stringstream name;
+  name << "object id " << i << " ";
+  for (unsigned j = 0; j < 500; ++j) name << 'a';
+  ghobject_t hoid(hobject_t(sobject_t(name.str(), CEPH_NOSNAP)));
+  hoid.hobj.set_hash(i % 2);
+  return hoid;
+}
+
+TEST_P(StoreTest, LongnameSplitTest) {
+  ObjectStore::Sequencer osr("test");
+  int r;
+  coll_t cid;
+  {
+    ObjectStore::Transaction t;
+    t.create_collection(cid, 0);
+    cerr << "Creating collection " << cid << std::endl;
+    r = store->apply_transaction(&osr, std::move(t));
+    ASSERT_EQ(r, 0);
+  }
+  for (unsigned i = 0; i < 320; ++i) {
+    ObjectStore::Transaction t;
+    ghobject_t hoid = generate_long_name(i);
+    t.touch(cid, hoid);
+    cerr << "Creating object " << hoid << std::endl;
+    r = store->apply_transaction(&osr, std::move(t));
+  }
+
+  ghobject_t test_obj = generate_long_name(319);
+  ghobject_t test_obj_2 = test_obj;
+  test_obj_2.generation = 0;
+  {
+    ObjectStore::Transaction t;
+    // should cause a split
+    t.collection_move_rename(
+      cid, test_obj,
+      cid, test_obj_2);
+    r = store->apply_transaction(&osr, std::move(t));
+  }
+
+  for (unsigned i = 0; i < 319; ++i) {
+    ObjectStore::Transaction t;
+    ghobject_t hoid = generate_long_name(i);
+    t.remove(cid, hoid);
+    cerr << "Removing object " << hoid << std::endl;
+    r = store->apply_transaction(&osr, std::move(t));
+  }
+  {
+    ObjectStore::Transaction t;
+    t.remove(cid, test_obj_2);
+    t.remove_collection(cid);
+    cerr << "Cleaning" << std::endl;
+    r = store->apply_transaction(&osr, std::move(t));
+    ASSERT_EQ(r, 0);
+  }
+
+}
+
 TEST_P(StoreTest, ManyObjectTest) {
   ObjectStore::Sequencer osr("test");
   int NUM_OBJS = 2000;
@@ -1622,11 +1692,17 @@ public:
     char buf[100];
     snprintf(buf, sizeof(buf), "OBJ_%u", seq);
     string name(buf);
+    if (seq % 2) {
+      for (unsigned i = 0; i < 300; ++i) {
+	name.push_back('a');
+      }
+    }
     ++seq;
     return ghobject_t(
       hobject_t(
 	name, string(), rand() & 2 ? CEPH_NOSNAP : rand(),
-	seq % 16, // use smaller set of hash values so clone can work
+	(((seq / 1024) % 2) * 0xF00 ) +
+	(seq & 0xFF),
 	poolid, ""));
   }
 };
@@ -1711,6 +1787,39 @@ public:
     }
   };
 
+  class C_SyntheticOnStash : public Context {
+  public:
+    SyntheticWorkloadState *state;
+    ObjectStore::Transaction *t;
+    ghobject_t oid, noid;
+
+    C_SyntheticOnStash(SyntheticWorkloadState *state,
+		       ObjectStore::Transaction *t, ghobject_t oid,
+		       ghobject_t noid)
+      : state(state), t(t), oid(oid), noid(noid) {}
+
+    void finish(int r) {
+      Mutex::Locker locker(state->lock);
+      EnterExit ee("clone finish");
+      ASSERT_TRUE(state->in_flight_objects.count(oid));
+      ASSERT_EQ(r, 0);
+      state->in_flight_objects.erase(oid);
+      if (state->contents.count(noid))
+        state->available_objects.insert(noid);
+      --(state->in_flight);
+      bufferlist r2;
+      r = state->store->read(
+	state->cid, noid, 0,
+	state->contents[noid].data.length(), r2);
+      if (!state->contents[noid].data.contents_equal(r2)) {
+	dump_bl_mismatch(state->contents[noid].data, r2);
+	assert(0 == " mismatch after clone");
+        ASSERT_TRUE(state->contents[noid].data.contents_equal(r2));
+      }
+      state->cond.Signal();
+    }
+  };
+
   class C_SyntheticOnClone : public Context {
   public:
     SyntheticWorkloadState *state;
@@ -1843,6 +1952,43 @@ public:
     return status;
   }
 
+  int stash() {
+    Mutex::Locker locker(lock);
+    EnterExit ee("stash");
+    if (!can_unlink())
+      return -ENOENT;
+    if (!can_create())
+      return -ENOSPC;
+    wait_for_ready();
+
+    ghobject_t old_obj;
+    int max = 20;
+    do {
+      old_obj = get_uniform_random_object();
+    } while (--max && !contents[old_obj].data.length());
+    available_objects.erase(old_obj);
+    ghobject_t new_obj = old_obj;
+    new_obj.generation++;
+    available_objects.erase(new_obj);
+
+    ObjectStore::Transaction *t = new ObjectStore::Transaction;
+    t->collection_move_rename(cid, old_obj, cid, new_obj);
+    ++in_flight;
+    in_flight_objects.insert(old_obj);
+
+    // *copy* the data buffer, since we may modify it later.
+    contents[new_obj].attrs = contents[old_obj].attrs;
+    contents[new_obj].data.clear();
+    contents[new_obj].data.append(contents[old_obj].data.c_str(),
+				  contents[old_obj].data.length());
+    contents.erase(old_obj);
+    int status = store->queue_transaction(
+      osr, std::move(*t),
+      new C_SyntheticOnStash(this, t, old_obj, new_obj));
+    delete t;
+    return status;
+  }
+
   int clone() {
     Mutex::Locker locker(lock);
     EnterExit ee("clone");
@@ -2327,6 +2473,8 @@ TEST_P(StoreTest, Synthetic) {
       test_obj.write();
     } else if (val > 50) {
       test_obj.clone();
+    } else if (val > 30) {
+      test_obj.stash();
     } else if (val > 10) {
       test_obj.read();
     } else {
@@ -2366,6 +2514,8 @@ TEST_P(StoreTest, AttrSynthetic) {
       test_obj.setattrs();
     } else if (val > 45) {
       test_obj.clone();
+    } else if (val > 37) {
+      test_obj.stash();
     } else if (val > 30) {
       test_obj.getattrs();
     } else {
@@ -3075,13 +3225,14 @@ TEST_P(StoreTest, Rename) {
   coll_t cid(spg_t(pg_t(0, 2122),shard_id_t::NO_SHARD));
   ghobject_t srcoid(hobject_t("src_oid", "", CEPH_NOSNAP, 0, 0, ""));
   ghobject_t dstoid(hobject_t("dest_oid", "", CEPH_NOSNAP, 0, 0, ""));
-  bufferlist data;
-  data.append("foo");
+  bufferlist a, b;
+  a.append("foo");
+  b.append("bar");
   int r;
   {
     ObjectStore::Transaction t;
     t.create_collection(cid, 0);
-    t.write(cid, srcoid, 0, data.length(), data);
+    t.write(cid, srcoid, 0, a.length(), a);
     r = store->apply_transaction(&osr, std::move(t));
     ASSERT_EQ(r, 0);
   }
@@ -3089,14 +3240,37 @@ TEST_P(StoreTest, Rename) {
   {
     ObjectStore::Transaction t;
     t.collection_move_rename(cid, srcoid, cid, dstoid);
-    t.write(cid, srcoid, 0, data.length(), data);
-    t.setattr(cid, srcoid, "attr", data);
+    t.remove(cid, srcoid);
+    t.write(cid, srcoid, 0, b.length(), b);
+    t.setattr(cid, srcoid, "attr", b);
     r = store->apply_transaction(&osr, std::move(t));
     ASSERT_EQ(r, 0);
   }
   ASSERT_TRUE(store->exists(cid, srcoid));
   ASSERT_TRUE(store->exists(cid, dstoid));
   {
+    bufferlist bl;
+    store->read(cid, srcoid, 0, 3, bl);
+    ASSERT_TRUE(bl.contents_equal(b));
+    store->read(cid, dstoid, 0, 3, bl);
+    ASSERT_TRUE(bl.contents_equal(a));
+  }
+  {
+    ObjectStore::Transaction t;
+    t.remove(cid, dstoid);
+    t.collection_move_rename(cid, srcoid, cid, dstoid);
+    t.remove(cid, srcoid);
+    t.setattr(cid, srcoid, "attr", a);
+    r = store->apply_transaction(&osr, std::move(t));
+    ASSERT_EQ(r, 0);
+  }
+  ASSERT_TRUE(store->exists(cid, dstoid));
+  {
+    bufferlist bl;
+    store->read(cid, dstoid, 0, 3, bl);
+    ASSERT_TRUE(bl.contents_equal(b));
+  }
+  {
     ObjectStore::Transaction t;
     t.remove(cid, dstoid);
     t.remove(cid, srcoid);
diff --git a/src/test/objectstore/test_transaction.cc b/src/test/objectstore/test_transaction.cc
index 6e12b5d..ebaccaa 100644
--- a/src/test/objectstore/test_transaction.cc
+++ b/src/test/objectstore/test_transaction.cc
@@ -14,6 +14,8 @@
 
 #include "os/ObjectStore.h"
 #include <gtest/gtest.h>
+#include "common/Clock.h"
+#include "include/utime.h"
 
 TEST(Transaction, MoveConstruct)
 {
@@ -73,3 +75,115 @@ TEST(Transaction, Swap)
   ASSERT_TRUE(a.empty());
   ASSERT_FALSE(b.empty());
 }
+
+ObjectStore::Transaction generate_transaction()
+{
+  auto a = ObjectStore::Transaction{};
+  a.set_use_tbl(false);
+  a.nop();
+
+  coll_t cid;
+  object_t obj("test_name");
+  snapid_t snap(0);
+  hobject_t hoid(obj, "key", snap, 0, 0, "nspace");
+  ghobject_t oid(hoid);
+
+  coll_t acid;
+  object_t aobj("another_test_name");
+  snapid_t asnap(0);
+  hobject_t ahoid(obj, "another_key", snap, 0, 0, "another_nspace");
+  ghobject_t aoid(hoid);
+  std::set<string> keys;
+  keys.insert("any_1");
+  keys.insert("any_2");
+  keys.insert("any_3");
+
+  bufferlist bl;
+  bl.append_zero(4096);
+
+  a.write(cid, oid, 1, 4096, bl, 0);
+
+  a.omap_setkeys(acid, aoid, bl);
+
+  a.omap_rmkeys(cid, aoid, keys);
+
+  a.touch(acid, oid);
+
+  return a;
+}
+
+TEST(Transaction, GetNumBytes)
+{
+  auto a = ObjectStore::Transaction{};
+  a.set_use_tbl(false);
+  a.nop();
+  ASSERT_TRUE(a.get_encoded_bytes() == a.get_encoded_bytes_test());
+
+  coll_t cid;
+  object_t obj("test_name");
+  snapid_t snap(0);
+  hobject_t hoid(obj, "key", snap, 0, 0, "nspace");
+  ghobject_t oid(hoid);
+
+  coll_t acid;
+  object_t aobj("another_test_name");
+  snapid_t asnap(0);
+  hobject_t ahoid(obj, "another_key", snap, 0, 0, "another_nspace");
+  ghobject_t aoid(hoid);
+  std::set<string> keys;
+  keys.insert("any_1");
+  keys.insert("any_2");
+  keys.insert("any_3");
+
+  bufferlist bl;
+  bl.append_zero(4096);
+
+  a.write(cid, oid, 1, 4096, bl, 0);
+  ASSERT_TRUE(a.get_encoded_bytes() == a.get_encoded_bytes_test());
+
+  a.omap_setkeys(acid, aoid, bl);
+  ASSERT_TRUE(a.get_encoded_bytes() == a.get_encoded_bytes_test());
+
+  a.omap_rmkeys(cid, aoid, keys);
+  ASSERT_TRUE(a.get_encoded_bytes() == a.get_encoded_bytes_test());
+
+  a.touch(acid, oid);
+  ASSERT_TRUE(a.get_encoded_bytes() == a.get_encoded_bytes_test());
+}
+
+void bench_num_bytes(bool legacy)
+{
+  const int max = 2500000;
+  auto a = generate_transaction();
+
+  if (legacy) {
+    cout << "get_encoded_bytes_test: ";
+  } else {
+    cout << "get_encoded_bytes: ";
+  }
+
+  utime_t start = ceph_clock_now(NULL);
+  if (legacy) {
+    for (int i = 0; i < max; ++i) {
+      a.get_encoded_bytes_test();
+    }
+  } else {
+    for (int i = 0; i < max; ++i) {
+      a.get_encoded_bytes();
+    }
+  }
+
+  utime_t end = ceph_clock_now(NULL);
+  cout << max << " encodes in " << (end - start) << std::endl;
+
+}
+
+TEST(Transaction, GetNumBytesBenchLegacy)
+{
+   bench_num_bytes(true);
+}
+
+TEST(Transaction, GetNumBytesBenchCurrent)
+{
+   bench_num_bytes(false);
+}
diff --git a/src/test/objectstore_bench.cc b/src/test/objectstore_bench.cc
index d8cd166..5ec8503 100644
--- a/src/test/objectstore_bench.cc
+++ b/src/test/objectstore_bench.cc
@@ -269,7 +269,7 @@ int main(int argc, const char *argv[])
     for (int i = 0; i < cfg.threads; i++) {
       std::stringstream oss;
       oss << "osbench-thread-" << i;
-      oids.emplace_back(pg.make_temp_object(oss.str()));
+      oids.emplace_back(pg.make_temp_hobject(oss.str()));
 
       ObjectStore::Sequencer osr(__func__);
       ObjectStore::Transaction t;
@@ -278,7 +278,7 @@ int main(int argc, const char *argv[])
       assert(r == 0);
     }
   } else {
-    oids.emplace_back(pg.make_temp_object("osbench"));
+    oids.emplace_back(pg.make_temp_hobject("osbench"));
 
     ObjectStore::Sequencer osr(__func__);
     ObjectStore::Transaction t;
diff --git a/src/test/opensuse-13.2/ceph.spec.in b/src/test/opensuse-13.2/ceph.spec.in
index 498eac4..b52d7e2 100644
--- a/src/test/opensuse-13.2/ceph.spec.in
+++ b/src/test/opensuse-13.2/ceph.spec.in
@@ -46,7 +46,8 @@ restorecon -R /etc/rc\.d/init\.d/ceph > /dev/null 2>&1; \
 restorecon -R /etc/rc\.d/init\.d/radosgw > /dev/null 2>&1; \
 restorecon -R /var/run/ceph > /dev/null 2>&1; \
 restorecon -R /var/lib/ceph > /dev/null 2>&1; \
-restorecon -R /var/log/ceph > /dev/null 2>&1;
+restorecon -R /var/log/ceph > /dev/null 2>&1; \
+restorecon -R /var/log/radosgw > /dev/null 2>&1;
 %endif
 
 %{!?_udevrulesdir: %global _udevrulesdir /lib/udev/rules.d}
@@ -108,11 +109,6 @@ BuildRequires:	boost-devel
 BuildRequires:  cmake
 BuildRequires:	cryptsetup
 BuildRequires:	fuse-devel
-%if 0%{?suse_version}
-BuildRequires:	python-Cython
-%else
-BuildRequires:	Cython
-%endif
 BuildRequires:	gdbm
 BuildRequires:	hdparm
 BuildRequires:	leveldb-devel > 1.2
@@ -155,15 +151,20 @@ BuildRequires:	libbz2-devel
 %if 0%{with tcmalloc}
 BuildRequires:	gperftools-devel
 %endif
+BuildRequires:  btrfsprogs
 BuildRequires:	mozilla-nss-devel
 BuildRequires:	keyutils-devel
 BuildRequires:	libatomic-ops-devel
+BuildRequires:  libopenssl-devel
 BuildRequires:  lsb-release
+BuildRequires:  openldap2-devel
+BuildRequires:	python-Cython
 %endif
 %if 0%{?fedora} || 0%{?rhel} 
 %if 0%{?_with_systemd}
 Requires:	systemd
 %endif
+BuildRequires:	btrfs-progs
 BuildRequires:	nss-devel
 BuildRequires:	keyutils-libs-devel
 BuildRequires:	libatomic_ops-devel
@@ -171,7 +172,10 @@ Requires(post):	chkconfig
 Requires(preun):	chkconfig
 Requires(preun):	initscripts
 BuildRequires:	gperftools-devel
+BuildRequires:  openldap-devel
+BuildRequires:  openssl-devel
 BuildRequires:  redhat-lsb-core
+BuildRequires:	Cython
 %endif
 # boost
 %if 0%{?fedora} || 0%{?rhel} 
@@ -208,6 +212,10 @@ BuildRequires:	python-sphinx10
 %if 0%{?fedora} || 0%{?suse_version} || 0%{?rhel} >= 7
 BuildRequires:	python-sphinx
 %endif
+#hardened-cc1
+%if 0%{?fedora} || 0%{?rhel}
+BuildRequires:  redhat-rpm-config
+%endif
 
 %description
 Ceph is a massively scalable, open-source, distributed storage system that runs
@@ -224,6 +232,7 @@ Requires:      ceph-common = %{epoch}:%{version}-%{release}
 Requires:      librbd1 = %{epoch}:%{version}-%{release}
 Requires:      librados2 = %{epoch}:%{version}-%{release}
 Requires:      libcephfs1 = %{epoch}:%{version}-%{release}
+Requires:      librgw2 = %{epoch}:%{version}-%{release}
 %if 0%{with selinux}
 Requires:      ceph-selinux = %{epoch}:%{version}-%{release}
 %endif
@@ -253,6 +262,7 @@ Summary:	Ceph Common
 Group:		System Environment/Base
 Requires:	librbd1 = %{epoch}:%{version}-%{release}
 Requires:	librados2 = %{epoch}:%{version}-%{release}
+Requires:	libcephfs1 = %{epoch}:%{version}-%{release}
 Requires:	python-rados = %{epoch}:%{version}-%{release}
 Requires:	python-rbd = %{epoch}:%{version}-%{release}
 Requires:	python-cephfs = %{epoch}:%{version}-%{release}
@@ -300,14 +310,12 @@ of cluster membership, configuration, and state.
 %package fuse
 Summary:	Ceph fuse-based client
 Group:		System Environment/Base
-Requires:	%{name}
 %description fuse
 FUSE based client for Ceph distributed network file system
 
 %package -n rbd-fuse
 Summary:	Ceph fuse-based client
 Group:		System Environment/Base
-Requires:	%{name}
 Requires:	librados2 = %{epoch}:%{version}-%{release}
 Requires:	librbd1 = %{epoch}:%{version}-%{release}
 %description -n rbd-fuse
@@ -316,7 +324,6 @@ FUSE based client to map Ceph rbd images to files
 %package -n rbd-mirror
 Summary:	Ceph daemon for mirroring RBD images
 Group:		System Environment/Base
-Requires:	%{name}
 Requires:	ceph-common = %{epoch}:%{version}-%{release}
 Requires:	librados2 = %{epoch}:%{version}-%{release}
 %description -n rbd-mirror
@@ -326,7 +333,6 @@ changes asynchronously.
 %package -n rbd-nbd
 Summary:	Ceph RBD client base on NBD
 Group:		System Environment/Base
-Requires:	%{name}
 Requires:	librados2 = %{epoch}:%{version}-%{release}
 Requires:	librbd1 = %{epoch}:%{version}-%{release}
 %description -n rbd-nbd
@@ -340,6 +346,7 @@ Requires:	ceph-common = %{epoch}:%{version}-%{release}
 Requires:	ceph-selinux = %{epoch}:%{version}-%{release}
 %endif
 Requires:	librados2 = %{epoch}:%{version}-%{release}
+Requires:	librgw2 = %{epoch}:%{version}-%{release}
 %if 0%{?rhel} || 0%{?fedora}
 Requires:	mailcap
 # python-flask for powerdns
@@ -350,16 +357,17 @@ Requires:	python-flask
 Requires:      python-Flask
 %endif
 %description radosgw
-This package is an S3 HTTP REST gateway for the RADOS object store. It
-is implemented as a FastCGI module using libfcgi, and can be used in
-conjunction with any FastCGI capable web server.
+RADOS is a distributed object store used by the Ceph distributed
+storage system.  This package provides a REST gateway to the
+object store that aims to implement a superset of Amazon's S3
+service as well as the OpenStack Object Storage ("Swift") API.
 
 %if %{with ocf}
 %package resource-agents
 Summary:	OCF-compliant resource agents for Ceph daemons
 Group:		System Environment/Base
 License:	LGPL-2.0
-Requires:	%{name} = %{epoch}:%{version}
+Requires:	ceph-base = %{epoch}:%{version}
 Requires:	resource-agents
 %description resource-agents
 Resource agents for monitoring and managing Ceph daemons
@@ -406,6 +414,24 @@ Obsoletes:	ceph-devel < %{epoch}:%{version}-%{release}
 This package contains libraries and headers needed to develop programs
 that use RADOS object store.
 
+%package -n librgw2
+Summary:	RADOS gateway client library
+Group:		System Environment/Libraries
+License:	LGPL-2.0
+Requires:	librados2 = %{epoch}:%{version}-%{release}
+%description -n librgw2
+This package provides a library implementation of the RADOS gateway
+(distributed object store with S3 and Swift personalities).
+
+%package -n librgw2-devel
+Summary:	RADOS gateway client library
+Group:		Development/Libraries
+License:	LGPL-2.0
+Requires:	librados2 = %{epoch}:%{version}-%{release}
+%description -n librgw2-devel
+This package contains libraries and headers needed to develop programs
+that use RADOS gateway client library.
+
 %package -n python-rados
 Summary:	Python libraries for the RADOS object store
 Group:		System Environment/Libraries
@@ -564,7 +590,7 @@ This package contains the Java libraries for the Ceph File System.
 %package selinux
 Summary:	SELinux support for Ceph MON, OSD and MDS
 Group:		System Environment/Base
-Requires:	%{name}
+Requires:	ceph-base = %{epoch}:%{version}-%{release}
 Requires:	policycoreutils, libselinux-utils
 Requires(post): selinux-policy-base >= %{_selinux_policy_version}, policycoreutils, gawk
 Requires(postun): policycoreutils
@@ -601,7 +627,6 @@ Summary:	Compatibility package for Ceph headers
 Group:		Development/Libraries
 License:	LGPL-2.0
 Obsoletes:	ceph-devel
-Requires:	%{name} = %{epoch}:%{version}-%{release}
 Requires:	librados2-devel = %{epoch}:%{version}-%{release}
 Requires:	libradosstriper1-devel = %{epoch}:%{version}-%{release}
 Requires:	librbd1-devel = %{epoch}:%{version}-%{release}
@@ -733,11 +758,13 @@ install -m 0644 -D etc/sysconfig/ceph $RPM_BUILD_ROOT%{_localstatedir}/adm/fillu
   install -m 0644 -D systemd/ceph-create-keys at .service $RPM_BUILD_ROOT%{_unitdir}/ceph-create-keys at .service
   install -m 0644 -D systemd/ceph-mds at .service $RPM_BUILD_ROOT%{_unitdir}/ceph-mds at .service
   install -m 0644 -D systemd/ceph-radosgw at .service $RPM_BUILD_ROOT%{_unitdir}/ceph-radosgw at .service
+  install -m 0644 -D systemd/ceph-rbd-mirror at .service $RPM_BUILD_ROOT%{_unitdir}/ceph-rbd-mirror at .service
   install -m 0644 -D systemd/ceph.target $RPM_BUILD_ROOT%{_unitdir}/ceph.target
   install -m 0644 -D systemd/ceph-osd.target $RPM_BUILD_ROOT%{_unitdir}/ceph-osd.target
   install -m 0644 -D systemd/ceph-mon.target $RPM_BUILD_ROOT%{_unitdir}/ceph-mon.target
   install -m 0644 -D systemd/ceph-mds.target $RPM_BUILD_ROOT%{_unitdir}/ceph-mds.target
   install -m 0644 -D systemd/ceph-radosgw.target $RPM_BUILD_ROOT%{_unitdir}/ceph-radosgw.target
+  install -m 0644 -D systemd/ceph-rbd-mirror.target $RPM_BUILD_ROOT%{_unitdir}/ceph-rbd-mirror.target
   install -m 0644 -D systemd/ceph-disk at .service $RPM_BUILD_ROOT%{_unitdir}/ceph-disk at .service
   install -m 0755 -D systemd/ceph $RPM_BUILD_ROOT%{_sbindir}/rcceph
 %else
@@ -942,6 +969,9 @@ rm -rf $RPM_BUILD_ROOT
 %{_bindir}/ceph-rbdnamer
 %{_bindir}/ceph-syn
 %{_bindir}/ceph-crush-location
+%{_bindir}/cephfs-data-scan
+%{_bindir}/cephfs-journal-tool
+%{_bindir}/cephfs-table-tool
 %{_bindir}/rados
 %{_bindir}/rbd
 %{_bindir}/rbd-replay
@@ -1018,9 +1048,6 @@ fi
 #################################################################################
 %files mds
 %{_bindir}/ceph-mds
-%{_bindir}/cephfs-journal-tool
-%{_bindir}/cephfs-table-tool
-%{_bindir}/cephfs-data-scan
 %{_mandir}/man8/ceph-mds.8*
 %if 0%{?_with_systemd}
 %{_unitdir}/ceph-mds at .service
@@ -1067,6 +1094,10 @@ fi
 %defattr(-,root,root,-)
 %{_bindir}/rbd-mirror
 %{_mandir}/man8/rbd-mirror.8*
+%if 0%{?_with_systemd}
+%{_unitdir}/ceph-rbd-mirror at .service
+%{_unitdir}/ceph-rbd-mirror.target
+%endif
 
 #################################################################################
 %files -n rbd-nbd
@@ -1079,6 +1110,7 @@ fi
 %defattr(-,root,root,-)
 %{_bindir}/radosgw
 %{_bindir}/radosgw-admin
+%{_bindir}/radosgw-token
 %{_bindir}/radosgw-object-expirer
 %{_mandir}/man8/radosgw.8*
 %{_mandir}/man8/radosgw-admin.8*
@@ -1161,12 +1193,27 @@ fi
 
 #################################################################################
 %if %{with ocf}
+
 %files resource-agents
 %defattr(0755,root,root,-)
-%dir /usr/lib/ocf
-%dir /usr/lib/ocf/resource.d
-%dir /usr/lib/ocf/resource.d/ceph
-/usr/lib/ocf/resource.d/%{name}/*
+# N.B. src/ocf/Makefile.am uses $(prefix)/lib
+%dir %{_prefix}/lib/ocf
+%dir %{_prefix}/lib/ocf/resource.d
+%dir %{_prefix}/lib/ocf/resource.d/ceph
+%if 0%{_with_systemd}
+%exclude %{_prefix}/lib/ocf/resource.d/ceph/ceph
+%exclude %{_prefix}/lib/ocf/resource.d/ceph/mds
+%exclude %{_prefix}/lib/ocf/resource.d/ceph/mon
+%exclude %{_prefix}/lib/ocf/resource.d/ceph/osd
+%endif
+%if ! 0%{_with_systemd}
+%{_prefix}/lib/ocf/resource.d/ceph/ceph
+%{_prefix}/lib/ocf/resource.d/ceph/mds
+%{_prefix}/lib/ocf/resource.d/ceph/mon
+%{_prefix}/lib/ocf/resource.d/ceph/osd
+%endif
+%{_prefix}/lib/ocf/resource.d/ceph/rbd
+
 %endif
 
 #################################################################################
@@ -1206,7 +1253,8 @@ fi
 #################################################################################
 %files -n python-rados
 %defattr(-,root,root,-)
-%{python_sitelib}/rados.py*
+%{python_sitearch}/rados.so
+%{python_sitearch}/rados-*.egg-info
 
 #################################################################################
 %files -n libradosstriper1
@@ -1256,6 +1304,25 @@ ln -sf %{_libdir}/librbd.so.1 /usr/lib64/qemu/librbd.so.1
 %endif
 
 #################################################################################
+%files -n librgw2
+%defattr(-,root,root,-)
+%{_libdir}/librgw.so.*
+
+%post -n librgw2
+/sbin/ldconfig
+
+%postun -n librgw2
+/sbin/ldconfig
+
+#################################################################################
+%files -n librgw2-devel
+%defattr(-,root,root,-)
+%dir %{_includedir}/rados
+%{_includedir}/rados/librgw.h
+%{_includedir}/rados/rgw_file.h
+%{_libdir}/librgw.so
+
+#################################################################################
 %files -n python-rbd
 %defattr(-,root,root,-)
 %{python_sitearch}/rbd.so
@@ -1282,7 +1349,8 @@ ln -sf %{_libdir}/librbd.so.1 /usr/lib64/qemu/librbd.so.1
 #################################################################################
 %files -n python-cephfs
 %defattr(-,root,root,-)
-%{python_sitelib}/cephfs.py*
+%{python_sitearch}/cephfs.so
+%{python_sitearch}/cephfs-*.egg-info
 %{python_sitelib}/ceph_volume_client.py*
 
 #################################################################################
@@ -1310,6 +1378,7 @@ ln -sf %{_libdir}/librbd.so.1 /usr/lib64/qemu/librbd.so.1
 %{_bindir}/ceph_smalliobenchfs
 %{_bindir}/ceph_smalliobenchrbd
 %{_bindir}/ceph_test_*
+%{_bindir}/librgw_file*
 %{_bindir}/ceph_tpbench
 %{_bindir}/ceph_xattr_bench
 %{_bindir}/ceph-coverage
diff --git a/src/test/osd/TestOSDMap.cc b/src/test/osd/TestOSDMap.cc
index ea4053f..0b50b32 100644
--- a/src/test/osd/TestOSDMap.cc
+++ b/src/test/osd/TestOSDMap.cc
@@ -103,21 +103,21 @@ TEST_F(OSDMapTest, Features) {
   uint64_t features = osdmap.get_features(CEPH_ENTITY_TYPE_OSD, NULL);
   ASSERT_TRUE(features & CEPH_FEATURE_CRUSH_TUNABLES);
   ASSERT_TRUE(features & CEPH_FEATURE_CRUSH_TUNABLES2);
-  ASSERT_FALSE(features & CEPH_FEATURE_CRUSH_TUNABLES3);
+  ASSERT_TRUE(features & CEPH_FEATURE_CRUSH_TUNABLES3);
   ASSERT_TRUE(features & CEPH_FEATURE_CRUSH_V2);
   ASSERT_TRUE(features & CEPH_FEATURE_OSD_ERASURE_CODES);
   ASSERT_TRUE(features & CEPH_FEATURE_OSDHASHPSPOOL);
-  ASSERT_FALSE(features & CEPH_FEATURE_OSD_PRIMARY_AFFINITY);
+  ASSERT_TRUE(features & CEPH_FEATURE_OSD_PRIMARY_AFFINITY);
 
   // clients have a slightly different view
   features = osdmap.get_features(CEPH_ENTITY_TYPE_CLIENT, NULL);
   ASSERT_TRUE(features & CEPH_FEATURE_CRUSH_TUNABLES);
   ASSERT_TRUE(features & CEPH_FEATURE_CRUSH_TUNABLES2);
-  ASSERT_FALSE(features & CEPH_FEATURE_CRUSH_TUNABLES3);
+  ASSERT_TRUE(features & CEPH_FEATURE_CRUSH_TUNABLES3);
   ASSERT_TRUE(features & CEPH_FEATURE_CRUSH_V2);
   ASSERT_FALSE(features & CEPH_FEATURE_OSD_ERASURE_CODES);  // dont' need this
   ASSERT_TRUE(features & CEPH_FEATURE_OSDHASHPSPOOL);
-  ASSERT_FALSE(features & CEPH_FEATURE_OSD_PRIMARY_AFFINITY);
+  ASSERT_TRUE(features & CEPH_FEATURE_OSD_PRIMARY_AFFINITY);
 
   // remove teh EC pool, but leave the rule.  add primary affinity.
   {
diff --git a/src/test/osd/TestPGLog.cc b/src/test/osd/TestPGLog.cc
index f3c6121..34d1313 100644
--- a/src/test/osd/TestPGLog.cc
+++ b/src/test/osd/TestPGLog.cc
@@ -29,6 +29,7 @@
 
 class PGLogTest : public ::testing::Test, protected PGLog {
 public:
+  PGLogTest() : PGLog(g_ceph_context) {}
   virtual void SetUp() { }
 
   virtual void TearDown() {
@@ -165,6 +166,9 @@ public:
       const hobject_t &hoid) {
       removed.insert(hoid);
     }
+    void try_stash(const hobject_t &, version_t) override {
+      // lost/unfound cases are not tested yet
+    }
     void trim(
       const pg_log_entry_t &entry) {}
   };
@@ -274,6 +278,9 @@ struct TestHandler : public PGLog::LogEntryHandler {
     removed.push_back(hoid);
   }
   void cant_rollback(const pg_log_entry_t &entry) {}
+  void try_stash(const hobject_t &, version_t) override {
+    // lost/unfound cases are not tested yet
+  }
   void trim(
     const pg_log_entry_t &entry) {}
 };
diff --git a/src/test/osd/TestRados.cc b/src/test/osd/TestRados.cc
index f35b987..1833828 100644
--- a/src/test/osd/TestRados.cc
+++ b/src/test/osd/TestRados.cc
@@ -54,6 +54,13 @@ public:
     if (m_op <= m_objects) {
       stringstream oid;
       oid << m_op;
+      if (m_op % 2) {
+	// make it a long name
+	oid << " ";
+	for (unsigned i = 0; i < 300; ++i) {
+	  oid << i;
+	}
+      }
       cout << m_op << ": write initial oid " << oid.str() << std::endl;
       context.oid_not_flushing.insert(oid.str());
       if (m_ec_pool) {
diff --git a/src/test/osd/osd-markdown.sh b/src/test/osd/osd-markdown.sh
index 4dfa78d..7db2cb0 100755
--- a/src/test/osd/osd-markdown.sh
+++ b/src/test/osd/osd-markdown.sh
@@ -38,8 +38,7 @@ function run() {
 function markdown_N_impl() {
   markdown_times=$1
   total_time=$2
-  interval=$(($total_time / markdown_times))
-  sleep 10
+  sleeptime=$3
   for i in `seq 1 $markdown_times`
   do
     # check the OSD is UP
@@ -47,7 +46,7 @@ function markdown_N_impl() {
     ./ceph osd tree | grep osd.0 |grep up || return 1
     # mark the OSD down.
     ./ceph osd down 0
-    sleep $interval
+    sleep $sleeptime
   done
 }
 
@@ -59,13 +58,14 @@ function TEST_markdown_exceed_maxdown_count() {
     run_osd $dir 0 || return 1
     run_osd $dir 1 || return 1
     run_osd $dir 2 || return 1
-    local count=5
-    local period=40
+    # 3+1 times within 120s, osd should stay dead on the 4th time
+    local count=3
+    local sleeptime=10
+    local period=120
     ceph tell osd.0 injectargs '--osd_max_markdown_count '$count'' || return 1
     ceph tell osd.0 injectargs '--osd_max_markdown_period '$period'' || return 1
 
-    markdown_N_impl $(($count+1)) $period
-    # down N+1 times ,the osd.0 shoud die
+    markdown_N_impl $(($count+1)) $period $sleeptime
     ./ceph osd tree | grep down | grep osd.0 || return 1
 }
 
@@ -77,12 +77,14 @@ function TEST_markdown_boot() {
     run_osd $dir 1 || return 1
     run_osd $dir 2 || return 1
 
-    local count=5
-    local period=40
+    # 3 times within 120s, should stay up
+    local count=3
+    local sleeptime=10
+    local period=120
     ceph tell osd.0 injectargs '--osd_max_markdown_count '$count'' || return 1
     ceph tell osd.0 injectargs '--osd_max_markdown_period '$period'' || return 1
 
-    markdown_N_impl $count $period
+    markdown_N_impl $count $period $sleeptime
     #down N times, osd.0 should be up
     ./ceph osd tree | grep up | grep osd.0 || return 1
 }
@@ -95,13 +97,15 @@ function TEST_markdown_boot_exceed_time() {
     run_osd $dir 1 || return 1
     run_osd $dir 2 || return 1
 
-    local count=5
-    local period=40
+    
+    # 3+1 times, but over 40s, > 20s, so should stay up
+    local count=3
+    local period=20
+    local sleeptime=10
     ceph tell osd.0 injectargs '--osd_max_markdown_count '$count'' || return 1
     ceph tell osd.0 injectargs '--osd_max_markdown_period '$period'' || return 1
 
-    #actually we will down 6 times in 60s, so the 5th down will be in 50s > period
-    markdown_N_impl $(($count+1)) $(($period + 20))
+    markdown_N_impl $(($count+1)) $period $sleeptime
     ./ceph osd tree | grep up | grep osd.0 || return 1
 }
 
diff --git a/src/test/osd/types.cc b/src/test/osd/types.cc
index ca1e56a..907d306 100644
--- a/src/test/osd/types.cc
+++ b/src/test/osd/types.cc
@@ -1442,15 +1442,15 @@ TEST(ghobject_t, parse) {
   const char *v[] = {
     "GHMIN",
     "GHMAX",
-    "13 at 0:00000000::::head@",
-    "13 at 0:00000000::::head at deadbeef",
-    "@-1:60c2fa6d:::inc_osdmap.1:333 at deadbeef",
-    "@-1:60c2fa6d:::inc%02osdmap.1:333 at deadbeef",
-    "@-1:60c2fa6d:::inc_osdmap.1:333@",
-    "1 at MIN@deadbeefff",
-    "1 at MAX@",
-    "@MAX at 123",
-    "@-40:00000000:nspace::obj:head@",
+    "13#0:00000000::::head#",
+    "13#0:00000000::::head#deadbeef",
+    "#-1:60c2fa6d:::inc_osdmap.1:333#deadbeef",
+    "#-1:60c2fa6d:::inc%02osdmap.1:333#deadbeef",
+    "#-1:60c2fa6d:::inc_osdmap.1:333#",
+    "1#MIN#deadbeefff",
+    "1#MAX#",
+    "#MAX#123",
+    "#-40:00000000:nspace::obj:head#",
     NULL
   };
 
diff --git a/src/test/pybind/test_ceph_argparse.py b/src/test/pybind/test_ceph_argparse.py
index 7c96881..a649731 100755
--- a/src/test/pybind/test_ceph_argparse.py
+++ b/src/test/pybind/test_ceph_argparse.py
@@ -380,17 +380,6 @@ class TestMDS(TestArgparse):
     def test_set_max_mds(self):
         self.check_1_natural_arg('mds', 'set_max_mds')
 
-    def test_setmap(self):
-        self.assert_valid_command(['mds', 'setmap', '1'])
-        self.assert_valid_command(['mds', 'setmap', '1', '--yes-i-really-mean-it'])
-        assert_equal({}, validate_command(sigdict, ['mds', 'setmap',
-                                                    '--yes-i-really-mean-it']))
-        assert_equal({}, validate_command(sigdict, ['mds', 'setmap', '-1',
-                                                    '--yes-i-really-mean-it']))
-        assert_equal({}, validate_command(sigdict, ['mds', 'setmap', '1',
-                                                    '--yes-i-really-mean-it',
-                                                    'toomany']))
-
     def test_set_state(self):
         self.assert_valid_command(['mds', 'set_state', '1', '2'])
         assert_equal({}, validate_command(sigdict, ['mds', 'set_state']))
@@ -415,10 +404,6 @@ class TestMDS(TestArgparse):
     def test_rmfailed(self):
         self.assert_valid_command(['mds', 'rmfailed', '0'])
         self.assert_valid_command(['mds', 'rmfailed', '0', '--yes-i-really-mean-it'])
-        assert_equal({}, validate_command(sigdict, ['mds', 'rmfailed',
-                                                    '--yes-i-really-mean-it']))
-        assert_equal({}, validate_command(sigdict, ['mds', 'rmfailed', '-1',
-                                                    '--yes-i-really-mean-it']))
         assert_equal({}, validate_command(sigdict, ['mds', 'rmfailed', '0',
                                                     '--yes-i-really-mean-it',
                                                     'toomany']))
@@ -1111,9 +1096,8 @@ class TestOSD(TestArgparse):
     def test_reweight_by_utilization(self):
         self.assert_valid_command(['osd', 'reweight-by-utilization'])
         self.assert_valid_command(['osd', 'reweight-by-utilization', '100'])
-        assert_equal({}, validate_command(sigdict, ['osd',
-                                                    'reweight-by-utilization',
-                                                    '50']))
+		self.assert_valid_command(['osd', 'reweight-by-utilization', '100', '.1'])
+        self.assert_valid_command(['osd', 'reweight-by-utilization', '--no-increasing'])
         assert_equal({}, validate_command(sigdict, ['osd',
                                                     'reweight-by-utilization',
                                                     '100',
diff --git a/src/test/pybind/test_ceph_daemon.py b/src/test/pybind/test_ceph_daemon.py
index a95c8fc..4fb68f7 100755
--- a/src/test/pybind/test_ceph_daemon.py
+++ b/src/test/pybind/test_ceph_daemon.py
@@ -11,12 +11,15 @@ License version 2, as published by the Free Software
 Foundation.  See file COPYING.
 """
 
-from StringIO import StringIO
-
 from unittest import TestCase
 
 from ceph_daemon import DaemonWatcher
 
+try:
+    from StringIO import StringIO
+except ImportError:
+    from io import StringIO
+
 
 class TestDaemonWatcher(TestCase):
     def test_format(self):
diff --git a/src/test/rbd_mirror/image_replay.cc b/src/test/rbd_mirror/image_replay.cc
new file mode 100644
index 0000000..87d4497
--- /dev/null
+++ b/src/test/rbd_mirror/image_replay.cc
@@ -0,0 +1,224 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+
+#include "common/ceph_argparse.h"
+#include "common/config.h"
+#include "common/debug.h"
+#include "common/errno.h"
+#include "global/global_init.h"
+#include "global/signal_handler.h"
+#include "librbd/ImageCtx.h"
+#include "librbd/ImageState.h"
+#include "tools/rbd_mirror/ImageReplayer.h"
+#include "tools/rbd_mirror/Threads.h"
+
+#include <string>
+#include <vector>
+
+#define dout_subsys ceph_subsys_rbd_mirror
+#undef dout_prefix
+#define dout_prefix *_dout << "rbd-mirror-image-replay: "
+
+rbd::mirror::ImageReplayer *replayer = nullptr;
+
+void usage() {
+  std::cout << "usage: ceph_test_rbd_mirror_image_replay [options...] \\" << std::endl;
+  std::cout << "           <client-id> <local-pool> <remote-pool> <image>" << std::endl;
+  std::cout << std::endl;
+  std::cout << "  client-id     client ID to register in remote journal" << std::endl;
+  std::cout << "  local-pool    local (secondary, destination) pool" << std::endl;
+  std::cout << "  remote-pool   remote (primary, source) pool" << std::endl;
+  std::cout << "  image         image to replay (mirror)" << std::endl;
+  std::cout << std::endl;
+  std::cout << "options:\n";
+  std::cout << "  -m monaddress[:port]      connect to specified monitor\n";
+  std::cout << "  --keyring=<path>          path to keyring for local cluster\n";
+  std::cout << "  --log-file=<logfile>      file to log debug output\n";
+  std::cout << "  --debug-rbd-mirror=<log-level>/<memory-level>  set rbd-mirror debug level\n";
+  generic_server_usage();
+}
+
+static atomic_t g_stopping;
+
+static void handle_signal(int signum)
+{
+  g_stopping.set(1);
+}
+
+int get_image_id(rbd::mirror::RadosRef cluster, int64_t pool_id,
+		 const std::string &image_name, std::string *image_id)
+{
+  librados::IoCtx ioctx;
+
+  int r = cluster->ioctx_create2(pool_id, ioctx);
+  if (r < 0) {
+    derr << "error opening ioctx for pool " << pool_id
+	 << ": " << cpp_strerror(r) << dendl;
+    return r;
+  }
+
+  librbd::ImageCtx *image_ctx = new librbd::ImageCtx(image_name, "", NULL,
+						     ioctx, true);
+  r = image_ctx->state->open();
+  if (r < 0) {
+    derr << "error opening remote image " << image_name
+	 << ": " << cpp_strerror(r) << dendl;
+    delete image_ctx;
+    return r;
+  }
+
+  *image_id = image_ctx->id;
+  image_ctx->state->close();
+  return 0;
+}
+
+int main(int argc, const char **argv)
+{
+  std::vector<const char*> args;
+  argv_to_vec(argc, argv, args);
+  env_to_vec(args);
+
+  global_init(nullptr, args, CEPH_ENTITY_TYPE_CLIENT,
+	      CODE_ENVIRONMENT_DAEMON,
+	      CINIT_FLAG_UNPRIVILEGED_DAEMON_DEFAULTS);
+
+  for (auto i = args.begin(); i != args.end(); ++i) {
+    if (ceph_argparse_flag(args, i, "-h", "--help", (char*)NULL)) {
+      usage();
+      return EXIT_SUCCESS;
+    }
+  }
+
+  if (args.size() < 4) {
+    usage();
+    return EXIT_FAILURE;
+  }
+
+  std::string client_id = args[0];
+  std::string local_pool_name = args[1];
+  std::string remote_pool_name = args[2];
+  std::string image_name = args[3];
+
+  dout(1) << "client_id=" << client_id << ", local_pool_name="
+	  << local_pool_name << ", remote_pool_name=" << remote_pool_name
+	  << ", image_name=" << image_name << dendl;
+
+  rbd::mirror::ImageReplayer::BootstrapParams bootstap_params(local_pool_name,
+							      image_name);
+  int64_t local_pool_id;
+  int64_t remote_pool_id;
+  std::string remote_image_id;
+
+  if (local_pool_name == remote_pool_name) {
+    std::cerr << "local and remote pools can't be the same" << std::endl;
+    return EXIT_FAILURE;
+  }
+
+  if (g_conf->daemonize) {
+    global_init_daemonize(g_ceph_context);
+  }
+  g_ceph_context->enable_perf_counter();
+
+  common_init_finish(g_ceph_context);
+
+  init_async_signal_handler();
+  register_async_signal_handler(SIGHUP, sighup_handler);
+  register_async_signal_handler_oneshot(SIGINT, handle_signal);
+  register_async_signal_handler_oneshot(SIGTERM, handle_signal);
+
+  dout(5) << "connecting to cluster" << dendl;
+
+  rbd::mirror::RadosRef local(new librados::Rados());
+  rbd::mirror::RadosRef remote(new librados::Rados());
+  rbd::mirror::Threads *threads = nullptr;
+
+  C_SaferCond start_cond, stop_cond;
+
+  int r = local->init_with_context(g_ceph_context);
+  if (r < 0) {
+    derr << "could not initialize rados handle" << dendl;
+    goto cleanup;
+  }
+
+  r = local->connect();
+  if (r < 0) {
+    derr << "error connecting to local cluster" << dendl;
+    goto cleanup;
+  }
+
+  r = local->pool_lookup(local_pool_name.c_str());
+  if (r < 0) {
+    derr << "error finding local pool " << local_pool_name
+	 << ": " << cpp_strerror(r) << dendl;
+    goto cleanup;
+  }
+  local_pool_id = r;
+
+  r = remote->init_with_context(g_ceph_context);
+  if (r < 0) {
+    derr << "could not initialize rados handle" << dendl;
+    goto cleanup;
+  }
+
+  r = remote->connect();
+  if (r < 0) {
+    derr << "error connecting to local cluster" << dendl;
+    goto cleanup;
+  }
+
+  r = remote->pool_lookup(remote_pool_name.c_str());
+  if (r < 0) {
+    derr << "error finding remote pool " << remote_pool_name
+	 << ": " << cpp_strerror(r) << dendl;
+    goto cleanup;
+  }
+  remote_pool_id = r;
+
+  r = get_image_id(remote, remote_pool_id, image_name, &remote_image_id);
+  if (r < 0) {
+    derr << "error resolving ID for remote image " << image_name
+	 << ": " << cpp_strerror(r) << dendl;
+    goto cleanup;
+  }
+
+  dout(5) << "starting replay" << dendl;
+
+  threads = new rbd::mirror::Threads(reinterpret_cast<CephContext*>(
+    local->cct()));
+  replayer = new rbd::mirror::ImageReplayer(threads, local, remote, client_id,
+					    local_pool_id, remote_pool_id,
+					    remote_image_id);
+
+  replayer->start(&start_cond, &bootstap_params);
+  r = start_cond.wait();
+  if (r < 0) {
+    derr << "failed to start: " << cpp_strerror(r) << dendl;
+    goto cleanup;
+  }
+
+  dout(5) << "replay started" << dendl;
+
+  while (!g_stopping.read()) {
+    usleep(200000);
+  }
+
+  dout(1) << "termination signal received, stopping replay" << dendl;
+
+  replayer->stop(&stop_cond);
+  r = stop_cond.wait();
+  assert(r == 0);
+
+  dout(1) << "shutdown" << dendl;
+
+ cleanup:
+  unregister_async_signal_handler(SIGHUP, sighup_handler);
+  unregister_async_signal_handler(SIGINT, handle_signal);
+  unregister_async_signal_handler(SIGTERM, handle_signal);
+  shutdown_async_signal_handler();
+
+  delete replayer;
+  delete threads;
+  g_ceph_context->put();
+
+  return r < 0 ? EXIT_SUCCESS : EXIT_FAILURE;
+}
diff --git a/src/test/rbd_mirror/image_sync/test_mock_ImageCopyRequest.cc b/src/test/rbd_mirror/image_sync/test_mock_ImageCopyRequest.cc
new file mode 100644
index 0000000..ff3584e
--- /dev/null
+++ b/src/test/rbd_mirror/image_sync/test_mock_ImageCopyRequest.cc
@@ -0,0 +1,451 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+
+#include "test/rbd_mirror/test_mock_fixture.h"
+#include "include/rbd/librbd.hpp"
+#include "librbd/ImageCtx.h"
+#include "librbd/ImageState.h"
+#include "librbd/Operations.h"
+#include "test/librados_test_stub/MockTestMemIoCtxImpl.h"
+#include "test/librbd/mock/MockImageCtx.h"
+#include "test/rbd_mirror/mock/MockJournaler.h"
+#include "tools/rbd_mirror/image_sync/ImageCopyRequest.h"
+#include "tools/rbd_mirror/image_sync/ObjectCopyRequest.h"
+#include "tools/rbd_mirror/Threads.h"
+#include <boost/scope_exit.hpp>
+
+namespace rbd {
+namespace mirror {
+namespace image_sync {
+
+template <>
+struct ObjectCopyRequest<librbd::MockImageCtx> {
+  static ObjectCopyRequest* s_instance;
+  static ObjectCopyRequest* create(librbd::MockImageCtx *local_image_ctx,
+                                   librbd::MockImageCtx *remote_image_ctx,
+                                   const ImageCopyRequest<librbd::MockImageCtx>::SnapMap *snap_map,
+                                   uint64_t object_number, Context *on_finish) {
+    assert(s_instance != nullptr);
+    Mutex::Locker locker(s_instance->lock);
+    s_instance->snap_map = snap_map;
+    s_instance->object_contexts[object_number] = on_finish;
+    s_instance->cond.Signal();
+    return s_instance;
+  }
+
+  MOCK_METHOD0(send, void());
+
+  Mutex lock;
+  Cond cond;
+
+  const ImageCopyRequest<librbd::MockImageCtx>::SnapMap *snap_map;
+  std::map<uint64_t, Context *> object_contexts;
+
+  ObjectCopyRequest() : lock("lock") {
+    s_instance = this;
+  }
+};
+
+ObjectCopyRequest<librbd::MockImageCtx>* ObjectCopyRequest<librbd::MockImageCtx>::s_instance = nullptr;
+
+} // namespace image_sync
+} // namespace mirror
+} // namespace rbd
+
+// template definitions
+#include "tools/rbd_mirror/image_sync/ImageCopyRequest.cc"
+template class rbd::mirror::image_sync::ImageCopyRequest<librbd::MockImageCtx>;
+
+namespace rbd {
+namespace mirror {
+namespace image_sync {
+
+using ::testing::_;
+using ::testing::InSequence;
+using ::testing::Invoke;
+using ::testing::Return;
+using ::testing::WithArg;
+
+class TestMockImageSyncImageCopyRequest : public TestMockFixture {
+public:
+  typedef ImageCopyRequest<librbd::MockImageCtx> MockImageCopyRequest;
+  typedef ObjectCopyRequest<librbd::MockImageCtx> MockObjectCopyRequest;
+
+  virtual void SetUp() {
+    TestMockFixture::SetUp();
+
+    librbd::RBD rbd;
+    ASSERT_EQ(0, create_image(rbd, m_remote_io_ctx, m_image_name, m_image_size));
+    ASSERT_EQ(0, open_image(m_remote_io_ctx, m_image_name, &m_remote_image_ctx));
+
+    ASSERT_EQ(0, create_image(rbd, m_local_io_ctx, m_image_name, m_image_size));
+    ASSERT_EQ(0, open_image(m_local_io_ctx, m_image_name, &m_local_image_ctx));
+  }
+
+  void expect_get_snap_id(librbd::MockImageCtx &mock_image_ctx) {
+    EXPECT_CALL(mock_image_ctx, get_snap_id(_))
+      .WillRepeatedly(Invoke([&mock_image_ctx](std::string snap_name) {
+        RWLock::RLocker snap_locker(mock_image_ctx.image_ctx->snap_lock);
+        return mock_image_ctx.image_ctx->get_snap_id(snap_name);
+      }));
+  }
+
+  void expect_get_object_count(librbd::MockImageCtx &mock_image_ctx,
+                               uint64_t count) {
+    EXPECT_CALL(mock_image_ctx, get_object_count(_))
+      .WillOnce(Return(count)).RetiresOnSaturation();
+  }
+
+  void expect_update_client(journal::MockJournaler &mock_journaler, int r) {
+    EXPECT_CALL(mock_journaler, update_client(_, _))
+      .WillOnce(WithArg<1>(CompleteContext(r)));
+  }
+
+  void expect_object_copy_send(MockObjectCopyRequest &mock_object_copy_request) {
+    EXPECT_CALL(mock_object_copy_request, send());
+  }
+
+  bool complete_object_copy(MockObjectCopyRequest &mock_object_copy_request,
+                            uint64_t object_num, int r) {
+    Mutex::Locker locker(mock_object_copy_request.lock);
+    while (mock_object_copy_request.object_contexts.count(object_num) == 0) {
+      if (mock_object_copy_request.cond.WaitInterval(m_local_image_ctx->cct,
+                                                     mock_object_copy_request.lock,
+                                                     utime_t(10, 0)) != 0) {
+        return false;
+      }
+    }
+
+    m_threads->work_queue->queue(mock_object_copy_request.object_contexts[object_num], r);
+    return true;
+  }
+
+  MockImageCopyRequest::SnapMap wait_for_snap_map(MockObjectCopyRequest &mock_object_copy_request) {
+    Mutex::Locker locker(mock_object_copy_request.lock);
+    while (mock_object_copy_request.snap_map == nullptr) {
+      if (mock_object_copy_request.cond.WaitInterval(m_local_image_ctx->cct,
+                                                     mock_object_copy_request.lock,
+                                                     utime_t(10, 0)) != 0) {
+        return MockImageCopyRequest::SnapMap();
+      }
+    }
+    return *mock_object_copy_request.snap_map;
+  }
+
+  MockImageCopyRequest *create_request(librbd::MockImageCtx &mock_remote_image_ctx,
+                                       librbd::MockImageCtx &mock_local_image_ctx,
+                                       journal::MockJournaler &mock_journaler,
+                                       librbd::journal::MirrorPeerSyncPoint &sync_point,
+                                       Context *ctx) {
+    return new MockImageCopyRequest(&mock_local_image_ctx,
+                                    &mock_remote_image_ctx,
+                                    m_threads->timer, &m_threads->timer_lock,
+                                    &mock_journaler, &m_client_meta,
+                                    &sync_point, ctx);
+  }
+
+  using TestFixture::create_snap;
+  int create_snap(const char* snap_name) {
+    librados::snap_t remote_snap_id;
+    int r = create_snap(m_remote_image_ctx, snap_name, &remote_snap_id);
+    if (r < 0) {
+      return r;
+    }
+
+    librados::snap_t local_snap_id;
+    r = create_snap(m_local_image_ctx, snap_name, &local_snap_id);
+    if (r < 0) {
+      return r;
+    }
+
+    // collection of all existing snaps in local image
+    MockImageCopyRequest::SnapIds local_snap_ids({local_snap_id});
+    if (!m_snap_map.empty()) {
+      local_snap_ids.insert(local_snap_ids.end(),
+                            m_snap_map.rbegin()->second.begin(),
+                            m_snap_map.rbegin()->second.end());
+    }
+    m_snap_map[remote_snap_id] = local_snap_ids;
+    m_client_meta.snap_seqs[remote_snap_id] = local_snap_id;
+    return 0;
+  }
+
+  librbd::ImageCtx *m_remote_image_ctx;
+  librbd::ImageCtx *m_local_image_ctx;
+  librbd::journal::MirrorPeerClientMeta m_client_meta;
+  MockImageCopyRequest::SnapMap m_snap_map;
+};
+
+TEST_F(TestMockImageSyncImageCopyRequest, SimpleImage) {
+  ASSERT_EQ(0, create_snap("snap1"));
+  m_client_meta.sync_points = {{"snap1", boost::none}};
+
+  librbd::MockImageCtx mock_remote_image_ctx(*m_remote_image_ctx);
+  librbd::MockImageCtx mock_local_image_ctx(*m_local_image_ctx);
+  journal::MockJournaler mock_journaler;
+  MockObjectCopyRequest mock_object_copy_request;
+
+  expect_get_snap_id(mock_remote_image_ctx);
+
+  InSequence seq;
+  expect_get_object_count(mock_remote_image_ctx, 1);
+  expect_get_object_count(mock_remote_image_ctx, 0);
+  expect_update_client(mock_journaler, 0);
+  expect_object_copy_send(mock_object_copy_request);
+  expect_update_client(mock_journaler, 0);
+
+  C_SaferCond ctx;
+  MockImageCopyRequest *request = create_request(mock_remote_image_ctx,
+                                                 mock_local_image_ctx,
+                                                 mock_journaler,
+                                                 m_client_meta.sync_points.front(),
+                                                 &ctx);
+  request->send();
+
+  ASSERT_EQ(m_snap_map, wait_for_snap_map(mock_object_copy_request));
+  ASSERT_TRUE(complete_object_copy(mock_object_copy_request, 0, 0));
+  ASSERT_EQ(0, ctx.wait());
+}
+
+TEST_F(TestMockImageSyncImageCopyRequest, Throttled) {
+  ASSERT_EQ(0, create_snap("snap1"));
+  m_client_meta.sync_points = {{"snap1", boost::none}};
+
+  librbd::MockImageCtx mock_remote_image_ctx(*m_remote_image_ctx);
+  librbd::MockImageCtx mock_local_image_ctx(*m_local_image_ctx);
+  journal::MockJournaler mock_journaler;
+  MockObjectCopyRequest mock_object_copy_request;
+
+  expect_get_snap_id(mock_remote_image_ctx);
+
+  InSequence seq;
+  expect_get_object_count(mock_remote_image_ctx, 50);
+  expect_get_object_count(mock_remote_image_ctx, 0);
+  expect_update_client(mock_journaler, 0);
+  for (int i = 0; i < 50; ++i) {
+    expect_object_copy_send(mock_object_copy_request);
+  }
+  expect_update_client(mock_journaler, 0);
+
+  C_SaferCond ctx;
+  MockImageCopyRequest *request = create_request(mock_remote_image_ctx,
+                                                 mock_local_image_ctx,
+                                                 mock_journaler,
+                                                 m_client_meta.sync_points.front(),
+                                                 &ctx);
+  request->send();
+
+  ASSERT_EQ(m_snap_map, wait_for_snap_map(mock_object_copy_request));
+  for (uint64_t i = 0; i < 50; ++i) {
+    ASSERT_TRUE(complete_object_copy(mock_object_copy_request, i, 0));
+  }
+  ASSERT_EQ(0, ctx.wait());
+}
+
+TEST_F(TestMockImageSyncImageCopyRequest, SnapshotSubset) {
+  ASSERT_EQ(0, create_snap("snap1"));
+  ASSERT_EQ(0, create_snap("snap2"));
+  ASSERT_EQ(0, create_snap("snap3"));
+  m_client_meta.sync_points = {{"snap3", "snap2", boost::none}};
+
+  librbd::MockImageCtx mock_remote_image_ctx(*m_remote_image_ctx);
+  librbd::MockImageCtx mock_local_image_ctx(*m_local_image_ctx);
+  journal::MockJournaler mock_journaler;
+  MockObjectCopyRequest mock_object_copy_request;
+
+  expect_get_snap_id(mock_remote_image_ctx);
+
+  InSequence seq;
+  expect_get_object_count(mock_remote_image_ctx, 1);
+  expect_get_object_count(mock_remote_image_ctx, 0);
+  expect_get_object_count(mock_remote_image_ctx, 1);
+  expect_get_object_count(mock_remote_image_ctx, 1);
+  expect_update_client(mock_journaler, 0);
+  expect_object_copy_send(mock_object_copy_request);
+  expect_update_client(mock_journaler, 0);
+
+  C_SaferCond ctx;
+  MockImageCopyRequest *request = create_request(mock_remote_image_ctx,
+                                                 mock_local_image_ctx,
+                                                 mock_journaler,
+                                                 m_client_meta.sync_points.front(),
+                                                 &ctx);
+  request->send();
+
+  MockImageCopyRequest::SnapMap snap_map(m_snap_map);
+  snap_map.erase(snap_map.begin());
+  ASSERT_EQ(snap_map, wait_for_snap_map(mock_object_copy_request));
+
+  ASSERT_TRUE(complete_object_copy(mock_object_copy_request, 0, 0));
+  ASSERT_EQ(0, ctx.wait());
+}
+
+TEST_F(TestMockImageSyncImageCopyRequest, RestartCatchup) {
+  ASSERT_EQ(0, create_snap("snap1"));
+  ASSERT_EQ(0, create_snap("snap2"));
+  m_client_meta.sync_points = {{"snap1", boost::none},
+                               {"snap2", "snap1", boost::none}};
+
+  librbd::MockImageCtx mock_remote_image_ctx(*m_remote_image_ctx);
+  librbd::MockImageCtx mock_local_image_ctx(*m_local_image_ctx);
+  journal::MockJournaler mock_journaler;
+  MockObjectCopyRequest mock_object_copy_request;
+
+  expect_get_snap_id(mock_remote_image_ctx);
+
+  InSequence seq;
+  expect_get_object_count(mock_remote_image_ctx, 1);
+  expect_get_object_count(mock_remote_image_ctx, 0);
+  expect_get_object_count(mock_remote_image_ctx, 0);
+  expect_update_client(mock_journaler, 0);
+  expect_object_copy_send(mock_object_copy_request);
+  expect_update_client(mock_journaler, 0);
+
+  C_SaferCond ctx;
+  MockImageCopyRequest *request = create_request(mock_remote_image_ctx,
+                                                 mock_local_image_ctx,
+                                                 mock_journaler,
+                                                 m_client_meta.sync_points.back(),
+                                                 &ctx);
+  request->send();
+
+  ASSERT_EQ(m_snap_map, wait_for_snap_map(mock_object_copy_request));
+  ASSERT_TRUE(complete_object_copy(mock_object_copy_request, 0, 0));
+  ASSERT_EQ(0, ctx.wait());
+}
+
+TEST_F(TestMockImageSyncImageCopyRequest, RestartPartialSync) {
+  ASSERT_EQ(0, create_snap("snap1"));
+  m_client_meta.sync_points = {{"snap1", librbd::journal::MirrorPeerSyncPoint::ObjectNumber{0U}}};
+
+  librbd::MockImageCtx mock_remote_image_ctx(*m_remote_image_ctx);
+  librbd::MockImageCtx mock_local_image_ctx(*m_local_image_ctx);
+  journal::MockJournaler mock_journaler;
+  MockObjectCopyRequest mock_object_copy_request;
+
+  expect_get_snap_id(mock_remote_image_ctx);
+
+  InSequence seq;
+  expect_get_object_count(mock_remote_image_ctx, 1);
+  expect_get_object_count(mock_remote_image_ctx, 2);
+  expect_update_client(mock_journaler, 0);
+  expect_object_copy_send(mock_object_copy_request);
+  expect_update_client(mock_journaler, 0);
+
+  C_SaferCond ctx;
+  MockImageCopyRequest *request = create_request(mock_remote_image_ctx,
+                                                 mock_local_image_ctx,
+                                                 mock_journaler,
+                                                 m_client_meta.sync_points.front(),
+                                                 &ctx);
+  request->send();
+
+  ASSERT_TRUE(complete_object_copy(mock_object_copy_request, 1, 0));
+  ASSERT_EQ(0, ctx.wait());
+}
+
+TEST_F(TestMockImageSyncImageCopyRequest, Cancel) {
+  std::string max_ops_str;
+  ASSERT_EQ(0, _rados.conf_get("rbd_concurrent_management_ops", max_ops_str));
+  ASSERT_EQ(0, _rados.conf_set("rbd_concurrent_management_ops", "1"));
+  BOOST_SCOPE_EXIT( (max_ops_str) ) {
+    ASSERT_EQ(0, _rados.conf_set("rbd_concurrent_management_ops", max_ops_str.c_str()));
+  } BOOST_SCOPE_EXIT_END;
+
+  ASSERT_EQ(0, create_snap("snap1"));
+  m_client_meta.sync_points = {{"snap1", boost::none}};
+
+  librbd::MockImageCtx mock_remote_image_ctx(*m_remote_image_ctx);
+  librbd::MockImageCtx mock_local_image_ctx(*m_local_image_ctx);
+  journal::MockJournaler mock_journaler;
+  MockObjectCopyRequest mock_object_copy_request;
+
+  expect_get_snap_id(mock_remote_image_ctx);
+
+  InSequence seq;
+  expect_get_object_count(mock_remote_image_ctx, 2);
+  expect_get_object_count(mock_remote_image_ctx, 2);
+  expect_update_client(mock_journaler, 0);
+  expect_object_copy_send(mock_object_copy_request);
+  expect_update_client(mock_journaler, 0);
+
+  C_SaferCond ctx;
+  MockImageCopyRequest *request = create_request(mock_remote_image_ctx,
+                                                 mock_local_image_ctx,
+                                                 mock_journaler,
+                                                 m_client_meta.sync_points.front(),
+                                                 &ctx);
+  request->send();
+
+  ASSERT_EQ(m_snap_map, wait_for_snap_map(mock_object_copy_request));
+  request->cancel();
+
+  ASSERT_TRUE(complete_object_copy(mock_object_copy_request, 0, 0));
+  ASSERT_EQ(0, ctx.wait());
+}
+
+TEST_F(TestMockImageSyncImageCopyRequest, MissingSnap) {
+  ASSERT_EQ(0, create_snap("snap1"));
+  m_client_meta.sync_points = {{"missing-snap", boost::none}};
+
+  librbd::MockImageCtx mock_remote_image_ctx(*m_remote_image_ctx);
+  librbd::MockImageCtx mock_local_image_ctx(*m_local_image_ctx);
+  journal::MockJournaler mock_journaler;
+
+  expect_get_snap_id(mock_remote_image_ctx);
+
+  C_SaferCond ctx;
+  MockImageCopyRequest *request = create_request(mock_remote_image_ctx,
+                                                 mock_local_image_ctx,
+                                                 mock_journaler,
+                                                 m_client_meta.sync_points.front(),
+                                                 &ctx);
+  request->send();
+  ASSERT_EQ(-ENOENT, ctx.wait());
+}
+
+TEST_F(TestMockImageSyncImageCopyRequest, MissingFromSnap) {
+  ASSERT_EQ(0, create_snap("snap1"));
+  m_client_meta.sync_points = {{"snap1", "missing-snap", boost::none}};
+
+  librbd::MockImageCtx mock_remote_image_ctx(*m_remote_image_ctx);
+  librbd::MockImageCtx mock_local_image_ctx(*m_local_image_ctx);
+  journal::MockJournaler mock_journaler;
+
+  expect_get_snap_id(mock_remote_image_ctx);
+
+  C_SaferCond ctx;
+  MockImageCopyRequest *request = create_request(mock_remote_image_ctx,
+                                                 mock_local_image_ctx,
+                                                 mock_journaler,
+                                                 m_client_meta.sync_points.front(),
+                                                 &ctx);
+  request->send();
+  ASSERT_EQ(-ENOENT, ctx.wait());
+}
+
+TEST_F(TestMockImageSyncImageCopyRequest, EmptySnapMap) {
+  ASSERT_EQ(0, create_snap("snap1"));
+  ASSERT_EQ(0, create_snap("snap2"));
+  m_client_meta.snap_seqs = {{0, 0}};
+  m_client_meta.sync_points = {{"snap2", "snap1", boost::none}};
+
+  librbd::MockImageCtx mock_remote_image_ctx(*m_remote_image_ctx);
+  librbd::MockImageCtx mock_local_image_ctx(*m_local_image_ctx);
+  journal::MockJournaler mock_journaler;
+
+  expect_get_snap_id(mock_remote_image_ctx);
+
+  C_SaferCond ctx;
+  MockImageCopyRequest *request = create_request(mock_remote_image_ctx,
+                                                 mock_local_image_ctx,
+                                                 mock_journaler,
+                                                 m_client_meta.sync_points.front(),
+                                                 &ctx);
+  request->send();
+  ASSERT_EQ(-EINVAL, ctx.wait());
+}
+
+} // namespace image_sync
+} // namespace mirror
+} // namespace rbd
diff --git a/src/test/rbd_mirror/image_sync/test_mock_ObjectCopyRequest.cc b/src/test/rbd_mirror/image_sync/test_mock_ObjectCopyRequest.cc
new file mode 100644
index 0000000..d99d7df
--- /dev/null
+++ b/src/test/rbd_mirror/image_sync/test_mock_ObjectCopyRequest.cc
@@ -0,0 +1,550 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+
+#include "test/rbd_mirror/test_mock_fixture.h"
+#include "include/interval_set.h"
+#include "include/rbd/librbd.hpp"
+#include "librbd/AioImageRequestWQ.h"
+#include "librbd/ImageCtx.h"
+#include "librbd/ImageState.h"
+#include "librbd/internal.h"
+#include "librbd/Operations.h"
+#include "test/librados_test_stub/MockTestMemIoCtxImpl.h"
+#include "test/librbd/mock/MockImageCtx.h"
+#include "tools/rbd_mirror/Threads.h"
+#include "tools/rbd_mirror/image_sync/ObjectCopyRequest.h"
+
+// template definitions
+#include "tools/rbd_mirror/image_sync/ObjectCopyRequest.cc"
+template class rbd::mirror::image_sync::ObjectCopyRequest<librbd::MockImageCtx>;
+
+namespace rbd {
+namespace mirror {
+namespace image_sync {
+
+using ::testing::_;
+using ::testing::DoDefault;
+using ::testing::InSequence;
+using ::testing::Invoke;
+using ::testing::Return;
+using ::testing::WithArg;
+
+namespace {
+
+void scribble(librbd::ImageCtx *image_ctx, int num_ops, size_t max_size,
+              interval_set<uint64_t> *what)
+{
+  uint64_t object_size = 1 << image_ctx->order;
+  for (int i=0; i<num_ops; i++) {
+    uint64_t off = rand() % (object_size - max_size + 1);
+    uint64_t len = 1 + rand() % max_size;
+
+    bufferlist bl;
+    bl.append(std::string(len, '1'));
+
+    int r = image_ctx->aio_work_queue->write(off, len, bl.c_str(), 0);
+    ASSERT_EQ(static_cast<int>(len), r);
+
+    interval_set<uint64_t> w;
+    w.insert(off, len);
+    what->union_of(w);
+  }
+  std::cout << " wrote " << *what << std::endl;
+}
+
+} // anonymous namespace
+
+class TestMockImageSyncObjectCopyRequest : public TestMockFixture {
+public:
+  typedef ObjectCopyRequest<librbd::MockImageCtx> MockObjectCopyRequest;
+
+  virtual void SetUp() {
+    TestMockFixture::SetUp();
+
+    librbd::RBD rbd;
+    ASSERT_EQ(0, create_image(rbd, m_remote_io_ctx, m_image_name, m_image_size));
+    ASSERT_EQ(0, open_image(m_remote_io_ctx, m_image_name, &m_remote_image_ctx));
+
+    ASSERT_EQ(0, create_image(rbd, m_local_io_ctx, m_image_name, m_image_size));
+    ASSERT_EQ(0, open_image(m_local_io_ctx, m_image_name, &m_local_image_ctx));
+  }
+
+  void expect_list_snaps(librbd::MockImageCtx &mock_image_ctx,
+                         librados::MockTestMemIoCtxImpl &mock_io_ctx, int r) {
+    auto &expect = EXPECT_CALL(mock_io_ctx,
+                               list_snaps(mock_image_ctx.image_ctx->get_object_name(0),
+                                          _));
+    if (r < 0) {
+      expect.WillOnce(Return(r));
+    } else {
+      expect.WillOnce(DoDefault());
+    }
+  }
+
+  void expect_get_object_name(librbd::MockImageCtx &mock_image_ctx) {
+    EXPECT_CALL(mock_image_ctx, get_object_name(0))
+                  .WillOnce(Return(mock_image_ctx.image_ctx->get_object_name(0)));
+  }
+
+  MockObjectCopyRequest *create_request(librbd::MockImageCtx &mock_remote_image_ctx,
+                                        librbd::MockImageCtx &mock_local_image_ctx,
+                                        Context *on_finish) {
+    expect_get_object_name(mock_local_image_ctx);
+    expect_get_object_name(mock_remote_image_ctx);
+    return new MockObjectCopyRequest(&mock_local_image_ctx,
+                                     &mock_remote_image_ctx, &m_snap_map,
+                                     0, on_finish);
+  }
+
+  void expect_read(librados::MockTestMemIoCtxImpl &mock_io_ctx, uint64_t offset,
+                   uint64_t length, int r) {
+    auto &expect = EXPECT_CALL(mock_io_ctx, read(_, length, offset, _));
+    if (r < 0) {
+      expect.WillOnce(Return(r));
+    } else {
+      expect.WillOnce(DoDefault());
+    }
+  }
+
+  void expect_read(librados::MockTestMemIoCtxImpl &mock_io_ctx,
+                   const interval_set<uint64_t> &extents, int r) {
+    for (auto extent : extents) {
+      expect_read(mock_io_ctx, extent.first, extent.second, r);
+      if (r < 0) {
+        break;
+      }
+    }
+  }
+
+  void expect_write(librados::MockTestMemIoCtxImpl &mock_io_ctx,
+                    uint64_t offset, uint64_t length, int r) {
+    auto &expect = EXPECT_CALL(mock_io_ctx, write(_, _, length, offset, _));
+    if (r < 0) {
+      expect.WillOnce(Return(r));
+    } else {
+      expect.WillOnce(DoDefault());
+    }
+  }
+
+  void expect_write(librados::MockTestMemIoCtxImpl &mock_io_ctx,
+                    const interval_set<uint64_t> &extents, int r) {
+    for (auto extent : extents) {
+      expect_write(mock_io_ctx, extent.first, extent.second, r);
+      if (r < 0) {
+        break;
+      }
+    }
+  }
+
+  void expect_truncate(librados::MockTestMemIoCtxImpl &mock_io_ctx,
+                       uint64_t offset, int r) {
+    auto &expect = EXPECT_CALL(mock_io_ctx, truncate(_, offset, _));
+    if (r < 0) {
+      expect.WillOnce(Return(r));
+    } else {
+      expect.WillOnce(DoDefault());
+    }
+  }
+
+  void expect_remove(librados::MockTestMemIoCtxImpl &mock_io_ctx, int r) {
+    auto &expect = EXPECT_CALL(mock_io_ctx, remove(_, _));
+    if (r < 0) {
+      expect.WillOnce(Return(r));
+    } else {
+      expect.WillOnce(DoDefault());
+    }
+  }
+
+  void expect_update_object_map(librbd::MockImageCtx &mock_image_ctx,
+                                librbd::MockObjectMap &mock_object_map,
+                                librados::snap_t snap_id, uint8_t state,
+                                int r) {
+    if (mock_image_ctx.image_ctx->object_map != nullptr) {
+      auto &expect = EXPECT_CALL(mock_object_map, aio_update(snap_id, 0, 1, state, _, _));
+      if (r < 0) {
+        expect.WillOnce(WithArg<5>(Invoke([this, r](Context *ctx) {
+            m_threads->work_queue->queue(ctx, r);
+          })));
+      } else {
+        expect.WillOnce(WithArg<5>(Invoke([&mock_image_ctx, snap_id, state, r](Context *ctx) {
+            RWLock::RLocker snap_locker(mock_image_ctx.image_ctx->snap_lock);
+            RWLock::WLocker object_map_locker(mock_image_ctx.image_ctx->object_map_lock);
+            mock_image_ctx.image_ctx->object_map->aio_update(snap_id, 0, 1,
+                                                             state,
+                                                             boost::none, ctx);
+          })));
+      }
+    }
+  }
+
+  using TestFixture::create_snap;
+  int create_snap(const char* snap_name) {
+    librados::snap_t remote_snap_id;
+    int r = create_snap(m_remote_image_ctx, snap_name, &remote_snap_id);
+    if (r < 0) {
+      return r;
+    }
+
+    librados::snap_t local_snap_id;
+    r = create_snap(m_local_image_ctx, snap_name, &local_snap_id);
+    if (r < 0) {
+      return r;
+    }
+
+    // collection of all existing snaps in local image
+    MockObjectCopyRequest::SnapIds local_snap_ids({local_snap_id});
+    if (!m_snap_map.empty()) {
+      local_snap_ids.insert(local_snap_ids.end(),
+                            m_snap_map.rbegin()->second.begin(),
+                            m_snap_map.rbegin()->second.end());
+    }
+    m_snap_map[remote_snap_id] = local_snap_ids;
+    m_local_snap_ids.push_back(local_snap_id);
+    return 0;
+  }
+
+  std::string get_snap_name(librbd::ImageCtx *image_ctx,
+                            librados::snap_t snap_id) {
+    auto it = std::find_if(image_ctx->snap_ids.begin(),
+                           image_ctx->snap_ids.end(),
+                           [snap_id](const std::pair<std::string, librados::snap_t> &pair) {
+        return (pair.second == snap_id);
+      });
+    if (it == image_ctx->snap_ids.end()) {
+      return "";
+    }
+    return it->first;
+  }
+
+  int compare_objects() {
+    MockObjectCopyRequest::SnapMap snap_map(m_snap_map);
+    if (snap_map.empty()) {
+      return -ENOENT;
+    }
+
+    int r;
+    uint64_t object_size = 1 << m_remote_image_ctx->order;
+    while (!snap_map.empty()) {
+      librados::snap_t remote_snap_id = snap_map.begin()->first;
+      librados::snap_t local_snap_id = *snap_map.begin()->second.begin();
+      snap_map.erase(snap_map.begin());
+
+      std::string snap_name = get_snap_name(m_remote_image_ctx, remote_snap_id);
+      if (snap_name.empty()) {
+        return -ENOENT;
+      }
+
+      std::cout << "comparing '" << snap_name << " (" << remote_snap_id
+                << " to " << local_snap_id << ")" << std::endl;
+
+      r = librbd::snap_set(m_remote_image_ctx, snap_name.c_str());
+      if (r < 0) {
+        return r;
+      }
+
+      r = librbd::snap_set(m_local_image_ctx, snap_name.c_str());
+      if (r < 0) {
+        return r;
+      }
+
+      bufferlist remote_bl;
+      remote_bl.append(std::string(object_size, '1'));
+      r = m_remote_image_ctx->aio_work_queue->read(0, object_size,
+                                                   remote_bl.c_str(), 0);
+      if (r < 0) {
+        return r;
+      }
+
+      bufferlist local_bl;
+      local_bl.append(std::string(object_size, '1'));
+      r = m_local_image_ctx->aio_work_queue->read(0, object_size,
+                                                  local_bl.c_str(), 0);
+      if (r < 0) {
+        return r;
+      }
+
+      if (!remote_bl.contents_equal(local_bl)) {
+        return -EBADMSG;
+      }
+    }
+
+    r = librbd::snap_set(m_remote_image_ctx, nullptr);
+    if (r < 0) {
+      return r;
+    }
+    r = librbd::snap_set(m_local_image_ctx, nullptr);
+    if (r < 0) {
+      return r;
+    }
+
+    return 0;
+  }
+
+  librbd::ImageCtx *m_remote_image_ctx;
+  librbd::ImageCtx *m_local_image_ctx;
+
+  MockObjectCopyRequest::SnapMap m_snap_map;
+  std::vector<librados::snap_t> m_local_snap_ids;
+};
+
+TEST_F(TestMockImageSyncObjectCopyRequest, DNE) {
+  ASSERT_EQ(0, create_snap("sync"));
+  librbd::MockImageCtx mock_remote_image_ctx(*m_remote_image_ctx);
+  librbd::MockImageCtx mock_local_image_ctx(*m_local_image_ctx);
+
+  librbd::MockObjectMap mock_object_map;
+  mock_local_image_ctx.object_map = &mock_object_map;
+
+  expect_test_features(mock_local_image_ctx);
+
+  C_SaferCond ctx;
+  MockObjectCopyRequest *request = create_request(mock_remote_image_ctx,
+                                                  mock_local_image_ctx, &ctx);
+
+  librados::MockTestMemIoCtxImpl &mock_remote_io_ctx(get_mock_io_ctx(
+    request->get_remote_io_ctx()));
+
+  InSequence seq;
+  expect_list_snaps(mock_remote_image_ctx, mock_remote_io_ctx, -ENOENT);
+
+  request->send();
+  ASSERT_EQ(0, ctx.wait());
+}
+
+TEST_F(TestMockImageSyncObjectCopyRequest, Write) {
+  // scribble some data
+  interval_set<uint64_t> one;
+  scribble(m_remote_image_ctx, 10, 102400, &one);
+
+  ASSERT_EQ(0, create_snap("sync"));
+  librbd::MockImageCtx mock_remote_image_ctx(*m_remote_image_ctx);
+  librbd::MockImageCtx mock_local_image_ctx(*m_local_image_ctx);
+
+  librbd::MockObjectMap mock_object_map;
+  mock_local_image_ctx.object_map = &mock_object_map;
+
+  expect_test_features(mock_local_image_ctx);
+
+  C_SaferCond ctx;
+  MockObjectCopyRequest *request = create_request(mock_remote_image_ctx,
+                                                  mock_local_image_ctx, &ctx);
+
+  librados::MockTestMemIoCtxImpl &mock_remote_io_ctx(get_mock_io_ctx(
+    request->get_remote_io_ctx()));
+  librados::MockTestMemIoCtxImpl &mock_local_io_ctx(get_mock_io_ctx(
+    request->get_local_io_ctx()));
+
+  InSequence seq;
+  expect_list_snaps(mock_remote_image_ctx, mock_remote_io_ctx, 0);
+  expect_read(mock_remote_io_ctx, 0, one.range_end(), 0);
+  expect_write(mock_local_io_ctx, 0, one.range_end(), 0);
+  expect_update_object_map(mock_local_image_ctx, mock_object_map,
+                           m_local_snap_ids[0], OBJECT_EXISTS, 0);
+
+  request->send();
+  ASSERT_EQ(0, ctx.wait());
+  ASSERT_EQ(0, compare_objects());
+}
+
+TEST_F(TestMockImageSyncObjectCopyRequest, ReadError) {
+  // scribble some data
+  interval_set<uint64_t> one;
+  scribble(m_remote_image_ctx, 10, 102400, &one);
+
+  ASSERT_EQ(0, create_snap("sync"));
+  librbd::MockImageCtx mock_remote_image_ctx(*m_remote_image_ctx);
+  librbd::MockImageCtx mock_local_image_ctx(*m_local_image_ctx);
+
+  librbd::MockObjectMap mock_object_map;
+  mock_local_image_ctx.object_map = &mock_object_map;
+
+  expect_test_features(mock_local_image_ctx);
+
+  C_SaferCond ctx;
+  MockObjectCopyRequest *request = create_request(mock_remote_image_ctx,
+                                                  mock_local_image_ctx, &ctx);
+
+  librados::MockTestMemIoCtxImpl &mock_remote_io_ctx(get_mock_io_ctx(
+    request->get_remote_io_ctx()));
+
+  InSequence seq;
+  expect_list_snaps(mock_remote_image_ctx, mock_remote_io_ctx, 0);
+  expect_read(mock_remote_io_ctx, 0, one.range_end(), -EINVAL);
+
+  request->send();
+  ASSERT_EQ(-EINVAL, ctx.wait());
+}
+
+TEST_F(TestMockImageSyncObjectCopyRequest, WriteError) {
+  // scribble some data
+  interval_set<uint64_t> one;
+  scribble(m_remote_image_ctx, 10, 102400, &one);
+
+  ASSERT_EQ(0, create_snap("sync"));
+  librbd::MockImageCtx mock_remote_image_ctx(*m_remote_image_ctx);
+  librbd::MockImageCtx mock_local_image_ctx(*m_local_image_ctx);
+
+  librbd::MockObjectMap mock_object_map;
+  mock_local_image_ctx.object_map = &mock_object_map;
+
+  expect_test_features(mock_local_image_ctx);
+
+  C_SaferCond ctx;
+  MockObjectCopyRequest *request = create_request(mock_remote_image_ctx,
+                                                  mock_local_image_ctx, &ctx);
+
+  librados::MockTestMemIoCtxImpl &mock_remote_io_ctx(get_mock_io_ctx(
+    request->get_remote_io_ctx()));
+  librados::MockTestMemIoCtxImpl &mock_local_io_ctx(get_mock_io_ctx(
+    request->get_local_io_ctx()));
+
+  InSequence seq;
+  expect_list_snaps(mock_remote_image_ctx, mock_remote_io_ctx, 0);
+  expect_read(mock_remote_io_ctx, 0, one.range_end(), 0);
+  expect_write(mock_local_io_ctx, 0, one.range_end(), -EINVAL);
+
+  request->send();
+  ASSERT_EQ(-EINVAL, ctx.wait());
+}
+
+TEST_F(TestMockImageSyncObjectCopyRequest, WriteSnaps) {
+  // scribble some data
+  interval_set<uint64_t> one;
+  scribble(m_remote_image_ctx, 10, 102400, &one);
+  ASSERT_EQ(0, create_snap("one"));
+
+  interval_set<uint64_t> two;
+  scribble(m_remote_image_ctx, 10, 102400, &two);
+  ASSERT_EQ(0, create_snap("two"));
+
+  if (one.range_end() < two.range_end()) {
+    interval_set<uint64_t> resize_diff;
+    resize_diff.insert(one.range_end(), two.range_end() - one.range_end());
+    two.union_of(resize_diff);
+  }
+
+  ASSERT_EQ(0, create_snap("sync"));
+  librbd::MockImageCtx mock_remote_image_ctx(*m_remote_image_ctx);
+  librbd::MockImageCtx mock_local_image_ctx(*m_local_image_ctx);
+
+  librbd::MockObjectMap mock_object_map;
+  mock_local_image_ctx.object_map = &mock_object_map;
+
+  expect_test_features(mock_local_image_ctx);
+
+  C_SaferCond ctx;
+  MockObjectCopyRequest *request = create_request(mock_remote_image_ctx,
+                                                  mock_local_image_ctx, &ctx);
+
+  librados::MockTestMemIoCtxImpl &mock_remote_io_ctx(get_mock_io_ctx(
+    request->get_remote_io_ctx()));
+  librados::MockTestMemIoCtxImpl &mock_local_io_ctx(get_mock_io_ctx(
+    request->get_local_io_ctx()));
+
+  InSequence seq;
+  expect_list_snaps(mock_remote_image_ctx, mock_remote_io_ctx, 0);
+  expect_read(mock_remote_io_ctx, 0, one.range_end(), 0);
+  expect_write(mock_local_io_ctx, 0, one.range_end(), 0);
+  expect_read(mock_remote_io_ctx, two, 0);
+  expect_write(mock_local_io_ctx, two, 0);
+  expect_update_object_map(mock_local_image_ctx, mock_object_map,
+                           m_local_snap_ids[0], OBJECT_EXISTS, 0);
+  expect_update_object_map(mock_local_image_ctx, mock_object_map,
+                           m_local_snap_ids[1], OBJECT_EXISTS, 0);
+  expect_update_object_map(mock_local_image_ctx, mock_object_map,
+                           m_local_snap_ids[2], OBJECT_EXISTS_CLEAN, 0);
+
+  request->send();
+  ASSERT_EQ(0, ctx.wait());
+  ASSERT_EQ(0, compare_objects());
+}
+
+TEST_F(TestMockImageSyncObjectCopyRequest, Trim) {
+  // scribble some data
+  interval_set<uint64_t> one;
+  scribble(m_remote_image_ctx, 10, 102400, &one);
+  ASSERT_EQ(0, create_snap("one"));
+
+  // trim the object
+  uint64_t trim_offset = rand() % one.range_end();
+  ASSERT_LE(0, m_remote_image_ctx->aio_work_queue->discard(
+    trim_offset, one.range_end() - trim_offset));
+  ASSERT_EQ(0, create_snap("sync"));
+
+  librbd::MockImageCtx mock_remote_image_ctx(*m_remote_image_ctx);
+  librbd::MockImageCtx mock_local_image_ctx(*m_local_image_ctx);
+
+  librbd::MockObjectMap mock_object_map;
+  mock_local_image_ctx.object_map = &mock_object_map;
+
+  expect_test_features(mock_local_image_ctx);
+
+  C_SaferCond ctx;
+  MockObjectCopyRequest *request = create_request(mock_remote_image_ctx,
+                                                  mock_local_image_ctx, &ctx);
+
+  librados::MockTestMemIoCtxImpl &mock_remote_io_ctx(get_mock_io_ctx(
+    request->get_remote_io_ctx()));
+  librados::MockTestMemIoCtxImpl &mock_local_io_ctx(get_mock_io_ctx(
+    request->get_local_io_ctx()));
+
+  InSequence seq;
+  expect_list_snaps(mock_remote_image_ctx, mock_remote_io_ctx, 0);
+  expect_read(mock_remote_io_ctx, 0, one.range_end(), 0);
+  expect_write(mock_local_io_ctx, 0, one.range_end(), 0);
+  expect_truncate(mock_local_io_ctx, trim_offset, 0);
+  expect_update_object_map(mock_local_image_ctx, mock_object_map,
+                           m_local_snap_ids[0], OBJECT_EXISTS, 0);
+  expect_update_object_map(mock_local_image_ctx, mock_object_map,
+                           m_local_snap_ids[1], OBJECT_EXISTS, 0);
+
+  request->send();
+  ASSERT_EQ(0, ctx.wait());
+  ASSERT_EQ(0, compare_objects());
+}
+
+TEST_F(TestMockImageSyncObjectCopyRequest, Remove) {
+  // scribble some data
+  interval_set<uint64_t> one;
+  scribble(m_remote_image_ctx, 10, 102400, &one);
+  ASSERT_EQ(0, create_snap("one"));
+
+  // remove the object
+  uint64_t object_size = 1 << m_remote_image_ctx->order;
+  ASSERT_LE(0, m_remote_image_ctx->aio_work_queue->discard(0, object_size));
+  ASSERT_EQ(0, create_snap("sync"));
+  librbd::MockImageCtx mock_remote_image_ctx(*m_remote_image_ctx);
+  librbd::MockImageCtx mock_local_image_ctx(*m_local_image_ctx);
+
+  librbd::MockObjectMap mock_object_map;
+  mock_local_image_ctx.object_map = &mock_object_map;
+
+  expect_test_features(mock_local_image_ctx);
+
+  C_SaferCond ctx;
+  MockObjectCopyRequest *request = create_request(mock_remote_image_ctx,
+                                                  mock_local_image_ctx, &ctx);
+
+  librados::MockTestMemIoCtxImpl &mock_remote_io_ctx(get_mock_io_ctx(
+    request->get_remote_io_ctx()));
+  librados::MockTestMemIoCtxImpl &mock_local_io_ctx(get_mock_io_ctx(
+    request->get_local_io_ctx()));
+
+  InSequence seq;
+  expect_list_snaps(mock_remote_image_ctx, mock_remote_io_ctx, 0);
+  expect_read(mock_remote_io_ctx, 0, one.range_end(), 0);
+  expect_write(mock_local_io_ctx, 0, one.range_end(), 0);
+  expect_remove(mock_local_io_ctx, 0);
+  expect_update_object_map(mock_local_image_ctx, mock_object_map,
+                           m_local_snap_ids[0], OBJECT_EXISTS, 0);
+  expect_update_object_map(mock_local_image_ctx, mock_object_map,
+                           m_local_snap_ids[1], OBJECT_NONEXISTENT, 0);
+
+  request->send();
+  ASSERT_EQ(0, ctx.wait());
+  ASSERT_EQ(0, compare_objects());
+}
+
+} // namespace image_sync
+} // namespace mirror
+} // namespace rbd
diff --git a/src/test/rbd_mirror/image_sync/test_mock_SnapshotCopyRequest.cc b/src/test/rbd_mirror/image_sync/test_mock_SnapshotCopyRequest.cc
new file mode 100644
index 0000000..10c3ac3
--- /dev/null
+++ b/src/test/rbd_mirror/image_sync/test_mock_SnapshotCopyRequest.cc
@@ -0,0 +1,239 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+
+#include "test/rbd_mirror/test_mock_fixture.h"
+#include "include/rbd/librbd.hpp"
+#include "librbd/ImageCtx.h"
+#include "librbd/ImageState.h"
+#include "librbd/Operations.h"
+#include "test/librados_test_stub/MockTestMemIoCtxImpl.h"
+#include "test/librbd/mock/MockImageCtx.h"
+#include "test/rbd_mirror/mock/MockJournaler.h"
+#include "tools/rbd_mirror/image_sync/SnapshotCopyRequest.h"
+#include "tools/rbd_mirror/Threads.h"
+
+// template definitions
+#include "tools/rbd_mirror/image_sync/SnapshotCopyRequest.cc"
+template class rbd::mirror::image_sync::SnapshotCopyRequest<librbd::MockImageCtx>;
+
+namespace rbd {
+namespace mirror {
+namespace image_sync {
+
+using ::testing::_;
+using ::testing::DoAll;
+using ::testing::DoDefault;
+using ::testing::InSequence;
+using ::testing::Invoke;
+using ::testing::InvokeWithoutArgs;
+using ::testing::Return;
+using ::testing::StrEq;
+using ::testing::WithArg;
+
+class TestMockImageSyncSnapshotCopyRequest : public TestMockFixture {
+public:
+  typedef SnapshotCopyRequest<librbd::MockImageCtx> MockSnapshotCopyRequest;
+
+  virtual void SetUp() {
+    TestMockFixture::SetUp();
+
+    librbd::RBD rbd;
+    ASSERT_EQ(0, create_image(rbd, m_remote_io_ctx, m_image_name, m_image_size));
+    ASSERT_EQ(0, open_image(m_remote_io_ctx, m_image_name, &m_remote_image_ctx));
+
+    ASSERT_EQ(0, create_image(rbd, m_local_io_ctx, m_image_name, m_image_size));
+    ASSERT_EQ(0, open_image(m_local_io_ctx, m_image_name, &m_local_image_ctx));
+  }
+
+  void expect_snap_create(librbd::MockImageCtx &mock_image_ctx,
+                          const std::string &snap_name, uint64_t snap_id, int r) {
+    EXPECT_CALL(*mock_image_ctx.operations, execute_snap_create(StrEq(snap_name), _, 0))
+                  .WillOnce(DoAll(InvokeWithoutArgs([&mock_image_ctx, snap_id, snap_name]() {
+                                    inject_snap(mock_image_ctx, snap_id, snap_name);
+                                  }),
+                                  WithArg<1>(Invoke([this, r](Context *ctx) {
+                                    m_threads->work_queue->queue(ctx, r);
+                                  }))));
+  }
+
+  void expect_snap_remove(librbd::MockImageCtx &mock_image_ctx,
+                          const std::string &snap_name, int r) {
+    EXPECT_CALL(*mock_image_ctx.operations, execute_snap_remove(StrEq(snap_name), _))
+                  .WillOnce(WithArg<1>(Invoke([this, r](Context *ctx) {
+                              m_threads->work_queue->queue(ctx, r);
+                            })));
+  }
+
+  void expect_update_client(journal::MockJournaler &mock_journaler, int r) {
+    EXPECT_CALL(mock_journaler, update_client(_, _))
+                  .WillOnce(WithArg<1>(CompleteContext(r)));
+  }
+
+  static void inject_snap(librbd::MockImageCtx &mock_image_ctx,
+                   uint64_t snap_id, const std::string &snap_name) {
+    mock_image_ctx.snap_ids[snap_name] = snap_id;
+  }
+
+  MockSnapshotCopyRequest *create_request(librbd::MockImageCtx &mock_remote_image_ctx,
+                                          librbd::MockImageCtx &mock_local_image_ctx,
+                                          journal::MockJournaler &mock_journaler,
+                                          Context *on_finish) {
+    return new MockSnapshotCopyRequest(&mock_local_image_ctx,
+                                       &mock_remote_image_ctx, &m_snap_map,
+                                       &mock_journaler, &m_client_meta,
+                                       on_finish);
+  }
+
+  int create_snap(librbd::ImageCtx *image_ctx, const std::string &snap_name) {
+    int r = image_ctx->operations->snap_create(snap_name.c_str());
+    if (r < 0) {
+      return r;
+    }
+
+    r = image_ctx->state->refresh();
+    if (r < 0) {
+      return r;
+    }
+    return 0;
+  }
+
+  void validate_snap_seqs(const librbd::journal::MirrorPeerClientMeta::SnapSeqs &snap_seqs) {
+    ASSERT_EQ(snap_seqs, m_client_meta.snap_seqs);
+  }
+
+  void validate_snap_map(const MockSnapshotCopyRequest::SnapMap &snap_map) {
+    ASSERT_EQ(snap_map, m_snap_map);
+  }
+
+  librbd::ImageCtx *m_remote_image_ctx;
+  librbd::ImageCtx *m_local_image_ctx;
+
+  MockSnapshotCopyRequest::SnapMap m_snap_map;
+  librbd::journal::MirrorPeerClientMeta m_client_meta;
+};
+
+TEST_F(TestMockImageSyncSnapshotCopyRequest, Empty) {
+  librbd::MockImageCtx mock_remote_image_ctx(*m_remote_image_ctx);
+  librbd::MockImageCtx mock_local_image_ctx(*m_local_image_ctx);
+  journal::MockJournaler mock_journaler;
+
+  InSequence seq;
+  expect_update_client(mock_journaler, 0);
+
+  C_SaferCond ctx;
+  MockSnapshotCopyRequest *request = create_request(mock_remote_image_ctx,
+                                                    mock_local_image_ctx,
+                                                    mock_journaler, &ctx);
+  request->send();
+  ASSERT_EQ(0, ctx.wait());
+
+  validate_snap_map({});
+  validate_snap_seqs({});
+}
+
+TEST_F(TestMockImageSyncSnapshotCopyRequest, UpdateClientError) {
+  librbd::MockImageCtx mock_remote_image_ctx(*m_remote_image_ctx);
+  librbd::MockImageCtx mock_local_image_ctx(*m_local_image_ctx);
+  journal::MockJournaler mock_journaler;
+
+  InSequence seq;
+  expect_update_client(mock_journaler, -EINVAL);
+
+  C_SaferCond ctx;
+  MockSnapshotCopyRequest *request = create_request(mock_remote_image_ctx,
+                                                    mock_local_image_ctx,
+                                                    mock_journaler, &ctx);
+  request->send();
+  ASSERT_EQ(-EINVAL, ctx.wait());
+}
+
+TEST_F(TestMockImageSyncSnapshotCopyRequest, SnapCreate) {
+  ASSERT_EQ(0, create_snap(m_remote_image_ctx, "snap1"));
+  ASSERT_EQ(0, create_snap(m_remote_image_ctx, "snap2"));
+
+  librbd::MockImageCtx mock_remote_image_ctx(*m_remote_image_ctx);
+  librbd::MockImageCtx mock_local_image_ctx(*m_local_image_ctx);
+  journal::MockJournaler mock_journaler;
+
+  InSequence seq;
+  expect_snap_create(mock_local_image_ctx, "snap1", 12, 0);
+  expect_snap_create(mock_local_image_ctx, "snap2", 14, 0);
+  expect_update_client(mock_journaler, 0);
+
+  C_SaferCond ctx;
+  MockSnapshotCopyRequest *request = create_request(mock_remote_image_ctx,
+                                                    mock_local_image_ctx,
+                                                    mock_journaler, &ctx);
+  request->send();
+  ASSERT_EQ(0, ctx.wait());
+
+  uint64_t snap_id1 = m_remote_image_ctx->snap_ids["snap1"];
+  uint64_t snap_id2 = m_remote_image_ctx->snap_ids["snap2"];
+  validate_snap_map({{snap_id1, {12}}, {snap_id2, {14, 12}}});
+  validate_snap_seqs({{snap_id1, 12}, {snap_id2, 14}});
+}
+
+TEST_F(TestMockImageSyncSnapshotCopyRequest, SnapCreateError) {
+  ASSERT_EQ(0, create_snap(m_remote_image_ctx, "snap1"));
+
+  librbd::MockImageCtx mock_remote_image_ctx(*m_remote_image_ctx);
+  librbd::MockImageCtx mock_local_image_ctx(*m_local_image_ctx);
+  journal::MockJournaler mock_journaler;
+
+  InSequence seq;
+  expect_snap_create(mock_local_image_ctx, "snap1", 12, -EINVAL);
+
+  C_SaferCond ctx;
+  MockSnapshotCopyRequest *request = create_request(mock_remote_image_ctx,
+                                                    mock_local_image_ctx,
+                                                    mock_journaler, &ctx);
+  request->send();
+  ASSERT_EQ(-EINVAL, ctx.wait());
+}
+
+TEST_F(TestMockImageSyncSnapshotCopyRequest, SnapRemove) {
+  ASSERT_EQ(0, create_snap(m_remote_image_ctx, "snap1"));
+  ASSERT_EQ(0, create_snap(m_local_image_ctx, "snap1"));
+
+  librbd::MockImageCtx mock_remote_image_ctx(*m_remote_image_ctx);
+  librbd::MockImageCtx mock_local_image_ctx(*m_local_image_ctx);
+  journal::MockJournaler mock_journaler;
+
+  InSequence seq;
+  expect_snap_remove(mock_local_image_ctx, "snap1", 0);
+  expect_snap_create(mock_local_image_ctx, "snap1", 12, 0);
+  expect_update_client(mock_journaler, 0);
+
+  C_SaferCond ctx;
+  MockSnapshotCopyRequest *request = create_request(mock_remote_image_ctx,
+                                                    mock_local_image_ctx,
+                                                    mock_journaler, &ctx);
+  request->send();
+  ASSERT_EQ(0, ctx.wait());
+
+  uint64_t snap_id1 = m_remote_image_ctx->snap_ids["snap1"];
+  validate_snap_map({{snap_id1, {12}}});
+  validate_snap_seqs({{snap_id1, 12}});
+}
+
+TEST_F(TestMockImageSyncSnapshotCopyRequest, SnapRemoveError) {
+  ASSERT_EQ(0, create_snap(m_local_image_ctx, "snap1"));
+
+  librbd::MockImageCtx mock_remote_image_ctx(*m_remote_image_ctx);
+  librbd::MockImageCtx mock_local_image_ctx(*m_local_image_ctx);
+  journal::MockJournaler mock_journaler;
+
+  InSequence seq;
+  expect_snap_remove(mock_local_image_ctx, "snap1", -EINVAL);
+
+  C_SaferCond ctx;
+  MockSnapshotCopyRequest *request = create_request(mock_remote_image_ctx,
+                                                    mock_local_image_ctx,
+                                                    mock_journaler, &ctx);
+  request->send();
+  ASSERT_EQ(-EINVAL, ctx.wait());
+}
+
+} // namespace image_sync
+} // namespace mirror
+} // namespace rbd
diff --git a/src/test/rbd_mirror/image_sync/test_mock_SyncPointCreateRequest.cc b/src/test/rbd_mirror/image_sync/test_mock_SyncPointCreateRequest.cc
new file mode 100644
index 0000000..e983402
--- /dev/null
+++ b/src/test/rbd_mirror/image_sync/test_mock_SyncPointCreateRequest.cc
@@ -0,0 +1,142 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+
+#include "test/rbd_mirror/test_mock_fixture.h"
+#include "include/rbd/librbd.hpp"
+#include "librbd/journal/Types.h"
+#include "test/librados_test_stub/MockTestMemIoCtxImpl.h"
+#include "test/librbd/mock/MockImageCtx.h"
+#include "test/rbd_mirror/mock/MockJournaler.h"
+#include "tools/rbd_mirror/image_sync/SyncPointCreateRequest.h"
+
+// template definitions
+#include "tools/rbd_mirror/image_sync/SyncPointCreateRequest.cc"
+template class rbd::mirror::image_sync::SyncPointCreateRequest<librbd::MockImageCtx>;
+
+namespace rbd {
+namespace mirror {
+namespace image_sync {
+
+using ::testing::_;
+using ::testing::InSequence;
+using ::testing::WithArg;
+
+class TestMockImageSyncSyncPointCreateRequest : public TestMockFixture {
+public:
+  typedef SyncPointCreateRequest<librbd::MockImageCtx> MockSyncPointCreateRequest;
+
+  virtual void SetUp() {
+    TestMockFixture::SetUp();
+
+    librbd::RBD rbd;
+    ASSERT_EQ(0, create_image(rbd, m_remote_io_ctx, m_image_name, m_image_size));
+    ASSERT_EQ(0, open_image(m_remote_io_ctx, m_image_name, &m_remote_image_ctx));
+  }
+
+  void expect_update_client(journal::MockJournaler &mock_journaler, int r) {
+    EXPECT_CALL(mock_journaler, update_client(_, _))
+      .WillOnce(WithArg<1>(CompleteContext(r)));
+  }
+
+  void expect_image_refresh(librbd::MockImageCtx &mock_remote_image_ctx, int r) {
+    EXPECT_CALL(*mock_remote_image_ctx.state, refresh(_))
+      .WillOnce(CompleteContext(r));
+  }
+
+  void expect_snap_create(librbd::MockImageCtx &mock_remote_image_ctx, int r) {
+    EXPECT_CALL(*mock_remote_image_ctx.operations, snap_create(_, _))
+      .WillOnce(WithArg<1>(CompleteContext(r)));
+  }
+
+  MockSyncPointCreateRequest *create_request(librbd::MockImageCtx &mock_remote_image_ctx,
+                                             journal::MockJournaler &mock_journaler,
+                                             Context *ctx) {
+    return new MockSyncPointCreateRequest(&mock_remote_image_ctx, "uuid",
+                                          &mock_journaler, &m_client_meta, ctx);
+  }
+
+  librbd::ImageCtx *m_remote_image_ctx;
+  librbd::journal::MirrorPeerClientMeta m_client_meta;
+};
+
+TEST_F(TestMockImageSyncSyncPointCreateRequest, Success) {
+  librbd::MockImageCtx mock_remote_image_ctx(*m_remote_image_ctx);
+  journal::MockJournaler mock_journaler;
+
+  InSequence seq;
+  expect_update_client(mock_journaler, 0);
+  expect_image_refresh(mock_remote_image_ctx, 0);
+  expect_snap_create(mock_remote_image_ctx, 0);
+
+  C_SaferCond ctx;
+  MockSyncPointCreateRequest *req = create_request(mock_remote_image_ctx,
+                                                   mock_journaler, &ctx);
+  req->send();
+  ASSERT_EQ(0, ctx.wait());
+
+  ASSERT_EQ(1U, m_client_meta.sync_points.size());
+}
+
+TEST_F(TestMockImageSyncSyncPointCreateRequest, ResyncSuccess) {
+  m_client_meta.sync_points.emplace_front("start snap", "", boost::none);
+  auto sync_point = m_client_meta.sync_points.front();
+
+  librbd::MockImageCtx mock_remote_image_ctx(*m_remote_image_ctx);
+  journal::MockJournaler mock_journaler;
+
+  InSequence seq;
+  expect_update_client(mock_journaler, 0);
+  expect_image_refresh(mock_remote_image_ctx, 0);
+  expect_snap_create(mock_remote_image_ctx, 0);
+
+  C_SaferCond ctx;
+  MockSyncPointCreateRequest *req = create_request(mock_remote_image_ctx,
+                                                   mock_journaler, &ctx);
+  req->send();
+  ASSERT_EQ(0, ctx.wait());
+
+  ASSERT_EQ(2U, m_client_meta.sync_points.size());
+  ASSERT_EQ(sync_point, m_client_meta.sync_points.front());
+  ASSERT_EQ("start snap", m_client_meta.sync_points.back().from_snap_name);
+}
+
+TEST_F(TestMockImageSyncSyncPointCreateRequest, SnapshotExists) {
+  librbd::MockImageCtx mock_remote_image_ctx(*m_remote_image_ctx);
+  journal::MockJournaler mock_journaler;
+
+  InSequence seq;
+  expect_update_client(mock_journaler, 0);
+  expect_image_refresh(mock_remote_image_ctx, 0);
+  expect_snap_create(mock_remote_image_ctx, -EEXIST);
+  expect_update_client(mock_journaler, 0);
+  expect_image_refresh(mock_remote_image_ctx, 0);
+  expect_snap_create(mock_remote_image_ctx, 0);
+
+  C_SaferCond ctx;
+  MockSyncPointCreateRequest *req = create_request(mock_remote_image_ctx,
+                                                   mock_journaler, &ctx);
+  req->send();
+  ASSERT_EQ(0, ctx.wait());
+
+  ASSERT_EQ(1U, m_client_meta.sync_points.size());
+}
+
+TEST_F(TestMockImageSyncSyncPointCreateRequest, ClientUpdateError) {
+  librbd::MockImageCtx mock_remote_image_ctx(*m_remote_image_ctx);
+  journal::MockJournaler mock_journaler;
+
+  InSequence seq;
+  expect_update_client(mock_journaler, -EINVAL);
+
+  C_SaferCond ctx;
+  MockSyncPointCreateRequest *req = create_request(mock_remote_image_ctx,
+                                                   mock_journaler, &ctx);
+  req->send();
+  ASSERT_EQ(-EINVAL, ctx.wait());
+
+  ASSERT_TRUE(m_client_meta.sync_points.empty());
+}
+
+} // namespace image_sync
+} // namespace mirror
+} // namespace rbd
diff --git a/src/test/rbd_mirror/image_sync/test_mock_SyncPointPruneRequest.cc b/src/test/rbd_mirror/image_sync/test_mock_SyncPointPruneRequest.cc
new file mode 100644
index 0000000..4558d6c
--- /dev/null
+++ b/src/test/rbd_mirror/image_sync/test_mock_SyncPointPruneRequest.cc
@@ -0,0 +1,219 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+
+#include "test/rbd_mirror/test_mock_fixture.h"
+#include "include/rbd/librbd.hpp"
+#include "librbd/journal/Types.h"
+#include "test/librados_test_stub/MockTestMemIoCtxImpl.h"
+#include "test/librbd/mock/MockImageCtx.h"
+#include "test/rbd_mirror/mock/MockJournaler.h"
+#include "tools/rbd_mirror/image_sync/SyncPointPruneRequest.h"
+
+// template definitions
+#include "tools/rbd_mirror/image_sync/SyncPointPruneRequest.cc"
+template class rbd::mirror::image_sync::SyncPointPruneRequest<librbd::MockImageCtx>;
+
+namespace rbd {
+namespace mirror {
+namespace image_sync {
+
+using ::testing::_;
+using ::testing::InSequence;
+using ::testing::StrEq;
+using ::testing::WithArg;
+
+class TestMockImageSyncSyncPointPruneRequest : public TestMockFixture {
+public:
+  typedef SyncPointPruneRequest<librbd::MockImageCtx> MockSyncPointPruneRequest;
+
+  virtual void SetUp() {
+    TestMockFixture::SetUp();
+
+    librbd::RBD rbd;
+    ASSERT_EQ(0, create_image(rbd, m_remote_io_ctx, m_image_name, m_image_size));
+    ASSERT_EQ(0, open_image(m_remote_io_ctx, m_image_name, &m_remote_image_ctx));
+  }
+
+  void expect_update_client(journal::MockJournaler &mock_journaler, int r) {
+    EXPECT_CALL(mock_journaler, update_client(_, _))
+      .WillOnce(WithArg<1>(CompleteContext(r)));
+  }
+
+  void expect_image_refresh(librbd::MockImageCtx &mock_remote_image_ctx, int r) {
+    EXPECT_CALL(*mock_remote_image_ctx.state, refresh(_))
+      .WillOnce(CompleteContext(r));
+  }
+
+  void expect_snap_remove(librbd::MockImageCtx &mock_remote_image_ctx,
+                          const std::string &snap_name, int r) {
+    EXPECT_CALL(*mock_remote_image_ctx.operations, snap_remove(StrEq(snap_name), _))
+      .WillOnce(WithArg<1>(CompleteContext(r)));
+  }
+
+  MockSyncPointPruneRequest *create_request(librbd::MockImageCtx &mock_remote_image_ctx,
+                                            journal::MockJournaler &mock_journaler,
+                                            bool sync_complete, Context *ctx) {
+    return new MockSyncPointPruneRequest(&mock_remote_image_ctx, sync_complete,
+                                         &mock_journaler, &m_client_meta, ctx);
+  }
+
+  librbd::ImageCtx *m_remote_image_ctx;
+  librbd::journal::MirrorPeerClientMeta m_client_meta;
+};
+
+TEST_F(TestMockImageSyncSyncPointPruneRequest, SyncInProgressSuccess) {
+  librbd::journal::MirrorPeerClientMeta client_meta;
+  client_meta.sync_points.emplace_front("snap1", boost::none);
+  m_client_meta = client_meta;
+
+  librbd::MockImageCtx mock_remote_image_ctx(*m_remote_image_ctx);
+  journal::MockJournaler mock_journaler;
+
+  InSequence seq;
+  expect_image_refresh(mock_remote_image_ctx, 0);
+  expect_update_client(mock_journaler, 0);
+
+  C_SaferCond ctx;
+  MockSyncPointPruneRequest *req = create_request(mock_remote_image_ctx,
+                                                  mock_journaler, false, &ctx);
+  req->send();
+  ASSERT_EQ(0, ctx.wait());
+  ASSERT_EQ(client_meta, m_client_meta);
+}
+
+TEST_F(TestMockImageSyncSyncPointPruneRequest, RestartedSyncInProgressSuccess) {
+  librbd::journal::MirrorPeerClientMeta client_meta;
+  client_meta.sync_points.emplace_front("snap2", "snap1", boost::none);
+  client_meta.sync_points.emplace_front("snap1", boost::none);
+  m_client_meta = client_meta;
+
+  librbd::MockImageCtx mock_remote_image_ctx(*m_remote_image_ctx);
+  journal::MockJournaler mock_journaler;
+
+  InSequence seq;
+  expect_snap_remove(mock_remote_image_ctx, "snap2", 0);
+  expect_image_refresh(mock_remote_image_ctx, 0);
+  expect_update_client(mock_journaler, 0);
+
+  C_SaferCond ctx;
+  MockSyncPointPruneRequest *req = create_request(mock_remote_image_ctx,
+                                                  mock_journaler, false, &ctx);
+  req->send();
+  ASSERT_EQ(0, ctx.wait());
+
+  client_meta.sync_points.pop_back();
+  ASSERT_EQ(client_meta, m_client_meta);
+}
+
+TEST_F(TestMockImageSyncSyncPointPruneRequest, SyncCompleteSuccess) {
+  librbd::journal::MirrorPeerClientMeta client_meta;
+  client_meta.sync_points.emplace_front("snap1", boost::none);
+  m_client_meta = client_meta;
+
+  librbd::MockImageCtx mock_remote_image_ctx(*m_remote_image_ctx);
+  journal::MockJournaler mock_journaler;
+
+  InSequence seq;
+  expect_snap_remove(mock_remote_image_ctx, "snap1", 0);
+  expect_image_refresh(mock_remote_image_ctx, 0);
+  expect_update_client(mock_journaler, 0);
+
+  C_SaferCond ctx;
+  MockSyncPointPruneRequest *req = create_request(mock_remote_image_ctx,
+                                                  mock_journaler, true, &ctx);
+  req->send();
+  ASSERT_EQ(0, ctx.wait());
+  ASSERT_TRUE(m_client_meta.sync_points.empty());
+}
+
+TEST_F(TestMockImageSyncSyncPointPruneRequest, RestartedSyncCompleteSuccess) {
+  librbd::journal::MirrorPeerClientMeta client_meta;
+  client_meta.sync_points.emplace_front("snap2", "snap1", boost::none);
+  client_meta.sync_points.emplace_front("snap1", boost::none);
+  m_client_meta = client_meta;
+
+  librbd::MockImageCtx mock_remote_image_ctx(*m_remote_image_ctx);
+  journal::MockJournaler mock_journaler;
+
+  InSequence seq;
+  expect_image_refresh(mock_remote_image_ctx, 0);
+  expect_update_client(mock_journaler, 0);
+
+  C_SaferCond ctx;
+  MockSyncPointPruneRequest *req = create_request(mock_remote_image_ctx,
+                                                  mock_journaler, true, &ctx);
+  req->send();
+  ASSERT_EQ(0, ctx.wait());
+  client_meta.sync_points.pop_front();
+  ASSERT_EQ(client_meta, m_client_meta);
+}
+
+TEST_F(TestMockImageSyncSyncPointPruneRequest, RestartedCatchUpSyncCompleteSuccess) {
+  librbd::journal::MirrorPeerClientMeta client_meta;
+  client_meta.sync_points.emplace_front("snap3", "snap2", boost::none);
+  client_meta.sync_points.emplace_front("snap2", "snap1", boost::none);
+  m_client_meta = client_meta;
+
+  librbd::MockImageCtx mock_remote_image_ctx(*m_remote_image_ctx);
+  journal::MockJournaler mock_journaler;
+
+  InSequence seq;
+  expect_snap_remove(mock_remote_image_ctx, "snap1", 0);
+  expect_image_refresh(mock_remote_image_ctx, 0);
+  expect_update_client(mock_journaler, 0);
+
+  C_SaferCond ctx;
+  MockSyncPointPruneRequest *req = create_request(mock_remote_image_ctx,
+                                                  mock_journaler, true, &ctx);
+  req->send();
+  ASSERT_EQ(0, ctx.wait());
+  client_meta.sync_points.pop_front();
+  ASSERT_EQ(client_meta, m_client_meta);
+}
+
+TEST_F(TestMockImageSyncSyncPointPruneRequest, SnapshotDNE) {
+  librbd::journal::MirrorPeerClientMeta client_meta;
+  client_meta.sync_points.emplace_front("snap1", boost::none);
+  m_client_meta = client_meta;
+
+  librbd::MockImageCtx mock_remote_image_ctx(*m_remote_image_ctx);
+  journal::MockJournaler mock_journaler;
+
+  InSequence seq;
+  expect_snap_remove(mock_remote_image_ctx, "snap1", -ENOENT);
+  expect_image_refresh(mock_remote_image_ctx, 0);
+  expect_update_client(mock_journaler, 0);
+
+  C_SaferCond ctx;
+  MockSyncPointPruneRequest *req = create_request(mock_remote_image_ctx,
+                                                  mock_journaler, true, &ctx);
+  req->send();
+  ASSERT_EQ(0, ctx.wait());
+  ASSERT_TRUE(m_client_meta.sync_points.empty());
+}
+
+TEST_F(TestMockImageSyncSyncPointPruneRequest, ClientUpdateError) {
+  librbd::journal::MirrorPeerClientMeta client_meta;
+  client_meta.sync_points.emplace_front("snap2", "snap1", boost::none);
+  client_meta.sync_points.emplace_front("snap1", boost::none);
+  m_client_meta = client_meta;
+
+  librbd::MockImageCtx mock_remote_image_ctx(*m_remote_image_ctx);
+  journal::MockJournaler mock_journaler;
+
+  InSequence seq;
+  expect_image_refresh(mock_remote_image_ctx, 0);
+  expect_update_client(mock_journaler, -EINVAL);
+
+  C_SaferCond ctx;
+  MockSyncPointPruneRequest *req = create_request(mock_remote_image_ctx,
+                                                  mock_journaler, true, &ctx);
+  req->send();
+  ASSERT_EQ(-EINVAL, ctx.wait());
+
+  ASSERT_EQ(client_meta, m_client_meta);
+}
+
+} // namespace image_sync
+} // namespace mirror
+} // namespace rbd
diff --git a/src/test/rbd_mirror/mock/MockJournaler.cc b/src/test/rbd_mirror/mock/MockJournaler.cc
new file mode 100644
index 0000000..43f23e8
--- /dev/null
+++ b/src/test/rbd_mirror/mock/MockJournaler.cc
@@ -0,0 +1,10 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+
+#include "MockJournaler.h"
+
+namespace journal {
+
+MockJournaler *MockJournaler::s_instance = nullptr;
+
+} // namespace journal
diff --git a/src/test/rbd_mirror/mock/MockJournaler.h b/src/test/rbd_mirror/mock/MockJournaler.h
new file mode 100644
index 0000000..5613eda
--- /dev/null
+++ b/src/test/rbd_mirror/mock/MockJournaler.h
@@ -0,0 +1,42 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+
+#ifndef TEST_RBD_MIRROR_MOCK_JOURNALER_H
+#define TEST_RBD_MIRROR_MOCK_JOURNALER_H
+
+#include <gmock/gmock.h>
+#include "librbd/Journal.h"
+
+namespace journal {
+
+struct MockJournaler {
+  static MockJournaler *s_instance;
+  static MockJournaler &get_instance() {
+    assert(s_instance != nullptr);
+    return *s_instance;
+  }
+
+  MockJournaler() {
+    s_instance = this;
+  }
+
+  MOCK_METHOD2(update_client, void(const bufferlist&, Context *on_safe));
+};
+
+} // namespace journal
+
+namespace librbd {
+
+struct MockImageCtx;
+
+namespace journal {
+
+template <>
+struct TypeTraits<MockImageCtx> {
+  typedef ::journal::MockJournaler Journaler;
+};
+
+} // namespace journal
+} // namespace librbd
+
+#endif // TEST_RBD_MIRROR_MOCK_JOURNALER_H
diff --git a/src/test/rbd_mirror/test_ClusterWatcher.cc b/src/test/rbd_mirror/test_ClusterWatcher.cc
index 97f4859..1629a16 100644
--- a/src/test/rbd_mirror/test_ClusterWatcher.cc
+++ b/src/test/rbd_mirror/test_ClusterWatcher.cc
@@ -42,8 +42,9 @@ public:
     }
   }
 
-  void create_pool(bool enable_mirroring, const peer_t &peer, string *name=nullptr) {
-    string pool_name = get_temp_pool_name();
+  void create_pool(bool enable_mirroring, const peer_t &peer,
+                   string *uuid = nullptr, string *name=nullptr) {
+    string pool_name = get_temp_pool_name("test-rbd-mirror-");
     ASSERT_EQ("", create_one_pool_pp(pool_name, *m_cluster));
     int64_t pool_id = m_cluster->pool_lookup(pool_name.c_str());
     ASSERT_GE(pool_id, 0);
@@ -51,8 +52,11 @@ public:
     if (enable_mirroring) {
       librados::IoCtx ioctx;
       ASSERT_EQ(0, m_cluster->ioctx_create2(pool_id, ioctx));
-      ASSERT_EQ(0, librbd::mirror_set_enabled(ioctx, true));
-      ASSERT_EQ(0, librbd::mirror_peer_add(ioctx, peer.cluster_uuid,
+      ASSERT_EQ(0, librbd::mirror_mode_set(ioctx, RBD_MIRROR_MODE_POOL));
+
+      std::string gen_uuid;
+      ASSERT_EQ(0, librbd::mirror_peer_add(ioctx,
+                                           uuid != nullptr ? uuid : &gen_uuid,
 					   peer.cluster_name,
 					   peer.client_name));
       m_peer_configs[peer].insert(pool_id);
@@ -79,7 +83,7 @@ public:
 
   void create_cache_pool(const string &base_pool, string *cache_pool_name) {
     bufferlist inbl;
-    *cache_pool_name = get_temp_pool_name();
+    *cache_pool_name = get_temp_pool_name("test-rbd-mirror-");
     ASSERT_EQ("", create_one_pool_pp(*cache_pool_name, *m_cluster));
     ASSERT_EQ(0, m_cluster->mon_command(
       "{\"prefix\": \"osd tier add\", \"pool\": \"" + base_pool +
@@ -143,13 +147,11 @@ TEST_F(TestClusterWatcher, NoMirroredPools) {
 }
 
 TEST_F(TestClusterWatcher, ReplicatedPools) {
-  string uuid1 = "00000000-0000-0000-0000-000000000001";
-  string uuid2 = "20000000-2222-2222-2222-000000000002";
-  peer_t site1(uuid1, "site1", "mirror1");
-  peer_t site2(uuid2, "site2", "mirror2");
+  peer_t site1("", "site1", "mirror1");
+  peer_t site2("", "site2", "mirror2");
   string first_pool, last_pool;
   check_peers();
-  create_pool(true, site1, &first_pool);
+  create_pool(true, site1, &site1.uuid, &first_pool);
   check_peers();
   create_pool(false, peer_t());
   check_peers();
@@ -157,11 +159,11 @@ TEST_F(TestClusterWatcher, ReplicatedPools) {
   check_peers();
   create_pool(false, peer_t());
   check_peers();
-  create_pool(true, site2);
+  create_pool(true, site2, &site2.uuid);
   check_peers();
-  create_pool(true, site2);
+  create_pool(true, site2, &site2.uuid);
   check_peers();
-  create_pool(true, site2, &last_pool);
+  create_pool(true, site2, &site2.uuid, &last_pool);
   check_peers();
   delete_pool(first_pool, site1);
   check_peers();
@@ -170,9 +172,9 @@ TEST_F(TestClusterWatcher, ReplicatedPools) {
 }
 
 TEST_F(TestClusterWatcher, CachePools) {
-  peer_t site1("11111111-1111-1111-1111-111111111111", "site1", "mirror1");
+  peer_t site1("", "site1", "mirror1");
   string base1, base2, cache1, cache2;
-  create_pool(true, site1, &base1);
+  create_pool(true, site1, &site1.uuid, &base1);
   check_peers();
 
   create_cache_pool(base1, &cache1);
@@ -181,7 +183,7 @@ TEST_F(TestClusterWatcher, CachePools) {
   } BOOST_SCOPE_EXIT_END;
   check_peers();
 
-  create_pool(false, peer_t(), &base2);
+  create_pool(false, peer_t(), nullptr, &base2);
   create_cache_pool(base2, &cache2);
   BOOST_SCOPE_EXIT( base2, cache2, this_ ) {
     this_->remove_cache_pool(base2, cache2);
diff --git a/src/test/rbd_mirror/test_ImageReplayer.cc b/src/test/rbd_mirror/test_ImageReplayer.cc
new file mode 100644
index 0000000..b042f57
--- /dev/null
+++ b/src/test/rbd_mirror/test_ImageReplayer.cc
@@ -0,0 +1,648 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+/*
+ * Ceph distributed storage system
+ *
+ * Copyright (C) 2016 Mirantis Inc
+ *
+ * Author: Mykola Golub <mgolub at mirantis.com>
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2.1 of the License, or (at your option) any later version.
+ *
+ */
+
+#include "include/rados/librados.hpp"
+#include "include/rbd/librbd.hpp"
+#include "include/stringify.h"
+#include "cls/journal/cls_journal_types.h"
+#include "cls/journal/cls_journal_client.h"
+#include "cls/rbd/cls_rbd_client.h"
+#include "journal/Journaler.h"
+#include "librbd/AioCompletion.h"
+#include "librbd/AioImageRequestWQ.h"
+#include "librbd/ImageCtx.h"
+#include "librbd/ImageState.h"
+#include "librbd/Journal.h"
+#include "librbd/Utils.h"
+#include "librbd/internal.h"
+#include "tools/rbd_mirror/types.h"
+#include "tools/rbd_mirror/ImageReplayer.h"
+#include "tools/rbd_mirror/Threads.h"
+
+#include "test/librados/test.h"
+#include "gtest/gtest.h"
+
+using rbd::mirror::RadosRef;
+
+void register_test_rbd_mirror() {
+}
+
+#define TEST_IO_SIZE 512
+#define TEST_IO_COUNT 11
+
+class TestImageReplayer : public ::testing::Test {
+public:
+  struct C_WatchCtx : public librados::WatchCtx2 {
+    TestImageReplayer *test;
+    std::string oid;
+    Mutex lock;
+    Cond cond;
+    bool notified;
+
+    C_WatchCtx(TestImageReplayer *test, const std::string &oid)
+      : test(test), oid(oid), lock("C_WatchCtx::lock"), notified(false) {
+    }
+
+    virtual void handle_notify(uint64_t notify_id, uint64_t cookie,
+                               uint64_t notifier_id, bufferlist& bl_) {
+      bufferlist bl;
+      test->m_remote_ioctx.notify_ack(oid, notify_id, cookie, bl);
+
+      Mutex::Locker locker(lock);
+      notified = true;
+      cond.Signal();
+    }
+
+    virtual void handle_error(uint64_t cookie, int err) {
+      ASSERT_EQ(0, err);
+    }
+  };
+
+  TestImageReplayer() : m_client_id("TestImageReplayer"), m_watch_handle(0)
+  {
+    EXPECT_EQ("", connect_cluster_pp(m_local_cluster));
+
+    m_local_pool_name = get_temp_pool_name();
+    EXPECT_EQ("", create_one_pool_pp(m_local_pool_name, m_local_cluster));
+    EXPECT_EQ(0, m_local_cluster.ioctx_create(m_local_pool_name.c_str(),
+					      m_local_ioctx));
+
+    EXPECT_EQ("", connect_cluster_pp(m_remote_cluster));
+
+    m_remote_pool_name = get_temp_pool_name();
+    EXPECT_EQ("", create_one_pool_pp(m_remote_pool_name, m_remote_cluster));
+    m_remote_pool_id = m_remote_cluster.pool_lookup(m_remote_pool_name.c_str());
+    EXPECT_GE(m_remote_pool_id, 0);
+
+    EXPECT_EQ(0, m_remote_cluster.ioctx_create(m_remote_pool_name.c_str(),
+					       m_remote_ioctx));
+
+    m_image_name = get_temp_image_name();
+    uint64_t features = g_ceph_context->_conf->rbd_default_features;
+    features |= RBD_FEATURE_EXCLUSIVE_LOCK | RBD_FEATURE_JOURNALING;
+    int order = 0;
+    EXPECT_EQ(0, librbd::create(m_remote_ioctx, m_image_name.c_str(), 1 << 22,
+				false, features, &order, 0, 0));
+    m_remote_image_id = get_image_id(m_remote_ioctx, m_image_name);
+
+    m_threads = new rbd::mirror::Threads(reinterpret_cast<CephContext*>(
+      m_local_ioctx.cct()));
+  }
+
+  ~TestImageReplayer()
+  {
+    delete m_replayer;
+    delete m_threads;
+
+    EXPECT_EQ(0, m_remote_cluster.pool_delete(m_remote_pool_name.c_str()));
+    EXPECT_EQ(0, m_local_cluster.pool_delete(m_local_pool_name.c_str()));
+  }
+
+  template <typename ImageReplayerT = rbd::mirror::ImageReplayer>
+  void create_replayer() {
+    m_replayer = new ImageReplayerT(m_threads,
+      rbd::mirror::RadosRef(new librados::Rados(m_local_ioctx)),
+      rbd::mirror::RadosRef(new librados::Rados(m_remote_ioctx)),
+      m_client_id, m_local_ioctx.get_id(), m_remote_pool_id, m_remote_image_id);
+  }
+
+  void start(rbd::mirror::ImageReplayer::BootstrapParams *bootstap_params =
+	     nullptr)
+  {
+    C_SaferCond cond;
+    m_replayer->start(&cond, bootstap_params);
+    ASSERT_EQ(0, cond.wait());
+
+    ASSERT_EQ(0U, m_watch_handle);
+    std::string oid = ::journal::Journaler::header_oid(m_remote_image_id);
+    m_watch_ctx = new C_WatchCtx(this, oid);
+    ASSERT_EQ(0, m_remote_ioctx.watch2(oid, &m_watch_handle, m_watch_ctx));
+  }
+
+  void stop()
+  {
+    if (m_watch_handle != 0) {
+      m_remote_ioctx.unwatch2(m_watch_handle);
+      delete m_watch_ctx;
+      m_watch_ctx = nullptr;
+      m_watch_handle = 0;
+    }
+
+    C_SaferCond cond;
+    m_replayer->stop(&cond);
+    ASSERT_EQ(0, cond.wait());
+  }
+
+  void bootstrap()
+  {
+    create_replayer<>();
+
+    rbd::mirror::ImageReplayer::BootstrapParams
+      bootstap_params(m_local_pool_name, m_image_name);
+    start(&bootstap_params);
+    wait_for_replay_complete();
+    stop();
+  }
+
+  std::string  get_temp_image_name()
+  {
+    return "image" + stringify(++_image_number);
+  }
+
+  std::string get_image_id(librados::IoCtx &ioctx, const string &image_name)
+  {
+    std::string obj = librbd::util::id_obj_name(image_name);
+    std::string id;
+    EXPECT_EQ(0, librbd::cls_client::get_id(&ioctx, obj, &id));
+    return id;
+  }
+
+  void open_image(librados::IoCtx &ioctx, const std::string &image_name,
+		  bool readonly, librbd::ImageCtx **ictxp)
+  {
+    librbd::ImageCtx *ictx = new librbd::ImageCtx(image_name.c_str(),
+						  "", "", ioctx, readonly);
+    EXPECT_EQ(0, ictx->state->open());
+    *ictxp = ictx;
+  }
+
+  void open_local_image(librbd::ImageCtx **ictxp)
+  {
+    open_image(m_local_ioctx, m_image_name, true, ictxp);
+  }
+
+  void open_remote_image(librbd::ImageCtx **ictxp)
+  {
+    open_image(m_remote_ioctx, m_image_name, false, ictxp);
+  }
+
+  void close_image(librbd::ImageCtx *ictx)
+  {
+    ictx->state->close();
+  }
+
+  void get_commit_positions(cls::journal::ObjectPosition *master_position,
+			    cls::journal::ObjectPosition *mirror_position)
+  {
+    std::string master_client_id = "";
+    std::string mirror_client_id = m_client_id;
+
+    C_SaferCond cond;
+    uint64_t minimum_set;
+    uint64_t active_set;
+    std::set<cls::journal::Client> registered_clients;
+    std::string oid = ::journal::Journaler::header_oid(m_remote_image_id);
+    cls::journal::client::get_mutable_metadata(m_remote_ioctx, oid,
+					       &minimum_set, &active_set,
+					       &registered_clients, &cond);
+    ASSERT_EQ(0, cond.wait());
+
+    *master_position = cls::journal::ObjectPosition();
+    *mirror_position = cls::journal::ObjectPosition();
+
+    std::set<cls::journal::Client>::const_iterator c;
+    for (c = registered_clients.begin(); c != registered_clients.end(); c++) {
+      std::cout << __func__ << ": client: " << *c << std::endl;
+      cls::journal::ObjectPositions object_positions =
+	c->commit_position.object_positions;
+      cls::journal::ObjectPositions::const_iterator p =
+	object_positions.begin();
+      if (p != object_positions.end()) {
+	if (c->id == master_client_id) {
+	  ASSERT_EQ(cls::journal::ObjectPosition(), *master_position);
+	  *master_position = *p;
+	} else if (c->id == mirror_client_id) {
+	  ASSERT_EQ(cls::journal::ObjectPosition(), *mirror_position);
+	  *mirror_position = *p;
+	}
+      }
+    }
+  }
+
+  bool wait_for_watcher_notify(int seconds)
+  {
+    if (m_watch_handle == 0) {
+      return false;
+    }
+
+    Mutex::Locker locker(m_watch_ctx->lock);
+    while (!m_watch_ctx->notified) {
+      if (m_watch_ctx->cond.WaitInterval(g_ceph_context, m_watch_ctx->lock,
+					 utime_t(seconds, 0)) != 0) {
+        return false;
+      }
+    }
+    m_watch_ctx->notified = false;
+    return true;
+  }
+
+  void wait_for_replay_complete()
+  {
+    cls::journal::ObjectPosition master_position;
+    cls::journal::ObjectPosition mirror_position;
+
+    for (int i = 0; i < 100; i++) {
+      printf("m_replayer->flush()\n");
+      m_replayer->flush();
+      get_commit_positions(&master_position, &mirror_position);
+      if (master_position == mirror_position) {
+	break;
+      }
+      wait_for_watcher_notify(1);
+    }
+
+    ASSERT_EQ(master_position, mirror_position);
+  }
+
+  void write_test_data(librbd::ImageCtx *ictx, const char *test_data, off_t off,
+                       size_t len)
+  {
+    size_t written;
+    written = ictx->aio_work_queue->write(off, len, test_data, 0);
+    printf("wrote: %d\n", (int)written);
+    ASSERT_EQ(len, written);
+  }
+
+  void read_test_data(librbd::ImageCtx *ictx, const char *expected, off_t off,
+                      size_t len)
+  {
+    ssize_t read;
+    char *result = (char *)malloc(len + 1);
+
+    ASSERT_NE(static_cast<char *>(NULL), result);
+    read = ictx->aio_work_queue->read(off, len, result, 0);
+    printf("read: %d\n", (int)read);
+    ASSERT_EQ(len, static_cast<size_t>(read));
+    result[len] = '\0';
+    if (memcmp(result, expected, len)) {
+      printf("read: %s\nexpected: %s\n", result, expected);
+      ASSERT_EQ(0, memcmp(result, expected, len));
+    }
+    free(result);
+  }
+
+  void generate_test_data() {
+    for (int i = 0; i < TEST_IO_SIZE; ++i) {
+      m_test_data[i] = (char) (rand() % (126 - 33) + 33);
+    }
+    m_test_data[TEST_IO_SIZE] = '\0';
+  }
+
+  void flush(librbd::ImageCtx *ictx)
+  {
+    C_SaferCond aio_flush_ctx;
+    librbd::AioCompletion *c = librbd::AioCompletion::create(&aio_flush_ctx);
+    c->get();
+    ictx->aio_work_queue->aio_flush(c);
+    ASSERT_EQ(0, c->wait_for_complete());
+    c->put();
+
+    C_SaferCond journal_flush_ctx;
+    ictx->journal->flush_commit_position(&journal_flush_ctx);
+    ASSERT_EQ(0, journal_flush_ctx.wait());
+
+    printf("flushed\n");
+  }
+
+  static int _image_number;
+
+  rbd::mirror::Threads *m_threads = nullptr;
+  librados::Rados m_local_cluster, m_remote_cluster;
+  std::string m_client_id;
+  std::string m_local_pool_name, m_remote_pool_name;
+  librados::IoCtx m_local_ioctx, m_remote_ioctx;
+  std::string m_image_name;
+  int64_t m_remote_pool_id;
+  std::string m_remote_image_id;
+  rbd::mirror::ImageReplayer *m_replayer;
+  C_WatchCtx *m_watch_ctx;
+  uint64_t m_watch_handle;
+  char m_test_data[TEST_IO_SIZE + 1];
+};
+
+int TestImageReplayer::_image_number;
+
+TEST_F(TestImageReplayer, Bootstrap)
+{
+  bootstrap();
+}
+
+TEST_F(TestImageReplayer, BootstrapErrorInvalidPool)
+{
+  create_replayer<>();
+
+  rbd::mirror::ImageReplayer::BootstrapParams
+    bootstap_params("INVALID_LOCAL_POOL_NAME", m_image_name);
+  C_SaferCond cond;
+  m_replayer->start(&cond, &bootstap_params);
+  ASSERT_EQ(-ENOENT, cond.wait());
+}
+
+TEST_F(TestImageReplayer, BootstrapErrorLocalImageExists)
+{
+  int order = 0;
+  EXPECT_EQ(0, librbd::create(m_local_ioctx, m_image_name.c_str(), 1 << 22,
+			      false, 0, &order, 0, 0));
+
+  create_replayer<>();
+  rbd::mirror::ImageReplayer::BootstrapParams
+    bootstap_params(m_local_pool_name, m_image_name);
+  C_SaferCond cond;
+  m_replayer->start(&cond, &bootstap_params);
+  ASSERT_EQ(-EEXIST, cond.wait());
+}
+
+TEST_F(TestImageReplayer, BootstrapErrorNoJournal)
+{
+  // disable remote journal journaling
+  librbd::ImageCtx *ictx;
+  open_remote_image(&ictx);
+  uint64_t features;
+  ASSERT_EQ(0, librbd::get_features(ictx, &features));
+  ASSERT_EQ(0, librbd::update_features(ictx, RBD_FEATURE_JOURNALING, false));
+  close_image(ictx);
+
+  create_replayer<>();
+  rbd::mirror::ImageReplayer::BootstrapParams
+    bootstap_params(m_local_pool_name, m_image_name);
+  C_SaferCond cond;
+  m_replayer->start(&cond, &bootstap_params);
+  ASSERT_EQ(-ENOENT, cond.wait());
+}
+
+TEST_F(TestImageReplayer, StartInterrupted)
+{
+  create_replayer<>();
+  rbd::mirror::ImageReplayer::BootstrapParams
+    bootstap_params(m_local_pool_name, m_image_name);
+  C_SaferCond start_cond, stop_cond;
+  m_replayer->start(&start_cond, &bootstap_params);
+  m_replayer->stop(&stop_cond);
+  int r = start_cond.wait();
+  printf("start returned %d\n", r);
+  // TODO: improve the test to avoid this race  // TODO: improve the test to avoid this race
+  ASSERT_TRUE(r == -EINTR || r == 0);
+  ASSERT_EQ(0, stop_cond.wait());
+}
+
+TEST_F(TestImageReplayer, ErrorJournalReset)
+{
+  bootstrap();
+
+  ASSERT_EQ(0, librbd::Journal<>::reset(m_remote_ioctx, m_remote_image_id));
+
+  C_SaferCond cond;
+  m_replayer->start(&cond);
+  ASSERT_EQ(-EEXIST, cond.wait());
+}
+
+TEST_F(TestImageReplayer, ErrorNoJournal)
+{
+  bootstrap();
+
+  // disable remote journal journaling
+  // (reset before disabling, so it does not fail with EBUSY)
+  ASSERT_EQ(0, librbd::Journal<>::reset(m_remote_ioctx, m_remote_image_id));
+  librbd::ImageCtx *ictx;
+  open_remote_image(&ictx);
+  uint64_t features;
+  ASSERT_EQ(0, librbd::get_features(ictx, &features));
+  ASSERT_EQ(0, librbd::update_features(ictx, RBD_FEATURE_JOURNALING, false));
+  close_image(ictx);
+
+  rbd::mirror::ImageReplayer::BootstrapParams
+    bootstap_params(m_local_pool_name, m_image_name);
+  C_SaferCond cond;
+  m_replayer->start(&cond, &bootstap_params);
+  ASSERT_EQ(-ENOENT, cond.wait());
+}
+
+TEST_F(TestImageReplayer, StartStop)
+{
+  bootstrap();
+
+  start();
+  wait_for_replay_complete();
+  stop();
+}
+
+TEST_F(TestImageReplayer, WriteAndStartReplay)
+{
+  bootstrap();
+
+  // Write to remote image and start replay
+
+  librbd::ImageCtx *ictx;
+
+  generate_test_data();
+  open_remote_image(&ictx);
+  for (int i = 0; i < TEST_IO_COUNT; ++i) {
+    write_test_data(ictx, m_test_data, TEST_IO_SIZE * i, TEST_IO_SIZE);
+  }
+  flush(ictx);
+  close_image(ictx);
+
+  start();
+  wait_for_replay_complete();
+  stop();
+
+  open_local_image(&ictx);
+  for (int i = 0; i < TEST_IO_COUNT; ++i) {
+    read_test_data(ictx, m_test_data, TEST_IO_SIZE * i, TEST_IO_SIZE);
+  }
+  close_image(ictx);
+}
+
+TEST_F(TestImageReplayer, StartReplayAndWrite)
+{
+  bootstrap();
+
+  // Start replay and write to remote image
+
+  librbd::ImageCtx *ictx;
+
+  start();
+
+  generate_test_data();
+  open_remote_image(&ictx);
+  for (int i = 0; i < TEST_IO_COUNT; ++i) {
+    write_test_data(ictx, m_test_data, TEST_IO_SIZE * i, TEST_IO_SIZE);
+  }
+  flush(ictx);
+
+  wait_for_replay_complete();
+
+  for (int i = TEST_IO_COUNT; i < 2 * TEST_IO_COUNT; ++i) {
+    write_test_data(ictx, m_test_data, TEST_IO_SIZE * i, TEST_IO_SIZE);
+  }
+  flush(ictx);
+  close_image(ictx);
+
+  wait_for_replay_complete();
+
+  open_local_image(&ictx);
+  for (int i = 0; i < 2 * TEST_IO_COUNT; ++i) {
+    read_test_data(ictx, m_test_data, TEST_IO_SIZE * i, TEST_IO_SIZE);
+  }
+  close_image(ictx);
+
+  stop();
+}
+
+TEST_F(TestImageReplayer, NextTag)
+{
+  bootstrap();
+
+  // write, reopen, and write again to test switch to the next tag
+
+  librbd::ImageCtx *ictx;
+
+  start();
+
+  generate_test_data();
+
+  const int N = 10;
+
+  for (int j = 0; j < N; j++) {
+    open_remote_image(&ictx);
+    for (int i = j * TEST_IO_COUNT; i < (j + 1) * TEST_IO_COUNT; ++i) {
+      write_test_data(ictx, m_test_data, TEST_IO_SIZE * i, TEST_IO_SIZE);
+    }
+    close_image(ictx);
+  }
+
+  wait_for_replay_complete();
+
+  open_local_image(&ictx);
+  for (int i = 0; i < N * TEST_IO_COUNT; ++i) {
+    read_test_data(ictx, m_test_data, TEST_IO_SIZE * i, TEST_IO_SIZE);
+  }
+  close_image(ictx);
+
+  stop();
+}
+
+class ImageReplayer : public rbd::mirror::ImageReplayer {
+public:
+  ImageReplayer(rbd::mirror::Threads *threads,
+		rbd::mirror::RadosRef local, rbd::mirror::RadosRef remote,
+		const std::string &client_id, int64_t local_pool_id,
+		int64_t remote_pool_id,	const std::string &remote_image_id)
+    : rbd::mirror::ImageReplayer(threads, local, remote, client_id,
+				 local_pool_id, remote_pool_id, remote_image_id)
+    {}
+
+  void set_error(const std::string &state, int r) {
+    m_errors[state] = r;
+  }
+
+  int get_error(const std::string &state) const {
+    std::map<std::string, int>::const_iterator i = m_errors.find(state);
+    return i == m_errors.end() ? 0 : i->second;
+  }
+
+protected:
+  virtual void on_start_get_registered_client_status_finish(int r,
+      const std::set<cls::journal::Client> &registered_clients,
+      const BootstrapParams &bootstrap_params) {
+      rbd::mirror::ImageReplayer::on_start_get_registered_client_status_finish(
+	get_error("on_start_get_registered_client_status"), registered_clients,
+	bootstrap_params);
+  }
+
+  virtual void on_start_remote_journaler_init_finish(int r) {
+    ASSERT_EQ(0, r);
+    rbd::mirror::ImageReplayer::on_start_remote_journaler_init_finish(
+      get_error("on_start_remote_journaler_init"));
+  }
+
+  virtual void on_start_local_image_open_finish(int r) {
+    int test_r = get_error("on_start_local_image_open");
+    if (!test_r) {
+      rbd::mirror::ImageReplayer::on_start_local_image_open_finish(r);
+      return;
+    }
+
+    // The image open error was imitated, so we need to close the image back
+    // before propagating the error.
+    ASSERT_EQ(0, r);
+    set_error("on_start_local_image_open", 0);
+    FunctionContext *ctx = new FunctionContext(
+      [this, test_r](int r) {
+	on_start_local_image_open_finish(test_r);
+      });
+    close_local_image(ctx);
+  }
+
+  virtual void on_start_wait_for_local_journal_ready_finish(int r) {
+    ASSERT_EQ(0, r);
+    rbd::mirror::ImageReplayer::on_start_wait_for_local_journal_ready_finish(
+      get_error("on_start_wait_for_local_journal_ready"));
+  }
+
+  virtual void on_stop_journal_replay_shut_down_finish(int r) {
+    ASSERT_EQ(0, r);
+    rbd::mirror::ImageReplayer::on_stop_journal_replay_shut_down_finish(
+      get_error("on_stop_journal_replay_shut_down"));
+  }
+
+  virtual void on_stop_local_image_close_finish(int r) {
+    ASSERT_EQ(0, r);
+    rbd::mirror::ImageReplayer::on_stop_local_image_close_finish(
+      get_error("on_stop_local_image_close"));
+  }
+
+private:
+  std::map<std::string, int> m_errors;
+};
+
+#define TEST_ON_START_ERROR(state) \
+TEST_F(TestImageReplayer, Error_on_start_##state)			\
+{									\
+  create_replayer<ImageReplayer>();					\
+  reinterpret_cast<ImageReplayer *>(m_replayer)->			\
+    set_error("on_start_" #state, -1);					\
+  rbd::mirror::ImageReplayer::BootstrapParams				\
+    bootstap_params(m_local_pool_name, m_image_name);			\
+  C_SaferCond cond;							\
+  m_replayer->start(&cond, &bootstap_params);				\
+  ASSERT_EQ(-1, cond.wait());						\
+}
+
+#define TEST_ON_STOP_ERROR(state) \
+TEST_F(TestImageReplayer, Error_on_stop_##state)			\
+{									\
+  create_replayer<ImageReplayer>();					\
+  reinterpret_cast<ImageReplayer *>(m_replayer)->			\
+    set_error("on_stop_" #state, -1);					\
+  rbd::mirror::ImageReplayer::BootstrapParams				\
+    bootstap_params(m_local_pool_name, m_image_name);			\
+  start(&bootstap_params);						\
+  /* TODO: investigate: without wait below I observe: */		\
+  /* librbd/journal/Replay.cc: 70: FAILED assert(m_op_events.empty()) */\
+  wait_for_replay_complete();						\
+  C_SaferCond cond;							\
+  m_replayer->stop(&cond);						\
+  ASSERT_EQ(0, cond.wait());						\
+}
+
+TEST_ON_START_ERROR(get_registered_client_status);
+TEST_ON_START_ERROR(remote_journaler_init);
+TEST_ON_START_ERROR(wait_for_local_journal_ready);
+
+TEST_ON_STOP_ERROR(journal_replay_shut_down);
+TEST_ON_STOP_ERROR(no_error);
+
diff --git a/src/test/rbd_mirror/test_ImageSync.cc b/src/test/rbd_mirror/test_ImageSync.cc
new file mode 100644
index 0000000..10622a1
--- /dev/null
+++ b/src/test/rbd_mirror/test_ImageSync.cc
@@ -0,0 +1,130 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+
+#include "test/rbd_mirror/test_fixture.h"
+#include "include/rbd/librbd.hpp"
+#include "journal/Journaler.h"
+#include "librbd/AioImageRequestWQ.h"
+#include "librbd/ExclusiveLock.h"
+#include "librbd/ImageCtx.h"
+#include "librbd/ImageState.h"
+#include "tools/rbd_mirror/ImageSync.h"
+#include "tools/rbd_mirror/Threads.h"
+
+void register_test_image_sync() {
+}
+
+namespace rbd {
+namespace mirror {
+
+namespace {
+
+void scribble(librbd::ImageCtx *image_ctx, int num_ops, size_t max_size)
+{
+  for (int i=0; i<num_ops; i++) {
+    uint64_t off = rand() % (image_ctx->size - max_size + 1);
+    uint64_t len = 1 + rand() % max_size;
+
+    if (rand() % 4 == 0) {
+      ASSERT_EQ((int)len, image_ctx->aio_work_queue->discard(off, len));
+    } else {
+      std::string str(len, '1');
+      ASSERT_EQ((int)len, image_ctx->aio_work_queue->write(off, len,
+                                                           str.c_str(), 0));
+    }
+  }
+}
+
+} // anonymous namespace
+class TestImageSync : public TestFixture {
+public:
+
+  virtual void SetUp() {
+    TestFixture::SetUp();
+    create_and_open(m_local_io_ctx, &m_local_image_ctx);
+    create_and_open(m_remote_io_ctx, &m_remote_image_ctx);
+
+    m_remote_journaler = new ::journal::Journaler(
+      m_threads->work_queue, m_threads->timer, &m_threads->timer_lock,
+      m_remote_io_ctx, m_remote_image_ctx->id, "mirror-uuid", 5);
+
+    m_client_meta = {"image-id"};
+
+    librbd::journal::ClientData client_data(m_client_meta);
+    bufferlist client_data_bl;
+    ::encode(client_data, client_data_bl);
+
+    ASSERT_EQ(0, m_remote_journaler->register_client(client_data_bl));
+  }
+
+  void create_and_open(librados::IoCtx &io_ctx, librbd::ImageCtx **image_ctx) {
+    librbd::RBD rbd;
+    ASSERT_EQ(0, create_image(rbd, io_ctx, m_image_name, m_image_size));
+    ASSERT_EQ(0, open_image(io_ctx, m_image_name, image_ctx));
+
+    C_SaferCond ctx;
+    {
+      RWLock::RLocker owner_locker((*image_ctx)->owner_lock);
+      (*image_ctx)->exclusive_lock->try_lock(&ctx);
+    }
+    ASSERT_EQ(0, ctx.wait());
+    ASSERT_TRUE((*image_ctx)->exclusive_lock->is_lock_owner());
+  }
+
+  ImageSync<> *create_request(Context *ctx) {
+    return new ImageSync<>(m_local_image_ctx, m_remote_image_ctx,
+                           m_threads->timer, &m_threads->timer_lock,
+                           "mirror-uuid", m_remote_journaler, &m_client_meta,
+                           ctx);
+  }
+
+  librbd::ImageCtx *m_remote_image_ctx;
+  librbd::ImageCtx *m_local_image_ctx;
+  ::journal::Journaler *m_remote_journaler;
+  librbd::journal::MirrorPeerClientMeta m_client_meta;
+};
+
+TEST_F(TestImageSync, Empty) {
+  C_SaferCond ctx;
+  ImageSync<> *request = create_request(&ctx);
+  request->start();
+  ASSERT_EQ(0, ctx.wait());
+
+  ASSERT_EQ(0U, m_client_meta.sync_points.size());
+  ASSERT_EQ(0, m_remote_image_ctx->state->refresh());
+  ASSERT_EQ(0U, m_remote_image_ctx->snap_ids.size());
+  ASSERT_EQ(0, m_local_image_ctx->state->refresh());
+  ASSERT_EQ(1U, m_local_image_ctx->snap_ids.size()); // deleted on journal replay
+}
+
+TEST_F(TestImageSync, Simple) {
+  scribble(m_remote_image_ctx, 10, 102400);
+  {
+    RWLock::RLocker owner_locker(m_remote_image_ctx->owner_lock);
+    ASSERT_EQ(0, m_remote_image_ctx->flush());
+  }
+
+  C_SaferCond ctx;
+  ImageSync<> *request = create_request(&ctx);
+  request->start();
+  ASSERT_EQ(0, ctx.wait());
+
+  int64_t object_size = std::min<int64_t>(
+    m_remote_image_ctx->size, 1 << m_remote_image_ctx->order);
+  bufferlist read_remote_bl;
+  read_remote_bl.append(std::string(object_size, '1'));
+  bufferlist read_local_bl;
+  read_local_bl.append(std::string(object_size, '1'));
+
+  for (uint64_t offset = 0; offset < m_remote_image_ctx->size;
+       offset += object_size) {
+    ASSERT_LE(0, m_remote_image_ctx->aio_work_queue->read(
+                   offset, object_size, read_remote_bl.c_str(), 0));
+    ASSERT_LE(0, m_local_image_ctx->aio_work_queue->read(
+                   offset, object_size, read_local_bl.c_str(), 0));
+    ASSERT_TRUE(read_remote_bl.contents_equal(read_local_bl));
+  }
+}
+
+} // namespace mirror
+} // namespace rbd
diff --git a/src/test/rbd_mirror/test_PoolWatcher.cc b/src/test/rbd_mirror/test_PoolWatcher.cc
index d176828..5cb6805 100644
--- a/src/test/rbd_mirror/test_PoolWatcher.cc
+++ b/src/test/rbd_mirror/test_PoolWatcher.cc
@@ -53,7 +53,7 @@ TestPoolWatcher() : m_lock("TestPoolWatcherLock"),
   }
 
   void create_pool(bool enable_mirroring, const peer_t &peer, string *name=nullptr) {
-    string pool_name = get_temp_pool_name();
+    string pool_name = get_temp_pool_name("test-rbd-mirror-");
     ASSERT_EQ("", create_one_pool_pp(pool_name, *m_cluster));
     int64_t pool_id = m_cluster->pool_lookup(pool_name.c_str());
     ASSERT_GE(pool_id, 0);
@@ -61,8 +61,9 @@ TestPoolWatcher() : m_lock("TestPoolWatcherLock"),
     if (enable_mirroring) {
       librados::IoCtx ioctx;
       ASSERT_EQ(0, m_cluster->ioctx_create2(pool_id, ioctx));
-      ASSERT_EQ(0, librbd::mirror_set_enabled(ioctx, true));
-      ASSERT_EQ(0, librbd::mirror_peer_add(ioctx, peer.cluster_uuid,
+      ASSERT_EQ(0, librbd::mirror_mode_set(ioctx, RBD_MIRROR_MODE_POOL));
+      std::string uuid;
+      ASSERT_EQ(0, librbd::mirror_peer_add(ioctx, &uuid,
 					   peer.cluster_name,
 					   peer.client_name));
     }
@@ -81,7 +82,7 @@ TestPoolWatcher() : m_lock("TestPoolWatcherLock"),
 
   void create_cache_pool(const string &base_pool, string *cache_pool_name) {
     bufferlist inbl;
-    *cache_pool_name = get_temp_pool_name();
+    *cache_pool_name = get_temp_pool_name("test-rbd-mirror-");
     ASSERT_EQ("", create_one_pool_pp(*cache_pool_name, *m_cluster));
     ASSERT_EQ(0, m_cluster->mon_command(
       "{\"prefix\": \"osd tier add\", \"pool\": \"" + base_pool +
@@ -134,8 +135,14 @@ TestPoolWatcher() : m_lock("TestPoolWatcherLock"),
     int order = 0;
     ASSERT_EQ(0, librbd::create(ioctx, name.c_str(), 1 << 22, false,
 				features, &order, 0, 0));
-    if (mirrored)
+    if (mirrored) {
+      librbd::Image image;
+      librbd::RBD rbd;
+      rbd.open(ioctx, image, name.c_str());
+      image.mirror_image_enable();
+      image.close();
       m_mirrored_images[ioctx.get_id()].insert(get_image_id(&ioctx, name));
+    }
     if (image_name != nullptr)
       *image_name = name;
   }
@@ -167,8 +174,14 @@ TestPoolWatcher() : m_lock("TestPoolWatcherLock"),
     int order = 0;
     librbd::clone(pioctx, parent_image_name.c_str(), snap_name.c_str(),
 		  cioctx, name.c_str(), features, &order, 0, 0);
-    if (mirrored)
+    if (mirrored) {
+      librbd::Image image;
+      librbd::RBD rbd;
+      rbd.open(cioctx, image, name.c_str());
+      image.mirror_image_enable();
+      image.close();
       m_mirrored_images[cioctx.get_id()].insert(get_image_id(&cioctx, name));
+    }
     if (image_name != nullptr)
       *image_name = name;
   }
@@ -213,6 +226,8 @@ TEST_F(TestPoolWatcher, ReplicatedPools) {
   check_images();
   clone_image(first_pool, parent_image, first_pool, true, &parent_image2);
   check_images();
+  create_image(first_pool, false);
+  check_images();
 
   create_pool(false, peer_t(), &local_pool);
   check_images();
@@ -248,6 +263,8 @@ TEST_F(TestPoolWatcher, CachePools) {
   check_images();
   create_image(base1);
   check_images();
+  create_image(base1, false);
+  check_images();
 
   create_pool(false, peer_t(), &base2);
   create_cache_pool(base2, &cache2);
diff --git a/src/test/rbd_mirror/test_fixture.cc b/src/test/rbd_mirror/test_fixture.cc
new file mode 100644
index 0000000..56620db
--- /dev/null
+++ b/src/test/rbd_mirror/test_fixture.cc
@@ -0,0 +1,101 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+
+#include "test/rbd_mirror/test_fixture.h"
+#include "include/stringify.h"
+#include "include/rbd/librbd.hpp"
+#include "librbd/ImageCtx.h"
+#include "librbd/ImageState.h"
+#include "librbd/Operations.h"
+#include "test/librados/test.h"
+#include "tools/rbd_mirror/Threads.h"
+
+namespace rbd {
+namespace mirror {
+
+std::string TestFixture::_local_pool_name;
+std::string TestFixture::_remote_pool_name;
+librados::Rados TestFixture::_rados;
+uint64_t TestFixture::_image_number = 0;
+
+TestFixture::TestFixture() {
+}
+
+void TestFixture::SetUpTestCase() {
+  _local_pool_name = get_temp_pool_name("test-rbd-mirror-");
+  ASSERT_EQ("", create_one_pool_pp(_local_pool_name, _rados));
+
+  _remote_pool_name = get_temp_pool_name("test-rbd-mirror-");
+  ASSERT_EQ("", create_one_pool_pp(_remote_pool_name, _rados));
+}
+
+void TestFixture::TearDownTestCase() {
+  ASSERT_EQ(0, _rados.pool_delete(_remote_pool_name.c_str()));
+  ASSERT_EQ(0, _rados.pool_delete(_local_pool_name.c_str()));
+  _rados.shutdown();
+}
+
+void TestFixture::SetUp() {
+  ASSERT_EQ(0, _rados.ioctx_create(_local_pool_name.c_str(), m_local_io_ctx));
+  ASSERT_EQ(0, _rados.ioctx_create(_remote_pool_name.c_str(), m_remote_io_ctx));
+  m_image_name = get_temp_image_name();
+
+  m_threads = new rbd::mirror::Threads(reinterpret_cast<CephContext*>(
+    m_local_io_ctx.cct()));
+}
+
+void TestFixture::TearDown() {
+  for (auto image_ctx : m_image_ctxs) {
+    image_ctx->state->close();
+  }
+
+  m_remote_io_ctx.close();
+  m_local_io_ctx.close();
+
+  delete m_threads;
+}
+
+int TestFixture::create_image(librbd::RBD &rbd, librados::IoCtx &ioctx,
+                              const std::string &name, uint64_t size) {
+  int order = 18;
+  return rbd.create2(ioctx, name.c_str(), size, RBD_FEATURES_ALL, &order);
+}
+
+int TestFixture::open_image(librados::IoCtx &io_ctx,
+                            const std::string &image_name,
+                            librbd::ImageCtx **image_ctx) {
+  *image_ctx = new librbd::ImageCtx(image_name.c_str(), "", NULL, io_ctx,
+                                    false);
+  m_image_ctxs.insert(*image_ctx);
+  return (*image_ctx)->state->open();
+}
+
+int TestFixture::create_snap(librbd::ImageCtx *image_ctx, const char* snap_name,
+                             librados::snap_t *snap_id) {
+  int r = image_ctx->operations->snap_create(snap_name);
+  if (r < 0) {
+    return r;
+  }
+
+  r = image_ctx->state->refresh();
+  if (r < 0) {
+    return r;
+  }
+
+  if (image_ctx->snap_ids.count(snap_name) == 0) {
+    return -ENOENT;
+  }
+
+  if (snap_id != nullptr) {
+    *snap_id = image_ctx->snap_ids[snap_name];
+  }
+  return 0;
+}
+
+std::string TestFixture::get_temp_image_name() {
+  ++_image_number;
+  return "image" + stringify(_image_number);
+}
+
+} // namespace mirror
+} // namespace rbd
diff --git a/src/test/rbd_mirror/test_fixture.h b/src/test/rbd_mirror/test_fixture.h
new file mode 100644
index 0000000..79a6f86
--- /dev/null
+++ b/src/test/rbd_mirror/test_fixture.h
@@ -0,0 +1,61 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+
+#ifndef CEPH_TEST_RBD_MIRROR_TEST_FIXTURE_H
+#define CEPH_TEST_RBD_MIRROR_TEST_FIXTURE_H
+
+#include "include/int_types.h"
+#include "include/rados/librados.hpp"
+#include <gtest/gtest.h>
+#include <set>
+
+namespace librbd {
+class ImageCtx;
+class RBD;
+}
+
+namespace rbd {
+namespace mirror {
+
+class Threads;
+
+class TestFixture : public ::testing::Test {
+public:
+  TestFixture();
+
+  static void SetUpTestCase();
+  static void TearDownTestCase();
+
+  virtual void SetUp();
+  virtual void TearDown();
+
+  librados::IoCtx m_local_io_ctx;
+  librados::IoCtx m_remote_io_ctx;
+
+  std::string m_image_name;
+  uint64_t m_image_size = 1 << 24;
+
+  std::set<librbd::ImageCtx *> m_image_ctxs;
+
+  Threads *m_threads = nullptr;
+
+  int create_image(librbd::RBD &rbd, librados::IoCtx &ioctx,
+                   const std::string &name, uint64_t size);
+  int open_image(librados::IoCtx &io_ctx, const std::string &image_name,
+                 librbd::ImageCtx **image_ctx);
+
+  int create_snap(librbd::ImageCtx *image_ctx, const char* snap_name,
+                  librados::snap_t *snap_id = nullptr);
+
+  static std::string get_temp_image_name();
+
+  static std::string _local_pool_name;
+  static std::string _remote_pool_name;
+  static librados::Rados _rados;
+  static uint64_t _image_number;
+};
+
+} // namespace mirror
+} // namespace rbd
+
+#endif // CEPH_TEST_RBD_MIRROR_TEST_FIXTURE_H
diff --git a/src/test/rbd_mirror/test_main.cc b/src/test/rbd_mirror/test_main.cc
index ca24d94..71fe23a 100644
--- a/src/test/rbd_mirror/test_main.cc
+++ b/src/test/rbd_mirror/test_main.cc
@@ -10,11 +10,15 @@
 
 extern void register_test_cluster_watcher();
 extern void register_test_pool_watcher();
+extern void register_test_rbd_mirror();
+extern void register_test_image_sync();
 
 int main(int argc, char **argv)
 {
   register_test_cluster_watcher();
   register_test_pool_watcher();
+  register_test_rbd_mirror();
+  register_test_image_sync();
 
   ::testing::InitGoogleTest(&argc, argv);
 
diff --git a/src/test/rbd_mirror/test_mock_ImageSync.cc b/src/test/rbd_mirror/test_mock_ImageSync.cc
new file mode 100644
index 0000000..726fa95
--- /dev/null
+++ b/src/test/rbd_mirror/test_mock_ImageSync.cc
@@ -0,0 +1,337 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+
+#include "test/rbd_mirror/test_mock_fixture.h"
+#include "include/rbd/librbd.hpp"
+#include "librbd/journal/Types.h"
+#include "test/librados_test_stub/MockTestMemIoCtxImpl.h"
+#include "test/librbd/mock/MockImageCtx.h"
+#include "test/librbd/mock/MockObjectMap.h"
+#include "test/rbd_mirror/mock/MockJournaler.h"
+#include "tools/rbd_mirror/ImageSync.h"
+#include "tools/rbd_mirror/Threads.h"
+#include "tools/rbd_mirror/image_sync/ImageCopyRequest.h"
+#include "tools/rbd_mirror/image_sync/SnapshotCopyRequest.h"
+#include "tools/rbd_mirror/image_sync/SyncPointCreateRequest.h"
+#include "tools/rbd_mirror/image_sync/SyncPointPruneRequest.h"
+
+// template definitions
+#include "tools/rbd_mirror/ImageSync.cc"
+template class rbd::mirror::ImageSync<librbd::MockImageCtx>;
+
+namespace rbd {
+namespace mirror {
+
+namespace image_sync {
+
+template <>
+class ImageCopyRequest<librbd::MockImageCtx> {
+public:
+  static ImageCopyRequest* s_instance;
+  Context *on_finish;
+
+  static ImageCopyRequest* create(librbd::MockImageCtx *local_image_ctx,
+                                  librbd::MockImageCtx *remote_image_ctx,
+                                  SafeTimer *timer, Mutex *timer_lock,
+                                  journal::MockJournaler *journaler,
+                                  librbd::journal::MirrorPeerClientMeta *client_meta,
+                                  librbd::journal::MirrorPeerSyncPoint *sync_point,
+                                  Context *on_finish) {
+    assert(s_instance != nullptr);
+    s_instance->on_finish = on_finish;
+    return s_instance;
+  }
+
+  ImageCopyRequest() {
+    s_instance = this;
+  }
+  MOCK_METHOD0(cancel, void());
+  MOCK_METHOD0(send, void());
+};
+
+template <>
+class SnapshotCopyRequest<librbd::MockImageCtx> {
+public:
+  static SnapshotCopyRequest* s_instance;
+  Context *on_finish;
+
+  static SnapshotCopyRequest* create(librbd::MockImageCtx *local_image_ctx,
+                                     librbd::MockImageCtx *remote_image_ctx,
+                                     SnapshotCopyRequest<librbd::ImageCtx>::SnapMap *snap_map,
+                                     journal::MockJournaler *journaler,
+                                     librbd::journal::MirrorPeerClientMeta *client_meta,
+                                     Context *on_finish) {
+    assert(s_instance != nullptr);
+    s_instance->on_finish = on_finish;
+    return s_instance;
+  }
+
+  SnapshotCopyRequest() {
+    s_instance = this;
+  }
+  MOCK_METHOD0(send, void());
+};
+
+template <>
+class SyncPointCreateRequest<librbd::MockImageCtx> {
+public:
+  static SyncPointCreateRequest *s_instance;
+  Context *on_finish;
+
+  static SyncPointCreateRequest* create(librbd::MockImageCtx *remote_image_ctx,
+                                        const std::string &mirror_uuid,
+                                        journal::MockJournaler *journaler,
+                                        librbd::journal::MirrorPeerClientMeta *client_meta,
+                                        Context *on_finish) {
+    assert(s_instance != nullptr);
+    s_instance->on_finish = on_finish;
+    return s_instance;
+  }
+
+  SyncPointCreateRequest() {
+    s_instance = this;
+  }
+  MOCK_METHOD0(send, void());
+};
+
+template <>
+class SyncPointPruneRequest<librbd::MockImageCtx> {
+public:
+  static SyncPointPruneRequest *s_instance;
+  Context *on_finish;
+  bool sync_complete;
+
+  static SyncPointPruneRequest* create(librbd::MockImageCtx *remote_image_ctx,
+                                       bool sync_complete,
+                                       journal::MockJournaler *journaler,
+                                       librbd::journal::MirrorPeerClientMeta *client_meta,
+                                       Context *on_finish) {
+    assert(s_instance != nullptr);
+    s_instance->on_finish = on_finish;
+    s_instance->sync_complete = sync_complete;
+    return s_instance;
+  }
+
+  SyncPointPruneRequest() {
+    s_instance = this;
+  }
+  MOCK_METHOD0(send, void());
+};
+
+ImageCopyRequest<librbd::MockImageCtx>* ImageCopyRequest<librbd::MockImageCtx>::s_instance = nullptr;
+SnapshotCopyRequest<librbd::MockImageCtx>* SnapshotCopyRequest<librbd::MockImageCtx>::s_instance = nullptr;
+SyncPointCreateRequest<librbd::MockImageCtx>* SyncPointCreateRequest<librbd::MockImageCtx>::s_instance = nullptr;
+SyncPointPruneRequest<librbd::MockImageCtx>* SyncPointPruneRequest<librbd::MockImageCtx>::s_instance = nullptr;
+
+} // namespace image_sync
+
+using ::testing::_;
+using ::testing::InSequence;
+using ::testing::Invoke;
+using ::testing::Return;
+using ::testing::WithArg;
+
+class TestMockImageSync : public TestMockFixture {
+public:
+  typedef ImageSync<librbd::MockImageCtx> MockImageSync;
+  typedef image_sync::ImageCopyRequest<librbd::MockImageCtx> MockImageCopyRequest;
+  typedef image_sync::SnapshotCopyRequest<librbd::MockImageCtx> MockSnapshotCopyRequest;
+  typedef image_sync::SyncPointCreateRequest<librbd::MockImageCtx> MockSyncPointCreateRequest;
+  typedef image_sync::SyncPointPruneRequest<librbd::MockImageCtx> MockSyncPointPruneRequest;
+
+  virtual void SetUp() {
+    TestMockFixture::SetUp();
+
+    librbd::RBD rbd;
+    ASSERT_EQ(0, create_image(rbd, m_remote_io_ctx, m_image_name, m_image_size));
+    ASSERT_EQ(0, open_image(m_remote_io_ctx, m_image_name, &m_remote_image_ctx));
+
+    ASSERT_EQ(0, create_image(rbd, m_local_io_ctx, m_image_name, m_image_size));
+    ASSERT_EQ(0, open_image(m_local_io_ctx, m_image_name, &m_local_image_ctx));
+  }
+
+  void expect_create_sync_point(librbd::MockImageCtx &mock_local_image_ctx,
+                                MockSyncPointCreateRequest &mock_sync_point_create_request,
+                                int r) {
+    EXPECT_CALL(mock_sync_point_create_request, send())
+      .WillOnce(Invoke([this, &mock_local_image_ctx, &mock_sync_point_create_request, r]() {
+          if (r == 0) {
+            mock_local_image_ctx.snap_ids["snap1"] = 123;
+            m_client_meta.sync_points.emplace_back("snap1", boost::none);
+          }
+          m_threads->work_queue->queue(mock_sync_point_create_request.on_finish, r);
+        }));
+  }
+
+  void expect_copy_snapshots(MockSnapshotCopyRequest &mock_snapshot_copy_request, int r) {
+    EXPECT_CALL(mock_snapshot_copy_request, send())
+      .WillOnce(Invoke([this, &mock_snapshot_copy_request, r]() {
+          m_threads->work_queue->queue(mock_snapshot_copy_request.on_finish, r);
+        }));
+  }
+
+  void expect_copy_image(MockImageCopyRequest &mock_image_copy_request, int r) {
+    EXPECT_CALL(mock_image_copy_request, send())
+      .WillOnce(Invoke([this, &mock_image_copy_request, r]() {
+          m_threads->work_queue->queue(mock_image_copy_request.on_finish, r);
+        }));
+  }
+
+  void expect_rollback_object_map(librbd::MockObjectMap &mock_object_map, int r) {
+    if ((m_local_image_ctx->features & RBD_FEATURE_OBJECT_MAP) != 0) {
+      EXPECT_CALL(mock_object_map, rollback(_, _))
+        .WillOnce(WithArg<1>(Invoke([this, r](Context *ctx) {
+            m_threads->work_queue->queue(ctx, r);
+          })));
+    }
+  }
+
+  void expect_create_object_map(librbd::MockImageCtx &mock_image_ctx,
+                                librbd::MockObjectMap *mock_object_map) {
+    EXPECT_CALL(mock_image_ctx, create_object_map(CEPH_NOSNAP))
+      .WillOnce(Return(mock_object_map));
+  }
+
+  void expect_open_object_map(librbd::MockImageCtx &mock_image_ctx,
+                              librbd::MockObjectMap &mock_object_map) {
+    EXPECT_CALL(mock_object_map, open(_))
+      .WillOnce(Invoke([this](Context *ctx) {
+          m_threads->work_queue->queue(ctx, 0);
+        }));
+  }
+
+  void expect_prune_sync_point(MockSyncPointPruneRequest &mock_sync_point_prune_request,
+                               bool sync_complete, int r) {
+    EXPECT_CALL(mock_sync_point_prune_request, send())
+      .WillOnce(Invoke([this, &mock_sync_point_prune_request, sync_complete, r]() {
+          ASSERT_EQ(sync_complete, mock_sync_point_prune_request.sync_complete);
+          if (r == 0 && !m_client_meta.sync_points.empty()) {
+            if (sync_complete) {
+              m_client_meta.sync_points.pop_front();
+            } else {
+              while (m_client_meta.sync_points.size() > 1) {
+                m_client_meta.sync_points.pop_back();
+              }
+            }
+          }
+          m_threads->work_queue->queue(mock_sync_point_prune_request.on_finish, r);
+        }));
+  }
+
+  MockImageSync *create_request(librbd::MockImageCtx &mock_remote_image_ctx,
+                                librbd::MockImageCtx &mock_local_image_ctx,
+                                journal::MockJournaler &mock_journaler,
+                                Context *ctx) {
+    return new MockImageSync(&mock_local_image_ctx, &mock_remote_image_ctx,
+                             m_threads->timer, &m_threads->timer_lock,
+                             "mirror-uuid", &mock_journaler, &m_client_meta,
+                             ctx);
+  }
+
+  librbd::ImageCtx *m_remote_image_ctx;
+  librbd::ImageCtx *m_local_image_ctx;
+  librbd::journal::MirrorPeerClientMeta m_client_meta;
+};
+
+TEST_F(TestMockImageSync, SimpleSync) {
+  librbd::MockImageCtx mock_remote_image_ctx(*m_remote_image_ctx);
+  librbd::MockImageCtx mock_local_image_ctx(*m_local_image_ctx);
+  journal::MockJournaler mock_journaler;
+  MockImageCopyRequest mock_image_copy_request;
+  MockSnapshotCopyRequest mock_snapshot_copy_request;
+  MockSyncPointCreateRequest mock_sync_point_create_request;
+  MockSyncPointPruneRequest mock_sync_point_prune_request;
+
+  librbd::MockObjectMap *mock_object_map = new librbd::MockObjectMap();
+  mock_local_image_ctx.object_map = mock_object_map;
+  expect_test_features(mock_local_image_ctx);
+
+  InSequence seq;
+  expect_create_sync_point(mock_local_image_ctx, mock_sync_point_create_request, 0);
+  expect_copy_snapshots(mock_snapshot_copy_request, 0);
+  expect_copy_image(mock_image_copy_request, 0);
+  expect_rollback_object_map(*mock_object_map, 0);
+  expect_create_object_map(mock_local_image_ctx, mock_object_map);
+  expect_open_object_map(mock_local_image_ctx, *mock_object_map);
+  expect_prune_sync_point(mock_sync_point_prune_request, true, 0);
+
+  C_SaferCond ctx;
+  MockImageSync *request = create_request(mock_remote_image_ctx,
+                                          mock_local_image_ctx,
+                                          mock_journaler, &ctx);
+  request->start();
+  ASSERT_EQ(0, ctx.wait());
+}
+
+TEST_F(TestMockImageSync, RestartSync) {
+  librbd::MockImageCtx mock_remote_image_ctx(*m_remote_image_ctx);
+  librbd::MockImageCtx mock_local_image_ctx(*m_local_image_ctx);
+  journal::MockJournaler mock_journaler;
+  MockImageCopyRequest mock_image_copy_request;
+  MockSnapshotCopyRequest mock_snapshot_copy_request;
+  MockSyncPointCreateRequest mock_sync_point_create_request;
+  MockSyncPointPruneRequest mock_sync_point_prune_request;
+
+  m_client_meta.sync_points = {{"snap1", boost::none},
+                               {"snap2", "snap1", boost::none}};
+  mock_local_image_ctx.snap_ids["snap1"] = 123;
+  mock_local_image_ctx.snap_ids["snap2"] = 234;
+
+  librbd::MockObjectMap *mock_object_map = new librbd::MockObjectMap();
+  mock_local_image_ctx.object_map = mock_object_map;
+  expect_test_features(mock_local_image_ctx);
+
+  InSequence seq;
+  expect_prune_sync_point(mock_sync_point_prune_request, false, 0);
+  expect_copy_snapshots(mock_snapshot_copy_request, 0);
+  expect_copy_image(mock_image_copy_request, 0);
+  expect_rollback_object_map(*mock_object_map, 0);
+  expect_create_object_map(mock_local_image_ctx, mock_object_map);
+  expect_open_object_map(mock_local_image_ctx, *mock_object_map);
+  expect_prune_sync_point(mock_sync_point_prune_request, true, 0);
+
+  C_SaferCond ctx;
+  MockImageSync *request = create_request(mock_remote_image_ctx,
+                                          mock_local_image_ctx,
+                                          mock_journaler, &ctx);
+  request->start();
+  ASSERT_EQ(0, ctx.wait());
+}
+
+TEST_F(TestMockImageSync, CancelImageCopy) {
+  librbd::MockImageCtx mock_remote_image_ctx(*m_remote_image_ctx);
+  librbd::MockImageCtx mock_local_image_ctx(*m_local_image_ctx);
+  journal::MockJournaler mock_journaler;
+  MockImageCopyRequest mock_image_copy_request;
+  MockSnapshotCopyRequest mock_snapshot_copy_request;
+  MockSyncPointCreateRequest mock_sync_point_create_request;
+  MockSyncPointPruneRequest mock_sync_point_prune_request;
+
+  m_client_meta.sync_points = {{"snap1", boost::none}};
+
+  InSequence seq;
+  expect_copy_snapshots(mock_snapshot_copy_request, 0);
+
+  C_SaferCond image_copy_ctx;
+  EXPECT_CALL(mock_image_copy_request, send())
+    .WillOnce(Invoke([&image_copy_ctx]() {
+        image_copy_ctx.complete(0);
+      }));
+  EXPECT_CALL(mock_image_copy_request, cancel());
+
+  C_SaferCond ctx;
+  MockImageSync *request = create_request(mock_remote_image_ctx,
+                                          mock_local_image_ctx,
+                                          mock_journaler, &ctx);
+  request->start();
+
+  // cancel the image copy once it starts
+  ASSERT_EQ(0, image_copy_ctx.wait());
+  request->cancel();
+  m_threads->work_queue->queue(mock_image_copy_request.on_finish, 0);
+
+  ASSERT_EQ(-ECANCELED, ctx.wait());
+}
+
+} // namespace mirror
+} // namespace rbd
diff --git a/src/test/rbd_mirror/test_mock_fixture.cc b/src/test/rbd_mirror/test_mock_fixture.cc
new file mode 100644
index 0000000..6f45ca9
--- /dev/null
+++ b/src/test/rbd_mirror/test_mock_fixture.cc
@@ -0,0 +1,59 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+
+#include "test/rbd_mirror/test_mock_fixture.h"
+#include "include/rbd/librbd.hpp"
+#include "test/librados_test_stub/LibradosTestStub.h"
+#include "test/librados_test_stub/MockTestMemRadosClient.h"
+#include "test/librbd/mock/MockImageCtx.h"
+
+namespace rbd {
+namespace mirror {
+
+using ::testing::_;
+using ::testing::Invoke;
+using ::testing::WithArg;
+
+TestMockFixture::TestRadosClientPtr TestMockFixture::s_test_rados_client;
+::testing::NiceMock<librados::MockTestMemRadosClient> *
+  TestMockFixture::s_mock_rados_client = NULL;
+
+void TestMockFixture::SetUpTestCase() {
+  s_test_rados_client = librados_test_stub::get_rados_client();
+
+  // use a mock version of the in-memory rados client
+  s_mock_rados_client = new ::testing::NiceMock<librados::MockTestMemRadosClient>(
+      s_test_rados_client->cct());
+  librados_test_stub::set_rados_client(TestRadosClientPtr(s_mock_rados_client));
+  TestFixture::SetUpTestCase();
+}
+
+void TestMockFixture::TearDownTestCase() {
+  TestFixture::TearDownTestCase();
+  librados_test_stub::set_rados_client(s_test_rados_client);
+  s_test_rados_client->put();
+  s_test_rados_client.reset();
+}
+
+void TestMockFixture::SetUp() {
+  TestFixture::SetUp();
+}
+
+void TestMockFixture::TearDown() {
+  TestFixture::TearDown();
+
+  // Mock rados client lives across tests -- reset it to initial state
+  ::testing::Mock::VerifyAndClear(s_mock_rados_client);
+  s_mock_rados_client->default_to_dispatch();
+}
+
+void TestMockFixture::expect_test_features(librbd::MockImageCtx &mock_image_ctx) {
+  EXPECT_CALL(mock_image_ctx, test_features(_, _))
+    .WillRepeatedly(WithArg<0>(Invoke([&mock_image_ctx](uint64_t features) {
+        return (mock_image_ctx.features & features) != 0;
+      })));
+}
+
+} // namespace mirror
+} // namespace rbd
+
diff --git a/src/test/rbd_mirror/test_mock_fixture.h b/src/test/rbd_mirror/test_mock_fixture.h
new file mode 100644
index 0000000..5ce1a74
--- /dev/null
+++ b/src/test/rbd_mirror/test_mock_fixture.h
@@ -0,0 +1,53 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+
+#ifndef CEPH_TEST_RBD_MIRROR_TEST_MOCK_FIXTURE_H
+#define CEPH_TEST_RBD_MIRROR_TEST_MOCK_FIXTURE_H
+
+#include "test/rbd_mirror/test_fixture.h"
+#include "test/librados_test_stub/LibradosTestStub.h"
+#include <boost/shared_ptr.hpp>
+#include <gmock/gmock.h>
+
+namespace librados {
+class TestRadosClient;
+class MockTestMemIoCtxImpl;
+class MockTestMemRadosClient;
+}
+
+namespace librbd {
+class MockImageCtx;
+}
+
+ACTION_P(CompleteContext, r) {
+  arg0->complete(r);
+}
+
+namespace rbd {
+namespace mirror {
+
+class TestMockFixture : public TestFixture {
+public:
+  typedef boost::shared_ptr<librados::TestRadosClient> TestRadosClientPtr;
+
+  static void SetUpTestCase();
+  static void TearDownTestCase();
+
+  virtual void SetUp();
+  virtual void TearDown();
+
+  void expect_test_features(librbd::MockImageCtx &mock_image_ctx);
+
+  ::testing::NiceMock<librados::MockTestMemRadosClient> &get_mock_rados_client() {
+    return *s_mock_rados_client;
+  }
+
+private:
+  static TestRadosClientPtr s_test_rados_client;
+  static ::testing::NiceMock<librados::MockTestMemRadosClient> *s_mock_rados_client;
+};
+
+} // namespace mirror
+} // namespace rbd
+
+#endif // CEPH_TEST_RBD_MIRROR_TEST_MOCK_FIXTURE_H
diff --git a/src/test/rgw/test_rgw_period_history.cc b/src/test/rgw/test_rgw_period_history.cc
new file mode 100644
index 0000000..320f550
--- /dev/null
+++ b/src/test/rgw/test_rgw_period_history.cc
@@ -0,0 +1,330 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+/*
+ * Ceph - scalable distributed file system
+ *
+ * Copyright (C) 2015 Red Hat
+ *
+ * This is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software
+ * Foundation. See file COPYING.
+ *
+ */
+#include "rgw/rgw_period_history.h"
+#include "rgw/rgw_rados.h"
+#include "global/global_init.h"
+#include "common/ceph_argparse.h"
+#include <boost/lexical_cast.hpp>
+#include <gtest/gtest.h>
+
+namespace {
+
+// construct a period with the given fields
+RGWPeriod make_period(const std::string& id, epoch_t realm_epoch,
+                      const std::string& predecessor)
+{
+  RGWPeriod period(id);
+  period.set_realm_epoch(realm_epoch);
+  period.set_predecessor(predecessor);
+  return period;
+}
+
+const auto current_period = make_period("5", 5, "4");
+
+// mock puller that throws an exception if it's called
+struct ErrorPuller : public RGWPeriodHistory::Puller {
+  int pull(const std::string& id, RGWPeriod& period) override {
+    throw std::runtime_error("unexpected call to pull");
+  }
+};
+ErrorPuller puller; // default puller
+
+// mock puller that records the period ids requested and returns an error
+using Ids = std::vector<std::string>;
+class RecordingPuller : public RGWPeriodHistory::Puller {
+  const int error;
+ public:
+  RecordingPuller(int error) : error(error) {}
+  Ids ids;
+  int pull(const std::string& id, RGWPeriod& period) override {
+    ids.push_back(id);
+    return error;
+  }
+};
+
+// mock puller that returns a fake period by parsing the period id
+struct NumericPuller : public RGWPeriodHistory::Puller {
+  int pull(const std::string& id, RGWPeriod& period) override {
+    // relies on numeric period ids to divine the realm_epoch
+    auto realm_epoch = boost::lexical_cast<epoch_t>(id);
+    auto predecessor = boost::lexical_cast<std::string>(realm_epoch-1);
+    period = make_period(id, realm_epoch, predecessor);
+    return 0;
+  }
+};
+
+} // anonymous namespace
+
+// for ASSERT_EQ()
+bool operator==(const RGWPeriod& lhs, const RGWPeriod& rhs)
+{
+  return lhs.get_id() == rhs.get_id()
+      && lhs.get_realm_epoch() == rhs.get_realm_epoch();
+}
+
+TEST(PeriodHistory, InsertBefore)
+{
+  RGWPeriodHistory history(g_ceph_context, &puller, current_period);
+
+  // inserting right before current_period 5 will attach to history
+  auto c = history.insert(make_period("4", 4, "3"));
+  ASSERT_TRUE(c);
+  ASSERT_FALSE(c.has_prev());
+  ASSERT_TRUE(c.has_next());
+
+  // cursor can traverse forward to current_period
+  c.next();
+  ASSERT_EQ(5u, c.get_epoch());
+  ASSERT_EQ(current_period, c.get_period());
+}
+
+TEST(PeriodHistory, InsertAfter)
+{
+  RGWPeriodHistory history(g_ceph_context, &puller, current_period);
+
+  // inserting right after current_period 5 will attach to history
+  auto c = history.insert(make_period("6", 6, "5"));
+  ASSERT_TRUE(c);
+  ASSERT_TRUE(c.has_prev());
+  ASSERT_FALSE(c.has_next());
+
+  // cursor can traverse back to current_period
+  c.prev();
+  ASSERT_EQ(5u, c.get_epoch());
+  ASSERT_EQ(current_period, c.get_period());
+}
+
+TEST(PeriodHistory, InsertWayBefore)
+{
+  RGWPeriodHistory history(g_ceph_context, &puller, current_period);
+
+  // inserting way before current_period 5 will not attach to history
+  auto c = history.insert(make_period("1", 1, ""));
+  ASSERT_FALSE(c);
+  ASSERT_EQ(0, c.get_error());
+}
+
+TEST(PeriodHistory, InsertWayAfter)
+{
+  RGWPeriodHistory history(g_ceph_context, &puller, current_period);
+
+  // inserting way after current_period 5 will not attach to history
+  auto c = history.insert(make_period("9", 9, "8"));
+  ASSERT_FALSE(c);
+  ASSERT_EQ(0, c.get_error());
+}
+
+TEST(PeriodHistory, PullPredecessorsBeforeCurrent)
+{
+  RecordingPuller puller{-EFAULT};
+  RGWPeriodHistory history(g_ceph_context, &puller, current_period);
+
+  // create a disjoint history at 1 and verify that periods are requested
+  // backwards from current_period
+  auto c1 = history.attach(make_period("1", 1, ""));
+  ASSERT_FALSE(c1);
+  ASSERT_EQ(-EFAULT, c1.get_error());
+  ASSERT_EQ(Ids{"4"}, puller.ids);
+
+  auto c4 = history.insert(make_period("4", 4, "3"));
+  ASSERT_TRUE(c4);
+
+  c1 = history.attach(make_period("1", 1, ""));
+  ASSERT_FALSE(c1);
+  ASSERT_EQ(-EFAULT, c1.get_error());
+  ASSERT_EQ(Ids({"4", "3"}), puller.ids);
+
+  auto c3 = history.insert(make_period("3", 3, "2"));
+  ASSERT_TRUE(c3);
+
+  c1 = history.attach(make_period("1", 1, ""));
+  ASSERT_FALSE(c1);
+  ASSERT_EQ(-EFAULT, c1.get_error());
+  ASSERT_EQ(Ids({"4", "3", "2"}), puller.ids);
+
+  auto c2 = history.insert(make_period("2", 2, "1"));
+  ASSERT_TRUE(c2);
+
+  c1 = history.attach(make_period("1", 1, ""));
+  ASSERT_TRUE(c1);
+  ASSERT_EQ(Ids({"4", "3", "2"}), puller.ids);
+}
+
+TEST(PeriodHistory, PullPredecessorsAfterCurrent)
+{
+  RecordingPuller puller{-EFAULT};
+  RGWPeriodHistory history(g_ceph_context, &puller, current_period);
+
+  // create a disjoint history at 9 and verify that periods are requested
+  // backwards down to current_period
+  auto c9 = history.attach(make_period("9", 9, "8"));
+  ASSERT_FALSE(c9);
+  ASSERT_EQ(-EFAULT, c9.get_error());
+  ASSERT_EQ(Ids{"8"}, puller.ids);
+
+  auto c8 = history.attach(make_period("8", 8, "7"));
+  ASSERT_FALSE(c8);
+  ASSERT_EQ(-EFAULT, c8.get_error());
+  ASSERT_EQ(Ids({"8", "7"}), puller.ids);
+
+  auto c7 = history.attach(make_period("7", 7, "6"));
+  ASSERT_FALSE(c7);
+  ASSERT_EQ(-EFAULT, c7.get_error());
+  ASSERT_EQ(Ids({"8", "7", "6"}), puller.ids);
+
+  auto c6 = history.attach(make_period("6", 6, "5"));
+  ASSERT_TRUE(c6);
+  ASSERT_EQ(Ids({"8", "7", "6"}), puller.ids);
+}
+
+TEST(PeriodHistory, MergeBeforeCurrent)
+{
+  RGWPeriodHistory history(g_ceph_context, &puller, current_period);
+
+  auto c = history.get_current();
+  ASSERT_FALSE(c.has_prev());
+
+  // create a disjoint history at 3
+  auto c3 = history.insert(make_period("3", 3, "2"));
+  ASSERT_FALSE(c3);
+
+  // insert the missing period to merge 3 and 5
+  auto c4 = history.insert(make_period("4", 4, "3"));
+  ASSERT_TRUE(c4);
+  ASSERT_TRUE(c4.has_prev());
+  ASSERT_TRUE(c4.has_next());
+
+  // verify that the merge didn't destroy the original cursor's history
+  ASSERT_EQ(current_period, c.get_period());
+  ASSERT_TRUE(c.has_prev());
+}
+
+TEST(PeriodHistory, MergeAfterCurrent)
+{
+  RGWPeriodHistory history(g_ceph_context, &puller, current_period);
+
+  auto c = history.get_current();
+  ASSERT_FALSE(c.has_next());
+
+  // create a disjoint history at 7
+  auto c7 = history.insert(make_period("7", 7, "6"));
+  ASSERT_FALSE(c7);
+
+  // insert the missing period to merge 5 and 7
+  auto c6 = history.insert(make_period("6", 6, "5"));
+  ASSERT_TRUE(c6);
+  ASSERT_TRUE(c6.has_prev());
+  ASSERT_TRUE(c6.has_next());
+
+  // verify that the merge didn't destroy the original cursor's history
+  ASSERT_EQ(current_period, c.get_period());
+  ASSERT_TRUE(c.has_next());
+}
+
+TEST(PeriodHistory, MergeWithoutCurrent)
+{
+  RGWPeriodHistory history(g_ceph_context, &puller, current_period);
+
+  // create a disjoint history at 7
+  auto c7 = history.insert(make_period("7", 7, "6"));
+  ASSERT_FALSE(c7);
+
+  // create a disjoint history at 9
+  auto c9 = history.insert(make_period("9", 9, "8"));
+  ASSERT_FALSE(c9);
+
+  // insert the missing period to merge 7 and 9
+  auto c8 = history.insert(make_period("8", 8, "7"));
+  ASSERT_FALSE(c8); // not connected to current_period yet
+
+  // insert the missing period to merge 5 and 7-9
+  auto c = history.insert(make_period("6", 6, "5"));
+  ASSERT_TRUE(c);
+  ASSERT_TRUE(c.has_next());
+
+  // verify that we merged all periods from 5-9
+  c.next();
+  ASSERT_EQ(7u, c.get_epoch());
+  ASSERT_TRUE(c.has_next());
+  c.next();
+  ASSERT_EQ(8u, c.get_epoch());
+  ASSERT_TRUE(c.has_next());
+  c.next();
+  ASSERT_EQ(9u, c.get_epoch());
+  ASSERT_FALSE(c.has_next());
+}
+
+TEST(PeriodHistory, AttachBefore)
+{
+  NumericPuller puller;
+  RGWPeriodHistory history(g_ceph_context, &puller, current_period);
+
+  auto c1 = history.attach(make_period("1", 1, ""));
+  ASSERT_TRUE(c1);
+
+  // verify that we pulled and merged all periods from 1-5
+  auto c = history.get_current();
+  ASSERT_TRUE(c);
+  ASSERT_TRUE(c.has_prev());
+  c.prev();
+  ASSERT_EQ(4u, c.get_epoch());
+  ASSERT_TRUE(c.has_prev());
+  c.prev();
+  ASSERT_EQ(3u, c.get_epoch());
+  ASSERT_TRUE(c.has_prev());
+  c.prev();
+  ASSERT_EQ(2u, c.get_epoch());
+  ASSERT_TRUE(c.has_prev());
+  c.prev();
+  ASSERT_EQ(1u, c.get_epoch());
+  ASSERT_FALSE(c.has_prev());
+}
+
+TEST(PeriodHistory, AttachAfter)
+{
+  NumericPuller puller;
+  RGWPeriodHistory history(g_ceph_context, &puller, current_period);
+
+  auto c9 = history.attach(make_period("9", 9, "8"));
+  ASSERT_TRUE(c9);
+
+  // verify that we pulled and merged all periods from 5-9
+  auto c = history.get_current();
+  ASSERT_TRUE(c);
+  ASSERT_TRUE(c.has_next());
+  c.next();
+  ASSERT_EQ(6u, c.get_epoch());
+  ASSERT_TRUE(c.has_next());
+  c.next();
+  ASSERT_EQ(7u, c.get_epoch());
+  ASSERT_TRUE(c.has_next());
+  c.next();
+  ASSERT_EQ(8u, c.get_epoch());
+  ASSERT_TRUE(c.has_next());
+  c.next();
+  ASSERT_EQ(9u, c.get_epoch());
+  ASSERT_FALSE(c.has_next());
+}
+
+int main(int argc, char** argv)
+{
+  vector<const char*> args;
+  argv_to_vec(argc, (const char **)argv, args);
+
+  global_init(NULL, args, CEPH_ENTITY_TYPE_CLIENT, CODE_ENVIRONMENT_UTILITY, 0);
+  common_init_finish(g_ceph_context);
+
+  ::testing::InitGoogleTest(&argc, argv);
+  return RUN_ALL_TESTS();
+}
diff --git a/src/test/run-rbd-unit-tests.sh b/src/test/run-rbd-unit-tests.sh
index 7bd27ef..00b4d51 100755
--- a/src/test/run-rbd-unit-tests.sh
+++ b/src/test/run-rbd-unit-tests.sh
@@ -7,7 +7,7 @@ export LD_LIBRARY_PATH="$LD_LIBRARY_PATH:$CEPH_SRC/.libs"
 PATH="$CEPH_SRC:$PATH"
 
 unittest_librbd
-for i in 0 1 5 29 109
+for i in 0 1 61 109
 do
     RBD_FEATURES=$i unittest_librbd
 done
diff --git a/src/test/strtol.cc b/src/test/strtol.cc
index 93d6e68..646c055 100644
--- a/src/test/strtol.cc
+++ b/src/test/strtol.cc
@@ -215,6 +215,27 @@ TEST(SIStrToLL, Error) {
   test_strict_sistrtoll_err("1024E"); // overflows after adding the suffix
 }
 
+// since strict_sistrtoll is an alias of strict_si_cast<uint64_t>(), quite a few
+// of cases are covered by existing test cases of strict_sistrtoll already.
+TEST(StrictSICast, Error) {
+  {
+    std::string err;
+    // the SI prefix is way too large for `int`.
+    (void)strict_si_cast<int>("2E", &err);
+    ASSERT_NE(err, "");
+  }
+  {
+    std::string err;
+    (void)strict_si_cast<int>("-2E", &err);
+    ASSERT_NE(err, "");
+  }
+  {
+    std::string err;
+    (void)strict_si_cast<int>("1T", &err);
+    ASSERT_NE(err, "");
+  }
+}
+
 /*
  * Local Variables:
  * compile-command: "cd .. ; make unittest_strtol && ./unittest_strtol"
diff --git a/src/test/system/rados_watch_notify.cc b/src/test/system/rados_watch_notify.cc
index 5a081ee..e69e932 100644
--- a/src/test/system/rados_watch_notify.cc
+++ b/src/test/system/rados_watch_notify.cc
@@ -163,8 +163,7 @@ int main(int argc, const char **argv)
 
   // create a pool and an object, watch the object, notify,
   // then delete the object, notify
-  if (false) {
-    // this test is currently broken, pending the resolution of bug #2339
+  // this test is enabled for the resolution of bug #2339.
   pool += ".";
   {
     StRadosCreatePool r1(argc, argv, NULL, setup_sem, NULL, pool, 1, ".obj");
@@ -190,7 +189,6 @@ int main(int argc, const char **argv)
       return EXIT_FAILURE;
     }
   }
-  }
 
   printf("******* SUCCESS **********\n");
   return EXIT_SUCCESS;
diff --git a/src/test/test_filejournal.cc b/src/test/test_filejournal.cc
index 0d88eed..8a1172c 100644
--- a/src/test/test_filejournal.cc
+++ b/src/test/test_filejournal.cc
@@ -142,6 +142,7 @@ TEST(TestFileJournal, WriteSmall) {
     bufferlist bl;
     bl.append("small");
     int orig_len = j.prepare_entry(tls, &bl);
+    j.reserve_throttle_and_backoff(bl.length());
     j.submit_entry(1, bl, orig_len, new C_SafeCond(&wait_lock, &cond, &done));
     wait();
 
@@ -170,6 +171,7 @@ TEST(TestFileJournal, WriteBig) {
     }
     vector<ObjectStore::Transaction> tls;
     int orig_len = j.prepare_entry(tls, &bl);
+    j.reserve_throttle_and_backoff(bl.length());
     j.submit_entry(1, bl, orig_len, new C_SafeCond(&wait_lock, &cond, &done));
     wait();
     j.close();
@@ -198,6 +200,7 @@ TEST(TestFileJournal, WriteMany) {
     for (int i=0; i<100; i++) {
       bl.append("small");
       int orig_len = j.prepare_entry(tls, &bl);
+      j.reserve_throttle_and_backoff(bl.length());
       j.submit_entry(seq++, bl, orig_len, gb.new_sub());
     }
     gb.activate();
@@ -227,6 +230,7 @@ TEST(TestFileJournal, WriteManyVecs) {
     first.append("small");
     vector<ObjectStore::Transaction> tls;
     int orig_len = j.prepare_entry(tls, &first);
+    j.reserve_throttle_and_backoff(first.length());
     j.submit_entry(1, first, orig_len, gb.new_sub());
 
     bufferlist bl;
@@ -237,6 +241,7 @@ TEST(TestFileJournal, WriteManyVecs) {
     }
     bufferlist origbl = bl;
     orig_len = j.prepare_entry(tls, &bl);
+    j.reserve_throttle_and_backoff(bl.length());
     j.submit_entry(2, bl, orig_len, gb.new_sub());
     gb.activate();
     wait();
@@ -276,12 +281,15 @@ TEST(TestFileJournal, ReplaySmall) {
     bufferlist bl;
     bl.append("small");
     int orig_len = j.prepare_entry(tls, &bl);
+    j.reserve_throttle_and_backoff(bl.length());
     j.submit_entry(1, bl, orig_len, gb.new_sub());
     bl.append("small");
     orig_len = j.prepare_entry(tls, &bl);
+    j.reserve_throttle_and_backoff(bl.length());
     j.submit_entry(2, bl, orig_len, gb.new_sub());
     bl.append("small");
     orig_len = j.prepare_entry(tls, &bl);
+    j.reserve_throttle_and_backoff(bl.length());
     j.submit_entry(3, bl, orig_len, gb.new_sub());
     gb.activate();
     wait();
@@ -335,15 +343,19 @@ TEST(TestFileJournal, ReplayCorrupt) {
     bufferlist bl;
     bl.append(needle);
     int orig_len = j.prepare_entry(tls, &bl);
+    j.reserve_throttle_and_backoff(bl.length());
     j.submit_entry(1, bl, orig_len, gb.new_sub());
     bl.append(needle);
     orig_len = j.prepare_entry(tls, &bl);
+    j.reserve_throttle_and_backoff(bl.length());
     j.submit_entry(2, bl, orig_len, gb.new_sub());
     bl.append(needle);
     orig_len = j.prepare_entry(tls, &bl);
+    j.reserve_throttle_and_backoff(bl.length());
     j.submit_entry(3, bl, orig_len, gb.new_sub());
     bl.append(needle);
     orig_len = j.prepare_entry(tls, &bl);
+    j.reserve_throttle_and_backoff(bl.length());
     j.submit_entry(4, bl, orig_len, gb.new_sub());
     gb.activate();
     wait();
@@ -424,6 +436,7 @@ TEST(TestFileJournal, WriteTrim) {
       bl.zero();
       ls.push_back(new C_Sync);
       int orig_len = j.prepare_entry(tls, &bl);
+      j.reserve_throttle_and_backoff(bl.length());
       j.submit_entry(seq++, bl, orig_len, ls.back()->c);
 
       while (ls.size() > size_mb/2) {
@@ -475,6 +488,7 @@ TEST(TestFileJournal, WriteTrimSmall) {
       bl.zero();
       ls.push_back(new C_Sync);
       int orig_len = j.prepare_entry(tls, &bl);
+      j.reserve_throttle_and_backoff(bl.length());
       j.submit_entry(seq++, bl, orig_len, ls.back()->c);
 
       while (ls.size() > size_mb/2) {
@@ -516,6 +530,7 @@ TEST(TestFileJournal, ReplayDetectCorruptFooterMagic) {
       bufferlist bl;
       bl.append(needle);
       int orig_len = j.prepare_entry(tls, &bl);
+      j.reserve_throttle_and_backoff(bl.length());
       j.submit_entry(i, bl, orig_len, gb.new_sub());
     }
     gb.activate();
@@ -524,6 +539,7 @@ TEST(TestFileJournal, ReplayDetectCorruptFooterMagic) {
     bufferlist bl;
     bl.append("needle");
     int orig_len = j.prepare_entry(tls, &bl);
+    j.reserve_throttle_and_backoff(bl.length());
     j.submit_entry(5, bl, orig_len, new C_SafeCond(&wait_lock, &cond, &done));
     wait();
 
@@ -573,6 +589,7 @@ TEST(TestFileJournal, ReplayDetectCorruptPayload) {
       bufferlist bl;
       bl.append(needle);
       int orig_len = j.prepare_entry(tls, &bl);
+      j.reserve_throttle_and_backoff(bl.length());
       j.submit_entry(i, bl, orig_len, gb.new_sub());
     }
     gb.activate();
@@ -581,6 +598,7 @@ TEST(TestFileJournal, ReplayDetectCorruptPayload) {
     bufferlist bl;
     bl.append("needle");
     int orig_len = j.prepare_entry(tls, &bl);
+    j.reserve_throttle_and_backoff(bl.length());
     j.submit_entry(5, bl, orig_len, new C_SafeCond(&wait_lock, &cond, &done));
     wait();
 
@@ -630,6 +648,7 @@ TEST(TestFileJournal, ReplayDetectCorruptHeader) {
       bufferlist bl;
       bl.append(needle);
       int orig_len = j.prepare_entry(tls, &bl);
+      j.reserve_throttle_and_backoff(bl.length());
       j.submit_entry(i, bl, orig_len, gb.new_sub());
     }
     gb.activate();
@@ -638,6 +657,7 @@ TEST(TestFileJournal, ReplayDetectCorruptHeader) {
     bufferlist bl;
     bl.append("needle");
     int orig_len = j.prepare_entry(tls, &bl);
+    j.reserve_throttle_and_backoff(bl.length());
     j.submit_entry(5, bl, orig_len, new C_SafeCond(&wait_lock, &cond, &done));
     wait();
 
diff --git a/src/test/test_pageset.cc b/src/test/test_pageset.cc
index bfc7ab7..a699e72 100644
--- a/src/test/test_pageset.cc
+++ b/src/test/test_pageset.cc
@@ -4,6 +4,12 @@
 
 #include "os/memstore/PageSet.h"
 
+template <typename T>
+bool is_aligned(T* ptr) {
+  const auto align_mask = alignof(T) - 1;
+  return (reinterpret_cast<uintptr_t>(ptr) & align_mask) == 0;
+}
+
 TEST(PageSet, AllocAligned)
 {
   PageSet pages(1);
@@ -15,6 +21,12 @@ TEST(PageSet, AllocAligned)
   ASSERT_EQ(1u, range[1]->offset);
   ASSERT_EQ(2u, range[2]->offset);
   ASSERT_EQ(3u, range[3]->offset);
+
+  // verify that the Page pointers are properly aligned
+  ASSERT_TRUE(is_aligned(range[0].get()));
+  ASSERT_TRUE(is_aligned(range[1].get()));
+  ASSERT_TRUE(is_aligned(range[2].get()));
+  ASSERT_TRUE(is_aligned(range[3].get()));
 }
 
 TEST(PageSet, AllocUnaligned)
diff --git a/src/test/test_pidfile.sh b/src/test/test_pidfile.sh
index 2dec1f7..19a3b13 100755
--- a/src/test/test_pidfile.sh
+++ b/src/test/test_pidfile.sh
@@ -25,40 +25,21 @@ function run() {
 function TEST_without_pidfile() {
     local dir=$1
     setup $dir
-    local RUNID=`uuidgen`
-    run_mon $dir a --pid-file= --daemonize=$RUNID || { teardown_unexist_pidfile $dir $RUNID; return 1; }
-    run_osd $dir 0 --pid-file= --daemonize=$RUNID || { teardown_unexist_pidfile $dir $RUNID; return 1; }
-    teardown_unexist_pidfile $dir $RUNID || return 1
-}
-
-function teardown_unexist_pidfile() {
-    local dir=$1
-    shift
-    local RUNID=$1
-    shift
-    local delays=${4:-0 0 1 1 1 2 3 5 5 5 10 10 20 60 60 60 120}
-    local pids=$(ps aux|awk "/cep[h].*$RUNID.*/ {print \$2}")
-    local status=0
-    for i in $pids ; do
-        local kill_complete=false
-        for try in $delays ; do  
-            if kill $i 2> /dev/null ; then
-                kill_complete=false
-                sleep $try
-            else
-                kill_complete=true
-                break
-            fi
-       done
-       if ! $kill_complete ; then
-            status=1
-       fi   
-    done
-    if [ $(stat -f -c '%T' .) == "btrfs" ]; then
-         __teardown_btrfs $dir
-    fi
-    rm -fr $dir
-    return $status
+    local data=$dir/osd1
+    local id=1
+    ceph-mon \
+        --id $id \
+        --mkfs \
+        --mon-data=$data \
+        --run-dir=$dir || return 1
+    expect_failure $dir "ignore empty --pid-file" ceph-mon \
+        -f \
+        --log-to-stderr \
+        --pid-file= \
+        --id $id \
+        --mon-data=$data \
+        --run-dir=$dir || return 1
+    teardown $dir
 }
 
 function TEST_pidfile() {
@@ -87,6 +68,7 @@ function TEST_pidfile() {
     # if the pid in the file is different from the pid of the daemon
     # the file is not removed because it is assumed to be owned by
     # another daemon
+    cp $dir/osd.0.pid $dir/osd.0.pid.old  # so that kill_daemon finds the pid
     echo 123 > $dir/osd.0.pid
     kill_daemons $dir TERM osd.0 || return 1
     test -f $dir/osd.0.pid || return 1
@@ -99,4 +81,5 @@ function TEST_pidfile() {
     teardown $dir || return 1
 }
 
-main pidfile
+main pidfile "$@"
+
diff --git a/src/test/test_pool_create.sh b/src/test/test_pool_create.sh
new file mode 100755
index 0000000..657b6dd
--- /dev/null
+++ b/src/test/test_pool_create.sh
@@ -0,0 +1,58 @@
+#!/bin/bash
+
+
+#Generic create pool use crush rule  test
+#
+
+# Includes
+source ../qa/workunits/ceph-helpers.sh
+
+function run() {
+    local dir=$1
+    shift
+
+    export CEPH_MON="127.0.0.1:17108"
+    export CEPH_ARGS
+    CEPH_ARGS+="--fsid=$(uuidgen) --auth-supported=none "
+    CEPH_ARGS+="--mon-host=$CEPH_MON "
+
+    local funcs=${@:-$(set | sed -n -e 's/^\(TEST_[0-9a-z_]*\) .*/\1/p')}
+    for func in $funcs ; do
+        $func $dir || return 1
+    done
+}
+
+function TEST_pool_create() {
+    local dir=$1
+    setup $dir || return 1
+    run_mon $dir a || return 1
+    run_osd $dir 0 || return 1
+    run_osd $dir 1 || return 1
+    run_osd $dir 2 || return 1
+
+    local rulename=testrule
+    local poolname=rulepool
+    local var=`ceph osd crush rule dump|grep -w ruleset|sed -n '$p'|grep -o '[0-9]\+'`
+    var=`expr  $var + 1 `
+    ceph osd getcrushmap -o "$dir/map1"
+    crushtool -d "$dir/map1" -o "$dir/map1.txt"
+
+    local minsize=0
+    local maxsize=1
+    sed -i '/# end crush map/i\rule '$rulename' {\n ruleset \'$var'\n type replicated\n min_size \'$minsize'\n max_size \'$maxsize'\n step take default\n step choose firstn 0 type osd\n step emit\n }\n' "$dir/map1.txt"
+    crushtool  -c "$dir/map1.txt" -o "$dir/map1.bin"
+    ceph osd setcrushmap -i "$dir/map1.bin"
+    ceph osd pool create $poolname 200 $rulename 2>"$dir/rev"
+    local result=$(cat "$dir/rev" | grep "Error EINVAL: pool size")
+
+    if [ "$result" = "" ];
+    then
+      ceph osd pool delete  $poolname $poolname  --yes-i-really-really-mean-it
+      ceph osd crush rule rm $rulename
+      return 1
+    fi
+    ceph osd crush rule rm $rulename
+}
+
+main testpoolcreate
+
diff --git a/src/test/test_rgw_admin_log.cc b/src/test/test_rgw_admin_log.cc
index f460251..4f5affe 100644
--- a/src/test/test_rgw_admin_log.cc
+++ b/src/test/test_rgw_admin_log.cc
@@ -558,12 +558,6 @@ int parse_json_resp(JSONParser &parser) {
   return 0;
 }
 
-struct RGWMetadataLogData {
-  obj_version read_version;
-  obj_version write_version;
-  string status;
-};
-
 struct cls_log_entry_json {
   string section;
   string name;
@@ -583,7 +577,7 @@ static int decode_json(JSONObj *obj, RGWMetadataLogData &data) {
   jo = obj->find_obj("status");
   if (!jo)
     return -1;
-  JSONDecoder::decode_json("status", data.status, jo);
+  JSONDecoder::decode_json("status", data, jo);
   return 0;
 }
 
@@ -1078,19 +1072,19 @@ TEST(TestRGWAdmin, mdlog_list) {
     list<cls_log_entry_json>::iterator it = entries.begin();
     EXPECT_TRUE(it->section.compare("user") == 0);
     EXPECT_TRUE(it->name.compare(uid) == 0);
-    EXPECT_TRUE(it->log_data.status.compare("write") == 0);
+    EXPECT_TRUE(it->log_data.status == MDLOG_STATUS_WRITE);
     ++it;
     EXPECT_TRUE(it->section.compare("user") == 0);
     EXPECT_TRUE(it->name.compare(uid) == 0);
-    EXPECT_TRUE(it->log_data.status.compare("complete") == 0);
+    EXPECT_TRUE(it->log_data.status == MDLOG_STATUS_COMPLETE);
     ++it;
     EXPECT_TRUE(it->section.compare("user") == 0);
     EXPECT_TRUE(it->name.compare(uid) == 0);
-    EXPECT_TRUE(it->log_data.status.compare("write") == 0);
+    EXPECT_TRUE(it->log_data.status == MDLOG_STATUS_WRITE);
     ++it;
     EXPECT_TRUE(it->section.compare("user") == 0);
     EXPECT_TRUE(it->name.compare(uid) == 0);
-    EXPECT_TRUE(it->log_data.status.compare("complete") == 0);
+    EXPECT_TRUE(it->log_data.status == MDLOG_STATUS_COMPLETE);
   }
 
   sleep(1); /*To get a modified time*/
@@ -1112,19 +1106,19 @@ TEST(TestRGWAdmin, mdlog_list) {
     list<cls_log_entry_json>::iterator it = entries.begin();
     EXPECT_TRUE(it->section.compare("user") == 0);
     EXPECT_TRUE(it->name.compare(uid) == 0);
-    EXPECT_TRUE(it->log_data.status.compare("write") == 0);
+    EXPECT_TRUE(it->log_data.status == MDLOG_STATUS_WRITE);
     ++it;
     EXPECT_TRUE(it->section.compare("user") == 0);
     EXPECT_TRUE(it->name.compare(uid) == 0);
-    EXPECT_TRUE(it->log_data.status.compare("complete") == 0);
+    EXPECT_TRUE(it->log_data.status == MDLOG_STATUS_COMPLETE);
     ++it;
     EXPECT_TRUE(it->section.compare("user") == 0);
     EXPECT_TRUE(it->name.compare(uid) == 0);
-    EXPECT_TRUE(it->log_data.status.compare("write") == 0);
+    EXPECT_TRUE(it->log_data.status == MDLOG_STATUS_WRITE);
     ++it;
     EXPECT_TRUE(it->section.compare("user") == 0);
     EXPECT_TRUE(it->name.compare(uid) == 0);
-    EXPECT_TRUE(it->log_data.status.compare("complete") == 0);
+    EXPECT_TRUE(it->log_data.status == MDLOG_STATUS_COMPLETE);
   }
 
   sleep(1);
@@ -1148,18 +1142,18 @@ TEST(TestRGWAdmin, mdlog_list) {
     list<cls_log_entry_json>::iterator it = entries.begin();
     EXPECT_TRUE(it->section.compare("user") == 0);
     EXPECT_TRUE(it->name.compare(uid) == 0);
-    EXPECT_TRUE(it->log_data.status.compare("remove") == 0);
+    EXPECT_TRUE(it->log_data.status == MDLOG_STATUS_REMOVE);
     ++it;
     EXPECT_TRUE(it->section.compare("user") == 0);
     EXPECT_TRUE(it->name.compare(uid) == 0);
     ++it;
     EXPECT_TRUE(it->section.compare("user") == 0);
     EXPECT_TRUE(it->name.compare(uid) == 0);
-    EXPECT_TRUE(it->log_data.status.compare("write") == 0);
+    EXPECT_TRUE(it->log_data.status == MDLOG_STATUS_WRITE);
     ++it;
     EXPECT_TRUE(it->section.compare("user") == 0);
     EXPECT_TRUE(it->name.compare(uid) == 0);
-    EXPECT_TRUE(it->log_data.status.compare("complete") == 0);
+    EXPECT_TRUE(it->log_data.status == MDLOG_STATUS_COMPLETE);
   }
 
   sleep(1);
diff --git a/src/test/test_rgw_admin_opstate.cc b/src/test/test_rgw_admin_opstate.cc
index 2656857..3499aa4 100644
--- a/src/test/test_rgw_admin_opstate.cc
+++ b/src/test/test_rgw_admin_opstate.cc
@@ -807,7 +807,7 @@ int main(int argc, char *argv[]){
 
   global_init(NULL, args, CEPH_ENTITY_TYPE_CLIENT, CODE_ENVIRONMENT_UTILITY, 0);
   common_init_finish(g_ceph_context);
-  store = RGWStoreManager::get_storage(g_ceph_context, false, false);
+  store = RGWStoreManager::get_storage(g_ceph_context, false, false, false);
   g_test = new admin_log::test_helper();
   finisher = new Finisher(g_ceph_context);
 #ifdef GTEST
diff --git a/src/test/test_striper.cc b/src/test/test_striper.cc
index 4676101..2e0c23f 100644
--- a/src/test/test_striper.cc
+++ b/src/test/test_striper.cc
@@ -8,12 +8,11 @@
 
 TEST(Striper, Stripe1)
 {
-  ceph_file_layout l;
-  memset(&l, 0, sizeof(l));
+  file_layout_t l;
 
-  l.fl_object_size = 262144;
-  l.fl_stripe_unit = 4096;
-  l.fl_stripe_count = 3;
+  l.object_size = 262144;
+  l.stripe_unit = 4096;
+  l.stripe_count = 3;
 
   vector<ObjectExtent> ex;
   Striper::file_to_extents(g_ceph_context, 1, &l, 5006035, 46419, 5006035, ex);
@@ -28,12 +27,11 @@ TEST(Striper, Stripe1)
 
 TEST(Striper, EmptyPartialResult)
 {
-  ceph_file_layout l;
-  memset(&l, 0, sizeof(l));
+  file_layout_t l;
 
-  l.fl_object_size = 4194304;
-  l.fl_stripe_unit = 4194304;
-  l.fl_stripe_count = 1;
+  l.object_size = 4194304;
+  l.stripe_unit = 4194304;
+  l.stripe_count = 1;
 
   vector<ObjectExtent> ex;
   Striper::file_to_extents(g_ceph_context, 1, &l, 725549056, 131072, 72554905600, ex);
@@ -59,12 +57,11 @@ TEST(Striper, EmptyPartialResult)
 
 TEST(Striper, GetNumObj)
 {
-  ceph_file_layout l;
-  memset(&l, 0, sizeof(l));
+  file_layout_t l;
 
-  l.fl_object_size = 262144;
-  l.fl_stripe_unit = 4096;
-  l.fl_stripe_count = 3;
+  l.object_size = 262144;
+  l.stripe_unit = 4096;
+  l.stripe_count = 3;
   uint64_t size,numobjs;
   size = 6999;
   numobjs = Striper::get_num_objects(l, size);
diff --git a/src/test/test_subprocess.cc b/src/test/test_subprocess.cc
index a38669e..29c7b94 100644
--- a/src/test/test_subprocess.cc
+++ b/src/test/test_subprocess.cc
@@ -38,7 +38,7 @@ TEST(SubProcess, True)
   SubProcess p("true");
   ASSERT_EQ(p.spawn(), 0);
   ASSERT_EQ(p.join(), 0);
-  ASSERT_TRUE(p.err()[0] == '\0');
+  ASSERT_TRUE(p.err().c_str()[0] == '\0');
 }
 
 TEST(SubProcess, False)
@@ -46,7 +46,7 @@ TEST(SubProcess, False)
   SubProcess p("false");
   ASSERT_EQ(p.spawn(), 0);
   ASSERT_EQ(p.join(), 1);
-  ASSERT_FALSE(p.err()[0] == '\0');
+  ASSERT_FALSE(p.err().c_str()[0] == '\0');
 }
 
 TEST(SubProcess, NotFound)
@@ -58,7 +58,7 @@ TEST(SubProcess, NotFound)
   std::cerr << "stderr: " << buf;
   ASSERT_EQ(p.join(), 1);
   std::cerr << "err: " << p.err() << std::endl;
-  ASSERT_FALSE(p.err()[0] == '\0');
+  ASSERT_FALSE(p.err().c_str()[0] == '\0');
 }
 
 TEST(SubProcess, Echo)
@@ -72,7 +72,7 @@ TEST(SubProcess, Echo)
   std::cerr << "stdout: " << buf;
   ASSERT_EQ(buf, "1 2 3\n");
   ASSERT_EQ(echo.join(), 0);
-  ASSERT_TRUE(echo.err()[0] == '\0');
+  ASSERT_TRUE(echo.err().c_str()[0] == '\0');
 }
 
 TEST(SubProcess, Cat)
@@ -91,7 +91,7 @@ TEST(SubProcess, Cat)
   ASSERT_TRUE(read_from_fd(cat.get_stderr(), buf));
   ASSERT_EQ(buf, "");
   ASSERT_EQ(cat.join(), 0);
-  ASSERT_TRUE(cat.err()[0] == '\0');
+  ASSERT_TRUE(cat.err().c_str()[0] == '\0');
 }
 
 TEST(SubProcess, CatDevNull)
@@ -106,7 +106,7 @@ TEST(SubProcess, CatDevNull)
   ASSERT_TRUE(read_from_fd(cat.get_stderr(), buf));
   ASSERT_EQ(buf, "");
   ASSERT_EQ(cat.join(), 0);
-  ASSERT_TRUE(cat.err()[0] == '\0');
+  ASSERT_TRUE(cat.err().c_str()[0] == '\0');
 }
 
 TEST(SubProcess, Killed)
@@ -117,7 +117,7 @@ TEST(SubProcess, Killed)
   cat.kill();
   ASSERT_EQ(cat.join(), 128 + SIGTERM);
   std::cerr << "err: " << cat.err() << std::endl;
-  ASSERT_FALSE(cat.err()[0] == '\0');
+  ASSERT_FALSE(cat.err().c_str()[0] == '\0');
 }
 
 TEST(SubProcess, CatWithArgs)
@@ -139,7 +139,7 @@ TEST(SubProcess, CatWithArgs)
   ASSERT_FALSE(buf.empty());
   ASSERT_EQ(cat.join(), 1);
   std::cerr << "err: " << cat.err() << std::endl;
-  ASSERT_FALSE(cat.err()[0] == '\0');
+  ASSERT_FALSE(cat.err().c_str()[0] == '\0');
 }
 
 TEST(SubProcess, Subshell)
@@ -164,7 +164,7 @@ TEST(SubProcess, Subshell)
   ASSERT_EQ(buf, "error from subshell\n");
   ASSERT_EQ(sh.join(), 13);
   std::cerr << "err: " << sh.err() << std::endl;
-  ASSERT_FALSE(sh.err()[0] == '\0');
+  ASSERT_FALSE(sh.err().c_str()[0] == '\0');
 }
 
 TEST(SubProcessTimed, True)
@@ -172,7 +172,7 @@ TEST(SubProcessTimed, True)
   SubProcessTimed p("true", SubProcess::CLOSE, SubProcess::CLOSE, SubProcess::CLOSE, 10);
   ASSERT_EQ(p.spawn(), 0);
   ASSERT_EQ(p.join(), 0);
-  ASSERT_TRUE(p.err()[0] == '\0');
+  ASSERT_TRUE(p.err().c_str()[0] == '\0');
 }
 
 TEST(SubProcessTimed, SleepNoTimeout)
@@ -182,7 +182,7 @@ TEST(SubProcessTimed, SleepNoTimeout)
 
   ASSERT_EQ(sleep.spawn(), 0);
   ASSERT_EQ(sleep.join(), 0);
-  ASSERT_TRUE(sleep.err()[0] == '\0');
+  ASSERT_TRUE(sleep.err().c_str()[0] == '\0');
 }
 
 TEST(SubProcessTimed, Killed)
@@ -198,7 +198,7 @@ TEST(SubProcessTimed, Killed)
   ASSERT_TRUE(buf.empty());
   ASSERT_EQ(cat.join(), 128 + SIGTERM);
   std::cerr << "err: " << cat.err() << std::endl;
-  ASSERT_FALSE(cat.err()[0] == '\0');
+  ASSERT_FALSE(cat.err().c_str()[0] == '\0');
 }
 
 TEST(SubProcessTimed, SleepTimedout)
@@ -213,7 +213,7 @@ TEST(SubProcessTimed, SleepTimedout)
   ASSERT_FALSE(buf.empty());
   ASSERT_EQ(sleep.join(), 128 + SIGKILL);
   std::cerr << "err: " << sleep.err() << std::endl;
-  ASSERT_FALSE(sleep.err()[0] == '\0');
+  ASSERT_FALSE(sleep.err().c_str()[0] == '\0');
 }
 
 TEST(SubProcessTimed, SubshellNoTimeout)
@@ -233,7 +233,7 @@ TEST(SubProcessTimed, SubshellNoTimeout)
   std::cerr << "stderr: " << buf << std::endl;
   ASSERT_EQ(buf, msg);
   ASSERT_EQ(sh.join(), 0);
-  ASSERT_TRUE(sh.err()[0] == '\0');
+  ASSERT_TRUE(sh.err().c_str()[0] == '\0');
 }
 
 TEST(SubProcessTimed, SubshellKilled)
@@ -250,7 +250,7 @@ TEST(SubProcessTimed, SubshellKilled)
   ASSERT_TRUE(buf.empty());
   ASSERT_EQ(sh.join(), 128 + SIGTERM);
   std::cerr << "err: " << sh.err() << std::endl;
-  ASSERT_FALSE(sh.err()[0] == '\0');
+  ASSERT_FALSE(sh.err().c_str()[0] == '\0');
 }
 
 TEST(SubProcessTimed, SubshellTimedout)
@@ -264,5 +264,5 @@ TEST(SubProcessTimed, SubshellTimedout)
   ASSERT_FALSE(buf.empty());
   ASSERT_EQ(sh.join(), 128 + SIGTERM);
   std::cerr << "err: " << sh.err() << std::endl;
-  ASSERT_FALSE(sh.err()[0] == '\0');
+  ASSERT_FALSE(sh.err().c_str()[0] == '\0');
 }
diff --git a/src/tools/Makefile-client.am b/src/tools/Makefile-client.am
index 0a31d5c..509cba3 100644
--- a/src/tools/Makefile-client.am
+++ b/src/tools/Makefile-client.am
@@ -46,12 +46,11 @@ rbd_SOURCES = \
 	tools/rbd/action/ImportDiff.cc \
 	tools/rbd/action/Info.cc \
 	tools/rbd/action/Journal.cc \
-	tools/rbd/action/Kernel.cc \
-	tools/rbd/action/Nbd.cc \
 	tools/rbd/action/List.cc \
 	tools/rbd/action/Lock.cc \
 	tools/rbd/action/MergeDiff.cc \
 	tools/rbd/action/MirrorPool.cc \
+	tools/rbd/action/MirrorImage.cc \
 	tools/rbd/action/ObjectMap.cc \
 	tools/rbd/action/Remove.cc \
 	tools/rbd/action/Rename.cc \
@@ -59,6 +58,11 @@ rbd_SOURCES = \
 	tools/rbd/action/Snap.cc \
 	tools/rbd/action/Status.cc \
 	tools/rbd/action/Watch.cc
+if LINUX
+rbd_SOURCES += \
+	tools/rbd/action/Kernel.cc \
+	tools/rbd/action/Nbd.cc
+endif # LINUX
 noinst_HEADERS += \
 	tools/rbd/ArgumentTypes.h \
 	tools/rbd/IndentStream.h \
@@ -67,11 +71,14 @@ noinst_HEADERS += \
 	tools/rbd/Utils.h
 rbd_LDADD = \
 	libjournal.la libcls_journal_client.la \
-	$(LIBKRBD) $(LIBRBD) $(LIBRBD_TYPES) $(LIBRADOS) $(CEPH_GLOBAL) \
+	$(LIBRBD) $(LIBRBD_TYPES) $(LIBRADOS) $(CEPH_GLOBAL) \
 	$(BOOST_REGEX_LIBS) $(BOOST_PROGRAM_OPTIONS_LIBS)
 if LINUX
+rbd_LDADD += $(LIBKRBD)
+endif # LINUX
 bin_PROGRAMS += rbd
 
+if LINUX
 rbd_nbd_SOURCES = tools/rbd_nbd/rbd-nbd.cc
 rbd_nbd_CXXFLAGS = $(AM_CXXFLAGS)
 rbd_nbd_LDADD = $(LIBRBD) $(LIBRADOS) $(CEPH_GLOBAL) $(BOOST_REGEX_LIBS)
@@ -83,18 +90,38 @@ endif # LINUX
 librbd_mirror_internal_la_SOURCES = \
 	tools/rbd_mirror/ClusterWatcher.cc \
 	tools/rbd_mirror/ImageReplayer.cc \
+	tools/rbd_mirror/ImageSync.cc \
 	tools/rbd_mirror/Mirror.cc \
 	tools/rbd_mirror/PoolWatcher.cc \
 	tools/rbd_mirror/Replayer.cc \
-	tools/rbd_mirror/types.cc
+	tools/rbd_mirror/Threads.cc \
+	tools/rbd_mirror/types.cc \
+	tools/rbd_mirror/image_replayer/BootstrapRequest.cc \
+	tools/rbd_mirror/image_replayer/CloseImageRequest.cc \
+	tools/rbd_mirror/image_replayer/OpenLocalImageRequest.cc \
+	tools/rbd_mirror/image_sync/ImageCopyRequest.cc \
+	tools/rbd_mirror/image_sync/ObjectCopyRequest.cc \
+	tools/rbd_mirror/image_sync/SnapshotCopyRequest.cc \
+	tools/rbd_mirror/image_sync/SyncPointCreateRequest.cc \
+	tools/rbd_mirror/image_sync/SyncPointPruneRequest.cc
 noinst_LTLIBRARIES += librbd_mirror_internal.la
 noinst_HEADERS += \
 	tools/rbd_mirror/ClusterWatcher.h \
 	tools/rbd_mirror/ImageReplayer.h \
+	tools/rbd_mirror/ImageSync.h \
 	tools/rbd_mirror/Mirror.h \
 	tools/rbd_mirror/PoolWatcher.h \
 	tools/rbd_mirror/Replayer.h \
-	tools/rbd_mirror/types.h
+	tools/rbd_mirror/Threads.h \
+	tools/rbd_mirror/types.h \
+	tools/rbd_mirror/image_replayer/BootstrapRequest.h \
+	tools/rbd_mirror/image_replayer/CloseImageRequest.h \
+	tools/rbd_mirror/image_replayer/OpenLocalImageRequest.h \
+	tools/rbd_mirror/image_sync/ImageCopyRequest.h \
+	tools/rbd_mirror/image_sync/ObjectCopyRequest.h \
+	tools/rbd_mirror/image_sync/SnapshotCopyRequest.h \
+	tools/rbd_mirror/image_sync/SyncPointCreateRequest.h \
+	tools/rbd_mirror/image_sync/SyncPointPruneRequest.h
 
 rbd_mirror_SOURCES = \
 	tools/rbd_mirror/main.cc
diff --git a/src/tools/Makefile-server.am b/src/tools/Makefile-server.am
index 599c5db..cbdb715 100644
--- a/src/tools/Makefile-server.am
+++ b/src/tools/Makefile-server.am
@@ -35,6 +35,7 @@ if WITH_RADOS
 cephfs_journal_tool_SOURCES = \
 	tools/cephfs/cephfs-journal-tool.cc \
 	tools/cephfs/JournalTool.cc \
+	tools/cephfs/RoleSelector.cc \
 	tools/cephfs/JournalFilter.cc \
 	tools/cephfs/JournalScanner.cc \
 	tools/cephfs/EventOutput.cc \
@@ -47,6 +48,7 @@ bin_PROGRAMS += cephfs-journal-tool
 cephfs_table_tool_SOURCES = \
 	tools/cephfs/cephfs-table-tool.cc \
 	tools/cephfs/TableTool.cc \
+	tools/cephfs/RoleSelector.cc \
 	tools/cephfs/MDSUtility.cc
 cephfs_table_tool_LDADD = $(LIBMDS) $(LIBRADOS) $(CEPH_GLOBAL)
 bin_PROGRAMS += cephfs-table-tool
@@ -54,6 +56,7 @@ bin_PROGRAMS += cephfs-table-tool
 cephfs_data_scan_SOURCES = \
 	tools/cephfs/cephfs-data-scan.cc \
 	tools/cephfs/DataScan.cc \
+	tools/cephfs/RoleSelector.cc \
 	tools/cephfs/MDSUtility.cc
 cephfs_data_scan_LDADD = $(LIBMDS) libcls_cephfs_client.la $(LIBRADOS) $(CEPH_GLOBAL)
 bin_PROGRAMS += cephfs-data-scan
diff --git a/src/tools/Makefile.am b/src/tools/Makefile.am
index 0976bee..e730850 100644
--- a/src/tools/Makefile.am
+++ b/src/tools/Makefile.am
@@ -43,7 +43,8 @@ noinst_HEADERS += \
 	tools/rados/RadosImport.h \
 	tools/ceph_objectstore_tool.h \
 	tools/rados/PoolDump.h \
-	tools/cephfs/DataScan.h
+	tools/cephfs/DataScan.h \
+	tools/cephfs/RoleSelector.h
 
 EXTRA_DIST += \
 	tools/setup-virtualenv.sh
diff --git a/src/tools/ceph_conf.cc b/src/tools/ceph_conf.cc
index 0d0b85c..f047e7c 100644
--- a/src/tools/ceph_conf.cc
+++ b/src/tools/ceph_conf.cc
@@ -153,6 +153,8 @@ int main(int argc, const char **argv)
 
   global_pre_init(NULL, args, CEPH_ENTITY_TYPE_CLIENT, CODE_ENVIRONMENT_DAEMON,
 		  CINIT_FLAG_NO_DAEMON_ACTIONS);
+  g_conf->apply_changes(NULL);
+  g_conf->complain_about_parse_errors(g_ceph_context);
 
   // do not common_init_finish(); do not start threads; do not do any of thing
   // wonky things the daemon whose conf we are examining would do (like initialize
diff --git a/src/tools/ceph_objectstore_tool.cc b/src/tools/ceph_objectstore_tool.cc
index 9a44cfc..74348bc 100644
--- a/src/tools/ceph_objectstore_tool.cc
+++ b/src/tools/ceph_objectstore_tool.cc
@@ -2514,7 +2514,7 @@ int main(int argc, char **argv)
   bufferlist bl;
   OSDSuperblock superblock;
   bufferlist::iterator p;
-  ret = fs->read(coll_t::meta(), OSD_SUPERBLOCK_POBJECT, 0, 0, bl);
+  ret = fs->read(coll_t::meta(), OSD_SUPERBLOCK_GOBJECT, 0, 0, bl);
   if (ret < 0) {
     cerr << "Failure to read OSD superblock: " << cpp_strerror(ret) << std::endl;
     goto out;
diff --git a/src/tools/cephfs/DataScan.cc b/src/tools/cephfs/DataScan.cc
index ce6a4e0..d2d22be 100644
--- a/src/tools/cephfs/DataScan.cc
+++ b/src/tools/cephfs/DataScan.cc
@@ -36,9 +36,11 @@ void DataScan::usage()
     << "\n"
     << "    --force-corrupt: overrite apparently corrupt structures\n"
     << "    --force-init: write root inodes even if they exist\n"
-    << "    --force-pool: use data pool even if it is not in MDSMap\n"
+    << "    --force-pool: use data pool even if it is not in FSMap\n"
     << "\n"
     << "  cephfs-data-scan scan_frags [--force-corrupt]\n"
+    << "\n"
+    << "  cephfs-data-scan tmap_upgrade <metadata_pool>\n"
     << std::endl;
 
   generic_client_usage();
@@ -65,7 +67,7 @@ bool DataScan::parse_kwarg(
     dout(4) << "Using local file output to '" << val << "'" << dendl;
     driver = new LocalFileDriver(val, data_io);
     return true;
-  } else if (arg == std::string("-n")) {
+  } else if (arg == std::string("--worker_n")) {
     std::string err;
     n = strict_strtoll(val.c_str(), 10, &err);
     if (!err.empty()) {
@@ -74,7 +76,7 @@ bool DataScan::parse_kwarg(
       return false;
     }
     return true;
-  } else if (arg == std::string("-m")) {
+  } else if (arg == std::string("--worker_m")) {
     std::string err;
     m = strict_strtoll(val.c_str(), 10, &err);
     if (!err.empty()) {
@@ -87,6 +89,15 @@ bool DataScan::parse_kwarg(
     filter_tag = val;
     dout(10) << "Applying tag filter: '" << filter_tag << "'" << dendl;
     return true;
+  } else if (arg == std::string("--filesystem")) {
+    std::shared_ptr<const Filesystem> fs;
+    *r = fsmap->parse_filesystem(val, &fs);
+    if (*r != 0) {
+      std::cerr << "Invalid filesystem '" << val << "'" << std::endl;
+      return false;
+    }
+    fscid = fs->fscid;
+    return true;
   } else {
     return false;
   }
@@ -131,6 +142,7 @@ int DataScan::main(const std::vector<const char*> &args)
 
   std::string const &command = args[0];
   std::string data_pool_name;
+  std::string metadata_pool_name;
 
   // Consume any known --key val or --flag arguments
   for (std::vector<const char *>::const_iterator i = args.begin() + 1;
@@ -147,17 +159,69 @@ int DataScan::main(const std::vector<const char*> &args)
       continue;
     }
 
+    // Trailing positional argument
     if (i + 1 == args.end() &&
         (command == "scan_inodes" || command == "scan_extents")) {
       data_pool_name = *i;
       continue;
     }
 
+    // Trailing positional argument
+    if (i + 1 == args.end() && (command == "tmap_upgrade")) {
+      metadata_pool_name = *i;
+      continue;
+    }
+
     // Fall through: unhandled
     std::cerr << "Unknown argument '" << *i << "'" << std::endl;
     return -EINVAL;
   }
 
+  if (command == "tmap_upgrade") {
+    // Special case tmap_upgrade away from other modes, as this is a
+    // specialized command that will only exist in the Jewel series,
+    // and doesn't require the initialization of the `driver` member
+    // that is done below.
+    rados.connect();
+
+    // Initialize metadata_io from pool on command line
+    if (metadata_pool_name.empty()) {
+      std::cerr << "Metadata pool not specified" << std::endl;
+      usage();
+      return -EINVAL;
+    }
+
+    long metadata_pool_id = rados.pool_lookup(metadata_pool_name.c_str());
+    if (metadata_pool_id < 0) {
+      std::cerr << "Pool '" << metadata_pool_name << "' not found!" << std::endl;
+      return -ENOENT;
+    } else {
+      dout(4) << "pool '" << metadata_pool_name
+        << "' has ID " << metadata_pool_id << dendl;
+    }
+
+    r = rados.ioctx_create(metadata_pool_name.c_str(), metadata_io);
+    if (r != 0) {
+      return r;
+    }
+    std::cerr << "Created ioctx for " << metadata_pool_name << std::endl;
+
+    return tmap_upgrade();
+  }
+
+  // If caller didn't specify a namespace, try to pick
+  // one if only one exists
+  if (fscid == FS_CLUSTER_ID_NONE) {
+    if (fsmap->get_filesystems().size() == 1) {
+      fscid = fsmap->get_filesystems().begin()->first;
+    } else {
+      std::cerr << "Specify a filesystem with --filesystem" << std::endl;
+      return -EINVAL;
+    }
+  }
+  auto fs =  fsmap->get_filesystem(fscid);
+  assert(fs != nullptr);
+
   // Default to output to metadata pool
   if (driver == NULL) {
     driver = new MetadataDriver();
@@ -168,7 +232,7 @@ int DataScan::main(const std::vector<const char*> &args)
 
   dout(4) << "connecting to RADOS..." << dendl;
   rados.connect();
-  r = driver->init(rados, mdsmap);
+  r = driver->init(rados, fsmap, fscid);
   if (r < 0) {
     return r;
   }
@@ -191,7 +255,7 @@ int DataScan::main(const std::vector<const char*> &args)
         << "' has ID " << data_pool_id << dendl;
     }
 
-    if (!mdsmap->is_data_pool(data_pool_id)) {
+    if (!fs->mds_map.is_data_pool(data_pool_id)) {
       std::cerr << "Warning: pool '" << data_pool_name << "' is not a "
         "CephFS data pool!" << std::endl;
       if (!force_pool) {
@@ -207,8 +271,14 @@ int DataScan::main(const std::vector<const char*> &args)
     }
   }
 
+  // Initialize metadata_io from MDSMap for scan_frags
   if (command == "scan_frags") {
-    int const metadata_pool_id = mdsmap->get_metadata_pool();
+    const auto fs = fsmap->get_filesystem(fscid);
+    if (fs == nullptr) {
+      std::cerr << "Filesystem id " << fscid << " does not exist" << std::endl;
+      return -ENOENT;
+    }
+    int const metadata_pool_id = fs->mds_map.get_metadata_pool();
 
     dout(4) << "resolving metadata pool " << metadata_pool_id << dendl;
     std::string metadata_pool_name;
@@ -233,7 +303,7 @@ int DataScan::main(const std::vector<const char*> &args)
   } else if (command == "scan_frags") {
     return scan_frags();
   } else if (command == "init") {
-    return driver->init_roots(mdsmap->get_first_data_pool());
+    return driver->init_roots(fs->mds_map.get_first_data_pool());
   } else {
     std::cerr << "Unknown command '" << command << "'" << std::endl;
     return -EINVAL;
@@ -279,8 +349,8 @@ int MetadataDriver::inject_unlinked_inode(
 
   // Force layout to default: should we let users override this so that
   // they don't have to mount the filesystem to correct it?
-  inode.inode.layout = g_default_file_layout;
-  inode.inode.layout.fl_pg_pool = data_pool_id;
+  inode.inode.layout = file_layout_t::get_default();
+  inode.inode.layout.pool_id = data_pool_id;
 
   // Assume that we will get our stats wrong, and that we may
   // be ignoring dirfrags that exist
@@ -289,7 +359,7 @@ int MetadataDriver::inject_unlinked_inode(
   // Serialize
   bufferlist inode_bl;
   ::encode(std::string(CEPH_FS_ONDISK_MAGIC), inode_bl);
-  inode.encode(inode_bl);
+  inode.encode(inode_bl, CEPH_FEATURES_SUPPORTED_DEFAULT);
 
   // Write
   r = metadata_io.write_full(oid.name, inode_bl);
@@ -329,6 +399,11 @@ int MetadataDriver::init_roots(int64_t data_pool_id)
   if (r != 0) {
     return r;
   }
+  bool created = false;
+  r = find_or_create_dirfrag(MDS_INO_MDSDIR(0), frag_t(), &created);
+  if (r != 0) {
+    return r;
+  }
 
   return 0;
 }
@@ -400,39 +475,21 @@ int parse_oid(const std::string &oid, uint64_t *inode_no, uint64_t *obj_id)
   return 0;
 }
 
-// Pending sharded pgls & add in progress mechanism for that
-#undef SHARDEDPGLS
 
 int DataScan::scan_extents()
 {
-#ifdef SHARDED_PGLS
-  float progress = 0.0;
-  librados::NObjectIterator i = data_io.nobjects_begin(n, m);
-#else
-  librados::NObjectIterator i = data_io.nobjects_begin();
-#endif
-
-  librados::NObjectIterator i_end = data_io.nobjects_end();
-  int r = 0;
-
-  for (; i != i_end; ++i) {
-    const std::string oid = i->get_oid();
-#ifdef SHARDED_PGLS
-    if (i.get_progress() != progress) {
-      if (int(i.get_progress() * 100) / 5 != int(progress * 100) / 5) {
-        std::cerr << percentify(i.get_progress()) << "%" << std::endl;
-      }
-      progress = i.get_progress();
-    }
-#endif
-
+  return forall_objects(data_io, false, [this](
+        std::string const &oid,
+        uint64_t obj_name_ino,
+        uint64_t obj_name_offset) -> int
+  {
     // Read size
     uint64_t size;
     time_t mtime;
-    r = data_io.stat(oid, &size, &mtime);
+    int r = data_io.stat(oid, &size, &mtime);
     if (r != 0) {
       dout(4) << "Cannot stat '" << oid << "': skipping" << dendl;
-      continue;
+      return r;
     }
 
     // I need to keep track of
@@ -445,61 +502,132 @@ int DataScan::scan_extents()
     //  and the actual size (offset of last object + size of highest ID seen)
     //
     //  This logic doesn't take account of striping.
-    uint64_t inode_no = 0;
-    uint64_t obj_id = 0;
-    r = parse_oid(oid, &inode_no, &obj_id);
-    if (r != 0) {
-      dout(4) << "Bad object name '" << oid << "' skipping" << dendl;
-      continue;
-    }
-
-    int r = ClsCephFSClient::accumulate_inode_metadata(
+    r = ClsCephFSClient::accumulate_inode_metadata(
         data_io,
-        inode_no,
-        obj_id,
+        obj_name_ino,
+        obj_name_offset,
         size,
         mtime);
     if (r < 0) {
       derr << "Failed to accumulate metadata data from '"
         << oid << "': " << cpp_strerror(r) << dendl;
-      continue;
+      return r;
     }
-  }
 
-  return 0;
+    return r;
+  });
 }
 
-int DataScan::scan_inodes()
+int DataScan::probe_filter(librados::IoCtx &ioctx)
 {
-#ifdef SHARDED_PGLS
-  float progress = 0.0;
-  librados::NObjectIterator i = data_io.nobjects_begin(n, m);
-#else
-  librados::NObjectIterator i;
-  bool legacy_filtering = false;
+  bufferlist filter_bl;
+  ClsCephFSClient::build_tag_filter("test", &filter_bl);
+  librados::ObjectCursor range_i;
+  librados::ObjectCursor range_end;
+
+  std::vector<librados::ObjectItem> tmp_result;
+  librados::ObjectCursor tmp_next;
+  int r = ioctx.object_list(ioctx.object_list_begin(), ioctx.object_list_end(),
+                            1, filter_bl, &tmp_result, &tmp_next);
+
+  return r >= 0;
+}
+
+int DataScan::forall_objects(
+    librados::IoCtx &ioctx,
+    bool untagged_only,
+    std::function<int(std::string, uint64_t, uint64_t)> handler
+    )
+{
+  librados::ObjectCursor range_i;
+  librados::ObjectCursor range_end;
+  ioctx.object_list_slice(
+      ioctx.object_list_begin(),
+      ioctx.object_list_end(),
+      n,
+      m,
+      &range_i,
+      &range_end);
+
 
   bufferlist filter_bl;
-  ClsCephFSClient::build_tag_filter(filter_tag, &filter_bl);
 
-  // try/catch to deal with older OSDs that don't support
-  // the cephfs pgls filtering mode
-  try {
-    i = data_io.nobjects_begin(filter_bl);
-    dout(4) << "OSDs accepted cephfs object filtering" << dendl;
-  } catch (const std::runtime_error &e) {
-    // A little unfriendly, librados raises std::runtime_error
-    // on pretty much any unhandled I/O return value, such as
-    // the OSD saying -EINVAL because of our use of a filter
-    // mode that it doesn't know about.
-    std::cerr << "OSDs do not support cephfs object filtering: using "
-                 "(slower) fallback mode" << std::endl;
-    legacy_filtering = true;
-    i = data_io.nobjects_begin();
+  bool legacy_filtering = false;
+  if (untagged_only) {
+    // probe to deal with older OSDs that don't support
+    // the cephfs pgls filtering mode
+    legacy_filtering = !probe_filter(ioctx);
+    if (!legacy_filtering) {
+      ClsCephFSClient::build_tag_filter(filter_tag, &filter_bl);
+    }
+  }
+
+  int r = 0;
+  while(range_i < range_end) {
+    std::vector<librados::ObjectItem> result;
+    int r = ioctx.object_list(range_i, range_end, 1,
+                                filter_bl, &result, &range_i);
+    if (r < 0) {
+      derr << "Unexpected error listing objects: " << cpp_strerror(r) << dendl;
+      return r;
+    }
+
+    for (const auto &i : result) {
+      const std::string &oid = i.oid;
+      uint64_t obj_name_ino = 0;
+      uint64_t obj_name_offset = 0;
+      r = parse_oid(oid, &obj_name_ino, &obj_name_offset);
+      if (r != 0) {
+        dout(4) << "Bad object name '" << oid << "', skipping" << dendl;
+        continue;
+      }
+
+      if (untagged_only && legacy_filtering) {
+        dout(20) << "Applying filter to " << oid << dendl;
+
+        // We are only interested in 0th objects during this phase: we touched
+        // the other objects during scan_extents
+        if (obj_name_offset != 0) {
+          dout(20) << "Non-zeroth object" << dendl;
+          continue;
+        }
+
+        bufferlist scrub_tag_bl;
+        int r = ioctx.getxattr(oid, "scrub_tag", scrub_tag_bl);
+        if (r >= 0) {
+          std::string read_tag;
+          bufferlist::iterator q = scrub_tag_bl.begin();
+          try {
+            ::decode(read_tag, q);
+            if (read_tag == filter_tag) {
+              dout(20) << "skipping " << oid << " because it has the filter_tag"
+                       << dendl;
+              continue;
+            }
+          } catch (const buffer::error &err) {
+          }
+          dout(20) << "read non-matching tag '" << read_tag << "'" << dendl;
+        } else {
+          dout(20) << "no tag read (" << r << ")" << dendl;
+        }
+
+      } else if (untagged_only) {
+        assert(obj_name_offset == 0);
+        dout(20) << "OSD matched oid " << oid << dendl;
+      }
+
+      int this_oid_r = handler(oid, obj_name_ino, obj_name_offset);
+      if (r == 0 && this_oid_r < 0) {
+        r = this_oid_r;
+      }
+    }
   }
 
-#endif
-  librados::NObjectIterator i_end = data_io.nobjects_end();
+  return r;
+}
 
+int DataScan::scan_inodes()
+{
   bool roots_present;
   int r = driver->check_roots(&roots_present);
   if (r != 0) {
@@ -514,77 +642,31 @@ int DataScan::scan_inodes()
     return -EIO;
   }
 
-  for (; i != i_end; ++i) {
-    const std::string oid = i->get_oid();
-#ifdef SHARDED_PGLS
-    if (i.get_progress() != progress) {
-      if (int(i.get_progress() * 100) / 5 != int(progress * 100) / 5) {
-        std::cerr << percentify(i.get_progress()) << "%" << std::endl;
-      }
-      progress = i.get_progress();
-    }
-#endif
-
-    uint64_t obj_name_ino = 0;
-    uint64_t obj_name_offset = 0;
-    r = parse_oid(oid, &obj_name_ino, &obj_name_offset);
-    if (r != 0) {
-      dout(4) << "Bad object name '" << oid << "', skipping" << dendl;
-      continue;
-    }
-
-    if (legacy_filtering) {
-      dout(20) << "Applying filter to " << oid << dendl;
-
-      // We are only interested in 0th objects during this phase: we touched
-      // the other objects during scan_extents
-      if (obj_name_offset != 0) {
-        dout(20) << "Non-zeroth object" << dendl;
-        continue;
-      }
-
-      bufferlist scrub_tag_bl;
-      int r = data_io.getxattr(oid, "scrub_tag", scrub_tag_bl);
-      if (r >= 0) {
-        std::string read_tag;
-        bufferlist::iterator q = scrub_tag_bl.begin();
-	try {
-	  ::decode(read_tag, q);
-	  if (read_tag == filter_tag) {
-	    dout(20) << "skipping " << oid << " because it has the filter_tag"
-		     << dendl;
-	    continue;
-	  }
-	} catch (const buffer::error &err) {
-	}
-	dout(20) << "read non-matching tag '" << read_tag << "'" << dendl;
-      } else {
-        dout(20) << "no tag read (" << r << ")" << dendl;
-      }
-
-    } else {
-      assert(obj_name_offset == 0);
-      dout(20) << "OSD matched oid " << oid << dendl;
-    }
+  return forall_objects(data_io, true, [this](
+        std::string const &oid,
+        uint64_t obj_name_ino,
+        uint64_t obj_name_offset) -> int
+  {
+    int r = 0;
 
     AccumulateResult accum_res;
     inode_backtrace_t backtrace;
-    ceph_file_layout loaded_layout = g_default_file_layout;
-    int r = ClsCephFSClient::fetch_inode_accumulate_result(
+    file_layout_t loaded_layout = file_layout_t::get_default();
+    r = ClsCephFSClient::fetch_inode_accumulate_result(
         data_io, oid, &backtrace, &loaded_layout, &accum_res);
 
     if (r == -EINVAL) {
       dout(4) << "Accumulated metadata missing from '"
               << oid << ", did you run scan_extents?" << dendl;
-      continue;
-    } else  if (r < 0) {
+      return r;
+    } else if (r < 0) {
       dout(4) << "Unexpected error loading accumulated metadata from '"
               << oid << "': " << cpp_strerror(r) << dendl;
       // FIXME: this creates situation where if a client has a corrupt
       // backtrace/layout, we will fail to inject it.  We should (optionally)
       // proceed if the backtrace/layout is corrupt but we have valid
       // accumulated metadata.
-      continue;
+      return r;
     }
 
     const time_t file_mtime = accum_res.max_mtime;
@@ -593,12 +675,12 @@ int DataScan::scan_inodes()
 
     // This is the layout we will use for injection, populated either
     // from loaded_layout or from best guesses
-    ceph_file_layout guessed_layout;
-    guessed_layout.fl_pg_pool = data_pool_id;
+    file_layout_t guessed_layout;
+    guessed_layout.pool_id = data_pool_id;
 
     // Calculate file_size, guess the layout
     if (accum_res.ceiling_obj_index > 0) {
-      uint32_t chunk_size = g_default_file_layout.fl_object_size;
+      uint32_t chunk_size = file_layout_t::get_default().object_size;
       // When there are multiple objects, the largest object probably
       // indicates the chunk size.  But not necessarily, because files
       // can be sparse.  Only make this assumption if size seen
@@ -607,46 +689,46 @@ int DataScan::scan_inodes()
         chunk_size = accum_res.max_obj_size;
       }
 
-      if (loaded_layout.fl_pg_pool == uint32_t(-1)) {
+      if (loaded_layout.pool_id == -1) {
         // If no stashed layout was found, guess it
-        guessed_layout.fl_object_size = chunk_size;
-        guessed_layout.fl_stripe_unit = chunk_size;
-        guessed_layout.fl_stripe_count = 1;
-      } else if (!ceph_file_layout_is_valid(&loaded_layout) ||
-          loaded_layout.fl_object_size < accum_res.max_obj_size) {
+        guessed_layout.object_size = chunk_size;
+        guessed_layout.stripe_unit = chunk_size;
+        guessed_layout.stripe_count = 1;
+      } else if (!loaded_layout.is_valid() ||
+          loaded_layout.object_size < accum_res.max_obj_size) {
         // If the max size seen exceeds what the stashed layout claims, then
         // disbelieve it.  Guess instead.  Same for invalid layouts on disk.
         dout(4) << "bogus xattr layout on 0x" << std::hex << obj_name_ino
                 << std::dec << ", ignoring in favour of best guess" << dendl;
-        guessed_layout.fl_object_size = chunk_size;
-        guessed_layout.fl_stripe_unit = chunk_size;
-        guessed_layout.fl_stripe_count = 1;
+        guessed_layout.object_size = chunk_size;
+        guessed_layout.stripe_unit = chunk_size;
+        guessed_layout.stripe_count = 1;
       } else {
         // We have a stashed layout that we can't disprove, so apply it
         guessed_layout = loaded_layout;
         dout(20) << "loaded layout from xattr:"
-          << " os: " << guessed_layout.fl_object_size
-          << " sc: " << guessed_layout.fl_stripe_count
-          << " su: " << guessed_layout.fl_stripe_unit
+          << " os: " << guessed_layout.object_size
+          << " sc: " << guessed_layout.stripe_count
+          << " su: " << guessed_layout.stripe_unit
           << dendl;
         // User might have transplanted files from a pool with a different
         // ID, so whatever the loaded_layout says, we'll force the injected
         // layout to point to the pool we really read from
-        guessed_layout.fl_pg_pool = data_pool_id;
+        guessed_layout.pool_id = data_pool_id;
       }
 
-      if (guessed_layout.fl_stripe_count == 1) {
+      if (guessed_layout.stripe_count == 1) {
         // Unstriped file: simple chunking
-        file_size = guessed_layout.fl_object_size * accum_res.ceiling_obj_index
+        file_size = guessed_layout.object_size * accum_res.ceiling_obj_index
                     + accum_res.ceiling_obj_size;
       } else {
-        // Striped file: need to examine the last fl_stripe_count objects
+        // Striped file: need to examine the last stripe_count objects
         // in the file to determine the size.
 
         // How many complete (i.e. not last stripe) objects?
         uint64_t complete_objs = 0;
-        if (accum_res.ceiling_obj_index > guessed_layout.fl_stripe_count - 1) {
-          complete_objs = (accum_res.ceiling_obj_index / guessed_layout.fl_stripe_count) * guessed_layout.fl_stripe_count;
+        if (accum_res.ceiling_obj_index > guessed_layout.stripe_count - 1) {
+          complete_objs = (accum_res.ceiling_obj_index / guessed_layout.stripe_count) * guessed_layout.stripe_count;
         } else {
           complete_objs = 0;
         }
@@ -672,15 +754,15 @@ int DataScan::scan_inodes()
           time_t omtime(0);
           r = data_io.stat(std::string(buf), &osize, &omtime);
           if (r == 0) {
-	    if (osize > 0) {
-	      // Upper bound within this object
-	      uint64_t upper_size = (osize - 1) / guessed_layout.fl_stripe_unit
-		* (guessed_layout.fl_stripe_unit * guessed_layout.fl_stripe_count)
-		+ (i % guessed_layout.fl_stripe_count)
-		* guessed_layout.fl_stripe_unit + (osize - 1)
-		% guessed_layout.fl_stripe_unit + 1;
-	      incomplete_size = MAX(incomplete_size, upper_size);
-	    }
+            if (osize > 0) {
+              // Upper bound within this object
+              uint64_t upper_size = (osize - 1) / guessed_layout.stripe_unit
+                * (guessed_layout.stripe_unit * guessed_layout.stripe_count)
+                + (i % guessed_layout.stripe_count)
+                * guessed_layout.stripe_unit + (osize - 1)
+                % guessed_layout.stripe_unit + 1;
+              incomplete_size = MAX(incomplete_size, upper_size);
+            }
           } else if (r == -ENOENT) {
             // Absent object, treat as size 0 and ignore.
           } else {
@@ -691,18 +773,18 @@ int DataScan::scan_inodes()
         if (r != 0 && r != -ENOENT) {
           derr << "Unexpected error checking size of ino 0x" << std::hex
                << obj_name_ino << std::dec << ": " << cpp_strerror(r) << dendl;
-          continue;
+          return r;
         }
-        file_size = complete_objs * guessed_layout.fl_object_size
+        file_size = complete_objs * guessed_layout.object_size
                     + incomplete_size;
       }
     } else {
       file_size = accum_res.ceiling_obj_size;
-      if (loaded_layout.fl_pg_pool == uint32_t(-1)
-          || loaded_layout.fl_object_size < accum_res.max_obj_size) {
+      if (loaded_layout.pool_id < 0
+          || loaded_layout.object_size < accum_res.max_obj_size) {
         // No layout loaded, or inconsistent layout, use default
-        guessed_layout = g_default_file_layout;
-        guessed_layout.fl_pg_pool = data_pool_id;
+        guessed_layout = file_layout_t::get_default();
+        guessed_layout.pool_id = data_pool_id;
       } else {
         guessed_layout = loaded_layout;
       }
@@ -760,37 +842,59 @@ int DataScan::scan_inodes()
         }
       }
     }
-  }
 
-  return 0;
+    return r;
+  });
 }
 
-int DataScan::scan_frags()
+bool DataScan::valid_ino(inodeno_t ino) const
 {
-  librados::NObjectIterator i;
-  bool legacy_filtering = false;
+  return (ino >= inodeno_t((1ull << 40)))
+    || (MDS_INO_IS_STRAY(ino))
+    || (MDS_INO_IS_MDSDIR(ino))
+    || ino == MDS_INO_ROOT
+    || ino == MDS_INO_CEPH;
+}
 
-  bufferlist filter_bl;
-  ClsCephFSClient::build_tag_filter(filter_tag, &filter_bl);
+int DataScan::tmap_upgrade()
+{
+  librados::NObjectIterator i = metadata_io.nobjects_begin();
+  const librados::NObjectIterator i_end = metadata_io.nobjects_end();
 
-  // try/catch to deal with older OSDs that don't support
-  // the cephfs pgls filtering mode
-  try {
-    i = metadata_io.nobjects_begin(filter_bl);
-    dout(4) << "OSDs accepted cephfs object filtering" << dendl;
-  } catch (const std::runtime_error &e) {
-    // A little unfriendly, librados raises std::runtime_error
-    // on pretty much any unhandled I/O return value, such as
-    // the OSD saying -EINVAL because of our use of a filter
-    // mode that it doesn't know about.
-    std::cerr << "OSDs do not support cephfs object filtering: using "
-                 "(slower) fallback mode" << std::endl;
-    legacy_filtering = true;
-    i = metadata_io.nobjects_begin();
+  int overall_r = 0;
+
+  for (; i != i_end; ++i) {
+    const std::string oid = i->get_oid();
+
+    uint64_t inode_no = 0;
+    uint64_t frag_id = 0;
+    int r = parse_oid(oid, &inode_no, &frag_id);
+    if (r == -EINVAL) {
+      dout(10) << "Not a dirfrag: '" << oid << "'" << dendl;
+      continue;
+    } else {
+      // parse_oid can only do 0 or -EINVAL
+      assert(r == 0);
+    }
+
+    if (!valid_ino(inode_no)) {
+      dout(10) << "Not a difrag (invalid ino): '" << oid << "'" << dendl;
+      continue;
+    }
+
+    r = metadata_io.tmap_to_omap(oid, true);
+    dout(20) << "tmap2omap(" << oid << "): " << r << dendl;
+    if (r < 0) {
+      derr << "Error converting '" << oid << "': " << cpp_strerror(r) << dendl;
+      overall_r = r;
+    }
   }
 
-  librados::NObjectIterator i_end = metadata_io.nobjects_end();
+  return overall_r;
+}
 
+int DataScan::scan_frags()
+{
   bool roots_present;
   int r = driver->check_roots(&roots_present);
   if (r != 0) {
@@ -805,14 +909,16 @@ int DataScan::scan_frags()
     return -EIO;
   }
 
-  for (; i != i_end; ++i) {
-    const std::string oid = i->get_oid();
-    uint64_t obj_name_ino = 0;
-    uint64_t obj_name_offset = 0;
+  return forall_objects(metadata_io, true, [this](
+        std::string const &oid,
+        uint64_t obj_name_ino,
+        uint64_t obj_name_offset) -> int
+  {
+    int r = 0;
     r = parse_oid(oid, &obj_name_ino, &obj_name_offset);
     if (r != 0) {
       dout(4) << "Bad object name '" << oid << "', skipping" << dendl;
-      continue;
+      return r;
     }
 
     if (obj_name_ino < (1ULL << 40)) {
@@ -820,39 +926,7 @@ int DataScan::scan_frags()
       // orphaned then we should be resetting them some other
       // way
       dout(10) << "Skipping system ino " << obj_name_ino << dendl;
-      continue;
-    }
-
-    if (legacy_filtering) {
-      dout(20) << "Applying filter to " << oid << dendl;
-
-      // We are only interested in 0th objects during this phase: we touched
-      // the other objects during scan_extents
-      if (obj_name_offset != 0) {
-        dout(20) << "Non-zeroth object" << dendl;
-        continue;
-      }
-
-      bufferlist scrub_tag_bl;
-      int r = metadata_io.getxattr(oid, "scrub_tag", scrub_tag_bl);
-      if (r >= 0) {
-        std::string read_tag;
-        bufferlist::iterator q = scrub_tag_bl.begin();
-        ::decode(read_tag, q);
-        if (read_tag == filter_tag) {
-          dout(20) << "skipping " << oid << " because it has the filter_tag"
-                   << dendl;
-          continue;
-        } else {
-          dout(20) << "read non-matching tag '" << read_tag << "'" << dendl;
-        }
-      } else {
-        dout(20) << "no tag read (" << r << ")" << dendl;
-      }
-
-    } else {
-      assert(obj_name_offset == 0);
-      dout(20) << "OSD matched oid " << oid << dendl;
+      return 0;
     }
 
     AccumulateResult accum_res;
@@ -860,8 +934,7 @@ int DataScan::scan_frags()
 
     // Default to inherit layout (i.e. no explicit layout on dir) which is
     // expressed as a zeroed layout struct (see inode_t::has_layout)
-    ceph_file_layout loaded_layout;
-    memset(&loaded_layout, 0, sizeof(loaded_layout));
+    file_layout_t loaded_layout;
 
     int parent_r = 0;
     bufferlist parent_bl;
@@ -872,10 +945,10 @@ int DataScan::scan_frags()
     librados::ObjectReadOperation op;
     op.getxattr("parent", &parent_bl, &parent_r);
     op.getxattr("layout", &layout_bl, &layout_r);
-    int r = metadata_io.operate(oid, &op, &op_bl);
+    r = metadata_io.operate(oid, &op, &op_bl);
     if (r != 0 && r != -ENODATA) {
       derr << "Unexpected error reading backtrace: " << cpp_strerror(parent_r) << dendl;
-      continue;
+      return r;
     }
 
     if (parent_r != -ENODATA) {
@@ -885,7 +958,7 @@ int DataScan::scan_frags()
       } catch (buffer::error &e) {
         dout(4) << "Corrupt backtrace on '" << oid << "': " << e << dendl;
         if (!force_corrupt) {
-          continue;
+          return -EINVAL;
         } else {
           // Treat backtrace as absent: we'll inject into lost+found
           backtrace = inode_backtrace_t();
@@ -900,7 +973,7 @@ int DataScan::scan_frags()
       } catch (buffer::error &e) {
         dout(4) << "Corrupt layout on '" << oid << "': " << e << dendl;
         if (!force_corrupt) {
-          continue;
+          return -EINVAL;
         }
       }
     }
@@ -925,7 +998,7 @@ int DataScan::scan_frags()
         fnode.fragstat.nfiles = 1;
         fnode.fragstat.nsubdirs = 0;
       } else {
-        continue;
+        return r;
       }
     }
 
@@ -974,9 +1047,9 @@ int DataScan::scan_frags()
         }
       }
     }
-  }
 
-  return 0;
+    return r;
+  });
 }
 
 int MetadataTool::read_fnode(
@@ -1072,8 +1145,7 @@ int MetadataDriver::inject_lost_and_found(
 
     // To have a directory not specify a layout, give it zeros (see
     // inode_t::has_layout)
-    ceph_file_layout inherit_layout;
-    memset(&inherit_layout, 0, sizeof(inherit_layout));
+    file_layout_t inherit_layout;
 
     // Construct LF inode
     build_dir_dentry(CEPH_INO_LOST_AND_FOUND, 1, 0, inherit_layout, &lf_ino);
@@ -1429,7 +1501,7 @@ int MetadataDriver::find_or_create_dirfrag(
     object_t frag_oid = InodeStore::get_object_name(ino, fragment, "");
     op.omap_set_header(fnode_bl);
     r = metadata_io.operate(frag_oid.name, &op);
-    if (r == -EOVERFLOW) {
+    if (r == -EOVERFLOW || r == -EEXIST) {
       // Someone else wrote it (see case A above)
       dout(10) << "Dirfrag creation race: 0x" << std::hex
         << ino << " " << fragment << std::dec << dendl;
@@ -1475,7 +1547,7 @@ int MetadataDriver::inject_linkage(
   bufferlist dentry_bl;
   ::encode(snap, dentry_bl);
   ::encode('I', dentry_bl);
-  inode.encode_bare(dentry_bl);
+  inode.encode_bare(dentry_bl, CEPH_FEATURES_SUPPORTED_DEFAULT);
 
   // Write out
   std::map<std::string, bufferlist> vals;
@@ -1495,9 +1567,12 @@ int MetadataDriver::inject_linkage(
 }
 
 
-int MetadataDriver::init(librados::Rados &rados, const MDSMap *mdsmap)
+int MetadataDriver::init(
+    librados::Rados &rados, const FSMap *fsmap, fs_cluster_id_t fscid)
 {
-  int const metadata_pool_id = mdsmap->get_metadata_pool();
+  auto fs =  fsmap->get_filesystem(fscid);
+  assert(fs != nullptr);
+  int const metadata_pool_id = fs->mds_map.get_metadata_pool();
 
   dout(4) << "resolving metadata pool " << metadata_pool_id << dendl;
   std::string metadata_pool_name;
@@ -1511,7 +1586,8 @@ int MetadataDriver::init(librados::Rados &rados, const MDSMap *mdsmap)
   return rados.ioctx_create(metadata_pool_name.c_str(), metadata_io);
 }
 
-int LocalFileDriver::init(librados::Rados &rados, const MDSMap *mdsmap)
+int LocalFileDriver::init(
+    librados::Rados &rados, const FSMap *fsmap, fs_cluster_id_t fscid)
 {
   return 0;
 }
@@ -1576,7 +1652,8 @@ int LocalFileDriver::inject_with_backtrace(
     if (is_file) {
       // FIXME: inject_data won't cope with interesting (i.e. striped)
       // layouts (need a librados-compatible Filer to read these)
-      inject_data(path_builder, dentry.inode.size, dentry.inode.layout.fl_object_size, bt.ino);
+      inject_data(path_builder, dentry.inode.size,
+		  dentry.inode.layout.object_size, bt.ino);
     } else {
       int r = mkdir(path_builder.c_str(), 0755);
       if (r != 0 && r != -EPERM) {
@@ -1603,7 +1680,8 @@ int LocalFileDriver::inject_lost_and_found(
   }
   
   std::string file_path = lf_path + "/" + lost_found_dname(ino);
-  return inject_data(file_path, dentry.inode.size, dentry.inode.layout.fl_object_size, ino);
+  return inject_data(file_path, dentry.inode.size,
+		     dentry.inode.layout.object_size, ino);
 }
 
 int LocalFileDriver::init_roots(int64_t data_pool_id)
@@ -1643,7 +1721,7 @@ int LocalFileDriver::check_roots(bool *result)
 
 void MetadataTool::build_file_dentry(
     inodeno_t ino, uint64_t file_size, time_t file_mtime,
-    const ceph_file_layout &layout, InodeStore *out)
+    const file_layout_t &layout, InodeStore *out)
 {
   assert(out != NULL);
 
@@ -1671,7 +1749,7 @@ void MetadataTool::build_file_dentry(
 
 void MetadataTool::build_dir_dentry(
     inodeno_t ino, uint64_t nfiles,
-    time_t mtime, const ceph_file_layout &layout, InodeStore *out)
+    time_t mtime, const file_layout_t &layout, InodeStore *out)
 {
   assert(out != NULL);
 
diff --git a/src/tools/cephfs/DataScan.h b/src/tools/cephfs/DataScan.h
index cc9e39e..107ab74 100644
--- a/src/tools/cephfs/DataScan.h
+++ b/src/tools/cephfs/DataScan.h
@@ -28,7 +28,10 @@ class RecoveryDriver {
     bool force_init;
 
   public:
-    virtual int init(librados::Rados &rados, const MDSMap *mdsmap) = 0;
+    virtual int init(
+        librados::Rados &rados,
+        const FSMap *fsmap,
+        fs_cluster_id_t fscid) = 0;
 
     void set_force_corrupt(const bool val)
     {
@@ -112,7 +115,10 @@ class LocalFileDriver : public RecoveryDriver
     {}
 
     // Implement RecoveryDriver interface
-    int init(librados::Rados &rados, const MDSMap *mdsmap);
+    int init(
+        librados::Rados &rados,
+        const FSMap *fsmap,
+        fs_cluster_id_t fscid);
 
     int inject_with_backtrace(
         const inode_backtrace_t &bt,
@@ -142,7 +148,7 @@ class MetadataTool
    */
   void build_file_dentry(
     inodeno_t ino, uint64_t file_size, time_t file_mtime,
-    const ceph_file_layout &layout,
+    const file_layout_t &layout,
     InodeStore *out);
 
   /**
@@ -151,7 +157,7 @@ class MetadataTool
   void build_dir_dentry(
     inodeno_t ino, uint64_t nfiles,
     time_t mtime,
-    const ceph_file_layout &layout,
+    const file_layout_t &layout,
     InodeStore *out);
 
   /**
@@ -205,7 +211,10 @@ class MetadataDriver : public RecoveryDriver, public MetadataTool
   public:
 
     // Implement RecoveryDriver interface
-    int init(librados::Rados &rados, const MDSMap *mdsmap);
+    int init(
+        librados::Rados &rados,
+        const FSMap *fsmap,
+        fs_cluster_id_t fscid);
 
     int inject_with_backtrace(
         const inode_backtrace_t &bt,
@@ -224,6 +233,7 @@ class DataScan : public MDSUtility, public MetadataTool
 {
   protected:
     RecoveryDriver *driver;
+    fs_cluster_id_t fscid;
 
     // IoCtx for data pool (where we scrape file backtraces from)
     librados::IoCtx data_io;
@@ -249,7 +259,17 @@ class DataScan : public MDSUtility, public MetadataTool
      */
     int scan_frags();
 
-    // Accept pools which are not in the MDSMap
+    /**
+     * Check if an inode number is in the permitted ranges
+     */
+    bool valid_ino(inodeno_t ino) const;
+
+    /**
+     * Invoke tmap_to_omap on all metadata pool objects
+     */
+    int tmap_upgrade();
+
+    // Accept pools which are not in the FSMap
     bool force_pool;
     // Respond to decode errors by overwriting
     bool force_corrupt;
@@ -274,14 +294,24 @@ class DataScan : public MDSUtility, public MetadataTool
       const std::vector<const char*> &arg,
       std::vector<const char *>::const_iterator &i);
 
+    int probe_filter(librados::IoCtx &ioctx);
 
+    /**
+     * Apply a function to all objects in an ioctx's pool, optionally
+     * restricted to only those objects with a 00000000 offset and
+     * no tag matching DataScan::scrub_tag.
+     */
+    int forall_objects(
+        librados::IoCtx &ioctx,
+        bool untagged_only,
+        std::function<int(std::string, uint64_t, uint64_t)> handler);
 
   public:
     void usage();
     int main(const std::vector<const char *> &args);
 
     DataScan()
-      : driver(NULL), data_pool_id(-1), n(0), m(1),
+      : driver(NULL), fscid(FS_CLUSTER_ID_NONE), data_pool_id(-1), n(0), m(1),
         force_pool(false), force_corrupt(false),
         force_init(false)
     {
diff --git a/src/tools/cephfs/Dumper.cc b/src/tools/cephfs/Dumper.cc
index 1abd74c..af04bf6 100644
--- a/src/tools/cephfs/Dumper.cc
+++ b/src/tools/cephfs/Dumper.cc
@@ -17,6 +17,7 @@
 #endif
 
 #include "include/compat.h"
+#include "include/fs_types.h"
 #include "common/entity_name.h"
 #include "common/errno.h"
 #include "common/safe_io.h"
@@ -31,16 +32,19 @@
 
 #define HEADER_LEN 4096
 
-int Dumper::init(int rank_)
+int Dumper::init(mds_role_t role_)
 {
-  rank = rank_;
+  role = role_;
 
   int r = MDSUtility::init();
   if (r < 0) {
     return r;
   }
 
-  JournalPointer jp(rank, mdsmap->get_metadata_pool());
+  auto fs =  fsmap->get_filesystem(role.fscid);
+  assert(fs != nullptr);
+
+  JournalPointer jp(role.rank, fs->mds_map.get_metadata_pool());
   int jp_load_result = jp.load(objecter);
   if (jp_load_result != 0) {
     std::cerr << "Error loading journal: " << cpp_strerror(jp_load_result) << std::endl;
@@ -74,8 +78,12 @@ int Dumper::dump(const char *dump_file)
 {
   int r = 0;
 
-  Journaler journaler(ino, mdsmap->get_metadata_pool(), CEPH_FS_ONDISK_MAGIC,
-                                       objecter, 0, 0, &timer, &finisher);
+  auto fs =  fsmap->get_filesystem(role.fscid);
+  assert(fs != nullptr);
+
+  Journaler journaler(ino, fs->mds_map.get_metadata_pool(),
+                      CEPH_FS_ONDISK_MAGIC, objecter, 0, 0,
+                      &timer, &finisher);
   r = recover_journal(&journaler);
   if (r) {
     return r;
@@ -94,7 +102,7 @@ int Dumper::dump(const char *dump_file)
     char buf[HEADER_LEN];
     memset(buf, 0, sizeof(buf));
     snprintf(buf, HEADER_LEN, "Ceph mds%d journal dump\n start offset %llu (0x%llx)\n       length %llu (0x%llx)\n    write_pos %llu (0x%llx)\n    format %llu\n    trimmed_pos %llu (0x%llx)\n%c",
-	    rank, 
+	    role.rank, 
 	    (unsigned long long)start, (unsigned long long)start,
 	    (unsigned long long)len, (unsigned long long)len,
 	    (unsigned long long)journaler.last_committed.write_pos, (unsigned long long)journaler.last_committed.write_pos,
@@ -174,6 +182,9 @@ int Dumper::undump(const char *dump_file)
 {
   cout << "undump " << dump_file << std::endl;
   
+  auto fs =  fsmap->get_filesystem(role.fscid);
+  assert(fs != nullptr);
+
   int r = 0;
   int fd = ::open(dump_file, O_RDONLY);
   if (fd < 0) {
@@ -203,7 +214,7 @@ int Dumper::undump(const char *dump_file)
   } else {
     // Old format dump, any untrimmed objects before expire_pos will
     // be discarded as trash.
-    trimmed_pos = start - (start % g_default_file_layout.fl_object_size);
+    trimmed_pos = start - (start % file_layout_t::get_default().object_size);
   }
 
   if (trimmed_pos > start) {
@@ -233,14 +244,14 @@ int Dumper::undump(const char *dump_file)
   h.stream_format = format;
   h.magic = CEPH_FS_ONDISK_MAGIC;
 
-  h.layout = g_default_file_layout;
-  h.layout.fl_pg_pool = mdsmap->get_metadata_pool();
+  h.layout = file_layout_t::get_default();
+  h.layout.pool_id = fs->mds_map.get_metadata_pool();
   
   bufferlist hbl;
   ::encode(h, hbl);
 
   object_t oid = file_object_t(ino, 0);
-  object_locator_t oloc(mdsmap->get_metadata_pool());
+  object_locator_t oloc(fs->mds_map.get_metadata_pool());
   SnapContext snapc;
 
   cout << "writing header " << oid << std::endl;
@@ -266,7 +277,7 @@ int Dumper::undump(const char *dump_file)
    * will be taken care of during normal operation by Journaler's
    * prezeroing behaviour */
   {
-    uint32_t const object_size = h.layout.fl_object_size;
+    uint32_t const object_size = h.layout.object_size;
     assert(object_size > 0);
     uint64_t const last_obj = h.write_pos / object_size;
     uint64_t const purge_count = 2;
diff --git a/src/tools/cephfs/Dumper.h b/src/tools/cephfs/Dumper.h
index e94c596..97b56a7 100644
--- a/src/tools/cephfs/Dumper.h
+++ b/src/tools/cephfs/Dumper.h
@@ -29,16 +29,16 @@ class Journaler;
 
 class Dumper : public MDSUtility {
 private:
-  int rank;
+  mds_role_t role;
   inodeno_t ino;
 
 public:
-  Dumper() : rank(-1), ino(-1)
+  Dumper() : ino(-1)
   {}
 
-  void handle_mds_map(MMDSMap* m);
+  void handle_mds_map(MFSMap* m);
 
-  int init(int rank);
+  int init(mds_role_t role_);
   int recover_journal(Journaler *journaler);
   int dump(const char *dumpfile);
   int undump(const char *dumpfile);
diff --git a/src/tools/cephfs/EventOutput.cc b/src/tools/cephfs/EventOutput.cc
index a93c099..52eddba 100644
--- a/src/tools/cephfs/EventOutput.cc
+++ b/src/tools/cephfs/EventOutput.cc
@@ -36,7 +36,7 @@ int EventOutput::binary() const
   for (JournalScanner::EventMap::const_iterator i = scan.events.begin(); i != scan.events.end(); ++i) {
     LogEvent *le = i->second.log_event;
     bufferlist le_bin;
-    le->encode(le_bin);
+    le->encode(le_bin, CEPH_FEATURES_SUPPORTED_DEFAULT);
 
     std::stringstream filename;
     filename << "0x" << std::hex << i->first << std::dec << "_" << le->get_type_str() << ".bin";
diff --git a/src/tools/cephfs/JournalScanner.cc b/src/tools/cephfs/JournalScanner.cc
index f2d22d0..7df9390 100644
--- a/src/tools/cephfs/JournalScanner.cc
+++ b/src/tools/cephfs/JournalScanner.cc
@@ -137,7 +137,7 @@ int JournalScanner::scan_events()
   uint64_t object_size = g_conf->mds_log_segment_size;
   if (object_size == 0) {
     // Default layout object size
-    object_size = g_default_file_layout.fl_object_size;
+    object_size = file_layout_t::get_default().object_size;
   }
 
   uint64_t read_offset = header->expire_pos;
diff --git a/src/tools/cephfs/JournalTool.cc b/src/tools/cephfs/JournalTool.cc
index d07d487..63e5ac1 100644
--- a/src/tools/cephfs/JournalTool.cc
+++ b/src/tools/cephfs/JournalTool.cc
@@ -60,7 +60,7 @@ void JournalTool::usage()
     << "    <output>: [summary|binary|json] [--path <path>]\n"
     << "\n"
     << "Options:\n"
-    << "  --rank=<int>  Journal rank (default 0)\n";
+    << "  --rank=<str>  Journal rank (default 0)\n";
 
   generic_client_usage();
 }
@@ -82,14 +82,17 @@ int JournalTool::main(std::vector<const char*> &argv)
   }
 
   std::vector<const char*>::iterator arg = argv.begin();
+
   std::string rank_str;
-  if(ceph_argparse_witharg(argv, arg, &rank_str, "--rank", (char*)NULL)) {
-    std::string rank_err;
-    rank = strict_strtol(rank_str.c_str(), 10, &rank_err);
-    if (!rank_err.empty()) {
-        derr << "Bad rank '" << rank_str << "'" << dendl;
-        usage();
-    }
+  if(!ceph_argparse_witharg(argv, arg, &rank_str, "--rank", (char*)NULL)) {
+    // Default: act on rank 0.  Will give the user an error if they
+    // try invoking this way when they have more than one filesystem.
+    rank_str = "0";
+  }
+
+  r = role_selector.parse(*fsmap, rank_str);
+  if (r != 0) {
+    return r;
   }
 
   std::string mode;
@@ -111,7 +114,9 @@ int JournalTool::main(std::vector<const char*> &argv)
   dout(4) << "JournalTool: connecting to RADOS..." << dendl;
   rados.connect();
  
-  int const pool_id = mdsmap->get_metadata_pool();
+  auto fs = fsmap->get_filesystem(role_selector.get_ns());
+  assert(fs != nullptr);
+  int const pool_id = fs->mds_map.get_metadata_pool();
   dout(4) << "JournalTool: resolving pool " << pool_id << dendl;
   std::string pool_name;
   r = rados.pool_reverse_lookup(pool_id, &pool_name);
@@ -126,18 +131,27 @@ int JournalTool::main(std::vector<const char*> &argv)
 
   // Execution
   // =========
-  dout(4) << "Executing for rank " << rank << dendl;
-  if (mode == std::string("journal")) {
-    return main_journal(argv);
-  } else if (mode == std::string("header")) {
-    return main_header(argv);
-  } else if (mode == std::string("event")) {
-    return main_event(argv);
-  } else {
-    derr << "Bad command '" << mode << "'" << dendl;
-    usage();
-    return -EINVAL;
+  for (auto role : role_selector.get_roles()) {
+    rank = role.rank;
+    dout(4) << "Executing for rank " << rank << dendl;
+    if (mode == std::string("journal")) {
+      r = main_journal(argv);
+    } else if (mode == std::string("header")) {
+      r = main_header(argv);
+    } else if (mode == std::string("event")) {
+      r = main_event(argv);
+    } else {
+      derr << "Bad command '" << mode << "'" << dendl;
+      usage();
+      return -EINVAL;
+    }
+
+    if (r != 0) {
+      return r;
+    }
   }
+
+  return r;
 }
 
 
@@ -528,7 +542,7 @@ int JournalTool::journal_export(std::string const &path, bool import)
    */
   {
     Dumper dumper;
-    r = dumper.init(rank);
+    r = dumper.init(mds_role_t(role_selector.get_ns(), rank));
     if (r < 0) {
       derr << "dumper::init failed: " << cpp_strerror(r) << dendl;
       return r;
@@ -558,15 +572,10 @@ int JournalTool::journal_reset(bool hard)
     return r;
   }
 
-  if (mdsmap->is_dne(mds_rank_t(rank))) {
-    std::cerr << "MDS rank " << rank << " does not exist" << std::endl;
-    return -ENOENT;
-  }
-
   if (hard) {
-    r = resetter.reset_hard(rank);
+    r = resetter.reset_hard(mds_role_t(role_selector.get_ns(), rank));
   } else {
-    r = resetter.reset(rank);
+    r = resetter.reset(mds_role_t(role_selector.get_ns(), rank));
   }
   resetter.shutdown();
 
@@ -960,7 +969,7 @@ int JournalTool::replay_offline(EMetaBlob const &metablob, bool const dry_run)
     inode_bl.clear();
     std::string magic = CEPH_FS_ONDISK_MAGIC;
     ::encode(magic, inode_bl);
-    inode.encode(inode_bl);
+    inode.encode(inode_bl, CEPH_FEATURES_SUPPORTED_DEFAULT);
 
     if (!dry_run) {
       r = io.write_full(root_oid.name, inode_bl);
@@ -1043,7 +1052,7 @@ int JournalTool::replay_offline(EMetaBlob const &metablob, bool const dry_run)
       inode.snap_blob = fb.snapbl;
       inode.symlink = fb.symlink;
       inode.old_inodes = fb.old_inodes;
-      inode.encode_bare(dentry_bl);
+      inode.encode_bare(dentry_bl, CEPH_FEATURES_SUPPORTED_DEFAULT);
       
       vals[key] = dentry_bl;
       if (!dry_run) {
@@ -1095,7 +1104,7 @@ int JournalTool::erase_region(JournalScanner const &js, uint64_t const pos, uint
   // is needed inside the ENoOp to make up the difference.
   bufferlist tmp;
   ENoOp enoop(0);
-  enoop.encode_with_header(tmp);
+  enoop.encode_with_header(tmp, CEPH_FEATURES_SUPPORTED_DEFAULT);
 
   dout(4) << "erase_region " << pos << " len=" << length << dendl;
 
@@ -1111,7 +1120,7 @@ int JournalTool::erase_region(JournalScanner const &js, uint64_t const pos, uint
   // Serialize an ENoOp with the correct amount of padding
   enoop = ENoOp(padding);
   bufferlist entry;
-  enoop.encode_with_header(entry);
+  enoop.encode_with_header(entry, CEPH_FEATURES_SUPPORTED_DEFAULT);
   JournalStream stream(JOURNAL_FORMAT_RESILIENT);
 
   // Serialize region of log stream
@@ -1126,7 +1135,7 @@ int JournalTool::erase_region(JournalScanner const &js, uint64_t const pos, uint
   uint32_t object_size = g_conf->mds_log_segment_size;
   if (object_size == 0) {
     // Default layout object size
-    object_size = g_default_file_layout.fl_object_size;
+    object_size = file_layout_t::get_default().object_size;
   }
 
   uint64_t write_offset = pos;
@@ -1184,9 +1193,9 @@ void JournalTool::encode_fullbit_as_inode(
 
   // Serialize InodeStore
   if (bare) {
-    new_inode.encode_bare(*out_bl);
+    new_inode.encode_bare(*out_bl, CEPH_FEATURES_SUPPORTED_DEFAULT);
   } else {
-    new_inode.encode(*out_bl);
+    new_inode.encode(*out_bl, CEPH_FEATURES_SUPPORTED_DEFAULT);
   }
 }
 
@@ -1209,8 +1218,9 @@ int JournalTool::consume_inos(const std::set<inodeno_t> &inos)
   int r = 0;
 
   // InoTable is a per-MDS structure, so iterate over assigned ranks
+  auto fs = fsmap->get_filesystem(role_selector.get_ns());
   std::set<mds_rank_t> in_ranks;
-  mdsmap->get_mds_set(in_ranks);
+  fs->mds_map.get_mds_set(in_ranks);
 
   for (std::set<mds_rank_t>::iterator rank_i = in_ranks.begin();
       rank_i != in_ranks.end(); ++rank_i)
diff --git a/src/tools/cephfs/JournalTool.h b/src/tools/cephfs/JournalTool.h
index f717859..f8f9060 100644
--- a/src/tools/cephfs/JournalTool.h
+++ b/src/tools/cephfs/JournalTool.h
@@ -12,6 +12,7 @@
  */
 
 #include "MDSUtility.h"
+#include "RoleSelector.h"
 #include <vector>
 
 #include "mds/mdstypes.h"
@@ -32,7 +33,10 @@ class JournalScanner;
 class JournalTool : public MDSUtility
 {
   private:
-    int rank;
+    MDSRoleSelector role_selector;
+    // Bit hacky, use this `rank` member to control behaviour of the
+    // various main_ functions.
+    mds_rank_t rank;
 
     // Entry points
     int main_journal(std::vector<const char*> &argv);
diff --git a/src/tools/cephfs/MDSUtility.cc b/src/tools/cephfs/MDSUtility.cc
index d335d92..b6b9eab 100644
--- a/src/tools/cephfs/MDSUtility.cc
+++ b/src/tools/cephfs/MDSUtility.cc
@@ -27,7 +27,7 @@ MDSUtility::MDSUtility() :
 {
   monc = new MonClient(g_ceph_context);
   messenger = Messenger::create_client_messenger(g_ceph_context, "mds");
-  mdsmap = new MDSMap();
+  fsmap = new FSMap();
   objecter = new Objecter(g_ceph_context, messenger, monc, NULL, 0, 0);
 }
 
@@ -37,7 +37,7 @@ MDSUtility::~MDSUtility()
   delete objecter;
   delete monc;
   delete messenger;
-  delete mdsmap;
+  delete fsmap;
   assert(waiting_for_mds_map == NULL);
 }
 
@@ -91,11 +91,11 @@ int MDSUtility::init()
   Mutex init_lock("MDSUtility:init");
   Cond cond;
   bool done = false;
-  assert(!mdsmap->get_epoch());
+  assert(!fsmap->get_epoch());
   lock.Lock();
   waiting_for_mds_map = new C_SafeCond(&init_lock, &cond, &done, NULL);
   lock.Unlock();
-  monc->sub_want("mdsmap", 0, CEPH_SUBSCRIBE_ONETIME);
+  monc->sub_want("fsmap", 0, CEPH_SUBSCRIBE_ONETIME);
   monc->renew_subs();
 
   // Wait for MDS map
@@ -104,7 +104,7 @@ int MDSUtility::init()
   while (!done)
     cond.Wait(init_lock);
   init_lock.Unlock();
-  dout(4) << "Got MDS map " << mdsmap->get_epoch() << dendl;
+  dout(4) << "Got MDS map " << fsmap->get_epoch() << dendl;
 
   finisher.start();
 
@@ -130,8 +130,8 @@ bool MDSUtility::ms_dispatch(Message *m)
 {
    Mutex::Locker locker(lock);
    switch (m->get_type()) {
-   case CEPH_MSG_MDS_MAP:
-     handle_mds_map((MMDSMap*)m);
+   case CEPH_MSG_FS_MAP:
+     handle_mds_map((MFSMap*)m);
      break;
    case CEPH_MSG_OSD_MAP:
      break;
@@ -142,9 +142,9 @@ bool MDSUtility::ms_dispatch(Message *m)
 }
 
 
-void MDSUtility::handle_mds_map(MMDSMap* m)
+void MDSUtility::handle_mds_map(MFSMap* m)
 {
-  mdsmap->decode(m->get_encoded());
+  fsmap->decode(m->get_encoded());
   if (waiting_for_mds_map) {
     waiting_for_mds_map->complete(0);
     waiting_for_mds_map = NULL;
diff --git a/src/tools/cephfs/MDSUtility.h b/src/tools/cephfs/MDSUtility.h
index 4034043..4d233c9 100644
--- a/src/tools/cephfs/MDSUtility.h
+++ b/src/tools/cephfs/MDSUtility.h
@@ -15,8 +15,8 @@
 #define MDS_UTILITY_H_
 
 #include "osdc/Objecter.h"
-#include "mds/MDSMap.h"
-#include "messages/MMDSMap.h"
+#include "mds/FSMap.h"
+#include "messages/MFSMap.h"
 #include "msg/Dispatcher.h"
 #include "msg/Messenger.h"
 #include "auth/Auth.h"
@@ -32,7 +32,7 @@
 class MDSUtility : public Dispatcher {
 protected:
   Objecter *objecter;
-  MDSMap *mdsmap;
+  FSMap *fsmap;
   Messenger *messenger;
   MonClient *monc;
 
@@ -46,7 +46,7 @@ public:
   MDSUtility();
   ~MDSUtility();
 
-  void handle_mds_map(MMDSMap* m);
+  void handle_mds_map(MFSMap* m);
   bool ms_dispatch(Message *m);
   bool ms_handle_reset(Connection *con) { return false; }
   void ms_handle_remote_reset(Connection *con) {}
diff --git a/src/tools/cephfs/Resetter.cc b/src/tools/cephfs/Resetter.cc
index 6beaf98..f1102f3 100644
--- a/src/tools/cephfs/Resetter.cc
+++ b/src/tools/cephfs/Resetter.cc
@@ -25,14 +25,18 @@
 
 #define dout_subsys ceph_subsys_mds
 
-int Resetter::reset(int rank)
+int Resetter::reset(mds_role_t role)
 {
   Mutex mylock("Resetter::reset::lock");
   Cond cond;
   bool done;
   int r;
 
-  JournalPointer jp(rank, mdsmap->get_metadata_pool());
+  auto fs =  fsmap->get_filesystem(role.fscid);
+  assert(fs != nullptr);
+  int const pool_id = fs->mds_map.get_metadata_pool();
+
+  JournalPointer jp(role.rank, pool_id);
   int jp_load_result = jp.load(objecter);
   if (jp_load_result != 0) {
     std::cerr << "Error loading journal: " << cpp_strerror(jp_load_result) <<
@@ -41,7 +45,7 @@ int Resetter::reset(int rank)
   }
 
   Journaler journaler(jp.front,
-      mdsmap->get_metadata_pool(),
+      pool_id,
       CEPH_FS_ONDISK_MAGIC,
       objecter, 0, 0, &timer, &finisher);
 
@@ -109,10 +113,14 @@ int Resetter::reset(int rank)
   return 0;
 }
 
-int Resetter::reset_hard(int rank)
+int Resetter::reset_hard(mds_role_t role)
 {
-  JournalPointer jp(rank, mdsmap->get_metadata_pool());
-  jp.front = rank + MDS_INO_LOG_OFFSET;
+  auto fs =  fsmap->get_filesystem(role.fscid);
+  assert(fs != nullptr);
+  int const pool_id = fs->mds_map.get_metadata_pool();
+
+  JournalPointer jp(role.rank, pool_id);
+  jp.front = role.rank + MDS_INO_LOG_OFFSET;
   jp.back = 0;
   int r = jp.save(objecter);
   if (r != 0) {
@@ -121,12 +129,13 @@ int Resetter::reset_hard(int rank)
   }
 
   Journaler journaler(jp.front,
-    mdsmap->get_metadata_pool(),
+    pool_id,
     CEPH_FS_ONDISK_MAGIC,
     objecter, 0, 0, &timer, &finisher);
   journaler.set_writeable();
 
-  ceph_file_layout default_log_layout = MDCache::gen_default_log_layout(*mdsmap);
+  file_layout_t default_log_layout = MDCache::gen_default_log_layout(
+      fsmap->get_filesystem(role.fscid)->mds_map);
   journaler.create(&default_log_layout, g_conf->mds_journal_format);
 
   C_SaferCond cond;
@@ -150,7 +159,7 @@ int Resetter::reset_hard(int rank)
   }
 
   dout(4) << "Successfully wrote new journal pointer and header for rank "
-    << rank << dendl;
+    << role << dendl;
   return 0;
 }
 
@@ -161,7 +170,7 @@ int Resetter::_write_reset_event(Journaler *journaler)
   LogEvent *le = new EResetJournal;
 
   bufferlist bl;
-  le->encode_with_header(bl);
+  le->encode_with_header(bl, CEPH_FEATURES_SUPPORTED_DEFAULT);
   
   cout << "writing EResetJournal entry" << std::endl;
   C_SaferCond cond;
diff --git a/src/tools/cephfs/Resetter.h b/src/tools/cephfs/Resetter.h
index 2baaf47..115f6ff 100644
--- a/src/tools/cephfs/Resetter.h
+++ b/src/tools/cephfs/Resetter.h
@@ -36,8 +36,8 @@ public:
    * For use when no journal header/pointer was present: write one
    * out from scratch.
    */
-  int reset_hard(int rank);
-  int reset(int rank);
+  int reset_hard(mds_role_t role);
+  int reset(mds_role_t role);
 };
 
 #endif /* JOURNAL_RESETTER_H_ */
diff --git a/src/tools/cephfs/RoleSelector.cc b/src/tools/cephfs/RoleSelector.cc
new file mode 100644
index 0000000..d51f011
--- /dev/null
+++ b/src/tools/cephfs/RoleSelector.cc
@@ -0,0 +1,58 @@
+
+#include "RoleSelector.h"
+
+int MDSRoleSelector::parse_rank(
+    const FSMap &fsmap,
+    std::string const &str)
+{
+  if (str == "all" || str == "*") {
+    std::set<mds_rank_t> in;
+    const MDSMap &mds_map = fsmap.get_filesystem(fscid)->mds_map;
+    mds_map.get_mds_set(in);
+
+    for (auto rank : in) {
+      roles.push_back(mds_role_t(fscid, rank));
+    }
+
+    return 0;
+  } else {
+    std::string rank_err;
+    mds_rank_t rank = strict_strtol(str.c_str(), 10, &rank_err);
+    if (!rank_err.empty()) {
+      return -EINVAL;
+    }
+    if (fsmap.get_filesystem(fscid)->mds_map.is_dne(rank)) {
+      return -ENOENT;
+    }
+    roles.push_back(mds_role_t(fscid, rank));
+    return 0;
+  }
+}
+
+int MDSRoleSelector::parse(const FSMap &fsmap, std::string const &str)
+{
+  auto colon_pos = str.find(":");
+  if (colon_pos == std::string::npos) {
+    // An unqualified rank.  Only valid if there is only one
+    // namespace.
+    if (fsmap.get_filesystems().size() == 1) {
+      fscid = fsmap.get_filesystems().begin()->first;
+      return parse_rank(fsmap, str);
+    } else {
+      return -EINVAL;
+    }
+  } else if (colon_pos == 0 || colon_pos == str.size() - 1) {
+    return -EINVAL;
+  } else {
+    const std::string ns_str = str.substr(0, colon_pos);
+    const std::string rank_str = str.substr(colon_pos + 1);
+    std::shared_ptr<const Filesystem> fs_ptr;
+    int r = fsmap.parse_filesystem(ns_str, &fs_ptr);
+    if (r != 0) {
+      return r;
+    }
+    fscid = fs_ptr->fscid;
+    return parse_rank(fsmap, rank_str);
+  }
+}
+
diff --git a/src/tools/cephfs/RoleSelector.h b/src/tools/cephfs/RoleSelector.h
new file mode 100644
index 0000000..933c51d
--- /dev/null
+++ b/src/tools/cephfs/RoleSelector.h
@@ -0,0 +1,35 @@
+
+#ifndef ROLE_SELECTOR_H_
+#define ROLE_SELECTOR_H_
+
+#include <string>
+#include <vector>
+#include "mds/mdstypes.h"
+#include "mds/FSMap.h"
+
+/**
+ * When you want to let the user act on a single rank in a namespace,
+ * or all of them.
+ */
+class MDSRoleSelector
+{
+  public:
+    const std::vector<mds_role_t> &get_roles() const {return roles;}
+    int parse(const FSMap &fsmap, std::string const &str);
+    MDSRoleSelector()
+      : fscid(FS_CLUSTER_ID_NONE)
+    {}
+    fs_cluster_id_t get_ns() const
+    {
+      return fscid;
+    }
+  protected:
+    int parse_rank(
+        const FSMap &fsmap,
+        std::string const &str);
+    std::vector<mds_role_t> roles;
+    fs_cluster_id_t fscid;
+};
+
+#endif // ROLE_SELECTOR_H_
+
diff --git a/src/tools/cephfs/TableTool.cc b/src/tools/cephfs/TableTool.cc
index 2d14a4f..2ff020a 100644
--- a/src/tools/cephfs/TableTool.cc
+++ b/src/tools/cephfs/TableTool.cc
@@ -38,38 +38,32 @@ void TableTool::usage()
 
 
 /**
- * For a function that takes an MDS rank as an argument and
- * returns an error code, execute it either on all ranks (if
- * this->rank is MDS_RANK_NONE), or on the rank specified
- * by this->rank.
+ * For a function that takes an MDS role as an argument and
+ * returns an error code, execute it on the roles specified
+ * by `role_selector`.
  */
-int TableTool::apply_rank_fn(std::function<int(mds_rank_t, Formatter *)> fptr, Formatter *f)
+int TableTool::apply_role_fn(std::function<int(mds_role_t, Formatter *)> fptr, Formatter *f)
 {
   assert(f != NULL);
 
   int r = 0;
-  std::set<mds_rank_t> apply_to_ranks;
-  if (rank == MDS_RANK_NONE) {
-    mdsmap->get_mds_set(apply_to_ranks);
-  } else {
-    apply_to_ranks.insert(rank);
-  }
 
   f->open_object_section("ranks");
 
-  for (std::set<mds_rank_t>::iterator rank_i = apply_to_ranks.begin();
-      rank_i != apply_to_ranks.end(); ++rank_i) {
+  for (auto role : role_selector.get_roles()) {
     std::ostringstream rank_str;
-    rank_str << *rank_i;
+    rank_str << role.rank;
     f->open_object_section(rank_str.str().c_str());
 
     f->open_object_section("data");
-    int rank_r = fptr(*rank_i, f);
+    int rank_r = fptr(role, f);
     f->close_section();
     r = r ? r : rank_r;
 
     f->dump_int("result", rank_r);
     f->close_section();
+
+    
   }
 
   f->close_section();
@@ -90,21 +84,21 @@ protected:
   // The RADOS object ID for the table
   std::string object_name;
 
-  // The rank in question (may be NONE)
-  mds_rank_t rank;
+  // The role in question (may be NONE)
+  mds_role_t role;
 
   // Whether this is an MDSTable subclass (i.e. has leading version field to decode)
   bool mds_table;
 
 public:
-  TableHandler(mds_rank_t r, std::string const &name, bool mds_table_)
-    : rank(r), mds_table(mds_table_)
+  TableHandler(mds_role_t r, std::string const &name, bool mds_table_)
+    : role(r), mds_table(mds_table_)
   {
     // Compose object name of the table we will dump
     std::ostringstream oss;
     oss << "mds";
-    if (rank != MDS_RANK_NONE) {
-      oss << rank;
+    if (!role.is_none()) {
+      oss << role.rank;
     }
     oss << "_" << name;
     object_name = oss.str();
@@ -127,7 +121,7 @@ public:
           f->dump_int("version", version);
         }
         A table_inst;
-        table_inst.set_rank(rank);
+        table_inst.set_rank(role.rank);
         table_inst.decode(q);
         table_inst.dump(f);
 
@@ -147,7 +141,7 @@ public:
   {
     A table_inst;
     // Compose new (blank) table
-    table_inst.set_rank(rank);
+    table_inst.set_rank(role.rank);
     table_inst.reset_state();
     // Write the table out
     return write(table_inst, io);
@@ -183,21 +177,21 @@ private:
   // The RADOS object ID for the table
   std::string object_name;
 
-  // The rank in question (may be NONE)
-  mds_rank_t rank;
+  // The role (rank may be NONE)
+  mds_role_t role;
 
   // Whether this is an MDSTable subclass (i.e. has leading version field to decode)
   bool mds_table;
 
 public:
-  TableHandlerOmap(mds_rank_t r, std::string const &name, bool mds_table_)
-    : rank(r), mds_table(mds_table_)
+  TableHandlerOmap(mds_role_t r, std::string const &name, bool mds_table_)
+    : role(r), mds_table(mds_table_)
   {
     // Compose object name of the table we will dump
     std::ostringstream oss;
     oss << "mds";
-    if (rank != MDS_RANK_NONE) {
-      oss << rank;
+    if (!role.is_none()) {
+      oss << role.rank;
     }
     oss << "_" << name;
     object_name = oss.str();
@@ -212,13 +206,14 @@ public:
     bufferlist header_bl;
     int r = io->omap_get_header(object_name, &header_bl);
     if (r != 0) {
-      derr << "error reading header: " << cpp_strerror(r) << dendl;
+      derr << "error reading header on '" << object_name << "': "
+           << cpp_strerror(r) << dendl;
       return r;
     }
 
     // Decode the header
     A table_inst;
-    table_inst.set_rank(rank);
+    table_inst.set_rank(role.rank);
     try {
       table_inst.decode_header(header_bl);
     } catch (buffer::error &e) {
@@ -259,7 +254,7 @@ public:
   int reset(librados::IoCtx *io)
   {
     A table_inst;
-    table_inst.set_rank(rank);
+    table_inst.set_rank(role.rank);
     table_inst.reset_state();
     bufferlist header_bl;
     table_inst.encode_header(&header_bl);
@@ -277,14 +272,14 @@ public:
 class InoTableHandler : public TableHandler<InoTable>
 {
   public:
-  explicit InoTableHandler(mds_rank_t r)
+  explicit InoTableHandler(mds_role_t r)
     : TableHandler(r, "inotable", true)
   {}
 
   int take_inos(librados::IoCtx *io, inodeno_t max, Formatter *f)
   {
     InoTable inst;
-    inst.set_rank(rank);
+    inst.set_rank(role.rank);
     inst.reset_state();
 
     int r = 0;
@@ -317,18 +312,7 @@ int TableTool::main(std::vector<const char*> &argv)
   dout(4) << "connecting to RADOS..." << dendl;
   rados.connect();
  
-  int const pool_id = mdsmap->get_metadata_pool();
-  dout(4) << "resolving pool " << pool_id << dendl;
-  std::string pool_name;
-  r = rados.pool_reverse_lookup(pool_id, &pool_name);
-  if (r < 0) {
-    derr << "Pool " << pool_id << " identified in MDS map not found in RADOS!" << dendl;
-    return r;
-  }
 
-  dout(4) << "creating IoCtx.." << dendl;
-  r = rados.ioctx_create(pool_name.c_str(), io);
-  assert(r == 0);
 
   // Require at least 3 args <rank> <mode> <arg> [args...]
   if (argv.size() < 3) {
@@ -336,33 +320,47 @@ int TableTool::main(std::vector<const char*> &argv)
     return -EINVAL;
   }
 
-  const std::string rank_str = std::string(argv[0]);
+  const std::string role_str = std::string(argv[0]);
   const std::string mode = std::string(argv[1]);
+  const std::string table = std::string(argv[2]);
 
-  if (rank_str == "all") {
-    rank = MDS_RANK_NONE;
-  } else {
-    std::string rank_err;
-    rank = strict_strtol(rank_str.c_str(), 10, &rank_err);
-    if (!rank_err.empty()) {
-      derr << "Bad rank '" << rank_str << "'" << dendl;
-      usage();
-    }
+  r = role_selector.parse(*fsmap, role_str);
+  if (r < 0) {
+    derr << "Bad rank selection: " << role_str << "'" << dendl;
+    return r;
+  }
+
+  auto fs =  fsmap->get_filesystem(role_selector.get_ns());
+  assert(fs != nullptr);
+  int const pool_id = fs->mds_map.get_metadata_pool();
+  dout(4) << "resolving pool " << pool_id << dendl;
+  std::string pool_name;
+  r = rados.pool_reverse_lookup(pool_id, &pool_name);
+  if (r < 0) {
+    derr << "Pool " << pool_id << " identified in MDS map not found in RADOS!"
+         << dendl;
+    return r;
+  }
+
+  dout(4) << "creating IoCtx.." << dendl;
+  r = rados.ioctx_create(pool_name.c_str(), io);
+  if (r != 0) {
+    return r;
   }
 
   JSONFormatter jf(true);
   if (mode == "reset") {
     const std::string table = std::string(argv[2]);
     if (table == "session") {
-      r = apply_rank_fn([this](mds_rank_t rank, Formatter *f) -> int {
+      r = apply_role_fn([this](mds_role_t rank, Formatter *f) -> int {
             return TableHandlerOmap<SessionMapStore>(rank, "sessionmap", false).reset(&io);
       }, &jf);
     } else if (table == "inode") {
-      r = apply_rank_fn([this](mds_rank_t rank, Formatter *f) -> int {
+      r = apply_role_fn([this](mds_role_t rank, Formatter *f) -> int {
             return TableHandler<InoTable>(rank, "inotable", true).reset(&io);
       }, &jf);
     } else if (table == "snap") {
-      r = TableHandler<SnapServer>(MDS_RANK_NONE, "snaptable", true).reset(&io);
+      r = TableHandler<SnapServer>(mds_role_t(), "snaptable", true).reset(&io);
       jf.open_object_section("reset_snap_status");
       jf.dump_int("result", r);
       jf.close_section();
@@ -375,18 +373,18 @@ int TableTool::main(std::vector<const char*> &argv)
   } else if (mode == "show") {
     const std::string table = std::string(argv[2]);
     if (table == "session") {
-      r = apply_rank_fn([this](mds_rank_t rank, Formatter *f) -> int {
+      r = apply_role_fn([this](mds_role_t rank, Formatter *f) -> int {
         return TableHandlerOmap<SessionMapStore>(rank, "sessionmap", false).load_and_dump(&io, f);
       }, &jf);
     } else if (table == "inode") {
-      r = apply_rank_fn([this](mds_rank_t rank, Formatter *f) -> int {
+      r = apply_role_fn([this](mds_role_t rank, Formatter *f) -> int {
         return TableHandler<InoTable>(rank, "inotable", true).load_and_dump(&io, f);;
       }, &jf);
     } else if (table == "snap") {
       jf.open_object_section("show_snap_table");
       {
         r = TableHandler<SnapServer>(
-            MDS_RANK_NONE, "snaptable", true).load_and_dump(&io, &jf);
+            mds_role_t(), "snaptable", true).load_and_dump(&io, &jf);
         jf.dump_int("result", r);
       }
       jf.close_section();
@@ -403,7 +401,7 @@ int TableTool::main(std::vector<const char*> &argv)
       derr << "Bad ino '" << ino_str << "'" << dendl;
       return -EINVAL;
     }
-    r = apply_rank_fn([this, ino](mds_rank_t rank, Formatter *f) -> int {
+    r = apply_role_fn([this, ino](mds_role_t rank, Formatter *f) -> int {
       return InoTableHandler(rank).take_inos(&io, ino, f);
     }, &jf);
   } else {
diff --git a/src/tools/cephfs/TableTool.h b/src/tools/cephfs/TableTool.h
index 57705ef..bcd3167 100644
--- a/src/tools/cephfs/TableTool.h
+++ b/src/tools/cephfs/TableTool.h
@@ -13,10 +13,10 @@
 
 
 #include "MDSUtility.h"
+#include "RoleSelector.h"
 
 #include "include/rados/librados.hpp"
 
-
 /**
  * Command line tool for debugging the backing store of
  * MDSTable instances.
@@ -24,18 +24,17 @@
 class TableTool : public MDSUtility
 {
   private:
-    mds_rank_t rank;
+    MDSRoleSelector role_selector;
 
     // I/O handles
     librados::Rados rados;
     librados::IoCtx io;
 
-    int apply_rank_fn(std::function<int(mds_rank_t, Formatter *)> fptr, Formatter *f);
+    int apply_role_fn(std::function<int(mds_role_t, Formatter *)> fptr, Formatter *f);
 
   public:
     void usage();
-    TableTool() :
-      rank(MDS_RANK_NONE) {}
     int main(std::vector<const char*> &argv);
 
 };
+
diff --git a/src/tools/psim.cc b/src/tools/psim.cc
index 04a1987..90e6fb9 100644
--- a/src/tools/psim.cc
+++ b/src/tools/psim.cc
@@ -57,7 +57,6 @@ int main(int argc, char **argv)
       snprintf(foo, sizeof(foo), "%d.%d", f, b);
       object_t oid(foo);
       ceph_object_layout l = osdmap.make_object_layout(oid, 0, nspace);
-	//osdmap.file_to_object_layout(oid, g_default_file_layout);
       vector<int> osds;
       pg_t pgid = pg_t(l.ol_pgid);
       //pgid.u.ps = f * 4 + b;
diff --git a/src/tools/rados/rados.cc b/src/tools/rados/rados.cc
index fb4967f..d3b37ab 100644
--- a/src/tools/rados/rados.cc
+++ b/src/tools/rados/rados.cc
@@ -143,6 +143,11 @@ void usage(ostream& out)
 "       --lock-duration              Lock duration (in seconds)\n"
 "       --lock-type                  Lock type (shared, exclusive)\n"
 "\n"
+"SCRUB AND REPAIR:\n"
+"   list-inconsistent-pg <pool>      list inconsistent PGs in given pool\n"
+"   list-inconsistent-obj <pgid>     list inconsistent objects in given pg\n"
+"   list-inconsistent-snapset <pgid> list inconsistent snapsets in the given pg\n"
+"\n"
 "CACHE POOLS: (for testing/development only)\n"
 "   cache-flush <obj-name>           flush cache pool object (blocking)\n"
 "   cache-try-flush <obj-name>       flush cache pool object (non-blocking)\n"
@@ -424,7 +429,7 @@ static int do_put(IoCtx& io_ctx, RadosStriper& striper,
       }
       continue;
     }
-    indata.append(buf, count);
+    indata.append(buffer::ptr(buffer::create_static(count, buf)));
     if (use_striper) {
       if (offset == 0)
 	ret = striper.write_full(oid, indata);
@@ -1210,6 +1215,218 @@ static int do_cache_flush_evict_all(IoCtx& io_ctx, bool blocking)
   return errors ? -1 : 0;
 }
 
+static int do_get_inconsistent_pg_cmd(const std::vector<const char*> &nargs,
+				      Rados& rados,
+				      Formatter& formatter)
+{
+  if (nargs.size() < 2) {
+    usage_exit();
+  }
+  int64_t pool_id = rados.pool_lookup(nargs[1]);
+  if (pool_id < 0) {
+    cerr << "pool \"" << nargs[1] << "\" not found" << std::endl;
+    return (int)pool_id;
+  }
+  std::vector<PlacementGroup> pgs;
+  int ret = rados.get_inconsistent_pgs(pool_id, &pgs);
+  if (ret) {
+    return ret;
+  }
+  formatter.open_array_section("pgs");
+  for (auto& pg : pgs) {
+    formatter.dump_stream("pg") << pg;
+  }
+  formatter.close_section();
+  formatter.flush(cout);
+  cout << std::endl;
+  return 0;
+}
+
+static void dump_shard(const shard_info_t& shard,
+		       const inconsistent_obj_t& inc,
+		       Formatter &f)
+{
+  f.dump_bool("missing", shard.has_shard_missing());
+  if (shard.has_shard_missing()) {
+    return;
+  }
+  f.dump_bool("read_error", shard.has_read_error());
+  f.dump_bool("data_digest_mismatch", shard.has_data_digest_mismatch());
+  f.dump_bool("omap_digest_mismatch", shard.has_omap_digest_mismatch());
+  f.dump_bool("size_mismatch", shard.has_size_mismatch());
+  if (!shard.has_read_error()) {
+    f.dump_bool("data_digest_mismatch_oi", shard.has_data_digest_mismatch_oi());
+    f.dump_bool("omap_digest_mismatch_oi", shard.has_omap_digest_mismatch_oi());
+    f.dump_bool("size_mismatch_oi", shard.has_size_mismatch_oi());
+  }
+  f.dump_unsigned("size", shard.size);
+  if (shard.omap_digest_present) {
+    f.dump_format("omap_digest", "0x%08x", shard.omap_digest);
+  }
+  if (shard.data_digest_present) {
+    f.dump_format("data_digest", "0x%08x", shard.data_digest);
+  }
+  if (inc.has_attr_mismatch()) {
+    f.open_object_section("attrs");
+    for (auto kv : shard.attrs) {
+      f.open_object_section("attr");
+      f.dump_string("name", kv.first);
+      bufferlist b64;
+      kv.second.encode_base64(b64);
+      string v(b64.c_str(), b64.length());
+      f.dump_string("value", v);
+      f.close_section();
+    }
+    f.close_section();
+  }
+}
+
+static void dump_object_id(const object_id_t& object,
+			Formatter &f)
+{
+  f.dump_string("name", object.name);
+  f.dump_string("nspace", object.nspace);
+  f.dump_string("locator", object.locator);
+  switch (object.snap) {
+  case CEPH_NOSNAP:
+    f.dump_string("snap", "head");
+    break;
+  case CEPH_SNAPDIR:
+    f.dump_string("snap", "snapdir");
+    break;
+  default:
+    f.dump_format("snap", "0x%08x", object.snap);
+    break;
+  }
+}
+
+static void dump_inconsistent(const inconsistent_obj_t& inc,
+			      Formatter &f)
+{
+  f.open_object_section("object");
+  dump_object_id(inc.object, f);
+  f.close_section();
+  f.dump_bool("missing", inc.has_shard_missing());
+  f.dump_bool("stat_err", inc.has_stat_error());
+  f.dump_bool("read_err", inc.has_read_error());
+  f.dump_bool("data_digest_mismatch", inc.has_data_digest_mismatch());
+  f.dump_bool("omap_digest_mismatch", inc.has_omap_digest_mismatch());
+  f.dump_bool("size_mismatch", inc.has_size_mismatch());
+  f.dump_bool("attr_mismatch", inc.has_attr_mismatch());
+  f.open_array_section("shards");
+  for (auto osd_shard : inc.shards) {
+    f.open_object_section("shard");
+    f.dump_int("osd", osd_shard.first);
+    dump_shard(osd_shard.second, inc, f);
+    f.close_section();
+  }
+  f.close_section();
+  f.close_section();
+}
+
+static void dump_inconsistent(const inconsistent_snapset_t& inc,
+			      Formatter &f)
+{
+  dump_object_id(inc.object, f);
+  f.dump_bool("ss_attr_missing", inc.ss_attr_missing());
+  f.dump_bool("ss_attr_corrupted", inc.ss_attr_corrupted());
+  f.dump_bool("clone_missing", inc.clone_missing());
+  f.dump_bool("snapset_mismatch", inc.snapset_mismatch());
+  f.dump_bool("head_mismatch", inc.head_mismatch());
+  f.dump_bool("headless", inc.headless());
+  f.dump_bool("size_mismatch", inc.size_mismatch());
+
+  if (inc.clone_missing()) {
+    f.open_array_section("clones");
+    for (auto snap : inc.clones) {
+      f.dump_unsigned("snap", snap);
+    }
+    f.close_section();
+
+    f.open_array_section("missing");
+    for (auto snap : inc.missing) {
+      f.dump_unsigned("snap", snap);
+    }
+    f.close_section();
+  }
+  f.close_section();
+}
+
+// dispatch the call by type
+static int do_get_inconsistent(Rados& rados,
+			       const PlacementGroup& pg,
+			       const librados::object_id_t &start,
+			       unsigned max_return,
+			       AioCompletion *c,
+			       std::vector<inconsistent_obj_t>* objs,
+			       uint32_t* interval)
+{
+  return rados.get_inconsistent_objects(pg, start, max_return, c,
+					objs, interval);
+}
+
+static int do_get_inconsistent(Rados& rados,
+			       const PlacementGroup& pg,
+			       const librados::object_id_t &start,
+			       unsigned max_return,
+			       AioCompletion *c,
+			       std::vector<inconsistent_snapset_t>* snapsets,
+			       uint32_t* interval)
+{
+  return rados.get_inconsistent_snapsets(pg, start, max_return, c,
+					 snapsets, interval);
+}
+
+template <typename T>
+static int do_get_inconsistent_cmd(const std::vector<const char*> &nargs,
+				   Rados& rados,
+				   Formatter& formatter)
+{
+  if (nargs.size() < 2) {
+    usage_exit();
+  }
+  PlacementGroup pg;
+  int ret = 0;
+  ret = pg.parse(nargs[1]);
+  if (!ret) {
+    cerr << "bad pg: " << nargs[1] << std::endl;
+    return ret;
+  }
+
+  uint32_t interval = 0;
+  const unsigned max_item_num = 32;
+  for (librados::object_id_t start;;) {
+    std::vector<T> items;
+    auto completion = librados::Rados::aio_create_completion();
+    ret = do_get_inconsistent(rados, pg, start, max_item_num, completion,
+			      &items, &interval);
+    completion->wait_for_safe();
+    ret = completion->get_return_value();
+    completion->release();
+    if (ret == -EAGAIN) {
+      cerr << "interval#" << interval << " expired." << std::endl;
+      break;
+    }
+    if (start.name.empty()) {
+      formatter.open_array_section("inconsistents");
+    }
+    for (auto& inc : items) {
+      formatter.open_object_section("inconsistent");
+      dump_inconsistent(inc, formatter);
+    }
+    if (items.size() < max_item_num) {
+      formatter.close_section();
+      break;
+    }
+    if (!items.empty()) {
+      start = items.back().object;
+    }
+    items.clear();
+  }
+  formatter.flush(cout);
+  return ret;
+}
+
 /**********************************************
 
 **********************************************/
@@ -1407,11 +1624,8 @@ static int rados_tool_common(const std::map < std::string, std::string > &opts,
   i = opts.find("format");
   if (i != opts.end()) {
     const char *format = i->second.c_str();
-    if (strcmp(format, "xml") == 0)
-      formatter = new XMLFormatter(pretty_format);
-    else if (strcmp(format, "json") == 0)
-      formatter = new JSONFormatter(pretty_format);
-    else {
+    formatter = Formatter::create(format);
+    if (!formatter) {
       cerr << "unrecognized format: " << format << std::endl;
       return -EINVAL;
     }
@@ -2833,7 +3047,21 @@ static int rados_tool_common(const std::map < std::string, std::string > &opts,
     } else {
       cout << std::endl;
     }
-
+  } else if (strcmp(nargs[0], "list-inconsistent-pg") == 0) {
+    if (!formatter) {
+      formatter = new JSONFormatter(pretty_format);
+    }
+    ret = do_get_inconsistent_pg_cmd(nargs, rados, *formatter);
+  } else if (strcmp(nargs[0], "list-inconsistent-obj") == 0) {
+    if (!formatter) {
+      formatter = new JSONFormatter(pretty_format);
+    }
+    ret = do_get_inconsistent_cmd<inconsistent_obj_t>(nargs, rados, *formatter);
+  } else if (strcmp(nargs[0], "list-inconsistent-snapset") == 0) {
+    if (!formatter) {
+      formatter = new JSONFormatter(pretty_format);
+    }
+    ret = do_get_inconsistent_cmd<inconsistent_snapset_t>(nargs, rados, *formatter);
   } else if (strcmp(nargs[0], "cache-flush") == 0) {
     if (!pool_name || nargs.size() < 2)
       usage_exit();
diff --git a/src/tools/rbd/ArgumentTypes.cc b/src/tools/rbd/ArgumentTypes.cc
index 698a643..94355bb 100644
--- a/src/tools/rbd/ArgumentTypes.cc
+++ b/src/tools/rbd/ArgumentTypes.cc
@@ -209,7 +209,8 @@ void add_create_image_options(po::options_description *opt,
   // TODO get default image format from conf
   if (include_format) {
     opt->add_options()
-      (IMAGE_FORMAT.c_str(), po::value<ImageFormat>(), "image format [1 or 2]")
+      (IMAGE_FORMAT.c_str(), po::value<ImageFormat>(),
+       "image format [1 (deprecated) or 2]")
       (IMAGE_NEW_FORMAT.c_str(),
        po::value<ImageNewFormat>()->zero_tokens(),
        "use image format 2\n(deprecated)");
@@ -288,12 +289,14 @@ std::string get_short_features_help(bool append_suffix) {
 
     std::string suffix;
     if (append_suffix) {
-      if ((pair.first & RBD_FEATURES_MUTABLE) != 0) {
-        suffix += "*";
-      }
       if ((pair.first & g_conf->rbd_default_features) != 0) {
         suffix += "+";
       }
+      if ((pair.first & RBD_FEATURES_MUTABLE) != 0) {
+        suffix += "*";
+      } else if ((pair.first & RBD_FEATURES_DISABLE_ONLY) != 0) {
+        suffix += "-";
+      }
       if (!suffix.empty()) {
         suffix = "(" + suffix + ")";
       }
@@ -308,6 +311,7 @@ std::string get_long_features_help() {
   std::ostringstream oss;
   oss << "Image Features:" << std::endl
       << "  (*) supports enabling/disabling on existing images" << std::endl
+      << "  (-) supports disabling-only on existing images" << std::endl
       << "  (+) enabled by default for new images if features not specified"
       << std::endl;
   return oss.str();
diff --git a/src/tools/rbd/Utils.cc b/src/tools/rbd/Utils.cc
index c4fbee4..1b6df94 100644
--- a/src/tools/rbd/Utils.cc
+++ b/src/tools/rbd/Utils.cc
@@ -390,6 +390,9 @@ int get_image_options(const boost::program_options::variables_map &vm,
     } else {
       format = g_conf->rbd_default_format;
     }
+    if (format == 1) {
+      std::cerr << "rbd: image format 1 is deprecated" << std::endl;
+    }
 
     if (features_specified && features != 0) {
       if (format_specified && format == 1) {
@@ -616,5 +619,18 @@ std::string image_id(librbd::Image& image) {
   return string(prefix + strlen(RBD_DATA_PREFIX));
 }
 
+std::string mirror_image_state(rbd_mirror_image_state_t mirror_image_state) {
+  switch (mirror_image_state) {
+    case RBD_MIRROR_IMAGE_DISABLING:
+      return "disabling";
+    case RBD_MIRROR_IMAGE_ENABLED:
+      return "enabled";
+    case RBD_MIRROR_IMAGE_DISABLED:
+      return "disabled";
+    default:
+      return "unknown";
+  }
+}
+
 } // namespace utils
 } // namespace rbd
diff --git a/src/tools/rbd/Utils.h b/src/tools/rbd/Utils.h
index 7caf43d..0cd8a41 100644
--- a/src/tools/rbd/Utils.h
+++ b/src/tools/rbd/Utils.h
@@ -100,6 +100,8 @@ int snap_set(librbd::Image &image, const std::string &snap_name);
 
 std::string image_id(librbd::Image& image);
 
+std::string mirror_image_state(rbd_mirror_image_state_t mirror_image_state);
+
 } // namespace utils
 } // namespace rbd
 
diff --git a/src/tools/rbd/action/Clone.cc b/src/tools/rbd/action/Clone.cc
index df24349..0ac991b 100644
--- a/src/tools/rbd/action/Clone.cc
+++ b/src/tools/rbd/action/Clone.cc
@@ -64,6 +64,7 @@ int execute(const po::variables_map &vm) {
   if (r < 0) {
     return r;
   }
+  opts.set(RBD_IMAGE_OPTION_FORMAT, static_cast<uint64_t>(2));
 
   librados::Rados rados;
   librados::IoCtx io_ctx;
diff --git a/src/tools/rbd/action/Export.cc b/src/tools/rbd/action/Export.cc
index 324a4b3..4fe5957 100644
--- a/src/tools/rbd/action/Export.cc
+++ b/src/tools/rbd/action/Export.cc
@@ -1,6 +1,7 @@
 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
 // vim: ts=8 sw=2 smarttab
 
+#include "include/compat.h"
 #include "tools/rbd/ArgumentTypes.h"
 #include "tools/rbd/Shell.h"
 #include "tools/rbd/Utils.h"
diff --git a/src/tools/rbd/action/ImportDiff.cc b/src/tools/rbd/action/ImportDiff.cc
index 21a817c..fb69c2e 100644
--- a/src/tools/rbd/action/ImportDiff.cc
+++ b/src/tools/rbd/action/ImportDiff.cc
@@ -1,6 +1,7 @@
 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
 // vim: ts=8 sw=2 smarttab
 
+#include "include/compat.h"
 #include "tools/rbd/ArgumentTypes.h"
 #include "tools/rbd/Shell.h"
 #include "tools/rbd/Utils.h"
diff --git a/src/tools/rbd/action/Info.cc b/src/tools/rbd/action/Info.cc
index f3d81ac..beb7b08 100644
--- a/src/tools/rbd/action/Info.cc
+++ b/src/tools/rbd/action/Info.cc
@@ -71,6 +71,7 @@ static int do_show_info(const char *imgname, librbd::Image& image,
   uint8_t old_format;
   uint64_t overlap, features, flags;
   bool snap_protected = false;
+  librbd::mirror_image_info_t mirror_image;
   int r;
 
   r = image.stat(info, sizeof(info));
@@ -100,6 +101,13 @@ static int do_show_info(const char *imgname, librbd::Image& image,
       return r;
   }
 
+  if (features & RBD_FEATURE_JOURNALING) {
+    r = image.mirror_image_get_info(&mirror_image, sizeof(mirror_image));
+    if (r < 0) {
+      return r;
+    }
+  }
+
   char prefix[RBD_MAX_BLOCK_NAME_SIZE + 1];
   strncpy(prefix, info.block_name_prefix, RBD_MAX_BLOCK_NAME_SIZE);
   prefix[RBD_MAX_BLOCK_NAME_SIZE] = '\0';
@@ -179,6 +187,28 @@ static int do_show_info(const char *imgname, librbd::Image& image,
     }
   }
 
+  if (features & RBD_FEATURE_JOURNALING) {
+    if (f) {
+      f->open_object_section("mirroring");
+      f->dump_string("state",
+          utils::mirror_image_state(mirror_image.state));
+      if (mirror_image.state != RBD_MIRROR_IMAGE_DISABLED) {
+        f->dump_string("global_id", mirror_image.global_id);
+        f->dump_bool("primary", mirror_image.primary);
+      }
+      f->close_section();
+    } else {
+      std::cout << "\tmirroring state: "
+                << utils::mirror_image_state(mirror_image.state) << std::endl;
+      if (mirror_image.state != RBD_MIRROR_IMAGE_DISABLED) {
+        std::cout << "\tmirroring global id: " << mirror_image.global_id
+                  << std::endl
+                  << "\tmirroring primary: "
+                  << (mirror_image.primary ? "true" : "false") <<std::endl;
+      }
+    }
+  }
+
   if (f) {
     f->close_section();
     f->flush(std::cout);
diff --git a/src/tools/rbd/action/Journal.cc b/src/tools/rbd/action/Journal.cc
index 2c556a6..2995684 100644
--- a/src/tools/rbd/action/Journal.cc
+++ b/src/tools/rbd/action/Journal.cc
@@ -205,8 +205,8 @@ public:
     return 0;
   }
 
-  int shutdown() {
-    ::journal::Journaler::shutdown();
+  int shut_down() {
+    ::journal::Journaler::shut_down();
 
     int r = unregister_client();
     if (r < 0) {
@@ -250,7 +250,7 @@ public:
       }
     }
 
-    r = m_journaler.shutdown();
+    r = m_journaler.shut_down();
     if (r < 0 && m_r == 0) {
       m_r = r;
     }
@@ -679,7 +679,7 @@ public:
     if (r1 < 0 && r == 0) {
       r = r1;
     }
-    r1 = m_journaler.shutdown();
+    r1 = m_journaler.shut_down();
     if (r1 < 0 && r == 0) {
       r = r1;
     }
diff --git a/src/tools/rbd/action/MergeDiff.cc b/src/tools/rbd/action/MergeDiff.cc
index 7289e11..85627b3 100644
--- a/src/tools/rbd/action/MergeDiff.cc
+++ b/src/tools/rbd/action/MergeDiff.cc
@@ -5,6 +5,7 @@
 #include <sys/types.h>
 #include <unistd.h>
 
+#include "include/compat.h"
 #include "tools/rbd/ArgumentTypes.h"
 #include "tools/rbd/Shell.h"
 #include "tools/rbd/Utils.h"
diff --git a/src/tools/rbd/action/MirrorImage.cc b/src/tools/rbd/action/MirrorImage.cc
new file mode 100644
index 0000000..d3a322c
--- /dev/null
+++ b/src/tools/rbd/action/MirrorImage.cc
@@ -0,0 +1,213 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+/*
+ * Ceph - scalable distributed file system
+ *
+ * Copyright (C) 2016 SUSE LINUX GmbH
+ *
+ * This is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software
+ * Foundation.  See file COPYING.
+ *
+ */
+#include "tools/rbd/ArgumentTypes.h"
+#include "tools/rbd/Shell.h"
+#include "tools/rbd/Utils.h"
+#include "include/stringify.h"
+#include "common/config.h"
+#include "common/errno.h"
+#include "common/Formatter.h"
+#include "common/TextTable.h"
+#include "global/global_context.h"
+#include <iostream>
+#include <boost/program_options.hpp>
+#include <boost/regex.hpp>
+
+namespace rbd {
+namespace action {
+namespace mirror_image {
+
+namespace at = argument_types;
+namespace po = boost::program_options;
+
+
+void get_arguments(po::options_description *positional,
+                           po::options_description *options) {
+  at::add_image_spec_options(positional, options, at::ARGUMENT_MODIFIER_NONE);
+}
+
+void get_arguments_disable(po::options_description *positional,
+                           po::options_description *options) {
+  options->add_options()
+    ("force", po::bool_switch(), "disable even if not primary");
+  at::add_image_spec_options(positional, options, at::ARGUMENT_MODIFIER_NONE);
+}
+
+int execute_enable_disable(const po::variables_map &vm, bool enable,
+                           bool force) {
+  size_t arg_index = 0;
+  std::string pool_name;
+  std::string image_name;
+  std::string snap_name;
+  int r = utils::get_pool_image_snapshot_names(
+      vm, at::ARGUMENT_MODIFIER_NONE, &arg_index, &pool_name, &image_name,
+      &snap_name, utils::SNAPSHOT_PRESENCE_NONE);
+  if (r < 0) {
+    return r;
+  }
+
+  librados::Rados rados;
+  librados::IoCtx io_ctx;
+  librbd::Image image;
+  r = utils::init_and_open_image(pool_name, image_name, "", false,
+                                 &rados, &io_ctx, &image);
+  if (r < 0) {
+    return r;
+  }
+
+  r = enable ? image.mirror_image_enable() : image.mirror_image_disable(force);
+  if (r < 0) {
+    return r;
+  }
+
+  std::cout << (enable ? "Mirroring enabled" : "Mirroring disabled")
+    << std::endl;
+
+  return 0;
+}
+
+int execute_disable(const po::variables_map &vm) {
+  return execute_enable_disable(vm, false, vm["force"].as<bool>());
+}
+
+int execute_enable(const po::variables_map &vm) {
+  return execute_enable_disable(vm, true, false);
+}
+
+void get_arguments_promote(po::options_description *positional,
+                           po::options_description *options) {
+  options->add_options()
+    ("force", po::bool_switch(), "promote even if not cleanly demoted by remote cluster");
+  at::add_image_spec_options(positional, options, at::ARGUMENT_MODIFIER_NONE);
+}
+
+int execute_promote(const po::variables_map &vm) {
+  size_t arg_index = 0;
+  std::string pool_name;
+  std::string image_name;
+  std::string snap_name;
+  int r = utils::get_pool_image_snapshot_names(
+      vm, at::ARGUMENT_MODIFIER_NONE, &arg_index, &pool_name, &image_name,
+      &snap_name, utils::SNAPSHOT_PRESENCE_NONE);
+  if (r < 0) {
+    return r;
+  }
+
+  bool force = vm["force"].as<bool>();
+
+  librados::Rados rados;
+  librados::IoCtx io_ctx;
+  librbd::Image image;
+  r = utils::init_and_open_image(pool_name, image_name, "", false,
+                                 &rados, &io_ctx, &image);
+  if (r < 0) {
+    return r;
+  }
+
+  r = image.mirror_image_promote(force);
+  if (r < 0) {
+    std::cerr << "rbd: error promoting image to primary" << std::endl;
+    return r;
+  }
+
+  std::cout << "" << std::endl;
+  return 0;
+}
+
+int execute_demote(const po::variables_map &vm) {
+  size_t arg_index = 0;
+  std::string pool_name;
+  std::string image_name;
+  std::string snap_name;
+  int r = utils::get_pool_image_snapshot_names(
+      vm, at::ARGUMENT_MODIFIER_NONE, &arg_index, &pool_name, &image_name,
+      &snap_name, utils::SNAPSHOT_PRESENCE_NONE);
+  if (r < 0) {
+    return r;
+  }
+
+  librados::Rados rados;
+  librados::IoCtx io_ctx;
+  librbd::Image image;
+  r = utils::init_and_open_image(pool_name, image_name, "", false,
+                                 &rados, &io_ctx, &image);
+  if (r < 0) {
+    return r;
+  }
+
+  r = image.mirror_image_demote();
+  if (r < 0) {
+    std::cerr << "rbd: error demoting image to secondary" << std::endl;
+    return r;
+  }
+
+  std::cout << "Image demoted to secondary" << std::endl;
+  return 0;
+}
+
+int execute_resync(const po::variables_map &vm) {
+  size_t arg_index = 0;
+  std::string pool_name;
+  std::string image_name;
+  std::string snap_name;
+  int r = utils::get_pool_image_snapshot_names(
+      vm, at::ARGUMENT_MODIFIER_NONE, &arg_index, &pool_name, &image_name,
+      &snap_name, utils::SNAPSHOT_PRESENCE_NONE);
+  if (r < 0) {
+    return r;
+  }
+
+  librados::Rados rados;
+  librados::IoCtx io_ctx;
+  librbd::Image image;
+  r = utils::init_and_open_image(pool_name, image_name, "", false,
+                                 &rados, &io_ctx, &image);
+  if (r < 0) {
+    return r;
+  }
+
+  r = image.mirror_image_resync();
+  if (r < 0) {
+    std::cerr << "rbd: error flagging image resync" << std::endl;
+    return r;
+  }
+
+  std::cout << "Flagged image for resync from primary" << std::endl;
+  return 0;
+}
+
+Shell::Action action_enable(
+  {"mirror", "image", "enable"}, {},
+  "Enable RBD mirroring for an image.", "",
+  &get_arguments, &execute_enable);
+Shell::Action action_disable(
+  {"mirror", "image", "disable"}, {},
+  "Disable RBD mirroring for an image.", "",
+  &get_arguments_disable, &execute_disable);
+Shell::Action action_promote(
+  {"mirror", "image", "promote"}, {},
+  "Promote an image to primary for RBD mirroring.", "",
+  &get_arguments_promote, &execute_promote);
+Shell::Action action_demote(
+  {"mirror", "image", "demote"}, {},
+  "Demote an image to secondary for RBD mirroring.", "",
+  &get_arguments, &execute_demote);
+Shell::Action action_resync(
+  {"mirror", "image", "resync"}, {},
+  "Force resync to primary image for RBD mirroring.", "",
+  &get_arguments, &execute_resync);
+
+} // namespace mirror_image
+} // namespace action
+} // namespace rbd
diff --git a/src/tools/rbd/action/MirrorPool.cc b/src/tools/rbd/action/MirrorPool.cc
index 4d37ec1..8ba055e 100644
--- a/src/tools/rbd/action/MirrorPool.cc
+++ b/src/tools/rbd/action/MirrorPool.cc
@@ -23,37 +23,6 @@ namespace po = boost::program_options;
 
 namespace {
 
-int init_remote(const std::string &config_path, const std::string &client_name,
-                const std::string &cluster_name, const std::string &pool_name,
-                librados::Rados *rados, librados::IoCtx *io_ctx) {
-  int r = rados->init2(client_name.c_str(), cluster_name.c_str(), 0);
-  if (r < 0) {
-    std::cerr << "rbd: couldn't initialize remote rados!" << std::endl;
-    return r;
-  }
-
-  r = rados->conf_read_file(config_path.empty() ? nullptr :
-                                                  config_path.c_str());
-  if (r < 0) {
-    std::cerr << "rbd: couldn't read remote configuration" << std::endl;
-    return r;
-  }
-
-  r = rados->connect();
-  if (r < 0) {
-    std::cerr << "rbd: couldn't connect to the remote cluster!" << std::endl;
-    return r;
-  }
-
-  if (io_ctx != nullptr) {
-    r = utils::init_io_ctx(*rados, pool_name, io_ctx);
-    if (r < 0) {
-      return r;
-    }
-  }
-  return 0;
-}
-
 int validate_uuid(const std::string &uuid) {
   boost::regex pattern("^[A-F0-9]{8}-[A-F0-9]{4}-[A-F0-9]{4}-[A-F0-9]{4}-[A-F0-9]{12}$",
                        boost::regex::icase);
@@ -65,39 +34,31 @@ int validate_uuid(const std::string &uuid) {
   return 0;
 }
 
-void add_cluster_uuid_option(po::options_description *positional) {
+void add_uuid_option(po::options_description *positional) {
   positional->add_options()
-    ("cluster-uuid", po::value<std::string>(), "cluster UUID");
+    ("uuid", po::value<std::string>(), "peer uuid");
 }
 
-int get_cluster_uuid(const po::variables_map &vm, size_t arg_index,
-                     std::string *cluster_uuid) {
-  *cluster_uuid = utils::get_positional_argument(vm, arg_index);
-  if (cluster_uuid->empty()) {
-    std::cerr << "rbd: must specify cluster uuid" << std::endl;
+int get_uuid(const po::variables_map &vm, size_t arg_index,
+             std::string *uuid) {
+  *uuid = utils::get_positional_argument(vm, arg_index);
+  if (uuid->empty()) {
+    std::cerr << "rbd: must specify peer uuid" << std::endl;
     return -EINVAL;
   }
-  return validate_uuid(*cluster_uuid);
+  return validate_uuid(*uuid);
 }
 
 int get_remote_cluster_spec(const po::variables_map &vm,
                             const std::string &spec,
                             std::string *remote_client_name,
-                            std::string *remote_cluster,
-                            std::string *remote_cluster_uuid) {
+                            std::string *remote_cluster) {
   if (vm.count("remote-client-name")) {
     *remote_client_name = vm["remote-client-name"].as<std::string>();
   }
   if (vm.count("remote-cluster")) {
     *remote_cluster = vm["remote-cluster"].as<std::string>();
   }
-  if (vm.count("remote-cluster-uuid")) {
-    *remote_cluster_uuid = vm["remote-cluster-uuid"].as<std::string>();
-    int r = validate_uuid(*remote_cluster_uuid);
-    if (r < 0) {
-      return r;
-    }
-  }
 
   if (!spec.empty()) {
     boost::regex pattern("^(?:(client\\.[^@]+)@)?([^/@]+)$");
@@ -126,7 +87,7 @@ void format_mirror_peers(const std::string &config_path,
     formatter->open_array_section("peers");
     for (auto &peer : peers) {
       formatter->open_object_section("peer");
-      formatter->dump_string("cluster_uuid", peer.cluster_uuid);
+      formatter->dump_string("uuid", peer.uuid);
       formatter->dump_string("cluster_name", peer.cluster_name);
       formatter->dump_string("client_name", peer.client_name);
       formatter->close_section();
@@ -144,7 +105,7 @@ void format_mirror_peers(const std::string &config_path,
       tbl.define_column("CLIENT", TextTable::LEFT, TextTable::LEFT);
       for (auto &peer : peers) {
         tbl << " "
-            << peer.cluster_uuid
+            << peer.uuid
             << peer.cluster_name
             << peer.client_name
             << TextTable::endrow;
@@ -164,8 +125,7 @@ void get_peer_add_arguments(po::options_description *positional,
      "(example: [<client name>@]<cluster name>");
   options->add_options()
     ("remote-client-name", po::value<std::string>(), "remote client name")
-    ("remote-cluster", po::value<std::string>(), "remote cluster name")
-    ("remote-cluster-uuid", po::value<std::string>(), "remote cluster uuid");
+    ("remote-cluster", po::value<std::string>(), "remote cluster name");
 }
 
 int execute_peer_add(const po::variables_map &vm) {
@@ -174,10 +134,9 @@ int execute_peer_add(const po::variables_map &vm) {
 
   std::string remote_client_name = g_ceph_context->_conf->name.to_str();
   std::string remote_cluster;
-  std::string remote_cluster_uuid;
   int r = get_remote_cluster_spec(
     vm, utils::get_positional_argument(vm, arg_index),
-    &remote_client_name, &remote_cluster, &remote_cluster_uuid);
+    &remote_client_name, &remote_cluster);
   if (r < 0) {
     return r;
   }
@@ -194,44 +153,30 @@ int execute_peer_add(const po::variables_map &vm) {
     return r;
   }
 
-  if (remote_cluster_uuid.empty()) {
-    librados::Rados remote_rados;
-    librados::IoCtx remote_io_ctx;
-    r = init_remote(config_path, remote_client_name, remote_cluster,
-                    pool_name, &remote_rados, &remote_io_ctx);
-    if (r < 0) {
-      return r;
-    }
-
-    r = remote_rados.cluster_fsid(&remote_cluster_uuid);
-    if (r < 0) {
-      std::cerr << "rbd: error retrieving remote cluster id" << std::endl;
-      return r;
-    }
-  }
-
   librbd::RBD rbd;
-  r = rbd.mirror_peer_add(io_ctx, remote_cluster_uuid, remote_cluster,
-                          remote_client_name);
+  std::string uuid;
+  r = rbd.mirror_peer_add(io_ctx, &uuid, remote_cluster, remote_client_name);
   if (r < 0) {
     std::cerr << "rbd: error adding mirror peer" << std::endl;
     return r;
   }
+
+  std::cout << uuid << std::endl;
   return 0;
 }
 
 void get_peer_remove_arguments(po::options_description *positional,
                                po::options_description *options) {
   at::add_pool_options(positional, options);
-  add_cluster_uuid_option(positional);
+  add_uuid_option(positional);
 }
 
 int execute_peer_remove(const po::variables_map &vm) {
   size_t arg_index = 0;
   std::string pool_name = utils::get_pool_name(vm, &arg_index);
 
-  std::string cluster_uuid;
-  int r = get_cluster_uuid(vm, arg_index, &cluster_uuid);
+  std::string uuid;
+  int r = get_uuid(vm, arg_index, &uuid);
   if (r < 0) {
     return r;
   }
@@ -244,7 +189,7 @@ int execute_peer_remove(const po::variables_map &vm) {
   }
 
   librbd::RBD rbd;
-  r = rbd.mirror_peer_remove(io_ctx, cluster_uuid);
+  r = rbd.mirror_peer_remove(io_ctx, uuid);
   if (r < 0) {
     std::cerr << "rbd: error removing mirror peer" << std::endl;
     return r;
@@ -255,7 +200,7 @@ int execute_peer_remove(const po::variables_map &vm) {
 void get_peer_set_arguments(po::options_description *positional,
                             po::options_description *options) {
   at::add_pool_options(positional, options);
-  add_cluster_uuid_option(positional);
+  add_uuid_option(positional);
   positional->add_options()
     ("key", "peer parameter [client or cluster]")
     ("value", "new client or cluster name");
@@ -265,8 +210,8 @@ int execute_peer_set(const po::variables_map &vm) {
   size_t arg_index = 0;
   std::string pool_name = utils::get_pool_name(vm, &arg_index);
 
-  std::string cluster_uuid;
-  int r = get_cluster_uuid(vm, arg_index++, &cluster_uuid);
+  std::string uuid;
+  int r = get_uuid(vm, arg_index++, &uuid);
   if (r < 0) {
     return r;
   }
@@ -291,10 +236,9 @@ int execute_peer_set(const po::variables_map &vm) {
 
   librbd::RBD rbd;
   if (key == "client") {
-    r = rbd.mirror_peer_set_client(io_ctx, cluster_uuid.c_str(), value.c_str());
+    r = rbd.mirror_peer_set_client(io_ctx, uuid.c_str(), value.c_str());
   } else {
-    r = rbd.mirror_peer_set_cluster(io_ctx, cluster_uuid.c_str(),
-                                    value.c_str());
+    r = rbd.mirror_peer_set_cluster(io_ctx, uuid.c_str(), value.c_str());
   }
   if (r < 0) {
     return r;
@@ -302,15 +246,20 @@ int execute_peer_set(const po::variables_map &vm) {
   return 0;
 }
 
-void get_enable_disable_arguments(po::options_description *positional,
-                                  po::options_description *options) {
+void get_disable_arguments(po::options_description *positional,
+                           po::options_description *options) {
   at::add_pool_options(positional, options);
 }
 
-int execute_enable_disable(const po::variables_map &vm, bool enabled) {
-  size_t arg_index = 0;
-  std::string pool_name = utils::get_pool_name(vm, &arg_index);
+void get_enable_arguments(po::options_description *positional,
+                          po::options_description *options) {
+  at::add_pool_options(positional, options);
+  positional->add_options()
+    ("mode", "mirror mode [image or pool]");
+}
 
+int execute_enable_disable(const std::string &pool_name,
+                           rbd_mirror_mode_t mirror_mode) {
   librados::Rados rados;
   librados::IoCtx io_ctx;
   int r = utils::init(pool_name, &rados, &io_ctx);
@@ -319,7 +268,7 @@ int execute_enable_disable(const po::variables_map &vm, bool enabled) {
   }
 
   librbd::RBD rbd;
-  r = rbd.mirror_set_enabled(io_ctx, enabled);
+  r = rbd.mirror_mode_set(io_ctx, mirror_mode);
   if (r < 0) {
     return r;
   }
@@ -327,11 +276,28 @@ int execute_enable_disable(const po::variables_map &vm, bool enabled) {
 }
 
 int execute_disable(const po::variables_map &vm) {
-  return execute_enable_disable(vm, false);
+  size_t arg_index = 0;
+  std::string pool_name = utils::get_pool_name(vm, &arg_index);
+
+  return execute_enable_disable(pool_name, RBD_MIRROR_MODE_DISABLED);
 }
 
 int execute_enable(const po::variables_map &vm) {
-  return execute_enable_disable(vm, true);
+  size_t arg_index = 0;
+  std::string pool_name = utils::get_pool_name(vm, &arg_index);
+
+  rbd_mirror_mode_t mirror_mode;
+  std::string mode = utils::get_positional_argument(vm, arg_index++);
+  if (mode == "image") {
+    mirror_mode = RBD_MIRROR_MODE_IMAGE;
+  } else if (mode == "pool") {
+    mirror_mode = RBD_MIRROR_MODE_POOL;
+  } else {
+    std::cerr << "rbd: must specify 'image' or 'pool' mode." << std::endl;
+    return -EINVAL;
+  }
+
+  return execute_enable_disable(pool_name, mirror_mode);
 }
 
 void get_info_arguments(po::options_description *positional,
@@ -363,8 +329,8 @@ int execute_info(const po::variables_map &vm) {
   }
 
   librbd::RBD rbd;
-  bool enabled;
-  r = rbd.mirror_is_enabled(io_ctx, &enabled);
+  rbd_mirror_mode_t mirror_mode;
+  r = rbd.mirror_mode_get(io_ctx, &mirror_mode);
   if (r < 0) {
     return r;
   }
@@ -375,14 +341,32 @@ int execute_info(const po::variables_map &vm) {
     return r;
   }
 
+  std::string mirror_mode_desc;
+  switch (mirror_mode) {
+  case RBD_MIRROR_MODE_DISABLED:
+    mirror_mode_desc = "disabled";
+    break;
+  case RBD_MIRROR_MODE_IMAGE:
+    mirror_mode_desc = "image";
+    break;
+  case RBD_MIRROR_MODE_POOL:
+    mirror_mode_desc = "pool";
+    break;
+  default:
+    mirror_mode_desc = "unknown";
+    break;
+  }
+
   if (formatter != nullptr) {
     formatter->open_object_section("mirror");
-    formatter->dump_bool("enabled", enabled);
+    formatter->dump_string("mode", mirror_mode_desc);
   } else {
-    std::cout << "Enabled: " << (enabled ? "true" : "false") << std::endl;
+    std::cout << "Mode: " << mirror_mode_desc << std::endl;
   }
 
-  format_mirror_peers(config_path, formatter, mirror_peers);
+  if (mirror_mode != RBD_MIRROR_MODE_DISABLED) {
+    format_mirror_peers(config_path, formatter, mirror_peers);
+  }
   if (formatter != nullptr) {
     formatter->close_section();
     formatter->flush(std::cout);
@@ -406,11 +390,11 @@ Shell::Action action_set(
 Shell::Action action_disable(
   {"mirror", "pool", "disable"}, {},
   "Disable RBD mirroring by default within a pool.", "",
-  &get_enable_disable_arguments, &execute_disable);
+  &get_disable_arguments, &execute_disable);
 Shell::Action action_enable(
   {"mirror", "pool", "enable"}, {},
   "Enable RBD mirroring by default within a pool.", "",
-  &get_enable_disable_arguments, &execute_enable);
+  &get_enable_arguments, &execute_enable);
 Shell::Action action_info(
   {"mirror", "pool", "info"}, {},
   "Show information about the pool mirroring configuration.", {},
diff --git a/src/tools/rbd/action/Snap.cc b/src/tools/rbd/action/Snap.cc
index 571853c..5452ef3 100644
--- a/src/tools/rbd/action/Snap.cc
+++ b/src/tools/rbd/action/Snap.cc
@@ -175,7 +175,7 @@ int execute_list(const po::variables_map &vm) {
   librados::Rados rados;
   librados::IoCtx io_ctx;
   librbd::Image image;
-  r = utils::init_and_open_image(pool_name, image_name, "", false, &rados,
+  r = utils::init_and_open_image(pool_name, image_name, "", true, &rados,
                                  &io_ctx, &image);
   if (r < 0) {
     return r;
diff --git a/src/tools/rbd_mirror/ClusterWatcher.cc b/src/tools/rbd_mirror/ClusterWatcher.cc
index 91a7c5a..7a1e14a 100644
--- a/src/tools/rbd_mirror/ClusterWatcher.cc
+++ b/src/tools/rbd_mirror/ClusterWatcher.cc
@@ -10,7 +10,7 @@
 
 #define dout_subsys ceph_subsys_rbd_mirror
 #undef dout_prefix
-#define dout_prefix *_dout << "rbd-mirror: "
+#define dout_prefix *_dout << "rbd-mirror: ClusterWatcher::" << __func__ << ": "
 
 using std::list;
 using std::map;
@@ -45,7 +45,7 @@ const std::set<std::string>& ClusterWatcher::get_pool_names() const
 
 void ClusterWatcher::refresh_pools()
 {
-  dout(20) << __func__ << dendl;
+  dout(20) << "enter" << dendl;
   map<peer_t, set<int64_t> > peer_configs;
   set<string> pool_names;
   read_configs(&peer_configs, &pool_names);
@@ -94,14 +94,14 @@ void ClusterWatcher::read_configs(map<peer_t, set<int64_t> > *peer_configs,
       continue;
     }
 
-    bool enabled;
-    r = librbd::mirror_is_enabled(ioctx, &enabled);
+    rbd_mirror_mode_t mirror_mode;
+    r = librbd::mirror_mode_get(ioctx, &mirror_mode);
     if (r < 0) {
       derr << "could not tell whether mirroring was enabled for " << pool_name
 	   << " : " << cpp_strerror(r) << dendl;
       continue;
     }
-    if (!enabled) {
+    if (mirror_mode == RBD_MIRROR_MODE_DISABLED) {
       dout(10) << "mirroring is disabled for pool " << pool_name << dendl;
       continue;
     }
diff --git a/src/tools/rbd_mirror/ImageReplayer.cc b/src/tools/rbd_mirror/ImageReplayer.cc
index af83d01..25afe93 100644
--- a/src/tools/rbd_mirror/ImageReplayer.cc
+++ b/src/tools/rbd_mirror/ImageReplayer.cc
@@ -1,14 +1,34 @@
 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
 // vim: ts=8 sw=2 smarttab
 
+#include "common/Formatter.h"
 #include "common/debug.h"
 #include "common/errno.h"
 #include "include/stringify.h"
+#include "cls/rbd/cls_rbd_client.h"
+#include "common/Timer.h"
+#include "common/WorkQueue.h"
+#include "journal/Journaler.h"
+#include "journal/ReplayEntry.h"
+#include "journal/ReplayHandler.h"
+#include "librbd/ExclusiveLock.h"
+#include "librbd/ImageCtx.h"
+#include "librbd/ImageState.h"
+#include "librbd/Journal.h"
+#include "librbd/Operations.h"
+#include "librbd/Utils.h"
+#include "librbd/internal.h"
+#include "librbd/journal/Replay.h"
 #include "ImageReplayer.h"
+#include "ImageSync.h"
+#include "Threads.h"
+#include "tools/rbd_mirror/image_replayer/BootstrapRequest.h"
+#include "tools/rbd_mirror/image_replayer/CloseImageRequest.h"
+#include "tools/rbd_mirror/image_replayer/OpenLocalImageRequest.h"
 
 #define dout_subsys ceph_subsys_rbd_mirror
 #undef dout_prefix
-#define dout_prefix *_dout << "rbd-mirror: "
+#define dout_prefix *_dout << "rbd-mirror: " << *this << "::" << __func__ << ": "
 
 using std::map;
 using std::string;
@@ -18,44 +38,838 @@ using std::vector;
 namespace rbd {
 namespace mirror {
 
-ImageReplayer::ImageReplayer(RadosRef local, RadosRef remote,
+using librbd::util::create_context_callback;
+using namespace rbd::mirror::image_replayer;
+
+namespace {
+
+struct ReplayHandler : public ::journal::ReplayHandler {
+  ImageReplayer *replayer;
+  ReplayHandler(ImageReplayer *replayer) : replayer(replayer) {}
+
+  virtual void get() {}
+  virtual void put() {}
+
+  virtual void handle_entries_available() {
+    replayer->handle_replay_ready();
+  }
+  virtual void handle_complete(int r) {
+    replayer->handle_replay_complete(r);
+  }
+};
+
+struct C_ReplayCommitted : public Context {
+  ImageReplayer *replayer;
+  ::journal::ReplayEntry replay_entry;
+
+  C_ReplayCommitted(ImageReplayer *replayer, ::journal::ReplayEntry &&replay_entry) :
+    replayer(replayer), replay_entry(std::move(replay_entry)) {
+  }
+  virtual void finish(int r) {
+    replayer->handle_replay_committed(&replay_entry, r);
+  }
+};
+
+class ImageReplayerAdminSocketCommand {
+public:
+  virtual ~ImageReplayerAdminSocketCommand() {}
+  virtual bool call(Formatter *f, stringstream *ss) = 0;
+};
+
+class StatusCommand : public ImageReplayerAdminSocketCommand {
+public:
+  explicit StatusCommand(ImageReplayer *replayer) : replayer(replayer) {}
+
+  bool call(Formatter *f, stringstream *ss) {
+    if (f) {
+      f->open_object_section("status");
+      f->dump_stream("state") << replayer->get_state();
+      f->close_section();
+      f->flush(*ss);
+    } else {
+      *ss << "state: " << replayer->get_state();
+    }
+    return true;
+  }
+
+private:
+  ImageReplayer *replayer;
+};
+
+class FlushCommand : public ImageReplayerAdminSocketCommand {
+public:
+  explicit FlushCommand(ImageReplayer *replayer) : replayer(replayer) {}
+
+  bool call(Formatter *f, stringstream *ss) {
+    int r = replayer->flush();
+    if (r < 0) {
+      *ss << "flush: " << cpp_strerror(r);
+      return false;
+    }
+    return true;
+  }
+
+private:
+  ImageReplayer *replayer;
+};
+
+} // anonymous namespace
+
+class ImageReplayerAdminSocketHook : public AdminSocketHook {
+public:
+  ImageReplayerAdminSocketHook(CephContext *cct, const std::string &name,
+			       ImageReplayer *replayer) :
+    admin_socket(cct->get_admin_socket()) {
+    std::string command;
+    int r;
+
+    command = "rbd mirror status " + name;
+    r = admin_socket->register_command(command, command, this,
+				       "get status for rbd mirror " + name);
+    if (r == 0) {
+      commands[command] = new StatusCommand(replayer);
+    }
+
+    command = "rbd mirror flush " + name;
+    r = admin_socket->register_command(command, command, this,
+				       "flush rbd mirror " + name);
+    if (r == 0) {
+      commands[command] = new FlushCommand(replayer);
+    }
+  }
+
+  ~ImageReplayerAdminSocketHook() {
+    for (Commands::const_iterator i = commands.begin(); i != commands.end();
+	 ++i) {
+      (void)admin_socket->unregister_command(i->first);
+      delete i->second;
+    }
+  }
+
+  bool call(std::string command, cmdmap_t& cmdmap, std::string format,
+	    bufferlist& out) {
+    Commands::const_iterator i = commands.find(command);
+    assert(i != commands.end());
+    Formatter *f = Formatter::create(format);
+    stringstream ss;
+    bool r = i->second->call(f, &ss);
+    delete f;
+    out.append(ss);
+    return r;
+  }
+
+private:
+  typedef std::map<std::string, ImageReplayerAdminSocketCommand*> Commands;
+
+  AdminSocket *admin_socket;
+  Commands commands;
+};
+
+ImageReplayer::ImageReplayer(Threads *threads, RadosRef local, RadosRef remote,
+			     const std::string &client_id,
+			     int64_t local_pool_id,
 			     int64_t remote_pool_id,
-			     const string &remote_image_id) :
-  m_lock(stringify("rbd::mirror::ImageReplayer ") + stringify(remote_pool_id) +
-	 string(" ") + remote_image_id),
-  m_remote_pool_id(remote_pool_id),
-  m_image_id(remote_image_id),
+			     const std::string &remote_image_id) :
+  m_threads(threads),
   m_local(local),
-  m_remote(remote)
+  m_remote(remote),
+  m_client_id(client_id),
+  m_remote_pool_id(remote_pool_id),
+  m_local_pool_id(local_pool_id),
+  m_remote_image_id(remote_image_id),
+  m_lock("rbd::mirror::ImageReplayer " + stringify(remote_pool_id) + " " +
+	 remote_image_id),
+  m_state(STATE_UNINITIALIZED),
+  m_local_image_ctx(nullptr),
+  m_local_replay(nullptr),
+  m_remote_journaler(nullptr),
+  m_replay_handler(nullptr),
+  m_on_finish(nullptr),
+  m_asok_hook(nullptr)
 {
 }
 
 ImageReplayer::~ImageReplayer()
 {
+  assert(m_local_image_ctx == nullptr);
+  assert(m_local_replay == nullptr);
+  assert(m_remote_journaler == nullptr);
+  assert(m_replay_handler == nullptr);
+
+  delete m_asok_hook;
 }
 
-int ImageReplayer::start()
+void ImageReplayer::start(Context *on_finish,
+			  const BootstrapParams *bootstrap_params)
 {
+  dout(20) << "on_finish=" << on_finish << ", m_on_finish=" << m_on_finish
+	   << dendl;
+
+  {
+    Mutex::Locker locker(m_lock);
+    assert(is_stopped_());
+
+    m_state = STATE_STARTING;
+
+    assert(m_on_finish == nullptr);
+    m_on_finish = on_finish;
+  }
+
   int r = m_remote->ioctx_create2(m_remote_pool_id, m_remote_ioctx);
   if (r < 0) {
     derr << "error opening ioctx for remote pool " << m_remote_pool_id
-	 << " : " << cpp_strerror(r) << dendl;
-    return r;
+	 << ": " << cpp_strerror(r) << dendl;
+    on_start_fail_start(r);
+    return;
+  }
+
+  if (bootstrap_params != nullptr && !bootstrap_params->empty()) {
+    r = m_local->pool_lookup(bootstrap_params->local_pool_name.c_str());
+    if (r < 0) {
+      derr << "error finding local pool " << bootstrap_params->local_pool_name
+           << ": " << cpp_strerror(r) << dendl;
+      on_start_fail_start(r);
+      return;
+    }
+    m_local_pool_id = r;
   }
-  m_pool_name = m_remote_ioctx.get_pool_name();
-  r = m_local->ioctx_create(m_pool_name.c_str(), m_local_ioctx);
+
+  r = m_local->ioctx_create2(m_local_pool_id, m_local_ioctx);
   if (r < 0) {
-    derr << "error opening ioctx for local pool " << m_pool_name
-	 << " : " << cpp_strerror(r) << dendl;
-    return r;
+    derr << "error opening ioctx for local pool " << m_local_pool_id
+         << ": " << cpp_strerror(r) << dendl;
+    on_start_fail_start(r);
+    return;
   }
-  return 0;
+
+  CephContext *cct = static_cast<CephContext *>(m_local->cct());
+
+  double commit_interval = cct->_conf->rbd_journal_commit_age;
+  m_remote_journaler = new ::journal::Journaler(m_threads->work_queue,
+						m_threads->timer,
+						&m_threads->timer_lock,
+						m_remote_ioctx,
+						m_remote_image_id, m_client_id,
+						commit_interval);
+
+  on_start_get_registered_client_status_start(bootstrap_params);
+}
+
+void ImageReplayer::on_start_get_registered_client_status_start(
+  const BootstrapParams *bootstrap_params)
+{
+  dout(20) << "enter" << dendl;
+
+  struct Metadata {
+    uint64_t minimum_set;
+    uint64_t active_set;
+    std::set<cls::journal::Client> registered_clients;
+    BootstrapParams bootstrap_params;
+  } *m = new Metadata();
+
+  if (bootstrap_params) {
+    m->bootstrap_params = *bootstrap_params;
+  }
+
+  FunctionContext *ctx = new FunctionContext(
+    [this, m, bootstrap_params](int r) {
+      on_start_get_registered_client_status_finish(r, m->registered_clients,
+						   m->bootstrap_params);
+      delete m;
+    });
+
+  m_remote_journaler->get_mutable_metadata(&m->minimum_set, &m->active_set,
+					   &m->registered_clients, ctx);
+}
+
+void ImageReplayer::on_start_get_registered_client_status_finish(int r,
+  const std::set<cls::journal::Client> &registered_clients,
+  const BootstrapParams &bootstrap_params)
+{
+  dout(20) << "r=" << r << dendl;
+
+  if (r < 0) {
+    derr << "error obtaining registered client status: "
+	 << cpp_strerror(r) << dendl;
+    on_start_fail_start(r);
+    return;
+  }
+  if (on_start_interrupted()) {
+    return;
+  }
+
+  for (auto c : registered_clients) {
+    if (c.id == m_client_id) {
+      librbd::journal::ClientData client_data;
+      bufferlist::iterator bl = c.data.begin();
+      try {
+	::decode(client_data, bl);
+      } catch (const buffer::error &err) {
+	derr << "failed to decode client meta data: " << err.what() << dendl;
+	on_start_fail_start(-EINVAL);
+	return;
+      }
+
+      // TODO: unsafe cast
+      m_client_meta =
+	boost::get<librbd::journal::MirrorPeerClientMeta>(client_data.client_meta);
+      m_local_image_id = m_client_meta.image_id;
+
+      dout(20) << "client found, pool_id=" << m_local_pool_id << ", image_id="
+	       << m_local_image_id << dendl;
+
+      if (!bootstrap_params.empty()) {
+	dout(0) << "ignoring bootsrap params: client already registered" << dendl;
+      }
+
+      on_start_remote_journaler_init_start();
+      return;
+    }
+  }
+
+  dout(20) << "client not found" << dendl;
+  bootstrap(bootstrap_params);
+}
+
+void ImageReplayer::bootstrap(const BootstrapParams &bootstrap_params) {
+  int r;
+  BootstrapParams params;
+
+  if (!bootstrap_params.empty()) {
+    dout(20) << "using external bootstrap params" << dendl;
+    params = bootstrap_params;
+  } else {
+    r = get_bootstrap_params(&params);
+    if (r < 0) {
+      derr << "error obtaining bootstrap parameters: "
+	   << cpp_strerror(r) << dendl;
+      on_start_fail_start(r);
+      return;
+    }
+  }
+
+  dout(20) << "bootstrap params: "
+           << "local_pool_name=" << params.local_pool_name << ", "
+	   << "local_image_name=" << params.local_image_name << dendl;
+
+  // TODO: add a new bootstrap state and support canceling
+  Context *ctx = create_context_callback<
+    ImageReplayer, &ImageReplayer::handle_bootstrap>(this);
+  BootstrapRequest<> *request = BootstrapRequest<>::create(
+    m_local_ioctx, m_remote_ioctx, &m_local_image_ctx,
+    params.local_image_name, m_remote_image_id, m_threads->work_queue,
+    m_threads->timer, &m_threads->timer_lock, m_client_id, m_remote_journaler,
+    &m_client_meta, ctx);
+  request->send();
+}
+
+void ImageReplayer::handle_bootstrap(int r) {
+  dout(20) << "r=" << r << dendl;
+
+  if (r < 0) {
+    on_start_fail_start(r);
+    return;
+  }
+  if (on_start_interrupted()) {
+    return;
+  }
+
+  on_start_remote_journaler_init_start();
+}
+
+void ImageReplayer::on_start_remote_journaler_init_start()
+{
+  if (on_start_interrupted()) {
+    return;
+  }
+
+  dout(20) << "enter" << dendl;
+
+  FunctionContext *ctx = new FunctionContext(
+    [this](int r) {
+      on_start_remote_journaler_init_finish(r);
+    });
+
+  m_remote_journaler->init(ctx);
+}
+
+void ImageReplayer::on_start_remote_journaler_init_finish(int r)
+{
+  dout(20) << "r=" << r << dendl;
+
+  if (r < 0) {
+    derr << "error initializing journal: " << cpp_strerror(r) << dendl;
+    on_start_fail_start(r);
+    return;
+  }
+  if (on_start_interrupted()) {
+    return;
+  }
+
+
+  on_start_local_image_open_start();
+}
+
+void ImageReplayer::on_start_local_image_open_start()
+{
+  dout(20) << "enter" << dendl;
+  if (m_local_image_ctx != nullptr) {
+    // already opened during bootstrap
+    on_start_wait_for_local_journal_ready_start();
+    return;
+  }
+
+  // open and lock the local image
+  Context *ctx = create_context_callback<
+    ImageReplayer, &ImageReplayer::on_start_local_image_open_finish>(this);
+  OpenLocalImageRequest<> *request = OpenLocalImageRequest<>::create(
+    m_local_ioctx, &m_local_image_ctx, "", m_local_image_id,
+    m_threads->work_queue, ctx);
+  request->send();
 }
 
-void ImageReplayer::stop()
+void ImageReplayer::on_start_local_image_open_finish(int r)
 {
+  dout(20) << "r=" << r << dendl;
+
+  if (r < 0) {
+    derr << "error opening local image " <<  m_local_image_id
+	 << ": " << cpp_strerror(r) << dendl;
+    on_start_fail_start(r);
+    return;
+  }
+  if (on_start_interrupted()) {
+    return;
+  }
+
+  on_start_wait_for_local_journal_ready_start();
+}
+
+void ImageReplayer::on_start_wait_for_local_journal_ready_start()
+{
+  dout(20) << "enter" << dendl;
+
+  if (!m_asok_hook) {
+    CephContext *cct = static_cast<CephContext *>(m_local->cct());
+    std::string name = m_local_ioctx.get_pool_name() + "/" +
+      m_local_image_ctx->name;
+
+    m_asok_hook = new ImageReplayerAdminSocketHook(cct, name, this);
+  }
+
+  FunctionContext *ctx = new FunctionContext(
+    [this](int r) {
+      on_start_wait_for_local_journal_ready_finish(r);
+    });
+  m_local_image_ctx->journal->wait_for_journal_ready(ctx);
+}
+
+void ImageReplayer::on_start_wait_for_local_journal_ready_finish(int r)
+{
+  dout(20) << "r=" << r << dendl;
+
+  if (r < 0) {
+    derr << "error when waiting for local journal ready: " << cpp_strerror(r)
+	 << dendl;
+    on_start_fail_start(r);
+    return;
+  }
+  if (on_start_interrupted()) {
+    return;
+  }
+
+  r = m_local_image_ctx->journal->start_external_replay(&m_local_replay);
+  if (r < 0) {
+    derr << "error starting external replay on local image "
+	 <<  m_local_image_id << ": " << cpp_strerror(r) << dendl;
+    on_start_fail_start(r);
+    return;
+  }
+
+  m_replay_handler = new ReplayHandler(this);
+
+  m_remote_journaler->start_live_replay(m_replay_handler,
+					1 /* TODO: configurable */);
+
+  dout(20) << "m_remote_journaler=" << *m_remote_journaler << dendl;
+
+  assert(r == 0);
+
+  Context *on_finish(nullptr);
+
+  {
+    Mutex::Locker locker(m_lock);
+
+    if (m_state == STATE_STOPPING) {
+      on_start_fail_start(-EINTR);
+      return;
+    }
+
+    assert(m_state == STATE_STARTING);
+    m_state = STATE_REPLAYING;
+
+    std::swap(m_on_finish, on_finish);
+  }
+
+  dout(20) << "start succeeded" << dendl;
+
+  if (on_finish) {
+    dout(20) << "on finish complete, r=" << r << dendl;
+    on_finish->complete(r);
+  }
+}
+
+void ImageReplayer::on_start_fail_start(int r)
+{
+  dout(20) << "r=" << r << dendl;
+
+  FunctionContext *ctx = new FunctionContext(
+    [this, r](int r1) {
+      assert(r1 == 0);
+      on_start_fail_finish(r);
+    });
+
+  m_threads->work_queue->queue(ctx, 0);
+}
+
+void ImageReplayer::on_start_fail_finish(int r)
+{
+  dout(20) << "r=" << r << dendl;
+
+  if (m_remote_journaler) {
+    if (m_remote_journaler->is_initialized()) {
+      m_remote_journaler->shut_down();
+    }
+    delete m_remote_journaler;
+    m_remote_journaler = nullptr;
+  }
+
+  if (m_local_replay) {
+    shut_down_journal_replay(true);
+    m_local_image_ctx->journal->stop_external_replay();
+    m_local_replay = nullptr;
+  }
+
+  if (m_replay_handler) {
+    delete m_replay_handler;
+    m_replay_handler = nullptr;
+  }
+
+  if (m_local_image_ctx) {
+    bool owner;
+    if (librbd::is_exclusive_lock_owner(m_local_image_ctx, &owner) == 0 &&
+	owner) {
+      librbd::unlock(m_local_image_ctx, "");
+    }
+    m_local_image_ctx->state->close();
+    m_local_image_ctx = nullptr;
+  }
+
+  m_local_ioctx.close();
   m_remote_ioctx.close();
+
+  Context *on_finish(nullptr);
+
+  {
+    Mutex::Locker locker(m_lock);
+    if (m_state == STATE_STOPPING) {
+      assert(r == -EINTR);
+      dout(20) << "start interrupted" << dendl;
+      m_state = STATE_STOPPED;
+    } else {
+      assert(m_state == STATE_STARTING);
+      dout(20) << "start failed" << dendl;
+      m_state = STATE_UNINITIALIZED;
+    }
+    std::swap(m_on_finish, on_finish);
+  }
+
+  if (on_finish) {
+    dout(20) << "on finish complete, r=" << r << dendl;
+    on_finish->complete(r);
+  }
+}
+
+bool ImageReplayer::on_start_interrupted()
+{
+  Mutex::Locker locker(m_lock);
+
+  if (m_state == STATE_STARTING) {
+    return false;
+  }
+
+  assert(m_state == STATE_STOPPING);
+
+  on_start_fail_start(-EINTR);
+  return true;
+}
+
+void ImageReplayer::stop(Context *on_finish)
+{
+  dout(20) << "on_finish=" << on_finish << ", m_on_finish=" << m_on_finish
+	   << dendl;
+
+  Mutex::Locker locker(m_lock);
+  assert(is_running_());
+
+  if (m_state == STATE_STARTING) {
+    dout(20) << "interrupting start" << dendl;
+
+    if (on_finish) {
+      Context *on_start_finish = m_on_finish;
+      FunctionContext *ctx = new FunctionContext(
+	[this, on_start_finish, on_finish](int r) {
+	  if (on_start_finish) {
+	    on_start_finish->complete(r);
+	  }
+	  on_finish->complete(0);
+	});
+
+      m_on_finish = ctx;
+    }
+  } else {
+    assert(m_on_finish == nullptr);
+    m_on_finish = on_finish;
+    on_stop_journal_replay_shut_down_start();
+  }
+  m_state = STATE_STOPPING;
+}
+
+void ImageReplayer::on_stop_journal_replay_shut_down_start()
+{
+  dout(20) << "enter" << dendl;
+
+  FunctionContext *ctx = new FunctionContext(
+    [this](int r) {
+      on_stop_journal_replay_shut_down_finish(r);
+    });
+
+  m_local_replay->shut_down(false, ctx);
+}
+
+void ImageReplayer::on_stop_journal_replay_shut_down_finish(int r)
+{
+  dout(20) << "r=" << r << dendl;
+
+  if (r < 0) {
+    derr << "error flushing journal replay: " << cpp_strerror(r) << dendl;
+  }
+
+  m_local_image_ctx->journal->stop_external_replay();
+  m_local_replay = nullptr;
+
+  on_stop_local_image_close_start();
+}
+
+void ImageReplayer::on_stop_local_image_close_start()
+{
+  dout(20) << "enter" << dendl;
+
+  // close and delete the image (from outside the image's thread context)
+  Context *ctx = create_context_callback<
+    ImageReplayer, &ImageReplayer::on_stop_local_image_close_finish>(this);
+  CloseImageRequest<> *request = CloseImageRequest<>::create(
+    &m_local_image_ctx, m_threads->work_queue, ctx);
+  request->send();
+}
+
+void ImageReplayer::on_stop_local_image_close_finish(int r)
+{
+  dout(20) << "r=" << r << dendl;
+
+  if (r < 0) {
+    derr << "error closing local image: " << cpp_strerror(r) << dendl;
+  }
+
   m_local_ioctx.close();
+
+  m_remote_journaler->stop_replay();
+  m_remote_journaler->shut_down();
+  delete m_remote_journaler;
+  m_remote_journaler = nullptr;
+
+  delete m_replay_handler;
+  m_replay_handler = nullptr;
+
+  m_remote_ioctx.close();
+
+  Context *on_finish(nullptr);
+
+  {
+    Mutex::Locker locker(m_lock);
+    assert(m_state == STATE_STOPPING);
+
+    m_state = STATE_STOPPED;
+
+    std::swap(m_on_finish, on_finish);
+  }
+
+  dout(20) << "stop complete" << dendl;
+
+  if (on_finish) {
+    dout(20) << "on finish complete, r=" << r << dendl;
+    on_finish->complete(r);
+  }
+}
+
+void ImageReplayer::close_local_image(Context *on_finish)
+{
+  m_local_image_ctx->state->close(on_finish);
+}
+
+void ImageReplayer::handle_replay_ready()
+{
+  dout(20) << "enter" << dendl;
+
+  ::journal::ReplayEntry replay_entry;
+  if (!m_remote_journaler->try_pop_front(&replay_entry)) {
+    return;
+  }
+
+  dout(20) << "processing entry tid=" << replay_entry.get_commit_tid() << dendl;
+
+  bufferlist data = replay_entry.get_data();
+  bufferlist::iterator it = data.begin();
+  Context *on_ready = create_context_callback<
+    ImageReplayer, &ImageReplayer::handle_replay_process_ready>(this);
+  Context *on_commit = new C_ReplayCommitted(this, std::move(replay_entry));
+  m_local_replay->process(&it, on_ready, on_commit);
+}
+
+int ImageReplayer::flush()
+{
+  // TODO: provide async method
+
+  dout(20) << "enter" << dendl;
+
+  {
+    Mutex::Locker locker(m_lock);
+
+    if (m_state != STATE_REPLAYING) {
+      return 0;
+    }
+
+    m_state = STATE_FLUSHING_REPLAY;
+  }
+
+  C_SaferCond replay_flush_ctx;
+  m_local_replay->flush(&replay_flush_ctx);
+  int r = replay_flush_ctx.wait();
+  if (r < 0) {
+    derr << "error flushing local replay: " << cpp_strerror(r) << dendl;
+  }
+
+  C_SaferCond journaler_flush_ctx;
+  m_remote_journaler->flush_commit_position(&journaler_flush_ctx);
+  int r1 = journaler_flush_ctx.wait();
+  if (r1 < 0) {
+    derr << "error flushing remote journal commit position: "
+	 << cpp_strerror(r1) << dendl;
+  }
+
+  {
+    Mutex::Locker locker(m_lock);
+    assert(m_state == STATE_FLUSHING_REPLAY);
+
+    m_state = STATE_REPLAYING;
+  }
+
+  dout(20) << "done" << dendl;
+
+  return r < 0 ? r : r1;
+}
+
+void ImageReplayer::handle_replay_process_ready(int r)
+{
+  // journal::Replay is ready for more events -- attempt to pop another
+
+  dout(20) << "enter" << dendl;
+
+  if (r < 0) {
+    derr << "error replaying journal entry: " << cpp_strerror(r)
+	 << dendl;
+    // TODO: handle error
+  }
+
+  assert(r == 0);
+  handle_replay_ready();
+}
+
+void ImageReplayer::handle_replay_complete(int r)
+{
+  dout(20) "r=" << r << dendl;
+
+  //m_remote_journaler->stop_replay();
+}
+
+void ImageReplayer::handle_replay_committed(
+  ::journal::ReplayEntry *replay_entry, int r)
+{
+  dout(20) << "commit_tid=" << replay_entry->get_commit_tid() << ", r=" << r
+	   << dendl;
+
+  m_remote_journaler->committed(*replay_entry);
+}
+
+int ImageReplayer::get_bootstrap_params(BootstrapParams *params)
+{
+  int r = librbd::cls_client::dir_get_name(&m_remote_ioctx, RBD_DIRECTORY,
+					   m_remote_image_id,
+					   &params->local_image_name);
+  if (r < 0) {
+    derr << "error looking up name for remote image id " << m_remote_image_id
+	 << ": " << cpp_strerror(r) << dendl;
+    return r;
+  }
+
+  params->local_pool_name = m_remote_ioctx.get_pool_name();
+
+  return 0;
+}
+
+void ImageReplayer::shut_down_journal_replay(bool cancel_ops)
+{
+  C_SaferCond cond;
+  m_local_replay->shut_down(cancel_ops, &cond);
+  int r = cond.wait();
+  if (r < 0) {
+    derr << "error flushing journal replay: " << cpp_strerror(r) << dendl;
+  }
+}
+
+std::ostream &operator<<(std::ostream &os, const ImageReplayer::State &state)
+{
+  switch (state) {
+  case ImageReplayer::STATE_UNINITIALIZED:
+    os << "Uninitialized";
+    break;
+  case ImageReplayer::STATE_STARTING:
+    os << "Starting";
+    break;
+  case ImageReplayer::STATE_REPLAYING:
+    os << "Replaying";
+    break;
+  case ImageReplayer::STATE_FLUSHING_REPLAY:
+    os << "FlushingReplay";
+    break;
+  case ImageReplayer::STATE_STOPPING:
+    os << "Stopping";
+    break;
+  case ImageReplayer::STATE_STOPPED:
+    os << "Stopped";
+    break;
+  default:
+    os << "Unknown(" << state << ")";
+    break;
+  }
+  return os;
+}
+
+std::ostream &operator<<(std::ostream &os, const ImageReplayer &replayer)
+{
+  os << "ImageReplayer[" << replayer.m_remote_pool_id << "/"
+     << replayer.m_remote_image_id << "]";
+  return os;
 }
 
 } // namespace mirror
diff --git a/src/tools/rbd_mirror/ImageReplayer.h b/src/tools/rbd_mirror/ImageReplayer.h
index 311f96e..9dc26e1 100644
--- a/src/tools/rbd_mirror/ImageReplayer.h
+++ b/src/tools/rbd_mirror/ImageReplayer.h
@@ -11,32 +11,191 @@
 #include "common/Mutex.h"
 #include "common/WorkQueue.h"
 #include "include/rados/librados.hpp"
+#include "cls/journal/cls_journal_types.h"
+#include "librbd/journal/Types.h"
 #include "types.h"
 
+namespace journal {
+
+class Journaler;
+class ReplayHandler;
+class ReplayEntry;
+
+}
+
+namespace librbd {
+
+class ImageCtx;
+
+namespace journal {
+
+template <typename> class Replay;
+
+}
+
+}
+
 namespace rbd {
 namespace mirror {
 
+class ImageReplayerAdminSocketHook;
+struct Threads;
+
 /**
  * Replays changes from a remote cluster for a single image.
  */
 class ImageReplayer {
 public:
-  ImageReplayer(RadosRef local, RadosRef remote,
+  enum State {
+    STATE_UNINITIALIZED,
+    STATE_STARTING,
+    STATE_REPLAYING,
+    STATE_FLUSHING_REPLAY,
+    STATE_STOPPING,
+    STATE_STOPPED,
+  };
+
+  struct BootstrapParams {
+    std::string local_pool_name;
+    std::string local_image_name;
+
+    BootstrapParams() {}
+    BootstrapParams(const std::string &local_pool_name,
+		    const std::string local_image_name) :
+      local_pool_name(local_pool_name),
+      local_image_name(local_image_name) {}
+
+    bool empty() const {
+      return local_pool_name.empty() && local_image_name.empty();
+    }
+  };
+
+  ImageReplayer(Threads *threads, RadosRef local, RadosRef remote,
+		const std::string &client_id, int64_t local_pool_id,
 		int64_t remote_pool_id, const std::string &remote_image_id);
-  ~ImageReplayer();
+  virtual ~ImageReplayer();
   ImageReplayer(const ImageReplayer&) = delete;
   ImageReplayer& operator=(const ImageReplayer&) = delete;
 
-  int start();
-  void stop();
+  State get_state() { Mutex::Locker l(m_lock); return get_state_(); }
+  bool is_stopped() { Mutex::Locker l(m_lock); return is_stopped_(); }
+  bool is_running() { Mutex::Locker l(m_lock); return is_running_(); }
+
+  void start(Context *on_finish = nullptr,
+	     const BootstrapParams *bootstrap_params = nullptr);
+  void stop(Context *on_finish = nullptr);
+  int flush();
+
+  virtual void handle_replay_ready();
+  virtual void handle_replay_process_ready(int r);
+  virtual void handle_replay_complete(int r);
+
+  virtual void handle_replay_committed(::journal::ReplayEntry* replay_entry, int r);
+
+protected:
+  /**
+   * @verbatim
+   *                   (error)
+   * <uninitialized> <------------------------ FAIL
+   *    |                                       ^
+   *    v                                       *
+   * <starting>                                 *
+   *    |                                       *
+   *    v                               (error) *
+   * GET_REGISTERED_CLIENT_STATUS * * * * * * * *
+   *    |                                       *
+   *    | (sync required)                       *
+   *    |\-----\                                *
+   *    |      |                                *
+   *    |      v                                *
+   *    |   BOOTSTRAP_IMAGE * * * * * * * * * * *
+   *    |      |                                *
+   *    |      v                                *
+   *    |/-----/                                *
+   *    |                                       *
+   *    v (no sync required)            (error) *
+   * REMOTE_JOURNALER_INIT  * * * * * * * * * * *
+   *    |                                       *
+   *    v                               (error) *
+   * LOCAL_IMAGE_OPEN (skip if not              *
+   *    |              needed                   *
+   *    v                               (error) *
+   * WAIT_FOR_LOCAL_JOURNAL_READY * * * * * * * *
+   *    |
+   *    v
+   * <replaying>
+   *    |
+   *    v
+   * <stopping>
+   *    |
+   *    v
+   * JOURNAL_REPLAY_SHUT_DOWN
+   *    |
+   *    v
+   * LOCAL_IMAGE_CLOSE
+   *    |
+   *    v
+   * <stopped>
+   *
+   * @endverbatim
+   */
+
+  virtual void on_start_get_registered_client_status_start(
+    const BootstrapParams *bootstrap_params);
+  virtual void on_start_get_registered_client_status_finish(int r,
+    const std::set<cls::journal::Client> &registered_clients,
+    const BootstrapParams &bootstrap_params);
+
+  void bootstrap(const BootstrapParams &params);
+  void handle_bootstrap(int r);
+
+  virtual void on_start_remote_journaler_init_start();
+  virtual void on_start_remote_journaler_init_finish(int r);
+  virtual void on_start_local_image_open_start();
+  virtual void on_start_local_image_open_finish(int r);
+  virtual void on_start_wait_for_local_journal_ready_start();
+  virtual void on_start_wait_for_local_journal_ready_finish(int r);
+  virtual void on_start_fail_start(int r);
+  virtual void on_start_fail_finish(int r);
+  virtual bool on_start_interrupted();
+
+  virtual void on_stop_journal_replay_shut_down_start();
+  virtual void on_stop_journal_replay_shut_down_finish(int r);
+  virtual void on_stop_local_image_close_start();
+  virtual void on_stop_local_image_close_finish(int r);
+
+  void close_local_image(Context *on_finish); // for tests
 
 private:
-  Mutex m_lock;
-  int64_t m_remote_pool_id;
-  std::string m_pool_name;
-  std::string m_image_id;
+  State get_state_() const { return m_state; }
+  bool is_stopped_() const { return m_state == STATE_UNINITIALIZED ||
+                                    m_state == STATE_STOPPED; }
+  bool is_running_() const { return !is_stopped_() && m_state != STATE_STOPPING; }
+
+  int get_bootstrap_params(BootstrapParams *params);
+
+  void shut_down_journal_replay(bool cancel_ops);
+
+  friend std::ostream &operator<<(std::ostream &os,
+				  const ImageReplayer &replayer);
+
+  Threads *m_threads;
   RadosRef m_local, m_remote;
+  std::string m_client_id;
+  int64_t m_remote_pool_id, m_local_pool_id;
+  std::string m_remote_image_id, m_local_image_id;
+  Mutex m_lock;
+  State m_state;
+  std::string m_local_pool_name, m_remote_pool_name;
   librados::IoCtx m_local_ioctx, m_remote_ioctx;
+  librbd::ImageCtx *m_local_image_ctx;
+  librbd::journal::Replay<librbd::ImageCtx> *m_local_replay;
+  ::journal::Journaler *m_remote_journaler;
+  ::journal::ReplayHandler *m_replay_handler;
+  Context *m_on_finish;
+  ImageReplayerAdminSocketHook *m_asok_hook;
+
+  librbd::journal::MirrorPeerClientMeta m_client_meta;
 };
 
 } // namespace mirror
diff --git a/src/tools/rbd_mirror/ImageSync.cc b/src/tools/rbd_mirror/ImageSync.cc
new file mode 100644
index 0000000..5bb1457
--- /dev/null
+++ b/src/tools/rbd_mirror/ImageSync.cc
@@ -0,0 +1,310 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+
+#include "ImageSync.h"
+#include "common/errno.h"
+#include "journal/Journaler.h"
+#include "librbd/ImageCtx.h"
+#include "librbd/ObjectMap.h"
+#include "librbd/Utils.h"
+#include "librbd/journal/Types.h"
+#include "tools/rbd_mirror/image_sync/ImageCopyRequest.h"
+#include "tools/rbd_mirror/image_sync/SnapshotCopyRequest.h"
+#include "tools/rbd_mirror/image_sync/SyncPointCreateRequest.h"
+#include "tools/rbd_mirror/image_sync/SyncPointPruneRequest.h"
+
+#define dout_subsys ceph_subsys_rbd_mirror
+#undef dout_prefix
+#define dout_prefix *_dout << "rbd::mirror::ImageSync: " \
+                           << this << " " << __func__
+
+namespace rbd {
+namespace mirror {
+
+using namespace image_sync;
+using librbd::util::create_context_callback;
+using librbd::util::unique_lock_name;
+
+template <typename I>
+ImageSync<I>::ImageSync(I *local_image_ctx, I *remote_image_ctx,
+                        SafeTimer *timer, Mutex *timer_lock,
+                        const std::string &mirror_uuid, Journaler *journaler,
+                        MirrorPeerClientMeta *client_meta, Context *on_finish)
+  : m_local_image_ctx(local_image_ctx), m_remote_image_ctx(remote_image_ctx),
+    m_timer(timer), m_timer_lock(timer_lock), m_mirror_uuid(mirror_uuid),
+    m_journaler(journaler), m_client_meta(client_meta), m_on_finish(on_finish),
+    m_lock(unique_lock_name("ImageSync::m_lock", this)) {
+}
+
+template <typename I>
+void ImageSync<I>::start() {
+  send_prune_catch_up_sync_point();
+}
+
+template <typename I>
+void ImageSync<I>::cancel() {
+  Mutex::Locker locker(m_lock);
+
+  CephContext *cct = m_local_image_ctx->cct;
+  ldout(cct, 20) << dendl;
+
+  m_canceled = true;
+  if (m_image_copy_request != nullptr) {
+    m_image_copy_request->cancel();
+  }
+}
+
+template <typename I>
+void ImageSync<I>::send_prune_catch_up_sync_point() {
+  if (m_client_meta->sync_points.size() <= 1) {
+    send_create_sync_point();
+    return;
+  }
+
+  CephContext *cct = m_local_image_ctx->cct;
+  ldout(cct, 20) << dendl;
+
+  Context *ctx = create_context_callback<
+    ImageSync<I>, &ImageSync<I>::handle_prune_catch_up_sync_point>(this);
+  SyncPointPruneRequest<I> *request = SyncPointPruneRequest<I>::create(
+    m_remote_image_ctx, false, m_journaler, m_client_meta, ctx);
+  request->send();
+}
+
+template <typename I>
+void ImageSync<I>::handle_prune_catch_up_sync_point(int r) {
+  CephContext *cct = m_local_image_ctx->cct;
+  ldout(cct, 20) << ": r=" << r << dendl;
+
+  if (r < 0) {
+    lderr(cct) << "failed to prune catch-up sync point: "
+               << cpp_strerror(r) << dendl;
+    finish(r);
+    return;
+  }
+
+  send_create_sync_point();
+}
+
+template <typename I>
+void ImageSync<I>::send_create_sync_point() {
+  // TODO: when support for disconnecting laggy clients is added,
+  //       re-connect and create catch-up sync point
+  if (m_client_meta->sync_points.size() > 0) {
+    send_copy_snapshots();
+    return;
+  }
+
+  CephContext *cct = m_local_image_ctx->cct;
+  ldout(cct, 20) << dendl;
+
+  Context *ctx = create_context_callback<
+    ImageSync<I>, &ImageSync<I>::handle_create_sync_point>(this);
+  SyncPointCreateRequest<I> *request = SyncPointCreateRequest<I>::create(
+    m_remote_image_ctx, m_mirror_uuid, m_journaler, m_client_meta, ctx);
+  request->send();
+}
+
+template <typename I>
+void ImageSync<I>::handle_create_sync_point(int r) {
+  CephContext *cct = m_local_image_ctx->cct;
+  ldout(cct, 20) << ": r=" << r << dendl;
+
+  if (r < 0) {
+    lderr(cct) << "failed to create sync point: " << cpp_strerror(r)
+               << dendl;
+    finish(r);
+    return;
+  }
+
+  send_copy_snapshots();
+}
+
+template <typename I>
+void ImageSync<I>::send_copy_snapshots() {
+  CephContext *cct = m_local_image_ctx->cct;
+  ldout(cct, 20) << dendl;
+
+  Context *ctx = create_context_callback<
+    ImageSync<I>, &ImageSync<I>::handle_copy_snapshots>(this);
+  SnapshotCopyRequest<I> *request = SnapshotCopyRequest<I>::create(
+    m_local_image_ctx, m_remote_image_ctx, &m_snap_map, m_journaler,
+    m_client_meta, ctx);
+  request->send();
+}
+
+template <typename I>
+void ImageSync<I>::handle_copy_snapshots(int r) {
+  CephContext *cct = m_local_image_ctx->cct;
+  ldout(cct, 20) << ": r=" << r << dendl;
+
+  if (r < 0) {
+    lderr(cct) << "failed to copy snapshot metadata: "
+               << cpp_strerror(r) << dendl;
+    finish(r);
+    return;
+  }
+
+  send_copy_image();
+}
+
+template <typename I>
+void ImageSync<I>::send_copy_image() {
+  m_lock.Lock();
+  if (m_canceled) {
+    m_lock.Unlock();
+    finish(-ECANCELED);
+    return;
+  }
+
+  CephContext *cct = m_local_image_ctx->cct;
+  ldout(cct, 20) << dendl;
+
+  Context *ctx = create_context_callback<
+    ImageSync<I>, &ImageSync<I>::handle_copy_image>(this);
+  m_image_copy_request = ImageCopyRequest<I>::create(
+    m_local_image_ctx, m_remote_image_ctx, m_timer, m_timer_lock,
+    m_journaler, m_client_meta, &m_client_meta->sync_points.front(),
+    ctx);
+  m_lock.Unlock();
+
+  m_image_copy_request->send();
+}
+
+template <typename I>
+void ImageSync<I>::handle_copy_image(int r) {
+  {
+    Mutex::Locker locker(m_lock);
+    m_image_copy_request = nullptr;
+    if (r == 0 && m_canceled) {
+      r = -ECANCELED;
+    }
+  }
+
+  CephContext *cct = m_local_image_ctx->cct;
+  ldout(cct, 20) << ": r=" << r << dendl;
+
+  if (r == -ECANCELED) {
+    ldout(cct, 10) << "image copy canceled" << dendl;
+    finish(r);
+    return;
+  } else if (r < 0) {
+    lderr(cct) << "failed to copy image: " << cpp_strerror(r) << dendl;
+    finish(r);
+    return;
+  }
+
+  send_copy_object_map();
+}
+
+template <typename I>
+void ImageSync<I>::send_copy_object_map() {
+  m_local_image_ctx->snap_lock.get_read();
+  if (!m_local_image_ctx->test_features(RBD_FEATURE_OBJECT_MAP,
+                                        m_local_image_ctx->snap_lock)) {
+    m_local_image_ctx->snap_lock.put_read();
+    send_prune_sync_points();
+    return;
+  }
+
+  assert(m_local_image_ctx->object_map != nullptr);
+
+  assert(!m_client_meta->sync_points.empty());
+  librbd::journal::MirrorPeerSyncPoint &sync_point =
+    m_client_meta->sync_points.front();
+  auto snap_id_it = m_local_image_ctx->snap_ids.find(sync_point.snap_name);
+  assert(snap_id_it != m_local_image_ctx->snap_ids.end());
+  librados::snap_t snap_id = snap_id_it->second;
+
+  CephContext *cct = m_local_image_ctx->cct;
+  ldout(cct, 20) << ": snap_id=" << snap_id << ", "
+                 << "snap_name=" << sync_point.snap_name << dendl;
+
+  // rollback the object map (copy snapshot object map to HEAD)
+  RWLock::WLocker object_map_locker(m_local_image_ctx->object_map_lock);
+  Context *ctx = create_context_callback<
+    ImageSync<I>, &ImageSync<I>::handle_copy_object_map>(this);
+  m_local_image_ctx->object_map->rollback(snap_id, ctx);
+  m_local_image_ctx->snap_lock.put_read();
+}
+
+template <typename I>
+void ImageSync<I>::handle_copy_object_map(int r) {
+  CephContext *cct = m_local_image_ctx->cct;
+  ldout(cct, 20) << dendl;
+
+  assert(r == 0);
+  send_refresh_object_map();
+}
+
+template <typename I>
+void ImageSync<I>::send_refresh_object_map() {
+  CephContext *cct = m_local_image_ctx->cct;
+  ldout(cct, 20) << dendl;
+
+  Context *ctx = create_context_callback<
+    ImageSync<I>, &ImageSync<I>::handle_refresh_object_map>(this);
+  m_object_map = m_local_image_ctx->create_object_map(CEPH_NOSNAP);
+  m_object_map->open(ctx);
+}
+
+template <typename I>
+void ImageSync<I>::handle_refresh_object_map(int r) {
+  CephContext *cct = m_local_image_ctx->cct;
+  ldout(cct, 20) << dendl;
+
+  assert(r == 0);
+  {
+    RWLock::WLocker snap_locker(m_local_image_ctx->snap_lock);
+    std::swap(m_local_image_ctx->object_map, m_object_map);
+  }
+  delete m_object_map;
+
+  send_prune_sync_points();
+}
+
+template <typename I>
+void ImageSync<I>::send_prune_sync_points() {
+  CephContext *cct = m_local_image_ctx->cct;
+  ldout(cct, 20) << dendl;
+
+  Context *ctx = create_context_callback<
+    ImageSync<I>, &ImageSync<I>::handle_prune_sync_points>(this);
+  SyncPointPruneRequest<I> *request = SyncPointPruneRequest<I>::create(
+    m_remote_image_ctx, true, m_journaler, m_client_meta, ctx);
+  request->send();
+}
+
+template <typename I>
+void ImageSync<I>::handle_prune_sync_points(int r) {
+  CephContext *cct = m_local_image_ctx->cct;
+  ldout(cct, 20) << ": r=" << r << dendl;
+
+  if (r < 0) {
+    lderr(cct) << "failed to prune sync point: "
+               << cpp_strerror(r) << dendl;
+    finish(r);
+    return;
+  }
+
+  if (!m_client_meta->sync_points.empty()) {
+    send_copy_image();
+    return;
+  }
+
+  finish(0);
+}
+
+template <typename I>
+void ImageSync<I>::finish(int r) {
+  CephContext *cct = m_local_image_ctx->cct;
+  ldout(cct, 20) << ": r=" << r << dendl;
+
+  m_on_finish->complete(r);
+  delete this;
+}
+
+} // namespace mirror
+} // namespace rbd
+
+template class rbd::mirror::ImageSync<librbd::ImageCtx>;
diff --git a/src/tools/rbd_mirror/ImageSync.h b/src/tools/rbd_mirror/ImageSync.h
new file mode 100644
index 0000000..175cb78
--- /dev/null
+++ b/src/tools/rbd_mirror/ImageSync.h
@@ -0,0 +1,122 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+
+#ifndef RBD_MIRROR_IMAGE_SYNC_H
+#define RBD_MIRROR_IMAGE_SYNC_H
+
+#include "include/int_types.h"
+#include "librbd/ImageCtx.h"
+#include "librbd/Journal.h"
+#include "common/Mutex.h"
+#include <map>
+#include <vector>
+
+class Context;
+class Mutex;
+class SafeTimer;
+namespace journal { class Journaler; }
+namespace librbd { namespace journal { struct MirrorPeerClientMeta; } }
+
+namespace rbd {
+namespace mirror {
+
+namespace image_sync { template <typename> class ImageCopyRequest; }
+
+template <typename ImageCtxT = librbd::ImageCtx>
+class ImageSync {
+public:
+  typedef librbd::journal::TypeTraits<ImageCtxT> TypeTraits;
+  typedef typename TypeTraits::Journaler Journaler;
+  typedef librbd::journal::MirrorPeerClientMeta MirrorPeerClientMeta;
+
+  ImageSync(ImageCtxT *local_image_ctx, ImageCtxT *remote_image_ctx,
+            SafeTimer *timer, Mutex *timer_lock, const std::string &mirror_uuid,
+            Journaler *journaler, MirrorPeerClientMeta *client_meta,
+            Context *on_finish);
+
+  void start();
+  void cancel();
+
+private:
+  /**
+   * @verbatim
+   *
+   * <start>
+   *    |
+   *    v
+   * PRUNE_CATCH_UP_SYNC_POINT
+   *    |
+   *    v
+   * CREATE_SYNC_POINT (skip if already exists and
+   *    |               not disconnected)
+   *    v
+   * COPY_SNAPSHOTS
+   *    |
+   *    v
+   * COPY_IMAGE . . . . . . . . . . . . . .
+   *    |                                 .
+   *    v                                 .
+   * COPY_OBJECT_MAP (skip if object      .
+   *    |             map disabled)       .
+   *    v                                 .
+   * REFRESH_OBJECT_MAP (skip if object   .
+   *    |                map disabled)    .
+   *    v
+   * PRUNE_SYNC_POINTS                    . (image sync canceled)
+   *    |                                 .
+   *    v                                 .
+   * <finish> < . . . . . . . . . . . . . .
+   *
+   * @endverbatim
+   */
+
+  typedef std::vector<librados::snap_t> SnapIds;
+  typedef std::map<librados::snap_t, SnapIds> SnapMap;
+
+  ImageCtxT *m_local_image_ctx;
+  ImageCtxT *m_remote_image_ctx;
+  SafeTimer *m_timer;
+  Mutex *m_timer_lock;
+  std::string m_mirror_uuid;
+  Journaler *m_journaler;
+  MirrorPeerClientMeta *m_client_meta;
+  Context *m_on_finish;
+
+  SnapMap m_snap_map;
+
+  Mutex m_lock;
+  bool m_canceled = false;
+
+  image_sync::ImageCopyRequest<ImageCtxT> *m_image_copy_request;
+  decltype(ImageCtxT::object_map) m_object_map = nullptr;
+
+  void send_prune_catch_up_sync_point();
+  void handle_prune_catch_up_sync_point(int r);
+
+  void send_create_sync_point();
+  void handle_create_sync_point(int r);
+
+  void send_copy_snapshots();
+  void handle_copy_snapshots(int r);
+
+  void send_copy_image();
+  void handle_copy_image(int r);
+
+  void send_copy_object_map();
+  void handle_copy_object_map(int r);
+
+  void send_refresh_object_map();
+  void handle_refresh_object_map(int r);
+
+  void send_prune_sync_points();
+  void handle_prune_sync_points(int r);
+
+  void finish(int r);
+};
+
+} // namespace mirror
+} // namespace rbd
+
+extern template class rbd::mirror::ImageSync<librbd::ImageCtx>;
+
+#endif // RBD_MIRROR_IMAGE_SYNC_H
diff --git a/src/tools/rbd_mirror/Mirror.cc b/src/tools/rbd_mirror/Mirror.cc
index 67111b0..2ce0177 100644
--- a/src/tools/rbd_mirror/Mirror.cc
+++ b/src/tools/rbd_mirror/Mirror.cc
@@ -6,10 +6,11 @@
 #include "common/debug.h"
 #include "common/errno.h"
 #include "Mirror.h"
+#include "Threads.h"
 
 #define dout_subsys ceph_subsys_rbd_mirror
 #undef dout_prefix
-#define dout_prefix *_dout << "rbd-mirror: "
+#define dout_prefix *_dout << "rbd-mirror: Mirror::" << __func__ << ": "
 
 using std::chrono::seconds;
 using std::list;
@@ -26,16 +27,23 @@ using librbd::mirror_peer_t;
 namespace rbd {
 namespace mirror {
 
-Mirror::Mirror(CephContext *cct) :
+Mirror::Mirror(CephContext *cct, const std::vector<const char*> &args) :
   m_cct(cct),
+  m_args(args),
   m_lock("rbd::mirror::Mirror"),
   m_local(new librados::Rados())
 {
+  cct->lookup_or_create_singleton_object<Threads>(m_threads,
+                                                  "rbd_mirror::threads");
 }
 
 void Mirror::handle_signal(int signum)
 {
   m_stopping.set(1);
+  {
+    Mutex::Locker l(m_lock);
+    m_cond.Signal();
+  }
 }
 
 int Mirror::init()
@@ -60,6 +68,7 @@ int Mirror::init()
 
 void Mirror::run()
 {
+  dout(20) << "enter" << dendl;
   while (!m_stopping.read()) {
     m_local_cluster_watcher->refresh_pools();
     Mutex::Locker l(m_lock);
@@ -67,16 +76,19 @@ void Mirror::run()
     // TODO: make interval configurable
     m_cond.WaitInterval(g_ceph_context, m_lock, seconds(30));
   }
+  dout(20) << "return" << dendl;
 }
 
 void Mirror::update_replayers(const map<peer_t, set<int64_t> > &peer_configs)
 {
+  dout(20) << "enter" << dendl;
   assert(m_lock.is_locked());
-  set<peer_t> peers;
   for (auto &kv : peer_configs) {
     const peer_t &peer = kv.first;
     if (m_replayers.find(peer) == m_replayers.end()) {
-      unique_ptr<Replayer> replayer(new Replayer(m_local, peer));
+      dout(20) << "starting replayer for " << peer << dendl;
+      unique_ptr<Replayer> replayer(new Replayer(m_threads, m_local, peer,
+						 m_args));
       // TODO: make async, and retry connecting within replayer
       int r = replayer->init();
       if (r < 0) {
@@ -89,7 +101,8 @@ void Mirror::update_replayers(const map<peer_t, set<int64_t> > &peer_configs)
   // TODO: make async
   for (auto it = m_replayers.begin(); it != m_replayers.end();) {
     peer_t peer = it->first;
-    if (peers.find(peer) == peers.end()) {
+    if (peer_configs.find(peer) == peer_configs.end()) {
+      dout(20) << "removing replayer for " << peer << dendl;
       m_replayers.erase(it++);
     } else {
       ++it;
diff --git a/src/tools/rbd_mirror/Mirror.h b/src/tools/rbd_mirror/Mirror.h
index cafbdd8..6b6cc97 100644
--- a/src/tools/rbd_mirror/Mirror.h
+++ b/src/tools/rbd_mirror/Mirror.h
@@ -19,6 +19,8 @@
 namespace rbd {
 namespace mirror {
 
+struct Threads;
+
 /**
  * Contains the main loop and overall state for rbd-mirror.
  *
@@ -27,7 +29,7 @@ namespace mirror {
  */
 class Mirror {
 public:
-  Mirror(CephContext *cct);
+  Mirror(CephContext *cct, const std::vector<const char*> &args);
   Mirror(const Mirror&) = delete;
   Mirror& operator=(const Mirror&) = delete;
 
@@ -40,6 +42,8 @@ private:
   void update_replayers(const map<peer_t, set<int64_t> > &peer_configs);
 
   CephContext *m_cct;
+  std::vector<const char*> m_args;
+  Threads *m_threads = nullptr;
   Mutex m_lock;
   Cond m_cond;
   RadosRef m_local;
diff --git a/src/tools/rbd_mirror/PoolWatcher.cc b/src/tools/rbd_mirror/PoolWatcher.cc
index 480df57..74b54cd 100644
--- a/src/tools/rbd_mirror/PoolWatcher.cc
+++ b/src/tools/rbd_mirror/PoolWatcher.cc
@@ -14,7 +14,7 @@
 
 #define dout_subsys ceph_subsys_rbd_mirror
 #undef dout_prefix
-#define dout_prefix *_dout << "rbd-mirror: "
+#define dout_prefix *_dout << "rbd-mirror: PoolWatcher::" << __func__ << ": "
 
 using std::list;
 using std::map;
@@ -25,7 +25,7 @@ using std::vector;
 
 using librados::Rados;
 using librados::IoCtx;
-using librbd::cls_client::dir_list;
+using librbd::cls_client::mirror_image_list;
 
 namespace rbd {
 namespace mirror {
@@ -36,7 +36,7 @@ PoolWatcher::PoolWatcher(RadosRef cluster, double interval_seconds,
   m_refresh_cond(cond),
   m_stopping(false),
   m_cluster(cluster),
-  m_timer(g_ceph_context, m_lock),
+  m_timer(g_ceph_context, m_lock, false),
   m_interval(interval_seconds)
 {
   m_timer.init();
@@ -57,7 +57,7 @@ const map<int64_t, set<string> >& PoolWatcher::get_images() const
 
 void PoolWatcher::refresh_images(bool reschedule)
 {
-  dout(20) << __func__ << dendl;
+  dout(20) << "enter" << dendl;
   map<int64_t, set<string> > images;
   list<pair<int64_t, string> > pools;
   int r = m_cluster->pool_list2(pools);
@@ -93,46 +93,31 @@ void PoolWatcher::refresh_images(bool reschedule)
       continue;
     }
 
-    // TODO: read mirrored images from mirroring settings object. For
-    // now just treat all images in a pool with mirroring enabled as mirrored
-    bool enabled;
-    r = librbd::mirror_is_enabled(ioctx, &enabled);
+    rbd_mirror_mode_t mirror_mode;
+    r = librbd::mirror_mode_get(ioctx, &mirror_mode);
     if (r < 0) {
       derr << "could not tell whether mirroring was enabled for " << pool_name
 	   << " : " << cpp_strerror(r) << dendl;
       continue;
     }
-    if (!enabled) {
+    if (mirror_mode == RBD_MIRROR_MODE_DISABLED) {
       dout(20) << "pool " << pool_name << " has mirroring disabled" << dendl;
       continue;
     }
 
-    set<string> image_ids;
-
     // only format 2 images can be mirrored, so only check the format
     // 2 rbd_directory structure
-    int max_read = 1024;
-    string last_read = "";
-    do {
-      map<string, string> pool_images;
-      r = dir_list(&ioctx, RBD_DIRECTORY,
-		   last_read, max_read, &pool_images);
-      if (r < 0) {
-        derr << "error listing images in pool " << pool_name << ": "
-	     << cpp_strerror(r) << dendl;
-        continue;
-      }
-      for (auto& pair : pool_images) {
-	image_ids.insert(pair.second);
-      }
-      if (!pool_images.empty()) {
-	last_read = pool_images.rbegin()->first;
-      }
-      r = pool_images.size();
-    } while (r == max_read);
-
-    if (r > 0) {
-      images[pool_id] = std::move(image_ids);
+    std::vector<std::string> image_ids;
+    r = mirror_image_list(&ioctx, &image_ids);
+    if (r < 0) {
+      derr << "error listing mirrored images in pool " << pool_name << ": "
+           << cpp_strerror(r) << dendl;
+      continue;
+    }
+
+    if (!image_ids.empty()) {
+      std::set<std::string> image_set(image_ids.begin(), image_ids.end());
+      images[pool_id] = std::move(image_set);
     }
   }
 
diff --git a/src/tools/rbd_mirror/Replayer.cc b/src/tools/rbd_mirror/Replayer.cc
index e787187..620a6a8 100644
--- a/src/tools/rbd_mirror/Replayer.cc
+++ b/src/tools/rbd_mirror/Replayer.cc
@@ -10,7 +10,7 @@
 
 #define dout_subsys ceph_subsys_rbd_mirror
 #undef dout_prefix
-#define dout_prefix *_dout << "rbd-mirror: "
+#define dout_prefix *_dout << "rbd-mirror: Replayer::" << __func__ << ": "
 
 using std::chrono::seconds;
 using std::map;
@@ -21,9 +21,12 @@ using std::vector;
 namespace rbd {
 namespace mirror {
 
-Replayer::Replayer(RadosRef local_cluster, const peer_t &peer) :
+Replayer::Replayer(Threads *threads, RadosRef local_cluster,
+                   const peer_t &peer, const std::vector<const char*> &args) :
+  m_threads(threads),
   m_lock(stringify("rbd::mirror::Replayer ") + stringify(peer)),
   m_peer(peer),
+  m_args(args),
   m_local(local_cluster),
   m_remote(new librados::Rados),
   m_replayer_thread(this)
@@ -37,12 +40,14 @@ Replayer::~Replayer()
     Mutex::Locker l(m_lock);
     m_cond.Signal();
   }
-  m_replayer_thread.join();
+  if (m_replayer_thread.is_started()) {
+    m_replayer_thread.join();
+  }
 }
 
 int Replayer::init()
 {
-  dout(20) << __func__ << "Replaying for " << m_peer << dendl;
+  dout(20) << "replaying for " << m_peer << dendl;
 
   int r = m_remote->init2(m_peer.client_name.c_str(),
 			  m_peer.cluster_name.c_str(), 0);
@@ -59,62 +64,98 @@ int Replayer::init()
     return r;
   }
 
-  r = m_remote->connect();
+  r = m_remote->conf_parse_env(nullptr);
   if (r < 0) {
-    derr << "error connecting to remote cluster " << m_peer
+    derr << "could not parse environment for " << m_peer
 	 << " : " << cpp_strerror(r) << dendl;
     return r;
   }
 
-  string cluster_uuid;
-  r = m_remote->cluster_fsid(&cluster_uuid);
+  if (!m_args.empty()) {
+    r = m_remote->conf_parse_argv(m_args.size(), &m_args[0]);
+    if (r < 0) {
+      derr << "could not parse command line args for " << m_peer
+	   << " : " << cpp_strerror(r) << dendl;
+      return r;
+    }
+  }
+
+  r = m_remote->connect();
   if (r < 0) {
-    derr << "error reading cluster uuid from remote cluster " << m_peer
+    derr << "error connecting to remote cluster " << m_peer
 	 << " : " << cpp_strerror(r) << dendl;
     return r;
   }
 
-  if (cluster_uuid != m_peer.cluster_uuid) {
-    derr << "configured cluster uuid does not match actual cluster uuid. "
-	 << "expected: " << m_peer.cluster_uuid
-	 << " observed: " << cluster_uuid << dendl;
-    return -EINVAL;
-  }
+  dout(20) << "connected to " << m_peer << dendl;
 
-  dout(20) << __func__ << "connected to " << m_peer << dendl;
+  std::string uuid;
+  r = m_local->cluster_fsid(&uuid);
+  if (r < 0) {
+    derr << "error retrieving local cluster uuid: " << cpp_strerror(r)
+	 << dendl;
+    return r;
+  }
+  m_client_id = uuid;
 
   // TODO: make interval configurable
   m_pool_watcher.reset(new PoolWatcher(m_remote, 30, m_lock, m_cond));
   m_pool_watcher->refresh_images();
 
+  m_replayer_thread.create("replayer");
+
   return 0;
 }
 
 void Replayer::run()
 {
+  dout(20) << "enter" << dendl;
+
   while (!m_stopping.read()) {
     Mutex::Locker l(m_lock);
     set_sources(m_pool_watcher->get_images());
     m_cond.WaitInterval(g_ceph_context, m_lock, seconds(30));
   }
+
+  // Stopping
+  map<int64_t, set<string> > empty_sources;
+  while (true) {
+    Mutex::Locker l(m_lock);
+    set_sources(empty_sources);
+    if (m_images.empty()) {
+      break;
+    }
+    m_cond.WaitInterval(g_ceph_context, m_lock, seconds(1));
+  }
 }
 
 void Replayer::set_sources(const map<int64_t, set<string> > &images)
 {
+  dout(20) << "enter" << dendl;
+
   assert(m_lock.is_locked());
-  // TODO: make stopping and starting ImageReplayers async
   for (auto it = m_images.begin(); it != m_images.end();) {
     int64_t pool_id = it->first;
     auto &pool_images = it->second;
     if (images.find(pool_id) == images.end()) {
-      m_images.erase(it++);
+      for (auto images_it = pool_images.begin();
+	   images_it != pool_images.end();) {
+	if (stop_image_replayer(images_it->second)) {
+	  pool_images.erase(images_it++);
+	}
+      }
+      if (pool_images.empty()) {
+	m_images.erase(it++);
+      }
       continue;
     }
     for (auto images_it = pool_images.begin();
 	 images_it != pool_images.end();) {
       if (images.at(pool_id).find(images_it->first) ==
 	  images.at(pool_id).end()) {
-	pool_images.erase(images_it++);
+	if (stop_image_replayer(images_it->second)) {
+	  pool_images.erase(images_it++);
+	}
       } else {
 	++images_it;
       }
@@ -124,23 +165,67 @@ void Replayer::set_sources(const map<int64_t, set<string> > &images)
 
   for (const auto &kv : images) {
     int64_t pool_id = kv.first;
+
+    // TODO: clean up once remote peer -> image replayer refactored
+    librados::IoCtx remote_ioctx;
+    int r = m_remote->ioctx_create2(pool_id, remote_ioctx);
+    if (r < 0) {
+      derr << "failed to lookup remote pool " << pool_id << ": "
+           << cpp_strerror(r) << dendl;
+      continue;
+    }
+
+    librados::IoCtx local_ioctx;
+    r = m_local->ioctx_create(remote_ioctx.get_pool_name().c_str(), local_ioctx);
+    if (r < 0) {
+      derr << "failed to lookup local pool " << remote_ioctx.get_pool_name()
+           << ": " << cpp_strerror(r) << dendl;
+      continue;
+    }
+
     // create entry for pool if it doesn't exist
     auto &pool_replayers = m_images[pool_id];
     for (const auto &image_id : kv.second) {
-      if (pool_replayers.find(image_id) == pool_replayers.end()) {
-	unique_ptr<ImageReplayer> image_replayer(new ImageReplayer(m_local,
+      auto it = pool_replayers.find(image_id);
+      if (it == pool_replayers.end()) {
+	unique_ptr<ImageReplayer> image_replayer(new ImageReplayer(m_threads,
+								   m_local,
 								   m_remote,
+								   m_client_id,
+								   local_ioctx.get_id(),
 								   pool_id,
 								   image_id));
-	int r = image_replayer->start();
-	if (r < 0) {
-	  continue;
-	}
-	pool_replayers.insert(std::make_pair(image_id, std::move(image_replayer)));
+	it = pool_replayers.insert(
+	  std::make_pair(image_id, std::move(image_replayer))).first;
       }
+      start_image_replayer(it->second);
     }
   }
 }
 
+void Replayer::start_image_replayer(unique_ptr<ImageReplayer> &image_replayer)
+{
+  if (!image_replayer->is_stopped()) {
+    return;
+  }
+
+  image_replayer->start();
+}
+
+bool Replayer::stop_image_replayer(unique_ptr<ImageReplayer> &image_replayer)
+{
+  if (image_replayer->is_stopped()) {
+    return true;
+  }
+
+  if (image_replayer->is_running()) {
+    image_replayer->stop();
+  } else {
+    // TODO: check how long it is stopping and alert if it is too long.
+  }
+
+  return false;
+}
+
 } // namespace mirror
 } // namespace rbd
diff --git a/src/tools/rbd_mirror/Replayer.h b/src/tools/rbd_mirror/Replayer.h
index ca4d3e7..83748b9 100644
--- a/src/tools/rbd_mirror/Replayer.h
+++ b/src/tools/rbd_mirror/Replayer.h
@@ -23,12 +23,15 @@
 namespace rbd {
 namespace mirror {
 
+struct Threads;
+
 /**
  * Controls mirroring for a single remote cluster.
  */
 class Replayer {
 public:
-  Replayer(RadosRef local_cluster, const peer_t &peer);
+  Replayer(Threads *threads, RadosRef local_cluster, const peer_t &peer,
+	   const std::vector<const char*> &args);
   ~Replayer();
   Replayer(const Replayer&) = delete;
   Replayer& operator=(const Replayer&) = delete;
@@ -40,11 +43,17 @@ public:
 private:
   void set_sources(const std::map<int64_t, std::set<std::string> > &images);
 
+  void start_image_replayer(unique_ptr<ImageReplayer> &image_replayer);
+  bool stop_image_replayer(unique_ptr<ImageReplayer> &image_replayer);
+
+  Threads *m_threads;
   Mutex m_lock;
   Cond m_cond;
   atomic_t m_stopping;
 
   peer_t m_peer;
+  std::vector<const char*> m_args;
+  std::string m_client_id;
   RadosRef m_local, m_remote;
   std::unique_ptr<PoolWatcher> m_pool_watcher;
   // index by pool so it's easy to tell what is affected
diff --git a/src/tools/rbd_mirror/Threads.cc b/src/tools/rbd_mirror/Threads.cc
new file mode 100644
index 0000000..8fa7d6d
--- /dev/null
+++ b/src/tools/rbd_mirror/Threads.cc
@@ -0,0 +1,38 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+
+#include "tools/rbd_mirror/Threads.h"
+#include "common/Timer.h"
+#include "common/WorkQueue.h"
+
+namespace rbd {
+namespace mirror {
+
+Threads::Threads(CephContext *cct) : timer_lock("Threads::timer_lock") {
+  thread_pool = new ThreadPool(cct, "Journaler::thread_pool", "tp_journal",
+                               cct->_conf->rbd_op_threads, "rbd_op_threads");
+  thread_pool->start();
+
+  work_queue = new ContextWQ("Journaler::work_queue",
+                             cct->_conf->rbd_op_thread_timeout, thread_pool);
+
+  timer = new SafeTimer(cct, timer_lock, true);
+  timer->init();
+}
+
+Threads::~Threads() {
+  {
+    Mutex::Locker timer_locker(timer_lock);
+    timer->shutdown();
+  }
+  delete timer;
+
+  work_queue->drain();
+  delete work_queue;
+
+  thread_pool->stop();
+  delete thread_pool;
+}
+
+} // namespace mirror
+} // namespace rbd
diff --git a/src/tools/rbd_mirror/Threads.h b/src/tools/rbd_mirror/Threads.h
new file mode 100644
index 0000000..ba95283
--- /dev/null
+++ b/src/tools/rbd_mirror/Threads.h
@@ -0,0 +1,34 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+
+#ifndef CEPH_RBD_MIRROR_THREADS_H
+#define CEPH_RBD_MIRROR_THREADS_H
+
+#include "common/Mutex.h"
+
+class CephContext;
+class ContextWQ;
+class SafeTimer;
+class ThreadPool;
+
+namespace rbd {
+namespace mirror {
+
+struct Threads {
+  ThreadPool *thread_pool = nullptr;
+  ContextWQ *work_queue = nullptr;
+
+  SafeTimer *timer = nullptr;
+  Mutex timer_lock;
+
+  explicit Threads(CephContext *cct);
+  Threads(const Threads&) = delete;
+  Threads& operator=(const Threads&) = delete;
+
+  ~Threads();
+};
+
+} // namespace mirror
+} // namespace rbd
+
+#endif // CEPH_RBD_MIRROR_THREADS_H
diff --git a/src/tools/rbd_mirror/image_replayer/BootstrapRequest.cc b/src/tools/rbd_mirror/image_replayer/BootstrapRequest.cc
new file mode 100644
index 0000000..4260c02
--- /dev/null
+++ b/src/tools/rbd_mirror/image_replayer/BootstrapRequest.cc
@@ -0,0 +1,302 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+
+#include "BootstrapRequest.h"
+#include "CloseImageRequest.h"
+#include "OpenLocalImageRequest.h"
+#include "common/debug.h"
+#include "common/dout.h"
+#include "common/errno.h"
+#include "common/WorkQueue.h"
+#include "journal/Journaler.h"
+#include "librbd/ImageCtx.h"
+#include "librbd/ImageState.h"
+#include "librbd/internal.h"
+#include "librbd/Utils.h"
+#include "tools/rbd_mirror/ImageSync.h"
+
+#define dout_subsys ceph_subsys_rbd_mirror
+#undef dout_prefix
+#define dout_prefix *_dout << "rbd::mirror::image_replayer::BootstrapRequest: " \
+                           << this << " " << __func__
+
+namespace rbd {
+namespace mirror {
+namespace image_replayer {
+
+using librbd::util::create_context_callback;
+
+namespace {
+
+template <typename I>
+struct C_CreateImage : public Context {
+  librados::IoCtx &local_io_ctx;
+  std::string local_image_name;
+  I *remote_image_ctx;
+  Context *on_finish;
+
+  C_CreateImage(librados::IoCtx &local_io_ctx,
+                const std::string &local_image_name, I *remote_image_ctx,
+                Context *on_finish)
+    : local_io_ctx(local_io_ctx), local_image_name(local_image_name),
+      remote_image_ctx(remote_image_ctx), on_finish(on_finish) {
+  }
+
+  virtual void finish(int r) override {
+    assert(r == 0);
+
+    // TODO: rbd-mirror should offer a feature mask capability
+    RWLock::RLocker snap_locker(remote_image_ctx->snap_lock);
+    int order = remote_image_ctx->order;
+    r = librbd::create(local_io_ctx, local_image_name.c_str(),
+                       remote_image_ctx->size, false,
+                       remote_image_ctx->features, &order,
+                       remote_image_ctx->stripe_unit,
+                       remote_image_ctx->stripe_count);
+    on_finish->complete(r);
+  }
+};
+
+} // anonymous namespace
+
+template <typename I>
+BootstrapRequest<I>::BootstrapRequest(librados::IoCtx &local_io_ctx,
+                                      librados::IoCtx &remote_io_ctx,
+                                      I **local_image_ctx,
+                                      const std::string &local_image_name,
+                                      const std::string &remote_image_id,
+                                      ContextWQ *work_queue, SafeTimer *timer,
+                                      Mutex *timer_lock,
+                                      const std::string &mirror_uuid,
+                                      Journaler *journaler,
+                                      MirrorPeerClientMeta *client_meta,
+                                      Context *on_finish)
+  : m_local_io_ctx(local_io_ctx), m_remote_io_ctx(remote_io_ctx),
+    m_local_image_ctx(local_image_ctx), m_local_image_name(local_image_name),
+    m_remote_image_id(remote_image_id), m_work_queue(work_queue),
+    m_timer(timer), m_timer_lock(timer_lock), m_mirror_uuid(mirror_uuid),
+    m_journaler(journaler), m_client_meta(client_meta), m_on_finish(on_finish) {
+}
+
+template <typename I>
+BootstrapRequest<I>::~BootstrapRequest() {
+  assert(m_remote_image_ctx == nullptr);
+}
+
+template <typename I>
+void BootstrapRequest<I>::send() {
+  open_remote_image();
+}
+
+template <typename I>
+void BootstrapRequest<I>::open_remote_image() {
+  dout(20) << dendl;
+
+  // TODO: need factory method to support mocking
+  m_remote_image_ctx = new I("", m_remote_image_id, nullptr, m_remote_io_ctx,
+                             false);
+
+  Context *ctx = create_context_callback<
+    BootstrapRequest<I>, &BootstrapRequest<I>::handle_open_remote_image>(
+      this);
+  m_remote_image_ctx->state->open(ctx);
+}
+
+template <typename I>
+void BootstrapRequest<I>::handle_open_remote_image(int r) {
+  dout(20) << ": r=" << r << dendl;
+
+  if (r < 0) {
+    derr << "failed to open remote image: " << cpp_strerror(r) << dendl;
+    m_ret_val = r;
+    close_remote_image();
+    return;
+  }
+
+  create_local_image();
+}
+
+template <typename I>
+void BootstrapRequest<I>::create_local_image() {
+  dout(20) << dendl;
+
+  // TODO: local image might already exist (e.g. interrupted sync)
+  //       need to determine what type of bootstrap we are performing
+
+  // TODO: librbd should provide an AIO image creation method -- this is
+  //       blocking so we execute in our worker thread
+  Context *ctx = create_context_callback<
+    BootstrapRequest<I>, &BootstrapRequest<I>::handle_create_local_image>(
+      this);
+  m_work_queue->queue(new C_CreateImage<I>(m_local_io_ctx, m_local_image_name,
+                                           m_remote_image_ctx, ctx), 0);
+}
+
+template <typename I>
+void BootstrapRequest<I>::handle_create_local_image(int r) {
+  dout(20) << ": r=" << r << dendl;
+
+  if (r < 0) {
+    derr << "failed to create local image: " << cpp_strerror(r) << dendl;
+    m_ret_val = r;
+    close_remote_image();
+    return;
+  }
+
+  open_local_image();
+}
+
+template <typename I>
+void BootstrapRequest<I>::open_local_image() {
+  dout(20) << dendl;
+
+  Context *ctx = create_context_callback<
+    BootstrapRequest<I>, &BootstrapRequest<I>::handle_open_local_image>(
+      this);
+  OpenLocalImageRequest<I> *request = OpenLocalImageRequest<I>::create(
+    m_local_io_ctx, m_local_image_ctx, m_local_image_name, "", m_work_queue,
+    ctx);
+  request->send();
+}
+
+template <typename I>
+void BootstrapRequest<I>::handle_open_local_image(int r) {
+  dout(20) << ": r=" << r << dendl;
+
+  if (r < 0) {
+    assert(*m_local_image_ctx == nullptr);
+    derr << "failed to open local image: " << cpp_strerror(r) << dendl;
+    m_ret_val = r;
+    close_remote_image();
+    return;
+  }
+
+  register_client();
+}
+
+template <typename I>
+void BootstrapRequest<I>::register_client() {
+  dout(20) << dendl;
+
+  // TODO: if client fails to register newly created image to journal,
+  //       need to ensure we can recover (i.e. see if image of the same
+  //       name already exists)
+
+  librbd::journal::MirrorPeerClientMeta client_meta(*m_client_meta);
+  client_meta.image_id = (*m_local_image_ctx)->id;
+
+  librbd::journal::ClientData client_data(client_meta);
+  bufferlist client_data_bl;
+  ::encode(client_data, client_data_bl);
+
+  Context *ctx = create_context_callback<
+    BootstrapRequest<I>, &BootstrapRequest<I>::handle_register_client>(
+      this);
+  m_journaler->register_client(client_data_bl, ctx);
+}
+
+template <typename I>
+void BootstrapRequest<I>::handle_register_client(int r) {
+  dout(20) << ": r=" << r << dendl;
+
+  if (r < 0) {
+    derr << "failed to register with remote journal: " << cpp_strerror(r)
+         << dendl;
+    close_local_image();
+    return;
+  }
+
+  m_client_meta->image_id = (*m_local_image_ctx)->id;
+  image_sync();
+}
+
+template <typename I>
+void BootstrapRequest<I>::image_sync() {
+  dout(20) << dendl;
+
+  // TODO: need factory method to support mocking
+  Context *ctx = create_context_callback<
+    BootstrapRequest<I>, &BootstrapRequest<I>::handle_image_sync>(
+      this);
+  ImageSync<I> *request = new ImageSync<I>(*m_local_image_ctx,
+                                           m_remote_image_ctx, m_timer,
+                                           m_timer_lock, m_mirror_uuid,
+                                           m_journaler, m_client_meta, ctx);
+  request->start();
+}
+
+template <typename I>
+void BootstrapRequest<I>::handle_image_sync(int r) {
+  dout(20) << ": r=" << r << dendl;
+
+  if (r < 0) {
+    derr << "failed to sync remote image: " << cpp_strerror(r) << dendl;
+    m_ret_val = r;
+    close_local_image();
+    return;
+  }
+
+  close_remote_image();
+}
+
+template <typename I>
+void BootstrapRequest<I>::close_local_image() {
+  dout(20) << dendl;
+
+  Context *ctx = create_context_callback<
+    BootstrapRequest<I>, &BootstrapRequest<I>::handle_close_local_image>(
+      this);
+  CloseImageRequest<I> *request = CloseImageRequest<I>::create(
+    m_local_image_ctx, m_work_queue, ctx);
+  request->send();
+}
+
+template <typename I>
+void BootstrapRequest<I>::handle_close_local_image(int r) {
+  dout(20) << ": r=" << r << dendl;
+
+  if (r < 0) {
+    derr << "error encountered closing local image: " << cpp_strerror(r)
+         << dendl;
+  }
+
+  close_remote_image();
+}
+
+template <typename I>
+void BootstrapRequest<I>::close_remote_image() {
+  dout(20) << dendl;
+
+  Context *ctx = create_context_callback<
+    BootstrapRequest<I>, &BootstrapRequest<I>::handle_close_remote_image>(
+      this);
+  CloseImageRequest<I> *request = CloseImageRequest<I>::create(
+    &m_remote_image_ctx, m_work_queue, ctx);
+  request->send();
+}
+
+template <typename I>
+void BootstrapRequest<I>::handle_close_remote_image(int r) {
+  dout(20) << ": r=" << r << dendl;
+
+  if (r < 0) {
+    derr << "error encountered closing remote image: " << cpp_strerror(r)
+         << dendl;
+  }
+
+  finish(m_ret_val);
+}
+
+template <typename I>
+void BootstrapRequest<I>::finish(int r) {
+  dout(20) << ": r=" << r << dendl;
+
+  m_on_finish->complete(r);
+  delete this;
+}
+
+} // namespace image_replayer
+} // namespace mirror
+} // namespace rbd
+
+template class rbd::mirror::image_replayer::BootstrapRequest<librbd::ImageCtx>;
diff --git a/src/tools/rbd_mirror/image_replayer/BootstrapRequest.h b/src/tools/rbd_mirror/image_replayer/BootstrapRequest.h
new file mode 100644
index 0000000..24c6866
--- /dev/null
+++ b/src/tools/rbd_mirror/image_replayer/BootstrapRequest.h
@@ -0,0 +1,137 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+
+#ifndef RBD_MIRROR_IMAGE_REPLAYER_BOOTSTRAP_REQUEST_H
+#define RBD_MIRROR_IMAGE_REPLAYER_BOOTSTRAP_REQUEST_H
+
+#include "include/int_types.h"
+#include "include/rados/librados.hpp"
+#include "librbd/Journal.h"
+#include <string>
+
+class Context;
+class ContextWQ;
+class Mutex;
+class SafeTimer;
+namespace journal { class Journaler; }
+namespace librbd { class ImageCtx; }
+
+namespace rbd {
+namespace mirror {
+namespace image_replayer {
+
+template <typename ImageCtxT = librbd::ImageCtx>
+class BootstrapRequest {
+public:
+  typedef librbd::journal::TypeTraits<ImageCtxT> TypeTraits;
+  typedef typename TypeTraits::Journaler Journaler;
+  typedef librbd::journal::MirrorPeerClientMeta MirrorPeerClientMeta;
+
+  static BootstrapRequest* create(librados::IoCtx &local_io_ctx,
+                                  librados::IoCtx &remote_io_ctx,
+                                  ImageCtxT **local_image_ctx,
+                                  const std::string &local_image_name,
+                                  const std::string &remote_image_id,
+                                  ContextWQ *work_queue, SafeTimer *timer,
+                                  Mutex *timer_lock,
+                                  const std::string &mirror_uuid,
+                                  Journaler *journaler,
+                                  MirrorPeerClientMeta *client_meta,
+                                  Context *on_finish) {
+    return new BootstrapRequest(local_io_ctx, remote_io_ctx, local_image_ctx,
+                                local_image_name, remote_image_id, work_queue,
+                                timer, timer_lock, mirror_uuid, journaler,
+                                client_meta, on_finish);
+  }
+
+  BootstrapRequest(librados::IoCtx &local_io_ctx,
+                   librados::IoCtx &remote_io_ctx,
+                   ImageCtxT **local_image_ctx,
+                   const std::string &local_image_name,
+                   const std::string &remote_image_id, ContextWQ *work_queue,
+                   SafeTimer *timer, Mutex *timer_lock,
+                   const std::string &mirror_uuid, Journaler *journaler,
+                   MirrorPeerClientMeta *client_meta, Context *on_finish);
+  ~BootstrapRequest();
+
+  void send();
+
+private:
+  /**
+   * @verbatim
+   *
+   * <start>
+   *    |
+   *    v
+   * OPEN_REMOTE_IMAGE  * * * * * * * * * * * *
+   *    |                                     *
+   *    v                                     *
+   * CREATE_LOCAL_IMAGE * * * * * * * * * * * * (error)
+   *    |                                     *
+   *    v                                     *
+   * OPEN_LOCAL_IMAGE * * * * * * * * * * * * *
+   *    |                                     *
+   *    v                                     *
+   * REGISTER_CLIENT  * * * *                 *
+   *    |                   *                 *
+   *    v                   v                 *
+   * IMAGE_SYNC * * * > CLOSE_LOCAL_IMAGE     *
+   *    |                   |                 *
+   *    |     /-------------/                 *
+   *    |     |                               *
+   *    v     v                               *
+   * CLOSE_REMOTE_IMAGE < * * * * * * * * * * *
+   *    |
+   *    v
+   * <finish>
+   *
+   * @endverbatim
+   */
+  librados::IoCtx &m_local_io_ctx;
+  librados::IoCtx &m_remote_io_ctx;
+  ImageCtxT **m_local_image_ctx;
+  std::string m_local_image_name;
+  std::string m_remote_image_id;
+  ContextWQ *m_work_queue;
+  SafeTimer *m_timer;
+  Mutex *m_timer_lock;
+  std::string m_mirror_uuid;
+  Journaler *m_journaler;
+  MirrorPeerClientMeta *m_client_meta;
+  Context *m_on_finish;
+
+  ImageCtxT *m_remote_image_ctx = nullptr;
+  int m_ret_val = 0;
+
+  void open_remote_image();
+  void handle_open_remote_image(int r);
+
+  void create_local_image();
+  void handle_create_local_image(int r);
+
+  void open_local_image();
+  void handle_open_local_image(int r);
+
+  void register_client();
+  void handle_register_client(int r);
+
+  void image_sync();
+  void handle_image_sync(int r);
+
+  void close_local_image();
+  void handle_close_local_image(int r);
+
+  void close_remote_image();
+  void handle_close_remote_image(int r);
+
+  void finish(int r);
+
+};
+
+} // namespace image_replayer
+} // namespace mirror
+} // namespace rbd
+
+extern template class rbd::mirror::image_replayer::BootstrapRequest<librbd::ImageCtx>;
+
+#endif // RBD_MIRROR_IMAGE_REPLAYER_BOOTSTRAP_REQUEST_H
diff --git a/src/tools/rbd_mirror/image_replayer/CloseImageRequest.cc b/src/tools/rbd_mirror/image_replayer/CloseImageRequest.cc
new file mode 100644
index 0000000..3751245
--- /dev/null
+++ b/src/tools/rbd_mirror/image_replayer/CloseImageRequest.cc
@@ -0,0 +1,84 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+
+#include "CloseImageRequest.h"
+#include "common/dout.h"
+#include "common/errno.h"
+#include "common/WorkQueue.h"
+#include "librbd/ImageCtx.h"
+#include "librbd/ImageState.h"
+#include "librbd/Utils.h"
+
+#define dout_subsys ceph_subsys_rbd_mirror
+#undef dout_prefix
+#define dout_prefix *_dout << "rbd::mirror::image_replayer::CloseImageRequest: " \
+                           << this << " " << __func__
+
+namespace rbd {
+namespace mirror {
+namespace image_replayer {
+
+using librbd::util::create_context_callback;
+
+template <typename I>
+CloseImageRequest<I>::CloseImageRequest(I **image_ctx, ContextWQ *work_queue,
+                                        Context *on_finish)
+  : m_image_ctx(image_ctx), m_work_queue(work_queue), m_on_finish(on_finish) {
+}
+
+template <typename I>
+void CloseImageRequest<I>::send() {
+  close_image();
+}
+
+template <typename I>
+void CloseImageRequest<I>::close_image() {
+  dout(20) << dendl;
+
+  Context *ctx = create_context_callback<
+    CloseImageRequest<I>, &CloseImageRequest<I>::handle_close_image>(this);
+  (*m_image_ctx)->state->close(ctx);
+}
+
+template <typename I>
+void CloseImageRequest<I>::handle_close_image(int r) {
+  dout(20) << ": r=" << r << dendl;
+
+  if (r < 0) {
+    derr << "error encountered while closing image: " << cpp_strerror(r)
+         << dendl;
+  }
+
+  switch_thread_context();
+}
+
+template <typename I>
+void CloseImageRequest<I>::switch_thread_context() {
+  dout(20) << dendl;
+
+  // swap the librbd thread context for the rbd-mirror thread context
+  Context *ctx = create_context_callback<
+    CloseImageRequest<I>, &CloseImageRequest<I>::handle_switch_thread_context>(
+      this);
+  m_work_queue->queue(ctx, 0);
+}
+
+template <typename I>
+void CloseImageRequest<I>::handle_switch_thread_context(int r) {
+  dout(20) << dendl;
+
+  assert(r == 0);
+
+  delete *m_image_ctx;
+  *m_image_ctx = nullptr;
+
+  m_on_finish->complete(0);
+  delete this;
+}
+
+} // namespace image_replayer
+} // namespace mirror
+} // namespace rbd
+
+template class rbd::mirror::image_replayer::CloseImageRequest<librbd::ImageCtx>;
+
diff --git a/src/tools/rbd_mirror/image_replayer/CloseImageRequest.h b/src/tools/rbd_mirror/image_replayer/CloseImageRequest.h
new file mode 100644
index 0000000..8c43297
--- /dev/null
+++ b/src/tools/rbd_mirror/image_replayer/CloseImageRequest.h
@@ -0,0 +1,66 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+
+#ifndef RBD_MIRROR_IMAGE_REPLAYER_CLOSE_IMAGE_REQUEST_H
+#define RBD_MIRROR_IMAGE_REPLAYER_CLOSE_IMAGE_REQUEST_H
+
+#include "include/int_types.h"
+#include "librbd/ImageCtx.h"
+#include <string>
+
+class Context;
+class ContextWQ;
+namespace librbd { class ImageCtx; }
+
+namespace rbd {
+namespace mirror {
+namespace image_replayer {
+
+template <typename ImageCtxT = librbd::ImageCtx>
+class CloseImageRequest {
+public:
+  static CloseImageRequest* create(ImageCtxT **image_ctx, ContextWQ *work_queue,
+                                   Context *on_finish) {
+    return new CloseImageRequest(image_ctx, work_queue, on_finish);
+  }
+
+  CloseImageRequest(ImageCtxT **image_ctx, ContextWQ *work_queue,
+                    Context *on_finish);
+
+  void send();
+
+private:
+  /**
+   * @verbatim
+   *
+   * <start>
+   *    |
+   *    v
+   * CLOSE_IMAGE
+   *    |
+   *    v
+   * SWITCH_CONTEXT
+   *    |
+   *    v
+   * <finish>
+   *
+   * @endverbatim
+   */
+  ImageCtxT **m_image_ctx;
+  ContextWQ *m_work_queue;
+  Context *m_on_finish;
+
+  void close_image();
+  void handle_close_image(int r);
+
+  void switch_thread_context();
+  void handle_switch_thread_context(int r);
+};
+
+} // namespace image_replayer
+} // namespace mirror
+} // namespace rbd
+
+extern template class rbd::mirror::image_replayer::CloseImageRequest<librbd::ImageCtx>;
+
+#endif // RBD_MIRROR_IMAGE_REPLAYER_CLOSE_IMAGE_REQUEST_H
diff --git a/src/tools/rbd_mirror/image_replayer/OpenLocalImageRequest.cc b/src/tools/rbd_mirror/image_replayer/OpenLocalImageRequest.cc
new file mode 100644
index 0000000..4e40c4e
--- /dev/null
+++ b/src/tools/rbd_mirror/image_replayer/OpenLocalImageRequest.cc
@@ -0,0 +1,140 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+
+#include "OpenLocalImageRequest.h"
+#include "CloseImageRequest.h"
+#include "common/errno.h"
+#include "common/WorkQueue.h"
+#include "librbd/ExclusiveLock.h"
+#include "librbd/ImageCtx.h"
+#include "librbd/ImageState.h"
+#include "librbd/Utils.h"
+
+#define dout_subsys ceph_subsys_rbd_mirror
+#undef dout_prefix
+#define dout_prefix *_dout << "rbd::mirror::image_replayer::OpenLocalImageRequest: " \
+                           << this << " " << __func__
+
+namespace rbd {
+namespace mirror {
+namespace image_replayer {
+
+using librbd::util::create_context_callback;
+
+template <typename I>
+OpenLocalImageRequest<I>::OpenLocalImageRequest(librados::IoCtx &local_io_ctx,
+                                                I **local_image_ctx,
+                                                const std::string &local_image_name,
+                                                const std::string &local_image_id,
+                                                ContextWQ *work_queue,
+                                                Context *on_finish)
+  : m_local_io_ctx(local_io_ctx), m_local_image_ctx(local_image_ctx),
+    m_local_image_name(local_image_name), m_local_image_id(local_image_id),
+    m_work_queue(work_queue), m_on_finish(on_finish) {
+}
+
+template <typename I>
+void OpenLocalImageRequest<I>::send() {
+  send_open_image();
+}
+
+template <typename I>
+void OpenLocalImageRequest<I>::send_open_image() {
+  dout(20) << dendl;
+
+  *m_local_image_ctx = new librbd::ImageCtx(m_local_image_name,
+                                            m_local_image_id, nullptr,
+                                            m_local_io_ctx, false);
+
+  Context *ctx = create_context_callback<
+    OpenLocalImageRequest<I>, &OpenLocalImageRequest<I>::handle_open_image>(
+      this);
+  (*m_local_image_ctx)->state->open(ctx);
+}
+
+template <typename I>
+void OpenLocalImageRequest<I>::handle_open_image(int r) {
+  dout(20) << ": r=" << r << dendl;
+
+  if (r < 0) {
+    derr << "failed to open image '" << m_local_image_id << "': "
+         << cpp_strerror(r) << dendl;
+    send_close_image(r);
+    return;
+  } else if ((*m_local_image_ctx)->exclusive_lock == nullptr) {
+    derr << "image does not support exclusive lock" << dendl;
+    send_close_image(-EINVAL);
+    return;
+  }
+
+  send_lock_image();
+}
+
+template <typename I>
+void OpenLocalImageRequest<I>::send_lock_image() {
+  dout(20) << dendl;
+
+  Context *ctx = create_context_callback<
+    OpenLocalImageRequest<I>, &OpenLocalImageRequest<I>::handle_lock_image>(
+      this);
+
+  RWLock::RLocker owner_locker((*m_local_image_ctx)->owner_lock);
+  (*m_local_image_ctx)->exclusive_lock->request_lock(ctx);
+}
+
+template <typename I>
+void OpenLocalImageRequest<I>::handle_lock_image(int r) {
+  dout(20) << ": r=" << r << dendl;
+
+  if (r < 0) {
+    derr << "failed to lock image '" << m_local_image_id << "': "
+       << cpp_strerror(r) << dendl;
+    send_close_image(r);
+    return;
+  } else if ((*m_local_image_ctx)->exclusive_lock == nullptr ||
+             !(*m_local_image_ctx)->exclusive_lock->is_lock_owner()) {
+    derr << "image is not locked" << dendl;
+    send_close_image(-EBUSY);
+    return;
+  }
+
+  finish(0);
+}
+
+template <typename I>
+void OpenLocalImageRequest<I>::send_close_image(int r) {
+  dout(20) << dendl;
+
+  if (m_ret_val == 0 && r < 0) {
+    m_ret_val = r;
+  }
+
+  Context *ctx = create_context_callback<
+    OpenLocalImageRequest<I>, &OpenLocalImageRequest<I>::handle_close_image>(
+      this);
+  CloseImageRequest<I> *request = CloseImageRequest<I>::create(
+    m_local_image_ctx, m_work_queue, ctx);
+  request->send();
+}
+
+template <typename I>
+void OpenLocalImageRequest<I>::handle_close_image(int r) {
+  dout(20) << dendl;
+
+  assert(r == 0);
+  finish(m_ret_val);
+}
+
+template <typename I>
+void OpenLocalImageRequest<I>::finish(int r) {
+  dout(20) << ": r=" << r << dendl;
+
+  m_on_finish->complete(r);
+  delete this;
+}
+
+} // namespace image_replayer
+} // namespace mirror
+} // namespace rbd
+
+template class rbd::mirror::image_replayer::OpenLocalImageRequest<librbd::ImageCtx>;
diff --git a/src/tools/rbd_mirror/image_replayer/OpenLocalImageRequest.h b/src/tools/rbd_mirror/image_replayer/OpenLocalImageRequest.h
new file mode 100644
index 0000000..daf5c0a
--- /dev/null
+++ b/src/tools/rbd_mirror/image_replayer/OpenLocalImageRequest.h
@@ -0,0 +1,87 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+
+#ifndef RBD_MIRROR_IMAGE_REPLAYER_OPEN_LOCAL_IMAGE_REQUEST_H
+#define RBD_MIRROR_IMAGE_REPLAYER_OPEN_LOCAL_IMAGE_REQUEST_H
+
+#include "include/int_types.h"
+#include "librbd/ImageCtx.h"
+#include <string>
+
+class Context;
+class ContextWQ;
+namespace librbd { class ImageCtx; }
+
+namespace rbd {
+namespace mirror {
+namespace image_replayer {
+
+template <typename ImageCtxT = librbd::ImageCtx>
+class OpenLocalImageRequest {
+public:
+  static OpenLocalImageRequest* create(librados::IoCtx &local_io_ctx,
+                                       ImageCtxT **local_image_ctx,
+                                       const std::string &local_image_name,
+                                       const std::string &local_image_id,
+                                       ContextWQ *work_queue,
+                                       Context *on_finish) {
+    return new OpenLocalImageRequest(local_io_ctx, local_image_ctx,
+                                     local_image_name, local_image_id,
+                                     work_queue, on_finish);
+  }
+
+  OpenLocalImageRequest(librados::IoCtx &local_io_ctx,
+                        ImageCtxT **local_image_ctx,
+                        const std::string &local_image_name,
+                        const std::string &local_image_id,
+                        ContextWQ *m_work_queue,
+                        Context *on_finish);
+
+  void send();
+
+private:
+  /**
+   * @verbatim
+   *
+   * <start>
+   *    |
+   *    v
+   * OPEN_IMAGE * * * * * * *
+   *    |                   *
+   *    v                   v
+   * LOCK_IMAGE * * * > CLOSE_IMAGE
+   *    |                   |
+   *    v                   |
+   * <finish> <-------------/
+   *
+   * @endverbatim
+   */
+  librados::IoCtx &m_local_io_ctx;
+  ImageCtxT **m_local_image_ctx;
+  std::string m_local_image_name;
+  std::string m_local_image_id;
+  ContextWQ *m_work_queue;
+  Context *m_on_finish;
+
+  int m_ret_val = 0;
+
+  void send_open_image();
+  void handle_open_image(int r);
+
+  void send_lock_image();
+  void handle_lock_image(int r);
+
+  void send_close_image(int r);
+  void handle_close_image(int r);
+
+  void finish(int r);
+
+};
+
+} // namespace image_replayer
+} // namespace mirror
+} // namespace rbd
+
+extern template class rbd::mirror::image_replayer::OpenLocalImageRequest<librbd::ImageCtx>;
+
+#endif // RBD_MIRROR_IMAGE_REPLAYER_OPEN_LOCAL_IMAGE_REQUEST_H
diff --git a/src/tools/rbd_mirror/image_sync/ImageCopyRequest.cc b/src/tools/rbd_mirror/image_sync/ImageCopyRequest.cc
new file mode 100644
index 0000000..aedf2f5
--- /dev/null
+++ b/src/tools/rbd_mirror/image_sync/ImageCopyRequest.cc
@@ -0,0 +1,287 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+
+#include "ImageCopyRequest.h"
+#include "ObjectCopyRequest.h"
+#include "common/errno.h"
+#include "journal/Journaler.h"
+#include "librbd/Utils.h"
+
+#define dout_subsys ceph_subsys_rbd_mirror
+#undef dout_prefix
+#define dout_prefix *_dout << "rbd::mirror::image_sync::ImageCopyRequest: " \
+                           << this << " " << __func__
+
+namespace rbd {
+namespace mirror {
+namespace image_sync {
+
+using librbd::util::create_context_callback;
+using librbd::util::unique_lock_name;
+
+template <typename I>
+ImageCopyRequest<I>::ImageCopyRequest(I *local_image_ctx, I *remote_image_ctx,
+                                      SafeTimer *timer, Mutex *timer_lock,
+                                      Journaler *journaler,
+                                      MirrorPeerClientMeta *client_meta,
+                                      MirrorPeerSyncPoint *sync_point,
+                                      Context *on_finish)
+  : m_local_image_ctx(local_image_ctx), m_remote_image_ctx(remote_image_ctx),
+    m_timer(timer), m_timer_lock(timer_lock), m_journaler(journaler),
+    m_client_meta(client_meta), m_sync_point(sync_point),
+    m_on_finish(on_finish),
+    m_lock(unique_lock_name("ImageCopyRequest::m_lock", this)),
+    m_client_meta_copy(*client_meta) {
+  assert(!m_client_meta_copy.sync_points.empty());
+  assert(!m_client_meta_copy.snap_seqs.empty());
+}
+
+template <typename I>
+void ImageCopyRequest<I>::send() {
+  int r = compute_snap_map();
+  if (r < 0) {
+    finish(r);
+    return;
+  }
+
+  send_update_max_object_count();
+}
+
+template <typename I>
+void ImageCopyRequest<I>::cancel() {
+  Mutex::Locker locker(m_lock);
+
+  CephContext *cct = m_local_image_ctx->cct;
+  ldout(cct, 20) << dendl;
+  m_canceled = true;
+}
+
+template <typename I>
+void ImageCopyRequest<I>::send_update_max_object_count() {
+  uint64_t max_objects = m_client_meta->sync_object_count;
+  {
+    RWLock::RLocker snap_locker(m_remote_image_ctx->snap_lock);
+    max_objects = std::max(max_objects,
+                           m_remote_image_ctx->get_object_count(CEPH_NOSNAP));
+    for (auto snap_id : m_remote_image_ctx->snaps) {
+      max_objects = std::max(max_objects,
+                             m_remote_image_ctx->get_object_count(snap_id));
+    }
+  }
+
+  if (max_objects == m_client_meta->sync_object_count) {
+    send_object_copies();
+    return;
+  }
+
+  CephContext *cct = m_local_image_ctx->cct;
+  ldout(cct, 20) << ": sync_object_count=" << max_objects << dendl;
+
+  m_client_meta_copy = *m_client_meta;
+  m_client_meta_copy.sync_object_count = max_objects;
+
+  bufferlist client_data_bl;
+  librbd::journal::ClientData client_data(m_client_meta_copy);
+  ::encode(client_data, client_data_bl);
+
+  Context *ctx = create_context_callback<
+    ImageCopyRequest<I>, &ImageCopyRequest<I>::handle_update_max_object_count>(
+      this);
+  m_journaler->update_client(client_data_bl, ctx);
+}
+
+template <typename I>
+void ImageCopyRequest<I>::handle_update_max_object_count(int r) {
+  CephContext *cct = m_local_image_ctx->cct;
+  ldout(cct, 20) << ": r=" << r << dendl;
+
+  if (r < 0) {
+    lderr(cct) << "failed to update client data: " << cpp_strerror(r) << dendl;
+    finish(r);
+    return;
+  }
+
+  // update provided meta structure to reflect reality
+  m_client_meta->sync_object_count = m_client_meta_copy.sync_object_count;
+  m_object_no = 0;
+  if (m_sync_point->object_number) {
+    m_object_no = *m_sync_point->object_number + 1;
+  }
+  m_end_object_no = m_client_meta_copy.sync_object_count;
+
+  send_object_copies();
+}
+
+template <typename I>
+void ImageCopyRequest<I>::send_object_copies() {
+  CephContext *cct = m_local_image_ctx->cct;
+  bool complete;
+  {
+    Mutex::Locker locker(m_lock);
+    for (int i = 0; i < cct->_conf->rbd_concurrent_management_ops; ++i) {
+      send_next_object_copy();
+      if (m_ret_val < 0 && m_current_ops == 0) {
+        break;
+      }
+    }
+    complete = (m_current_ops == 0);
+  }
+  if (complete) {
+    send_flush_sync_point();
+  }
+}
+
+template <typename I>
+void ImageCopyRequest<I>::send_next_object_copy() {
+  assert(m_lock.is_locked());
+  if (m_canceled) {
+    return;
+  } else if (m_ret_val < 0 || m_object_no >= m_end_object_no) {
+    return;
+  }
+
+  uint64_t ono = m_object_no++;
+
+  CephContext *cct = m_local_image_ctx->cct;
+  ldout(cct, 20) << ": object_num=" << ono << dendl;
+
+  ++m_current_ops;
+
+  Context *ctx = create_context_callback<
+    ImageCopyRequest<I>, &ImageCopyRequest<I>::handle_object_copy>(this);
+  ObjectCopyRequest<I> *req = ObjectCopyRequest<I>::create(
+    m_local_image_ctx, m_remote_image_ctx, &m_snap_map, ono, ctx);
+  req->send();
+}
+
+template <typename I>
+void ImageCopyRequest<I>::handle_object_copy(int r) {
+  CephContext *cct = m_local_image_ctx->cct;
+  ldout(cct, 20) << ": r=" << r << dendl;
+
+  bool complete;
+  {
+    Mutex::Locker locker(m_lock);
+    assert(m_current_ops > 0);
+    --m_current_ops;
+
+    if (r < 0) {
+      lderr(cct) << "object copy failed: " << cpp_strerror(r) << dendl;
+      if (m_ret_val == 0) {
+        m_ret_val = r;
+      }
+    }
+
+    send_next_object_copy();
+    complete = (m_current_ops == 0);
+  }
+
+  if (complete) {
+    send_flush_sync_point();
+  }
+}
+
+template <typename I>
+void ImageCopyRequest<I>::send_flush_sync_point() {
+  if (m_ret_val < 0) {
+    finish(m_ret_val);
+    return;
+  }
+
+  m_client_meta_copy = *m_client_meta;
+  if (m_object_no > 0) {
+    m_sync_point->object_number = m_object_no - 1;
+  } else {
+    m_sync_point->object_number = boost::none;
+  }
+
+  CephContext *cct = m_local_image_ctx->cct;
+  ldout(cct, 20) << ": sync_point=" << *m_sync_point << dendl;
+
+  bufferlist client_data_bl;
+  librbd::journal::ClientData client_data(m_client_meta_copy);
+  ::encode(client_data, client_data_bl);
+
+  Context *ctx = create_context_callback<
+    ImageCopyRequest<I>, &ImageCopyRequest<I>::handle_flush_sync_point>(
+      this);
+  m_journaler->update_client(client_data_bl, ctx);
+}
+
+template <typename I>
+void ImageCopyRequest<I>::handle_flush_sync_point(int r) {
+  CephContext *cct = m_local_image_ctx->cct;
+  ldout(cct, 20) << ": r=" << r << dendl;
+
+  if (r < 0) {
+    *m_client_meta = m_client_meta_copy;
+
+    lderr(cct) << "failed to update client data: " << cpp_strerror(r) << dendl;
+    finish(r);
+    return;
+  }
+
+  finish(0);
+}
+
+template <typename I>
+void ImageCopyRequest<I>::finish(int r) {
+  CephContext *cct = m_local_image_ctx->cct;
+  ldout(cct, 20) << ": r=" << r << dendl;
+
+  m_on_finish->complete(r);
+  delete this;
+}
+
+template <typename I>
+int ImageCopyRequest<I>::compute_snap_map() {
+  CephContext *cct = m_local_image_ctx->cct;
+
+  librados::snap_t snap_id_start = 0;
+  librados::snap_t snap_id_end;
+  {
+    RWLock::RLocker snap_locker(m_remote_image_ctx->snap_lock);
+    snap_id_end = m_remote_image_ctx->get_snap_id(m_sync_point->snap_name);
+    if (snap_id_end == CEPH_NOSNAP) {
+      lderr(cct) << "failed to locate snapshot: "
+                 << m_sync_point->snap_name << dendl;
+      return -ENOENT;
+    }
+
+    if (!m_sync_point->from_snap_name.empty()) {
+      snap_id_start = m_remote_image_ctx->get_snap_id(
+        m_sync_point->from_snap_name);
+      if (snap_id_start == CEPH_NOSNAP) {
+        lderr(cct) << "failed to locate from snapshot: "
+                   << m_sync_point->from_snap_name << dendl;
+        return -ENOENT;
+      }
+    }
+  }
+
+  SnapIds snap_ids;
+  for (auto it = m_client_meta->snap_seqs.begin();
+       it != m_client_meta->snap_seqs.end(); ++it) {
+    snap_ids.insert(snap_ids.begin(), it->second);
+    if (it->first < snap_id_start) {
+      continue;
+    } else if (it->first > snap_id_end) {
+      break;
+    }
+
+    m_snap_map[it->first] = snap_ids;
+  }
+
+  if (m_snap_map.empty()) {
+    lderr(cct) << "failed to map snapshots within boundary" << dendl;
+    return -EINVAL;
+  }
+
+  return 0;
+}
+
+} // namespace image_sync
+} // namespace mirror
+} // namespace rbd
+
+template class rbd::mirror::image_sync::ImageCopyRequest<librbd::ImageCtx>;
diff --git a/src/tools/rbd_mirror/image_sync/ImageCopyRequest.h b/src/tools/rbd_mirror/image_sync/ImageCopyRequest.h
new file mode 100644
index 0000000..f2d1396
--- /dev/null
+++ b/src/tools/rbd_mirror/image_sync/ImageCopyRequest.h
@@ -0,0 +1,119 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+
+#ifndef RBD_MIRROR_IMAGE_SYNC_IMAGE_COPY_REQUEST_H
+#define RBD_MIRROR_IMAGE_SYNC_IMAGE_COPY_REQUEST_H
+
+#include "include/int_types.h"
+#include "include/rados/librados.hpp"
+#include "common/Mutex.h"
+#include "librbd/Journal.h"
+#include "librbd/journal/Types.h"
+#include <map>
+#include <vector>
+
+class Context;
+namespace journal { class Journaler; }
+namespace librbd { struct ImageCtx; }
+
+namespace rbd {
+namespace mirror {
+namespace image_sync {
+
+template <typename ImageCtxT = librbd::ImageCtx>
+class ImageCopyRequest {
+public:
+  typedef std::vector<librados::snap_t> SnapIds;
+  typedef std::map<librados::snap_t, SnapIds> SnapMap;
+  typedef librbd::journal::TypeTraits<ImageCtxT> TypeTraits;
+  typedef typename TypeTraits::Journaler Journaler;
+  typedef librbd::journal::MirrorPeerSyncPoint MirrorPeerSyncPoint;
+  typedef librbd::journal::MirrorPeerClientMeta MirrorPeerClientMeta;
+
+  static ImageCopyRequest* create(ImageCtxT *local_image_ctx,
+                                  ImageCtxT *remote_image_ctx,
+                                  SafeTimer *timer, Mutex *timer_lock,
+                                  Journaler *journaler,
+                                  MirrorPeerClientMeta *client_meta,
+                                  MirrorPeerSyncPoint *sync_point,
+                                  Context *on_finish) {
+    return new ImageCopyRequest(local_image_ctx, remote_image_ctx, timer,
+                                timer_lock, journaler, client_meta, sync_point,
+                                on_finish);
+  }
+
+  ImageCopyRequest(ImageCtxT *local_image_ctx, ImageCtxT *remote_image_ctx,
+                   SafeTimer *timer, Mutex *timer_lock, Journaler *journaler,
+                   MirrorPeerClientMeta *client_meta,
+                   MirrorPeerSyncPoint *sync_point, Context *on_finish);
+
+  void send();
+  void cancel();
+
+private:
+  /**
+   * @verbatim
+   *
+   * <start>
+   *    |
+   *    v
+   * UPDATE_MAX_OBJECT_COUNT
+   *    |
+   *    |   . . . . .
+   *    |   .       .  (parallel execution of
+   *    v   v       .   multiple objects at once)
+   * COPY_OBJECT  . .
+   *    |
+   *    v
+   * FLUSH_SYNC_POINT
+   *    |
+   *    v
+   * <finish>
+   *
+   * @endverbatim
+   */
+
+  ImageCtxT *m_local_image_ctx;
+  ImageCtxT *m_remote_image_ctx;
+  SafeTimer *m_timer;
+  Mutex *m_timer_lock;
+  Journaler *m_journaler;
+  MirrorPeerClientMeta *m_client_meta;
+  MirrorPeerSyncPoint *m_sync_point;
+  Context *m_on_finish;
+
+  SnapMap m_snap_map;
+
+  Mutex m_lock;
+  bool m_canceled = false;
+
+  uint64_t m_object_no = 0;
+  uint64_t m_end_object_no;
+  uint64_t m_current_ops = 0;
+  int m_ret_val = 0;
+
+  MirrorPeerClientMeta m_client_meta_copy;
+
+  void send_update_max_object_count();
+  void handle_update_max_object_count(int r);
+
+  void send_object_copies();
+  void send_next_object_copy();
+  void handle_object_copy(int r);
+
+  void send_flush_sync_point();
+  void handle_flush_sync_point(int r);
+
+  void finish(int r);
+
+  int compute_snap_map();
+
+};
+
+} // namespace image_sync
+} // namespace mirror
+} // namespace rbd
+
+extern template class rbd::mirror::image_sync::ImageCopyRequest<librbd::ImageCtx>;
+
+#endif // RBD_MIRROR_IMAGE_SYNC_IMAGE_COPY_REQUEST_H
diff --git a/src/tools/rbd_mirror/image_sync/ObjectCopyRequest.cc b/src/tools/rbd_mirror/image_sync/ObjectCopyRequest.cc
new file mode 100644
index 0000000..c49beed
--- /dev/null
+++ b/src/tools/rbd_mirror/image_sync/ObjectCopyRequest.cc
@@ -0,0 +1,364 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+
+#include "ObjectCopyRequest.h"
+#include "librados/snap_set_diff.h"
+#include "librbd/ObjectMap.h"
+#include "librbd/Utils.h"
+#include "common/errno.h"
+
+#define dout_subsys ceph_subsys_rbd_mirror
+#undef dout_prefix
+#define dout_prefix *_dout << "rbd::mirror::image_sync::ObjectCopyRequest: " \
+                           << this << " " << __func__
+
+namespace rbd {
+namespace mirror {
+namespace image_sync {
+
+using librbd::util::create_context_callback;
+using librbd::util::create_rados_ack_callback;
+using librbd::util::create_rados_safe_callback;
+
+template <typename I>
+ObjectCopyRequest<I>::ObjectCopyRequest(I *local_image_ctx, I *remote_image_ctx,
+                                        const SnapMap *snap_map,
+                                        uint64_t object_number,
+                                        Context *on_finish)
+  : m_local_image_ctx(local_image_ctx), m_remote_image_ctx(remote_image_ctx),
+    m_snap_map(snap_map), m_object_number(object_number),
+    m_on_finish(on_finish) {
+  assert(!snap_map->empty());
+
+  m_local_io_ctx.dup(m_local_image_ctx->data_ctx);
+  m_local_oid = m_local_image_ctx->get_object_name(object_number);
+
+  m_remote_io_ctx.dup(m_remote_image_ctx->data_ctx);
+  m_remote_oid = m_remote_image_ctx->get_object_name(object_number);
+}
+
+template <typename I>
+void ObjectCopyRequest<I>::send() {
+  send_list_snaps();
+}
+
+template <typename I>
+void ObjectCopyRequest<I>::send_list_snaps() {
+  CephContext *cct = m_local_image_ctx->cct;
+  ldout(cct, 20) << dendl;
+
+  librados::AioCompletion *rados_completion = create_rados_ack_callback<
+    ObjectCopyRequest<I>, &ObjectCopyRequest<I>::handle_list_snaps>(this);
+
+  librados::ObjectReadOperation op;
+  op.list_snaps(&m_snap_set, &m_snap_ret);
+
+  m_remote_io_ctx.snap_set_read(CEPH_SNAPDIR);
+  int r = m_remote_io_ctx.aio_operate(m_remote_oid, rados_completion, &op,
+                                      nullptr);
+  assert(r == 0);
+  rados_completion->release();
+}
+
+template <typename I>
+void ObjectCopyRequest<I>::handle_list_snaps(int r) {
+  if (r == 0 && m_snap_ret < 0) {
+    r = m_snap_ret;
+  }
+
+  CephContext *cct = m_local_image_ctx->cct;
+  ldout(cct, 20) << ": r=" << r << dendl;
+
+  if (r == -ENOENT) {
+    finish(0);
+    return;
+  }
+  if (r < 0) {
+    lderr(cct) << "failed to list snaps: " << cpp_strerror(r) << dendl;
+    finish(r);
+    return;
+  }
+
+  compute_diffs();
+  send_read_object();
+}
+
+template <typename I>
+void ObjectCopyRequest<I>::send_read_object() {
+  CephContext *cct = m_local_image_ctx->cct;
+  if (m_snap_sync_ops.empty()) {
+    // no more snapshot diffs to read from remote
+    finish(0);
+    return;
+  }
+
+  // build the read request
+  auto &sync_ops = m_snap_sync_ops.begin()->second;
+  assert(!sync_ops.empty());
+
+  // map the sync op start snap id back to the necessary read snap id
+  auto snap_map_it = m_snap_map->upper_bound(
+    m_snap_sync_ops.begin()->first);
+  assert(snap_map_it != m_snap_map->end());
+  librados::snap_t snap_seq = snap_map_it->first;
+  m_remote_io_ctx.snap_set_read(snap_seq);
+
+  bool read_required = false;
+  librados::ObjectReadOperation op;
+  for (auto &sync_op : sync_ops) {
+    switch (std::get<0>(sync_op)) {
+    case SYNC_OP_TYPE_WRITE:
+      if (!read_required) {
+        ldout(cct, 20) << ": snap_seq=" << snap_seq << dendl;
+        read_required = true;
+      }
+
+      ldout(cct, 20) << ": read op: " << std::get<1>(sync_op) << "~"
+                     << std::get<2>(sync_op) << dendl;
+      op.read(std::get<1>(sync_op), std::get<2>(sync_op),
+              &std::get<3>(sync_op), nullptr);
+      break;
+    default:
+      break;
+    }
+  }
+
+  if (!read_required) {
+    // nothing written to this object for this snapshot (must be trunc/remove)
+    send_write_object();
+    return;
+  }
+
+  librados::AioCompletion *comp = create_rados_safe_callback<
+    ObjectCopyRequest<I>, &ObjectCopyRequest<I>::handle_read_object>(this);
+  int r = m_remote_io_ctx.aio_operate(m_remote_oid, comp, &op, nullptr);
+  assert(r == 0);
+  comp->release();
+}
+
+template <typename I>
+void ObjectCopyRequest<I>::handle_read_object(int r) {
+  CephContext *cct = m_local_image_ctx->cct;
+  ldout(cct, 20) << ": r=" << r << dendl;
+
+  if (r < 0) {
+    lderr(cct) << "failed to read from remote object: " << cpp_strerror(r)
+               << dendl;
+    finish(r);
+    return;
+  }
+
+  send_write_object();
+}
+
+template <typename I>
+void ObjectCopyRequest<I>::send_write_object() {
+  // retrieve the local snap context for the op
+  SnapIds snap_ids;
+  librados::snap_t snap_seq = m_snap_sync_ops.begin()->first;
+  if (snap_seq != 0) {
+    auto snap_map_it = m_snap_map->find(snap_seq);
+    assert(snap_map_it != m_snap_map->end());
+    snap_ids = snap_map_it->second;
+  }
+
+  CephContext *cct = m_local_image_ctx->cct;
+  ldout(cct, 20) << ": "
+                 << "snap_seq=" << snap_seq << ", "
+                 << "snaps=" << snap_ids << dendl;
+
+  auto &sync_ops = m_snap_sync_ops.begin()->second;
+  assert(!sync_ops.empty());
+
+  librados::ObjectWriteOperation op;
+  for (auto &sync_op : sync_ops) {
+    switch (std::get<0>(sync_op)) {
+    case SYNC_OP_TYPE_WRITE:
+      ldout(cct, 20) << ": write op: " << std::get<1>(sync_op) << "~"
+                     << std::get<3>(sync_op).length() << dendl;
+      op.write(std::get<1>(sync_op), std::get<3>(sync_op));
+      break;
+    case SYNC_OP_TYPE_TRUNC:
+      ldout(cct, 20) << ": trunc op: " << std::get<1>(sync_op) << dendl;
+      op.truncate(std::get<1>(sync_op));
+      break;
+    case SYNC_OP_TYPE_REMOVE:
+      ldout(cct, 20) << ": remove op" << dendl;
+      op.remove();
+      break;
+    default:
+      assert(false);
+    }
+  }
+
+  librados::AioCompletion *comp = create_rados_safe_callback<
+    ObjectCopyRequest<I>, &ObjectCopyRequest<I>::handle_write_object>(this);
+  int r = m_local_io_ctx.aio_operate(m_local_oid, comp, &op, snap_seq,
+                                     snap_ids);
+  assert(r == 0);
+  comp->release();
+}
+
+template <typename I>
+void ObjectCopyRequest<I>::handle_write_object(int r) {
+  CephContext *cct = m_local_image_ctx->cct;
+  ldout(cct, 20) << ": r=" << r << dendl;
+
+  if (r == -ENOENT) {
+    r = 0;
+  }
+  if (r < 0) {
+    lderr(cct) << "failed to write to local object: " << cpp_strerror(r)
+               << dendl;
+    finish(r);
+    return;
+  }
+
+  m_snap_sync_ops.erase(m_snap_sync_ops.begin());
+  if (!m_snap_sync_ops.empty()) {
+    send_read_object();
+    return;
+  }
+
+  send_update_object_map();
+}
+
+template <typename I>
+void ObjectCopyRequest<I>::send_update_object_map() {
+  m_local_image_ctx->snap_lock.get_read();
+  if (!m_local_image_ctx->test_features(RBD_FEATURE_OBJECT_MAP,
+                                        m_local_image_ctx->snap_lock) ||
+      m_snap_object_states.empty()) {
+    m_local_image_ctx->snap_lock.put_read();
+    finish(0);
+    return;
+  }
+
+  assert(m_local_image_ctx->object_map != nullptr);
+
+  auto snap_object_state = *m_snap_object_states.begin();
+  m_snap_object_states.erase(m_snap_object_states.begin());
+
+  CephContext *cct = m_local_image_ctx->cct;
+  ldout(cct, 20) << ": "
+                 << "snap_id=" << snap_object_state.first << ", "
+                 << "object_state=" << static_cast<uint32_t>(
+                      snap_object_state.second)
+                 << dendl;
+
+  RWLock::WLocker object_map_locker(m_local_image_ctx->object_map_lock);
+  Context *ctx = create_context_callback<
+    ObjectCopyRequest<I>, &ObjectCopyRequest<I>::handle_update_object_map>(
+      this);
+  m_local_image_ctx->object_map->aio_update(snap_object_state.first,
+                                            m_object_number,
+                                            m_object_number + 1,
+                                            snap_object_state.second,
+                                            boost::none, ctx);
+  m_local_image_ctx->snap_lock.put_read();
+}
+
+template <typename I>
+void ObjectCopyRequest<I>::handle_update_object_map(int r) {
+  CephContext *cct = m_local_image_ctx->cct;
+  ldout(cct, 20) << ": r=" << r << dendl;
+
+  assert(r == 0);
+  if (!m_snap_object_states.empty()) {
+    send_update_object_map();
+    return;
+  }
+  finish(0);
+}
+
+template <typename I>
+void ObjectCopyRequest<I>::compute_diffs() {
+  CephContext *cct = m_local_image_ctx->cct;
+
+  uint64_t prev_end_size = 0;
+  bool prev_exists = false;
+  librados::snap_t start_snap_id = 0;
+  librados::snap_t end_snap_id;
+  for (auto &pair : *m_snap_map) {
+    assert(!pair.second.empty());
+    end_snap_id = pair.second.front();
+
+    interval_set<uint64_t> diff;
+    uint64_t end_size;
+    bool exists;
+    calc_snap_set_diff(cct, m_snap_set, start_snap_id, end_snap_id, &diff,
+                       &end_size, &exists);
+
+    ldout(cct, 20) << ": "
+                   << "start_snap=" << start_snap_id << ", "
+                   << "end_snap_id=" << end_snap_id << ", "
+                   << "diff=" << diff << ", "
+                   << "end_size=" << end_size << ", "
+                   << "exists=" << exists << dendl;
+
+    if (exists) {
+      // clip diff to size of object (in case it was truncated)
+      if (end_size < prev_end_size) {
+        interval_set<uint64_t> trunc;
+        trunc.insert(end_size, prev_end_size);
+        trunc.intersection_of(diff);
+        diff.subtract(trunc);
+        ldout(cct, 20) << ": clearing truncate diff: " << trunc << dendl;
+      }
+
+      // prepare the object map state
+      {
+        RWLock::RLocker snap_locker(m_local_image_ctx->snap_lock);
+        uint8_t object_state = OBJECT_EXISTS;
+        if (m_local_image_ctx->test_features(RBD_FEATURE_FAST_DIFF,
+                                             m_local_image_ctx->snap_lock) &&
+            diff.empty() && end_size == prev_end_size) {
+          object_state = OBJECT_EXISTS_CLEAN;
+        }
+        m_snap_object_states[end_snap_id] = object_state;
+      }
+
+      // object write/zero, or truncate
+      for (auto it = diff.begin(); it != diff.end(); ++it) {
+        ldout(cct, 20) << ": read/write op: " << it.get_start() << "~"
+                       << it.get_len() << dendl;
+        m_snap_sync_ops[start_snap_id].emplace_back(SYNC_OP_TYPE_WRITE,
+                                                    it.get_start(),
+                                                    it.get_len(),
+                                                    bufferlist());
+      }
+      if (end_size < prev_end_size) {
+        ldout(cct, 20) << ": trunc op: " << end_size << dendl;
+        m_snap_sync_ops[start_snap_id].emplace_back(SYNC_OP_TYPE_TRUNC,
+                                                    end_size, 0U, bufferlist());
+      }
+    } else {
+      m_snap_object_states[end_snap_id] = OBJECT_NONEXISTENT;
+      if (prev_exists) {
+        // object remove
+        ldout(cct, 20) << ": remove op" << dendl;
+        m_snap_sync_ops[start_snap_id].emplace_back(SYNC_OP_TYPE_REMOVE, 0U, 0U,
+                                                    bufferlist());
+      }
+    }
+
+    prev_end_size = end_size;
+    prev_exists = exists;
+    start_snap_id = end_snap_id;
+  }
+}
+
+template <typename I>
+void ObjectCopyRequest<I>::finish(int r) {
+  CephContext *cct = m_local_image_ctx->cct;
+  ldout(cct, 20) << ": r=" << r << dendl;
+
+  m_on_finish->complete(r);
+  delete this;
+}
+
+} // namespace image_sync
+} // namespace mirror
+} // namespace rbd
+
+template class rbd::mirror::image_sync::ObjectCopyRequest<librbd::ImageCtx>;
diff --git a/src/tools/rbd_mirror/image_sync/ObjectCopyRequest.h b/src/tools/rbd_mirror/image_sync/ObjectCopyRequest.h
new file mode 100644
index 0000000..83fe16c
--- /dev/null
+++ b/src/tools/rbd_mirror/image_sync/ObjectCopyRequest.h
@@ -0,0 +1,129 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+
+#ifndef RBD_MIRROR_IMAGE_SYNC_OBJECT_COPY_REQUEST_H
+#define RBD_MIRROR_IMAGE_SYNC_OBJECT_COPY_REQUEST_H
+
+#include "include/int_types.h"
+#include "include/rados/librados.hpp"
+#include "common/snap_types.h"
+#include "librbd/ImageCtx.h"
+#include <list>
+#include <map>
+#include <string>
+#include <tuple>
+#include <vector>
+
+class Context;
+
+namespace rbd {
+namespace mirror {
+namespace image_sync {
+
+template <typename ImageCtxT = librbd::ImageCtx>
+class ObjectCopyRequest {
+public:
+  typedef std::vector<librados::snap_t> SnapIds;
+  typedef std::map<librados::snap_t, SnapIds> SnapMap;
+
+  static ObjectCopyRequest* create(ImageCtxT *local_image_ctx,
+                                   ImageCtxT *remote_image_ctx,
+                                   const SnapMap *snap_map,
+                                   uint64_t object_number, Context *on_finish) {
+    return new ObjectCopyRequest(local_image_ctx, remote_image_ctx, snap_map,
+                                 object_number, on_finish);
+  }
+
+  ObjectCopyRequest(ImageCtxT *local_image_ctx, ImageCtxT *remote_image_ctx,
+                    const SnapMap *snap_map, uint64_t object_number,
+                    Context *on_finish);
+
+  void send();
+
+  // testing support
+  inline librados::IoCtx &get_local_io_ctx() {
+    return m_local_io_ctx;
+  }
+  inline librados::IoCtx &get_remote_io_ctx() {
+    return m_remote_io_ctx;
+  }
+
+private:
+  /**
+   * @verbatim
+   *
+   * <start>
+   *    |
+   *    v
+   * LIST_SNAPS
+   *    |
+   *    v
+   * READ_OBJECT <--------\
+   *    |                 | (repeat for each snapshot)
+   *    v                 |
+   * WRITE_OBJECT --------/
+   *    |
+   *    |     /-----------\
+   *    |     |           | (repeat for each snapshot)
+   *    v     v           |
+   * UPDATE_OBJECT_MAP ---/ (skip if object
+   *    |                    map disabled)
+   *    |
+   *    v
+   * <finish>
+   *
+   * @endverbatim
+   */
+
+  enum SyncOpType {
+    SYNC_OP_TYPE_WRITE,
+    SYNC_OP_TYPE_TRUNC,
+    SYNC_OP_TYPE_REMOVE
+  };
+
+  typedef std::tuple<SyncOpType, uint64_t, uint64_t, bufferlist> SyncOp;
+  typedef std::list<SyncOp> SyncOps;
+  typedef std::map<librados::snap_t, SyncOps> SnapSyncOps;
+  typedef std::map<librados::snap_t, uint8_t> SnapObjectStates;
+
+  ImageCtxT *m_local_image_ctx;
+  ImageCtxT *m_remote_image_ctx;
+  const SnapMap *m_snap_map;
+  uint64_t m_object_number;
+  Context *m_on_finish;
+
+  decltype(m_local_image_ctx->data_ctx) m_local_io_ctx;
+  decltype(m_remote_image_ctx->data_ctx) m_remote_io_ctx;
+  std::string m_local_oid;
+  std::string m_remote_oid;
+
+  librados::snap_set_t m_snap_set;
+  int m_snap_ret;
+
+  SnapSyncOps m_snap_sync_ops;
+  SnapObjectStates m_snap_object_states;
+
+  void send_list_snaps();
+  void handle_list_snaps(int r);
+
+  void send_read_object();
+  void handle_read_object(int r);
+
+  void send_write_object();
+  void handle_write_object(int r);
+
+  void send_update_object_map();
+  void handle_update_object_map(int r);
+
+  void compute_diffs();
+  void finish(int r);
+
+};
+
+} // namespace image_sync
+} // namespace mirror
+} // namespace rbd
+
+extern template class rbd::mirror::image_sync::ObjectCopyRequest<librbd::ImageCtx>;
+
+#endif // RBD_MIRROR_IMAGE_SYNC_OBJECT_COPY_REQUEST_H
diff --git a/src/tools/rbd_mirror/image_sync/SnapshotCopyRequest.cc b/src/tools/rbd_mirror/image_sync/SnapshotCopyRequest.cc
new file mode 100644
index 0000000..63202bc
--- /dev/null
+++ b/src/tools/rbd_mirror/image_sync/SnapshotCopyRequest.cc
@@ -0,0 +1,255 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+
+#include "SnapshotCopyRequest.h"
+#include "common/errno.h"
+#include "journal/Journaler.h"
+#include "librbd/Operations.h"
+#include "librbd/Utils.h"
+#include "librbd/journal/Types.h"
+
+#define dout_subsys ceph_subsys_rbd_mirror
+#undef dout_prefix
+#define dout_prefix *_dout << "rbd::mirror::image_sync::SnapshotCopyRequest: " \
+                           << this << " " << __func__
+
+namespace rbd {
+namespace mirror {
+namespace image_sync {
+
+namespace {
+
+template <typename I>
+const std::string &get_snapshot_name(I *image_ctx, librados::snap_t snap_id) {
+  auto snap_it = std::find_if(image_ctx->snap_ids.begin(),
+                              image_ctx->snap_ids.end(),
+                              [snap_id](
+      const std::pair<std::string, librados::snap_t> &pair) {
+    return pair.second == snap_id;
+  });
+  assert(snap_it != image_ctx->snap_ids.end());
+  return snap_it->first;
+}
+
+} // anonymous namespace
+
+using librbd::util::create_context_callback;
+
+
+
+template <typename I>
+SnapshotCopyRequest<I>::SnapshotCopyRequest(I *local_image_ctx,
+                                            I *remote_image_ctx,
+                                            SnapMap *snap_map,
+                                            Journaler *journaler,
+                                            librbd::journal::MirrorPeerClientMeta *meta,
+                                            Context *on_finish)
+  : m_local_image_ctx(local_image_ctx), m_remote_image_ctx(remote_image_ctx),
+    m_snap_map(snap_map), m_journaler(journaler), m_client_meta(meta),
+    m_on_finish(on_finish), m_snap_seqs(meta->snap_seqs) {
+  m_snap_map->clear();
+
+  // snap ids ordered from oldest to newest
+  m_remote_snap_ids.insert(remote_image_ctx->snaps.begin(),
+                           remote_image_ctx->snaps.end());
+  m_local_snap_ids.insert(local_image_ctx->snaps.begin(),
+                          local_image_ctx->snaps.end());
+}
+
+template <typename I>
+void SnapshotCopyRequest<I>::send() {
+  send_snap_remove();
+}
+
+template <typename I>
+void SnapshotCopyRequest<I>::send_snap_remove() {
+  CephContext *cct = m_local_image_ctx->cct;
+  // TODO: issue #14937 needs to add support for cloned images
+  {
+    RWLock::RLocker snap_locker(m_remote_image_ctx->snap_lock);
+    if (m_remote_image_ctx->parent_md.spec.pool_id != -1 ||
+        std::find_if(m_remote_image_ctx->snap_info.begin(),
+                     m_remote_image_ctx->snap_info.end(),
+                     [](const std::pair<librados::snap_t, librbd::SnapInfo>& pair) {
+            return pair.second.parent.spec.pool_id != -1;
+          }) != m_remote_image_ctx->snap_info.end()) {
+      lderr(cct) << "cloned images are not currentl supported" << dendl;
+      finish(-EINVAL);
+      return;
+    }
+  }
+
+  librados::snap_t local_snap_id = CEPH_NOSNAP;
+  while (local_snap_id == CEPH_NOSNAP && !m_local_snap_ids.empty()) {
+    librados::snap_t snap_id = *m_local_snap_ids.begin();
+
+    // if local snapshot id isn't in our mapping table, delete it
+    // we match by id since snapshots can be renamed
+    if (std::find_if(m_snap_seqs.begin(), m_snap_seqs.end(),
+                     [snap_id](const SnapSeqs::value_type& pair) {
+        return pair.second == snap_id; }) == m_snap_seqs.end()) {
+      local_snap_id = snap_id;
+      m_local_snap_ids.erase(m_local_snap_ids.begin());
+    }
+  }
+
+  if (local_snap_id == CEPH_NOSNAP && m_local_snap_ids.empty()) {
+    // no local snapshots to delete
+    send_snap_create();
+    return;
+  }
+
+  m_snap_name = get_snapshot_name(m_local_image_ctx, local_snap_id);
+
+  ldout(cct, 20) << ": "
+                 << "snap_name=" << m_snap_name << ", "
+                 << "snap_id=" << local_snap_id << dendl;
+
+  Context *ctx = create_context_callback<
+    SnapshotCopyRequest<I>, &SnapshotCopyRequest<I>::handle_snap_remove>(
+      this);
+  RWLock::RLocker owner_locker(m_local_image_ctx->owner_lock);
+  m_local_image_ctx->operations->execute_snap_remove(m_snap_name.c_str(), ctx);
+}
+
+template <typename I>
+void SnapshotCopyRequest<I>::handle_snap_remove(int r) {
+  CephContext *cct = m_local_image_ctx->cct;
+  ldout(cct, 20) << ": r=" << r << dendl;
+
+  if (r < 0) {
+    lderr(cct) << "failed to remove snapshot '" << m_snap_name << "': "
+               << cpp_strerror(r) << dendl;
+    finish(r);
+    return;
+  }
+
+  send_snap_remove();
+}
+
+template <typename I>
+void SnapshotCopyRequest<I>::send_snap_create() {
+  librados::snap_t remote_snap_id = CEPH_NOSNAP;
+  while (remote_snap_id == CEPH_NOSNAP && !m_remote_snap_ids.empty()) {
+    librados::snap_t snap_id = *m_remote_snap_ids.begin();
+    if (m_snap_seqs.find(snap_id) == m_snap_seqs.end()) {
+      // missing remote -> local mapping
+      remote_snap_id = snap_id;
+    } else {
+      // already have remote -> local mapping
+      m_remote_snap_ids.erase(m_remote_snap_ids.begin());
+    }
+  }
+
+  if (remote_snap_id == CEPH_NOSNAP && m_remote_snap_ids.empty()) {
+    // no local snapshots to create
+    send_update_client();
+    return;
+  }
+
+  m_snap_name = get_snapshot_name(m_remote_image_ctx, remote_snap_id);
+
+  CephContext *cct = m_local_image_ctx->cct;
+  ldout(cct, 20) << ": "
+                 << "snap_name=" << m_snap_name << ", "
+                 << "snap_id=" << remote_snap_id << dendl;
+
+  Context *ctx = create_context_callback<
+    SnapshotCopyRequest<I>, &SnapshotCopyRequest<I>::handle_snap_create>(
+      this);
+  RWLock::RLocker owner_locker(m_local_image_ctx->owner_lock);
+  m_local_image_ctx->operations->execute_snap_create(m_snap_name.c_str(), ctx,
+                                                     0U);
+}
+
+template <typename I>
+void SnapshotCopyRequest<I>::handle_snap_create(int r) {
+  CephContext *cct = m_local_image_ctx->cct;
+  ldout(cct, 20) << ": r=" << r << dendl;
+
+  if (r < 0) {
+    lderr(cct) << "failed to create snapshot '" << m_snap_name << "': "
+               << cpp_strerror(r) << dendl;
+    finish(r);
+    return;
+  }
+
+  assert(!m_remote_snap_ids.empty());
+  librados::snap_t remote_snap_id = *m_remote_snap_ids.begin();
+  m_remote_snap_ids.erase(m_remote_snap_ids.begin());
+
+  auto snap_it = m_local_image_ctx->snap_ids.find(m_snap_name);
+  assert(snap_it != m_local_image_ctx->snap_ids.end());
+  librados::snap_t local_snap_id = snap_it->second;
+
+  ldout(cct, 20) << ": mapping remote snap id " << remote_snap_id << " to "
+                 << local_snap_id << dendl;
+  m_snap_seqs[remote_snap_id] = local_snap_id;
+
+  send_snap_create();
+}
+
+template <typename I>
+void SnapshotCopyRequest<I>::send_update_client() {
+  CephContext *cct = m_local_image_ctx->cct;
+  ldout(cct, 20) << dendl;
+
+  compute_snap_map();
+
+  librbd::journal::MirrorPeerClientMeta client_meta(*m_client_meta);
+  client_meta.snap_seqs = m_snap_seqs;
+
+  librbd::journal::ClientData client_data(client_meta);
+  bufferlist data_bl;
+  ::encode(client_data, data_bl);
+
+  Context *ctx = create_context_callback<
+    SnapshotCopyRequest<I>, &SnapshotCopyRequest<I>::handle_update_client>(
+      this);
+  m_journaler->update_client(data_bl, ctx);
+}
+
+template <typename I>
+void SnapshotCopyRequest<I>::handle_update_client(int r) {
+  CephContext *cct = m_local_image_ctx->cct;
+  ldout(cct, 20) << ": r=" << r << dendl;
+
+  if (r < 0) {
+    lderr(cct) << "failed to update client data: " << cpp_strerror(r) << dendl;
+    finish(r);
+    return;
+  }
+
+  m_client_meta->snap_seqs = m_snap_seqs;
+
+  finish(0);
+}
+
+template <typename I>
+void SnapshotCopyRequest<I>::finish(int r) {
+  CephContext *cct = m_local_image_ctx->cct;
+  ldout(cct, 20) << ": r=" << r << dendl;
+
+  if (r >= 0) {
+    m_client_meta->snap_seqs = m_snap_seqs;
+  }
+
+  m_on_finish->complete(r);
+  delete this;
+}
+
+template <typename I>
+void SnapshotCopyRequest<I>::compute_snap_map() {
+  SnapIds local_snap_ids;
+  for (auto &pair : m_snap_seqs) {
+    local_snap_ids.reserve(1 + local_snap_ids.size());
+    local_snap_ids.insert(local_snap_ids.begin(), pair.second);
+    m_snap_map->insert(std::make_pair(pair.first, local_snap_ids));
+  }
+}
+
+} // namespace image_sync
+} // namespace mirror
+} // namespace rbd
+
+template class rbd::mirror::image_sync::SnapshotCopyRequest<librbd::ImageCtx>;
diff --git a/src/tools/rbd_mirror/image_sync/SnapshotCopyRequest.h b/src/tools/rbd_mirror/image_sync/SnapshotCopyRequest.h
new file mode 100644
index 0000000..44368f2
--- /dev/null
+++ b/src/tools/rbd_mirror/image_sync/SnapshotCopyRequest.h
@@ -0,0 +1,112 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+
+#ifndef RBD_MIRROR_IMAGE_SYNC_SNAPSHOT_COPY_REQUEST_H
+#define RBD_MIRROR_IMAGE_SYNC_SNAPSHOT_COPY_REQUEST_H
+
+#include "include/int_types.h"
+#include "include/rados/librados.hpp"
+#include "common/snap_types.h"
+#include "librbd/ImageCtx.h"
+#include "librbd/Journal.h"
+#include <map>
+#include <set>
+#include <string>
+#include <tuple>
+
+class Context;
+namespace journal { class Journaler; }
+namespace librbd { namespace journal { struct MirrorPeerClientMeta; } }
+
+namespace rbd {
+namespace mirror {
+namespace image_sync {
+
+template <typename ImageCtxT = librbd::ImageCtx>
+class SnapshotCopyRequest {
+public:
+  typedef librbd::journal::TypeTraits<ImageCtxT> TypeTraits;
+  typedef typename TypeTraits::Journaler Journaler;
+
+  typedef std::vector<librados::snap_t> SnapIds;
+  typedef std::map<librados::snap_t, SnapIds> SnapMap;
+
+  static SnapshotCopyRequest* create(ImageCtxT *local_image_ctx,
+                                     ImageCtxT *remote_image_ctx,
+                                     SnapMap *snap_map, Journaler *journaler,
+                                     librbd::journal::MirrorPeerClientMeta *client_meta,
+                                     Context *on_finish) {
+    return new SnapshotCopyRequest(local_image_ctx, remote_image_ctx,
+                                   snap_map, journaler, client_meta, on_finish);
+  }
+
+  SnapshotCopyRequest(ImageCtxT *local_image_ctx, ImageCtxT *remote_image_ctx,
+                      SnapMap *snap_map, Journaler *journaler,
+                      librbd::journal::MirrorPeerClientMeta *client_meta,
+                      Context *on_finish);
+
+  void send();
+
+private:
+  /**
+   * @verbatim
+   *
+   * <start>
+   *    |
+   *    |   /-------\
+   *    |   |       |
+   *    v   v       | (repeat as needed)
+   * REMOVE_SNAP <--/
+   *    |
+   *    |   /-------\
+   *    |   |       |
+   *    v   v       | (repeat as needed)
+   * CREATE_SNAP <--/
+   *    |
+   *    v
+   * UPDATE_CLIENT
+   *    |
+   *    v
+   * <finish>
+   *
+   * @endverbatim
+   */
+
+  typedef std::set<librados::snap_t> SnapIdSet;
+  typedef std::map<librados::snap_t, librados::snap_t> SnapSeqs;
+
+  ImageCtxT *m_local_image_ctx;
+  ImageCtxT *m_remote_image_ctx;
+  SnapMap *m_snap_map;
+  Journaler *m_journaler;
+  librbd::journal::MirrorPeerClientMeta *m_client_meta;
+  Context *m_on_finish;
+
+  SnapIdSet m_local_snap_ids;
+  SnapIdSet m_remote_snap_ids;
+  SnapSeqs m_snap_seqs;
+
+  std::string m_snap_name;
+
+  void send_snap_remove();
+  void handle_snap_remove(int r);
+
+  void send_snap_create();
+  void handle_snap_create(int r);
+
+  void send_update_client();
+  void handle_update_client(int r);
+
+  void finish(int r);
+
+  void compute_snap_map();
+
+};
+
+} // namespace image_sync
+} // namespace mirror
+} // namespace rbd
+
+extern template class rbd::mirror::image_sync::SnapshotCopyRequest<librbd::ImageCtx>;
+
+#endif // RBD_MIRROR_IMAGE_SYNC_SNAPSHOT_COPY_REQUEST_H
diff --git a/src/tools/rbd_mirror/image_sync/SyncPointCreateRequest.cc b/src/tools/rbd_mirror/image_sync/SyncPointCreateRequest.cc
new file mode 100644
index 0000000..7446049
--- /dev/null
+++ b/src/tools/rbd_mirror/image_sync/SyncPointCreateRequest.cc
@@ -0,0 +1,162 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+
+#include "SyncPointCreateRequest.h"
+#include "include/uuid.h"
+#include "common/errno.h"
+#include "journal/Journaler.h"
+#include "librbd/ImageCtx.h"
+#include "librbd/ImageState.h"
+#include "librbd/Operations.h"
+#include "librbd/Utils.h"
+
+#define dout_subsys ceph_subsys_rbd_mirror
+#undef dout_prefix
+#define dout_prefix *_dout << "rbd::mirror::image_sync::SyncPointCreateRequest: " \
+                           << this << " " << __func__
+
+namespace rbd {
+namespace mirror {
+namespace image_sync {
+
+namespace {
+
+static const std::string SNAP_NAME_PREFIX(".rbd-mirror");
+
+} // anonymous namespace
+
+using librbd::util::create_context_callback;
+
+template <typename I>
+SyncPointCreateRequest<I>::SyncPointCreateRequest(I *remote_image_ctx,
+                                                  const std::string &mirror_uuid,
+                                                  Journaler *journaler,
+                                                  MirrorPeerClientMeta *client_meta,
+                                                  Context *on_finish)
+  : m_remote_image_ctx(remote_image_ctx), m_mirror_uuid(mirror_uuid),
+    m_journaler(journaler), m_client_meta(client_meta), m_on_finish(on_finish),
+    m_client_meta_copy(*client_meta) {
+  assert(m_client_meta->sync_points.size() < 2);
+
+  // initialize the updated client meta with the new sync point
+  m_client_meta_copy.sync_points.emplace_back();
+  if (m_client_meta_copy.sync_points.size() > 1) {
+    m_client_meta_copy.sync_points.back().from_snap_name =
+      m_client_meta_copy.sync_points.front().snap_name;
+  }
+}
+
+template <typename I>
+void SyncPointCreateRequest<I>::send() {
+  send_update_client();
+}
+
+template <typename I>
+void SyncPointCreateRequest<I>::send_update_client() {
+  uuid_d uuid_gen;
+  uuid_gen.generate_random();
+
+  MirrorPeerSyncPoint &sync_point = m_client_meta_copy.sync_points.back();
+  sync_point.snap_name = SNAP_NAME_PREFIX + "." + m_mirror_uuid + "." +
+                         uuid_gen.to_string();
+
+  CephContext *cct = m_remote_image_ctx->cct;
+  ldout(cct, 20) << ": sync_point=" << sync_point << dendl;
+
+  bufferlist client_data_bl;
+  librbd::journal::ClientData client_data(m_client_meta_copy);
+  ::encode(client_data, client_data_bl);
+
+  Context *ctx = create_context_callback<
+    SyncPointCreateRequest<I>, &SyncPointCreateRequest<I>::handle_update_client>(
+      this);
+  m_journaler->update_client(client_data_bl, ctx);
+}
+
+template <typename I>
+void SyncPointCreateRequest<I>::handle_update_client(int r) {
+  CephContext *cct = m_remote_image_ctx->cct;
+  ldout(cct, 20) << ": r=" << r << dendl;
+
+  if (r < 0) {
+    lderr(cct) << "failed to update client data: " << cpp_strerror(r) << dendl;
+    finish(r);
+    return;
+  }
+
+  // update provided meta structure to reflect reality
+  *m_client_meta = m_client_meta_copy;
+
+  send_refresh_image();
+}
+
+template <typename I>
+void SyncPointCreateRequest<I>::send_refresh_image() {
+  CephContext *cct = m_remote_image_ctx->cct;
+  ldout(cct, 20) << dendl;
+
+  Context *ctx = create_context_callback<
+    SyncPointCreateRequest<I>, &SyncPointCreateRequest<I>::handle_refresh_image>(
+      this);
+  m_remote_image_ctx->state->refresh(ctx);
+}
+
+template <typename I>
+void SyncPointCreateRequest<I>::handle_refresh_image(int r) {
+  CephContext *cct = m_remote_image_ctx->cct;
+  ldout(cct, 20) << ": r=" << r << dendl;
+
+  if (r < 0) {
+    lderr(cct) << "remote image refresh failed: " << cpp_strerror(r) << dendl;
+    finish(r);
+    return;
+  }
+
+  send_create_snap();
+}
+
+template <typename I>
+void SyncPointCreateRequest<I>::send_create_snap() {
+  CephContext *cct = m_remote_image_ctx->cct;
+  ldout(cct, 20) << dendl;
+
+  MirrorPeerSyncPoint &sync_point = m_client_meta_copy.sync_points.back();
+
+  Context *ctx = create_context_callback<
+    SyncPointCreateRequest<I>, &SyncPointCreateRequest<I>::handle_create_snap>(
+      this);
+  m_remote_image_ctx->operations->snap_create(
+    sync_point.snap_name.c_str(), ctx);
+}
+
+template <typename I>
+void SyncPointCreateRequest<I>::handle_create_snap(int r) {
+  CephContext *cct = m_remote_image_ctx->cct;
+  ldout(cct, 20) << ": r=" << r << dendl;
+
+  if (r == -EEXIST) {
+    send_update_client();
+    return;
+  } else if (r < 0) {
+    lderr(cct) << "failed to create snapshot: " << cpp_strerror(r) << dendl;
+    finish(r);
+    return;
+  }
+
+  finish(0);
+}
+
+template <typename I>
+void SyncPointCreateRequest<I>::finish(int r) {
+  CephContext *cct = m_remote_image_ctx->cct;
+  ldout(cct, 20) << ": r=" << r << dendl;
+
+  m_on_finish->complete(r);
+  delete this;
+}
+
+} // namespace image_sync
+} // namespace mirror
+} // namespace rbd
+
+template class rbd::mirror::image_sync::SyncPointCreateRequest<librbd::ImageCtx>;
diff --git a/src/tools/rbd_mirror/image_sync/SyncPointCreateRequest.h b/src/tools/rbd_mirror/image_sync/SyncPointCreateRequest.h
new file mode 100644
index 0000000..ce09eda
--- /dev/null
+++ b/src/tools/rbd_mirror/image_sync/SyncPointCreateRequest.h
@@ -0,0 +1,90 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+
+#ifndef RBD_MIRROR_IMAGE_SYNC_SYNC_POINT_CREATE_REQUEST_H
+#define RBD_MIRROR_IMAGE_SYNC_SYNC_POINT_CREATE_REQUEST_H
+
+#include "librbd/Journal.h"
+#include "librbd/journal/Types.h"
+#include <string>
+
+class Context;
+namespace journal { class Journaler; }
+namespace librbd { class ImageCtx; }
+namespace librbd { namespace journal { struct MirrorPeerClientMeta; } }
+
+namespace rbd {
+namespace mirror {
+namespace image_sync {
+
+template <typename ImageCtxT = librbd::ImageCtx>
+class SyncPointCreateRequest {
+public:
+  typedef librbd::journal::TypeTraits<ImageCtxT> TypeTraits;
+  typedef typename TypeTraits::Journaler Journaler;
+  typedef librbd::journal::MirrorPeerClientMeta MirrorPeerClientMeta;
+  typedef librbd::journal::MirrorPeerSyncPoint MirrorPeerSyncPoint;
+
+  static SyncPointCreateRequest* create(ImageCtxT *remote_image_ctx,
+                                        const std::string &mirror_uuid,
+                                        Journaler *journaler,
+                                        MirrorPeerClientMeta *client_meta,
+                                        Context *on_finish) {
+    return new SyncPointCreateRequest(remote_image_ctx, mirror_uuid, journaler,
+                                      client_meta, on_finish);
+  }
+
+  SyncPointCreateRequest(ImageCtxT *remote_image_ctx,
+                         const std::string &mirror_uuid, Journaler *journaler,
+                         MirrorPeerClientMeta *client_meta, Context *on_finish);
+
+  void send();
+
+private:
+  /**
+   * @verbatim
+   *
+   * <start>
+   *    |
+   *    v
+   * UPDATE_CLIENT < . .
+   *    |              .
+   *    v              .
+   * REFRESH_IMAGE     .
+   *    |              . (repeat on EEXIST)
+   *    v              .
+   * CREATE_SNAP . . . .
+   *    |
+   *    v
+   * <finish>
+   *
+   * @endverbatim
+   */
+
+  ImageCtxT *m_remote_image_ctx;
+  std::string m_mirror_uuid;
+  Journaler *m_journaler;
+  MirrorPeerClientMeta *m_client_meta;
+  Context *m_on_finish;
+
+  MirrorPeerClientMeta m_client_meta_copy;
+
+  void send_update_client();
+  void handle_update_client(int r);
+
+  void send_refresh_image();
+  void handle_refresh_image(int r);
+
+  void send_create_snap();
+  void handle_create_snap(int r);
+
+  void finish(int r);
+};
+
+} // namespace image_sync
+} // namespace mirror
+} // namespace rbd
+
+extern template class rbd::mirror::image_sync::SyncPointCreateRequest<librbd::ImageCtx>;
+
+#endif // RBD_MIRROR_IMAGE_SYNC_SYNC_POINT_CREATE_REQUEST_H
diff --git a/src/tools/rbd_mirror/image_sync/SyncPointPruneRequest.cc b/src/tools/rbd_mirror/image_sync/SyncPointPruneRequest.cc
new file mode 100644
index 0000000..6c653e4
--- /dev/null
+++ b/src/tools/rbd_mirror/image_sync/SyncPointPruneRequest.cc
@@ -0,0 +1,202 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+
+#include "SyncPointPruneRequest.h"
+#include "common/errno.h"
+#include "journal/Journaler.h"
+#include "librbd/ImageCtx.h"
+#include "librbd/ImageState.h"
+#include "librbd/Operations.h"
+#include "librbd/Utils.h"
+#include <set>
+
+#define dout_subsys ceph_subsys_rbd_mirror
+#undef dout_prefix
+#define dout_prefix *_dout << "rbd::mirror::image_sync::SyncPointPruneRequest: " \
+                           << this << " " << __func__
+namespace rbd {
+namespace mirror {
+namespace image_sync {
+
+using librbd::util::create_context_callback;
+
+template <typename I>
+SyncPointPruneRequest<I>::SyncPointPruneRequest(I *remote_image_ctx,
+                                                bool sync_complete,
+                                                Journaler *journaler,
+                                                MirrorPeerClientMeta *client_meta,
+                                                Context *on_finish)
+  : m_remote_image_ctx(remote_image_ctx), m_sync_complete(sync_complete),
+    m_journaler(journaler), m_client_meta(client_meta), m_on_finish(on_finish),
+    m_client_meta_copy(*client_meta) {
+}
+
+template <typename I>
+void SyncPointPruneRequest<I>::send() {
+  if (m_client_meta->sync_points.empty()) {
+    send_remove_snap();
+    return;
+  }
+
+  if (m_sync_complete) {
+    // if sync is complete, we can remove the master sync point
+    auto it = m_client_meta_copy.sync_points.begin();
+    MirrorPeerSyncPoint &sync_point = *it;
+
+    ++it;
+    if (it == m_client_meta_copy.sync_points.end() ||
+        it->from_snap_name != sync_point.snap_name) {
+      m_snap_names.push_back(sync_point.snap_name);
+    }
+
+    if (!sync_point.from_snap_name.empty()) {
+      m_snap_names.push_back(sync_point.from_snap_name);
+    }
+  } else {
+    // if we have more than one sync point, trim the extras off
+    std::set<std::string> snap_names;
+    for (auto it = m_client_meta_copy.sync_points.rbegin();
+         it != m_client_meta_copy.sync_points.rend(); ++it) {
+      MirrorPeerSyncPoint &sync_point =
+        m_client_meta_copy.sync_points.back();
+      if (&sync_point == &m_client_meta_copy.sync_points.front()) {
+        break;
+      }
+
+      if (snap_names.count(sync_point.snap_name) == 0) {
+        snap_names.insert(sync_point.snap_name);
+        m_snap_names.push_back(sync_point.snap_name);
+      }
+
+      MirrorPeerSyncPoint &front_sync_point =
+        m_client_meta_copy.sync_points.front();
+      if (!sync_point.from_snap_name.empty() &&
+          snap_names.count(sync_point.from_snap_name) == 0 &&
+          sync_point.from_snap_name != front_sync_point.snap_name) {
+        snap_names.insert(sync_point.from_snap_name);
+        m_snap_names.push_back(sync_point.from_snap_name);
+      }
+    }
+  }
+
+  send_remove_snap();
+}
+
+template <typename I>
+void SyncPointPruneRequest<I>::send_remove_snap() {
+  if (m_snap_names.empty()) {
+    send_refresh_image();
+    return;
+  }
+
+  std::string snap_name = m_snap_names.front();
+
+  CephContext *cct = m_remote_image_ctx->cct;
+  ldout(cct, 20) << ": snap_name=" << snap_name << dendl;
+
+  Context *ctx = create_context_callback<
+    SyncPointPruneRequest<I>, &SyncPointPruneRequest<I>::handle_remove_snap>(
+      this);
+  m_remote_image_ctx->operations->snap_remove(snap_name.c_str(), ctx);
+}
+
+template <typename I>
+void SyncPointPruneRequest<I>::handle_remove_snap(int r) {
+  CephContext *cct = m_remote_image_ctx->cct;
+  ldout(cct, 20) << ": r=" << r << dendl;
+
+  assert(!m_snap_names.empty());
+  std::string snap_name = m_snap_names.front();
+  m_snap_names.pop_front();
+
+  if (r == -ENOENT) {
+    r = 0;
+  }
+  if (r < 0) {
+    lderr(cct) << "failed to remove snapshot '" << snap_name << "': "
+               << cpp_strerror(r) << dendl;
+    finish(r);
+    return;
+  }
+
+  send_remove_snap();
+}
+
+template <typename I>
+void SyncPointPruneRequest<I>::send_refresh_image() {
+  CephContext *cct = m_remote_image_ctx->cct;
+  ldout(cct, 20) << dendl;
+
+  Context *ctx = create_context_callback<
+    SyncPointPruneRequest<I>, &SyncPointPruneRequest<I>::handle_refresh_image>(
+      this);
+  m_remote_image_ctx->state->refresh(ctx);
+}
+
+template <typename I>
+void SyncPointPruneRequest<I>::handle_refresh_image(int r) {
+  CephContext *cct = m_remote_image_ctx->cct;
+  ldout(cct, 20) << ": r=" << r << dendl;
+
+  if (r < 0) {
+    lderr(cct) << "remote image refresh failed: " << cpp_strerror(r) << dendl;
+    finish(r);
+    return;
+  }
+
+  send_update_client();
+}
+
+template <typename I>
+void SyncPointPruneRequest<I>::send_update_client() {
+  CephContext *cct = m_remote_image_ctx->cct;
+  ldout(cct, 20) << dendl;
+
+  if (m_sync_complete) {
+    m_client_meta_copy.sync_points.pop_front();
+  } else {
+    while (m_client_meta_copy.sync_points.size() > 1) {
+      m_client_meta_copy.sync_points.pop_back();
+    }
+  }
+
+  bufferlist client_data_bl;
+  librbd::journal::ClientData client_data(m_client_meta_copy);
+  ::encode(client_data, client_data_bl);
+
+  Context *ctx = create_context_callback<
+    SyncPointPruneRequest<I>, &SyncPointPruneRequest<I>::handle_update_client>(
+      this);
+  m_journaler->update_client(client_data_bl, ctx);
+}
+
+template <typename I>
+void SyncPointPruneRequest<I>::handle_update_client(int r) {
+  CephContext *cct = m_remote_image_ctx->cct;
+  ldout(cct, 20) << ": r=" << r << dendl;
+
+  if (r < 0) {
+    lderr(cct) << "failed to update client data: " << cpp_strerror(r) << dendl;
+    finish(r);
+    return;
+  }
+
+  // update provided meta structure to reflect reality
+  *m_client_meta = m_client_meta_copy;
+  finish(0);
+}
+
+template <typename I>
+void SyncPointPruneRequest<I>::finish(int r) {
+  CephContext *cct = m_remote_image_ctx->cct;
+  ldout(cct, 20) << ": r=" << r << dendl;
+
+  m_on_finish->complete(r);
+  delete this;
+}
+
+} // namespace image_sync
+} // namespace mirror
+} // namespace rbd
+
+template class rbd::mirror::image_sync::SyncPointPruneRequest<librbd::ImageCtx>;
diff --git a/src/tools/rbd_mirror/image_sync/SyncPointPruneRequest.h b/src/tools/rbd_mirror/image_sync/SyncPointPruneRequest.h
new file mode 100644
index 0000000..b643fbb
--- /dev/null
+++ b/src/tools/rbd_mirror/image_sync/SyncPointPruneRequest.h
@@ -0,0 +1,94 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+
+#ifndef RBD_MIRROR_IMAGE_SYNC_SYNC_POINT_PRUNE_REQUEST_H
+#define RBD_MIRROR_IMAGE_SYNC_SYNC_POINT_PRUNE_REQUEST_H
+
+#include "librbd/Journal.h"
+#include "librbd/journal/Types.h"
+#include <list>
+#include <string>
+
+class Context;
+namespace journal { class Journaler; }
+namespace librbd { class ImageCtx; }
+namespace librbd { namespace journal { struct MirrorPeerClientMeta; } }
+
+namespace rbd {
+namespace mirror {
+namespace image_sync {
+
+template <typename ImageCtxT = librbd::ImageCtx>
+class SyncPointPruneRequest {
+public:
+  typedef librbd::journal::TypeTraits<ImageCtxT> TypeTraits;
+  typedef typename TypeTraits::Journaler Journaler;
+  typedef librbd::journal::MirrorPeerClientMeta MirrorPeerClientMeta;
+  typedef librbd::journal::MirrorPeerSyncPoint MirrorPeerSyncPoint;
+
+  static SyncPointPruneRequest* create(ImageCtxT *remote_image_ctx,
+                                       bool sync_complete,
+                                       Journaler *journaler,
+                                       MirrorPeerClientMeta *client_meta,
+                                       Context *on_finish) {
+    return new SyncPointPruneRequest(remote_image_ctx, sync_complete, journaler,
+                                      client_meta, on_finish);
+  }
+
+  SyncPointPruneRequest(ImageCtxT *remote_image_ctx, bool sync_complete,
+                        Journaler *journaler, MirrorPeerClientMeta *client_meta,
+                        Context *on_finish);
+
+  void send();
+
+private:
+  /**
+   * @verbatim
+   *
+   * <start>
+   *    |
+   *    |    . . . . .
+   *    |    .       .
+   *    v    v       . (repeat if from snap
+   * REMOVE_SNAP . . .  unused by other sync)
+   *    |
+   *    v
+   * REFRESH_IMAGE
+   *    |
+   *    v
+   * UPDATE_CLIENT
+   *    |
+   *    v
+   * <finish>
+   *
+   * @endverbatim
+   */
+
+  ImageCtxT *m_remote_image_ctx;
+  bool m_sync_complete;
+  Journaler *m_journaler;
+  MirrorPeerClientMeta *m_client_meta;
+  Context *m_on_finish;
+
+  MirrorPeerClientMeta m_client_meta_copy;
+  std::list<std::string> m_snap_names;
+
+  void send_remove_snap();
+  void handle_remove_snap(int r);
+
+  void send_refresh_image();
+  void handle_refresh_image(int r);
+
+  void send_update_client();
+  void handle_update_client(int r);
+
+  void finish(int r);
+};
+
+} // namespace image_sync
+} // namespace mirror
+} // namespace rbd
+
+extern template class rbd::mirror::image_sync::SyncPointPruneRequest<librbd::ImageCtx>;
+
+#endif // RBD_MIRROR_IMAGE_SYNC_SYNC_POINT_PRUNE_REQUEST_H
diff --git a/src/tools/rbd_mirror/main.cc b/src/tools/rbd_mirror/main.cc
index 1236bf2..017f5a4 100644
--- a/src/tools/rbd_mirror/main.cc
+++ b/src/tools/rbd_mirror/main.cc
@@ -32,8 +32,8 @@ static void handle_signal(int signum)
 int main(int argc, const char **argv)
 {
   std::vector<const char*> args;
-  argv_to_vec(argc, argv, args);
   env_to_vec(args);
+  argv_to_vec(argc, argv, args);
 
   global_init(nullptr, args, CEPH_ENTITY_TYPE_CLIENT,
 	      CODE_ENVIRONMENT_DAEMON,
@@ -58,7 +58,10 @@ int main(int argc, const char **argv)
   register_async_signal_handler_oneshot(SIGINT, handle_signal);
   register_async_signal_handler_oneshot(SIGTERM, handle_signal);
 
-  mirror = new rbd::mirror::Mirror(g_ceph_context);
+  std::vector<const char*> cmd_args;
+  argv_to_vec(argc, argv, cmd_args);
+
+  mirror = new rbd::mirror::Mirror(g_ceph_context, cmd_args);
   int r = mirror->init();
   if (r < 0) {
     std::cerr << "failed to initialize: " << cpp_strerror(r) << std::endl;
diff --git a/src/tools/rbd_mirror/types.cc b/src/tools/rbd_mirror/types.cc
index 88ad3b2..b58dc14 100644
--- a/src/tools/rbd_mirror/types.cc
+++ b/src/tools/rbd_mirror/types.cc
@@ -5,7 +5,7 @@
 
 std::ostream& operator<<(std::ostream& lhs, const rbd::mirror::peer_t &peer)
 {
-  return lhs << "name: " << peer.cluster_name
-	     << " uuid: " << peer.cluster_uuid
+  return lhs << "uuid: " << peer.uuid
+	     << " cluster: " << peer.cluster_name
 	     << " client: " << peer.client_name;
 }
diff --git a/src/tools/rbd_mirror/types.h b/src/tools/rbd_mirror/types.h
index bdfc23b..c45b963 100644
--- a/src/tools/rbd_mirror/types.h
+++ b/src/tools/rbd_mirror/types.h
@@ -22,26 +22,26 @@ struct peer_t {
   peer_t() = default;
   peer_t(const std::string &uuid, const std::string &cluster_name,
 	 const std::string &client_name)
-    : cluster_uuid(uuid), cluster_name(cluster_name), client_name(client_name)
+    : uuid(uuid), cluster_name(cluster_name), client_name(client_name)
   {
   }
   peer_t(const librbd::mirror_peer_t &peer) :
-    cluster_uuid(peer.cluster_uuid),
+    uuid(peer.uuid),
     cluster_name(peer.cluster_name),
     client_name(peer.client_name)
   {
   }
-  std::string cluster_uuid;
+  std::string uuid;
   std::string cluster_name;
   std::string client_name;
   bool operator<(const peer_t &rhs) const {
-    return this->cluster_uuid < rhs.cluster_uuid;
+    return this->uuid < rhs.uuid;
   }
   bool operator()(const peer_t &lhs, const peer_t &rhs) const {
-    return lhs.cluster_uuid < rhs.cluster_uuid;
+    return lhs.uuid < rhs.uuid;
   }
   bool operator==(const peer_t &rhs) const {
-    return cluster_uuid == rhs.cluster_uuid;
+    return uuid == rhs.uuid;
   }
 };
 
diff --git a/src/tools/setup-virtualenv.sh b/src/tools/setup-virtualenv.sh
index f1c3f9a..9ff2d26 100755
--- a/src/tools/setup-virtualenv.sh
+++ b/src/tools/setup-virtualenv.sh
@@ -15,17 +15,19 @@
 # GNU Library Public License for more details.
 #
 
-rm -fr virtualenv
-virtualenv virtualenv
-. virtualenv/bin/activate
+DIR=$1
+rm -fr $DIR
+mkdir -p $DIR
+virtualenv --python python2.7 $DIR
+. $DIR/bin/activate
 # older versions of pip will not install wrap_console scripts
 # when using wheel packages
-pip --log virtualenv/log.txt install --upgrade 'pip >= 6.1'
+pip --log $DIR/log.txt install --upgrade 'pip >= 6.1'
 if test -d wheelhouse ; then
     export NO_INDEX=--no-index
 fi
-pip --log virtualenv/log.txt install $NO_INDEX --use-wheel --find-links=file://$(pwd)/wheelhouse --upgrade distribute
-pip --log virtualenv/log.txt install $NO_INDEX --use-wheel --find-links=file://$(pwd)/wheelhouse 'tox >=1.9' 
+pip --log $DIR/log.txt install $NO_INDEX --use-wheel --find-links=file://$(pwd)/wheelhouse --upgrade distribute
+pip --log $DIR/log.txt install $NO_INDEX --use-wheel --find-links=file://$(pwd)/wheelhouse 'tox >=1.9'
 if test -f requirements.txt ; then
-    pip --log virtualenv/log.txt install $NO_INDEX --use-wheel --find-links=file://$(pwd)/wheelhouse -r requirements.txt
+    pip --log $DIR/log.txt install $NO_INDEX --use-wheel --find-links=file://$(pwd)/wheelhouse -r requirements.txt
 fi
diff --git a/src/tracing/librados.tp b/src/tracing/librados.tp
index 7171787..a66464c 100644
--- a/src/tracing/librados.tp
+++ b/src/tracing/librados.tp
@@ -2273,6 +2273,34 @@ TRACEPOINT_EVENT(librados, rados_watch2_exit,
     )
 )
 
+TRACEPOINT_EVENT(librados, rados_aio_watch_enter,
+    TP_ARGS(
+        rados_ioctx_t, ioctx,
+        const char*, oid,
+        rados_completion_t, completion,
+        uint64_t*, phandle,
+        rados_watchcb2_t, callback,
+        void*, arg),
+    TP_FIELDS(
+        ctf_integer_hex(rados_ioctx_t, ioctx, ioctx)
+        ctf_string(oid, oid)
+        ctf_integer_hex(rados_completion_t, completion, completion)
+        ctf_integer_hex(uint64_t, phandle, phandle)
+        ctf_integer_hex(rados_watchcb2_t, callback, callback)
+        ctf_integer_hex(void*, arg, arg)
+    )
+)
+
+TRACEPOINT_EVENT(librados, rados_aio_watch_exit,
+    TP_ARGS(
+        int, retval,
+        uint64_t, handle),
+    TP_FIELDS(
+        ctf_integer(int, retval, retval)
+        ctf_integer(uint64_t, handle, handle)
+    )
+)
+
 TRACEPOINT_EVENT(librados, rados_unwatch_enter,
     TP_ARGS(
         rados_ioctx_t, ioctx,
@@ -2311,6 +2339,26 @@ TRACEPOINT_EVENT(librados, rados_unwatch2_exit,
     )
 )
 
+TRACEPOINT_EVENT(librados, rados_aio_unwatch_enter,
+    TP_ARGS(
+        rados_ioctx_t, ioctx,
+        uint64_t, handle,
+        rados_completion_t, completion),
+    TP_FIELDS(
+        ctf_integer_hex(rados_ioctx_t, ioctx, ioctx)
+        ctf_integer(uint64_t, handle, handle)
+        ctf_integer_hex(rados_completion_t, completion, completion)
+    )
+)
+
+TRACEPOINT_EVENT(librados, rados_aio_unwatch_exit,
+    TP_ARGS(
+        int, retval),
+    TP_FIELDS(
+        ctf_integer(int, retval, retval)
+    )
+)
+
 TRACEPOINT_EVENT(librados, rados_watch_check_enter,
     TP_ARGS(
         rados_ioctx_t, ioctx,
@@ -2441,6 +2489,24 @@ TRACEPOINT_EVENT(librados, rados_watch_flush_exit,
     )
 )
 
+TRACEPOINT_EVENT(librados, rados_aio_watch_flush_enter,
+    TP_ARGS(
+        rados_t, cluster,
+        rados_completion_t, completion),
+    TP_FIELDS(
+        ctf_integer_hex(rados_t, cluster, cluster)
+        ctf_integer_hex(rados_completion_t, completion, completion)
+    )
+)
+
+TRACEPOINT_EVENT(librados, rados_aio_watch_flush_exit,
+    TP_ARGS(
+        int, retval),
+    TP_FIELDS(
+        ctf_integer(int, retval, retval)
+    )
+)
+
 TRACEPOINT_EVENT(librados, rados_set_alloc_hint_enter,
     TP_ARGS(
         rados_ioctx_t, ioctx,
@@ -2990,6 +3056,22 @@ TRACEPOINT_EVENT(librados, rados_write_op_operate_enter,
     )
 )
 
+TRACEPOINT_EVENT(librados, rados_write_op_operate2_enter,
+    TP_ARGS(
+        rados_write_op_t, op,
+        rados_ioctx_t, ioctx,
+        const char*, oid,
+        struct timespec*, ts,
+        int, flags),
+    TP_FIELDS(
+        ctf_integer_hex(rados_write_op_t, op, op)
+        ctf_integer_hex(rados_ioctx_t, ioctx, ioctx)
+        ctf_string(oid, oid)
+        ceph_ctf_timespecp(ts, ts)
+        ctf_integer_hex(int, flags, flags)
+    )
+)
+
 TRACEPOINT_EVENT(librados, rados_write_op_operate_exit,
     TP_ARGS(
         int, retval),
@@ -3434,3 +3516,31 @@ TRACEPOINT_EVENT(librados, rados_cache_unpin_exit,
         ctf_integer(int, retval, retval)
     )
 )
+
+TRACEPOINT_EVENT(librados, rados_inconsistent_pg_list_enter,
+    TP_ARGS(
+        rados_t, cluster,
+        int64_t, id,
+        size_t, maxlen),
+    TP_FIELDS(
+        ctf_integer_hex(rados_t, cluster, cluster)
+        ctf_integer(int64_t, id, id)
+        ctf_integer(size_t, maxlen, maxlen)
+    )
+)
+
+TRACEPOINT_EVENT(librados, rados_inconsistent_pg_list_pg,
+    TP_ARGS(
+        const char*, buf),
+    TP_FIELDS(
+        ctf_string(buf, buf)
+    )
+)
+
+TRACEPOINT_EVENT(librados, rados_inconsistent_pg_list_exit,
+    TP_ARGS(
+        int, retval),
+    TP_FIELDS(
+        ctf_integer(int, retval, retval)
+    )
+)
diff --git a/src/tracing/objectstore.tp b/src/tracing/objectstore.tp
index 9c81083..d9f76e2 100644
--- a/src/tracing/objectstore.tp
+++ b/src/tracing/objectstore.tp
@@ -520,6 +520,19 @@ TRACEPOINT_EVENT(objectstore, coll_move_rename_exit,
     )
 )
 
+TRACEPOINT_EVENT(objectstore, coll_try_rename_enter,
+    TP_ARGS(),
+    TP_FIELDS()
+)
+
+TRACEPOINT_EVENT(objectstore, coll_try_rename_exit,
+    TP_ARGS(
+        int, retval),
+    TP_FIELDS(
+        ctf_integer(int, retval, retval)
+    )
+)
+
 TRACEPOINT_EVENT(objectstore, coll_remove_enter,
     TP_ARGS(
         const char *, osr_name),
diff --git a/src/tracing/tracing-common.h b/src/tracing/tracing-common.h
index aed4122..3e07f9d 100644
--- a/src/tracing/tracing-common.h
+++ b/src/tracing/tracing-common.h
@@ -79,6 +79,12 @@
     ctf_integer(long int, field##_usec, (p) == NULL ? 0 : (p)->tv_usec) \
     ctf_integer(uint8_t, field##_isnull, (p) == NULL)
 
+// p should be of type struct timespec*
+#define ceph_ctf_timespecp(field, p) \
+    ctf_integer(long int, field##_sec, (p) == NULL ? 0 : (p)->tv_sec) \
+    ctf_integer(long int, field##_nsec, (p) == NULL ? 0 : (p)->tv_nsec) \
+    ctf_integer(uint8_t, field##_isnull, (p) == NULL)
+
 // val should be of type time_t
 // Currently assumes that time_t is an integer and no more than 64 bits wide.
 // This is verified by the configure script.
diff --git a/src/upstart/ceph-rbd-mirror-all-starter.conf b/src/upstart/ceph-rbd-mirror-all-starter.conf
new file mode 100644
index 0000000..038cdb1
--- /dev/null
+++ b/src/upstart/ceph-rbd-mirror-all-starter.conf
@@ -0,0 +1,18 @@
+description "Ceph rbd-mirror (task to start all instances)"
+
+start on starting ceph-rbd-mirror-all
+
+task
+
+script
+  set -e
+  # TODO what's the valid charset for cluster names and daemon ids?
+  find -L /var/lib/ceph/rbd-mirror/ -mindepth 1 -maxdepth 1 -regextype posix-egrep -regex '.*/[A-Za-z0-9]+-[A-Za-z0-9._-]+' -printf '%P\n' \
+  | while read f; do
+    if [ -e "/var/lib/ceph/rbd-mirror/$f/done" ]; then
+        cluster="${f%%-*}"
+        id="${f#*-}"
+        initctl emit ceph-rbd-mirror cluster="$cluster" id="$id"
+    fi
+  done
+end script
diff --git a/src/upstart/ceph-rbd-mirror-all.conf b/src/upstart/ceph-rbd-mirror-all.conf
new file mode 100644
index 0000000..7e6126b
--- /dev/null
+++ b/src/upstart/ceph-rbd-mirror-all.conf
@@ -0,0 +1,4 @@
+description "Ceph rbd mirror (all instances)"
+
+start on starting ceph-all
+stop on runlevel [!2345] or stopping ceph-all
diff --git a/src/upstart/ceph-rbd-mirror.conf b/src/upstart/ceph-rbd-mirror.conf
new file mode 100644
index 0000000..a990111
--- /dev/null
+++ b/src/upstart/ceph-rbd-mirror.conf
@@ -0,0 +1,26 @@
+description "Ceph rbd mirror"
+
+start on ceph-rbd-mirror
+stop on runlevel [!2345] or stopping ceph-rbd-mirror-all
+
+respawn
+respawn limit 3 1800
+
+limit nofile 8096 65536
+
+pre-start script
+    set -e
+    test -x /usr/bin/rbd-mirror || { stop; exit 0; }
+    test -d "/var/lib/ceph/rbd-mirror/${cluster:-ceph}-$id" || { stop; exit 0; }
+
+    install -d -m0770 -o ceph -g ceph /var/run/ceph
+end script
+
+instance ${cluster:-ceph}/$id
+export cluster
+export id
+
+# this breaks oneiric
+#usage "cluster = name of cluster (defaults to 'ceph'); id = instance id"
+
+exec /usr/bin/rbd-mirror --cluster="${cluster:-ceph}" --id "$id" -f --setuser ceph --setgroup ceph
diff --git a/src/vstart.sh b/src/vstart.sh
index cccab88..151ca1b 100755
--- a/src/vstart.sh
+++ b/src/vstart.sh
@@ -10,6 +10,12 @@ if [ -n "$VSTART_DEST" ]; then
   CEPH_DIR=$SRC_PATH
   CEPH_BIN=$SRC_PATH
   CEPH_LIB=$SRC_PATH/.libs
+
+  if [ -e CMakeCache.txt ]; then
+      CEPH_BIN=$VSTART_DEST/../../src
+      CEPH_LIB=$CEPH_BIN
+  fi
+
   CEPH_CONF_PATH=$VSTART_DEST
   CEPH_DEV_DIR=$VSTART_DEST/dev
   CEPH_OUT_DIR=$VSTART_DEST/out
@@ -114,13 +120,13 @@ keyring_fn="$CEPH_CONF_PATH/keyring"
 osdmap_fn="/tmp/ceph_osdmap.$$"
 monmap_fn="/tmp/ceph_monmap.$$"
 
-usage="usage: $0 [option]... [mon] [mds] [osd]\n"
+usage="usage: $0 [option]... [\"mon\"] [\"mds\"] [\"osd\"]\n"
 usage=$usage"options:\n"
 usage=$usage"\t-d, --debug\n"
 usage=$usage"\t-s, --standby_mds: Generate standby-replay MDS for each active\n"
 usage=$usage"\t-l, --localhost: use localhost instead of hostname\n"
 usage=$usage"\t-i <ip>: bind to specific ip\n"
-usage=$usage"\t-r start radosgw (needs ceph compiled with --radosgw and apache2 with mod_fastcgi)\n"
+usage=$usage"\t-r start radosgw (needs ceph compiled with --radosgw)\n"
 usage=$usage"\t-n, --new\n"
 usage=$usage"\t--valgrind[_{osd,mds,mon}] 'toolname args...'\n"
 usage=$usage"\t--nodaemon: use ceph-run as wrapper for mon/osd/mds\n"
@@ -593,7 +599,7 @@ EOF
 	    fi
 
 	    rm -rf $CEPH_DEV_DIR/osd$osd || true
-	    for f in $CEPH_DEV_DIR/osd$osd/* ; do btrfs sub delete $f || true ; done || true
+	    for f in $CEPH_DEV_DIR/osd$osd/*; do btrfs sub delete $f &> /dev/null || true; done
 	    mkdir -p $CEPH_DEV_DIR/osd$osd
 
 	    uuid=`uuidgen`
@@ -621,6 +627,18 @@ EOF
 fi
 
 if [ "$start_mds" -eq 1 -a "$CEPH_NUM_MDS" -gt 0 ]; then
+    cmd="$CEPH_ADM osd pool create cephfs_data 8"
+    echo $cmd
+    $cmd
+
+    cmd="$CEPH_ADM osd pool create cephfs_metadata 8"
+    echo $cmd
+    $cmd
+
+    cmd="$CEPH_ADM fs new cephfs cephfs_metadata cephfs_data"
+    echo $cmd
+    $cmd
+
     mds=0
     for name in a b c d e f g h i j k l m n o p
     do
@@ -651,17 +669,6 @@ EOF
 			mon 'allow *' osd 'allow *' mds 'allow'
 	    fi
 
-        cmd="$CEPH_ADM osd pool create cephfs_data 8"
-        echo $cmd
-        $cmd
-
-        cmd="$CEPH_ADM osd pool create cephfs_metadata 8"
-        echo $cmd
-        $cmd
-
-        cmd="$CEPH_ADM fs new cephfs cephfs_metadata cephfs_data"
-        echo $cmd
-        $cmd
 	fi
 	
 	run 'mds' $CEPH_BIN/ceph-mds -i $name $ARGS $CMDS_ARGS
@@ -676,9 +683,6 @@ EOF
 #$CEPH_BIN/ceph-mds -d $ARGS --mds_thrash_fragments 0 --mds_thrash_exports 0 #--debug_ms 20
 #$CEPH_ADM mds set max_mds 2
     done
-    cmd="$CEPH_ADM mds set max_mds $CEPH_NUM_MDS"
-    echo $cmd
-    $cmd
 fi
 
 if [ "$ec" -eq 1 ]; then
@@ -721,17 +725,6 @@ do_hitsets $hitset
 
 do_rgw()
 {
-    # Start server
-    echo start rgw on http://localhost:$CEPH_RGW_PORT
-    RGWDEBUG=""
-    if [ "$debug" -ne 0 ]; then
-        RGWDEBUG="--debug-rgw=20"
-    fi
-
-    RGWSUDO=
-    [ $CEPH_RGW_PORT -lt 1024 ] && RGWSUDO=sudo
-    $RGWSUDO $CEPH_BIN/radosgw -c $conf_fn --log-file=${CEPH_OUT_DIR}/rgw.log ${RGWDEBUG} --debug-ms=1
-
     # Create S3 user
     local akey='0555b35654ad1656d804'
     local skey='h7GhxuBLTrlhVUyxSPUKUV8r/2EI4ngqJxD7iBdBYLhwluN30JaT3Q=='
@@ -768,6 +761,17 @@ do_rgw()
     echo "  user      : tester"
     echo "  password  : testing"
     echo ""
+
+    # Start server
+    echo start rgw on http://localhost:$CEPH_RGW_PORT
+    RGWDEBUG=""
+    if [ "$debug" -ne 0 ]; then
+        RGWDEBUG="--debug-rgw=20"
+    fi
+
+    RGWSUDO=
+    [ $CEPH_RGW_PORT -lt 1024 ] && RGWSUDO=sudo
+    $RGWSUDO $CEPH_BIN/radosgw -c $conf_fn --log-file=${CEPH_OUT_DIR}/rgw.log ${RGWDEBUG} --debug-ms=1
 }
 if [ "$start_rgw" -eq 1 ]; then
     do_rgw
diff --git a/src/xxHash/xxhash.c b/src/xxHash/xxhash.c
new file mode 100644
index 0000000..35f5315
--- /dev/null
+++ b/src/xxHash/xxhash.c
@@ -0,0 +1,1012 @@
+/*
+xxHash - Fast Hash algorithm
+Copyright (C) 2012-2016, Yann Collet
+
+BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+* Redistributions of source code must retain the above copyright
+notice, this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above
+copyright notice, this list of conditions and the following disclaimer
+in the documentation and/or other materials provided with the
+distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+You can contact the author at :
+- xxHash source repository : https://github.com/Cyan4973/xxHash
+*/
+
+
+/* *************************************
+*  Tuning parameters
+***************************************/
+/*!XXH_FORCE_MEMORY_ACCESS
+ * By default, access to unaligned memory is controlled by `memcpy()`, which is safe and portable.
+ * Unfortunately, on some target/compiler combinations, the generated assembly is sub-optimal.
+ * The below switch allow to select different access method for improved performance.
+ * Method 0 (default) : use `memcpy()`. Safe and portable.
+ * Method 1 : `__packed` statement. It depends on compiler extension (ie, not portable).
+ *            This method is safe if your compiler supports it, and *generally* as fast or faster than `memcpy`.
+ * Method 2 : direct access. This method doesn't depend on compiler but violate C standard.
+ *            It can generate buggy code on targets which do not support unaligned memory accesses.
+ *            But in some circumstances, it's the only known way to get the most performance (ie GCC + ARMv6)
+ * See http://stackoverflow.com/a/32095106/646947 for details.
+ * Prefer these methods in priority order (0 > 1 > 2)
+ */
+#ifndef XXH_FORCE_MEMORY_ACCESS   /* can be defined externally, on command line for example */
+#  if defined(__GNUC__) && ( defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) || defined(__ARM_ARCH_6K__) || defined(__ARM_ARCH_6Z__) || defined(__ARM_ARCH_6ZK__) || defined(__ARM_ARCH_6T2__) )
+#    define XXH_FORCE_MEMORY_ACCESS 2
+#  elif defined(__INTEL_COMPILER) || \
+  (defined(__GNUC__) && ( defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) || defined(__ARM_ARCH_7R__) || defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7S__) ))
+#    define XXH_FORCE_MEMORY_ACCESS 1
+#  endif
+#endif
+
+/*!XXH_ACCEPT_NULL_INPUT_POINTER :
+ * If the input pointer is a null pointer, xxHash default behavior is to trigger a memory access error, since it is a bad pointer.
+ * When this option is enabled, xxHash output for null input pointers will be the same as a null-length input.
+ * By default, this option is disabled. To enable it, uncomment below define :
+ */
+/* #define XXH_ACCEPT_NULL_INPUT_POINTER 1 */
+
+/*!XXH_FORCE_NATIVE_FORMAT :
+ * By default, xxHash library provides endian-independant Hash values, based on little-endian convention.
+ * Results are therefore identical for little-endian and big-endian CPU.
+ * This comes at a performance cost for big-endian CPU, since some swapping is required to emulate little-endian format.
+ * Should endian-independance be of no importance for your application, you may set the #define below to 1,
+ * to improve speed for Big-endian CPU.
+ * This option has no impact on Little_Endian CPU.
+ */
+#define XXH_FORCE_NATIVE_FORMAT 0
+
+/*!XXH_USELESS_ALIGN_BRANCH :
+ * This is a minor performance trick, only useful with lots of very small keys.
+ * It means : don't check for aligned/unaligned input, because performance will be the same.
+ * It saves one initial branch per hash.
+ */
+#if defined(__i386) || defined(_M_IX86) || defined(__x86_64__) || defined(_M_X64)
+#  define XXH_USELESS_ALIGN_BRANCH 1
+#endif
+
+
+/* *************************************
+*  Compiler Specific Options
+***************************************/
+#ifdef _MSC_VER    /* Visual Studio */
+#  pragma warning(disable : 4127)      /* disable: C4127: conditional expression is constant */
+#  define FORCE_INLINE static __forceinline
+#else
+#  if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L   /* C99 */
+#    ifdef __GNUC__
+#      define FORCE_INLINE static inline __attribute__((always_inline))
+#    else
+#      define FORCE_INLINE static inline
+#    endif
+#  else
+#    define FORCE_INLINE static
+#  endif /* __STDC_VERSION__ */
+#endif
+
+
+/* *************************************
+*  Includes & Memory related functions
+***************************************/
+/* Modify the local functions below should you wish to use some other memory routines */
+/* for malloc(), free() */
+#include <stdlib.h>
+static void* XXH_malloc(size_t s) { return malloc(s); }
+static void  XXH_free  (void* p)  { free(p); }
+/* for memcpy() */
+#include <string.h>
+static void* XXH_memcpy(void* dest, const void* src, size_t size) { return memcpy(dest,src,size); }
+
+#include "xxhash.h"
+
+
+/* *************************************
+*  Basic Types
+***************************************/
+#ifndef MEM_MODULE
+# define MEM_MODULE
+# if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L   /* C99 */
+#   include <stdint.h>
+    typedef uint8_t  BYTE;
+    typedef uint16_t U16;
+    typedef uint32_t U32;
+    typedef  int32_t S32;
+    typedef uint64_t U64;
+#  else
+    typedef unsigned char      BYTE;
+    typedef unsigned short     U16;
+    typedef unsigned int       U32;
+    typedef   signed int       S32;
+    typedef unsigned long long U64;
+#  endif
+#endif
+
+
+#if (defined(XXH_FORCE_MEMORY_ACCESS) && (XXH_FORCE_MEMORY_ACCESS==2))
+
+/* Force direct memory access. Only works on CPU which support unaligned memory access in hardware */
+static U32 XXH_read32(const void* memPtr) { return *(const U32*) memPtr; }
+static U64 XXH_read64(const void* memPtr) { return *(const U64*) memPtr; }
+
+#elif (defined(XXH_FORCE_MEMORY_ACCESS) && (XXH_FORCE_MEMORY_ACCESS==1))
+
+/* __pack instructions are safer, but compiler specific, hence potentially problematic for some compilers */
+/* currently only defined for gcc and icc */
+typedef union { U32 u32; U64 u64; } __attribute__((packed)) unalign;
+
+static U32 XXH_read32(const void* ptr) { return ((const unalign*)ptr)->u32; }
+static U64 XXH_read64(const void* ptr) { return ((const unalign*)ptr)->u64; }
+
+#else
+
+/* portable and safe solution. Generally efficient.
+ * see : http://stackoverflow.com/a/32095106/646947
+ */
+
+static U32 XXH_read32(const void* memPtr)
+{
+    U32 val;
+    memcpy(&val, memPtr, sizeof(val));
+    return val;
+}
+
+static U64 XXH_read64(const void* memPtr)
+{
+    U64 val;
+    memcpy(&val, memPtr, sizeof(val));
+    return val;
+}
+
+#endif   /* XXH_FORCE_DIRECT_MEMORY_ACCESS */
+
+
+/* ****************************************
+*  Compiler-specific Functions and Macros
+******************************************/
+#define GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__)
+
+/* Note : although _rotl exists for minGW (GCC under windows), performance seems poor */
+#if defined(_MSC_VER)
+#  define XXH_rotl32(x,r) _rotl(x,r)
+#  define XXH_rotl64(x,r) _rotl64(x,r)
+#else
+#  define XXH_rotl32(x,r) ((x << r) | (x >> (32 - r)))
+#  define XXH_rotl64(x,r) ((x << r) | (x >> (64 - r)))
+#endif
+
+#if defined(_MSC_VER)     /* Visual Studio */
+#  define XXH_swap32 _byteswap_ulong
+#  define XXH_swap64 _byteswap_uint64
+#elif GCC_VERSION >= 403
+#  define XXH_swap32 __builtin_bswap32
+#  define XXH_swap64 __builtin_bswap64
+#else
+static U32 XXH_swap32 (U32 x)
+{
+    return  ((x << 24) & 0xff000000 ) |
+            ((x <<  8) & 0x00ff0000 ) |
+            ((x >>  8) & 0x0000ff00 ) |
+            ((x >> 24) & 0x000000ff );
+}
+static U64 XXH_swap64 (U64 x)
+{
+    return  ((x << 56) & 0xff00000000000000ULL) |
+            ((x << 40) & 0x00ff000000000000ULL) |
+            ((x << 24) & 0x0000ff0000000000ULL) |
+            ((x << 8)  & 0x000000ff00000000ULL) |
+            ((x >> 8)  & 0x00000000ff000000ULL) |
+            ((x >> 24) & 0x0000000000ff0000ULL) |
+            ((x >> 40) & 0x000000000000ff00ULL) |
+            ((x >> 56) & 0x00000000000000ffULL);
+}
+#endif
+
+
+/* *************************************
+*  Architecture Macros
+***************************************/
+typedef enum { XXH_bigEndian=0, XXH_littleEndian=1 } XXH_endianess;
+
+/* XXH_CPU_LITTLE_ENDIAN can be defined externally, for example on the compiler command line */
+#ifndef XXH_CPU_LITTLE_ENDIAN
+    static const int g_one = 1;
+#   define XXH_CPU_LITTLE_ENDIAN   (*(const char*)(&g_one))
+#endif
+
+
+/* ***************************
+*  Memory reads
+*****************************/
+typedef enum { XXH_aligned, XXH_unaligned } XXH_alignment;
+
+FORCE_INLINE U32 XXH_readLE32_align(const void* ptr, XXH_endianess endian, XXH_alignment align)
+{
+    if (align==XXH_unaligned)
+        return endian==XXH_littleEndian ? XXH_read32(ptr) : XXH_swap32(XXH_read32(ptr));
+    else
+        return endian==XXH_littleEndian ? *(const U32*)ptr : XXH_swap32(*(const U32*)ptr);
+}
+
+FORCE_INLINE U32 XXH_readLE32(const void* ptr, XXH_endianess endian)
+{
+    return XXH_readLE32_align(ptr, endian, XXH_unaligned);
+}
+
+static U32 XXH_readBE32(const void* ptr)
+{
+    return XXH_CPU_LITTLE_ENDIAN ? XXH_swap32(XXH_read32(ptr)) : XXH_read32(ptr);
+}
+
+FORCE_INLINE U64 XXH_readLE64_align(const void* ptr, XXH_endianess endian, XXH_alignment align)
+{
+    if (align==XXH_unaligned)
+        return endian==XXH_littleEndian ? XXH_read64(ptr) : XXH_swap64(XXH_read64(ptr));
+    else
+        return endian==XXH_littleEndian ? *(const U64*)ptr : XXH_swap64(*(const U64*)ptr);
+}
+
+FORCE_INLINE U64 XXH_readLE64(const void* ptr, XXH_endianess endian)
+{
+    return XXH_readLE64_align(ptr, endian, XXH_unaligned);
+}
+
+static U64 XXH_readBE64(const void* ptr)
+{
+    return XXH_CPU_LITTLE_ENDIAN ? XXH_swap64(XXH_read64(ptr)) : XXH_read64(ptr);
+}
+
+
+/* *************************************
+*  Macros
+***************************************/
+#define XXH_STATIC_ASSERT(c)   { enum { XXH_static_assert = 1/(int)(!!(c)) }; }    /* use only *after* variable declarations */
+
+
+/* *************************************
+*  Constants
+***************************************/
+#define PRIME32_1   2654435761U
+#define PRIME32_2   2246822519U
+#define PRIME32_3   3266489917U
+#define PRIME32_4    668265263U
+#define PRIME32_5    374761393U
+
+#define PRIME64_1 11400714785074694791ULL
+#define PRIME64_2 14029467366897019727ULL
+#define PRIME64_3  1609587929392839161ULL
+#define PRIME64_4  9650029242287828579ULL
+#define PRIME64_5  2870177450012600261ULL
+
+XXH_PUBLIC_API unsigned XXH_versionNumber (void) { return XXH_VERSION_NUMBER; }
+
+
+/* ***************************
+*  Simple Hash Functions
+*****************************/
+FORCE_INLINE U32 XXH32_endian_align(const void* input, size_t len, U32 seed, XXH_endianess endian, XXH_alignment align)
+{
+    const BYTE* p = (const BYTE*)input;
+    const BYTE* bEnd = p + len;
+    U32 h32;
+#define XXH_get32bits(p) XXH_readLE32_align(p, endian, align)
+
+#ifdef XXH_ACCEPT_NULL_INPUT_POINTER
+    if (p==NULL)
+    {
+        len=0;
+        bEnd=p=(const BYTE*)(size_t)16;
+    }
+#endif
+
+    if (len>=16)
+    {
+        const BYTE* const limit = bEnd - 16;
+        U32 v1 = seed + PRIME32_1 + PRIME32_2;
+        U32 v2 = seed + PRIME32_2;
+        U32 v3 = seed + 0;
+        U32 v4 = seed - PRIME32_1;
+
+        do
+        {
+            v1 += XXH_get32bits(p) * PRIME32_2;
+            v1 = XXH_rotl32(v1, 13);
+            v1 *= PRIME32_1;
+            p+=4;
+            v2 += XXH_get32bits(p) * PRIME32_2;
+            v2 = XXH_rotl32(v2, 13);
+            v2 *= PRIME32_1;
+            p+=4;
+            v3 += XXH_get32bits(p) * PRIME32_2;
+            v3 = XXH_rotl32(v3, 13);
+            v3 *= PRIME32_1;
+            p+=4;
+            v4 += XXH_get32bits(p) * PRIME32_2;
+            v4 = XXH_rotl32(v4, 13);
+            v4 *= PRIME32_1;
+            p+=4;
+        }
+        while (p<=limit);
+
+        h32 = XXH_rotl32(v1, 1) + XXH_rotl32(v2, 7) + XXH_rotl32(v3, 12) + XXH_rotl32(v4, 18);
+    }
+    else
+    {
+        h32  = seed + PRIME32_5;
+    }
+
+    h32 += (U32) len;
+
+    while (p+4<=bEnd)
+    {
+        h32 += XXH_get32bits(p) * PRIME32_3;
+        h32  = XXH_rotl32(h32, 17) * PRIME32_4 ;
+        p+=4;
+    }
+
+    while (p<bEnd)
+    {
+        h32 += (*p) * PRIME32_5;
+        h32 = XXH_rotl32(h32, 11) * PRIME32_1 ;
+        p++;
+    }
+
+    h32 ^= h32 >> 15;
+    h32 *= PRIME32_2;
+    h32 ^= h32 >> 13;
+    h32 *= PRIME32_3;
+    h32 ^= h32 >> 16;
+
+    return h32;
+}
+
+
+XXH_PUBLIC_API unsigned int XXH32 (const void* input, size_t len, unsigned int seed)
+{
+#if 0
+    /* Simple version, good for code maintenance, but unfortunately slow for small inputs */
+    XXH32_CREATESTATE_STATIC(state);
+    XXH32_reset(state, seed);
+    XXH32_update(state, input, len);
+    return XXH32_digest(state);
+#else
+    XXH_endianess endian_detected = (XXH_endianess)XXH_CPU_LITTLE_ENDIAN;
+
+#  if !defined(XXH_USELESS_ALIGN_BRANCH)
+    if ((((size_t)input) & 3) == 0)   /* Input is 4-bytes aligned, leverage the speed benefit */
+    {
+        if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT)
+            return XXH32_endian_align(input, len, seed, XXH_littleEndian, XXH_aligned);
+        else
+            return XXH32_endian_align(input, len, seed, XXH_bigEndian, XXH_aligned);
+    }
+#  endif
+
+    if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT)
+        return XXH32_endian_align(input, len, seed, XXH_littleEndian, XXH_unaligned);
+    else
+        return XXH32_endian_align(input, len, seed, XXH_bigEndian, XXH_unaligned);
+#endif
+}
+
+FORCE_INLINE U64 XXH64_endian_align(const void* input, size_t len, U64 seed, XXH_endianess endian, XXH_alignment align)
+{
+    const BYTE* p = (const BYTE*)input;
+    const BYTE* bEnd = p + len;
+    U64 h64;
+#define XXH_get64bits(p) XXH_readLE64_align(p, endian, align)
+
+#ifdef XXH_ACCEPT_NULL_INPUT_POINTER
+    if (p==NULL)
+    {
+        len=0;
+        bEnd=p=(const BYTE*)(size_t)32;
+    }
+#endif
+
+    if (len>=32)
+    {
+        const BYTE* const limit = bEnd - 32;
+        U64 v1 = seed + PRIME64_1 + PRIME64_2;
+        U64 v2 = seed + PRIME64_2;
+        U64 v3 = seed + 0;
+        U64 v4 = seed - PRIME64_1;
+
+        do
+        {
+            v1 += XXH_get64bits(p) * PRIME64_2;
+            p+=8;
+            v1 = XXH_rotl64(v1, 31);
+            v1 *= PRIME64_1;
+            v2 += XXH_get64bits(p) * PRIME64_2;
+            p+=8;
+            v2 = XXH_rotl64(v2, 31);
+            v2 *= PRIME64_1;
+            v3 += XXH_get64bits(p) * PRIME64_2;
+            p+=8;
+            v3 = XXH_rotl64(v3, 31);
+            v3 *= PRIME64_1;
+            v4 += XXH_get64bits(p) * PRIME64_2;
+            p+=8;
+            v4 = XXH_rotl64(v4, 31);
+            v4 *= PRIME64_1;
+        }
+        while (p<=limit);
+
+        h64 = XXH_rotl64(v1, 1) + XXH_rotl64(v2, 7) + XXH_rotl64(v3, 12) + XXH_rotl64(v4, 18);
+
+        v1 *= PRIME64_2;
+        v1 = XXH_rotl64(v1, 31);
+        v1 *= PRIME64_1;
+        h64 ^= v1;
+        h64 = h64 * PRIME64_1 + PRIME64_4;
+
+        v2 *= PRIME64_2;
+        v2 = XXH_rotl64(v2, 31);
+        v2 *= PRIME64_1;
+        h64 ^= v2;
+        h64 = h64 * PRIME64_1 + PRIME64_4;
+
+        v3 *= PRIME64_2;
+        v3 = XXH_rotl64(v3, 31);
+        v3 *= PRIME64_1;
+        h64 ^= v3;
+        h64 = h64 * PRIME64_1 + PRIME64_4;
+
+        v4 *= PRIME64_2;
+        v4 = XXH_rotl64(v4, 31);
+        v4 *= PRIME64_1;
+        h64 ^= v4;
+        h64 = h64 * PRIME64_1 + PRIME64_4;
+    }
+    else
+    {
+        h64  = seed + PRIME64_5;
+    }
+
+    h64 += (U64) len;
+
+    while (p+8<=bEnd)
+    {
+        U64 k1 = XXH_get64bits(p);
+        k1 *= PRIME64_2;
+        k1 = XXH_rotl64(k1,31);
+        k1 *= PRIME64_1;
+        h64 ^= k1;
+        h64 = XXH_rotl64(h64,27) * PRIME64_1 + PRIME64_4;
+        p+=8;
+    }
+
+    if (p+4<=bEnd)
+    {
+        h64 ^= (U64)(XXH_get32bits(p)) * PRIME64_1;
+        h64 = XXH_rotl64(h64, 23) * PRIME64_2 + PRIME64_3;
+        p+=4;
+    }
+
+    while (p<bEnd)
+    {
+        h64 ^= (*p) * PRIME64_5;
+        h64 = XXH_rotl64(h64, 11) * PRIME64_1;
+        p++;
+    }
+
+    h64 ^= h64 >> 33;
+    h64 *= PRIME64_2;
+    h64 ^= h64 >> 29;
+    h64 *= PRIME64_3;
+    h64 ^= h64 >> 32;
+
+    return h64;
+}
+
+
+XXH_PUBLIC_API unsigned long long XXH64 (const void* input, size_t len, unsigned long long seed)
+{
+#if 0
+    /* Simple version, good for code maintenance, but unfortunately slow for small inputs */
+    XXH64_CREATESTATE_STATIC(state);
+    XXH64_reset(state, seed);
+    XXH64_update(state, input, len);
+    return XXH64_digest(state);
+#else
+    XXH_endianess endian_detected = (XXH_endianess)XXH_CPU_LITTLE_ENDIAN;
+
+#  if !defined(XXH_USELESS_ALIGN_BRANCH)
+    if ((((size_t)input) & 7)==0)   /* Input is aligned, let's leverage the speed advantage */
+    {
+        if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT)
+            return XXH64_endian_align(input, len, seed, XXH_littleEndian, XXH_aligned);
+        else
+            return XXH64_endian_align(input, len, seed, XXH_bigEndian, XXH_aligned);
+    }
+#  endif
+
+    if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT)
+        return XXH64_endian_align(input, len, seed, XXH_littleEndian, XXH_unaligned);
+    else
+        return XXH64_endian_align(input, len, seed, XXH_bigEndian, XXH_unaligned);
+#endif
+}
+
+/* **************************************************
+*  Advanced Hash Functions
+****************************************************/
+
+/*** Allocation ***/
+struct XXH32_state_s
+{
+    U64 total_len;
+    U32 seed;
+    U32 v1;
+    U32 v2;
+    U32 v3;
+    U32 v4;
+    U32 mem32[4];   /* defined as U32 for alignment */
+    U32 memsize;
+};   /* typedef'd to XXH32_state_t within xxhash.h */
+
+struct XXH64_state_s
+{
+    U64 total_len;
+    U64 seed;
+    U64 v1;
+    U64 v2;
+    U64 v3;
+    U64 v4;
+    U64 mem64[4];   /* defined as U64 for alignment */
+    U32 memsize;
+};   /* typedef'd to XXH64_state_t within xxhash.h */
+
+
+XXH_PUBLIC_API XXH32_state_t* XXH32_createState(void)
+{
+    XXH_STATIC_ASSERT(sizeof(XXH32_stateBody_t) >= sizeof(XXH32_state_t));   /* A compilation error here means XXH32_state_t is not large enough */
+    return (XXH32_state_t*)XXH_malloc(sizeof(XXH32_state_t));
+}
+XXH_PUBLIC_API XXH_errorcode XXH32_freeState(XXH32_state_t* statePtr)
+{
+    XXH_free(statePtr);
+    return XXH_OK;
+}
+
+XXH_PUBLIC_API XXH64_state_t* XXH64_createState(void)
+{
+    XXH_STATIC_ASSERT(sizeof(XXH64_stateBody_t) >= sizeof(XXH64_state_t));   /* A compilation error here means XXH64_state_t is not large enough */
+    return (XXH64_state_t*)XXH_malloc(sizeof(XXH64_state_t));
+}
+XXH_PUBLIC_API XXH_errorcode XXH64_freeState(XXH64_state_t* statePtr)
+{
+    XXH_free(statePtr);
+    return XXH_OK;
+}
+
+
+/*** Hash feed ***/
+
+XXH_PUBLIC_API XXH_errorcode XXH32_reset(XXH32_state_t* statePtr, unsigned int seed)
+{
+    XXH32_state_t state;   /* using a local state to memcpy() in order to avoid strict-aliasing warnings */
+    memset(&state, 0, sizeof(state));
+    state.seed = seed;
+    state.v1 = seed + PRIME32_1 + PRIME32_2;
+    state.v2 = seed + PRIME32_2;
+    state.v3 = seed + 0;
+    state.v4 = seed - PRIME32_1;
+    memcpy(statePtr, &state, sizeof(state));
+    return XXH_OK;
+}
+
+
+XXH_PUBLIC_API XXH_errorcode XXH64_reset(XXH64_state_t* statePtr, unsigned long long seed)
+{
+    XXH64_state_t state;   /* using a local state to memcpy() in order to avoid strict-aliasing warnings */
+    memset(&state, 0, sizeof(state));
+    state.seed = seed;
+    state.v1 = seed + PRIME64_1 + PRIME64_2;
+    state.v2 = seed + PRIME64_2;
+    state.v3 = seed + 0;
+    state.v4 = seed - PRIME64_1;
+    memcpy(statePtr, &state, sizeof(state));
+    return XXH_OK;
+}
+
+
+FORCE_INLINE XXH_errorcode XXH32_update_endian (XXH32_state_t* state, const void* input, size_t len, XXH_endianess endian)
+{
+    const BYTE* p = (const BYTE*)input;
+    const BYTE* const bEnd = p + len;
+
+#ifdef XXH_ACCEPT_NULL_INPUT_POINTER
+    if (input==NULL) return XXH_ERROR;
+#endif
+
+    state->total_len += len;
+
+    if (state->memsize + len < 16)   /* fill in tmp buffer */
+    {
+        XXH_memcpy((BYTE*)(state->mem32) + state->memsize, input, len);
+        state->memsize += (U32)len;
+        return XXH_OK;
+    }
+
+    if (state->memsize)   /* some data left from previous update */
+    {
+        XXH_memcpy((BYTE*)(state->mem32) + state->memsize, input, 16-state->memsize);
+        {
+            const U32* p32 = state->mem32;
+            state->v1 += XXH_readLE32(p32, endian) * PRIME32_2;
+            state->v1 = XXH_rotl32(state->v1, 13);
+            state->v1 *= PRIME32_1;
+            p32++;
+            state->v2 += XXH_readLE32(p32, endian) * PRIME32_2;
+            state->v2 = XXH_rotl32(state->v2, 13);
+            state->v2 *= PRIME32_1;
+            p32++;
+            state->v3 += XXH_readLE32(p32, endian) * PRIME32_2;
+            state->v3 = XXH_rotl32(state->v3, 13);
+            state->v3 *= PRIME32_1;
+            p32++;
+            state->v4 += XXH_readLE32(p32, endian) * PRIME32_2;
+            state->v4 = XXH_rotl32(state->v4, 13);
+            state->v4 *= PRIME32_1;
+            p32++;
+        }
+        p += 16-state->memsize;
+        state->memsize = 0;
+    }
+
+    if (p <= bEnd-16)
+    {
+        const BYTE* const limit = bEnd - 16;
+        U32 v1 = state->v1;
+        U32 v2 = state->v2;
+        U32 v3 = state->v3;
+        U32 v4 = state->v4;
+
+        do
+        {
+            v1 += XXH_readLE32(p, endian) * PRIME32_2;
+            v1 = XXH_rotl32(v1, 13);
+            v1 *= PRIME32_1;
+            p+=4;
+            v2 += XXH_readLE32(p, endian) * PRIME32_2;
+            v2 = XXH_rotl32(v2, 13);
+            v2 *= PRIME32_1;
+            p+=4;
+            v3 += XXH_readLE32(p, endian) * PRIME32_2;
+            v3 = XXH_rotl32(v3, 13);
+            v3 *= PRIME32_1;
+            p+=4;
+            v4 += XXH_readLE32(p, endian) * PRIME32_2;
+            v4 = XXH_rotl32(v4, 13);
+            v4 *= PRIME32_1;
+            p+=4;
+        }
+        while (p<=limit);
+
+        state->v1 = v1;
+        state->v2 = v2;
+        state->v3 = v3;
+        state->v4 = v4;
+    }
+
+    if (p < bEnd)
+    {
+        XXH_memcpy(state->mem32, p, bEnd-p);
+        state->memsize = (int)(bEnd-p);
+    }
+
+    return XXH_OK;
+}
+
+XXH_PUBLIC_API XXH_errorcode XXH32_update (XXH32_state_t* state_in, const void* input, size_t len)
+{
+    XXH_endianess endian_detected = (XXH_endianess)XXH_CPU_LITTLE_ENDIAN;
+
+    if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT)
+        return XXH32_update_endian(state_in, input, len, XXH_littleEndian);
+    else
+        return XXH32_update_endian(state_in, input, len, XXH_bigEndian);
+}
+
+
+
+FORCE_INLINE U32 XXH32_digest_endian (const XXH32_state_t* state, XXH_endianess endian)
+{
+    const BYTE * p = (const BYTE*)state->mem32;
+    const BYTE* bEnd = (const BYTE*)(state->mem32) + state->memsize;
+    U32 h32;
+
+    if (state->total_len >= 16)
+    {
+        h32 = XXH_rotl32(state->v1, 1) + XXH_rotl32(state->v2, 7) + XXH_rotl32(state->v3, 12) + XXH_rotl32(state->v4, 18);
+    }
+    else
+    {
+        h32  = state->seed + PRIME32_5;
+    }
+
+    h32 += (U32) state->total_len;
+
+    while (p+4<=bEnd)
+    {
+        h32 += XXH_readLE32(p, endian) * PRIME32_3;
+        h32  = XXH_rotl32(h32, 17) * PRIME32_4;
+        p+=4;
+    }
+
+    while (p<bEnd)
+    {
+        h32 += (*p) * PRIME32_5;
+        h32 = XXH_rotl32(h32, 11) * PRIME32_1;
+        p++;
+    }
+
+    h32 ^= h32 >> 15;
+    h32 *= PRIME32_2;
+    h32 ^= h32 >> 13;
+    h32 *= PRIME32_3;
+    h32 ^= h32 >> 16;
+
+    return h32;
+}
+
+
+XXH_PUBLIC_API unsigned int XXH32_digest (const XXH32_state_t* state_in)
+{
+    XXH_endianess endian_detected = (XXH_endianess)XXH_CPU_LITTLE_ENDIAN;
+
+    if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT)
+        return XXH32_digest_endian(state_in, XXH_littleEndian);
+    else
+        return XXH32_digest_endian(state_in, XXH_bigEndian);
+}
+
+
+
+/* **** XXH64 **** */
+
+FORCE_INLINE XXH_errorcode XXH64_update_endian (XXH64_state_t* state, const void* input, size_t len, XXH_endianess endian)
+{
+    const BYTE* p = (const BYTE*)input;
+    const BYTE* const bEnd = p + len;
+
+#ifdef XXH_ACCEPT_NULL_INPUT_POINTER
+    if (input==NULL) return XXH_ERROR;
+#endif
+
+    state->total_len += len;
+
+    if (state->memsize + len < 32)   /* fill in tmp buffer */
+    {
+        XXH_memcpy(((BYTE*)state->mem64) + state->memsize, input, len);
+        state->memsize += (U32)len;
+        return XXH_OK;
+    }
+
+    if (state->memsize)   /* some data left from previous update */
+    {
+        XXH_memcpy(((BYTE*)state->mem64) + state->memsize, input, 32-state->memsize);
+        {
+            const U64* p64 = state->mem64;
+            state->v1 += XXH_readLE64(p64, endian) * PRIME64_2;
+            state->v1 = XXH_rotl64(state->v1, 31);
+            state->v1 *= PRIME64_1;
+            p64++;
+            state->v2 += XXH_readLE64(p64, endian) * PRIME64_2;
+            state->v2 = XXH_rotl64(state->v2, 31);
+            state->v2 *= PRIME64_1;
+            p64++;
+            state->v3 += XXH_readLE64(p64, endian) * PRIME64_2;
+            state->v3 = XXH_rotl64(state->v3, 31);
+            state->v3 *= PRIME64_1;
+            p64++;
+            state->v4 += XXH_readLE64(p64, endian) * PRIME64_2;
+            state->v4 = XXH_rotl64(state->v4, 31);
+            state->v4 *= PRIME64_1;
+            p64++;
+        }
+        p += 32-state->memsize;
+        state->memsize = 0;
+    }
+
+    if (p+32 <= bEnd)
+    {
+        const BYTE* const limit = bEnd - 32;
+        U64 v1 = state->v1;
+        U64 v2 = state->v2;
+        U64 v3 = state->v3;
+        U64 v4 = state->v4;
+
+        do
+        {
+            v1 += XXH_readLE64(p, endian) * PRIME64_2;
+            v1 = XXH_rotl64(v1, 31);
+            v1 *= PRIME64_1;
+            p+=8;
+            v2 += XXH_readLE64(p, endian) * PRIME64_2;
+            v2 = XXH_rotl64(v2, 31);
+            v2 *= PRIME64_1;
+            p+=8;
+            v3 += XXH_readLE64(p, endian) * PRIME64_2;
+            v3 = XXH_rotl64(v3, 31);
+            v3 *= PRIME64_1;
+            p+=8;
+            v4 += XXH_readLE64(p, endian) * PRIME64_2;
+            v4 = XXH_rotl64(v4, 31);
+            v4 *= PRIME64_1;
+            p+=8;
+        }
+        while (p<=limit);
+
+        state->v1 = v1;
+        state->v2 = v2;
+        state->v3 = v3;
+        state->v4 = v4;
+    }
+
+    if (p < bEnd)
+    {
+        XXH_memcpy(state->mem64, p, bEnd-p);
+        state->memsize = (int)(bEnd-p);
+    }
+
+    return XXH_OK;
+}
+
+XXH_PUBLIC_API XXH_errorcode XXH64_update (XXH64_state_t* state_in, const void* input, size_t len)
+{
+    XXH_endianess endian_detected = (XXH_endianess)XXH_CPU_LITTLE_ENDIAN;
+
+    if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT)
+        return XXH64_update_endian(state_in, input, len, XXH_littleEndian);
+    else
+        return XXH64_update_endian(state_in, input, len, XXH_bigEndian);
+}
+
+
+
+FORCE_INLINE U64 XXH64_digest_endian (const XXH64_state_t* state, XXH_endianess endian)
+{
+    const BYTE * p = (const BYTE*)state->mem64;
+    const BYTE* bEnd = (const BYTE*)state->mem64 + state->memsize;
+    U64 h64;
+
+    if (state->total_len >= 32)
+    {
+        U64 v1 = state->v1;
+        U64 v2 = state->v2;
+        U64 v3 = state->v3;
+        U64 v4 = state->v4;
+
+        h64 = XXH_rotl64(v1, 1) + XXH_rotl64(v2, 7) + XXH_rotl64(v3, 12) + XXH_rotl64(v4, 18);
+
+        v1 *= PRIME64_2;
+        v1 = XXH_rotl64(v1, 31);
+        v1 *= PRIME64_1;
+        h64 ^= v1;
+        h64 = h64*PRIME64_1 + PRIME64_4;
+
+        v2 *= PRIME64_2;
+        v2 = XXH_rotl64(v2, 31);
+        v2 *= PRIME64_1;
+        h64 ^= v2;
+        h64 = h64*PRIME64_1 + PRIME64_4;
+
+        v3 *= PRIME64_2;
+        v3 = XXH_rotl64(v3, 31);
+        v3 *= PRIME64_1;
+        h64 ^= v3;
+        h64 = h64*PRIME64_1 + PRIME64_4;
+
+        v4 *= PRIME64_2;
+        v4 = XXH_rotl64(v4, 31);
+        v4 *= PRIME64_1;
+        h64 ^= v4;
+        h64 = h64*PRIME64_1 + PRIME64_4;
+    }
+    else
+    {
+        h64  = state->seed + PRIME64_5;
+    }
+
+    h64 += (U64) state->total_len;
+
+    while (p+8<=bEnd)
+    {
+        U64 k1 = XXH_readLE64(p, endian);
+        k1 *= PRIME64_2;
+        k1 = XXH_rotl64(k1,31);
+        k1 *= PRIME64_1;
+        h64 ^= k1;
+        h64 = XXH_rotl64(h64,27) * PRIME64_1 + PRIME64_4;
+        p+=8;
+    }
+
+    if (p+4<=bEnd)
+    {
+        h64 ^= (U64)(XXH_readLE32(p, endian)) * PRIME64_1;
+        h64 = XXH_rotl64(h64, 23) * PRIME64_2 + PRIME64_3;
+        p+=4;
+    }
+
+    while (p<bEnd)
+    {
+        h64 ^= (*p) * PRIME64_5;
+        h64 = XXH_rotl64(h64, 11) * PRIME64_1;
+        p++;
+    }
+
+    h64 ^= h64 >> 33;
+    h64 *= PRIME64_2;
+    h64 ^= h64 >> 29;
+    h64 *= PRIME64_3;
+    h64 ^= h64 >> 32;
+
+    return h64;
+}
+
+
+XXH_PUBLIC_API unsigned long long XXH64_digest (const XXH64_state_t* state_in)
+{
+    XXH_endianess endian_detected = (XXH_endianess)XXH_CPU_LITTLE_ENDIAN;
+
+    if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT)
+        return XXH64_digest_endian(state_in, XXH_littleEndian);
+    else
+        return XXH64_digest_endian(state_in, XXH_bigEndian);
+}
+
+
+/* **************************
+*  Canonical representation
+****************************/
+
+/*! Default XXH result types are basic unsigned 32 and 64 bits.
+*   The canonical representation follows human-readable write convention, aka big-endian (large digits first).
+*   These functions allow transformation of hash result into and from its canonical format.
+*   This way, hash values can be written into a file or buffer, and remain comparable across different systems and programs.
+*/
+
+XXH_PUBLIC_API void XXH32_canonicalFromHash(XXH32_canonical_t* dst, XXH32_hash_t hash)
+{
+    XXH_STATIC_ASSERT(sizeof(XXH32_canonical_t) == sizeof(XXH32_hash_t));
+    if (XXH_CPU_LITTLE_ENDIAN) hash = XXH_swap32(hash);
+    memcpy(dst, &hash, sizeof(*dst));
+}
+
+XXH_PUBLIC_API void XXH64_canonicalFromHash(XXH64_canonical_t* dst, XXH64_hash_t hash)
+{
+    XXH_STATIC_ASSERT(sizeof(XXH64_canonical_t) == sizeof(XXH64_hash_t));
+    if (XXH_CPU_LITTLE_ENDIAN) hash = XXH_swap64(hash);
+    memcpy(dst, &hash, sizeof(*dst));
+}
+
+XXH_PUBLIC_API XXH32_hash_t XXH32_hashFromCanonical(const XXH32_canonical_t* src)
+{
+    return XXH_readBE32(src);
+}
+
+XXH_PUBLIC_API XXH64_hash_t XXH64_hashFromCanonical(const XXH64_canonical_t* src)
+{
+    return XXH_readBE64(src);
+}
+
diff --git a/src/xxHash/xxhash.h b/src/xxHash/xxhash.h
new file mode 100644
index 0000000..ed7ae14
--- /dev/null
+++ b/src/xxHash/xxhash.h
@@ -0,0 +1,255 @@
+/*
+   xxHash - Extremely Fast Hash algorithm
+   Header File
+   Copyright (C) 2012-2016, Yann Collet.
+
+   BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)
+
+   Redistribution and use in source and binary forms, with or without
+   modification, are permitted provided that the following conditions are
+   met:
+
+       * Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+       * Redistributions in binary form must reproduce the above
+   copyright notice, this list of conditions and the following disclaimer
+   in the documentation and/or other materials provided with the
+   distribution.
+
+   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+   You can contact the author at :
+   - xxHash source repository : https://github.com/Cyan4973/xxHash
+*/
+
+/* Notice extracted from xxHash homepage :
+
+xxHash is an extremely fast Hash algorithm, running at RAM speed limits.
+It also successfully passes all tests from the SMHasher suite.
+
+Comparison (single thread, Windows Seven 32 bits, using SMHasher on a Core 2 Duo @3GHz)
+
+Name            Speed       Q.Score   Author
+xxHash          5.4 GB/s     10
+CrapWow         3.2 GB/s      2       Andrew
+MumurHash 3a    2.7 GB/s     10       Austin Appleby
+SpookyHash      2.0 GB/s     10       Bob Jenkins
+SBox            1.4 GB/s      9       Bret Mulvey
+Lookup3         1.2 GB/s      9       Bob Jenkins
+SuperFastHash   1.2 GB/s      1       Paul Hsieh
+CityHash64      1.05 GB/s    10       Pike & Alakuijala
+FNV             0.55 GB/s     5       Fowler, Noll, Vo
+CRC32           0.43 GB/s     9
+MD5-32          0.33 GB/s    10       Ronald L. Rivest
+SHA1-32         0.28 GB/s    10
+
+Q.Score is a measure of quality of the hash function.
+It depends on successfully passing SMHasher test set.
+10 is a perfect score.
+
+A 64-bits version, named XXH64, is available since r35.
+It offers much better speed, but for 64-bits applications only.
+Name     Speed on 64 bits    Speed on 32 bits
+XXH64       13.8 GB/s            1.9 GB/s
+XXH32        6.8 GB/s            6.0 GB/s
+*/
+
+#ifndef XXHASH_H_5627135585666179
+#define XXHASH_H_5627135585666179 1
+
+#if defined (__cplusplus)
+extern "C" {
+#endif
+
+
+/* ****************************
+*  Definitions
+******************************/
+#include <stddef.h>   /* size_t */
+typedef enum { XXH_OK=0, XXH_ERROR } XXH_errorcode;
+
+
+/* ****************************
+*  API modifier
+******************************/
+/*!XXH_PRIVATE_API
+*  Transforms all publics symbols within `xxhash.c` into private ones.
+*  Methodology :
+*  instead of : #include "xxhash.h"
+*  do :
+*     #define XXH_PRIVATE_API
+*     #include "xxhash.c"   // note the .c , instead of .h
+*  also : don't compile and link xxhash.c separately
+*/
+#ifdef XXH_PRIVATE_API
+#  if defined(__GNUC__)
+#    define XXH_PUBLIC_API static __attribute__((unused))
+#  elif defined (__cplusplus) || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */)
+#    define XXH_PUBLIC_API static inline
+#  elif defined(_MSC_VER)
+#    define XXH_PUBLIC_API static __inline
+#  else
+#    define XXH_PUBLIC_API static   /* this version may generate warnings for unused static functions; disable the relevant warning */
+#  endif
+#else
+#  define XXH_PUBLIC_API   /* do nothing */
+#endif
+
+/*!XXH_NAMESPACE, aka Namespace Emulation :
+
+If you want to include _and expose_ xxHash functions from within your own library,
+but also want to avoid symbol collisions with another library which also includes xxHash,
+
+you can use XXH_NAMESPACE, to automatically prefix any public symbol from `xxhash.c`
+with the value of XXH_NAMESPACE (so avoid to keep it NULL and avoid numeric values).
+
+Note that no change is required within the calling program as long as it also includes `xxhash.h` :
+regular symbol name will be automatically translated by this header.
+*/
+#ifdef XXH_NAMESPACE
+#  define XXH_CAT(A,B) A##B
+#  define XXH_NAME2(A,B) XXH_CAT(A,B)
+#  define XXH32 XXH_NAME2(XXH_NAMESPACE, XXH32)
+#  define XXH64 XXH_NAME2(XXH_NAMESPACE, XXH64)
+#  define XXH_versionNumber XXH_NAME2(XXH_NAMESPACE, XXH_versionNumber)
+#  define XXH32_createState XXH_NAME2(XXH_NAMESPACE, XXH32_createState)
+#  define XXH64_createState XXH_NAME2(XXH_NAMESPACE, XXH64_createState)
+#  define XXH32_freeState XXH_NAME2(XXH_NAMESPACE, XXH32_freeState)
+#  define XXH64_freeState XXH_NAME2(XXH_NAMESPACE, XXH64_freeState)
+#  define XXH32_reset XXH_NAME2(XXH_NAMESPACE, XXH32_reset)
+#  define XXH64_reset XXH_NAME2(XXH_NAMESPACE, XXH64_reset)
+#  define XXH32_update XXH_NAME2(XXH_NAMESPACE, XXH32_update)
+#  define XXH64_update XXH_NAME2(XXH_NAMESPACE, XXH64_update)
+#  define XXH32_digest XXH_NAME2(XXH_NAMESPACE, XXH32_digest)
+#  define XXH64_digest XXH_NAME2(XXH_NAMESPACE, XXH64_digest)
+#endif
+
+
+/* *************************************
+*  Version
+***************************************/
+#define XXH_VERSION_MAJOR    0
+#define XXH_VERSION_MINOR    5
+#define XXH_VERSION_RELEASE  1
+#define XXH_VERSION_NUMBER  (XXH_VERSION_MAJOR *100*100 + XXH_VERSION_MINOR *100 + XXH_VERSION_RELEASE)
+XXH_PUBLIC_API unsigned XXH_versionNumber (void);
+
+
+/* ****************************
+*  Simple Hash Functions
+******************************/
+typedef unsigned int       XXH32_hash_t;
+typedef unsigned long long XXH64_hash_t;
+
+XXH_PUBLIC_API XXH32_hash_t XXH32 (const void* input, size_t length, unsigned int seed);
+XXH_PUBLIC_API XXH64_hash_t XXH64 (const void* input, size_t length, unsigned long long seed);
+
+/*!
+XXH32() :
+    Calculate the 32-bits hash of sequence "length" bytes stored at memory address "input".
+    The memory between input & input+length must be valid (allocated and read-accessible).
+    "seed" can be used to alter the result predictably.
+    Speed on Core 2 Duo @ 3 GHz (single thread, SMHasher benchmark) : 5.4 GB/s
+XXH64() :
+    Calculate the 64-bits hash of sequence of length "len" stored at memory address "input".
+    "seed" can be used to alter the result predictably.
+    This function runs faster on 64-bits systems, but slower on 32-bits systems (see benchmark).
+*/
+
+
+/* ****************************
+*  Streaming Hash Functions
+******************************/
+typedef struct XXH32_state_s XXH32_state_t;   /* incomplete type */
+typedef struct XXH64_state_s XXH64_state_t;   /* incomplete type */
+
+
+/*! Static allocation
+    For static linking only, do not use in the context of DLL !
+        XXHnn_CREATESTATE_STATIC(name);
+            is static-allocation equivalent of :
+        XXHnn_state_t* name = XXHnn_createState();
+*/
+typedef struct { long long ll[ 6]; } XXH32_stateBody_t;
+typedef struct { long long ll[11]; } XXH64_stateBody_t;
+
+#define XXH32_CREATESTATE_STATIC(name) XXH32_stateBody_t name##xxhbody; void* name##xxhvoid = &(name##xxhbody); XXH32_state_t* name = (XXH32_state_t*)(name##xxhvoid)   /* no final ; */
+#define XXH64_CREATESTATE_STATIC(name) XXH64_stateBody_t name##xxhbody; void* name##xxhvoid = &(name##xxhbody); XXH64_state_t* name = (XXH64_state_t*)(name##xxhvoid)   /* no final ; */
+
+
+/*!Dynamic allocation
+   To be preferred in the context of DLL */
+
+XXH_PUBLIC_API XXH32_state_t* XXH32_createState(void);
+XXH_PUBLIC_API XXH_errorcode  XXH32_freeState(XXH32_state_t* statePtr);
+
+XXH_PUBLIC_API XXH64_state_t* XXH64_createState(void);
+XXH_PUBLIC_API XXH_errorcode  XXH64_freeState(XXH64_state_t* statePtr);
+
+
+/* hash streaming */
+
+XXH_PUBLIC_API XXH_errorcode XXH32_reset  (XXH32_state_t* statePtr, unsigned int seed);
+XXH_PUBLIC_API XXH_errorcode XXH32_update (XXH32_state_t* statePtr, const void* input, size_t length);
+XXH_PUBLIC_API XXH32_hash_t  XXH32_digest (const XXH32_state_t* statePtr);
+
+XXH_PUBLIC_API XXH_errorcode XXH64_reset  (XXH64_state_t* statePtr, unsigned long long seed);
+XXH_PUBLIC_API XXH_errorcode XXH64_update (XXH64_state_t* statePtr, const void* input, size_t length);
+XXH_PUBLIC_API XXH64_hash_t  XXH64_digest (const XXH64_state_t* statePtr);
+
+/*!
+These functions generate the xxHash of an input provided in multiple segments,
+as opposed to provided as a single block.
+
+XXH state must first be allocated, using either static or dynamic method provided above.
+
+Start a new hash by initializing state with a seed, using XXHnn_reset().
+
+Then, feed the hash state by calling XXHnn_update() as many times as necessary.
+Obviously, input must be valid, hence allocated and read accessible.
+The function returns an error code, with 0 meaning OK, and any other value meaning there is an error.
+
+Finally, a hash value can be produced anytime, by using XXHnn_digest().
+This function returns the nn-bits hash as an int or long long.
+
+It's still possible to continue inserting input into the hash state after a digest,
+and later on generate some new hashes, by calling again XXHnn_digest().
+
+When done, free XXH state space if it was allocated dynamically.
+*/
+
+
+/* **************************
+*  Canonical representation
+****************************/
+typedef struct { unsigned char digest[4]; } XXH32_canonical_t;
+typedef struct { unsigned char digest[8]; } XXH64_canonical_t;
+
+XXH_PUBLIC_API void XXH32_canonicalFromHash(XXH32_canonical_t* dst, XXH32_hash_t hash);
+XXH_PUBLIC_API void XXH64_canonicalFromHash(XXH64_canonical_t* dst, XXH64_hash_t hash);
+
+XXH_PUBLIC_API XXH32_hash_t XXH32_hashFromCanonical(const XXH32_canonical_t* src);
+XXH_PUBLIC_API XXH64_hash_t XXH64_hashFromCanonical(const XXH64_canonical_t* src);
+
+/*! Default result type for XXH functions are primitive unsigned 32 and 64 bits.
+*   The canonical representation uses human-readable write convention, aka big-endian (large digits first).
+*   These functions allow transformation of hash result into and from its canonical format.
+*   This way, hash values can be written into a file / memory, and remain comparable on different systems and programs.
+*/
+
+
+#if defined (__cplusplus)
+}
+#endif
+
+#endif /* XXHASH_H_5627135585666179 */
diff --git a/systemd/Makefile.am b/systemd/Makefile.am
index 6d93c3c..a6aecc9 100644
--- a/systemd/Makefile.am
+++ b/systemd/Makefile.am
@@ -4,11 +4,13 @@ unitfiles = \
         ceph-mon.target \
         ceph-mds.target \
         ceph-radosgw.target \
+	ceph-rbd-mirror.target \
 	ceph-mds at .service \
 	ceph-mon at .service \
 	ceph-create-keys at .service \
 	ceph-osd at .service \
 	ceph-radosgw at .service \
+	ceph-rbd-mirror at .service \
 	ceph-disk at .service \
 	rbdmap.service
 
diff --git a/systemd/Makefile.in b/systemd/Makefile.in
index 49ec69d..5a62803 100644
--- a/systemd/Makefile.in
+++ b/systemd/Makefile.in
@@ -1,7 +1,7 @@
-# Makefile.in generated by automake 1.15 from Makefile.am.
+# Makefile.in generated by automake 1.14.1 from Makefile.am.
 # @configure_input@
 
-# Copyright (C) 1994-2014 Free Software Foundation, Inc.
+# Copyright (C) 1994-2013 Free Software Foundation, Inc.
 
 # This Makefile.in is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -15,17 +15,7 @@
 @SET_MAKE@
 
 VPATH = @srcdir@
-am__is_gnu_make = { \
-  if test -z '$(MAKELEVEL)'; then \
-    false; \
-  elif test -n '$(MAKE_HOST)'; then \
-    true; \
-  elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
-    true; \
-  else \
-    false; \
-  fi; \
-}
+am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
 am__make_running_with_option = \
   case $${target_option-} in \
       ?) ;; \
@@ -90,6 +80,7 @@ build_triplet = @build@
 host_triplet = @host@
 target_triplet = @target@
 subdir = systemd
+DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
 am__aclocal_m4_deps = $(top_srcdir)/m4/ac_check_classpath.m4 \
 	$(top_srcdir)/m4/ac_prog_jar.m4 \
@@ -108,7 +99,6 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/ac_check_classpath.m4 \
 	$(top_srcdir)/m4/pkg.m4 $(top_srcdir)/configure.ac
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
 	$(ACLOCAL_M4)
-DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON)
 mkinstalldirs = $(install_sh) -d
 CONFIG_HEADER = $(top_builddir)/src/acconfig.h
 CONFIG_CLEAN_FILES =
@@ -162,7 +152,6 @@ am__uninstall_files_from_dir = { \
 am__installdirs = "$(DESTDIR)$(unitdir)"
 DATA = $(unit_DATA)
 am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
-am__DIST_COMMON = $(srcdir)/Makefile.in
 DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
 ACLOCAL = @ACLOCAL@
 AMTAR = @AMTAR@
@@ -255,7 +244,6 @@ LN_S = @LN_S@
 LTLIBOBJS = @LTLIBOBJS@
 LTTNG_GEN_TP_CHECK = @LTTNG_GEN_TP_CHECK@
 LTTNG_GEN_TP_PROG = @LTTNG_GEN_TP_PROG@
-LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
 MAKEINFO = @MAKEINFO@
 MANIFEST_TOOL = @MANIFEST_TOOL@
 MKDIR_P = @MKDIR_P@
@@ -282,7 +270,10 @@ PTHREAD_CC = @PTHREAD_CC@
 PTHREAD_CFLAGS = @PTHREAD_CFLAGS@
 PTHREAD_LIBS = @PTHREAD_LIBS@
 PYTHON = @PYTHON@
+PYTHON_CFLAGS = @PYTHON_CFLAGS@
+PYTHON_CONFIG_CHECK = @PYTHON_CONFIG_CHECK@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
+PYTHON_LDFLAGS = @PYTHON_LDFLAGS@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
 PYTHON_PREFIX = @PYTHON_PREFIX@
 PYTHON_VERSION = @PYTHON_VERSION@
@@ -351,7 +342,6 @@ program_transform_name = @program_transform_name@
 psdir = @psdir@
 pyexecdir = @pyexecdir@
 pythondir = @pythondir@
-runstatedir = @runstatedir@
 sbindir = @sbindir@
 sharedstatedir = @sharedstatedir@
 srcdir = @srcdir@
@@ -372,11 +362,13 @@ unitfiles = \
         ceph-mon.target \
         ceph-mds.target \
         ceph-radosgw.target \
+	ceph-rbd-mirror.target \
 	ceph-mds at .service \
 	ceph-mon at .service \
 	ceph-create-keys at .service \
 	ceph-osd at .service \
 	ceph-radosgw at .service \
+	ceph-rbd-mirror at .service \
 	ceph-disk at .service \
 	rbdmap.service
 
@@ -402,6 +394,7 @@ $(srcdir)/Makefile.in:  $(srcdir)/Makefile.am  $(am__configure_deps)
 	echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign systemd/Makefile'; \
 	$(am__cd) $(top_srcdir) && \
 	  $(AUTOMAKE) --foreign systemd/Makefile
+.PRECIOUS: Makefile
 Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
 	@case '$?' in \
 	  *config.status*) \
@@ -600,8 +593,6 @@ uninstall-am: uninstall-unitDATA
 	mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \
 	ps ps-am tags-am uninstall uninstall-am uninstall-unitDATA
 
-.PRECIOUS: Makefile
-
 
 # Tell versions [3.59,3.63) of GNU make to not export all variables.
 # Otherwise a system limit (for SysV at least) may be exceeded.
diff --git a/systemd/ceph-rbd-mirror.target b/systemd/ceph-rbd-mirror.target
new file mode 100644
index 0000000..7bd94e0
--- /dev/null
+++ b/systemd/ceph-rbd-mirror.target
@@ -0,0 +1,5 @@
+[Unit]
+Description=ceph target allowing to start/stop all ceph-rbd-mirror at .service instances at once
+PartOf=ceph.target
+[Install]
+WantedBy=multi-user.target ceph.target
diff --git a/systemd/ceph-rbd-mirror at .service b/systemd/ceph-rbd-mirror at .service
new file mode 100644
index 0000000..4c2e2f0
--- /dev/null
+++ b/systemd/ceph-rbd-mirror at .service
@@ -0,0 +1,22 @@
+[Unit]
+Description=Ceph rbd mirror daemon
+After=network-online.target local-fs.target
+Wants=network-online.target local-fs.target
+
+[Service]
+LimitNOFILE=1048576
+LimitNPROC=1048576
+EnvironmentFile=-/etc/sysconfig/ceph
+Environment=CLUSTER=ceph
+ExecStart=/usr/bin/rbd-mirror -f --cluster ${CLUSTER} --id %i --setuser ceph --setgroup ceph
+ExecReload=/bin/kill -HUP $MAINPID
+PrivateDevices=yes
+ProtectHome=true
+ProtectSystem=full
+PrivateTmp=true
+Restart=on-failure
+StartLimitInterval=30min
+StartLimitBurst=3
+
+[Install]
+WantedBy=ceph-rbd-mirror.target
diff --git a/test-driver b/test-driver
index 8e575b0..d306056 100755
--- a/test-driver
+++ b/test-driver
@@ -3,7 +3,7 @@
 
 scriptversion=2013-07-13.22; # UTC
 
-# Copyright (C) 2011-2014 Free Software Foundation, Inc.
+# Copyright (C) 2011-2013 Free Software Foundation, Inc.
 #
 # This program is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
@@ -106,14 +106,11 @@ trap "st=143; $do_exit" 15
 # Test script is run here.
 "$@" >$log_file 2>&1
 estatus=$?
-
 if test $enable_hard_errors = no && test $estatus -eq 99; then
-  tweaked_estatus=1
-else
-  tweaked_estatus=$estatus
+  estatus=1
 fi
 
-case $tweaked_estatus:$expect_failure in
+case $estatus:$expect_failure in
   0:yes) col=$red res=XPASS recheck=yes gcopy=yes;;
   0:*)   col=$grn res=PASS  recheck=no  gcopy=no;;
   77:*)  col=$blu res=SKIP  recheck=no  gcopy=yes;;
@@ -122,12 +119,6 @@ case $tweaked_estatus:$expect_failure in
   *:*)   col=$red res=FAIL  recheck=yes gcopy=yes;;
 esac
 
-# Report the test outcome and exit status in the logs, so that one can
-# know whether the test passed or failed simply by looking at the '.log'
-# file, without the need of also peaking into the corresponding '.trs'
-# file (automake bug#11814).
-echo "$res $test_name (exit status: $estatus)" >>$log_file
-
 # Report outcome to console.
 echo "${col}${res}${std}: $test_name"
 
diff --git a/udev/95-ceph-osd.rules b/udev/95-ceph-osd.rules
index 808436f..5349d0f 100644
--- a/udev/95-ceph-osd.rules
+++ b/udev/95-ceph-osd.rules
@@ -28,6 +28,16 @@ ACTION=="change", SUBSYSTEM=="block", \
   ENV{ID_PART_ENTRY_TYPE}=="cafecafe-9b03-4f30-b4c6-b4b80ceff106", \
   OWNER="ceph", GROUP="ceph", MODE="660"
 
+# LOCKBOX_UUID
+ACTION=="add", SUBSYSTEM=="block", \
+  ENV{DEVTYPE}=="partition", \
+  ENV{ID_PART_ENTRY_TYPE}=="fb3aabf9-d25f-47cc-bf5e-721d1816496b", \
+  OWNER:="ceph", GROUP:="ceph", MODE:="660", \
+  RUN+="/usr/sbin/ceph-disk --log-stdout -v trigger /dev/$name"
+ACTION=="change", SUBSYSTEM=="block", \
+  ENV{ID_PART_ENTRY_TYPE}=="fb3aabf9-d25f-47cc-bf5e-721d1816496", \
+  OWNER="ceph", GROUP="ceph", MODE="660"
+
 # MPATH_OSD_UUID
 ACTION=="add", SUBSYSTEM=="block", \
   ENV{ID_PART_ENTRY_TYPE}=="4fbd7e29-8ae0-4982-bf9d-5a8d867af560", \
@@ -55,6 +65,15 @@ ACTION=="change", SUBSYSTEM=="block", \
   ENV{ID_PART_ENTRY_TYPE}=="cafecafe-8ae0-4982-bf9d-5a8d867af560", \
   OWNER="ceph", GROUP="ceph", MODE="660"
 
+# MPATH_BLOCK_UUID
+ACTION=="add", SUBSYSTEM=="block", \
+  ENV{ID_PART_ENTRY_TYPE}=="7f4a666a-16f3-47a2-8445-152ef4d03f6c", \
+  OWNER:="ceph", GROUP:="ceph", MODE:="660", \
+  RUN+="/usr/sbin/ceph-disk --log-stdout -v trigger /dev/$name"
+ACTION=="change", SUBSYSTEM=="block", \
+  ENV{ID_PART_ENTRY_TYPE}=="7f4a666a-16f3-47a2-8445-152ef4d03f6c", \
+  OWNER="ceph", GROUP="ceph", MODE="660"
+
 # DMCRYPT_JOURNAL_UUID
 ACTION=="add" SUBSYSTEM=="block", \
   ENV{DEVTYPE}=="partition", \

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-ceph/ceph.git



More information about the Pkg-ceph-commits mailing list